Using TouchMove (swipe, velocity) [[SOLVED]]

Got a LiveCode personal license? Are you a beginner, hobbyist or educator that's new to LiveCode? This forum is the place to go for help getting started. Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller

Post Reply
William Jamieson
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 212
Joined: Fri Feb 01, 2013 1:31 am
Contact:

Using TouchMove (swipe, velocity) [[SOLVED]]

Post by William Jamieson » Wed Dec 24, 2014 12:18 am

How do you detect swipes with Android? I am trying to calculate the velocity of the motion of the finger on the screen.

I tried to get two iterations of the loc of the target when I touch the target using

Code: Select all

on TouchMove pID, pX, pY
put line 2 of sTouchTimer into line 1 of sTouchTimer
put the millisecs & comma & pY into line 2 of sTouchTimer
end TouchMove
This creates a variable with two lines, each representing a point in time and a y-coordinate. However, the message only gets sent every 140 milliseconds and is typically not enough to pick up a contact that lasts only 100 milliseconds giving a variable with only one coordinate

I tried to use this to pick up a just in case coordinate

Code: Select all

on TouchMove pID, pX, pY
put line 2 of sTouchTimer into line 1 of sTouchTimer
put the millisecs & comma & pY into line 2 of sTouchTimer
send "TouchMoveRecording" to me in 10 milliseconds
end TouchMove

on TouchMoveRecording
   put the milliseconds & comma & item 2 of the mouseloc into sTouchMoveRecording
end TouchMoveRecording

function GetBackupTouchRecording  --I use this function to get a second point for my velocity equation
   return sTouchMoveRecording
end GetBackupTouchRecording
The problem with this is that the mouseLoc doesn't update in that time either, so until the TouchMove message gets sent again, the coordinate will be the same.

I tried setting the acceleratedRendering to true with a compositorTileSize of 64 to speed up and graphic processing but that didn't work either.

Has anyone worked with swipe before? Got any ideas?

I will leave a file here so you can put it on your phone and see what I am talking about. Something to compare it to is Google+ app or Facebook app where they use scrolling
[EDIT] They wont allow me to upload my file, but I can email it if requested. Let me know if you think more info is needed.

Thank you for contributing to this thread.

Cheers,

-Will
Last edited by William Jamieson on Tue Dec 30, 2014 11:47 pm, edited 2 times in total.

Klaus
Posts: 14199
Joined: Sat Apr 08, 2006 8:41 am
Contact:

Re: Using TouchMove (swipe, velocity)

Post by Klaus » Wed Dec 24, 2014 1:34 pm

Hi Will,

not an mobile expert, but "touchmove" is the equivalent to the desktop "mousemove",
so you shluld not need teh "TouchMoveRecording" handler at all!

Try this instead:

Code: Select all

on TouchMove pID, pX, pY
  put line 2 of sTouchTimer into line 1 of sTouchTimer
  put the millisecs & comma & pY into line 2 of sTouchTimer
  ##send "TouchMoveRecording" to me in 10 milliseconds
  put the milliseconds & comma & pY into sTouchMoveRecording
end TouchMove

## Not needed, since MOUSEMOVE and TOUCHMOVE are sent in REALTIME!
## on TouchMoveRecording
##   put the milliseconds & comma & item 2 of the mouseloc into sTouchMoveRecording
## end TouchMoveRecording

function GetBackupTouchRecording  --I use this function to get a second point for my velocity equation
   return sTouchMoveRecording
end GetBackupTouchRecording
Hope I understood your problem correctly... 8)

Best

Klaus

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7393
Joined: Sat Apr 08, 2006 8:31 pm
Contact:

Re: Using TouchMove (swipe, velocity)

Post by jacque » Wed Dec 24, 2014 10:16 pm

Touch messages and mouse messages both get sent on mobile, so to avoid branching the code for mobile/desktop, and to make things work the same way on both, I only use mouse messages. It's easier that way.

