Tutorial: 05 - Modifying the Screen

05 - Modifying the Screen

View the Video Tutorial

Scriptel ScripTouch devices allow you re-arrange elements on their displays which is functionality that OmniScript exposes to you. Each device can hold a variable number of "regions" and these regions are either buttons, lines or containers. You can manipulate all but the first two regions on the device. These routines will work for devices without displays but obviously the results will not be visible.

Regions are updated by sending a RegionUpdateRequest to OmniScript. OmniScript will then parse the request and attempt to manipulate the regions stored on your device. All region updates are stored in runtime memory which means that if you reset your device (un-plug and plug back in) it will return to factory defaults.

You get a list of all regions currently stored on the device when you get the DeviceOpenResponse upon connecting to a device. DeviceOpenResponse contains a ScriptelDevice object which contains an array of Region objects. See the documentation for these types for more information.

Here is an example of how to send a RegionUpdateRequest to OmniScript:

function tutorial() {
    var socket = new WebSocket("ws://localhost:8080");
    socket.onopen = function() {
        console.log("Web Socket Open");
    };
    socket.onclose = function() {
        console.log("Web Socket Closed");
    };
    socket.onmessage = function(evt) {
        var msg = JSON.parse(evt.data);
        if(msg._class==="ConnectionOpen") {
            //We've just connected to the server.
            if(msg.serverInfo.devices.length>0) {
                //Lets open the first available device:
                var device = msg.serverInfo.devices[0];
                console.log("Opening device",device.uuid,": ",device.manufacturer,device.product);
                var obj = {"_class":"DeviceOpenRequest","uuid":device.uuid};
                socket.send(JSON.stringify(obj));
            }
        } else if(msg._class==="DeviceOpenResponse") {
            var obj = {
                "_class": "RegionUpdateRequest",
                "region": {
                    "_class": "Region"
                    "id": 10,
                    "x1": 20,
                    "y1": 20,
                    "x2": 100,
                    "y2": 40,
                    "buttonType": {
                        "_class": "RegionButton";
                        "caption": "Button!",
                        "parentContainer": 2,
                    }
                }
            };
            socket.send(JSON.stringify(obj));
        } else {
            console.log(msg);
        }
    };
}

You'll notice in all cases you need to provide the id of the region to replace and a set of coordinates to tell the device which the location of the new region on screen. The example will place a large button on the left-hand corner of the screen with the caption "Button!". For more information see the below sections for in-depth descriptions of each region type. All regions share a set of flags that can be set for any type. See RegionFlags for more information.

When a region is successfully updated by OmniScript it'll pass back a RegionUpdateResponse object that contains all of the attributes filled in (if you omitted anything). This way you know all of the defaults that were substituted.

Button Regions

Button regions serve two purposes: they can act as traditional buttons or they can serve as textual labels. Buttons are the only region type capable of displaying text. The length of the text of the button is limited to the number returned in the captionLength member of the DisplayInfo object returned in the ScriptelDevice in the DeviceOpenResponse object returned to you when you opened the device. Typically this is around 11 characters.

When updating buttons there are two members you must populate within the RegionButton object you send. These are caption and parentContainer. The "caption" member should be set to the text you'd like be displayed within the button. Text on a ScripTouch device is a block font (all characters take up the same amount of space). The amount of space a character will consume is stored in DisplayInfo returned when you open a device. The text can be set to empty (e.g. ""). The parentContainer member should be populated with the container you'd like to attach the button to. Typically you'll want the parent to be the root container (container 2).

All buttons have flags that can be set that modify how the buttons behave. See RegionButtonFlags for more information.

Here's an example which is the same as the above example but with all of the options filled out:

{
    "_class": "RegionUpdateRequest",
    "region": {
        "_class": "Region",
        "id": 10,
        "x1": 20,
        "y1": 20,
        "x2": 100,
        "y2": 40,
        "buttonType": {
            "_class": "RegionButton",
            "caption": "Button!",
            "parentContainer": 2,
            "flags": {
                "_class": "RegionButtonFlags",
                "clearOnSelect": true,
                "confirmOnSelect": true,
                "enabled": true,
                "highlightOnSelect": true
            }
        },
        "flags": {
            "_class": "RegionFlags",
            "acceptsTouch": true,
            "decodeRegion": true,
            "hasFrame": true,
            "inUse": true,
            "visible": true
        }
    }
}

Here's another example of using a button as a textual label:

{
    "_class": "RegionUpdateRequest",
    "region": {
        "_class": "Region",
        "id": 10,
        "x1": 20,
        "y1": 20,
        "x2": 100,
        "y2": 40,
        "buttonType": {
            "_class": "RegionButton",
            "caption": "Label",
            "parentContainer": 2,
            "flags": {
                "_class": "RegionButtonFlags",
                "clearOnSelect": false,
                "confirmOnSelect": false,
                "enabled": false,
                "highlightOnSelect": false
            }
        },
        "flags": {
            "_class": "RegionFlags",
            "acceptsTouch": true,
            "decodeRegion": true,
            "hasFrame": false,
            "inUse": true,
            "visible": true
        }
    }
}

Line Regions

Line regions are exactly what the name implies, they're regions that store line segments.

Here's an example of how to update a line region:

{
    "_class": "RegionUpdateRequest",
    "region": {
        "_class": "Region",
        "id": 10,
        "x1": 20,
        "y1": 20,
        "x2": 100,
        "y2": 40,
        "lineType": {
            "_class": "RegionLine",
            "parentContainer": 2,
        }
    }
}

This will add a short line segment to the lower left of the screen of your device.

Container Regions

Containers store lines and buttons. The parentContainer member of line and button regions associates them to a particular region. Containers can be used to group up buttons and lines.

This example creates a new container:

{
    "_class": "RegionUpdateRequest",
    "region": {
        "_class": "Region",
        "id": 10,
        "x1": 20,
        "y1": 20,
        "x2": 100,
        "y2": 40,
        "containerType": {
            "_class": "RegionContainer",
        },
        "flags": {
            "hasFrame": true
        }
    }
}