home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 300-399 / ff386.lzh / XLispStat / src1.lzh / IView / iviewintrn.c < prev    next >
C/C++ Source or Header  |  1990-10-04  |  29KB  |  1,030 lines

  1. /* XLISP-STAT 2.1 Copyright (c) 1990, by Luke Tierney                  */
  2. /* Additions to Xlisp 2.1, Copyright (c) 1989 by David Michael Betz    */
  3. /* You may give out copies of this software; for conditions see the    */
  4. /* file COPYING included with this distribution.                       */
  5.  
  6. #include "xlisp.h"
  7. #include "osdef.h"
  8. #ifdef ANSI
  9. #include "iviewproto.h"
  10. #include "Stproto.h"
  11. #else
  12. #include "iviewfun.h"
  13. #include "Stfun.h"
  14. #endif ANSI
  15.  
  16. typedef IView StGrInfo;
  17.  
  18. /* forward declarations */
  19. #ifdef ANSI
  20. StGrInfo StGrGetGrInfo(StGWWinInfo *);
  21. void set_axis(IVIEW_WINDOW,int,int,int,int),
  22.      draw_tick(IVIEW_WINDOW,int,int,double,int),drag(IVIEW_WINDOW,int,int),
  23.      dragbrush(IVIEW_WINDOW,int,int),IViewSetIsLinked(IVIEW_WINDOW,int);
  24. #else
  25. StGrInfo StGrGetGrInfo();
  26. void set_axis(),
  27.      draw_tick(),drag(),
  28.      dragbrush(),IViewSetIsLinked();
  29. #endif
  30.  
  31. #define BRUSH_WIDTH 20
  32. #define BRUSH_HEIGHT 40
  33. #define AXIS_LABEL_GAP 4
  34. #define AXIS_TICK_LENGTH 3
  35. #define AXIS_LABEL_TEMPLATE "12345"
  36. #define CLICK_WIDTH 4
  37. #define CLICK_HEIGHT 4
  38.  
  39. #ifndef TRUE
  40. #define TRUE 1
  41. #endif TRUE
  42. #ifndef FALSE
  43. #define FALSE 0
  44. #endif FALSE
  45. /*   in iviewdef.h JKL 
  46. typedef struct brush {
  47.   int left, top, width, height, showing;
  48. } Brush;
  49.  
  50. typedef struct clickrange {
  51.   int width, height;
  52. } ClickRange;
  53.  
  54. typedef struct content {
  55.   int left, top, width, height, origin_x, origin_y, x_variable, y_variable;
  56. } Content;
  57.  
  58. typedef struct {
  59.   int left, top, right, bottom;
  60. } Margin;
  61.  
  62. typedef struct {
  63.   int showing, labeled, ticks, height, edge;
  64. } Axis;
  65.  
  66. typedef struct iview {
  67.   char *data;
  68.   Content content;
  69.   Margin margin;
  70.   Axis x_axis, y_axis;
  71.   Brush brush;
  72.   ClickRange clickrange;
  73.   MouseMode mouseMode;
  74.   int showingLabels, fixed_aspect, dirty;
  75.   long links;
  76.   double *scale, *shift;
  77. } *IView;
  78.  
  79. typedef IView StGrInfo;
  80. */
  81. #define IViewGetIView(w) ((IView) StGWGetRefCon(IViewWindowWinInfo(w)))
  82.  
  83. /**************************************************************************/
  84. /**                                                                      **/
  85. /**                       IView Creation Functions                       **/
  86. /**                                                                      **/
  87. /**************************************************************************/
  88.  
  89. void IViewFreeMem(w)
  90.      IVIEW_WINDOW w;
  91. {
  92.   IView iview = IViewGetIView(w);
  93.  
  94.   if (iview != nil) {
  95.     if (IViewData(w) != nil) {
  96.       IViewDataFree(IViewData(w));
  97.       IViewSetData(w, nil);
  98.     }
  99.     StFree(iview->scale);
  100.     StFree(iview->shift);
  101.     StFree(iview);
  102.     StGWSetRefCon(IViewWindowWinInfo(w), nil);
  103.   }
  104. }
  105.  
  106. IVIEW_WINDOW IViewNew(object)
  107.      /* char * */ LVAL object; /* changed  JKL */
  108. {
  109.   IVIEW_WINDOW w = (IVIEW_WINDOW) IViewWindowNew(object, FALSE);
  110.   IView iview;
  111.   /*char*/ StGWWinInfo *gwinfo; /* changed JKL */
  112.   int vars, i;
  113.  
  114.   gwinfo = StGWObWinInfo(object);
  115.   get_iview_ivars(object, &vars);
  116.  
  117.   iview = (IView) StCalloc(sizeof(struct iview), 1);
  118.   StGWSetRefCon(gwinfo, iview);
  119.   IViewSetData(w, IViewDataNew(vars));
  120.   if(vars>0){ /* test added JKL */
  121.      iview->scale = (double *) StCalloc(vars, sizeof(double));
  122.      iview->shift = (double *) StCalloc(vars, sizeof(double));}
  123.   
  124.   StGWSetFreeMem(gwinfo, IViewFreeMem);
  125.   StGrSetContentVariables(gwinfo, 0, 1);
  126.   IViewSetBrush(w, 0, 0, BRUSH_WIDTH, BRUSH_HEIGHT);
  127.   StGrSetClickRange(gwinfo, CLICK_WIDTH, CLICK_HEIGHT);
  128.   IViewSetShowingLabels(w, FALSE);
  129.   IViewSetMouseMode(w, selecting);
  130.   IViewSetIsLinked(w, FALSE);
  131.   StGrSetMargin(gwinfo, 0, 0, 0, 0);
  132.   IViewSetFixedAspect(w, TRUE);
  133.   iview->brush.showing = FALSE;
  134.   
  135.   for (i = 0; i < vars; i++) {
  136.     IViewSetScaledRange(w, i, 0.0, 1.0);
  137.     IViewSetScale(w, i, 1.0);
  138.     IViewSetShift(w, i, 0.0);
  139.   }
  140.   return(w);
  141. }
  142.  
  143. /**************************************************************************/
  144. /**                                                                      **/
  145. /**                 IView State Accessors and Mutators                   **/
  146. /**                                                                      **/
  147. /**************************************************************************/
  148.  
  149. int StGrDirty(gwinfo)
  150. /*    char*/ StGWWinInfo *gwinfo; /* changed JKL */
  151. {
  152.   StGrInfo gr = (StGrInfo) StGWGetRefCon(gwinfo);
  153.   if (gr == nil) StPerror("no graph installed in this window");
  154.   return(gr->dirty);
  155. }
  156.  
  157. void StGrSetDirty(gwinfo, dirty) 
  158.     /*char*/ StGWWinInfo *gwinfo; /* changed JKL */
  159.    int dirty;
  160. {
  161.   StGrInfo gr = (StGrInfo) StGWGetRefCon(gwinfo);
  162.   if (gr == nil) StPerror("no graph installed in this window");
  163.   gr->dirty = dirty;
  164. }
  165.  
  166. static  StGrInfo StGrGetGrInfo(gwinfo) 
  167.     /*char*/ StGWWinInfo *gwinfo; /* changed JKL */
  168. {
  169.   StGrInfo gr = (StGrInfo) StGWGetRefCon(gwinfo);
  170.   if (gr == nil) StPerror("no graph installed in this window");
  171.   return(gr);
  172. }
  173.  
  174. void StGrSetContentRect(gwinfo, left, top, width, height)
  175.      /*char*/ StGWWinInfo *gwinfo; /* changed JKL */
  176.      int left, top, width, height;
  177. {
  178.   StGrInfo gr = StGrGetGrInfo(gwinfo);
  179.  
  180.   gr->content.left = left; gr->content.top = top;
  181.   gr->content.width = width; gr->content.height = height;
  182. }
  183.  
  184. void StGrGetContentRect(gwinfo, left, top, width, height)
  185.      /*char*/ StGWWinInfo *gwinfo; /* changed JKL */
  186.      int *left, *top, *width, *height;
  187. {
  188.   StGrInfo gr = StGrGetGrInfo(gwinfo);
  189.  
  190.   if (left != nil) *left = gr->content.left;
  191.   if (top != nil) *top = gr->content.top;
  192.   if (width != nil) *width = gr->content.width;
  193.   if (height != nil) *height = gr->content.height;
  194. }
  195.  
  196. void StGrSetContentOrigin(gwinfo, x, y)
  197.      /*char*/ StGWWinInfo *gwinfo; /* changed JKL */
  198.      int x, y;
  199. {
  200.   StGrInfo gr = StGrGetGrInfo(gwinfo);
  201.  
  202.   gr->content.origin_x = x;
  203.   gr->content.origin_y = y;
  204. }
  205.  
  206. void StGrGetContentOrigin(gwinfo, x, y)
  207.      /*char*/ StGWWinInfo *gwinfo; /* changed JKL */
  208.      int *x, *y;
  209. {
  210.   StGrInfo gr = StGrGetGrInfo(gwinfo);
  211.  
  212.   if (x != nil) *x = gr->content.origin_x;
  213.   if (y != nil) *y = gr->content.origin_y;
  214. }
  215.  
  216. void StGrSetContentVariables(gwinfo, x, y)
  217.      /*char*/ StGWWinInfo *gwinfo; /* changed JKL */
  218.      int x, y;
  219. {
  220.   StGrInfo gr = StGrGetGrInfo(gwinfo);
  221.   int vars = StGrNumVariables(gwinfo);
  222.   
  223.   gr->content.x_variable = (vars > x && x >= 0) ? x : 0;
  224.   gr->content.y_variable = (vars > y && y >= 0) ? y : 1;
  225. }
  226.  
  227. void StGrGetContentVariables(gwinfo, x, y)
  228.      /*char*/ StGWWinInfo *gwinfo; /* changed JKL */
  229.      int *x, *y;
  230. {
  231.   StGrInfo gr = StGrGetGrInfo(gwinfo);
  232.  
  233.   if (x != nil) *x = gr->content.x_variable;
  234.   if (y != nil) *y = gr->content.y_variable;
  235. }
  236.  
  237. void StGrSetClickRange(gwinfo, width, height)
  238.      /*char*/ StGWWinInfo *gwinfo; /* changed JKL */
  239.      int width, height;
  240. {
  241.   StGrInfo gr = StGrGetGrInfo(gwinfo);
  242.  
  243.   gr->clickrange.width = width;
  244.   gr->clickrange.height = height;
  245. }
  246.  
  247. void StGrGetClickRange(gwinfo, width, height)
  248.      /*char*/ StGWWinInfo *gwinfo; /* changed JKL */
  249.      int *width, *height;
  250. {
  251.   StGrInfo gr = StGrGetGrInfo(gwinfo);
  252.  
  253.   if (width != nil) *width = gr->clickrange.width;
  254.   if (height != nil) *height = gr->clickrange.height;
  255. }
  256.  
  257. void IViewSetMouseMode(w, mode)
  258.     IVIEW_WINDOW w;
  259.     MouseMode mode;
  260. {
  261.   /*char*/ StGWWinInfo *gwinfo = IViewWindowWinInfo(w);/* changed JKL */
  262.   IView iview = IViewGetIView(w);
  263.   if (iview == nil) return;
  264.  
  265.   if (iview->mouseMode == brushing) IViewEraseBrush(w);
  266.   iview->mouseMode = mode;
  267.   if (iview->mouseMode == brushing) IViewDrawBrush(w);
  268.   switch (mode) {
  269.   case brushing:  StGWSetCursor(gwinfo, BRUSH_CURSOR); break;
  270.   case usermode:  StGWSetCursor(gwinfo, HAND_CURSOR);  break;
  271.   case selecting:
  272.   default:        StGWSetCursor(gwinfo, ARROW_CURSOR);
  273.   }
  274. }
  275.  
  276. MouseMode IViewMouseMode(w)
  277.     IVIEW_WINDOW w;
  278. {
  279.   IView iview = IViewGetIView(w);
  280.   if (iview == nil) return((MouseMode) 0);
  281.  
  282.   return(iview->mouseMode);
  283. }
  284.  
  285. void IViewSetShowingLabels(w, show)
  286.     IVIEW_WINDOW w;
  287.     int show;
  288. {
  289.   IView iview = IViewGetIView(w);
  290.   if (iview == nil) return;
  291.   
  292.   IViewUnselectAllPoints(w);
  293.   iview->showingLabels = show;
  294. }
  295.  
  296. int IViewShowingLabels(w)
  297.      IVIEW_WINDOW w;
  298. {
  299.   IView iview = IViewGetIView(w);
  300.  
  301.   return(iview != nil && iview->showingLabels);
  302. }
  303.  
  304. void IViewSetData(w, data)
  305.     IVIEW_WINDOW w;
  306.     /*char * */ IViewDATA data; /* changed JKL */
  307. {
  308.   IView iview = IViewGetIView(w);
  309.  
  310.   if (iview != nil) iview->data = data;
  311. }
  312.  
  313. /* char * */ IViewDATA StGrData(gwinfo)
  314.     /*char*/ StGWWinInfo *gwinfo;/* changed JKL */
  315. {
  316.   StGrInfo gr = StGrGetGrInfo(gwinfo);
  317.   if (gr->data == nil) StPerror("No data in this IView");
  318.   return(gr->data);
  319. }
  320.  
  321. /* char * */ IViewDATA IViewData(w)  /* changed  JKL */
  322.      IVIEW_WINDOW w;
  323. {
  324.   IView iview = IViewGetIView(w);
  325.   if (iview == nil) StPerror("No IView installed in this window");
  326.   if (iview->data == nil) StPerror("No data in this IView");
  327.   return(iview->data);
  328. }
  329.  
  330. void StGrSetMargin(gwinfo, left, top, right, bottom)
  331.      /*char*/ StGWWinInfo *gwinfo;/* changed JKL */
  332.      int left, top, right, bottom;
  333. {
  334.   StGrInfo gr = StGrGetGrInfo(gwinfo);
  335.   
  336.   gr->margin.left = left;
  337.   gr->margin.top = top;
  338.   gr->margin.right = right;
  339.   gr->margin.bottom = bottom;
  340. }
  341.  
  342. void StGrGetMargin(gwinfo, left, top, right, bottom)
  343.      /*char*/ StGWWinInfo *gwinfo; /* changed JKL */
  344.      int *left, *top, *right, *bottom;
  345. {
  346.   StGrInfo gr = StGrGetGrInfo(gwinfo);
  347.   
  348.   if (left != nil) *left = gr->margin.left;
  349.   if (top != nil) *top = gr->margin.top;
  350.   if (right != nil) *right = gr->margin.right;
  351.   if (bottom != nil) *bottom = gr->margin.bottom;
  352. }
  353.  
  354. void IViewSetFixedAspect(w, fixed)
  355.      IVIEW_WINDOW w;
  356.      int fixed;
  357. {
  358.   IView iview = IViewGetIView(w);
  359.   if (iview == nil) StPerror("No IView installed in this window");
  360.   iview->fixed_aspect = fixed;
  361. }
  362.  
  363. int IViewFixedAspect(w)
  364.      IVIEW_WINDOW w;
  365. {
  366.   IView iview = IViewGetIView(w);
  367.   if (iview == nil) StPerror("No IView installed in this window");
  368.   return(iview->fixed_aspect);
  369. }
  370.  
  371. void IViewSetScale(w, var, scale)
  372.      IVIEW_WINDOW w;
  373.      unsigned var;
  374.      double scale;
  375. {
  376.   IView iview = IViewGetIView(w);
  377.   if (iview == nil) StPerror("No IView installed in this window");
  378.   if (var >= IViewNumVariables(w) || scale <= 0.0) return;
  379.   else iview->scale[var] = scale;
  380. }
  381.  
  382. double IViewScale(w, var)
  383.      IVIEW_WINDOW w;
  384.      unsigned var;
  385. {
  386.   IView iview = IViewGetIView(w);
  387.   if (iview == nil) StPerror("No IView installed in this window");
  388.   if (var >= IViewNumVariables(w)) return(0.0);
  389.   else return(iview->scale[var]);
  390. }
  391.  
  392. void IViewSetShift(w, var, shift)
  393.      IVIEW_WINDOW w;
  394.      unsigned var;
  395.      double shift;
  396. {
  397.   IView iview = IViewGetIView(w);
  398.   if (iview == nil) StPerror("No IView installed in this window");
  399.   if (var >= IViewNumVariables(w)) return;
  400.   else iview->shift[var] = shift;
  401. }
  402.  
  403. double IViewShift(w, var)
  404.      IVIEW_WINDOW w;
  405.      unsigned var;
  406. {
  407.   IView iview = IViewGetIView(w);
  408.   if (iview == nil) StPerror("No IView installed in this window");
  409.   if (var >= IViewNumVariables(w)) return(0.0);
  410.   else return(iview->shift[var]);
  411. }
  412.  
  413. /**************************************************************************/
  414. /**                                                                      **/
  415. /**                            Axis Functions                            **/
  416. /**                                                                      **/
  417. /**************************************************************************/
  418.  
  419. static void set_axis(w, which, showing, labeled, ticks)
  420.     IVIEW_WINDOW w;
  421.     int which, showing, labeled, ticks;
  422. {
  423.   /*char*/ StGWWinInfo *gwinfo = IViewWindowWinInfo(w); /* changed JKL */
  424.   IView iview = IViewGetIView(w);
  425.   Axis *axis;
  426.   
  427.   if (iview == nil) StPerror("No IView installed in this window");
  428.    
  429.   switch (which) {
  430.   case 'X': axis = &iview->x_axis; break;
  431.   case 'Y': axis = &iview->y_axis; break;
  432.   }
  433.  
  434.   axis->showing = showing;
  435.   axis->labeled = labeled;
  436.   axis->ticks = ticks;
  437.  
  438.   if (axis->showing) {
  439.     axis->height = StGWTextAscent(gwinfo)
  440.                  + StGWTextWidth(gwinfo, AXIS_LABEL_TEMPLATE) / 2
  441.                  + AXIS_LABEL_GAP + AXIS_TICK_LENGTH;
  442.     if (axis->labeled)
  443.       axis->height += StGWTextAscent(gwinfo) + AXIS_LABEL_GAP;
  444.     axis->edge = StGWTextWidth(gwinfo, AXIS_LABEL_TEMPLATE);
  445.   }
  446.   else {
  447.     axis->height = 0;
  448.     axis->edge = 0;
  449.   }
  450. }  
  451.   
  452. void IViewGetAxisMargin(w, left, top, right, bottom)
  453.     IVIEW_WINDOW w;
  454.     int *left, *top, *right, *bottom;
  455. {
  456.   IView iview = IViewGetIView(w);
  457.   if (iview == nil) StPerror("No IView installed in this window");
  458.  
  459.   if (left != nil) 
  460.     *left = (iview->x_axis.edge > iview->y_axis.height)
  461.           ? iview->x_axis.edge : iview->y_axis.height;
  462.   if (bottom != nil)
  463.     *bottom = (iview->y_axis.edge > iview->x_axis.height)
  464.             ? iview->y_axis.edge : iview->x_axis.height;
  465.   if (top != nil) *top = iview->y_axis.edge;
  466.   if (right != nil) *right = iview->x_axis.edge;
  467. }
  468.  
  469. void IViewSetXaxis(w, showing, labeled, ticks)
  470.     IVIEW_WINDOW w;
  471.     int showing, labeled, ticks;
  472. {
  473.   set_axis(w, 'X', showing, labeled, ticks);
  474. }
  475.  
  476. void IViewGetXaxis(w, showing, labeled, ticks)
  477.     IVIEW_WINDOW w;
  478.     int *showing, *labeled, *ticks;
  479. {
  480.   IView iview = IViewGetIView(w);
  481.   if (iview == nil) StPerror("No IView installed in this window");
  482.   if (showing != nil) *showing = iview->x_axis.showing;
  483.   if (labeled != nil) *labeled = iview->x_axis.labeled;
  484.   if (ticks != nil) *ticks = iview->x_axis.ticks;
  485. }
  486.  
  487. void IViewSetYaxis(w, showing, labeled, ticks)
  488.     IVIEW_WINDOW w;
  489.     int showing, labeled, ticks;
  490. {
  491.   set_axis(w, 'Y', showing, labeled, ticks);
  492. }
  493.  
  494. void IViewGetYaxis(w, showing, labeled, ticks)
  495.     IVIEW_WINDOW w;
  496.     int *showing, *labeled, *ticks;
  497. {
  498.   IView iview = IViewGetIView(w);
  499.   if (iview == nil) StPerror("No IView installed in this window");
  500.   if (showing != nil) *showing = iview->y_axis.showing;
  501.   if (labeled != nil) *labeled = iview->y_axis.labeled;
  502.   if (ticks != nil) *ticks = iview->y_axis.ticks;
  503. }
  504.  
  505. static void draw_tick(w, x, y, value, axis)
  506.     IVIEW_WINDOW w;
  507.     int x, y, axis;
  508.     double value;
  509. {
  510.   char s[100];
  511.   int offset;
  512.   /*char*/ StGWWinInfo *gwinfo = IViewWindowWinInfo(w); /* changed JKL */
  513.   
  514.   offset = StGWTextWidth(gwinfo, AXIS_LABEL_TEMPLATE) / 3;
  515.   switch (axis) {
  516.   case 'X':
  517.     offset += AXIS_TICK_LENGTH + StGWTextAscent(gwinfo);
  518.     StGWDrawLine(gwinfo, x, y, x, y + AXIS_TICK_LENGTH);
  519.     sprintf(s, "%.3g", value);
  520.     StGWDrawText(gwinfo, s, x, y + offset, 1, 0);
  521.     break;
  522.   case 'Y':
  523.     offset += AXIS_TICK_LENGTH + AXIS_LABEL_GAP;
  524.     StGWDrawLine(gwinfo, x, y, x - AXIS_TICK_LENGTH, y);
  525.     sprintf(s, "%.3g", value);
  526.     StGWDrawTextUp(gwinfo, s, x - offset, y, 1, 0);
  527.     break;
  528.   }
  529. }
  530.   
  531. void IViewDrawAxes(w)
  532.     IVIEW_WINDOW w;
  533. {
  534.   IView iview = IViewGetIView(w);
  535.   int left, top, width, height, right, bottom, x, y;
  536.   double low, high, value;
  537.   int offset, tick, i;
  538.   /*char*/ StGWWinInfo *gwinfo = IViewWindowWinInfo(w);/* changed JKL */
  539.   
  540.   if (iview == nil) StPerror("No IView installed in this window");
  541.   StGrGetContentVariables(gwinfo, &x, &y);
  542.   StGrGetContentRect(gwinfo, &left, &top, &width, &height);
  543.   right = left + width;
  544.   bottom = top + height;
  545.   
  546.   offset = StGWTextWidth(gwinfo, AXIS_LABEL_TEMPLATE) / 3;
  547.   if (iview->x_axis.showing) {
  548.     StGWDrawLine(gwinfo, left, bottom + 1, right, bottom + 1);
  549.     IViewGetRange(w, x, &low, &high);
  550.     if (iview->x_axis.ticks >= 2) {
  551.       draw_tick(w, left, bottom + 1, low, 'X'); 
  552.       draw_tick(w, right, bottom + 1, high, 'X');
  553.       for (i = 1; i < iview->x_axis.ticks - 1; i++) {
  554.         tick = left + (((double) i) * width) / (iview->x_axis.ticks - 1);
  555.         value = low + i * (high - low) / (iview->x_axis.ticks - 1);
  556.         draw_tick(w, tick, bottom + 1, value, 'X');
  557.       }
  558.     }
  559.     if (iview->x_axis.labeled) {
  560.       offset += AXIS_TICK_LENGTH + AXIS_LABEL_GAP + 2 * StGWTextAscent(gwinfo);
  561.       StGWDrawText(gwinfo, IViewVariableLabel(w, x),
  562.                            (left + right) / 2, bottom + offset, 1, 0);
  563.     }
  564.   }
  565.   offset = StGWTextWidth(gwinfo, AXIS_LABEL_TEMPLATE) / 3;
  566.   if (iview->y_axis.showing) {
  567.     StGWDrawLine(gwinfo, left - 1, bottom, left - 1, top);
  568.     IViewGetRange(w, y, &low, &high);
  569.     if (iview->y_axis.ticks >= 2) {
  570.       draw_tick(w, left - 1, bottom, low, 'Y'); 
  571.       draw_tick(w, left - 1, top, high, 'Y');
  572.       for (i = 1; i < iview->y_axis.ticks - 1; i++) {
  573.         tick = bottom - (((double) i) * height) / (iview->y_axis.ticks - 1);
  574.         value = low + i * (high - low) / (iview->y_axis.ticks - 1);
  575.         draw_tick(w, left - 1, tick, value, 'Y');
  576.       }
  577.     }
  578.     if (iview->y_axis.labeled) {
  579.       offset += AXIS_TICK_LENGTH + 2 * AXIS_LABEL_GAP + StGWTextAscent(gwinfo);
  580.       StGWDrawTextUp(gwinfo, IViewVariableLabel(w, y),
  581.                             left - offset, (top + bottom) / 2, 1, 0);
  582.     }
  583.   }
  584. }
  585.  
  586. /**************************************************************************/
  587. /**                                                                      **/
  588. /**                           Brush Functions                            **/
  589. /**                                                                      **/
  590. /**************************************************************************/
  591.  
  592. void IViewSetBrush(w, x, y, width, height)
  593.      IVIEW_WINDOW w;
  594.      int x, y, width, height;
  595. {
  596.   IView iview = IViewGetIView(w);
  597.   int showing = iview->brush.showing;
  598.   if (iview == nil) return;
  599.  
  600.   if (showing) IViewEraseBrush(w);
  601.   iview->brush.left = x - width;
  602.   iview->brush.top = y - height;
  603.   iview->brush.width = width;
  604.   iview->brush.height = height;
  605.   if (showing) IViewDrawBrush(w);
  606. }
  607.  
  608. void IViewGetBrush(w, x, y, width, height)
  609.      IVIEW_WINDOW w;
  610.      int *x, *y, *width, *height;
  611. {
  612.   IView iview = IViewGetIView(w);
  613.   if (iview == nil) return;
  614.  
  615.   if (x != nil) *x = iview->brush.left + iview->brush.width;
  616.   if (y != nil) *y = iview->brush.top + iview->brush.height;
  617.   if (width != nil) *width = iview->brush.width;
  618.   if (height != nil) *height = iview->brush.height;
  619. }
  620.  
  621. void IViewEraseBrush(w)
  622.      IVIEW_WINDOW w;
  623. {
  624.   /*char*/ StGWWinInfo *gwinfo = IViewWindowWinInfo(w);/* changed JKL */
  625.   IView iview = IViewGetIView(w);
  626.   int mode, type;
  627.   
  628.   if (iview != nil && iview->brush.showing) {
  629.     mode = StGWDrawMode(gwinfo); StGWSetDrawMode(gwinfo, 1);
  630.     type = StGWLineType(gwinfo); StGWSetLineType(gwinfo, 1);
  631.     StGWFrameRect(gwinfo, iview->brush.left, iview->brush.top,
  632.                           iview->brush.width, iview->brush.height);
  633.     iview->brush.showing = FALSE;
  634.     StGWSetDrawMode(gwinfo, mode);
  635.     StGWSetLineType(gwinfo, type);
  636.   }
  637. }
  638.  
  639. void IViewDrawBrush(w)
  640.      IVIEW_WINDOW w;
  641. {
  642.   /*char*/ StGWWinInfo *gwinfo = IViewWindowWinInfo(w);/* changed JKL */
  643.   IView iview = IViewGetIView(w);
  644.   int mode, type;
  645.  
  646.   if (iview != nil && ! iview->brush.showing) {
  647.     mode = StGWDrawMode(gwinfo); StGWSetDrawMode(gwinfo, 1);
  648.     type = StGWLineType(gwinfo); StGWSetLineType(gwinfo, 1);
  649.     StGWFrameRect(gwinfo, iview->brush.left, iview->brush.top,
  650.                           iview->brush.width, iview->brush.height);
  651.     iview->brush.showing = TRUE;
  652.     StGWSetDrawMode(gwinfo, mode);
  653.     StGWSetLineType(gwinfo, type);
  654.   }
  655. }
  656.  
  657. void IViewMoveBrush(w, x, y)
  658.      IVIEW_WINDOW w;
  659. {
  660.   IView iview = IViewGetIView(w);
  661.   if (iview == nil) return;
  662.  
  663.   IViewEraseBrush(w);
  664.   iview->brush.left = x - iview->brush.width;
  665.   iview->brush.top = y - iview->brush.height;
  666.   IViewDrawBrush(w);
  667. }
  668.  
  669. /**************************************************************************/
  670. /**                                                                      **/
  671. /**                      Mouse Action Functions                          **/
  672. /**                                                                      **/
  673. /**************************************************************************/
  674.  
  675. static struct {
  676.   int x, y, left, top, width, height;
  677. } dragRect;
  678.  
  679. static void drag(w, x, y)
  680.      IVIEW_WINDOW w;
  681.      int x, y;
  682. {
  683.   /*char*/ StGWWinInfo *gwinfo = IViewWindowWinInfo(w);/* changed JKL */
  684.   
  685.   if (dragRect.width != 0 && dragRect.height != 0) 
  686.     StGWFrameRect(gwinfo, dragRect.left, dragRect.top, 
  687.                           dragRect.width, dragRect.height);
  688.   dragRect.width = abs(dragRect.x - x); 
  689.   dragRect.height = abs(dragRect.y - y);
  690.   dragRect.left = (x < dragRect.x) ? x : dragRect.x; 
  691.   dragRect.top = (y < dragRect.y) ? y : dragRect.y; 
  692.   if (dragRect.width != 0 && dragRect.height != 0) 
  693.     StGWFrameRect(gwinfo, dragRect.left, dragRect.top, 
  694.                           dragRect.width, dragRect.height);
  695. }
  696.  
  697. void IViewStdSelectingMouseAction(w, x, y, type, mods)
  698.      IVIEW_WINDOW w;
  699.      int x, y;
  700.      MouseEventType type;
  701.      MouseClickModifier mods;
  702. {
  703.   int mode, line_type;
  704.   int clickwidth, clickheight;
  705.   /*char*/ StGWWinInfo *gwinfo = IViewWindowWinInfo(w);/* changed JKL */
  706.  
  707.   if (type == MouseClick) {
  708.     if (mods != ExtendModifier) IViewUnselectAllPoints(w);
  709.     StGrGetClickRange(gwinfo, &clickwidth, &clickheight);
  710.     IViewAdjustPointsInRect(w, x - clickwidth / 2, y - clickheight / 2,
  711.                                clickwidth, clickheight, pointSelected);
  712.     
  713.     mode = StGWDrawMode(gwinfo); StGWSetDrawMode(gwinfo, 1);
  714.     line_type = StGWLineType(gwinfo); StGWSetLineType(gwinfo, 1);
  715.     dragRect.x = x; dragRect.y = y;
  716.     dragRect.left = x, dragRect.top = y;
  717.     dragRect.width = 0; dragRect.height = 0;
  718.     StGWWhileButtonDown(gwinfo, drag, TRUE);
  719.     if (dragRect.width != 0 && dragRect.height != 0)
  720.     StGWFrameRect(gwinfo, dragRect.left, dragRect.top, 
  721.                           dragRect.width, dragRect.height);
  722.     StGWSetDrawMode(gwinfo, mode);
  723.     StGWSetLineType(gwinfo, line_type);
  724.  
  725.     IViewAdjustPointsInRect(w, dragRect.left, dragRect.top,
  726.                                dragRect.width, dragRect.height, pointSelected);
  727.   }
  728. }
  729.  
  730. static void dragbrush(w, x, y)
  731.      IVIEW_WINDOW w;
  732.      int x, y;
  733. {
  734.   IView iview = IViewGetIView(w);
  735.   
  736.   IViewMoveBrush(w, x, y);
  737.   IViewAdjustPointsInRect(w, iview->brush.left, iview->brush.top,
  738.                              iview->brush.width, iview->brush.height,
  739.                              pointSelected);
  740. }
  741.  
  742. void IViewStdBrushingMouseAction(w, x, y, type, mods)
  743.      IVIEW_WINDOW w;
  744.      int x, y;
  745.      MouseEventType type;
  746.      MouseClickModifier mods;
  747. {
  748.   IView iview = IViewGetIView(w);
  749.   /*char*/ StGWWinInfo *gwinfo = IViewWindowWinInfo(w);/* changed JKL */
  750.  
  751.   IViewMoveBrush(w, x, y);
  752.   if (type == MouseClick) {
  753.     if (mods != ExtendModifier) IViewUnselectAllPoints(w);
  754.     StGWWhileButtonDown(gwinfo, dragbrush, TRUE);
  755.   }
  756.   else if (type == MouseMove) {
  757.     IViewMoveBrush(w, x, y);
  758.     IViewAdjustPointsInRect(w, iview->brush.left, iview->brush.top,
  759.                                iview->brush.width, iview->brush.height, pointHilited);
  760.   }
  761. }
  762.  
  763. void IViewStdMouseAction(w, x, y, type, mods)
  764.      IVIEW_WINDOW w;
  765.      int x, y;
  766.      MouseEventType type;
  767.      MouseClickModifier mods;
  768. {
  769.   switch (IViewMouseMode(w)) {
  770.   case selecting: IViewStdSelectingMouseAction(w, x, y, type, mods); break;
  771.   case brushing:  IViewStdBrushingMouseAction(w, x, y, type, mods); break;
  772.   }
  773. }
  774.  
  775. void IViewStdUnselectAllPoints(w)
  776.      IVIEW_WINDOW w;
  777. {
  778.   int i, n = IViewNumPoints(w);
  779.   IViewCheckLinks(w);
  780.   IViewClearPointMarks(w);
  781.   for (i = 0; i < n; i++)
  782.     if ((int) IViewPointState(w, i) > (int) pointNormal 
  783.         && ! IViewPointMasked(w, i)) 
  784.       IViewSetPointState(w, i, pointNormal);
  785.   IViewAdjustScreens(w);
  786. }
  787.  
  788. void IViewEraseSelection(w)
  789.     IVIEW_WINDOW w;
  790. {
  791.   int n = IViewNumPoints(w), i;
  792.   IViewCheckLinks(w);
  793.   IViewClearPointMarks(w);
  794.   for (i = 0; i < n; i++) 
  795.     if (IViewPointState(w, i) == pointSelected)
  796.       IViewSetPointState(w, i, pointInvisible);
  797.   IViewAdjustScreens(w);
  798. }
  799.  
  800. void IViewMaskSelection(w)
  801.     IVIEW_WINDOW w;
  802. {
  803.   int n = IViewNumPoints(w), i;
  804.   
  805.   IViewClearPointMarks(w);
  806.   for (i = 0; i < n; i++) 
  807.     if (IViewPointState(w, i) == pointSelected)
  808.       IViewSetPointMask(w, i, TRUE);
  809.   IViewRedrawContent(w);
  810. }
  811.  
  812. void IViewUnmaskAllPoints(w)
  813.     IVIEW_WINDOW w;
  814. {
  815.   int n = IViewNumPoints(w), i;
  816.   
  817.   IViewClearPointMarks(w);
  818.   for (i = 0; i < n; i++) IViewSetPointMask(w, i, FALSE);
  819.   IViewRedrawContent(w);
  820. }
  821.  
  822. void IViewShowAllPoints(w)
  823.     IVIEW_WINDOW w;
  824. {
  825.   int n = IViewNumPoints(w), i;
  826.   IViewCheckLinks(w);
  827.   IViewClearPointMarks(w);
  828.   for (i = 0; i < n; i++) IViewSetPointState(w, i, pointNormal);
  829.   IViewAdjustScreens(w);
  830. }
  831.  
  832. int IViewAllPointsShowing(w)
  833.     IVIEW_WINDOW w;
  834. {
  835.   int result = TRUE, n = IViewNumPoints(w), i;
  836.   
  837.   for (i = 0; i < n && result; i++)
  838.     if (IViewPointState(w, i) == pointInvisible) result = FALSE;
  839.   return(result);
  840. }
  841.  
  842. int IViewAllPointsUnmasked(w)
  843.     IVIEW_WINDOW w;
  844. {
  845.   int result = TRUE, n = IViewNumPoints(w), i;
  846.   
  847.   for (i = 0; i < n && result; i++)
  848.     if (IViewPointMasked(w, i)) result = FALSE;
  849.   return(result);
  850. }
  851.  
  852. int IViewAnyPointsSelected(w)
  853.     IVIEW_WINDOW w;
  854. {
  855.   int result = FALSE, n = IViewNumPoints(w), i;
  856.   
  857.   for (i = 0; i < n && ! result; i++)
  858.     if (IViewPointState(w, i) == pointSelected) result = TRUE;
  859.   return(result);
  860. }
  861.  
  862. /*************************************************************************/
  863. /**                                                                     **/
  864. /**                      IView Linking Functions                        **/
  865. /**                                                                     **/
  866. /*************************************************************************/
  867. #ifdef OLDLINKS
  868. typedef struct IViewEntry{
  869.   IVIEW_WINDOW w;
  870.   struct IViewEntry *next;
  871. } IViewEntry;
  872.  
  873. static IViewEntry *LinkedList = nil;
  874.  
  875. int IViewInternalIsLinked(w)
  876.      IVIEW_WINDOW w;
  877. {
  878.   register IViewEntry *entry;
  879.   
  880.   for (entry = LinkedList; entry != nil; entry = entry->next) {
  881.     if (entry->w == w)
  882.       return (TRUE);
  883.   }
  884.   return (FALSE);
  885. }
  886.  
  887. void IViewLinkWindow(w)
  888.      IVIEW_WINDOW w;
  889. {
  890.   IViewEntry *entry;
  891.   int i, n = IViewNumPoints(w);
  892.   
  893. #ifdef CHECK_ACTIVE_IVIEW
  894.   if (w == nil || ! IViewWindowIsActive(w) || IViewInternalIsLinked(w)) return;
  895. #else
  896.   if (w == nil || IViewInternalIsLinked(w)) return;
  897. #endif CHECK_ACTIVE_IVIEW  
  898.   entry = (IViewEntry *) StCalloc(1, sizeof(IViewEntry));
  899.   
  900.   entry->w = w;
  901.   entry->next = LinkedList;
  902.   LinkedList = entry;
  903.   IViewSetIsLinked(w, TRUE);
  904.   
  905.   for (i = 0; i < n; i++) IViewMatchPointState(w, i);
  906.   IViewAdjustScreens(w);
  907. }
  908.  
  909. void IViewUnlinkWindow(w)
  910.      IVIEW_WINDOW w;
  911. {
  912.   register IViewEntry    *entry, *entry2;
  913.   
  914.   IViewSetIsLinked(w, FALSE);
  915.  
  916.   if (LinkedList != nil) {               /* if list empty, ignore */
  917.     if ((*LinkedList).w == w) {           /* is it the first element? */
  918.       entry2 = LinkedList;
  919.       LinkedList = LinkedList->next;
  920.     }
  921.     else {
  922.       for (entry = LinkedList; entry != nil; entry = entry2) {
  923.         entry2 = entry->next;
  924.         if (entry2 == nil)
  925.           return;                      /* w not in list! */
  926.         if (entry2->w == w)    {          /* found it */
  927.            entry->next = entry2->next;
  928.            break;
  929.         }
  930.       }
  931.     }
  932.     StFree(entry2);                 /* get rid of entry record */
  933.   }
  934. }
  935.  
  936. void IViewUnlinkAllWindows(void)
  937. {
  938.   IViewEntry *view_list;
  939.   IVIEW_WINDOW w;
  940.   
  941.   for (view_list = LinkedList; view_list != nil;) {
  942.     w = view_list->w;
  943.     view_list = view_list->next;
  944.     IViewUnlinkWindow(w);
  945.   }
  946. }
  947.  
  948. void IViewMatchPointState(w, p)
  949.      IVIEW_WINDOW w;
  950.      unsigned p;
  951. {
  952.   IViewEntry *list;
  953.  
  954.   for (list = LinkedList; list != nil; list = list->next) {
  955.     if (w != list->w && IViewPointState(w, p) != IViewPointState(list->w, p)) {
  956.       IViewSetPointScreenState(list->w, p, IViewPointState(list->w, p));
  957.       IViewDataSetPointState(IViewData(list->w), p, IViewPointState(w, p));
  958.       IViewAdjustOwnScreenPoint(list->w, p);
  959.       IViewSetPointScreenState(list->w, p, IViewPointState(list->w, p));
  960.     }
  961.   }
  962. }
  963.  
  964. void IViewAdjustScreens(w)
  965.     IVIEW_WINDOW w;
  966. {
  967.   IViewEntry *list;
  968.  
  969.   IViewAdjustOwnScreen(w);
  970.   if (IViewIsLinked(w)) {
  971.     for (list = LinkedList; list != nil; list = list->next)
  972.       if (w != list->w) IViewAdjustOwnScreen(list->w);
  973.   }
  974. }
  975.  
  976. static void IViewSetIsLinked(w, linked)
  977.      IVIEW_WINDOW w;
  978.      int linked;
  979. {
  980.   IView iview = IViewGetIView(w);
  981.   if (iview == nil) StPerror("No IView installed in this window");
  982.   iview->links = linked;
  983. }
  984.  
  985. int IViewIsLinked(w)
  986.      IVIEW_WINDOW w;
  987. {
  988.   IView iview = IViewGetIView(w);
  989.   if (iview == nil) StPerror("No IView installed in this window");
  990.   return(iview->links != nil);
  991. }
  992.  
  993. IViewCheckLinks(w) IVIEW_WINDOW w; {}
  994.  
  995. #else
  996. void IViewSetLinks(w, links)
  997.      IVIEW_WINDOW w;
  998.      long links;
  999. {
  1000.   IView iview = IViewGetIView(w);
  1001.   if (iview == nil) StPerror("No IView installed in this window");
  1002.   iview->links = links;
  1003. }
  1004.  
  1005. long IViewGetLinks(w)
  1006.      IVIEW_WINDOW w;
  1007. {
  1008.   IView iview = IViewGetIView(w);
  1009.   if (iview == nil) StPerror("No IView installed in this window");
  1010.   return(iview->links);
  1011. }
  1012.  
  1013. int IViewIsLinked(w)
  1014.      IVIEW_WINDOW w;
  1015. {
  1016.   IView iview = IViewGetIView(w);
  1017.   if (iview == nil) return(FALSE);
  1018.   else return(iview->links != nil);
  1019. }
  1020.  
  1021. static void IViewSetIsLinked(w, linked)
  1022.      IVIEW_WINDOW w;
  1023.      int linked;
  1024. {
  1025.   IView iview = IViewGetIView(w);
  1026.   if (iview == nil) StPerror("No IView installed in this window");
  1027.   iview->links = linked;
  1028. }
  1029. #endif OLDLINKS
  1030.