Boost logo

Boost :

Subject: Re: [boost] Thoughts for a GUI (Primitives) Library
From: Alec Chapman (archapm_at_[hidden])
Date: 2010-09-08 08:31:32


Robert Ramey wrote:
> To make progress in this area. Someone has to:
>
> a) define a doable task
> b) do it
> c) submit it for everyone to pick at it
> d) go back and re-do it
> e) loop until it's accepted.

Completely agree. Here would be my shot at this. I know it's very
manageable in scope and would still be useful in my projects, but those
aren't very demanding. The question is if people think it could be more
broadly useful.

Initially the library would simply provide a general method for binding data
and broadly specifying layout. To actually render the controls, it would
internally wrap an existing third party library and provide a way of
accessing the underlying controls for low level display settings (actually,
it would offer a choice of existing third party libraries to make it easy to
use in existing projects).

To give a quick idea of what I'm proposing, the closest analog seems to be
data binding in WPF, though I'm not terribly familiar with this so people
may know of better examples. The basic idea is that any class that models
something like the property map concept or iterator concept would
automatically have a reasonable default view which could also be completely
changed. More complex dialogs could easily be created by nesting these
types inside each other.

A view basically consists of a list of subviews (eg particular controls) and
a layout for them (eg vertical list). I think this is a fairly well
established idea already. What would be nice is if I could define default
views for arbitrary classes through template specialization. For example,
suppose I had an existing employee class:

struct Employee {
    int id,
    string name
};

Then defining a default view might go something like this:

template<>
View default_view(Employee& e)
{
    View v;
    v.set_layout(vertical_list); //accepts certain predefined layouts or an
arbitrary function
    v << employee.id; //add the first subview; this calls default_view<int>
    v.add_sub_view(default_view(employee.name)); //the previous line could
equivalently be written like this
    return v;
}

Suppose I have an object of type Employee: Employee employee = { 999, "Joe
Smith" }; I could then call show(employee) or equivalently
show(default_view(employee)) to pop up a window for display/editing.

There are a few nice things about this approach:
1. I can define a view for my data without modifying the class definition.
2. It requires almost no boilerplate code.
3. It's easy to define views for complex types as long as views for the
subtypes are defined.
4. Most importantly, IMO, a lot of very powerful things can be done with
iterators
5. If an object models something like the Boost property map concept, it
automatically has a reasonable default view.

For the last point, consider the following alternative definition of an
Employee class:

// declare the class
typedef
    property<employee_id_t, int,
    property<employee_name_t, string,
> > Employee;

// create and populate
Employee employee;
put(employee_id, employee, 999);
employee[employee_name] = "Joe Smith"; //alternate syntax

The nested template syntax makes it possible to automatically loop over the
members to create a view with no work by the user. default_view(employee)
would be automatically defined. An existing class could get the same
behavior by specializing the a few functions (put, get, etc.)

Iterators:

The library would define a default view for any container that can provide
an iterator, such as std::vector, std::list, etc. So I could easily define
a Department class that has a list of employees:

typedef
    property<dept_code_t, int,
    property<dept_name_t, string,
    property<dept_employees, list<Employee>
> > > Department;

Calling show(department) would create a dialog with a list box of employees.
Double clicking on an employee could automatically pop up a more detailed
dialog with no event handling code required from the user.

If I have a Company class that has a list of Departments, I could easily
select among several standard views for complex iterators:
Tabbed dialog with a page for each department Department combo box that
controls an employee list box Record selectors to flip through departments,
along with a search function

This is getting long, so I'll just add that I have some idea of how events
could be incorporated as well. If people are interested in this approach we
can discuss it more.

Alec


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