In search of a Scripted Memo Board
- Kim McCabe
- Posts: 38
- Joined: Fri Mar 20, 2020 5:34 am
- Has thanked: 58 times
- Been thanked: 65 times
In search of a Scripted Memo Board
Does anyone have a scripted memo board that I can buy. Something that visitor's can leave a photo and a note on.
- These users thanked the author Kim McCabe for the post:
- Ilan Tochner
- Ilan Tochner
- Posts: 6527
- Joined: Sun Dec 23, 2012 8:44 am
- Has thanked: 4992 times
- Been thanked: 4473 times
- Contact:
- Kim McCabe
- Posts: 38
- Joined: Fri Mar 20, 2020 5:34 am
- Has thanked: 58 times
- Been thanked: 65 times
-
- Posts: 1314
- Joined: Sun Dec 23, 2012 2:26 pm
- Has thanked: 1134 times
- Been thanked: 1142 times
Re: In search of a Scripted Memo Board
Unless someone else offers, I don't mind having a go at this. Can you just clarify the functionality and size?Kim McCabe wrote: ↑Tue Aug 18, 2020 3:15 amDoes anyone have a scripted memo board that I can buy. Something that visitor's can leave a photo and a note on.
- These users thanked the author Graham Mills for the post (total 3):
- Ilan Tochner • Alexina Proctor • Frank SquirrelHerder
- Kim McCabe
- Posts: 38
- Joined: Fri Mar 20, 2020 5:34 am
- Has thanked: 58 times
- Been thanked: 65 times
Re: In search of a Scripted Memo Board
Hi, That's awesome! I think we need one in the Marketplace as I think a lot of people would buy one too. I had one in SL and used it on all of my places. Here is a link to one. It doesn't need to be this fancy with sound and all. But I would like one that people can add messages to and a photo. I'm adding a link to the page in the sl market so you can see what they did. https://marketplace.secondlife.com/p/pi ... rd/2132952Graham Mills wrote: ↑Tue Aug 18, 2020 12:05 pmUnless someone else offers, I don't mind having a go at this. Can you just clarify the functionality and size?Kim McCabe wrote: ↑Tue Aug 18, 2020 3:15 amDoes anyone have a scripted memo board that I can buy. Something that visitor's can leave a photo and a note on.
- These users thanked the author Kim McCabe for the post (total 2):
- Alexina Proctor • Frank SquirrelHerder
-
- Posts: 1314
- Joined: Sun Dec 23, 2012 2:26 pm
- Has thanked: 1134 times
- Been thanked: 1142 times
Re: In search of a Scripted Memo Board
First thoughts. At the moment this PinBlock handles only image UUID and 127 char of text (approx two short sentences) which it stores in the description field (which means you see some of it in the hover text when you mouse over it). It stores no readily recoverable user data and presently does not apply any type of lock to prevent deletion/overwriting.
To use it you insert the script below in a cube which in edit mode you can then shift-copy to create an array of the required dimensions (I would keep it small).
Touching/leftclicking the cube pops up a menu with options:
clear: removes both image and text data
edit: pops up a text box. Text entered is copied to the PinBlock description field so is limited to 127 chars. If you enter a valid texture UUID (obtained from the rightclick menu in inventory), the texture is displayed with the avatar name in an overlay at bottom right (this can be readily removed by commenting out the relevant line using //).
chat: sends the text in the description field in an instant message
display: sends the text and image UUID to a larger display prim (not done)
I have yet to fix listeners and timeouts on the dialogs. At present the image is displayed on all sides; you can either colour sides with unwanted images black or set the value for prim_surface to the appropriate value (0-5). [UPDATE] The text stored in the description field is now rendered on the prim but is overwritten by any image added subsequently (and vice versa). And yes, the word-wrap needs some work.
I played around with dragging images and notecards onto prims but came to the conclusion that in the first instance there was some merit in simplicity. Feedback welcome.
To use it you insert the script below in a cube which in edit mode you can then shift-copy to create an array of the required dimensions (I would keep it small).
Touching/leftclicking the cube pops up a menu with options:
clear: removes both image and text data
edit: pops up a text box. Text entered is copied to the PinBlock description field so is limited to 127 chars. If you enter a valid texture UUID (obtained from the rightclick menu in inventory), the texture is displayed with the avatar name in an overlay at bottom right (this can be readily removed by commenting out the relevant line using //).
chat: sends the text in the description field in an instant message
display: sends the text and image UUID to a larger display prim (not done)
I have yet to fix listeners and timeouts on the dialogs. At present the image is displayed on all sides; you can either colour sides with unwanted images black or set the value for prim_surface to the appropriate value (0-5). [UPDATE] The text stored in the description field is now rendered on the prim but is overwritten by any image added subsequently (and vice versa). And yes, the word-wrap needs some work.
I played around with dragging images and notecards onto prims but came to the conclusion that in the first instance there was some merit in simplicity. Feedback welcome.
Code: Select all
//script for basic pinblock 0.1
integer chan;
integer hndl;
integer hndl_dialog;
integer display_chan = -1221;//needs to be static
integer prim_surface = ALL_SIDES;
string avatar;
default
{
state_entry()
{
chan = (integer)(llFrand(-1000000000.0) - 1000000000.0);
hndl = llListen(chan, "", NULL_KEY, "");
}
on_rez(integer n)
{
chan = (integer)(llFrand(-1000000000.0) - 1000000000.0);
hndl = llListen(chan, "", NULL_KEY, "");
}
touch_start(integer n)
{
llListenRemove(hndl_dialog);
llDialog(llDetectedKey(0), "Choose option", ["clear", "chat", "display", "edit"], chan + 1);
hndl_dialog = llListen(chan + 1, "", NULL_KEY, "");
}
listen(integer c, string name, key id, string msg)
{
if (c == chan + 1)
{
if (msg == "edit")
{
llTextBox(id, "Enter 127 char text or image UUID", chan);
}
else if (msg == "clear")
{
llSetObjectDesc("");
llSetTexture(TEXTURE_BLANK, ALL_SIDES);
}
else if (msg == "chat")
{
llInstantMessage(id, llGetObjectDesc());
}
else if (msg == "display")
{
//do stuff on remote display prim
llWhisper(display_chan, (string)llGetTexture(0)+"|"+llGetObjectDesc());
}
}
if (c == chan)
{
if (osIsUUID(msg) == 1)
{
llSetTexture(msg, ALL_SIDES);
string sDynamicID = ""; // not implemented yet
string sContentType = "vector"; // vector = text/lines,etc. image = texture only
string sData = ""; // Storage for our drawing commands
string sExtraParams = "width:256,height:256"; // optional parameters in the following format: [param]:[value],[param]:[value]
integer iTimer = 0; // timer is not implemented yet, leave @ 0
integer iAlpha = 100; // 0 = 100% Alpha, 255 = 100% Solid
//
// sData (drawing commands) used in the example.
// draw a filled rectangle
sData = osSetPenSize(sData, 3); // Set the pen width to 3 pixels
sData = osSetPenColor(sData, "Black"); // Set the pen color to red
sData = osMovePen(sData, 200, 240); // Upper left corner at <28,78>
sData = osDrawFilledRectangle(sData, 55, 55); // 200 pixels by 100 pixels
// setup text to go in the drawn box
sData = osMovePen(sData, 205, 245); // place pen @ X,Y coordinates
sData = osSetFontName(sData, "Arial"); // Set the Fontname to use
sData = osSetFontSize(sData, 4); // Set the Font Size in pixels
sData = osSetPenColor(sData, "White"); // Set the pen color to Green
sData = osDrawText(sData, osKey2Name(id)); // The text to write
// Now draw it out
osSetDynamicTextureDataBlend( sDynamicID, sContentType, sData, sExtraParams, iTimer, iAlpha );
}
else
{
llSetObjectDesc(msg);
string CommandList = "";
list words = llParseString2List(msg, [" "], []);//[".", ",", ";", ":"]);
integer len = llGetListLength(words);
integer i = 0;
integer n = 0;
string s = "";
do
{
while(llStringLength(s) < 21)
{
if (llListFindList([llList2String(words, i)], [".", ",", ";", ":"]) > -1)
{
s = s +llList2String(words, i);
}
else
{
s = s + " "+llList2String(words, i);
}
i++;
}
CommandList = osMovePen( CommandList, 10, 10 + n*20 ); // Upper left corner at <10,10>
CommandList = osDrawText( CommandList, s );
n++;
s = "";
}
while (i < len);
CommandList = osSetFontSize(CommandList, 8);
CommandList = osMovePen( CommandList, 10, 230 ); // Upper left corner at <10,10>
CommandList = osDrawText( CommandList, osKey2Name(id) );
osSetDynamicTextureData( "", "vector", CommandList, "width:256,height:256", 0 );
}
}
}
}
- Kim McCabe
- Posts: 38
- Joined: Fri Mar 20, 2020 5:34 am
- Has thanked: 58 times
- Been thanked: 65 times
Re: In search of a Scripted Memo Board
WOW, I'm going to check it it out now. Thank You so much for doing this. I'll be back!Graham Mills wrote: ↑Wed Aug 19, 2020 9:17 pmFirst thoughts. At the moment this PinBlock handles only image UUID and 127 char of text (approx two short sentences) which it stores in the description field (which means you see some of it in the hover text when you mouse over it). It stores no readily recoverable user data and presently does not apply any type of lock to prevent deletion/overwriting.
To use it you insert the script below in a cube which in edit mode you can then shift-copy to create an array of the required dimensions (I would keep it small).
Touching/leftclicking the cube pops up a menu with options:
clear: removes both image and text data
edit: pops up a text box. Text entered is copied to the PinBlock description field so is limited to 127 chars. If you enter a valid texture UUID (obtained from the rightclick menu in inventory), the texture is displayed with the avatar name in an overlay at bottom right (this can be readily removed by commenting out the relevant line using //).
chat: sends the text in the description field in an instant message
display: sends the text and image UUID to a larger display prim (not done)
I have yet to fix listeners and timeouts on the dialogs. At present the image is displayed on all sides; you can either colour sides with unwanted images black or set the value for prim_surface to the appropriate value (0-5). [UPDATE] The text stored in the description field is now rendered on the prim but is overwritten by any image added subsequently (and vice versa). And yes, the word-wrap needs some work.
I played around with dragging images and notecards onto prims but came to the conclusion that in the first instance there was some merit in simplicity. Feedback welcome.
Code: Select all
//script for basic pinblock 0.1 integer chan; integer hndl; integer hndl_dialog; integer display_chan = -1221;//needs to be static integer prim_surface = ALL_SIDES; string avatar; default { state_entry() { chan = (integer)(llFrand(-1000000000.0) - 1000000000.0); hndl = llListen(chan, "", NULL_KEY, ""); } on_rez(integer n) { chan = (integer)(llFrand(-1000000000.0) - 1000000000.0); hndl = llListen(chan, "", NULL_KEY, ""); } touch_start(integer n) { llListenRemove(hndl_dialog); llDialog(llDetectedKey(0), "Choose option", ["clear", "chat", "display", "edit"], chan + 1); hndl_dialog = llListen(chan + 1, "", NULL_KEY, ""); } listen(integer c, string name, key id, string msg) { if (c == chan + 1) { if (msg == "edit") { llTextBox(id, "Enter 127 char text or image UUID", chan); } else if (msg == "clear") { llSetObjectDesc(""); llSetTexture(TEXTURE_BLANK, ALL_SIDES); } else if (msg == "chat") { llInstantMessage(id, llGetObjectDesc()); } else if (msg == "display") { //do stuff on remote display prim llWhisper(display_chan, (string)llGetTexture(0)+"|"+llGetObjectDesc()); } } if (c == chan) { if (osIsUUID(msg) == 1) { llSetTexture(msg, ALL_SIDES); string sDynamicID = ""; // not implemented yet string sContentType = "vector"; // vector = text/lines,etc. image = texture only string sData = ""; // Storage for our drawing commands string sExtraParams = "width:256,height:256"; // optional parameters in the following format: [param]:[value],[param]:[value] integer iTimer = 0; // timer is not implemented yet, leave @ 0 integer iAlpha = 100; // 0 = 100% Alpha, 255 = 100% Solid // // sData (drawing commands) used in the example. // draw a filled rectangle sData = osSetPenSize(sData, 3); // Set the pen width to 3 pixels sData = osSetPenColor(sData, "Black"); // Set the pen color to red sData = osMovePen(sData, 200, 240); // Upper left corner at <28,78> sData = osDrawFilledRectangle(sData, 55, 55); // 200 pixels by 100 pixels // setup text to go in the drawn box sData = osMovePen(sData, 205, 245); // place pen @ X,Y coordinates sData = osSetFontName(sData, "Arial"); // Set the Fontname to use sData = osSetFontSize(sData, 4); // Set the Font Size in pixels sData = osSetPenColor(sData, "White"); // Set the pen color to Green sData = osDrawText(sData, osKey2Name(id)); // The text to write // Now draw it out osSetDynamicTextureDataBlend( sDynamicID, sContentType, sData, sExtraParams, iTimer, iAlpha ); } else { llSetObjectDesc(msg); string CommandList = ""; list words = llParseString2List(msg, [" "], []);//[".", ",", ";", ":"]); integer len = llGetListLength(words); integer i = 0; integer n = 0; string s = ""; do { while(llStringLength(s) < 21) { if (llListFindList([llList2String(words, i)], [".", ",", ";", ":"]) > -1) { s = s +llList2String(words, i); } else { s = s + " "+llList2String(words, i); } i++; } CommandList = osMovePen( CommandList, 10, 10 + n*20 ); // Upper left corner at <10,10> CommandList = osDrawText( CommandList, s ); n++; s = ""; } while (i < len); CommandList = osSetFontSize(CommandList, 8); CommandList = osMovePen( CommandList, 10, 230 ); // Upper left corner at <10,10> CommandList = osDrawText( CommandList, osKey2Name(id) ); osSetDynamicTextureData( "", "vector", CommandList, "width:256,height:256", 0 ); } } } }
- Kim McCabe
- Posts: 38
- Joined: Fri Mar 20, 2020 5:34 am
- Has thanked: 58 times
- Been thanked: 65 times
Re: In search of a Scripted Memo Board
Was just checking it out. That's pretty nifty so far. I'm so amazed at what people can do with scripting!Graham Mills wrote: ↑Wed Aug 19, 2020 9:17 pmFirst thoughts. At the moment this PinBlock handles only image UUID and 127 char of text (approx two short sentences) which it stores in the description field (which means you see some of it in the hover text when you mouse over it). It stores no readily recoverable user data and presently does not apply any type of lock to prevent deletion/overwriting.
To use it you insert the script below in a cube which in edit mode you can then shift-copy to create an array of the required dimensions (I would keep it small).
Touching/leftclicking the cube pops up a menu with options:
clear: removes both image and text data
edit: pops up a text box. Text entered is copied to the PinBlock description field so is limited to 127 chars. If you enter a valid texture UUID (obtained from the rightclick menu in inventory), the texture is displayed with the avatar name in an overlay at bottom right (this can be readily removed by commenting out the relevant line using //).
chat: sends the text in the description field in an instant message
display: sends the text and image UUID to a larger display prim (not done)
I have yet to fix listeners and timeouts on the dialogs. At present the image is displayed on all sides; you can either colour sides with unwanted images black or set the value for prim_surface to the appropriate value (0-5). [UPDATE] The text stored in the description field is now rendered on the prim but is overwritten by any image added subsequently (and vice versa). And yes, the word-wrap needs some work.
I played around with dragging images and notecards onto prims but came to the conclusion that in the first instance there was some merit in simplicity. Feedback welcome.
Code: Select all
//script for basic pinblock 0.1 integer chan; integer hndl; integer hndl_dialog; integer display_chan = -1221;//needs to be static integer prim_surface = ALL_SIDES; string avatar; default { state_entry() { chan = (integer)(llFrand(-1000000000.0) - 1000000000.0); hndl = llListen(chan, "", NULL_KEY, ""); } on_rez(integer n) { chan = (integer)(llFrand(-1000000000.0) - 1000000000.0); hndl = llListen(chan, "", NULL_KEY, ""); } touch_start(integer n) { llListenRemove(hndl_dialog); llDialog(llDetectedKey(0), "Choose option", ["clear", "chat", "display", "edit"], chan + 1); hndl_dialog = llListen(chan + 1, "", NULL_KEY, ""); } listen(integer c, string name, key id, string msg) { if (c == chan + 1) { if (msg == "edit") { llTextBox(id, "Enter 127 char text or image UUID", chan); } else if (msg == "clear") { llSetObjectDesc(""); llSetTexture(TEXTURE_BLANK, ALL_SIDES); } else if (msg == "chat") { llInstantMessage(id, llGetObjectDesc()); } else if (msg == "display") { //do stuff on remote display prim llWhisper(display_chan, (string)llGetTexture(0)+"|"+llGetObjectDesc()); } } if (c == chan) { if (osIsUUID(msg) == 1) { llSetTexture(msg, ALL_SIDES); string sDynamicID = ""; // not implemented yet string sContentType = "vector"; // vector = text/lines,etc. image = texture only string sData = ""; // Storage for our drawing commands string sExtraParams = "width:256,height:256"; // optional parameters in the following format: [param]:[value],[param]:[value] integer iTimer = 0; // timer is not implemented yet, leave @ 0 integer iAlpha = 100; // 0 = 100% Alpha, 255 = 100% Solid // // sData (drawing commands) used in the example. // draw a filled rectangle sData = osSetPenSize(sData, 3); // Set the pen width to 3 pixels sData = osSetPenColor(sData, "Black"); // Set the pen color to red sData = osMovePen(sData, 200, 240); // Upper left corner at <28,78> sData = osDrawFilledRectangle(sData, 55, 55); // 200 pixels by 100 pixels // setup text to go in the drawn box sData = osMovePen(sData, 205, 245); // place pen @ X,Y coordinates sData = osSetFontName(sData, "Arial"); // Set the Fontname to use sData = osSetFontSize(sData, 4); // Set the Font Size in pixels sData = osSetPenColor(sData, "White"); // Set the pen color to Green sData = osDrawText(sData, osKey2Name(id)); // The text to write // Now draw it out osSetDynamicTextureDataBlend( sDynamicID, sContentType, sData, sExtraParams, iTimer, iAlpha ); } else { llSetObjectDesc(msg); string CommandList = ""; list words = llParseString2List(msg, [" "], []);//[".", ",", ";", ":"]); integer len = llGetListLength(words); integer i = 0; integer n = 0; string s = ""; do { while(llStringLength(s) < 21) { if (llListFindList([llList2String(words, i)], [".", ",", ";", ":"]) > -1) { s = s +llList2String(words, i); } else { s = s + " "+llList2String(words, i); } i++; } CommandList = osMovePen( CommandList, 10, 10 + n*20 ); // Upper left corner at <10,10> CommandList = osDrawText( CommandList, s ); n++; s = ""; } while (i < len); CommandList = osSetFontSize(CommandList, 8); CommandList = osMovePen( CommandList, 10, 230 ); // Upper left corner at <10,10> CommandList = osDrawText( CommandList, osKey2Name(id) ); osSetDynamicTextureData( "", "vector", CommandList, "width:256,height:256", 0 ); } } } }
- These users thanked the author Kim McCabe for the post:
- Graham Mills
-
- Posts: 1314
- Joined: Sun Dec 23, 2012 2:26 pm
- Has thanked: 1134 times
- Been thanked: 1142 times
Re: In search of a Scripted Memo Board
Further thoughts, still trying to keep things simple:
- Display pinblock to large screen (text and image) for 30 sec, locked against other users. "Disappears" on timeout.
- Lock pinblock prims for 4 min to allow uninterrupted editing.
- Prims edited by prim owner stay locked for other users.
- Render text and image on opposite sides of the prim and give users the option to flip the prim round.
- Put menu on pinblock?
- Have a rezzer that can generate an array of pinblocks plus display screen?
-
- Posts: 1314
- Joined: Sun Dec 23, 2012 2:26 pm
- Has thanked: 1134 times
- Been thanked: 1142 times
Re: In search of a Scripted Memo Board
Scratch code for the display screen which needs to be located within 10 m of the pinblock (ensure pinblock and display prim use same channel to communicate, default -1221). Presently displays image on face 0 and text on face 3 of a cube sheared and flattened so that both face the viewer (may need to adjust scale and rotation of faces). Assumes that the image was added last to the pinblock, otherwise displays text instead of image (needs fixing).
[UPDATE: Now autoconfigures/shapes the prim if you add the script to a standard 0.5x0.5x0.5 m box prim and touch/leftclick it.]
Times out after 30 sec and disappears so make it phantom, especially if at ground level.
Handy tip: if you want to know where a transparent object is, Ctrl-Alt-t will show and hide it again.
[UPDATE: Now autoconfigures/shapes the prim if you add the script to a standard 0.5x0.5x0.5 m box prim and touch/leftclick it.]
Times out after 30 sec and disappears so make it phantom, especially if at ground level.
Handy tip: if you want to know where a transparent object is, Ctrl-Alt-t will show and hide it again.
Code: Select all
integer hndl;
integer display_chan = -1221;
integer locked;
integer face_txt = 3;
integer face_img = 0;
default
{
state_entry()
{
hndl = llListen(display_chan, "", NULL_KEY, "");
locked = 0;
}
on_rez(integer n)
{
hndl = llListen(display_chan, "", NULL_KEY, "");
locked = 0;
}
touch_start(integer n)
{
if (llGetScale() == <0.5, 0.5, 0.5>) //configure display prim
{
llSetObjectName("PinBlock Display");
llSetStatus(STATUS_PHANTOM, TRUE);
llSetPos(llGetPos() + <0,0,1>);
vector angles_in_radians = <270,0,0>*DEG_TO_RAD; // Change to Radians
rotation rot_xyzq = llEuler2Rot(angles_in_radians); // Change to a Rotation
llSetRot(llGetRot()*rot_xyzq);
llSetPrimitiveParams([
PRIM_SIZE, <2.62524, 2.01980, 0.00191>, // keep the prim thin
PRIM_TYPE, PRIM_TYPE_BOX, 0, <0,1,0>, 0.0, ZERO_VECTOR,
<1,1,0>, <0.0, -0.4, 0.0>]);
llRotateTexture(PI, 0);
llSetTexture(TEXTURE_BLANK, 0);
llSetTexture(TEXTURE_BLANK, 3);
llOffsetTexture(-0.3, 0, 3);
}
}
listen(integer c, string name, key id, string msg)
{
if ((c == display_chan) && (locked == 0))
{
llSetAlpha(100.0, ALL_SIDES);
locked = 1;
llSetTimerEvent(30.0);//unlock, blank, set alpha
list display = llParseString2List(msg, ["|"], []);
if (osIsUUID(llList2String(display, 0)) == 1)
{
llSetTexture(llList2String(display, 0), face_img);
}
if (llStringLength(llList2String(display, 1)) > 0)
{
string submsg = llList2String(display, 1);
string CommandList = "";
list words = llParseString2List(submsg, [" "], []);//[".", ",", ";", ":"]);
integer len = llGetListLength(words);
integer i = 0;
integer n = 0;
string s = "";
do
{
while(llStringLength(s) < 21)
{
if (llListFindList([llList2String(words, i)], [".", ",", ";", ":"]) > -1)
{
s = s +llList2String(words, i);
}
else
{
s = s + " "+llList2String(words, i);
}
i++;
}
CommandList = osMovePen( CommandList, 10, 10 + n*20 ); // Upper left corner at <10,10>
CommandList = osDrawText( CommandList, s );
n++;
s = "";
}
while (i < len);
CommandList = osSetFontSize(CommandList, 8);
CommandList = osMovePen( CommandList, 10, 230 ); // Upper left corner at <10,10>
CommandList = osDrawText( CommandList, osKey2Name(id) );
osSetDynamicTextureDataFace("", "vector", CommandList, "width:512,height:256", 0, face_txt);;
}
}
}
timer()
{
llSetTimerEvent(0.0);
locked = 0;
llSetAlpha(0.0, ALL_SIDES);
llSetTexture(TEXTURE_BLANK, ALL_SIDES);
}
}