lots of work for different widgets.

This commit is contained in:
Christopher Jeffrey 2014-01-11 16:52:33 -06:00
parent 5b38ebfefd
commit 045f8d6dc1
2 changed files with 236 additions and 108 deletions

View File

@ -283,6 +283,7 @@ function Screen(options) {
this.dattr = ((0 << 18) | (0x1ff << 9)) | 0x1ff;
this.renders = 0;
this.position = {
left: this.left = this.rleft = 0,
right: this.right = this.rright = 0,
@ -633,6 +634,12 @@ Screen.prototype.render = function() {
this.draw(0, this.rows - 1);
if (this.focused && this.focused._updateCursor) {
this.focused._updateCursor(true);
}
this.renders++;
this.emit('render');
};
@ -2803,7 +2810,8 @@ Element.prototype._getShrinkBox = function(xi, xl, yi, yl, get) {
if (!this.screen.autoPadding) {
xl += this.padding.left + this.padding.right;
} else {
xl += this.padding.right;
//xl += this.padding.right;
xl += this.iright;
}
}
}
@ -2824,7 +2832,8 @@ Element.prototype._getShrinkBox = function(xi, xl, yi, yl, get) {
if (!this.screen.autoPadding) {
yl += this.padding.top + this.padding.bottom;
} else {
yl += this.padding.bottom;
//yl += this.padding.bottom;
yl += this.ibottom;
}
}
}
@ -3020,7 +3029,8 @@ Element.prototype._getCoords = function(get) {
noleft: noleft,
noright: noright,
notop: notop,
nobot: nobot
nobot: nobot,
renders: this.screen.renders
};
};
@ -4507,12 +4517,12 @@ Textarea.prototype.__proto__ = Input.prototype;
Textarea.prototype.type = 'textarea';
Textarea.prototype._updateCursor = function() {
Textarea.prototype._updateCursor = function(get) {
if (this.screen.focused !== this) {
return;
}
var lpos = this._getCoords();
var lpos = get ? this.lpos : this._getCoords();
if (!lpos) return;
var last = this._clines[this._clines.length-1]
@ -5327,6 +5337,8 @@ function Prompt(options) {
options = options || {};
options.hidden = true;
Box.call(this, options);
this._.input = new Textbox({
@ -5419,6 +5431,7 @@ function Question(options) {
}
options = options || {};
options.hidden = true;
Box.call(this, options);
@ -5526,10 +5539,39 @@ Message.prototype.display = function(text, time, callback) {
callback = time;
time = null;
}
time = time || 3;
if (time == null) time = 3;
//time = time || 3;
this.show();
this.setContent(text);
this.screen.render();
if (time === Infinity || time === -1 || time === 0) {
var end = function() {
if (end.done) return;
end.done = true;
self.hide();
self.screen.render();
if (callback) callback();
};
setTimeout(function() {
self.screen.on('keypress', function fn(ch, key) {
if (key.name === 'mouse') return;
self.screen.removeListener('keypress', fn);
end();
});
if (!self.options.mouse) return;
self.screen.on('mouse', function fn(data) {
if (data.action === 'mousemove') return;
self.screen.removeListener('mouse', fn);
end();
});
}, 10);
return;
}
setTimeout(function() {
self.hide();
self.screen.render();
@ -5537,58 +5579,8 @@ Message.prototype.display = function(text, time, callback) {
}, time * 1000);
};
Message.prototype.error = function(text, callback) {
return this.display('{red-fg}Error: ' + text + '{/red-fg}', callback);
};
/**
* Info - TODO: Merge display method into Message?
*/
function Info(options) {
var self = this;
if (!(this instanceof Node)) {
return new Info(options);
}
options = options || {};
Box.call(this, options);
}
Info.prototype.__proto__ = Box.prototype;
Info.prototype.type = 'info';
Info.prototype.display = function(text, callback) {
this.show();
this.setContent(text);
this.screen.render();
function end() {
if (end.done) return;
end.done = true;
self.hide();
self.screen.render();
if (callback) callback();
}
return setTimeout(function() {
self.screen.on('keypress', function fn(ch, key) {
if (key.name === 'mouse') return;
self.screen.removeListener('keypress', fn);
end();
});
if (!self.options.mouse) return;
self.screen.on('mouse', function fn(data) {
if (data.action === 'mousemove') return;
self.screen.removeListener('mouse', fn);
end();
});
}, 10);
Message.prototype.error = function(text, time, callback) {
return this.display('{red-fg}Error: ' + text + '{/red-fg}', time, callback);
};
/**
@ -5711,28 +5703,69 @@ function Listbar(options) {
Box.call(this, options);
/*
this._.debug = new Box({
parent: this.screen,
top: 0,
left: 0,
shrink: true,
content: '...'
});
*/
// XXX Make consistent with vertical lists.
if (this.style.selected) {
this.style.item = this.style.item || merge({}, this.style);
this.style.item.focus = this.style.selected;
}
if (options.commands || options.items) {
this.setItems(options.commands || options.items);
}
if (options.keys) {
this.on('keypress', function(ch, key) {
if (key.name === 'left') {
this.on('element keypress', function(el, ch, key) {
if (key.name === 'left' || (options.vi && key.name === 'h')) {
self.sel(-1);
self.screen.render();
return;
}
if (key.name === 'right') {
if (key.name === 'right' || (options.vi && key.name === 'l')) {
self.sel(1);
self.screen.render();
return;
}
if (key.name === 'enter'
|| (options.vi && key.name === 'k' && !key.shift)) {
self.emit('action', self.items[self.selected], self.selected);
self.emit('select', self.items[self.selected], self.selected);
return;
}
if (key.name === 'escape' || (options.vi && key.name === 'q')) {
self.emit('action');
self.emit('cancel');
return;
}
});
}
if (options.globalKeys) {
this.screen.on('keypress', function(ch, key) {
if (/^[0-9]$/.test(ch)) {
var i = +ch - 1;
if (!~i) i = 9;
var button = self.items[i];
if (button) {
button.press();
button.focus();
}
}
});
}
this.on('focus', function() {
if (self.items[self.leftBase + self.leftOffset]) {
self.items[self.leftBase + self.leftOffset].focus();
if (self.items[self.selected]) {
self.items[self.selected].focus();
}
});
}
@ -5741,17 +5774,27 @@ Listbar.prototype.__proto__ = Box.prototype;
Listbar.prototype.type = 'listbar';
Listbar.prototype.__defineGetter__('selected', function() {
return this.leftBase + this.leftOffset;
});
Listbar.prototype.setOptions =
Listbar.prototype.setCommands =
Listbar.prototype.setItems = function(commands) {
if (Array.isArray(commands)) {
var obj = {};
commands.forEach(function(text, i) {
obj[text] = { prefix: i };
});
commands = obj;
commands = commands.reduce(function(obj, text, i) {
obj[text] = { prefix: ++i + '' };
return obj;
}, {});
}
Object.keys(commands).forEach(function(key, i) {
var cmd = commands[key];
if (typeof cmd === 'function') {
commands[key] = { prefix: ++i + '', callback: cmd };
}
});
this.items.forEach(function(el) {
el.detach();
});
@ -5768,13 +5811,13 @@ Listbar.prototype.setItems = function(commands) {
, len
, button;
title = (cmd.prefix ? '{light-black-fg}'
title = (cmd.prefix != null ? '{light-black-fg}'
+ cmd.prefix
+ '{/light-black-fg}'
+ ':' : '')
+ name;
len = ((cmd.prefix ? cmd.prefix + ':' : '') + name).length;
len = ((cmd.prefix != null ? cmd.prefix + ':' : '') + name).length;
button = new Button({
parent: self,
@ -5784,14 +5827,16 @@ Listbar.prototype.setItems = function(commands) {
content: title,
width: len + 2,
align: 'center',
autoFocus: false,
tags: true,
mouse: true,
style: self.style.item
style: merge({}, self.style.item)
});
self._[name] = button;
cmd.element = button;
self.items.push(button);
button._.cmd = cmd;
if (cmd.callback) {
button.on('press', cmd.callback);
@ -5815,7 +5860,7 @@ Listbar.prototype.render = function() {
el.hide();
} else {
el.left = drawn + 1;
drawn += el.width + 3;
drawn += el.width + 2;
el.show();
}
});
@ -5828,13 +5873,11 @@ Listbar.prototype.select = function(offset) {
if (!lpos) return;
var self = this
, width = lpos.xl - lpos.xi
, width = (lpos.xl - lpos.xi) - this.iwidth
, drawn = 0
, visible = 0
, el;
width = width - this.iwidth;
if (offset < 0) offset = 0;
else if (offset >= this.items.length) offset = this.items.length - 1;
@ -5845,22 +5888,42 @@ Listbar.prototype.select = function(offset) {
if (i < self.leftBase) return;
var lpos = el._getCoords();
if (!lpos) return;
drawn += (lpos.xl - lpos.xi) + 3;
drawn += (lpos.xl - lpos.xi) + 2;
//drawn += el.width + 2;
//drawn += el.getText().length + 2 + 2;
if (drawn <= width) visible++;
});
this.leftOffset = offset;
if (this.leftOffset > visible - 1) {
d = this.leftOffset - (visible - 1);
this.leftOffset -= d;
this.leftBase += d;
} else if (this.leftOffset < 0) {
d = this.leftOffset;
this.leftOffset += -d;
this.leftBase += d;
var diff = offset - (this.leftBase + this.leftOffset);
if (offset > this.leftBase + this.leftOffset) {
if (offset - this.leftBase > visible - 1) {
this.leftOffset -= diff - 1;
this.leftBase += diff;
} else {
this.leftOffset += diff;
}
} else if (offset < this.leftBase + this.leftOffset) {
diff = -diff;
if (offset - this.leftBase < 0) {
this.leftOffset += diff - 1;
//this.leftOffset = 0;
this.leftBase -= diff;
} else {
this.leftOffset -= diff;
}
}
/*
this._.debug.setContent(JSON.stringify({
leftOffset: this.leftOffset,
leftBase: this.leftBase,
drawn: drawn,
visible: visible,
width: width,
diff: diff
}, null, 2));
*/
el.focus();
};
@ -5918,6 +5981,13 @@ Passbox.prototype.type = 'passbox';
* Helpers
*/
function merge(a, b) {
Object.keys(b).forEach(function(key) {
a[key] = b[key];
});
return a;
}
function asort(obj) {
return obj.sort(function(a, b) {
a = a.name.toLowerCase();
@ -5979,7 +6049,6 @@ exports.RadioButton = exports.radiobutton = RadioButton;
exports.Prompt = exports.prompt = Prompt;
exports.Question = exports.question = Question;
exports.Message = exports.message = Message;
exports.Info = exports.info = Info;
exports.Loading = exports.loading = Loading;
exports.PickList = exports.picklist = PickList;
exports.Listbar = exports.listbar = Listbar;

View File

@ -5,13 +5,24 @@ screen = blessed.screen({
dump: __dirname + '/logs/listbar.log'
});
var box = blessed.box({
parent: screen,
top: 0,
right: 0,
width: 'shrink',
height: 'shrink',
content: '...'
});
var bar = blessed.listbar({
parent: screen,
bottom: 0,
left: 0,
height: 1,
mouse: true,
keys: true,
shrinkBox: true,
globalKeys: true,
vi: true,
style: {
bg: 'green',
item: {
@ -19,28 +30,76 @@ var bar = blessed.listbar({
hover: {
bg: 'blue'
},
focus: {
fg: 'blue'
}
//focus: {
// bg: 'blue'
//}
},
selected: {
bg: 'blue'
}
},
items: [
'one',
'two',
'three',
'four',
'five',
'six',
'seven',
'eight',
'nine',
'ten',
'eleven',
'twelve',
'thirteen',
'fourteen',
'fifteen'
]
commands: {
'one': function() {
box.setContent('Pressed one.');
screen.render();
},
'two': function() {
box.setContent('Pressed two.');
screen.render();
},
'three': function() {
box.setContent('Pressed three.');
screen.render();
},
'four': function() {
box.setContent('Pressed four.');
screen.render();
},
'five': function() {
box.setContent('Pressed five.');
screen.render();
},
'six': function() {
box.setContent('Pressed six.');
screen.render();
},
'seven': function() {
box.setContent('Pressed seven.');
screen.render();
},
'eight': function() {
box.setContent('Pressed eight.');
screen.render();
},
'nine': function() {
box.setContent('Pressed nine.');
screen.render();
},
'ten': function() {
box.setContent('Pressed ten.');
screen.render();
},
'eleven': function() {
box.setContent('Pressed eleven.');
screen.render();
},
'twelve': function() {
box.setContent('Pressed twelve.');
screen.render();
},
'thirteen': function() {
box.setContent('Pressed thirteen.');
screen.render();
},
'fourteen': function() {
box.setContent('Pressed fourteen.');
screen.render();
},
'fifteen': function() {
box.setContent('Pressed fifteen.');
screen.render();
}
}
});
bar.focus();