# HG changeset patch # User Diggory Hardy # Date 1228476579 0 # Node ID 6acd96f8685f28fb353590cf0ed36b2817b4128d # Parent 2a1428ec5344b82930b4f05f49255a028cf79dec Translation reloading as far as AContent name/desc supported. Limited & crude support for updating gui. Gave AContent support for multiple callbacks. New locale: "en". diff -r 2a1428ec5344 -r 6acd96f8685f data/L10n/en.mtt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/data/L10n/en.mtt Fri Dec 05 11:29:39 2008 +0000 @@ -0,0 +1,5 @@ +{MT01} +!{en International English} + +{MiscOptions} + diff -r 2a1428ec5344 -r 6acd96f8685f data/conf/options.mtt --- a/data/conf/options.mtt Thu Dec 04 10:32:20 2008 +0000 +++ b/data/conf/options.mtt Fri Dec 05 11:29:39 2008 +0000 @@ -2,7 +2,7 @@ {MiscOptions} - + diff -r 2a1428ec5344 -r 6acd96f8685f mde/content/Content.d --- a/mde/content/Content.d Thu Dec 04 10:32:20 2008 +0000 +++ b/mde/content/Content.d Fri Dec 05 11:29:39 2008 +0000 @@ -17,6 +17,8 @@ */ module mde.content.Content; +import util = mde.util; + debug { import tango.util.log.Log : Log, Logger; private Logger logger; @@ -68,9 +70,14 @@ desc_ = d; } - /// Current implementation has 1 callback; can be changed to allow many. + /** Add a callback. Callbacks are called in the order added. */ EventContent addCallback (void delegate (AContent) cb) { - this.cb = cb; + this.cb ~= cb; + return this; + } + /// ditto + EventContent addCallback (void function (AContent) cb) { + this.cb ~= util.toDg (cb); return this; } @@ -83,17 +90,16 @@ /// End of an event, e.g. a button release or end of an edit (calls callbacks). void endEvent () { - if (cb) - cb (this); + foreach (dg; cb) + dg (this); } final char[] symbol; // Symbol name for this content protected: char[] name_, desc_; // name and description - void delegate (AContent) cb; + void delegate (AContent) cb[]; } -// FIXME: needs changes to allow updating translated strings. Move to Content and extend AContent? /** A generic way to handle a list of type IContent. */ class ContentList : AContent { diff -r 2a1428ec5344 -r 6acd96f8685f mde/content/Items.d --- a/mde/content/Items.d Thu Dec 04 10:32:20 2008 +0000 +++ b/mde/content/Items.d Fri Dec 05 11:29:39 2008 +0000 @@ -35,34 +35,21 @@ /** Get a specific content item. * + * loadTranslation() $(B must) be called before this function. + * * E.g. get ("Options.MiscOptions.L10n") returns miscOpts.L10n, * Items.get ("Options.MiscOptions") returns a ContentList of all misc options. */ AContent get (char[] item) { + assert (currentL10n is miscOpts.L10n(), "must call loadTranslation (code error)"); + char[] h = head (item); if (h == "Options") { - if (item is null) { - if (Options.allContentList is null) { - AContent[] list; - list.length = Options.optionsClasses.length; - size_t i; - foreach (n,opts; Options.optionsClasses) { - if (opts.contentList is null) - loadTransl (opts, n); - list[i++] = opts.contentList; - } - Options.allContentList = new ContentList (h, list); - Translation trl = Translation.get (h); - Translation.Entry trle = trl.getStruct (h); - Options.allContentList.name (trle.name, trle.desc); - } + if (item is null) return Options.allContentList; - } + h = head (item); auto p = h in Options.optionsClasses; if (p) { - if (p.contentList is null) - loadTransl (*p, h); - if (item == null) return p.contentList; @@ -71,19 +58,53 @@ return *q; } } else if (h == "imde") { - if (!imdeTransl) { - Translation trl = Translation.get (h); - Translation.Entry trle = trl.getStruct ("quit"); - quit.name (trle.name, trle.desc); - imdeTransl = true; + h = head (item); + if (h == "quit" && item is null) + return quit; + } + throw new ContentItemException (h); + } + + /** Creates some content on first run (required by get()). + * + * If the correct translation strings are not loaded, this loads them. */ + void loadTranslation () { + if (currentL10n is miscOpts.L10n()) return; + + // Create Option classes' ContentLists if necessary: + if (Options.allContentList is null) { + AContent[] list; + list.length = Options.optionsClasses.length; + size_t i; + foreach (n,opts; Options.optionsClasses) { + opts.contentList = new ContentList (n, opts.content); + list[i++] = opts.contentList; } - h = head (item); - if (h == "quit" && item is null) { - quit.name ("Quit"); //FIXME - return quit; + Options.allContentList = new ContentList ("Options", list); + } + + // Translate Options: + Translation.Entry trle; + with (Options.allContentList) { + trle = Translation.get (symbol).getStruct (symbol); + name (trle.name, trle.desc); + } + foreach (n,opts; Options.optionsClasses) { + Translation trl; + trl = Translation.get (n); + trle = trl.getStruct (n); + opts.contentList.name (trle.name, trle.desc); + foreach (s, v; opts.content) { + trle = trl.getStruct (s); + v.name (trle.name, trle.desc); } } - throw new ContentItemException (h); + + // Translate imde: + trle = Translation.get ("imde").getStruct ("quit"); + quit.name (trle.name, trle.desc); + + currentL10n = miscOpts.L10n(); } private: @@ -101,16 +122,4 @@ return ret; } - void loadTransl (Options p, char[] n) { - debug logger.trace ("Loading translation strings for Options."~n); - Translation trans = Translation.get (n); - Translation.Entry transled = trans.getStruct (n); - p.contentList = new ContentList (n, p.content); - p.contentList.name (transled.name, transled.desc); - foreach (s, v; p.content) { - transled = trans.getStruct (s); - v.name (transled.name, transled.desc); - } - } - - bool imdeTransl = false; // Has section imde been translated? + char[] currentL10n; // Strings will be reloaded if this is not miscOpts.L10n(). diff -r 2a1428ec5344 -r 6acd96f8685f mde/gui/WidgetManager.d --- a/mde/gui/WidgetManager.d Thu Dec 04 10:32:20 2008 +0000 +++ b/mde/gui/WidgetManager.d Fri Dec 05 11:29:39 2008 +0000 @@ -25,11 +25,12 @@ import mde.gui.widget.Ifaces; import mde.gui.renderer.createRenderer; -// For adding the input event callbacks and requesting redraws: import imde = mde.imde; import mde.input.Input; import mde.scheduler.Scheduler; import mde.setup.Screen; +import Items = mde.content.Items; // loadTranslation +import mde.lookup.Options; // miscOpts.L10n callback import tango.core.sync.Mutex; import tango.util.log.Log : Log, Logger; @@ -69,6 +70,9 @@ // Events we want to know about: imde.input.addMouseClickCallback(&clickEvent); imde.input.addMouseMotionCallback(&motionEvent); + + Items.loadTranslation (); + miscOpts.L10n.addCallback (&reloadStrings); } @@ -437,6 +441,14 @@ } } + /** Called when translation strings have been reloaded. */ + void reloadStrings (AContent c) { + Items.loadTranslation; + child.reloadStrings; //FIXME : all widgets, resize + requestRedraw; + } + +protected: /** Second stage of loading the widgets. * * loadDesign handles the data; this method needs to: @@ -484,8 +496,9 @@ /** Called before saving (usually when the GUI is about to be destroyed, although not * necessarily). */ - void preSave () {} + void preSave (); +public: //BEGIN IWidgetManager methods IChildWidget makeWidget (widgetID id, IContent content = null) { debug (mdeWidgets) logger.trace ("Creating widget \""~id~'"'); diff -r 2a1428ec5344 -r 6acd96f8685f mde/gui/widget/Ifaces.d --- a/mde/gui/widget/Ifaces.d Thu Dec 04 10:32:20 2008 +0000 +++ b/mde/gui/widget/Ifaces.d Fri Dec 05 11:29:39 2008 +0000 @@ -185,6 +185,14 @@ * Should be propegated up to parents. */ void childChanged (); +/ + + /** Called if translated strings have been reloaded and widgets need to reload theirs. + * + * Returns: true when widget's dimensions (may) have changed. + * + * Should be propegated down to all child widgets. */ + bool reloadStrings (); + //END Load and save //BEGIN Size and position diff -r 2a1428ec5344 -r 6acd96f8685f mde/gui/widget/TextWidget.d --- a/mde/gui/widget/TextWidget.d Thu Dec 04 10:32:20 2008 +0000 +++ b/mde/gui/widget/TextWidget.d Fri Dec 05 11:29:39 2008 +0000 @@ -44,6 +44,14 @@ super (mgr, id, data); } + bool reloadStrings () { + adapter.getDimensions (mw, mh); + bool r = (mw != w || mh != h) ? true : false; + w = mw; + h = mh; + return true; + } + void draw () { super.draw(); adapter.draw (x,y); @@ -82,6 +90,11 @@ super (mgr, id,data); } + bool reloadStrings () { + adapter.text = content.toString(index); + return super.reloadStrings; + } + protected: IContent content; int index; diff -r 2a1428ec5344 -r 6acd96f8685f mde/gui/widget/Widget.d --- a/mde/gui/widget/Widget.d Thu Dec 04 10:32:20 2008 +0000 +++ b/mde/gui/widget/Widget.d Fri Dec 05 11:29:39 2008 +0000 @@ -71,6 +71,11 @@ bool rendererChanged () { return false; } + + // Widgets displaying strings will need this. + bool reloadStrings () { + return false; + } //END Load and save //BEGIN Size and position @@ -177,6 +182,13 @@ super (mgr, id, data); } + // Tells all subWidgets to reload strings, but cannot adjust size of self, so not ultimately useful. + bool reloadStrings () { + foreach (widg; subWidgets) + widg.reloadStrings; + return false; + } + IChildWidget[] children () { return subWidgets; } diff -r 2a1428ec5344 -r 6acd96f8685f mde/lookup/Translation.d --- a/mde/lookup/Translation.d Thu Dec 04 10:32:20 2008 +0000 +++ b/mde/lookup/Translation.d Fri Dec 05 11:29:39 2008 +0000 @@ -78,8 +78,14 @@ * On errors, a message is logged and the function continues, likely resulting in some * symbol names being untranslated. */ Translation get (char[] section) { - if (sections is null) { - char[][] files = [miscOpts.L10n()]; // initial locale plus dependencies + if (sections is null || loadedL10n !is miscOpts.L10n()) { + if (sections) { // Clear entries hash-map, but re-use classes + foreach (s; sections) + s.entries = null; + } + loadedL10n = miscOpts.L10n(); + debug logger.trace ("Loading L10n: "~loadedL10n); + char[][] files = [loadedL10n]; // initial locale plus dependencies size_t read = 0; // index in files of next file to read while (read < files.length) { try { @@ -113,7 +119,8 @@ } return *p; } - Translation[char[]] sections; + private Translation[char[]] sections; + private char[] loadedL10n; // reload if different } final char[] section; // ONLY used to log an error message @@ -160,16 +167,8 @@ } /* Mergetag functionality. - * - * Merge tags in to entries, prefering existing values. - * Replace depends. - * - * User-defined type "entry": - * first two element is string and must exist - * second element is description and is optional - * third element is version and is optional - * no limit on number of elements to allow future extensions - */ + * + * Merge tags in to entries, prefering existing values. */ void addTag (char[] tp, ID id, char[] dt) { if (tp == "entry") { // If the tag already exists, don't replace it @@ -181,8 +180,6 @@ return; } entries[cast(char[]) id] = entry; - } else if (tp == "char[][]") { - if (id == cast(ID)"depends") depends = cast(ID[]) parseTo!(char[][]) (dt); } } @@ -209,8 +206,6 @@ static Logger logger; Entry[char[]] entries; // all entries - - ID[] depends; // dependancy sections (only used while loading) //END Data debug (mdeUnitTest) unittest {