/usr/lib/python2.7/dist-packages/enable/drag.py is in python-enable 4.5.1-4.
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 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | #-------------------------------------------------------------------------------
#
# Define the classes used to support the Enable package 'drag' functionality.
#
# Written by: David C. Morrill
#
# Date: 09/22/2003
#
# (c) Copyright 2003 by Enthought, Inc.
#
# Classes defined: DragHandler
#
#-------------------------------------------------------------------------------
from base import add_rectangles, intersect_coordinates, send_event_to, \
bounds_to_coordinates
from events import DragEvent
from interactor import Interactor
#-------------------------------------------------------------------------------
# 'DragHandler' class:
#-------------------------------------------------------------------------------
class DragHandler ( Interactor ):
#---------------------------------------------------------------------------
# Initialize the object:
#---------------------------------------------------------------------------
def init ( self, components, bounds_rect, drag_root, drag_bounds_rect,
drag_copy, drag_event, start_event ):
self.components = components[:]
self.bounds_rect = bounds_rect
self.drag_root = drag_root
self.drag_bounds_rect = self.drag_bounds_rect_start = drag_bounds_rect
self.drag_copy = drag_copy
self.drag_event = drag_event
self.start_event = start_event
self.drag_x = self.start_x = start_event.x
self.drag_y = self.start_y = start_event.y
self.window = components[0].window
self.drag_over = []
self.on_trait_change( self.drag_done, drag_event )
#---------------------------------------------------------------------------
# Handle the mouse moving while dragging:
#---------------------------------------------------------------------------
def _mouse_move_changed ( self, event ):
# Get the current drag location:
x = event.x
y = event.y
# If the mouse did not actually move, then ignore the event:
if (x == self.drag_x) and (y == self.drag_y):
return
# Save the new position:
self.drag_x = x
self.drag_y = y
# Calculate the distance moved from the original starting point:
dx = x - self.start_x
dy = y - self.start_y
# Calculate the new drag bounds:
xl, yb, xr, yt = add_rectangles( self.drag_bounds_rect_start,
( dx, dy, dx, dy ) )
# Adjust the new drag location if it is not completely within the drag
# bounds. Exit if the result is the same as the previous location:
if self.bounds_rect is not None:
bxl, byb, bxr, byt = self.bounds_rect
if xl < bxl:
xr += bxl - xl
xl = bxl
elif xr > bxr:
xl -= xr - bxr
xr = bxr
if yb < byb:
yt += byb - yb
yb = byb
elif yt > byt:
yb -= yt - byt
yt = byt
x = xl - self.drag_bounds_rect[0] + self.drag_x
y = yb - self.drag_bounds_rect[1] + self.drag_y
# If the new drag bounds is the same as the last one, nothing changed:
drag_bounds_rect = bounds_to_coordinates( self.drag_validate( event,
( xl, yb, xr - xl, yt - yb ) ) )
if drag_bounds_rect == self.drag_bounds_rect:
return
# Update the drag bounds and current drag location:
self.drag_bounds_rect = drag_bounds_rect
# Notify each drag component of its new drag location:
dx = drag_bounds_rect[0] - self.drag_bounds_rect_start[0]
dy = drag_bounds_rect[1] - self.drag_bounds_rect_start[1]
for component in self.components:
cx, cy = component.location()
component.dragged = DragEvent( x = cx + dx,
y = cy + dy,
x0 = self.start_x,
y0 = self.start_y,
copy = self.drag_copy,
components = self.components,
start_event = self.start_event,
window = event.window )
# Process the 'drag_over' events for any objects being dragged over:
drag_over_event = DragEvent( x = x,
y = y,
x0 = self.start_x,
y0 = self.start_y,
copy = self.drag_copy,
components = self.components,
start_event = self.start_event,
window = event.window )
new_drag_over = []
cur_drag_over = self.drag_over
for component in self.drag_root.components_at( x, y ):
new_drag_over.append( component )
if component in cur_drag_over:
cur_drag_over.remove( component )
component.drag_over = drag_over_event
else:
component.drag_enter = drag_over_event
for component in cur_drag_over:
component.drag_leave = drag_over_event
self.drag_over = new_drag_over
# Tell the Enable window where the drag is now:
self.window.set_drag_bounds_rect( drag_bounds_rect )
#---------------------------------------------------------------------------
# Validate the proposed new drag location (by default, just accept it):
#---------------------------------------------------------------------------
def drag_validate ( self, event, drag_bounds ):
return drag_bounds
#---------------------------------------------------------------------------
# Handle the user releasing the original drag button:
#---------------------------------------------------------------------------
def drag_done ( self, event ):
components = self.components
drag_copy = self.drag_copy
start_event = self.start_event
# 'Unhook' the drag done notification handler:
self.on_trait_change( self.drag_done, self.drag_event, remove = True )
# Compute the new drag bounds:
x = event.x
y = event.y
dx = x - self.start_x
dy = y - self.start_y
xl, yb, xr, yt = add_rectangles( self.drag_bounds_rect_start,
( dx, dy, dx, dy ) )
drag_bounds_rect = bounds_to_coordinates( self.drag_validate( event,
( xl, yb, xr - xl, yt - yb ) ) )
# If the new bounds are not within the drag area, use the last drag
# location:
if ((self.bounds_rect is not None) and
(intersect_coordinates( self.bounds_rect, drag_bounds_rect ) !=
drag_bounds_rect)):
drag_bounds_rect = self.drag_bounds_rect
# Notify each dragged component where it was dropped:
dx = drag_bounds_rect[0] - self.drag_bounds_rect_start[0]
dy = drag_bounds_rect[1] - self.drag_bounds_rect_start[1]
for component in components:
cx, cy = component.location()
component.dropped = DragEvent( x = cx + dx,
y = cy + dy,
x0 = self.start_x,
y0 = self.start_y,
copy = drag_copy,
components = components,
start_event = start_event,
window = event.window )
# Process the 'dropped_on' event for the object(s) it was dropped on:
components_at = self.drag_root.components_at( x, y )
drag_event = DragEvent( x = self.start_x + dx,
y = self.start_y + dy,
x0 = self.start_x,
y0 = self.start_y,
copy = drag_copy,
components = components,
start_event = start_event,
window = event.window )
index = send_event_to( components_at, 'dropped_on', drag_event )
# Send all the runner-ups a 'drag_leave' consolation prize:
drag_over = self.drag_over
for component in components_at[ 0: index ]:
if component in drag_over:
component.drag_leave = drag_event
# Make sure all of the dragged components are drawable again:
if not drag_copy:
for component in components:
component._drawable = True
# Redraw the window to clean-up any drag artifacts:
self.window.redraw()
# Finally, release any references we have been using:
self.components[:] = []
self.drag_over = self.drag_root = self.window = None
|