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

📄 lines.cpp

📁 Wxpython Implemented on Windows CE, Source code
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    lineShape->SetPen(old_pen);
    lineShape->SetBrush(old_brush);
  }

  if (lpt->m_type == CONTROL_POINT_ENDPOINT_FROM || lpt->m_type == CONTROL_POINT_ENDPOINT_TO)
  {
    m_canvas->SetCursor(wxCursor(wxCURSOR_BULLSEYE));
    lpt->m_oldCursor = wxSTANDARD_CURSOR;
  }
}

void wxLineShape::OnSizingEndDragLeft(wxControlPoint* pt, double x, double y, int WXUNUSED(keys), int WXUNUSED(attachment))
{
  wxLineControlPoint* lpt = (wxLineControlPoint*) pt;

  wxClientDC dc(GetCanvas());
  GetCanvas()->PrepareDC(dc);

  this->SetDisableLabel(false);
  wxLineShape *lineShape = (wxLineShape *)this;

  if (lpt->m_type == CONTROL_POINT_LINE)
  {
    m_canvas->Snap(&x, &y);

    wxRealPoint pt = wxRealPoint(x, y);

    // Move the control point back to where it was;
    // MoveControlPoint will move it to the new position
    // if it decides it wants. We only moved the position
    // during user feedback so we could redraw the line
    // as it changed shape.
    lpt->m_xpos = lpt->m_originalPos.x; lpt->m_ypos = lpt->m_originalPos.y;
    lpt->m_point->x = lpt->m_originalPos.x; lpt->m_point->y = lpt->m_originalPos.y;

    OnMoveMiddleControlPoint(dc, lpt, pt);
  }
  if (lpt->m_type == CONTROL_POINT_ENDPOINT_FROM)
  {
    if (lpt->m_oldCursor)
      m_canvas->SetCursor(* lpt->m_oldCursor);

//    this->Erase(dc);

//    lpt->m_xpos = x; lpt->m_ypos = y;

    if (lineShape->GetFrom())
    {
      lineShape->GetFrom()->MoveLineToNewAttachment(dc, lineShape, x, y);
    }
  }
  if (lpt->m_type == CONTROL_POINT_ENDPOINT_TO)
  {
    if (lpt->m_oldCursor)
      m_canvas->SetCursor(* lpt->m_oldCursor);

//    lpt->m_xpos = x; lpt->m_ypos = y;

    if (lineShape->GetTo())
    {
      lineShape->GetTo()->MoveLineToNewAttachment(dc, lineShape, x, y);
    }
  }

  // Needed?
#if 0
  int i = 0;
  for (i = 0; i < lineShape->GetLineControlPoints()->GetCount(); i++)
    if (((wxRealPoint *)(lineShape->GetLineControlPoints()->Item(i)->GetData())) == lpt->m_point)
      break;

  // N.B. in OnMoveControlPoint, an event handler in Hardy could have deselected
  // the line and therefore deleted 'this'. -> GPF, intermittently.
  // So assume at this point that we've been blown away.

  lineShape->OnMoveControlPoint(i+1, x, y);
#endif
}

// This is called only when a non-end control point is moved.
bool wxLineShape::OnMoveMiddleControlPoint(wxDC& dc, wxLineControlPoint* lpt, const wxRealPoint& pt)
{
    lpt->m_xpos = pt.x; lpt->m_ypos = pt.y;
    lpt->m_point->x = pt.x; lpt->m_point->y = pt.y;

    GetEventHandler()->OnMoveLink(dc);

    return true;
}

// Implement movement of endpoint to a new attachment
// OBSOLETE: done by dragging with the left button.

#if 0
void wxLineControlPoint::OnDragRight(bool draw, double x, double y, int keys, int attachment)
{
  if (m_type == CONTROL_POINT_ENDPOINT_FROM || m_type == CONTROL_POINT_ENDPOINT_TO)
  {
    m_xpos = x; m_ypos = y;
  }
}

void wxLineControlPoint::OnBeginDragRight(double x, double y, int keys, int attachment)
{
  wxClientDC dc(GetCanvas());
  GetCanvas()->PrepareDC(dc);

  wxLineShape *lineShape = (wxLineShape *)m_shape;
  if (m_type == CONTROL_POINT_ENDPOINT_FROM || m_type == CONTROL_POINT_ENDPOINT_TO)
  {
    Erase(dc);
    lineShape->GetEventHandler()->OnDraw(dc);
    if (m_type == CONTROL_POINT_ENDPOINT_FROM)
    {
      lineShape->GetFrom()->GetEventHandler()->OnDraw(dc);
      lineShape->GetFrom()->GetEventHandler()->OnDrawContents(dc);
    }
    else
    {
      lineShape->GetTo()->GetEventHandler()->OnDraw(dc);
      lineShape->GetTo()->GetEventHandler()->OnDrawContents(dc);
    }
    m_canvas->SetCursor(wxCursor(wxCURSOR_BULLSEYE));
    m_oldCursor = wxSTANDARD_CURSOR;
  }
}

