B4A 1.92 and panel issues

NJDude

Expert
Licensed User
Longtime User
Ok, the attached sample shows the problem I'm having with panels after upgrading.

Version 1.90:

Tapping on the panels plays the sound and registers the shot.

Version 1.92:

It plays the sound and registers the shot only if tapping on Panel1.

The way 1.90 is doing it is ideal for the application I'm developing (which is done, I'm in the process of testing it), I got scared when it didn't work, this is a paid app that I have to deliver soon to a customer.
 

Attachments

  • PanelProblem192.zip
    37.4 KB · Views: 315

Erel

B4X founder
Staff member
Licensed User
Longtime User
Due to the change in Android 4.0.3 it is no longer possible to return a value from Panel_Touch. Previously if you didn't return True from this event then the ACTION_MOVE and ACTION_UP touch events were not sent. Now they are always sent.

The solution is simple.
You should only act when action = Activity.ACTION_DOWN:
B4X:
Sub Panel1_Touch(Action As Int, X As Float, Y As Float) 
   If Action = Activity.ACTION_DOWN Then
      Dim DestRect As Rect
      shot.Play(Bang, 1, 1, 4, 0, 1)
      DestRect.Initialize(X - 15dip, Y - 15dip, X + 15dip, Y + 15dip)
       cBullseye.DrawBitmap(Bullet, Null, DestRect)
      Panel1.Invalidate
   End If
End Sub
 
Upvote 0

bparent

Member
Licensed User
Longtime User
I added that to my project and didn't work, it seems I'll have to keep this particular project locked on 1.90. :confused:

I am having what I think is a similar problem. The code below works as expected on V1.90, but does not show the Button click positions on the label in V1.92.

'Activity module
Sub Process_Globals 'These global variables will be declared once when the application starts.
'These variables can be accessed from all modules.
End Sub
Sub Globals 'These global variables will be redeclared each time the activity is created.
'These variables can only be accessed from this module.
Dim TransparentPanelOnTop As Panel
Dim Button1 As Button
Dim Button2 As Button
Dim Label1 As Label
Dim PositionX As Float
Dim PositionY As Float
End Sub
Sub Activity_Create(FirstTime As Boolean)
Label1.Initialize("Label1")
Button1.Initialize("Button1")
Button2.Initialize("Button2")
TransparentPanelOnTop.Initialize("TransparentPanelOnTop")
Label1.Text = "Waiting for click..."
Button1.Text = "I am a Button1 CLICK ME"
Button2.Text = "I am a Button2 CLICK ME"
Activity.AddView(Label1,10,10,Activity.Width - 20,60)
Activity.AddView(Button1,10,100,Activity.Width - 20,60)
Activity.AddView(Button2,10,180,Activity.Width - 20,60)
Activity.AddView(TransparentPanelOnTop,0,0,100%x,100%y)
TransparentPanelOnTop.Color = Colors.Transparent
TransparentPanelOnTop.BringToFront
End Sub
Sub Activity_Resume
End Sub
Sub Activity_Pause (UserClosed As Boolean)
End Sub
Sub TransparentPanelOnTop_Touch (Action As Int, x As Float, Y As Float) As Boolean 'Return True to consume the event
If Action = Activity.ACTION_DOWN Then
PositionX = x
PositionY = Y
End If
End Sub
Sub Button1_Click
Label1.Text = "You Clicked Button1 with positions : X = " & PositionX & " Y = " & PositionY
End Sub
Sub Button2_Click
Label1.Text = "You Clicked Button2 with positions : X = " & PositionX & " Y = " & PositionY
End Sub
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Panel_Touch can no longer return a result. It now behaves as if you always return true. This means that the panel will consume the touch event.
The solution is to use Reflection library:
B4X:
Sub Process_Globals 'These global variables will be declared once when the application starts.
'These variables can be accessed from all modules.
End Sub
Sub Globals 'These global variables will be redeclared each time the activity is created.
'These variables can only be accessed from this module.
   Dim TransparentPanelOnTop As Panel
   Dim Button1 As Button
   Dim Button2 As Button
   Dim Label1 As Label
   Dim PositionX As Float
   Dim PositionY As Float
End Sub
Sub Activity_Create(FirstTime As Boolean)
   Label1.Initialize("Label1")
   Button1.Initialize("Button1")
   Button2.Initialize("Button2")
   TransparentPanelOnTop.Initialize("") 'remove the event name parameter
   Label1.Text = "Waiting for click..."
   Button1.Text = "I am a Button1 CLICK ME"
   Button2.Text = "I am a Button2 CLICK ME"
   Activity.AddView(Label1,10,10,Activity.Width - 20,60)
   Activity.AddView(Button1,10,100,Activity.Width - 20,60)
   Activity.AddView(Button2,10,180,Activity.Width - 20,60)
   Activity.AddView(TransparentPanelOnTop,0,0,100%x,1 00%y)
   TransparentPanelOnTop.Color = Colors.Transparent
   TransparentPanelOnTop.BringToFront
   Dim r As Reflector
   r.Target = TransparentPanelOnTop
   r.SetOnTouchListener( "TransparentPanelOnTop_Touch")
End Sub
Sub Activity_Resume

End Sub
Sub Activity_Pause (UserClosed As Boolean)

