refactor wrapContent. fix/use/improve getCoords(), scroll(), hide().
This commit is contained in:
parent
76cc6d37e7
commit
da49a89b28
105
lib/widget.js
105
lib/widget.js
|
@ -439,7 +439,9 @@ Screen.prototype._listenMouse = function(el) {
|
||||||
// if (self.grabKeys && self.focused !== el
|
// if (self.grabKeys && self.focused !== el
|
||||||
// && !el.hasAncestor(self.focused)) continue;
|
// && !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;
|
if (!ret) continue;
|
||||||
left = ret.xi;
|
left = ret.xi;
|
||||||
top = ret.yi;
|
top = ret.yi;
|
||||||
|
@ -1777,8 +1779,8 @@ Element.prototype.onScreenEvent = function(type, listener) {
|
||||||
|
|
||||||
Element.prototype.hide = function() {
|
Element.prototype.hide = function() {
|
||||||
if (this.hidden) return;
|
if (this.hidden) return;
|
||||||
this.hidden = true;
|
|
||||||
this.clearPos();
|
this.clearPos();
|
||||||
|
this.hidden = true;
|
||||||
this.emit('hide');
|
this.emit('hide');
|
||||||
var below = this.screen.history[this.screen.history.length-2];
|
var below = this.screen.history[this.screen.history.length-2];
|
||||||
if (below && this.screen.focused === this) below.focus();
|
if (below && this.screen.focused === this) below.focus();
|
||||||
|
@ -1833,9 +1835,9 @@ Element.prototype._focus = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
Element.prototype.setContent = function(content, noClear) {
|
Element.prototype.setContent = function(content, noClear) {
|
||||||
|
if (!noClear) this.clearPos();
|
||||||
this.content = content || '';
|
this.content = content || '';
|
||||||
this.parseContent();
|
this.parseContent();
|
||||||
if (!noClear) this.clearPos();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Element.prototype.parseContent = function() {
|
Element.prototype.parseContent = function() {
|
||||||
|
@ -1950,10 +1952,20 @@ Element.prototype._wrapContent = function(content, width) {
|
||||||
, margin = 0
|
, margin = 0
|
||||||
, rtof = []
|
, rtof = []
|
||||||
, ftor = []
|
, ftor = []
|
||||||
, fake = [];
|
, fake = []
|
||||||
|
, out = []
|
||||||
|
, no = 0
|
||||||
|
, line
|
||||||
|
, align
|
||||||
|
, cap
|
||||||
|
, total
|
||||||
|
, i
|
||||||
|
, part
|
||||||
|
, esc
|
||||||
|
, j
|
||||||
|
, lines;
|
||||||
|
|
||||||
var lines = content.split('\n')
|
lines = content.split('\n');
|
||||||
, out = [];
|
|
||||||
|
|
||||||
if (!content) {
|
if (!content) {
|
||||||
out.push(content);
|
out.push(content);
|
||||||
|
@ -1968,9 +1980,15 @@ Element.prototype._wrapContent = function(content, width) {
|
||||||
if (this.type === 'textarea') margin++;
|
if (this.type === 'textarea') margin++;
|
||||||
if (width > margin) width -= margin;
|
if (width > margin) width -= margin;
|
||||||
|
|
||||||
lines.forEach(function(line, no) {
|
for (; no < lines.length; no++) {
|
||||||
var align = state
|
line = lines[no];
|
||||||
, cap;
|
align = state;
|
||||||
|
//cap = null;
|
||||||
|
//total = null;
|
||||||
|
//i = null;
|
||||||
|
//part = null;
|
||||||
|
//esc = null;
|
||||||
|
//j = null;
|
||||||
|
|
||||||
ftor.push([]);
|
ftor.push([]);
|
||||||
|
|
||||||
|
@ -2000,11 +2018,6 @@ Element.prototype._wrapContent = function(content, width) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var total
|
|
||||||
, i
|
|
||||||
, part
|
|
||||||
, esc;
|
|
||||||
|
|
||||||
if (!wrap && line.length > width) {
|
if (!wrap && line.length > width) {
|
||||||
line = line.slice(0, width);
|
line = line.slice(0, width);
|
||||||
}
|
}
|
||||||
|
@ -2018,7 +2031,7 @@ Element.prototype._wrapContent = function(content, width) {
|
||||||
if (++total === width) {
|
if (++total === width) {
|
||||||
// Try to find a space to break on:
|
// Try to find a space to break on:
|
||||||
if (line[i] !== ' ') {
|
if (line[i] !== ' ') {
|
||||||
var j = i;
|
j = i;
|
||||||
while (j > i - 10 && j > 0 && line[j] !== ' ') j--;
|
while (j > i - 10 && j > 0 && line[j] !== ' ') j--;
|
||||||
if (line[j] === ' ') i = j + 1;
|
if (line[j] === ' ') i = j + 1;
|
||||||
else i++;
|
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
|
// Make sure we didn't wrap the line to the very end, otherwise
|
||||||
// we get a pointless empty line after a newline.
|
// 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 only an escape code got cut off, at it to `part`.
|
||||||
if (/^(?:\x1b[\[\d;]*m)+$/.test(line)) {
|
if (/^(?:\x1b[\[\d;]*m)+$/.test(line)) {
|
||||||
out[out.length-1] += line;
|
out[out.length-1] += line;
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
out.push(self._align(line, width, align));
|
out.push(self._align(line, width, align));
|
||||||
ftor[no].push(out.length - 1);
|
ftor[no].push(out.length - 1);
|
||||||
rtof.push(no);
|
rtof.push(no);
|
||||||
});
|
}
|
||||||
|
|
||||||
out.rtof = rtof;
|
out.rtof = rtof;
|
||||||
out.ftor = ftor;
|
out.ftor = ftor;
|
||||||
|
@ -2103,14 +2116,16 @@ Element.prototype.removeKey = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
Element.prototype.clearPos = 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;
|
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();
|
var lpos = this._getCoords();
|
||||||
if (!lpos) return;
|
if (!lpos) return;
|
||||||
this.screen.clearRegion(
|
this.screen.clearRegion(
|
||||||
|
@ -3298,7 +3313,11 @@ ScrollableBox.prototype.scroll = function(offset, always) {
|
||||||
, d
|
, d
|
||||||
, p
|
, p
|
||||||
, t
|
, t
|
||||||
, b;
|
, b
|
||||||
|
, i
|
||||||
|
, max
|
||||||
|
, emax
|
||||||
|
, l;
|
||||||
|
|
||||||
if (this.alwaysScroll || always) {
|
if (this.alwaysScroll || always) {
|
||||||
// Semi-workaround
|
// Semi-workaround
|
||||||
|
@ -3328,15 +3347,7 @@ ScrollableBox.prototype.scroll = function(offset, always) {
|
||||||
// Find max "bottom" value for
|
// Find max "bottom" value for
|
||||||
// content and descendant elements.
|
// content and descendant elements.
|
||||||
// Scroll the content if necessary.
|
// Scroll the content if necessary.
|
||||||
var diff = this.childBase - base
|
if (this.childBase === base) {
|
||||||
, w
|
|
||||||
, i
|
|
||||||
, max
|
|
||||||
, emax
|
|
||||||
, t
|
|
||||||
, l;
|
|
||||||
|
|
||||||
if (diff === 0) {
|
|
||||||
return this.emit('scroll');
|
return this.emit('scroll');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3351,7 +3362,6 @@ ScrollableBox.prototype.scroll = function(offset, always) {
|
||||||
if (emax < 0) emax = 0;
|
if (emax < 0) emax = 0;
|
||||||
|
|
||||||
this.childBase = Math.min(this.childBase, Math.max(emax, max));
|
this.childBase = Math.min(this.childBase, Math.max(emax, max));
|
||||||
diff = this.childBase - base;
|
|
||||||
|
|
||||||
if (this.childBase < 0) {
|
if (this.childBase < 0) {
|
||||||
this.childBase = 0;
|
this.childBase = 0;
|
||||||
|
@ -3359,20 +3369,26 @@ ScrollableBox.prototype.scroll = function(offset, always) {
|
||||||
this.childBase = this.baseLimit;
|
this.childBase = this.baseLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (diff > 0) {
|
if (this.childBase > base) {
|
||||||
l = Math.min(this.childBase, this._clines.length);
|
l = Math.min(this.childBase, this._clines.length);
|
||||||
for (i = base; i < l; i++) {
|
for (i = base; i < l; i++) {
|
||||||
this.contentIndex += this._clines[i].length + 1;
|
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);
|
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;
|
this.contentIndex -= this._clines[i].length + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optimize scrolling with CSR + IL/DL.
|
// Optimize scrolling with CSR + IL/DL.
|
||||||
p = this.lpos;
|
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)) {
|
if (this.childBase !== base && this.screen.cleanSides(this)) {
|
||||||
t = p.yi + this.itop;
|
t = p.yi + this.itop;
|
||||||
b = p.yl - this.ibottom - 1;
|
b = p.yl - this.ibottom - 1;
|
||||||
|
@ -4013,8 +4029,6 @@ Textbox.prototype.type = 'textbox';
|
||||||
|
|
||||||
Textbox.prototype.updateCursor = function() {
|
Textbox.prototype.updateCursor = function() {
|
||||||
if (this.screen.focused !== this) return;
|
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();
|
var lpos = this._getCoords();
|
||||||
if (!lpos) return;
|
if (!lpos) return;
|
||||||
this.screen.program.cup(lpos.yi + this.itop,
|
this.screen.program.cup(lpos.yi + this.itop,
|
||||||
|
@ -5329,8 +5343,11 @@ Listbar.prototype.render = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
Listbar.prototype.select = function(offset) {
|
Listbar.prototype.select = function(offset) {
|
||||||
|
var lpos = this._getCoords();
|
||||||
|
if (!lpos) return;
|
||||||
|
|
||||||
var self = this
|
var self = this
|
||||||
, width = this.lpos ? this.lpos.xl - this.lpos.xi : this.width
|
, width = lpos.xl - lpos.xi
|
||||||
, drawn = 0
|
, drawn = 0
|
||||||
, visible = 0
|
, visible = 0
|
||||||
, el;
|
, el;
|
||||||
|
@ -5345,7 +5362,9 @@ Listbar.prototype.select = function(offset) {
|
||||||
|
|
||||||
this.items.forEach(function(el, i) {
|
this.items.forEach(function(el, i) {
|
||||||
if (i < self.leftBase) return;
|
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++;
|
if (drawn <= width) visible++;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue