When you create a binding, you provide a name, a UI control, a game component, and an array of numbers. The array of numbers is a list of card faces (0 for front, 1 for back, and so on) that need to be updated when the bound state changes. For example, if the bound state represented a monster's toughness, then you would use [1], because this information only appears on the back of a monster token.
The Binding Process
When the update() method is called,
it will first call controlToSetting() to convert the
state of the UI component into a setting value (a string).
It will then look in the private settings of the game component for
a setting with the provided name. If the setting does not exist or
is different from the the setting returned from controlToSetting(),
then it will copy the new value into the game component's private settings
and mark the sheets listed in the list of card faces as being out of date.
update() returns true if it updated the component.
When the initComponent() method is called, it will first fetch the named setting from the game component's private settings and then call settingToControl() to modify the state of the control to reflect the setting value.
Handling of SettingBackedControls
The arkham.diy.SettingBackedControl can be used to customize the
mapping between the component state and setting values. When the bound control
implements this interface, then update and initComponent
will call the fromSetting and toSetting methods provided
by the control instead of the default controlToSetting and
settingToControl methods provided by the binding class.
As an example of when this would be useful, consider the case where you
have a combo box of different options, and you want those options to be
localized into the game language. The default binding class will use the string
value of the selected option, so if a component is created in one language,
saved, and opened in another language, the value saved with the component
won't match any of the available options (since it is written in the original
language). Using SettingBackedControl, you could map each label to
a number or other neutral identifer instead. (Although, if the list of
options is fixed, you could use IndexedComboBoxBinding for this
purpose.)
Writing Binding Classes
The Binding base class will copy the text that a user writes
in a text component to a private setting (for update()) and
will set the text in the component to the value of the private setting
(for initComponent(). For other kinds of components, you need to create
an appropriate subclass that knows about the specific kind of control
it is binding the game component state to. To create a subclass you
only need to override the controlToSetting() and
settingToControl() methods to handle the new type of control.
For example, the following binding will bind a checkbox to a yes/no
setting value in the game component:
function CheckboxBinding( name, uiControl, gameComponent, sheetsToUpdate ) { // call superclass constructor Binding.call( this, name, uiControl, gameComponent, sheetsToUpdate ); } CheckboxBinding.subclass( Binding ); CheckboxBinding.prototype.toSetting = function controlToSetting( control ) { if( control.selected ) return 'yes'; else return 'no'; } CheckboxBinding.prototype.settingToControl = function settingToControl( control, value ) { control.selected = value != null && value.equals( 'yes' ); }
If you wish to create more advanced binding behaviours, such as calling methods on the game component instead of setting custom settings, you can override update() and initComponent. It is critical that the update() method returns true if and only if the setting is updated with a different value.
name | the name of the binding; this is used as the setting key to bind the control to; if the name starts with $, the actual key name will be determined by removing the $ and replacing all underscore characters with dashes |
uiControl | the UI component that takes part in the binding |
gameComponent | the game component to bind with the UI component |
sheetsToUpdate | an aray of sheet indices that depend on the bound setting |
returns true if the setting has changed
control | the control whose state must be converted to a string |
returns a string representing the state of the control
value | the string value to be represented by the control |
control | the UI component to modify |
To create a new type of active binding, you must subclass ActiveBinding and override the installActivationHandler() method to make the binding active. (Typically, this means adding a listener to this.control.) This base class adds an ActionListener to this.control, which is sufficient for many kinds of component.
name | the name of the binding; this is used as the setting key to bind the control to |
uiControl | the UI component that takes part in the binding |
gameComponent | the game component to bind with the UI component |
sheetsToUpdate | an array of sheet indices that depend on the bound setting |
editor | the editor that will contain the bound controls |
gameComponent | the game component that that will be edited using the controls |
If bindClass is not specified, then a default class will be searched for Bindings.getBindingClass.
name | the setting key to use for the binding |
control | the UI control that will be used to edit the setting |
sheetsToUpdate | an array of sheet indices that depend on the bound setting |
bindClass | the optional Binding contructor to be used to create the binding |
bindings.bindAll( [ 'determination', detmCtrl, [0] ], [ 'special-effect', effectField, [1] ], [ 'hint', hintField, [0,1] ] );
bindingArray | an array of arrays of binding arguments |
returns an update function for these bindings
returns a field populator function for these bindings
Creates and install listeners on the editor associated with this Bindings instance that will bind the editor controls with the component settings.
Returns a string representation of all of the bindings associated with this Bindings instance.
If componentClass itself does not have a registered binding class, then this method will search up the chain of superclasses of the component's class and return the first registered binding class it finds.
componentClass | a type of component that will be bound using bindingClass |
bindingClass | a constructor for a binding class that can convert between setting strings and component state |
Note: This cannot be used with editable combo boxes.