# HG changeset patch # User Diggory Hardy # Date 1224780349 -3600 # Node ID 9520cc0448e54f227160c469cda65e22d03315d3 # Parent 08a4ae11454bdffa1c73537bda76f49e973bc634 Boolean options are now encapsulated within a Content class (currently an experiment). This should facilitate generic option editing widgets. diff -r 08a4ae11454b -r 9520cc0448e5 data/conf/gui.mtt --- a/data/conf/gui.mtt Tue Oct 21 11:35:15 2008 +0100 +++ b/data/conf/gui.mtt Thu Oct 23 17:45:49 2008 +0100 @@ -7,7 +7,7 @@ - + diff -r 08a4ae11454b -r 9520cc0448e5 data/conf/options.mtt --- a/data/conf/options.mtt Tue Oct 21 11:35:15 2008 +0100 +++ b/data/conf/options.mtt Thu Oct 23 17:45:49 2008 +0100 @@ -1,16 +1,16 @@ {MT01} -{misc} +{MiscOptions} -{font} +{FontOptions} -{video} +{VideoOptions} diff -r 08a4ae11454b -r 9520cc0448e5 mde/font/FontTexture.d --- a/mde/font/FontTexture.d Tue Oct 21 11:35:15 2008 +0100 +++ b/mde/font/FontTexture.d Thu Oct 23 17:45:49 2008 +0100 @@ -433,8 +433,8 @@ // this bit of renderMode, if set, means read glyph as BGR not RGB when using LCD rendering enum { RENDER_LCD_BGR = 1 << 30 } -OptionsFont fontOpts; -class OptionsFont : Options { +FontOptions fontOpts; +class FontOptions : Options { /* renderMode have one of the following values, possibly with bit 31 set (see RENDER_LCD_BGR): * FT_LOAD_TARGET_NORMAL (0x00000) * FT_LOAD_TARGET_LIGHT (0x10000) @@ -447,8 +447,8 @@ mixin (impl!("int renderMode, lcdFilter;")); static this() { - fontOpts = new OptionsFont; - Options.addOptionsClass (fontOpts, "font"); + fontOpts = new FontOptions; + Options.addOptionsClass (fontOpts, "FontOptions"); } } diff -r 08a4ae11454b -r 9520cc0448e5 mde/gui/content/Content.d --- a/mde/gui/content/Content.d Tue Oct 21 11:35:15 2008 +0100 +++ b/mde/gui/content/Content.d Thu Oct 23 17:45:49 2008 +0100 @@ -13,13 +13,21 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -/** The content system − type agnostic part. +/** The content system − common types. */ module mde.gui.content.Content; import Int = tango.text.convert.Integer; -/** Content − universal part. +debug { + import tango.util.log.Log : Log, Logger; + private Logger logger; + static this () { + logger = Log.getLogger ("mde.gui.content.Content"); + } +} + +/** IContent − interface for all Content classes. * * Services like copy/paste could work on universal content. However, they would need to run a * conversion to the appropriate type (or try next-oldest item on clipboard?). @@ -55,47 +63,70 @@ /** Generically return strings. * - * Every Content should return a string for i == 0; preferably its value. Other values of i - * can be used to return other strings. For unsupported values of i, null should be returned. - */ + * This serves two purposes: generically returning a string of/related to the content (i == 0), + * and returning associated descriptors. Functions should adhere to (or add to) this table. + * + * $(TABLE + * $(TR $(TH i) $(TH returns)) + * $(TR $(TD 0) $(TD value)) + * $(TR $(TD 1) $(TD Translated name or null)) + * $(TR $(TD 2) $(TD Translated description or null)) + * $(TR $(TD other) $(TD null)) + * ) */ char[] toString (uint i); } -/+ -/** Extension to interface providing text-specific tools. */ -interface IContentText : IContent + +/** Base class for content containing a simple value. + * + * All derived classes should support functions to set/get any ValueContent type, but return the + * default value of any type other than it's own. */ +abstract class ValueContent : IContent { - char[] text (); /// Get/set the value. - void text (char[] v); /// ditto -} -+/ -/+ FIXME - use content lists or drop? -/** Get a content from the list (what list?). */ -ContentText getContentText (char[] id) { - return new ContentText (id); // forget the list for now + protected this () {} + + void name (char[] n, char[] d = null) { + name_ = n; + desc_ = d; + } +protected: + char[] name_, desc_;// name and description, loaded by lookup.Translation } -/** ditto */ -ContentInt getContentInt (char[] id) { - return new ContentInt (42); // forget the list for now -} -+/ - -/+FIXME - currently unused -/** Text content. */ -/* May end up extending a universal content type. - * Services like copy/paste could work on universal content. - * - * NOTE: Needs to be a reference type really. - * Could alternately be: - * alias ContentTextStruct* ContentText - * where ContentTextStruct is a struct. */ -class ContentText : IContent +class BoolContent : ValueContent { this () {} - this (char[] text) { - text_ = text; + this (bool val) { + v = val; + } + + /// Get the text. + char[] toString (uint i) { + debug logger.trace ("BoolContent.toString"); + return (i == 0) ? v ? "true" : "false" + : (i == 1) ? name_ + : (i == 2) ? desc_ + : null; } + void opAssign (bool val) { + v = val; + } + bool opCall () { + return v; + } + + protected bool v; +} + +/** Text content. */ +class TextContent : ValueContent +{ + this () {} + this (char[] text, char[] name = null) { + text_ = text; + name_ = name; + } + /+ ContentText dup () { return new ContentText (text_); } @@ -107,19 +138,21 @@ // FIXME: convert return null; } - - alias toString text; + +/ /// Get the text. - char[] toString () { - return text_; + char[] toString (uint i) { + debug logger.trace ("TextContent.toString"); + return (i == 0) ? text_ + : (i == 1) ? name_ + : (i == 2) ? desc_ + : null; } protected: - //NOTE: need to allow cache-invalidating when text changes! char[] text_; } - +/+ /** Integer content. */ class ContentInt : IContent { diff -r 08a4ae11454b -r 9520cc0448e5 mde/gui/content/options.d --- a/mde/gui/content/options.d Tue Oct 21 11:35:15 2008 +0100 +++ b/mde/gui/content/options.d Thu Oct 23 17:45:49 2008 +0100 @@ -25,36 +25,53 @@ import mde.lookup.Options; import mde.lookup.Translation; +debug { + import tango.util.log.Log : Log, Logger; + private Logger logger; + static this () { + logger = Log.getLogger ("mde.gui.content.options"); + } +} + class OptionList { - this (Options opts, char[] i18nOptionsName) - in { assert (opts !is null, "OptionList: invalid Options instance"); } - body { - Translation trans = Translation.load (i18nOptionsName); + this (char[] optsName) + { + auto p = optsName in Options.subClasses; + if (p is null) { + logger.error ("OptionList created with invalid options class name."); + return; // list is empty, nothing displayed + } + Options opts = *p; + + Translation trans = Translation.load ("L10n/"~optsName); + char[][] list = opts.list; - char[][] list = opts.list!(char[])(); + textOpts.length = list.length + opts.content.length; + size_t i; + foreach (s; list) { + Translation.Entry transled = trans.getStruct (s); + textOpts[i] = new OptionContent(opts, s, transled.name, transled.desc); + ++i; + } + foreach (s, v; opts.content) { + Translation.Entry transled = trans.getStruct (s); + v.name (transled.name, transled.desc); // set Content name & desc. Only needs doing once + textOpts[i++] = v; + } - textOpts.length = list.length; - foreach (i,s; list) { - Translation.Entry transled = trans.getStruct (s); - textOpts[i] = new ContentOptionText(opts, s, transled.name, transled.desc); - } } - ContentOption[] list () { + IContent[] list () { return textOpts; } - static OptionList trial () { - return new OptionList (miscOpts, "L10n/OptionsMisc"); - } - protected: - ContentOption[] textOpts; + IContent[] textOpts; } //FIXME - todo.txt -class ContentOptionText : ContentOption +class OptionContent : IContent { this (Options o, char[] s, char[] name, char[] desc) { opts = o; @@ -65,7 +82,7 @@ char[] toString (uint i) { if (i == 0) - return opts.get!(char[])(symb); + return "dummy"; //opts.get!(char[])(symb); else if (i == 1) return name_; else if (i == 2) @@ -77,22 +94,6 @@ void value (char[] v) { opts.set!(char[])(symb, v); }+/ -} - -abstract class ContentOption : IContent -{ - // Get the symbol name (useful?) - /+ - /// Get the translated name - char[] name () { - return name_; - } - - /// Get the description (translated) - char[] description () { - return desc_; - } - +/ protected: Options opts; // the set of options within which our option lies char[] symb; // the symbol name of our option diff -r 08a4ae11454b -r 9520cc0448e5 mde/gui/widget/TextWidget.d --- a/mde/gui/widget/TextWidget.d Tue Oct 21 11:35:15 2008 +0100 +++ b/mde/gui/widget/TextWidget.d Thu Oct 23 17:45:49 2008 +0100 @@ -24,6 +24,14 @@ import mde.gui.renderer.IRenderer; import mde.gui.content.Content; +debug { + import tango.util.log.Log : Log, Logger; + private Logger logger; + static this () { + logger = Log.getLogger ("mde.gui.widget.TextWidget"); + } +} + /// Basic text widget class TextLabelWidget : Widget { @@ -53,6 +61,7 @@ class ContentLabelWidget : Widget { this (IWidgetManager mgr, widgetID id, WidgetData data, IContent c) { + debug assert (c, "content is null (code error)"); WDCheck (data, 3, 0); content = c; index = data.ints[1]; diff -r 08a4ae11454b -r 9520cc0448e5 mde/gui/widget/layout.d --- a/mde/gui/widget/layout.d Tue Oct 21 11:35:15 2008 +0100 +++ b/mde/gui/widget/layout.d Thu Oct 23 17:45:49 2008 +0100 @@ -100,16 +100,19 @@ this (IWidgetManager mgr, widgetID id, WidgetData data) { debug scope (failure) logger.warn ("TrialContentLayoutWidget: failure"); - WDCheck (data, 2, 1); + WDCheck (data, 2, 2); - OptionList optsList = OptionList.trial(); - rows = optsList.list.length; + OptionList optsList = new OptionList(data.strings[1]); cols = 1; - - // Get all sub-widgets - subWidgets.length = rows*cols; - foreach (i, c; optsList.list) { - subWidgets[i] = mgr.makeWidget (data.strings[0], c); + if ((rows = optsList.list.length) > 0) { + // Get all sub-widgets + subWidgets.length = rows*cols; + foreach (i, c; optsList.list) { + subWidgets[i] = mgr.makeWidget (data.strings[0], c); + } + } else { + rows = 1; + subWidgets = [mgr.makeWidget (data.strings[0], new TextContent (data.strings[1], "Invalid Options section"))]; } super (mgr, id, data); } @@ -176,7 +179,6 @@ * * As such, this must be the first function called after this(). */ void finalize () { - logger.trace ("initWidths.length: {}", initWidths.length); if (initWidths.length == cols + rows) { col.setWidths (initWidths[0..cols]); row.setWidths (initWidths[cols..$]); diff -r 08a4ae11454b -r 9520cc0448e5 mde/lookup/Options.d --- a/mde/lookup/Options.d Tue Oct 21 11:35:15 2008 +0100 +++ b/mde/lookup/Options.d Thu Oct 23 17:45:49 2008 +0100 @@ -30,6 +30,8 @@ import mde.setup.paths; import mde.exception; +public import mde.gui.content.Content; + import mde.file.mergetag.Reader; import mde.file.mergetag.Writer; import mde.file.mergetag.DataSet; @@ -52,7 +54,7 @@ * should be used for reading variables, and via the addOptionsClass() hook will be loaded from * files during pre-init (init0 stage). Do not write changes directly to the subclasses or they will * not be saved; instead use set(), for example, miscOpts.set!(char[])("L10n","en-GB"). Use an -* example like OptionsMisc as a template for creating a new Options sub-class. +* example like MiscOptions as a template for creating a new Options sub-class. * * Optionally, overload the validate() function. This is called after loading, allowing conditions * to be enforced on variables. Use set!()() to change the variables. If an exception is thrown, @@ -79,7 +81,7 @@ // All supported types, for generic handling via templates. It should be possible to change // the supported types simply by changing this list now (untested). template store(A...) { alias A store; } - alias store!(bool, int, double, char[]) TYPES; + alias store!(int, double, char[]) TYPES;//FIXME removed bool //BEGIN Templates: internal private { // Get name of a type. Basically just stringof, but special handling for arrays. @@ -92,11 +94,14 @@ } // Pointer lists - template PLists(T, A...) { + template PLists(A...) { static if (A.length) { - const char[] PLists = T.stringof~"*[ID] opts"~TName!(T)~";\n" ~ PLists!(A); + static if (is (T == bool)) { + const char[] PLists = PLists!(A[1..$]); + } else + const char[] PLists = A[0].stringof~"*[ID] opts"~TName!(A[0])~";\n" ~ PLists!(A[1..$]); } else - const char[] PLists = T.stringof~"*[ID] opts"~TName!(T)~";\n"; + const char[] PLists = ""; } // True if type is one of A @@ -112,10 +117,19 @@ // For addTag template addTagMixin(T, A...) { - const char[] ifBlock = `if (tp == "`~T.stringof~`") { - `~T.stringof~`** p = id in opts`~TName!(T)~`; - if (p !is null) **p = parseTo!(`~T.stringof~`) (dt); - }`; + static if (is(T == bool)) { + const char[] ifBlock = `if (tp == "`~T.stringof~`") { + auto p = id in opts; + if (p) { + auto q = cast(BoolContent) (*p); + if (q) q = parseTo!(`~T.stringof~`) (dt); + } +}`; + } else + const char[] ifBlock = `if (tp == "`~T.stringof~`") { + `~T.stringof~`** p = id in opts`~TName!(T)~`; + if (p !is null) **p = parseTo!(`~T.stringof~`) (dt); +}`; static if (A.length) const char[] addTagMixin = ifBlock~` else `~addTagMixin!(A).addTagMixin; else @@ -130,6 +144,14 @@ } else const char[] writeAllMixin = ``; } + + // For list + template listMixin(A...) { + static if (A.length) { + const char[] listMixin = `ret ~= opts`~TName!(A[0])~`.keys;` ~ listMixin!(A[1..$]); + } else + const char[] listMixin = ``; + } } //END Templates: internal @@ -144,6 +166,7 @@ assert (c !is null); // Instance must be created before calling addOptionsClass assert (((cast(ID) i) in subClasses) is null); // Don't allow a silent replacement } body { + c.secName = i; subClasses[cast(ID) i] = c; } @@ -233,7 +256,7 @@ * via hash-maps, which is a little slower than direct access but necessary since the option * must be changed in two separate places. */ void set(T) (char[] symbol, T val) { - static assert (TIsIn!(T,TYPES), "Options does not support type "~T.stringof); + static assert (TIsIn!(T,TYPES) && !is(T == bool), "Options does not support type "~T.stringof); changed = true; // something got set (don't bother checking this isn't what it already was) @@ -245,7 +268,7 @@ 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. */ @@ -260,25 +283,30 @@ // log and ignore: logger.error ("Options.get: invalid symbol"); } - } + }+/ /** List the names of all options of a specific type. */ - char[][] list(T) () { - static assert (TIsIn!(T,TYPES), "Options does not support type "~T.stringof); - - mixin (`alias opts`~TName!(T)~` optsVars;`); - - return optsVars.keys; + char[][] list () { + char[][] ret; + mixin (listMixin!(TYPES)); + return ret; + } + + /// Get all Options stored with a ValueContent. + ValueContent[char[]] content() { + return opts; } /// Variable validate function. This implementation does nothing. void validate() {} protected { + char[] secName; // name of this option setting; set null after translation is loaded OptionChanges optionChanges; // all changes to options (for saving) // The "pointer lists", e.g. char[]*[ID] optscharA; - mixin (PLists!(TYPES)); + mixin (PLists!(TYPES)); //FIXME adds unused optsbool + ValueContent[char[]] opts; // generic list of option values } //BEGIN Mergetag loading/saving code @@ -295,6 +323,19 @@ //BEGIN Templates: impl & optionsThis private { + // Replace, e.g., bool, with BoolContent + template contentName(A) { + static if (is(A == bool)) { + const char[] contentName = "BoolContent"; + } else static if (is(A == int)) { + const char[] contentName = "int";// no IntContent yet + } else static if (is(A == double)) { + const char[] contentName = "double"; + } else static if (is(A == char[])) { + const char[] contentName = "char[]"; + } else + static assert (false, "unsuppurted type: "~ A); + } // Return index of first comma, or halts if not found. template cIndex(char[] A) { static if (A.length == 0) @@ -313,9 +354,10 @@ else const size_t scIndex = 1 + scIndex!(A[1..$]); } - // Look for "type symbols;" in A and return symbols as a comma separated list of names - // (even if type is encountered more than once). Output may contain spaces and, if - // non-empty, will contain a trailing comma. Assumes scIndex always returns less than A.$. + /* Look for "type symbols;" in A and return symbols as a comma separated list of names + (even if type is encountered more than once). Output may contain spaces and will have a + trailing comma unless no match was found in which case an empty string is returned. + Assumes scIndex always returns less than A.$ . */ template parseT(char[] type, char[] A) { static if (A.length < type.length + 1) // end of input, no match const char[] parseT = ""; @@ -327,7 +369,7 @@ else // no match const char[] parseT = parseT!(type, A[scIndex!(A)+1 .. $]); } - // May have a trailing comma. Assumes cIndex always returns less than A.$. + // May have a trailing comma. Assumes cIndex always returns less than A.$ . template aaVars(char[] A) { static if (A.length == 0) const char[] aaVars = ""; @@ -337,6 +379,16 @@ const char[] aaVars = "\""~A[0..cIndex!(A)]~"\"[]:&"~A[0..cIndex!(A)] ~ "," ~ aaVars!(A[cIndex!(A)+1..$]); } + // May have a trailing comma. Assumes cIndex always returns less than A.$ . + template aaVarsBool(char[] A) {//FIXME + static if (A.length == 0) + const char[] aaVarsBool = ""; + else static if (A[0] == ' ') + const char[] aaVarsBool = aaVarsBool!(A[1..$]); + else + const char[] aaVarsBool = "\""~A[0..cIndex!(A)]~"\"[]:"~A[0..cIndex!(A)] ~ "," ~ + aaVarsBool!(A[cIndex!(A)+1..$]); + } // strip Trailing Comma template sTC(char[] A) { static if (A.length && A[$-1] == ',') @@ -353,19 +405,54 @@ else const char[] listOrNull = "["~A~"]"; } + // if B is empty return an empty string otherswise return what's below: + template catOrNothing(char[] A,char[] B) { + static if (B.length) + const char[] catOrNothing = A~` `~sTC!(B)~";\n"; + else + const char[] catOrNothing = ``; + } + // foreach decl... + template createBCs(char[] A) { + static if (A.length == 0) + const char[] createBCs = ""; + else static if (A[0] == ' ') + const char[] createBCs = createBCs!(A[1..$]); + else + const char[] createBCs = A[0..cIndex!(A)]~ " = new BoolContent (false);\n"~ + createBCs!(A[cIndex!(A)+1..$]); + } // for recursing on TYPES template optionsThisInternal(char[] A, B...) { static if (B.length) { + static if (is(B[0] == bool)) {//FIXME + const char[] optionsThisInternal = createBCs!(parseT!(B[0].stringof,A))~ + `opts = `~listOrNull!(sTC!(aaVarsBool!(parseT!(B[0].stringof,A))))~";\n" ~ + optionsThisInternal!(A,B[1..$]); + } else const char[] optionsThisInternal = `opts`~TName!(B[0])~` = `~listOrNull!(sTC!(aaVars!(parseT!(B[0].stringof,A))))~";\n" ~ optionsThisInternal!(A,B[1..$]); } else const char[] optionsThisInternal = ``; } + template declValsInternal(char[] A, B...) { + static if (B.length) { + const char[] declValsInternal = catOrNothing!(contentName!(B[0]),parseT!(B[0].stringof,A)) ~ declValsInternal!(A,B[1..$]); + } else + const char[] declValsInternal = ``; + } } protected { + /** Declares the values. + * + * Basic types are replaced with a ValueContent class to keep the option synchronized and + * generalize use. */ + template declVals(char[] A) { + const char[] declVals = declValsInternal!(A, TYPES,bool); + } /** Produces the implementation code to go in the constuctor. */ template optionsThis(char[] A) { const char[] optionsThis = "optionChanges = new OptionChanges;\n" ~ - optionsThisInternal!(A,TYPES); + optionsThisInternal!(A,TYPES,bool); } /+ Needs too many custom parameters to be worth it? Plus makes class less readable. /** Produces the implementation code to go in the static constuctor. */ @@ -381,7 +468,7 @@ * * In case this() needs to be customized, mixin(impl!(A)) is equivalent to: * --- - * mixin (A~` + * mixin (declVals!(A)~` this () { `~optionsThis!(A)~` }`); @@ -395,7 +482,7 @@ * Extending: mixins could also be used for the static this() {...} or even the whole * class, but doing so would rather decrease readability of any implementation. */ template impl(char[] A /+, char[] symb+/) { - const char[] impl = A~"\nthis(){\n"~optionsThis!(A)~"}"; + const char[] impl = declVals!(A)~"\nthis(){\n"~optionsThis!(A)~"}"; // ~"\nstatic this(){\n"~optClassAdd!(symb)~"}" } } @@ -466,9 +553,11 @@ */ /** A home for all miscellaneous options, at least for now. */ -OptionsMisc miscOpts; -class OptionsMisc : Options { - mixin (impl!("bool exitImmediately; int maxThreads, logOptions; double pollInterval; char[] L10n, a,b,c,g,z;")); +MiscOptions miscOpts; +class MiscOptions : Options { + const A = "bool exitImmediately; int maxThreads, logOptions; double pollInterval; char[] L10n;"; + //pragma (msg, impl!(A)); + mixin (impl!(A)); void validate() { // Try to enforce sensible values, whilst being reasonably flexible: @@ -481,7 +570,7 @@ } static this() { - miscOpts = new OptionsMisc; - Options.addOptionsClass (miscOpts, "misc"); + miscOpts = new MiscOptions; + Options.addOptionsClass (miscOpts, "MiscOptions"); } } diff -r 08a4ae11454b -r 9520cc0448e5 mde/setup/Init.d --- a/mde/setup/Init.d Tue Oct 21 11:35:15 2008 +0100 +++ b/mde/setup/Init.d Thu Oct 23 17:45:49 2008 +0100 @@ -182,7 +182,7 @@ } // a debugging option: - imde.run = !args.contains("q") && !miscOpts.exitImmediately; + imde.run = !args.contains("q") && !miscOpts.exitImmediately(); debug logger.trace ("Init: applied pre-init options"); //BEGIN Load dynamic libraries diff -r 08a4ae11454b -r 9520cc0448e5 mde/setup/Screen.d --- a/mde/setup/Screen.d Tue Oct 21 11:35:15 2008 +0100 +++ b/mde/setup/Screen.d Thu Oct 23 17:45:49 2008 +0100 @@ -48,7 +48,7 @@ } /** All video options. */ - class OptionsVideo : Options { + class VideoOptions : Options { mixin (impl!("bool fullscreen,hardware,resizable,noFrame; int screenW,screenH,windowW,windowH;")); } @@ -75,19 +75,19 @@ //BEGIN Create window and initialize OpenGL // Window creation flags and size flags = SDL_OPENGL; - if (vidOpts.hardware) flags |= SDL_HWSURFACE | SDL_DOUBLEBUF; + if (videoOpts.hardware()) flags |= SDL_HWSURFACE | SDL_DOUBLEBUF; else flags |= SDL_SWSURFACE; int w, h; - if (vidOpts.fullscreen) { + if (videoOpts.fullscreen()) { flags |= SDL_FULLSCREEN; - w = vidOpts.screenW; - h = vidOpts.screenH; + w = videoOpts.screenW; + h = videoOpts.screenH; } else { - if (vidOpts.resizable) flags |= SDL_RESIZABLE; - if (vidOpts.noFrame) flags |= SDL_NOFRAME; - w = vidOpts.windowW; - h = vidOpts.windowH; + if (videoOpts.resizable()) flags |= SDL_RESIZABLE; + if (videoOpts.noFrame()) flags |= SDL_NOFRAME; + w = videoOpts.windowW; + h = videoOpts.windowH; } // OpenGL attributes @@ -155,12 +155,12 @@ /** Called when a resize event occurs (when the window manager resizes the window). */ void resizeEvent (int w, int h) { // Save new size to config - if (vidOpts.fullscreen) { // probably resizeEvent only called when not fullscreen - vidOpts.set!(int) ("screenW", w); - vidOpts.set!(int) ("screenH", h); + if (videoOpts.fullscreen()) { // probably resizeEvent only called when not fullscreen + videoOpts.set!(int) ("screenW", w); + videoOpts.set!(int) ("screenH", h); } else { - vidOpts.set!(int) ("windowW", w); - vidOpts.set!(int) ("windowH", h); + videoOpts.set!(int) ("windowW", w); + videoOpts.set!(int) ("windowH", h); } if (setWindow (w,h)) @@ -262,8 +262,8 @@ static this() { logger = Log.getLogger ("mde.setup.Screen"); - vidOpts = new OptionsVideo; - Options.addOptionsClass (vidOpts, "video"); + videoOpts = new VideoOptions; + Options.addOptionsClass (videoOpts, "VideoOptions"); } // DATA: @@ -271,5 +271,5 @@ uint flags = 0; IDrawable[] drawables; Logger logger; - OptionsVideo vidOpts; + VideoOptions videoOpts; }