[gnome-games/sudoku-tube] Show the peer's cursor



commit 8ac9d16103003f61032c314d6600913072cf5318
Author: Zhang Sen <zh jesse gmail com>
Date:   Mon Aug 17 22:12:38 2009 +0800

    Show the peer's cursor

 gnome-sudoku/src/lib/main.py       |    8 +++++-
 gnome-sudoku/src/lib/networking.py |   40 ++++++++++++++++++++---------------
 gnome-sudoku/src/lib/number_box.py |    3 ++
 gnome-sudoku/src/lib/view.py       |   33 +++++++++++++++++++++++++++++
 4 files changed, 65 insertions(+), 19 deletions(-)
---
diff --git a/gnome-sudoku/src/lib/main.py b/gnome-sudoku/src/lib/main.py
index 8ff8b38..b60cbc5 100644
--- a/gnome-sudoku/src/lib/main.py
+++ b/gnome-sudoku/src/lib/main.py
@@ -563,6 +563,7 @@ class SudokuGame(gconf_wrapper.GConfWrapper):
         proxy_of_side_view = networking.SideViewProxy(bus, our_obj_path, mode,
                  self._side_grid_vew)
         logger.debug("exported side-view on dbus")
+        self._side_grid_vew.show()
 
         # Then fetch our peer's side-grid-view
         _remote_view_proxy = bus.get_object(object_path=peer_obj_path)
@@ -570,10 +571,12 @@ class SudokuGame(gconf_wrapper.GConfWrapper):
         # we issue command on remote_view_handler, which will communicate with
         # remote_view
         view_handler = networking.RemoteViewHandler(_remote_view_proxy)
+        # FIXME this is ugly, but we need a way to disconnect this callback
+        # when we are disconnected
+        self._view_handler_cb = self._main_grid_vew.connect("focus-changed",
+                lambda view, x, y: view_handler.set_focus(x, y))
         self._main_model.add_observer(view_handler)
 
-        self._side_grid_vew.show()
-
     def _close_current_game(self):
         """Close current running game
 
@@ -614,6 +617,7 @@ class SudokuGame(gconf_wrapper.GConfWrapper):
         self._is_initiator = None
         self._side_grid_vew.hide()
         self._tube = None
+        self._main_grid_vew.disconnect(self._view_handler_cb)
         logger.debug("tube has been closed")
 
     def _stop_network_game(self, *args):
diff --git a/gnome-sudoku/src/lib/networking.py b/gnome-sudoku/src/lib/networking.py
index 65ca5aa..330c048 100644
--- a/gnome-sudoku/src/lib/networking.py
+++ b/gnome-sudoku/src/lib/networking.py
@@ -44,17 +44,14 @@ class SideViewProxy(dbus.service.Object):
             self._view.set_value(x, y, value)
         # else is competitive mode
         elif value:
-            self._set_invisible(x, y)
+            self._view.set_invisible(x, y)
         else:
-            self._set_empty(x, y)
-
-    def _set_invisible(self, x, y):
-        self._view.set_background_color(x, y, (0, 0, 0))
-
-    def _set_empty(self, x, y):
-        self._view.set_value(x, y, 0)
-        self._view.set_background_color(x, y, None)
+            self._view.set_empty(x, y)
 
+    @dbus.service.method(dbus_interface=view_interface,
+            in_signature="ii", out_signature="")
+    def set_focus(self, x, y):
+        self._view.set_focus(x, y)
 
 class RemoteViewHandler:
 
@@ -67,17 +64,26 @@ class RemoteViewHandler:
         self._remote_proxy = remote_proxy
 
     def update(self, changes):
+        def reply_handler():
+            pass
+        def error_handler(error):
+            logger.error('Failed to update the remote view: %s' % error)
+
         for box in changes:
             x, y, value = box.x, box.y, box.value
             if value is None:
                 pass
             else:
                 self._remote_proxy.set_value(x, y, value,
-                        reply_handler=self._handle_reply,
-                        error_handler=self._handle_error)
-
-    def _handle_reply(self):
-        pass
-
-    def _handle_error(self, error):
-        logger.error('Failed to update the remote view: %s' % error)
+                        reply_handler=reply_handler,
+                        error_handler=error_handler)
+
+    def set_focus(self, x, y):
+        def reply_handler():
+            pass
+        def error_handler(error):
+            logger.error('Failed to set_focus: %s' % error)
+
+        self._remote_proxy.set_focus(x, y,
+                reply_handler=reply_handler,
+                error_handler=error_handler)
diff --git a/gnome-sudoku/src/lib/number_box.py b/gnome-sudoku/src/lib/number_box.py
index 7d9ad81..fda7366 100644
--- a/gnome-sudoku/src/lib/number_box.py
+++ b/gnome-sudoku/src/lib/number_box.py
@@ -503,6 +503,9 @@ class _NumberBox (gtk.Widget):
         self.custom_background_color = color
         self.queue_draw()
 
+    def get_background_color(self):
+        return self.custom_background_color
+
     def set_value (self, v):
         self.value = v
         if 0 < v <= self.upper:
diff --git a/gnome-sudoku/src/lib/view.py b/gnome-sudoku/src/lib/view.py
index c2e995c..e4b9387 100644
--- a/gnome-sudoku/src/lib/view.py
+++ b/gnome-sudoku/src/lib/view.py
@@ -3,6 +3,7 @@
 import math
 import random
 
+import gobject
 import gtk
 
 import colors
@@ -233,6 +234,11 @@ class SudokuNumberGrid (gtk.AspectFrame):
 
 class SudokuView(SudokuNumberGrid):
 
+    __gsignals__ = {
+            "focus-changed": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
+                (int, int))
+            }
+
     def __init__(self, group_size, controller=None):
         """User commands take action through controller. The GUI is updated by
         model. So in reality, it's like:
@@ -369,6 +375,7 @@ class SudokuView(SudokuNumberGrid):
         self._notes_model.set_notes(widget.x, widget.y, top_note, bottom_note)
 
     def _focus_callback(self, widget, event):
+        self.emit("focus-changed", widget.x, widget.y)
         if self._do_highlight_cells:
             self._highlight_cells()
 
@@ -447,6 +454,9 @@ class SudokuView(SudokuNumberGrid):
 
 class SudokuSideView(SudokuNumberGrid):
     def __init__(self, group_size):
+        self._focus = None
+        self._focus_bg = None
+
         SudokuNumberGrid.__init__(self, group_size)
         for x in range(self.group_size):
             for y in range(self.group_size):
@@ -457,3 +467,26 @@ class SudokuSideView(SudokuNumberGrid):
             for y in range(self.group_size):
                 self.set_value(x, y, 0)
                 self.set_background_color(x, y, None)
+        self._focus = None
+        self._focus_bg = None
+
+    def set_invisible(self, x, y):
+        self.set_background_color(x, y, (0, 0, 0))
+        if self._focus and (x, y) == (self._focus.x, self._focus.y):
+            self._focus_bg = (0, 0, 0)
+
+    def set_empty(self, x, y):
+        self.set_value(x, y, 0)
+        self.set_background_color(x, y, None)
+
+    def set_focus(self, x, y):
+        # restore previously focused entry
+        if self._focus:
+            self.set_background_color(self._focus.x, self._focus.y,
+                    self._focus_bg)
+        # highlight new focused entry
+        self._focus = self.__entries__[(x, y)]
+        self._focus_bg = self._focus.get_background_color()
+        self.set_background_color(x, y, (0, 1, 0))
+        # this _focus/_focus_bg is not at all elegant, but for now it does what
+        # I need, should come up with a better solution



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