
Hi. I'm Ben, first time poster, occasional lurker. I've been playing around with ideas for a nice cross platform C++ GUI, something I think is lacking. Is there any interest in this? More importantly, are there any thoughts on how this should best be done, and features that would be needed. My idea was to have a base window class, with child windows derived from that (admitedly my ideas are retardly simple on occasion), and a special toplevel window derived too. The base window class would obviously need a number of virtual functions for mouse/key/painting etc and I'm not sure how much this would affect performance, I expect at most you'd have two or three levels of inheritance working, and maybe a dozen or so virtuals? Because I'd like this to be usable in real-time systems (like games) rather than just event driven ones I thought that a desktop class would work well as a top level control for all the windows. To handle the drawing itself, I thought some kind of canvas object, obviously this would be the most platform specific part, with members for the different drawing operations you might need, lines/rects/blitting etc. I've actually worked up a test version of a lot of this, a win32 version and a glut version. The win32 version obviously uses the win32 api. The glut version uses glut but no acceleration at all, everything is rendered to a bitmap and glBitmap'ed to the screen at the end, so all lines etc use software algorithms. Also, the glut version unfortunately isn't totally portable for font based reasons, I had to use windows fonts since glut doesn't let you use truetype fonts afaik. The test version implements the top level window, a textbox and button class. Another point I'd like advice on is how best to handle the platform specific parts of a library like this. Right now, there are three classes (desktop, canvas and window_top_level) with platform specific parts variables or that need seperate versions of methods. I've just used #defines to configure which platform is used, and for ease of finding things I've grouped the platform specific parts in seperate files (so I have a window_top_level.cpp, window_top_level_glut.cpp and window_top_level_windows.cpp) with the common methods in the named cpp file. I have a feeling this might not be the best way of doing things. And ideas? I think it might be better if each platform has an entire implementation in one file to itself. I'm sorry if this is a bit rambling, it's a bit of a mind dump to be honest. I can stick the demo online if anyone is interested. If you are, let me know. Ben.

"Benjamin Munson" <benjaminm@runbox.com> wrote in message news:dfb8sa$j9$1@sea.gmane.org...
Hi. I'm Ben, first time poster, occasional lurker.
I've been playing around with ideas for a nice cross platform C++ GUI, something I think is lacking. Is there any interest in this? More importantly, are there any thoughts on how this should best be done, and features that would be needed.
You might want to look at (and add to) http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?BoostGUI regards Andy Little

I am interested in such a library too (now it is the main reason I offen use Java instead of C++) so I would like to help to project such a library and then to implement it. I have a little experience in OWL, some in Java GUI, MFC and some more in Win API. Unfortunattly I didn't even use (seriously) other platform then Win32/Intel (as C++ compiler I use Borland C++ 5.5, Microsoft Visual C++ Toolkit 2003, Microsoft Visual Studio .NET 2003), so I can only write part for Win. What you say? Adam Badura

Adam Badura wrote:
I am interested in such a library too (now it is the main reason I offen use Java instead of C++) so I would like to help to project such a library and then to implement it. I have a little experience in OWL, some in Java GUI, MFC and some more in Win API. Unfortunattly I didn't even use (seriously) other platform then Win32/Intel (as C++ compiler I use Borland C++ 5.5, Microsoft Visual C++ Toolkit 2003, Microsoft Visual Studio .NET 2003), so I can only write part for Win. What you say?
I too like the Java GUI framework. Especially, the layouts and constructor-creates-a-window features make it possible to rapidly produce a GUI. I tried to make attempts in this direction a while ago, but there are numerous issues. Not only do you need to consider the OS you are targetting (Windows, Linux, MacOS, OS/2, ...), but also what GUI library you are targetting (Qt, Motif, John Torjo's Win32 framework, Win32 API, MFC, WTL, ...). Do you go for a unified coordinate system (Windows and Mac have different coordinate orientations, so do you transform?) What colour model do you use (RGB, CMY, HSV)? Can you convert between them? Do you have a standard colour set (like in HTML)? What event dispatching mechanism do you use (message maps, signals/slots, boost::signal, boost::function)? Are you going to write yet another Windows to C++ layer when ATL/WTL does it *a lot* better than you could do (without ripping the ATL/WTL logic)? What about other OSes? I would say that leveraging the base API for an OS (PalmOS, Windows, GDK, ...) should be avoided -- there are libraries already available that do this. I would suggest using the C++ frameworks as the base line for developing a C++ GUI framework. That way, you can have a thin layer on top of the framework. On top of the thin layer, you could then add support for features like layouts and constructing a window *creates* that window. You could then do something like: int gui_main( int argc, const char ** argv ) { boost::smart_ptr< gui::main_frame > frame( new gui::main_frame( "Hello World" )); frame -> resize( 300, 250 ); frame -> show(); frame -> Invalidate(); // Use an ATL/WTL specific feature return 0; } There is then the issue of supporting window-based objects (that consume window/GUI resources), windowless objects (those that don't) and custom/owner drawn components. Can you mix native components (e.g. a WTL splitter) with the generic framework in *both* directions? - Reece Haston Dunn Software Engineer, Sophos www.sophos.com

