CSE 457

Introduction to Computer Graphics

libui: The Interface Library

This documentation still needs work. If you find anything confusing or incomplete, please let me know. Any comments may you have will greatly facilitate it's revision.


Overview

The user-interface library you will be using in 457 is designed to be powerful and simple to use. It provides you with buttons, toggle buttons, sliders, rectangular drawing areas, file dialogs, and a text feedback area.

The main things that the libui library provides you with are:


Reference

Data types and Constants

uiBool
Boolean type:
typedef enum {uiFalse, uiTrue} uiBool;

uiColorRGB
RGB color type:
typedef struct { float r; float g; float b; } uiColorRGB;

uiDrawingPlane
The different planes to draw into. Specified when calling uiSetCurrentWindow() .
typedef enum {uiNormal, uiOverlayPlane} uiDrawingPlane;

uiNormal
The normal drawing plane. This is a full-color drawing plane, where colors are specified using the glColor* calls. Most drawing will take place in this plane.
uiOverlayPlane
The overlay plane. This is a drawing plane that sits on top of the normal plane, which can be used to draw on top of things without disturbing them. This plane is an indexed-color plane, so colors are specified using glIndex(). Index 0 is transparent.

uiAppOptions
Options for the uiInitWindows() call. The options parameter of this call should be the logical OR of the desired options, or uiNone for none of them.
typedef enum {uiHasNone = 0, uiHasControls = 1, uiHasText = 2, uiHasDouble = 4 } uiAppOptions;

uiHasNone
none of the following.
uiHasControls
The control area in the upper-right of the main window is present.
uiHasText
The text area at the bottom of the main window is present.
uiHasDouble
Double-buffering is enabled for the application.
uiIndexedColorMode
Main windows use indexed color.

Examples:
uiInitWindows( 0, NULL, uiHasControls );
uiInitWindows( 0, NULL, uiHasControls | uiHasText);

uiMouseAction
Enumerated type indicating what kind of mouse action has taken place.
typedef enum {
uiLeftMouseDown, uiLeftMouseUp,
uiLeftMouseDrag, uiLeftMouseClick,
uiRightMouseDown, uiRightMouseUp,
uiRightMouseDrag, uiRightMouseClick
} uiMouseAction;
uiLeftMouseDown, uiRightMouseDown
The left or right mouse button was pressed.
uiLeftMouseUp, uiRightMouseUp
The left or right mouse button was released.
uiLeftMouseDrag, uiRightMouseDrag
The mouse was moved while a button was held down. A drag action will always be preceeded by a corresponding uiMouseDown action.
uiLeftMouseClick, uiRightMouseClick
The mouse button has been briefly pressed and released without motion in between. When a uiMouseClick action is reported, the corresponding uiMouseDown and uiMouseUp actions are not reported.

uiWindow
Opaque type returned from uiAddWindow().

uiSlider
Slider type returned from uiAddSlider().

uiToggleButton
Toggle button type returned from uiToggleButton().

Callback types

typedef void (* uiExposeCallback)( uiWindow *window);
Exposure callback routine. Called in response to a window being exposed.

  • window: the window which has been exposed

The application can force the exposure routine to be called by calling uiDirtyWindow() .

typedef int (* uiIdleCallback) (void);
Idle procedure. Called periodically when the system has nothing better to do. An idle procedure is added to the work queue with uiSetIdleCallback(), and removed depending upon the return value of your idle procedure:

TRUE
The idle procedure is through with its task, and should be removed from the work queue. (To put it back on the queue, you need to call uiSetIdleCallback again.)
FALSE
The idle procedure is not through with its task, and will remain on the event queue

typedef int (* uiTimerCallback) (void);
Similar to an IdleCallback, only also incorporates a pause interval. A timer procedure is added with uiSetTimerCallback() where you define a pause interval (in milliseconds). Like an idle procedure, a timer procedure is added and removed depending on its return value:
TRUE
The timer procedure is through, remove this from the timer queue. (To put it back on the queue, you need to call uiSetTimerCallback again.)
FALSE
The timer procedure is not through with its task, and will remain on the event queue.

typedef void (* uiCallback ) (void);
Button or slider callback. Called in response to the user pressing the button or moving the slider with which it is associated. See uiAddButton(), uiAddToggleButton() and uiAddSlider() .

typedef void (* uiMouseCallback) (uiWindow *window, int x, int y, uiMouseAction action);
Mouse action callback - called in response to mouse input in window.

window
The window in which the mouse action took place.
x, y
The location of the mouse action.
action
The mouse action which caused the callback to be invoked.

