comparison mde/gui/WMScreen.d @ 159:b06b04c75e86

Finished last commit, rearranged code for the WidgetManager class. There is now a GUI options section. Created a third WidgetManager class called WidgetLoader to handle file loading/saving. Moved most of the code in WMScreen's draw/clickEvent/motionEvent functions to WidgetManager.
author Diggory Hardy <diggory.hardy@gmail.com>
date Thu, 21 May 2009 20:55:10 +0200
parents a86f8445ccc8
children 7f7b2011b759
comparison
equal deleted inserted replaced
158:f132e599043f 159:b06b04c75e86
20 * (likely also with content modules). 20 * (likely also with content modules).
21 *****************************************************************************/ 21 *****************************************************************************/
22 module mde.gui.WMScreen; 22 module mde.gui.WMScreen;
23 23
24 import mde.gui.WidgetManager; 24 import mde.gui.WidgetManager;
25 import mde.gui.WidgetLoader;
25 import mde.gui.widget.Ifaces; 26 import mde.gui.widget.Ifaces;
26 import mde.gui.renderer.createRenderer; 27 import mde.gui.renderer.createRenderer;
27 28
28 import mde.setup.Screen; 29 import mde.setup.Screen;
29 import mde.input.Input; 30 import mde.input.Input;
44 * 45 *
45 * Currently mouse coordinates are passed to widgets untranslated. It may make 46 * Currently mouse coordinates are passed to widgets untranslated. It may make
46 * sense to translate them and possibly drop events for some uses, such as if 47 * sense to translate them and possibly drop events for some uses, such as if
47 * the gui is drawn to a texture. 48 * the gui is drawn to a texture.
48 * 49 *
49 * Public non IWidget* methods should be thread-safe. 50 * Public non IWidget* methods should be thread-safe, even to the same
51 * instance (by locking on a mutex).
50 *****************************************************************************/ 52 *****************************************************************************/
51 scope class WMScreen : AWidgetManager, Screen.IDrawable { 53 scope class WMScreen : AWidgetLoader, Screen.IDrawable {
52 /** Construct a new widget manager. 54 /** Construct a new widget manager.
53 * 55 *
54 * Must be run after static this. 56 * Must be run after static this.
55 * 57 *
56 * params: 58 * params:
70 /** Draw the gui. */ 72 /** Draw the gui. */
71 void draw() { 73 void draw() {
72 synchronized(mutex) { 74 synchronized(mutex) {
73 debug (mdeDrawEvents) 75 debug (mdeDrawEvents)
74 logger.trace ("drawing"); 76 logger.trace ("drawing");
75 if (child) 77 wmDrawWidgets();
76 child.draw;
77 if (childIPPW)
78 childIPPW.drawPopup;
79 drawPopup;
80 } 78 }
81 } 79 }
82 80
83 /** For mouse click events. 81 /** For mouse click events. */
84 *
85 * Sends the event on to the relevant windows and all click callbacks. */
86 void clickEvent (ushort usx, ushort usy, ubyte b, bool state) { 82 void clickEvent (ushort usx, ushort usy, ubyte b, bool state) {
87 try { 83 try {
88 mutex.lock; 84 mutex.lock;
89 scope(exit) mutex.unlock; 85 scope(exit) mutex.unlock;
90 if (child is null) return; 86 wmMouseClick (cast(wdabs) usx, cast(wdabs) usy, b, state);
91
92 wdabs cx = cast(wdabs) usx, cy = cast(wdabs) usy;
93
94 // Callbacks have the highest priority receiving events (e.g. a button release)
95 foreach (dg; clickCallbacks)
96 if (dg (cx, cy, b, state)) return;
97
98 // Update underMouse to get the widget clicked on
99 updateUnderMouse (cx, cy, state);
100
101 // Disable keyboard input if on another widget:
102 if (keyFocus && keyFocus !is underMouse) {
103 keyFocus.keyFocusLost;
104 keyFocus = null;
105 input.setLetterCallback (null);
106 }
107
108 // Finally, post the actual event:
109 if (b == 3 && state) { // right click - open context menu
110 IContent contextContent = underMouse.content;
111 if (contextContent is null) return;
112 // NOTE: Creates new widgets every time; not optimal
113 popupContext = makeWidget (this, "context", contextContent);
114 popupContext.setup (0, 3);
115 positionPopup (underMouse, popupContext);
116 requestRedraw;
117 } else // post other button presses to clickEvent
118 if (underMouse.clickEvent (cast(wdabs)cx,cast(wdabs)cy,b,state) & 1) {
119 // keyboard input requested
120 keyFocus = underMouse;
121 input.setLetterCallback (&underMouse.keyEvent);
122 }
123 } catch (Exception e) { 87 } catch (Exception e) {
124 logger.error ("clickEvent: exception processing event: {}", e.msg); 88 logger.error ("clickEvent: exception processing event: {}", e.msg);
125 } 89 }
126 } 90 }
127 91
128 /** For mouse motion events. 92 /** For mouse motion events. */
129 *
130 * Sends the event on to all motion callbacks. */
131 void motionEvent (ushort scx, ushort scy) { 93 void motionEvent (ushort scx, ushort scy) {
132 try { 94 try {
133 mutex.lock; 95 mutex.lock;
134 scope(exit) mutex.unlock; 96 scope(exit) mutex.unlock;
135 wdabs cx = cast(wdabs) scx, cy = cast(wdabs) scy; 97 wmMouseMotion (cast(wdabs) scx, cast(wdabs) scy);
136 foreach (dg; motionCallbacks)
137 dg (cx, cy);
138
139 updateUnderMouse (cx, cy, false);
140 } catch (Exception e) { 98 } catch (Exception e) {
141 logger.error ("motionEvent: exception processing event: {}", e.msg); 99 logger.error ("motionEvent: exception processing event: {}", e.msg);
142 } 100 }
143 } 101 }
144 102
164 child.setHeight (h, -1); 122 child.setHeight (h, -1);
165 child.setPosition (0,0); 123 child.setPosition (0,0);
166 } 124 }
167 125
168 protected: 126 protected:
127 final override void setLetterCallback(void delegate(ushort, char[]) dlg) {
128 input.setLetterCallback (dlg);
129 }
130
169 /* Second stage of widget loading. 131 /* Second stage of widget loading.
170 * Note: sizeEvent should be called with window size before this. */ 132 * Note: sizeEvent should be called with window size before this. */
171 final override void createRootWidget () { 133 final override void createRootWidget () {
172 // The renderer needs to be created on the first load, but not after this. 134 // The renderer needs to be created on the first load, but not after this.
173 if (rend is null) 135 if (rend is null)