# HG changeset patch # User Diggory Hardy # Date 1207666341 -3600 # Node ID b5fadd8d930b3bc6987e0f122663a9ec34ad4bdc # Parent 0aa621b3e0701e93ab5681c6e239b865b016fbbe Small addition to GUI, paths work-around for Windows. New GUI widget containing a widget. Paths on windows now uses "." and "./user" as a temporary measure. committer: Diggory Hardy diff -r 0aa621b3e070 -r b5fadd8d930b data/conf/gui.mtt --- a/data/conf/gui.mtt Fri Apr 04 17:07:38 2008 +0100 +++ b/data/conf/gui.mtt Tue Apr 08 15:52:21 2008 +0100 @@ -2,4 +2,8 @@ {W1} - + +{W2} + + + diff -r 0aa621b3e070 -r b5fadd8d930b mde/gui/IWindow.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mde/gui/IWindow.d Tue Apr 08 15:52:21 2008 +0100 @@ -0,0 +1,34 @@ +/* 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 . */ + +/// Window interface (used by Widgets). +module mde.gui.IWindow; + +import mde.gui.Widget; + +interface IWindow +{ + /** Widget ID type. Each ID is unique under this window. + * + * Type is int since this is the widget data type. */ + alias int widgetID; + + /** Get a widget by ID. + * + * Returns the widget with the given ID from the Window's widget list. If the widget hasn't yet + * been created, creates it using the Window's widget creation data (throws on error; don't + * catch the exception). */ + Widget getWidget (widgetID i); +} diff -r 0aa621b3e070 -r b5fadd8d930b mde/gui/Widget.d --- a/mde/gui/Widget.d Fri Apr 04 17:07:38 2008 +0100 +++ b/mde/gui/Widget.d Tue Apr 08 15:52:21 2008 +0100 @@ -16,6 +16,7 @@ /// GUI Widget module. module mde.gui.Widget; +import mde.gui.IWindow; import mde.gui.exception; import gl = mde.gl; @@ -27,6 +28,13 @@ */ interface Widget { + /* this() should look like this: + this (IWindow window, int[] data) + * where: + * window is the parent window (only needed for getting sub-widgets, hence no need to store) + * data is the widget creation data, stripped of the widget type (see createWidget). + */ + /** Draw, starting from given x and y. * * Maybe replace later with drawClipped, especially for cases where only part of the widget is @@ -44,7 +52,7 @@ { int w, h; // size - this (int[] data) { + this (IWindow, int[] data) { if (data.length != 2) throw new WidgetDataException; w = data[0]; @@ -62,15 +70,46 @@ } } -enum WIDGET_TYPES : int { - BOX = 1 +/// Encapsulates another widget +class SingleWidget : Widget +{ + int w, h; // size + Widget subWidget; + + this (IWindow window, int[] data) { + if (data.length != 1) throw new WidgetDataException; + + subWidget = window.getWidget (data[0]); + + subWidget.getSize (w,h); + w += 10; + h += 10; + } + + void draw (int x, int y) { + gl.setColor (1.0f, 0.6f, 0.0f); + gl.drawBox (x,x+w, y,y+h); + + subWidget.draw (x+5, y+5); + } + + void getSize (out int w, out int h) { + w = this.w; + h = this.h; + } } -Widget createWidget (int[] data) { +// Widget types. Start high so they can be reordered easily later. +enum WIDGET_TYPES : int { + BOX = 1001, SINGLE +} + +Widget createWidget (IWindow window, int[] data) { if (data.length < 1) throw new WidgetDataException ("No widget data"); int type = data[0]; // type is first element of data data = data[1..$]; // the rest is passed to the Widget - if (type == WIDGET_TYPES.BOX) return new BoxWidget (data); + if (type == WIDGET_TYPES.BOX) return new BoxWidget (window, data); + else if (type == WIDGET_TYPES.SINGLE) return new SingleWidget (window, data); else throw new WidgetDataException ("Bad widget type"); } diff -r 0aa621b3e070 -r b5fadd8d930b mde/gui/gui.d --- a/mde/gui/gui.d Fri Apr 04 17:07:38 2008 +0100 +++ b/mde/gui/gui.d Tue Apr 08 15:52:21 2008 +0100 @@ -16,6 +16,7 @@ /// Base GUI module. module mde.gui.gui; +import mde.gui.IWindow; import mde.gui.Widget; import mde.gui.exception; @@ -68,11 +69,11 @@ windows ~= w; try { w.finalise(); + + gl.addDrawCallback (&w.draw); } catch (WindowLoadException e) { logger.error ("Window failed to load: " ~ e.msg); } - - gl.addDrawCallback (&w.draw); } } } @@ -91,7 +92,7 @@ * 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). */ -class Window : mt.IDataSection +class Window : mt.IDataSection, IWindow { alias int widgetID; // Widget ID type. Each ID is unique under this window. Type is int since this is the widget data type. private int[][widgetID] widgetData; // Data for all widgets under this window. @@ -101,7 +102,7 @@ int x,y; // Window position int w,h; // Window size (calculated from Widgets) - const BORDER_WIDTH = 5; // Temporary way to handle window decorations + const BORDER_WIDTH = 8; // Temporary way to handle window decorations // Call after loading is finished to setup the window and confirm that it's valid. @@ -122,7 +123,7 @@ if (d is null) throw new WindowLoadException ("Widget not found"); // Throws WidgetDataException (a WindowLoadException) if bad data: - Widget w = createWidget (*d); + Widget w = createWidget (this, *d); widgets[i] = w; return w; } diff -r 0aa621b3e070 -r b5fadd8d930b mde/resource/paths.d --- a/mde/resource/paths.d Fri Apr 04 17:07:38 2008 +0100 +++ b/mde/resource/paths.d Tue Apr 08 15:52:21 2008 +0100 @@ -37,10 +37,11 @@ import mde.mergetag.DataSet; import mde.mergetag.exception; +import tango.io.Console; import tango.io.FilePath; -import tango.util.log.Log : Log, Logger; import tango.stdc.stdlib; import tango.stdc.stringz; +//import tango.scrapple.sys.win32.Registry; // Trouble getting this to work /** Order to read files in. * @@ -124,8 +125,8 @@ paths[pathsLen++] = fp.toString~'/'; return true; } catch (Exception e) { - logger.error ("Creating path "~path~" failed:"); - logger.error (e.msg); + // No logging avaiable yet: Use Stdout/Cout + Cout ("Creating path "~path~" failed:" ~ e.msg).newline; } } return false; @@ -142,14 +143,14 @@ char[] logDir; //BEGIN Path resolution -static this() { - logger = Log.getLogger ("mde.resource.paths"); -} - // These are used several times: const DATA = "/data"; const CONF = "/conf"; +/** Find at least one path for each required directory. +* +* Note: the logger cannot be used yet, so only output is exception messages. */ + version (linux) { void resolvePaths () { // Home directory: @@ -177,26 +178,27 @@ } } else version (Windows) { void resolvePaths () { - static assert (false, "No registry code"); + //FIXME: Get path from registry + //FIXME: Get user path (Docs&Settings/USER/Local Settings/Application data/mde) // Base paths: - char[] userPath = `...`; - char[] installPath = `registryInstallPath or "."`; - char[] staticPath = findPath (installPath ~ DATA); + PathView installPath = findPath (false, "");; + PathView userPath = findPath (true, "user"); // FIXME: see above + PathView staticPath = findPath (false, "data"); // Static data paths: dataDir.addPath (staticPath.toString); // we know this is valid anyway dataDir.tryPath (userPath.toString ~ DATA); if (!dataDir.pathsLen) throw new mdeException ("Fatal: no data path found!"); - + // Configuration paths: confDir.tryPath (staticPath.toString ~ CONF); - bool sysConf = confDir.tryPath (installPath ~ CONF); - confDir.tryPath (userPath.toString ~ CONF, !sysConf); // create if no system conf dir + confDir.tryPath ("conf"); + confDir.tryPath (userPath.toString ~ CONF, true); if (!confDir.pathsLen) throw new mdeException ("Fatal: no conf path found!"); // Logging path: - logDir = userPath; + logDir = userPath.toString; } } else { static assert (false, "Platform is not linux or Windows: no support for paths on this platform yet!"); @@ -207,8 +209,6 @@ // There are NO CHECKS that this is not exceeded. const MAX_PATHS = 3; -Logger logger; - /* Try each path in succession, returning the first to exist and be a folder. * If none are valid and create is true, will try creating each in turn. * If still none are valid, throws. */ @@ -219,17 +219,17 @@ } if (create) { // try to create a folder, using each path in turn until succesful foreach (path; paths) { - PathView pv = new FilePath (path); + FilePath fp = new FilePath (path); try { - return pv; + return fp.create; } catch (Exception e) {} } } // no valid path... - logger.fatal ("Unable to find"~(create ? " or create" : "")~" a required path! The following were tried:"); - foreach (path; paths) logger.fatal ('\t' ~ path); - throw new mdeException ("Unable to resolve a required path (see log for details)."); + char[] msg = "Unable to find"~(create ? " or create" : "")~" a required path! The following were tried:"; + foreach (path; paths) msg ~= " \"" ~ path ~ '\"'; + throw new mdeException (msg); } //END Path resolution diff -r 0aa621b3e070 -r b5fadd8d930b mde/scheduler/Init.d --- a/mde/scheduler/Init.d Fri Apr 04 17:07:38 2008 +0100 +++ b/mde/scheduler/Init.d Tue Apr 08 15:52:21 2008 +0100 @@ -55,6 +55,7 @@ try { paths.resolvePaths(); } catch (Exception e) { + // NOTE: an exception thrown here cannot be caught by main()! throw new InitException ("Resolving paths failed: " ~ e.msg); }