void wxLineControlPoint::OnEndDragRight(double x, double y, int keys, int attachment)
{
  wxClientDC dc(GetCanvas());
  GetCanvas()->PrepareDC(dc);

  wxLineShape *lineShape = (wxLineShape *)m_shape;
  if (m_type == CONTROL_POINT_ENDPOINT_FROM)
  {
    if (m_oldCursor)
      m_canvas->SetCursor(m_oldCursor);

    m_xpos = x; m_ypos = y;

    if (lineShape->GetFrom())
    {
      lineShape->GetFrom()->EraseLinks(dc);

      int new_attachment;
      double distance;

      if (lineShape->GetFrom()->HitTest(x, y, &new_attachment, &distance))
        lineShape->SetAttachments(new_attachment, lineShape->GetAttachmentTo());

      lineShape->GetFrom()->MoveLinks(dc);
    }
  }
  if (m_type == CONTROL_POINT_ENDPOINT_TO)
  {
    if (m_oldCursor)
      m_canvas->SetCursor(m_oldCursor);
    m_shape->Erase(dc);

    m_xpos = x; m_ypos = y;

    if (lineShape->GetTo())
    {
      lineShape->GetTo()->EraseLinks(dc);

      int new_attachment;
      double distance;
      if (lineShape->GetTo()->HitTest(x, y, &new_attachment, &distance))
        lineShape->SetAttachments(lineShape->GetAttachmentFrom(), new_attachment);

      lineShape->GetTo()->MoveLinks(dc);
    }
  }
  int i = 0;
  for (i = 0; i < lineShape->GetLineControlPoints()->GetCount(); i++)
    if (((wxRealPoint *)(lineShape->GetLineControlPoints()->Item(i)->GetData())) == m_point)
      break;
  lineShape->OnMoveControlPoint(i+1, x, y);
  if (!m_canvas->GetQuickEditMode()) m_canvas->Redraw(dc);
}
#endif

/*
 * Get the point on the given line (x1, y1) (x2, y2)
 * distance 'length' along from the end,
 * returned values in x and y
 */

void GetPointOnLine(double x1, double y1, double x2, double y2,
                    double length, double *x, double *y)
{
  double l = (double)sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1));

  if (l < 0.01)
    l = (double) 0.01;

  double i_bar = (x2 - x1)/l;
  double j_bar = (y2 - y1)/l;

  *x = (- length*i_bar) + x2;
  *y = (- length*j_bar) + y2;
}

wxArrowHead *wxLineShape::AddArrow(WXTYPE type, int end, double size, double xOffset,
    const wxString& name, wxPseudoMetaFile *mf, long arrowId)
{
  wxArrowHead *arrow = new wxArrowHead(type, end, size, xOffset, name, mf, arrowId);
  m_arcArrows.Append(arrow);
  return arrow;
}

/*
 * Add arrowhead at a particular position in the arrowhead list.
 */
bool wxLineShape::AddArrowOrdered(wxArrowHead *arrow, wxList& referenceList, int end)
{
  wxNode *refNode = referenceList.GetFirst();
  wxNode *currNode = m_arcArrows.GetFirst();
  wxString targetName(arrow->GetName());
  if (!refNode) return false;

  // First check whether we need to insert in front of list,
  // because this arrowhead is the first in the reference
  // list and should therefore be first in the current list.
  wxArrowHead *refArrow = (wxArrowHead *)refNode->GetData();
  if (refArrow->GetName() == targetName)
  {
    m_arcArrows.Insert(arrow);
    return true;
  }

  wxArrowHead *currArrow = (wxArrowHead *)currNode->GetData();
  while (refNode && currNode)
  {
    refArrow = (wxArrowHead *)refNode->GetData();

    // Matching: advance current arrow pointer
    if ((currArrow->GetArrowEnd() == end) &&
        (currArrow->GetName() == refArrow->GetName()))
    {
      currNode = currNode->GetNext(); // Could be NULL now
      if (currNode)
        currArrow = (wxArrowHead *)currNode->GetData();
    }

    // Check if we're at the correct position in the
    // reference list
    if (targetName == refArrow->GetName())
    {
      if (currNode)
        m_arcArrows.Insert(currNode, arrow);
      else
        m_arcArrows.Append(arrow);
      return true;
    }
    refNode = refNode->GetNext();
  }
  m_arcArrows.Append(arrow);
  return true;
}

