]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/wx/lib/gestures.py
   6 #drpython@bluebottle.com 
   8 #Released under the terms of the wxWindows License. 
  11 This is a class to add Mouse Gestures to a program. 
  12 It can be used in two ways: 
  15     Automatically runs mouse gestures. 
  16     You need to set the gestures, and their associated actions, 
  17     as well as the Mouse Button/Modifiers to use. 
  20     Same as above, but you do not need to set the mouse button/modifiers. 
  21     You can launch this from events as you wish. 
  23 An example is provided in the demo. 
  24 The parent window is where the mouse events will be recorded. 
  25 (So if you want to record them in a pop up window, use manual mode, 
  26 and set the pop up as the parent). 
  28 Start() starts recording mouse movement. 
  29 End() stops the recording, compiles all the gestures into a list, 
  30 and looks through the registered gestures to find a match. 
  31 The first matchs associated    action is then run. 
  33 The marginoferror is how much to forgive when calculating movement: 
  34 If the margin is 25, then movement less than 25 pixels will not be detected. 
  36 Recognized:  L, R, U, D, 1, 3, 7, 9 
  38 Styles:  Manual (Automatic By Default), DisplayNumbersForDiagonals (Off By Default). 
  41 The criteria for a direction is as follows: 
  42 x in a row.  (Where x is the WobbleTolerance). 
  43 So if the WobbleTolerance is 9 
  44  'URUUUUUUUUUUUUUUURUURUUUU1' is Up. 
  46 The higher this number, the less sensitive this class is. 
  47 So the more likely something like 1L will translate to 1. 
  49 This is good, since the mouse does tend to wobble somewhat, 
  50 and a higher number allows for this. 
  52 To change this, use SetWobbleTolerance 
  54 Also, to help with recognition of a diagonal versus 
  55 a vey messy straight line, if the greater absolute value 
  56 is not greater than twice the lesser, only the grater value 
  59 In automatic mode, EVT_MOUSE_EVENTS is used. 
  60 This allows the user to change the mouse button/modifiers at runtime. 
  63 ########################################### 
  67 0.0.1:  Treats a mouse leaving event as mouse up. 
  68         (Bug Report, Thanks Peter Damoc). 
  71 0.0.0:  Initial Release. 
  74 ########################################### 
  77 #Fully Implement Manual Mode 
  79 #Add "Ends With":  AddGestureEndsWith(self, gesture, action, args) 
  80 #Add "Starts With":  AddGestuteStartsWith(self, gesture, action, args) 
  82 #For better control of when the gesture starts and stops, 
  84 #At the moment, you need to Bind the OnMouseMotion event if you want to use 
  90     def __init__(self
, parent
, Auto
=True, MouseButton
=wx
.MOUSE_BTN_MIDDLE
): 
  95         self
.actionarguments 
= [] 
  97         self
.mousebutton 
= MouseButton
 
 100         self
.recording 
= False 
 102         self
.lastposition 
= (-1, -1) 
 104         self
.pen 
= wx
.Pen(wx
.Colour(0, 144, 255), 5) 
 106         self
.dc 
= wx
.ScreenDC() 
 107         self
.dc
.SetPen(self
.pen
) 
 109         self
.showgesture 
= False 
 111         self
.wobbletolerance 
= 7 
 117     def _check_modifiers(self
, event
): 
 118         '''Internal:  Returns True if all needed modifiers are down 
 119         for the given event.''' 
 120         if len(self
.modifiers
) > 0: 
 122             if wx
.WXK_CONTROL 
in self
.modifiers
: 
 123                 good 
= good 
and event
.ControlDown() 
 124             if wx
.WXK_SHIFT 
in self
.modifiers
: 
 125                 good 
= good 
and event
.ShiftDown() 
 126             if wx
.WXK_ALT 
in self
.modifiers
: 
 127                 good 
= good 
and event
.AltDown() 
 131     def AddGesture(self
, gesture
, action
, *args
): 
 132         '''Registers a gesture, and an associated function, with any arguments needed.''' 
 133         #Make Sure not a duplicate: 
 134         self
.RemoveGesture(gesture
) 
 136         self
.gestures
.append(gesture
) 
 137         self
.actions
.append(action
) 
 138         self
.actionarguments
.append(args
) 
 140     def DoAction(self
, gesture
): 
 141         '''If the gesture is in the array of registered gestures, run the associated function.''' 
 142         if gesture 
in self
.gestures
: 
 143             i 