There is a standard method for detecting swipes. The basic idea is to store the current mouseloc on a mousedown, and get it again on a mouseup. Then compare the two locations to see if they are outside of a range (10 or 15 pixels, or so) and if they are, it's a swipe. You can use the two locations to find out the direction of the swipe as well.

Scroll down about halfway to see an example of swipe code here:
http://lessons.runrev.com/m/4069/l/2960 ... r-the-ipad

This uses touch events, but you could substitute mouse events if you want and get the same thing. Either way will work.
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

William Jamieson
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 212
Joined: Fri Feb 01, 2013 1:31 am
Contact:

Re: Using TouchMove (swipe, velocity)

Post by William Jamieson » Wed Dec 24, 2014 10:23 pm

Hey Klaus!

Thank you for posting your input. I can always use a little Christmas cheer from you in my code. Yes, I agree with you. The TouchMove should be in real time.

I know that the code in the second example may not be the best way as I am struggling to find resolution, but if I remove that as you have it, it just becomes the code in the first example... Which is the problem I am trying to solve.

To re-explain that. Yes, there doesn't need to be a lot of fancy code going on in a touchmove handler, but without doing something different than what I am doing, the code simply doesn't run fast enough, making it so what you wrote and what I wrote both do not work.

Do you think there is a way to speed up the sample rate of the TouchMove handler? Is there processes that I should eliminate from the background??

William Jamieson
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 212
Joined: Fri Feb 01, 2013 1:31 am
Contact:

Re: Using TouchMove (swipe, velocity) [NOT SOLVED]

Post by William Jamieson » Fri Dec 26, 2014 10:26 am

Here is some more clarity on the situation if someone feels like they know what is going on.

Here is the report from the handler nested int the TouchMove handler

("MoveTouch" is the name of the handler in the TouchMove handler)

Code: Select all

