Boost logo

Boost :

Subject: Re: [boost] [rfc] cppgui
From: Felipe Magno de Almeida (felipe.m.almeida_at_[hidden])
Date: 2009-07-11 14:33:01


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

Sorry for the long delay,

[snip]

>> 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

Ok.I like the free functions idea. To use ADL and allow non-intrusive
interoperability.
But I didn't like the Eve approach. Creating the assemblage code
for Eve is just too hard. If the widget uses overload to use some
properties. Then using the parameters becomes a hell if/else code.
I think the only manageable way to create a assemblage code is using
some static information as well. To allow some metaprogramming and overload
to help.
I think this means a DSEL would be crucial. What do you think?

> - 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.

Ok.

> - 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.

Ok. So we must define what must be returned by widgets. These should be
defined for the layout, and the free functions required should mirror
this.
I don't understand why ':' position is required. Couldn't end of the
widget be used instead?

>>> 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.

I would think a I/O layer for edition would fit here.
Where a string button would be a int button with a I/O controlling
the string editing.

> - As a widget-author, all you need to do is to "publish" your widget's
> abilities. ie a single string that describes your widget.

string? I think we should do that by type_traits/concept_maps. As much
static information as possible the better.

> "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.

I would expect very few multiple interfaces. I think a adaptor to use
multiple different I/O controls to the widget would make the system
more scalable.

> 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;
> };

I think using fusion here would be great.

> This struct needs to be described to the widget system:
> - the struct needs a descriptor string: "Date" // I'll comment about
> the naming later

How about a tag?

> - the struct needs to be flagged as a 'struct' or 'aggregate' or
> 'record' - ie that it has members fields

Or everything that isn't a primitive as our terms (std::string
would be a primitve, for example) we could consider a fusion
sequence. Which means it is a aggregate of other aggregates
and primitives. Which would give more information to the widget
selector as the grouping of these primitives.

> - each item within needs a descriptor "Year", "Month", "Day"

I guess a date would have sub-elements year, month and day.
These descriptions could be derived from a date primitive.

> - 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",...] )

I have to think about this type duality, where something could be a
enumeration of strings or numbers.

> 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

Yes, but these should static information IMO.

> 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).

Yes.

> ** 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.

Or the widget could be reused with a adapter.
But different widgets could be written for the same thing.

> 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.

I think a adapter layer would be appropriate too.

>>> 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.)

Yes, I think non-intrusiveness is important.

> 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...

I think that some adapter is necessary, so that we don't need to derive
a huge amount of widgets to different types.

> Tony

I do like where this is going.

Regards,

-- 
Felipe Magno de Almeida

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