Difference between revisions of "NexUI"

From Second Life Wiki
Jump to navigation Jump to search
Line 16: Line 16:
|-
|-
| 0
| 0
| 'process' touch_start() event
| ''process'' touch_start() event
|-
|-
| 1
| 1
| 'process' touch() event
| ''process'' touch() event
|-
|-
| 2
| 2
| 'process' touch_end() event and 'get' values
| ''process'' touch_end() event and ''get'' values
|-
|-
| 3
| 3
| 'set' values
| ''set'' values
|}
|}



Revision as of 12:17, 29 November 2008

User Interface Project

A project to try create an efficient, flexible and innovative User Interface in LSL. Without being complex to use or using a ridicolous amount of constants, providing direct results that can be returned and used by the scripter directly in a Master script for efficiency, or used via automation of a UI master to a link-message protocol sent to scripts written by the original scripter.

The User Interface Project is to create a UI that can be used in-world as well as on the HUD, providing pseudo-dynamic graphical feedback to the user(s).

Design

Mode Stuff
0 process touch_start() event
1 process touch() event
2 process touch_end() event and get values
3 set values

Setup

Rez a object to serve as root, recommended as the menu-background of the UI.

new script, name as 'uiMaster'. This is the default basic setup: <lsl> default{

   state_entry(){
       uiInit();
       llMinEventDelay( 0.10 );
   }
   
   touch_start( integer dn ){
       integer lLink = llDetectedLinkNumber( 0 );
       string lName = llGetLinkName( lLink );
       integer x = llListFindList( uiNm, [lName] );
       if( ~x ) Lnk = llList2Integer( uiLnk, x );
       
       if( lName == "My UI Element #1" ){
           // uiFunction( 0 );
       }
   }
   
   touch( integer dn ){
       integer lLink = llDetectedLinkNumber( 0 );
       string lName = llGetLinkName( lLink );
       integer x = llListFindList( uiNm, [lName] );
       if( ~x ) Lnk = llList2Integer( uiLnk, x );
       
       if( lName == "My UI Element #1" ){
           // uiFunction( 1 );
       }
   }
   
   touch_end( integer dn ){
       integer lLink = llDetectedLinkNumber( 0 );
       string lName = llGetLinkName( lLink );
       integer x = llListFindList( uiNm, [lName] );
       if( ~x ) Lnk = llList2Integer( uiLnk, x );
       
       if( lName == "My UI Element #1" ){
           // variable = uiFunction( 2 );
       }
   }

} </lsl>

new scripts (4 total), name as 'uiSlave:0', 'uiSlave:1', 'uiSlave:2' and 'uiSlave:3', which serve to speed up feedback significantly of the pseudo dynamic graphics.

<lsl> integer x;

default{

   state_entry(){
       x = (integer)llList2String( llParseString2List( llGetScriptName(), [":"], [] ), 1 );
       state Main;
   }

}

state Main{

   link_message( integer sn, integer n, string str, key k ){
       if( n == x ){
           list t = llParseString2List( str, ["|"], [] );
           llSetLinkPrimitiveParams( (integer)llList2String(t,0), 
               [(integer)llList2String(t,1),
                (integer)llList2String(t,2),
                    (key)llList2String(t,3),
                 (vector)llList2String(t,4),
                 (vector)llList2String(t,5),
                  (float)llList2String(t,6)] );
       }
   }

} </lsl>

uiFunctions

Initialization

Initializes UI Elements into lists. Goes through all child prims to identify them as being a UI element by their prim description. And includes them into global lists of link number, name and their UI type for:

  • use in other functions
  • debug
  • saving time from re-searching entire linksets again and;
  • preventing objects having hard-coded scripts which would defy the point of flexibility.

