mac-rom/Toolbox/MenuMgr/StandardMDEF.a
Elliot Nunn 4325cdcc78 Bring in CubeE sources
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included.

The Tools directory, containing mostly junk, is also excluded.
2017-12-26 09:52:23 +08:00

3323 lines
133 KiB
Plaintext

;
; File: StandardMDEF.a
;
; Contains: Standard text menu definition procedure.
;
; Originally written by Andy Hertzfeld in July 1982.
;
; Copyright: © 1982-1992 by Apple Computer, Inc. All rights reserved.
;
; This file is used in these builds: ROM, disk
;
; Change History (most recent first):
;
; <SM4> 12/7/92 CSS Update from Reality:
; <64> 12/4/92 KSM Don't call DisposHandle if NIL upon exiting even though the call
; can handle it. It wastes time and inhibits debugging other
; things.
; <SM3> 11/5/92 SWC Changed PackMacs.a->Packages.a.
; <SM2> 10/16/92 RB Removed SOME of the NOT forROM conditionals, since some of that
; code did not make sense anymore for SuperMario ROMs. This fixed
; the disabled menu items not being drawn in gray color instead of
; gray pattern.
; <63> 8/22/91 KSM csd,#Bruges: fix font/face cleanup problem in script systems.
; <62> 3/26/91 KSM rlc,#85632: Reset the font back to the default after script
; changed it.
; <61> 3/22/91 KSM dty,#83819: Reroll change <55> per Gang Of 5.
; <60> 3/22/91 DTY bbm, #oops: Change <59> started plotting the label colours and
; other small icons in a 32x32 grid because a beq was entered as a
; bra. Change that branch to the way it should be.
; <59> 3/20/91 KSM dcc,#82082: Fix bug where cicn rect size is used to plot
; nomarksmallicons.
; <58> 3/15/91 DTY gbm, #83819: Unroll <55> because Go5 said donÕt fix.
; <57> 3/4/91 dba dty: kill SysVers conditionals
; <56> 2/27/91 KSM ngk,#ngk-b5-001: Fix #51 (BRC#80417) uncovered a fudge in the
; DoCalcItemMsg msg which is no longer correct (ADDQ #4,d7) and
; was removed.
; <55> 2/27/91 KSM rlc,#83819: Call RemoveBalloon before scrolling to avoid wrong
; balloon bits being restored.
; <54> 2/25/91 KSM dcc,#DCC003: DonÕt use ttDisabled mode to plot icons in B&W mode
; when the item is disabled. Painting gray over that icon might
; completely erase it.
; <53> 2/20/91 KSM stb,#1003794: Don't call ProcessMgr unless trap is implemented
; (i.e., at boot time).
; <52> 2/11/91 KSM NGK,#None: Fix non-7.0 build problem.
; <51> 2/10/91 KSM RLC,#79297: Speed up CalcMenuSize by calling GetItemRecord in a
; loop! This avoids calling ExpandItem each time. Each time
; through the drawing loop, TextFace and TextMode were being
; called. The strategy has been changed to now set up the
; environment outside the loop, then change it only when necessary
; and change it back before the next iteration. 22% speed up.
; RLC,#80417: A branch in calc size routine never added the
; padding to the item width for items w/ small icons or h-menus.
; RLC,#80417: Also (from same bug report) we find that the calc
; for h-menus of id=256 never got the space for the arrow added to
; them NGK,#82082: NEVER try to plot a CICN when itÕs a
; NoMarkSmallIcon
; <50> 1/14/91 KSM <kaz> Clean up and speed up GetItemHeight (round 2).
; <49> 1/13/91 KSM <KAZ> Update register saving conventions for GetItemHeight (No
; longer saves D4 and D5).
; <48> 12/12/90 KSM <dba> Fix for disabled items: use new icon utility calls to plot
; all icons in "true gray" , and draw h-menu arrow in true gray.
; Also fix cicn centering bug when icon is smaller than text (Finder Label menu).
; Alex you saved TOO MANY registers in GetItemHeight, routines depend on D7 being set up!
; <47> 11/29/90 RLC <ksm> Move the tip of the balloon 8 pixels inside the menu
; item's rect. (The help manager used to do this instead of having
; the MDEF do it. This meant that all custom MDEF's would have
; their tips be 8 pixels off horizontally).
; <46> 11/19/90 kaz GetItemHeight now looks at the text face to return the height
; (as outline & shadow are taller than plain). DrawMenu loop uses
; GetItemHeight instead of MFHeight. <jng>
; <45> 11/12/90 kaz Broke out GetItemWidth() as a utility from CalcMenu() Ñ
; CalcMenuItem() will now return the individual item size instead
; of menuWidth. <KSM>
; <44> 11/9/90 RLC <ksm> Remove check of menu title bit in MenuEnable flags when
; passing itemHelpString to the __HMShowMenuBalloon call.
; <43> 11/2/90 KSM <ngk>TextMode 31 was left on after a drawItemMsg.
; <42> 10/29/90 kaz drawItemMsg now draws the background in color; Color calls no
; longer RTS for popup CDEF. <jng>
; <41> 10/16/90 RLC When calling HMShowMenuBalloon, don't pass itemHelpString in
; itemReserved parameter if entire menu is disabled (probably by
; modal dialog menu being up). Otherwise, the help manager puts up
; the Aux menu information when, in fact, the menu item and title
; should have gotten the 'modal dialog menu' help message.
; <40> 10/10/90 KSM Fix bug where we couldnÕt draw more than 256 items (real
; important).
; <39> 9/28/90 KSM <dba> Fix bug where no icon is drawn for items that have
; hierarchical menus (instead, we draw only a large icon).
; <38> 9/16/90 RLC (KSM also) Change call to HMShowMenuBalloon to pass the
; helpstring StringHandle (in itemReserved parameter longword)
; found in AppleMenu & System Menus after calling _GetAuxMenuItem.
; Make sure all fields of AuxMenuItem Record are clear b4 calling
; _GetAuxMenuItem.
; <37> 9/15/90 KSM Consolidate the blitting arrows code. Save 126 bytes.
; <36> 9/11/90 KSM Remove some unnecessary register saving in DoCalcItemMsg and
; DoDrawItemMsg. Update DoCalcItemMsg to call _CalcMenuSize and
; GetSizes to set up stack frame correctly.
; <35> 9/11/90 gbm make PixPats be allocated in the system heap, since they need to
; stay around in the color window manager port when apps go away
; <34> 9/7/90 KSM Add enabledState to stackframe to factor out multiple calls to
; EnableTest. Fix auxmenuitem stack frame to be in sych with
; MFPrivate.a. Intense speed up of GetItemRecord by caching some
; data in locals.
; <33> 8/24/90 BG Conditionalized System 7.0 feature so that it doesn't interfere
; with building ROMs.
; <32> 8/21/90 RLC Remove all of that extraneous LastStrAttrPtr junk and make the
; calls to mChooseMsg not always call HMRemoveBalloon() [FASTER!].
; <31> 8/17/90 dvb More grayish problem
; <30> 8/17/90 dvb grayishTextCopy->grayishTextOr
; <29> 8/15/90 BG In DRAWITEXT, there was a check after the item had been drawn to
; see whether one is onColorMachine and to not gray the item out
; if -onColorMachine- is true. This is not correct and the check
; was removed. There was a comment indicating what the code was
; originally supposed to do that had been removed and that comment
; was restored as well. If there _is_ some problem with trying to
; gray out menu items on color machines, it SHOULDNT be fixed by
; just not graying out the item. Have a nice day.
; <28> 8/13/90 JSM Fix previous fix.
; <27> 8/10/90 PN Fix graying for non-color machines since drawstring on these
; machines does not recognize _PenPat(grayishtext).
; <26> 8/9/90 DC Fixed up color environment again to look even better (I hope)
; <25> 8/6/90 DC Fix up color environment around PlotIconSuite for menu
; colorizers (Kolor et al.)
; <24> 8/6/90 RLC Change _Button to _Stilldown to fix multiple calls to mChoose
; message redrawing balloon.
; <23> 8/2/90 kaz TruncateString() now saves D1 (sys just). Fixes a bug with
; DrawItem w/ sysJust == right.
; <22> 7/20/90 DVB Fix for b&w systems
; <21> 7/17/90 DVB Enable grayish menu items
; <20> 6/12/90 PKE NEEDED FOR SIXPACK: Fixed bug in default setting of itemScript.
; <19> 6/11/90 kaz Removed condensing for drawItemMsg per HI request.
; <18> 6/4/90 kaz Fixed a bug where DoCalcItemMsg tried to get the menuWidth off
; the menu handle rather than the menu ptr.
; <17> 5/31/90 DC Changed the name of selected transform constant from
; ttPrimitiveSelected to ttSelected (Sorry)
; <16> 5/30/90 DC Changed name of icon interface from IconUtils.a to Icons.a
; <15> 5/23/90 ngk Icon ID for StandardFile will now use an offset from -4000
; rather than 256. <KSM>
; <14> 5/22/90 DC Changed name of PlotBestIcon to PlotIconSuite
; <13> 4/25/90 DFH Fix "gray" icon plotting to use ttOffline rather than
; ttDisabled. Looks way better.
; <12> 4/23/90 RLC Remove help mgr macros and include the Balloons.a file instead.
; <11> 4/11/90 RLC Fix quik typo in ttSelected, (SP)
; <10> 4/11/90 KSM Update calls to _GetAuxMenuItem to include itemnum param and add
; support for color icons.
; <10> 4/11/90 KSM Update calls to _GetAuxMenuItem to include itemnum param and add
; support for color icons.
; <9> 3/19/90 EMT Removed unneccessary ROM85 test.
; <8> 3/14/90 JSM Fix bug calculating width for menu items with sub-menus, also
; was adding 1 pixel indent for NoMarkSmallIconCmd items width
; calculations to wrong register.
; <7> 3/8/90 HJR Remove extra IF hasPopupCDEF statement so that file will
; assemble.
; <6> 3/8/90 BBH fix check for mDrawItemMsg in truncatestring (screwed up the
; comparison). sorry
; <5> 3/8/90 BBH use TruncString instead of my braindead routine. Also, we check
; to see if the MDEF message is mDrawItemMsg (which is the only
; case we will want to truncate) to eliminate the truncation check
; for regular mDrawMsg's.
; <4> 3/5/90 BBH added popup cdef support to mdef
; <3> 1/31/90 JSM Add NoMarkSmallIconCmd itemCmd for Standard File.
; <2> 1/23/90 RLC Update BalloonHelp macros.
; <2.4> 11/17/89 dba got rid of checks for 64K ROMs; tightened up 7.0-specific parts
; <2.3> 9/26/89 CCH added conditionals around references to SysVers equate for ROM.
; <2.2> 9/25/89 DFH extending menu item information. Icon border is one pixel.
; Version 13.
; <2.1> 9/12/89 RLC fix Balloon Positioner for menus.
; <2.0> 8/30/89 KSM fix bug (BRC#44525) in PopUp calculation which allow pop-up to
; go off top of screen
; <1.9> 8/29/89 RLC changed calling convention to the HelpMgr & tweaked the
; HMShowMenuBalloon call
; <1.8> 8/22/89 SES removed references to nFiles.
; <1.7> 8/21/89 PKE 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.6> 8/15/89 dba NEEDED FOR 6.0.4: fix bug in GetItemHeight where it relies on
; GetIconSize not trashing A0
; <1.5> 8/10/89 RLC Changed selector message to Help Mgr Pack to MOVEQ #select,D0
; <1.4> 6/2/89 KSM Updated conditionals for ROM/SYS build AGAIN.
; <1.3> 6/2/89 KSM Updated conditionals for ROM/SYS build.
; <1.2> 6/1/89 KSM BALLOON HELP support added.
; <1.1> 11/11/88 CCH Fixed Header.
; <1.0> 11/9/88 CCH Adding to EASE.
; <¥1.3> 10/3/88 EMT Roll in latest bug fixes.
; <S550> 7/27/88 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
; <S476> 4/22/88 EMT Fixed hierchical menus being forced below menu bar
; <S422> 3/8/88 MED Fixed StandardMDEF.a to use SetScriptFont uniformally instead of
; inaccurate calculation
; <S394> 2/12/88 DBG Fixed errant branch, which was reversed, causing crash on +/SE
; PMAB364> 1/23/88 EMT Fix Pop-up menus to come up on any screen
; 9/15/87 FJL PMAB276 Allow item = 0 to popupmenuselect
; 8/21/87 FJL PMAB239 Calculate menu width correctly when have shrunken or
; small icons
; 7/14/87 FJL PMAB205 Juggler support -- support shrunken and small icons
; 4/14/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.
; 3/30/87 FJL PMAB155 DonÕt reference MenuDisable in StandardMDEF.a on 64K
; ROMs.
; 3/17/87 FJL Do invert for MacPlus/MacSE rather than redraw (for MacDraw
; custom menu) when choosing item
; 3/9/87 FJL Add variable speed menu scrolling
; 3/6/87 FJL Clean up all OnNuMac conditionals for System Disk --> Universal
; defproc
; 2/20/87 FJL C844 New routine PopUpMenuSelect.
; 2/20/87 FJL C838 Sped up menu scrolling by an amazing amount.
; 2/10/87 FJL C792 Add scrolling indicator to top and bottom of scrollable
; menus.
; 12/8/86 FJL C408 Added color support
; 11/25/86 FJL C466 Fixed ENABLETEST (local label) so enables items > 31 unless
; whole menu disabled.
; 11/4/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.
; 10/30/86 FJL C222 Fixes for hierarchical menus
; 10/1/86 DAF Changed include headers
; 1/30/86 EHB Re-did scrolling so icons would work
; 1/7/86 EHB DonÕt leave extra space at bottom of screen (reversed 30 Jan)
; 1/7/86 EHB Fixed enable bug for items > 31 (see C466 below)
; 10/15/85 EHB Fixed bugs in display of menu icons
; 10/11/85 EHB Do test byte of low memory justification word, so intl. people
; can use the high byte for further discrimination (yuck).
; 9/30/85 EHB Made scrolling smoother.
; <v5> 9/27/85 EHB Added International menu display. Added emergency menu
; scrolling.
; <v4> 8/26/85 EHB ROM/Ram version (tests ROM85)
; <v3> 8/1/85 EHB adapted for variable height system fonts
; 7/29/85 EHB converted back to porkshop
; 4/10/85 EHB fixed CalcMenuSize for items with 0 length
; 2/15/85 SC fixed applemark/commandMark bug in command keys
; 2/14/85 JTC named rsrc.
; 1/11/85 JTC convert to MDS
; 2/13/84 AJH speeded up CalcMenuSize message (linear instead of N squared)
; 11/6/83 AJH back to old disabling; special-cased "-" item
; 10/30/83 AJH changed disabling
; 4/28/83 AJH added "calcMenuSize" message
; 3/17/83 AJH no more forcing bold
; 3/17/83 AJH Fixed 4 pixel choosing offset
; 1/28/83 AJH made "GrayRect" use FillRect and a hardwired gray
; 12/27/82 AJH Broke off into separate file for resources
;
; To Do:
; *** Fix all this pixel tweeking! It is unecessary if it was done correctly.
;
;
; 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
;===============================================================================================
; start addition <BBH>
; 4 DrawItem handle entry: ptr to not used < BBH 12/4/89 >entry: theItem to draw
; return: no chg < BBH 12/4/89 >return: no chg
; NOTE that foreground/background colors are not set for this message
; (application should have set these up beforehand)
;
; 5 CalcItem handle entry: ptr to not used < BBH 12/4/89 >entry: theItem to calc
; return: topLeft no change return: no change
; botRight sized appropriately
; end addition <BBH>
;===============================================================================================
LOAD 'StandardEqu.d'
INCLUDE 'ColorEqu.a'
INCLUDE 'Packages.a'
INCLUDE 'MFPrivate.a'
INCLUDE 'IconUtilsPriv.a'
INCLUDE 'Balloons.a'
mDrawItemMsg EQU 4
mCalcItemMsg EQU 5
ArrowSize EQU $20 ; Size of the arrow data (bytes)
BalloonTipOverlap EQU $8 ; Amount help balloon overlaps menu (pixels)
PlotSUITE EQU (paramPlotIconSuite << 8) + (selectPlotIconSuite AND $FF) ; <54>
PlotICON EQU (paramPlotIconHandle << 8) + (selectPlotIconHandle AND $FF) ; <54>
PlotSICN EQU (paramPlotSICNHandle << 8) + (selectPlotSICNHandle AND $FF) ; <54>
PlotCIcon EQU (paramPlotCIconHandle << 8) + (selectPlotCIconHandle AND $FF) ; <54>
; extensions to a menu item <2.2>
itemHierarchicalID EQU 4 ; hierarchical menu ID
Sizeof_stackitem EQU 6 ; number of bytes before aux item
itemIconHandle EQU Sizeof_stackitem+auxMenuIconHandle ; handle to icon (or nil)
itemIconSize EQU Sizeof_stackitem+auxMenuIconSize ; full-sized/small/shrunken
itemIconGray EQU Sizeof_stackitem+auxMenuIconGray ; whether icon should be grayed
itemScript EQU Sizeof_stackitem+auxMenuScript ; item text script code
itemHelpString EQU Sizeof_stackitem+auxMenuHelpString ; string for balloon help
Sizeof_extendeditem EQU Sizeof_stackitem+Sizeof_auxdata ; size of our stack item
; value for itemIconSize (but not itemCmd) <2.2>
LargeIconCmd EQU $1F ; large icon plotted
FamilyIconCmd EQU $20 ; icon cache or suite (_PlotIconSuite knows for sure!)
; special values of the itemCmd field before expansion <2.2>
ShrunkenIconCmd EQU $1D ; itemCmd == $1D ==> large icon plotted in 16x16
SmallIconCmd EQU $1E ; itemCmd == $1E ==> small icon plotted
NoMarkSmallIconCmd EQU $1A ; itemCmd == $1A ==> small icon with no mark
; Assumes no item in menu will ever be marked,
; and doesn't leave space to left of menu item
; for one. Used in popup in Standard File.
;----------------------------------------------------------------------------------------
;
; StackFrame and Global Definitions
;
;----------------------------------------------------------------------------------------
MDEF0 PROC EXPORT
;
; Stack Frame Definition for TextMenuProc
; PROCEDURE TextMenuProc( message :Integer,
; theMenu :menuHandle,
; VAR menuRect :Rect,
; hitPt :Point,
; VAR whichItem :Integer);
StackFrame RECORD {A6Link},DECR
ParamBegin EQU * ; parameters start after this point
MMESSAGE DS.W 1 ; message
MMENUHANDLE DS.L 1 ; theMenu
MMENURECT DS.L 1 ; VAR menuRect
MPOINT DS.L 1 ; hitPt
MWHICHITEM DS.L 1 ; VAR whichItem
MLeftTop EQU MPOINT
MPopUpItem EQU MWHICHITEM
ParamSize EQU ParamBegin-* ; size of all the passed parameters
RetAddr DS.L 1 ; place holder for return address
A6Link DS.L 1 ; place holder for A6 link
MFHeight DS.W 1 ; NOTE: This is really the "leading" field of fontinfo
MWidMax DS.W 1
MDescent DS.W 1
MAscent DS.W 1
MInfoRec EQU MAscent
MSpaceWidth DS.W 1
saveForeColor DS.W 3
saveBackColor DS.W 3
pixelDepth DS.W 1
colorOffset DS.W 1
invertFlag DS.W 1 ; 0 = normal item, 1 = inverted item
scrollFlag DS.W 1 ; 0 = scrolling item, 1 = choosing item
HItemFlag DS.W 1 ; 0 = no sub menu, 1 = item has submenu
iconHandle DS.L 1
HierArrowRect DS.W 4
OrigMenuRect DS.W 4
ScrollSpeed DS.L 1
SlowPixels DS.W 1
onColorMachine DS.W 1
enableState DS.W 1 ; Inside DrawItem only! (0=disabled, 1=enabled)
irTmpItemNo DS.W 1 ; Temp item number
irItemNo DS.W 1 ; Item number last checked (0 means none yet)
irItemAddr DS.L 1 ; Points to length byte of item
expandItemErr DS.W 1 ; Error returned from ExpandItem
processMgrIn DS.B 1 ; ZERO if not in or not checked, NON-zero if implemented
processMgrChkd DS.B 1 ; ZERO if unimplemented check not yet done
arrowHandle DS.L 1 ; Handle used for plotting arrows
stackItem DS.B Sizeof_extendeditem
tempString DS.B 256
LinkSize EQU * ; size of all the local variables
ENDR
FastSpeed EQU 0
SlowSpeed EQU 10
FirstMDMsg EQU 0 ; first message
LastMDMsg EQU 5 ; last message <BBH>
;----------------------------------------------------------------------------------------
;
; Start of Code -- save work registers and dispatch on message number
;
;----------------------------------------------------------------------------------------
BRA.S StartMDEF
; Standard Header
DC.W 0 ; flags word
DC.L ('MDEF') ; type
DC.W 0 ; ID
DC.W 13 ; 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>
; version 13= System 7.0 <2.2>
StartMDEF
MDEFSaveReg REG D3-D7/A2-A4
WITH StackFrame
LINK A6,#LinkSize ; set up a stack frame <1Aug85>
MOVEM.L MDEFSaveReg,-(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 1s if yes
lea GoMdefProc, a0 ; get the dispatch table base <FJL>
move.w mMessage(a6), d0 ; get the message type
clr.w enableState(a6) ; Just set to something for now <34>
clr.w irTmpItemNo(A6) ; clear the temp value
clr.w irItemNo(A6) ; clear the item #
clr.l irItemAddr(A6) ; clear the address
clr.w expandItemErr(a6) ; No Error yet
clr.b processMgrIn(a6) ; DonÕt know if Process Mgr installed <53>
clr.b processMgrChkd(a6) ; HavenÕt done Process Mgr check yet <53>
clr.l arrowHandle(a6) ; Set handle to nil initially <48>
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
move.l arrowHandle(a6),d0 ; the arrow handle or NIL <48><64>
beq.s @skipDispose ; Don't bother if already NIL <64>
move.l d0,a0 ; Get ready for DisposeHandle <64>
_DisposeHandle ; DisposeHandle can deal with NIL <48>
@skipDispose
MOVEM.L (SP)+,MDEFSaveReg ; restore work registers
UNLK A6 ; unbuild the stack frame
MOVE.L (SP)+,A0 ; get return address
ADD #ParamSize,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
dc.w DoDrawItemMsg-GoMdefProc ; draw item <BBH 12/7/89> #4
dc.w DoCalcItemMsg-GoMdefProc ; calc item <BBH 12/7/89> #5
;********************************************************************************************
;* *
;* 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
tst.w itemHierarchicalID(a1) ; does item have sub-menu? <2.2>
beq.s @NoSubMenu ; no ==> leave flag cleared <2.2>
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 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
bsr RemoveAnyBalloon ; Be sure to remove any balloon before inverting <55>
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.
IF NOT forROM THEN ; <2.2>
; 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 NOT forROM
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
clr MenuDisable+2 ; clear Item only, not ID
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
IF NOT forROM THEN ; <2.2>
; 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 NOT forROM
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
bsr RemoveAnyBalloon ; Be sure to remove any balloon before inverting <55>
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
SUBQ #2,SP ; room for Boolean
_HMGetBalloons ; what is the state of What Is? mode? (This is a FAST call)
TST.B (SP)+
BEQ.S @FlashInProgress
SUBQ #2,SP ; check status of button
; _Button ; call button if helpmgr includes OSEventAvail patch
_StillDown
TST.B (SP)+ ; if true then button is still down
BEQ.S @FlashInProgress ; else the item is flashing so donÕt flash the balloon
BSR.S ShowMenuBalloon ; show the balloon for the chosen item
@FlashInProgress
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
move.l d4, MenuDisable ; put in low-memory where apps can query it if they want
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
ShowMenuBalloon
MOVE.L D4,-(SP) ; <48> Save only the needed registers!
MOVE.L (A3),A0 ; get menuPtr <KSM/RLC 01Jun89>
MOVE D4,D0 ; get item number <KSM/RLC 01Jun89>
BSR GETITEMRECORD ; look it up <KSM/RLC 01Jun89>
BSR IsDash ; Is it a dash? (other attrs?) <KSM/RLC 01Jun89>
BNE.S @needBubble ; no, just return the item num <KSM/RLC 01Jun89>
MOVEQ #-1,D4 ; else make item num -1 for dash <KSM/RLC 01Jun89>
@needBubble
; FUNCTION HMShowMenuBalloon(itemNum,itemMenuID: INTEGER;
; itemFlags,itemReserved: LONGINT;
; tip: Point; alternateRect: RectPtr; tipProc: Ptr;
; theProc,variant: INTEGER): OSErr;
SUBQ #2,SP ; room for result
MOVE.W D4,-(SP) ; item number
MOVE.L (A3), A0 ; get menu ptr
MOVE.W menuID(A0),-(SP) ; push menuID
MOVE.L MENUENABLE(A0),D0 ; <41> get menu flags in D0
MOVE.L D0,-(SP) ; <41> push menu flags
MOVE.L stackItem+itemHelpString(A6),-(SP) ; push help string handle in itemReserved
MOVE.L MBSaveLoc,A0 ; get MBSave handle
MOVE.L (A0),A0 ; deref
MOVE.W mbItemRect+bottom(A0),D4
SUB.W mbItemRect+top(A0),D4
LSR.W #1,D4 ; find half way down from top of menu
MOVE.L mbItemRect+botRight(A0),D0 ; use the right side of the menu rect
SUBQ.W #BalloonTipOverlap,D0 ; <47> tweak the horizontal part
SWAP D0
SUB.W D4,D0 ; put the tip in the middle of the right vert
SWAP D0
MOVE.L D0,-(SP) ; push the tip
PEA mbItemRect(A0) ; push the alternaterect
CLR.L -(SP) ; NIL tipProc
CLR.L -(SP) ; theProc & variant = 0
_HMShowMenuBalloon
ADDQ #2,SP ; toss result
MOVE.L (SP)+,D4 ; <48>
RTS
;------------------------------- DONE CHOOSE MSG ------------------------------------
;---------------------------------------
; Utility -- RemoveAnyBalloon <55 KSM>
;---------------------------------------
;
; Insure no balloon is currently displayed. This utility was addded as change <55>
;
RemoveAnyBalloon
subq #2,sp ; room for Boolean
_HMGetBalloons ; Get state of WhatIs mode (Show Balloons?)
tst.b (sp) ; EQ means off (leave result on stack for now)
beq.s @helpIsOff
_HMRemoveBalloon ; Remove any balloons before scrolling
@helpIsOff
addq #2,sp ; room for Boolean
rts
;---------------------------------------
; Utility -- 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 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.
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.
; On entry: A1 points to the item
; On exit: D1 contains the result (height is in the high word)
GetIconSize
TST.W itemIconSize(A1) ; does it have an icon? <2.2>
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>
cmpi.w #NoMarkSmallIconCmd, itemIconSize(A1) ; Never look for a cicn in this case <59>
beq.s @noColor ; <59><60>
; <51> the check of itemIconSize indicates if we have an icon, this check prevents the use of icon #256
; for things like smallIcon, shrunkIcon, etc.
; tst.b itemIcon(a1) ; icon specÕd in resource type? <2.2><51>
; beq.s @noColor ; jump if not <2.2><51>
; 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.w #FamilyIconCmd, itemIconSize(A1) ; is there an icon suite/cache?
beq.s @0 ; yes -> branch
cmpi.w #ShrunkenIconCmd, itemIconSize(A1) ; is there a shrunken icon? <2.2>
beq.s @0 ; yes -> branch
cmpi.w #SmallIconCmd, itemIconSize(A1) ; is there a small icon? <2.2>
beq.s @0 ; yes -> branch
cmpi.w #NoMarkSmallIconCmd, itemIconSize(A1) ; is this a small icon with no mark?
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.
; On entry: A4 points to the item
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.
; On entry: A1 points to the item
; On exit: D1 has icon width (if any) in the high word.
; Trashes: D0, D1
GetItemHeight
GIHtReg REG d1-d2/a0-a2 ; TextFace can trash d0-d2 and a0-a1 (d0 is OK)
; and GetSizes trashes a2
bsr.s GetIconSize
swap d1
; We need to check to see if the style will change the MFHeight
moveq #0,d0 ; clear out high byte
move.b ITEMSTYLE(a1),d0 ; get style setting
beq.s @MFHeightIsOK
; Save standard FontInfo so we only call GetSizes once
move.l a3,-(sp) ; Save a work register
lea MInfoRec(A6),a3
move.l (a3)+,-(sp) ; Save ascent/descent
move.l (a3)+,-(sp) ; Save widMax/MFHeight (leading)
move.w MSpaceWidth(a6),-(sp) ; Save MSpaceWidth
movem.l GIHtReg,-(sp)
swap d0 ; WARNING: Assumes highword is ZERO from above!
move.l d0,-(sp) ; Set up for BOTH TextFace calls
_TextFace ; Set to new face
bsr.s GetSizes ; Compute the new MFHeight
_TextFace ; Restore back TextFace(0)
move.w MFHeight(a6),d0 ; Get new MFHeight into d0 for calc
movem.l (sp)+,GIHtReg
move.w (sp)+,MSpaceWidth(a6) ; Restore MSpaceWidth
move.l (sp)+,-(a3) ; Restore widMax/MFHeight (leading)
move.l (sp)+,-(a3) ; Restore ascent/descent
move.l (sp)+,a3
bra.s @MFHeightIsCalculated
@MFHeightIsOK
move.w MFHeight(a6),d0 ; Get the MFHeight
@MFHeightIsCalculated
addq.w #2,d1 ; Compute Icon height + 2
cmp.w d0,d1 ; Is Icon height + 2 < MFHeight?
blt.s @fontLarger ; if yes, use font height
move.w d1,d0
@fontLarger
rts
;---------------------------------------
; Utility -- GetItemWidth
;---------------------------------------
; GetItemWidth gets the width of the current menu item into D0.
; On entry: A1 points to the item's attr byte list
; A4 is the item string
; D7 has icon width (if any)
; Trashes: D0, D1, D7
GetItemWidth
MOVE.W MWidMax(A6),D1 ; get char width <1Aug85>
CMP.W #NoMarkSmallIconCmd,itemIconSize(A1) ; small icon with no mark?
BNE.S @addMark ; no, add in space for mark
ADDQ.W #1,D7 ; add in one pixel indent for small icon
BRA.S @noMark ; and continue
@addMark
ADD.W D1,D7 ; add once for mark <1Aug85>
@noMark
TST.W itemHierarchicalID(a1) ; does item have sub-menu?
BNE.S @spaceForCmd ; yes, include room for hierarchical arrow
TST.B itemCmd(A1) ; is there a commmand? <2.2><51=BRC#80417>
BEQ.S @justAddMargin ; if not, skip but still must add margin! <51=BRC#80417>
@spaceForCmd
ADD.W D1,D7 ; add twice for command equivalent <1Aug85>
ADD.W D1,D7 ; <1Aug85>
@justAddMargin ; <51=BRC#79297>
ADDQ.W #8,D7 ; plus an eight pixel margin <1Aug85>
MOVEQ #-1,d1 ; Two words (non-zero) to indicate no TextFont/Face chgs <51>
MOVE.L d1,-(sp) ; <skip font, skip face> is pushed onto the stack <51>
MOVEQ #0,D1 ; clear out high byte
MOVE.B ITEMSTYLE(A1),D1 ; get style setting
beq.s @NoFaceChg ; <51=BRC#79297>
MOVE.W D1,-(SP) ; push the style
_TextFace ; tell LisaGraf about new style
clr.w 2(sp) ; Say we need to clean up face <51=BRC#79297>
@NoFaceChg
; If there is a script defined for this item, then set font for proper string width calc,
; do calc, and restore font to #0.
; use utility routine for setting the font from the script
move.w itemScript(a1),d0 ; pass script number <2.2>
bmi.s @NoScriptChg ; skip setting if default <2.2><20>
bsr SetScriptFont ; set TextFont according to script <S422 08Mar88 MED>
clr.w (sp) ; Say we need to clean up font <51>
@NoScriptChg
CLR -(SP) ; make room for stringWidth result
MOVE.L A4,-(SP) ; move string pointer
_StringWidth ; find out the width
ADD.W (SP)+,D7 ; add width to extra
; Now clean up TextFont/TextFace as required <51=BRC#79297>
move.w (sp)+,d0 ; Clear if we need to restore the font
bne.s @chkFace
move.w d0,-(sp)
_TextFont
@chkFace
move.w (sp)+,d0 ; Clear if we need to restore the face
bne.s @chksDone
move.w d0,-(sp)
_TextFace
@chksDone
MOVE.W D7, D0 ; return the value
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.
;
; On entry: D0 Item number
; A3 Menu handle
;
; 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.W D3,D4 ; found the item we want yet? <40>
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
; 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
bsr PushThePort
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.b 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
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 theZone, -(sp) ; we set the zone to the system zone so the <35 gbm>
move.l sysZone, theZone ; pixpat gets created there <35 gbm>
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
move.l (sp)+, theZone ; restore the correct heap <35 gbm>
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 -- CenterRectInMFHeight
;---------------------------------------
; CenterRectInMFHeight fixes the rect pointed to by a0 when the icon height
; is smaller than the item height.
; On Entry: A0 points to the rect
; On Exit: The rect is centered within MFHeight
; Trashes D0, but A0 is preserved
CenterRectInMFHeight
move.w bottom(a0),d0 ; Compute rect height (bottom-top)
sub.w top(a0),d0
sub.w MFHeight(a6),d0 ; IF (iconHt-MFHeight) >= 0 THEN branch
bge.s @dontBumpRectDown
neg.w d0 ; d0 = MFHeight - icon ht
subq.w #1,d0 ; already 1 down from top
lsr.w #1,d0 ; get 1/2 delta
add.w d0,top(a0)
add.w d0,bottom(a0)
@dontBumpRectDown
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 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>
IF NOT forROM THEN ; <2.2>
; 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 NOT forROM
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
; 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 zero for TextFace and TextFont
_TextFace ; change textface to normal
_TextFont ; change textfont to normal
DRAW1MLOOP MOVE.L MMENURECT(A6),A0 ; get menuRect pointer <27Sep85>
ADD.W MAscent(A6),D3 ; add in the ascent for baseline
bsr DrawTheItem ; call drawing routine
BEQ.S DONEDRAW ; if null item, EXIT W/atBottom TRUE <27Sep85> <S550 27Jul88 EMT>
; We can't just use MFHeight & MAscent 'cuz there might be outlines/shadow text, etc
SUB.W MAscent(A6), D3 ; get rid of the ascent here so we can
BSR GetItemHeightA4 ; get the true item height
ADD D0, D3 ; and add it to cumulative total
; DrawTheItem w/ icons will increment D3 (baseline) for some bizarre
; "centering" scheme. We try to undo the damage here
TST.W itemIconSize(A4) ; does it have an icon? <2.2>
BEQ.S @1 ; skip if it doesnÕt
SUB.W MFHeight(A6),D0 ; undoes the algorithm in NotDash
LSR.W #1,D0
SUB.W D0, D3
@1
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
;
BlitSaveReg REG a4/d4
BlitDownScrollIndic
movem.l BlitSaveReg, -(sp) ; store work registers
; calculate where bottom of menu is
movem.l (a0),d0-d1 ; Copy Rect into registers
movem.l d0-d1,HierArrowRect(a6) ; copy to hier rect
swap d1 ; make d1 right,bottom
sub.w MFHeight(a6), d1 ; bottom-MFHeight
move.w d1, HierArrowRect+Top(a6) ; top=bottom-MFHeight
lea DownArrow, a4 ; store arrow address in a4 for DoTheBlit
bra.s DoTheBlit
BlitUpScrollIndic
movem.l BlitSaveReg, -(sp) ; store work registers
; calculate where top of menu is
movem.l (a0),d0-d1 ; Copy Rect into registers
movem.l d0-d1,HierArrowRect(a6) ; copy to hier rect
swap d0 ; make d1 left,top
add.w MFHeight(a6), d0 ; top-MFHeight
move.w d0, HierArrowRect+bottom(a6); bottom=top+MFHeight
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
move MWidMax(A6), d0
add d0,HierArrowRect+Left(A6) ; note top is ok already
st enableState(A6) ; Up and down arrows are never grayed
bsr.s BlitCommon
movem.l (sp)+, BlitSaveReg ; restore work registers
bsr ResetPreviousColors ; reset colors stored in stackframe
rts
;---------------------------------------
; Utility -- BlitCommon
;---------------------------------------
; Blit the bits pointed to by A4
; On Entry: A4 points to bits to be blitted
; HierArrowRect(A6) has rect to blit into (topLeft is setup)
; thePort has been set
; Trashes: D0, A4
BlitCommon
; fix up HierArrowRect to have height/width = min(16,MFHeight)
move.w MFHeight(a6), d0 ; get height
cmpi.w #16, d0 ; which is smaller?
ble.s @MFIsSmaller
move.w #16, d0 ; 16 is the smaller value
@MFIsSmaller
move.l HierArrowRect(a6), HierArrowRect+4(a6) ; Copy topLeft to botRight
add.w d0,HierArrowRect+right(a6)
add.w d0,HierArrowRect+bottom(a6)
; The icon utils require a real handle to plot the arrow
move.l arrowHandle(a6),a0 ; Did we already allocate this?
move.l a0,d0
bne.s @justCopyTheData
moveq #ArrowSize,d0
_NewHandle
bne.s @cantDoIt
move.l a0,arrowHandle(a6) ; Save the handle in case we have more hier items
@justCopyTheData
move.l (a0),a1 ; Dest ptr is in handle
move.l a4,a0 ; Src ptr is arrow bits
moveq #(ArrowSize/4)-1,d0 ; Size is always 32 (d0=#longs to move - 1)
@arrowLoop move.l (a0)+,(a1)+
dbf d0,@arrowLoop
lea HierArrowRect(a6),a0 ; Put the rectPtr into a0 <54>
bsr CenterRectInMFHeight
moveq #atNone,d1 ; Put the alignment into d0 <54>
move.l arrowHandle(a6),a1 ; Put the icon handle into a1 <54>
; NOTE: The clr.w below only affects the h-menu arrow. The itemIconGray flag
; only applies to this itemÕs icon, but not the h-arrow. Since we use a common
; subroutine to plot both the icon and the h-arrow, we must clear this flag before
; plotting the arrow, and thereby assume the icon has already been plotted.
clr.w stackItem+itemIconGray(A6) ; Assumes itemÕs icon drawn before h-menu <54>
move.w #PlotSICN,d0 ; And plot the SICN <54>
bsr.s IconPlotFromHandle ; Go plot it <54>
@cantDoIt
rts
;---------------------------------------
; Utility -- IconPlotFromHandle <54>
;---------------------------------------
; Set up for and call to PlotIconSuite, PlotIconHandle, PlotSICNHandle, or PlotCIconHandle
; Since they all take the same arguments, this saves code.
; On Entry: a0 is the RectPtr
; a1 is the IconHandle
; d0 is the call to make (PlotXXXX constant)
; High byte is #of params, low byte is selector #
; d1.w is the alignment
; On Exit: d0 contains result and ccÕs are set
; FUNCTION PlotIconSuite(theRect: Rect; align: INTEGER; transform: INTEGER; theIconSuite: Handle): OSErr;
; FUNCTION PlotIconHandle(theRect: Rect; align: INTEGER; transform: INTEGER; theIcon: Handle): OSErr;
; FUNCTION PlotSICNHandle(theRect: Rect; align: INTEGER; transform: INTEGER; theSICN: Handle): OSErr;
; FUNCTION PlotCIconHandle(theRect: Rect; align: INTEGER; transform: INTEGER; theCIcon: CIconHandle): OSErr;
; NOTE: The ttDisabled transform conflicts with the BitClearItem used on disabled items
; (avoids the use of slow grayishTextMode only on B&W machines currently).
; Icons drawn in ttDisabled mode and subsequently BitClearÕd will become completely erased!
; The tests below insure that disabled items on B&W machines never use ttDisabled for the icon.
; It is O.K. on any machine to use this mode when only the itemIconGray flag is true since the
; entire item will not be BitClearÕd. The Pascal-ish comments below indicate the intention.
IconPlotFromHandle
subq.w #2,sp ; Make room for result
move.l a0,-(sp) ; Push the rect ptr
move.w d1,-(sp) ; Push the alignment
moveq #ttNone,d1 ; transform := ttNone;
tst.b enableState(a6) ; if (enableState=false) then begin
bne.s @checkIconGray
tst.b onColorMachine(a6) ; if (onColorMachine=true) then
bne.s @mustDisable ; transform := ttDisabled;
bra.s @haveTransform ; otherwise on B&W machine, donÕt use it
@checkIconGray
tst stackItem+itemIconGray(A6) ; end else if (itemIconGray=true) then
beq.s @haveTransform ; EQ -> ProcessMgr doesnÕt was it gray either
@mustDisable
moveq #ttDisabled,d1 ; transform := ttDisabled;
@haveTransform
move.w d1,-(sp) ; Push the transform
move.l a1,-(sp) ; Push the icon data handle
_IconDispatch
move.w (sp)+,d0 ; Return result
rts
;---------------------------------------
; Utility -- BlitHierArrow
;---------------------------------------
; Blit up the hierarchical arrow
;
BlitHierArrow
; calculate where arrow should go
move.l a4,-(sp)
subq #4, sp
move.l sp, -(sp) ; reserve space on stack for result
_GetPen
move.l (sp)+, d0 ; get y,x
swap d0 ; get x,y
sub MAscent(a6), d0 ; move up by the font ascent to get top of item
swap d0 ; have top, left of where will blit arrow
move.l d0, HierArrowRect(a6) ; store top, left
lea HierArrow, A4
bsr.s BlitCommon
move.l (sp)+,a4
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.w itemIconSize(A1) ; Does it have an icon? <2.2>
BNE.S @NoDash ; No dash, skip.
TST.B itemCmd(A1) ; Does it have a cmd?
@NoDash
RTS ; Return result in Z
;----------------------------------------
; Utility -- PushThePort
;----------------------------------------
; Push the port onto the stack (subroutine to save code).
PushThePort
MOVE.L (SP),-(SP) ; copy return address
PEA 4(SP) ; write over old return address with port
_GetPort ; get the port, but leave it on the stack
rts
;----------------------------------------
; 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 #mctRGB2, colorOffset(a6) ; use the item color if there is an entry <ksm37>
bsr SetColors ; set colors <ksm37>
BSR.S EnableTest ; Check the enabled state of this item
SNE enableState(a6) ; Set TRUE if not enabled
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 NotDash ; If not, draw item normally <S550 27Jul88 EMT>
;---------------------------------------
; Utility -- DrawDash
;---------------------------------------
; handle the case of a dash item by drawing a line
DrawDash
;ksm37 move #mctRGB2, colorOffset(a6) ; use the item color if there is an entry <FJL C408>
;ksm37 bsr SetColors ; set colors <FJL C408>
TST.B onColorMachine(A6)
BEQ.S @ditherGrayLine
; FUNCTION GetGray(device: GDHandle; backGround: RGBColor; VAR foreGround: RGBColor): BOOLEAN;
sub #12,sp ; put (back,fore) colors on stack
pea (sp)
_GetBackColor
pea 6(sp)
_GetForeColor
subq #6,sp ; Make room for result & gdhandle
move.l MMenuRect(a6),-(sp) ; Global menu rect
_GetMaxDevice ; leave main device on stack
lea 6(sp),a0 ; Get address of back color
move.l a0,-(sp) ; Push back
pea 6(a0) ; Push fore
_GetGray ; Do we have a gray?
move.b (sp)+,d0
bne.s @rgbGrayLine ; NE (TRUE) means we have the gray
add #12,sp
bra.s @ditherGrayLine
@rgbGrayLine
addq #6,sp ; Get rid of back color
pea (sp)
_RGBForeColor
addq #6,sp ; Get rid of fore color
bra @b
@ditherGrayLine
MOVE.L (A5),A0 ; get QuickDraw globals
PEA Gray(A0) ; set pattern to gray
_PenPat
@b
MOVE.W D3,-(SP) ; save y position
MOVE.W D5,-(SP) ; push x position
MOVE.W MFHeight(A6),D0 ; center the dash
LSR.W #1,D0 ; by backing up to top of cell
SUB.W MAscent(A6),D0 ; and going halfway down
ADD.W D0,D3 ; add to current position
MOVE.W D3,-(SP) ; push new y position
_MoveTo
MOVE.W D6,-(SP) ; push right edge
MOVE D3,-(SP) ; push y
_LineTo ; draw the line
MOVE.W (SP)+,D3 ; restore baseline
_PenNormal ; This wonÕt create a new pixpat
@oldMac2
BRA DoneDrawItem ; dive back into mainstream
NotDash
; IF NOT forROM THEN ; only do this for System builds, not ROMs <33><SM2> rb
TST.B onColorMachine(a6) ; on color machine?
BEQ.S @skipPenMode ; no, skip _TextMode
TST.B enableState(a6) ; <34>
BNE.S @skipPenMode ; Yes=>go set mode
MOVEQ #grayishTextOr,D0 ; disabled item on color machine
MOVE.W D0,-(SP)
_TextMode
@skipPenMode ; <51=BRC#79297>
; ENDIF ; { NOT forROM } <33><SM2> rb
ADDQ.W #2, D5 ; Add the 2 pixels here instead <S550 27Jul88 EMT>
move.w itemIconSize(A4),D0 ; does it have an icon? <2.2>
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
CMP.W #NoMarkSmallIconCmd,itemIconSize(A4) ; small icon with no mark?
BEQ.S CHKDRAWICON ; no mark if so
MOVE.W MWidMax(A6),D0 ; get char width <27Sep85>
BSR TweakPos ; get hpos into D2, adjust d5,d6 <27Sep85>
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 itemIconSize == ShrunkenIconCmd ($1D) we draw the icon into a 16x16 <FJL PMAB205>
; area instead of the normal 32x32
; when itemIconSize == SmallIconCmd ($1E) we draw a small icon into a 16x16 <FJL PMAB205>
; area
;
; when itemIconSize == FamilyIconCmd ($20) we draw an icon suite into a 16x16 area
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
; 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 #1,D1 ; down from top of item <15Oct85>
MOVE.L (SP)+, D0 ; Restore it into D0 instead <S550 27Jul88 EMT>
MOVE.W D1,(A0)+ ; and stuff top <1Aug85>
MOVE.W D5, D2 ; Assume left-to-right <S550 27Jul88 EMT>
CMP.W #NoMarkSmallIconCmd,itemIconSize(A4) ; small icon with no mark?
BNE.S @CheckJust ; no, continue
ADDQ.W #1,D2 ; add 1 pixel to left indent
@CheckJust
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>
CMP.W #NoMarkSmallIconCmd,itemIconSize(A4) ; small icon with no mark?
BNE.S @LeftRight ; no, continue
SUBQ.W #1,D2 ; subtract one pixel from left
@LeftRight ; <S550 27Jul88 EMT>
MOVE.W D2,(A0)+ ; push left <27Sept85> <S550 27Jul88 EMT>
MOVE.L -4(A0),(A0) ; copy bottom right
ADD.L D0, (A0) ; Add height, width to get bottom, right <S550 27Jul88 EMT>
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>
LEA TEMPRECT,A0
BSR CenterRectInMFHeight
; Check to see if we have a suite/cached icon
cmpi.w #FamilyIconCmd, itemIconSize(A4) ; is there an icon suite/cache?
bne.s @skipPlotFamiliarIcon ; no -> branch
bsr SetColors ; set up the colors for a non-inverted item <DCC 8/03/90>
move.l (sp)+,a0 ; Put rect ptr into a0 <54>
move.l itemIconHandle(a4),a1 ; Data handle into a1 <54>
moveq #atAbsoluteCenter,d1 ; Put in the exact center <54>
move.w #PlotSUITE,d0 ; Use _PlotIconSuite <54>
bsr.s IconPlotFromHandle ; <54>
bra DonePlot ; and we're done
@skipPlotFamiliarIcon
tst.b onColorMachine(a6)
beq.s @DoPlotIcon
CMP.W #NoMarkSmallIconCmd,itemIconSize(A4) ; small icon with no mark? <51>
beq.s @DoPlotIcon ; No mark small icons are never cicnÕs <51>
; attempt to get color icon first and if unsuccessful then get regular icon <FJL C408>
tst.b itemIcon(a4) ; icon specÕd in resource? <2.2>
beq.s @DoPlotIcon ; jump if not <2.2>
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
;_______________________________________________________________________________________________<48>
; This is the new plotting stuff for cicn's. It uses the new Icon Utils call PlotCIconHandle.
; Color icons from cicn resources will NO LONGER invert. It looks like sh*t anyway and
; is inconsistent with the way we draw icon suites. So, here goes..
; The fgnd and bkgnd colors are preserved across the call.
; FUNCTION PlotCIconHandle(theRect: Rect; align: INTEGER; transform: INTEGER;
; theCIcon: CIconHandle): OSErr;
; Now plot that cicn using DaveÕs cool new call made just for the MDEF...
move.l (sp)+,a0 ; Save off the rectptr (already on stack)
move.l iconHandle(a6),a1 ; <54>
moveq #atNone,d1 ; alignment <54>
move.w #PlotCIcon,d0 ; Use _PlotCIconHandle <54>
bsr.s IconPlotFromHandle ; <54>
;_______________________________________________________________________________________________<48>
move.l iconHandle(a6), -(sp) ; dispose of CIcon
_DisposCIcon
bra.s DrawCmdChar ; and continue
@DoPlotIcon
;_______________________________________________________________________________________________<48>
moveq #1,d2 ; d2=0 means plot SICN, d2<>0 means plot large
MOVE.W #$0100,D1 ; d1 is base of icon IDs; std. menu icons are 256-511
move.l #'ICON',a1 ; a1 is resource type for icon
; check for special icons - small, or no-mark small
move.w itemIconSize(A4),d0 ; Icon kind is in d0
cmpi.w #SmallIconCmd, d0 ; is it a small icon?
beq.s @stdSmallIcon ; yes -> get std. small icon
cmpi.w #NoMarkSmallIconCmd, d0 ; is it a small icon with no mark?
bne.s @gotIconInfo ; no -> get std. icon
@noMarkSmallIcon
MOVE.W #genericIconBase,d1 ; StdFile icons begin at genericIconBase
@stdSmallIcon
moveq #0,d2 ; use SICN plotting
move.l #'SICN',a1 ; use SICN resource
@gotIconInfo
; calculate icon ID
moveq #0,d0
MOVE.B itemIcon(A4),D0 ; Set up the icon offset
ADD.W d1,d0
; get the resource to plot
subq #4,sp ; Make room for GetResource result
move.l a1,-(sp) ; push rsrc type
MOVE.W D0,-(SP) ; push icon number
_GetResource ; get the icon handle (keep it on stack)
move.l (sp)+,d0 ; did we get one?
; get out of here if there was no resource
movea.l (sp)+,a0 ; Get rect ptr off stack without changing ccÕs
beq.s DonePlot
move.l d0,a1 ; Put the rsrc handle into a1 <54>
moveq #atAbsoluteCenter,d1 ; alignment <54>
move.w #PlotICON,d0 ; Use _PlotIconHandle <54>
tst.w d2 ; Which plot to use? <54>
bne.s @useICON ; NE means plot ICON <54>
move.w #PlotSICN,d0 ; Use _PlotSICNHandle <54>
@useICON
bsr.s IconPlotFromHandle ; Go do the plot <54>
;_______________________________________________________________________________________________<48>
DonePlot
; ------------ draw the command character or hierarchical arrow ------------------
; There can only be one or the other, not both
DrawCmdChar
TST.B itemCmd(A4) ; is there a command key? <2.2>
BNE.S NeedPadding ; yes <2.2>
TST.W itemHierarchicalID(a4) ; is there a H Menu? <2.2> <FJL C222>
BEQ.S DRAWITEXT ; if not, skip
NeedPadding
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>
tst.w itemHierarchicalID(a4) ; is there a H Menu? <2.2> <FJL C222>
beq.s @DoCmdKey ; no, so do as key equivalent <2.2> <FJL C222>
bsr.s BlitHierArrow ; draw the Hierarchical arrow
bra.s DrawIText ; continue <FJL C222>
@DoCmdKey
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 character <15Feb85>
_DrawChar ; draw the character
CLR.W 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
@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 ; get the style parameter
beq.s @noFaceChg ; <51=BRC#79297>
MOVE.W D0,-(SP) ; Set style parameter
_TextFace ; get into that face
@noFaceChg ; <51=BRC#79297>
; if there is a script for this font then set it
move.w itemScript(a4), d0 ; get script number <2.2>
bmi.s @1 ; skip if default <2.2><20>
bsr SetScriptFont ; no, 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>
;------------------------------------------------------------
;
; NOTE NOTE NOTE NOTE
; If menu message is not mDrawItemMsg, we will immediately return from this routine
;
JSR TruncateString
; D5 left, D6 right, A2 the string
; returns pointer to tempString(A6) where
; the truncated copy is
; may also set the condense bit in the current port
;
; NOTE that style cleanup is done at @2 below
;
;------------------------------------------------------------
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>
;------------------------------------------------------------
;
; NOTE NOTE NOTE NOTE
; If menu message is not mDrawItemMsg, we will immediately return from this routine
;
JSR TruncateString ; D5 left, D6 right, A2 the string
; returns pointer to tempString(A6) where
; the truncated copy is
; may also set the condense bit in the current port
;
; NOTE that style cleanup is done at @2 below
;
;------------------------------------------------------------
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
; note that TruncateString may truncate the string and set the condensed bit
; so the style cleanup is necessary belowÉ
MOVE.B ITEMSTYLE(A4),d0 ; did we change the face?
bne.s @styleCleanup ; Force clean of of face <63>
move.w itemScript(a4), d0 ; did we change the font? <62><63>
bge.s @styleCleanup ; Force clean of of face/font <62><63>
CMP.W #mDrawItemMsg, mMessage(a6) ; <51=BRC#79297>
BNE.S @nostyleCleanup ; always clean up on a drawItem msg ; <51=BRC#79297><63>
@styleCleanup
CLR.L -(SP) ; push empty set for TextFace and TextFont
_TextFace ; restore textface to normal
_TextFont ; restore textfont to normal
@nostyleCleanup ; <51=BRC#79297>
; if the item is disabled, gray it out <29>
TST.B enableState(A6) ; If enabled, donÕt bitclear or reset textmode
BNE.S DoneDrawItem
;IF (not forROM) THEN <SM2> rb
TST.B onColorMachine(A6) ; If color, we drew in gray so donÕt bitclear
BNE.S @fixcolor
;ENDIF <SM2> rb
BSR.S BitClearItem
;IF (not forROM) THEN <SM2> rb
@fixColor
MOVE.W #srcOr,-(SP)
_TextMode
;ENDIF <SM2> rb
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.W itemIconSize(A4) ; does it have an icon? <2.2>
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 font 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
; 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 -- 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,
; D0 has the item number of interest.
;
; On exit: A0 points to the item string of interest
; A1 points to that itemÕs attribute byte list.
; If the item canÕt be found, A0 and A1 both return NIL.
;
; Eats: D0 and D1
;
; TODO: If this is called inside a loop, 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
;<51> <KSM #34>
; We are smarter now because we just cache the last item we used
; THEREFORE this routine SHOULD be used to index thru the
; menu data structure in ALL cases!
GETITEMRECORD
TST D0 ; make sure item number is valid
BLE.S NOITEM ; if itÕs not, donÕt bother
;<34>begin
move.w D0,irTmpItemNo(A6) ; save off the initial item number
move.w irItemNo(A6), D1
beq.s @oldEntry
cmp.w D0,D1 ; is this the one we saved?
beq.s @cacheSavedTheDay ; EQ means weÕve cached this one
bgt.s @oldEntry ; GT means the cache is past D0
; Well, our cache is somewhere before D0, preflight loop entry
sub.w D1,D0 ; Offset the item number for loop entry
move.l irItemAddr(A6),A1 ; Get that itemÕs address
moveq #0,D1 ; clear D1 for byte arithmetic
move.b (A1)+,D1 ; get length that item
addq #4,D1 ; Fudge it for the initial condition
add D1,A1 ; Point past properties
bra.s GETILOOP
@cacheSavedTheDay
move.l irItemAddr(A6),A1
tst.b (A1) ; is this the NIL item?
beq.s NOITEM ; if so, we really didnÕt get one
move.l a1,a0 ; put the item string into a0
lea stackItem(a6),a1 ; cached attributes to A1
bra.s EXIT
;<34>end
@oldEntry
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
EXIT
MOVE.L A0,D0 ; and set the z-flag <2.2>
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.w irTmpItemNo(A6), irItemNo(A6) ; Save off the item weÕve cached <34>
move.l A1,irItemAddr(A6) ; Save off the address <34>
BSR.S ExpandItem ; puff item up to full size <2.2>
BRA.S EXIT ; and leave <2.2>
; ExpandItem. Take basic menu item data and fill in more with _GetAuxMenuItem.
; New in <2.1>.
; On entry: A1 points to a menu item
; A3 is the menu handle
;
; On exit: A0 points to the item string of interest
; A1 points to that itemÕs attribute byte list (on the stack)
; Eats D0, D1
ExpandItem
; copy menu item attributes to stack, split into distinct fields (unroll the variant in itemCmd).
movem.l d2/a2,-(sp) ; save regs <2.2>
; Clear out entire MF data area first
lea stackItem(a6),a0 ; address of working copy
moveq #0,d0
move #(Sizeof_extendeditem/2)-1,d0
@loop
clr.w (a0)+
dbf d0,@loop
move.l a1,a2 ; move pointer to safe register
moveq #0,D1 ; clear D1 for byte arithmetic
move.b (a1)+,d1 ; get length
add.w d1,a1 ; bump to item properties
lea stackItem(a6),a0 ; address of working copy
; set defaults (one at a time, to avoid odd-address problems since string be any length)
move.b (a1)+,(a0)+ ; copy attribute byte - itemIcon
move.b (a1)+,(a0)+ ; copy attribute byte - itemCmd
move.b (a1)+,(a0)+ ; copy attribute byte - itemMark
move.b (a1)+,(a0)+ ; copy attribute byte - itemStyle
lea stackItem(a6),a0 ; address of working copy, again
move.w #iuSystemScript,itemScript(a0) ; set default (negative) for itemScript <20>
; check for script code
moveq #0,d1 ; clear the air
move.b itemCmd(a0),d1 ; get record variant field
cmp.w #ScriptMenuCmd,d1 ; is there a script code?
bne.s notScripted ; jump if not
clr.w itemScript(a0) ; clear out for wordizing the byte <20>
move.b itemIcon(a0),itemScript+1(a0) ; if scripted, icon has script number
clr.b itemIcon(a0) ; reset field to say "no icon"
bra.s doneConvert ; rejoin
; check for hierarchical item
notScripted
cmp.w #HMenuCmd,d1 ; hierarchical menu?
bne.s notHierarchical ; jump if not
move.b itemMark(a0),itemHierarchicalID+1(a0)
add.w #256,itemHierarchicalID(a0) ; force h-menu id to be nonzero (h-menu base id = 256) <51=BRC#80417>
clr.b itemMark(a0) ; reset to say "no mark"
clr.b itemCmd(a0) ; reset to say "no command key"
bra.s unsizedIcon ; go do the icon
; check for icon and icon type
notHierarchical
cmp.w #ShrunkenIconCmd,d1 ; shrunken icon?
beq.s sizedIcon ; jump if so
cmp.w #SmallIconCmd,d1 ; small icon?
beq.s sizedIcon ; jump if so
cmp.w #NoMarkSmallIconCmd,d1 ; small icon with no mark?
beq.s sizedIcon ; jump if so
unsizedIcon
tst.b itemIcon(a0) ; is there an icon?
beq.s getAuxdata ; jump if not
move.w #LargeIconCmd,itemIconSize(a0) ; save default icon type
bra.s getAuxData ; and continue (donÕt clear itemCmd!)
sizedIcon
move.w d1,itemIconSize(a0) ; copy type to proper field
doneConvert
clr.b itemCmd(a0) ; reset field to say "no command key"
getAuxData
tst.w expandItemErr(a6) ; did we get an error for this menu?
bne.s @skipAuxCall
; Need to check if Process Mgr is installed in case we are called at <53>
; boot time from things like StdFile (InitPicker, etc.) <53>
tst.b processMgrIn(a6) ; Is Process Mgr installed? <53>
bne.s @pmgrInstalled ; NE means it is <53>
tst.b processMgrChkd(a6) ; Have we done Process Mgr check yet? <53>
bne.s @skipAuxCall ; NE means we did and it isnÕt there! <53>
st.b processMgrChkd(a6) ; Show we have done Process Mgr check <53>
move.l a0,-(sp)
move.w #$009F, d0 ; load _Unimplemented number <53>
_GetTrapAddress ; load _Unimplemented address <53>
move.l a0, d1 ; copy routine address <53>
move.w #$008F, d0 ; load OSDispatch number <53>
_GetTrapAddress ,newTool ; load OSDispatch address <53>
cmp.l a0, d1 ; Process Mgr installed? <53>
sne.b d0 ; Ones if Process Mgr installed <53>
move.l (sp)+,a0 ; Restore saved register <53>
move.b d0,processMgrIn(a6) ; was Process Mgr installed? <53>
beq.s @skipAuxCall ; EQ means unimplemented, so skip call <53>
@pmgrInstalled ; <53>
subq.l #2,sp ; room for return result
move.l a3,-(sp) ; push menu handle
move.l a2,-(sp) ; push pointer to menu item
pea itemIconHandle(a0) ; push buffer address
move.l #Sizeof_auxdata,-(sp) ; push buffer size
_GetAuxMenuItem ; get the extra info
move.w (sp)+,expandItemErr(a6) ; Save off the error code
@skipAuxCall
move.l a2,a0 ; point at name (in list item)
lea stackItem(a6),a1 ; point at the (extended) attributes
tst.l itemIconHandle(a1) ; icon handle known now?
beq.s doneExpand ; jump if not
clr.b itemIcon(a1) ; nuke unneeded resource #
doneExpand
movem.l (sp)+,d2/a2 ; restore regs <2.2>
rts ; return to sender
;----------------------------------------------------------------------------------------
;
; 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 NOT forROM THEN ; <2.2> <SM2> rb
BSR.S PushThePort
; 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 NOT forROM <SM2> rb
; 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.l -(sp) ; clear stack for TextFont/Face <FJL CXXX> <51=BRC#79297>
_TextFont ; use system font in menus <FJL CXXX> <51=BRC#79297>
_TextFace ; use standard face in menus <FJL CXXX> <51=BRC#79297>
bsr GetSizes ; get font sizes from wmgr port <FJL CXXX>
BSR.S PushThePort
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
SUB.W MBarHeight,D5 ; get what low memory says <EHB 5Aug85>
sub #16, d5 ; hierarchical menus need a little more margin <FJL C222>
MOVEQ #0,D6 ; set initial <height,width> to 0
IF 0 THEN ; We now call GetItemRecord to index thru the items (itÕs fast now) ; <51=BRC#79297>
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
ENDIF
MOVEQ #1,D4 ; D4 is the item number counter ; <51=BRC#79297>
;
; here is the main loop of calcMenuSize. Process each item one at a time, keeping the
; height and maximum width in D6
;
CMLOOP
MOVE.L D4,D0 ; find current item record ; <51=BRC#79297>
MOVE.L (A3),A0 ; point to the menuRecord ; <51=BRC#79297>
BSR.S GetItemRecord ; point to first item ; <51=BRC#79297>
BEQ DoCalcDone1 ; if zero, weÕre done ; <51=BRC#79297>
MOVE.L A0,A4 ; keep pointer in A4 ; <51=BRC#79297>
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
; 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>
@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>
BSR GetItemWidth ; calc the width of the requested item < kaz #44>
CMP D0,D6 ; compare with maxWidth
BGE.S CALCNEXT ; if max is bigger, go process next one
MOVE D0,D6 ; this one was the biggest
;
; go process next item; loop till we get a null one
;
CALCNEXT
IF 0 THEN ; Calling GetItemRecord keeps us from calling ExpandItem unnecessarily. <51=BRC#79297>
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
MOVE.L a4,a1 ; for expansion <2.2>
BSR ExpandItem ; et, voila! <2.2>
ENDIF
ADDQ #1,D4 ; Point to next item <51=BRC#79297>
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.
BSR.S PushThePort
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
@SizeOK
MOVE.W D6,MENUHEIGHT(A0) ; update menu height
; GetItemWidth/GetItemHeight preserve TextFace internally now <51=BRC#79297>
; CLR.W -(SP) ; better restore style to normal
; _TextFace ; set the style
; IF NOT forROM THEN ; <2.2> <SM2> rb
_SetPort ; restore original grafPort <PMAB364 23Jan88 EMT>
; ENDIF ; if NOT forROM <SM2> rb
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
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
;
BSR.S PushThePort
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 ; <2.0 BRC#44525> Remove the even value (they never round well)
SUB #7, D0 ; <2.0 BRC#44525> This is not enough slop to prevent rounding problems
SUB.W MFHeight(A6), D0 ; <2.0 BRC#44525> Subtracting item height gives enough
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
;===============================================================================================
; start addition <BBH>
;----------------------------------------------------------------------------------------
;
; Msg #4 -- Draw Item -- going to draw an item in the menu in the given rectangle
;
;----------------------------------------------------------------------------------------
;
; here is the part of the TextMenuProc that draws the menu. For most of this routine,
; A3 holds the menuHandle, D4 is the item to be drawn
;
DoDrawItemMsg
bsr GetSizes ; get font info into stackframe
MOVE.L MMENURECT(A6),A0 ; < BBH 12/4/89 > get the menuRect
MOVE.W top(A0),D3 ; < BBH 12/4/89 > get the top of the rectangle to draw in
ADD.W MAscent(A6),D3 ; < BBH 12/4/89 > add in the ascent for baseline
MOVE.L MWHICHITEM(A6),A0 ; < BBH 12/4/89 > get the item to draw
MOVE.W (A0),D4 ; < BBH 12/4/89 > dereference
; We need to color the background for the item
bsr SaveCurrentColors ; save fore/back colors in stackframe
move #mctRGB2, colorOffset(a6) ; use the item color if there is an entry
bsr SetColors ; set colors
MOVE.L MMENURECT(A6),-(SP) ; get menuRect pointer
_EraseRect
bsr ResetPreviousColors ; and set back to the previous stuff
MOVE.L MMENURECT(A6),A0 ; get menuRect pointer
bsr DrawTheItem ; call drawing routine
rts
;----------------------------------------------------------------------------------------
;
; Msg #5 -- Calc Item -- calculate rectangle for given item
;
;----------------------------------------------------------------------------------------
;
; here is the part of the TextMenuProc that draws the menu. For most of this routine,
; A3 holds the menuHandle, D4 is the item to be drawn
;
DoCalcItemMsg
MOVE.L A3, -(SP) ; push menu handle
_CalcMenuSize ; get valid height and width
BSR GetSizes ; get font info into the stack
MOVE.L MWHICHITEM(A6),A0 ; < BBH 12/4/89 > get the item to calculate
MOVE.W (A0),D0 ; < BBH 12/4/89 > dereference
MOVE.L (a3),a0 ; get pointer to menu
BSR GETITEMRECORD ; look it up
BEQ.S @noItem ; if so, nothing selected
MOVEA.L A0,A4 ; store the string in a4 for GetItemWidth
; a1 = item attr byte list
BSR GetItemHeight ; get height of item in D0, icon size in D1
SWAP D1 ; get icon width in low word
MOVE.W D1,D7 ; store there for GetItemWidth
ADD.W MSpaceWidth(A6), D7 ; Add in width of a single space
;; <56> removed ADDQ.W #4, D7 fudging factor
MOVE.L MMENURECT(A6),A0 ; get the menuRect
MOVE.W top(A0),D3 ; get the top
ADD.W D0,D3 ; add height
MOVE.W D3,bottom(A0) ; set the bottom
BSR GetItemWidth ; gimme the width of the item in D0
MOVE.L MMENURECT(A6),A0 ; get the menuRect
MOVE.W left(A0),D3 ; get left of menu
ADD.W D0, D3 ; add the width
MOVE.W D3,right(A0) ; and set the right
BRA.S @done
@noItem
MOVE.L MMENURECT(A6),A0 ; get the menuRect
MOVE.W top(A0), bottom(A0) ; no width or height
MOVE.W left(A0), right(A0)
@done
rts
; end addition <BBH>
;===============================================================================================
;----------------------------------------
; 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
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
@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
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
@ResetBW
tst invertFlag(a6) ; normal or inverted colors ? <51=BRC#79297>
beq.s @ResetEnd ; 0 = normal colors, so no need to reset <51=BRC#79297>
moveq #BlackColor, d0 ; always reset to black on white
move.l d0, -(sp)
_ForeColor
moveq #WhiteColor, d0
move.l d0, -(sp)
_BackColor
@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
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
@SetBW
tst invertFlag(a6) ; normal or inverted colors ? <51=BRC#79297>
beq.s @SetColorsDone ; 0 = normal colors, so branch <51=BRC#79297>
moveq #WhiteColor, d0 ; <51=BRC#79297>
move.l d0, -(sp) ; <51=BRC#79297>
_ForeColor ; <51=BRC#79297>
moveq #BlackColor, d0 ; <51=BRC#79297>
move.l d0, -(sp) ; <51=BRC#79297>
_BackColor ; <51=BRC#79297>
@SetColorsDone ; <51=BRC#79297>
rts
;----------------------------------------
; Utility -- TruncateString <BBH 12/4/89>
;----------------------------------------
;
; On Entry: A4 item information
; D1 system justification
; D5 left
; D6 right
; A2 pointer to string
; on exit: A2 pointer to tempString(A6) with truncated string
; Used: A0, A1, D0, D1
;
TruncateString
; note that for normal draw messages, we will not need to truncate
; because of the mCalcItemMsg will give us enough room (we hope)
;
CMP.W #mDrawItemMsg, mMessage(a6)
BEQ.S @GoTruncate ; (fixed <6>)
rts
@GoTruncate
MOVEM.L D1/D3,-(SP) ; save register
; are we big enough?
MOVE.W D6, D3 ; D2 get the width = right
SUB.W D5, D3 ; minus left
SUB.W #1, D3 ; minus right indent
CLR.W -(SP) ; returned length
MOVE.L A2,-(SP) ; push string
_StringWidth ; will smash D1
MOVE.W (SP)+,D0 ; get result
CMP.W D0,D3
BGT.S @TruncateDone ; D3>D0 (size avail > string width)
; copy the string please
MOVEQ #0,D0 ; clear length
MOVE.L A2, A0 ; < BBH 12/4/89 >
LEA.L tempString(A6),A1 ; < BBH 12/4/89 >
MOVE.L A1,A2 ; store in a2 which is the string to return
MOVE.B (A0),D0 ; < BBH 12/4/89 >
ADDQ #1,D0
_BlockMove ; < BBH 12/4/89 >
;Removed 'cuz it's ugly <#19 kaz>
; set the condensed bit please
; MOVE.B ITEMSTYLE(A4),D0
; BSET #condenseBit,D0 ; add condensed
; MOVE.W D0,-(SP) ; and set it
; _TextFace
SUBQ #2,SP ; returns whether string truncated
MOVE.W D3,-(SP) ; width
MOVE.L A2,-(SP) ; put the string pointer
MOVE.W #smTruncEnd, -(SP) ; truncate at end
_TruncString
ADDQ #2,SP ; pop result (and ignore it)
@TruncateDone
MOVEM.L (SP)+,D1/D3 ; restore work register
RTS
;--------------------------------------------------------------------------------------------
;
; 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