; ; viewer.s ; ; Filer-like windows with re-arranging icons (MDW) ; ; © 1995-1998 Straylight ; ;----- Licensing note ------------------------------------------------------- ; ; This file is part of Straylight's Sapphire library. ; ; Sapphire is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2, or (at your option) ; any later version. ; ; Sapphire is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with Sapphire. If not, write to the Free Software Foundation, ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ;----- Standard header ------------------------------------------------------ GET libs:header GET libs:swis GET libs:stream ;----- External dependencies ------------------------------------------------ GET sapphire:akbd GET sapphire:alloc GET sapphire:divide GET sapphire:drag GET sapphire:fastMove GET sapphire:msgs GET sapphire:sapphire GET sapphire:screen GET sapphire:wimp GET sapphire:win GET sapphire:winUtils ;----- Macros --------------------------------------------------------------- MACRO $label MSGB $msg,$branch $label DCD $msg B $branch MEND ;----- Main code ------------------------------------------------------------ AREA |Sapphire$$Code|,CODE,READONLY ;----- Creating and deleting viewers ---------------------------------------- ; --- viewer_create --- ; ; On entry: R0 == pointer to a viewer definition block ; R1 == pointer to a list ; R2 == sprite area for window ; ; On exit: R0 == viewer handle ; May return an error ; ; Use: Creates a viewer window. The viewer definition block ; contains various interesting bits of information about the ; viewer which are likely to be known at assembly time: ; ; (word) address of a list manager definition block ; (word) address of a shape handler function (or 0) ; (word) standard width of icons ; (word) standard height of icons ; (string) banner text message tag, or empty ; ; The shape function is used to allow viewer icons to have a ; non-rectangular shape. The function is called with a reason ; code in R0; entry and exit conditions depend on this: ; ; vwShape_size ; On entry ; R1 == pointer to list item ; R2 == standard width of icon ; R3 == standard height of icon ; ; On exit ; R2 == width of this icon ; R3 == height of this icon ; ; Use ; This routine is used to find the actual size of an icon. ; The icons are aligned on a grid according to the largest ; one: this routine is used to find out which one that is. ; ; vwShape_intersects ; On entry ; R1 == pointer to list item ; R2 == address of bounding box of this icon ; R3 == address of bounding box to compare ; ; On exit ; CS if boxes intersect, else CC ; ; Use ; For detecting mouse clicks etc. on an icon. viewer has ; already ensured that the box in R3 intersects with the ; bounding box, so for rectangular icons, you can just return ; with C set always. This entry is provided so that you ; can check against the sprite and text of a text+sprite ; icon separately. ; ; More reason codes may be added later; it will always be ; sensible to return immediately preserving all registers and ; flags. EXPORT viewer_create viewer_create ROUT STMFD R13!,{R1-R5,R10,R14} ;Save some registers ; --- Move arguments into other registers --- MOV R5,R0 ;Look after block def MOV R4,R2 ;And the sprite area ; --- Allocate a viewer block --- MOV R0,#vw__size ;Get the block size BL alloc ;Allocate the memory BLCS alloc_error ;If it failed, get error BCS %99viewer_create ;And return to caller MOV R10,R0 ;Look after the pointer ; --- Fill in bits of the block --- STR R1,[R10,#vw__list] ;Store the list address LDMIA R5!,{R0-R3} ;Load regs from def block STR R0,[R10,#vw__listDef] ;Store list definition addr CMP R1,#0 ;Is the shape function 0? ADREQ R1,vw__dummyShape ;Yes -- use default one STR R1,[R10,#vw__shape] ;Store that away nicely ADD R14,R10,#vw__stdDimens ;Point to standard icon sz STMIA R14,{R2,R3} ;Store them away nicely LDRB R0,[R5,#0] ;Load first byte of banner CMP R0,#0 ;Is it actually defined? MOVNE R0,R5 ;Yes -- point to it then BLNE msgs_lookup ;And translate the tag STR R0,[R10,#vw__banner] ;Store that away nicely ; --- Now create a window --- MOV R0,R11 ;Copy definition to scratch ADR R1,vw__windDef ;Point to my definition MOV R2,#88 ;Size of window definition BL fastMove ;Copy the data over STR R4,[R11,#64] ;Store caller's sprite area ADD R14,R10,#vw__title ;Point to title buffer STR R14,[R11,#72] ;Save this in window block MOV R1,R11 ;Point to window definition SWI XWimp_CreateWindow ;Try to do that then BVS %98viewer_create ;If it failed, tidy up STR R0,[R10,#vw__window] ;Save the window handle ; --- Set up the event handler --- ADR R1,vw__events ;Point to event handler MOV R2,R10 ;Use viewer handle as R10 MOV R3,R12 ;Pass workspace in R12 (*) BL win_eventHandler ;Set up the event handler BVS %97viewer_create ;If it failed, tidy up ; --- Fix up rest of viewer block --- MOV R14,#0 ;No handler defined yet STR R14,[R10,#vw__handler] ;Save that in my block STR R14,[R10,#vw__flags] ;Clear the flags too STR R14,[R10,#vw__tempSel] ;No temporary selection ; --- Now return to caller --- MOV R0,R10 ;Get the viewer handle LDMFD R13!,{R1-R5,R10,R14} ;Restore registers BICS PC,R14,#V_flag ;And return to caller ; --- Handle minor mishaps --- 97viewer_create MOV R5,R0 ;Look after error pointer ADD R1,R10,#vw__window ;Point to window handle SWI Wimp_DeleteWindow ;Destroy the window MOV R0,R5 ;And get the error back 98viewer_create MOV R5,R0 ;Look after error pointer MOV R0,R10 ;Point to viewer block BL free ;Free the block up MOV R0,R5 ;And get the error back 99viewer_create ADD R2,R0,#4 ;Point to error text ADR R0,vw__createErr ;Point to error skeleton BL msgs_error ;Translate and substitute LDMFD R13!,{R1-R5,R10,R14} ;Restore registers ORRS PC,R14,#V_flag ;And return the error vw__dummyShape ORRS PC,R14,#C_flag ;Dummy shape function vw__createErr DCD 1 DCB "vwCRTE",0 vw__windDef DCD 0,0,0,0 DCD 0,0 DCD 0 DCD &BF000002 DCB 7,2,7,1,3,1,12,0 DCD 0,0,0,0 DCD &1700013D DCD &0000A000 DCD 1 DCW 1,0 DCD 0,-1,256 DCD 0 LTORG ; --- viewer_destroy --- ; ; On entry: R0 == viewer handle ; ; On exit: -- ; ; Use: Destroys a viewer, removing it from the screen etc. EXPORT viewer_destroy viewer_destroy ROUT STMFD R13!,{R0,R1,R10,R14} ;Save some registers MOV R10,R0 ;Look after the handle LDR R0,[R10,#vw__window] ;Load the window handle BL win_windowDeleted ;Say it's been deleted ADD R1,R10,#vw__window ;Find the window handle SWI Wimp_DeleteWindow ;Destroy the window MOV R0,R10 ;Point to the viewer block BL free ;Release the memory LDMFD R13!,{R0,R1,R10,PC}^ ;And return to caller LTORG ;----- Opening and closing -------------------------------------------------- ; --- viewer_open --- ; ; On entry: R0 == viewer handle ; R1 == opening style ; R2,R3 == extra arguments ; ; On exit: -- ; ; Use: Opens a viewer window on the screen. EXPORT viewer_open viewer_open ROUT STMFD R13!,{R0,R1,R4,R10,R14} ;Save some registers MOV R10,R0 ;Get the viewer handle MOV R4,R1 ;Look after opening style SUB R13,R13,#36 ;Make a window state block LDR R14,[R10,#vw__window] ;Load the window handle STR R14,[R13,#0] ;Save it in the block MOV R1,R13 ;Point to the block SWI Wimp_GetWindowState ;And read the window state ; --- If window is open, skip on --- BL vw__open ;Is the window open? BCS %10viewer_open ;Yes -- skip onwards then ; --- Open the window onto the screen --- LDR R1,[R10,#vw__listDef] ;Find the list definition LDR R0,[R10,#vw__list] ;And the list base MOV R14,PC ;Set up return address ADD PC,R1,#vw__items ;Find how many items STR R1,[R10,#vw__icons] ;Store this away MOV R1,R13 ;Point at window state blk BL vw__tWidth ;Work out title width BL vw__rescanSize ;Rescan the item size BL vw__extend ;Yes -- make it big then BL vw__resize ;Work out new arrangement BL vw__setExtent ;Set the window's extent ; --- Finally work out where to open it --- 10viewer_open MOV R0,R4 ;Get the opening style BL winUtils_setPosition ;Set the window position BL vw__openWindow ;Open the window there ADD R13,R13,#36 ;Reclaim the stack space LDR R14,[R10,#vw__flags] ;Load the flags word ORR R14,R14,#vwFlag__opened ;We've now opened it STR R14,[R10,#vw__flags] ;Store the flags back LDMFD R13!,{R0,R1,R4,R10,PC}^ ;And return to caller LTORG ; --- viewer_close --- ; ; On entry: R0 == viewer handle ; ; On exit: -- ; ; Use: Closes a viewer window. EXPORT viewer_close viewer_close ROUT STMFD R13!,{R0,R1,R14} ;Save some registers ADD R1,R0,#vw__window ;Find the window handle SWI Wimp_CloseWindow ;Close the window LDMFD R13!,{R0,R1,PC}^ ;And return to caller LTORG ;----- Event handling ------------------------------------------------------- ; --- viewer_eventHandler --- ; ; On entry: R0 == viewer handle ; R1 == pointer to event handler ; R2 == value to pass in R10 ; R3 == value to pass in R12 ; ; On exit: R1-R3 == old values ; ; Use: Sets up the event handle for the viewer. EXPORT viewer_eventHandler viewer_eventHandler ROUT STMFD R13!,{R4-R6,R14} ;Save some registers ADD R14,R0,#vw__handler ;Point to handler block LDMIA R14,{R4-R6} ;Load the old handler STMIA R14,{R1-R3} ;Save the new one MOV R1,R4 ;Transfer information over MOV R2,R5 ;All of it, don't let it MOV R3,R6 ;Get away! LDMFD R13!,{R4-R6,PC}^ ;And return to caller LTORG ; --- vw__events --- ; ; On entry: R0 == event code ; R1 == pointer to event block ; ; On exit: CS if handled, else CC ; ; Use: Handles events for a viewer window. vw__events ROUT CMP R0,#17 ;Is this a message? CMPNE R0,#18 ;Check *both* types BEQ %10vw__events ;Yes -- handle them CMP R0,#9 ;Is the event interesting? ADDCC PC,PC,R0,LSL #2 ;Yes -- dispatch it then MOVS PC,R14 ;Otherwise ignore it ; --- Branch table --- MOVS PC,R14 B vw__evRedraw B vw__evOpen B vw__evClose MOVS PC,R14 MOVS PC,R14 B vw__evMouse MOVS PC,R14 B vw__evKey ; --- Handle messages --- ; ; This is a little odd, in the interests of expandability. 10vw__events STMFD R13!,{R2-R4,R14} ;Save some registers LDR R2,[R1,#16] ;Load the message code ADR R3,vw__msgTable ;Point to the message table 00 LDR R4,[R3],#8 ;Load the message code CMP R4,R2 ;Do I recognise this event? SUBEQ R3,R3,#4 ;Yes -- point to branch instr STREQ R3,[R13,#12] ;Store as return address CMPNE R4,#-1 ;Is it the end of the list? BNE %b00 ;No -- keep looping then LDMFD R13!,{R2-R4,PC}^ ;Call the routine ; --- Message table --- vw__msgTable MSGB &1,vw__mDataSave MSGB &3,vw__mDataLoad MSGB &502,vw__mHelpRq MSGB &400CF,vw__mFontChnge DCD -1,-1 LTORG ; --- vw__dispatch --- ; ; On entry: R0 == event code ; R1-R5 set up for event ; ; On exit: CS or CC according to event handler ; ; Use: Dispatches an event to the user's handler. EXPORT vw__dispatch vw__dispatch ROUT STMFD R13!,{R8-R10,R12,R14} ;Save some registers ADD R14,R10,#vw__handler ;Find the handler routine MOV R9,R10 ;Pass viewer handle in R9 LDMIA R14,{R8,R10,R12} ;Load the things out ADDS R0,R0,#0 ;Clear the carry flag TEQ R8,#0 ;Is there a routine? MOVNE R14,PC ;Yes -- set up return addr MOVNE PC,R8 ;And call the routine LDMFD R13!,{R8-R10,R12,R14} ;Restore registers ORRCSS PC,R14,#C_flag ;If it set C, we do too BICCCS PC,R14,#C_flag ;Otherwise we clear it LTORG ; --- vw_evRedraw --- ; ; On entry: R1 == pointer to window handle in block ; ; On exit: CS ; ; Use: Redraws a viewer window. vw__evRedraw ROUT STMFD R13!,{R0-R7,R14} ;Save some registers SWI Wimp_RedrawWindow ;Start the redraw job CMP R0,#0 ;Is this the end yet? BEQ %90vw__evRedraw ;Yes -- do nothing then ; --- Find the window origin --- MOV R7,R1 ;Remember the block pointer LDR R2,[R7,#4] ;Load the left hand side ADD R14,R7,#16 ;Point to top and scroll pos LDMIA R14,{R3-R5} ;Load those positions out SUB R6,R3,R5 ;Find the top position SUB R5,R2,R4 ;And the left side SUB R13,R13,#32 ;Space for rectangle block ; --- The main redraw loop --- ; ; First of all, handle the banner. 10vw__evRedraw LDR R14,[R10,#vw__banner] ;Load the banner address CMP R14,#0 ;Is there one defined? BEQ %f00 ;No -- skip ahead then ; --- See if we need to do this --- LDR R14,[R7,#28+16] ;Load the top coordinate CMP R14,R6 ;Is this above the line? BLT %f00 ;No -- don't bother then ; --- Render the banner's background --- MOV R0,#3 ;Get the banner colour SWI Wimp_SetColour ;Set this as the colour MOV R0,#4 ;Move the graphics cursor LDR R1,[R7,#28+0] ;Find left side of window MOV R2,R6 ;Baseline on window origin SWI OS_Plot ;Do the cursor move MOV R0,#101 ;Rectangle fill absolute LDR R1,[R7,#28+8] ;Load right side of window ADD R2,R6,#vw__banHeight ;Get the banner height SWI OS_Plot ;Do that too ; --- Now plot the banner text --- MOV R14,R13 ;Point at the stack block MOV R0,#28 ;We have an odd left side MOV R1,#0 ;Baseline is along origin LDR R2,[R10,#vw__fixedWidth] ;Load width of the banner MOV R3,#vw__banHeight ;Get the banner's height STMIA R14!,{R0-R3} ;Save the coordinates LDR R0,=&37000131 ;Get the icon flags word LDR R1,[R10,#vw__banner] ;Load the banner pointer MOV R2,#-1 ;No validation string MOV R3,#1 ;Bogus string length STMIA R14!,{R0-R3} ;Save the other bits MOV R1,R13 ;Point to the block SWI Wimp_PlotIcon ;Plot the text as an icon ; --- Now alter the graphics rectangle --- 00 ADD R14,R7,#28 ;Find the clipping rectangle LDMIA R14,{R0-R3} ;Load the rectangle out SUB R0,R0,R5 ;Convert to window coords SUB R1,R1,R6 ;This isn't terribly hard SUB R2,R2,R5 ;Just subtract origin posn SUB R3,R3,R6 ;For all the coordinates STMIA R14,{R0-R3} ;Store those in the block ; --- Plot each interesting icon --- MOV R0,#vwEvent_redraw ;Say this is a redraw event MOV R1,#0 ;Start at the beginning MOV R2,R13 ;Use my stack buffer ADD R3,R7,#28 ;Point to the clip block 00 BL vw__enum ;Get next icon ready BCC %f00 ;If no more, skip onwards BL vw__intSimple ;Do quick clipping check BLCS vw__dispatch ;Yes -- package off the event B %b00 ;Loop round for the rest ; --- Finish off the redraw loop --- 00 MOV R1,R7 ;Point at the event block BL drag_redraw ;Draw the drag box if reqd SWI Wimp_GetRectangle ;Get another rectangle CMP R0,#0 ;Is there more to do? BNE %10vw__evRedraw ;Yes -- loop back to do it ADD R13,R13,#32 ;Restore the stack pointer 90vw__evRedraw LDMFD R13!,{R0-R7,R14} ;Unstack the registers ORRS PC,R14,#C_flag ;And *claim the event* LTORG ; --- vw__evOpen --- ; ; On entry: R1 == pointer to an open-window block ; ; On exit: CS ; ; Use: Opens a viewer window. vw__evOpen ROUT STMFD R13!,{R0,R14} ;Save some registers MOV R14,#0 ;Force horizontal scroll STR R14,[R1,#20] ;To stop it looking odd BL screen_justChangedMode ;Just had a mode change? BCS %50vw__evOpen ;Yes -- handle that ; --- Just rescan the size like nice people --- BL vw__resize ;Modify the arrangement BLCS vw__setExtent ;Maybe modify the extent too BLCS vw__refresh ;If so, force a redraw BL vw__openWindow ;Whatever, open the window LDMFD R13!,{R0,R14} ;Restore the registers ORRS PC,R14,#C_flag ;And claim the event ; --- Just changed mode -- anything could have happened --- 50vw__evOpen BL vw__tWidth ;Rescan the title width BL vw__rescanSize ;Rescan the icon sizes BL vw__resize ;Rearrange the icons BL vw__setExtent ;Rework the extent BL vw__refresh ;Redraw the work area BL vw__openWindow ;And reopen the window LDMFD R13!,{R0,R14} ;Restore the registers ORRS PC,R14,#C_flag ;And claim the event LTORG ; --- vw__evClose --- ; ; On entry: R1 == pointer to block ; ; On exit: CC or CS ; ; Use: Handles a close request for a viewer, vw__evClose ROUT STMFD R13!,{R0,R14} ;Save some registers MOV R0,#vwEvent_close ;Get the event code BL vw__dispatch ;Send it to the user LDMFD R13!,{R0,PC} ;And return this state LTORG ; --- vw__evMouse --- ; ; On entry: R1 == pointer to pointer info block ; ; On exit: CS ; ; Use: Handles a mouse click on the viewer. vw__evMouse ROUT STMFD R13!,{R0-R4,R14} ;Save some registers MOV R4,R1 ;Look after this pointer LDMIA R4,{R2,R3} ;Load the coordinates out BL vw__whichIcon ;Which icon is that? LDR R2,[R4,#8] ;Load the button state TST R2,#&002 ;Is this a menu click? MOVNE R0,#vwEvent_menu ;Yes -- pass that event TST R2,#&005 ;Another normal click? MOVNE R0,#vwEvent_double ;Yes -- that's a double TST R2,#&050 ;Is it a drag? MOVNE R0,#vwEvent_drag ;Yes -- use that event then TST R2,#&500 ;Or a normal click? MOVNE R0,#vwEvent_click ;Yes -- that's a real one BL vw__dispatch ;Sent the event on LDMFD R13!,{R0-R4,R14} ;Save some registers ORRS PC,R14,#C_flag ;We dealt with it LTORG ; --- vw__evKey --- ; ; On entry: R1 == pointer to caret info block ; ; On exit: CC if unclaimed, else CS ; ; Use: Handles a keypress while the viewer has the input focus. vw__evKey ROUT STMFD R13!,{R0,R1,R14} ;Save some registers LDR R0,[R1,#24] ;Load the character code BL akbd_translate ;Try translating the key MOV R1,R0 ;Put this back in R1 MOV R0,#vwEvent_key ;Get the event code BL vw__dispatch ;Dispatch the event LDMFD R13!,{R0,R1,R14} ;Restore registers ORRCSS PC,R14,#C_flag ;Claim if he claimed it BICCCS PC,R14,#C_flag ;Don't claim if he didn't LTORG ; --- vw__mDataSave --- ; ; On entry: R0 == message code ; R1 == pointer to message block ; ; On exit: -- ; ; Use: Handles a file dropped on the viewer. vw__mDataSave ROUT STMFD R13!,{R0-R4,R14} ;Save some registers MOV R4,#vwDrop_save ;Say it's a save event ADD R3,R1,#44 ;Point to the filename LDR R2,[R1,#36] ;Load the estimated size LDR R1,[R1,#40] ;And the filetype MOV R0,#vwEvent_drop ;Get the event code BL vw__dispatch ;And send it to the client LDMFD R13!,{R0-R4,PC}^ ;And return to caller LTORG ; --- vw__mDataLoad --- ; ; On entry: R0 == message code ; R1 == pointer to message block ; ; On exit: -- ; ; Use: Handles a file dropped on the viewer. vw__mDataLoad ROUT STMFD R13!,{R0-R4,R14} ;Save some registers MOV R4,#vwDrop_load ;Say it's a load event ADD R3,R1,#44 ;Point to the filename LDR R2,[R1,#36] ;Load the estimated size LDR R1,[R1,#40] ;And the filetype MOV R0,#vwEvent_drop ;Get the event code BL vw__dispatch ;And send it to the client LDMFD R13!,{R0-R4,PC}^ ;And return to caller LTORG ; --- vw__mHelpRq --- ; ; On entry: R0 == message code ; R1 == pointer to message block ; ; On exit: -- ; ; Use: Handles a help request for the viewer. vw__mHelpRq ROUT STMFD R13!,{R0-R3,R14} ;Save some registers ADD R14,R1,#20 ;Find the mouse position LDMIA R14,{R2,R3} ;Load the coordinates BL vw__whichIcon ;Find the icon pointed at MOV R0,#vwEvent_help ;It's a help request BL vw__dispatch ;Send it to the client LDMFD R13!,{R0-R3,PC}^ ;And return to caller LTORG ; --- vw__mFontChnge --- ; ; On entry: R0 == message code ; R1 == pointer to message block ; ; On exit: -- ; ; Use: Handles font changed events for the viewer. vw__mFontChnge ROUT STMFD R13!,{R0-R4,R14} ;Save some registers SUB R13,R13,#36 ;Make a window state block LDR R14,[R10,#vw__window] ;Load viewer's window handle STR R14,[R13,#0] ;Store it in the block MOV R1,R13 ;Point to this block SWI Wimp_GetWindowState ;Read the window information BL vw__tWidth ;Rescan the title width BL vw__rescanSize ;Rescan the icon sizes BL vw__resize ;Rearrange the icons BL vw__setExtent ;Rework the extent BL vw__refresh ;Redraw the work area BL vw__openWindow ;And reopen the window ADD R13,R13,#36 ;Restore the stack pointer LDMFD R13!,{R0-R4,PC}^ ;Return to caller LTORG ;----- Icon position handling ----------------------------------------------- ; --- vw__callShape --- ; ; On entry: R0 == reason code ; R1-R? == other arguments ; R10 == pointer to viewer block ; ; On exit: R0-R? and C returned from shape function ; ; Use: Calls a shape function and returns the result. EXPORT vw__callShape vw__callShape ROUT STMFD R13!,{R8-R10,R12,R14} ;Save some registers LDR R8,[R10,#vw__shape] ;Load the shape function addr MOV R9,R10 ;Point to the viewer block ADD R14,R10,#vw__handler+4 ;Find owner's R10 and R12 LDMIA R14,{R10,R12} ;Load them out nicely too CMP R0,R0 ;Set the C flag on entry MOV R14,PC ;Set up the return address MOV PC,R8 ;Call the shape function LDMFD R13!,{R8-R10,R12,R14} ;Restore registers ORRCSS PC,R14,#C_flag ;If it set C, return C set BICCCS PC,R14,#C_flag ;Otherwise return C clear LTORG ; --- vw__whichIcon --- ; ; On entry: R2,R3 == mouse coordinates (screen relative) ; R10 == pointer to viewer block ; ; On exit: R1 == icon beneath the mouse pointer ; ; Use: Works out which icon the user is pointing at, should this be ; interesting. vw__whichIcon ROUT STMFD R13!,{R0,R2-R6,R14} ;Save lots of registers ; --- Find the window's state --- SUB R13,R13,#36 ;Drop the stack to make a blk LDR R14,[R10,#vw__window] ;Get the window handle STR R14,[R13,#0] ;Store that in the block MOV R1,R13 ;Point to the block SWI Wimp_GetWindowState ;Read the window state LDR R0,[R13,#4] ;Load the left hand side ADD R14,R13,#16 ;Point to the top edge LDMIA R14,{R4-R6} ;Load those values out SUB R5,R0,R5 ;Work out x origin position SUB R6,R4,R6 ;And the y origin position ; --- Find the click position --- SUB R2,R2,R5 ;Translate click coordinates SUB R3,R3,R6 ;Do that nicely MOV R14,R13 ;Point to my nice block STMIA R14!,{R2,R3} ;Save coordinates away STMIA R14!,{R2,R3} ;And do it again ; --- Now do the enumeration --- MOV R1,#0 ;Start at the beginning ADD R2,R13,#16 ;Point to spare bit of block MOV R3,R13 ;Point to my coordinates BL vw__withinBox ;Try to find a match MOVCC R1,#0 ;No match -- no icon ADD R13,R13,#36 ;Recover stack space LDMFD R13!,{R0,R2-R6,PC}^ ;And return to caller LTORG ; --- vw__rescanSize --- ; ; On entry: R10 == pointer to viewer block ; ; On exit: -- ; ; Use: Recalculates the sizes of icons in the viewer. vw__rescanSize ROUT STMFD R13!,{R0-R7,R14} ;Save some registers ; --- Set up for the loop --- LDR R6,[R10,#vw__listDef] ;Find the list block MOV R1,#0 ;No item found yet ADD R7,R10,#vw__stdDimens ;Find standard dimensions LDMIA R7,{R4,R5} ;These are minimum sizes ; --- Now read all the items --- 00 LDR R0,[R10,#vw__list] ;Find the list head MOV R2,#0 ;Match any flags MOV R3,#0 ;Still match any flags MOV R14,PC ;Set up return address ADD PC,R6,#vw__enumerate ;Read the next list item BCC %10vw__rescanSize ;If no more, skip on LDMIA R7,{R2,R3} ;Load standard sizes MOV R0,#vwShape_size ;Get the reason code BL vw__callShape ;And call the shape function CMP R4,R2 ;Now update the sizes MOVCC R4,R2 ;Use the biggest on both CMP R5,R3 ;Check the height too MOVCC R5,R3 ;Use the biggest again B %b00 ;Now loop round for more ; --- Finished -- store result away --- 10 ADD R14,R10,#vw__iconWidth ;Find current sizes STMIA R14,{R4,R5} ;Store these new sizes LDMFD R13!,{R0-R7,PC}^ ;And return to caller LTORG ; --- vw__intSimple --- ; ; On entry: R2 == pointer to a box ; R3 == pointer to another box ; ; On exit: CS if boxes intersect, else CC ; ; Use: Informs you whether boxes intersect. Saves lots of ; registers. This is typically used before calling the ; caller's shape routine to see if it's really worth it. EXPORT vw__intSimple vw__intSimple ROUT STMFD R13!,{R0-R6,R14} ;Save some registers LDMIA R3,{R4-R6,R14} ;Load second box out LDMIA R2,{R0-R3} ;Load first box out CMP R2,R4 ;Now do the compare CMPGE R3,R5 CMPGE R6,R0 CMPGE R14,R1 LDMFD R13!,{R0-R6,R14} ;Restore registers ORRGES PC,R14,#C_flag ;Return C set if OK BICLTS PC,R14,#C_flag ;Otherwise return CC LTORG ; --- vw__enum --- ; ; On entry: R1 == 0 for first call, or item pointer ; R2 == pointer to 16-byte coordinate buffer ; R4 == continuation value from old call ; R10 == pointer to viewer block ; ; On exit: CS if more icons, and ; R1 == item handle ; R4 == new continuation value ; else CC and ; R1,R4 corrupted ; ; Use: Scans through icons, returning their coordinates in the ; block. ; ; This routine is exported, although it isn't for user ; consumption. People using it in application code will be ; shot. EXPORT vw__enum vw__enum ROUT STMFD R13!,{R0,R2,R3,R5-R8,R14} ;Save some registers ; --- Set up for first go round --- CMP R1,#0 ;Is this the first go? BNE %05vw__enum ;No -- skip onwards then MOV R4,#0 ;Yes -- start at top left ADD R14,R10,#vw__iconWidth ;Find the icon dimensions LDMIA R14,{R7,R14} ;Load them out of the block MOV R5,#vw__iconGap ;Set up the gap nicely ADD R7,R5,R7 ;Work out right hand side MOV R8,#-vw__iconGap ;Work out top edge SUB R6,R8,R14 ;And set up the bottom STMIA R2,{R5-R8} ;Save all of those away B %10vw__enum ;Now skip on to next bit ; --- Sort out a subsequent round --- 05vw__enum LDMIA R2,{R5,R6} ;Load bottom left of icon ADD R14,R10,#vw__iconWidth ;Find the icon dimensions LDMIA R14,{R7,R8} ;Load them out of the block ADD R4,R4,#1 ;Bump horizontal position LDR R14,[R10,#vw__across] ;How many icons going across? CMP R4,R14 ;Reached the edge yet? ADDCC R5,R5,R7 ;No -- move along then ADDCC R5,R5,#vw__iconGap ;Add on our extra spacing MOVCS R5,#vw__iconGap ;Otherwise go back to left MOVCS R4,#0 ;Return left side position SUBCS R6,R6,R8 ;Drop down one row SUBCS R6,R6,#vw__iconGap ;And add on the spacing ADD R7,R5,R7 ;Work out other box position ADD R8,R6,R8 ;To make the box right STMIA R2,{R5-R8} ;Store all that away ; --- Now advance the icon pointer --- 10vw__enum LDR R0,[R10,#vw__list] ;Load the list base MOV R2,#0 ;Give me all the icons MOV R3,#0 ;I really mean that LDR R5,[R10,#vw__listDef] ;Find the list block MOV R14,PC ;Set up return address ADD PC,R5,#vw__enumerate ;Get the next item LDMFD R13!,{R0,R2,R3,R5-R8,R14} ;Unstack registers ORRCSS PC,R14,#C_flag ;If more to come, OK BICCCS PC,R14,#C_flag ;Otherwise return the end LTORG ; --- vw__withinBox --- ; ; On entry: R1 == 0 for first call, or pointer from previous ; R2 == pointer to 16-byte buffer ; R3 == pointer to coordinate box (window relative) ; R4 == value from previous call ; R10 == pointer to viewer block ; ; On exit: CS if match found, and ; R1 == item handle of match ; R4 == continuation value ; else CC and ; R1,R4 corrupted ; ; Use: Enumerates icons which intersect a given rectangle. The ; coordinates of a matching icon are left in the block; these ; must be set up correctly for the next call. vw__withinBox ROUT STMFD R13!,{R0,R14} ;Save some registers MOV R0,#vwShape_intersects ;Get shape fn reason code 00 BL vw__enum ;Get another icon BCC %10vw__withinBox ;If no more, return now BL vw__intSimple ;Check simple intersection BLCS vw__callShape ;And then the complex one BCC %b00 ;If no match, skip back LDMFD R13!,{R0,R14} ;Restore registers ORRS PC,R14,#C_flag ;And return match 10vw__withinBox LDMFD R13!,{R0,R14} ;Restore registers BICS PC,R14,#C_flag ;Return no match LTORG ; --- vw__iconBox --- ; ; On entry: R1 == item pointer ; R2 == pointer to a block to fill in ; R10 == viewer handle ; ; On exit: -- ; ; Use: Works out the bounding box of an icon (within the window). vw__iconBox ROUT STMFD R13!,{R0-R5,R14} ;Save some registers ; --- First, get the icon index --- LDR R0,[R10,#vw__list] ;Load the list head pointer LDR R5,[R10,#vw__listDef] ;Find the definition too MOV R14,PC ;Set up return address ADD PC,R5,#vw__itemToIndex ;Find the item's index ; --- Now work out its across and down position --- MOV R0,R1 ;Get the item index LDR R1,[R10,#vw__across] ;Find icons going across BL divide ;Do the division ; --- Finally find the actual position --- ADD R14,R10,#vw__iconWidth ;Point to icon dimens LDMIA R14,{R4,R5} ;Load the width and height ADD R3,R4,#vw__iconGap ;Add on the gap here ADD R14,R5,#vw__iconGap ;And again, please MUL R14,R0,R14 ;Work out vertical placing MUL R0,R1,R3 ;And the horizontal placing RSB R14,R14,#0 ;Make vertical position -ve ADD R0,R0,#vw__iconGap ;Push the icon in a little SUB R14,R14,#vw__iconGap ;And push it down a little ADD R3,R0,R4 ;Work out the right side SUB R1,R14,R5 ;And the bottom edge STMIA R2,{R0,R1,R3,R14} ;Save them in my block LDMFD R13!,{R0-R5,PC}^ ;And return to caller LTORG ;----- Default selection model ---------------------------------------------- ; --- viewer_select --- ; ; On entry: R0 == viewer handle ; R1 == icon handle ; R2 == 0 to unselect, 1 to select or 2 to toggle ; ; On exit: -- ; ; Use: Selects an icon, or maybe unselects it. Whatever, it doesn't ; flicker if it doesn't need to. EXPORT viewer_select viewer_select ROUT CMP R1,#0 ;Is there an icon? MOVEQS PC,R14 ;No -- do nothing then STMFD R13!,{R0-R5,R10,R14} ;Save some registers MOV R10,R0 ;Get the viewer block pointer ; --- Read the current flags --- LDR R4,[R10,#vw__listDef] ;Get the list definition MOV R5,R2 ;And get the argument MOV R3,#0 ;Don't toggle flags MOV R2,#0 ;Don't clear any flags LDR R0,[R10,#vw__list] ;Load the list base address MOV R14,PC ;Set up return address ADD PC,R4,#vw__setFlags ;Read the current flags ; --- Work out the new ones --- AND R2,R2,#1 ;Leave only selected flag CMP R5,#1 ;What is the operation? MOVLT R3,#0 ;Clear -- clear the flag MOVEQ R3,#1 ;Set -- set the flag EORGT R3,R2,#1 ;Toggle -- toggle the flag CMP R3,R2 ;Have we made a difference? LDMEQFD R13!,{R0-R5,R10,PC}^ ;No -- return now then ; --- Set the new flags now --- MOV R2,#1 ;Clear the selected bit MOV R14,PC ;Set up return address ADD PC,R4,#vw__setFlags ;Set the new flags MOV R0,R10 ;Get handle in R0 BL viewer_update ;Update the icon LDMFD R13!,{R0-R5,R10,PC}^ ;Return to caller LTORG ; --- viewer_isSelected --- ; ; On entry: R0 == viewer handle ; R1 == icon handle ; ; On exit: CS if icon is selected, else CC ; ; Use: Informs you whether an icon is selected. EXPORT viewer_isSelected viewer_isSelected ROUT CMP R1,#0 ;Is there an icon? BICEQS PC,R14,#C_flag ;No -- not selected then STMFD R13!,{R0-R4,R14} ;Save some registers MOV R2,#0 ;Don't clear any flags MOV R3,#0 ;Don't toggle any either LDR R4,[R0,#vw__listDef] ;Find the list block LDR R0,[R0,#vw__list] ;Find the list base MOV R14,PC ;Set up return address ADD PC,R4,#vw__setFlags ;Read the current flags TST R2,#1 ;Is it selected then? LDMFD R13!,{R0-R4,R14} ;Restore caller's registers ORRNES PC,R14,#C_flag ;If selected, return C set BICEQS PC,R14,#C_flag ;Otherwise clear C on exit LTORG ; --- viewer_selectAll --- ; ; On entry: R0 == viewer handle ; R2 == 0 to deselect, or 1 to select ; ; On exit: -- ; ; Use: Selects or deselects all the icons in a viewer. EXPORT viewer_selectAll viewer_selectAll ROUT STMFD R13!,{R0-R5,R10,R14} ;Save some registers MOV R10,R0 ;Look after the handle MOV R1,#0 ;Start at the beginning MOV R4,R2 ;Look after selection state LDR R5,[R10,#vw__listDef] ;Find the list block 00 LDR R0,[R10,#vw__list] ;Find the list head MOV R2,#1 ;Check the selected bit EOR R3,R4,#1 ;Find interesting icons MOV R14,PC ;Set up return address ADD PC,R5,#vw__enumerate ;Find next icon BCC %f00 ;If all done, skip on MOV R0,R10 ;Get viewer handle MOV R2,R4 ;Get selection state BL viewer_select ;Do the selection B %b00 ;And skip back for the rest 00 MOV R14,#0 ;Clear temporary selection STR R14,[R10,#vw__tempSel] ;Store that in the block LDMFD R13!,{R0-R5,R10,PC}^ ;Return to caller when done LTORG ; --- viewer_click --- ; ; On entry: R0 == viewer handle ; R1 == icon handle (or 0) ; R2 == mouse button state ; ; On exit: -- ; ; Use: Handles a click, drag etc. according to the standard ; selection model. EXPORT viewer_click viewer_click ROUT TST R2,#&002 ;Is this a menu click? BNE %20viewer_click ;Yes -- handle it then TST R2,#&400 ;Is this a SELECT click? BNE %10viewer_click ;Yes -- handle that TST R2,#&050 ;Is this a drag? BNE %50viewer_click ;Yes -- start a drag box TST R2,#&100 ;Is this an ADJUST click? MOVEQS PC,R14 ;No -- do nothing then ; --- Handle an ADJUST click --- STMFD R13!,{R2,R14} ;Save some registers BL viewer_clearTemp ;Clear temporary selection MOV R2,#2 ;Now select interesting icon BL viewer_select ;Do the selection op LDMFD R13!,{R2,PC}^ ;And return to caller ; --- Handle a SELECT click --- 10viewer_click STMFD R13!,{R2,R14} ;Save some registers BL viewer_clearTemp ;Clear temporary selection BL viewer_isSelected ;Is the icon selected? LDMCSFD R13!,{R2,PC}^ ;Yes -- do nothing then MOV R2,#0 ;Clear entire selection BL viewer_selectAll ;Do that then MOV R2,#1 ;Now select my icon BL viewer_select ;Go do that then LDMFD R13!,{R2,PC}^ ;And return to caller ; --- Handle a MENU click --- 20viewer_click STMFD R13!,{R0-R5,R10,R14} ;Save some registers MOV R10,R0 ;Look after the handle BL viewer_clearTemp ;Clear temporary selection MOV R4,R1 ;Look after icon handle LDR R5,[R10,#vw__listDef] ;Find the list definition LDR R0,[R10,#vw__list] ;Find the list base MOV R1,#0 ;Start at the beginning MOV R2,#1 ;Check selected bit MOV R3,#1 ;Any with it set? MOV R14,PC ;Set return address ADD PC,R5,#vw__enumerate ;Find first selected icon LDMCSFD R13!,{R0-R5,R10,PC}^ ;Robust selection -- quit now MOV R0,R10 ;Get the handle back MOV R1,R4 ;Get clicked icon MOV R2,#1 ;Select the icon BL viewer_select ;Go select it then STR R1,[R10,#vw__tempSel] ;This is temporary selection LDMFD R13!,{R0-R5,R10,PC}^ ;Return to caller ; --- Handle a drag --- 50viewer_click CMP R1,#0 ;Is there actually an icon? BNE %60viewer_click ;Yes -- handle that STMFD R13!,{R0-R5,R14} ;Save some registers MOV R4,R0 ;Pass viewer handle in R10 MOV R5,#0 ;I have no workspace LDR R0,[R4,#vw__window] ;Load the window handle MOV R1,#0 ;No flags to set ADR R2,vw__dragSel ;Point to drag handler MOV R3,#0 ;No magic number in R9 BL drag_start ;Start the drag operation LDMFD R13!,{R0-R5,PC}^ ;And return to caller ; --- Handle drag on an icon -- select it --- 60viewer_click STMFD R13!,{R2,R14} ;Save some registers MOV R2,#1 ;Select the icon BL viewer_select ;Do that then LDMFD R13!,{R2,PC}^ ;And return to caller LTORG ; --- vw__dragSel --- ; ; On entry: R0 == drag op event code ; Other registers depend on this ; ; On exit: -- ; ; Use: Handles events during a marquee-select drag operation. vw__dragSel ROUT CMP R0,#7 ;Is this a kosher event? ADDCC PC,PC,R0,LSL #2 ;Yes -- then dispatch it MOVS PC,R14 ;Otherwise ignore it B vw__dragRender ;Draw the drag box B vw__dragRender ;Undraw the drag box B vw__dragRender ;Rotate the drag box MOVS PC,R14 ;Do no coordinate conversion B vw__dragScroll ;Auto-scroll the viewer B vw__dragDone ;Completed the drag OK MOVS PC,R14 ;Drag operation cancelled ; --- Draw the drag box --- vw__dragRender STMFD R13!,{R0-R5,R14} ;Save some registers ; --- Set the colour up --- MOV R0,#1 ;Background colour is 1 MOV R1,#7 ;Make lines black, please BL drag_eorColour ;Set the colour up ; --- Now render the drag box --- SUB R4,R4,R2 ;Get the box width SUB R5,R5,R3 ;And the box height MOV R0,#4 ;Move cursor absolute ADD R1,R6,R2 ;Find the start position ADD R2,R7,R3 ;Set up the y position too SWI OS_Plot ;Move the graphics cursor MOV R0,#17 ;Relative dotted plot MOV R1,R4 ;Plot bottom line MOV R2,#0 ;Keep y constant SWI OS_Plot MOV R0,#49 ;Relative dotted plot MOV R1,#0 ;Keep x constant MOV R2,R5 ;Plot right hand side SWI OS_Plot MOV R0,#49 ;Relative dotted plot RSB R1,R4,#0 ;Plot top line MOV R2,#0 ;Keep y constant SWI OS_Plot MOV R0,#57 ;Relative dotted plot MOV R1,#0 ;Keep x constant RSB R2,R5,#0 ;Plot left hand side SWI OS_Plot ;Plot that too LDMFD R13!,{R0-R5,PC}^ ;And return to caller ; --- Scroll the window during the drag --- vw__dragScroll STMFD R13!,{R0-R3,R14} ;Save some registers BL drag_scroll ;Get the scroll position STR R3,[R1,#24] ;Save vertical scroll posn BL vw__openWindow ;Reopen the window LDMFD R13!,{R0-R3,PC}^ ;And return to caller ; --- Handle the end of the drag --- vw__dragDone STMFD R13!,{R0-R5,R14} ;Save some registers ; --- Fiddle the coordinates --- CMP R2,R4 ;Are these the right way? EORGT R2,R2,R4 ;No -- swap them round then EORGT R4,R2,R4 EORGT R2,R2,R4 CMP R3,R5 ;Are these the right way? EORGT R3,R3,R5 ;No -- swap them round then EORGT R5,R3,R5 EORGT R3,R3,R5 ; --- Now enumerate matching boxes --- STMFD R13!,{R2-R5} ;Stuff the drag box on stack SUB R13,R13,#16 ;And make another block MOV R0,R10 ;Get the viewer handle MOV R1,#0 ;Start at the beginning ADD R3,R13,#16 ;Point at the drag box 00 MOV R2,R13 ;Point to my spare block BL vw__withinBox ;Get next matching icon MOVCS R2,#1 ;Select this icon please BLCS viewer_select ;Please do that BCS %b00 ;And loop back ; --- Finished -- return --- ADD R13,R13,#32 ;Restore the stack block LDMFD R13!,{R0-R5,PC}^ ;And return to caller LTORG ; --- viewer_clearTemp --- ; ; On entry: R0 == viewer handle ; ; On exit: -- ; ; Use: Clears the temporary selection (use when you receive a ; menu closed event). viewer_clearTemp ROUT STMFD R13!,{R1,R2,R14} ;Save some registers LDR R1,[R0,#vw__tempSel] ;Find temporary selection CMP R1,#0 ;Is that defined? LDMEQFD R13!,{R1,R2,PC}^ ;No -- return now MOV R2,#0 ;Yes -- deselect the icon BL viewer_select ;Go do that then MOV R14,#0 ;And also clear temp select STR R14,[R0,#vw__tempSel] ;Store that in the block LDMFD R13!,{R1,R2,PC}^ ;Return to caller when done LTORG ; --- viewer_dragSelection --- ; ; On entry: R0 == viewer handle ; ; On exit: -- ; ; Use: Starts a drag of the icons within the viewer. When the drag ; is finished, you get sent a vwEvent_dragged event. EXPORT viewer_dragSelection viewer_dragSelection ROUT STMFD R13!,{R0-R10,R14} ;Save lots of registers MOV R10,R0 ;Look after the viewer handle LDR R9,[R10,#vw__listDef] ;Find the list definition ; --- First, see if we need DragASprite --- MOV R0,#161 ;Read CMOS locations MOV R1,#28 ;Various strange status flags SWI OS_Byte ;Do the read op TST R2,#2 ;Is the bit set? BEQ %50viewer_dragSelection ;No -- use normal Wimp box ; --- Work out what sprite to use --- ; ; We need to ask the client here. LDR R0,[R10,#vw__list] ;Load the list base pointer MOV R1,#0 ;Start at the beginning MOV R2,#1 ;Check the selected bit MOV R3,#1 ;Make sure it's on MOV R14,PC ;Set up return address ADD PC,R9,#vw__enumerate ;Read first matching item BCC %90viewer_dragSelection ;No selection -- no drag MOVCS R4,R1 ;Match -- get icon handle MOVCS R14,PC ;And set up again ADDCS PC,R9,#vw__enumerate ;Read next matching iten MOVCS R4,#-1 ;If more than one, say `many' MOV R1,R4 ;Give this to the client MOV R0,#vwEvent_sprite ;Pretend it's an event BL vw__dispatch ;And send it off nicely BCC %50viewer_dragSelection ;Told to use Wimp box ; --- Now use DragASprite nicely --- MOV R2,R1 ;Look after the name MOV R3,R0 ;And the sprite area SUB R13,R13,#20 ;Make a small block MOV R1,R13 ;Point to the block SWI Wimp_GetPointerInfo ;Read the pointer position MOV R14,R13 ;Point to the block LDMIA R14,{R0,R1} ;Load the coordinates out SUB R0,R0,#64 ;Turn into a little box SUB R1,R1,#64 ;Chop off a little bit STMIA R14!,{R0,R1} ;Store them back ADD R0,R0,#128 ;Work out the other side ADD R1,R1,#128 ;Add on quite a lot actually STMIA R14!,{R0,R1} ;Store them back MOV R0,#&C5 ;DragASprite flags MOV R1,R3 ;Get the sprite area MOV R3,R13 ;Point to my rectangle block SWI XDragASprite_Start ;Start the drag operation ADD R13,R13,#20 ;Reclaim the stack pointer BVC %70viewer_dragSelection ;If it worked, set up handler ; --- Try and do a dotted outline --- 50 SUB R13,R13,#40 ;Make a small block LDR R0,[R10,#vw__list] ;Find the list definition MOV R1,#0 ;Start at the beginning MOV R2,#1 ;Check selected bits MOV R3,#1 ;Make sure they're on MOV R14,PC ;Set up return address ADD PC,R9,#vw__enumerate ;Do the enumeration ADDCC R13,R13,#40 ;Restore stack pointer BCC %90viewer_dragSelection ;No selection -- no drag MOV R2,R13 ;Point to a block BL vw__iconBox ;Find the icon's bounding box LDMIA R2,{R4-R7} ;Load the bounding box ; --- Now work out the bounding box of selected icons --- 00 MOV R2,#1 ;Check selected bits MOV R3,#1 ;Make sure they're on MOV R14,PC ;Set up return address ADD PC,R9,#vw__enumerate ;Do the enumeration BCC %f00 ;No more -- skip onwards MOV R2,R13 ;Point to a block BL vw__iconBox ;Find the bounding box LDMIA R2,{R2,R3,R8,R14} ;Load these coordinates CMP R4,R2 MOVGT R4,R2 CMP R5,R3 MOVGT R5,R3 CMP R6,R8 MOVLT R6,R8 CMP R7,R14 MOVLT R7,R14 B %b00 ;Loop back for the rest now ; --- Translate coordinates to screen relative --- 00 MOV R1,R13 ;Point to my block SWI Wimp_GetPointerInfo ;Read the pointer position LDMIA R13,{R8,R9} ;Load the position out LDR R14,[R10,#vw__window] ;Load the window handle STR R14,[R13,#0] ;Store it in the block SWI Wimp_GetWindowState ;Read the window position LDR R0,[R13,#4] ;Load the left hand side ADD R14,R13,#16 ;Point to top edge/scroll LDMIA R14,{R1-R3} ;Load those out nicely SUB R2,R0,R2 ;Work out x origin pos SUB R3,R1,R3 ;And the y origin pos ADD R4,R4,R2 ADD R5,R5,R3 ADD R6,R6,R2 ADD R7,R7,R3 SUB R4,R4,#vw__iconGap /2 SUB R5,R5,#vw__iconGap /2 ADD R6,R6,#vw__iconGap /2 ADD R7,R7,#vw__iconGap /2 ADD R14,R13,#8 ;Point to bit of block STMIA R14,{R4-R7} ;Save the drag box position ; --- Work out the parent box position --- SUB R4,R4,R8 ;Work out min x position SUB R5,R5,R9 ;And the min y position SUB R6,R6,R8 ;Fiddle with max x SUB R7,R7,R9 ;And max y BL screen_getInfo ;Read the screen information ADD R14,R0,#screen_width ;Find the screen dimensions LDMIA R14,{R8,R9} ;Load them out nicely ADD R6,R6,R8 ;Work out max x position ADD R7,R7,R9 ;And the max y position ADD R14,R0,#screen_dx ;Get the pixel sizes LDMIA R14,{R8,R9} ;Load those out too SUB R6,R6,R8 ;Subtract a pixel off SUB R7,R7,R9 ;To make things nice ADD R14,R13,#24 ;Point to parent box area STMIA R14,{R4-R7} ;Save that lot away ; --- Start the drag (phew...) --- MOV R14,#5 ;Drag fixed sized box STR R14,[R13,#4] ;Store it in the block MOV R1,R13 ;Point to the block SWI Wimp_DragBox ;And start the drag op ADD R13,R13,#40 ;Reclaim my drag box block ; --- Set up my handler at the end of it --- 70 ADR R0,vw__dragIcn ;Point to my handler MOV R2,R10 ;Pass viewer handle in R10 MOV R3,R12 ;And workspace (?) in R12 BL win_unknownHandler ;Register that routine please 90 LDMFD R13!,{R0-R10,PC}^ ;And return to caller LTORG ; --- vw__dragIcn --- ; ; On entry: R0 == event code ; R1 == pointer to event block ; ; On exit: -- ; ; Use: Handles events during a selection drag. vw__dragIcn ROUT CMP R0,#7 ;Is it a drag end event? MOVNES PC,R14 ;Nope -- nothing to do STMFD R13!,{R0-R2,R14} ;Save some registers SWI XDragASprite_Stop ;Turn off any sprite drags SUB R13,R13,#20 ;Make a little block MOV R1,R13 ;Point to the block SWI Wimp_GetPointerInfo ;Read the pointer position ADD R14,R1,#12 ;Point to window handle LDMIA R14,{R1,R2} ;Load window and icon ADD R13,R13,#20 ;Restore stack block MOV R0,#vwEvent_dragged ;Get the event code BL vw__dispatch ;Send it the event LDMFD R13!,{R0-R2,PC}^ ;And return to caller LTORG ;----- Miscellaneous -------------------------------------------------------- ; --- viewer_window --- ; ; On entry: R0 == viewer handle ; ; On exit: R0 == window handle ; ; Use: Returns the window handle of the viewer. EXPORT viewer_window viewer_window ROUT LDR R0,[R0,#vw__window] ;Load the window handle MOVS PC,R14 ;And return to caller LTORG ; --- viewer_update --- ; ; On entry: R0 == viewer handle ; R1 == icon handle ; ; On exit: -- ; ; Use: Updates (redraws) a given icon. EXPORT viewer_update viewer_update ROUT STMFD R13!,{R2,R14} ;Save some registers MOV R2,#vwEvent_redraw ;Normal is redraw event BL vw__doUpdate ;Go and do the update LDMFD R13!,{R2,PC}^ ;And return to caller LTORG ; --- vw__doUpdate --- ; ; On entry: R0 == viewer handle ; R1 == icon handle ; R2 == event code to send ; ; On exit: -- ; ; Use: Updates an item, passing a given event to the client. This ; is purely for the use of gallery ;-) EXPORT vw__doUpdate vw__doUpdate ROUT STMFD R13!,{R0-R7,R10,R14} ;Save some registers MOV R10,R0 ;Get the viewer handle in R10 MOV R7,R2 ;Find the event code ; --- Start the update job --- SUB R13,R13,#32+44 ;Make a rectangle block MOV R2,R13 ;Point to space for box BL vw__iconBox ;Find the icon's box LDMIA R2,{R2-R5} ;Load the box coordinates ADD R14,R13,#32+4 ;Find the update block STMIA R14,{R2-R5} ;Store the rectangle there LDR R14,[R10,#vw__window] ;Load the window handle STR R14,[R13,#32+0] ;Store in my nice block MOV R4,R1 ;Look after icon handle ADD R1,R13,#32 ;Point to update block SWI Wimp_UpdateWindow ;Start the update job CMP R0,#0 ;Anything to do? BEQ %90vw__doUpdate ;No -- skip to end then ; --- Read the window origin --- LDR R2,[R13,#32+4] ;Load the left hand side ADD R14,R13,#32+16 ;Find top and scroll offsets LDMIA R14,{R3,R5,R6} ;Load those out too SUB R6,R3,R6 ;Find the y origin position SUB R5,R2,R5 ;And the x origin position ; --- Now embark on the main loop --- 00 ADD R14,R13,#32+28 ;Point to graphics rectangle LDMIA R14,{R0-R3} ;Load that out SUB R0,R0,R5 ;Adjust the block by origin SUB R1,R1,R6 ;This is just to keep the SUB R2,R2,R5 ;User's event handler happy SUB R3,R3,R6 ;I know what needs to be done STMIA R14,{R0-R3} ;Store that lot back MOV R0,R7 ;Get the redraw event ready MOV R1,R4 ;Point to the item MOV R2,R13 ;Point to his icon block ADD R3,R13,#32+28 ;Point to clipping block BL vw__dispatch ;Send to the handler ; --- Do any other bits of drawing --- ADD R1,R13,#32 ;Point to update block CMP R7,#vwEvent_draw ;Gallery redraw event? (yuk) BLEQ drag_redraw ;Yes -- update drag rectangle SWI Wimp_GetRectangle ;Do that rectangle CMP R0,#0 ;Any more to do? BNE %b00 ;Yes -- do it then ; --- Wrap up and return --- 90 ADD R13,R13,#32+44 ;Restore the stack LDMFD R13!,{R0-R7,R10,PC}^ ;And return to caller LTORG ; --- viewer_setTitle --- ; ; On entry: R0 == viewer handle ; R1 == title string ; ; On exit: -- ; ; Use: Sets the viewer window's title. EXPORT viewer_setTitle viewer_setTitle ROUT STMFD R13!,{R0-R2,R10,R14} ;Save some registers MOV R10,R0 ;Get the viewer handle LDR R2,[R10,#vw__window] ;Load the window handle MOV R0,R1 ;Get the string to set ADD R1,R10,#vw__title ;Point to title bar buffer BL winUtils_setTitle ;Do the title setting BL vw__open ;Is the window open? LDMCCFD R13!,{R0-R2,R10,PC}^ ;No -- do nothing then SUB R13,R13,#36 ;Make a window state block LDR R14,[R10,#vw__window] ;Load the window handle STR R14,[R13,#0] ;Store it in the block MOV R1,R13 ;Point to the block SWI Wimp_GetWindowState ;Read the current position BL vw__tWidth ;Yes -- reset the width BL vw__setExtent ;And reset the extent BL vw__openWindow ;Open the window, in case ADD R13,R13,#36 ;And reset the stack pointer LDMFD R13!,{R0-R2,R10,PC}^ ;And return to caller LTORG ; --- vw__open --- ; ; On entry: R10 == pointer to viewer block ; ; On exit: CS if window is open, else CC ; ; Use: Sees if a viewer window is currently open. vw__open ROUT STMFD R13!,{R0,R1,R14} ;Save some registers SUB R13,R13,#36 ;Make some space LDR R14,[R10,#vw__window] ;Load the window handle STR R14,[R13,#0] ;Save it in the block MOV R1,R13 ;Point to the block SWI Wimp_GetWindowState ;Read the information LDR R14,[R13,#32] ;Load the flags word TST R14,#1<<16 ;Is the window open? ADD R13,R13,#36 ;Reclaim the stack space LDMFD R13!,{R0,R1,R14} ;Restore registers ORRNES PC,R14,#C_flag ;Return with C set if so BICEQS PC,R14,#C_flag ;Otherwise clear C LTORG ; --- vw__openWindow --- ; ; On entry: R1 == pointer to window state block ; R10 == pointer to viewer block ; ; On exit: R0 corrupted (just like Wimp_OpenWindow) ; ; Use: Opens a viewer window, and informs the user through the ; vwEvent_open event. vw__openWindow ROUT SWI Wimp_OpenWindow ;Reopen the window as ordered MOV R0,#vwEvent_open ;Send the event along nicely B vw__dispatch ;And report, and return LTORG ; --- vw__tWidth --- ; ; On entry: R10 == pointer to viewer block ; ; On exit: -- ; ; Use: Updates the window's fixed width parameter. vw__tWidth ROUT STMFD R13!,{R0,R1,R14} ;Save some registers ADD R0,R10,#vw__title ;Point to title buffer BL wimp_strWidth ;Get the string width ADD R1,R0,#vw__titleAdd ;Add on a fudge factor LDR R0,[R10,#vw__banner] ;Load the banner address CMP R0,#0 ;Is the banner there? BLNE wimp_strWidth ;Yes -- get its width ADDNE R0,R0,#vw__banAdd ;And add on its fudge CMP R1,R0 ;Which is bigger? MOVCC R1,R0 ;Use the biggest one STR R1,[R10,#vw__fixedWidth] ;Store the new width LDMFD R13!,{R0,R1,PC}^ ;And return to caller LTORG ; --- viewer_rescan --- ; ; On entry: R0 == viewer handle ; ; On exit: -- ; ; Use: Rescans all the icons in the viewer and forces a redraw, ; in case icons have been added or deleted (or renamed). Note ; that the redraw is done *anyway* -- it's your responsibility ; to avoid calling this routine when you don't need to. EXPORT viewer_rescan viewer_rescan ROUT STMFD R13!,{R0,R1,R10,R14} ;Save some registers MOV R10,R0 ;Get the viewer handle BL vw__open ;Is the window open at all? LDMCCFD R13!,{R0,R1,R10,PC}^ ;No -- handle on open then SUB R13,R13,#36 ;Make a window state block LDR R14,[R10,#vw__window] ;Load the window handle STR R14,[R13,#0] ;Save it in the block MOV R1,R13 ;Point to the block SWI Wimp_GetWindowState ;And read the window state ; --- Open the window onto the screen --- LDR R1,[R10,#vw__listDef] ;Find the list definition LDR R0,[R10,#vw__list] ;And the list base MOV R14,PC ;Set up return address ADD PC,R1,#vw__items ;Find how many items STR R1,[R10,#vw__icons] ;Store this away MOV R1,R13 ;Point at window state blk BL vw__rescanSize ;Rescan the item size BL vw__extend ;Yes -- make it big then BL vw__resize ;Work out new arrangement BL vw__setExtent ;Set the window's extent BL vw__refresh ;Force update of display BL vw__openWindow ;And open the window ADD R13,R13,#36 ;Reclaim my stack space LDMFD R13!,{R0,R1,R10,PC}^ ;And return to caller LTORG ;----- Icon rearrangement routines ------------------------------------------ ; --- vw__resize --- ; ; On entry: R1 == pointer to window state block ; R10 == pointer to viewer block ; ; On exit: CS if the size has changed, else CC ; ; Use: Updates the icon arrangement within a window, returning ; whether the arrangement is different now. Note that this ; doesn't redraw the window; it just recaches the extent. ; If the size has changed, you'll probably need to call ; vw__setExtent and vw__refresh to get everything looking nice. vw__resize ROUT STMFD R13!,{R0-R3,R14} ;Save some registers ; --- Now work out how many icons we should have --- LDMIB R1,{R1-R3} ;Load the x coords from win SUB R0,R3,R1 ;Work out the window width SUB R0,R0,#vw__iconGap ;Subtract off extra border LDR R2,[R10,#vw__iconWidth] ;Load the icon width out ADD R1,R2,#vw__iconGap ;Add on the gap BL divide ;Divide one by the other MOV R3,R0 ;Icons which fit across win BL screen_getInfo ;Find the screen information LDR R0,[R0,#screen_width] ;Load the screen width SUB R0,R0,#40+vw__iconGap ;Fudge for scroll bar ADD R1,R2,#vw__iconGap ;Get icon width+gap again BL divide ;Divide one by the other MOV R2,R0 ;Icons which fit across scrn ; --- Fiddle these numbers appropriately --- LDR R0,[R10,#vw__icons] ;Load number of icons CMP R3,R0 ;Too many across window? MOVCS R3,R0 ;Yes -- use number we have CMP R2,R0 ;Too many across screen? MOVCS R2,R0 ;Yes -- use number we have CMP R2,R3 ;More than fit across screen? MOVCS R2,R3 ;Use -- use that then (erk) CMP R2,#0 ;No icons at all? MOVEQ R2,#1 ;Then have at least one ; --- Work out how many go down --- MOV R1,R2 ;Get number going across BL divide ;Do the division CMP R1,#0 ;Any extra ones on bottom? ADDNE R0,R0,#1 ;Yes -- add an extra row MOVS R3,R0 ;Look after this value MOVEQ R3,#0 ;If it's zero, use one ; --- Now see if anything's changed --- ADD R14,R10,#vw__across ;Find old across counter LDMIA R14,{R0,R1} ;Load across and down values CMP R0,R2 ;Compare with old ones CMPEQ R1,R3 ;Are they the same? STMNEIA R14,{R2,R3} ;If not, store new ones LDMFD R13!,{R0-R3,R14} ;Restore caller's registers ORRNES PC,R14,#C_flag ;If changed, return C set BICEQS PC,R14,#C_flag ;Otherwise return C clear LTORG ; --- vw__setExtent --- ; ; On entry: R10 == pointer to viewer block ; ; On exit: -- ; ; Use: Resets the extent of a viewer window, in case the ; arrangement of icons or banner/title text has changed. ; If the window is currently open, you should follow this ; call with a Wimp_OpenWindow SWI. vw__setExtent ROUT STMFD R13!,{R0-R3,R14} ;Save some registers ; --- Work out correct horizontal extent --- BL screen_getInfo ;Find the screen information LDR R0,[R0,#screen_width] ;Load the screen width SUB R0,R0,#40+vw__iconGap ;Fudge for scroll bar MOV R2,R0 ;Look after this value LDR R3,[R10,#vw__iconWidth] ;Load the icon width ADD R3,R3,#vw__iconGap ;Add on the inter-icon gap MOV R1,R3 ;Divide by this BL divide ;Divide one by the other LDR R14,[R10,#vw__icons] ;Load the number of icons CMP R0,R14 ;Is this bigger? MOVCS R0,R14 ;Yes -- then use that CMP R0,#0 ;Unless there's none MOVEQ R0,#1 ;In which case use one MUL R2,R3,R0 ;Work out the correct width ADD R2,R2,#vw__iconGap ;Add on extra border around LDR R14,[R10,#vw__fixedWidth] ;Load width of title/banner CMP R2,R14 ;Do we have enough here? MOVCC R2,R14 ;No -- then use more ; --- And now the vertical extent --- LDR R1,[R10,#vw__iconHeight] ;Load the icon height ADD R1,R1,#vw__iconGap ;Add on the gap LDR R14,[R10,#vw__down] ;Load vertical number of icns MUL R1,R14,R1 ;Work out the size ADD R1,R1,#vw__iconGap ;Add on extra border ; --- Work out the other two --- RSB R1,R1,#0 ;And vertical extent -ve LDR R3,[R10,#vw__banner] ;Load banner pointer CMP R3,#0 ;Do we have a banner? MOVNE R3,#vw__banHeight ;Yes -- then add above origin MOV R0,#0 ;Start at the left side ; --- Make sure the extent is big enough --- SUBS R14,R2,#vw__minWidth ;Get the minimum width SUBCC R2,R2,R14 ;Make bigger if needs be SUB R14,R3,R1 ;Work out extent height SUBS R14,R14,#vw__minHeight ;Get the minimum height ADDCC R1,R1,R14 ;Make bigger if needs be ; --- Finally set up the extent --- ADD R14,R10,#vw__extent ;Set the window extent STMIA R14,{R0-R3} ;Save the values in there LDR R0,[R10,#vw__window] ;Load the window handle ADD R1,R10,#vw__extent ;Point to the extent block SWI Wimp_SetExtent ;Set the window's extent LDMFD R13!,{R0-R3,PC}^ ;And return to caller LTORG ; --- vw__refresh --- ; ; On entry: R10 == pointer to a viewer block ; ; On exit: -- ; ; Use: Forces a redraw of the contents of a viewer. Use in ; conjunction with vw__resize. vw__refresh ROUT STMFD R13!,{R0-R4,R14} ;Save some registers LDR R0,[R10,#vw__window] ;Load the window handle MOV R1,#-&FFFFFFF ;Force a redraw of the world MOV R2,#-&FFFFFFF ;This hack prevents problems MOV R3,#&FFFFFFF ;with the extent being bodged MOV R4,#&FFFFFFF ;by the Wimp. SWI Wimp_ForceRedraw ;Redraw the whole lot LDMFD R13!,{R0-R4,PC}^ ;And return to caller LTORG ; --- vw__extend --- ; ; On entry: R1 == pointer to window open block ; R10 == pointer to a viewer block ; ; On exit: -- ; ; Use: Extends the viewer window if necessary to accomodate new ; items. The new coordinates to open are written back to the ; window open block. Correct procedure for adding items is ; as follows: ; ; 1. Get window state ; 2. Call vw__extend ; 3. Call vw__resize ; 4. Call vw__setExtent ; 5. Call vw__refresh vw__extend ROUT STMFD R13!,{R0-R8,R14} ;Save some registers ; --- Load current and maximum width and height --- MOV R8,R1 ;Look after this address LDMIB R8,{R4-R7} ;Load the window dimensions SUB R6,R6,R4 ;Find the window width SUB R7,R7,R5 ;And its height ADD R14,R10,#vw__extent ;Find the current extent LDMIA R14,{R0-R3} ;Load the dimensions out SUB R4,R2,R0 ;Find the maximum width SUB R5,R3,R1 ;And the maximum height LDR R14,[R10,#vw__flags] ;Load the flags word TST R14,#vwFlag__opened ;Has viewer ever been opened? BNE %f00 ;Yes -- skip onwards ; --- Set up special values for first time --- MOV R4,#0 ;No -- force width to max MOV R5,#0 ;And height forced to max LDR R6,[R10,#vw__fixedWidth] ;Set a default width though CMP R6,#vw__minWidth ;Get the minimum width MOVCC R6,#vw__minWidth ;If too small, use this MOV R7,#vw__minHeight ;Use the minimum height too ; --- Find out if we have anything to do horizontally --- ; ; We only try to extend if the window is currently as wide ; as it will go. 00 CMP R6,R4 ;Does the width shape up? BCC %50vw__extend ;No -- skip to vertical ; --- Extend the width --- ; ; We ensure that the width of the window is the smaller ; of the maximum width we allow and the width of the number ; of icons in the window. MOV R0,#vw__maxWidth ;Get the maximum width LDR R3,[R10,#vw__iconWidth] ;Find the icon width ADD R3,R3,#vw__iconGap ;And add on the gap as usual MOV R1,R3 ;Divide by this BL divide ;Divide one by the other LDR R1,[R10,#vw__icons] ;Load total number of icns CMP R0,R1 ;Which one is bigger? MOVCS R0,R1 ;Use the smaller CMP R0,#0 ;Are there no icons at all? MOVEQ R0,#1 ;None -- make space for one MUL R0,R3,R0 ;Work out new improved width ADD R0,R0,#vw__iconGap ;Add on the extra border CMP R6,R0 ;Which is bigger? MOVCC R6,R0 ;Use the bigger of the two ; --- Now do things vertically --- ; ; This is basically the same. We only extend if the window ; is as tall at it will go. 50vw__extend CMP R7,R5 ;Does the height shape up? BCC %90vw__extend ;No -- skip on then ; --- Extend the height --- ; ; This is trickier, because we have to work out how many ; icons there will be vertically. LDR R3,[R10,#vw__iconHeight] ;Load the icon height ADD R3,R3,#vw__iconGap ;Add on the inter-icon gap SUB R0,R6,#vw__iconGap ;Get the current width LDR R1,[R10,#vw__iconWidth] ;Find the icon width ADD R1,R1,#vw__iconGap ;And add on the gap as usual BL divide ;Find how many will fit MOV R1,R0 ;We will divide by this LDR R0,[R10,#vw__icons] ;Load the number of icons BL divide ;Work out number down CMP R1,#0 ;Is there a remainder? ADDNE R0,R0,#1 ;Yes -- extra one then CMP R0,#0 ;Are there no icons? MOVEQ R0,#1 ;None -- make space for one MOV R2,R0 ;Look after this value MOV R0,#vw__maxHeight ;Get the maximum height MOV R1,R3 ;And the icon height BL divide ;Do the division again CMP R0,R2 ;Which one is bigger? MOVCS R0,R2 ;Use the smaller MUL R0,R3,R0 ;Work out new improved height ADD R0,R0,#vw__iconGap ;Add on the extra border LDR R14,[R10,#vw__banner] ;Do we have a banner string? CMP R14,#0 ;Quick check for that... ADDNE R0,R0,#vw__banHeight ;Yes -- add that on too CMP R7,R0 ;Which is bigger? MOVCC R7,R0 ;Use the bigger ; --- Now update the window block --- 90vw__extend LDMIB R8,{R0-R3} ;Load the current values ADD R2,R0,R6 ;Work out new right side SUBS R1,R3,R7 ;And the new bottom SUBLT R3,R3,R1 ;Move the top if hit bottom SUBLT R1,R1,R1 ;And move the bottom too STMIB R8,{R0-R3} ;Save that lot back again LDMFD R13!,{R0-R8,PC}^ ;And return to caller LTORG ;----- Viewer block structure ----------------------------------------------- ; ; This is shadowed by gallery.s -- keep them in step. ^ 0 ; --- Information about the window --- vw__window # 4 ;Window handle vw__extent # 16 ;Current window extent vw__flags # 4 ;Any flags of interest vw__list # 4 ;Pointer to list head vw__listDef # 4 ;Pointer to list handler vw__handler # 12 ;Viewer's event handler gl__handler # 4 ;Gallery's event handler vw__shape # 4 ;Shape handler function vw__banner # 4 ;Pointer to banner string vw__fixedWidth # 4 ;Width of banner/title ; --- Icon sizing information --- vw__icons # 4 ;Cache number of icons vw__stdDimens # 8 ;`Standard' width and height vw__iconWidth # 4 ;Width of icons currently vw__iconHeight # 4 ;Height of icons currently vw__across # 4 ;Number of icons across vw__down # 4 ;Number of icons down ; --- Data for default selection model --- vw__tempSel # 4 ;Temporary selected icon ; --- Big buffers at the end --- vw__title # 256 ;Title bar buffer vw__size # 0 ;Size of a viewer block ; --- Flags bits --- ; ; Gallery `borrows' top-end flags bits here vwFlag__opened EQU (1<<0) ;Has the window been opened? ;----- Constants ------------------------------------------------------------ vw__iconGap EQU 16 ;Gap between icons vw__banHeight EQU 48 ;Height of viewer banner vw__minWidth EQU 380 ;Minimum width for a viewer vw__minHeight EQU 160 ;Minimum height vw__titleAdd EQU 164 ;Fudge factor to add to title vw__banAdd EQU 64 ;Fudge factor for the banner vw__maxWidth EQU 900-vw__iconGap ;Maximum width of a viewer vw__maxHeight EQU 700-vw__iconGap ;Maximum height of a viewer ;----- List definition format ----------------------------------------------- ^ 0 vw__itemToIndex # 4 ;Item to index routine ;Entry: R0 == pointer to list ; R1 == pointer to item ;Exit: R1 == index, or -1 vw__indexToItem # 4 ;Index to item routine ;Entry: R0 == pointer to list ; R1 == index of item ;Exit: R1 == item ptr, or 0 vw__enumerate # 4 ;Enumeration function ;Entry: R0 == list pointer ; R1 == item, or 0 ; R2 == BIC mask ; R3 == test mask ;Exit: CS if match, and ; R1 == item ptr vw__items # 4 ;Function to return items ;Entry: R0 == list pointer ;Exit: R1 == number of items vw__setFlags # 4 ;Function to set/read flags ;Entry: R1 == pointer to item ; R2 == BIC mask ; R3 == EOR mask ;Exit: R2 == new flags ;----- Shape function reason codes ------------------------------------------ ^ 0 vwShape_size # 1 ;Read an icon's size ;Entry: R1 == list item ; R2,R3 == std size ;Exit: R2,R3 == actual size vwShape_intersects # 1 ;Does icon intersect box? ;Entry: R1 == list item ; R2 == ptr to icon box ; R3 == ptr to box ;Exit: CS if intersect vwShape_slowBit # 1 ;Does slow bit need redraw? ;Entry: R1 == list item ; R2 == ptr to icon box ; R3 == ptr to box ;Exit: CS if intersect ;----- Viewer event codes --------------------------------------------------- ^ 0 vwEvent_close # 1 ;User has closed the window vwEvent_click # 1 ;User has clicked an icon ;R1 == icon handle (or 0) ;R2 == mouse status vwEvent_double # 1 ;User has double-clicked ;R1 == icon handle (or 0) ;R2 == mouse status vwEvent_drag # 1 ;User has dragged the mouse ;R1 == icon handle (or 0) ;R2 == mouse status vwEvent_menu # 1 ;User has clicked menu ;R1 == icon handle (or 0) ;R2 == mouse status vwEvent_redraw # 1 ;Redraw a viewer icon ;R1 == icon handle ;R2 == pointer to coords blk ;R3 == pointer to clip blk ;R5,R6 == window origin vwEvent_drop # 1 ;File dropped on the viewer ;R1 == filetype of data ;R2 == estimated size ;R3 == address of filename ;R4 == drop type vwEvent_help # 1 ;Help request for the viewer ;R1 == icon handle, or 0 vwEvent_key # 1 ;Key pressed ;R1 == key code (translated) ;Return CS if used, else CC vwEvent_dragged # 1 ;Icons dropped on a window ;R1 == destination window ;R2 == destination icon vwEvent_sprite # 1 ;Return sprite name to use ;Entry: R1 == icon handle ; (-1 for many) ;Exit: CS if sprite found, ; R0 == ptr to spr area ; R1 == pointer to name ; else CC vwEvent_open # 1 ;The viewer has been moved ;R1 == ptr to open/state blk vwEvent_draw # 1 ;Slowly redraw icon ;R1 == icon handle ;R2 == pointer to coords blk ;R3 == pointer to clip blk ;R5,R6 == window origin ;(Event only used by gallery) vwEvent_unDraw # 1 ;Undraw temporary part ;R1 == icon handle ;R2 == pointer to coords blk ;R3 == pointer to clip blk ;R5,R6 == window origin ;(Event only used by gallery) ; --- Drop event subreason codes --- ^ 0 vwDrop_save # 1 ;File from another app vwDrop_load # 1 ;File from filing system ;----- That's all, folks ---------------------------------------------------- END