Moving button unwanted behaviour

Anything beyond the basics in using the LiveCode language. Share your handlers, functions and magic here.

Moderators: Klaus, FourthWorld, heatherlaine, kevinmiller, robinmiller

mrcoollion
Posts: 520
Joined: Thu Sep 11, 2014 1:49 pm
Location: The Netherlands

Moving button unwanted behaviour

Post by mrcoollion » Thu Jun 09, 2016 9:00 am

Here I am again,

I am building a button click or move routine (for a mobile app).
I have one problem and that is when I move the button by keeping mousedown for 2 seconds, after I release the button (mouse up) it keeps sticking to my mouse.
So if I click the message after the move, before 2 seconds are past, the button keeps sticking to my mouse until I click the button again.

What I really want is, to have the button immediately un-stick after the move is done (after mouseup).
Tried many things but cannot get it to work properly (used 'grab me' but that was even worse).

The script is below. Just place it in a button on a card and test.
Any suggestions ?

Code: Select all

local MovingYN
on mousedown
   put "No"into MovingYN
end mousedown
---------------------------------------------------------------------------------
on mouseStillDown // mousedown
   --wait 100 millisec with messages
   if the mouse is down then
      send "StartMove" to me in 2 seconds
   end if
end mouseStillDown //mousedown
---------------------------------------------------------------------------------
on mouseMove
   if MovingYN is "Yes"  then
      set  the loc of me to  the mouseLoc
   end if
end mouseMove
   ---------------------------------------------------------------------------------
on mouseup
   if MovingYN is "Yes"  then 
      put the loc of me into  TheNewLocation
      Answer information "Button has moved to: " & the topleft of me
      put "No"into MovingYN
      // Now do any routine related to moving this button
      
      // End any routine
   else
      answer "Button was only clicked!"
      // Now do any routine related to clicking this button
      
      // end any routine
   end if
end mouseup
---------------------------------------------------------------------------------
On StartMove
   put "Yes"into MovingYN
end StartMove
---------------------------------------------------------------------------------

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 6614
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: Moving button unwanted behaviour

Post by dunbarx » Thu Jun 09, 2016 2:11 pm

Hi.

Try this:

Code: Select all

on mouseDown
   send "grabMe" to me in 120
end mouseDown

on grabme
   if the mouseLoc is within the rect of me and the mouse is down then
      set the loc of me to the mouseLoc
      send "grabMe" to me in 1
      else
      exit to top
   end if
end grabme
Now this handler is a bit ugly. Do you see why?

Craig Newman

mrcoollion
Posts: 520
Joined: Thu Sep 11, 2014 1:49 pm
Location: The Netherlands

Re: Moving button unwanted behaviour

Post by mrcoollion » Thu Jun 09, 2016 6:39 pm

exit to top
Bit of a nasty way to leave but I use it sometime as well
..
I will try your suggestions and give my remarks later today.
Thanks Craig

mrcoollion
Posts: 520
Joined: Thu Sep 11, 2014 1:49 pm
Location: The Netherlands

Re: Moving button unwanted behaviour

Post by mrcoollion » Thu Jun 09, 2016 6:54 pm

Cudo's to you Craig,

Your routine works perfect and has very few lines of code :D .
I only made very small changes to enable me to incorporate the difference between move and click scripts.

Thanks again !!!

Code: Select all

local MovedYN
on mouseDown
   put "No" into MovedYN
   send "grabMe" to me in 60
end mouseDown

on grabme
   if the mouseLoc is within the rect of me and the mouse is down then
      set the loc of me to the mouseLoc
      put "Yes" into MovedYN
      send "grabMe" to me in 1
      else
      exit to top
   end if
end grabme

on Mouseup
   if MovedYN is "Yes" then
      answer "Button has been moved !"
   else
      answer "Button has been clicked!"
   end if
end Mouseup

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 6614
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: Moving button unwanted behaviour

Post by dunbarx » Thu Jun 09, 2016 9:30 pm

Hi.

"Exit to top" is an essential snippet. Can't be beat. It derives from "Exit to HyperCard". Use it wisely, and whenever you need to. You will need to, trust me.