1419585507765: List 1: MoveTouch Handler processing in 1 milliseconds ----This is the total time it took to process MoveTouch handler
1419585507765: List 1: The unlock screen in mouseMove is taking 0 Milliseconds ----- This is the total time it is taking to unlock the screen after changing the loc of the grp I am scrolling
1419585507765: List 1: The TouchMove handler is taking 1 milliseconds to process
1419585507780: List 1: MoveTouch Handler processing in 0 milliseconds
1419585507780: List 1: The unlock screen in mouseMove is taking 0 Milliseconds
1419585507780: List 1: The TouchMove handler is taking 0 milliseconds to process
1419585507809: List 1: I am scrolling pY 498 xMid 172 ----Did not start actually moving the grp until this command is sent
1419585507809: List 1: MoveTouch Handler processing in 12 milliseconds
1419585507810: List 1: Scroll recording 1419585507810,498  ----This is the milliseconds and item 2 of the loc of the group
1419585507810: List 1: MoveTouch Scrolling is taking 1 millisecs ---This is the processing that handles repositioning the grp
1419585507882: List 1: The unlock screen in mouseMove is taking 71 Milliseconds
1419585507883: List 1: The TouchMove handler is taking 86 milliseconds to process
1419585507885: List 1: Scroll recording 1419585507885,452
1419585507885: List 1: MoveTouch Scrolling is taking 1 millisecs
1419585507970: List 1: The unlock screen in mouseMove is taking 84 Milliseconds
1419585507970: List 1: The TouchMove handler is taking 86 milliseconds to process
1419585507973: List 1: Scroll recording 1419585507973,418
1419585507974: List 1: MoveTouch Scrolling is taking 1 millisecs
1419585508062: List 1: The unlock screen in mouseMove is taking 88 Milliseconds
1419585508062: List 1: The TouchMove handler is taking 89 milliseconds to process
1419585508066: List 1: Scroll recording 1419585508066,385
1419585508066: List 1: MoveTouch Scrolling is taking 1 millisecs
1419585508171: List 1: The unlock screen in mouseMove is taking 105 Milliseconds
1419585508171: List 1: The TouchMove handler is taking 106 milliseconds to process
1419585508174: List 1: Scroll recording 1419585508174,357
1419585508174: List 1: MoveTouch Scrolling is taking 1 millisecs
1419585508274: List 1: The unlock screen in mouseMove is taking 100 Milliseconds
1419585508274: List 1: The TouchMove handler is taking 101 milliseconds to process
1419585508278: List 1: Scroll recording 1419585508278,321
1419585508278: List 1: MoveTouch Scrolling is taking 1 millisecs
1419585508377: List 1: The unlock screen in mouseMove is taking 99 Milliseconds
1419585508377: List 1: The TouchMove handler is taking 100 milliseconds to process
1419585508380: List 1: Scroll recording 1419585508380,274
1419585508380: List 1: MoveTouch Scrolling is taking 1 millisecs
1419585508393: List 1: The unlock screen in mouseMove is taking 12 Milliseconds
1419585508393: List 1: The TouchMove handler is taking 14 milliseconds to process
1419585508395: List 1: Scroll recording 1419585508395,265
1419585508395: List 1: MoveTouch Scrolling is taking 1 millisecs
1419585508410: List 1: The unlock screen in mouseMove is taking 15 Milliseconds
1419585508410: List 1: The TouchMove handler is taking 16 milliseconds to process
1419585508413: List 1: Scroll recording 1419585508413,256
1419585508413: List 1: MoveTouch Scrolling is taking 1 millisecs
1419585508426: List 1: The unlock screen in mouseMove is taking 13 Milliseconds
1419585508426: List 1: The TouchMove handler is taking 14 milliseconds to process
1419585508429: List 1: Scroll recording 1419585508428,247
1419585508429: List 1: MoveTouch Scrolling is taking 1 millisecs
1419585508442: List 1: The unlock screen in mouseMove is taking 13 Milliseconds
1419585508442: List 1: The TouchMove handler is taking 14 milliseconds to process
1419585508444: List 1: Scroll recording 1419585508444,240
1419585508445: List 1: MoveTouch Scrolling is taking 0 millisecs
1419585508457: List 1: The unlock screen in mouseMove is taking 12 Milliseconds
1419585508458: List 1: The TouchMove handler is taking 14 milliseconds to process
Conclusion: It starts out at 100 milliseconds then drops to 20 milliseconds about a half second into the scroll. There is something going on in the livecode engine during those first changes of the location of my group that is taking up an extra 80 milliseconds and it isn't allowing me to record a swipe. What could it be?

Dixie
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1336
Joined: Sun Jul 12, 2009 10:53 am

Re: Using TouchMove (swipe, velocity)

Post by Dixie » Fri Dec 26, 2014 11:26 am

Let me see if I understand...
You wish to know the time that it takes you to swipe your finger across the screen ?

Ok... the attached stack will return the time in millseconds that it took to swipe 60 pixels... If you wish to calculate the time it takes to swipe on the screen over a greater distance then you can alter the length (the number of pixels needed to register a swipe) in the script..

It will return to you the time it took to swipe the 60 pixels, from there you can then calculate the speed..:-)
Attachments
swipeTime.livecode.zip
(2.43 KiB) Downloaded 284 times

William Jamieson
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 212
Joined: Fri Feb 01, 2013 1:31 am
Contact:

Re: Using TouchMove (swipe, velocity)

Post by William Jamieson » Fri Dec 26, 2014 8:21 pm

Hey Dixie. Thank you for posting here and creating that sample stack. However, I think what I am trying to solve was misunderstood and I am trying my best to communicate it as clearly as possible.

It is not an issue of calculation, its an issue of Android processing time. The fact is that for moving large groups, it takes a while for the screen to redraw only the first few times. This creates a lag making it so the TOUCHMOVE AND the MOUSEMOVE handlers DONT EVEN EXECUTE. If they were running, then yes, your stack would be a possible solution.

