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
[source,c]
-------------------------------------------------------------------------------
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
[source,c]
-------------------------------------------------------------------------------
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
[source,c]
-------------------------------------------------------------------------------
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
[source,json]
-------------------------------------------------------------------------------
{
 "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 link:widget_button.html[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` link:widgets_events.html[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.

.Generic widget JSON attributes
[cols=",,,3",options="header"]
|==============================================================================
|  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 link:widgets_events.html[event handler].
