B4A Library Gestures (multi-touch) library

This library allows a View to detect multi-touch gestures. Note that the demo does nothing on the device but logs the multiple touches to LogCat so you will need to be connected to the IDE and viewing filtered LogCat output to see the results of the demo.

The quality of multi-touch support appears variable across devices. Erel reports that this library works fine on his Nexus but my Orange San Francisco (ZTE Blade) is pretty rubbish at tracking pointers as you can see from the comments in the library. You get what you pay for I guess!

EDIT :- Version 1.1 posted. See post #18 for details.

EDIT :- Version 1.2 posted. See post #26 for details.
 

Attachments

  • Gestures1.2.zip
    10.4 KB · Views: 5,506
Last edited:

Ph1lJ

Member
Licensed User
Longtime User
Hi
I'm attempting to run the 'Gesture' demo - have made no changes to the your supplied code but :-

HTML:
Compiling code.                         Error
Error parsing program.
Error description: Unknown type: gestures
Are you missing a library reference?
Occurred on line: 12
Dim g As Gestures

This is the message I get when trying to complie this demo - I have set the
LogCat.

Any ideas
 

Cableguy

Expert
Licensed User
Longtime User
Andrew, I cant manage to get this to work with my Galaxy S... I have changed the value of detected moves asn sugested in the demo, 5 up, 5 down, but no response!

EDIT: I didnt noticed that this posted to the catlog...all is working well, Thanks...I have one question, when the gesture is started out of the target view is it registered?
 
Last edited:

agraham

Expert
Licensed User
Longtime User
The gesture data is only passed to a view when the gesture is started within the view. Once the view is getting gesture data it remains getting data until the gesture is ended, even if the gesture goes outside the bounds of the view. You can see this in the demo.
 

Cableguy

Expert
Licensed User
Longtime User
Thanks Andrew...I now understand a bit more about the gestures concept...
I have one question...How would you go for managing simple gestures, like swipe across a view, from left to right or from top to bottom, and then act accordinly?
 

agraham

Expert
Licensed User
Longtime User
How would you go for managing simple gestures
I don't really know, depends upon what you want to do. Like maybe record the start and end coordinates of a gesture and the time between them and so work out a distance and a speed for the gesture and do whatever.
 

francoisg

Active Member
Licensed User
Longtime User
Hi, this works but it is real slow on all my test devices (lag between moving and getting the event handler code fired) ...

Changed the demo app to draw circles around the touch points and it lags quit a bit ...
 

agraham

Expert
Licensed User
Longtime User
Have you seen this comment in Sub pnl_gesture?

B4X:
' noise on the touch screen electroincs can cause lots of apparent move events
' this loop slows the rate down to one comfortable for LogCat
' adjust the value for your device if necessary
If movecount < 10 Then 
   ...
 

francoisg

Active Member
Licensed User
Longtime User
Hi,
yes I did - I changed the gesture event handler code to

Sub pnl_gesture(o As Object, ptrID As Int, action As Int, x As Float, y As Float) As Boolean
Dim canv As Canvas
canv.Initialize(Activity)
Dim ix, iy As Int
canv.DrawColor(Colors.Black)
Dim xx, yy As Float : xx = -1
For i = 0 To g.GetPointerCount-1
id = g.GetPointerID(i)
ix = g.GetX(id)
iy = g.GetY(id)

canv.DrawCircle(ix, iy, 60, Colors.Red, False, 2)
If xx <> -1 Then canv.DrawLine(xx, yy, ix, iy, Colors.Blue, 1)
xx = ix
yy = iy
Next
If action = g.ACTION_UP Then canv.DrawColor(Colors.Black)
Return True ' need to return true otherwise we don't get any other events in the gesture
End Sub


So, there is no log being generated etc, only drawing (Also, i removed the panel and changed the listener code to g.SetOnTouchListener(Activity, "pnl_gesture")) ...

Any ideas - maybe my drawing code can do with some changes ;-)
 

francoisg

Active Member
Licensed User
Longtime User
That helped a lot - thank you for the advice! Just a note, for anybody else that would like to try this - you need to call Activity.Invalidate when done drawing in order to actually see the changes ;-)
Took me a while to figure that out!
 

francoisg

Active Member
Licensed User
Longtime User
Thank you - applied the idea on my game engine as well and (obviously) it's now also much faster (and smoother) and more efficient!
Thank you again for the suggestions!
 

acorrias

Member
Licensed User
Longtime User
chatching pointer data on move event

