Loading...
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.
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.WidgetType(ID/name).WidgetMember |
Project.Fader("Fader15").Value = 128 Project.CustomScript(3).ExecuteClick Project.Label("Label22").ForeColor.SetRGB(50,0,90) |
Project.DeviceType(ID/name).DeviceMember |
Project.PowerPointDevice(1).Next Project.TCP_Client(2). |
Project.Nodes.Type(ID/name).NodeMember |
Project.Nodes.Mouse(1).ConnectTarget(2) Project.Nodes.Email(2).DisableOutput |
Project.Variables.Type(name).VariableDataTypeMember |
Project.Variables.Integer("var_int") = 10 Project.Variables.Boolean("var_bool").ToInteger |
Description |
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).BackColor.SetRGB(0,128,128)
Project.Label(i).Transparent = False
DebugMessage(Project.Label(i).Text)
}
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"
L.BackColor.SetRGB(0,128,128)
L.Transparent=False
DebugMessage(L.Text)
}
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.
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"){
F.FadeDown(2)
}
}
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.
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:
DebugMessage(Context.Name)
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.
Context.Client(Client Key[optional]) |
Example: |
This accesses all available client members; set a dot and choose one from the list. The optional Client Key parameter can be used to address a specific client in the system. The Script Assistant offers you available Client Keys. If not set, it refers to the client executing the script. Optionally, you can choose a Client Key to address one client specifically: |
Context.Client(Client Key).Groups.GroupName |
Example: vstring = Context.Client.Groups.<CustomGroupName> |
The Group member refers to Group Values. Set a dot and choose one of the available group names from ScriptAssist to request or edit the respective key. The optional Client Key parameter can be used to address other clients in the system, apart from the particular client executing the script. The Script Assistant offers you available Client Keys. Info: When a Group Value (available in in the WD Unlimited Edition only) is applied to a Window, clients can access pages independent from each other. Per default the Group Value is set to "None" and the pages are synchronized. The return values for above examples show the according Client key, Internal or External information, the IP address (or localhost) and the Session Key from the computer / Session it is executed from. It could look as follows: Client > c21e4700-11aa-22bb-33cc-44dd55ee66ff InternalExternal > Internal IpAddress > 2.0.0.100 or localhost Session > 5e551040-f00f-e99e-d88d-c7b6a55a6b7c
Example 2: DebugMessage(Context.Client("c21e4700-11aa-22bb-33cc-44dd55ee66ff").Groups.InternalExternal) The Debug Logger shows the according Internal or External key from the computer with the defined Client Key.
Example 3: If Context.Client.Groups.Session = "5e551040-f00f-e99e-d88d-c7b6a55a6b7c" {WDMacro("Adminmacro")} A CustomScript button executing this command will execute a macro only if called from the context of the defined Session, not if clicked in other Sessions.
Example 4: Context.Client.Groups.Team = "team_red" This example shows how to assign a Key to a Custom Group called "Team". |
Context.Client.Key |
Example: |
This returns the Client Key as a string value. The return value depends on where the command was executed but has always this format: 82bb84eb-65cc-45c9-bdf1-dc4784f6d4a8 The first example shows how to use it with a string variable named "vstring". You could also write it into a Widget, e.g. a Label via the script: Label1.Text = Context.Client.Key |
Context.Client(Client Key).IP |
Example: Example2: |
This returns the IP address of the Client that executed the command (Example1) or from the Client with the specified Client Key (Example2). The return value could be: 2.0.0.1 or localhost The examples shows how to use it with a string variable named "vstring". You could also write it into a Widget, e.g. a Label via the script: Label1.Text = Context.Client.Ip |
Context.Client(Client Key).PageName |
Example: Example2: |
This returns the name of the current page (Example1) or switches to (Example2). In both cases, the first line refers to the Client that executed the command and the second to the Client with the specified Client Key. The first example shows how to use it with a string variable named "vstring". The return value could be: Page1 You could also write it into a Widget, e.g. a Label via the script: Label1.Text = Context.Client.PageName |
Context.ClientExists(Client Key) |
Example: |
This returns the status of the connection state of the client with the respective Client key as a string or Boolean value. You could also write it into a Widget, e.g. a Label via the script: Label1.Text = Context.ClientExists("c21e4700-11aa-22bb-33cc-44dd55ee66ff") |
Context.ClientKeys |
Example: |
This returns a list containing all Client Keys of currently connected clients or sessions. You could also write it into a Widget, e.g. a DropDown List via the script and a local variable "list": or simply display it in the Debug Logger: DebugMessage(Context.ClientKeys) |
Context.Name |
Example: |
This returns the name of the widget, macro, etc. from which the script is executed, including the parent objects as a string value. If the CustomScriptButton with ID 1 executed the above example, the return value would be: You could also write it into a Widget, e.g. a Label via the script: Label1.Text = Context.Name Context.WidgetName would return the widget's name only: CustomScript1 |
Context.Page |
Example: Example2: |
This accesses all available page members for the page that contains the widget or other object which executed this command. Set a dot and choose a further member from the list. The sub members are described in the topic "Page and Window Members". You could also write it into a Widget, e.g. a Label via the script: Label1.Text = Context.Page |
Context.Script |
Example: |
This returns the CustomScript button's script type that includes this command . You could also write it into a Widget, e.g. a Label via the script: Label1.Text = Context.Script |
ContextName.Session |
Example: |
This accesses all available session members, set a dot and choose one from the list. |
ContextName.SessionName.Contains(search expression) |
Example: |
This returns a Boolean value (False or True) if the indicated expression is stored in the Session. You could also write it into a Widget, e.g. a Label via the script: Label1.Text = Context.Session.Value("Jonathan") |
ContextName.SessionName.Value(specifier) |
Example: |
This command can set or retrieve your own custom value, stored within the WD and responding to the Key in the Session cookie. Please note that you can only store string values! Please refer to the topic "Session and Session Value" in the manual for further information. |
Context.Stack |
Example: |
This returns a list of all objects (different widgets or macros that call other objects/ macros/ functions) which are part of the chain of executing scripts. You could also display it in the Debug Logger: DebugMessage(Context.Stack) |
Context.WidgetId |
Example: |
This returns the ID of the widget that executes this command. You could also write it into a Widget, e.g. a Label via the script: Label1.Text = Context.WidgetId |
Context.WidgetName |
Example: |
This returns the name of the widget that executes this command. You could also write it into a Widget, e.g. a Label via the script: Label1.Text = Context.WidgetName |
Context.WidgetType |
Example: |
This returns the type of the widget that executes this command. You could also write it into a Widget, e.g. a Label via the script: Label1.Text = Context.WidgetType |
Context.Window |
Example: Example2: |
This accesses all available window members for the window that contains the widget or other object which executed this command. Set a dot and choose a further member from the list. The sub members are described in the topic "Page and Window Members". You could also write it into a Widget, e.g. a Label via the script: Label1.Text = Context.Window |