Boost logo

Boost :

Subject: Re: [boost] [rfc] cppgui
From: Gottlob Frege (gottlobfrege_at_[hidden])
Date: 2009-07-06 02:29:21


On Fri, Jul 3, 2009 at 4:34 PM, Felipe Magno de
Almeida<felipe.m.almeida_at_[hidden]> wrote:

>> - eve layout engine can be used separately from the scripting language
>> ie directly in code
>
> You mean the Eve engine right?

yep

> I'm still trying to put up a basic example of using eve with cppgui.
> But am having a really hard time finding enough information on how to
> do so. I couldn't find any example, and the only tutorial I found in
> adobe site is really strange. Even uses boost::ref(new X), where I
> have no idea how lifetime is dealt with.
> I'm feeling kinda stupid for not being able to navigate adobe site
> well. All I seem to find is overview and reference information.
>

It is not you - it is the site - it IS hard to find what you are
looking for. For now, let's assume that 'layout' will be decoupled
from 'widget library' and maybe you won't have to worry about Eve too
much (yet).

>> I'm not against a springs and struts system, but think about what your
>> goals really are.
>
> Maybe cppgui is not really a GUI library. But a widget system. I think
> even a minimum of autoresizing, and layout is needed with this. So
> that if someone wants to use it alone, he still can.
>
>> An interface needs to be properly aligned and
>> logically grouped. The more that can be done automatically the better.
>> The ultimate goal is to describe the data model and have the interface
>> be automatic (and yet still aestetic).
>
> But these should probably be decoupled from cppgui. Maybe more
> libraries should be written together, which could work decoupled from
> each other. Just like adobe does with adam and eve.
>
>> Eve is a step in that
>> direction. We should strive to do as well or better.
>
> Ok. I'm buying. How should we procede? I think cppgui should be only a
> widget system with signals, coordinate systems, etc. The layout and
> property systems should be decoupled. Cppgui should be be workable
> with eve, and with a new layout system as well.
>

Yep, decoupled. So for any layout system, widgets just need to
describe their measurements. width, height, etc. A few things to
learn from Eve and other experiences:
- widgets (or static/free functions related to the widget) should be
able to calculate their sizes based on inputs - ie a text label widget
should be able to return its size for a given text string
- note that X, Y isn't really the widget's problem. The widget can
calculate its size, but something else will tell it where to be.
- measurements need to include more than just size - it is also
worthwhile to know what the text *baseline* is, and where the ':' is
(if any) in a text label (ie think of a label like "File Name:").
This is so we can align by ':' and by baseline. In general, widgets
should be able to return a set of 'guidelines' (probably *named*
guidelines like "baseline", etc), that a layout system can choose (or
not) to align widgets to.
Some example measurements can be found at
http://stlab.adobe.com/wiki/index.php/Layout_Terminology#Widget_Extents,
although I notice that there really isn't any descriptions offered
there. :-(
In ASL docs/code, 'measurements' are usually referred to as 'metrics' (IIRC).

>> We need to concentrate on properly describing the data first. A
>> language (c++ or other) that says 'this data is a number (with min max
>> etc)' or not only is this a string, but it is an email address (so
>> that interfaces like the iPhone can adapt with @ symbols etc).
>
> How do you intent this to work, without having to define all possible
> cases up-front, allowing extensibility?
>

A few thoughts:
- Start at the bottom - with known data types (int, float, string).
- use a capabilities hierarchy. ie a generic string-editing-widget
can be used as a number-editing-widget, just not the best one.
Similarly it can be a date-editing-widget, etc.
- As a widget-author, all you need to do is to "publish" your widget's
abilities. ie a single string that describes your widget.
"NumberEditor". Eventually we build up a standard set of
descriptions, similar to standard 'concepts' in STL, type-traits, etc.
 ie, we can have 3 different widgets that all advertise as
"NumberEditor", and that would mean they all implement the concept
(and interface) of NumberEditor. I suppose a widget might need to
advertise multiple interfaces that it implements, we would need to
support that as well.

