Interface Commands

 

This section describes the interface commands available to both Layout and Modeler LScripts. These functions create, edit and request information from controls in an interface. Controls can include text, lists, buttons, and tabs.

Although some of these commands and their parameters can be created automatically using the LScript Interface Designer(LSID), its important to be able to read and understand their usage in case you have to edit them manually.

Messages

info
The info() command displays a message on the screen. This message box supports multiple data types.

prototype:           void info(text)

text:                   string; message to be displayed.

example:

info("hello world!");

prototype:      void info(text)

text               string; message to be displayed.

example:

info("hello world!");

warn

The warn() command displays a warning message on the screen. This message box supports multiple data types. The script continues to run after the command is invoked.

prototype:      void warn(text)

text               string; message to be displayed.

example:

warn("Invalid Selection");

error
The error() command displays an error message on the screen. This message box supports multiple data types. The script ends after the error() command is invoked.

prototype:      void error(text)

text      string; message to be displayed.

example:

error("Internal Error: " + errorCode);

setdesc (Layout Only)
The setdesc() command sets the current script’s description in a Layout plug-in panel. It accepts either a single string

prototype:      void setdesc(...text...)

text               string; a comma-separated list of strings.

example:

textValue = "Text3 ";
setdesc("Text1 ", "Text2 ", textValue);

Progress Monitor (Modeler Only)

moninit
The moninit() command is the entry point to the monitor control commands. moninit() initializes a monitor window for your script. LScript must call this command before it can use other monitor.

The monitor system is basically a progress indicator. A progress indicator shows the user that the script is processing information, and that the computer has not locked-up for some reason. You initialize the monitor by telling it how many steps you need to take to finish your work, and the monitor system uses this value to display the progress bar. The progress bar shows the user how much more time is left until a process is done. You can also display a message in the monitor dialog box.

The user can click a Cancel button in the dialog box at anytime; the Cancel action is handled by the monstep() function (discussed next).

prototype:       void moninit(steps [,message])

steps             integer; number of steps until completion

message        string; message to be displayed.

example:

moninit(100, "Processing…");

monstep
monstep() uses a specific distance to advance the progress bar that was created by moninit(). If you provide no value, the advance count defaults to 1. You can advance the progress indicator by larger values simply by specifying them.

monstep() will return a Boolean value. Most of the time, this value will be false. However, if the user clicks the Cancel button on the monitor window, monstep() will return true. When this happens, your script should exit as gracefully as possible.

prototype:           Boolean monstep([step])

step                   integer; optional advance amount.

example:

editbegin();

if(monstep())
{
   lyrsetfg(fg);
   lyrsetbg(bg);
   editend(ABORT);
   return;
}

monend
The monend() command completes the monitor system; it closes the progress window if one is open, and frees up the monitor system for other parts of Modeler (only one monitor window can be active at a time).

prototype: void monend(void)

Requester

reqbegin
reqbegin() initiates a "requester," an input dialog box that gathers information and options from the user. It can also impart information and messages (as static text).

Invoking reqbegin() will place you in requester mode. This mode must be active to use other requester-related functions and it must be terminated by a call to reqend(). You may terminate your script at any time during requester mode, and LScript will automatically issue a reqend() if you forget to do so.

reqbegin() takes a single argument, which is the title for your requester dialog.

prototype:             void reqbegin(title)

title                      string; dialog box title

example:

reqbegin("My Requester");

reqend
reqend() terminates the requester mode. Use reqend() to terminate a requester dialog after processing user input.

prototype: void reqend(void)

reqopen
The reqopen() function can be used in place of reqpost() to open the Requester panel in non-modal mode. In this mode, the panel remains open and interactive to the user even after the options() UDF has terminated. In order to process changes to panel controls in non-modal mode, controls must have an active refresh callback applied. As controls are modified, these refresh callbacks are invoked by LScript, and the script's process() UDF is subsequently invoked by Layout to refresh the object's onscreen attributes.This function will now accept up to two new arguments to enable idle-time processing.  The first argument is the name of the UDF to be invoked.  The UDF takes no arguments, and is enabled to allow for drawing on the Requester panel.  The second optional argument is the timeout interval (in milliseconds) to be used between calls to the idle-time UDF.  If ommitted, the default timeout value is 500 milliseconds (one-half of a second).