The ugly part was the way I threw this together. The "grabMe" handler needs to be slowed down, or it will throw a recursion error. Try it. Waiting 1 tick is adequate to allow the user to:

- move the button smoothly
- keep the recursion error at bay unless the user holds the mouse down for a VERY long time

But it is still ugly. It should be rethought so that the tick is not required at all. Game for that?

Craig

mrcoollion
Posts: 520
Joined: Thu Sep 11, 2014 1:49 pm
Location: The Netherlands

Re: Moving button unwanted behaviour

Post by mrcoollion » Fri Jun 10, 2016 1:40 pm

Hi Craig,

Tried it and sure enough after a few moves I got the error so I took up the gauntlet and came up with the following changes.
With the following changed 'grabme' routine the problem seems solved...
No exit or delay needed and fewer lines of code 8)

Thanks for the help Craig :D

Code: Select all

on grabme
   put "Yes" into MovedYN
   repeat while  the mouseLoc is within the rect of me and the mouse is down
      set the loc of me to the mouseLoc
   end repeat
end grabme

sturgis
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1682
Joined: Sat Feb 28, 2009 11:49 pm

Re: Moving button unwanted behaviour

Post by sturgis » Sun Jun 12, 2016 2:23 pm

Just for completeness, if you ever have need to use your initial method to move things around, you were close. Here's a version (super simple) that works.

Code: Select all

-- there is still a problem with this method, but it should be easy enough to fix..
-- if you click the button and drag the mouse away before 2 seconds without releasing it,
-- the button will 'jump' to the mouse location after 2 seconds
-- one could add a mouseleave handler that resets the moveDelay if needed.

local MovingDelay
on mousedown
   put the millisec into MovingDelay
end mousedown
---------------------------------------------------------------------------------
on mouseMove
   if MovingDelay is not empty and the millisec - MovingDelay > 2000 then
      set  the loc of me to  the mouseLoc
   end if
end mouseMove
   ---------------------------------------------------------------------------------
on mouseup
   answer information "The mouse was down for" && the millisec - movingDelay && "milliseconds"
   put empty into movingDelay
end mouseup
---------------------------------------------------------------------------------
on mouseRelease
   -- this is needed on the off chance you move the mouse fast enough to 
   -- be outside the rect of the button on mouseup. In which case, mouseup is not sent
   -- to the button, but mouserelease still is.
   answer information "The mouse was down for" && the millisec - movingDelay && "milliseconds"
   put empty into movingDelay
end mouseRelease

mrcoollion
Posts: 520
Joined: Thu Sep 11, 2014 1:49 pm
Location: The Netherlands

Re: Moving button unwanted behaviour

Post by mrcoollion » Mon Jun 13, 2016 4:03 pm

Thanks Sturgis...
:D

Tried your code and it also works really nice however there is a difference and depending on what you want as a developer both codes have their purpose.
The difference is (as I see it) that your code needs the mouse to move and the other code only needs the mouse to be pressed ....
I like your code best if you want to move things around and tweak the reaction time on when to start moving. I like the other code better when I want the user to keep pressing a button until it 'unlocks' and only then have the user move the button. In your case if the user keeps his cursor or finger still nothing 'unlocks'.

So again, depending on what you want as a developer both codes have their purpose ... really thanks for the support and I am sure I will find a need for both ways. :D :D :D

mrcoollion
Posts: 520
Joined: Thu Sep 11, 2014 1:49 pm
Location: The Netherlands

Re: Moving button unwanted behaviour

Post by mrcoollion » Tue Jun 14, 2016 6:26 pm

Small addition to the sturgis code
I changed 'if MovingDelay is not empty and the millisec - MovingDelay > 2000 then'
into 'if MovingDelay is not empty and the millisec - MovingDelay > 2000 and the mouseLoc is within the rect of me then'.

This solves the issue mentioned by Sturgis in the remarks section of his code.

Code: Select all

-- there is still a problem with this method, but it should be easy enough to fix..
-- if you click the button and drag the mouse away before 2 seconds without releasing it,
-- the button will 'jump' to the mouse location after 2 seconds
-- one could add a mouseleave handler that resets the moveDelay if needed. 
-- >> Solved with the addition of 'and the mouseLoc is within the rect of me' 

