
Hi, I'm already working on a GUI library for some time (three weeks). And come up with some designs and code. I'm sure to have it for review when ready and I would like to ask for comments here to get it going in the right direction. The code is in www.sourceforge.net/projects/cppgui The code is not completely compiling right now, but I'm writing it with support for win32/64, gtk and qt. The main design decision I have is that the GUI interface and the implementation specific code is completely decoupled. That way I can have a application that executes win32, gtk *and* qt at the same time. It is indeed what the first example does. In that, I call the implementations as drivers. And I can have the driver specified in the create window function. Just as this: wnd<> w = create<frame_window>( _driver = drivers::win32 ); For this to work, I had to create two hierarchies: window window_impl_base | | / \ / \ / \ / \ / \ / \ / \ / \ frame button frame_impl_base button_impl_base The first hierarchy is the one exposed to the user and the second must be derived from the drivers. The first can be subclassed by the user with this syntax: class my_frame : gui::subclass<my_frame, gui::frame> { my_frame() { wnd_lock<my_frame> w = wnd_pointer_cast_lock<my_frame>(wnd_from_this()); wnd_lock<gui::controls:button> btn = create<gui::controls::button> ( _parent = w, _size = std::make_pair(20, 20) ); btn_ = btn; } static void info(gui::create_info& i) { i.pos = std::make_pair(100, 100); } wnd<> btn_; }; And then the info function is called before my_frame instantiation automagically. This way my_frame can override the window creation properties before it is actually created by the driver. There's a injection of the window implementation in the window base class of the hierarchy too, so that calling GUI functions from inside the constructor would be safe too. Now, what I think is the most complicated part: wnd<> and wnd_lock<> classes. I decided to use functors as a way to execute handlers for GUI events. Therefore, window smart pointers could end up inside functors objects through boost::bind and others. The problem is: The window should be destroyable while waiting for user response. But if smart pointers inside functors were registered within the window, there would be a cyclic relationship that would prohibit it. And then I created these two classes. wnd<> being like weak_ptr in shared_ptr and wnd_lock<> would be the shared_ptr itself. I honestly do not like this solution and even less the wnd_lock<> name. It even seem to imply thread mutual exclusion, which it does *not*. Also, I found when using asio and win32gui that it is nice to have a class just for the handlers, which holds all its state. So I created a way to register event classes to windows, and to which you can return a functor that returns this event class object to be used in the handler binder. So you can do this: struct event_class { void btn_clicked(wnd_lock<> btn) { // do something } int x; // data required for handlers }; my_frame::my_frame() { wnd_lock<controls::button> btn = create<controls::button> ( _parent = wnd_from_this(), _text = "My button!" ); add_event_class<event_class>(); // this registers to call event_class::btn_clicked with // the event_class object under the window's lifetime management. btn->on_click(boost::bind(&event_class::btn_clicked , boost::bind(get_event_f<event_class>(), _1 )); } That way event classes can be completely defined inside a .cpp file, and any alteration to it wouldn't need the world to recompile, nor would be coupling between event handlers and the visual creation code. In theory, at least. But I find the syntax horrible for event registration and the event handler class ends up being referenced *a lot* inside the window's constructor. So, any comments would be *really* appreciated. And keep in mind that the library is in pre-alpha state (and that's why I'm posting this rfc here, so that I can find a better design to code). Which means that most parts aren't implemented yet. (Most controls, dialogs, resource files, etc). Thanks and best regards, -- Felipe Magno de Almeida

Hi Felipe.
I'm already working on a GUI library for some time (three weeks). And come up with some designs and code.
We use wxWidgets for a portable GUI framework and it works fine for us. Good points are: - is open source - has no license problems that we ran into - has a huge user base - is extremely active - has been extremely active for a long time now - releases new versions reasonably often (unlike boost :-))) *gdr*) - the documentation is good enough (as an extremely good introduction for regular usage there is even a paper book published) - written in a good enough style that it has been easy for us to fix and supply patches for a few problematic areas we ran into. On the 'bad side', wxWidgets does not implement just a GUI library but also has its own 'conquer the world' mentality so it has parts like its own threading, network or file system support but we do not use any of those areas. I do not mean to infer that no one should explore implementing the 'ultimate GUI library' but from my viewpoint it seems more reasonable to hook up to this project and mold it into something better if something does not suit you. The whole GUI support has so many niches and platform specific implementation details in it that I do not believe one can make it ideal but only 'good enough' and strive to constantly improve it. And an existing library such as wxWidgets already has a giant lead in the right direction. Starting a boost.GUI library just for the sake of 'implementing the whole world as a part of boost' does not seem like a good way to go. One possibly good way I see to go about this would be to merge with an external library such as wxWidgets, the same as was done for the (excellent!) asio library, with great benefits for both sides. Boost would get GUI support and the GUI library would get the benefits of existing excellent boost libraries and not have to reimplement them (thus removing the need for double maintenance efforts). Also, users would find it easier to learn/access both of the libraries. Just my 2 cents worth... Best regards, Jurko Gospodnetic'

