# HG changeset patch # User Diggory Hardy # Date 1215278866 -3600 # Node ID 159775502bb461672be1eefc26474c9395d40ea3 # Parent 77c7d32351144e5cd7015a2183247afda6e889e8 The first dynamically generated widget lists, based on Options, are here! diff -r 77c7d3235114 -r 159775502bb4 codeDoc/jobs.txt --- a/codeDoc/jobs.txt Sat Jul 05 15:36:39 2008 +0100 +++ b/codeDoc/jobs.txt Sat Jul 05 18:27:46 2008 +0100 @@ -3,7 +3,6 @@ In progress: -in mdeOld branch: GUI Content. @@ -53,5 +52,3 @@ Done (for mercurial log message): -Added content IDs... -Added widget strings... \ No newline at end of file diff -r 77c7d3235114 -r 159775502bb4 data/conf/gui.mtt --- a/data/conf/gui.mtt Sat Jul 05 15:36:39 2008 +0100 +++ b/data/conf/gui.mtt Sat Jul 05 18:27:46 2008 +0100 @@ -12,4 +12,4 @@ {WEmbedded} - + diff -r 77c7d3235114 -r 159775502bb4 mde/gui/content/Content.d --- a/mde/gui/content/Content.d Sat Jul 05 15:36:39 2008 +0100 +++ b/mde/gui/content/Content.d Sat Jul 05 18:27:46 2008 +0100 @@ -29,10 +29,9 @@ */ // Don't include dimension/drawing stuff because it's renderer specific and content should not be! // NOTE: an interface or a class? -alias IContent Content; // use either name until it's settled... -/** ditto */ interface IContent { + /+ NOTE: None of this is really used yet, but was (mostly) intended for clipboard copying. /** Return a copy of self. */ IContent dup (); @@ -42,6 +41,7 @@ // FIXME: throw or return null on error or unsupported conversion? ContentText toText (); ContentInt toInt (); /// ditto + +/ /** Every Content should be convertible to a string, which, if possible, should be a sensible * conversion of its content. */ @@ -66,7 +66,7 @@ * Could alternately be: * alias ContentTextStruct* ContentText * where ContentTextStruct is a struct. */ -class ContentText : Content +class ContentText : IContent { this () {} this (char[] text) { @@ -98,7 +98,7 @@ } /** Integer content. */ -class ContentInt : Content +class ContentInt : IContent { this () {} this (int integer) { diff -r 77c7d3235114 -r 159775502bb4 mde/gui/widget/Ifaces.d --- a/mde/gui/widget/Ifaces.d Sat Jul 05 15:36:39 2008 +0100 +++ b/mde/gui/widget/Ifaces.d Sat Jul 05 18:27:46 2008 +0100 @@ -70,8 +70,9 @@ * A widget is a region of a GUI window which handles rendering and user-interaction for itself * and is able to communicate with it's window and parent/child widgets as necessary. * - * A widget's constructor should have the prototype and doc explaining what initialization data is - * used (excluding the widget ID, which every widget recieves): + * If a widget is to be creatable by Window.makeWidget, it must be listed in the createWidget + * module, have a constructor of the following form, and should implement getCreationData(). + * Use Ddoc to explain what initialization data is used. * ---------------------------------- * /++ Constructor for a ... widget. * + diff -r 77c7d3235114 -r 159775502bb4 mde/gui/widget/TextWidget.d --- a/mde/gui/widget/TextWidget.d Sat Jul 05 15:36:39 2008 +0100 +++ b/mde/gui/widget/TextWidget.d Sat Jul 05 18:27:46 2008 +0100 @@ -86,3 +86,50 @@ alias ContentWidget!(ContentText) TextWidget; alias ContentWidget!(ContentInt) IntWidget; + + +/// Adapter to ease use of ContentOptionWidget +struct ContentOptionAdapter { + void set (IContent c, int col) { + if (font is null) font = FontStyle.get("default"); + + content = c; + colour = Colour (cast(ubyte) (col >> 16u), + cast(ubyte) (col >> 8u), + cast(ubyte) col ); + } + + void getDimensions (out wdsize w, out wdsize h) { + font.updateBlock (content.toString, textCache); + w = cast(wdim) textCache.w; + h = cast(wdim) textCache.h; + } + + void draw (wdabs x, wdabs y) { + font.textBlock (x,y, content.toString, textCache, colour); + } + + IContent content; + TextBlock textCache; + Colour colour; + static FontStyle font; +} + +/// Basic text widget +class ContentOptionWidget : Widget +{ + this (IWindow wind, int[] data, IContent c) { + if (data.length != 2) throw new WidgetDataException; + content.set (c, data[1]); + content.getDimensions (mw, mh); + super (wind,data); + } + + void draw () { + super.draw(); + content.draw (x,y); + } + +protected: + ContentOptionAdapter content; +} diff -r 77c7d3235114 -r 159775502bb4 mde/gui/widget/createWidget.d --- a/mde/gui/widget/createWidget.d Sat Jul 05 15:36:39 2008 +0100 +++ b/mde/gui/widget/createWidget.d Sat Jul 05 18:27:46 2008 +0100 @@ -69,7 +69,8 @@ Text = 0x21, Int = 0x22, - GridLayout = LAYOUT | WSIZABLE | HSIZABLE | 0x4 + GridLayout = LAYOUT | WSIZABLE | HSIZABLE | 0x4, + TrialContentLayout = LAYOUT | WSIZABLE | HSIZABLE | 0x5 } //const char[][int] WIDGET_NAMES; @@ -81,7 +82,8 @@ "Int", "SizableBlank", "Button", - "GridLayout" ]; + "GridLayout", + "TrialContentLayout"]; // Purely to add indentation. Could just return "" without affecting functionality. static char[] indent (uint i) { diff -r 77c7d3235114 -r 159775502bb4 mde/gui/widget/layout.d --- a/mde/gui/widget/layout.d Sat Jul 05 15:36:39 2008 +0100 +++ b/mde/gui/widget/layout.d Sat Jul 05 18:27:46 2008 +0100 @@ -19,6 +19,9 @@ import mde.gui.widget.Widget; import mde.gui.exception; +import mde.gui.widget.TextWidget; +import mde.gui.content.options; + debug { import tango.util.log.Log : Log, Logger; private Logger logger; @@ -84,24 +87,31 @@ /************************************************************************************************* * Trial layout of sub-widgets of one type only. *************************************************************************************************/ -class TrialLayout : GridWidget +class TrialContentLayoutWidget : GridWidget { this (IWindow wind, int[] data) { - assert (false, "Not ready"); - if (data.length != 6) throw new WidgetDataException; - super (wind, data); + debug scope (failure) + logger.warn ("TrialContentLayoutWidget: failure"); + if (data.length != 3) throw new WidgetDataException; - rows = data[1]; - cols = data[2]; + OptionList optsList = OptionList.trial(); + rows = optsList.list.length; + cols = 1; // Get all sub-widgets subWidgets.length = rows*cols; - foreach (i, ref subWidget; subWidgets) { - //subWidget = new ContentWidget (data[3..6]); + foreach (i, c; optsList.list) { + subWidgets[i] = new ContentOptionWidget (wind, data[1..3], c); } + super (wind, data); } + int[] getCreationData () { + return [widgetType]; + } +private: + OptionList optsList; } @@ -115,7 +125,7 @@ * * The grid has no border but has spacing between widgets. *************************************************************************************************/ -class GridWidget : Widget +abstract class GridWidget : Widget { //BEGIN Creation & saving /** Partial constructor for a grid layout widget. diff -r 77c7d3235114 -r 159775502bb4 mde/lookup/Options.d --- a/mde/lookup/Options.d Sat Jul 05 15:36:39 2008 +0100 +++ b/mde/lookup/Options.d Sat Jul 05 18:27:46 2008 +0100 @@ -206,7 +206,7 @@ static if (!TIsIn!(T,TYPES)) static assert (false, "Options.set does not currently support type "~T.stringof); - mixin (`alias opts`~T.stringof~` optsVars;`); + mixin (`alias opts`~TName!(T)~` optsVars;`); changed = true; // something got set (don't bother checking this isn't what it already was) @@ -215,10 +215,37 @@ optionChanges.set!(T) (cast(ID) symbol, val); } catch (ArrayBoundsException) { // log and ignore: - logger.error ("Options.set: unkw!"); + logger.error ("Options.set: invalid symbol"); } } + /** Get option symbol of an Options sub-class. + * + * Using this method to read an option is not necessary, but allows for generic use. */ + T get(T) (char[] symbol) { + static if (!TIsIn!(T,TYPES)) + static assert (false, "Options.get does not currently support type "~T.stringof); + + mixin (`alias opts`~TName!(T)~` optsVars;`); + + try { + return *(optsVars[cast(ID) symbol]); + } catch (ArrayBoundsException) { + // log and ignore: + logger.error ("Options.get: invalid symbol"); + } + } + + /** List the names of all options of a specific type. */ + char[][] list(T) () { + static if (!TIsIn!(T,TYPES)) + static assert (false, "Options.list does not currently support type "~T.stringof); + + mixin (`alias opts`~TName!(T)~` optsVars;`); + + return optsVars.keys; + } + protected { OptionChanges optionChanges; // all changes to options (for saving) @@ -385,8 +412,8 @@ static if (!TIsIn!(T,TYPES)) static assert (false, "OptionChanges.set does not currently support type "~T.stringof); - mixin (`alias opts`~T.stringof~` optsVars;`); - mixin (`alias `~T.stringof~`s vars;`); + mixin (`alias opts`~TName!(T)~` optsVars;`); + mixin (`alias `~TName!(T)~`s vars;`); T** p = id in optsVars; if (p !is null) **p = x; @@ -416,7 +443,7 @@ /** A home for all miscellaneous options, at least for now. */ OptionsMisc miscOpts; class OptionsMisc : Options { - mixin (impl!("bool useThreads, exitImmediately; int logOptions; double pollInterval; char[] L10n;")); + mixin (impl!("bool useThreads, exitImmediately; int logOptions; double pollInterval; char[] L10n, a,b,c;")); static this() { miscOpts = new OptionsMisc;