home *** CD-ROM | disk | FTP | other *** search
- /*
- * ComboBox.c, Interleaf, 16aug93 2:37pm Version 1.1.
- */
-
- /***********************************************************
- Copyright 1993 Interleaf, Inc.
-
- Permission to use, copy, modify, and distribute this software
- and its documentation for any purpose without fee is granted,
- provided that the above copyright notice appear in all copies
- and that both copyright notice and this permission notice appear
- in supporting documentation, and that the name of Interleaf not
- be used in advertising or publicly pertaining to distribution of
- the software without specific written prior permission.
-
- Interleaf makes no representation about the suitability of this
- software for any purpose. It is provided "AS IS" without any
- express or implied warranty.
- ******************************************************************/
-
- /*
- * (C) Copyright 1991,1992, 1993
- * Interleaf, Inc.
- * 9 Hillside Avenue,
- * Waltham, MA 02154
- *
- * ComboBox.c (DtComboBoxWidget):
- *
- * I wanted a margin around the widget (outside the shadow, like buttons),
- * so that the combo-box could be made the same size as a
- * push-button, etc. The bulletin-board widget always puts the shadow at
- * the outside edge of the widget, so combo-box is a sublcass of
- * manager, and we do everything ourselves.
- *
- * One must be carefull when using Dimension (for core width and height).
- * Dimension is an unsigned short. This causes problems when subtracting
- * and ending up with what should be a negative number (but it doesn't).
- * All child widget positioning is done by the combo_box. We don't
- * use any heavy-weight forms, etc. to help us out.
- *
- * There is no padding when editable. If using a label given it a
- * small margin, so it doesn't run up against the side of our
- * shadow or the arrow.
- *
- * Make some of the ComboBox functions common, so they can be shared
- * with SpinButton.
- *
- * The label-string resource got out of control. Its role kept getting
- * expanded; now the whole thing is a mess. Currently it shadows the
- * label's label-string. If the user sets it explicitly it will
- * take affect for as long as update-label is false. If update-label
- * is true, it will take affect until the end-user makes a selection
- * off the list.
- *
- * Known bugs:
- * Changing margin_width or margin_height resources when the
- * combo_box has focus will probably result in display glitches.
- *
- */
- #include "ComboBoxP.h"
- #include <Xm/VendorSP.h>
- #include <Xm/DrawP.h>
- #include <Xm/MenuUtilP.h>
-
- #include <Xm/DisplayP.h>
- #define DisplayUserGrabbed(w) \
- ((XmDisplayRec*) XmGetXmDisplay(XtDisplay(w)))->display.userGrabbed
-
- static void ClassInitialize (void);
- static void Initialize (DtComboBoxWidget request,
- DtComboBoxWidget new, ArgList given_args,
- Cardinal *num_args);
- static XmNavigability WidgetNavigable (DtComboBoxWidget combo);
- static void _ComboBoxFocusIn (DtComboBoxWidget combo, XEvent *event,
- char **params, Cardinal *num_params);
- static void _ComboBoxFocusOut (DtComboBoxWidget combo, XEvent *event,
- char **params, Cardinal *num_params);
- static void DrawHighlight (DtComboBoxWidget combo, Boolean clear);
- static void _ComboBoxActivate (Widget w, XEvent *event, char **params,
- Cardinal *num_params);
- static void _ComboBoxKbdCancel (Widget w, XEvent *event, char **params,
- Cardinal *num_params);
- static void CheckResources (DtComboBoxWidget combo);
- static void Destroy (DtComboBoxWidget combo);
- static void Resize (DtComboBoxWidget combo);
- static void Redisplay (DtComboBoxWidget w, XEvent *event,
- Region region);
- static XtGeometryResult GeometryManager (Widget w,
- XtWidgetGeometry *request,
- XtWidgetGeometry *reply);
- static void SetComboBoxSize (DtComboBoxWidget combo);
- static void ForceChildSizes (DtComboBoxWidget combo);
- static void LayoutChildren (DtComboBoxWidget combo);
- static Boolean SetValues (DtComboBoxWidget current,
- DtComboBoxWidget request, DtComboBoxWidget new);
- static void ClearShadow (DtComboBoxWidget w, Boolean all);
- static void DrawShadow (DtComboBoxWidget w);
- static char* GetTextString (XmString xm_string);
- static void SetTextFieldData (DtComboBoxPart *combo_p, XmString item);
- static void SetMaximumLabelSize (DtComboBoxPart *combo_p);
- static void SetLabelData (DtComboBoxPart *combo_p, XmString item,
- Boolean force_label_string);
- static void select_cb (Widget w, XtPointer client_data,
- XtPointer call_data);
- static void shell_event_handler (Widget widget, XtPointer client_data,
- XEvent* event, Boolean *dispatch);
- static void list_event_handler (Widget widget, XtPointer client_data,
- XEvent* event, Boolean *dispatch);
- static void TextFieldActivate (DtComboBoxPart *combo_p);
- static void activate_cb (Widget w, XtPointer client_data,
- XtPointer call_data);
- static void arrow_expose_cb (Widget w, XtPointer client_data,
- XtPointer call_data);
- static void text_losing_focus_cb (Widget w, XtPointer client_data,
- XtPointer call_data);
- static void text_activate_cb (Widget w, XtPointer client_data,
- XtPointer call_data);
- static void text_focus_cb (Widget w, XtPointer client_data,
- XtPointer call_data);
- static void SyncWithList (DtComboBoxPart *combo_p);
- static XmImportOperator _XmSetSyntheticResForChild (Widget widget,
- int offset,
- XtArgVal * value);
-
- static XmString InitLabel = NULL;
- extern void DtComboBoxSelectItemMoveup(DtComboBoxWidget combo, XmString item);
-
- /*
- * DtComboBoxWidget specific defines.
- */
- #define COMBO_SHADOW(w) w->manager.shadow_thickness
- #define COMBO_MARGIN_W(w) w->combo_box.margin_width
- #define COMBO_MARGIN_H(w) w->combo_box.margin_height
- #define COMBO_H_SPACING(w) w->combo_box.horizontal_spacing
- #define COMBO_V_SPACING(w) w->combo_box.vertical_spacing
- #define LIST_EVENTS (ButtonPressMask | ButtonReleaseMask | \
- FocusChangeMask | EnterWindowMask | \
- LeaveWindowMask)
- #define SHELL_EVENTS ButtonPressMask
- #define INVALID_DIMENSION (0xFFFF)
- #define MAXINT 2147483647 /* Taken from TextF.c */
-
-
- static char ComboBoxTranslationTable[] = "\
- <FocusIn>: ComboBoxFocusIn() \n\
- <FocusOut>: ComboBoxFocusOut() \n\
- <Key>osfDown: ComboBoxActivate() \n\
- <Btn1Down>,<Btn1Up>: ComboBoxActivate() \n\
- <Key>osfSelect: ComboBoxActivate() \n\
- ~s ~m ~a <Key>space: ComboBoxActivate() \n\
- ";
-
- static char ComboBoxLabelTranslationTable[] = "\
- <Key>osfDown: ComboBoxActivate(label) \n\
- <Btn1Down>,<Btn1Up>: ComboBoxActivate(label) \n\
- <Key>osfSelect: ComboBoxActivate(label) \n\
- ~s ~m ~a <Key>space: ComboBoxActivate(label) \n\
- ";
-
- static char ComboBoxListTranslationTable[] = "\
- <Key>osfCancel: ListKbdCancel() ComboBoxKbdCancel() \n\
- ";
-
- static XtActionsRec ComboBoxActionTable[] = {
- {"ComboBoxFocusIn", (XtActionProc)_ComboBoxFocusIn},
- {"ComboBoxFocusOut", (XtActionProc)_ComboBoxFocusOut},
- {"ComboBoxActivate", (XtActionProc)_ComboBoxActivate},
- {"ComboBoxKbdCancel", (XtActionProc)_ComboBoxKbdCancel},
- };
-
-
- /*
- * DtComboBoxWidget resources
- */
- #define offset(field) XtOffset(DtComboBoxWidget, field)
- static XtResource resources[] = {
- {XmNshadowThickness, XmCShadowThickness, XmRHorizontalDimension,
- sizeof(Dimension), offset(manager.shadow_thickness),
- XmRImmediate, (XtPointer)TEXT_FIELD_SHADOW},
-
- /*
- * ComboBox specific resources
- */
- {XmNactivateCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
- offset(combo_box.activate_callback), XmRCallback,
- (XtPointer)NULL},
- {XmNalignment, XmCAlignment, XmRAlignment, sizeof(unsigned char),
- offset(combo_box.alignment), XmRImmediate,
- (XtPointer)XmALIGNMENT_BEGINNING},
- {XmNarrowSpacing, XmCArrowSpacing, XmRHorizontalDimension,
- sizeof(Dimension), offset(combo_box.arrow_spacing),
- XmRImmediate, (XtPointer)0},
- {XmNarrowType, XmCArrowType, XmRArrowType, sizeof(unsigned char),
- offset(combo_box.arrow_type), XmRImmediate, (XtPointer)XmWINDOWS},
- {XmNcolumns, XmCColumns, XmRShort, sizeof(short),
- offset(combo_box.text_columns), XmRImmediate, (XtPointer)20},
- {XmNfocusCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
- offset(combo_box.focus_callback), XmRCallback,
- (XtPointer)NULL},
- {XmNhorizontalSpacing, XmCHorizontalSpacing, XmRHorizontalDimension,
- sizeof(Dimension), offset(combo_box.horizontal_spacing),
- XmRImmediate, (XtPointer)INVALID_DIMENSION},
- {XmNitemCount, XmCItemCount, XmRInt, sizeof(int),
- offset(combo_box.item_count), XmRImmediate, (XtPointer)0},
- /*
- * items is used only for seeing if the user changed the list. It
- * is only a pointer that reflects the current list's items.
- */
- {XmNitems, XmCItems, XmRXmStringTable, sizeof(XmStringTable),
- offset(combo_box.items), XmRImmediate, (XtPointer)NULL},
- {XmNlabelString, XmCXmString, XmRXmString, sizeof(XmString),
- offset(combo_box.label_string), XmRImmediate, (XtPointer)NULL},
- {XmNlist, XmCList, XmRWidget, sizeof(Widget),
- offset(combo_box.list), XmRImmediate, (XtPointer)NULL},
- {XmNlistFontList, XmCListFontList, XmRFontList, sizeof(XmFontList),
- offset(combo_box.list_font_list), XmRImmediate, (XtPointer)NULL},
- {XmNlistMarginHeight, XmCListMarginHeight, XmRVerticalDimension,
- sizeof(Dimension), offset(combo_box.list_margin_height),
- XmRImmediate, (XtPointer)MARGIN},
- {XmNlistMarginWidth, XmCListMarginWidth, XmRHorizontalDimension,
- sizeof(Dimension), offset(combo_box.list_margin_width),
- XmRImmediate, (XtPointer)MARGIN},
- {XmNlistSpacing, XmCListSpacing, XmRDimension,sizeof(Dimension),
- offset(combo_box.list_spacing), XmRImmediate, (XtPointer)0},
- {XmNlosingFocusCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
- offset(combo_box.losing_focus_callback), XmRCallback,
- (XtPointer)NULL},
- {XmNmarginHeight, XmCMarginHeight, XmRVerticalDimension,
- sizeof(Dimension), offset(combo_box.margin_height),
- XmRImmediate, (XtPointer)MARGIN},
- {XmNmarginWidth, XmCMarginWidth, XmRHorizontalDimension, sizeof(Dimension),
- offset(combo_box.margin_width), XmRImmediate, (XtPointer)MARGIN},
- {XmNmaxLength, XmCMaxLength, XmRInt, sizeof(unsigned int),
- offset(combo_box.text_max_length), XmRImmediate, (XtPointer)MAXINT},
- {XmNmenuPostCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
- offset(combo_box.menu_post_callback), XmRCallback, (XtPointer)NULL},
- {XmNorientation, XmCOrientation, XmROrientation, sizeof(unsigned char),
- offset(combo_box.orientation), XmRImmediate, (XtPointer)XmRIGHT},
- {XmNpoppedUp, XmCPoppedUp, XmRBoolean, sizeof(Boolean),
- offset(combo_box.popped_up), XmRImmediate, (XtPointer)FALSE},
- {XmNrecomputeSize, XmCRecomputeSize, XmRBoolean, sizeof(Boolean),
- offset(combo_box.recompute_size), XmRImmediate, (XtPointer)TRUE},
- {XmNselectedItem, XmCXmString, XmRXmString, sizeof(XmString),
- offset(combo_box.selected_item), XmRImmediate, (XtPointer)NULL},
- {XmNselectedPosition, XmCSelectedPosition, XmRInt, sizeof(unsigned int),
- offset(combo_box.selected_position), XmRImmediate, (XtPointer)0},
- {XmNselectionCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
- offset(combo_box.selection_callback), XmRCallback, (XtPointer)NULL},
- {XmNtextField, XmCTextField, XmRWidget, sizeof(Widget),
- offset(combo_box.text), XmRImmediate, (XtPointer)NULL},
- {XmNtopItemPosition, XmCTopItemPosition, XmRInt, sizeof(int),
- offset(combo_box.top_item_position), XmRImmediate, (XtPointer)1},
- {XmNtype, XmCType, XmRType, sizeof(unsigned char),
- offset(combo_box.type), XmRImmediate,
- (XtPointer)XmDROP_DOWN_LIST_BOX},
- {XmNupdateLabel, XmCUpdateLabel, XmRBoolean, sizeof(Boolean),
- offset(combo_box.update_label), XmRImmediate, (XtPointer)TRUE},
- {XmNvisibleItemCount, XmCVisibleItemCount, XmRInt, sizeof(int),
- offset(combo_box.visible_item_count), XmRImmediate, (XtPointer)10},
- {XmNverticalSpacing, XmCVerticalSpacing, XmRVerticalDimension,
- sizeof(Dimension), offset(combo_box.vertical_spacing),
- XmRImmediate, (XtPointer)INVALID_DIMENSION},
- {XmNmoveSelectedItemUp, XmCMoveSelectedItemUp, XmRBoolean, sizeof(Boolean),
- offset(combo_box.move_selecteditem_up), XmRImmediate, (XtPointer)FALSE},
- {XmNnoCallbackForArrow, XmCNoCallbackForArrow, XmRBoolean, sizeof(Boolean),
- offset(combo_box.no_callback_for_arrow), XmRImmediate, (XtPointer)FALSE}
- };
-
- /*
- * List resources (used for GetValues).
- */
- static XmSyntheticResource syn_resources[] = {
- {XmNarrowSize, sizeof(Dimension), offset(combo_box.arrow_size),
- _DtComboBoxGetArrowSize, _XmSetSyntheticResForChild},
- {XmNlabelString, sizeof(XmString), offset(combo_box.label_string),
- _DtComboBoxGetLabelString, _XmSetSyntheticResForChild},
- {XmNitemCount, sizeof(int), offset(combo_box.item_count),
- _DtComboBoxGetListItemCount, _XmSetSyntheticResForChild},
- {XmNitems, sizeof(XmStringTable), offset(combo_box.items),
- _DtComboBoxGetListItems, _XmSetSyntheticResForChild},
- {XmNlistFontList, sizeof(XmFontList), offset(combo_box.list_font_list),
- _DtComboBoxGetListFontList, _XmSetSyntheticResForChild},
- {XmNlistMarginHeight, sizeof(Dimension),
- offset(combo_box.list_margin_height),
- _DtComboBoxGetListMarginHeight, _XmSetSyntheticResForChild},
- {XmNlistMarginWidth, sizeof(Dimension),offset(combo_box.list_margin_width),
- _DtComboBoxGetListMarginWidth, _XmSetSyntheticResForChild},
- {XmNlistSpacing, sizeof(Dimension), offset(combo_box.list_spacing),
- _DtComboBoxGetListSpacing, _XmSetSyntheticResForChild},
- {XmNtopItemPosition, sizeof(int), offset(combo_box.top_item_position),
- _DtComboBoxGetListTopItemPosition, _XmSetSyntheticResForChild},
- {XmNvisibleItemCount, sizeof(int), offset(combo_box.visible_item_count),
- _DtComboBoxGetListVisibleItemCount, _XmSetSyntheticResForChild},
- };
- #undef offset
-
- /* Need Class Extension for widget navigation */
- static XmBaseClassExtRec baseClassExtRec = {
- NULL,
- NULLQUARK,
- XmBaseClassExtVersion,
- sizeof(XmBaseClassExtRec),
- (XtInitProc)NULL, /* InitializePrehook */
- (XtSetValuesFunc)NULL, /* SetValuesPrehook */
- (XtInitProc)NULL, /* InitializePosthook */
- (XtSetValuesFunc)NULL, /* SetValuesPosthook */
- NULL, /* secondaryObjectClass */
- (XtInitProc)NULL, /* secondaryCreate */
- (XmGetSecResDataFunc)NULL, /* getSecRes data */
- { 0 }, /* fastSubclass flags */
- (XtArgsProc)NULL, /* getValuesPrehook */
- (XtArgsProc)NULL, /* getValuesPosthook */
- (XtWidgetClassProc)NULL, /* classPartInitPrehook */
- (XtWidgetClassProc)NULL, /* classPartInitPosthook*/
- NULL, /* ext_resources */
- NULL, /* compiled_ext_resources*/
- 0, /* num_ext_resources */
- FALSE, /* use_sub_resources */
- (XmWidgetNavigableProc) WidgetNavigable, /* widgetNavigable */
- (XmFocusChangeProc)NULL, /* focusChange */
- (XmWrapperData)NULL /* wrapperData */
- };
-
- /*
- * Define Class Record.
- */
- DtComboBoxClassRec dtComboBoxClassRec =
- {
- { /* core_class fields */
- (WidgetClass)&(xmManagerClassRec), /* superclass */
- (String)"DtComboBox", /* class_name */
- (Cardinal)sizeof(DtComboBoxRec), /* widget_size */
- (XtProc)ClassInitialize, /* class_initialize */
- (XtWidgetClassProc)NULL, /* class_part_init */
- (XtEnum)FALSE, /* class_inited */
- (XtInitProc)Initialize, /* initialize */
- (XtArgsProc)NULL, /* initialize_hook */
- (XtRealizeProc)XtInheritRealize, /* realize */
- (XtActionList)ComboBoxActionTable, /* actions */
- (Cardinal)XtNumber(ComboBoxActionTable), /* num_actions */
- (XtResourceList)resources, /* resources */
- (Cardinal)XtNumber(resources), /* num_resources */
- (XrmClass)NULLQUARK, /* xrm_class */
- (Boolean)TRUE, /* compress_motion */
- (XtEnum)XtExposeCompressMaximal, /* compress_exposure */
- (Boolean)TRUE, /* compress_enterleave*/
- (Boolean)FALSE, /* visible_interest */
- (XtWidgetProc)Destroy, /* destroy */
- (XtWidgetProc)Resize, /* resize */
- (XtExposeProc)Redisplay, /* expose */
- (XtSetValuesFunc)SetValues, /* set_values */
- (XtArgsFunc)NULL, /* set values hook */
- (XtAlmostProc)XtInheritSetValuesAlmost, /* set values almost */
- (XtArgsProc)NULL, /* get values hook */
- (XtAcceptFocusProc)NULL, /* accept_focus */
- (XtVersionType)XtVersion, /* Version */
- (XtPointer)NULL, /* PRIVATE cb list */
- (String)XtInheritTranslations, /* tm_table */
- (XtGeometryHandler)XtInheritQueryGeometry, /* query_geom */
- (XtStringProc)XtInheritDisplayAccelerator, /* display_accelerator*/
- (XtPointer)&baseClassExtRec /* extension */
- },
- { /* composite_class fields */
- (XtGeometryHandler)GeometryManager, /* geometry_manager */
- (XtWidgetProc)XtInheritChangeManaged, /* change_managed */
- (XtWidgetProc)XtInheritInsertChild, /* insert_child */
- (XtWidgetProc)XtInheritDeleteChild, /* delete_child */
- (XtPointer)NULL /* extension */
- },
- { /* constraint_class fields */
- (XtResourceList)NULL, /* resources */
- (Cardinal)0, /* num_resources */
- (Cardinal)0, /* constraint_size */
- (XtInitProc)NULL, /* initialize */
- (XtWidgetProc)NULL, /* destroy */
- (XtSetValuesFunc)NULL, /* set_values */
- (XtPointer)NULL /* extension */
- },
- { /* manager class */
- (String)XtInheritTranslations, /* translations */
- (XmSyntheticResource*)syn_resources, /* syn resources */
- (int)XtNumber(syn_resources), /* num syn_resources */
- (XmSyntheticResource*)NULL, /* get_cont_resources */
- (int)0, /* num_get_cont_resources */
- (XmParentProcessProc)XmInheritParentProcess,/* parent_process */
- (XtPointer)NULL /* extension */
- },
- { /* combo_box_class fields */
- (Boolean)0,
- }
- };
-
- WidgetClass dtComboBoxWidgetClass = (WidgetClass)&dtComboBoxClassRec;
-
- /*
- * Must set up the record type for the class extensions to work.
- */
- static void
- ClassInitialize(void)
- {
- baseClassExtRec.record_type = XmQmotif;
- }
-
- /*
- * ComboBox initialization function. This builds the widgets inside
- * our widget, to get the correct layout. If the type resource
- * is XmDROP_DOWN_COMBO_BOX, we create a textField; if FALSE, we create a
- * label. If the user changes this resource later, we will create the
- * other widget (textField or Label). We don't want to carry backage from
- * both widgets if the user never changes the type resource.
- */
- static void
- Initialize(DtComboBoxWidget request,
- DtComboBoxWidget new,
- ArgList given_args,
- Cardinal *num_args)
- {
- int k;
- XtTranslations trans = XtParseTranslationTable(ComboBoxTranslationTable);
- XtTranslations list_trans =
- XtParseTranslationTable(ComboBoxListTranslationTable);
- DtComboBoxPart *combo_p = (DtComboBoxPart*)&(new->combo_box);
- Boolean force_label_string = FALSE;
- Arg args[15];
- int n;
-
- /* Overwrite the manager's focusIn and focusOut translations */
- XtOverrideTranslations((Widget)new, trans);
-
- if (InitLabel == NULL)
- InitLabel = XmStringCreateSimple("");
-
- /*
- * force_label_string usage if it is specified and items is not.
- * This will be the perminant label string only if update-label
- * is false, else it is only used until the user picks something
- * new off the list.
- */
- if (combo_p->label_string == NULL)
- combo_p->label_string = InitLabel;
- else if (!combo_p->items)
- force_label_string = TRUE;
-
-
- combo_p->text = (Widget)NULL;
- combo_p->label = (Widget)NULL;
- combo_p->sep = (Widget)NULL;
- combo_p->old_width = 0;
- combo_p->old_height = 0;
-
- CheckResources(new);
-
- /*
- * Create the text or label depending on the type resource.
- * When part of X-Designer, we create both at initialization to
- * avoid later crashes.
- */
- #ifndef XDESIGNER
- if (combo_p->type == XmDROP_DOWN_COMBO_BOX)
- #endif
- {
- n = 0;
- XtSetArg(args[n], XmNcolumns, combo_p->text_columns); n++;
- XtSetArg(args[n], XmNmaxLength, combo_p->text_max_length); n++;
- XtSetArg(args[n], XmNmarginWidth, 2); n++;
- XtSetArg(args[n], XmNmarginHeight, 2); n++;
- combo_p->text = XtCreateManagedWidget("Text",
- xmTextFieldWidgetClass,
- (Widget)new, args, n);
- XtAddCallback(combo_p->text, XmNlosingFocusCallback,
- text_losing_focus_cb, (XtPointer)new);
- XtAddCallback(combo_p->text, XmNactivateCallback,
- text_activate_cb, (XtPointer)new);
- XtAddCallback(combo_p->text, XmNfocusCallback,
- text_focus_cb, (XtPointer)new);
- if (combo_p->horizontal_spacing == INVALID_DIMENSION)
- combo_p->horizontal_spacing = 0;
- if (combo_p->vertical_spacing == INVALID_DIMENSION)
- combo_p->vertical_spacing = 0;
- }
- #ifndef XDESIGNER
- else
- #endif
- {
- XtTranslations label_trans =
- XtParseTranslationTable(ComboBoxLabelTranslationTable);
-
- COMBO_SHADOW(new) = LABEL_SHADOW;
- n = 0;
- XtSetArg(args[n], XmNalignment, combo_p->alignment); n++;
- XtSetArg(args[n], XmNrecomputeSize, FALSE); n++;
- XtSetArg(args[n], XmNlabelString, InitLabel); n++;
- XtSetArg(args[n], XmNmarginLeft, LABEL_PADDING); n++;
- XtSetArg(args[n], XmNmarginRight, LABEL_PADDING); n++;
- XtSetArg(args[n], XmNmarginWidth, 0); n++;
- XtSetArg(args[n], XmNmarginHeight, 0); n++;
- XtSetArg(args[n], XmNstringDirection,
- new->manager.string_direction); n++;
- combo_p->label = XtCreateManagedWidget("Label",
- xmLabelWidgetClass,
- (Widget)new, args, n);
- XtOverrideTranslations((Widget)combo_p->label, label_trans);
- if (combo_p->horizontal_spacing == INVALID_DIMENSION)
- combo_p->horizontal_spacing = 1;
- if (combo_p->vertical_spacing == INVALID_DIMENSION)
- combo_p->vertical_spacing = 2;
- }
-
- #ifdef XDESIGNER
- /* Unmanage the one we don't use */
- if (combo_p->type == XmDROP_DOWN_COMBO_BOX)
- XtUnmanageChild(combo_p->label);
- else
- XtUnmanageChild(combo_p->text);
- #endif
-
- /*
- * Create the separator used if non-editable combo-box.
- */
- #ifndef XDESIGNER
- if (combo_p->type == XmDROP_DOWN_LIST_BOX)
- #endif
- {
- n = 0;
- XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
- combo_p->sep = XtCreateManagedWidget("ComboBoxSeparator",
- xmSeparatorWidgetClass,
- (Widget)new, args, n);
- }
-
- /*
- * Create the ArrowWidget.
- */
- n = 0;
- XtSetArg(args[n], XmNtraversalOn, FALSE); n++;
- XtSetArg(args[n], XmNhighlightThickness, 0); n++;
- XtSetArg(args[n], XmNshadowThickness, 0); n++;
- if (combo_p->arrow_type == XmMOTIF) {
- XtSetArg(args[n], XmNarrowDirection, XmARROW_DOWN); n++;
- XtSetArg(args[n], XmNforeground, new->core.background_pixel); n++;
- combo_p->arrow = XtCreateManagedWidget("ComboBoxArrow",
- xmArrowButtonWidgetClass,
- (Widget)new, args, n);
- }
- else {
- combo_p->arrow = XtCreateManagedWidget("ComboBoxArrow",
- xmDrawnButtonWidgetClass,
- (Widget)new, args, n);
- XtAddCallback(combo_p->arrow, XmNexposeCallback, arrow_expose_cb,
- (XtPointer)new);
- }
- XtAddCallback(combo_p->arrow, XmNactivateCallback, activate_cb,
- (XtPointer)new);
-
- /*
- * Create the shell and associated list widgets.
- */
- n = 0;
- for ( k = 0; k < *num_args; k++ )
- {
- if ( (strcmp(given_args[k].name, XmNvisual) == 0 ) ||
- (strcmp(given_args[k].name, XmNcolormap) == 0 ) ||
- (strcmp(given_args[k].name, XmNdepth) == 0) )
- {
- args[n].name = given_args[k].name;
- args[n].value = given_args[k].value;
- n++;
- }
- }
-
- XtSetArg(args[n], XtNoverrideRedirect, TRUE); n++;
- XtSetArg(args[n], XtNallowShellResize, TRUE); n++;
- XtSetArg(args[n], XtNsaveUnder, TRUE); n++;
- combo_p->shell = XtCreatePopupShell("ComboBoxMenuShell",
- topLevelShellWidgetClass,
- (Widget)new, args, n);
-
- n = 0;
- combo_p->frame = XtCreateManagedWidget("ComboBoxRowColumn",
- xmFrameWidgetClass,
- combo_p->shell, args, n);
-
- n = 0;
- /* Store combo widget in list for later use */
- XtSetArg(args[n], XmNuserData, (XtPointer)new); n++;
- if (combo_p->list_font_list) {
- XtSetArg(args[n], XmNfontList, combo_p->list_font_list); n++;
- }
- XtSetArg(args[n], XmNitemCount, combo_p->item_count); n++;
- XtSetArg(args[n], XmNitems, combo_p->items); n++;
- XtSetArg(args[n], XmNlistMarginHeight, combo_p->list_margin_height); n++;
- XtSetArg(args[n], XmNlistMarginWidth, combo_p->list_margin_width); n++;
- XtSetArg(args[n], XmNlistSpacing, combo_p->list_spacing); n++;
- XtSetArg(args[n], XmNstringDirection, new->manager.string_direction); n++;
- XtSetArg(args[n], XmNtopItemPosition, combo_p->top_item_position); n++;
- XtSetArg(args[n], XmNvisibleItemCount, combo_p->visible_item_count); n++;
- XtSetArg(args[n], XmNlistSizePolicy, XmRESIZE_IF_POSSIBLE); n++;
- combo_p->list = XmCreateScrolledList(combo_p->frame, "List",
- args, n);
- XtOverrideTranslations((Widget)combo_p->list, list_trans);
-
- /* selected_item resource used before selected_position */
- if (combo_p->selected_item)
- DtComboBoxSelectItem((Widget)new, combo_p->selected_item);
- else
- XmListSelectPos(combo_p->list, combo_p->selected_position + 1, FALSE);
-
- SyncWithList(combo_p);
- XtManageChild(combo_p->list);
- XtRealizeWidget(combo_p->shell);
-
- combo_p->max_shell_width = combo_p->shell->core.width;
- combo_p->max_shell_height = combo_p->shell->core.height;
-
- XtAddCallback(combo_p->list, XmNdefaultActionCallback, select_cb, new);
- XtAddCallback(combo_p->list, XmNbrowseSelectionCallback, select_cb, new);
-
- /*
- * Set up event handlers needed for handling grab states.
- */
- XtInsertEventHandler(combo_p->list, LIST_EVENTS, TRUE,
- (XtEventHandler)list_event_handler,
- (XtPointer)new, XtListHead);
- XtInsertEventHandler(combo_p->shell, SHELL_EVENTS, TRUE,
- (XtEventHandler)shell_event_handler,
- (XtPointer)new, XtListHead);
-
- /*
- * Set initial value in text or label if items was specified
- * Copy given label-string.
- */
- if (combo_p->label_string)
- combo_p->label_string = XmStringCopy(combo_p->label_string);
- if (combo_p->type == XmDROP_DOWN_LIST_BOX) {
- SetMaximumLabelSize(combo_p);
- SetLabelData(combo_p, NULL, force_label_string);
- }
- else
- SetTextFieldData(combo_p, NULL);
-
- SetComboBoxSize(new);
- LayoutChildren(new);
- }
-
-
- /*
- * Allow the manager to gain focus if not editable. If editable (using
- * text-field), then let the toolkit give focus to the text-field.
- */
- static XmNavigability
- WidgetNavigable(DtComboBoxWidget combo)
- {
- XmNavigationType nav_type = ((XmManagerWidget)combo)->manager.navigation_type;
-
- if (combo->core.sensitive && combo->core.ancestor_sensitive &&
- ((XmManagerWidget)combo)->manager.traversal_on) {
- if ((nav_type == XmSTICKY_TAB_GROUP) ||
- (nav_type == XmEXCLUSIVE_TAB_GROUP) ||
- ((nav_type == XmTAB_GROUP) &&
- !_XmShellIsExclusive((Widget)combo))) {
- if (combo->combo_box.type == XmDROP_DOWN_COMBO_BOX)
- return(XmDESCENDANTS_TAB_NAVIGABLE);
- else
- return(XmTAB_NAVIGABLE);
- }
- return(XmDESCENDANTS_NAVIGABLE);
- }
- return(XmNOT_NAVIGABLE);
- }
-
- /*
- * The combo_box gets focus.
- */
- static void
- _ComboBoxFocusIn(DtComboBoxWidget combo,
- XEvent *event,
- String *params,
- Cardinal *num_params)
- {
- DrawHighlight(combo, FALSE);
- }
-
- /*
- * The combo_box loses focus. Only happens if not editable.
- */
- static void
- _ComboBoxFocusOut(DtComboBoxWidget combo,
- XEvent *event,
- String *params,
- Cardinal *num_params)
- {
- DrawHighlight(combo, TRUE);
- }
-
- /*
- * This function gets called whenever we draw or clear the shadow (to
- * redraw highlight during resize, etc), as well as during focus_in
- * and focus_out events.
- */
- static void
- DrawHighlight(DtComboBoxWidget combo,
- Boolean clear)
- {
- XRectangle rect[4] ;
-
- if (XtIsRealized(combo)) {
- if (clear) {
- rect[0].x = rect[1].x = rect[2].x = 0;
- rect[3].x = combo->combo_box.old_width - COMBO_MARGIN_W(combo);
- rect[0].y = rect[2].y = rect[3].y = 0 ;
- rect[1].y = combo->combo_box.old_height - COMBO_MARGIN_H(combo);
- rect[0].width = rect[1].width = combo->combo_box.old_width;
- rect[2].width = rect[3].width = COMBO_MARGIN_W(combo);
- rect[0].height = rect[1].height = COMBO_MARGIN_H(combo);
- rect[2].height = rect[3].height = combo->combo_box.old_height;
- XFillRectangles(XtDisplayOfObject((Widget)combo),
- XtWindowOfObject((Widget)combo),
- combo->manager.background_GC, rect, 4);
- }
- else if (XmGetFocusWidget((Widget)combo) == (Widget)combo) {
- rect[0].x = rect[1].x = rect[2].x = 0;
- rect[3].x = XtWidth(combo) - COMBO_MARGIN_W(combo);
- rect[0].y = rect[2].y = rect[3].y = 0 ;
- rect[1].y = XtHeight(combo) - COMBO_MARGIN_H(combo);
- rect[0].width = rect[1].width = XtWidth(combo);
- rect[2].width = rect[3].width = COMBO_MARGIN_W(combo);
- rect[0].height = rect[1].height = COMBO_MARGIN_H(combo);
- rect[2].height = rect[3].height = XtHeight(combo);
- XFillRectangles(XtDisplayOfObject((Widget)combo),
- XtWindowOfObject((Widget)combo),
- combo->manager.highlight_GC, rect, 4);
- }
- }
- }
-
- /*
- * osfSelect virtual key hit. Simulate hitting the arrow.
- */
- static void
- _ComboBoxActivate(Widget w,
- XEvent *event,
- String *params,
- Cardinal *num_params)
- {
- DtComboBoxWidget combo;
-
- if (*num_params == 0) /* no params means combo */
- combo = (DtComboBoxWidget)w;
- else /* params means label */
- combo = (DtComboBoxWidget)XtParent(w);
-
- activate_cb((Widget)combo->combo_box.arrow, (XtPointer)combo, NULL);
- }
-
- /*
- * osfCancel virtual key hit.
- */
- static void
- _ComboBoxKbdCancel(Widget w,
- XEvent *event,
- String *params,
- Cardinal *num_params)
- {
- DtComboBoxWidget combo;
- DtComboBoxPart *combo_p;
- XtPointer data;
- Arg args[1];
-
- /* Get combo-box off list data */
- XtSetArg(args[0], XmNuserData, &data);
- XtGetValues(w, args, 1);
-
- combo = (DtComboBoxWidget)data;
- combo_p = (DtComboBoxPart*)&(combo->combo_box);
-
- combo_p->popped_up = FALSE;
- XtPopdown(combo_p->shell);
- XtUngrabPointer(combo_p->shell, CurrentTime);
- XtUngrabKeyboard(combo_p->list, CurrentTime);
- /*
- * _XmRemoveGrab() was causing trouble on irix and linux. The navigator
- * stopped responding to clicks cause of it.
- *
- */
- #if 0
- _XmRemoveGrab(combo_p->shell);
- #else
- XtRemoveGrab(combo_p->shell);
-
- DisplayUserGrabbed(w) = False;
- #endif
- if (combo_p->type == XmDROP_DOWN_COMBO_BOX)
- XmProcessTraversal(combo_p->text, XmTRAVERSE_CURRENT);
- }
-
- /*
- * This function goes through most of the resources and makes sure
- * they have legal values.
- */
- static void
- CheckResources(DtComboBoxWidget combo)
- {
- DtComboBoxPart *combo_p = (DtComboBoxPart*)&(combo->combo_box);
-
- if ((combo_p->alignment != XmALIGNMENT_CENTER) &&
- (combo_p->alignment != XmALIGNMENT_BEGINNING) &&
- (combo_p->alignment != XmALIGNMENT_END)) {
- XtWarning(COMBO_ALIGNMENT);
- combo_p->alignment = XmALIGNMENT_CENTER;
- }
- if (combo_p->margin_height < 0.0) {
- XtWarning(COMBO_MARGIN_HEIGHT);
- combo_p->margin_height = 2;
- }
- if (combo_p->margin_width < 0.0) {
- XtWarning(COMBO_MARGIN_WIDTH);
- combo_p->margin_width = 2;
- }
- if (combo_p->horizontal_spacing < 0.0) {
- XtWarning(COMBO_HORIZONTAL_SPACING);
- combo_p->horizontal_spacing = 0;
- }
- if (combo_p->vertical_spacing < 0.0) {
- XtWarning(COMBO_VERTICAL_SPACING);
- combo_p->vertical_spacing = 0;
- }
- if ((combo_p->orientation != XmLEFT) &&
- (combo_p->orientation != XmRIGHT)) {
- XtWarning(COMBO_ORIENTATION);
- combo_p->orientation = XmRIGHT;
- }
- if (combo_p->item_count < 0) {
- XtWarning(COMBO_ITEM_COUNT);
- combo_p->item_count = 0;
- }
- if ((combo_p->selected_position < 0) ||
- ((combo_p->selected_position >= combo_p->item_count) &&
- (combo_p->item_count > 0))) {
- XtWarning(COMBO_VISIBLE_ITEM);
- combo_p->selected_position = 0;
- }
- }
-
- /*
- * Destroy procedure called by the toolkit. Remove all callbacks and
- * event-handlers.
- */
- static void
- Destroy(DtComboBoxWidget combo)
- {
- DtComboBoxPart *combo_p = (DtComboBoxPart*)&(combo->combo_box);
-
- if (combo_p->label_string)
- XmStringFree(combo_p->label_string);
-
- DisplayUserGrabbed(combo) = False;
-
- #if whydotheydothis
- if (combo_p->text) {
- XtRemoveCallback(combo_p->text, XmNlosingFocusCallback,
- text_losing_focus_cb, (XtPointer)combo);
- XtRemoveCallback(combo_p->text, XmNactivateCallback,
- text_activate_cb, (XtPointer)combo);
- XtRemoveCallback(combo_p->text, XmNfocusCallback,
- text_focus_cb, (XtPointer)combo);
- }
-
- #if i_hope_it_has_been_ungrabbed_cuz_this_memory_has_already_been_freed
- if (((ShellWidget)(combo_p->shell))->shell.popped_up) {
- combo_p->popped_up = FALSE;
- XtPopdown(combo_p->shell);
- XtUngrabPointer(combo_p->shell, CurrentTime);
- XtUngrabKeyboard(combo_p->list, CurrentTime);
- _XmRemoveGrab(combo_p->shell);
- }
- #endif /* i_hope_it_has_been_ungrabbed_cuz_this_memory_has_already_been_freed */
-
- XtRemoveCallback(combo_p->arrow, XmNactivateCallback, activate_cb,
- (XtPointer)combo);
- if (combo_p->arrow_type == XmWINDOWS)
- XtRemoveCallback(combo_p->arrow, XmNexposeCallback,
- arrow_expose_cb, (XtPointer)combo);
- XtRemoveCallback(combo_p->list, XmNdefaultActionCallback,
- select_cb, combo);
- XtRemoveCallback(combo_p->list, XmNbrowseSelectionCallback,
- select_cb, combo);
-
- XtRemoveEventHandler(combo_p->list, LIST_EVENTS, TRUE,
- (XtEventHandler)list_event_handler,
- (XtPointer)combo);
-
- XtRemoveEventHandler(combo_p->shell, SHELL_EVENTS, TRUE,
- (XtEventHandler)shell_event_handler,
- (XtPointer)combo);
- #endif /* whydotheydothis */
- }
-
-
- /*
- * Resize function called by toolkit. The size of our combo-box
- * has already been changed. That is why we must store
- * old_width and old_height.
- */
- static void
- Resize(DtComboBoxWidget combo)
- {
- DtComboBoxPart *combo_p = (DtComboBoxPart*)&(combo->combo_box);
-
- ClearShadow(combo, TRUE);
- LayoutChildren(combo);
- DrawShadow(combo);
- combo_p->old_width = combo->core.width;
- combo_p->old_height = combo->core.height;
- }
-
-
- /*
- * Redisplay function called by toolkit. The widget didn't change size,
- * so just redisplay the shadow.
- */
- static void
- Redisplay(DtComboBoxWidget w,
- XEvent *event,
- Region region)
- {
- /* Wow.. These guys _released_ this shit. */
- #if 0
- DrawShadow(w, COMBO_MARGIN_W(w), COMBO_MARGIN_H(w), COMBO_SHADOW(w));
- #else
- DrawShadow(w);
- #endif
- }
-
-
- /*
- * GeometryManager function called by toolkit when a child resizes/moves.
- * We are not allowing any changes but width/height of the text-field.
- * this is because the user can retrieve the text-field and make changes
- * that we want to honor. If they mess around with the label or arrow,
- * then we won't honor the request.
- * If the text-field requests a change, then make the change, and allow
- * our SetComboBoxSize() and LayoutChildren() figure out what size will
- * be allowed.
- * Returning GeometryDone was suppose to tell the toolkit
- * that we resized the child ourselves, but the text-field had trouble
- * with this (its' geometry_manager wasn't called or working right?), so
- * we return GeometryYes.
- */
- static XtGeometryResult
- GeometryManager(Widget w,
- XtWidgetGeometry *request,
- XtWidgetGeometry *reply)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)(w->core.parent);
-
- /* Ignore everything but text-field */
- if (w != combo->combo_box.text)
- return(XtGeometryNo);
-
- /* Only allow width/height changes */
- if (!(request->request_mode & (CWWidth | CWHeight)))
- return(XtGeometryNo);
-
- /* Set the text-field to the requested size */
- if (request->request_mode & CWWidth)
- w->core.width = request->width;
- if (request->request_mode & CWHeight)
- w->core.height = request->height;
- XtResizeWidget(w, w->core.width, w->core.height, w->core.border_width);
-
- ClearShadow(combo, TRUE);
- if (combo->combo_box.recompute_size)
- SetComboBoxSize(combo);
- LayoutChildren(combo);
- DrawShadow(combo);
- return(XtGeometryYes);
- }
-
- /*
- * This function sets the size of the combo_box widget based on the
- * current size of the children. Don't worry if it doesn't work, the
- * children will be squeezed in later.
- */
- static void
- SetComboBoxSize(DtComboBoxWidget combo)
- {
- DtComboBoxPart *combo_p = (DtComboBoxPart*)&(combo->combo_box);
- Widget text_holder = ((combo_p->type == XmDROP_DOWN_COMBO_BOX) ?
- combo_p->text : combo_p->label);
- Dimension shadow = COMBO_SHADOW(combo) * 2;
- Dimension h_spacing = COMBO_H_SPACING(combo) * 2;
- Dimension v_spacing = COMBO_V_SPACING(combo) * 2;
- short arrow_width;
- short sep_width = 0;
-
- /*
- * Find out how big the arrow can be (needed to get
- * available_width for text_holder).
- */
- arrow_width = (Dimension)(text_holder->core.height * ARROW_MULT);
- arrow_width = (arrow_width < ARROW_MIN) ? ARROW_MIN : arrow_width;
-
- if (combo_p->type == XmDROP_DOWN_LIST_BOX)
- sep_width = combo_p->sep->core.width;
-
- (void)XtMakeResizeRequest((Widget)combo, arrow_width + sep_width +
- combo_p->arrow_spacing +
- text_holder->core.width + shadow + h_spacing +
- (COMBO_MARGIN_W(combo) * 2),
- text_holder->core.height + shadow + v_spacing +
- (COMBO_MARGIN_H(combo) * 2),
- NULL, NULL);
- combo_p->old_width = combo->core.width;
- combo_p->old_height = combo->core.height;
- }
-
- /*
- * This function makes the text_holder (label or text-field) smaller
- * if the combo_box couldn't grow to the needed full size. It will
- * also make the text_holder grow if there is space. The textfield will
- * grow with the combo_box, but the label will only grow to its'
- * maximum size. The label will also shrink down to nothing, but the
- * text-field will always keep its' core height.
- */
- static void
- ForceChildSizes(DtComboBoxWidget combo)
- {
- DtComboBoxPart *combo_p = (DtComboBoxPart*)&(combo->combo_box);
- Dimension full_available_height, available_height, available_width;
- Dimension arrow_width;
- Dimension sep_width = 0;
-
- /* Calculate available height for children */
- if ((available_height = combo->core.height - (COMBO_SHADOW(combo) * 2) -
- (COMBO_MARGIN_H(combo) * 2) - (COMBO_V_SPACING(combo) * 2)) <= 0) {
- full_available_height = available_height = 1;
- }
- else {
- /* Seperator need available_height plus the vertical_spacing */
- full_available_height = (available_height +
- (COMBO_V_SPACING(combo) * 2));
- }
-
- /* Get initial available width for children */
- available_width = (combo->core.width - (COMBO_SHADOW(combo) * 2) -
- (COMBO_MARGIN_W(combo) * 2) -
- (COMBO_H_SPACING(combo) * 2));
-
- /* label only grows to maximum width needed */
- if ((combo_p->type == XmDROP_DOWN_LIST_BOX) &&
- ((int)available_height > (int)combo_p->label_max_height))
- available_height = combo_p->label_max_height;
- else if (combo_p->type == XmDROP_DOWN_COMBO_BOX)
- available_height = combo_p->text->core.height;
-
- /*
- * Find out how big the arrow can be (needed to get
- * available_width for text_holder).
- */
- arrow_width = (Dimension)(available_height * ARROW_MULT);
- arrow_width = (arrow_width < ARROW_MIN) ? ARROW_MIN : arrow_width;
-
- if (combo_p->type == XmDROP_DOWN_LIST_BOX)
- sep_width = combo_p->sep->core.width;
-
- /* Make sure width isn't too small or too big */
- if ((int)(available_width -=
- (arrow_width + sep_width + combo_p->arrow_spacing)) <= 0)
- available_width = 1;
-
- if (combo_p->type == XmDROP_DOWN_LIST_BOX) { /** label **/
- if ((int)available_width > (int)combo_p->label_max_length)
- available_width = combo_p->label_max_length;
-
- if ((available_width != combo_p->label->core.width) ||
- (available_height != combo_p->label->core.height))
- XtResizeWidget(combo_p->label, available_width, available_height,
- combo_p->label->core.border_width);
-
- if (full_available_height != combo_p->sep->core.height)
- XtResizeWidget(combo_p->sep, combo_p->sep->core.width,
- full_available_height,
- combo_p->sep->core.border_width);
- }
- else if (combo_p->text->core.width != available_width) /** TextField **/
- XtResizeWidget(combo_p->text, available_width,
- combo_p->text->core.height,
- combo_p->text->core.border_width);
- if ((arrow_width != combo_p->arrow->core.width) ||
- (combo_p->arrow->core.height != available_height)) {
- available_height = (available_height < ARROW_MIN) ? ARROW_MIN :
- available_height;
- XtResizeWidget(combo_p->arrow, arrow_width, available_height,
- combo_p->arrow->core.border_width);
- }
- }
-
- /*
- * This function positions the children within the combo_box widget.
- * It calls ForceChildSizes() to make sure the children fit within the
- * combo_box widget, but it will not try to resize the combo_box widget.
- */
- static void
- LayoutChildren(DtComboBoxWidget combo)
- {
- DtComboBoxPart *combo_p = (DtComboBoxPart*)&(combo->combo_box);
- Widget text_holder = ((combo_p->type == XmDROP_DOWN_COMBO_BOX)
- ? combo_p->text : combo_p->label);
- Position start_x = (COMBO_SHADOW(combo) + COMBO_MARGIN_W(combo) +
- COMBO_H_SPACING(combo));
- Position start_y = (COMBO_SHADOW(combo) + COMBO_MARGIN_H(combo) +
- COMBO_V_SPACING(combo));
- short available_height = combo->core.height - (start_y * 2);
- Position y, arrow_y;
-
- ForceChildSizes(combo);
-
- /* Center text_holder within combo_box */
- y = available_height - text_holder->core.height;
- y = ((y < 0) ? 0 : y)/2 + start_y;
-
- /* Center arrow within combo_box */
- arrow_y = available_height - combo_p->arrow->core.height;
- arrow_y = ((arrow_y < 0) ? 0 : arrow_y)/2 + start_y;
-
- if (combo_p->orientation == XmLEFT) {
- XtMoveWidget(combo_p->arrow, start_x, arrow_y);
- start_x += combo_p->arrow->core.width;
- if (combo_p->type == XmDROP_DOWN_LIST_BOX) {
- XtMoveWidget(combo_p->sep, start_x, start_y -
- COMBO_V_SPACING(combo));
- start_x += combo_p->sep->core.width;
- }
- start_x += combo_p->arrow_spacing;
- XtMoveWidget(text_holder, start_x, y);
- }
- else {
- XtMoveWidget(text_holder, start_x, y);
- /*
- * We want the arrow at the end of the combo_box, so
- * the user can use recompute_size more effectively.
- */
- start_x = combo->core.width - start_x - combo_p->arrow->core.width;
- if (combo_p->type == XmDROP_DOWN_LIST_BOX) {
- start_x -= combo_p->sep->core.width;
- XtMoveWidget(combo_p->sep, start_x, start_y -
- COMBO_V_SPACING(combo));
- start_x += combo_p->sep->core.width;
- }
- XtMoveWidget(combo_p->arrow, start_x, arrow_y);
- }
- }
-
- /*
- * SetValues() routine for ComboBox widget.
- */
- static Boolean
- SetValues(DtComboBoxWidget current,
- DtComboBoxWidget request,
- DtComboBoxWidget new)
- {
- DtComboBoxPart *new_p = (DtComboBoxPart*)&(new->combo_box);
- DtComboBoxPart *cur_p = (DtComboBoxPart*)&(current->combo_box);
- Boolean label_size_changed = FALSE;
- Boolean force_label_string = FALSE;
- Arg args[10];
- int n;
-
- CheckResources(new);
-
- if (new_p->text != cur_p->text) {
- XtWarning(COMBO_TEXT);
- new_p->text = cur_p->text;
- }
-
- /*
- * Pass any list specific resources on to our List Widget.
- * Check each one, since it's too costly to always set them.
- */
- n = 0;
- if (new_p->item_count != cur_p->item_count){
- if (new_p->items && (new_p->item_count < 0)) {
- XtWarning(COMBO_ITEM_COUNT);
- new_p->item_count = 0;
- }
- XtSetArg(args[n], XmNitemCount, new_p->item_count); n++;
- }
- if (new_p->items != cur_p->items) {
- XtSetArg(args[n], XmNitems, new_p->items); n++;
- /* Make sure itemCount will get sent to list */
- if (new_p->item_count == cur_p->item_count) {
- XtSetArg(args[n], XmNitemCount, new_p->item_count); n++;
- }
- }
- if (new_p->list_font_list != cur_p->list_font_list) {
- XtSetArg(args[n], XmNfontList, new_p->list_font_list); n++;
- }
- if (new_p->list_margin_height != cur_p->list_margin_height) {
- XtSetArg(args[n], XmNlistMarginHeight, new_p->list_margin_height); n++;
- }
- if (new_p->list_margin_width != cur_p->list_margin_width) {
- XtSetArg(args[n], XmNlistMarginWidth, new_p->list_margin_width); n++;
- }
- if (new_p->list_spacing != cur_p->list_spacing) {
- XtSetArg(args[n], XmNlistSpacing, new_p->list_spacing); n++;
- }
- if (new->manager.string_direction != current->manager.string_direction) {
- XtSetArg(args[n], XmNstringDirection, new->manager.string_direction); n++;
- }
- if (new_p->top_item_position != cur_p->top_item_position) {
- XtSetArg(args[n], XmNtopItemPosition, new_p->top_item_position); n++;
- }
- if (new_p->visible_item_count != cur_p->visible_item_count) {
- XtSetArg(args[n], XmNvisibleItemCount, new_p->visible_item_count); n++;
- }
- if (n > 0) {
- XtSetValues(new_p->list, args, n);
- new_p->max_shell_width = new_p->shell->core.width;
- new_p->max_shell_height = new_p->shell->core.height;
- }
-
- /* If arrow type changes delete the old one and create the new one */
- if (new_p->arrow_type != cur_p->arrow_type) {
- XtRemoveCallback(new_p->arrow, XmNactivateCallback, activate_cb,
- (XtPointer)new);
- if (cur_p->arrow_type == XmWINDOWS)
- XtRemoveCallback(new_p->arrow, XmNexposeCallback,
- arrow_expose_cb, (XtPointer)new);
- XtDestroyWidget(new_p->arrow);
-
- n = 0;
- XtSetArg(args[n], XmNtraversalOn, FALSE); n++;
- XtSetArg(args[n], XmNhighlightThickness, 0); n++;
- XtSetArg(args[n], XmNshadowThickness, 0); n++;
- if (new_p->arrow_type == XmMOTIF) {
- XtSetArg(args[n], XmNarrowDirection, XmARROW_DOWN); n++;
- XtSetArg(args[n], XmNforeground, new->core.background_pixel); n++;
- new_p->arrow = XtCreateManagedWidget("ComboBoxArrow",
- xmArrowButtonWidgetClass,
- (Widget)new, args, n);
- }
- else {
- new_p->arrow = XtCreateManagedWidget("ComboBoxArrow",
- xmDrawnButtonWidgetClass,
- (Widget)new, args, n);
- XtAddCallback(new_p->arrow, XmNexposeCallback, arrow_expose_cb,
- (XtPointer)new);
- }
- XtAddCallback(new_p->arrow, XmNactivateCallback, activate_cb,
- (XtPointer)new);
- }
-
- /*
- * Type resource changed. If the widget (textField or Label)
- * doesn't exist, then create it. Always reset orientation
- * constraint resources when type changes; otherwise, the
- * text_holder widget positioning could be screwed up. We don't
- * reset both widgets if the orientation changes (because we might
- * not have created both widgets).
- * If label must be created, also create the separator widget.
- */
- if (new_p->type != cur_p->type) {
- if (new_p->type == XmDROP_DOWN_COMBO_BOX) {
- if (new_p->text == NULL) {
- n = 0;
- XtSetArg(args[n], XmNcolumns, new_p->text_columns); n++;
- XtSetArg(args[n], XmNmaxLength, new_p->text_max_length); n++;
- XtSetArg(args[n], XmNmarginWidth, 2); n++;
- XtSetArg(args[n], XmNmarginHeight, 2); n++;
- new_p->text = XtCreateWidget("ComboBoxTextField",
- xmTextFieldWidgetClass,
- (Widget)new, args, n);
- XtAddCallback(new_p->text, XmNlosingFocusCallback,
- text_losing_focus_cb, (XtPointer)new);
- XtAddCallback(new_p->text, XmNactivateCallback,
- text_activate_cb, (XtPointer)new);
- XtAddCallback(new_p->text, XmNfocusCallback,
- text_focus_cb, (XtPointer)new);
- if (new_p->horizontal_spacing == cur_p->horizontal_spacing)
- new_p->horizontal_spacing = 0;
- if (new_p->vertical_spacing == cur_p->vertical_spacing)
- new_p->vertical_spacing = 0;
- }
- XtUnmanageChild(new_p->sep);
- XtUnmanageChild(new_p->label);
- XtManageChild(new_p->text);
- }
- else {
- if (new_p->label == NULL) {
- XtTranslations label_trans =
- XtParseTranslationTable(ComboBoxLabelTranslationTable);
-
- n = 0;
- XtSetArg(args[n], XmNalignment, new_p->alignment); n++;
- XtSetArg(args[n], XmNrecomputeSize, FALSE); n++;
- XtSetArg(args[n], XmNmarginLeft, LABEL_PADDING); n++;
- XtSetArg(args[n], XmNmarginRight, LABEL_PADDING); n++;
- XtSetArg(args[n], XmNmarginWidth, 0); n++;
- XtSetArg(args[n], XmNmarginHeight, 0); n++;
- XtSetArg(args[n], XmNstringDirection,
- new->manager.string_direction); n++;
- new_p->label = XtCreateWidget("ComboBoxLabel",
- xmLabelWidgetClass,
- (Widget)new, args, n);
- XtOverrideTranslations((Widget)new_p->label, label_trans);
- if (new_p->horizontal_spacing == cur_p->horizontal_spacing)
- new_p->horizontal_spacing = 1;
- if (new_p->vertical_spacing == cur_p->vertical_spacing)
- new_p->vertical_spacing = 2;
-
- n = 0;
- XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
- new_p->sep = XtCreateWidget("ComboBoxSeparator",
- xmSeparatorWidgetClass,
- (Widget)new, args, n);
- }
- else if (new->manager.string_direction !=
- current->manager.string_direction) {
- XtSetArg(args[0], XmNstringDirection,
- new->manager.string_direction);
- XtSetValues(new_p->label, args, 1);
- }
- XtUnmanageChild(new_p->text);
- XtManageChild(new_p->label);
- XtManageChild(new_p->sep);
- }
- /*
- * Text-fields and labels have different shadows. Only
- * change if user didn't change the shadow resource.
- */
- if (COMBO_SHADOW(new) == COMBO_SHADOW(current))
- COMBO_SHADOW(new) = ((new_p->type == XmDROP_DOWN_COMBO_BOX) ?
- TEXT_FIELD_SHADOW : LABEL_SHADOW);
- }
-
- if (new_p->text && (new_p->text == cur_p->text)) {
- n = 0;
- if (new_p->text_columns != cur_p->text_columns) {
- XtSetArg(args[n], XmNcolumns, new_p->text_columns); n++;
- }
- if (new_p->text_max_length != cur_p->text_max_length) {
- XtSetArg(args[n], XmNmaxLength, new_p->text_max_length); n++;
- }
- if (n > 0)
- XtSetValues(new_p->text, args, n);
- }
-
- /*
- * LabelWidget alignment has changed.
- */
- if (new_p->label && (new_p->alignment != cur_p->alignment)) {
- XtSetArg(args[0], XmNalignment, new_p->alignment);
- XtSetValues(new_p->label, args, 1);
- }
-
- if (new_p->label && ((new_p->items != cur_p->items) ||
- (new_p->item_count != cur_p->item_count) ||
- (new_p->label != cur_p->label))) {
- SetMaximumLabelSize(new_p);
- label_size_changed = TRUE;
- }
-
- /* Copy and free label-string */
- if (new_p->label_string != cur_p->label_string) {
- if (new_p->label_string)
- new_p->label_string = XmStringCopy(new_p->label_string);
- if (cur_p->label_string)
- XmStringFree(cur_p->label_string);
- /*
- * force_label_string usage if it is specified and items is not.
- * This will be the perminant label string only if update-label
- * is false, else it is only used until the user picks something
- * new off the list.
- */
- if (new_p->items == cur_p->items)
- force_label_string = TRUE;
- }
-
- if ((new_p->items != cur_p->items) ||
- (new_p->alignment != cur_p->alignment) ||
- (new_p->type != cur_p->type) ||
- (new_p->item_count != cur_p->item_count) ||
- (new_p->selected_position != cur_p->selected_position) ||
- (new_p->selected_item != cur_p->selected_item) ||
- (new_p->label != cur_p->label) ||
- (new_p->update_label != cur_p->update_label) ||
- (new_p->label_string != cur_p->label_string)) {
-
- /* selected_item resource used before selected_position */
- if (new_p->selected_item &&
- (new_p->selected_item != cur_p->selected_item))
- DtComboBoxSelectItem((Widget)new, new_p->selected_item);
- else
- XmListSelectPos(new_p->list, new_p->selected_position + 1, FALSE);
-
-
- if (new_p->type == XmDROP_DOWN_COMBO_BOX)
- SetTextFieldData(new_p, NULL);
- else
- SetLabelData(new_p, NULL, force_label_string);
- }
-
- /*
- * Must recalculate the combo_box and re-layout the children.
- * If this is not editable, then set the label to its' maximum
- * size; it will get chopped if it is too big. This is needed
- * because we shrink the label down, and SetComboBoxSize() uses
- * the label's core sizes to figure what size to become.
- */
- if ((new_p->type != cur_p->type) ||
- (new_p->arrow_type != cur_p->arrow_type) ||
- (COMBO_MARGIN_W(new) != COMBO_MARGIN_W(current)) ||
- (COMBO_MARGIN_H(new) != COMBO_MARGIN_H(current)) ||
- (COMBO_H_SPACING(new) != COMBO_H_SPACING(current)) ||
- (COMBO_V_SPACING(new) != COMBO_V_SPACING(current)) ||
- (COMBO_SHADOW(new) != COMBO_SHADOW(current)) ||
- (new_p->orientation != cur_p->orientation) ||
- (new_p->arrow_spacing != cur_p->arrow_spacing) ||
- ((new_p->type == XmDROP_DOWN_LIST_BOX) && label_size_changed)) {
- ClearShadow(current, TRUE);
- if (new_p->recompute_size)
- SetComboBoxSize(new);
- LayoutChildren(new);
- DrawShadow(new);
- }
-
- SyncWithList(new_p);
- return(FALSE);
- }
-
-
- /*
- * This function clears the shadow around our widget. If all is TRUE,
- * then clear all 4 sides; otherwise, only clear the right and bottom
- * sides (during resize).
- */
- static void
- ClearShadow(DtComboBoxWidget w,
- Boolean all)
- {
- Dimension shadow = COMBO_SHADOW(w);
- Dimension margin_w = COMBO_MARGIN_W(w);
- Dimension margin_h = COMBO_MARGIN_H(w);
-
- if ((shadow > 0) && XtIsRealized(w)) {
- if (all) {
- XClearArea(XtDisplayOfObject((Widget)w),
- XtWindowOfObject((Widget)w),
- margin_w, margin_h,
- w->combo_box.old_width - (margin_w * 2),
- shadow, FALSE);
- XClearArea(XtDisplayOfObject((Widget)w),
- XtWindowOfObject((Widget)w),
- margin_w, margin_h, shadow,
- w->combo_box.old_height - (margin_h * 2), FALSE);
- }
- XClearArea(XtDisplayOfObject((Widget)w),
- XtWindowOfObject((Widget)w), margin_w,
- w->combo_box.old_height - margin_h - shadow,
- w->combo_box.old_width - (margin_w * 2), shadow, FALSE);
- XClearArea(XtDisplayOfObject((Widget)w), XtWindowOfObject((Widget)w),
- w->combo_box.old_width - margin_w - shadow,
- margin_h, shadow,
- w->combo_box.old_height - (margin_h * 2), FALSE);
- }
- DrawHighlight(w, TRUE);
- }
-
- /*
- * This functions draws the shadow around our combo-box.
- */
- static void
- DrawShadow(DtComboBoxWidget w)
- {
- Dimension shadow = COMBO_SHADOW(w);
- Dimension margin_w = COMBO_MARGIN_W(w);
- Dimension margin_h = COMBO_MARGIN_H(w);
-
- if ((shadow > 0) && XtIsRealized(w)) {
- _XmDrawShadows(XtDisplayOfObject((Widget)w),
- XtWindowOfObject((Widget)w),
- w->manager.top_shadow_GC,
- w->manager.bottom_shadow_GC,
- margin_w, margin_h,
- w->core.width - (margin_w * 2),
- w->core.height - (margin_h * 2),
- shadow, XmSHADOW_OUT);
- }
- DrawHighlight(w, FALSE);
- }
-
- /*
- * Take the string out of the list and put it into the text-field.
- * text-fields don't handle xm-strings, so we must get the char*
- * out of it (only getting the first segment). This is slower than
- * storing the text-strings (char*) ourselves, but that would take
- * up a lot of memory. Since this setting happens during a user
- * action, speed isn't a problem.
- */
- static void
- SetTextFieldData(DtComboBoxPart *combo_p,
- XmString item)
- {
- XmListWidget list = (XmListWidget)combo_p->list;
- Arg arg;
-
-
- if (!item && list->list.itemCount)
- item = list->list.items[combo_p->selected_position];
-
- if (!item)
- {
- combo_p->selected_item = NULL;
- XtSetArg(arg, XmNvalue, "");
- XtSetValues(combo_p->text, &arg, 1);
- }
- else
- {
- XmStringContext context = NULL;
- char * text = NULL;
- XmStringCharSet charset = NULL;
-
- XmStringDirection direction;
- XmStringComponentType unknown_tag;
- XmStringComponentType type;
-
- unsigned short ul = 0;
- unsigned char * uv = NULL;
-
- Boolean done = FALSE;
-
- combo_p->selected_item = item;
-
- XmStringInitContext(&context, item);
-
- /* Loop until 1st char* found */
- while (!done)
- {
- type = XmStringGetNextComponent(context,
- &text,
- &charset,
- &direction,
- &unknown_tag,
- &ul,
- &uv);
- switch (type)
- {
- case XmSTRING_COMPONENT_END:
- done = TRUE;
- break;
-
- case XmSTRING_COMPONENT_TEXT:
- case XmSTRING_COMPONENT_LOCALE_TEXT:
- XtSetArg(arg, XmNvalue, text);
- XtSetValues(combo_p->text, &arg, 1);
-
- if (text)
- XtFree((char *) text);
-
- done = TRUE;
- break;
-
- case XmSTRING_COMPONENT_CHARSET:
- if (charset)
- XtFree((char *) charset);
- break;
-
- default:
- if (uv)
- XtFree((char *) uv);
- break;
- }
-
-
-
- }
-
- if (context)
- XmStringFreeContext(context);
- }
-
- }
-
-
- /*
- * Set the maximum size of the label, depending on the
- * characteristics of the list of items.
- */
- static void
- SetMaximumLabelSize(DtComboBoxPart *combo_p)
- {
- XmListWidget list = (XmListWidget)combo_p->list;
- XmFontList font_list;
- Dimension width, height;
- Dimension longest = 0;
- Dimension highest = 0;
- Arg args[5];
- int i;
-
- /* Get font info from the widget */
- XtSetArg(args[0], XmNfontList, &font_list);
- XtGetValues(combo_p->label, args, 1);
-
- if ( list->list.itemCount && combo_p->update_label) {
- /*
- * Loop through all the items to find the biggest dimensions
- */
- for (i = 0; i < combo_p->item_count; i++) {
- XmStringExtent(font_list, list->list.items[i], &width, &height);
- longest = (width > longest) ? width : longest;
- highest = (height > highest) ? height : highest;
- }
- }
- else {
- XmStringExtent(font_list, combo_p->label_string, &longest, &highest);
- }
-
- combo_p->label_max_length = longest + (LABEL_PADDING * 2);
- combo_p->label_max_height = highest;
- XtResizeWidget(combo_p->label, combo_p->label_max_length, highest,
- combo_p->label->core.border_width);
- }
-
-
- /*
- * Put the current list item into the label.
- * This could probably be faster if we see if the label is the
- * same as the new item?
- */
- static void
- SetLabelData(DtComboBoxPart *combo_p,
- XmString item,
- Boolean force_label_string)
- {
- XmListWidget list = (XmListWidget)combo_p->list;
- int index = combo_p->selected_position;
- Arg arg;
-
- /*
- * If the item is empty, get the current item from the list, or
- * use label_string if update_label is FALSE. If that is empty,
- * use InitLabel.
- */
- if (force_label_string || (combo_p->update_label == FALSE))
- item = combo_p->label_string ? combo_p->label_string : InitLabel;
- else {
- if (!item) {
- if (list->list.itemCount)
- item = list->list.items[index];
- else
- item = InitLabel;
- }
-
- /* Keep label_string in sync with item picked */
- if (combo_p->label_string)
- XmStringFree(combo_p->label_string);
- combo_p->label_string = XmStringCopy(item);
- }
-
- combo_p->selected_item = item;
- XtSetArg(arg, XmNlabelString, item);
- XtSetValues(combo_p->label, &arg, 1);
- }
-
- /*
- * This is the browseSelect and defaultAction callback handler for the
- * ListWidget. If using the textWidget, we only take the first
- * segment of the XmString (TextWidgets don't handle XmStrings). If we
- * are using a label, then just set the labelString resource.
- */
- static void
- select_cb(Widget w,
- XtPointer client_data,
- XtPointer call_data)
- {
- DtComboBoxWidget combo_w = (DtComboBoxWidget)client_data;
- DtComboBoxPart *combo_p = (DtComboBoxPart*)&(combo_w->combo_box);
- XmListCallbackStruct *info = (XmListCallbackStruct*)call_data;
- DtComboBoxCallbackStruct cb;
-
- combo_p->selected_position = info->item_position - 1;
- if (combo_p->type == XmDROP_DOWN_COMBO_BOX) {
- SetTextFieldData(combo_p, info->item);
- }
- else { /* Set the labelWidget string */
- SetLabelData(combo_p, info->item, FALSE);
- }
-
- /*
- * Only popdown if this is the defaultAction callback. We don't
- * want to popdown with browseSelect callback; that would cause the
- * menu to popdown when the user moved selection with the keyboard.
- * Doing it this way, allows the menu to stay up during
- * keyboard navigation. When menu goes away, make sure input
- * focus goes back into the textField (if editable).
- */
- if (info->reason == XmCR_DEFAULT_ACTION) {
- combo_p->popped_up = FALSE;
- XtPopdown(combo_p->shell);
- XtUngrabPointer(combo_p->shell, CurrentTime);
- XtUngrabKeyboard(combo_p->list, CurrentTime);
- /*
- * _XmRemoveGrab() was causing trouble on irix and linux. The navigator
- * stopped responding to clicks cause of it.
- *
- */
- #if 0
- _XmRemoveGrab(combo_p->shell);
- #else
- XtRemoveGrab(combo_p->shell);
-
- DisplayUserGrabbed(w) = False;
- #endif
- XFlush(XtDisplay(combo_p->shell));
- if (combo_p->type == XmDROP_DOWN_COMBO_BOX)
- XmProcessTraversal(combo_p->text, XmTRAVERSE_CURRENT);
- }
-
- if (((ShellWidget)(combo_p->shell))->shell.popped_up == FALSE) {
- /* The list will free info->item */
- cb.reason = XmCR_SELECT;
- cb.event = info->event;
- cb.item_or_text = info->item;
- cb.item_position = combo_p->selected_position;
- XtCallCallbackList((Widget)w, combo_p->selection_callback,
- (XtPointer)&cb);
- }
- }
-
-
- /*
- * This is the event_handler for our shell widget. The grab happens
- * on the shell while the user is not doing anything inside the list.
- * This allows us to know if the user pressed a button outside our
- * application. If the user pressed a button anywhere but inside
- * the shell, then popdown the menu and ungrab everything.
- */
- static void
- shell_event_handler(Widget widget,
- XtPointer client_data,
- XEvent *event,
- Boolean *dispatch)
- {
- DtComboBoxWidget combo_w = (DtComboBoxWidget)client_data;
- DtComboBoxPart *combo_p = (DtComboBoxPart*)&(combo_w->combo_box);
- XmScrolledWindowWidget sw = (XmScrolledWindowWidget)XtParent(combo_p->list);
- XmScrollBarWidget v_scrollbar = sw->swindow.vScrollBar;
- XmScrollBarWidget h_scrollbar = sw->swindow.hScrollBar;
- Window window = event->xbutton.window;
-
- if (((ShellWidget)(combo_p->shell))->shell.popped_up &&
- (window != XtWindowOfObject(combo_p->list)) &&
- (h_scrollbar && (window != XtWindowOfObject((Widget)h_scrollbar))) &&
- (v_scrollbar && (window != XtWindowOfObject((Widget)v_scrollbar)))) {
- combo_p->popped_up = FALSE;
- XtPopdown(combo_p->shell);
- XtUngrabPointer(combo_p->shell, CurrentTime);
- XtUngrabKeyboard(combo_p->list, CurrentTime);
- /*
- * _XmRemoveGrab() was causing trouble on irix and linux. The navigator
- * stopped responding to clicks cause of it.
- *
- */
- #if 0
- _XmRemoveGrab(combo_p->shell);
- #else
- XtRemoveGrab(combo_p->shell);
-
- DisplayUserGrabbed(widget) = False;
- #endif
- if (combo_p->type == XmDROP_DOWN_COMBO_BOX)
- XmProcessTraversal(combo_p->text, XmTRAVERSE_CURRENT);
- }
- }
-
-
- /*
- * This is the event_handler for our list widget. Getting the pointer
- * grabbing to work correctly was not very easy. In order for everything
- * to work correctly, we only do grab-pointer, for the shell, while not
- * doing anything inside the list. If doing something inside the list
- * we remove the grab on the shell. This is the only way that the
- * list will get the ButtonRelease if doing browse while outside the
- * list. The toolkit automatically does a grab in between ButtonPress
- * and ButtonRelease; therefore, the shell ungrab can't be done inside
- * the ButtonPress event.
- */
- static void
- list_event_handler(Widget widget,
- XtPointer client_data,
- XEvent *event,
- Boolean *dispatch)
- {
- DtComboBoxWidget combo_w = (DtComboBoxWidget)client_data;
- DtComboBoxPart *combo_p = (DtComboBoxPart*)&(combo_w->combo_box);
- static int btn_down = False;
-
- switch (event->type) {
- case ButtonPress:
- /*
- * Can't ungrab shell because of toolkit interaction (the toolkit
- * automatically does a grab in between ButtonPress and
- * ButtonRelease).
- */
- btn_down = True;
- break;
- case ButtonRelease:
- /*
- * Get rid of menu when Button is released.
- */
- combo_p->popped_up = FALSE;
- XtPopdown(combo_p->shell);
- XtUngrabKeyboard(combo_p->list, CurrentTime);
- /*
- * _XmRemoveGrab() was causing trouble on irix and linux. The navigator
- * stopped responding to clicks cause of it.
- *
- */
- #if 0
- _XmRemoveGrab(combo_p->shell);
- #else
- XtRemoveGrab(combo_p->shell);
-
- DisplayUserGrabbed(widget) = False;
-
- #endif
- if (combo_p->type == XmDROP_DOWN_COMBO_BOX)
- XmProcessTraversal(combo_p->text, XmTRAVERSE_CURRENT);
- btn_down = False;
- break;
- case FocusOut:
- /*
- * There are interaction problems between the list and the
- * scrollbars in terms of Focus. We always want our list
- * to have focus, so grab it back if we lose it.
- */
- if (((ShellWidget)(combo_p->shell))->shell.popped_up) {
- _XmGrabKeyboard(widget, False, GrabModeAsync, GrabModeAsync,
- CurrentTime);
- XtSetKeyboardFocus(combo_p->list, RevertToNone);
- }
- break;
- case EnterNotify:
- /*
- * Don't let the shell have the pointer grabbed while
- * we are inside the list.
- */
- if (btn_down == False) {
- XtUngrabPointer(combo_p->shell, CurrentTime);
- }
- break;
- case LeaveNotify:
- /*
- * Only let the shell have the grab if the menu is up
- * and the btn isn't down. We don't want the shell to
- * have the grab while the user is interacting in any way
- * with the list.
- */
- if ((((ShellWidget)(combo_p->shell))->shell.popped_up) &&
- (btn_down == FALSE)) {
- _XmGrabPointer(combo_p->shell, True, ButtonPressMask,
- GrabModeAsync, GrabModeAsync, None,
- XmGetMenuCursor(XtDisplayOfObject(combo_p->shell)),
- CurrentTime);
- }
- break;
- }
- }
-
-
- /* Caller must free string */
- static char*
- GetTextString(XmString xm_string)
- {
- XmStringContext context;
- XmStringComponentType type;
- XmStringCharSet charset;
- XmStringDirection direction;
- XmStringComponentType unknown_tag;
- unsigned short ul;
- unsigned char *uv;
- char *text = NULL;
- Boolean done = FALSE;
-
- XmStringInitContext(&context, xm_string);
-
- /* Loop until 1st char* found */
- while (!done) {
- type = XmStringGetNextComponent(context, &text, &charset,
- &direction, &unknown_tag,
- &ul, &uv);
- switch (type) {
- case XmSTRING_COMPONENT_END:
- done = TRUE;
- break;
- case XmSTRING_COMPONENT_TEXT:
- case XmSTRING_COMPONENT_LOCALE_TEXT:
- done = TRUE;
- break;
- default:
- break;
- }
- }
- XmStringFreeContext(context);
- return(text);
- }
-
- static void
- TextFieldActivate(DtComboBoxPart *combo_p)
- {
- XmTextFieldWidget w = (XmTextFieldWidget)(combo_p->text);
- XmListWidget list = (XmListWidget)combo_p->list;
- XmAnyCallbackStruct cb;
- char *data = NULL;
- char *text = NULL;
- Arg arg;
-
- XtSetArg(arg, XmNvalue, &data);
- XtGetValues((Widget)w, &arg, 1);
-
- if ( list->list.itemCount)
- text = GetTextString(list->list.items[combo_p->selected_position]);
-
- if (text && data && (strcmp(text, data) == 0)) {
- XtFree(text);
- return;
- }
- /* Only send callback if both are not NULL */
- else if (!((text == NULL) && (data == NULL))) {
- cb.reason = XmCR_ACTIVATE;
- cb.event = NULL;
- XtCallCallbackList((Widget)w, w->text.activate_callback,
- (XtPointer) &cb);
- if (text)
- XtFree(text);
- }
- }
-
- /*
- * This is the activate callback for the arrow button. This
- * sets the shell position and width, does the correct grabs, and
- * puts the shell on the screen.
- */
- static void
- activate_cb(Widget w,
- XtPointer client_data,
- XtPointer call_data)
- {
- DtComboBoxWidget combo_w = (DtComboBoxWidget)client_data;
- DtComboBoxPart *combo_p = (DtComboBoxPart*)&(combo_w->combo_box);
- Display *disp = XtDisplayOfObject((Widget)combo_w);
- int screen;
- Dimension width, height;
- Dimension disp_width, disp_height;
- Position root_x, root_y;
- Arg args[5];
- int n;
- char *text;
- XmString item;
-
- if ((combo_p->type == XmDROP_DOWN_COMBO_BOX) &&
- !combo_p->no_callback_for_arrow)
- {
- TextFieldActivate(combo_p);
- }
-
-
- /*
- * Don't popup if no items in the list.
- */
- if (!((XmListWidget)combo_p->list)->list.itemCount)
- return;
-
-
- if ( combo_p->move_selecteditem_up )
- {
- if ( combo_p->selected_item )
- {
- text = GetTextString(((XmListWidget)combo_p->list)->
- list.items[combo_p->selected_position]);
-
- item = ((XmListWidget)combo_p->list)->
- list.items[combo_p->selected_position];
-
- DtComboBoxSelectItemMoveup(combo_w, item);
- }
- else
- {
- XmListSelectPos(combo_p->list, 1, False);
- XmListSetPos (combo_p->list, 1 );
- }
- }
-
- screen = DefaultScreen(disp);
- disp_width = DisplayWidth(disp, screen);
- disp_height = DisplayHeight(disp, screen);
-
- /*
- * Call the menu-post callback if requested. This allows the
- * user to change the items, instead of using the losing-focus callback.
- * If the user used the losing-focus callback to change the items, the
- * size of the list/shell will change while it is popped up. We
- * could disallow SetValues while the menu is posted, but let's see
- * how things go first.
- */
- if (combo_p->menu_post_callback) {
- XmAnyCallbackStruct info;
-
- info.reason = XmCR_MENU_POST;
- info.event = (XEvent*)NULL;
- XtCallCallbackList((Widget)combo_w, combo_p->menu_post_callback,
- (XtPointer)&info);
- }
-
- width = combo_p->max_shell_width;
- height = combo_p->max_shell_height;
-
- /* Get root coords of ComboBox */
- XtTranslateCoords((Widget)combo_w, combo_w->core.x, combo_w->core.y,
- &root_x, &root_y);
-
- /*
- * Make necessary adjustments for offset of our widget
- * inside its' parent. Calculate the width of the shell.
- * This must be done every time the shell gets popped up, because
- * the x/y can change as well as the width (from list's visibleItemCount
- * or geometry management changes).
- */
- root_x -= combo_w->core.x;
- root_y -= combo_w->core.y;
- root_y += (combo_w->core.height - COMBO_MARGIN_H(combo_w));
-
- /*
- * Make sure the shell is at least as big as our combo-box, and
- * make sure it stays on the screen.
- */
- if (width < combo_w->core.width)
- width = combo_w->core.width;
- if ((int)(root_x + width) > (int)disp_width)
- width = (disp_width - root_x);
- if ((int)(root_y + height) > (int)disp_height)
- height = (disp_height - root_y);
-
- n = 0;
- XtSetArg(args[n], XmNx, root_x); n++;
- XtSetArg(args[n], XmNy, root_y); n++;
- XtSetArg(args[n], XmNwidth, width); n++;
- XtSetArg(args[n], XmNheight, height); n++;
- XtSetValues(combo_p->shell, args, n);
-
- combo_p->popped_up = TRUE;
- XtPopup(combo_p->shell, XtGrabNone);
-
- /*
- * Set up the grab for the shell and list. The shell gets the
- * pointer grab so that events will go into the list and scrollbars
- * correctly, but events outside the shell will go to the shell.
- * See shell and list event handlers for details about grabs.
- */
- _XmGrabPointer(combo_p->shell, True, ButtonPressMask,
- GrabModeAsync, GrabModeAsync, None,
- XmGetMenuCursor(disp), CurrentTime);
- _XmGrabKeyboard(combo_p->list, False, GrabModeAsync, GrabModeAsync,
- CurrentTime);
-
- /*
- * _XmAddGrab() was causing trouble on irix and linux. The navigator
- * stopped responding to clicks cause of it.
- *
- */
- #if 0
- _XmAddGrab(combo_p->shell, True, True);
- #else
- XtAddGrab(combo_p->shell, True, True);
-
- DisplayUserGrabbed(w) = True;
- #endif
-
- /*
- * Where to define the cursor for the list widget. It would be
- * nice to do it in the list's realize function, but that's not
- * possible. We can't use the ComboBox realize function, because
- * the list isn't realized at that point. This is the simpliest
- * way to get this done. This is needed to make sure the list has the
- * correct menu during browse scrolling, etc.
- */
- XDefineCursor(disp, XtWindowOfObject(combo_p->shell),
- XmGetMenuCursor(disp));
- }
-
-
- /*
- * Make sure arrow is symetrical. 45 degree angle. I'm not sure how
- * inefficient get/releasing the GC every time is (they are cached by
- * the toolkit)?
- */
- static void
- arrow_expose_cb(Widget w,
- XtPointer client_data,
- XtPointer call_data)
- {
- Display *disp = XtDisplayOfObject(w);
- Window win = XtWindowOfObject(w);
- XGCValues values;
- short center_w = w->core.width/2;
- short center_h = ((int)(w->core.height - 3))/2;
- XPoint points[10];
- Arg arg;
- GC gc;
-
- XtSetArg(arg, XmNforeground, &(values.foreground));
- XtGetValues(w, &arg, 1);
-
- values.line_width = 0;
- values.line_style = LineSolid;
- values.fill_style = FillSolid;
- gc = XtGetGC(w, GCForeground | GCFillStyle | GCLineStyle | GCLineWidth,
- &values);
-
- XDrawLine(disp, win, gc, 1, center_h + center_w + 1, w->core.width - 2,
- center_h + center_w + 1);
-
- /* A - bottom point */
- points[0].x = center_w;
- points[0].y = center_h + (int)(center_w * .8);
-
- /* B - far left point */
- points[1].x = center_w - (int)(center_w * .8);
- points[1].y = center_h;
-
- /* C - inner left point */
- points[2].x = center_w - (int)(center_w * .3);
- points[2].y = points[1].y;
-
- /* D - top left point */
- points[3].x = points[2].x;
- points[3].y = center_h - (int)(center_w * .8);
-
- /* E - top right point */
- points[4].x = center_w + (int)(center_w * .3);
- points[4].y = points[3].y;
-
- /* F - inner right point */
- points[5].x = points[4].x;
- points[5].y = points[1].y;
-
- /* G - far right point */
- points[6].x = center_w + (int)(center_w * .8);
- points[6].y = points[1].y;
-
- /* A - bottom point */
- points[7].x = points[0].x;
- points[7].y = points[0].y;
-
- XDrawLines(disp, win, gc, points, 8, CoordModeOrigin);
- XFillPolygon(disp, win, gc, points, 8, Convex, CoordModeOrigin);
- XtReleaseGC(w, gc);
- }
-
- /*
- * We get the text-field losing-focus callback, so pass it on to
-
- * the user if they requested it. Our losing-focus callback
- * is just a convenience callback, so that the user doesn't
- * have to get the text-field first. This make our integration
- * with XDesigner a little easier.
- */
- static void
- text_losing_focus_cb(Widget w,
- XtPointer client_data,
- XtPointer call_data)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)client_data;
- DtComboBoxPart *combo_p = (DtComboBoxPart*)&(combo->combo_box);
-
- if (combo_p->losing_focus_callback)
- XtCallCallbackList((Widget)combo, combo_p->losing_focus_callback,
- (XtPointer)call_data);
- }
-
- /*
- * We get the text-field activate callback, so pass it on to
- * the user if they requested it. Our activate callback
- * is just a convenience callback, so that the user doesn't
- * have to get the text-field first. This make our integration
- * with XDesigner a little easier.
- */
- static void
- text_activate_cb(Widget w,
- XtPointer client_data,
- XtPointer call_data)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)client_data;
-
- if (combo->combo_box.activate_callback)
- XtCallCallbackList((Widget)combo,
- combo->combo_box.activate_callback,
- (XtPointer)call_data);
- }
-
-
- /*
- * We get the text-field focus callback, so pass it on to
- * the user if they requested it. Our focus callback
- * is just a convenience callback, so that the user doesn't
- * have to get the text-field first. This make our integration
- * with XDesigner a little easier.
- */
- static void
- text_focus_cb(Widget w,
- XtPointer client_data,
- XtPointer call_data)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)client_data;
- DtComboBoxPart *combo_p = (DtComboBoxPart*)&(combo->combo_box);
-
- if (combo_p->focus_callback)
- XtCallCallbackList((Widget)combo, combo_p->focus_callback,
- (XtPointer)call_data);
- }
-
- /*
- * Try and keep our list related rsources in sync with the list widget.
- * This is not always possible, depending on if the programmer makes
- * list widget calls directly. If we get out of sync with the
- * list widget, our SetValues() may not work correctly (when the
- * comparisons are done). Should do get values in case list widget
- * names are changed?
- */
- static void
- SyncWithList(DtComboBoxPart *combo_p)
- {
- XmListWidget list = (XmListWidget)combo_p->list;
-
- combo_p->items = list->list.items;
- combo_p->item_count = list->list.itemCount;
- combo_p->list_font_list = list->list.font;
- combo_p->list_margin_height = list->list.margin_height;
- combo_p->list_margin_width = list->list.margin_width;
- combo_p->list_spacing = list->list.ItemSpacing;
- combo_p->top_item_position = list->list.top_position;
- combo_p->visible_item_count = list->list.visibleItemCount;
- /* selected position must be into the items */
- if (!(combo_p->selected_position < combo_p->item_count))
- combo_p->selected_position = 0;
- }
-
- /*
- * Routines which manipulate the ComboBox list. These are external
- * for use by users of our widget.
- */
- Widget
- DtCreateComboBox(Widget parent,
- char *name,
- Arg *arglist,
- int num_args)
- {
- return(XtCreateWidget(name, dtComboBoxWidgetClass, parent,
- arglist, num_args));
- }
-
- void
- DtComboBoxAddItem(Widget combo_w,
- XmString item,
- int pos,
- Boolean unique)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)combo_w;
- DtComboBoxPart *combo_p = (DtComboBoxPart*)&(combo->combo_box);
- XmStringTable list_items = ((XmListWidget)combo_p->list)->list.items;
- int i;
-
- if (item && ((XmListWidget)combo_p->list)->list.itemCount) {
- for (i = 0; i < combo_p->item_count; i++)
- if (XmStringCompare(item, list_items[i]))
- break;
- if ((i < combo_p->item_count) && unique)
- return;
- }
-
- XmListAddItem(combo_p->list, item, pos);
- SyncWithList(combo_p);
-
- if (combo_p->label) {
- SetMaximumLabelSize(combo_p);
- if (combo_p->type == XmDROP_DOWN_LIST_BOX) {
- ClearShadow(combo, TRUE);
- if (combo_p->recompute_size)
- SetComboBoxSize(combo);
- LayoutChildren(combo);
- DrawShadow(combo);
- }
- }
- if (combo_p->type == XmDROP_DOWN_COMBO_BOX)
- SetTextFieldData(combo_p, NULL);
- else
- SetLabelData(combo_p, NULL, FALSE);
- }
-
- void
- DtComboBoxAddItemSelected(Widget combo_w,
- XmString item,
- int pos,
- Boolean unique)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)combo_w;
- DtComboBoxPart *combo_p = (DtComboBoxPart*)&(combo->combo_box);
- XmStringTable list_items = ((XmListWidget)combo_p->list)->list.items;
- int i;
-
- if (item && ((XmListWidget)combo_p->list)->list.itemCount) {
- for (i = 0; i < combo_p->item_count; i++)
- if (XmStringCompare(item, list_items[i]))
- break;
- if ((i < combo_p->item_count) && unique)
- return;
- }
-
- XmListAddItem(combo_p->list, item, pos);
- XmListSelectPos(combo_p->list, pos, False);
- SyncWithList(combo_p);
-
- if (combo_p->label) {
- SetMaximumLabelSize(combo_p);
- if (combo_p->type == XmDROP_DOWN_LIST_BOX) {
- ClearShadow(combo, TRUE);
- if (combo_p->recompute_size)
- SetComboBoxSize(combo);
- LayoutChildren(combo);
- DrawShadow(combo);
- }
- }
- if (combo_p->type == XmDROP_DOWN_COMBO_BOX)
- SetTextFieldData(combo_p, NULL);
- else
- SetLabelData(combo_p, NULL, FALSE);
- }
-
-
- void
- DtComboBoxDeleteAllItems(Widget combo_w)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)combo_w;
- DtComboBoxPart *combo_p = (DtComboBoxPart*)&(combo->combo_box);
-
- XmListDeleteAllItems(combo_p->list);
- SyncWithList(combo_p);
-
- if (combo_p->label) {
- SetMaximumLabelSize(combo_p);
- if (combo_p->type == XmDROP_DOWN_LIST_BOX) {
- ClearShadow(combo, TRUE);
- if (combo_p->recompute_size)
- SetComboBoxSize(combo);
- LayoutChildren(combo);
- DrawShadow(combo);
- }
- }
- if (combo_p->type == XmDROP_DOWN_COMBO_BOX)
- SetTextFieldData(combo_p, NULL);
- else
- SetLabelData(combo_p, NULL, FALSE);
- }
-
-
- void
- DtComboBoxDeletePos(Widget combo_w,
- int pos)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)combo_w;
- DtComboBoxPart *combo_p = (DtComboBoxPart*)&(combo->combo_box);
-
- XmListDeletePos(combo_p->list, pos);
- SyncWithList(combo_p);
-
- if (combo_p->label) {
- SetMaximumLabelSize(combo_p);
- if (combo_p->type == XmDROP_DOWN_LIST_BOX) {
- ClearShadow(combo, TRUE);
- if (combo_p->recompute_size)
- SetComboBoxSize(combo);
- LayoutChildren(combo);
- DrawShadow(combo);
- }
- }
- if (combo_p->type == XmDROP_DOWN_COMBO_BOX)
- SetTextFieldData(combo_p, NULL);
- else
- SetLabelData(combo_p, NULL, FALSE);
- }
-
- void
- DtComboBoxSetItem(Widget combo_w,
- XmString item)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)combo_w;
- DtComboBoxPart *combo_p = (DtComboBoxPart*)&(combo->combo_box);
- XmStringTable list_items = ((XmListWidget)combo_p->list)->list.items;
- int i;
-
- if (item && ((XmListWidget)combo_p->list)->list.itemCount) {
- for (i = 0; i < combo_p->item_count; i++)
- if (XmStringCompare(item, list_items[i]))
- break;
- if (i < combo_p->item_count) {
- combo_p->selected_position = i;
- if (combo_p->type == XmDROP_DOWN_COMBO_BOX)
- SetTextFieldData(combo_p, NULL);
- else
- SetLabelData(combo_p, NULL, FALSE);
- XmListSetItem(combo_p->list, item);
- SyncWithList(combo_p);
- }
- else
- XtWarning(COMBO_SET_ITEM);
- }
- else
- XtWarning(COMBO_SET_ITEM);
- }
-
- void
- DtComboBoxSelectItem(Widget combo_w,
- XmString item)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)combo_w;
- DtComboBoxPart *combo_p = (DtComboBoxPart*)&(combo->combo_box);
- XmStringTable list_items = ((XmListWidget)combo_p->list)->list.items;
- int i;
-
- if (item && ((XmListWidget)combo_p->list)->list.itemCount) {
- for (i = 0; i < combo_p->item_count; i++)
- if (XmStringCompare(item, list_items[i]))
- break;
- if (i < combo_p->item_count) {
- combo_p->selected_position = i;
- if (combo_p->type == XmDROP_DOWN_COMBO_BOX)
- SetTextFieldData(combo_p, NULL);
- else
- SetLabelData(combo_p, NULL, FALSE);
- XmListDeselectAllItems(combo_p->list);
- XmListSelectItem(combo_p->list, item, FALSE);
- SyncWithList(combo_p);
- }
- else
- XtWarning(COMBO_SELECT_ITEM);
- }
- else
- XtWarning(COMBO_SELECT_ITEM);
- }
-
- void
- DtComboBoxSelectItemMoveup(DtComboBoxWidget combo,
- XmString item)
- {
- DtComboBoxPart *combo_p = (DtComboBoxPart*)&(combo->combo_box);
- XmStringTable list_items = ((XmListWidget)combo_p->list)->list.items;
- int i;
-
- if (item && ((XmListWidget)combo_p->list)->list.itemCount) {
- for (i = 0; i < combo_p->item_count; i++)
- if (XmStringCompare(item, list_items[i]))
- break;
- if (i < combo_p->item_count) {
- combo_p->selected_position = i;
- if (combo_p->type == XmDROP_DOWN_COMBO_BOX)
- SetTextFieldData(combo_p, NULL);
- else
- SetLabelData(combo_p, NULL, FALSE);
- XmListDeselectAllItems(combo_p->list);
- XmListAddItem(combo_p->list, item, 1);
- XmListSelectItem(combo_p->list, item, FALSE);
- XmListDeletePos(combo_p->list, combo_p->selected_position+2);
- combo_p->selected_position = 0;
- XmListSetPos(combo_p->list, 1);
- SyncWithList(combo_p);
- }
- else
- XtWarning(COMBO_SELECT_ITEM);
- }
- else
- XtWarning(COMBO_SELECT_ITEM);
- }
-
-
- /*
- * Synthetic GetValues for List resources.
- */
-
- static XmImportOperator
- _XmSetSyntheticResForChild(Widget widget,
- int offset,
- XtArgVal *value)
- {
- return(XmSYNTHETIC_LOAD);
- }
-
- void
- _DtComboBoxGetArrowSize(Widget w,
- int resource_offset,
- XtArgVal *value)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)w;
-
- *value = (XtArgVal)combo->combo_box.arrow->core.height;
- }
-
- void
- _DtComboBoxGetLabelString(Widget w,
- int resource_offset,
- XtArgVal *value)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)w;
-
- if (combo->combo_box.label_string)
- *value = (XtArgVal)XmStringCopy(combo->combo_box.label_string);
- else
- *value = (XtArgVal)NULL;
- }
-
- void
- _DtComboBoxGetListItemCount(Widget w,
- int resource_offset,
- XtArgVal *value)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)w;
- int data;
- Arg arg;
-
- XtSetArg(arg, XmNitemCount, &data);
- XtGetValues(combo->combo_box.list, &arg, 1);
- *value = (XtArgVal)data;
- }
-
- void
- _DtComboBoxGetListItems(Widget w,
- int resource_offset,
- XtArgVal *value)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)w;
- XmStringTable data;
- Arg arg;
-
- XtSetArg(arg, XmNitems, &data);
- XtGetValues(combo->combo_box.list, &arg, 1);
- *value = (XtArgVal)data;
- }
-
- void
- _DtComboBoxGetListFontList(Widget w,
- int resource_offset,
- XtArgVal *value)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)w;
- XmFontList data;
- Arg arg;
-
- XtSetArg(arg, XmNfontList, &data);
- XtGetValues(combo->combo_box.list, &arg, 1);
- *value = (XtArgVal)data;
- }
-
- void
- _DtComboBoxGetListMarginHeight(Widget w,
- int resource_offset,
- XtArgVal *value)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)w;
- Dimension data;
- Arg arg;
-
- XtSetArg(arg, XmNmarginHeight, &data);
- XtGetValues(combo->combo_box.list, &arg, 1);
- *value = (XtArgVal)data;
- }
-
- void
- _DtComboBoxGetListMarginWidth(Widget w,
- int resource_offset,
- XtArgVal *value)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)w;
- Dimension data;
- Arg arg;
-
- XtSetArg(arg, XmNmarginWidth, &data);
- XtGetValues(combo->combo_box.list, &arg, 1);
- *value = (XtArgVal)data;
- }
-
- void
- _DtComboBoxGetListSpacing(Widget w,
- int resource_offset,
- XtArgVal *value)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)w;
- Dimension data;
- Arg arg;
-
- XtSetArg(arg, XmNspacing, &data);
- XtGetValues(combo->combo_box.list, &arg, 1);
- *value = (XtArgVal)data;
- }
-
- void
- _DtComboBoxGetListTopItemPosition(Widget w,
- int resource_offset,
- XtArgVal *value)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)w;
- int data;
- Arg arg;
-
- XtSetArg(arg, XmNtopItemPosition, &data);
- XtGetValues(combo->combo_box.list, &arg, 1);
- *value = (XtArgVal)data;
- }
-
- void
- _DtComboBoxGetListVisibleItemCount(Widget w,
- int resource_offset,
- XtArgVal *value)
- {
- DtComboBoxWidget combo = (DtComboBoxWidget)w;
- int data;
- Arg arg;
-
- XtSetArg(arg, XmNvisibleItemCount, &data);
- XtGetValues(combo->combo_box.list, &arg, 1);
- *value = (XtArgVal)data;
- }
-