From 8ebf34a385ff69e4d462a39b8b23ae745aa44694 Mon Sep 17 00:00:00 2001 From: DanyaPostfactum Date: Tue, 17 Sep 2013 19:07:16 +1000 Subject: [PATCH] Add autoscroll delay --- lib/ace/mouse/dragdrop_handler.js | 64 +++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 8 deletions(-) diff --git a/lib/ace/mouse/dragdrop_handler.js b/lib/ace/mouse/dragdrop_handler.js index 302538e1..9da78933 100644 --- a/lib/ace/mouse/dragdrop_handler.js +++ b/lib/ace/mouse/dragdrop_handler.js @@ -35,6 +35,10 @@ var dom = require("../lib/dom"); var event = require("../lib/event"); var useragent = require("../lib/useragent"); +var AUTOSCROLL_DELAY = 200; +var SCROLL_CURSOR_DELAY = 200; +var SCROLL_CURSOR_HYSTERESIS = 5; + function DragdropHandler(mouseHandler) { var editor = mouseHandler.editor; @@ -62,6 +66,9 @@ function DragdropHandler(mouseHandler) { var timerId, range; var dragCursor, counter = 0; var dragOperation; + var autoScrollStartTime; + var cursorMovedTime; + var cursorPointOnCaretMoved; this.onDragStart = function(e) { // webkit workaround, see this.onMouseDown @@ -185,8 +192,29 @@ function DragdropHandler(mouseHandler) { event.addListener(mouseTarget, "dragleave", this.onDragLeave.bind(mouseHandler)); event.addListener(mouseTarget, "drop", this.onDrop.bind(mouseHandler)); - function onDragInterval() { - dragCursor = editor.renderer.screenToTextCoordinates(x, y); + function scrollCursorIntoView(cursor, prevCursor) { + var now = new Date().getTime(); + var vMovement = !prevCursor || cursor.row != prevCursor.row; + var hMovement = !prevCursor || cursor.column != prevCursor.column; + if (!cursorMovedTime || vMovement || hMovement) { + editor.$blockScrolling += 1; + editor.moveCursorToPosition(cursor); + editor.$blockScrolling -= 1; + cursorMovedTime = now; + cursorPointOnCaretMoved = {x: x, y: y}; + } else { + var distance = calcDistance(cursorPointOnCaretMoved.x, cursorPointOnCaretMoved.y, x, y); + if (distance > SCROLL_CURSOR_HYSTERESIS) { + cursorMovedTime = null; + } else if (now - cursorMovedTime >= SCROLL_CURSOR_DELAY) { + editor.renderer.scrollCursorIntoView(); + cursorMovedTime = null; + } + } + } + + function autoScroll(cursor, prevCursor) { + var now = new Date().getTime(); var lineHeight = editor.renderer.layerConfig.lineHeight; var characterWidth = editor.renderer.layerConfig.characterWidth; var editorRect = editor.renderer.scroller.getBoundingClientRect(); @@ -202,15 +230,31 @@ function DragdropHandler(mouseHandler) { }; var nearestXOffset = Math.min(offsets.x.left, offsets.x.right); var nearestYOffset = Math.min(offsets.y.top, offsets.y.bottom); - var scrollCursor = {row: dragCursor.row, column: dragCursor.column}; + var scrollCursor = {row: cursor.row, column: cursor.column}; if (nearestXOffset / characterWidth <= 2) { scrollCursor.column += (offsets.x.left < offsets.x.right ? -3 : +2); } if (nearestYOffset / lineHeight <= 1) { scrollCursor.row += (offsets.y.top < offsets.y.bottom ? -1 : +1); } - editor.moveCursorToPosition(dragCursor); - editor.renderer.scrollCursorIntoView(scrollCursor); + var vScroll = cursor.row != scrollCursor.row; + var hScroll = cursor.column != scrollCursor.column; + var vMovement = !prevCursor || cursor.row != prevCursor.row; + if (vScroll || (hScroll && !vMovement)) { + if (!autoScrollStartTime) + autoScrollStartTime = now; + else if (now - autoScrollStartTime >= AUTOSCROLL_DELAY) + editor.renderer.scrollCursorIntoView(scrollCursor); + } else { + autoScrollStartTime = null; + } + } + + function onDragInterval() { + var prevCursor = dragCursor; + dragCursor = editor.renderer.screenToTextCoordinates(x, y); + scrollCursorIntoView(dragCursor, prevCursor); + autoScroll(dragCursor, prevCursor); } function addDragMarker() { @@ -232,6 +276,8 @@ function DragdropHandler(mouseHandler) { editor.$blockScrolling -= 1; range = null; counter = 0; + autoScrollStartTime = null; + cursorMovedTime = null; event.removeListener(document, "mousemove", onMouseMove); } @@ -355,11 +401,13 @@ function DragdropHandler(mouseHandler) { } }; - function calcDistance(ax, ay, bx, by) { - return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2)); - } }).call(DragdropHandler.prototype); + +function calcDistance(ax, ay, bx, by) { + return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2)); +} + exports.DragdropHandler = DragdropHandler; }); \ No newline at end of file