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

📄 lines.cpp

📁 wxGTK 是 wxWidgets 的 linux GTK+ (>2.2.3)版本。wxWidgets 是一个跨平台的 GUI 框架
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/////////////////////////////////////////////////////////////////////////////// Name:        lines.cpp// Purpose:     wxLineShape// Author:      Julian Smart// Modified by:// Created:     12/07/98// RCS-ID:      $Id: lines.cpp,v 1.27 2006/04/18 22:26:26 PC Exp $// Copyright:   (c) Julian Smart// Licence:     wxWindows licence/////////////////////////////////////////////////////////////////////////////// For compilers that support precompilation, includes "wx.h".#include "wx/wxprec.h"#ifdef __BORLANDC__#pragma hdrstop#endif#ifndef WX_PRECOMP#include "wx/wx.h"#endif#if wxUSE_PROLOGIO#include "wx/deprecated/wxexpr.h"#endif#ifdef new#undef new#endif#include <ctype.h>#include "wx/ogl/ogl.h"// Line shapeIMPLEMENT_DYNAMIC_CLASS(wxLineShape, wxShape)wxLineShape::wxLineShape(){  m_sensitivity = OP_CLICK_LEFT | OP_CLICK_RIGHT;  m_draggable = false;  m_attachmentTo = 0;  m_attachmentFrom = 0;/*  m_actualTextWidth = 0.0;  m_actualTextHeight = 0.0;*/  m_from = NULL;  m_to = NULL;  m_erasing = false;  m_arrowSpacing = 5.0; // For the moment, don't bother saving this to file.  m_ignoreArrowOffsets = false;  m_isSpline = false;  m_maintainStraightLines = false;  m_alignmentStart = 0;  m_alignmentEnd = 0;  m_lineControlPoints = NULL;  // Clear any existing regions (created in an earlier constructor)  // and make the three line regions.  ClearRegions();  wxShapeRegion *newRegion = new wxShapeRegion;  newRegion->SetName(wxT("Middle"));  newRegion->SetSize(150, 50);  m_regions.Append((wxObject *)newRegion);  newRegion = new wxShapeRegion;  newRegion->SetName(wxT("Start"));  newRegion->SetSize(150, 50);  m_regions.Append((wxObject *)newRegion);  newRegion = new wxShapeRegion;  newRegion->SetName(wxT("End"));  newRegion->SetSize(150, 50);  m_regions.Append((wxObject *)newRegion);  for (int i = 0; i < 3; i++)    m_labelObjects[i] = NULL;}wxLineShape::~wxLineShape(){  if (m_lineControlPoints)  {    ClearPointList(*m_lineControlPoints);    delete m_lineControlPoints;  }  for (int i = 0; i < 3; i++)  {    if (m_labelObjects[i])    {      m_labelObjects[i]->Select(false);      m_labelObjects[i]->RemoveFromCanvas(m_canvas);      delete m_labelObjects[i];      m_labelObjects[i] = NULL;    }  }  ClearArrowsAtPosition(-1);}void wxLineShape::MakeLineControlPoints(int n){  if (m_lineControlPoints)  {    ClearPointList(*m_lineControlPoints);    delete m_lineControlPoints;  }  m_lineControlPoints = new wxList;  for (int i = 0; i < n; i++)  {    wxRealPoint *point = new wxRealPoint(-999, -999);    m_lineControlPoints->Append((wxObject*) point);  }}wxNode *wxLineShape::InsertLineControlPoint(wxDC* dc){    if (dc)        Erase(*dc);  wxNode *last = m_lineControlPoints->GetLast();  wxNode *second_last = last->GetPrevious();  wxRealPoint *last_point = (wxRealPoint *)last->GetData();  wxRealPoint *second_last_point = (wxRealPoint *)second_last->GetData();  // Choose a point half way between the last and penultimate points  double line_x = ((last_point->x + second_last_point->x)/2);  double line_y = ((last_point->y + second_last_point->y)/2);  wxRealPoint *point = new wxRealPoint(line_x, line_y);  wxNode *node = m_lineControlPoints->Insert(last, (wxObject*) point);  return node;}bool wxLineShape::DeleteLineControlPoint(){  if (m_lineControlPoints->GetCount() < 3)    return false;  wxNode *last = m_lineControlPoints->GetLast();  wxNode *second_last = last->GetPrevious();  wxRealPoint *second_last_point = (wxRealPoint *)second_last->GetData();  delete second_last_point;  delete second_last;  return true;}void wxLineShape::Initialise(){  if (m_lineControlPoints)  {    // Just move the first and last control points    wxNode *first = m_lineControlPoints->GetFirst();    wxRealPoint *first_point = (wxRealPoint *)first->GetData();    wxNode *last = m_lineControlPoints->GetLast();    wxRealPoint *last_point = (wxRealPoint *)last->GetData();    // If any of the line points are at -999, we must    // initialize them by placing them half way between the first    // and the last.    wxNode *node = first->GetNext();    while (node)    {      wxRealPoint *point = (wxRealPoint *)node->GetData();      if (point->x == -999)      {        double x1, y1, x2, y2;        if (first_point->x < last_point->x)          { x1 = first_point->x; x2 = last_point->x; }        else          { x2 = first_point->x; x1 = last_point->x; }        if (first_point->y < last_point->y)          { y1 = first_point->y; y2 = last_point->y; }        else          { y2 = first_point->y; y1 = last_point->y; }        point->x = ((x2 - x1)/2 + x1);        point->y = ((y2 - y1)/2 + y1);      }      node = node->GetNext();    }  }}// Format a text string according to the region size, adding// strings with positions to region text listvoid wxLineShape::FormatText(wxDC& dc, const wxString& s, int i){  double w, h;  ClearText(i);  if (m_regions.GetCount() < 1)    return;  wxNode *node = m_regions.Item(i);  if (!node)    return;  wxShapeRegion *region = (wxShapeRegion *)node->GetData();  region->SetText(s);  dc.SetFont(* region->GetFont());  region->GetSize(&w, &h);  // Initialize the size if zero  if (((w == 0) || (h == 0)) && (s.Length() > 0))  {    w = 100; h = 50;    region->SetSize(w, h);  }  wxStringList *string_list = oglFormatText(dc, s, (w-5), (h-5), region->GetFormatMode());  node = (wxNode*)string_list->GetFirst();  while (node)  {    wxChar *s = (wxChar *)node->GetData();    wxShapeTextLine *line = new wxShapeTextLine(0.0, 0.0, s);    region->GetFormattedText().Append((wxObject *)line);    node = node->GetNext();  }  delete string_list;  double actualW = w;  double actualH = h;  if (region->GetFormatMode() & FORMAT_SIZE_TO_CONTENTS)  {    oglGetCentredTextExtent(dc, &(region->GetFormattedText()), m_xpos, m_ypos, w, h, &actualW, &actualH);    if ((actualW != w ) || (actualH != h))    {      double xx, yy;      GetLabelPosition(i, &xx, &yy);      EraseRegion(dc, region, xx, yy);      if (m_labelObjects[i])      {        m_labelObjects[i]->Select(false, &dc);        m_labelObjects[i]->Erase(dc);        m_labelObjects[i]->SetSize(actualW, actualH);      }      region->SetSize(actualW, actualH);      if (m_labelObjects[i])      {        m_labelObjects[i]->Select(true, & dc);        m_labelObjects[i]->Draw(dc);      }    }  }  oglCentreText(dc, &(region->GetFormattedText()), m_xpos, m_ypos, actualW, actualH, region->GetFormatMode());  m_formatted = true;}void wxLineShape::DrawRegion(wxDC& dc, wxShapeRegion *region, double x, double y){  if (GetDisableLabel())    return;  double w, h;  double xx, yy;  region->GetSize(&w, &h);  // Get offset from x, y  region->GetPosition(&xx, &yy);  double xp = xx + x;  double yp = yy + y;  // First, clear a rectangle for the text IF there is any  if (region->GetFormattedText().GetCount() > 0)  {      dc.SetPen(GetBackgroundPen());      dc.SetBrush(GetBackgroundBrush());      // Now draw the text      if (region->GetFont()) dc.SetFont(* region->GetFont());      dc.DrawRectangle((long)(xp - w/2.0), (long)(yp - h/2.0), (long)w, (long)h);      if (m_pen) dc.SetPen(* m_pen);      dc.SetTextForeground(region->GetActualColourObject());#ifdef __WXMSW__      dc.SetTextBackground(GetBackgroundBrush().GetColour());#endif      oglDrawFormattedText(dc, &(region->GetFormattedText()), xp, yp, w, h, region->GetFormatMode());  }}void wxLineShape::EraseRegion(wxDC& dc, wxShapeRegion *region, double x, double y){  if (GetDisableLabel())    return;  double w, h;  double xx, yy;  region->GetSize(&w, &h);  // Get offset from x, y  region->GetPosition(&xx, &yy);  double xp = xx + x;  double yp = yy + y;  if (region->GetFormattedText().GetCount() > 0)  {      dc.SetPen(GetBackgroundPen());      dc.SetBrush(GetBackgroundBrush());      dc.DrawRectangle((long)(xp - w/2.0), (long)(yp - h/2.0), (long)w, (long)h);  }}// Get the reference point for a label. Region x and y// are offsets from this.// position is 0, 1, 2void wxLineShape::GetLabelPosition(int position, double *x, double *y){  switch (position)  {    case 0:    {      // Want to take the middle section for the label      int n = m_lineControlPoints->GetCount();      int half_way = (int)(n/2);      // Find middle of this line      wxNode *node = m_lineControlPoints->Item(half_way - 1);      wxRealPoint *point = (wxRealPoint *)node->GetData();      wxNode *next_node = node->GetNext();      wxRealPoint *next_point = (wxRealPoint *)next_node->GetData();      double dx = (next_point->x - point->x);      double dy = (next_point->y - point->y);      *x = (double)(point->x + dx/2.0);      *y = (double)(point->y + dy/2.0);      break;    }    case 1:    {      wxNode *node = m_lineControlPoints->GetFirst();      *x = ((wxRealPoint *)node->GetData())->x;      *y = ((wxRealPoint *)node->GetData())->y;      break;    }    case 2:    {      wxNode *node = m_lineControlPoints->GetLast();      *x = ((wxRealPoint *)node->GetData())->x;      *y = ((wxRealPoint *)node->GetData())->y;      break;    }    default:      break;  }}/* * Find whether line is supposed to be vertical or horizontal and * make it so. * */void GraphicsStraightenLine(wxRealPoint *point1, wxRealPoint *point2){  double dx = point2->x - point1->x;  double dy = point2->y - point1->y;  if (dx == 0.0)    return;  else if (fabs(dy/dx) > 1.0)  {    point2->x = point1->x;  }  else point2->y = point1->y;}void wxLineShape::Straighten(wxDC *dc){  if (!m_lineControlPoints || m_lineControlPoints->GetCount() < 3)    return;  if (dc)    Erase(* dc);  wxNode *first_point_node = m_lineControlPoints->GetFirst();  wxNode *last_point_node = m_lineControlPoints->GetLast();  wxNode *second_last_point_node = last_point_node->GetPrevious();  wxRealPoint *last_point = (wxRealPoint *)last_point_node->GetData();  wxRealPoint *second_last_point = (wxRealPoint *)second_last_point_node->GetData();  GraphicsStraightenLine(last_point, second_last_point);  wxNode *node = first_point_node;  while (node && (node != second_last_point_node))  {    wxRealPoint *point = (wxRealPoint *)node->GetData();    wxRealPoint *next_point = (wxRealPoint *)(node->GetNext()->GetData());    GraphicsStraightenLine(point, next_point);    node = node->GetNext();  }  if (dc)    Draw(* dc);}void wxLineShape::Unlink(){  if (m_to)    m_to->GetLines().DeleteObject(this);  if (m_from)    m_from->GetLines().DeleteObject(this);  m_to = NULL;  m_from = NULL;}void wxLineShape::SetEnds(double x1, double y1, double x2, double y2){  // Find centre point  wxNode *first_point_node = m_lineControlPoints->GetFirst();  wxNode *last_point_node = m_lineControlPoints->GetLast();  wxRealPoint *first_point = (wxRealPoint *)first_point_node->GetData();  wxRealPoint *last_point = (wxRealPoint *)last_point_node->GetData();  first_point->x = x1;  first_point->y = y1;  last_point->x = x2;  last_point->y = y2;  m_xpos = (double)((x1 + x2)/2.0);  m_ypos = (double)((y1 + y2)/2.0);}// Get absolute positions of endsvoid wxLineShape::GetEnds(double *x1, double *y1, double *x2, double *y2){  wxNode *first_point_node = m_lineControlPoints->GetFirst();  wxNode *last_point_node = m_lineControlPoints->GetLast();  wxRealPoint *first_point = (wxRealPoint *)first_point_node->GetData();  wxRealPoint *last_point = (wxRealPoint *)last_point_node->GetData();  *x1 = first_point->x; *y1 = first_point->y;  *x2 = last_point->x; *y2 = last_point->y;}void wxLineShape::SetAttachments(int from_attach, int to_attach){  m_attachmentFrom = from_attach;  m_attachmentTo = to_attach;}bool wxLineShape::HitTest(double x, double y, int *attachment, double *distance){  if (!m_lineControlPoints)    return false;  // Look at label regions in case mouse is over a label  bool inLabelRegion = false;

⌨️ 快捷键说明

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