Mercurial > projects > mde
diff mde/gui/Gui.d @ 34:6b4116e6355c
Work on the Gui: some of the framework for drag & drop. Also made Window an IWidget.
Implemented getWidget(x,y) to find the widget under this location for IWidgets (but not Gui).
Made Window an IWidget and made it work a little more similarly to widgets.
Implemented callbacks on the Gui for mouse events (enabling drag & drop, etc.).
committer: Diggory Hardy <diggory.hardy@gmail.com>
author | Diggory Hardy <diggory.hardy@gmail.com> |
---|---|
date | Fri, 02 May 2008 16:03:52 +0100 |
parents | 316b0230a849 |
children | 928db3c75ed3 |
line wrap: on
line diff
--- a/mde/gui/Gui.d Thu May 01 10:55:04 2008 +0100 +++ b/mde/gui/Gui.d Fri May 02 16:03:52 2008 +0100 @@ -22,6 +22,7 @@ module mde.gui.Gui; import mde.gui.IGui; +import mde.gui.widget.Ifaces; import mde.gui.widget.Window; import mde.gui.renderer.createRenderer; import mde.gui.exception; @@ -46,9 +47,6 @@ // Handle externally or with a GUI Manager? /** A GUI handles a bunch of windows, all to be drawn to the same device. */ -/* NOTE: currently GUI just keeps a list of windows and simply calls draw and clickEvent on them all. -* Coords should be stored here and draw/clickEvent should be called like for widgets. -* (Also functionality like z-order?) */ class Gui : IGui { //BEGIN Methods for external use //BEGIN Loading code @@ -62,8 +60,8 @@ IReader reader; try { reader = confDir.makeMTReader (fileName, PRIORITY.HIGH_ONLY, null, true); - reader.dataSecCreator = delegate mt.IDataSection(mt.ID) { - return new Window; + reader.dataSecCreator = delegate mt.IDataSection(mt.ID id) { + return new Window (id); }; reader.read; } catch (mt.MTException e) { @@ -105,18 +103,35 @@ * Currently no concept of how to draw overlapping windows, or how to not bother drawing windows * which don't need redrawing. */ void draw() { - foreach (w; windows) - w.draw(); + foreach_reverse (w; windows) // Draw, starting with back-most window. + w.draw; } - /** Send an input event. + /** For mouse click events. * - * I.e. send all mouse click events to all active GUIs, which check the coordinates and forward - * to any relevent windows. */ + * Sends the event on to the relevant windows and all click callbacks. */ void clickEvent (ushort cx, ushort cy, ubyte b, bool state) { - foreach (w; windows) - w.clickEvent (cx,cy,b,state); + // NOTE: buttons receive the up-event even when drag-callbacks are in place. + foreach (dg; clickCallbacks) + dg (cx, cy, b, state); + + foreach (w; windows) { + IWidget widg = w.getWidget (cx,cy); + if (widg !is null) { + widg.clickEvent (cx,cy,b,state); + return; // only pass to first window + } + } } + + /** For mouse motion events. + * + * Sends the event on to all motion callbacks. */ + void motionEvent (ushort cx, ushort cy) { + foreach (dg; motionCallbacks) + dg (cx, cy); + } + //END Methods for external use //BEGIN IGui methods @@ -126,9 +141,23 @@ } body { return rend; } + + void addClickCallback (void delegate(ushort, ushort, ubyte, bool) dg) { + clickCallbacks[dg.ptr] = dg; + } + void addMotionCallback (void delegate(ushort, ushort) dg) { + motionCallbacks[dg.ptr] = dg; + } + void removeCallbacks (void* frame) { + clickCallbacks.remove(frame); + motionCallbacks.remove(frame); + } //END IGui methods private: - Window[] windows; + Window[] windows; // Windows. First window is "on top", others may be obscured. IRenderer rend; + // callbacks indexed by their frame pointers: + void delegate(ushort cx, ushort cy, ubyte b, bool state) [void*] clickCallbacks; + void delegate(ushort cx, ushort cy) [void*] motionCallbacks; }