[gnome-games/sudoku-tube] Make tracker working
- From: Zhang Sen <zhangsen src gnome org>
- To: svn-commits-list gnome org
- Subject: [gnome-games/sudoku-tube] Make tracker working
- Date: Sun, 12 Jul 2009 13:29:56 +0000 (UTC)
commit b14df4da6e75ab35bbd6391b79c07c37e60a5d92
Author: Zhang Sen <zh jesse gmail com>
Date: Sun Jul 12 21:11:25 2009 +0800
Make tracker working
* Again undo/redo is not working
* Don't understand what trackers_for_point() is for
gnome-sudoku/src/lib/gsudoku.py | 127 ++++-------------------------------
gnome-sudoku/src/lib/main.py | 2 +-
gnome-sudoku/src/lib/tracker_box.py | 103 ++++++++++++++++++++++++----
3 files changed, 104 insertions(+), 128 deletions(-)
---
diff --git a/gnome-sudoku/src/lib/gsudoku.py b/gnome-sudoku/src/lib/gsudoku.py
index b1c8084..919f89c 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
@@ -9,20 +8,6 @@ import colors
import number_box
import sudoku
-TRACKER_COLORS = [
- # Use tango colors recommended here:
- # http://tango.freedesktop.org/Tango_Icon_Theme_Guidelines
- tuple([x / 255.0 for x in cols]) for cols in
- [(32, 74, 135), # Sky Blue 3
- (78, 154, 6), # Chameleon 3
- (206, 92, 0), # Orange 3
- (143, 89, 2), # Chocolate 3
- (92, 53, 102), # Plum 3
- (85, 87, 83), # Aluminium 5
- (196, 160, 0), # Butter 3
- ]
- ]
-
def gtkcolor_to_rgb (color):
return (color.red / float(2**16),
color.green / float(2**16),
@@ -105,6 +90,9 @@ class SudokuNumberGrid (gtk.AspectFrame):
def set_readonly_appearance(self, x, y, flag):
self.__entries__[(x, y)].set_read_only(flag)
+ def set_color(self, x, y, color):
+ self.__entries__[(x, y)].set_color(color)
+
def set_focus(self, x, y):
self.table.set_focus_child(self.__entries__[x, y])
@@ -160,8 +148,13 @@ class ParallelDict (dict):
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)
@@ -197,6 +190,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:
@@ -212,7 +206,10 @@ class SudokuView(SudokuNumberGrid, gobject.GObject):
self.__entries__[(x, y)].set_notes((top_note, bottom_note))
def _number_changed_cb(self, widget, 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):
self._model.set_notes(widget.x, widget.y, top_note, bottom_note)
@@ -320,7 +317,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)
@@ -411,8 +407,6 @@ class SudokuModel:
self.auto_fills = 0
self.hints = 0
self.impossible_hints = 0
- self.trackers = {}
- self.__trackers_tracking__ = {}
self._blank_grid()
self._setup_grid(grid, group_size)
@@ -517,45 +511,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, trackers = []):
- """Add value val at position x, y.
-
- If tracker is True, we track it with tracker ID tracker.
-
- Otherwise, we use any currently tracking trackers to track our addition.
-
- Providing the tracker arg is mostly useful for e.g. undo/redo
- or removed items.
-
- To specify NO trackers, use trackers = [-1]
- """
- # Add the value to the UI to display
- self.set_value(x, y, val)
- if self.doing_initial_setup:
- self.set_readonly_appearance(x, y, True)
- # Handle any trackers.
- if trackers:
- # Explicitly specified tracker
- for tracker in trackers:
- if tracker == -1:
- pass
- self.__entries__[(x, y)].set_color(self.get_tracker_color(tracker))
- self.trackers[tracker].append((x, y, val))
- elif True in self.__trackers_tracking__.values():
- for k, v in self.__trackers_tracking__.items():
- if v:
- self.__entries__[(x, y)].set_color(self.get_tracker_color(k))
- self.trackers[k].append((x, y, val))
- # Add value to our underlying sudoku grid -- this will raise
- # an error if the value is out of bounds with the current
- # rules.
- try:
- self.grid.add(x, y, val, True)
- except sudoku.ConflictError, err:
- self._complain_conflicts(err.x, err.y, err.value)
- # Draw our entry
- self.__entries__[(x, y)].queue_draw()
-
def remove (self, x, y, do_removal = False):
"""Remove x, y from our visible grid.
@@ -606,14 +561,6 @@ class SudokuModel:
self.__entries__[(x, y)].set_impossible(False)
self.impossibilities = implications
- 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 _trackers_for_point(self, x, y, val = None):
if val:
# if we have a value we can do this a simpler way...
@@ -627,52 +574,6 @@ class SudokuModel:
self.trackers.items())
return [t[0] for t in track_for_point]
- def get_tracker_color (self, identifier):
- if len(TRACKER_COLORS)>identifier:
- return TRACKER_COLORS[identifier]
- else:
- random_color = TRACKER_COLORS[0]
- while random_color in 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)
- TRACKER_COLORS.append(random_color)
- return self.get_tracker_color(identifier)
-
- 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."""
- ret = []
- while self.trackers[identifier]:
- x, y, v = self.trackers[identifier][0]
- ret.append((x, y, v, self._trackers_for_point(x, y, v)))
- self.remove(x, y)
- if self.grid and self.grid._get_(x, y):
- self.grid.remove(x, y)
- return ret
-
- def delete_except_for_tracker (self, identifier):
- tracks = self.trackers[identifier]
- removed = []
- for x in range(self.group_size):
- for y in range(self.group_size):
- val = self.grid._get_(x, y)
- if (val
- and (x, y, val) not in tracks
- and not self.grid.virgin._get_(x, y)
- ):
- removed.append((x, y, val, self._trackers_for_point(x, y, val)))
- self.remove(x, y)
- if self.grid and self.grid._get_(x, y):
- self.grid.remove(x, y)
-
- return removed
-
def add_tracker (self, x, y, tracker, val = None):
self.__entries__[(x, y)].set_color(self.get_tracker_color(tracker))
if not val:
diff --git a/gnome-sudoku/src/lib/main.py b/gnome-sudoku/src/lib/main.py
index e4680bd..99d721d 100644
--- a/gnome-sudoku/src/lib/main.py
+++ b/gnome-sudoku/src/lib/main.py
@@ -196,7 +196,7 @@ class UI (gconf_wrapper.GConfWrapper):
self._main_grid_vew.connect('puzzle-finished', self.you_win_callback)
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.hide()
tracker_ui_container.pack_start(self.tracker_ui)
diff --git a/gnome-sudoku/src/lib/tracker_box.py b/gnome-sudoku/src/lib/tracker_box.py
index d81c484..2e0e712 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
@@ -35,7 +36,7 @@ class TrackerBox (gtk.VBox):
self.builder = gtk.Builder()
self.builder.add_from_file(os.path.join(defaults.UI_DIR,
'tracker.ui'))
- self.main_ui = main_ui
+ self._tracker_model = TrackerModel(main_ui)
vbox = self.builder.get_object('vbox1')
vbox.unparent()
self.pack_start(vbox, expand = True, fill = True)
@@ -88,10 +89,10 @@ class TrackerBox (gtk.VBox):
self.tracker_actions.set_sensitive(False)
def add_tracker (self):
- tracker_id = self.main_ui.gsd.create_tracker()
+ tracker_id = self._tracker_model.create_tracker()
pixbuf = self._pixbuf_transform_color(
STOCK_PIXBUFS['tracks'],
- self.main_ui.gsd.get_tracker_color(tracker_id),
+ self._tracker_model.get_tracker_color(tracker_id),
)
# select our new tracker
self.tracker_tree.get_selection().select_iter(
@@ -132,7 +133,7 @@ class TrackerBox (gtk.VBox):
for row in self.tracker_model:
tid = row[0]
if tid != -1: # -1 == no tracker
- self.main_ui.gsd.toggle_tracker(tid, tid == selected_tracker_id)
+ self._tracker_model.toggle_tracker(tid, tid == selected_tracker_id)
self.tracker_actions.set_sensitive(selected_tracker_id != -1)
def _clear_cb (self, action):
@@ -149,15 +150,89 @@ class TrackerBox (gtk.VBox):
self._tracker_keep_tracks(selected_tracker_id)
def _tracker_delete_tracks (self, tracker_id):
- clearer = Undo.UndoableObject(
- lambda *args: self.main_ui.cleared.append(self.main_ui.gsd.delete_by_tracker(tracker_id)),
- lambda *args: [self.main_ui.gsd.add_value(*entry) for entry in self.main_ui.cleared.pop()],
- self.main_ui.history)
- clearer.perform()
+ self._tracker_model.delete_by_tracker(tracker_id)
def _tracker_keep_tracks (self, tracker_id):
- clearer = Undo.UndoableObject(
- lambda *args: self.main_ui.cleared.append(self.main_ui.gsd.delete_except_for_tracker(tracker_id)),
- lambda *args: [self.main_ui.gsd.add_value(*entry) for entry in self.main_ui.cleared.pop()],
- self.main_ui.history)
- clearer.perform()
+ self._tracker_model.delete_except_for_tracker(tracker_id)
+
+
+class TrackerModel:
+ """The 'model' that really perform the change on the SudokuView, e.g. set
+ the color"""
+
+ TRACKER_COLORS = [
+ # Use tango colors recommended here:
+ # http://tango.freedesktop.org/Tango_Icon_Theme_Guidelines
+ tuple([x / 255.0 for x in cols]) for cols in
+ [(32, 74, 135), # Sky Blue 3
+ (78, 154, 6), # Chameleon 3
+ (206, 92, 0), # Orange 3
+ (143, 89, 2), # Chocolate 3
+ (92, 53, 102), # Plum 3
+ (85, 87, 83), # Aluminium 5
+ (196, 160, 0), # Butter 3
+ ]
+ ]
+
+ 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)
+
+ def delete_except_for_tracker(self, identifier):
+ for tracker_id in self._trackers:
+ if not identifier == tracker_id:
+ self.delete_by_tracker(tracker_id)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]