[gnome-games/sudoku-tube] Let SudokuView directly access tracker stuff
- From: Zhang Sen <zhangsen src gnome org>
- To: svn-commits-list gnome org
- Subject: [gnome-games/sudoku-tube] Let SudokuView directly access tracker stuff
- Date: Fri, 24 Jul 2009 03:00:00 +0000 (UTC)
commit f0075eea3d39dcf271dd5c1f4f682f793cb288e5
Author: Zhang Sen <zh jesse gmail com>
Date: Fri Jul 24 07:47:27 2009 +0800
Let SudokuView directly access tracker stuff
gnome-sudoku/src/lib/main.py | 10 ++--
gnome-sudoku/src/lib/number_box.py | 6 --
gnome-sudoku/src/lib/tracker_box.py | 104 ++--------------------------
gnome-sudoku/src/lib/view.py | 134 ++++++++++++++++++++++++++++++++---
4 files changed, 133 insertions(+), 121 deletions(-)
---
diff --git a/gnome-sudoku/src/lib/main.py b/gnome-sudoku/src/lib/main.py
index 54d1b16..2a3101c 100644
--- a/gnome-sudoku/src/lib/main.py
+++ b/gnome-sudoku/src/lib/main.py
@@ -233,9 +233,9 @@ 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 = tracker_box.Tracker(self._main_grid_vew)
- self._tracker.hide()
- tracker_ui_container.pack_start(self._tracker.get_view())
+ self._tracker_ui = tracker_box.TrackerBox(self._main_grid_vew)
+ self._tracker_ui.hide()
+ tracker_ui_container.pack_start(self._tracker_ui)
self._setup_side_view()
side_grid_container.add(self._side_grid_vew)
@@ -514,9 +514,9 @@ class UI (gconf_wrapper.GConfWrapper):
def tracker_toggle_cb (self, widg):
if widg.get_active():
- self._tracker.show()
+ self._tracker_ui.show()
else:
- self._tracker.hide()
+ self._tracker_ui.hide()
def toggle_toolbar_cb (self, widg):
if widg.get_active():
diff --git a/gnome-sudoku/src/lib/number_box.py b/gnome-sudoku/src/lib/number_box.py
index fabcb11..7d9ad81 100644
--- a/gnome-sudoku/src/lib/number_box.py
+++ b/gnome-sudoku/src/lib/number_box.py
@@ -531,12 +531,6 @@ class SudokuNumberBox (_NumberBox):
def unset_color (self):
self.set_color(None)
- def set_error_highlight (self, val):
- if val:
- self.set_text_color((1.0, 0, 0))
- else:
- self.set_text_color(self.normal_color)
-
def set_read_only (self, val):
self.read_only = val
if not hasattr(self, 'bold_font'):
diff --git a/gnome-sudoku/src/lib/tracker_box.py b/gnome-sudoku/src/lib/tracker_box.py
index 8f512ff..882064d 100644
--- a/gnome-sudoku/src/lib/tracker_box.py
+++ b/gnome-sudoku/src/lib/tracker_box.py
@@ -31,38 +31,6 @@ def _add_tracker_stock_icon():
_add_tracker_stock_icon()
-TRACKER_COLORS = [
- # Use tango colors recommended here:
- # http://tango.freedesktop.org/Tango_Icon_Theme_Guidelines
- tuple([c / 255.0 for c 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 _get_tracker_color(identifier):
- try:
- return TRACKER_COLORS[identifier]
- except IndexError:
- new_color = _generate_new_color()
- TRACKER_COLORS.append(new_color)
- return _get_tracker_color(identifier)
-
-def _generate_new_color():
- 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)
- return random_color
-
def _pixbuf_transform_color(pixbuf, color):
"""Return new pixbuf with color changed to color"""
pixbuf_str = pixbuf.get_pixels()
@@ -79,13 +47,13 @@ def _pixbuf_transform_color(pixbuf, color):
pixbuf.get_rowstride())
-class _TrackerBox (gtk.VBox):
+class TrackerBox(gtk.VBox):
- def __init__(self, controller):
+ def __init__(self, sudoku_view):
gtk.VBox.__init__(self)
self.builder = gtk.Builder()
self.builder.add_from_file(os.path.join(defaults.UI_DIR, 'tracker.ui'))
- self._view_controller = controller
+ self._view_controller = sudoku_view.get_tracker_controller()
vbox = self.builder.get_object('vbox1')
vbox.unparent()
self.pack_start(vbox, expand = True, fill = True)
@@ -143,9 +111,8 @@ class _TrackerBox (gtk.VBox):
def add_tracker (self):
tracker_id = self._view_controller.create_tracker()
- pixbuf = _pixbuf_transform_color(
- STOCK_PIXBUFS['tracks'],
- _get_tracker_color(tracker_id))
+ color = self._view_controller.get_tracker_color(tracker_id)
+ pixbuf = _pixbuf_transform_color(STOCK_PIXBUFS['tracks'], color)
# select our new tracker
self.tracker_tree.get_selection().select_iter(
self.tracker_model.append([tracker_id,
@@ -186,64 +153,3 @@ class _TrackerBox (gtk.VBox):
mod, itr = self.tracker_tree.get_selection().get_selected()
selected_tracker_id = mod.get_value(itr, 0)
self._view_controller.delete_except_for_tracker(selected_tracker_id)
-
-
-class Tracker:
- """The controller that really perform the changes on the SudokuView, e.g.
- set the color"""
-
- def __init__(self, sudoku_view):
- self._sudoku_view = sudoku_view
- self._trackers = {}
- self.__trackers_tracking__ = {}
- self._tracker_box_view = _TrackerBox(self)
-
- 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 = _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 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)
-
- def get_view(self):
- return self._tracker_box_view
-
- def hide(self):
- self._tracker_box_view.hide()
-
- def show(self):
- self._tracker_box_view.show_all()
diff --git a/gnome-sudoku/src/lib/view.py b/gnome-sudoku/src/lib/view.py
index 2b799ca..8e32715 100644
--- a/gnome-sudoku/src/lib/view.py
+++ b/gnome-sudoku/src/lib/view.py
@@ -8,6 +8,92 @@ import gobject
import colors
import number_box
+
+TRACKER_COLORS = [
+ # Use tango colors recommended here:
+ # http://tango.freedesktop.org/Tango_Icon_Theme_Guidelines
+ tuple([c / 255.0 for c 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 _generate_new_color():
+ 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)
+ return random_color
+
+
+class _Tracker:
+ def __init__(self, sudoku_view):
+ self._trackers = {} # id => [coords]
+ self.__trackers_tracking__ = {} # id => True/False
+ self._tracker_by_coords = {} # coords => id
+ self._sudoku_view = sudoku_view
+
+ def add_to_tracker(self, tracker_id, x, y):
+ self._trackers[tracker_id].append((x, y))
+ self._tracker_by_coords[(x, y)] = tracker_id
+
+ def remove_from_tracker(self, tracker_id, x, y):
+ # TODO how to remove from self._trackers?
+ self._tracker_by_coords[(x, y)] = None
+
+ def get_active_tracker(self):
+ for tracker_id in self.__trackers_tracking__:
+ if self.__trackers_tracking__[tracker_id]:
+ return tracker_id
+ return None
+
+ def get_tracker_by_coord(self, x, y):
+ if (x, y) in self._tracker_by_coords:
+ return self._tracker_by_coords[(x, y)]
+ else:
+ return None
+
+ def create_tracker(self):
+ identifier = 0
+ while identifier in self._trackers:
+ identifier += 1
+ self._trackers[identifier] = []
+ return identifier
+
+ def toggle_tracker(self, identifier, flag):
+ self.__trackers_tracking__[identifier] = flag
+
+ def delete_by_tracker(self, identifier):
+ """Delete all cells tracked by tracker ID identifier."""
+ # copy the list, or there will be infinite-loop
+ entries = self._trackers[identifier]
+ self._trackers[identifier] = []
+ for (x, y) in entries:
+ self._tracker_by_coords[(x, y)] = None
+ 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)
+
+ def get_tracker_color(self, identifier):
+ try:
+ return TRACKER_COLORS[identifier]
+ except IndexError:
+ new_color = _generate_new_color()
+ TRACKER_COLORS.append(new_color)
+ return self.get_tracker_color(identifier)
+
+
def gtkcolor_to_rgb (color):
return (color.red / float(2**16),
color.green / float(2**16),
@@ -85,6 +171,10 @@ class SudokuNumberGrid (gtk.AspectFrame):
e.modify_bg(gtk.STATE_NORMAL, color)
def set_value(self, x, y, value):
+ if not value:
+ tid = self._tracker.get_tracker_by_coord(x, y)
+ if tid is not None:
+ self._tracker.remove_from_tracker(tid, x, y)
self.__entries__[(x, y)].set_value(value)
def set_readonly_appearance(self, x, y, flag):
@@ -108,10 +198,8 @@ class SudokuView(SudokuNumberGrid, gobject.GObject):
# some signals to give notice about change of the View
__gsignals__ = {
# 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))}
+ "puzzle-finished": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ())
+ }
def __init__(self, group_size):
SudokuNumberGrid.__init__(self, group_size)
@@ -128,6 +216,8 @@ class SudokuView(SudokuNumberGrid, gobject.GObject):
e.connect('focus-in-event', self._focus_callback)
e.connect('key-press-event', self._key_press_cb)
+ self._tracker = _Tracker(self)
+
def connect_to_model(self, model):
if not model:
return
@@ -151,18 +241,37 @@ class SudokuView(SudokuNumberGrid, gobject.GObject):
values should be a list of NumberBoxModel"""
for box in values:
x, y, value, conflict = box.x, box.y, box.value, box.conflict
- if value is not None:
+ is_new_value = value is not None
+ if is_new_value:
self.set_value(x, y, value)
- self.emit("view-updated", x, y, value)
- if conflict is not None:
- self._show_conflict(x, y, conflict)
+ self.set_color(x, y,
+ self._refresh_color(x, y, conflict, is_new_value))
+
+ def _refresh_color(self, x, y, conflict, is_new_value):
+ """Set the color according to several rules, conflict/tracker, etc
+ """
+ # conflict
+ if conflict:
+ return (1.0, 0, 0)
+
+ # there is active tracker
+ tid = self._tracker.get_active_tracker()
+ if tid is not None and is_new_value: # old values won't go into tracker
+ self._tracker.add_to_tracker(tid, x, y)
+ return self._tracker.get_tracker_color(tid)
+
+ # the entry was in a tracker; should resume it if its color has been
+ # overridden by conflict
+ tid = self._tracker.get_tracker_by_coord(x, y)
+ if tid is not None:
+ return self._tracker.get_tracker_color(tid)
+
+ # default black color
+ return None
def puzzle_finished_cb(self):
self.emit("puzzle-finished")
- def _show_conflict(self, x, y, flag):
- self.__entries__[(x, y)].set_error_highlight(flag)
-
def update_notes(self, notes_list):
for notes in notes_list:
x, y, top_note, bottom_note = notes
@@ -258,3 +367,6 @@ class SudokuView(SudokuNumberGrid, gobject.GObject):
return opposite_edge[x], y
else:
return None, None
+
+ def get_tracker_controller(self):
+ return self._tracker
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]