Mercurial > projects > mde
comparison mde/gui/widget/PopupMenu.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 | 5b37d0400732 |
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 * Pop-up menus based on content structures. | 17 * Pop-up menus based on content structures. |
18 *************************************************************************************************/ | 18 *****************************************************************************/ |
19 module mde.gui.widget.PopupMenu; | 19 module mde.gui.widget.PopupMenu; |
20 | 20 |
21 import mde.gui.widget.Widget; | 21 import mde.gui.widget.AParentWidget; |
22 import mde.gui.widget.TextWidget; | |
23 import mde.gui.widget.layout; | |
24 | 22 |
25 import mde.content.miscContent; | 23 import mde.content.miscContent; |
26 import mde.gui.exception; | 24 import mde.gui.exception; |
27 | 25 |
28 debug { | 26 debug { |
31 static this () { | 29 static this () { |
32 logger = Log.getLogger ("mde.gui.widget.PopupMenu"); | 30 logger = Log.getLogger ("mde.gui.widget.PopupMenu"); |
33 } | 31 } |
34 } | 32 } |
35 | 33 |
36 /************************************************************************************************* | 34 /****************************************************************************** |
37 * Widget which pops up a menu based on a content. | 35 * Widget which pops up a menu based on a content. |
38 *************************************************************************************************/ | 36 *****************************************************************************/ |
39 class PopupMenuWidget : AParentSingleWidget | 37 class PopupMenuWidget : APopupParentWidget |
40 { | 38 { |
41 this (IWidgetManager mgr, IParentWidget parent, widgetID id, WidgetData data, IContent c) { | 39 this (IWidgetManager mgr, IParentWidget parent, widgetID id, WidgetData data, IContent c) { |
42 content = c; | 40 content = c; |
43 WDCMinCheck (data, 1,1, content); | 41 WDCMinCheck (data, 1,1, content); |
44 super (mgr, parent, id); | 42 super (mgr, parent, id); |
45 | 43 |
46 subWidget = mgr.makeWidget (this, data.strings[0], content); | 44 popup = mgr.makeWidget (this, data.strings[0], content); |
45 subWidgets = [popup]; | |
47 | 46 |
48 adapter = mgr.renderer.getAdapter; | 47 adapter = mgr.renderer.getAdapter; |
49 adapter.text = content.toString (1); | 48 adapter.text = content.toString (1); |
50 adapter.getDimensions (mw, mh); | 49 adapter.getDimensions (mw, mh); |
51 w = mw; | 50 w = mw; |
52 h = mh; | 51 h = mh; |
53 } | 52 } |
54 | 53 |
55 override int clickEvent (wdabs, wdabs, ubyte b, bool state) { | 54 override int clickEvent (wdabs, wdabs, ubyte b, bool state) { |
56 if (b == 1 && state == true) { | 55 if (b == 1 && state == true) { |
57 // If active, the popup is closed by WidgetManager since the click isn't on the popup. | |
58 if (!pushed) { | 56 if (!pushed) { |
59 pushed = true; | 57 parentIPPW.addChildIPPW (this); |
60 mgr.addPopup (this, subWidget); // causes redraw | 58 parentIPPW.menuActive = true; |
61 mgr.addClickCallback (&openMenuCallback); // prevents first up-click from closing menu, if on self. | 59 mgr.positionPopup (this, popup); |
62 } | 60 pushed = true; |
61 } else { | |
62 // NOTE: perhaps shouldn't do anything when | |
63 // parentIPPW.parentIPPW.menuActive | |
64 // (this causes funny behaviour when clicking a submenu): | |
65 parentIPPW.removeChildIPPW (this); | |
66 } | |
63 } | 67 } |
64 return 0; | 68 return 0; |
65 } | 69 } |
66 | 70 |
67 override void popupClose () { | 71 override void removedIPPW () { |
72 super.removedIPPW; | |
68 pushed = false; | 73 pushed = false; |
69 } | 74 } |
70 override bool popupParentClick () { | 75 |
71 pushed = false; | 76 override void underMouse (bool state) { |
72 return true; | 77 if (state && !pushed && parentIPPW.menuActive) { |
78 parentIPPW.addChildIPPW (this); | |
79 menuActive = true; | |
80 mgr.positionPopup (this, popup, 1); // causes redraw | |
81 pushed = true; | |
82 } | |
73 } | 83 } |
74 | 84 |
75 override void draw () { | 85 override void draw () { |
76 mgr.renderer.drawButton (x,y, w,h, pushed); | 86 mgr.renderer.drawButton (x,y, w,h, pushed); |
77 adapter.draw (x,y); | 87 adapter.draw (x,y); |
78 } | 88 } |
79 | 89 |
80 protected: | 90 protected: |
81 bool openMenuCallback (wdabs cx, wdabs cy, ubyte b, bool state) { | |
82 if (b == 1 && state == false) { // receive first up-click | |
83 mgr.removeCallbacks (cast(void*) this); | |
84 if (cx >= x && cx < x+w && cy >= y && cy < y+h) | |
85 return true; // up-click is on self; don't close the menu | |
86 } | |
87 return false; | |
88 } | |
89 bool pushed = false; | 91 bool pushed = false; |
90 IRenderer.TextAdapter adapter; | 92 IRenderer.TextAdapter adapter; |
91 IContent content; | 93 IContent content; |
92 } | 94 } |
93 | |
94 /************************************************************************************************* | |
95 * Widget which pops up a sub-menu based on a content on mouse-over. | |
96 *************************************************************************************************/ | |
97 class SubMenuWidget : PopupMenuWidget | |
98 { | |
99 this (IWidgetManager mgr, IParentWidget parent, widgetID id, WidgetData data, IContent c) { | |
100 super (mgr, parent, id, data, c); | |
101 } | |
102 | |
103 override int clickEvent (wdabs, wdabs, ubyte b, bool state) { | |
104 return 0; | |
105 } | |
106 | |
107 override void highlight (bool state) { | |
108 if (state && !pushed) { | |
109 pushed = true; | |
110 mgr.addPopup (this, subWidget, 1); // causes redraw | |
111 } | |
112 } | |
113 } | |
114 | |
115 /************************************************************************************************* | |
116 * A function which returns a ContentListWidget or MenuButtonContentWidget. | |
117 *************************************************************************************************/ | |
118 IChildWidget flatMenuContent (IWidgetManager mgr, IParentWidget parent, widgetID id, WidgetData data, IContent c) { | |
119 if (c is null) throw new ContentException; | |
120 if (cast(IContentList) c) | |
121 return new ContentListWidget(mgr,parent,id,data,c); | |
122 if (cast(EventContent) c) | |
123 return new MenuButtonContentWidget(mgr,parent,id,data,c); | |
124 // generic uneditable option | |
125 return new DisplayContentWidget(mgr,parent,id,data,c); | |
126 } | |
127 | |
128 /************************************************************************************************* | |
129 * A function which returns a SubMenuWidget or MenuButtonContentWidget. | |
130 *************************************************************************************************/ | |
131 IChildWidget subMenuContent (IWidgetManager mgr, IParentWidget parent, widgetID id, WidgetData data, IContent c) { | |
132 if (c is null) throw new ContentException; | |
133 if (cast(IContentList) c) | |
134 return new SubMenuWidget(mgr,parent,id,data,c); | |
135 if (cast(EventContent) c) | |
136 return new MenuButtonContentWidget(mgr,parent,id,data,c); | |
137 // generic uneditable option | |
138 return new DisplayContentWidget(mgr,parent,id,data,c); | |
139 } | |
140 | |
141 /************************************************************************************************* | |
142 * A menu content-button, like ButtonContentWidget, but which can be activated with the up-click. | |
143 *************************************************************************************************/ | |
144 class MenuButtonContentWidget : ATextWidget | |
145 { | |
146 this (IWidgetManager mgr, IParentWidget parent, widgetID id, WidgetData, IContent c) { | |
147 content = cast(EventContent) c; | |
148 if (content is null) throw new ContentException (this); | |
149 adapter = mgr.renderer.getAdapter (); | |
150 super (mgr, parent, id); | |
151 } | |
152 | |
153 override bool setup (uint n, uint flags) { | |
154 if (!(flags & 3)) return false; // string or renderer (and possibly font) changed | |
155 adapter.text = content.toString(1); | |
156 return super.setup (n, 3); // force redimensioning | |
157 } | |
158 | |
159 override int clickEvent (wdabs, wdabs, ubyte b, bool state) { | |
160 if (b == 1) { // on up or down click | |
161 pushed = false; | |
162 mgr.requestRedraw; | |
163 content.endEvent; | |
164 } | |
165 return 0; | |
166 } | |
167 | |
168 override void highlight (bool state) { | |
169 pushed = state; | |
170 } | |
171 | |
172 override void draw () { | |
173 mgr.renderer.drawButton (x,y, w,h, pushed); | |
174 adapter.draw (x,y); | |
175 } | |
176 | |
177 protected: | |
178 EventContent content; | |
179 bool pushed; | |
180 } |