mirror of
https://github.com/arduino/Arduino.git
synced 2025-01-17 06:52:18 +01:00
Fixing double- and triple-click selection behavior (Peter Lewis)
Double clicking selects words, double-clicking and dragging does too. Triple-click for lines. http://code.google.com/p/arduino/issues/detail?id=824
This commit is contained in:
parent
b133faa68f
commit
a6eb9ea5eb
@ -834,6 +834,17 @@ public class JEditTextArea extends JComponent
|
||||
return lineElement.getEndOffset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the end offset of the specified line, but not past the end of the text
|
||||
* @param line The line
|
||||
* @return The end offset of the specified line, safe to use for a selection, or -1 if the line is
|
||||
* invalid.
|
||||
*/
|
||||
public int getSafeLineStopOffset(int line)
|
||||
{
|
||||
return Math.min(getLineStopOffset(line),getDocumentLength());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the specified line.
|
||||
* @param line The line
|
||||
@ -1144,7 +1155,7 @@ public class JEditTextArea extends JComponent
|
||||
{
|
||||
throw new IllegalArgumentException("Bounds out of"
|
||||
+ " range: " + newStart + "," +
|
||||
newEnd);
|
||||
newEnd + " [" + getDocumentLength() + "]");
|
||||
}
|
||||
|
||||
// If the new position is the same as the old, we don't
|
||||
@ -1201,6 +1212,86 @@ public class JEditTextArea extends JComponent
|
||||
// getLineOfOffset(end));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isWordCharacter( char ch, String noWordSep )
|
||||
{
|
||||
return Character.isLetterOrDigit(ch) || ch=='_' || noWordSep.indexOf(ch) != -1;
|
||||
}
|
||||
|
||||
protected void setNewSelectionWord( int line, int offset )
|
||||
{
|
||||
if (getLineLength(line) == 0) {
|
||||
newSelectionStart = getLineStartOffset(line);
|
||||
newSelectionEnd = newSelectionStart;
|
||||
return;
|
||||
}
|
||||
|
||||
String noWordSep = (String)document.getProperty("noWordSep");
|
||||
if(noWordSep == null)
|
||||
noWordSep = "";
|
||||
|
||||
String lineText = getLineText(line);
|
||||
|
||||
int wordStart = 0;
|
||||
int wordEnd = lineText.length();
|
||||
|
||||
char ch = lineText.charAt(Math.max(0,offset - 1));
|
||||
|
||||
// special case for whitespace (fry 0122, bug #348)
|
||||
// this is really nasty.. turns out that double-clicking any non-letter
|
||||
// or digit char gets lumped together.. sooo, this quickly gets messy,
|
||||
// because really it needs to check whether the chars are of the same
|
||||
// type.. so a double space or double - might be grouped together,
|
||||
// but what about a +=1? do + and - get grouped but not the 1? blech,
|
||||
// coming back to this later. it's not a difficult fix, just a
|
||||
// time-consuming one to track down all the proper cases.
|
||||
/*
|
||||
if (ch == ' ') {
|
||||
//System.out.println("yeehaa");
|
||||
|
||||
for(int i = offset - 1; i >= 0; i--) {
|
||||
if (lineText.charAt(i) == ' ') {
|
||||
wordStart = i;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(int i = offset; i < lineText.length(); i++) {
|
||||
if (lineText.charAt(i) == ' ') {
|
||||
wordEnd = i + 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
*/
|
||||
|
||||
// If the user clicked on a non-letter char,
|
||||
// we select the surrounding non-letters
|
||||
boolean selectNoLetter = !isWordCharacter(ch,noWordSep);
|
||||
|
||||
for(int i = offset - 1; i >= 0; i--) {
|
||||
ch = lineText.charAt(i);
|
||||
if (selectNoLetter ^ !isWordCharacter(ch,noWordSep)) {
|
||||
wordStart = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = offset; i < lineText.length(); i++) {
|
||||
ch = lineText.charAt(i);
|
||||
if(selectNoLetter ^ !isWordCharacter(ch,noWordSep)) {
|
||||
wordEnd = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//}
|
||||
int lineStart = getLineStartOffset(line);
|
||||
|
||||
newSelectionStart = lineStart + wordStart;
|
||||
newSelectionEnd = lineStart + wordEnd;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@ -1684,6 +1775,14 @@ public class JEditTextArea extends JComponent
|
||||
protected int selectionEnd;
|
||||
protected int selectionEndLine;
|
||||
protected boolean biasLeft;
|
||||
|
||||
protected int newSelectionStart; // hack to get around lack of multiple returns in Java
|
||||
protected int newSelectionEnd;
|
||||
|
||||
protected boolean selectWord;
|
||||
protected boolean selectLine;
|
||||
protected int selectionAncorStart;
|
||||
protected int selectionAncorEnd;
|
||||
|
||||
protected int bracketPosition;
|
||||
protected int bracketLine;
|
||||
@ -2021,9 +2120,26 @@ public class JEditTextArea extends JComponent
|
||||
{
|
||||
if (popup != null && popup.isVisible()) return;
|
||||
|
||||
setSelectionRectangular((evt.getModifiers()
|
||||
& InputEvent.CTRL_MASK) != 0);
|
||||
select(getMarkPosition(),xyToOffset(evt.getX(),evt.getY()));
|
||||
if ( !selectWord && !selectLine ) {
|
||||
setSelectionRectangular((evt.getModifiers()
|
||||
& InputEvent.CTRL_MASK) != 0);
|
||||
select(getMarkPosition(),xyToOffset(evt.getX(),evt.getY()));
|
||||
} else {
|
||||
int line = yToLine(evt.getY());
|
||||
if ( selectWord ) {
|
||||
setNewSelectionWord( line, xToOffset(line,evt.getX()) );
|
||||
} else {
|
||||
newSelectionStart = getLineStartOffset(line);
|
||||
newSelectionEnd = getSafeLineStopOffset(line);
|
||||
}
|
||||
if ( newSelectionStart < selectionAncorStart ) {
|
||||
select(newSelectionStart,selectionAncorEnd);
|
||||
} else if ( newSelectionEnd > selectionAncorEnd ) {
|
||||
select(selectionAncorStart,newSelectionEnd);
|
||||
} else {
|
||||
select(newSelectionStart,newSelectionEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final Cursor normalCursor = new Cursor(Cursor.DEFAULT_CURSOR);
|
||||
@ -2094,6 +2210,9 @@ public class JEditTextArea extends JComponent
|
||||
int offset = xToOffset(line,evt.getX());
|
||||
int dot = getLineStartOffset(line) + offset;
|
||||
|
||||
selectLine = false;
|
||||
selectWord = false;
|
||||
|
||||
switch(evt.getClickCount()) {
|
||||
|
||||
case 1:
|
||||
@ -2159,74 +2278,11 @@ public class JEditTextArea extends JComponent
|
||||
bl.printStackTrace();
|
||||
}
|
||||
|
||||
String noWordSep = (String)document.getProperty("noWordSep");
|
||||
if(noWordSep == null)
|
||||
noWordSep = "";
|
||||
|
||||
// Ok, it's not a bracket... select the word
|
||||
String lineText = getLineText(line);
|
||||
|
||||
int wordStart = 0;
|
||||
int wordEnd = lineText.length();
|
||||
|
||||
char ch = lineText.charAt(Math.max(0,offset - 1));
|
||||
|
||||
// special case for whitespace (fry 0122, bug #348)
|
||||
// this is really nasty.. turns out that double-clicking any non-letter
|
||||
// or digit char gets lumped together.. sooo, this quickly gets messy,
|
||||
// because really it needs to check whether the chars are of the same
|
||||
// type.. so a double space or double - might be grouped together,
|
||||
// but what about a +=1? do + and - get grouped but not the 1? blech,
|
||||
// coming back to this later. it's not a difficult fix, just a
|
||||
// time-consuming one to track down all the proper cases.
|
||||
/*
|
||||
if (ch == ' ') {
|
||||
//System.out.println("yeehaa");
|
||||
|
||||
for(int i = offset - 1; i >= 0; i--) {
|
||||
if (lineText.charAt(i) == ' ') {
|
||||
wordStart = i;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(int i = offset; i < lineText.length(); i++) {
|
||||
if (lineText.charAt(i) == ' ') {
|
||||
wordEnd = i + 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
*/
|
||||
|
||||
// If the user clicked on a non-letter char,
|
||||
// we select the surrounding non-letters
|
||||
boolean selectNoLetter = (!Character.isLetterOrDigit(ch)
|
||||
&& noWordSep.indexOf(ch) == -1);
|
||||
|
||||
for(int i = offset - 1; i >= 0; i--) {
|
||||
ch = lineText.charAt(i);
|
||||
if (selectNoLetter ^ (!Character.isLetterOrDigit(ch) &&
|
||||
noWordSep.indexOf(ch) == -1)) {
|
||||
wordStart = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = offset; i < lineText.length(); i++) {
|
||||
ch = lineText.charAt(i);
|
||||
if(selectNoLetter ^ (!Character.isLetterOrDigit(ch) &&
|
||||
noWordSep.indexOf(ch) == -1)) {
|
||||
wordEnd = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//}
|
||||
|
||||
int lineStart = getLineStartOffset(line);
|
||||
select(lineStart + wordStart,lineStart + wordEnd);
|
||||
setNewSelectionWord( line, offset );
|
||||
select(newSelectionStart,newSelectionEnd);
|
||||
selectWord = true;
|
||||
selectionAncorStart = selectionStart;
|
||||
selectionAncorEnd = selectionEnd;
|
||||
|
||||
/*
|
||||
String lineText = getLineText(line);
|
||||
@ -2242,7 +2298,10 @@ public class JEditTextArea extends JComponent
|
||||
private void doTripleClick(MouseEvent evt, int line,
|
||||
int offset, int dot)
|
||||
{
|
||||
select(getLineStartOffset(line),getLineStopOffset(line)-1);
|
||||
selectLine = true;
|
||||
select(getLineStartOffset(line),getSafeLineStopOffset(line));
|
||||
selectionAncorStart = selectionStart;
|
||||
selectionAncorEnd = selectionEnd;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user