⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lines.cpp

📁 Wxpython Implemented on Windows CE, Source code
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    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 + -