Applications specify the mouse callback routine in uiAddWindow().

typedef void (* uiFileBoxCallback) (char *filename);
File-selection dialog callback routine.

filename
The name of the file that was selected when the OK button was pressed.

uiMenuCallback
!!!!

Image Library types

typedef enum { SCALAR, VECTOR } argType;
Color depth of an Image.

SCALAR
Image is black and white
VECTOR
Image is color

typedef struct {
    Real x, y, z;
} Vector;

Vector type. For images, x is used as the red component, y is used as green and z is used as blue.

typedef struct {
    int _width, _height;
    argType _type;
    union {
      Real *scal_image;
      Vector *vec_image;
    } _image; int _scale_pixel_values;
    Real _pixel_scale_factor;
} Image;

Image type. Routines are available for accessing all the fields of this structure, so you shouldn't have to worry about them.

Macros

The following macros are defined by libui:
#define MIN(a,b) ((a)<(b)?(a):(b))
Fairly simple, expands to find the minimum of two items

#define MAX(a,b) ((a)>(b)?(a):(b))
MIN's complement

#define CLAMP(x,lo,hi) (MAX(MIN(x,hi),lo))
Clamps number specified by x to be between hi and lo



Routines

Initialization routines

void uiSetControlWidth (int width);
void uiSetControlHeight (int height);
Sets the width and height of the control area in which buttons and sliders are placed. The control area is located in the upper-right corner of the main application window.

void uiSetTextHeight ( int height );
Sets the height of the text area at the bottom of the application window. The text displayed in this area can be changed and examined by calling uiSetText() and uiGetText().

void uiSetMainWindowWidth (int width);
void uiSetMainWindowHeight (int height);
Sets the size of the main application window. This includes the control area and the text area. It is up to the application to make sure that this window is big enough to hold all of the things it wants to place inside of it.

uiBool uiInitWindows (unsigned int argc, char **argv, uiAppOptions options);
Initializes the interface library and creates the main application window.

argc, argv
If you wish, you can pass the arguments from main to uiInitWindows(). Normally, you would just pass 0 and NULL .
options
Sets what aspects of the application windows will be enabled. You may elect to have a text region, control region, double buffer, or more. See the definition of uiAppOptions for a complete list of options. To select two or more options, pass in their logical OR.

The application should call uiInitWindows to initialize the ui Library. This call should be made after the sizes of the parts of the application have been set.

void uiMainLoop();
This function starts the applications' main loop. In this loop, libui will process user interaction, and call the appropriate callbacks where defined. NB: This function never returns, so it should be the last statement in your main() function.




Window routines

uiWindow *uiAddWindow (int x, int y, int width, int height, uiExposeCallback expose, uiMouseCallback mouse, void *userData );
Adds a drawing area inside the main window.

x, y
The (x, y) location of the upper-left corner of the new window relative to the upper-left corner of the main application window. Note: the coordinate system used by this call (unfortunately) considers the origin to be at the upper-left, with x increasing going to the right and y increasing going down. This is not the same coordinate system used by OpenGL, which considers the origin to be the lower-left corner, with y increasing going up.
width, height
The width and height of the new window.
expose
A callback to be invoked when the window is exposed. If no callback is to be invoked, pass NULL for the the expose paramater.
mouse
A callback to be invoked in response to mouse input for this window. If no mouse callback is to be invoked, pass NULL for the mouse paramater.
userData
A pointer to some private data you wish to associate with this window. If no private data is necessary, pass NULL for the userData paramater.
Drawing areas are rectangular regions in which the application can do drawing. To specify which window is to be drawn into, the application must call uiSetCurrentWindow().

void uiSetUserData ( uiWindow *window, void *data );
Sets window's private data to point to data.

void *uiGetUserData ( uiWindow *window );
Retrieves window's private data.

void uiSetCurrentWindow (uiWindow *window, uiDrawingPlane plane);
Sets the current drawing window.

window
The window into which drawing should be done.
plane
The drawing layer onto which drawing should be done. If plane is uiNormal, drawing will take place in the normal drawing window. If plane is uiOverlayPlane, drawing will take place in the overlay plane.
Note that the normal drawing plane (uiNormal) is a full-color RGB plane, while the overlay plane (uiOverlayPlane ) is an indexed plane.

void uiDirtyWindow (uiWindow *window);
Forces a window's expose callback to be invoked.

window
The window whose expose callback is to be invoked.
This call is used to signal a window to redisplay it's contents. This can be useful if the application is written in such a way that drawing is done only (mostly?) inside of expose callbacks. This helps to concentrate the drawing code in one area, which in turn helps to locate drawing-related bugs.

