From 9545cb620bc3849dff66cbb5568a18e301ae1a38 Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Wed, 20 Jul 2016 22:11:57 -0600 Subject: [PATCH] Add KeyEntryView (%KE) --- core/key_entry_view.js | 63 ++++++++++ core/mci_view_factory.js | 249 ++++++++++++++++++++------------------- 2 files changed, 190 insertions(+), 122 deletions(-) create mode 100644 core/key_entry_view.js diff --git a/core/key_entry_view.js b/core/key_entry_view.js new file mode 100644 index 00000000..e18b5441 --- /dev/null +++ b/core/key_entry_view.js @@ -0,0 +1,63 @@ +/* jslint node: true */ +'use strict'; + +const View = require('./view.js').View; +const valueWithDefault = require('./misc_util.js').valueWithDefault; +const isPrintable = require('./string_util.js').isPrintable; +const stylizeString = require('./string_util.js').stylizeString; + +const _ = require('lodash'); + +module.exports = class KeyEntryView extends View { + constructor(options) { + options.acceptsFocus = valueWithDefault(options.acceptsFocus, true); + options.acceptsInput = valueWithDefault(options.acceptsInput, true); + + super(options); + + this.eatTabKey = options.eatTabKey || true; + this.caseInsensitive = options.caseInsensitive || true; + + // :TODO: allow (by default) only supplied keys[] to even draw + } + + onKeyPress(ch, key) { + if(ch && isPrintable(ch)) { + this.redraw(); // sets position + this.client.term.write(stylizeString(ch, this.textStyle)); + } + + if(this.caseInsensitive) { + ch = ch.toUpperCase(); + } + + this.keyEntered = ch || key.name; + + if(key && 'tab' === key.name && !this.eatTabKey) { + return this.emit('action', 'next', key); + } + + this.emit('action', 'accept'); + // NOTE: we don't call super here. KeyEntryView is a special snowflake. + } + + setPropertyValue(propName, propValue) { + switch(propName) { + case 'eatTabKey' : + if(_.isBoolean(propValue)) { + this.eatTabKey = propValue; + } + break; + + case 'caseInsensitive' : + if(_.isBoolean(propValue)) { + this.caseInsensitive = propValue; + } + break; + } + + super.setPropertyValue(propName, propValue); + } + + getData() { return this.keyEntered; } +}; \ No newline at end of file diff --git a/core/mci_view_factory.js b/core/mci_view_factory.js index d5092074..11ce305f 100644 --- a/core/mci_view_factory.js +++ b/core/mci_view_factory.js @@ -1,23 +1,24 @@ /* jslint node: true */ 'use strict'; -var TextView = require('./text_view.js').TextView; -var EditTextView = require('./edit_text_view.js').EditTextView; -var ButtonView = require('./button_view.js').ButtonView; -var VerticalMenuView = require('./vertical_menu_view.js').VerticalMenuView; -var HorizontalMenuView = require('./horizontal_menu_view.js').HorizontalMenuView; -var SpinnerMenuView = require('./spinner_menu_view.js').SpinnerMenuView; -var ToggleMenuView = require('./toggle_menu_view.js').ToggleMenuView; -var MaskEditTextView = require('./mask_edit_text_view.js').MaskEditTextView; -var StatusBarView = require('./status_bar_view.js').StatusBarView; -var MultiLineEditTextView = require('./multi_line_edit_text_view.js').MultiLineEditTextView; -var getPredefinedMCIValue = require('./predefined_mci.js').getPredefinedMCIValue; -var ansi = require('./ansi_term.js'); +// ENiGMA½ +const TextView = require('./text_view.js').TextView; +const EditTextView = require('./edit_text_view.js').EditTextView; +const ButtonView = require('./button_view.js').ButtonView; +const VerticalMenuView = require('./vertical_menu_view.js').VerticalMenuView; +const HorizontalMenuView = require('./horizontal_menu_view.js').HorizontalMenuView; +const SpinnerMenuView = require('./spinner_menu_view.js').SpinnerMenuView; +const ToggleMenuView = require('./toggle_menu_view.js').ToggleMenuView; +const MaskEditTextView = require('./mask_edit_text_view.js').MaskEditTextView; +//const StatusBarView = require('./status_bar_view.js').StatusBarView; +const KeyEntryView = require('./key_entry_view.js'); +const MultiLineEditTextView = require('./multi_line_edit_text_view.js').MultiLineEditTextView; +const getPredefinedMCIValue = require('./predefined_mci.js').getPredefinedMCIValue; +const ansi = require('./ansi_term.js'); -var packageJson = require('../package.json'); - -var assert = require('assert'); -var _ = require('lodash'); +// deps +const assert = require('assert'); +const _ = require('lodash'); exports.MCIViewFactory = MCIViewFactory; @@ -26,7 +27,7 @@ function MCIViewFactory(client) { } MCIViewFactory.UserViewCodes = [ - 'TL', 'ET', 'ME', 'MT', 'PL', 'BT', 'VM', 'HM', 'SM', 'TM', + 'TL', 'ET', 'ME', 'MT', 'PL', 'BT', 'VM', 'HM', 'SM', 'TM', 'KE', // // XY is a special MCI code that allows finding positions @@ -77,122 +78,126 @@ MCIViewFactory.prototype.createFromMCI = function(mci, cb) { // switch(mci.code) { // Text Label (Text View) - case 'TL' : - setOption(0, 'textStyle'); - setOption(1, 'justify'); - setWidth(2); + case 'TL' : + setOption(0, 'textStyle'); + setOption(1, 'justify'); + setWidth(2); - view = new TextView(options); - break; + view = new TextView(options); + break; - // Edit Text - case 'ET' : - setWidth(0); + // Edit Text + case 'ET' : + setWidth(0); - setOption(1, 'textStyle'); - setFocusOption(0, 'focusTextStyle'); + setOption(1, 'textStyle'); + setFocusOption(0, 'focusTextStyle'); - view = new EditTextView(options); - break; + view = new EditTextView(options); + break; - // Masked Edit Text - case 'ME' : - setOption(0, 'textStyle'); - setFocusOption(0, 'focusTextStyle'); + // Masked Edit Text + case 'ME' : + setOption(0, 'textStyle'); + setFocusOption(0, 'focusTextStyle'); - view = new MaskEditTextView(options); - break; + view = new MaskEditTextView(options); + break; - // Multi Line Edit Text - case 'MT' : - // :TODO: apply params - view = new MultiLineEditTextView(options); - break; + // Multi Line Edit Text + case 'MT' : + // :TODO: apply params + view = new MultiLineEditTextView(options); + break; - // Pre-defined Label (Text View) - // :TODO: Currently no real point of PL -- @method replaces this pretty much... probably remove - case 'PL' : - if(mci.args.length > 0) { - options.text = getPredefinedMCIValue(this.client, mci.args[0]); - if(options.text) { - setOption(1, 'textStyle'); - setOption(2, 'justify'); - setWidth(3); - - view = new TextView(options); - } - } - break; - - // Button - case 'BT' : - if(mci.args.length > 0) { - options.dimens = { width : parseInt(mci.args[0], 10) }; - } - - setOption(1, 'textStyle'); - setOption(2, 'justify'); - - setFocusOption(0, 'focusTextStyle'); - - view = new ButtonView(options); - break; - - // Vertial Menu - case 'VM' : - setOption(0, 'itemSpacing'); - setOption(1, 'justify'); - setOption(2, 'textStyle'); - - setFocusOption(0, 'focusTextStyle'); - - view = new VerticalMenuView(options); - break; - - // Horizontal Menu - case 'HM' : - setOption(0, 'itemSpacing'); - setOption(1, 'textStyle'); - - setFocusOption(0, 'focusTextStyle'); - - view = new HorizontalMenuView(options); - break; - - case 'SM' : - setOption(0, 'textStyle'); - setOption(1, 'justify'); - - setFocusOption(0, 'focusTextStyle'); - - view = new SpinnerMenuView(options); - break; - - case 'TM' : - if(mci.args.length > 0) { - var styleSG1 = { fg : parseInt(mci.args[0], 10) }; - if(mci.args.length > 1) { - styleSG1.bg = parseInt(mci.args[1], 10); - } - options.styleSG1 = ansi.getSGRFromGraphicRendition(styleSG1, true); - } - - setFocusOption(0, 'focusTextStyle'); - - view = new ToggleMenuView(options); - break; - - default : - options.text = getPredefinedMCIValue(this.client, mci.code); - if(_.isString(options.text)) { - setWidth(0); - - setOption(1, 'textStyle'); - setOption(2, 'justify'); + // Pre-defined Label (Text View) + // :TODO: Currently no real point of PL -- @method replaces this pretty much... probably remove + case 'PL' : + if(mci.args.length > 0) { + options.text = getPredefinedMCIValue(this.client, mci.args[0]); + if(options.text) { + setOption(1, 'textStyle'); + setOption(2, 'justify'); + setWidth(3); view = new TextView(options); } - break; + } + break; + + // Button + case 'BT' : + if(mci.args.length > 0) { + options.dimens = { width : parseInt(mci.args[0], 10) }; + } + + setOption(1, 'textStyle'); + setOption(2, 'justify'); + + setFocusOption(0, 'focusTextStyle'); + + view = new ButtonView(options); + break; + + // Vertial Menu + case 'VM' : + setOption(0, 'itemSpacing'); + setOption(1, 'justify'); + setOption(2, 'textStyle'); + + setFocusOption(0, 'focusTextStyle'); + + view = new VerticalMenuView(options); + break; + + // Horizontal Menu + case 'HM' : + setOption(0, 'itemSpacing'); + setOption(1, 'textStyle'); + + setFocusOption(0, 'focusTextStyle'); + + view = new HorizontalMenuView(options); + break; + + case 'SM' : + setOption(0, 'textStyle'); + setOption(1, 'justify'); + + setFocusOption(0, 'focusTextStyle'); + + view = new SpinnerMenuView(options); + break; + + case 'TM' : + if(mci.args.length > 0) { + var styleSG1 = { fg : parseInt(mci.args[0], 10) }; + if(mci.args.length > 1) { + styleSG1.bg = parseInt(mci.args[1], 10); + } + options.styleSG1 = ansi.getSGRFromGraphicRendition(styleSG1, true); + } + + setFocusOption(0, 'focusTextStyle'); + + view = new ToggleMenuView(options); + break; + + case 'KE' : + view = new KeyEntryView(options); + break; + + default : + options.text = getPredefinedMCIValue(this.client, mci.code); + if(_.isString(options.text)) { + setWidth(0); + + setOption(1, 'textStyle'); + setOption(2, 'justify'); + + view = new TextView(options); + } + break; } return view;