Tonight we attempt to design a GUI system from scratch. Huzzah.
one plus one
Shared publicly•View activity
- Decide what you want at the end first. Not how it'll work, not what paradigm it'll follow. Literally what it will look like, how will it animate and what ways can it be used (mouse, pad, keyboard, scripted), how do you transition from one screen to another, what about polyps, fixed on screen elements etc. Then work back from that to figure out what data would be needed to construct it. Once you have both these ends the code is simpler to write!Feb 6, 2012
- Haha autocorrect is awesome polyps == popups! :)Feb 6, 2012
- Tonight we do the washing up and clean up after a toddler who has copiously wet the bed. Your Tonight May Vary.Feb 6, 2012
- Hah, I'd just gone searching to try to figure out what you meant! Sound advice, thank you.
Unsurprisingly, this is for Pioneer. I know visually what I want, and its basically what jQuery gives you out of the box - nice swishy transitions, zooms, etc. I think the model is appropriate since we want to expose some parts of this to scripts, but even in core it'd be wonderful to just say "slide this widget onto the screen and once its there, call this method".
In the long-term I'm intending to move Pioneer away from its 800x600 virtual screen, mostly because it looks like shit on a really high-res widescreen monitor. So my intention is that positioning will be done as 0.0-1.0 in x, 0.0-1.0 in y, measured against a chosen container edge. Scaling by default will be aspect-aware, so I can say that a particular image (quad) should use 10% of the horizontal width and its height will do the right thing.
I'm pretty sure I want a fluid layout, where widgets ask for a minimum/ideal/maximum amount of space and are then handed out an amount depending on the layout strategy of the container they're in. This is not so different to what we have now, but we don't use it in a lot of places. I want fixed position to be used very very sparingly, mostly where precise positioning is required, like control panel buttons.
Scrollbars should be automatic at the container level. If scrolling is enabled for a container then it will give out the maximum possible width/height to each component (based on its requested dimensions).
I like the model Unity uses for its UI where each widget has a corresponding style component. This also gives a convenient place for transitions to hook - they simply modify styles. To do positoning or zooming-type animations I think I don't want to try to modify the widget's metrics, but rather apply a transform at draw time.
I'm still not sure how font metrics feed into widget metrics. I've been assuming for a while that I need a way for a widget to say it wants a height of N lines of text, but whenever I try to think of a clear example I can't. Perhaps I don't care - perhaps it just needs to say "I'll take all of the vertical space you can give me, and please scroll me if I blow it". Though I can see that text layout needs to know whether it should prioritise width over height or vice-versa when doing wrapping.
I've done a good amount of research and experimentation with various GUI systems, both for Pioneer itself (Rocket, GWEN, Guichan, etc) and elsewhere (GTK+, jQuery, Zune, etc). They all have things I like and don't like, which is why I think this has gone on so long.
So basically I think I want to do the lightest and most obvious design possible and see what falls out. That's proving a little more painful than I'd like because Pioneer's GUI has way too much global state which has to be fixed first. It will happen though - I'm quite determined :)Feb 6, 2012
- After some hacking and thinking, I don't see how a transition that modifies size can not modify the metrics (or at least something that looks like the metrics to outsiders), as transitions need force a relayout. Otherwise you get a nice sliding effect that leaves a hole in the layout, which is kind of pointless.Feb 6, 2012
- Oh another thing to consider, which popped up because I'm currently coding it, is whether or not your GUI window/tab/popup/etc will be composited to a a texture or fully rendered per frame.
I'm just in the process of porting a UI from one framework to another and am having to composite each window so that we'r not rendering thousands of characters of text each frame.Feb 6, 2012
- Oh yes, I want render-to-texture and compositing, for two reasons. One to limit the amount of redraw that needs to be done (a simple "this widget is dirty" flag), and then so we can have nice shader effects over the UI. Fortunately doing compositing isn't really an architectural change, so I don't need to think about it too much yet.Feb 6, 2012