diff --git a/core/mci_view_factory.js b/core/mci_view_factory.js index e5fe2bf9..ba761165 100644 --- a/core/mci_view_factory.js +++ b/core/mci_view_factory.js @@ -5,10 +5,10 @@ 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 SpinnerMenuView = require('./spinner_menu_view.js').SpinnerMenuView; var Config = require('./config.js').config; var packageJson = require('../package.json'); - var assert = require('assert'); var os = require('os'); var _ = require('lodash'); @@ -168,6 +168,15 @@ MCIViewFactory.prototype.createFromMCI = function(mci) { view = new VerticalMenuView(options); break; + case 'SM' : + setOption(0, 'textStyle'); + setOption(1, 'justify'); + + setFocusOption(0, 'focusTextStyle'); + + view = new SpinnerMenuView(options); + break; + default : options.text = this.getPredefinedViewLabel(mci.code); if(options.text) { diff --git a/core/menu_view.js b/core/menu_view.js index 1ffdb2ab..aab10b87 100644 --- a/core/menu_view.js +++ b/core/menu_view.js @@ -60,7 +60,7 @@ function MenuView(options) { util.inherits(MenuView, View); -MenuView.prototype.redraw = function() { +MenuView.prototype.redrawAllItems = function() { MenuView.super_.prototype.redraw.call(this); this.cachePositions(); @@ -71,6 +71,19 @@ MenuView.prototype.redraw = function() { this.drawItem(i); } }; +/* + +MenuView.prototype.redraw = function() { + MenuView.super_.prototype.redraw.call(this); + + this.cachePositions(); + + var count = this.items.length; + for(var i = 0; i < count; ++i) { + this.items[i].focused = this.focusedItemIndex === i; + this.drawItem(i); + } +};*/ MenuView.prototype.setItems = function(items) { var self = this; @@ -78,8 +91,7 @@ MenuView.prototype.setItems = function(items) { this.items = []; // :TODO: better way? items.forEach(function onItem(itemText) { self.items.push({ - text : itemText, - selected : false, + text : itemText }); }); } diff --git a/core/spinner_menu_view.js b/core/spinner_menu_view.js new file mode 100644 index 00000000..90ce9a4b --- /dev/null +++ b/core/spinner_menu_view.js @@ -0,0 +1,107 @@ +/* jslint node: true */ +'use strict'; + +var MenuView = require('./menu_view.js').MenuView; +var ansi = require('./ansi_term.js'); +var strUtil = require('./string_util.js'); + +var util = require('util'); +var assert = require('assert'); +var _ = require('lodash'); + +exports.SpinnerMenuView = SpinnerMenuView; + +function SpinnerMenuView(options) { + options.justify = options.justify || 'center'; + + MenuView.call(this, options); + + var self = this; + + this.cachePositions = function() { + if(self.positionCacheExpired) { + var count = this.items.length; + // :TODO: change all xPosition, yPosition -> position.x, .y + for(var i = 0; i < count; ++i) { + self.items[i].xPosition = self.position.x; + } + self.positionCacheExpired = false; + } + }; + + this.updateSelection = function() { + assert(!self.positionCacheExpired); + + assert(this.focusedItemIndex >= 0 && this.focusedItemIndex <= self.items.length); + + self.drawItem(this.focusedItemIndex); + }; + + this.drawItem = function() { + var item = self.items[this.focusedItemIndex]; + if(!item) { + return; + } + + this.client.term.write(ansi.goto(this.position.x, this.position.y)); + this.client.term.write(self.getANSIColor(this.hasFocus ? self.getFocusColor() : self.getColor())); + + var text = strUtil.stylizeString(item.text, item.focused ? self.focusTextStyle : self.textStyle); + + self.client.term.write( + strUtil.pad(text, this.dimens.width + 1, this.fillChar, this.justify)); + }; +} + +util.inherits(SpinnerMenuView, MenuView); + +SpinnerMenuView.prototype.redraw = function() { + SpinnerMenuView.super_.prototype.redraw.call(this); + + this.cachePositions(); + this.drawItem(this.focusedItemIndex); +}; + +SpinnerMenuView.prototype.setFocus = function(focused) { + SpinnerMenuView.super_.prototype.setFocus.call(this, focused); + + this.redraw(); +}; + +SpinnerMenuView.prototype.onSpecialKeyPress = function(keyName) { + + if(this.isSpecialKeyMapped('up', keyName)) { + if(0 === this.focusedItemIndex) { + this.focusedItemIndex = this.items.length - 1; + } else { + this.focusedItemIndex--; + } + } else if(this.isSpecialKeyMapped('down', keyName)) { + if(this.items.length - 1 === this.focusedItemIndex) { + this.focusedItemIndex = 0; + } else { + this.focusedItemIndex++; + } + } + + this.updateSelection(); + + SpinnerMenuView.super_.prototype.onSpecialKeyPress.call(this, keyName); +}; + +SpinnerMenuView.prototype.getData = function() { + return this.focusedItemIndex; +}; + +SpinnerMenuView.prototype.setItems = function(items) { + SpinnerMenuView.super_.prototype.setItems.call(this, items); + + var longest = 0; + for(var i = 0; i < this.items.length; ++i) { + if(longest < this.items[i].text.length) { + longest = this.items[i].text.length; + } + } + + this.dimens.width = longest; +}; \ No newline at end of file diff --git a/core/text_view.js b/core/text_view.js index 59c9859f..10628537 100644 --- a/core/text_view.js +++ b/core/text_view.js @@ -37,11 +37,11 @@ function TextView(options) { this.drawText = function(s) { // + // |<- this.maxLength // ABCDEFGHIJK - // |ABCDEFG| ^_ length - // ^-- dimens.width + // |ABCDEFG| ^_ this.text.length + // ^-- this.dimens.width // - var textToDraw = _.isString(this.textMaskChar) ? new Array(s.length + 1).join(this.textMaskChar) : strUtil.stylizeString(s, this.hasFocus ? this.focusTextStyle : this.textStyle); @@ -58,31 +58,7 @@ function TextView(options) { var textAnsiColor = this.getANSIColor(this.hasFocus ? this.getFocusColor() : this.getColor()); var fillAnsiColor = this.getANSIColor(this.getColor()); - //console.log(textToDraw) - ///console.log(this.dimens.width + 1) - this.client.term.write(strUtil.pad(textToDraw, this.dimens.width + 1, this.fillChar, this.justify, textAnsiColor, fillAnsiColor)); - -/* - if(_.isString(this.textMaskChar)) { - this.client.term.write(strUtil.pad( - new Array(s.length + 1).join(this.textMaskChar), - this.dimens.width + 1, - this.fillChar, - this.justify, - ansiColor, - this.getANSIColor(this.getColor()))); - } else { - var text = strUtil.stylizeString(s, this.hasFocus ? this.focusTextStyle : this.textStyle); - this.client.term.write(strUtil.pad( - text, - this.dimens.width + 1, - this.fillChar, - this.justify, - ansiColor, - this.getANSIColor(this.getColor()))); - } - */ }; this.setText(options.text || ''); diff --git a/core/vertical_menu_view.js b/core/vertical_menu_view.js index 3e67fe99..d58a632b 100644 --- a/core/vertical_menu_view.js +++ b/core/vertical_menu_view.js @@ -64,7 +64,7 @@ function VerticalMenuView(options) { self.client.term.write(ansi.goto(item.xPosition, self.position.y)); this.client.term.write(self.getANSIColor( - index === self.focusedItemIndex || item.selected ? self.getFocusColor() : self.getColor())); + index === self.focusedItemIndex ? self.getFocusColor() : self.getColor())); var text = strUtil.stylizeString(item.text, item.focused ? self.focusTextStyle : self.textStyle); @@ -75,6 +75,10 @@ function VerticalMenuView(options) { util.inherits(VerticalMenuView, MenuView); +VerticalMenuView.prototype.redraw = function() { + VerticalMenuView.super_.prototype.redrawAllItems.call(this); +}; + VerticalMenuView.prototype.setPosition = function(pos) { VerticalMenuView.super_.prototype.setPosition.call(this, pos); diff --git a/mods/art/demo_edit_text_view.ans b/mods/art/demo_edit_text_view.ans index 4f8a2db6..c0b234cf 100644 Binary files a/mods/art/demo_edit_text_view.ans and b/mods/art/demo_edit_text_view.ans differ diff --git a/mods/menu.json b/mods/menu.json index 6ac170de..a917520f 100644 --- a/mods/menu.json +++ b/mods/menu.json @@ -204,11 +204,14 @@ "options" : { "cls" : true }, "form" : { "0" : { - "CB4ET1ET2ET3ET5" : { + "ET1ET2ET3ET5SM4" : { "mci" : { "ET1" : { "maxLength" : 1 }, "ET2" : { "maxLength" : 1 }, "ET3" : { "maxLength" : 1 }, + "SM4" : { + "items" : [ "YES", "NO", "Maybe So" ] + }, "ET5" : { "password" : true, "submit" : [ "esc" ],