From 5ceda38732c57211d3f38e6cbbd7b8a521a0a9e5 Mon Sep 17 00:00:00 2001 From: Daniel Francis Date: Wed, 03 Oct 2012 00:23:16 +0000 Subject: Start sugarizing; use Gtk3 --- (limited to 'tracker_info.py') diff --git a/tracker_info.py b/tracker_info.py new file mode 100644 index 0000000..798c4ac --- /dev/null +++ b/tracker_info.py @@ -0,0 +1,208 @@ +# -*- coding: utf-8 -*- +#!/usr/bin/python + +import random +import copy + +NO_TRACKER = -1 # Tracker id for untracked values + +class TrackerInfo(object): + '''Tracker state machine(singleton) + + The singleton instance of this class is used to manipulate tracker + selection and tracked values, as well as interrogate tracker colors. + + _tracks - dictionary for tracked values. The tracker id is used as the + key. A tracker is a dictionary that stored tracked values keyed by + its coordinates(x, y). _tracks[tracker_id][(x, y)] == tracked value + + current_tracker - The tracker id for the currently selected tracker + showing_tracker - The tracker id for the tracker that is currently being + viewed. The point to this member is to store off the tracker when + the player switches to "Untracked" so that the last tracker they were + working on stays in view after the switch. + ''' + __single = None + _tracks = {} + _colors = {} + current_tracker = NO_TRACKER + showing_tracker = NO_TRACKER + + def __new__(cls, *args, **kwargs): + '''Overridden to implement as a singleton + ''' + # Check to see if a __single exists already for this class + # Compare class types instead of just looking for None so + # that subclasses will create their own __single objects + if cls != type(cls.__single): + cls.__single = object.__new__(cls, *args, **kwargs) + return cls.__single + + def __init__(self): + # Only initialize the colors once + if self._colors: + return + # Use tango colors recommended here: + # http://tango.freedesktop.org/Tango_Icon_Theme_Guidelines + for tracker_id, cols in enumerate( + [(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 + ]): + self._colors[tracker_id] = tuple([x / 255.0 for x in cols]) + + def load(self, pickle): + self.current_tracker, self.showing_tracker, self._tracks = pickle + + 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] + + def delete_tracker(self, tracker_id): + if self._tracks.has_key(tracker_id): + del self._tracks[tracker_id] + + def reset (self): + ''' Reset the tracker information + ''' + self._tracks = {} + self.current_tracker = NO_TRACKER + self.showing_tracker = NO_TRACKER + + def use_trackers (self, trackers): + self._tracks = trackers + + def get_trackers(self): + return copy.deepcopy(self._tracks) + + def set_tracker(self, tracker_id): + self.current_tracker = tracker_id + if tracker_id != NO_TRACKER: + self.showing_tracker = tracker_id + + def hide_tracker(self): + self.showing_tracker = NO_TRACKER + + def get_tracker_view(self): + return((self.current_tracker, self.showing_tracker)) + + def set_tracker_view(self, tview): + self.current_tracker, self.showing_tracker = tview + + def get_color (self, tracker_id): + # Untracked items don't get specially colored + if tracker_id == NO_TRACKER: + return None + # Create a random color for new trackers that are beyond the defaults + if not self._colors.has_key(tracker_id): + random_color = self._colors[0] + while random_color in self._colors.values(): + # 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) + self._colors[tracker_id] = random_color + return self._colors[tracker_id] + + def get_color_markup(self, tracker_id): + color_tuple = self.get_color (tracker_id) + if not color_tuple: + return None + color_markup = '#' + color_markup += str(hex(int(color_tuple[0]*255))[2:]).zfill(2) + color_markup += str(hex(int(color_tuple[1]*255))[2:]).zfill(2) + color_markup += str(hex(int(color_tuple[2]*255))[2:]).zfill(2) + return color_markup.upper() + + def get_current_color(self): + return self.get_color(self.current_tracker) + + def get_showing_color(self): + return self.get_color(self.showing_tracker) + + def add_trace(self, x, y, value, tracker_id = None): + '''Add a tracked value + + By default(tracker_id set to None) this method adds a value to the + current tracker. tracker_id can be passed in to add it to a specific + tracker. + ''' + if tracker_id == None: + to_tracker = self.current_tracker + else: + to_tracker = tracker_id + # Need a tracker + if to_tracker == NO_TRACKER: + return + # Make sure the dictionary is available for the tracker. + if not self._tracks.has_key(to_tracker): + self._tracks[to_tracker] = {} + # Add it + self._tracks[to_tracker][(x, y)] = value + + def remove_trace(self, x, y, from_tracker = None): + '''Remove a tracked value + + By default(from_tracker set to None) this method removes all tracked + values for a particular cell(x, y coords). from_tracker can be passed + to remove tracked values from a particular tracker only. + ''' + if from_tracker == None: + from_tracks = self._tracks.keys() + else: + from_tracks = [from_tracker] + # Delete them + for tracker in from_tracks: + if self._tracks.has_key(tracker) and self._tracks[tracker].has_key((x, y)): + del self._tracks[tracker][(x, y)] + + def get_trackers_for_cell(self, x, y): + '''Return all trackers for a cell + + This function is used for the undo mechanism. A list in the format + (tracker, value) is returned so that it may later be reinstated with + reset_trackers_for_cell(). + ''' + ret = [] + for tracker, track in self._tracks.items(): + if track.has_key((x, y)): + ret.append((tracker, track[(x, y)])) + return ret + + def reset_trackers_for_cell(self, x, y, old_trackers): + '''Reset all trackers to a previous state for a cell + + This function is used for the undo mechanism. It reinstates the + tracked values the list created by get_trackers_for_cell(). + ''' + # Remove all the current traces + for tracker, track in self._tracks.items(): + if track.has_key((x, y)): + del self._tracks[tracker][(x, y)] + # Add the old ones back + for tracker, value in old_trackers: + self._tracks[tracker][(x, y)] = value + + -- cgit v0.9.1