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
|
||||
// && !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++;
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue