mirror of
https://github.com/embarklabs/neo-blessed.git
synced 2025-02-22 07:38:06 +00:00
add text input and setContent.
This commit is contained in:
parent
812aa7fa42
commit
41c4560a6f
@ -1239,6 +1239,7 @@ Program.prototype.text = function(text, attr) {
|
||||
|
||||
Program.prototype._attr = function(param, val) {
|
||||
var self = this
|
||||
, param = param || 'normal'
|
||||
, parts = param.split(/\s*[,;]\s*/);
|
||||
|
||||
if (parts.length > 1) {
|
||||
@ -2041,6 +2042,7 @@ Program.prototype.setScrollRegion = function(top, bottom) {
|
||||
|
||||
// CSI s
|
||||
// Save cursor (ANSI.SYS).
|
||||
Program.prototype.sc =
|
||||
Program.prototype.saveCursor = function() {
|
||||
this.savedX = this.x;
|
||||
this.savedY = this.y;
|
||||
@ -2050,6 +2052,7 @@ Program.prototype.saveCursor = function() {
|
||||
|
||||
// CSI u
|
||||
// Restore cursor (ANSI.SYS).
|
||||
Program.prototype.rc =
|
||||
Program.prototype.restoreCursor = function() {
|
||||
this.x = this.savedX || 1;
|
||||
this.y = this.savedY || 1;
|
||||
@ -2638,7 +2641,8 @@ exports = Program;
|
||||
exports.Program = Program;
|
||||
exports.Tput = Tput;
|
||||
|
||||
['Screen', 'Box', 'Text', 'List', 'Line', 'ProgressBar', 'ScrollableBox', 'ScrollableText'].forEach(function(key) {
|
||||
['Screen', 'Box', 'Text', 'List', 'Line', 'ProgressBar',
|
||||
'ScrollableBox', 'ScrollableText', 'Textbox'].forEach(function(key) {
|
||||
exports.__defineGetter__(key, function() {
|
||||
return (exports._widget || (exports._widget = require('./widget')))[key];
|
||||
});
|
||||
|
220
lib/widget.js
220
lib/widget.js
@ -227,7 +227,9 @@ Screen.prototype._listenKeys = function(el) {
|
||||
if (~self.input.indexOf(self.focused)) {
|
||||
self.focused.emit('keypress', ch, key);
|
||||
}
|
||||
self.emit('keypress', ch, key);
|
||||
if (!self._grabKeys) {
|
||||
self.emit('keypress', ch, key);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@ -548,6 +550,16 @@ Element.prototype.focus = function() {
|
||||
this.screen.emit('element focus', old, this);
|
||||
};
|
||||
|
||||
Element.prototype.setContent = function(content) {
|
||||
var ret = this.render(true);
|
||||
this.content = content || '';
|
||||
this.screen.clearRegion(
|
||||
ret.xi + (this.border ? 1 : 0),
|
||||
ret.xl - (this.border ? 1 : 0),
|
||||
ret.yi + (this.border ? 1 : 0),
|
||||
ret.yl - (this.border ? 1 : 0));
|
||||
};
|
||||
|
||||
Element.prototype.__defineGetter__('left', function() {
|
||||
var left = this.position.left;
|
||||
|
||||
@ -1319,10 +1331,170 @@ Input.prototype.__proto__ = Box.prototype;
|
||||
|
||||
function Textbox(options) {
|
||||
Input.call(this, options);
|
||||
this.value = options.value || '';
|
||||
this.content = options.content || '';
|
||||
if (options.label) {
|
||||
// TODO: Make sure negative relative coords work.
|
||||
this.append(new Text({
|
||||
content: options.label,
|
||||
top: -1 - (this.border ? 1 : 0)
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
Textbox.prototype.__proto__ = Input.prototype;
|
||||
|
||||
Textbox.prototype.setInput = function(callback) {
|
||||
var self = this;
|
||||
|
||||
this.screen._grabKeys = true;
|
||||
|
||||
this.focus();
|
||||
//this.screen.program.saveCursor();
|
||||
this.screen.program.cup(this.top + 1 + (this.border ? 1 : 0), this.left + 1 + (this.border ? 1 : 0));
|
||||
this.screen.program.showCursor();
|
||||
this.screen.program.sgr('normal');
|
||||
|
||||
this._callback = function(err, value) {
|
||||
//self.screen.program.restoreCursor();
|
||||
self.screen.program.hideCursor();
|
||||
// Wait for global keypress event to fire.
|
||||
process.nextTick(function() {
|
||||
self.screen._grabKeys = false;
|
||||
});
|
||||
return err
|
||||
? callback(err)
|
||||
: callback(null, value);
|
||||
};
|
||||
|
||||
this.__listener = this._listener.bind(this);
|
||||
this.on('keypress', this.__listener);
|
||||
};
|
||||
|
||||
Textbox.prototype._listenerFast = function(ch, key) {
|
||||
var y = this.top + 1 + (this.border ? 1 : 0)
|
||||
, x = this.left + 1 + (this.border ? 1 : 0)
|
||||
, line = this.screen.lines[y]
|
||||
, callback = this._callback
|
||||
, value = this.value;
|
||||
|
||||
if (key.name === 'escape' || key.name === 'enter') {
|
||||
delete this._callback;
|
||||
this.value = '';
|
||||
this.removeListener('keypress', this.__listener);
|
||||
delete this.__listener;
|
||||
this.screen.program.cup(y, x);
|
||||
this.screen.program.write(Array(value.length + 1).join(' '));
|
||||
callback(null, key.name === 'enter' ? value : null);
|
||||
} else if (key.name === 'backspace') {
|
||||
if (this.value.length) {
|
||||
this.value = this.value.slice(0, -1);
|
||||
this.screen.program.cub();
|
||||
this.screen.program.write(' ');
|
||||
this.screen.program.cub();
|
||||
}
|
||||
} else {
|
||||
if (ch) {
|
||||
this.value += ch;
|
||||
this.screen.program.write(ch);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Textbox.prototype._listenerStupid = function(ch, key) {
|
||||
var y = this.top + 1 + (this.border ? 1 : 0)
|
||||
, x = this.left + 1 + (this.border ? 1 : 0)
|
||||
, line = this.screen.lines[y]
|
||||
, callback = this._callback
|
||||
, value = this.value;
|
||||
|
||||
if (key.name === 'escape' || key.name === 'enter') {
|
||||
delete this._callback;
|
||||
this.value = '';
|
||||
this.removeListener('keypress', this.__listener);
|
||||
delete this.__listener;
|
||||
this.screen.clearRegion(x, x + value.length, y, y);
|
||||
callback(null, key.name === 'enter' ? value : null);
|
||||
} else if (key.name === 'backspace') {
|
||||
if (this.value.length) {
|
||||
line[x + this.value.length][1] = ' ';
|
||||
line.dirty = true;
|
||||
this.value = this.value.slice(0, -1);
|
||||
}
|
||||
} else {
|
||||
if (ch) {
|
||||
line[x + this.value.length][0] = this.screen.dattr;
|
||||
line[x + this.value.length][1] = ch;
|
||||
line.dirty = true;
|
||||
this.value += ch;
|
||||
}
|
||||
}
|
||||
|
||||
this.screen.render();
|
||||
};
|
||||
|
||||
Textbox.prototype._listener = function(ch, key) {
|
||||
var callback = this._callback
|
||||
, value = this.content;
|
||||
|
||||
//var y = this.top + 1 + (this.border ? 1 : 0)
|
||||
// , line = this.screen.lines[y];
|
||||
|
||||
if (key.name === 'escape' || key.name === 'enter') {
|
||||
delete this._callback;
|
||||
//this.content = '';
|
||||
this.setContent('');
|
||||
this.removeListener('keypress', this.__listener);
|
||||
delete this.__listener;
|
||||
callback(null, key.name === 'enter' ? value : null);
|
||||
} else if (key.name === 'backspace') {
|
||||
if (this.content.length) {
|
||||
//this.content = this.content.slice(0, -1);
|
||||
this.setContent(this.content.slice(0, -1));
|
||||
this.screen.program.cub();
|
||||
}
|
||||
} else {
|
||||
if (ch) {
|
||||
//this.content += ch;
|
||||
this.setContent(this.content + ch);
|
||||
this.screen.program.cuf();
|
||||
}
|
||||
}
|
||||
|
||||
//line.dirty = true;
|
||||
|
||||
this.screen.render();
|
||||
};
|
||||
|
||||
Textbox.prototype.setEditor = function(callback) {
|
||||
var self = this;
|
||||
|
||||
this.focus();
|
||||
|
||||
self.screen.program.normalBuffer();
|
||||
self.screen.program.showCursor();
|
||||
|
||||
return readEditor(function(err, value) {
|
||||
self.screen.program.alternateBuffer();
|
||||
self.screen.program.hideCursor();
|
||||
self.screen.alloc();
|
||||
self.screen.render();
|
||||
if (err) return callback(err);
|
||||
self.setContent(value);
|
||||
return callback(null, value);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Textarea
|
||||
*/
|
||||
|
||||
function Textarea(options) {
|
||||
Input.call(this, options);
|
||||
}
|
||||
|
||||
Textarea.prototype.__proto__ = Input.prototype;
|
||||
|
||||
/**
|
||||
* Button
|
||||
*/
|
||||
@ -1469,6 +1641,52 @@ function attrCode(code, cur) {
|
||||
return (flags << 18) | (fg << 9) | bg;
|
||||
}
|
||||
|
||||
function readEditor(callback) {
|
||||
var spawn = require('child_process').spawn
|
||||
, fs = require('fs')
|
||||
, editor = process.env.EDITOR || 'vi'
|
||||
, file = '/tmp/blessed.' + Math.random().toString(36);
|
||||
|
||||
var write = process.stdout.write;
|
||||
process.stdout.write = function() {};
|
||||
|
||||
try {
|
||||
process.stdin.pause();
|
||||
} catch (e) {
|
||||
;
|
||||
}
|
||||
|
||||
var resume = function() {
|
||||
try {
|
||||
process.stdin.resume();
|
||||
} catch (e) {
|
||||
;
|
||||
}
|
||||
process.stdout.write = write;
|
||||
};
|
||||
|
||||
var ps = spawn(editor, [file], {
|
||||
stdio: 'inherit',
|
||||
env: process.env,
|
||||
cwd: process.env.HOME
|
||||
});
|
||||
|
||||
ps.on('error', function(err) {
|
||||
resume();
|
||||
return callback(err);
|
||||
});
|
||||
|
||||
ps.on('exit', function(code) {
|
||||
resume();
|
||||
return fs.readFile(file, 'utf8', function(err, data) {
|
||||
return fs.unlink(file, function() {
|
||||
if (err) return callback(err);
|
||||
return callback(null, data);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
|
@ -175,12 +175,42 @@ screen.on('element focus', function(old, cur) {
|
||||
screen.render();
|
||||
});
|
||||
|
||||
program.on('keypress', function(ch, key) {
|
||||
var input = new blessed.Textbox({
|
||||
mouse: true,
|
||||
content: '',
|
||||
fg: 4,
|
||||
bg: -1,
|
||||
barBg: -1,
|
||||
barFg: 4,
|
||||
border: {
|
||||
type: 'ascii',
|
||||
fg: -1,
|
||||
bg: -1
|
||||
},
|
||||
width: '30%',
|
||||
height: 3,
|
||||
right: 0,
|
||||
top: 0
|
||||
});
|
||||
|
||||
screen.append(input);
|
||||
|
||||
screen.on('keypress', function(ch, key) {
|
||||
if (key.name === 'tab') {
|
||||
return key.shift
|
||||
? screen.focusPrev()
|
||||
: screen.focusNext();
|
||||
}
|
||||
if (key.name === 'i') {
|
||||
return input.setInput(function(err, value) {
|
||||
screen.children[0].setContent(value);
|
||||
});
|
||||
}
|
||||
if (key.name === 'e') {
|
||||
return input.setEditor(function(err, value) {
|
||||
screen.children[0].setContent(value);
|
||||
});
|
||||
}
|
||||
if (key.name === 'escape' || key.name === 'q') {
|
||||
return process.exit(0);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user