ftp.nice.ch/pub/next/unix/developer/pcn.2.0.s.tar.gz#/contrib/gauge/Gauge/Range.c

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.