home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Code Resources / Jims CDEFs 1.50 / CDEF Source / source / cdefHSlider.c < prev    next >
Encoding:
Text File  |  1995-11-13  |  22.2 KB  |  699 lines  |  [TEXT/KAHL]

  1. //------------------------- © 1994 - 1995 by James G. Stout ------------------------
  2. //    File    : cdefHSlider.c
  3. //    Date    : April 6, 1994
  4. //    Author    : Jim Stout
  5. //            :
  6. //    Purpose    : A slider CDEF modeled after the on in the Brightness Control panel
  7. //            :
  8. //            : see cdefHSlider.h for more detail and variation codes
  9. //            :
  10. //            : If you find a use for this, I'd love to know about it.  Bug reports
  11. //            : are always interesting.
  12. //            :
  13. //            : Internet    : JimS@WRQ.COM(work hours, PST)
  14. //            : AppleLink   : WRQ            (daily)
  15. //            : CompuServe  : 73240,2052    (weekly or so)
  16. //            : AOL         : JasG        (weekly or so)
  17. //            : eWorld      : Jim Stout    (weekly or so)
  18. //----------------------------------------------------------------------------------
  19. //#define _DEBUGCDEF                    // comment this to build CDEF
  20.  
  21. #include "fatCDEF.h"
  22.  
  23. #include <Controls.h>
  24. #include <GestaltEqu.h>
  25. #include <Memory.h>
  26. #include <QDOffscreen.h>
  27. #include <ToolUtils.h>
  28. #include <Types.h>
  29. #include <Windows.h>
  30.  
  31. #include "grayCDEF.h"
  32. #include "colorCDEF.h"
  33. #include "miscCDEF.h"
  34. #include "qdCDEF.h"
  35.  
  36. #include "cdefHSlider.h"
  37.  
  38. #ifdef _DEBUGCDEF
  39. pascal long CDmain (short, ControlHandle, short, long);
  40.  
  41. pascal long CDmain (short varCode, ControlHandle theCtl, short message, long param)
  42. #else
  43.  
  44. //==================================================================================
  45. // CDEF entry point
  46. //==================================================================================
  47. pascal long main (short varCode, ControlHandle theCtl, short message, long param)
  48. #endif
  49. {
  50.     long        ret = 0L;
  51.     SignedByte    cState, dState;
  52.     
  53. #include "fatEntry.c"
  54.     
  55.     cState = HGetState((Handle)theCtl);
  56.     HLock((Handle)theCtl);
  57.     if((**theCtl).contrlData) {
  58.         dState = HGetState((**theCtl).contrlData);
  59.         HLock((**theCtl).contrlData);
  60.     }
  61.     
  62.     switch(message) {
  63.         case initCntl:
  64.             doInit(theCtl);
  65.             if((**theCtl).contrlData) {
  66.                 dState = HGetState((**theCtl).contrlData);
  67.                 HLock((**theCtl).contrlData);
  68.             }
  69.         break;
  70.         case dispCntl:
  71.             doDisp(theCtl);
  72.         break;
  73.         case drawCntl:
  74.             if ((**theCtl).contrlVis != 0 &&
  75.                 ((WindowPeek)(**theCtl).contrlOwner)->visible) {
  76.                 doDraw(theCtl, varCode);
  77.             }
  78.         break;
  79.         case testCntl:
  80.             ret = doTest (theCtl, varCode, param);
  81.         break;
  82.         case calcCRgns:
  83.             RectRgn((RgnHandle)(param & 0x7fffffffL), &(**theCtl).contrlRect);
  84.         break;
  85.         case calcCntlRgn:
  86.         case calcThumbRgn:
  87.             RectRgn((RgnHandle)(param), &(**theCtl).contrlRect);
  88.         break;
  89.     }
  90.  
  91.     if((**theCtl).contrlData)
  92.         HSetState((**theCtl).contrlData, dState);
  93.     HSetState((Handle)theCtl, cState);
  94.     
  95. #include "fatExit.c"
  96.     
  97.     return (ret);
  98. }
  99.  
  100. //==================================================================================
  101. //    Initialize our control data
  102. //==================================================================================
  103.  
  104. static void doInit (ControlHandle theCtl)
  105. {
  106.     Rect        scaleRect;
  107.     CGrafPtr    offPort=0;
  108.     CDEFHandle    hCDEF;
  109.     
  110. //----------------------------------------------------------------------------------
  111. // force the scale rect to the size we want. It'll be clipped to the control Rect
  112. //----------------------------------------------------------------------------------
  113.     
  114.     scaleRect = (**theCtl).contrlRect;
  115.     scaleRect.right = scaleRect.left + 121;
  116.     scaleRect.bottom = scaleRect.top + 24;
  117.         
  118. //----------------------------------------------------------------------------------
  119. // force the min & max as well
  120. //----------------------------------------------------------------------------------
  121.     
  122.     (**theCtl).contrlMin = 0;
  123.     (**theCtl).contrlMax = 100;                            // number of pixels in scale
  124.     
  125.     hCDEF = (CDEFHandle)NewHandle(sizeof(CDEFData));
  126.     if(hCDEF) {
  127.         (**hCDEF).pDepth = 1;                            // filled in in doDraw()
  128.         (**hCDEF).offPort = 0;
  129.         (**hCDEF).scaleRect = scaleRect;
  130.         (**hCDEF).qdVers = getQDVers();
  131.         
  132.         (**theCtl).contrlData = (Handle)hCDEF;
  133.     }
  134.     else
  135.         (**theCtl).contrlData = 0;
  136. }
  137.  
  138. //==================================================================================
  139. //    Get rid of our control data
  140. //==================================================================================
  141.  
  142. static void doDisp        (ControlHandle theCtl)
  143. {
  144.     BitMap        *theBits;
  145.     CDEFHandle    hCDEF;
  146.     
  147.     hCDEF = (CDEFHandle)(**theCtl).contrlData;
  148.     if(hCDEF) {
  149.         if((**hCDEF).offPort) {
  150.             if(((**hCDEF).offPort->portVersion & 0x8000) != 0) {    // offPort is GWorld
  151.                 DisposeGWorld((**hCDEF).offPort);                
  152.             }
  153.             else {                                                    // offport is bitmap
  154.                 theBits = &((GrafPtr)(**hCDEF).offPort)->portBits;
  155.                 DisposePtr((*theBits).baseAddr);
  156.                 ClosePort((GrafPtr)(**hCDEF).offPort);
  157.                 DisposePtr((Ptr)(**hCDEF).offPort);
  158.             }
  159.         }
  160.         HUnlock((Handle)hCDEF);
  161.         DisposeHandle((Handle)hCDEF);
  162.         (**theCtl).contrlData = 0;
  163.     }
  164. }
  165.  
  166. //==================================================================================
  167. //    Test to see if the mouse was pressed in the control thumb and drag accordingly
  168. //==================================================================================
  169.  
  170. static long doTest (ControlHandle theCtl, short varCode, long param)
  171. {
  172.     Rect    rThumb, rScale;
  173.     Point    p;
  174.     long    ret=0,secs;
  175.     short    partCode;
  176.     CDEFHandle    hCDEF;
  177.     
  178.     hCDEF = (CDEFHandle)(**theCtl).contrlData;
  179.     if(!hCDEF)
  180.         return(ret);
  181.  
  182.     partCode = (**theCtl).contrlHilite;
  183.     rScale = (**hCDEF).scaleRect;
  184.     
  185. //----------------------------------------------------------------------------------
  186. // get the thumb rect, calculated from control value
  187. //----------------------------------------------------------------------------------
  188.  
  189.     getThumbRect(theCtl, &rThumb, &rScale);
  190.     InsetRect(&rScale,4,7);                                    // inset for active area
  191.     
  192.     p.h = LoWord(param);
  193.     p.v = HiWord(param);
  194.     
  195.     if(PtInRect(p, &rThumb)) {                                // click in thumb?
  196.         ret = 1;
  197.         dragThumb(theCtl, varCode, param);
  198.     }
  199.     else
  200.     if(PtInRect(p, &rScale)) {                                // click in scale?
  201.         if(p.h < rThumb.left)
  202.             ret = 2;                                        // decrease
  203.         else
  204.         if(p.h > rThumb.right)
  205.             ret = 3;                                        // increase
  206.             
  207.         if(partCode == ret) {
  208.             scaleClick(theCtl, varCode, (short)ret);
  209.             Delay(6L, & secs);
  210.         }
  211.     }
  212.     return(ret);
  213. }
  214.  
  215. //==================================================================================
  216. // Respond to a mouse down in our "thumb", track the mouse to reposition the thumb,
  217. // set a new control value and call the actionProc (if any).
  218. //==================================================================================
  219. static void dragThumb (ControlHandle theCtl, short varCode, long param)
  220. {
  221.     short    newVal,maxDrag,minDrag;
  222.     Rect    rThumb, rScale;
  223.     Point    p,oldPt;
  224.  
  225.     rScale = (**(CDEFHandle)(**theCtl).contrlData).scaleRect;
  226.     getThumbRect(theCtl, &rThumb, &rScale);
  227.     
  228.     p.h = oldPt.h = LoWord(param);
  229.     p.v = HiWord(param);
  230.     
  231.     if(PtInRect(p, &rThumb)) {
  232.         maxDrag = rScale.right - 4 - (rThumb.right - p.h);
  233.         minDrag = rScale.left + 4 + (p.h - rThumb.left);
  234.         while (StillDown()) {
  235.             if(oldPt.h != p.h) {                            // mouse moved
  236.                 OffsetRect(&rThumb, (p.h-oldPt.h), 0);        // move the thumb
  237.                 if(rThumb.left < rScale.left+5) {            // pin to left of scale
  238.                     OffsetRect(&rThumb, rScale.left - rThumb.left+5, 0); 
  239.                 }
  240.                 else
  241.                 if(rThumb.right > rScale.right-5) {            // pin to right of scale
  242.                     OffsetRect(&rThumb, rScale.right - rThumb.right-5, 0); 
  243.                 }
  244.                 newVal =  -(rScale.left - rThumb.left + 5);
  245.                 if(newVal != (**theCtl).contrlValue) {
  246.                     (**theCtl).contrlValue = newVal;
  247.                     doDraw(theCtl, varCode);
  248.                     if((**theCtl).contrlAction != nil)
  249.                         CallControlActionProc((**theCtl).contrlAction,
  250.                                                 theCtl, 1);
  251.                 }
  252.                 if(p.h > minDrag && p.h < maxDrag)            // track move
  253.                     oldPt.h = p.h;    
  254.             }
  255.             GetMouse(&p);
  256.         }
  257.     }
  258. }
  259.  
  260. //==================================================================================
  261. // Adjust the control after detecting a click in the scale instead of the thumb -
  262. // set a new control value and call the actionProc (if any).
  263. //==================================================================================
  264. static void scaleClick (ControlHandle theCtl, short varCode, short partCode)
  265. {
  266.     Rect    rThumb, rScale;
  267.     short    newVal;
  268.  
  269.     rScale = (**(CDEFHandle)(**theCtl).contrlData).scaleRect;
  270.     getThumbRect(theCtl, &rThumb, &rScale);
  271.     
  272.     if(partCode == 2) {
  273.         OffsetRect(&rThumb, -1, 0);
  274.     }
  275.     else 
  276.     if(partCode == 3) {
  277.          OffsetRect(&rThumb, 1, 0);
  278.     }    
  279.     if(rThumb.left < rScale.left+5)                            // pin to left of scale
  280.         OffsetRect(&rThumb, rScale.left - rThumb.left+5, 0); 
  281.     else
  282.     if(rThumb.right > rScale.right-5)                        // pin to right of scale
  283.         OffsetRect(&rThumb, rScale.right - rThumb.right-5, 0);
  284.         
  285.     newVal =  -(rScale.left - rThumb.left + 5);
  286.     
  287.     if(newVal != (**theCtl).contrlValue) {
  288.         (**theCtl).contrlValue = newVal;
  289.         doDraw(theCtl, varCode);
  290.         if((**theCtl).contrlAction != nil)
  291.             CallControlActionProc((**theCtl).contrlAction, theCtl, partCode);
  292.     }
  293. }
  294.  
  295. //==================================================================================
  296. //    Calculate the thumb location from the control value
  297. //==================================================================================
  298.  
  299. static void getThumbRect(ControlHandle theCtl, Rect *rThumb, Rect *rScale)
  300. {
  301.     short    h;
  302.     
  303.     SetRect(rThumb, 0, 0, 11, 24);
  304.     h = (**theCtl).contrlValue + (rScale)->left + 5;
  305.     OffsetRect(rThumb, h, (rScale)->top);
  306. }
  307.  
  308. //==================================================================================
  309. //    Draw both the scale and thumb into one bitmap.  We've got the scale & thumb
  310. //  stored as bitmap data in a char array in cdefHSliderBits.c.
  311. //==================================================================================
  312.  
  313. Boolean drawParts (ControlHandle theCtl, short varCode, Rect *rThumb)
  314. {
  315. #include "cdefHSliderBits.c"                        // bitmap data
  316.  
  317.     Rect        rScale, r, partRect;
  318.     Boolean        inColor = false, haveGray = false;
  319.     RGBColor    saveFore, saveBack, grayFrame, tingeColor, fillColor;
  320.     RGBColor    scaleColor = {56797, 56797, 56797};
  321.     BitMap        bits;
  322.     GrafPtr        offPort;
  323.     Pattern        pat = { 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA};
  324.     RgnHandle     saveClip, clipRgn;
  325.     CDEFHandle    hCDEF;
  326.     
  327.     hCDEF = (CDEFHandle)(**theCtl).contrlData;        // already locked
  328.     if(hCDEF) {
  329. //----------------------------------------------------------------------------------
  330. // set up our drawing rects & save clip region since we change it below
  331. //----------------------------------------------------------------------------------
  332.         
  333.         SetRect(&rScale, 0, 0, 121, 24);
  334.         r = partRect = rScale ;
  335.         
  336.         saveClip = NewRgn();
  337.         GetClip(saveClip);
  338.         
  339. //----------------------------------------------------------------------------------
  340. //    Set colors - either cFrameColor or grayed version of cFrameColor if inactive
  341. //----------------------------------------------------------------------------------
  342.  
  343.           if((**hCDEF).pDepth > 2) {
  344.               inColor = true;
  345.               setPartColor(theCtl, cFrameColor, true);
  346.           }
  347.           else
  348.               ForeColor(blackColor);
  349.               
  350.         if((**theCtl).contrlHilite == 0xFF) {        // inactive control
  351.             if(inColor) {                            // try to draw it in
  352.                 haveGray = getGray(&grayFrame);        // gray
  353.                 if(haveGray)
  354.                     RGBForeColor(&grayFrame);
  355.             }
  356.         }
  357.  
  358.         if(inColor)
  359.             saveColors(&saveFore, &saveBack);        // saveFore may be gray...
  360.           
  361. //----------------------------------------------------------------------------------
  362. //    Clip drawing to the scale so we don't wipe out any background pattern
  363. //----------------------------------------------------------------------------------
  364.  
  365.         InsetRect(&rScale, 0, 5);
  366.         clipRgn = NewRgn();
  367.         OpenRgn();
  368.         FrameRoundRect(&rScale, 11, 11);
  369.         CloseRgn(clipRgn);
  370.         SetClip(clipRgn);
  371.         
  372. //----------------------------------------------------------------------------------
  373. // draw the scale into this offport
  374. //----------------------------------------------------------------------------------
  375.  
  376.         offPort = (GrafPtr)(**hCDEF).offPort;
  377.                                                     // construct a bitmap    
  378.         bits.bounds = partRect;                        // on the fly…
  379.         bits.rowBytes = 16;                            // for the scale
  380.         bits.baseAddr = hScale;                        // in data array
  381.         
  382.         BackColor(whiteColor);                        // foreColor set above
  383.         
  384.         CopyBits(&bits,                                // from bitmap
  385.                 &(offPort)->portBits,                // to offscreen port
  386.                 &bits.bounds,                        // from rect
  387.                 &bits.bounds,                         // to rect
  388.                 srcCopy, nil);
  389.                 
  390. //----------------------------------------------------------------------------------
  391. // draw the 3D version of the scale
  392. //----------------------------------------------------------------------------------
  393.                     
  394.         if(varCode & ctl3D && inColor) {
  395.               InsetRect(&partRect, 3, 8);
  396.             RGBForeColor(&scaleColor);
  397.             RGBBackColor(&saveBack);
  398.             
  399. //----------------------------------------------------------------------------------
  400. // fill center of scale with light gray
  401. //----------------------------------------------------------------------------------
  402.  
  403.             PaintRoundRect(&partRect,4,4);
  404.  
  405. //----------------------------------------------------------------------------------
  406. // draw 3D shadow along bottom & right
  407. //----------------------------------------------------------------------------------
  408.  
  409.               setPartColor(theCtl, cTingeLight, true);
  410.               GetForeColor(&tingeColor);
  411.               tingeColor.red-=13107;
  412.               tingeColor.green-=13107;
  413.               tingeColor.blue-=13107;
  414.               RGBForeColor(&tingeColor);
  415.               MoveTo(partRect.left+1, partRect.bottom-1);
  416.               LineTo(partRect.right-2, partRect.bottom-1);
  417.               MoveTo(partRect.right-1, partRect.bottom-2);
  418.               LineTo(partRect.right-1, partRect.top+1);
  419.               MoveTo(partRect.right-2, partRect.bottom-2);
  420.               LineTo(partRect.right-2, partRect.bottom-2);
  421.         }
  422.         else
  423.  
  424. //----------------------------------------------------------------------------------
  425. //    Draw other scale variations
  426. //----------------------------------------------------------------------------------
  427.  
  428.           if(varCode & scaleNoFill) {
  429.               if(inColor)
  430.                   setPartColor(theCtl, cBodyColor, false);
  431.               InsetRect(&partRect, 3, 8);
  432.             PenPat( (ConstPatternParam) "\x00\x00\x00\x00\x00\x00\x00\x00");
  433.               PaintRoundRect(&partRect, 4,4);
  434.           }
  435.           else
  436.           if(varCode & scaleGray) {
  437.               if(inColor) {
  438.                   setPartColor(theCtl, cBodyColor, true);
  439.                   GetForeColor(&fillColor);
  440.                   if(fillColor.red == 65535 && 
  441.                       fillColor.green == 65535 &&
  442.                       fillColor.blue == 65535) {
  443.                       ForeColor(blackColor);
  444.                   }
  445.                   if(haveGray) {                        // must be inactive
  446.                       if(getGray(&fillColor)) {
  447.                           RGBForeColor(&fillColor);
  448.                       }
  449.                   }
  450.               }
  451.               InsetRect(&partRect, 3, 8);
  452.               FillRoundRect(&partRect, 4, 4, &pat);
  453.           }
  454.  
  455. //----------------------------------------------------------------------------------
  456. //     draw the thumb - first, clip our drawing to the shape of the thumb so we don't
  457. //    wipe out any background pattern.
  458. //----------------------------------------------------------------------------------
  459.  
  460.         if(clipRgn)
  461.             DisposeRgn(clipRgn);
  462.         clipRgn = NewRgn();
  463.         OpenRgn();
  464.         FrameRoundRect(rThumb, 12, 8);
  465.         CloseRgn(clipRgn);
  466.         SetClip(clipRgn);
  467.         
  468. //----------------------------------------------------------------------------------
  469. //    Now, blit the thumb to the screen & colorize/shade it if needed
  470. //----------------------------------------------------------------------------------
  471.           if(inColor) {
  472.               RGBForeColor(&saveFore);
  473.               BackColor(whiteColor);
  474.           }
  475.  
  476.         SetRect(&partRect, 0, 0, 11, 24);            // construct a bitmap
  477.         bits.bounds = partRect;                        // on the fly…
  478.         bits.rowBytes = 2;                            // for the thumb
  479.         bits.baseAddr = hThumb;                        // in data array
  480.         
  481.         CopyBits(&bits,                                // from bitmap
  482.                 &(offPort)->portBits,                // to onscreen port
  483.                 &partRect,                            // from rect
  484.                 rThumb,                                 // to rect
  485.                 srcCopy, nil);
  486.  
  487. //----------------------------------------------------------------------------------
  488. //    Draw 3D version of thumb
  489. //----------------------------------------------------------------------------------
  490.                 
  491.           if(varCode & ctl3D && inColor) {    
  492.               RGBForeColor(&scaleColor);
  493.               InsetRect(rThumb, 3, 1);
  494.               PaintRect(rThumb);
  495.  
  496.               MoveTo((*rThumb).left-2, (*rThumb).bottom-2);
  497.               LineTo((*rThumb).left-2, (*rThumb).top+1);
  498.               MoveTo((*rThumb).right+1, (*rThumb).bottom-2);
  499.               LineTo((*rThumb).right+1, (*rThumb).top+1);
  500.  
  501. //----------------------------------------------------------------------------------
  502. // draw the 3D shadow in a grayed cTingeColor
  503. //----------------------------------------------------------------------------------
  504.  
  505.               RGBForeColor(&tingeColor);
  506.               MoveTo((*rThumb).left, (*rThumb).bottom-1);
  507.               LineTo((*rThumb).right-1, (*rThumb).bottom-1);
  508.               LineTo((*rThumb).right-1, (*rThumb).top);
  509.               MoveTo((*rThumb).right-2, (*rThumb).bottom-2);
  510.               LineTo((*rThumb).right-2, (*rThumb).bottom-2);
  511.           }
  512.           else {                                        // colorize center part
  513.               if(inColor) {                            // of thumb
  514.                   ForeColor(whiteColor);
  515.                   setPartColor(theCtl, cThumbColor, true);
  516.                   InsetRect(rThumb, 3, 1);
  517.                   PaintRect(rThumb);
  518.               }
  519.           }
  520.       }
  521.       SetClip(saveClip);
  522.       DisposeRgn(saveClip);
  523.       DisposeRgn(clipRgn);
  524.       
  525.       return(haveGray);
  526. }
  527.  
  528. //==================================================================================
  529. //    Draw the control, it is made up from the scale bitmap and the thumb bitmap
  530. //    which are assembled into an offscreen bitmap in "drawParts".
  531. //==================================================================================
  532.  
  533. static void doDraw (ControlHandle theCtl, short varCode)
  534. {
  535.     Rect            offRect,rThumb,rScale;
  536.     RgnHandle        saveClip, newClip;
  537.     BitMap            *offBits;
  538.     PixMapHandle    pmHdl;
  539.     CGrafPtr        savePort;
  540.     GDHandle        saveGDev;
  541.     PenState        savePen;
  542.     Boolean            inactive = false, haveGray = false, inColor = false, haveGW = false;
  543.     RGBColor        saveFore,saveBack;
  544.     CDEFHandle        hCDEF;
  545.     
  546.     hCDEF = (CDEFHandle)(**theCtl).contrlData;                    // already locked
  547.     if(hCDEF) {
  548.  
  549. //----------------------------------------------------------------------------------    
  550. // If control has been moved we need to update our rect
  551. //----------------------------------------------------------------------------------
  552.  
  553.         rScale = (**theCtl).contrlRect;
  554.         rScale.right = rScale.left + 121;
  555.         rScale.bottom = rScale.top + 24;
  556.  
  557.         (**hCDEF).scaleRect = rScale;
  558.         (**theCtl).contrlData = (Handle)hCDEF;
  559.  
  560. //----------------------------------------------------------------------------------
  561. // Create or update our GWorld
  562. //----------------------------------------------------------------------------------
  563.     
  564.         (**hCDEF).pDepth = getOff(&(**hCDEF).offPort, &(**theCtl).contrlRect);
  565.         
  566.         if((**hCDEF).pDepth == 0)                                // oh… oh…                
  567.             return;                                        
  568.         
  569.         if(((**hCDEF).offPort->portVersion & 0x8000) != 0) {    // have a GWorld
  570.             haveGW = true;
  571.             pmHdl = getLockedPixels(&(**hCDEF).offPort, (**hCDEF).qdVers);
  572.             if(!pmHdl)
  573.                 return;                                            // nuts…
  574.         }
  575.  
  576. //----------------------------------------------------------------------------------
  577. //    Do the clip region properly.  Thanks Ari!
  578. //----------------------------------------------------------------------------------
  579.  
  580.         saveClip = NewRgn();
  581.         GetClip(saveClip);
  582.         
  583.         newClip = NewRgn();
  584.         RectRgn(newClip, &(**theCtl).contrlRect);
  585.         SectRgn(saveClip, newClip, newClip);
  586.         
  587.         if(EmptyRgn(newClip)) {                                    // if empty, don't waste
  588.             DisposeRgn(saveClip);                                // time drawing...
  589.             DisposeRgn(newClip);
  590.             return;
  591.         }
  592.     
  593.         SetClip(newClip);
  594.         
  595. //----------------------------------------------------------------------------------
  596. // Calculate size for offRect (scale) & position the thumb rect
  597. //----------------------------------------------------------------------------------
  598.         
  599.         SetRect(&offRect, 0, 0, 121, 24);
  600.         rScale = (**hCDEF).scaleRect;
  601.         
  602.         SetRect(&rThumb, 0, 0, 11, 24);
  603.         OffsetRect(&rThumb, (**theCtl).contrlValue+5,0);
  604.         
  605. //----------------------------------------------------------------------------------
  606. // Initialize and set for drawing into offScreen port
  607. //----------------------------------------------------------------------------------
  608.  
  609.         if((**theCtl).contrlHilite == 0xFF)                // inactive control
  610.             inactive = true;
  611.             
  612.         if((**hCDEF).pDepth > 2) {                            // save onscreen    
  613.             inColor = true;                                    // colors
  614.             saveColors(&saveFore, &saveBack);
  615.         }
  616.         
  617.         if(haveGW) {                                        // we have a pixMap        
  618.             GetGWorld(&savePort, &saveGDev);
  619.             SetGWorld((**hCDEF).offPort, nil);
  620.             offBits = (BitMap *)*pmHdl;
  621.             if((**(*savePort).bkPixPat).patType != 0 &&
  622.                 (savePort->portVersion & 0x8000) != 0)
  623.                 BackPixPat((*savePort).bkPixPat);
  624.         }
  625.         else {                                                // we have a bitMap    
  626.             GetPort((GrafPtr*)&savePort);
  627.             SetPort((GrafPtr)(**hCDEF).offPort);        
  628.             offBits = (BitMap *)&((GrafPtr)(**hCDEF).offPort)->portBits;
  629.         }
  630.         
  631.         if(inColor) {                                        // need same colors
  632.             RGBForeColor(&saveFore);                        // offscreen
  633.             RGBBackColor(&saveBack);
  634.         }
  635.  
  636. //----------------------------------------------------------------------------------
  637. //    Erase background of offscreen port - pay attention to origin so patterned
  638. //    backgrounds are aligned
  639. //----------------------------------------------------------------------------------
  640.  
  641.         SetOrigin((**theCtl).contrlRect.left, (**theCtl).contrlRect.top);
  642.         EraseRect(&(**theCtl).contrlRect);
  643.         SetOrigin(0,0);
  644.                     
  645. //----------------------------------------------------------------------------------
  646. // draw the control parts into the offscreen port
  647. //----------------------------------------------------------------------------------
  648.     
  649.         haveGray = drawParts (theCtl, varCode, &rThumb);
  650.         
  651. //----------------------------------------------------------------------------------
  652. // Now, set up to copy the offscreen bit/pixmap to the screen
  653. //----------------------------------------------------------------------------------
  654.  
  655.         if(haveGW)
  656.             SetGWorld(savePort, saveGDev);
  657.         else
  658.             SetPort((GrafPtr)savePort);
  659.  
  660.         if(inColor) {
  661.             ForeColor(blackColor);
  662.             BackColor(whiteColor);
  663.         }
  664.  
  665. //----------------------------------------------------------------------------------
  666. // now copy it to the onscreen port and restore our colors
  667. //----------------------------------------------------------------------------------
  668.     
  669.         CopyBits(offBits,
  670.                 &((GrafPtr)savePort)->portBits,
  671.                 &offRect,
  672.                 &rScale,
  673.                 srcCopy, nil);
  674.         
  675.         if(haveGW) {
  676.             unlockPixels(pmHdl, (**hCDEF).qdVers);
  677.             DisposeGWorld((**hCDEF).offPort);
  678.             (**hCDEF).offPort = 0;
  679.         }
  680.         
  681.         if(inColor)
  682.             restoreColors(&saveFore, &saveBack);
  683.         
  684. //----------------------------------------------------------------------------------
  685. // if we failed to get an inactive gray color, do it the old way
  686. //----------------------------------------------------------------------------------
  687.  
  688.         if(inactive && !haveGray) {                            // use the old way of drawing
  689.             GetPenState(&savePen);                            // an inactive control
  690.             PenMode(patBic);
  691.             PenPat( (ConstPatternParam) "\xAA\x55\xAA\x55\xAA\x55\xAA\x55");
  692.             PaintRect(&(**theCtl).contrlRect);
  693.             SetPenState(&savePen);
  694.         }
  695.         SetClip(saveClip);
  696.         DisposeRgn(saveClip);
  697.         DisposeRgn(newClip);
  698.     }
  699. }