comparison mde/gui/widget/createWidget.d @ 90:b525ff28774b

Widgets generated dynamically from a list can now be standard widgets selected from data files. Started on allowing alignment to be shared between instances of a layout widget in a dynamic list (to allow column alignment of list's rows).
author Diggory Hardy <diggory.hardy@gmail.com>
date Wed, 01 Oct 2008 23:37:51 +0100
parents 56c0ddd90193
children 4d5d53e4f881
comparison
equal deleted inserted replaced
89:97e6dce08037 90:b525ff28774b
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 /// GUI Widget module. 16 /** This module contains code to create a widget based on an enumeration value passed at runtime.
17 *
18 * It could be a part of the WidgetLoader.makeWidget function, but having it here makes things
19 * tidier. */
17 module mde.gui.widget.createWidget; 20 module mde.gui.widget.createWidget;
18 21
19 import mde.gui.widget.Ifaces; 22 import mde.gui.widget.Ifaces;
20 import mde.gui.exception : WidgetDataException; 23 import mde.gui.exception : WidgetDataException;
24 import mde.gui.content.Content; //NOTE - maybe move IContent to a separate module
21 25
22 // Widgets to create: 26 // Widgets to create:
23 import mde.gui.widget.layout; 27 import mde.gui.widget.layout;
24 import mde.gui.widget.miscWidgets; 28 import mde.gui.widget.miscWidgets;
25 import mde.gui.widget.TextWidget; 29 import mde.gui.widget.TextWidget;
36 * Usually called by the widget manager's makeWidget function. 40 * Usually called by the widget manager's makeWidget function.
37 * 41 *
38 * Widget created of type data.ints[0] (see enum WIDGET_TYPES), with one of the following CTORs: 42 * Widget created of type data.ints[0] (see enum WIDGET_TYPES), with one of the following CTORs:
39 * --- 43 * ---
40 * this (IWidgetManager mgr, WidgetData data); 44 * this (IWidgetManager mgr, WidgetData data);
41 * // Called if (data.ints[0] & WIDGET_TYPES.TAKES_PARENT): 45 * // Called if (data.ints[0] & WIDGET_TYPES.TAKES_CONTENT):
42 * this (IWidgetManager mgr, WidgetData data, IParentWidget parent); 46 * this (IWidgetManager mgr, WidgetData data, IContent content);
43 * --- 47 * ---
44 *************************************************************************************************/ 48 *************************************************************************************************/
45 IChildWidget createWidget (IWidgetManager mgr, WidgetData data, IParentWidget parent) 49 IChildWidget createWidget (IWidgetManager mgr, WidgetData data, IContent content)
46 in { 50 in {
47 assert (mgr !is null, "createWidget: mgr is null"); 51 assert (mgr !is null, "createWidget: mgr is null");
48 } body { 52 } body {
49 if (data.ints.length < 1) { 53 if (data.ints.length < 1) {
50 logger.error ("No int data; creating a debug widget"); 54 logger.error ("No int data; creating a debug widget");
71 }+/ 75 }+/
72 76
73 private: 77 private:
74 /// Widget types. 78 /// Widget types.
75 enum WIDGET_TYPE : int { 79 enum WIDGET_TYPE : int {
76 TAKES_PARENT = 0x4000, // CTOR takes reference to its parent 80 TAKES_CONTENT = 0x4000, // Flag indicates widget's this should be passed an IContent reference.
77 PARENT = 0x8000, // widget can have children 81 PARENT = 0x8000, // widget can have children; not used by code (except in data files)
78 82
79 // Use widget names rather than usual capitals convention 83 // Use widget names rather than usual capitals convention
80 Unnamed = 0x0, // Only for use by widgets not created with createWidget 84 Unnamed = 0x0, // Only for use by widgets not created with createWidget
81 85
82 // blank: 0x1 86 // blank: 0x1
85 Debug = 0xF, 89 Debug = 0xF,
86 90
87 // buttons: 0x10 91 // buttons: 0x10
88 Button = 0x10, 92 Button = 0x10,
89 93
90 // content: 0x20 94 // labels: 0x20
91 Text = 0x21, 95 ContentLabel = TAKES_CONTENT | 0x20,
92 Int = 0x22, 96 TextLabel = 0x21,
93 97
94 GridLayout = PARENT | 0x100, 98 GridLayout = TAKES_CONTENT | PARENT | 0x100,
95 TrialContentLayout = PARENT | 0x110, 99 TrialContentLayout = PARENT | 0x110,
96 100
97 FloatingArea = PARENT | 0x200, 101 FloatingArea = PARENT | 0x200,
98 } 102 }
99 103
103 const char[][] WIDGETS = [ 107 const char[][] WIDGETS = [
104 "FixedBlank", 108 "FixedBlank",
105 "SizableBlank", 109 "SizableBlank",
106 "Debug", 110 "Debug",
107 "Button", 111 "Button",
108 "Text", 112 "TextLabel",
109 "Int", 113 "ContentLabel",
110 "GridLayout",
111 "TrialContentLayout", 114 "TrialContentLayout",
112 "FloatingArea"]; 115 "FloatingArea",
116 "GridLayout"];
113 117
114 /* Generates a binary search algorithm. */ 118 /* Generates a binary search algorithm. */
115 char[] binarySearch (char[] var, char[][] consts) { 119 char[] binarySearch (char[] var, char[][] consts) {
116 if (consts.length > 3) { 120 if (consts.length > 3) {
117 return "if (" ~ var ~ " <= WIDGET_TYPE." ~ consts[$/2 - 1] ~ ") {\n" ~ 121 return "if (" ~ var ~ " <= WIDGET_TYPE." ~ consts[$/2 - 1] ~ ") {\n" ~
122 } else { 126 } else {
123 char[] ret; 127 char[] ret;
124 foreach (c; consts) { 128 foreach (c; consts) {
125 ret ~= "if (" ~ var ~ " == WIDGET_TYPE." ~ c ~ ") {\n" ~ 129 ret ~= "if (" ~ var ~ " == WIDGET_TYPE." ~ c ~ ") {\n" ~
126 " debug (mdeWidgets) logger.trace (\"Creating new "~c~"Widget.\");\n" ~ 130 " debug (mdeWidgets) logger.trace (\"Creating new "~c~"Widget.\");\n" ~
127 " static if (WIDGET_TYPE."~c~" & WIDGET_TYPE.TAKES_PARENT)\n" ~ 131 " static if (WIDGET_TYPE."~c~" & WIDGET_TYPE.TAKES_CONTENT)\n" ~
128 " return new " ~ c ~ "Widget (mgr, data, parent);\n" ~ 132 " return new " ~ c ~ "Widget (mgr, data, content);\n" ~
129 " else\n" ~ 133 " else\n" ~
130 " return new " ~ c ~ "Widget (mgr, data);\n" ~ 134 " return new " ~ c ~ "Widget (mgr, data);\n" ~
131 "} else "; 135 "} else ";
132 } 136 }
133 ret = ret[0..$-6] ~ '\n'; // remove last else 137 ret = ret[0..$-6] ~ '\n'; // remove last else
134 return ret; 138 return ret;
135 } 139 }
136 } 140 }
141
142 debug { // check items in WIDGETS are listed in order
143 char[] WIDGETS_check () {
144 char[] ret;
145 for (int i = WIDGETS.length-2; i > 0; --i) {
146 ret ~= "WIDGET_TYPE."~WIDGETS[i] ~" >= WIDGET_TYPE."~ WIDGETS[i+1];
147 if (i>1) ret ~= " || ";
148 }
149 return ret;
150 }
151 mixin ("static if ("~WIDGETS_check~")
152 static assert (false, \"WIDGETS is not in order!\");");
153 }