/usr/lib/python2.7/dist-packages/wx-2.6-gtk2-unicode/wx/lib/gestures.py is in python-wxgtk2.6 2.6.3.2.2-5ubuntu4.
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 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 | #Mouse Gestures
#Version 0.0.1
#By Daniel Pozmanter
#drpython@bluebottle.com
#Released under the terms of the wxWindows License.
"""
This is a class to add Mouse Gestures to a program.
It can be used in two ways:
1. Automatic:
Automatically runs mouse gestures.
You need to set the gestures, and their associated actions,
as well as the Mouse Button/Modifiers to use.
2. Manual:
Same as above, but you do not need to set the mouse button/modifiers.
You can launch this from events as you wish.
An example is provided in the demo.
The parent window is where the mouse events will be recorded.
(So if you want to record them in a pop up window, use manual mode,
and set the pop up as the parent).
Start() starts recording mouse movement.
End() stops the recording, compiles all the gestures into a list,
and looks through the registered gestures to find a match.
The first matchs associated action is then run.
The marginoferror is how much to forgive when calculating movement:
If the margin is 25, then movement less than 25 pixels will not be detected.
Recognized: L, R, U, D, 1, 3, 7, 9
Styles: Manual (Automatic By Default), DisplayNumbersForDiagonals (Off By Default).
Not Yet Implemented
The criteria for a direction is as follows:
x in a row. (Where x is the WobbleTolerance).
So if the WobbleTolerance is 9
'URUUUUUUUUUUUUUUURUURUUUU1' is Up.
The higher this number, the less sensitive this class is.
So the more likely something like 1L will translate to 1.
This is good, since the mouse does tend to wobble somewhat,
and a higher number allows for this.
To change this, use SetWobbleTolerance
Also, to help with recognition of a diagonal versus
a vey messy straight line, if the greater absolute value
is not greater than twice the lesser, only the grater value
is counted.
In automatic mode, EVT_MOUSE_EVENTS is used.
This allows the user to change the mouse button/modifiers at runtime.
"""
###########################################
'''
Changelog:
0.0.1: Treats a mouse leaving event as mouse up.
(Bug Report, Thanks Peter Damoc).
0.0.0: Initial Release.
'''
###########################################
#ToDo:
#Fully Implement Manual Mode
#Add "Ends With": AddGestureEndsWith(self, gesture, action, args)
#Add "Starts With": AddGestuteStartsWith(self, gesture, action, args)
#For better control of when the gesture starts and stops,
#use manual mode.
#At the moment, you need to Bind the OnMouseMotion event if you want to use
#manual mode.
import wx
class MouseGestures:
def __init__(self, parent, Auto=True, MouseButton=wx.MOUSE_BTN_MIDDLE):
self.parent = parent
self.gestures = []
self.actions = []
self.actionarguments = []
self.mousebutton = MouseButton
self.modifiers = []
self.recording = False
self.lastposition = (-1, -1)
self.pen = wx.Pen(wx.Colour(0, 144, 255), 5)
self.dc = wx.ScreenDC()
self.dc.SetPen(self.pen)
self.showgesture = False
self.wobbletolerance = 7
self.rawgesture = ''
self.SetAuto(Auto)
def _check_modifiers(self, event):
'''Internal: Returns True if all needed modifiers are down
for the given event.'''
if len(self.modifiers) > 0:
good = True
if wx.WXK_CONTROL in self.modifiers:
good = good and event.ControlDown()
if wx.WXK_SHIFT in self.modifiers:
good = good and event.ShiftDown()
if wx.WXK_ALT in self.modifiers:
good = good and event.AltDown()
return good
return True
def AddGesture(self, gesture, action, *args):
'''Registers a gesture, and an associated function, with any arguments needed.'''
#Make Sure not a duplicate:
self.RemoveGesture(gesture)
self.gestures.append(gesture)
self.actions.append(action)
self.actionarguments.append(args)
def DoAction(self, gesture):
'''If the gesture is in the array of registered gestures, run the associated function.'''
if gesture in self.gestures:
i = self.gestures.index(gesture)
apply(self.actions[i], self.actionarguments[i])
def End(self):
'''Stops recording the points to create the mouse gesture from,
and creates the mouse gesture, returns the result as a string.'''
self.recording = False
#Figure out the gestures (Look for occurances of 5 in a row or more):
tempstring = '0'
possiblechange = '0'
directions = ''
for g in self.rawgesture:
l = len(tempstring)
if g != tempstring[l - 1]:
if g == possiblechange:
tempstring = g + g
else:
possiblechange = g
else:
tempstring += g
if len(tempstring) >= self.wobbletolerance:
ld = len(directions)
if ld > 0:
if directions[ld - 1] != g:
directions += g
else:
directions += g
tempstring = '0'
if self.showgesture:
self.parent.Refresh()
return directions
def GetDirection(self, point1, point2):
'''Gets the direction between two points.'''
#point1 is the old point
#point2 is current
x1, y1 = point1
x2, y2 = point2
#(Negative = Left, Up)
#(Positive = Right, Down)
horizontal = x2 - x1
vertical = y2 - y1
horizontalchange = abs(horizontal) > 0
verticalchange = abs(vertical) > 0
if horizontalchange and verticalchange:
ah = abs(horizontal)
av = abs(vertical)
if ah > av:
if (ah / av) > 2:
vertical = 0
verticalchange = False
elif av > ah:
if (av / ah) > 2:
horizontal = 0
horizontalchange = False
if horizontalchange and verticalchange:
#Diagonal
if (horizontal > 0) and (vertical > 0):
return '3'
elif (horizontal > 0) and (vertical < 0):
return '9'
elif (horizontal < 0) and (vertical > 0):
return '1'
else:
return '7'
else:
#Straight Line
if horizontalchange:
if horizontal > 0:
return 'R'
else:
return 'L'
else:
if vertical > 0:
return 'D'
else:
return 'U'
def GetRecording(self):
'''Returns whether or not Gesture Recording has started.'''
return self.recording
def OnMotion(self, event):
'''Internal. Used if Start() has been run'''
if self.recording:
currentposition = event.GetPosition()
if self.lastposition != (-1, -1):
self.rawgesture += self.GetDirection(self.lastposition, currentposition)
if self.showgesture:
#Draw it!
px1, py1 = self.parent.ClientToScreen(self.lastposition)
px2, py2 = self.parent.ClientToScreen(currentposition)
self.dc.DrawLine(px1, py1, px2, py2)
self.lastposition = currentposition
event.Skip()
def OnMouseEvent(self, event):
'''Internal. Used in Auto Mode.'''
if event.ButtonDown(self.mousebutton) and self._check_modifiers(event):
self.Start()
elif (event.ButtonUp(self.mousebutton) or event.Leaving()) and self.GetRecording():
result = self.End()
self.DoAction(result)
event.Skip()
def RemoveGesture(self, gesture):
'''Removes a gesture, and its associated action'''
if gesture in self.gestures:
i = self.gestures.index(gesture)
del self.gestures[i]
del self.actions[i]
del self.actionarguments[i]
def SetAuto(self, auto):
'''Warning: Once auto is set, it stays set, unless you manually use UnBind'''
if auto:
self.parent.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseEvent)
self.parent.Bind(wx.EVT_MOTION, self.OnMotion)
def SetGesturePen(self, pen):
'''Sets the wx pen used to visually represent each gesture'''
self.pen = pen
self.dc.SetPen(self.pen)
def SetGesturePen(self, colour, width):
'''Sets the colour and width of the line drawn to visually represent each gesture'''
self.pen = wx.Pen(colour, width)
self.dc.SetPen(self.pen)
def SetGesturesVisible(self, vis):
'''Sets whether a line is drawn to visually represent each gesture'''
self.showgesture = vis
def SetModifiers(self, modifiers=[]):
'''Takes an array of wx Key constants (Control, Shift, and/or Alt).
Leave empty to unset all modifiers.'''
self.modifiers = modifiers
def SetMouseButton(self, mousebutton):
'''Takes the wx constant for the target mousebutton'''
self.mousebutton = mousebutton
def SetWobbleTolerance(self, wobbletolerance):
'''Sets just how much wobble this class can take!'''
self.WobbleTolerance = wobbletolerance
def Start(self):
'''Starts recording the points to create the mouse gesture from'''
self.recording = True
self.rawgesture = ''
self.lastposition = (-1, -1)
if self.showgesture:
self.parent.Refresh()
|