touchscreen: distinguish start of scroll from tap - language-agnostic

I'm writing something for a touchscreen phone. I'd like the program to run a specified function when the user taps on the screen. I'd like to scroll the screen when the user drags a finger up or down the screen.
The OS has three relevant callback functions (1) detect when screen is touched, (2) detect when finger is dragged on screen and (3) detect when the finger leaves the screen. In each case, the callback function gets the screen coordinates where the relevant event happened.
The problem is that a drag obviously starts with a finger touching the screen and ends when the finger leaves the screen. Tapping is usually detected as a touch, very short drag and end touch. If I just call my specified function on a tap, I'll trigger on screen drag events rather than genuine taps.
The best I can think of is to mark the time or location when the user first touches. If we are in the drag callback function a short time or distance later, treat it as a scroll. Otherwise, if there's been a leave-the-screen callback, treat it as a tap. Issues include the cost of noting the time, deciding how much time or distance to use as a trigger and if there is a better general approach.
My app is in python for a symbian device. As that's not a very popular platform, any suggestions for the best way to implement would be appreciated.

The best approach I can think of is:
Touch callback: set action_location = drag_location = current_location (current_location reported by os)
Un-touch callback: if action_location within distance_threshold (e.g., 20 or 25 pixels) of current_location, execute action
Drag callback: if drag_location more than distance_threshold from current_location, scroll and set drag_location = current_location

Related

Handling a keyboard event in one place for the whole program

I'm creating a little developer console for an AS3 AIR application, I'm wanting F12 to add the toggle the display of the console screen but I don't want to litter my program with a bunch of calls to the Console to show or hide it, I also don't really want to be re-creating the console on different screens of my application.
I'm wondering if there's a way or a place I can put my keyboard event to toggle the display that will handle it across the entire application? At the moment I've tried putting it into my Main class which calls the first screen in the hopes that would be able to handle it but as soon as I click on another screen my eventListener isn't called.
Any ideas?
You could add your event listener to FlexGlobals.topLevelApplication instead of specific views, this would achieve the reduction you require
For true application level keyboard handling, attach the listener on the NativeApplication.nativeApplication object.
NativeApplication.nativeApplication.addEventListener(KeyboardEvent.KEY_DOWN, toggleDevConsole,false,0,true);
Attaching the listener to the stage will only work when that particular stage (window) has the focus. This will become an issue if your application has multiple windows that require interaction.
For single window applications, either will work.
Woops, I'm not quite with it today!
For future reference I added the event listener to the Stage in my Main function and it's being picked up every time.
stage.addEventListener(KeyboardEvent.KEY_DOWN, toggleDevConsole, false, 0, true);

as3: mouse_move event in full screen mode and mouseLock on slow mouse movements

