/***********************************************************************/ /* Open Visualization Data Explorer */ /* (C) Copyright IBM Corp. 1989,1999 */ /* ALL RIGHTS RESERVED */ /* This code licensed under the */ /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */ /***********************************************************************/ #include /* Construct and manage the "frame sequencer guide" to be used as a * popup of the "sequence controller" (alias VCR control) * * August 1990 * IBM T.J. Watson Research Center * R. T. Maganti */ /* */ /* * Templates of the local subroutines */ #ifdef OS2 #include #include #endif #include #include #include #include #include #include #include #include #include #include "Stepper.h" #include "Number.h" #include "SlideBar.h" #include "FrameControl.h" #include "FrameControlP.h" static void Initialize( XmFrameControlWidget request, XmFrameControlWidget new ); static Boolean SetValues( XmFrameControlWidget current, XmFrameControlWidget request, XmFrameControlWidget new ); static void Destroy( XmFrameControlWidget sw ); static void NumberFromGuide( XmSlideBarWidget slide_bar, XmFrameControlWidget frame_control, SlideBarCallbackStruct* call_data); static void CallbackFromNumber (XmNumberWidget w, XmFrameControlWidget frame_control, XmDoubleCallbackStruct* call_data); static XmNumberWidget CreateFrameControlNumber( int x,int y,int label_offset, int min,int value, int max, char* title, Widget *label, XmFrameControlWidget frame_control, Boolean above, Boolean editable, Boolean make_stepper, Boolean label_is_widget, Boolean create_arrow, Pixel color ); static Widget CreateNumberArrow(XmFrameControlWidget parent, Widget ref, int xpos, Pixel color); static void AdjustIncrementLimits (XmFrameControlWidget frame_control); static void ChangeSlideBarValue( XmFrameControlWidget frame_control, int value, int which, Boolean passed_from_outside ); extern void _XmForegroundColorDefault(); extern void _XmBackgroundColorDefault(); /* Declare defaults */ #define DEF_MIN 1 #define DEF_MAX 100 #define DEF_STEP 1 static XtResource resources[] = { { XmNstart, XmCStart, XmRShort, sizeof(short), XtOffset(XmFrameControlWidget, frame_control.start_value), XmRImmediate, (caddr_t) DEF_MIN }, { XmNnext, XmCNext, XmRShort, sizeof(short), XtOffset(XmFrameControlWidget, frame_control.next_value), XmRImmediate, (caddr_t) DEF_MIN }, { XmNcurrent, XmCCurrent, XmRShort, sizeof(short), XtOffset(XmFrameControlWidget, frame_control.current_value), XmRImmediate, (caddr_t) (DEF_MIN + 1) }, { XmNstop, XmCStop, XmRShort, sizeof(short), XtOffset(XmFrameControlWidget, frame_control.stop_value), XmRImmediate, (caddr_t) DEF_MIN }, { XmNminimum, XmCMinimum, XmRShort, sizeof(short), XtOffset(XmFrameControlWidget, frame_control.min_value), XmRImmediate, (caddr_t) DEF_MIN }, { XmNincrement, XmCIncrement, XmRShort, sizeof(short), XtOffset(XmFrameControlWidget, frame_control.increment), XmRImmediate, (caddr_t) DEF_MIN }, { XmNmaximum, XmCMaximum, XmRShort, sizeof(short), XtOffset(XmFrameControlWidget, frame_control.max_value), XmRImmediate, (caddr_t) DEF_MIN }, { XmNvalueCallback, XmCValueCallback, XmRCallback, sizeof(caddr_t), XtOffset(XmFrameControlWidget, frame_control.value_callback), XmRCallback, NULL }, { XmNlimitColor, XmCLimitColor, XmRPixel, sizeof(Pixel), XtOffset(XmFrameControlWidget, frame_control.limit_color), XmRCallProc, (caddr_t) _XmForegroundColorDefault }, { XmNnextColor, XmCNextColor, XmRPixel, sizeof(Pixel), XtOffset(XmFrameControlWidget, frame_control.next_color), XmRCallProc, (caddr_t) _XmForegroundColorDefault }, { XmNcurrentColor, XmCCurrentColor, XmRPixel, sizeof(Pixel), XtOffset(XmFrameControlWidget, frame_control.current_color), XmRCallProc, (caddr_t) _XmForegroundColorDefault }, { XmNcurrentVisible, XmCCurrentVisible, XmRBoolean, sizeof(Boolean), XtOffset(XmFrameControlWidget, frame_control.current_visible), XmRImmediate, (caddr_t) True }, { XmNminSensitive, XmCMinSensitive, XmRBoolean, sizeof(Boolean), XtOffset(XmFrameControlWidget, frame_control.min_sensitive), XmRImmediate, (caddr_t) TRUE }, { XmNmaxSensitive, XmCMaxSensitive, XmRBoolean, sizeof(Boolean), XtOffset(XmFrameControlWidget, frame_control.max_sensitive), XmRImmediate, (caddr_t) TRUE }, { XmNincSensitive, XmCIncSensitive, XmRBoolean, sizeof(Boolean), XtOffset(XmFrameControlWidget, frame_control.inc_sensitive), XmRImmediate, (caddr_t) TRUE }, }; /* Maintain actions support for basic manager functioning */ static char defaultTranslations[] = ": Enter() \n\ : FocusIn()"; extern void _XmManagerEnter(); extern void _XmManagerFocusIn(); static XtActionsRec actionsList[] = { { "Enter", (XtActionProc) _XmManagerEnter }, { "FocusIn", (XtActionProc) _XmManagerFocusIn }, }; /**************************************************************** * * Full class record constant * ****************************************************************/ XmFrameControlClassRec xmFrameControlClassRec = { { /* core_class fields */ (WidgetClass) &xmFormClassRec, /* superclass */ "XmFrameControl", /* class_name */ sizeof(XmFrameControlRec), /* widget_size */ NULL, /* class_initialize */ NULL, /* class_part_init */ FALSE, /* class_inited */ (XtInitProc) Initialize, /* initialize */ NULL, /* initialize_hook */ (XtRealizeProc)_XtInherit, /* realize */ actionsList, /* actions */ XtNumber(actionsList), /* num_actions */ resources, /* resources */ XtNumber(resources), /* num_resources */ NULLQUARK, /* xrm_class */ FALSE, /* compress_motion */ FALSE, /* compress_exposure */ TRUE, /* compress_enterlv */ FALSE, /* visible_interest */ (XtWidgetProc) Destroy, /* destroy */ (XtWidgetProc)_XtInherit, /* resize */ (XtExposeProc)_XtInherit, /* expose */ (XtSetValuesFunc) SetValues, /* set_values */ NULL, /* set_values_hook */ (XtAlmostProc)_XtInherit, /* set_values_almost */ NULL, /* get_values_hook */ NULL, /* accept_focus */ XtVersion, /* version */ NULL, /* callback_private */ defaultTranslations, /* tm_table */ NULL, /* query_geometry */ NULL, /* display_accelerator */ NULL, /* extension */ }, { /* composite_class fields */ XtInheritGeometryManager, /* geometry_manager */ (XtWidgetProc)_XtInherit, /* from BulletinBoard *//* change_managed */ (XtWidgetProc)_XtInherit, /* insert_child */ (XtWidgetProc)_XtInherit, /* delete_child */ NULL, /* extension */ }, { /* constraint_class fields */ NULL, /* resource list */ 0, /* num resources */ sizeof(XmFormConstraintRec), /* constraint size */ NULL, /* init proc */ NULL, /* destroy proc */ NULL, /* set values proc */ NULL, /* extension */ }, { /* manager_class fields */ #if (XmVersion >= 1001) XtInheritTranslations, /* translations */ #else (XtTranslations)_XtInherit, /* translations */ #endif NULL, /* get resources */ 0, /* num get_resources */ NULL, /* get_cont_resources */ 0, /* num_get_cont_resources */ (XmParentProcessProc)NULL, /* parent_process */ NULL, /* extension */ }, { /* bulletin board class - none */ NULL, /* mumble */ NULL, /* mumble */ }, { /* form class - none */ NULL, /* mumble */ }, { /* frame_control class - none */ NULL, /* mumble */ } }; WidgetClass xmFrameControlWidgetClass = (WidgetClass) &xmFrameControlClassRec; /* Subroutine: Initialize * Purpose: Create and Initialize the component widgets */ static void Initialize( XmFrameControlWidget request, XmFrameControlWidget new ) { Arg wargs[32]; XColor screen_color, exact_color; int n; char string[100]; XmString xmstring; Widget arrow; Widget w; /* Windows are mapped in reverse order, those created first are on top */ new->frame_control.next_number = CreateFrameControlNumber(38, 15, 3, new->frame_control.start_value, new->frame_control.next_value, new->frame_control.stop_value, "Next", (Widget *)&new->frame_control.next_label, new, TRUE, TRUE, TRUE, TRUE, TRUE, new->frame_control.next_color); new->frame_control.start_number = CreateFrameControlNumber(5, 15, 3, new->frame_control.min_value, new->frame_control.start_value, new->frame_control.stop_value, "Start", (Widget *)&new->frame_control.start_label, new, TRUE, TRUE, TRUE, FALSE, TRUE, new->frame_control.limit_color); new->frame_control.stop_number = CreateFrameControlNumber(70, 15, 3, new->frame_control.start_value, new->frame_control.stop_value, new->frame_control.max_value, "End", (Widget *)&new->frame_control.stop_label, new, TRUE, TRUE, TRUE, FALSE, TRUE, new->frame_control.limit_color); new->frame_control.inc_stepper = (XmStepperWidget) CreateFrameControlNumber(38, 75, 3, 1, new->frame_control.increment, 16383, "Increment", (Widget *)&new->frame_control.inc_label, new, FALSE, TRUE, TRUE, TRUE, FALSE, NULL); new->frame_control.min_number = CreateFrameControlNumber(12, 75, 2, -16383, new->frame_control.min_value, 16383, "Min", (Widget *)&new->frame_control.min_label, new, FALSE, TRUE, FALSE, FALSE, FALSE, NULL); new->frame_control.max_number = CreateFrameControlNumber(79, 75, 2, -16383, new->frame_control.max_value, 16383, "Max", (Widget *)&new->frame_control.max_label, new, FALSE, TRUE, FALSE, FALSE, FALSE, NULL); /* Create the actual frame_control part of the popup */ n = 0; XtSetArg(wargs[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNtopPosition, 47); n++; XtSetArg(wargs[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(wargs[n], XmNleftOffset, 5); n++; XtSetArg(wargs[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(wargs[n], XmNrightOffset, 5); n++; #ifdef COMMENT XtSetArg(wargs[n], XmNbottomAttachment, XmATTACH_NONE); n++; #endif XtSetArg(wargs[n], XmNstart, new->frame_control.start_value); n++; XtSetArg(wargs[n], XmNstop, new->frame_control.stop_value); n++; XtSetArg(wargs[n], XmNnext, new->frame_control.next_value); n++; XtSetArg(wargs[n], XmNmaxValue, new->frame_control.max_value); n++; XtSetArg(wargs[n], XmNmarkColor, new->frame_control.next_color); n++; XtSetArg(wargs[n], XmNcurrentColor, new->frame_control.current_color); n++; XtSetArg(wargs[n], XmNlimitColor, new->frame_control.limit_color); n++; XtSetArg(wargs[n], XmNwidth, new->core.width); n++; XtSetArg(wargs[n], XmNheight, new->core.height); n++; XtSetArg(wargs[n], XmNminValue, new->frame_control.min_value); n++; XtSetArg(wargs[n], XmNcurrent, new->frame_control.current_value); n++; XtSetArg(wargs[n], XmNcurrentVisible, new->frame_control.current_visible); n++; new->frame_control.bar = (XmSlideBarWidget)XmCreateSlideBar ((Widget)new, "frame_control_bar", wargs, n); XtAddCallback ((Widget)new->frame_control.bar, XmNvalueCallback, (XtCallbackProc)NumberFromGuide, new); XtManageChild((Widget)new->frame_control.bar); /* Set up "current" arrow */ n = 0; XtSetArg(wargs[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(wargs[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(wargs[n], XmNleftPosition, 39); n++; XtSetArg(wargs[n], XmNtopPosition, 36); n++; XtSetArg(wargs[n], XmNwidth, 16); n++; XtSetArg(wargs[n], XmNheight, 16); n++; XtSetArg(wargs[n], XmNforeground, new->frame_control.current_color); n++; XtSetArg(wargs[n], XmNarrowDirection, XmARROW_DOWN); n++; XtSetArg(wargs[n], XmNshadowThickness, 0); n++; arrow = XmCreateArrowButton((Widget)new, "arrow2", wargs, n); XtManageChild(arrow); /* Set up "current" label */ n = 0; XtSetArg(wargs[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(wargs[n], XmNbottomAttachment, XmATTACH_NONE); n++; XtSetArg(wargs[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(wargs[n], XmNresizable, False); n++; XtSetArg(wargs[n], XmNleftWidget, arrow); n++; XtSetArg(wargs[n], XmNtopPosition, 35); n++; /* Create a large label, so subsequent resizes are not a problem */ if (new->frame_control.current_visible) { sprintf(string,"Current: %d ",new->frame_control.current_value); } else { sprintf(string,"Current: "); } xmstring = XmStringCreate(string, XmSTRING_DEFAULT_CHARSET); XtSetArg(wargs[n], XmNlabelString, xmstring); n++; new->frame_control.current_label = (XmLabelWidget)XmCreateLabel((Widget)new,"label", wargs, n); XmStringFree(xmstring); XtManageChild((Widget)new->frame_control.current_label); n = 0; XtSetArg(wargs[n], XmNtitle, "Frame Control Warning"); n++; new->frame_control.warning_dialog = XmCreateWarningDialog(XtParent(new), "FCWarning", wargs, n); XtUnmanageChild(XmMessageBoxGetChild(new->frame_control.warning_dialog, XmDIALOG_CANCEL_BUTTON)); XtUnmanageChild(XmMessageBoxGetChild(new->frame_control.warning_dialog, XmDIALOG_HELP_BUTTON)); } static Boolean SetValues( XmFrameControlWidget current, XmFrameControlWidget request, XmFrameControlWidget new ) { Arg wargs[16]; double dval; FrameControlCallbackStruct callback_data; int n; char string[100]; XmString xmstring; if(new->frame_control.current_visible != current->frame_control.current_visible) { XtSetArg(wargs[0], XmNcurrentVisible, new->frame_control.current_visible); XtSetValues((Widget)new->frame_control.bar, wargs, 1); if (new->frame_control.current_visible) { sprintf(string,"Current: %d",new->frame_control.current_value); } else { sprintf(string,"Current:"); } xmstring = XmStringCreate(string, XmSTRING_DEFAULT_CHARSET); n = 0; XtSetArg(wargs[n], XmNlabelString, xmstring); n++; XtSetValues((Widget)new->frame_control.current_label, wargs, n); XmStringFree(xmstring); } if(new->frame_control.current_value != current->frame_control.current_value) { XtSetArg(wargs[0], XmNcurrent, new->frame_control.current_value); XtSetValues((Widget)new->frame_control.bar, wargs, 1); if (new->frame_control.current_visible) { sprintf(string,"Current: %d",new->frame_control.current_value); } else { sprintf(string,"Current:"); } xmstring = XmStringCreate(string, XmSTRING_DEFAULT_CHARSET); n = 0; XtSetArg(wargs[n], XmNlabelString, xmstring); n++; XtSetValues((Widget)new->frame_control.current_label, wargs, n); XmStringFree(xmstring); } if(new->frame_control.start_value != current->frame_control.start_value) { XtSetArg(wargs[0], XmNstart, new->frame_control.start_value); XtSetValues((Widget)new->frame_control.bar, wargs, 1); dval = new->frame_control.start_value; DoubleSetArg(wargs[0], XmNdValue, dval); XtSetValues((Widget)new->frame_control.start_number, wargs, 1); DoubleSetArg(wargs[0], XmNdMinimum, dval); XtSetValues((Widget)new->frame_control.next_number, wargs, 1); XtSetValues((Widget)new->frame_control.stop_number, wargs, 1); } if(new->frame_control.stop_value != current->frame_control.stop_value) { XtSetArg(wargs[0], XmNstop, new->frame_control.stop_value); XtSetValues((Widget)new->frame_control.bar, wargs, 1); dval = new->frame_control.stop_value; DoubleSetArg(wargs[0], XmNdValue, dval); XtSetValues((Widget)new->frame_control.stop_number, wargs, 1); DoubleSetArg(wargs[0], XmNdMaximum, dval); XtSetValues((Widget)new->frame_control.start_number, wargs, 1); XtSetValues((Widget)new->frame_control.next_number, wargs, 1); } if(new->frame_control.next_value != current->frame_control.next_value) { XtSetArg(wargs[0], XmNnext, new->frame_control.next_value); XtSetValues((Widget)new->frame_control.bar, wargs, 1); dval = new->frame_control.next_value; DoubleSetArg(wargs[0], XmNdValue, dval); XtSetValues((Widget)new->frame_control.next_number, wargs, 1); } if(new->frame_control.increment != current->frame_control.increment) { dval = new->frame_control.increment; DoubleSetArg(wargs[0], XmNdValue, dval); XtSetValues((Widget)new->frame_control.inc_stepper, wargs, 1); } if(new->frame_control.min_value != current->frame_control.min_value) { dval = (double)new->frame_control.min_value; DoubleSetArg(wargs[0], XmNdValue, dval); XtSetValues((Widget)new->frame_control.min_number, wargs, 1); if (new->frame_control.start_value < new->frame_control.min_value) { n = 0; new->frame_control.start_value = new->frame_control.min_value; DoubleSetArg(wargs[n], XmNdValue, dval); n++; DoubleSetArg(wargs[n], XmNdMinimum, dval); n++; if (new->frame_control.min_value > new->frame_control.stop_value) { DoubleSetArg(wargs[n], XmNdMaximum, dval); n++; } XtSetValues((Widget)new->frame_control.start_number, wargs, n); DoubleSetArg(wargs[0], XmNdMinimum, dval); XtSetValues((Widget)new->frame_control.next_number, wargs, 1); XtSetValues((Widget)new->frame_control.stop_number, wargs, 1); callback_data.reason = XmCR_START; callback_data.value = new->frame_control.min_value; XtCallCallbacks((Widget)new, XmNvalueCallback, &callback_data); if (new->frame_control.next_value < new->frame_control.min_value) { n = 0; new->frame_control.next_value = new->frame_control.start_value; DoubleSetArg(wargs[n], XmNdValue, dval); n++; DoubleSetArg(wargs[n], XmNdMinimum, dval); n++; if (new->frame_control.min_value > new->frame_control.stop_value) { DoubleSetArg(wargs[n], XmNdMaximum, dval); n++; } XtSetValues((Widget)new->frame_control.next_number, wargs, n); callback_data.reason = XmCR_NEXT; callback_data.value = new->frame_control.start_value; XtCallCallbacks((Widget)new, XmNvalueCallback, &callback_data); if (new->frame_control.stop_value frame_control.min_value) { new->frame_control.stop_value =new->frame_control.min_value; n = 0; DoubleSetArg(wargs[n], XmNdValue, dval); n++; DoubleSetArg(wargs[n], XmNdMinimum, dval); n++; if (new->frame_control.min_value > new->frame_control.max_value) { DoubleSetArg(wargs[n], XmNdMaximum, dval); n++; } XtSetValues((Widget)new->frame_control.stop_number, wargs, n); callback_data.reason = XmCR_STOP; callback_data.value = new->frame_control.stop_value; XtCallCallbacks((Widget)new, XmNvalueCallback, &callback_data); if (new->frame_control.min_value > new->frame_control.max_value) { new->frame_control.max_value = new->frame_control.min_value; DoubleSetArg(wargs[0], XmNdValue, dval); XtSetValues((Widget)new->frame_control.max_number, wargs, 1); } } } } DoubleSetArg(wargs[0], XmNdMinimum, dval); XtSetValues((Widget)new->frame_control.start_number, wargs, 1); XtSetArg(wargs[0], XmNminValue, new->frame_control.min_value); XtSetArg(wargs[1], XmNmaxValue, new->frame_control.max_value); XtSetArg(wargs[2], XmNstart, new->frame_control.start_value); XtSetArg(wargs[3], XmNstop, new->frame_control.stop_value); XtSetArg(wargs[4], XmNnext, new->frame_control.next_value); XtSetValues((Widget)new->frame_control.bar, wargs, 5); } if(new->frame_control.max_value != current->frame_control.max_value) { dval = (double)new->frame_control.max_value; DoubleSetArg(wargs[0], XmNdValue, dval); XtSetValues((Widget)new->frame_control.max_number, wargs, 1); if (new->frame_control.stop_value > new->frame_control.max_value) { n = 0; new->frame_control.stop_value = new->frame_control.max_value; DoubleSetArg(wargs[n], XmNdValue, dval); n++; DoubleSetArg(wargs[n], XmNdMaximum, dval); n++; if (new->frame_control.max_value < new->frame_control.start_value) { DoubleSetArg(wargs[n], XmNdMinimum, dval); n++; } XtSetValues((Widget)new->frame_control.stop_number, wargs, n); DoubleSetArg(wargs[0], XmNdMaximum, dval); XtSetValues((Widget)new->frame_control.start_number, wargs, 1); XtSetValues((Widget)new->frame_control.next_number, wargs, 1); callback_data.reason = XmCR_STOP; callback_data.value = new->frame_control.max_value; XtCallCallbacks((Widget)new, XmNvalueCallback, &callback_data); if (new->frame_control.next_value > new->frame_control.max_value) { n = 0; new->frame_control.next_value = new->frame_control.stop_value; DoubleSetArg(wargs[n], XmNdValue, dval); n++; DoubleSetArg(wargs[n], XmNdMaximum, dval); n++; if (new->frame_control.max_value < new->frame_control.start_value) { DoubleSetArg(wargs[n], XmNdMinimum, dval); n++; } XtSetValues((Widget)new->frame_control.next_number, wargs, n); callback_data.reason = XmCR_NEXT; callback_data.value = new->frame_control.stop_value; XtCallCallbacks((Widget)new, XmNvalueCallback, &callback_data); if (new->frame_control.start_value > new->frame_control.max_value) { new->frame_control.start_value = new->frame_control.stop_value; n = 0; DoubleSetArg(wargs[n], XmNdValue, dval); n++; DoubleSetArg(wargs[n], XmNdMaximum, dval); n++; if (new->frame_control.max_value < new->frame_control.min_value) { DoubleSetArg(wargs[n], XmNdMinimum, dval); n++; } XtSetValues((Widget)new->frame_control.start_number, wargs, n); callback_data.reason = XmCR_START; callback_data.value = new->frame_control.start_value; XtCallCallbacks((Widget)new, XmNvalueCallback, &callback_data); if (new->frame_control.min_value > new->frame_control.max_value) { new->frame_control.min_value = new->frame_control.max_value; DoubleSetArg(wargs[0], XmNdValue, dval); XtSetValues((Widget)new->frame_control.min_number, wargs, 1); } } } } DoubleSetArg(wargs[0], XmNdMaximum, dval); XtSetValues((Widget)new->frame_control.stop_number, wargs, 1); XtSetArg(wargs[0], XmNminValue, new->frame_control.min_value); XtSetArg(wargs[1], XmNmaxValue, new->frame_control.max_value); XtSetArg(wargs[2], XmNstart, new->frame_control.start_value); XtSetArg(wargs[3], XmNstop, new->frame_control.stop_value); XtSetArg(wargs[4], XmNnext, new->frame_control.next_value); XtSetValues((Widget)new->frame_control.bar, wargs, 5); } if(new->frame_control.current_color != current->frame_control.current_color) { XtSetArg(wargs[0], XmNcurrentColor, new->frame_control.current_color); XtSetValues((Widget)new->frame_control.bar, wargs, 1); /* Set the color of the associated label widget */ XtSetArg(wargs[0], XmNforeground, new->frame_control.current_color); XtSetValues((Widget)new->frame_control.current_label, wargs, 1); } if(new->frame_control.next_color != current->frame_control.next_color) { XtSetArg(wargs[0], XmNmarkColor, new->frame_control.next_color); XtSetValues((Widget)new->frame_control.bar, wargs, 1); /* Set the color of the associated label widget */ XtSetArg(wargs[0], XmNforeground, new->frame_control.next_color); XtSetValues((Widget)new->frame_control.next_label, wargs, 1); } if(new->frame_control.limit_color != current->frame_control.limit_color) { XtSetArg(wargs[0], XmNlimitColor, new->frame_control.limit_color); XtSetValues((Widget)new->frame_control.bar, wargs, 1); /* Set the color of the associated label widget */ XtSetArg(wargs[0], XmNforeground, new->frame_control.limit_color); XtSetValues((Widget)new->frame_control.start_label, wargs, 1); /* Set the color of the associated label widget */ XtSetArg(wargs[0], XmNforeground, new->frame_control.limit_color); XtSetValues((Widget)new->frame_control.stop_label, wargs, 1); } if(new->frame_control.min_sensitive != current->frame_control.min_sensitive) { XtSetSensitive((Widget)new->frame_control.min_number, new->frame_control.min_sensitive); } if(new->frame_control.max_sensitive != current->frame_control.max_sensitive) { XtSetSensitive((Widget)new->frame_control.max_number, new->frame_control.max_sensitive); } if(new->frame_control.inc_sensitive != current->frame_control.inc_sensitive) { XtSetSensitive((Widget)new->frame_control.inc_stepper, new->frame_control.inc_sensitive); } XFlush(XtDisplay(new)); return True; } static void Destroy( XmFrameControlWidget sw ) { XtRemoveAllCallbacks((Widget)sw, XmNvalueCallback); } /* Subroutine: CreateNumber Arrow * Purpose: Create the arrow indicator on top of the Stepper */ static Widget CreateNumberArrow(XmFrameControlWidget parent, Widget ref, int xpos, Pixel color) { Arg wargs[30]; int n; Widget arrow; n = 0; XtSetArg(wargs[n], XmNtopAttachment, XmATTACH_NONE); n++; XtSetArg(wargs[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(wargs[n], XmNrightAttachment, XmATTACH_NONE); n++; XtSetArg(wargs[n], XmNleftPosition, xpos); n++; XtSetArg(wargs[n], XmNbottomWidget, ref); n++; XtSetArg(wargs[n], XmNbottomOffset, 3); n++; XtSetArg(wargs[n], XmNwidth, 16); n++; XtSetArg(wargs[n], XmNheight, 16); n++; XtSetArg(wargs[n], XmNforeground, color); n++; XtSetArg(wargs[n], XmNarrowDirection, XmARROW_DOWN); n++; XtSetArg(wargs[n], XmNshadowThickness, 0); n++; arrow = XmCreateArrowButton((Widget)parent, "arrow", wargs, n); XtManageChild(arrow); return arrow; } /* Subroutine: CreateFrameControlNumber * Purpose: Handle creation of number (digital readout) widget */ static XmNumberWidget CreateFrameControlNumber( int x, int y, int label_offset, int min, int value, int max, char* title, Widget *label, XmFrameControlWidget fc, Boolean above, Boolean editable, Boolean make_stepper, Boolean label_is_widget, Boolean create_arrow, Pixel color ) { Arg wargs[20]; double dmin, dmax, dval; Widget number; Widget arrow; XmString text; int len; /* * Create the panel-meter like number display */ /* The stepper's values are absolute */ dmin = (double)min; dmax = (double)max; dval = (double)value; /* Placement gets recomputed in the expose callback */ XtSetArg(wargs[0], XmNtopAttachment, XmATTACH_POSITION); XtSetArg(wargs[1], XmNleftAttachment, XmATTACH_POSITION); XtSetArg(wargs[2], XmNbottomAttachment, XmATTACH_NONE); XtSetArg(wargs[3], XmNrightAttachment, XmATTACH_NONE); XtSetArg(wargs[4], XmNleftPosition, x); XtSetArg(wargs[5], XmNtopPosition, y); /* Estimate a comfortably large size to initially create NumberWidget */ XtSetArg(wargs[6], XmNheight, 19); DoubleSetArg(wargs[7], XmNdMinimum, dmin); DoubleSetArg(wargs[8], XmNdMaximum, dmax); DoubleSetArg(wargs[9], XmNdValue, dval); XtSetArg(wargs[10], XmNdecimalPlaces, 0); /* Center text in the field and resize for tighter fit of font */ XtSetArg(wargs[12], XmNcenter, TRUE); XtSetArg(wargs[13], XmNrecomputeSize, FALSE); if( editable ) XtSetArg(wargs[14], XmNeditable, TRUE); else XtSetArg(wargs[14], XmNeditable, FALSE); if( make_stepper ) { XtSetArg(wargs[11], XmNdigits, 7); XtSetArg(wargs[15], XmNdataType, DOUBLE); number = XmCreateStepper((Widget)fc, title, wargs, 16); } else { XtSetArg(wargs[11], XmNcharPlaces, 7); XtSetArg(wargs[15], XmNdataType, DOUBLE); number = XmCreateNumber((Widget)fc, title, wargs, 16); } /* Callback for when a new value is entered directly */ XtAddCallback((Widget)number, XmNactivateCallback, (XtCallbackProc)CallbackFromNumber, fc); XtManageChild(number); if (create_arrow) { arrow = CreateNumberArrow(fc, number, x + label_offset, color); } if(create_arrow) { XtSetArg(wargs[0], XmNleftAttachment, XmATTACH_WIDGET); XtSetArg(wargs[1], XmNleftWidget, arrow); } else { XtSetArg(wargs[0], XmNleftAttachment, XmATTACH_POSITION); XtSetArg(wargs[1], XmNleftPosition, x + label_offset); } XtSetArg(wargs[2], XmNrightAttachment, XmATTACH_NONE); if( above ) { XtSetArg(wargs[3], XmNtopAttachment, XmATTACH_NONE); XtSetArg(wargs[4], XmNbottomAttachment, XmATTACH_WIDGET); XtSetArg(wargs[5], XmNbottomWidget, number); } else { XtSetArg(wargs[3], XmNtopAttachment, XmATTACH_WIDGET); XtSetArg(wargs[4], XmNbottomAttachment, XmATTACH_NONE); XtSetArg(wargs[5], XmNtopWidget, number); } XtSetArg(wargs[6], XmNleftOffset, label_offset); /* Create the string for the label, and then the label */ text = XmStringCreate(title, XmSTRING_DEFAULT_CHARSET); XtSetArg(wargs[7], XmNlabelString, text); *label = XmCreateLabel((Widget)fc, "label", wargs, 8); XtManageChild(*label); XmStringFree(text); return (XmNumberWidget)number; } /* Subroutine: NumberFromGuide * Purpose: Change all values necessary in response to a value change * from user manipulation of the VCR frame_control * Note: DISARM is a final value after the frame_control is released * Note: Numbers and ChangeVCRxxValue use external (min based) values */ static void NumberFromGuide( XmSlideBarWidget slide_bar, XmFrameControlWidget fc, SlideBarCallbackStruct* call_data) { Arg wargs[2]; double dval; FrameControlCallbackStruct callback_data; if( call_data->indicator == XmCR_START ) { fc->frame_control.start_value = call_data->value; dval = fc->frame_control.start_value; DoubleSetArg(wargs[0], XmNdValue, dval); XtSetValues((Widget)fc->frame_control.start_number, wargs, 1); if(call_data->reason==XmCR_DISARM) { dval = (double)(call_data->value); DoubleSetArg(wargs[0], XmNdMinimum, dval); XtSetValues((Widget)fc->frame_control.next_number, wargs, 1); XtSetValues((Widget)fc->frame_control.stop_number, wargs, 1); callback_data.reason = XmCR_START; callback_data.value = call_data->value; XtCallCallbacks((Widget)fc, XmNvalueCallback, &callback_data); AdjustIncrementLimits(fc); } } else if( call_data->indicator == XmCR_STOP ) { fc->frame_control.stop_value = call_data->value; dval = fc->frame_control.stop_value; DoubleSetArg(wargs[0], XmNdValue, dval); XtSetValues((Widget)fc->frame_control.stop_number, wargs, 1); if(call_data->reason==XmCR_DISARM) { dval = (double)(call_data->value); DoubleSetArg(wargs[0], XmNdMaximum, dval); XtSetValues((Widget)fc->frame_control.start_number, wargs, 1); XtSetValues((Widget)fc->frame_control.next_number, wargs, 1); callback_data.reason = XmCR_STOP; callback_data.value = call_data->value; XtCallCallbacks((Widget)fc, XmNvalueCallback, &callback_data); AdjustIncrementLimits(fc); } } else { fc->frame_control.next_value = call_data->value; dval = fc->frame_control.next_value; DoubleSetArg(wargs[0], XmNdValue, dval); XtSetValues((Widget)fc->frame_control.next_number, wargs, 1); if(call_data->reason==XmCR_DISARM) { callback_data.reason = XmCR_NEXT; callback_data.value = call_data->value; XtCallCallbacks((Widget)fc, XmNvalueCallback, &callback_data); } } } /* Subroutine: CallbackFromNumber * Purpose: Callback routine from number widget to allow/disallow stepper * to manipulate the value, or to set a new value. */ static void CallbackFromNumber( XmNumberWidget nw, XmFrameControlWidget fc, XmDoubleCallbackStruct* call_data ) { int value, which; FrameControlCallbackStruct callback_data; Arg wargs[10]; double dval; XmString xms; XtArgVal dx_l; if( call_data->reason == XmCR_ACTIVATE ) { if (call_data->value > 0) { value = (int)(call_data->value + 0.5); } else { value = (int)(call_data->value - 0.5); } dval = call_data->value; if( nw == fc->frame_control.start_number ) { fc->frame_control.start_value = value; if (fc->frame_control.start_value > fc->frame_control.next_value) { fc->frame_control.next_value = value; DoubleSetArg(wargs[0], XmNdValue, dval); XtSetValues((Widget)fc->frame_control.next_number, wargs, 1); callback_data.reason = XmCR_NEXT; callback_data.value = value; XtCallCallbacks((Widget)fc, XmNvalueCallback, &callback_data); } if (fc->frame_control.start_value > fc->frame_control.stop_value) { fc->frame_control.stop_value = value; DoubleSetArg(wargs[0], XmNdValue, dval); XtSetValues((Widget)fc->frame_control.stop_number, wargs, 1); callback_data.reason = XmCR_STOP; callback_data.value = value; XtCallCallbacks((Widget)fc, XmNvalueCallback, &callback_data); } which = XmCR_START; callback_data.reason = XmCR_START; callback_data.value = value; XtCallCallbacks((Widget)fc, XmNvalueCallback, &callback_data); ChangeSlideBarValue(fc, value, which, FALSE); } else if( nw == fc->frame_control.next_number ) { fc->frame_control.next_value = value; if (fc->frame_control.next_value > fc->frame_control.stop_value) { fc->frame_control.stop_value = value; DoubleSetArg(wargs[0], XmNdValue, dval); XtSetValues((Widget)fc->frame_control.stop_number, wargs, 1); callback_data.reason = XmCR_STOP; callback_data.value = value; XtCallCallbacks((Widget)fc, XmNvalueCallback, &callback_data); } if (fc->frame_control.next_value < fc->frame_control.start_value) { fc->frame_control.start_value = value; DoubleSetArg(wargs[0], XmNdValue, dval); XtSetValues((Widget)fc->frame_control.start_number, wargs, 1); callback_data.reason = XmCR_START; callback_data.value = value; XtCallCallbacks((Widget)fc, XmNvalueCallback, &callback_data); } which = XmCR_NEXT; callback_data.reason = XmCR_NEXT; callback_data.value = value; XtCallCallbacks((Widget)fc, XmNvalueCallback, &callback_data); ChangeSlideBarValue(fc, value, which, FALSE); } else if( nw == fc->frame_control.stop_number ) { fc->frame_control.stop_value = value; if (fc->frame_control.stop_value < fc->frame_control.next_value) { fc->frame_control.next_value = value; DoubleSetArg(wargs[0], XmNdValue, dval); XtSetValues((Widget)fc->frame_control.next_number, wargs, 1); callback_data.reason = XmCR_NEXT; callback_data.value = value; XtCallCallbacks((Widget)fc, XmNvalueCallback, &callback_data); } if (fc->frame_control.stop_value < fc->frame_control.start_value) { fc->frame_control.start_value = value; DoubleSetArg(wargs[0], XmNdValue, dval); XtSetValues((Widget)fc->frame_control.start_number, wargs, 1); callback_data.reason = XmCR_START; callback_data.value = value; XtCallCallbacks((Widget)fc, XmNvalueCallback, &callback_data); } which = XmCR_STOP; callback_data.reason = XmCR_STOP; callback_data.value = value; XtCallCallbacks((Widget)fc, XmNvalueCallback, &callback_data); ChangeSlideBarValue(fc, value, which, FALSE); } else if( nw == fc->frame_control.min_number ) { if(!fc->frame_control.max_sensitive) { XtVaGetValues((Widget)fc->frame_control.max_number, XmNdValue, DoubleVal(dval, dx_l), NULL); if(value > dval) { XtVaSetValues((Widget)fc->frame_control.min_number, XmNdValue, DoubleVal(dval, dx_l), NULL); value = dval; xms = XmStringCreateSimple("Min must be less than data driven max"); XtVaSetValues((Widget)fc->frame_control.warning_dialog, XmNmessageString, xms, NULL); XmStringFree(xms); XtManageChild((Widget)fc->frame_control.warning_dialog); } } XtSetArg(wargs[0], XmNminimum, value); XtSetValues((Widget)fc, wargs, 1); callback_data.reason = XmCR_MIN; callback_data.value = value; XtCallCallbacks((Widget)fc, XmNvalueCallback, &callback_data); } else if( nw == fc->frame_control.max_number ) { if(!fc->frame_control.min_sensitive) { XtVaGetValues((Widget)fc->frame_control.min_number, XmNdValue, DoubleVal(dval, dx_l), NULL); if(value < dval) { XtVaSetValues((Widget)fc->frame_control.max_number, XmNdValue, DoubleVal(dval, dx_l), NULL); value = dval; xms = XmStringCreateSimple("Max must be greater than data driven min"); XtVaSetValues((Widget)fc->frame_control.warning_dialog, XmNmessageString, xms, NULL); XmStringFree(xms); XtManageChild((Widget)fc->frame_control.warning_dialog); } } XtSetArg(wargs[0], XmNmaximum, value); XtSetValues((Widget)fc, wargs, 1); callback_data.reason = XmCR_MAX; callback_data.value = value; XtCallCallbacks((Widget)fc, XmNvalueCallback, &callback_data); } else { if( (XmStepperWidget)nw == fc->frame_control.inc_stepper ) { fc->frame_control.increment = value; callback_data.reason = XmCR_INCREMENT; callback_data.value = value; XtCallCallbacks((Widget)fc, XmNvalueCallback, &callback_data); } return; } } } /* Subroutine: ChangeSlideBarValue * Purpose: Adjust the guidebar markers and digital readouts for a new value */ static void ChangeSlideBarValue( XmFrameControlWidget fc, int value, int which, Boolean passed_from_outside ) { Arg wargs[2]; double dval; int ival; /* Digital readout numbers are min based and double */ dval = (double)(value); if( which == XmCR_START ) { fc->frame_control.start_value = value; /* Reposition the frame_control marker */ XtSetArg(wargs[0], XmNstart, fc->frame_control.start_value); XtSetValues((Widget)fc->frame_control.bar, wargs, 1); /* Change the digital readout if it wasn't the source */ if( passed_from_outside ) { DoubleSetArg(wargs[0], XmNdValue, dval); XtSetValues((Widget)fc->frame_control.next_number, wargs, 1); } /* Reposition next value indicators if it was affected */ if( fc->frame_control.start_value > fc->frame_control.next_value ) { fc->frame_control.next_value = fc->frame_control.start_value; XtSetArg(wargs[0], XmNnext, fc->frame_control.next_value); XtSetValues((Widget)fc->frame_control.bar, wargs, 1); DoubleSetArg(wargs[0], XmNdValue, dval); XtSetValues((Widget)fc->frame_control.next_number, wargs, 1); } /* Reset the minimums on the next and stop digital readouts */ DoubleSetArg(wargs[0], XmNdMinimum, dval); XtSetValues((Widget)fc->frame_control.next_number, wargs, 1); XtSetValues((Widget)fc->frame_control.stop_number, wargs, 1); AdjustIncrementLimits(fc); } else if( which == XmCR_NEXT ) { fc->frame_control.next_value = value; /* Reposition the frame_control marker */ XtSetArg(wargs[0], XmNnext, fc->frame_control.next_value); XtSetValues((Widget)fc->frame_control.bar, wargs, 1); /* Change the digital readout if it wasn't the source */ if( passed_from_outside ) { DoubleSetArg(wargs[0], XmNdValue, dval); XtSetValues((Widget)fc->frame_control.next_number, wargs, 1); } } else if( which == XmCR_STOP ) { fc->frame_control.stop_value = value; /* Reposition the frame_control marker */ XtSetArg(wargs[0], XmNstop, fc->frame_control.stop_value); XtSetValues((Widget)fc->frame_control.bar, wargs, 1); /* Change the digital readout if it wasn't the source */ if( passed_from_outside ) { DoubleSetArg(wargs[0], XmNdValue, dval); XtSetValues((Widget)fc->frame_control.stop_number, wargs, 1); } /* Reposition next value indicators if it was affected */ if( fc->frame_control.stop_value < fc->frame_control.next_value ) { fc->frame_control.next_value = fc->frame_control.stop_value; XtSetArg(wargs[0], XmNnext, fc->frame_control.next_value); XtSetValues((Widget)fc->frame_control.bar, wargs, 1); DoubleSetArg(wargs[0], XmNdValue, dval); XtSetValues((Widget)fc->frame_control.next_number, wargs, 1); } /* Reset the maximums on the next and start digital readouts */ DoubleSetArg(wargs[0], XmNdMaximum, dval); XtSetValues((Widget)fc->frame_control.start_number, wargs, 1); XtSetValues((Widget)fc->frame_control.next_number, wargs, 1); AdjustIncrementLimits(fc); } else if( which == XmCR_INCREMENT ) { /* Application is responsible for making sure this is within range */ XtSetArg(wargs[0], XmNiValue, value); XtSetValues((Widget)fc->frame_control.inc_stepper, wargs, 1); } } /* Subroutine: AdjustIncrementLimits * Purpose: Adjust the max limit of the increment stepper to reflect * the current range */ static void AdjustIncrementLimits( XmFrameControlWidget fc ) { Arg wargs[2]; int ival; #ifdef Comment /* Set the upper bound on the increment, but not less than the inc */ ival = fc->frame_control.stop_value - fc->frame_control.start_value; if( ival < fc->frame_control.increment ) ival = fc->frame_control.increment; XtSetArg(wargs[0], XmNiMaximum, ival); XtSetValues((Widget)fc->frame_control.inc_stepper, wargs, 1); #endif } /* Subroutine: XmCreateFrameControl * Purpose: This function creates and returns a FrameControl widget. */ Widget XmCreateFrameControl( Widget parent, char *name, ArgList args, Cardinal num_args) { return (XtCreateWidget(name, xmFrameControlWidgetClass, parent, args, num_args)); }