MenuHints.a

These are notes on how to behave like the 7.0 MDEF.
Note that this applies only to color machines.
 
There are 3 things you will want to do:
1) Draw disabled items in Òtrue grayÓ
2) Draw lines (dashes) in Òtrue grayÓ
3) Support Balloon Help properly.
 
*************************************************************************************
DEFINITION: True Gray - the "average" of the foreground and background color.
                Black fgnd and White bkgnd yields a nice gray.
                Red fgnd and White bkgnd yields a nice pink.
 
                Q: How do I get this average correctly?
                A: There is a new trap _GetGray which does this for you!
 
                In the MPW interface file "Palettes.[acp]" is the prototype:
    FUNCTION GetGray(device: GDHandle;bkgnd: RGBColor;VAR fgnd: RGBColor): BOOLEAN;
 
                where:  (note that menus never span monitors)
                            device - is the device on which you are drawing
                            bkgnd  - is the RGB color of the background
                            fgnd   - is the RGB color of your ENABLED text
 
                returns:    TRUE if there was an available color between the ones given
                                  and fgnd is replace with that "gray" RGB value.
 
                            FALSE if the was no RGB color between the two given and
                                  you should bitclear the text the old way.
 
*************************************************************************************
#1 - Drawing disabled items in gray
 
    Call GetGray with the current foreground and background colors for the
    current item derived from the 'mctb' if any.  If it returns false, use
    the B&W algorithm.  Otherwise, set the foreground color and draw the item.
    Remember to use the correct entries in the 'mctb' for each part of the item.
 
*************************************************************************************
#2 - Drawing gray lines for the dash item
 
;---------------------------------------
;   Utility -- DrawDash
;---------------------------------------
; handle the case of a dash item by drawing a line
DrawDash
 
            TST.B   onColorMachine(A6)  ; Are we on a color machine?
            BEQ.S   @ditherGrayLine     ; If not, draw dithered line
 
;   FUNCTION GetGray(device: GDHandle; backGround: RGBColor; VAR foreGround: RGBColor): BOOLEAN;
 
            sub     #12,sp              ; put (back,fore) colors on stack
            pea     (sp)
            _GetBackColor
            pea     6(sp)
            _GetForeColor
            subq    #6,sp               ; Make room for result & gdhandle
            move.l  MMenuRect(a6),-(sp) ; Global menu rect
            _GetMaxDevice               ; leave main device on stack
            lea     6(sp),a0            ; Get address of back color
            move.l  a0,-(sp)            ; Push back
            pea     6(a0)               ; Push fore
            _GetGray                    ; Do we have a gray?
            move.b  (sp)+,d0
            bne.s   @rgbGrayLine        ; NE (TRUE) means we have the gray
            add     #12,sp
            bra.s   @ditherGrayLine
@rgbGrayLine
            addq    #6,sp               ; Get rid of back color
            pea     (sp)
            _RGBForeColor
            addq    #6,sp               ; Get rid of fore color
            bra     @b
 
@ditherGrayLine
            MOVE.L  (A5),A0             ; get QuickDraw globals
            PEA     Gray(A0)            ; set pattern to gray
            _PenPat
@b
            MOVE.W  D3,-(SP)            ; save y position
            MOVE.W  D5,-(SP)            ; push x position
            MOVE.W  MFHeight(A6),D0 ; center the dash
            LSR.W   #1,D0               ; by backing up to top of cell
            SUB.W   MAscent(A6),D0      ; and going halfway down
            ADD.W   D0,D3               ; add to current position
            MOVE.W  D3,-(SP)            ; push new y position
            _MoveTo
 
            MOVE.W  D6,-(SP)            ; push  right edge
            MOVE    D3,-(SP)            ; push  y
            _LineTo                     ; draw  the line
            MOVE.W  (SP)+,D3            ; restore baseline
 
            _PenNormal                  ; This wonÕt create a new pixpat
@oldMac2
            BRA     DoneDrawItem        ; dive  back into mainstream
 
*************************************************************************************
#3 - Balloon Help support
 