= self
.gestures
.index(gesture
) 
 144             apply(self
.actions
[i
], self
.actionarguments
[i
]) 
 147         '''Stops recording the points to create the mouse gesture from, 
 148         and creates the mouse gesture, returns the result as a string.''' 
 149         self
.recording 
= False 
 151         #Figure out the gestures (Look for occurances of 5 in a row or more): 
 158         for g 
in self
.rawgesture
: 
 160             if g 
!= tempstring
[l 
- 1]: 
 161                 if g 
== possiblechange
: 
 167             if len(tempstring
) >= self
.wobbletolerance
: 
 170                     if directions
[ld 
- 1] != g
: 
 177             self
.parent
.Refresh() 
 181     def GetDirection(self
, point1
, point2
): 
 182         '''Gets the direction between two points.''' 
 183         #point1 is the old point 
 189         #(Negative = Left, Up) 
 190         #(Positive = Right, Down) 
 195         horizontalchange 
= abs(horizontal
) > 0 
 196         verticalchange 
= abs(vertical
) > 0 
 198         if horizontalchange 
and verticalchange
: 
 204                     verticalchange 
= False 
 208                     horizontalchange 
= False 
 210         if horizontalchange 
and verticalchange
: 
 212             if (horizontal 
> 0) and (vertical 
> 0): 
 214             elif (horizontal 
> 0) and (vertical 
< 0): 
 216             elif (horizontal 
< 0) and (vertical 
> 0): 
 233     def GetRecording(self
): 
 234         '''Returns whether or not Gesture Recording has started.''' 
 235         return self
.recording
 
 237     def OnMotion(self
, event
): 
 238         '''Internal.  Used if Start() has been run''' 
 240             currentposition 
= event
.GetPosition() 
 241             if self
.lastposition 
!= (-1, -1): 
 242                 self
.rawgesture 
+= self
.GetDirection(self
.lastposition
, currentposition
) 
 245                     px1
, py1 
= self
.parent
.ClientToScreen(self
.lastposition
) 
 246                     px2
, py2 
= self
.parent
.ClientToScreen(currentposition
) 
 247                     self
.dc
.DrawLine(px1
, py1
, px2
, py2
) 
 249             self
.lastposition 
= currentposition
 
 253     def OnMouseEvent(self
, event
): 
 254         '''Internal.  Used in Auto Mode.''' 
 255         if event
.ButtonDown(self
.mousebutton
) and self
._check
_modifiers
(event
): 
 257         elif (event
.ButtonUp(self
.mousebutton
) or event
.Leaving()) and self
.GetRecording(): 
 259             self
.DoAction(result
) 
 262     def RemoveGesture(self
, gesture
): 
 263         '''Removes a gesture, and its associated action''' 
 264         if gesture 
in self
.gestures
: 
 265             i 
= self
.gestures
.index(gesture
) 
 269             del self
.actionarguments
[i
] 
 271     def SetAuto(self
, auto
): 
 272         '''Warning:  Once auto is set, it stays set, unless you manually use UnBind''' 
 274             self
.parent
.Bind(wx
.EVT_MOUSE_EVENTS
, self
.OnMouseEvent
) 
 275             self
.parent
.Bind(wx
.EVT_MOTION
, self
.OnMotion
) 
 277     def SetGesturePen(self
, pen
): 
 278         '''Sets the wx pen used to visually represent each gesture''' 
 280         self
.dc
.SetPen(self
.pen
) 
 282     def SetGesturePen(self
, colour
, width
): 
 283         '''Sets the colour and width of the line drawn to visually represent each gesture''' 
 284         self
.pen 
= wx
.Pen(colour
, width
) 
 285         self
.dc
.SetPen(self
.pen
) 
 287     def SetGesturesVisible(self
, vis
): 
 288         '''Sets whether a line is drawn to visually represent each gesture''' 
 289         self
.showgesture 
= vis
 
 291     def SetModifiers(self
, modifiers
=[]): 
 292         '''Takes an array of wx Key constants (Control, Shift, and/or Alt). 
 293         Leave empty to unset all modifiers.''' 
 294         self
.modifiers 
= modifiers
 
 296     def SetMouseButton(self
, mousebutton
): 
 297         '''Takes the wx constant for the target mousebutton''' 
 298         self
.mousebutton 
= mousebutton
 
 300     def SetWobbleTolerance(self
, wobbletolerance
): 
 301         '''Sets just how much wobble this class can take!''' 
 302         self
.WobbleTolerance 
= wobbletolerance
 
 305         '''Starts recording the points to create the mouse gesture from''' 
 306         self
.recording 
= True 
 308         self
.lastposition 
= (-1, -1) 
 310             self
.parent
.Refresh()