How do I access UI elements to change their properties?

A user asked:

I have built a UI with buttons and progressBars. The progressBars are actually being used as small color indicators of availability. I want to change the color of the progress bars according to the files found.

But I get 'undefined' if I put it after the creation of the rollout with the progress bars. I want to change the color of these progress bars after they are created based on the data collected.

Answer:

Consider that you are creating a UI rollout with some progressbar in it.

   macroScript TestUI category:"MXS Help"
   (
     -- note that the mactoscript itself defines a scope
     rollout testUI_Rollout"Testing..."
     (
       progressbar Indicator01 width:20 height:20 color:green value:100
     )
     createDialog testUI_Rollout 100 100
   )

You have three ways to access the Indicator01:

  1. Inside the rollout

  2. Before the rollout is created

  3. After the rollout is created

The first way is obvious and is not explained here.

The second way is rather interesting because you can access values that are not yet defined, but are at least pre-initialized.

   macroScript TestUI category:"MXS Help"
   (
     local testUI_Rollout
     -- this defines a variable
     -- which has a memory address but still not valid value.
     -- If you create a function that accesses the variable, the
     -- evaluation will proceed as it sees the variable and assumes
     -- it is a valid rollout. Later, when the actual execution of
     -- the script happens, the variable will REALLY point at a valid
     -- rollout, so everybody is happy!

     fn changeTheLamp theColor =
     (
       testUI_Rollout.Indicator01.color = theColor
       -- the function is outside of the rollout context,
       -- so it has to prefix the UI element access.
     )

     -- This rollout is defined even before the rollout with the lamp
     -- Still, it will be able to change the lamp to yellow using the
     -- above function!
     rollout Changer_Rollout"Testing..."
     (
       button changeIt"CHANGE STATE"
       on changeIt pressed do changeTheLamp [255,255,0]
     )

     rollout testUI_Rollout"Testing..."
     (
       progressbar Indicator01 width:20 height:20 color:green value:100
     )
     createDialog Changer_Rollout 100 30 100 100
     createDialog testUI_Rollout 100 100 100 200
   )

In the third way, consider that you want to access the value of Indicator01 or change its color after the dialog was created. In this case, because the variable TestUi_Rollout points at the rollout definition, you have to access Indicator01 by prefixing it with the rollout name:

   macroScript TestUI category:"MXS Help"
   (
     -- note that the mactoscript itself defines a scope
     rollout testUI_Rollout "Testing..."
     (
       progressbar Indicator01 width:20 height:20 color:green value:100
     )
     createDialog testUI_Rollout 100 100
     TestUI_rollout.Indicator01.color = red
   )

Note that the line is inside the scope of the macroScript where TestUI_rollout is visible. If you want to access the rollout from another script, you must define the rollout as a global variable:

   macroScript TestUI category:"MXS Help"
   (
     global testUI_Rollout --now the rollout is visible to anyone outside!
     rollouttestUI_Rollout"Testing..."
     (
       progressbar Indicator01 width:20 height:20 color:green value:100
     )
     createDialog testUI_Rollout 100 100
   )
   macroScript ChangeStatusTestUI category:"MXS Help"
   (
     TestUI_rollout.Indicator01.color = red
   )

If you execute the first macro, a rollout with green light appears.

If you execute the second one, the lamp turns red.

As you can see, you can access anything from anywhere, provided that you have defined the respective rollouts as local or global variables in upper scopes to make them "visible". Even better, you can declare the variables prior to defining their actual contents and access them before the point they are defined.