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 ### 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 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 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 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) { Screen.prototype.insertLine = function(n, y, top, bottom) {
this.program.csr(top, bottom); if (!this.tput
this.program.cup(y, 0); || !this.tput.strings.change_scroll_region
this.program.il(1); || !this.tput.strings.delete_line
this.program.csr(0, this.height - 1); || !this.tput.strings.insert_line) return;
this.program.cup(y, 0);
if (n < 1) n = 1; 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; var j = this.rows - 1 - bottom;
j = this.rows - 1 - j + 1; 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) { Screen.prototype.deleteLine = function(n, y, top, bottom) {
this.program.csr(top, bottom); if (!this.tput
this.program.cup(y, 0); || !this.tput.strings.change_scroll_region
this.program.dl(1); || !this.tput.strings.delete_line
this.program.csr(0, this.height - 1); || !this.tput.strings.insert_line) return;
this.program.cup(y, 0);
if (n < 1) n = 1; 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; var j = this.rows - 1 - bottom;
j = this.rows - 1 - j + 1; j = this.rows - 1 - j + 1;
@ -1953,7 +1967,7 @@ Box.prototype.insertLine = function(i, line) {
this.screen.insertLine(1, this.screen.insertLine(1,
this._lastPos.yi + (this.border ? 1 : 0) + this.padding + i, this._lastPos.yi + (this.border ? 1 : 0) + this.padding + i,
this._lastPos.yi, 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); this._clines.splice((this.childBase || 0) + (this.border ? 1 : 0) + this.padding + i, 0, line);
// OR: // OR:
@ -1973,7 +1987,7 @@ Box.prototype.deleteLine = function(i) {
this.screen.deleteLine(1, this.screen.deleteLine(1,
this._lastPos.yi + (this.border ? 1 : 0) + this.padding + i, this._lastPos.yi + (this.border ? 1 : 0) + this.padding + i,
this._lastPos.yi, this._lastPos.yi,
this._lastPos.yl - 1); this._lastPos.yl - (this.border ? 1 : 0) - this.padding - 1);
reset = false; reset = false;
} }
this._clines.splice((this.childBase || 0) + (this.border ? 1 : 0) + this.padding + i, 1); 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.type = 'scrollable-box';
ScrollableBox.prototype.scroll = function(offset) { 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: // Maybe do for lists:
// if (this.items) visible = Math.min(this.items.length, visible); // if (this.items) visible = Math.min(this.items.length, visible);
@ -2120,11 +2139,11 @@ ScrollableBox.prototype.scroll = function(offset) {
} }
if (this.childOffset > visible - 1) { if (this.childOffset > visible - 1) {
var d = this.childOffset - (visible - 1); d = this.childOffset - (visible - 1);
this.childOffset -= d; this.childOffset -= d;
this.childBase += d; this.childBase += d;
} else if (this.childOffset < 0) { } else if (this.childOffset < 0) {
var d = this.childOffset; d = this.childOffset;
this.childOffset += -d; this.childOffset += -d;
this.childBase += d; this.childBase += d;
} }
@ -2135,6 +2154,23 @@ ScrollableBox.prototype.scroll = function(offset) {
this.childBase = this.baseLimit; 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'); this.emit('scroll');
}; };
@ -2474,6 +2510,8 @@ function ScrollableText(options) {
this.on('parsed content', function() { this.on('parsed content', function() {
self._recalculateIndex(); self._recalculateIndex();
}); });
self._recalculateIndex();
} }
ScrollableText.prototype.__proto__ = ScrollableBox.prototype; ScrollableText.prototype.__proto__ = ScrollableBox.prototype;