1 ///////////////////////////////////////////////////////////////////////////// 2 // Name: lines.h 3 // Purpose: wxLineShape 4 // Author: Julian Smart 5 // Modified by: 6 // Created: 12/07/98 7 // RCS-ID: $Id: lines.h 35650 2005-09-23 12:56:45Z MR $ 8 // Copyright: (c) Julian Smart 9 // Licence: wxWindows licence 10 ///////////////////////////////////////////////////////////////////////////// 11 12 #ifndef _OGL_LINES_H_ 13 #define _OGL_LINES_H_ 14 15 16 class WXDLLIMPEXP_OGL wxLabelShape; 17 class WXDLLIMPEXP_OGL wxPseudoMetaFile; 18 class WXDLLIMPEXP_OGL wxLineControlPoint; 19 /* 20 * Arcs with multiple arrowheads 21 * 22 */ 23 24 // Types of arrowhead 25 // (i) Built-in 26 #define ARROW_HOLLOW_CIRCLE 1 27 #define ARROW_FILLED_CIRCLE 2 28 #define ARROW_ARROW 3 29 #define ARROW_SINGLE_OBLIQUE 4 30 #define ARROW_DOUBLE_OBLIQUE 5 31 // (ii) Custom 32 #define ARROW_METAFILE 20 33 34 // Position of arrow on line 35 #define ARROW_POSITION_START 0 36 #define ARROW_POSITION_END 1 37 #define ARROW_POSITION_MIDDLE 2 38 39 // Line alignment flags 40 // Vertical by default 41 #define LINE_ALIGNMENT_HORIZ 1 42 #define LINE_ALIGNMENT_VERT 0 43 #define LINE_ALIGNMENT_TO_NEXT_HANDLE 2 44 #define LINE_ALIGNMENT_NONE 0 45 46 class WXDLLIMPEXP_OGL wxArrowHead: public wxObject 47 { 48 DECLARE_DYNAMIC_CLASS(wxArrowHead) 49 50 public: 51 wxArrowHead(WXTYPE type = 0, int end = 0, double size = 0.0, double dist = 0.0, const wxString& name = wxEmptyString, wxPseudoMetaFile *mf = NULL, 52 long arrowId = -1); 53 ~wxArrowHead(); 54 wxArrowHead(wxArrowHead& toCopy); 55 _GetType()56 inline WXTYPE _GetType() const { return m_arrowType; } GetPosition()57 inline int GetPosition() const { return m_arrowEnd; } SetPosition(int pos)58 inline void SetPosition(int pos) { m_arrowEnd = pos; } GetXOffset()59 inline double GetXOffset() const { return m_xOffset; } GetYOffset()60 inline double GetYOffset() const { return m_yOffset; } GetSpacing()61 inline double GetSpacing() const { return m_spacing; } GetSize()62 inline double GetSize() const { return m_arrowSize; } GetName()63 inline wxString GetName() const { return m_arrowName; } SetXOffset(double x)64 inline void SetXOffset(double x) { m_xOffset = x; } SetYOffset(double y)65 inline void SetYOffset(double y) { m_yOffset = y; } GetMetaFile()66 inline wxPseudoMetaFile *GetMetaFile() const { return m_metaFile; } GetId()67 inline long GetId() const { return m_id; } GetArrowEnd()68 inline int GetArrowEnd() const { return m_arrowEnd; } GetArrowSize()69 inline double GetArrowSize() const { return m_arrowSize; } 70 void SetSize(double size); SetSpacing(double sp)71 inline void SetSpacing(double sp) { m_spacing = sp; } 72 73 protected: 74 WXTYPE m_arrowType; 75 int m_arrowEnd; // Position on line 76 double m_xOffset; // Distance from arc start or end, w.r.t. point on arrowhead 77 // nearest start or end. If zero, use default spacing. 78 double m_yOffset; // vertical offset (w.r.t. a horizontal line). Normally zero. 79 double m_spacing; // Spacing from the last arrowhead 80 double m_arrowSize; // Length of arrowhead 81 wxString m_arrowName; // Name of arrow 82 bool m_saveToFile; // true if we want to save custom arrowheads to file. 83 wxPseudoMetaFile* m_metaFile; // Pseudo metafile if this is a custom arrowhead 84 long m_id; // identifier 85 }; 86 87 // Line object 88 class WXDLLIMPEXP_OGL wxLabelShape; 89 class WXDLLIMPEXP_OGL wxLineShape: public wxShape 90 { 91 DECLARE_DYNAMIC_CLASS(wxLineShape) 92 93 public: 94 wxLineShape(); 95 ~wxLineShape(); 96 97 // Called when a connected object has moved, to move the link to 98 // correct position 99 // moveControlPoints must be disabled when a control point is being 100 // dragged. 101 void OnMoveLink(wxDC& dc, bool moveControlPoints = true); 102 bool OnMovePre(wxDC& dc, double x, double y, double old_x, double old_y, bool display = true); 103 void OnDraw(wxDC& dc); 104 void OnDrawContents(wxDC& dc); 105 void OnDrawControlPoints(wxDC& dc); 106 void OnEraseControlPoints(wxDC& dc); 107 void OnErase(wxDC& dc); OnMoveControlPoint(int WXUNUSED (which),double WXUNUSED (x),double WXUNUSED (y))108 virtual bool OnMoveControlPoint(int WXUNUSED(which), double WXUNUSED(x), double WXUNUSED(y)) { return false; } 109 virtual bool OnMoveMiddleControlPoint(wxDC& dc, wxLineControlPoint* lpt, const wxRealPoint& pt); 110 virtual bool OnLabelMovePre(wxDC& dc, wxLabelShape* labelShape, double x, double y, double old_x, double old_y, bool display); 111 void OnDrawOutline(wxDC& dc, double x, double y, double w, double h); 112 void GetBoundingBoxMin(double *w, double *h); 113 void FormatText(wxDC& dc, const wxString& s, int regionId = 0); 114 virtual void SetEnds(double x1, double y1, double x2, double y2); 115 virtual void GetEnds(double *x1, double *y1, double *x2, double *y2); GetFrom()116 inline virtual wxShape *GetFrom() { return m_from; } GetTo()117 inline virtual wxShape *GetTo() { return m_to; } GetAttachmentFrom()118 inline virtual int GetAttachmentFrom() { return m_attachmentFrom; } GetAttachmentTo()119 inline virtual int GetAttachmentTo() { return m_attachmentTo; } 120 121 virtual void SetFrom(wxShape *object); 122 virtual void SetTo(wxShape *object); 123 virtual void DrawArrows(wxDC& dc); 124 125 // Finds the x, y points at the two ends of the line. 126 // This function can be used by e.g. line-routing routines to 127 // get the actual points on the two node images where the lines will be drawn 128 // to/from. 129 void FindLineEndPoints(double *fromX, double *fromY, double *toX, double *toY); 130 131 // Format one region at this position 132 void DrawRegion(wxDC& dc, wxShapeRegion *region, double x, double y); 133 134 // Erase one region at this position 135 void EraseRegion(wxDC& dc, wxShapeRegion *region, double x, double y); 136 137 // Get the reference point for a label. Region x and y 138 // are offsets from this. 139 // position is 0 (middle), 1 (start), 2 (end) 140 void GetLabelPosition(int position, double *x, double *y); 141 142 // Can override this to create a different class of label shape 143 virtual wxLabelShape* OnCreateLabelShape(wxLineShape *parent = NULL, wxShapeRegion *region = NULL, double w = 0.0, double h = 0.0); 144 145 // Straighten verticals and horizontals 146 virtual void Straighten(wxDC* dc = NULL); 147 148 // Not implemented SetMaintainStraightLines(bool flag)149 inline void SetMaintainStraightLines(bool flag) { m_maintainStraightLines = flag; } GetMaintainStraightLines()150 inline bool GetMaintainStraightLines() const { return m_maintainStraightLines; } 151 152 // Make handle control points 153 void MakeControlPoints(); 154 void ResetControlPoints(); 155 156 // Make a given number of control points 157 virtual void MakeLineControlPoints(int n); 158 virtual wxNode *InsertLineControlPoint(wxDC* dc); 159 virtual bool DeleteLineControlPoint(); 160 virtual void Initialise(); GetLineControlPoints()161 inline wxList *GetLineControlPoints() { return m_lineControlPoints; } 162 163 // Override dragging behaviour - don't want to be able to drag lines! 164 void OnDragLeft(bool draw, double x, double y, int keys=0, int attachment = 0); 165 void OnBeginDragLeft(double x, double y, int keys=0, int attachment = 0); 166 void OnEndDragLeft(double x, double y, int keys=0, int attachment = 0); 167 168 // Control points ('handles') redirect control to the actual shape, to make it easier 169 // to override sizing behaviour. 170 virtual void OnSizingDragLeft(wxControlPoint* pt, bool draw, double x, double y, int keys=0, int attachment = 0); 171 virtual void OnSizingBeginDragLeft(wxControlPoint* pt, double x, double y, int keys=0, int attachment = 0); 172 virtual void OnSizingEndDragLeft(wxControlPoint* pt, double x, double y, int keys=0, int attachment = 0); 173 174 // Override select, to create/delete temporary label-moving objects 175 void Select(bool select = true, wxDC* dc = NULL); 176 177 // Set to spline (true) or line (false) SetSpline(bool spl)178 inline void SetSpline(bool spl) { m_isSpline = spl; } IsSpline()179 inline bool IsSpline() const { return m_isSpline; } 180 181 void Unlink(); 182 void SetAttachments(int from_attach, int to_attach); SetAttachmentFrom(int attach)183 inline void SetAttachmentFrom(int attach) { m_attachmentFrom = attach; } SetAttachmentTo(int attach)184 inline void SetAttachmentTo(int attach) { m_attachmentTo = attach; } 185 186 bool HitTest(double x, double y, int *attachment, double *distance); 187 188 #if wxUSE_PROLOGIO 189 // I/O 190 virtual void WriteAttributes(wxExpr *clause); 191 virtual void ReadAttributes(wxExpr *clause); 192 #endif 193 194 virtual void FindNth(wxShape *image, int *nth, int *no_arcs, bool incoming); 195 196 // Find which position we're talking about at this (x, y). 197 // Returns ARROW_POSITION_START, ARROW_POSITION_MIDDLE, ARROW_POSITION_END 198 int FindLinePosition(double x, double y); 199 200 // This is really to distinguish between lines and other images. 201 // For lines, want to pass drag to canvas, since lines tend to prevent 202 // dragging on a canvas (they get in the way.) Draggable()203 virtual bool Draggable() const { return false; } 204 205 // Does the copying for this object 206 void Copy(wxShape& copy); 207 208 // Add an arrowhead. 209 wxArrowHead *AddArrow(WXTYPE type, int end = ARROW_POSITION_END, 210 double arrowSize = 10.0, double xOffset = 0.0, 211 const wxString& name = wxEmptyString, 212 wxPseudoMetaFile *mf = NULL, long arrowId = -1); 213 214 // Add an arrowhead in the position indicated by the reference 215 // list of arrowheads, which contains all legal arrowheads for this 216 // line, in the correct order. 217 // E.g. reference list: a b c d e 218 // Current line list: a d 219 // Add c, then line list is: a c d 220 // If no legal arrowhead position, return false. 221 // Assume reference list is for one end only, since it potentially defines 222 // the ordering for any one of the 3 positions. So we don't check 223 // the reference list for arrowhead position. 224 bool AddArrowOrdered(wxArrowHead *arrow, wxList& referenceList, int end); 225 226 // Delete arrowhead(s) 227 void ClearArrowsAtPosition(int end = -1); 228 bool ClearArrow(const wxString& name); 229 wxArrowHead *FindArrowHead(int position, const wxString& name); 230 wxArrowHead *FindArrowHead(long arrowId); 231 bool DeleteArrowHead(int position, const wxString& name); 232 bool DeleteArrowHead(long arrowId); 233 void DrawArrow(wxDC& dc, wxArrowHead *arrow, double xOffset, bool proportionalOffset); SetIgnoreOffsets(bool ignore)234 inline void SetIgnoreOffsets(bool ignore) { m_ignoreArrowOffsets = ignore; } GetArrows()235 inline wxList& GetArrows() const { return (wxList&) m_arcArrows; } 236 237 // Find horizontal width for drawing a line with 238 // arrows in minimum space. Assume arrows at 239 // END only 240 double FindMinimumWidth(); 241 242 // Set alignment flags. ALIGNMENT NOT IMPLEMENTED. 243 void SetAlignmentOrientation(bool isEnd, bool isHoriz); 244 void SetAlignmentType(bool isEnd, int alignType); 245 bool GetAlignmentOrientation(bool isEnd); 246 int GetAlignmentType(bool isEnd); GetAlignmentStart()247 int GetAlignmentStart() const { return m_alignmentStart; } GetAlignmentEnd()248 int GetAlignmentEnd() const { return m_alignmentEnd; } 249 250 // Find next control point in line after the start/end point 251 // (depending on whether the node object is at start or end) 252 wxRealPoint *GetNextControlPoint(wxShape *nodeObject); IsEnd(wxShape * nodeObject)253 inline bool IsEnd(wxShape *nodeObject) const { return (m_to == nodeObject); } 254 255 private: 256 bool m_erasing; // flag to say whether we're erasing or drawing 257 // this line (really so metafiles can draw a 258 // blank rectangle) 259 bool m_ignoreArrowOffsets; // Don't always want to draw arrowhead offsets 260 // because they may not work on tool palettes (for example) 261 bool m_isSpline; 262 bool m_maintainStraightLines; 263 264 protected: 265 // Temporary list of line segment orientations 266 // so we know what direction the line is supposed to be dog-legging 267 // in. The values are integer: 0 for vertical, 1 for horizontal. 268 wxList m_lineOrientations; 269 270 // Temporary pointers for start, middle and end label editing objects 271 // (active only when the line is selected) 272 wxLabelShape* m_labelObjects[3]; 273 274 // These define the segmented line - not to be confused with temporary control 275 // points which appear when object is selected (although in this case they'll 276 // probably be the same) 277 wxList* m_lineControlPoints; 278 279 double m_arrowSpacing; // Separation between adjacent arrows 280 281 wxShape* m_to; 282 wxShape* m_from; 283 284 int m_attachmentTo; // Attachment point at one end 285 int m_attachmentFrom; // Attachment point at other end 286 287 // Alignment flags 288 int m_alignmentStart; 289 int m_alignmentEnd; 290 291 wxList m_arcArrows; 292 293 }; 294 295 #endif 296 // _OGL_LINES_H_ 297