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.