Repository URL to install this package:
Version:
5.0.0 ▾
|
# (C) Copyright 2005-2021 Enthought, Inc., Austin, TX
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in LICENSE.txt and may be redistributed only under
# the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
#
# Thanks for using Enthought open source!
""" Defines the DataLabelTool class.
"""
# Major library imports
from numpy import array, asarray, argmin, sqrt
# Enthought library imports
from traits.api import Any, Bool, Enum
from enable.tools.api import DragTool
class DataLabelTool(DragTool):
"""A tool for dragging a data label.
Attach this tool to a DataLabel object by setting the tool's **component**
to the DataLabel.
"""
#: The mouse button that initiates the drag.
drag_button = Enum("left", "right")
#: Use the root of the label's arrow (if any) as the closest corner of the
#: label?
auto_arrow_root = Bool(True)
# The original position of the label with respect to the data point.
_original_offset = Any
# This is used in the auto_arrow_root = 'corners' case.
_corner_names = (
"bottom left",
"bottom right",
"top right",
"top left",
"top center",
"bottom center",
"left center",
"right center",
)
def is_draggable(self, x, y):
"""Returns whether the (x,y) position is in a region that is OK to
drag.
Overrides DragTool.
"""
if self.component:
label = self.component
return (
x >= label.x
and x <= label.x2
and y >= label.y
and y <= label.y2
)
else:
return False
def drag_start(self, event):
"""Called when the drag operation starts.
Implements DragTool.
"""
if self.component:
label = self.component
pointx, pointy = label.component.map_screen(label.data_point)
self._original_offset = (label.x - pointx, label.y - pointy)
event.window.set_mouse_owner(self, event.net_transform())
event.handled = True
def dragging(self, event):
"""This method is called for every mouse_move event that the tool
receives while the user is dragging the mouse.
Implements DragTool. Moves and redraws the label.
"""
if self.component:
label = self.component
dx = int(event.x - self.mouse_down_position[0])
dy = int(event.y - self.mouse_down_position[1])
label.label_position = (
self._original_offset[0] + dx,
self._original_offset[1] + dy,
)
if self.auto_arrow_root:
# Determine which corner is closest to the point
p = asarray(label.component.map_screen(label.data_point))
x, y = label.position
x2 = label.x2
y2 = label.y2
xmid = (x + x2) / 2
ymid = (y + y2) / 2
anchors = array(
(
(x, y),
(x2, y),
(x2, y2),
(x, y2),
(xmid, y2),
(xmid, y),
(x, ymid),
(x2, ymid),
)
)
diff = anchors - p
closest = argmin((diff ** 2).sum(axis=-1))
label.arrow_root = self._corner_names[closest]
event.handled = True
label.request_redraw()
def drag_end(self, event):
"""Called when a mouse event causes the drag operation to end.
Implements DragTool.
"""
if self.component:
if event.window.mouse_owner == self:
event.window.set_mouse_owner(None)
event.handled = True
self.component.request_redraw()