home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 February: Tool Chest / Dev.CD Feb 94.toast / Tool Chest / Development Platforms / AppsToGo / AppsToGo.src / DTS.Lib / PICTControl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-18  |  9.9 KB  |  425 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** Program:         pictcontrol.c
  5. ** Written by:      Eric Soldan
  6. **
  7. ** Copyright © 1993 Apple Computer, Inc.
  8. ** All rights reserved.
  9. */
  10.  
  11. /* You may incorporate this sample code into your applications without
  12. ** restriction, though the sample code has been provided "AS IS" and the
  13. ** responsibility for its operation is 100% yours.  However, what you are
  14. ** not permitted to do is to redistribute the source as "DSC Sample Code"
  15. ** after having made changes. If you're going to re-distribute the source,
  16. ** we require that you make it clear in the source that the code was
  17. ** descended from Apple Sample Code, but that you've made changes. */
  18.  
  19.  
  20.  
  21. /*****************************************************************************/
  22.  
  23.  
  24.  
  25. #ifndef __PICTCONTROL__
  26. #include "PICTControl.h"
  27. #endif
  28.  
  29. #ifndef __CONTROLS__
  30. #include <Controls.h>
  31. #endif
  32.  
  33. #ifndef __DTSLib__
  34. #include "DTS.Lib.h"
  35. #endif
  36.  
  37. #ifndef __ERRORS__
  38. #include <Errors.h>
  39. #endif
  40.  
  41. #ifndef __GWLAYERS__
  42. #include "GWLayers.h"
  43. #endif
  44.  
  45. #ifndef __MEMORY__
  46. #include <Memory.h>
  47. #endif
  48.  
  49. #ifndef __PACKAGES__
  50. #include <Packages.h>
  51. #endif
  52.  
  53. #ifndef __RESOURCES__
  54. #include <Resources.h>
  55. #endif
  56.  
  57. #ifndef __STRINGUTILS__
  58. #include "StringUtils.h"
  59. #endif
  60.  
  61. #ifndef __UTILITIES__
  62. #include "Utilities.h"
  63. #endif
  64.  
  65.  
  66.  
  67. /*****************************************************************************/
  68.  
  69.  
  70.  
  71. typedef struct cdefRsrcJMP {
  72.     long    moveInst;
  73.     long    jsrInst;
  74.     short    jmpInst;
  75.     long    jmpAddress;
  76. } cdefRsrcJMP;
  77. typedef cdefRsrcJMP *cdefRsrcJMPPtr, **cdefRsrcJMPHndl;
  78.  
  79.  
  80.  
  81. /*****************************************************************************/
  82.  
  83.  
  84.  
  85. short    gPICTCtl = rPICTCtl;
  86.  
  87. extern ControlHandle    gWhichCtlHit;
  88. extern Boolean            gWhichCtlDbl;
  89. extern Boolean            gWhichCtlTracking;
  90.  
  91. static pascal long        CPICTCtl   (short varCode, ControlHandle ctl, short msg, long parm);
  92. static pascal void        CPICTAction(ControlHandle ctl, short part);
  93. static cdefRsrcJMPHndl    gCDEF;
  94.  
  95.  
  96.  
  97. /*****************************************************************************/
  98. /*****************************************************************************/
  99. /*****************************************************************************/
  100.  
  101.  
  102.  
  103. #pragma segment Controls
  104. static pascal long    CPICTCtl(short varCode, ControlHandle ctl, short msg, long parm)
  105. {
  106.     Rect            viewRct, r;
  107.     short            thisHilite, keepHilite;
  108.     unsigned long    resPICTID, id, variant, sticky, offScreen;
  109.     PicHandle        pict;
  110.     ControlHandle    cc;
  111.     WindowPtr        ww, curPort, keepPort;
  112.     LayerObj        wlayer, blayer;
  113.     RgnHandle        oldClip, newClip, colorRgn;
  114.     Point            pt;
  115.  
  116.     viewRct    = (*ctl)->contrlRect;
  117.     thisHilite = (*ctl)->contrlHilite;
  118.     resPICTID  = (*ctl)->contrlRfCon & 0x0000FFFFL;
  119.     variant    = (*ctl)->contrlRfCon & 0xFFFF0000L;
  120.     sticky     = variant & 0x00010000L;
  121.     offScreen  = variant & 0x00020000L;
  122.  
  123.     switch (msg) {
  124.  
  125.         case drawCntl:
  126.  
  127.             GetPort(&curPort);                        /* Find out color area v.s. b/w area. */
  128.             if (offScreen) {
  129.                 NewLayer(&wlayer, nil, nil, curPort, 0, 0);
  130.                 r = curPort->portRect;
  131.                 SectRect(&r, &viewRct, &r);
  132.                 (*wlayer)->dstRect = r;                /* Minimize the size of the offscreen. */
  133.                 NewLayer(&blayer, wlayer, nil, nil, 0, 0);
  134.                 SetLayerWorld(blayer);
  135.                 InvalLayer(wlayer, r, false);
  136.             }
  137.  
  138.             if (sticky) {
  139.                 if (thisHilite < 2)
  140.                     thisHilite = (*ctl)->contrlValue;
  141.                 if (thisHilite == 2)
  142.                     thisHilite = 255;
  143.             }
  144.  
  145.             switch (thisHilite) {
  146.                 case 1:
  147.                 case 255:
  148.                     id = (thisHilite == 1) ? (resPICTID + 2) :(resPICTID + 4);
  149.                     if (!Get1Resource('PICT', id)) id = resPICTID;
  150.                     (*ctl)->contrlRfCon = (id + variant - offScreen);
  151.                     keepHilite = (*ctl)->contrlHilite;
  152.                     (*ctl)->contrlHilite = 99;
  153.                     CPICTCtl(varCode, ctl, msg, parm);
  154.                     (*ctl)->contrlHilite = keepHilite;
  155.                     (*ctl)->contrlRfCon  = (resPICTID | variant);
  156.                     if (thisHilite == 1)
  157.                         if (id == resPICTID)
  158.                             InvertRect(&viewRct);
  159.                                 /* If there is no hilite==1 'PICT', invert the base 'PICT'. */
  160.                     break;
  161.                 default:
  162.                     EraseRect(&viewRct);        /* Start pict fresh and clean. */
  163.  
  164.                     if (!(pict = (PicHandle)Get1Resource('PICT', resPICTID))) {
  165.                         FrameRect(&viewRct);
  166.                         break;
  167.                     }
  168.  
  169.                     oldClip  = NewRgn();
  170.                     newClip  = NewRgn();
  171.                     colorRgn = ScreenDepthRegion(4);
  172.  
  173.                     GetPort(&keepPort);
  174.                     SetPort((*ctl)->contrlOwner);
  175.                     pt.h = pt.v = 0;
  176.                     GlobalToLocal(&pt);
  177.                     OffsetRgn(colorRgn, pt.h, pt.v);
  178.                     SetPort(keepPort);
  179.  
  180.                     GetClip(oldClip);            /* Draw color area first. */
  181.                     RectRgn(newClip, &curPort->portRect);
  182.                     SectRgn(newClip, colorRgn, newClip);
  183.                     SetClip(newClip);
  184.                     DrawPicture(pict, &viewRct);
  185.  
  186.                     pict = (PicHandle)Get1Resource('PICT', resPICTID + 1);
  187.                     if (!pict)
  188.                         pict = (PicHandle)Get1Resource('PICT', resPICTID);
  189.                     if (pict) {
  190.                         RectRgn(newClip, &curPort->portRect);    /* Draw b/w pict area. */
  191.                         DiffRgn(newClip, colorRgn, newClip);
  192.                         SetClip(newClip);
  193.                         DrawPicture(pict, &viewRct);
  194.                     }
  195.  
  196.                     SetClip(oldClip);
  197.                     DisposeRgn(oldClip);
  198.                     DisposeRgn(newClip);
  199.                     DisposeRgn(colorRgn);
  200.  
  201.                     break;
  202.             }
  203.  
  204.             if (offScreen) {
  205.                 UpdateLayer(wlayer);
  206.                 ResetLayerWorld(blayer);
  207.                 DisposeThisAndBelowLayers(wlayer);
  208.             }
  209.  
  210.             break;
  211.  
  212.         case testCntl:
  213.  
  214.             if ((*ctl)->contrlHilite == 255) return(0);
  215.                 /* Control disabled, so no click.  (We probably don't get called in this case. */
  216.  
  217.             if (!sticky) return(PtInRect(*(Point *)&parm, &viewRct));
  218.                 /* Don't make user call WhichControl unless the variant
  219.                 ** is for double-clicking.  (Then it has to be called.) */
  220.  
  221.             if (ctl != gWhichCtlHit) return(0);
  222.                 /* WhichControl already found the control hit.  Unless it is the one
  223.                 ** found by WhichControl, consider it unhit. */
  224.  
  225.             if (gWhichCtlTracking) return(1);
  226.                 /* We already handled it, but the control manager is insistent. */
  227.  
  228.             if (!(*ctl)->contrlValue) {            /* Turn off any other controls in this family. */
  229.                 ww = (*ctl)->contrlOwner;
  230.                 for (cc = nil; cc = CPICTNext(ww, cc, 1, true);) {
  231.                     if (cc != ctl) {
  232.                         if (((*cc)->contrlMax & 0xFFF0) == ((*ctl)->contrlMax & 0xFFF0)) {
  233.                             if ((*cc)->contrlValue) {
  234.                                 (*cc)->contrlValue  = 0;
  235.                                 (*cc)->contrlHilite = 0;
  236.                                 CPICTCtl(varCode, cc, drawCntl, 0);
  237.                             }
  238.                         }
  239.                     }
  240.                 }
  241.             }
  242.  
  243.             (*ctl)->contrlValue = 1;
  244.             if (gWhichCtlDbl)                        /* If user double-clicked... */
  245.                 if (!((*ctl)->contrlMax & 0x01))    /* If double-clicking allowed... */
  246.                     (*ctl)->contrlValue = 2;
  247.  
  248.             CPICTCtl(varCode, ctl, drawCntl, 0);
  249.  
  250.             gWhichCtlTracking = true;
  251.             return(1);
  252.  
  253.             break;
  254.  
  255.         case calcCRgns:
  256.         case calcCntlRgn:
  257.             if (msg == calcCRgns)
  258.                 parm &= 0x00FFFFFF;
  259.             RectRgn((RgnHandle)parm, &viewRct);
  260.             break;
  261.  
  262.         case initCntl:
  263.             break;
  264.  
  265.         case dispCntl:
  266.             break;
  267.  
  268.         case posCntl:
  269.             break;
  270.  
  271.         case thumbCntl:
  272.             break;
  273.  
  274.         case dragCntl:
  275.             break;
  276.  
  277.         case autoTrack:
  278.             break;
  279.     }
  280.  
  281.     return(0);
  282. }
  283.  
  284.  
  285.  
  286. /*****************************************************************************/
  287.  
  288.  
  289.  
  290. #pragma segment Controls
  291. ControlHandle    CPICTNew(WindowPtr window, Rect *r, Boolean vis, short val, short min, short max,
  292.                          short viewID, short refcon)
  293. {
  294.     WindowPtr        oldPort;
  295.     Rect            viewRct, rct;
  296.     Boolean            err;
  297.     ControlHandle    viewCtl;
  298.     unsigned long    variant;
  299.     PicHandle        pict;
  300.  
  301.     GetPort(&oldPort);
  302.     SetPort(window);
  303.  
  304.     viewRct = *r;
  305.     viewCtl = nil;
  306.  
  307.     err = false;
  308.  
  309.     if (!gCDEF) {
  310.         gCDEF = (cdefRsrcJMPHndl)GetResource('CDEF', (viewID / 16));
  311.         if (gCDEF) {
  312.             (*gCDEF)->jmpAddress = (long)CPICTCtl;
  313.             FlushInstructionCache();    /* Make sure that instruction caches don't kill us. */
  314.         }
  315.         else err = true;
  316.     }
  317.  
  318.     if (!err) {
  319.         if (viewID & 0x04) {
  320.             viewID -= 0x04;
  321.             if (pict = (PicHandle)Get1Resource('PICT', refcon)) {
  322.                 rct = (*pict)->picFrame;
  323.                 viewRct.right  = viewRct.left + (rct.right  - rct.left);
  324.                 viewRct.bottom = viewRct.top  + (rct.bottom - rct.top);
  325.             }
  326.         }
  327.         variant   = (viewID & 0x0F);
  328.         variant <<= 16;
  329.         viewCtl = NewControl(window, &viewRct, "\p", vis, val, min, max, viewID, (variant | refcon));
  330.         if (viewCtl)
  331.             SetCtlAction(viewCtl, (ProcPtr)CPICTAction);
  332.         else
  333.             err = true;
  334.     }
  335.  
  336.     SetPort(oldPort);
  337.  
  338.     return(viewCtl);
  339. }
  340.  
  341.  
  342.  
  343. /*****************************************************************************/
  344.  
  345.  
  346.  
  347. #pragma segment Controls
  348. ControlHandle    CPICTNext(WindowPtr window, ControlHandle ctl, short dir, Boolean justActive)
  349. {
  350.     ControlHandle    nextCtl, priorCtl;
  351.  
  352.     if (!window) return(nil);
  353.     if (!gCDEF)  return(nil);
  354.  
  355.     if (dir > 0) {
  356.         if (!ctl)
  357.             ctl = ((WindowPeek)window)->controlList;
  358.         else
  359.             ctl = (*ctl)->nextControl;
  360.         while (ctl) {
  361.             if ((!justActive) || ((*ctl)->contrlVis)) {
  362.                 if ((!justActive) || ((*ctl)->contrlHilite != 255)) {
  363.                     if (*(*ctl)->contrlDefProc == *(Handle)gCDEF)
  364.                         return(ctl);
  365.                             /* The handle may be locked, which means that the hi-bit
  366.                             ** may be on, thus invalidating the compare.  Dereference the
  367.                             ** handles to get rid of this possibility. */
  368.                 }
  369.             }
  370.             ctl = (*ctl)->nextControl;
  371.         }
  372.         return(ctl);
  373.     }
  374.  
  375.     nextCtl = ((WindowPeek)window)->controlList;
  376.     for (priorCtl = nil; ;nextCtl = (*nextCtl)->nextControl) {
  377.         if ((!nextCtl) || (nextCtl == ctl)) return(priorCtl);
  378.         if ((!justActive) || ((*nextCtl)->contrlVis)) {
  379.             if ((!justActive) || ((*nextCtl)->contrlHilite != 255)) {
  380.                 if (*(*ctl)->contrlDefProc == *(Handle)gCDEF)
  381.                     priorCtl = nextCtl;
  382.                         /* The handle may be locked, which means that the hi-bit
  383.                         ** may be on, thus invalidating the compare.  Dereference the
  384.                         ** handles to get rid of this possibility. */
  385.             }
  386.         }
  387.     }
  388. }
  389.  
  390.  
  391.  
  392. /*****************************************************************************/
  393.  
  394.  
  395.  
  396. #pragma segment Controls
  397. Boolean    IsPICTCtl(ControlHandle ctl)
  398. {
  399.     if (*(*ctl)->contrlDefProc == *(Handle)gCDEF) return(true);
  400.         /* The handle may be locked, which means that the hi-bit
  401.         ** may be on, thus invalidating the compare.  Dereference the
  402.         ** handles to get rid of this possibility. */
  403.     return(false);
  404. }
  405.  
  406.  
  407.  
  408. /*****************************************************************************/
  409.  
  410.  
  411.  
  412. #pragma segment Controls
  413. static pascal void    CPICTAction(ControlHandle ctl, short part)
  414. {
  415.     static short    lastPart = 0;
  416.  
  417.     if (lastPart != part) {
  418.         lastPart = part;
  419.         CPICTCtl(0, ctl, drawCntl, part);
  420.     }
  421. }
  422.  
  423.  
  424.  
  425.