On 10/21/07, Jurko Gospodnetic' <jurko.gospodnetic@docte.hr> wrote:
Hi Felipe.
Hi Jurko,
I'm already working on a GUI library for some time (three weeks). And come up with some designs and code.
We use wxWidgets for a portable GUI framework and it works fine for us. Good points are:
I'm well aware of wxWidgets. [snip]
I do not mean to infer that no one should explore implementing the 'ultimate GUI library' but from my viewpoint it seems more reasonable to hook up to this project and mold it into something better if something does not suit you.
Not to be too hard on wxWidgets, but wxWidgets isn't even near what I expect from a C++ GUI library.
The whole GUI support has so many niches and platform specific implementation details in it that I do not believe one can make it ideal but only 'good enough' and strive to constantly improve it.
I agree with you here.
And an existing library such as wxWidgets already has a giant lead in the right direction.
But I disagree with this.
Starting a boost.GUI library just for the sake of 'implementing the whole world as a part of boost' does not seem like a good way to go. One possibly good way I see to go about this would be to merge with an external library such as wxWidgets,
To get anything near of what I want, it would be needed to rewrite wxWidget from scratch, so I don't see much difference in approach.
the same as was done for the (excellent!) asio library, with great benefits for both sides.
Asio was at boost quality expectations, and that's why after review it was accepted. I believe those are two completely issues.
Boost would get GUI support and the GUI library would get the benefits of existing excellent boost libraries and not have to reimplement them
Why doesn't wxWidgets use boost? It doesn't have to be included in boost to use it. boost.asio used boost even before it was added (boost.bind) IIRC.
(thus removing the need for double maintenance efforts). Also, users would find it easier to learn/access both of the libraries.
I can't see how. IMO, there would probably be more discussion than development, because of the two different views at C++ development from wxWidgets developers and boost developers.
Just my 2 cents worth...
Best regards, Jurko Gospodnetic'
Thanks, -- Felipe Magno de Almeida

