boot3/Toolbox/MenuMgr/StandardMDEF.a

3323 lines
133 KiB
Plaintext
Raw Normal View History

;
; File: StandardMDEF.a
;
; Contains: Standard text menu definition procedure.
;
; Originally written by Andy Hertzfeld in July 1982.
;
; Copyright: <09> 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<6F>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<6F>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<69>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() <20>
; 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<64>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.
; <<3C>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<6F>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<6F>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<6F>t know if Process Mgr installed <53>
clr.b processMgrChkd(a6) ; Haven<65>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<73>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<6E>s left side? <FJL C222>
blt NoItemSel ; yes, so no item selected <FJL C222>
cmp right(a2), d5 ; to right of menu<6E>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<61>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<73>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<6F>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<73>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<69>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<64>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<69>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<77>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<6F>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<77>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<6F>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<6E>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<61>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<65>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<6F>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<61>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<69>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<65>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<73>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<65>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<61>s custom "line" menu does not handle "choose item" message properly.
; Of course it<69>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<65>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<65>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<64>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<6F>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<69>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<73>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<6F>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<6F>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<65>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<65>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<63>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<61>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<61>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<6F>t use it
@checkIconGray
tst stackItem+itemIconGray(A6) ; end else if (itemIconGray=true) then
beq.s @haveTransform ; EQ -> ProcessMgr doesn<73>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<65>s baseline, top of item + font<6E>s ascent
; d4 Item Number
; d5 left edge, pixels
; d6 right edge, pixels
; a2 item<65>s string pointer
; a4 item<65>s properties pointer
; -- GetSizes has been called
;
; Now: <S550 27Jul88 EMT>
; On entry: D3 Item<65>s baseline, top of item + font<6E>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<6F>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<65>s rect
Bsr GetItemHeightA4 ; get item<65>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<63>s <51>
; attempt to get color icon first and if unsuccessful then get regular icon <FJL C408>
tst.b itemIcon(a4) ; icon spec<65>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<76>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<63>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<6F>
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<6F>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<6F>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<70>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<65>s attribute byte list.
; If the item can<61>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<61>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<69>s not, don<6F>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<77>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<65>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<64>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<77>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<64>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<64>t get one
move.w irTmpItemNo(A6), irItemNo(A6) ; Save off the item we<77>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<65>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<6F>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<73>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<67>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<69>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<77>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<77>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<77>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<6F>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<77>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<6E>s vertical height without worrying about saving more bits each
; time it got bigger. But we can<61>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<65>s vertical in D2, and continue
;
; We didn<64>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<64>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<69>s vertical is in D2
MOVEQ #1, D4 ; yes ==> couldn<64>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<65>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<65>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<6F>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<69>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<77>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<63>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 <20>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<63>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<6D>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<65>s color entry
move.l (sp)+, d1 ; get the result, and set/un-set z-flag
beq.s @TryTitleEntry ; couldn<64>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<6C>s color entry
move.l (sp)+, d1 ; get the result, and set/un-set z-flag
beq.s @TryMenuBarEntry ; couldn<64>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<61>s color entry
move.l (sp)+, d1 ; get the result, and set/un-set z-flag
beq.s @SetDefault ; couldn<64>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