1

I am going to implement a customized shape of control like a D-PAD for my Android application.

enter image description here

As you can see from the picture, there are 5 control buttons. But everyone knows that a view's touch area is a rectangle. My target is to fire the correct touch event when user is touch inside the visible bounds of each control.

My primitive idea is to intercept the touch event and do some pure geometric computation. But I found it is somehow every complicated and not seem a good way to solve this problem.

Is there anyone could give me some inspiration?

Robin
  • 10,052
  • 6
  • 31
  • 52

2 Answers2

3

There is not a function that allows you to do that. Either you slice your shapes in simple geometrical sections and test, or maybe you can use the technique with a bitmap mask described in this link.

EDIT:

  1. Translate both the click point and the center of your circle to the origin
  2. Calculate the radius of the click point sqrt(x^2 + y^2)
  3. If the radius is greater than the radius of the inner circle and less than the outer radius... continue
  4. Calculate the angle arctan(y/x) to get which one of the four buttons was hit.
Community
  • 1
  • 1
Merlevede
  • 8,140
  • 1
  • 24
  • 39
  • I have already considered bitmap pixel color peeking, but it seems to complicated and cpu/memory killing when I want too use a colorful d-pad – Robin Mar 05 '14 at 05:31
  • OH I see. I think the geometrical computation is not that difficult (well, depends on your background of course). – Merlevede Mar 05 '14 at 05:35
  • Yes I see, is this sqrt/arctan too heavy if I need to test every touch event during a move action? – Robin Mar 05 '14 at 06:08
  • Oh no, absolutely not!!! You could do arctan() more than 500 times for each touch event and you wouldn't notice. The smooth scrolling and de-acceleration of a scrollbar has much more math operations on every touch event. – Merlevede Mar 05 '14 at 06:09
0

You could stay with one image and color each section as follows:

  • Up: RGBA: #FFFFFFFE (alpha 254)
  • Right: RGBA: #FFFFFEFF (blue 254)
  • Down: RGBA: #FFFEFFFF (green 254)
  • Left: RGBA: #FEFFFFFF (red 254)
  • Circle: RGBA: #FFFFFEFE (blue 254 alpha 254)

You'll need to decompress the dpad to a raw bitmap to read the pixel quickly (don't use glReadPixels), but that is a one time operation.

I'd highly recommend overlaying the border, arrows and any special coloring on top as a second texture.

To do this, get the pixel out of the texture for the dpad image at the touch point. If it's alpha is 0, it's a miss, otherwise you can simply check the RGBA value to determine which region was hit. Visually, these values should make no different on appearance.

The advantage of this approach is that it is very precise and can handle any D-Pad shape you can think of. The accepted answer obviously works, but doesn't handle other shapes.

jjxtra
  • 20,415
  • 16
  • 100
  • 140