
David Abrahams wrote:
button("click me") doesn't have to be a widget. Think expression templates. It can just build up a type to be used by window to add a button.
As usual, David is right ;-) Look at some of the GUI implementations for Haskell (it is legite to mention Haskell now after FC++ has entered the Boost scene ;-)) They use expressions, which are converted to GUI elements through monadic transitions. I love the notion of *only* dealing with (abstract) expressions when constructing things, and then having it come alive at some point, such as when the expression is attached to a main window. That way, one can more easily serialize/deserialize whole GUI trees, and avoid carrying around "ifdefs" in the GUI expressions. It is a bit similar to the Bridge Pattern applied in the Java AWT library, where all GUI components have peers doing the dirty work, but I would prefer an even more lose connection, through (1) GUI Syntax on one hand and (2) GUI Interaction on the other. Losing the wrapper luggage, we could focus on proper expressions for GUI components and write (dynamic or precompilation) converters from XUL or any other XMLish specification onto that expression language. Then, it is "just" a matter of (monadically) blow some life into the expressions, via std::vector<std::string> occupations; gui::gui_toolkit g; // The implementation, corresponding to David Turner's "window" // Certain people do not like 'list' being reused ;-) // The iterators are saved, but not traversed for now. // 'occupationList' is just an expression, holding the "frozen" iterators gui::list occupationList(occupations.begin(), occupations.end()); g.add(occupationList); // This is where the list come alive, and the iterators are traversed One question is whether Model Objects should be attached to the GUI expressions or the live GUI components? If attached to the former notions, they will have to be frozen, and then populated by the GUI components. Yes, there is a transaction problem here... /David