Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
mdefproc.a
;EASE$$$ READ ONLY COPY of file ÒMdefProc.aÓ |
; 1.6 PKE 08/22/1989 Rolling in from reality sources (YAY) |
;<1.7> PKE 08/21/1989 NEEDED FOR 6.0.4: (really dba) Fix bug in bug fix. GrayRect takes |
; its parameter in A0, so A0 must be set up with TempRect before calling |
; GrayRect. I tried to fix the earlier bug by not relying on A0 -- big mistake. |
; Instead, get TempRect into a0. |
; 1.5 PKE 08/15/1989 Rolling in from Reality sources |
;<1.6> dba 08/15/1989 NEEDED FOR 6.0.4: fix bug in GetItemHeight where it relies |
; on GetIconSize not trashing A0 |
;<1.5> RLC 08/10/1989 Changed selector message to Help Mgr Pack to MOVEQ |
; #select,D0 |
; 1.1 CCH 11/11/1988 Fixed Header. |
; 1.0 CCH 11/ 9/1988 Adding to EASE. |
; OLD REVISIONS BELOW |
;¥1.3 EMT 10/3/88 Roll in latest bug fixes. |
; END EASE MODIFICATION HISTORY |
;---------------------------------------------------------------- |
; © Apple Computer, Inc. 1982, 1983, 1984, 1985, 1986, 1987, 1988 |
; All Rights Reserved |
;---------------------------------------------------------------- |
;File mDefProc.ASM |
;------------------------------------------------------------ |
; |
; Standard Menu Definition Procedure for Text Menus |
; |
; written by Andy Hertzfeld July 1982 |
; |
; Here is the default menu definition procedure for text menus. It knows how to |
; draw a text menu, or select from within a text menu. It is always called from the |
; window manager port with clipping set to the menuRect. (Not CalcMenuSize) |
; |
; MODIFICATION HISTORY: |
; 27-Dec-82 AJH Broke off into separate file for resources |
; 28-Jan-83 AJH made "GrayRect" use FillRect and a hardwired gray |
; 17-Mar-83 AJH Fixed 4 pixel choosing offset |
; 17-Mar-83 AJH no more forcing bold |
; 28-Apr-83 AJH added "calcMenuSize" message |
; 30-Oct-83 AJH changed disabling |
; 06-Nov-83 AJH back to old disabling; special-cased "-" item |
; 13-Feb-84 AJH speeded up CalcMenuSize message (linear instead of N squared) |
; 11-Jan-85 JTC convert to MDS |
; 14-Feb-85 JTC named rsrc. |
; 15-Feb-85 SC fixed applemark/commandMark bug in command keys |
; 10-Apr-85 EHB fixed CalcMenuSize for items with 0 length |
; 29-Jul-85 EHB converted back to porkshop |
;v3 01-Aug-85 EHB adapted for variable height system fonts |
;v4 26-Aug-85 EHB ROM/Ram version (tests ROM85) |
;v5 27-Sep-85 EHB Added International menu display. |
; Added emergency menu scrolling. |
; 30-Sep-85 EHB Made scrolling smoother. |
; 11-Oct-85 EHB Do test byte of low memory justification word, so intl. people |
; can use the high byte for further discrimination (yuck). |
; 15-Oct-85 EHB Fixed bugs in display of menu icons |
; |
;------------------ Lonely Hearts ROMs ------------------------ |
; |
; Dec-85 EHB Different low memory locations if on old ROMs |
; |
; ----------------- System File 3.0 --------------------------- |
; |
; 07-Jan-86 EHB Fixed enable bug for items > 31 (see C466 below) |
; 07-Jan-86 EHB Don't leave extra space at bottom of screen (reversed 30 Jan) |
; 30-Jan-86 EHB Re-did scrolling so icons would work |
; |
; 01-Oct-86 DAF Changed include headers |
; 30-Oct-86 FJL C222 Fixes for hierarchical menus |
; 04-Nov-86 FJL CXXX General clean up of menu manager. |
; When #ScriptMenuCmd ($1C) in itemCmd field item |
; to be printed in script whose ID is in the itemIcon field -- |
; also, command keys draw as cmdletter/cmdchar rather |
; than normal cmdchar/cmdletter (for International). |
; Also slow down scrolling. |
; 08-Dec-86 FJL C408 Added color support |
; 25-Nov-86 FJL C466 Fixed ENABLETEST (local label) so enables items > 31 unless whole |
; menu disabled. |
; 10-Feb-87 FJL C792 Add scrolling indicator to top and bottom of scrollable menus. |
; 20-Feb-87 FJL C838 Sped up menu scrolling by an amazing amount. |
; 20-Feb-87 FJL C844 New routine PopUpMenuSelect. |
; 06-Mar-87 FJL Clean up all OnNuMac conditionals for System Disk --> Universal defproc |
; 09-Mar-87 FJL Add variable speed menu scrolling |
; 17-Mar-87 FJL Do invert for MacPlus/MacSE rather than redraw (for MacDraw custom menu) |
; when choosing item |
; 30-Mar-87 FJL PMAB155 Don't reference MenuDisable in mdefproc.a on 64K ROMs. |
; 08-Apr-87 DBG&JTC S171 Save D2 (volatile register) around call to CalcMenuSize in PopUpMenu |
; message. |
; 14-Apr-87 FJL PMAB177 Use CopyBits instead of CopyMask for drawing hierarchical and scrolling |
; arrows. Do moveq #BitMapRec, d0 instead of move.w #BitMapRec, d0 |
; before call to NewHandle. |
; |
;------------------------------- System 4.2 and beyond ----------------------------------- |
; |
; 14-Jul-87 FJL PMAB205 Juggler support -- support shrunken and small icons |
; 21-Aug-87 FJL PMAB239 Calculate menu width correctly when have shrunken or small icons |
; 15-Sep-87 FJL PMAB276 Allow item = 0 to popupmenuselect |
; PMAB364 23Jan88 EMT Fix Pop-up menus to come up on any screen |
; S394 12Feb88 DBG Fixed errant branch, which was reversed, causing crash on +/SE |
; S422 08Mar88 MED Fixed mdefproc.a to use SetScriptFont uniformally instead of inaccurate calculation |
; S476 22Apr88 EMT Fixed hierchical menus being forced below menu bar |
; S550 27Jul88 EMT Removed references to WMgrPort for ROM |
; Fixed problems when teSysJust set for right-to-left drawing |
; Treat dash as special only if no icon or cmd. Primarily for MultiFinder |
; Handle color icons other than 32x32 |
; And some miscellaneous code cleanup |
;--------------------------------------------------------------- |
; |
; PROCEDURE TextMenuProc( message :Integer, |
; theMenu :menuHandle, |
; VAR menuRect :Rect, |
; hitPt :Point, |
; VAR whichItem :Integer); |
; |
;Msg theMenu menuRect hitPt whichItem |
;------ ----------- ----------- ------- ----------- |
; 0 Draw handle entry: ptr to not used not used |
; return: no chg |
; 1 Choose handle entry: ptr to mouse pt entry: ptr to currently selected item |
; return: no chg return: newly selected item |
; 2 Calc handle not used not used not used |
; 3 PopUp handle entry: none top/left entry: CrsrItem to be placed at HitPt |
; return: menu rect return: TopMenuItem |
BLANKS ON |
STRING ASIS |
;---------------------------------------------------------------------------------------- |
; |
; Conditional Definitions |
; |
;---------------------------------------------------------------------------------------- |
IF (&TYPE('forTESTING') = 'UNDEFINED') THEN |
forTESTING EQU 0 |
ENDIF |
IF (&TYPE('forRAM') = 'UNDEFINED') THEN |
forRAM EQU 0 |
ENDIF |
INCLUDE 'inc.sum.a' |
LOAD 'nequ.d' |
INCLUDE 'colorequ.a' |
IF forTESTING THEN ; uggghhhlllyyy |
INCLUDE 'myEquates.a' |
ENDIF |
ShrunkenIconCmd EQU $1D ; itemCmd == $1D ==> large icon plotted in 16x16 |
SmallIconCmd EQU $1E ; itemCmd == $1E ==> small icon plotted |
;---------------------------------------------------------------------------------------- |
; |
; StackFrame and Global Definitions |
; |
;---------------------------------------------------------------------------------------- |
MDEF0 PROC EXPORT |
; |
; Stack Frame Definition for TextMenuProc |
; |
MFHeight EQU -2 ; <1Aug85> cell height |
MWidMax EQU MFHeight - 2 ; <1Aug85> |
MDescent EQU MWidMax - 2 ; <1Aug85> |
MAscent EQU MDescent - 2 ; <1Aug85> |
MInfoRec EQU MAscent ; <1Aug85> |
MSpaceWidth EQU MInfoRec - 2 ; <S550 27Jul88 EMT> |
saveForeColor EQU MSpaceWidth - 6 ; <FJL C408> |
saveBackColor EQU saveForeColor-6 ; <FJL C408> |
pixelDepth EQU saveBackColor-2 ; <FJL C408> |
colorOffset EQU pixelDepth - 2 ; <FJL C408> |
invertFlag EQU colorOffset - 2 ; <FJL C408> 0 = normal item, 1 = inverted item |
scrollFlag EQU invertFlag - 2 ; <FJL 17Mar87> 0 = scrolling item, 1 = choosing item |
HItemFlag EQU scrollFlag - 2 ; <FJL 17Mar87> 0 = no sub menu, 1 = item has submenu |
iconHandle EQU HItemFlag - 4 ; <FJL C408> |
HierArrowRect EQU iconHandle - 8 ; <FJL 25Jan87> |
OrigMenuRect EQU HierArrowRect-8 ; <FJL C792> |
ScrollSpeed EQU OrigMenuRect - 4; <FJL 09Mar87> |
SlowPixels EQU ScrollSpeed - 2 ; <FJL 09Mar87> |
onColorMachine EQU SlowPixels-2 ; <FJL 06Mar87> |
lastItemStrPtr EQU onColorMachine-4 ; <KSM/RLC 31May89> |
lastAttrPtr EQU lastItemStrPtr-4 ; <KSM/RLC 31May89> |
LinkSize EQU lastAttrPtr ; <FJL C792> |
MWHICHITEM EQU 8 |
MPopUpItem EQU MWhichItem ; <FJL C844> |
MPOINT EQU MWHICHITEM+4 |
MLeftTop EQU MPoint ; <FJL C844> |
MMENURECT EQU MPOINT+4 |
MMENUHANDLE EQU MMENURECT+4 |
MMESSAGE EQU MMENUHANDLE+4 |
FastSpeed EQU 0 |
SlowSpeed EQU 10 |
FirstMDMsg EQU 0 ; first message |
LastMDMsg EQU 3 ; last message |
;---------------------------------------------------------------------------------------- |
; |
; Start of Code -- save work registers and dispatch on message number |
; |
;---------------------------------------------------------------------------------------- |
BRA.S StartMDEF |
; Standard Header |
DC.W 0 ; flags word |
DC.B 'MDEF' ; type |
DC.W 0 ; ID |
DC.W 12 ; version 4 = MacPlus |
; version 5 = Alladin |
; version 6 = onNuMac ROM |
; version 10= Universal |
; version 11= Universal 4.2 <FJL PMAB205> |
; version 12= Universal 6.0 <PMAB364 23Jan88 EMT> |
StartMDEF |
LINK A6,#LinkSize ; set up a stack frame <1Aug85> |
MOVEM.L D3-D7/A2-A4,-(SP) ; save a whole bunch of work registers |
MOVE.L MMENUHANDLE(A6),A3 ; keep menuHandle in A3 |
move.l a3, a0 ; <FJL 27Jan87> |
_HLock ; lock it down |
clr invertFlag(a6) ; most drawing done in normal (not inverted) mode <FJL C408> |
clr scrollFlag(a6) ; only set this flag when call InvertItem <FJL 17Mar87> |
; while scrolling |
clr onColorMachine(a6) ; clear color machine flag <FJL 06Mar87> |
cmpi.w #$3FFF, ROM85 ; color machine ? |
sls onColorMachine(a6) ; set byte to 1's if yes |
lea GoMdefProc, a0 ; get the dispatch table base <FJL> |
move.w mMessage(a6), d0 ; get the message type |
cmpi #LastMDMsg, d0 ; is the message within bounds? <FJL> |
bhi.s @InvalidMsg ; oops, its too high |
cmpi #FirstMDMsg, d0 ; |
blo.s @InvalidMsg ; oops, its too low |
add.w d0, d0 ; double to get words |
add.w GoMdefProc(d0), a0 ; compute the dispatch address |
jsr (a0) ; and dispatch |
@InvalidMsg |
move.l a3, a0 ; get menuHandle |
_HUnlock ; and unlock it before we leave |
MOVEM.L (SP)+,D3-D7/A2-A4 ; restore work registers |
UNLK A6 ; unbuild the stack frame |
MOVE.L (SP)+,A0 ; get return address |
ADD #18,SP ; strip parameters |
JMP (A0) ; return to caller |
; Dispatch Table |
GoMdefProc dc.w DoDrawMsg-GoMdefProc ; draw is message #0 |
dc.w DoChooseMsg-GoMdefProc ; choose menu size is msg #1 |
dc.w DoCalcMsg-GoMdefProc ; calc menu is msg #2 |
dc.w DoPopUpItemMsg-GoMdefProc ; calc top of popup item #3 |
;******************************************************************************************** |
;* * |
;* IF YOU ADD ANOTHER MESSAGE YOU MUST UPDATE THE VARIABLE "LastMDMsg" FOUND ABOVE !!!!!! * |
;* * |
;******************************************************************************************** |
;---------------------------------------------------------------------------------------- |
; |
; Msg #1 -- Choose -- examine the mouse position and hilite the appropriate item |
; |
;---------------------------------------------------------------------------------------- |
DoChooseMsg |
; |
; -------------------------- DO SETUP STUFF --------------------------- |
; |
bsr GetSizes ; get font info into stackframe |
MOVE.L MWHICHITEM(A6),A4 ; get pointer to whichItem |
MOVE.W (A4),D3 ; remember oldWhichItem |
CLR (A4) ; set whichItem to zero |
MOVE.L MMENURECT(A6),A2 ; get the menu rect <27Sep85> |
; store original menurect in the stackframe <FJL C792> |
move.l Top(a2), OrigMenuRect+Top(a6) |
move.l Bottom(a2), OrigMenuRect+Bottom(a6) |
move.l #FastSpeed, ScrollSpeed(a6) ; assume fast-speed <FJL 09Mar87> |
move MFHeight(a6), d0 ; get height of scroll arrow <FJL 09Mar87> |
asr #1, d0 ; num pixels for slow scroll = height/2 <FJL 09Mar87> |
move d0, SlowPixels(a6) |
clr HItemFlag(a6) ; assume "old" item has no submenu <FJL 17Mar87> |
move d3, d0 ; get item |
move.l (a3),a0 ; get menuPtr |
bsr GetItemRecord ; look it up |
cmp.b #HMenuCmd, ItemCmd(a1) ; does item have sub-menu? |
bne.s @NoSubMenu ; no ==> leave flag cleared |
move #1, HItemFlag(a6) ; yes ==> set flag |
@NoSubMenu MOVE.W TopMenuItem,D4 ; get top of (scrolled) menu <30Jan86> |
MOVE.L MPOINT(A6),D5 ; get the mouse point <27Sep85> |
BEQ NOITEMSEL ; => special case for flashing <27Sep85> |
; |
; ------------------- ADJUST MENURECT BASED ON SCROLLING ARROWS ---------------- |
; |
move AtMenuBottom, d0 ; check for down scrolling arrow <FJL C792> |
cmp Bottom(a2), d0 ; is AtMenuBottom > bottom of menu rect ? |
ble.s @NoScroll ; no, so chk top |
move MFHeight(a6), d0 ; yes, so make menuRect smaller by down scrolling arrow rect |
sub d0, Bottom(a2) |
@NoScroll |
move TopMenuItem, d0 ; check for up scrolling arrow |
cmp Top(a2), d0 ; is TopMenuItem < top of menu rect ? |
bge.s @NoScroll2 ; no, so just do PtInRect |
move MFHeight(a6), d0 ; yes, so make menuRect smaller by up scrolling arrow rect |
add d0, Top(a2) |
@NoScroll2 |
; |
; If the point isn't in the adjusted menuRect, check for autoscrolling |
; |
CLR.W -(SP) ; make room for PtInRect result |
MOVE.L D5,-(SP) ; push the point |
MOVE.L A2,-(SP) ; push the rect |
_PtInRect ; test if the point is in the rect |
TST.B (SP)+ ; was it? |
BNE @3 ; => yes, go select something |
;----------------------- CHECK FOR AUTOSCROLLING DOWN ------------------------------- |
; |
; Only scroll if mouse pt directly above/below menu. This allows |
; hierarchical menus to work properly -- scroll when mouse above/below menu, |
; -- return to a previous menu if outside of the scrolling rectangles. |
; |
cmp left(a2), d5 ; to left of menu's left side? <FJL C222> |
blt NoItemSel ; yes, so no item selected <FJL C222> |
cmp right(a2), d5 ; to right of menu's right side? <FJL C222> |
bgt NoItemSel ; yes, so no item selected <FJL C222> |
MOVE.W MFHeight(A6),D7 ; get distance for scroll <30Sep85> |
SWAP D5 ; get mouse.v into low word <27Sep85> |
CMP.W top(A2),D5 ; above top? <27Sep85> |
BGE @2 ; => no, check bottom <27Sep85> |
ADD.W D7,D4 ; try to go up an item <27Sep85> |
CMP.W top(A2),D4 ; menu top must be <= to MenuRect.Top <30Jan86> |
BGT NOITEMSEL ; => can't go up <27Sep85> |
; how far is mouse into scrolling arrow? <FJL 09Mar87> |
move top(a2), d0 ; get top of menu into d0 <FJL 09Mar87> |
sub d5, d0 ; subtract mouse.v <FJL 09Mar87> |
cmp SlowPixels(a6), d0 ; is it more than slow num ? <FJL 09Mar87> |
bgt.s @ContDown ; yes ==> do it fast <FJL 09Mar87> |
move.l #SlowSpeed, ScrollSpeed(a6) ; no ==> do it slow <FJL 09Mar87> |
@ContDown |
;+++ move AtMenuBottom, d0 ; <FJL C792> |
;+++ cmp Bottom(a2), d0 ; is AtMenuBottom<> bottom of menu? |
;+++ bne.s @1 ; yes, so just do scrolling |
move AtMenuBottom, D0 ; <FJL PMAB205> |
cmp Bottom(A2), D0 ; is AtMenuBottom > bottom of menu ? |
bgt.s @1 ; yes -> no scrolling arrow needed |
add MFHeight(a6), d0 |
cmp Bottom(A2), D0 ; is AtMenuBottom+scrollamt > bottom of menu ? <FJL PMAB276> |
ble.s @1 ; yes -> no scrolling arrow needed <FJL PMAB276> |
; If we get here then we are scrolling down and the last item is showing. Therefore |
; we want to draw the down scroll arrow before scrolling. |
move.l a2, a0 ; BlitScrollIndic expects menuRect ptr in A0 |
bsr BlitDownScrollIndic |
move MFHeight(a6), d0 ; move bottom of menuRect up so arrow doesn't get scrolled |
sub d0, Bottom(a2) ; and fall into scrolling code |
;----------------------- DO THE AUTOSCROLLING -------------------------------------- |
@1 |
MOVE.W D3,D0 ; get the current selection <30Sep85> |
BSR InvertItem ; and deselect it <30Sep85> |
; When a HMenu is up and the item with the HMenu is the topmost or bottommost item |
; garbage is left on the screen unless we bring down the HMenu first. |
; Solution: 1) Don't scroll if an HMenu is up. |
; 2) DrawMenu clears a flag in mbSaveLoc every time a menu is drawn. |
; 3) If that flag is clear, then we set the flag and skip scrolling. |
; This gives MenuSelect a chance to bring down the HMenu before |
; the MDEF is called again. |
; 4) If the flag is set, then it is okay to scroll. |
;>>>>>------------- MacPlus/MacSE patches ------------------>>>>> |
IF forRAM THEN |
cmp.w #$FFFF, ROM85 ; on old Mac or MacXL? |
beq.s @OkToScroll ; yes -> skip HMenu specific stuff |
; RADIUS patches out complete menu mgr ==> could |
; have GetItemCmd installed, but mbSaveLoc |
; not initialized. |
cmpi.l #$FFFFFFFF, mbSaveLoc ; has the MBDF data structure been initialized? |
beq.s @OkToScroll |
move.w #$009F, d0 ; load _Unimplemented number |
_GetTrapAddress ; load _Unimplemented address |
move.l a0, d1 ; copy routine address |
move.w #$004E, d0 ; load _GetItemCmd number |
_GetTrapAddress ,newTool ; load _GetItemCmd address |
cmp.l a0, d1 ; new HMenu Mgr installed? |
beq.s @OkToScroll ; no -> skip HMenu specific stuff |
ENDIF ; if forRAM |
;<<<<<--------------------------------------<<<<< |
move.l mbSaveLoc, a0 ; get mbUglyScroll in mbSaveLoc |
move.l (a0), a0 |
tst mbUglyScroll(a0) ; is mbUglyScroll set ? |
bne.s @OkToScroll ; yes, so HMenu was already brought down |
move #1, mbUglyScroll(a0); no, so set field |
bra.s @DoneScroll ; and skip scrolling this time through |
@OkToScroll |
MOVE.W D4,topMenuItem ; stuff new topItem <27Sep85> |
CLR.L -(SP) ; room for region #1 <30Sep85> |
_NewRgn ; get it <30Sep85> |
MOVE.L (SP),D6 ; save in D6 <30Jan86> |
CLR.L -(SP) ; room for region #2 <30Jan86> |
_NewRgn ; get it <30Jan86> |
bsr SaveCurrentColors ; save current colors in stack frame <FJL C408> |
move #mctRGB2, colorOffset(a6) ; this offset is unimportant here <FJL C408> |
; since all we care about is bkgd color <FJL C408> |
bsr SetColors ; set proper colors for ScrollRect <FJL C408> |
; |
; Delay depending on how far cursor is into the scroll arrow. <FJL 09Mar87> |
; |
bsr DoScrollWait |
@DoTheScroll |
MOVE.L A2,-(SP) ; push rect <27Sep85> |
CLR.W -(SP) ; dh = 0 <30Sep85> |
MOVE.W D7,-(SP) ; dv = itemHeight <30Sep85> |
MOVE.L D6,-(SP) ; push update region |
_ScrollRect ; scroll the menu <30Sep85> |
bsr ChkScrollArrows ; chk if scrolling arrows should still be up <FJL C792> |
bsr ResetPreviousColors ; reset colors stored in stackframe <FJL C408> |
MOVE.L (SP),-(SP) ; point to region #2 <30Jan86> |
_GetClip ; save the clip in it <30Jan86> |
MOVE.L D6,-(SP) ; point to update region <30Jan86> |
_SetClip ; set clip to it <30Jan86> |
BSR DrawScrolledItem ; call fast routine to draw item <FJL C838> |
ADD D7, AtMenuBottom ; update new menu bottom <FJL C838> |
MOVE.L (SP),-(SP) ; point to saved clip <30Jan86> |
_SetClip ; and restore it <30Jan86> |
_DisposRgn ; dispose of region #2 <30Jan86> |
_DisposRgn ; dispose of region #1 <30Jan86> |
; |
; When scrolling, no item is selected, so clear the Item in MenuDisable global <FJL C792> |
; |
@DoneScroll |
IF forRAM THEN |
tst.w ROM85 ; on old Mac or MacXL? |
bmi.s @NoMenuDisable ; yes -> MenuDisable is not available in low-memory , so skip |
ENDIF ;forRAM |
clr MenuDisable+2 ; clear Item only, not ID |
@NoMenuDisable |
BRA DoChooseDone ; and return <27Sep85> |
;----------------------- CHECK FOR AUTOSCROLLING UP ---------------------------------- |
@2 MOVE.W bottom(A2),D0 ; get bottom <30Jan86> |
CMP.W D0,D5 ; below bottom? <30Jan86> |
BLT NOITEMSEL ; => no <27Sep85> |
CMP.W atMenuBottom,D0 ; done scrolling? <30Jan86> |
BGE NOITEMSEL ; => yes, nothing below us <30Jan86> |
NEG.W D7 ; change direction of scroll <30Sep85> |
ADD.W D7,D4 ; else scroll down <27Sep85> |
; how far is mouse into scrolling arrow?<FJL 09Mar87> |
move d5, d0 ; get mouse.v into d0 <FJL 09Mar87> |
sub bottom(a2), d0 ; subtract bottom of menu <FJL 09Mar87> |
cmp SlowPixels(a6), d0 ; is it more than slow num ? <FJL 09Mar87> |
bgt.s @ContUp ; yes ==> do it fast <FJL 09Mar87> |
move.l #SlowSpeed, ScrollSpeed(a6) ; no ==> do it slow <FJL 09Mar87> |
@ContUp |
move TopMenuItem, d0 ; <FJL C792> |
cmp Top(a2), d0 ; is TopMenuItem <> top of menu rect ? |
bne @1 ; yes, so just do scrolling |
; If we get here then we are scrolling up and the first item is showing. Therefore |
; we want to draw the up scroll arrow before scrolling. |
move.l a2, a0 ; BlitScrollIndic expects menuRect ptr in A0 |
bsr BlitUpScrollIndic |
move MFHeight(a6), d0 ; move top of menuRect up so arrow doesn't get scrolled |
add d0, Top(a2) ; and fall into scrolling code |
bra @1 |
;-------------------------------- DO THE CHOOSE ------------------------------------ |
; the point is in the menu, so waltz through the itemList keeping track of vertical |
; position seeing which item it's in. In the following loop, D4 holds the item number |
; while D2 has the cumulative vertical space |
; |
@3 |
; |
; With popup menus it is possible to have the mouse pt above TopMenuItem <FJL 22Mar87> |
; but no down-scrolling taking place because TopMenuItem may be below top |
; of the menuRect. "Choose" must recognize this case and branch to NoItemSel. |
; |
CMP Top(a2), D4 ; is TopMenuItem > top of menuRect ? |
BLE.S @DoChoose ; no ==> ok to choose |
CMP MPoint+V(a6), D4 ; yes ==> is TopMenuItem > mouse pt ? |
BGT.S NoItemSel ; yes ==> no choice |
@DoChoose MOVE.W D4,D2 ; top of menu into D2 <30Jan86> |
MOVEQ #1,D4 ; start with first item <30Jan86> |
MSELOOP MOVE.L (A3),A0 ; get menuPtr |
MOVE D4,D0 ; get item number |
BSR GETITEMRECORD ; look it up |
BEQ.S NOITEMSEL ; if so, nothing selected |
BSR GetItemHeight ; get item height in D0 <1Aug85> |
ADD D0,D2 ; update vertical <1Aug85> |
CMP MPOINT+V(A6),D2 ; compare with mouse point |
BGT.S GOTSEL ; when D2 is bigger, we found it |
; |
; we didn't reach it yet, so keep stepping down till we do |
; |
NEXTMSEL ADDQ #1,D4 ; bump to next item |
BRA.S MSELOOP ; loop till we find it |
; |
; we found it so update whichItem. First we better make sure it's enabled |
GOTSEL |
; |
; put item rect in mbSaveLoc so MenuSelect has it to do Hierarchical menu drag <FJL C222> |
; must store this regardless of whether item changed (consider case where an item |
; has a HMenu and you move to the HMenu, and then back into the item with that HMenu). |
; |
LEA TEMPRECT,A0 ; get pointer to temporary rectangle |
MOVE.L MMENURECT(A6),A1 ; point to menuRect |
MOVE.L (A1)+,(A0) ; copy menuRect into tempRect |
MOVE.L (A1),4(A0) |
MOVE D2,BOTTOM(A0) ; D2 has the bottom coordinate |
SUB D0,D2 ; subtract the height |
MOVE D2,TOP(A0) ; set up the top |
;>>>>>------------- MacPlus/MacSE patches ------------------>>>>> |
IF forRAM THEN |
cmp.w #$FFFF, ROM85 ; on old Mac or MacXL? |
beq.s @SkipRectStore ; yes -> skip HMenu specific stuff |
; RADIUS patches out complete menu mgr ==> could |
; have GetItemCmd installed, but mbSaveLoc |
; not initialized. |
cmpi.l #$FFFFFFFF, mbSaveLoc ; has the MBDF data structure been initialized? |
beq.s @SkipRectStore |
move.w #$009F, d0 ; load _Unimplemented number |
_GetTrapAddress ; load _Unimplemented address |
move.l a0, d1 ; copy routine address |
move.w #$004E, d0 ; load _GetItemCmd number |
_GetTrapAddress ,newTool ; load _GetItemCmd address |
cmp.l a0, d1 ; new HMenu Mgr installed? |
beq.s @SkipRectStore ; no -> skip HMenu specific stuff |
ENDIF ; if forRAM |
;<<<<<--------------------------------------<<<<< |
move.l mbSaveLoc, a0 ; get handle to save loc |
move.l (a0), a0 ; dereference |
move.l TempRect, mbItemRect(a0) ; save top, left |
move.l TempRect+4, mbItemRect+4(a0) ; save bottom, right |
@SkipRectStore |
BSR ENABLETEST ; make sure whole menu is enabled |
BEQ.S DoInverting ; if not, no selection |
MOVE D4,(A4) ; menu is enabled, so store item |
bra.s DoInverting ; and continue |
; |
; At this label the mouse is not in any item, so clear d4 so we return the <FJL C531> |
; correct value in low-memory MenuDisable. Can only reach here by a branch. |
; |
NOITEMSEL clr d4 ; at this label no item selected |
; |
; see if whichItem changed; if it has, unselect the old item and select the new one |
; |
DoInverting |
CMP (A4),D3 ; have they changed? |
BEQ.S GetDisabledItem ; if not, we're all done, no hiliting change |
MOVE D3,D0 ; unhilite old item |
BSR INVERTITEM ; |
MOVE (A4),D0 ; hilite new item |
not invertFlag(a6) ; tell InvertItem to draw in reverse colors <FJL C408> |
BSR INVERTITEM ; |
clr invertFlag(a6) ; reset invertFlag <FJL C408> |
; |
; "User ed" requested that apps be able to find out if a disabled menu item was chosen. <FJL C531> |
; We return the ID and item in the global MenuDisable. If the item is zero then <FJL C531> |
; no item was chosen (i.e. the mouse was outside the menu), or was in the title. <FJL C531> |
; |
GetDisabledItem |
move.l (a3), a0 ; get menu ptr |
swap d4 ; put item in hi-byte |
move menuID(a0), d4 ; put menuID in lo-byte |
swap d4 ; restore d4 |
IF forRAM THEN |
tst.w ROM85 ; on old Mac or MacXL? |
bmi.s @NoMenuDisable ; yes -> MenuDisable is not available in low-memory , so skip |
ENDIF ;forRAM |
move.l d4, MenuDisable ; put in low-memory where apps can query it if they want |
@NoMenuDisable |
DoChooseDone |
move.l OrigMenuRect(a6), Top(a2) ; reset menuRect in case we changed it<FJL C792> |
move.l OrigMenuRect+Bottom(a6), Bottom(a2) |
rts ; return to dispatcher |
;------------------------------- DONE CHOOSE MSG ------------------------------------ |
;--------------------------------------- |
; Utility -- DoScrollWait <FJL 09Mar87> |
;--------------------------------------- |
; |
; Delay for ScrollSpeed ticks. If cursor moves out of slow scroll area then leave wait loop. |
; |
DoScrollWait |
tst.l ScrollSpeed(a6) ; how fast should we scroll? |
beq.s @NoWait ; zero means fast as possible |
move.l d3, -(sp) ; save temp reg on the stack |
subq #4, sp ; space for result |
_TickCount ; get current tick count |
move.l (sp)+, d3 |
add.l ScrollSpeed(a6), d3 ; we want to wait until tick count in d3 |
@Loop subq #4, sp ; space for VAR parameter |
move.l sp, -(sp) ; push address of parameter |
_GetMouse |
move.l (sp)+, d5 ; get mouse pt |
swap d5 ; get .v into lo-word |
tst d7 |
bge.s @ScrollingDown |
; how far is mouse into scrolling arrow? <FJL 09Mar87> |
move d5, d0 ; get mouse.v into d0 <FJL 09Mar87> |
sub bottom(a2), d0 ; subtract bottom of menu <FJL 09Mar87> |
cmp SlowPixels(a6), d0 ; is it more than slow num ? <FJL 09Mar87> |
bgt.s @DoneWait ; yes ==> do it fast ==> stop waiting <FJL 09Mar87> |
bra.s @ContLoop |
@ScrollingDown ; how far is mouse into scrolling arrow? |
move top(a2), d0 ; get top of menu into d0 |
sub d5, d0 ; subtract mouse.v |
cmp SlowPixels(a6), d0 ; is it more than slow num ? |
bgt.s @DoneWait ; yes ==> do it fast ==> stop waiting |
@ContLoop |
subq #4, sp ; space for result |
_TickCount |
cmp.l (sp)+, d3 ; reached desired tick count yet? |
bgt.s @Loop ; no ==> keep looping |
; yes ==> we're done waiting |
@DoneWait |
move.l (sp)+, d3 ; restore work register |
@NoWait |
rts |
;--------------------------------------- |
; Utility -- ChkScrollArrows |
;--------------------------------------- |
; if scrolling up, and if last item is appearing, then lower clip by height of <FJL C792> |
; rectangle containing indicator arrow, and erase arrow rectangle. |
ChkScrollArrows |
tst d7 |
bge.s @ChkScrollDown ; if D7 >= 0 then scrolling down not up |
move d7, d0 ; get amount of scroll |
neg d0 ; take negative since to make it positive |
add MFHeight(a6), d0 ; add in height of scroll arrow |
add Bottom(a2), d0 ; add to bottom of menuRect |
cmp AtMenuBottom, d0 ; is new bottom of menuRect >= AtMenuBottom |
blt.s @NotLastItem ; no ==> not showing last item |
; last item is being drawn -> open clip so scroll arrow gets erased and last item gets drawn <FJL C792> |
move.l d6, a0 ; change the bottom of the update region |
move.l (a0), a0 ; get ptr to rgn |
move MFHeight(a6), d0 ; get menu item height |
add d0, 2+Bottom(a0) ; Bottom = Bottom + menu item height |
add d0, Bottom(a2) ; update bottom of menuRect <FJL C838> |
move.l d6, -(sp) ; and erase the whole region |
_EraseRgn |
@NotLastItem |
rts |
; if scrolling down, and if first item is appearing, then increase clip by height of <FJL C792> |
; rectangle containing indicator arrow, and erase arrow rectangle. |
; NOTE: TopMenuItem has already been adjusted by scroll amount, so don't subtract it here |
@ChkScrollDown |
move Top(a2), d0 ; get Top of menuRect |
sub MFHeight(a6), d0 ; sub height of scroll arrow |
cmp TopMenuItem, d0 ; is new top of menuRect <= TopMenuItem |
bgt.s @NotFirstItem ; no ==> not showing first item |
; first item is being drawn -> open clip so scroll arrow gets erased and first item gets drawn <FJL C792> |
move.l d6, a0 ; change the top of the update region |
move.l (a0), a0 ; get ptr to rgn |
move MFHeight(a6), d0 ; get menu item height |
sub d0, 2+Top(a0) ; Top = Top - menu item height |
sub d0, Top(a2) ; update top of menuRect <FJL C838> |
move.l d6, -(sp) ; and erase the whole region |
_EraseRgn |
@NotFirstItem |
rts |
;--------------------------------------- |
; Utility -- GetSizes |
;--------------------------------------- |
; GetSizes reads the size of the current font into the stack frame. It puts |
; ascent+descent+leading into the leading field and tweaks width for chicago |
GetSizes LEA MInfoRec(A6),A2 ; point to our info rec <1Aug85> |
MOVE.L A2,-(SP) ; push a pointer <1Aug85> |
_GetFontInfo ; and get the font's info <1Aug85> |
MOVE.W (A2)+,D0 ; get ascent <1Aug85> |
ADD.W (A2)+,D0 ; add descent <1Aug85> |
; fudge width if font is Chicago so that space between command key and command <FJL 21Jan87> |
; character look better. Can't assume that a width of 14 means chicago, so check |
; explicitly. |
TST.W ROM85 ; running on new roms? |
BMI.S @ChkCurFM ; => no, then only check CurFMFamily |
TST.W SysFontFam ; We ar on post-MacPlus so can check SysFontFamily |
BNE.S @NotChicago ; If SysFontFam <> 0 then not Chicago |
; If on post-MacPlus then check CurFMFamily too. |
@ChkCurFM TST.W CurFMFamily ; is CurFMFamily == 0 ? |
BNE.S @NotChicago ; no, so not Chicago |
SUBQ #2,(A2) ; yes its Chicago, so fudge width <1Aug85> |
@NotChicago ADDQ #2,A2 ; skip over widmax <1Aug85> |
ADD.W D0,(A2) ; add leading, store total height in MFHeight(A6) <1Aug85> |
SUBQ.L #2, SP ; Make room in stack <S550 27Jul88 EMT> |
MOVE.W #' ', -(SP) ; ch = space <S550 27Jul88 EMT> |
_CharWidth ; See how wide it is <S550 27Jul88 EMT> |
MOVE.W (SP)+, MSpaceWidth(A6) ; Put it in our stack frame <S550 27Jul88 EMT> |
RTS |
;--------------------------------------- |
; Utility -- GetIconSize |
;--------------------------------------- |
; GetIconSize is a utility which returns the height and width of an icon. The item pointer is in |
; A1 and the result is returned in D1. The height is in the high word. <S550 27Jul88 EMT> |
GetIconSize |
cmpi.b #ScriptMenuCmd, itemCmd(a1) ; is there a script defined? <FJL CXXX> |
beq.s @noIcon ; yes, icon field stores scriptID <FJL CXXX> |
TST.B ITEMICON(A1) ; does it have an icon? <1Aug85> |
BNE.S @hasIcon ; skip around if it does <1Aug85> |
@noIcon |
MOVEQ.L #0, D1 ; No icon - return 0 <S550 27Jul88 EMT> |
RTS ; Go home <S550 27Jul88 EMT> |
@hasIcon |
tst.b onColorMachine(a6) ; If color, than check color icon <S550 27Jul88 EMT> |
beq.s @noColor ; <S550 27Jul88 EMT> |
; Get the cicn resource because its faster than calling GetCIcon <S550 27Jul88 EMT> |
SUBQ.L #4, SP ; make room for function result <S550 27Jul88 EMT> |
MOVE.L #'cicn',-(SP) ; push the resource type <S550 27Jul88 EMT> |
MOVE.W #$0100,D0 ; menu icons are 256-511 <S550 27Jul88 EMT> |
MOVE.B ITEMICON(A1),D0 ; <S550 27Jul88 EMT> |
MOVE.W D0,-(SP) ; push icon number <S550 27Jul88 EMT> |
_GetResource ; get handle to cicn resource <S550 27Jul88 EMT> |
MOVE.L (SP)+, D1 ; get it in D1 <S550 27Jul88 EMT> |
BEQ.S @noColor ; no color icon, must be regular icon <S550 27Jul88 EMT> |
MOVE.L D1, -(SP) ; Since we don't know what resLoad is <S550 27Jul88 EMT> |
_LoadResource ; call LoadResource to be sure <S550 27Jul88 EMT> |
MOVE.L D1, A0 ; get cicn resource handle in a0 <S550 27Jul88 EMT> |
MOVE.L (A0), A0 ; dereference, cicn begins with pixMap <S550 27Jul88 EMT> |
MOVE.L pBounds+botRight(A0), D1 ; get bottom,right in D1 <S550 27Jul88 EMT> |
SUB.L pBounds+topLeft(a0), D1 ; height = bottom,right - top,left <S550 27Jul88 EMT> |
BRA.S @testShrunk ; <S550 27Jul88 EMT> |
@noColor ; <S550 27Jul88 EMT> |
MOVE.L #$00200020, D1 ; Large b/w icons are 32 x 32 <S550 27Jul88 EMT> |
@testShrunk ; <S550 27Jul88 EMT> |
cmpi.b #ShrunkenIconCmd, itemCmd(A1) ; is there a shrunken icon? <FJL PMAB205> |
beq.s @0 ; yes -> branch |
cmpi.b #SmallIconCmd, itemCmd(A1) ; is there a small icon? <FJL PMAB205> |
bne.s @1 ; no -> branch <S550 27Jul88 EMT> |
@0 |
LSR.L #1, D1 ; Divide by 2 to get smaller size <S550 27Jul88 EMT> |
BCLR #15, D1 ; Clear out because height could be odd <S550 27Jul88 EMT> |
@1 |
RTS |
;--------------------------------------- |
; Utility -- GetItemHeightA4 <FJL PMAB205> |
;--------------------------------------- |
; GetItemHeight gets the height of the current menu item into D0. |
; The item pointer is in A4. Use GetItemHeight. |
GetItemHeightA4 |
MoveM.L A1, -(SP) ; save work register |
Move.L A4, A1 ; set up for call to GetItemHeight |
Bsr.S GetItemHeight |
MoveM.L (SP)+, A1 ; restore work register |
Rts |
;--------------------------------------- |
; Utility -- GetItemHeight |
;--------------------------------------- |
; GetItemHeight gets the height of the current menu item into D0. |
; The item pointer is in A1. Width of icon (if any) is in the high word of D1. |
GetItemHeight |
BSR.S GetIconSize ; Returns height, width in D1 <S550 27Jul88 EMT> |
SWAP D1 ; Get height in low word <S550 27Jul88 EMT> |
MOVE.W MFHeight(A6),D0 ; get menu item height <1Aug85> |
ADDQ.W #4, D1 ; Add 4 for good measure <S550 27Jul88 EMT> |
CMP.W D0, D1 ; Is height + 4 > MFHeight? <S550 27Jul88 EMT> |
BLT.S @1 ; Nope, skip around <S550 27Jul88 EMT> |
MOVE.W D1, D0 ; Yes, use height + 4 instead <S550 27Jul88 EMT> |
@1 RTS |
;--------------------------------------- |
; Utility -- EnableTest |
;--------------------------------------- |
; EnableTest is a utility which tests if an item is enabled. It expects a menuHandle |
; in A3 and the item number in D4. It returns the result in the Z-flag |
ENABLETEST MOVE.L (A3),A0 ; get menu pointer |
MOVE.L MENUENABLE(A0),D0 ; get enable flags |
CMPI.W #31,D4 ; is item > 32 <7Jan86><FJL C466> |
BGT.S @0 ; => no enable/disable <7Jan86><FJL C466> |
BTST D4,D0 ; is item enabled? |
BEQ.S ETDONE ; if not, return 0 |
@0 BTST #0,D0 ; test menu bit |
BEQ.S ETDONE ; if off, return 0 <S550 27Jul88 EMT> |
MOVE.W D4, D0 ; Put item number in D0 <S550 27Jul88 EMT> |
BSR GetItemRecord ; Go get it <S550 27Jul88 EMT> |
BSR IsDash ; Is it a dash? <S550 27Jul88 EMT> |
ETDONE RTS ; return to caller |
;--------------------------------------- |
; Utility -- InvertItem |
;--------------------------------------- |
; InvertItem is an internal utility that hilites/unHilites an item. The item number is |
; passed in D0. It also assumes A3 has the menuHandle. If the high bit of D0 |
; is set, bit-clear with gray instead of inverting the item (used by DoDrawMsg routine). |
INVERTITEM MOVEM.L D3-D4,-(SP) ; save work registers |
MOVE D0,D3 ; keep item number in safe place |
BEQ INVERTDONE ; if zero, ignore |
MOVE.W TopMenuItem,D2 ; start at top of menu <30Jan86> |
MOVEQ #1,D4 ; D4 hold item index <27Sep85> |
IILOOP MOVE D4,D0 ; get item |
MOVE.L (A3),A0 ; get menuPtr |
BSR GETITEMRECORD ; look it up |
beq InvertDone ; z-flag ==> can't find it <FJL 22Mar87> |
BSR.S GetItemHeight ; get item height into D0 <1Aug85> |
CMP.B D3,D4 ; found the item we want yet? |
BEQ.S GOINVERT ; if so, go invert it |
ADD D0,D2 ; add total to cumulative v position |
ADDQ #1,D4 ; bump to next position |
BRA.S IILOOP ; loop till we find it |
; it's time to invert the item. The menuRect contains the horizontal bounds, D2 contains |
; the top of the vertical, D0 has the vertical size |
GOINVERT MOVE.B 1(A0),D1 ; remember 1st char of item |
LEA TEMPRECT,A0 ; get pointer to temporary rectangle |
MOVE.L MMENURECT(A6),A1 ; point to menuRect |
MOVE.L (A1)+,(A0) ; copy menuRect into tempRect |
MOVE.L (A1),4(A0) |
MOVE D2,TOP(A0) ; D2 has the top coordinate |
ADD D0,D2 ; add in the height |
MOVE D2,BOTTOM(A0) ; set up the bottom |
; |
; Instead of inverting the item's rectangle we redraw it. If the invertFlag(a6) <FJL C408> |
; is set then SetColors will invert the colors properly for us. If it isn't set <FJL C408> |
; then the item will just be redrawn in normal colors. <FJL C408> |
; |
movem.l a2-a4/d3-d7, -(sp) ; save same work registers as does DrawMsg |
move #srcOr, -(sp) |
_TextMode ; set mode to srcOr |
; set up for call to DrawTheItem. Before doing this, we must clip to the item's rectangle |
; so that outline and shadowed text will not draw outside of the item rect. But, because |
; scrolling with icons can produce "parts of items", we must clip to the intersection of the |
; menu rect and the item rect. AND we must clip to screen in case menu draws past screen bounds. |
subq #4, sp ; space for result |
_NewRgn |
move.l (sp), -(sp) ; make copy of region so can delete later |
_GetClip |
subq #2, sp ; space for boolean result |
move.l MMenuRect(a6), -(sp); push menurect address |
pea TempRect ; push itemrect address |
pea HierArrowRect(a6) ; push dest rect (reuse stackframe variable) |
_SectRect |
addq #2, sp ; ignore result |
subq #4, sp ; get current portRect |
move.l sp, -(sp) ; make space on stack for return |
_GetPort |
move.l (sp)+, a0 ; get port |
subq #2, sp ; space for boolean result |
pea portRect(a0) ; push portRect address |
pea HierArrowRect(a6) ; push clip rect address |
pea HierArrowRect(a6) ; push dest address |
_SectRect |
addq #2, sp ; ignore result |
pea HierArrowRect(a6) ; push clip rect |
_ClipRect |
tst scrollFlag(a6) ; being called from scroll routine? |
bne.s @DoRedraw ; yes, so do the drawing |
; On MacPlus and MacSE do InvertRect instead of redrawing when choosing an item. <FJL 17Mar87> |
; Do this because MacDraw's custom "line" menu does not handle "choose item" message properly. |
; Of course it's not as easy as that since we use the Choose message as a way to clean up |
; the garbage left over when a hierarchical menu is brought down, and this assumes that |
; the item is redrawn, NOT inverted. If this is the case then HItemFlag will be set. |
tst onColorMachine(a6) ; on MacII ? |
bne.s @DoRedraw ; yes ==> always redraw |
tst HItemFlag(a6) ; does item have submenu? |
bne.s @DoRedraw ; yes ==> then redraw to eliminate garbage beneath submenu |
pea TempRect ; push ptr to item's rectangle |
_InverRect ; invert it |
bra.s @RedrawDone ; and leave |
@DoRedraw |
; erase the rect to the proper background color |
bsr SaveCurrentColors ; save current colors in stack frame <FJL C408> |
move #mctRGB2, colorOffset(a6) ; this offset is unimportant here <FJL C408> |
; since all we care about is bkgd color <FJL C408> |
bsr SetColors ; set proper colors for EraseRect <FJL C408> |
pea TempRect ; push a pointer to the rectangle |
_EraseRect ; erase it |
bsr ResetPreviousColors ; reset colors after EraseRect |
; and draw the item |
lea TempRect, a0 ; get address of item's rectangle |
move Top(a0), d3 ; get top |
add MAscent(a6),d3 ; add in the ascent for baseline |
; move Left(a0), d5 ; move left edge into d5 <S550 27Jul88 EMT> |
; move Right(a0), d6 ; move right edge into d6 <S550 27Jul88 EMT> |
; <S550 27Jul88 EMT> |
; move d4,d0 ; get item <S550 27Jul88 EMT> |
; move.l (a3),a0 ; get menuPtr <S550 27Jul88 EMT> |
; bsr GetItemRecord ; look it up <S550 27Jul88 EMT> |
; move.l a0,a2 ; keep string pointer in A2 <S550 27Jul88 EMT> |
; move.l a1,a4 ; keep properties in A4 <S550 27Jul88 EMT> |
bsr DrawTheItem ; call drawing routine (it calls ResetPreviousColors) |
@RedrawDone move.l (sp), -(sp) ; reset clip to region it was before drawing item |
_SetClip |
_DisposRgn |
movem.l (sp)+, a2-a4/d3-d7 ; restore work registers |
INVERTDONE MOVEM.L (SP)+,D3-D4 ; recover work regs |
RTS |
;--------------------------------------- |
; Utility -- GrayRect |
;--------------------------------------- |
; GrayRect is a utility that bit-clears the current "tempRect" with gray |
; |
; We assume that this routine is only called by Draw msg, that SaveCurrentColors <FJL C408> |
; has been called already, and that ResetPreviousColors will be called after this. <FJL C408> |
GRAYRECT |
MOVE.L A0,-(SP) ; push rect address |
MOVE.L (A5),A0 ; get QuickDraw globals |
PEA Gray(A0) ; push gray |
_PenPat ; set pen to it |
MOVE #PatBIC,-(SP) ; push patBIC penMode |
_PenMode ; set penMode |
move #mctRGB2, colorOffset(a6) ; use text color for fore color <FJL C408> |
bsr SetColors ; set colors for bit clear <FJL C408> |
_PaintRect ; "OR" on the dim pattern |
_PenNormal |
RTS |
;--------------------------------------- |
; Utility -- TweakPos |
;--------------------------------------- |
; TweakPos is passed an element size in D0. It gets a horizontal offset into |
; D2 depending on whether things are right justified or not. It also adjusts |
; D5 and D6 (the left and right positions). |
TweakPos |
MOVE D5,D2 ; assume left to right <27Sep85> |
; ADDQ #2,D2 ; and indent element a little <27Sep85> <S550 27Jul88 EMT> |
ADD.W D0,D5 ; assume bump past icon <27Sep85> |
TST.B TESysJust+1 ; check for right just <11oct85> |
BPL.S @1 ; => guessed right <27Sep85> |
SUB.W D0,D6 ; else back up for icon <27Sep85> |
SUB.W D0,D5 ; and fix up left <27Sep85> |
MOVE.W D6,D2 ; and set position <27Sep85> |
@1 RTS |
;--------------------------------------- |
; Utility -- DrawScrolledItem <FJL C838> |
;--------------------------------------- |
; DrawScrolledItem is a faster way to draw the item that appears after a menu is scrolled. |
; The old method was to redraw the whole menu, and because clipping was set to just |
; the item that appeared no flashing occured. The problem is that with the new features, |
; most noticeably color and hierarchical menus, scrolling can be fairly slow. Actually this |
; method turns out to speed up scrolling by a factor of 2-3!! |
; |
DrawScrolledItem |
MOVE.W D4,D2 ; top of menu into D2 |
MOVEQ #1, D4 ; start with first item |
TST D7 |
BGE.S @ScrollingDown ; if D7 >= 0 then scrolling down not up |
@ScrollingUp |
MOVE Bottom(a2), D3 ; fake mouse pt to be just above bottom of menu |
SUBQ #1, D3 ; one pixel above menu bottom, or down scroll arrow |
BRA.S @Loop |
@ScrollingDown |
MOVE Top(a2), D3 ; fake mouse pt to be just below top of menu |
ADDQ #1, D3 ; one pixel below menu top, or up scroll arrow |
@Loop MOVE.L (A3),A0 ; get menuPtr |
MOVE D4,D0 ; get item number |
BSR GetItemRecord ; look it up |
BEQ.S @LastItemSel ; if none then must be last item |
BSR GetItemHeight ; get item height in D0 |
ADD D0,D2 ; update vertical |
CMP D3,D2 ; compare with mouse point |
BGT.S @GotSel ; when D2 is bigger, we found it |
; |
; we didn't reach it yet, so keep stepping down till we do |
; |
ADDQ #1,D4 ; bump to next item |
BRA.S @Loop ; loop till we find it |
; |
; we found it so draw the item |
; |
@LastItemSel |
SUBQ #1, D4 ; back up one item |
@GotSel MOVE D4, D0 ; InvertItem wants item number in D0 |
MOVE #1, scrollFlag(a6) ; set flag for InvertItem <FJL 17Mar87> |
BSR InvertItem ; InvertItem will draw the item |
; Because of fucking icons, there could be just part of the scrolled item showing, so if |
; we are scrolling up then redraw the item above too, or if scrolling down then redraw the |
; item below. |
TST D7 |
BGE.S @ScrollingDown2 ; if D7 >= 0 then scrolling down not up |
@ScrollingUp2 |
SUBQ #1, D4 ; draw item above this one |
MOVE D4, D0 |
BSR InvertItem |
BRA.S @NoItemSel |
@ScrollingDown2 |
ADDQ #1, D4 ; draw item below this one |
MOVE D4, D0 |
BSR InvertItem |
@NoItemSel CLR scrollFlag(a6) ; clear flag after InvertItem call <FJL 17Mar87> |
rts |
;---------------------------------------------------------------------------------------- |
; |
; Msg #0 -- Draw Menu -- bits behind have been saved, menu structure has been drawn, |
; and menu rectangle is cleared to proper color (all by mbarproc) |
; |
;---------------------------------------------------------------------------------------- |
; |
; here is the part of the TextMenuProc that draws the menu. For most of this routine, |
; A3 holds the menuHandle, D4 is the item counter and D3 holds the cumulative |
; vertical position. DrawMenu is broken off for use in scrolling. |
; |
; To clear up a very tricky scrolling menu bug, we need to NOT SCROLL when a hierarchical menu |
; is up in the last item (i.e. topmost or bottommost). If we don't bring the HMenu down first |
; a little bit of garbage is left on the screen. We clear the field mbUglyScroll each |
; time a menu is drawn, then set it when the first time into the scrolling routine. Thereafter |
; we check it and realize that the HMenu is already down, so it's ok to scroll. |
; |
; Changed so that caller sets global TopMenuItem so that can be forced to draw from <FJL C844> |
DoDrawMsg |
bsr GetSizes ; get font info into stackframe |
MOVE.L MMenuRect(A6),A0 ; get menu rect pointer <30Jan86> |
clr atMenuBottom ; clear bottom memory <FJL C222> |
;>>>>>------------- MacPlus/MacSE patches ------------------>>>>> |
IF forRAM THEN |
cmp.w #$FFFF, ROM85 ; on old Mac or MacXL? |
beq.s @SetTMI ; yes -> skip HMenu specific stuff |
; RADIUS patches out complete menu mgr ==> could |
; have GetItemCmd installed, but mbSaveLoc |
; not initialized. |
cmpi.l #$FFFFFFFF, mbSaveLoc ; has the MBDF data structure been initialized? |
beq.s @SetTMI |
move.w #$009F, d0 ; load _Unimplemented number |
_GetTrapAddress ; load _Unimplemented address |
move.l a0, d1 ; copy routine address |
move.w #$004E, d0 ; load _GetItemCmd number |
_GetTrapAddress ,newTool ; load _GetItemCmd address |
cmp.l a0, d1 ; new HMenu Mgr installed? |
bne.s @ScrollClrOK ; yes -> MenuSelect sets TopMenuItem properly |
@SetTMI MOVE.L MMenuRect(A6),A0 ; get menu rect pointer <30Jan86> |
MOVE.W top(A0),topMenuItem ; no -> say to draw from top <30Jan86> |
bra.s @SkipScrollClr ; and skip HMenu specific stuff |
@ScrollClrOK |
ENDIF ; if forRAM |
;<<<<<--------------------------------------<<<<< |
move.l mbSaveLoc, a0 ; clear mbUglyScroll every time draw a menu <FJL C792> |
move.l (a0), a0 |
clr mbUglyScroll(a0) |
@SkipScrollClr |
bsr.s DrawMenu ; call draw menu |
bsr.s ChkScrollIndic ; draw scrolling indicator (if necessary) <FJL C792> |
rts |
;--------------------------------------- |
; Utility -- DrawMenu |
;--------------------------------------- |
DRAWMENU MOVEM.L a2-A4/D3-D7,-(SP) ; save some regs <27Sep85> |
MOVEQ #1,D4 ; start with first item |
MOVE.W topMenuItem,D3 ; and point to top of first item |
ADD.W MAscent(A6),D3 ; add in the ascent for baseline |
; apps that screw around with the wmgrport textfont and textface unwittingly, have <FJL CXXX> |
; menu items show up in the wrong font/face/etc.... |
CLR.L -(SP) ; push empty set for TextFace and TextFont |
_TextFace ; change textface to normal |
_TextFont ; change textfont to normal |
move #srcOr, -(sp) ; set text mode to srcOr <FJL C408> |
_TextMode ; <FJL C408> |
DRAW1MLOOP MOVE.L MMENURECT(A6),A0 ; get menuRect pointer <27Sep85> |
; MOVE.L (A0)+,D5 ; get left edge <27Sep85> <S550 27Jul88 EMT> |
; MOVE.L (A0),D6 ; get right edge, too <27Sep85> <S550 27Jul88 EMT> |
; <S550 27Jul88 EMT> |
; MOVE D4,D0 ; get item number in D0 <S550 27Jul88 EMT> |
; MOVE.L (A3),A0 ; get menu pointer <S550 27Jul88 EMT> |
; BSR GETITEMRECORD ; look it up <S550 27Jul88 EMT> |
; <S550 27Jul88 EMT> |
; MOVE.L A0,A2 ; keep string pointer in A2 <S550 27Jul88 EMT> |
; MOVE.L A1,A4 ; keep properties in A4 <S550 27Jul88 EMT> |
bsr DrawTheItem ; call drawing routine |
BEQ.S DONEDRAW ; if null item, EXIT W/atBottom TRUE <27Sep85> <S550 27Jul88 EMT> |
; |
; we're done with this item so bump to the next one |
; |
cmpi.b #ScriptMenuCmd, itemCmd(a4) ; is there a script defined? <FJL CXXX> |
beq.s @1 ; yes, icon field stores scriptID <FJL CXXX> |
TST.B ITEMICON(A4) ; does it have an icon? |
BEQ.S @1 ; skip if it doesnt |
MOVE.W D7,D0 ; get delta height |
LSR.W #1,D0 ; divide by 2 |
SUB.W D0,D7 ; and get remainder |
ADD D7,D3 ; bump the rest of the difference for icon |
@1 ADD MFHeight(A6),D3 ; bump to next baseline |
ADDQ #1,D4 ; bump to next item |
BRA.s DRAW1MLOOP ; loop till done |
; When we return to DoneDraw, D3 points to the baseline of the cell that would follow the |
; last cell. Back up to the bottom of the last cell and save as menubottom. |
DONEDRAW SUB.W MAscent(A6),D3 ; back up to "top of cell" <30Jan86> |
MOVE.W D3,AtMenuBottom ; update bottom <30Jan86> |
MOVEM.L (SP)+,a2-A4/D3-D7 ; restore some regs <27Sep85> |
RTS |
;--------------------------------------- |
; Utility -- ChkScrollIndic <FJL C792> |
;--------------------------------------- |
; Blit up the scrolling down arrow if we need to |
; |
ChkScrollIndic |
move.l MMenuRect(a6), a0 ; get menu rect ptr |
move AtMenuBottom, d0 ; get AtMenuBottom |
cmp Bottom(a0), d0 ; is AtMenuBottom > bottom of MenuRect |
ble.s @CkUpIndic ; no ==> don't need down arrow, see if need up arrow |
bsr.s BlitDownScrollIndic ; yes ==> blit the down arrow |
@CkUpIndic move.l MMenuRect(a6), a0 ; get menu rect ptr <FJL C844> |
move TopMenuItem, d0 ; get TopMenuItem |
cmp Top(a0), d0 ; is TopMenuItem < top of MenuRect |
bge.s @DoneChk ; no ==> don't need up arrow |
bsr.s BlitUpscrollIndic ; yes ==> blit the up arrow |
@DoneChk rts |
;--------------------------------------- |
; Utility -- BlitDownScrollIndic / BlitUpScrollIndic <FJL C792> |
;--------------------------------------- |
; Blit up the scrolling arrows |
; |
BlitDownScrollIndic |
movem.l a3-a4/d4, -(sp) ; store work registers |
; calculate where bottom of menu is |
move Bottom(a0), HierArrowRect+Bottom(a6) ; store bottom |
move Bottom(a0), HierArrowRect+Top(a6) ; top = bottom - MFHeight |
move MFHeight(a6), d0 |
sub d0, HierArrowRect+Top(a6) |
move Left(a0), HierArrowRect+Left(a6) ; store left |
move Right(a0), HierArrowRect+Right(a6) ; store right |
lea DownArrow, a4 ; store arrow address in a4 for DoTheBlit |
bra.s DoTheBlit |
BlitUpScrollIndic |
movem.l a3-a4/d4, -(sp) ; store work registers |
; calculate where top of menu is |
move Top(a0), HierArrowRect+Top(a6) ; store top |
move Top(a0), HierArrowRect+Bottom(a6) ; bottom = top + MFHeight |
move MFHeight(a6), d0 |
add d0, HierArrowRect+Bottom(a6) |
move Left(a0), HierArrowRect+Left(a6) ; store left |
move Right(a0), HierArrowRect+Right(a6) ; store right |
lea UpArrow, a4 ; store arrow address in a4 for DoTheBlit |
; and drop into DoTheBlit |
DoTheBlit |
bsr SaveCurrentColors ; save current colors in stack frame |
move #-1, d4 ; force SetColors to get the title color |
; entry not an item entry |
move #mctRGB2, colorOffset(a6) ; set fore/back colors for this item |
bsr SetColors ; set proper colors for blit |
; erase rect now that the fore/back colors are set properly |
pea HierArrowRect(a6) |
_EraseRect |
; create bitMap for arrow |
moveq #bitMapRec, d0 ; alloc bitmap for 16Vert x 16Horiz x 1Deep bit map |
_NewHandle |
_HLock |
move.l (a0), a3 ; dereference |
move #2, rowBytes(a3) ; 16 x 1 bits wide |
move.l #$00000000,bounds(a3) ; top = 0, left = 0 |
move.l #$00100010,bounds+4(a3) ; bottom = $10, right = $10 |
move.l a4, baseAddr(a3) ; store correct arrow bitmap in baseAddr |
; set arrow rect |
;+++; left = left + MWidMax |
;+++; right = newleft + MWidMax + 4 |
;+++ move MWidMax(a6), d0 |
;+++ add d0, HierArrowRect+Left(a6) |
;+++ move HierArrowRect+Left(a6), HierArrowRect+Right(a6) |
;+++ add #4, d0 |
;+++ add d0, HierArrowRect+Right(a6) |
; left = MenuRect.left + MWidMax <FJL PMAB205> |
; right = left + min(16,MFHeight(A6)) |
; bottom = top + min(16,MFHeight(A6)) |
move MWidMax(A6), d0 |
add HierArrowRect+Left(A6), d0 |
move d0, HierArrowRect+Left(A6) |
move d0, HierArrowRect+Right(A6) |
moveq #16, d0 |
cmp.w MFHeight(A6), d0 |
bge.s @1 |
move MFHeight(A6), d0 |
@1 add d0, HierArrowRect+Right(A6) |
move HierArrowRect+Top(A6), HierArrowRect+Bottom(A6) |
add d0, HierArrowRect+Bottom(A6) |
; get current portRect |
subq #4, sp |
move.l sp, -(sp) ; make space on stack for return |
_GetPort |
move.l (sp)+, a0 ; get port |
; copy from the bitMap into the port |
move.l a3, -(sp) ; push src bitMap ptr |
pea portBits(a0) ; push dest pointer (for the screen) |
pea bounds(a3) ; push src bounds rect |
pea HierArrowRect(a6) ; push dest bounds rect |
move #srcOr, -(sp) ; srcOr |
clr.l -(sp) ; no maskRgn |
_CopyBits |
move.l a3, a0 ; get bitMap ptr |
_RecoverHandle ; get bitMap handle |
_DisposHandle ; and toss it |
movem.l (sp)+, a3-a4/d4 ; restore work registers |
bsr ResetPreviousColors ; reset colors stored in stackframe |
rts |
;--------------------------------------- |
; Utility -- IsDash |
;--------------------------------------- |
; IsDash is a utility which tests if an item is the special dash separator. |
; It returns the result in the Z-flag <S550 27Jul88 EMT> |
IsDash |
CMP.B #$2D,1(A0) ; first char a dash? |
BNE.S @NoDash ; No dash, skip. |
TST.B itemIcon(A1) ; Does it have an icon? |
BNE.S @NoDash ; No dash, skip. |
TST.B itemCmd(A1) ; Does it have a cmd? |
@NoDash |
RTS ; Return result in Z |
;---------------------------------------- |
; Utility -- DrawTheItem |
;---------------------------------------- |
; separated actual drawing routine out so |
; can ChooseMsg can call it since we now |
; redraw the selected item rather than |
; just inverting it. |
; |
; Used to be: <S550 27Jul88 EMT> |
; On entry: d3 Item's baseline, top of item + font's ascent |
; d4 Item Number |
; d5 left edge, pixels |
; d6 right edge, pixels |
; a2 item's string pointer |
; a4 item's properties pointer |
; -- GetSizes has been called |
; |
; Now: <S550 27Jul88 EMT> |
; On entry: D3 Item's baseline, top of item + font's ascent |
; D4 Item Number |
; A0 Menu rectangle pointer (for left and right edge) |
; A3 Menu handle |
; -- GetSizes has been called |
; -- GetItemRecord has been called |
; -- D5, D6, A2, and A4 are all set up just like old times |
; |
; On exit: Z Set if the item does not exist |
; |
DrawTheItem |
MOVE.W Left(A0), D5 ; Get the left edge <S550 27Jul88 EMT> |
MOVE.W Right(A0), D6 ; Get the right edge <S550 27Jul88 EMT> |
MOVE.W D4, D0 ; Prepare item number for GetItemRecord <S550 27Jul88 EMT> |
MOVE.L (A3), A0 ; Dereference menu handle <S550 27Jul88 EMT> |
BSR GetItemRecord ; Go get it <S550 27Jul88 EMT> |
BEQ NoDrawItem ; Skip whole mess if not a valid item <S550 27Jul88 EMT> |
MOVE.L A0, A2 ; Store string pointer in A2 <S550 27Jul88 EMT> |
MOVE.L A1, A4 ; And properties in A4 <S550 27Jul88 EMT> |
bsr SaveCurrentColors ; save fore/back colors in stackframe <FJL C408> |
MOVE.L A2, A0 ; Get string pointer for IsDash <S550 27Jul88 EMT> |
MOVE.L A4, A1 ; And properties too <S550 27Jul88 EMT> |
BSR.S IsDash ; Is it a dash? <S550 27Jul88 EMT> |
BNE.S NotDash ; If not, draw item normally <S550 27Jul88 EMT> |
;--------------------------------------- |
; Utility -- DrawDash |
;--------------------------------------- |
; handle the case of a dash item by drawing a line |
DrawDash |
move #mctRGB2, colorOffset(a6) ; use the item color if there is an entry <FJL C408> |
bsr SetColors ; set colors <FJL C408> |
MOVE.L (A5),A0 ; get QuickDraw globals |
PEA Gray(A0) ; set pattern to gray |
_PenPat |
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 ; pen back to normal |
BRA DoneDrawItem ; dive back into mainstream |
NotDash |
ADDQ.W #2, D5 ; Add the 2 pixels here instead <S550 27Jul88 EMT> |
cmpi.b #ScriptMenuCmd, itemCmd(a4) ; is there a script defined? <FJL CXXX> |
beq.s DrawMark ; yes, icon field stores scriptID <FJL CXXX> |
MOVE.B ITEMICON(A4),D0 ; does it have an icon? |
BEQ.S DrawMark ; if not, skip |
; for icon, center the baseline in the item's rect |
Bsr GetItemHeightA4 ; get item's height in D0 |
SUB.W MFHeight(A6),D0 ; subtract font height <1Aug85> |
MOVE.W D0,D7 ; save font height in D7 <1Aug85> |
LSR.W #1,D0 ; get delta <1Aug85> |
ADD.W D0,D3 ; keep baseline in D3 <1Aug85> |
; --------------------- draw the mark -------------------------- |
DrawMark MOVE.W MWidMax(A6),D0 ; get char width <27Sep85> |
BSR TweakPos ; get hpos into D2, adjust d5,d6 <27Sep85> |
; When itemCmd == HMenuCmd ($1B) the itemMark field is used to store <FJL C222> |
; the hierarchical menu number so don't draw a mark by mistake. <FJL C222> |
cmpi.b #HMenuCmd, itemCmd(a4) ; hierarchical menu for this item? <FJL C222> |
beq.s ChkDrawIcon |
TST.B ITEMMARK(A4) ; does it have a mark? |
BEQ.S CHKDRAWICON ; if not, skip |
MOVE.W D2,-(SP) ; |
MOVE D3,-(SP) ; push v position |
_MoveTo ; position pen |
move #mctRGB1, colorOffset(a6) ; tell SetColors to get the MARK <FJL C408> |
bsr SetColors ; set mark colors <FJL C408> |
CLR D0 ; clear out high part |
MOVE.B ITEMMARK(A4),D0 ; get the mark character |
MOVE.W D0,-(SP) ; push it |
_DrawChar |
; --------------------- draw the icon -------------------------- |
CHKDRAWICON |
; when itemCmd == ScriptMenuCmd ($1C) the itemIcon field is used to <FJL CXXX> |
; store the script ID number, so don't draw an icon by mistake. <FJL CXXX> |
; when itemCmd == ShrunkenIconCmd ($1D) we draw the icon into a 16x16 <FJL PMAB205> |
; area instead of the normal 32x32 |
; when itemCmd == SmallIconCmd ($1E) we draw a small icon into a 16x16 <FJL PMAB205> |
; area |
; cmpi.b #ScriptMenuCmd, itemCmd(a4) ; script for this item? <FJL CXXX> |
; beq DrawCmdChar |
; |
; TST.B ITEMICON(A4) ; does it have an icon? <15Oct85> |
MOVE.L A4, A1 ; Copy A4 into A1 for GetIconSize <S550 27Jul88 EMT> |
BSR GetIconSize ; Get the height, width of the icon <S550 27Jul88 EMT> |
TST.L D1 ; Is there one? <S550 27Jul88 EMT> |
BEQ DrawCmdChar ; if not, skip |
; |
; get horizontal position into D2 |
; |
; MOVEQ #40,D0 ; get field size (width) for large icon <27Sep85> |
; |
; Cmpi.b #ShrunkenIconCmd, itemCmd(A4) ;is this a shrunken icon ? <FJL PMAB205> |
; Beq.s @SmallDst ; yes -> branch <FJL PMAB205> |
; Cmpi.b #SmallIconCmd, itemCmd(A4) ;is this a small icon ? |
; Bne.s @DoTweak ; no -> branch |
;@SmallDst Bsr GetItemHeightA4 ; get item height for small icons into D0 |
;@DoTweak BSR TweakPos ; get hpos into D2, adjust D5,D6 <27Sep85> |
; draw the icon. First back up to top of rect |
LEA TEMPRECT,A0 ; get pointer to rectangle |
MOVE.L A0,-(SP) ; push rect for plotIcon call |
MOVE.L D1, -(SP) ; Save height, width on stack <S550 27Jul88 EMT> |
MOVE.W D3,D1 ; get baseline <1Aug85> |
MOVE.W D7,D0 ; font height from D7 <15Oct85> |
LSR.W #1,D0 ; get delta <15Oct85> |
SUB.W D0,D1 ; subtract delta <15Oct85> |
SUB.W MAscent(A6),D1 ; subtract font height <15Oct85> |
ADDQ.W #2,D1 ; down from top of item <15Oct85> |
MOVE.L (SP)+, D0 ; Restore it into D0 instead <S550 27Jul88 EMT> |
; cmpi.b #ShrunkenIconCmd, itemCmd(A4); is this a shrunken icon ? <FJL PMAB205> |
; beq.s @SetupSmallDstIcon ; yes -> branch <FJL PMAB205> |
; cmpi.b #SmallIconCmd, itemCmd(A4) ; is this a smallicon ? |
; bne.s @SetupRegularIcon |
; |
;@SetupSmallDstIcon |
; move D1, (A0)+ ; and stuff top |
; move D2, (A0) ; push left |
; subq.w #3, (A0)+ ; fudge to line up small icon on the left |
; move.l -4(A0),(A0) ; copy bottom/right |
; add #16, (A0)+ ; bottom := top + 16 |
; add #16, (A0) ; right := left + 16 |
; bra.s @DoneSetup |
; |
; |
;@SetupRegularIcon |
MOVE.W D1,(A0)+ ; and stuff top <1Aug85> |
MOVE.W D5, D2 ; Assume left-to-right <S550 27Jul88 EMT> |
TST.B TESysJust+1 ; Test for right just <S550 27Jul88 EMT> |
BPL.S @LeftRight ; Guessed right <S550 27Jul88 EMT> |
MOVE.W D6, D2 ; Otherwise get right side <S550 27Jul88 EMT> |
SUB.W D0, D2 ; And subtract out width <S550 27Jul88 EMT> |
@LeftRight ; <S550 27Jul88 EMT> |
MOVE.W D2,(A0)+ ; push left <27Sept85> <S550 27Jul88 EMT> |
; ADDQ.W #3,(A0)+ ; indent a little <15Oct85> |
MOVE.L -4(A0),(A0) ; copy bottom right |
ADD.L D0, (A0) ; Add height, width to get bottom, right <S550 27Jul88 EMT> |
; ADD #32,(A0)+ ; bottom := top + 32 |
; ADD #32,(A0) ; right := left + 32 |
;@DoneSetup |
ADD.W MSpaceWidth(A6), D0 ; Add single space to width of icon <S550 27Jul88 EMT> |
BSR TweakPos ; get hpos into D2, adjust D5,D6 <S550 27Jul88 EMT> |
;>>>>>------------- NuMac ------------------>>>>> |
;+++ IF onNuMac THEN |
tst.b onColorMachine(a6) |
beq.s @DoPlotIcon |
; attempt to get color icon first and if unsuccessful then get regular icon <FJL C408> |
subq #4, sp ; make room for function result |
move #$0100, d0 ; menu icons are 256-511 |
move.b itemIcon(a4), d0 ; get icon number - 256 |
move d0, -(sp) ; push icon number |
_GetCIcon |
move.l (sp)+, iconHandle(a6) ; get icon handle, and save in stackframe |
beq.s @DoPlotIcon ; no color icon, must be regular icon |
; check to be sure icon is <= 32 x 32 |
; no longer care about icon size <S550 27Jul88 EMT> |
; move.l iconHandle(a6), a0 ; get icon handle |
; move.l (a0), a0 ; dereference, a0 points at pixMap |
; move.l pBounds+Top(a0), d0 ; get top, left |
; move.l pBounds+Bottom(a0), d1 ; get bottom, right |
; sub d0, d1 ; width = right - left |
; cmp #32, d1 ; width == 32 ? |
; bne.s @DispIcon ; if not then don't plot it |
; swap d0 |
; swap d1 |
; sub d0, d1 ; height = bottom - top |
; cmp #32, d1 ; height == 32? |
; bne.s @DispIcon ; if not then don't plot it |
; force colors to black on white for PlotCIcon regardless of InvertFlag, |
; unless it's 1 or 2 bit mode in which case we want it white on black so icon mask |
; is inverted properly |
cmpi.w #4, PixelDepth(a6) ; is this 4+ mode ? |
blt.s @FunkySettings ; no, so branch and do funky color setting |
pea RGBBlack ; in 4+ mode force black on white always |
_RGBForeColor |
pea RGBWhite |
_RGBBackColor |
bra.s @1 |
@FunkySettings ; in 1 or 2 bit, use black on white for normal |
; and white on black for selected |
pea RGBBlack |
pea RGBWhite |
tst invertFlag(a6) ; invert mode? |
bne.s @2 ; yes --> branch |
_RGBBackColor |
_RGBForeColor |
bra.s @1 |
@2 _RGBForeColor |
_RGBBackColor |
; everything checks out so plot it |
@1 move.l iconHandle(a6), -(sp) ; got a color icon so push it on the stack |
_PlotCIcon ; rect is already on the stack |
;@DispIcon does not properly clean up stack. Good thing we don't use it anymore. |
move.l iconHandle(a6), -(sp) ; dispose of CIcon |
_DisposCIcon |
bra.s DrawCmdChar ; and continue |
;+++ ENDIF |
;<<<<<--------------------------------------<<<<< |
@DoPlotIcon |
Cmpi.B #SmallIconCmd, itemCmd(A4) ; is it a small icon ? <FJL PMAB205> |
Bne.S @GetLargeIcon ; no -> get large icon |
Clr.L -(SP) ; yes -> get small icon |
Move.L #'SICN', -(SP) ; push res type |
Bra.S @GetIconCommon ; and use common code |
@GetLargeIcon |
CLR.L -(SP) ; make room for function result |
MOVE.L #'ICON',-(SP) ; push the resource type |
@GetIconCommon |
MOVE.W #$0100,D0 ; menu icons are 256-511 |
MOVE.B ITEMICON(A4),D0 ; does it have an icon? |
MOVE D0,-(SP) ; push icon number |
_GetResource ; get the icon handle |
move.l #$00100010, D0 ; assume src icon is 16x16 |
moveq #2, D1 ; and rowbytes is 2 |
cmpi.b #SmallIconCmd, itemCmd(a4) ; is it? |
beq.s @PushIconSrcSize ; yes -> branch |
add.l d0,d0 ; double it to make 32x32 |
add.l d1,d1 ; double rowbytes too |
@PushIconSrcSize |
move.l d0,-(sp) ; push size |
move d1,-(sp) ; push rowbytes |
move #mctRGB2, colorOffset(a6) ; use the item color if there is an entry <FJL C408> |
bsr SetColors ; set colors <FJL C408> |
@PlotIt bsr PlotAnySizeIcon ; plot the icon <FJL PMAB205> |
@DonePlot |
; --------------------- draw the command character -------------------------- |
DrawCmdChar |
TST.B ITEMCMD(A4) ; is there one? |
BEQ.S DRAWITEXT ; if not, skip |
cmpi.b #ScriptMenuCmd, itemCmd(a4) ; script for this item? <FJL CXXX> |
beq.s DrawIText ; if so, skip <FJL CXXX> |
cmpi.b #ShrunkenIconCmd, itemCmd(a4) ; shrunken icon? <FJL PMAB205> |
beq.s DrawIText ; if so, skip |
cmpi.b #SmallIconCmd, itemCmd(a4) ; small icon? <FJL PMAB205> |
beq.s DrawIText ; if so, skip |
move #mctRGB3, colorOffset(a6) ; tell SetColors to get the CMD <FJL C408> |
bsr SetColors ; set colors for command character <FJL C408> |
MOVE.W MWidMax(A6),D0 ; get width <27Sep85> |
ADD.W D0,D0 ; *2 <27Sep85> |
SUB.W D0,D6 ; assume it will go on right <27Sep85> |
MOVE D6,-(SP) ; put it on stack <27Sep85> |
TST.B TESysJust+1 ; check for right just <11oct85> |
BPL.S @1 ; => guessed right <27Sep85> |
ADDQ #2,D5 ; else indent a little FIRST <S550 27Jul88 EMT> |
MOVE.W D5,(SP) ; else do it from left <27Sep85> |
ADD.W D0,D5 ; and bump left position <27Sep85> |
ADD.W D0,D6 ; else back up for icon <27Sep85> |
@1 MOVE.W D3,-(SP) ; push vertical position |
_MoveTo ; position pen |
; |
; if this item has a sub-menu, then blit an arrow in the command key <FJL C222> |
; field to indicate its existence . <FJL C222> |
; |
cmpi.b #HMenuCmd, itemCmd(a4) ; is there a H Menu? <FJL C222> |
bne.s @NormalCmd ; no, so do as normal <FJL C222> |
bsr BlitHierArrow ; draw the Hierarchical arrow |
bra.s DrawIText ; continue <FJL C222> |
@NormalCmd MOVE.B TESysJust+1,D1 ; need special justification? <FJL CXXX> |
EXT.W D1 ; make it a signed word <FJL CXXX> |
BNE.S @JustifiedCmd ; => yes <FJL CXXX> |
MOVE.W #commandMark,-(SP) ; push command mark (propeller) <15Feb85> |
_DrawChar ; draw the character |
CLR D0 ; clear high part |
MOVE.B ITEMCMD(A4),D0 ; get command character |
MOVE.W D0,-(SP) ; push command char |
_DrawChar ; draw it |
bra.s DrawIText ; and continue |
@JustifiedCmd ; draw commandletter/propeller <FJL CXXX> |
CLR D0 ; clear high part |
MOVE.B ITEMCMD(A4),D0 ; get command character |
MOVE.W D0,-(SP) ; push command char |
_DrawChar ; draw it |
MOVE.W #commandMark,-(SP) ; push command character <15Feb85> |
_DrawChar ; draw the character |
; ---------------- draw the text of the item (position in D5) ---------------------- |
DRAWITEXT |
move #mctRGB2, colorOffset(a6) ; tell SetColors to get the TEXT <FJL C408> |
bsr SetColors ; set colors for text <FJL C408> |
CLR D0 ; clear it out |
MOVE.B ITEMSTYLE(A4),D0 ; push the style parameter |
MOVE.W D0,-(SP) ; push style parameter |
_TextFace ; get into that face |
; if there is a script for this font then set it |
cmpi.b #ScriptMenuCmd, itemCmd(a4) ; script for this item? <FJL CXXX> |
bne.s @1 ; no, so skip <FJL CXXX> |
move.b itemIcon(a4), d0 ; pass script number <S422 08Mar88 MED> |
bsr SetScriptFont ; yes, so set the proper font <FJL CXXX> |
@1 MOVE.B TESysJust+1,D1 ; need special justification? <11oct85> |
EXT.W D1 ; make it a signed word <11oct85> |
BNE.S @DrawIntl ; => yes <27Sep85> |
MOVE.W D5,-(SP) ; and baseline left <27Sep85> |
MOVE.W D3,-(SP) ; else push baseline vertical <27Sep85> |
_MoveTo ; push the pen <27Sep85> |
MOVE.L A2,-(SP) ; point to the string <27Sep85> |
_DrawString ; and draw it <27Sep85> |
BRA.S @2 |
; |
; do International stuff here if TESysJust is negative |
; |
@DrawIntl LEA TempRect,A0 ; build rect for TextBox <27Sep85> |
SUBQ #1,D5 ; textBox indents by one <27Sep85> |
MOVE.W D3,(A0) ; get y position <27Sep85> |
MOVE.W MAscent(A6),D0 ; move up to top of rect <27Sep85> |
SUB.W D0,(A0)+ ; <27Sep85> |
MOVE.W D5,(A0)+ ; D5 is left <27Sep85> |
MOVE.W D3,(A0) ; as top and bottom <27Sep85> |
MOVE.W MDescent(A6),D0 ; and move down to bottom <27Sep85> |
ADD.W D0,(A0)+ ; <27Sep85> |
MOVE.W D6,(A0) ; and setup right <27Sep85> |
MOVEQ #0,D0 ; get length <27Sep85> |
MOVE.B (A2)+,D0 ; into D0 <27Sep85> |
MOVE.L A2,-(SP) ; push text pointer <27Sep85> |
MOVE.L D0,-(SP) ; and length <27Sep85> |
PEA TempRect ; push rect of rects <27Sep85> |
MOVE.W D1,-(SP) ; and justification word <11oct85> |
_TextBox |
@2 CLR.L -(SP) ; push empty set for TextFace and TextFont |
_TextFace ; restore textface to normal |
_TextFont ; restore textfont to normal |
; |
; if the item is disabled, gray it out |
; |
BSR ENABLETEST ; is it enabled? |
BNE.S DoneDrawItem ; branch if it is |
bsr.s BitClearItem ; bit clear the item, notice that colors are set properly |
DoneDrawItem |
bsr ResetPreviousColors ; restore colors saved in the stackframe <FJL C408> |
MOVEQ #1, D0 ; Force Z flag off for normal return <S550 27Jul88 EMT> |
NoDrawItem ; <S550 27Jul88 EMT> |
; Z flag is already set <S550 27Jul88 EMT> |
rts ; and return to caller |
;--------------------------------------- |
; Utility -- BitClearItem ; attempt to speed graying of menu items <FJL 26Jan87> |
;--------------------------------------- |
; Paint the item with gray. Speed up is about 20%!! |
; |
; On Entry: D4 item number |
; |
BitClearItem |
movem.l d3/d7, -(sp) ; save work registers |
TST.B ITEMICON(A4) ; does it have an icon? |
BEQ.S @1 ; skip if it doesnt |
MOVE.W D7,D0 ; get delta height |
LSR.W #1,D0 ; divide by 2 |
SUB.W D0,D7 ; and get remainder |
ADD D7,D3 ; bump the rest of the difference for icon |
@1 ADD MFHeight(A6),D3 ; bump to next baseline |
LEA TEMPRECT,A0 ; get pointer to temporary rectangle |
MOVE.L MMenuRect(a6), A1 ; get pointer to menu rect |
MOVE.L (A1),(A0) ; copy menuRect into tempRect |
MOVE.L 4(A1),4(A0) |
SUB MAscent(A6), D3 ; move up by the fon't ascent to get bottom of item |
MOVE D3, Bottom(A0) ; store as bottom |
Bsr GetItemHeightA4 ; get item height into D0 <FJL PMAB205> |
Sub.W D0, D3 |
lea TempRect,a0 ; get rectangle in A0 <1.7> |
MOVE D3,top(a0) ; D3 has the height <1.6> <1.7> |
BSR GRAYRECT ; bit clear tempRect with gray |
@ClearDone |
movem.l (sp)+, d3/d7 ; restore work registers |
rts |
;--------------------------------------- |
; Utility -- SetScriptFont |
;--------------------------------------- |
; Input d0: script number |
; |
; set the script's base font. No need to check if script manager is installed |
; since AddResMenu has already done that |
; |
SetScriptFont |
clr.l -(sp) ; make room for long result |
;; clr d0 ; clear lo-word |
;; move.b itemIcon(a4), d0 ; get script number |
; make d0 an argument, the script number <S422 08Mar88 MED> |
and.w #$00FF,d0 ; get bottom byte for script <S422 08Mar88 MED> |
move d0, -(sp) ; push script number |
move #smScriptSysFond, -(sp) ; push base font verb |
_GetScript |
move.l (sp)+, d0 ; get result |
blt.s @verbErr ; verb error if d0 < 0 |
move d0, -(sp) ; push font number |
_TextFont |
@verbErr rts |
;--------------------------------------- |
; Utility -- BlitHierArrow |
;--------------------------------------- |
; Blit up the hierarchical arrow |
; |
BlitHierArrow |
movem.l a3/d4, -(sp) ; store work registers |
; calculate where arrow should go |
subq #4, sp |
move.l sp, -(sp) ; reserve space on stack for result |
_GetPen |
move.l (sp)+, d4 ; get y,x |
swap d4 ; get x,y |
sub MAscent(a6), d4 ; move up by the fon't ascent to get top of item |
swap d4 ; have top, left of where will blit arrow |
move.l d4, HierArrowRect(a6) ; store top, left |
move.l d4, HierArrowRect+4(a6) ; calculate bottom, right |
move MFHeight(a6), d4 ; get height |
cmpi #16, d4 ; make height/width = 16 unless smaller than 16.<FJL PMAB205> |
ble.s @1 |
move #16, d4 |
@1 add d4, HierArrowRect+Bottom(a6); bottom = top + height |
add d4, HierArrowRect+Right(a6) ; right = left + width |
; create bitMap for arrow |
moveq #bitMapRec, d0 ; alloc bitmap for 16Vert x 16Horiz x 1Deep bit map |
_NewHandle |
_HLock |
move.l (a0), a3 ; dereference |
move #2, rowBytes(a3) ; 16 x 1 bits wide |
move.l #$00000000,bounds(a3) ; top = 0, left = 0 |
move.l #$00100010,bounds+4(a3) ; bottom = 0, right = 0 |
lea HierArrow, a1 ; get mask data address |
move.l a1, baseAddr(a3) ; store it |
; get current portRect |
CommonBlit subq #4, sp |
move.l sp, -(sp) ; make space on stack for return |
_GetPort |
move.l (sp)+, a0 ; get port |
; copy from the bitMap into the port |
move.l a3, -(sp) ; push src bitMap ptr |
pea portBits(a0) ; push dest pointer (for the screen) |
pea bounds(a3) ; push src bounds rect |
pea HierArrowRect(a6) ; push dest bounds rect |
move #srcOr, -(sp) ; srcOr |
clr.l -(sp) ; no maskRgn |
_CopyBits |
move.l a3, a0 ; get bitMap ptr |
_RecoverHandle ; get bitMap handle |
_DisposHandle ; and toss it |
movem.l (sp)+, a3/d4 ; restore work registers |
rts |
;--------------------------------------- |
; Utility -- GetItemRecord |
;--------------------------------------- |
; GetItemRecord is the main utility used for accessing the menu item data structure. |
; It has a register interface to save code. On entry, A0 points to a menuInfo block, |
; while D0 has the item number of interest. On exit, A0 points to the item string |
; of interest while A1 points to that item's attribute byte list. If the item can't |
; be found, A0 and A1 both return NIL. |
; |
; TODO: If this is called inside a loop, then we have a factorial function!! |
; Therefore look where this is called from and see if we can't be smarter about |
; how to move thru the menulist |
GETITEMRECORD |
TST D0 ; make sure item number is valid |
BLE.S NOITEM ; if it's not, don't bother |
; |
MOVEQ #0,D1 ; clear D1 for byte arithmetic |
LEA MENUDATA(A0),A1 ; get menuData handle |
MOVE.B (A1)+,D1 ; get title length |
ADD D1,A1 ; skip over title string |
; |
; here is the item search loop. A1 points to the beginning of the next item. |
; |
GETILOOP SUBQ #1,D0 ; is this the one we're looking for? |
BEQ.S GOTITEM ; if so, we got it |
MOVE.B (A1)+,D1 ; get length of current item |
BEQ.S NOITEM ; length zero marks end of list |
; |
ADDQ #4,D1 ; there are 4 bytes of item properties |
ADD D1,A1 ; bump to next item |
BRA.S GETILOOP ; loop till done |
; |
; the item couldn't be found so return NIL |
; |
NOITEM SUB.L A0,A0 ; zero A0 |
MOVE.L A0,A1 ; and A1 too |
MOVE.L A0,D0 ; and set the z-flag |
CLR.L lastItemStrPtr(A6) ; <KSM/RLC 31May89> |
CLR.L lastAttrPtr(A6) ; <KSM/RLC 31May89> |
RTS ; return to caller |
; |
; we found the item so return a pointer to it in A0 and a pointer to the item properties |
; in A1 |
; |
GOTITEM TST.B (A1) ; is this the NIL item? |
BEQ.S NOITEM ; if so, we really didn't get one |
; |
MOVE.L A1,A0 ; A0 points to item string |
MOVE.B (A1)+,D1 ; get length |
ADD D1,A1 ; bump to item properties |
MOVE.L A0,lastItemStrPtr(A6) ; <KSM/RLC 31May89> |
MOVE.L A1,lastAttrPtr(A6) ; <KSM/RLC 31May89> |
RTS ; return to caller |
;---------------------------------------------------------------------------------------- |
; |
; Msg #2 -- Calc Menu Size |
; |
;---------------------------------------------------------------------------------------- |
; Calculate the menu size for the given text menu. The handle is in A3. |
; |
; DONE: <FJL PMAB205> Menus with icons did not show scroll arrows properly after you had |
; scrolled all the way up, then start to scroll down again. The reason |
; was that the menu height is not an even multiple of MFHeight. |
; This code returns an even multiple of MFHeight if the menu scrolls. |
DoCalcMsg |
IF forRAM THEN |
SUBQ #4,SP |
MOVE.L SP,-(SP) ; point to top of stack |
_GetPort ; get the current port |
; CMP.W #$3FFF, ROM85 ; color machine ? <PMAB364 23Jan88 EMT> |
TST.B onColorMachine(A6) ; color machine ? <S394 12Feb88 DBG> |
BEQ.S @SetBWPort ; <PMAB364 23Jan88 EMT> |
MOVE.L WMgrCPort, -(SP) ; get color port <PMAB364 23Jan88 EMT> |
BRA.S @SetPort ; <PMAB364 23Jan88 EMT> |
@SetBWPort ; <PMAB364 23Jan88 EMT> |
MOVE.L WmgrPort,-(SP) ; push the wmgr port, do not use color port here. |
@SetPort ; <PMAB364 23Jan88 EMT> |
_SetPort ; set it <PMAB364 23Jan88 EMT> |
ENDIF ; if forRAM |
; since calc msg could be called at any time, we need to reset the wmgr's textfont here else |
; could get incorrectly sized menus |
clr -(sp) ; clear stack for TextFont <FJL CXXX> |
_TextFont ; use system font in menus <FJL CXXX> |
bsr GetSizes ; get font sizes from wmgr port <FJL CXXX> |
SUBQ.L #4, SP ; <PMAB364 23Jan88 EMT> |
MOVE.L SP, -(SP) ; <PMAB364 23Jan88 EMT> |
_GetPort ; Get the current port <PMAB364 23Jan88 EMT> |
MOVE.L (SP)+, A0 ; Put it in A0 <PMAB364 23Jan88 EMT> |
; MOVE.L WMgrPort,A0 ; get the port <27Sep85> |
MOVE.W PortRect+bottom(A0),D5 ; get the screen bottom <27Sep85> |
SUB.W portRect+top(A0), D5 ; subtract the top <S476 22Apr88 EMT> |
; the maximum size for a menu is screen height minus menubar height minus a fudge factor. |
GetMBHeight |
TST.W ROM85 ; running on new roms? <EHB 26Aug85> |
BMI.S @0 ; => no, use old menubar height <EHB 26Aug85> |
SUB.W MBarHeight,D5 ; get what low memory says <EHB 5Aug85> |
BNE.S @1 ; => it's a good height <EHB 5Aug85> |
@0 SUB.W #20,D5 ; else stuff default height <EHB 5Aug85> |
@1 |
sub #16, d5 ; hierarchical menus need a little more margin <FJL C222> |
; make d5 an even multiple of MFHeight so that scrolling with different sized items <FJL PMAB205> |
; will work properly. |
;+++ dc.w $a9ff |
;+++ Divu MFHeight(A6), d5 ; (max menu height) div (MFHeight) |
;+++ Move D5,D6 ; get quotient |
;+++ MoveQ #0,D5 ; clear D5 |
;+++ Move D6,D5 ; return quotient |
;+++ Mulu MFHeight(A6), D5 ; max menu height = MFHeight x quotient |
MOVEQ #0,D6 ; set initial <height,width> to 0 |
MOVEQ #1,D0 ; find item 1 |
MOVE.L (A3),A0 ; point to the menuRecord |
BSR.S GetItemRecord ; point to first item |
BEQ DoCalcDone1 ; if zero, we're done <EHB 10-Apr-85> |
MOVE.L A0,A4 ; keep pointer in A4 |
; |
; here is the main loop of calcMenuSize. Process each item one at a time, keeping the |
; height and maximum width in D6 |
; |
CMLOOP |
MOVEQ #0,D7 ; set "extra" width to zero |
MOVE.L (A3),A0 ; handle -> pointer |
MOVEQ #0,D0 ; clear out high part |
MOVE.B (A4),D0 ; get length of item |
BEQ DoCalcDone ; if zero, we're done with this menu |
LEA 1(A4,D0),A1 ; point A1 at the properties |
; handle the vertical |
BSR GetItemHeight ; get height of item into D0 |
SWAP D1 ; Get width of icon into low word <S550 27Jul88 EMT> |
MOVE.W D1, D7 ; Copy width into D7 <S550 27Jul88 EMT> |
ADD.W MSpaceWidth(A6), D7 ; Add in width of a single space <S550 27Jul88 EMT> |
; cmpi.b #ScriptMenuCmd, itemCmd(a1) ; is there a script defined? <FJL CXXX> |
; beq.s @0 ; yes, icon field stores scriptID <FJL CXXX> |
; |
; TST.B ITEMICON(A1) ; is there an icon for this item? |
; BEQ.S @0 ; if not, don't adjust height |
; MOVEQ #40,D7 ; add 40 to width for icons |
; MOVEQ #36,D0 ; and 36 to height for icons <27Sep85> |
; |
; Cmpi.B #ShrunkenIconCmd, itemCmd(A1) ; is there a shrunken icon? <FJL PMAB205> |
; Beq.s @NewWidth ; yes -> different width |
; Cmpi.B #SmallIconCmd, itemCmd(A1) ; is there a small icon ? |
; Bne.S @0 ; no -> branch |
;@NewWidth MoveQ #20, D7 ; yes -> width is half size of regular icon |
; Bsr GetItemHeight ; get height into D0 |
@0 SWAP D6 ; get vertical into low word <27Sep85> |
ADD.W D0,D6 ; increment vertical height <27Sep85> |
CMP.W D5,D6 ; past bottom of screen? <27Sep85> |
BLT.S @1 ; => no <27Sep85> |
SUB.W D0,D6 ; yes, don't make menu taller <27Sep85> |
; handle the horizontal |
@1 SWAP D6 ; but get vertical in high first <27Sep85> |
MOVE.W MWidMax(A6),D1 ; get char width <1Aug85> |
ADD.W D1,D7 ; add once for mark <1Aug85> |
cmpi.b #ScriptMenuCmd, itemCmd(a1) ; is there a script defined? <FJL CXXX> |
beq.s @2 ; yes, then no command <FJL CXXX> |
cmpi.b #ShrunkenIconCmd, itemCmd(a1) ; is there a shrunken icon? <FJL PMAB239> |
beq.s @2 ; yes, then no command <FJL PMAB239> |
cmpi.b #SmallIconCmd, itemCmd(a1) ; is there a small icon defined? <FJL PMAB239> |
beq.s @2 ; yes, then no command <FJL PMAB239> |
TST.B ITEMCMD(A1) ; is there a commmand? |
BEQ.S @2 ; if not, skip |
ADD.W D1,D7 ; add twice for command equivalent <1Aug85> |
ADD.W D1,D7 ; <1Aug85> |
ADD.W #8,D7 ; plus an eight pixel margin <1Aug85> |
@2 |
MOVEQ #0,D1 ; clear out high byte |
MOVE.B ITEMSTYLE(A1),D1 ; get style setting |
@3 MOVE.W D1,-(SP) ; push the style |
_TextFace ; tell LisaGraf about new style |
; |
; If there is a script defined for this item, then set font for proper string width calc, |
; do calc, and restore font to #0. |
; |
cmpi.b #ScriptMenuCmd, itemCmd(a1) ; is there a script defined? <FJL CXXX> |
bne.s @NoScript ; yes, icon field stores scriptID <FJL CXXX> |
;; clr d0 ; clear it out <FJL CXXX> |
;; move.b itemCmd(a1), d0 ; get scriptID <FJL CXXX> |
;; mulu #512, d0 ; calculate font num = ID*512-512+$4000 <FJL CXXX> |
;; addi #$3C00, d0 ; <FJL CXXX> |
;; move d0, -(sp) ; push font num <FJL CXXX> |
;; _TextFont ; and set font <FJL CXXX> |
; use utility routine for setting the font from the script |
move.b itemIcon(a1), d0 ; pass script number <S422 08Mar88 MED> |
bsr SetScriptFont ; set TextFont according to script <S422 08Mar88 MED> |
clr -(sp) ; make room for StringWidth result <FJL CXXX> |
move.l a4, -(sp) ; move string pointer <FJL CXXX> |
_StringWidth ; find out the width <FJL CXXX> |
clr -(sp) ; restore font to normal <FJL CXXX> |
_TextFont ; <FJL CXXX> |
bra.s @ContCalc ; and continue with the calculation <FJL CXXX> |
@NoScript CLR -(SP) ; make room for stringWidth result |
MOVE.L A4,-(SP) ; move string pointer |
_StringWidth ; find out the width |
@ContCalc ADD.W (SP)+,D7 ; add width to extra |
CMP D7,D6 ; compare with maxWidth |
BGE.S CALCNEXT ; if max is bigger, go process next one |
MOVE D7,D6 ; this one was the biggest |
; |
; go process next item; loop till we get a null one |
; |
CALCNEXT |
MOVEQ #0,D0 ; zero high part |
MOVE.B (A4),D0 ; get the length of current item |
LEA 5(A4,D0),A4 ; point to the next item |
BRA CMLOOP ; loop till done |
; we've scanned all the items update menuHeight and menuWidth |
DoCalcDone ADDQ.W #4,D6 ; add some extra for right margin |
DoCalcDone1 ; if NIL menu, return 0 <EHB 10-Apr-85> |
; Ensure that the menu is not too wide. |
SUBQ.L #4, SP ; <PMAB364 23Jan88 EMT> |
MOVE.L SP, -(SP) ; <PMAB364 23Jan88 EMT> |
_GetPort ; Get the current port <PMAB364 23Jan88 EMT> |
MOVE.L (SP)+, A0 ; Put it in A0 <PMAB364 23Jan88 EMT> |
MOVE.W portRect+Right(A0), D0 ; Get right edge <PMAB364 23Jan88 EMT> |
SUB.W portRect+Left(A0), D0 ; Subtract left edge to get width <PMAB364 23Jan88 EMT> |
SUB.W #16, D0 ; Subtract a little more for margin <PMAB364 23Jan88 EMT> |
CMP.W D0, D6 ; Is menu too wide? <PMAB364 23Jan88 EMT> |
BLE.S @1 ; Nope, move along <PMAB364 23Jan88 EMT> |
MOVE.W D0, D6 ; Too wide, clip its wings <PMAB364 23Jan88 EMT> |
@1 ; <PMAB364 23Jan88 EMT> |
MOVE.L (A3),A0 ; get menu pointer |
MOVE.W D6,MENUWIDTH(A0) ; update menu width |
SWAP D6 |
; if menu is taller than max allowable (which is now an even multiple of MFHeight) <FJL PMAB205> |
; then make it equal to the max allowable. |
;+++ Cmp.W D5,D6 ; too tall ? |
;+++ Blt.S @SizeOK ; => no |
;+++ Move.W D5,D6 ; yes, make it equal to max allowable |
@SizeOK |
MOVE.W D6,MENUHEIGHT(A0) ; update menu height |
CLR.W -(SP) ; better restore style to normal |
_TextFace ; set the style |
IF forRAM THEN |
_SetPort ; restore original grafPort <PMAB364 23Jan88 EMT> |
ENDIF ; if forRAM |
rts ; all done! so return to dispatcher |
;---------------------------------------------------------------------------------------- |
; |
; Msg #3 -- Calc TopMenuItem and MenuRect so that the top of PopUpItem is at TopLeft |
; |
;---------------------------------------------------------------------------------------- |
; Begin by calculating how far the top of WhichItem is from the top of the menu. |
; Then place the menu. The various possibilities are: |
; 1. The whole menu fits on the screen and PopUpItem lines up with TopLeft |
; 2. The whole menu fits on the screen and PopUpItem cannot line up with TopLeft without |
; causing the menu to scroll. In this case adjust menuRect so that complete menu is |
; is on the screen, but PopUpItem is as close to TopLeft as possible. |
; 3. The whole menu is not on the screen. In this case adjust the menuRect so that as much |
; of the menu is showing as possible on the screen, and position PopUpItem so that |
; it is showing and as close as possible to TopLeft. |
; |
; Return the MenuRect and TopMenuItem. TopMenuItem is returned in the VAR PopUpItem param.; |
; |
; Historical Note: It would be desireable to have popups change vertical size as they scrolled, |
; instead of having all that white space when the scrolling menu is first |
; displayed. The reason for this is due to the design of the MBDF. |
; The MBDF saves the bits behind and draws the drop shadow at the same |
; time. If there were two messages instead, one to save the bits behind |
; and one to draw the drop shadow, the we could save all of the bits behind |
; the menurect, from the top of the screen to the bottom, and then change |
; the menu's vertical height without worrying about saving more bits each |
; time it got bigger. But we can't, so... |
; |
; <FJL PMAB205> Pass PopUpItem = 0 and force top of menuRect to Top parameter |
DoPopUpItemMsg |
BSR GetSizes ; get font info into the stack |
MOVE.L MPopUpItem(A6), A4 ; get ptr to PopUpItem |
MOVE (A4), D3 ; store item in D3 |
CLR D2 ; top of menu starts at zero |
CLR D6 ; ditto |
;+++ Tst.W D3 ; item == 0 ? <FJL PMAB234><FJL PMAB276> |
;+++ Beq.S @LoopComplete ; yes -> special case <FJL PMAB234><FJL PMAB276> |
MOVEQ #1, D4 ; start with first item |
@Loop CMP D3,D4 ; have we reached the PopUpItem yet? |
BGT.S @1 ; no ==> continue calculating <FJL PMAB205><FJL PMAB234> |
MOVE D6, D2 ; yes ==> save item's vertical in D2, and continue |
; |
; We didn't reach it yet, so get the height and keep stepping down. |
; |
@1 MOVE.L (A3),A0 ; get menuPtr |
MOVE D4,D0 ; get item number |
BSR GetItemRecord ; look it up |
BEQ.S @LoopComplete ; if item not found then must be end of item list |
BSR GetItemHeight ; get item height in D0 |
ADD D0,D6 ; update vertical |
ADDQ #1,D4 ; bump to next item |
BRA.S @Loop ; loop till we get to end of item list |
; If we couldn't find the item then default to item number 1 |
@LoopComplete |
TST D2 ; is D2 still zero ? |
BNE.S @GotItem ; no ==> got the item, and it's vertical is in D2 |
MOVEQ #1, D4 ; yes ==> couldn't find item, use item #1 |
; Distance from top of menu to top of PopUpItem is now in D2. |
@GotItem MOVE.L (A3), A0 ; get menu ptr |
TST.L MenuWidth(A0) ; is the size valid? |
BPL.S @SkipCalcSize ; yes, so no need to recalc (oooohhhh, recursion) |
MOVE.L D2, -(SP) ; Save D2 around call <S171 DBG&JTC 08Apr87> |
MOVE.L A3, -(SP) ; push menu handle |
_CalcMenuSize ; get valid height and width |
MOVE.L (SP)+, D2 ; Restore D2 <S171 DBG&JTC 08Apr87> |
@SkipCalcSize |
; |
; First check if menu has to scroll, i.e. its height is larger than the screen size |
; minus 8 pixels of slop. <FJL PMAB205, no longer include menubar height in this calc> |
; |
; Register Usage:-- A0 menuRect ptr |
; A1 port ptr |
; A2 menu ptr |
; A3 menu handle |
; A4 PopUpItem ptr |
; -- D2 Distance from top of menu to PopUpItem |
; D3 PopUpItem |
; D4 TopMenuItem |
; D5 Desired top of PopUpItem, the "Top" in MLeftTop |
; D6 Total menu height, including all menu items |
; |
SUBQ #4, SP ; get current portRect |
MOVE.L SP, -(SP) ; make space on stack of return |
_GetPort |
MOVE.L (SP)+, A1 ; put port in A1 |
MOVE.L MMenuRect(A6), A0 ; put ptr to menuRect in A0 |
MOVE.L (A3), A2 ; put menu ptr in A2 |
MOVE MLeftTop+2(a6), D5 ; put desired Top of PopUpItem in D5 |
MOVE D5, D4 ; put TopMenuItem = D5 - D2 in D4 |
SUB D2, D4 |
Cmpi.w #0, D3 ; is PopUpItem = 0 ? <FJL PMAB205> |
Bne.s @StdPopUp ; no -> branch |
Move portRect+Bottom(A1),D0 ; calc max allowable menu height = bottom of |
Sub D5, D0 ; screen - 8 - Top of PopUpItem |
Sub #8, D0 |
Cmp D6, D0 ; is max allowable menu height < total menuHeight ? |
Blt.s @HasToScroll |
Bra.S @WontScroll |
@StdPopUp MOVE portRect+Bottom(A1),D0 ; calculate max allowable menu height based on |
SUB portRect+Top(A1), D0 ; screen height - 8 pixels of slop |
SUB #8, D0 |
CMP D6, D0 ; is max allowable menu height < total menuHeight ? |
BLT.S @HasToScroll ; yes ==> has to scroll |
;------------------------------------------------------------------------------------------------- |
; If here, then the complete menu WILL fit on the screen |
;------------------------------------------------------------------------------------------------- |
; Check the following possibilities: |
; 1. Top and bottom are both on the screen ==> leave it alone, PopUpItem and TopLeft will match |
; 2. Top is on screen, bottom is not ==> move bottom of menurect up until it is at least |
; 5 pixels above the bottom of the screen. Leave TopMenuItem alone |
; 3. Bottom is on screen, top is not ==> move top of menurect down until it is at least |
; 5 pixels below the top of the screen. Leave TopMenuItem alone |
@WontScroll MOVE D4, Top(A0) ; assume TopMenuItem, and top and bottom of menu are ok |
MOVE D4, (A4) ; return TopMenuItem in VAR PopUpItem |
MOVE D4, Bottom(A0) |
ADD D6, Bottom(A0) |
MOVE portRect+Top(A1),D0 ; get the top of the screen |
ADD MBarHeight, D0 ; move down 2 pixels from menubar |
ADD #2, D0 |
CMP D0, D4 ; is TopMenuItem < 2 pixels below menu bar? |
BGE.S @ChkBottom ; no ==> therefore Top is ok |
; yes ==> therefore move top down by multiple of MFHeight |
; until we get at least 2 pixels below the menu bar |
MOVE D4, D1 ; start at TopMenuItem |
@TopLoop ADD MFHeight(a6), D1 ; move down to next item |
CMP D0, D1 ; is top of menu >= 2 pixels below menu bar? |
BLT.S @TopLoop ; no ==> haven't moved top down far enough yet |
MOVE D1, Top(A0) ; yes ==> store new top |
ADD D6, D1 |
MOVE D1, Bottom(A0) ; store bottom of menu |
BRA.S @AdjustLeftRight ; do left/right adjustment <PMAB364 23Jan88 EMT> |
@ChkBottom MOVE D4, D0 ; find bottom of menu = TopMenuItem + total menu height |
ADD D6, D0 |
MOVE portRect+Bottom(A1),D1 ; calc bottom of screen - 5 pixels |
SUB #5, D1 |
CMP D1, D0 ; is Bottom of menu > 5 pixels above screen bottom ? |
BLE.S @AdjustLeftRight ; no ==> therefore Bottom is ok too <PMAB364 23Jan88 EMT> |
; yes ==> move bottom up by multiple of MFHeight until |
; we get at least 5 pixels above the screen bottom |
@BotLoop SUB MFHeight(a6), D0 ; move up to next item |
CMP D1, D0 ; is bottom of menu <= 5 pixels above screen bottom ? |
BGT.S @BotLoop ; no ==> haven't moved bottom up far enough yet |
MOVE D0, Bottom(A0) ; store bottom |
SUB D6, D0 ; calc top of menu |
MOVE D0, Top(a0) |
BRA.S @AdjustLeftRight ; do left/right adjustment <PMAB364 23Jan88 EMT> |
;------------------------------------------------------------------------------------------------- |
; If here then the complete menu WILL NOT fit on the screen |
;------------------------------------------------------------------------------------------------- |
; Leave TopMenuItem alone, but calculate where menurect should go so that when the items scroll |
; they fill up the menu exactly, i.e. as the menu is scrolled, TopMenuItem will match the |
; top of the menu rect at some point exactly. If we don't do this there may be strange |
; behavior when the menu is scrolled completely down, i.e. the top item is showing. |
; |
; If PopUpItem = 0 then force top of menu to be at Top/Left <FJL PMAB205> |
; |
; |
@HasToScroll |
MOVE D4, (A4) ; return TopMenuItem in VAR PopUpItem |
Move D4, D1 ; set up D1 <FJL PMAB205> |
Move D1, Top(A0) ; assume PopUpItem = 0 and store Top of menuRect |
Cmpi.w #0, D3 ; is PopUpItem = 0 ? |
Beq.s @CalcBottom ; yes -> branch and only calc the bottom of the rect |
MOVE portRect+Top(a1), D0; calc 2 pixels below the top of the screen <FJL PMAB205> |
ADDQ #2, D0 ; |
CMP D0, D4 ; is TopMenuItem > 2 pixels below top of screen? |
BLE.S @CalcBelow ; no ==> branch and calc top of menuRect as |
; (MFHeight x N) **BELOW** TopMenuItem |
; yes ==> fall thru and calc top of menuRect as |
; (MFHeight x N) **ABOVE** TopMenuItem |
; |
; Start at TopMenuItem, and move **UP** by increments of MFHeight until we reach at |
; least 2 pixels below the menubar. |
; |
MOVE D4, D1 ; start at TopMenuItem |
@UpLoop SUB MFHeight(a6), D1 ; move up one MFHeight |
CMP D0, D1 ; is top of menu rect < 2 pixels below the menubar ? |
BGE.S @UpLoop ; no ==> keep moving up |
ADD MFHeight(a6), D1 ; yes ==> force top of menurect to be on the screen |
MOVE D1, Top(a0) ; store top of menurect |
BRA.S @CalcBottom ; calc bottom of menurect |
; |
; Start at TopMenuItem, and move **DOWN** by increments of MFHeight until we reach at |
; least 2 pixels below the menubar. |
; |
@CalcBelow MOVE D4, D1 ; start at TopMenuItem |
@DownLoop ADD MFHeight(a6), D1 ; move down one MFHeight |
CMP D0, D1 ; is top of menu rect >= 2 pixels below the menubar ? |
BLT.S @DownLoop ; no ==> keep moving down |
MOVE D1, Top(a0) ; store top of menurect |
; |
; Start at top of menurect and move down by multiples of MFHeight until the bottom of the |
; menurect is about 5 pixels above the screen bottom. This makes the menurect an exact |
; multiple of MFHeight. |
; |
@CalcBottom MOVE portRect+Bottom(a1), D0 ; calc 5 pixels above screen bottom |
SUBQ #5, D0 |
@BotLoop2 ADD MFHeight(a6), D1 ; move down by one MFHeight |
CMP D0, D1 ; is bottom of menurect > 5 pixels above screen bottom ? |
BLE.S @BotLoop2 ; no ==> keep moving down |
SUB MFHeight(a6), D1 ; yes ==> force bottom of menurect onto the screen |
MOVE D1, Bottom(a0) ; store bottom of menuRect |
;------------------------------------------------------------------------------------------------- |
; Now adjust menuLeft and menuRight if menu hangs over left or right edge of the screen. |
;------------------------------------------------------------------------------------------------- |
@AdjustLeftRight |
MOVE MLeftTop(A6), D0 ; get left edge |
MOVE.W portRect+Left(A1), D2 ; Get left edge of screen <PMAB364 23Jan88 EMT> |
ADDQ.W #4, D2 ; Leave room for border <PMAB364 23Jan88 EMT> |
CMP.W D2, D0 ; Compare with left edge of screen <PMAB364 23Jan88 EMT> |
BGE.S @TryRight ; If greater, it's OK <PMAB364 23Jan88 EMT> |
; Adjust so the menu fits on the screen. |
MOVE D2, D0 ; make left edge equal to (fake) screen edge <PMAB364 23Jan88 EMT> |
@TryRight |
MOVE.W D0, D1 ; <PMAB364 23Jan88 EMT> |
ADD.W MenuWidth(A2), D1 ; calc right edge <PMAB364 23Jan88 EMT> |
MOVE.W portRect+Right(A1), D2 ; Get right edge of screen <PMAB364 23Jan88 EMT> |
SUBQ.W #4, D2 ; Leave room for border <PMAB364 23Jan88 EMT> |
CMP.W D2, D1 ; Compare with right edge of screen <PMAB364 23Jan88 EMT> |
BLE.S @StoreLeftRight ; if smaller, we're cool |
; Adjust so the menu fits on the screen. |
MOVE D2, D1 ; make right edge equal to (fake) screen edge <PMAB364 23Jan88 EMT> |
MOVE.W D1, D0 ; <PMAB364 23Jan88 EMT> |
SUB.W menuWidth(A2), D0 ; left = right - menuWidth <PMAB364 23Jan88 EMT> |
@StoreLeftRight |
MOVE.W D0, Left(A0) ; store left <PMAB364 23Jan88 EMT> |
MOVE.W D1, Right(A0) ; store right <PMAB364 23Jan88 EMT> |
RTS |
;---------------------------------------- |
; Utility -- SaveCurrentColors <FJL C408> |
;---------------------------------------- |
; Save the current fore/back colors in the stackframe. |
; Get the device's pixel depth in the stackframe too. |
; Only need to save if color machine |
SaveCurrentColors |
;>>>>>------------- NuMac ------------------>>>>> |
;+++ IF onNuMac THEN |
tst.b onColorMachine(a6) |
beq.s @SaveEnd |
pea saveForeColor(a6) ; push location to save fore color |
pea saveBackColor(a6) ; push location to save back color |
_GetBackColor ; and get 'em |
_GetForeColor |
SUBQ #4,SP |
MOVE.L SP,-(SP) ; point to top of stack |
_GetPort ; get the current port |
move.l (sp)+, a0 |
subq #4, sp ; space for GDHandle return |
pea portRect(a0) ; draw menus on main screen |
_GetMaxDevice ; get max pixel device |
MOVE.L (sp)+, A0 ; get the grafDevice |
MOVE.L (A0),A0 ; hndl->ptr |
MOVE.L GDPMap(A0),A1 ; get the device's pixmap |
MOVE.L (A1),A1 ; hndl->ptr |
move.w pixelSize(a1), PixelDepth(a6) ; and store the value |
;+++ ENDIF |
@SaveEnd |
;<<<<<--------------------------------------<<<<< |
rts |
;---------------------------------------- |
; Utility -- ResetPreviousColors <FJL C408> |
;---------------------------------------- |
; Restore the fore/back colors from those saved |
; in the stackframe in SaveCurrentColors. |
; Need to reset on both color and b/w machines. Assume b/w machine always have |
; black on white. |
ResetPreviousColors |
;>>>>>------------- NuMac ------------------>>>>> |
;+++ IF onNuMac THEN |
tst.b onColorMachine(a6) |
beq.s @ResetBW |
pea saveForeColor(a6) ; push location of saved fore color |
pea saveBackColor(a6) ; push location of saved back color |
_RGBBackColor |
_RGBForeColor |
bra.s @ResetEnd |
;+++ ELSE ;=============================================== |
@ResetBW |
moveq #BlackColor, d0 ; always reset to black on white |
move.l d0, -(sp) |
_ForeColor |
moveq #WhiteColor, d0 |
move.l d0, -(sp) |
_BackColor |
;+++ ENDIF |
;<<<<<--------------------------------------<<<<< |
@ResetEnd |
rts |
;---------------------------------------- |
; Utility -- SetColors <FJL C408> |
;---------------------------------------- |
; |
; On Entry: A3 MenuHandle |
; D4 Item Number |
; colorOffset(a6) Offset into menu color table indicating mark/text/cmd |
; Used: A0, D1 |
SetColors |
;>>>>>------------- NuMac ------------------>>>>> |
;+++ IF onNuMac THEN |
tst.b onColorMachine(a6) |
beq @SetBW |
cmpi.w #2, PixelDepth(a6) ; is this 2+ mode and color ? |
blt.s @SetDefault ; if 1 bit mode then use Black/White only |
tst invertFlag(a6) ; normal or inverted colors ? |
beq.s @1 ; 0 = normal colors, so branch |
; for inverted menu colors always invert the background color with the item name's color |
move #mctRGB2, colorOffset(a6) |
@1 |
subq #4, sp ; save space for result |
move.l (a3), a0 ; get menu ptr |
move menuID(a0), -(sp) ; push ID |
move d4, -(sp) ; push Item |
_GetMCEntry ; get item's color entry |
move.l (sp)+, d1 ; get the result, and set/un-set z-flag |
beq.s @TryTitleEntry ; couldn't find item entry so try title entry |
move.l d1, a0 ; get color record ptr in A0 |
move colorOffset(a6), d0 ; offset for mark/cmd/char |
pea (a0, d0) ; push foreground color |
pea mctRGB4(a0) ; push background color |
bra.s @DoTheSet ; branch to do actual color setting |
@TryTitleEntry |
subq #4, sp ; save space for result |
move.l (a3), a0 ; get menu ptr |
move menuID(a0), -(sp) ; push ID |
clr -(sp) ; Item = 0 ===> title entry |
_GetMCEntry ; get title's color entry |
move.l (sp)+, d1 ; get the result, and set/un-set z-flag |
beq.s @TryMenuBarEntry ; couldn't find title entry so try menu bar entry |
move.l d1, a0 ; get color record ptr in A0 |
move #mctRGB3, d0 ; offset for items default color |
pea (a0, d0) ; push foreground color |
pea mctRGB4(a0) ; push background color |
bra.s @DoTheSet ; branch to do actual color setting |
@TryMenuBarEntry |
subq #4, sp ; save space for result |
clr.l -(sp) ; ID = 0, Item = 0 ===> menu bar entry |
_GetMCEntry ; get menu bar's color entry |
move.l (sp)+, d1 ; get the result, and set/un-set z-flag |
beq.s @SetDefault ; couldn't find menu bar entry so use black/white |
move.l d1, a0 ; get color record ptr in A0 |
move #mctRGB3, d0 ; offset for items default color |
pea (a0,d0) ; push foreground color |
pea mctRGB2(a0) ; push background color |
bra.s @DoTheSet ; and branch to do the actual color setting |
@SetDefault |
pea RGBBlack ; use black as default forecolor |
pea RGBWhite ; use white as default background color |
@DoTheSet tst invertFlag(a6) ; normal or inverted colors ? |
beq.s @2 ; 0 = normal colors, so branch |
_RGBForeColor ; set fore/back colors |
_RGBBackColor |
bra.s @SetColorsDone |
@2 _RGBBackColor ; set back/fore colors |
_RGBForeColor |
bra.s @SetColorsDone |
;+++ ELSE ;=============================================== |
@SetBW |
moveq #BlackColor, d0 |
move.l d0, -(sp) |
moveq #WhiteColor, d0 |
move.l d0, -(sp) |
tst invertFlag(a6) ; normal or inverted colors ? |
beq.s @3 ; 0 = normal colors, so branch |
_ForeColor |
_BackColor |
bra.s @SetColorsDone |
@3 _BackColor |
_ForeColor |
;+++ ENDIF |
;<<<<<--------------------------------------<<<<< |
@SetColorsDone |
rts |
;----------------------------------------------------------------------------------------------- |
; PROCEDURE PlotAnySizeIcon(theRect: Rect; theIcon: IconHandle; iconSize: Point; |
; rowBytes: Integer) <FJLPMAB205> |
; |
; Plots a given icon of arbitrary size at a given place in your local coordinate system. |
; |
PlotAnySizeIcon |
LEA ICONBITMAP,A1 ;get address of icon mgr bitMap |
MOVE.L 10(SP),D0 ;get the icon handle |
BEQ.S DONEIPLOT ;if NIL, dont plot |
MOVE.L D0,A0 ;get iconHandle in address reg |
; |
MOVE.L (A0),(A1)+ ;icon mptr is the base address |
MOVE 4(sp),(A1)+ ;set up rowBytes |
CLR.L (A1)+ ;set up topLeft |
MOVE.L 6(SP),(A1) ;set up botRight |
; |
MOVE.L 14(SP),D1 ;get theRect |
LEA IconBitMap,A1 ;point A1 at bitmap again |
; |
; push parameters for copyBits call |
; |
MOVE.L A1,-(SP) ;source bitMap is iconBitMap |
MOVE.L GrafGLOBALS(A5),A0 ;get lisaGraf global baseaddress |
MOVE.L THEPORT(A0),A0 ;get thePort |
PEA PORTBITS(A0) ;that's the destination bitmap |
; |
PEA BOUNDS(A1) ;boundsRect of bitmap is source |
MOVE.L D1,-(SP) ;theRect is the destination |
CLR.W -(SP) ;theMode is srcCopy (0) |
CLR.L -(SP) ;no mask region |
_CopyBits ;let Bill blit those bits |
DONEIPLOT MOVE.L (SP)+,A0 ;get return address |
ADD #14,SP ;strip 12 bytes of parameters |
JMP (A0) ;return to caller |
; |
;-------------------------------------------------------------------------------------------- |
; |
; End of Code. Begin Data Definitions. |
; |
;-------------------------------------------------------------------------------------------- |
; bounds rect for hier arrow is top=0, left=0, bottom=$10, right=$10 |
HierArrow DC.W $0000, $0000, $0020, $0030, $0038, $003C, $003E, $003F |
DC.W $003E, $003C, $0038, $0030, $0020, $0000, $0000, $0000 |
; bounds rect for down arrow is top=0, left=0, bottom=$10, right=$10 |
DownArrow DC.W $0000, $0000, $0000, $0000, $0000, $7FF0, $3FE0, $1FC0 |
DC.W $0F80, $0700, $0200, $0000, $0000, $0000, $0000, $0000 |
; bounds rect for up arrow is top=0, left=0, bottom=$10, right=$10 |
UpArrow DC.W $0000, $0000, $0000, $0000, $0000, $0200, $0700, $0F80 |
DC.W $1FC0, $3FE0, $7FF0, $0000, $0000, $0000, $0000, $0000 |
END ; of menu defproc!! |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14