[gnome-games/sudoku-tube] Collaborative mode



commit 20f8a4e1c8627db801fdae17075b7e6c50bce70d
Author: Zhang Sen <zh jesse gmail com>
Date:   Sun Aug 16 19:58:29 2009 +0800

    Collaborative mode

 gnome-sudoku/data/contact_selector_dialog.ui |   15 +++++++++++++++
 gnome-sudoku/data/network_game_offer.ui      |    4 +++-
 gnome-sudoku/src/lib/contact_selector.py     |   25 +++++++++++++++++--------
 gnome-sudoku/src/lib/main.py                 |   26 +++++++++++---------------
 gnome-sudoku/src/lib/networking.py           |   25 +++++++++++++------------
 gnome-sudoku/src/lib/tp_tube.py              |    5 +++--
 gnome-sudoku/src/lib/tube_handler.py         |   16 ++++++++++------
 7 files changed, 72 insertions(+), 44 deletions(-)
---
diff --git a/gnome-sudoku/data/contact_selector_dialog.ui b/gnome-sudoku/data/contact_selector_dialog.ui
index 82c164e..dd60cc0 100644
--- a/gnome-sudoku/data/contact_selector_dialog.ui
+++ b/gnome-sudoku/data/contact_selector_dialog.ui
@@ -12,6 +12,21 @@
         <property name="visible">True</property>
         <property name="orientation">vertical</property>
         <property name="spacing">2</property>
+        <child>
+          <object class="GtkCheckButton" id="gamemode_button">
+            <property name="label" translatable="yes">Collaborate</property>
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">False</property>
+            <property name="tooltip_text" translatable="yes">You will be able to see your friend's solutions, vice vesa</property>
+            <property name="draw_indicator">True</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
         <child internal-child="action_area">
           <object class="GtkHButtonBox" id="action_area">
             <property name="visible">True</property>
diff --git a/gnome-sudoku/data/network_game_offer.ui b/gnome-sudoku/data/network_game_offer.ui
index bad125e..c020c59 100644
--- a/gnome-sudoku/data/network_game_offer.ui
+++ b/gnome-sudoku/data/network_game_offer.ui
@@ -49,7 +49,7 @@
                 <property name="label" translatable="yes">gtk-no</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
+                <property name="receives_default">False</property>
                 <property name="use_stock">True</property>
               </object>
               <packing>
@@ -63,6 +63,8 @@
                 <property name="label" translatable="yes">gtk-ok</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="has_default">True</property>
                 <property name="receives_default">True</property>
                 <property name="use_stock">True</property>
               </object>
diff --git a/gnome-sudoku/src/lib/contact_selector.py b/gnome-sudoku/src/lib/contact_selector.py
index e8c8ed6..0c83a44 100644
--- a/gnome-sudoku/src/lib/contact_selector.py
+++ b/gnome-sudoku/src/lib/contact_selector.py
@@ -304,6 +304,7 @@ def contact_selector_run(parent=None):
     ui_file = os.path.join(defaults.UI_DIR, 'contact_selector_dialog.ui')
     builder.add_from_file(ui_file)
     dialog = builder.get_object("contact_selector_dialog")
+    game_mode = builder.get_object("gamemode_button")
 
     if parent:
         dialog.set_transient_for(parent)
@@ -312,18 +313,26 @@ def contact_selector_run(parent=None):
     selector.show()
 
     dialog.vbox.pack_start(selector)
+    dialog.vbox.reorder_child(selector, 0)
     response = dialog.run()
     if response == gtk.RESPONSE_OK:
-        out = selector.dup_selected()
-    dialog.destroy()
+        selected = selector.dup_selected()
+        if selected:
+            conn, handle, contact = selected
+            mode = game_mode.get_active()
+            logger.debug("selected: %s\n"
+                         "  connection: %s\n"
+                         "  handle: %d\n"
+                         "  collaborate :%d" % (
+                    contact.alias, conn.service_name, handle, mode))
+            out = (conn, handle, mode)
+        else:
+            logger.debug("canceled")
+            out = None
 
+    dialog.destroy()
     return out
 
 
 if __name__ == "__main__":
-    out = contact_selector_run()
-    if out:
-        print "selected: %s\nconnection: %s\nhandle: %d" % (
-                out[2].alias, out[0].service_name, out[1])
-    else:
-        print "None selected"
+    print contact_selector_run()
diff --git a/gnome-sudoku/src/lib/main.py b/gnome-sudoku/src/lib/main.py
index 823a1da..c401628 100644
--- a/gnome-sudoku/src/lib/main.py
+++ b/gnome-sudoku/src/lib/main.py
@@ -447,9 +447,7 @@ class SudokuGame(gconf_wrapper.GConfWrapper):
         choice = contact_selector.contact_selector_run(self.w)
         if choice:
             self._is_initiator = True