End Sub
Sub TransparentPanelOnTop_Touch (viewtag As Object, Action As Int, x As Float, Y As Float, motionevent As Object) As Boolean 'Return True to consume the event
   If Action = Activity.ACTION_DOWN Then
      PositionX = x
      PositionY = Y
      Return False
   End If
End Sub
Sub Button1_Click
   Label1.Text = "You Clicked Button1 with positions : X = " & PositionX & " Y = " & PositionY
End Sub
Sub Button2_Click
   Label1.Text = "You Clicked Button2 with positions : X = " & PositionX & " Y = " & PositionY
End Sub

You should make sure not to call DoEvents or Msgbox inside this event as it will fail in Android 4.0.3 and above.

Note that you should post code with [ code ] tags.
 
Upvote 0

bparent

Member
Licensed User
Longtime User
Panel_Touch can no longer return a result. It now behaves as if you always return true. This means that the panel will consume the touch event.
The solution is to use Reflection library:

You should make sure not to call DoEvents or Msgbox inside this event as it will fail in Android 4.0.3 and above.

Note that you should post code with [ code ] tags.

Thanks for the reply. Do you have an example of how to use the Reflection library to handle the touch event?
Also, with regard to using the [ code ] tags, is there a way to copy the code without losing the formatting? When I try to select and copy code within [ code ] tags so that I can test the code I end up having to tediously enter returns in the Basic IDE so I can run the code.
 
Upvote 0

Roger Garstang

Well-Known Member
Licensed User
Longtime User
Also, with regard to using the [ code ] tags, is there a way to copy the code without losing the formatting? When I try to select and copy code within [ code ] tags so that I can test the code I end up having to tediously enter returns in the Basic IDE so I can run the code.

Switch browsers (Firefox works fine). IE is horrible for keeping to standards as well as handling the clipboard data. There has been a long standing bug in how it handles the contents copied. I can't remember the details but clipboards usually capture multiple types of data when you copy like Plain Text, Rich Text, HTML, etc so when pasted applications can grab the type of data they need. If I recall correctly IE did something like only copying Rich Text or HTML to the clipboard and didn't put Plain Text data, so whitespace formatting gets lost.
 
Upvote 0

bparent

Member
Licensed User
Longtime User
The reply you quoted had the example at the end of the ACTIVITY_CREATE sub. The named sub is what then gets called like any other event. I use this to get LongPress functionality on a spinner, etc.

Thanks Roger. I did not notice those lines added. Guess it is hard to highlight added code within [ code ] tags. I also noticed the signature within the TransparentPanelOnTop_Touch(viewtag As Object, Action As Int, x As Float, Y As Float, motionevent As Object) sub has changed from the routine I had copied from another thread.

Maybe this is another caveat with borrowing code and using the Reflection library, events, the wiki, etc. It seems the wiki shows a different signature for the event?
 
Upvote 0

bparent

Member
Licensed User
Longtime User
Switch browsers (Firefox works fine). IE is horrible for keeping to standards as well as handling the clipboard data. There has been a long standing bug in how it handles the contents copied. I can't remember the details but clipboards usually capture multiple types of data when you copy like Plain Text, Rich Text, HTML, etc so when pasted applications can grab the type of data they need. If I recall correctly IE did something like only copying Rich Text or HTML to the clipboard and didn't put Plain Text data, so whitespace formatting gets lost.

You are right. IE can be a pain, but at work that is the default browser. Firefox works better as you indicated. Thanks again. Learning new things everyday from helpful people like yourself and Erel.
 
Upvote 0

CarlM

Member
Licensed User
Longtime User
Also, with regard to using the [ code ] tags, is there a way to copy the code without losing the formatting? When I try to select and copy code within [ code ] tags so that I can test the code I end up having to tediously enter returns in the Basic IDE so I can run the code.

I select the code, copy and paste into MS Word (v10). Re-select it in Word then copy and paste into B4A.
(It sounds more effort than it actually is).
 
Upvote 0

Roger Garstang

Well-Known Member
Licensed User
Longtime User
Panel_Touch can no longer return a result. It now behaves as if you always return true. This means that the panel will consume the touch event.

Is this statement still accurate in the most recent version? I made a semi-transparent black panel as a fullscreen background for a textbox to have the user type a value in (Sort of a dimmed background effect like a msgbox, etc). I noticed I could click and interact with things under the panel which created problems. I thought I was going to have to put checks in all the button click and tab changes, etc to prevent interaction when this panel was showing. I decided just to try creating a panel touch event sub and returned true and now no interaction is allowed. So, was this change reversed and another way found to prevent the recycled errors or is something wrong?
 
Last edited:
Upvote 0

Roger Garstang

Well-Known Member
Licensed User
Longtime User
So, what does that mean for my situation? The panel wasn't "eating" the touch events as they were still being passed on to the activity/views below it, and returning true caused it to work properly and not pass them on when it was stated a return value did nothing now and it should have already behaved as though true was passed...
 
Upvote 0

Roger Garstang

Well-Known Member
Licensed User
Longtime User
How were you testing it? If you had a Touch Event sub...even an empty one it behaves the same as if True was returned. I had no Event Sub. So, it appears that the internal code only executes the way mentioned if there is an Event Sub. So, a panel doesn't behave as if you always return true to the touch event, the event behaves as if you always returned true (And there must be an event).

May want to add a property or something like BubbleEvent that can be set to true or false and determine if the event gets passed to parent.
 
Upvote 0
Top