This file is indexed.

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