readme, tput, mouse, types, misc.
This commit is contained in:
parent
07334af6fc
commit
77593efd05
35
README.md
35
README.md
|
@ -572,6 +572,41 @@ Elements are rendered with the lower elements in the children array being
|
|||
painted first. In terms of the painter's algorithm, the lowest indicies in the
|
||||
array are the furthest away, just like in the DOM.
|
||||
|
||||
### Optimization and CSR
|
||||
|
||||
You may notice a lot of terminal apps (e.g. mutt, irssi, vim, ncmpcpp) don't
|
||||
have sidebars, and only have "elements" that take up the entire width of the
|
||||
screen. The reason for this is speed (and general cleanliness). VT-like
|
||||
terminals have something called a CSR (change_scroll_region) code, as well as
|
||||
IL (insert_line), and DL (delete_code) codes. Using these three codes, it is
|
||||
possible to create a very efficient rendering by avoiding redrawing the entire
|
||||
screen when a line is inserted or removed. Since blessed is extremely dynamic,
|
||||
it is hard to do this optimization automatically (blessed assumes you may
|
||||
create any element of any width in any position). So, there is a solution:
|
||||
|
||||
``` js
|
||||
var box = new blessed.Box(...);
|
||||
box.setContent('line 1\nline 2');
|
||||
box.insertBottom('line 3');
|
||||
box.insertBottom('line 4');
|
||||
box.insertTop('line 0');
|
||||
```
|
||||
|
||||
If your element has the same width as the screen, the line insertion will be
|
||||
optimized by using a combination CSR/IL/DL codes. These methods may be made
|
||||
smarter in the future to detect whether any elements are being overlapped to
|
||||
the sides.
|
||||
|
||||
Outputting:
|
||||
|
||||
```
|
||||
| line 0 |
|
||||
| line 1 |
|
||||
| line 2 |
|
||||
| line 3 |
|
||||
| line 4 |
|
||||
```
|
||||
|
||||
### Testing
|
||||
|
||||
- For an interactive test, see `test/widget.js`.
|
||||
|
|
145
lib/program.js
145
lib/program.js
|
@ -834,7 +834,7 @@ Program.prototype.nextLine = function() {
|
|||
// ESC c Full Reset (RIS).
|
||||
Program.prototype.reset = function() {
|
||||
//this.x = this.y = 1;
|
||||
if (this.tput) return this.put.ris();
|
||||
if (this.tput) return this.put.rs1 ? this.put.rs1() : this.put.ris();
|
||||
return this.write('\x1bc');
|
||||
};
|
||||
|
||||
|
@ -848,7 +848,7 @@ Program.prototype.tabSet = function() {
|
|||
Program.prototype.saveCursor = function() {
|
||||
this.savedX = this.x || 1;
|
||||
this.savedY = this.y || 1;
|
||||
if (this.tput) return this.put.sc(); // not correct
|
||||
if (this.tput) return this.put.sc();
|
||||
return this.esc('7');
|
||||
};
|
||||
|
||||
|
@ -856,7 +856,7 @@ Program.prototype.saveCursor = function() {
|
|||
Program.prototype.restoreCursor = function() {
|
||||
this.x = this.savedX || 1;
|
||||
this.y = this.savedY || 1;
|
||||
if (this.tput) return this.put.rc(); // not correct
|
||||
if (this.tput) return this.put.rc();
|
||||
return this.esc('8');
|
||||
};
|
||||
|
||||
|
@ -869,6 +869,13 @@ Program.prototype.lineHeight = function() {
|
|||
Program.prototype.charset = function(val, level) {
|
||||
level = level || 0;
|
||||
|
||||
// See also:
|
||||
// acs_chars / acsc / ac
|
||||
// enter_alt_charset_mode / smacs / as
|
||||
// exit_alt_charset_mode / rmacs / ae
|
||||
// enter_pc_charset_mode / smpch / S2
|
||||
// exit_pc_charset_mode / rmpch / S3
|
||||
|
||||
// tput: TODO
|
||||
// if (this.tput) return this.put('s' + level, val);
|
||||
|
||||
|
@ -889,12 +896,16 @@ Program.prototype.charset = function(val, level) {
|
|||
|
||||
switch (val) {
|
||||
case 'SCLD': // DEC Special Character and Line Drawing Set.
|
||||
if (this.tput) return this.put.smacs();
|
||||
val = '0';
|
||||
break;
|
||||
case 'UK': // UK
|
||||
val = 'A';
|
||||
break;
|
||||
case 'US': // United States (USASCII).
|
||||
case 'USASCII':
|
||||
case 'ASCII':
|
||||
if (this.tput) return this.put.rmacs();
|
||||
val = 'B';
|
||||
break;
|
||||
case 'Dutch': // Dutch
|
||||
|
@ -934,6 +945,7 @@ Program.prototype.charset = function(val, level) {
|
|||
val = '/A';
|
||||
break;
|
||||
default: // Default
|
||||
if (this.tput) return this.put.rmacs();
|
||||
val = 'B';
|
||||
break;
|
||||
}
|
||||
|
@ -941,6 +953,18 @@ Program.prototype.charset = function(val, level) {
|
|||
return this.write('\x1b(' + val);
|
||||
};
|
||||
|
||||
Program.prototype.enter_alt_charset_mode =
|
||||
Program.prototype.as =
|
||||
Program.prototype.smacs = function() {
|
||||
return this.charset('SCLD');
|
||||
};
|
||||
|
||||
Program.prototype.exit_alt_charset_mode =
|
||||
Program.prototype.ae =
|
||||
Program.prototype.rmacs = function() {
|
||||
return this.charset('US');
|
||||
};
|
||||
|
||||
// ESC N
|
||||
// Single Shift Select of G2 Character Set
|
||||
// ( SS2 is 0x8e). This affects next character only.
|
||||
|
@ -1157,6 +1181,7 @@ Program.prototype.clear = function() {
|
|||
Program.prototype.el =
|
||||
Program.prototype.eraseInLine = function(param) {
|
||||
if (this.tput) {
|
||||
//if (this.tput.back_color_erase) ...
|
||||
switch (param) {
|
||||
case 'left':
|
||||
param = 1;
|
||||
|
@ -1824,12 +1849,24 @@ Program.prototype.decset = function() {
|
|||
};
|
||||
|
||||
Program.prototype.dectcem =
|
||||
Program.prototype.cnorm =
|
||||
Program.prototype.cvvis =
|
||||
Program.prototype.showCursor = function() {
|
||||
this.cursorHidden = false;
|
||||
// NOTE: In xterm terminfo:
|
||||
// cnorm stops blinking cursor
|
||||
// cvvis starts blinking cursor
|
||||
if (this.tput) return this.put.cnorm();
|
||||
//if (this.tput) return this.put.cvvis();
|
||||
// return this.write('\x1b[?12l\x1b[?25h'); // cursor_normal
|
||||
// return this.write('\x1b[?12;25h'); // cursor_visible
|
||||
return this.setMode('?25');
|
||||
};
|
||||
|
||||
Program.prototype.alternate =
|
||||
Program.prototype.smcup =
|
||||
Program.prototype.alternateBuffer = function() {
|
||||
if (this.tput) return this.put.smcup();
|
||||
if (this.term('vt') || this.term('linux')) return;
|
||||
//return this.setMode('?47');
|
||||
//return this.setMode('?1047');
|
||||
|
@ -1932,19 +1969,26 @@ Program.prototype.decrst = function() {
|
|||
};
|
||||
|
||||
Program.prototype.dectcemh =
|
||||
Program.prototype.cursor_invisible =
|
||||
Program.prototype.vi =
|
||||
Program.prototype.civis =
|
||||
Program.prototype.hideCursor = function() {
|
||||
this.cursorHidden = true;
|
||||
if (this.tput) return this.put.civis();
|
||||
return this.resetMode('?25');
|
||||
};
|
||||
|
||||
Program.prototype.rmcup =
|
||||
Program.prototype.normalBuffer = function() {
|
||||
//return this.resetMode('?47');
|
||||
//return this.resetMode('?1047');
|
||||
if (this.tput) return this.put.rmcup();
|
||||
return this.resetMode('?1049');
|
||||
};
|
||||
|
||||
Program.prototype.enableMouse = function() {
|
||||
if (this.term('rxvt')) {
|
||||
return this.setMouse({ urxvtMouse: true });
|
||||
if (this.term('rxvt-unicode')) {
|
||||
return this.setMouse({ urxvtMouse: true }, true);
|
||||
}
|
||||
|
||||
if (this.term('xterm') || this.term('screen')) {
|
||||
|
@ -1952,35 +1996,51 @@ Program.prototype.enableMouse = function() {
|
|||
allMotion: true,
|
||||
utfMouse: true,
|
||||
sendFocus: true
|
||||
});
|
||||
}, true);
|
||||
}
|
||||
|
||||
if (this.term('vt')) {
|
||||
return this.setMouse({ vt200Mouse: true });
|
||||
return this.setMouse({ vt200Mouse: true }, true);
|
||||
}
|
||||
};
|
||||
|
||||
Program.prototype.disableMouse = function() {
|
||||
return this.setMouse({
|
||||
x10Mouse: false,
|
||||
vt200Mouse: false,
|
||||
hiliteTracking: false,
|
||||
cellMotion: false,
|
||||
allMotion: false,
|
||||
sendFocus: false,
|
||||
utfMouse: false,
|
||||
sgrMouse: false,
|
||||
urxvtMouse: false
|
||||
//return this.setMouse({
|
||||
// x10Mouse: false,
|
||||
// vt200Mouse: false,
|
||||
// hiliteTracking: false,
|
||||
// cellMotion: false,
|
||||
// allMotion: false,
|
||||
// sendFocus: false,
|
||||
// utfMouse: false,
|
||||
// sgrMouse: false,
|
||||
// urxvtMouse: false
|
||||
//}, false);
|
||||
|
||||
if (!this._currentMouse) return;
|
||||
|
||||
var obj = {};
|
||||
|
||||
Object.keys(this._currentMouse).forEach(function(key) {
|
||||
obj[key] = false;
|
||||
});
|
||||
|
||||
return this.setMouse(obj, false);
|
||||
};
|
||||
|
||||
// Set Mouse
|
||||
Program.prototype.setMouse = function(opt) {
|
||||
Program.prototype.setMouse = function(opt, enable) {
|
||||
if (opt.normalMouse != null) {
|
||||
opt.cellMotion = opt.normalMouse;
|
||||
opt.allMotion = opt.normalMouse;
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
this._currentMouse = opt;
|
||||
} else {
|
||||
delete this._currentMouse;
|
||||
}
|
||||
|
||||
// Make sure we're not a vtNNN
|
||||
if (this.term('vt')) return;
|
||||
|
||||
|
@ -2191,7 +2251,6 @@ Program.prototype.tabClear = function(param) {
|
|||
// Ps = 1 1 -> Print all pages.
|
||||
Program.prototype.mc =
|
||||
Program.prototype.mediaCopy = function() {
|
||||
// tput: TODO. See: mc0, mc5p, mc4, mc5
|
||||
//if (dec) {
|
||||
// this.write('\x1b[?' + Array.prototype.slice.call(arguments).join(';') + 'i');
|
||||
// return;
|
||||
|
@ -2199,6 +2258,34 @@ Program.prototype.mediaCopy = function() {
|
|||
return this.write('\x1b[' + Array.prototype.slice.call(arguments).join(';') + 'i');
|
||||
};
|
||||
|
||||
Program.prototype.print_screen =
|
||||
Program.prototype.ps =
|
||||
Program.prototype.mc0 = function() {
|
||||
if (this.tput) return this.put.mc0();
|
||||
return this.mc('0');
|
||||
};
|
||||
|
||||
Program.prototype.prtr_on =
|
||||
Program.prototype.po =
|
||||
Program.prototype.mc5 = function() {
|
||||
if (this.tput) return this.put.mc5();
|
||||
return this.mc('5');
|
||||
};
|
||||
|
||||
Program.prototype.prtr_off =
|
||||
Program.prototype.pf =
|
||||
Program.prototype.mc4 = function() {
|
||||
if (this.tput) return this.put.mc4();
|
||||
return this.mc('4');
|
||||
};
|
||||
|
||||
Program.prototype.prtr_non =
|
||||
Program.prototype.pO =
|
||||
Program.prototype.mc5p = function() {
|
||||
if (this.tput) return this.put.mc5p();
|
||||
return this.mc('?5');
|
||||
};
|
||||
|
||||
// CSI > Ps; Ps m
|
||||
// Set or reset resource-values used by xterm to decide whether
|
||||
// to construct escape sequences holding information about the
|
||||
|
@ -2247,8 +2334,14 @@ Program.prototype.setPointerMode = function(param) {
|
|||
// CSI ! p Soft terminal reset (DECSTR).
|
||||
// http://vt100.net/docs/vt220-rm/table4-10.html
|
||||
Program.prototype.decstr =
|
||||
Program.prototype.rs2 =
|
||||
Program.prototype.softReset = function() {
|
||||
return this.write('\x1b[!p');
|
||||
//if (this.tput) return this.put.init_2string();
|
||||
//if (this.tput) return this.put.reset_2string();
|
||||
if (this.tput) return this.put.rs2();
|
||||
//return this.write('\x1b[!p');
|
||||
//return this.write('\x1b[!p\x1b[?3;4l\x1b[4l\x1b>'); // init
|
||||
return this.write('\x1b[!p\x1b[?3;4l\x1b[4l\x1b>'); // reset
|
||||
};
|
||||
|
||||
// CSI Ps$ p
|
||||
|
@ -2643,9 +2736,17 @@ Program.prototype.selectiveEraseRectangle = function(params) {
|
|||
// The ``page'' parameter is not used by xterm, and will be omit-
|
||||
// ted.
|
||||
Program.prototype.decrqlp =
|
||||
Program.prototype.req_mouse_pos =
|
||||
Program.prototype.reqmp =
|
||||
Program.prototype.requestLocatorPosition = function(params, callback) {
|
||||
// Correct for tput?
|
||||
if (this.tput) return this.put.req_mouse_pos.apply(this.put, arguments);
|
||||
if (this.tput && this.tput.req_mouse_pos) {
|
||||
// See also:
|
||||
// get_mouse / getm / Gm
|
||||
// mouse_info / minfo / Mi
|
||||
// Correct for tput?
|
||||
var code = this.tput.req_mouse_pos.apply(this.tput, params);
|
||||
return this.receive(code, callback);
|
||||
}
|
||||
return this.receive('\x1b[' + (param || '') + '\'|', callback);
|
||||
};
|
||||
|
||||
|
|
|
@ -524,6 +524,13 @@ Tput.prototype.inject = function(info) {
|
|||
return methods[key].call(self, args);
|
||||
};
|
||||
});
|
||||
|
||||
this.info = info;
|
||||
this.all = info.all;
|
||||
this.methods = info.methods;
|
||||
this.bools = info.bools;
|
||||
this.numbers = info.numbers;
|
||||
this.strings = info.strings;
|
||||
};
|
||||
|
||||
Tput.prototype._compile = function(val) {
|
||||
|
|
130
lib/widget.js
130
lib/widget.js
|
@ -46,9 +46,12 @@ function Node(options) {
|
|||
|
||||
Node.prototype.__proto__ = EventEmitter.prototype;
|
||||
|
||||
Node.prototype.type = 'node';
|
||||
|
||||
Node.prototype.prepend = function(element) {
|
||||
var old = element.parent;
|
||||
|
||||
element.detach();
|
||||
element.parent = this;
|
||||
|
||||
if (this._isScreen && !this.focused) {
|
||||
|
@ -77,6 +80,7 @@ Node.prototype.prepend = function(element) {
|
|||
Node.prototype.append = function(element) {
|
||||
var old = element.parent;
|
||||
|
||||
element.detach();
|
||||
element.parent = this;
|
||||
|
||||
if (this._isScreen && !this.focused) {
|
||||
|
@ -260,6 +264,8 @@ Screen.global = null;
|
|||
|
||||
Screen.prototype.__proto__ = Node.prototype;
|
||||
|
||||
Screen.prototype.type = 'screen';
|
||||
|
||||
// TODO: Bubble events.
|
||||
Screen.prototype._listenMouse = function(el) {
|
||||
var self = this;
|
||||
|
@ -834,6 +840,8 @@ function Element(options) {
|
|||
|
||||
Element.prototype.__proto__ = Node.prototype;
|
||||
|
||||
Element.prototype.type = 'element';
|
||||
|
||||
/*
|
||||
Element._emit = Element.prototype.emit;
|
||||
Element.prototype.emit = function(type) {
|
||||
|
@ -1268,6 +1276,8 @@ function Box(options) {
|
|||
|
||||
Box.prototype.__proto__ = Element.prototype;
|
||||
|
||||
Box.prototype.type = 'box';
|
||||
|
||||
// TODO: Optimize. Move elsewhere.
|
||||
Box.prototype._getShrinkSize = function(content) {
|
||||
return {
|
||||
|
@ -1315,7 +1325,8 @@ Box.prototype.render = function(stop) {
|
|||
yl = yi_ + this.height;
|
||||
}
|
||||
|
||||
if (this.parent.childBase != null && ~this.parent.items.indexOf(this)) {
|
||||
// Check to make sure we're visible and inside of the visible scroll area.
|
||||
if (this.parent.childBase != null && (!this.parent.items || ~this.parent.items.indexOf(this))) {
|
||||
var rtop = this.rtop - (this.parent.border ? 1 : 0)
|
||||
, visible = this.parent.height - (this.parent.border ? 2 : 0);
|
||||
|
||||
|
@ -1473,9 +1484,25 @@ outer:
|
|||
}
|
||||
|
||||
if (this.border) {
|
||||
// var alt;
|
||||
// if (this.screen.tput
|
||||
// && this.screen.tput.strings.enter_alt_charset_mode
|
||||
// && this.border.type === 'ascii') {
|
||||
// //this.screen.program.put.smacs();
|
||||
// battr |= 32 << 18;
|
||||
// alt = true;
|
||||
// }
|
||||
|
||||
yi = yi_;
|
||||
for (xi = xi_; xi < xl; xi++) {
|
||||
if (!lines[yi]) break;
|
||||
|
||||
// if (alt) {
|
||||
// if (xi === xi_) ch = 'l';
|
||||
// else if (xi === xl - 1) ch = 'k';
|
||||
// else ch = 'q';
|
||||
// } else
|
||||
|
||||
if (this.border.type === 'ascii') {
|
||||
if (xi === xi_) ch = '┌';
|
||||
else if (xi === xl - 1) ch = '┐';
|
||||
|
@ -1494,6 +1521,11 @@ outer:
|
|||
yi = yi_ + 1;
|
||||
for (; yi < yl; yi++) {
|
||||
if (!lines[yi]) break;
|
||||
|
||||
// if (alt) {
|
||||
// ch = 'x';
|
||||
// } else
|
||||
|
||||
if (this.border.type === 'ascii') {
|
||||
ch = '│';
|
||||
} else if (this.border.type === 'bg') {
|
||||
|
@ -1517,6 +1549,13 @@ outer:
|
|||
yi = yl - 1;
|
||||
for (xi = xi_; xi < xl; xi++) {
|
||||
if (!lines[yi]) break;
|
||||
|
||||
// if (alt) {
|
||||
// if (xi === xi_) ch = 'm';
|
||||
// else if (xi === xl - 1) ch = 'j';
|
||||
// else ch = 'q';
|
||||
// } else
|
||||
|
||||
if (this.border.type === 'ascii') {
|
||||
if (xi === xi_) ch = '└';
|
||||
else if (xi === xl - 1) ch = '┘';
|
||||
|
@ -1532,6 +1571,11 @@ outer:
|
|||
lines[yi].dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
// if (alt) {
|
||||
// //this.screen.program.put.rmacs();
|
||||
// battr &= ~(32 << 18);
|
||||
// }
|
||||
}
|
||||
|
||||
this.children.forEach(function(el) {
|
||||
|
@ -1543,20 +1587,27 @@ outer:
|
|||
|
||||
// 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 _lastPos instead of render(true).
|
||||
// Maybe _lastPos could be updated on .left, .right, etc setters?
|
||||
Box.prototype.insertTop = function(line) {
|
||||
if (!this._lastPos) return;
|
||||
if (this._lastPos.xi === 0 && this._lastPos.xl === this.screen.width) {
|
||||
if (this._lastPos && this._lastPos.xi === 0 && this._lastPos.xl === this.screen.width) {
|
||||
this.screen.insertTop(this._lastPos.yi, this._lastPos.yl - 1);
|
||||
}
|
||||
this.setContent(line + '\n' + this.content, true);
|
||||
// this.screen.render();
|
||||
};
|
||||
|
||||
Box.prototype.insertBottom = function(line) {
|
||||
if (!this._lastPos) return;
|
||||
if (this._lastPos.xi === 0 && this._lastPos.xl === this.screen.width) {
|
||||
if (this._lastPos && this._lastPos.xi === 0 && this._lastPos.xl === this.screen.width) {
|
||||
this.screen.insertBottom(this._lastPos.yi, this._lastPos.yl - 1);
|
||||
}
|
||||
this.setContent(this.content + '\n' + line, true);
|
||||
// this.screen.render();
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1606,6 +1657,8 @@ function Line(options) {
|
|||
|
||||
Line.prototype.__proto__ = Box.prototype;
|
||||
|
||||
Line.prototype.type = 'line';
|
||||
|
||||
/**
|
||||
* ScrollableBox
|
||||
*/
|
||||
|
@ -1624,6 +1677,8 @@ function ScrollableBox(options) {
|
|||
|
||||
ScrollableBox.prototype.__proto__ = Box.prototype;
|
||||
|
||||
ScrollableBox.prototype.type = 'scrollable-box';
|
||||
|
||||
ScrollableBox.prototype.scroll = function(offset) {
|
||||
var visible = this.height - (this.border ? 2 : 0);
|
||||
// Maybe do for lists:
|
||||
|
@ -1664,6 +1719,7 @@ function List(options) {
|
|||
ScrollableBox.call(this, options);
|
||||
|
||||
this.items = [];
|
||||
this.ritems = [];
|
||||
this.selected = 0;
|
||||
|
||||
this.selectedBg = convert(options.selectedBg);
|
||||
|
@ -1677,6 +1733,7 @@ function List(options) {
|
|||
this.mouse = options.mouse || false;
|
||||
|
||||
if (options.items) {
|
||||
this.ritems = options.items;
|
||||
options.items.forEach(this.add.bind(this));
|
||||
}
|
||||
|
||||
|
@ -1783,6 +1840,8 @@ function List(options) {
|
|||
|
||||
List.prototype.__proto__ = ScrollableBox.prototype;
|
||||
|
||||
List.prototype.type = 'list';
|
||||
|
||||
List.prototype.add = function(item) {
|
||||
var self = this;
|
||||
|
||||
|
@ -1821,7 +1880,11 @@ List.prototype.remove = function(child) {
|
|||
|
||||
List.prototype.setItems = function(items) {
|
||||
var i = 0
|
||||
, original = this.items.slice();
|
||||
, original = this.items.slice()
|
||||
//, selected = this.selected
|
||||
, sel = this.ritems[this.selected];
|
||||
|
||||
this.ritems = items;
|
||||
|
||||
this.select(0);
|
||||
|
||||
|
@ -1836,6 +1899,11 @@ List.prototype.setItems = function(items) {
|
|||
for (; i < original.length; i++) {
|
||||
this.remove(original[i]);
|
||||
}
|
||||
|
||||
// Try to find our old item if it still exists.
|
||||
sel = items.indexOf(sel);
|
||||
if (~sel) this.select(sel);
|
||||
//this.select(~sel ? sel : selected);
|
||||
};
|
||||
|
||||
List.prototype.select = function(index) {
|
||||
|
@ -1947,6 +2015,8 @@ function ScrollableText(options) {
|
|||
|
||||
ScrollableText.prototype.__proto__ = ScrollableBox.prototype;
|
||||
|
||||
ScrollableText.prototype.type = 'scrollable-text';
|
||||
|
||||
ScrollableText.prototype._scroll = ScrollableText.prototype.scroll;
|
||||
ScrollableText.prototype.scroll = function(offset) {
|
||||
var base = this.childBase
|
||||
|
@ -2013,6 +2083,8 @@ function Input(options) {
|
|||
|
||||
Input.prototype.__proto__ = Box.prototype;
|
||||
|
||||
Input.prototype.type = 'input';
|
||||
|
||||
/**
|
||||
* Textbox
|
||||
*/
|
||||
|
@ -2025,10 +2097,27 @@ function Textbox(options) {
|
|||
this.screen._listenKeys(this);
|
||||
this.value = options.value || '';
|
||||
this.secret = options.secret;
|
||||
this.censor = options.censor;
|
||||
|
||||
var self = this;
|
||||
|
||||
this.on('resize', updateCursor);
|
||||
this.on('move', updateCursor);
|
||||
|
||||
function updateCursor() {
|
||||
//if (!self.visible) return;
|
||||
if (self.screen.focused !== self) return;
|
||||
self.screen.program.cup(
|
||||
self.top + 1 + (self.border ? 1 : 0),
|
||||
self.left + 1 + (self.border ? 1 : 0)
|
||||
+ self.value.length);
|
||||
}
|
||||
}
|
||||
|
||||
Textbox.prototype.__proto__ = Input.prototype;
|
||||
|
||||
Textbox.prototype.type = 'textbox';
|
||||
|
||||
Textbox.prototype.setInput = function(callback) {
|
||||
var self = this;
|
||||
|
||||
|
@ -2122,7 +2211,10 @@ Textbox.prototype.render = function(stop) {
|
|||
// Could technically optimize this.
|
||||
if (this.secret) {
|
||||
this.setContent('');
|
||||
//this.setContent(Array(this.value.length + 1).join('*'));
|
||||
return this._render(stop);
|
||||
}
|
||||
if (this.censor) {
|
||||
this.setContent(Array(this.value.length + 1).join('*'));
|
||||
return this._render(stop);
|
||||
}
|
||||
this.setContent(this.value.slice(-(this.width - (this.border ? 2 : 0) - 1)));
|
||||
|
@ -2136,19 +2228,31 @@ Textbox.prototype.setEditor = function(callback) {
|
|||
|
||||
self.screen.program.normalBuffer();
|
||||
self.screen.program.showCursor();
|
||||
var _listenedMouse = self.screen._listenedMouse;
|
||||
if (self.screen._listenedMouse) {
|
||||
self.screen.program.disableMouse();
|
||||
}
|
||||
|
||||
return readEditor(function(err, value) {
|
||||
self.screen.program.alternateBuffer();
|
||||
self.screen.program.hideCursor();
|
||||
if (_listenedMouse) {
|
||||
self.screen.program.enableMouse();
|
||||
}
|
||||
self.screen.alloc();
|
||||
self.screen.render();
|
||||
if (err) return callback(err);
|
||||
value = value.replace(/[\r\n]/g, '');
|
||||
self.value = value;
|
||||
if (!self.secret) {
|
||||
self.setContent(value);
|
||||
}
|
||||
|
||||
////if (self.censor) {
|
||||
//// self.setContent(Array(self.value.length + 1).join('*'));
|
||||
////} else
|
||||
//if (!self.secret) {
|
||||
// self.setContent(value);
|
||||
//}
|
||||
//return callback(null, value);
|
||||
|
||||
return self.setInput(callback);
|
||||
});
|
||||
};
|
||||
|
@ -2166,6 +2270,8 @@ function Textarea(options) {
|
|||
|
||||
Textarea.prototype.__proto__ = Input.prototype;
|
||||
|
||||
Textarea.prototype.type = 'textarea';
|
||||
|
||||
/**
|
||||
* Button
|
||||
*/
|
||||
|
@ -2202,6 +2308,8 @@ function Button(options) {
|
|||
|
||||
Button.prototype.__proto__ = Input.prototype;
|
||||
|
||||
Button.prototype.type = 'button';
|
||||
|
||||
Button.prototype.press = function() {
|
||||
var self = this;
|
||||
this.emit('press');
|
||||
|
@ -2237,6 +2345,8 @@ function ProgressBar(options) {
|
|||
|
||||
ProgressBar.prototype.__proto__ = Input.prototype;
|
||||
|
||||
ProgressBar.prototype.type = 'progress-bar';
|
||||
|
||||
ProgressBar.prototype._render = ProgressBar.prototype.render;
|
||||
ProgressBar.prototype.render = function(stop) {
|
||||
// NOTE: Maybe move this `hidden` check down below `stop` check and return `ret`.
|
||||
|
|
Loading…
Reference in New Issue