Appendix B. LibCXXW theme files

Index

Creating generic widgets using named callbacks
Creating widgets directly from an XML theme file
Steps for creating generic widgets from a theme file
dims, colors, and borders
Using dims, colors, and borders from the default theme
Derivedcolors, and borders
Gradient colors
Specifying x::w::dim_axis_arg values
fonts
Other values in theme files
x::w::halign values
x::w::valign values
x::w::scrollbar_visibility values
x::w::text_param values
x::w::shortcut values
x::w::list_item_param values
x::w::bidi values
x::w::bidi_format values
containers
Common elements to all layouts
type=book layouts
Creating type=book layouts
type=book layout elements
append_pages and insert_pages
remove
open
close
type=bookpage factorys
halign
valign
set_appearance
add
type=border layouts
Creating type=border layouts
type=border layout elements
replace
update_border, update_borders
update_title
type=standard_combobox and type=editable_combobox layouts
Creating type=standard_combobox and type=editable_combobox layouts
Initializing x::w::new_standard_comboboxlayoutmanager and x::w::new_editable_comboboxlayoutmanager
Creating a type=editable_combobox with a validated input field
type=standard_combobox and type=editable_combobox layout elements
type=grid layouts
Creating type=grid layouts
type=grid layout elements
background_color
remove_background_color
halign
valign
padding
default_col_border and default_row_border
percent
remove_col_defaults and remove_row_defaults
remove_all, remove_row, remove_rows, and remove_cell
append_row, insert_row, append_columns, insert_columns, replace_row, and replace_cell
type=grid factorys
halign
valign
padding
border
colspan and rowspan
remove_when_hidden
elements and containers
type=item layouts
Creating type=item layouts
Initializing x::w::new_itemlayoutmanagers
type=item layout elements
append_item and insert_item
remove_item and remove_items
type=list layouts
Creating type=list layouts
Initializing x::w::new_listlayoutmanagers
type=list layout elements
append_items, replace_all_items, insert_items, and replace_items
remove_item and remove_items
autoselect
append_copy_cut_paste
type=menubar layouts
type=menubar factorys
Adding menus
type=page layouts
Creating type=page layouts
type=page layout elements
append and insert
open and <close/>
type=page factorys
type=pane layouts
Creating type=pane layouts
Initializing x::w::new_panelayoutmanager
type=pane layout elements
append_panes, insert_panes, replace_panes, remove_pane, <remove_all_panes/>, and replace_all_panes
type=pane factorys
type=peephole layouts
Creating type=peephole layouts
Initializing x::w::new_scrollable_peepholelayoutmanagers
type=table layouts
Creating type=table layouts
Initializing x::w::new_tablelayoutmanager
type=table layout elements
replace_header
append_items, replace_all_items, and other list layout manager methods
type=toolbox layouts
Creating type=toolbox layouts
Initializing x::w::new_toolboxlayoutmanager
type=toolbox layout elements
append_tools, insert_tools, remove_tool, and remove_tools
type=toolbox factorys
elements
type=elements factorys
Manual processing of an elements factory
Processing an elements factory after creating a new widget or container
show, hide, show_all, and hide_all
autofocus, get_focus_first, get_focus_before, get_focus_after, get_focus_before_me, get_focus_after_me, and request_focus
Creating tooltips
Creating context popup menus
Label element widgets
Specifying label options
Canvas element widgets
Focusable label element widgets
Button element widgets
Input field element widgets
Creating validated input fields
Date input field element widgets
Image element widgets
Checkbox element widgets
Radio element widgets
Progress bar element widgets
Color picker element widgets
Font picker element widgets
Scroll-bar element widgets
appearances
Creating and using appearance objects
Contents of appearances in theme files
std::optional and std::vector fields
cxxwcreator tool

A theme UI file automates creation of widgets from an XML document, which generates the contents of a layout manager or a factory. The theme UI file also creates several supporting objects: dims, colors, and borders; as well as custom appearance objects.

<?xml version="1.0" encoding="utf-8"?>
<theme version="1"
       xmlns:xi="http://www.w3.org/2003/XInclude">

  <layout type="grid" id="main-window-grid">

    <!-- ... -->

  </layout>

  <factory type="grid" id="button-row">

    <!-- ... -->

  </layout>

  <layout type="book" id="formatting-options">


    <!-- ... -->

  </layout>

  <factory type="book" id="formatting-generic-options">

    <!-- ... -->

  </layout>
</theme>