<lsl> uiInit(){

   integer y = llGetNumberOfPrims();
   while( --y-1 ){
       list Dat = llGetObjectDetails( llGetLinkKey( y ), [OBJECT_NAME,OBJECT_DESC] );
       string lDesc = llList2String( Dat, 1 );
       if( llGetSubString( lDesc, 0, 2 ) == "UI_" ){
           uiLnk = (uiLnk = []) + uiLnk + y;
           uiNm = (uiNm = []) + uiNm + llList2String( Dat, 0 );
           uiType = (uiType = []) + uiType + lDesc;
       }
   }

} </lsl>

Process Description
uiInit Initializes by assorting all the child prims
By Nexii Malthus


Slider

Slider script.

<lsl> list uiSlider1( integer Mode, key kTexture ){ if( llDetectedTouchFace( 0 ) != 0 ) return []; if( Mode == 0 ){ // START //

} else if( Mode == 1 ){ // TOUCH //

   vector Scale = < 1.0, 0.5, 0.0 >;
   vector Offset; vector ST = llDetectedTouchST( 0 );
   if( ST.y > 0.98 ){Offset.y = -0.25;ST.y = 1.0;}
   else if( ST.y < 0.02 ){Offset.y = 0.25;ST.y = 0.0;}
   else Offset.y = 0.25 - ST.y/2;
   
   llMessageLinked( LINK_THIS, Smoother, llDumpList2String( [Lnk,PRIM_TEXTURE,0,kTexture,Scale,Offset,0], "|" ), "" );
   if( ++Smoother > 3 ) Smoother = 0;
   return [ST.y];

} else if( Mode == 2 ){ // END //

   vector ST = llDetectedTouchST( 0 );
   if( ST.y > 0.98 ) ST.y = 1.0;
   else if( ST.y < 0.02 ) ST.y = 0.0;
   return [ST.y];

} return []; } </lsl>

Textures <lsl> key kTextureSlide1 = "05d64d5d-a42e-2c91-3088-6e7f4851c458"; key kTextureSlide2 = "2f0f4512-d804-9e3e-61a2-222bf4270b2f"; </lsl>

Input Description
integer Mode Mode of uiFunction, 0 - Touch Start, 1 - Touch, 2 - Touch End
Output Description
return list uiSlider1( 1, key kTexture ) Returns list with value [Range], 0.0 - 1.0 of slider. Empty list on error.
return list uiSlider1( 2, key kTexture ) Returns list with value [Range], 0.0 - 1.0 of slider. Empty list on error.
By Nexii Malthus


Turn

Turn component, imagine a turntable, or the iPod menu.

<lsl> list uiTurn( integer Mode ){

   integer Face = llDetectedTouchFace( 0 );
   if( Face != 0 ) return [];
   
   if( Mode == 0 ){
       
   } else if( Mode == 1 ){
       vector ST = llDetectedTouchST( 0 );
       
       vector Scale = < 0.97, 0.97, 0.0 >;
       vector Offset = < 0.0, 0.0, 0.0 >;
       float Turn = llAtan2( 0.5 - ST.y, 0.5 - ST.x );
       
       llMessageLinked( LINK_THIS, Smoother, llDumpList2String( [Lnk,PRIM_TEXTURE,0,"9ab6a2f8-8f26-0edc-53ba-db786618ce49",Scale,Offset,Turn], "|" ), "" );
       if( ++Smoother > 3 ) Smoother = 0;
       return [Turn];
   } else if( Mode == 2 ){
       vector ST = llDetectedTouchST( 0 );
       return [llAtan2( 0.5 - ST.y, 0.5 - ST.x )];
   } return [];}

</lsl>

Input Description
integer Mode Mode of uiFunction, 0 - Touch Start, 1 - Touch, 2 - Touch End
Output Description
return list uiTurn( 1 ) Returns list with value [Angle], angle in radians, -PI to 0 to PI, or when multiplied by RAD_TO_DEG it is -180 to 0 to 180. Empty list on error.
return list uiTurn( 2 ) Returns list with final value [Angle]. Empty list on error.
By Nexii Malthus


Click and Drag

Based on my Click and Drag script.