local MovingDelay
on mousedown
   put the millisec into MovingDelay
end mousedown
---------------------------------------------------------------------------------
on mouseMove
   if MovingDelay is not empty and the millisec - MovingDelay > 2000 and the mouseLoc is within the rect of me then
      set  the loc of me to  the mouseLoc
   end if
end mouseMove
   ---------------------------------------------------------------------------------
on mouseup
   answer information "From mouseup: The mouse was down for" && the millisec - movingDelay && "milliseconds"
   put empty into movingDelay
end mouseup
---------------------------------------------------------------------------------
on mouseRelease
   -- this is needed on the off chance you move the mouse fast enough to 
   -- be outside the rect of the button on mouseup. In which case, mouseup is not sent
   -- to the button, but mouserelease still is.
   answer information "From mouseRelease: The mouse was down for" && the millisec - movingDelay && "milliseconds"
   put empty into movingDelay
end mouseRelease

sturgis
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1682
Joined: Sat Feb 28, 2009 11:49 pm

Re: Moving button unwanted behaviour

Post by sturgis » Tue Jun 14, 2016 6:35 pm

I tweaked the code similar to what mrcoollion did, plus added a timer that changes the cursor to the hand after the delay so that there is a visual cue that the button is now held by the cursor. If interested I'll post the changes. Slightly more complicated but the visual feedback seems to work well.

mrcoollion
Posts: 520
Joined: Thu Sep 11, 2014 1:49 pm
Location: The Netherlands

Re: Moving button unwanted behaviour

Post by mrcoollion » Tue Jun 14, 2016 6:40 pm

Please do post! :)

Regards CL

sturgis
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1682
Joined: Sat Feb 28, 2009 11:49 pm

Re: Moving button unwanted behaviour

Post by sturgis » Tue Jun 14, 2016 6:50 pm

Ok, here it is. Added a constant for the delay, added sMoving as the actual "are we going to move this" flag. added sMessage so that the switch to hand cursor can be cancelled if the mouse leaves the rect of the button before time.

Code: Select all

-- there is still a problem with this method, but it should be easy enough to fix..
-- if you click the button and drag the mouse away before 2 seconds without releasing it,
-- the button will 'jump' to the mouse location after 2 seconds
-- one could add a mouseleave handler that resets the moveDelay if needed.

local MovingDelay,sMoving,sMessage
constant kDelay=500
on mousedown
   put the millisec into MovingDelay
   put true into sMoving
   send "talkToTheHand" to me in kDelay millisec -- sets the cursor to hand, doesn't rely on mousemove
   put the result into sMessage -- the message id so we can cancel it if the mouse leaves the button before time
end mousedown

command talkToTheHand
   set the cursor to hand
   lock cursor
end talkToTheHand
---------------------------------------------------------------------------------
on mouseMove
   if sMoving is not empty and the millisec - MovingDelay > kDelay then
      set  the loc of me to  the mouseLoc
   else
      if the mouseloc is not within the rect of me then 
         cancel sMessage
         put empty into sMoving
         unlock cursor
      end if
   end if
end mouseMove
   ---------------------------------------------------------------------------------
on mouseup
   unlock cursor
   answer information "The mouse was down for" && the millisec - movingDelay && "milliseconds"
   put empty into sMoving
end mouseup
---------------------------------------------------------------------------------
on mouseRelease
   -- this is needed on the off chance you move the mouse fast enough to 
   -- be outside the rect of the button on mouseup. In which case, mouseup is not sent
   -- to the button, but mouserelease still is.
   unlock cursor
   answer information "The mouse was down for" && the millisec - movingDelay && "milliseconds"
   put empty into sMoving
end mouseRelease

mrcoollion
Posts: 520
Joined: Thu Sep 11, 2014 1:49 pm
Location: The Netherlands

Re: Moving button unwanted behaviour

Post by mrcoollion » Tue Jun 14, 2016 8:00 pm

Great and thanks Sturgis :D ,

