Difference between revisions of "NexUI"

From Second Life Wiki
Jump to navigation Jump to search
 
(8 intermediate revisions by the same user not shown)
Line 3: Line 3:


= User Interface Project =
= User Interface Project =
'''Project Subject to change at any time due to being currently under development.'''


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.
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.
Line 8: Line 10:
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).
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).


== Setup ==
Update: Due to issues with high size due to compiled code being quite extensive due to number of helper functions stacking up as well complexity of functions generally, as well as for general ease-of-use, I will be re-designing the project into an API.


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


new script, name as 'uiMaster'. This is the default basic setup:
{| uiFunction
<lsl>
|-
default{
| Mode
    state_entry(){
| Stuff
        uiInit();
|-
        llMinEventDelay( 0.10 );
| 0
    }
| ''process'' touch_start() event, initialization
   
|-
    touch_start( integer dn ){
| 1
        integer lLink = llDetectedLinkNumber( 0 );
| ''process'' touch() event, feedback, and ''get'' values
        string lName = llGetLinkName( lLink );
|-
        integer x = llListFindList( uiNm, [lName] );
| 2
        if( ~x ) Lnk = llList2Integer( uiLnk, x );
| ''process'' touch_end() event and ''get'' values
       
|-
        if( lName == "My UI Element #1" ){
| 3
            // uiFunction( 0 );
| ''get'' values
        }
|-
    }
| 4
   
| ''set'' values, refresh graphics
    touch( integer dn ){
|-
        integer lLink = llDetectedLinkNumber( 0 );
| 5
        string lName = llGetLinkName( lLink );
| ''initalize'', set default values, refresh
        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.
== Design, Menu ==


<lsl>
Example notecard script 'uiMenu:Test' for child prim named 'Test'
integer x;
<pre>
Menu A{
    Texture: 00000000-0000-0000-0000-000000000000
    Button: Rect : 0.12, 0.20 | 0.20, 0.23 : Goto : Menu B : Transition : Alpha
    Button: Rect : 0.12, 0.15 | 0.20, 0.18 : Return : "Custom String"
    Button: Rect : 0.12, 0.10 | 0.20, 0.13 : Link Msg : LINK_SET : 1024 : "Toggle" : ""
    Button: Rect : 0.12, 0.05 | 0.20, 0.08 : Goto : Menu C : Transition : Alpha
}


default{
Menu B{
     state_entry(){
     Texture: 00000000-0000-0000-0000-000000000000
        x = (integer)llList2String( llParseString2List( llGetScriptName(), [":"], [] ), 1 );
    Button: Rect : 0.50, 0.40 | 0.70, 0.44 : Goto : Menu B : Transition : Alpha
        state Main;
    }
}
}


state Main{
Menu C{
     link_message( integer sn, integer n, string str, key k ){
     Texture: 00000000-0000-0000-0000-000000000000
        if( n == x ){
    Repeats: 0.5, 1.0
            list t = llParseString2List( str, ["|"], [] );
    Offset: -0.25, 0.0
            llSetLinkPrimitiveParams( (integer)llList2String(t,0),
    Button: Rect : 0.10, 0.90 | 0.20, 0.95 : Goto : Menu D : Transition : Anim : 1.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 #############-->


{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
Menu D{
!style="color: #000000; background-color: #aaaaff;" height="20px"|
    Texture: 00000000-0000-0000-0000-000000000000
Initialization
    Repeats: 0.5, 1.0
|-
    Offset: 0.25, 0.0
|
     Button: Rect : 0.80, 0.90 | 0.90, 0.95 : Goto : Menu C : Transition : Anim : 1.0
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>
</pre>


{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
== Setup ==
!style="background-color: #d0d0ee" | Process
!style="background-color: #d0d0ee" | Description
|-
| uiInit
| Initializes by assorting all the child prims
|}
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
|}


<!--############# SLIDER #############-->
== uiFunctions ==


<!--############# TURN #############-->
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Slider
Turn
|-
|-
|
|
Slider script.
Turn component, imagine a turntable, or the 'iPod' menu.
 
<lsl>
<lsl>
list uiSlider1( integer Mode, key kTexture ){
    link_message( integer sender, integer num, string str, key k ){
if( llDetectedTouchFace( 0 ) == -1 ) return [-1];
        // Example use here..
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 [-1]; }
</lsl>
</lsl>


{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
!style="background-color: #d0d0ee" | Input
!style="background-color: #d0d0ee" | Description
|-
| integer Mode
| Mode of uiFunction, 0 - Touch Start, 1 - Touch, 2 - Touch End
|-
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Description
!style="background-color: #d0d0ee" | Description
|-
|-
| return list uiSlider1( 1, key kTexture )
| return link message, num with (TBD)
| Returns list with value of 0.0 - 1.0 of slider.
| Returns ''Str'' as ''¬'' delimited list with values: [Angle], angle is 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 uiSlider1( 2, key kTexture )
| return link message, num with (TBD)
| Returns list with value of 0.0 - 1.0 of slider.
| Returns ''Str'' as ''¬'' delimited list with values: [Final Angle], Empty list on error.
|}
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
|}
 
 
<!--############# CLICK AND DRAG #############-->
 
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Click and Drag
|-
|-
|
Based on my [[ClickAndDrag|Click and Drag]] script.
<lsl>
list uiCND( integer Mode ){
if( llDetectedTouchFace( 0 ) == -1 ) return [-1];
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 [-1];
    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 //
    key nKey = llDetectedKey( 0 ); vector tPos = llDetectedTouchPos( 0 );
    tData2 = [ tPos, llDetectedTouchNormal( 0 ), llDetectedTouchBinormal( 0 ) ];
    vector ST2 = llDetectedTouchST( 0 );
   
    if( ST1 == <-1,-1,0> || ST2 == <-1,-1,0> )
        return [-1];
   
    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 [-1]; }
</lsl>
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
!style="background-color: #d0d0ee" | Input
!style="background-color: #d0d0ee" | Input
!style="background-color: #d0d0ee" | Description
!style="background-color: #d0d0ee" | Description
|-
|-
| integer Mode
| link message, num, str, key
| Mode of uiFunction, 0 - Touch Start, 1 - Touch, 2 - Touch End
| Num (TBD) ''OR'''d with ''Mode'' of uiFunction, As follows: 3 - Get or 4 - Set
|-
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Description
|-
| return list uiCND( 2 )
| Returns list of values, if on error returns one item of '-1', [[ClickAndDrag|else same return data as my script.]]
|}
|}
<div style="float:right;font-size: 80%;">
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
By Nexii Malthus</div>
|}
|}

Latest revision as of 00:22, 19 December 2008

User Interface Project

Project Subject to change at any time due to being currently under development.

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).

Update: Due to issues with high size due to compiled code being quite extensive due to number of helper functions stacking up as well complexity of functions generally, as well as for general ease-of-use, I will be re-designing the project into an API.

Design, Components

Mode Stuff
0 process touch_start() event, initialization
1 process touch() event, feedback, and get values
2 process touch_end() event and get values
3 get values
4 set values, refresh graphics
5 initalize, set default values, refresh

Design, Menu

Example notecard script 'uiMenu:Test' for child prim named 'Test'

Menu A{
    Texture: 00000000-0000-0000-0000-000000000000
    Button: Rect : 0.12, 0.20 | 0.20, 0.23 : Goto : Menu B : Transition : Alpha
    Button: Rect : 0.12, 0.15 | 0.20, 0.18 : Return : "Custom String"
    Button: Rect : 0.12, 0.10 | 0.20, 0.13 : Link Msg : LINK_SET : 1024 : "Toggle" : ""
    Button: Rect : 0.12, 0.05 | 0.20, 0.08 : Goto : Menu C : Transition : Alpha
}

Menu B{
    Texture: 00000000-0000-0000-0000-000000000000
    Button: Rect : 0.50, 0.40 | 0.70, 0.44 : Goto : Menu B : Transition : Alpha
}

Menu C{
    Texture: 00000000-0000-0000-0000-000000000000
    Repeats: 0.5, 1.0
    Offset: -0.25, 0.0
    Button: Rect : 0.10, 0.90 | 0.20, 0.95 : Goto : Menu D : Transition : Anim : 1.0
}

Menu D{
    Texture: 00000000-0000-0000-0000-000000000000
    Repeats: 0.5, 1.0
    Offset: 0.25, 0.0
    Button: Rect : 0.80, 0.90 | 0.90, 0.95 : Goto : Menu C : Transition : Anim : 1.0
}

Setup

uiFunctions

Turn

Turn component, imagine a turntable, or the 'iPod' menu. <lsl>

   link_message( integer sender, integer num, string str, key k ){
       // Example use here..
   }

</lsl>

Output Description
return link message, num with (TBD) Returns Str as ¬ delimited list with values: [Angle], angle is 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 link message, num with (TBD) Returns Str as ¬ delimited list with values: [Final Angle], Empty list on error.
Input Description
link message, num, str, key Num (TBD) OR'd with Mode of uiFunction, As follows: 3 - Get or 4 - Set
By Nexii Malthus