From ee1c4a0169dc78910e91a77b075c987f6554ccf8 Mon Sep 17 00:00:00 2001 From: Fabian Jakobs Date: Tue, 13 Apr 2010 18:23:34 +0200 Subject: [PATCH] add Ruben's text selection mode --- src/Editor.js | 8 +- src/MarkerLayer.js | 171 +++++++++++++++++++++++++++-------------- src/VirtualRenderer.js | 1 + 3 files changed, 118 insertions(+), 62 deletions(-) diff --git a/src/Editor.js b/src/Editor.js index 769546d3..0cd9e1a7 100644 --- a/src/Editor.js +++ b/src/Editor.js @@ -31,8 +31,6 @@ ace.Editor = function(doc, renderer) { column : 0 }; - - this.selectionAnchor = null; this.selectionLead = null; this.selection = null; @@ -40,7 +38,9 @@ ace.Editor = function(doc, renderer) { this.renderer.draw(); }; -ace.Editor.prototype.resize = function() { +ace.Editor.prototype.resize = function() +{ + this.renderer.scrollToY(this.renderer.getScrollTop()); this.renderer.draw(); }; @@ -636,7 +636,7 @@ ace.Editor.prototype._moveSelection = function(mover) { this.renderer.removeMarker(this.selection); } this.selection = this.renderer.addMarker(this.getSelectionRange(), - "selection"); + "selection", "text"); this.renderer.scrollCursorIntoView(); }; diff --git a/src/MarkerLayer.js b/src/MarkerLayer.js index c02ea039..4a10916c 100644 --- a/src/MarkerLayer.js +++ b/src/MarkerLayer.js @@ -10,11 +10,15 @@ ace.MarkerLayer = function(parentEl) { this._markerId = 1; }; -ace.MarkerLayer.prototype.addMarker = function(range, clazz) { +ace.MarkerLayer.prototype.setDocument = function(doc) { + this.doc = doc; +}; + +ace.MarkerLayer.prototype.addMarker = function(range, clazz, type) { var id = this._markerId++; this.markers[id] = { range : range, - type : "line", + type : type || "line", clazz : clazz }; @@ -40,68 +44,119 @@ ace.MarkerLayer.prototype.update = function(config) { var html = []; for ( var key in this.markers) { var marker = this.markers[key]; - var range = marker.range; + var range = { + start: marker.range.start, + end: marker.range.end + }; + + // clip + if (range.start.row > config.lastRow) continue; + if (range.end.row < config.firstRow) continue; + + if (range.end.row > config.lastRow) { + range.end = { + row: config.lastRow, + column: this.doc.getLine(config.lastRow).length + }; + } + + if (range.start.row < config.firstRow) { + range.start = { + row: config.firstRow, + column: 0 + }; + } if (range.start.row !== range.end.row) { - if (range.start.row >= config.firstRow - && range.start.row <= config.lastRow) { - html - .push( - "
"); + if (marker.type == "line") { + this.drawTextMarker(html, range, marker.clazz, config); + } else { + this.drawMultiLineMarker(html, range, marker.clazz, config); } - - if (range.end.row >= config.firstRow - && range.end.row <= config.lastRow) { - html - .push("
"); - } - ; - - for ( var row = range.start.row + 1; row < range.end.row; row++) { - if (row >= config.firstRow && row <= config.lastRow) { - html.push("
"); - } - } - ; } else { - if (range.start.row >= config.firstRow - && range.start.row <= config.lastRow) { - html.push("
"); - } + this.drawSingleLineMarker(html, range, marker.clazz, config); } } this.element.innerHTML = html.join(""); +}; + +ace.MarkerLayer.prototype.drawTextMarker = function(stringBuilder, range, clazz, layerConfig) { + + // selection start + var row = range.start.row; + var lineRange = { start: {}, end: {}}; + + lineRange.start.row = row; + lineRange.start.column = range.start.column; + lineRange.end.row = row; + lineRange.end.column = this.doc.getLine(row).length; + this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig); + + // selection end + var row = range.end.row; + lineRange.start.row = row; + lineRange.start.column = 0; + lineRange.end.row = row; + lineRange.end.column = range.end.column; + this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig); + + for (var row = range.start.row + 1; row < range.end.row; row++) { + lineRange.start.row = row; + lineRange.end.row = row; + lineRange.end.column = this.doc.getLine(row).length; + this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig); + } +}; + +ace.MarkerLayer.prototype.drawMultiLineMarker = function(stringBuilder, range, clazz, layerConfig) { + + var height = layerConfig.lineHeight; + var width = Math.round(layerConfig.width - (range.start.column * layerConfig.characterWidth)); + var top = (range.start.row - layerConfig.firstRow) * layerConfig.lineHeight; + var left = Math.round(range.start.column * layerConfig.characterWidth); + + stringBuilder.push( + "
" + ); + + var top = (range.end.row - layerConfig.firstRow) * layerConfig.lineHeight; + var width = Math.round(range.end.column * layerConfig.characterWidth); + + stringBuilder.push( + "
" + ); + + for (var row = range.start.row + 1; row < range.end.row; row++) { + var top = (row - layerConfig.firstRow) * layerConfig.lineHeight; + stringBuilder.push( + "
" + ); + } +}; + +ace.MarkerLayer.prototype.drawSingleLineMarker = function(stringBuilder, range, clazz, layerConfig) { + + var height = layerConfig.lineHeight; + var width = Math.round((range.end.column - range.start.column) * layerConfig.characterWidth); + var top = (range.start.row - layerConfig.firstRow) * layerConfig.lineHeight; + var left = Math.round(range.start.column * layerConfig.characterWidth); + + stringBuilder.push( + "
" + ); }; \ No newline at end of file diff --git a/src/VirtualRenderer.js b/src/VirtualRenderer.js index 3034e12b..1d07c96e 100644 --- a/src/VirtualRenderer.js +++ b/src/VirtualRenderer.js @@ -37,6 +37,7 @@ ace.VirtualRenderer = function(container) { ace.VirtualRenderer.prototype.setDocument = function(doc) { this.lines = doc.lines; this.doc = doc; + this.markerLayer.setDocument(doc); }; ace.VirtualRenderer.prototype.setTokenizer = function(tokenizer) {