Mercurial > projects > mde
diff mde/gui/content/Content.d @ 99:5de5810e3516
Implemented an editable TextContent widget; it's now possible to edit text options using the GUI.
The widget supports moving the text entry-point using arrows and home/end, but there's no visual indicator or edit-point setting using the mouse.
author | Diggory Hardy <diggory.hardy@gmail.com> |
---|---|
date | Fri, 14 Nov 2008 12:44:32 +0000 |
parents | 49e7cfed4b34 |
children | 0ea4a3e651ae |
line wrap: on
line diff
--- a/mde/gui/content/Content.d Wed Nov 12 13:18:51 2008 +0000 +++ b/mde/gui/content/Content.d Fri Nov 14 12:44:32 2008 +0000 @@ -20,6 +20,7 @@ //FIXME: efficient conversions? Need to dup result when formatting a string anyway? import Int = tango.text.convert.Integer; import Float = tango.text.convert.Float; +import derelict.sdl.keysym; debug { import tango.util.log.Log : Log, Logger; @@ -151,6 +152,7 @@ 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. */ @@ -177,9 +179,62 @@ } 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; + } + + /// 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 void delegate (char[],char[])[] cngCb; }