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.