home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1988 / 03 / krute / krute.ls3 < prev    next >
Text File  |  1987-12-03  |  35KB  |  1,097 lines

  1. *----------------------------------- file information -----------------------------    *
  2. *                                                                                                                *
  3. *    rectCDEF.Asm                                                                                            *        
  4. *                                                                                                                *
  5. *                                                                                                                *
  6. *    Assembly language source code for several styles of rectangular button controls    *
  7. *    The assembled code is meant to be a CDEF resource                                            *
  8. *                                                                                                                *
  9. *    The CDEF provides 16 styles of rectangular button controls                                *
  10. *    A button can:  (1)    contain text, an ICON, or a PICT                                        *
  11. *                        (2)    can be outlined, or shadow-outlined                                    *
  12. *                        (3)    if it contains an ICON or a PICT, can be bare                    *
  13. *                        (4)    indicate pressing via inversion or a content change            *
  14. *                                                                                                                *
  15. *    Edited with QUED/M 2.04                                                                                *
  16. *    Compiled under MDS 2.01                                                                                *
  17. *                                                                                                                *
  18. *    Written and ⌐1987 by Stan Krute. All rights reserved. No part of this file,        *
  19. *    or the object code it leads to, may be reproduced, in any form or by any means,    *
  20. *    without    the express written permission of the author and copyright holder.         *
  21. *                                                                                                                *
  22. *    Timestamp:        6:51 pm PST                    November 16, 1987                                    *
  23. *    Spacestamp:        18617 Camp Creek Road    Hornbrook, California   96044                    *
  24. *                                                                                                                *
  25. *    This file looks good in 9 point Courier, QUED/M 2.04 tabs set to 3                    *
  26. *                                                                                                                *
  27. *---------------------------------------------------------------------------------    *
  28.  
  29.  
  30. * --------------------------------- using the CDEF -------------------------------- *
  31.  
  32. ; details on using the CDEF resource produced by this code
  33.  
  34. ;    a custom control is most easily specified via a CNTL resource, 
  35. ;        which uses a procID to indicate the CDEF resource ID and variation code
  36.  
  37. ;     for this CDEF, the resource ID is 40
  38.  
  39. ;     there are 16 variations, as follows:
  40.  
  41. ;        variation    content    border        highlighting via        proc ID
  42. ;        ---------    -------    --------        ----------------        -----
  43. ;        0                text        outlined        inversion                640
  44. ;        1                text        outlined        content change            641
  45. ;        2                text        shadowed        inversion                642
  46. ;        3                text        shadowed        content change            643
  47.  
  48. ;        4                PICT        bare            inversion                644
  49. ;        5                PICT        bare            content change            645
  50. ;        6                PICT        outlined        inversion                646
  51. ;        7                PICT        outlined        content change            647
  52. ;        8                PICT        shadowed        inversion                648
  53. ;        9                PICT        shadowed        content change            649
  54.  
  55. ;        10                ICON        bare            inversion                650
  56. ;        11                ICON        bare            content change            651
  57. ;        12                ICON        outlined        inversion                652
  58. ;        13                ICON        outlined        content change            653
  59. ;        14                ICON        shadowed        inversion                654
  60. ;        15                ICON        shadowed        content change            655
  61.  
  62. ;    for TEXT variations, select a font via the CNTL's contrlValue field:
  63. ;        -1 for the window's font, 0 for the System font, 1 for the application font,
  64. ;        anything else a standard Mac font number
  65. ;    in the case of a font other than the System or window's font, store the font 
  66. ;        style in the high byte of the contrlMin field, and the font size in the 
  67. ;        low byte of the contrlMax field
  68.  
  69. ;    for PICT and ICON variations, store a resource ID indicating the PICT or ICON 
  70. ;            resource in the low word of the CNTL's refCon field
  71.  
  72. ;    for variations that indicate highlighting via a content change, store a resource 
  73. ;            ID indicating the highlighted-state STR  (for text variations), PICT, or 
  74. ;            ICON resource in the high word of the CNTL's refCon field
  75.  
  76. ; when figuring the size of a text button's boundsRect :
  77. ;    be sure to size the button so the text will fit. Successive approximation works 
  78. ;     well. Rule of thumb for an initial height: 8 greater than the font size.
  79.  
  80. ; when figuring the size of a PICTure button's CNTL's boundsRect :
  81. ;    if the picture has no outline, try a boundsRect that matches the PICT's boundsRect
  82. ;    if the picture is outlined, try a boundsRect that's at least 4 wider and 4 
  83. ;        higher  -- that size lets the picture perfectly match the button's interior
  84. ;    pictures in larger boundsRects get centered
  85.  
  86. ; when figuring the size of a ICON button's CNTL's boundsRect :
  87. ;    if the icon has no outline, try a boundsRect that matches the ICON's boundsRect
  88. ;    if the icon is outlined, try a boundsRect that's at least 4 wider and 4 
  89. ;        higher  -- that size lets the icon perfectly match the button's interior
  90. ;    icons in larger boundsRects get centered
  91.  
  92.  
  93. *----------------------------------- include files ---------------------------------*
  94.  
  95. ; standard Mac definitions
  96.     Include    MacTraps.D            ; condensed trap file
  97.     Include    SysEqu.D                ; system equates
  98.     Include    ToolEqu.D            ; toolbox equates
  99.     Include    QuickEqu.D            ; toolbox equates
  100.  
  101. ; our stuff
  102.     Include    rectCDEFEqu.Txt    ; private definitions for this file        
  103.  
  104.  
  105. *------------------------------- common entry point --------------------------------*
  106.  
  107. rectCDEFProc                            
  108.  
  109. ; provide a stack frame
  110.     LINK        A6,#-autoBytes        ; set frame pointer, with enough 
  111.                                         ; bytes for automatic variables
  112. ; save some registers
  113.     MOVEM.L    D3-D7/A2-A4,-(SP)    ; save some work registers
  114.  
  115. ; the key to 68000 code : fill those registers 
  116.     LEA        param(A6),A0            ; A0 points to param
  117.     MOVE.L    (A0)+,D3                    ; D3 holds param ( usage varies )
  118.     MOVE.W    (A0)+,D7                    ; D7 holds message (operation selector )
  119.     MOVEA.L    (A0)+,A2                    ; A2 holds theControl (control record handle )
  120.     CLR.L        D4                            ; clear out D4
  121.     MOVE.W    (A0)+,D4                    ; varCode into D4
  122.     MOVE.B    varFlagTable(D4),D4    ; D4 holds a byte of variation flags
  123.  
  124. ; set a default function result of 0, while A0's pointing in the right direction
  125.     CLR.L        (A0)                    
  126.  
  127. ; lock the control record down
  128.     MOVEA.L    A2,A0                
  129.     _HLock
  130.  
  131. ; get a pointer to the control record
  132.     MOVE.L    (A2),A2
  133.  
  134. ; lock down and get a pointer to any control data block
  135.     MOVE.L    contrlData(A2),D0    ; grab the handle
  136.     BEQ        caseOut            ; jump if NIL handle
  137.  
  138. ; we've got a control data block, so lock it
  139.     MOVEA.L    D0,A3                ; copy the handle
  140.     MOVEA.L    A3,A0                ; lock the block
  141.     _HLock
  142.     MOVEA.L    (A3),A3            ; get a pointer to the control data block
  143.  
  144. caseOut
  145. ; case out on the message
  146. ; just jump off a table of routine offsets
  147.     ADD.W        D7, D7                        ; double the message  integer
  148.     MOVE.W    messageTable(D7),D0        ; grab a table offset
  149.     JSR        messageTable(D0)            ; jump to messageTable + offset
  150.  
  151. ; clean up and go home
  152. ; if there was a control data block, unlock it
  153.     MOVE.L    contrlData(A2),D0    ; grab the handle
  154.     BEQ        unlockRec            ; jump if NIL handle
  155.  
  156. ; we've got a control data block, so unlock it
  157.     MOVEA.L    D0,A0                ; move the block's handle into place
  158.     _HUnlock                        ; and unlock it
  159.  
  160. unlockRec
  161. ; unlock the control record
  162.     MOVEA.L    theControl(A6),A0                    
  163.     _HUnlock
  164.  
  165. ; restore the saved registers
  166.     MOVEM.L    (SP)+,D3-D7/A2-A4    
  167.  
  168. ; remove the stack frame
  169.     UNLK        A6                        
  170.  
  171. ; fetch the return address
  172.     MOVEA.L    (SP)+, A0                
  173.                                         
  174. ; set stack pointer to the function result
  175.     ADD.L        #theResult-param,SP        
  176.  
  177. ; we're outta here
  178.     JMP        (A0)                    
  179.         
  180.  
  181. *---------------------------- the message jump table ------------------------------ *
  182.  
  183. ; there are nine possible messages
  184.  
  185. messageTable    
  186.     DC.W        doDrawCntl-messageTable        ; draw the control
  187.     DC.W        doTestCntl-messageTable        ; test the control
  188.     DC.W        doCalcCCntl-messageTable    ; calculate the control's region             
  189.     DC.W        doInitCntl-messageTable        ; do control initialization chores
  190.     DC.W        doDispCntl-messageTable        ; do control disposal chores
  191.     DC.W        doPosCntl-messageTable        ; reposition & update the control
  192.     DC.W        doThumbCntl-messageTable    ; calculate control dragging params
  193.     DC.W        doDragCntl-messageTable        ; drag the control 
  194.     DC.W        doAutoTrack-messageTable    ; do the control's action proc
  195.  
  196.  
  197. *---------------------------- the variations flag table --------------------------- *
  198.  
  199. ; there are sixteen control variations
  200.  
  201. ; eight bits are used to flag eight qualities of a control variation
  202. ; from bit 7 (hi) to bit 0 (lo), the bits are symbolically named :
  203. ;        textBit - pictBit - iconBit - outBit - shadBit - bareBit - invBit - chngBit
  204.  
  205. varFlagTable    
  206.     DC.B        %10010010        ; text - outlined - invert
  207.     DC.B        %10010001        ; text - outlined - content change
  208.     DC.B        %10011010        ; text - shadowed - invert
  209.     DC.B        %10011001        ; text - shadowed - content change
  210.  
  211.     DC.B        %01000110        ; pict - bare - invert
  212.     DC.B        %01000101        ; pict - bare - content change
  213.     DC.B        %01010010        ; pict - outlined - invert
  214.     DC.B        %01010001        ; pict - outlined - content change
  215.     DC.B        %01011010        ; pict - shadowed - invert
  216.     DC.B        %01011001        ; pict - shadowed - content change
  217.  
  218.     DC.B        %00100110        ; icon - bare - invert
  219.     DC.B        %00100101        ; icon - bare - content change
  220.     DC.B        %00110010        ; icon - outlined - invert
  221.     DC.B        %00110001        ; icon - outlined - content change
  222.     DC.B        %00111010        ; icon - shadowed - invert
  223.     DC.B        %00111001        ; icon - shadowed - content change
  224.  
  225.  
  226. *---------------------------------- doDrawCntl -------------------------------------*
  227.  
  228. ; the application wants the CDEF to draw the control
  229.  
  230. doDrawCntl
  231. ;  if control is invisible, do nothing
  232.     TST.B        contrlVis(A2)         ; non-zero if the control is visible
  233.     BEQ        drawn                    ; it's invisible, so no need to draw it
  234.  
  235. ; save the entry pen state
  236.     PEA        entryPenState(A6)
  237.     _GetPenState
  238.  
  239. ; normalize the pen state
  240.     _PenNormal
  241.  
  242. ; save a copy of the entry clip region
  243.     CLR.L        -(SP)                                ; get a new region 
  244.     _NewRgn
  245.     MOVE.L    (SP),entryClipRgnCopy(A6)    ; copy the entry clip region into it
  246.     _GetClip
  247.  
  248. shadOutTest
  249. ; see if a shadowed outline is to be drawn
  250.     BTST    #shadBit,D4            ; check it out
  251.     BEQ    simpOutTest            ; no shadowed outline, on to the simple outline test
  252.     BSR    doShadOutline        ; draw a shadowed outline
  253.     BSR    shadOutIntClip        ; set a clip rect for the interior
  254.     BRA    interiorDrawing    ; on to the interior tests
  255.  
  256. simpOutTest
  257. ; see if a simple outline is to be drawn
  258.     BTST    #outBit,D4            ; check it out
  259.     BEQ    noOutNoTest            ; if not, on to the no-outline duties
  260.     BSR    doSimpOutline        ; draw a simple outline
  261.     BSR    simpOutIntClip        ; set a clip rect for the interior
  262.     BRA    interiorDrawing    ; on to the interior tests
  263.  
  264. noOutNoTest
  265.     BSR    noOutIntClip        ; set a clip rect for the interior
  266.  
  267. interiorDrawing
  268. textTest
  269. ; see if the button will contain text
  270.     BTST    #textBit,D4            ; text ?
  271.     BEQ    pictTest                ; no, so next test
  272.     BSR    doTextInterior        ; yes, so draw text interior
  273.     BRA    drawn                    ; and jump on
  274.  
  275. pictTest
  276.     BTST    #pictBit,D4            ; pict ?
  277.     BEQ    iconNoTest            ; no, so it's an icon button
  278.     BSR    doPictInterior        ; yes, so draw pict interior
  279.     BRA    drawn                    ; and jump on
  280.  
  281. iconNoTest
  282.     BSR    doIconInterior        ; draw icon interior
  283.  
  284. drawn
  285. ; all drawn
  286.  
  287. ; restore the entry pen state
  288.     PEA        entryPenState(A6)
  289.     _SetPenState
  290.  
  291. ; restore the entry clipping region, and get rid of its holder
  292.     MOVE.L    entryClipRgnCopy(A6),-(SP)
  293.     MOVE.L    (SP),-(SP)
  294.     _SetClip
  295.     _DisposRgn
  296.  
  297. ; so long
  298.     RTS
  299.  
  300.  
  301. *--------------------------------- doShadOutline ---------------------------------- *
  302.  
  303. ; draw a shadowed outline for a button
  304.  
  305. doShadOutline
  306. ; move to the starting point for the horizontal shadow line: (left+2,bottom)
  307.     MOVE.W        contrlRect+left(A2),-(SP)
  308.     ADDQ.W        #0002,(SP)
  309.     MOVE.W        contrlRect+bottom(A2),-(SP)
  310.     _MoveTo
  311.  
  312. ; draw a line to the right side of the horizontal shadow line: (right,bottom)
  313.     MOVE.W        contrlRect+right(A2),-(SP)
  314.     MOVE.W        contrlRect+bottom(A2),-(SP)
  315.     _LineTo
  316.  
  317. ; draw a line to the top of the vertical shadow line: (right,top+2)
  318.     MOVE.W        contrlRect+right(A2),-(SP)
  319.     MOVE.W        contrlRect+top(A2),-(SP)
  320.     ADDQ.W        #$0002,(SP)
  321.     _LineTo
  322.  
  323. ; now draw an outline rect at (top,left,bottom,right)
  324.     PEA            contrlRect(A2)
  325.     _FrameRect
  326.  
  327. ; all done
  328.     RTS
  329.  
  330. *-------------------------------- doSimpOutline ----------------------------------- *
  331.  
  332. ; draw a simple outline for a button
  333.  
  334. doSimpOutline
  335.  
  336. ;  draw an outline rect at (top,left,bottom,right)
  337.     PEA            contrlRect(A2)
  338.     _FrameRect
  339.  
  340. ; all done
  341.     RTS
  342.  
  343. *--------------------------------- shadOutIntClip --------------------------------- *
  344.  
  345. ; set the clip region for the interior of a shadowed outlined button
  346.  
  347. shadOutIntClip
  348.  
  349. ; use the rect at (top+2,left+2,bottom-2,right-2)
  350.     MOVE.L        contrlRect+top(A2),interiorClipRect+top(A6)  
  351.     MOVE.L        contrlRect+bottom(A2),interiorClipRect+bottom(A6)    
  352.     ADDI.L        #$00020002,interiorClipRect+top(A6)    
  353.     SUBI.L        #$00020002,interiorClipRect+bottom(A6)    
  354.     PEA            interiorClipRect(A6)
  355.     _ClipRect
  356.  
  357. ; all done
  358.     RTS
  359.  
  360.  
  361. *------------------------------- simpOutIntClip ----------------------------------- *
  362.  
  363. ; set the clip region for the interior of a simply outlined button
  364.  
  365. simpOutIntClip
  366.  
  367. ; use the rect at (top+2,left+2,bottom-2,right-2)
  368.     MOVE.L        contrlRect+top(A2),interiorClipRect+top(A6)  
  369.     MOVE.L        contrlRect+bottom(A2),interiorClipRect+bottom(A6)    
  370.     ADDI.L        #$00020002,interiorClipRect+top(A6)    
  371.     SUBI.L        #$00020002,interiorClipRect+bottom(A6)    
  372.     PEA            interiorClipRect(A6)
  373.     _ClipRect
  374.  
  375. ; all done
  376.     RTS
  377.  
  378.  
  379. *-------------------------------- noOutIntClip ------------------------------------ *
  380.  
  381. ; set the clip region for the interior of a non-outlined button
  382.  
  383. noOutIntClip
  384.  
  385. ; use the rect at (top,left,bottom,right)
  386.     MOVE.L        contrlRect+top(A2),interiorClipRect+top(A6)  
  387.     MOVE.L        contrlRect+bottom(A2),interiorClipRect+bottom(A6)    
  388.     PEA            interiorClipRect(A6)
  389.     _ClipRect
  390.  
  391. ; done
  392.     RTS
  393.  
  394. *-------------------------------- doTextInterior ---------------------------------- *
  395.  
  396. ; draw a button's text content, in an indicated font
  397.  
  398. doTextInterior
  399.  
  400. ; get a pointer to the current grafPort into A4
  401.     PEA            currentGrafPort(A6)
  402.     _GetPort
  403.     MOVEA.L        currentGrafPort(A6),A4  
  404.     
  405. ;  we may be using a font other than the window's, so save current font settings
  406.     MOVE.L        txFont(A4),curFontAndFace(A6)    ; font and style
  407.     MOVE.W        txSize(A4),curSize(A6)            ; size
  408.  
  409. ; the control's font is indicated by a value in the control record's contrlValue 
  410. ;    field:  -1 for the window's font, 0 for the System font, 1 for the application 
  411. ;    font, anything else a standard Mac font number
  412.  
  413. ; in the case of a font other than the System or window's font, the font style  
  414. ;    is in the ContrlMin field, and the font size is in the contrlMax field
  415.  
  416. ; case out on the font
  417.     MOVE.W        contrlValue(A2),D0
  418.     BMI            useWindowsFont
  419.     
  420. ; see if the new font is the System font or something else
  421.     TST.W            D0
  422.     BEQ            useSystemFont
  423.  
  424. useCustomFont
  425. ; set the font, style, and size for a font other than the System or window's font
  426.     MOVE.W        D0,txFont(A4)                    ; set the font
  427.     MOVE.W        contrlMin(A2),txFace(A4)        ; set the style
  428.     MOVE.W        contrlMax(A2),txSize(A4)        ; set the size
  429.     BRA            figgerFontInfo
  430.  
  431. useSystemFont
  432. ;  set the font, style, and size for the system font (all zeroes will do it)
  433.     CLR.L            txFont(A4)    ; set the font and style
  434.     CLR.W            txSize(A4)    ; set the size
  435.  
  436. useWindowsFont
  437. ; we're using the window's current font, so font number, size, and style already set
  438.  
  439. figgerFontInfo
  440. ; so the font's set up -- let's get some more information
  441.     PEA            fontInfo(A6)
  442.     _GetFontInfo
  443.  
  444. ; from that info, we can figure the vertical positioning for the button's text
  445. ; the equation: vertPos = rectBottom - (fontDescent + ((rectHeight-fontHeight)/2))
  446.     MOVE.W    interiorClipRect+bottom(A6),D0    ; bottom - top gives rectHeight
  447.     MOVE.L    D0,D7                                        ; bottom will be used again
  448.     SUB.W        interiorClipRect+top(A6),D0            
  449.     SUB.W        fontInfo+ascent(A6),D0                ; then subtract fontHeight         
  450.     SUB.W        fontInfo+descent(A6),D0        
  451.     ASR.W        #1,D0                                        ; divide what's left by 2
  452.     ADD.W        fontInfo+descent(A6),D0                ; add it to the descent
  453.     SUB.W        D0,D7                                        ; then subtract it from bottom
  454.     
  455. ; determine whether we'll be drawing the control's title or a STR resource
  456. ; if the control hilites via a content change and is hilited and there's a handle to
  457. ;    the STR resource, we draw the STR resource
  458. ; content change ?
  459.     BTST        #chngBit,D4
  460.     BEQ        useTitle        ; no content change, so use control's title
  461. ; control hilites via a content change
  462. ; is it hilited ?
  463.     MOVE.B    contrlHilite(A2),D0
  464.     BEQ        useTitle        ; 0=active, not hilited, so use control's title        
  465.     ADDQ.B    #1,D0
  466.     BEQ        useTitle        ; 255=inactive, not hilited, so use control's title
  467.  
  468. ; control hiltes via a content change, and it's hilited
  469. ; do we have a handle to the content change string ?
  470.     MOVE.L    firstRsrcHndl(A3),D5
  471.     BEQ        useTitle        ; no, so use control's title
  472.  
  473. useSTR
  474. ; okay, we'll be using a content change STR resource, and we have a non-NIL handle
  475. ; lock the resource, put a pointer to it into D5, and set a flag
  476.     MOVEA.L    D5,A0                        ; handle into A0
  477.     _HLock                                ; lock the STR resource
  478.     MOVEA.L    D5,A0        
  479.     MOVE.L    (A0),D5                    ; set a pointer to it
  480.     MOVE.W    #1,usingCCRsrc(A6)    ; set a flag
  481.     BRA        setStrWidth
  482.  
  483. useTitle
  484. ; using the control's title
  485. ; put a pointer to the string into D5, and clear a flag
  486.     LEA        contrlTitle(A2),A0        
  487.     MOVE.L    A0,D5                        ; set a pointer
  488.     CLR.W        usingCCRsrc(A6)        ; clear a flag
  489.  
  490. setStrWidth
  491. ; now, the horizontal positioning: start by getting the button's string's width
  492.     SUBQ.L        #2,SP                ; room for function result
  493.     MOVE.L        D5,-(SP)            ; the string 
  494.     _StringWidth
  495.         
  496. ; now, use that width to get the horizontal positioning
  497. ; the equation: horzPos = rectLeft +  ( (rectWidth-stringWidth) / 2)
  498.     MOVE.W    interiorClipRect+right(A6),D0        ; get rect width  ( right - left )
  499.     SUB.W        interiorClipRect+left(A6),D0
  500.     SUB.W        (SP)+,D0                                    ; subtract string width
  501.     ASR.W        #1,D0                                        ; divide what's left by two
  502.     ADD.W        interiorClipRect+left(A6),D0        ; and add in the left side of rect
  503.         
  504. ; now we have the horizontal and vertical starting position for string drawing
  505. ; let's move there ...
  506.     MOVE.W        D0,-(SP)        ; the horizontal starting position    
  507.     MOVE.W        D7,-(SP)        ; the vertical starting position
  508.     _MoveTo
  509.  
  510. ; paint a button's interior's background, according to the button's hilite state
  511. ;    and whether we're drawing a content change
  512.  
  513. ; test for content change imminent
  514.     TST.W        usingCCRsrc(A6)    ; remember, we just set or cleared this flag above
  515.     BNE        cCImminent1        ; flag set, content change imminent
  516.  
  517. ; test the hilite state
  518. bkgHSTest1
  519.     MOVE.B    contrlHilite(A2),D7    
  520.     BEQ        hSActive1            ; 0 indicates an active button
  521.  
  522. bkgHSTest2
  523.     ADDQ.B    #1,D7                ; 255 indicates an inactive button
  524.     BNE        hSHilit1            ; 1-253 indicates a highlighted button
  525.  
  526. hSInactive1
  527. ; the button is inactive, so paint interior background white
  528.  
  529. cCImminent1 
  530. ; a content change is imminent, so paint interior background white
  531.  
  532. hSActive1
  533. ; the button is active, so paint interior background white
  534.     MOVEA.L        (A5),A0
  535.     PEA            white(A0)
  536.     _PenPat
  537.  
  538. hSHilit1 
  539. ; the button is highlighted, so paint interior background black
  540.  
  541. paintInteriorBkg
  542. ; paint the button's interior background
  543.     PEA        interiorClipRect(A6)
  544.     _PaintRect
  545.  
  546. ; draw the button's interior's text, according to the button's hilite state
  547. ; and whether we're drawing a content change
  548.  
  549. ; clear a flag that, if set, signals an inactive button
  550.     CLR.B        D6
  551.  
  552. ; test for content change imminent
  553.     TST.W        usingCCRsrc(A6)
  554.     BNE        cCImminent2    ; flag set, content change imminent
  555.  
  556. ; test the hilite state
  557. txtIntHSTest1
  558.     MOVE.B    contrlHilite(A2),D7    
  559.     BEQ        txtHSActive2    ; 0 indicates an active button
  560.  
  561. txtIntHSTest2
  562.     ADDQ.B    #1,D7                ; 255 indicates an inactive button
  563.     BNE        txtHSHilit2        ; 1-253 indicates a highlighted button
  564.  
  565. txtHSInactive2
  566. ; the button is inactive, so we'll draw the text in  black, then gray it out
  567.     ADDQ.B    #1,D6            ; set the inactive flag
  568.     BRA        drawText        ; and jump to draw
  569.  
  570. txtHSHilit2
  571. ; the button is highlighted, so we'll draw the text in white
  572.     MOVE.W        #srcBic,txMode(A4)    ; so the black bits show as white
  573.  
  574. cCImminent2
  575. ; a content change is imminent, so we'll draw the text in black
  576.  
  577. txtHSActive2
  578. ; the button is active, so we'll draw the text in black
  579.  
  580. drawText
  581. ; draw the button's string
  582.     MOVE.L        D5,-(SP)        ; pointer to the string to draw
  583.     _DrawString
  584.  
  585. ; if we used a STR resource, unlock it
  586.     TST.W        usingCCRsrc(A6)            ; are we using ?
  587.     BNE        grayTest                        ; no, so jump ahead
  588.     MOVE.L    firstRsrcHndl(A3),A0        ; yes, so get the handle
  589.     _HUnlock                                    ; and unlock it
  590.  
  591. grayTest
  592. ; see if we've got an inactive button, in which case we gray the text out
  593.     TST.B        D6    
  594.     BEQ        txtGetNorm        ; not inactive, so no graying out
  595.  
  596. ; yup, we're inactive, so let's get grayed out
  597. ; set the pen pattern to gray 
  598.     MOVEA.L        (A5),A0
  599.     PEA            gray(A0)                
  600.     _PenPat                    
  601.     
  602. ; and set pattern transfer mode to ANDing with the inverse of the pattern
  603.     MOVE    #PatBic,-(SP)            
  604.     _PenMode                        
  605.         
  606. ; now paint the clip rectangle gray
  607.     PEA        interiorClipRect(A6)             
  608.     _PaintRect                        
  609.  
  610. txtGetNorm
  611. ; get things back to normal, in case they were changed
  612. ; normalize the text transfer mode
  613.     MOVE.W        #srcOr,txMode(A4)    
  614.  
  615. ;restore the window's prior font settings
  616.     MOVE.L        curFontAndFace(A6),txFont(A4)
  617.     MOVE.W        curSize(A6),txSize(A4)
  618.  
  619. textDrawn
  620. ; text button interior's all drawn
  621.     RTS
  622.  
  623.  
  624. *------------------------------------ doPictInterior -------------------------------*
  625.  
  626. ; draw a PICTure interior for the button
  627.  
  628. doPictInterior
  629. ; we'll draw in the picture's bounding rectangle
  630. ; we'll try to center this rectangle horizontally and vertically 
  631. ;    in the control's clipping rectangle
  632. ; if the control's too small, the icon lines up against 
  633. ;    the top and or left sides of the control's clipping rectangle
  634.  
  635. ; move clipping rectangle's top and left coords into place
  636.     MOVE.L    interiorClipRect+top(A6),pictRect+top(A6)
  637.     
  638. ; get the clipping rect's width into D6
  639.     MOVE.W    interiorClipRect+right(A6),D6        
  640.     SUB.W        interiorClipRect+left(A6),D6
  641.     
  642. ; get a pointer and handle to the picture
  643. ; if the control hilites via a content change and is hilited, we draw the secondary
  644. ;    PICT  resource
  645. ; does the control hilite via a content change ?
  646.     BTST        #chngBit,D4
  647.     BEQ        usePictOne        ; doesn't hilite via a content change
  648.  
  649. ; is the control hilited ?
  650.     MOVE.B    contrlHilite(A2),D1
  651.     BEQ        usePictOne        ; 0=active, not hilited
  652.     ADDQ.B    #1,D1
  653.     BEQ        usePictOne        ; 255=inactive, not hilited
  654.  
  655. usePictTwo
  656. ; we'll be using the secondary PICT resource
  657. ; get a handle and set a flag
  658.     MOVE.L    secondRsrcHndl(A3),D5    ; the handle
  659.     BEQ        usePictOne                    ; in case of a NIL handle
  660.     MOVE.W    #1,usingCCRsrc(A6)        ; the flag
  661.     BRA        getPictPointer
  662.  
  663. usePictOne
  664. ; we'll be using the primary PICT resource
  665. ; get a handle and set a flag
  666.     MOVE.L    firstRsrcHndl(A3),D5        ; the handle
  667.     BEQ        pictDrawn                    ; in case of a NIL handle
  668.     CLR.W        usingCCRsrc(A6)            ; the flag
  669.  
  670. getPictPointer
  671. ; lock the PICT, and get a pointer to it
  672.     MOVEA.L    D5,A0
  673.     _HLock                            ; lock the PICT
  674.     MOVEA.L    D5,A4
  675.     MOVEA.L    (A4),A4                ; get a pointer
  676.  
  677. figPicWidth
  678. ; figure the picture's width 
  679.     MOVE.W    picFrame+right(A4),D1
  680.     SUB.W        picFrame+left(A4),D1
  681.  
  682. ; now subtract the picture's width from the clip width
  683.     SUB.W        D1,D6
  684.     
  685. ; if 2 or more, divide by 2 and use as horizontal offset
  686. ; if it's < 2,  no horizontal offset
  687.     CMPI.W    #2,D6
  688.     BLT.S        doPictRight
  689.     
  690. ; divide and add the offset in
  691.     ASR.W        #1,D6                        ; divide by two
  692.     ADD.W        D6,pictRect+left(A6)
  693.     
  694. ; now do the right coord of rectangle
  695. doPictRight
  696.     MOVE.W    pictRect+left(A6),pictRect+right(A6)
  697.     ADD.W        D1,pictRect+right(A6)
  698.  
  699. ; get the clipping rect's height
  700.     MOVE.W    interiorClipRect+bottom(A6),D0    ; get clip height into D0
  701.     SUB.W        interiorClipRect+top(A6),D0
  702.     
  703. ; figure the picture's height
  704.     MOVE.W    picFrame+bottom(A4),D1
  705.     SUB.W        picFrame+top(A4),D1
  706.  
  707. ; now subtract the picture's height from the clip height
  708.     SUB.W        D1,D0
  709.  
  710. ; if 2 or more, divide by 2 and use as vertical offset
  711. ; if it's < 2,  no vertical offset
  712.     CMPI.W    #2,D0
  713.     BLT.S        doPictBottom
  714.  
  715. ; divide and add the offset in
  716.     ASR.W        #1,D0                        ; divide by two
  717.     ADD.W        D0,pictRect+top(A6)        
  718.     
  719. ; now do the bottom coord of rectangle
  720. doPictBottom
  721.     MOVE.W    pictRect+top(A6),pictRect+bottom(A6)
  722.     ADD.W        D1,pictRect+bottom(A6)
  723.  
  724. ; clear the background
  725.     PEA        interiorClipRect(A6)
  726.     _EraseRect
  727.  
  728. ; okay, let's draw  the picture (remember, it gets clipped to the button's interior )
  729.     MOVE.L        D5,-(SP)            ; the picture's handle
  730.     PEA            pictRect(A6)    ; the destination rectangle
  731.     _DrawPicture    
  732.  
  733. ; unlock the PICT
  734.     MOVEA.L    D5,A0                    ; handle's still here
  735.     _HUnlock                            
  736.  
  737. ; now, adjust the picture for buttons that are hilited inverts or inactive
  738.     BSR        interiorAdjust
  739.  
  740. pictDrawn
  741. ; pict button interior's all drawn
  742.     RTS
  743.  
  744.  
  745. *---------------------------------- interiorAdjust----------------------------------*
  746.  
  747. ; adjust a button's interior for buttons that are hilited inverts or inactive
  748.  
  749. interiorAdjust
  750.  
  751. ; test the hilite state
  752. hiliteTest1
  753.     MOVE.B    contrlHilite(A2),D0    
  754.     BEQ        intAdjDone        ; 0 indicates a non-hilited active button
  755.  
  756. hiliteTest2
  757.     ADDQ.B    #1,D0                ; 255 indicates an inactive button
  758.     BNE        itsHilited        ; 1-253 indicates a highlighted button
  759.  
  760. itsInactive
  761. ; the button is inactive, so we'll gray it out
  762. ; set the pen pattern to gray
  763.     MOVEA.L        (A5),A0
  764.     PEA            gray(A0)                
  765.     _PenPat                    
  766.     
  767. ; and set pattern transfer mode to ANDing with the inverse of the pattern
  768.     MOVE    #PatBic,-(SP)            
  769.     _PenMode                        
  770.         
  771. ; now paint the clip rectangle gray
  772.     PEA        interiorClipRect(A6)             
  773.     _PaintRect                        
  774.  
  775. ;  leave
  776.     BRA    intAdjDone
  777.  
  778. itsHilited
  779. ; the button is highlighted
  780. ; test for being an invert
  781.     TST.W        usingCCRsrc(A6)
  782.     BNE        intAdjDone            ; a content changer, so we done
  783.  
  784. ; the button's a hilited invert, so invert it
  785.     PEA        interiorClipRect(A6)             
  786.     _InverRect                        
  787.  
  788. intAdjDone
  789. ; all done with the adjustment
  790.     RTS
  791.  
  792.  
  793. *---------------------------------- doIconInterior ---------------------------------*
  794.  
  795. ; draw an ICONic interior for the button
  796.  
  797. doIconInterior
  798.  
  799. ; we'll draw in an icon-sized rectangle 
  800. ; we'll try to center this rectangle horizontally and vertically 
  801. ;    in the control's clipping rectangle
  802. ; if the control's too small, the icon lines up against 
  803. ;    the top and or left sides of the control's clipping rectangle
  804.  
  805. ; move clipping rectangle's top and left coords into place
  806.     MOVE.L    interiorClipRect+top(A6),iconRect+top(A6)
  807.     
  808. ; get the clipping rect's width into D0
  809.     MOVE.W    interiorClipRect+right(A6),D0        
  810.     SUB.W        interiorClipRect+left(A6),D0
  811.     
  812. ; now subtract the icon width
  813.     SUBI.W    #iconSize,D0
  814.     
  815. ; if 2 or more, divide by 2 and use as horizontal offset
  816. ; if it's < 2,  no horizontal offset
  817.     CMPI.W    #2,D0
  818.     BLT.S        doIconRight
  819.  
  820. ; divide and add the offset in
  821.     ASR.W        #1,D0            ; divide by two
  822.     ADD.W        D0,iconRect+left(A6)
  823.     
  824. ; now do the right coord of rectangle
  825. doIconRight
  826.     MOVE.W    iconRect+left(A6),iconRect+right(A6)
  827.     ADD.W        #iconSize,iconRect+right(A6)
  828.     
  829. ; get the clipping rect's height
  830.     MOVE.W    interiorClipRect+bottom(A6),D0    ; get clip height into D0
  831.     SUB.W        interiorClipRect+top(A6),D0
  832.     
  833. ; now subtract the icon height from the clip height
  834.     SUBI.W        #iconSize,D0
  835.     
  836. ; if 2 or more, divide by 2 and use as vertical offset
  837. ; if it's < 2,  no vertical offset
  838.     CMPI.W    #2,D0
  839.     BLT.S        doIconBottom
  840.  
  841. ; divide and add the offset in
  842.     ASR.W        #1,D0                        ; divide by two
  843.     ADD.W        D0,iconRect+top(A6)
  844.     
  845. ; now do the bottom coord of rectangle
  846. doIconBottom
  847.     MOVE.W    iconRect+top(A6),iconRect+bottom(A6)
  848.     ADD.W        #iconSize,iconRect+bottom(A6)
  849.  
  850. ; get a handle to the icon
  851. ; if the control hilites via a content change and is hilited, we draw the secondary
  852. ;    ICON  resource
  853. ; content change ?
  854.     BTST        #chngBit,D4
  855.     BEQ        useIconOne
  856. ; hilited ?
  857.     MOVE.B    contrlHilite(A2),D1
  858.     BEQ        useIconOne
  859.     ADDQ.B    #1,D1
  860.     BEQ        useIconOne
  861.  
  862. useIconTwo
  863. ; we'll be using the secondary ICON resource
  864. ; get a handle and set a flag
  865.     MOVE.L    secondRsrcHndl(A3),D5    ; the handle
  866.     BEQ        useIconOne                    ; in case of a NIL handle
  867.     MOVE.W    #1,usingCCRsrc(A6)        ; the flag
  868.     BRA        clearBack                    ; and jump ahead
  869.  
  870. useIconOne
  871. ; we'll be using the primary ICON resource
  872. ; get a handle and set a flag
  873.     MOVE.L    firstRsrcHndl(A3),D5        ; the handle
  874.     BEQ        iconDrawn                    ; in case of a NIL handle
  875.     CLR.W        usingCCRsrc(A6)            ; the flag
  876.  
  877. clearBack
  878. ; clear the background
  879.     PEA        interiorClipRect(A6)
  880.     _EraseRect
  881.  
  882. ; okay, let's draw  the icon  (remember, it gets clipped to the button's interior )
  883.     PEA            iconRect(A6)    ; the destination rectangle
  884.     MOVE.L        D5,-(SP)            ; the icon's handle
  885.     _PlotIcon
  886.  
  887. ; now, adjust the icon for buttons that are hilited inverts or inactive
  888.     BSR        interiorAdjust
  889.  
  890. iconDrawn
  891. ; icon button interior's all drawn
  892.     RTS
  893.         
  894.  
  895. *----------------------------------------- doTestCntl -----------------------------    *
  896.  
  897. ;    the application wants CDEF to test a point to see if it's in an active control
  898.  
  899. doTestCntl            
  900.  
  901. ; first, see if the control's even active, or if it's in one of the two inactive modes
  902.     MOVE.B        contrlHilite(A2),D7     ;inactive control ?
  903.     CMPI.B        #inact254,D7                
  904.     BEQ            setReturn2                ;yes, so return appropriate code        
  905.     CMPI.B        #inact255,D7
  906.     BEQ            setReturn3                ;yes, so return appropriate code
  907.             
  908. ; the control has been found to be active
  909. ; now find out if the supplied point is in the control's rectangle
  910.     SUBQ.L        #2,SP                    ; room for the function result
  911.     MOVE.L        D3,-(SP)                ; param holds the mouse coords
  912.     PEA            contrlRect(A2)        ; pointer to the control's rectangle
  913.     _PtInRect
  914.     TST.B            (SP)+                    ; scan result while chucking
  915.     BEQ            setReturn3            ; if point isn't in the control ...
  916.     
  917. ; okay, the control's active, and the mouse point's in it
  918. ; the control has no separate parts,  so we return the whole control's part number
  919. setReturn1    
  920.     MOVE.L        #wholePartNumber,theResult(A6)
  921.     RTS
  922.  
  923. ; and here are the return codes for the other possibilities
  924. setReturn2    
  925.     MOVE.L         #254,theResult(A6)    ;inactive type 254
  926.     RTS
  927.  
  928. setReturn3    
  929.     MOVE.L        #0,theResult(A6)        ;inactive type 255 
  930.     RTS                                        ;or not in  control
  931.  
  932.  
  933. *------------------------------------- doCalcCCntl --------------------------------    *
  934.  
  935. ;    calculate the control's region
  936.  
  937.  
  938. doCalcCCntl
  939.     MOVE.L        D3,-(SP)            ; param holds the waiting handle
  940.     PEA            contrlRect(A2)    ; use the control's rectangle    
  941.     _RectRgn                            
  942.     RTS
  943.  
  944.  
  945. *------------------------------------- doInitCntl ---------------------------------    *
  946.  
  947. ; do any special initialization of the control
  948.  
  949. ; in this case, set up a control data block
  950. ; then load in any necessary resources, and store handles in the control data block
  951.  
  952. doInitCntl
  953.  
  954. ; try to get a control data block
  955.     MOVE.L    #cntlDataBlokSize,D0
  956.     _NewHandle,CLEAR
  957.  
  958. ; store the result
  959.     MOVE.L    A0,contrlData(A2)
  960.     BEQ        initDone        ; if we got no block, leave
  961.  
  962. lockDataBlock
  963.     MOVEA.L    A0,A3            ; save a copy of the block's handle
  964.     _Hlock                    ; lock the block down
  965.     MOVEA.L    (A3),A3        ; get a pointer to the locked block
  966.  
  967. initTextTest
  968. ; is this is a text control ?
  969.     BTST        #textBit,D4        ; the test
  970.     BEQ        initPictTest    ; no, so jump on
  971.  
  972. ;got a text control - does it indicate hiliting via a content change ?
  973.     BTST        #chngBit,D4        ; the test
  974.     BEQ        initPictTest    ; no, so jump on
  975.  
  976. ; got a text control with content change hiliting, so load in the string resource and lock it
  977.     SUBQ.L    #4,SP                                ; room for a handle
  978.     MOVE.L    #'STR ',-(SP)                    ; the resource type
  979.     MOVE.W        contrlRFcon(A2),-(SP)    ; the resource id
  980.     _GetResource                                ; try to grab that resource
  981.     MOVE.L    (SP)+,firstRsrcHndl(A3)        ; store its handle (possibly NIL) 
  982.     BRA        initDone
  983.  
  984. initPictTest
  985. ; see if this is a PICT control
  986.     BTST        #pictBit,D4        ; the test
  987.     BEQ        initIconTest    ; no, so jump on
  988.  
  989. ; got a pict control, so load in the main PICT
  990.     SUBQ.L    #4,SP                                ; room for a handle
  991.     MOVE.L    #'PICT',-(SP)                    ; the resource type
  992.     MOVE.W        contrlRFcon+2(A2),-(SP)    ; the resource id
  993.     _GetResource                                ; try to grab that resource
  994.     MOVE.L    (SP)+,firstRsrcHndl(A3)        ; store its handle (possibly NIL) 
  995.  
  996. isPictCC
  997. ; does it indicate hiliting via a content change ?
  998.     BTST        #chngBit,D4        ; the test
  999.     BEQ        initDone            ; no, so done
  1000.  
  1001. ; got a pict control with content change, so load in the secondary PICT
  1002.     SUBQ.L    #4,SP                                ; room for a handle
  1003.     MOVE.L    #'PICT',-(SP)                    ; the resource type
  1004.     MOVE.W        contrlRFcon(A2),-(SP)    ; the resource id
  1005.     _GetResource                                ; try to grab that resource
  1006.     MOVE.L    (SP)+,secondRsrcHndl(A3)    ; store its handle (possibly NIL) 
  1007.     BRA        initDone                            ; done
  1008.  
  1009. initIconTest
  1010. ; no test needed; we have an icon control, so load in the main ICON
  1011.     SUBQ.L    #4,SP                                ; room for a handle
  1012.     MOVE.L    #'ICON',-(SP)                    ; the resource type
  1013.     MOVE.W        contrlRFcon+2(A2),-(SP)    ; the resource id
  1014.     _GetResource                                ; try to grab that resource
  1015.     MOVE.L    (SP)+,firstRsrcHndl(A3)        ; store its handle (possibly NIL) 
  1016.  
  1017. isIconCC
  1018. ; does it indicate hiliting via a content change ?
  1019.     BTST        #chngBit,D4        ; the test
  1020.     BEQ        initDone            ; no, so done
  1021.  
  1022. ; got an icon control with content change, so load in the secondary ICON
  1023.     SUBQ.L    #4,SP                                ; room for a handle
  1024.     MOVE.L    #'ICON',-(SP)                    ; the resource type
  1025.     MOVE.W        contrlRFcon(A2),-(SP)    ; the resource id
  1026.     _GetResource                                ; try to grab that resource
  1027.     MOVE.L    (SP)+,secondRsrcHndl(A3)    ; store its handle (possibly NIL) 
  1028.  
  1029. initDone
  1030. ; that's it for initialization
  1031.     RTS
  1032.  
  1033.  
  1034. *------------------------------------- doDispCntl ---------------------------------    *
  1035.  
  1036. ; do any special disposal operations for the control
  1037.  
  1038. ; in this case, release resources whose handles are stored in the control's 
  1039. ;    data block, then release that block
  1040.  
  1041. doDispCntl        
  1042. ; see if we ever got a control data block
  1043.     TST.L        contrlData(A2)
  1044.     BEQ        dispDone            ; no block, so leave
  1045.  
  1046. checkFirst
  1047. ; see if there's a handle in the first slot
  1048.     TST.L        firstRsrcHndl(A3)                ; got a real handle ?
  1049.     BEQ        checkSecond                        ; no, it's NIL, so jump ahead
  1050.     MOVE.L        firstRsrcHndl(A3),-(SP)    ; handle okay, so let go of that resource
  1051.     _ReleaseResource
  1052.  
  1053. checkSecond
  1054. ; see if there's a handle in the second slot
  1055.     TST.L        secondRsrcHndl(A3)                ; got a real handle ?
  1056.     BEQ        dropDataBlock                        ; no, it's NIL, so jump ahead
  1057.     MOVE.L        secondRsrcHndl(A3),-(SP)    ; handle okay, so let go of that resource
  1058.     _ReleaseResource
  1059.  
  1060. dropDataBlock
  1061. ; now get rid of the control's data block
  1062.     MOVEA.L    contrlData(A2),A0
  1063.     _DisposHandle
  1064.  
  1065. dispDone        RTS
  1066.  
  1067. *------------------------------------- doPosCntl ----------------------------------    *
  1068.  
  1069. ;    the position routine
  1070. ;    in this case, do nothing
  1071.  
  1072. doPosCntl            RTS
  1073.  
  1074.  
  1075. *------------------------------------ doThumbCntl ---------------------------------    *
  1076.  
  1077. ;    the thumb routine
  1078. ;    in this case, do nothing
  1079.  
  1080. doThumbCntl        RTS
  1081.  
  1082.  
  1083. *------------------------------------ doDragCntl ----------------------------------    *
  1084.  
  1085. ;    the drag routine
  1086. ;    in this case, do nothing
  1087.  
  1088. doDragCntl            RTS
  1089.  
  1090.  
  1091. *------------------------------------ doAutoTrack ---------------------------------    *
  1092.  
  1093. ;    the track routine
  1094. ;    in this case, do nothing
  1095.  
  1096. doAutoTrack            RTS