I agree, wxWidgets isn't very "C++ like". For what I would call an ideal C++ widget library look at creating GUIs with Adobe's Future through Eve. It is a GUI library without inheritance. http://opensource.adobe.com/group__asl__tutorials__eve.html http://opensource.adobe.com/group__asl__widgets__carbon.html On 10/21/07, Felipe Magno de Almeida <felipe.m.almeida@gmail.com> wrote:
On 10/21/07, Jurko Gospodnetic' <jurko.gospodnetic@docte.hr> wrote:
Hi Felipe.
Hi Jurko,
I'm already working on a GUI library for some time (three weeks). And come up with some designs and code.
We use wxWidgets for a portable GUI framework and it works fine for us. Good points are:
I'm well aware of wxWidgets.
[snip]
I do not mean to infer that no one should explore implementing the 'ultimate GUI library' but from my viewpoint it seems more reasonable to hook up to this project and mold it into something better if something does not suit you.
Not to be too hard on wxWidgets, but wxWidgets isn't even near what I expect from a C++ GUI library.
The whole GUI support has so many niches and platform specific implementation details in it that I do not believe one can make it ideal but only 'good enough' and strive to constantly improve it.
I agree with you here.
And an existing library such as wxWidgets already has a giant lead in the right direction.
But I disagree with this.
Starting a boost.GUI library just for the sake of 'implementing the whole world as a part of boost' does not seem like a good way to go. One possibly good way I see to go about this would be to merge with an external library such as wxWidgets,
To get anything near of what I want, it would be needed to rewrite wxWidget from scratch, so I don't see much difference in approach.
the same as was done for the (excellent!) asio library, with great benefits for both sides.
Asio was at boost quality expectations, and that's why after review it was accepted. I believe those are two completely issues.
Boost would get GUI support and the GUI library would get the benefits of existing excellent boost libraries and not have to reimplement them
Why doesn't wxWidgets use boost? It doesn't have to be included in boost to use it. boost.asio used boost even before it was added (boost.bind) IIRC.
(thus removing the need for double maintenance efforts). Also, users would find it easier to learn/access both of the libraries.
I can't see how. IMO, there would probably be more discussion than development, because of the two different views at C++ development from wxWidgets developers and boost developers.
Just my 2 cents worth...
Best regards, Jurko Gospodnetic'
Thanks, -- Felipe Magno de Almeida _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Hi.
Not to be too hard on wxWidgets, but wxWidgets isn't even near what I expect from a C++ GUI library.
[...snip...]
And an existing library such as wxWidgets already has a giant lead in the right direction.
But I disagree with this.
Hmmm, what parts did you find lacking? (I do not wish to sound brisk here, I am actually very much interested in the answer.) We have found it to be a tool allowing us to implement portable GUIs using C++. Sometimes class design or other implementation detail encountered in it smells a bit but whenever we approached any concrete problem we found the developers to be most responsive and I can not say we found any extreme design flaws nor anything set in concrete an unchangeable. On the other hand, the library allowed us to solve all the GUI related tasks we set before it. We also use a great wxFormBuilder form designer together with it, allowing fast visual and portable form design during development. Also open source and also an extremely active and responsive project. Preparing the needed similar toolset for a new library seems like a really daunting task...
To get anything near of what I want, it would be needed to rewrite wxWidget from scratch, so I don't see much difference in approach.
Again, I would have to better understand what you expect from a GUI library in order to understand this. As I said above... so far we have not found any big enough problems with wxWidgets.
Why doesn't wxWidgets use boost? It doesn't have to be included in boost to use it. boost.asio used boost even before it was added (boost.bind) IIRC.
I really do not know why it does not use boost. Most likely the two library evolved separately and so there is fear that depending on boost would reduce their platform portability. I personally believe they should but that is a topic for their own mailing list. I also believe that most work with any hypothetical wxWidgets/boost library integration would be in the initial step to upgrade wxWidgets to use boost functionality wherever possible instead of its own (possibly improving respective boost library implementations in the process).
(thus removing the need for double maintenance efforts). Also, users would find it easier to learn/access both of the libraries.
I can't see how. IMO, there would probably be more discussion than development, because of the two different views at C++ development from wxWidgets developers and boost developers.
I can not say I ever saw any drastically different views regarding C++ development in these two groups. My guess would be that both groups automatically consider the other 'different' enough and that no one has enough reason to push for better integration between the libraries. For that matter... I do not either, personally... We already use and are acquainted with both libraries and both are being maintained separately from us with high enough quality. The only potential issue with the two libraries not being cohesive enough is that there is duplicated code in both (different implementations for the same tasks) which can and does confuse new developers coming into both libraries. So far we have dealt with the issue by using wxWidgets only for tasks not supported by boost, which pretty much comes to just its GUI part. And if I had to cast my vote for 'the most needed C++ library' it would be a good logging library and not the GUI one... :-) That is the one area where we have not been able to find a 'good enough' solution for our needs. Best regards, Jurko Gospodnetic'

