[gnome-games/applygsoc2009: 35/76] XXX: Make tracker working



commit 366a8d31f9ee20a2bba99343332317659298644e
Author: Pablo Castellano <pablog src gnome org>
Date:   Thu Aug 26 15:33:35 2010 +0200

    XXX: Make tracker working
    
    * Again undo/redo is not working
    * Don't understand what trackers_for_point() is for

 gnome-sudoku/src/lib/gsudoku.py      |   61 +++++------------------
 gnome-sudoku/src/lib/main.py         |    6 +-
 gnome-sudoku/src/lib/tracker_box.py  |   90 +++++++++++++++++++++++++++++-----
 gnome-sudoku/src/lib/tracker_info.py |   14 -----
 4 files changed, 94 insertions(+), 77 deletions(-)
---
diff --git a/gnome-sudoku/src/lib/gsudoku.py b/gnome-sudoku/src/lib/gsudoku.py
index 44fb99d..4b424a7 100644
--- a/gnome-sudoku/src/lib/gsudoku.py
+++ b/gnome-sudoku/src/lib/gsudoku.py
@@ -1,6 +1,5 @@
 # -*- coding: utf-8 -*-
 import math
-import random
 
 import gtk
 import gobject
@@ -43,6 +42,9 @@ class SudokuNumberGrid (gtk.AspectFrame):
         self.table.set_border_width(2)
         self.show_all()
 
+    def set_color(self, x, y, color):
+        self.__entries__[(x, y)].set_color(color)
+
     def set_parent_for(self, parent):
         for entry in self.__entries__.values():
             entry.set_parent_win(parent)
@@ -73,8 +75,13 @@ class SudokuNumberGrid (gtk.AspectFrame):
 
 class SudokuView (SudokuNumberGrid, gobject.GObject):
 
+    # some signals to give notice about change of the View
     __gsignals__ = {
-        'puzzle-finished':(gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ())}
+            # atm. only used by dancer
+            "puzzle-finished": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
+            # atm. only used by tracker
+            "view-updated": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
+                (int, int, int))}
 
     def __init__(self, group_size):
         SudokuNumberGrid.__init__(self, group_size)
@@ -114,6 +121,7 @@ class SudokuView (SudokuNumberGrid, gobject.GObject):
             x, y = box.x, box.y,
             if box.value is not None:
                 self.set_value(x, y, box.value)
+				self.emit("view-updated", x, y, box.value)
             if box.top_note is not None or box.bottom_note is not None:
                 self._set_notes(x, y, box.top_note, box.bottom_note)
             if box.conflict is not None:
@@ -131,6 +139,10 @@ class SudokuView (SudokuNumberGrid, gobject.GObject):
     def _number_changed_cb(self, widget, new_number):
         print "user input: number", (widget.x, widget.y, new_number)
         self._model.set_value(widget.x, widget.y, new_number)
+		self.update_model(widget.x, widget.y, new_number)
+
+    def update_model(self, x, y, value):
+        self._model.set_value(x, y, value)
 
     def _notes_changed_cb(self, widget, top_note, bottom_note):
         print "user input: notes", (widget.x, widget.y, top_note, bottom_note)
@@ -242,8 +254,6 @@ class SudokuModel:
         self.show_impossible_implications = False
         self.impossible_hints = 0
         self.impossibilities = []
-        self.trackers = {}
-        self.__trackers_tracking__ = {}
         self._setup_grid(grid, group_size)
 
         self._observers = []
@@ -575,49 +585,6 @@ class SudokuModel:
     def _record_conflicts(self, x, y, new_conflicts):
         self.__error_pairs__[(x, y)] = new_conflicts
 
-    def add_value (self, x, y, val, tracker = None):
-        """Add value val at position x, y.
-
-        If tracker is set, we track the value with it.  Otherwise,
-        the current tracker is used(default).
-        """
-        # If the cell already has a value - remove it first.
-        e = self.__entries__[(x, y)]
-        if e.get_value():
-            self.remove(x, y)
-        # Explicitly specified tracker
-        if tracker:
-            # Only add it to the display when it's tracker is visible
-            if tracker == tracker_info.NO_TRACKER or tracker == self.tinfo.showing_tracker:
-                self.__entries__[(x, y)].set_value(val, tracker)
-            # If the tracker isn't showing at the moment - add it as a trace
-            if tracker != tracker_info.NO_TRACKER:
-                self.tinfo.add_trace(x, y, val, tracker)
-        else:
-            # Add a trace(tracked value) if a tracker is selected
-            if self.tinfo.current_tracker != tracker_info.NO_TRACKER:
-                self.tinfo.add_trace(x, y, val)
-            # Remove all tracked values(all traces) for the cell if the player
-            # adds an untracked value
-            else:
-                self.tinfo.remove_trace(x, y)
-            self.__entries__[(x, y)].set_value(val, self.tinfo.current_tracker)
-            if self.doing_initial_setup:
-                self.__entries__[(x, y)].set_read_only(True)
-            else:
-                self.__entries__[(x, y)].recolor(self.tinfo.current_tracker)
-        # Add it to the underlying grid
-        self.grid.add(x, y, val, True)
-        # Highlight any conflicts that the new value creates
-        self.highlight_conflicts(x, y)
-        # Draw our entry
-        self.__entries__[(x, y)].queue_draw()
-        # Update all hints if we need to
-        if self.always_show_hints and not self.doing_initial_setup:
-            self.update_all_hints()
-        if not self.doing_initial_setup:
-            self._mark_impossible_implications(x, y)
-
     def remove (self, x, y, *args):
         """Remove x, y from our visible grid.
 
diff --git a/gnome-sudoku/src/lib/main.py b/gnome-sudoku/src/lib/main.py
index 7aa7e7c..aaa28a5 100644
--- a/gnome-sudoku/src/lib/main.py
+++ b/gnome-sudoku/src/lib/main.py
@@ -111,11 +111,11 @@ class UI (gconf_wrapper.GConfWrapper):
     def _open_game(self, game_type, puzzle):
         """Finally enter the puzzle"""
 		self._puzzle = puzzle
-        if type == game_selector.NewOrSavedGameSelector.NEW_GAME:
+        if game_type == game_selector.NewOrSavedGameSelector.NEW_GAME:
             self._main_model = gsudoku.SudokuModel(puzzle, 9)
             self._main_grid_vew.connect_to_model(self._main_model)
 #            self._main_grid_vew.connect('puzzle-finished', self.you_win_callback)
-        elif type == game_selector.NewOrSavedGameSelector.SAVED_GAME:
+        elif game_type == game_selector.NewOrSavedGameSelector.SAVED_GAME:
             saver.open_game(self, puzzle)
         self._post_open_setup()
 
@@ -194,7 +194,7 @@ class UI (gconf_wrapper.GConfWrapper):
         self._main_grid_vew = gsudoku.SudokuView(group_size=9)
         main_grid_container.pack_start(self._main_grid_vew, padding=6)
 
-        self.tracker_ui = tracker_box.TrackerBox(self)
+        self.tracker_ui = tracker_box.TrackerBox(self._main_grid_vew)
         self.tracker_ui.show_all()
         self.tracker_ui.hide()
         main_area.pack_start(self.tracker_ui, expand=False)
diff --git a/gnome-sudoku/src/lib/tracker_box.py b/gnome-sudoku/src/lib/tracker_box.py
index 5f3345a..39da95e 100644
--- a/gnome-sudoku/src/lib/tracker_box.py
+++ b/gnome-sudoku/src/lib/tracker_box.py
@@ -1,6 +1,7 @@
 # -*- coding: utf-8 -*-
 
 import os.path
+import random
 
 import gtk
 import gobject
@@ -36,7 +37,7 @@ class TrackerBox (gtk.VBox):
         self.builder = gtk.Builder()
         self.builder.set_translation_domain(DOMAIN)
         self.builder.add_from_file(os.path.join(UI_DIR, 'tracker.ui'))
-        self.main_ui = main_ui
+        self._tracker_model = TrackerModel(main_ui)
         self.tinfo = tracker_info.TrackerInfo()
         self.tinfo.ui = self
         self.vb = self.builder.get_object('vbox1')
@@ -174,17 +175,17 @@ class TrackerBox (gtk.VBox):
         else:
             selected_tracker_id = tracker_info.NO_TRACKER
         if selected_tracker_id != tracker_info.NO_TRACKER:
-            self.main_ui.gsd.cover_track()
+            self._tracker_model.cover_track()
         # Remove the underline on the showing_tracker
         self.redraw_row(self.tinfo.showing_tracker)
         self.tinfo.set_tracker(selected_tracker_id)
         self.set_tracker_action_sense(self.tinfo.showing_tracker != tracker_info.NO_TRACKER)
        # Show the tracker
         if selected_tracker_id != tracker_info.NO_TRACKER:
-            self.main_ui.gsd.show_track()
-        self.main_ui.gsd.update_all_notes()
+            self._tracker_model.show_track()
+        self._tracker_model.update_all_notes()
         if self.main_ui.gconf['always_show_hints']:
-            self.main_ui.gsd.update_all_hints()
+            self._tracker_model.update_all_hints()
 
     def remove_tracker_cb (self, action):
         mod, itr = self.tracker_tree.get_selection().get_selected()
@@ -201,8 +202,8 @@ class TrackerBox (gtk.VBox):
     def hide_tracker_cb (self, action):
         hiding_tracker = self.tinfo.showing_tracker
         self.select_tracker(tracker_info.NO_TRACKER)
-        self.main_ui.gsd.cover_track(True)
-        self.main_ui.gsd.update_all_notes()
+        self._tracker_model.cover_track(True)
+        self._tracker_model.update_all_notes()
         self.set_tracker_action_sense(False)
         self.redraw_row(hiding_tracker)
         self.redraw_row(tracker_info.NO_TRACKER)
@@ -234,9 +235,9 @@ class TrackerBox (gtk.VBox):
         cleared_values, cleared_notes = self.do_delete_tracker(True)
         # Apply the values
         for x, y, val, tid in cleared_values:
-            self.main_ui.gsd.set_value(x, y, val)
+            self._tracker_model.set_value(x, y, val)
         # Then apply the notes
-        self.main_ui.gsd.apply_notelist(cleared_notes, True)
+        self._tracker_model.apply_notelist(cleared_notes, True)
         # Store the undo counts
         self.main_ui.cleared.append(len(cleared_values))
         self.main_ui.cleared_notes.append(len(cleared_notes))
@@ -266,10 +267,10 @@ class TrackerBox (gtk.VBox):
             return
         ui_row = [track_row[0], track_row[1], track_row[2]]
         # For the values, store it like (tracker_id, list_of_cleared_values)
-        cleared_values = self.main_ui.gsd.delete_by_tracker()
+        cleared_values = self._tracker_model.delete_by_tracker()
         self.main_ui.cleared.append((self.tinfo.showing_tracker, ui_row, cleared_values))
         # The notes already have tracker info in them, so just store the list
-        cleared_notes = self.main_ui.gsd.clear_notes(tracker = self.tinfo.showing_tracker)
+        cleared_notes = self._tracker_model.clear_notes(tracker = self.tinfo.showing_tracker)
         self.main_ui.cleared_notes.append(cleared_notes)
         # Delete it from tracker_info
         self.hide_tracker_cb(None)
@@ -290,6 +291,69 @@ class TrackerBox (gtk.VBox):
         self.tracker_tree.get_selection().select_iter(self.tracker_model.append(ui_row))
         # Add all the values
         for value in cleared_values:
-            self.main_ui.gsd.add_value(*value)
+            self._tracker_model.add_value(*value)
         # The notes already have tracker info in them, so just store the list
-        self.main_ui.gsd.apply_notelist(self.main_ui.cleared_notes.pop())
+        self._tracker_model.apply_notelist(self.main_ui.cleared_notes.pop())
+
+
+class TrackerModel:
+    """The 'model' that really perform the change on the SudokuView, e.g. set
+    the color"""
+
+    def __init__(self, sudoku_view):
+        self._sudoku_view = sudoku_view
+        self._trackers = {}
+        self.__trackers_tracking__ = {}
+
+        sudoku_view.connect("view-updated", self._view_updated_cb)
+
+    def _view_updated_cb(self, view, x, y, value):
+        if not self._has_active_trackers():
+            return
+        for tracker_id, is_active in self.__trackers_tracking__.items():
+            if is_active:
+                self._add_to_tracker(tracker_id, x, y)
+
+    def _add_to_tracker(self, tracker_id, x, y):
+        color = self.get_tracker_color(tracker_id)
+        self._sudoku_view.set_color(x, y, color)
+        self._trackers[tracker_id].append((x, y))
+
+    def _has_active_trackers(self):
+        return True in self.__trackers_tracking__.values()
+
+    def create_tracker(self, identifier=0):
+        if not identifier:
+            identifier = 0
+        while self._trackers.has_key(identifier):
+            identifier += 1
+        self._trackers[identifier] = []
+        return identifier
+
+    def get_tracker_color(self, identifier):
+        return self.TRACKER_COLORS[identifier]
+        if 0:
+            new_color = self._generate_new_color()
+            self.TRACKER_COLORS.append(new_color)
+            return self.get_tracker_color(identifier)
+
+    def _generate_new_color(self):
+        random_color = self.TRACKER_COLORS[0]
+        while random_color in self.TRACKER_COLORS:
+            # If we have generated all possible colors, this will
+            # enter an infinite loop
+            random_color = (random.randint(0, 100)/100.0,
+                            random.randint(0, 100)/100.0,
+                            random.randint(0, 100)/100.0)
+        return random_color
+
+    def toggle_tracker(self, identifier, value):
+        """Toggle tracking for tracker identified by identifier."""
+        self.__trackers_tracking__[identifier] = value
+
+    def delete_by_tracker(self, identifier):
+        """Delete all cells tracked by tracker ID identifer."""
+        # copy the list, or there will be infinite-loop
+        entries = self._trackers[identifier][:]
+        for (x, y) in entries:
+            self._sudoku_view.update_model(x, y, 0)
diff --git a/gnome-sudoku/src/lib/tracker_info.py b/gnome-sudoku/src/lib/tracker_info.py
index 798c4ac..71ebf33 100644
--- a/gnome-sudoku/src/lib/tracker_info.py
+++ b/gnome-sudoku/src/lib/tracker_info.py
@@ -61,20 +61,6 @@ class TrackerInfo(object):
     def save(self):
         return (self.current_tracker, self.showing_tracker, self.get_trackers())
 
-    def create_tracker (self, tracker_id = 0):
-        '''Create storage for a new tracker
-
-        tracker_id can be passed in to attempt creation of a specific id, but
-        if the tracker_id already exists then the passed number will be
-        incremented until a suitable key can be allocated.
-        '''
-        if not tracker_id:
-            tracker_id = 0
-        while self._tracks.has_key(tracker_id):
-            tracker_id += 1
-        self._tracks[tracker_id] = {}
-        return tracker_id
-
     def get_tracker(self, tracker_id):
         if self._tracks.has_key(tracker_id):
             return self._tracks[tracker_id]



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