This is MultiList.c in view mode; [Download] [Up]
#if ( !defined(lint) && !defined(SABER))
static char PCN_rcsid[] = "$Header: /ufs/comp/mei/PROJ_PCN/onprofile/IFModel/Xsw/RCS/MultiList.c,v 1.1 1992/04/17 18:25:49 mei Exp $";
#endif
/*
* Copyright 1989 Massachusetts Institute of Technology
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of M.I.T. not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. M.I.T. makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
/*
* MultiList.c - MultiList widget
*
* This is the MultiList widget, it is useful to display a multiList, without the
* overhead of having a widget for each item in the multiList. It allows
* the user to select an item in a multiList and notifies the application through
* a callback function.
*
* Created: 8/13/88
* By: Chris D. Peterson
* MIT X Consortium
*/
#include <stdio.h>
#include <ctype.h>
#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
#include <X11/Xmu/Drawing.h>
#include <X11/Xaw/XawInit.h>
#include "MultiListP.h"
/*
* Default Translation table.
*/
static char defaultTranslations[] =
"<Btn1Down>: Set()Notify()\n\
<Btn1Motion>: Move()\n\
";
/****************************************************************
*
* Full class record constant
*
****************************************************************/
/* Private Data */
#define offset(field) XtOffset(MultiListWidget, field)
static XtResource resources[] = {
{XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
offset(multiList.foreground), XtRString, "XtDefaultForeground"},
{XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor),
offset(simple.cursor), XtRString, "left_ptr"},
{XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
offset(multiList.font),XtRString, "XtDefaultFont"},
{XtNlist, XtCList, XtRPointer, sizeof(char **),
offset(multiList.list), XtRString, NULL},
{XtNsingle, XtCSingle, XtRBoolean, sizeof(Boolean),
offset(multiList.single), XtRString, "True"},
{XtNdefaultColumns, XtCColumns, XtRInt, sizeof(int),
offset(multiList.default_cols), XtRImmediate, (XPointer)2},
{XtNlongest, XtCLongest, XtRInt, sizeof(int),
offset(multiList.longest), XtRImmediate, (XPointer)0},
{XtNnumberStrings, XtCNumberStrings, XtRInt, sizeof(int),
offset(multiList.nitems), XtRImmediate, (XPointer)0},
{XtNpasteBuffer, XtCBoolean, XtRBoolean, sizeof(Boolean),
offset(multiList.paste), XtRString, (XPointer) "False"},
{XtNforceColumns, XtCColumns, XtRBoolean, sizeof(Boolean),
offset(multiList.force_cols), XtRString, (XPointer) "False"},
{XtNverticalMultiList, XtCBoolean, XtRBoolean, sizeof(Boolean),
offset(multiList.vertical_cols), XtRString, (XPointer) "False"},
{XtNinternalWidth, XtCWidth, XtRDimension, sizeof(Dimension),
offset(multiList.internal_width), XtRImmediate, (XPointer)4},
{XtNinternalHeight, XtCHeight, XtRDimension, sizeof(Dimension),
offset(multiList.internal_height), XtRImmediate, (XPointer)2},
{XtNcolumnSpacing, XtCSpacing, XtRDimension, sizeof(Dimension),
offset(multiList.column_space), XtRImmediate, (XPointer)6},
{XtNrowSpacing, XtCSpacing, XtRDimension, sizeof(Dimension),
offset(multiList.row_space), XtRImmediate, (XPointer)2},
{XtNcallback, XtCCallback, XtRCallback, sizeof(XPointer),
offset(multiList.callback), XtRCallback, NULL},
};
static void Initialize();
static void Destroy();
static void ChangeSize();
static void Resize();
static void Redisplay();
static Boolean Layout();
static XtGeometryResult PreferredGeom();
static Boolean SetValues();
static void Notify(), Set(), Unset(), Move();
static XtActionsRec actions[] = {
{"Notify", Notify},
{"Set", Set},
{"Unset", Unset},
{"Move", Move},
{NULL,NULL}
};
MultiListClassRec multiListClassRec = {
{
/* core_class fields */
#define superclass (&simpleClassRec)
/* superclass */ (WidgetClass) superclass,
/* class_name */ "MultiList",
/* widget_size */ sizeof(MultiListRec),
/* class_initialize */ XawInitializeWidgetSet,
/* class_part_initialize */ NULL,
/* class_inited */ FALSE,
/* initialize */ Initialize,
/* initialize_hook */ NULL,
/* realize */ XtInheritRealize,
/* actions */ actions,
/* num_actions */ XtNumber(actions),
/* resources */ resources,
/* num_resources */ XtNumber(resources),
/* xrm_class */ NULLQUARK,
/* compress_motion */ TRUE,
/* compress_exposure */ FALSE,
/* compress_enterleave */ TRUE,
/* visible_interest */ FALSE,
/* destroy */ Destroy,
/* resize */ Resize,
/* expose */ Redisplay,
/* set_values */ SetValues,
/* set_values_hook */ NULL,
/* set_values_almost */ XtInheritSetValuesAlmost,
/* get_values_hook */ NULL,
/* accept_focus */ NULL,
/* version */ XtVersion,
/* callback_private */ NULL,
/* tm_table */ defaultTranslations,
/* query_geometry */ PreferredGeom,
},
/* Simple class fields initialization */
{
/* change_sensitive */ XtInheritChangeSensitive
}
};
WidgetClass multiListWidgetClass = (WidgetClass)&multiListClassRec;
/****************************************************************
*
* Private Procedures
*
****************************************************************/
static void GetGCs(w)
Widget w;
{
XGCValues values;
MultiListWidget lw = (MultiListWidget) w;
values.foreground = lw->multiList.foreground;
values.font = lw->multiList.font->fid;
lw->multiList.normgc = XtGetGC(w, (unsigned) GCForeground | GCFont,
&values);
values.foreground = lw->core.background_pixel;
lw->multiList.revgc = XtGetGC(w, (unsigned) GCForeground | GCFont,
&values);
values.tile = XmuCreateStippledPixmap(XtScreen(w),
lw->multiList.foreground,
lw->core.background_pixel,
lw->core.depth);
values.fill_style = FillTiled;
lw->multiList.graygc = XtGetGC(w, (unsigned) GCFont | GCTile | GCFillStyle,
&values);
}
/* Function Name: ResetMultiList
* Description: Resets the new multiList when important things change.
* Arguments: w - the widget.
* changex, changey - allow the height or width to change?
* Returns: none.
*/
static void
ResetMultiList(w, changex, changey)
Widget w;
Boolean changex, changey;
{
MultiListWidget lw = (MultiListWidget) w;
Dimension width = w->core.width;
Dimension height = w->core.height;
register int i, len;
/*
* If multiList is NULL then the multiList will just be the name of the widget.
*/
if (lw->multiList.list == NULL) {
lw->multiList.list = &(lw->core.name);
lw->multiList.nitems = 1;
}
if (lw->multiList.nitems == 0) /* Get number of items. */
for ( ; lw->multiList.list[lw->multiList.nitems] != NULL ; lw->multiList.nitems++);
if (lw->multiList.longest == 0) /* Get column width. */
for ( i = 0 ; i < lw->multiList.nitems; i++) {
len = XTextWidth(lw->multiList.font, lw->multiList.list[i],
strlen(lw->multiList.list[i]));
if (len > lw->multiList.longest)
lw->multiList.longest = len;
}
lw->multiList.col_width = lw->multiList.longest + lw->multiList.column_space;
if (Layout(w, changex, changey, &width, &height))
ChangeSize(w, width, height);
lw->multiList.state =
(Boolean *)XtCalloc(lw->multiList.nitems, sizeof(Boolean));
}
/* Function Name: ChangeSize.
* Description: Laysout the widget.
* Arguments: w - the widget to try change the size of.
* Returns: none.
*/
static void
ChangeSize(w, width, height)
Widget w;
Dimension width, height;
{
XtWidgetGeometry request, reply;
request.request_mode = CWWidth | CWHeight;
request.width = width;
request.height = height;
switch ( XtMakeGeometryRequest(w, &request, &reply) ) {
case XtGeometryYes:
case XtGeometryNo:
break;
case XtGeometryAlmost:
Layout(w, (request.height != reply.height),
(request.width != reply.width),
&(reply.width), &(reply.height));
request = reply;
switch (XtMakeGeometryRequest(w, &request, &reply) ) {
case XtGeometryYes:
case XtGeometryNo:
break;
case XtGeometryAlmost:
request = reply;
if (Layout(w, FALSE, FALSE,
&(request.width), &(request.height))) {
char buf[BUFSIZ];
sprintf(buf, "MultiList Widget: %s %s",
"Size Changed when it shouldn't have",
"when computing layout");
XtAppWarning(XtWidgetToApplicationContext(w), buf);
}
request.request_mode = CWWidth | CWHeight;
XtMakeGeometryRequest(w, &request, &reply);
break;
default:
XtAppWarning(XtWidgetToApplicationContext(w),
"MultiList Widget: Unknown geometry return.");
break;
}
break;
default:
XtAppWarning(XtWidgetToApplicationContext(w),
"MultiList Widget: Unknown geometry return.");
break;
}
}
/* Function Name: Initialize
* Description: Function that initilizes the widget instance.
* Arguments: junk - NOT USED.
* new - the new widget.
* Returns: none
*/
/* ARGSUSED */
static void
Initialize(junk, new)
Widget junk, new;
{
MultiListWidget lw = (MultiListWidget) new;
/*
* Initialize all private resources.
*/
GetGCs(new);
/* Set row height. */
lw->multiList.row_height = lw->multiList.font->max_bounds.ascent
+ lw->multiList.font->max_bounds.descent
+ lw->multiList.row_space;
ResetMultiList(new, (new->core.width == 0), (new->core.height == 0));
lw->multiList.highlight = lw->multiList.is_highlighted = NO_HIGHLIGHT;
} /* Initialize */
/* Function Name: CvtToItem
* Description: Converts Xcoord to item number of item containing that
* point.
* Arguments: w - the multiList widget.
* xloc, yloc - x location, and y location.
* Returns: the item number.
*/
static int
CvtToItem(w, xloc, yloc, item)
Widget w;
int xloc, yloc;
int *item;
{
int one, another;
MultiListWidget lw = (MultiListWidget) w;
int ret_val = OKAY;
if (lw->multiList.vertical_cols) {
one = lw->multiList.nrows * ((xloc - (int) lw->multiList.internal_width)
/ lw->multiList.col_width);
another = (yloc - (int) lw->multiList.internal_height)
/ lw->multiList.row_height;
/* If out of range, return minimum possible value. */
if (another >= lw->multiList.nrows) {
another = lw->multiList.nrows - 1;
ret_val = OUT_OF_RANGE;
}
}
else {
one = (lw->multiList.ncols * ((yloc - (int) lw->multiList.internal_height)
/ lw->multiList.row_height)) ;
/* If in right margin handle things right. */
another = (xloc - (int) lw->multiList.internal_width) / lw->multiList.col_width;
if (another >= lw->multiList.ncols) {
another = lw->multiList.ncols - 1;
ret_val = OUT_OF_RANGE;
}
}
if ((xloc < 0) || (yloc < 0))
ret_val = OUT_OF_RANGE;
if (one < 0) one = 0;
if (another < 0) another = 0;
*item = one + another;
if (*item >= lw->multiList.nitems) return(OUT_OF_RANGE);
return(ret_val);
}
/* Function Name: FindmyCornerItems.
* Description: Find the corners of the rectangle in item space.
* Arguments: w - the multiList widget.
* event - the event structure that has the rectangle it it.
* ul_ret, lr_ret - the corners ** RETURNED **.
* Returns: none.
*/
FindmyCornerItems(w, event, ul_ret, lr_ret)
Widget w;
XEvent * event;
int *ul_ret, *lr_ret;
{
int xloc, yloc;
xloc = event->xexpose.x;
yloc = event->xexpose.y;
CvtToItem(w, xloc, yloc, ul_ret);
xloc += event->xexpose.width;
yloc += event->xexpose.height;
CvtToItem(w, xloc, yloc, lr_ret);
}
/* Function Name: ItemInmyRectangle
* Description: returns TRUE if the item passed is in the given rectangle.
* Arguments: w - the multiList widget.
* ul, lr - corners of the rectangle in item space.
* item - item to check.
* Returns: TRUE if the item passed is in the given rectangle.
*/
ItemInmyRectangle(w, ul, lr, item)
Widget w;
int ul, lr, item;
{
MultiListWidget lw = (MultiListWidget) w;
register int mod_item;
int things;
if (item < ul || item > lr)
return(FALSE);
if (lw->multiList.vertical_cols)
things = lw->multiList.nrows;
else
things = lw->multiList.ncols;
mod_item = item % things;
if ( (mod_item >= ul % things) && (mod_item <= lr % things ) )
return(TRUE);
return(FALSE);
}
/* Function Name: HighlightmyBackground
* Description: paints the color of the background for the given item.
* Arguments: w - the widget.
* x, y - ul corner of the area item occupies.
* item - the item we are dealing with.
* gc - the gc that is used to paint this rectangle
* Returns:
*/
HighlightmyBackground(w, x, y, item, gc)
Widget w;
int x, y, item;
GC gc;
{
MultiListWidget lw = (MultiListWidget) w;
int hl_x, hl_y, width, height;
hl_x = x - lw->multiList.column_space/2;
width = XTextWidth(lw->multiList.font, lw->multiList.list[item],
strlen(lw->multiList.list[item])) + lw->multiList.column_space;
hl_y = y - lw->multiList.row_space/2;
height = lw->multiList.row_height;
XFillRectangle(XtDisplay(w), XtWindow(w), gc, hl_x, hl_y, width, height);
}
/* Function Name: PaintmyItemName
* Description: paints the name of the item in the appropriate location.
* Arguments: w - the multiList widget.
* item - the item to draw.
* Returns: none.
*
* NOTE: no action taken on an unrealized widget.
*/
PaintmyItemName(w, item)
Widget w;
int item;
{
char * str;
GC gc;
int x, y, str_y;
MultiListWidget lw = (MultiListWidget) w;
if (!XtIsRealized(w)) return; /* Just in case... */
if (lw->multiList.vertical_cols) {
x = lw->multiList.col_width * (item / lw->multiList.nrows)
+ lw->multiList.internal_width;
y = lw->multiList.row_height * (item % lw->multiList.nrows)
+ lw->multiList.internal_height;
}
else {
x = lw->multiList.col_width * (item % lw->multiList.ncols)
+ lw->multiList.internal_width;
y = lw->multiList.row_height * (item / lw->multiList.ncols)
+ lw->multiList.internal_height;
}
str_y = y + lw->multiList.font->max_bounds.ascent;
if (lw->multiList.single) {
if (item == lw->multiList.is_highlighted) {
if (item == lw->multiList.highlight) {
gc = lw->multiList.revgc;
HighlightmyBackground(w, x, y, item, lw->multiList.normgc);
}
else {
if (XtIsSensitive(w))
gc = lw->multiList.normgc;
else
gc = lw->multiList.graygc;
HighlightmyBackground(w, x, y, item, lw->multiList.revgc);
lw->multiList.is_highlighted = NO_HIGHLIGHT;
}
}
else {
if (item == lw->multiList.highlight) {
gc = lw->multiList.revgc;
HighlightmyBackground(w, x, y, item, lw->multiList.normgc);
lw->multiList.is_highlighted = item;
}
else {
if (XtIsSensitive(w))
gc = lw->multiList.normgc;
else
gc = lw->multiList.graygc;
}
}
} else {
if (lw->multiList.state[item]) {
gc = lw->multiList.revgc;
HighlightmyBackground(w, x, y, item, lw->multiList.normgc);
}
else {
if (XtIsSensitive(w))
gc = lw->multiList.normgc;
else
gc = lw->multiList.graygc;
HighlightmyBackground(w, x, y, item, lw->multiList.revgc);
}
}
str = lw->multiList.list[item]; /* draw it */
XDrawString(XtDisplay(w), XtWindow(w), gc, x, str_y, str, strlen(str));
}
/* Function Name: Redisplay
* Description: Repaints the widget window on expose events.
* Arguments: w - the multiList widget.
* event - the expose event for this repaint.
* junk - NOT USED.
* Returns:
*/
/* ARGSUSED */
static void
Redisplay(w, event, junk)
Widget w;
XEvent *event;
Region junk;
{
int item; /* an item to work with. */
int ul_item, lr_item; /* corners of items we need to paint. */
MultiListWidget lw = (MultiListWidget) w;
if (event == NULL) { /* repaint all. */
ul_item = 0;
lr_item = lw->multiList.nrows * lw->multiList.ncols - 1;
XClearWindow(XtDisplay(w), XtWindow(w));
}
else
FindmyCornerItems(w, event, &ul_item, &lr_item);
for (item = ul_item; (item <= lr_item && item < lw->multiList.nitems) ; item++)
if (ItemInmyRectangle(w, ul_item, lr_item, item))
PaintmyItemName(w, item);
}
/* Function Name: PreferredGeom
* Description: This tells the parent what size we would like to be
* given certain constraints.
* Arguments: w - the widget.
* intended - what the parent intends to do with us.
* requested - what we want to happen.
* Returns: none.
*/
static XtGeometryResult
PreferredGeom(w, intended, requested)
Widget w;
XtWidgetGeometry *intended, *requested;
{
Dimension new_width, new_height;
Boolean change, width_req, height_req;
width_req = intended->request_mode & CWWidth;
height_req = intended->request_mode & CWHeight;
if (width_req)
new_width = intended->width;
else
new_width = w->core.width;
if (height_req)
new_height = intended->height;
else
new_height = w->core.height;
requested->request_mode = 0;
/*
* We only care about our height and width.
*/
if ( !width_req && !height_req)
return(XtGeometryYes);
change = Layout(w, !width_req, !height_req, &new_width, &new_height);
requested->request_mode |= CWWidth;
requested->width = new_width;
requested->request_mode |= CWHeight;
requested->height = new_height;
if (change)
return(XtGeometryAlmost);
return(XtGeometryYes);
}
/* Function Name: Resize
* Description: resizes the widget, by changing the number of rows and
* columns.
* Arguments: w - the widget.
* Returns: none.
*/
static void
Resize(w)
Widget w;
{
Dimension width, height;
width = w->core.width;
height = w->core.height;
if (Layout(w, FALSE, FALSE, &width, &height))
XtAppWarning(XtWidgetToApplicationContext(w),
"MultiList Widget: Size changed when it shouldn't have when resising.");
}
/* Function Name: Layout
* Description: lays out the item in the multiList.
* Arguments: w - the widget.
* xfree, yfree - TRUE if we are free to resize the widget in
* this direction.
* width, height - the is the current width and height that
* we are going to layout the multiList widget to,
* depending on xfree and yfree of course.
*
* Returns: TRUE if width or height have been changed.
*/
static Boolean
Layout(w, xfree, yfree, width, height)
Widget w;
Boolean xfree, yfree;
Dimension *width, *height;
{
MultiListWidget lw = (MultiListWidget) w;
Boolean change = FALSE;
/*
* If force columns is set then always use number of columns specified
* by default_cols.
*/
if (lw->multiList.force_cols) {
lw->multiList.ncols = lw->multiList.default_cols;
if (lw->multiList.ncols <= 0) lw->multiList.ncols = 1;
/* 12/3 = 4 and 10/3 = 4, but 9/3 = 3 */
lw->multiList.nrows = ( ( lw->multiList.nitems - 1) / lw->multiList.ncols) + 1 ;
if (xfree) { /* If allowed resize width. */
*width = lw->multiList.ncols * lw->multiList.col_width
+ 2 * lw->multiList.internal_width;
change = TRUE;
}
if (yfree) { /* If allowed resize height. */
*height = (lw->multiList.nrows * lw->multiList.row_height)
+ 2 * lw->multiList.internal_height;
change = TRUE;
}
return(change);
}
/*
* If both width and height are free to change the use default_cols
* to determine the number columns and set new width and height to
* just fit the window.
*/
if (xfree && yfree) {
lw->multiList.ncols = lw->multiList.default_cols;
if (lw->multiList.ncols <= 0) lw->multiList.ncols = 1;
lw->multiList.nrows = ( ( lw->multiList.nitems - 1) / lw->multiList.ncols) + 1 ;
*width = lw->multiList.ncols * lw->multiList.col_width
+ 2 * lw->multiList.internal_width;
*height = (lw->multiList.nrows * lw->multiList.row_height)
+ 2 * lw->multiList.internal_height;
change = TRUE;
}
/*
* If the width is fixed then use it to determine the number of columns.
* If the height is free to move (width still fixed) then resize the height
* of the widget to fit the current multiList exactly.
*/
else if (!xfree) {
lw->multiList.ncols = ( (*width - 2 * lw->multiList.internal_width)
/ lw->multiList.col_width);
if (lw->multiList.ncols <= 0) lw->multiList.ncols = 1;
lw->multiList.nrows = ( ( lw->multiList.nitems - 1) / lw->multiList.ncols) + 1 ;
if ( yfree ) {
*height = (lw->multiList.nrows * lw->multiList.row_height)
+ 2 * lw->multiList.internal_height;
change = TRUE;
}
}
/*
* The last case is xfree and !yfree we use the height to determine
* the number of rows and then set the width to just fit the resulting
* number of columns.
*/
else if (!yfree) { /* xfree must be TRUE. */
lw->multiList.nrows = (*height - 2 * lw->multiList.internal_height)
/ lw->multiList.row_height;
if (lw->multiList.nrows <= 0) lw->multiList.nrows = 1;
lw->multiList.ncols = (( lw->multiList.nitems - 1 ) / lw->multiList.nrows) + 1;
*width = lw->multiList.ncols * lw->multiList.col_width
+ 2 * lw->multiList.internal_width;
change = TRUE;
}
return(change);
}
/* Function Name: Notify
* Description: Notifies the user that a button has been pressed, and
* calles the callback, if the XtNpasteBuffer resource
* is true then the name of the item is also put in the
* X cut buffer ( buf (0) ).
* Arguments: w - the widget that the notify occured in.
* event - event that caused this notification.
* params, num_params - not used.
* Returns: none.
*/
/* ARGSUSED */
static void
Notify(w, event, params, num_params)
Widget w;
XEvent * event;
String * params;
Cardinal *num_params;
{
MultiListWidget lw = ( MultiListWidget ) w;
int item, item_len;
XswMultiListReturnStruct ret_value;
/*
* Find item and if out of range then unhighlight and return.
*
* If the current item is unhighlighted then the user has aborted the
* notify, so unhighlight and return.
*/
if ( ((CvtToItem(w, event->xbutton.x, event->xbutton.y, &item))
== OUT_OF_RANGE)) {
ret_value.string = "";
ret_value.list_index = XSW_LIST_NONE;
XtCallCallbacks( w, XtNcallback, (XPointer) &ret_value);
return;
}
if (lw->multiList.single && (lw->multiList.highlight != item) ) {
if (lw->multiList.highlight != NO_HIGHLIGHT)
XswMultiListUnhighlight(w, lw->multiList.highlight);
ret_value.string = "";
ret_value.list_index = XSW_LIST_NONE;
XtCallCallbacks( w, XtNcallback, (XPointer) &ret_value);
return;
}
item_len = strlen(lw->multiList.list[item]);
if ( lw->multiList.paste ) /* if XtNpasteBuffer set then paste it. */
XStoreBytes(XtDisplay(w), lw->multiList.list[item], item_len);
/*
* Call Callback function.
*/
if (lw->multiList.single &&
(lw->multiList.highlight == NO_HIGHLIGHT)) {
ret_value.string = "";
ret_value.list_index = XSW_LIST_NONE;
} else {
ret_value.string = lw->multiList.list[item];
ret_value.list_index = item;
}
XtCallCallbacks( w, XtNcallback, (XPointer) &ret_value);
}
/* Function Name: Unset
* Description: unhighlights the current element.
* Arguments: w - the widget that the event occured in.
* event - not used.
* params, num_params - not used.
* Returns: none.
*/
/* ARGSUSED */
static void
Unset(w, event, params, num_params)
Widget w;
XEvent * event;
String * params;
Cardinal *num_params;
{
int item;
if ( (CvtToItem(w, event->xbutton.x, event->xbutton.y, &item))
!= OUT_OF_RANGE) {
XswMultiListUnhighlight(w, item); /* highlighted then do it. */
}
}
/* Function Name: Set
* Description: Highlights the current element.
* Arguments: w - the widget that the event occured in.
* event - event that caused this notification.
* params, num_params - not used.
* Returns: none.
*/
/* ARGSUSED */
static void
Set(w, event, params, num_params)
Widget w;
XEvent * event;
String * params;
Cardinal *num_params;
{
int item;
MultiListWidget lw = (MultiListWidget) w;
if ( (CvtToItem(w, event->xbutton.x, event->xbutton.y, &item))
!= OUT_OF_RANGE) {
if (lw->multiList.single) {
XswMultiListHighlight(w, item);
} else {
if (!lw->multiList.state[item])
XswMultiListHighlight(w, item);
else
XswMultiListUnhighlight(w, item);
lw->multiList.toggle_state = lw->multiList.state[item];
}
} else {
lw->multiList.toggle_state = False;
for(item = 0; item < lw->multiList.nitems; item++)
XswMultiListUnhighlight(w, item);
}
}
/* ARGSUSED */
static void
Move(w, event, params, num_params)
Widget w;
XEvent * event;
String * params;
Cardinal *num_params;
{
int item;
MultiListWidget lw = (MultiListWidget) w;
if (!lw->multiList.single) {
if ( (CvtToItem(w, event->xbutton.x, event->xbutton.y, &item))
!= OUT_OF_RANGE) {
if (lw->multiList.toggle_state)
XswMultiListHighlight(w, item);
else
XswMultiListUnhighlight(w, item);
}
}
}
/*
* Set specified arguments into widget
*/
static void
Destroy(cl)
MultiListWidget cl;
{
XtReleaseGC((Widget) cl, cl->multiList.normgc);
XtReleaseGC((Widget) cl, cl->multiList.graygc);
XtReleaseGC((Widget) cl, cl->multiList.revgc);
XtFree(cl->multiList.state);
}
static Boolean
SetValues(current, request, new)
Widget current, request, new;
{
int i;
MultiListWidget cl = (MultiListWidget) current;
MultiListWidget rl = (MultiListWidget) request;
MultiListWidget nl = (MultiListWidget) new;
Boolean redraw = FALSE;
if ((cl->multiList.foreground != rl->multiList.foreground) ||
(cl->core.background_pixel != rl->core.background_pixel) ||
(cl->multiList.font != rl->multiList.font) ) {
XtReleaseGC((Widget) cl, cl->multiList.normgc);
XtReleaseGC((Widget) cl, cl->multiList.graygc);
XtReleaseGC((Widget) cl, cl->multiList.revgc);
GetGCs(new);
redraw = TRUE;
}
/* Reset row height. */
if ((cl->multiList.row_space != rl->multiList.row_space) ||
(cl->multiList.font != rl->multiList.font))
nl->multiList.row_height = nl->multiList.font->max_bounds.ascent
+ nl->multiList.font->max_bounds.descent
+ nl->multiList.row_space;
if ((cl->core.width != rl->core.width) ||
(cl->core.height != rl->core.height) ||
(cl->multiList.internal_width != rl->multiList.internal_width) ||
(cl->multiList.internal_height != rl->multiList.internal_height) ||
(cl->multiList.column_space != rl->multiList.column_space) ||
(cl->multiList.row_space != rl->multiList.row_space) ||
(cl->multiList.default_cols != rl->multiList.default_cols) ||
( (cl->multiList.force_cols != rl->multiList.force_cols) &&
(rl->multiList.force_cols != rl->multiList.ncols) ) ||
(cl->multiList.vertical_cols != rl->multiList.vertical_cols) ||
(cl->multiList.longest != rl->multiList.longest) ||
(cl->multiList.nitems != rl->multiList.nitems) ||
(cl->multiList.font != rl->multiList.font) ||
(cl->multiList.list != rl->multiList.list) ) {
ResetMultiList(new, TRUE, TRUE);
redraw = TRUE;
}
if (cl->multiList.list != rl->multiList.list)
for(i = 0; i < rl->multiList.nitems; i++)
cl->multiList.state[i] = False;
if ((cl->core.sensitive != rl->core.sensitive) ||
(cl->core.ancestor_sensitive != rl->core.ancestor_sensitive)) {
redraw = TRUE;
}
if (!XtIsRealized(current))
return(FALSE);
return(redraw);
}
/* Exported Functions */
/* Function Name: XswMultiListChange.
* Description: Changes the multiList being used and shown.
* Arguments: w - the multiList widget.
* multiList - the new multiList.
* nitems - the number of items in the multiList.
* longest - the length (in Pixels) of the longest element
* in the multiList.
* resize - if TRUE the the multiList widget will
* try to resize itself.
* Returns: none.
* NOTE: If nitems of longest are <= 0 then they will be calculated.
* If nitems is <= 0 then the multiList needs to be NULL terminated.
*/
void
XswMultiListChange(w, multiList, nitems, longest, resize_it)
Widget w;
char ** multiList;
int nitems, longest;
Boolean resize_it;
{
MultiListWidget lw = (MultiListWidget) w;
lw->multiList.list = multiList;
if (nitems <= 0) nitems = 0;
lw->multiList.nitems = nitems;
if (longest <= 0) longest = 0;
lw->multiList.longest = longest;
ResetMultiList(w, resize_it, resize_it);
if ( XtIsRealized(w) )
Redisplay(w, NULL, NULL);
}
/* Function Name: XswMultiListUnhighlight
* Description: unlights the current highlighted element.
* Arguments: w - the widget.
* Returns: none.
*/
void
XswMultiListUnhighlight(w, item)
Widget w;
int item;
{
MultiListWidget lw = ( MultiListWidget ) w;
if (lw->multiList.single) {
lw->multiList.highlight = NO_HIGHLIGHT;
if (lw->multiList.is_highlighted != NO_HIGHLIGHT)
PaintmyItemName(w, lw->multiList.is_highlighted);
} else {
if (lw->multiList.state[item]) {
lw->multiList.state[item] = False;
PaintmyItemName(w, item); /* unhighlight this one. */
}
}
}
/* Function Name: XswMultiListHighlight
* Description: Highlights the given item.
* Arguments: w - the multiList widget.
* item - the item to hightlight.
* Returns: none.
*/
void
XswMultiListHighlight(w, item)
Widget w;
int item;
{
MultiListWidget lw = ( MultiListWidget ) w;
if (XtIsSensitive(w)) {
if (lw->multiList.single) {
lw->multiList.highlight = item;
if (lw->multiList.is_highlighted != NO_HIGHLIGHT)
PaintmyItemName(w, lw->multiList.is_highlighted);
/* Unhighlight. */
PaintmyItemName(w, item); /* HIGHLIGHT this one. */
} else {
if (!lw->multiList.state[item]) {
lw->multiList.state[item] = True;
PaintmyItemName(w, item); /* HIGHLIGHT this one. */
}
}
}
}
/* Function Name: XswMultiListShowCurrent
* Description: returns the currently highlighted object.
* Arguments: w - the multiList widget.
* Returns: the info about the currently highlighted object.
*/
XswMultiListReturnStruct *
XswMultiListShowCurrent(w)
Widget w;
{
MultiListWidget lw = ( MultiListWidget ) w;
XswMultiListReturnStruct * ret_val;
int i, n;
ret_val =
(XswMultiListReturnStruct *)
XtMalloc((lw->multiList.nitems+1) *
sizeof(XswMultiListReturnStruct));
if (lw->multiList.single) {
ret_val->list_index = lw->multiList.highlight;
if (ret_val->list_index == XSW_LIST_NONE)
ret_val->string = "";
else
ret_val->string = lw->multiList.list[ ret_val->list_index ];
n = 1;
} else {
n = 0;
for(i = 0; i < lw->multiList.nitems; i++) {
if (lw->multiList.state[i]) {
ret_val[n].string = lw->multiList.list[i];
ret_val[n].list_index = i;
n++;
}
}
}
ret_val[n].string = "";
ret_val[n].list_index = XSW_LIST_NONE;
return(ret_val);
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.