Revision: 4874 http://sourceforge.net/p/vexi/code/4874 Author: mkpg2 Date: 2016-07-16 00:05:55 +0000 (Sat, 16 Jul 2016) Log Message: ----------- Support international keyboards. - Need to use key typed events and not key pressed. - New core event KeyTyped. - Make KeyTyped event primary source of characters in text widgets - Still use KeyPressed for control characters (arrow keys, delete ... etc.)
Modified Paths: -------------- branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/Constants.java branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/Surface.java branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/plat/Swing.java branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/focusmanager.t branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/surface.t branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/text/edit.t branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/text/field.t branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/shadowtext.t branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/textarea.t branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/textfield.t branches/vexi3/org.vexi-vexi.widgets/src_poke/poke/widgets/textfield.t trunk/org.vexi-build.shared/meta/module.revisions Modified: branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/Constants.java =================================================================== --- branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/Constants.java 2016-07-15 01:16:46 UTC (rev 4873) +++ branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/Constants.java 2016-07-16 00:05:55 UTC (rev 4874) @@ -93,6 +93,7 @@ static final JS SC_DoubleClick3 = JSU.S("DoubleClick3",true); static final JS SC_KeyPressed = JSU.S("KeyPressed",true); static final JS SC_KeyReleased = JSU.S("KeyReleased",true); + static final JS SC_KeyTyped = JSU.S("KeyTyped",true); static final JS SC__Enter = JSU.S("_Enter",true); static final JS SC__Leave = JSU.S("_Leave",true); static final JS SC__Move = JSU.S("_Move",true); @@ -112,4 +113,5 @@ static final JS SC__DoubleClick3 = JSU.S("_DoubleClick3",true); static final JS SC__KeyPressed = JSU.S("_KeyPressed",true); static final JS SC__KeyReleased = JSU.S("_KeyReleased",true); + static final JS SC__KeyTyped = JSU.S("_KeyTyped",true); } \ No newline at end of file Modified: branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/Surface.java =================================================================== --- branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/Surface.java 2016-07-15 01:16:46 UTC (rev 4873) +++ branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/Surface.java 2016-07-16 00:05:55 UTC (rev 4874) @@ -204,6 +204,11 @@ // Event Handling Helper methods for subclasses /////////////////////////////////////////// private boolean keypress_scheduled = false; + + protected final void KeyTyped(String key) { + message(SC_KeyTyped, SC__KeyTyped, JSU.S(key), true); + } + protected final void KeyPressed(String key) { // check that we've not already got a keypress active // otherwise the application may 'queue up' keypresses @@ -448,9 +453,14 @@ return o; } - if (event==SC_KeyPressed) { + if (event==SC_KeyTyped) { // set up appropriate combination key values String value = JSU.toString(this.value); + this.value = JSU.S(value); + + }else if (event==SC_KeyPressed) { + // set up appropriate combination key values + String value = JSU.toString(this.value); if (shift && !value.equals("shift")) { value = value.toUpperCase(); } Modified: branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/plat/Swing.java =================================================================== --- branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/plat/Swing.java 2016-07-15 01:16:46 UTC (rev 4873) +++ branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/plat/Swing.java 2016-07-16 00:05:55 UTC (rev 4874) @@ -654,26 +654,25 @@ public void componentResized(int newwidth, int newheight) { SizeChange(newwidth, newheight); } private void checkEvent(InputEvent e) { + // HACK this isn't right. These should be passed with the value + // (because they are set here, but then the event is scheduled + // and these values can change before it is run) alt = e.isAltDown(); control = e.isControlDown(); shift = e.isShiftDown(); } public void keyTyped(KeyEvent k) { - checkEvent(k); - // REMARK - we are a so called 'passive Input Method' client. - // We receive composed text (e.g. Asian characters) as key events - // where we want to convert them into a KeyPressed/KeyReleased - // Vexi event. Unfortunately we need a way to distinguish between - // events due to inputMethods (which we want) and those from the - // keyboard which are already handled via keyPressed/keyReleased. - // HACK - simplest is to just except non-ascii chars. - int unicode = (int)k.getKeyChar(); - if (255 >= unicode) { - return; + // These return odd characters we don't want to pass to the traps. + // Are we losing anything doing it this way? + switch (k.getKeyChar()) { + case KeyEvent.VK_TAB: return; + case KeyEvent.VK_ENTER: return; + case KeyEvent.VK_BACK_SPACE: return; + case KeyEvent.VK_DELETE: return; } - KeyPressed(""+k.getKeyChar()); - KeyReleased(""+k.getKeyChar()); + + KeyTyped(""+k.getKeyChar()); } @@ -744,18 +743,18 @@ // VK_ entries not defined for Java 1.4 case 524: return "windows_key"; case 525: return "context_menu"; - // usually only single / known characters + // usually only single / known characters default: - char c = k.getKeyChar(); - if (c >= 1 && c <= 26) { - c = (char)('a' + c - 1); - } - // WORKAROUND shift+ctrl+6 (i.e. C-^) returning empty character - if (k.getKeyCode() == 54 && k.isControlDown() && k.isShiftDown()) { - c = '^'; - } - //System.out.println(c+": "+k.getKeyCode()); - return String.valueOf(c); + char c = k.getKeyChar(); + if (c >= 1 && c <= 26) { + c = (char)('a' + c - 1); + } + // WORKAROUND shift+ctrl+6 (i.e. C-^) returning empty character + if (k.getKeyCode() == 54 && k.isControlDown() && k.isShiftDown()) { + c = '^'; + } + //System.out.println(c+": "+k.getKeyCode()); + return String.valueOf(c); } } } Modified: branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/focusmanager.t =================================================================== --- branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/focusmanager.t 2016-07-15 01:16:46 UTC (rev 4873) +++ branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/focusmanager.t 2016-07-16 00:05:55 UTC (rev 4874) @@ -191,24 +191,36 @@ } //////// Key Event Handling /////////////////////////////////// + + /** pass key-type events to focused child */ + const surfaceKeyTyped = function(v) { + model.focusModelKeyTyped(v); + return; + }; + surface.event._KeyTyped ++= surfaceKeyTyped; + /** pass key-press events to focused child */ - var surfaceKeyPress = function(v) { + const surfaceKeyPress = function(v) { model.focusModelKeyPressed(v); return; - } + }; surface.event._KeyPressed ++= surfaceKeyPress; /** pass key-release events to focused child */ - var surfaceKeyRelease = function(v) { + const surfaceKeyRelease = function(v) { model.focusModelKeyReleased(v); return; - } + }; surface.event._KeyReleased ++= surfaceKeyRelease; /** focus model keypress event */ + model.focusModelKeyTyped = function(v) { + focus.KeyTyped = v; + }; + model.focusModelKeyPressed = function(v) { if (focus and focus.grabKeyList and focus.grabKeyList[v]) { // the focused widget wishes to intercept special keys @@ -236,7 +248,7 @@ // pass keypress onto focused widget focus.KeyPressed = v; } - } + }; /** focus model keyrelease event */ model.focusModelKeyReleased = function(v) { @@ -244,7 +256,7 @@ or v!="tab" or v!="TAB" or v.charCodeAt(0)!=65535)) { focus.KeyReleased = v; } - } + }; </ui:box> </vexi> Modified: branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/surface.t =================================================================== --- branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/surface.t 2016-07-15 01:16:46 UTC (rev 4873) +++ branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/surface.t 2016-07-16 00:05:55 UTC (rev 4874) @@ -67,7 +67,7 @@ "_Release1", "_Release2", "_Release3" ); /** special case key events for focusable integration */ - .util.redirect..addRedirect(thisbox, event, "_KeyPressed", "_KeyReleased" ); + .util.redirect..addRedirect(thisbox, event, "_KeyPressed", "_KeyReleased", "_KeyTyped" ); /** redirect frame properties for access */ .util.redirect..addRedirect(frame, thisbox, Modified: branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/text/edit.t =================================================================== --- branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/text/edit.t 2016-07-15 01:16:46 UTC (rev 4873) +++ branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/text/edit.t 2016-07-16 00:05:55 UTC (rev 4874) @@ -929,261 +929,344 @@ //thisbox.syncCursor = function() { return true; } /** handles keyboard editing - cursor movement, character insertion and deletion */ - KeyPressed ++= function(v) { - cascade = v; - + KeyTyped ++= function(v) { + cascade = v; + // key input invalidates textstore textstore = null; // the index of cWord in cBlock cwInd = cWord ? cBlock.indexof(cWord) : null; + + // special case select mode + if (select) deleteSelectedText(); - // character insertion - if (v.length == 1) { - // special case select mode - if (select) deleteSelectedText(); - - var type = .block..getCharType(v); - if (insert) { - if (cWord) { - // this is a box of the same character type - if (type == cWord.chartype) { - if (cPos == 0) { - cWord.text = v + cWord.text; - } else if (cPos == cWord.text.length) { - cWord.text += v; - } else { - var str1 = cWord.text.substring(0, cPos); - var str2 = cWord.text.substring(cPos, cWord.text.length); - cWord.text = str1 + v + str2; - } - cPos++; + var type = .block..getCharType(v); + if (insert) { + if (cWord) { + // this is a box of the same character type + if (type == cWord.chartype) { + if (cPos == 0) { + cWord.text = v + cWord.text; + } else if (cPos == cWord.text.length) { + cWord.text += v; + } else { + var str1 = cWord.text.substring(0, cPos); + var str2 = cWord.text.substring(cPos, cWord.text.length); + cWord.text = str1 + v + str2; + } + cPos++; + + } else if (cPos == 0 and cwInd != 0 and type == cBlock[cwInd-1].chartype) { + // cursor is at the start of a word which follows a set of spaces + cBlock[cwInd-1].text += v; + + } else { + // need to insert new word + var w = .word(vexi.box, cBlock.wordargs); + w.text = v; + w.chartype = type; - } else if (cPos == 0 and cwInd != 0 and type == cBlock[cwInd-1].chartype) { - // cursor is at the start of a word which follows a set of spaces - cBlock[cwInd-1].text += v; + if (cPos == 0) { + // place before current word + cBlock[cwInd] = w; + } else if (cPos == cWord.text.length) { + // place after current word + cBlock[cBlock.numchildren] = w; + cPos = 1; + cWord = w; + } else { - // need to insert new word - var w = .word(vexi.box, cBlock.wordargs); - w.text = v; - w.chartype = type; - - if (cPos == 0) { - // place before current word - cBlock[cwInd] = w; - - } else if (cPos == cWord.text.length) { - // place after current word - cBlock[cBlock.numchildren] = w; - cPos = 1; - cWord = w; - - } else { - // need to split current word - var w2 = .word(vexi.box, cBlock.wordargs); - w2.text = cWord.text.slice(cPos); - cWord.text = cWord.text.slice(0, cPos); - cBlock[cwInd+1] = w; - cBlock[cwInd+2] = w2; - cPos = 0; - cWord = w2; - } + // need to split current word + var w2 = .word(vexi.box, cBlock.wordargs); + w2.text = cWord.text.slice(cPos); + cWord.text = cWord.text.slice(0, cPos); + cBlock[cwInd+1] = w; + cBlock[cwInd+2] = w2; + cPos = 0; + cWord = w2; } - - } else { - // no word in this block - create one - cBlock[0] = .word(vexi.box, cBlock.wordargs); - cBlock[0].text = v; - cBlock[0].chartype = type; - cPos = 1; - cWord = cBlock[0]; } } else { - // insert == false - - // delete next character and insert new char - KeyPressed = "delete"; - insert = true; - KeyPressed = v; - insert = false; + // no word in this block - create one + cBlock[0] = .word(vexi.box, cBlock.wordargs); + cBlock[0].text = v; + cBlock[0].chartype = type; + cPos = 1; + cWord = cBlock[0]; } } else { - // actions + // insert == false - // the index of cBlock in thisbox - cbInd = thisbox.indexof(cBlock); + // delete next character and insert new char + KeyPressed = "delete"; + insert = true; + KeyTyped = v; + insert = false; + } + cBlock.reflowbox = true; + syncCursorAndOffset(false); + return true; + }; + + + KeyPressed ++= function(v) { + cascade = v; + + if (v.length == 1) return; + + // key input invalidates textstore + textstore = null; + + // the index of cWord in cBlock + cwInd = cWord ? cBlock.indexof(cWord) : null; + + // actions + + // the index of cBlock in thisbox + cbInd = thisbox.indexof(cBlock); + + switch(v) { + // select all + case "C-a": + case "C-A": + selectAll(); + break; + + // unselect all + case "escape": + unselectAll(); + break; + + // copy + case "C-c": + case "C-C": + copy(); + break; - switch(v) { - // select all - case "C-a": - case "C-A": - selectAll(); - break; + // cut + case "C-x": + case "C-X": + cut(); + break; - // unselect all - case "escape": - unselectAll(); - break; + // paste + case "C-v": + case "C-V": + paste(); + break; + + // add circumflex (caret) accent + case "C-^": + checkAndApplyCaret(cbInd, cwInd, cPos); + break; - // copy - case "C-c": - case "C-C": - copy(); - break; - - // cut - case "C-x": - case "C-X": - cut(); - break; - - // paste - case "C-v": - case "C-V": - paste(); - break; + // move cursor right + case "right": + case "C-right": + if (unselectRight()) return; + case "RIGHT": + case "C-RIGHT": + if (vexi.ui.key.control) { + // control key held down - shift to end of next word + if (cWord and cWord.text.length>cPos) { + // force skipping to end of cWord if cursor is mid-word + cwInd--; + } + OUT:while (thisbox[cbInd]) { + while (thisbox[cbInd][++cwInd]) { + if (1>=thisbox[cbInd][cwInd].chartype) { + continue; + } + break OUT; + } + cbInd++; + cwInd = thisbox.numchildren>cbInd ? -1 : thisbox[cbInd-1].numchildren-1; + } + aBlock = thisbox.numchildren>cbInd ? thisbox[cbInd] : thisbox[thisbox.numchildren-1]; + if (aBlock.numchildren-1 > cwInd) { + aWord = aBlock[cwInd+1]; + aPos = 0; + } else { + aWord = aBlock[cwInd]; + aPos = aWord.text.length; + } - // add circumflex (caret) accent - case "C-^": - checkAndApplyCaret(cbInd, cwInd, cPos); - break; + } else { + // normal case + aBlock = cBlock; + aWord = cWord; + aPos = cPos; - // move cursor right - case "right": - case "C-right": - if (unselectRight()) return; - case "RIGHT": - case "C-RIGHT": - if (vexi.ui.key.control) { - // control key held down - shift to end of next word - if (cWord and cWord.text.length>cPos) { - // force skipping to end of cWord if cursor is mid-word - cwInd--; - } - OUT:while (thisbox[cbInd]) { - while (thisbox[cbInd][++cwInd]) { - if (1>=thisbox[cbInd][cwInd].chartype) { - continue; - } - break OUT; + if (aWord and ++aPos >= aWord.text.length) { + // shift cursor forwards and check whether the position is legal + if (aWord.text.length >= aPos) { + if (cwInd != aBlock.numchildren-1) { + aPos = 0; + aWord = aBlock[cwInd+1]; } - cbInd++; - cwInd = thisbox.numchildren>cbInd ? -1 : thisbox[cbInd-1].numchildren-1; + } else if (thisbox.numchildren-1 > cbInd) { + aWord = null; + } else { + aPos--; } - aBlock = thisbox.numchildren>cbInd ? thisbox[cbInd] : thisbox[thisbox.numchildren-1]; - if (aBlock.numchildren-1 > cwInd) { - aWord = aBlock[cwInd+1]; + } + + if (!aWord) { + // find the next available legal position + if (thisbox.indexof(aBlock) != thisbox.numchildren-1) { + aBlock = thisbox[thisbox.indexof(aBlock)+1]; aPos = 0; + aWord = aBlock.numchildren ? aBlock[0] : null; } else { - aWord = aBlock[cwInd]; - aPos = aWord.text.length; + return; } + } + } + // invoke selection or set cursor position + if (vexi.ui.key.shift) { + selectWords(); + } else { + cBlock = aBlock; + cWord = aWord; + cPos = aPos; + } + break; + + // move cursor left + case "left": + case "C-left": + if (unselectLeft()) { + return; + } + case "LEFT": + case "C-LEFT": + if (vexi.ui.key.control) { + // control key held down - shift to start of previous word + if (cWord and cPos>0) { + // force skipping to start of cWord if cursor is mid-word + cwInd++; + } + OUT:while (thisbox[cbInd]) { + while (thisbox[cbInd][--cwInd]) { + if (1>=thisbox[cbInd][cwInd].chartype) { + continue; + } + break OUT; + } + cbInd--; + cwInd = (cbInd>=0) ? thisbox[cbInd].numchildren : 0; + } + if (0>cbInd) { + // already at start of text + return; + } + aBlock = thisbox[cbInd]; + aWord = aBlock[cwInd]; + aPos = 0; + } else { + aBlock = cBlock; + aWord = cWord; + aPos = cPos; - } else { - // normal case - aBlock = cBlock; - aWord = cWord; - aPos = cPos; - - if (aWord and ++aPos >= aWord.text.length) { - // shift cursor forwards and check whether the position is legal - if (aWord.text.length >= aPos) { - if (cwInd != aBlock.numchildren-1) { - aPos = 0; - aWord = aBlock[cwInd+1]; - } - } else if (thisbox.numchildren-1 > cbInd) { - aWord = null; + if (0 > --aPos) { + // shift the cursor backwards and check whether the position is legal + if (!aWord or cwInd == 0) { + // nowhere to go with current block, try next block + if (cbInd > 0) { + aBlock = thisbox[cbInd-1]; + aWord = aBlock.numchildren ? aBlock[aBlock.numchildren-1] : null; + aPos = aWord ? aWord.text.length : 0; } else { - aPos--; + return; } - } - if (!aWord) { - // find the next available legal position - if (thisbox.indexof(aBlock) != thisbox.numchildren-1) { - aBlock = thisbox[thisbox.indexof(aBlock)+1]; - aPos = 0; - aWord = aBlock.numchildren ? aBlock[0] : null; + } else if (aWord) { + // get prior word + if (cwInd>0) { + aWord = aBlock[cwInd-1]; + aPos = aWord.text.length-1; + } else if (cbInd>0) { + aBlock = thisbox[cbInd-1]; + aWord = aBlock.numchildren ? aBlock[aBlock.numchildren-1] : null; + aPos = aWord ? aWord.text.length : 0; } else { return; } } } - // invoke selection or set cursor position - if (vexi.ui.key.shift) { - selectWords(); - } else { - cBlock = aBlock; - cWord = aWord; - cPos = aPos; - } - break; - - // move cursor left - case "left": - case "C-left": - if (unselectLeft()) { - return; - } - case "LEFT": - case "C-LEFT": + } + // invoke selection or set cursor position + if (vexi.ui.key.shift) { + selectWords(); + } else { + cBlock = aBlock; + cWord = aWord; + cPos = aPos; + } + break; + + // move cursor up + case "up": + case "C-up": + if (unselectLeft()) { + return; + } + case "UP": + case "C-UP": + if (multiline) { if (vexi.ui.key.control) { - // control key held down - shift to start of previous word - if (cWord and cPos>0) { - // force skipping to start of cWord if cursor is mid-word - cwInd++; - } - OUT:while (thisbox[cbInd]) { - while (thisbox[cbInd][--cwInd]) { - if (1>=thisbox[cbInd][cwInd].chartype) { - continue; - } - break OUT; - } + // control key held down - shift to start of previous block + if (!cWord or (cwInd == 0 and cPos == 0)) { cbInd--; - cwInd = (cbInd>=0) ? thisbox[cbInd].numchildren : 0; } - if (0>cbInd) { - // already at start of text - return; + if (0 > cbInd) { + cbInd = 0; } aBlock = thisbox[cbInd]; - aWord = aBlock[cwInd]; + aWord = aBlock[0]; aPos = 0; - } else { + + } else if (cWord and cBlock.multiline and cWord.y > 0) { + // search for next line within cBlock + var i = cwInd-1; + // pass through words on the same line + while (i>0 and cBlock[i].y == cWord.y) { + i--; + } + var ly = cBlock[i].y; + // pass through words on the previous line until we reach the word in question or the start of the line + while (i>0 and cBlock[i].y == ly and cBlock[i].x > cOffset) { + i--; + } + if (cBlock[i].y != ly) { + i++; + } aBlock = cBlock; - aWord = cWord; - aPos = cPos; + aWord = cBlock[i]; + aPos = (cOffset > aWord.x+aWord.width) ? aWord.text.length : static.getIndInWord(aWord, cOffset-aWord.x); + + } else if (cbInd > 0) { + // next line upwards is in previous block + if (thisbox[cbInd-1].numchildren) { + var nblock = thisbox[cbInd-1]; + var i = nblock.numchildren-1; + var ly = nblock[i].y; + while (i>0 and nblock[i-1].y == ly and nblock[i].x > cOffset) { + i--; + } + aBlock = nblock; + aWord = i>=0 ? nblock[i] : nblock[0]; + aPos = cOffset ? static.getIndInWord(aWord, cOffset-aWord.x) : 0; - if (0 > --aPos) { - // shift the cursor backwards and check whether the position is legal - if (!aWord or cwInd == 0) { - // nowhere to go with current block, try next block - if (cbInd > 0) { - aBlock = thisbox[cbInd-1]; - aWord = aBlock.numchildren ? aBlock[aBlock.numchildren-1] : null; - aPos = aWord ? aWord.text.length : 0; - } else { - return; - } - - } else if (aWord) { - // get prior word - if (cwInd>0) { - aWord = aBlock[cwInd-1]; - aPos = aWord.text.length-1; - } else if (cbInd>0) { - aBlock = thisbox[cbInd-1]; - aWord = aBlock.numchildren ? aBlock[aBlock.numchildren-1] : null; - aPos = aWord ? aWord.text.length : 0; - } else { - return; - } - } + } else { + // no words in next block + aBlock = thisbox[cbInd-1]; + aWord = null; + aPos = 0; } } // invoke selection or set cursor position @@ -1194,182 +1277,76 @@ cWord = aWord; cPos = aPos; } - break; + } + // invoke syncCursor directly + syncCursor(); + return true; + + // move cursor down + case "down": + case "C-down": + if (unselectRight()) { + return; + } + case "DOWN": + case "C-DOWN": + if (multiline) { + if (vexi.ui.key.control) { + // control key held down - shift to end of next block + if (!cWord or (cBlock.numchildren-1 == cwInd and (cWord?cWord.text.length:0) == cPos)) { + cbInd++; + } + if (cbInd >= thisbox.numchildren) { + cbInd = thisbox.numchildren-1; + } + aBlock = thisbox[cbInd]; + aWord = aBlock[aBlock.numchildren-1]; + aPos = aWord?aWord.text.length:0; - // move cursor up - case "up": - case "C-up": - if (unselectLeft()) { - return; - } - case "UP": - case "C-UP": - if (multiline) { - if (vexi.ui.key.control) { - // control key held down - shift to start of previous block - if (!cWord or (cwInd == 0 and cPos == 0)) { - cbInd--; - } - if (0 > cbInd) { - cbInd = 0; - } - aBlock = thisbox[cbInd]; - aWord = aBlock[0]; + } else if (cWord and cBlock.multiline and cBlock.height > cWord.y+cWord.height) { + // search for next line within cBlock + var i = cwInd; + // pass through words on the same line + while (cBlock[i+1] and cBlock[i].y == cWord.y) { + i++; + } + var ly = cBlock[i].y; + // pass through words on the next line until we reach the word in question or the end of the line + while (cBlock[i+1] and cBlock[i].y == ly and cOffset > cBlock[i].x+cBlock[i].width) { + i++; + } + aBlock = cBlock; + aWord = cBlock[i]; + aPos = (cOffset > aWord.x+aWord.width) ? aWord.text.length : static.getIndInWord(aWord, cOffset-aWord.x); + if (cPos == aWord.text.length and aBlock.indexof(aWord) != aBlock.numchildren-1) { + // increment cWord/cPos + aWord = aBlock[aBlock.indexof(aWord)+1]; aPos = 0; - - } else if (cWord and cBlock.multiline and cWord.y > 0) { - // search for next line within cBlock - var i = cwInd-1; - // pass through words on the same line - while (i>0 and cBlock[i].y == cWord.y) { - i--; - } - var ly = cBlock[i].y; - // pass through words on the previous line until we reach the word in question or the start of the line - while (i>0 and cBlock[i].y == ly and cBlock[i].x > cOffset) { - i--; - } - if (cBlock[i].y != ly) { - i++; - } - aBlock = cBlock; - aWord = cBlock[i]; - aPos = (cOffset > aWord.x+aWord.width) ? aWord.text.length : static.getIndInWord(aWord, cOffset-aWord.x); - - } else if (cbInd > 0) { - // next line upwards is in previous block - if (thisbox[cbInd-1].numchildren) { - var nblock = thisbox[cbInd-1]; - var i = nblock.numchildren-1; - var ly = nblock[i].y; - while (i>0 and nblock[i-1].y == ly and nblock[i].x > cOffset) { - i--; - } + } + + } else if (thisbox.numchildren-1 > cbInd) { + // next line is in next block + if (thisbox[cbInd+1].numchildren) { + var nblock = thisbox[cbInd+1]; + var i = 0; + while (nblock[i] and nblock[i].y == 0 and (cOffset > nblock[i].x+nblock[i].width)) i++; + if (!nblock[i] or (cOffset > nblock[i].x+nblock[i].width)) { aBlock = nblock; - aWord = i>=0 ? nblock[i] : nblock[0]; - aPos = cOffset ? static.getIndInWord(aWord, cOffset-aWord.x) : 0; - + aWord = aBlock[aBlock.numchildren-1]; + aPos = aWord.text.length; } else { - // no words in next block - aBlock = thisbox[cbInd-1]; - aWord = null; - aPos = 0; + aBlock = nblock; + aWord = nblock[i]; + aPos = static.getIndInWord(aWord, cOffset-aWord.x); } - } - // invoke selection or set cursor position - if (vexi.ui.key.shift) { - selectWords(); - } else { - cBlock = aBlock; - cWord = aWord; - cPos = aPos; - } - } - // invoke syncCursor directly - syncCursor(); - return true; - - // move cursor down - case "down": - case "C-down": - if (unselectRight()) { - return; - } - case "DOWN": - case "C-DOWN": - if (multiline) { - if (vexi.ui.key.control) { - // control key held down - shift to end of next block - if (!cWord or (cBlock.numchildren-1 == cwInd and (cWord?cWord.text.length:0) == cPos)) { - cbInd++; - } - if (cbInd >= thisbox.numchildren) { - cbInd = thisbox.numchildren-1; - } - aBlock = thisbox[cbInd]; - aWord = aBlock[aBlock.numchildren-1]; - aPos = aWord?aWord.text.length:0; - } else if (cWord and cBlock.multiline and cBlock.height > cWord.y+cWord.height) { - // search for next line within cBlock - var i = cwInd; - // pass through words on the same line - while (cBlock[i+1] and cBlock[i].y == cWord.y) { - i++; - } - var ly = cBlock[i].y; - // pass through words on the next line until we reach the word in question or the end of the line - while (cBlock[i+1] and cBlock[i].y == ly and cOffset > cBlock[i].x+cBlock[i].width) { - i++; - } - aBlock = cBlock; - aWord = cBlock[i]; - aPos = (cOffset > aWord.x+aWord.width) ? aWord.text.length : static.getIndInWord(aWord, cOffset-aWord.x); - if (cPos == aWord.text.length and aBlock.indexof(aWord) != aBlock.numchildren-1) { - // increment cWord/cPos - aWord = aBlock[aBlock.indexof(aWord)+1]; - aPos = 0; - } - - } else if (thisbox.numchildren-1 > cbInd) { - // next line is in next block - if (thisbox[cbInd+1].numchildren) { - var nblock = thisbox[cbInd+1]; - var i = 0; - while (nblock[i] and nblock[i].y == 0 and (cOffset > nblock[i].x+nblock[i].width)) i++; - if (!nblock[i] or (cOffset > nblock[i].x+nblock[i].width)) { - aBlock = nblock; - aWord = aBlock[aBlock.numchildren-1]; - aPos = aWord.text.length; - } else { - aBlock = nblock; - aWord = nblock[i]; - aPos = static.getIndInWord(aWord, cOffset-aWord.x); - } - - } else { - // no words in next block - aBlock = thisbox[cbInd+1]; - aWord = null; - aPos = 0; - } - } - // invoke selection or set cursor position - if (vexi.ui.key.shift) { - selectWords(); } else { - cBlock = aBlock; - cWord = aWord; - cPos = aPos; + // no words in next block + aBlock = thisbox[cbInd+1]; + aWord = null; + aPos = 0; } } - // invoke syncCursor directly - syncCursor(); - return true; - - // move cursor to start of line - case "home": - case "HOME": - // special case select mode - if (unselectLeft()) { - return; - } - - if (multiline and cWord and cWord.y != 0) { - var i = cwInd-1; - while (i>0 and cBlock[i] and cBlock[i].y == cWord.y) { - i--; - } - aBlock = cBlock; - aWord = aBlock[i+1]; - aPos = 0; - - } else { - // single line or empty block - aBlock = cBlock; - aWord = aBlock[0]; - aPos = 0; - } // invoke selection or set cursor position if (vexi.ui.key.shift) { selectWords(); @@ -1378,264 +1355,299 @@ cWord = aWord; cPos = aPos; } - break; - - // move cursor to end of line - case "end": - case "END": - // special case select mode - if (unselectRight()) { - return; + } + // invoke syncCursor directly + syncCursor(); + return true; + + // move cursor to start of line + case "home": + case "HOME": + // special case select mode + if (unselectLeft()) { + return; + } + + if (multiline and cWord and cWord.y != 0) { + var i = cwInd-1; + while (i>0 and cBlock[i] and cBlock[i].y == cWord.y) { + i--; } + aBlock = cBlock; + aWord = aBlock[i+1]; + aPos = 0; + + } else { + // single line or empty block + aBlock = cBlock; + aWord = aBlock[0]; + aPos = 0; + } + // invoke selection or set cursor position + if (vexi.ui.key.shift) { + selectWords(); + } else { + cBlock = aBlock; + cWord = aWord; + cPos = aPos; + } + break; + + // move cursor to end of line + case "end": + case "END": + // special case select mode + if (unselectRight()) { + return; + } + + if (multiline and cWord) { + var i = cwInd+1; + while (cBlock[i] and cBlock[i].y == cWord.y) i++; + aBlock = cBlock; + aWord = aBlock[i-1]; + aPos = aWord.text.length; + + } else { + // single line or empty block + aBlock = cBlock; + aWord = aBlock.numchildren ? aBlock[cBlock.numchildren-1] : null; + aPos = aWord ? aWord.text.length : 0; + } + // invoke selection or set cursor position + if (vexi.ui.key.shift) { + selectWords(); + } else { + cBlock = aBlock; + cWord = aWord; + cPos = aPos; + } + break; + + case "enter": + case "ENTER": + // special case select mode + if (select) { + deleteSelectedText(); + } + + if (multiline) { + // multiline edits add blocks at cursor point - if (multiline and cWord) { - var i = cwInd+1; - while (cBlock[i] and cBlock[i].y == cWord.y) i++; - aBlock = cBlock; - aWord = aBlock[i-1]; - aPos = aWord.text.length; + // create new block + var nblock = .block(vexi.box, blockargs); + if (nblock.font != cBlock.font) + nblock.font = cBlock.font; + if (nblock.fontsize != cBlock.fontsize) + nblock.fontsize = cBlock.fontsize; + if (nblock.textcolor != cBlock.textcolor) + nblock.textcolor = cBlock.textcolor; - } else { - // single line or empty block - aBlock = cBlock; - aWord = aBlock.numchildren ? aBlock[cBlock.numchildren-1] : null; - aPos = aWord ? aWord.text.length : 0; + if (cWord) { + // in empty block if cWord is null + + // move trailing words + while (cBlock.numchildren > cwInd+1) { + nblock[0] = cBlock[cBlock.numchildren-1]; + } + if (cPos == 0) { + // move cWord + nblock[0] = cWord; + + } else if (cPos != cWord.text.length) { + // split cWord + nblock[0] = .word(vexi.box, nblock.wordargs); + nblock[0].text = cWord.text.substring(cPos); + nblock[0].chartype = cWord.chartype; + cWord.text = cWord.text.substring(0, cPos); + } } - // invoke selection or set cursor position - if (vexi.ui.key.shift) { - selectWords(); - } else { - cBlock = aBlock; - cWord = aWord; - cPos = aPos; - } - break; + thisbox[cbInd+1] = nblock; + cBlock.reflowbox = true; + // cBlock.reflow called at the end of KeyPressed + // so no need to reflow nblock(cBlock) manually + cBlock = nblock; + cWord = cBlock.numchildren ? cBlock[0] : null; + cPos = 0; + } + break; + + // switch insert mode on/off + case "insert": + case "INSERT": + insert = !insert; + break; + + // delete - deletes forwards + case "delete": + case "DELETE": + case "C-delete": + case "C-DELETE": + // special case select mode + if (select) { + deleteSelectedText(); + } else if (cWord) { + // normal operation - case "enter": - case "ENTER": - // special case select mode - if (select) { - deleteSelectedText(); - } - - if (multiline) { - // multiline edits add blocks at cursor point - - // create new block - var nblock = .block(vexi.box, blockargs); - if (nblock.font != cBlock.font) - nblock.font = cBlock.font; - if (nblock.fontsize != cBlock.fontsize) - nblock.fontsize = cBlock.fontsize; - if (nblock.textcolor != cBlock.textcolor) - nblock.textcolor = cBlock.textcolor; - - if (cWord) { - // in empty block if cWord is null + if (cPos == cWord.text.length) { + // at the end of a block + if (thisbox.numchildren-1 > cbInd) { + // increment cbInd as we're interested in the next block + cbInd++; - // move trailing words - while (cBlock.numchildren > cwInd+1) { - nblock[0] = cBlock[cBlock.numchildren-1]; - } - if (cPos == 0) { - // move cWord - nblock[0] = cWord; + // combine blocks by taking words from thisbox[cbInd] + if (cBlock.numchildren > thisbox[cbInd].numchildren) { + while (thisbox[cbInd].numchildren) { + cBlock.add(thisbox[cbInd][0]); + } + thisbox[cbInd].thisbox = null; - } else if (cPos != cWord.text.length) { - // split cWord - nblock[0] = .word(vexi.box, nblock.wordargs); - nblock[0].text = cWord.text.substring(cPos); - nblock[0].chartype = cWord.chartype; - cWord.text = cWord.text.substring(0, cPos); + } else { + // combine blocks by taking words from cBlock + while (cBlock.numchildren) { + thisbox[cbInd][0] = cBlock[cBlock.numchildren-1]; + } + cBlock.thisbox = null; + cBlock = thisbox[cbInd-1]; // -1 as cBlock was just deleted + cwInd = cBlock.indexof(cWord); } + if (cBlock[cwInd+1] and cWord.chartype == cBlock[cwInd+1].chartype) { + // combine same-type words if together + cWord.text += cBlock[cwInd+1].text; + cBlock[cwInd+1] = null; + } } - thisbox[cbInd+1] = nblock; - cBlock.reflowbox = true; - // cBlock.reflow called at the end of KeyPressed - // so no need to reflow nblock(cBlock) manually - cBlock = nblock; - cWord = cBlock.numchildren ? cBlock[0] : null; - cPos = 0; + + } else if (cWord.text.length == 1) { + // one letter left in word + cBlock[cwInd] = null; + if (cBlock.numchildren) { + if (cBlock.numchildren == cwInd) { + cWord = cBlock[cwInd-1]; + cPos = cWord.text.length; + } else { + cWord = cBlock[cwInd]; + cPos = 0; + } + } else { + cWord = null; + cPos = 0; + } + + } else { + // word is larger than one letter + cWord.text = cWord.text.slice(0, cPos) + cWord.text.slice(cPos+1); + if (cPos == cWord.text.length and cBlock.numchildren-1 > cwInd) { + cPos = 0; + cWord = cBlock[cwInd+1]; + } } - break; + + } else if (thisbox.numchildren-1 > cbInd) { + // no word in this block, try and remove it + cBlock.thisbox = null; + cBlock = thisbox[cbInd]; + cPos = 0; + cWord = cBlock.numchildren ? cBlock[0] : null; + } + break; + + // backspace - deletes backwards + case "back_space": + case "BACK_SPACE": + case "C-back_space": + case "C-BACK_SPACE": + // special case select mode + if (select) { + deleteSelectedText(); + } + else if (cWord) { + // normal operation - // switch insert mode on/off - case "insert": - case "INSERT": - insert = !insert; - break; - - // delete - deletes forwards - case "delete": - case "DELETE": - case "C-delete": - case "C-DELETE": - // special case select mode - if (select) { - deleteSelectedText(); - } else if (cWord) { - // normal operation - - if (cPos == cWord.text.length) { - // at the end of a block - if (thisbox.numchildren-1 > cbInd) { - // increment cbInd as we're interested in the next block - cbInd++; + if (cPos == 0) { + // at the start of a word + if (cwInd == 0) { + // at the start of a block + if (cbInd != 0) { + // decrement cbInd as we're interested in the prior block + --cbInd; - // combine blocks by taking words from thisbox[cbInd] if (cBlock.numchildren > thisbox[cbInd].numchildren) { + // combine blocks by taking words from thisbox[cbInd] while (thisbox[cbInd].numchildren) { - cBlock.add(thisbox[cbInd][0]); + cBlock[0] = thisbox[cbInd][thisbox[cbInd].numchildren-1]; } thisbox[cbInd].thisbox = null; } else { // combine blocks by taking words from cBlock while (cBlock.numchildren) { - thisbox[cbInd][0] = cBlock[cBlock.numchildren-1]; + thisbox[cbInd][thisbox[cbInd].numchildren] = cBlock[0]; } cBlock.thisbox = null; - cBlock = thisbox[cbInd-1]; // -1 as cBlock was just deleted - cwInd = cBlock.indexof(cWord); + cBlock = thisbox[cbInd]; } - if (cBlock[cwInd+1] and cWord.chartype == cBlock[cwInd+1].chartype) { - // combine same-type words if together - cWord.text += cBlock[cwInd+1].text; - cBlock[cwInd+1] = null; + + // combine same-type words if together + cwInd = cBlock.indexof(cWord); + if (cwInd != 0 and cWord.chartype == cBlock[cwInd-1].chartype) { + cPos = cBlock[cwInd-1].text.length; + cWord.text = cBlock[cwInd-1].text + cWord.text; + cBlock[cwInd-1].thisbox = null; } } - } else if (cWord.text.length == 1) { - // one letter left in word - cBlock[cwInd] = null; - if (cBlock.numchildren) { - if (cBlock.numchildren == cwInd) { - cWord = cBlock[cwInd-1]; - cPos = cWord.text.length; - } else { - cWord = cBlock[cwInd]; - cPos = 0; + } else { + // delete from previous word + var w = cBlock[cwInd-1]; + if (w.text.length == 1) { + cBlock[cwInd-1] = null; + } else { + w.text = w.text.substring(0, w.text.length-1); + if (w.chartype == cWord.chartype) { + cPos = w.text.length; + w.text += cWord.text; + cBlock[cwInd] = null; + cWord = w; } - } else { - cWord = null; - cPos = 0; } - - } else { - // word is larger than one letter - cWord.text = cWord.text.slice(0, cPos) + cWord.text.slice(cPos+1); - if (cPos == cWord.text.length and cBlock.numchildren-1 > cwInd) { - cPos = 0; - cWord = cBlock[cwInd+1]; - } } - } else if (thisbox.numchildren-1 > cbInd) { - // no word in this block, try and remove it - cBlock.thisbox = null; - cBlock = thisbox[cbInd]; - cPos = 0; - cWord = cBlock.numchildren ? cBlock[0] : null; - } - break; - - // backspace - deletes backwards - case "back_space": - case "BACK_SPACE": - case "C-back_space": - case "C-BACK_SPACE": - // special case select mode - if (select) { - deleteSelectedText(); - } - else if (cWord) { - // normal operation + } else if (cWord.text.length == 1) { + // delete the word altogether + cWord.thisbox = null; - if (cPos == 0) { - // at the start of a word - if (cwInd == 0) { - // at the start of a block - if (cbInd != 0) { - // decrement cbInd as we're interested in the prior block - --cbInd; - - if (cBlock.numchildren > thisbox[cbInd].numchildren) { - // combine blocks by taking words from thisbox[cbInd] - while (thisbox[cbInd].numchildren) { - cBlock[0] = thisbox[cbInd][thisbox[cbInd].numchildren-1]; - } - thisbox[cbInd].thisbox = null; - - } else { - // combine blocks by taking words from cBlock - while (cBlock.numchildren) { - thisbox[cbInd][thisbox[cbInd].numchildren] = cBlock[0]; - } - cBlock.thisbox = null; - cBlock = thisbox[cbInd]; - } - - // combine same-type words if together - cwInd = cBlock.indexof(cWord); - if (cwInd != 0 and cWord.chartype == cBlock[cwInd-1].chartype) { - cPos = cBlock[cwInd-1].text.length; - cWord.text = cBlock[cwInd-1].text + cWord.text; - cBlock[cwInd-1].thisbox = null; - } - } - - } else { - // delete from previous word - var w = cBlock[cwInd-1]; - if (w.text.length == 1) { - cBlock[cwInd-1] = null; - } else { - w.text = w.text.substring(0, w.text.length-1); - if (w.chartype == cWord.chartype) { - cPos = w.text.length; - w.text += cWord.text; - cBlock[cwInd] = null; - cWord = w; - } - } - } + if (cwInd == 0) { + // at the start of a block + cWord = cBlock.numchildren ? cBlock[0] : null; + cPos = 0; - } else if (cWord.text.length == 1) { - // delete the word altogether - cWord.thisbox = null; - - if (cwInd == 0) { - // at the start of a block - cWord = cBlock.numchildren ? cBlock[0] : null; - cPos = 0; - - } else if (cwInd == cBlock.numchildren) { - // at the end of a block - cWord = cBlock[cwInd-1]; - cPos = cWord.text.length; - - } else { - // mid-block - cWord = cBlock[cwInd]; - cPos = 0; - } + } else if (cwInd == cBlock.numchildren) { + // at the end of a block + cWord = cBlock[cwInd-1]; + cPos = cWord.text.length; + } else { - // delete from within the word - cWord.text = cWord.text.slice(0, cPos-1) + cWord.text.slice(cPos); - cPos--; + // mid-block + cWord = cBlock[cwInd]; + cPos = 0; } - } else { - // no word in this block, try to delete the block - if (cbInd > 0) { - cBlock.thisbox = null; - cBlock = thisbox[cbInd-1]; - cWord = cBlock.numchildren ? cBlock[cBlock.numchildren-1] : null; - cPos = cWord ? cWord.text.length : 0; - } + // delete from within the word + cWord.text = cWord.text.slice(0, cPos-1) + cWord.text.slice(cPos); + cPos--; } - break; + + } else { + // no word in this block, try to delete the block + if (cbInd > 0) { + cBlock.thisbox = null; + cBlock = thisbox[cbInd-1]; + cWord = cBlock.numchildren ? cBlock[cBlock.numchildren-1] : null; + cPos = cWord ? cWord.text.length : 0; + } } + break; } cBlock.reflowbox = true; Modified: branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/text/field.t =================================================================== --- branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/text/field.t 2016-07-15 01:16:46 UTC (rev 4873) +++ branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/text/field.t 2016-07-16 00:05:55 UTC (rev 4874) @@ -25,10 +25,11 @@ visible ++= static.visibleWrite; th_view ++= static.viewWrite; KeyPressed ++= static.keypressWrite; + KeyTyped ++= static.keytypedWrite; </ui:box> - static.keypressWrite = function(v) { + static.keytypedWrite = function(v){ var edit = trapee.v_edit; if (!edit.select and v.length == 1 and trapee.maxlength > 0 and edit.text.length >= trapee.maxlength) { // limit amount of text @@ -43,12 +44,9 @@ } } - if (v == "enter" || v == "ENTER") { - // fire action - trapee.action = true; - } else if (v.length>1) { + if (v.length>1) { // pass to edit - edit.KeyPressed = v; + edit.KeyTyped = v; } else { // alpha numeric -- 48-57 (0-9), 65-90 (A-Z), 97-122 (a-z) var c = v.charCodeAt(0); @@ -56,26 +54,36 @@ case "alpha": if ((c>=97 and 122>=c) or (c>=65 and 90>=c)) { // pass to edit - edit.KeyPressed = v; + edit.KeyTyped = v; } break; case "alphanumeric": if ((c>=97 and 122>=c) or (c>=65 and 90>=c) or (c>=48 and 57>=c)) { // pass to edit - edit.KeyPressed = v; + edit.KeyTyped = v; } break; case "numeric": if (c>=48 and 57>=c) { // pass to edit - edit.KeyPressed = v; + edit.KeyTyped = v; } break; default: // pass to edit - edit.KeyPressed = v; + edit.KeyTyped = v; } } + }; + + static.keypressWrite = function(v) { + if (v == "enter" || v == "ENTER") { + // fire action + trapee.action = true; + } else if (v.length>1) { + // pass to edit + trapee.v_edit.KeyPressed = v; + } } /** retrieve a integer offset of where the cursor is within the textfield */ Modified: branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/shadowtext.t =================================================================== --- branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/shadowtext.t 2016-07-15 01:16:46 UTC (rev 4873) +++ branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/shadowtext.t 2016-07-16 00:05:55 UTC (rev 4874) @@ -14,6 +14,7 @@ thisbox.th_shadowtext; thisbox.th_shadowwrap; + thisbox.KeyTyped ++= static.keypressWrite; thisbox.KeyPressed ++= static.keypressWrite; thisbox.shadowtext ++= static.shadowtextWrite; thisbox.v_container ++= static.containerWrite; Modified: branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/textarea.t =================================================================== --- branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/textarea.t 2016-07-15 01:16:46 UTC (rev 4873) +++ branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/textarea.t 2016-07-16 00:05:55 UTC (rev 4874) @@ -11,7 +11,8 @@ thisbox.liveValuePut = true; thisbox.th_scroll; - thisbox.KeyPressed ++= static.keypressWrite; + thisbox.KeyTyped ++= static.keyeventWrite; + thisbox.KeyPressed ++= static.keyeventWrite; thisbox.enabled ++= static.enableWrite; thisbox.focused ++= static.focusWrite; thisbox.value ++= static.valueRead; @@ -34,9 +35,9 @@ static.enableWrite = function(v) { cascade = v; trapee.v_edit.enabled = trapee.enabled; } /** passon keypress to editbox */ - static.keypressWrite = function(v) { + static.keyeventWrite = function(v) { cascade = v; - trapee.v_edit.KeyPressed = v; + trapee.v_edit[trapname] = v; if (trapee.liveValuePut) { trapee.v_valueput = true; trapee.value = trapee.value; Modified: branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/textfield.t =================================================================== --- branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/textfield.t 2016-07-15 01:16:46 UTC (rev 4873) +++ branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/textfield.t 2016-07-16 00:05:55 UTC (rev 4874) @@ -16,6 +16,7 @@ thisbox.value = ""; thisbox.v_valueput = false; + KeyTyped ++= static.keytypedEvent; KeyPressed ++= static.keypressEvent; password ++= static.passwordWrite; value ++= static.valueRead; @@ -36,6 +37,51 @@ trapee.v_field.value = v; } + static.keytypedEvent = function(v){ + var edit = trapee.v_edit; + if (trapee.password) { + // deal with input for password fields + var do_del = true; + var cPos = edit.getCPos(); + var sPos = edit.getSPos(); + var val = trapee.value; + + if (edit.select) { + // delete text matching selected text + if (cPos > sPos) { + val = val.substring(0, sPos) + val.substring(cPos, val.length); + } else { + val = val==null?"":val.substring(0, cPos) + val.substring(sPos, val.length); + } + do_del = false; + } + + val = + val==null or val=="" + ? v + : val.substring(0, cPos) + v + val.substring(cPos, val.length); + v = '*'; + + // must be done after as not to inadvertently modify cPos + edit.KeyTyped = v; + trapee.v_valueput = true; + trapee.value = val; + + } else { + if (trapee.forcecase) { + if (trapee.forcecase == "upper") { + v = v.toUpperCase(); + } else if (trapee.forcecase == "lower") { + v = v.toLowerCase(); + } + } + // normal textfield input + cascade = v; + trapee.text = trapee.text; + } + + }; + /** fire action or filter key in case of password fields */ static.keypressEvent = function(v) { var edit = trapee.v_edit; @@ -69,7 +115,7 @@ else return; } - if (edit.select and ((v.length == 1) or + if (edit.select and ( (v.toLowerCase() == "delete") or (v.toLowerCase() == "back_space"))) { // delete text matching selected text if (cPos > sPos) { @@ -80,14 +126,6 @@ do_del = false; } - if (v.length == 1) { - // insert single character - val = - val==null or val=="" - ? v - : val.substring(0, cPos) + v + val.substring(cPos, val.length); - v = '*'; - } else if (v == "back_space") { // delete character before cPos if (do_del and (cPos > 0)) { @@ -115,21 +153,6 @@ trapee.value = val; } else { - if (v.length==1 and trapee.forcecase) { - var c = v.charCodeAt(0); - if (trapee.forcecase.indexOf("upper")==0) { - // 97-122 (a-z) - if (122>=c and c>=97) { - v = vexi.string.fromCharCode(c-32); - } - } else - if (trapee.forcecase.indexOf("lower")) { - // 65-90 (A-Z) - if (90>=c and c>=65) { - v = vexi.string.fromCharCode(c+32); - } - } - } // normal textfield input cascade = v; trapee.text = trapee.text; Modified: branches/vexi3/org.vexi-vexi.widgets/src_poke/poke/widgets/textfield.t =================================================================== --- branches/vexi3/org.vexi-vexi.widgets/src_poke/poke/widgets/textfield.t 2016-07-15 01:16:46 UTC (rev 4873) +++ branches/vexi3/org.vexi-vexi.widgets/src_poke/poke/widgets/textfield.t 2016-07-16 00:05:55 UTC (rev 4874) @@ -1,17 +1,29 @@ <!-- public domain --> -<vexi xmlns:ui="vexi://ui" xmlns:w="vexi.widget" xmlns:poke="poke"> +<vexi xmlns:ui="vexi://ui" xmlns:w="vexi.widget" xmlns:poke="poke" xmlns:lay="vexi.layout"> <w:surface /> <ui:box fill="white" orient="vertical"> + <lay:grid cols="2" maxwidth="350"> + <ui:Box text="Field" shrink="true"/> + <w:textfield id="field" shadowtext="normal text"/> + <ui:Box text="Password" shrink="true"/> + <ui:Box> + <w:textfield id="password" password="true" shadowtext="password"/> + <ui:Box id="reveal"/> + </ui:Box> + <ui:Box text="Area" shrink="true"/> + <w:textarea /> + + </lay:grid> <ui:box> - <ui:Box /> - <w:textfield id="field" fill="yellow" /> - <ui:Box /> - </ui:box> - <ui:box> <w:link id="enable" text="Enable" /> </ui:box> + + $password.value ++= function(v){ + cascade = v; + $reveal.text = v; + }; $enable.action ++= function(v) { $field.enabled = !$field.enabled; } vexi.ui.frame = thisbox; Modified: trunk/org.vexi-build.shared/meta/module.revisions =================================================================== --- trunk/org.vexi-build.shared/meta/module.revisions 2016-07-15 01:16:46 UTC (rev 4873) +++ trunk/org.vexi-build.shared/meta/module.revisions 2016-07-16 00:05:55 UTC (rev 4874) @@ -1 +1 @@ -{"https:\/\/ebuild-project.org\/svn\/ebuild\/plugins":"180","https:\/\/emanate-project.org\/svn\/eapi":"223"} \ No newline at end of file +{"https:\/\/ebuild-project.org\/svn\/ebuild\/plugins":"209","https:\/\/emanate-project.org\/svn\/eapi":"223"} \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic patterns at an interface-level. Reveals which users, apps, and protocols are consuming the most bandwidth. Provides multi-vendor support for NetFlow, J-Flow, sFlow and other flows. Make informed decisions using capacity planning reports.http://sdm.link/zohodev2dev _______________________________________________ Vexi-svn mailing list Vexi-svn@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/vexi-svn