]>
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.
10 #This is a class to add Mouse Gestures to a program.
11 #It can be used in two ways:
14 # Automatically runs mouse gestures.
15 # You need to set the gestures, and their associated actions,
16 # as well as the Mouse Button/Modifiers to use.
19 # Same as above, but you do not need to set the mouse button/modifiers.
20 # You can launch this from events as you wish.
22 #An example is provided in the demo.
23 #The parent window is where the mouse events will be recorded.
24 #(So if you want to record them in a pop up window, use manual mode,
25 #and set the pop up as the parent).
27 #Start() starts recording mouse movement.
28 #End() stops the recording, compiles all the gestures into a list,
29 #and looks through the registered gestures to find a match.
30 #The first matchs associated action is then run.
32 #The marginoferror is how much to forgive when calculating movement:
33 #If the margin is 25, then movement less than 25 pixels will not be detected.
35 #Recognized: L, R, U, D, 1, 3, 7, 9
37 #Styles: Manual (Automatic By Default), DisplayNumbersForDiagonals (Off By Default).
40 #The criteria for a direction is as follows:
41 #x in a row. (Where x is the WobbleTolerance).
42 #So if the WobbleTolerance is 9
43 # 'URUUUUUUUUUUUUUUURUURUUUU1' is Up.
45 #The higher this number, the less sensitive this class is.
46 #So the more likely something like 1L will translate to 1.
48 #This is good, since the mouse does tend to wobble somewhat,
49 #and a higher number allows for this.
51 #To change this, use SetWobbleTolerance
53 #Also, to help with recognition of a diagonal versus
54 #a vey messy straight line, if the greater absolute value
55 #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.
62 ###########################################
66 0.0.1: Treats a mouse leaving event as mouse up.
67 (Bug Report, Thanks Peter Damoc).
70 0.0.0: Initial Release.
73 ###########################################
76 #Fully Implement Manual Mode
78 #Add "Ends With": AddGestureEndsWith(self, gesture, action, args)
79 #Add "Starts With": AddGestuteStartsWith(self, gesture, action, args)
81 #For better control of when the gesture starts and stops,
83 #At the moment, you need to Bind the OnMouseMotion event if you want to use
89 def __init__(self
, parent
, Auto
=True, MouseButton
=wx
.MOUSE_BTN_MIDDLE
):
94 self
.actionarguments
= []
96 self
.mousebutton
= MouseButton
99 self
.recording
= False
101 self
.lastposition
= (-1, -1)
103 self
.pen
= wx
.Pen(wx
.Colour(0, 144, 255), 5)
105 self
.dc
= wx
.ScreenDC()
106 self
.dc
.SetPen(self
.pen
)
108 self
.showgesture
= False
110 self
.wobbletolerance
= 7
116 def _check_modifiers(self
, event
):
117 '''Internal: Returns True if all needed modifiers are down
118 for the given event.'''
119 if len(self
.modifiers
) > 0:
121 if wx
.WXK_CONTROL
in self
.modifiers
:
122 good
= good
and event
.ControlDown()
123 if wx
.WXK_SHIFT
in self
.modifiers
:
124 good
= good
and event
.ShiftDown()
125 if wx
.WXK_ALT
in self
.modifiers
:
126 good
= good
and event
.AltDown()
130 def AddGesture(self
, gesture
, action
, *args
):
131 '''Registers a gesture, and an associated function, with any arguments needed.'''
132 #Make Sure not a duplicate:
133 self
.RemoveGesture(gesture
)
135 self
.gestures
.append(gesture
)
136 self
.actions
.append(action
)
137 self
.actionarguments
.append(args
)
139 def DoAction(self
, gesture
):
140 '''If the gesture is in the array of registered gestures, run the associated function.'''
141 if gesture
in self
.gestures
:
142 i
= self
.gestures
.index(gesture
)
143 apply(self
.actions
[i
], self
.actionarguments
[i
])
146 '''Stops recording the points to create the mouse gesture from,
147 and creates the mouse gesture, returns the result as a string.'''
148 self
.recording
= False
150 #Figure out the gestures (Look for occurances of 5 in a row or more):
157 for g
in self
.rawgesture
:
159 if g
!= tempstring
[l
- 1]:
160 if g
== possiblechange
:
166 if len(tempstring
) >= self
.wobbletolerance
:
169 if directions
[ld
- 1] != g
:
176 self
.parent
.Refresh()
180 def GetDirection(self
, point1
, point2
):
181 '''Gets the direction between two points.'''
182 #point1 is the old point
188 #(Negative = Left, Up)
189 #(Positive = Right, Down)
194 horizontalchange
= abs(horizontal
) > 0
195 verticalchange
= abs(vertical
) > 0
197 if horizontalchange
and verticalchange
:
203 verticalchange
= False
207 horizontalchange
= False
209 if horizontalchange
and verticalchange
:
211 if (horizontal
> 0) and (vertical
> 0):
213 elif (horizontal
> 0) and (vertical
< 0):
215 elif (horizontal
< 0) and (vertical
> 0):
232 def GetRecording(self
):
233 '''Returns whether or not Gesture Recording has started.'''
234 return self
.recording
236 def OnMotion(self
, event
):
237 '''Internal. Used if Start() has been run'''
239 currentposition
= event
.GetPosition()
240 if self
.lastposition
!= (-1, -1):
241 self
.rawgesture
+= self
.GetDirection(self
.lastposition
, currentposition
)
244 px1
, py1
= self
.parent
.ClientToScreen(self
.lastposition
)
245 px2
, py2
= self
.parent
.ClientToScreen(currentposition
)
246 self
.dc
.DrawLine(px1
, py1
, px2
, py2
)
248 self
.lastposition
= currentposition
252 def OnMouseEvent(self
, event
):
253 '''Internal. Used in Auto Mode.'''
254 if event
.ButtonDown(self
.mousebutton
) and self
._check
_modifiers
(event
):
256 elif (event
.ButtonUp(self
.mousebutton
) or event
.Leaving()) and self
.GetRecording():
258 self
.DoAction(result
)
261 def RemoveGesture(self
, gesture
):
262 '''Removes a gesture, and its associated action'''
263 if gesture
in self
.gestures
:
264 i
= self
.gestures
.index(gesture
)
268 del self
.actionarguments
[i
]
270 def SetAuto(self
, auto
):
271 '''Warning: Once auto is set, it stays set, unless you manually use UnBind'''
273 self
.parent
.Bind(wx
.EVT_MOUSE_EVENTS
, self
.OnMouseEvent
)
274 self
.parent
.Bind(wx
.EVT_MOTION
, self
.OnMotion
)
276 def SetGesturePen(self
, pen
):
277 '''Sets the wx pen used to visually represent each gesture'''
279 self
.dc
.SetPen(self
.pen
)
281 def SetGesturePen(self
, colour
, width
):
282 '''Sets the colour and width of the line drawn to visually represent each gesture'''
283 self
.pen
= wx
.Pen(colour
, width
)
284 self
.dc
.SetPen(self
.pen
)
286 def SetGesturesVisible(self
, vis
):
287 '''Sets whether a line is drawn to visually represent each gesture'''
288 self
.showgesture
= vis
290 def SetModifiers(self
, modifiers
=[]):
291 '''Takes an array of wx Key constants (Control, Shift, and/or Alt).
292 Leave empty to unset all modifiers.'''
293 self
.modifiers
= modifiers
295 def SetMouseButton(self
, mousebutton
):
296 '''Takes the wx constant for the target mousebutton'''
297 self
.mousebutton
= mousebutton
299 def SetWobbleTolerance(self
, wobbletolerance
):
300 '''Sets just how much wobble this class can take!'''
301 self
.WobbleTolerance
= wobbletolerance
304 '''Starts recording the points to create the mouse gesture from'''
305 self
.recording
= True
307 self
.lastposition
= (-1, -1)
309 self
.parent
.Refresh()