📄 canvas.cpp
字号:
m_dragState = StartDraggingLeft;
m_firstDragX = x;
m_firstDragY = y;
}
else if (event.LeftUp())
{
// N.B. Only register a click if the same object was
// identified for down *and* up.
if (nearest_object == m_draggedShape)
nearest_object->GetEventHandler()->OnLeftClick((double)x, (double)y, keys, attachment);
m_draggedShape = NULL;
m_dragState = NoDragging;
}
else if (event.LeftDClick())
{
nearest_object->GetEventHandler()->OnLeftDoubleClick((double)x, (double)y, keys, attachment);
m_draggedShape = NULL;
m_dragState = NoDragging;
}
else if (event.RightDown())
{
m_draggedShape = nearest_object;
m_draggedAttachment = attachment;
m_dragState = StartDraggingRight;
m_firstDragX = x;
m_firstDragY = y;
}
else if (event.RightUp())
{
if (nearest_object == m_draggedShape)
nearest_object->GetEventHandler()->OnRightClick((double)x, (double)y, keys, attachment);
m_draggedShape = NULL;
m_dragState = NoDragging;
}
}
else // Canvas event (no nearest object)
{
if (event.LeftDown())
{
m_draggedShape = NULL;
m_dragState = StartDraggingLeft;
m_firstDragX = x;
m_firstDragY = y;
}
else if (event.LeftUp())
{
OnLeftClick((double)x, (double)y, keys);
m_draggedShape = NULL;
m_dragState = NoDragging;
}
else if (event.RightDown())
{
m_draggedShape = NULL;
m_dragState = StartDraggingRight;
m_firstDragX = x;
m_firstDragY = y;
}
else if (event.RightUp())
{
OnRightClick((double)x, (double)y, keys);
m_draggedShape = NULL;
m_dragState = NoDragging;
}
}
}
}
/*
* Try to find a sensitive object, working up the hierarchy of composites.
*
*/
wxShape *wxShapeCanvas::FindFirstSensitiveShape(double x, double y, int *new_attachment, int op)
{
wxShape *image = FindShape(x, y, new_attachment);
if (!image) return NULL;
wxShape *actualImage = FindFirstSensitiveShape1(image, op);
if (actualImage)
{
double dist;
// Find actual attachment
actualImage->HitTest(x, y, new_attachment, &dist);
}
return actualImage;
}
wxShape *wxShapeCanvas::FindFirstSensitiveShape1(wxShape *image, int op)
{
if (image->GetSensitivityFilter() & op)
return image;
if (image->GetParent())
return FindFirstSensitiveShape1(image->GetParent(), op);
return NULL;
}
// Helper function: true if 'contains' wholly contains 'contained'.
static bool WhollyContains(wxShape *contains, wxShape *contained)
{
double xp1, yp1, xp2, yp2;
double w1, h1, w2, h2;
double left1, top1, right1, bottom1, left2, top2, right2, bottom2;
xp1 = contains->GetX(); yp1 = contains->GetY(); xp2 = contained->GetX(); yp2 = contained->GetY();
contains->GetBoundingBoxMax(&w1, &h1);
contained->GetBoundingBoxMax(&w2, &h2);
left1 = (double)(xp1 - (w1 / 2.0));
top1 = (double)(yp1 - (h1 / 2.0));
right1 = (double)(xp1 + (w1 / 2.0));
bottom1 = (double)(yp1 + (h1 / 2.0));
left2 = (double)(xp2 - (w2 / 2.0));
top2 = (double)(yp2 - (h2 / 2.0));
right2 = (double)(xp2 + (w2 / 2.0));
bottom2 = (double)(yp2 + (h2 / 2.0));
return ((left1 <= left2) && (top1 <= top2) && (right1 >= right2) && (bottom1 >= bottom2));
}
wxShape *wxShapeCanvas::FindShape(double x, double y, int *attachment, wxClassInfo *info, wxShape *notObject)
{
double nearest = 100000.0;
int nearest_attachment = 0;
wxShape *nearest_object = NULL;
// Go backward through the object list, since we want:
// (a) to have the control points drawn LAST to overlay
// the other objects
// (b) to find the control points FIRST if they exist
wxObjectList::compatibility_iterator current = GetDiagram()->GetShapeList()->GetLast();
while (current)
{
wxShape *object = (wxShape *)current->GetData();
double dist;
int temp_attachment;
// First pass for lines, which might be inside a container, so we
// want lines to take priority over containers. This first loop
// could fail if we clickout side a line, so then we'll
// try other shapes.
if (object->IsShown() &&
object->IsKindOf(CLASSINFO(wxLineShape)) &&
object->HitTest(x, y, &temp_attachment, &dist) &&
((info == NULL) || object->IsKindOf(info)) &&
(!notObject || !notObject->HasDescendant(object)))
{
// A line is trickier to spot than a normal object.
// For a line, since it's the diagonal of the box
// we use for the hit test, we may have several
// lines in the box and therefore we need to be able
// to specify the nearest point to the centre of the line
// as our hit criterion, to give the user some room for
// manouevre.
if (dist < nearest)
{
nearest = dist;
nearest_object = object;
nearest_attachment = temp_attachment;
}
}
if (current)
current = current->GetPrevious();
}
current = GetDiagram()->GetShapeList()->GetLast();
while (current)
{
wxShape *object = (wxShape *)current->GetData();
double dist;
int temp_attachment;
// On second pass, only ever consider non-composites or divisions. If children want to pass
// up control to the composite, that's up to them.
if (object->IsShown() && (object->IsKindOf(CLASSINFO(wxDivisionShape)) || !object->IsKindOf(CLASSINFO(wxCompositeShape)))
&& object->HitTest(x, y, &temp_attachment, &dist) && ((info == NULL) || object->IsKindOf(info)) &&
(!notObject || !notObject->HasDescendant(object)))
{
if (!object->IsKindOf(CLASSINFO(wxLineShape)))
{
// If we've hit a container, and we have already found a line in the
// first pass, then ignore the container in case the line is in the container.
// Check for division in case line straddles divisions (i.e. is not wholly contained).
if (!nearest_object || !(object->IsKindOf(CLASSINFO(wxDivisionShape)) || WhollyContains(object, nearest_object)))
{
nearest_object = object;
nearest_attachment = temp_attachment;
current = GetDiagram()->GetShapeList()->GetFirst()->GetPrevious(); // finish loop
}
}
}
if (current)
current = current->GetPrevious();
}
*attachment = nearest_attachment;
return nearest_object;
}
/*
* Higher-level events called by OnEvent
*
*/
void wxShapeCanvas::OnLeftClick(double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys))
{
}
void wxShapeCanvas::OnRightClick(double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys))
{
}
void wxShapeCanvas::OnDragLeft(bool WXUNUSED(draw), double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys))
{
}
void wxShapeCanvas::OnBeginDragLeft(double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys))
{
}
void wxShapeCanvas::OnEndDragLeft(double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys))
{
}
void wxShapeCanvas::OnDragRight(bool WXUNUSED(draw), double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys))
{
}
void wxShapeCanvas::OnBeginDragRight(double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys))
{
}
void wxShapeCanvas::OnEndDragRight(double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys))
{
}
void wxShapeCanvas::AddShape(wxShape *object, wxShape *addAfter)
{ GetDiagram()->AddShape(object, addAfter); }
void wxShapeCanvas::InsertShape(wxShape *object)
{ GetDiagram()->InsertShape(object); }
void wxShapeCanvas::RemoveShape(wxShape *object)
{ GetDiagram()->RemoveShape(object); }
bool wxShapeCanvas::GetQuickEditMode()
{ return GetDiagram()->GetQuickEditMode(); }
void wxShapeCanvas::Redraw(wxDC& dc)
{ GetDiagram()->Redraw(dc); }
void wxShapeCanvas::Snap(double *x, double *y)
{ GetDiagram()->Snap(x, y); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -