~ubuntu-branches/ubuntu/utopic/python-chaco/utopic

« back to all changes in this revision

Viewing changes to chaco/tools/pan_tool.py

  • Committer: Package Import Robot
  • Author(s): Andrew Starr-Bochicchio
  • Date: 2014-06-01 17:04:08 UTC
  • mfrom: (7.2.5 sid)
  • Revision ID: package-import@ubuntu.com-20140601170408-m86xvdjd83a4qon0
Tags: 4.4.1-1ubuntu1
* Merge from Debian unstable. Remaining Ubuntu changes:
 - Let the binary-predeb target work on the usr/lib/python* directory
   as we don't have usr/share/pyshared anymore.

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
from numpy import inf
5
5
 
6
6
# Enthought library imports
7
 
from enable.api import BaseTool, Pointer
8
 
from traits.api import Bool, Enum, Float, Tuple
 
7
from enable.api import BaseTool, Pointer, KeySpec
 
8
from traits.api import Bool, Enum, Float, Tuple, Instance
9
9
 
10
10
 
11
11
class PanTool(BaseTool):
29
29
    # constrain_direction to the desired direction.
30
30
    constrain_key = Enum(None, "shift", "control", "alt")
31
31
 
 
32
    # Keys to Pan via keyboard
 
33
    pan_right_key = Instance(KeySpec, args=("Right",))
 
34
    pan_left_key = Instance(KeySpec, args=("Left",))
 
35
    pan_up_key = Instance(KeySpec, args=("Up",))
 
36
    pan_down_key = Instance(KeySpec, args=("Down",))
 
37
 
 
38
    # number of pixels the keys should pan
 
39
    # disabled if 0.0
 
40
    pan_keys_step = Float(0.0)
 
41
 
32
42
    # Constrain the panning to one direction?
33
43
    constrain = Bool(False)
34
44
 
67
77
    # The possible event states of this tool (overrides enable.Interactor).
68
78
    event_state = Enum("normal", "panning")
69
79
 
 
80
    def normal_key_pressed(self, event):
 
81
        """ Handles a key being pressed when the tool is in the 'normal'
 
82
        state.
 
83
        """
 
84
        if self.pan_keys_step == 0.0:
 
85
            return
 
86
        src = self.component.bounds[0]/2, self.component.bounds[1]/2
 
87
        dest = src
 
88
        if self.pan_left_key.match(event):
 
89
            dest = (src[0] - self.pan_keys_step,
 
90
                    src[1])
 
91
        elif self.pan_right_key.match(event):
 
92
            dest = (src[0] + self.pan_keys_step,
 
93
                    src[1])
 
94
        elif self.pan_down_key.match(event):
 
95
            dest = (src[0],
 
96
                    src[1] - self.pan_keys_step)
 
97
        elif self.pan_up_key.match(event):
 
98
            dest = (src[0],
 
99
                    src[1] + self.pan_keys_step)
 
100
        if src != dest:
 
101
            self._original_xy = src
 
102
            event.x = dest[0]
 
103
            event.y = dest[1]
 
104
            self.panning_mouse_move(event)
 
105
        return
70
106
 
71
107
    def normal_left_down(self, event):
72
108
        """ Handles the left mouse button being pressed when the tool is in
136
172
 
137
173
        if self._auto_constrain and self.constrain_direction is None:
138
174
            # Determine the constraint direction
139
 
            if abs(event.x - self._original_xy[0]) > abs(event.y - self._original_xy[1]):
 
175
            x_orig, y_orig = self._original_xy
 
176
            if abs(event.x - x_orig) > abs(event.y - y_orig):
140
177
                self.constrain_direction = "x"
141
178
            else:
142
179
                self.constrain_direction = "y"
143
180
 
144
 
        for direction, bound_name, ndx in [("x","width",0), ("y","height",1)]:
 
181
        direction_info = [("x", "width", 0), ("y", "height", 1)]
 
182
        for direction, bound_name, index in direction_info:
145
183
            if not self.constrain or self.constrain_direction == direction:
146
184
                mapper = getattr(plot, direction + "_mapper")
147
 
                range = mapper.range
148
185
                domain_min, domain_max = mapper.domain_limits
149
186
                eventpos = getattr(event, direction)
150
 
                origpos = self._original_xy[ndx]
 
187
                origpos = self._original_xy[index]
151
188
 
152
189
                screenlow, screenhigh = mapper.screen_bounds
153
190
                screendelta = self.speed * (eventpos - origpos)
154
 
                #if getattr(plot, direction + "_direction", None) == "flipped":
155
 
                #    screendelta = -screendelta
156
191
 
157
192
                newlow = mapper.map_data(screenlow - screendelta)
158
193
                newhigh = mapper.map_data(screenhigh - screendelta)
166
201
                # linear mappers (which is used 99% of the time).
167
202
                if domain_min is None:
168
203
                    if self.restrict_to_data:
169
 
                        domain_min = min([source.get_data().min() for source in range.sources])
 
204
                        domain_min = min([source.get_data().min()
 
205
                                          for source in mapper.range.sources])
170
206
                    else:
171
207
                        domain_min = -inf
172
208
                if domain_max is None:
173
209
                    if self.restrict_to_data:
174
 
                        domain_max = max([source.get_data().max() for source in range.sources])
 
210
                        domain_max = max([source.get_data().max()
 
211
                                          for source in mapper.range.sources])
175
212
                    else:
176
213
                        domain_max = inf
 
214
 
177
215
                if (newlow <= domain_min) and (newhigh >= domain_max):
178
216
                    # Don't do anything; effectively, freeze the pan
179
217
                    continue
 
218
 
180
219
                if newlow <= domain_min:
181
 
                    delta = newhigh - newlow
182
220
                    newlow = domain_min
183
 
                    # Don't let the adjusted newhigh exceed domain_max; this
184
 
                    # can happen with a nonlinear mapper.
185
 
                    newhigh = min(domain_max, domain_min + delta)
 
221
                    # Calculate delta in screen space, which is always linear.
 
222
                    screen_delta = mapper.map_screen(domain_min) - screenlow
 
223
                    newhigh = mapper.map_data(screenhigh + screen_delta)
186
224
                elif newhigh >= domain_max:
187
 
                    delta = newhigh - newlow
188
225
                    newhigh = domain_max
189
 
                    # Don't let the adjusted newlow go below domain_min; this
190
 
                    # can happen with a nonlinear mapper.
191
 
                    newlow = max(domain_min, domain_max - delta)
 
226
                    # Calculate delta in screen space, which is always linear.
 
227
                    screen_delta = mapper.map_screen(domain_max) - screenhigh
 
228
                    newlow = mapper.map_data(screenlow + screen_delta)
192
229
 
193
230
                # Use .set_bounds() so that we don't generate two range_changed
194
231
                # events on the DataRange
195
 
                range.set_bounds(newlow, newhigh)
 
232
                mapper.range.set_bounds(newlow, newhigh)
196
233
 
197
234
        event.handled = True
198
235