Multi-touch detector (click / double-click / long-click)

Soen Eber

Vatican mole
VVO Supporter 🍦🎈👾❤
Joined
Sep 20, 2018
Messages
3,931
muilti-click detects if a user performs a click, double-click, or long-click action (holds the mouse button down for an extended period of time). It comes in two scripts, although the main script may be excluded if you do not intend to use timers for any other action, such as dialog boxes. Otherwise there would be interference related to timer processing.

multi-click sends 3 link messages: "click", "double-click", "long-click". Each message is sent to the LINK_SET with a value of 0 and a key of the person who clicked the object the script is contained within. Message text intentionally includes hyphens ('-') instead of spaces as separators to prevent unintended side effects if message text is processed through one of the llParseString2List functions.

delay times for double-click and long-click determination can be set through the _long_click_delay and _double_click_delay values.
No other values should be changed.

script multi-click
C-like:
// multi-click
// Soen Eber (in-world) 2024
// license: use as you wish for commercial or non-commercial use, open or closed source as you prefer
// attribution would be helpful, but is not required

// muilti-click detects if a user performs a click, double-click, or long-click action (holds the mouse button down
// for an extended period of time).  It comes in two scripts, although the main script may be excluded if you do no
// intend to use timers for any other action, such as dialog boxes. Otherwise there would be interference related
// to timer processing.

// multi-click sends 3 link messages: "click", "double-click", "long-click".  Each message is sent to the LINK_SET
// with a value of 0 and a key of the person who clicked the object the script is contained within.  Message text
// intentionally includes hyphens ('-') instead of spaces as separators to prevent unintended side effects if
// message text is processed through one of the llParseString2List functions.

// delay times for double-click and long-click determination can be set through the _long_click_delay and
// _double_click_delay values.

// these values may be changed
float   _long_click_delay = 2.0;
float   _double_click_delay = 0.3;

// these values should be left alone
integer _wait_for_click = FALSE;
integer _long_hold = FALSE;
float   _elapsed = 0.0;
key     _id_touched;

// the on_click, on_double_click, and on_long_click functions may be edited.  If your intended code involves
// timer processing, such as for dialog boxes, you should only remove the llownerSay text and make your edits
// in the main script.
on_click()
{
    llMessageLinked(LINK_SET,0,"click",_id_touched);
    llOwnerSay("clicked by "+llKey2Name(_id_touched));
}
on_double_click()
{
    llMessageLinked(LINK_SET,0,"double_click",_id_touched);
    llOwnerSay("double-clicked by "+llKey2Name(_id_touched));
}
on_long_click()
{
    llMessageLinked(LINK_SET,0,"long_click",_id_touched);
    llOwnerSay("long-clicked by "+llKey2Name(_id_touched));
}

// the following code should be left untouched
//
default
{
    state_entry()
    {
        _elapsed = 0.0;
    }
    on_rez(integer startup_param)
    {
        llResetScript();
    }
    touch_start(integer num_detected)
    {
        _id_touched = llDetectedKey(0);
        _elapsed = llGetAndResetTime();
    }
    touch(integer num_detected)
    {
        _elapsed = llGetTime();
        if (_elapsed >= _long_click_delay) {
            on_long_click();
            _elapsed = llGetAndResetTime();
            _long_hold = TRUE;
        }
    }
    touch_end(integer num_detected)
    {
        if (_elapsed < _long_click_delay) {
            if (_wait_for_click) {
                llSetTimerEvent(0);
                _wait_for_click = FALSE;
                if (_long_hold) {
                    _long_hold = FALSE;
                }
                else {
                    on_double_click();
                }
            }
            else {
                _wait_for_click = TRUE;
                llSetTimerEvent(_double_click_delay);
            }
        }
    }
    timer()
    {
        llSetTimerEvent(0.0);
        if (_wait_for_click) {
            _wait_for_click = FALSE;
            if (_long_hold) {
                _long_hold = FALSE;
            }
            else {
                on_click();
            }
        }
    }
}
script main
C-like:
do_click(key id)
{
    llOwnerSay(llKey2Name(id)+" clicked me");
}
do_double_click(key id)
{
    llOwnerSay(llKey2Name(id)+" double clicked me");
}
do_long_click(key id)
{
    llOwnerSay(llKey2Name(id)+" long clicked me");
}
default
{
    state_entry()
    {
    }
    link_message(integer link, integer value, string msg, key id)
    {
        if (msg == "click") {
            do_click(id);
        }
        else if (msg == "double_click") {
            do_double_click(id);
        }
        else if (msg == "long_click") {
            do_long_click(id);
        }
    }
}
 
  • 1Like
Reactions: Jopsy Pendragon