11-16-2009 09:46 AM
I am having a problem getting scrolling working on a touchscreen device. The problem I am encountering is that something is consuming my touchEvent, but it isn't one of my classes. I need a better understanding of how the touchEvent cascades through the screen stack so I can compensate for this. Does anybody have a link to a helpful article?
My code is structured like this:
MainScreen holds a...
VerticalFieldManager which holds a...
HorizontalFieldManager which holds a...
VerticalFieldManager which holds a...
bunch of LabelFields and custom buttons that exceed the display size of the screen.
I've overridden touchEvent in each of the managers with code that simply logs the true/false result of super.touchEvent(x) and returns the same value.
The behaviour I'm seeing is:
-When I touch and move the screen the label gains focus and all my overridden touchevents return false ... and scrolling does nothing.
-When I touch a label that is only partially on the screen the label gains focus and all my overridden touchEvents return true ... and scrolling works.
The question I am trying to answer is:
How does the API determine who received or consumed the touchEvent? Does the manager get a chance to consume the event before the fields it contains, or does the event system flow the other way with child fields firing before managers?
I'd appreciate any help / advice / resources you can give me.
Thanks in advance,
Solved! Go to Solution.
11-16-2009 02:54 PM
My understanding is that the touch event go the field under focus even if you touch outside the field. It is developer's responsibility to detech that the touch has happened outside the field extent and handle it.
Please do share the solution to your issue and how you went about troubleshooting it.
11-17-2009 09:52 AM
Thanks mb1, you are right. The currently focussed field receives the event. All of it's managers also receive this event in the following recursive stack-type order:
If you have CustomBaseScreen contains Manager1, which contains Manager2, which contains FocusedField then the following results:
CustomBaseScreen.touchEvent() is called...
Manager1.touchEvent() is called...
Manager2.touchEvent() is called...
FocusedField.touchEvent() is called...
...or to phrase it differently, the CustomBaseScreen gets the touchEvent first, but inside its super.touchEvent() it calls the touchEvent on whichever of its children contains FocusedField.
I worked this out by overriding touchEvent and inserting simple logger messages. like this:
logMessage("Class X is starting touchEvent.");
logMessage("Class X is finishing touchEvent.");
So I guess that if I want this to behave like most systems where the object you click on receives the event I will have to:
1) Check if the touch event is outside the borders of the focused field.
2) Figure out what actually exists at the touched location
3) Call touchEvent for the field at the touched location.
11-17-2009 10:52 AM
Almost forgot ....
The original scrolling problem I was having ended up not being related to the touchevent itself at all. I had forgotten to call setVirtualExtent(...) in my manager.sublayout() override. (I had only called setExtent(...) ) Using the trackball you can scroll just fine without setVirtualExtent; using the touchscreen, not so much.
03-02-2010 08:50 PM
May I be the first to suggest, that this is the most retarted way of handling a touchEvent I could have ever thought of? If I override touchEvent in one of my fields, you'd better darn make sure my field gets notified of a touchevent on it.
I know there are VERY likely underlying factors that lead to this behavior, but because of this setup, I'm having to spend a couple of hours to refactor my class, so that I can properly handle this in all of my fields.
Sorry; this is completely retarted.
Hopefully someone looks at it and gets this resolved.
03-18-2010 11:33 PM - edited 03-18-2010 11:35 PM
So I finally got around to getting my problem fixed.
Here's what you should watch out for, if you come across this problem:
1. You don't need to override anything in your managers. However, if you're moving your fields around; or doing anything useful for that matter on your Manager's sublayout method, start off by calling layoutChild on all of your fields, then call setPositionChild on all of your fields and setExtent only at the end.
2. Each of your fields should check to see if the touch happened on it. You do this, by callin getX(1), getY(1) on the TouchEvent and then ensuring that x >= 0 && x <=getWidth() && y >= 0 && y <= getHeight().
- If the coordinate falls within these ranges, you can handle the event and return TRUE.
- If the coordinate is negative or is greater than this field's extent, you need to return FALSE, so that another field can check [delegate].
I hope this at least provides someone with a hint. In my case, both were issues, though my biggest problem was #1. Some buttons were getting the touch events and some weren't which had me pulling what little hair I had left out. The most useful way of finding out what was going on I found was to simply add a border to my manager. I could then see where my buttons were being layed out vs. where my manager was being layed out. In my case, my buttons were being layed out way beyond the bounds of the manager, which is why they weren't receiving my touch events.
BTW, I still think it's retarted!