<lsl> list uiCND( integer Mode ){ if( llDetectedTouchFace( 0 ) != 0 ) return []; if( Mode == 0 ){ // START //

   tData1 = [ llDetectedTouchPos(0), llDetectedTouchNormal(0), llDetectedTouchBinormal(0) ];
   ST1 = llDetectedTouchST( 0 );

} else if( Mode == 1 ){ // TOUCH //

   vector ST2 = llDetectedTouchST( 0 );
   if( ST1 == <-1,-1,0> || ST2 == <-1,-1,0> ) return [];
   if( llVecDist( ST1, ST2 ) > 0.01 ){
       llSetLinkColor( Lnk, < 0.0, 0.0, 1.0 >, 0 ); llSetLinkAlpha( Lnk, 0.2, 0 );
       float relSize = 0.08;//0.084;
       vector selCentre = <1,1,0> - ((ST2+ST1)/2);
       vector selSize = (ST1-ST2); selSize = <llFabs(selSize.x),llFabs(selSize.y),0>;
       
       vector Scale = <relSize/selSize.x,relSize/selSize.y,0>;
       vector Offset = (selCentre-<0.5,0.5,0>);
       Offset = <Offset.x*Scale.x,Offset.y*Scale.y,0>;
       llMessageLinked( LINK_THIS, Smoother, llDumpList2String( [Lnk,PRIM_TEXTURE,0,kTextureDrag,Scale,Offset,0], "|" ), "" );
       if( ++Smoother > 3 ) Smoother = 0;
   }

} else if( Mode == 2 ){ // END //

   tData2 = [ llDetectedTouchPos( 0 ), llDetectedTouchNormal( 0 ), llDetectedTouchBinormal( 0 ) ];
   vector ST2 = llDetectedTouchST( 0 );
   
   if( ST1 == <-1,-1,0> || ST2 == <-1,-1,0> )
       return [];
   
   if( llVecDist( ST1, ST2 ) < 0.01 ){
       llSetLinkColor( Lnk, < 0.0, 1.0, 0.0 >, 0 ); llSetLinkAlpha( Lnk, 1.0, 0 );
       vector Scale = < 1.0, 1.0, 0>;
       vector Offset = < 1.0, 1.0, 0 > - ST1;
       llSetLinkPrimitiveParams( Lnk, [ PRIM_TEXTURE, 0, kTextureClick, Scale, Offset, 0 ]);
       llSetLinkAlpha( Lnk, 0.0, 0 );
       return [0] + tData1;
   } else {
       llSetLinkColor( Lnk, < 0.0, 0.0, 1.0 >, 0 ); llSetLinkAlpha( Lnk, 0.2, 0 );
       float relSize = 0.08;
       vector selCentre = <1,1,0> - ((ST2+ST1)/2);
       vector selSize = (ST1-ST2); selSize = <llFabs(selSize.x),llFabs(selSize.y),0>;
       vector Scale = <relSize/selSize.x,relSize/selSize.y,0>;
       vector Offset = (selCentre-<0.5,0.5,0>);Offset = <Offset.x*Scale.x,Offset.y*Scale.y,0>;
       llSetLinkPrimitiveParams( Lnk, [ PRIM_TEXTURE, 0, kTextureDrag, Scale, Offset, 0 ]);
       llSetLinkAlpha( Lnk, 0.0, 0 );
       return [1] + tData1 + tData2;
   }

} return []; } </lsl>

Textures <lsl> key kTextureClick = "5d431ade-24f3-2390-f1ba-ca404cad2864"; key kTextureDrag = "efc411bc-2005-10ff-da0c-3dda972f6e70"; </lsl>

Input Description
integer Mode Mode of uiFunction, 0 - Touch Start, 1 - Touch, 2 - Touch End
Output Description
return list uiCND( 2 ) Returns list of values, Click [0,World Pos,Normal,Bi-Normal], Drag [1,Pos1,N1,BN1,Pos2,N2,BN2], if on error returns empty list.
By Nexii Malthus