Fixed: Double click word select reacts on mouseup but it it should be mousedown

This commit is contained in:
Fabian Jakobs 2010-05-18 12:08:59 +02:00
commit a2d4b9a451
7 changed files with 145 additions and 30 deletions

View file

@ -18,8 +18,8 @@ ace.Editor = function(renderer, doc) {
var mouseTarget = renderer.getMouseEventTarget();
ace.addListener(mouseTarget, "mousedown", ace.bind(this.onMouseDown, this));
ace.addListener(mouseTarget, "dblclick", ace.bind(this.onMouseDoubleClick, this));
ace.addTripleClickListener(mouseTarget, ace.bind(this.onMouseTripleClick, this));
ace.addMultiMouseDownListener(mouseTarget, 2, ace.bind(this.onMouseDoubleClick, this));
ace.addMultiMouseDownListener(mouseTarget, 3, ace.bind(this.onMouseTripleClick, this));
ace.addMouseWheelListener(mouseTarget, ace.bind(this.onMouseWheel, this));
this.$selectionMarker = null;
@ -246,7 +246,9 @@ ace.Editor = function(renderer, doc) {
pos.row = Math.max(0, Math.min(pos.row, this.doc.getLength()-1));
this.moveCursorToPosition(pos);
this.selection.setSelectionAnchor(pos.row, pos.column);
if (!this.$clickSelection)
this.selection.setSelectionAnchor(pos.row, pos.column);
this.renderer.scrollCursorIntoView();
var self = this;
@ -259,16 +261,33 @@ ace.Editor = function(renderer, doc) {
var onMouseSelectionEnd = function() {
clearInterval(timerId);
self.$clickSelection = null;
};
var onSelectionInterval = function() {
if (mousePageX === undefined || mousePageY === undefined)
return;
selectionLead = self.renderer.screenToTextCoordinates(mousePageX, mousePageY);
selectionLead.row = Math.max(0, Math.min(selectionLead.row, self.doc.getLength()-1));
var cursor = self.renderer.screenToTextCoordinates(mousePageX, mousePageY);
cursor.row = Math.max(0, Math.min(cursor.row, self.doc.getLength()-1));
if (self.$clickSelection) {
if (self.$clickSelection.contains(cursor.row, cursor.column)) {
self.selection.setSelectionRange(self.$clickSelection);
} else {
if (self.$clickSelection.compare(cursor.row, cursor.column) == -1) {
var anchor = self.$clickSelection.end;
} else {
var anchor = self.$clickSelection.start;
}
self.selection.setSelectionAnchor(anchor.row, anchor.column);
self.selection.selectToPosition(cursor);
}
}
else {
self.selection.selectToPosition(cursor);
}
self.selection.selectToPosition(selectionLead);
self.renderer.scrollCursorIntoView();
};
@ -280,11 +299,13 @@ ace.Editor = function(renderer, doc) {
this.onMouseDoubleClick = function(e) {
this.selection.selectWord();
this.$clickSelection = this.getSelectionRange();
this.$updateDesiredColumn();
};
this.onMouseTripleClick = function(e) {
this.selection.selectLine();
this.$clickSelection = this.getSelectionRange();
this.$updateDesiredColumn();
};

View file

@ -14,35 +14,79 @@ ace.Range = function(startRow, startColumn, endRow, endColumn) {
(function() {
this.toString = function() {
return ("Range: [" + this.start.row + "/" + this.start.column +
"] -> [" + this.end.row + "/" + this.end.column + "]");
};
this.contains = function(row, column) {
return this.compare(row, column) == 0;
};
this.compare = function(row, column) {
if (!this.isMultiLine()) {
if (row === this.start.row) {
return column < this.start.column ? -1 : (column > this.end.column ? 1 : 0);
};
}
if (row < this.start.row)
return -1;
if (row > this.end.row)
return 1;
if (this.start.row === row)
return column >= this.start.column ? 0 : -1;
if (this.end.row === row)
return column <= this.end.column ? 0 : 1;
return 0;
};
this.clipRows = function(firstRow, lastRow) {
if (this.end.row > lastRow) {
this.end = {
var end = {
row: lastRow+1,
column: 0
};
}
if (this.start.row > lastRow) {
this.start = {
var start = {
row: lastRow+1,
column: 0
};
}
if (this.start.row < firstRow) {
this.start = {
var start = {
row: firstRow,
column: 0
};
}
if (this.end.row < firstRow) {
this.end = {
var end = {
row: firstRow,
column: 0
};
}
return this;
return ace.Range.fromPoints(start || this.start, end || this.end);
};
this.extend = function(row, column) {
var cmp = this.compare(row, column);
if (cmp == 0)
return this;
else if (cmp == -1)
var start = {row: row, column: column};
else
var end = {row: row, column: column};
return ace.Range.fromPoints(start || this.start, end || this.end);
};
this.isEmpty = function() {

View file

@ -33,8 +33,17 @@ ace.Selection = function(doc) {
};
this.setSelectionAnchor = function(row, column) {
this.clearSelection();
this.selectionAnchor = this.$clipPositionToDocument(row, column);
var anchor = this.$clipPositionToDocument(row, column);
if (!this.selectionAnchor) {
this.selectionAnchor = anchor;
this.$dispatchEvent("changeSelection", {});
}
else if (this.selectionAnchor.row !== anchor.row || this.selectionAnchor.column !== anchor.column) {
this.selectionAnchor = anchor;
this.$dispatchEvent("changeSelection", {});
}
};
this.getSelectionAnchor = function() {

View file

@ -46,7 +46,7 @@ ace.layer.Marker = function(parentEl) {
for ( var key in this.markers) {
var marker = this.markers[key];
var range = marker.range.clone().clipRows(config.firstRow, config.lastRow);
var range = marker.range.clipRows(config.firstRow, config.lastRow);
if (range.isEmpty()) continue;
if (range.isMultiLine()) {

View file

@ -120,7 +120,7 @@
self.addListener(el, "mousewheel", listener);
};
this.addTripleClickListener = function(el, callback) {
this.addMultiMouseDownListener = function(el, count, callback) {
var clicks = 0;
var listener = function(e) {
clicks += 1;
@ -130,7 +130,7 @@
}, 600);
}
if (clicks == 3) {
if (clicks == count) {
clicks = 0;
callback(e);
}

View file

@ -19,24 +19,14 @@ RangeTest = new TestCase("RangeTest", {
},
"test: clip to rows": function() {
var range = new ace.Range(0, 20, 100, 30);
range.clipRows(10, 30);
assertPosition(10, 0, range.start);
assertPosition(31, 0, range.end);
var range = new ace.Range(0, 20, 30, 10);
range.clipRows(10, 30);
assertPosition(10, 0, range.start);
assertPosition(30, 10, range.end);
assertRange(10, 0, 31, 0, new ace.Range(0, 20, 100, 30).clipRows(10, 30));
assertRange(10, 0, 30, 10, new ace.Range(0, 20, 30, 10).clipRows(10, 30));
var range = new ace.Range(0, 20, 3, 10);
range.clipRows(10, 30);
var range = range.clipRows(10, 30);
assertTrue(range.isEmpty());
assertPosition(10, 0, range.start);
assertPosition(10, 0, range.end);
assertRange(10, 0, 10, 0, range);
},
"test: isEmpty": function() {
@ -67,5 +57,51 @@ RangeTest = new TestCase("RangeTest", {
clone.end.column = 20;
assertPosition(3, 4, range.end);
},
"test: contains for multi line ranges": function() {
var range = new ace.Range(1, 10, 5, 20);
assertTrue(range.contains(1, 10));
assertTrue(range.contains(2, 0));
assertTrue(range.contains(3, 100));
assertTrue(range.contains(5, 19));
assertTrue(range.contains(5, 20));
assertFalse(range.contains(1, 9));
assertFalse(range.contains(0, 0));
assertFalse(range.contains(5, 21));
},
"test: contains for single line ranges": function() {
var range = new ace.Range(1, 10, 1, 20);
assertTrue(range.contains(1, 10));
assertTrue(range.contains(1, 15));
assertTrue(range.contains(1, 20));
assertFalse(range.contains(0, 9));
assertFalse(range.contains(2, 9));
assertFalse(range.contains(1, 9));
assertFalse(range.contains(1, 21));
},
"test: extend range": function() {
var range = new ace.Range(2, 10, 2, 30);
var range = range.extend(2, 5);
assertRange(2, 5, 2, 30, range);
var range = range.extend(2, 35);
assertRange(2, 5, 2, 35, range);
var range = range.extend(2, 15);
assertRange(2, 5, 2, 35, range);
var range = range.extend(1, 4);
assertRange(1, 4, 2, 35, range);
var range = range.extend(6, 10);
assertRange(1, 4, 6, 10, range);
}
});

View file

@ -3,6 +3,11 @@ assertPosition = function(row, column, cursor) {
assertEquals(column, cursor.column);
};
assertRange = function(startRow, startColumn, endRow, endColumn, range) {
assertPosition(startRow, startColumn, range.start);
assertPosition(endRow, endColumn, range.end);
};
assertJsonEquals = function(expectedJson, foundJson) {
assertEquals(JSON.stringify(expectedJson), JSON.stringify(foundJson));
};