home *** CD-ROM | disk | FTP | other *** search
- *******************************************************************************
- *
- * List Manager/LineEdit Demo -- Version 3.0
- *
- * (C) Copyright Apple Computer, Inc. 1988-1990
- * All rights reserved.
- *
- * Developer Technical Support Apple II Sample Code
- *
- * by Keith Rollin and Jim Mensch
- *
- * This program demonstrates the use of lists and LineEdit items in a window. It
- * uses controls to create, rename, remove and sort items in a list, and uses a
- * LineEdit item to enter new and rename old items. Cut, Copy, Paste, and Clear
- * are supported.
- *
- *******************************************************************************
- eject
-
- **********************************************************************
- * *
- * Apple IIGS Source Code Sampler, Volume I *
- * *
- * Copyright (c) Apple Computer, Inc. 1988-1990 *
- * All Rights Reserved *
- * *
- * Written by Apple II Developer Tech Support *
- * *
- * *
- * *
- * ---------------------------------------------------------------- *
- * *
- * This program and its derivatives are licensed only for *
- * use on Apple computers. *
- * *
- * Works based on this program must contain and *
- * conspicuously display this notice. *
- * *
- * This software is provided for your evaluation and to *
- * assist you in developing software for the Apple IIGS *
- * computer. *
- * *
- * DISCLAIMER OF WARRANTY *
- * *
- * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT *
- * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, *
- * WITH RESPECT TO ITS MERCHANTABILITY OR ITS FITNESS *
- * FOR ANY PARTICULAR PURPOSE. THE ENTIRE RISK AS TO *
- * THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH *
- * YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU (AND *
- * NOT APPLE OR AN APPLE AUTHORIZED REPRESENTATIVE) *
- * ASSUME THE ENTIRE COST OF ALL NECESSARY SERVICING, *
- * REPAIR OR CORRECTION. *
- * *
- * Apple does not warrant that the functions *
- * contained in the Software will meet your requirements *
- * or that the operation of the Software will be *
- * uninterrupted or error free or that defects in the *
- * Software will be corrected. *
- * *
- * SOME STATES DO NOT ALLOW THE EXCLUSION *
- * OF IMPLIED WARRANTIES, SO THE ABOVE EXCLUSION MAY *
- * NOT APPLY TO YOU. THIS WARRANTY GIVES YOU SPECIFIC *
- * LEGAL RIGHTS AND YOU MAY ALSO HAVE OTHER RIGHTS *
- * WHICH VARY FROM STATE TO STATE. *
- * *
- * *
- **********************************************************************
- eject
-
- case on
-
- copy 2/ainclude/E16.Quickdraw
- copy 2/ainclude/E16.Memory
- copy 2/ainclude/E16.EVENT
- copy 2/ainclude/E16.Control
- copy 2/ainclude/E16.Window
- copy 2/ainclude/E16.Dialog
- copy 2/ainclude/E16.List
- mcopy macros/lists.macros
-
- *******************************************************************************
- *
- * Equates used in this program.
- *
- *******************************************************************************
- DPHandle gequ 0 ; Handle to Tool Direct Page area
- DPPointer gequ DPHandle+4 ; Pointer to Tool Direct Page area
- deref gequ DPPointer+4 ; Temporary Handle dereference area
- TempLong gequ deref+4
- TempWord gequ TempLong+4
-
- ScreenMode gequ mode640
- ScreenWidth gequ 640
-
-
- EJECT
- *******************************************************************************
- *
- Main start
- *
- * Description: This is the main routine. It calls routines to Initialize
- * the tools, initialize application specific data, run the
- * main EventLoop, close the application, and close the tools.
- * Then it calls the ProDOS Quit command.
- *
- *
- * Inputs: NONE
- *
- * Outputs: NONE
- *
- * External Refs:
- * Import InitTools
- * Import InitApp
- * Import EventLoop
- * Import CloseApp
- * Import CloseTools
- * Import QuitParms
- *
- * Entry Points: NONE
- *
- *******************************************************************************
-
- jsr InitTools
- jsr InitApp
-
- _ShowCursor
-
- jsr EventLoop
-
- jsr CloseApp
- jsr CloseTools
-
- _Quit QuitParms
-
- end
-
- EJECT
- *******************************************************************************
- *
- Globals data
- *
- * Description: Holder of all of our data.
- *
- *
- * Inputs: N/A
- *
- * Outputs: N/A
- *
- * External Refs:
- * Import PrUpdate
- * Import PrOldUpdate
- *
- * Entry Points:
- * Export QuitParms ; used by Main
- *
- *******************************************************************************
- *
- * Standard global data
- *
- *******************************************************************************
-
- TitleString str 'Apple IIgs List Mgr/LineEdit Example Application'
- AutString str 'By Rollin and Mensch Apple DTS -- Version: 3.0'
- VersString str 'Copyright (c) 1988-1990 Apple Computer'
-
- MenuHeight ds 2 ; Stored height of menu bar
- MyID ds 2 ; Application ID
- MyDP ds 2 ; My direct page storage
-
- QuitFlag ds 2
- QuitParms dc i4'0' ; Pathname of next app
- dc i2'$00' ; flags
-
- EventRecord ANOP
- EventWhat ds 2
- EventMessage ds 4
- EventWhen ds 4
- EventWhere ds 4
- EventModifiers ds 2
- TaskData ds 4
- TaskMask dc i4'$0000FFFF'
-
- EJECT
- *******************************************************************************
- *
- * Application specific global data
- *
- *******************************************************************************
-
- ; This is a list of pointers to the text that is used to create our menus. It
- ; is used by InitApp to find all of the menu templates and use them to create
- ; our menubar. This loop loads MenuPtrLen-4 into an index, gets the
- ; corresponding menu template pointer in this table, and uses that in a
- ; NewMenu call. It then decrements the index by 4, and repeats the procees
- ; until the index is negative.
-
- MenuPtr dc i4'AppMenu'
- dc i4'FileMenu'
- dc i4'EditMenu'
- MenuPtrLen equ *-MenuPtr
-
-
- ; Menu list: menu items should be numbered consecutivly starting from 250.
- ; As a convention, use 256 as about and 257 as Quit.
-
- AppMenu dc c'$$@\XN1',i1'$0D'
- dc c'--About List Manager/LineEdit Demo...\N256V',i1'$00'
- dc c'.'
- FileMenu dc c'$$ File \N2',i1'$00'
- dc c'--Close Document\N255DV',i1'$00'
- dc c'--Quit\N257*Qq',i1'$00'
- dc c'.'
- EditMenu dc c'$$ Edit \N3',i1'$00'
- dc c'--Undo\N250*ZzVD',i1'$00'
- dc c'--Cut\N251*Xx',i1'$00'
- dc c'--Copy\N252*Cc',i1'$00'
- dc c'--Paste\N253*Vv',i1'$00'
- dc c'--Clear\N254',i1'$00'
- dc c'.'
-
- ErrOut ds 4
- TempSave ds 4
- TempHndl ds 4
-
- ;
- ; Control definitions for use with new control
- ;
- NumCtrls dc i2'5'
- MyCtrlList dc i4'NewBRec,DelBRec,RepBRec,RstBRec,SortBRec'
-
- MyCtlHdls ANOP
- NewBHdl ds 4 ; storage for returned handles
- DelBHdl ds 4
- RepBHdl ds 4
- RstBHdl ds 4
- SortBHdl ds 4
- LEHandle ds 4
-
- NewBTitle str 'New Entry'
- DelBTitle str 'Remove'
- RepBTitle str 'Replace'
- RstBTitle str 'UnHilite'
- SortBTitle str 'Sort'
-
- NewBRect dc i2'10,250,25,350'
- DelBRect dc i2'30,250,45,350'
- RepBRect dc i2'50,250,65,350'
- RstBRect dc i2'70,250,85,350'
- SortBRect dc i2'90,250,105,350'
- destRect dc i2'100,20,110,224'
- viewRect dc i2'97,10,113,234'
-
- NewBRec ANOP
- dc i4'0'
- dc i4'1'
- dc i4'simpleProc' ; defproc = simple button
- dc i2'0,0' ; no params
- dc i2'1' ; starting value
- dc i2'boldButton' ; control flags
- dc i4'NewBTitle' ; pointer to title string
- dc i4'NewBRect' ; pointer to bounds rect
- cRecSize equ *-NewBRec ; size of my control record
-
- DelBRec ANOP
- dc i4'0' ; color table pointer
- dc i4'2' ; refcon ( control dispatch number )
- dc i4'simpleProc' ; defproc = simple button
- dc i2'0,0' ; no params
- dc i2'1' ; starting value
- dc i2'simpRound' ; control flags
- dc i4'DelBTitle' ; pointer to title string
- dc i4'DelBRect' ; pointer to bounds rect
-
-
- RepBRec ANOP
- dc i4'0' ; color table pointer
- dc i4'3' ; refcon ( control dispatch number )
- dc i4'simpleProc' ; defproc = simple button
- dc i2'0,0' ; no params
- dc i2'1' ; starting value
- dc i2'simpRound' ; control flags
- dc i4'RepBTitle' ; pointer to title string
- dc i4'RepBRect' ; pointer to bounds rect
-
- RstBRec ANOP
- dc i4'0' ; color table pointer
- dc i4'4' ; refcon ( control dispatch number )
- dc i4'simpleProc' ; defproc = simple button
- dc i2'0,0' ; no params
- dc i2'1' ; starting value
- dc i2'simpRound' ; control flags
- dc i4'RstBTitle' ; pointer to title string
- dc i4'RstBRect' ; pointer to bounds rect
-
- SortBRec ANOP
- dc i4'0' ; color table pointer
- dc i4'6' ; refcon ( control dispatch number )
- dc i4'simpleProc' ; defproc = simple button
- dc i2'0,0' ; no params
- dc i2'1' ; starting value
- dc i2'simpRound' ; control flags
- dc i4'SortBTitle' ; pointer to title string
- dc i4'SortBRect' ; pointer to bounds rect
-
-
- FullRect dc i2'0,0,120,400'
- ListCtlHndl ds 4
-
- MemberSize equ 10
-
- MyList ANOP ; List record
- ListRect dc i2'10,10,92,210' ; list is 200x80
- MLNum dc i2'5' ; number of members in the list
- dc i2'8' ; max seen at once
- dc i2'selectOnlyOne' ; single selection/pascal strings
- dc i2'1' ; list start
- dc i4'0' ; list control handle
- dc i4'0' ; no list draw
- dc i2'10' ; list member height
- dc i2'MemberSize' ; list record size
- dc i4'MyData' ; pointer to member list
- dc i4'5' ; list ref con (control dispatch number)
- dc i4'0' ; color table pointer (default colors)
-
- ;
- ; These are the data records for each member of the list. Each one consists of:
- ; - a pointer to the string to be printed
- ; - a word of bit flags (only the lower byte is used; the upper byte is
- ; used as padding to make data access easier.
- ; - a 4 byte space to hold a handle for those items whose names have been
- ; stored in the heap with the Memory Manager
- ; We define only 5 members initially. However, we reserve space in the member
- ; record array for 30 members total.
-
- MyData dc i4'member1'
- dc i2'0'
- dc i4'0'
- dc i4'member2'
- dc i2'0'
- dc i4'0'
- dc i4'member3'
- dc i2'0'
- dc i4'0'
- dc i4'member4'
- dc i2'0'
- dc i4'0'
- dc i4'member5'
- dc i2'0'
- dc i4'0'
- ds 25*MemberSize ; and at the end, room for 25 more
- MyDataTSize equ *-MyData
-
- member1 str 'Member 1'
- member2 str 'Member 2'
- member3 str 'Member 3'
- member4 str 'Member 4'
- member5 str 'Member 5'
-
- MyWindow dc i2'WindEnd-*' ; size of paramBlock
- dc i2'%0010000000100000' ; frame bits : alert, vis
- dc i4'0' ; no title bar, no title...
- dc i4'0' ; ref con 0
- dc i2'0,0,0,0' ; zoomed rect
- dc i4'0' ; color table = default
- dc i2'0,0' ; scroll bar XY origin
- dc i2'0,0' ; no scroll no max...
- dc i2'0,0' ; No zooming...
- dc i2'0,0' ; no scrolling
- dc i2'0,0' ; no paging....
- dc i4'0' ; no info bar, no ref con
- dc i2'0' ; info bar height (none...)
- dc i4'0' ; Frame defproc, NIL=standard
- dc i4'0' ; no info bar def proc
- dc i4'0' ; no auto updates..(yet)
- dc i2'20,20,140,420' ; bounds rect...
- dc i4'$FFFFFFFF' ; plane= on top...
- dc i4'0' ; NIL storage pointer
- WindEnd equ *
- WindPointer ds 4
-
- end
-
-
- EJECT
- *******************************************************************************
- *
- InitApp start
- *
- * Description: Perform any application specific initialization.
- *
- * Inputs: NONE
- *
- * Outputs: NONE
- *
- * External Refs:
- * Import CreateList
- * Import CreateCtrls
- * Import NoSelection
- *
- * Entry Points: NONE
- *
- *******************************************************************************
- using Globals
-
- stz QuitFlag
-
- pha
- pha
- PushLong #MyWindow
- _NewWindow
- PullLong WindPointer
-
- PushLong WindPointer
- _SetPort
-
- jsr CreateList ; make a list in the window
- jsr CreateCtrls
- jsr NoSelection ; reset the buttons to unselected
-
- PushWord #255 ; deactivate the delete button
- PushLong NewBHdl ; handle to the delete button
- _HiLiteControl
-
- PushWord #25 ; set the size of LineEdit's
- _LESetScrapLen ; scrap to 25 characters
-
- rts
- end
-
- EJECT
- *******************************************************************************
- *
- CloseApp start
- *
- * Description: Close down things. This disposes of all items and memory
- * that we allocated.
- *
- *
- * Inputs: NONE
- *
- * Outputs: NONE
- *
- * External Refs: NONE
- *
- * Entry Points: NONE
- *
- *******************************************************************************
- using Globals
-
- rts
- end
-
- EJECT
- *******************************************************************************
- *
- EventLoop start
- *
- * Description: Main Event Loop. Handle things until user selects Quit.
- *
- *
- * Inputs: NONE
- *
- * Outputs: NONE
- *
- * External Refs:
- * Import MenuSelect
- * Import Ignore
- * Import doUpdate
- * Import InContent
- * Import doActivate
- * Import doKey
- *
- * Entry Points: NONE
- *
- *******************************************************************************
- using Globals
-
- PushLong LEHandle ; flash the LineEdit cursor
- _LEIdle
-
- pha ; Push on space for TaskMaster result
- PushWord #everyEvent ; GetNextEvent mask
- PushLong #EventRecord ; Pointer to Event Record
- _TaskMaster
-
- pla ; Get TaskMaster result
- beq EventLoop ; Remove if you want to use null events
- asl A ; Turn it into an index
- tax
- jsr (TaskTable,x) ; Call appropriate event handler
-
- lda QuitFlag ; Quit selected?
- beq EventLoop ; no - keep looping
-
- rts ; yes- leave the program
-
- TaskTable dc i2'Ignore' ; 0 Null
- dc i2'Ignore' ; 1 MouseDown
- dc i2'Ignore' ; 2 MouseUp
- dc i2'doKey' ; 3 KeyDown
- dc i2'Ignore' ; 4 undefined
- dc i2'doKey' ; 5 AutoKey
- dc i2'doUpdate' ; 6 Update
- dc i2'Ignore' ; 7 undefined
- dc i2'doActivate' ; 8 Activate
- dc i2'Ignore' ; 9 Switch
- dc i2'Ignore' ; 10 Desk accessory
- dc i2'Ignore' ; 11 Device driver
- dc i2'Ignore' ; 12 ap
- dc i2'Ignore' ; 13 ap
- dc i2'Ignore' ; 14 ap
- dc i2'Ignore' ; 15 ap
- dc i2'Ignore' ; TASK 0 indesk
- dc i2'MenuSelect' ; TASK 1 in menuBar
- dc i2'Ignore' ; TASK 2 in system window
- dc i2'InContent' ; TASK 3 in content
- dc i2'Ignore' ; TASK 4 in Drag
- dc i2'Ignore' ; TASK 5 in grow
- dc i2'Ignore' ; TASK 6 in goaway
- dc i2'Ignore' ; TASK 7 in zoom
- dc i2'Ignore' ; TASK 8 in info bar
- dc i2'MenuSelect' ; TASK 9 in special menu
- dc i2'Ignore' ; TASK 10 in NDA
- dc i2'Ignore' ; TASK 11 in frame
- dc i2'Ignore' ; TASK 12 in drop
-
- end
-
- EJECT
- *******************************************************************************
- *
- MenuSelect start
- *
- * Description: This routine is called when TaskMaster returns a menu
- * event. It takes the menu item that was hit and calculates
- * an offset into the menu dispatch table. It then calls that
- * routine and unhilites the menu when it is done.
- *
- * Inputs: TaskData holds menu item selected.
- *
- * Outputs: NONE
- *
- * External Refs:
- * Import Ignore
- * Import doAbout
- * Import doQuit
- * Import doCut
- * Import doCopy
- * Import doPaste
- * Import doClear
- *
- * Entry Points: NONE
- *
- *******************************************************************************
- using Globals
-
- lda TaskData ; Get the ID of the menu item selected.
- sec ; Turn it into an index by subtracting
- sbc #250 ; the starting ID number (25) and mul-
- asl a ; tiplying by 2 (each table entry con-
- tax ; sists of 2 bytes).
- jsr (MenuTable,x) ; Call the routine behind it.
-
- PushWord #0 ; Routine done - unhilite the menubar.
- PushWord TaskData+2
- _HiLiteMenu
-
- rts
-
- MenuTable dc i2'Ignore' ; undo
- dc i2'doCut' ; cut
- dc i2'doCopy' ; copy
- dc i2'doPaste' ; paste
- dc i2'doClear' ; clear
- dc i2'Ignore' ; close
- dc i2'doAbout'
- dc i2'doQuit'
- end
-
- EJECT
- *******************************************************************************
- *
- Ignore start
- *
- * Description: Called when I want to ignore an event.
- *
- *
- * Inputs: NONE
- *
- * Outputs: NONE
- *
- * External Refs: NONE
- *
- * Entry Points: NONE
- *
- *******************************************************************************
-
- rts
- end
-
- EJECT
- *******************************************************************************
- *
- doUpdate start
- *
- * Description: Called by the Main Event Loop to update a window's
- * contents.
- *
- *
- * Inputs: NONE
- *
- * Outputs: NONE
- *
- * External Refs: NONE
- *
- * Entry Points: NONE
- *
- *******************************************************************************
- using Globals
-
- lda WindPointer ; first test to see that its our window
- ora WindPointer+2
- beq NotUp ; bad bad update event!
-
- PushLong WindPointer ; Prepare to update our window
- _BeginUpdate
-
- PushLong WindPointer ; draw all of the controls
- _DrawControls
-
- PushLong #viewRect ; frame our lineEdit item
- _FrameRect
-
- PushLong LEHandle ; update the LineEdit item
- _LEUpdate
-
- PushLong WindPointer ; end updating of our window
- _EndUpdate
-
- NotUp ANOP
- rts
- end
-
- EJECT
- *******************************************************************************
- *
- doActivate start
- *
- * Description: This routine is called when our window is either coming
- * to front, or no longer being in front. Its main function
- * is to make the LineEdit item (in)active.
- *
- *
- * Inputs: Event record from TaskMaster
- *
- * Outputs: NONE
- *
- * External Refs: NONE
- *
- * Entry Points: NONE
- *
- *******************************************************************************
- using Globals
-
- PushLong LEHandle
- lda EventModifiers
- and #activeFlag
- bne Activate
- _LEDeactivate
- bra done
- Activate _LEActivate
- done ANOP
- rts
- end
-
- EJECT
- *******************************************************************************
- *
- doKey start
- *
- * Description: Called by the Main Event loop when a Keydown or AutoKey
- * Event occurs. If the RETURN key was hit, a hit on the
- * "New Item" button is simulated. Otherwise, the key press
- * is passed on to LEKey.
- *
- *
- * Inputs: Event record from TaskMaster
- *
- * Outputs: LineEdit or List is modified
- *
- * External Refs:
- * Import NewListItem
- * Import ckNewAndRep
- *
- * Entry Points: NONE
- *
- *******************************************************************************
- using Globals
-
- lda EventMessage ; get the character pressed
- and #$007f ; clear the high if it's set
- cmp #$0D ; see if it's a <RETURN>
- beq doCR ; if is one, simulate New Item hit
- PushWord EventMessage ; else, pass this on to LEKey
- PushWord EventModifiers
- PushLong LEHandle
- _LEKey
-
- jsr ckNewAndRep ; update the New and Replace buttons
- bra done
-
- doCR ANOP
- PushWord #1 ; Hilite the New button
- PushLong NewBHdl
- _HiLiteControl
-
- PushWord #0 ; UnHilite the New button
- PushLong NewBHdl
- _HiLiteControl
-
- jsr NewListItem ; add the LineEdit text to the list.
-
- done ANOP
- rts
- end
-
- EJECT
- *******************************************************************************
- *
- doEdit start
- *
- * Description: This block is really 4 routines to handle the Edit Menu.
- * Any Edit selections are passed on to the appropriate
- * LineEdit routine. Undo is currently not supported.
- *
- *
- * Inputs: NONE
- *
- * Outputs: NONE
- *
- * External Refs:
- * Import ckNewAndRep
- *
- * Entry Points:
- * Entry doCut
- * Entry doCopy
- * Entry doPaste
- * Entry doClear
- *
- *******************************************************************************
- using Globals
-
- doCut Entry
- PushLong LEHandle ; Handle a "Cut" command
- _LECut
- bra done
-
- doCopy Entry
- PushLong LEHandle ; Handle a "Copy" command
- _LECopy
- rts ; Don't update New and Replace buttons
-
- doPaste Entry
- PushLong LEHandle ; Handle a "Paste" command
- _LEPaste
- bra done
-
- doClear Entry
- PushLong LEHandle ; Handle a "Clear" command
- _LEDelete
-
- done ANOP
- jsr ckNewAndRep ; update the New and Replace buttons
-
- rts
- end
-
- EJECT
- *******************************************************************************
- *
- InContent start
- *
- * Description: Called to handle clicks in a window's contents. FindControl
- * is called to determine on what, if any, control was hit.
- * If a control is hit, it is tracked, and the appropriate
- * routine is called to perform some action. If a control
- * is not hit, then a check is made to see if the LineEdit
- * item was hit. If so, then the click is passed on to LEClick
- * for handling.
- *
- *
- * Inputs: NONE
- *
- * Outputs: NONE
- *
- * External Refs:
- * Import NewListItem
- * Import DelListItem
- * Import RepListItem
- * Import RstListItem
- * Import ListHit
- * Import SortHit
- *
- * Entry Points: NONE
- *
- *******************************************************************************
- using Globals
-
- ; First, find out where we clicked, and see if it was on a control
-
- pha ; result space
- PushLong #TempHndl
- PushLong EventWhere ; push the point
- PushLong WindPointer
- _FindControl
- pla
- bne IC0010 ; hit a control! Track it!
- brl ckLine ; didn't hit control. See if we hit LE
- IC0010 ANOP
- pha ; result space
- PushLong EventWhere ; push mouse location
- PushLong #-1 ; use default action procedure
- PushLong TempHndl ; push on handle to control hit
- _TrackControl ; track it
- pla ; where did we end up?
- bne IC0020 ; still in control. Do something
- brl done ; out of control - exit this routine
- IC0020 ANOP
- cmp #simpleButton ; was it a button?
- beq CallCtlAction ; if so then handle it
- cmp #$88 ; was it the list itself?
- bne done ; if not, then not a hit!
-
- ; We use a neat trick to determine what routine to call inresponse to a
- ; click on a control. We keep a 'routine index' in the refcon field of
- ; the control. When a click occurs on that control, we retrieve the
- ; refcon, turn it into an index into a table of routine pointers, get
- ; the pointer to a routine, and call it!
-
- CallCtlAction ANOP
- pha ; space for result
- pha
- PushLong TempHndl ; get the item number from the refcon
- _GetCtlRefCon
- pla ; low byte of ref con
- plx ; (we don't use high byte)
- dec a ; subtract 1 from the refcon then
- asl a ; multiply by two to get table offset
- tax
- jsr (InCTable,x) ; jump to routine to handle this ctl
- bra done
-
- ; the mouse click did not occur in any of the regular controls. check to
- ; see if we clicked in the LineEdit item. If so, then call LEClick.
-
- ckLine ANOP
- lda EventWhere ; Check to see if we clicked in the
- sta LocalPt ; LineEdit item. We do this by doing a
- lda EventWhere+2 ; PtInRect. But we need the mouse in
- sta LocalPt+2 ; local coordinates for this.
-
- PushLong #LocalPt
- _GlobalToLocal
-
- pha ; space for result
- PushLong #LocalPt
- PushLong #destRect
- _PtInRect ; see if we clicked in the edit item
- pla
- beq done ; no, we didn't, so leave
-
- PushLong #EventRecord ; yes we did, so call LEClick
- PushLong LEHandle
- _LEClick
-
- done rts
-
- theRefCon ds 4
- InCTable dc i2'NewListItem,DelListItem,RepListItem'
- dc i2'RstListItem,ListHit,SortHit'
- LocalPt ds 4
-
- end
-
- EJECT
- *******************************************************************************
- *
- NewListItem start
- *
- * Description: This routine is called by InContent if a click occured
- * on the "New" button. This routine determines is there
- * is enough room in the List record for another item. If
- * so, then a pointer to the next record is is created, and
- * AddMember is called to create a new List member using
- * the text from the LineEdit item. When that is done, we
- * tell the List Manager about it, and hilite the LineEdit
- * text so that it is easily changed into something else.
- *
- *
- * Inputs: NONE
- *
- * Outputs: List updated. LineEdit text hilited.
- *
- * External Refs:
- * Import AddMember
- *
- * Entry Points: NONE
- *
- *******************************************************************************
- using Globals
-
- lda MLNum ; # of elements in the list
- cmp #30 ; do we have 30 already?
- bge NLIDone
- inc MLNum ; bump number of list entries
-
- ; Create a pointer to the next available space in the array of list record.
- ; This is done by multiplying the entry number the entry size. Multiplying
- ; is done by using the formula x = index*2 + index*8 (assuming that the size
- ; of a member record = 10)
-
- asl a ; multiply by 2
- sta TempWord ; save it for adding to *8 later
- asl a ; by four
- asl a ; and eight
- clc
- adc TempWord ; add in the times 2 part
-
- ; AddMember is the routine that we use to assign the text of the LineEdit
- ; item to a certain list record. All we have to do is enter with the
- ; accumulator holding a pointer to the right record, and it does the rest.
-
- jsr AddMember ; enter with record offset in Acc.
-
- ; Now tell the List Manager that we changed the list. Also, make sure that
- ; the item that is hilited in the list is STILL hilited. Do this by getting
- ; a pointer to the selected record, and passing it to _NewList
-
- pha ; long space for result
- pha
- PushLong #0 ; start searching from the beginning
- PushLong #MyList
- _NextMember ; Get pointer Keep it on the stack
- PushLong #MyList ; pointer to my list record
- _NewList ; and make the new list!
-
- ; finally, hilite the line edit text so that we can easily change it later
-
- PushWord #0 ; starting hilite range
- PushWord #255 ; ending range
- PushLong LEHandle ; hande to the LE control
- _LESetSelect ; hilite it.
-
- NLIDone ANOP
- rts
-
- end
-
- EJECT
- *******************************************************************************
- *
- DelListItem start
- *
- * Description: Called by InContent to remove a member from the list. It
- * is called only when there is a hilited list item to be
- * removed. This routine determines which item is hilited,
- * removes it from the list of member records, decrements
- * the number of members in the list, and redraws the list.
- *
- *
- * Inputs: NONE
- *
- * Outputs: NONE
- *
- * External Refs:
- * Import DisposeMember
- * Import NoSelection
- * Import ckNewAndRep
- *
- * Entry Points: NONE
- *
- *******************************************************************************
- using Globals
-
- lda MLNum ; contains # of elements
- cmp #1 ; do we have only 1 left?
- beq DLIDone ; if so then remove no more!
- dec MLNum ; adjust number of list entries
-
- ; DisposeMember finds the hilited list item, and puts an index to it in the
- ; X register. Also, if the string for the name of the member was stored in
- ; a handle, that handle is disposed of.
-
- jsr DisposeMember ; X set up for us on exit
-
- loop ANOP
- lda MyData+MemberSize,x
- sta MyData,x ; move all data down 10 bytes
- inx ; ...in memory...
- inx ; ...two bytes at a time
- cpx #MyDataTSize ; is X bumped past the end of records?
- blt loop ; nope, keep looping
-
- PushLong #0 ; Draw All members to redraw the list!
- PushLong #MyList
- _NewList ; and create the new list!
-
- jsr NoSelection ; now reset the apropriate buttons
-
- DLIDone ANOP
- jsr ckNewAndRep
- rts
-
- end
-
- EJECT
- *******************************************************************************
- *
- RepListItem start
- *
- * Description: This routine is called from InContent to replace the text
- * of the hilited member with the text in the LineEdit Item.
- * It calls NextMember to find the hilited item, Disposes of
- * it, and then inserts a new item in the same place with the
- * new name.
- *
- *
- * Inputs: NONE
- *
- * Outputs: NONE
- *
- * External Refs:
- * Import DisposeMember
- * Import AddMember
- * Import NoSelection
- *
- * Entry Points: NONE
- *
- *******************************************************************************
- using Globals
-
- pha ; space for result
- pha
- PushLong #0 ; member to start looking at
- PushLong #MyList ; NOTE: This is the list template ptr
- _NextMember
- PullLong TempLong ; Pointer to item Selected
-
- ;
- ; Now that we know which member is being replaced, call DisposeMember to free
- ; up the memory that is allocated to it, and then call AddMember to fill in that
- ; member's record with new information.
- ;
- jsr DisposeMember
- txa
- jsr AddMember
-
- ; The information for the currently selected member has been changed. Now
- ; redraw the member.
-
- PushLong TempLong ; pass ptr of member to redraw
- PushLong #MyList
- _DrawMember
-
- jsr NoSelection ; now reset the apropriate buttons
-
- ; finally, hilite the line edit text so that we can easily change it later
-
- PushWord #0 ; starting hilite range
- PushWord #255 ; ending range
- PushLong LEHandle ; hande to the LE control
- _LESetSelect ; hilite it.
-
- rts
- end
-
- EJECT
- *******************************************************************************
- *
- RstListItem start
- *
- * Description: This routine is called by InContent to unhilite, or reset,
- * the currently selected item. It simply calls ResetMember
- * and then redraws that member.
- *
- *
- * Inputs: NONE
- *
- * Outputs: NONE
- *
- * External Refs:
- * Import NoSelection
- *
- * Entry Points: NONE
- *
- *******************************************************************************
- using Globals
-
- pha ; space for result
- pha
- PushLong #MyList ; NOTE: This Is the list template ptr
- _ResetMember ; get item selected & unselect it
- PullLong TempLong ; Item Selected
-
- ; Obviously, at this point we could have omitted the PullLong/PushLong
- ; sequence to save some bytes, but we wanted to make sure that people were
- ; clear on what ResetMember returned, and what was passed to DrawMember.
-
- PushLong TempLong ; pass ptr of member to redraw
- PushLong #MyList ; now redraw the list
- _DrawMember
-
- jsr NoSelection ; turn off those buttons
- rts
- end
-
- EJECT
- *******************************************************************************
- *
- ListHit start
- *
- * Description: This routine is called by InContent when a hit on the List
- * item has occured. It activates the buttons we need when a
- * list item is selected, and gets the text of the item and
- * puts it into the LineEdit box. Finally, it hilites the
- * LineEdit text so that we can easily change it if we want.
- *
- *
- * Inputs: NONE
- *
- * Outputs: NONE
- *
- * External Refs: NONE
- *
- * Entry Points: NONE
- *
- *******************************************************************************
- using Globals
-
- PushWord #0 ; activate the delete button
- PushLong DelBHdl ; handle to the delete button
- _HiLiteControl
-
- PushWord #255 ; now deactivate the replace button
- PushLong RepBHdl ; until we change edit item
- _HiLiteControl
-
- PushWord #0 ; now activate the replace button
- PushLong RstBHdl
- _HiLiteControl
-
- ;
- ; Find out which member we hit, and insert its text into Line Edit
- ;
- pha ; space for result
- pha
- PushLong #0 ; NIL to start at first entry
- PushLong #MyList ; pointer to my list record...
- _NextMember
- PullLong deref ; pointer to the next record
-
- ldy #2 ; get the pointer to the string. We do
- lda [deref],y ; this by getting the pointer that the
- tax ; handle points to, and storing it back
- lda [deref] ; out in 'deref'.
- sta deref
- stx deref+2
-
- PushWord deref+2 ; push on a pointer to the first character
- lda deref
- ina
- pha
- lda [deref] ; get the length of the string
- and #$00FF
- pha ; push on the length
- PushLong LEHandle
- _LESetText
-
- ; Now invalidate the area of the screen that contained the text so that
- ; LineEdit will redraw it.
-
- PushLong #destRect
- _InvalRect
-
- ; finally, hilite the line edit text so that we can easily change it later
-
- PushWord #0 ; starting hilite range
- PushWord #255 ; ending range
- PushLong LEHandle ; hande to the LE control
- _LESetSelect ; hilite it.
-
- rts
- end
-
- EJECT
- *******************************************************************************
- *
- SortHit start
- *
- * Description: This routine is called by InCotent when a click on the
- * Sort button occurs. It calls _SortList with a pointer to
- * a custom sorting routine, and then redraws the entire list.
- * The custom sorting procedure sorts the list in reverse
- * alphabetical order.
- *
- *
- * Inputs: NONE
- *
- * Outputs: NONE
- *
- * External Refs: NONE
- *
- * Entry Points: NONE
- *
- *******************************************************************************
- using Globals
-
- PushLong #MySort ; Case insensitive sort routine
- PushLong #MyList
- _SortList
-
- PushLong #0 ; redraw all members
- PushLong #MyList
- _DrawMember
-
- rts
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- MySort ANOP
- ;
- ; This is the custom sorting routine. It is passed the pointers to
- ; 2 member records to compare. If the first member is 'less than' the
- ; second, then return with the carry set. Otherwise, the carry should
- ; be returned clear. When I am done, remove the parameters off of the
- ; stack and RTL back to the List Manager.
- ;
- ; The following are equates that I use for a 'local direct page'. I
- ; save off the register that points to the normal direct page, and
- ; put the value of the stack pointer into the Direct Page register.
- ; This way, the stack doubles as my direct page, and I can easily
- ; access the variables that were pushed on it. These equates repre-
- ; sent the information on the stack when my routine is called.
- ; Specifically, there is a 3 byte return address that will get me
- ; back to the list manager, and then there are 2 4-byte parameters
- ; that are pointers to the 2 members I have to compare.
- ;
- RTLAddr equ 1
- MemberA equ RTLAddr+3
- MemberB equ MemberA+4
-
- tsc ; save the old Direct Page and
- phd ; make the stack our DP so that
- tcd ; we can use the params as pointers
-
- ldy #2 ; replace the pointer to the first
- lda [MemberA],y ; member with the pointer to the
- tax ; string of that member.
- lda [MemberA]
- sta MemberA
- stx MemberA+2
-
- lda [MemberB],y ; do the same thing with the second
- tax ; member.
- lda [MemberB]
- sta MemberB
- stx MemberB+2
-
- SHORTMX ; Use 8-bit registers
-
- ldy #1 ; Start comparing with char #1
- cmpLoop ANOP
- lda [MemberB],y ; Now compare the string characters.
- jsr upperIt
- sta firstChar
- lda [MemberA],y
- jsr upperIt
- cmp firstChar ; If they are not equal, exit with the
- bne done ; carry is set appropriately.
-
- tya ; Check to see if we ended a string
- dec a
- cmp [MemberB] ; end of Member B?
- beq AGreater ; if so, exit with carry set.
-
- cmp [MemberA] ; end of Member A?
- beq BGreater ; if so, exit with carry clear.
-
- iny ; bump index to examine next char.
- bra cmpLoop
-
- AGreater clc
- bra done
- BGreater sec
- done LONGMX
-
- pld ; restore the Direct Page reg from stack.
-
- lda 0,s ; move the RTL address up so that it is
- sta 8,s ; in the right place after we remove the
- lda 2,s ; parameters.
- sta 10,s
- pla ; remove the pointers to the members from
- pla ; the stack.
- pla
- pla
- rtl
-
- longa off
- upperIt cmp #'z'+1
- bcs aa
- cmp #'a'
- bcc aa
- sbc #32
- aa rts
- longa on
-
- firstChar dc i1'0'
-
- end
-
- EJECT
- *******************************************************************************
- *
- ckNewAndRep start
- *
- * Description: Called from all over the place to correctly set the
- * activation states of the New and Replace buttons.
- *
- *
- * Inputs: NONE
- *
- * Outputs: NONE
- *
- * External Refs: NONE
- *
- * Entry Points: NONE
- *
- *******************************************************************************
- using Globals
-
- ; Disable the replace button if no items are selected
-
- pha ; long space for result
- pha
- PushLong #0 ; start searching from the beginning
- PushLong #MyList
- _NextMember
- pla ; was a pointer returned (if a long
- sta TempWord ; zero is return, there are not items
- pla ; selected).
- ora TempWord
- beq DisableRepItem
-
- PushWord #0 ; activate the replace button
- bra FixRepButton
-
- DisableRepItem ANOP
- PushWord #255 ; deactivate the replace button
-
- FixRepButton ANOP
- PushLong RepBHdl
- _HiLiteControl
-
- ; Enable or disable the New entry button depending on whether or not there
- ; is any text in the LineEdit buffer.
-
- pha
- PushLong LEHandle
- _LEGetTextLen
- pla
- beq disableIt ; if no length, then no text.
-
- PushWord #0 ; activate the New button
- bra CallHilite
-
- disableIt ANOP
- PushWord #255 ; deactivate the New button
-
- CallHilite ANOP
- PushLong NewBHdl
- _HiLiteControl
-
- RTS
- end
-
- EJECT
- *******************************************************************************
- *
- AddMember start
- *
- * Description: Utility routine called from NewListItem and RepListItem to
- * insert a new member. This routine will read the entry in
- * the LineEdit record, store it in a handle, and create a
- * new member record at the spot that is specified by the
- * accumulator. It does not redraw the list.
- *
- *
- * Inputs: A = the offset to the record that you want to change.
- *
- * Outputs: X = the offset to the record that was changed.
- *
- * External Refs: NONE
- *
- * Entry Points: NONE
- *
- *******************************************************************************
- using Globals
-
- sta RecordIndex
-
- pha ; space for handle
- pha
- PushLong LEHandle
- _LEGetTextHand ; get the text from Line Edit
- PullLong TempHandle
-
- pha
- PushLong LEHandle
- _LEGetTextLen ; find out how large it is.
- PullWord StringSize
-
- pha ; make room for NewHandle result
- pha
- PushWord #0 ; push handle size that we want
- lda StringSize ; but add 1 to it to take into
- inc a ; account the string length byte
- pha
- PushWord MyID
- PushWord #attrFixed+attrNoCross
- PushLong #0
- _NewHandle ; create a handle for the string
-
- ; save the handle we got in 'StringHandle' so that we can later store it in the
- ; member's record. Also store it in 'deref' so that we can dereference it. The
- ; macro PullLong addr1,addr2 will do that for us in one step!
-
- PullLong StringHandle,deref
-
- ldy #2 ; dereference the String Handle to get
- lda [deref],y ; just a pointer.
- tax
- lda [deref]
- sta deref
- stx deref+2
-
- lda StringSize ; create a Pascal string from the lineEdit
- sta [deref] ; item for the List Manager
-
- ; Copy the LineEdit string into the string's handle. However, set the
- ; destination to be the second byte of the handle, as we need to put the
- ; length of the string in the first byte.
-
- PushLong TempHandle ; handle of the source string
- lda deref+2 ; deref holds a pointer to the start
- pha ; of the destination, but we have to bump
- lda deref ; by one to account for the length byte
- inc a ; that we have to stick there.
- pha
- PushWord #0 ; bytes to transfer must be LONG, so
- PushWord StringSize ; create a high byte of zero.
- _HandToPtr
-
- ; initialize the data in the member record we are creating.
-
- ldx RecordIndex
- lda deref ; get low word of address of new string
- sta MyData,x ; and save it
- lda deref+2 ; and now the high word
- sta MyData+2,x
- lda #0 ; store a memflag byte
- sta MyData+4,x
- lda StringHandle ; store the handle to the string so that
- sta MyData+6,x ; we can easily dispose of it later.
- lda StringHandle+2
- sta MyData+8,x
-
- rts
-
- StringHandle ds 4
- TempHandle ds 4
- StringSize ds 4
- RecordIndex ds 2
-
- end
-
- EJECT
- *******************************************************************************
- *
- DisposeMember start
- *
- * Description: Find the currently hilited list member and and return
- * with an offset to it. Will also dispose of any memory
- * associated with it to hold the displayed text.
- *
- *
- * Inputs: NONE
- *
- * Outputs: X = offset from start of Member record array where the
- * currently hilited member is stored.
- *
- * External Refs: NONE
- *
- * Entry Points: NONE
- *
- *******************************************************************************
- using Globals
-
- ; Call _NextMember to find the hilited item. Calculate the offset
- ; within MyData of that record, and dispose of any string handles
- ; that may be there.
-
- pha ; space for result
- pha
- PushLong #0 ; NIL to start at first entry
- PushLong #MyList ; pointer to my list record.
- _NextMember
- pla ; pointer to the next record
- plx ; discard the high byte
- sec ; subtract the front of the list to
- sbc #MyData ; get the offset into the table
- tax ; put into X so we can adjust the list
- stx RecordIndex ; save it here for when we exit
-
- lda MyData+6+2,x ; See if there's a string handle by
- ora MyData+6,x ; checking for a NULL handle.
- beq done ; no string - so nothing to dispose of
-
- PushLong MyData+6,x ; get the string handle and dispose of it
- _DisposeHandle
- done ANOP
- ldx RecordIndex ; return with offset in X register.
- rts
-
- RecordIndex ds 2
-
- end
-
-
- EJECT
- *******************************************************************************
- *
- NoSelection start
- *
- * Description: Set the activation state of the buttons to reflect the
- * fact that no list items are selected.
- *
- *
- * Inputs: NONE
- *
- * Outputs: NONE
- *
- * External Refs: NONE
- *
- * Entry Points: NONE
- *
- *******************************************************************************
- using Globals
-
- PushWord #255 ; deactivate the delete button
- PushLong DelBHdl ; handle to the delete button
- _HiLiteControl
-
- PushWord #255 ; deactivate the reset button
- PushLong RstBHdl
- _HiLiteControl
-
- PushWord #255 ; deactivate the replace button
- PushLong RepBHdl
- _HiLiteControl
-
- rts
- end
-
- EJECT
- *******************************************************************************
- *
- CreateCtrls start
- *
- * Description: Called at initialization time to create all of the
- * simple buttons we use.
- *
- *
- * Inputs: NONE
- *
- * Outputs: NONE
- *
- * External Refs: NONE
- *
- * Entry Points: NONE
- *
- *******************************************************************************
- using Globals
-
- stz CCCount ; zero our counter
- CCLoop ANOP
- lda CCCount ; get the next ctrl num to add
- asl a ; multiply it by four to make it an
- asl a ; offset into our control table
- tax ; now use it as an index
- lda MyCtrlList,x ; to get the pointer to the control data
- sta deref ; and save it in the DPage
- lda MyCtrlList+2,x ; so we can read it nicely
- sta deref+2
- stx TempWord ; save x for a moment
-
- pha ; space for result
- pha
- PushLong WindPointer ; pointer to my window
-
- ; Push on NewControl parameters. These parameters are obtained from tables
- ; in our Globals section. Each one is 'cRecSize' long, so we load the Y reg
- ; with that value (less 2), and use it to access all of the parameters in
- ; the table, pushing each one on the stack as we go.
-
- ldy #cRecSize-2
- CCL010 lda [deref],y ; Get these parameters from a list of
- pha ; data blocks in the Globals data
- dey ; section.
- dey
- bpl CCL010 ; if not done, get the next one!
-
- _NewControl ; if so, then just call new control!
-
- ldx TempWord ; retrieve x
- pla ; and save the control handle
- sta MyCtlHdls,x
- pla
- sta MyCtlHdls+2,x
-
- inc CCCount ; bump counter to get next record
- lda CCCount
- cmp NumCtrls ; test to see if we did the last one
- blt CCLoop ; if so, then just end
-
- ;
- ; Create the LineEdit item.
- ;
- pha ; space for result
- pha
- PushLong #destRect
- PushLong #destRect
- PushWord #20 ; Allow only 20 chars in list item
- _LENew
- PullLong LEHandle
-
- rts
-
- tempHandle ds 4
- CCCount ds 2
-
- end
-
- EJECT
- *******************************************************************************
- *
- CreateList start
- *
- * Description: Called at initialization time to create the list item. It
- * simply calls _CreateList with a parameter block defined
- * in the Globals data section.
- *
- *
- * Inputs: NONE
- *
- * Outputs: NONE
- *
- * External Refs: NONE
- *
- * Entry Points: NONE
- *
- *******************************************************************************
- using Globals
-
- pha ; room for result
- pha
- PushLong WindPointer
- PushLong #MyList ; pointer to list rec
- _CreateList
- PullLong ListCtlHndl ; and get our list control handle
-
- rts
- end
-
- EJECT
- *******************************************************************************
- *
- doQuit start
- *
- * Description: Quit routine. Set the QuitFlag to TRUE for the EventLoop.
- *
- *
- * Inputs: NONE
- *
- * Outputs: QuitFlag set to $FFFF
- *
- * External Refs: NONE
- *
- * Entry Points: NONE
- *
- *******************************************************************************
- using Globals
-
- lda #$FFFF
- sta QuitFlag
- rts
- end
-
- copy lists.inits.asm
-
- END
-