
you might consider adding operator[] to point and size also, consider defining area in terms of 2 points, and adding operator[] to that, too regards, michael toksvig "Reece Dunn" <msclrhd@hotmail.com> wrote in message news:BAY101-F20FDD5860C530B8D6ADE17A0AC0@phx.gbl...
Hi All,
I have been working on revising my GUI library that is currently in the sandbox. The motivation for doing this was Andy Little's comment that most GUI libraries start from a particular operating system and then abstract its interface, providing work-arounds for other GUI systems.
There are several considerations to make with a GUI library. For insatance, it should be possible to support GUI interfaces on portable devices (e.g. Palm Pilot/PalmOS) and terminal devices (like is done with the VIM editor). With these devices, code needs to be written to provide common components such as buttons.
Also, the target operating system places design problems on creating a generic interface. For example, Windows supports char * and wchar_t * versions of its API, but the version that should be used depends on whether you are targetting Windows 9x or NT based systems. Windows also requires each component type to be registered before you can create an instance of it.
Each operating system has different arguments that it passes when an event is generated, containing data relating to that event. Consideration must be made to allow events to be written generically, but also allow you to hook into OS-specific events and get OS-specific data.
With all this in mind, how do you design a GUI library for C++? Although a GUI component exists on the screen and is drawn on that screen, the components and graphics elements should be kept seperate, since it is primarily the OSs role to render a component. There are shared elements (mostly the position, size and area types) and the graphics layer should allow for graphics-based events to be handled by the components library.
Taking a look at how C++ is designed, it is predominantly data orientated. That is, C++ allows you to create new data types that fit into the language via operator overloading. The STL provides collections of data and algorithms for manipulating those collections. Terminal-based applications are supported by I/O streams that allow you to send data out and read data in.
I have taken this as the primary design feature when implementing the GUI components. Thus, each component has an event to signal user interaction (ondatachanged, onselectionchanged, onpressed) and data that is associated with the component.
The first thing that comes to mind when reading "data that is associated with the component" is data binding. I think it is a mistake to build data binding directly into the component architecture. The reason for this is twofold:
You would need to use templates to bind the different data objects to the control which makes it harder to implement the controls in a platform-independant way and can lead to code bloat. Also, consider having a textbox widget that you use to enter the age. Having:
gui::textbox< long > age;
How does the textbox perform the conversion? By storing the data as a string, the user can extract the information on data collection like this:
long age = boost::lexical_cast< long >( age_input.get_text());
or
long age = ::atol( age_input.get_text());
Another thing to take into account is when an input field has a validity based on other component values. For example, the valitity of a dates day field is dependant on month and year. In this instance, it is best to put all the validation logic in the base component and extract the data to a date class such as Boost.DateTime's date.
A component has a size and position, as well as visibility (visible or hidden) and enabled/disabled states. The component should make it easy to interoperate with native API.
The majority of the current proposals (mine included) have taken the approach of providing native interoperability with the OS-specific data structures. This is very difficult to maintain properly and support generic code because of the different names of the data elements, types used (long or float) and whether an area is (position + size) or (top-left + bottom-right). Also, most OSs have (0,0) being the top-left corner, but MacOS has (0,0) being bottom-left.
With this in mind, I have taken a drastic approach: do not provide native interoperability for size, position and area. I have designed them as:
struct position{ float x; float y; }; struct size{ float dx; float dy; }; struct area { float top; float left; float width; float height; };
This means that the interface must convert these to the native representations and vise versa.
The current implementation (Windows specific at this time) can be found at: http://uk.geocities.com/msclrhd/gui/gui.zip
Thoughts? Comments?
Regards, Reece
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost