Page 1 of 3

I have a problem. How can I make the button stop receiving clicks until the action inside it is finished?

Posted: Wed Oct 12, 2022 11:42 am
by royF
There is a button called "CheckMe" that executes the "evaluateVictory" action.
When I brought my friends to play, I noticed that out of impatience, they press the button a large number of times per second, which crashes the software and creates a loop of executing the "evaluateVictory" action.

I tried the following simple code:

Code: Select all

on mouseUp
   disable me
   evaluateVictory
   enable me
end mouseUp
but without success....

help?

Thanks!!

Re: I have a problem. How can I make the button stop receiving clicks until the action inside it is finished?

Posted: Wed Oct 12, 2022 12:43 pm
by stam
That looks like it should work… What exactly is failing?
Have you tried setting a breakpoint and stepping through your code?

Re: I have a problem. How can I make the button stop receiving clicks until the action inside it is finished?

Posted: Wed Oct 12, 2022 2:14 pm
by royF
I tried breakpoint, it didn't help.
My assumption is that it doesn't work because the click several times within a second informs livecode to play the command several times.

I am attaching a sample file and an impression

Re: I have a problem. How can I make the button stop receiving clicks until the action inside it is finished?

Posted: Wed Oct 12, 2022 2:20 pm
by stam
Part of the reason why I suggested a break point was so that you could check to make sure the button is visibly disabled, as that shouldn’t be happening I don’t think.

I’m travelling so no way to check actual code.

As a safeguard why don’t you add a script local or global Boolean as a flag to ensure evaluateVictory only runs once (ie when the flag permits)?

Re: I have a problem. How can I make the button stop receiving clicks until the action inside it is finished?

Posted: Wed Oct 12, 2022 2:49 pm
by dunbarx
Do it this way. In the script of a new button:

Code: Select all

on mouseUp
   if the noGo of me = "false" then beep 2
  set the noGo of me to "true"
end mouseUp

on mouseEnter
   set the noGo of me to "false"
end mouseEnter
First time, the user will hear two beeps. But then unless the user leaves the button and returns, the button will ignore whatever he does. It is a good idea to initialize the state of the "noGo" custom property (to "false") on openCard.

Craig

Re: I have a problem. How can I make the button stop receiving clicks until the action inside it is finished?

Posted: Wed Oct 12, 2022 3:02 pm
by Klaus
The problem in your script is the SEND command.

Code: Select all

On mouseUp
   disable me
   
   ## ALWAYS use quotes for the commands to send!
   send "StepByStep" to me in 2 sec 
   enable me
end mouseUp

on StepByStep
   add 1 to fld "List"
end StepByStep
This way the "enable me" almost instantly gets executed, since SEND is only taking less than a millisecond.

This is a cheap-o solution:

Code: Select all

On mouseUp
   disable me
   send "StepByStep" to me in 2 sec 
end mouseUp

on StepByStep
   add 1 to fld "List"

   ## Add this line here:
   enable me
end StepByStep

Re: I have a problem. How can I make the button stop receiving clicks until the action inside it is finished?

Posted: Wed Oct 12, 2022 3:08 pm
by royF
Thanks everyone Klaus Dunbarx and Stam!
Klaus you solved the problem! :D :D :D :D
See you until the next issue 😉

Re: I have a problem. How can I make the button stop receiving clicks until the action inside it is finished?

Posted: Wed Oct 12, 2022 5:46 pm
by jacque
There is a command made especially for this problem:

Code: Select all

get flushEvents("mouseUp")
Use it like this :

Code: Select all

on mouseUp
   evaluateVictory
   get flushEvents("mouseUp")
end mouseUp
See the dictionary.

Re: I have a problem. How can I make the button stop receiving clicks until the action inside it is finished?

Posted: Wed Oct 12, 2022 6:23 pm
by dunbarx
Jacque.

How could this work?:

Code: Select all

on mouseUp
   twoBeeps
   get flushEvents("mouseUp")
end mouseUp

on twoBeeps
   beep 2
end twoBeeps
You can click all day and get lots of beeps.

Klaus' offering uses a delay, two seconds, to "prevent" successive clicks from doing anything. But it does not prevent clicks after that time period. Perhaps the OP is not concerned with activity after such a delay. Mine requires that the mouse leave the button and return, again, perhaps not ideal.

I remember a long discussion a couple of months ago on this very topic, to prevent unwanted fast successive clicks on a button. Have to dig that up...

Craig

Re: I have a problem. How can I make the button stop receiving clicks until the action inside it is finished?

Posted: Wed Oct 12, 2022 6:32 pm
by royF
jacque your solution sound excellent.
But right after you click the button, the next click depending on the number of clicks, no matter where you are on the screen, will activate the button again.
The button remains marked for the next click

Re: I have a problem. How can I make the button stop receiving clicks until the action inside it is finished?

Posted: Wed Oct 12, 2022 8:37 pm
by jacque
dunbarx wrote:
Wed Oct 12, 2022 6:23 pm
You can click all day and get lots of beeps.
Yes, but that's to be expected. It's no different than a user repeatedly clicking a button with your script. It's meant for long handlers that may cause the user to think the button did not respond, or for impatient users like small children who may click repeatedly while the handler is executing. It also prevents double-clicks.

