Mercurial > projects > mde
comparison mde/gui/widget/Ifaces.d @ 131:9cff74f68b84
Major revisions to popup handling. Buttons can close menus now, plus some smaller impovements. Removed Widget module.
Moved Widget.AWidget to AChildWidget.AChildWidget and Widget.AParentWidget to AParentWidget.AParentWidget.
Removed ASingleParentWidget to improve code sharing.
AChildWidget doesn't implement IParentWidget like AWidget did.
New IPopupParentWidget extending IParentWidget for the WM and some widgets to handle popups.
Cut old popup management code.
New underMouse() function replacing highlight(); called on all widgets.
Separate menu-popup and button widgets aren't needed for menus now.
Functions returning content widgets have been moved to their own module.
Cleaned up jobs.txt.
Switched to 80 line length for Ddoc.
author | Diggory Hardy <diggory.hardy@gmail.com> |
---|---|
date | Wed, 21 Jan 2009 13:01:40 +0000 |
parents | c5c38eaadb64 |
children | 9fd705793568 |
comparison
equal
deleted
inserted
replaced
130:c5c38eaadb64 | 131:9cff74f68b84 |
---|---|
11 See the GNU General Public License for more details. | 11 See the GNU General Public License for more details. |
12 | 12 |
13 You should have received a copy of the GNU General Public License | 13 You should have received a copy of the GNU General Public License |
14 along with this program. If not, see <http://www.gnu.org/licenses/>. */ | 14 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
15 | 15 |
16 /************************************************************************************************* | 16 /****************************************************************************** |
17 * Widget interfaces. | 17 * Widget interfaces. |
18 * | 18 * |
19 * This module contains the primary documentation for the declared methods; also the Widget module | 19 * This module contains the primary documentation for the declared methods; |
20 * has some brief comments and basic implementations. | 20 * also the Widget module has some brief comments and basic implementations. |
21 * | 21 * |
22 * Widgets are connected as the nodes of a tree. Widgets know their parent as a IParentWidget | 22 * Widgets are connected as the nodes of a tree. Widgets know their parent as a |
23 * class and their children as IChildWidget classes. The gui manager is a special widget only | 23 * IParentWidget class and their children as IChildWidget classes. The gui |
24 * implementing IParentWidget; all other widgets must implement IChildWidget and optionally | 24 * manager is a special widget only implementing IParentWidget; all other |
25 * IParentWidget. | 25 * widgets must implement IChildWidget and optionally IParentWidget. |
26 *************************************************************************************************/ | 26 * |
27 * It's recommended that widgets inherit one of the A*Widget classes rather | |
28 * than impement I*Widget directly. | |
29 *****************************************************************************/ | |
27 module mde.gui.widget.Ifaces; | 30 module mde.gui.widget.Ifaces; |
28 | 31 |
29 public import mde.gui.types; | 32 public import mde.gui.types; |
30 public import mde.gui.renderer.IRenderer; | 33 public import mde.gui.renderer.IRenderer; |
31 import mde.content.Content; | 34 import mde.content.Content; |
32 | 35 |
33 | 36 |
34 /************************************************************************************************* | 37 /****************************************************************************** |
35 * Interface for parent widgets, including IWidgetManager. | 38 * Interface for parent widgets, including IWidgetManager. |
36 * | 39 * |
37 * All widgets implement this via AWidget to make things simpler (code sharing). | 40 * All widgets implement this via AWidget to make things simpler (code sharing). |
38 * | 41 * |
39 * Notation: | 42 * Notation: |
40 * Positive/negative direction: along the x/y axis in this direction. | 43 * Positive/negative direction: along the x/y axis in this direction. |
41 * Layout widget: a widget containing multiple sub-widges (which hence controls how they are | 44 * Layout widget: a widget containing multiple sub-widges (which hence |
42 * laid out). | 45 * controls how they are laid out). |
43 *************************************************************************************************/ | 46 *****************************************************************************/ |
44 interface IParentWidget | 47 interface IParentWidget |
45 { | 48 { |
46 /** Checks for recursion of unsafe widgets to prevent infinite recursion. */ | 49 /** Checks for recursion of unsafe widgets to prevent infinite recursion. */ |
47 void recursionCheck (widgetID); | 50 void recursionCheck (widgetID); |
51 | |
52 /** IPPWs return self, other widgets recurse call on parent. */ | |
53 IPopupParentWidget getParentIPPW (); | |
48 | 54 |
49 /** Child widgets should call this on their parent if their minimal size changes, since they | 55 /** Child widgets should call this on their parent if their minimal size changes, since they |
50 * cannot resize themselves. | 56 * cannot resize themselves. |
51 * | 57 * |
52 * Children may depend on their parent resizing them if necessary to keep width valid. | 58 * Children may depend on their parent resizing them if necessary to keep width valid. |
63 * (e.g. this doesn't apply to FloatingAreaWidget). | 69 * (e.g. this doesn't apply to FloatingAreaWidget). |
64 * | 70 * |
65 * NEVER and ALWAYS often don't result in usable GUIs, and aren't expected to be used except | 71 * NEVER and ALWAYS often don't result in usable GUIs, and aren't expected to be used except |
66 * for debugging. | 72 * for debugging. |
67 * | 73 * |
68 * NOTE: ANY_SUBWIDGETS can cause problems like enlarging a menu bar containing a resizable | 74 * Note: ANY_SUBWIDGETS can cause problems like enlarging a menu bar containing a resizable |
69 * blank instead of the main part of a window. */ | 75 * blank instead of the main part of a window. */ |
70 enum SIZABILITY_ENUM { | 76 enum SIZABILITY_ENUM { |
71 NEVER = 0, /// Parents are never resizable | 77 NEVER = 0, /// Parents are never resizable |
72 ALL_SUBWIDGETS = 3, /// Parents are only resizable if all sub-widgets are | 78 ALL_SUBWIDGETS = 3, /// Parents are only resizable if all sub-widgets are |
73 ANY_SUBWIDGETS = 2, /// Parents are resizable if any sub-widgets are | 79 ANY_SUBWIDGETS = 2, /// Parents are resizable if any sub-widgets are |
76 SUBWIDGETS = 2, /// Flag set by ALL_SUBWIDGETS and ANY_SUBWIDGETS | 82 SUBWIDGETS = 2, /// Flag set by ALL_SUBWIDGETS and ANY_SUBWIDGETS |
77 } | 83 } |
78 static const SIZABILITY = SIZABILITY_ENUM.ALL_SUBWIDGETS; /// ditto | 84 static const SIZABILITY = SIZABILITY_ENUM.ALL_SUBWIDGETS; /// ditto |
79 } | 85 } |
80 | 86 |
81 | 87 /****************************************************************************** |
82 /************************************************************************************************* | 88 * Interface for parents of popups and the widget manager. |
89 * | |
90 * An IPopupParentWidget (IPPW) may have 0 or 1 child IPPWs; the child may have | |
91 * its own IPPW. Each IPPW when added to a parent IPPW is responsible for | |
92 * managing one popup. | |
93 * | |
94 * So any child IPPW should also be a descendant widget, and is usually the or | |
95 * a descendant of the popup. | |
96 * | |
97 * An IPPW usually has one popup to manage (the popup being one of its child | |
98 * widgets), but the popup is only active if the IPPW is added as a child of | |
99 * its parent IPPW. | |
100 * | |
101 * The widget manager is an IPPW, but unlike most IPPWs its popup(s), if | |
102 * existing, probably have nothing to do with its child IPPWs. | |
103 *****************************************************************************/ | |
104 interface IPopupParentWidget : IParentWidget | |
105 { | |
106 /** Add caller ippw as current child IPopupParentWidget of called IPPW. | |
107 * | |
108 * ippw is added as called IPPW's child IPPW, and its functions are | |
109 * called to draw popup and pass events. The called IPPW's previous child | |
110 * IPPW is replaced. | |
111 * | |
112 * ippw is then responsible for managing a popup. */ | |
113 void addChildIPPW (IPopupParentWidget ippw); | |
114 /** Remove ippw from being the called IPPW's child IPPW and disable | |
115 * menuActive. | |
116 * | |
117 * Do nothing if ippw is not the called IPPW's child IPPW. | |
118 * | |
119 * Returns: true if ippw was the child IPPW. | |
120 * | |
121 * I.e. this deactivates ippw's popup. */ | |
122 bool removeChildIPPW (IPopupParentWidget ippw); | |
123 | |
124 /** Notify the called IPPW that it has been removed. */ | |
125 void removedIPPW (); | |
126 | |
127 /** Set/get menuActive state. | |
128 * | |
129 * This is set on the parent IPPW when a popup menu is opened and unset | |
130 * when the menu is closed. | |
131 * If set on the parent IPPW, popup menus can be opened with just a mouse- | |
132 * over and buttons activated with an up-click. */ | |
133 void menuActive (bool); | |
134 bool menuActive (); | |
135 | |
136 /** Called by descendant widgets such as buttons when an action occurred, | |
137 * which should close a menu. (But also called when not in a menu.) */ | |
138 void menuDone (); | |
139 | |
140 /** Get the widget under cx,cy. | |
141 * | |
142 * The IPPW should first recurse the call to its child IPPW if it exists. | |
143 * If this doesn't yield a widget, it should try getting one from its popup | |
144 * and then itself. It should return the first widget found or null. | |
145 * | |
146 * If closePopup is true and a widget isn't returned from the childIPPW, | |
147 * the childIPPW should be removed (to close popups when a click is not on | |
148 * the popup or its parent) and menuActive set false. */ | |
149 IChildWidget getPopupWidget (wdabs cx, wdabs cy, bool closePopup); | |
150 | |
151 /** Draw. | |
152 * | |
153 * The IPPW should first draw its popup, then call on its child IPPW if | |
154 * that exists. */ | |
155 void drawPopup (); | |
156 | |
157 /// Returns true if ippw is child IPPW. | |
158 debug bool isChild (IPopupParentWidget ippw); | |
159 } | |
160 | |
161 /****************************************************************************** | |
83 * Interface for the widget manager. | 162 * Interface for the widget manager. |
84 * | 163 * |
85 * This class handles widget rendering, input, loading and saving. | 164 * This class handles widget rendering, input, loading and saving. |
86 *************************************************************************************************/ | 165 *****************************************************************************/ |
87 interface IWidgetManager : IParentWidget | 166 interface IWidgetManager : IPopupParentWidget |
88 { | 167 { |
89 // Loading/saving: | 168 // Loading/saving: |
90 /** Create a widget by looking up the data for id then looking up data.ints[0] in WIDGET_TYPES. | 169 /** Create a widget by looking up the data for id then looking up data.ints[0] in WIDGET_TYPES. |
91 * | 170 * |
92 * Params: | 171 * Params: |
110 WidgetData widgetData (widgetID id); | 189 WidgetData widgetData (widgetID id); |
111 void widgetData (widgetID id, WidgetData data); /// ditto | 190 void widgetData (widgetID id, WidgetData data); /// ditto |
112 wdims dimData (widgetID id); /// ditto | 191 wdims dimData (widgetID id); /// ditto |
113 void dimData (widgetID id, wdims d); /// ditto | 192 void dimData (widgetID id, wdims d); /// ditto |
114 | 193 |
194 /** Position popup left or right of parent, or left or right of parent | |
195 * (flags & 1 == 1). */ | |
196 void positionPopup (IChildWidget parent, IChildWidget popup, int flags = 0); | |
197 | |
115 // Rendering: | 198 // Rendering: |
116 /** For when a widget needs redrawing. | 199 /** For when a widget needs redrawing. |
117 * | 200 * |
118 * Must be called because rendering may only be done on events. | 201 * Must be called because rendering may only be done on events. |
119 * | 202 * |
124 * | 207 * |
125 * Normally specific to the GUI, but widgets have no direct contact with the GUI and this | 208 * Normally specific to the GUI, but widgets have no direct contact with the GUI and this |
126 * provides the possibility of per-window renderers (if desired). */ | 209 * provides the possibility of per-window renderers (if desired). */ |
127 IRenderer renderer (); | 210 IRenderer renderer (); |
128 | 211 |
129 /** Creates and positions a pop-up widget (widg), | |
130 * | |
131 * Set flags = 1 to place widg left or right of parent, otherwise it will be placed above or | |
132 * below parent. | |
133 * | |
134 * WidgetManager sets its position, draws it, and passes it click events. If a click event | |
135 * occurs which isn't on the popup or it's parent, it is removed (unless a newer | |
136 * popup is not removed). | |
137 * | |
138 * Popups currently should not change their size while active. */ | |
139 void addPopup (IChildWidget parent, IChildWidget popup, int flags = 0); | |
140 /** Remove the popup added by this parent, and any popups added afterwards. | |
141 * If parent added multiple popups, this would just remove the top one. */ | |
142 void removePopup (IChildWidget parent); | |
143 | |
144 // User input: | 212 // User input: |
145 /** Add a mouse click callback. | 213 /** Add a mouse click callback. |
146 * | 214 * |
147 * This is a delegate this will be called for all mouse click events recieved by the gui, not | 215 * This is a delegate this will be called for all mouse click events recieved by the gui, not |
148 * simply all click events on the widget (as clickEvent recieves). | 216 * simply all click events on the widget (as clickEvent recieves). |
159 // Note: don't try to pass a reference and cast to void* in the function; it's a different address. | 227 // Note: don't try to pass a reference and cast to void* in the function; it's a different address. |
160 void removeCallbacks (void* frame); | 228 void removeCallbacks (void* frame); |
161 } | 229 } |
162 | 230 |
163 | 231 |
164 /************************************************************************************************* | 232 /****************************************************************************** |
165 * Interface for (child) widgets, i.e. all widgets other than the manager. | 233 * Interface for (child) widgets, i.e. all widgets other than the manager. |
166 * | 234 * |
167 * A widget is a region of a GUI window which handles rendering and user-interaction for itself | 235 * A widget is a region of a GUI window which handles rendering and user-interaction for itself |
168 * and is able to communicate with its manager and child widgets as necessary. (Passing widgets | 236 * and is able to communicate with its manager and child widgets as necessary. (Passing widgets |
169 * a reference to their parent has not been found useful.) | 237 * a reference to their parent has not been found useful.) |
188 * initialisation data. The method should throw a WidgetDataException (created without | 256 * initialisation data. The method should throw a WidgetDataException (created without |
189 * parameters) if the data has wrong length or is otherwise invalid. | 257 * parameters) if the data has wrong length or is otherwise invalid. |
190 * | 258 * |
191 * All widgets should set their own size in this() or setup() (must be setup() if it could change), | 259 * All widgets should set their own size in this() or setup() (must be setup() if it could change), |
192 * although some parents may set child-widgets' size during their creation. | 260 * although some parents may set child-widgets' size during their creation. |
193 *************************************************************************************************/ | 261 *****************************************************************************/ |
194 //NOTE: add another this() without the data for default initialization, for the GUI editor? | 262 //NOTE: add another this() without the data for default initialization, for the GUI editor? |
195 interface IChildWidget : IParentWidget | 263 interface IChildWidget |
196 { | 264 { |
197 //BEGIN Load and save | 265 //BEGIN Load and save |
198 /** 2nd stage of initialization for widgets; also called on some changes. | 266 /** 2nd stage of initialization for widgets; also called on some changes. |
199 * | 267 * |
200 * Widgets should call recursively on their children, redo anything indicated by flags, and | 268 * Widgets should call recursively on their children, redo anything indicated by flags, and |
307 void keyEvent (ushort sym, char[] letter); | 375 void keyEvent (ushort sym, char[] letter); |
308 | 376 |
309 /** Called when keyboard input focus is lost. */ | 377 /** Called when keyboard input focus is lost. */ |
310 void keyFocusLost (); | 378 void keyFocusLost (); |
311 | 379 |
312 /** Called when the mouse moves over the button and when it leaves. No need to call | 380 /** Called on all widgets when the mouse moves over it (state == true) and |
313 * requestRedraw. */ | 381 * when it leaves (state == false). */ |
314 void highlight (bool state); | 382 void underMouse (bool state); |
315 | 383 |
316 /** When a pop-up is closed the manager calls requestRedraw and this function on its parent. */ | 384 /** When a pop-up is closed the manager calls requestRedraw and this function on its parent. */ |
317 void popupClose (); | 385 void popupClose (); |
318 /** When a click is on the parent of a popup, this function is called instead of the usual | 386 /** When a click is on the parent of a popup, this function is called instead of the usual |
319 * clickEvent. | 387 * clickEvent. |