-            conn, handle, contact = choice
-            logger.debug("selected: %s\n  connection: %s\n  handle: %d" % (
-                    contact.alias, conn.service_name, handle))
+            conn, handle, mode = choice
 
             puzzle = self._generate_new_puzzle()
             if not puzzle:
@@ -458,7 +456,7 @@ class SudokuGame(gconf_wrapper.GConfWrapper):
                 return
 
             self._tube_offer = tp_tube.TubeOffer(
-                    conn, handle, self._tube_service, puzzle)
+                    conn, handle, self._tube_service, puzzle, mode)
 
             connecting_label = gtk.Label(_("Connecting..."))
             self._wait_dialog = gtk.Dialog("Sending request...",
@@ -471,14 +469,12 @@ class SudokuGame(gconf_wrapper.GConfWrapper):
             self._wait_dialog.connect("response", self._wait_dialog_response_cb)
 
             self._tube_offer.connect("offer-succeeded",
-                    self._tube_offered_cb, puzzle)
+                    self._tube_offered_cb, puzzle, mode)
             self._tube_offer.connect("offer-failed", self._offer_fail_cb)
 
             self._tube_offer.execute()
             self._is_waiting_for_response = True
             self._wait_dialog.run()
-        else:
-            logger.debug("None selected")
 
     def _wait_dialog_response_cb(self, dialog, response_id):
         if self._is_waiting_for_response:
@@ -506,12 +502,11 @@ class SudokuGame(gconf_wrapper.GConfWrapper):
         self._wait_dialog.vbox.pack_start(fail_label)
         self._wait_dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)
 
-    def _process_accepted_tube(self, bus, tube, puzzle):
+    def _process_accepted_tube(self, bus, tube, puzzle, mode):
         """User has accepted the tube
         """
 
         self._is_initiator = False
-        self._bus = bus
         self._tube = tube
         self._tube[tp_tube.CHANNEL_INTERFACE].connect_to_signal(
                 'Closed', self._tube_closed_cb)
@@ -522,22 +517,23 @@ class SudokuGame(gconf_wrapper.GConfWrapper):
         self.do_stop()
         self._open_game(game_selector.NewOrSavedGameSelector.NEW_GAME, puzzle)
         self._init_side_view_display(puzzle)
-        self._negotiate_sideview_proxy(self._bus)
+        self._negotiate_sideview_proxy(bus, mode)
 
-    def _tube_offered_cb(self, offer, bus, tube, puzzle):
+    def _tube_offered_cb(self, offer, bus, tube, puzzle, mode):
         """Called when the peer accepts our tube"""
         self._wait_dialog.destroy()
+        self.do_stop()
         self._tube = tube
+
         self._tube[tp_tube.CHANNEL_INTERFACE].connect_to_signal(
                 'Closed', self._tube_closed_cb)
-        self.do_stop()
         self._open_game(game_selector.NewOrSavedGameSelector.NEW_GAME, puzzle)
 
         if not self._negotiate_peer_proxy(bus):
             return
 
         self._init_side_view_display(puzzle)
-        self._negotiate_sideview_proxy(bus)
+        self._negotiate_sideview_proxy(bus, mode)
 
     def _negotiate_peer_proxy(self, bus):
         if self._is_initiator:
@@ -563,7 +559,7 @@ class SudokuGame(gconf_wrapper.GConfWrapper):
                 if val:
                     self._side_grid_vew.set_value(x, y, val)
 
-    def _negotiate_sideview_proxy(self, bus):
+    def _negotiate_sideview_proxy(self, bus, mode):
         receiver_view = self._view_obj_path + "/receiver"
         initiator_view = self._view_obj_path + "/initiator"
         if self._is_initiator:
@@ -572,7 +568,7 @@ class SudokuGame(gconf_wrapper.GConfWrapper):
             our_obj_path, peer_obj_path = receiver_view, initiator_view
 
         # First export our own side-grid-view on dbus
-        proxy_of_side_view = networking.SideViewProxy(bus, our_obj_path,
+        proxy_of_side_view = networking.SideViewProxy(bus, our_obj_path, mode,
                  self._side_grid_vew)
         logger.debug("exported side-view on dbus")
 
diff --git a/gnome-sudoku/src/lib/networking.py b/gnome-sudoku/src/lib/networking.py
index 958cab5..65ca5aa 100644
--- a/gnome-sudoku/src/lib/networking.py
+++ b/gnome-sudoku/src/lib/networking.py
@@ -32,21 +32,26 @@ class SideViewProxy(dbus.service.Object):
     """A dbus object, which exports a sudoku game's side-view on dbus
     """
 
-    def __init__(self, bus, obj_path, sudoku_view):
+    def __init__(self, bus, obj_path, mode, sudoku_view):
         dbus.service.Object.__init__(self, bus, obj_path)
         self._view = sudoku_view
+        self._is_collaborate = mode
 
     @dbus.service.method(dbus_interface=view_interface,
             in_signature="iii", out_signature="")
     def set_value(self, x, y, value):
-        self._view.set_value(x, y, value)
-
-    @dbus.service.method(dbus_interface=view_interface)
-    def set_invisible(self, x, y):
+        if self._is_collaborate:
+            self._view.set_value(x, y, value)
+        # else is competitive mode
+        elif value:
+            self._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))
 
