📄 basic.cpp
字号:
void wxShape::OnMovePost(wxDC& WXUNUSED(dc), double WXUNUSED(x), double WXUNUSED(y), double WXUNUSED(old_x), double WXUNUSED(old_y), bool WXUNUSED(display))
{
}
void wxShape::OnErase(wxDC& dc)
{
if (!m_visible)
return;
// Erase links
wxNode *current = m_lines.GetFirst();
while (current)
{
wxLineShape *line = (wxLineShape *)current->GetData();
line->GetEventHandler()->OnErase(dc);
current = current->GetNext();
}
GetEventHandler()->OnEraseContents(dc);
}
void wxShape::OnEraseContents(wxDC& dc)
{
if (!m_visible)
return;
double maxX, maxY, minX, minY;
double xp = GetX();
double yp = GetY();
GetBoundingBoxMin(&minX, &minY);
GetBoundingBoxMax(&maxX, &maxY);
double topLeftX = (double)(xp - (maxX / 2.0) - 2.0);
double topLeftY = (double)(yp - (maxY / 2.0) - 2.0);
int penWidth = 0;
if (m_pen)
penWidth = m_pen->GetWidth();
dc.SetPen(GetBackgroundPen());
dc.SetBrush(GetBackgroundBrush());
dc.DrawRectangle(WXROUND(topLeftX - penWidth), WXROUND(topLeftY - penWidth),
WXROUND(maxX + penWidth*2.0 + 4.0), WXROUND(maxY + penWidth*2.0 + 4.0));
}
void wxShape::EraseLinks(wxDC& dc, int attachment, bool recurse)
{
if (!m_visible)
return;
wxNode *current = m_lines.GetFirst();
while (current)
{
wxLineShape *line = (wxLineShape *)current->GetData();
if (attachment == -1 || ((line->GetTo() == this && line->GetAttachmentTo() == attachment) ||
(line->GetFrom() == this && line->GetAttachmentFrom() == attachment)))
line->GetEventHandler()->OnErase(dc);
current = current->GetNext();
}
if (recurse)
{
wxNode *node = m_children.GetFirst();
while (node)
{
wxShape *child = (wxShape *)node->GetData();
child->EraseLinks(dc, attachment, recurse);
node = node->GetNext();
}
}
}
void wxShape::DrawLinks(wxDC& dc, int attachment, bool recurse)
{
if (!m_visible)
return;
wxNode *current = m_lines.GetFirst();
while (current)
{
wxLineShape *line = (wxLineShape *)current->GetData();
if (attachment == -1 ||
(line->GetTo() == this && line->GetAttachmentTo() == attachment) ||
(line->GetFrom() == this && line->GetAttachmentFrom() == attachment))
line->Draw(dc);
current = current->GetNext();
}
if (recurse)
{
wxNode *node = m_children.GetFirst();
while (node)
{
wxShape *child = (wxShape *)node->GetData();
child->DrawLinks(dc, attachment, recurse);
node = node->GetNext();
}
}
}
// Returns true if pt1 <= pt2 in the sense that one point comes before another on an
// edge of the shape.
// attachmentPoint is the attachment point (= side) in question.
// This is the default, rectangular implementation.
bool wxShape::AttachmentSortTest(int attachmentPoint, const wxRealPoint& pt1, const wxRealPoint& pt2)
{
int physicalAttachment = LogicalToPhysicalAttachment(attachmentPoint);
switch (physicalAttachment)
{
case 0:
case 2:
{
return (pt1.x <= pt2.x) ;
}
case 1:
case 3:
{
return (pt1.y <= pt2.y) ;
}
}
return false;
}
bool wxShape::MoveLineToNewAttachment(wxDC& dc, wxLineShape *to_move,
double x, double y)
{
if (GetAttachmentMode() == ATTACHMENT_MODE_NONE)
return false;
int newAttachment, oldAttachment;
double distance;
// Is (x, y) on this object? If so, find the new attachment point
// the user has moved the point to
bool hit = HitTest(x, y, &newAttachment, &distance);
if (!hit)
return false;
EraseLinks(dc);
if (to_move->GetTo() == this)
oldAttachment = to_move->GetAttachmentTo();
else
oldAttachment = to_move->GetAttachmentFrom();
// The links in a new ordering.
wxList newOrdering;
// First, add all links to the new list.
wxNode *node = m_lines.GetFirst();
while (node)
{
newOrdering.Append(node->GetData());
node = node->GetNext();
}
// Delete the line object from the list of links; we're going to move
// it to another position in the list
newOrdering.DeleteObject(to_move);
double old_x = (double) -99999.9;
double old_y = (double) -99999.9;
node = newOrdering.GetFirst();
bool found = false;
while (!found && node)
{
wxLineShape *line = (wxLineShape *)node->GetData();
if ((line->GetTo() == this && oldAttachment == line->GetAttachmentTo()) ||
(line->GetFrom() == this && oldAttachment == line->GetAttachmentFrom()))
{
double startX, startY, endX, endY;
double xp, yp;
line->GetEnds(&startX, &startY, &endX, &endY);
if (line->GetTo() == this)
{
xp = endX;
yp = endY;
} else
{
xp = startX;
yp = startY;
}
wxRealPoint thisPoint(xp, yp);
wxRealPoint lastPoint(old_x, old_y);
wxRealPoint newPoint(x, y);
if (AttachmentSortTest(newAttachment, newPoint, thisPoint) && AttachmentSortTest(newAttachment, lastPoint, newPoint))
{
found = true;
newOrdering.Insert(node, to_move);
}
old_x = xp;
old_y = yp;
}
node = node->GetNext();
}
if (!found)
newOrdering.Append(to_move);
GetEventHandler()->OnChangeAttachment(newAttachment, to_move, newOrdering);
return true;
}
void wxShape::OnChangeAttachment(int attachment, wxLineShape* line, wxList& ordering)
{
if (line->GetTo() == this)
line->SetAttachmentTo(attachment);
else
line->SetAttachmentFrom(attachment);
ApplyAttachmentOrdering(ordering);
wxClientDC dc(GetCanvas());
GetCanvas()->PrepareDC(dc);
MoveLinks(dc);
if (!GetCanvas()->GetQuickEditMode()) GetCanvas()->Redraw(dc);
}
// Reorders the lines according to the given list.
void wxShape::ApplyAttachmentOrdering(wxList& linesToSort)
{
// This is a temporary store of all the lines.
wxList linesStore;
wxNode *node = m_lines.GetFirst();
while (node)
{
wxLineShape *line = (wxLineShape *)node->GetData();
linesStore.Append(line);
node = node->GetNext();;
}
m_lines.Clear();
node = linesToSort.GetFirst();
while (node)
{
wxLineShape *line = (wxLineShape *)node->GetData();
if (linesStore.Member(line))
{
// Done this one
linesStore.DeleteObject(line);
m_lines.Append(line);
}
node = node->GetNext();
}
// Now add any lines that haven't been listed in linesToSort.
node = linesStore.GetFirst();
while (node)
{
wxLineShape *line = (wxLineShape *)node->GetData();
m_lines.Append(line);
node = node->GetNext();
}
}
// Reorders the lines coming into the node image at this attachment
// position, in the order in which they appear in linesToSort.
// Any remaining lines not in the list will be added to the end.
void wxShape::SortLines(int attachment, wxList& linesToSort)
{
// This is a temporary store of all the lines at this attachment
// point. We'll tick them off as we've processed them.
wxList linesAtThisAttachment;
wxNode *node = m_lines.GetFirst();
while (node)
{
wxLineShape *line = (wxLineShape *)node->GetData();
wxNode *next = node->GetNext();
if ((line->GetTo() == this && line->GetAttachmentTo() == attachment) ||
(line->GetFrom() == this && line->GetAttachmentFrom() == attachment))
{
linesAtThisAttachment.Append(line);
delete node;
node = next;
}
else node = node->GetNext();
}
node = linesToSort.GetFirst();
while (node)
{
wxLineShape *line = (wxLineShape *)node->GetData();
if (linesAtThisAttachment.Member(line))
{
// Done this one
linesAtThisAttachment.DeleteObject(line);
m_lines.Append(line);
}
node = node->GetNext();
}
// Now add any lines that haven't been listed in linesToSort.
node = linesAtThisAttachment.GetFirst();
while (node)
{
wxLineShape *line = (wxLineShape *)node->GetData();
m_lines.Append(line);
node = node->GetNext();
}
}
void wxShape::OnHighlight(wxDC& WXUNUSED(dc))
{
}
void wxShape::OnLeftClick(double x, double y, int keys, int attachment)
{
if ((m_sensitivity & OP_CLICK_LEFT) != OP_CLICK_LEFT)
{
attachment = 0;
double dist;
if (m_parent)
{
m_parent->HitTest(x, y, &attachment, &dist);
m_parent->GetEventHandler()->OnLeftClick(x, y, keys, attachment);
}
return;
}
}
void wxShape::OnRightClick(double x, double y, int keys, int attachment)
{
if ((m_sensitivity & OP_CLICK_RIGHT) != OP_CLICK_RIGHT)
{
attachment = 0;
double dist;
if (m_parent)
{
m_parent->HitTest(x, y, &attachment, &dist);
m_parent->GetEventHandler()->OnRightClick(x, y, keys, attachment);
}
return;
}
}
double DragOffsetX = 0.0;
double DragOffsetY = 0.0;
void wxShape::OnDragLeft(bool draw, double x, double y, int keys, int attachment)
{
if ((m_sensitivity & OP_DRAG_LEFT) != OP_DRAG_LEFT)
{
attachment = 0;
double dist;
if (m_parent)
{
m_parent->HitTest(x, y, &attachment, &dist);
m_parent->GetEventHandler()->OnDragLeft(draw, x, y, keys, attachment);
}
return;
}
wxClientDC dc(GetCanvas());
GetCanvas()->PrepareDC(dc);
dc.SetLogicalFunction(OGLRBLF);
wxPen dottedPen(*wxBLACK, 1, wxDOT);
dc.SetPen(dottedPen);
dc.SetBrush(* wxTRANSPARENT_BRUSH);
double xx, yy;
xx = x + DragOffsetX;
yy = y + DragOffsetY;
m_canvas->Snap(&xx, &yy);
// m_xpos = xx; m_ypos = yy;
double w, h;
GetBoundingBoxMax(&w, &h);
GetEventHandler()->OnDrawOutline(dc, xx, yy, w, h);
}
void wxShape::OnBeginDragLeft(double x, double y, int keys, int attachment)
{
if ((m_sensitivity & OP_DRAG_LEFT) != OP_DRAG_LEFT)
{
attachment = 0;
double dist;
if (m_parent)
{
m_parent->HitTest(x, y, &attachment, &dist);
m_parent->GetEventHandler()->OnBeginDragLeft(x, y, keys, attachment);
}
return;
}
DragOffsetX = m_xpos - x;
DragOffsetY = m_ypos - y;
wxClientDC dc(GetCanvas());
GetCanvas()->PrepareDC(dc);
// New policy: don't erase shape until end of drag.
// Erase(dc);
double xx, yy;
xx = x + DragOffsetX;
yy = y + DragOffsetY;
m_canvas->Snap(&xx, &yy);
// m_xpos = xx; m_ypos = yy;
dc.SetLogicalFunction(OGLRBLF);
wxPen dottedPen(*wxBLACK, 1, wxDOT);
dc.SetPen(dottedPen);
dc.SetBrush((* wxTRANSPARENT_BRUSH));
double w, h;
GetBoundingBoxMax(&w, &h);
GetEventHandler()->OnDrawOutline(dc, xx, yy, w, h);
m_canvas->CaptureMouse();
}
void wxShape::OnEndDragLeft(double x, double y, int keys, int attachment)
{
if (!m_draggable)
return;
m_canvas->ReleaseMouse();
if ((m_sensitivity & OP_DRAG_LEFT) != OP_DRAG_LEFT)
{
attachment = 0;
double dist;
if (m_parent)
{
m_parent->HitTest(x, y, &attachment, &dist);
m_parent->GetEventHandler()->OnEndDragLeft(x, y, keys, attachment);
}
return;
}
wxClientDC dc(GetCanvas());
GetCanvas()->PrepareDC(dc);
dc.SetLogicalFunction(wxCOPY);
double xx = x + DragOffsetX;
double yy = y + DragOffsetY;
m_canvas->Snap(&xx, &yy);
// canvas->Snap(&m_xpos, &m_ypos);
// New policy: erase shape at end of drag.
Erase(dc);
Move(dc, xx, yy);
if (m_canvas && !m_canvas->GetQuickEditMode()) m_canvas->Redraw(dc);
}
void wxShape::OnDragRight(bool draw, double x, double y, int keys, int attachment)
{
if ((m_sensitivity & OP_DRAG_RIGHT) != OP_DRAG_RIGHT)
{
attachment = 0;
double dist;
if (m_parent)
{
m_parent->HitTest(x, y, &attachment, &dist);
m_parent->GetEventHandler()->OnDragRight(draw, x, y, keys, attachment);
}
return;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -