Android Question panel touch question

DPaul

Active Member
Licensed User
Longtime User
Hi, a "programming" question.

I can put a canvas on a panel and detect "touches" , finger down and up, x and y coordinates.
OK.
Imagine that my canvas is divided into areas, with lines visible across it.
Now i want to know which "area" was touched.

Question: i can do this with IF statements, style "if x < than ... and Y >... etc ", that is tedious.
It would be easier if i could do a select case, with some kind of "between" statements.
I think that is not possible, unless there is some B4A function i am unaware of.
Thanks for any advice.
Paul
 

DPaul

Active Member
Licensed User
Longtime User
Thanks, but I know this lib.
It does not provide a programming shortcut for what i want to do.

Paul
 
Upvote 0

ronell

Well-Known Member
Licensed User
Longtime User
did you already try this?
B4X:
Sub Panel1_Touch (Action As Int, X As Float, Y As Float)
  
    Select Action
        Case Activity.ACTION_DOWN
            If x > 0 And x < Panel1.Width/2 And y > 0 And y < Panel1.Height/2 Then
                Log("1st part")
            Else if X > Panel1.Width/2 And x < Panel1.Width And y > 0 And y < Panel1.Height/2 Then
                Log("2nd part")
            else if x > 0 And x < Panel1.Width/2 And y > Panel1.Height/2 And Y < Panel1.Height Then
                Log("3rd part")
            else if x > Panel1.width/2 And x < Panel1.Width And y > Panel1.Height/2 And y < Panel1.Height Then
                Log("4th part")
            End If
    End Select
  
End Sub
 
Upvote 0

DPaul

Active Member
Licensed User
Longtime User
Also thanks,

I'm familiar with the above syntax.
I'm just looking for a select case "between" statement of sorts.
That would shorten the code, and I believe, is more efficient than "if" statements,
(although i do not know if that is true in B4A.)

Guess it does not exist.:(

Paul
 
Upvote 0

eps

Expert
Licensed User
Longtime User
How do you mean buttons cannot change shape at runtime?

Do you mean that you want something other than a square or rectangle?

or are you saying that the buttons need to resize as opposed to change shape? In which case they can.

ETA : something like this...

B4X:
panel_mainmenu.AddView(1_button, 0, 0, 48%x, 45%y - 30dip)
 
Upvote 0

DPaul

Active Member
Licensed User
Longtime User
OK, i do understand that doing buttons instead of virtual squares on a panel,
solves the immediate problem of knowing which area has been pressed.
I've tried that, but all goes well with 4 or so, it gets more complicated to manage with 20 of different shapes.

If i draw shapes on a panel, i have ultimate flexibility also at runtime, to add/remove other shapes,
to change color of the lines, etc..., in function of the pressed one.

I only have to discover which one is pressed, and i'm trying to find the syntax with the least amount of code.
That's all.

Paul
 
Upvote 0

eps

Expert
Licensed User
Longtime User
Okay.... what are you actually trying to do?

Have you thought of using ScrollView or ULV from @Informatix ? Maybe this will help? Sorry I mistakenly thought you were attempting to create a menu of some description, but maybe not?
 
Upvote 0

JordiCP

Expert
Licensed User
Longtime User
If squares are regularly spaced and for instance, there are 5 horizontal x 6 vertical each one with width=WSQ and height HSQ, then

Assign them an index (from left to right and up to down with 0,1,2)..... and define the following values

WSQ,HSQ --> width and height of each square
X0,Y0 --> Horizontal and vertical offset of the first square in each column and row
HDIST, VDIST --> horizontal and vertical distance between squares

(not tested, there may be some syntax errors)
B4X:
Sub Panel1_Touch (Action As Int, X As Float, Y As Float)

  Dim index as Int =-1
  For row = 0 to maxSquaresPerRow-1
    For col= 0 to maxSquaresPerColumn-1
      if X>= X0 + col*HDIST AND X<X0 + col*HDIST + WSQ AND Y>= Y0 + row*VDIST AND Y<= Y0+row*VDIST + HSQ Then
          index = maxSquaresPerRow * row + col
      End if
    Next
  Next
  If index>=0 then
     'You got it! --> do something with it
  End if

End Sub
 
Upvote 0

DPaul

Active Member
Licensed User
Longtime User
Thanks for all the help.
a) Unfortunately the shapes may include triangles, or even trapezoids, so there's a challenge.
b) Hotspots are tempting, but you seem to need a panel for each one.

