# HG changeset patch # User Diggory Hardy # Date 1225977399 0 # Node ID dbf332403c6e5732bb1ff406d093a497bbdea376 # Parent 2a364c7d82c93121387089c011cc1f313d0b2914 Improvements to FloatingAreaWidget: positioning, passing click events and draw order. diff -r 2a364c7d82c9 -r dbf332403c6e data/conf/gui.mtt --- a/data/conf/gui.mtt Thu Nov 06 11:07:18 2008 +0000 +++ b/data/conf/gui.mtt Thu Nov 06 13:16:39 2008 +0000 @@ -4,7 +4,7 @@ {Working} - + @@ -14,8 +14,7 @@ - - + + {Basic} diff -r 2a364c7d82c9 -r dbf332403c6e doc/Readme.txt --- a/doc/Readme.txt Thu Nov 06 11:07:18 2008 +0000 +++ b/doc/Readme.txt Thu Nov 06 13:16:39 2008 +0000 @@ -30,6 +30,7 @@ Credits: Me (Diggory Hardy) for just about everything in mde as of now. +Someone (?) for the toDg function in mde.util . Also thanks to: Walter Bright and Digital Mars for D and DMD. diff -r 2a364c7d82c9 -r dbf332403c6e mde/font/FontTexture.d --- a/mde/font/FontTexture.d Thu Nov 06 11:07:18 2008 +0000 +++ b/mde/font/FontTexture.d Thu Nov 06 13:16:39 2008 +0000 @@ -253,7 +253,7 @@ } // if here, no existing texture had the room for the glyph so create a new texture // NOTE: check if using more than one texture impacts performance due to texture switching - logger.info ("Creating a new font texture."); + debug logger.trace ("Creating a new font texture."); tex ~= TexPacker.create(); assert (tex[$-1].addGlyph (ga), "Failed to fit glyph in a new texture but addGlyph didn't throw"); diff -r 2a364c7d82c9 -r dbf332403c6e mde/gui/WidgetManager.d --- a/mde/gui/WidgetManager.d Thu Nov 06 11:07:18 2008 +0000 +++ b/mde/gui/WidgetManager.d Thu Nov 06 13:16:39 2008 +0000 @@ -101,6 +101,7 @@ return; } IChildWidget widg = child.getWidget (cast(wdabs)cx,cast(wdabs)cy); + //debug logger.trace ("Click on {}", widg); if (widg !is null) widg.clickEvent (cast(wdabs)cx,cast(wdabs)cy,b,state); } diff -r 2a364c7d82c9 -r dbf332403c6e mde/gui/widget/Floating.d --- a/mde/gui/widget/Floating.d Thu Nov 06 11:07:18 2008 +0000 +++ b/mde/gui/widget/Floating.d Thu Nov 06 13:16:39 2008 +0000 @@ -33,21 +33,12 @@ static this () { logger = Log.getLogger ("mde.gui.widget.Floating"); } -//FIXME - documentation -/** GUI Window class - * - * A window class instance does two things: (1) specify a region of the screen upon which the window - * and its associated widgets are drawn, and (2) load, save, and generally manage all its widgets. - * - * Let the window load a table of widget data, of type int[][widgetID]. Each widget will, when - * created, be given its int[] of data, which this() must confirm is valid (or throw). - */ /** An area to contain floating widgets. * - * The position of each sub-widget is set from data, but not the size. + * The position of each sub-widget is set from dimension data, but not the size. * Rationale: parents' need to set subwidgets' positions when its position is set, so it needs to - * know their positions. Size setting is still under work FIXME. + * know their positions. * * Data: Each string item is interpreted as a subwidget widgetID. * Ints supplied may consist of just the widget type or @@ -56,29 +47,57 @@ class FloatingAreaWidget : AParentWidget { this (IWidgetManager mgr, widgetID id, WidgetData data) { - subWidgets.length = data.strings.length; - foreach (i,s; data.strings) - subWidgets[i] = mgr.makeWidget (s); - foreach (w; subWidgets) - w.finalize; - sWCoords.length = subWidgets.length; + if (data.ints.length != 1) + throw new WidgetDataException (this); - if (data.ints.length != 1) { - if (data.ints.length != 2*subWidgets.length + 1) { - throw new WidgetDataException (this); - } - foreach (i, ref c; sWCoords) { - c.x = cast(wdim) data.ints[i + 1]; - c.y = cast(wdim) data.ints[i + 1 + sWCoords.length]; - } + subWidgets.length = data.strings.length; // widgets created from string data + sWOrder.length = subWidgets.length; + foreach (i,s; data.strings) { + subWidgets[i] = mgr.makeWidget (s); + sWOrder[i] = i; + } + + sWCoords = mgr.dimData (id); + if (sWCoords.length != subWidgets.length * 2) { + // don't bother logging a warning; correct data will be saved anyway + sWCoords.length = subWidgets.length * 2; // maybe some data kept } super (mgr, id, data); + } + + bool saveChanges () { + foreach (widget; subWidgets) + widget.saveChanges (); - foreach (w; subWidgets) { - //FIXME: set default size - w.setWidth (w.minWidth, -1); - w.setHeight (w.minHeight, -1); + mgr.setDimData (id, sWCoords); // save positions + return true; + } + + void setWidth (wdim nw, int) { + w = nw; + // check all floating widgets are visible + foreach (i, widg; subWidgets) { + wdim d; + if (sWCoords[i] + (d = widg.width) > w) { + if (d > w) + sWCoords[i] = 0; + else + sWCoords[i] = w - d; + } + } + } + void setHeight (wdim nh, int) { + h = nh; + foreach (i, widg; subWidgets) { + wdim d; + size_t n = i + subWidgets.length; + if (sWCoords[n] + (d = widg.height) > h) { + if (d > h) + sWCoords[n] = 0; + else + sWCoords[n] = h - d; + } } } @@ -88,8 +107,9 @@ void setPosition (wdim x, wdim y) { super.setPosition (x,y); - foreach (i,c; sWCoords) - subWidgets[i].setPosition (x+c.x, y+c.y); + size_t n = subWidgets.length; + foreach (i,widg; subWidgets) + widg.setPosition (x+sWCoords[i], y+sWCoords[i+n]); } void draw () { @@ -97,12 +117,32 @@ mgr.renderer.restrict (x,y, w,h); - foreach (w; subWidgets) - w.draw; + foreach (i; sWOrder) + subWidgets[i].draw; + } + + IChildWidget getWidget (wdim cx, wdim cy) { + debug assert (cx >= x && cx < x + w && cy >= y && cy < y + h, "getWidget: not on widget (code error)"); + + size_t n = subWidgets.length; + foreach_reverse (j,i; sWOrder) { + wdim lx = cx - (x + sWCoords[i ]); + wdim ly = cy - (y + sWCoords[i+n]); + if (lx >= 0 && lx < subWidgets[i].width && + ly >= 0 && ly < subWidgets[i].height) + { + sWOrder[j..$-1] = sWOrder[j+1..$].dup; + sWOrder[$-1] = i; + mgr.requestRedraw; + return subWidgets[i]; + } + } + return this; // no match } protected: - wdimPair[] sWCoords; // coords for subwidgets, relative to this widget + wdim[] sWCoords; // coords for subwidgets, relative to this widget: [x1,x2,...,y1,y2,...] + size_t[] sWOrder; // indexes for draw order (top widget at end of list) /+ /** Call after loading is finished to setup the window and confirm that it's valid. diff -r 2a364c7d82c9 -r dbf332403c6e mde/gui/widget/Ifaces.d --- a/mde/gui/widget/Ifaces.d Thu Nov 06 11:07:18 2008 +0000 +++ b/mde/gui/widget/Ifaces.d Thu Nov 06 13:16:39 2008 +0000 @@ -138,9 +138,9 @@ * initialisation data. The method should throw a WidgetDataException (created without * parameters) if the data has wrong length or is otherwise invalid. * - * A parent widget is responsible for setting the size of its children widgets, however it must - * satisfy their minimal sizes as available from minWidth() and minHeight(). setWidth() and - * setHeight() are called on all widgets after creation. + * All widgets should set their own size in this() or finalize(), although some parents may set + * child-widgets' size during their creation. Widgets may rely on setPosition() being called after + * finalize(). * * Also see finalize(). *************************************************************************************************/ diff -r 2a364c7d82c9 -r dbf332403c6e mde/gui/widget/TextWidget.d --- a/mde/gui/widget/TextWidget.d Thu Nov 06 11:07:18 2008 +0000 +++ b/mde/gui/widget/TextWidget.d Thu Nov 06 13:16:39 2008 +0000 @@ -41,6 +41,8 @@ * adapter = mgr.renderer.getAdapter ("string", 0xRRGGBB); */ this (IWidgetManager mgr, widgetID id, WidgetData data) { adapter.getDimensions (mw, mh); + w = mw; + h = mh; super (mgr, id, data); } diff -r 2a364c7d82c9 -r dbf332403c6e mde/gui/widget/Widget.d --- a/mde/gui/widget/Widget.d Thu Nov 06 11:07:18 2008 +0000 +++ b/mde/gui/widget/Widget.d Thu Nov 06 13:16:39 2008 +0000 @@ -208,7 +208,7 @@ /** For pressable buttons. * - * Normally overriding classes implement this, draw and activated. */ + * Overriding classes should implement this() (setting the size), draw() and activated(). */ abstract class AButtonWidget : AWidget { protected this (IWidgetManager mgr, widgetID id, WidgetData data) {