34
34
# if the mouse pointer should be used to control the center
35
35
# of the zoom action
36
zoom_to_mouse = Bool(False)
36
zoom_to_mouse = Bool(True)
38
# if the mouse pointer should be used to control the center
39
# of the zoom action even for key events based zoom
40
keys_zoom_to_mouse = Bool(True)
38
42
# The axis to which the selection made by this tool is perpendicular. This
39
43
# only applies in 'range' mode.
59
63
# inherited from ToolHistoryMixin, but requires instances of ZoomState
60
64
_history = List(ToolState, [ZoomState((1.0, 1.0), (1.0, 1.0))])
66
def _do_zoom(self, new_index_factor, new_value_factor):
67
if self.zoom_to_mouse:
68
location = self.position
69
x_map = self._get_x_mapper()
70
y_map = self._get_y_mapper()
72
cx = (x_map.range.high + x_map.range.low)/2
73
if self._index_factor == new_index_factor:
76
x = x_map.map_data(location[0])
77
nextx = x + (cx - x)*(self._index_factor/new_index_factor)
79
cy = (y_map.range.high + y_map.range.low)/2
80
if self._value_factor == new_value_factor:
83
y = y_map.map_data(location[1])
84
nexty = y + (cy - y)*(self._value_factor/new_value_factor)
86
pan_state = PanState((cx,cy), (nextx, nexty))
87
zoom_state = ZoomState((self._index_factor, self._value_factor),
88
(new_index_factor, new_value_factor))
90
states = GroupedToolState([pan_state, zoom_state])
92
self._append_state(states)
96
zoom_state = ZoomState((self._index_factor, self._value_factor),
97
(new_index_factor, new_value_factor))
99
zoom_state.apply(self)
100
self._append_state(zoom_state)
62
102
#--------------------------------------------------------------------------
63
103
# public interface
64
104
#--------------------------------------------------------------------------
86
126
if self._zoom_limit_reached(new_value_factor, 'x'):
89
if self.zoom_to_mouse:
90
location = self.position
92
x_map = self._get_x_mapper()
93
y_map = self._get_y_mapper()
95
next = (x_map.map_data(location[0]),
96
y_map.map_data(location[1]))
97
prev = (x_map.map_data(self.component.bounds[0]/2),
98
y_map.map_data(self.component.bounds[1]/2))
100
pan_state = PanState(prev, next)
101
zoom_state = ZoomState((self._index_factor, self._value_factor),
102
(new_index_factor, new_value_factor))
104
states = GroupedToolState([pan_state, zoom_state])
106
self._append_state(states)
110
zoom_state = ZoomState((self._index_factor, self._value_factor),
111
(new_index_factor, new_value_factor))
113
zoom_state.apply(self)
114
self._append_state(zoom_state)
128
self._do_zoom(new_index_factor, new_value_factor)
116
130
def zoom_out(self, factor=0):
136
150
if self._zoom_limit_reached(new_value_factor, 'x'):
139
if self.zoom_to_mouse:
140
location = self.position
142
x_map = self._get_x_mapper()
143
y_map = self._get_y_mapper()
145
next = (x_map.map_data(location[0]),
146
y_map.map_data(location[1]))
147
prev = (x_map.map_data(self.component.bounds[0]/2),
148
y_map.map_data(self.component.bounds[1]/2))
150
pan_state = PanState(prev, next)
151
zoom_state = ZoomState((self._index_factor, self._value_factor),
152
(new_index_factor, new_value_factor))
154
states = GroupedToolState([pan_state, zoom_state])
156
self._append_state(states)
160
zoom_state = ZoomState((self._index_factor, self._value_factor),
161
(new_index_factor, new_value_factor))
163
zoom_state.apply(self)
164
self._append_state(zoom_state)
153
self._do_zoom(new_index_factor, new_value_factor)
166
155
def zoom_in_x(self, factor=0):
178
167
if self._zoom_limit_reached(new_value_factor, 'x'):
181
if self.zoom_to_mouse:
182
location = self.position
184
x_map = self._get_x_mapper()
185
y_map = self._get_y_mapper()
187
next = (x_map.map_data(location[0]),
188
y_map.map_data(location[1]))
189
prev = (x_map.map_data(self.component.bounds[0]/2),
190
y_map.map_data(self.component.bounds[1]/2))
192
pan_state = PanState(prev, next)
193
zoom_state = ZoomState((self._index_factor, self._value_factor),
194
(new_index_factor, new_value_factor))
196
states = GroupedToolState([pan_state, zoom_state])
198
self._append_state(states)
202
zoom_state = ZoomState((self._index_factor, self._value_factor),
203
(new_index_factor, new_value_factor))
205
zoom_state.apply(self)
206
self._append_state(zoom_state)
170
self._do_zoom(new_index_factor, new_value_factor)
208
172
def zoom_out_x(self, factor=0):
219
183
new_value_factor = self._value_factor / factor
220
184
if self._zoom_limit_reached(new_value_factor, 'x'):
223
if self.zoom_to_mouse:
224
location = self.position
226
x_map = self._get_x_mapper()
227
y_map = self._get_y_mapper()
229
next = (x_map.map_data(location[0]),
230
y_map.map_data(location[1]))
231
prev = (x_map.map_data(self.component.bounds[0]/2),
232
y_map.map_data(self.component.bounds[1]/2))
234
pan_state = PanState(prev, next)
235
zoom_state = ZoomState((self._index_factor, self._value_factor),
236
(new_index_factor, new_value_factor))
238
states = GroupedToolState([pan_state, zoom_state])
240
self._append_state(states)
244
zoom_state = ZoomState((self._index_factor, self._value_factor),
245
(new_index_factor, new_value_factor))
247
zoom_state.apply(self)
248
self._append_state(zoom_state)
186
self._do_zoom(new_index_factor, new_value_factor)
250
189
def zoom_in_y(self, factor=0):
262
201
if self._zoom_limit_reached(new_value_factor, 'y'):
265
if self.zoom_to_mouse:
266
location = self.position
268
x_map = self._get_x_mapper()
269
y_map = self._get_y_mapper()
271
next = (x_map.map_data(location[0]),
272
y_map.map_data(location[1]))
273
prev = (x_map.map_data(self.component.bounds[0]/2),
274
y_map.map_data(self.component.bounds[1]/2))
276
pan_state = PanState(prev, next)
277
zoom_state = ZoomState((self._index_factor, self._value_factor),
278
(new_index_factor, new_value_factor))
280
states = GroupedToolState([pan_state, zoom_state])
282
self._append_state(states)
286
zoom_state = ZoomState((self._index_factor, self._value_factor),
287
(new_index_factor, new_value_factor))
289
zoom_state.apply(self)
290
self._append_state(zoom_state)
204
self._do_zoom(new_index_factor, new_value_factor)
292
206
def zoom_out_y(self, factor=0):
304
218
if self._zoom_limit_reached(new_value_factor, 'y'):
307
if self.zoom_to_mouse:
308
location = self.position
310
x_map = self._get_x_mapper()
311
y_map = self._get_y_mapper()
313
next = (x_map.map_data(location[0]),
314
y_map.map_data(location[1]))
315
prev = (x_map.map_data(self.component.bounds[0]/2),
316
y_map.map_data(self.component.bounds[1]/2))
318
pan_state = PanState(prev, next)
319
zoom_state = ZoomState((self._index_factor, self._value_factor),
320
(new_index_factor, new_value_factor))
322
states = GroupedToolState([pan_state, zoom_state])
324
self._append_state(states)
328
zoom_state = ZoomState((self._index_factor, self._value_factor),
329
(new_index_factor, new_value_factor))
331
zoom_state.apply(self)
332
self._append_state(zoom_state)
221
self._do_zoom(new_index_factor, new_value_factor)
334
223
#--------------------------------------------------------------------------
335
224
# BaseTool interface
339
228
""" Handles a key being pressed when the tool is in the 'normal'
231
if not self.keys_zoom_to_mouse:
232
self.position = self._center_screen()
342
233
if self.zoom_in_key.match(event):
343
self.position = self._center_screen()
345
235
event.handled = True
346
236
elif self.zoom_out_key.match(event):
347
self.position = self._center_screen()
349
238
event.handled = True
350
239
elif self.zoom_in_x_key.match(event):
351
self.position = self._center_screen()
352
240
self.zoom_in_x(self.zoom_factor)
353
241
event.handled = True
354
242
elif self.zoom_out_x_key.match(event):
355
self.position = self._center_screen()
356
243
self.zoom_out_x(self.zoom_factor)
357
244
event.handled = True
358
245
elif self.zoom_in_y_key.match(event):
359
self.position = self._center_screen()
360
246
self.zoom_in_y(self.zoom_factor)
361
247
event.handled = True
362
248
elif self.zoom_out_y_key.match(event):
363
self.position = self._center_screen()
364
249
self.zoom_out_y(self.zoom_factor)
365
250
event.handled = True