{ /* ENiGMA½ Menu Configuration This configuration is in HJSON format. Strict to-spec JSON is also perfectly valid. The hjson npm can be used to convert to/from JSON. See http://hjson.org/ for more information and syntax. */ /* :TODO: Fully convert to HJSON 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: { nextTimeout: 1500 } } matrix: { art: matrix options: { } 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:login2 }, { value: { 1: 1 }, action: @menu:newUserApplication //action: @menu:apply }, { value: { 1: 2 }, action: @menu:logoff } ] } } } } } "login" : { "prompt" : "userLoginCredentials", "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" : { "password" : null }, "action" : "@systemMethod:login" } ]*/ }, login2: { art: USERLOG //next: messageArea next: fullLoginSequenceLoginArt config: { tooNodeArt: TOONODE } form: { 0: { mci: { ET1: { maxLength: @config:users.usernameMax argName: username focus: true } ET2: { password: true maxLength: @config:users.passwordMax argName: password submit: true } } submit: { *: [ { value: { password: null } action: @systemMethod:login } ] } actionKeys: [ { keys: [ "escape" ] action: @menu:matrix } ] } } } "logoff" : { "art" : "LOGOFF", "next" : "@systemMethod:logoff", }, /* nua -> send sysop mail -> { active } -> matrix -> you must active -> matrix TODO: display PRINT before this (Obv/2) */ newUserApplication: { art: NUA next: newUserFeedbackToSysOpPreamble form: { 0: { mci: { ET1: { focus: true argName: username maxLength: @config:users.usernameMax } ET2: { argName: realName maxLength: 32 } MET3: { argName: birthdate maskPattern: "####/##/##" } ME4: { argName: sex maskPattern: A textStyle: upper } 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 } TM12: { argName: submission items: [ "apply", "cancel" ] submit: true } } submit: { *: [ { value: { "submission" : 0 } action: @method:apply/submitApplication extraArgs: { inactive: userNeedsActivated error: newUserCreateError } } { value: { "submission" : 1 } action: @menu:matrix } ] } actionKeys: [ { keys: [ "escape" ] action: @menu:matrix } ] } } } newUserFeedbackToSysOpPreamble: { art: LETTER options: { pause: true } next: newUserFeedbackToSysOp extraArgs: { messageAreaName: private_mail } } newUserFeedbackToSysOp: { status: Feedback to SysOp module: msg_area_post_fse // :TODO: If the user is auto-approved, login seq. else, DONE.ANS -> Logoff // :TODO: client.nextOrFallback(): go next or fallback. Use in MenuModule base also fallback: fullLoginSequenceLoginArt config: { art: { header: MSGEHDR body: MSGBODY footerEditor: MSGEFTR footerEditorMenu: MSGEMFT help: MSGEHLP }, editorMode: edit editorType: area } form: { 0: { mci: { TL1: { argName: from } ET2: { argName: to focus: true text: @config:general.sysOp.username // :TODO: readOnly: true } ET3: { argName: subject maxLength: 72 submit: true text: New user feedback } } submit: { 3: [ { value: { subject: null } action: @method:headerSubmit } ] } } 1: { mci: { MT1: { width: 79 argName: message mode: edit } } 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: clear items: [ "save", "help" ] } } submit: { *: [ { value: { 1: 0 } action: @method:editModeMenuSave } { value: { 1: 1 } action: @method:editModeMenuHelp } ] } actionKeys: [ { keys: [ "escape" ] action: @method:editModeEscPressed } { keys: [ "?" ] action: @method:editModeMenuHelp } ] } } } } fullLoginSequenceLoginArt: { desc: Logging In art: LOGIN options: { pause: true } next: fullLoginSequenceLastCallers } fullLoginSequenceLastCallers: { desc: Last Callers module: last_callers art: LASTCALL options: { pause: true } next: fullLoginSequenceSysStats } fullLoginSequenceSysStats: { desc: System Stats art: SYSSTAT options: { pause: true } next: fullLoginSequenceUserStats } fullLoginSequenceUserStats: { desc: User Stats art: STATUS options: { pause: true } next: mainMenu }, "newUserActive" : { "art" : "SO-CC1.ANS", "options" : { "pause" : true }, "next" : "currentUserStats" }, "currentUserStats" : { "art" : "userstats", "options" : { "pause" : true } //"action" : "@menu:lastCallers" }, mainMenu: { art: MMENU desc: Main Menu prompt: menuCommand submit: [ { "value" : { "command" : "G" }, "action" : "@menu:logoff" }, { "value" : { "command" : "O" }, "action" : "@menu:doorPimpWars" } { value: { command: "D" } action: @menu:doorMenu } /* { "value" : { "command" : "L" }, "action" : "@menu:doorLORD" }, */ { value: { command: "E" } action: @menu:doorTestExample } { "value" : { "command" : "L" }, "action" : "@menu:mainMenuLastCallers" }, { "value" : { "command" : "Y" }, "action" : "@menu:mainMenuUserStats" }, { "value" : { "command" : "M" }, "action" : "@menu:messageArea" }, { value: { command: "C" } action: @menu:mainMenuUserConfig } { value: { command: "S" } action: @menu:mainMenuSystemStats } { "value" : 1, "action" : "@menu:mainMenu" } ] } mainMenuLastCallers: { module: last_callers art: LASTCALL options: { pause: true } } mainMenuUserStats: { art: STATUS options: { pause: true } } mainMenuSystemStats: { art: SYSSTAT options: { pause: true } } mainMenuUserConfig: { module: @systemModule:user_config art: CONFSCR form: { 0: { mci: { ET1: { argName: email } ET2: { argName: location } ET3: { argName: webAddress } ET4: { argName: affils } ME5: { maskPattern: "####/##/##" argName: birthdate } ME11: { maskPattern: "##x##" argName: termSize } } actionKeys: [ { keys: [ "escape" ] action: @method:exitKeyPressed } ] } } } doorMenu: { desc: Doors Menu art: DOORMNU prompt: menuCommand submit: [ { value: { command: "G" } action: @menu:logoff } { value: { command: "Q" } action: @systemMethod:fallbackMenu } { value: { command: "1" } action: @menu:doorPimpWars } { value: { command: "2" } action: @menu:doorLORD } ] } /////////////////////////////////////////////////////////////////////// // Message Area Related /////////////////////////////////////////////////////////////////////// messageArea: { module: msg_area art: MSGMNU desc: Message Area prompt: menuCommand submit: [ { value: { command: "P" } action: @menu:messageAreaNewPost } { value: { command: "C" } action: @menu:messageAreaChangeCurrentArea } { value: { command: "L" } action: @menu:messageAreaMessageList } { value: { command: "Q" } action: @menu:mainMenu } { value: { command: "G" } action: @menu:logoff } { value: 1 action: @menu:messageArea } ] } messageAreaChangeCurrentArea: { art: CHANGE module: msg_area_list "form" : { "0" : { "mci" : { "VM1" : { "focus" : true, "submit" : true, "argName" : "area" } }, "submit" : { "*" : [ { "value" : { "area" : null }, "action" : "@method:changeArea" } ] }, "actionKeys" : [ { keys: [ "escape", "q", "shift + q" ] action: @systemMethod:fallbackMenu } ] } } }, messageAreaMessageList: { module: msg_list art: MSGLIST config: { listType: public } form: { 0: { mci: { VM1: { focus: true submit: true argName: message } } submit: { *: [ { value: { message: null } action: @method:selectMessage } ] } actionKeys: [ { keys: [ "escape", "q", "shift + q" ] action: @systemMethod:fallbackMenu } ] } } } messageAreaViewPost: { module: msg_area_view_fse config: { art: { header: MSGVHDR body: MSGBODY footerView: MSGVFTR help: MSGVHLP }, editorMode: view editorType: area } form: { 0: { mci: { // :TODO: ensure this block isn't even req. for theme to apply... } } 1: { mci: { MT1: { width: 79 //"height" : 14, mode: preview } } submit: { *: [ { "value" : "message", "action" : "@method:editModeEscPressed" } ] } actionKeys: [ { keys: [ "escape" ] viewId: 1 } ] } 2: { TLTL: { mci: { TL1: { width: 5 } TL2: { width: 4 } } } } 4: { mci: { HM1: { // :TODO: (#)Jump/(L)Index (msg list)/Last // (p)rev, (n)ext, (r)eply, (q)uit/ESC, (?)help items: [ "prev", "next", "reply", "quit", "help" ] } } submit: { *: [ { value: { 1: 0 } action: @method:prevMessage } { value: { 1: 1 } action: @method:nextMessage } { value: { 1: 2 } action: @method:replyMessage extraArgs: { menu: messageAreaReplyPost } } { value: { 1: 3 } action: @menu:messageArea } { value: { 1: 4 } action: @method:viewModeMenuHelp } ] } actionKeys: [ { keys: [ "p", "shift + p" ] action: @method:prevMessage } { keys: [ "n", "shift + n" ] action: @method:nextMessage } { keys: [ "r", "shift + r" ] action: @method:replyMessage extraArgs: { menu: messageAreaReplyPost } } { keys: [ "escape", "q", "shift + q" ] action: @systemMethod:fallbackMenu //action: @menu:messageArea } { keys: [ "?" ] action: @method:viewModeMenuHelp } { keys: [ "down arrow", "up arrow", "page up", "page down" ] action: @method:movementKeyPressed } ] } } }, messageAreaReplyPost: { module: msg_area_post_fse config: { art: { header: MSGEHDR body: MSGBODY quote: MSGQUOT footerEditor: MSGEFTR footerEditorMenu: MSGEMFT help: MSGEHLP } editorMode: edit editorType: area } form: { 0: { mci: { // :TODO: use appropriate system properties for these lenghts TL1: { //width: 27 argName: from } ET2: { //width: 27 argName: to focus: true } ET3: { argName: subject maxLength: 72 submit: true } TL4: { // :TODO: this is for RE: line (NYI) //width: 27 //textOverflow: ... } MA5: { //width: 27 //textOverflow: ... } } submit: { 3: [ { "value" : { "subject" : null }, "action" : "@method:headerSubmit" } ] } } 1: { mci: { MT1: { width: 79 height: 14 argName: message mode: edit } } submit: { *: [ { "value": "message", "action": "@method:editModeEscPressed" } ] } actionKeys: [ { keys: [ "escape" ], viewId: 1 } ] } 3: { HM: { mci: { HM1: { items: [ "save", "discard", "quote", "help" ] } } submit: { *: [ { value: { 1: 0 } action: @method:editModeMenuSave } { value: { 1: 1 } action: @systemMethod:fallbackMenu } { value: { 1: 2 }, action: @method:editModeMenuQuote } { value: { 1: 3 } action: @method:editModeMenuHelp } ] } actionKeys: [ { keys: [ "escape" ] action: @method:editModeEscPressed } { keys: [ "s", "shift + s" ] action: @method:editModeMenuSave } { keys: [ "d", "shift + d" ] action: @systemMethod:fallbackMenu } { keys: [ "q", "shift + q" ] action: @method:editModeMenuQuote } { keys: [ "?" ] action: @method:editModeMenuHelp } ] } } // Quote builder 5: { mci: { MT1: { width: 79 height: 7 } VM3: { width: 79 height: 4 argName: quote } } submit: { *: [ { value: { quote: null } action: @method:appendQuoteEntry } ] } actionKeys: [ { keys: [ "escape" ] action: @method:quoteBuilderEscPressed } ] } } } // :TODO: messageAreaSelect (change msg areas -> call @systemMethod -> fallback to menu messageAreaNewPost: { status: Posting message, module: msg_area_post_fse //"fallback" : "messageArea", // :TODO: remove once default fallback is in place config: { art: { header: MSGEHDR body: MSGBODY footerEditor: MSGEFTR footerEditorMenu: MSGEMFT help: MSGEHLP } editorMode: edit editorType: area } form: { 0: { mci: { TL1: { argName: from } ET2: { argName: to focus: true text: All } ET3: { argName: subject maxLength: 72 submit: true } } "submit" : { "3" : [ { "value" : { "subject" : null }, "action" : "@method:headerSubmit" } ] } } 1: { "mci" : { MT1: { width: 79 argName: message mode: edit } } 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: clear "items" : [ "save", "discard", "help" ] } }, "submit" : { "*" : [ { "value" : { "1" : 0 }, "action" : "@method:editModeMenuSave" }, { "value" : { "1" : 1 }, "action" : "@menu:messageArea" } { "value" : { "1" : 2 }, "action" : "@method:editModeMenuHelp" } ] }, actionKeys: [ // :TODO: Need better name { keys: [ "escape" ] action: @method:editModeEscPressed } { keys: [ "?" ] action: @method:editModeMenuHelp } ] // :TODO: something like the following for overriding keymap // this should only override specified entries. others will default /* "keyMap" : { "accept" : [ "return" ] } */ } } } }, /////////////////////////////////////////////////////////////////////// // Doors /////////////////////////////////////////////////////////////////////// doorPimpWars: { desc: Playing PimpWars module: abracadabra 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 // :TODO: Obv/2 name for this? 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}" ] } }, doorTestExample: { module: abracadabra config: { name: example dropFileType: DOOR cmd: "/usr/bin/dosemu" args: [ "-quiet", "-f", "/home/nuskooler/DOS/X/LORD/dosemu.conf", "X:\\SLOWMO.EXE 1 120 X:\\LORD\\LAIRANS.ANS"] } } //////////////////////////////////////////////////////////////////////// // Mods //////////////////////////////////////////////////////////////////////// idleLogoff: { art: IDLELOG next: @systemMethod:logoff }, //////////////////////////////////////////////////////////////////////// // Mods //////////////////////////////////////////////////////////////////////// "lastCallers" :{ "module" : "last_callers", "art" : "LASTCALL.ANS", "options" : { "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", "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" ], "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" : 4 }, "action" : "@menu:demoVerticalMenuView" }, { "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", "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", "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", "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", "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", "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 } ] } } } }, "demoVerticalMenuView" : { "art" : "demo_vertical_menu_view1.ans", "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", "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" }, "demoDefaultsDosAnsi_bw_mindgames" : { "art" : "bw_mindgames.ans" }, "demoDefaultsDosAnsi_test" : { "art" : "test.ans" }, "demoFullScreenEditor" : { "module" : "@systemModule:fse", "config" : { "editorType" : "netMail", "art" : { "header" : "demo_fse_netmail_header.ans", "body" : "demo_fse_netmail_body.ans", "footerEditor" : "demo_fse_netmail_footer_edit.ans", "footerEditorMenu" : "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", "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 } } } } } } } */ } }