Mercurial > projects > mde
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 } |