Chapter 7. Logic interactions between GUI elements

GUI logic

All the basic concepts of creating a plugin for RKWard have been described in the previous chapters. Those basic concepts should be sufficient for many -- if not most -- cases. However, sometimes you want more control over how your plugin's GUI behaves.

For instance, suppose you want to extend the t-test example used in this documentation to allow both: comparing a variable against another variable (as shown), and comparing a variable against a constant value. Now, one way of doing this would be to add a radio-control that switches between the two modes, and adding a spinbox to enter the constant value to compare against. Consider this simplified example:

<!DOCTYPE rkplugin>
<document>
	<code file="code.js"/>

	<dialog label="T-Test">
		<row>
			<varselector id="vars"/>
			<column>
				<varslot id="x" types="number" source="vars" required="true" label="compare"/>
				<radio id="mode" label="Compare against">
					<option value="variable" checked="true" label="another variable (select below)"/>
					<option value="constant" label="a constant value (set below)"/>
				</radio>
				<varslot id="y" types="number" source="vars" required="true" label="variable" i18n_context="Noun; a variable"/>
				<spinbox id="constant" initial="0" label="constant" i18n_context="Noun; a constant"/>
			</column>
		</row>
	</dialog>
</document>
	

So far so good, but there are a number of problems with this GUI. First, both the varslot and the spinbox are always shown, whereas only one of the two is really used. Worse, the varslot always requires a valid selection, even if you compare against a constant. Obviously, if we create a multi-purpose GUI like this, we want more flexibility. Enter: the <logic> section (inserted at the same level as <code>, <dialog>, or <wizard>).

	[...]
	<code file="code.js"/>

	<logic>
		<convert id="varmode" mode="equals" sources="mode.string" standard="variable" />

		<connect client="y.visible" governor="varmode" />
		<connect client="constant.visible" governor="varmode.not" />
	</logic>

	<dialog label="T-Test">
	[...]
	

The first line inside the logic section is a <convert> tag. Basically, this provides a new boolean (on or off, true or false) property, which can be used later on. This property ("varmode") is true, whenever the upper radio button is selected and false whenever the lower radio button is selected. How is this done?

First, under sources, the source properties to work on are listed (in this case only one each; you could list several as sources="mode.string;somethingelse", then "varmode" would only be true, if both "mode.string" and "somethingelse" are equal to the string "variable"). Note that in this case we don't just write "mode" (as we would in getString("mode")), but "mode.string". This is actually the internal way a radio control works: It has a property string, which holds its string value. getString("mode") is just a shorthand, and equivalent to getString("mode.string"). See the reference for all properties of the different GUI elements.

Second, we set the mode of conversion to mode="equals". This means, we want to check, whether the source(s) is (are) equal to a certain value. Finally standard is the value to compare against, so with standard="variable", we check whether the property "mode.string" is equal to the string "variable" (the value of the upper radio option). If it is equal, then the property varmode is true, else it is false.

Now to the real stuff: We <connect> the "varmode" property to y.visible, which controls whether the varslot "y" is shown or not. Note that any element which is made invisible is implicitly non-required. Thus, if the upper radio-option is selected, the varslot "y" is required, and visible. Else it is not required and hidden.

For the spinbox, we want the exact reverse. Fortunately, we do not need another <convert> for this: Boolean properties can be negated very easily by appending the modifier "not", so we <connect> "varmode.not" to the spinbox's visibility property. In effect, either the varslot is shown and required, or the spinbox is shown and required - depending on which option is selected in the radio control. The GUI is changing itself according to the radio option. Try the example, if you like.

For a complete list of properties, refer to the reference. One more property, however, is special in that all GUI elements have it: enabled. This is slightly less drastic than visible. It does not show/hide the GUI element, but only enables/disables it. Disabled elements are typically shown grayed out, and do not react to user input.

Note

Besides <convert> and <connect>, there are several further elements for use in the <logic> section. E.g. conditional constructs can also be implemented using the <switch>-element. Refer to the reference on logic elements for details.