Project and Context Member

Navigation:  Widget Designer > Script Language > Object and Member Notation (dot syntax) >

Project and Context Member

prev main next

Navigation:  Widget Designer > Script Language > Object and Member Notation (dot syntax) >

Project and Context Member

prev main next


Show/Hide hidden text

The previous topic describes members referring to objects like widgets or variables. Besides those, there are two special, superior objects, Project and Context. They provide information and functionality more abstracted than the normal objects.

Those two powerful tools enable you to program highly sophisticated and automated interfaces, they can turn scripting more complex on one hand, but much more flexible and effective on the other hand.

Project member

The Project is the main parent element of the whole Widget Designer. Using this object permits you dynamic access to all child objects like widgets, certain devices, nodes and global variables.

Accessing Members through the Project Object


Project.Fader("Fader15").Value = 128










Project.Variables.Integer("var_int") = 10



The Script Assistant offers you a list of all available device and widget types, nodes and variables that exist in your project. Simply enter "Project", set a dot and choose an entry from the Script Assistant.

To access the members of a specific object, you have to enter either the ID (if applicable) or the name of the object.

Now, all object specific  properties can be read or set  and all methods can be executed.

For variables, if you access a property, you can even use the data type specific members on them.

All variables accessed by the Project object have their respective data type member. This is explained in this chapter.

The main purpose of using the Project object is automating actions that should be performed on many child elements at once. This makes it for example easy to substitute a row of widget IDs with iterating variables to access their members, or to write a script that searches for all widgets with a special type or value.

This is possible because you can use variables instead of explicitly naming an object. In a few cases this can also be done with normal commands. If you wanted to enable the "Flash" property of 10 Labels (Label1 to Label 10) you could use a for-loop and the following global command:

For i = 1 to 10 {        WDLabelStartFlash(i)}

If you wanted to do the same using the Label member "StartFlash" you would have to write ten script lines: Label1.StartFlash to Label10.StartFlash

This is when the Project member comes into place. The general syntax for widgets is: Project.WidgetType(ID or Name).WidgetMember

For i = 1 to 10 {Project.Label(i).StartFlash}

You can address specific Labels either by their ID (as shown above) or by their name. Often, users change the name in order to "group" certain Widgets or other objects. Another way is using the "Notes" which is shown further down. For now, let's assume we have 10 Labels named Room1_1, Room1_2, ... Room1_10. You can append a variable to a string with a "+" as shown below:

For i = 1 to 10 {Project.Label("Room1_" + i).StartFlash}


Keep in mind that the actions or possibilities with common commands are limited, whilst member notation permits full access. For devices in the Configuration dialog, there are no common commands for example. Looking at Widgets, many return values and a few methods are only accessible via members.

For i = 1 to 10 {

 Project.Tcp_Client(i).Send("Test at " + Now.ToString)

 Project.Label(i).Text = "Client" + i + " sent a message"


 Project.Label(i).Transparent = False



It is also possible to combine this way of scripting with variables. The following script is an alternative for the last one:

For i = 1 to 10 {

 Project.Tcp_Client(i).Send("Test at " + Now.ToString)

 var L = Project.Label(i)

 L.Text = "Client" + i + " sent a message"






Lastly, it is possible to combine this with an if-statement.

Advanced Example 1:

Imagine a WD project that is supposed to monitor position values of a theatrical rigging system. For that, Label1 to Label20 display the height of 20 flown battens. To the left, Label21-40 display the batten name. E.g.

[Label1] = 20 [Label21] = meters for Batten1

[Label2] = 15 [Label22] = meters for Batten2


[Label20] = 20 [Label40] = meters for Batten20


The following script checks with an if-condition which battens are still at their maximum height of 20m. The associated label with the batten name should then flash and turn green.

for i = 1 to 20 {

 if Project.Label(i).Text = 20 {

         Project.Label(i + 20).ForeColor.SetRGB(0,255,0)

         Project.Label(i + 20).StartFlash



This script searches through all labels with ID 1 to 20 for a text value "20" and performs the respective action (set fore color and start flashing) on the label next to the ones where the condition applies (label ID + 20).

Of course this is a very small and simple example, but as the Widget Designer offers you a maximum GUI of 8K x 8K pixels, huge monitoring displays can be arranged, also with BarGraphs, Gauges and other kinds of optical display options.

Finding something special there quickly can become quite difficult, this example provides a simple solution for this problem. The search algorithms can of course be a lot more complex and also include user input, searches can also be automatically timed.


Advanced Example 2:

As already mentioned above, you can change the name of a widget for grouping purposes. The "Notes" field provides an alternative or addition to that. Let's say you have many Faders per page which are already named "Room1_Display_Number" and you would like to fade down only those Faders whose Notes contain the word "Scene1" :

for i=1 to 50 {

 var F = Project.Fader("Room1_Display_" + i)

 if F.Notes.Contains("Scene1"){





As the Notes field is available for many widgets, it is a very easy and versatile tool to group, address or identify them. Another common application is to "reset" toggle buttons, in the way that all toggle button that are currently in the "Pressed" mode should be clicked (but those in the "Released" mode stay). To achieve this, you could use this command: WDCustomScriptForceReleased(i)


As done already in a previous example, we used "var F" to shorten our script as a reference to the Fader. You could also combine this with smart naming of pages. If you named your pages "Room1", "Room2" etc. you could create a string Variable and use this command in a PageEnter script to write the current page name into the variable, e.g. v_currentpage = Window1.PageName
Now, you could start the loop from above example with:
var F = Project.Fader(v_currentpage + "_Display_" + i)

...and use this script anywhere you like without the need to edit it: in a Custom Script Button (even if it is set to "Fix") or Macro or even the PageLeave script.


As shown with all these examples, the Project object enables you to use a complete new dimension of dynamic and flexible scripting within the application.


Context members

The object "Context" always refers to the context of the script wherein it is run.
For example, if you execute a script by clicking a CustomScript button, the context includes the page and window where the widget is located. In addition, it holds the information with which client it was executed. Imagine your project is displayed in your GUI and at the same time via the Web Server in an external browser. It makes a difference whether you click the button in your GUI, or in the browser, they have two different contexts. If you add faders to the project, each client can have different values for the same fader, because the widget is used in different contexts.
If you are interested in the Web Server and the control of those client differing values, please have a look at the topic Group Values.

However, as said above, the context does not only refer to multiple clients. It is also useful for addressing windows, pages and widgets automatically. Try the following:
Create a project and set up one CustomScript button in Page1. Create another window with Page2 and set up a label.
Open the property dialog of the button and type the following into the "On Press Script" section:
Click on the button to execute the script, the Debug Logger will show: Window1/Page1/CustomScript1/ClickScript.
This is the whole context of the executed script, including all parent elements.
Repeat this with the label's On Click Script, and you will get this result: Window2/Page2/Label1/ClickScript.

This should give you a good impression of what a script's context is, it always matters from where it is executed.

Please be aware that scripts must be executed "for real", i.e. for example, a button must be clicked. If you right-click in the script field and choose "Test" or "Test Selected Lines", there is no context! Always execute the script the way it will be by the user afterward.

Here is a list of all available Context members and what they are intended to do, it is recommended to take some time and try them all out. The Debug Logger is a useful tool for this purpose. Keep in mind that each member that returns a value can have additional members referring to their data type.