Globals: XPanels

LightWave

Variant Parameters Animation Envelopes Globals Table of Contents

XPanels

Availability  LightWave 6.0
Component  Layout, Modeler
Header  lwxpanel.h

This global is a new addition to LightWave's system of platform-independent user interface components. To understand its place in that system and how it differs from Panels, it may help to know something about the history of user interfaces in LightWave.

XPanels is the third generation of LightWave interface APIs. The first was the requester API, which in its original Modeler incarnation predates the plug-in architecture itself. Modeler requesters were always modal. You gave Modeler a list of controls and their initial values, Modeler formatted and displayed the dialog, and after the user closed the dialog, you read out the control values. The original requester API is now just another way of creating an xpanel, and you can use it in Layout as well as Modeler.

Panels is the second generation, and it's pretty bohemian, like Algol was to Fortran. It introduced callbacks so that you can respond to the user interactively, and it comes with a list of 50 or so predefined control types and some drawing functions. You can set the size of a panel and the positions of its controls, and you can decorate your panels and tell them to send you a steady stream of mouse and keyboard events. As with requesters, controls are defined using a sequence of function calls.

XPanels is a return to the Modeler requester philosophy of automation. You give up some control over the appearance and behavior of your controls, but in exchange, things that can require a lot of code with panels, like adding an E (envelope) button to a numeric edit field, along with all of the functionality that implies, are very easy to do with xpanels. And xpanels can be embedded in LightWave's own windows. Unlike the previous interface models, the controls on an xpanel are defined primarily through arrays of static data.

Panels continues to support some control types, such as the OpenGL control, that have no xpanel equivalents, so it's still your best option in some cases. But you aren't forced to choose, since Panels also allows you to create xpanel controls--xpanels embedded within your panel.

Global Call

   LWXPanelFuncs *xpanf;
   xpanf = global( LWXPANELFUNCS_GLOBAL, GFUSE_TRANSIENT );

The global function returns a pointer to an LWXPanelFuncs.

   typedef struct st_LWXPanelFuncs {
      int             version;
      LWXPDrawFuncs  *drawf;
      LWXPanelID     (*create)     (int type, LWXPanelControl *);
      void           (*destroy)    (LWXPanelID);
      void           (*describe)   (LWXPanelID, LWXPanelDataDesc *,
                                      LWXPanelGetFunc *,
                                      LWXPanelSetFunc *);
      void           (*hint)       (LWXPanelID, unsigned long,
                                      LWXPanelHint *);
      void *         (*getData)    (LWXPanelID, unsigned long);
      void           (*setData)    (LWXPanelID, unsigned long, void *);
      void *         (*formGet)    (LWXPanelID, unsigned long);
      void           (*formSet)    (LWXPanelID, unsigned long, void *);
      void           (*viewInst)   (LWXPanelID, void *);
      void           (*viewRefresh)(LWXPanelID);
      int            (*post)       (LWXPanelID);
      int            (*open)       (LWXPanelID);
   } LWXPanelFuncs;

A panel is a window or a dialog box containing buttons, edit fields, dropdown lists, image rectangles, and other user interface elements collectively called controls. You create panels to allow users to enter and change settings that affect the operation of your plug-in.

The XPanels system distinguishes between two kinds of panels, called forms and views. They differ primarily in the method used to move data values into and out of controls.

A view panel presents a "view" of a data instance, which is a pointer to some data owned by your plug-in, typically a handler's instance data. You pass this pointer to XPanels in the viewInst function. The callbacks you pass to the describe function will be called by XPanels to update this data.

A form panel isn't passed a data instance pointer, so you have greater freedom in choosing how to represent your data within your plug-in. XPanels interacts with your data through the formGet and formSet functions and your change notification callback.

Because they don't store a data instance pointer, forms have no way to distinguish between multiple instances of the same dataset, making it more difficult to use the same panel with different data. The significance of this may grow as XPanels evolves. In the future, for example, users may be able to multiselect every instance of your plug-in and edit the parameters for all of them simultaneously.

version
The version number of the interface. Certain control types or hints may not be available in older interfaces.

drawf
Drawing functions, which are explained in detail below. Custom drawing on xpanels is limited to contexts in which an LWXPDrArea region is defined.

panel = create( type, controls )
Create a new panel. The type can be LWXP_VIEW or LWXP_FORM. The controls argument is an array of LWXPanelControl structures describing the controls on the panel. It must have at least panel lifetime, meaning that the controls variable must be valid as long as the panel exists. The easiest way to ensure this is to declare the array static. See below for more about the controls list.

destroy( panel )
Free the panel and related resources allocated by create.

describe( panel, datadesc, getfunc, setfunc )
Define the data values for a panel. The datadesc argument is a list of value IDs and their types. Like the controls list passed to create, datadesc must have at least panel lifetime. For view panels, the values are updated interactively using your getfunc and setfunc callbacks. If the panel is a form, the getfunc and setfunc arguments are ignored and should be NULL.

hint( panel, id, hints )
Apply a hint array to the panel or one of its controls. This may be called multiple times, but only while the panel is closed. The hint array is applied to the panel if the ID is 0. Otherwise it's applied to the control with the corresponding ID.

data = getData( panel, id )
Returns the user data for the panel (id == 0) or for one of its controls, set by a previous call to setData.

setData( panel, id, data )
Set the user data for a panel (id == 0) or one of its controls. The data pointer is passed to several of the callbacks. It's also what getData returns.

value = formGet( panel, vid )
Read the value of a control on a form panel. Returns NULL if the value is undefined.

formSet( panel, vid, value )
Write a value to a control on a form panel.

viewInst( panel, instance )
Set the instance data pointer for a view panel. This is what is passed to the get and set callbacks you designate when you call the describe function.

viewRefresh( panel )
Refreshes a view panel by reloading control values from the instance data. Use this when the instance data has been modified by something other than the user's interaction with your interface. When called from a form, viewRefresh redraws the controls.

result = post( panel )
Display the panel for modal interaction. Modal means that the user must close the panel before continuing to work in LightWave. This function won't return until the panel has been closed. It returns 1 if the user dismisses the panel with the "OK" button and 0 if the user presses "Cancel" (or if the panel couldn't be displayed). See the description of the XpDLOGTYPE macro for more information about the buttons, like "OK" and "Cancel," that are automatically added to modal panels.

result = open( panel )
Display the panel for non-modal interaction. This function returns immediately and the panel stays open until the user closes it. Returns 1 if the panel was opened successfully, otherwise it returns 0. Handlers generally won't need to call open (or post), since LightWave takes care of opening the panel you return in the panel field of the LWInterface structure.

Describing Controls and Data

Each of the controls on a panel is described by an LWXPanelControl structure. An array of these is passed as the second argument to the create function when the panel is created.

   typedef struct st_LWXPanelControl {
      unsigned long   cid;
      const char     *label;
      const char     *ctrlclass;
   } LWXPanelControl;

The second argument to the describe function is an array of LWXPanelDataDesc.

   typedef struct st_LWXPanelDataDesc {
      unsigned long   vid;
      const char     *name;
      const char     *datatype;
   } LWXPanelDataDesc;

The first member of both structures is an identifier. It can be any positive integer greater than or equal to 0x8000. Values less than 0x8000 are reserved for use by XPanels. The second member is a human-readable description. For controls, this string is used as a label that appears next to the control on the panel. The third member identifies the class of the control or the data type of the value.

In most cases, your control array and data description array will be parallel, and the value IDs in the data description will match the control IDs in the control array. But some control types don't have an associated value, and you might declare some values to XPanels that aren't directly associated with any control.

Control Types

