Mercurial > projects > mde
diff mde/gui/content/Content.d @ 101:71f0f1f83620
Some path adjustments for windows (untested) and fonts. All types of option can be edited.
paths: support for getting the full path for a font when just the file name is entered, in order to unify usage on windows and linux.
paths: Used getSpecialPath for some windows paths; needs testing.
Content: Moved line-editing code to abstract ValueContent class and added some conversion functions, so that any type of ValueContent can be edited as text.
author | Diggory Hardy <diggory.hardy@gmail.com> |
---|---|
date | Sun, 16 Nov 2008 17:03:47 +0000 |
parents | 0ea4a3e651ae |
children | 42e241e7be3e |
line wrap: on
line diff
--- a/mde/gui/content/Content.d Sat Nov 15 17:39:14 2008 +0000 +++ b/mde/gui/content/Content.d Sun Nov 16 17:03:47 2008 +0000 @@ -91,7 +91,75 @@ name_ = n; desc_ = d; } + + /// Get the text. + char[] toString (uint i) { + return (i == 0) ? sv + : (i == 1) ? name_ + : (i == 2) ? desc_ + : null; + } + + /** Acts on a keystroke and returns the new value. + * + * Supports one-line editing: left/right, home/end, backspace/delete. */ + char[] keyStroke (ushort sym, char[] i) { + debug assert (i.length, "TextContent.keyStroke: no value (??)"); // impossible? + char k = *i; + if (k > 0x20) { + if (k == 0x7f) { // delete + size_t p = pos; + if (p < sv.length) ++p; + while (p < sv.length && (sv[p] & 0x80) && !(sv[p] & 0x40)) + ++p; + sv = sv[0..pos] ~ sv[p..$]; + } else { // insert character + char[] tail = sv[pos..$]; + sv.length = sv.length + i.length; + size_t npos = pos+i.length; + if (tail) sv[npos..$] = tail.dup; // cannot assign with overlapping ranges + sv[pos..npos] = i; + pos = npos; + } + } else { // use sym; many keys output 0 + if (sym == SDLK_BACKSPACE) { // backspace; k == 0x8 + char[] tail = sv[pos..$]; + if (pos) --pos; + while (pos && (sv[pos] & 0x80) && !(sv[pos] & 0x40)) + --pos; + sv = sv[0..pos] ~ tail; + } else if (sym == SDLK_LEFT) { + if (pos) --pos; + while (pos && (sv[pos] & 0x80) && !(sv[pos] & 0x40)) + --pos; + } else if (sym == SDLK_RIGHT) { + if (pos < sv.length) ++pos; + while (pos < sv.length && (sv[pos] & 0x80) && !(sv[pos] & 0x40)) + ++pos; + } else if (sym == SDLK_HOME || sym == SDLK_UP) { + pos = 0; + } else if (sym == SDLK_END || sym == SDLK_DOWN) { + pos = sv.length; + } else + debug logger.trace ("Symbol: {}", sym); + } + return sv; + } + + size_t getEditIndex () { + size_t i = 0; + for (size_t p = 0; p < pos; ++p) + if (!(sv[p] & 0x80) || sv[p] & 0x40) + ++i; + return i; + } + + /// Call at the end of an edit to convert sv to v and call callbacks + void endEdit (); protected: + char[] sv; // string of value; updated on assignment for displaying and editing + size_t pos; // editing position; used by keyStroke + char[] symb; char[] name_, desc_;// name and description, loaded by lookup.Translation } @@ -113,7 +181,7 @@ /** Create a content with _symbol name symbol. */ this (char[] symbol, bool val = false) { symb = symbol; - v = val; + assignNoCB (val); } /** Adds cb to the list of callback functions called when the value is changed. Returns this. */ @@ -122,17 +190,13 @@ return this; } - /// Get the text. - char[] toString (uint i) { - return (i == 0) ? v ? "true" : "false" - : (i == 1) ? name_ - : (i == 2) ? desc_ - : null; + void assignNoCB (bool val) { + v = val; + sv = v ? "true" : "false"; } - void opAssign (bool val) { - v = val; - foreach (cb; cngCb) + assignNoCB (val); + foreach (cb; cngCb) cb(symb, val); } bool opCall () { @@ -140,9 +204,14 @@ } alias opCall opCast; - bool v; //FIXME: should be protected but Options needs to set without calling callbacks + void endEdit () { + v = sv && (sv[0] == 't' || sv[0] == 'T' || sv[0] == '1'); + foreach (cb; cngCb) + cb(symb, v); + } + protected: - char[] symb; + bool v; void delegate (char[],bool)[] cngCb; // change callbacks } @@ -152,7 +221,6 @@ this (char[] symbol, char[] val = null) { symb = symbol; v = val; - pos = v.length; } /** Adds cb to the list of callback functions called when the value is changed. Returns this. */ @@ -161,14 +229,9 @@ return this; } - /// Get the text. - char[] toString (uint i) { - return (i == 0) ? v - : (i == 1) ? name_ - : (i == 2) ? desc_ - : null; + void assignNoCB (char[] val) { + v = val; } - void opAssign (char[] val) { v = val; foreach (cb; cngCb) @@ -179,70 +242,13 @@ } alias opCall opCast; - /** Acts on a keystroke and returns the new value. - * - * Supports one-line editing: left/right, home/end, backspace/delete. */ - char[] keyStroke (ushort sym, char[] i) { - debug assert (i.length, "TextContent.keyStroke: no value (??)"); // impossible? - char k = *i; - if (k > 0x20) { - if (k == 0x7f) { // delete - size_t p = pos; - if (p < v.length) ++p; - while (p < v.length && (v[p] & 0x80) && !(v[p] & 0x40)) - ++p; - v = v[0..pos] ~ v[p..$]; - } else { // insert character - char[] tail = v[pos..$]; - v.length = v.length + i.length; - size_t npos = pos+i.length; - if (tail) v[npos..$] = tail.dup; // cannot assign with overlapping ranges - v[pos..npos] = i; - pos = npos; - } - } else { // use sym; many keys output 0 - if (sym == SDLK_BACKSPACE) { // backspace; k == 0x8 - char[] tail = v[pos..$]; - if (pos) --pos; - while (pos && (v[pos] & 0x80) && !(v[pos] & 0x40)) - --pos; - v = v[0..pos] ~ tail; - } else if (sym == SDLK_LEFT) { - if (pos) --pos; - while (pos && (v[pos] & 0x80) && !(v[pos] & 0x40)) - --pos; - } else if (sym == SDLK_RIGHT) { - if (pos < v.length) ++pos; - while (pos < v.length && (v[pos] & 0x80) && !(v[pos] & 0x40)) - ++pos; - } else if (sym == SDLK_HOME || sym == SDLK_UP) { - pos = 0; - } else if (sym == SDLK_END || sym == SDLK_DOWN) { - pos = v.length; - } else - debug logger.trace ("Symbol: {}", sym); - } - return v; - } - - size_t getEditIndex () { - size_t i = 0; - for (size_t p = 0; p < pos; ++p) - if (!(v[p] & 0x80) || v[p] & 0x40) - ++i; - return i; - } - - /// Gives all callbacks the modified value void endEdit () { foreach (cb; cngCb) cb(symb, v); } - char[] v; protected: - char[] symb; - size_t pos; // editing position; used by keyStroke + alias sv v; // don't need separate v and sv in this case void delegate (char[],char[])[] cngCb; } @@ -252,7 +258,7 @@ /** Create a content with _symbol name symbol. */ this (char[] symbol, int val = 0) { symb = symbol; - v = val; + assignNoCB (val); } /** Adds cb to the list of callback functions called when the value is changed. Returns this. */ @@ -261,17 +267,13 @@ return this; } - /// Get the text. - char[] toString (uint i) { - return (i == 0) ? Int.toString (v) - : (i == 1) ? name_ - : (i == 2) ? desc_ - : null; + void assignNoCB (int val) { + v = val; + sv = Int.toString (v); } - void opAssign (int val) { - v = val; - foreach (cb; cngCb) + assignNoCB (val); + foreach (cb; cngCb) cb(symb, val); } int opCall () { @@ -279,9 +281,14 @@ } alias opCall opCast; - int v; + void endEdit () { + v = Int.toInt (sv); + foreach (cb; cngCb) + cb(symb, v); + } + protected: - char[] symb; + int v; void delegate (char[],int)[] cngCb; } @@ -291,7 +298,7 @@ /** Create a content with _symbol name symbol. */ this (char[] symbol, double val = 0) { symb = symbol; - v = val; + assignNoCB (val); } /** Adds cb to the list of callback functions called when the value is changed. Returns this. */ @@ -300,17 +307,13 @@ return this; } - /// Get the text. - char[] toString (uint i) { - return (i == 0) ? Float.toString (v) - : (i == 1) ? name_ - : (i == 2) ? desc_ - : null; + void assignNoCB (double val) { + v = val; + sv = Float.toString (v); } - void opAssign (double val) { - v = val; - foreach (cb; cngCb) + assignNoCB (val); + foreach (cb; cngCb) cb(symb, val); } double opCall () { @@ -318,8 +321,13 @@ } alias opCall opCast; - double v; + void endEdit () { + v = Float.toFloat (sv); + foreach (cb; cngCb) + cb(symb, v); + } + protected: - char[] symb; + double v; void delegate (char[],double)[] cngCb; }