Revision: 4368
http://vexi.svn.sourceforge.net/vexi/?rev=4368&view=rev
Author: clrg
Date: 2012-03-12 15:59:39 +0000 (Mon, 12 Mar 2012)
Log Message:
-----------
Improved cursor placement handling
Modified Paths:
--------------
trunk/org.vexi-vexi.widgets/src_main/org/vexi/lib/text/edit.t
Modified: trunk/org.vexi-vexi.widgets/src_main/org/vexi/lib/text/edit.t
===================================================================
--- trunk/org.vexi-vexi.widgets/src_main/org/vexi/lib/text/edit.t
2012-03-09 01:18:15 UTC (rev 4367)
+++ trunk/org.vexi-vexi.widgets/src_main/org/vexi/lib/text/edit.t
2012-03-12 15:59:39 UTC (rev 4368)
@@ -655,77 +655,96 @@
// reset need to loop
updateCurPos = false;
- if (aWord and aInWord) {
- // place cursor at mouse position if it's over a word
- var tx = aX-aBlock.distanceto(aWord).x;
- var ci = static.getIndInWord(aWord, tx);
+ if (!aWord or !aInWord) while(true) {
+ // using a while loop so we can "break" out
+ // to avoid a more complex suite of if/else
- if (ci == aWord.text.length and aBlock.numchildren >
aBlock.indexof(aWord)+1) {
- // place cursor after word
- //aBlock = aBlock;
- aPos = 0;
- aWord = aBlock[aBlock.indexof(aWord)+1];
-
- } else {
- // place cursor in word
- //aBlock = aBlock;
- aPos = ci;
- //aWord = aWord;
- }
-
- } else while (true) {
// place cursor as close to the mouse position as possible
var d = thisbox.distanceto(aBlock);
var dY = d.y;
var dX = d.x;
+ // STAGE 1: find the correct block
+
+ var aI = thisbox.indexof(aBlock);
+ if (aI == -1) {
+ // aBlock no longer part of this edit
+ // -> probably an error
+ throw "Invalid edit state";
+
+ } else
+ if (!multiline) {
+ aBlock = thisbox[0];
+ } else
if (dY > aY) {
- // mouse is above aBlock
- var i = thisbox.indexof(aBlock);
- for (i--; i >= 0; i--) {
- aBlock = thisbox[i];
- dY -= aBlock.height;
+ // mouse is above aBlock;
+ // this occurs when the user moves the mouse
+ // outside of the edit but continues to hold
+ // the button down
+ // -> update ablock to correct block for the
+ // height of the mouse
+ var i;
+ for (i = aI; i > 0; i--) {
+ dY -= thisbox[i].height;
if (aY > dY) break;
}
- if (i == -1) {
- aWord = aBlock[0];
- aPos = 0;
- break;
- }
+ aBlock = thisbox[i];
- } else if (aY > dY+aBlock.height) {
+ } else
+ if (aY > dY+aBlock.height) {
// mouse is below aBlock
- var n = thisbox.numchildren;
- dY += aBlock.height;
- var i = thisbox.indexof(aBlock);
- for (i++; n > i; i++) {
- aBlock = thisbox[i];
- dY += aBlock.height;
+ // -> update ablock to correct block for the
+ // height of the mouse
+ var i;
+ for (i = aI; n-1 > i; i++) {
+ dY += thisbox[i].height;
if (dY > aY) break;
}
- if (i == thisbox.numchildren) {
- aWord = aBlock.numchildren ?
aBlock[aBlock.numchildren-1] : null;
- aPos = aWord ? aWord.text.length : 0;
- break;
- }
+ aBlock = thisbox[i];
}
- // else working within the current block
+ // else working within the vertical confines of
+ // the current block; mouse to left or right of word
+ // STAGE 2: find the aligned word
+
if (aBlock.numchildren == 0) {
// empty block
aWord = null;
aPos = 0;
+ break;
} else {
- // block with children
+ // STAGE 2a: find a word on the correct line
+
var ind1 = 0;
var ind2 = aBlock.numchildren-1;
var indm = 0;
+ var lineY;
+ var subY = aY - dY;
+ var w1 = aBlock[ind1];
+ var w2 = aBlock[ind2];
+ var wm;
+
+ if (!aBlock.multiline or w1.y+w1.height >= subY) {
+ // use top line
+ lineY = 0;
+ wm = aBlock[0];
+
+ } else
+ if (aY >= w2.y) {
+ // use bottom line
+ lineY = w2.y;
+ wm = aBlock[aBlock.numchildren-1];
+
+ } else
while (ind2 > ind1) {
+ // locate the line
+
// the middle
indm = vexi.math.floor(ind1+(ind2-ind1)/2);
+ wm = aBlock[indm];
- if (aY > aBlock[indm].y+aBlock[indm].height) {
+ if (aY > wm.y+wm.height) {
// indm is on a line below mouse click
if (ind1 == indm) {
indm = ind2;
@@ -733,7 +752,7 @@
ind1 = indm;
continue;
}
- if (aBlock[indm].y > aY) {
+ if (wm.y > aY) {
// indm is on a line above mouse click
if (ind2 == indm) {
indm = ind1;
@@ -742,28 +761,50 @@
continue;
}
// indm is on the same line that was clicked
+ lineY = wm.y;
break;
}
- if (aX > dX) {
- // to the right of current line, find word at the
end of the line
- var n = aBlock.numchildren;
- while (n > indm+1 and aBlock[indm].y ==
aBlock[indm+1].y) {
- indm++;
- }
- aWord = aBlock[indm];
- aPos = aWord ? aWord.text.length : 0;
- } else {
- // to the left, find word at the start of the line
- while (indm-1 >= 0 and aBlock[indm].y ==
aBlock[indm-1].y) {
- indm--;
- }
- aWord = aBlock[indm];
- aPos = 0;
- }
+ // STAGE 2b: we have the line and a starting point
+ // (word) from which we can find the word that is
+ // closest to the mouse cursor
+
+ // go left
+ for (var i = indm; i>=0 and wm.x > aX-dX; i--)
+ wm = aBlock[i];
+
+ // go right
+ var n = aBlock.numchildren;
+ for (var i = indm; n>i and aX-dX >= wm.x; i++)
+ wm = aBlock[i];
+
+ aWord = wm;
}
break;
}
+
+ if (aWord==null) {
+ aPos = 0;
+ } else {
+ // place cursor at mouse x position
+ // relative to aWord
+ var tx = aX-aBlock.distanceto(aWord).x;
+ var ci = static.getIndInWord(aWord, tx);
+
+ if (ci == aWord.text.length and aBlock.numchildren >
aBlock.indexof(aWord)+1) {
+ // place cursor after word
+ //aBlock = aBlock;
+ aPos = 0;
+ aWord = aBlock[aBlock.indexof(aWord)+1];
+
+ } else {
+ // place cursor in word
+ //aBlock = aBlock;
+ aPos = ci;
+ //aWord = aWord;
+ }
+ }
+
// FEATURE: syncCursor should probably happen post-highlight ?
if (abortTip) {
abortTip = false;
@@ -805,6 +846,7 @@
// clean up; thread no longer in progress
doHighlight = false;
+ frameToThis = null;
tip = false;
}
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Try before you buy = See our experts in action!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-dev2
_______________________________________________
Vexi-svn mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/vexi-svn