The following definitions list the control class (the string that goes in the ctrlclass field of the LWXPanelControl), the data type of the control's value (the string that goes in the datatype field of the LWXPanelDataDesc), and the C equivalent (the kind of variable your plug-in stores the value in). The definitions will often refer to hints and callbacks, both of which are described in later sections.

"string" : "string" : char[]
A text edit field.

"integer" : "integer" : int
An integer edit field.

"float" : "float" : double
An edit field for floating-point numbers. Variations on the floating-point control type are summarized in the following table. Controls that include envelope (E) and texture (T) buttons use variant parameters as their underlying data type.

"float"

"float"

double
"float3" "float3" double[3]
"float-env" "float-env" double[] (vparm)
"float3-env" "float3-env" double[][3] (vparm)
"distance" "distance" double
"distance3" "distance3" double[3]
"distance-env" "distance-env" double[] (vparm)
"distance3-env" "distance3-env" double[][3] (vparm)
"percent" "percent" double
"percent3" "percent3" double[3]
"percent-env" "percent-env" double[] (vparm)
"percent3-env" "percent3-env" double[][3] (vparm)
"angle" "angle" double
"angle3" "angle3" double[3]
"angle-env" "angle-env" double[] (vparm)
"angle3-env" "angle3-env" double[][3] (vparm)
"color" "color" double[3]
"color-env" "color-env" double[][3] (vparm)
"time" "time" double

Distance controls display units; their internal values are in meters. Percent controls display percentages; their internal values are the percent values divided by 100 (100% is 1.0). Angle controls display angles in degrees and store them in radians. Times are stored as elapsed seconds, but are displayed in the units selected by the user elsewhere in LightWave's interface.

"vButton"
A button. XPanels calls the control's button click callback whenever the user presses the button.

"iBoolean" : "integer" : int
A checkbox.

"iSlider" : "integer" : int
"iSliderText" : "integer" : int
A slider (a thumb button that can be dragged within a horizontal track). Use the XpMIN and XpMAX hints to define the range of the slider. The Text version includes an integer edit field.

"iChoice" : "integer" : int
An array of radio buttons (mutually exclusive boolean buttons). The value is a 0-based index into the list of choices. To initialize the choices, use the XpSTRLIST hint.

"axis" : "axis" : 0, 1, 2
Radio buttons for selecting X, Y or Z.

"iPopChoice" : "integer" : int
A scrolling popup menu. The value is a 0-based index. You can initialize a popup with the XpSTRLIST hint and a static array of strings, or the XpPOPFUNCS hint and popup item count and name callbacks.

"vPopCmd"
A popup menu that works like a multiple-choice button. Your popup command callback receives a 0-based index.

"sPresetText" : "string" : char[]
Combines a string edit field and a popup menu. The user can type into the edit field or fill the field with the value associated with one of the presets named in the menu.

"sFileName" : "string" : char[]
Combines a string edit field and a button that opens the file dialog. Use the XpXREQCFG macro to set the mode (load or save), the title string and the file type filter.

"iChoTransform" : "integer" : int
"iPopTransform" : "integer" : int
Like iChoice and iPopChoice controls, but the value isn't the menu index. It is instead the value of an array element referenced by the index. The array contains values that are more useful to your plug-in than the 0, 1, 2... indexes into the menu. For the i-th menu item, the value is map[i], where map[] is an integer array associated with the control using the XpCHOXFORM or XpPOPXFORM hints.

"dThumbnail"
A rectangular area that you can draw on using the drawing functions. Thumbnails generate mouse events. The user can click, double-click, or drag out a rectangular selection.

"sInfo" : "string" : char[]
A read-only text field.

Hints

