fix textbox/textarea.
This commit is contained in:
parent
d2226c3295
commit
36415f76b6
141
lib/widget.js
141
lib/widget.js
|
@ -364,6 +364,10 @@ function Screen(options) {
|
|||
return process.exit(1);
|
||||
});
|
||||
|
||||
process.on('SIGTERM', function() {
|
||||
return process.exit(0);
|
||||
});
|
||||
|
||||
process.on('exit', function() {
|
||||
reset();
|
||||
});
|
||||
|
@ -1390,9 +1394,11 @@ Screen.prototype.rewindFocus = function() {
|
|||
var old = this.history[this.history.length-1]
|
||||
, el;
|
||||
|
||||
this.history.pop();
|
||||
|
||||
while (this.history.length) {
|
||||
el = this.history.pop();
|
||||
if (!el.detached && !el.visible) {
|
||||
if (!el.detached && el.visible) {
|
||||
this.history.push(el);
|
||||
el._focus(old);
|
||||
return el;
|
||||
|
@ -1916,25 +1922,6 @@ Element.prototype.setContent = function(content, noClear) {
|
|||
this.parseContent();
|
||||
};
|
||||
|
||||
Element.prototype.setContent_ = function(content, noClear) {
|
||||
var old, pos;
|
||||
|
||||
if (!noClear) {
|
||||
old = this._pcontent;
|
||||
pos = this._getCoords();
|
||||
}
|
||||
|
||||
this.content = content || '';
|
||||
this.parseContent();
|
||||
|
||||
if (!noClear && pos && this._pcontent !== old) {
|
||||
// this.clearPos(pos);
|
||||
this.screen.clearRegion(
|
||||
pos.xi, pos.xl,
|
||||
pos.yi, pos.yl);
|
||||
}
|
||||
};
|
||||
|
||||
Element.prototype.getContent = function() {
|
||||
return this._clines.fake.join('\n');
|
||||
};
|
||||
|
@ -4167,6 +4154,8 @@ Input.prototype.type = 'input';
|
|||
*/
|
||||
|
||||
function Textarea(options) {
|
||||
var self = this;
|
||||
|
||||
if (!(this instanceof Node)) {
|
||||
return new Textarea(options);
|
||||
}
|
||||
|
@ -4181,11 +4170,34 @@ function Textarea(options) {
|
|||
|
||||
this.value = options.value || '';
|
||||
|
||||
//this.on('prerender', this._render.bind(this));
|
||||
this.__updateCursor = this._updateCursor.bind(this);
|
||||
this.on('resize', this.__updateCursor);
|
||||
this.on('move', this.__updateCursor);
|
||||
this.on('focus', this.readInput.bind(this, null));
|
||||
//this.on('prerender', this._render.bind(this));
|
||||
|
||||
if (options.inputOnFocus) {
|
||||
this.on('focus', this.readInput.bind(this, null));
|
||||
}
|
||||
|
||||
if (!options.inputOnFocus && options.keys) {
|
||||
this.on('keypress', function(ch, key) {
|
||||
if (self._reading) return;
|
||||
if (key.name === 'enter' || (options.vi && key.name === 'i')) {
|
||||
return self.readInput();
|
||||
}
|
||||
if (key.name === 'e') {
|
||||
return self.readEditor();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (options.mouse) {
|
||||
this.on('click', function(data) {
|
||||
if (self._reading) return;
|
||||
if (data.button !== 'right') return;
|
||||
self.readEditor();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Textarea.prototype.__proto__ = Input.prototype;
|
||||
|
@ -4221,6 +4233,8 @@ Textarea.prototype._updateCursor = function() {
|
|||
cy = lpos.yi + this.itop + line;
|
||||
cx = lpos.xi + this.ileft + last.length;
|
||||
|
||||
// XXX Not sure, but this may still sometimes
|
||||
// cause problems when leaving editor.
|
||||
if (cy === program.y && cx === program.x) {
|
||||
return;
|
||||
}
|
||||
|
@ -4248,13 +4262,10 @@ Textarea.prototype.readInput = function(callback) {
|
|||
var self = this
|
||||
, focused = this.screen.focused === this;
|
||||
|
||||
// We need to maintain an array of
|
||||
// callbacks for legacy reasons.
|
||||
if (this._callback) {
|
||||
return callback ? this._callbacks.push(callback) : null;
|
||||
}
|
||||
if (this._reading) return;
|
||||
this._reading = true;
|
||||
|
||||
this._callbacks = callback ? [callback] : [];
|
||||
this._callback = callback;
|
||||
|
||||
if (!focused) {
|
||||
this.screen.saveFocus();
|
||||
|
@ -4265,19 +4276,24 @@ Textarea.prototype.readInput = function(callback) {
|
|||
|
||||
this._updateCursor();
|
||||
this.screen.program.showCursor();
|
||||
this.screen.program.sgr('normal');
|
||||
//this.screen.program.sgr('normal');
|
||||
|
||||
this._done = function fn(err, value) {
|
||||
if (!self._reading) return;
|
||||
|
||||
this._callback = function fn(err, value) {
|
||||
if (fn.done) return;
|
||||
fn.done = true;
|
||||
|
||||
self._reading = false;
|
||||
|
||||
delete self._callback;
|
||||
delete self._done;
|
||||
|
||||
self.removeListener('keypress', self.__listener);
|
||||
delete self.__listener;
|
||||
|
||||
self.removeListener('blur', self.__callback);
|
||||
delete self.__callback;
|
||||
self.removeListener('blur', self.__done);
|
||||
delete self.__done;
|
||||
|
||||
self.screen.program.hideCursor();
|
||||
self.screen.grabKeys = false;
|
||||
|
@ -4286,6 +4302,13 @@ Textarea.prototype.readInput = function(callback) {
|
|||
self.screen.restoreFocus();
|
||||
}
|
||||
|
||||
if (self.options.inputOnFocus) {
|
||||
self.screen.rewindFocus();
|
||||
}
|
||||
|
||||
// Ugly
|
||||
if (err === 'stop') return;
|
||||
|
||||
if (err) {
|
||||
self.emit('error', err);
|
||||
} else if (value != null) {
|
||||
|
@ -4295,24 +4318,22 @@ Textarea.prototype.readInput = function(callback) {
|
|||
}
|
||||
self.emit('action', value);
|
||||
|
||||
self._callbacks.forEach(function(callback) {
|
||||
return err
|
||||
? callback(err)
|
||||
: callback(null, value);
|
||||
});
|
||||
if (!callback) return;
|
||||
|
||||
delete self._callbacks;
|
||||
return err
|
||||
? callback(err)
|
||||
: callback(null, value);
|
||||
};
|
||||
|
||||
this.__listener = this._listener.bind(this);
|
||||
this.on('keypress', this.__listener);
|
||||
|
||||
this.__callback = this._callback.bind(this, null, null);
|
||||
this.on('blur', this.__callback);
|
||||
this.__done = this._done.bind(this, null, null);
|
||||
this.on('blur', this.__done);
|
||||
};
|
||||
|
||||
Textarea.prototype._listener = function(ch, key) {
|
||||
var callback = this._callback
|
||||
var done = this._done
|
||||
, value = this.value;
|
||||
|
||||
if (key.name === 'enter') {
|
||||
|
@ -4325,14 +4346,22 @@ Textarea.prototype._listener = function(ch, key) {
|
|||
;
|
||||
}
|
||||
|
||||
if (this.options.keys && key.ctrl && key.name === 'e') {
|
||||
return this.readEditor();
|
||||
}
|
||||
|
||||
// TODO: Optimize typing by writing directly
|
||||
// to the screen and screen buffer here.
|
||||
if (key.name === 'escape') {
|
||||
callback(null, key.name === 'enter' ? value : null);
|
||||
done(null, null);
|
||||
} else if (key.name === 'backspace') {
|
||||
if (this.value.length) {
|
||||
this.value = this.value.slice(0, -1);
|
||||
}
|
||||
} else if (ch) {
|
||||
this.value += ch;
|
||||
if (!/^[\x00-\x08\x0b-\x0c\x0e-\x1f\x7f]$/.test(ch)) {
|
||||
this.value += ch;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.value !== value) {
|
||||
|
@ -4373,11 +4402,13 @@ Textarea.prototype.clearValue = function() {
|
|||
};
|
||||
|
||||
Textarea.prototype.submit = function() {
|
||||
return this._listener('\x1b', { name: 'escape' });
|
||||
if (!this.__listener) return;
|
||||
return this.__listener('\x1b', { name: 'escape' });
|
||||
};
|
||||
|
||||
Textarea.prototype.cancel = function() {
|
||||
return this._listener('\x1b', { name: 'escape' });
|
||||
if (!this.__listener) return;
|
||||
return this.__listener('\x1b', { name: 'escape' });
|
||||
};
|
||||
|
||||
Textarea.prototype._render = Box.prototype.render;
|
||||
|
@ -4390,6 +4421,19 @@ Textarea.prototype.editor =
|
|||
Textarea.prototype.setEditor =
|
||||
Textarea.prototype.readEditor = function(callback) {
|
||||
var self = this;
|
||||
|
||||
if (this._reading) {
|
||||
var _cb = this._callback
|
||||
, cb = callback;
|
||||
|
||||
this._done('stop');
|
||||
|
||||
callback = function(err, value) {
|
||||
if (_cb) _cb(err, value);
|
||||
if (cb) cb(err, value);
|
||||
};
|
||||
}
|
||||
|
||||
return this.screen.readEditor({ value: this.value }, function(err, value) {
|
||||
if (err) return callback && callback(err);
|
||||
self.setValue(value);
|
||||
|
@ -4426,7 +4470,7 @@ Textbox.prototype.type = 'textbox';
|
|||
Textbox.prototype.__olistener = Textbox.prototype._listener;
|
||||
Textbox.prototype._listener = function(ch, key) {
|
||||
if (key.name === 'enter') {
|
||||
this._callback(null, key.name === 'enter' ? this.value : null);
|
||||
this._done(null, this.value);
|
||||
return;
|
||||
}
|
||||
return this.__olistener(ch, key);
|
||||
|
@ -4454,6 +4498,11 @@ Textbox.prototype.setValue = function(value) {
|
|||
}
|
||||
};
|
||||
|
||||
Textarea.prototype.submit = function() {
|
||||
if (!this.__listener) return;
|
||||
return this.__listener('\r', { name: 'enter' });
|
||||
};
|
||||
|
||||
/**
|
||||
* Button
|
||||
*/
|
||||
|
|
|
@ -213,11 +213,17 @@ var input = blessed.textbox({
|
|||
width: '30%',
|
||||
height: 3,
|
||||
right: 0,
|
||||
top: 2
|
||||
top: 2,
|
||||
keys: true,
|
||||
vi: true,
|
||||
mouse: true
|
||||
//inputOnFocus: true
|
||||
});
|
||||
|
||||
input.on('submit', function() {
|
||||
input.on('submit', function(value) {
|
||||
if (value) screen.children[0].setContent(value);
|
||||
input.clearInput();
|
||||
screen.render();
|
||||
});
|
||||
|
||||
screen.append(input);
|
||||
|
@ -240,6 +246,7 @@ var button = blessed.Button({
|
|||
|
||||
button.on('press', function() {
|
||||
button.setContent('Clicked!');
|
||||
screen.render();
|
||||
});
|
||||
|
||||
screen.append(button);
|
||||
|
@ -247,19 +254,19 @@ screen.append(button);
|
|||
screen.on('keypress', function(ch, key) {
|
||||
if (key.name === 'tab') {
|
||||
return key.shift
|
||||
? screen.focusPrev()
|
||||
? screen.focusPrevious()
|
||||
: screen.focusNext();
|
||||
}
|
||||
if (key.name === 'i') {
|
||||
return input.readInput(function(err, value) {
|
||||
if (value) screen.children[0].setContent(value);
|
||||
});
|
||||
}
|
||||
if (key.name === 'e') {
|
||||
return input.readEditor(function(err, value) {
|
||||
if (value) screen.children[0].setContent(value);
|
||||
});
|
||||
}
|
||||
//if (key.name === 'i') {
|
||||
// return input.readInput(function(err, value) {
|
||||
// ;
|
||||
// });
|
||||
//}
|
||||
//if (key.name === 'e') {
|
||||
// return input.readEditor(function(err, value) {
|
||||
// ;
|
||||
// });
|
||||
//}
|
||||
if (key.name === 'escape' || key.name === 'q') {
|
||||
return process.exit(0);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue