2014-10-31 04:59:21 +00:00
|
|
|
/* jslint node: true */
|
|
|
|
'use strict';
|
|
|
|
|
2016-07-03 02:02:00 +00:00
|
|
|
// ENiGMA½
|
|
|
|
const View = require('./view.js').View;
|
|
|
|
const miscUtil = require('./misc_util.js');
|
2016-08-11 04:48:13 +00:00
|
|
|
const pipeToAnsi = require('./color_codes.js').pipeToAnsi;
|
2015-04-27 22:04:41 +00:00
|
|
|
|
2016-07-03 02:02:00 +00:00
|
|
|
// deps
|
|
|
|
const util = require('util');
|
|
|
|
const assert = require('assert');
|
|
|
|
const _ = require('lodash');
|
2014-10-31 04:59:21 +00:00
|
|
|
|
|
|
|
exports.MenuView = MenuView;
|
|
|
|
|
2015-04-09 04:54:13 +00:00
|
|
|
function MenuView(options) {
|
2014-10-31 22:25:11 +00:00
|
|
|
options.acceptsFocus = miscUtil.valueWithDefault(options.acceptsFocus, true);
|
2014-11-01 15:50:11 +00:00
|
|
|
options.acceptsInput = miscUtil.valueWithDefault(options.acceptsInput, true);
|
2016-08-11 04:48:13 +00:00
|
|
|
|
2015-04-09 04:54:13 +00:00
|
|
|
View.call(this, options);
|
2014-10-31 04:59:21 +00:00
|
|
|
|
2016-08-11 04:48:13 +00:00
|
|
|
this.disablePipe = options.disablePipe || false;
|
|
|
|
|
2016-07-03 02:02:00 +00:00
|
|
|
const self = this;
|
2014-10-31 22:25:11 +00:00
|
|
|
|
2015-04-09 04:54:13 +00:00
|
|
|
if(options.items) {
|
|
|
|
this.setItems(options.items);
|
2014-11-02 19:07:17 +00:00
|
|
|
} else {
|
|
|
|
this.items = [];
|
2014-10-31 04:59:21 +00:00
|
|
|
}
|
|
|
|
|
2015-04-27 23:27:23 +00:00
|
|
|
this.caseInsensitiveHotKeys = miscUtil.valueWithDefault(options.caseInsensitiveHotKeys, true);
|
|
|
|
|
|
|
|
this.setHotKeys(options.hotKeys);
|
2015-04-27 22:04:41 +00:00
|
|
|
|
2015-04-09 04:54:13 +00:00
|
|
|
this.focusedItemIndex = options.focusedItemIndex || 0;
|
2014-11-01 15:50:11 +00:00
|
|
|
this.focusedItemIndex = this.items.length >= this.focusedItemIndex ? this.focusedItemIndex : 0;
|
|
|
|
|
2015-05-04 21:39:48 +00:00
|
|
|
this.itemSpacing = _.isNumber(options.itemSpacing) ? options.itemSpacing : 0;
|
2014-10-31 22:25:11 +00:00
|
|
|
|
2015-05-06 04:19:21 +00:00
|
|
|
// :TODO: probably just replace this with owner draw / pipe codes / etc. more control, less specialization
|
2015-04-09 04:54:13 +00:00
|
|
|
this.focusPrefix = options.focusPrefix || '';
|
|
|
|
this.focusSuffix = options.focusSuffix || '';
|
2014-11-02 19:07:17 +00:00
|
|
|
|
2015-04-09 04:54:13 +00:00
|
|
|
this.fillChar = miscUtil.valueWithDefault(options.fillChar, ' ').substr(0, 1);
|
|
|
|
this.justify = options.justify || 'none';
|
2015-08-26 05:17:09 +00:00
|
|
|
|
|
|
|
this.hasFocusItems = function() {
|
|
|
|
return !_.isUndefined(self.focusItems);
|
|
|
|
};
|
2015-12-24 02:08:24 +00:00
|
|
|
|
|
|
|
this.getHotKeyItemIndex = function(ch) {
|
|
|
|
if(ch && self.hotKeys) {
|
2016-07-03 02:02:00 +00:00
|
|
|
const keyIndex = self.hotKeys[self.caseInsensitiveHotKeys ? ch.toLowerCase() : ch];
|
2015-12-24 02:08:24 +00:00
|
|
|
if(_.isNumber(keyIndex)) {
|
|
|
|
return keyIndex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
};
|
2014-10-31 04:59:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
util.inherits(MenuView, View);
|
|
|
|
|
2014-11-02 19:07:17 +00:00
|
|
|
MenuView.prototype.setItems = function(items) {
|
2016-08-11 04:48:13 +00:00
|
|
|
const self = this;
|
|
|
|
|
2014-11-02 19:07:17 +00:00
|
|
|
if(items) {
|
2016-07-03 02:02:00 +00:00
|
|
|
this.items = [];
|
|
|
|
items.forEach( itemText => {
|
2016-08-11 04:48:13 +00:00
|
|
|
this.items.push(
|
|
|
|
{
|
|
|
|
text : self.disablePipe ? itemText : pipeToAnsi(itemText, self.client)
|
|
|
|
}
|
|
|
|
);
|
2014-11-02 19:07:17 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-01-05 06:32:43 +00:00
|
|
|
MenuView.prototype.getCount = function() {
|
|
|
|
return this.items.length;
|
|
|
|
};
|
|
|
|
|
2016-07-03 02:02:00 +00:00
|
|
|
MenuView.prototype.getItems = function() {
|
|
|
|
return this.items.map( item => {
|
|
|
|
return item.text;
|
2016-01-05 06:32:43 +00:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2015-09-16 04:44:31 +00:00
|
|
|
MenuView.prototype.getItem = function(index) {
|
|
|
|
return this.items[index].text;
|
|
|
|
};
|
|
|
|
|
2015-09-18 04:53:19 +00:00
|
|
|
MenuView.prototype.focusNext = function() {
|
2015-10-11 22:05:45 +00:00
|
|
|
this.emit('index update', this.focusedItemIndex);
|
2015-09-18 04:53:19 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
MenuView.prototype.focusPrevious = function() {
|
2015-10-11 22:05:45 +00:00
|
|
|
this.emit('index update', this.focusedItemIndex);
|
2015-09-18 04:53:19 +00:00
|
|
|
};
|
|
|
|
|
2015-12-24 02:08:24 +00:00
|
|
|
MenuView.prototype.setFocusItemIndex = function(index) {
|
|
|
|
this.focusedItemIndex = index;
|
|
|
|
};
|
|
|
|
|
|
|
|
MenuView.prototype.onKeyPress = function(ch, key) {
|
2016-07-03 02:02:00 +00:00
|
|
|
const itemIndex = this.getHotKeyItemIndex(ch);
|
2015-12-24 02:08:24 +00:00
|
|
|
if(itemIndex >= 0) {
|
|
|
|
this.setFocusItemIndex(itemIndex);
|
|
|
|
|
|
|
|
if(true === this.hotKeySubmit) {
|
|
|
|
this.emit('action', 'accept');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
MenuView.super_.prototype.onKeyPress.call(this, ch, key);
|
|
|
|
};
|
|
|
|
|
2015-08-26 05:17:09 +00:00
|
|
|
MenuView.prototype.setFocusItems = function(items) {
|
2016-08-11 04:48:13 +00:00
|
|
|
const self = this;
|
|
|
|
|
2015-08-26 05:17:09 +00:00
|
|
|
if(items) {
|
|
|
|
this.focusItems = [];
|
2016-07-03 02:02:00 +00:00
|
|
|
items.forEach( itemText => {
|
2016-08-11 04:48:13 +00:00
|
|
|
this.focusItems.push(
|
|
|
|
{
|
|
|
|
text : self.disablePipe ? itemText : pipeToAnsi(itemText, self.client)
|
|
|
|
}
|
|
|
|
);
|
2015-08-26 05:17:09 +00:00
|
|
|
});
|
|
|
|
}
|
2015-10-11 22:05:45 +00:00
|
|
|
};
|
2015-08-26 05:17:09 +00:00
|
|
|
|
2015-05-04 21:39:48 +00:00
|
|
|
MenuView.prototype.setItemSpacing = function(itemSpacing) {
|
2015-06-30 05:14:17 +00:00
|
|
|
itemSpacing = parseInt(itemSpacing);
|
2015-05-04 21:39:48 +00:00
|
|
|
assert(_.isNumber(itemSpacing));
|
|
|
|
|
|
|
|
this.itemSpacing = itemSpacing;
|
|
|
|
this.positionCacheExpired = true;
|
|
|
|
};
|
|
|
|
|
2015-06-30 05:14:17 +00:00
|
|
|
MenuView.prototype.setPropertyValue = function(propName, value) {
|
|
|
|
switch(propName) {
|
2016-08-04 04:43:06 +00:00
|
|
|
case 'itemSpacing' : this.setItemSpacing(value); break;
|
|
|
|
case 'items' : this.setItems(value); break;
|
|
|
|
case 'focusItems' : this.setFocusItems(value); break;
|
|
|
|
case 'hotKeys' : this.setHotKeys(value); break;
|
|
|
|
case 'hotKeySubmit' : this.hotKeySubmit = value; break;
|
|
|
|
case 'justify' : this.justify = value; break;
|
2015-06-30 05:14:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
MenuView.super_.prototype.setPropertyValue.call(this, propName, value);
|
|
|
|
};
|
|
|
|
|
2015-04-27 23:27:23 +00:00
|
|
|
MenuView.prototype.setHotKeys = function(hotKeys) {
|
|
|
|
if(_.isObject(hotKeys)) {
|
|
|
|
if(this.caseInsensitiveHotKeys) {
|
|
|
|
this.hotKeys = {};
|
|
|
|
for(var key in hotKeys) {
|
|
|
|
this.hotKeys[key.toLowerCase()] = hotKeys[key];
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
this.hotKeys = hotKeys;
|
2015-06-05 22:20:26 +00:00
|
|
|
}
|
2015-04-27 22:04:41 +00:00
|
|
|
}
|
2015-05-06 04:19:21 +00:00
|
|
|
};
|
2015-04-27 22:04:41 +00:00
|
|
|
|