Nice - hahakid.
I saw that image from another thread and I was going to post it here. Pretty slick UI!
Also I just stumbled on this today - it is a short text on user interface design from this guy who built a massive multiplayer game from scratch on his own. The rest of his work is pretty incredible but there is some nice stuff he talks about in this text:
Might be good for ideas -
http://www.quelsolaar.com/technology/seduce.htmlAnyway I will chime in on this topic
-- class structure -------------------------------------------
It was pointed out that for others to add new object types, they would have to modify the manager class quite a bit. Instead I should use a uiObject type and then button/slider/checkbox inherits this uiObject.
A base ui object is definitely the way to go.
Personally I would keep functionality quite minimal but give it as much information as possible about things like mouse click location, drag time, drag direction etc etc
You could have some basic functions (boundingBox hit etc) that could be easily overridden for more complex behaviors by people extending the base object.
If the base object is structured simply it will allow for a nice range of gui tools.
I learned this the hard way with Laser Tag - it took me a couple of tries to build a base brush class that would be useful but would not limit the brushes that were extending it.
Any thoughts on the class structure?
I Would have to think about it more but something like:
[guiengine /manager]
[gui settings]
- xmlSettings saver/loader
- (later on) save load entire gui from xml
[gui appearance]
- theme chooser
- type size etc
- overall effects - overall gui transparency etc
[gui communication]
-event callbacks
- (later on) networked events (with networked gui objects)
[gui objects]
- base gui object
- simpler slider
- simple button
- key assignment object (eg letter 'c' does capture)
- (later on) advanced controls
- (later on) networked gui objects
Now that I look of it I am not sure if that is a overall class structure or a wishlist - but I would imagine something like that. I think an important decision would be whether the manager owns the gui objects or whether we create them and then register them with the gui manager class.
-- input events --------------------------------------------------------
We can't inherit the mouse events from testApp, correct? So within each testApp mouseDown etc you would have to put:
guiClass.mouseDown(x,y);
This is one of my biggest frustrations - obviously it would be great to register mouse and keyboard events with the of core - so that you don't have to fill the testApp mousePressed, mouseReleased, key pressed etc with all the relevent gui events.
If you do go this way (I am not sure how you would avoid it at the moment) one thing I like to do with keyPressed is first send the keypress to my gui and then return true or false if the key is mapped to something - that way you can avoid duplicate key press events
testApp:keyPressed(int key){
if( !gui.keyPressed(key) ){
//gui is not using this key -
// put you misc testApp key events here
}
}
-- gui events --------------------------------------------------------
When a user clicks a button, what should the action be? Should a generic function in testApp be called, then use switch statements to do something with that action. What about creating event listeners like in flash for each object & definining our own function?
I think callbacks are the way to go - my gui class for laser tag didn't have callbacks and it was pretty miserable - I had to ask my gui for every setting whether it had changed its value - then if it had I would request its new value. Uggg. But callbacks can be tricky and could make the code quite complicated - I would cede this to someone who knows more on this subject.
-- colours / style sheets ---------------------------------------------
Should each individual button & slider be colour changable, or one general stylesheet gui?
What other properties do I need?
Thats a tough one.
The objects could have abstract properties like strong, normal, highlight, etc that define their importance, mode etc and then the stylesheet could just interpret these with a color - font weight etc.
I would go maybe go with general stylesheets that defines the whole gui and then people can tweak the stylesheet if they want to change the appearance.
For color I would do rgba rather than rgb - as it might be quite useful down the road.
-- typeface --------------------------------------------------------
Should we have a ofTrueTypeFont within the gui manager and then a seperate function to load a font, or pass a ofTrueTypeFont from the testApp by reference?
I have gone for the second option in ofControlGui with this:
void init(ofTrueTypeFont & _type);
However perhaps the first is better
I am not sure - I might imagine you would need to have more than one typeface, especially as OF loads the typeface in at the requested size - so you would need two ofTrueTypeFont objects to have two different sizes of the same typeface.
One thing I have found is that type in gui's can really slow things down especially on laptops with limited graphics hardware. This can be as much as 10-15 fps when drawing a lot of type to the screen. It is so much that in Laser Tag all non dynamic type is actually ofImages and the gui's for some of my other installations have an option to just show the text of the selected control.
-- tabs / panels ---------------------------------------------------
Gui objects should be able to be grouped, then hidden/shown as needed to create multi layout interfaces.
In controlP5 for processing these are Tabs I believe. Andreas mentioned in his code he has Panels.
I can imagine for each object you could set the panel it belongs to:
guiClass.createPanel("panel1", "Layers"); // id, label, size & position etc
button.setPanel("panel1")
Any thoughts on these?
I imagine that could work fine with specifying relative coords to the panel rather than absolute screen coords for each gui. I think that could be a really nice feature and of course collapsable, grouped, all that stuff would be really useful. You could reposition the panels and then their position could be saved to xml so they remember how you had them.
-- xml ---------------------------------------------------
In theory when the new ofXml is out with 0.05, you could build the whole user interface from an xml file, with that file storing a list of all objects, positions & events.
For now I will use xml for a style sheet, with loadStyleFromXml("red.xml") and saveStyleToXml() functions.
Sounds good!
Anyway I don't think I am an expert on this subject at all - so maybe someone else has better advice.
Theo
Any of your thoughts on the above most welcome,
Thanks