Boost logo

Boost :

From: Reece Dunn (msclrhd_at_[hidden])
Date: 2004-12-29 14:26:13


Hi All,

We have different people with different needs and ideas as to what
constitutes a UI system. The general concensus is that the resulting
library should be designed independant of any target implementation and
should support general platforms such as text-based systems. It is also
advisable to allow interaction with a target platform to allow for
platform-specific user code if required.

There are several layers to a (G)UI library:
[1] The platform independant layer.
[2] The geometry layer - unit type, point, size, rect.
[3] The base graphics layer - fonts, canvas, pens, images, etc.
[4] The event handling layer - event loop, events, event handlers.
[5] The UI object layer - frames, forms, widgets, lightweight objects, etc.

Each of these layers is conceptually independant, but builds on top of
the other. Should there be a separate library for each of these layers
(Boost.Platform, Boost.Geometry, Boost.Graphics, Boost.Events and
Boost.UIObject)?

The design for the UI object layer must be able to support:
* native-based UI objects that are dynamically constructed.
* native-based UI objects taken from pre-built elements, e.g. objects
on a form.
* lightweight UI objects that are not native-based.
* custom drawn native-based UI objects (either dynamically constructed
or from pre-constructed objects), in essence a hybrid of native-based
and lightweight UI objects.

All of these UI object forms need to be supported, including bindings to
different platforms/APIs. I see the basic UI object heirarchy as:

    ui::object
       ui::frame
          ui::form
          ui::main_frame
          ui::popup
          ...
       ui::widget
          ui::textfield
          ui::textarea
          ui::button
          ui::grid
          ui::table
          ...
       ui::layout_manager
          ui::flow_layout
          ...

Here, I want to keep the UI object heirarchy as simple as possible. That
is, the heirarchy is not dependant on platform specifics, but the UI
object group to which the object belongs.

A UI object consists of event processing and sizing/positioning. A frame
is a UI object that has border (frame) decoration, with a main frame
being a top-level frame, a form being a frame that is defined by an
external resource and a popup is a frame that hosts components (e.g. a
list of menu items for a specific menu item). A widget is a UI object
that has specific events and data associated with it. A layout manager
is a lightweight UI object that aids the positioning of widgets.

The question is how to make it easy to specify both lightweight and
native UI objects.

Using a component< render_as< Renderer > > structure does not allow for
an easy implementation -- how do you map the implementation details for
a specific component and how do you make it extensible?

I do not yet see an easy approach. I am thinking of a PIMPL-style
implementation, but using templates to simplify allocation does not
allow for easy construction of UI objects. Consider:

    ui::button ok( "OK", ui::button::push );
    ui::button_impl< ui::lightweight_button > cancel( "Cancel" );

Likewise, having a constructor that takes an implementation, how do we
construct the generic interface that allows this implementation. Consider:

    ui::button cancel( "Cancel", new ui::lightweight_button());

Also, having a shallow interface (i.e. each UI object is a top-level
object), you would need duplicate code to handle common things like
event handling and move/resize operations.

All of these approaches has their own advantages and disadvantages.

Regards,
Reece


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk