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>");
|