I looked on a few GUI C++ libraries, but none of them satisfied me. Most commonly of this reasons: 1) weak support if at all for exceptions (wxWidgets for example) 2) using own classes instead of standard (most common for string) (wxWidgets and MFC for example) 3) using own typedef for char w_char and so on (FLTK or FOX I don't remember well) 4) and like that... Commercial solutions I didn't even analise. I imagined to things like this (I even started, but than had my hard disk broken and lost all data) 1) implement library using nativ API for OS (Win API for Windows for example) 2) use only those parts of API that are REALLY needed (withouth them implementation wont be possible) 3) implement own graphic drawer (like Graphic or Graphic2D for Java or DC for Win) giving support to standard thigns like drawing primitives (points, lines, circles, rectangles, ellipses), drawing texts, or mor advanced things like regions... and you know... everything you feel is needed in such a class 4) this drawer draws all the windows (more precisly windows draw themselfs using this drawer) 5) I didn't thought about messages queues, signals and so on... any solutions? I think using something already made and multiplatform (boost signals and functions as you sayd) could be a good one? Note that using drawer makes it easy to use perhabs for example OpenGL instead on nativ API. Note about color that I started working on library for color management (with conversions) - I posted here a message on that. Anyway I think that GUI library that is standard, multiplatform and using all that C++ and its standard library has to offer is badly needed. Its lack stops me many times of using C++ and most of me friends use now only Java aspecially that it becomes faster. So I'm willing to work on that subject. Adam Badura

In message <dgbrjk$k7r$1@sea.gmane.org>, Adam Badura <abadura@o2.pl> writes
I looked on a few GUI C++ libraries, but none of them satisfied me. Most commonly of this reasons: 1) weak support if at all for exceptions (wxWidgets for example)
wxWidgets can certainly support exceptions.
2) using own classes instead of standard (most common for string) (wxWidgets and MFC for example)
wxWidgets has a wxString class: but you can use a std::string as well; and wxWidgets may well migrate to using std::string. Currently it is forward compatible, to the extent that it implements most of the std::string functions. But I take the point that wxWidgets and MFC currently have native types that (approximately) duplicate the std versions. -- Alec Ross

Alec Ross wrote:
In message <dgbrjk$k7r$1@sea.gmane.org>, Adam Badura <abadura@o2.pl> writes
2) using own classes instead of standard (most common for string) (wxWidgets and MFC for example)
wxWidgets has a wxString class: but you can use a std::string as well; and wxWidgets may well migrate to using std::string. Currently it is forward compatible, to the extent that it implements most of the std::string functions.
But I take the point that wxWidgets and MFC currently have native types that (approximately) duplicate the std versions.
Also, there is nothing stopping you doing: window.SetText( std::string( "Hello World" ).c_str()); and: ATL::CString text; window.GetText( text ); return std::string( static_cast< const char * >( text )); If you want to use TCHAR's: typedef std::basic_string< TCHAR > _tstring; so you could have: namespace boost { namespace gui { #if defined(BOOST_WINDOWS) || defined(BOOST_HAS_TCHAR) typedef std::basic_string< TCHAR > string; #else typedef std::string string; #endif }} Then you can use gui::string in a generic, cross-platform way. Granted, it is (slightly) more work, but there is no need to use the string types provided by a particular GUI framework. - Reece Haston Dunn Software Engineer, Sophos www.sophos.com

