From bb287cb465a6f9b3e130a99ea30204c90cd862fe Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 9 Apr 2013 18:32:11 -0600 Subject: [PATCH] Add ConfigPanel superclass that can bind fields to config values When you give a config field a `name` attribute based on a config key path, such as 'editor.fontSize', it is automatically kept in sync with the config value. You can also specify a `type` attribute of 'int' or 'float' to automatically convert the field value to a numeric type. Specifying a type of 'string' is optional to signal no conversion. --- spec/app/config-panel-spec.coffee | 36 ++++++++++++++++++++++++++++++ src/app/config-panel.coffee | 24 ++++++++++++++++++++ src/app/editor-config-panel.coffee | 8 +++---- 3 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 spec/app/config-panel-spec.coffee create mode 100644 src/app/config-panel.coffee diff --git a/spec/app/config-panel-spec.coffee b/spec/app/config-panel-spec.coffee new file mode 100644 index 000000000..d1023bc06 --- /dev/null +++ b/spec/app/config-panel-spec.coffee @@ -0,0 +1,36 @@ +ConfigPanel = require 'config-panel' + +describe "ConfigPanel", -> + it "automatically binds named input fields to their corresponding config keys", -> + class TestPanel extends ConfigPanel + @content: -> + @div => + @input outlet: 'intInput', name: 'foo.int', type: 'int' + @input outlet: 'floatInput', name: 'foo.float', type: 'float' + @input outlet: 'stringInput', name: 'foo.string', type: 'string' + + config.set('foo.int', 22) + + panel = new TestPanel + expect(panel.intInput.val()).toBe '22' + expect(panel.floatInput.val()).toBe '' + expect(panel.stringInput.val()).toBe '' + + config.set('foo.int', 10) + expect(panel.intInput.val()).toBe '10' + expect(panel.floatInput.val()).toBe '' + expect(panel.stringInput.val()).toBe '' + + config.set('foo.string', 'hey') + expect(panel.intInput.val()).toBe '10' + expect(panel.floatInput.val()).toBe '' + expect(panel.stringInput.val()).toBe 'hey' + + panel.intInput.val('90.2').change() + expect(config.get('foo.int')).toBe 90 + + panel.floatInput.val('90.2').change() + expect(config.get('foo.float')).toBe 90.2 + + panel.stringInput.val('moo').change() + expect(config.get('foo.string')).toBe 'moo' diff --git a/src/app/config-panel.coffee b/src/app/config-panel.coffee new file mode 100644 index 000000000..7dd4971c4 --- /dev/null +++ b/src/app/config-panel.coffee @@ -0,0 +1,24 @@ +$ = require 'jquery' +{View} = require 'space-pen' + +module.exports = +class ConfigPanel extends View + initialize: -> + @bindFormFields() + + bindFormFields: -> + for input in @find('input[name]').toArray() + do (input) => + input = $(input) + name = input.attr('name') + type = input.attr('type') + @observeConfig name, (value) -> input.val(value) if value + input.on 'change', -> + value = input.val() + config.set name, switch type + when 'int' + parseInt(value) + when 'float' + parseFloat(value) + else + value diff --git a/src/app/editor-config-panel.coffee b/src/app/editor-config-panel.coffee index 1d9b6e216..c6c487b5b 100644 --- a/src/app/editor-config-panel.coffee +++ b/src/app/editor-config-panel.coffee @@ -1,13 +1,13 @@ -{View} = require 'space-pen' +ConfigPanel = require 'config-panel' module.exports = -class EditorConfigPanel extends View +class EditorConfigPanel extends ConfigPanel @content: -> @div class: 'config-panel', => @div class: 'row', => @label for: 'editor.fontSize', "Font Size:" - @input name: 'editor.fontSize', size: 2 + @input name: 'editor.fontSize', type: 'integer', size: 2 @div class: 'row', => @label for: 'editor.fontFamily', "Font Family:" - @input name: 'editor.fontFamily' + @input name: 'editor.fontFamily', type: 'string'