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

View file

@ -14,35 +14,79 @@ ace.Range = function(startRow, startColumn, endRow, endColumn) {
(function() { (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) { this.clipRows = function(firstRow, lastRow) {
if (this.end.row > lastRow) { if (this.end.row > lastRow) {
this.end = { var end = {
row: lastRow+1, row: lastRow+1,
column: 0 column: 0
}; };
} }
if (this.start.row > lastRow) { if (this.start.row > lastRow) {
this.start = { var start = {
row: lastRow+1, row: lastRow+1,
column: 0 column: 0
}; };
} }
if (this.start.row < firstRow) { if (this.start.row < firstRow) {
this.start = { var start = {
row: firstRow, row: firstRow,
column: 0 column: 0
}; };
} }
if (this.end.row < firstRow) { if (this.end.row < firstRow) {
this.end = { var end = {
row: firstRow, row: firstRow,
column: 0 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() { this.isEmpty = function() {

View file

@ -33,8 +33,17 @@ ace.Selection = function(doc) {
}; };
this.setSelectionAnchor = function(row, column) { this.setSelectionAnchor = function(row, column) {
this.clearSelection(); var anchor = this.$clipPositionToDocument(row, column);
this.selectionAnchor = 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() { this.getSelectionAnchor = function() {

View file

@ -46,7 +46,7 @@ ace.layer.Marker = function(parentEl) {
for ( var key in this.markers) { for ( var key in this.markers) {
var marker = this.markers[key]; 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.isEmpty()) continue;
if (range.isMultiLine()) { if (range.isMultiLine()) {

View file

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

View file

@ -19,24 +19,14 @@ RangeTest = new TestCase("RangeTest", {
}, },
"test: clip to rows": function() { "test: clip to rows": function() {
var range = new ace.Range(0, 20, 100, 30); assertRange(10, 0, 31, 0, new ace.Range(0, 20, 100, 30).clipRows(10, 30));
range.clipRows(10, 30); assertRange(10, 0, 30, 10, new ace.Range(0, 20, 30, 10).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);
var range = new ace.Range(0, 20, 3, 10); var range = new ace.Range(0, 20, 3, 10);
range.clipRows(10, 30); var range = range.clipRows(10, 30);
assertTrue(range.isEmpty()); assertTrue(range.isEmpty());
assertPosition(10, 0, range.start); assertRange(10, 0, 10, 0, range);
assertPosition(10, 0, range.end);
}, },
"test: isEmpty": function() { "test: isEmpty": function() {
@ -67,5 +57,51 @@ RangeTest = new TestCase("RangeTest", {
clone.end.column = 20; clone.end.column = 20;
assertPosition(3, 4, range.end); 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); 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) { assertJsonEquals = function(expectedJson, foundJson) {
assertEquals(JSON.stringify(expectedJson), JSON.stringify(foundJson)); assertEquals(JSON.stringify(expectedJson), JSON.stringify(foundJson));
}; };