With flash and AS3 it seems to be a problem with mouse move event in full screen mode and mouseLock activated that I don't understand how to solve.
When I enter in full screen mode with Stage.mouseLock property enabled and i make very slow movements with the mouse, the two properties to determine the location of the mouse (MouseEvent.movementX and MouseEvent.movementY) return zero (0).
A print of the event event.toString() returns:
[MouseEvent type="mouseMove" bubbles=true cancelable=false eventPhase=2 localX=0 localY=0 stageX=0 stageY=0 relatedObject=null ctrlKey=false altKey=false shiftKey=false buttonDown=false delta=0]
"The mouse can be moved as far as I want always returning 0 for x and y if the mouse are moved very slow, so it's impossible to determine the movement of the mouse." (*) After a better test I've added a correction of this sentence, below in the "Note".
It's very strange because the event are fired correctly when the mouse is moved (also with slow movements), but the returning movement is 0. Seems like the movement is < 1 but are reported only integer movements, so the values are always returned 0.
I've tried also changing mouse settings of OS (Mac OSX) without success.
If you want I can give you sample code to enter in fullscreen mode and activate Stage.mouseLock properties.
Thank you for any suggestion.
Note:
After testing better I've found that flash player (my flash player version is 11,7,700,203) has a behavior that looks like a bug: if the current mouse movement (movementX and movementY) is equals to the previous movement, than flash return movementX=0 and movementY=0. The next mouse movement will be the correct value because it will be different from zero.
Because of this, with a constant movement always in the same direction (with a very slow movement is easier to reproduce), the player show "zero values" every two events fired.
At this link you can test a working example (faster than code yourself an example).
If the behavior I've found is correct, than it's easy to modify the code to rectify this problem, anyway IMHO it remain a bug. I'll report it to adobe.
At this other link (thank you to #nemostein) there is another working example.
I try to explain me better: if you move the cursor very slowly (i.e. to the right direction) you'll receive the output Movement( X:1 Y:0 ) when you move the cursor enough. If you move again the cursor enough to the right you'll receive the output Movement( X:0 Y:0 ). If you repeat the micro movements you'll receive the movements report always with this pattern: (x:1,y:0),(x:0,y:0),(x:1,y:0),(x:0,y:0)... instead of (x:1,y:0),(x:1,y:0),(x:1,y:0)...
I think it's wrong to receive a movement like (x:0,y:0) and seems to me that this values are returned every time when you make a movement equals (both the x and the y) to your previous movement.
I hope this is understandable.
There is no bug, but the MouseEvent.movementX/Y (alongside with MouseEvent.localX/Y and MouseEvent.stageX/Y) are somewhat misleading...
Although they are Numbers, not ints, there is no such thing like "half pixel", so they always reports int values.
The precision you're looking for (e.g.: movementX == 0.75) can't be achieved.
I couldn't reproduce the behavior you described at the note ("current mouse movement equals to the previous") and here is a working example of Stage.mouseLock = true and Stage.displayState = StageDisplayState.FULL_SCREEN.
Note that if you move the cursor very slowly you'll, eventually, receive an MouseEvent.movementX/Y == 1 (when you moved the cursor enough).
I've asked in adobe forum and they told me to open a bug.
Here is the link: https://bugbase.adobe.com/index.cfm?event=bug&id=3575123

How can I detect the number of fingers used in a swipe gesture?

My intention is to have different gesture-based actions occur depending on whether the user swipes the screen with one or two fingers. I'm a little new to touch app development and I'm not seeing the necessary information in either Manipulation events or the Toolkit GestureService. I'm fine with using more low-level touch logic or manually tracking the number of touch contacts if necessary, I just need a little guidance on how to differentiate single from double-touch in a gesture.
This may help you to resolve your problem. There is property to find the second touch point in the gesture panel.
GestureSample sample = TouchPanel.ReadGesture();
Vector2 first = sample.Position;
Vector2 second = sample.Position2;
Position2 property will return the seocond touch position in the Gesture panel.

Using TOUCH BEGIN/MOVE/END to create TAP / SWIPE events for four concurrent users

I'm using a multi-touch screen for making an interactive presentation with Adobe AIR and four people is going to use the screen at once.
I've done some testing with MouseEvent (which works fine with one user) and I think that replacing that event with my own that can handle multiple users is the way to go, or did I miss something here?
Theres some work creating that event so i'd love some input, thanks.
You need to set the inputMode to use multi-touch, then you'll want to be listening for TouchEvents instead of MouseEvents (believe for a single point at least it will still dispatch the MouseEvent, not sure if this is true for multiple touches though).
http://help.adobe.com/en_US/flex/mobileapps/WSe11993ea1bd776e5-13e27e4812a431dbafc-8000.html
flash.ui.Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;

Adobe AIR: touch screen doesn't trigger mouse down event correctly

i have designed a gaming kiosk app in as3
i am using it on a Sony vaio l pc (like hp's touchsmarts) in windows 7
the app doesn't need any multi-touch gestures (only single touch clicks and drags) so i am using mouse events
everything is fine (including mouse click and move events) except that a single touch to the screen (with no move) doesn't fire a mouse down. it is fired only after a small move of the finger
outside the app, on my desktop, i see that the small windows 7 cursor jumps immediately to where a finger is placed, meaning this issue isn't a hardware or a windows problem but rather how internally the flash app receives "translated" touch-to-mouse events from the os.
for example, in a windows Solitaire game, a simple touch to the screen immediately highlights the touched card.
in my app, a button will change to the down state only if i touch it and also move my finger slightly (click events - down and up - are triggered fine)
shouldn't the MOUSE_DOWN event trigger exactly like how a TOUCH_BEGIN would in the new touchevent class?
any ideas?
I encountered the same problem.
Setting the Multitouch.inputMode property to MultitouchInputMode.TOUCH_POINT (the default value is MultitouchInputMode.GESTURE) appears to make the MOUSE_DOWN event dispatch when the user touches the screen and not when they touch and move or touch and release.
If the cursor moves when they touch, then I assume the OS is just registering this as a MOUSE_MOVE and not a MOUSE_DOWN. Since it's a touchscreen, you could just consider MOUSE_MOVE a click since the user probably isn't actually dragging their finger around creating a real MOUSE_MOVE event.
Well, if they are actually dragging their finger around for stuff then you could assume a MOUSE_MOVE that suddenly places the cursor on a button (with no prior MOUSE_MOVE i.e. dragging), it's a MOUSE_DOWN.
Just bought a new touchscreen and encountered the problem again.
So the solution is to set Multitouch.inputMode to MultitouchInputMode.TOUCH_POINT by writing anywhere in your code:
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
Notice, that it does not work when testing by Ctrl+Enter in Flash Editor (at least in CC 2015). So, for example, you need to open .SWF separately in Flash Player.
EDIT: But it does work in Debug mode! (Ctrl+Shift+Enter)