Mercurial > projects > mde
diff mde/gui/widget/Window.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/widget/Window.d Thu May 01 10:55:04 2008 +0100 +++ b/mde/gui/widget/Window.d Fri May 02 16:03:52 2008 +0100 @@ -28,6 +28,13 @@ // not yet implemented: //import tango.scrapple.text.convert.parseFrom : parseFrom; +import tango.util.log.Log : Log, Logger; + +private Logger logger; +static this () { + logger = Log.getLogger ("mde.gui.widget.Window"); +} + /** GUI Window class * * A window class instance does two things: (1) specify a region of the screen upon which the window @@ -39,23 +46,31 @@ class Window : mt.IDataSection, IWindow { //BEGIN Methods for GUI + this (char[] id) { + name = id; + } + /** Call after loading is finished to setup the window and confirm that it's valid. * * Throws: WindowLoadException. Do not use the instance in this case! */ - void finalise (IGui gui) { + void finalise (IGui gui) + in { + assert (gui !is null, "Window.finalise ("~name~"): gui is null"); + } body { // Check data was loaded: if (widgetData is null) throw new WindowLoadException ("No widget data"); - // Create the renderer: + gui_ = gui; rend = gui.renderer; // Create the primary widget (and indirectly all sub-widgets), throwing on error: - widget = getWidget (0, this);// primary widget always has ID 0. + widget = makeWidget (0, this);// primary widget always has ID 0. widgetData = null; // data is no longer needed: allow GC to collect (cannot safely delete) widgetX = x + rend.windowBorder; // widget position widgetY = y + rend.windowBorder; // must be updated if the window is moved + widget.setPosition (widgetX, widgetY); widget.getCurrentSize (w,h);// Find the initial size w += rend.windowBorder * 2; // Adjust for border @@ -64,23 +79,6 @@ xw = x+w; yh = y+h; } - - void draw () { - // background - rend.drawWindow (x,y, w,h); - - // Tell the widget to draw itself: - widget.draw(widgetX, widgetY); - } - - void clickEvent (ushort cx, ushort cy, ubyte b, bool state) { - if (cx >= x && cx < xw && cy >= y && cy < yh) { // click on window? - if (cx >= widgetX && cx < xw-rend.windowBorder && cy >= widgetY && cy < yh-rend.windowBorder) // click on widget? - widget.clickEvent (cx-widgetX, cy-widgetY, b, state); - // FIXME: else window dragging? - } - } - //BEGIN Mergetag code void addTag (char[] tp, mt.ID id, char[] dt) { if (tp == "int[][int]") { @@ -104,17 +102,21 @@ /** Get/create a widget by ID. * * Should $(I only) be called internally and by sub-widgets! */ - IWidget getWidget (widgetID i, IParentWidget parent) + IWidget makeWidget (widgetID i, IWidget parent) in { // widgetData is normally left to be garbage collected after widgets have been created: - assert (widgetData !is null, "getWidget: widgetData is null"); + assert (widgetData !is null, "Window.makeWidget ("~name~"): widgetData is null"); } body { // See if it's already been created: IWidget* p = i in widgets; - if (p !is null) return *p; // yes - else { // no + if (p !is null) { // yes + char[128] tmp; + logger.warn (logger.format (tmp, "Window.makeWidget ("~name~"): widget {} has multiple uses!", i)); + return *p; + } + else { // no int[]* d = i in widgetData; - if (d is null) throw new WindowLoadException ("Widget not found"); + if (d is null) throw new WindowLoadException ("Window.makeWidget ("~name~"): Widget not found"); // Throws WidgetDataException (a WindowLoadException) if bad data: IWidget widg = createWidget (this, parent, *d); @@ -123,6 +125,10 @@ } } + IGui gui () { + return gui_; + } + /+void requestRedraw () { }+/ @@ -131,15 +137,62 @@ } //END IWindow methods - //BEGIN IParentWidget methods - //END IParentWidget methods + //BEGIN IWidget methods + void getMinimumSize (out int w, out int h) { + widget.getMinimumSize (x,y); + w += rend.windowBorder * 2; // Adjust for border + h += rend.windowBorder * 2; + } + void getCurrentSize (out int cw, out int ch) { + cw = w; + ch = h; + } + + void setPosition (int x, int y) { + /+ Note: this is currently unused. Maybe only use it internally? + this.x = x; + this.y = y; + + widgetX = x + rend.windowBorder; + widgetY = y + rend.windowBorder; + + widget.setPosition (widgetX, widgetY); + +/ + } + + IWidget getWidget (int cx, int cy) { + if (cx < x || cx >= xw || cy < y || cy >= yh) // not over window + return null; + if (cx >= widgetX && cx < xw-rend.windowBorder && cy >= widgetY && cy < yh-rend.windowBorder) + // over the widget + return widget.getWidget (cx, cy); + else // over the window border + return this; + } + void clickEvent (ushort cx, ushort cy, ubyte b, bool state) { + //if (cx >= x && cx < xw && cy >= y && cy < yh) { // click on window? + // FIXME: repositioning? + } + + void draw () { + // background + rend.drawWindow (x,y, w,h); + + // Tell the widget to draw itself: + widget.draw(); + } + //END IWidget methods private: + char[] name; // The window's name (id from config file) + IGui gui_; // The gui managing this window + int[][widgetID] widgetData; // Data for all widgets under this window (deleted after loading) IWidget[widgetID] widgets; // List of all widgets under this window (created on demand). IWidget widget; // The primary widget in this window. IRenderer rend; // The window's renderer + // FIXME: revise which parameters are stored once Gui knows window position int x,y; // Window position int w,h; // Window size (calculated from Widgets) int xw, yh; // x+w, y+h (frequent use by clickEvent)