- interpolated lookup tables in C++
- buoyancy and fast submerged volume approximation with Physx
- game scripting languages
- Crazy Eddie himself (the project lead) has left the project
- The system seems to constrain or clip siblings to their parent window space
- Frame windows don't support tiling of the window borders
- Adding new and unique widgets to CEGUI is neither straightforward nor well documented. For a game, implementing new and unique widgets is a core task.
- It is a difficult framework to learn which considering its other limitations makes it a poor choice for me
- Its main script bindings are for Lua but after much research and testing I had already decided to use Python (there are also python bindings for CEGUI but even less well documented).
- It also adds a large number of large dll dependencies
So my intention is to re-implement the better features of CEGUI but making it customised to my own specific requirements and without making it too generalised and thus unwieldy.
The design goals of my gui are:
- Minimal but flexible class interface
- Implemented for speed and support for lower end systems
- Support for tiling and scaling of gui textures on each gui part
- Input injection
- Support for imagesets
- Support for a flexible system of relative and/or absolute scaling and positioning of gui elements
- Support for composing complex widgets from groups of simpler gui elements
- No forced clipping of gui elements
- pixel accurate rendering of gui widgets
- Python script bindings
- Easily extensible facility for producing new/custom widgets
- Signals and Slots
- Serialisation
So far I have implemented the basic building block of my gui which is the GuiElement. Each GuiElement's position and size is defined through a class GuiLayout. GuiLayouts allow the client to define the width, height, x position and y position as relative to another GuiElement or as an absolute value in pixels. Through the GuiLayout instance each GuiElement can also be constrained to a minimum or maximum height. When an element resizes, all its children are also triggered to perform a resize, maintaining the constraints of their GuiLayout.
Some example client code might illustrate:
// declare a GuiLayout for a new window:
GuiLayout windowLayout;
windowLayout.width.value = 0.5;
windowLayout.width.metrics_mode = GUI_RELATIVE_PARENT;
windowLayout.height.value = 0.5;
windowLayout.height.metrics_mode = GUI_RELATIVE_PARENT;
windowLayout.alignFrom = GUI_CENTRE;
windowLayout.alignTo = GUI_CENTRE;
windowLayout.relativeTo = 0; // null indicates relative to screen
// create the window using the GuiLayout:
GuiElement* myWindow = new GuiElement("myWindowName", windowLayout);
// now create a GuiLayout for a new button:
GuiLayout buttonLayout;
buttonLayout.width.value = 0.2;
buttonLayout.width.metrics_mode = GUI_RELATIVE_PARENT;
buttonLayout.height.value = 20;
buttonLayout.height.metrics_mode = GUI_ABSOLUTE_PIXELS;
buttonLayout.offsetX = -32;
buttonLayout.offsetX.metrics_mode = GUI_ABSOLUTE_PIXELS;
buttonLayout.offsetY = -32;
buttonLayout.offsetY.metrics_mode = GUI_ABSOLUTE_PIXELS;
buttonLayout.alignFrom = GUI_BOTTOM_RIGHT;
buttonLayout.alignTo = GUI_BOTTOM_RIGHT;
buttonLayout.relativeTo = myWindow;
// and create the button
GuiElement* myButton = new GuiElement("myButtonName", buttonLayout);
This simple example shows code that creates a window which is positioned so that its centre is always in the centre of its parent (the screen), and is half the size of the screen. It then creates a button which is 1/5th the width of the window, 20 pixels high, and fixed so that its bottom right corner is always 32 pixels back and up from the window's bottom right corner. The above example is in C++, but this can also be done in python, so one doesn't need to recompile to modify the gui.
A bit more code is actually required to specify the texturing of the GuiElements (the texture to use and whether it is stretched or tiled) but this should give the idea. More importantly though, is the concept that other Widgets are implemented in terms of GuiElements. So a REAL window widget is actually a collection of GuiElements laid out using the methods above. More and more sophisticated elements can be created from these simple building blocks... A single call to GuiElement* myWindow = new GuiWindow("myWindowName", windowLayout) would internally be creating a number of child GuiElements to represent different parts of the window in question.
This design approach is largely copied from the way CEGUI works, but simplified and without the unweildy xml specifications. Where CEGUI uses xml to define complicated relative dimensions and mathematical operations, I decided that this sort of control is best left to python scripting (xml is best used as a way for representing data rather than functions in my opinion).
Well that little snippet is all for now. The next task I am tackling is connecting the SigSlot library to control gui events, and the unenviable task of grappling with formatting, clipping and drawing text quickly.
If anyone stumbles across this and is genuinely interested in some of the layout implementation details let me know and I might post some of it up.
No comments:
Post a Comment