Analytica 5.0 added several features that allow you to improve your end-user interfaces that you create for your model. One of those enhancements is the ChangeNodeVisibility( ) function that allows you to hide and show, or disable and enable various objects in your interface. You may have an input or output node, button, text or image that is only applicable in certain situations, for example, if a previous option had been selected. By hiding or disabling it, you can remove distraction and make it clearer what your user should be entering.
In today's video, I use the a blackjack game that is implemented in Analytica, where buttons are disabled unless the option is available given the cards showing and state of play, and where various images and text hide and appear at different points in the game. I particularly like the way the logic is structured for determining what is hidden or disabled and what is visible. A guiding principle for creating transparent, understandable and maintainable code or models is referential transparency. This is the idea that when you see the result of a computation, you can look at a Definition and see exactly how that result was computed, as if the Definition is an implicit but equivalent representation of the explicit (fully computed) result. In this case, I think of the state of visibility is the result of a computation, and the way this model structures its management of visibility keeps it referentially transparent.
Enjoy this fun Video Short. Keep an eye on how UI elements disable and hide. When you decide to start hiding or disabling UI elements, please consider structuring your own UI-state logic in a similar fashion, especially if the UI gets very fancy.
Here is the edit table from the video that encodes the logic for when each element is enabled or not:
The identifiers that appear in the expressions are all variables that appear elsewhere in the model. When I'm trying to figure out why a particular button is enabled when it shouldn't be, I can easily trace back through the model's logic here, viewing the results of the various variables of the model. If each UI control had individually changed the visibility of other elements, then you wouldn't really know which control had gotten it into its current state, and you wouldn't have this referential transparency.
Here is the table that determines whether each EI element is hidden or disabled when it is not enabled.
The Hit, Stand, Double and Surrender buttons are disabled but still visible, whereas the “Busted!!” images are hidden when not visible. These are combined to compute the actual state — the second parameter to ChangeNodeVisibility — in
UI_Element_State with this expression
if UI_element_enabled_ and not disable_all Then 'Enabled' else if Hidden_when_disabled then 'Hidden' else 'Disabled'
In the blackjack model, only one of the UI elements is an input node — the input node for
Your_bet. In most models, input/output nodes make up the majority of UI elements. When you control the visibility of input/output nodes, or alias nodes (which is less common), you need to remember that there is an variable object for the actual variable, and an additional object for its input node, each has its own identifier. Because input and output nodes behave as aliases of the original variable, you see the original variable's object window and attribute values then the input node is selected, and it can be a bit tricky to figure out what the identifier of the input or output node is. If you where to evaluate
ChangeNodeVisibility(Handle(Your_bet),'Hidden'), the input node would still be visible, but inside the internals of your model, the variable node for
Your_bet would now be invisible. Although the blackjack model doesn't use this, to save you from having to figure out what the identifier of the input node is, you can call ChangeNodeVisibility on the variable node, but specify the third optional parameter to hide its input node(s).
ChangeNodeVisibility(Handle(Your_bet), 'Disabled', 'UserInputs' )