allow multiple selections with shared edges

This commit is contained in:
nightwing
2013-02-25 12:30:58 +04:00
parent 7eeb988f87
commit 6f7a33e39b
4 changed files with 46 additions and 18 deletions

View File

@@ -84,14 +84,14 @@ function DefaultHandlers(mouseHandler) {
// selection
if (inSelection && !editor.isFocused()) {
editor.focus();
if (this.$focusTimout && !this.$clickSelection) {
if (this.$focusTimout && !this.$clickSelection && !editor.inMultiSelectMode) {
this.setState("focusWait");
this.captureMouse(ev);
return ev.preventDefault();
}
}
if (!inSelection || this.$clickSelection || ev.getShiftKey()) {
if (!inSelection || this.$clickSelection || ev.getShiftKey() || editor.inMultiSelectMode) {
// Directly pick STATE_SELECT, since the user is not clicking inside
// a selection.
this.startSelect(pos);

View File

@@ -78,9 +78,13 @@ var EditSession = require("./edit_session").EditSession;
if (!this.inMultiSelectMode && this.rangeCount == 0) {
var oldRange = this.toOrientedRange();
if (range.intersects(oldRange))
this.rangeList.add(oldRange);
this.rangeList.add(range);
if (this.rangeList.ranges.length != 2) {
this.rangeList.removeAll();
return $blockChangeEvents || this.fromOrientedRange(range);
}
this.rangeList.removeAll();
this.rangeList.add(oldRange);
this.$onAddRange(oldRange);
}

View File

@@ -40,19 +40,18 @@ var RangeList = function() {
(function() {
this.comparePoints = comparePoints;
this.pointIndex = function(pos, startIndex) {
this.pointIndex = function(pos, excludeEdges, startIndex) {
var list = this.ranges;
for (var i = startIndex || 0; i < list.length; i++) {
var range = list[i];
var cmp = comparePoints(pos, range.end);
if (cmp > 0)
var cmpEnd = comparePoints(pos, range.end);
if (cmpEnd > 0)
continue;
if (cmp == 0)
return i;
cmp = comparePoints(pos, range.start);
if (cmp >= 0)
var cmpStart = comparePoints(pos, range.start);
if (cmpEnd === 0)
return excludeEdges && cmpStart !== 0 ? -i-2 : i;
if (cmpStart > 0 || (cmpStart === 0 && !excludeEdges))
return i;
return -i-1;
@@ -61,17 +60,17 @@ var RangeList = function() {
};
this.add = function(range) {
var startIndex = this.pointIndex(range.start);
var excludeEdges = !range.isEmpty();
var startIndex = this.pointIndex(range.start, excludeEdges);
if (startIndex < 0)
startIndex = -startIndex - 1;
var endIndex = this.pointIndex(range.end, startIndex);
var endIndex = this.pointIndex(range.end, excludeEdges, startIndex);
if (endIndex < 0)
endIndex = -endIndex - 1;
else
endIndex++;
return this.ranges.splice(startIndex, endIndex - startIndex, range);
};
@@ -102,7 +101,7 @@ var RangeList = function() {
if (cmp < 0)
continue;
if (cmp == 0 && !(range.isEmpty() || next.isEmpty()))
if (cmp == 0 && !range.isEmpty() && !next.isEmpty())
continue;
if (comparePoints(range.end, next.end) < 0) {
@@ -198,10 +197,16 @@ var RangeList = function() {
break;
if (r.start.row == startRow && r.start.column >= start.column ) {
r.start.column += colDiff;
r.start.row += lineDif;
}
if (r.end.row == startRow && r.end.column >= start.column) {
if (r.end.row == startRow && r.end.column >= start.column) {
// special handling for the case when two ranges share an edge
if (r.end.column == start.column && colDiff > 0 && i < n - 1) {
if (r.end.column > r.start.column && r.end.column == ranges[i+1].start.column)
r.end.column -= colDiff;
}
r.end.column += colDiff;
r.end.row += lineDif;
}

View File

@@ -72,6 +72,26 @@ module.exports = {
assert.equal(rangeList.pointIndex({row: 8, column: 9}), 2);
assert.equal(rangeList.pointIndex({row: 18, column: 9}), -4);
},
"test: rangeList pointIndex excludeEdges": function() {
var rangeList = new RangeList();
rangeList.ranges = [
new Range(1,2,3,4),
new Range(4,2,5,4),
new Range(8,8,9,9),
new Range(10,10,10,10)
];
assert.equal(rangeList.pointIndex({row: 0, column: 1}, true), -1);
assert.equal(rangeList.pointIndex({row: 1, column: 2}, true), -1);
assert.equal(rangeList.pointIndex({row: 1, column: 3}, true), 0);
assert.equal(rangeList.pointIndex({row: 3, column: 4}, true), -2);
assert.equal(rangeList.pointIndex({row: 4, column: 1}, true), -2);
assert.equal(rangeList.pointIndex({row: 5, column: 1}, true), 1);
assert.equal(rangeList.pointIndex({row: 8, column: 9}, true), 2);
assert.equal(rangeList.pointIndex({row: 10, column: 10}, true), 3);
assert.equal(rangeList.pointIndex({row: 18, column: 9}, true), -5);
},
"test: rangeList add": function() {
var rangeList = new RangeList();
@@ -153,7 +173,6 @@ module.exports = {
rangeList.substractPoint({row: 6, column: 7});
assert.equal(rangeList.ranges.length, 2);
}
};
});