From 34bf823f1f4e1692b5b8ecb1a4103308fffaef57 Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Wed, 13 May 2015 22:21:55 -0600 Subject: [PATCH] * Some solid progress on themeing / customization via theme.json --- core/client.js | 2 +- core/config.js | 9 +++++++ core/menu_module.js | 1 + core/menu_util.js | 39 +++++++++++++++++++++++++--- core/theme.js | 4 +-- core/view_controller.js | 14 +++++++++- mods/art/themes/NU-MAYA/theme.json | 41 ++++++++++++++++++++---------- mods/menu.json | 20 +++++++-------- 8 files changed, 98 insertions(+), 32 deletions(-) diff --git a/core/client.js b/core/client.js index bbe768d6..b6ba9902 100644 --- a/core/client.js +++ b/core/client.js @@ -89,7 +89,7 @@ function Client(input, output) { this.output = output; this.term = new term.ClientTerminal(this.output); this.user = new user.User(); - this.currentThemeInfo = { name : 'N/A', description : 'None' }; + this.currentTheme = { info : { name : 'N/A', description : 'None' } }; // // Peek at |data| and emit for any specialized handling diff --git a/core/config.js b/core/config.js index ce7bc945..926b7158 100644 --- a/core/config.js +++ b/core/config.js @@ -93,6 +93,15 @@ function getDefaultConfig() { passwordChar : '*', // TODO: move to user ? }, + /* + Concept + "theme" : { + "default" : "defaultThemeName", // or "*" + "passwordChar" : "*", + ... + } + */ + paths : { mods : paths.join(__dirname, './../mods/'), servers : paths.join(__dirname, './servers/'), diff --git a/core/menu_module.js b/core/menu_module.js index 563ab3c7..1e369598 100644 --- a/core/menu_module.js +++ b/core/menu_module.js @@ -20,6 +20,7 @@ function MenuModule(options) { PluginModule.call(this, options); var self = this; + this.menuName = options.menuName; this.menuConfig = options.menuConfig; this.menuConfig.options = options.menuConfig.options || {}; this.menuMethods = {}; // methods called from @method's diff --git a/core/menu_util.js b/core/menu_util.js index e474d290..1a69fb4e 100644 --- a/core/menu_util.js +++ b/core/menu_util.js @@ -17,9 +17,10 @@ var _ = require('lodash'); var stripJsonComments = require('strip-json-comments'); -exports.loadMenu = loadMenu; -exports.getFormConfigByIDAndMap = getFormConfigByIDAndMap; -exports.handleAction = handleAction; +exports.loadMenu = loadMenu; +exports.getFormConfigByIDAndMap = getFormConfigByIDAndMap; +exports.handleAction = handleAction; +exports.applyThemeCustomization = applyThemeCustomization; function loadModJSON(fileName, cb) { @@ -119,7 +120,12 @@ function loadMenu(options, cb) { 'Creating menu module instance'); try { - var moduleInstance = new modData.mod.getModule( { menuConfig : modData.config, args : options.args } ); + var moduleInstance = new modData.mod.getModule( + { + menuName : options.name, + menuConfig : modData.config, + args : options.args, + }); callback(null, moduleInstance); } catch(e) { callback(e); @@ -205,3 +211,28 @@ function handleAction(client, formData, conf) { break; } } + +function applyThemeCustomization(options) { + // + // options.name : menu/prompt name + // options.configMci : menu or prompt config (menu.json / prompt.json) specific mci section + // options.client : client + // + assert(_.isString(options.name)); + assert(_.isObject(options.client)); + + console.log(options.configMci) + + if(_.isUndefined(options.configMci)) { + options.configMci = {}; + } + + if(_.has(options.client.currentTheme, [ 'customization', 'byName', options.name ])) { + var themeConfig = options.client.currentTheme.customization.byName[options.name]; + Object.keys(themeConfig).forEach(function mciEntry(mci) { + _.defaults(options.configMci[mci], themeConfig[mci]); + }); + } + + // :TODO: apply generic stuff, e.g. "VM" (vs "VM1") +} \ No newline at end of file diff --git a/core/theme.js b/core/theme.js index d08032c1..1db4719c 100644 --- a/core/theme.js +++ b/core/theme.js @@ -42,8 +42,8 @@ function loadTheme(themeID, cb) { theme.helpers = { getPasswordChar : function() { var pwChar = Config.defaults.passwordChar; - if(_.isObject(theme.defaults) && _.isObject(theme.defaults.general)) { - var themePasswordChar = theme.defaults.general.passwordChar; + if(_.has(theme, 'customization.defaults.general')) { + var themePasswordChar = theme.customization.defaults.general.passwordChar; if(_.isString(themePasswordChar)) { pwChar = themePasswordChar.substr(0, 1); } else if(_.isNumber(themePasswordChar)) { diff --git a/core/view_controller.js b/core/view_controller.js index 29ff527c..9634fe01 100644 --- a/core/view_controller.js +++ b/core/view_controller.js @@ -507,10 +507,22 @@ ViewController.prototype.loadFromMenuConfig = function(options, cb) { callback(err); }); }, + function applyThemeCustomization(callback) { + if(_.isObject(formConfig)) { + menuUtil.applyThemeCustomization({ + name : self.client.currentMenuModule.menuName, + client : self.client, + configMci : formConfig.mci, + }); + } + + //console.log(test) + + callback(null); + }, function applyViewConfiguration(callback) { // // :TODO: need to merge configs from menu -> theme (specific) -> theme (default) -> defaults - if(_.isObject(formConfig)) { self.applyViewConfig(formConfig, function configApplied(err, info) { initialFocusId = info.initialFocusId; diff --git a/mods/art/themes/NU-MAYA/theme.json b/mods/art/themes/NU-MAYA/theme.json index df0045d6..f3f4d7b8 100644 --- a/mods/art/themes/NU-MAYA/theme.json +++ b/mods/art/themes/NU-MAYA/theme.json @@ -3,21 +3,34 @@ "name" : "Nu Mayan", "author" : "NuSkooler" }, - "defaults" : { - "general" : { - "passwordChar" : "φ" - }, - "views" : { - // :TODO: This should apply - by default - to all ToggleMenu's unless overridden elsewhere - "TM" : { - "styleSGR1" : "|00|30|01" + "customization" : { + "defaults" : { + "general" : { + "passwordChar" : "φ" + }, + "mci" : { + "TM" : { + "styleSGR1" : "|00|30|01" + } } - } - }, - "menus" : { - "matrix" : { - "VM1" : { - "itemSpacing" : 0 + }, + "byName" : { + "matrix" : { + "VM1" : { + "itemSpacing" : 1 + } + }, + "apply" : { + "ET1" : { "width" : 21 }, + "ET2" : { "width" : 21 }, + "ET3" : { "width" : 21 }, + "ET4" : { "width" : 21 }, + "ET5" : { "width" : 21 }, + "ET6" : { "width" : 21 }, + "ET7" : { "width" : 21 }, + "ET8" : { "width" : 21 }, + "ET9" : { "width" : 21 }, + "ET10" : { "width" : 21 } } } } diff --git a/mods/menu.json b/mods/menu.json index 5e1c3e62..92e8c7bd 100644 --- a/mods/menu.json +++ b/mods/menu.json @@ -56,8 +56,8 @@ "submit" : true, "focus" : true, // :TODO: need a good way to localize these ... Standard Orig->Lookup seems good. - "items" : [ "Login", "Apply", "Log Off" ], - "itemSpacing" : 1 + "items" : [ "Login", "Apply", "Log Off" ]//, + //"itemSpacing" : 1 } }, "submit" : { @@ -124,13 +124,13 @@ "ET1" : { "focus" : true, "argName" : "username", - "width" : 15, + //"width" : 15, "maxLength" : "@config:users.usernameMax" }, "ET2" : { "width" : 15, "argName" : "realName", - "width" : 15, + //"width" : 15, "maxLength" : 32 }, "ET3" : { @@ -145,34 +145,34 @@ }, "ET5" : { "argName" : "location", - "width" : 15, + //"width" : 15, "maxLength" : 32 }, "ET6" : { "argName" : "affils", - "width" : 15, + //"width" : 15, "maxLength" : 32 }, "ET7" : { "argName" : "email", - "width" : 15, + //"width" : 15, "maxLength" : 255 }, "ET8" : { "argName" : "web", - "width" : 15, + //"width" : 15, "maxLength" : 255 }, "ET9" : { "argName" : "password", "password" : true, - "width" : 15, + //"width" : 15, "maxLength" : "@config:users.passwordMax" }, "ET10" : { "argName" : "passwordConfirm", "password" : true, - "width" : 15, + //"width" : 15, "maxLength" : "@config:users.passwordMax" }, "BT12" : {