automatically optimize scrollable elements for csr and il/dl.

This commit is contained in:
Christopher Jeffrey 2013-07-14 11:04:48 -05:00
parent 6a44fd9a35
commit 95848bafa3
2 changed files with 58 additions and 15 deletions

View File

@ -714,6 +714,11 @@ array are the furthest away, just like in the DOM.
### Optimization and CSR
**NOTE:** This is now automatically optimized for full-width scrollable elements.
**TODO:** Detect to see if there are any elements under/to the sides of
non-full-width elements.
You may notice a lot of terminal apps (e.g. mutt, irssi, vim, ncmpcpp) don't
have sidebars, and only have "elements" that take up the entire width of the
screen. The reason for this is speed (and general cleanliness). VT-like

View File

@ -581,14 +581,21 @@ Screen.prototype.blankLine = function(ch, dirty) {
};
Screen.prototype.insertLine = function(n, y, top, bottom) {
this.program.csr(top, bottom);
this.program.cup(y, 0);
this.program.il(1);
this.program.csr(0, this.height - 1);
this.program.cup(y, 0);
if (!this.tput
|| !this.tput.strings.change_scroll_region
|| !this.tput.strings.delete_line
|| !this.tput.strings.insert_line) return;
if (n < 1) n = 1;
this.program.saveCursor();
this.program.csr(top, bottom);
this.program.cup(y, 0);
this.program.il(n);
this.program.csr(0, this.height - 1);
this.program.cup(y, 0);
this.program.restoreCursor();
var j = this.rows - 1 - bottom;
j = this.rows - 1 - j + 1;
@ -601,14 +608,21 @@ Screen.prototype.insertLine = function(n, y, top, bottom) {
};
Screen.prototype.deleteLine = function(n, y, top, bottom) {
this.program.csr(top, bottom);
this.program.cup(y, 0);
this.program.dl(1);
this.program.csr(0, this.height - 1);
this.program.cup(y, 0);
if (!this.tput
|| !this.tput.strings.change_scroll_region
|| !this.tput.strings.delete_line
|| !this.tput.strings.insert_line) return;
if (n < 1) n = 1;
this.program.saveCursor();
this.program.csr(top, bottom);
this.program.cup(y, 0);
this.program.dl(n);
this.program.csr(0, this.height - 1);
this.program.cup(y, 0);
this.program.restoreCursor();
var j = this.rows - 1 - bottom;
j = this.rows - 1 - j + 1;
@ -1953,7 +1967,7 @@ Box.prototype.insertLine = function(i, line) {
this.screen.insertLine(1,
this._lastPos.yi + (this.border ? 1 : 0) + this.padding + i,
this._lastPos.yi,
this._lastPos.yl - 1);
this._lastPos.yl - (this.border ? 1 : 0) - this.padding - 1);
}
this._clines.splice((this.childBase || 0) + (this.border ? 1 : 0) + this.padding + i, 0, line);
// OR:
@ -1973,7 +1987,7 @@ Box.prototype.deleteLine = function(i) {
this.screen.deleteLine(1,
this._lastPos.yi + (this.border ? 1 : 0) + this.padding + i,
this._lastPos.yi,
this._lastPos.yl - 1);
this._lastPos.yl - (this.border ? 1 : 0) - this.padding - 1);
reset = false;
}
this._clines.splice((this.childBase || 0) + (this.border ? 1 : 0) + this.padding + i, 1);
@ -2106,7 +2120,12 @@ ScrollableBox.prototype.__proto__ = Box.prototype;
ScrollableBox.prototype.type = 'scrollable-box';
ScrollableBox.prototype.scroll = function(offset) {
var visible = this.height - (this.border ? 2 : 0) - this.padding * 2;
var visible = this.height - (this.border ? 2 : 0) - this.padding * 2
, base = this.childBase
, d
, p
, t
, b;
// Maybe do for lists:
// if (this.items) visible = Math.min(this.items.length, visible);
@ -2120,11 +2139,11 @@ ScrollableBox.prototype.scroll = function(offset) {
}
if (this.childOffset > visible - 1) {
var d = this.childOffset - (visible - 1);
d = this.childOffset - (visible - 1);
this.childOffset -= d;
this.childBase += d;
} else if (this.childOffset < 0) {
var d = this.childOffset;
d = this.childOffset;
this.childOffset += -d;
this.childBase += d;
}
@ -2135,6 +2154,23 @@ ScrollableBox.prototype.scroll = function(offset) {
this.childBase = this.baseLimit;
}
// Optimize scrolling with CSR + IL/DL.
p = this._lastPos;
if (this.childBase !== base && p && (p.xl - p.xi) === this.screen.width) {
t = p.yi + (this.border ? 1 : 0) + this.padding;
b = p.yl - (this.border ? 1 : 0) - this.padding - 1;
d = this.childBase - base;
if (d > 0 && d < visible) {
// scrolled down
this.screen.deleteLine(d, t, t, b);
} else if (d < 0 && -d < visible) {
// scrolled up
d = -d;
this.screen.insertLine(d, t, t, b);
}
}
this.emit('scroll');
};
@ -2474,6 +2510,8 @@ function ScrollableText(options) {
this.on('parsed content', function() {
self._recalculateIndex();
});
self._recalculateIndex();
}
ScrollableText.prototype.__proto__ = ScrollableBox.prototype;