From 658c64c8c86eb8ec63834abb976f152e938f4b78 Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Mon, 29 Jun 2015 23:14:17 -0600 Subject: [PATCH] * Bunch of WIP on new setPropertyValue() stuff making it easier to set props from JSON --- core/mask_edit_text_view.js | 8 ++ core/menu_view.js | 11 +++ core/multi_line_edit_text_view2.js | 8 ++ core/text_view.js | 15 ++++ core/user.js | 2 +- core/vertical_menu_view.js | 35 ++++++-- core/view.js | 45 +++++++++-- core/view_controller.js | 123 +++++++++++++++++++++-------- 8 files changed, 202 insertions(+), 45 deletions(-) diff --git a/core/mask_edit_text_view.js b/core/mask_edit_text_view.js index 858c5ab3..b5cbb670 100644 --- a/core/mask_edit_text_view.js +++ b/core/mask_edit_text_view.js @@ -161,3 +161,11 @@ MaskEditTextView.prototype.onKeyPress = function(ch, key) { MaskEditTextView.super_.prototype.onKeyPress.call(this, ch, key); }; + +MaskEditTextView.prototype.setPropertyValue = function(propName, value) { + switch(propName) { + case 'maskPattern' : this.setMaskPattern(value); break; + } + + MaskEditTextView.super_.prototype.setPropertyValue.call(this, propName, value); +}; \ No newline at end of file diff --git a/core/menu_view.js b/core/menu_view.js index 634f2559..9d2b5d26 100644 --- a/core/menu_view.js +++ b/core/menu_view.js @@ -105,12 +105,23 @@ MenuView.prototype.setItems = function(items) { }; MenuView.prototype.setItemSpacing = function(itemSpacing) { + itemSpacing = parseInt(itemSpacing); assert(_.isNumber(itemSpacing)); this.itemSpacing = itemSpacing; this.positionCacheExpired = true; }; +MenuView.prototype.setPropertyValue = function(propName, value) { + switch(propName) { + case 'itemSpacing' : this.setItemSpacing(value); break; + case 'items' : this.setItems(value); break; + case 'hotKeys' : this.setHotKeys(value); break; + } + + MenuView.super_.prototype.setPropertyValue.call(this, propName, value); +}; + MenuView.prototype.setHotKeys = function(hotKeys) { if(_.isObject(hotKeys)) { if(this.caseInsensitiveHotKeys) { diff --git a/core/multi_line_edit_text_view2.js b/core/multi_line_edit_text_view2.js index 06f7914f..0f3bec5e 100644 --- a/core/multi_line_edit_text_view2.js +++ b/core/multi_line_edit_text_view2.js @@ -1010,6 +1010,14 @@ MultiLineEditTextView2.prototype.getData = function() { return this.getOutputText(0, this.textLines.length, true); }; +MultiLineEditTextView2.prototype.setPropertyValue = function(propName, value) { +/* switch(propName) { + case 'text' : this.setText(value); break; + } +*/ + MultiLineEditTextView2.super_.prototype.setPropertyValue.call(this, propName, value); +}; + var HANDLED_SPECIAL_KEYS = [ 'up', 'down', 'left', 'right', 'home', 'end', diff --git a/core/text_view.js b/core/text_view.js index 621d5848..aedea9d4 100644 --- a/core/text_view.js +++ b/core/text_view.js @@ -138,3 +138,18 @@ TextView.prototype.setText = function(text) { TextView.prototype.clearText = function() { this.setText(''); }; + +TextView.prototype.setPropertyValue = function(propName, value) { + switch(propName) { + case 'textMaskChar' : this.textMaskChar = value.substr(0, 1); break; + case 'textOverflow' : this.textOverflow = value; break; + case 'maxLength' : this.maxLength = parseInt(value, 10); break; + case 'password' : + if(true === value) { + this.textMaskChar = this.client.currentTheme.helpers.getPasswordChar(); + } + break; + } + + TextView.super_.prototype.setPropertyValue.call(this, propName, value); +}; \ No newline at end of file diff --git a/core/user.js b/core/user.js index 2826a88b..219c7114 100644 --- a/core/user.js +++ b/core/user.js @@ -46,7 +46,7 @@ function User() { this.isGroupMember = function(groupIdOrName) { return _.isString(self.groups[groupIdOrName]); - } + }; } diff --git a/core/vertical_menu_view.js b/core/vertical_menu_view.js index 19939dfc..b46a0356 100644 --- a/core/vertical_menu_view.js +++ b/core/vertical_menu_view.js @@ -23,7 +23,7 @@ function VerticalMenuView(options) { this.performAutoScale = function() { if(this.autoScale.height) { this.dimens.height = (self.items.length * (self.itemSpacing + 1)) - (self.itemSpacing); - this.dimens.height = Math.min(this.dimens.height, self.client.term.termHeight - self.position.row); + this.dimens.height = Math.min(self.dimens.height, self.client.term.termHeight - self.position.row); } if(this.autoScale.width) { @@ -39,6 +39,15 @@ function VerticalMenuView(options) { this.performAutoScale(); + this.updateViewVisibleItems = function() { + self.maxVisibleItems = Math.ceil(self.dimens.height / (self.itemSpacing + 1)); + + self.viewWindow = { + top : self.focusedItemIndex, + bottom : Math.min(self.focusedItemIndex + self.maxVisibleItems, self.items.length) - 1 + }; + }; + this.drawItem = function(index) { var item = self.items[index]; if(!item) { @@ -60,6 +69,13 @@ util.inherits(VerticalMenuView, MenuView); VerticalMenuView.prototype.redraw = function() { VerticalMenuView.super_.prototype.redraw.call(this); + if(this.positionCacheExpired) { + this.performAutoScale(); + this.updateViewVisibleItems(); + + this.positionCacheExpired = false; + } + var row = this.position.row; for(var i = this.viewWindow.top; i <= this.viewWindow.bottom; ++i) { this.items[i].row = row; @@ -69,6 +85,12 @@ VerticalMenuView.prototype.redraw = function() { } }; +VerticalMenuView.prototype.setHeight = function(height) { + VerticalMenuView.super_.prototype.setHeight.call(this, height); + + this.positionCacheExpired = true; +}; + VerticalMenuView.prototype.setPosition = function(pos) { VerticalMenuView.super_.prototype.setPosition.call(this, pos); @@ -135,12 +157,11 @@ VerticalMenuView.prototype.getData = function() { VerticalMenuView.prototype.setItems = function(items) { VerticalMenuView.super_.prototype.setItems.call(this, items); - this.performAutoScale(); + this.positionCacheExpired = true; +}; - this.maxVisibleItems = Math.ceil(this.dimens.height / (this.itemSpacing + 1)); +VerticalMenuView.prototype.setItemSpacing = function(itemSpacing) { + VerticalMenuView.super_.prototype.setItemSpacing.call(this, itemSpacing); - this.viewWindow = { - top : this.focusedItemIndex, - bottom : Math.min(this.focusedItemIndex + this.maxVisibleItems, this.items.length) - 1 - }; + this.positionCacheExpired = true; }; \ No newline at end of file diff --git a/core/view.js b/core/view.js index 675b8187..d8cdb3a0 100644 --- a/core/view.js +++ b/core/view.js @@ -146,6 +146,7 @@ View.prototype.setDimension = function(dimens) { }; View.prototype.setHeight = function(height) { + height = parseInt(height, 10); assert(_.isNumber(height)); // :TODO: assert height is within this.client.term.termHeight @@ -154,6 +155,7 @@ View.prototype.setHeight = function(height) { }; View.prototype.setWidth = function(width) { + width = parseInt(width); assert(_.isNumber(width)); // :TODO: assert width is appropriate for this.client.term.termWidth @@ -174,19 +176,50 @@ View.prototype.getFocusSGR = function() { return this.ansiFocusSGR; }; -View.prototype.setProperty = function(propName, value) { +View.prototype.setPropertyValue = function(propName, value) { switch(propName) { case 'height' : this.setHeight(value); break; case 'width' : this.setWidth(value); break; case 'focus' : this.setFocus(value); break; + + case 'text' : + if('setText' in this) { + this.setText(value); + } + break; + + case 'textStyle' : this.textStyle = value; break; + case 'focusTextStyle' : this.focusTextStyle = value; break; + + case 'justify' : this.justify = value; break; + + case 'fillChar' : + if('fillChar' in this) { + if(_.isNumber(value)) { + this.fillChar = String.fromCharCode(value); + } else if(_.isString(value)) { + this.fillChar = value.substr(0, 1); + } + } + + case 'submit' : + if(_.isBoolean(value)) { + this.submit = value; + } else { + this.submit = _.isArray(value) && value.length > 0; + } + break; + + case 'submitArgName' : this.submitArgName = value; break; } - // :TODO: setStyleSGRx() - /* - if(/styleSGR[0-9]+/.test(propName)) { - this.styleSGR + if(/styleSGR[0-9]{1,2}/.test(propName)) { + if(_.isObject(value)) { + this[propName] = ansi.getSGRFromGraphicRendition(value, true); + } else if(_.isString(value)) { + this[propName] = ansi.fromPipeCode(value); + } } - */ }; View.prototype.redraw = function() { diff --git a/core/view_controller.js b/core/view_controller.js index f1cc0f6d..2a61b6e2 100644 --- a/core/view_controller.js +++ b/core/view_controller.js @@ -159,6 +159,64 @@ function ViewController(options) { // :TODO: move this elsewhere this.setViewPropertiesFromMCIConf = function(view, conf) { + // :TODO: This broke at least VerticalMenuView due to order of setting properties... really, + // shouldn't matter what the order is, so that should be fixed. + + for(var propName in conf) { + var propValue; + var propAsset = asset.getViewPropertyAsset(conf[propName]); + if(propAsset) { + switch(propAsset.type) { + case 'config' : + propValue = asset.resolveConfigAsset(config[propName]); + break; + + // :TODO: handle @art (e.g. text : @art ...) + + default : + propValue = propValue = conf[propName]; + break; + + + } + } else { + propValue = conf[propName]; + } + + if(!_.isUndefined(propValue)) { + view.setPropertyValue(propName, propValue); + } + } + + // :TODO: Experimental.... + /* + function setViewProperty2(propName) { + if(!_.isUndefined(conf[propName])) { + var propValue; + var propAsset = asset.getViewPropertyAsset(conf[propName]); + if(propAsset) { + switch(propAsset.type) { + case 'config' : + propValue = asset.resolveConfigAsset(config[propName]); + break; + + // :TODO: handle @art (e.g. text : @art ...) + + default : + propValue = propValue = conf[propName]; + break; + + + } + } else { + propValue = conf[propName]; + } + + if(!_.isUndefined(propValue)) { + view.setPropertyValue(propName, propValue); + } + } + } function setViewProp(propName, setter) { if(!_.isUndefined(conf[propName])) { @@ -189,37 +247,43 @@ function ViewController(options) { view[propName] = propValue; } } - - /* - var propValue = asset.resolveConfigAsset(conf[propName]); - if(propValue) { - if(setter) { - setter(propValue); - } else { - view[propName] = propValue; - } - } - */ } } + */ - setViewProp('width', function(v) { view.setWidth(parseInt(v, 10)); }); - setViewProp('height', function(v) { view.setHeight(parseInt(v, 10)); }); - - setViewProp('itemSpacing', function(v) { view.setItemSpacing(v); }); - setViewProp('items', function(v) { view.setItems(v); }); - - setViewProp('text', function(v) { view.setText(v); }); - setViewProp('textStyle'); - setViewProp('focusTextStyle'); - setViewProp('textMaskChar', function(v) { view.textMaskChar = v.substr(0, 1); }); - setViewProp('justify'); - setViewProp('textOverflow'); + //setViewProp('width', function(v) { view.setWidth(parseInt(v, 10)); }); + //setViewProp('height', function(v) { view.setHeight(parseInt(v, 10)); }); + //setViewProp('itemSpacing', function(v) { view.setItemSpacing(v); }); + //setViewProp('items', function(v) { view.setItems(v); }); + //setViewProp('text', function(v) { view.setText(v); }); + //setViewProp('textStyle'); + //setViewProp('focusTextStyle'); + //setViewProp('textMaskChar', function(v) { view.textMaskChar = v.substr(0, 1); }); + //setViewProp('justify'); + //setViewProp('textOverflow'); + //setViewProp('maskPattern', function(v) { view.setMaskPattern(v); }); + //setViewProp('maxLength'); + //setViewProp('hotKeys', function(v) { view.setHotKeys(v); }); + //setViewProp('argName', function(v) { view.submitArgName = v; }); - setViewProp('maskPattern', function(v) { view.setMaskPattern(v); }); - - setViewProp('maxLength'); + // :TODO: better yet, just loop through properties directly from the JSON and + // call setPropertyValue(). View should be responsible for any conversions, e.g. + // boolean vs maskchar for 'password', etc. + /* + [ + 'width', 'height', + 'itemSpacing', 'items', + 'text', 'textStyle', 'focusTextStyle', 'textMaskChar', + 'justify', 'textOverflow', + 'maskPattern', + 'maxLength', + 'fillChar', + 'password', + ].forEach(function pn(thePropName) { + setViewProperty2(thePropName); + }); + // // styleSGRx: 1..25 // @@ -248,9 +312,6 @@ function ViewController(options) { } }); - - setViewProp('hotKeys', function(v) { view.setHotKeys(v); }); - setViewProp('submit', function(v) { if(_.isBoolean(v)) { view.submit = v; @@ -258,8 +319,8 @@ function ViewController(options) { view.submit = _.isArray(v) && v.length > 0; } }); - - setViewProp('argName', function(v) { view.submitArgName = v; }); + */ + }; this.applyViewConfig = function(config, cb) {