# HG changeset patch # User Jeremy Thurgood # Date 1282995044 -7200 # Node ID 3476e8f3b100d9dc14bd5531f0d6b79ed5400300 # Parent 0630a37cb371bda5ba10bcb9b123c713445c2948 Fixed mouse and cursor handling. diff -r 0630a37cb371 -r 3476e8f3b100 gamelib/cursor.py --- a/gamelib/cursor.py Sat Aug 28 13:10:55 2010 +0200 +++ b/gamelib/cursor.py Sat Aug 28 13:30:44 2010 +0200 @@ -57,11 +57,11 @@ """Mix-in widget to ensure that mouse_move is propogated to parents""" cursor = HAND + _cursor_group = RenderUpdates() + _loaded_cursor = None def __init__(self, screen, *args, **kwargs): Widget.__init__(self, *args, **kwargs) - self._cursor_group = RenderUpdates() - self._loaded_cursor = None self.screen = screen def enter_screen(self): @@ -70,24 +70,13 @@ def leave_screen(self): pygame.mouse.set_visible(1) - def draw_all(self, _surface): - Widget.draw_all(self, _surface) - item = self.screen.state.tool - if item is None: - self.set_cursor(HAND) - else: - self.set_cursor(item.CURSOR) - surface = self.get_root().surface - if self.cursor != self._loaded_cursor: - self._loaded_cursor = self.cursor - if self.cursor is None: - pygame.mouse.set_visible(1) - self._cursor_group.empty() - else: - pygame.mouse.set_visible(0) - self.cursor.load() - self._cursor_group.empty() - self._cursor_group.add(self.cursor) + def draw_all(self, surface): + Widget.draw_all(self, surface) + self.draw_cursor(self.get_root().surface) + + def draw_cursor(self, surface): + self.set_cursor(self.screen.state.tool) + self.cursor.set_highlight(self.cursor_highlight()) if self.cursor is not None: self._cursor_group.update() self._cursor_group.draw(surface) @@ -95,8 +84,27 @@ def mouse_delta(self, event): self.invalidate() - def set_cursor(self, cursor): - CursorWidget.cursor = cursor + @classmethod + def set_cursor(cls, item): + if item is None: + cls.cursor = HAND + else: + cls.cursor = item.CURSOR + if cls.cursor != cls._loaded_cursor: + cls._loaded_cursor = cls.cursor + if cls.cursor is None: + pygame.mouse.set_visible(1) + cls._cursor_group.empty() + else: + pygame.mouse.set_visible(0) + cls.cursor.load() + cls._cursor_group.empty() + cls._cursor_group.add(cls.cursor) - def cursor_highlight(self, enable): - self.cursor.set_highlight(enable) + def cursor_highlight(self): + if self.screen.state.highlight_override: + return True + current_thing = self.screen.state.current_thing + if current_thing: + return current_thing.is_interactive() + return False diff -r 0630a37cb371 -r 3476e8f3b100 gamelib/gamescreen.py --- a/gamelib/gamescreen.py Sat Aug 28 13:10:55 2010 +0200 +++ b/gamelib/gamescreen.py Sat Aug 28 13:30:44 2010 +0200 @@ -85,14 +85,15 @@ handle_result(result, self) def mouse_move(self, event): + self.state.highlight_override = False if not self.subwidgets: self._mouse_move(event.pos) def _mouse_move(self, pos): - self.state.mouse_move(pos, self.screen) + self.state.highlight_override = False + self.state.mouse_move(pos) def show_message(self, message, style=None): - self.parent.cursor_highlight(False) # Display the message as a modal dialog MessageDialog(self.screen, message, 60, style=style).present() # queue a redraw to show updated state @@ -108,7 +109,6 @@ self.detail.set_image_rect(Rect(0, 0, w, h)) self.add_centered(self.detail) self.state.do_enter_detail() - self.parent.cursor_highlight(False) def clear_detail(self): """Hide the detail view""" @@ -153,7 +153,8 @@ self._mouse_move(event.pos) def _mouse_move(self, pos): - self.state.mouse_move_detail(self.global_to_local(pos), self.screen) + self.state.highlight_override = False + self.state.mouse_move_detail(self.global_to_local(pos)) def show_message(self, message, style=None): self.parent.show_message(message, style) @@ -227,8 +228,3 @@ def begin_frame(self): if self.running: self.state_widget.animate() - - def mouse_delta(self, event): - CursorWidget.mouse_delta(self, event) - if not self.state_widget.rect.collidepoint(event.pos): - self.cursor_highlight(False) diff -r 0630a37cb371 -r 3476e8f3b100 gamelib/state.py --- a/gamelib/state.py Sat Aug 28 13:10:55 2010 +0200 +++ b/gamelib/state.py Sat Aug 28 13:30:44 2010 +0200 @@ -91,6 +91,9 @@ # scene transion helpers self.do_check = None self.old_pos = None + # current thing + self.current_thing = None + self.highlight_override = False def add_scene(self, scene): self.scenes[scene.name] = scene @@ -112,16 +115,17 @@ def set_current_scene(self, name): old_scene = self.current_scene self.current_scene = self.scenes[name] + self.current_thing = None if old_scene and old_scene != self.current_scene: self.previous_scene = old_scene self.set_do_enter_leave() def set_current_detail(self, name): + self.current_thing = None if name is None: self.current_detail = None else: self.current_detail = self.detail_views[name] - self.current_scene._current_thing = None return self.current_detail.get_detail_size() def add_inventory_item(self, name): @@ -187,12 +191,12 @@ self.do_check = None # Fix descriptions, etc. if self.old_pos: - self.current_scene.mouse_move(self.tool, self.old_pos, screen) + self.current_scene.update_current_thing(self.old_pos) return self.current_scene.enter() raise RuntimeError('invalid do_check value %s' % self.do_check) - def mouse_move(self, pos, screen): - self.current_scene.mouse_move(self.tool, pos, screen) + def mouse_move(self, pos): + self.current_scene.mouse_move(pos) # So we can do sensible things on enter and leave self.old_pos = pos @@ -200,8 +204,8 @@ """Flag that we need to run the enter loop""" self.do_check = constants.LEAVE - def mouse_move_detail(self, pos, screen): - self.current_detail.mouse_move(self.tool, pos, screen) + def mouse_move_detail(self, pos): + self.current_detail.mouse_move(pos) class StatefulGizmo(object): @@ -251,7 +255,6 @@ self._background = get_image(self.FOLDER, self.BACKGROUND) else: self._background = None - self._current_thing = None def add_item(self, item): self.state.add_item(item) @@ -265,7 +268,8 @@ self.leave() def _get_description(self): - text = self._current_thing and self._current_thing.get_description() + text = (self.state.current_thing and + self.state.current_thing.get_description()) if text is None: return None label = BoomLabel(text) @@ -305,8 +309,8 @@ Returns a Result object to provide feedback to the player. """ - if self._current_thing is not None: - return self._current_thing.interact(item) + if self.state.current_thing is not None: + return self.state.current_thing.interact(item) def animate(self): """Animate all the things in the scene. @@ -324,24 +328,23 @@ def leave(self): return None - def mouse_move(self, item, pos, screen): + def update_current_thing(self, pos): + if self.state.current_thing is not None: + if not self.state.current_thing.contains(pos): + self.state.current_thing.leave() + self.state.current_thing = None + for thing in self.things.itervalues(): + if thing.contains(pos): + thing.enter(self.state.tool) + self.state.current_thing = thing + break + + def mouse_move(self, pos): """Call to check whether the cursor has entered / exited a thing. Item may be an item in the list of items or None for the hand. """ - if self._current_thing is not None: - if self._current_thing.contains(pos): - screen.cursor_highlight(self._current_thing.is_interactive()) - return - else: - self._current_thing.leave() - self._current_thing = None - for thing in self.things.itervalues(): - if thing.contains(pos): - thing.enter(item) - self._current_thing = thing - break - screen.cursor_highlight(self._current_thing is not None) + self.update_current_thing(pos) def get_detail_size(self): return self._background.get_size() diff -r 0630a37cb371 -r 3476e8f3b100 gamelib/widgets.py --- a/gamelib/widgets.py Sat Aug 28 13:10:55 2010 +0200 +++ b/gamelib/widgets.py Sat Aug 28 13:30:44 2010 +0200 @@ -49,9 +49,7 @@ self.screen.state_widget.mouse_move(event) def mouse_move(self, event): - pos = self.parent.global_to_local(event.pos) - if self.rect.collidepoint(pos): - self.screen.cursor_highlight(True) + self.screen.state.highlight_override = True class MessageDialog(BoomLabel, CursorWidget): @@ -83,3 +81,6 @@ def mouse_down(self, event): self.dismiss() + + def cursor_highlight(self): + return False