Enable/disable one element based on another
In some cases, you may have one input element that makes sense only when another element has a certain value. For example, suppose that you have a <boolean> that turns on a Recombination Model. If the model is on, then the user must also specify the minority carrier lifetime for electrons and holes. When the Recombination Model is on, these other elements should be active and editable; when it is off, they should be inactive and grayed out, as shown below:
You can include this functionality in your Rappture program by adding an <enable> condition to each of the affected elements. For example,
<boolean id="recomb"> <about> <label>Recombination Model</label> </about> <default>off</default> </boolean> <number id="taun"> <about> <label>Minority Carrier Lifetime for electrons</label> <enable>input.group(dd).boolean(recomb)</enable> </about> <default>1e-6</default> </number> <number id="taup"> <about> <label>Minority Carrier Lifetime for holes</label> <enable>input.group(dd).boolean(recomb)</enable> </about> <default>1e-6</default> </number>
Note the <about><enable> attribute in each of the elements number(taun) and number(taup). It says that each of these elements should be enabled whenever the boolean value input.group(dd).boolean(recomb) is true. So when the Recombination Model is turned on, these elements are enabled, and when it is off, they are disabled.
Enabling/disabling panels of elements
You may have an entire panel of controls that make sense only when a certain option is selected. Instead of adding an <enable> condition to each one, you can put all of the controls in a group, and then enable/disable the entire group. When a group is disabled, it disappears completely. So this capability can be used to swap in and out various pages of controls. For example, suppose you have a <choice> widget that specifies a simulation model. Each model has a set of completely different parameters, and those parameters need only be shown when the model is selected. Otherwise, they just add clutter.
Here is an example of a <choice> element, with a panel of controls beneath it that changes based on the current choice:
Each panel is a <group> that gets enabled only when the appropriate choice is selected.
<choice id="model"> <about> <label>Model</label> </about> <option> <about><label>Drift-Diffusion</label></about> <value>dd</value> </option> <option> <about><label>Boltzmann Transport Equation</label></about> <value>bte</value> </option> <option> <about><label>Quantum Mechanical NEGF</label></about> <value>negf</value> </option> <default>Drift-Diffusion</default> </choice> <group id="dd"> <about> <label>Drift-Diffusion Options</label> <enable>input.choice(model) == "dd"</enable> </about> ... </group> <group id="bte"> <about> <label>Boltzmann Transport Equation Options</label> <enable>input.choice(model) == "bte"</enable> </about> ...
Each <group> has an <about><enable> condition that references the choice input.choice(model). If the choice has the value "dd", then the first panel is shown. If it has the value "bte", then the second panel is shown, and so on. Note that these values match the <value> attribute for each option in the <choice> definition.
Enabling/disabling based on numerical values
In addition to simple choices and boolean values, the <enable> condition can also depend on numerical values. For example, suppose you have a parameter such as High-Energy Lifetime, that gets used only when another paramter exceeds some threshold:
In this case, the trick is that the value of the Tight-Binding Energy has units of eV and we must remove the units before comparing any values. We do this by adding :eV to the path when requesting the value in the <enable> condition:
<number id="tbe"> <about> <label>Tight-binding Energy</label> </about> <units>eV</units> <min>0eV</min> <max>10eV</max> <default>3.12eV</default> </number> <number id="tau"> <about> <label>High-energy lifetime</label> <description>This is used only when the tight-binding energy is above 3eV</description> <enable>input.(negf).number(tbe):eV >= 3</enable> </about> <units>ns</units> <min>0s</min> <max>1s</max> <default>10ns</default> </number>
The path input.(negf).(tbe):eV requests the value of the Tight-binding Energy in units of eV, without the units string. If that number is >= 3, then the High-energy Lifetime is enabled. In the example above, the > sign has been replaced with the text >. This is because the greater than (>) and less than (<) signs are reserved xml characters used to describe tags. Because we don't want the xml parser to get confused and think we are starting or ending a tag, we translate the reserved characters to entity references. The table of xml predefined entity references is listed below.
Some common expressions are listed below.
|Logical Name||Written Expression||Translated to XML|
|Less Than||x < 5||x < 5|
|Greater Than||x > 5||x > 5|
|Less Than or Equal To||x <= 5||x <= 5|
|Greater Than or Equal To||x >= 5||x >= 5|
|Equal||x == 5||x == 5|
|Or||x | | y||x | | y|
|And||x && y||x && y|
A tool can also have hidden parameters or "secret" options that the user doesn't see, but that are passed along through the driver file to the tool. A hidden option has an <enable> condition that is hard-coded to some boolean "false" value. For example,
<integer id="secret"> <about> <label>Secret input number</label> <description>This number never shows up as a user control, but it can be accessed in the simulator.</description> <enable>no</enable> </about> <default>7</default> </integer>
This integer is passed along to the tool with the default value. Since it never has a chance of being enabled, it is hidden completely from the user.