Wednesday, August 26, 2009

SPW does stupid easy GUI screens.

I would like an easy way to write GUI screens for my games... one function to draw the GUI, handle GUI state, and respond to GUI events. No widget graphs, no parent child relationships, no callbacks. It can be done. The code below uses a new GUI module in the SPW library. Many more widgets are required, as at the moment there are only input boxes, buttons, toggles and menu widgets.
import pygame
from spw.gui import GUI, Context

class Window(object):
def draw_gui(self):
text = GUI.input("textbox", (70,10,100,30))
if GUI.toggle("show", (290,10,10,10)):
if GUI.button("quit", "Quit", (190,30,100,100)):
print text
raise SystemExit
options = "new", "open", "save"
action ="file", "FILE", (10,10,50,30), options)
if action is not None: print action

context = Context(pygame.display.set_mode((320,240)))
window = Window()
while True:
e = pygame.event.wait()
if e.type == pygame.QUIT: break
with context as canvas:
GUI.draw(window, canvas, e)


illume said...

Looks super awesome. I'm so using this for pyweek :)

How do you write tests for it? I guess you could write tests by posting events into the event queue, and then seeing what happens.

You have any ideas about testing it?

illume said...

ok, two other questions...

Can I pass in many events at once? Rather than drawing for each event?

Is it possible to get back the changed rectangles? So I could pass them to display.update myself? I guess a draw(no_update) method, which returns the rectangles would do that.

Those two things would make it easier to integrate with other parts of pygame... but probably shouldn't be shown by default. I like how it is at the moment... So you can keep a nice simple clean, less-code way of doing things.

ok, I could just read the source... but I'm a bit excited... hehe.

Florian said...

This is an implementation of immediate mode GUI as was discussed a while ago on pyglet-users. The concept has some limitations (coupled drawing/input processing, no way to reference gui elements outside the drawing path, slow, impossible to apply outside layout constraints etc.), and if you'd wish to overcome them, they make the whole point of immediate mode GUI pretty much moot. It's a nice idea though if all you have is 3-10 elements.

Simon Wittber said...

Florian, I believe I can address those issues.

The point of using an Immediate mode GUI is to _not_ need to reference widgets from various parts of the program. The idea is that different parts of an application can represent their state to a user, allowing it to be changed. You reference the state of your objects, not the widgets. That makes much more sense to me.

Slow? That is pure FUD, and suggest you provide some backup statements if you want to be taken seriously.

Layout is achieved by using a custom LAYOUT event. I'm working on this now.

Simon Wittber said...

Illume: I haven't thought about testing yet, though those features you suggest are good ideas. I'll see what I can do.

Richard Jones said...

It looks like there's some interesting ideas in there but I'm having a little trouble seeing how the various bits are connected. I presume the canvas just invokes draw_gui() on whatever object is passed...

If you'll allow me some comments on the API itself it seems a little convoluted. For example I can't see why there's a "with" statement in there now. Nor what purpose GUI.draw serves, or why it takes the arguments it takes. Perhaps with other examples / doc it'll be clearer :)

Steve Ferg said...

Of possible interest: EasyGui

illume said...


some imgui libraries have layout. As Simon says, you can send a layout event to the controls.

Since it's an OO way of doing it, it should be ok to inspect the gui instance, and change things in there if you want.

It shouldn't be slow if it does dirty rectangle drawing. There's also no reason you can't batch things for renderers that require batches for reasonable speed.

This screen shot shows a very complex gui which uses an imgui system:
I think that is proof that imguis can be useful, and performant in complex situations.


Simon Wittber said...

BTW, Unity3D is my daily tool for work, and it is where the inspiration for the SPW implementation came from. Apart from the other need features, it is a very productive way to build GUI screens.

Popular Posts