void uiGetWindowSize (uiWindow *window, int *width, int *height);
Returns the size of window in width and height. Pass NULL to either if you don't care about their values.

void uiMapCoordinates (uiWindow *src, uiWindow *dst, int *x, int *y);
Maps a location from the coordinate space of one window to the coordinate space of another. This is most often used when one window is contained withing another.

src
The source window, in which the coordinates are initially expressed.
dst
The destination window, to which the coordinates are to be translated.
x, y
The point in window src to be translated. After the routine returns, they will be set to the transformed coordinates.




Control routines

void uiAddButton (char *label, uiCallback pushCallback);
Adds a button control to the control area.

label
The text to be used as a label for the button.
pushCallback
The callback procedure to be invoked when the button is pushed.
Controls (buttons, sliders, menus, etc.) are added one below another, starting at the top of the control area.

uiToggleButton uiAddToggleButton( char *label, uiBool initialState, uiCallback valueChangedCallback);
Adds a toggle button to the control area.

label
The text to be used as a label for the button.
initialState
The initial state for the toggle button.
valueChangedCallback
The callback procedure to be invoked when the state of the toggle button changes.
A toggle button (or checkbox) is a small button which can be set to either True or False by the user. Toggle buttons, like other controls, are added one below another, starting at the top of the control area.

uiBool uiGetToggleButtonState ( uiToggleButton button );
Returns the current state of button.

void uiSetToggleButtonState ( uiToggleButton button, uiBool state);
Sets the current state of toggle button button to be state.

uiSlider uiAddSlider ( char *label, double value, double min, double max, int decimals, uiCallback valueChangedCallback );
Adds a slider control to the control area.

label
The name for the slider.
value
The initial value for the slider.
min, max
The minimum and maximum values that the slider can have.
decimals
Number of decimals to use (eg, 10 is 0 decimals, 10.5 is 1, etc.)
valueChangedCallback
The callback procedure to be invoked when the slider's value is changed. Note that you can always get the value of a slider with uiGetSliderValue() , so you only really need to use the callback in cases where you want to take some immediate action in response to a slider being changed. Additionally, the callback only occurs when the user has released the mouse, not while the user is dragging the slider.
Sliders, like all other controls, are added one below another, starting at the top of the control area.

double uiGetSliderValue ( uiSlider slider );
Returns the current value of slider.

void uiSetSliderValue ( uiSlider slider, double t);
Sets the value of the slider.

void uiSetSliderParams ( uiSlider slider, double min, double max, double current, int decimal_points)
Sets the various paramaters of the slider.

slider
The uiSlider that is being modified.
min
The new minimum value for the slider. The minimum value must be less than both the current and the max values.
max
The maximum value for the slider. The maximum value must be greater than both the current and the min values.
current
The new "current" value that the slider will show. The current value must be between min and max, inclusive.
decimal_points
The number of digits to the right of the decimal that will be displayed and reported. Valid ranges are any non-negative integer.

See also uiGetSliderParams() for obtaining the current parameter set for a slider.

void uiGetSliderParams (uiSlider slider, double *min, double *max, double *current, int * decimal_points)
Get the various parameters for slider.

slider
The uiSlider that is being read.
min
A pointer to where the minimum value of the slider should be written.
max
A pointer to where the maximum value of the slider should be written.
current
A pointer to where the current value of the slider should be written.
decimal_points
A pointer to where the current number of significant digits right of the decimal should be stored.
See also uiSetSliderParams() .

uiMenu uiMakeMenu (char *menuTitle);
This function creates the "menu button". When the user clicks on this button, a pop-up menu will appear. To add items to this popup menu, call uiAddMenuItem(), passing in the uiMenu type returned by this function.

void uiAddMenuItem (uiMenu menu, char *menuText, uiMenuCallback callback, int userData);
Add a menu item to the menu menu, which was created with uiMakeMenu().

menu
The menu to which this menu item is to be appended. menu is the value returned by uiMakeMenu.
menuText
This is the label to be associated with this menu item. When the user clicks on the menu button to reveal the popup menu, it is this text that the user will see.
callback
The callback routine to be invoked when the user selects this menu item. If no such callback routine is to be used, pass NULL for this argument.
userData
This is the optional user data associated with this menu item. When the callback is invoked in response to user activity, this data is passed to the callback routine.

Although the userData is only an int, it can still be useful. Typically, the id of the menu item being created is used for userData, so that one callback routine can be used for the entire menu. All that the callback routine would have to do, then, is process its argument userData in a switch ... case ... break block.

