From 6da3ed808d04be60de8d6f8adad5263b9c1c81d1 Mon Sep 17 00:00:00 2001 From: Marcel Gerber Date: Wed, 27 Jul 2016 20:33:41 +0200 Subject: [PATCH] Improve search tick mark positioning --- src/search/ScrollTrackMarkers.js | 78 ++++++++++++++++++++++++++------ 1 file changed, 65 insertions(+), 13 deletions(-) diff --git a/src/search/ScrollTrackMarkers.js b/src/search/ScrollTrackMarkers.js index 94bd9a5461d..aacbd8639d4 100644 --- a/src/search/ScrollTrackMarkers.js +++ b/src/search/ScrollTrackMarkers.js @@ -67,8 +67,43 @@ define(function (require, exports, module) { * @type {?jQueryObject} */ var $markedTickmark; + + /** + * Vertical space above and below the scrollbar + * @type {number} + */ + var scrollbarTrackOffset; + + switch (brackets.platform) { + case "win": // Custom scrollbar CSS has no gap around the track + scrollbarTrackOffset = 0; + break; + case "mac": // Native scrollbar has padding around the track + scrollbarTrackOffset = 4; + break; + case "linux": // Custom scrollbar CSS has assymmetrical gap; this approximates it + scrollbarTrackOffset = 2; + break; + } + /** + * Vertical space above and below the scrollbar. + * @return {number} amount Value in pixels + */ + function getScrollbarTrackOffset() { + return scrollbarTrackOffset; + } + /** + * Sets how much vertical space there's above and below the scrollbar, which depends + * on the OS and may also be affected by extensions + * @param {number} offset Value in pixels + */ + function setScrollbarTrackOffset(offset) { + scrollbarTrackOffset = offset; + } + + function _getScrollbar(editor) { // Be sure to select only the direct descendant, not also elements within nested inline editors return $(editor.getRootElement()).children(".CodeMirror-vscrollbar"); @@ -81,16 +116,8 @@ define(function (require, exports, module) { trackHt = $sb[0].offsetHeight; if (trackHt > 0) { - // Scrollbar visible: determine offset of track from top of scrollbar - if (brackets.platform === "win") { - trackOffset = 0; // Custom scrollbar CSS has no gap around the track - } else if (brackets.platform === "mac") { - trackOffset = 4; // Native scrollbar has padding around the track - } else { //(Linux) - trackOffset = 2; // Custom scrollbar CSS has assymmetrical gap; this approximates it - } + trackOffset = getScrollbarTrackOffset(); trackHt -= trackOffset * 2; - } else { // No scrollbar: use the height of the entire code content var codeContainer = $(editor.getRootElement()).find("> .CodeMirror-scroll > .CodeMirror-sizer > div > .CodeMirror-lines > div")[0]; @@ -101,9 +128,31 @@ define(function (require, exports, module) { /** Add all the given tickmarks to the DOM in a batch */ function _renderMarks(posArray) { - var html = ""; + var html = "", + cm = editor._codeMirror, + editorHt = cm.getScrollerElement().scrollHeight; + + // We've pretty much taken these vars and the getY function from CodeMirror's annotatescrollbar addon + // https://github.com/codemirror/CodeMirror/blob/master/addon/scroll/annotatescrollbar.js + var wrapping = cm.getOption("lineWrapping"), + singleLineH = wrapping && cm.defaultTextHeight() * 1.5, + curLine = null, + curLineObj = null; + + function getY(cm, pos) { + if (curLine !== pos.line) { + curLine = pos.line; + curLineObj = cm.getLineHandle(curLine); + } + if (wrapping && curLineObj.height > singleLineH) { + return cm.charCoords(pos, "local").top; + } + return cm.heightAtLine(curLineObj, "local"); + } + posArray.forEach(function (pos) { - var top = Math.round(pos.line / editor.lineCount() * trackHt) + trackOffset; + var cursorTop = getY(cm, pos), + top = Math.round(cursorTop / editorHt * trackHt) + trackOffset; top--; // subtract ~1/2 the ht of a tickmark to center it on ideal pos html += "
"; @@ -140,8 +189,8 @@ define(function (require, exports, module) { return; } - var $sb = _getScrollbar(editor); - var $overlay = $("
"); + var $sb = _getScrollbar(editor), + $overlay = $("
"); $sb.parent().append($overlay); _calcScaling(); @@ -201,4 +250,7 @@ define(function (require, exports, module) { exports.setVisible = setVisible; exports.addTickmarks = addTickmarks; exports.markCurrent = markCurrent; + + exports.getScrollbarTrackOffset = getScrollbarTrackOffset; + exports.setScrollbarTrackOffset = setScrollbarTrackOffset; });