And if I had to cast my vote for 'the most needed C++ library' it would be a good logging library and not the GUI one... :-) That is the one area where we have not been able to find a 'good enough' solution
He he ;) Please take a look at : http://torjo.com/log2/doc/html/ I'm really interested in your feedback ! Best, John -- http://John.Torjo.com -- C++ expert ... call me only if you want things done right

John Torjo wrote:
And if I had to cast my vote for 'the most needed C++ library' it would be a good logging library and not the GUI one... :-) That is the one area where we have not been able to find a 'good enough' solution
He he ;) Please take a look at : http://torjo.com/log2/doc/html/
I'm really interested in your feedback !
Best, John
Hi, Note other ongoing effort on Logging library: - by Andrey Semashev: http://www.sourceforge.net/projects/cppgui - and by me: http://code.google.com/p/loglite/ Regards, JD

JD wrote:
John Torjo wrote:
And if I had to cast my vote for 'the most needed C++ library' it would be a good logging library and not the GUI one... :-) That is the one area where we have not been able to find a 'good enough' solution
He he ;) Please take a look at : http://torjo.com/log2/doc/html/
I'm really interested in your feedback !
Best, John
Hi,
Note other ongoing effort on Logging library: - by Andrey Semashev: http://www.sourceforge.net/projects/cppgui
Not quite exactly. My lib is here: http://sourceforge.net/projects/boost-log
- and by me: http://code.google.com/p/loglite/

John Torjo wrote:
And if I had to cast my vote for 'the most needed C++ library' it would be a good logging library and not the GUI one... :-) That is the one area where we have not been able to find a 'good enough' solution
He he ;) Please take a look at : http://torjo.com/log2/doc/html/
I'm really interested in your feedback !
Best, John
The documentation needs to be corrected, since in some places it lists the filter as a template parameter type while in others it says that it is not. If you cleaned up the documentation to be consistent, I would love to look at it and try it out for a project on which I am working.

