Merge branch 'issue-42'
This commit is contained in:
commit
707f38ff9d
4 changed files with 185 additions and 22 deletions
|
|
@ -152,3 +152,7 @@
|
|||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
}
|
||||
|
||||
.ace_dragging .ace_marker-layer, .ace_dragging .ace_text-layer {
|
||||
cursor: move;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
/* vim:ts=4:sts=4:sw=4:
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
|
|
@ -20,6 +21,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Fabian Jakobs <fabian AT ajax DOT org>
|
||||
* Mihai Sucan <mihai DOT sucan AT gmail DOT com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
|
@ -585,7 +587,7 @@ var EditSession = function(text, mode) {
|
|||
action.start = delta.range.start;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// update selection based on last operation
|
||||
this.selection.clearSelection();
|
||||
var action = actions[actions.length-1];
|
||||
|
|
@ -599,6 +601,45 @@ var EditSession = function(text, mode) {
|
|||
return this.doc.replace(range, text);
|
||||
};
|
||||
|
||||
/**
|
||||
* Move a range of text from the given range to the given position.
|
||||
*
|
||||
* @param fromRange {Range} The range of text you want moved within the
|
||||
* document.
|
||||
* @param toPosition {Object} The location (row and column) where you want
|
||||
* to move the text to.
|
||||
* @return {Range} The new range where the text was moved to.
|
||||
*/
|
||||
this.moveText = function(fromRange, toPosition) {
|
||||
var text = this.getTextRange(fromRange);
|
||||
this.remove(fromRange);
|
||||
|
||||
var toRow = toPosition.row;
|
||||
var toColumn = toPosition.column;
|
||||
|
||||
// Make sure to update the insert location, when text is removed in
|
||||
// front of the chosen point of insertion.
|
||||
if (!fromRange.isMultiLine() && fromRange.start.row == toRow &&
|
||||
fromRange.end.column < toColumn)
|
||||
toColumn -= text.length;
|
||||
|
||||
if (fromRange.isMultiLine() && fromRange.end.row < toRow) {
|
||||
var lines = this.doc.$split(text);
|
||||
toRow -= lines.length - 1;
|
||||
}
|
||||
|
||||
var endRow = toRow + fromRange.end.row - fromRange.start.row;
|
||||
var endColumn = fromRange.isMultiLine() ?
|
||||
fromRange.end.column :
|
||||
toColumn + fromRange.end.column - fromRange.start.column;
|
||||
|
||||
var toRange = new Range(toRow, toColumn, endRow, endColumn);
|
||||
|
||||
this.insert(toRange.start, text);
|
||||
|
||||
return toRange;
|
||||
};
|
||||
|
||||
this.indentRows = function(startRow, endRow, indentString) {
|
||||
indentString = indentString.replace(/\t/g, this.getTabString());
|
||||
for (var row=startRow; row<=endRow; row++) {
|
||||
|
|
|
|||
|
|
@ -762,6 +762,13 @@ var Editor =function(renderer, session) {
|
|||
});
|
||||
};
|
||||
|
||||
this.moveText = function(range, toPosition) {
|
||||
if (this.$readOnly)
|
||||
return null;
|
||||
|
||||
return this.session.moveText(range, toPosition);
|
||||
};
|
||||
|
||||
this.copyLinesUp = function() {
|
||||
if (this.$readOnly)
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
/* vim:ts=4:sts=4:sw=4:
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
|
|
@ -20,6 +21,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Fabian Jakobs <fabian AT ajax DOT org>
|
||||
* Mihai Sucan <mihai DOT sucan AT gmail DOT com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
|
@ -38,6 +40,14 @@
|
|||
define(function(require, exports, module) {
|
||||
|
||||
var event = require("pilot/event");
|
||||
var dom = require("pilot/dom");
|
||||
|
||||
var STATE_UNKNOWN = 0;
|
||||
var STATE_SELECT = 1;
|
||||
var STATE_DRAG = 2;
|
||||
|
||||
var DRAG_TIMER = 250; // milliseconds
|
||||
var DRAG_OFFSET = 5; // pixels
|
||||
|
||||
var MouseHandler = function(editor) {
|
||||
this.editor = editor;
|
||||
|
|
@ -67,40 +77,57 @@ var MouseHandler = function(editor) {
|
|||
this.getScrollSpeed = function() {
|
||||
return this.$scrollSpeed;
|
||||
};
|
||||
|
||||
|
||||
this.$getEventPosition = function(e) {
|
||||
var pageX = event.getDocumentX(e);
|
||||
var pageY = event.getDocumentY(e);
|
||||
var pos = this.editor.renderer.screenToTextCoordinates(pageX, pageY);
|
||||
pos.row = Math.max(0, Math.min(pos.row, this.editor.session.getLength()-1));
|
||||
return pos;
|
||||
};
|
||||
|
||||
this.$distance = function(ax, ay, bx, by) {
|
||||
return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2));
|
||||
};
|
||||
|
||||
this.onMouseDown = function(e) {
|
||||
var pageX = event.getDocumentX(e);
|
||||
var pageY = event.getDocumentY(e);
|
||||
var pos = this.$getEventPosition(e);
|
||||
var editor = this.editor;
|
||||
|
||||
var pos = editor.renderer.screenToTextCoordinates(pageX, pageY);
|
||||
pos.row = Math.max(0, Math.min(pos.row, editor.session.getLength()-1));
|
||||
var self = this;
|
||||
var selectionRange = editor.getSelectionRange();
|
||||
var selectionEmpty = selectionRange.isEmpty();
|
||||
var state = STATE_UNKNOWN;
|
||||
var inSelection = false;
|
||||
|
||||
var button = event.getButton(e)
|
||||
if (button != 0) {
|
||||
var isEmpty = editor.selection.isEmpty()
|
||||
if (isEmpty) {
|
||||
if (selectionEmpty) {
|
||||
editor.moveCursorToPosition(pos);
|
||||
}
|
||||
if(button == 2) {
|
||||
editor.textInput.onContextMenu({x: pageX, y: pageY}, isEmpty);
|
||||
editor.textInput.onContextMenu({x: pageX, y: pageY}, selectionEmpty);
|
||||
event.capture(editor.container, function(){}, editor.textInput.onContextMenuClose);
|
||||
}
|
||||
return;
|
||||
} else
|
||||
inSelection = !editor.getReadOnly() &&
|
||||
!selectionEmpty &&
|
||||
selectionRange.contains(pos.row, pos.column);
|
||||
|
||||
if (!inSelection) {
|
||||
// Directly pick STATE_SELECT, since the user is not clicking inside
|
||||
// a selection.
|
||||
onStartSelect(pos);
|
||||
}
|
||||
|
||||
if (e.shiftKey)
|
||||
editor.selection.selectToPosition(pos)
|
||||
else {
|
||||
editor.moveCursorToPosition(pos);
|
||||
if (!editor.$clickSelection)
|
||||
editor.selection.clearSelection(pos.row, pos.column);
|
||||
}
|
||||
|
||||
|
||||
editor.renderer.scrollCursorIntoView();
|
||||
|
||||
var self = this;
|
||||
var mousePageX, mousePageY;
|
||||
var overwrite = editor.getOverwrite();
|
||||
var dragCursor = null;
|
||||
var mousedownTime = (new Date()).getTime();
|
||||
|
||||
var onMouseSelection = function(e) {
|
||||
mousePageX = event.getDocumentX(e);
|
||||
|
|
@ -109,17 +136,88 @@ var MouseHandler = function(editor) {
|
|||
|
||||
var onMouseSelectionEnd = function() {
|
||||
clearInterval(timerId);
|
||||
if (state == STATE_UNKNOWN)
|
||||
onStartSelect(pos);
|
||||
else if (state == STATE_DRAG)
|
||||
onMouseDragSelectionEnd();
|
||||
|
||||
self.$clickSelection = null;
|
||||
state = STATE_UNKNOWN;
|
||||
};
|
||||
|
||||
var onMouseDragSelectionEnd = function() {
|
||||
dom.removeCssClass(editor.container, "ace_dragging");
|
||||
|
||||
if (!self.$clickSelection) {
|
||||
if (!dragCursor) {
|
||||
editor.moveCursorToPosition(pos);
|
||||
editor.selection.clearSelection(pos.row, pos.column);
|
||||
}
|
||||
}
|
||||
|
||||
if (!dragCursor)
|
||||
return;
|
||||
|
||||
var selection = editor.getSelectionRange();
|
||||
if (selection.contains(dragCursor.row, dragCursor.column)) {
|
||||
dragCursor = null;
|
||||
return;
|
||||
}
|
||||
|
||||
editor.clearSelection();
|
||||
var newRange = editor.moveText(selection, dragCursor);
|
||||
if (!newRange) {
|
||||
dragCursor = null;
|
||||
return;
|
||||
}
|
||||
|
||||
editor.selection.setSelectionRange(newRange);
|
||||
};
|
||||
|
||||
var onSelectionInterval = function() {
|
||||
if (mousePageX === undefined || mousePageY === undefined)
|
||||
return;
|
||||
|
||||
if (state == STATE_UNKNOWN) {
|
||||
var distance = self.$distance(pageX, pageY, mousePageX, mousePageY);
|
||||
var time = (new Date()).getTime();
|
||||
|
||||
|
||||
if (distance > DRAG_OFFSET) {
|
||||
state = STATE_SELECT;
|
||||
var cursor = editor.renderer.screenToTextCoordinates(mousePageX, mousePageY);
|
||||
cursor.row = Math.max(0, Math.min(cursor.row, editor.session.getLength()-1));
|
||||
onStartSelect(cursor);
|
||||
} else if ((time - mousedownTime) > DRAG_TIMER) {
|
||||
state = STATE_DRAG;
|
||||
dom.addCssClass(editor.container, "ace_dragging");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (state == STATE_DRAG)
|
||||
onDragSelectionInterval();
|
||||
else if (state == STATE_SELECT)
|
||||
onUpdateSelectionInterval();
|
||||
};
|
||||
|
||||
function onStartSelect(pos) {
|
||||
if (e.shiftKey)
|
||||
editor.selection.selectToPosition(pos)
|
||||
else {
|
||||
if (!self.$clickSelection) {
|
||||
editor.moveCursorToPosition(pos);
|
||||
editor.selection.clearSelection(pos.row, pos.column);
|
||||
}
|
||||
}
|
||||
state = STATE_SELECT;
|
||||
}
|
||||
|
||||
var onUpdateSelectionInterval = function() {
|
||||
var cursor = editor.renderer.screenToTextCoordinates(mousePageX, mousePageY);
|
||||
cursor.row = Math.max(0, Math.min(cursor.row, editor.session.getLength()-1));
|
||||
|
||||
if (self.$clickSelection) {
|
||||
if (self.$clickSelection) {
|
||||
if (self.$clickSelection.contains(cursor.row, cursor.column)) {
|
||||
editor.selection.setSelectionRange(self.$clickSelection);
|
||||
} else {
|
||||
|
|
@ -138,7 +236,16 @@ var MouseHandler = function(editor) {
|
|||
|
||||
editor.renderer.scrollCursorIntoView();
|
||||
};
|
||||
|
||||
|
||||
var onDragSelectionInterval = function() {
|
||||
dragCursor = editor.renderer.screenToTextCoordinates(mousePageX, mousePageY);
|
||||
dragCursor.row = Math.max(0, Math.min(dragCursor.row,
|
||||
editor.session.getLength() - 1));
|
||||
|
||||
editor.renderer.updateCursor(dragCursor, overwrite);
|
||||
editor.renderer.scrollCursorIntoView();
|
||||
};
|
||||
|
||||
event.capture(editor.container, onMouseSelection, onMouseSelectionEnd);
|
||||
var timerId = setInterval(onSelectionInterval, 20);
|
||||
|
||||
|
|
@ -146,11 +253,15 @@ var MouseHandler = function(editor) {
|
|||
};
|
||||
|
||||
this.onMouseDoubleClick = function(e) {
|
||||
var pos = this.$getEventPosition(e);
|
||||
this.editor.moveCursorToPosition(pos);
|
||||
this.editor.selection.selectWord();
|
||||
this.$clickSelection = this.editor.getSelectionRange();
|
||||
};
|
||||
|
||||
this.onMouseTripleClick = function(e) {
|
||||
var pos = this.$getEventPosition(e);
|
||||
this.editor.moveCursorToPosition(pos);
|
||||
this.editor.selection.selectLine();
|
||||
this.$clickSelection = this.editor.getSelectionRange();
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue