Could someone explain this Multitouch Example issue....

PaulR

Active Member
Licensed User
Longtime User
Hi

I am using code from the Multitouch Example in an app, and after changing/moving bits of code to Subs I am seeing an issue I don't understand.

Using just the Multitouch Example code I can replicate.

Here's the Multitouch Example code with the only changes being that some of the code has been moved to a subroutine and the p As Point variable is declared in Sub Process_Globals instead of Sub GesturesTouch.

B4X:
'Activity module
Sub Process_Globals
   Dim p As Point '*** this was declared in Sub GesturesTouch in orig 
End Sub

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, Color As Int)
   Dim Canvas As Canvas
   Dim RowHeight As Int
   Dim TextSize As Float
   TextSize = 18
   Dim TextRect As Rect
   
End Sub

Sub Activity_Create(FirstTime As Boolean)
   'Create a panel and add it to the activity
   bgd.Initialize("")
   Activity.AddView(bgd, 0, 0, 100%x, 100%y)
   Canvas.Initialize(bgd)
   'Add a listener for this panel   
   G.SetOnTouchListener(bgd, "GesturesTouch")
   TouchMap.Initialize
   
   RowHeight = Canvas.MeasureStringHeight("M", Typeface.DEFAULT, TextSize) + 5dip
   TextRect.Initialize(0, 0, 120dip, 20dip + RowHeight * 10)

   Activity.AddMenuItem("Clear", "mnuClear")
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 Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

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  '*** this was uncommented in original
   Select Action
      Case G.ACTION_DOWN, G.ACTION_POINTER_DOWN
         'New Point is assigned to the new touch
         p.Id = PointerID
         p.Color = Colors.RGB(Rnd(0, 255), Rnd(0, 255), Rnd(0, 255))
         TouchMap.Put(PointerID, p)
      Case G.ACTION_POINTER_UP
         TouchMap.Remove(PointerID)
      Case G.ACTION_UP
         'This is the end of this gesture
         TouchMap.Clear
   End Select
   
   DrawPointValues       '***** exact code from Sub DrawPointValues was here *****
   
   bgd.Invalidate
   Return True
End Sub

Sub DrawPointValues
   'Clear the previous text
   Canvas.DrawRect(TextRect, Colors.Transparent, True, 0)
   Dim px, py As Int
   For i = 0 To TouchMap.Size - 1
      p = TouchMap.GetValueAt(i)
      px = G.GetX(p.id)
      py = G.GetY(p.id)
      Dim s As String
      s = p.Id & ": " & px & " x " & py
      Canvas.DrawText(s, 10dip, 20dip + i * RowHeight, Typeface.DEFAULT, TextSize, p.Color, "LEFT")
      If p.prevX > 0 AND p.prevY > 0 Then
         Canvas.DrawLine(p.prevX, p.prevY, px, py, p.Color, 5dip)
      End If
      p.prevX = px
      p.prevY = py
   Next
End Sub

The issue is that when the code from Sub DrawPointValues is in the original place the display code works, displaying the co-ordinates of the touches.

When the code is moved to a subroutine and p is declared somewhere else, all the values for all points are the values of the last point touched.

What am I missing?
 

PaulR

Active Member
Licensed User
Longtime User
Ah right, thanks very much... that's it working now I am declaring p As Point back in the GesturesTouch. I assumed Map held the contents instead of a reference.

I've read up on how objects are handled automagically in Java and it's clearer now what's happening.
 
Upvote 0
Top