refactor wrapContent. fix/use/improve getCoords(), scroll(), hide().

This commit is contained in:
Christopher Jeffrey 2013-07-23 15:26:57 -05:00
parent 76cc6d37e7
commit da49a89b28
1 changed files with 62 additions and 43 deletions

View File

@ -439,7 +439,9 @@ Screen.prototype._listenMouse = function(el) {
// if (self.grabKeys && self.focused !== el
// && !el.hasAncestor(self.focused)) continue;
ret = el.lpos;
// Need to use _getCoords() over lpos for when the
// element is obfuscated by a scrollable parent.
ret = el._getCoords();
if (!ret) continue;
left = ret.xi;
top = ret.yi;
@ -1777,8 +1779,8 @@ Element.prototype.onScreenEvent = function(type, listener) {
Element.prototype.hide = function() {
if (this.hidden) return;
this.hidden = true;
this.clearPos();
this.hidden = true;
this.emit('hide');
var below = this.screen.history[this.screen.history.length-2];
if (below && this.screen.focused === this) below.focus();
@ -1833,9 +1835,9 @@ Element.prototype._focus = function() {
};
Element.prototype.setContent = function(content, noClear) {
if (!noClear) this.clearPos();
this.content = content || '';
this.parseContent();
if (!noClear) this.clearPos();
};
Element.prototype.parseContent = function() {
@ -1950,10 +1952,20 @@ Element.prototype._wrapContent = function(content, width) {
, margin = 0
, rtof = []
, ftor = []
, fake = [];
, fake = []
, out = []
, no = 0
, line
, align
, cap
, total
, i
, part
, esc
, j
, lines;
var lines = content.split('\n')
, out = [];
lines = content.split('\n');
if (!content) {
out.push(content);
@ -1968,9 +1980,15 @@ Element.prototype._wrapContent = function(content, width) {
if (this.type === 'textarea') margin++;
if (width > margin) width -= margin;
lines.forEach(function(line, no) {
var align = state
, cap;
for (; no < lines.length; no++) {
line = lines[no];
align = state;
//cap = null;
//total = null;
//i = null;
//part = null;
//esc = null;
//j = null;
ftor.push([]);
@ -2000,11 +2018,6 @@ Element.prototype._wrapContent = function(content, width) {
}
}
var total
, i
, part
, esc;
if (!wrap && line.length > width) {
line = line.slice(0, width);
}
@ -2018,7 +2031,7 @@ Element.prototype._wrapContent = function(content, width) {
if (++total === width) {
// Try to find a space to break on:
if (line[i] !== ' ') {
var j = i;
j = i;
while (j > i - 10 && j > 0 && line[j] !== ' ') j--;
if (line[j] === ' ') i = j + 1;
else i++;
@ -2050,19 +2063,19 @@ Element.prototype._wrapContent = function(content, width) {
// Make sure we didn't wrap the line to the very end, otherwise
// we get a pointless empty line after a newline.
if (line === '') return;
if (line === '') continue;
}
// If only an escape code got cut off, at it to `part`.
if (/^(?:\x1b[\[\d;]*m)+$/.test(line)) {
out[out.length-1] += line;
return;
continue;
}
out.push(self._align(line, width, align));
ftor[no].push(out.length - 1);
rtof.push(no);
});
}
out.rtof = rtof;
out.ftor = ftor;
@ -2103,14 +2116,16 @@ Element.prototype.removeKey = function() {
};
Element.prototype.clearPos = function() {
// if (this.lpos && !this.lpos.cleared) {
// // optimize by making sure we only clear once.
// this.lpos.cleared = true;
// this.screen.clearRegion(
// this.lpos.xi, this.lpos.xl,
// this.lpos.yi, this.lpos.yl);
// }
if (this.detached) return;
// Need to use _getCoords() over lpos here to avoid clearing
// elements which are obfuscated by a scrollable parent.
// NOTE: COULD USE THIS MULTIPLE PLACES - explanation:
// We could use this.lpos because we don't want
// to clear coordinates that may have changed and may
// not be what/where is actually rendered.
// var lpos = this._getCoords() && this.lpos;
var lpos = this._getCoords();
if (!lpos) return;
this.screen.clearRegion(
@ -3298,7 +3313,11 @@ ScrollableBox.prototype.scroll = function(offset, always) {
, d
, p
, t
, b;
, b
, i
, max
, emax
, l;
if (this.alwaysScroll || always) {
// Semi-workaround
@ -3328,15 +3347,7 @@ ScrollableBox.prototype.scroll = function(offset, always) {
// Find max "bottom" value for
// content and descendant elements.
// Scroll the content if necessary.
var diff = this.childBase - base
, w
, i
, max
, emax
, t
, l;
if (diff === 0) {
if (this.childBase === base) {
return this.emit('scroll');
}
@ -3351,7 +3362,6 @@ ScrollableBox.prototype.scroll = function(offset, always) {
if (emax < 0) emax = 0;
this.childBase = Math.min(this.childBase, Math.max(emax, max));
diff = this.childBase - base;
if (this.childBase < 0) {
this.childBase = 0;
@ -3359,20 +3369,26 @@ ScrollableBox.prototype.scroll = function(offset, always) {
this.childBase = this.baseLimit;
}
if (diff > 0) {
if (this.childBase > base) {
l = Math.min(this.childBase, this._clines.length);
for (i = base; i < l; i++) {
this.contentIndex += this._clines[i].length + 1;
}
} else {
} else if (this.childBase < base) {
b = Math.min(base, this._clines.length);
l = Math.min(this.childBase, this._clines.length);
for (i = base - 1; i >= l; i--) {
for (i = b - 1; i >= l; i--) {
this.contentIndex -= this._clines[i].length + 1;
}
}
// Optimize scrolling with CSR + IL/DL.
p = this.lpos;
// Only really need _getCoords() if we want
// to allow nestable scrolling elements...
// or if we **really** want shrinkable
// scrolling elements.
// p = this._getCoords();
if (this.childBase !== base && this.screen.cleanSides(this)) {
t = p.yi + this.itop;
b = p.yl - this.ibottom - 1;
@ -4013,8 +4029,6 @@ Textbox.prototype.type = 'textbox';
Textbox.prototype.updateCursor = function() {
if (this.screen.focused !== this) return;
//this.screen.program.cup(this.top + this.itop,
// this.left + this.ileft + this.value.length);
var lpos = this._getCoords();
if (!lpos) return;
this.screen.program.cup(lpos.yi + this.itop,
@ -5329,8 +5343,11 @@ Listbar.prototype.render = function() {
};
Listbar.prototype.select = function(offset) {
var lpos = this._getCoords();
if (!lpos) return;
var self = this
, width = this.lpos ? this.lpos.xl - this.lpos.xi : this.width
, width = lpos.xl - lpos.xi
, drawn = 0
, visible = 0
, el;
@ -5345,7 +5362,9 @@ Listbar.prototype.select = function(offset) {
this.items.forEach(function(el, i) {
if (i < self.leftBase) return;
drawn += (el.lpos ? el.lpos.xl - el.lpos.xi : el.width) + 3;
var lpos = el._getCoords();
if (!lpos) return;
drawn += (lpos.xl - lpos.xi) + 3;
if (drawn <= width) visible++;
});