1 #if ( !defined(lint) && !defined(SABER))
2 static char Xrcs_id[] = "$XConsortium: MList.c,v 1.29 90/05/08 15:16:32 converse Exp $";
6 * Copyright 1989 Massachusetts Institute of Technology
8 * Permission to use, copy, modify, distribute, and sell this software and its
9 * documentation for any purpose is hereby granted without fee, provided that
10 * the above copyright notice appear in all copies and that both that
11 * copyright notice and this permission notice appear in supporting
12 * documentation, and that the name of M.I.T. not be used in advertising or
13 * publicity pertaining to distribution of the software without specific,
14 * written prior permission. M.I.T. makes no representations about the
15 * suitability of this software for any purpose. It is provided "as is"
16 * without express or implied warranty.
18 * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
20 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
22 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
23 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
28 * MList.c - MList widget
30 * This is the MList widget, it is useful to display a list, without the
31 * overhead of having a widget for each item in the list. It allows
32 * the user to select an item in a list and notifies the application through
33 * a callback function.
36 * By: Chris D. Peterson
43 #include <X11/IntrinsicP.h>
44 #include <X11/StringDefs.h>
46 #include <X11/Xmu/Drawing.h>
48 #include <X11/Xaw/XawInit.h>
53 * Default Translation table.
56 static char defaultTranslations[] =
60 /****************************************************************
62 * Full class record constant
64 ****************************************************************/
68 #define offset(field) XtOffset(MListWidget, field)
70 static XtResource resources[] = {
71 {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
72 offset(list.foreground), XtRString, "XtDefaultForeground"},
73 {XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor),
74 offset(simple.cursor), XtRString, "left_ptr"},
75 {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
76 offset(list.font),XtRString, "XtDefaultFont"},
77 {XtNlist, XtCMList, XtRPointer, sizeof(char **),
78 offset(list.list), XtRString, NULL},
79 {XtNdefaultColumns, XtCColumns, XtRInt, sizeof(int),
80 offset(list.default_cols), XtRImmediate, (caddr_t)2},
81 {XtNlongest, XtCLongest, XtRInt, sizeof(int),
82 offset(list.longest), XtRImmediate, (caddr_t)0},
83 {XtNnumberStrings, XtCNumberStrings, XtRInt, sizeof(int),
84 offset(list.nitems), XtRImmediate, (caddr_t)0},
85 {XtNpasteBuffer, XtCBoolean, XtRBoolean, sizeof(Boolean),
86 offset(list.paste), XtRString, (caddr_t) "False"},
87 {XtNforceColumns, XtCColumns, XtRBoolean, sizeof(Boolean),
88 offset(list.force_cols), XtRString, (caddr_t) "False"},
89 {XtNverticalList, XtCBoolean, XtRBoolean, sizeof(Boolean),
90 offset(list.vertical_cols), XtRString, (caddr_t) "False"},
91 {XtNinternalWidth, XtCWidth, XtRDimension, sizeof(Dimension),
92 offset(list.internal_width), XtRImmediate, (caddr_t)4},
93 {XtNinternalHeight, XtCHeight, XtRDimension, sizeof(Dimension),
94 offset(list.internal_height), XtRImmediate, (caddr_t)2},
95 {XtNcolumnSpacing, XtCSpacing, XtRDimension, sizeof(Dimension),
96 offset(list.column_space), XtRImmediate, (caddr_t)6},
97 {XtNrowSpacing, XtCSpacing, XtRDimension, sizeof(Dimension),
98 offset(list.row_space), XtRImmediate, (caddr_t)2},
99 {XtNcallback, XtCCallback, XtRCallback, sizeof(caddr_t),
100 offset(list.callback), XtRCallback, NULL},
103 static void Initialize();
104 static void ChangeSize();
105 static void Resize();
106 static void Redisplay();
107 static Boolean Layout();
108 static XtGeometryResult PreferredGeom();
109 static Boolean SetValues();
110 static void Notify(), Set(), Unset();
112 static XtActionsRec actions[] = {
118 MListClassRec mlistClassRec = {
120 /* core_class fields */
121 #define superclass (&simpleClassRec)
122 /* superclass */ (WidgetClass) superclass,
123 /* class_name */ "MList",
124 /* widget_size */ sizeof(MListRec),
125 /* class_initialize */ XawInitializeWidgetSet,
126 /* class_part_initialize */ NULL,
127 /* class_inited */ FALSE,
128 /* initialize */ Initialize,
129 /* initialize_hook */ NULL,
130 /* realize */ XtInheritRealize,
131 /* actions */ actions,
132 /* num_actions */ XtNumber(actions),
133 /* resources */ resources,
134 /* num_resources */ XtNumber(resources),
135 /* xrm_class */ NULLQUARK,
136 /* compress_motion */ TRUE,
137 /* compress_exposure */ FALSE,
138 /* compress_enterleave */ TRUE,
139 /* visible_interest */ FALSE,
142 /* expose */ Redisplay,
143 /* set_values */ SetValues,
144 /* set_values_hook */ NULL,
145 /* set_values_almost */ XtInheritSetValuesAlmost,
146 /* get_values_hook */ NULL,
147 /* accept_focus */ NULL,
148 /* version */ XtVersion,
149 /* callback_private */ NULL,
150 /* tm_table */ defaultTranslations,
151 /* query_geometry */ PreferredGeom,
153 /* Simple class fields initialization */
155 /* change_sensitive */ XtInheritChangeSensitive
159 WidgetClass mlistWidgetClass = (WidgetClass)&mlistClassRec;
161 /****************************************************************
165 ****************************************************************/
167 static void GetGCs(w)
171 MListWidget lw = (MListWidget) w;
173 values.foreground = lw->list.foreground;
174 values.font = lw->list.font->fid;
175 lw->list.normgc = XtGetGC(w, (unsigned) GCForeground | GCFont,
178 values.foreground = lw->core.background_pixel;
179 lw->list.revgc = XtGetGC(w, (unsigned) GCForeground | GCFont,
182 values.tile = XmuCreateStippledPixmap(XtScreen(w),
184 lw->core.background_pixel,
186 values.fill_style = FillTiled;
188 lw->list.graygc = XtGetGC(w, (unsigned) GCFont | GCTile | GCFillStyle,
192 /* Function Name: ResetMList
193 * Description: Resets the new list when important things change.
194 * Arguments: w - the widget.
195 * changex, changey - allow the height or width to change?
200 ResetMList(w, changex, changey)
202 Boolean changex, changey;
204 MListWidget lw = (MListWidget) w;
205 Dimension width = w->core.width;
206 Dimension height = w->core.height;
210 * If list is NULL then the list will just be the name of the widget.
213 if (lw->list.list == NULL) {
214 lw->list.list = &(lw->core.name);
218 if (lw->list.nitems == 0) /* Get number of items. */
219 for ( ; lw->list.list[lw->list.nitems] != NULL ; lw->list.nitems++);
221 if (lw->list.longest == 0) /* Get column width. */
222 for ( i = 0 ; i < lw->list.nitems; i++) {
223 len = XTextWidth(lw->list.font, lw->list.list[i],
224 strlen(lw->list.list[i]));
225 if (len > lw->list.longest)
226 lw->list.longest = len;
229 lw->list.col_width = lw->list.longest + lw->list.column_space;
231 if (Layout(w, changex, changey, &width, &height))
232 ChangeSize(w, width, height);
235 /* Function Name: ChangeSize.
236 * Description: Laysout the widget.
237 * Arguments: w - the widget to try change the size of.
242 ChangeSize(w, width, height)
244 Dimension width, height;
246 XtWidgetGeometry request, reply;
248 request.request_mode = CWWidth | CWHeight;
249 request.width = width;
250 request.height = height;
252 switch ( XtMakeGeometryRequest(w, &request, &reply) ) {
256 case XtGeometryAlmost:
257 Layout(w, (request.height != reply.height),
258 (request.width != reply.width),
259 &(reply.width), &(reply.height));
261 switch (XtMakeGeometryRequest(w, &request, &reply) ) {
265 case XtGeometryAlmost:
267 if (Layout(w, FALSE, FALSE,
268 &(request.width), &(request.height))) {
270 sprintf(buf, "MList Widget: %s %s",
271 "Size Changed when it shouldn't have",
272 "when computing layout");
273 XtAppWarning(XtWidgetToApplicationContext(w), buf);
275 request.request_mode = CWWidth | CWHeight;
276 XtMakeGeometryRequest(w, &request, &reply);
279 XtAppWarning(XtWidgetToApplicationContext(w),
280 "MList Widget: Unknown geometry return.");
285 XtAppWarning(XtWidgetToApplicationContext(w),
286 "MList Widget: Unknown geometry return.");
291 /* Function Name: Initialize
292 * Description: Function that initilizes the widget instance.
293 * Arguments: junk - NOT USED.
294 * new - the new widget.
300 Initialize(junk, new)
303 MListWidget lw = (MListWidget) new;
306 * Initialize all private resources.
311 /* Set row height. */
312 lw->list.row_height = lw->list.font->max_bounds.ascent
313 + lw->list.font->max_bounds.descent
314 + lw->list.row_space;
316 ResetMList(new, (new->core.width == 0), (new->core.height == 0));
318 lw->list.highlight = NO_HIGHLIGHT;
319 lw->list.nhighlighted = 0;
320 lw->list.is_highlighted = (int *) malloc(0);
327 * Determine if the specified item is selected
337 for (i = 0; i < lw->list.nhighlighted; i++) {
338 if (lw->list.is_highlighted[i] == item)
345 /* Function Name: CvtToItem
346 * Description: Converts Xcoord to item number of item containing that
348 * Arguments: w - the list widget.
349 * xloc, yloc - x location, and y location.
350 * Returns: the item number.
354 CvtToItem(w, xloc, yloc, item)
360 MListWidget lw = (MListWidget) w;
363 if (lw->list.vertical_cols) {
364 one = lw->list.nrows * ((xloc - (int) lw->list.internal_width)
365 / lw->list.col_width);
366 another = (yloc - (int) lw->list.internal_height)
367 / lw->list.row_height;
368 /* If out of range, return minimum possible value. */
369 if (another >= lw->list.nrows) {
370 another = lw->list.nrows - 1;
371 ret_val = OUT_OF_RANGE;
375 one = (lw->list.ncols * ((yloc - (int) lw->list.internal_height)
376 / lw->list.row_height)) ;
377 /* If in right margin handle things right. */
378 another = (xloc - (int) lw->list.internal_width) / lw->list.col_width;
379 if (another >= lw->list.ncols) {
380 another = lw->list.ncols - 1;
381 ret_val = OUT_OF_RANGE;
384 if ((xloc < 0) || (yloc < 0))
385 ret_val = OUT_OF_RANGE;
386 if (one < 0) one = 0;
387 if (another < 0) another = 0;
388 *item = one + another;
389 if (*item >= lw->list.nitems) return(OUT_OF_RANGE);
393 /* Function Name: FindCornerItems.
394 * Description: Find the corners of the rectangle in item space.
395 * Arguments: w - the list widget.
396 * event - the event structure that has the rectangle it it.
397 * ul_ret, lr_ret - the corners ** RETURNED **.
401 static FindCornerItems(w, event, ul_ret, lr_ret)
404 int *ul_ret, *lr_ret;
408 xloc = event->xexpose.x;
409 yloc = event->xexpose.y;
410 CvtToItem(w, xloc, yloc, ul_ret);
411 xloc += event->xexpose.width;
412 yloc += event->xexpose.height;
413 CvtToItem(w, xloc, yloc, lr_ret);
416 /* Function Name: ItemInRectangle
417 * Description: returns TRUE if the item passed is in the given rectangle.
418 * Arguments: w - the list widget.
419 * ul, lr - corners of the rectangle in item space.
420 * item - item to check.
421 * Returns: TRUE if the item passed is in the given rectangle.
424 static ItemInRectangle(w, ul, lr, item)
428 MListWidget lw = (MListWidget) w;
429 register int mod_item;
432 if (item < ul || item > lr)
434 if (lw->list.vertical_cols)
435 things = lw->list.nrows;
437 things = lw->list.ncols;
439 mod_item = item % things;
440 if ( (mod_item >= ul % things) && (mod_item <= lr % things ) )
445 /* Function Name: HighlightBackground
446 * Description: paints the color of the background for the given item.
447 * Arguments: w - the widget.
448 * x, y - ul corner of the area item occupies.
449 * item - the item we are dealing with.
450 * gc - the gc that is used to paint this rectangle
454 static HighlightBackground(w, x, y, item, gc)
459 MListWidget lw = (MListWidget) w;
460 int hl_x, hl_y, width, height;
462 hl_x = x - lw->list.column_space/2;
463 width = XTextWidth(lw->list.font, lw->list.list[item],
464 strlen(lw->list.list[item])) + lw->list.column_space;
465 hl_y = y - lw->list.row_space/2;
466 height = lw->list.row_height + lw->list.row_space;
468 XFillRectangle(XtDisplay(w), XtWindow(w), gc, hl_x, hl_y, width, height);
471 /* Function Name: PaintItemName
472 * Description: paints the name of the item in the appropriate location.
473 * Arguments: w - the list widget.
474 * item - the item to draw.
477 * NOTE: no action taken on an unrealized widget.
480 static PaintItemName(w, item)
487 MListWidget lw = (MListWidget) w;
489 if (!XtIsRealized(w)) return; /* Just in case... */
491 if (lw->list.vertical_cols) {
492 x = lw->list.col_width * (item / lw->list.nrows)
493 + lw->list.internal_width;
494 y = lw->list.row_height * (item % lw->list.nrows)
495 + lw->list.internal_height;
498 x = lw->list.col_width * (item % lw->list.ncols)
499 + lw->list.internal_width;
500 y = lw->list.row_height * (item / lw->list.ncols)
501 + lw->list.internal_height;
504 str_y = y + lw->list.font->max_bounds.ascent;
506 if (IsHighlit(lw, item)) {
508 HighlightBackground(w, x, y, item, lw->list.normgc);
511 if (XtIsSensitive(w))
512 gc = lw->list.normgc;
514 gc = lw->list.graygc;
515 HighlightBackground(w, x, y, item, lw->list.revgc);
518 str = lw->list.list[item]; /* draw it */
519 XDrawString(XtDisplay(w), XtWindow(w), gc, x, str_y, str, strlen(str));
522 /* Function Name: Redisplay
523 * Description: Repaints the widget window on expose events.
524 * Arguments: w - the list widget.
525 * event - the expose event for this repaint.
532 Redisplay(w, event, junk)
537 int item; /* an item to work with. */
538 int ul_item, lr_item; /* corners of items we need to paint. */
539 MListWidget lw = (MListWidget) w;
541 if (event == NULL) { /* repaint all. */
543 lr_item = lw->list.nrows * lw->list.ncols - 1;
544 XClearWindow(XtDisplay(w), XtWindow(w));
547 FindCornerItems(w, event, &ul_item, &lr_item);
549 for (item = ul_item; (item <= lr_item && item < lw->list.nitems) ; item++)
550 if (ItemInRectangle(w, ul_item, lr_item, item))
551 PaintItemName(w, item);
554 /* Function Name: PreferredGeom
555 * Description: This tells the parent what size we would like to be
556 * given certain constraints.
557 * Arguments: w - the widget.
558 * intended - what the parent intends to do with us.
559 * requested - what we want to happen.
563 static XtGeometryResult
564 PreferredGeom(w, intended, requested)
566 XtWidgetGeometry *intended, *requested;
568 Dimension new_width, new_height;
569 Boolean change, width_req, height_req;
571 width_req = intended->request_mode & CWWidth;
572 height_req = intended->request_mode & CWHeight;
575 new_width = intended->width;
577 new_width = w->core.width;
580 new_height = intended->height;
582 new_height = w->core.height;
584 requested->request_mode = 0;
587 * We only care about our height and width.
590 if ( !width_req && !height_req)
591 return(XtGeometryYes);
593 change = Layout(w, !width_req, !height_req, &new_width, &new_height);
595 requested->request_mode |= CWWidth;
596 requested->width = new_width;
597 requested->request_mode |= CWHeight;
598 requested->height = new_height;
601 return(XtGeometryAlmost);
602 return(XtGeometryYes);
605 /* Function Name: Resize
606 * Description: resizes the widget, by changing the number of rows and
608 * Arguments: w - the widget.
616 Dimension width, height;
618 width = w->core.width;
619 height = w->core.height;
621 if (Layout(w, FALSE, FALSE, &width, &height))
622 XtAppWarning(XtWidgetToApplicationContext(w),
623 "MList Widget: Size changed when it shouldn't have when resising.");
626 /* Function Name: Layout
627 * Description: lays out the item in the list.
628 * Arguments: w - the widget.
629 * xfree, yfree - TRUE if we are free to resize the widget in
631 * width, height - the is the current width and height that
632 * we are going to layout the list widget to,
633 * depending on xfree and yfree of course.
635 * Returns: TRUE if width or height have been changed.
639 Layout(w, xfree, yfree, width, height)
641 Boolean xfree, yfree;
642 Dimension *width, *height;
644 MListWidget lw = (MListWidget) w;
645 Boolean change = FALSE;
648 * If force columns is set then always use number of columns specified
652 if (lw->list.force_cols) {
653 lw->list.ncols = lw->list.default_cols;
654 if (lw->list.ncols <= 0) lw->list.ncols = 1;
655 /* 12/3 = 4 and 10/3 = 4, but 9/3 = 3 */
656 lw->list.nrows = ( ( lw->list.nitems - 1) / lw->list.ncols) + 1 ;
657 if (xfree) { /* If allowed resize width. */
658 *width = lw->list.ncols * lw->list.col_width
659 + 2 * lw->list.internal_width;
662 if (yfree) { /* If allowed resize height. */
663 *height = (lw->list.nrows * lw->list.row_height)
664 + 2 * lw->list.internal_height;
671 * If both width and height are free to change the use default_cols
672 * to determine the number columns and set new width and height to
673 * just fit the window.
676 if (xfree && yfree) {
677 lw->list.ncols = lw->list.default_cols;
678 if (lw->list.ncols <= 0) lw->list.ncols = 1;
679 lw->list.nrows = ( ( lw->list.nitems - 1) / lw->list.ncols) + 1 ;
680 *width = lw->list.ncols * lw->list.col_width
681 + 2 * lw->list.internal_width;
682 *height = (lw->list.nrows * lw->list.row_height)
683 + 2 * lw->list.internal_height;
687 * If the width is fixed then use it to determine the number of columns.
688 * If the height is free to move (width still fixed) then resize the height
689 * of the widget to fit the current list exactly.
692 lw->list.ncols = ( (*width - 2 * lw->list.internal_width)
693 / lw->list.col_width);
694 if (lw->list.ncols <= 0) lw->list.ncols = 1;
695 lw->list.nrows = ( ( lw->list.nitems - 1) / lw->list.ncols) + 1 ;
697 *height = (lw->list.nrows * lw->list.row_height)
698 + 2 * lw->list.internal_height;
703 * The last case is xfree and !yfree we use the height to determine
704 * the number of rows and then set the width to just fit the resulting
707 else if (!yfree) { /* xfree must be TRUE. */
708 lw->list.nrows = (*height - 2 * lw->list.internal_height)
709 / lw->list.row_height;
710 if (lw->list.nrows <= 0) lw->list.nrows = 1;
711 lw->list.ncols = (( lw->list.nitems - 1 ) / lw->list.nrows) + 1;
712 *width = lw->list.ncols * lw->list.col_width
713 + 2 * lw->list.internal_width;
719 /* Function Name: Notify
720 * Description: Notifies the user that a button has been pressed, and
721 * calles the callback, if the XtNpasteBuffer resource
722 * is true then the name of the item is also put in the
723 * X cut buffer ( buf (0) ).
724 * Arguments: w - the widget that the notify occured in.
725 * event - event that caused this notification.
726 * params, num_params - not used.
732 Notify(w, event, params, num_params)
736 Cardinal *num_params;
738 MListWidget lw = ( MListWidget ) w;
740 XawMListReturnStruct ret_value;
743 * Find item and if out of range then unhighlight and return.
745 * If the current item is unhighlighted then the user has aborted the
746 * notify, so unhighlight and return.
749 if ( ((CvtToItem(w, event->xbutton.x, event->xbutton.y, &item))
750 == OUT_OF_RANGE) || (lw->list.highlight != item) ) {
751 XawMListUnhighlight(w, lw->list.highlight);
752 lw->list.highlight = NO_HIGHLIGHT;
755 lw->list.highlight = NO_HIGHLIGHT;
757 item_len = strlen(lw->list.list[item]);
759 if ( lw->list.paste ) /* if XtNpasteBuffer set then paste it. */
760 XStoreBytes(XtDisplay(w), lw->list.list[item], item_len);
763 * Call Callback function.
766 ret_value.string = lw->list.list[item];
767 ret_value.list_index = item;
769 XtCallCallbacks( w, XtNcallback, (caddr_t) &ret_value);
772 /* Function Name: Unset
773 * Description: unhighlights the current element.
774 * Arguments: w - the widget that the event occured in.
776 * params, num_params - not used.
782 Unset(w, event, params, num_params)
786 Cardinal *num_params;
788 MListWidget lw = (MListWidget) w;
790 XawMListUnhighlight(w, lw->list.highlight);
793 /* Function Name: Set
794 * Description: Highlights the current element.
795 * Arguments: w - the widget that the event occured in.
796 * event - event that caused this notification.
797 * params, num_params - not used.
803 Set(w, event, params, num_params)
807 Cardinal *num_params;
810 MListWidget lw = (MListWidget) w;
812 if ( (CvtToItem(w, event->xbutton.x, event->xbutton.y, &item))
816 if (IsHighlit(lw, item))
817 (void) XawMListUnhighlight(w, item);
819 (void) XawMListHighlight(w, item);
820 lw->list.highlight = item;
825 * Set specified arguments into widget
829 SetValues(current, request, new)
830 Widget current, request, new;
832 MListWidget cl = (MListWidget) current;
833 MListWidget rl = (MListWidget) request;
834 MListWidget nl = (MListWidget) new;
835 Boolean redraw = FALSE;
837 if ((cl->list.foreground != rl->list.foreground) ||
838 (cl->core.background_pixel != rl->core.background_pixel) ||
839 (cl->list.font != rl->list.font) ) {
840 XtDestroyGC(cl->list.normgc);
841 XtDestroyGC(cl->list.graygc);
842 XtDestroyGC(cl->list.revgc);
847 /* Reset row height. */
849 if ((cl->list.row_space != rl->list.row_space) ||
850 (cl->list.font != rl->list.font))
851 nl->list.row_height = nl->list.font->max_bounds.ascent
852 + nl->list.font->max_bounds.descent
853 + nl->list.row_space;
855 if ((cl->core.width != rl->core.width) ||
856 (cl->core.height != rl->core.height) ||
857 (cl->list.internal_width != rl->list.internal_width) ||
858 (cl->list.internal_height != rl->list.internal_height) ||
859 (cl->list.column_space != rl->list.column_space) ||
860 (cl->list.row_space != rl->list.row_space) ||
861 (cl->list.default_cols != rl->list.default_cols) ||
862 ( (cl->list.force_cols != rl->list.force_cols) &&
863 (rl->list.force_cols != rl->list.ncols) ) ||
864 (cl->list.vertical_cols != rl->list.vertical_cols) ||
865 (cl->list.longest != rl->list.longest) ||
866 (cl->list.nitems != rl->list.nitems) ||
867 (cl->list.font != rl->list.font) ||
868 (cl->list.list != rl->list.list) ) {
870 ResetMList(new, TRUE, TRUE);
874 if (cl->list.list != rl->list.list)
875 nl->list.highlight = NO_HIGHLIGHT;
877 if ((cl->core.sensitive != rl->core.sensitive) ||
878 (cl->core.ancestor_sensitive != rl->core.ancestor_sensitive)) {
879 nl->list.highlight = NO_HIGHLIGHT;
883 if (!XtIsRealized(current))
889 /* Exported Functions */
891 /* Function Name: XawMListChange.
892 * Description: Changes the list being used and shown.
893 * Arguments: w - the list widget.
894 * list - the new list.
895 * nitems - the number of items in the list.
896 * longest - the length (in Pixels) of the longest element
898 * resize - if TRUE the the list widget will
899 * try to resize itself.
901 * NOTE: If nitems of longest are <= 0 then they will be calculated.
902 * If nitems is <= 0 then the list needs to be NULL terminated.
906 #if NeedFunctionPrototypes
907 XawMListChange(Widget w, char ** list, int nitems, int longest,
908 #if NeedWidePrototypes
914 XawMListChange(w, list, nitems, longest, resize_it)
921 MListWidget lw = (MListWidget) w;
923 lw->list.list = list;
925 if (nitems <= 0) nitems = 0;
926 lw->list.nitems = nitems;
927 if (longest <= 0) longest = 0;
928 lw->list.longest = longest;
930 ResetMList(w, resize_it, resize_it);
931 /* lw->list.is_highlighted = */
932 lw->list.highlight = NO_HIGHLIGHT;
933 if ( XtIsRealized(w) )
934 Redisplay(w, NULL, NULL);
937 /* Function Name: XawMListUnhighlight
938 * Description: unlights the current highlighted element.
939 * Arguments: w - the widget, item - the element to unhighlight
944 #if NeedFunctionPrototypes
945 XawMListUnhighlight(Widget w, int item)
947 XawMListUnhighlight(w, item)
953 MListWidget lw = (MListWidget) w;
955 if (IsHighlit(w, item)) {
956 for (i = 0; i < lw->list.nhighlighted; i++)
957 if (lw->list.is_highlighted[i] == item) break;
958 lw->list.nhighlighted--;
959 lw->list.is_highlighted[i] =
960 lw->list.is_highlighted[lw->list.nhighlighted];
961 lw->list.is_highlighted = (int *)
962 realloc((char *)lw->list.is_highlighted,
963 sizeof(int) * lw->list.nhighlighted);
964 PaintItemName(w, item); /* unhighlight this one. */
968 /* Function Name: XawMListHighlight
969 * Description: Highlights the given item.
970 * Arguments: w - the list widget.
971 * item - the item to hightlight.
976 #if NeedFunctionPrototypes
977 XawMListHighlight(Widget w, int item)
979 XawMListHighlight(w, item)
984 MListWidget lw = ( MListWidget ) w;
986 if (XtIsSensitive(w)) {
987 if (!IsHighlit(lw, item)) {
988 lw->list.is_highlighted = (int *)
989 realloc((char *)lw->list.is_highlighted,
990 sizeof(int) * (lw->list.nhighlighted + 1));
991 lw->list.is_highlighted[lw->list.nhighlighted] = item;
992 lw->list.nhighlighted++;
994 PaintItemName(w, item); /* HIGHLIGHT this one. */
998 /* Function Name: XawMListShowCurrent
999 * Description: returns the currently highlighted object.
1000 * Arguments: w - the list widget.
1001 * Returns: the info about the currently highlighted object.
1004 XawMListReturnStruct *
1005 #if NeedFunctionPrototypes
1006 XawMListShowCurrent(Widget w, int *numselected)
1008 XawMListShowCurrent(w, numselected)
1013 MListWidget lw = ( MListWidget ) w;
1014 XawMListReturnStruct * ret_val;
1017 *numselected = lw->list.nhighlighted;
1018 ret_val = (XawMListReturnStruct *)
1019 XtMalloc (sizeof(XawMListReturnStruct) * lw->list.nhighlighted);
1021 for (i = 0; i < lw->list.nhighlighted; i++) {
1022 ret_val[i].list_index = lw->list.is_highlighted[i];
1023 ret_val[i].string = lw->list.list[ ret_val->list_index ];