force exit of mouseDown?
ambassador at fourthworld.com
Fri Jun 24 13:39:13 EDT 2011
Nicolas Cueto wrote:
> mouseStillDown, for example. When part of a script set as a behavior,
> mouseStillDown would not work. But that same script with the same
> mouseStillDown handler, when actually stored as a button's script,
> worked as expected.
In a way that's kinda good news, as mouseStillDown is an anomaly among
mouse messages. I think you'll find the other mouse messages quite
reliable in behavior scripts, but mouseStillDown is an oddity as noted
in the Dictionary:
Usually, it is easier and more efficient to use the mouseMove
message to track the movement of the mouse while the button
is being held down.
Note: If there is no mouseStillDown handler in the target
object's script, no mouseStillDown message is sent, even if
there is a mouseStillDown handler in an object that's
further along the message path.
Your behavior script should work if you add this to the target object:
Why is mouseStillDown so different from other mouse messages?
Because it's uniquely inefficient, and the mouseMove message was
provided to provide an alternative that's far more flexible and takes
fewer system resources for many similar needs.
Most OSes provide a message when the mouse first goes down, but not all
of them provide a second message sent continuously while the mouse is
being held down. So to provide mouseStillDown for us the engine needs
to continually poll the OS for the state of the mouse button. It does
this with a frequency defined in the idleRate, which is far less
frequent than checking "if the mouse is down" in a repeat loop, but
still not optimal.
If the message was always sent into the message path whether or not it's
needed, anytime the user holds the mouse down it would trigger a lot of
messaging overhead that's never used.
But what if you need it?
Like the idle message (HyperCard's message-clogging workaround for not
having timers), all you need to do is include a mouseStillDown handler
in any target you want it to be sent to, and the engine will then know
to trigger that seldom-used message.
Historically, mouseStillDown was most often used for dragging or other
operations in which things need to be updated while the mouse is moving.
In such cases, the developer probably doesn't need to update anything
until the location of the mouse changes, but mouseStillDown is
continually being sent anyway, requiring a lot of redundant processing
for things which have no visible effect.
So the mouseMove message was added, providing a way to update things
only when the mouse is moved.
MouseMove also works when the mouse is up, which can be useful for
update mouse position indicators in a drawing program's rulers, for example.
This additional flexibility requires us to use a few other handlers to
substitute for mouseStillDown, but it well worth the few seconds it
takes to set up. You'll need a mouseDown to set a flag so the mouseMove
can know that the mouse is down without having to poll the OS (you can
also use this flag for other useful info, as shown below), and you'll
need mouseUp and mouseRelease messages to clear the flag.
This example is for a splitter control that adjusts the groups on either
side of it:
-- Provide the info mouseMove will need later:
put the mouseH - the left of me into sXOffset
-- Is the flag still set?
if sXOffset is not empty then
-- If so, handle the splitter drag here:
set the rect of grp "LeftGroup" to \
0,0,the left of me, the height of this cd
set the rect of grp "RightGroup" to \
the right of me, 0, the width of this cd,
the height of this cd
-- Clear the flag when the mouse is released over the control:
put empty into sXOffset
-- Clear the flag when the mouse is release when not over the control:
put empty into sXOffset
In addition to handling simple drags like a splitter, drag-and-drop
operations can be handled using the messages provided for those
(dragStart, dragMove, dragDrop, dragEnd) far more simply than emulating
drag-and-drop behaviors with mouseStillDown.
So once we use mouseMove for movement-related things and the
drag-and-drop messages for those types of actions, the remaining subset
of cases where mouseStillDown can be useful are relatively few. And for
those, you can still use it so long as you provide a handler for it in
the target object.
> One other thing I noticed during development and had thought due to my
> uncertain knowledge about the various mouse-related handlers, was that
> I couldn't rely on "me" but had to be more specific. Something like
> "put the short name of the owner of me into tGroup; if the flag of
> button "theButton" of group tGroup is...", rather than simply "if the
> flag of me is...".
More good news: the uncertainty you subjectively felt is well addressed
by the implementation. If you experiment a bit you'll find that "me" in
a behavior script will always refer to the target object.
Once you've experimented to verify this, you'll become confident with
their use and will want to use them every day. And every night. And on
the weekends. Highly addictive. :) Behaviors are one of the most
powerful additions to the language since arrays.
> Anyway. I doubt I will ever rely on behaviors again. And I don't feel
> confident enough with my programming skills to present this to LC as
> something like a bug. Cause I have been known to be wrong -- though
> not about mouseStillDown working now when it wasn't before.
Having addressed the unique anomaly that is the mouseStillDown message,
I hope you're inspired to give behaviors a fresh try.
While your own confidence may not be as strong as the moment, I'm
completely confident with with just an hour or two's experimentation to
verify how behaviors work, you'll enjoy using them going forward and
have simpler and more robust code in the process.
Hope all is well with you and yours in Tokyo -
LiveCode training and consulting: http://www.fourthworld.com
Webzine for LiveCode developers: http://www.LiveCodeJournal.com
LiveCode Journal blog: http://LiveCodejournal.com/blog.irv
More information about the Use-livecode