home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 6 / FreshFish_September1994.bin / bbs / misc / cp-4.3.lha / cP / Source / drawview.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-03  |  31.1 KB  |  1,400 lines

  1. #include "cp.h"
  2.  
  3. #define SIZETIC  5  /* size major tik in pixels */
  4. #define BOXOFF   10  /* add to filename box size */
  5. #define TIKCOLOR 2  /* color for tiks */
  6. #define BORDER   20 /* size between filename boxes */
  7.  
  8. struct RastPort *rp;
  9. struct ViewPort *vp;
  10.  
  11. struct World wd;
  12. struct CurView cv;
  13. struct CurView ov;
  14.  
  15. WORD WIDTH;
  16. WORD HEIGHT;
  17. WORD OFFSET;
  18.  
  19. WORD xoff;
  20. WORD yoff;
  21.  
  22. LONG precision = 2L;
  23.  
  24. /* Draw everything if full is TRUE autoscale */
  25.  
  26. void DrawView ( BOOL full )
  27. {
  28.  
  29.       vp = &(Scr-> ViewPort); /* Always reinit since could be new screen */
  30.       rp = PlotWindowWnd-> RPort;
  31.  
  32.     if (cv.xmin>=cv.xmax||cv.ymin>=cv.ymax)    FindWorld ();
  33.  
  34.      if( !(IsListEmpty(SetList)))
  35.        {
  36.  
  37.           if( full ) FindWorld ();
  38.     
  39.         if (! HandlePlotWindowIDCMP()) Death(0);
  40.  
  41.           SetAPen(rp,1);
  42.  
  43.           OFFSET = rp->Font->tf_YSize + 2 * BORDER + Scr-> BarHeight;
  44.           HEIGHT = PlotWindowWnd-> Height - OFFSET - ( CPANEL ? 4 : 3 ) * GADHEIGHT;
  45.  
  46.           yoff = OFFSET + HEIGHT;
  47.  
  48.           xoff = rp-> Font-> tf_XSize * 6 + BORDER + SIZETIC;
  49.  
  50.           DrawFileNameBoxes( yoff - HEIGHT);
  51.  
  52.           if ( WIDTH < BORDER || HEIGHT < BORDER ) Death(20);
  53.  
  54.           DrawColorBox( xoff , yoff, WIDTH, HEIGHT, 14);
  55.  
  56.           XAxis();
  57.           YAxis();
  58.           LabelTitle();
  59.           
  60.           DrawAllSets ();
  61.  
  62.           if ( sym ) SymAllSets();
  63.           if ( grid ) Grid();
  64.        }
  65.      else
  66.          Erase( TRUE );
  67.          
  68. }
  69.  
  70. /* Draw all sets in SetList */
  71.  
  72. void DrawAllSets ()
  73. {
  74. WORD p = 4;
  75. struct Set *node;
  76.  
  77.      for ( node = (struct Set *)SetList-> lh_Head; node-> snode.ln_Succ; node = (struct Set *)node-> snode.ln_Succ )
  78.        {
  79.  
  80.           SetAPen(rp,min(p,lastcolor));
  81.  
  82.           DrawSet ( node-> FirstPoint );
  83.  
  84.           p++;
  85.  
  86.           if ( p > lastcolor - 2 ) p = 4;
  87.  
  88.              if(! HandlePlotWindowIDCMP())    Death(5);
  89.  
  90.        }
  91. }
  92.  
  93. /* Draw symbols on all sets */
  94.  
  95. void SymAllSets ()
  96. {
  97. struct Set *node;
  98.  
  99.      SetDrMd( rp, JAM2);
  100.  
  101.      if (depth > 2)
  102.           SetAPen(rp,15);
  103.      else
  104.           SetAPen(rp,1);
  105.  
  106.      for ( node = (struct Set *)SetList-> lh_Head; node-> snode.ln_Succ; node = (struct Set *)node-> snode.ln_Succ )
  107.        {
  108.  
  109.           SymSet ( node-> FirstPoint );
  110.  
  111.              if(! HandlePlotWindowIDCMP())    Death(5);
  112.  
  113.        }
  114. }
  115.  
  116. /* Adjust view so all data sets show */
  117.  
  118. void FindWorld ()
  119. {
  120. struct Set *node;
  121.  
  122.      node = (struct Set *)SetList-> lh_Head;
  123.  
  124.      wd.xmax = node-> xmax;
  125.      wd.xmin = node-> xmin;
  126.      wd.ymax = node-> ymax;
  127.      wd.ymin = node-> ymin;
  128.  
  129.      for ( node = (struct Set *)SetList-> lh_Head; node-> snode.ln_Succ; node = (struct Set *)node-> snode.ln_Succ )
  130.        {
  131.  
  132.           wd.xmax = max( wd.xmax, node-> xmax);
  133.           wd.xmin = min( wd.xmin, node-> xmin);
  134.           wd.ymax = max( wd.ymax, node-> ymax);
  135.           wd.ymin = min( wd.ymin, node-> ymin);
  136.  
  137.        }
  138.  
  139.      ov.xmax = cv.xmax = wd.xmax;
  140.      ov.xmin = cv.xmin = wd.xmin;
  141.      ov.ymax = cv.ymax = wd.ymax;
  142.      ov.ymin = cv.ymin = wd.ymin;
  143.  
  144.      wd.xdelta = wd.xmax - wd.xmin;
  145.      wd.ydelta = wd.ymax - wd.ymin;
  146.  
  147.      ov.xdelta = cv.xdelta = wd.xdelta;
  148.      ov.ydelta = cv.ydelta = wd.ydelta;
  149. }
  150.  
  151. /* Draw one set */
  152.  
  153. void DrawSet ( struct Point *ThisPoint )
  154. {
  155. LONG qx, qy;
  156. LONG le, te, re, be;
  157.  
  158. struct Rectangle rect;
  159. struct Region *new_region;
  160. struct Region *old_region;
  161.  
  162.      rect.MinX = xoff;
  163.      rect.MaxX = xoff + WIDTH;
  164.      rect.MinY = yoff - HEIGHT;
  165.      rect.MaxY = yoff;
  166.  
  167.      le = PlotWindowWnd-> LeftEdge;
  168.      te = PlotWindowWnd-> TopEdge;
  169.      re = PlotWindowWnd-> LeftEdge + PlotWindowWnd-> Width;
  170.      be = PlotWindowWnd-> TopEdge + PlotWindowWnd-> Height;
  171.  
  172.      if ( ! (new_region = NewRegion())) return;
  173.  
  174.      if ( ! (OrRectRegion( new_region, &rect))) return;
  175.  
  176.      if (( old_region = InstallClipRegion( PlotWindowWnd-> WLayer, new_region ))) return;
  177.  
  178.      qx = ScaleX( ThisPoint-> xval);
  179.      qy = ScaleY( ThisPoint-> yval);
  180.  
  181.      if ( qx < le ) qx = le;
  182.      if ( qx > re ) qx = re;
  183.      if ( qy < te ) qy = te;
  184.      if ( qy > be ) qy = be;
  185.  
  186.      Move ( rp, qx, qy );
  187.  
  188.      do
  189.        {
  190.  
  191.           ThisPoint = ThisPoint-> NextPoint;
  192.  
  193.           qx = ScaleX( ThisPoint-> xval);
  194.  
  195.           /* need to change if not time sampled data */
  196.           if ( qx < le ) continue;
  197.           if ( qx > re && RealTime ) break;
  198.  
  199.           qy = ScaleY( ThisPoint-> yval);
  200.  
  201.           if ( qy < te ) qy = te;
  202.           if ( qy > be ) qy = be;
  203.  
  204.           Draw ( rp, qx, qy);
  205.  
  206.        } while ( ThisPoint-> NextPoint );
  207.  
  208.      new_region = InstallClipRegion(PlotWindowWnd->WLayer, old_region);
  209.  
  210.      DisposeRegion(new_region);
  211. }
  212.  
  213. /* draw symbols on one set */
  214.  
  215. void SymSet ( struct Point *ThisPoint )
  216. {
  217. LONG qx, qy;
  218. WORD dx, dy;
  219. BOOL clip;
  220.  
  221.      dx = xoff + WIDTH;
  222.      dy = yoff - HEIGHT;
  223.  
  224.      do {
  225.  
  226.  
  227.           clip = FALSE;
  228.  
  229.           qx = ScaleX( ThisPoint-> xval);
  230.           qy = ScaleY( ThisPoint-> yval);
  231.  
  232.           if ( qx < xoff )
  233.             {
  234.                qx = xoff;
  235.                clip = TRUE;
  236.             }
  237.           else if ( qx > dx )
  238.             {
  239.                qx = dx;
  240.                clip = TRUE;
  241.             }
  242.           if ( qy > yoff )
  243.             {
  244.                qy = yoff;
  245.                clip = TRUE;
  246.             }
  247.           else if ( qy < dy )
  248.             {
  249.                qy = dy;
  250.                clip = TRUE;
  251.             }
  252.  
  253.           if ( !clip )
  254.             {
  255.                Move ( rp, qx - 1, qy + 1);
  256.                Draw ( rp, qx + 1, qy - 1);
  257.                Move ( rp, qx + 1, qy + 1);
  258.                Draw ( rp, qx - 1, qy - 1);
  259.             }
  260.  
  261.           ThisPoint = ThisPoint-> NextPoint;
  262.  
  263.      } while ( ThisPoint );
  264. }
  265.  
  266. /* Draw recessed bevel box filled with color */
  267.  
  268. void DrawColorBox ( WORD xs ,WORD ys , WORD xw ,WORD yh, WORD color)
  269. {
  270.  
  271.      SetAPen( rp, (MONO ? 0 : color));
  272.  
  273.      RectFill( rp, xs, ys - yh - 1, xs + xw, ys + 1 );
  274.  
  275.      DrawBevelBox( rp, xs - 2, ys - yh - 1 , xw + 5, yh + 4, GT_VisualInfo, VisualInfo, GTBB_Recessed, TRUE, TAG_DONE);
  276. }
  277.  
  278.  
  279. /* Draw Color boxes with filenames in them */
  280.  
  281. WORD DrawFileNameBoxes( WORD ys)
  282. {
  283. struct Set *node;
  284. struct TextExtent txex;
  285. WORD p = 4, h = 0, w = 0, xs, ns = 0;
  286.  
  287.  
  288.      for ( node = (struct Set *)SetList-> lh_Head; node-> snode.ln_Succ; node = (struct Set *)node-> snode.ln_Succ )
  289.        {
  290.           TextExtent( rp, node-> fn, strlen( node-> fn ), &txex);
  291.  
  292.           w = max( w, txex.te_Width);
  293.           h = max( h, txex.te_Height);
  294.  
  295.           ns++;
  296.        }
  297.  
  298.      w += BOXOFF;
  299.      h += BOXOFF;
  300.  
  301.      SetBPen( rp, 1);
  302.  
  303.      if ( ns > 1 )
  304.           xs = PlotWindowWnd-> Width - w - BORDER;
  305.      else
  306.        {
  307.           xs = ( PlotWindowWnd-> Width / 2 - w / 2);
  308.           ys = (WORD)(txex.te_Height * 1.5);
  309.        }
  310.  
  311.      WIDTH = PlotWindowWnd-> Width - (ns > 1 ? w + 2 * BORDER : xoff) - xoff; /* if only one set fnbox on top so width = windowwidth - 2*xoff */
  312.  
  313.     Erase(FALSE); /* need to erase before drawing fnboxes but could not get calc width till now */
  314.     
  315.     if (NOFNAME) /* if not drawing filename boxes set box symetrical and return */
  316.       {
  317.           WIDTH = PlotWindowWnd-> Width - ( 2 * xoff);
  318.           return((WORD)xoff);
  319.       }
  320.  
  321.      for ( node = (struct Set *)SetList-> lh_Head; node-> snode.ln_Succ; node = (struct Set *)node-> snode.ln_Succ )
  322.        {
  323.           SetAPen( rp, p);
  324.  
  325.           ys += h;
  326.  
  327.           TextExtent( rp, node-> fn, strlen( node-> fn ), &txex);
  328.  
  329.           if ( MONO == FALSE ) DrawColorBox( xs , ys, w, h, p );
  330.  
  331.           SetDrMd( rp, (JAM2 | INVERSVID));
  332.  
  333.           Move ( rp, xs + w/2 - txex.te_Width/2 , ys - BOXOFF / 2 );
  334.           Text( rp, node-> fn, strlen( node-> fn));
  335.  
  336.           ys += BORDER;
  337.  
  338.           SetDrMd( rp, JAM2);
  339.  
  340.           p++;
  341.           if ( p > lastcolor - 2 ) p = 4;
  342.        }
  343.  
  344.      return (WORD)( ns > 1 ? w + 2 * BORDER : xoff ); /* return no longer used for anything */
  345. }
  346.  
  347. /* Adjust xmin and xmax to even nubers and draw tiks with text */
  348.  
  349. void XAxis()
  350. {
  351.      LOGX ? logXAxis() : linXAxis();
  352. }
  353.  
  354. /* Adjust ymin and ymax to even nubers and draw tiks with text */
  355.  
  356. void YAxis()
  357. {
  358.      LOGY ? logYAxis() : linYAxis();
  359. }
  360.  
  361. void logXAxis()
  362. {
  363. LONG j, k, l;
  364. double q, r;
  365. struct TextExtent txex;
  366.  
  367.      /* Cant do negative log scale set lin */
  368.  
  369.      if( cv.xmin <= 0.0 )
  370.        {
  371.           SetWindowTitles( PlotWindowWnd, NULL, "Cant do LOG  X value <= zero" );
  372.           LOGX = FALSE;
  373.           linXAxis();
  374.           return;
  375.        }
  376.  
  377.      j = (LONG) log10( 1.00001 * cv.xmin );
  378.      if( log10( cv.xmin ) <= 0.0 ) j-- ;
  379.      cv.xmin = pow( 10.0, (double)j );
  380.  
  381.      k = (LONG) log10( 0.99999 * cv.xmax );
  382.      if( log10( cv.xmax ) > 0.0 ) k++ ;
  383.      cv.xmax = pow( 10.0, (double)k );
  384.  
  385.      cv.xdec = k - j;
  386.  
  387.      cv.xmode = -1;
  388.  
  389.      cv.xdelta = cv.xmax - cv.xmin;
  390.  
  391.      cv.xfact = 1;
  392.  
  393.     if (strlen(XLAB))
  394.       {    
  395.           TextExtent( rp, XLAB, strlen( XLAB ), &txex);
  396.  
  397.           SetAPen( rp, (MONO ? 1 : TIKCOLOR));
  398.           SetBPen( rp, 0);
  399.  
  400.           Move ( rp, xoff + WIDTH/2 - txex.te_Width/2, yoff + 2 * GADHEIGHT);
  401.           Text( rp, XLAB, strlen( XLAB ));
  402.  
  403.       }
  404.  
  405.      for( q = cv.xmin ; q < cv.xmax; j++)
  406.        {
  407.           ticX( q, TRUE);
  408.           for( l = 2; l < 10; l++)
  409.             {
  410.                r = q * l;
  411.                if( r > cv.xmax ) break;
  412.                ticX( r, FALSE);
  413.             }
  414.           q = pow( 10.0, (double)j );
  415.        }
  416.  
  417.      ticX( cv.xmax, TRUE);
  418. }
  419.  
  420. void logYAxis()
  421. {
  422. LONG j, k, l;
  423. double q, r;
  424.  
  425.      /* Cant do negative log scale set lin */
  426.  
  427.      if( cv.ymin <= 0.0 )
  428.        {
  429.  
  430.           SetWindowTitles( PlotWindowWnd, NULL, "Cant do LOG  Y value <= zero" );
  431.  
  432.           LOGY = FALSE;
  433.           linYAxis();
  434.           return;
  435.        }
  436.  
  437.      if (YLAB) LabelY(YLAB);
  438.  
  439.      j = (LONG) log10( 1.00001 * cv.ymin );
  440.      if( log10( cv.ymin ) <= 0.0 ) j-- ;
  441.      cv.ymin = pow( 10.0, (double)j );
  442.  
  443.      k = (LONG) log10( 0.99999 * cv.ymax );
  444.      if( log10( cv.ymax ) > 0.0 ) k++ ;
  445.      cv.ymax = pow( 10.0, (double)k );
  446.  
  447.      cv.ydec = k - j;
  448.  
  449.      cv.ymode = -1;
  450.  
  451.      cv.ydelta = cv.ymax - cv.ymin;
  452.  
  453.      cv.yfact = 1;
  454.  
  455.      for( q = cv.ymin ; q < cv.ymax; j++)
  456.        {
  457.           ticY( q, TRUE);
  458.           for( l = 2; l < 10; l++)
  459.             {
  460.                r = q * l;
  461.                if( r > cv.ymax ) break;
  462.                ticY( r, FALSE);
  463.             }
  464.           q = pow( 10.0, (double)j );
  465.        }
  466.  
  467.      ticY( cv.ymax, TRUE);
  468. }
  469.  
  470. void linXAxis()
  471. {
  472. double a, p;
  473. LONG b;
  474. WORD k;
  475. UBYTE s[32], t[128];
  476. struct TextExtent txex;
  477.  
  478.      /* if x all the same value kluge */
  479.  
  480.      if ( cv.xmax <= cv.xmin )
  481.        {
  482.           if ( cv.xmax == 0.0 ) cv.xmax = 1.0;
  483.           cv.xmax *= 1.01;
  484.           cv.xmin *= 0.99;
  485.        }
  486.  
  487.      /* end kluge */
  488.  
  489.      /* Calculate X View */
  490.  
  491.      cv.xtik = cv.xsubt = cv.xmode = cv.xprec = 0.0;
  492.  
  493.  
  494.      tik( cv.xmin, cv.xmax, &cv.xtik, &cv.xsubt, &cv.xmode, &cv.xprec);
  495.  
  496.      a = cv.xmin / cv.xtik;
  497.      Round ( &a );
  498.      b = (LONG)a;
  499.      if ( a < 0 && b != a ) b--;
  500.      cv.xmin = cv.xtik * b;
  501.  
  502.      a = cv.xmax / cv.xtik;
  503.      Round ( &a );
  504.      b = (LONG)a;
  505.      if ( a > 0 && b != a ) b++;
  506.      cv.xmax = cv.xtik * b;
  507.  
  508.      cv.xdelta = cv.xmax - cv.xmin;
  509.  
  510.      SetDrMd( rp, JAM1);
  511.  
  512.     if ( XLAB) strcpy( t, XLAB);
  513.     else       strcpy(t,"");
  514.  
  515.      if ( cv.xmode )
  516.        {
  517.           CalcMode ( cv.xdelta , &cv.xfact );
  518.           sprintf( s, "x %.0le", cv.xfact);
  519.           E2xTen( s );
  520.         
  521.         if (XLAB)
  522.           {
  523.               strcat( t,"  ");
  524.               strcat( t, s);
  525.           }
  526.         else strcpy( t, s);
  527.        }
  528.  
  529.     if (strlen(t))
  530.       {    
  531.           TextExtent( rp, t, strlen( t ), &txex);
  532.  
  533.           SetAPen( rp, (MONO ? 1 : TIKCOLOR));
  534.  
  535.           Move ( rp, xoff + WIDTH/2 - txex.te_Width/2, yoff + 2 * GADHEIGHT);
  536.           Text( rp, t, strlen( t ));
  537.  
  538.       }
  539.  
  540.      /* Draw Tick Marks */
  541.  
  542.      a = p = cv.xmin;
  543.      do
  544.        {
  545.           ticX( a, TRUE );
  546.           a += cv.xtik;
  547.           for ( k = 1; k <= cv.xsubt && p <= cv.xmax; k++)
  548.             {
  549.                ticX( p, FALSE);
  550.                p = a - k * cv.xtik / cv.xsubt;
  551.             }
  552.        } while ( p < cv.xmax );
  553.  
  554.      ticX( cv.xmax, TRUE);
  555. }
  556.  
  557. void linYAxis()
  558. {
  559. double a, p;
  560. LONG b;
  561. WORD k;
  562. UBYTE s[32], t[128];
  563.  
  564.      /* if y all the same value kluge */
  565.  
  566.      if ( cv.ymax == cv.ymin )
  567.        {
  568.           if ( cv.ymax == 0.0 ) cv.ymax = 1.0;
  569.           cv.ymax *= 1.01;
  570.           cv.ymin *= 0.99;
  571.        }
  572.  
  573.      /* end kluge */
  574.  
  575.      /* Calculate Y View */
  576.  
  577.      cv.ytik = cv.ysubt = cv.ymode = cv.yprec = 0.0;
  578.  
  579.      tik( cv.ymin, cv.ymax, &cv.ytik, &cv.ysubt, &cv.ymode, &cv.yprec);
  580.  
  581.      a = cv.ymin / cv.ytik;
  582.      Round ( &a );
  583.      b = (LONG)a;
  584.      if ( a < 0 && b != a ) b--;
  585.      cv.ymin = cv.ytik * b;
  586.  
  587.      a = cv.ymax / cv.ytik;
  588.      Round ( &a );
  589.      b = (LONG)a;
  590.      if ( a > 0 && b != a ) b++;
  591.      cv.ymax = cv.ytik * b;
  592.  
  593.      cv.ydelta = cv.ymax - cv.ymin;
  594.  
  595.  
  596.      SetDrMd( rp, JAM1);
  597.  
  598.     if ( YLAB) strcpy( t, YLAB);
  599.     else       strcpy(t,"");
  600.  
  601.  
  602.      if ( cv.ymode )
  603.        {
  604.           CalcMode ( cv.ydelta , &cv.yfact );
  605.  
  606.           sprintf( s, "%.0le", cv.yfact);
  607.           E2xTen( s );
  608.  
  609.         if (YLAB)
  610.           {
  611.               strcat( t,"  ");
  612.               strcat( t, s);
  613.           }
  614.         else strcpy( t, s);
  615.  
  616.  
  617.        }
  618.  
  619.     if (strlen(t))  LabelY(t);
  620.  
  621.      /* Draw Tick Marks */
  622.  
  623.      a = p = cv.ymin;
  624.      do
  625.        {
  626.           ticY( a , TRUE);
  627.           a += cv.ytik;
  628.           for ( k = 1; k <= cv.ysubt && p <= cv.ymax; k++)
  629.             {
  630.                ticY( p, FALSE);
  631.                p = a - k * cv.ytik / cv.ysubt;
  632.             }
  633.        } while ( p < cv.ymax );
  634.  
  635.      ticY( cv.ymax, TRUE);
  636. }
  637.  
  638. /* Y label text needs to be rotated 90 degrees */
  639.  
  640. void LabelY(UBYTE *lab)
  641. {
  642. struct TextExtent txex;
  643.  
  644.      TextExtent( rp, lab, strlen( lab ), &txex);
  645.      
  646.      SetAPen( rp, (MONO ? 1 : TIKCOLOR));
  647.  
  648.     Move(rp,(SHORT)(txex.te_Height*1.5), yoff - HEIGHT/2 + txex.te_Width/2);
  649.  
  650.     VertText(rp,lab,strlen(lab));
  651. }
  652.  
  653. void LabelTitle()
  654. {
  655. struct TextExtent txex;
  656.     
  657.     if (strlen(TITLE))
  658.       {
  659.           TextExtent( rp, TITLE, strlen( TITLE ), &txex);
  660.  
  661.           SetAPen( rp, (MONO ? 1 : TIKCOLOR));
  662.  
  663.           Move ( rp, xoff + WIDTH/2 - txex.te_Width/2, PlotWindowWnd-> TopEdge + 1);
  664.           Text( rp, TITLE, strlen( TITLE ));
  665.        }
  666. }
  667.  
  668. void Grid()
  669. {
  670.      if (! IsListEmpty(SetList))
  671.        {
  672.          LOGX ? logXGrid() : linXGrid() ;
  673.          LOGY ? logYGrid() : linYGrid() ;
  674.        }
  675. }
  676.  
  677. void logXGrid()
  678. {
  679. double q;
  680. double j, k;
  681. LONG x;
  682.  
  683.      SetDrMd( rp, COMPLEMENT);
  684.      SetDrPt( rp, 0x3333);
  685.  
  686.      j = log10( cv.xmin ) + 1.0;
  687.      k = log10( cv.xmax );
  688.  
  689.      for( j; j < k; j += 1.0)
  690.        {
  691.           q = pow( 10.0, (double)j );
  692.           x = ScaleX( q );
  693.           if ( x < xoff + WIDTH - 1 )
  694.             {
  695.                Move( rp, x, yoff );
  696.                Draw( rp, x, yoff - HEIGHT );
  697.             }
  698.        }
  699.  
  700.      SetDrPt( rp, 0xFFFF);
  701. }
  702.  
  703.  
  704. void logYGrid()
  705. {
  706. double q;
  707. double j, k;
  708. LONG y;
  709.  
  710.      SetDrMd( rp, COMPLEMENT);
  711.      SetDrPt( rp, 0x3333);
  712.  
  713.      j = log10( cv.ymin ) + 1.0;
  714.      k = log10( cv.ymax );
  715.  
  716.      for( j; j < k; j += 1.0)
  717.        {
  718.           q = pow( 10.0, (double)j );
  719.           y = ScaleY( q );
  720.           if ( y > yoff - HEIGHT + 1 )
  721.             {
  722.                Move( rp, xoff, y );
  723.                Draw( rp, xoff + WIDTH, y );
  724.             }
  725.        }
  726.  
  727.      SetDrPt( rp, 0xFFFF);
  728. }
  729.  
  730. void linXGrid()
  731. {
  732. double a;
  733. WORD x;
  734.  
  735.      SetDrMd( rp, COMPLEMENT);
  736.      SetDrPt( rp, 0x3333);
  737.  
  738.      a = cv.xmin;
  739.  
  740.      while ( a  < cv.xmax - cv.xtik )
  741.        {
  742.           a += cv.xtik;
  743.           x = ScaleX( (double)a );
  744.           if ( x < xoff + WIDTH - 1 )
  745.             {
  746.                Move( rp, x, yoff);
  747.                Draw( rp, x, yoff - HEIGHT);
  748.             }
  749.        }
  750.  
  751.      SetDrPt( rp, 0xFFFF);
  752. }
  753.  
  754. void linYGrid()
  755. {
  756. double a;
  757. WORD y;
  758.  
  759.      SetDrMd( rp, COMPLEMENT);
  760.      SetDrPt( rp, 0x3333);
  761.  
  762.      a = cv.ymin;
  763.  
  764.      while ( a < cv.ymax - cv.ytik )
  765.        {
  766.           a += cv.ytik;
  767.           y = ScaleY( (double)a );
  768.           if ( y > yoff - HEIGHT + 1 )
  769.             {
  770.                Move( rp, xoff, y );
  771.                Draw( rp, xoff + WIDTH, y );
  772.             }
  773.        }
  774.  
  775.      SetDrPt( rp, 0xFFFF);
  776. }
  777.  
  778. /* Color entire window with pen zero then refresh gadgets if control panel on*/
  779.  
  780. void Erase( BOOL all )
  781. {
  782. struct Rectangle frect;
  783. struct Rectangle drect;
  784. struct Region *new_region;
  785. struct Region *old_region;
  786.  
  787.  
  788.      SetDrMd( rp, JAM2);
  789.  
  790.     if ( !(IsListEmpty(SetList)) || ! all )
  791.       {
  792.          frect.MinX = 0;
  793.          frect.MaxX = PlotWindowWnd-> Width;
  794.          frect.MinY = 0;
  795.          frect.MaxY = PlotWindowWnd-> Height;
  796.  
  797.          drect.MinX = xoff;
  798.          drect.MaxX = xoff + WIDTH;
  799.          drect.MinY = yoff - HEIGHT;
  800.          drect.MaxY = yoff;
  801.  
  802.          if ( ! (new_region = NewRegion())) return;
  803.  
  804.          if ( ! (OrRectRegion(  new_region, &frect))) return;
  805.          if ( ! (XorRectRegion( new_region, &drect))) return;
  806.  
  807.          if (( old_region = InstallClipRegion( PlotWindowWnd-> WLayer, new_region ))) return;
  808.     
  809.         EraseRect( rp, 0, 0, PlotWindowWnd-> Width, PlotWindowWnd-> Height);
  810.  
  811.          new_region = InstallClipRegion(PlotWindowWnd->WLayer, old_region);
  812.  
  813.          DisposeRegion(new_region);
  814.       }
  815.     else
  816.         SetRast( rp, 0);
  817.  
  818.      if ( CPANEL ) RefreshGadgets( PlotWindowGadgets[0], PlotWindowWnd, NULL);
  819.  
  820. }
  821.  
  822. /* Draw an XAxis tik and put text if major */
  823.  
  824. void ticX ( double val, BOOL major)
  825. {
  826. LONG x, y;
  827. UBYTE tx[32];
  828. UBYTE *txp;
  829. UBYTE fm[32];
  830. double rs;
  831. struct TextExtent txex;
  832.  
  833.      x = ScaleX((double) val);
  834.      y = yoff + 3;
  835.      Move ( rp, x, y);
  836.      txp = tx;
  837.  
  838.      if ( major )
  839.           y += SIZETIC;
  840.      else
  841.           y += SIZETIC/2;
  842.  
  843.      SetDrMd( rp, JAM2);
  844.      SetBPen(rp,0);
  845.      SetAPen( rp, ( MONO ? 1 : TIKCOLOR));
  846.  
  847.      Draw( rp, x, y);
  848.  
  849.      if ( major )
  850.        {
  851.           if ( cv.xmode == 1 )
  852.             {
  853.                rs = val / cv.xfact;
  854.                Round( &rs );
  855.                sprintf( tx, "%lg", rs);
  856.             }
  857.           else if ( cv.xmode == 0 )
  858.             {
  859.                sprintf( fm, "%%.%hdlf", cv.xprec);
  860.                sprintf( tx, fm, val);
  861.             }
  862.           else if ( cv.xmode == -1 )
  863.             {
  864.                sprintf( tx, "%le", val);
  865.                E2xTen( tx );
  866.                txp++;
  867.             }
  868.  
  869.           TextExtent( rp, txp, strlen( txp ), &txex);
  870.           Move ( rp, x - txex.te_Width/2, y + txex.te_Height + SIZETIC / 2 );
  871.           Text( rp, txp, strlen( txp ));
  872.        }
  873.  
  874. }
  875.  
  876. /* Draw a YAxis tik and put text if major */
  877.  
  878. void ticY ( double val, BOOL major)
  879. {
  880. LONG x, y;
  881. UBYTE tx[32];
  882. UBYTE *txp;
  883. UBYTE fm[32];
  884. double rs;
  885. struct TextExtent txex;
  886.  
  887.      y = ScaleY((double) val);
  888.      x = xoff - 3;
  889.      Move ( rp, x, y);
  890.      txp = tx;
  891.  
  892.      if ( major )
  893.           x -= SIZETIC;
  894.      else
  895.           x -= SIZETIC/2;
  896.  
  897.      SetDrMd( rp, JAM2);
  898.      SetBPen( rp, 0);
  899.      SetAPen( rp, (MONO ? 1 : TIKCOLOR));
  900.  
  901.      Draw( rp, x, y);
  902.  
  903.      if ( major )
  904.        {
  905.           if ( cv.ymode == 1 )
  906.             {
  907.                rs = val / cv.yfact;
  908.                Round( &rs );
  909.                sprintf( tx, "%lg", rs);
  910.             }
  911.           else if ( cv.ymode == 0 )
  912.             {
  913.                sprintf( fm, "%%.%hdlf", cv.yprec);
  914.                sprintf( tx, fm, val);
  915.             }
  916.           else if ( cv.ymode == -1 )
  917.             {
  918.                sprintf( tx, "%le", val);
  919.                E2xTen( tx );
  920.                txp++;
  921.             }
  922.  
  923.  
  924.           TextExtent(rp, txp, strlen( txp ), &txex);
  925.           Move( rp, x - txex.te_Width - SIZETIC / 2, y + txex.te_Height/2 - 1);
  926.           Text( rp, txp, strlen( txp ));
  927.        }
  928. }
  929.  
  930. /* Routine does everything when Zoom gadget selected */
  931.  
  932. void Zoom()
  933. {
  934. BOOL   running = TRUE;
  935. BOOL   select = FALSE;
  936. LONG   j = 0, k = 0;
  937. WORD   selco[2];
  938. static WORD Cross [2];
  939. struct IntuiMessage *m;
  940. double a,b,c,d;
  941.  
  942.      ReportMouse( TRUE, PlotWindowWnd);
  943.      SetMouseQueue( PlotWindowWnd, 1 );
  944.      do {
  945.  
  946.        Wait ( 1L << PlotWindowWnd-> UserPort-> mp_SigBit );
  947.  
  948.        while( m = GT_GetIMsg( PlotWindowWnd->UserPort )) {
  949.  
  950.           CopyMem(( char * )m, ( char * )&PlotWindowMsg, (long)sizeof( struct IntuiMessage ));
  951.  
  952.           GT_ReplyIMsg( m );
  953.  
  954.           switch ( PlotWindowMsg.Class ) {
  955.  
  956.                case IDCMP_MOUSEMOVE:
  957.  
  958.                     if ( PlotWindowMsg.MouseX > xoff && PlotWindowMsg.MouseX < xoff + WIDTH
  959.                          && PlotWindowMsg.MouseY < yoff && PlotWindowMsg.MouseY > yoff - HEIGHT)
  960.                       {
  961.                          SetDrMd( rp, COMPLEMENT);
  962.  
  963.                          if ( k )
  964.                            {
  965.                               Move( rp, xoff, Cross[1]);
  966.                               Draw( rp, xoff + WIDTH, Cross[1]);
  967.  
  968.                               Move( rp, Cross[0], yoff);
  969.                               Draw( rp, Cross[0], yoff - HEIGHT);
  970.                            }
  971.  
  972.  
  973.                          Move( rp, xoff, PlotWindowMsg.MouseY);
  974.                          Draw( rp, xoff + WIDTH, PlotWindowMsg.MouseY);
  975.  
  976.                          Move( rp, PlotWindowMsg.MouseX, yoff);
  977.                          Draw( rp, PlotWindowMsg.MouseX, yoff - HEIGHT);
  978.  
  979.                          if ( select )
  980.                            {
  981.                               if ( j )
  982.                                 {
  983.                                    Move( rp, selco[0], selco[1]);
  984.                                    Draw( rp, selco[0], Cross[1]);
  985.                                    Move( rp, selco[0], selco[1]);
  986.                                    Draw( rp, Cross[0], selco[1]);
  987.                                 }
  988.  
  989.                               Move( rp, selco[0], selco[1]);
  990.                               Draw( rp, selco[0], PlotWindowMsg.MouseY);
  991.                               Move( rp, selco[0], selco[1]);
  992.                               Draw( rp, PlotWindowMsg.MouseX, selco[1]);
  993.  
  994.                               j++;
  995.                            }
  996.  
  997.                          Cross[0] = PlotWindowMsg.MouseX;
  998.                          Cross[1] = PlotWindowMsg.MouseY;
  999.  
  1000.                          k++;
  1001.                       }
  1002.  
  1003.                     break;
  1004.  
  1005.                case IDCMP_MOUSEBUTTONS:
  1006.                     if (PlotWindowMsg.Code == SELECTUP) running = FALSE;
  1007.                     else if (PlotWindowMsg.Code == SELECTDOWN)
  1008.                       {
  1009.                          select = TRUE;
  1010.                          selco[0] = PlotWindowMsg.MouseX;
  1011.                          selco[1] = PlotWindowMsg.MouseY;
  1012.                          SetRGB4( &Scr-> ViewPort, 17,15,15,4);  /* set xpointer yellow for select */
  1013.  
  1014.                       }
  1015.                     break;
  1016.  
  1017.                case IDCMP_VANILLAKEY:
  1018.  
  1019.                               if ( k )
  1020.                                 {
  1021.                                    Move( rp, xoff, Cross[1]);
  1022.                                    Draw( rp, xoff + WIDTH, Cross[1]);
  1023.  
  1024.                                    Move( rp, Cross[0], yoff);
  1025.                                    Draw( rp, Cross[0], yoff - HEIGHT);
  1026.                                    goto end;
  1027.                                 }
  1028.  
  1029.                default:
  1030.                     break;
  1031.           }
  1032.        }
  1033.      } while ( running);
  1034.  
  1035.         SetPointer( PlotWindowWnd, WAITPointer, WAITHEIGHT, WAITWIDTH, WAITXOFF , WAITYOFF);    /* Set pointer cross for zoom */
  1036.      
  1037.      if ( selco[0] == PlotWindowMsg.MouseX || selco[1] == PlotWindowMsg.MouseY )
  1038.        {
  1039.          ReportMouse( FALSE, PlotWindowWnd);
  1040.           DrawView( FALSE );
  1041.           return;
  1042.        }
  1043.      if ( select )
  1044.        {
  1045.        
  1046.            /* save unzoom settings */
  1047.            ov.xmin   = cv.xmin;
  1048.            ov.xmax   = cv.xmax;
  1049.            ov.ymin   = cv.ymin;
  1050.            ov.ymax   = cv.ymax;
  1051.            ov.xdelta = cv.xdelta;
  1052.            ov.ydelta = cv.ydelta;
  1053.            
  1054.  
  1055.           a = ZoomX( selco[0] );
  1056.           b = ZoomX( PlotWindowMsg.MouseX );
  1057.           c = ZoomY( selco[1] );
  1058.           d = ZoomY( PlotWindowMsg.MouseY );
  1059.  
  1060.           cv.xmin = min( a, b);
  1061.           cv.xmax = max( a, b);
  1062.  
  1063.           cv.ymin = min( c, d);
  1064.           cv.ymax = max( c, d);
  1065.  
  1066.           cv.xdelta = cv.xmax - cv.xmin;
  1067.           cv.ydelta = cv.ymax - cv.ymin;
  1068.  
  1069.          DrawView( FALSE );
  1070.      
  1071.       }
  1072. end:
  1073.       SetRGB4( &Scr-> ViewPort, 17,7, 8,15);  /* set pointer blue */
  1074.  
  1075.       ReportMouse( FALSE, PlotWindowWnd);
  1076.  
  1077. }
  1078.  
  1079. /* When mode is exponential keep in engineering units */
  1080.  
  1081. void CalcMode ( double delta , double *fact )
  1082. {
  1083. UBYTE s[32];
  1084. WORD e;
  1085. WORD j = 0, k = 0;
  1086.  
  1087.      sprintf( s ,"%.0le", delta);
  1088.  
  1089.      while ( s[k] != 'e' ) ++k;
  1090.  
  1091.      sscanf( &s[++k], "%hd", &e);
  1092.  
  1093.      if ( e < 1 )  while( j > e ) j -= 3;
  1094.      else  while( j+1 < e ) j += 3;
  1095.  
  1096.      *fact = pow( 10.0, (double)j );
  1097. }
  1098.  
  1099. /* Change exponetial to X10 */
  1100.  
  1101. void E2xTen( UBYTE *s)
  1102. {
  1103. WORD e;
  1104. WORD k = 0;
  1105.  
  1106.      while ( s[k] != 'e' && s[k] != 'E') ++k;
  1107.  
  1108.      sscanf( &s[++k], "%hd", &e);
  1109.  
  1110.      sprintf( s,"* 10%+hd",e);
  1111. }
  1112.  
  1113. /* Write X and Y to screen when mouse select
  1114.    Erase text if mouse has moved more than 3
  1115.    pixels since seldown */
  1116.  
  1117. void Identify(WORD x, WORD y, BOOL SelDOWN)
  1118. {
  1119. static WORD ox;
  1120. static WORD oy;
  1121. struct TextExtent txex;
  1122. static double zx;
  1123. static double zy;
  1124. UBYTE txt[32];
  1125. UBYTE fmt[8];
  1126.  
  1127.      SetDrMd( rp, COMPLEMENT);
  1128.  
  1129.      if( SelDOWN )
  1130.        {
  1131.           SetDrMd( rp, JAM1);
  1132.           SetAPen(rp,15);
  1133.           WritePixel( rp, x, y);
  1134.           SetAPen(rp,min(12,lastcolor));
  1135.           WritePixel( rp, x+1, y+1);
  1136.           WritePixel( rp, x+1, y-1);
  1137.           WritePixel( rp, x-1, y-1);
  1138.           WritePixel( rp, x-1, y+1);
  1139.  
  1140.           SetAPen(rp,13);
  1141.           WritePixel( rp, x+2, y+2);
  1142.           WritePixel( rp, x+2, y-2);
  1143.           WritePixel( rp, x-2, y-2);
  1144.           WritePixel( rp, x-2, y+2);
  1145.  
  1146.           zx = ZoomX( x );
  1147.           zy = ZoomY( y );
  1148.  
  1149.           SetDrMd( rp, COMPLEMENT);
  1150.        }
  1151.  
  1152.      else if ( (x >= ox - 3 && x <= ox + 3 )  && ( y >= oy - 3 && y <= oy + 3 ))
  1153.        {
  1154.           SetDrMd( rp, JAM1);
  1155.           x = ox;
  1156.           y = oy;
  1157.        }
  1158.      else
  1159.        {
  1160.           x = ox;
  1161.           y = oy;
  1162.        }
  1163.  
  1164.  
  1165.      if (depth > 2)
  1166.           SetAPen(rp,15);
  1167.      else
  1168.           SetAPen(rp,1);
  1169.  
  1170.     sprintf( fmt ,"%%.%ldlE", precision);
  1171.      sprintf( txt ,fmt, zx);
  1172.  
  1173.      TextExtent( rp, txt, strlen( txt ), &txex);
  1174.      Move ( rp, x+6, y + txex.te_Height);
  1175.      Text (rp,txt, strlen(txt));
  1176.  
  1177.      sprintf( txt ,fmt, zy);
  1178.  
  1179.      TextExtent( rp, txt, strlen( txt ), &txex);
  1180.      Move ( rp, x+6, y-2 );
  1181.      Text (rp,txt, strlen(txt));
  1182.  
  1183.      ox = x;
  1184.      oy = y;
  1185. }
  1186.  
  1187.  
  1188. int CrossHair()
  1189. {
  1190. LONG   k = 0;
  1191. BOOL  xlock = FALSE, ylock = FALSE;
  1192. static WORD Cross [2];
  1193. struct IntuiMessage *m;
  1194. double x, y;
  1195. WORD running = TRUE;
  1196. UBYTE txt[128];
  1197. UBYTE fmt[64];
  1198.  
  1199.     sprintf( fmt ,"Y = %%-%ld.%ldlE   X = %%-%ld.%ldlE", precision+6,precision,precision+6,precision);
  1200.  
  1201.         SetPointer( PlotWindowWnd, IDPointer, IDWIDTH, IDHEIGHT, IDXOFF , IDYOFF);
  1202.  
  1203.      ReportMouse( TRUE, PlotWindowWnd);
  1204.      SetMouseQueue( PlotWindowWnd, 1 );
  1205.      do {
  1206.  
  1207.        Wait ( 1L << PlotWindowWnd-> UserPort-> mp_SigBit );
  1208.  
  1209.        while( m = GT_GetIMsg( PlotWindowWnd->UserPort )) {
  1210.  
  1211.           CopyMem(( char * )m, ( char * )&PlotWindowMsg, (long)sizeof( struct IntuiMessage ));
  1212.  
  1213.           GT_ReplyIMsg( m );
  1214.  
  1215.           switch ( PlotWindowMsg.Class ) {
  1216.  
  1217.                case IDCMP_MOUSEMOVE:
  1218.  
  1219.                     if ( PlotWindowMsg.MouseX > xoff && PlotWindowMsg.MouseX < xoff + WIDTH
  1220.                          && PlotWindowMsg.MouseY < yoff && PlotWindowMsg.MouseY > yoff - HEIGHT)
  1221.                       {
  1222.                      SetDrMd( rp, COMPLEMENT);
  1223.  
  1224.                          if ( k )
  1225.                            {
  1226.                               if (!ylock)
  1227.                                 {  
  1228.                                   Move( rp, xoff, Cross[1]);
  1229.                                   Draw( rp, xoff + WIDTH, Cross[1]);
  1230.                                 }
  1231.  
  1232.                               if (!xlock)
  1233.                                 {
  1234.                                     Move( rp, Cross[0], yoff);
  1235.                                   Draw( rp, Cross[0], yoff - HEIGHT);
  1236.                                 }
  1237.                            }
  1238.  
  1239.                     if (!ylock)
  1240.                       {
  1241.                              Move( rp, xoff, PlotWindowMsg.MouseY);
  1242.                              Draw( rp, xoff + WIDTH, PlotWindowMsg.MouseY);
  1243.                              Cross[1] = PlotWindowMsg.MouseY;
  1244.                           y = ZoomY( Cross[1] );
  1245.                        }
  1246.  
  1247.                          if (!xlock)
  1248.                            {
  1249.                                Move( rp, PlotWindowMsg.MouseX, yoff);
  1250.                              Draw( rp, PlotWindowMsg.MouseX, yoff - HEIGHT);
  1251.                              Cross[0] = PlotWindowMsg.MouseX;
  1252.                           x = ZoomX( Cross[0] );
  1253.                            }
  1254.  
  1255.  
  1256.                         sprintf( txt ,fmt, y , x);
  1257.                         SetWindowTitles( PlotWindowWnd, txt, txt );    
  1258.  
  1259.                          k++;
  1260.                       }
  1261.  
  1262.                     break;
  1263.  
  1264.                case IDCMP_MOUSEBUTTONS:
  1265.                     if (PlotWindowMsg.Code == SELECTDOWN)
  1266.                          Identify( Cross[0], Cross[1], TRUE);
  1267.                     else if (PlotWindowMsg.Code == SELECTUP)
  1268.                          Identify( Cross[0], Cross[1], FALSE);
  1269.                
  1270.                     break;
  1271.  
  1272.                case IDCMP_VANILLAKEY:
  1273.                 switch (PlotWindowMsg.Code)
  1274.                   {  
  1275.                       case  32 : /* hit space , same as X */
  1276.                         if (!xlock) xlock = TRUE;
  1277.                         else xlock = FALSE;
  1278.                         break;
  1279.                       case 'x' : /* hit x */
  1280.                       case 'X' : /* hit X */
  1281.                         if (!xlock) xlock = TRUE;
  1282.                         else xlock = FALSE;
  1283.                         break;
  1284.                       case 'y' : /* hit y */
  1285.                       case 'Y' : /* hit Y */
  1286.                         if (!ylock) ylock = TRUE;
  1287.                         else ylock = FALSE;
  1288.                         break;
  1289.                     default:
  1290.                         running = FALSE;
  1291.                         break;
  1292.                   }
  1293.                 
  1294.                 break;
  1295.  
  1296.                default:
  1297.                    running = FALSE;
  1298.                     break;
  1299.           }
  1300.        }
  1301.      } while ( running);
  1302.  
  1303.  
  1304.      if ( k )
  1305.        {
  1306.              SetDrMd( rp, COMPLEMENT);
  1307.  
  1308.              Move( rp, xoff, Cross[1]);
  1309.              Draw( rp, xoff + WIDTH, Cross[1]);
  1310.  
  1311.              Move( rp, Cross[0], yoff);
  1312.              Draw( rp, Cross[0], yoff - HEIGHT);
  1313.        }
  1314.      
  1315.       ReportMouse( FALSE, PlotWindowWnd);
  1316.  
  1317.     return (1);
  1318. }
  1319.  
  1320. int Measure(WORD startX, WORD startY)
  1321. {
  1322. LONG   k = 0;
  1323. double orX, orY;
  1324. double dx, dy;
  1325. struct IntuiMessage *m;
  1326. WORD running = TRUE;
  1327. static WORD oldX, oldY;
  1328. UBYTE txt[128];
  1329. UBYTE fmt[64];
  1330.  
  1331.  
  1332.     orX = ZoomX(startX);
  1333.     orY = ZoomY(startY);
  1334.  
  1335.     sprintf( fmt ,"deltaY = %%-%ld.%ldlE   deltaX = %%-%ld.%ldlE", precision+6,precision,precision+6,precision);
  1336.  
  1337.         SetPointer( PlotWindowWnd, MSPointer, MSWIDTH, MSHEIGHT, MSXOFF , MSYOFF);
  1338.  
  1339.      ReportMouse( TRUE, PlotWindowWnd);
  1340.      SetMouseQueue( PlotWindowWnd, 1 );
  1341.      do {
  1342.  
  1343.        Wait ( 1L << PlotWindowWnd-> UserPort-> mp_SigBit );
  1344.  
  1345.        while( m = GT_GetIMsg( PlotWindowWnd->UserPort )) {
  1346.  
  1347.           CopyMem(( char * )m, ( char * )&PlotWindowMsg, (long)sizeof( struct IntuiMessage ));
  1348.  
  1349.           GT_ReplyIMsg( m );
  1350.  
  1351.           switch ( PlotWindowMsg.Class ) {
  1352.  
  1353.                case IDCMP_MOUSEMOVE:
  1354.  
  1355.                     if ( PlotWindowMsg.MouseX > xoff && PlotWindowMsg.MouseX < xoff + WIDTH
  1356.                          && PlotWindowMsg.MouseY < yoff && PlotWindowMsg.MouseY > yoff - HEIGHT)
  1357.                       {
  1358.                      SetDrMd( rp, COMPLEMENT);
  1359.  
  1360.                          if ( k )
  1361.                            {
  1362.                               Move( rp, startX, startY);
  1363.                               Draw( rp, oldX, oldY);
  1364.                            }
  1365.  
  1366.                          Move( rp, startX, startY);
  1367.                          Draw( rp, PlotWindowMsg.MouseX, PlotWindowMsg.MouseY);
  1368.  
  1369.                             oldX = PlotWindowMsg.MouseX;
  1370.                             oldY = PlotWindowMsg.MouseY;
  1371.  
  1372.                       dy = ZoomY( PlotWindowMsg.MouseY ) - orY;
  1373.                       dx = ZoomX( PlotWindowMsg.MouseX ) - orX;
  1374.  
  1375.                         sprintf( txt ,fmt, dy , dx);
  1376.                         SetWindowTitles( PlotWindowWnd, txt, txt );    
  1377.  
  1378.                          k++;
  1379.                       }
  1380.  
  1381.                     break;
  1382.  
  1383.                default:
  1384.                    running = FALSE;
  1385.                     break;
  1386.           }
  1387.        }
  1388.      } while ( running);
  1389.  
  1390.  
  1391.      
  1392.      ReportMouse( FALSE, PlotWindowWnd);
  1393.  
  1394.     Delay (10);
  1395.      while( m = GT_GetIMsg( PlotWindowWnd->UserPort )) GT_ReplyIMsg( m );
  1396.  
  1397.     return (1);
  1398. }
  1399.  
  1400.