home *** CD-ROM | disk | FTP | other *** search
/ QuickTime 2.0 Developer Kit / QuickTime 2.0 Developer Kit.iso / mac / MAC / Programming Stuff / Sample Code / Music Architecture / Mixed Bag / •Instrument Editor / Instrument Editor Controls.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-22  |  17.6 KB  |  943 lines  |  [TEXT/KAHL]

  1.  
  2.  
  3.  
  4. /************************************
  5. * Inclusions
  6. ************************************/
  7.  
  8. #include <QuickDraw.h>
  9. #include <Memory.h>
  10. #include <Resources.h>
  11. #include <OSUtils.h>
  12. #include <OSUtils.h>
  13. #include <OSUtils.h>
  14. #include <Events.h>
  15.  
  16. #define privateEasyControls
  17. #include "BigEasy2.h"
  18. #include "BigEasyGrafish.h"
  19. #include "BigEasyTextish.h"
  20. #include "BigEasyControls.h"
  21. #include "Instrument Editor Controls.h"
  22.  
  23.  
  24. /************************************
  25. * Constants
  26. ************************************/
  27.  
  28. #define kSlop 10
  29. #define kBarVMargin 4
  30. #define kSliderCursor 200
  31.  
  32. /************************************
  33.     Default Styles
  34. ************************************/
  35.  
  36. static tSliderStyle dDefaultSliderStyle =
  37.     {
  38.     longNum,
  39.     120,15,
  40.     80,13,
  41.     nil
  42.     };
  43.  
  44.  
  45. /************************************
  46. * Prototypes
  47. ************************************/
  48. static void MaybeRaisedRect(short c,Rect *r,Boolean b);
  49.  
  50. static void NewSlider(easyControlPtr ec);
  51. static void DisposeSlider(easyControlPtr ec);
  52. static void DrawSlider(easyControlPtr );
  53. static void TrackSlider(easyControlPtr,Point p);
  54. static void KeySlider(easyControlPtr,short k,short m,Boolean *tookKey);
  55. static void DrawSliderValue(easyControlPtr );
  56. static void HitTestSlider(void);
  57. static void SetSliderValue(struct easyControlRecord *ec,long value);
  58.  
  59.  
  60. static void NewBoolean(easyControlPtr ec);
  61. static void DisposeBoolean(easyControlPtr ec);
  62. static void DrawBoolean(easyControlPtr );
  63. static void TrackBoolean(easyControlPtr,Point p);
  64. static void KeyBoolean(easyControlPtr,short k,short m,Boolean *tookKey);
  65. static void DrawBooleanValue(easyControlPtr );
  66. static void HitTestBoolean(void);
  67. static void SetBooleanValue(struct easyControlRecord *ec,long value);
  68.  
  69.  
  70. static void NewToggle(easyControlPtr ec);
  71. static void DisposeToggle(easyControlPtr ec);
  72. static void DrawToggle(easyControlPtr );
  73. static void DrawToggleValue(easyControlPtr );
  74. static void HitTestToggle(easyControlPtr,Point p);
  75. static void TrackToggle(easyControlPtr,Point p,short *trackResult,short mods);
  76. static void KeyToggle(easyControlPtr,short k,short mods,Boolean *tookKey);
  77. static void SetToggleValue(easyControlPtr,long);
  78. static void Idle(easyControlPtr,long *);
  79.  
  80. easyControlType toggleType =
  81.     {
  82.     NewToggle,
  83.     DisposeToggle,
  84.     DrawToggle,
  85.     HitTestToggle,
  86.     TrackToggle,
  87.     KeyToggle,
  88.     SetToggleValue,
  89.     Idle,
  90.     DrawToggleValue
  91.     };
  92.  
  93. easyControlType sliderType =
  94.     {
  95.     NewSlider,
  96.     DisposeSlider,
  97.     DrawSlider,
  98.     (becHitTestProcPtr)HitTestSlider,
  99.     (becTrackProcPtr)TrackSlider,
  100.     KeySlider,
  101.     SetSliderValue,
  102.     Idle,
  103.     DrawSliderValue
  104.     };
  105.  
  106. easyControlType booleanType =
  107.     {
  108.     NewBoolean,
  109.     DisposeBoolean,
  110.     DrawBoolean,
  111.     (becHitTestProcPtr)HitTestBoolean,
  112.     (becTrackProcPtr)TrackBoolean,
  113.     KeyBoolean,
  114.     SetBooleanValue,
  115.     Idle,
  116.     DrawBooleanValue
  117.     };
  118.  
  119.  
  120.  
  121.  
  122.  
  123. /************************************
  124. * Routines
  125. ************************************/
  126.  
  127. void MaybeRaisedRect(short c,Rect *r,Boolean b)
  128. /*
  129.   * if background, draw a flat rect,
  130.   * else a raised rect.
  131.   */
  132.     {
  133.     if(b)
  134.         {
  135.         Fore555(c);
  136.         PaintRect(r);
  137.         }
  138.     else
  139.         RaisedRect(r,c);
  140.     }
  141.  
  142.  
  143.  
  144. /*
  145.   * Sliders
  146.   *
  147.   * Sliders copy their style into a handle, stored
  148.   * in the slide field of the easyControl.
  149.   */
  150.  
  151. void TrackSlider(easyControlPtr ec,Point p)
  152.  /*
  153.    * Track the mouse within the slider as long
  154.    * as the button is held down, all the while
  155.    * updating the value and drawing the bar.
  156.    */
  157.     {
  158.      tSliderStyle *st;
  159.      Point lastP;
  160.      long oldValue;
  161.      long value;
  162.      long vRange, rRange,rounding;
  163.      double fVRange, fRRange, fRounding;        /* for floating point sliders    */
  164.      Rect slopRect;
  165.      long q;
  166.      Boolean zingCursor;
  167.      Handle tempH;
  168.  
  169.      GoCursor(kSliderCursor);
  170.      zingCursor = true;
  171.  
  172.      st = *(tSliderStyle **)ec->style;
  173.      HLock(tempH = RecoverHandle((Ptr)st));
  174.      oldValue = ec->value;
  175.  
  176.      slopRect = ec->rect;
  177.      InsetRect(&slopRect,-kSlop,-kSlop);
  178.  
  179.      if(st->numberType == floatNum)
  180.          {
  181.          fVRange = AsFloat(ec->high) - AsFloat(ec->low);
  182.          fRRange = st->sWidth - 2;
  183.          fRounding = (fRRange / fVRange) / 2;
  184.          }
  185.      else
  186.          {
  187.          vRange = ec->high - ec->low;
  188.          rRange = st->sWidth - 2;
  189.          rounding = (rRange / vRange) / 2;
  190.          }
  191.  
  192.      if(ec->initActionProc)                    /* Call initAction proc once        */
  193.         (*ec->initActionProc)(ec->value,ec->refcon);
  194.     while(Button())
  195.          {
  196.         q = TickCount()+2;
  197.         while(TickCount() < q)
  198.             SystemTask();
  199.  
  200.  
  201.         if(ec->actionProc)                    /* Call action proc every time        */
  202.             (*ec->actionProc)(ec->value,ec->refcon);
  203.  
  204.         lastP.h = p.h+1;                        /* Guarantee do first time through    */
  205.         GetMouse(&p);
  206.          if( (p.h != lastP.h) || (p.v != lastP.v) )
  207.              {
  208.              if(PtInRect(p,&slopRect))
  209.                  {
  210.                  if(!zingCursor)
  211.                      {
  212.                      GoCursor(kSliderCursor);
  213.                      zingCursor = true;
  214.                      }
  215.                  if(st->numberType == floatNum)
  216.                      ;
  217.                  else
  218.                     value = ec->low + (long)(p.h - ec->rect.left + rounding + 1) * vRange/rRange;
  219.                 }
  220.             else
  221.                 {
  222.                 value = oldValue;
  223.                 if(zingCursor)
  224.                     {
  225.                     InitCursor();
  226.                     zingCursor = false;
  227.                     }
  228.                 }
  229.  
  230.             if(value < ec->low)
  231.                 value = ec->low;
  232.             else if(value > ec->high)
  233.                 value = ec->high;
  234.  
  235.             if(value != ec->value)
  236.                 {
  237.                 ec->value = value;
  238.                 DrawSliderValue(ec);
  239.  
  240.                 if(ec->valueProc)                /* Call value proc for new value    */
  241. /*                    (*ec->valueProc)(ec); */
  242.                     (*ec->valueProc)((easyControl)RecoverHandle((Ptr)ec));
  243.                 }
  244.             lastP = p;
  245.             }
  246.          }
  247.      if(ec->doneActionProc)                    /* Call doneAction proc once        */
  248.         (*ec->doneActionProc)(ec->value,ec->refcon);
  249.  
  250.      HUnlock(tempH);
  251.      InitCursor();
  252.      }
  253.  
  254. void DrawSlider(easyControlPtr ec)
  255. /*
  256.   * Draw the slider passed.
  257.   */
  258.     {
  259.     register tSliderStyle *st;
  260.     Rect r;
  261.     Handle tempH;
  262.  
  263.     st = *(tSliderStyle **)ec->style;
  264.     HLock(tempH = RecoverHandle((Ptr)st));
  265.     r = ec->rect;
  266. /*    r.right = r.left + st->sWidth;
  267.     r.bottom = r.top + st->sHeight;*/
  268.  
  269.     if(ec->flags & easyControlActive)
  270.         PenPat((Pattern *)dBlackPat);
  271.     else
  272.         PenPat((Pattern *)&dGrayPat);
  273.  
  274.     Fore555(ec->color[controlFrame]);
  275.     PenSize(1,1);
  276.     FrameRect(&r);
  277.     InsetRect(&r,1,1);
  278.     Fore555(ec->color[controlBackground]);
  279.     PaintRect(&r);
  280.  
  281.     DrawSliderValue(ec);
  282.     HUnlock(tempH);
  283.     }
  284.  
  285.  
  286. void DrawSliderValue(easyControlPtr ec)
  287.     {
  288.     Rect bar,r;
  289.     register tSliderStyle *st;
  290.     long value;
  291.     Boolean undefined;
  292.  
  293.     st = *(tSliderStyle **)ec->style;        /* already locked by caller    */
  294.  
  295.     value = ec->value;
  296.     undefined = false;
  297.     if(value == 0x7FFFffff)
  298.         {
  299.         value = ec->high;
  300.         undefined = true;
  301.         }
  302.     else if(value < ec->low)
  303.         value = ec->low;
  304.     else if(value > ec->high)
  305.         value = ec->high;
  306.  
  307.     bar.top = ec->rect.top + kBarVMargin;
  308.     bar.bottom = ec->rect.top + st->sHeight - kBarVMargin;
  309.     bar.left = ec->rect.left + 1;
  310.     bar.right = ec->rect.left + 1 + (long)(value - ec->low) * (long)(st->sWidth - 2) /
  311.             (long)(ec->high - ec->low);
  312.  
  313.     if(undefined)
  314.         InsetRect(&bar,0,2);
  315.  
  316.     if(ec->flags & easyControlActive)
  317.         PenPat((Pattern *)&dBlackPat);
  318.     else
  319.         PenPat((Pattern *)&dGrayPat);
  320.  
  321.     RaisedRect(&bar,ec->color[controlPart1]);
  322.  
  323.     bar.left = bar.right;
  324.     bar.right = ec->rect.left + st->sWidth - 1;
  325.     if(ec->variation & drawRightSlider)
  326.         RaisedRect(&bar,ec->color[controlPart2]);
  327.     else
  328.         {
  329.         Fore555(ec->color[controlBackground]);
  330.         PaintRect(&bar);
  331.         }
  332.  
  333.     if(st->tHeight)                        /* tHeight = 0 means no text    */
  334.         {
  335.         r.left = ec->rect.left;
  336.         r.top = ec->rect.top + st->sHeight - 1;
  337.         r.right = r.left + st->tWidth;
  338.         r.bottom = r.top + st->tHeight;
  339.         Fore555(ec->color[controlFrame]);
  340.         FrameRect(&r);
  341.         InsetRect(&r,1,1);
  342.         Fore555(ec->color[controlBackground]);
  343.         PaintRect(&r);
  344.         MoveTo(r.left + 2,r.bottom - (st->tHeight - 9)/2);
  345.         Fore555(ec->color[controlFrame]);
  346.         if(st->drawValue)
  347.             (*st->drawValue)((easyControl)RecoverHandle((Ptr)ec));
  348.         else
  349.             {
  350.             if(undefined)
  351.                 DrawString("\p----");
  352.             else if(st->numberType == longNum)
  353.                 DrawNum(value);
  354.             else if(st->numberType == fixedNum)
  355.                 DrawFixed(value,4);
  356.             else if(st->numberType == fracNum)
  357.                 DrawFrac(value,8);
  358.             else
  359.                 DrawString((StringPtr)"\pxyz");
  360.             }
  361.         }
  362.     }
  363.  
  364. void NewSlider(easyControlPtr ec)
  365. /*
  366.   * Do allocations for a new easyControl slider type
  367.   */
  368.     {
  369.     Handle h;
  370.     register tSliderStyle *st;
  371.  
  372. /*
  373.   * Copy the style information to our very own handle
  374.   */
  375.     if(ec->style == 0)
  376.         ec->style = &dDefaultSliderStyle;
  377.     h = NewHandle(sizeof(tSliderStyle));
  378.     BlockMove(ec->style,*h,sizeof(tSliderStyle));
  379.     ec->style = h;
  380.     st = (tSliderStyle *)*h;
  381.     st->sWidth = ec->rect.right - ec->rect.left;
  382.     st->sHeight = ec->rect.bottom - ec->rect.top;
  383.  
  384.     ec->low = 0;
  385.     ec->high = 100;
  386.     }
  387.  
  388. void DisposeSlider(easyControlPtr ec)
  389. /*
  390.   * Deallocate the slider
  391.   */
  392.     {
  393.     DisposHandle((Handle)ec->style);
  394.     }
  395.  
  396. void SetSliderValue(struct easyControlRecord *ec,long value)
  397.     {
  398.     ec->value = value;    
  399.     }
  400.  
  401. void HitTestSlider()
  402.     {
  403.     }
  404.  
  405. void NewToggle(easyControlPtr ec)
  406.     {
  407.     ec->low = 0;
  408.     ec->high = 1;
  409.     }
  410.  
  411. void DisposeToggle(easyControlPtr ec)
  412.     {
  413.     #pragma unused(ec)
  414.     }
  415.  
  416. void DrawToggle(easyControlPtr ec)
  417.     {
  418.     Rect r;
  419.  
  420.     r = ec->rect;
  421.     Fore555(ec->color[0]);
  422.     PenSize(1,1);
  423.     FrameRect(&r);
  424.     DrawToggleValue(ec);
  425.     }
  426.  
  427. void DrawToggleValue(easyControlPtr ec)
  428.     {
  429.     register tToggleStyle *st;
  430.     Rect r;
  431.     short c;
  432.     PicHandle p;
  433.  
  434.     r = ec->rect;
  435.     InsetRect(&r,1,1);
  436.  
  437.     if((ec->variation & checkboxToggle) && !(ec->flags & easyControlTracking))    /* checkbox version ? */
  438.         {
  439.         MaybeRaisedRect(ec->color[controlBackground],&r,ec->flags & easyControlBack);
  440.         if(ec->value)
  441.             {
  442.             Fore555(ec->color[controlFrame]);
  443.             PenSize(2,2);
  444.             MoveTo(r.left,r.top);
  445.             LineTo(r.right-2,r.bottom-2);
  446.             MoveTo(r.left,r.bottom-2);
  447.             LineTo(r.right-2,r.top);
  448.             }
  449.         }
  450.     else
  451.         {
  452.         if((!ec->value) ^ (ec->variation & checkboxToggle != 0))
  453.             c = ec->color[controlBackground];
  454.         else
  455.             c = ec->color[controlPart1];
  456.         
  457.         if(ec->flags & easyControlBack)
  458.             {
  459.             Fore555(c);
  460.             PaintRect(&r);
  461.             }
  462.         else
  463.             {
  464.             RaisedRect(&r,c);
  465.         
  466.             st = ec->style;
  467.             if(st && st->p)                    /* res ID zero doesn't draw */
  468.                 {
  469.                 p = (PicHandle)GetResource('PICT',st->p);
  470.                 if(p)
  471.                     {
  472.                     r = (**p).picFrame;
  473.                     OffsetRect(&r,((ec->rect.left  + ec->rect.right) - (r.left + r.right))/2,
  474.                             ((ec->rect.top + ec->rect.bottom) - (r.top + r.bottom))/2);
  475.                     DrawPicture(p,&r);
  476.                     }
  477.                 else                        /* missing picture */
  478.                     {
  479.                     GoBlack();
  480.                     PenSize(1,1);
  481.                     MoveTo(ec->rect.left,ec->rect.top);
  482.                     LineTo(ec->rect.right-1,ec->rect.bottom-1);
  483.                     }
  484.                 }
  485.             }
  486.         }
  487.     }
  488.  
  489. void TrackToggle(register easyControlPtr ec,Point p,
  490.             short *trackResult,short mods)
  491.     {
  492.     long oldValue,newValue;
  493.     register Boolean inRect;
  494.     long dummylong;
  495.     
  496.     #pragma unused(mods)
  497.  
  498.     oldValue = ec->value;
  499.     newValue = !ec->value;
  500.  
  501.     if(ec->variation & dontTrackToggle)
  502.         {
  503.         ec->value = newValue;
  504.         DrawToggleValue(ec);
  505.         if(!(ec->variation & toggleToggle))
  506.             Delay(5,&dummylong);
  507.         inRect = true;
  508.         }
  509.     else
  510.         do
  511.             {
  512.             SystemTask();
  513.             GetMouse(&p);
  514.             inRect = PtInRect(p,&ec->rect);
  515.             if(inRect)
  516.                 newValue = !oldValue;
  517.             else
  518.                 newValue = oldValue;
  519.             if(newValue != ec->value)
  520.                 {
  521.                 ec->value = newValue;
  522.                 DrawToggleValue(ec);
  523.                 }
  524.             } while(Button());
  525.  
  526.     if(!(ec->variation & toggleToggle) && (ec->value))        /* if it's not toggle-ish, reset it    */
  527.         {
  528.         ec->value = 0;
  529.         DrawToggleValue(ec);
  530.         }
  531.  
  532.     *trackResult = inRect;
  533.     }
  534.  
  535. void SetToggleValue(easyControlPtr ec,long v)
  536.     {
  537.     ec->value = v;
  538.     DrawToggleValue(ec);
  539.     }
  540.  
  541. void HitTestToggle(easyControlPtr ec,Point p)
  542.     {
  543.     #pragma unused(ec)
  544.     #pragma unused(p)
  545.     }
  546.  
  547. void Idle(easyControlPtr ec, long *r)
  548.     {
  549.     if(*r & 1)
  550.         Fore555(ec->color[1]);
  551.     else
  552.         Fore555(ec->color[0]);
  553.  
  554.     PenSize(1,1);
  555.     FrameRect(&ec->rect);
  556.     }
  557.  
  558. void KeySlider(register easyControlPtr ec,short k,short m,register Boolean *tookKey)
  559.     {
  560.     register short step;
  561.  
  562.     *tookKey = true;
  563.  
  564.     if(m&shiftKey)
  565.         step = 10;
  566.     else
  567.         step = 1;
  568.     switch(k)
  569.         {
  570.         case 28:
  571.             ec->value-=step;
  572.             break;
  573.         case 29:
  574.             ec->value+=step;
  575.             break;
  576.         default:
  577.             *tookKey = false;
  578.         }
  579.     DrawSliderValue(ec);
  580.     }
  581.  
  582. void KeyToggle(easyControlPtr ec,short k,short m,Boolean *tookKey)
  583.     {
  584. #pragma unused (m)
  585.  
  586.     long dummylong;
  587.     
  588.     if(k == ' ')        /* spacebar only */
  589.         {
  590.         *tookKey = true;
  591.  
  592.         if(ec->variation & toggleToggle)
  593.             {
  594.             ec->value = !ec->value;
  595.             DrawToggleValue(ec);
  596.             }
  597.         else
  598.             {
  599.             ec->value = 1;
  600.             DrawToggleValue(ec);
  601.             Delay(5,&dummylong);
  602.             ec->value = 0;
  603.             DrawToggleValue(ec);
  604.             }
  605.     
  606.         if(ec->valueProc)
  607.             (*ec->valueProc)((easyControl)RecoverHandle((Ptr)ec));
  608.         }
  609.     else
  610.         *tookKey = false;
  611.     }
  612.  
  613.  
  614.  
  615.  
  616.  
  617.  
  618.  
  619.  
  620.  
  621.  
  622.  
  623.  
  624.  
  625.  
  626.  
  627.  
  628.  
  629.  
  630.  
  631.  
  632.  
  633.  
  634.  
  635.  
  636.  
  637.  
  638.  
  639.  
  640. void NewBoolean(easyControlPtr ec)
  641. /*
  642.   * Do allocations for a new easyControl Boolean type
  643.   */
  644.     {
  645.     Handle h;
  646.     register tSliderStyle *st;
  647.  
  648. /*
  649.   * Copy the style information to our very own handle
  650.   */
  651.     if(ec->style == 0)
  652.         ec->style = &dDefaultSliderStyle;
  653.     h = NewHandle(sizeof(tSliderStyle));
  654.     BlockMove(ec->style,*h,sizeof(tSliderStyle));
  655.     ec->style = h;
  656.     st = (tSliderStyle *)*h;
  657.     st->sWidth = ec->rect.right - ec->rect.left;
  658.     st->sHeight = ec->rect.bottom - ec->rect.top;
  659.  
  660.     ec->low = 0;
  661.     ec->high = 100;
  662.     }
  663.  
  664. void DisposeBoolean(easyControlPtr ec)
  665. /*
  666.   * Deallocate the slider
  667.   */
  668.     {
  669.     DisposHandle((Handle)ec->style);
  670.     }
  671.  
  672. void SetBooleanValue(struct easyControlRecord *ec,long value)
  673.     {
  674.     ec->value = value;    
  675.     }
  676.  
  677. void HitTestBoolean()
  678.     {
  679.     }
  680.  
  681. void DrawBoolean(easyControlPtr ec)
  682. /*
  683.   * Draw the slider passed.
  684.   */
  685.     {
  686.     register tSliderStyle *st;
  687.     Rect r;
  688.     Handle tempH;
  689.     short bCount;
  690.  
  691.     bCount = 0;
  692.  
  693.         {
  694.         long x;
  695.  
  696.         x = ec->high;
  697.         while(x>>=1)
  698.             bCount++;
  699.         }
  700.  
  701.  
  702.     st = *(tSliderStyle **)ec->style;
  703.     HLock(tempH = RecoverHandle((Ptr)st));
  704.     r = ec->rect;
  705.  
  706.  
  707.     if(ec->flags & easyControlActive)
  708.         PenPat((Pattern *)dBlackPat);
  709.     else
  710.         PenPat((Pattern *)&dGrayPat);
  711.  
  712.     Fore555(ec->color[controlFrame]);
  713.     PenSize(1,1);
  714.     FrameRect(&r);
  715.     InsetRect(&r,1,1);
  716.     Fore555(ec->color[controlBackground]);
  717.     PaintRect(&r);
  718.  
  719.     DrawBooleanValue(ec);
  720.     EraseRect(&r);
  721.  
  722.     HUnlock(tempH);
  723.     }
  724.  
  725.  
  726.  
  727.  
  728.  
  729. void DrawBooleanValue(easyControlPtr ec)
  730.     {
  731.     Rect bar,r;
  732.     register tSliderStyle *st;
  733.     long value;
  734.     Boolean undefined;
  735.  
  736.     st = *(tSliderStyle **)ec->style;        /* already locked by caller    */
  737.  
  738.     value = ec->value;
  739.     undefined = false;
  740.     if(value == 0x7FFFffff)
  741.         {
  742.         value = ec->high;
  743.         undefined = true;
  744.         }
  745.     else if(value < ec->low)
  746.         value = ec->low;
  747.     else if(value > ec->high)
  748.         value = ec->high;
  749.  
  750.     bar.top = ec->rect.top + kBarVMargin;
  751.     bar.bottom = ec->rect.top + st->sHeight - kBarVMargin;
  752.     bar.left = ec->rect.left + 1;
  753.     bar.right = ec->rect.left + 1 + (long)(value - ec->low) * (long)(st->sWidth - 2) /
  754.             (long)(ec->high - ec->low);
  755.  
  756.     if(undefined)
  757.         InsetRect(&bar,0,2);
  758.  
  759.     if(ec->flags & easyControlActive)
  760.         PenPat((Pattern *)&dBlackPat);
  761.     else
  762.         PenPat((Pattern *)&dGrayPat);
  763.  
  764.     RaisedRect(&bar,ec->color[controlPart1]);
  765.  
  766.     bar.left = bar.right;
  767.     bar.right = ec->rect.left + st->sWidth - 1;
  768.     if(ec->variation & drawRightSlider)
  769.         RaisedRect(&bar,ec->color[controlPart2]);
  770.     else
  771.         {
  772.         Fore555(ec->color[controlBackground]);
  773.         PaintRect(&bar);
  774.         }
  775.  
  776.     if(st->tHeight)                        /* tHeight = 0 means no text    */
  777.         {
  778.         r.left = ec->rect.left;
  779.         r.top = ec->rect.top + st->sHeight - 1;
  780.         r.right = r.left + st->tWidth;
  781.         r.bottom = r.top + st->tHeight;
  782.         Fore555(ec->color[controlFrame]);
  783.         FrameRect(&r);
  784.         InsetRect(&r,1,1);
  785.         Fore555(ec->color[controlBackground]);
  786.         PaintRect(&r);
  787.         MoveTo(r.left + 2,r.bottom - (st->tHeight - 9)/2);
  788.         Fore555(ec->color[controlFrame]);
  789.         if(st->drawValue)
  790.             (*st->drawValue)((easyControl)RecoverHandle((Ptr)ec));
  791.         else
  792.             {
  793.             if(undefined)
  794.                 DrawString("\p----");
  795.             else if(st->numberType == longNum)
  796.                 DrawNum(value);
  797.             else if(st->numberType == fixedNum)
  798.                 DrawFixed(value,4);
  799.             else if(st->numberType == fracNum)
  800.                 DrawFrac(value,8);
  801.             else
  802.                 DrawString((StringPtr)"\pxyz");
  803.             }
  804.         }
  805.     }
  806.     
  807.     
  808.     
  809.     
  810.     
  811.  
  812.  
  813.  
  814.  
  815.  
  816.  
  817. void TrackBoolean(easyControlPtr ec,Point p)
  818.  /*
  819.    * Track the mouse within the slider as long
  820.    * as the button is held down, all the while
  821.    * updating the value and drawing the bar.
  822.    */
  823.     {
  824.      tSliderStyle *st;
  825.      Point lastP;
  826.      long oldValue;
  827.      long value;
  828.      long vRange, rRange,rounding;
  829.      double fVRange, fRRange, fRounding;        /* for floating point sliders    */
  830.      Rect slopRect;
  831.      long q;
  832.      Boolean zingCursor;
  833.      Handle tempH;
  834.  
  835.      GoCursor(kSliderCursor);
  836.      zingCursor = true;
  837.  
  838.      st = *(tSliderStyle **)ec->style;
  839.      HLock(tempH = RecoverHandle((Ptr)st));
  840.      oldValue = ec->value;
  841.  
  842.      slopRect = ec->rect;
  843.      InsetRect(&slopRect,-kSlop,-kSlop);
  844.  
  845.      if(st->numberType == floatNum)
  846.          {
  847.          fVRange = AsFloat(ec->high) - AsFloat(ec->low);
  848.          fRRange = st->sWidth - 2;
  849.          fRounding = (fRRange / fVRange) / 2;
  850.          }
  851.      else
  852.          {
  853.          vRange = ec->high - ec->low;
  854.          rRange = st->sWidth - 2;
  855.          rounding = (rRange / vRange) / 2;
  856.          }
  857.  
  858.      if(ec->initActionProc)                    /* Call initAction proc once        */
  859.         (*ec->initActionProc)(ec->value,ec->refcon);
  860.     while(Button())
  861.          {
  862.         q = TickCount()+2;
  863.         while(TickCount() < q)
  864.             SystemTask();
  865.  
  866.  
  867.         if(ec->actionProc)                    /* Call action proc every time        */
  868.             (*ec->actionProc)(ec->value,ec->refcon);
  869.  
  870.         lastP.h = p.h+1;                        /* Guarantee do first time through    */
  871.         GetMouse(&p);
  872.          if( (p.h != lastP.h) || (p.v != lastP.v) )
  873.              {
  874.              if(PtInRect(p,&slopRect))
  875.                  {
  876.                  if(!zingCursor)
  877.                      {
  878.                      GoCursor(kSliderCursor);
  879.                      zingCursor = true;
  880.                      }
  881.                  if(st->numberType == floatNum)
  882.                      ;
  883.                  else
  884.                     value = ec->low + (long)(p.h - ec->rect.left + rounding + 1) * vRange/rRange;
  885.                 }
  886.             else
  887.                 {
  888.                 value = oldValue;
  889.                 if(zingCursor)
  890.                     {
  891.                     InitCursor();
  892.                     zingCursor = false;
  893.                     }
  894.                 }
  895.  
  896.             if(value < ec->low)
  897.                 value = ec->low;
  898.             else if(value > ec->high)
  899.                 value = ec->high;
  900.  
  901.             if(value != ec->value)
  902.                 {
  903.                 ec->value = value;
  904.                 DrawSliderValue(ec);
  905.  
  906.                 if(ec->valueProc)                /* Call value proc for new value    */
  907. /*                    (*ec->valueProc)(ec); */
  908.                     (*ec->valueProc)((easyControl)RecoverHandle((Ptr)ec));
  909.                 }
  910.             lastP = p;
  911.             }
  912.          }
  913.      if(ec->doneActionProc)                    /* Call doneAction proc once        */
  914.         (*ec->doneActionProc)(ec->value,ec->refcon);
  915.  
  916.      HUnlock(tempH);
  917.      InitCursor();
  918.      }
  919.  
  920. void KeyBoolean(register easyControlPtr ec,short k,short m,register Boolean *tookKey)
  921.     {
  922.     register short step;
  923.  
  924.     *tookKey = true;
  925.  
  926.     if(m&shiftKey)
  927.         step = 10;
  928.     else
  929.         step = 1;
  930.     switch(k)
  931.         {
  932.         case 28:
  933.             ec->value-=step;
  934.             break;
  935.         case 29:
  936.             ec->value+=step;
  937.             break;
  938.         default:
  939.             *tookKey = false;
  940.         }
  941.     DrawSliderValue(ec);
  942.     }
  943.