All widgets, including the main application window, have
an opaque appdata
member that LibCXX Widget Toolkit does not use
itself.
appdata
is an opaque
x::ptr<x::obj>
object,
a reference-counted
object. See LibCXX's documentation for more information.
appdata
provides convenient means for an application
to attach its own data to a widget, by deriving from
x::obj
, and saving a
x::ref
to it in appdata
.
With application windows having complicated layouts, and a large number of widgets, it's more convenient to stash away a direct reference to a particular widget, rather than having to drill down and find it, each time. As explained in the section called “Containers own references to the widgets in the container”, LibCXX Widget Toolkit's containers own references to their elements, and in order for application windows and their elements to be properly destroyed and terminated the application must release its own references to them. With LibCXX Widget Toolkit built on top of LibCXX's reference-counted object framework, a lingering reference from an application to some widget will prevent proper destruction of widgets.
The appdata
provides one convenient way to compile a
list of all widgets in one place, safely:
A list of the widgets gets collected into an object and
installed as an appdata
object, that's attached
to the top level main window object.
The appdata
may contain anything that the
application wants, not just x::ref
s to
various widgets in the main window.
The application only holds a reference to the top level
widget, such as an
x::w::main_window
.
The application always uses the top level widget to access
the appdata
.
When the top level widget goes out of scope and gets
destroyed, no other reference to the appdata
remain, so it gets destroyed, together with its references to
the widgets in the appdata
.
Because top level elements, and all containers,
own references to their
child elements, all references to the child elements
properly go out of scope and they get properly destroyed.
The earlier example in this
chapter gives an example of this approach.
inputfieldsandbuttons.C
creates a window containing, amongst other things, two
x::w::input_field
.
Besides being placed into the window, they're also placed into
an object that's attached to the main window's appdata
.
When the window gets closed the application retrieves the main window's
appdata
, retrieves the two input fields, and prints
their contents.
#include <xrefptr_traits.H> #include "inputfields.inc.H" class appdataObj : virtual public x::obj, public inputfields { public: using inputfields::inputfields; }; typedef x::ref<appdataObj> appdata_t;
The sample program uses some supporting framework from the
LibCXX base classes and templates library.
The
Makefile in the
examples
directory
runs a stylesheet to process
inputfields.xml, a
simplistic list of fields and their types.
This generates a header file that declares two classes. The first one
has a list of x::ptr
s for all fields. The
declared x::ptr
s are convenient to have when
creating them, piecemeal.
The second class is inputfields
, with
the final collection of the listed fields,
as their natural x::ref
s.
This is multiply-inherited with
x::obj
to produce a reference-counted
object, an appdata_t
. This gets
create
()d and attached as the
x::w::main_window
's
appdata
.
Before exiting, the sample program retrieves the main window's
appdata
, and shows the contents of the input
fields.
Every widget has an available appdata
.
The application can use this to attach an object to any
widget; but it is important to understand that the widget owns a reference to its appdata
so this
object should not have its own reference to the widget or to
any of its parent container elements (see
the section called “Containers own references to the widgets in the container” for more information). Otherwise
this creates a problematic circular reference.
With some care, it's possible to use
weak pointers, though.
See Chapter 18, The book layout manager for another
example of using appdata
.
See the section called “Using singleton objects” for a different approach to
conveniently compiling a collection of all objects in a manner that's
compatible with LibCXX Widget Toolkit's rules for reference-counted objects.