Also, there is nothing stopping you doing:
window.SetText( std::string( "Hello World" ).c_str());
and:
ATL::CString text; window.GetText( text ); return std::string( static_cast< const char * >( text ));
If you want to use TCHAR's:
typedef std::basic_string< TCHAR > _tstring;
so you could have:
namespace boost { namespace gui { #if defined(BOOST_WINDOWS) || defined(BOOST_HAS_TCHAR) typedef std::basic_string< TCHAR > string; #else typedef std::string string; #endif }}
Then you can use gui::string in a generic, cross-platform way. Granted, it is (slightly) more work, but there is no need to use the string types provided by a particular GUI framework.
Naturally. Usability of library which cannot use "string" objects would be a best bad. But that makes code longer and harder to understand. STD is made to be used. What for do we have all those classes if every library makes its own (without deriving them from stnadard classes). It is not a case of life or death but i think it is a good habit (to use standard classes) and makes a library (generaly) better. Adam Badura

Adam Badura wrote:
Also, there is nothing stopping you doing:
window.SetText( std::string( "Hello World" ).c_str());
Naturally. Usability of library which cannot use "string" objects would be a best bad. But that makes code longer and harder to understand. STD is made to be used. What for do we have all those classes if every library makes its own (without deriving them from stnadard classes). It is not a case of life or death but i think it is a good habit (to use standard classes) and makes a library (generaly) better.
You would use the above to interact with (GUI) libraries that do not have std::xstring support, just like you would with the C-style functions, ifstream and others. Granted, this situation is not ideal and there are proposals to add std::xstring variants for the C/C++ standard library functions. With a standard GUI library proposal, you would use std::[w]string (depending on the character support for the platform). That is a no brainer. What I was referring to is how you would interact with legacy GUI libraries that don't have inbuilt std::[w]string support, for example: namespace gui { namespace detail { namespace wtl { struct window { void set_text( const gui::string & text ) { SetText( text.c_str()); }; }; }}} - Reece

"Alec Ross" <alec@arlross.demon.co.uk> wrote in message news:wFtaDnDjCYKDFwhn@arlross.demon.co.uk...
In message <dgbrjk$k7r$1@sea.gmane.org>, Adam Badura <abadura@o2.pl> writes
I looked on a few GUI C++ libraries, but none of them satisfied me. Most commonly of this reasons: 1) weak support if at all for exceptions (wxWidgets for example)
wxWidgets can certainly support exceptions.
From http://www.wxwidgets.org/ (General FAQ - FAQ can be entered from a "box" on right of the frontpage) " How to use C++ exceptions with wxWidgets? wxWidgets library itself is unfortunately not exception-safe (as its initial version predates, by far, the addition of the exceptions to the C++ language). However you can still use the exceptions in your own code and use the other libraries using the exceptions for the error reporting together with wxWidgets. There are a few issues to keep in mind, though:
a.. You shouldn't let the exceptions propagate through wxWidgets code, in particular you should always catch the exceptions thrown by the functions called from an event handler in the handler itself and not let them propagate upwards to wxWidgets. b.. You may need to ensure that the compiler support for the exceptions is enabled as, considering that wxWidgets itself doesn't use the exceptions and turning their support on results in the library size augmentation of 10% to 20%, it is turned off by default for a few compilers. Moreover, for gcc (or at least its mingw version) you must also turn on the RTTI support to be able to use the exceptions, so you should use --disable-no_rtti --disable-no_exceptions options when configuring the library (attention to the double negation). " Adam Badura

Adam Badura wrote:
I looked on a few GUI C++ libraries, but none of them satisfied me. Most commonly of this reasons: 1) weak support if at all for exceptions (wxWidgets for example) 2) using own classes instead of standard (most common for string) (wxWidgets and MFC for example)
Well, given that std::basic_string's support for Unicode is lacking, I would consider using custom string class an advantage of those libraries. Hey, you can't even convert std::string to std::wstring, and you can't construct std::wstring from char*. Can you convert std::wstring to any of Unicode's normalization forms? How portable is reading of std::wstring from a file with specific 8-bit encoding? - Volodya

