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

LiveCode is the premier environment for creating multi-platform solutions for all major operating systems - Windows, Mac OS X, Linux, the Web, Server environments and Mobile platforms. Brand new to LiveCode? Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

royF
Posts: 13
Joined: Mon Oct 10, 2022 10:48 pm

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

Post by royF » Wed Oct 12, 2022 11:42 am

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!!

stam
Posts: 2686
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

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

Post by stam » Wed Oct 12, 2022 12:43 pm

That looks like it should work… What exactly is failing?
Have you tried setting a breakpoint and stepping through your code?

royF
Posts: 13
Joined: Mon Oct 10, 2022 10:48 pm

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

Post by royF » Wed Oct 12, 2022 2:14 pm

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
Attachments
StepByStep - Test.zip
Livecode sample file and an impression
(849 Bytes) Downloaded 78 times

stam
Posts: 2686
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

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

Post by stam » Wed Oct 12, 2022 2:20 pm

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)?

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

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

Post by dunbarx » Wed Oct 12, 2022 2:49 pm

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

Klaus
Posts: 13829
Joined: Sat Apr 08, 2006 8:41 am
Location: Germany
Contact:

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

Post by Klaus » Wed Oct 12, 2022 3:02 pm

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

royF
Posts: 13
Joined: Mon Oct 10, 2022 10:48 pm

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

Post by royF » Wed Oct 12, 2022 3:08 pm

Thanks everyone Klaus Dunbarx and Stam!
Klaus you solved the problem! :D :D :D :D
See you until the next issue 😉

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7238
Joined: Sat Apr 08, 2006 8:31 pm
Location: Minneapolis MN
Contact:

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

Post by jacque » Wed Oct 12, 2022 5:46 pm

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.
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

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

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

Post by dunbarx » Wed Oct 12, 2022 6:23 pm

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

royF
Posts: 13
Joined: Mon Oct 10, 2022 10:48 pm

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

Post by royF » Wed Oct 12, 2022 6:32 pm

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

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7238
Joined: Sat Apr 08, 2006 8:31 pm
Location: Minneapolis MN
Contact:

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

Post by jacque » Wed Oct 12, 2022 8:37 pm

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.
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

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

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

Post by dunbarx » Thu Oct 13, 2022 3:13 am

@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

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

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

Post by dunbarx » Thu Oct 13, 2022 3:16 am

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

crokyweb
Posts: 14
Joined: Fri Apr 15, 2022 1:55 pm

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

Post by crokyweb » Tue Oct 10, 2023 1:40 pm

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
Attachments
Schermata 2023-10-10 alle 14.40.31.png

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

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

Post by dunbarx » Tue Oct 10, 2023 2:25 pm

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
Last edited by dunbarx on Tue Oct 10, 2023 3:00 pm, edited 1 time in total.

Post Reply

Return to “Getting Started with LiveCode - Experienced Developers”