Creating widgets directly from an XML theme file

It's always possible to create label widgets by specifying a named element in the theme file, and implementing the named x::w::uielements callback when generating the widgets.

It is possible to create regular widgets directly from a specification in the XML theme file. uigenerator4.C gives an example of creating label widgets from the theme file. This example creates the same label widget wordwraplabel.C, but this approach makes it possible to tweak labels without recompiling the code.

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

  <!--

Custom fonts and colors

The <label> also uses a font called "label", which comes from the
default theme.

  -->
  <font id="title">
    <family>liberation sans</family>
    <point_size>24</point_size>
    <weight>bold</weight>
  </font>

  <color id="background">
    <r>1</r>
    <g>1</g>
    <b>.75</b>
  </color>

  <layout id="main-window-grid" type="grid">
    <background_color>
      <color>background</color>
    </background_color>
    <append_row>
      <name>main-window-contents</name>
    </append_row>
  </layout>

  <factory id="main-window-contents" type="grid">
    <element>
      <label type="theme_text">                                 $#
                                                                $#
${font:title}${color:blue}${decoration:underline}Lorem Ipsum${decoration:none}${color:black}${font:label}

dolor sit amet, consectetur adipisicing elit,                   $#
sed do eiusmod tempor incididunt ut labore et dolore mana       $#
aliqua. Ut enim ad minim veniam, quis nostrud exercitation      $#
ullamco laboris nisi ut aliquip ex ea commodo consequat.        $#
Duis aute irure dolor in reprehenderit in voluptate velit       $#
esse cillum dolore eu fugiat nulla pariatur.                    $#
Excepteur sint occaecat cupidatat non proident,                 $#
sunt in culpa qui officia deserunt mollit anim id est           $#
laborum.</label>

      <options>
	<alignment>center</alignment>
	<widthmm>100.00</widthmm>
      </options>
    </element>
  </factory>

</theme>

The contents of the label is a x::w::theme_text with references to colors and fonts defined in the theme file or the default display theme.

Steps for creating generic widgets from a theme file

Create a generator and an element container
x:w::const_uigenerators generator=
    x::w::const_uigenerators::create("themefile.xml");

x::w::uielements widgets;

The first step is the same as when using named callbacks. A x::w::const_uigenerators object gets created, which loads the theme file and compiles it. An x::w::uielements object gets constructed, which receives the new widgets.

Call a layout manager's or a factory's generate()
x::w::gridlayoutmanager lm=container->gridlayout();

lm->generate("bottom-part", generator, widgets);

A layout manager's or a factory's generate() processes a layout or a factory with a matching id and type. The above example will process the following XML from the theme file:

<layout id="bottom-part" type="grid">

<!-- ... -->
</layout>

The first step is the same as when using named callbacks. A x::w::const_uigenerators object gets created, which loads the theme file and compiles it. An x::w::uielements object gets constructed, which receives the new widgets.

Fetch the created widgets
x::w::button ok_button=widgets.get_element("ok-button");
		

x::w::uielements's get_element() returns a created widget. The above example returns the widget created by the following XML in the theme file

    <element id="ok-button">
      <button>
	<element>
	  <label type="theme_text">Ok</label>
	</element>
      </button>
      <config>
	<appearance>normal_theme</appearance>
      </config>
      <shortcut>Enter</shortcut>
    </element>

Other useful x::w::uielements methods include get_layoutmanager(), and get_listitemhandle(). All new objects created by processing the theme file are referenced by their names. generate() creates them and places them in the x::w::uielements container. The container's method throw an exception if the referenced widget or other object with the given name does not exist.