Vladimir Prus wrote:
Adam Badura wrote:
I looked on a few GUI C++ libraries, but none of them satisfied me. Most commonly of this reasons: 1) weak support if at all for exceptions (wxWidgets for example) 2) using own classes instead of standard (most common for string) (wxWidgets and MFC for example)
Well, given that std::basic_string's support for Unicode is lacking, I would consider using custom string class an advantage of those libraries. Hey, you can't even convert std::string to std::wstring, and you can't construct std::wstring from char*. Can you convert std::wstring to any of Unicode's normalization forms? How portable is reading of std::wstring from a file with specific 8-bit encoding?
WRT the MFC/ATL/WTL libraries, they use the Win32 API calls WideCharToMultiByte (WC2MB) and MultiByteToWideChar (MB2WC) to do the conversion using the current thread's codepage. Likewise, their CA2W/CW2A helper classes do a similar thing. The WC2MB/MB2WC API allow you to pass in a specific codepage (not just the current thread/user's). Some of these include: UTF7 = 65000 UTF8 = 65001 UTF16 (Little Endian) = 1200 UTF16 (Big Endian) = 1200 So, you could say something like: std::cout << unicode_cast< std::string >( russian_text, unicode::utf8 ); where, on windows, unicode_cast uses WC2MB/MB2WC and unicode::utf8 is the UTF8 codepage (65001). Going the other way, reading std::wstring from a file... you can detect UTF8/16/32 (LE and BE) by having a Byte Order Mark (BOM) at the start of the file (defined at www.unicode.org) -- this is what is done in Windows. Then you can say: 0xFE 0xFF -- unicode::utf16be; 0xFF 0xFE -- unicode::utf16le; 0xEF 0xBB 0xBF -- unicode::utf8; Then you could have something like: operator>>( std::basic_istream< char > * is, std::wstring & str ) { std::string s; is >> s; // read in a string in its native (raw) form str = unicode_cast< std::wstring >( s, is.unicode_format()); return is; } where *stream::unicode_format() returns the identified unicode form, or some implementation-specific default value. I am not sure about how this would work for Linux, Mac and other operating systems, though. - Reece

Reece Dunn wrote:
Vladimir Prus wrote:
Adam Badura wrote:
I looked on a few GUI C++ libraries, but none of them satisfied me. Most commonly of this reasons: 1) weak support if at all for exceptions (wxWidgets for example) 2) using own classes instead of standard (most common for string) (wxWidgets and MFC for example)
Well, given that std::basic_string's support for Unicode is lacking, I would consider using custom string class an advantage of those libraries. Hey, you can't even convert std::string to std::wstring, and you can't construct std::wstring from char*. Can you convert std::wstring to any of Unicode's normalization forms? How portable is reading of std::wstring from a file with specific 8-bit encoding?
WRT the MFC/ATL/WTL libraries, they use the Win32 API calls WideCharToMultiByte (WC2MB) and MultiByteToWideChar (MB2WC) to do the conversion using the current thread's codepage. Likewise, their CA2W/CW2A helper classes do a similar thing.
The WC2MB/MB2WC API allow you to pass in a specific codepage (not just the current thread/user's). Some of these include: UTF7 = 65000 UTF8 = 65001 UTF16 (Little Endian) = 1200 UTF16 (Big Endian) = 1200
So, you could say something like:
std::cout << unicode_cast< std::string >( russian_text, unicode::utf8 );
Sure, but there's no "std::" in front of "unicode_cast". In fact, I don't know what the "unicode_cast" comes from. My points is not that you cannot implement all the missing functionality for std::string. The point is that std:: namespace does not have this functionality.
I am not sure about how this would work for Linux, Mac and other operating systems, though.
Assuming unicode_cast is from MFC/ATL/WTL -- then well, none for Linux. - Volodya

Sure, but there's no "std::" in front of "unicode_cast". In fact, I don't know what the "unicode_cast" comes from. My points is not that you cannot implement all the missing functionality for std::string. The point is that std:: namespace does not have this functionality.
OK. Then std should have this functionality :) and why doesn't it? Adam Badura

Vladimir Prus wrote:
Reece Dunn wrote:
WRT the MFC/ATL/WTL libraries, they use the Win32 API calls WideCharToMultiByte (WC2MB) and MultiByteToWideChar (MB2WC) to do the conversion using the current thread's codepage. Likewise, their CA2W/CW2A helper classes do a similar thing.
The WC2MB/MB2WC API allow you to pass in a specific codepage (not just the current thread/user's). Some of these include: UTF7 = 65000 UTF8 = 65001 UTF16 (Little Endian) = 1200 UTF16 (Big Endian) = 1200
So, you could say something like:
std::cout << unicode_cast< std::string >( russian_text, unicode::utf8 );
Sure, but there's no "std::" in front of "unicode_cast". In fact, I don't know what the "unicode_cast" comes from. My points is not that you cannot implement all the missing functionality for std::string. The point is that std:: namespace does not have this functionality.
I was proposing unicode_cast as a standard/Boost replacement for the CA2W/CW2A functionality in MFC/ATL in the same way that boost::lexical_cast, et. al. work. I agree that this functionality is lacking in the current standard.
I am not sure about how this would work for Linux, Mac and other operating systems, though.
Assuming unicode_cast is from MFC/ATL/WTL -- then well, none for Linux.
I was suggesting unicode_cast initially as a Boost library (I should have made this clearer). Then, you would have: namespace boost { namespace unicode { enum encoding { utf8, utf16le, utf16be, ... // values implementation defined }; class basic_*fstream{}; // unicode aware file streams unicode_cast< To >( From from, unicode::encoding to_unicode_encoding ) }} using boost::unicode::unicode_cast; This would most likely complement the current work for Unicode support in boost. - Reece
participants (6)
-
Adam Badura
-
Alec Ross
-
Andy Little
-
Benjamin Munson
-
Reece Dunn
-
Vladimir Prus