Scripting is done in JavaScript. Scripts can be placed before or after the pages declaration and can also be included in the event handlers for widgets.
For complicated sets of tasks it is best to write them as functions outside of the pages declarations and then call them within event handlers. For example, in the game of life demo interface there is a button labelled “Kill All Cells”. When pressed this button loops through every button in the MultiButton widget and sets its value to 0. The function for this is as follows (life is the variable name for the MultiButton widget):
control.buttonKiller = function() { for (var i = 0; i < life.children.length; i++) { life.children[i].setValue(0); } }
We attach the function to the global control object so that we don't have to worry about scope when we call it. To call this function we can attach it to a button as follows:
{ "name": "killButton", "type": "Button", "x": .0, "y": .65, "width": .375, "height": .075, "mode": "contact", "isLocal": true, "ontouchstart": "control.buttonKiller()" },
The documentation for each widget lists various methods for them. In addition to widget specific methods there are a number of useful global methods listed below.
- interfaceManager.refreshInterface() - if you have loaded an interface from a remote destination, you can call this method to reload the file. This is very useful when you are designing your interfaces. Just include a button that calls this method in your interface and you can edit your JSON and immediately see the results of the editing.
- oscManager.sendOSC(address, typetags, args...) - this lets you send an OSC message directly from an event handler or other JavaScript function. As a easy example, to send a message with an integer and a float as arguments you would use:
oscManager.sendOSC("/someOSCaddress", "if", 0, 2.2);
- midiManager.sendMIDI("miditype", channel, number, value) - Send MIDI from any event handler. Currently supported types are noteon, noteoff, cc and program change. To send CC #55 value 127 on channel 1:
midiManager.sendMIDI("cc", 1, 55, 127);
- control.changePage(pageNumber) - This method allows you to switch between different pages in your interface. You can pass the method a number or pass the string 'next' or 'previous' to move forwards or backwards by one page.
- control.showToolbar() - Reveals the main application toolbar at the bottom of the screen so you can select a new destination, a new interface etc.
- control.hideToolbar() - Hides the main application toolbar.
Defining Delegates for OSC / MIDI processing
Whenever Control receives a MIDI or OSC message it looks for a widget that outputs the same message and updates its value with the one received. For example, if Control receives an OSC message at "/volume", it will search for a widget that outputs to this address and then update that particular widgets value.
Although this is sufficient for many uses sometimes it is necessary to do custom parsing of OSC and MIDI messages. To do this interfaces can optionally specify a delegate to parse messages. The delegate can be any javascript object; normally you would simply define one when assigning the delegate. An example is given below:
oscManager.delegate = { processOSC : function(oscAddress, typetags, args) { switch(oscAddress) { case "/nextPage": control.changePage('next'); break; case "/previousPage": control.changePage('previous'); break; case "/changeToPage": control.changePage(args[0]); break; default: oscManager.processOSC(oscAddress, typetags, args); break; } } }
Note the line of code oscManager.processOSC(oscAddress, typetags, args);
. We put this as the default case for our switch statement; if the address of our OSC message doesn't match one of the three we defined earlier in the switch this line triggers the default action for OSC messages, which is to search for a widget with the same output address and set its value as described earlier.