void uiSetText ( char *text );
Sets the contents of the text field at the bottom of the window.

text
The text to be displayed. Pass NULL if no text is to be displayed.
This function only has effect if uiInitWindows() was called with the uiHasText option.

char *uiGetText ( void );
Returns a pointer to the string in the text field at the bottom of the window. This pointer points to memory allocated just for your program. If you don't call uiFreeText(), that memory won't be freed, and you'll have a memory leak!

void uiFreeText(char * s);
Frees the memory allocated by libui when uiGetText() is called. Without this freeing call, you will have a memory leak!




Image routines

Image *uiNewImage (int width, int height, argType type );
Returns a newly allocated image.

width
The width of new image.
height
The height of new image.
type
The type of image - either SCALAR, for a grayscale image, or VECTOR, for a color image.

Note that this routine allocates the memory for the image, so you need to call uiDeleteImage() to free up this memory when you're done with the image.

void uiDeleteImage ( Image *im );
Frees the memory that has been allocated for an image.

Image *uiOpenImage (char * filename, int width, int height);
Opens an RGB file, and reads it into memory. Returns a pointer to the new image.

filename
Name of RGB file to be opened.
width
Desired width of new image. If the RGB image on disk has a different width, the image will be scaled.
height
Desired height of new image. If the RGB image on disk has a different height, the image will be scaled.

If the file cannot be opened, or some other error occurs, uiOpenImage() returns NULL. All images that are opened are created as VECTOR images. When you are done with this image, be sure to call uiCloseImage() to properly free the memory associated with the image.

void uiSaveImage(Image *image, char *filename);
Save an image to disk as an RGB file.

image
Pointer to image to be saved. This image can either be VECTOR or scalar.
filename
Name of file to save image to. This name should end with ".rgb" (no quotes). If it does not, a .rgb extention will be added for you.

Pixel scaling is disabled in uiSaveImage, so you must call uiScalePixelValues() to reenable scaling, if desired.

void uiCloseImage (Image *im);
Close the image im that was opened with uiOpenImage().

int uiImageWidth ( Image *im );
int uiImageHeight ( Image *im );
Returns the width or height of an image.

argType uiImageType ( Image *im );
Returns the type of an image, either SCALAR, for a grayscale image, or VECTOR for a color image.

void uiSetScalarValue ( Image *im, int ix, int iy, Real val );
Sets the grayscale intensity of a pixel in an image.

im
The image to modify.
ix, iy
The coordinates of the pixel whose color is to be set.
val
The grayscale value of the pixel. This should be normalized to be between 0.0 and 1.0.

void uiSetVectorValue ( Image *im, int ix, int iy, Vector val );
Sets the color of a pixel in an image.

im
The image to modify.
ix, iy
The coordinates of the pixel whose color is to be set.
val
The color of the pixel. This is a vector where the first (x) component is taken to be the red value, the second (y) component is taken to be the green value, and the the third (z) component is taken to be the blue value. All values should be normalized to be between 0.0 and 1.0.

Real uiGetScalarValue ( Image *im, int ix, int iy );
Returns the gray value of a pixel.

im
The image.
ix, iy
The coordinates of the pixel.

Vector uiGetVectorValue ( Image *im, int ix, int iy );
Returns the color value of a pixel.

im
The image.
ix, iy
The coordinates of the pixel.

unsigned long uiGetPixelValue ( Image *im, int ix, int iy );
Returns the color value of a pixel in a packed representation that OpenGL is familiar with.

im
The image.
ix, iy
The coordinates of the pixel.

The return value of this function is a packed representation of the pixel color. That is, the 32-bit unsigned long that is returned "looks like" RRGGBBAA, where the red component is the upper 8 bits, the green is the next 8, blue next, and alpha is the lowest 8 bits. This value can be used as the argument to a glColor4ub call.

unsigned long *uiGetPixelData ( Image *im );
Returns an array of pixel values that the call glDrawPixels can understand.

im
The image to get the pixel data from.

This is just like calling uiGetPixelValue() for each pixel in the image.

