About Automatic Layouting, and Skinning
Posted: Fri Dec 24, 2010 15:46
Hello, CrazyEddie and kulik !
I am currently using your library for a project of flexible and networked RPG-oriented game engine, which, thanks to libraries like CEGUI is going quite well.
So first of all let me thank you for your great work ! I'll post a video of my project soon, I promise.
It's been more than I year that I have been sporadically using CEGUI, designing layouts, reading your updates about where you're headed, and I'm starting to get a view of the two only points where I feel CEGUI lacks something. I think these two points are the only thing needed for CEGUI to be considered complete and more than anything, easy to use. Everything else (like the tools) would be a bonus.
These two points are :
- Automatic layouting as a core feature and not as a particular type of window. Absolute positioning (be it ratio-based or pixel-based) should be possible but would be rarely used.
When I say layouting, I'm talking about positionning but also automatic shrinking and expanding.
To illustrate this first point, the thing to ask yourself is : what do you do when you design an interface mockup on paper. You divide the screen rectangles into sub rectangles, and then put constraints on them, depending on what you want to fit inside them. You very rarely care in the exact position of a widget : it generally just fit as a content in a subdivision you defined, with given margins.
Designing a GUI layout in code should feel exactly like this process. I will create a window and then divide it vertically. The subdivisions themselve could have minimum or maximum size constraints. And they should always shrink and expand, in the limit defined by these constraints, to their contents.
The hassle associated to writing any layout would be vastly diminished, and the result would be much more flexible and scalable. The absolute positioning system would still be usable.
I think the current approach of a separate LayoutContainer wouldn't allow this because the system needs to recurse through the whole hierarchy to play nicely, whereas a separate LayoutContainer can't recurse.
If you think the idea is worth any value I would gladly make a more detailed proposal, maybe even a patch ? I don't think the amount of coding involved is enormous, but I think I'll look into it by myself.
Thinking about it, since I need such a system for my project I may even write a patch anyway and see what it's worth
The second point where CEGUI has been giving me headaches is the skinning :
- An easy and straightforward skining system
I think the current system has reached a point of over-flexibility, where you can basically do anything you want in a Look'n'Feel definition, but the cost associated with doing anything is way is way too high, and the responsibilities are interleaved in a confused and confusing manner.
Skining should really be just this : the visual appearance of a window/widget. Skinning and logic should not be mixed, so you could change a skin on the fly on any widget at any time.
A skin should really just be defined by this :
- Top, bottom, left, right borders images
- All four angles images
- A filler image
- A global image
- A font, size, color
And that's it. Defining the look of a widget should take you from 3 to ~10 lines of text, and involve nothing else than the appearance of a window at a given state.
It should be appliable to any widget, whatever the type of this widget : I shouldn't care whether the widget will be a pushbutton or a statictext or whatever when writing a skin : it should be reusable accross many different types.
A skin is not linked to any functional definition. It's not linked to a particular kind of widget. It can be applied to ANY widget.
The current skinning systems contains many other things which I don't think should be part of a skinning system.
- Layouting should be part of layouts, not skin. The current system allows layouting in the look'n'feel : the current framewindow is one widget, whereas it should be really three widgets assembled in a layout, and accessible from code logic.
- The logic between switching different states should not be part of the skin. For example, if a button has three states, which are linked to three different skin (button_normal, button_hover, and button_down), these should be defined separately in a look'n'feel definition.
So, in the end, I guess a Skin definition should be factored out from the current Look'n'feel, to make responsibilities more clear and design more easy and straightforward.
The skin would define general appearances appliable to any widget, whereas the look'n'feel would bind specific skins to specific states.
I understand this is a much more complicated topic than the layouting, so I'm more leaving this as an inspiration if you plan to refactor this part of the library any soon.
So... here they are. The two only frustrations I've encountered from an end-user point of view. The rest is really great
I am currently using your library for a project of flexible and networked RPG-oriented game engine, which, thanks to libraries like CEGUI is going quite well.
So first of all let me thank you for your great work ! I'll post a video of my project soon, I promise.
It's been more than I year that I have been sporadically using CEGUI, designing layouts, reading your updates about where you're headed, and I'm starting to get a view of the two only points where I feel CEGUI lacks something. I think these two points are the only thing needed for CEGUI to be considered complete and more than anything, easy to use. Everything else (like the tools) would be a bonus.
These two points are :
- Automatic layouting as a core feature and not as a particular type of window. Absolute positioning (be it ratio-based or pixel-based) should be possible but would be rarely used.
When I say layouting, I'm talking about positionning but also automatic shrinking and expanding.
To illustrate this first point, the thing to ask yourself is : what do you do when you design an interface mockup on paper. You divide the screen rectangles into sub rectangles, and then put constraints on them, depending on what you want to fit inside them. You very rarely care in the exact position of a widget : it generally just fit as a content in a subdivision you defined, with given margins.
Designing a GUI layout in code should feel exactly like this process. I will create a window and then divide it vertically. The subdivisions themselve could have minimum or maximum size constraints. And they should always shrink and expand, in the limit defined by these constraints, to their contents.
The hassle associated to writing any layout would be vastly diminished, and the result would be much more flexible and scalable. The absolute positioning system would still be usable.
I think the current approach of a separate LayoutContainer wouldn't allow this because the system needs to recurse through the whole hierarchy to play nicely, whereas a separate LayoutContainer can't recurse.
If you think the idea is worth any value I would gladly make a more detailed proposal, maybe even a patch ? I don't think the amount of coding involved is enormous, but I think I'll look into it by myself.
Thinking about it, since I need such a system for my project I may even write a patch anyway and see what it's worth
The second point where CEGUI has been giving me headaches is the skinning :
- An easy and straightforward skining system
I think the current system has reached a point of over-flexibility, where you can basically do anything you want in a Look'n'Feel definition, but the cost associated with doing anything is way is way too high, and the responsibilities are interleaved in a confused and confusing manner.
Skining should really be just this : the visual appearance of a window/widget. Skinning and logic should not be mixed, so you could change a skin on the fly on any widget at any time.
A skin should really just be defined by this :
- Top, bottom, left, right borders images
- All four angles images
- A filler image
- A global image
- A font, size, color
And that's it. Defining the look of a widget should take you from 3 to ~10 lines of text, and involve nothing else than the appearance of a window at a given state.
It should be appliable to any widget, whatever the type of this widget : I shouldn't care whether the widget will be a pushbutton or a statictext or whatever when writing a skin : it should be reusable accross many different types.
A skin is not linked to any functional definition. It's not linked to a particular kind of widget. It can be applied to ANY widget.
The current skinning systems contains many other things which I don't think should be part of a skinning system.
- Layouting should be part of layouts, not skin. The current system allows layouting in the look'n'feel : the current framewindow is one widget, whereas it should be really three widgets assembled in a layout, and accessible from code logic.
- The logic between switching different states should not be part of the skin. For example, if a button has three states, which are linked to three different skin (button_normal, button_hover, and button_down), these should be defined separately in a look'n'feel definition.
So, in the end, I guess a Skin definition should be factored out from the current Look'n'feel, to make responsibilities more clear and design more easy and straightforward.
The skin would define general appearances appliable to any widget, whereas the look'n'feel would bind specific skins to specific states.
I understand this is a much more complicated topic than the layouting, so I'm more leaving this as an inspiration if you plan to refactor this part of the library any soon.
So... here they are. The two only frustrations I've encountered from an end-user point of view. The rest is really great