Apple II Technical Notes _____________________________________________________________________________ Developer Technical Support Apple IIGS #74: A Faster List Manager Draw Routine Written by: Jim Mensch November 1989 This Technical Note presents a method for speeding up custom List Draw routines, with sample source code for the APW assembler. _____________________________________________________________________________ The List Manager is designed to allow users to select from relatively small lists. In this respect, it does quite well. However, when the width or height of the displayed area gets above a certain size (about 20 chars wide and 6 items tall) the list starts to scroll slower than normal. This is due to the design of the List Manager's scroll routine. To scroll text, the List Manager calls ScrollRect to scroll the list, then it redraws all the visible members. On small lists this is fine, but on larger lists it can cause the redrawing of much data that is already on the screen, which can take time. To cure this problem, you can include a simple draw procedure in your program that checks the clipRgn before anything is drawn. This way, you will not attempt to redraw items that do not need redrawing. The custom draw routine in this Note is an example of one such routine that could be used. It first checks the current clipRgn (which the List Manager was kind enough to shrink down to include only the portion of the list that needs redrawing) against the passed item rectangle. If the rectangle is in any way enclosed in the clipRgn, then the member is redrawn; otherwise the routine simply returns to the List Manager without drawing. This sample routine is designed to work only with Pascal-style strings, but it can be easily modified to use any other type of string you choose. MyListDraw Start ; ; This routine draws a list member if any part of the member's ; rectangle is inside the current clipRgn. ; ; Note that the Data Bank register is not defined on entry ; to this routine. If you use any absolute addressing, you ; must set B yourself and restore its value before exiting. ; top equ 0 left equ top+2 bottom equ left+2 right equ bottom+2 rgnBounds equ 2 ; oldDPage equ 1 theRTL equ oldDPage+2 listHand equ theRTL+3 memPtr equ listHand+4 theRect equ memPtr+4 using globals phd tsc tcd pha pha _GetClipHandle PullLong listHand ldy #2 lda [listhand],y tax lda [listhand] sta listhand stx listhand+2 lda [therect] ; now test the top dec a ; adjust and give a little slack ldy #rgnbounds+bottom cmp [listhand],y ; rgnRectBottom>=top? blt skip2 brl NoDraw ; if not don't draw.. Skip2 ldy #bottom ; now see if the bottom is higher than ; the top inc a ; give a little slack lda [therect],y ldy #rgnBounds+top cmp [listhand],y blt NoDraw NoTest ANOP PushLong theRect _EraseRect ; erase the old rectangle ldy #left lda [theRect],y tax ldy #bottom lda [theRect],y dec a phx pha _MoveTo ldy #2 lda [memptr],y pha lda [memptr] pha _DrawString ldy #4 lda [memPtr],y and #$00C0 ; strip to the 6 and 7 bits beq memDrawn ; if they are both 0 the member is drawn cmp #$0080 ; member selected? bne noSelect ; member not selectable PushLong theRect _InvertRect bra memDrawn ; if we get here the member is disabled noSelect PushLong #DimMask _SetPenMask PushLong theRect _EraseRect PushLong #NorMask _SetPenMask memDrawn ANOP ; exit here pld sep #$20 longa off pla ply plx plx plx plx plx plx phy pha rep #$20 longa on rtl DimMask dc i1'$55,$AA,$55,$AA,$55,$AA,$55,$AA' NorMask dc i1'$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF' end Further Reference _____________________________________________________________________________ o Apple IIGS Toolbox Reference, Volumes 1 and 3