As i said, i'm looking for coding efficiency, and i've picked up a few ideas from the above.
Still need to do some thinking though.

I could color each space in a different color, and retrieve the BG color.
That would be fast, but it is not going to work for obvious reasons.

Paul
 
Upvote 0

JordiCP

Expert
Licensed User
Longtime User
I could color each space in a different color, and retrieve the BG color.
You were quite near to it with this sentence...:eek:

Have a mutable bitmap with the same dimensions in which you draw the same shapes as with the first one, but with color ARGB(0,0,0,1), ARGB(0,0,0,2) .....
So there won't be color restrictions with the visible panel.
B4X:
Sub Panel1_Touch (Action As Int, X As Float, Y As Float)
   Select Action
      Case Activity.ACTION_DOWN
         selectedIndex= mySecondPanel.getPixel(X,Y)
   End Select
End Sub
 
Upvote 0

DPaul

Active Member
Licensed User
Longtime User
Mutable bitmaps: sound very sexy. :)
I'm going to try them immediately.
Will let you know if they achieve the goal !
thx,
Paul
 
Upvote 0

DPaul

Active Member
Licensed User
Longtime User
Hi,

I almost got this working...but i may have a problem with the statement sequence:
This code puts a smaller blue rect on a green rect (on a panel with the same size)
If i start with cvs.initialize(pnl), the .getpixel actually produces the right results (blue and green),BUT... i see no drawing.
if i put cvs.initialize(pnl) where the xxxxxx are, i see the drawing, but the getpixel gives zeros instead of the colors.

.......
cvs.Initialize(pnl)
bmp.InitializeMutable(780dip, 440dip)
cvs.Initialize2(bmp)
'xxxxxxxxxxx
cvs.DrawColor(Colors.Green)
Dim rect1 As Rect
rect1.Initialize(195dip,210dip, 585dip,310dip)
cvs.DrawRect(rect1, Colors.blue, True, 0)

pnl.Invalidate

I've tried multiple combinations, but either i get the pixels, or the drawing, i would like both at the same time :(

Paul
 
Upvote 0

JordiCP

Expert
Licensed User
Longtime User
You need two canvas, one assotiated to the panel and the other to the bitmap.

Then perform the same operations on both
 
Upvote 0

DPaul

Active Member
Licensed User
Longtime User
You need two canvas, one assotiated to the panel and the other to the bitmap.
Then perform the same operations on both

Woooww... this is it!
No more if... x> and y< or and else.........needed!
One click and you can identify the area on the panel.
Limitless possibilities, maybe even replace simple views that also drift around on my panel!
From a style point of view, that is also a plus!

I will buy you a drink if we ever meet!
Muchas Gracias!
Pablo
 
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
May I suggest you to convert your solution into a class (compilable to lib) and share it...
It seems quite interesting
 
Upvote 0

DPaul

Active Member
Licensed User
Longtime User
May I suggest you to convert your solution into a class (compilable to lib) and share it...
It seems quite interesting
Hi,

I am not sure if that is possible /useful.
The core of the whole thing are the few lines of code above,
the rest is application specific logic.

Let me finalize the whole setup, and find out what the best way of doing things is.
e.g. how will i differentiate between the colors. In my case, the colors will all look the same on the screen,
because internally they will vary by only 1 point. (R, G or B?) What least affects the color. (probably the smallest value = dark)
If i choose R, i must make sure there are no other squares with the same R etc..

Is a select case the way to go ?
Or, as Jordi seems to suggest in post #14, some kind of list would be easier / faster ?
I have some work to do. ;)
Paul
 
Upvote 0
Top