move more scroll stuff to the model

This commit is contained in:
Fabian Jakobs 2011-07-27 19:39:47 +02:00
commit d81d2858ad
4 changed files with 79 additions and 56 deletions

View file

@ -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;

View file

@ -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) {

View file

@ -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
};
};

View file

@ -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));
};