That's it for the widgets. The hard part is the 'widget selector'
that matches the required widget to the data model. Currently, the
'widget selector' is usually the coder (via hand-written code, or RC
files, or Eve, etc), or maybe the UI designer if you can teach them
Eve (which I recommend you do!).
But with descriptions, the 'widget selector' can be automated code.
Consider an example:

struct Date // a poor date struct
{
   int year;
   int month;
   string day;
};

This struct needs to be described to the widget system:
- the struct needs a descriptor string: "Date" // I'll comment about
the naming later
- the struct needs to be flagged as a 'struct' or 'aggregate' or
'record' - ie that it has members fields
- each item within needs a descriptor "Year", "Month", "Day"
- each item needs to be described by type - int, int, string
- each item optionally gets min/max/default and/or an
array/enumeration of possible values (ie [ "Monday", "Tuesday",...] )

Now, the point is that the 'widget-selector' system can look at this
struct and do:
1. do I have a "Date" widget? if yes, use that and be done (or if I
have more than one to choose from, check other constraints to decide
the best one)
2. if I don't have a "Date" widget, I need to make a group of widgets,
one for each member of "Date". ie:
   2.1 Do I have a "Year" widget?
   2.2 If not, do I have an "int" widget? (should, it is a base type)
etc

Note that the widget-selector can decide on the proper selector not
only by the descriptor tag "Day" or just type "string", but also be
the optional criteria - if the string has an enumeration ("Monday",
"Tuesday",...) then the choice might be a pop-up list box (or even a
group of radio buttons if the list is short), or it could just default
to an edit box (and force the validation to happen later).

** As for naming - obviously, if I named my struct up there "Date" and
your widget advertises that it can edit a "Date", then we had better
be talking about the same structure. So maybe it would need
"namespacing" like "MyApp.Date", and then an appropriate widget is
unlikely to be found. - But think about "Boost.DateTime". You can
write a widget that understands "Boost.DateTime" (and maybe a few
people will write competing widgets) and my code will use the boost
DateTime library, and we'll understand each other.

The important part is that, for the widgets, it isn't really more work
- it is just communicating (in some agreed upon way) what it is that
the widget is already doing.

>> Once we have the data description, we can build widgets that can
>> 'advertise' what data types they can display/edit.
>
> I think widgets should be very generic. A push_button displays
> strings, a image_button displays images. There should be no
> restriction if it is an email address or a number.
> The same goes for edit boxes. The restriction should come as a
> controller of these widgets. Connecting to signals. These should
> probably be part of a input/output system for these data types.
>

>From a coding perspective, I agree with you. Write a generic edit
box, and allow hooks for input-validation. From there you can get
postal-code specific editing, or whatever you want - we obviously
can't predict all the possible things someone might want to edit.

But whenever we find things recurring, we specialize the widget (even
if that means wrapping the generic edit box and some validation
together).
Obviously we do this all the time - if we didn't specialize widgets,
all UIs would be full of edit boxes, and almost nothing else. ie no
need for a drop-down list, just type in a edit box; no need for a
file-browser, just type in the file name; no special number control
with increment/decrement handling; etc etc etc.

>> Then the layout
>> engine can pick the best widget given the data  model and the space
>> constraints. For example, you might pick 3 radio buttons for clarity
>> of choice or a dropdown list if little space is available. This should
>> be decided at the layout level.
>
> That would be really cool.
>
>> This is all doable. I've seen and/or built all the necessary building
>> blocks to make it so.
>
> Ok. Then there should be 3 libraries? Widget system, layout system and
> a data model system?
>

Yep. With the widget system being the easiest and first. Once the
widget system describes itself enough, we can move on to layout and
data model. (In fact, for a given widget set, layout info and data
info can actually be completely separate. ie given a widget system
that I can't modify (eg Win32 widget set), I could write complimentary
functions to return metrics and data descriptions, and then hook all
the pieces together independently.)
I guess the real interesting (first?) step is agreeing what the
model/interface for a particular widget is or should be. ie why write
a number-editing-widget before we can figure out how it should work.
Once we figure out the interface and behaviour, then not only can we
go and write it, but we can also label it "Boost.Number" and then away
we go...

Tony


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