home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Pascal / Libraries / DBL Pascal Library / DefProcs / ICON Cntl / IconCDEF.p next >
Encoding:
Text File  |  1992-10-02  |  8.2 KB  |  256 lines  |  [TEXT/PJMM]

  1. unit IconCDEF;
  2.  
  3. {David B. Lamkins, June 1991}
  4.  
  5. {This is a CDEF for a momentary-action icon button that provides the following features:}
  6. {    • Uses control title, rather than a separate dialog item or control title.}
  7. {    • Handles “showTitle” variant (CDEF ID*16+1) to display control title centered under icon.}
  8. {    • Handles “useWFont” variant (CDEF ID*16+8) to display title using window font.}
  9. {    • Recognizes HiliteControl to enable/disable button.}
  10. {}
  11. {Use:}
  12. {    CNTL min = ICON resource ID for control value 0.}
  13. {    CNTL max = ICON resource ID for control value 1.}
  14. {    CNTL title = title to display for showTitle variant.}
  15. {    CNTL proc ID = 96, 97, 104, or 105 (since this is CDEF 6).}
  16. {    CNTL refcon is unused.}
  17. {    DITL rect must be at least as large as CNTL rect, otherwise Dialog Mgr won't detect hit in control.}
  18. {    You can not use SetCtlMin and SetCtlMax to change the icons on the fly…}
  19. {    Calling SetCtlValue changes the displayed icon.}
  20. {    If the dialog contains TE fields, “useWFont” requires special handling. The following is}
  21. {      derived from Apple's Q&A Stack:}
  22. {            theDialog := GetNewDialog(…);}
  23. {            SetPort(theDialog);}
  24. {            TextFont(…);}
  25. {            TextSize(…);}
  26. {            ShowWindow(theDialog);}
  27. {            for i := 1 to 3 do}
  28. {                if EventAvail(everyEvent, evt) then}
  29. {                    ;}
  30. {            with DialogPeek(theDialog)^.textH^^ do}
  31. {                begin}
  32. {                    txFont := theDialog^.txFont;}
  33. {                    txSize := theDialog^.txSize;}
  34. {                end;}
  35. {            InitCursor;}
  36. {            repeat}
  37. {                ModalDialog(…);}
  38. {                …}
  39. {            until …;}
  40. {            DisposDialog(theDialog);}
  41.  
  42. interface
  43.  
  44.     function main (varCode: Integer; theControl: ControlHandle; message: Integer; param: Longint): Longint;
  45.  
  46. implementation
  47.  
  48. {$SETC Debugging=False}
  49.  
  50.     function main;
  51.         const
  52.             calcCntlRgn = 10;        {new in System 6.x and 7.0}
  53.             calcThumbRgn = 11;    {new in System 6.x and 7.0}
  54.             titleInset = 1;
  55.             showTitle = 1;            {variant code}
  56.             partCode = 1;            {our part code}
  57.  
  58.         type
  59.             PrivateData = record
  60.                     icon0: Handle;        {the 0-state icon}
  61.                     icon1: Handle;        {the 1-state icon}
  62.                     patGrey: Pattern;    {our own grey pattern - can't use globals}
  63.                     ourRgn: RgnHandle;    {the control's region for tracking hits}
  64.                 end;
  65.             DataPtr = ^PrivateData;
  66.             DataHandle = ^DataPtr;
  67.  
  68.         var
  69.             savePort: GrafPtr;        {original port during drawing}
  70.             saveFont: Integer;        {original font}
  71.             saveSize: Integer;        {original size}
  72.             saveFace: Style;        {original style}
  73.             centerLine: Integer;    {vertical center line of icon}
  74.             titleWidth: Integer;        {width of the title}
  75.             titleRect: Rect;            {bounding rect of the title}
  76.             textBaseline: Integer;    {vertical position of title}
  77.             info: FontInfo;            {font info for drawing title}
  78.  
  79.     begin {Main — Icon Button CDEF}
  80.         main := 0;        {we normally return a zero}
  81.         HLock(Handle(theControl));    {lock down the control data for the duration}
  82.         with theControl^^ do
  83.             begin
  84.  
  85.         {----- Initialization -----}
  86.                 if message = initCntl then
  87.                     begin
  88. {$IFC Debugging}
  89.                         DebugStr('initCntl');
  90. {$ENDC}
  91.                         contrlData := NewHandleClear(SIZEOF(PrivateData));    {allocate private storage}
  92.                         if contrlData <> nil then
  93.                             begin
  94.                                 HLock(contrlData);
  95.                                 with DataHandle(contrlData)^^ do
  96.                                     begin    {create our local bitmap data}
  97.                                         StuffHex(@patGrey, 'AA55AA55AA55AA55');
  98.                                         icon0 := GetIcon(contrlMin);    {get handles to our icons}
  99.                                         icon1 := GetIcon(contrlMax);
  100.                                         ourRgn := NewRgn;    {create a region to hold button/title outline}
  101.                                     end;
  102.                                 HUnLock(contrlData);
  103.                             end;
  104.                     end
  105.  
  106.         {----- Disposal -----}
  107.                 else if message = dispCntl then
  108.                     begin
  109. {$IFC Debugging}
  110.                         DebugStr('dispCntl');
  111. {$ENDC}
  112.             {Don't know who else might be using our ICONs, so leave them alone.}
  113.                         if contrlData <> nil then
  114.                             begin
  115.                                 DisposeRgn(DataHandle(contrlData)^^.ourRgn);    {done forever with this region}
  116.                                 DisposHandle(contrlData);    {don't need our local data anymore, either}
  117.                             end;
  118.                     end
  119.  
  120.                 else if contrlData <> nil then
  121.                     begin
  122.                         HLock(contrlData);    {lock down control's private data}
  123.                         with DataHandle(contrlData)^^ do
  124.                             case message of
  125.  
  126.         {----- Drawing -----}
  127.                                 drawCntl: 
  128.                                     begin
  129. {$IFC Debugging}
  130.                                         DebugStr('drawCntl');
  131. {$ENDC}
  132.                                         GetPort(savePort);    {make sure we have the right port}
  133.                                         SetPort(contrlOwner);
  134.                                         with contrlOwner^ do    {remember the original font}
  135.                                             begin
  136.                                                 saveFont := txFont;
  137.                                                 saveSize := txSize;
  138.                                                 saveFace := txFace;
  139.                                             end;
  140.                                         if BAND(varCode, useWFont) = 0 then        {if we need system font, set it}
  141.                                             begin
  142.                                                 TextSize(0);
  143.                                                 TextFont(0);
  144.                                             end;
  145.                                         TextFace([]);    {make sure we have a clean face}
  146.                                         GetFontInfo(info);    {measure the title}
  147. {$PUSH}
  148. {$R-}
  149.                                         titleWidth := TextWidth(@contrlTitle[1], 0, ORD(contrlTitle[0]));
  150. {$POP}
  151.                                         with contrlRect do
  152.                                             begin    {force the control rect to fit an icon}
  153.                                                 bottom := top + 32;
  154.                                                 right := left + 32;
  155.                                                 centerLine := left + 16;
  156.                                             end;
  157.                                         with info, titleRect do
  158.                                             begin    {position the control title and establish its bounding rect}
  159.                                                 top := contrlRect.bottom;
  160.                                                 bottom := top + ascent + descent + leading;
  161.                                                 left := centerLine - titleWidth div 2;
  162.                                                 right := left + titleWidth;
  163.                                                 textBaseline := bottom - descent;
  164.                                             end;
  165.                                         InsetRect(titleRect, -titleInset, 0);
  166.                                         OpenRgn;    {make our region include the icon and the label}
  167.                                         FrameRect(contrlRect);
  168.                                         if BAND(varCode, showTitle) <> 0 then
  169.                                             FrameRect(titleRect);
  170.                                         CloseRgn(ourRgn);    {save the control's region for future reference}
  171.                                         if contrlValue < 0 then    {make sure our control value is legitimate}
  172.                                             contrlValue := 0
  173.                                         else if contrlValue > 1 then
  174.                                             contrlValue := 1;
  175.                                         if contrlVis <> 0 then {if the control is visible…}
  176.                                             if (icon0 <> nil) and (icon1 <> nil) then    {…and both icons are present…}
  177.                                                 begin    {draw the control}
  178.                                                     LoadResource(icon0);    {what if ICONs were purged?}
  179.                                                     LoadResource(icon1);
  180.                                                     if BAND(varCode, showTitle) <> 0 then
  181.                                                         begin    {draw the title}
  182.                                                             EraseRect(titleRect);
  183.                                                             MoveTo(titleRect.left + titleInset, textBaseline);
  184.                                                             DrawString(contrlTitle);
  185.                                                         end;
  186.                                                     case contrlHilite of
  187.                                                         0, 255:    {display normal control}
  188.                                                             case contrlValue of
  189.                                                                 0: 
  190.                                                                     PlotIcon(contrlRect, icon0);
  191.                                                                 1: 
  192.                                                                     PlotIcon(contrlRect, icon1);
  193.                                                             end;
  194.                                                         1:     {display active control}
  195.                                                             begin
  196.                                                                 if BAND(varCode, showTitle) <> 0 then
  197.                                                                     InvertRect(titleRect);    {hilite the title}
  198.                                                                 case contrlValue of    {display “pressed” icon}
  199.                                                                     0: 
  200.                                                                         PlotIcon(contrlRect, icon1);
  201.                                                                     1: 
  202.                                                                         PlotIcon(contrlRect, icon0);
  203.                                                                 end;
  204.                                                             end;
  205.                                                     end;
  206.                                                     if contrlHilite = 255 then
  207.                                                         begin    {grey out disabled control}
  208.                                                             PenPat(patGrey);
  209.                                                             PenMode(patBic);
  210.                                                             PaintRect(contrlRect);
  211.                                                             PaintRect(titleRect);
  212.                                                         end;
  213.                                                 end
  214.                                             else
  215.                                                 begin    {no icon? draw a blank…}
  216.                                                     PenPat(patGrey);
  217.                                                     PaintRect(contrlRect);
  218.                                                 end;
  219.                                         TextFont(saveFont);    {set everything back the way it was}
  220.                                         TextSize(saveSize);
  221.                                         TextFace(saveFace);
  222.                                         SetPort(savePort);
  223.                                     end;
  224.  
  225.         {----- Testing -----}
  226.                                 testCntl: 
  227.                                     begin
  228. {$IFC Debugging}
  229.                                         DebugStr('testCntl');
  230. {$ENDC}
  231.                                         if (contrlHilite <> 255) and PtInRgn(Point(param), ourRgn) then
  232.                                             main := partCode;    {hit our control}
  233.                                     end;
  234.  
  235.         {----- Regions -----}
  236.                                 calcCRgns, calcCntlRgn: 
  237.                                     begin
  238. {$IFC Debugging}
  239.                                         DebugStr('calcCRgns, calcCntlRgn');
  240. {$ENDC}
  241.                                         if (message <> calcCRgns) or not BTST(param, 31) then
  242.                                             CopyRgn(ourRgn, RgnHandle(param));    {return control region}
  243.                                     end;
  244.  
  245.                                 otherwise
  246.                                     ;    {don't handle other messages}
  247.  
  248.                             end;
  249.                         HUnLock(contrlData);
  250.                     end;
  251.             end;
  252.         HUnLock(Handle(theControl));
  253.     end;
  254.  
  255.  
  256. end.