I was able to figure out a solution however that works for now.... It was to move my velocity sampling lines of code to the beginning of the handler before the MoveTouch. That way I would get a single point as the touch started, (my code is set to not start scrolling until 10 pixels of movement), then it would come around a second time and give me a second point to calculate velocity (Much like your equation Dixie) before the screen would redraw causing the app to freeze momentarily. That was enough to get the sample I needed for the velocity of the group. I do not know if that is a permanent solution however, it did work on my Android Galaxy S3. I have yet to test it on slower devices.

The solution ended up looking like this:

Code: Select all

on TouchMove pID, pX, pY
if sScroll is not "true" then exit TouchMove

##Record Touch Timing
   put line 2 of sTouchTimer into line 1 of sTouchTimer
   put the millisecs & comma & pY into line 2 of sTouchTimer --Use the touch

MoveTouch ---The handler where I move my enormous scrolling group which takes 13 to 140 milliseconds depending on whether it is starting to move or not

pass TouchMove
end TouchMove
If that doesn't work, another way to get around it is to not redraw the screen until I can get a second sample point from the touchMove handler.
Such code like this would do the trick, but idk if it is necessary yet

Code: Select all

on TouchMove pID, pX, pY
if sScroll is not "true" then exit TouchMove

##Record Touch Timing
   put line 2 of sTouchTimer into line 1 of sTouchTimer
   put the millisecs & comma & pY into line 2 of sTouchTimer --Use the touch

if the number of lines in sTouchTimer < 2 then pass TouchMove  --Let it come around again to get the second sampling point.

MoveTouch ---The handler where I move my enormous scrolling group which takes 13 to 140 milliseconds depending on whether it is starting to move or not

pass TouchMove
end TouchMove
Anyways, this took a rediculous amount of testing to figure out. Was one of those solutions that came to me while I was sleeping (Im weird, I dream about code. lol)

I hope this demonstrates a solution to all those in the future trying to figure out how to work with mobile processing times.

I am still curious as to why it is that during the first half second that the engine needs 5 times the amount of time to redraw the moving group...? Any ideas?

Cheers,

-Will

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7393
Joined: Sat Apr 08, 2006 8:31 pm
Contact:

Re: Using TouchMove (swipe, velocity)

Post by jacque » Sat Dec 27, 2014 4:55 pm

