add Log and Table elements. update README.

This commit is contained in:
Christopher Jeffrey 2015-03-30 04:58:15 -07:00
parent c7a6ce60f8
commit 91bc189ba3
3 changed files with 361 additions and 16 deletions

186
README.md
View File

@ -544,14 +544,16 @@ A box with scrollable content.
- __baseLimit__ - a limit to the childBase. default is `Infinity`. - __baseLimit__ - a limit to the childBase. default is `Infinity`.
- __alwaysScroll__ - a option which causes the ignoring of `childOffset`. this - __alwaysScroll__ - a option which causes the ignoring of `childOffset`. this
in turn causes the childBase to change every time the element is scrolled. in turn causes the childBase to change every time the element is scrolled.
- __scrollbar__ - object enabling a scrollbar. allows `ch`, `fg`, and `bg` - __scrollbar__ - object enabling a scrollbar.
properties. - __scrollbar.style__ - style of the scrollbar.
- __scrollbar.track__ - style of the scrollbar track if present (takes regular
style options).
##### Properties: ##### Properties:
- inherits all from Box. - inherits all from Box.
- __childBase__ - the offset of the top of the scroll content. - __childBase__ - the offset of the top of the scroll content.
- __childOffset__ - the offset of the chosen item (if there is one). - __childOffset__ - the offset of the chosen item/line.
##### Events: ##### Events:
@ -605,16 +607,8 @@ A scrollable list which can display selectable items.
##### Options: ##### Options:
- inherits all from Box. - inherits all from Box.
- __selectedFg, selectedBg__ - foreground and background for selected item, - __style.selected__ - style for a selected item.
treated like fg and bg. (can be contained in style: e.g. `style.selected.fg`). - __style.item__ - style for an unselected item.
- __selectedBold, selectedUnderline__ - character attributes for selected item,
treated like bold and underline. (can be contained in style: e.g.
`style.selected.bold`).
- __itemFg, itemBg__ - foreground and background for unselected item,
treated like fg and bg. (can be contained in style: e.g. `style.item.fg`).
- __itemBold, itemUnderline__ - character attributes for an unselected item,
treated like bold and underline. (can be contained in style: e.g.
`style.item.bold`).
- __mouse__ - whether to automatically enable mouse support for this list - __mouse__ - whether to automatically enable mouse support for this list
(allows clicking items). (allows clicking items).
- __keys__ - use predefined keys for navigating the list. - __keys__ - use predefined keys for navigating the list.
@ -790,8 +784,7 @@ A progress bar allowing various styles. This can also be used as a form input.
- inherits all from Input. - inherits all from Input.
- __orientation__ - can be `horizontal` or `vertical`. - __orientation__ - can be `horizontal` or `vertical`.
- __barFg, barBg__ - (completed) bar foreground and background. - __style.bar__ - style of the bar contents itself.
(can be contained in `style`: e.g. `style.bar.fg`).
- __pch__ - the character to fill the bar with (default is space). - __pch__ - the character to fill the bar with (default is space).
- __filled__ - the amount filled (0 - 100). - __filled__ - the amount filled (0 - 100).
- __value__ - same as `filled`. - __value__ - same as `filled`.
@ -920,6 +913,169 @@ A radio button which can be used in a form element.
- inherits all from Checkbox. - inherits all from Checkbox.
#### Prompt (from Box)
A prompt box containing a text input, okay, and cancel buttons.
##### Options:
- inherits all from Box.
##### Properties:
- inherits all from Box.
##### Events:
- inherits all from Box.
##### Methods:
- inherits all from Box.
#### Question (from Box)
A question box containing okay and cancel buttons.
##### Options:
- inherits all from Box.
##### Properties:
- inherits all from Box.
##### Events:
- inherits all from Box.
##### Methods:
- inherits all from Box.
#### Message (from Box)
A box containing a message to be displayed.
##### Options:
- inherits all from Box.
##### Properties:
- inherits all from Box.
##### Events:
- inherits all from Box.
##### Methods:
- inherits all from Box.
#### Loading (from Box)
A box with a spinning line to denote loading.
##### Options:
- inherits all from Box.
##### Properties:
- inherits all from Box.
##### Events:
- inherits all from Box.
##### Methods:
- inherits all from Box.
#### Listbar (from Box)
A horizontal list. Useful for a main menu bar.
##### Options:
- inherits all from Box.
- __style.selected__ - style for a selected item.
- __style.item__ - style for an unselected item.
##### Properties:
- inherits all from Box.
##### Events:
- inherits all from Box.
##### Methods:
- inherits all from Box.
#### Log (from ScrollableText)
A log permanently scrolled to the bottom.
##### Options:
- inherits all from ScrollableText.
##### Properties:
- inherits all from ScrollableText.
##### Events:
- inherits all from ScrollableText.
- __line__ - emitted on a log line. passes in line.
##### Methods:
- inherits all from ScrollableText.
- __log/add(text)__ - add a log line.
#### Table (from Box)
A stylized table of text elements.
##### Options:
- inherits all from Box.
- __rows/data__ - array of array of strings representing rows.
- __pad__ - spaces to attempt to pad on the sides of each cell. `2` by default:
one space on each side.
- __style.header__ - header style.
- __style.cell__ - cell style.
##### Properties:
- inherits all from Box.
##### Events:
- inherits all from Box.
##### Methods:
- inherits all from Box.
- __setRows/setData(rows)__ - set rows in table. array of arrays of strings.
```
table.setData([
[ 'Animals', 'Foods' ],
[ 'Elephant', 'Apple' ],
[ 'Bird', 'Orange' ]
]);
```
#### Terminal (from Box) #### Terminal (from Box)
A box which spins up a pseudo terminal and renders the output. Useful for A box which spins up a pseudo terminal and renders the output. Useful for

