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

📄 lines.cpp

📁 wxGTK 是 wxWidgets 的 linux GTK+ (>2.2.3)版本。wxWidgets 是一个跨平台的 GUI 框架
💻 CPP
📖 第 1 页 / 共 5 页
字号:
  for (int i = 0; i < 3; i ++)  {    wxNode *regionNode = m_regions.Item(i);    if (regionNode)    {      wxShapeRegion *region = (wxShapeRegion *)regionNode->GetData();      if (region->m_formattedText.GetCount() > 0)      {        double xp, yp, cx, cy, cw, ch;        GetLabelPosition(i, &xp, &yp);        // Offset region from default label position        region->GetPosition(&cx, &cy);        region->GetSize(&cw, &ch);        cx += xp;        cy += yp;        double rLeft = (double)(cx - (cw/2.0));        double rTop = (double)(cy - (ch/2.0));        double rRight = (double)(cx + (cw/2.0));        double rBottom = (double)(cy + (ch/2.0));        if (x > rLeft && x < rRight && y > rTop && y < rBottom)        {          inLabelRegion = true;          i = 3;        }      }    }  }  wxNode *node = m_lineControlPoints->GetFirst();  while (node && node->GetNext())  {    wxRealPoint *point1 = (wxRealPoint *)node->GetData();    wxRealPoint *point2 = (wxRealPoint *)node->GetNext()->GetData();    // For inaccurate mousing allow 8 pixel corridor    int extra = 4;    double dx = point2->x - point1->x;    double dy = point2->y - point1->y;    double seg_len = sqrt(dx*dx+dy*dy);    double distance_from_seg =      seg_len*((x-point1->x)*dy-(y-point1->y)*dx)/(dy*dy+dx*dx);    double distance_from_prev =      seg_len*((y-point1->y)*dy+(x-point1->x)*dx)/(dy*dy+dx*dx);    if ((fabs(distance_from_seg) < extra &&         distance_from_prev >= 0 && distance_from_prev <= seg_len)        || inLabelRegion)    {      *attachment = 0;      *distance = distance_from_seg;      return true;    }    node = node->GetNext();  }  return false;}void wxLineShape::DrawArrows(wxDC& dc){  // Distance along line of each arrow: space them out evenly.  double startArrowPos = 0.0;  double endArrowPos = 0.0;  double middleArrowPos = 0.0;  wxNode *node = m_arcArrows.GetFirst();  while (node)  {    wxArrowHead *arrow = (wxArrowHead *)node->GetData();    switch (arrow->GetArrowEnd())    {      case ARROW_POSITION_START:      {        if ((arrow->GetXOffset() != 0.0) && !m_ignoreArrowOffsets)          // If specified, x offset is proportional to line length          DrawArrow(dc, arrow, arrow->GetXOffset(), true);        else        {          DrawArrow(dc, arrow, startArrowPos, false);      // Absolute distance          startArrowPos += arrow->GetSize() + arrow->GetSpacing();        }        break;      }      case ARROW_POSITION_END:      {        if ((arrow->GetXOffset() != 0.0) && !m_ignoreArrowOffsets)          DrawArrow(dc, arrow, arrow->GetXOffset(), true);        else        {          DrawArrow(dc, arrow, endArrowPos, false);          endArrowPos += arrow->GetSize() + arrow->GetSpacing();        }        break;      }      case ARROW_POSITION_MIDDLE:      {        arrow->SetXOffset(middleArrowPos);        if ((arrow->GetXOffset() != 0.0) && !m_ignoreArrowOffsets)          DrawArrow(dc, arrow, arrow->GetXOffset(), true);        else        {          DrawArrow(dc, arrow, middleArrowPos, false);          middleArrowPos += arrow->GetSize() + arrow->GetSpacing();        }        break;      }    }    node = node->GetNext();  }}void wxLineShape::DrawArrow(wxDC& dc, wxArrowHead *arrow, double xOffset, bool proportionalOffset){  wxNode *first_line_node = m_lineControlPoints->GetFirst();  wxRealPoint *first_line_point = (wxRealPoint *)first_line_node->GetData();  wxNode *second_line_node = first_line_node->GetNext();  wxRealPoint *second_line_point = (wxRealPoint *)second_line_node->GetData();  wxNode *last_line_node = m_lineControlPoints->GetLast();  wxRealPoint *last_line_point = (wxRealPoint *)last_line_node->GetData();  wxNode *second_last_line_node = last_line_node->GetPrevious();  wxRealPoint *second_last_line_point = (wxRealPoint *)second_last_line_node->GetData();  // Position where we want to start drawing  double positionOnLineX = 0.0, positionOnLineY = 0.0;  // Position of start point of line, at the end of which we draw the arrow.  double startPositionX = 0.0 , startPositionY = 0.0;  switch (arrow->GetPosition())  {    case ARROW_POSITION_START:    {      // If we're using a proportional offset, calculate just where this will      // be on the line.      double realOffset = xOffset;      if (proportionalOffset)      {        double totalLength =          (double)sqrt((second_line_point->x - first_line_point->x)*(second_line_point->x - first_line_point->x) +                      (second_line_point->y - first_line_point->y)*(second_line_point->y - first_line_point->y));        realOffset = (double)(xOffset * totalLength);      }      GetPointOnLine(second_line_point->x, second_line_point->y,                     first_line_point->x, first_line_point->y,                     realOffset, &positionOnLineX, &positionOnLineY);      startPositionX = second_line_point->x;      startPositionY = second_line_point->y;      break;    }    case ARROW_POSITION_END:    {      // If we're using a proportional offset, calculate just where this will      // be on the line.      double realOffset = xOffset;      if (proportionalOffset)      {        double totalLength =          (double)sqrt((second_last_line_point->x - last_line_point->x)*(second_last_line_point->x - last_line_point->x) +                      (second_last_line_point->y - last_line_point->y)*(second_last_line_point->y - last_line_point->y));        realOffset = (double)(xOffset * totalLength);      }      GetPointOnLine(second_last_line_point->x, second_last_line_point->y,                     last_line_point->x, last_line_point->y,                     realOffset, &positionOnLineX, &positionOnLineY);      startPositionX = second_last_line_point->x;      startPositionY = second_last_line_point->y;      break;    }    case ARROW_POSITION_MIDDLE:    {      // Choose a point half way between the last and penultimate points      double x = ((last_line_point->x + second_last_line_point->x)/2);      double y = ((last_line_point->y + second_last_line_point->y)/2);      // If we're using a proportional offset, calculate just where this will      // be on the line.      double realOffset = xOffset;      if (proportionalOffset)      {        double totalLength =          (double)sqrt((second_last_line_point->x - x)*(second_last_line_point->x - x) +                      (second_last_line_point->y - y)*(second_last_line_point->y - y));        realOffset = (double)(xOffset * totalLength);      }      GetPointOnLine(second_last_line_point->x, second_last_line_point->y,                     x, y, realOffset, &positionOnLineX, &positionOnLineY);      startPositionX = second_last_line_point->x;      startPositionY = second_last_line_point->y;      break;    }  }  /*   * Add yOffset to arrow, if any   */  const double myPi = (double) M_PI;  // The translation that the y offset may give  double deltaX = 0.0;  double deltaY = 0.0;  if ((arrow->GetYOffset() != 0.0) && !m_ignoreArrowOffsets)  {    /*                                 |(x4, y4)                                 |d                                 |       (x1, y1)--------------(x3, y3)------------------(x2, y2)       x4 = x3 - d * sin(theta)       y4 = y3 + d * cos(theta)       Where theta = tan(-1) of (y3-y1)/(x3-x1)     */     double x1 = startPositionX;     double y1 = startPositionY;     double x3 = positionOnLineX;     double y3 = positionOnLineY;     double d = -arrow->GetYOffset(); // Negate so +offset is above line     double theta;     if (x3 == x1)       theta = (double)(myPi/2.0);     else       theta = (double)atan((y3-y1)/(x3-x1));     double x4 = (double)(x3 - (d*sin(theta)));     double y4 = (double)(y3 + (d*cos(theta)));     deltaX = x4 - positionOnLineX;     deltaY = y4 - positionOnLineY;  }  switch (arrow->_GetType())  {    case ARROW_ARROW:    {      double arrowLength = arrow->GetSize();      double arrowWidth = (double)(arrowLength/3.0);      double tip_x, tip_y, side1_x, side1_y, side2_x, side2_y;      oglGetArrowPoints(startPositionX+deltaX, startPositionY+deltaY,                       positionOnLineX+deltaX, positionOnLineY+deltaY,                       arrowLength, arrowWidth, &tip_x, &tip_y,                       &side1_x, &side1_y, &side2_x, &side2_y);      wxPoint points[4];      points[0].x = (int) tip_x; points[0].y = (int) tip_y;      points[1].x = (int) side1_x; points[1].y = (int) side1_y;      points[2].x = (int) side2_x; points[2].y = (int) side2_y;      points[3].x = (int) tip_x; points[3].y = (int) tip_y;      dc.SetPen(* m_pen);      dc.SetBrush(* m_brush);      dc.DrawPolygon(4, points);      break;    }    case ARROW_HOLLOW_CIRCLE:    case ARROW_FILLED_CIRCLE:    {      // Find point on line of centre of circle, which is a radius away      // from the end position      double diameter = (double)(arrow->GetSize());      double x, y;      GetPointOnLine(startPositionX+deltaX, startPositionY+deltaY,                   positionOnLineX+deltaX, positionOnLineY+deltaY,                   (double)(diameter/2.0),                   &x, &y);      // Convert ellipse centre to top-left coordinates      double x1 = (double)(x - (diameter/2.0));      double y1 = (double)(y - (diameter/2.0));      dc.SetPen(* m_pen);      if (arrow->_GetType() == ARROW_HOLLOW_CIRCLE)        dc.SetBrush(GetBackgroundBrush());      else        dc.SetBrush(* m_brush);      dc.DrawEllipse((long) x1, (long) y1, (long) diameter, (long) diameter);      break;    }    case ARROW_SINGLE_OBLIQUE:    {      break;    }    case ARROW_METAFILE:    {      if (arrow->GetMetaFile())      {        // Find point on line of centre of object, which is a half-width away        // from the end position        /*         *                width         * <-- start pos  <-----><-- positionOnLineX         *                _____         * --------------|  x  | <-- e.g. rectangular arrowhead         *                -----         */        double x, y;        GetPointOnLine(startPositionX, startPositionY,                   positionOnLineX, positionOnLineY,                   (double)(arrow->GetMetaFile()->m_width/2.0),                   &x, &y);        // Calculate theta for rotating the metafile.        /*          |          |     o(x2, y2)   'o' represents the arrowhead.          |    /          |   /          |  /theta          | /(x1, y1)          |______________________        */        double theta = 0.0;        double x1 = startPositionX;        double y1 = startPositionY;        double x2 = positionOnLineX;        double y2 = positionOnLineY;        if ((x1 == x2) && (y1 == y2))          theta = 0.0;        else if ((x1 == x2) && (y1 > y2))          theta = (double)(3.0*myPi/2.0);        else if ((x1 == x2) && (y2 > y1))          theta = (double)(myPi/2.0);        else if ((x2 > x1) && (y2 >= y1))          theta = (double)atan((y2 - y1)/(x2 - x1));        else if (x2 < x1)          theta = (double)(myPi + atan((y2 - y1)/(x2 - x1)));        else if ((x2 > x1) && (y2 < y1))          theta = (double)(2*myPi + atan((y2 - y1)/(x2 - x1)));        else        {          wxLogFatalError(wxT("Unknown arrowhead rotation case in lines.cc"));        }        // Rotate about the centre of the object, then place        // the object on the line.        if (arrow->GetMetaFile()->GetRotateable())          arrow->GetMetaFile()->Rotate(0.0, 0.0, theta);        if (m_erasing)        {          // If erasing, just draw a rectangle.          double minX, minY, maxX, maxY;          arrow->GetMetaFile()->GetBounds(&minX, &minY, &maxX, &maxY);          // Make erasing rectangle slightly bigger or you get droppings.          int extraPixels = 4;          dc.DrawRectangle((long)(deltaX + x + minX - (extraPixels/2.0)), (long)(deltaY + y + minY - (extraPixels/2.0)),                           (long)(maxX - minX + extraPixels), (long)(maxY - minY + extraPixels));        }        else          arrow->GetMetaFile()->Draw(dc, x+deltaX, y+deltaY);      }      break;    }    default:    {    }  }}void wxLineShape::OnErase(wxDC& dc){    const wxPen *old_pen = m_pen;    const wxBrush *old_brush = m_brush;    wxPen bg_pen = GetBackgroundPen();    wxBrush bg_brush = GetBackgroundBrush();    SetPen(&bg_pen);    SetBrush(&bg_brush);    double bound_x, bound_y;    GetBoundingBoxMax(&bound_x, &bound_y);    if (m_font) dc.SetFont(* m_font);    // Undraw text regions    for (int i = 0; i < 3; i++)    {      wxNode *node = m_regions.Item(i);      if (node)      {        double x, y;        wxShapeRegion *region = (wxShapeRegion *)node->GetData();        GetLabelPosition(i, &x, &y);        EraseRegion(dc, region, x, y);      }    }    // Undraw line    dc.SetPen(GetBackgroundPen());    dc.SetBrush(GetBackgroundBrush());    // Drawing over the line only seems to work if the line has a thickness    // of 1.    if (old_pen && (old_pen->GetWidth() > 1))    {      dc.DrawRectangle((long)(m_xpos - (bound_x/2.0) - 2.0), (long)(m_ypos - (bound_y/2.0) - 2.0),                        (long)(bound_x+4.0),  (long)(bound_y+4.0));    }    else    {      m_erasing = true;      GetEventHandler()->OnDraw(dc);      GetEventHandler()->OnEraseControlPoints(dc);      m_erasing = false;    }    if (old_pen) SetPen(old_pen);    if (old_brush) SetBrush(old_brush);}void wxLineShape::GetBoundingBoxMin(double *w, double *h){  double x1 = 10000;  double y1 = 10000;  double x2 = -10000;  double y2 = -10000;  wxNode *node = m_lineControlPoints->GetFirst();  while (node)  {    wxRealPoint *point = (wxRealPoint *)node->GetData();    if (point->x < x1) x1 = point->x;    if (point->y < y1) y1 = point->y;    if (point->x > x2) x2 = point->x;    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();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -