diff --git a/core/color_codes.js b/core/color_codes.js index b1bcff93..0676c780 100644 --- a/core/color_codes.js +++ b/core/color_codes.js @@ -7,6 +7,7 @@ var assert = require('assert'); exports.pipeToAnsi = exports.enigmaToAnsi = enigmaToAnsi; exports.stripPipeCodes = exports.stripEnigmaCodes = stripEnigmaCodes; +exports.pipeStrLen = exports.enigmaStrLen = enigmaStrLen; exports.renegadeToAnsi = renegadeToAnsi; // :TODO: Not really happy with the module name of "color_codes". Would like something better @@ -63,6 +64,14 @@ function enigmaToAnsi(s) { return result; } +function stripEnigmaCodes(s) { + return s.replace(/\|[\d]{2}/g, ''); +} + +function enigmaStrLen(s) { + return stripEnigmaCodes(s).length; +} + function renegadeToAnsi(s) { if(-1 == s.indexOf('|')) { return s; // no pipe codes present @@ -124,8 +133,3 @@ if(-1 == s.indexOf('|')) { return result; } - -function stripEnigmaCodes(s) { - return s.replace(/\|[\d]{2}/g, ''); -} - diff --git a/core/door.js b/core/door.js index e75db66c..88f4ec46 100644 --- a/core/door.js +++ b/core/door.js @@ -23,7 +23,7 @@ function Door(client, exeInfo) { // exeInfo.cwd // exeInfo.encoding -}; +} require('util').inherits(Door, events.EventEmitter); diff --git a/core/menu_view.js b/core/menu_view.js index 6268f863..9ec3cd41 100644 --- a/core/menu_view.js +++ b/core/menu_view.js @@ -40,6 +40,10 @@ function MenuView(options) { this.fillChar = miscUtil.valueWithDefault(options.fillChar, ' ').substr(0, 1); this.justify = options.justify || 'none'; + + this.hasFocusItems = function() { + return !_.isUndefined(self.focusItems); + }; } util.inherits(MenuView, View); @@ -48,14 +52,23 @@ MenuView.prototype.setItems = function(items) { var self = this; if(items) { this.items = []; // :TODO: better way? - items.forEach(function onItem(itemText) { - self.items.push({ - text : itemText - }); + items.forEach(function item(itemText) { + self.items.push( { text : itemText } ); }); } }; +MenuView.prototype.setFocusItems = function(items) { + var self = this; + + if(items) { + this.focusItems = []; + items.forEach(function item(itemText) { + self.focusItems.push( { text : itemText } ); + }); + } +} + MenuView.prototype.setItemSpacing = function(itemSpacing) { itemSpacing = parseInt(itemSpacing); assert(_.isNumber(itemSpacing)); @@ -68,6 +81,7 @@ MenuView.prototype.setPropertyValue = function(propName, value) { switch(propName) { case 'itemSpacing' : this.setItemSpacing(value); break; case 'items' : this.setItems(value); break; + case 'focusItems' : this.setFocusItems(value); break; case 'hotKeys' : this.setHotKeys(value); break; } diff --git a/core/system_menu_method.js b/core/system_menu_method.js index f35d1498..c94db3be 100644 --- a/core/system_menu_method.js +++ b/core/system_menu_method.js @@ -128,7 +128,7 @@ function logoff(callingMenu, formData, extraArgs) { // client.term.write( ansi.normal() + '\n' + - require('crypto').randomBytes(Math.floor(Math.random() * 25) + 5).toString() + + require('crypto').randomBytes(Math.floor(Math.random() * 35) + 10).toString(client.term.outputEncoding) + 'NO CARRIER'); client.end(); diff --git a/core/vertical_menu_view.js b/core/vertical_menu_view.js index 38c3f246..de317972 100644 --- a/core/vertical_menu_view.js +++ b/core/vertical_menu_view.js @@ -5,6 +5,7 @@ var MenuView = require('./menu_view.js').MenuView; var ansi = require('./ansi_term.js'); var strUtil = require('./string_util.js'); var miscUtil = require('./misc_util.js'); +var colorCodes = require('./color_codes.js'); var util = require('util'); var assert = require('assert'); @@ -48,6 +49,7 @@ function VerticalMenuView(options) { }; }; + /* this.drawItem = function(index) { var item = self.items[index]; if(!item) { @@ -61,6 +63,47 @@ function VerticalMenuView(options) { strUtil.pad(text, this.dimens.width, this.fillChar, this.justify) ); }; + */ + + this.drawItem = function(index) { + var item = self.items[index]; + + if(!item) { + return; + } + + var focusItem; + var text; + + if(self.hasFocusItems()) { + focusItem = self.focusItems[index]; + } + + if(focusItem) { + if(item.focused) { + text = strUtil.stylizeString(focusItem.text, self.focusTextStyle); + } else { + text = strUtil.stylizeString(item.text, self.textStyle); + } + + // :TODO: Need to support pad() + // :TODO: shoudl we detect if pipe codes are used? + self.client.term.write( + ansi.goto(item.row, self.position.col) + + colorCodes.enigmaToAnsi(text) + ); + + } else { + text = strUtil.stylizeString(item.text, item.focused ? self.focusTextStyle : self.textStyle); + + self.client.term.write( + ansi.goto(item.row, self.position.col) + + (index === self.focusedItemIndex ? self.getFocusSGR() : self.getSGR()) + + strUtil.pad(text, this.dimens.width, this.fillChar, this.justify) + ); + } + + }; } util.inherits(VerticalMenuView, MenuView); @@ -161,6 +204,12 @@ VerticalMenuView.prototype.setItems = function(items) { this.positionCacheExpired = true; }; +VerticalMenuView.prototype.setFocusItems = function(items) { + VerticalMenuView.super_.prototype.setFocusItems.call(this, items); + + this.positionCacheExpired = true; +} + VerticalMenuView.prototype.setItemSpacing = function(itemSpacing) { VerticalMenuView.super_.prototype.setItemSpacing.call(this, itemSpacing); diff --git a/mods/abracadabra.js b/mods/abracadabra.js index a5b928be..c25edfad 100644 --- a/mods/abracadabra.js +++ b/mods/abracadabra.js @@ -153,11 +153,11 @@ function AbracadabraModule(options) { self.client.term.write(ansi.resetScreen()); doorInstance.run(); - } + }; this.fallbackModule = function() { self.client.gotoMenuModule( { name : self.menuConfig.fallback } ); - } + }; } require('util').inherits(AbracadabraModule, MenuModule); diff --git a/mods/art/demo_vertical_menu_view1.ans b/mods/art/demo_vertical_menu_view1.ans new file mode 100644 index 00000000..6ba4156b Binary files /dev/null and b/mods/art/demo_vertical_menu_view1.ans differ diff --git a/mods/menu.json b/mods/menu.json index 91323249..c515662d 100644 --- a/mods/menu.json +++ b/mods/menu.json @@ -571,9 +571,7 @@ "Vertical Menu Views", "Horizontal Menu Views", "Art Display", - "Full Screen Editor", - "Some More Stuff", - "Other" + "Full Screen Editor" ], "height" : 10, "itemSpacing" : 1, @@ -599,6 +597,10 @@ "value" : { "1" : 3 }, "action" : "@menu:demoMultiLineEditTextView" }, + { + "value" : { "1" : 4 }, + "action" : "@menu:demoVerticalMenuView" + }, { "value" : { "1" : 5 }, "action" : "@menu:demoHorizontalMenuView" @@ -817,6 +819,53 @@ } } }, + "demoVerticalMenuView" : { + "art" : "demo_vertical_menu_view1.ans", + "options" : { "cls" : true }, + "form" : { + "0" : { + "BTVM" : { + "mci" : { + "VM1" : { + "items" : [ + "|33Oblivion/2", + "|33iNiQUiTY", + "|33ViSiON/X" + ], + "focusItems" : [ + "|33Oblivion|01/|00|332", + "|01|33i|00|33N|01i|00|33QU|01i|00|33TY", + "|33ViSiON/X" + ] + // + // :TODO: how to do the following: + // 1) Supply a view a string for a standard vs focused item + // "items" : [...], "focusItems" : [ ... ] ? + // "draw" : "@method:drawItemX", then items: [...] + }, + "BT5" : { + "text" : "< Back" + } + }, + "submit" : { + "*" : [ + { + "value" : 5, + "action" : "@menu:demoMain" + } + ] + }, + "actionKeys" : [ + { + "keys" : [ "escape" ], + "viewId" : 5 + } + ] + } + } + } + + }, "demoArtDisplay" : { "art" : "demo_selection_vm.ans", "options" : { "cls" : true }, diff --git a/mods/msg_area_post_fse.js b/mods/msg_area_post_fse.js index 871c145c..1917f67d 100644 --- a/mods/msg_area_post_fse.js +++ b/mods/msg_area_post_fse.js @@ -68,10 +68,6 @@ AreaPostFSEModule.prototype.enter = function(client) { }; AreaPostFSEModule.prototype.validateToUserName = function(un, cb) { - - console.log('bazinga') - - var self = this; if(!self.isLocalEmail()) { diff --git a/mods/msg_list.js b/mods/msg_list.js new file mode 100644 index 00000000..625d2607 --- /dev/null +++ b/mods/msg_list.js @@ -0,0 +1,39 @@ +/* jslint node: true */ +'use strict'; + +var MenuModule = require('../core/menu_module.js').MenuModule; + +exports.getModule = MessageListModule; + +exports.moduleInfo = { + name : 'Message List', + desc : 'Module for listing/browsing available messages', + author : 'NuSkooler', +}; + +// +// :TODO: +// * Avail data: +// To +// From +// Subject +// Date +// Status (New/Read) +// Message Num (Area) +// Message Total (Area) +// Message Area desc +// Message Area Name +// +// Ideas +// * Module config can define custom formats for items & focused items (inc. Pipe Codes) +// * Single list view +// * + +function MessageListModule(options) { + MenuModule.call(this, options); + + var self = this; +} + +require('util').inherits(MessageListModule, MenuModule); +