]>
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()