home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Code Resources / Progress CDEFs 1.3 / Progress Arc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-29  |  8.8 KB  |  216 lines  |  [TEXT/KAHL]

  1. /*****************************************************************
  2.  
  3. Legal stuff:
  4.  
  5. Progress Arc CDEF 1.3 by Eddy J. Gurney. This CDEF is copyright ©1993–4 by Eddy J. Gurney
  6. and The Eccentricity Group, but is "freeware". It may be freely distributed, modified, included
  7. in any application, on a source code compilation CD-ROM, etc. as long as the following simple
  8. restrictions are met:
  9.     1) this entire copyright notice remains intact when this source is redistributed, modified, etc.
  10.     2) the copyright notice in the CDEF itself (the "copyright" string) remains intact,
  11.     3) this source, or any of its derivitave works (including the CDEF itself), are NOT made
  12.         available on or used in any form by any electronic service (or associated electronic
  13.         service) which restricts the electronic distribution of some or all of its files (ie, ZiffNet).
  14. Feel free to add your name, company, whatever to the copyright. However you can NOT remove
  15. the restrictions I've described above or add further restrictions on its use or distribution.
  16. Finally, no warranty of any kind is expressed or implied.
  17.  
  18. Usage:
  19.  
  20. This CDEF allows you to very easily display a circular progress indicator from your application.
  21. To use it, copy the CDEF to your project's resource file. Add a "CNTL" to your dialog, and set
  22. the control's ProcID to:
  23.     16*the resource ID you gave this CDEF (default ID is 601) + variation code (see below).
  24. Next set the initial, minimum and maximum values. (ie., 0, 0, 100 for a "percentage" arc).
  25. Finally, if you would like to use custom colors for the progress arc, use a variation code of
  26. 1 instead of 0 and and edit the colors (stored in a corresponding 'cctb' resource) as desired.
  27. (FrameColor is used for the frame, BodyColor is used as the background color [never
  28. really used], TextColor is used for the "done" part of the arc, and ThumbColor is used for the
  29. "to do" part of the arc. This is the same order as they appear in Resorcerer's "CNTL" editor,
  30. so you don't have to edit the 'cctb' directly.) If you use custom controls, make sure to try
  31. them at various bit depths to make sure QuickDraw maps the done/to do parts to different
  32. colors (the default colors are OK).
  33.  
  34. After that, in your program all you have to do is call SetCtlValue() and this CDEF will 
  35. automagically draw your "progress arc"!
  36.  
  37. !!WARNING!! This CDEF assumes the presence of the _Gestalt trap (available in System 7 or
  38. later.) I didn't want to include the glue to emulate _Gestalt under System 6 (to keep the
  39. size down).  If you need to use this in an application that may be running under System 6,
  40. just define SystemSevenOrLater to 0 instead of 1 and rebuild the code resource.
  41.  
  42. If someone knows of a "supported" way to check for Color QuickDraw without calling _Gestalt,
  43. let me know and I'll include it in the next release.
  44.  
  45. P.S. I code in Geneva 9, so if this looks unformatted, that's why. It will look fine in any window
  46. about 640 pixels wide when viewed in Geneva 9. :-)
  47.  
  48. E-mail comments, suggestions, requests to: egurney@vcd.hp.com
  49.  
  50. 1.0: First public release
  51. 1.3 changes (thanks Steve LoBasso for the suggestions):
  52.      . Bumped version to 1.3 to correspond with my Progress Bar CDEF which this is based off of
  53.      . RGBForeColor and RGBBackColor can move memory; we copy the AuxCtlTable color data to a
  54.        temporary variable to avoid the trap overhead of HLock/HUnlock.
  55.      . Added code to ensure the control value is never outside the control min/max range
  56.  
  57. ******************************************************************/
  58.  
  59. #ifdef SystemSevenOrLater
  60. #undef SystemSevenOrLater
  61. #endif
  62.  
  63. #define SystemSevenOrLater 1
  64.  
  65. #include <GestaltEqu.h>
  66. #include <SetUpA4.h>
  67.  
  68. const unsigned char copyright[] = "Progress Arc CDEF 1.3 ©1993–94 Eddy J. Gurney/TEG. Freeware.";
  69.  
  70. pascal long main(short variation, ControlHandle theControl, short msg, long param)
  71. {
  72.     /* These need to be declared static to work. See the Note on p. 283 of Think C 6 User's Guide */    
  73.     const static RGBColor    kBlack = { 0, 0, 0 };
  74.     const static RGBColor    kWhite = { 0xffff, 0xffff, 0xffff };
  75.     const static RGBColor    kDarkGray = { 0x4000, 0x4000, 0x4000 };
  76.     const static RGBColor    kSteelBlue= { 0xcccc, 0xcccc, 0xffff };
  77.     long                    result;
  78.  
  79.     RememberA0();
  80.     SetUpA4();
  81.  
  82.     result = 0;
  83.  
  84.     switch (msg) {
  85.         case initCntl: {
  86.             long            gestaltResponse;
  87.  
  88.             (void)Gestalt(gestaltQuickdrawVersion, &gestaltResponse);
  89.             (*theControl)->contrlData = (Handle)(gestaltResponse >= gestalt8BitQD);
  90.             break;
  91.         }
  92.  
  93.         case drawCntl: {
  94.             PenState        oldPenState;
  95.             Boolean        hasColorQD = (Boolean)(*theControl)->contrlData;
  96.             RGBColor        oldForeColor, oldBackColor, tempColor;
  97.             Rect            arcRect;
  98.             AuxCtlHandle    auxControlData;
  99.             short        length, doneArcDegree, toDoArcDegree, controlValue;
  100.  
  101.             if ((*theControl)->contrlVis) {
  102.                 GetPenState(&oldPenState);
  103.                 PenNormal();
  104.     
  105.                 arcRect = (*theControl)->contrlRect;
  106.     
  107.                 if (hasColorQD) {
  108.                     GetForeColor(&oldForeColor);
  109.                     GetBackColor(&oldBackColor);
  110.                     /* Check if we should use custom colors, or the default Finder colors */
  111.                     if (variation == 1 && GetAuxCtl(theControl, &auxControlData)) {
  112.                         /* Because RGBForeColor/RGBBackColor can move memory, we copy the color
  113.                            to a temporary variable. This way, we avoid the trap overhead of HLock/HUnlock. */
  114.                         tempColor = (*(*auxControlData)->acCTable)->ctTable[cFrameColor].rgb;
  115.                         RGBForeColor(&tempColor);
  116.                         tempColor = (*(*auxControlData)->acCTable)->ctTable[cBodyColor].rgb;
  117.                         RGBBackColor(&tempColor);
  118.                     } else {
  119.                         auxControlData = nil;
  120.                         RGBForeColor(&kBlack);
  121.                         RGBBackColor(&kWhite);
  122.                     }
  123.                 } /* If no Color QD, we'll be drawing in black because of our call to PenNormal above */
  124.                 FrameOval(&arcRect);    /* Frame the progress arc in the frame color */
  125.  
  126.                 InsetRect(&arcRect, 1, 1);
  127.  
  128.                 /* Make sure the controlValue is in bounds. SetCtlValue does this already, but the user could
  129.                    have a bad "initial" value, or could set the contrlValue field directly.*/
  130.                 if ((*theControl)->contrlValue > (*theControl)->contrlMax)
  131.                     controlValue = (*theControl)->contrlMax;
  132.                 else if ((*theControl)->contrlValue < (*theControl)->contrlMin)
  133.                     controlValue = (*theControl)->contrlMin;
  134.                 else
  135.                     controlValue = (*theControl)->contrlValue;
  136.                 
  137.                 /* Determine how much of the progress bar to draw, making sure we don't divide by zero */
  138.                 if (length = ((*theControl)->contrlMax - (*theControl)->contrlMin)) {
  139.                     doneArcDegree = ((long)(controlValue - (*theControl)->contrlMin) * 360) / length;
  140.                 }
  141.                 toDoArcDegree = 360 - doneArcDegree;
  142.  
  143.                 if (hasColorQD) {
  144.                     if (variation == 1 && auxControlData != nil) {
  145.                         tempColor = (*(*auxControlData)->acCTable)->ctTable[cTextColor].rgb;
  146.                         RGBForeColor(&tempColor);
  147.                     } else
  148.                         RGBForeColor(&kDarkGray);
  149.                 } /* If no Color QD, we're still drawing in black */
  150.                 PaintArc(&arcRect, 0, doneArcDegree);        /* Draw the "done" part */ 
  151.  
  152.                 if (hasColorQD) {
  153.                     /* QD checks to see if the foreground color maps into the same color as the background
  154.                          color. If so, QD inverts the foreground color and draws with it instead. This is BAD for
  155.                          us! If the user is in 1-bit mode, "Steel Blue" will map to white, which QD sees is the
  156.                          same as the background color, and sets it to black instead… and the progress bar
  157.                          becomes "invisible"! So we "trick" QD by changing the background color, which doesn't
  158.                          matter since we never draw with it anyway. Thanks to Knaster & Rollin (Macintosh
  159.                          Programming Secrets) for describing this behavior… */
  160.                     if (variation == 1 && auxControlData != nil) {
  161.                         tempColor = (*(*auxControlData)->acCTable)->ctTable[cThumbColor].rgb;
  162.                         RGBForeColor(&tempColor);
  163.                         tempColor = (*(*auxControlData)->acCTable)->ctTable[cFrameColor].rgb;
  164.                         RGBBackColor(&tempColor);
  165.                     } else {
  166.                         RGBForeColor(&kSteelBlue);
  167.                         RGBBackColor(&kBlack);
  168.                     }
  169.                 } else { /* If no Color QD, we switch to white via patBic (force white where pattern black) mode */
  170.                     PenMode(patBic);
  171.                 }
  172.                 PaintArc(&arcRect, doneArcDegree, toDoArcDegree);    /* Draw the "to do" part */
  173.  
  174.                 if (hasColorQD) {
  175.                     RGBForeColor(&oldForeColor);
  176.                     RGBBackColor(&oldBackColor);
  177.                 }
  178.                 SetPenState(&oldPenState);
  179.             }
  180.             break;
  181.         }
  182.         
  183.         case calcCRgns:    /* This is the message sent if using 24-bit addressing */
  184.             param = (long)StripAddress((Ptr)param);        /* Mask off the high byte if necessary */
  185.             /* Fall through on purpose! */
  186.  
  187.         case calcCntlRgn:    /* Under 32-bit addressing we get this message */
  188.             RectRgn((RgnHandle)param, &(*theControl)->contrlRect);
  189.             break;
  190.  
  191.     #ifdef FOR_COMPLETENESS
  192.         case testCntl:
  193.         case dispCntl:
  194.         case posCntl:
  195.         case thumbCntl:
  196.         case dragCntl:
  197.         case autoTrack:
  198.         case undoDev:
  199.         case cutDev:
  200.         case copyDev:
  201.         case pasteDev:
  202.         case clearDev:
  203.         case cursorDev:
  204.         case calcThumbRgn:
  205.             break;    /* We don't respond to any of these messages */
  206.     #endif
  207.  
  208.         default:    /* Any other messages we don't handle or which aren't defined yet */
  209.             break;
  210.     }
  211.  
  212.     RestoreA4();
  213.  
  214.     return result;
  215. }
  216.