void wxLineShape::ClearArrowsAtPosition(int end)
{
  wxNode *node = m_arcArrows.GetFirst();
  while (node)
  {
    wxArrowHead *arrow = (wxArrowHead *)node->GetData();
    wxNode *next = node->GetNext();
    switch (end)
    {
      case -1:
      {
        delete arrow;
        delete node;
        break;
      }
      case ARROW_POSITION_START:
      {
        if (arrow->GetArrowEnd() == ARROW_POSITION_START)
        {
          delete arrow;
          delete node;
        }
        break;
      }
      case ARROW_POSITION_END:
      {
        if (arrow->GetArrowEnd() == ARROW_POSITION_END)
        {
          delete arrow;
          delete node;
        }
        break;
      }
      case ARROW_POSITION_MIDDLE:
      {
        if (arrow->GetArrowEnd() == ARROW_POSITION_MIDDLE)
        {
          delete arrow;
          delete node;
        }
        break;
      }
    }
    node = next;
  }
}

bool wxLineShape::ClearArrow(const wxString& name)
{
  wxNode *node = m_arcArrows.GetFirst();
  while (node)
  {
    wxArrowHead *arrow = (wxArrowHead *)node->GetData();
    if (arrow->GetName() == name)
    {
      delete arrow;
      delete node;
      return true;
    }
    node = node->GetNext();
  }
  return false;
}

/*
 * Finds an arrowhead at the given position (if -1, any position)
 *
 */

wxArrowHead *wxLineShape::FindArrowHead(int position, const wxString& name)
{
  wxNode *node = m_arcArrows.GetFirst();
  while (node)
  {
    wxArrowHead *arrow = (wxArrowHead *)node->GetData();
    if (((position == -1) || (position == arrow->GetArrowEnd())) &&
        (arrow->GetName() == name))
      return arrow;
    node = node->GetNext();
  }
  return NULL;
}

wxArrowHead *wxLineShape::FindArrowHead(long arrowId)
{
  wxNode *node = m_arcArrows.GetFirst();
  while (node)
  {
    wxArrowHead *arrow = (wxArrowHead *)node->GetData();
    if (arrowId == arrow->GetId())
      return arrow;
    node = node->GetNext();
  }
  return NULL;
}

/*
 * Deletes an arrowhead at the given position (if -1, any position)
 *
 */

bool wxLineShape::DeleteArrowHead(int position, const wxString& name)
{
  wxNode *node = m_arcArrows.GetFirst();
  while (node)
  {
    wxArrowHead *arrow = (wxArrowHead *)node->GetData();
    if (((position == -1) || (position == arrow->GetArrowEnd())) &&
        (arrow->GetName() == name))
    {
      delete arrow;
      delete node;
      return true;
    }
    node = node->GetNext();
  }
  return false;
}

// Overloaded DeleteArrowHead: pass arrowhead id.
bool wxLineShape::DeleteArrowHead(long id)
{
  wxNode *node = m_arcArrows.GetFirst();
  while (node)
  {
    wxArrowHead *arrow = (wxArrowHead *)node->GetData();
    if (arrow->GetId() == id)
    {
      delete arrow;
      delete node;
      return true;
    }
    node = node->GetNext();
  }
  return false;
}

/*
 * Calculate the minimum width a line
 * occupies, for the purposes of drawing lines in tools.
 *
 */

double wxLineShape::FindMinimumWidth()
{
  double minWidth = 0.0;
  wxNode *node = m_arcArrows.GetFirst();
  while (node)
  {
    wxArrowHead *arrowHead = (wxArrowHead *)node->GetData();
    minWidth += arrowHead->GetSize();
    if (node->GetNext())
      minWidth += arrowHead->GetSpacing();

    node = node->GetNext();
  }
  // We have ABSOLUTE minimum now. So
  // scale it to give it reasonable aesthetics
  // when drawing with line.
  if (minWidth > 0.0)
    minWidth = (double)(minWidth * 1.4);
  else
    minWidth = 20.0;

  SetEnds(0.0, 0.0, minWidth, 0.0);
  Initialise();

  return minWidth;
}

// Find which position we're talking about at this (x, y).
// Returns ARROW_POSITION_START, ARROW_POSITION_MIDDLE, ARROW_POSITION_END
int wxLineShape::FindLinePosition(double x, double y)
{
  double startX, startY, endX, endY;
  GetEnds(&startX, &startY, &endX, &endY);

  // Find distances from centre, start and end. The smallest wins.
  double centreDistance = (double)(sqrt((x - m_xpos)*(x - m_xpos) + (y - m_ypos)*(y - m_ypos)));
  double startDistance = (double)(sqrt((x - startX)*(x - startX) + (y - startY)*(y - startY)));
  double endDistance = (double)(sqrt((x - endX)*(x - endX) + (y - endY)*(y - endY)));

  if (centreDistance < startDistance && centreDistance < endDistance)
    return ARROW_POSITION_MIDDLE;
  else if (startDistance < endDistance)
    return ARROW_POSITION_START;
  else
    

⌨️ 快捷键说明

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