Skip to content

Instantly share code, notes, and snippets.

@OJezu
Created February 24, 2015 01:36
Show Gist options
  • Save OJezu/2474fdcafbfa2fbf70da to your computer and use it in GitHub Desktop.
Save OJezu/2474fdcafbfa2fbf70da to your computer and use it in GitHub Desktop.
blessed-aligned-list
'use strict';
var sprintf = require('sprintf');
var uuid = require('node-uuid');
var Box = require('blessed').Box;
var List = require('blessed').List;
var Node = require('blessed').Node;
var Text = require('blessed').Text;
function AlignedList(options){
if( !(this instanceof AlignedList) ){
return new AlignedList(options);
}
List.call(this, options);
this.selected = -1;
this.interactive = true;
this._columns = this._parseColumns(options.columns);
this._spacer = ' ';
this._header = options.header;
this._headerStyle = options.style && options.style.header || options.headerStyle;
this._top = 0;
this._row_height = 1;
this._addHeader();
}
AlignedList.prototype = Object.create(List.prototype);
AlignedList.prototype.constructor = AlignedList;
AlignedList.prototype._parseColumns = function(columns){
var left = 0;
return columns.map(function(c){
if( typeof(c) === 'object' ){
c = {
left: left,
width: c.width || 10,
align: c.align || 'left',
};
left += c.width+1;
} else {
c = {
left: left,
width: c,
align: 'left',
}
left += c.width+1;
}
return c;
});
};
AlignedList.prototype._addHeader = function _addHeader(){
if(this._header){
this.addRow(this._header, true);
}
}
AlignedList.prototype._parseColumnWidth = function _parseColumnWidth(total, spacing){
if(!spacing){
return [total];
}
var auto_count = spacing.filter(function(e){return e === undefined || e === null;}).length;
var width_left = total - spacing.filter(function(e){return parseInt(e)}).reduce(function(a,b){return a+b}, 0);
return spacing.map(function(e){
if(e !== undefined && e !== null){
return e;
}
var w = Math.max(Math.round(width_left/auto_count), 0);
width_left -= w;
--auto_count;
return w;
});
};
AlignedList.prototype._addCells = function(row, row_style, entries){
this._top += this._row_height;
entries.forEach(function(e, i){
var c = this._columns[i];
var cell;
if(!c){
return;
}
//var cell_options = {};
var cell_options = Object.create(row_style);
cell_options.top = 0;
cell_options.bottom = 0;
cell_options.left = c.left;
cell_options.width = c.width;
console.log(cell_options);
//process.exit();
if( !(e instanceof Node) ){
cell_options.content = e;
cell_options.align = c.align;
cell = Text(cell_options);
} else {
cell = Box(cell_options);
cell.append(e);
}
row.append(cell);
}, this);
}
AlignedList.prototype.addRow = function(entries, unselectable) {
var self = this;
this.ritems.push(entries);
// Note: Could potentially use Button here.
var row_options = {
screen: this.screen,
align: this.align || 'left',
top: this.items.length,
left: 0,
right: (this.scrollbar ? 1 : 0),
tags: this.parseTags,
height: 1,
hoverEffects: this.mouse ? this.style.item.hover : null,
focusEffects: this.mouse ? this.style.item.focus : null,
autoFocus: false,
unselectable: !!unselectable,
};
if (!this.screen.autoPadding) {
row_options.top = this.itop + this.items.length;
row_options.left = this.ileft;
row_options.right = this.iright + (this.scrollbar ? 1 : 0);
}
var cell_options_proto = {};
['bg', 'fg', 'bold', 'underline',
'blink', 'inverse', 'invisible'].forEach(function(name) {
cell_options_proto[name] =
row_options[name] = function() {
var attr = self.items[self.selected] === row && self.interactive
? self.style.selected[name]
: self.style.item[name];
if (typeof attr === 'function') attr = attr(entries);
cell_options_proto[name] = attr;
return attr;
};
});
var row = new Box(row_options);
row.id = uuid.v4();
this._addCells(row, cell_options_proto, entries);
this.items.push(row);
this.append(row);
if ((this.selected < 0 || this.items[this.selected].options.unselectable)
&& !unselectable) {
this.select(this.items.length-1);
}
if (this.mouse) {
row.on('click', function(data) {
if (row_options.unselectable) {
return;
}
if (self.items[self.selected] === row) {
self.emit('action', row, self.selected);
self.emit('select', row, self.selected);
return;
}
self.select(row);
self.screen.render();
});
}
return row.id;
};
AlignedList.prototype.clearRows = function(){
List.prototype.clearItems.call(this);
this._addHeader();
}
module.exports = AlignedList;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment