Mercurial > projects > mde
view mde/content/Items.d @ 128:41582439a42b
Added support for dynamic EnumContent loading and saving, with translation loading.
WMScreen.init removed; code moved to this() since class is now created by main() instead of a static this().
Fix for SwitchWidget not passing events. Still some resizing bugs evident in SwitchWidget :-(
author | Diggory Hardy <diggory.hardy@gmail.com> |
---|---|
date | Wed, 14 Jan 2009 20:24:14 +0000 |
parents | c9843fbaac88 |
children | 264028f4115a |
line wrap: on
line source
/* LICENSE BLOCK Part of mde: a Modular D game-oriented Engine Copyright © 2007-2008 Diggory Hardy This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ /************************************************************************************************** * A generic way to access content items. Also loads translations on-demand. *************************************************************************************************/ module mde.content.Items; import mde.content.miscContent; import mde.gui.exception; import imde = mde.imde; 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.Items"); } } /** 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. */ Content get (char[] item) { assert (currentL10n is miscOpts.L10n(), "must call loadTranslation (code error)"); char[] orig = item; // item is modified by head() char[] h = head (item); if (h == "Options") { if (item is null) return Options.allContentList; h = head (item); auto p = h in Options.optionsClasses; if (p) { if (item == null) return p.contentList; auto q = (h = head (item)) in p.content; if (q && item is null) // enforce item is an exact match return *q; } } else if (h == "imde") { h = head (item); if (h == "menu" && item is null) return imde.menu; else if (h == "quit" && item is null) return imde.quit; } else if (h == "dynamic") { auto i = head (item) in items; if (i) return *i; } return new ErrorContent ("Error: bad content specifier", orig); } /** 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) { Content[] 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; } Options.allContentList = new ContentList ("Options", list); } Translation trl; Translation.Entry trle; // Translate Options: with (Options.allContentList) { trle = Translation.get (symbol).getStruct (symbol); name (trle.name, trle.desc); } foreach (n,opts; Options.optionsClasses) { 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); IContentList cl = cast(IContentList) v; if (cl) { foreach (i,c; cl.list) { trle = trl.getStruct (c.symbol); c.name (trle.name, trle.desc); } } } } // Translate imde: trl = Translation.get ("imde"); trle = trl.getStruct ("menu"); imde.menu.name (trle.name, trle.desc); trle = trl.getStruct ("quit"); imde.quit.name (trle.name, trle.desc); // Translate dynamic content: if (items.length) { trl = Translation.get ("dynamic"); foreach (n,item; items) { trle = trl.getStruct (n); item.name (trle.name, trle.desc); IContentList cl = cast(IContentList) item; if (cl) { foreach (i,c; cl.list) { trle = trl.getStruct (c.symbol); c.name (trle.name, trle.desc); } } } } currentL10n = miscOpts.L10n(); } /** Add content c with name c.symbol, so that translations are loaded for it and it can be * returned by get ("dynamic."~c.symbol). */ Content addContent (Content c) { items[c.symbol] = c; return c; } private: // NOTE: possibly add all content to this list. Lookups would be faster. Content[char[]] items; // dynamically added content /** Takes the string "head.tail" where tail may contain '.' but head does not, returns "head", * with str set to "tail". */ char[] head (ref char[] str) { size_t i = 0; while (i < str.length && str[i] != '.') ++i; char[] ret = str[0..i]; if (i == str.length) str = null; else str = str[i+1..$]; return ret; } char[] currentL10n; // Strings will be reloaded if this is not miscOpts.L10n().