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
[email protected]
https://lists.sourceforge.net/lists/listinfo/vexi-svn