void uiScalePixelValues ( Image *im, uiBool val );
Specifies whether or not to scale the intensity values of an image when retreiving pixel data from it (using uiGetPixelValue() or uiGetPixelData().

im
The image.
val
uiTrue if you want to enable pixel value scaling, and uiFalse if you want to disable it.

void uiSetScaleFactor ( Image *im, Real val );
Sets the pixel scaling factor for an image.

im
The image to set the scaling factor of.
val
The scale factor to use when generating pixel values for this image.

This procedure sets a constant scaling factor to multiply the value of each pixel with when querying pixel values.




Drawing Routines

void uiGetColorTableParams (int *start, int *size);
Only valid when using indexed color mode in the main window(s).
Sets *start to be the starting index of the color table and *size to be the size of the table.

void uiSetColorTableEntry (int which, float red, float green, float blue);
Only valid when using indexed color mode in the main window(s).
Sets one entry of the color table.

which
index # to set
red, green, blue
floating-point values [0.0, 1.0] for red, green, and blue channels

void uiSetColorTable (int start, int length, float *data);
Only valid when using indexed color mode in the main window(s).
Sets a set of entries of the color table.

start
starting index of the color table
length
number of entries to set
data
array of data containing floating-point values [0.0, 1.0] for red, green, and blue channels

void uiSetColorIndex (uiColorIndex index);
Set the current drawing color to an indexed-color.

index
Index in color map to assign current color

void uiSetColorRGB (uiColorRGB color);
Set the current drawing color to the RGB color specified.

color
RGB Color to assign current color

int uiGetBlackPixel (void);
Returns the color index that will produce black on the overlay plane.

int uiGetWhitePixel (void);
Returns the color index that will produce white on the overlay plane.

void uiSetBackground ( void );
Sets the current drawing color to the window's background color.

void uiDrawLine (int x1, int y1, int x2, int y2);
Draws a line between two points. This must be preceeded by a uiSetCurrentWindow call, and must be followed by a uiFlush call.

x1, y1
first point
x2, y2
second point

void uiSetDrawMode (uiDrawMode mode);
Used to specify the drawing mode. This can only be used when drawing with indexed-color

mode
Mode to do drawing
UI_XOR : specifies drawing in XOR mode
UI_COPY : specifies drawing in standard draw mode

void uiDrawImage (Image * im, int x, int y);
Draws image to given coordinates

im
Pointer to image in memory
x, y
Coordinates to draw image

void uiFlush();
Signal to draw queued objects immediately. The function Miscellaneous routines
void uiSetIdleCallback (uiIdleCallback idleProc );
Defines an idle procedure to be called periodically when the program has nothing better to do. You may call uiSetIdleCallback() anywhere in your program, just as long as uiInitWindows() has already been called. To disable an idle procedure, the procedure should return TRUE; this will remove the procedure from the work queue (you need to call uiSetIdleCallback again to replace it). To leave an idle procedure on the work queue, the procedure should return FALSE. Because idle procedures, even empty ones, consume large amounts of system resources, it is best to leave them disabled until needed.

void uiSetTimerCallback (uiTimerCallback timerProc, unsigned long interval);
Like an idle callback, only is called at a defined interval (in milliseconds). Will be continually called until the callback procedure returns TRUE when it is removed from the event queue. To replace it, you must call uiSetTimerCallback again.

void uiQuit();
Shuts down the interface library. This function never returns -- uiQuit() calls exit(1) as its last statement.

void uiPostFileDialog (char *title, char *filter, uiFileBoxCallback okCallback );
Presents a file-selection dialog.

title
The title of the dialog box.
filter
An optional filter that filenames must satisfy in order to be shown. (for example, "*.c" to show files ending with ".c")
okCallback
The callback procedure to be invoked when the user presses the OK button in the dialog. This is where the name of the selected file is made available. If no callback is to be invoked, pass NULL for this argument.
When the application calls uiPostFileDialog(), a file-selection box is presented. The uiPostFileDialog call returns control to the application immediately (while the dialog box is still up), and the application is notified when the OK button has been pressed via the okCallback.

void uiBusyCursor (int state, int interruptable)
Sets the cursor the watch. This is a useful user interface routine to let the user know that the current operation could take some time.

state
Determines whether the the cursor should be changed to the watch, or changed back. To change to the watch, use ENABLE_BUSY_CURSOR. To change back to the default icon, use DISABLE_BUSY_CURSOR. When the cursor is set to the watch, no user interaction will be allowed. Additionally, user interation will not be queued.
interruptable
This variable is currently not used. Always set it to 0.




Glossary

Callback Procedure
A routine that is called by the interface library in response to some action (the user presses a button, a window becomes visible, etc)
Idle Procedure
A routine that is called periodically by the interface library, when there is nothing else to do.
Overlay plane
A drawing plane which lies above another drawing area and whose image is drawn on top of the image beneath it. One color index (typically 0) is specified to be transparent.



Index

Back to the CS457 Home Page
mtwong@cs.washington.edu (last modified: 19 Mar 1996)