Changeset 101:71f0f1f83620
- Timestamp:
- 11/16/08 12:03:47 (2 months ago)
- Files:
-
- data/conf/gui.mtt (modified) (1 diff)
- data/conf/options.mtt (modified) (1 diff)
- mde/font/font.d (modified) (2 diffs)
- mde/gui/content/Content.d (modified) (14 diffs)
- mde/gui/widget/createWidget.d (modified) (2 diffs)
- mde/gui/widget/miscContent.d (modified) (1 diff)
- mde/gui/widget/textContent.d (modified) (2 diffs)
- mde/lookup/Options.d (modified) (1 diff)
- mde/scheduler/Scheduler.d (modified) (1 diff)
- mde/setup/Init.d (modified) (1 diff)
- mde/setup/paths.d (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
data/conf/gui.mtt
r100 r101 15 15 <WidgetData|optVal={0:[0x6030]}> 16 16 <WidgetData|optSep={0:[0x21, 0xff],1:["="]}> 17 <WidgetData|floating={0:[0x8200,13,6,14],1:["text","button","blank"]}> 18 <WidgetData|text={0:[0x4032]}> 17 <WidgetData|floating={0:[0x8200,6,14],1:["button","blank"]}> 19 18 {Basic} 20 19 <WidgetData|root={0:[0x21,0x90D970],1:["A string!"]}> data/conf/options.mtt
r100 r101 11 11 <int|lcdFilter=2> 12 12 <int|renderMode=0x30000> 13 <char[]|defaultFont="/usr/share/fonts/X11/Type1/n019003l.pfb">14 !<char[]|defaultFont="/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf">13 !<char[]|defaultFont="n019003l.pfb"> 14 <char[]|defaultFont="DejaVuSans.ttf"> 15 15 <int|defaultSize=16> 16 16 mde/font/font.d
r100 r101 23 23 24 24 import mde.setup.exception; // InitStage stuff 25 import mde.setup.paths; 25 26 26 27 import derelict.freetype.ft; … … 126 127 * Sharing an FT_Face would require calling FT_Set_Pixel_Sizes each time a glyph is rendered or 127 128 * swapping the size information (face.size)? */ 128 this (char[] path, int size)129 this (char[] file, int size) 129 130 in { 130 131 assert (library !is null, "font: library is null"); 131 132 } body { 132 if (FT_New_Face (library, toStringz(path), 0, &face))133 throw new fontLoadException ("Unable to read font: "~ path);133 if (FT_New_Face (library, getFontPath (file).ptr, 0, &face)) 134 throw new fontLoadException ("Unable to read font: "~file[0..$-1]); 134 135 135 136 if (!FT_IS_SCALABLE (face)) 136 137 throw new fontLoadException ("Currently no support for non-scalable fonts (which " ~ 137 path~ " is). Please report if you want to see support.");138 file[0..$-1] ~ " is). Please report if you want to see support."); 138 139 /* The following will need to be addressed when adding support for non-scalables: 139 140 * Use of face.size.metrics.height property. mde/gui/content/Content.d
r100 r101 92 92 desc_ = d; 93 93 } 94 protected: 94 95 /// Get the text. 96 char[] toString (uint i) { 97 return (i == 0) ? sv 98 : (i == 1) ? name_ 99 : (i == 2) ? desc_ 100 : null; 101 } 102 103 /** Acts on a keystroke and returns the new value. 104 * 105 * Supports one-line editing: left/right, home/end, backspace/delete. */ 106 char[] keyStroke (ushort sym, char[] i) { 107 debug assert (i.length, "TextContent.keyStroke: no value (??)"); // impossible? 108 char k = *i; 109 if (k > 0x20) { 110 if (k == 0x7f) { // delete 111 size_t p = pos; 112 if (p < sv.length) ++p; 113 while (p < sv.length && (sv[p] & 0x80) && !(sv[p] & 0x40)) 114 ++p; 115 sv = sv[0..pos] ~ sv[p..$]; 116 } else { // insert character 117 char[] tail = sv[pos..$]; 118 sv.length = sv.length + i.length; 119 size_t npos = pos+i.length; 120 if (tail) sv[npos..$] = tail.dup; // cannot assign with overlapping ranges 121 sv[pos..npos] = i; 122 pos = npos; 123 } 124 } else { // use sym; many keys output 0 125 if (sym == SDLK_BACKSPACE) { // backspace; k == 0x8 126 char[] tail = sv[pos..$]; 127 if (pos) --pos; 128 while (pos && (sv[pos] & 0x80) && !(sv[pos] & 0x40)) 129 --pos; 130 sv = sv[0..pos] ~ tail; 131 } else if (sym == SDLK_LEFT) { 132 if (pos) --pos; 133 while (pos && (sv[pos] & 0x80) && !(sv[pos] & 0x40)) 134 --pos; 135 } else if (sym == SDLK_RIGHT) { 136 if (pos < sv.length) ++pos; 137 while (pos < sv.length && (sv[pos] & 0x80) && !(sv[pos] & 0x40)) 138 ++pos; 139 } else if (sym == SDLK_HOME || sym == SDLK_UP) { 140 pos = 0; 141 } else if (sym == SDLK_END || sym == SDLK_DOWN) { 142 pos = sv.length; 143 } else 144 debug logger.trace ("Symbol: {}", sym); 145 } 146 return sv; 147 } 148 149 size_t getEditIndex () { 150 size_t i = 0; 151 for (size_t p = 0; p < pos; ++p) 152 if (!(sv[p] & 0x80) || sv[p] & 0x40) 153 ++i; 154 return i; 155 } 156 157 /// Call at the end of an edit to convert sv to v and call callbacks 158 void endEdit (); 159 protected: 160 char[] sv; // string of value; updated on assignment for displaying and editing 161 size_t pos; // editing position; used by keyStroke 162 char[] symb; 95 163 char[] name_, desc_;// name and description, loaded by lookup.Translation 96 164 } … … 114 182 this (char[] symbol, bool val = false) { 115 183 symb = symbol; 116 v = val;184 assignNoCB (val); 117 185 } 118 186 … … 123 191 } 124 192 125 /// Get the text. 126 char[] toString (uint i) { 127 return (i == 0) ? v ? "true" : "false" 128 : (i == 1) ? name_ 129 : (i == 2) ? desc_ 130 : null; 131 } 132 193 void assignNoCB (bool val) { 194 v = val; 195 sv = v ? "true" : "false"; 196 } 133 197 void opAssign (bool val) { 134 v = val;135 foreach (cb; cngCb)198 assignNoCB (val); 199 foreach (cb; cngCb) 136 200 cb(symb, val); 137 201 } … … 141 205 alias opCall opCast; 142 206 143 bool v; //FIXME: should be protected but Options needs to set without calling callbacks 144 protected: 145 char[] symb; 207 void endEdit () { 208 v = sv && (sv[0] == 't' || sv[0] == 'T' || sv[0] == '1'); 209 foreach (cb; cngCb) 210 cb(symb, v); 211 } 212 213 protected: 214 bool v; 146 215 void delegate (char[],bool)[] cngCb; // change callbacks 147 216 } … … 153 222 symb = symbol; 154 223 v = val; 155 pos = v.length;156 224 } 157 225 … … 162 230 } 163 231 164 /// Get the text. 165 char[] toString (uint i) { 166 return (i == 0) ? v 167 : (i == 1) ? name_ 168 : (i == 2) ? desc_ 169 : null; 170 } 171 232 void assignNoCB (char[] val) { 233 v = val; 234 } 172 235 void opAssign (char[] val) { 173 236 v = val; … … 180 243 alias opCall opCast; 181 244 182 /** Acts on a keystroke and returns the new value.183 *184 * Supports one-line editing: left/right, home/end, backspace/delete. */185 char[] keyStroke (ushort sym, char[] i) {186 debug assert (i.length, "TextContent.keyStroke: no value (??)"); // impossible?187 char k = *i;188 if (k > 0x20) {189 if (k == 0x7f) { // delete190 size_t p = pos;191 if (p < v.length) ++p;192 while (p < v.length && (v[p] & 0x80) && !(v[p] & 0x40))193 ++p;194 v = v[0..pos] ~ v[p..$];195 } else { // insert character196 char[] tail = v[pos..$];197 v.length = v.length + i.length;198 size_t npos = pos+i.length;199 if (tail) v[npos..$] = tail.dup; // cannot assign with overlapping ranges200 v[pos..npos] = i;201 pos = npos;202 }203 } else { // use sym; many keys output 0204 if (sym == SDLK_BACKSPACE) { // backspace; k == 0x8205 char[] tail = v[pos..$];206 if (pos) --pos;207 while (pos && (v[pos] & 0x80) && !(v[pos] & 0x40))208 --pos;209 v = v[0..pos] ~ tail;210 } else if (sym == SDLK_LEFT) {211 if (pos) --pos;212 while (pos && (v[pos] & 0x80) && !(v[pos] & 0x40))213 --pos;214 } else if (sym == SDLK_RIGHT) {215 if (pos < v.length) ++pos;216 while (pos < v.length && (v[pos] & 0x80) && !(v[pos] & 0x40))217 ++pos;218 } else if (sym == SDLK_HOME || sym == SDLK_UP) {219 pos = 0;220 } else if (sym == SDLK_END || sym == SDLK_DOWN) {221 pos = v.length;222 } else223 debug logger.trace ("Symbol: {}", sym);224 }225 return v;226 }227 228 size_t getEditIndex () {229 size_t i = 0;230 for (size_t p = 0; p < pos; ++p)231 if (!(v[p] & 0x80) || v[p] & 0x40)232 ++i;233 return i;234 }235 236 /// Gives all callbacks the modified value237 245 void endEdit () { 238 246 foreach (cb; cngCb) … … 240 248 } 241 249 242 char[] v; 243 protected: 244 char[] symb; 245 size_t pos; // editing position; used by keyStroke 250 protected: 251 alias sv v; // don't need separate v and sv in this case 246 252 void delegate (char[],char[])[] cngCb; 247 253 } … … 253 259 this (char[] symbol, int val = 0) { 254 260 symb = symbol; 255 v = val;261 assignNoCB (val); 256 262 } 257 263 … … 262 268 } 263 269 264 /// Get the text. 265 char[] toString (uint i) { 266 return (i == 0) ? Int.toString (v) 267 : (i == 1) ? name_ 268 : (i == 2) ? desc_ 269 : null; 270 } 271 270 void assignNoCB (int val) { 271 v = val; 272 sv = Int.toString (v); 273 } 272 274 void opAssign (int val) { 273 v = val;274 foreach (cb; cngCb)275 assignNoCB (val); 276 foreach (cb; cngCb) 275 277 cb(symb, val); 276 278 } … … 280 282 alias opCall opCast; 281 283 284 void endEdit () { 285 v = Int.toInt (sv); 286 foreach (cb; cngCb) 287 cb(symb, v); 288 } 289 290 protected: 282 291 int v; 283 protected:284 char[] symb;285 292 void delegate (char[],int)[] cngCb; 286 293 } … … 292 299 this (char[] symbol, double val = 0) { 293 300 symb = symbol; 294 v = val;301 assignNoCB (val); 295 302 } 296 303 … … 301 308 } 302 309 303 /// Get the text. 304 char[] toString (uint i) { 305 return (i == 0) ? Float.toString (v) 306 : (i == 1) ? name_ 307 : (i == 2) ? desc_ 308 : null; 309 } 310 310 void assignNoCB (double val) { 311 v = val; 312 sv = Float.toString (v); 313 } 311 314 void opAssign (double val) { 312 v = val;313 foreach (cb; cngCb)315 assignNoCB (val); 316 foreach (cb; cngCb) 314 317 cb(symb, val); 315 318 } … … 319 322 alias opCall opCast; 320 323 324 void endEdit () { 325 v = Float.toFloat (sv); 326 foreach (cb; cngCb) 327 cb(symb, v); 328 } 329 330 protected: 321 331 double v; 322 protected:323 char[] symb;324 332 void delegate (char[],double)[] cngCb; 325 333 } mde/gui/widget/createWidget.d
r99 r101 107 107 DisplayContent = TAKES_CONTENT | 0x30, 108 108 BoolContent = TAKES_CONTENT | 0x31, 109 TextContent = TAKES_CONTENT | 0x32,109 ValueContent = TAKES_CONTENT | 0x32, 110 110 111 111 GridLayout = TAKES_CONTENT | PARENT | 0x100, … … 127 127 "DisplayContent", 128 128 "BoolContent", 129 " TextContent",129 "ValueContent", 130 130 "editContent", 131 131 "TrialContentLayout", mde/gui/widget/miscContent.d
r99 r101 29 29 if (cast(BoolContent) c) 30 30 return new BoolContentWidget(mgr,id,data,c); 31 else if (cast( TextContent) c)32 return new TextContentWidget(mgr,id,data,c);31 else if (cast(ValueContent) c) 32 return new ValueContentWidget(mgr,id,data,c); 33 33 else // generic uneditable option 34 34 return new DisplayContentWidget(mgr,id,data,c); mde/gui/widget/textContent.d
r100 r101 32 32 } 33 33 34 35 class TextContentWidget : ATextWidget34 /// Capable of editing any ValueContent class 35 class ValueContentWidget : ATextWidget 36 36 { 37 37 this (IWidgetManager mgr, widgetID id, WidgetData data, IContent c) { 38 38 WDCheck(data, 1); 39 content = cast( TextContent) c;40 if (!content) content = new TextContent (null, null);41 //throw new ContentException ();39 content = cast(ValueContent) c; 40 if (!content) //content = new TextContent (null, null); 41 throw new ContentException (); 42 42 adapter = mgr.renderer.getAdapter (content.toString(0)); 43 43 super (mgr, id, data); … … 64 64 65 65 protected: 66 TextContent content;66 ValueContent content; 67 67 } mde/lookup/Options.d
r98 r101 125 125 if (p) { 126 126 auto q = cast(`~VContentN!(T)~`) (*p); 127 if (q) q. v= parseTo!(`~T.stringof~`) (dt);127 if (q) q.assignNoCB = parseTo!(`~T.stringof~`) (dt); 128 128 } 129 129 }`; mde/scheduler/Scheduler.d
r95 r101 26 26 import tango.util.log.Log : Log, Logger; 27 27 private Logger logger; 28 } 29 static this() { 30 debug logger = Log.getLogger ("mde.scheduler.Scheduler");28 static this() { 29 logger = Log.getLogger ("mde.scheduler.Scheduler"); 30 } 31 31 } 32 32 mde/setup/Init.d
r98 r101 120 120 if (args.contains("conf-path")) 121 121 paths.extraConfPath = args["conf-path"]; 122 122 123 if (args.contains("base-path")) 123 124 paths.resolvePaths (args["base-path"]); mde/setup/paths.d
r91 r101 40 40 import tango.io.Console; 41 41 import tango.io.FilePath; 42 import tango.sys.Environment; 43 //import tango.scrapple.sys.win32.Registry; // Trouble getting this to work 42 version (linux) { 43 import tango.io.FileScan; 44 import tango.util.container.SortedMap; 45 import tango.sys.Environment; 46 } else version (Windows) 47 import tango.sys.win32.SpecialPath; 48 49 debug { 50 import tango.util.log.Log : Log, Logger; 51 private Logger logger; 52 static this() { 53 logger = Log.getLogger ("mde.setup.paths"); 54 } 55 } 44 56 45 57 /** Order to read files in. … … 112 124 Cout ("\nConf paths found:"); 113 125 confDir.coutPaths; 114 Cout ("\nLog file directory:\n\t")(logDir).newline; 126 Cout ("\nLog file directory:\n\t")(logDir); 127 version (Windows) { 128 Cout ("\nFont directory:\n\t")(fontDir).newline; 129 } else version (linux) { 130 Cout ("\nFont filse found:"); 131 foreach (f,p; fontFiles) 132 Cout ("\n\t")(f)("\t")(p[0..$-1]); 133 Cout.newline; 134 } 115 135 } 116 136 … … 191 211 /** These are the actual instances, one for each of the data and conf "directories". */ 192 212 mdeDirectory dataDir, confDir; 193 char[] logDir; 213 char[] logDir; /// Directory for log files 194 214 195 215 //BEGIN Path resolution … … 203 223 // FIXME: use tango/sys/Environment.d 204 224 version (linux) { 225 SortedMap!(char[],char[]) fontFiles; // key is file name, value is CString path 226 /** Get the actual path of a font file, or throw NoFileException if not found. 227 * 228 * Returns a C string (null terminated). */ 229 char[] getFontPath (char[] file) { 230 char[] ret; 231 if (fontFiles.get (file, ret)) 232 return ret; 233 throw new NoFileException ("Unable to find font file: "~file); 234 } 235 205 236 // base-path not used on posix 206 void resolvePaths (char[] = null) {237 void resolvePaths (char[] base = "data") { 207 238 // Home directory: 208 239 char[] HOME = Environment.get("HOME", "."); … … 211 242 // Static data (must exist): 212 243 FilePath staticPath = 213 findPath (false, "/usr/share/games/mde", "/usr/local/share/games/mde", "data");244 findPath (false, "/usr/share/games/mde", "/usr/local/share/games/mde", base); 214 245 // Config (can just use defaults if necessary, so long as we can save afterwards): 215 246 FilePath userPath = findPath (true, HOME~"/.config/mde", HOME~"/.mde"); … … 230 261 // Logging path: 231 262 logDir = userPath.toString; 263 264 // Font paths: 265 auto fs = new FileScan; 266 // Scan for directories containing truetype and type1 fonts: 267 fs.sweep ("/usr/share/fonts", (FilePath fp, bool isDir) 268 { return isDir || fp.suffix == ".ttf" || fp.suffix == ".pfb"; }, 269 true); 270 fontFiles = new SortedMap!(char[],char[]); 271 foreach (fp; fs.files) 272 fontFiles.add (fp.file, fp.cString); // both strings should be slices of same memory 273 logger.trace ("found {} font files, {} dirs", fs.files.length, fs.folders.length); 232 274 } 233 275 } else version (Windows) { 276 char[] fontDir; 277 /** Get the actual path of a font file, or throw NoFileException if not found. 278 * 279 * Returns a C string (null terminated). */ 280 char[] getFontPath (char[] file) { 281 FilePath path = new FilePath (fontDir~file); 282 if (path.exists && !path.isFolder) 283 return path.CString; 284 throw new NoFileException ("Unable to find font file: "~file); 285 } 286 234 287 void resolvePaths (char[] base = "./") { 235 //FIXME: Get path from registry 236 //FIXME: Get user path (Docs&Settings/USER/Local Settings/Application data/mde) 237 //http://www.dsource.org/projects/tango/forums/topic/187 288 //FIXME: Get base path from registry 238 289 239 290 // Base paths: 240 291 FilePath installPath = findPath (false, base); 241 FilePath staticPath = findPath (false, installPath. append("data").toString);242 FilePath userPath = findPath (true, installPath.append("user").toString); // FIXME: see above 292 FilePath staticPath = findPath (false, installPath.toString); 293 FilePath userPath = findPath (true, getSpecialPath(CSIDL_LOCAL_APPDATA) ~ "/mde"); 243 294 244 295 // Static data paths: … … 257 308 // Logging path: 258 309 logDir = userPath.toString; 310 311 // Font path: 312 fontDir = getSpecialPath (CSIDL_FONTS) ~ "/"; // append separator 259 313 } 260 314 } else {
