{ /* Menu Configuration Tip: demjson's jsonlint is an excellent tool for linting JSON files that contains comments: jsonlint -S menu.json Some concept/ideas: "mci" : { "BT1" : { ... "draw" : "@script:blah.js/drawButton" // @method:scriptName[.js]/methodName (foreign .js) // @art:artName // @method:/methodName (local to module.js) // ... pass isFocused/etc. into draw method NOte that @draw & @art should check theme first. @draw:myMethod -> theme/draw.js::myMethod(opts) priority: @draw:location.js/myMethod -> outside of theme @draw:myMethod -> checks theme -> local first -OR- just inside themes for customization... e.g; { "myTheme" { "views" : { "VerticalMenuView" : { "draw" : "@method:location.js/myMethod" } } } } } } */ "menus" : { "connected" : { "art" : "CONNECT", "next" : "matrix", "options" : { "cls" : true, "nextTimeout" : 1500 } }, "matrix" : { "art" : "matrix", "form" : { "0" : { // :TODO: Make form "0" the default if missing (e.g. optional)... not sure how with current structure though "VM" : { "mci" : { "VM1" : { "submit" : true, "focus" : true, // :TODO: need a good way to localize these ... Standard Orig->Lookup seems good. "items" : [ "Login", "Apply", "Log Off" ]//, } }, "submit" : { "*" : [ { "value" : { "1" : 0 }, "action" : "@menu:login" }, { "value" : { "1" : 1 }, "action" : "@menu:apply" }, { "value" : { "1" : 2 }, "action" : "@menu:logoff" } ] } } } }, "options" : { "cls" : true } }, "login" : { // :TODO: may want { "prompt" : { "name" : "blah", "action" : ... }} "prompt" : "userCredentials", "fallback" : "matrix", "next" : "fullLoginSequenceLoginArt", "action" : "@systemMethod:login", // :TODO: support alt submit method for prompts // if present, standard filters apply. No need for multiple submit ID's // since a prompt can only utilize one: "submit" : [ { "value" : { "1" : "thing" }, "action" : "@method:doThings" } ], "options" : { "cls" : true } }, "logoff" : { "art" : "LOGOFF", "action" : "@systemMethod:logoff", "options" : { "cls" : true } }, "apply" : { "art" : "APPLY", "next" : "newUserActive", "form" : { "0" : { "BTBTETETETETETETETETETMETL" : { "mci" : { "ET1" : { "focus" : true, "argName" : "username", "maxLength" : "@config:users.usernameMax" }, "ET2" : { "argName" : "realName", "maxLength" : 32 }, "ME3" : { "argName" : "birthdate", "maskPattern" : "####/##/##" }, "ET4" : { "argName" : "sex", "maxLength" : 1 }, "ET5" : { "argName" : "location", "maxLength" : 32 }, "ET6" : { "argName" : "affils", "maxLength" : 32 }, "ET7" : { "argName" : "email", "maxLength" : 255 }, "ET8" : { "argName" : "web", "maxLength" : 255 }, "ET9" : { "argName" : "password", "password" : true, "maxLength" : "@config:users.passwordMax" }, "ET10" : { "argName" : "passwordConfirm", "password" : true, "maxLength" : "@config:users.passwordMax" }, "BT12" : { "submit" : true, "text" : "Apply" }, "BT13" : { "submit" : [ "escape" ], "text" : "Cancel" } }, "submit" : { "12" : [ // Apply { "value" : 12, // :TODO: better, this should be optional; if not present it's a any match "action" : "@method:apply/submitApplication", "extraArgs" : { "inactive" : "userNeedsActivated", "error" : "newUserCreateError" } } ], "13" : [ // Cancel { "value" : 13, "action" : "@menu:matrix" } ] } } } }, "options" : { "cls" : true } }, "fullLoginSequenceLoginArt" : { "art" : "LOGIN", "options" : { "cls" : true, "pause" : true }, "action" : "@menu:fullLoginSequenceLastCallers" }, "fullLoginSequenceLastCallers": { "module" : "last_callers", "art" : "LASTCALL", "options" : { "cls" : true, "pause" : true }, "config" : { "dateTimeFormat" : "ddd MMM Do h:mm a" }, "action" : "@menu:fullLoginSequenceUserStats" }, "fullLoginSequenceUserStats" : { "art" : "userstats", "options" : { "cls" : true, "pause" : true }, "action" : "@menu:mainMenu" }, "newUserActive" : { "art" : "SO-CC1.ANS", "options" : { "cls" : true, "pause" : true }, "action" : "@menu:currentUserStats" }, "currentUserStats" : { "art" : "userstats", "options" : { "cls" : true, "pause" : true } //"action" : "@menu:lastCallers" }, "mainMenu" : { "art" : "MAINMENU", "options" : { "cls" : true }, "prompt" : "menuCommand", "submit" : [ { "value" : { "command" : "G" }, "action" : "@menu:logoff" }, { "value" : { "command" : "D" }, "action" : "@menu:doorPimpWars" }, { "value" : { "command" : "L" }, "action" : "@menu:doorLORD" }, { "value" : { "command" : "M" }, "action" : "@menu:messageArea" }, { "value" : 1, "action" : "@menu:mainMenu" } ] }, /////////////////////////////////////////////////////////////////////// // Message Area Related /////////////////////////////////////////////////////////////////////// "messageArea" : { "module" : "msg_area", "art" : "MSGAREA", "options" : { "cls" : true }, "prompt" : "menuCommand", "submit" : [ { "value" : { "command" : "N" }, "action" : "@menu:messageAreaNewPost" } ] }, "messageAreaNewPost" : { "module" : "msg_area_post", "options" : { "cls" : true }, "config" : { "fseArt" : { "header" : "msg_area_post_header", "body" : "demo_fse_netmail_body.ans", "footerEdit" : "demo_fse_netmail_footer_edit.ans", "footerEditMenu" : "demo_fse_netmail_footer_edit_menu.ans", "footerView" : "demo_fse_netmail_footer_view.ans", "help" : "demo_fse_netmail_help.ans" } }, "form" : { "0" : { "ETETTLTL" : { "mci" : { "TL1" : { "width" : 36, "argName" : "from" }, "ET2" : { "width" : 36, "argName" : "to", "focus" : true }, "ET3" : { "width" : 65, "argName" : "subject", "maxLength" : 72, "submit" : true }, "TL4" : { "width" : 19, "textOverflow" : "..." } }, "submit" : { "3" : [ { "value" : { "subject" : null }, "action" : "@method:fseSubmitProxy" } ] } } }, "1" : { "MT" : { "mci" : { "MT1" : { "width" : 79, "height" : 17, "argName" : "message" } }, "submit" : { "*" : [ { "value" : "message", "action" : "@method:fseSubmitProxy" } ] }, "actionKeys" : [ { "keys" : [ "escape" ], "viewId" : 1 } ] } }, "2" : { "TLTL" : { "mci" : { "TL1" : { "width" : 5 }, "TL2" : { "width" : 4 } } } }, "3" : { "HM" : { "mci" : { "HM1" : { // :TODO: Continue, Save, Discard, Clear, Quote, Help "items" : [ "Save", "Discard", "Quote", "Help" ] } }, "submit" : { "*" : [ { "value" : { "1" : 0 }, "action" : "@method:fseSubmitProxy" }, { "value" : { "1" : 1 }, "action" : "@menu:messageArea" }, { "value" : { "1" : 2 }, "action" : "@method:fseSubmitProxy" }, { "value" : { "1" : 3 }, "action" : "@method:fseSubmitProxy" }, { "value" : 1, "action" : "@method:fseSubmitProxy" } ] }, "actionKeys" : [ // :TODO: Need better name { "keys" : [ "escape" ], "action" : "@method:fseSubmitProxy" } ] // :TODO: something like the following for overriding keymap // this should only override specified entries. others will default /* "keyMap" : { "accept" : [ "return" ] } */ } } } }, /* "messageAreaMenu" : { "module" : "message_area", "art" : "MSGAREA", "options" : { "cls" : true }, "prompt" : "menuCommand", "config" : { "fseArt" : { "header" : "demo_fse_netmail_header.ans", "body" : "demo_fse_netmail_body.ans", "footerEdit" : "demo_fse_netmail_footer_edit.ans", "footerEditMenu" : "demo_fse_netmail_footer_edit_menu.ans", "footerView" : "demo_fse_netmail_footer_view.ans", "help" : "demo_fse_netmail_help.ans" } }, "submit" : [ { "value" : { "command" : "R" }, "action" : "@method:readMessages" }, { "value" : { "command" : "P" }, "action" : "@method:postMessage" } ] } */ /////////////////////////////////////////////////////////////////////// // Doors /////////////////////////////////////////////////////////////////////// "doorPimpWars" : { "module" : "abracadabra", "fallback" : "mainMenu", "config" : { "name" : "PimpWars", "dropFileType" : "DORINFO", "cmd" : "/usr/bin/dosemu", "args" : [ "-quiet", "-f", "/home/nuskooler/DOS/X/LORD/dosemu.conf", "X:\\PW\\START.BAT {dropfile} {node}" ], "nodeMax" : 1, "tooManyArt" : "doortoomany.ans" } }, "doorLORD" : { "module" : "abracadabra", "fallback" : "mainMenu", "config" : { "name" : "LORD", "dropFileType" : "DOOR", "cmd" : "/usr/bin/dosemu", "args" : [ "-quiet", "-f", "/home/nuskooler/DOS/X/LORD/dosemu.conf", "X:\\LORD\\START.BAT {node}" ] } }, //////////////////////////////////////////////////////////////////////// // Mods //////////////////////////////////////////////////////////////////////// "idleLogoff" : { "art" : "IDLELOG", "options" : { "cls" : true }, "action" : "@systemMethod:logoff" }, //////////////////////////////////////////////////////////////////////// // Mods //////////////////////////////////////////////////////////////////////// "lastCallers" :{ "module" : "last_callers", "art" : "LASTCALL.ANS", "options" : { "cls" : true, "pause" : true }, "config" : { "dateTimeFormat" : "ddd MMM Do H:mm a" }, "form" : { "0" : { "TLTLTLTL" : { "mci" : { // :TODO: Bug: Without any keys here, theme customization does not apply!!!! "TL1" : { "styleSGR1" : "|00|24" }, "TL2" : { "styleSGR1" : "|00|24" }, "TL3" : { "styleSGR1" : "|00|24" }, "TL4" : { "styleSGR1" : "|00|24" } } } } } }, //////////////////////////////////////////////////////////////////////// // Demo Section //////////////////////////////////////////////////////////////////////// "demoMain" : { "art" : "demo_selection_vm.ans", "options" : { "cls" : true }, "form" : { "0" : { "VM" : { "mci" : { "VM1" : { "items" : [ "Single Line Text Editing Views", "Spinner & Toggle Views", "Mask Edit Views", "Multi Line Text Editor", "Vertical Menu Views", "Horizontal Menu Views", "Art Display", "Full Screen Editor", "Some More Stuff", "Other" ], "height" : 10, "itemSpacing" : 1, "justify" : "center", "focusTextStyle" : "small i" } }, "submit" : { "*" : [ { "value" : { "1" : 0 }, "action" : "@menu:demoEditTextView" }, { "value" : { "1" : 1 }, "action" : "@menu:demoSpinAndToggleView" }, { "value" : { "1" : 2 }, "action" : "@menu:demoMaskEditView" }, { "value" : { "1" : 3 }, "action" : "@menu:demoMultiLineEditTextView" }, { "value" : { "1" : 5 }, "action" : "@menu:demoHorizontalMenuView" }, { "value" : { "1" : 6 }, "action" : "@menu:demoArtDisplay" }, { "value" : { "1" : 7 }, "action" : "@menu:demoFullScreenEditor" } ] } } } } }, "demoEditTextView" : { "art" : "demo_edit_text_view1.ans", "options" : { "cls" : true }, "form" : { "0" : { "BTETETETET" : { "mci" : { "ET1" : { "width" : 20, "maxLength" : 20 }, "ET2" : { "width" : 20, "maxLength" : 40, "textOverflow" : "..." }, "ET3" : { "width" : 20, "fillChar" : "-", "styleSGR1" : "|00|36", "maxLength" : 20 }, "ET4" : { "width" : 20, "maxLength" : 20, "password" : true }, "BT5" : { "width" : 8, "text" : "< Back" } }, "submit" : { "*" : [ { "value" : 5, "action" : "@menu:demoMain" } ] }, "actionKeys" : [ { "keys" : [ "escape" ], "viewId" : 5 } ] } } } }, "demoSpinAndToggleView" : { "art" : "demo_spin_and_toggle.ans", "options" : { "cls" : true }, "form" : { "0" : { "BTSMSMTM" : { "mci" : { "SM1" : { "items" : [ "Henry Morgan", "François l'Ollonais", "Roche Braziliano", "Black Bart", "Blackbeard" ] }, "SM2" : { "items" : [ "Razor 1911", "DrinkOrDie", "TRSI" ] }, "TM3" : { "items" : [ "Yarly", "Nowaii" ], "styleSGR1" : "|00|30|01", "hotKeys" : { "Y" : 0, "N" : 1 } }, "BT8" : { "text" : "< Back" } }, "submit" : { "*" : [ { "value" : 8, "action" : "@menu:demoMain" } ] }, "actionKeys" : [ { "keys" : [ "escape" ], "viewId" : 8 } ] } } } }, "demoMaskEditView" : { "art" : "demo_mask_edit_text_view1.ans", "options" : { "cls" : true }, "form" : { "0" : { "BTMEME" : { "mci" : { "ME1" : { "maskPattern" : "##/##/##", "styleSGR1" : "|00|30|01", //"styleSGR2" : "|00|45|01", "styleSGR3" : "|00|30|35", "fillChar" : "#" }, "BT5" : { "text" : "< Back" } }, "submit" : { "*" : [ { "value" : 5, "action" : "@menu:demoMain" } ] }, "actionKeys" : [ { "keys" : [ "escape" ], "viewId" : 5 } ] } } } }, "demoMultiLineEditTextView" : { "art" : "demo_multi_line_edit_text_view1.ans", "options" : { "cls" : true }, "form" : { "0" : { "BTMT" : { "mci" : { "MT1" : { "width" : 70, "height" : 17, //"text" : "@art:demo_multi_line_edit_text_view_text.txt", // "text" : "@systemMethod:textFromFile" "text" : "Hints:\n\t* Insert / CTRL-V toggles overtype mode\n\t* CTRL-Y deletes the current line\n\t* Try Page Up / Page Down\n\t* Home goes to the start of line text\n\t* End goes to the end of a line\n\n\nTab handling:\n-------------------------------------------------\n\tA\tB\tC\tD\tE\tF\nA\tB\tC\tD\tE\tF\tG\tH\n\tA\tB\tC\tD\tE\tF\nA\tB\tC\tD\tE\tF\tG\tH\nA0\tBB\t1\tCCC\t2\tDDD\t3EEEE\nW\t\tX\t\tY\t\tZ\n\nAn excerpt from A Clockwork Orange:\n\"What sloochatted then, of course, was that my cellmates woke up and started joining in, tolchocking a bit wild in the near-dark, and the shoom seemed to wake up the whole tier, so that you could slooshy a lot of creeching and banging about with tin mugs on the wall, as though all the plennies in all the cells thought a big break was about to commence, O my brothers.\n", "focus" : true }, "BT5" : { "text" : "< Back" } }, "submit" : { "*" : [ { "value" : 5, "action" : "@menu:demoMain" } ] }, "actionKeys" : [ { "keys" : [ "escape" ], "viewId" : 5 } ] } } } }, "demoHorizontalMenuView" : { "art" : "demo_horizontal_menu_view1.ans", "options" : { "cls" : true }, "form" : { "0" : { "BTHMHM" : { "mci" : { "HM1" : { "items" : [ "One", "Two", "Three" ], "hotKeys" : { "1" : 0, "2" : 1, "3" : 2 } }, "HM2" : { "items" : [ "Uno", "Dos", "Tres" ], "hotKeys" : { "U" : 0, "D" : 1, "T" : 2 } }, "BT5" : { "text" : "< Back" } }, "submit" : { "*" : [ { "value" : 5, "action" : "@menu:demoMain" } ] }, "actionKeys" : [ { "keys" : [ "escape" ], "viewId" : 5 } ] } } } }, "demoArtDisplay" : { "art" : "demo_selection_vm.ans", "options" : { "cls" : true }, "form" : { "0" : { "VM" : { "mci" : { "VM1" : { "items" : [ "Defaults - DOS ANSI", "bw_mindgames.ans - DOS", "test.ans - DOS", "Defaults - Amiga", "Pause at Term Height" ], // :TODO: justify not working?? "focusTextStyle" : "small i" } }, "submit" : { "*" : [ { "value" : { "1" : 0 }, "action" : "@menu:demoDefaultsDosAnsi" }, { "value" : { "1" : 1 }, "action" : "@menu:demoDefaultsDosAnsi_bw_mindgames" }, { "value" : { "1" : 2 }, "action" : "@menu:demoDefaultsDosAnsi_test" } ] } } } } }, "demoDefaultsDosAnsi" : { "art" : "DM-ENIG2.ANS", "options" : { "cls" : true } }, "demoDefaultsDosAnsi_bw_mindgames" : { "art" : "bw_mindgames.ans", "options" : { "cls" : true } }, "demoDefaultsDosAnsi_test" : { "art" : "test.ans", "options" : { "cls" : true } }, "demoFullScreenEditor" : { "module" : "@systemModule:fse", "options" : { "cls" : true }, "config" : { "editorType" : "netMail", "art" : { "header" : "demo_fse_netmail_header.ans", "body" : "demo_fse_netmail_body.ans", "footerEdit" : "demo_fse_netmail_footer_edit.ans", "footerEditMenu" : "demo_fse_netmail_footer_edit_menu.ans", "footerView" : "demo_fse_netmail_footer_view.ans", "help" : "demo_fse_netmail_help.ans" } }, "form" : { "0" : { "ETETET" : { "mci" : { "ET1" : { // :TODO: from/to may be set by args // :TODO: focus may change dep on view vs edit "width" : 36, "focus" : true, "argName" : "to" }, "ET2" : { "width" : 36, "argName" : "from" }, "ET3" : { "width" : 65, "maxLength" : 72, "submit" : [ "enter" ], "argName" : "subject" } }, "submit" : { "3" : [ { "value" : { "subject" : null }, "action" : "@method:headerSubmit" } ] } } }, "1" : { "MT" : { "mci" : { "MT1" : { "width" : 79, "height" : 17, "text" : "", // :TODO: should not be req. "argName" : "message" } }, "submit" : { "*" : [ { "value" : "message", "action" : "@method:editModeEscPressed" } ] }, "actionKeys" : [ { "keys" : [ "escape" ], "viewId" : 1 } ] } }, "2" : { "TLTL" : { "mci" : { "TL1" : { "width" : 5 }, "TL2" : { "width" : 4 } } } }, "3" : { "HM" : { "mci" : { "HM1" : { // :TODO: Continue, Save, Discard, Clear, Quote, Help "items" : [ "Save", "Discard", "Quote", "Help" ] } }, "submit" : { "*" : [ { "value" : { "1" : 0 }, "action" : "@method:editModeMenuSave" }, { "value" : { "1" : 1 }, "action" : "@menu:demoMain" }, { "value" : { "1" : 2 }, "action" : "@method:editModeMenuQuote" }, { "value" : { "1" : 3 }, "action" : "@method:editModeMenuHelp" }, { "value" : 1, "action" : "@method:editModeEscPressed" } ] }, "actionKeys" : [ // :TODO: Need better name { "keys" : [ "escape" ], "action" : "@method:editModeEscPressed" } ] // :TODO: something like the following for overriding keymap // this should only override specified entries. others will default /* "keyMap" : { "accept" : [ "return" ] } */ } } } /* "form" : { "0" : { "ET1ET2MT3" : { "mci" : { "ET1" : { "width" : 20, "placeholder" : "TODO support this", "focus" : true }, "ET2" : { "width" : 20 }, "MT3" : { "width" : 79, "height" : 17, "text" : "", "submit" : [ "escape" ] } }, "submit" : { // :TODO: It may be nice to have a way to submit without data - e.g. we just care about the key press. "3" : [ { "value" : 3, "action" : "@method:editorEscPressed" } ] } } } } */ } /* :TODO: conceptual simplified menus -- actions/etc. without forms { "myMenu" : { "art" : "MENUART", "mci" : { // lack of "form": direct to form:0 {} "VM1" : { "items" : [ "Hello", "Goodbye" ], "action" : "@method:someMethod" // implies { "submit" : true } }, "submit" : { // alternate form with filters } } } } */ /* "demoEditTextView" : { "art" : "demo_edit_text_view.ans", "options" : { "cls" : true }, "form" : { "0" : { "ET1ET2ET3ET5SM4TM6" : { "mci" : { "ET1" : { "maxLength" : 1 }, "ET2" : { "maxLength" : 1 }, "ET3" : { "maxLength" : 1 }, "SM4" : { "items" : [ "One", "Two", "Three", "Four" ] }, "ET5" : { "password" : true, "submit" : [ "escape" ], "fillChar" : "#" }, "TM6" : { "items" : [ "Yes", "No" ], "hotkeys" : { "Y" : 0, "n" : 1 } } } } } } } */ } }