This is Range.c in view mode; [Download] [Up]
#if ( !defined(lint) && !defined(SABER)) static char PCN_rcsid[] = "$Header: /ufs/comp/mei/PROJ_PCN/onprofile/IFModel/Model/Gauge/RCS/Range.c,v 1.5 1992/04/17 18:15:21 mei Exp $"; #endif /********************************************************/ /* File: Range.c */ /* Content: A Widget for allowing user to define and */ /* select a range of display data to be further */ /* expanded */ /* Date: 3/1992 */ /********************************************************/ #include <stdio.h> #include <math.h> #include <string.h> #include <X11/IntrinsicP.h> #include <X11/Xresource.h> #include <X11/StringDefs.h> #include <X11/Xaw/Form.h> #include <X11/Xaw/Box.h> #include <X11/Xaw/Command.h> #include <X11/Xaw/Scrollbar.h> #include <Xsw/Xsw.h> #include <Xsw/Chart.h> #include "RangeP.h" #define BARHEIGHT_MAX 223 #define TOPBAR 1 #define BOTTOMBAR 2 #define TOP 1 #define BOTTOM 2 /********************************************************/ /* Range Resources */ /********************************************************/ static XtResource resources[] = { #define offset(field) XtOffset(RangeWidget, range.field) { XtNsetRange, XtCCallback, XtRCallback, sizeof(XtPointer), offset(set_range_callback), XtRCallback, NULL }, { XtNclearSetRange, XtCCallback, XtRCallback, sizeof(XtPointer), offset(clear_set_range_callback), XtRCallback, NULL }, { XtNresetRange, XtCCallback, XtRCallback, sizeof(XtPointer), offset(reset_range_callback), XtRCallback, NULL }, { XtNpopDownRange, XtCCallback, XtRCallback, sizeof(XtPointer), offset(pop_down_range_callback), XtRCallback, NULL }, { XtNtopBound, XtCTopBound, XtRFloat, sizeof(double), offset(topbound), XtRImmediate, "0" }, { XtNbottomBound, XtCBottomBound, XtRFloat, sizeof(double), offset(bottombound), XtRImmediate, "0" }, { XtNbarHeight, XtCBarHeight, XtRInt, sizeof(int), offset(bar_height), XtRImmediate, "223"}, { XtNbarBlocks, XtCBarBlocks, XtRInt, sizeof(int), offset(bar_blocks), XtRImmediate, "10" }, { XtNcellArray, XtCCellArray, XtRPointer, sizeof(double *), offset(cells), XtRImmediate, (XtPointer)NULL }, { XtNstateArray, XtCStateArray, XtRPointer, sizeof(Boolean *), offset(states), XtRImmediate, (XtPointer)NULL }, { XtNpalette, XtCPalette, XtRString, sizeof(String), offset(palette), XtRString, "Palette" }, { XtNcalcMax, XtCCalcMax, XtRFloat, sizeof(double), offset(calcMax), XtRImmediate, "100" }, { XtNcalcMin, XtCCalcMin, XtRFloat, sizeof(double), offset(calcMin), XtRImmediate, "0" }, { XtNsaveMax, XtCSaveMax, XtRFloat, sizeof(double), offset(saveMax), XtRImmediate, "100" }, { XtNsaveMin, XtCSaveMin, XtRFloat, sizeof(double), offset(saveMin), XtRImmediate, "0" }, { XtNisLog, XtCIsLog, XtRBoolean, sizeof(Boolean), offset(isLog), XtRString, "True" }, #undef offset }; /********************************************************/ /******************************************************** max is at left and min is at right total blocks = 3 last_pos= 2 thumb value range from 0-2 topbound and bottombound index range from 0-2 topbound and bottombound value = actual float value calculated from calc_val for the given index |--------|--------|--------| thumb | 0 | 1 | 2 | order |________|________|________| / / / / cell / / / / index & X 0 1 2 percent (-1.0) 0.95 0.5 0.0 values The formula for calculating the value from the index values is : (Viewer.c) let max, min="real" color range maximum, minimum (no matter if they are log or linear values, every interval is equal distance) total= total number of blocks ( ie 3 in this example) value = max - ((max-min)/total) * which Therefore, if top=bottom=0 (block number) then topbound index=0 bottombound index=1 0 1 2 |xxxxxxx| | | +---0---+---1---+---2---+ if top=bottom=2 (block number) then topbound index=2 bottombound index=3 0 1 2 | | |xxxxxxx| +---0---+---1---+---2---+ if top=1, bottom=2 (block number) then topbound index=1 bottombound index=3 0 1 2 | |xxxxxxx|xxxxxxx| +---0---+---1---+---2---+ The topbound value always take the index of the interval value as its index. The bottombound value always take an incremented index of current interval. So to make what ever the thumbs are pointing to an inclusive set. ********************************************************/ /********************************************************/ /********************************************************/ /* Full class record constant */ /********************************************************/ /* for application */ static void Move_up_down(/*Widget w, XtPointer client,call*/); static void RangeQuit(/*RangeWidget w, XtPointer client,call*/); static void RangeApply(/*RangeWidget w, XtPointer client,call*/); static void SaveRange(/*RangeWidget w, XtPointer client,call*/); static void RestoreRange(/*RangeWidget w, XtPointer client,call*/); static void get_range(/*Widget w, rw */); static void to_new_scroll_position(/*ScrollbarWidget w, int newpos, float thumb_width, int thumb_no */); static double set_label(/* RangeWidget w, int whichlabel*/); static double get_val(/* RangeWidget rw, int whichval*/); static int calc_idx(/* RangeWidget rw, int total, double value */); static double calc_val(/* RangeWidget rw, int total, which */); static void rangeSetNew(/* RangeWidget rw */); /* for widget */ static void Initialize(/* RangeWidget request,new */); static void Destroy(/* RangeWidget rw */); static Boolean SetValues(/* RangeWidget current,request,new */); RangeClassRec rangeClassRec = { { /* core_class fields */ /* superclass */ (WidgetClass) &formClassRec, /* class_name */ "range", /* widget_size */ sizeof(RangeRec), /* class_initialize */ NULL, /* class_part_init */ NULL, /* class_inited */ FALSE, /* initialize */ Initialize, /* initialize_hook */ NULL, /* realize */ XtInheritRealize, /* actions */ NULL, /* num_actions */ 0, /* resources */ resources, /* num_resources */ XtNumber(resources), /* xrm_class */ NULLQUARK, /* compress_motion */ TRUE, /* compress_exposure */ TRUE, /* compress_enterleave*/ TRUE, /* visible_interest */ FALSE, /* destroy */ Destroy, /* resize */ XtInheritResize, /* expose */ NULL, /* set_values */ SetValues, /* set_values_hook */ NULL, /* set_values_almost */ XtInheritSetValuesAlmost, /* get_values_hook */ NULL, /* accept_focus */ NULL, /* version */ XtVersion, /* callback_private */ NULL, /* tm_table */ NULL, /* query_geometry */ XtInheritQueryGeometry, /* display_accelerator*/ XtInheritDisplayAccelerator, /* extension */ NULL },{/* composite_class fields */ /* geometry_manager */ XtInheritGeometryManager, /* change_managed */ XtInheritChangeManaged, /* insert_child */ XtInheritInsertChild, /* delete_child */ XtInheritDeleteChild, /* extension */ NULL },{ /* constraint class fields */ /* subresources */ NULL, /* subresource_count */ 0, /* constraint_size */ sizeof(RangeConstraintsRec), /* initialize */ NULL, /* destroy */ NULL, /* set_values */ NULL, /* extension */ NULL }, { /* form_class fields */ /* layout */ XtInheritLayout } }; WidgetClass rangeWidgetClass = (WidgetClass) &rangeClassRec; /********************************************************/ /* Name : Initialize */ /* Content : side effect routine to be called during */ /* the initialization of Range Widget */ /* Date: 3/1992 */ /********************************************************/ /* ARGSUSED */ static void Initialize(request, neww) RangeWidget request,neww; { int i; Dimension size; static String MESG="Select the thresholds\nfor Color Range Display"; double value; /* String topstring[12], bottomstring[12]; */ if(neww->range.bar_blocks <= 0) neww->range.bar_blocks=32; neww->range.thumb_width = 1.0/neww->range.bar_blocks; if(neww->range.bar_height <=0 || neww->range.bar_height > 300 ) neww->range.bar_height=BARHEIGHT_MAX; neww->range.topcurpos = 0; neww->range.bottomcurpos = 0; neww->range.last_pos = neww->range.bar_blocks-1; neww->range.topbound = 0.0; neww->range.bottombound = 0.0; neww->range.save.max=0.0; neww->range.save.min=0.0; neww->range.calcMax=100.0; neww->range.calcMin=0.0; neww->range.saveMax=100.0; neww->range.saveMin=0.0; neww->range.isLog=True; /* value=get_val(neww,TOP); sprintf(topstring,"%9.2e",value); value=get_val(neww,BOTTOM); sprintf(bottomstring,"%9.2e",value); */ /* if no space is pass in for keeping the color bar's cells */ /* allocate and initialize from withing the widget */ if(neww->range.states == (Boolean *) NULL) { neww->range.states= (Boolean *)XtCalloc(neww->range.bar_blocks, sizeof(Boolean)); neww->range.cells= (double *)XtCalloc(neww->range.bar_blocks, sizeof(double)); for(i=0; i < neww->range.bar_blocks; i++) { neww->range.cells[i] = (double)(neww->range.bar_blocks - i - 1)/ (double)neww->range.bar_blocks; }/*for*/ } /**** allocate the widgets ****/ /* the label widget for title text */ neww->range.info=XtVaCreateManagedWidget( "info", labelWidgetClass, (Widget) neww, XtNlabel, MESG, NULL); /* the chart widget for color bar display */ neww->range.colorBar=XtVaCreateManagedWidget( "colorBar", chartWidgetClass, (Widget) neww, XtNwidthInCells, 1, XtNheightInCells, neww->range.last_pos, XtNcellArray, neww->range.cells, XtNstateArray, neww->range.states, XtNpalette, neww->range.palette, XtNtwoD, False, XtNwidth, neww->core.width, XtNheight, neww->range.bar_height, XtNborderWidth, 1, XtNfromVert,neww->range.info, XtNvertDistance, 8, XtNhorizDistance, 16, XtNleft, XtChainLeft, XtNright, XtChainLeft, NULL); /* scrollbar for top range */ neww->range.topRange=XtVaCreateManagedWidget( "topRange", scrollbarWidgetClass, (Widget) neww, XtNwidth, (Dimension) neww->core.width, XtNheight, neww->range.bar_height, XtNborderWidth, 1, XtNfromHoriz, neww->range.colorBar, XtNfromVert, neww->range.info, XtNhorizDistance, 10, XtNvertDistance, 8, NULL); XtAddCallback(neww->range.topRange,XtNscrollProc,Move_up_down,(XtPointer)TOPBAR); XtAddCallback(neww->range.topRange,XtNjumpProc,Move_up_down,(XtPointer)TOPBAR); /* scrollbar for bottom range */ neww->range.bottomRange=XtVaCreateManagedWidget( "bottomRange", scrollbarWidgetClass, (Widget) neww, XtNwidth, (Dimension) neww->core.width, XtNheight, neww->range.bar_height, XtNborderWidth, 1, XtNfromVert, neww->range.info, XtNfromHoriz, neww->range.topRange, XtNvertDistance, 8, NULL); XtAddCallback(neww->range.bottomRange,XtNscrollProc,Move_up_down,(XtPointer)BOTTOMBAR); XtAddCallback(neww->range.bottomRange,XtNjumpProc,Move_up_down,(XtPointer)BOTTOMBAR); /* XtNshapeStyle - for changing shape */ /* the "Apply" command button */ neww->range.selectApply= XtVaCreateManagedWidget( " Apply ", commandWidgetClass, (Widget) neww, XtNborderWidth, 1, XtNfromVert, neww->range.info, XtNfromHoriz,neww->range.bottomRange, XtNhorizDistance, 12, XtNvertDistance, 8, XtNright, XtChainRight, XtNleft, XtChainRight, NULL); XtAddCallback(neww->range.selectApply,XtNcallback, RangeApply,neww); XtVaGetValues(neww->range.selectApply, XtNwidth, &size, NULL); /* the "Reset" command button */ neww->range.selectReset= XtVaCreateManagedWidget( "Reset", commandWidgetClass, (Widget) neww, XtNfromVert,neww->range.selectApply, XtNfromHoriz,neww->range.bottomRange, XtNwidth, size, XtNborderWidth, 1, XtNhorizDistance, 12, XtNright, XtChainRight, XtNleft, XtChainRight, NULL); XtAddCallback(neww->range.selectReset,XtNcallback, XswRangeReset, (XtPointer)neww); /* the "Quit" command button */ neww->range.selectQuit= XtVaCreateManagedWidget( "Quit", commandWidgetClass, (Widget) neww, XtNfromVert,neww->range.selectReset, XtNfromHoriz,neww->range.bottomRange, XtNwidth, size, XtNborderWidth, 1, XtNhorizDistance, 12, XtNright, XtChainRight, XtNleft, XtChainRight, NULL); XtAddCallback(neww->range.selectQuit,XtNcallback, RangeQuit, neww); /* the "Save" command button */ neww->range.selectSave= XtVaCreateManagedWidget( "Save", commandWidgetClass, (Widget) neww, XtNfromVert,neww->range.selectQuit, XtNfromHoriz,neww->range.bottomRange, XtNwidth, size, XtNborderWidth, 1, XtNvertDistance, 16, XtNhorizDistance, 12, XtNright, XtChainRight, XtNleft, XtChainRight, NULL); XtAddCallback(neww->range.selectSave,XtNcallback, SaveRange,neww); /* the "Restore" command button */ neww->range.selectRestore = XtVaCreateManagedWidget( "Restore", commandWidgetClass, (Widget) neww, XtNfromVert,neww->range.selectSave, XtNfromHoriz,neww->range.bottomRange, XtNwidth, size, XtNborderWidth, 1, XtNhorizDistance, 12, XtNright, XtChainRight, XtNleft, XtChainRight, NULL); XtAddCallback(neww->range.selectRestore,XtNcallback, RestoreRange,neww); /* the top's text label button */ neww->range.topLabel= XtVaCreateManagedWidget( "Top", labelWidgetClass, (Widget) neww, XtNfromVert,neww->range.selectRestore, XtNfromHoriz,neww->range.bottomRange, XtNwidth, size, XtNborderWidth, 1, XtNvertDistance, 16, XtNhorizDistance, 12, XtNright, XtChainRight, XtNleft, XtChainRight, NULL); /* the top's value label button */ neww->range.topVal= XtVaCreateManagedWidget( "topVal", labelWidgetClass, (Widget) neww, XtNfromVert,neww->range.topLabel, XtNfromHoriz,neww->range.bottomRange, XtNwidth, size, XtNborderWidth, 0, XtNvertDistance, 0, XtNhorizDistance, 6, XtNright, XtChainRight, XtNleft, XtChainRight, NULL); /* the bottom's text label button */ neww->range.bottomLabel= XtVaCreateManagedWidget( "Bottom", labelWidgetClass, (Widget) neww, XtNfromVert,neww->range.topVal, XtNfromHoriz,neww->range.bottomRange, XtNwidth, size, XtNborderWidth, 1, XtNhorizDistance, 12, XtNright, XtChainRight, XtNleft, XtChainRight, NULL); /* the bottom's value label button */ neww->range.bottomVal= XtVaCreateManagedWidget( "bottomVal", labelWidgetClass, (Widget) neww, XtNfromVert,neww->range.bottomLabel, XtNfromHoriz,neww->range.bottomRange, XtNwidth, size, XtNborderWidth, 0, XtNvertDistance, 0, XtNhorizDistance, 6, XtNright, XtChainRight, XtNleft, XtChainRight, NULL); } /********************************************************/ /* Name: Destroy */ /* Content: The side effect routine to be called when */ /* Range widget is destroyed */ /* Date: 3/1992 */ /********************************************************/ /* ARGSUSED */ static void Destroy(rw) RangeWidget rw; { /* does not need to do any freeing right now */ XtFree((char *) rw->range.states); XtFree((char *) rw->range.cells); } /********************************************************/ /* Name: SetValues */ /* Content: The side effect routine to be called when */ /* Range widget's resources are altered */ /* Date: 3/1992 */ /********************************************************/ /*ARGSUSED*/ static Boolean SetValues(current,request,neww) Widget current,request,neww; { RangeWidget cw =(RangeWidget) current; RangeWidget nw =(RangeWidget) neww; int i; if(cw->range.bar_blocks != nw->range.bar_blocks) { nw->range.thumb_width= 1.0 / nw->range.bar_blocks; nw->range.last_pos=nw->range.bar_blocks-1; XtFree((char *) nw->range.states); XtFree((char *) nw->range.cells); XtFree((char *) cw->range.states); XtFree((char *) cw->range.cells); nw->range.states= (Boolean *)XtCalloc(nw->range.bar_blocks,sizeof(Boolean)); nw->range.cells= (double *)XtCalloc(nw->range.bar_blocks,sizeof(double)); for(i=0; i < nw->range.bar_blocks; i++) { nw->range.cells[i] = (double) (nw->range.bar_blocks - i - 1)/nw->range.bar_blocks; } }/*if change in bar_blocks*/ if(cw->range.bar_height != nw->range.bar_height) { XtVaSetValues(nw->range.colorBar, XtNheight,nw->range.bar_height,NULL); XtVaSetValues(nw->range.bottomRange, XtNheight,nw->range.bar_height,NULL); XtVaSetValues(nw->range.topRange, XtNheight,nw->range.bar_height,NULL); }/*if, propagate the height constraint down to scrollbar */ if( (cw->range.calcMax != nw->range.calcMax) || (cw->range.calcMin != nw->range.calcMin) || (cw->range.bar_blocks != nw->range.bar_blocks)) rangeSetNew(nw); return True; } /********************************************************/ /* Name: XswRangeReset */ /* Content: Clear all data for range select except what */ /* is save in the RangeSave structure. And also return*/ /* the main display back to pre-range select state */ /* Date: 3/1992 */ /********************************************************/ /*ARGSUSED*/ #if NeedFunctionPrototypesOFF void XswRangeReset( Widget w, XtPointer client_data, XtPointer call_data ) #else void XswRangeReset(w,client_data,call_data) Widget w; XtPointer client_data, /* RangeWidget */ call_data; #endif { RangeWidget parent = (RangeWidget) client_data; double value; parent->range.topcurpos=0; parent->range.bottomcurpos=0; to_new_scroll_position(parent->range.topRange,0, parent->range.thumb_width,1); to_new_scroll_position(parent->range.bottomRange,0, parent->range.thumb_width,1); XtCallCallbacks((Widget)parent, XtNclearSetRange, NULL); value=set_label(parent,TOP); parent->range.topbound=value; value=set_label(parent,BOTTOM); parent->range.bottombound=value; } /********************************************************/ /* Name: RangeQuit */ /* Content: leave the range select by popping down the */ /* popshell */ /* Date: 3/1992 */ /********************************************************/ /*ARGSUSED*/ static void RangeQuit(w,client_data,call_data) Widget w; XtPointer client_data, /* RangeWidget */ call_data; { RangeWidget parent = (RangeWidget) client_data; XtCallCallbacks((Widget)parent, XtNpopDownRange, NULL); } /********************************************************/ /* Name: RestoreRange */ /* Content: i) Restore the max and min saved from the */ /* SAVE action, ii) recompute the new index for the */ /* topbar and bottombar, and iii) setup the range */ /* select's new display */ /* Note, since the max and min might be different */ /* from when the Range SAVE is done, the index might */ /* be different from when the range is saved */ /* Date: 3/1992 */ /********************************************************/ /*ARGSUSED*/ static void RestoreRange(w,client_data,call_data) Widget w; XtPointer client_data, /* RangeWidget */ call_data; { RangeWidget parent = (RangeWidget) client_data; #if 0 /* * Steve Tuecke, 11/29/92 * Since String is a typedef for char *, this is not quite what we * want (string would be an array of char pointers), and could * cause problems with the sprintf's below. */ static String string[12]; #else static char string[12]; #endif double value; int idx; parent->range.topbound=parent->range.save.max; parent->range.bottombound=parent->range.save.min; idx=calc_idx(parent,parent->range.bar_blocks, parent->range.bottombound); if(idx > parent->range.last_pos) parent->range.bottomcurpos=parent->range.last_pos; else parent->range.bottomcurpos=idx-1; idx=calc_idx(parent,parent->range.bar_blocks, parent->range.topbound); if(idx > parent->range.last_pos) parent->range.topcurpos=parent->range.last_pos; else parent->range.topcurpos=idx; to_new_scroll_position(parent->range.topRange, parent->range.topcurpos,parent->range.thumb_width,1); to_new_scroll_position(parent->range.bottomRange, parent->range.bottomcurpos,parent->range.thumb_width,1); sprintf(string,"%9.2e",parent->range.topbound); XtVaSetValues(parent->range.topVal,XtNlabel,string,NULL); sprintf(string,"%9.2e",parent->range.bottombound); XtVaSetValues(parent->range.bottomVal,XtNlabel,string,NULL); } /********************************************************/ /* Name: SaveRange */ /* Content: save the maxbound and minbound so they may */ /* be reused in the future */ /* Date: 3/1992 */ /********************************************************/ /*ARGSUSED*/ static void SaveRange(w,client_data,call_data) Widget w; XtPointer client_data, /* RangeWidget */ call_data; { RangeWidget parent = (RangeWidget) client_data; get_range(NULL, parent); parent->range.save.max=parent->range.topbound; parent->range.save.min=parent->range.bottombound; } /********************************************************/ /* Name: get_range */ /* Content: i) to calculate the actual max and min value*/ /* from the current index position on both scroll bars */ /* and ii) save them in the topbound and bottombound */ /* fields. */ /* Note: the index used for bottomcurpos is increased */ /* by one */ /* Date: 3/1992 */ /********************************************************/ /*ARGSUSED*/ static void get_range(w,rw) Widget w; RangeWidget rw; { double value1, value2; value1=set_label(rw,TOP); value2=set_label(rw,BOTTOM); /* reset the bounds */ if(value1>value2) { rw->range.topbound=value1; rw->range.bottombound=value2; } else { rw->range.topbound=value2; rw->range.bottombound=value1; } } /********************************************************/ /* Name: RangeApply */ /* Content: To apply the range currented selected to */ /* the main data display's data */ /* Date: 3/1992 */ /********************************************************/ /*ARGSUSED*/ static void RangeApply(w,rbar,call_data) Widget w; RangeWidget rbar; /* rbar */ XtPointer call_data; { get_range(w,rbar); /* get the current range selected */ XtCallCallbacks((Widget)rbar, XtNsetRange, NULL); get_range(w,rbar); /* recalculate the new position relative */ /* to the possible new max and min values*/ #ifdef DEBUG printf("RangeApply: new topbound(%8.2e), bottombound(%8.2e)\n", rbar->range.topbound, rbar->range.bottombound); #endif } /********************************************************/ /* Name: to_new_scroll_position */ /* Content: routine to change thumb positions of the */ /* scrollbars */ /* Date: 3/1992 */ /********************************************************/ /* ARGSUSED */ static void to_new_scroll_position(w,newpos,thumb_width,thumb_no) Widget w; /* scrollbar widget */ int newpos; float thumb_width; int thumb_no; { XawScrollbarSetThumb(w, (float) newpos*thumb_width, (float) thumb_width*thumb_no); } /********************************************************/ /* Name: jump_down_one */ /* Content: to move the thumb of a scroll bar down by 1 */ /* Date: 3/1992 */ /********************************************************/ /* ARGSUSED */ static void jump_down_one(w,which) Widget w; XtPointer which; { RangeWidget parent = (RangeWidget) XtParent(w); int whichbar = (int) which; int lastpos=parent->range.last_pos; int curpos; if(whichbar == TOPBAR) curpos=parent->range.topcurpos; else curpos=parent->range.bottomcurpos; curpos =((curpos+1) > lastpos) ? lastpos : curpos+1; to_new_scroll_position(w,curpos,parent->range.thumb_width,1); if(whichbar == TOPBAR) parent->range.topcurpos=curpos; else parent->range.bottomcurpos=curpos; } /********************************************************/ /* Name: jump_up_one */ /* Content: to move the thumb of a scroll bar up by 1 */ /* Date: 3/1992 */ /********************************************************/ /* ARGSUSED */ static void jump_up_one(w,which) Widget w; /* scrollbar widget */ XtPointer which; { RangeWidget parent = (RangeWidget) XtParent(w); int whichbar = (int) which; int curpos; if(whichbar == TOPBAR) curpos=parent->range.topcurpos; else curpos=parent->range.bottomcurpos; curpos =((curpos-1) < 0) ? 0 : curpos-1; to_new_scroll_position(w,curpos,parent->range.thumb_width,1); if(whichbar == TOPBAR) parent->range.topcurpos=curpos; else parent->range.bottomcurpos=curpos; } /********************************************************/ /* Name: scroll_up_down_multi */ /* Content: to move the thumb of a scroll bar to the */ /* mouse ptr position */ /* Date: 3/1992 */ /********************************************************/ /* ARGSUSED */ static void scroll_up_down_multi(w,which) Widget w; /* scrollbar widget */ XtPointer which; { RangeWidget parent = (RangeWidget) XtParent(w); int whichbar = (int) which; float pos; int curpos; XtVaGetValues(w,XtNtopOfThumb,&pos,NULL); curpos = (int) (pos / parent->range.thumb_width); if( curpos > parent->range.last_pos ) curpos=parent->range.last_pos; to_new_scroll_position(w,curpos,parent->range.thumb_width,1); if(whichbar == TOPBAR) parent->range.topcurpos=curpos; else parent->range.bottomcurpos=curpos; } /********************************************************/ /* Name: Move_up_down */ /* Content: the callback routine for moving the thumb */ /* of the scroll bars */ /* Note: both jump and continuous scroll call this */ /* routine */ /* Date: 3/1992 */ /********************************************************/ /* ARGSUSED */ static void Move_up_down(w, client_data, call_data) Widget w; /* the scrollbar */ XtPointer client_data, /* 1 or 2 */ call_data; { RangeWidget parent = (RangeWidget) XtParent(w); Dimension d_leng; int whichbutton, leng; int thumb=(int)call_data; XtVaGetValues(w,XtNlength,&d_leng,NULL); leng=(int)d_leng; whichbutton = (thumb > leng) ? 2 : ((thumb < 0) ? 3:1); switch (whichbutton) { case 1:jump_up_one(w,client_data); break; case 2: scroll_up_down_multi(w,client_data); break; case 3:jump_down_one(w,client_data); break; }/*switch*/ rangeSetNew(parent); } /********************************************************/ /* Name: XswRangeGetNew */ /* Content: to retrieve the new max and min enforced on */ /* the main display data by the range select */ /* Date: 3/1992 */ /********************************************************/ #if NeedFunctionPrototypes void XswRangeGetNew( RangeWidget rw, double *max, double *min ) #else void XswRangeGetNew(rw,max,min) RangeWidget rw; double *max, *min; #endif { *max = rw->range.topbound; *min = rw->range.bottombound; } /********************************************************/ /* Name: rangeSetNew */ /* Content: inform the popup bar range that a new set of*/ /* max and min is created, better reset the labels */ /* Date: 4/1992 */ /********************************************************/ static void rangeSetNew(rw) RangeWidget rw; { (void) set_label(rw, TOP); (void) set_label(rw, BOTTOM); } static double set_label(rw, whichlabel) RangeWidget rw; int whichlabel; { #if 0 /* * Steve Tuecke, 11/29/92 * Since String is a typedef for char *, this is not quite what we * want (string would be an array of char pointers), and could * cause problems with the sprintf's below. */ static String string[12]; #else static char string[12]; #endif double value; value=get_val(rw, whichlabel); sprintf(string,"%9.2e",value); if(whichlabel==TOP) XtVaSetValues(rw->range.topVal,XtNlabel,string,NULL); else XtVaSetValues(rw->range.bottomVal,XtNlabel,string,NULL); return value; } static double get_val(rw,whichval) RangeWidget rw; int whichval; { double value; if( whichval == TOP) value=calc_val(rw,rw->range.bar_blocks, rw->range.topcurpos); else value=calc_val(rw, rw->range.bar_blocks, rw->range.bottomcurpos+1); return value; } /********************************************************/ /* Name: calc_val */ /* Content: Given a index and number of blocks to divide*/ /* the range between maximum and minimum, compute the */ /* value corresponding to the index */ /* Date: 3/1992 */ /********************************************************/ static double calc_val(rw, total, which) RangeWidget rw; int total, which; { double value; /* depending on rw->range.isLog these maybe log values */ double max = rw->range.calcMax, min = rw->range.calcMin; if(max==min) value=max; else value= max-((max-min)/total)*which; if(rw->range.isLog) { #ifdef sun4 value = exp10(value); #else /* Steve Tuecke, 11/9/92 -- most machines don't have exp10() */ value = pow(10.0, value); #endif } return(value); } /********************************************************/ /* Name: calc_idx */ /* Content: Divide the maximum and minimum used in the */ /* main display into "total" blocks and then calcu- */ /* late the index of the "val" that falls in */ /* Date: 3/1992 (hui) */ /********************************************************/ static int calc_idx(rw,total,val) RangeWidget rw; int total; /* total blocks */ double val; { double max = rw->range.calcMax, min = rw->range.calcMin; double value; double interval=(max-min)/total; int idx=0; if(rw->range.isLog) value=log10(val); else value=val; if(max==min) idx=total; /* to avoid divide by 0 */ else idx= (int) ((max-value)/interval); if( (max-value) > (double) (idx+0.5) * interval) idx++; /* handles the decimal larger than 0.5 */ if( idx < 0 ) idx=0; /* handle the boundaries */ if( idx >= total ) idx=total; return(idx); /* return a value between 0 to total */ }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.