The XML document's root element is a theme element. For future compatibility, its version attribute should be 1. The theme element contains layout and factory elements. Their id attributes must be unique, and serve as means of referring to each layout and factory element by name. Only the first layout and factory with a unique id takes effect, second and subsequent layouts and factorys with the same id get ignored. In all other respects the relative order of layouts and factorys doesn't matter, and together with XInclude this makes it possible to implement a theme file with shared layouts and factorys, and then include it from other theme files, extending and/or overriding parts of it.

The theme file's XML document also contains several other elements, like dims, colors, borders, and appearance, with their own ids that work the same way.

The element contents of layouts or a factorys depend on their type. The widget content effectively translates to invoking the corresponding methods of a layout manager or a factory:

layouts with a type of book

The element contents of this layout invoke the corresponding methods of a book layout manager.

layouts with a type of editable_combobox

The element contents of this layout invoke the corresponding methods of a editable combo-box layout manager.

layouts with a type of grid

The element contents of this layout invoke the corresponding methods of a grid layout manager.

layouts with a type of list

The element contents of this layout invoke the corresponding methods of a list layout manager.

layouts with a type of menubar

The element contents of this layout invoke the corresponding methods of a book layout manager.

layouts with a type of pane

The element contents of this layout invoke the corresponding methods of a pane layout manager.

layouts with a type of peephole

This is a placeholder for the corresponding methods of a peephole layout manager. All functionality related to the peephole layout manager comes from the config element of the container that creates a container managed by the peephole layout manager.

layouts with a type of standard_combobox

The element contents of this layout invoke the corresponding methods of a standard combo-box layout manager.

layouts with a type of table

The element contents of this layout invoke the corresponding methods of a table layout manager.

factorys with a type of book

The element contents of this layout invoke the corresponding methods of a book page factory.

factorys with a type of grid

The element contents of this layout invoke the corresponding methods of a grid factory.

factorys with a type of menubar

The element contents of this layout invoke the corresponding methods of a menu bar factory.

factorys with a type of pane

The element contents of this layout invoke the corresponding methods of a pane factory.

Creating generic widgets using named callbacks

#include <x/w/uielements.H>
#include <x/w/uigenerators.H>

x::w::gridlayoutmanager grid_layout=container->get_layoutmanager();

x::w::const_uigenerators generators=x::w::uigenerators::create("layouts.xml");

x::w::labelptr created_label;
x::w::buttonptr created_button;

x::w::uielements creators{
    {
          {"label",
           [&]
           (const INSERT_LIBX_NAMESPACE::w::factory &f)
           {
               created_label=f->create_label("Lorem ipsum");
           }
          },
          {"button",
           [&]
           (const INSERT_LIBX_NAMESPACE::w::factory &f)
           {
               created_button=f->create_button("Lorem ipsum");
           }
          },
    }
};

Creating widgets using a theme file is a three step process:

  1. create() an x::w::const_uigenerators object. This loads the theme file and effectively compiles it into an internal representation, a reference-counted object. create() returns a x::w::const_uigenerators handle, a reference to a const object object (the compiled theme file object remains constant after it's created).

  2. Create an x::w::uielements object. The x::w::uielements gets created in automatic scope, and this individual object is no longer required after the widgets get generate()d. The x::w::const_uigenerators contains multiple layout specifications, is constant, and can be used multiple times.

    An x::w::uielements servers a dual purpose. Its first member, factories is a map. The map key's is a text string, a label. The keys' values are lambdas, or callable objects. The lambdas receive a factory as their parameter. It's expected that each lambda uses the factory to create a single widget.

  3. Invoke a layout manager's generate() to execute the compiled theme file, and create its contents.

    grid_layout->generate("main-window-grid", generator, creators);

    A grid layout manager's generate() generates the contents of the contents of the layout manager from the theme file. The first parameter gives the name of a layout whose type must be grid, and have a matching id (main-window-grid, in this example). This executes the specification for this layout from the compiled theme file.

x::w::uielements's second purpose is to store widgets and other objects that generate() creates. x::w::uielements's various methods return different kinds of objects created by generate().

Note

These "other objects" also include layout managers and factories created by generate(). As explained in the section called “Layout managers”, instantiated layout manager (and factories) bring the connection thread to a screeching halt. x::w::uielements should be created in automatic scope, initialized, and used to generate() stuff.

Afterwords if any follow-up work is needed with any generated objects: they should be fetched out of the x::w::uilements object, and everything should then go out of automatic scope and get destroyed after all business gets taken care of.