To add a delay, wait an additional second or two (don't use "with messages") before flushing the queue.

Code: Select all

on mouseUp
   evaluateVictory
   wait 2 seconds
   get flushEvents("mouseUp")
end mouseUp
@royF: there is no way the button script should respond unless the user clicks on the button itself. Something else is activating your handler, maybe you left remnants of the other suggestions in the script, or maybe you didn't put the mouseUp handler in the button itself. If the mouseUp is in the card script, it will trigger from anywhere.

If your evaluateVictory handler doesn't take long to execute, then the next click will trigger the button again. If you want a delay, use the "wait" command, though no matter how long you wait the user may just keep clicking anyway and eventually the button will trigger again.

Re: I have a problem. How can I make the button stop receiving clicks until the action inside it is finished?

Posted: Thu Oct 13, 2022 3:13 am
by dunbarx
@RoyF. Do you see what Jacque means? The "flushEvents" command will clear extra pending clicks, which ar queued by the engine, but only those made while the handler is running. If the user clicks after it finishes, all bets are off, because a brand new "mouseUp" message is sent.

That is why waiting is one possible solution, since the user's actions will likely not outlast the wait time, though they certainly might. Or if it is not normally intended that the user will click the same button again right away, never mind repeatedly, then my handler explicitly sets a condition requiring that the cursor leave the button itself, and then re-enter and click.

Craig

Re: I have a problem. How can I make the button stop receiving clicks until the action inside it is finished?

Posted: Thu Oct 13, 2022 3:16 am
by dunbarx
I found the previous very exhaustive discussion. It explores several methods, similar to the ones here. This is worth perusing...

https://forums.livecode.com/viewtopic.p ... ted+clicks

Craig

Re: I have a problem. How can I make the button stop receiving clicks until the action inside it is finished?

Posted: Tue Oct 10, 2023 1:40 pm
by crokyweb
I want to create a countdown with a single button that acts as PLAY and STOP. PLAY works for me but I can't stop the script. Does anyone know how to help me thanks

on mousedown
set the label of button "Avvio" to "STOP"
repeat until the mouseClick or fld "Timer" is "00:00"
set the label of button "Avvio" to "STOP"
wait 1 second
---put flushEvents("mousedown") into ttmp
set itemdel to ":"
put item 2 of fld "timer" into tsecondi
put item 1 of fld "timer" into tminuti
switch
case tsecondi =00
put "59" into tsecondi
put tsecondi into item 2 of fld "timer"
subtract 1 from tminuti
if the length of tminuti is 2 then
put tminuti into item 1 of fld "timer"
else
put "0"& tminuti into item 1 of fld "timer"
end if
break

case tsecondi <=9
subtract 1 from tsecondi
if the length of tsecondi is 2 then
put tsecondi into item 2 of fld "timer"
else
put "0"&tsecondi into item 2 of fld "timer"
end if
break

case tsecondi >9 and tsecondi <59
subtract 1 from tsecondi
if the length of tsecondi is 2 then
put tsecondi into item 2 of fld "timer"
else
put "0"&tsecondi into item 2 of fld "timer"
end if
break

case tsecondi =59
subtract 1 from tsecondi
put tsecondi into item 2 of fld "timer"
break
end switch
end repeat
set the label of button "Avvio" to "START"
end mousedown

Re: I have a problem. How can I make the button stop receiving clicks until the action inside it is finished?

Posted: Tue Oct 10, 2023 2:25 pm
by dunbarx
Hi.

Please insert script snippets within the code brackets (</>) above:

Code: Select all

 on mousedown
set the label of button "Avvio" to "STOP"
repeat until the mouseClick or fld "Timer" is "00:00" 
set the label of button "Avvio" to "STOP"
wait 1 second
---put flushEvents("mousedown") into ttmp
set itemdel to ":"
put item 2 of fld "timer" into tsecondi
put item 1 of fld "timer" into tminuti 
switch
case tsecondi =00
put "59" into tsecondi
put tsecondi into item 2 of fld "timer"
subtract 1 from tminuti
if the length of tminuti is 2 then
put tminuti into item 1 of fld "timer"
else
put "0"& tminuti into item 1 of fld "timer"
end if
break

case tsecondi <=9
subtract 1 from tsecondi
if the length of tsecondi is 2 then
put tsecondi into item 2 of fld "timer"
else
put "0"&tsecondi into item 2 of fld "timer"
end if
break

case tsecondi >9 and tsecondi <59
subtract 1 from tsecondi
if the length of tsecondi is 2 then
put tsecondi into item 2 of fld "timer"
else
put "0"&tsecondi into item 2 of fld "timer"
end if
break

case tsecondi =59
subtract 1 from tsecondi
put tsecondi into item 2 of fld "timer"
break
end switch
end repeat
set the label of button "Avvio" to "START" 
end mousedown
See? Much better.



Craig