| 1 | ///////////////////////////////////////////////////////////////////////////// |
| 2 | // Name: shapes.h |
| 3 | // Purpose: Shape classes |
| 4 | // Author: Julian Smart |
| 5 | // Modified by: |
| 6 | // Created: 12/07/98 |
| 7 | // RCS-ID: $Id$ |
| 8 | // Copyright: (c) Julian Smart |
| 9 | // Licence: |
| 10 | ///////////////////////////////////////////////////////////////////////////// |
| 11 | |
| 12 | #ifndef _STUDIO_SHAPES_H_ |
| 13 | #define _STUDIO_SHAPES_H_ |
| 14 | |
| 15 | #ifdef __GNUG__ |
| 16 | // #pragma interface |
| 17 | #endif |
| 18 | |
| 19 | #include <wx/docview.h> |
| 20 | #include <wx/string.h> |
| 21 | #include <wx/wxexpr.h> |
| 22 | |
| 23 | #include "ogl.h" |
| 24 | #include "basicp.h" |
| 25 | #include "linesp.h" |
| 26 | #include "drawn.h" |
| 27 | |
| 28 | class csDiagramDocument; |
| 29 | |
| 30 | /* |
| 31 | * Override a few members for this application |
| 32 | */ |
| 33 | |
| 34 | class csDiagram: public wxDiagram |
| 35 | { |
| 36 | DECLARE_CLASS(csDiagram) |
| 37 | public: |
| 38 | csDiagram(csDiagramDocument* doc) { m_doc = doc; } |
| 39 | ~csDiagram(); |
| 40 | bool OnShapeSave(wxExprDatabase& db, wxShape& shape, wxExpr& expr); |
| 41 | bool OnShapeLoad(wxExprDatabase& db, wxShape& shape, wxExpr& expr); |
| 42 | |
| 43 | inline csDiagramDocument* GetDocument() const { return m_doc; } |
| 44 | virtual void Redraw(wxDC& dc); |
| 45 | |
| 46 | protected: |
| 47 | csDiagramDocument* m_doc; |
| 48 | }; |
| 49 | |
| 50 | class wxDiagramClipboard: public wxDiagram |
| 51 | { |
| 52 | DECLARE_DYNAMIC_CLASS(wxDiagramClipboard) |
| 53 | public: |
| 54 | wxDiagramClipboard() {} |
| 55 | ~wxDiagramClipboard() {} |
| 56 | |
| 57 | // Copy selection to clipboard |
| 58 | bool Copy(wxDiagram* diagram); |
| 59 | |
| 60 | // Copy contents to the diagram, with new ids. |
| 61 | // If dc is non-NULL, the pasted shapes will be selected. |
| 62 | // The offsets are used to place the shapes at a different position |
| 63 | // from the original (for example, for duplicating shapes). |
| 64 | bool Paste(wxDiagram* diagram, wxDC* dc = NULL, |
| 65 | int offsetX = 0, int offsetY = 0); |
| 66 | |
| 67 | #ifdef __WXMSW__ |
| 68 | // Draw contents to a Windows metafile device context and bitmap, and then copy |
| 69 | // to the Windows clipboard. |
| 70 | bool CopyToClipboard(double scale); |
| 71 | #endif |
| 72 | |
| 73 | // Overridables |
| 74 | // Start/end copying |
| 75 | virtual bool OnStartCopy(wxDiagram* diagramTo) { return TRUE; }; |
| 76 | virtual bool OnEndCopy(wxDiagram* diagramTo) { return TRUE; }; |
| 77 | |
| 78 | // Override this to e.g. have the shape added through a Do/Undo command system. |
| 79 | // By default, we'll just add it directly to the destination diagram, and |
| 80 | // select the shape (if dc is non-NULL). |
| 81 | virtual bool OnAddShape(wxDiagram* diagramTo, wxShape* newShape, wxDC* dc); |
| 82 | |
| 83 | protected: |
| 84 | bool DoCopy(wxDiagram* diagramFrom, wxDiagram* diagramTo, bool newIds, |
| 85 | wxDC* dc, int offsetX = 0, int offsetY = 0); |
| 86 | |
| 87 | }; |
| 88 | |
| 89 | class csDiagramCommand; |
| 90 | |
| 91 | class csDiagramClipboard: public wxDiagramClipboard |
| 92 | { |
| 93 | DECLARE_DYNAMIC_CLASS(csDiagramClipboard) |
| 94 | public: |
| 95 | csDiagramClipboard() { m_currentCmd = NULL; } |
| 96 | ~csDiagramClipboard() {} |
| 97 | |
| 98 | // Start/end copying |
| 99 | bool OnStartCopy(wxDiagram* diagramTo); |
| 100 | bool OnEndCopy(wxDiagram* diagramTo); |
| 101 | |
| 102 | bool OnAddShape(wxDiagram* diagramTo, wxShape* newShape, wxDC* dc); |
| 103 | |
| 104 | protected: |
| 105 | csDiagramCommand* m_currentCmd; |
| 106 | }; |
| 107 | |
| 108 | |
| 109 | /* |
| 110 | * The Studio shapes |
| 111 | * N.B. TODO: these should really all have another constructor |
| 112 | * for the ready-initialised shape, with the default one not having any |
| 113 | * data. Otherwise when copying a shape, you have to delete the old data |
| 114 | * first -> slightly less efficient. The initialised shapes are only required |
| 115 | * for the first creation of the shape in the palette, everything else is copied. |
| 116 | */ |
| 117 | |
| 118 | class csThinRectangleShape: public wxDrawnShape |
| 119 | { |
| 120 | DECLARE_DYNAMIC_CLASS(csThinRectangleShape) |
| 121 | public: |
| 122 | csThinRectangleShape(); |
| 123 | }; |
| 124 | |
| 125 | class csWideRectangleShape: public wxDrawnShape |
| 126 | { |
| 127 | DECLARE_DYNAMIC_CLASS(csWideRectangleShape) |
| 128 | public: |
| 129 | csWideRectangleShape(); |
| 130 | }; |
| 131 | |
| 132 | class csTriangleShape: public wxDrawnShape |
| 133 | { |
| 134 | DECLARE_DYNAMIC_CLASS(csTriangleShape) |
| 135 | public: |
| 136 | csTriangleShape(); |
| 137 | }; |
| 138 | |
| 139 | class csSemiCircleShape: public wxDrawnShape |
| 140 | { |
| 141 | DECLARE_DYNAMIC_CLASS(csSemiCircleShape) |
| 142 | public: |
| 143 | csSemiCircleShape(); |
| 144 | }; |
| 145 | |
| 146 | class csCircleShape: public wxCircleShape |
| 147 | { |
| 148 | DECLARE_DYNAMIC_CLASS(csCircleShape) |
| 149 | public: |
| 150 | csCircleShape(); |
| 151 | }; |
| 152 | |
| 153 | class csCircleShadowShape: public wxCircleShape |
| 154 | { |
| 155 | DECLARE_DYNAMIC_CLASS(csCircleShadowShape) |
| 156 | public: |
| 157 | csCircleShadowShape(); |
| 158 | }; |
| 159 | |
| 160 | class csOctagonShape: public wxPolygonShape |
| 161 | { |
| 162 | DECLARE_DYNAMIC_CLASS(csOctagonShape) |
| 163 | public: |
| 164 | csOctagonShape(); |
| 165 | |
| 166 | // The attachments are as if it's a rectangle |
| 167 | bool GetAttachmentPosition(int attachment, double *x, double *y, |
| 168 | int nth = 0, int no_arcs = 1, wxLineShape *line = NULL) |
| 169 | { return wxShape::GetAttachmentPosition(attachment, x, y, nth, no_arcs, line); } |
| 170 | int GetNumberOfAttachments() const |
| 171 | { return wxShape::GetNumberOfAttachments(); } |
| 172 | bool AttachmentIsValid(int attachment) const |
| 173 | { return wxShape::AttachmentIsValid(attachment); } |
| 174 | }; |
| 175 | |
| 176 | // This is a transparent shape for drawing around other shapes. |
| 177 | class csGroupShape: public wxRectangleShape |
| 178 | { |
| 179 | DECLARE_DYNAMIC_CLASS(csGroupShape) |
| 180 | public: |
| 181 | csGroupShape(); |
| 182 | |
| 183 | void OnDraw(wxDC& dc); |
| 184 | // Must modify the hit-test so it doesn't obscure shapes that are inside. |
| 185 | bool HitTest(double x, double y, int* attachment, double* distance); |
| 186 | }; |
| 187 | |
| 188 | class csTextBoxShape: public wxRectangleShape |
| 189 | { |
| 190 | DECLARE_DYNAMIC_CLASS(csTextBoxShape) |
| 191 | public: |
| 192 | csTextBoxShape(); |
| 193 | }; |
| 194 | |
| 195 | class csLineShape: public wxLineShape |
| 196 | { |
| 197 | DECLARE_DYNAMIC_CLASS(csLineShape) |
| 198 | public: |
| 199 | csLineShape(); |
| 200 | |
| 201 | virtual bool OnMoveMiddleControlPoint(wxDC& dc, wxLineControlPoint* lpt, const wxRealPoint& pt); |
| 202 | wxLabelShape* OnCreateLabelShape(wxLineShape *parent = NULL, wxShapeRegion *region = NULL, double w = 0.0, double h = 0.0); |
| 203 | }; |
| 204 | |
| 205 | /* |
| 206 | * Temporary arc label object |
| 207 | */ |
| 208 | |
| 209 | class csLabelShape: public wxLabelShape |
| 210 | { |
| 211 | DECLARE_DYNAMIC_CLASS(csLabelShape) |
| 212 | |
| 213 | public: |
| 214 | csLabelShape(wxLineShape *parent = NULL, wxShapeRegion *region = NULL, double w = 0.0, double h = 0.0); |
| 215 | |
| 216 | void OnEndDragLeft(double x, double y, int keys=0, int attachment = 0); |
| 217 | }; |
| 218 | |
| 219 | /* |
| 220 | * All shape event behaviour is routed through this handler, so we don't |
| 221 | * have to derive from each shape class. We plug this in to each shape. |
| 222 | */ |
| 223 | |
| 224 | class csEvtHandler: public wxShapeEvtHandler |
| 225 | { |
| 226 | DECLARE_DYNAMIC_CLASS(csEvtHandler) |
| 227 | public: |
| 228 | csEvtHandler(wxShapeEvtHandler *prev = NULL, wxShape *shape = NULL, const wxString& lab = ""); |
| 229 | ~csEvtHandler(); |
| 230 | |
| 231 | void OnLeftClick(double x, double y, int keys = 0, int attachment = 0); |
| 232 | void OnRightClick(double x, double y, int keys = 0, int attachment = 0); |
| 233 | void OnBeginDragRight(double x, double y, int keys = 0, int attachment = 0); |
| 234 | void OnDragRight(bool draw, double x, double y, int keys = 0, int attachment = 0); |
| 235 | void OnEndDragRight(double x, double y, int keys = 0, int attachment = 0); |
| 236 | void OnEndSize(double x, double y); |
| 237 | void OnDragLeft(bool draw, double x, double y, int keys = 0, int attachment = 0); |
| 238 | void OnBeginDragLeft(double x, double y, int keys = 0, int attachment = 0); |
| 239 | void OnEndDragLeft(double x, double y, int keys = 0, int attachment = 0); |
| 240 | void OnSizingEndDragLeft(wxControlPoint* pt, double x, double y, int keys = 0, int attachment = 0); |
| 241 | void OnChangeAttachment(int attachment, wxLineShape* line, wxList& ordering); |
| 242 | |
| 243 | void OnLeftDoubleClick(double x, double y, int keys = 0, int attachment = 0); |
| 244 | |
| 245 | // Copy any event handler data |
| 246 | virtual void CopyData(wxShapeEvtHandler& copy); |
| 247 | |
| 248 | // Popup up a property dialog |
| 249 | virtual bool EditProperties(); |
| 250 | |
| 251 | public: |
| 252 | wxString m_label; |
| 253 | }; |
| 254 | |
| 255 | extern void studioShapeEditProc(wxMenu& menu, wxCommandEvent& event); |
| 256 | |
| 257 | #endif |
| 258 | // _STUDIO_SHAPES_H_ |