Font Dialog
Volume Number: | | 4
|
Issue Number: | | 7
|
Column Tag: | | Assembly Language Lab
|
Font Dialog Box Using List Manager
By Ray A. Cameron, Brunswick, Victoria, Australia
Ray. A. Cameron is an Electrical Engineer from Brunswick, Victoria in Australia, employed by Telecom, the Australian Telecommunication Commission. He is currently involved in the introduction of optical fibre into the Customer Access Network. This is his first article for MacTutor.
MacTutor Down Under
Before I start writing about my routines ld like to say how fantastic MacTutor is for the service that it is providing to Mac programmers in disseminating programming ideas and techniques. It doesnt matter which language we program in, it is possible to gain information from every article published in MacTutor.
Something that I know would be beneficial to all readers of MacTutor is if the writers of articles include in their description not only how the program works (as published) but what problems they have encountered along the way or techniques thay have employed and why. Also any idiosyncrasies in the system software that dont appear to be fully explained in Inside Macintosh.
What This Program Does
The FontDialog routine displays a Modal Dialog box for the user to select a font name, size and style. The routine is designed to be incorporated into a program, as I have done with the Window example (distributed with the old MDS software and included here), which is on this months source disk. There are two routines that I have written, the first routine (SetupFontMap) creates a record of all the FONT resources available to the user in the system file. It doesnt look for FOND or NFNT resources or fonts attached to documents. The next routine (FontDialog) creates a Modal Dialog box (Fig 1) so that the user can choose a font name, size and style. The font name and size lists are created with the List Manager from data stored in the FontMap record. The routine also includes a UserFilter with the Modal Dialog to handle events.
Some of the procedures and functions used in the FontDialog routine take up a number of lines and are used often so lve converted them into Macros to save space. I wont describe the Macro file as it should be self explanatory.
Fig. 1 Our Font Dialog Box selects text, size & style
User Interface
The Dialog box presented in this example is similar to the one in Microsoft Word. Now that we can all use nested menus to select font, size and style, you might want to be old fashioned and go back to a text dialog box instead! You can select a font name by either clicking on a font name or by typing a character to select the first name starting with that character (or the first name to follow in alphabetical order). As you continue to type additional characters (up to 31) any file that matches the characters you type is found and selected. If you pause while typing, the next character is considered to be a new request, rather than a continuation of your first request. The Delay Until Repeat setting which you set in the (Control Panel) determines how long you can pause before additional characters are considered to be a new request. Hence our dialog box is fairly intelligent in that it includes a sort and search routine and uses the list manager, useful techniques for a variety of dialog functions.
The Font Size Selection Window displays the sizes that are currently available on the system (for the selected font name). If no font name is selected then the Font Size Selection Window is blank, this doesnt affect the font size in the textedit window. A font size can be selected by clicking on the desired size or by typing in the font size. Numbers and the back space character are assumed to be an input to alter the font size, whilst all other characters (except cr & enter) are used to find a matching font name. The font style has been separated into two sections, spacing (condense and extend) and style (outline, bold, etc). When the dialog box is first displayed the radio buttons and check boxes reflect the current settings. If their settings are altered it is possible to reset them to their original values by clicking on the group title concerned (either spacing or style). The settings are only reset if the mouse is released inside the title. To indicate that the mouse is inside the title the thickness of the frame around the group doubles. This type of facility (interface) lends itself to having the groups set to normal or plain if a double click occurs in the title, something which I havent implemented here.
At the bottom of the dialog box is displayed some (sample) text showing the affect of the selected settings. The sample text will only be displayed if the current settings of font name and size are valid. A valid font size can be from 4 to 127, normal quickdraw limitations.
If the Ok button is selected or the cr or enter keys are pressed while the current settings are invalid an alert box is displayed indicating which setting isnt valid.
Fig. 2 After text selection, our sample text window allows typing in the chosen font & style
FontMap
To produce the dialog box I require the names of the available fonts on the system as well as the sizes available for each font. The idea of a font menu with a range of font sizes on it (ie MacWrite) is relatively easy, all that is required is to test if the selected font has a desired size. If it does then the size is shown in outlined style, whilst if it doesnt its style is plain. To find every size available on the system for a particular font name is a little harder. I decided to produce a relocatable block which would contain the names of all the fonts (in alphabetical order) and the sizes of each font (in numerical order). Doing this reduces the amount of time required to set-up the Font Name and Font Size Selection Windows. Note that even some commercial software doesnt bother to alphabetize font lists! A graphical representation of the FontMap is shown in Fig 3. The first (word) field contains the number of different fonts minus one. Then there are font references, one reference (of three words) for each font. The first field is the font number, the next is the offset to the font name and the last is the offset to the font size list. Both offsets are from the start of the FontMap. The font references are sorted into the alphabetical order of the font names. The space allocated for each font name is the smallest number of even bytes that the name will fit in. The font sizes for each font are sorted into their numerical order within each font size list. The first word of the font size list is the number of font sizes in the list, then follows the font sizes, one word per font size. The handle to the Map is stored for access by the FontDialog routine and could be used to prepare the font sizes in a menu. By having the names and sizes sorted within FontMap it means that when they are placed into a list their cell position relates to their position in the FontMap.
Fig. 3 Layout of our custom font map structure
Apple have laid down in their user interface guidelines that font sizes that exist on a system be represented in some way, as in outlining in a menu etc. With the new font family resources (FONDs & NFNTs) it is possible to have a font that already has a style attribute associated with it, like Geneva Shadow. How are these fonts to be represented so that the user can tell them apart from a plain font size? The text sample is one solution and perhaps there are others.
Creating the Font Map
The SetupFontMap routine is called at the start of a program so that the FontMap can be used to set up the font size menu items. The routine, first of all evaluates what size to make the Map (relocatable block). It examines each FONT resource on the system and determines if the resource contains a font name or a font size. If the resource is a font name, the font (resource) ID and the pointer to the name are stored on the stack. If the resource is a font size, the font (resource) ID is stored in a non-relocatable block (SizeBlock). As each resource is examined, a running total is kept of how large to make the FontMap and how many different fonts there are. The FontMap is created and the number of font names minus one is loaded into the first field. The font IDs and name pointers are loaded into the font references from the stack. The font references are then sorted into the alphabetical order of the font names. The font names are then loaded into the Map, disposing of their original non-reloctable block in the process and replacing the name pointer with an offset. SetupFontMap then goes through SizeBlock and loads in all the font sizes associated with the first font. The sizes are then sorted into numerical order. SetupFontMap then continues until all fonts have their sizes loaded and sorted. All temporary blocks are disposed of as the routine is finished with them. The FontMap is then unlocked and control returns to the main program.
This routine should be rewritten so that it examines the font resources (FOND , FONT and NFNT) and the font resources associated with a document. It should also be recalled each time a new document is accessed in case there is a new font resource associated with it. But thats a task lll leave for you. [Note that Apple discourages the use of fonts within documents now. -Ed]
Font Dialog Mechanics
The FontDialog routine would generally be accessed by the selection of a menu item. The items associated with a dialog are stored in an item list which contains the item type, whether its enabled or not and a pointer to the routine that will draw the item, as well as other variables. The order of the items in the list is very important (as I found out). The items are drawn and accessed in the order that they appear in the item list. If items overlap, the item highest in the list (lowest item number) takes precedent. I wanted to set up the spacing and style groups as shown in Fig 1 so that if I clicked on either the title or a control, the program returned from the ModalDialog trap. At this stage of writing the program I wasnt using a UserFilter so I had to create routines to draw the bold frame around the Ok button and thin frames around the control groups. The problem arose when I wanted to draw the frame and the group title so that the frame wasnt drawn through the title (as per Fig 1). If the frame is drawn then the title, the routine that draws the title erases a section of the frame where the title goes. To do this the useritem would have to have a lower item number than the title. The useritem that represented the frame was disabled so I thought that the other items that were enabled wouldnt be affected by it. Wrong! By placing the useritem higher in the item list than the other items I had made all the lower items except for the top half of the title effectively invisible/disabled. To get around this problem (before I used a UserFilter) I placed the useritem lower in the item list and wrote a subroutine similar to TrackHeading. The routine created a region consisting of the useritem rect minus the group title rect, and made it the clipping region, it then drew a frame around the useritem rect and reset the clipping region. For details on regions and clipping check Chris Derossis article on Quickdraw Does Regions! (Pascal Procedures) in MacTutor Vol 1 No 3, February 1985. When a User Filter is used, the programmer isnt confined to accessing the dialog items in their order, which simplifies the drawing of the items.
The FontDialog routine creates a non-relocatable block into which it stores all its variables. This was done so that memory is allocated only when the routine is called. It allows the main program to check to see if there is enough spare memory before the routine is called, or the routine could become a separate code segment that isnt loaded into memory until its needed. The routine takes copies of the font number, size and face (style) that are passed to it so that these can be altered without affecting the original values, in case the user decides to cancel the dialog. The routine only accepts a single font variation (number, size and style), it isnt suitable for altering multiple font variations.
The spacing radio buttons and style check boxes are set up to display the original settings. I made the condense and extend style variations radio buttons because there is no point in both variations being selected (they cancel one another out).
The Font Name and Size Selection Windows are then created and the available font names and sizes are loaded into their respective list. Each list has its selection flags set so that only one cell is selected at a time and empty cells arent selectable. Even though the selection flag was set so that only one cell is selected, I found that I could select more than one cell by using the LSetSelect trap. I wanted to set a cell and I assumed that the List Manager would deselect the currently selected cell. Instead I had to deselect the currently selected cell and then select the desired cell (as shown in DKeyDown). When the mouse is used to select a cell, only one cell is selected, all others are deselected.
Only enough cells are created in each list to contain the font names and sizes. In some cases there are blank lines in the list. Clicking below the cells deselects the current selection, sometimes. For some reason it is possible to click below the cells in one spot and have the selection deselected while not in others. The area in which this occurs is the height of a cell.
A Sample Display Text Edit Record is then setup so that the STR resource number 264 is displayed in the useritem rect at the bottom of the dialog box. The string is displayed with the current font settings, if they are valid, if they arent valid then no text is displayed. The text is centered horizontally within the useritem rect, and also vertically if all the lines are visible.
The handles of the string resources to be used by the alert window are then loaded into the local variable block.
As the user modifies the settings in the dialog box, the routine checks to make sure that they are valid. If they arent valid a flag (OkActive) is cleared. I originally set the Ok button to be hilited with #254 (if the selections are invalid) which is supposed to make the control inactive but still indicate if it has been clicked in. When I did this, I found that the Ok button would be grey but it wouldnt indicate if it was clicked in. If I dragged the mouse an outline of the Ok button would move in the vertical axis. The problem occured when I let the default Modal Dialog routine handle the mouse or when I caught the event in the UserFilter and used the TrackControl trap. For this reason lve left the Ok button active when the settings are invalid and display an alert if the Ok button, cr or enter are selected. Before the alert is displayed the routine determines which variables arent valid and sets up the param strings accordingly. I havent checked to see if this still occurs since my Mac has been enhanced. From a user interface perspective it is good practice to inform the user what the problem is instead of not accepting their input or sounding a beep.
After the items have all been set up the ModalDialog trap is called.
Dialog Filter Proc
The DUserFilter filters all the events that it needs to handle and lets the default routine handle the remainder (by returning false). DUserFilter handles its events and returns true and an item No. if the main program is to do some variable updating or house keeping due to the event (ie a new font name is selected). When the DUserFilter handles an event and a setting hasnt altered, ie a click on the selected font name, the event is converted to a null event.
DNull checks to see if the mouse is within the textedit rect, if it is it converts the cursor to a handle, otherwise it sets it to the arrow. This section of code could be sped up by storing the textedit item rect in the local variable block instead of using the GetDItem trap every time. When ever a font attribute is altered the sample text is erased and the routine waits until KeyThresh ticks have occured and then redraws the sample with the new attributes. The DNull code checks to see if KeyTresh ticks have passed and if the sample requires updating. If it does then the DUserFilter returns true and item number 21 (a disabled useritem).
DMouseDown handles the mouse down events within the two group titles and the two list windows. All other mouse down events are handled by the default ModalDialog routines. When a mouse down occurs in either of the two group titles the routine (TrackHeading) tracks the mouse to see if it is released in it or not. If it is, ModalDialog returns with the item number, otherwise the event is set to null. When a mouse down occurs in either of the List Manager windows the routines check to see if the selection has altered. If it has ModalDialog returns with the item number, otherwise the event is set to null.
DKeyDown checks for a cr or enter key and returns item No 1 (Ok button) if it finds one. It then checks to see if a number or back space character has been pressed, if one has it deselects the selected cell in the Font Size Selection Window (if one is selected) and returns false for the default ModalDialog routine to handle it. DKeyDown then uses the character to search for a font name (NameSearch), as described in the User Interface section. The List Manager trap LSearch isnt suitable because it only checks for exact matches and I required the routine to check strings using the IUMagString trap. The FontMap is searched through because it is quicker than using the List Manager routines to check each cells contents. The routine then makes sure the desired cell is selected and visible.
DUpdate updates all the items in the dialog box. The update event removes the need to have an item number for every item that is drawn. A prime example is the bold box around the Ok button, another is the frame around the textedit item. Items dont have to be drawn in the order in which they appear in the dialogs item list. This allows the frames to be drawn around the spacing and style control item groups before the group titles are drawn. The programmer has complete control over what is drawn in the dialog and could in fact draw something that isnt related to an item in the item list. When lists are drawn they dont have a frame drawn around them, so lve had to include one on each list. After everything has been updated the event is set to a null event (SetoNull) and returned.
DActivate activates the dialog box (the two list windows and the dialog boxs text edit record). Ive also included the code to deactivate the dialog box, even though it never gets used. When the ShowWindow trap is called to display the dialog box the window is created, a deactivate event is created for the original front window as is an activate event for the dialog window. The main programs deactivate code isnt accessed because its event loop has been broken, the main program has to deactivate the front window before the dialog box routine is called. DActivate has to be able to filter out the (de)activate event for the original front window and not handle it. When the alert is shown, the dialog should be deactivated (just like the case above) with similar code to that in DDeactivate. The LActivate trap removes (hides) scroll bars when the list is deactivated instead of inactivating them so I didnt include the deactivate code because it was visually undesirable (sloppy).
The routines that handle the result of the ModalDialog trap perform the following functions:
DOk displays an alert if the settings arent valid and returns to the ModalDialog loop (WaitOk). If the settings are valid the original values are replaced with the desired values. The routine then passes onto DCancel.
DCancel closes the dialog box and disposes of the unwanted records and the local variable block. When there is a lot of information to be included (displayed) in a dialog, it is best to initially set the dialog to be invisible, setup the items involved and then show the dialog. This creates a clean crisp presentation, as opposed to items appearing slowly with delays between items. The same philosophy applies when the dialog is being closed. It is better to hide the dialog first and then to dispose of the items rather than to see items within the dialog (window) disappear before the window does, very sloppy.
Style resets the control check boxes to their original settings after the user has clicked in the style title. SStyle toggles a check box after it has been clicked in.
Spacing resets the control radio buttons to their original settings after the user clicked in the spacing title. SSpacing sets the radio button that was clicked in and clears the other radio buttons within the group.
The ModalDialog default routine handles a mouse down event in the control items (radio buttons and check boxes) and tracks the mouse and returns (with that items number) if the mouse is released within the item. The main routine then alters the value of the control, knowing that it was clicked in, this allows groups of radio buttons to be organised together.
FontName updates the font number variable after a new font name was selected. The Font Size Selection Window is then updated to show the sizes associated with the new font name. If no font name is selected the Font Size Selection Window is cleared.
FontSize updates the font size variable after a new font size was selected from the Font Size Selection Window. The textedit item (No 20) is then updated to display the new font size. If no font size was selected the textedit item retains its previous value (it isnt set to zero).
GetEditSize updates the font size variable after the user has altered the textedit item through a key stroke (0 through to 9 or backspace). The currently selected size in the Font Size Selection Window is deselected. The ModalDialog default routine returns with the textedit item number when the mouse is clicked within its rect even though its value doesnt change.
FontSample updates the font attributes associated with the sample text at the bottom of the dialog box. The text is then centered vertically within the user item rect if the height of the text lines is less than the height of the rect. The sample is then displayed with the new attributes.
Each of the above routines have code included in them to check if their font variable has in fact altered, if it has the sample text is then erased and isnt updated until KeyThresh ticks have lapsed.
Ill leave the remaining description of the routines to the comments placed within each listing. Best of luck with writing your dialog.
Fig. 4 A simple About Box Dialog
Continued in next frame
|
|
Volume Number: | | 4
|
Issue Number: | | 7
|
Column Tag: | | Assembly Language Lab
|
Font Dialog Box Using List Manager (code)
; File Window.Asm
;----------------------------------------------------------
; Macintosh 68000 Development System
;----------------------------------------------------------
; The Window Sample Program issued with the MDS.
; Modified by Ray.A.Cameron to demonstate a Modal Dialog Box.
; Mon May 4, 1988 21:29:54
This application displays a window within which you can enter and edit text. Program control is through four menus: the Apple menu, the File menu, the Edit menu, and the Font menu.The Apple menu has the standard desk accessories and an About feature. The File menu lets you quit the application. The Edit menu lets you cut, copy, paste, and clear the text in the window or in the desk accessories. Undo is provided for desk accesories only. Command key equivalents for undo, cut, copy, and paste are provided. The Font menu lets you display a Modal Dialog Box to select a Font Name, Size and attributes.
;----------------------- Includes ----------------
Include Traps.D ; Use System and ToolBox traps
Include ToolEqu.D; Use ToolBox equates
Include QuickEqu.D ; Use QuickDraw equates
Include SysEqu.D ; Use System equates
Include PackMacs.Txt ; Use Package equates
;------------------- Use of Registers -----------
; Operating Sys and Toolbox calls preserve D3-D7, A2-A4.
; Register use: A5-A7 are reserved by the system
; D1-D3, A0-A1 are unused
; D0 is used as a temp
ModifyReg Equ D4 ; modifier bits from GetNextEvent
MenuReg Equ D5 ; menu ID from MenuSelect,MenuKey
MenuItemReg Equ D6; item ID from MenuSelect,MenuKey
AppleHReg Equ D7; handle to the Apple Menu
TextHRegEqu A2 ; handle to TextEdit record
WindowPRegEqu A3; pointer to editing window
EditHRegEqu A4 ; handle to Edit menu
;------------------- Equates ----------------
; These are equates associated with the resources
; for the Window example.
AppleMenu Equ 1 ; First item in MENU resource
AboutItem Equ 1 ; First item in Apple menu
FileMenuEqu 2 ; Second item in MENU resource
QuitItem Equ 1 ; First item in File menu
EditMenuEqu 3 ; Third item in MENU resource
UndoItemEqu 1 ; Items in Edit menu
CutItem Equ 3 ; (Item 2 is a line)
CopyItemEqu 4
PasteItem Equ 5
ClearItem Equ 6
FontMenuEqu 4 ; Fourth item in MENU resource
DialogItemEqu 1 ; Only item in Font menu
AboutDialog Equ 1 ; About dialog is DLOG resource #1
ButtonItemEqu 1 ; First item in DITL used by DLOG #1
ASample Equ 1 ; Sample Window is WIND resource #1
;-------------------- Xdefs ----------------
; Xdef all labels to be symbolically displayed by debugger.
Xdef Start
Xdef InitManagers
Xdef SetupMenu
Xdef SetupWindow
Xdef SetupTextEdit
Xdef Activate
Xdef Deactivate
Xdef Update
Xdef KeyDown
Xdef MouseDown
Xdef SystemEvent
Xdef Content
Xdef Drag
Xdef InMenu
Xdef About
XRef SetupFontMap ; Routines
XRef FontDialog
XRef FontMap ; Variable
;----------------- Main Program -------------
Start
Bsr InitManagers ; Initialize managers
Bsr SetupMenu; Build menus, draw menu bar
Bsr SetupWindow; Draw Editing Window
Bsr SetupTextEdit; Initialize TextEdit
Bsr SetupFontMap ; Initialize the FontMap
EventLoop ; Main Program Loop
_SystemTask; Update Desk Accessories
; ProcedureTEIdle (hTE:TEHandle);
Move.l TextHReg,-(SP) ; Get handle to text record
_TEIdle; blink cursor etc.
; Function GetNextEvent(eventMask: Integer
; Var theEvent: EventRecord) : Boolean
Clr -(SP) ; Clear space for result
Move #$0FFF,-(SP) ; Allow 12 low events
Pea EventRecord; Place to return results
_GetNextEvent ; Look for an event
Move (SP)+,D0 ; Get result code
Beq EventLoop; No event... Keep waiting
Bsr HandleEvent; Go handle event
Beq EventLoop; Not Quit, keep going
Rts ; Quit, exit to Finder
Note: When an event handler finishes, it returns the Z flag set. If Quit was selected, it returns with the Z flag clear. An Rts is guaranteed to close all files and launch the Finder.
;------------------- InitManagers -------------
InitManagers
Pea -4(A5) ; Quickdraw's global area
_InitGraf; Init Quickdraw
_InitFonts ; Init Font Manager
Move.l #$0000FFFF,D0; Flush all events
_FlushEvents
_InitWindows ; Init Window Manager
_InitMenus ; Init Menu Manager
Clr.l -(SP) ; No restart Procedure
_InitDialogs ; Init Dialog Manager
_TEInit; Init Text Edit
_InitCursor; Turn on arrow cursor
Rts
;--------------------- SetupMenu ---------------
SetupMenu
; Apple Menu Set Up.
; Function GetMenu (menu ID:Integer): MenuHandle;
Clr.l -(SP) ; Space for menu handle
Move #AppleMenu,-(SP) ; Apple menu resource ID
_GetRMenu; Get menu handle
Move.l (SP),AppleHReg ; Save for later comparison
Move.l (SP),-(SP) ; Copy handle for AddResMenu
Clr -(SP) ; Append to menu
_InsertMenu; Which is currently empty
Move.l #'DRVR',-(SP); Load all drivers
_AddResMenu; And Add to Apple menu
; File Menu Set Up
Clr.l -(SP) ; Space for menu handle
Move #FileMenu,-(SP) ; File Menu Resource ID
_GetRMenu; Get File menu handle
Clr -(SP) ; Append to list
_InsertMenu; After Apple menu
; Edit Menu Set Up
Clr.l -(SP) ; Space for menu handle
Move #EditMenu,-(SP) ; Edit menu resource ID
_GetRMenu; Get handle to menu
Move.l (SP),EditHReg; Save for later
; Leave on stack for Insert
Clr -(SP) ; Append to list
_InsertMenu; After File menu
; Font Menu Set Up
Clr.l -(SP) ; Space for menu handle
Move #FontMenu,-(SP) ; Font Menu Resource ID
_GetRMenu; Get File menu handle
Clr -(SP) ; Append to list
_InsertMenu; After Edit menu
_DrawMenuBar ; Display the menu bar
Rts
;---------------- SetupWindow ---------------
SetupWindow
; Function GetNewWindow (windowID: Integer; wStorage: Ptr;
; behind: WindowPtr) : WindowPtr;
Clr.l -(SP) ; Space for window pointer
Move #ASample,-(SP) ; Resource ID for window
Pea WindowStorage(A5) ; Storage for window
Move.l #-1,-(SP); Make it the top window
_GetNewWindow ; Draw the window
Move.l (SP),WindowPReg ; Save for later
_SetPort ; Make it the current port
Rts
;------------- SetupTextEdit ----------------
SetupTextEdit
; ProcedureTENew (destRect,viewRect: Rect): TEHandle;
Clr.l -(SP) ; Space for text handle
Pea DestRect ; DestRect Rectangle
Pea ViewRect ; ViewRect Rectangle
_TENew ; New Text Record
Move.l (SP)+,TextHReg ; Save text handle
Rts
;------------- Event Handling Routines --------
HandleEvent
Use the event number as an index into the Event table. These 12 events are all the things that could spontaneously happen while the program is in the main loop.
Move Modify,ModifyReg ; More useful in a reg
Move What,D0 ; Get event number
Add D0,D0 ; *2 for table index
Move EventTable(D0),D0 ; Point to routine offset
Jmp EventTable(D0) ; and jump to it
EventTable
Dc.w NextEvent-EventTable ; Null Event (Not used)
Dc.w MouseDown-EventTable ; Mouse Down
Dc.w NextEvent-EventTable ; Mouse Up (Not used)
Dc.w KeyDown-EventTable ; Key Down
Dc.w NextEvent-EventTable ; Key Up (Not used)
Dc.w KeyDown-EventTable ; Auto Key
Dc.w Update-EventTable ; Update
Dc.w NextEvent-EventTable ; Disk (Not used)
Dc.w Activate-EventTable ; Activate
Dc.w NextEvent-EventTable ; Abort (Not used)
Dc.w NextEvent-EventTable ; Network (Not used)
Dc.w NextEvent-EventTable ; I/O Driver (Not used)
;-------------------- Event Actions -----------------
Activate
An activate event is posted by the system when a window needs to be activated or deactivated. The information that indicates which window needs to be updated was returned by the NextEvent call.
Cmp.l Message,WindowPReg; Was it our window?
Bne NextEvent ; No, get next event
Btst #activeFlag,ModifyReg ; Activate?
Beq Deactivate ; No, go do Deactivate
To activate our window, activate TextEdit, and disable Undo since we don't support it. Then set our window as the port since an accessory may have changed it. This activate event was generated by SelectWindow as a result of a click in the content region of our window. If the window had scroll bars, we would do ShowControl and HideControl here too.
; ProcedureTEActivate (hTE: TEHandle);
Move.l TextHReg,-(SP) ; Move Text Handle To Stack
_TEActivate; Activate Text
; Procedure DisableItem (menu:MenuHandle; item:Integer);
Move.l EditHReg,-(SP) ; Get handle to the menu
Move #UndoItem,-(SP) ; Enable 1st item (undo)
_DisableItem
SetOurPort; used by InAppleMenu
Move.l WindowPReg,-(SP) ; an accessory might have
_SetPort ; changed it.
NextEvent
Moveq #0,D0; Say that it's not Quit
Rts ; return to EventLoop
Deactivate
Move.l TextHReg,-(SP) ; Get Text Handle
_TeDeActivate ; Un Activate Text
Move.l EditHReg,-(SP) ; Get handle to the menu
Move #UndoItem,-(SP) ; Enable 1st item (undo)
_EnableItem
Bra NextEvent; Go get next event
Update
The window needs to be redrawn. Erase the window and then call TextEdit to redraw it.
; ProcedureBeginUpdate (theWindow: WindowPtr);
Move.l WindowPReg,-(SP) ; Get pointer to window
_BeginUpDate ; Begin the update
; EraseRect (rUpdate: Rect);
Pea ViewRect ; Erase visible area
_EraseRect
; TEUpdate (rUpdate: Rect; hTE: TEHandle);
Pea ViewRect ; Get visible area
Move.l TextHReg,-(SP) ; and handle to text
_TEUpdate; then update the window
; ProcedureEndUpdate (theWindow: WindowPtr);
Move.l WindowPReg,-(SP) ; Get pointer to window
_EndUpdate ; and end the update
Bra NextEvent; Go get next event
KeyDown
A key was pressed. First check to see if it was a command key. If so, go do it. Otherwise pass the key to TextEdit.
Btst #CmdKey,ModifyReg ; Is command key down?
Bne CommandDown; handle command key
; ProcedureTEKey (key: CHAR; hTE: TEHandle);
Move Message+2,-(SP) ; Get character
Move.l TextHReg,-(SP) ; and text record
_TEKey ; Give char to TextEdit
Bra NextEvent; Go get next event
CommandDown
The command key was down. Call MenuKey to find out if it was the command key equivalent for a menu command, pass the menu and item numbers to Choices.
; Function MenuKey (ch:CHAR): LongInt;
Clr.l -(SP) ; Space for Menu and Item
Move Message+2,-(SP) ; Get character
_MenuKey ; See if it's a command
Move (SP)+,MenuReg; Save Menu
Move (SP)+,MenuItemReg ; and Menu Item
Bra Choices ; Go dispatch command
;---------Mouse Down Events And Their Actions-----
MouseDown
If the mouse button was pressed, we must determine where the click occurred before we can do anything. Call FindWindow to determine where the click was; dispatch the event according to the result.
; Function FindWindow (thePt: Point;
; Var whichWindow: WindowPtr): Integer;
Clr -(SP) ; Space for result
Move.l Point,-(SP); Get mouse coordinates
Pea WWindow ; Event Window
_FindWindow; Who's got the click?
Move (SP)+,D0 ; Get region number
Add D0,D0 ; *2 for index into table
Move WindowTable(D0),D0; Point to routine offset
Jmp WindowTable(D0) ; Jump to routine
WindowTable
Dc.w NextEvent-WindowTable ; In Desk (Not used)
Dc.w InMenu-WindowTable; In Menu Bar
Dc.w SystemEvent-WindowTable ; System Window
Dc.w Content-WindowTable ; In Content
Dc.w Drag-WindowTable ; In Drag
Dc.w NextEvent-WindowTable ; In Grow (Not used)
Dc.w NextEvent-WindowTable ; In Go Away (Not used)
SystemEvent
The mouse button was pressed in a system window. SystemClick calls the appropriate desk accessory to handle the event.
; ProcedureSystemClick (theEvent: EventRecord;
; theWindow: WindowPtr);
Pea EventRecord; Get event record
Move.l WWindow,-(SP); and window pointer
_SystemClick ; Let the system do it
Bra NextEvent; Go get next event
Content
The click was in the content area of a window. If our window was in front, then call Quickdraw to get local coordinates, then pass the coordinates to TextEdit. We also determine whether the shift key was pressed so TextEdit can do shift-clicking. If our window wasn't in front, Move it to the front, but don't process click.
Clr.l -(SP) ; clear room for result
_FrontWindow ; get FrontWindow
Move.l (SP)+,D0 ; Is front window pointer
Cmp.l WindowPReg,D0; same as our pointer?
Beq.s @1; Yes, call TextEdit
We weren't active, select our window. This causes an activate event.
; ProcedureSelectWindow (theWindow: WindowPtr);
Move.l WWindow,-(SP); Window Pointer To Stack
_SelectWindow ; Select Window
Bra NextEvent; and get next event
@1
; We were active, pass the click (with shift) to TextEdit.
; ProcedureGlobalToLocal (Var pt:Point);
Pea Point ; Mouse Point
_GlobalToLocal ; Global To Local
; Procedure TEClick (pt: Point; extend: Boolean; hTE: TEHandle);
Move.l Point,-(SP); Mouse Point (GTL)
Btst #shiftKey,ModifyReg ; Is shift key down?
Sne D0; True if shift down
Note: We want the Boolean in the high byte, so use Move.b. The 68000 pushes an extra, unused byte on the stack for us.
Move.b D0,-(SP)
Move.l TextHReg,-(SP) ; Identify Text
_TEClick ; TEClick
Bra NextEvent; Go get next event
Drag
Move.l WWindow,-(SP); Pass window pointer
Move.l Point,-(SP); mouse coordinates
Pea WBounds ; and boundaries
_DragWindow; Drag Window
Bra NextEvent; Go get next event
InMenu
Clr.l -(SP) ; Get Space For Menu Choice
Move.l Point,-(SP); Mouse At Time Of Event
_MenuSelect; Menu Select
Move (SP)+,MenuReg; Save Menu
Move (SP)+,MenuItemReg ; and Menu Item
On entry to Choices, the resource ID of the Menu is saved in the low word of a register, and the resource ID of the MenuItem in another. The routine MenuKey, used when a command key is pressed, returns the sameinfo.
Choices ; Called by command key too
Cmp #AppleMenu,MenuReg ; Is It In Apple Menu?
Beq InAppleMenu; Go do Apple Menu
Cmp #FileMenu,MenuReg ; Is It In File Menu?
Beq InFileMenu ; Go do File Menu
Cmp #EditMenu,MenuReg ; Is It In Edit Menu?
Beq InEditMenu ; Go do Edit Menu
Cmp #FontMenu,MenuReg ; Is It In Font Menu?
Beq InFontMenu ; Go do Font Menu
ChoiceReturn
Bsr UnHiliteMenu ; Unhighlight the menu bar
Bra NextEvent; Go get next event
InFileMenu
Cmp #QuitItem,MenuItemReg ; Is It Quit?
Bne ChoiceReturn ; No, Go get next event
Bsr UnHiliteMenu ; Unhighlight the menu bar
Move #-1,D0 ; say it was Quit
Rts
InEditMenu
; First, call SystemEdit. If a desk accessory is active that uses the
Edit menu (such as the Notepad) this lets it use our menu. Decide whether
it was cut, copy, paste, or clear. Ignore Undo since we didn't implement
it.
Bsr SystemEdit ; Desk accessory active?
Bne ChoiceReturn ; Yes, SystemEdit handled it
Cmp #CutItem,MenuItemReg; Is It Cut?
Beq Cut ; Yes, go handle it
Cmp #CopyItem,MenuItemReg ; Is it Copy?
Beq Copy; Yes, go handle it
Cmp #PasteItem,MenuItemReg; Is it Paste?
Beq Paste ; Yes, go handle it
Cmp #ClearItem,MenuItemReg; Is it Clear?
Beq ClearIt ; Yes, go handle it
Bra ChoiceReturn ; Go get next event
InFontMenu
Cmp #DialogItem,MenuItemReg ; Is It Dialog?
Bne ChoiceReturn ; No, Go get next event
; ProcedureTEDeActivate (hTE: TEHandle)
Move.l TextHReg,-(SP) ; Identify Text
_TEDeActivate ; Deactivate Text
; Obtain the current Font number, size and attributes to setup the dialog
box.
Movea.lTextHReg,A0; Handle to the TE record
Movea.l(A0),A0 ; Pointer to the TE record
Move.w teFont(A0),D0;- Font Number
Cmp.w #1,D0 ; Default number?
Bne.s @0; No, -> @0
Move.w ApFontID,D0; Yes, load default number
@0 Move.w D0,DtxFont(A5)
Clr.w D0;- Font Face
Move.b teFace(A0),D0; Place the attribute bits in the
Move.w D0,DtxFace(A5) ; low byte of DtxFace(A5).
Move.w teSize(A0),D0;- Font Size
Bne.s @1; Default size, No -> @1
Move.b FMDefaultSize,D0 ; Yes, load default size
@1 Move.w D0,DtxSize(A5)
Clr.w -(SP)
Pea DtxFont(A5); Load the font's number address
Pea DtxFace(A5); Load the font's face address
Pea DtxSize(A5); Load the font's size address
Jsr FontDialog
Test to see if the okButton was pressed (ie install the new Font variables). If the cancelButton was pressed leave the Font variables as they are.
Move.b (SP)+,D0
Beq.s @2
Update the Font number, size, and face fields in the textedit record. The teAscent and teLineHite fields also require up dating. Reset the port to the textedit window, since the current GraphPort has been changed by the FontDialog routine.
Move.l WindowPReg,-(SP)
_SetPort
Move.w DtxFont(A5),-(SP)
_TextFont
Move.w DtxFace(A5),-(SP)
_TextFace
Move.w DtxSize(A5),-(SP)
_TextSize
; Procedure GetFontInfo (Var Info: FontInfo)
Pea Info(A5)
_GetFontInfo
Movea.lTextHReg,A1; DeReference the Handle
Movea.l(A1),A1
Move.w DtxFont(A5),teFont(A1); teFont
Move.b DtxFace+1(A5),teFace(A1) ; teFace
Move.w DtxSize(A5),teSize(A1); teSize
Move.w Info+ascent(A5),teAscent(A1) ; teAscent
Move.w Info+ascent(A5),D0; teLineHite
Add.w Info+descent(A5),D0
Add.w Info+leading(A5),D0
Move.w D0,teLineHite(A1)
@2 Bra GoSetOurPort
InAppleMenu
Cmp #AboutItem,MenuItemReg; Is It About?
Beq About ; If So Goto About...
; ProcedureGetItem (menu: MenuHandle; item: Integer;
; Var itemString: Str255);
Move.l AppleHReg,-(SP) ; Look in Apple Menu
Move MenuItemReg,-(SP) ; What Item Number?
Pea DeskName ; Get Item Name
_GetItem ; Get Item
; Function OpenDeskAcc (theAcc: Str255) : Integer;
Clr -(SP) ; Space For Opening Result
Pea DeskName ; Open Desk Acc
_OpenDeskAcc ; Open It
Move (SP)+,D0 ; Pop result
GoSetOurPort
Bsr SetOurPort ; Set port to us
Bra ChoiceReturn ; Unhilite menu and return
;----------- Text Editing Routines ---------
Cut; CUT
Move.l TextHReg,-(SP) ; Identify Text
_TECut ; Cut it and copy it
Bra ChoiceReturn ; Go get next event
Copy ; COPY
Move.l TextHReg,-(SP) ; Identify Text
_TECopy; Copy text to clipboard
Bra ChoiceReturn ; Go get next event
Paste ; PASTE
Move.l TextHReg,-(SP) ; Identify Text
_TEPaste ; Paste
Bra ChoiceReturn ; Go get next event
ClearIt ;CLEAR
Move.l TextHReg,-(SP) ; Point to text
_TEDelete; Clear without copying
Bra ChoiceReturn ; Go get next event
SystemEdit does undo, cut, copy, paste, and clear for desk accessories. It returns False (Beq) if the active window doesn't belong to a desk accessory.
SystemEdit
; Function SystemEdit (editCmd:Integer): Boolean;
Clr -(SP) ; Space for result
Move MenuItemReg,-(SP) ; Get item in Edit menu
Subq #1,(SP) ; SystemEdit is off by 1
_SysEdit ; Do It
Move.b (SP)+,D0 ; Pop result
Rts ; Beq if NOT handled
UnhiliteMenu
; ProcedureHiLiteMenu (menuID: Integer);
Clr -(SP) ; All Menus
_HiLiteMenu; UnHilite Them All
Rts
;--------------------Misc Routines------------
About
; Function GetNewDialog (dialogID: Integer; dStorage: Ptr;
; behind: WindowPtr) : DialogPtr
Clr.l -(SP) ; Space For dialog pointer
Move #AboutDialog,-(SP); Identify dialog rsrc #
Pea DStorage ; Storage area
Move.l #-1,-(SP); Dialog goes on top
_GetNewDialog ; Display dialog box
Move.l (SP),-(SP) ; Copy handle for Close
; Handle on stack
_SetPort ; Make dialog box the port
Move.l TextHReg,-(SP) ; Identify Text
_TEDeActivate ; Deactivate Text
WaitOK
; ProcedureModalDialog (filterProc: ProcPtr;
; Var itemHit: Integer);
Clr.l -(SP) ; Clear space For handle
Pea ItemHit ; Storage for item hit
_ModalDialog ; Wait for a response
Move ItemHit,D0 ; Look to see what was hit
Cmp #ButtonItem,D0 ; was it OK?
Bne WaitOK ; No, wait for OK
_CloseDialog ; Handle already on stack
Bra GoSetOurPort ; Set port to us and return
; ----------- Data Starts Here ------------
EventRecord ; NextEvent's Record
What: Dc 0 ; Event number
Message: Dc.l 0 ; Additional information
When: Dc.l0 ; Time event was posted
Point: Dc.l0 ; Mouse coordinates
Modify:Dc 0 ; State of keys and button
WWindow: Dc.l 0 ; Find Window's Result
DStorageDcb.w DWindLen,0 ; Storage For Dialog
DeskNameDcb.w 16,0; Desk Accessory's Name
WBounds Dc 28,4,308,508 ; Drag Window's Bounds
ViewRectDc 5,4,245,405 ; Text Record's View Rect
DestRectDc 5,4,245,405 ; Text Record's Dest Rect
ItemHit Dc0 ; Item clicked in dialog
;-------------- Nonrelocatable Storage ---------
Variables declared using Ds are placed in a global space relative to A5. When these variables are referenced, A5 must be explicitly mentioned.
DtxFont Ds.w1
DtxFace Ds.w1
DtxSize Ds.w1
Info Ds.w4 ; FontInfo Record
WindowStorage Ds.wWindowSize ; Storage for Window
End
;-------------- FontDialog --------------------
; Written by Ray.A.Cameron
; Version 1
;Wed May 6, 1988 21:00:51
XDef FontDialog ; Routine's name
XRef FontMap ; Variable's name
;---------- Includes -------------
Include Traps.D ; Use System and ToolBox traps
Include ToolEqu.D; Use ToolBox Equates
Include QuickEqu.D ; Use QuickDraw Equates
Include SysEqu.D ; Use System Equates
Include PackMacs.Txt ; Use Package Equates
Include FontMacros.Txt ; Use Macro file
; ---------- Equates ----------
FontDPtrEqu A4
FDialog Equ 260 ; Font dialog is DLOG resource #260
ADialog Equ 260 ; Alert dialog is ALRT resource #260
True Equ 1 ; Boolean True
False Equ 0 ; Boolean False
enterCode Equ 3 ; ASCII Enter
bsCode Equ 8 ; ASCII Back Space
crCode Equ 13 ; ASCII Carriage Return
param0 Equ 0 ; Offset to string 0 in DAStrings
param1 Equ 4 ; Offset to string 1 in DAStrings
param2 Equ 8 ; Offset to string 2 in DAStrings
OkActiveEqu 0 ; OkActive bit within Dialog Flags
SUpdate Equ 1 ; Sample update bit within Dialog Flags
Font Dialog 2
Continued from - Font Dialog
SRect Equ 2 ; Sample rect bit within Dialog Flags
SKey Equ 3 ; Sample key bit within Dialog Flags
; --------- Font Dialog Data Record -------
DStorageEqu $0 ; Storage for the Dialog Record
TempFontEqu $AA ; Currently selected font number
TempFaceEqu $AC ; Currently selected font style
TempSizeEqu $AE ; Currently selected font size
DFlags Equ $B0 ; Dialog Flags
NameListH Equ $B2 ; Font Name Selection List's Handle
NameCellEqu $B6 ; Font Name selected cell
SizeListH Equ $BA ; Font Size Selection List's Handle
SizeCellEqu $BE ; Font Size selected cell
TempCellEqu $C2 ; Temporary Cell variable
Item Equ $C6 ; Item's handle or procedure
ItemtypeEqu $CA ; Item's type
ItemBox Equ $CC ; Item's enclosing rect
ItemHit Equ $D4 ; Item clicked in dialog
loc_pt Equ $D6 ; mouse location
InitBoundsEqu $DA ; Init size of Lists
TextCursorEqu $E2 ; Handle to the IBeam cursor
thename Equ $E6 ; Text string
pnState Equ $1E6 ; Original state of the pen
String1 Equ $1F8 ; Alert text string1
String2 Equ $1FC ; Alert text string2
String3 Equ $200 ; Alert text string3
Sample Equ $204 ; Sample Text Edit Handle
SampleRectEqu $208; Sample Text Edit Rect
SampleTicks Equ $210; Ticks when Sample required updated
info Equ $214 ; GetFontInfo record
search Equ $21C ; String to search Font Name List
Globalslength Equ $23C
; This routine receives the following inputs:
; teFont: The current font's number
;teFace: The current type face's attributes in low byte
;Bit 0 - Bold Bit 3 - Outline Bit 6 - Extend
;Bit 1 - Italic Bit 4 - Shadow
;Bit 2 - Underline Bit 5 - Condense
;teSize: The current font's size
A ModalDialog box is displayed to allow the user to choose the font attributes that they desire. If the Ok button, enter key or carriage return is pressed the selected values will replace the original values otherwise the values remain the same.
FontDialog
Link A6,#0
; Boolean result20(A6) ; Ok or Cancel
; DtxFont Address 16(A6) ; Address of current Font number
; DtxFace Address 12(A6) ; Address of current Font style
; DtxSize Address 8(A6) ; Address of current Font size
; Return Address4(A6)
; Old A6 (A6)
Movem.lD0-D7/A0-A4,-(SP) ; Save register values.
Move.w #False,20(A6); Set up to return False.
; Create a non-relocatable block for Font Data Record.
Move.l #Globalslength,D0
_NewPtr,CLEAR
Move.l A0,FontDRec(A5) ; Store the pointer.
Movea.lA0,FontDPtr
GetPenStatepnState(A4) ; Save the current pen settings.
; Load the present values of the font number, face and size
; into temporary locations.
Movea.l16(A6),A0; Font number.
Move.w (A0),TempFont(A4)
Movea.l12(A6),A0; Font face.
Move.w (A0),TempFace(A4)
Movea.l8(A6),A0 ; Font size.
Move.w (A0),TempSize(A4)
; Obtain the iBeamCursor's resource and lock it down.
; Function GetCursor (cursorID: Integer): CursHandle
Subq.l #4,SP
Move.w #iBeamCursor,-(SP)
_GetCursor
Move.l (SP)+,TextCursor(A4)
HLock TextCursor(A4)
Subq.l #4,SP ; Space for dialog pointer.
Move.w #FDialog,-(SP) ; Identify dialog rsrc #.
Move.l FontDPtr,-(SP) ; Storage area.
Move.l #-1,-(SP); Dialog goes on top.
_GetNewDialog
_SetPort
Move.l OneOne,InitBounds+bottom(A4)
Bset.b #OkActive,DFlags(A4) ; selections are valid.
; Lock FontMap while its information is being accessed.
HLock FontMap(A5)
DeRefHndle FontMap(A5),A3
Set up the Style check boxes so that they show the current font's values.
Move.w TempFace(A4),D0 ; current face (style) byte.
Move.w #4,-(SP) ; Item No 4.
Move.w #5,-(SP) ; 5 Items (check boxes).
Move.w D0,-(SP) ; Bits to set.
Bsr SControl
Set up the Spacing radio buttons so that they show the current fonts values.
Move.w TempFace(A4),D0 ; current face (style) byte.
Andi.w #%01100000,D0; Examine Condense & Extend.
Bne.s @0; If neither are set, then
Move.w #%00010000,D0; add bit to represent "Normal".
@0 Lsr.W#4,D0
Move.w #11,-(SP); Item No 11.
Move.w #3,-(SP) ; 3 Items (radio buttons).
Move.w D0,-(SP) ; Bits to set.
Bsr SControl
; Set up the Font Name Selection Window
GetDItem FontDPtr,#17,Itemtype(A4),Item(A4),ItemBox(A4)
Subq.l #4,SP ; Space for the handle.
Pea ItemBox(A4)
Pea InitBounds(A4) ; Create one cell.
Clr.l -(SP) ; Cell size for text.
Move.w #0,-(SP) ; Text definition procedure.
Move.l FontDPtr,-(SP)
Move.b #False,-(SP) ; drawIt
Move.b #False,-(SP) ; hasGrow
Move.b #False,-(SP) ; scrollHoriz
Move.b #True,-(SP); scrollVert
_LNew
Move.l (SP),NameListH(A4); Store the List's handle.
DeRefHndle (SP)+,A0 ; Set the selection flags.
Move.b #%10000010,selFlags(A0) ; lOnlyOne, lNoNilHilite
Move.l #$FFFF0000,NameCell(A4) ; (0,-1), no cell
Jsr LdNames ; Load the Font Names.
; Set up the Font Size Selection Window
GetDItem FontDPtr,#19,Itemtype(A4),Item(A4),ItemBox(A4)
; Function LNew (rView, dataBounds: Rect; cSize: Point;
; theProc: Integer; theWindow: WindowPtr; drawIt, hasGrow,
; scrollHoriz, scrollVert: Boolean): ListHandle
Subq.l #4,SP ; Space for the handle.
Pea ItemBox(A4)
Pea InitBounds(A4) ; Create one cell.
Clr.l -(SP) ; Cell size for text.
Move.w #0,-(SP) ; Text definition procedure.
Move.l FontDPtr,-(SP)
Move.b #False,-(SP) ; drawIt
Move.b #False,-(SP) ; hasGrow
Move.b #False,-(SP) ; scrollHoriz
Move.b #True,-(SP); scrollVert
_LNew
Move.l (SP),SizeListH(A4); Store the List's handle.
DeRefHndle (SP)+,A0 ; Set the selection flags.
Move.b #%10000010,selFlags(A0) ; 1OnlyOne, lNoNilHilite
Move.l #$FFFF0000,SizeCell(A4)
Jsr LdSizes ; Load the current Font's Sizes.
; Set up the Font Size Text Edit item
Jsr SetEditSize
; Set up the Sample Display Text Edit Record
GetDItem FontDPtr,#21,Itemtype(A4),Item(A4),SampleRect(A4)
; Function TENew (destRect, viewRect: Rect): TEHandle
Subq.l #4,SP
Pea SampleRect(A4) ; Create a new text edit record.
Pea SampleRect(A4)
_TENew
Move.l (SP)+,Sample(A4) ; Store theTEdit handle.
HLock Sample(A4)
DeRefHndle Sample(A4),A0 ; Setup the variables.
Move.w #teJustCenter,teJust(A0)
Move.b MinusOne,teCROnly(A0)
GetResource'STR ',#264 ; Obtain the sample text.
HLock (SP); Leave the handle on the stack.
DeRefHndle (SP),A0; Address of text in A0.
Clr.l D0; Length of text in D0.
Move.b (A0)+,D0
Move.l A0,-(SP) ; Insert the sample string into
Move.l D0,-(SP) ; the record.
Move.l Sample(A4),-(SP)
_TEInsert
HUnlock(SP)+ ; Unlock the string resource.
Jsr SampleWindow ; Update the TEdit variables.
HUnlockSample(A4)
; Set up the Alert Dialog Variables
Move.w #-1,ACount ; Reset the Alert stage to 1.
GetResource 'STR ',#261; Obtain copies of the Alert strings
Move.l (SP)+,String1(A4) ; handles and store for easy
GetResource 'STR ',#262; access.
Move.l (SP)+,String2(A4)
GetResource 'STR ',#263
Move.l (SP)+,String3(A4)
; Display the Dialog Window
ShowWindow FontDPtr ; This posts an Activate event.
WaitOk
Pea DUserFilter
Pea ItemHit(A4)
_ModalDialog
Move.w ItemHit(A4),D0 ; Get the itemNo that was Hit.
Subq.w #1,D0 ; Allow for no item zero.
Lsl.w #1,D0 ; *2 for table index.
Move.w ItemTable(D0),D0 ; Point to routine offset
Jmp ItemTable(D0); and jump to it.
ItemTable
Dc.w DOk-ItemTable; Ok Button
Dc.w DCancel-ItemTable ; Cancel Button
Dc.w WaitOk-ItemTable ; Character Text (Disabled)
Dc.w SStyle-ItemTable ; Bold Check Box
Dc.w SStyle-ItemTable ; Italic Check Box
Dc.w SStyle-ItemTable ; Underline Check Box
Dc.w SStyle-ItemTable ; Outline Check Box
Dc.w SStyle-ItemTable ; Shadow Check Box
Dc.w Style-ItemTable ; Style Text (Enabled)
Dc.w WaitOk-ItemTable ; ThinBox User Item
Dc.w SSpacing-ItemTable; Normal Radio Button
Dc.w SSpacing-ItemTable; Condense Radio Button
Dc.w SSpacing-ItemTable; Extend Radio Button
Dc.w Spacing-ItemTable ; Spacing Text (Enabled)
Dc.w WaitOk-ItemTable ; ThinBox User Item
Dc.w WaitOk-ItemTable ; Font N... Text (Disabled)
Dc.w FontName-ItemTable; NameSel Wind User Item
Dc.w WaitOk-ItemTable ; Font S... Text (Disabled)
Dc.w FontSize-ItemTable; SizeSel Wind User Item
Dc.w GetEditSize-ItemTable ; Type size Text Edit
Dc.w FontSample-ItemTable; Sample Font User Item
DOk
; If the current Dialog selection isn't valid, set up the appropriate
param text strings and invoke the Caution Alert.
Btst.b #OkActive,DFlags(A4); Is the selection valid?
Bne @3; Yes -> @3
Clr.w D0; Set up the three param
Movea.l#DAStrings,A0; text strings.
Clr.l param0(A0)
Clr.l param1(A0)
Clr.l param2(A0)
Cmpi.w #-1,TempFont(A4) ; Is TempFont a valid selection?
Bne.s @0; Yes -> @0
Bset.b #0,D0 ; No -> include related text.
Move.l String1(A4),param0(A0)
@0 Cmpi.w #0,TempSize(A4) ; Is TempSize a valid selection?
Bne.s @1; Yes -> @1
Bset.b #1,D0 ; No -> include related text.
Move.l String2(A4),param2(A0)
@1 Cmpi.w #3,D0 ; If both TempFont and TempSize
Bne.s @2; are invalid include the conjunctive
Move.l String3(A4),param1(A0); string (String3).
@2 ; Function CautionAlert (alertID: Integer; filterProc: ProcPtr): Integer
Subq.l #2,SP
Move.w #ADialog,-(SP)
Clr.l -(SP)
_CautionAlert
Addq.l #2,SP
Bra WaitOk ; User to alter their selection.
@3 ;
If the current Dialog selection is valid, replace the original font number, style and size values with the values chosen by the user.
Movea.l16(A6),A0; Font number.
Move.w TempFont(A4),(A0)
Movea.l12(A6),A0; Font style.
Move.w TempFace(A4),(A0)
Movea.l8(A6),A0 ; Font size.
Move.w TempSize(A4),(A0)
Move.b #True,20(A6) ; Return True.
DCancel
HideWindow FontDPtr
LMDisposeNameListH(A4) ; Font Name List.
LMDisposeSizeListH(A4) ; Font Size List.
TEDisposeSample(A4) ; Sample Text Edit Record.
CloseDialog FontDRec(A5)
HUnLockFontMap(A5); FontMap .
HUnLockTextCursor(A4) ; iBeamCursor resource.
SetPenStatepnState(A4) ; Restore the pen settings.
DisposePtr FontDPtr ; Font Dialog Data Record.
Movem.l(SP)+,D0-D7/A0-A4 ; Restore registers.
Unlk A6
Movea.l(SP)+,A0 ; Pop args & return.
Add.l #12,SP
Jmp (A0)
Style
Move.w TempFace(A4),D2 ; Store for comparison later.
Movea.l12(A6),A0; Obtain original style values
Move.w (A0),D0 ; and retain lower five bits.
Andi.w #%00011111,D0
Andi.w #%11100000,TempFace(A4) ; Clear the lower 5 bits.
Or.w D0,TempFace(A4) ; Combine the two together.
Bra.s SetStyle
SStyle
Move.w TempFace(A4),D2 ; Store for comparison later.
Move.w ItemHit(A4),D0 ; Get the itemNo that was hit.
Subq.w #4,D0
Bchg.b D0,TempFace+1(A4) ; Toggle the selected item.
SetStyle
Cmp.w TempFace(A4),D2 ; Has the face altered?
Beq.s @1; No -> @1
Move.w TempFace(A4),D0
; Routine SControl (StItem, NofItems, ValueBits : Integer)
Move.w #4,-(SP) ; Item No 4.
Move.w #5,-(SP) ; 5 Items (check boxes).
Move.w D0,-(SP) ; Bits to set.
Bsr SControl
Btst.b #OkActive,DFlags(A4); Are Dialog selections valid.
Beq.s @1; No, don't update the sample.
Bclr.b #SRect,DFlags(A4) ; Erase Sample if it hasn't
Beq.s @0; been already.
EraseRectSampleRect(A4)
@0 Bset.b #SUpdate,DFlags(A4) ; Window requires updating.
Move.l Ticks,SampleTicks(A4)
@1 Jmp WaitOk
Spacing
Move.w TempFace(A4),D2 ; Store for comparison later.
Movea.l12(A6),A0; Obtain the original style values.
Move.w (A0),D0
Bra.s SetSpacing
SSpacing
Move.w TempFace(A4),D2 ; Store for comparison later.
Move.w ItemHit(A4),D1 ; Get the item No that was hit.
Sub.w #11,D1 ; Produce in D0 a byte that
Move.w #%00010000,D0; represents which bit to set.
Lsl.b D1,D0
SetSpacing
Andi.w #%11100000,D0; Clear the lower 5 bits.
Andi.w #%00011111,TempFace(A4) ; Clear the top 3 bits.
Or.w D0,TempFace(A4) ; Combine the two together.
Cmp.w TempFace(A4),D2 ; Has the face altered?
Beq.s @2; No -> @2
Move.w TempFace(A4),D0 ; Produce in the first 3 bits
Andi.w #%01100000,D0; of D0 the settings of the
Bne.s @0; 3 radio buttons.
Move.w #%00010000,D0
@0 Lsr.b#4,D0
; Routine SControl (StItem, NofItems, ValueBits : Integer)
Move.w #11,-(SP); Item No 11.
Move.w #3,-(SP) ; 3 Items (radio buttons).
Move.w D0,-(SP) ; Bits to set.
Bsr SControl
Btst.b #OkActive,DFlags(A4); Are Dialog selections valid.
Beq.s @2; No, don't update the sample.
Bclr.b #SRect,DFlags(A4); Erase Rect if it hasn't
Beq.s @1; been already.
EraseRectSampleRect(A4)
@1 Bset.b #SUpdate,DFlags(A4) ; Window requires updating.
Move.l Ticks,SampleTicks(A4)
@2 Jmp WaitOk
SControl
; Routine SControl (StItem, NofItems, ValueBits : Integer)
Link A6,#0
; StItem 12(A6) Start Item number
; NofItems 10(A6) Number of Items
; ValueBits 8(A6) Values of the items
; Return address4(A6)
; Old A6 (A6)
SetControl
GetDItem FontDPtr,12(A6),Itemtype(A4),Item(A4),ItemBox(A4)
Clr.w D0; Set D0 to 1 if the item
Lsr.W 8(A6) ; is to be set or 0 if its not.
Bcc.s @1
Addq.w #1,D0
@1 SetCtlValue Item(A4),D0
Addq.w #1,12(A6); Increment the item No counter.
Sub.w #1,10(A6); Any more items to process?
Bne.s SetControl ; Yes -> SetControl.
Unlk A6
Movea.l(SP)+,A0 ; Pop args & return.
Add.l #6,SP
Jmp (A0)
FontName
The user has made a new selection from the Font Name Selection Window, either a new font name or none. TempFont will change.
Bclr.b #SRect,DFlags(A4) ; Erase Rect if it hasn't
Beq.s @0; been already.
EraseRectSampleRect(A4)
@0 Move.w NameCell+v(A4),D0 ; Update the font number in
Bmi.s @1; TempFont with the number
Mulu #6,D0 ; of the font selected .
Move.w 2(A3,D0.W),TempFont(A4)
Cmpi.w #0,TempSize(A4)
Beq.s @2
Bset.b #OkActive,DFlags(A4); selections are valid.
Bset.b #SUpdate,DFlags(A4) ; Window requires updating.
Move.l Ticks,SampleTicks(A4)
Bra.s @3
@1 Move.w #-1,TempFont(A4); No Font Name is selected.
@2 Bclr.b #OkActive,DFlags(A4); selections aren't valid.
@3 Jsr LdSizes ; Update Font Size Selection Window.
GetDItem FontDPtr,#19,Itemtype(A4),Item(A4),ItemBox(A4)
EraseRect ItemBox(A4)
LMUpdate VisRgn(A4),SizeListH(A4)
Jmp WaitOk
FontSize
The user has made a new selection from the Font Size Selection Window, either a new font name or none. TempSize might not change.
Move.w TempSize(A4),D2 ; Store for comparison later.
Move.w NameCell+v(A4),D0
Bmi.s @0; No Font Name selected.
Mulu #6,D0
Move.w 2+4(A3,D0.W),D0 ; Offset to font's size list.
Lea (A3,D0.W),A0 ; Address of the size list.
Move.w SizeCell+v(A4),D0
Bmi.s @0; No Font Size selected.
Lsl.w #1,D0
Move.w 2(A0,D0.W),TempSize(A4) ; Store new font size.
Cmp.w TempSize(A4),D2 ; Has the size altered?
Beq.s @0; No -> @0
Jsr SetEditSize; Update the textedit window.
@0 Jmp WaitOk
GetEditSize
Convert the text in the font size text edit window into a number to update TempSize. TempSize might not have changed, if the mouse is clicked within the font size text edit window this routine is called.
GetDItem FontDPtr,#20,Itemtype(A4),Item(A4),ItemBox(A4)
GetIText Item(A4),thename(A4)
Lea thename(A4),A0
_StringToNum
Cmpi.w #4,D0
Blt @2; if <4
Cmpi.w #127,D0
Bgt @2; if >127
Cmp.w TempSize(A4),D0 ; Has the size altered?
Beq.s @1; No -> @1
Move.w D0,TempSize(A4) ; Yes -> update TempSize.
Cmp.w #-1,TempFont(A4) ; Is there a valid font name?
Beq.s @3; No -> @3
Bset.b #OkActive,DFlags(A4); selections are valid.
Bclr.b #SRect,DFlags(A4) ; Erase Rect if it hasn't
Beq.s @0; been already.
EraseRectSampleRect(A4)
@0 Bset.b #SUpdate,DFlags(A4) ; Window requires updating.
Move.l Ticks,SampleTicks(A4)
@1 Jmp WaitOk
@2 Clr.wTempSize(A4) ; Indicate its outside limits.
@3 Bclr.b #OkActive,DFlags(A4); selections aren't valid.
Bclr.b #SRect,DFlags(A4) ; Erase Rect if it hasn't
Beq.s @4; been already.
EraseRectSampleRect(A4)
@4 Jmp WaitOk
FontSample
Jsr SampleWindow ; update the attributes
TEUpdate SampleRect(A4),Sample(A4)
Bclr.b #SUpdate,DFlags(A4) ; Window has been updated.
Bset.b #SRect,DFlags(A4) ; Sample Rect isn't blank.
Jmp WaitOk
SetEditSize
Setup the font size text edit item. To access this routine there must be a valid font name.
GetDItem FontDPtr,#20,Itemtype(A4),Item(A4),ItemBox(A4)
Clr.l D7
Move.w TempSize(A4),D7
Cmpi.w #4,D7
Blt @1; if <4
Cmpi.w #127,D7
Bgt @1; if >127
Bset.b #OkActive,DFlags(A4); selections are valid.
Bclr.b #SRect,DFlags(A4) ; Erase Sample if it hasn't
Beq.s @0; been already.
EraseRectSampleRect(A4)
@0 Bset.b #SUpdate,DFlags(A4) ; Window requires updating.
Move.l Ticks,SampleTicks(A4)
Lea thename(A4),A0 ; Load thename pointer.
Move.l D7,D0
_NumToString
Move.l Item(A4),-(SP) ; Set the item text to the new
Move.l A0,-(SP) ; number string.
_SetIText
Move.l FontDPtr,-(SP)
Move.w #20,-(SP); Select complete text in the item.
Move.w #0,-(SP)
Move.w #255,-(SP)
_SelIText
Rts
@1 Clr.wTempSize(A4) ; Indicate it's outside limits.
Bclr.b #OkActive,DFlags(A4); selections aren't valid.
Bclr.b #SRect,DFlags(A4) ; Erase Sample if it hasn't
Beq.s @2; been already.
EraseRectSampleRect(A4)
@2 Rts
LdNames
; Load the NameList with the font names stored in FontMap.
; Function LAddRow (count, rowNum: Integer; lHandle: ListHandle): Integer
Subq.l #2,SP
Move.w (A3),-(SP) ; The number of font names - 1.
Move.w #0,-(SP)
Move.l NameListH(A4),-(SP)
_LAddRow
Addq.l #2,SP
Clr.w D7; Loop counter (the # of fonts -1).
@0 Move.w D7,D6
Mulu #6,D6 ; Point to the next font info.
Move.w 2(A3,D6.W),D0; Obtain the font's number.
Cmp.w TempFont(A4),D0 ; Is this font to be selected?
Bne.s @1; No -> @1.
Move.w D7,NameCell+v(A4) ; cell # into NameCell+v.
@1 Move.w 2+2(A3,D6.W),D6 ; Obtain the font's name offset.
; Procedure LSetCell (dataPtr: Ptr; dataLen: Integer; theCell: Cell;
lHandle: ListHandle)
Pea 1(A3,D6.W) ; Address of the name (string).
Clr.w D0
Move.b (A3,D6.W),D0 ; Length of the name.
Move.w D0,-(SP)
Move.w #0,-(SP) ; Cell column #.
Move.w D7,-(SP) ; Cell row #.
Move.l NameListH(A4),-(SP)
_LSetCell
Addq.w #1,D7 ; Increment the loop counter.
Cmp.w (A3),D7 ; Loaded all font names yet?
Ble.s @0; No -> @0.
Select the cell containing the font name which corresponds to the font number passed to the FontDialog Routine. If the font number isn't associated with one of the fonts on the current system file then don't select any name.
Cmpi.w #-1,NameCell+v(A4); Cell to be selected?
Beq.s @2; No -> @2
LMSetSelect #True,NameCell(A4),NameListH(A4)
DeRefHndle NameListH(A4),A0; Scroll if selected cell
Move.w visible+bottom(A0),D6 ; isn't visible, ie
;the last visible cell is
Cmp.w NameCell+v(A4),D6 ; less than selected cell.
Bgt.s @2
LMAutoScroll NameListH(A4)
@2 LMDoDraw #True,NameListH(A4) ; Drawing on.
Rts
LdSizes
; load SizeList with font sizes of TempFont in FontMap.
LMDoDraw #False,SizeListH(A4); Drawing off.
LMDelRow #0,#0,SizeListH(A4) ; Delete all the rows.
Move.l #$FFFF0000,SizeCell(A4)
Move.w TempFont(A4),D4 ;The font number.
Bmi @5; -ve, no font number passed to FontDialog.
Clr.w D7; Loop counter.
@1 Move.w D7,D6
Mulu #6,D6 ; Point to the next font info.
; Compare the font number with the font number that was passed
; to the FontDialog Routine.
Cmp.w 2(A3,D6.W),D4; Match?
Beq.s @2; Yes -> @2.
Addq.w #1,D7 ; Increment the loop counter.
Cmp.w (A3),D7 ; Looked at all font numbers yet?
Ble.s @1; No ->@1.
Bra @5; Yes & no match was found.
@2 Move.w 2+4(A3,D6.W),D7 ; Offset to font size list.
Move.w (A3,D7.W),D6 ; The number of font sizes.
; Procedure LAddRow (count, rowNum: Integer; lHandle: ListHandle): Integer
Subq.l #2,SP
Move.w D6,-(SP) ; Number of rows to add.
Move.w #0,-(SP)
Move.l SizeListH(A4),-(SP)
_LAddRow
Addq.l #2,SP
Clr.w D6; Setup the loop counter.
@3 Move.w D6,D5 ; Create an offset within size list.
Lsl.w #1,D5
Add.w D7,D5 ; Offset from the start of FontMap.
Clr.l D0; Clear .L for NumToString.
Move.w 2(A3,D5.W),D0; A font size.
Cmp.w TempSize(A4),D0 ; Is this the selected size?
Bne.s @4; No -> @4.
Move.w D6,SizeCell+v(A4); Store cell number to select
@4 Lea thename(A4),A0
_NumToString
; Procedure LSetCell (dataPtr: Ptr; dataLen: Integer; theCell: Cell;
lHandle: ListHandle)
Pea 1(A0) ; Address of the Size (string).
Clr.w D0
Move.b (A0),D0 ; Length of the Size.
Move.w D0,-(SP)
Move.w #0,-(SP) ; Cell column #.
Move.w D6,-(SP) ; Cell row #.
Move.l SizeListH(A4),-(SP)
_LSetCell
Addq.w #1,D6 ; Increment the loop counter.
Cmp.w (A3,D7.W),D6 ; Loaded all font sizes yet?
Blt.s @3; No -> @3.
Select the cell containing the font size which corresponds to the font size passed to the FontDialog Routine. If the font doesn't have the size selected, do nothing.
Cmpi.w #-1,SizeCell+v(A4); Cell to be selected?
Beq.s @5; No -> @5
LMSetSelect #True,SizeCell(A4),SizeListH(A4)
DeRefHndle SizeListH(A4),A0
; Scroll if the selected cell isn't
Move.l (A0),A0 ; visible, ie last visible cell is
Move.w visible+bottom(A0),D6 ; less than selected cell.
Cmp.w SizeCell+v(A4),D6
Bgt.s @5
LMAutoScroll SizeListH(A4)
@5 LMDoDraw #True,SizeListH(A4) ; Drawing on.
Rts
SampleWindow
; Update the sample TextEdit Record with the currently
; selected font attributes.
Btst.b #OkActive,DFlags(A4); Are the selections valid?
Beq @0; No -> @0
TextFont TempFont(A4) ; Font number
TextFace TempFace(A4) ; Font style
TextSize TempSize(A4) ; Font size
GetFontInfoinfo(A4)
DeRefHndle Sample(A4),A0
Move.w TempFont(A4),teFont(A0) ; teFont
Move.b TempFace+1(A4),teFace(A0) ; teFace
Move.w TempSize(A4),teSize(A0) ; teSize
Move.w info+ascent(A4),teAscent(A0) ; teAscent
Move.w info+ascent(A4),D0; teLineHite
Add.w info+descent(A4),D0
Add.w info+leading(A4),D0
Move.w D0,teLineHite(A0)
Move.l teViewRect+topLeft(A0),teDestRect+topLeft(A0)
Move.l teViewRect+botRight(A0),teDestRect+botRight(A0)
Mulu teNLines(A0) ,D0 ; Height of the sample text.
Move.w SampleRect+bottom(A4),D1
Sub.w SampleRect+top(A4),D1
Cmp.w D0,D1 ; Sample greater than Rect?
Ble @0; Yes -> @0
Sub.w D0,D1 ; Center the sample
Lsr.w #1,D1 ; lines in the middle
Add.w D1,teDestRect+top(A0) ; of SampleRect.
@0 Rts
; ------------ Modal Dialog User Filter ----------
DUserFilter
Link A6,#0
; Boolean result20(A6)
; Dialog (window) pointer16(A6)
; Address of the event record12(A6)
; Addr of word to fill in item no 8(A6)
; Return address4(A6)
; Old A6 (A6)
Use the event number as an index into the DEventTable. These 12 events are all the things that could spontaneously happen while the program is in the Modal Dialog event loop.
Movea.l16(A6),A4; Font Dialog Data Record.
Move.w #False,20(A6); Set function result to False.
Movea.l12(A6),A0; Event Records Address.
Move.w evtNum(A0),D0; Get the event number.
Lsl.w #1,D0 ; *2 for table index.
Move.w DEventTable(D0.W),D0; Point to the routine offset
Jmp DEventTable(D0.W) ; and jump to it.
DEventTable
Dc.w DNull-DEventTable ; Null
Dc.w DMouseDown-DEventTable; Mouse Down
Dc.w DFReturn-DEventTable; Mouse Up (Not used)
Dc.w DKeyDown-DEventTable; Key Down
Dc.w DFReturn-DEventTable; Key Up (Not used)
Dc.w DKeyDown-DEventTable; Auto Key
Dc.w DUpdate-DEventTable ; Update
Dc.w DFReturn-DEventTable; Disk (Not used)
Dc.w DActivate-DEventTable ; Activate
Dc.w DFReturn-DEventTable; Network (Not used)
Dc.w DFReturn-DEventTable; I/O Driver (Not used)
DNull
GetDItem 16(A6),#20,Itemtype(A4),Item(A4),ItemBox(A4)
GetMouse loc_pt(A4)
PtInRect loc_pt(A4),ItemBox(A4) ; Was mouse within the
Move.b (SP)+,D0 ; FontSize text edit Rect?
Beq.s @0; Yes -> iBeam cursor.
Move.l TextCursor(A4),A0
Move.l (A0),-(SP)
_SetCursor
Bra @1
@0 _InitCursor ; No -> Arrow cursor.
@1 Move.l Ticks,D0 ; If KeyTresh Ticks have passed
Sub.l SampleTicks(A4),D0; since last item alteration,
Cmp.w KeyThresh,D0 ; update the sample window by
Blt DFReturn ; indicating item #21 was hit.
Btst.b #SUpdate,DFlags(A4)
Beq DFReturn
Move.w #21,D0 ; Set the itemNo to 21, Sample
Bra DFTReturn
DMouseDown
Bclr.b #SKey,DFlags(A4) ; Not a SKey event.
; Obtain the (events) mouse location and convert it to
; local coordinates.
Move.l evtMouse(A0),loc_pt(A4)
GlobalToLocal loc_pt(A4)
; Check to see if the mouse was clicked inside one of the
; active rectangles.
Item9
; mouse was pressed down within item No 9? (Style heading)
GetDItem FontDPtr,#9,Itemtype(A4),Item(A4),ItemBox(A4)
PtInRect loc_pt(A4),ItemBox(A4)
Move.b (SP)+,D0 ; Was the point within the heading?
Beq.s Item14 ; No -> check item No 14's Rect.
; Routine TrackHeading (theDialog: DialogPtr; itemNo: Integer): Boolean
Subq.l #2,SP ; Set up for the result.
Move.l FontDPtr,-(SP)
Move.w #9,-(SP)
Bsr TrackHeading
Move.b (SP)+,D0 ; Was the mouse up within the item?
Beq SetoNull ; No, Convert event to null & return .
Move.w #9,D0 ; Yes, return True & the item No 9.
Bra DFTReturn
Item14
;mouse was pressed down within item No 14? (Spacing heading).
GetDItem FontDPtr,#14,Itemtype(A4),Item(A4),ItemBox(A4)
PtInRect loc_pt(A4),ItemBox(A4)
Move.b (SP)+,D0 ; Was the point within the heading?
Beq Item17 ; No -> check item No 17's Rect.
Subq.l #2,SP
Move.l FontDPtr,-(SP)
Move.w #14,-(SP)
Bsr TrackHeading
Move.b (SP)+,D0 ; Was the mouse up within the item?
Beq SetoNull ; No, Convert event to null & return .
Move.w #14,D0 ; Yes, return True & the item No 14.
Bra DFTReturn
Item17
; mouse was pressed down within item No 17?
; The Font Name Selection Window.
GetDItem FontDPtr,#17,Itemtype(A4),Item(A4),ItemBox(A4)
Addi.w #15,ItemBox+right(A4) ; include vertical scroll
PtInRect loc_pt(A4),ItemBox(A4)
Move.b (SP)+,D0 ; Was the point within the rect?
Beq Item19 ; No -> check item No 19's rect.
If a new selection is made return true and the item number, otherwise set the event to a null event and return.
; Function LClick (pt: Point; modifiers: Integer; lHandle: ListHandle):
Boolean
Subq.l #2,SP
Move.l loc_pt(A4),-(SP)
Movea.l12(A6),A0
Move.w evtMeta(A0),-(SP)
Move.l NameListH(A4),-(SP)
_LClick
Addq.l #2,SP
Clr.l TempCell(A4)
LMGetSelect #True,TempCell(A4),NameListH(A4)
Move.b (SP)+,D0 ; Is there a selected cell?
Bne @0; Yes -> @0.
Move.l #$FFFF0000,TempCell(A4) ; No set TempCell to 0,-1.
@0 Move.l TempCell(A4),D0 ; Has the selected cell changed?
Cmp.l NameCell(A4),D0
Beq SetoNull ; No -> SetoNull.
Move.l D0,NameCell(A4) ; Yes, return True & item No 17.
Move.w #17,D0
Bra DFTReturn
Item19
; Check to see if the mouse was pressed down within item No 19.
; The Font Size Selection Window.
GetDItem FontDPtr,#19,Itemtype(A4),Item(A4),ItemBox(A4)
Addi.w #15,ItemBox+right(A4)
PtInRect loc_pt(A4),ItemBox(A4)
Move.b (SP)+,D0 ; Was the point within the rect?
Beq DFReturn ; No -> DFReturn.
If a new selection is made return true and the item number, otherwise
set the event to a null event and return.
Subq.l #2,SP
Move.l loc_pt(A4),-(SP)
Movea.l12(A6),A0
Move.w evtMeta(A0),-(SP)
Move.l SizeListH(A4),-(SP)
_LClick
Addq.l #2,SP
Clr.l TempCell(A4)
LMGetSelect #True,TempCell(A4),SizeListH(A4)
Move.b (SP)+,D0 ; Is there a selected cell?
Bne @0; Yes -> @0.
Move.l #$FFFF0000,TempCell(A4)
@0 Move.l TempCell(A4),D0 ; Has selected cell changed?
Cmp.l SizeCell(A4),D0
Beq SetoNull ; No -> SetoNull.
Move.l D0,SizeCell(A4) ; Yes, return True & item No 19.
Move.w #19,D0
Bra DFTReturn
DKeyDown
Examine the key that was pressed, if it was a 'cr' or 'enter' then that is equivalent to clicking the Ok button.
Move.l evtMessage(A0),D0
Cmpi.b #crCode,D0 ; Was the cr key pressed?
Beq.s @1; Yes -> @1.
Cmpi.b #enterCode,D0; Was the enter key pressed?
Bne.s @2; No -> @2.
@1 Move.w #1,D0 ; Set the item No to Ok button.
Bra DFTReturn; Item No 1 - Ok.
@2 ;
If the key pressed was the back space key or a number then deselect the cell in the Font Size Selection Window (if there is one selected), then return, allowing the number or 'bs' to be used to alter the FontSize
; text edit data.
Cmpi.b #bsCode,D0 ; Was the bs key pressed?
Beq.s @3; Yes -> @3.
Cmpi.b #$30,D0
Blt.s NameSearch
Cmpi.b #$39,D0
Bgt.s NameSearch
@3 Bclr.b #SKey,DFlags(A4); Not a SKey event.
Cmpi.l #$FFFF0000,SizeCell(A4) ; If a cell is selected,
Beq DFReturn ; deselect it,
LMSetSelect #False,SizeCell(A4),SizeListH(A4) ; let the
; default routine
Move.l #$FFFF0000,SizeCell(A4) ; handle the event.
Bra DFReturn
NameSearch
Lea search(A4),A2
Bset.b #SKey,DFlags(A4) ; Was last event a SKey event?
Beq.s @0; No -> @0
Move.l evtTicks(A0),D1 ; Yes -> If this key down
Sub.l SampleTicks(A4),D1; within KeyThresh Ticks
Cmp.w KeyThresh,D1 ; continue the search string
Blt.s @1; else, reset search string.
@0 Clr.b(A2); Continue.
@1 Addq.b #1,(A2); Reset.
Move.l evtTicks(A0),SampleTicks(A4)
Clr.w D1; If search string is greater than
Move.b (A2),D1 ; 32, SetoNull.
Cmpi.b #31,D1
Bgt SetoNull
Move.b D0,(A2,D1.w) ; Add char to string.
DeRefHndle FontMap(A5),A3
Clr.w D7; Set loop counter.
@2 Move.w D7,D6
Mulu #6,D6 ; Offset to next font info.
Move.w 2+2(A3,D6.w),D6 ; Offset to name string.
; Function IUMagString (aPtr, bPtr: Ptr; aLen, bLen: Integer): Integer
Subq.l #2,SP
Pea 1(A3,D6.w) ; Address of FontName string.
Pea 1(A2) ; Address of search string.
Clr.w D0
Move.b (A3,D6.w),D0
Move.w D0,-(SP) ; Length of FontName string.
Move.b (A2),D0
Move.w D0,-(SP) ; Length of search string.
_IUMagString
Move.w (SP)+,D0 ; Was the FontName => ?
Bpl.s @3; Yes -> @3
Addq.w #1,D7 ; Have all the fonts been
Cmp.w (A3),D7 ; looked at?
Blt @2; No -> @2
@3 ; Is the desired cell selected?
; Yes -> Don't do anything.
; No -> Deselect existing cell & select new cell.
Cmp.w NameCell+v(A4),D7
Beq SetoNull
LMSetSelect#False,NameCell(A4),NameListH(A4)
Move.w D7,NameCell+v(A4)
LMSetSelect#True,NameCell(A4),NameListH(A4)
DeRefHndle NameListH(A4),A0; If selected cell isn't
Cmp.w visible+top(A0),D7; visible then AutoScroll.
Blt.s @4; else continue.
Cmp.w visible+bottom(A0),D7
Blt.s @5
@4 LMAutoScroll NameListH(A4)
@5 Move.w #17,D0
Bra DFTReturn
DUpdate
Bclr.b #SKey,DFlags(A4) ; Not a SKey event.
SetPortFontDPtr
BeginUpdateFontDPtr
DrawControls FontDPtr
; Update itemNo 1
; The BoldBox around the Ok button.
GetDItem FontDPtr,#1,Itemtype(A4),Item(A4),ItemBox(A4)
InsetRectItemBox(A4),#-4,#-4
PenSize#3,#3
FrameRoundRect ItemBox(A4),#16,#16
_PenNormal
; Update itemNo 3
; The Static Text heading "Character Font & Attributes".
GetDItem FontDPtr,#3,Itemtype(A4),Item(A4),ItemBox(A4)
GetIText Item(A4),thename(A4)
Lea thename(A4),A0 ; Address of the text.
Clr.l D0
Move.b (A0)+,D0 ; Length of the text.
TextBox A0,D0,ItemBox(A4),#0
; Update the Font Style Selection Window
; The ThinBox around the Style Check Boxes (item No 10).
GetDItem FontDPtr,#10,Itemtype(A4),Item(A4),ItemBox(A4)
FrameRectItemBox(A4)
; The Static Text heading "Style" (item No 9).
GetDItem FontDPtr,#9,Itemtype(A4),Item(A4),ItemBox(A4)
GetIText Item(A4),thename(A4)
Lea thename(A4),A0 ; Address of the text.
Clr.l D0
Move.b (A0)+,D0 ; Length of the text.
TextBox A0,D0,ItemBox(A4),#0
; Update the Font Spacing Selection Window
; The ThinBox around the Style Check Boxes (item No 15).
GetDItem FontDPtr,#15,Itemtype(A4),Item(A4),ItemBox(A4)
FrameRectItemBox(A4)
; The static text heading "Spacing" (item No 14).
GetDItem FontDPtr,#14,Itemtype(A4),Item(A4),ItemBox(A4)
GetIText Item(A4),thename(A4)
Lea thename(A4),A0 ; Address of the text.
Clr.l D0
Move.b (A0)+,D0 ; Length of the text.
TextBox A0,D0,ItemBox(A4),#0
; Update itemNo 16
; The Static Text heading "Font Name:".
GetDItem FontDPtr,#16,Itemtype(A4),Item(A4),ItemBox(A4)
GetIText Item(A4),thename(A4)
Lea thename(A4),A0 ; Address of the text.
Clr.l D0
Move.b (A0)+,D0 ; Length of the text.
TextBox A0,D0,ItemBox(A4),#0
; Update itemNo 17
; The Font Name Selection Window.
GetDItem FontDPtr,#17,Itemtype(A4),Item(A4),ItemBox(A4)
InsetRect ItemBox(A4),#-1,#-1
EraseRect ItemBox(A4)
FrameRect ItemBox(A4)
LMUpdate VisRgn(A4),NameListH(A4)
; Update itemNo 18
; The Static Text heading "Font Size:".
GetDItem FontDPtr,#18,Itemtype(A4),Item(A4),ItemBox(A4)
GetIText Item(A4),thename(A4)
Lea thename(A4),A0 ; Address of the text.
Clr.l D0
Move.b (A0)+,D0 ; Length of the text.
TextBox A0,D0,ItemBox(A4),#0
; Update itemNo 19
; The Font Size Selection Window.
GetDItem FontDPtr,#19,Itemtype(A4),Item(A4),ItemBox(A4)
InsetRect ItemBox(A4),#-1,#-1
EraseRect ItemBox(A4)
FrameRect ItemBox(A4)
LMUpdate VisRgn(A4),SizeListH(A4)
; Update itemNo 20
; The TextEdit text item.
GetDItem FontDPtr,#20,Itemtype(A4),Item(A4),ItemBox(A4)
EraseRect ItemBox(A4)
TEUpdate ItemBox(A4),teHandle(A4)
InsetRect ItemBox(A4),#-3,#-3
FrameRect ItemBox(A4) ; Frame the textedit item.
; Update itemNo 21
; Update the Sample Text Window.
EraseRect SampleRect(A4)
Bclr.b #SRect,DFlags(A4)
Btst.b #OkActive,DFlags(A4); Are selections valid?
Beq @0; No -> @0
TEUpdate SampleRect(A4),Sample(A4); Yes -> update sample
Move.l Ticks,SampleTicks(A4) ; and associated
Bclr.b #SUpdate,DFlags(A4) ; variables.
Bset.b #SRect,DFlags(A4)
@0 EndUpdateFontDPtr
Bra SetoNull
DActivate
Check first to see if this activate event is associated with this Dialog Window, compare the Dialog Window's pointer to that of the Window pointerin the event record. A0 contains the address of the event record.
Move.l FontDPtr,D0
Cmp.l evtMessage(A0),D0
Bne DFReturn ; Event not related to Dialog.
Bclr.b #SKey,DFlags(A4) ; Not a SKey event.
SetPortFontDPtr
Movea.l12(A6),A0; Address of the event record.
Move.w evtMeta(A0),D0 ; Obtain the modify word.
Lsr #1,D0 ; Check Bit 0 to see if its
Bcc DDeactivate; Activate or Deactivate.
TEActivate teHandle(A4)
LMActivate #True,NameListH(A4)
LMActivate #True,SizeListH(A4)
Bra SetoNull
DDeactivate
TEDeactivate teHandle(A4)
LMActivate #False,NameListH(A4)
LMActivate #False,SizeListH(A4)
Bra SetoNull
SetoNull
Movea.l12(A6),A0; Obtain the address of the Event
Clr.w evtNum(A0) ; Record & set it to a null event.
Bra.s DFReturn
DFTReturn
Move.b #True,20(A6) ; Dialog Filter (True) Return.
Movea.l8(A6),A0
Move.w D0,(A0)
DFReturn; Dialog Filter Return.
Unlk A6
Movea.l(SP)+,A0 ; Pop args & return.
Add.l #12,SP
Jmp (A0)
TrackHeading
Link A6,#-22
; Boolean result 14(A6)
; theDialog pointer 10(A6)
; itemNo 8(A6)
; Return address 4(A6)
; Old A6 (A6)
; Temporary Region Handle No1 -4(A6)
; Temporary Region Handle No2 -8(A6)
; Vis boolean -10(A6)
; Mouse Location-14(A6)
; Temporary Rectangle -22(A6)
Move.b #False,14(A6); Set up to return False.
; Get Rect of user item that surrounds the headings control
; items (check boxes or radio buttons).
Addq.w #1,8(A6)
GetDItem 10(A6),8(A6),Itemtype(A4),Item(A4),-22(A6)
; Create a region and store the current clipping region.
NewRgn
Move.l (SP),-4(A6); Store the regions handle.
_GetClip
Create a new clipping region which is the user item's rect inset by 1 pixel on all sides minus the intersection rectangle of the heading's rect and the newly created rect.
NewRgn
Move.l (SP),-8(A6); Store the regions handle.
InsetRect -22(A6),#1,#1
_OpenRgn
FrameRect-22(A6)
Find the rectangle that is the intersection of ItemBox(A4) and -22(A6). If they intersect then remove that rectangle from the clipping region.
SectRect ItemBox(A4),-22(A6),TempRect
Move.b (SP)+,D0 ; Was there an intersection?
Beq.s @1; No -> @1.
FrameRectTempRect
@1 _CloseRgn; handle is already on stack.
SetClip-8(A6) ; Set up the new clipping region.
PenSize #1,#1
PenMode#10 ; Inverts what ever is drawn over.
; Draw the rectangle in question, giving the user the
; impression that they have selected the heading.
FrameRect-22(A6)
Move.b #True,-10(A6); Set the vis byte to True.
Track
StillDown
Move.b (SP)+,D0 ; Is the mouse button still down?
Beq @1; No -> @1.
GetMouse -14(A6)
PtInRect -14(A6),ItemBox(A4)
Move.b (SP)+,D0 ; Has the mouse entered or
Cmp.b -10(A6),D0 ; left the item's rect?
Beq.s Track ; No -> Track.
FrameRect-22(A6); Yes -> toggle the rectangle.
Eori.b #1,-10(A6) ; Toggle the visible byte.
Bra.s Track
@1 Move.b -10(A6),D0 ; Is the rect visible?
Beq.s @2; No -> Return False.
FrameRect-22(A6); Yes -> Remove the rectangle &
Move.b #True,14(A6) ; return True.
@2 _PenNormal
SetClip-4(A6) ; Reset to its original setting.
DisposeRgn -4(A6) ; Dispose of two temporary regions.
DisposeRgn -8(A6)
Unlk A6
Movea.l(SP)+,A0 ; Pop args & return.
Add.l #6,SP
Jmp (A0)
; ---------- Variables ------
FontDRecDs.l1
;--------------- SetupFontMap -----------------
; Written by Ray.A.Cameron
; Version 1.0
; Mon May 4, 1988 21:41:50
XDef SetupFontMap ; Routine's name
XDef FontMap ; Global location for the FontMap's Handle
;---------- Includes -------------
Include Traps.D ; Use System and ToolBox traps
Include PackMacs.Txt ; Use Package Equates
; ---------- Equates ----------
True Equ 1
False Equ 0
FNum Equ %1111111111000000
FSize Equ %0000000000111111
SetupFontMap
Link A6,#0
Movem.lD0-D7/A0-A4,-(SP) ; Save register values.
; Function CountResources (theType: ResType): Integer;
Clr.w -(SP) ; Clear for answer.
Move.l #'FONT',-(SP); Count number of 'FONT' resources.
_CountResources
Clr.l D7
Move.w (SP)+,D7 ; Store the result.
Create a non-relocatable block into which will be stored each font resource ID, if the resource has a font size (ie no name).
Move.l D7,D0 ; Create a size to allow 2 bytes for
Lsl.w #1,D0 ; each resource ID.
_NewPtr,Clear
Movea.lA0,A4 ; Store pointer to non-relocatable block.
Setup the Resource Manager so that the resources aren't loaded into
memory.
; Procedure SetResLoad (load: Boolean);
Move.b #False,-(SP) ; Load False
_SetResLoad
Clr.w D3; Loop counter (# of font resources).
Clr.w D4; Offset into the theID non-relocatable block.
Clr.w D5; The number of different fonts.
Clr.l D6; The # of bytes to allocate to FontMap.
; Setup a non-relocatable block for the name of a resource.
Move.l #256,D0 ; The # of bytes required.
_NewPtr,Clear
Move.l A0,thename(A5) ; Store pointer.
ExamRes
Addq.w #1,D3 ; increment loop counter.
Obtain a handle to a resource with type 'FONT' and an index value from 1-to-CountResources.
; Function GetIndResource (theType: resType; index: Integer): Handle;
Clr.l -(SP) ; Space for handle
Move.l #'FONT',-(SP); Font resource type
Move.w D3,-(SP) ; Index value
_GetIndResource
; Use the handle to obtain the resources ID and name.
; The handle is already on the stack.
Pea theID(A5); point to theID
Pea theType(A5); point to theType
Move.l thename(A5),-(SP) ; load address of name
_GetResInfo
Move.w theID(A5),D0 ; Examine theID to see if resource
Andi.w #FSize,D0; has a font size (ie no name).
Beq.s NoSize ; NoSize, ie a name-> NoSize
Place theID of the font resource (which contains a font size) into the non-relocatable block. Then increment the offset.
Move.w theID(A5),(A4,D4.W)
Addq.w #2,D4 ; increment the offset
Bra.s Testloop
NoSize
Movea.lthename(A5),A0
Evaluate the number of bytes to allocate to this font's name in the FontMap. Add this to the running total.
Clr.l D0
Move.b (A0),D0 ; Create an even length for the name
Bset.l #0,D0 ; (ie add padding if its rEquired).
Addq.l #1,D0
Add.l D0,D6 ; Update the running total.
Move.l A0,-(SP) ;Place the pointer to the name and
Move.w theID(A5),-(SP) ; resource ID onto the stack.
Addq.w #1,D5 ; Increment the number of different fonts.
Create a new non-relocatable block for the next font resource name.
Move.l #256,D0 ; The # of bytes required.
_NewPtr,Clear
Move.l A0,thename(A5) ; Store pointer
Testloop
Cmp.w D3,D7 ; Have all font resources been
Bne.s ExamRes ; examined, No -> ExamRes
; Dispose of pointer in thename(A5)
Movea.lthename(A5),A0
_DisposPtr
Setup the Resource Manager so that the resources can be loaded into memory.
; Procedure SetResLoad (load: Boolean);
Move.b #True,-(SP); Load True
_SetResLoad
Evaluate the number of bytes required for the FontMap. Then create a relocatable block for the FontMap. D6 contains the number of bytes to allocate for the font names in the FontMap.
Addq.l #2,D6 ; 2 bytes for "the number of fonts"
Clr.l D0
Move.w D5,D0 ; The # of different fonts, each font
Mulu #6,D0 ; list rEquires 6 bytes.
Add.l D0,D6
Move.l D0,D3 ; Reserved for later.
The amount of space to allocate for the font sizes is 2 x the number of font resources. This allows one word per entry.
Lsl.l #1,D7
Add.l D7,D6 ; Grand Total in D6
Move.l D6,D0
_NewHandle
Move.l A0,FontMap(A5) ; Store the FontMap handle.
Movea.lA0,A2 ; Copy the handle.
_HLock ; lock it
Movea.l(A2),A2 ; Obtain the address of the FontMap.
Subq.w #1,D5 ; The number of fonts- 1.
Move.w D5,(A2) ; Store # of fonts- 1 in FontMap.
Lea.l 2(A2,D3.W),A1; start of font name list.
Lea.l 2(A2),A0 ; start of the font info list.
; Transfer theID and name pointer onto FontMap from stack.
Transfer
Move.w (SP)+,(A0)+; theID
Move.l (SP)+,(A0)+; name pointer.
Cmpa.l A0,A1 ; Have all the resources been transfered?
Bne.s Transfer ; No -> Transfer.
; The information on the FontMap, in the font info list is now sorted
; so that the first font info has the lowest (alphabetically) name
; associated with it.
Move.w (A2),D7
Mulu #6,D7 ; Point to last entry in list
@1 Move.w D7,D6
@2 Subq.w #6,D6
Bmi.s @3
Movea.l2+2(A2,D7.W),A1 ; Load pointer to aStr
Movea.l2+2(A2,D6.W),A0 ; Load pointer to bStr
; Compare the two strings.
; Function IUMagString (aPtr, bPtr: Ptr; aLen, bLen: Integer): Integer;
Clr.w -(SP) ; Clear for result.
Pea 1(A1) ; Address of aStr
Pea 1(A0) ; Address of bStr
Clr.w D0
Move.b (A1),D0
Move.w D0,-(SP) ; Length of aStr
Move.b (A0),D0
Move.w D0,-(SP) ; Length of bStr
_IUMagString ; Compare aStr and bStr
Move.w (SP)+,D0
Cmpi.w #1,D0 ; Was aStr greater than bstr
Beq.s @2; Yes -> @2.
; Swap the theID and the name pointers over
Move.w 2(A2,D7.W),D0; Swap theIDs over
Move.w 2(A2,D6.W),2(A2,D7.W)
Move.w D0,2(A2,D6.W)
Move.l 2+2(A2,D7.W),D0 ; Swap the pointers over
Move.l 2+2(A2,D6.W),2+2(A2,D7.W)
Move.l D0,2+2(A2,D6.W)
Bra.s @2
@3 Subq.w #6,D7 ; Shorten the search and repeat until
Bne.s @1; the table is completely sorted.
Now that the entries in the font info list have been sorted the font names are loaded into the FontMap and the name pointer is now replaced by a two byte offset, As each font name is loaded its non-relocatable block is disposed of.
Move.w (A2),D5
Addq.w #1,D5 ; The number of fonts.
Mulu #6,D5
Addq.w #2,D5
; D5 contains the offset to the postion of the first font name.
Clr.w D7; loop counter (the # of fonts - 1)
LoadNames
Move.w D7,D6
Mulu #6,D6 ; Point to the next font info
Movea.l2+2(A2,D6.W),A3 ; Obtain pointer to the name.
Move.w D5,2+2(A2,D6.W) ; Store name offset in FontMap.
; Perform a BlockMove to load the font's name.
; Procedure BlockMove (sourcePtr, destPtr: Ptr; byteCount: Size);
Clr.l D0
Move.b (A3),D0
Bset.l #0,D0
Addq.l #1,D0 ; # of bytes required to move.
Lea (A3),A0 ; load source address
Lea (A2,D5.W),A1 ; load destination address
Add.w D0,D5 ; point to next name (offset)
_BlockMove
Movea.lA3,A0 ; Dispose of the non-relocatable block
_DisposPtr ; it's no longer required.
Addq.w #1,D7 ; increment counter
Cmp.w (A2),D7
Ble.s LoadNames
; Load the font sizes
Clr.w D7; loop counter
LdFSizes
Lea (A2,D5.W),A0
Clr.w (A0)
Move.w D7,D6
Mulu #6,D6 ; Point to the next font info
Move.w 2(A2,D6.W),D3; theID of the font
Move.w D5,4+2(A2,D6.W) ; size list offset in FontMap
Clr.w D2; Offset into the theID block
@1 Move.w (A4,D2.W),D0 ; Obtain the next theID
Andi.w #FNum,D0
Cmp.w D3,D0
Bne.s @2
Move.w (A4,D2.W),D0
Andi.w #FSize,D0
Addq.w #1,(A0) ; Increment "# of font sizes" counter
Move.w (A0),D1 ; Offset to place font size in list
Lsl.w #1,D1 ; Doubled to allow for word length.
Move.w D0,(A0,D1.W) ; Store the font size
@2 Addq.w #2,D2 ; Increment offset counter
Cmp.w D2,D4 ; Examined the complete block
Bgt.s @1; No -> @1.
; Sort the font size list in order of smallest to largest.
Move.w (A0),D3 ; The # of font sizes
Lsl.w #1,D3 ; Offset to the last font size
Sort1
Move.w D3,D2
Sort2
Subq.w #2,D2
Beq.s Sort3
Move.w (A0,D3.W),D1
Cmp.w (A0,D2.W),D1
Bgt.s Sort2
Move.w (A0,D2.W),(A0,D3.W)
Move.w D1,(A0,D2.W)
Bra.s Sort2
Sort3
Subq.w #2,D3
Bne.s Sort1
; Convert the font "theID" into the font number
Move.w 2(A2,D6.W),D3
Lsr.w #7,D3
Move.w D3,2(A2,D6.W)
Update the offset in the FontMap (D5) to point to the location of the font sizes associated with the next font.
Move.w (A0),D0
Addq.w #1,D0
Lsl.w #1,D0
Add.w D0,D5
; Check to see if there are any more fonts to load into the FontMap.
Addq.w #1,D7
Cmp.w (A2),D7
Ble.s LdFSizes
The FontMap has been created, and loaded with its information. Dispose of the theID non-relocatable block and unlock the FontMap.
Movea.lA4,A0
_DisposPtr
Movea.lFontMap(A5),A0
_HUnlock
; Restore registers to their original values
Movem.l(SP)+,D0-D7/A0-A4
Unlk A6
Rts
; ---------- Variables ----------
theID Ds.w1
theType Ds.l1
thename Ds.l1
FontMap Ds.l1 ; Handle of the FontMap.
End
;------------------ FontMacros -------------
; Written by Ray.A.Cameron
; ----- Control Manager Routines
; Procedure DrawControls (gp: GrafPort)
.Macro DrawControls
Move.l %1,-(SP)
_DrawControls
.Endm
; Procedure HiliteControl (theControl: Control Handle; hiliteState:
Integer)
.Macro HiliteControl
Move.l %1,-(SP)
Move.w %2,-(SP)
_HiliteControl
.Endm
; Procedure SetCtlValue (theControl: ControlHandle; theValue: Integer)
.Macro SetCtlValue
Move.l %1,-(SP)
Move.w %2,-(SP)
_SetCtlValue
.Endm
; ----- Dialog Manager Routines
; Procedure CloseDialog (theDialog: DialogPtr)
.Macro CloseDialog
Move.l %1,-(SP)
_CloseDialog
.Endm
; Procedure GetDItem (theDialog: DialogPtr; itemNo:Integer;
; Var type: Integer; Var item: Handle; Var box: Rect)
.Macro GetDItem
Move.l %1,-(SP)
Move.w %2,-(SP)
Pea %3
Pea %4
Pea %5
_GetDItem
.Endm
; Procedure GetIText (item: Handle; Var text: Str255)
.Macro GetIText
Move.l %1,-(SP)
Pea %2
_GetIText
.Endm
; Procedure SetDItem (theDialog: DialogPtr; itemNo: Integer; type: Integer;
item: Handle; box: Rect)
.Macro SetDItem
Move.l %1,-(SP)
Move.w %2,-(SP)
Move.w %3,-(SP)
Pea %4
Pea %5
_SetDItem
.Endm
; ----- Event Manager Routines
; Procedure GetMouse (Var mouseLoc: Point)
.Macro GetMouse
Pea %1
_GetMouse
.Endm
; Function StillDown: Boolean
.Macro StillDown
Clr.w -(SP)
_StillDown
.Endm
; ----- List Manager Routines
; Procedure LActivate (act: Boolean; lHandle: ListHandle)
.Macro LMActivate
Move.b %1,-(SP)
Move.l %2,-(SP)
_LActivate
.Endm
; Procedure LAutoScroll (lHandle: ListHandle)
.Macro LMAutoScroll
Move.l %1,-(SP)
_LAutoScroll
.Endm
; Procedure LDelRow (count, rowNum: Integer; lHandle: ListHandle)
.Macro LMDelRow
Move.w %1,-(SP)
Move.w %2,-(SP)
Move.l %3,-(SP)
_LDelRow
.Endm
; Procedure LDispose (lHandle: ListHandle)
.Macro LMDispose
Move.l %1,-(SP)
_LDispose
.Endm
; Procedure LDoDraw (drawIt: Boolean; lHandle: ListHandle)
.Macro LMDoDraw
Move.b %1,-(SP)
Move.l %2,-(SP)
_LDoDraw
.Endm
; Function LGetSelect (next: Boolean; Var theCell: Cell;
; lHandle: ListHandle): Boolean
.Macro LMGetSelect
Clr.w -(SP)
Move.b %1,-(SP)
Pea %2
Move.l %3,-(SP)
_LGetSelect
.Endm
; Procedure LSetSelect (setIt: Boolean; theCell: Cell; lHandle: ListHandle)
.Macro LMSetSelect
Move.b %1,-(SP)
Move.l %2,-(SP)
Move.l %3,-(SP)
_LSetSelect
.Endm
; Procedure LUpdate (theRgn: RgnHandle; lHandle: ListHandle)
.Macro LMUpdate
Move.l %1,-(SP)
Move.l %2,-(SP)
_LUpdate
.Endm
; ----- Memory Manager Routines
; Procedure DisposePtr (p: Ptr)
; On Entry A0: p (pointer)
; On ExitA0: 0
; D0: result code (integer)
.Macro DisposePtr
Move.l %1,A0
_DisposPtr
.Endm
; Procedure HLock (h: Handle)
; On Entry A0 - h (Handle)
; On ExitD0 - result code (integer)
.Macro HLock
Movea.l%1,A0
_HLock
.Endm
; Procedure HUnLock (h: Handle);
; On Entry A0 - h (Handle)
; On ExitD0 - result code (integer)
.Macro HUnLock
Movea.l%1,A0
_HUnLock
.Endm
; ----- Quick Draw Routines
; Procedure DisposRgn (rgn: RgnHandle)
.Macro DisposeRgn
Move.l %1,-(SP)
_DisposRgn
.Endm
; Procedure EraseRect (r: Rect)
.Macro EraseRect
Pea %1
_EraseRect
.Endm
; Procedure FrameRect (r: Rect)
.Macro FrameRect
Pea %1
_FrameRect
.Endm
; Procedure FrameRoundRect
.Macro FrameRoundRect
Pea %1
Move.w %2,-(SP)
Move.w %3,-(SP)
_FrameRoundRect
.Endm
; Procedure GetFontInfo (Var info: FontInfo)
.Macro GetFontInfo
Pea %1
_GetFontInfo
.Endm
; Procedure GetPenState (Var pnState: PenState)
.Macro GetPenState
Pea %1
_GetPenState
.Endm
; Procedure GlobalToLocal (Var pt: Point);
.Macro GlobalToLocal
Pea %1
_GlobalToLocal
.Endm
; Procedure InsetRect (Var r: Rect; dh,dv: Integer)
.Macro InsetRect
Pea %1
Move.w %2,-(SP)
Move.w %3,-(SP)
_InsetRect
.Endm
; Function NewRgn: Rgn Handle
.Macro NewRgn
Clr.l -(SP)
_NewRgn
.Endm
; Procedure PenMode (mode: Integer)
.Macro PenMode
Move.w %1,-(SP)
_PenMode
.Endm
; Procedure PenSize (width, height: Integer)
.Macro PenSize
Move.w %1,-(SP)
Move.w %2,-(SP)
_PenSize
.Endm
; Function PtInRect (pt: Point; r: rect): Boolean
.Macro PtInRect
Clr.w -(SP)
Move.l %1,-(SP)
Pea %2
_PtInRect
.Endm
; Function SectRect (srcRectA, srcRectB: Rect; Var dstRect: Rect): Boolean
.Macro SectRect
Clr.w -(SP)
Pea %1
Pea %2
Pea %3
_SectRect
.Endm
; Procedure SetClip (rgn: RgnHandle)
.Macro SetClip
Move.l %1,-(SP)
_SetClip
.Endm
; Procedure SetPenState (pnState: PenState)
.Macro SetPenState
Pea %1
_SetPenState
.Endm
; Procedure SetPort (gp: GrafPort)
.Macro SetPort
Move.l %1,-(SP)
_SetPort
.Endm
; Procedure TextFace (face: stlye)
.Macro TextFace
Move.w %1,-(SP)
_TextFace
.Endm
; Procedure TextFont (font: Integer)
.Macro TextFont
Move.w %1,-(SP)
_TextFont
.Endm
; Procedure TextSize (size: Integer)
.Macro TextSize
Move.w %1,-(SP)
_TextSize
.Endm
; ----- Resource Manager Routines
; Function GetResource (theType: ResType; theID: Integer): Handle
.Macro GetResource
Clr.l -(SP)
Move.l #%1,-(SP)
Move.w %2,-(SP)
_GetResource
.Endm
; ----- Text Edit Routines
; Procedure TEActivate (hTE: TEHandle)
.Macro TEActivate
Move.l %1,-(SP)
_TEActivate
.Endm
; Procedure TEDeactivate (hTE: TEHandle)
.Macro TEDeactivate
Move.l %1,-(SP)
_TEDeactivate
.Endm
; Procedure TEDispose (hTE: TEHandle)
.Macro TEDispose
Move.l %1,-(SP)
_TEDispose
.Endm
; Procedure TEUpdate (rUpdate: Rect; hTE: TEHandle)
.Macro TEUpdate
Pea %1
Move.l %2,-(SP)
_TEUpdate
.Endm
; Procedure TextBox (text: Ptr; length: LongInt; box :Rect;
; just: Integer)
.Macro TextBox
Move.l %1,-(SP)
Move.l %2,-(SP)
Pea %3
Move.w %4,-(SP)
_TextBox
.Endm
; ----- Window Manager Routines
; Procedure BeginUpdate (gp: GrafPort)
.Macro BeginUpdate
Move.l %1,-(SP)
_BeginUpdate
.Endm
; Procedure EndUpdate (WindowPtr: WindowPtr)
.Macro EndUpdate
Move.l %1,-(SP)
_EndUpdate
.Endm
; Procedure HideWindow (theWindow: WindowPtr)
.Macro HideWindow
Move.l %1,-(SP)
_HideWindow
.Endm
; Procedure ShowWindow (theWindow: WindowPtr)
.Macro ShowWindow
Move.l %1,-(SP)
_ShowWindow
.Endm
; ----- Miscellaneous Routines
.Macro DeRefHndle
Movea.l%1,%2
Movea.l(%2),%2
.Endm
; File Window.Link
!Start
/Output Window
[
FontMap
FontDialog
Window
/Include Window.Rsrc
$
* Window.R
* resource file for the program called "Window"
*
Window.Rsrc
????????
Type RACA = STR
,0
© by Ray A. Cameron of Australia \0Dver 4 MAR 1988
Type FREF
,128
APPL 0
,129
TEXT 1
Type BNDL
,128
RACA 0
ICN#
0 128 1 129
FREF
0 128 1 129
* ------ Multifinder events ---------
* bit 15 = switcher save screen
* bit 14 = accept suspend resume events
* bit 13 = switcher enable option switch
* bit 12 = can do background on null events
* bit 11 = multifinder aware
* (activates & deactivates topmost
* window at resume, suspend events)
Type SIZE = GNRL
,-1
.H
4800 ;; $4800 = bits 14,11 set
.L
128000 ;; (for 150K recomended)
.L
80000 ;; (for 80K minimum)
.I
*
* MENU Resource #1 specifies the menus used by the Window program.
* For proper support of the Desk accessories, the Apple menu
* should be first, and the Edit menu should be third. The first 5 items
* in the Edit menu should be identical to those used below. This makes
* it possible for the desk accessories to share the Edit menu with your
* application.
*
Type MENU
,1 (16)
\14
About This Example...
(-
,2 (16)
File
Quit/Q
,3 (16)
Edit
(Undo/Z
(-
Cut/X
Copy/C
Paste/V
Clear
,4 (16)
Font
Dialog /F
* Dialog Resource #1 specifies properties of the About box. It points
* to Dialog Item List (DITL) Resource #1 as containing its items.
Type DLOG
,1
100 100 190 400
Visible NoGoAway
1
0
1
* Dialog Resource #260 specifies properties of the Font box. It points
* to Dialog Item List (DITL) Resource #260 as containing its items.
,260
This is the Font Modal Dialog.
30 38 330 473
Invisible NoGoAway
1
0
260
* Alert Resource #260 specifies properties of the Font Alert box. It
points
* to Dialog Item List (DITL) Resource #261 as containing its items.
Type ALRT
,260
30 38 100 473
261
6665
* Dialog Item List Resource #1 specifies the items in the About box.
* By convention, the first item in an item list is the OK button.
* If there is a cancel button, it should be second. This makes it
* easier to interpret the item number returned by the call to ModalDialog.
Type DITL
,1
3
Button
60 230 80 290
OK
StaticText
15 20 36 300
This sample program was written
StaticText
35 20 56 300
just to prove it could be done!
* Dialog Item List Resource #260 specifies the items in the Font box.
,260
21
button
8 359 26 427
Ok
button
8 281 26 349
Cancel
staticText Disabled
4 4 18 194
Character Font & Attributes
checkBox
63 339 79 422
Bold
checkBox
79 339 95 422
Italic
checkBox
95 339 111 422
Underline
checkBox
111 339 127 422
Outline
checkBox
127 339 143 422
Shadow
staticText
45 339 61 375
Style
userItem Disabled
53 331 151 427
radiobutton
95 235 111 318
Normal
radiobutton
111 235 127 318
Condense
radiobutton
127 235 143 318
Extend
staticText
77 235 93 288
Spacing
userItem Disabled
85 227 151 323
staticText
34 4 48 81
Font Name:
userItem
54 5 150 126
staticText
34 151 48 218
Font Size: