mirror of
https://github.com/embarklabs/neo-blessed.git
synced 2025-01-24 01:38:54 +00:00
docs. smartCSR option. minor fixes.
This commit is contained in:
parent
158572ae38
commit
51413c346e
@ -152,6 +152,11 @@ The base node which everything inherits from.
|
||||
- **prepend(node)** - prepend a node to this node's children.
|
||||
- **append(node)** - append a node to this node's children.
|
||||
- **remove(node)** - remove child node from node.
|
||||
- **insert(node, i)** - insert a node to this node's children at index `i`.
|
||||
- **insertBefore(node, refNode)** - insert a node to this node's children
|
||||
before the reference node.
|
||||
- **insertAfter(node, refNode)** - insert a node from node after the reference
|
||||
node.
|
||||
- **detach()** - remove node from its parent.
|
||||
- **emitDescendants(type, args..., [iterator])** - emit event for element, and
|
||||
recursively emit same event for all descendants.
|
||||
@ -166,6 +171,10 @@ The screen on which every other node renders.
|
||||
##### Options:
|
||||
|
||||
- **program** - the blessed Program to be associated with.
|
||||
- **smartCSR** - attempt to perform CSR optimization on all possible elements
|
||||
(not just full-width ones, elements with uniform cells to their sides).
|
||||
this is known to cause flickering with elements that are not full-width,
|
||||
however, it is more optimal for terminal rendering.
|
||||
|
||||
##### Properties:
|
||||
|
||||
|
251
lib/widget.js
251
lib/widget.js
@ -310,6 +310,7 @@ function Screen(options) {
|
||||
|
||||
this.program.alternateBuffer();
|
||||
this.program.hideCursor();
|
||||
this.program.cup(0, 0);
|
||||
this.alloc();
|
||||
|
||||
function reset() {
|
||||
@ -591,7 +592,6 @@ Screen.prototype.insertLine = function(n, y, 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;
|
||||
@ -618,7 +618,6 @@ Screen.prototype.deleteLine = function(n, y, 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;
|
||||
@ -673,6 +672,10 @@ Screen.prototype.cleanSides = function(el) {
|
||||
return pos._cleanSides = true;
|
||||
}
|
||||
|
||||
if (!this.options.smartCSR) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var yi = pos.yi + (el.border ? 1 : 0) + el.padding
|
||||
, yl = pos.yl - (el.border ? 1 : 0) - el.padding
|
||||
, first
|
||||
@ -881,6 +884,157 @@ Screen.prototype._reduceColor = function(col) {
|
||||
return col;
|
||||
};
|
||||
|
||||
// Convert an SGR string to our own attribute format.
|
||||
Screen.prototype.attrCode = function(code, cur) {
|
||||
var flags = (cur >> 18) & 0x1ff
|
||||
, fg = (cur >> 9) & 0x1ff
|
||||
, bg = cur & 0x1ff
|
||||
, c
|
||||
, i;
|
||||
|
||||
code = /^\x1b\[([\d;]*)m$/.exec(code);
|
||||
if (!code) return cur;
|
||||
|
||||
code = code[1].split(';');
|
||||
if (!code[0]) code[0] = '0';
|
||||
|
||||
for (i = 0; i < code.length; i++) {
|
||||
c = +code[i] || 0;
|
||||
switch (c) {
|
||||
case 0: // normal
|
||||
bg = 0x1ff;
|
||||
fg = 0x1ff;
|
||||
flags = 0;
|
||||
break;
|
||||
case 1: // bold
|
||||
flags |= 1;
|
||||
break;
|
||||
case 22:
|
||||
flags &= ~1;
|
||||
break;
|
||||
case 4: // underline
|
||||
flags |= 2;
|
||||
break;
|
||||
case 24:
|
||||
flags &= ~2;
|
||||
break;
|
||||
case 5: // blink
|
||||
flags |= 4;
|
||||
break;
|
||||
case 25:
|
||||
flags &= ~4;
|
||||
break;
|
||||
case 7: // inverse
|
||||
flags |= 8;
|
||||
break;
|
||||
case 27:
|
||||
flags &= ~8;
|
||||
break;
|
||||
case 8: // invisible
|
||||
flags |= 16;
|
||||
break;
|
||||
case 28:
|
||||
flags &= ~16;
|
||||
break;
|
||||
default: // color
|
||||
if (c === 48 && code[i+1] === '5') {
|
||||
i += 2;
|
||||
bg = +code[i];
|
||||
break;
|
||||
} else if (c === 38 && code[i+1] === '5') {
|
||||
i += 2;
|
||||
fg = +code[i];
|
||||
break;
|
||||
}
|
||||
if (c >= 40 && c <= 47) {
|
||||
bg = c - 40;
|
||||
} else if (c >= 100 && c <= 107) {
|
||||
bg = c - 100;
|
||||
bg += 8;
|
||||
} else if (c === 49) {
|
||||
bg = 0x1ff;
|
||||
} else if (c >= 30 && c <= 37) {
|
||||
fg = c - 30;
|
||||
} else if (c >= 90 && c <= 97) {
|
||||
fg = c - 90;
|
||||
fg += 8;
|
||||
} else if (c === 39) {
|
||||
fg = 0x1ff;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (flags << 18) | (fg << 9) | bg;
|
||||
};
|
||||
|
||||
// Convert our own attribute format to an SGR string.
|
||||
Screen.prototype.codeAttr = function(code) {
|
||||
var flags = (code >> 18) & 0x1ff
|
||||
, fg = (code >> 9) & 0x1ff
|
||||
, bg = code & 0x1ff
|
||||
, out = '';
|
||||
|
||||
// bold
|
||||
if (flags & 1) {
|
||||
out += '1;';
|
||||
}
|
||||
|
||||
// underline
|
||||
if (flags & 2) {
|
||||
out += '4;';
|
||||
}
|
||||
|
||||
// blink
|
||||
if (flags & 4) {
|
||||
out += '5;';
|
||||
}
|
||||
|
||||
// inverse
|
||||
if (flags & 8) {
|
||||
out += '7;';
|
||||
}
|
||||
|
||||
// invisible
|
||||
if (flags & 16) {
|
||||
out += '8;';
|
||||
}
|
||||
|
||||
if (bg !== 0x1ff) {
|
||||
bg = this._reduceColor(bg);
|
||||
if (bg < 16) {
|
||||
if (bg < 8) {
|
||||
bg += 40;
|
||||
} else if (bg < 16) {
|
||||
bg -= 8;
|
||||
bg += 100;
|
||||
}
|
||||
out += bg + ';';
|
||||
} else {
|
||||
out += '48;5;' + bg + ';';
|
||||
}
|
||||
}
|
||||
|
||||
if (fg !== 0x1ff) {
|
||||
fg = this._reduceColor(fg);
|
||||
if (fg < 16) {
|
||||
if (fg < 8) {
|
||||
fg += 30;
|
||||
} else if (fg < 16) {
|
||||
fg -= 8;
|
||||
fg += 90;
|
||||
}
|
||||
out += fg + ';';
|
||||
} else {
|
||||
out += '38;5;' + fg + ';';
|
||||
}
|
||||
}
|
||||
|
||||
if (out[out.length-1] === ';') out = out.slice(0, -1);
|
||||
|
||||
return '\x1b[' + out + 'm';
|
||||
};
|
||||
|
||||
Screen.prototype.focus = function(offset) {
|
||||
var shown = this.input.filter(function(el) {
|
||||
return el.visible;
|
||||
@ -1827,7 +1981,7 @@ Box.prototype.render = function(stop) {
|
||||
for (; cci < ci; cci++) {
|
||||
if (content[cci] === '\x1b') {
|
||||
if (c = /^\x1b\[[\d;]*m/.exec(content.substring(cci))) {
|
||||
attr = attrCode(c[0], attr);
|
||||
attr = this.screen.attrCode(c[0], attr);
|
||||
cci += c[0].length - 1;
|
||||
}
|
||||
}
|
||||
@ -1854,7 +2008,7 @@ outer:
|
||||
while (ch === '\x1b') {
|
||||
if (c = /^\x1b\[[\d;]*m/.exec(content.substring(ci - 1))) {
|
||||
ci += c[0].length - 1;
|
||||
attr = attrCode(c[0], attr);
|
||||
attr = this.screen.attrCode(c[0], attr);
|
||||
ch = content[ci] || ' ';
|
||||
ci++;
|
||||
} else {
|
||||
@ -2216,6 +2370,9 @@ ScrollableBox.prototype.scroll = function(offset) {
|
||||
b = p.yl - (this.border ? 1 : 0) - this.padding - 1;
|
||||
d = this.childBase - base;
|
||||
|
||||
// var attr = this.screen.olines[t][p.xi + (this.border ? 1 : 0) + this.padding][0];
|
||||
// this.screen.program.write(this.screen.codeAttr(attr, this.screen));
|
||||
|
||||
if (d > 0 && d < visible) {
|
||||
// scrolled down
|
||||
this.screen.deleteLine(d, t, t, b);
|
||||
@ -2224,6 +2381,8 @@ ScrollableBox.prototype.scroll = function(offset) {
|
||||
d = -d;
|
||||
this.screen.insertLine(d, t, t, b);
|
||||
}
|
||||
|
||||
// this.screen.program.sgr0();
|
||||
}
|
||||
|
||||
this.emit('scroll');
|
||||
@ -3917,90 +4076,6 @@ Passbox.prototype.type = 'passbox';
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
// Convert an SGR string to our own attribute format.
|
||||
function attrCode(code, cur) {
|
||||
var flags = (cur >> 18) & 0x1ff
|
||||
, fg = (cur >> 9) & 0x1ff
|
||||
, bg = cur & 0x1ff
|
||||
, c
|
||||
, i;
|
||||
|
||||
code = /^\x1b\[([\d;]*)m$/.exec(code);
|
||||
if (!code) return cur;
|
||||
|
||||
code = code[1].split(';');
|
||||
if (!code[0]) code[0] = '0';
|
||||
|
||||
for (i = 0; i < code.length; i++) {
|
||||
c = +code[i] || 0;
|
||||
switch (c) {
|
||||
case 0: // normal
|
||||
bg = 0x1ff;
|
||||
fg = 0x1ff;
|
||||
flags = 0;
|
||||
break;
|
||||
case 1: // bold
|
||||
flags |= 1;
|
||||
break;
|
||||
case 22:
|
||||
flags &= ~1;
|
||||
break;
|
||||
case 4: // underline
|
||||
flags |= 2;
|
||||
break;
|
||||
case 24:
|
||||
flags &= ~2;
|
||||
break;
|
||||
case 5: // blink
|
||||
flags |= 4;
|
||||
break;
|
||||
case 25:
|
||||
flags &= ~4;
|
||||
break;
|
||||
case 7: // inverse
|
||||
flags |= 8;
|
||||
break;
|
||||
case 27:
|
||||
flags &= ~8;
|
||||
break;
|
||||
case 8: // invisible
|
||||
flags |= 16;
|
||||
break;
|
||||
case 28:
|
||||
flags &= ~16;
|
||||
break;
|
||||
default: // color
|
||||
if (c === 48 && code[i+1] === '5') {
|
||||
i += 2;
|
||||
bg = +code[i];
|
||||
break;
|
||||
} else if (c === 38 && code[i+1] === '5') {
|
||||
i += 2;
|
||||
fg = +code[i];
|
||||
break;
|
||||
}
|
||||
if (c >= 40 && c <= 47) {
|
||||
bg = c - 40;
|
||||
} else if (c >= 100 && c <= 107) {
|
||||
bg = c - 100;
|
||||
bg += 8;
|
||||
} else if (c === 49) {
|
||||
bg = 0x1ff;
|
||||
} else if (c >= 30 && c <= 37) {
|
||||
fg = c - 30;
|
||||
} else if (c >= 90 && c <= 97) {
|
||||
fg = c - 90;
|
||||
fg += 8;
|
||||
} else if (c === 39) {
|
||||
fg = 0x1ff;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (flags << 18) | (fg << 9) | bg;
|
||||
}
|
||||
|
||||
function sp(line, width, align) {
|
||||
if (!align) return line;
|
||||
|
||||
|
@ -1,5 +1,10 @@
|
||||
var blessed = require('blessed')
|
||||
, screen = blessed.screen({ dump: __dirname + '/p.log' });
|
||||
, screen;
|
||||
|
||||
screen = blessed.screen({
|
||||
dump: __dirname + '/p.log',
|
||||
smartCSR: true
|
||||
});
|
||||
|
||||
var lorem = require('fs').readFileSync(__dirname + '/git.diff', 'utf8');
|
||||
|
||||
@ -16,6 +21,7 @@ function expectClean(value) {
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
blessed.box({
|
||||
parent: screen,
|
||||
left: 0,
|
||||
@ -26,8 +32,8 @@ blessed.box({
|
||||
content: 'This will disallow CSR.'
|
||||
});
|
||||
expectClean(false);
|
||||
*/
|
||||
|
||||
/*
|
||||
blessed.box({
|
||||
parent: screen,
|
||||
left: 'center',
|
||||
@ -41,7 +47,6 @@ blessed.box({
|
||||
content: 'CSR should still work.'
|
||||
});
|
||||
expectClean(true);
|
||||
*/
|
||||
|
||||
var text = blessed.scrollabletext({
|
||||
parent: screen,
|
||||
|
Loading…
x
Reference in New Issue
Block a user