mirror of
https://github.com/embarklabs/neo-blessed.git
synced 2025-02-02 14:14:41 +00:00
add mouse support
This commit is contained in:
parent
8eaad35dfa
commit
a10edf116e
231
lib/program.js
231
lib/program.js
@ -57,6 +57,10 @@ Program.prototype.listen = function() {
|
||||
self.emit('keypress', ch, key);
|
||||
});
|
||||
|
||||
this.input.on('data', function(data) {
|
||||
self.emit('data', data);
|
||||
});
|
||||
|
||||
readline.emitKeypressEvents(this.input);
|
||||
|
||||
this.input.resume();
|
||||
@ -72,6 +76,162 @@ Program.prototype.listen = function() {
|
||||
// self.x = cursor.x;
|
||||
// self.y = cursor.y;
|
||||
// });
|
||||
|
||||
this.on('newListener', function fn(type) {
|
||||
if (type === 'mouse') {
|
||||
self.removeListener('newListener', fn);
|
||||
self.bindMouse();
|
||||
}
|
||||
});
|
||||
|
||||
this.setMouse({ normalMouse: true });
|
||||
var i = 5;
|
||||
//this.on('keypress', function(ch, key) {
|
||||
// if (key.name === 'mouse') console.log(key);
|
||||
// if (!--i) this.setMouse({ normalMouse: false });
|
||||
//});
|
||||
this.on('mouse', function(data) {
|
||||
console.log(data);
|
||||
if (!--i) this.setMouse({ normalMouse: false });
|
||||
});
|
||||
};
|
||||
|
||||
// XTerm mouse events
|
||||
// http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking
|
||||
// To better understand these
|
||||
// the xterm code is very helpful:
|
||||
// Relevant files:
|
||||
// button.c, charproc.c, misc.c
|
||||
// Relevant functions in xterm/button.c:
|
||||
// BtnCode, EmitButtonCode, EditorButton, SendMousePosition
|
||||
Program.prototype.bindMouse = function() {
|
||||
this.on('data', this._bindMouse.bind(this));
|
||||
this.bindMouse = function() {};
|
||||
};
|
||||
|
||||
Program.prototype._bindMouse = function(s) {
|
||||
// send a mouse event:
|
||||
// regular/utf8: ^[[M Cb Cx Cy
|
||||
// urxvt: ^[[ Cb ; Cx ; Cy M
|
||||
// sgr: ^[[ Cb ; Cx ; Cy M/m
|
||||
// vt300: ^[[ 24(1/3/5)~ [ Cx , Cy ] \r
|
||||
// locator: CSI P e ; P b ; P r ; P c ; P p & w
|
||||
// motion example of a left click:
|
||||
// ^[[M 3<^[[M@4<^[[M@5<^[[M@6<^[[M@7<^[[M#7<
|
||||
// mouseup, mousedown, mousewheel
|
||||
// left click: ^[[M 3<^[[M#3<
|
||||
// mousewheel up: ^[[M`3>
|
||||
var self = this;
|
||||
|
||||
// FROM: node/lib/readline.js
|
||||
var ch
|
||||
, key = {
|
||||
name: undefined,
|
||||
ctrl: false,
|
||||
meta: false,
|
||||
shift: false
|
||||
}
|
||||
, parts;
|
||||
|
||||
if (Buffer.isBuffer(s)) {
|
||||
if (s[0] > 127 && s[1] === undefined) {
|
||||
s[0] -= 128;
|
||||
s = '\x1b' + s.toString('utf-8');
|
||||
} else {
|
||||
s = s.toString('utf-8');
|
||||
}
|
||||
}
|
||||
|
||||
// XTerm / X10
|
||||
if (parts = /^\x1b\[M([\x20-\x7f\x00]{3})/.exec(s)) {
|
||||
var b = parts[1].charCodeAt(0)
|
||||
, x = parts[1].charCodeAt(1)
|
||||
, y = parts[1].charCodeAt(2);
|
||||
|
||||
key.name = 'mouse';
|
||||
key.type = 'X10';
|
||||
key.button = b;
|
||||
key.x = x - 32;
|
||||
key.y = y - 32;
|
||||
|
||||
self.emit('keypress', null, key);
|
||||
self.emit('mouse', key);
|
||||
return;
|
||||
}
|
||||
|
||||
// URxvt
|
||||
if (parts = /^\x1b\[((?:\d+;){3})M/.exec(s)) {
|
||||
var parts = parts[1].split(';')
|
||||
, b = +parts[0]
|
||||
, x = +parts[1]
|
||||
, y = +parts[2];
|
||||
|
||||
key.name = 'mouse';
|
||||
key.type = 'urxvt';
|
||||
key.button = b;
|
||||
key.x = x;
|
||||
key.y = y;
|
||||
|
||||
self.emit('keypress', null, key);
|
||||
self.emit('mouse', key);
|
||||
return;
|
||||
}
|
||||
|
||||
// SGR
|
||||
if (parts = /^\x1b\[<((?:\d+;){3})([mM])/.exec(s)) {
|
||||
var down = parts[2] === 'm'
|
||||
, parts = parts[1].split(';')
|
||||
, b = +parts[0]
|
||||
, x = +parts[1]
|
||||
, y = +parts[2];
|
||||
|
||||
key.name = 'mouse';
|
||||
key.type = 'sgr';
|
||||
key.button = b;
|
||||
key.x = x;
|
||||
key.y = y;
|
||||
key.down = down;
|
||||
|
||||
self.emit('keypress', null, key);
|
||||
self.emit('mouse', key);
|
||||
return;
|
||||
}
|
||||
|
||||
// DEC
|
||||
if (parts = /^\x1b\[<((?:\d+;){4})&w/.exec(s)) {
|
||||
var parts = parts[1].split(';')
|
||||
, b = +parts[0]
|
||||
, x = +parts[1]
|
||||
, y = +parts[2]
|
||||
, page = +parts[3];
|
||||
|
||||
key.name = 'mouse';
|
||||
key.type = 'dec';
|
||||
key.button = b;
|
||||
key.x = x;
|
||||
key.y = y;
|
||||
|
||||
self.emit('keypress', null, key);
|
||||
self.emit('mouse', key);
|
||||
return;
|
||||
}
|
||||
|
||||
// vt300
|
||||
if (parts = /^\x1b\[24([0135])~\[(\d+),(\d+)\]\r/.exec(s)) {
|
||||
var b = +parts[1]
|
||||
, x = +parts[2]
|
||||
, y = +parts[3];
|
||||
|
||||
key.name = 'mouse';
|
||||
key.type = 'vt300';
|
||||
key.button = b;
|
||||
key.x = x;
|
||||
key.y = y;
|
||||
|
||||
self.emit('keypress', null, key);
|
||||
self.emit('mouse', key);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
Program.prototype.receive = function(text, callback) {
|
||||
@ -1082,6 +1242,77 @@ Program.prototype.normalBuffer = function() {
|
||||
return this.resetMode('?1049');
|
||||
};
|
||||
|
||||
// Set Mouse
|
||||
Program.prototype.setMouse = function(opt) {
|
||||
// Ps = 9 -> Send Mouse X & Y on button press. See the sec-
|
||||
// tion Mouse Tracking.
|
||||
// Ps = 9 -> Don't send Mouse X & Y on button press.
|
||||
// x10 mouse
|
||||
if (opt.x10Mouse != null) {
|
||||
if (opt.x10Mouse) this.setMode('?9');
|
||||
else this.resetMode('?9');
|
||||
}
|
||||
|
||||
// Ps = 1 0 0 0 -> Send Mouse X & Y on button press and
|
||||
// release. See the section Mouse Tracking.
|
||||
// Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and
|
||||
// release. See the section Mouse Tracking.
|
||||
// vt200 mouse
|
||||
if (opt.vt200Mouse != null) {
|
||||
if (opt.vt200Mouse) this.setMode('?1000');
|
||||
else this.resetMode('?1000');
|
||||
}
|
||||
|
||||
// Ps = 1 0 0 1 -> Use Hilite Mouse Tracking.
|
||||
// Ps = 1 0 0 1 -> Don't use Hilite Mouse Tracking.
|
||||
if (opt.hiliteTracking != null) {
|
||||
if (opt.hiliteTracking) this.setMode('?1001');
|
||||
else this.resetMode('?1001');
|
||||
}
|
||||
|
||||
// Ps = 1 0 0 2 -> Use Cell Motion Mouse Tracking.
|
||||
// Ps = 1 0 0 2 -> Don't use Cell Motion Mouse Tracking.
|
||||
// button event mouse
|
||||
if (opt.normalMouse != null) {
|
||||
if (opt.normalMouse) this.setMode('?1002');
|
||||
else this.resetMode('?1002');
|
||||
}
|
||||
|
||||
// Ps = 1 0 0 3 -> Use All Motion Mouse Tracking.
|
||||
// Ps = 1 0 0 3 -> Don't use All Motion Mouse Tracking.
|
||||
// any event mouse
|
||||
if (opt.normalMouse != null) {
|
||||
if (opt.normalMouse) this.setMode('?1003');
|
||||
else this.resetMode('?1003');
|
||||
}
|
||||
|
||||
// Ps = 1 0 0 4 -> Send FocusIn/FocusOut events.
|
||||
// Ps = 1 0 0 4 -> Don't send FocusIn/FocusOut events.
|
||||
if (opt.sendFocus != null) {
|
||||
if (opt.sendFocus) this.setMode('?1004');
|
||||
else this.resetMode('?1004');
|
||||
}
|
||||
|
||||
// Ps = 1 0 0 5 -> Enable Extended Mouse Mode.
|
||||
// Ps = 1 0 0 5 -> Disable Extended Mouse Mode.
|
||||
if (opt.utfMouse != null) {
|
||||
if (opt.utfMouse) this.setMode('?1005');
|
||||
else this.resetMode('?1005');
|
||||
}
|
||||
|
||||
// sgr mouse
|
||||
if (opt.sgrMouse != null) {
|
||||
if (opt.sgrMouse) this.setMode('?1006');
|
||||
else this.resetMode('?1006');
|
||||
}
|
||||
|
||||
// urxvt mouse
|
||||
if (opt.urxvtMouse != null) {
|
||||
if (opt.urxvtMouse) this.setMode('?1015');
|
||||
else this.resetMode('?1015');
|
||||
}
|
||||
};
|
||||
|
||||
// CSI Ps ; Ps r
|
||||
// Set Scrolling Region [top;bottom] (default = full size of win-
|
||||
// dow) (DECSTBM).
|
||||
|
Loading…
x
Reference in New Issue
Block a user