1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxCompositeShape
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #ifndef _OGL_COMPOSIT_H_
13 #define _OGL_COMPOSIT_H_
16 class WXDLLIMPEXP_OGL wxDivisionShape
;
17 class WXDLLIMPEXP_OGL wxOGLConstraint
;
20 * A composite object is an invisible rectangle surrounding all children
24 class WXDLLIMPEXP_OGL wxCompositeShape
: public wxRectangleShape
26 DECLARE_DYNAMIC_CLASS(wxCompositeShape
)
32 void OnDraw(wxDC
& dc
);
33 void OnDrawContents(wxDC
& dc
);
34 void OnErase(wxDC
& dc
);
35 bool OnMovePre(wxDC
& dc
, double x
, double y
, double oldX
, double oldY
, bool display
= true);
36 void OnDragLeft(bool draw
, double x
, double y
, int keys
, int attachment
= 0);
37 void OnBeginDragLeft(double x
, double y
, int keys
, int attachment
= 0);
38 void OnEndDragLeft(double x
, double y
, int keys
, int attachment
= 0);
40 void OnRightClick(double x
, double y
, int keys
, int attachment
= 0);
42 void SetSize(double w
, double h
, bool recursive
= true);
44 // Returns true if it settled down
48 void AddChild(wxShape
*child
, wxShape
*addAfter
= NULL
);
49 void RemoveChild(wxShape
*child
);
51 wxOGLConstraint
*AddConstraint(wxOGLConstraint
*constraint
);
52 wxOGLConstraint
*AddConstraint(int type
, wxShape
*constraining
, wxList
& constrained
);
53 wxOGLConstraint
*AddConstraint(int type
, wxShape
*constraining
, wxShape
*constrained
);
55 void DeleteConstraint(wxOGLConstraint
*constraint
);
57 // Delete constraints that involve this child.
58 void DeleteConstraintsInvolvingChild(wxShape
*child
);
60 // Remove the image from any constraints involving it, but DON'T
61 // remove any constraints.
62 void RemoveChildFromConstraints(wxShape
*child
);
64 // Find constraint, also returning actual composite the constraint was in,
65 // in case it had to find it recursively.
66 wxOGLConstraint
*FindConstraint(long id
, wxCompositeShape
**actualComposite
= NULL
);
68 // Returns true if something changed
71 // Make this composite into a container by creating one wxDivisionShape
74 // Calculates size and position of composite object based on children
78 void WriteAttributes(wxExpr
*clause
);
79 void ReadAttributes(wxExpr
*clause
);
80 // In case the object has constraints it needs to read in in a different pass
81 void ReadConstraints(wxExpr
*clause
, wxExprDatabase
*database
);
83 // Does the copying for this object
84 void Copy(wxShape
& copy
);
86 virtual wxDivisionShape
*OnCreateDivision();
88 // Finds the image used to visualize a container. This is any child
89 // of the composite that is not in the divisions list.
90 wxShape
*FindContainerImage();
92 // Returns true if division is a descendant of this container
93 bool ContainsDivision(wxDivisionShape
*division
);
95 inline wxList
& GetDivisions() const { return (wxList
&) m_divisions
; }
96 inline wxList
& GetConstraints() const { return (wxList
&) m_constraints
; }
101 wxList m_constraints
;
102 wxList m_divisions
; // In case it's a container
106 * A division object is a composite with special properties,
107 * to be used for containment. It's a subdivision of a container.
108 * A containing node image consists of a composite with a main child shape
109 * such as rounded rectangle, plus a list of division objects.
110 * It needs to be a composite because a division contains pieces
112 * NOTE a container has at least one wxDivisionShape for consistency.
113 * This can be subdivided, so it turns into two objects, then each of
114 * these can be subdivided, etc.
116 #define DIVISION_SIDE_NONE 0
117 #define DIVISION_SIDE_LEFT 1
118 #define DIVISION_SIDE_TOP 2
119 #define DIVISION_SIDE_RIGHT 3
120 #define DIVISION_SIDE_BOTTOM 4
122 class WXDLLIMPEXP_OGL wxDivisionShape
: public wxCompositeShape
124 DECLARE_DYNAMIC_CLASS(wxDivisionShape
)
130 void OnDraw(wxDC
& dc
);
131 void OnDrawContents(wxDC
& dc
);
132 bool OnMovePre(wxDC
& dc
, double x
, double y
, double oldX
, double oldY
, bool display
= true);
133 void OnDragLeft(bool draw
, double x
, double y
, int keys
, int attachment
= 0);
134 void OnBeginDragLeft(double x
, double y
, int keys
, int attachment
= 0);
135 void OnEndDragLeft(double x
, double y
, int keys
, int attachment
= 0);
137 void OnRightClick(double x
, double y
, int keys
= 0, int attachment
= 0);
139 // Don't want this kind of composite to resize its subdiagrams, so
140 // override composite's SetSize.
141 void SetSize(double w
, double h
, bool recursive
= true);
143 // Similarly for calculating size: it's fixed at whatever SetSize
144 // set it to, not in terms of children.
145 void CalculateSize();
147 void MakeControlPoints();
148 void ResetControlPoints();
149 void MakeMandatoryControlPoints();
150 void ResetMandatoryControlPoints();
153 void WriteAttributes(wxExpr
*clause
);
154 void ReadAttributes(wxExpr
*clause
);
156 // Does the copying for this object
157 void Copy(wxShape
& copy
);
159 // Divide horizontally (wxHORIZONTAL) or vertically (wxVERTICAL)
160 bool Divide(int direction
);
162 // Resize adjoining divisions at the given side. If test is true,
163 // just see whether it's possible for each adjoining region,
164 // returning false if it's not.
165 bool ResizeAdjoining(int side
, double newPos
, bool test
);
167 // Adjust a side, returning false if it's not physically possible.
168 bool AdjustLeft(double left
, bool test
);
169 bool AdjustTop(double top
, bool test
);
170 bool AdjustRight(double right
, bool test
);
171 bool AdjustBottom(double bottom
, bool test
);
173 // Edit style of left or top side
174 void EditEdge(int side
);
177 void PopupMenu(double x
, double y
);
179 inline void SetLeftSide(wxDivisionShape
*shape
) { m_leftSide
= shape
; }
180 inline void SetTopSide(wxDivisionShape
*shape
) { m_topSide
= shape
; }
181 inline void SetRightSide(wxDivisionShape
*shape
) { m_rightSide
= shape
; }
182 inline void SetBottomSide(wxDivisionShape
*shape
) { m_bottomSide
= shape
; }
183 inline wxDivisionShape
*GetLeftSide() const { return m_leftSide
; }
184 inline wxDivisionShape
*GetTopSide() const { return m_topSide
; }
185 inline wxDivisionShape
*GetRightSide() const { return m_rightSide
; }
186 inline wxDivisionShape
*GetBottomSide() const { return m_bottomSide
; }
188 inline void SetHandleSide(int side
) { m_handleSide
= side
; }
189 inline int GetHandleSide() const { return m_handleSide
; }
191 inline void SetLeftSidePen(const wxPen
*pen
) { m_leftSidePen
= pen
; }
192 inline wxPen
*GetLeftSidePen() const { return wx_const_cast(wxPen
*, m_leftSidePen
); }
193 inline void SetTopSidePen(const wxPen
*pen
) { m_topSidePen
= pen
; }
194 inline wxPen
*GetTopSidePen() const { return wx_const_cast(wxPen
*, m_topSidePen
); }
196 void SetLeftSideColour(const wxString
& colour
);
197 void SetTopSideColour(const wxString
& colour
);
198 void SetLeftSideStyle(const wxString
& style
);
199 void SetTopSideStyle(const wxString
& style
);
201 inline wxString
GetLeftSideColour() const { return m_leftSideColour
; }
202 inline wxString
GetTopSideColour() const { return m_topSideColour
; }
203 inline wxString
GetLeftSideStyle() const { return m_leftSideStyle
; }
204 inline wxString
GetTopSideStyle() const { return m_topSideStyle
; }
207 // Adjoining divisions. NULL indicates edge
208 // of container, and that side shouldn't be
210 wxDivisionShape
* m_leftSide
;
211 wxDivisionShape
* m_rightSide
;
212 wxDivisionShape
* m_topSide
;
213 wxDivisionShape
* m_bottomSide
;
215 int m_handleSide
; // Side at which handle is legal
217 const wxPen
* m_leftSidePen
;
218 const wxPen
* m_topSidePen
;
219 wxString m_leftSideColour
;
220 wxString m_topSideColour
;
221 wxString m_leftSideStyle
;
222 wxString m_topSideStyle
;
226 #define DIVISION_MENU_SPLIT_HORIZONTALLY 1
227 #define DIVISION_MENU_SPLIT_VERTICALLY 2
228 #define DIVISION_MENU_EDIT_LEFT_EDGE 3
229 #define DIVISION_MENU_EDIT_TOP_EDGE 4
230 #define DIVISION_MENU_EDIT_RIGHT_EDGE 5
231 #define DIVISION_MENU_EDIT_BOTTOM_EDGE 6
232 #define DIVISION_MENU_DELETE_ALL 7