B4A Library Gestures (multi-touch) library

Discussion in 'Additional libraries, classes and official updates' started by agraham, Jan 20, 2011.

  1. agraham

    agraham Expert Licensed User

    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.
     

    Attached Files:

    Last edited: Mar 27, 2012
    koaunglay, Peter Simpson, eps and 3 others like this.
  2. Ph1lJ

    Ph1lJ Member Licensed 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
     
  3. agraham

    agraham Expert Licensed User

    Right hand pane of the IDE, Libraries tab. Select Gestures library and it should work assuming you have copied the gestures files to your Additional Libraries folder.
     
  4. Ph1lJ

    Ph1lJ Member Licensed User

    Got it now

    Thanks - look useful
     
  5. Cableguy

    Cableguy Expert Licensed 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: Jul 10, 2011
  6. agraham

    agraham Expert Licensed 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.
     
  7. Cableguy

    Cableguy Expert Licensed 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?
     
  8. agraham

    agraham Expert Licensed User

    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.
     
  9. francoisg

    francoisg Active Member Licensed 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 ...
     
  10. agraham

    agraham Expert Licensed User

    Have you seen this comment in Sub pnl_gesture?

    Code:
    ' 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 
       ...
     
  11. francoisg

    francoisg Active Member Licensed 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 ;-)
     
  12. agraham

    agraham Expert Licensed User

    Code:
    Dim canv As Canvas
    canv.Initialize(
    Activity)
    ...
    canv.DrawColor(
    Colors.Black)
    That's a bit heavy to put in an event!
     
  13. francoisg

    francoisg Active Member Licensed User

    mmm... ok, any better (easier) way to render graphics in an event?
     
  14. agraham

    agraham Expert Licensed User

    Just draw in the event. Keep any initialisation outside, or at least do it only once at the beginning of a gesture.
     
  15. francoisg

    francoisg Active Member Licensed 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!
     
  16. agraham

    agraham Expert Licensed User

    If you know the area to be redrawn Invalidate2 or Invalidate3 will be more efficient instead of invalidating the entire activity surface.
     
  17. francoisg

    francoisg Active Member Licensed 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!
     
  18. agraham

    agraham Expert Licensed User

    Version 1.1 now posted fixes a silly bug in findPointerIndex found by Erel. :eek:
     
  19. acorrias

    acorrias Member Licensed 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.
    Code:
    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, 00100%x100%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(
    00120dip20dip + RowHeight * 10)
       
    Activity.AddMenuItem("Clear""mnuClear")
       BrushSize=
    2 :    MinInterFingerDist=60
    End Sub
    Sub mnuClear_Click
       
    Dim r As Rect
       r.Initialize(
    00100%x100%y)
       
    Canvas.DrawRect(r, Colors.Transparent, True0'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, True0'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, 10dip20dip , 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, 10dip20dip + 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: Aug 3, 2011
  20. Erel

    Erel Administrator Staff Member Licensed User

Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice