[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [pygame] Minimal GUI support



Awesome! I've been looking around for something like this (cuz looking 
through the code for the solarwolf menu buttons scares me). Have a nice 
day.

--Adrian

On 2002.01.25 11:05 Magnus Lie Hetland wrote:
> I've been thinking about some small supporting tool for writing
> GUI-like code in PyGame -- especially adding "widgets" to plain PyGame
> applications (e.g. games), such as the buttons in SolarWolf etc.
> 
> What I came up with was the FocusGroup (pardon the pun ;)
> 
> Basically, it's a Group (I inherited RenderUpdates; perhaps I should
> inherit
> Group instead, and use it as a mixin?) which can manage links between
> its
> members, where each link has a test connected to it. This test is used
> to see
> whether a specific event warrants a focus change along that link. The
> elements
> should be sprites which implement the methods focus(), blur() and
> handle(). The
> code is quite simple (and I'm sure there is plenty of room for
> improvement):
> 
> ------ begin focusgroup.py ------
> 
> mport pygame.sprite
> 
> class FocusAdapter:
>     def focus(self): pass
>     def blur(self): pass
> 
> class FocusGroup(pygame.sprite.RenderUpdates):
>     def __init__(self, *args, **kwds):
>         pygame.sprite.RenderUpdates.__init__(self, *args, **kwds)
>         self._links = []
>         self._current_focus = FocusAdapter()
>     def handle(self, event):
>         for sprite1, sprite2, test in self._links:
>             if sprite1 is self._current_focus and test(event):
>                 self.focus(sprite2)
>                 break
>         else:
>             return self._current_focus.handle(event)
>         return 1
>     def focus(self, sprite):
>         self._current_focus.blur()
>         self._current_focus = sprite
>         sprite.focus()
>     def blur(self):
>         for sprite in self.sprites:
>             sprite.blur()
>     def link(self, sprite1, sprite2, test):
>         self._links.append((sprite1, sprite2, test))
>     def remove(self, sprite):
>         self._links = [x for x in self._links if x[1] is not sprite]
>         pygame.sprite.RenderUpdates.remove(self, sprite)
> 
> ------- end focusgroup.py -------
> 
> Assuming the existence of some Sprites called quit_button and
> next_button, one could use the group like this:
> 
> def up_test(event):
>     return event.type == KEYDOWN and event.key in [K_UP, K_TAB]
> 
> def down_test(event):
>     return event.type == KEYDOWN and event.key in [K_DOWN, K_TAB]
> 
> buttons = FocusGroup([quit_button, next_button])
> buttons.link(next_button, quit_button, down_test)
> buttons.link(quit_button, next_button, up_test)
> 
> With this setup, only the button currently in focus would receive
> events through the focus group. This makes it possible to make rather
> complex widget layouts that one can navigate with arrow keys, tab,
> etc. (I guess I was inspired by the unpredictable behaviour of DVD
> menus when I thought of the graph solution ;)
> 
> In the event loop one would do something like this:
> 
>   if buttons.handle(event):
>       # ... do something
>   elif ...
>       ...
> 
> I was thinking of submitting it (perhaps with a more complete example)
> to the code repository, but wanted some feedback on it first... Is it
> really useful?
> 
> --
> Magnus Lie Hetland                                  The Anygui Project
> http://hetland.org                                  http://anygui.org
> ____________________________________
> pygame mailing list
> pygame-users@seul.org
> http://pygame.seul.org
> 
> 
____________________________________
pygame mailing list
pygame-users@seul.org
http://pygame.seul.org