Don't click here unless you want to be banned.

LSL Wiki : LibraryKeyboardScript

HomePage :: PageIndex :: RecentChanges :: RecentlyCommented :: UserSettings :: You are crawl805.us.archive.org
Ok, so here's my first addition to the library. Feedback welcome. bugs? Poor choice of implementation? Contact me in world.
Yes, I know it's commenty, but the comments aren't for you 733T 5cr!pt3r5 - it's to help newer people navigate, explain what's what - you don't need this script, anyway. XD

You can drop this in a rectangular prim and it should work.

Thanks to Strife for pointers/cleanup.

Max

//Max Case's Free Keyboard Script 1.0  04/18/2005
//Put it in a prim, attach it to yourself (or not) and watch as a keyboard magically appears whenever you type.
//Feel free to reuse, etc.

//Please don't just resell this script. That would be lame, since I am giving it to you for free.
//naturally, if you build something nice off of it, sell that. 
//Or make a nice texture you would like to sell with keyboard script, that's ok. Just leave script open to all to see.
//Feedback/Rates/Donations/Hate Mail always welcome. Don't be shy.
//leave in the comments. they don't affect performance, and they are meant to help other beginners learn about LSL.
// - Max
//25.03.2007 This was written before things like CHANGED_OWNER, and before I knew what I  was doing :) Dusting it off.

integer keyboard_status; //Used to track if the keyboard is visible or not.
key kbTexture = "eef62334-e85e-b8f5-0717-19056bdbafde";
integer box_face = 0; //What side to show the keyboard. 0 means Top

initialize() {
    llSay(0, "Welcome to Max's Symple Keyboard.");     //You can change the welcome messages here.
    llSay(0, "initializing...");
    llSetTexture(kbTexture, box_face);        //Setting the Keyboard Texture
    llSetTextureAnim(ANIM_ON | LOOP, box_face, 4, 1, 0, 0, 4); //Set the typing animation

    llSetAlpha(0.0, ALL_SIDES);            //Hide the keyboard.

    llSetTimerEvent(.5);         //honestly you could make this shorter, but what would be the point? .5 seems to work nice.
    keyboard_status = FALSE;    //Keep track of the keyboards visibility.
}

default {
    state_entry() {
       initialize();
    }

    changed(integer change) {
        if (change & CHANGED_OWNER) {
            llResetScript();
        }
    }         

    timer() {
        // are we typing? Well? Are we??? thanks to Strife for rewrite here.
        integer are_we_typing = llGetAgentInfo(llGetOwner()) & AGENT_TYPING; 

        if (keyboard_status != are_we_typing ) { //keyboard_status changed since last checked?
            llSetAlpha(!keyboard_status, box_face);//flip the keyboard_status
            keyboard_status = are_we_typing;//save the current keyboard_status.
        }
    }  
}


ScriptLibrary
Comments [Hide comments/form]
This is my first venture into "code reuse" in SL! :-) I just took Max's code, and made a very minor tweak (changed default face to be top instead of side). Mainly, I reformatted, added comments, renamed variables for clarity, and also enforced hungarian notation, CamelCode, and caps/underscores for "immutables". It also uses a Doxygen compatible format for automatic documentation extraction. I was just interested in finding out if folks think this level of comment/detail is a help or a hinderence. Also, I felt uncomfortable with either replacing the existing one or creating a new one till I got feedback, being a newb and all. -VA

/// @file LibraryKeyboardScript.lsl
/// Max Case's Free Keyboard Script 1.0  04/18/2005
///
/// Put it in a prim, attach it to yourself (or not) and watch as a
/// keyboard magically appears whenever you type.  Feel free to reuse, etc. 
/// Please don't just resell this script. That would be lame, since I am
/// giving it to you for free.  Naturally, if you build something nice off
/// of it, sell that.
///
/// Or make a nice texture you would like to sell with keyboard script, 
/// that's ok. Just leave script open to all to see.
///
/// Feedback/Rates/Donations/Hate Mail always welcome. Don't be shy.
/// leave in the comments; they don't affect performance.
/// – Max
///
/// Code comments assume that the keyboard is attached to a 
/// cube primitive ('prim'), one of the simplest default objects to make. -VA
///
/// @author Max Case, 04/18/2005
/// @author Vershana Amarula, 05/26/2005
///
/// Change history
///
/// 05/26/2005-VA  Tweaks, changed variable names, added comments 
///                and constants
///
///

///
/// Declaration section - define and initialize all needed variables
///

/// Keeps track of who is holding the object. 
key kOwner;

/// Keeps track of the last typing state detected. 
integer iPrevState;

/// UUID (or key) of the texture to represent the (yellow) keyboard. 
key TEX_KB_YELLOW = "eef62334-e85e-b8f5-0717-19056bdbafde";

/// Number of horizontal frames in the animated texture.
integer TEX_X_FRAMES = 4;

/// Number of vertical frames in the animated texture.
integer TEX_Y_FRAMES = 1;

/// Number of frames per second for the animated texture.
float TEX_FPS = 4.0;

/// UUID (or key) of a transparent texture (not really necessary). 
key TEX_TRANSPARENT = "f54a0c32-3cd1-d49a-5b4f-7b792bebc204";

/// The side of the prim upon which to display the keyboard. 
integer BOX_TOP = 0;

