color names. tabs in textareas/boxes. cleanup old code. focus behavior.

This commit is contained in:
Christopher Jeffrey 2013-07-11 20:48:30 -05:00
parent 150a7c2439
commit 3eb382e8f1
2 changed files with 73 additions and 125 deletions

View File

@ -190,6 +190,7 @@ var colorNames = exports.colorNames = {
exports.convert = function(color) { exports.convert = function(color) {
var val = colorNames[color]; var val = colorNames[color];
if (typeof val === 'string') val = val.replace(/[\- ]/g, '');
if (val == null) val = color; if (val == null) val = color;
if (val == null) val = -1; if (val == null) val = -1;
if (typeof val === 'string') { if (typeof val === 'string') {

View File

@ -25,7 +25,7 @@ function Node(options) {
this.screen = this.screen this.screen = this.screen
|| Screen.global || Screen.global
|| (function(){throw new Error('No active screen.')})(); || (function(){throw new Error('No active screen.')})();
this.parent = options.parent || null; // this.screen; this.parent = options.parent || null;
this.children = []; this.children = [];
this.$ = this._ = this.data = {}; this.$ = this._ = this.data = {};
this.uid = Node.uid++; this.uid = Node.uid++;
@ -53,7 +53,7 @@ Node.prototype.__proto__ = EventEmitter.prototype;
Node.prototype.type = 'node'; Node.prototype.type = 'node';
Node.prototype.prepend = function(element) { Node.prototype.prepend = function(element) {
var old = element.parent; // var old = element.parent;
element.detach(); element.detach();
element.parent = this; element.parent = this;
@ -82,7 +82,7 @@ Node.prototype.prepend = function(element) {
}; };
Node.prototype.append = function(element) { Node.prototype.append = function(element) {
var old = element.parent; // var old = element.parent;
element.detach(); element.detach();
element.parent = this; element.parent = this;
@ -111,7 +111,7 @@ Node.prototype.append = function(element) {
}; };
Node.prototype.remove = function(element) { Node.prototype.remove = function(element) {
element.parent = null; // this.screen; element.parent = null;
var i = this.children.indexOf(element); var i = this.children.indexOf(element);
if (~i) { if (~i) {
@ -237,7 +237,7 @@ function Screen(options) {
bottom: this.bottom = this.rbottom = 0 bottom: this.bottom = this.rbottom = 0
}; };
// this.focused = null; // this.focused;
this.hover = null; this.hover = null;
this.history = []; this.history = [];
this.clickable = []; this.clickable = [];
@ -252,7 +252,6 @@ function Screen(options) {
this.program.on('resize', function() { this.program.on('resize', function() {
self.alloc(); self.alloc();
self.render(); self.render();
// self.emit('resize');
(function emit(el) { (function emit(el) {
el.emit('resize'); el.emit('resize');
if (el.children) { if (el.children) {
@ -429,6 +428,7 @@ Screen.prototype._listenKeys = function(el) {
focused.emit('keypress', ch, key); focused.emit('keypress', ch, key);
focused.emit('key ' + key.name, ch, key); focused.emit('key ' + key.name, ch, key);
// self.emit('element keypress', focused, ch, key); // self.emit('element keypress', focused, ch, key);
// self.emit('element key ' + key.name, focused, ch, key);
} }
}); });
}; };
@ -548,7 +548,7 @@ Screen.prototype.deleteBottom = function(top, bottom) {
}; };
Screen.prototype.deleteTop = function(top, bottom) { Screen.prototype.deleteTop = function(top, bottom) {
// return this.insertBottom(top, bottom); // Same as: return this.insertBottom(top, bottom);
return this.deleteLine(1, top, top, bottom); return this.deleteLine(1, top, top, bottom);
}; };
@ -1020,10 +1020,6 @@ function Element(options) {
} }
}); });
// this.onScreenEvent('resize', function() {
// self.parseContent();
// });
this.on('resize', function() { this.on('resize', function() {
self.parseContent(); self.parseContent();
}); });
@ -1051,9 +1047,7 @@ function Element(options) {
this.on('mouseover', function() { this.on('mouseover', function() {
Object.keys(effects).forEach(function(key) { Object.keys(effects).forEach(function(key) {
var val = effects[key]; var val = effects[key];
//if (self._htemp[key] == null) {
self._htemp[key] = self[key]; self._htemp[key] = self[key];
//}
self[key] = val; self[key] = val;
}); });
self.screen.render(); self.screen.render();
@ -1074,23 +1068,6 @@ Element.prototype.__proto__ = Node.prototype;
Element.prototype.type = 'element'; Element.prototype.type = 'element';
/*
Element._emit = Element.prototype.emit;
Element.prototype.emit = function(type) {
var args = Array.prototype.slice.call(arguments)
, ret = Element._emit.apply(this, args);
if (this.screen) {
args.shift();
args.unshift(this);
args.unshift('element ' + type);
this.screen.emit.apply(this.screen, args);
}
return ret;
};
*/
Element.prototype.onScreenEvent = function(type, listener) { Element.prototype.onScreenEvent = function(type, listener) {
var self = this; var self = this;
if (this.parent) { if (this.parent) {
@ -1109,11 +1086,10 @@ Element.prototype.hide = function() {
this.hidden = true; this.hidden = true;
this.clearPos(); this.clearPos();
this.emit('hide'); this.emit('hide');
//if (this.screen.focused === this) {
// this.screen.focusPop(); if (this.screen.focused === this && this.history[this.history.length-2]) {
// var el = this.screen.focusPop(); this.history[this.history.length-2].focus();
// if (el) el.focus(); }
//}
}; };
Element.prototype.show = function() { Element.prototype.show = function() {
@ -1154,6 +1130,7 @@ Element.prototype.parseContent = function() {
// Could move these 2 lines back to setContent (?) // Could move these 2 lines back to setContent (?)
content = content.replace(/\x1b(?!\[[\d;]*m)/g, ''); content = content.replace(/\x1b(?!\[[\d;]*m)/g, '');
content = this._parseTags(content || ''); content = this._parseTags(content || '');
content = content.replace(/\t/g, ' ');
this._clines = wrapContent(content, width, this.parseTags, this.align); this._clines = wrapContent(content, width, this.parseTags, this.align);
this._clines.width = width; this._clines.width = width;
this._clines.content = this.content; this._clines.content = this.content;
@ -1584,10 +1561,8 @@ Box.prototype.render = function(stop) {
|| this.options.right == null)) { || this.options.right == null)) {
if (this.options.left == null && this.options.right != null) { if (this.options.left == null && this.options.right != null) {
xi_ = xl - w - (this.border ? 2 : 0) - this.padding; xi_ = xl - w - (this.border ? 2 : 0) - this.padding;
//xi_--; // make it one cell wider for newlines
} else { } else {
xl = xi_ + w + (this.border ? 2 : 0) + this.padding; xl = xi_ + w + (this.border ? 2 : 0) + this.padding;
//xl++; // make it one cell wider for newlines
} }
} }
@ -1741,25 +1716,9 @@ outer:
} }
if (this.border) { 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_; yi = yi_;
for (xi = xi_; xi < xl; xi++) { for (xi = xi_; xi < xl; xi++) {
if (!lines[yi]) break; 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 (this.border.type === 'ascii') {
if (xi === xi_) ch = '┌'; if (xi === xi_) ch = '┌';
else if (xi === xl - 1) ch = '┐'; else if (xi === xl - 1) ch = '┐';
@ -1778,11 +1737,6 @@ outer:
yi = yi_ + 1; yi = yi_ + 1;
for (; yi < yl; yi++) { for (; yi < yl; yi++) {
if (!lines[yi]) break; if (!lines[yi]) break;
// if (alt) {
// ch = 'x';
// } else
if (this.border.type === 'ascii') { if (this.border.type === 'ascii') {
ch = '│'; ch = '│';
} else if (this.border.type === 'bg') { } else if (this.border.type === 'bg') {
@ -1806,13 +1760,6 @@ outer:
yi = yl - 1; yi = yl - 1;
for (xi = xi_; xi < xl; xi++) { for (xi = xi_; xi < xl; xi++) {
if (!lines[yi]) break; 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 (this.border.type === 'ascii') {
if (xi === xi_) ch = '└'; if (xi === xi_) ch = '└';
else if (xi === xl - 1) ch = '┘'; else if (xi === xl - 1) ch = '┘';
@ -1828,11 +1775,6 @@ outer:
lines[yi].dirty = true; lines[yi].dirty = true;
} }
} }
// if (alt) {
// //this.screen.program.put.rmacs();
// battr &= ~(32 << 18);
// }
} }
this.children.forEach(function(el) { this.children.forEach(function(el) {
@ -1970,6 +1912,7 @@ ScrollableBox.prototype.type = 'scrollable-box';
ScrollableBox.prototype.scroll = function(offset) { ScrollableBox.prototype.scroll = function(offset) {
var visible = this.height - (this.border ? 2 : 0); var visible = this.height - (this.border ? 2 : 0);
// Maybe do for lists: // Maybe do for lists:
// if (this.items) visible = Math.min(this.items.length, visible); // if (this.items) visible = Math.min(this.items.length, visible);
if (this.alwaysScroll) { if (this.alwaysScroll) {
@ -1980,6 +1923,7 @@ ScrollableBox.prototype.scroll = function(offset) {
} else { } else {
this.childOffset += offset; this.childOffset += offset;
} }
if (this.childOffset > visible - 1) { if (this.childOffset > visible - 1) {
var d = this.childOffset - (visible - 1); var d = this.childOffset - (visible - 1);
this.childOffset -= d; this.childOffset -= d;
@ -1989,8 +1933,13 @@ ScrollableBox.prototype.scroll = function(offset) {
this.childOffset += -d; this.childOffset += -d;
this.childBase += d; this.childBase += d;
} }
if (this.childBase < 0) this.childBase = 0;
else if (this.childBase > this.baseLimit) this.childBase = this.baseLimit; if (this.childBase < 0) {
this.childBase = 0;
} else if (this.childBase > this.baseLimit) {
this.childBase = this.baseLimit;
}
this.emit('scroll'); this.emit('scroll');
}; };
@ -2364,6 +2313,7 @@ ScrollableText.prototype._recalculateIndex = function() {
for (var i = 0, t = 0; i < this.childBase; i++) { for (var i = 0, t = 0; i < this.childBase; i++) {
t += this._clines[i].length + 1; t += this._clines[i].length + 1;
} }
this.contentIndex = t; this.contentIndex = t;
}; };
@ -2405,7 +2355,6 @@ function Textbox(options) {
this.on('move', updateCursor); this.on('move', updateCursor);
function updateCursor() { function updateCursor() {
//if (!self.visible) return;
if (self.screen.focused !== self) return; if (self.screen.focused !== self) return;
self.screen.program.cup( self.screen.program.cup(
self.top + 1 + (self.border ? 1 : 0), self.top + 1 + (self.border ? 1 : 0),
@ -2421,13 +2370,18 @@ Textbox.prototype.type = 'textbox';
Textbox.prototype.input = Textbox.prototype.input =
Textbox.prototype.readInput = Textbox.prototype.readInput =
Textbox.prototype.setInput = function(callback) { Textbox.prototype.setInput = function(callback) {
var self = this; var self = this
, focused = this.screen.focused === this;
if (!focused) {
this.screen.saveFocus();
this.focus(); this.focus();
}
this.screen.grabKeys = true; this.screen.grabKeys = true;
// this.screen.program.saveCursor(); // Could possibly save and restore cursor.
this.screen.program.cup( this.screen.program.cup(
this.top + 1 + (this.border ? 1 : 0), this.top + 1 + (this.border ? 1 : 0),
this.left + 1 + (this.border ? 1 : 0) this.left + 1 + (this.border ? 1 : 0)
@ -2436,13 +2390,12 @@ Textbox.prototype.setInput = function(callback) {
this.screen.program.sgr('normal'); this.screen.program.sgr('normal');
this._callback = function(err, value) { this._callback = function(err, value) {
// self.screen.program.restoreCursor();
self.screen.program.hideCursor(); self.screen.program.hideCursor();
self.screen.grabKeys = false; self.screen.grabKeys = false;
//self.screen.focusPop(); if (!focused) {
//var el = self.screen.focusPop(); self.screen.restoreFocus();
//if (el) el.focus(); }
return err return err
? callback(err) ? callback(err)
@ -2473,6 +2426,8 @@ Textbox.prototype._listener = function(ch, key) {
} }
} else { } else {
if (ch) { if (ch) {
// Tabs only work with textareas.
if (ch === '\t') ch = ' ';
this.value += ch; this.value += ch;
if (this.secret) return; if (this.secret) return;
if (this.value.length < this.width - (this.border ? 2 : 0)) { if (this.value.length < this.width - (this.border ? 2 : 0)) {
@ -2524,23 +2479,11 @@ Textbox.prototype.editor =
Textbox.prototype.readEditor = Textbox.prototype.readEditor =
Textbox.prototype.setEditor = function(callback) { Textbox.prototype.setEditor = function(callback) {
var self = this; var self = this;
this.focus();
return this.screen.readEditor({ value: this.value }, function(err, value) { return this.screen.readEditor({ value: this.value }, function(err, value) {
if (err) return callback(err); if (err) return callback(err);
value = value.replace(/[\r\n]/g, ''); value = value.replace(/[\r\n]/g, '');
self.value = value; self.value = value;
return self.readInput(callback);
////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);
}); });
}; };
@ -2594,9 +2537,13 @@ Textarea.prototype.updateCursor = function() {
Textarea.prototype.input = Textarea.prototype.input =
Textarea.prototype.readInput = Textarea.prototype.readInput =
Textarea.prototype.setInput = function(callback) { Textarea.prototype.setInput = function(callback) {
var self = this; var self = this
, focused = this.screen.focused === this;
if (!focused) {
this.screen.saveFocus();
this.focus(); this.focus();
}
this.screen.grabKeys = true; this.screen.grabKeys = true;
@ -2607,6 +2554,11 @@ Textarea.prototype.setInput = function(callback) {
this._callback = function(err, value) { this._callback = function(err, value) {
self.screen.program.hideCursor(); self.screen.program.hideCursor();
self.screen.grabKeys = false; self.screen.grabKeys = false;
if (!focused) {
self.screen.restoreFocus();
}
return err return err
? callback(err) ? callback(err)
: callback(null, value); : callback(null, value);
@ -2678,9 +2630,6 @@ Textarea.prototype.editor =
Textarea.prototype.readEditor = Textarea.prototype.readEditor =
Textarea.prototype.setEditor = function(callback) { Textarea.prototype.setEditor = function(callback) {
var self = this; var self = this;
this.focus();
return this.screen.readEditor({ value: this.value }, function(err, value) { return this.screen.readEditor({ value: this.value }, function(err, value) {
if (err) return callback(err); if (err) return callback(err);
self.value = value; self.value = value;
@ -2688,7 +2637,7 @@ Textarea.prototype.setEditor = function(callback) {
self._typeScroll(); self._typeScroll();
self.updateCursor(); self.updateCursor();
self.screen.render(); self.screen.render();
return self.setInput(callback); return self.readInput(callback);
}); });
}; };
@ -2825,10 +2774,11 @@ ProgressBar.prototype.reset = function() {
// Convert an SGR string to our own attribute format. // Convert an SGR string to our own attribute format.
function attrCode(code, cur) { function attrCode(code, cur) {
var flags = (cur >> 18) & 0x1ff; var flags = (cur >> 18) & 0x1ff
var fg = (cur >> 9) & 0x1ff; , fg = (cur >> 9) & 0x1ff
var bg = cur & 0x1ff; , bg = cur & 0x1ff
var c, i; , c
, i;
code = /^\x1b\[([\d;]*)m$/.exec(code); code = /^\x1b\[([\d;]*)m$/.exec(code);
if (!code) return cur; if (!code) return cur;
@ -2967,9 +2917,6 @@ function wrapContent(content, width, tags, state) {
while (line.length > width) { while (line.length > width) {
for (i = 0, total = 0; i < line.length; i++) { for (i = 0, total = 0; i < line.length; i++) {
while (line[i] === '\x1b') { while (line[i] === '\x1b') {
//var c = /^\x1b\[[\d;]*m/.exec(line.substring(i));
//if (!c) { i++; break; }
//i += c[0].length;
while (line[i] && line[i++] !== 'm'); while (line[i] && line[i++] !== 'm');
} }
if (!line[i]) break; if (!line[i]) break;
@ -2986,7 +2933,8 @@ function wrapContent(content, width, tags, state) {
} }
} }
i++; // FIX // XXX This shouldn't be required, but is.
i++;
part = line.substring(0, i - 1); part = line.substring(0, i - 1);
esc = /\x1b[\[\d;]*$/.exec(part); esc = /\x1b[\[\d;]*$/.exec(part);
@ -2994,11 +2942,9 @@ function wrapContent(content, width, tags, state) {
if (esc) { if (esc) {
part = part.slice(0, -esc[0].length); part = part.slice(0, -esc[0].length);
line = line.substring(i - 1 - esc[0].length); line = line.substring(i - 1 - esc[0].length);
//out.push(part);
out.push(sp(part, width, align)); out.push(sp(part, width, align));
} else { } else {
line = line.substring(i - 1); line = line.substring(i - 1);
//out.push(part);
out.push(sp(part, width, align)); out.push(sp(part, width, align));
} }
} }
@ -3008,7 +2954,7 @@ function wrapContent(content, width, tags, state) {
out[out.length-1] += line; out[out.length-1] += line;
return; return;
} }
//out.push(line);
out.push(sp(line, width, align)); out.push(sp(line, width, align));
}); });
@ -3039,6 +2985,7 @@ var colors = {
function convert(color) { function convert(color) {
var val = colors[color]; var val = colors[color];
if (typeof val === 'string') val = val.replace(/[\- ]/g, '');
if (val == null) val = color; if (val == null) val = color;
if (val == null) val = -1; if (val == null) val = -1;
//if (typeof val === 'string') val = Screen._findColor(val); //if (typeof val === 'string') val = Screen._findColor(val);