No announcement yet.

UECIDE gciWidget, how does that work?

  • Filter
  • Time
  • Show
Clear All
new posts

  • UECIDE gciWidget, how does that work?

    I've run the example code from the UECIDE libraries and seen the good old Workshop 4 style display widgets. How does one define their actions and locations? There is the "TEST" files that we drop in the folder, but nowhere have I been able to find anything about how they are configured. The example sketch makes everything work nicely, but how did the files get generated?

    inquiring minds want to know!

  • #2
    GCI on the Picadillo is quite a manual environment.

    First you have to generate the GCI/DAT files themselves in 4D Workshop. I'm not sure if there's a specific Picadillo in there yet, but the normal 3.5" screen that is there does just as well. You lay out the widgets as you want them, and make sure you remember what they are all called. Drop the generated GCI and DAT files on to the SD card.

    Next is the programming side. That's all manual. I'm going to skip all the bits for the SD, TFT and touch screen as they are just "normal".

    You have to create objects for each widget in the DAT file. That's done by name with these lines:

    First create the pointer variables, and load the actual file (without the .gci or .dat extension):
    gciWidgetSet widgets(tft, ts, "/TEST~DTN");
    gciWidget *meter;
    gciWidget *angular;
    gciWidget *sw;
    They can be named anything you like, by the way. Next you have to create the objects themselves, which is done by name:

    meter = widgets.getWidgetByName("Meter0");
    angular = widgets.getWidgetByName("Coolgauge0");
    sw = widgets.getWidgetByName("4Dbutton0");
    The first line does the actual loading of the widgets from the SD card, the subsequent lines just find them in the loaded data.

    The next step is then to assign each widget to "pages", which are the equivalent of the forms in Workshop. Unfortunately the GCI and DAT files don't hold this information - it's in the generated software you'd upload to a 4D display, so isn't available to us - we have to do it manually:

        widgets.setPage(meter, 1);
        widgets.setPage(angular, 1);
        widgets.setPage(sw, 1);
    Now you are able to switch between different pages with the command:

    So, on to making it actually do something. You need to attach "events" to the widgets to make them react to your finger. That's done with the "attachEvent" function:

        sw->attachEvent(TAP, switchPress);
    That will attach the "tap" event to the function "switchPress" on the widget "sw", which is taken from "4Dbutton0" as above. The available events are:

    * PRESS: The act of pushing your finger against the screen
    * RELEASE: The act of lifting your finger up off the screen
    * DRAG: The act of moving your finger while it's pressed against the screen
    * TAP: The act of tapping the screen (PRESS then RELEASE with a small delay between)
    * REPEAT: Triggered repeatedly while your finger is against the screen, at increasing speed.

    The function that is called is a function you write. It gets passed one parameter, which is the widget that caused the event:

    void switchPress(gciWidget *w) {
        switchState = !switchState;
        sw->setValue(switchState ? 1 : 0);
        slider->setValue(switchState ? 1 : 0);
        led->setValue(switchState ? 1 : 0);
    You don't have to do anything with that widget variable, but it can be very useful if you want to share one callback function between multiple widgets. It's also good for simple access to the data contained within the widget.

    And of course nothing will happen unless you tell it to in the main loop - sample the touch screen and render the screen:

    void loop() {
    So what can you do to the widgets themselves? What functions and data are available to you? Here's a little list:

    widget->setValue(n) - Set the frame number of a widget to display
    widget->getValue() - Return the current displayed frame number
    widget->getFrames() - Return the number of frames in a widget
    widget->getEventX() - Get the X touch coordinate of the last event on the widget
    widget->getEventY() - Get the Y touch coordinate of the last event on the widget
    widget->getEventDX() - Get the drag X distance of the last event on the widget
    widget->getEventDY() - Get the drag Y distance of the last event on the widget
    widget->getWidth() - Get the width of the widget
    widget->getHeight() - Get the height of the widget
    widget->setUserValue(n) - Set a single value of "user" data in the widget
    widget->getUserValue() - Return the value set by setUserValue().

    The last two are deceptively useful. You can set a single value (between 0 and 0xFFFFFFFF) which is stored within the widget. That can then be queried. It's great if you have a number of widgets all the same and want to know which is which. You can set a unique value into each of them, and then if they all use the same callback for an event, you can look to see what the value is for the widget that's passed to the event, so you know exactly which widget it is that caused the event.

    Some widget types aren't yet fully supported, such as LED displays etc, but work is in progress to get them fully supported (I have a test version with LED display support I have to check over and integrate into the main repo sometime when I get time).