📄 lines.cpp
字号:
if (point->y > y2) y2 = point->y;
node = node->GetNext();
}
*w = (double)(x2 - x1);
*h = (double)(y2 - y1);
}
/*
* For a node image of interest, finds the position of this arc
* amongst all the arcs which are attached to THIS SIDE of the node image,
* and the number of same.
*/
void wxLineShape::FindNth(wxShape *image, int *nth, int *no_arcs, bool incoming)
{
int n = -1;
int num = 0;
wxNode *node = image->GetLines().GetFirst();
int this_attachment;
if (image == m_to)
this_attachment = m_attachmentTo;
else
this_attachment = m_attachmentFrom;
// Find number of lines going into/out of this particular attachment point
while (node)
{
wxLineShape *line = (wxLineShape *)node->GetData();
if (line->m_from == image)
{
// This is the nth line attached to 'image'
if ((line == this) && !incoming)
n = num;
// Increment num count if this is the same side (attachment number)
if (line->m_attachmentFrom == this_attachment)
num ++;
}
if (line->m_to == image)
{
// This is the nth line attached to 'image'
if ((line == this) && incoming)
n = num;
// Increment num count if this is the same side (attachment number)
if (line->m_attachmentTo == this_attachment)
num ++;
}
node = node->GetNext();
}
*nth = n;
*no_arcs = num;
}
void wxLineShape::OnDrawOutline(wxDC& dc, double WXUNUSED(x), double WXUNUSED(y), double WXUNUSED(w), double WXUNUSED(h))
{
const wxPen *old_pen = m_pen;
const wxBrush *old_brush = m_brush;
wxPen dottedPen(*wxBLACK, 1, wxDOT);
SetPen(& dottedPen);
SetBrush( wxTRANSPARENT_BRUSH );
GetEventHandler()->OnDraw(dc);
if (old_pen) SetPen(old_pen);
else SetPen(NULL);
if (old_brush) SetBrush(old_brush);
else SetBrush(NULL);
}
bool wxLineShape::OnMovePre(wxDC& dc, double x, double y, double old_x, double old_y, bool WXUNUSED(display))
{
double x_offset = x - old_x;
double y_offset = y - old_y;
if (m_lineControlPoints && !(x_offset == 0.0 && y_offset == 0.0))
{
wxNode *node = m_lineControlPoints->GetFirst();
while (node)
{
wxRealPoint *point = (wxRealPoint *)node->GetData();
point->x += x_offset;
point->y += y_offset;
node = node->GetNext();
}
}
// Move temporary label rectangles if necessary
for (int i = 0; i < 3; i++)
{
if (m_labelObjects[i])
{
m_labelObjects[i]->Erase(dc);
double xp, yp, xr, yr;
GetLabelPosition(i, &xp, &yp);
wxNode *node = m_regions.Item(i);
if (node)
{
wxShapeRegion *region = (wxShapeRegion *)node->GetData();
region->GetPosition(&xr, &yr);
}
else
{
xr = 0.0; yr = 0.0;
}
m_labelObjects[i]->Move(dc, xp+xr, yp+yr);
}
}
return true;
}
void wxLineShape::OnMoveLink(wxDC& dc, bool moveControlPoints)
{
if (!m_from || !m_to)
return;
if (m_lineControlPoints->GetCount() > 2)
Initialise();
// Do each end - nothing in the middle. User has to move other points
// manually if necessary.
double end_x, end_y;
double other_end_x, other_end_y;
FindLineEndPoints(&end_x, &end_y, &other_end_x, &other_end_y);
wxNode *first = m_lineControlPoints->GetFirst();
/* wxRealPoint *first_point = */ (wxRealPoint *)first->GetData();
wxNode *last = m_lineControlPoints->GetLast();
/* wxRealPoint *last_point = */ (wxRealPoint *)last->GetData();
/* This is redundant, surely? Done by SetEnds.
first_point->x = end_x; first_point->y = end_y;
last_point->x = other_end_x; last_point->y = other_end_y;
*/
double oldX = m_xpos;
double oldY = m_ypos;
SetEnds(end_x, end_y, other_end_x, other_end_y);
// Do a second time, because one may depend on the other.
FindLineEndPoints(&end_x, &end_y, &other_end_x, &other_end_y);
SetEnds(end_x, end_y, other_end_x, other_end_y);
// Try to move control points with the arc
double x_offset = m_xpos - oldX;
double y_offset = m_ypos - oldY;
// if (moveControlPoints && m_lineControlPoints && !(x_offset == 0.0 && y_offset == 0.0))
// Only move control points if it's a self link. And only works if attachment mode is ON.
if ((m_from == m_to) && (m_from->GetAttachmentMode() != ATTACHMENT_MODE_NONE) && moveControlPoints && m_lineControlPoints && !(x_offset == 0.0 && y_offset == 0.0))
{
wxNode *node = m_lineControlPoints->GetFirst();
while (node)
{
if ((node != m_lineControlPoints->GetFirst()) && (node != m_lineControlPoints->GetLast()))
{
wxRealPoint *point = (wxRealPoint *)node->GetData();
point->x += x_offset;
point->y += y_offset;
}
node = node->GetNext();
}
}
Move(dc, m_xpos, m_ypos);
}
// Finds the x, y points at the two ends of the line.
// This function can be used by e.g. line-routing routines to
// get the actual points on the two node images where the lines will be drawn
// to/from.
void wxLineShape::FindLineEndPoints(double *fromX, double *fromY, double *toX, double *toY)
{
if (!m_from || !m_to)
return;
// Do each end - nothing in the middle. User has to move other points
// manually if necessary.
double end_x = 0.0, end_y = 0.0;
double other_end_x = 0.0, other_end_y = 0.0;
wxNode *first = m_lineControlPoints->GetFirst();
/* wxRealPoint *first_point = */ (wxRealPoint *)first->GetData();
wxNode *last = m_lineControlPoints->GetLast();
/* wxRealPoint *last_point = */ (wxRealPoint *)last->GetData();
wxNode *second = first->GetNext();
wxRealPoint *second_point = (wxRealPoint *)second->GetData();
wxNode *second_last = last->GetPrevious();
wxRealPoint *second_last_point = (wxRealPoint *)second_last->GetData();
if (m_lineControlPoints->GetCount() > 2)
{
if (m_from->GetAttachmentMode() != ATTACHMENT_MODE_NONE)
{
int nth, no_arcs;
FindNth(m_from, &nth, &no_arcs, false); // Not incoming
m_from->GetAttachmentPosition(m_attachmentFrom, &end_x, &end_y, nth, no_arcs, this);
}
else
(void) m_from->GetPerimeterPoint(m_from->GetX(), m_from->GetY(),
(double)second_point->x, (double)second_point->y,
&end_x, &end_y);
if (m_to->GetAttachmentMode() != ATTACHMENT_MODE_NONE)
{
int nth, no_arcs;
FindNth(m_to, &nth, &no_arcs, true); // Incoming
m_to->GetAttachmentPosition(m_attachmentTo, &other_end_x, &other_end_y, nth, no_arcs, this);
}
else
(void) m_to->GetPerimeterPoint(m_to->GetX(), m_to->GetY(),
(double)second_last_point->x, (double)second_last_point->y,
&other_end_x, &other_end_y);
}
else
{
double fromX = m_from->GetX();
double fromY = m_from->GetY();
double toX = m_to->GetX();
double toY = m_to->GetY();
if (m_from->GetAttachmentMode() != ATTACHMENT_MODE_NONE)
{
int nth, no_arcs;
FindNth(m_from, &nth, &no_arcs, false);
m_from->GetAttachmentPosition(m_attachmentFrom, &end_x, &end_y, nth, no_arcs, this);
fromX = end_x;
fromY = end_y;
}
if (m_to->GetAttachmentMode() != ATTACHMENT_MODE_NONE)
{
int nth, no_arcs;
FindNth(m_to, &nth, &no_arcs, true);
m_to->GetAttachmentPosition(m_attachmentTo, &other_end_x, &other_end_y, nth, no_arcs, this);
toX = other_end_x;
toY = other_end_y;
}
if (m_from->GetAttachmentMode() == ATTACHMENT_MODE_NONE)
(void) m_from->GetPerimeterPoint(m_from->GetX(), m_from->GetY(),
toX, toY,
&end_x, &end_y);
if (m_to->GetAttachmentMode() == ATTACHMENT_MODE_NONE)
(void) m_to->GetPerimeterPoint(m_to->GetX(), m_to->GetY(),
fromX, fromY,
&other_end_x, &other_end_y);
}
*fromX = end_x;
*fromY = end_y;
*toX = other_end_x;
*toY = other_end_y;
}
void wxLineShape::OnDraw(wxDC& dc)
{
if (m_lineControlPoints)
{
if (m_pen)
dc.SetPen(* m_pen);
if (m_brush)
dc.SetBrush(* m_brush);
int n = m_lineControlPoints->GetCount();
wxPoint *points = new wxPoint[n];
int i;
for (i = 0; i < n; i++)
{
wxRealPoint* point = (wxRealPoint*) m_lineControlPoints->Item(i)->GetData();
points[i].x = WXROUND(point->x);
points[i].y = WXROUND(point->y);
}
if (m_isSpline)
dc.DrawSpline(n, points);
else
dc.DrawLines(n, points);
#ifdef __WXMSW__
// For some reason, last point isn't drawn under Windows.
dc.DrawPoint(points[n-1]);
#endif
delete[] points;
// Problem with pen - if not a solid pen, does strange things
// to the arrowhead. So make (get) a new pen that's solid.
if (m_pen && (m_pen->GetStyle() != wxSOLID))
{
wxPen *solid_pen =
wxThePenList->FindOrCreatePen(m_pen->GetColour(), 1, wxSOLID);
if (solid_pen)
dc.SetPen(* solid_pen);
}
DrawArrows(dc);
}
}
void wxLineShape::OnDrawControlPoints(wxDC& dc)
{
if (!m_drawHandles)
return;
// Draw temporary label rectangles if necessary
for (int i = 0; i < 3; i++)
{
if (m_labelObjects[i])
m_labelObjects[i]->Draw(dc);
}
wxShape::OnDrawControlPoints(dc);
}
void wxLineShape::OnEraseControlPoints(wxDC& dc)
{
// Erase temporary label rectangles if necessary
for (int i = 0; i < 3; i++)
{
if (m_labelObjects[i])
m_labelObjects[i]->Erase(dc);
}
wxShape::OnEraseControlPoints(dc);
}
void wxLineShape::OnDragLeft(bool WXUNUSED(draw), double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys), int WXUNUSED(attachment))
{
}
void wxLineShape::OnBeginDragLeft(double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys), int WXUNUSED(attachment))
{
}
void wxLineShape::OnEndDragLeft(double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys), int WXUNUSED(attachment))
{
}
/*
void wxLineShape::SetArrowSize(double length, double width)
{
arrow_length = length;
arrow_width = width;
}
void wxLineShape::SetStartArrow(int style)
{
start_style = style;
}
void wxLineShape::SetMiddleArrow(int style)
{
middle_style = style;
}
void wxLineShape::SetEndArrow(int style)
{
end_style = style;
}
*/
void wxLineShape::OnDrawContents(wxDC& dc)
{
if (GetDisableLabel())
return;
for (int i = 0; i < 3; i++)
{
wxNode *node = m_regions.Item(i);
if (node)
{
wxShapeRegion *region = (wxShapeRegion *)node->GetData();
double x, y;
GetLabelPosition(i, &x, &y);
DrawRegion(dc, region, x, y);
}
}
}
void wxLineShape::SetTo(wxShape *object)
{
m_to = object;
}
void wxLineShape::SetFrom(wxShape *object)
{
m_from = object;
}
void wxLineShape::MakeControlPoints()
{
if (m_canvas && m_lineControlPoints)
{
wxNode *first = m_lineControlPoints->GetFirst();
wxNode *last = m_lineControlPoints->GetLast();
wxRealPoint *first_point = (wxRealPoint *)first->GetData();
wxRealPoint *last_point = (wxRealPoint *)last->GetData();
wxLineControlPoint *control = new wxLineControlPoint(m_canvas, this, CONTROL_POINT_SIZE,
first_point->x, first_point->y,
CONTROL_POINT_ENDPOINT_FROM);
control->m_point = first_point;
m_canvas->AddShape(control);
m_controlPoints.Append(control);
wxNode *node = first->GetNext();
while (node != last)
{
wxRealPoint *point = (wxRealPoint *)node->GetData();
control = new wxLineControlPoint(m_canvas, this, CONTROL_POINT_SIZE,
point->x, point->y,
CONTROL_POINT_LINE);
control->m_point = point;
m_canvas->AddShape(control);
m_controlPoints.Append(control);
node = node->GetNext();
}
control = new wxLineControlPoint(m_canvas, this, CONTROL_POINT_SIZE,
last_point->x, last_point->y,
CONTROL_POINT_ENDPOINT_TO);
control->m_point = last_point;
m_canvas->AddShape(control);
m_controlPoints.Append(control);
}
}
void wxLineShape::ResetControlPoints()
{
if (m_canvas && m_lineControlPoints && m_controlPoints.GetCount() > 0)
{
wxNode *node = m_controlPoints.GetFirst();
wxNode *control_node = m_lineControlPoints->GetFirst();
while (node && control_node)
{
wxRealPoint *point = (wxRealPoint *)control_node->GetData();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -