Changeset 28:b5fadd8d930b
- Timestamp:
- 04/08/08 10:52:21
(9 months ago)
- Author:
- Diggory Hardy <diggory.hardy@gmail.com>
- branch:
- default
- convert_revision:
- f72a3976a5547b70cd6535d5ab287336c369e7d0
- Message:
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 <diggory.hardy@gmail.com>
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r27 |
r28 |
|
| 3 | 3 | <int|x=10> |
|---|
| 4 | 4 | <int|y=50> |
|---|
| 5 | | <int[][int]|widgetData=[0:[1,200,200]]> |
|---|
| | 5 | <int[][int]|widgetData=[0:[1001,200,200]]> |
|---|
| | 6 | {W2} |
|---|
| | 7 | <int|x=150> |
|---|
| | 8 | <int|y=200> |
|---|
| | 9 | <int[][int]|widgetData=[0:[1002,2],2:[1001,150,150]]> |
|---|
| r27 |
r28 |
|
| 17 | 17 | module mde.gui.Widget; |
|---|
| 18 | 18 | |
|---|
| | 19 | import mde.gui.IWindow; |
|---|
| 19 | 20 | import mde.gui.exception; |
|---|
| 20 | 21 | |
|---|
| … | … | |
| 28 | 29 | interface Widget |
|---|
| 29 | 30 | { |
|---|
| | 31 | /* this() should look like this: |
|---|
| | 32 | this (IWindow window, int[] data) |
|---|
| | 33 | * where: |
|---|
| | 34 | * window is the parent window (only needed for getting sub-widgets, hence no need to store) |
|---|
| | 35 | * data is the widget creation data, stripped of the widget type (see createWidget). |
|---|
| | 36 | */ |
|---|
| | 37 | |
|---|
| 30 | 38 | /** Draw, starting from given x and y. |
|---|
| 31 | 39 | * |
|---|
| … | … | |
| 45 | 53 | int w, h; // size |
|---|
| 46 | 54 | |
|---|
| 47 | | this (int[] data) { |
|---|
| | 55 | this (IWindow, int[] data) { |
|---|
| 48 | 56 | if (data.length != 2) throw new WidgetDataException; |
|---|
| 49 | 57 | |
|---|
| … | … | |
| 63 | 71 | } |
|---|
| 64 | 72 | |
|---|
| 65 | | enum WIDGET_TYPES : int { |
|---|
| 66 | | BOX = 1 |
|---|
| | 73 | /// Encapsulates another widget |
|---|
| | 74 | class SingleWidget : Widget |
|---|
| | 75 | { |
|---|
| | 76 | int w, h; // size |
|---|
| | 77 | Widget subWidget; |
|---|
| | 78 | |
|---|
| | 79 | this (IWindow window, int[] data) { |
|---|
| | 80 | if (data.length != 1) throw new WidgetDataException; |
|---|
| | 81 | |
|---|
| | 82 | subWidget = window.getWidget (data[0]); |
|---|
| | 83 | |
|---|
| | 84 | subWidget.getSize (w,h); |
|---|
| | 85 | w += 10; |
|---|
| | 86 | h += 10; |
|---|
| | 87 | } |
|---|
| | 88 | |
|---|
| | 89 | void draw (int x, int y) { |
|---|
| | 90 | gl.setColor (1.0f, 0.6f, 0.0f); |
|---|
| | 91 | gl.drawBox (x,x+w, y,y+h); |
|---|
| | 92 | |
|---|
| | 93 | subWidget.draw (x+5, y+5); |
|---|
| | 94 | } |
|---|
| | 95 | |
|---|
| | 96 | void getSize (out int w, out int h) { |
|---|
| | 97 | w = this.w; |
|---|
| | 98 | h = this.h; |
|---|
| | 99 | } |
|---|
| 67 | 100 | } |
|---|
| 68 | 101 | |
|---|
| 69 | | Widget createWidget (int[] data) { |
|---|
| | 102 | // Widget types. Start high so they can be reordered easily later. |
|---|
| | 103 | enum WIDGET_TYPES : int { |
|---|
| | 104 | BOX = 1001, SINGLE |
|---|
| | 105 | } |
|---|
| | 106 | |
|---|
| | 107 | Widget createWidget (IWindow window, int[] data) { |
|---|
| 70 | 108 | if (data.length < 1) throw new WidgetDataException ("No widget data"); |
|---|
| 71 | 109 | int type = data[0]; // type is first element of data |
|---|
| 72 | 110 | data = data[1..$]; // the rest is passed to the Widget |
|---|
| 73 | 111 | |
|---|
| 74 | | if (type == WIDGET_TYPES.BOX) return new BoxWidget (data); |
|---|
| | 112 | if (type == WIDGET_TYPES.BOX) return new BoxWidget (window, data); |
|---|
| | 113 | else if (type == WIDGET_TYPES.SINGLE) return new SingleWidget (window, data); |
|---|
| 75 | 114 | else throw new WidgetDataException ("Bad widget type"); |
|---|
| 76 | 115 | } |
|---|
| r27 |
r28 |
|
| 17 | 17 | module mde.gui.gui; |
|---|
| 18 | 18 | |
|---|
| | 19 | import mde.gui.IWindow; |
|---|
| 19 | 20 | import mde.gui.Widget; |
|---|
| 20 | 21 | import mde.gui.exception; |
|---|
| … | … | |
| 69 | 70 | try { |
|---|
| 70 | 71 | w.finalise(); |
|---|
| | 72 | |
|---|
| | 73 | gl.addDrawCallback (&w.draw); |
|---|
| 71 | 74 | } catch (WindowLoadException e) { |
|---|
| 72 | 75 | logger.error ("Window failed to load: " ~ e.msg); |
|---|
| 73 | 76 | } |
|---|
| 74 | | |
|---|
| 75 | | gl.addDrawCallback (&w.draw); |
|---|
| 76 | 77 | } |
|---|
| 77 | 78 | } |
|---|
| … | … | |
| 92 | 93 | * created, be given its int[] of data, which this() must confirm is valid (or throw). |
|---|
| 93 | 94 | */ |
|---|
| 94 | | class Window : mt.IDataSection |
|---|
| | 95 | class Window : mt.IDataSection, IWindow |
|---|
| 95 | 96 | { |
|---|
| 96 | 97 | alias int widgetID; // Widget ID type. Each ID is unique under this window. Type is int since this is the widget data type. |
|---|
| … | … | |
| 102 | 103 | int w,h; // Window size (calculated from Widgets) |
|---|
| 103 | 104 | |
|---|
| 104 | | const BORDER_WIDTH = 5; // Temporary way to handle window decorations |
|---|
| | 105 | const BORDER_WIDTH = 8; // Temporary way to handle window decorations |
|---|
| 105 | 106 | |
|---|
| 106 | 107 | |
|---|
| … | … | |
| 123 | 124 | |
|---|
| 124 | 125 | // Throws WidgetDataException (a WindowLoadException) if bad data: |
|---|
| 125 | | Widget w = createWidget (*d); |
|---|
| | 126 | Widget w = createWidget (this, *d); |
|---|
| 126 | 127 | widgets[i] = w; |
|---|
| 127 | 128 | return w; |
|---|
| r27 |
r28 |
|
| 38 | 38 | import mde.mergetag.exception; |
|---|
| 39 | 39 | |
|---|
| | 40 | import tango.io.Console; |
|---|
| 40 | 41 | import tango.io.FilePath; |
|---|
| 41 | | import tango.util.log.Log : Log, Logger; |
|---|
| 42 | 42 | import tango.stdc.stdlib; |
|---|
| 43 | 43 | import tango.stdc.stringz; |
|---|
| | 44 | //import tango.scrapple.sys.win32.Registry; // Trouble getting this to work |
|---|
| 44 | 45 | |
|---|
| 45 | 46 | /** Order to read files in. |
|---|
| … | … | |
| 125 | 126 | return true; |
|---|
| 126 | 127 | } catch (Exception e) { |
|---|
| 127 | | logger.error ("Creating path "~path~" failed:"); |
|---|
| 128 | | logger.error (e.msg); |
|---|
| | 128 | // No logging avaiable yet: Use Stdout/Cout |
|---|
| | 129 | Cout ("Creating path "~path~" failed:" ~ e.msg).newline; |
|---|
| 129 | 130 | } |
|---|
| 130 | 131 | } |
|---|
| … | … | |
| 143 | 144 | |
|---|
| 144 | 145 | //BEGIN Path resolution |
|---|
| 145 | | static this() { |
|---|
| 146 | | logger = Log.getLogger ("mde.resource.paths"); |
|---|
| 147 | | } |
|---|
| 148 | | |
|---|
| 149 | 146 | // These are used several times: |
|---|
| 150 | 147 | const DATA = "/data"; |
|---|
| 151 | 148 | const CONF = "/conf"; |
|---|
| | 149 | |
|---|
| | 150 | /** Find at least one path for each required directory. |
|---|
| | 151 | * |
|---|
| | 152 | * Note: the logger cannot be used yet, so only output is exception messages. */ |
|---|
| 152 | 153 | |
|---|
| 153 | 154 | version (linux) { |
|---|
| … | … | |
| 178 | 179 | } else version (Windows) { |
|---|
| 179 | 180 | void resolvePaths () { |
|---|
| 180 | | static assert (false, "No registry code"); |
|---|
| | 181 | //FIXME: Get path from registry |
|---|
| | 182 | //FIXME: Get user path (Docs&Settings/USER/Local Settings/Application data/mde) |
|---|
| 181 | 183 | |
|---|
| 182 | 184 | // Base paths: |
|---|
| 183 | | char[] userPath = `...`; |
|---|
| 184 | | char[] installPath = `registryInstallPath or "."`; |
|---|
| 185 | | char[] staticPath = findPath (installPath ~ DATA); |
|---|
| | 185 | PathView installPath = findPath (false, "");; |
|---|
| | 186 | PathView userPath = findPath (true, "user"); // FIXME: see above |
|---|
| | 187 | PathView staticPath = findPath (false, "data"); |
|---|
| 186 | 188 | |
|---|
| 187 | 189 | // Static data paths: |
|---|
| … | … | |
| 189 | 191 | dataDir.tryPath (userPath.toString ~ DATA); |
|---|
| 190 | 192 | if (!dataDir.pathsLen) throw new mdeException ("Fatal: no data path found!"); |
|---|
| 191 | | |
|---|
| | 193 | |
|---|
| 192 | 194 | // Configuration paths: |
|---|
| 193 | 195 | confDir.tryPath (staticPath.toString ~ CONF); |
|---|
| 194 | | bool sysConf = confDir.tryPath (installPath ~ CONF); |
|---|
| 195 | | confDir.tryPath (userPath.toString ~ CONF, !sysConf); // create if no system conf dir |
|---|
| | 196 | confDir.tryPath ("conf"); |
|---|
| | 197 | confDir.tryPath (userPath.toString ~ CONF, true); |
|---|
| 196 | 198 | if (!confDir.pathsLen) throw new mdeException ("Fatal: no conf path found!"); |
|---|
| 197 | 199 | |
|---|
| 198 | 200 | // Logging path: |
|---|
| 199 | | logDir = userPath; |
|---|
| | 201 | logDir = userPath.toString; |
|---|
| 200 | 202 | } |
|---|
| 201 | 203 | } else { |
|---|
| … | … | |
| 207 | 209 | // There are NO CHECKS that this is not exceeded. |
|---|
| 208 | 210 | const MAX_PATHS = 3; |
|---|
| 209 | | |
|---|
| 210 | | Logger logger; |
|---|
| 211 | 211 | |
|---|
| 212 | 212 | /* Try each path in succession, returning the first to exist and be a folder. |
|---|
| … | … | |
| 220 | 220 | if (create) { // try to create a folder, using each path in turn until succesful |
|---|
| 221 | 221 | foreach (path; paths) { |
|---|
| 222 | | PathView pv = new FilePath (path); |
|---|
| | 222 | FilePath fp = new FilePath (path); |
|---|
| 223 | 223 | try { |
|---|
| 224 | | return pv; |
|---|
| | 224 | return fp.create; |
|---|
| 225 | 225 | } |
|---|
| 226 | 226 | catch (Exception e) {} |
|---|
| … | … | |
| 228 | 228 | } |
|---|
| 229 | 229 | // no valid path... |
|---|
| 230 | | logger.fatal ("Unable to find"~(create ? " or create" : "")~" a required path! The following were tried:"); |
|---|
| 231 | | foreach (path; paths) logger.fatal ('\t' ~ path); |
|---|
| 232 | | throw new mdeException ("Unable to resolve a required path (see log for details)."); |
|---|
| | 230 | char[] msg = "Unable to find"~(create ? " or create" : "")~" a required path! The following were tried:"; |
|---|
| | 231 | foreach (path; paths) msg ~= " \"" ~ path ~ '\"'; |
|---|
| | 232 | throw new mdeException (msg); |
|---|
| 233 | 233 | } |
|---|
| 234 | 234 | //END Path resolution |
|---|
| r26 |
r28 |
|
| 56 | 56 | paths.resolvePaths(); |
|---|
| 57 | 57 | } catch (Exception e) { |
|---|
| | 58 | // NOTE: an exception thrown here cannot be caught by main()! |
|---|
| 58 | 59 | throw new InitException ("Resolving paths failed: " ~ e.msg); |
|---|
| 59 | 60 | } |
|---|