comparison mde/gui/widget/Ifaces.d @ 75:25cb7420dc91

A massive overhaul/rewrite for the gui's data management and setup code. Currently much that was working is broken. imde's classes are created in a static this instead of mde's main. gl setup code moved from gl/basic.d to gl/draw.d mergetag.DefaultData: now HIGH_LOW priority instead of LOW_HIGH. Reduced type list to only used types; small fix for indent function. setup.paths: new NoFileException thrown instead of MTFileIOException
author Diggory Hardy <diggory.hardy@gmail.com>
date Mon, 28 Jul 2008 18:17:48 +0100
parents 159775502bb4
children 65780e0e48e6
comparison
equal deleted inserted replaced
74:cee261eba249 75:25cb7420dc91
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 /** Window and widget interfaces. */ 16 /*************************************************************************************************
17 * Widget interfaces.
18 *
19 * Widgets are connected as the nodes of a tree. Widgets know their parent as a IParentWidget
20 * class and their children as IChildWidget classes. The gui manager is a special widget only
21 * implementing IParentWidget; all other widgets must implement IChildWidget and optionally
22 * IParentWidget.
23 *************************************************************************************************/
17 module mde.gui.widget.Ifaces; 24 module mde.gui.widget.Ifaces;
18 25
19 public import mde.gui.renderer.IRenderer; 26 public import mde.gui.renderer.IRenderer;
20 public import mde.gui.IGui; 27
21 28
22 /** Interface for Window, allowing widgets to call some of Window's methods. 29 /** Widget ID type. Each ID is unique under this window.
23 * 30 *
24 * Contains the methods in Window available for widgets to call on their root. 31 * Type is int since this is the widget data type. */
32 alias char[] widgetID;
33
34 /** Window coordinate and dimension/size type (int).
35 *
36 * Used to disambiguate between general integers and coordinates; all widget positions/sizes should
37 * use this type (or one of the aliases below).
38 *
39 * ---
40 * typedef int wdim; // Declared in IRenderer to avoid a circular import.
41 * ---
42 *
43 * Aliases of wdim providing extra information about what their contents hold: absolute position,
44 * position relative to the containing widget (wdrel should not be used if relative to anything
45 * else), or size. Their use instead of wdim is optional (and in some cases wdim values aren't of
46 * any of these types). Also don't use these aliases for variables which may also be used to other
47 * effects, e.g. if they can have special values with special meanings. */
48 alias wdim wdabs;
49 alias wdim wdrel; /// ditto
50 alias wdim wdsize; /// ditto
51
52 /** A pair of wdim variables, and strictly no other data (methods may be added if deemed useful).
53 *
54 * Potentially usable to return two wdim variables, e.g. width and height, from a function.
55 * However, the current usage of out variables looks like it's better. */
56 struct wdimPair {
57 wdim x, y; /// data
58 }
59
60
61 /*************************************************************************************************
62 * Common interface for all widgets.
25 * 63 *
26 * Notation: 64 * Notation:
27 * Positive/negative direction: along the x/y axis in this direction. 65 * Positive/negative direction: along the x/y axis in this direction.
28 * Layout widget: a widget containing multiple sub-widges (which hence controls how they are laid 66 * Layout widget: a widget containing multiple sub-widges (which hence controls how they are
29 * out). */ 67 * laid out).
30 interface IWindow : IWidget 68 *************************************************************************************************/
31 { 69 //NOTE: keep this?
32 /** Widget ID type. Each ID is unique under this window. 70 interface IWidget
33 * 71 {
34 * Type is int since this is the widget data type. */ 72 }
35 alias int widgetID; 73
36 74
37 /** Get a widget by ID. 75 /*************************************************************************************************
38 * 76 * Interface for the widget manager.
39 * Returns the widget with the given ID from the Window's widget list. If the widget hasn't yet 77 *
40 * been created, creates it using the Window's widget creation data. */ 78 * This class handles widget rendering, input, loading and saving.
41 IWidget makeWidget (widgetID i); 79 *************************************************************************************************/
42 80 interface IWidgetManager : IParentWidget
43 /** Get a string from the widgetString associative array. */ 81 {
44 char[] getWidgetString (int i); 82 // Loading/saving:
45 83 /** Create a widget by ID.
46 /** Add widget's saveData to the data to be saved, returning it's widgetID. */ 84 *
47 widgetID addCreationData (IWidget widget); 85 * Creates a widget, using the widget data with index id. Widget data is loaded from files,
48 86 * and per design (multiple gui layouts, called designs, may exist; data is per design).
49 /** Add a string to the widgetString associative array, returning it's index. */ 87 *
50 int addWidgetString (char[] str); 88 * Note: this method is only for "named" widgets; generic widgets instanciated in lists are
51 89 * created differently. */
52 /** Returns the window's gui. */ 90 IChildWidget makeWidget (widgetID id);
53 IGui gui (); 91
54 92 /** Record some changes, for saving. */
55 /** The widget/window needs redrawing. */ 93 void setData (widgetID id, WidgetData);
94
95 // Rendering:
96 /** For when a widget needs redrawing.
97 *
98 * Must be called because rendering may only be done on events.
99 *
100 * Currently it just causes everything to be redrawn next frame. */
56 void requestRedraw (); 101 void requestRedraw ();
57 102
58 /** Get the window's renderer. 103 /** Get the window's renderer.
59 * 104 *
60 * Normally specific to the GUI, but widgets have no direct contact with the GUI and this 105 * Normally specific to the GUI, but widgets have no direct contact with the GUI and this
61 * provides the possibility of per-window renderers (if desired). */ 106 * provides the possibility of per-window renderers (if desired). */
62 IRenderer renderer (); 107 IRenderer renderer ();
63 } 108
64 109
65 /** Interface for widgets. 110 // User input:
66 * 111 /** Add a mouse click callback: delegate will be called for all mouse click events recieved.
67 * Note that Window also implements this interface so that widgets can interact with their parent 112 *
68 * in a uniform way. 113 * The delegate should return true if it accepts the event and no further processing is
114 * required (i.e. the event should not be handled by anything else), false otherwise.
115 *
116 * Note that this is not a mechanism to prevent unwanted event handling, and in the future
117 * may be removed (so event handling cannot be cut short). */
118 void addClickCallback (bool delegate (wdabs cx, wdabs cy, ubyte b, bool state) dg);
119
120 /** Add a mouse motion callback: delegate will be called for all motion events recieved. */
121 void addMotionCallback (void delegate (wdabs cx, wdabs cy) dg);
122
123 // FIXME: keyboard callback (letter only, for text input? Also used for setting keybindings though...)
124
125 /** Remove all event callbacks on this widget (according to the delegate's .ptr). */
126 void removeCallbacks (IChildWidget frame);
127 }
128
129
130 /*************************************************************************************************
131 * Interface for parent widgets, including the gui manager.
132 *
133 * A widget may call these methods on its parent, and on the gui manager.
134 *************************************************************************************************/
135 interface IParentWidget : IWidget
136 {
137 // NOTE: Likely some day this interface will really be used.
138 // NOTE: What widget is NOT going to implement this? It will probably be inherited.
139 }
140
141
142 /*************************************************************************************************
143 * Interface for (child) widgets, i.e. all widgets other than the manager.
69 * 144 *
70 * A widget is a region of a GUI window which handles rendering and user-interaction for itself 145 * A widget is a region of a GUI window which handles rendering and user-interaction for itself
71 * and is able to communicate with it's window and parent/child widgets as necessary. 146 * and is able to communicate with its manager and parent/child widgets as necessary.
72 * 147 *
73 * If a widget is to be creatable by Window.makeWidget, it must be listed in the createWidget 148 * If a widget is to be creatable by IWidgetManager.makeWidget, it must be listed in the
74 * module, have a constructor of the following form, and should implement getCreationData(). 149 * createWidget module, have a constructor of the following form, and should update it's
75 * Use Ddoc to explain what initialization data is used. 150 * creation data as necessary via IWidgetManager.setData().
151 * It should use Ddoc to explain what initialization data is used.
76 * ---------------------------------- 152 * ----------------------------------
77 * /++ Constructor for a ... widget. 153 * /++ Constructor for a ... widget.
78 * + 154 * +
79 * + Widget uses the initialisation data: 155 * + Widget uses the initialisation data:
80 * + [widgetID, x, y] 156 * + [widgetID, x, y]
81 * + where x is ... and y is ... +/ 157 * + where x is ... and y is ... +/
82 * this (IWindow window, int[] data); 158 * this (IWidgetManager mgr, WidgetData data);
83 * ---------------------------------- 159 * ----------------------------------
84 * Where window is the root window (the window to which the widget belongs) and data is an array of 160 * Where mgr is the widget manager and data is
85 * initialisation data. The method should throw a WidgetDataException (created without parameters) 161 * initialisation data. The method should throw a WidgetDataException (created without
86 * if the data has wrong length or is otherwise invalid. 162 * parameters) if the data has wrong length or is otherwise invalid.
87 * 163 *
88 * The widget's size should be set either by it's this() method or by the first call to 164 * A parent widget is responsible for setting the size of its children widgets, however it must
89 * setSize(). setSize() is called on all widgets immediately after their creation, and throwing an 165 * satisfy their minimal sizes as available from minWidth() and minHeight(). setWidth() and
90 * exception at this point (but not on later calls to setSize) is an acceptible method of failure. 166 * setHeight() are called on all widgets after creation.
91 */ 167 *************************************************************************************************/
92 //NOTE: add another this() without the data for default initialization, for the GUI editor? 168 //NOTE: add another this() without the data for default initialization, for the GUI editor?
93 interface IWidget 169 interface IChildWidget : IWidget
94 { 170 {
95 //BEGIN Load and save 171 //BEGIN Load and save
96 /** Called after creating widgets to adjust size & other mutable attributes from saved data. 172 /** Called when the renderer is changed (at least when the changes affect dimensions).
97 * 173 * Also called after widget creation, before any other methods are called.
98 * As for setSize, setPosition should be called afterwards. 174 *
99 * 175 * Returns: true when widget's dimensions (may) have changed.
100 * Each widget should call adjust on each of its sub-widgets in turn with data, each time 176 *
101 * replacing data by the return value of the call. It should then take its own mutable data 177 * Should be propegated down to all child widgets. */
102 * from the beginning of the array and return the remainder of the array. 178 bool rendererChanged ();
103 * 179
104 * Adjust should handle errors gracefully by reverting to default values and not throwing. 180 /+ Use when widget editing is available? Requires widgets to know their parents.
105 * This is because the creation data and the user's mutable data may be stored separately and 181 /** Called when a child widget's size has changed.
106 * become out-of-sync during an update. */ 182 *
107 int[] adjust (int[] data); 183 * Should be propegated up to parents. */
108 184 void childChanged ();
109 /** Output data suitible for recreating the widget (data to be passed to this()). 185 +/
110 *
111 * Function may need to call Window's addCreationData() and addWidgetString() methods to save
112 * other data.
113 *
114 * Creation data is data only changed when the gui is edited. */
115 int[] getCreationData ();
116
117 /** Output data containing the widget's current adjustments (data to be passed to adjust()).
118 *
119 * Mutable data is data which can be changed during normal gui use, such as the size of
120 * resizible widgets or current tab of a tab widget.
121 *
122 * Should be a concatenation of each sub-widget's mutable data and the widget's own. */
123 int[] getMutableData ();
124 //END Load and save 186 //END Load and save
125 187
126 //BEGIN Size and position 188 //BEGIN Size and position
127 /** is the width / height resizable? 189 /** is the width / height resizable?
128 * 190 *
134 * 196 *
135 * Takes into account child-widgets and any other contents. */ 197 * Takes into account child-widgets and any other contents. */
136 wdim minWidth (); 198 wdim minWidth ();
137 wdim minHeight (); /// ditto 199 wdim minHeight (); /// ditto
138 200
139 /** Get the current size of the widget. */ 201 /** Get the current size of the widget.
140 void getCurrentSize (out wdim w, out wdim h); 202 *
203 * Deprecated: is it needed now?
204 */
205 deprecated void getCurrentSize (out wdim w, out wdim h);
141 206
142 /** Used to adjust the size. 207 /** Used to adjust the size.
143 * 208 *
144 * Params: 209 * Params:
145 * nw/nh = The new width/height 210 * nw/nh = The new width/height
146 * dir = Direction to resize from. This is only really applicable to layout widgets. 211 * dir = Direction to resize from. This is only really applicable to layout widgets.
147 * It must be either -1 (start resizing from highest row/col index, decreasing the 212 * It must be either -1 (start resizing from highest row/col index, decreasing the
148 * index as necessary), or +1 (resize from the lowest index, i.e. 0). 213 * index as necessary), or +1 (resize from the lowest index, i.e. 0).
149 * Most widgets can simply ignore it. 214 * Most widgets can simply ignore it.
150 * 215 *
151 * Implementation: 216 * If called with dimensions less than minWidth/minHeight return: the widget may set its size
152 * The size should be clamped to the widget's minimal size, i.e. the size set may be larger 217 * to either the dimension given or its minimal dimension (even though this is larger). If the
153 * than that given by the parameters. Conversely, the size should not be reduced to the 218 * larger size is set, events won't be received in the extra area. FIXME: sort out rendering.
154 * widget's maximal size (if any) but expanded as necessary (alignment to be implemented). 219 * Otherwise, the dimensions should always be set exactly.
155 * This should be true for both resizable and fixed widgets; fixed widgets may still be scaled 220 *
156 * to fill a whole row/column in a layout widget. 221 * setPosition must be called after calling either setWidth or setHeight. */
157 *
158 * If the actual size is needed, call getCurrentSize afterwards. setPosition must be called
159 * afterwards if the widget might be a layout widget. */
160 void setWidth (wdim nw, int dir); 222 void setWidth (wdim nw, int dir);
161 void setHeight (wdim nh, int dir); /// ditto 223 void setHeight (wdim nh, int dir); /// ditto
162 224
163 /** Set the current position (i.e. called on init and move). */ 225 /** Set the current position (i.e. called on init and move). */
164 void setPosition (wdim x, wdim y); 226 void setPosition (wdim x, wdim y);
189 * 251 *
190 * Maybe later enforce clipping of all sub-widget drawing, particularly for cases where only 252 * Maybe later enforce clipping of all sub-widget drawing, particularly for cases where only
191 * part of the widget is visible: scroll bars or a hidden window. */ 253 * part of the widget is visible: scroll bars or a hidden window. */
192 void draw (); 254 void draw ();
193 } 255 }
256
257
258 /*************************************************************************************************
259 * The data type all widgets creatable by the widget manager receive on creation.
260 *
261 * Conversion code to/from MT tags is contained in the addTag and writeAll methods of
262 * WidgetDataSet and WidgetDataChanges.
263 *************************************************************************************************/
264 struct WidgetData
265 {
266 int[] ints; // An array of integer data
267 char[] str; // One string
268 }