The hint function accepts as one of its arguments an array of panel-building commands, called hints. These are packaged as macros defined in the lwxpanel.h header file. The macros are used as initializers for the hint array passed to hint. For example,

   static LWXPanelHint hints[] = {
      XpLABEL( 0, "My Panel Title" ),
      XpSTRLIST( MY_POP, choices_array ),
      ...

There are currently over 50 hint macros.

XpH( x )
Cast the value to an LWXPanelHint. This is just a way to get values of different types into a single array.

XpEND
Terminate the hint array. Some macros are also followed by a sublist of hints which is terminated by XpEND.

XpCALL( hint_array )
Insert another hint array into this one.

XpLABEL
( id, label )
Set the label string for a control or group. An ID of 0 sets the label for the panel.

XpVECLABEL( ctlID, labels )
Set the labels for each of the three elements of a vector control (integer3, float3, etc.). labels is an array of three strings.

XpSTRLIST( ctlID, strlist )
Set the string array for a popup control.

XpCLASS( id, class )
Change the class of a control. Hints previously applied to this control may be lost if they're incompatible with the new class.

XpADD( ctlID, class, valID )
Create a control. You can also create controls using the LWXPanelControl array passed to the create function and the LWXPanelDataDesc array passed to describe.

XpDELETE( id )
Remove a control from the panel. This doesn't remove the control's value from the data description.

XpCTRLCFG( ctlID, options )
Set class-specific option flags for a control. Currently this is only used by dThumbnail controls, which can be configured using the following bit flags combined using bitwise-or.
THUM_SML    THUM_SQ      THUM_LAND    THUM_EURO
THUM_MED    THUM_NTSC    THUM_FULL
THUM_LRG    THUM_35MM    THUM_WIDE
THUM_XLG    THUM_PORT    THUM_ANAW
XpXREQCFG( ctlID, mode, title, filter )
Set options for the file dialog opened by an sFileName control. The mode is one of the following.
LWXPREQ_LOAD
LWXPREQ_SAVE
LWXPREQ_DIR

The title is the string that will appear in the title bar of the dialog. The filter is a string that identifies the file type. It's the same string you'd pass to the File Type global.

XpFOCUS( id )
Identify the control that should receive focus when the panel is first displayed. An ID of 0 indicates the panel should use a default setting, usually the first editable text field.

XpVALUE( ctlID, valID )
Associate a control ID with a value ID. Ordinarily, a control and its value are implicitly bound together by having the same ID in the LWXPanelControl and LWXPanelDataDesc arrays passed to create and describe, but a control and value pair aren't required to share the same ID.

XpRESTORE( id )
XpRESTORE_()
XpRESTORE_ON
XpRESTORE_OFF
Define what happens to control values when the user presses the Cancel button in a modal LWXP_VIEW panel. By default, values are reset to what they were when the panel was opened. The ON and OFF macros set this behavior for all values, and the other two toggle the behavior for a single value or for a list of values.

XpLINK_( valID )
XpLINK( valID, link )
Link a value to another value, or to a list of values. Links create a dependency relationship. If the link value changes, then the dependent valID value is also updated.

XpENABLE_( valID )
XpENABLE_MAP_( valID, map )
XpENABLEMSG_( valID, msg )
XpENABLEMSG_MAP_( valID, map, msg )
Link the enable state of the controls in the trailing ID list to the valID value. The trailing ID list actually contains value IDs, and the control IDs are inferred from this. If the valID value is true (non-zero), the dependent controls are enabled, otherwise they're disabled. If you supply a map (an integer array containing boolean values), the enable state will be based on map[value] rather than on the value directly. If you supply a message string, it will be displayed whenever the user tries to manipulate a disabled control. The message typically explains why the control is disabled: "Sprinkles is only valid when the flavor is vanilla."

XpINTXFORM( ctlID, count, ilist )
XpPOPXFORM( ctlID, count, ilist )
XpCHOXFORM( ctlID, count, ilist )
Set the transform map for the control. Transform control classes such as iPopTrans and iChoTrans provide a mechanism for mapping the control's underlying integer value into a more useful value for the client. ilist is an array of 32-bit values that XPanels will substitute for the base value of the control. When the base value is 0, XPanels uses ilist[0], and so on.

XpMIN( ctlID, min )
Set the minimum of a control's range. min is always an integer, as are the other range parameters in the following hints.

XpMAX( ctlID, max )
Set the maximum of a control's range.

XpSTEP( ctlID, step )
Set the increment of a range adjustment.

XpRANGE( ctlID, min, max, step )
Set all three range parameters.

XpHARDMINMAX( ctlID, bmin, bmax )
Enforce the range limits in the edit field component of a slider control. bmin and bmax are booleans that set or clear this for each end of the range. If the control is enveloped, the envelope values may still fall outside the limits.

XpCLRMINMAX( ctlID, bmin, bmax )
Remove a minimum or maximum set by XpMIN, XpMAX or XpRANGE.

XpSENS( ctlID, delta )
Set the sensitivity of a minislider. The delta scales the pixel to minislider translation. Larger deltas cause the minislider value to change more slowly.

XpTRACK
( ctlID, track )
Indicate whether the control should generate intermediate (tracking) events. If the boolean track flag is true (non-zero), events will be generated for the control as long as the user manipulates it on the interface. In particular, components such as sliders and text fields will generate a constant stream of events to inform the client of user actions. If this is false, events are only generated after the user has set a new value.

XpIMMUPD_( ctlID )
XpIMMUPD( ctlID, dep )
Create an "immediate update" dependency relationship for a control, such as a slider, that can generate LWXPEVENT_TRACK events. Whenever the control is being modified by the user (and is generating tracking events), the dependent controls will be updated.

XpDESTROYNOTIFY( func )
Set the callback that XPanels will call after the panel has been destroyed. The argument points to an LWXPanelDestroyNotifyFunc.

XpCHGNOTIFY
( func )
Set the callback that XPanels will call whenever a value is modified. The argument points to an LWXPanelChangeNotifyFunc.

XpBUTNOTIFY( ctlID, func )
Set the callback that XPanels will call when the button control is pressed. The argument points to an LWXPanelBtnClickFunc.

XpPOPCMDFUNC( ctlID, func )
Set the callback that XPanels will call when an item is selected in a popup control. The argument points to an LWXPanelPopCmdFunc.

XpPOPFUNCS( ctlID, countfunc, namefunc )
Set the callbacks that XPanels will call when the popup choice control is opened. The arguments point to an LWXPanelPopCntFunc and an LWXPanelPopNameFunc. The callbacks are an alternative to providing a static array of strings for the popup.

XpDRAWCBFUNC( ctlID, func )
Set the callback that XPanels will call when a drawable control needs to be drawn. The argument points to an LWXPanelControlDrawFunc. Currently this is restricted to use with dThumbnail controls.

XpZOOMCBFUNC( ctlID, func, rect )
Set the callback that XPanels will call when the user clicks and drags the mouse within the control. The function argument points to an LWXPanelControlZoomFunc. rect is a boolean that determines whether mouse dragging is reported. Currently this is only for dThumbnail controls.

XpALIAS_
( aliasID )
Create a new alias group, or add controls, values or other aliases to an existing alias group. An alias group is just an ID with its own list of IDs. The groups created using the ALIAS tag define a logical grouping of IDs but otherwise do not have any default behaviour. Instead, alias group IDs are generally used as arguments to other panel hints.

XpUNALIAS_( aliasID )
Remove the IDs in the trailing list from the alias group. If the ID list is empty (this hint is followed immediately by XpEND), all the elements of the group are removed and the group is disbanded.

XpGROUP_( groupID )
Create a new group, or add the trailing list of IDs to an existing group. The trailing list may contain the IDs of controls, aliases, other groups, stacks or tabs.

XpORDER_( groupID )
Reorder the IDs in a group. If the group ID is 0, this reorders IDs for the panel.

XpSTACK_( groupID, valID )
XpSTACK_MAP_( groupID, valID, map )
Define a control stack. Only one control at a time is visible in a stack (the rest are "hidden underneath"). Which control is visible is determined by the valID value. The value must be of integer type. A value of 0 selects the first control in the group. If you supply a map (an integer array), the visible control depends on map[value] rather than the value directly. A value of -1 means that no control from this group should be visible.

XpTABS_( groupID )
Create a tab window. Additional tab windows will be created for the IDs in the trailing list. The text displayed on the tab is taken from the label assigned to the ID using the XpLABEL hint.

XpCTRLFRONT( ctlID )
Identify the tab that should be displayed on top of other tabs. By default, the first tab is on top.

XpORIENT( ctlID, orientation )
Set the control's orientation, where 0 is horizontal and 1 is vertical. The default is horizontal. Not all controls can be oriented.

XpLEFT( groupID )
XpLEFT_()
Attempt to left align the first control in a group or the trailing list. If possible, subsequent controls are moved up beside the left-aligned control. This hint is ignored for some control classes (but see the XpNARROW hint), and space constraints can also affect whether it can be applied.

XpNARROW( groupID )
XpNARROW_()
The client may override the default "move up" rules by indicating that the controls in the group or the trailing list are narrow.

XpDIVADD( id )
XpDIVADD_( id )
This suggests the panel should draw a divider after the control or group specified by the ID list. The hint has one fixed argument so that the client can specify one of the special divider locations, intended mostly for inline panels: 0 for the top of the panel, -1 for the bottom.

XpDIVREM( id )
XpDIVREM_( id )
This indicates that the panel should not place a divider after the control or group. The panel performs some built-in guesswork on divider placement. Typically, they're put at "transition points," examples of which include points between a standalone control and a group, between separate groups, and between a group and a tab group. It won't always be easy to determine the abstract location of a divider solely from its appearance. For example, a divider may appear to follow a control but actually follow the group to which the control belongs.

XpBORDER( type )
Suggests the kind of border the panel should be drawn with. Possible values are
LWXPBDR_NONE
LWXPBDR_UP
LWXPBDR_DOWN
XpDLOGTYPE( type )
Modal panels include buttons that allow the user to accept or cancel their input. This macro specifies which buttons will be added. The numbers in the following list are the values returned by the post function when the user dismisses the panel by pressing the corresponding button.

LWXPDLG_OKCANCEL - OK 1, Cancel 0 (the default)
LWXPDLG_DONE - Done 1
LWXPDLG_OKONLY - OK 1
LWXPDLG_YESNO - Yes 1, No 0
LWXPDLG_YESNOALL - Yes 1, No 0, Yes To All 2, Cancel 3
LWXPDLG_YESNOCAN - Yes 1, No 0, Cancel 3

Callbacks

Xpanels and its controls rely on callbacks to communicate with your plug-in. Except for the data get and set callbacks, you tell XPanels about them using hints.

Data get/set

   typedef void *LWXPanelGetFunc (void *inst, unsigned long vid);
   typedef int   LWXPanelSetFunc (void *inst, unsigned long vid,
      void *value);

Your get and set functions are passed as the third and fourth arguments to the describe function when you're creating an LWXP_VIEW panel. XPanels calls the get function to get a value from you. The function returns a pointer to the value. XPanels calls the set function to give you a value when it has changed. The set callback returns a refresh code indicating what, if any, redrawing should take place on the panel. The code can be one of the following.

LWXPRC_NONE
LWXPRC_DFLT
LWXPRC_DRAW
LWXPRC_FULL

Destroy event

   typedef void LWXPanelDestroyNotifyFunc (void *);

This is called after the panel has been destroyed. Provide one of these if you need to do any panel-specific cleanup. Use the XpDESTROYNOTIFY hint to set the callback.

Value change event

   typedef void LWXPanelChangeNotifyFunc (LWXPanelID pan,
      unsigned long cid, unsigned long vid, int event_type);

This is called when user interaction is changing the value of a control, and when your panel is receiving or losing the input focus. Use the XpCHGNOTIFY hint to set the callback. The event type is one of the following.

LWXPEVENT_TRACK
LWXPEVENT_VALUE
LWXPEVENT_HIT
LWXPEVENT_FOCUS
LWXPEVENT_LOSEFOCUS

Typically, LWXP_FORM panels use the TRACK and VALUE events to dynamically follow changes in the values of their controls, while LWXP_VIEW panels rely instead on their data set callback.

Button click event

   typedef void LWXPanelBtnClickFunc (LWXPanelID pan, int cid);

Called when the user clicks a button control. Use the XpBUTNOTIFY hint to set the callback.

Popup command

   typedef void LWXPanelPopCmdFunc (LWXPanelID pan, int cid, int cmd);

Called when the user selects an item from a popup menu. Use the XpPOPCMDFUNC hint to set the callback.

Popup choice

   typedef int         LWXPanelPopCntFunc  (void *userdata);
   typedef const char *LWXPanelPopNameFunc (void *userdata, int idx);

Called when a popup is displayed. The count callback returns the number of items in the menu. The name callback is then called for each item and returns the string to be displayed for the item. Use the XpPOPFUNCS hint to set these callbacks.

Draw event

   typedef void LWXPanelControlDrawFunc (LWXPanelID pan,
      unsigned long cid, LWXPDrAreaID *reg, int w, int h);

Called when a drawable control (a dThumbnail) needs to be redrawn. Use the XpDRAWCBFUNC hint to set the callback.

Zoom event

   typedef void LWXPanelControlZoomFunc (LWXPanelID pan,
      unsigned long cid, int x, int y, int *region, int clickcount );

Called when the user clicks and drags the mouse within the control (a dThumbnail). Use the XpZOOMCBFUNC hint to set the callback.

Drawing Functions

Drawing is limited to contexts in which a valid LWXPDrAreaID is available, currently the draw callback of a thumbnail control.

   typedef struct st_LWXPDrawFuncs {
      void (*drawPixel)    (LWXPDrAreaID, int c, int x, int y );
      void (*drawRGBPixel) (LWXPDrAreaID, int r, int g, int b, int x,
                              int y );
      void (*drawLine)     (LWXPDrAreaID, int c, int x, int y, int x2,
                              int y2 );
      void (*drawBox)      (LWXPDrAreaID, int c, int x, int y, int w,
                              int h );
      void (*drawRGBBox)   (LWXPDrAreaID, int r, int g, int b, int x,
                              int y, int w, int h );
      void (*drawBorder)   (LWXPDrAreaID, int indent, int x, int y,
                              int w, int h );
      int  (*textWidth)    (LWXPDrAreaID, char *s );
      int  (*textHeight)   (LWXPDrAreaID, char *s );
      void (*drawText)     (LWXPDrAreaID, char *s, int c, int x, int y );
   } LWXPDrawFuncs;
drawPixel( drawid, color, x, y )
drawRGBPixel( drawid, r, g, b, x, y )
Draw a pixel. The coordinates are relative to the upper-left corner of the drawing area. The color is specified as one of the palette colors defined in lwpanel.h or as levels of red, green and blue between 0 and 255.

drawLine( drawid, color, x1, y1, x2, y2 )
Draw a line connecting the endpoints.

drawBox( drawid, color, x, y, w, h )
drawRGBBox( drawid, r, g, b, x, y, w, h )
Draw a solid rectangle.

drawBorder( drawid, indent, x, y, w, h )
Draw a rectangular border similar to the ones use to mark the borders of controls. The indent is the thickness of the border. If h is 0, drawBorder creates a horizontal divider.

tw = textWidth( drawid, string )
th = textHeight( drawid, string )
The pixel width and height of the text in the font used by panels.

drawText( drawid, string, color, x, y )
Render a line of text.

Example

Many of the SDK samples (including blotch, box, hotvideo, kepler, mandfilt, NoisyChan, specular, and txchan) use XPanels for their interfaces. xpanchan, xpanlgen and xpanxtreme were written specifically to demonstrate XPanels features.