mac-rom/Toolbox/ControlMgr/ButtonCDEF.a

955 lines
34 KiB
Plaintext
Raw Normal View History

;
; File: ButtonCDEF.a
;
; Contains: Standard Button Definition Procedure for the MacIntosh Control Manager
; This file contains the control definition procedures that define
; the standard "button" type controls. These include PushButtons,
; CheckBoxes, and a checkBox variant called RadioButton.
;
; Written by: Andy Hertzfeld August, 1982
;
; Copyright: <09> 1982-1992 by Apple Computer, Inc., all rights reserved.
;
; This file is used in these builds: Mac32 HcMac MacPP BigBang Sys606
;
; Change History (most recent first):
;
; <SM2> 10/22/92 CSS Change short branches to word branches.
; <14> 4/11/91 gbm csd, KSM, BRC#86464: Fix many references to the control
; rectangle which are invalid because the control handle can be
; unlocked.
; <13> 3/4/91 dba dty: get rid of SysVers conditionals
; <12> 12/14/90 VL (ksm) Use PaintRoundRect instead of PaintRect for dithering
; text. Also, changed PenMode to TextMode since grayishTextOr is a
; text mode.
; <11> 8/23/90 SAM Removed the MoveHHi from the DrawPBut routine so that MacApp
; will work (it assumes that handles will be ok across calls to
; DrawControl -- idiots!)
; <10> 8/17/90 dvb Change grayish textMode pnMode to txMode
; <9> 8/13/90 VL Fixed test for portVersion to avoid trashing portVersion's
; value.
; <8> 8/2/90 VL Replaced SysVers switch with UseTrueGrayText (for ROM build).
; <7> 8/1/90 VL Make text to be drawn in TrueGray when disabled (in a color
; grafport).
; <6> 6/14/90 DDG NEEDED FOR SIXPACK: Moved the control manager handle with
; _MoveHHi before we lock it down while we are drawing. This
; should prevent out-of memory problems.
; <5> 5/29/90 DDG NEEDED FOR SIXPACK: Added the proper tag to the previous
; comment.
; <4> 5/29/90 DDG NEEDED FOR SIXPACK: Fix a bug where the button title is left
; unlocked for the duration of the drawing call.
; <3> 5/1/90 DDG Removed the temporary conditionals that I added for Sys605.
; <2> 3/2/90 DDG Adding conditionals for Sys605
; <1.4> 11/17/89 dba took out checks for 64K ROMs
; <1.3> 8/22/89 SES removed references to nFiles; updated equates accordingly
; <1.2> 2/9/89 EMT added new messages for 32-bit clean Control Manager.
; <1.1> 11/11/88 CCH Fixed Header.
; <1.0> 11/9/88 CCH adding to EASE.
; <<3C>1.1> 9/23/88 CCH Got rid of inc.sum.d and empty nFiles
; <1.0> 2/12/88 BBM Adding file for the first time into EASE<53>
; <C948> 11/8/87 DAF Updated romres sources from system disk sources
; SMAB156> 3/30/87 DAF Tested ROM version before using teSysJust.
; <C818> 2/14/87 DAF Converted nuMac PaintRoundRgn to be unified with other Macs<63>
; Erase stopped setting backColor when drawing text.
; <C700> 1/26/87 DAF Universal version of ButtonCDEF.a (version 10)
; <C637> 1/14/87 DAF Changed textMode back to srcOR from srcCopy (sigh...)
; <C560> 12/21/86 DAF Added Mark Davis<69> code to allow reversed checkmarks for intl
; <C424> 11/18/86 DAF converted a BSET/BCLR to an HLock/HUnlock, in CalcPBut
; <C407> 11/16/86 DAF changed textMode (again) to srcCopy, as per Cary<72>s
; recommendation
; <C203> 10/8/86 DAF updated color support on nuMac for RGBColors changed textMode to
; srcOr.
; <C59> 6/30/86 DAF added color support for nuMac (mucho chango)
; <v4> 8/26/85 EHB made variable sized fonts work (ROM85>0 only)
; <v3> 5/20/85 EHB implemented Multi-Line buttons
; <v2> 5/16/85 EHB only return "254" if point in control!
; 3/12/85 JTC changed occurrences of LGlobals to GrafGlobals
; 2/14/85 JTC added res name
; 1/14/85 JTC convert to MDS
; 12/31/83 AJH made text of checkBox/radioButtons grayed out if disabled
; 10/17/83 AJH back to "gray-out" button disabling
; 10/12/83 AJH changed button disabling
; 9/27/83 AJH made variants > 7 not force the system font
; 8/29/83 AJH fixed scrambling bug in CalcPBut
; 6/7/83 AJH fixed scrambling bug, changed check draw for new QuickDraw
; 4/4/83 AJH made it force size 12 for text
; 4/1/83 AJH made it use hardwired gray
; 3/27/83 AJH made it respect initial clip in button drawing
; 3/11/83 AJH fixed up check box drawing
; 12/28/82 AJH Put button definitions in their own file
; 11/16/82 AJH Made branch tables offset based
; 11/14/82 AJH Improved PushButton roundness scaling; removed box in arrowBits
; 10/17/82 AJH Made controlProcs preserve A1
; 10/10/82 AJH Converted for QuickDraw Trap Interface
; 10/5/82 AJH Fixed checkBox flashing, added code saving optimizations
; 10/3/82 AJH Fixed bug in scrollBar positioning -- wasn<73>t ctl relative
; 9/29/82 AJH Added CheckBox control definition procedure
; 8/29/82 AJH Added "255" hiliting,
; 8/25/82 AJH Fixed corner-clobber bug in pushButProc
; 8/22/82 AJH Added clipping, centering to PushButProc
;
; To Do:
;
PRINT PUSH,OFF
LOAD 'StandardEqu.d'
INCLUDE 'ColorEqu.a'
PRINT POP
;----------------------------------------------------------------------------------------------------
CDEF0 PROC EXPORT
; FUNCTION PushButProc( selector: INTEGER; 18
; theControl: ControlHandle; 14
; message: INTEGER; 12
; param: LongInt): LongInt; 8 : 20
;
; PushButProc is the control definition procedure for simple pushButtons, one of the
; standard control types supported by the user interface toolBox.
; And a stack frame definition
CtlHndl EQU 14 ;incoming control handle param <C59/30Jun86> DAF
SavePen EQU -20
Align EQU -21 ;a dead byte for IsColor <C700/26Jan87> DAF
IsColor EQU -22 ;do we have colorQD and toolbox [boolean] <C700/26Jan87> DAF
IndicatorRect EQU -30
AuxCtlHndl EQU -34 ;handle of auxCtl ColorTable <C59/30Jun86> DAF
AuxCtlPtr EQU -38 ;ptr to auxCtl ColorTable <C59/30Jun86> DAF
ContentRGB EQU -44 ;window content color <C59/30Jun86> DAF
SavFgCol EQU -50 ;window port<72>s RGBFgColor <Cxxx/06Oct86> DAF
SavBkCol EQU -56 ;window port<72>s RGBBkColor <Cxxx/06Oct86> DAF
useGrayText EQU -58
FrameSize EQU -58
BRA.S @0 ; skip header
; standard header
DC.W 0 ; flags
DC.L ('CDEF')
DC.W 0
DC.W 11 ; version #
@0
LINK A6,#FrameSize ; set up a stack frame to address parameters <C59/30Jun86> DAF
MOVEM.L D3-D7/A1-A4,-(SP) ; save work registers
;
; buttons only handle messages 0,1,2,10,11 <1.2>
;
CMP.W #calcCtlMsg,12(A6) ; inspect message value <1.2>
BLS.S @MsgOK ; if <2, it<69>s OK <1.2>
CMP.W #calcWholeCtlMsg,12(A6) ; <1.2>
BEQ.S @MsgOK ; 10 is OK too <1.2>
CMP.W #calcThumbCtlMsg,12(A6) ; <1.2>
BNE DoneP1 ; And 11 <1.2>
@MsgOK
;
; save the penState and set it our way
;
PEA SavePen(A6) ; push pointer to savePenState
_GetPenState ; remember current penState
_PenNormal ; set the pen the way we want it
; Determine type of system. We need to know if we have color QuickDraw and a color
; window manager port.
CMP.W #$3FFF,ROM85 ; do we have color QD?
SLS IsColor(A6) ; set boolean depending on color or B&W system
BHI @BWSys ; no, this system has B&W QD <SM2> CSS
; save the current port<72>s colors and textMode <C59/30Jun86> DAF
MOVE.L GrafGlobals(A5),A0 ; get pointer to grafGlobals <C407/16Nov86> DAF
MOVE.L thePort(A0),A0 ; get pointer to thePort <C407/16Nov86> DAF
MOVE.W txMode(A0),-(SP) ; save the current text mode <C407/16Nov86> DAF
MOVE.W #srcOR,-(SP) ; push text mode <C637/16Nov86> DAF
_TextMode ; <C407/16Nov86> DAF
PEA SavFgCol(A6) ; save foreColor
_GetForeColor ;
PEA SavBkCol(A6) ; save backColor too
_GetBackColor ;
;
; get the CtlAuxRec for this guy and lock its colortable <C59/30Jun86> DAF
;
CLR.L -(SP) ; return the handle here
CLR.B -(SP) ; space for boolean func return
MOVE.L CtlHndl(A6),-(SP) ; push the control handle
PEA 6(SP) ; push a pointer to placeholder
_GetAuxCtl ; get its auxRec
ADDQ #2,SP ; don<6F>t need boolean result
MOVE.L (SP)+,A0 ; get auxCtl handle
MOVE.L (A0),A0 ; a pointer to the auxCtlRec
MOVE.L acCTable(A0),A0 ; get colortable<6C>s handle <1.3>
MOVE.L A0,AuxCtlHndl(A6) ; save the handle
_HLock ; lock the handle
MOVE.L (A0),AuxCtlPtr(A6) ; save a pointer
;
; get the WinAuxRec that this control is in and copy its content color to
; the stack frame.
;
CLR.L -(SP) ; make a placeholder for a handle
CLR.B -(SP) ; room for a boolean result
MOVE.L CtlHndl(A6),A0 ; get the controlHandle again
MOVE.L (A0),A0 ; get a pointer
MOVE.L contrlOwner(A0),-(SP) ; push the owning window pointer
PEA 6(SP) ; pointer to the placeholder
_GetAuxWin ; get the window auxRec
ADDQ #2,SP ; bag the boolean
MOVE.L (SP)+,A0 ; get the WinAuxRec handle
MOVE.L (A0),A0 ; handle->ptr
MOVE.L awCTable(A0),A0 ; get the colortable handle <1.3>
MOVE.L (A0),A0 ; handle->ptr
MOVE.W CTSize(A0),D0 ; get the table count
MULU.W #8,D0 ; get a table index
@1
TST.W CTTable+value(A0,D0) ; is it wContentColor (=0)?
BEQ.S @2 ;
SUBQ #8,D0 ; move to previous colorSpec
BGE.S @1 ; and loop back
CLR.L D0 ; if not found, just use the first one
@2
MOVE.L CTTable+rgb(A0,D0),ContentRGB(A6) ; copy the color over
MOVE.W CTTable+rgb+4(A0,D0),ContentRGB+4(A6) ;
@BWSys
;
; fetch the parameters into registers
;
LEA 8(A6),A0 ; get ptr to first parameter
MOVE.L (A0)+,D3 ; get param in D3
MOVE.W (A0)+,D0 ; get message
MOVE.L (A0)+,A3 ; get the control handle
MOVE.W (A0)+,D6 ; get selection index
MOVE.W D6,D7 ; remember raw selection code
AND #7,D6 ; strip high part of selection code
CLR.L (A0) ; clear out function result
MOVE.L (A3),A0 ; get control pointer in A0
;
; case out on the message number
;
msgAdjust EQU calcWholeCtlMsg-calcCtlMsg-1 ; So that 10 becomes 3, 11 becomes 4 <1.2>
CMP.W #calcCtlMsg, D0 ; Does message need adjusting? <1.2>
BLS @LoMsg ; Don<6F>t adjust if not. <1.2>
SUBQ.W #msgAdjust, D0 ; Adjust message for address calculation <1.2>
@LoMsg
ADD D0,D0 ; double for word index
LEA GoPushBut,A1 ; get table address
ADD 0(A1,D0),A1 ; compute dispatch address
JSR (A1) ; dispatch to appropriate routine
;
; clean up color stuff
TST.B IsColor(A6) ; are we on a color system?
BEQ.S @NoColor1 ; if on B&W, then skip
MOVE.L AuxCtlHndl(A6),A0 ; unlock the CDEF
_HUnlock
PEA SavFgCol(A6) ; restore the port colors
_RGBForeColor ;
PEA SavBkCol(A6) ;
_RGBBackColor ;
_TextMode ; restore the textMode <C407/16Nov86> DAF
@noColor1 ; END OF A COLOR-ONLY SECTION
;
; restore original pen state
;
PEA SavePen(A6) ; push savePenState
_SetPenState ; restore original pen state
;
; we<77>re done -- restore registers and return to caller
;
DoneP1
MOVEM.L (SP)+,D3-D7/A1-A4 ; restore work registers
UNLK A6 ; unlink stack frame
TenBytExit MOVE.L (SP)+,A0 ; get return address
ADD #12,SP ; strip parameters
JMP (A0) ; return to caller
;
; PushButProc dispatch table -- entries must be long branches!
;
GoPushBut
DC.W DrawPBut-GoPushBut ; draw is message 0
DC.W HitPBut-GoPushBut ; hit test is message 1
DC.W CalcPBut-GoPushBut ; calc regions is message 2
DC.W CalcWholePBut-GoPushBut ; calc whole regions is message 10 <1.2>
DC.W CalcThumbPBut-GoPushBut ; calc thumb regions is message 11 <1.2>
ButStub RTS
; SetUpColor takes a window part identifier in D0, finds the corresponding
; part in the AuxWinTable (the part code is in the .value field) and returns
; a pointer to its RGB on the stack. If the requested part is not found,
; the first color table element is used (I<>d use frameColor, but that might
; not be there!). Trashes A0/D0.
SetUpColor
MOVE.L D1,-(SP) ; save a register
MOVE.L AuxCtlPtr(A6),A0 ; get the color table pointer
MOVE.W CTSize(A0),D1 ; get the color table size
MULU #8,D1 ; convert to color table index
LegalIndex
CMP.W CTTable+value(A0,D1),D0 ; is this the one?
BEQ.S FoundIt ; if equal, then done
SUB.W #8,D1 ; try the previous one
BGE.S LegalIndex ; loop while index positive
MOVEQ #0,D1 ; OK, use the first one
FoundIt
LEA CTTable+rgb(A0,D1),A0 ; get the address of the color to use
MOVE.L A0,D0 ; we<77>ll need A0 in a second
MOVE.L (SP)+,D1 ; restore the register
MOVE.L (SP)+,A0 ; get the return address
MOVE.L D0,-(SP) ; push the rgb addr on the stack
JMP (A0) ; return to caller
;
; DrawPBut draws the pushButton
;
DrawPBut
TST.B ContrlVis(A0) ; is it visible?
BEQ.S ButStub ; if not, we<77>re done
;
; calculate roundness as function of rectangle size
;
BSR RoundCalc ; compute roundNess factor in D4
TST.B IsColor(A6) ; are we on a color system?
BEQ.S @NoColor2 ; if on B&W, then skip
;
; if pushbutton, paint bk to body color; if checkmark then erase to window content <C59/30Jun86> DAF
;
@9 TST.B D6 ; is it a pushButton?
BEQ.S @4 ;
; set the window content color to the back for the eraseRRect <C59/30Jun86> DAF
PEA ContentRGB(A6) ; push the pointer to content color
BRA.S @5
; set the body color for button <C59/30Jun86> DAF
@4
MOVE.L (A3),A0 ; get control rec pointer
MOVE.B contrlHilite(A0),D0 ; get the hilite byte
SUBQ.B #1,D0 ; make 0->$FF
CMP.B #$FD,D0 ; is the control hilited?
BHS.S @8 ; no, so continue
MOVEQ #cTextColor,D0 ; if it is, paint the button in text color
BRA.S @0
@8 MOVEQ #cBodyColor,D0 ; if its not, then paint body color
@0 BSR.S SetUpColor ; get info on the stack
;
; erase the bounding rectangle (if necessary)
;
@5
_RGBBackColor ; set it
MOVE.L (A3),A0 ; get controlHandle again
@NoColor2 ; END OF A COLOR-ONLY SECTION
LEA ContrlRect(A0),A4 ; get pointer to bounding rect
TST.B D6 ; is it a pushButton?
BEQ.S EraseCBound ; push buttons are always erased
TST.B D3 ; draw all?
BNE.S SkipCErase ; if not, don<6F>t bother to erase
;
EraseCBound
MOVE.L A4,-(SP) ; push rect
MOVE.L D4,-(SP) ; push rounding factor
_EraseRoundRect ; paint it the background color
;
; save the current font and force the system font
;
SkipCErase MOVE.L GrafGlobals(A5),A0 ; get GrafGlobals base
MOVE.L ThePort(A0),A0 ; get current port
MOVE.L txFont(A0),-(SP) ; remember the font,face
MOVE.W txSize(A0),-(SP) ; remember the size
SUBQ #8,D7 ; was code 8 or greater?
BGE.S @gotFont ; if so, use window<6F>s font
CLR.L txFont(A0) ; force system font, normal face
MOVE.W SysFontSize,D0 ; get default size <EHB 26Aug85>
BNZ.S @gotSize ; => it<69>s 0! <EHB 26Aug85>
MOVE.B FMDefaultSize,D0 ; get default size <EHB 26Aug85>
@gotSize
MOVE.W D0,txSize(A0) ; set size of font <EHB 26Aug85>
@gotFont
MOVE.L ClipRgn(A0),-(SP) ; push the current clipRgn handle
; save old clip region and clip to the bounding rectangle sected with oldClip
CLR.L -(SP) ; make space for region handle
_NewRgn ; allocate a region
MOVE.L (SP),A2 ; remember region but leave on stack
_GetClip ; remember the current clipRgn
MOVE.L (A3),A0 ; get control pointer
PEA ContrlRect(A0) ; push pointer to its bounding rect
_ClipRect ; make that the clipping region
MOVE.L A2,-(SP) ; push the old ClipRgn
MOVE.L 4(SP),-(SP) ; the answer goes into current clip
_SectRgn ; intersect new and old
; Save off some registers for mondo button title calculations, then
; set them up for our use
MOVE.L A3,A0 ; copy control handle to A0 for memory calls
_HGetState
MOVE.L D0,-(SP) ; save the state of the control handle for later
;;; _MoveHHi ; move it up, before we lock it down <11> SAM (Removed)
_HLock ; lock it down
MOVEM.L D4/A2-A3,-(SP) ; save registers <EHB 20-May-85>
MOVE.L (A3),A0 ; get pointer to control
LEA contrlTitle(A0),A2 ; get title into A2
LEA contrlRect(A0),A4 ; get rect into A4 <EHB 20-May-85>
MOVEQ #0,D7 ; <EHB 20-May-85>
MOVE.B (A2),D7 ; get string length into D7 <EHB 20-May-85>
BEQ NoTitle ; quick check for nothing <EHB 20-May-85>
; now count the number of lines in the title. Lines are separated by CR<43>s
MOVEQ #0,D4 ; save number of lines in D4 <EHB 20-May-85>
@2
ADDQ #1,D4 ; count next line <EHB 20-May-85>
BSR Pt2Next ; point to next line (index in D7) <EHB 20-May-85>
TST.B D7 ; D7 < 0 if done <EHB 20-May-85>
BPL.S @2 ; => get next line <EHB 20-May-85>
MOVE.B (A2),D7 ; get string length back <EHB 20-May-85>
; now get a font info record on stack, pointer to it in A3
SUBQ #8,SP ; make room for 4 INTEGERS <EHB 20-May-85>
MOVE.L SP,A3 ; save pointer in A3 <EHB 20-May-85>
MOVE.L A3,-(SP) ; push pointer to record <EHB 20-May-85>
_GetFontInfo ; and fill the record <EHB 20-May-85>
; Set up D5 to point to the baseline of the last line
BSR GetHeight ; get height of line into D0 <EHB 20-May-85>
MULU D4,D0 ; #lines times height <EHB 20-May-85>
MOVE.W bottom(A4),D1 ; get bottom of rect <EHB 20-May-85>
MOVE.W D1,D5 ; D5 will be baseline <EHB 20-May-85>
SUB.W top(A4),D1 ; get height of rect <EHB 20-May-85>
SUB.W D0,D1 ; get unused space <EHB 20-May-85>
ASR.W #1,D1 ; and DIV by 2 <EHB 20-May-85>
SUB.W D1,D5 ; move up from bottom <EHB 20-May-85>
SUB.W leading(A3),D5 ; to bottom of descender <EHB 20-May-85>
SUB.W descent(A3),D5 ; to first baseline <EHB 20-May-85>
DoNextLine
; get the width of the current line into D0
BSR Pt2Next ; next line in D7, len in D3 <EHB 20-May-85>
CLR.W -(SP) ; make room for result <EHB 20-May-85>
MOVE.L A2,-(SP) ; push title pointer <EHB 20-May-85>
MOVE.W D7,D0 ; get our offset into string <EHB 20-May-85>
ADDQ.B #2,D0 ; bump past length (or CR) <EHB 20-May-85>
MOVE.W D0,-(SP) ; push true offset into string <EHB 20-May-85>
MOVE.W D3,-(SP) ; push number of bytes <EHB 20-May-85>
_TextWidth ; get the string<6E>s width <EHB 20-May-85>
MOVE.W (SP)+,D0 ; and save result in D0 <EHB 20-May-85>
; if it<69>s a checkbox, don<6F>t center it, just move to right a little
TST.B D6 ; is it a check box?
BEQ.S ElCentro ; => no, go center the string <EHB 20-May-85>
; adjust positioning for push button
tst.w teSysJust ; right to left? <MED 27-Aug-86>
beq.s LeftBox ; no, normal case <MED 27-Aug-86>
RightBox
MOVE.W right(A4),D1 ; get the right edge <MED 27-Aug-86>
SUB.W left(A4),D1 ; get the width <MED 27-Aug-86>
SUB.W D0,D1 ; subtract string<6E>s width <MED 27-Aug-86>
sub.w #18,d1 ; subtract room for box <MED 27-Aug-86>
ADD.W left(A4),D1 ; and add into left <MED 27-Aug-86>
BRA.S DrawBTitle ; back to common code <MED 27-Aug-86>
LeftBox
MOVE.W Left(A4),D1 ; get the left edge
ADD.W #18,D1 ; leave room for check box
BRA.S DrawBTitle ; back to common code
ElCentro
; center the line in the rect
MOVE.W right(A4),D1 ; get the right edge
SUB.W left(A4),D1 ; get the width
SUB.W D0,D1 ; subtract string<6E>s width
ASR.W #1,D1 ; get centering offset
ADD.W left(A4),D1 ; and add into left
DrawBTitle
MOVE.W D1,-(SP) ; push horizontal position
MOVE.W D5,-(SP) ; and vertical position <EHB 20-May-85>
_MoveTo ; move the pen there
; now that registers are free, push colors on stack <C59/30Jun86> DAF
MOVE.L GrafGlobals(A5),A0 ; Save the pen mode
MOVE.L thePort(A0),A0 ;
MOVE.W txMode(A0),-(SP) ; <12>
TST.B IsColor(A6) ; are we on a color system?
BEQ.S @notColor ; no, skip the gray text checking stuff totally
MOVE.W portVersion(A0),D0 ; get portVersion into D0 for comparison
AND.W #$C000,D0 ; are we using a color grafport?
SNE useGrayText(A6) ; yes, set boolean useGrayText to true for future reference
BRA.S @doneCheckingForGrayText
@notColor ;
MOVE.B #0,useGrayText(A6) ; set boolean useGrayText to false
@doneCheckingForGrayText
TST.B IsColor(A6) ; are we on a color system?
BEQ.S @NoColor4 ; if on B&W, then skip
MOVE.L CtlHndl(A6),A0 ; get the control handle (not A3 in this section) <DAF 29Apr86>
MOVE.L (A0),A0 ; get control pointer
MOVE.B ContrlHilite(A0),D0 ; need to handle the case of 254/5 hiliting
BEQ.S @1 ; skip if hiliteValue == 0
CMP.B #$FE,D0 ; Is the button hilited?
BHS.S @Hilited ; skip if hiliteValue > 254 (i.e. disabled)
TST.B D6 ; Is it a check box or radio button?
BNE.S @1 ; yes => Want to set the forecolor to CTextColor in 7.0
MOVE.W #cBodyColor,D0 ; no => use cBodyColor as ForeColor in 6.0
BRA.S @4 ; (because BackColor is cTextColor)
@Hilited ;
TST.B useGrayText(A6) ; can we use GrayText?
BEQ.S @1 ;
MOVE.W #grayishTextOr,-(SP) ; yes => set the pen mode to grayishTextCopy
_TextMode ;
@1
MOVE.W #cTextColor,D0 ; use cTextColor as ForeColor
@4
BSR SetUpColor ; deposit appropriate values on stack
_RGBForeColor
@NoColor4
MOVE.L A2,-(SP) ; point to string <EHB 20-May-85>
MOVE.W D7,D0 ; get our offset into string <EHB 20-May-85>
ADDQ.B #2,D0 ; bump past length (or CR) <EHB 20-May-85>
MOVE.W D0,-(SP) ; push true offset into string <EHB 20-May-85>
MOVE.W D3,-(SP) ; push length in bytes <EHB 20-May-85>
_DrawText ; this is where we draw the line
_TextMode ; <12>
; bump baseline point up to next line, test for end
BSR GetHeight ; get line height into D0 <EHB 20-May-85>
SUB.W D0,D5 ; go up to next base line <EHB 20-May-85>
TST.B D7 ; done yet? <EHB 20-May-85>
BPL DoNextLine ; => nope <EHB 20-May-85>
ADDQ #8,SP ; strip font record <EHB 20-May-85>
NoTitle
MOVEM.L (SP)+,D4/A2-A3 ; and all those registers <EHB 20-May-85>
MOVE.L A3,A0 ; copy control handle to A0 for HSetState
MOVE.L (SP)+,D0 ; get the state off the stack and set it back
_HSetState
; <14>
; WARNING! Setting the state of the control record handle here may leave it unlocked! Several
; references are made below to items in the control record (mostly the control rect).
; Each reference must include reloading the control record pointer from the control
; record handle contained in register a3.
;
; We now return you to your regularly scheduled program.
; <14>
; restore original font, face and size
MOVE.L GrafGlobals(A5),A0 ; get GrafGlobals base
MOVE.L ThePort(A0),A0 ; get current port
MOVE.W (SP)+,txSize(A0) ; restore the size
MOVE.L (SP)+,txFont(A0) ; restore the font,face
;
; set the pen color to FrameColor <C59/30Jun86> DAF
;
TST.B IsColor(A6) ; are we on a color system?
BEQ.S @NoColor5 ; if on B&W, then skip
MOVEQ #cFrameColor,D0 ;
BSR SetUpColor ;
_RGBForeColor ;
@NoColor5 ; END OF A COLOR-ONLY SECTION
TST.B D6 ; is it a checkBox?
BNE PlotCheck ; if so, go draw it
move.l (a3), a0 ; get control pointer <14>
lea contrlRect(a0), a4 ; point to the control rect <14>
MOVE.L A4,-(SP) ; push the rectangle pointer
MOVE.L D4,-(SP) ; push rounding factor
_FrameRoundRect ; frame the button
;
; perform SpecialHilite if necessary
;
TST.B IsColor(A6) ; are we on a color system?
BEQ.S @NoColor6 ; if on B&W, then skip
TST.B useGrayText(A6) ; did we use GrayText?
BNE.S @skipSpecialHilite ; yes => skip SpecialHilite since GrayText represents hilite state already
MOVE.L (A3),A0 ; get control pointer
CMP.B #$FE,ContrlHilite(A0) ; is it the special hilite state?
BHS.S SpecialHilite ; if so, go do it
@skipSpecialHilite
BRA.S @Common6 ; and continue...
@NoColor6
;
; hilite the button if necessary
;
MOVE.L (A3),A0 ; get control pointer
MOVE.B ContrlHilite(A0),D0 ; is it hilited?
BEQ.S DoneDrwBut ; if not, we<77>re done
;
TST.B useGrayText(A6) ; did we use GrayText?
BNE.S @Common6 ; yes, skip SpecialHilite since GrayText represents hilite state already
CMP.B #$FE,D0 ; is it the special hilite state?
BHS.S SpecialHilite ; if so, go do it
;
lea contrlRect(a0), a4 ; point to the control rect <14>
MOVE.L A4,-(SP) ; push rectangle
MOVE.L D4,-(SP) ; push rounding factor
_InverRoundRect ; hilite by inverting
@Common6
;
; restore original clipping region and we<77>re done
;
DoneDrwBut
_PenNormal ; set the pen back to normal
MOVE.L A2,-(SP) ; push old clip region
_SetClip ; restore it
MOVE.L A2,-(SP) ; dispose of temporary region
_DisposRgn ; de-allocate it
RTS ; all done!
;------------
; Utility Pt2Next -- Point to next line within the title
; On Entry: A2 Title pointer
; D7 offset to end of next line to do
; On Exit: D7 offset to next line-2 (D7<0 if last line)
; D3 length of next line
CR EQU $0D ; CR = carriage return
Pt2Next
MOVEQ #0,D3 ; clear out count <EHB 20-May-85>
TST.B D7 ; pointing at count? <EHB 20-May-85>
BEQ.S @2 ; => yes, a leading CR <EHB 20-May-85>
@1
CMP.B #CR,0(A2,D7) ; is char a CR? <EHB 20-May-85>
BEQ.S @2 ; => yes, all done <EHB 20-May-85>
ADDQ #1,D3 ; else bump count by one <EHB 20-May-85>
SUBQ.B #1,D7 ; and move back in string <EHB 20-May-85>
BNE.S @1 ; => not end of string <EHB 20-May-85>
@2
SUBQ.B #1,D7 ; prepare for next string <EHB 20-May-85>
RTS ; D7 < 0 if last line <EHB 20-May-85>
;------------
; Utility GetHeight -- return in D0 the height of on line
; On Entry: A3 Font Record
; On Exit: D0 Line height
GetHeight
MOVEQ #0,D0 ; clear out height <EHB 20-May-85>
ADD.W ascent(A3),D0 ; height = ascent + descent + leading <EHB 20-May-85>
ADD.W descent(A3),D0 ; <EHB 20-May-85>
ADD.W leading(A3),D0 ; <EHB 20-May-85>
RTS
; SpecialHilite handles drawing the disabled button
SpecialHilite
BSR.S DisableText
BRA.S DoneDrwBut
DisableText
TST.B IsColor(A6) ; are we on a color system?
BEQ.S @NoColor7 ; if on B&W, then skip
TST.B D6 ; is it a pushbutton?
BNE.S @NoColor7 ; a checkbox, so go
MOVEQ #cTextColor,D0 ; set the colors apropos
BSR SetUpColor ;
_RGBForeColor ;
MOVEQ #cBodyColor,D0 ;
BSR SetUpColor ;
_RGBBackColor ;
@NoColor7 ; END OF A COLOR-ONLY SECTION
move.l (a3), a0 ; get control pointer <14>
lea contrlRect(a0), a4 ; point to the control rect <14>
MOVE.L A4,-(SP) ; push rectangle
MOVE.L #$00010001,-(SP) ; <12>
_InsetRect
MOVE.L A4,-(SP) ; push rectangle
MOVE.L D4,-(SP) ; push the rounding factor <12>
MOVE.L (A5),A0
PEA Gray(A0)
_PenPat
MOVE #patBIC,-(SP)
_PenMode
_PaintRoundRect ; gray it out <12>
_PenNormal
move.l (a3), a0 ; get control pointer <14>
lea contrlRect(a0), a4 ; point to the control rect <14>
MOVE.L A4,-(SP)
MOVE.L #$FFFFFFFF,-(SP) ; <12>
_InsetRect
RTS
; RoundCalc calculates the rounding factor in D4 based on the control<6F>s rect
RoundCalc
TST.B D6 ; is it a checkBox?
BNE.S CheckRound ; if so, special case it
;
MOVE.W ContrlRect+Bottom(A0),D4 ; get bottom coordinate
SUB.W ContrlRect+Top(A0),D4 ; figure out vertical height
LSR #1,D4 ; scale it down by a factor of 2
MOVE D4,D0 ; fill both halves with it
SWAP D4 ; get in high part
MOVE D0,D4 ; and in low part
RTS
;
CheckRound MOVEQ #0,D4 ; checkBoxes are square!
RTS
;
; HitPBut handles the button hit-test
;
HitPBut
MOVE.B ContrlHilite(A0),D4 ; get hiliteState <EHB 16-May-85>
ADDQ.B #1,D4 ; is it 255? <EHB 16-May-85>
BEQ.S @1 ; if so, skip
CLR.W -(SP) ; make room for function result
MOVE.L D3,-(SP) ; push the point
PEA ContrlRect(A0) ; push address of rect
_PtInRect ; in the rectangle?
TST.B (SP)+ ; examine result
BEQ.S @1 ; if not, we<77>re done
ADDQ.B #1,D4 ; 254 hiliting? <EHB 16-May-85>
BEQ.S Return254 ; => say it is so <EHB 16-May-85>
MOVE #inButton,22(A6) ; return that it was
TST.B D6 ; a checkBox?
BEQ.S @1 ; if not, we<77>re done
ADDQ #1,22(A6) ; if so, flag it
@1 RTS
Return254
MOVE #254,22(A6) ; indicate its 254-disabled
RTS
CalcWholePBut
CalcThumbPBut
MOVE.B #1, 23(A6) ; return 1 to show that we respond <V1.2>
;
; CalcPBut returns the bounding region of the button
;
CalcPBut
TST.B D6 ; is it a checkBox?
BNE.S CalcSquare ; check box bounds are just rects
;
BSR.S RoundCalc ; calculate rounding factor
_HidePen ; dont draw anything
_OpenRgn
MOVE.L A3,A0 ; copy to A0 for HLock <C424/18Nov86> DAF
_HLock ; lock it down <C424/18Nov86> DAF
MOVE.L (A3),A0 ; get pointer to control
PEA ContrlRect(A0) ; push rectangle pointer
MOVE.L D4,-(SP) ; push rounding factor
_FrameRoundRect ; frame the button
MOVE.L D3,-(SP) ; push the region
_CloseRgn ; make the rounded rectangular region
_ShowPen
MOVE.L A3,A0 ; copy to A0 for HLock <C424/18Nov86> DAF
_HUnlock ; unlock the control <C424/18Nov86> DAF
;
; set the pattern for indicator dragging
;
DragGray
MOVE.L (A5),A0 ; get qDraw globals
LEA Gray(A0),A0 ; point to gray pattern
MOVE.L (A0)+,DragPattern ; move in the 1st half
MOVE.L (A0),DragPattern+4 ; move in the 2nd half
RTS ; all done!
;
CalcSquare
MOVE.L D3,-(SP) ; push the region
PEA ContrlRect(A0) ; push the rectangle pointer
_RectRgn ; make a rectangular region
BRA.S DragGray ; all done -- go set drag pattern
;
; PlotCheck takes care of drawing the actual check box of the check box button. It
; figures out where to draw the box, draws it, and then checks it or not based on
; the current value and hilite state of the button
;
PlotCheck
; first set the window content color <C59/30Jun86> DAF
TST.B IsColor(A6) ; are we on a color system?
BEQ.S @NoColor8 ; if on B&W, then skip
PEA ContentRGB(A6)
_RGBBackColor ;
@NoColor8 ; END OF A COLOR-ONLY SECTION
move.l (a3), a0 ; get control pointer <14>
lea contrlRect(a0), a4 ; point to the control rect <14>
SUBQ #8,SP ; allocate a rectangle on the stack
MOVE.W bottom(A4),D0 ; get rect height <EHB 20-May-85>
MOVE.W D0,D1 ; save a copy <EHB 20-May-85>
SUB.W top(A4),D0 ; get height <EHB 20-May-85>
SUB.W #12,D0 ; sub box height <EHB 20-May-85>
ASR.W #1,D0 ; div by 2 <EHB 20-May-85>
SUB.W D0,D1 ; get offset from bottom <EHB 20-May-85>
MOVE D1,Bottom(SP) ; set up the bottom <EHB 20-May-85>
SUB #12,D1 ; compute the top <EHB 20-May-85>
MOVE D1,Top(SP) ; set up the top <EHB 20-May-85>
tst.w teSysJust ; right to left? <MED 27-Aug-86>
beq.s LeftBoxTitle ; no, normal case <MED 27-Aug-86>
RightBoxTitle
MOVE Right(A4),D1 ; get left edge of boundsRect <MED 27-Aug-86>
subq #2,D1 ; indent 2 pixels <MED 27-Aug-86>
MOVE D1,Right(SP) ; that<61>s the left of the checkRect <MED 27-Aug-86>
sub #12,D1 ; compute right edge <MED 27-Aug-86>
MOVE D1,Left(SP) ; update the right edge <MED 27-Aug-86>
bra.s EraseCheck ; continue <MED 27-Aug-86>
LeftBoxTitle
MOVE Left(A4),D1 ; get left edge of boundsRect <EHB 20-May-85>
ADDQ #2,D1 ; indent 2 pixels <EHB 20-May-85>
MOVE D1,Left(SP) ; that<61>s the left of the checkRect <EHB 20-May-85>
ADD #12,D1 ; compute right edge <EHB 20-May-85>
MOVE D1,Right(SP) ; update the right edge <EHB 20-May-85>
EraseCheck
;
; erase the check box
;
MOVE.L SP,-(SP) ; push rectangle pointer
_EraseRect ; erase it
;
; OK, now we must fill in the checkBox rectangle based on the value and hilite state
; of the control
;
MOVE.L (A3),A0 ; get control pointer <14>
MOVE.W ContrlValue(A0),D5 ; get the value
MOVE.B ContrlHilite(A0),D0 ; is it hilited?
BEQ.S FrameCheck ; if not, skip
;
; its hilited so up the penSize to indicate its hilited
;
CMP.B #$FE,D0 ; disabled?
BLO.S SkipDis ; if so, skip doubling
;
TST.B useGrayText(A6) ; did we use GrayText?
BNE.S FrameCheck ; yes => skip DisableText since GrayText represents disabled state
BSR DisableText
BRA.S FrameCheck
SkipDis
MOVE.L #$00020002,-(SP)
_PenSize ; up the penSize
FrameCheck
MOVE.L SP,-(SP) ; push the rectangle
CMP.B #2,D6 ; test for radio button
BEQ.S @1 ; if its a radio button, go do it
_FrameRect ; frame it
BRA.S @2
@1
_FrameOval
@2
_PenNormal
;
; now we can draw the check if we<77>re supposed to
;
LSR #1,D5 ; check out the low bit of D5
BCC.S DonePCheck ; if its off, we<77>re done
;
CMP.W #2,D6 ; test for radio button
BEQ.S DrawRButton ; if its a radio button, go do it
;
MOVE.L SP,-(SP) ; push the rectangle pointer
MOVE.L OneOne,-(SP) ; push the inset factor
_InsetRect ; inset the rectangle
MOVE.L TopLeft(SP),-(SP) ; push top left
_MoveTo ; move to it
MOVE.L BotRight(SP),-(SP) ; push bottom right
_LineTo ; draw one line of the cross
;
MOVE Right(SP),-(SP) ; push right
MOVE Top+2(SP),-(SP) ; push top
SUBQ #1,(SP) ; bias the top
_MoveTo ; move to it
MOVE Left(SP),-(SP) ; push left
SUBQ #1,(SP) ; bias the left
MOVE Bottom+2(SP),-(SP) ; push bottom
_LineTo ; draw the line
BRA.S DonePCheck
;
; draw the radio button check mark -- a little circle
;
DrawRButton
MOVE.L SP,-(SP) ; push pointer to rect
MOVE.L #$00030003,-(SP) ; push inset factor
_InsetRect ; inset it
MOVE.L SP,-(SP) ; push rect again
_PaintOval ; draw the circle?
;
DonePCheck
ADDQ #8,SP ; pop off the rectangle
BRA DoneDrwBut ; all done!
END