comparison mde/gui/widget/ParentContent.d @ 143:2ac3e0012788

Added a simple Slider widget. Moved SwitchWidget into PopupMenuWidget's module and renamed the module ParentContent. Made editContent create DisplayContentWidgets for DebugContent (instead of ButtonContentWidgets).
author Diggory Hardy <diggory.hardy@gmail.com>
date Mon, 09 Feb 2009 23:27:41 +0000
parents mde/gui/widget/PopupMenu.d@6f69a9c111eb
children 66c58e5b0062
comparison
equal deleted inserted replaced
142:9dabcc44f515 143:2ac3e0012788
1 /* LICENSE BLOCK
2 Part of mde: a Modular D game-oriented Engine
3 Copyright © 2007-2008 Diggory Hardy
4
5 This program is free software: you can redistribute it and/or modify it under the terms
6 of the GNU General Public License as published by the Free Software Foundation, either
7 version 2 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
10 without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 See the GNU General Public License for more details.
12
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/>. */
15
16 /******************************************************************************
17 * A pop-up widget and a switch (tab) widget (both parent widgets using
18 * content).
19 *****************************************************************************/
20 module mde.gui.widget.ParentContent;
21
22 import mde.gui.widget.AParentWidget;
23 import mde.gui.widget.layout;
24 import mde.content.AStringContent;
25 import mde.gui.exception;
26
27 debug {
28 import tango.util.log.Log : Log, Logger;
29 private Logger logger;
30 static this () {
31 logger = Log.getLogger ("mde.gui.widget.ParentContent");
32 }
33 }
34
35 /******************************************************************************
36 * Widget which pops up a ContentListWidget created with its content.
37 *
38 * Is a button displaying a content string, just like DisplayContentWidget.
39 *
40 * Popped up widget is a ContentListWidget created from the same creation data.
41 *****************************************************************************/
42 class PopupMenuWidget : APopupParentWidget
43 {
44 this (IWidgetManager mgr, IParentWidget parent, widgetID id, WidgetData data, IContent c) {
45 content = cast(Content)c;
46 WDCMinCheck (data, 3,1, content);
47 super (mgr, parent, id);
48
49 //popup = mgr.makeWidget (this, data.strings[0], content);
50 popup = new ContentListWidget (mgr, this, id, data, c);
51 subWidgets = [popup];
52
53 cIndex = data.ints[2];
54 if (cIndex == 0)
55 content.addCallback (&updateVal);
56 adapter = mgr.renderer.getAdapter;
57 adapter.text = content.toString (cIndex);
58 adapter.getDimensions (mw, mh);
59 w = mw;
60 h = mh;
61 }
62
63 override void recursionCheck (widgetID wID, IContent c) {
64 if (wID is id && c is content)
65 throw new WidgetRecursionException (wID);
66 parent.recursionCheck (wID, c);
67 }
68
69 override int clickEvent (wdabs, wdabs, ubyte b, bool state) {
70 if (b == 1 && state == true) {
71 if (!pushed) {
72 parentIPPW.addChildIPPW (this);
73 parentIPPW.menuActive = true;
74 if (popup.width != w && popup.minWidth <= w)
75 popup.setWidth (w, -1); // neatness
76 mgr.positionPopup (this, popup);
77 pushed = true;
78 } else if (!parentIPPW.parentMenuActive) { // if not a submenu
79 parentIPPW.removeChildIPPW (this);
80 }
81 }
82 return 0;
83 }
84
85 override void removedIPPW () {
86 super.removedIPPW;
87 pushed = false;
88 }
89
90 override void underMouse (bool state) {
91 if (state && !pushed && parentIPPW.menuActive) {
92 parentIPPW.addChildIPPW (this);
93 menuActive = true;
94 if (parentIPPW.parentMenuActive)
95 mgr.positionPopup (this, popup, 1);
96 else {
97 if (popup.width != w && popup.minWidth <= w)
98 popup.setWidth (w, -1); // neatness
99 mgr.positionPopup (this, popup);
100 }
101 pushed = true;
102 }
103 }
104
105 override void draw () {
106 mgr.renderer.drawButton (x,y, w,h, pushed);
107 adapter.draw (x,y);
108 }
109
110 protected:
111 void updateVal (Content) { // callback
112 adapter.text = content.toString(cIndex);
113 wdim omw = mw, omh = mh;
114 adapter.getDimensions (mw, mh);
115 if (omw != mw)
116 parent.minWChange (this, mw);
117 if (omh != mh)
118 parent.minHChange (this, mh);
119 }
120 bool pushed = false;
121 IRenderer.TextAdapter adapter;
122 Content content;
123 int cIndex;
124 }
125
126 /** A "tab" widget: it doesn't display the tabs, but shows one of a number of
127 * widgets dependant on an EnumContent.
128 *
129 * Sizability is set once. Min-size is updated when switching. */
130 class SwitchWidget : AParentWidget
131 {
132 this (IWidgetManager mgr, IParentWidget parent, widgetID id, WidgetData data, IContent c) {
133 super (mgr, parent, id);
134 content = cast(EnumContent) c;
135 if (content is null || (subWidgets.length = content.list.length) == 0)
136 throw new ContentException (this);
137 WDCheck (data, 1, subWidgets.length);
138
139 foreach (i,sc; content.list)
140 subWidgets[i] = mgr.makeWidget (this, data.strings[i], sc);
141 currentW = subWidgets[content()];
142
143 content.addCallback (&switchWidget);
144 }
145
146 override bool setup (uint n, uint flags) {
147 bool r = super.setup (n, flags);
148 if (r) {
149 mw = currentW.minWidth;
150 mh = currentW.minHeight;
151 w = currentW.width;
152 h = currentW.height;
153 static if (SIZABILITY & SIZABILITY_ENUM.START_TRUE)
154 isWS = isHS = true;
155 foreach (i,sc; content.list) {
156 static if (SIZABILITY == SIZABILITY_ENUM.ANY_SUBWIDGETS) {
157 isWS |= subWidgets[i].isWSizable;
158 isHS |= subWidgets[i].isHSizable;
159 } else static if (SIZABILITY == SIZABILITY_ENUM.ALL_SUBWIDGETS) {
160 isWS &= subWidgets[i].isWSizable;
161 isHS &= subWidgets[i].isHSizable;
162 }
163 }
164 }
165 return r;
166 }
167
168 override void minWChange (IChildWidget widget, wdim nmw) {
169 if (widget !is currentW) return;
170 mw = nmw;
171 parent.minWChange (this, nmw);
172 }
173 override void minHChange (IChildWidget widget, wdim nmh) {
174 if (widget !is currentW) return;
175 mh = nmh;
176 parent.minHChange (this, nmh);
177 }
178
179 override bool isWSizable () {
180 return isWS;
181 }
182 override bool isHSizable () {
183 return isHS;
184 }
185
186 override void setWidth (wdim nw, int dir) {
187 w = (nw >= mw ? nw : mw);
188 currentW.setWidth (w, dir);
189 }
190 override void setHeight (wdim nh, int dir) {
191 h = (nh >= mh ? nh : mh);
192 currentW.setHeight (h, dir);
193 }
194
195 override void setPosition (wdim nx, wdim ny) {
196 x = nx;
197 y = ny;
198 currentW.setPosition (nx,ny);
199 }
200
201 override IChildWidget getWidget (wdim cx, wdim cy) {
202 return currentW.getWidget (cx, cy);
203 }
204
205 override void draw () {
206 currentW.draw;
207 }
208
209 protected:
210 // callback on content
211 void switchWidget (Content) {
212 currentW = subWidgets[content()];
213 mw = currentW.minWidth;
214 mh = currentW.minHeight;
215 parent.minWChange (this, mw);
216 parent.minHChange (this, mh);
217 // Parent may change size. If it doesn't, we must set child's size.
218 // We can't tell if it did, so do it (call will be fast if size isn't
219 // changed anyway).
220 currentW.setWidth (w, -1);
221 currentW.setHeight (h, -1);
222 currentW.setPosition (x,y);
223 }
224
225 IChildWidget currentW;
226 EnumContent content;
227
228 bool isWS, isHS; // no infrastructure for changing sizability, so need to fix it.
229 }