mirror of
https://github.com/embarklabs/neo-blessed.git
synced 2025-01-11 03:25:45 +00:00
optimize clickable sort. better autofocus. flush on exception.
This commit is contained in:
parent
b2666ffecb
commit
d3c34f6f89
@ -104,7 +104,9 @@ EventEmitter.prototype.emit = function(type) {
|
|||||||
return this._emit(type, args);
|
return this._emit(type, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._emit(type, args);
|
if (this._emit(type, args) === false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
type = 'element ' + type;
|
type = 'element ' + type;
|
||||||
args.unshift(this);
|
args.unshift(this);
|
||||||
@ -132,6 +134,7 @@ EventEmitter.prototype.emit = function(type) {
|
|||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// this._emit.apply(this, arguments);
|
// this._emit.apply(this, arguments);
|
||||||
|
// if (this._bubbleStopped) return false;
|
||||||
//
|
//
|
||||||
// args = slice.call(arguments, 1);
|
// args = slice.call(arguments, 1);
|
||||||
// el = this;
|
// el = this;
|
||||||
|
@ -67,8 +67,16 @@ function Program(options) {
|
|||||||
|| 'xterm';
|
|| 'xterm';
|
||||||
|
|
||||||
this._buf = '';
|
this._buf = '';
|
||||||
this.__flush = this._flush.bind(this);
|
this._flush = this.flush.bind(this);
|
||||||
process.on('exit', this.__flush);
|
|
||||||
|
unshiftEvent(process, 'exit', function() {
|
||||||
|
// Ensure the buffer is flushed (it should
|
||||||
|
// always be at this point, but who knows).
|
||||||
|
self.flush();
|
||||||
|
// Ensure _exiting is set (could technically
|
||||||
|
// use process._exiting).
|
||||||
|
self._exiting = true;
|
||||||
|
});
|
||||||
|
|
||||||
if (!Program.global) {
|
if (!Program.global) {
|
||||||
Program.global = this;
|
Program.global = this;
|
||||||
@ -1238,8 +1246,8 @@ Program.prototype._parseChar = function(text, attr) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Program.prototype._buffer = function(text) {
|
Program.prototype._buffer = function(text) {
|
||||||
if (process._exiting) {
|
if (this._exiting) {
|
||||||
this._flush();
|
this.flush();
|
||||||
this.output.write(text);
|
this.output.write(text);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1251,10 +1259,10 @@ Program.prototype._buffer = function(text) {
|
|||||||
|
|
||||||
this._buf = text;
|
this._buf = text;
|
||||||
|
|
||||||
process.nextTick(this.__flush);
|
process.nextTick(this._flush);
|
||||||
};
|
};
|
||||||
|
|
||||||
Program.prototype._flush = function(text) {
|
Program.prototype.flush = function(text) {
|
||||||
if (!this._buf) return;
|
if (!this._buf) return;
|
||||||
this.output.write(this._buf);
|
this.output.write(this._buf);
|
||||||
this._buf = '';
|
this._buf = '';
|
||||||
@ -3526,12 +3534,6 @@ function unshiftEvent(obj, event, listener) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Ensure _exiting is set for future versions of node that may remove it.
|
|
||||||
// We need this to be the first listener executed.
|
|
||||||
unshiftEvent(process, 'exit', function() {
|
|
||||||
process._exiting = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expose
|
* Expose
|
||||||
*/
|
*/
|
||||||
|
@ -266,6 +266,7 @@ function Screen(options) {
|
|||||||
options = { program: options };
|
options = { program: options };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
options.tput = true;
|
||||||
options.buffer = true;
|
options.buffer = true;
|
||||||
options.program = options.program
|
options.program = options.program
|
||||||
|| require('./program').global
|
|| require('./program').global
|
||||||
@ -368,6 +369,7 @@ function Screen(options) {
|
|||||||
if (self._listenedMouse) {
|
if (self._listenedMouse) {
|
||||||
self.program.disableMouse();
|
self.program.disableMouse();
|
||||||
}
|
}
|
||||||
|
self.program.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
this._maxListeners = Infinity;
|
this._maxListeners = Infinity;
|
||||||
@ -420,16 +422,15 @@ Screen.prototype.debug = function() {
|
|||||||
return this.program.debug.apply(this.program, arguments);
|
return this.program.debug.apply(this.program, arguments);
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Bubble and capture events throughout the tree.
|
|
||||||
Screen.prototype._listenMouse = function(el) {
|
Screen.prototype._listenMouse = function(el) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if (el && !~this.clickable.indexOf(el)) {
|
if (el && !~this.clickable.indexOf(el)) {
|
||||||
el.clickable = true;
|
el.clickable = true;
|
||||||
if (el.options.autoFocus && !el._autoFocused) {
|
// if (el.options.autoFocus !== false && !el._autoFocused) {
|
||||||
el._autoFocused = true;
|
// el._autoFocused = true;
|
||||||
el.on('element click', el.focus.bind(el));
|
// el.on('element click', el.focus.bind(el));
|
||||||
}
|
// }
|
||||||
this.clickable.push(el);
|
this.clickable.push(el);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -438,11 +439,19 @@ Screen.prototype._listenMouse = function(el) {
|
|||||||
|
|
||||||
this.program.enableMouse();
|
this.program.enableMouse();
|
||||||
|
|
||||||
|
this.on('render', function() {
|
||||||
|
self._needsClickableSort = true;
|
||||||
|
});
|
||||||
|
|
||||||
this.program.on('mouse', function(data) {
|
this.program.on('mouse', function(data) {
|
||||||
if (self.lockKeys) return;
|
if (self.lockKeys) return;
|
||||||
|
|
||||||
var clickable = hsort(self.clickable)
|
if (self._needsClickableSort) {
|
||||||
, i = 0
|
self.clickable = hsort(self.clickable);
|
||||||
|
self._needsClickableSort = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var i = 0
|
||||||
, left
|
, left
|
||||||
, top
|
, top
|
||||||
, width
|
, width
|
||||||
@ -451,19 +460,15 @@ Screen.prototype._listenMouse = function(el) {
|
|||||||
, set
|
, set
|
||||||
, ret;
|
, ret;
|
||||||
|
|
||||||
for (; i < clickable.length; i++) {
|
for (; i < self.clickable.length; i++) {
|
||||||
el = clickable[i];
|
el = self.clickable[i];
|
||||||
|
|
||||||
if (!el.visible) continue;
|
if (!el.visible) continue;
|
||||||
|
|
||||||
// Something like (doesn't work because textbox is usually focused):
|
// if (self.grabMouse && self.focused !== el
|
||||||
// if (self.grabKeys && self.focused !== el
|
|
||||||
// && !el.hasAncestor(self.focused)) continue;
|
// && !el.hasAncestor(self.focused)) continue;
|
||||||
|
|
||||||
// Need to use _getCoords() over lpos for when the
|
ret = el.lpos;
|
||||||
// element is obfuscated by a scrollable parent.
|
|
||||||
ret = el._getCoords();
|
|
||||||
//ret = el.lpos;
|
|
||||||
if (!ret) continue;
|
if (!ret) continue;
|
||||||
left = ret.xi;
|
left = ret.xi;
|
||||||
top = ret.yi;
|
top = ret.yi;
|
||||||
@ -506,9 +511,19 @@ Screen.prototype._listenMouse = function(el) {
|
|||||||
|
|
||||||
self.emit('mouse', data);
|
self.emit('mouse', data);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Autofocus elements with the appropriate option.
|
||||||
|
this.on('element click', function(el, data) {
|
||||||
|
var target;
|
||||||
|
//do {
|
||||||
|
if (el.clickable === true && el.options.autoFocus !== false) {
|
||||||
|
target = el;
|
||||||
|
}
|
||||||
|
//} while (el = el.parent);
|
||||||
|
if (target) target.focus();
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Bubble and capture events throughout the tree.
|
|
||||||
Screen.prototype._listenKeys = function(el) {
|
Screen.prototype._listenKeys = function(el) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
@ -516,14 +531,14 @@ Screen.prototype._listenKeys = function(el) {
|
|||||||
el.keyable = true;
|
el.keyable = true;
|
||||||
// Listen for click, but do not enable
|
// Listen for click, but do not enable
|
||||||
// mouse if it's not enabled yet.
|
// mouse if it's not enabled yet.
|
||||||
if (el.options.autoFocus !== false && !el._autoFocused) {
|
// if (el.options.autoFocus !== false && !el._autoFocused) {
|
||||||
el._autoFocused = true;
|
// el._autoFocused = true;
|
||||||
var lm = this._listenedMouse;
|
// var lm = this._listenedMouse;
|
||||||
this._listenedMouse = true;
|
// this._listenedMouse = true;
|
||||||
this._listenMouse(el);
|
// this._listenMouse(el);
|
||||||
el.on('element click', el.focus.bind(el));
|
// el.on('element click', el.focus.bind(el));
|
||||||
this._listenedMouse = lm;
|
// this._listenedMouse = lm;
|
||||||
}
|
// }
|
||||||
this.keyable.push(el);
|
this.keyable.push(el);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1131,7 +1146,7 @@ Screen.prototype.draw = function(start, end) {
|
|||||||
: '\x1b[?25h';
|
: '\x1b[?25h';
|
||||||
}
|
}
|
||||||
|
|
||||||
// this.program._flush();
|
// this.program.flush();
|
||||||
// this.program.output.write(pre + main + post);
|
// this.program.output.write(pre + main + post);
|
||||||
this.program._write(pre + main + post);
|
this.program._write(pre + main + post);
|
||||||
}
|
}
|
||||||
@ -3911,6 +3926,7 @@ List.prototype.type = 'list';
|
|||||||
List.prototype.add = function(item) {
|
List.prototype.add = function(item) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
// Note: Could potentially use Button here.
|
||||||
var options = {
|
var options = {
|
||||||
screen: this.screen,
|
screen: this.screen,
|
||||||
content: item,
|
content: item,
|
||||||
@ -3921,7 +3937,8 @@ List.prototype.add = function(item) {
|
|||||||
tags: this.parseTags,
|
tags: this.parseTags,
|
||||||
height: 1,
|
height: 1,
|
||||||
hoverEffects: this.mouse ? this.style.item.hover : null,
|
hoverEffects: this.mouse ? this.style.item.hover : null,
|
||||||
focusEffects: this.mouse ? this.style.item.focus : null
|
focusEffects: this.mouse ? this.style.item.focus : null,
|
||||||
|
autoFocus: false
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.screen.autoPadding) {
|
if (this.screen.autoPadding) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user