[gnome-games/applygsoc2009: 35/76] XXX: Make tracker working
- From: Pablo Castellano <pablog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-games/applygsoc2009: 35/76] XXX: Make tracker working
- Date: Mon, 6 Sep 2010 02:50:09 +0000 (UTC)
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]