//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. } } }
/// @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; } } }
/// 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);
/// Time interval between tests for typing activity. Half a second seems to work well. integer TYPING_CHECK_PERIOD = 0.5;
/// Set up a timer to periodically check for typing activity. llSetTimerEvent(TYPING_CHECK_PERIOD);
/// 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] }