Does the standard method I posted above work? You probably shouldn't be using touchMove at all to get the coordinates. You'll find it much faster if you use mouseDown and mouseUp to get the coordinates and start/end times. (Or touchstart and touchEnd if you only want it to work on mobile. Don't use both mouse and touch messages or you will get double messages on the device.)

The layermode of the group should be set to "scrolling" to speed up movement. You can do that in the group property inspector.

Also you can avoid most of the issues by using a native scroller on Android. It was made for exactly this purpose and handles speed and momentum for you.
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

William Jamieson
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 212
Joined: Fri Feb 01, 2013 1:31 am
Contact:

Re: Using TouchMove (swipe, velocity)

Post by William Jamieson » Mon Dec 29, 2014 8:26 pm

Thank you for your response Jacque. However, with your recommendations I ran into a few problems.

1. Using the native android scroller will disable all messages sent to the application once activated by a touch.

2. The native scroller also doesn't allow scrolling to the left or right with momentum and deceleration

3. There is also a bug with the android native scroller where it doesn't work when the FullScreenMode is activated. I think we talked about that already in a different thread. I submitted that bug by the way and am awaiting RunRev's response.

4. In your example, if the user does mouseDown or TouchStart, slides their finger up and down, and then throws the group with the last point of touch being at the same location as the touchStart, the touchEnd and the TouchStart will have the same value, making it so the calculation will perceive the touch as a static touch or hold press. Which for my situation, would mean that what is intended by the user is not happening, therefore it is broken.

The layermode is already set to "scrolling" as well as the objects inside set to "dynamic" (idk if that helps too but it is worth a shot) and I am using an if statement that blocks the mouse commands (e.g. mouseDown) from activating if the stack finds itself on mobile.

However, I did solve the issue I first posted about using the solution above. So it is working and is not limited in any way and I am perfectly happy how it works (way better than the native scroller). The only reason I left this thread as unsolved is because of my question of why the Livecode engine takes so long to redraw the screen ONLY when the group first starts to scroll. I showed the time frames in one of the posts above.

I guess to understand it I would have to understand the engine. Which is not something I am going to dive into any time soon. But I thought there might be a magical setting like "acceleratedRending" or "compositorTileSize" that I could use to speed up the time that Livecode takes to redraw the screen initially. Or if there is a way to force the app to redraw the screen faster. I am just looking for a more elegant solution than the work-around I did above.

So I think you missed the point I was getting at Jacque, but thank you for your input because it brought up very good conversation I think other readers can learn from :D

-Will

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7393
Joined: Sat Apr 08, 2006 8:31 pm
Contact:

Re: Using TouchMove (swipe, velocity) [[Half-SOLVED]]

Post by jacque » Mon Dec 29, 2014 9:53 pm

I don't have a clear idea of exactly what you are trying to scroll, so yes, it's quite possible I missed your point. (A screenshot of the area would probably straighten me out.) You should of course do whatever is working for you. But just to clear up a few things about scrollers:

1. A scroller does not disable messages to the app, but it may block messages to some underlying controls, which would require some scripting to get around. You basically compare the start and end positions to see if it's a tap or a swipe.

2. A native scroller can easily scroll left and right, it just has to be enabled during setup. There's a nice example that ships with LiveCode but the most recent IDE no longer has a link to it. You can find it in the app folder here: Tools/Resources/Mobile Examples/Scroller Example.livecode (on a Mac, this is inside the Contents folder in the bundle.)

3. If there is a bug with fullscreen mode turned on, then yes, that's a blocker. I haven't had a chance to try it on a real device yet.

4. Since you have another solution this is probably moot, but I'm not clear on your example, since if you are using a scroller you shouldn't need to calculate speed or distance. The scroller handles that for you and your script only needs to set an offset position. But maybe I'm missing reason why you need to calculate that.

For layermode: do not set any of the contents of the group to dynamic, that will actually slow down the response. The more controls that are not static, more work the engine has to do. You only want the largest encompassing area that needs to move to have a non-static layermode. In this case, it's the group. If you are using a native scroller then you should set the layermode to "scrolling", otherwise set the layermode to "dynamic".

Reset all the controls inside the group to "static" and see if it speeds up your first screen draw. Every object with a non-static layermode requires some time while the engine caches it into RAM.
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

William Jamieson
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 212
Joined: Fri Feb 01, 2013 1:31 am
Contact:

Re: Using TouchMove (swipe, velocity) [[Half-SOLVED]]

Post by William Jamieson » Tue Dec 30, 2014 11:47 pm

Ahhh.. Wow. I am really learning a lot from your suggestions. I will look into the horizontal scroll and see if I can set the parameters to only scroll one row at a time. Hmm.. That is a good idea worth trying.

And on my Galaxy S3, i made a sample stack a while ago to determine when the touch messages are being sent. From what I found the native scroller allows a certain amount of play before it activates. Once it does, TouchRelease is sent, TouchEnd doesn't send, and TouchMove is no longer sent. Is there a workaround for this??

I think the fullscreenmode interaction should be fixable by RunRev so I am sure it wont be an issue for long. Its just an internal calculation that needs to be done.

The reason for calculating the velocity was to be able to plug it into the physics equation [Xf = Xo + Vo * t + (1/2) a * t ^ 2] to determine the next position of the group with a given deceleration with each frame. That is at least how I have it set up.

Awesome suggestion! Thank you for your insight on setting the layermode on the grouped controls to "static". I am not very familiar with how the layermode works so thank you for shining some light on that for me. I tried it and it reduced the time from about 140 milliseconds down to 90 milliseconds. I am getting a refresh rate that is consistently at about 12 frames per second which seems to be about the same with the native scroller on my S3, so that helped.

Sorry if my initial statement of the problem was unclear but I am glad that you got it.

Thanks for your help once again Jacque!

-Will

Post Reply