Boost would get GUI support and the GUI library would get the benefits of existing excellent boost libraries and not have to reimplement them
Why doesn't wxWidgets use boost? It doesn't have to be included in boost to use it. boost.asio used boost even before it was added (boost.bind) IIRC.
(thus removing the need for double maintenance efforts). Also, users would find it easier to learn/access both of the libraries.
I can't see how. IMO, there would probably be more discussion than development, because of the two different views at C++ development from wxWidgets developers and boost developers.
From my experience, wxWidgets has a great community and I have always got very positive responses when I have contacted the mailing list. I do not believe that wxWidgets developers have such a different view. Boost integration is already on their radar for wxWidgets3. (see e.g. http://www.wxwidgets.org/wiki/index.php/Development:_wxWidgets_3/LibsArgumen... ). They already work on better STL integration (they do know that a wxString class is not best practice nowadays and want to get rid of it). wxWidgets has evolved the way it has because they wanted to support as many plattforms and compilers as possible - and the compiler situation has become much better meanwhile. Well, I think it's worth a try to contact them and see if one could help each other :).
Best regards, Kai Schroeder

Please keep the MVC, model view controller, pattern in mind from the beginning so that we the users can map our existing data to the gui controls rather than having to add them. This pattern is also used in Java's Swing (not AWT) and somewhat in .NET's windows form. Though I will say that .NET is more like a wrapper around the Win32/64 api and doesn't use MVC extensively. Though in their defense the common IList, ICollection and IEnumerable interfaces works more consistently over all their controls than Java's multitude of control specific model interfaces. So a balance needs to be reached using C++ idioms. As an example, when working on a list control it could be associated with a range of random access iterators. The control than would not add all the items to the control but would rather use delay loading to ask the collection what the data when it needs it. Since STL collections doesn't provide change notifications nor classes by default than such a sublibrary would also need to be considered. -----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Felipe Magno de Almeida Sent: Saturday, October 20, 2007 9:43 PM To: boost@lists.boost.org Subject: [boost] [rfc] Gui library Hi, I'm already working on a GUI library for some time (three weeks). And come up with some designs and code. I'm sure to have it for review when ready and I would like to ask for comments here to get it going in the right direction. The code is in www.sourceforge.net/projects/cppgui The code is not completely compiling right now, but I'm writing it with support for win32/64, gtk and qt. The main design decision I have is that the GUI interface and the implementation specific code is completely decoupled. That way I can have a application that executes win32, gtk *and* qt at the same time. It is indeed what the first example does. In that, I call the implementations as drivers. And I can have the driver specified in the create window function. Just as this: wnd<> w = create<frame_window>( _driver = drivers::win32 ); For this to work, I had to create two hierarchies: window window_impl_base | | / \ / \ / \ / \ / \ / \ / \ / \ frame button frame_impl_base button_impl_base The first hierarchy is the one exposed to the user and the second must be derived from the drivers. The first can be subclassed by the user with this syntax: class my_frame : gui::subclass<my_frame, gui::frame> { my_frame() { wnd_lock<my_frame> w = wnd_pointer_cast_lock<my_frame>(wnd_from_this()); wnd_lock<gui::controls:button> btn = create<gui::controls::button> ( _parent = w, _size = std::make_pair(20, 20) ); btn_ = btn; } static void info(gui::create_info& i) { i.pos = std::make_pair(100, 100); } wnd<> btn_; }; And then the info function is called before my_frame instantiation automagically. This way my_frame can override the window creation properties before it is actually created by the driver. There's a injection of the window implementation in the window base class of the hierarchy too, so that calling GUI functions from inside the constructor would be safe too. Now, what I think is the most complicated part: wnd<> and wnd_lock<> classes. I decided to use functors as a way to execute handlers for GUI events. Therefore, window smart pointers could end up inside functors objects through boost::bind and others. The problem is: The window should be destroyable while waiting for user response. But if smart pointers inside functors were registered within the window, there would be a cyclic relationship that would prohibit it. And then I created these two classes. wnd<> being like weak_ptr in shared_ptr and wnd_lock<> would be the shared_ptr itself. I honestly do not like this solution and even less the wnd_lock<> name. It even seem to imply thread mutual exclusion, which it does *not*. Also, I found when using asio and win32gui that it is nice to have a class just for the handlers, which holds all its state. So I created a way to register event classes to windows, and to which you can return a functor that returns this event class object to be used in the handler binder. So you can do this: struct event_class { void btn_clicked(wnd_lock<> btn) { // do something } int x; // data required for handlers }; my_frame::my_frame() { wnd_lock<controls::button> btn = create<controls::button> ( _parent = wnd_from_this(), _text = "My button!" ); add_event_class<event_class>(); // this registers to call event_class::btn_clicked with // the event_class object under the window's lifetime management. btn->on_click(boost::bind(&event_class::btn_clicked , boost::bind(get_event_f<event_class>(), _1 )); } That way event classes can be completely defined inside a .cpp file, and any alteration to it wouldn't need the world to recompile, nor would be coupling between event handlers and the visual creation code. In theory, at least. But I find the syntax horrible for event registration and the event handler class ends up being referenced *a lot* inside the window's constructor. So, any comments would be *really* appreciated. And keep in mind that the library is in pre-alpha state (and that's why I'm posting this rfc here, so that I can find a better design to code). Which means that most parts aren't implemented yet. (Most controls, dialogs, resource files, etc). Thanks and best regards, -- Felipe Magno de Almeida _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (9)
-
Andrey Semashev
-
Edward Diener
-
Felipe Magno de Almeida
-
Jarrad Waterloo
-
JD
-
John Torjo
-
Jurko Gospodnetic'
-
Kai Schroeder
-
Simon Francis