Hi
I'm trying to learn b4a through its libraries. I'm going to develop a draw app with two thumbs. The first is the pencil and the second is the brush size, computed on the distance from the two thumbs.

I cannot understand how to get pointer data, as in the documentation there is written "As pointers move during a gesture an ACTION_MOVE occurs for pointerID 0 with data available for all pointers."

Could you explain it, please? Does it means that the event occurs only for pointerid=0? or does the actions rise for every touching object (thumbs). Thats to say that the touch listener is called back for every PointerID and it's possible to get x-y coords with g.GetX(pointerid), g.GetX(pointerid)?

thanks in advance
alex
PS: I have modified the sample code provided with the routine. As you could see my listener consider olty to touch situations (0) for main thumb drawing and (1) to second thumb. If you test you could realize that it is possibile to draw but it is not possible to change brush size As that move event doesn't rise for a pointerid different from 0.
B4X:
Sub Globals
   Dim bgd As Panel :    Dim G As Gestures
   Dim Label1 As Label :    Dim TouchMap As Map
   Type Point(Id As Int, prevX As Int, prevY As Int)
   Dim Canvas As Canvas :    Dim RowHeight As Int
   Dim TextSize As Float:    TextSize = 18
   Dim TextRect As Rect
   '--------- new ---------'
   Dim BrushSize As Int
   Dim BrushX As Int
   Dim BrushY As Int
   Dim MinInterFingerDist As Int
   Dim BrushDistance As Int
End Sub
Sub Activity_Create(FirstTime As Boolean)
   bgd.Initialize("")'Create a panel and add it to the activity
   Activity.AddView(bgd, 0, 0, 100%x, 100%y)
   Canvas.Initialize(bgd)
   G.SetOnTouchListener(bgd, "GesturesTouch")'Add a listener for this panel   
   TouchMap.Initialize
   RowHeight = Canvas.MeasureStringHeight("M", Typeface.DEFAULT, TextSize) + 5dip
   TextRect.Initialize(0, 0, 120dip, 20dip + RowHeight * 10)
   Activity.AddMenuItem("Clear", "mnuClear")
   BrushSize=2 :    MinInterFingerDist=60
End Sub
Sub mnuClear_Click
   Dim r As Rect
   r.Initialize(0, 0, 100%x, 100%y)
   Canvas.DrawRect(r, Colors.Transparent, True, 0) 'erase everything
   bgd.Invalidate
End Sub
Sub GesturesTouch(View As Object, PointerID As Int, Action As Int, X As Float, Y As Float) As Boolean
   Dim p As Point
   Dim px, py As Int
   Dim s As String
   Canvas.DrawRect(TextRect, Colors.Transparent, True, 0) 'Clear the previous text
   Select Action
      Case g.ACTION_DOWN,g.ACTION_POINTER_DOWN         'New Point is assigned to the new touch
         p.Id = PointerID :          TouchMap.Put(PointerID, p)
      Case g.ACTION_POINTER_UP
         TouchMap.Remove(PointerId)
      Case g.ACTION_UP
         TouchMap.Clear            'This is the end of this gesture
      Case g.ACTION_MOVE
      If Pointerid=1 Then
         [COLOR="SeaGreen"]p = TouchMap.GetValueAt(1) : px = g.GetX(p.id) : py = g.GetY(p.id)
         BrushDistance= Sqrt((pX-BrushX)*(pX-BrushX)+(pY-Brushy)*(pY-Brushy))
         If BrushDistance<MinInterFingerDist Then 
            BrushSize=1
         Else
            BrushSize=(BrushDistance-MinInterFingerDist)/10
         End If
         s = p.Id & ": " & px & " x " & py & "//" & BrushDistance & " - " & BrushSize
         Canvas.DrawText(s, 10dip, 20dip , Typeface.DEFAULT, TextSize, Colors.white, "LEFT")[/COLOR]
      Else

         [COLOR="Olive"]p = TouchMap.GetValueAt(0) : px = g.GetX(p.id) : py = g.GetY(p.id)
         s = p.Id & ": " & px & " x " & py
         Canvas.DrawText(s, 10dip, 20dip + RowHeight , Typeface.DEFAULT, TextSize, Colors.white, "LEFT")
         If p.prevX > 0 AND p.prevY > 0 Then
            Canvas.DrawLine(p.prevX, p.prevY, px, py, Colors.red, BrushSize)
         End If
         p.prevX = px :    p.prevY = py
         BrushX = px :    BrushY = py[/COLOR]      
      End If
   End Select
   bgd.Invalidate
   Return True
End Sub
 
Last edited:
Top