-    @dbus.service.method(dbus_interface=view_interface)
-    def set_empty(self, x, y):
+    def _set_empty(self, x, y):
         self._view.set_value(x, y, 0)
         self._view.set_background_color(x, y, None)
 
@@ -66,12 +71,8 @@ class RemoteViewHandler:
             x, y, value = box.x, box.y, box.value
             if value is None:
                 pass
-            elif value == 0:
-                self._remote_proxy.set_empty(x, y,
-                        reply_handler=self._handle_reply,
-                        error_handler=self._handle_error)
             else:
-                self._remote_proxy.set_invisible(x, y,
+                self._remote_proxy.set_value(x, y, value,
                         reply_handler=self._handle_reply,
                         error_handler=self._handle_error)
 
diff --git a/gnome-sudoku/src/lib/tp_tube.py b/gnome-sudoku/src/lib/tp_tube.py
index edff6b4..57c1e30 100644
--- a/gnome-sudoku/src/lib/tp_tube.py
+++ b/gnome-sudoku/src/lib/tp_tube.py
@@ -30,7 +30,7 @@ class TubeOffer(gobject.GObject):
                 (str,)),
             }
 
-    def __init__(self, conn, handle, tube_service, puzzle):
+    def __init__(self, conn, handle, tube_service, puzzle, game_mode):
         logger.debug("create an offer")
         gobject.GObject.__init__(self)
         self._tube_state = None
@@ -42,6 +42,7 @@ class TubeOffer(gobject.GObject):
         self._handle = handle
         self._tube_service = tube_service
         self._puzzle = puzzle
+        self._game_mode = game_mode
 
     def _tube_state_changed_cb(self, state):
         self._tube_state = state
@@ -93,7 +94,7 @@ class TubeOffer(gobject.GObject):
 
         logger.debug("offering tube")
         try:
-            data = {'puzzle': self._puzzle}
+            data = {'puzzle': self._puzzle, 'game_mode': self._game_mode}
             self._address = self._chan[CHANNEL_TYPE_DBUS_TUBE].Offer(
                     data,
                     SOCKET_ACCESS_CONTROL_CREDENTIALS)
diff --git a/gnome-sudoku/src/lib/tube_handler.py b/gnome-sudoku/src/lib/tube_handler.py
index b734b48..4c5ff69 100644
--- a/gnome-sudoku/src/lib/tube_handler.py
+++ b/gnome-sudoku/src/lib/tube_handler.py
@@ -85,7 +85,8 @@ class TubeHandler(dbus.service.Object):
         if state == TUBE_STATE_OPEN:
             logger.debug("Tube state changed ->open")
             bus = dbus.connection.Connection(self._address)
-            self._tube_received_cb(bus, self._tube_chan, self._puzzle)
+            self._tube_received_cb(bus, self._tube_chan,
+                    self._puzzle, self._game_mode)
         else:
             logger.debug("Tube state changed ->%s" % state)
 
@@ -101,26 +102,29 @@ class TubeHandler(dbus.service.Object):
             dialog.destroy()
 
         try:
-            puzzle = params['puzzle']
-        except KeyError:
-            logger.error("expected parameter missing from %s" % params)
+            puzzle = params["puzzle"]
+            mode = params["game_mode"]
+        except KeyError as err:
+            logger.error("expected parameter missing %s" % err)
             return # do nothing
 
         self._puzzle = str(puzzle)
+        self._game_mode = mode
         alias = _get_contact_alias(self._conn, self._peer_handle)
         logger.debug('got offer: %s' % self._puzzle)
 
         builder = gtk.Builder()
         builder.add_from_file(os.path.join(UI_DIR, 'network_game_offer.ui'))
         dialog = builder.get_object("dialog")
-        dialog.set_default_response(gtk.RESPONSE_OK)
         dialog.connect("response", reply_cb)
 
         name_label = builder.get_object("name_label")
         name_label.set_text(_("%s wants to play with you") % alias)
 
         info = sudoku.SudokuRater(self._puzzle).difficulty()
+        mode_str = _("Collaborative") if mode else _("Competitive")
+        text = info.to_string() + "\n" + _("Game mode: %s") % mode_str
         info_label = builder.get_object("info_label")
-        info_label.set_text(info.to_string())
+        info_label.set_text(text)
 
         dialog.run()



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