/usr/lib/python2.7/dist-packages/chaco/tools/tool_history_mixin.py is in python-chaco 4.5.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | """ Defines the ToolHistoryMixin class.
"""
from traits.api import HasTraits, Instance, Int, List
from enable.api import KeySpec
class ToolHistoryMixin(HasTraits):
""" A mix-in class for tools to maintain a tool state history and to move
backwards and forwards through that history stack.
This mix-in listens for keypressed events; to handle keypresses in a
subclass, call self._history_handle_key(event) to have this mix-in properly
process the event.
"""
# Key to go to the original or start state in the history.
reset_state_key = Instance(KeySpec, args=("Esc",))
# Key to go to the previous state in the history.
prev_state_key = Instance(KeySpec, args=("Left", "control"))
# Key to go to the next state in the history.
next_state_key = Instance(KeySpec, args=("Right", "control"))
# The state stack.
_history = List
# The current index into _history
_history_index = Int
#------------------------------------------------------------------------
# Abstract methods that subclasses must implement to handle keypresses
#------------------------------------------------------------------------
def _next_state_pressed(self):
""" Called when the tool needs to advance to the next state in the
stack.
The **_history_index** will have already been set to the index
corresponding to the next state.
"""
pass
def _prev_state_pressed(self):
""" Called when the tool needs to advance to the previous state in the
stack.
The **_history_index** will have already been set to the index
corresponding to the previous state.
"""
pass
def _reset_state_pressed(self):
""" Called when the tool needs to reset its history.
The history index will have already been set to 0.
"""
pass
#------------------------------------------------------------------------
# Protected methods for subclasses to use
#------------------------------------------------------------------------
def _current_state(self):
""" Returns the current history state.
"""
return self._history[self._history_index]
def _reset_state(self, state):
""" Clears the history stack and sets the first or original state in
the history to *state*.
"""
self._history = [state]
self._history_index = 0
return
def _append_state(self, state, set_index=True):
""" Clears the history after the current **_history_index**, and
appends the given state to the history.
If *set_index* is True, the method sets the **_history_index** to
match the new, truncated history. If it is False, the history index
is unchanged.
"""
new_history = self._history[:self._history_index+1] + [state]
self._history = new_history
if set_index:
self._history_index = len(self._history) - 1
return
def _pop_state(self):
""" Pops the most last state off the history stack.
If the history index points to the end of the stack, then it is
adjusted; otherwise, the index is unaffected. If the stack is empty,
the method raises an IndexError.
Returns the popped state.
"""
if len(self._history) == 0:
raise IndexError("Unable to pop empty history stack.")
if self._history_index == len(self._history) - 1:
self._history_index -= 1
return self._history.pop()
#------------------------------------------------------------------------
# Private methods / event handlers
#------------------------------------------------------------------------
def normal_key_pressed(self, event):
""" Handles a key being pressed, and takes appropriate action if it is
one of the history keys defined for this class.
"""
self._history_handle_key(event)
return
def _history_handle_key(self, event):
if self.reset_state_key is not None and self.reset_state_key.match(event):
self._history_index = 0
self._reset_state_pressed()
event.handled = True
elif self.prev_state_key is not None and self.prev_state_key.match(event):
if self._history_index > 0:
self._history_index -= 1
self._prev_state_pressed()
event.handled = True
elif self.next_state_key is not None and self.next_state_key.match(event):
if self._history_index <= len(self._history) - 2:
self._history_index += 1
self._next_state_pressed()
event.handled = True
else:
return
# EOF
|