prototype:      reqopen([udf[,interval]]);

example:

reqbegin();

reqopen();

Or:

reqopen("myudf",200);

reqisopen
reqisopen() is used to determine whether or not a Requester panel opened non-modally is currently open. A Boolean true is returned if the panel is currently open.

prototype:        Boolean reqisopen(void)

example:

if(reqisopen())
reqend();
else
{
   reqbegin("requester name");

reqpost
The reqpost command tells the requester system that you finished constructing your requester dialog, having populated it with your required fields, and that you want to display the dialog.

reqpost() returns a Boolean value (true or false) indicating whether or not the user wants to process with the provided values. A value of true indicates that the user chose OK, and processing should begin. A false return indicates that you should gracefully terminate your script because the user chose to Cancel.

The reqpost() and reqopen() functions accept up to two arguments to enable idle-time processing. The first argument is the name of the UDF to be invoked. The UDF takes no arguments, and is enabled to allow for drawing on the Requester panel. The second optional argument is the timeout interval (in milliseconds) to be used between calls to the idle-time UDF. If ommitted, the default timeout value is 500 milliseconds (one-half of a second). Certain conditions may prevent the system from invoking the UDF at exact interval times. Thus, the timeout value specified should be considered only an approximation--in other words, you should not make the assumption that only that amount of time has elapsed when your idle-time UDF is invoked.

prototype:           boolean reqpost(udf [,milliseconds])

udf                     udf; a User Defined Function to be involked.

milliseconds        integer, timeout interval.

example:

generic
{
   reqbegin("Testing Idle");
        c1 = ctlnumber("Number",1.0);
        reqpost("idleTest"); // called at 500-millisecond
                                    // intervals.
reqend();
}
color = <0,255 * .5,255 * .75>;
idleTest
{
   drawline(color,0,2,100,2);
   color.x += 5;
   color.y += 5;
   color.z += 5;
   if(color.x > 255) color.x = 0;
   if(color.y > 255) color.y = 0;
   if(color.z > 255) color.z = 0;
}

reqabort
The reqabort() function is called from within a control or requester callback function, and it immediately terminates the posted requester. No user intervention is required.

When reqabort() is called without arguments, a "Cancel" result is returned to the reqpost() function. This simulates a user clicking the Cancel button. If reqabort() receives a true value, then it passes an "OK" result to reqpost().

prototype:      void reqpost(state)

state             state; boolean, true/false.

example:

generic
{
   reqbegin("Reqabort() Test");
        reqsize(200,180);
        c1 = ctlstate("Goodbye",0,50,"goodbye");
        ctlposition(c1,35,10);
        if(reqpost())
             info("You pressed OK");
        else
             info("You pressed Cancel");
        reqend();
}

goodbye: val
{
        reqabort(true);
}

requpdate
The requpdate() function refreshes listboxes and information controls on the requester panel with new values when you use it within control callback functions. You cannot invoke requpdate() from within a listbox count or value callback function. If you try this, it will have no effect.

prototype:      requpdate([controlID])

controlID        Control Object Agent; control to be updated

example:

count;
lb_items;

generic
{
   for(count = 1;count <= 5;count++)
        lb_items += "Item_" + count;
   reqbegin("Testing requpdate()");
   c1 = ctllistbox_ ("Items", 300, 300, "lb_count",
"lb_value");
   c2 = ctlbutton("Increment",200,"inc_button");
   reqpost();
}
lb_count
{
   return(lb_items.count());
}
lb_value: index
{
   return(lb_items[index]);
}
inc_button
{
   x = count;
   y = 1;
   count += 5;
   while(x <= count)
   {
        lb_items[y] = "Item_" + x;
        ++x;
        ++y;
   }
   requpdate();
}     

reqsize
Use the reqsize() function to manually set the width and height of the requester panel.

prototype:         void reqsize(width,height)

width               integer; width of the panel.

height              integer; height of the panel.

example:

reqsize(100,100);

reqposition
A Requester panel's position can now be set and queried using the new reqposition() command. The command takes two optional arguments that specify the screen X and Y position for the panel. These values can be set at anytime between reqbegin() and reqend(). If the panel is open on the screen when the call is made, the panel's position is immediately altered.

Whether called with or without arguments, reqposition() will return the current position of the panel at the time the call is made. This makes it possible for a script to perform its own between-runs management of the panel's position on the screen (LScript does this automatically since v2.5, but there are only a limited number of panels it will remember).

  generic
  {
      reqbegin("Position Test");
      ...
      req_x = recall("req_x",0);
      req_y = recall("req_y",0);
      reqposition(req_x,req_y);
      ...
      return if !reqpost();
      ...
      (x,y) = reqposition();
      store("req_x",x);
      store("req_y",y);

      reqend();
      ...
  }

Because reqposition() will immediately update an open panel, on-screen positioning can be performed in real time:

   req_x,req_y;

  generic
  {
      reqbegin("Position Test");
      ...
      return if !reqpost("idle",500);
      ...
      reqend();
      ...
  }

  idle
  {
      ++req_x;
      ++req_y;
      reqposition(req_x,req_y);
  }

reqresize
The reqresize() function lets the user interactively resize requester panels. You define an internal resize callback within the script by using reqresize(). This function takes up to five arguments; the first, a required string value, should identify a UDF within the script.

The defined callback UDF should accept two integer arguments, indicating the new width and height of the Requester panel, and should return nothing. Two optional pairs of numbers can also be provided to indicate the minimum width and height, and maximum width and height, for the panel. If these numbers are omitted, the minimum width and height becomes that of the initial window, and the maximum width and height is limited only by the screen resolution.

The following Generic script illustrates the resize mechanism by locking a control to a specific location on the panel, regardless of its size. Resizing of Requester panels is enabled only when the reqresize() function successfully identifies a callback UDF. If reqresize() is not used, then the panel is locked to its initial size.

prototype:           void reqresize(resize_udf,

                         [minWidth,minHeight],[maxWidth,

                         maxHeight])

resize_udf          string; the udf that gets called when the panel is resized.

minWidth           integer; the minimum width of the panel.

minHeight          integer; the minimum height of the panel.

example:

c1;
generic
{
   reqbegin("Resize Me!");
        c1 = ctlnumber("Number",1.0);
        reqresize("resize",,,640,480);
        // maximum becomes 640x480
        reqpost();
   reqend();
}

resize: w,h
{
   c1.position(w - c1.w - 5,h - c1.h - 35);
}

reqredraw
The reqredraw() function establishes a callback UDF within the script that is activated whenever the panel itself is refreshed..

prototype:      void reqredraw(UDF)

UDF             string; callback function.

example:

reqredraw("callback")

reqkeyboard
A new callback named reqkeyboard() can be defined to intercept keyboard activity on the active Requester panel. This function takes a single argument which represents the raw key pressed. It should return a Boolean false or true value indicating that the key should or should not be further processed by the system, respectively.

@version 2.6
@warnings
@script generic

generic
{
    reqbegin("Testing reqkeyboard()");

    c1 = ctlstring("String","value");

    if(reqpost())
         info("You pressed Ok");
    else
         info("You pressed Cancel");

    reqend();
}

reqkeyboard: key
{
    if(key == 13) // enter
    {
         reqabort(true);
         return(true);
    }
    else if(key == 27) // escape
    {
         reqabort();
         return(true);
    }

    return(false);
}

The following pre-defined constants have been added to the environment in order to help process key events:
REQKB_F1         REQKB_KB0         REQKB_KP0
REQKB_F2         REQKB_KB1         REQKB_KP1
REQKB_F3         REQKB_KB2         REQKB_KP2
REQKB_F4         REQKB_KB3         REQKB_KP3
REQKB_F5         REQKB_KB4         REQKB_KP4
REQKB_F6         REQKB_KB5         REQKB_KP5
REQKB_F7         REQKB_KB6         REQKB_KP6
REQKB_F8         REQKB_KB7         REQKB_KP7
REQKB_F9         REQKB_KB8         REQKB_KP8
REQKB_F10       REQKB_KB9         REQKB_KP9
REQKB_F11
REQKB_F12       REQKB_ALT          REQKB_RETURN
                          REQKB_SHIFT      REQKB_INSERT
REQKB_LEFT     REQKB_CTRL       REQKB_HOME
REQKB_RIGHT                                REQKB_END
REQKB_UP         REQKB_DELETE  REQKB_PAGEUP
REQKB_DOWN   REQKB_HELP      REQKB_PAGEDOWN

getvalue
getvalue() retrieves the value in an input field. You must provide getvalue() with the control handle that is returned by one of the control creation functions. The type of return value depends on the type of control. It is customary to assign the return value of getvalue() to the original variable used to initialize the input control.

prototype:            result getvalue(handle)

result:                   varies; data value contained in field

handle:                 integer; control handle

example:

reqbegin("Testing List Box");
    c1 = ctllistbox("Items", 300, 300, "lb_count", "lb_name",
"lb_event");
   c2 = ctlbutton("Select",50,"button_event");
   return if !reqpost();
   sel = getvalue(c1);
reqend();

setvalue
setvalue() lets you modify the value of an existing requester control, and until you call reqend(), you can post a constructed requester dialog to the user for input as many times as necessary. setvalue() accepts a handle to the control to be changed, and a variable or constant value for the new value. Please see the lightswa.ls script, on your LightWave distribution, for an example of this practice.

prototype:       void setvalue(handle, value)

handle:          integer; control handle

value:            data type; new value for input field

example:

setvalue(c1,a);

The setvalue() function now first attempts to match a list value for ctlpopup() controls if a string value is provided.

Drawing Functions

Several Requester functions have been added to support user-drawing features in the panel. The drawing functions can be called only from within the script’s redraw callback.

drawpixel
The drawpixel() function draws a pixel on the panel at the specified point using the specified color.

prototype:         void drawpixel(<color>,xPos,yPos)

<color>            vector; color of the pixel to be drawn.

xPos               integer; X coordinate of the pixel.

yPos               integer; Y coordinate of the pixel.

example:

drawpixel(<200,200,200>, 10, 10);

drawline
The drawline() function draws a line on the panel between the specified points using the specified color.

prototype:           void drawline(<color>, x1, y1, x2, y2)

<color>              vector; the color of the line to be drawn.

x1                      integer; x coordinate of the starting point.

y1                      integer; y coordinate of the starting point.

x2                      integer; x coordinate of the ending position.

y2                      integer; y coordinate of the ending position.

example:

drawline(<200,200,200>, 10, 10, 50, 50);

drawbox
The drawbox() function draws a box filled with the specified color and the specified width and height. The box is positioned at the specified point.

prototype:              void drawbox(<color>, xPos, yPos, width, height)

xPos                     integer; X coordinate of the box’s starting corner.

yPos                     integer; Y coordinate of the box’s starting coordinate.

width                     integer; width of the box.

height                    integer, height of the box.

example:

drawbox(<200,200,200>, 10, 10, 50, 50);

drawborder
The drawborder() function draws an unfilled, 3D box outline at the specified point using the specified width and height. If height is 0, then a horizontal divider line is drawn. The drawborder() Requester redraw function accepts a fifth optional Boolean argument that indicates the indentation of the border to be drawn. If omitted (or false), then the border is draw with a "raised" look. If true, then the border has a "sunken" look.

prototype:                       void drawborder(xPos, yPos, width, height, bool)

xPos                              integer; X coordinate of the starting point.

yPos                              integer; Y coordinate of the starting point.

width                              integer; width of the border.

height                             integer; height of the border.

bool                                Boolean; controls the 3D look of the box.

example:

drawborder(5, 5, 100, 100, true);

drawtext
The drawtext() function draws the provided text using the specified color at the specified point.

prototype:                    void drawtext(text, <color>, xPos, yPos)

text                             string; The text to be drawn.

<color>                       vector; The color of the text to be drawn.

xPos                          integer; x coordinate to place text.

yPos                          integer; y coordinate to place text.

example:

drawtext("I’m drawing text", <200,200,200>, 10, 10);

drawtextwidth 

drawtextheight

drawtextwidth() and drawtextheight(), have been added to determine the display width and height, in pixels, of a text string.  They each take a single character string, and return an integer value representing this pixel width or height.

drawerase
The drawerase() function takes the X and Y position, and the width and height, of the area to be erased on the Requester panel.

prototype:                 void drawerase(xPos, yPos, width, height)

xPos:                       integer, x Position of the starting corner.

yPos:                       integer,y Position of the starting corner.

width:                       integer, width of the area to be erased.

height:         integer, height of the area to be erased.

example:

drawerase(10,10,50,25);

drawcircle(<color>,xcentre,ycentre,radius)

drawfillcircle(<bordercolour>,<fill color>,xcentre,ycentre,radius)

drawellipse(<colour>,xcentre,ycentre,xradius,yradius)

drawfillellipse(<bordercolour>,<fill color>,xcentre,ycentre,xradius,yradius)

Mouse Object Agent

The Mouse functions now take a single Object Agent argument that wraps all available parameters into a single package.  This Object Agent exports the following data members:

       ctl         the Control Object Agent involved in the event ('nil' if none)
        x           X position of the event
        y           Y position of the event
        button      which mouse button triggered the event; 1=LMB, 2=MMB, 3=RMB
        count       the click count; 1=single-click, 2=double-click
        keys[3]     indicates key active modifiers; [1]=CTRL, [2]=SHIFT, [3]=ALT

  The Object Agent currently exports no public methods.

        ...
        reqmousemove: md
        {
            if(md.ctl)
            {
                vp_x = md.x - md.ctl.x + md.ctl.xoffset;
                ...

reqmousemove when the mouse moves around.
reqmousedown when a button is pressed.
reqmouseup when a button is released.
reqmousetrack when the mouse moves with holding a button.

all of them generate the same object agent, with all these features. But the MOVE function will not be activated, when someone clicks with a still mouse. Makes it kind of icky to use, since most people stop before clicking somewhere... Thats why its important to put clicking actions in the DOWN functions.

Vice versa, you can get a pretty good value out of md.button when it appears in the MOVE function, because that means someone is dragging while holding a button.

TRACK is kind of weird, since it is essentially the same as MOVE. One difference I found, though, is that MOVE is called while someone drags a minislider, but TRACK isn't. Weird.
I could use it to my advantage to find out if someone has just released a minislider, to switch back from a preview mode to applying the actual effect of that minislider.

Dunno if it helps, but here are some code snippets from my dragn drop:

Code:


reqmousetrack: md // catch if the minislider is just released
{
if(c13.value != editGam)
{
quick = false;
setvalue(c13,editGam);
}
}

reqmousemove: md //_______ TRACK in window
{
if(md.y >= 90 && md.y <= 390 && md.x >= 20 && md.x <= 620 && xxx != 0)
{
if(md.button == 1) // LMB
{
getPickerInfo(md);
}
else if(md.button == 3 && rmbClick_x != nil) // RMB
{
t = Langle[xxx] + (md.x - rmbClick_x)/100;
Langle[xxx] = max(min(t,1.5),0.001);
rmbClick_x = md.x;

normalizeLights();
helpmessage = "Coverage Radius = " + Langle[xxx] + " , Light Intensity = " + round(Lint[xxx]*normalFactor,4) + "%";


requpdate(c1,c2);
setvalue(c2,lb_name(xxx));
}
}
else if(md.button == 1 && md.y >= 391 && md.y <= 421 && md.x >= 20 && md.x <= 620 && xxx != 0) // rollover toolbar
{
curs = false;
Lx[xxx] = md.x - 20;
Ly[xxx] = md.y - 90;
if(md.y >= 394 && md.y <= 415 && md.x >= 550 && md.x <= 566) // trashcan
{
clearLight();
}
requpdate(c1);
}
}
}

reqmousedown: md //_______ CLICK
{
if(about)
{
about = false;
requpdate();
}
else
{
if(md.y <= 45) // click in title
{
about = !about;
requpdate(c1);
}
if(md.y >= 90 && md.y <= 390 && md.x >= 20 && md.x <= 620 && imgPICK)
{
if(LightNum > 0) // ______ select a Light
{
dx1 = md.x - 24;
dx2 = md.x - 16;
dy1 = md.y - 94;
dy2 = md.y - 86;

for(i = 1; i <= LightNum; i++)
{
// found = false;
if(Lx[i] >= dx1 && Lx[i] <= dx2 && Ly[i] >= dy1 && Ly[i] <= dy2)
{
xxx = i;
setvalue(c2,lb_name(xxx));
requpdate(c2);
f = true;
}
}
}
if(!f) // nothing selected, make new one
{
LightNum = LightNum + 1;
xxx = LightNum;
Lx[xxx] = md.x - 20;
Ly[xxx] = md.y - 90;
Lphi[xxx] = 1; Ltheta[xxx] = 1; Langle[xxx] = 0.2;
Lint[xxx] = 1; Lcol[xxx] = <0,0,0>; Llumi[xxx] = 0.2;
f = false;
}
if(md.button == 3) // RMB Click
{
rmbClick_x = md.x;
rmbClick_y = md.y;
}

getPickerInfo(md);
}
if(md.button == 1 && md.y >= 391 && md.y <= 421 && md.x >= 550 && md.x <= 566 && md.count == 2)
{
// double click on trashcan
clearAllLights(true);
}
}
}

Layout Commands

About();
AboutOpenGL();
AddButton("<command>","<group>");
AddPlugins("<filename>");
AlertLevel("<level>");
AutoConfirm("<on/off>");
CommandHistory();
CommandInput("<command>");
Compositing();
DepthBufferAA("<type>");
DisplayOptions();
EditKeys();
EditMenus();
EditPlugins();
FogColor("<red>","<green>","<blue>");
FogMaxAmount("<amount>");
FogMaxDistance("<distance>");
FogMinAmount("<amount>");
FogMinDistance("<distance>");
FogType("<type>");
GeneralOptions();
Generics();
GradientBackdrop();
GraphEditor();
GroundColor("<red>","<green>","<blue>");
HideToolbar();
HideWindows();
ImageEditor();
ImageProcessing();
Item_SetWindowPos("<X>","<Y>");
ItemProperties();
LastPluginInterface();
Layout_SetWindowPos("<X>","<Y>");
Layout_SetWindowSize("<width>","<height>");
LimitDynamicRange();
MasterPlugins();
Model();
MotionOptions();
NadirColor("<red>","<green>","<blue>");
Numeric();
Presets();
RecentContentDirs();
RecentScenes();
RenderOptions();
Scene_SetWindowPos("<X>","<Y>");
Scene_SetWindowSize("<width>","<height>");
SceneEditor();
SkyColor("<red>","<green>","<blue>");
Statistics();
SurfaceEditor();
UnseenByAlphaChannel();
VIPER();
ZenithColor("<red>","<green>","<blue>");