View File

@ -2180,6 +2180,7 @@ Element.prototype.setContent = function(content, noClear, noTags) {
if (!noClear) this.clearPos(); if (!noClear) this.clearPos();
this.content = content || ''; this.content = content || '';
this.parseContent(noTags); this.parseContent(noTags);
this.emit('set content');
}; };
Element.prototype.getContent = function() { Element.prototype.getContent = function() {
@ -6747,6 +6748,152 @@ Listbar.prototype.selectTab = function(index) {
} }
}; };
/**
* Log
*/
function Log(options) {
var self = this;
if (!(this instanceof Node)) {
return new Log(options);
}
options = options || {};
ScrollableText.call(this, options);
this.on('set content', function() {
nextTick(function() {
self.setScrollPerc(100);
});
});
}
Log.prototype.__proto__ = ScrollableText.prototype;
Log.prototype.type = 'log';
Log.prototype.log =
Log.prototype.add = function(text) {
this.emit('line', text);
return this.pushLine(text);
};
/**
* Table
* TODO: Draw custom border with proper angles.
*/
function Table(options) {
var self = this;
if (!(this instanceof Node)) {
return new Table(options);
}
options = options || {};
options.shrink = true;
Box.call(this, options);
this.parseTags = true;
this.pad = options.pad != null
? options.pad
: 2;
this.setData(options.rows || options.data);
}
Table.prototype.__proto__ = Box.prototype;
Table.prototype.type = 'table';
Table.prototype.setRows =
Table.prototype.setData = function(rows) {
var self = this
, text = ''
, maxes = []
, total = 0
, line = '';
// TODO Pregenerate `generateTags` calls here!
this.rows = rows || [];
this.rows.forEach(function(row) {
row.forEach(function(cell, i) {
if (!maxes[i] || maxes[i] < cell.length + self.pad) {
maxes[i] = cell.length + self.pad;
}
});
});
maxes.forEach(function(cell) {
total += cell + 1 + self.pad;
});
// TODO Use these values to render the border
// elsewhere, in the usual border rendering.
this._maxes = maxes;
maxes.forEach(function(width, i) {
if (i !== 0) {
line += '\u253c'; // '┼'
}
for (var i = 0; i < width; i++) {
line += '\u2500'; // '─'
}
});
line = generateTags(self.style.border, line);
this.rows.forEach(function(row, i) {
var isHeader = i === 0;
var isFooter = i === self.rows.length - 1;
row.forEach(function(cell, i) {
var width = maxes[i];
if (i !== 0) {
// text += '\u2502'; // '│'
text += generateTags(self.style.border, '\u2502'); // '│'
}
while (cell.length < width) {
cell = ' ' + cell + ' ';
}
if (cell.length > width) {
// cell = cell.slice(0, -1);
cell = cell.substring(1);
}
// XXX Workaround
if (!self.options.tags) {
cell = helpers.escape(cell);
}
if (isHeader) {
cell = generateTags(self.style.header, cell);
} else {
cell = generateTags(self.style.cell, cell);
}
text += cell;
});
text += '\n';
if (!isFooter) {
text += line + '\n';
}
});
if (text[text.length - 1] === '\n') {
text = text.slice(0, -1);
}
return this.setContent(text);
};
/** /**
* Terminal * Terminal
*/ */
@ -7482,7 +7629,7 @@ function generateTags(style, text) {
var open = '' var open = ''
, close = ''; , close = '';
Object.keys(style).forEach(function(key) { Object.keys(style || {}).forEach(function(key) {
var val = style[key]; var val = style[key];
if (typeof val === 'string') { if (typeof val === 'string') {
val = val.replace(/^light(?!-)/, 'light-'); val = val.replace(/^light(?!-)/, 'light-');
@ -7627,6 +7774,9 @@ exports.Message = exports.message = Message;
exports.Loading = exports.loading = Loading; exports.Loading = exports.loading = Loading;
exports.Listbar = exports.listbar = Listbar; exports.Listbar = exports.listbar = Listbar;
exports.Log = exports.log = Log;
exports.Table = exports.table = Table;
exports.Terminal = exports.terminal = Terminal; exports.Terminal = exports.terminal = Terminal;
exports.Image = exports.image = Image; exports.Image = exports.image = Image;

39
test/widget-table.js Normal file
View File

@ -0,0 +1,39 @@
var blessed = require('../')
, screen;
screen = blessed.screen({
dump: __dirname + '/logs/table.log',
autoPadding: true
});
var table = blessed.table({
parent: screen,
top: 'center',
left: 'center',
data: null,
border: 'line',
style: {
border: {
fg: 'red'
},
header: {
fg: 'blue',
bold: true
},
cell: {
fg: 'magenta'
}
}
});
table.setData([
[ 'Animals', 'Foods', 'Times' ],
[ 'Elephant', 'Apple', '1:00am' ],
[ 'Bird', 'Orange', '2:15pm' ]
]);
screen.key('q', function() {
return process.exit(0);
});
screen.render();