In addition to all the code above i have made a version based on mouseStillDown .
With this version I do not need to move the mouse (or finger) but i can still tweak the reaction time as i can with the sturgis code.
I should be able to also filter the action on mouseButtonNumber so 'mouseStillDown' only reacts on the left mouse button but i cannot seem to get this working.

Code: Select all

local MovedYN, MovingDelay

on mouseDown
   put "No" into MovedYN
   put the millisec into MovingDelay
end mouseDown

on mouseStillDown
   repeat while MovingDelay is not empty and the millisec - MovingDelay > 1000 and the mouseLoc is within the rect of me and the mouse is down
      set the loc of me to the mouseLoc
      put "Yes" into MovedYN
      set the cursor to hand
      lock cursor
   end repeat
end mouseStillDown

on Mouseup
   if MovedYN is "Yes" then
      unlock cursor
      answer "From Mouseup : Button has been moved !"
   else
      answer "From Mouseup :  Button has been clicked!"
   end if
      put empty into movingDelay
end Mouseup

on mouseRelease
   answer "From Mouserelease: I have been triggered!"
   put empty into movingDelay
   unlock cursor // probably not necessary but just in case :-0
end mouseRelease

sturgis
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1682
Joined: Sat Feb 28, 2009 11:49 pm

Re: Moving button unwanted behaviour

Post by sturgis » Tue Jun 14, 2016 8:42 pm

Gotta go to town, but off the top of my head you probably need to do something simple like...

Code: Select all

on mouseDown pBtn
   if pBtn is 3 then
      put "No" into MovedYN
      put the millisec into MovingDelay
   end if
end mouseDown
And in your mousestilldown.. Since the dictionary says its sent "periodically" you probably don't want a tight repeat loop in it. Treat it like mousemove and change your repeat to an if.

Code: Select all

if movingDelay is not empty and the millisec - movingDelay > 1000 and the mouseloc is within the rect of me then
   set the loc of me to the mouseloc
   set the cursor to hand
   lock cursor
end if
The tight repeat loop won't leave room for other messages to process, so setting movingdelay probably won't happen, plus it may build up a queue of "mousestilldown" messages for no purpose, and probably negative (slow down or crash) effects.

mrcoollion
Posts: 520
Joined: Thu Sep 11, 2014 1:49 pm
Location: The Netherlands

Re: Moving button unwanted behaviour

Post by mrcoollion » Tue Jun 14, 2016 9:25 pm

Just tried your If/Then in place of the repeat suggestion.
Even though it does work the movement of the button is not smooth :( and if i move to fast the button is 'lost' .
With the repeat statement every thing works fine and the movement is very smooth.

Try it out yourself and past the code below in a button.
Put 1 or 2 into the whichroutine variable in line 12 to switch between If/Then or Repeat ...

Code: Select all

local MovedYN, MovingDelay,reactiontime

on mouseDown pressedButton
   put 500 into reactiontime
   if pressedButton is 1 then
      put "No" into MovedYN
      put the millisec into MovingDelay
   end if
end mouseDown

on mouseStillDown
   put 2 into whichroutine
   if whichroutine is 1 then
      If movingDelay is not empty and the millisec - movingDelay > reactiontime and the mouseloc is within the rect of me and the mouse is down then
         set the loc of me to the mouseloc
         set the cursor to hand
         lock cursor
      end if
   else
      repeat while MovingDelay is not empty and the millisec - MovingDelay > reactiontime and the mouseLoc is within the rect of me and the mouse is down
         set the loc of me to the mouseLoc
         put "Yes" into MovedYN
         set the cursor to hand
         lock cursor
      end repeat
   end if
end mouseStillDown

on Mouseup
   if MovedYN is "Yes" then
      unlock cursor
      answer "From Mouseup : Button has been moved !"
   else
      answer "From Mouseup :  Button has been clicked!"
   end if
      put empty into movingDelay
end Mouseup

on mouseRelease
   answer "From Mouserelease: I have been triggered!"
   put empty into movingDelay
   unlock cursor // probably not necessary but just in case :-0
end mouseRelease

Post Reply

Return to “Talking LiveCode”