;; Inside the CHOOSE message *after* inverting the chosen item...
 
            SUBQ    #2,SP                   ; room for Boolean
            _HMGetBalloons                  ; what is the state of What Is? mode? (This is a FAST call)
            TST.B   (SP)+
            BEQ.S   @FlashInProgress
 
            SUBQ    #2,SP                   ; check status of button
            _StillDown
            TST.B   (SP)+                   ; if true then button is still down
            BEQ.S   @FlashInProgress        ;   else the item is flashing so donÕt flash the balloon
 
            BSR.S   ShowMenuBalloon         ; show the balloon for the chosen item
 
@FlashInProgress
 
;; Other stuff to finish off CHOOSE message
            rts                         ; return to dispatcher
 
;---------------------------------------
;   Utility -- RemoveAnyBalloon
;---------------------------------------
;
; Insure no balloon is currently displayed.
; Remove balloons should be called before scrolling or when changing from one item to another.
; and when the mouse is over a dash.
;
; Note: The standard MBDF removes any balloon before saving bits for or
; restoring bits from a menu (or hierarchical menu) since menu balloons save bits too.
;
RemoveAnyBalloon
            subq    #2,sp                   ; room for Boolean
            _HMGetBalloons                  ; Show Balloons?
            tst.b   (sp)                    ; EQ means off (leave result on stack for now)
            beq.s   @helpIsOff
            _HMRemoveBalloon                ; Remove any balloons before scrolling
@helpIsOff
            addq    #2,sp                   ; room for Boolean
            rts
 
 
;---------------------------------------
;   Utility -- ShowMenuBalloon
;---------------------------------------
;
; Show the balloon for this item.
;
ShowMenuBalloon
            MOVE.L  D4,-(SP)                ; Save only the needed registers!
 
            MOVE.L  (A3),A0                 ; get menuPtr
            MOVE    D4,D0                   ; get item number
            BSR     GETITEMRECORD           ; look it up
            BSR     IsDash                  ; Is it a dash? (other attrs?)
            BNE.S   @needBalloon            ; no, just return the item num
            MOVEQ   #-1,D4                  ; else make item num -1 for dash
@needBalloon
 
;   FUNCTION  HMShowMenuBalloon(itemNum,itemMenuID: INTEGER;
;                               itemFlags,itemReserved: LONGINT;
;                               tip: Point; alternateRect: RectPtr; tipProc: Ptr;
;                               theProc,variant: INTEGER): OSErr;
 
            SUBQ    #2,SP                   ; room for result
            MOVE.W  D4,-(SP)                ; item number
 
            MOVE.L  (A3), A0                ; get menu ptr
            MOVE.W  menuID(A0),-(SP)        ; push menuID
            MOVE.L  MENUENABLE(A0),D0       ; get menu flags in D0
            MOVE.L  D0,-(SP)                ; push menu flags
 
            MOVE.L  #0,-(SP)                ; push help string handle in itemReserved
 
            MOVE.L  MBSaveLoc,A0            ; get MBSave handle
            MOVE.L  (A0),A0                 ; deref
            MOVE.W  mbItemRect+bottom(A0),D4
            SUB.W   mbItemRect+top(A0),D4
            LSR.W   #1,D4                   ; find half way down from top of menu
            MOVE.L  mbItemRect+botRight(A0),D0  ; use the right side of the menu rect
            SUBQ.W  #BalloonTipOverlap,D0   ;   tweak the horizontal part
            SWAP    D0
            SUB.W   D4,D0                   ; put the tip in the middle of the right vert
            SWAP    D0
            MOVE.L  D0,-(SP)                ; push the tip
 
            PEA     mbItemRect(A0)          ; push the alternaterect
            CLR.L   -(SP)                   ; NIL tipProc
            CLR.L   -(SP)                   ; theProc & variant = 0
            _HMShowMenuBalloon
            ADDQ    #2,SP                   ; toss result
 
            MOVE.L  (SP)+,D4                ; Restore saved registers.
            RTS