1
""" Makes a copy of the plot in the overlay and adds it to the canvas.
4
from __future__ import with_statement
6
# Enthought library imports
7
from traits.api import Bool, Callable, Enum, Float, Instance, Int, Trait, Tuple
8
from enable.api import Container
11
from chaco.api import AbstractOverlay
12
from enable.tools.api import DragTool
15
class PlotCloneTool(AbstractOverlay, DragTool):
16
""" On a drag operation, draws an overlay of self.component underneath
17
the cursor. On drag_end, a copy of the plot is dropped onto the
21
# The container to add the cloned plot to
22
dest = Instance(Container)
24
# A function that gets called on drag_end. It gets passed this tool
25
# and the position at which to place the new cloned plot.
26
plot_cloner = Callable
28
# The amount to fade the plot when we draw as overlay
31
# The possible event states for this tool.
32
event_state = Enum("normal", "dragging")
36
# The (x,y) position of the "last" mouse position we received
37
_offset = Trait(None, None, Tuple)
39
# The relative position of the mouse_down_position to the origin
40
# of the plot's coordinate system
41
_offset_from_plot = Tuple
43
# This is set to True before we attempt to move the plot, so that
44
# we do not get called again, in case we are an overlay on the plot
46
_recursion_check = Bool(False)
48
def overlay(self, component, gc, view_bounds=None, mode="normal"):
49
if self._recursion_check:
52
if self._offset is not None and (self._offset[0] > 10 or
53
self._offset[1] > 10):
56
gc.translate_ctm(*self._offset)
57
gc.set_alpha(self.alpha)
58
self._recursion_check = True
59
self.component._draw(gc, view_bounds, mode)
60
self._recursion_check = False
62
def drag_start(self, event):
63
""" Called when the drag operation starts.
67
self._offset = (event.x - self.mouse_down_position[0],
68
event.y - self.mouse_down_position[1])
69
self._offset_from_plot = (self.mouse_down_position[0] - self.component.x,
70
self.mouse_down_position[1] - self.component.y)
74
def dragging(self, event):
75
self._offset = (event.x - self.mouse_down_position[0],
76
event.y - self.mouse_down_position[1])
77
self.component.request_redraw()
79
def drag_end(self, event):
80
if self.plot_cloner is not None:
81
# Recreate the event transform history and figure out the coordinates
82
# of the event in the Canvas's coordinate system
83
offset = self._offset_from_plot
84
drop_position = (event.x - offset[0], event.y - offset[1])
85
self.plot_cloner(self, drop_position)
88
self.component.request_redraw()
91
class MPPlotCloneTool(PlotCloneTool):
95
_last_blob_pos = Tuple
97
def normal_blob_down(self, event):
98
if self.cur_bid == -1 and self.is_draggable(event.x, event.y):
99
self.cur_bid = event.bid
100
self.drag_start(event)
102
def dragging_blob_up(self, event):
103
if event.bid == self.cur_bid:
107
def dragging_blob_move(self, event):
108
if event.bid == self.cur_bid:
110
self._last_blob_pos = (event.x, event.y)
112
def drag_start(self, event):
114
self.original_padding = self.component.padding
115
if hasattr(event, "bid"):
116
event.window.capture_blob(self, event.bid,
117
event.net_transform())
119
event.window.set_mouse_owner(self, event.net_transform())
120
self.mouse_down_position = (event.x,event.y)
121
self.event_state = "dragging"
123
PlotCloneTool.drag_start(self, event)
126
def drag_end(self, event):
127
if hasattr(event, "bid"):
128
event.window.release_blob(event.bid)
129
self.event_state = "normal"
130
if self.plot_cloner is not None:
131
offset = self._offset_from_plot
132
drop_position = self._last_blob_pos
133
if len(drop_position) == 2:
134
self.plot_cloner(self, (drop_position[0] - offset[0],
135
drop_position[1] - offset[1]))