Testing if the mouse clicked on ME (button)?!

J. Landman Gay jacque at hyperactivesw.com
Sat Aug 9 14:31:36 EDT 2008


H Baric wrote:

> Making a timer, with just one button and one field.
> The one button is to start and stop the timer.
> The button's label is changed to "Stop" when it starts, and "Start" when it 
> stops. I think I got that?
> But, how to test when the user clicks on the button during the process? 
> (sorry, hey don't laugh! I have been searching and trying everything I know, 
> which isn't much yet!)

I'm just delighted you are posting here. I think this list can be scary 
for newcomers and they don't always post. I wish we had more like you. 
Please don't stop.

> 
> But it's simple right? *blush*

It can be, but the easy way isn't the right way. First let's fix your 
script to do it the easy way, and then I'll tell you why you shouldn't 
use it.

> on mouseUp
>     if the label of me is "Start" then
>         set the label of me to "Stop"
>         repeat with tCount = 1 to 60
>         put tCount into fld "Counter Show"
>         wait 1 second

While this repeat is running, nothing else can happen. The 60-second 
wait will block all other processes on the whole computer while the 
repeat loop goes around and around. Other background programs will stop 
whatever they are doing, the whole CPU will hang in limbo until that 
minute is over. That's one reason why we don't do it this way. But let's 
look at the script some more anyway.

>         if (I am clicked??) and the label of me is "Stop" then

The event you want here is "the mouseclick". When the user clicks, the 
"mouseclick" event is sent to whatever object is clicked. So the correct 
line is:

   if the mouseclick then

You don't need to check to see if the label is "stop" because the first 
line of the "if" clause has already set that and it can't possibly be 
anything else.

>             exit repeat
>             set the label of me to "Start"

When you exit the repeat, any remaining lines in the repeat loop will be 
skipped and the handler will proceed to the line after the "end repeat". 
That means the label here will never be set to "start" because the loop 
has already exited. Change the order so that the "exit" is the last 
thing that happens:

    set the label of me to "Start"
    exit repeat

So, here's the whole working script:

on mouseUp
     if the label of me is "Start" then
         set the label of me to "Stop"
         repeat with tCount = 1 to 60
          put tCount into fld "Counter Show"
          wait 1 second
          if the mouseclick then
             set the label of me to "Start"
             exit repeat
          end if
         end repeat
     end if
end mouseUp

That's the easy way, but don't do it. In addition to blocking the CPU 
while this repeat loop runs, there's another reason to avoid this 
technique. The "mouseclick" (or any other mouse events) are not reliable 
when checked in a loop. The engine will only recognize a mouse event if 
it occurs at the same moment the script is checking for it. In a very 
short loop, it will probably "see" the mouse event most of the time. But 
in very long scripts inside a repeat loop, another part of the handler 
may be running when the mouse is clicked (like during the 1-second wait 
above,) and the script won't be checking at that precise moment, so the 
loop will not exit.

So a much better way to handle this kind of thing is to use the 
techniques that Eric and others have pointed out. It's more complicated, 
but it is more reliable and it doesn't block the CPU. There is more info 
about this technique here:

<http://www.hyperactivesw.com/polling.html>

Thanks again for posting, I hope you inspire all our other new Revvers 
to do the same.

-- 
Jacqueline Landman Gay         |     jacque at hyperactivesw.com
HyperActive Software           |     http://www.hyperactivesw.com



More information about the use-livecode mailing list