[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[pygame] Minimal GUI support
- To: PyGame Users <pygame-users@seul.org>
- Subject: [pygame] Minimal GUI support
- From: Magnus Lie Hetland <magnus@hetland.org>
- Date: Fri, 25 Jan 2002 20:05:11 +0100
- Delivered-To: archiver@seul.org
- Delivered-To: pygame-users-outgoing@seul.org
- Delivered-To: pygame-users@seul.org
- Delivery-Date: Fri, 25 Jan 2002 14:05:13 -0500
- Mail-Followup-To: PyGame Users <pygame-users@seul.org>
- Reply-To: pygame-users@seul.org
- Sender: owner-pygame-users@seul.org
- User-Agent: Mutt/1.2.5i
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