Boost logo

Boost :

Subject: Re: [boost] Thoughts for a GUI (Primitives) Library
From: Gottlob Frege (gottlobfrege_at_[hidden])
Date: 2010-09-04 00:32:08


I'm afraid to step into this big discussion, but here it goes...

On Thu, Sep 2, 2010 at 5:17 PM, Gwenio <urulokiurae_at_[hidden]> wrote:
> Now for a start for discussion on event handling.
>
> *Event Loop:*
>
> There are two way that come to mind: let the application call a message
> loop/get message function to retreive a message or have the sending of
> messages handled internally like in Java.
> I personally lean toward having a function that is called to process
> messages, but would like to hear what advantages and disadvantages people
> can come up with for each method.
>

These are the same thing, seen from different points of view. Either
roll your own event loop, or pass in your function to the standard
supplied event loop, or derive from the standard event loop and
implement the virtual onEvent() function. A good library would allow
all of these.

>From the OS point of view, there *is* a event queue. You can provide
layers above that in various ways.

>
> Quick List of (some) Methods:
> - Callback Procedure
> This is the simplist form, it has a pointer to a function pointer that is to
> be called. This would be redundant, because the function would need to
> determine the message type, which would have already been done by the back
> end to convert the message to the correct form for the callback.
> - Abstract Handler Class
> This involves having a abstract base class for all event handlers to inherit
> from. The derived classes then define how to handle each type of event. The
> only problem with this arises when dealing with binaries compiled separately
> from the main program as not all aspects of virtual function calls is
> standardized. This would only be a problem in some cases, if ever.
> - Use Boost Signals
> It seems some people believe that Boost Signals would be a good way to
> implement event handling, but I am not very familiar with this
> particular library, so I cannot really comment on it.
> I would like to hear the reason for and against going this route though.
> - Descriptive Structure
> The last way I know of would be to pass a descriptive object (or a pointer
> to one) that provides the back end with the information needed to handle
> events (pointers to related object and pointers of functions to call, ect).
> This is fairly ambiguous, and would need a lot of work to design.
>

Let the Inversion Principle be your guide. The core code needs to
call a function to notify someone when something happens. It doesn't
care about the rest of the framework. So it requires a
boost::function. No more, no less. If that boost::function turns
around and calls signals/slots or an abstract framework or whatever,
that's fine, but it is not up to that piece of the framework to
decide.

In fact, "framework" is the problem. It is a "dirty word" in GUI
design. There should be no framework. Just pieces that happen to
work together. Not because they were designed together, but the
opposite - because they were designed separately. So separately that
they were made to work with anything, not just some pieces they
expected to work with.

>From another email:

On Thu, Sep 2, 2010 at 5:04 PM, Simonson, Lucanus J <
lucanus.j.simonson_at_[hidden]> wrote:
>
> Have you ever written a GUI framework before? Have you ever done cross
> platform applications (with a gui) that work with both Mac and Windows, for
> example? What application domain are you targeting? Games have pretty
> different requirements from office type applications. Before you attempt to
> improve on the state of the art be sure you have mastered the state of the
> art and are in a position to make the right calls on what the next steps
> are.
>

20+ years of writing GUIs. I'm on my 4th or 5th or more now, depending
on how you count. Some are backed by OS controls, some are
independent, some mimic and fit into the OS system, some require their
own framework. Some are "give me a place to put pixels and I'll do
the rest", cross-platform, desktop, mobile, etc. Even java (sadly
:-).

This is a _hard_ problem. Is it doable. Yes. If I had the
time/money I'd tackle it. But I think it would take at least 3 great
programmers and 3 years of work. That's what, at least 1 million$?
And maybe that doesn't even count the edit-box. Text editing is a
nightmare. (It happens to be something else I worked on for years and
years. I do NOT want to do it again. One of the other guys would
need to do that part!) Maybe now with ICU and FreeType and whatever
it would be not as bad, but I suspect it is still a nightmare.

There is a chance you could do it a piece at a time. That _would_
help keep each piece independent - each piece would need to work with
existing GUIs and somehow be a positive addition to the current state
of GUIs. That way people would start to want more.

More random thoughts:

- a check box with an isChecked() function is *wrong*. Ask the model,
not the view. In fact, I think we should spend more time defining a
Model library (_start_ with Adobe's Adam stuff). Given a good
description of the model, and the view becomes easier. Hand me your
model and I can automatically build an aesthetically pleasing GUI for
you. That's the "holy grail" of GUI, for me at least, and I think it
is now doable. It can't be the only option, but it would be a welcome
addition to existing GUIs, I would think.

- a layout engine should take "Layoutable" objects or something more
generic, not Controls. Split these concepts. I've worked on layout
engines that worked with rectangles - those were reusable engines.
I've worked on engines that required virtual functions in the base
class of the control hierarchy. Those are *not* reusable. Again,
Inversion Principle - a layout engine should take what it needs (no
more, no less), not what you happen to have.

- does a Button class create its view/window on construction, or
separately. Some systems, MFC-like, allow:
struct MyDialog : Dialog {
   Button ok;
   Button cancel;
   Text message;
};
You can create a Button without any "window" backing it. Instead you
need to call Button.createWindow() separately. I'm not a big fan of
this, but this is one way. The other is when you call ok = new
Button(), the HWND (or whatever) is created. If the HWND goes away,
so does the Button - what does that mean for your pointer? shared_ptr
and/or weak_ptr can help here.

- even a simple class like Button should be broken into a number of
pieces. ie Button behaviour (how it interacts with mouse and keyboard
- if you click down on the button then hold down the space bar, then
move the mouse outside the button (while still held down) does the
button still look pressed???) is separate from button drawing. So why
are they in the same class? I'd prefer more templates and CRTP and
simple free functions. Mix them together to build controls.

- a good GUI would be bindable to other languages - python, lua, java,
javascript, actionscript,... Lots of GUI-ish logic is often easier in
a scripting language. Of course exposing templates is hard to do. As
it multiple inheritance. There would be limitations depending on the
language.

- Adam/Eve is a nice language for declarative GUI. We also had a DSEL
version, which was nice (particularly for auto-layout, since the model
often lives in the code). But having the script outside the code
means the UI Designers can make it look good without touching the
code. A GUI builder is nice. Maybe we can convince Adobe to add one
to ASL.

Don't write a framework. Write some good reusable and useful and
novel and replaceable pieces of GUI code that can be used now. I
understand that a GUI "framework" that we could all use would be a
"win". But that's just too daunting. What's the biggest "win" that
could be added to existing frameworks? Model + auto layout?
Something else?

Tony


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