/// Opacity percentage that represents "completely transparent". 
float TRANSPARENT = 0.0;

/// Time interval to wait between testing for typing activity. 
float ONE_HALF_SECOND = .5;

/// Value to represent the (initial) state of "not typing". 
integer IS_NOT_TYPING = 0;

/// Perform all necessary operations to prepare script for use here.
initialize()
{
        // Announce startup of the script.
        llSay(0, "Welcome to Max's Symple Keyboard.");
        llSay(0, "initializing...");
       
        // Apply the transparent texture to all box surfaces.
        llSetTexture(TEX_TRANSPARENT, ALL_SIDES);
       
        // Make the object (typically a box) top look sort've
        // like a keyboard by applying a "keyboard" texture to
        // the top of it.
        llSetTexture(TEX_KB_YELLOW, BOX_TOP);
       
        // The texture is actually an animated image, so activate
        // the animation.  ANIM_ON is self explanatory; LOOP means 
        // to replay the animation continuously.  BOX_TOP is the side
        // of the prim containing the texture to be animated,
        // TEX_X_FRAMES is the number of internal animation frames
        // in each row of the TEX texture, and TEX_Y_FRAMES are
        // the number rows.  TEX_FPS is the number of frames to 
        // display each second.
        llSetTextureAnim(ANIM_ON | LOOP, BOX_TOP, TEX_X_FRAMES, 
                TEX_Y_FRAMES, 0.0, 0.0, TEX_FPS);
       
        // Make the entire box invisible (including the keyboard).
        llSetAlpha(TRANSPARENT, ALL_SIDES);

        // Honestly you could make this shorter, but what would be the
        // point? .5 seems to work nice.  
        llSetTimerEvent(ONE_HALF_SECOND);

        // During initialization, store the current owner to verify
        // against later.  If the owner changes, we'll reinitialize.
        kOwner = llGetOwner();
       
        // Assume that the owner is NOT typing at the time we're initialized.
        iPrevState = IS_NOT_TYPING;
}

/// All behaviors associated with the default state.
default
{
    // Operations to perform when entering state "default"
    state_entry()
    {
        // Checks to see if we have changed owner when the script starts
        // and (re)initializes if so.
        if(llGetOwner() != kOwner) 
        {
            initialize();
        }
    }

    // Operations to perform when "rezzing" (using) the object          
    on_rez(integer total_number)
    {
        // Checks for new owner when object is rezzed and (re)initializes
        // if so.
        if(llGetOwner() != kOwner)
        {
            initialize();
        }
    }

    // Operations to perform when the amount of time set with llSetTimerEvent
    // elapses (every half second in this case)
    timer()
    {
        // Are we typing?  Thanks to Strife for rewrite here, though I find 
        // this sort of condensed logic can be confusing for non-programmer 
        // type,  But this is definitely more efficient.
        integer iTypingState = llGetAgentInfo(kOwner) & AGENT_TYPING;

        // Has status changed since last checked?
        if (iPrevState != iTypingState) 
        {
            // Flip the visibility of the box top (this makes it 1 or 0, 
            // instead of AGENT_TYPING or 0) and save the current state.
            llSetAlpha(!iPrevState, BOX_TOP);
            iPrevState = iTypingState;
        }
    } 
}
-- VershanaAmarula (2005-05-30 07:13:35)
/// Time interval to wait between testing for typing activity. 
float ONE_HALF_SECOND = .5;

// [...]

// Honestly you could make this shorter, but what would be the
// point? .5 seems to work nice. 
llSetTimerEvent(ONE_HALF_SECOND);

This kind of thing is the bane of support programmers everywhere.

First, give it a meaningful name and explain why its that value when you define it.

/// Time interval between tests for typing activity. Half a second seems to work well.
integer TYPING_CHECK_PERIOD = 0.5;

Then explain the code in the code.

/// Set up a timer to periodically check for typing activity.

llSetTimerEvent(TYPING_CHECK_PERIOD);

Also, one additional change I made in my version of the keyboard should be added to the time.

/// Value to represent the state of "not being held"
integer IS_NOT_HELD = -1;

/// Value to represent the state of "typing"
integer IS_TYPING = AGENT_TYPING;

/// (define all states even if you don't use them all now, you'll be glad you did)

// [...]

timer()
{
    // Is someone holding me?
    integer iAttached = llGetAttached();

    if(iAttached == 0)
    {
        // Nope, make myself visible (if I haven't already)!
        if(iPrevState != IS_NOT_HELD)
        {
            llSetAlpha(1, BOX_TOP);
            iPrevState = IS_NOT_HELD;
         }
         return;
    }
// [rest of timer() is the same, since IS_DROPPED_STATE won't match AGENT_TYPING or !AGENT_TYPING]
}
-- ResunaOddfellow (2005-08-24 07:34:18)
@VershanaAmarula Thanks for the re-write. The thing is, I am trying to keep it accessible to less experienced people, and your format I think can be intimidating.

@Resuna Thanks.

I'm not making vars like time_to_check, because its less important for someone trying to make a keyboard to change that. It's clealy commented in the code, and is only called once, in the script head, so not so much hunting around for it. (aside from the fact the the script itself is only 49 lines, with comments.)
-- MaxCase (2007-03-25 06:58:25)
Attach a comment to this page: