From d81d2858adf377ca6af3a1e4bfd6b234525fc91d Mon Sep 17 00:00:00 2001 From: Fabian Jakobs Date: Wed, 27 Jul 2011 19:39:47 +0200 Subject: [PATCH] move more scroll stuff to the model --- lib/ace/model/window.js | 37 +++++++++++++++ lib/ace/view/layer/cursor.js | 6 ++- lib/ace/view/window_view.js | 89 ++++++++++++++---------------------- lib/ace/window_controller.js | 3 ++ 4 files changed, 79 insertions(+), 56 deletions(-) diff --git a/lib/ace/model/window.js b/lib/ace/model/window.js index d22f2307..0ce73dca 100644 --- a/lib/ace/model/window.js +++ b/lib/ace/model/window.js @@ -79,6 +79,9 @@ var Window = exports.Window = function(theme) { width: 0 }; + this.scrollLeft = 0; + this.scrollTop = 0; + this.showInvisibles = false; this.showPrintMargin = true; this.printMarginColumn = 80; @@ -130,6 +133,40 @@ var Window = exports.Window = function(theme) { top : cursorTop }; }; + + // SCROLLING + + this.scrollToY = function(scrollTop) { + scrollTop = Math.max(0, scrollTop); + if (this.scrollTop == scrollTop) + return; + + this.scrollTop = scrollTop; + this._emit("changeScrollTop"); + }; + + this.getScrollTop = function() { + return this.scrollTop; + }; + + this.scrollToX = function(scrollLeft) { + if (scrollLeft <= this.padding) + scrollLeft = 0; + + if (this.scrollLeft === scrollLeft) + return; + + this.scrollLeft = scrollLeft; + this._emit("changeScrollLeft"); + }; + + + this.getScrollLeft = function() { + return this.scrollLeft; + }; + + // SETTINGS + this.setBuffer = function(buffer) { if (this.buffer === buffer) return; diff --git a/lib/ace/view/layer/cursor.js b/lib/ace/view/layer/cursor.js index 5ed7abdb..d2f22985 100644 --- a/lib/ace/view/layer/cursor.js +++ b/lib/ace/view/layer/cursor.js @@ -88,10 +88,12 @@ var Cursor = function(model, parentEl) { this.update = function(config) { this.pixelPos = this.model.getCursorPixelPosition(true); + var charSize = this.model.characterSize; + this.cursor.style.left = this.pixelPos.left + "px"; this.cursor.style.top = this.pixelPos.top + "px"; - this.cursor.style.width = config.characterWidth + "px"; - this.cursor.style.height = config.lineHeight + "px"; + this.cursor.style.width = charSize.width + "px"; + this.cursor.style.height = charSize.height + "px"; var overwrite = this.model.buffer.getOverwrite() if (overwrite != this.overwrite) { diff --git a/lib/ace/view/window_view.js b/lib/ace/view/window_view.js index db5b630b..b108aecc 100644 --- a/lib/ace/view/window_view.js +++ b/lib/ace/view/window_view.js @@ -91,19 +91,17 @@ var WindowView = function(windowModel, container) { this.$cursorLayer = new CursorLayer(windowModel, this.content); this.$horizScroll = true; - this.scrollTop = 0; - this.scrollLeft = 0; this.scrollBar = new ScrollBar(container); this.scrollBar.addEventListener("scroll", this.onScroll.bind(this)); - + var _self = this; event.addListener(this.scroller, "scroll", function() { - _self.scrollToX(_self.scroller.scrollLeft); + windowModel.scrollToX(_self.scroller.scrollLeft); }); event.addListener(this.$gutter, "click", this.$onGutterClick.bind(this)); event.addListener(this.$gutter, "dblclick", this.$onGutterClick.bind(this)); - + this.$loop = new RenderLoop(this.$renderChanges.bind(this)); this.$loop.schedule(this.CHANGE_FULL); @@ -195,7 +193,7 @@ var WindowView = function(windowModel, container) { this.scrollBar.setHeight(size.scrollerHeight); if (this.session) { - this.scrollToY(this.getScrollTop()); + this.model.scrollToY(this.model.scrollTop); changes = changes | this.CHANGE_FULL; } } @@ -286,7 +284,7 @@ var WindowView = function(windowModel, container) { var offset = this.model.layerConfig.offset; textarea.style.left = (bounds.left + pos.left + this.model.padding) + "px"; - textarea.style.top = (bounds.top + pos.top - this.scrollTop + offset) + "px"; + textarea.style.top = (bounds.top + pos.top - this.model.scrollTop + offset) + "px"; }; this.updatePadding = function() { @@ -311,12 +309,12 @@ var WindowView = function(windowModel, container) { }; this.onScroll = function(e) { - this.scrollToY(e.data); + this.model.scrollToY(e.data); }; this.$updateScrollBar = function() { this.scrollBar.setInnerHeight(this.model.layerConfig.maxHeight); - this.scrollBar.setScrollTop(this.scrollTop); + this.scrollBar.setScrollTop(this.model.scrollTop); }; this.$renderChanges = function(changes) { @@ -393,7 +391,7 @@ var WindowView = function(windowModel, container) { this.$computeLayerConfig = function() { var session = this.session; - var offset = this.scrollTop % this.lineHeight; + var offset = this.model.scrollTop % this.lineHeight; var minHeight = this.model.size.scrollerHeight + this.lineHeight; var longestLine = this.$getLongestLine(); @@ -406,10 +404,10 @@ var WindowView = function(windowModel, container) { this.scroller.style.overflowX = horizScroll ? "scroll" : "hidden"; var maxHeight = this.session.getScreenLength() * this.lineHeight; - this.scrollTop = Math.max(0, Math.min(this.scrollTop, maxHeight - this.model.size.scrollerHeight)); + this.model.scrollToY(Math.max(0, Math.min(this.model.scrollTop, maxHeight - this.model.size.scrollerHeight))); var lineCount = Math.ceil(minHeight / this.lineHeight) - 1; - var firstRow = Math.max(0, Math.round((this.scrollTop - offset) / this.lineHeight)); + var firstRow = Math.max(0, Math.round((this.model.scrollTop - offset) / this.lineHeight)); var lastRow = firstRow + lineCount; // Map lines on the screen to lines in the document. @@ -431,7 +429,7 @@ var WindowView = function(windowModel, container) { minHeight = this.model.size.scrollerHeight + session.getRowHeight(lineHeight, lastRow)+ firstRowHeight; - offset = this.scrollTop - firstRowScreen * this.lineHeight; + offset = this.model.scrollTop - firstRowScreen * this.lineHeight; this.model.layerConfig = { width : longestLine, @@ -457,7 +455,7 @@ var WindowView = function(windowModel, container) { // scroller.scrollWidth was smaller than scrollLeft we needed if (this.$desiredScrollLeft) { - this.scrollToX(this.$desiredScrollLeft); + this.model.scrollToX(this.$desiredScrollLeft); this.$desiredScrollLeft = 0; } @@ -553,46 +551,42 @@ var WindowView = function(windowModel, container) { var left = pos.left; var top = pos.top; - if (this.scrollTop > top) { - this.scrollToY(top); + if (this.model.scrollTop > top) { + this.model.scrollToY(top); } - if (this.scrollTop + this.model.size.scrollerHeight < top + this.lineHeight) { - this.scrollToY(top + this.lineHeight - this.model.size.scrollerHeight); + if (this.model.scrollTop + this.model.size.scrollerHeight < top + this.lineHeight) { + this.model.scrollToY(top + this.lineHeight - this.model.size.scrollerHeight); } - var scrollLeft = this.scrollLeft; + var scrollLeft = this.model.scrollLeft; if (scrollLeft > left) { - this.scrollToX(left); + this.model.scrollToX(left); } if (scrollLeft + this.model.size.scrollerWidth < left + this.characterWidth) { if (left > this.model.layerConfig.width) this.$desiredScrollLeft = left + 2 * this.characterWidth; else - this.scrollToX(Math.round(left + this.characterWidth - this.model.size.scrollerWidth)); + this.model.scrollToX(Math.round(left + this.characterWidth - this.model.size.scrollerWidth)); } }; - this.getScrollTop = function() { - return this.scrollTop; - }; - this.getScrollLeft = function() { - return this.scrollLeft; + return this.model.scrollLeft; }; this.getScrollTopRow = function() { - return this.scrollTop / this.lineHeight; + return this.model.scrollTop / this.lineHeight; }; this.getScrollBottomRow = function() { - return Math.max(0, Math.floor((this.scrollTop + this.model.size.scrollerHeight) / this.lineHeight) - 1); + return Math.max(0, Math.floor((this.model.scrollTop + this.model.size.scrollerHeight) / this.lineHeight) - 1); }; this.scrollToRow = function(row) { - this.scrollToY(row * this.lineHeight); + this.model.scrollToY(row * this.lineHeight); }; this.scrollToLine = function(line, center) { @@ -605,41 +599,28 @@ var WindowView = function(windowModel, container) { if (center) { offset -= this.model.size.scrollerHeight / 2; } - this.scrollToY(offset); + this.model.scrollToY(offset); }; - this.scrollToY = function(scrollTop) { - // after calling scrollBar.setScrollTop - // scrollbar sends us event with same scrollTop. ignore it - scrollTop = Math.max(0, scrollTop); - if (this.scrollTop !== scrollTop) { - this.$loop.schedule(this.CHANGE_SCROLL); - this.scrollTop = scrollTop; - } + this.updateScrollLeft = function() { + this.scroller.scrollLeft = this.model.scrollLeft; }; - - this.scrollToX = function(scrollLeft) { - if (scrollLeft <= this.model.padding) - scrollLeft = 0; - - if (this.scrollLeft === scrollLeft) - return; - - this.scrollLeft = scrollLeft; - this.scroller.scrollLeft = scrollLeft; + + this.updateScrollTop = function() { + this.$loop.schedule(this.CHANGE_SCROLL); }; this.scrollBy = function(deltaX, deltaY) { - deltaY && this.scrollToY(this.scrollTop + deltaY); - deltaX && this.scrollToX(this.scrollLeft + deltaX); + deltaY && this.model.scrollToY(this.model.scrollTop + deltaY); + deltaX && this.model.scrollToX(this.model.scrollLeft + deltaX); }; this.screenToTextCoordinates = function(pageX, pageY) { var canvasPos = this.scroller.getBoundingClientRect(); - var col = Math.round((pageX + this.scrollLeft - canvasPos.left - this.model.padding - dom.getPageScrollLeft()) + var col = Math.round((pageX + this.model.scrollLeft - canvasPos.left - this.model.padding - dom.getPageScrollLeft()) / this.characterWidth); - var row = Math.floor((pageY + this.scrollTop - canvasPos.top - dom.getPageScrollTop()) + var row = Math.floor((pageY + this.model.scrollTop - canvasPos.top - dom.getPageScrollTop()) / this.lineHeight); return this.session.screenToDocumentPosition(row, Math.max(col, 0)); @@ -653,8 +634,8 @@ var WindowView = function(windowModel, container) { var y = pos.row * this.lineHeight; return { - pageX: canvasPos.left + x - this.getScrollLeft(), - pageY: canvasPos.top + y - this.getScrollTop() + pageX: canvasPos.left + x - this.model.scrollLeft, + pageY: canvasPos.top + y - this.model.scrollTop }; }; diff --git a/lib/ace/window_controller.js b/lib/ace/window_controller.js index a6309fd2..b9473ac9 100644 --- a/lib/ace/window_controller.js +++ b/lib/ace/window_controller.js @@ -48,6 +48,9 @@ var WindowController = exports.WindowController = function(model, view) { model.on("changeHorizScroll", view.updateHorizScroll.bind(view)); model.on("changeTheme", view.updateTheme.bind(view)); model.on("changeCharacterSize", view.updateCharacterSize.bind(view)); + model.on("changeScrollLeft", view.updateScrollLeft.bind(view)); + model.on("changeScrollTop", view.updateScrollTop.bind(view)); + };