allow handling of pre-wrapped text for line methods.

This commit is contained in:
Christopher Jeffrey 2013-07-23 14:10:46 -05:00
parent 6bfb47632e
commit 36c5351fde

View File

@ -1955,6 +1955,9 @@ Element.prototype._wrapContent = function(content, width) {
if (!content) {
out.push(content);
out.rtof = [0];
out.ftor = [[0]];
out.fake = lines;
return out;
}
@ -2908,123 +2911,167 @@ Box.prototype.render = function() {
return coords;
};
// Create a much more efficient rendering by using insert-line,
// delete-line, and change screen region codes when possible.
// NOTE: If someone does:
// box.left = box.right = 0;
// screen.render();
// box.left++;
// box.insertTop('foobar');
// Things will break because we're using lpos instead of _getCoords().
// Maybe lpos could be updated on .left, .right, etc setters?
Box.prototype.insertLine = function(i, line) {
var pos = this.lpos || 0;
if (typeof line === 'string') line = [line];
while (this._clines.length < i) {
this._clines.push('');
while (this._clines.fake.length < i) {
this._clines.fake.push('');
this._clines.ftor.push([this._clines.push('') - 1]);
//this._clines.rtof(this._clines.fake.length - 1);
}
if (i !== i || i == null) { //|| i >= this._clines.ftor.length) {
i = this._clines.ftor.length - 1;
}
i = Math.max(i, 0);
//i = Math.min(i, this._clines.length);
//i = Math.min(i, this._clines.fake.length);
var height = pos.yl - pos.yi - this.iheight
, base = this.childBase || 0
, visible = i >= base && i - base < height;
var start = this._clines.length
, diff
, r
, r1
, r2;
if (pos && visible && this.screen.cleanSides(this)) {
this.screen.insertLine(line.length,
pos.yi + this.itop + i - base,
pos.yi,
pos.yl - this.ibottom - 1);
if (i >= this._clines.ftor.length) {
r = this._clines.ftor[this._clines.ftor.length - 1];
r1 = r[0] + 1;
r2 = r[r.length-1] + 1;
} else {
r = this._clines.ftor[i];
r1 = r[0];
r2 = r[r.length-1];
}
line.forEach(function(line, j) {
this._clines.splice(i + j, 0, line);
this._clines.fake.splice(i + j, 0, line);
}, this);
this.setContent(this._clines.join('\n'), true);
this.setContent(this._clines.fake.join('\n'), true);
diff = this._clines.length - start;
if (diff > 0) {
var pos = this._getCoords();
if (!pos) return;
var height = pos.yl - pos.yi - this.iheight
, base = this.childBase || 0
, visible = r1 >= base && r1 - base < height;
//, visible = r1 >= base && r2 - base < height;
//if (r1 === r2)
if (pos && visible && this.screen.cleanSides(this)) {
this.screen.insertLine(diff,
pos.yi + this.itop + r1 - base,
pos.yi,
pos.yl - this.ibottom - 1);
}
}
};
Box.prototype.deleteLine = function(i, n) {
var pos = this.lpos || 0;
n = n || 1;
i = Math.max(i, 0);
i = Math.min(i, this._clines.length - 1);
var height = pos.yl - pos.yi - this.iheight
, base = this.childBase || 0
, visible = i >= base && i - base < height;
if (pos && visible && this.screen.cleanSides(this)) {
this.screen.deleteLine(n,
pos.yi + this.itop + i - base,
pos.yi,
pos.yl - this.ibottom - 1);
if (i !== i || i == null || i >= this._clines.ftor.length) {
i = this._clines.ftor.length - 1;
}
i = Math.max(i, 0);
i = Math.min(i, this._clines.ftor.length - 1);
var start = this._clines.length
, diff
, r = this._clines.ftor[i]
, r1 = r[0]
, r2 = r[r.length-1];
while (n--) {
this._clines.splice(i, 1);
this._clines.fake.splice(i, 1);
}
this.setContent(this._clines.fake.join('\n'), true);
diff = start - this._clines.length;
if (diff > 0) {
var pos = this._getCoords();
if (!pos) return;
var height = pos.yl - pos.yi - this.iheight
, base = this.childBase || 0
, visible = r1 >= base && r1 - base < height;
//, visible = r1 >= base && r2 - base < height;
//if (r1 === r2)
if (pos && visible && this.screen.cleanSides(this)) {
this.screen.deleteLine(diff,
pos.yi + this.itop + r1 - base,
pos.yi,
pos.yl - this.ibottom - 1);
}
}
this.setContent(this._clines.join('\n'), true);
if (this._clines.length < height) {
this.clearPos();
}
};
Box.prototype.insertTop = function(line) {
return this.insertLine((this.childBase || 0) + 0, line);
var fake = this._clines.rtof[this.childBase || 0];
return this.insertLine(fake, line);
};
Box.prototype.insertBottom = function(line) {
var h = (this.childBase || 0) + this.height - this.iheight
, i = Math.min(h, this._clines.length);
, i = Math.min(h, this._clines.length)
, fake = this._clines.rtof[i - 1] + 1;
return this.insertLine(i, line);
return this.insertLine(fake, line);
};
Box.prototype.deleteTop = function(n) {
return this.deleteLine((this.childBase || 0) + 0, n);
var fake = this._clines.rtof[this.childBase || 0];
return this.deleteLine(fake, n);
};
Box.prototype.deleteBottom = function(n) {
var h = (this.childBase || 0) + this.height - 1 - this.iheight
, i = Math.min(h, this._clines.length - 1)
, n = n || 1;
, n = n || 1
, fake = this._clines.rtof[i];
return this.deleteLine(i - (n - 1), n);
return this.deleteLine(fake - (n - 1), n);
};
Box.prototype.setLine = function(i, line) {
while (this._clines.length < i) {
this._clines.push('');
while (this._clines.fake.length < i) {
this._clines.fake.push('');
}
i = Math.max(i, 0);
//i = Math.min(i, this._clines.length);
this._clines[i] = line;
return this.setContent(this._clines.join('\n'), true);
//i = Math.min(i, this._clines.fake.length);
this._clines.fake[i] = line;
return this.setContent(this._clines.fake.join('\n'), true);
};
Box.prototype.setBaseLine = function(i, line) {
return this.setLine((this.childBase || 0) + i, line);
var fake = this._clines.rtof[this.childBase || 0];
return this.setLine(fake + i, line);
};
Box.prototype.getLine = function(i) {
i = Math.max(i, 0);
i = Math.min(i, this._clines.length - 1);
return this._clines[i];
i = Math.min(i, this._clines.fake.length - 1);
return this._clines.fake[i];
};
Box.prototype.getBaseLine = function(i) {
return this.getLine((this.childBase || 0) + i);
var fake = this._clines.rtof[this.childBase || 0];
return this.getLine(fake + i);
};
Box.prototype.clearLine = function(i) {
i = Math.min(i, this._clines.length - 1);
i = Math.min(i, this._clines.fake.length - 1);
return this.setLine(i, '');
};
@ -3037,11 +3084,11 @@ Box.prototype.shiftLine = function(n) {
};
Box.prototype.pushLine = function(line) {
return this.insertLine(this._clines.length, line);
return this.insertLine(this._clines.fake.length, line);
};
Box.prototype.popLine = function(n) {
return this.deleteLine(this._clines.length - 1, n);
return this.deleteLine(this._clines.fake.length - 1, n);
};
/**