Navigation C API Pages Python bindings Applications

Widget JSON

Widget layout can be loaded from a JSON description. The application can resolve widgets by unique id and event handlers are resolved from the application binary at runtime.

Function to load an application JSON layout
gp_widget *gp_app_layout_load(const char *app_name, void **uids);

gp_widget *gp_app_layout_load2(const char *app_name,
                               const gp_widget_json_callbacks *const callbacks,
                               gp_htable **uids);

Attempts to load an application layout based on app_name. The library first looks for a layout into a user directory and if there is no layout there system directory is used instead. This means that user can override system application layout by creating one in the user home directory.

The uids is a pointer to store the hash table of mappings between widget unique ids and pointers to.

Unless NULL id terminated array of callbacks is provided function and structure pointers are resolved from the runing application by dlsym().

The function returns NULL if no layout has been found or if it couldn’t be parsed.

Callback and structure description table
typedef struct gp_widget_json_addr {
        union {
                void *addr;
                int (*on_event)(gp_widget_event *);
                const struct gp_widget_table_col_ops *table_col_ops;
        };
        const char *id;
} gp_widget_json_addr;

/* Example use */
static const gp_widget_json_addr app_callbacks[] = {
        {.id = "abort", .on_event = abort_on_event},
        {.id = "file_table", .table_col_ops = file_table_ops},
        {}
};

The pointers to application callbacks can either be resolved by the dynamic linker at runtime, or can be explicitly passed in this table. The table has to be sorted by id and NULL id terminted.

Function to load an JSON layout
gp_widget *gp_widget_from_json_str(const char *str,
                                   const gp_widget_json_callbacks *const callbacks,
                                   gp_htable **uids);

gp_widget *gp_widget_layout_json(const char *fname,
                                 const gp_widget_json_callbacks *const callbacks,
                                 gp_htable **uids);

JSON layout can be also loaded from a file or C string.

Example JSON layout
{
 "info": {"version": 1, "license": "GPL-2.0-or-later", "author": "Joe Programmer"},
 "layout": {
  "widgets": [
   {"type": "button", "label": "Button", "on_event": "button_event"}
  ]
 }
}

A JSON layout always starts with an info block. The required parameters in the info block are license and version number. The license should be a SPDX licence identifier. Currently the version is set to 1 and the number will be increased if there are incompatible changes done in the format in a subsequent releases.

The inflo block is followed by a layout block, which describes the widgets.

Widget type defaults to grid and cols and rows default to 1 for a grid widget so the outer widget is a grid with exactly one cell.

The inner widget type is a button and as such it should have either btype or label, in this case we have a button with a label.

The button on_event callback is set to button_event which means that, at runtime, fuction with this name will be resolved by the dynamic linker and called when the button has been pressed.

Table 1. Generic widget JSON attributes
Attribute Type Default Description

uid

string

Widget universal id. Must be unique.

disabled

bool

false

Disables (grays out) widget and all subwidgets.

type

string

grid

Widget type, e.g. button.

align

enum

center

Sets both haling and valign {center, fill}

haling

enum

center

Horizontal alignment {center, left, right, fill}

valing

enum

center

Vertical alignment {center, top, bottom, fill}

on_event

string

Widget event handler function name.

The on_event function is a widget event handler.