; ; writable.s ; ; Writable dialogue boxes (MDW) ; ; © 1994-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 ;----- External dependencies ------------------------------------------------ GET sapphire:dbox GET sapphire:fastMove GET sapphire:msgs GET sapphire:sapphire GET sapphire:string ;----- Main code ------------------------------------------------------------ AREA |Sapphire$$Code|,CODE,READONLY ; --- writable --- ; ; On entry: R0 == pointer to writable dialogue block ; R1 == pointer to default string to display, or 0 for null ; R2 == pointer to routine to call when string set ; R3 == value to pass to routine in R10 ; R4 == value to pass to routine in R12 ; ; On exit: R0 == dialogue handle of created dialogue box ; May return an error ; ; Use: Displays a writable dialogue box, i.e. one with a writable ; icon and OK button, used instead of writable menu items, ; for reasons to do with caret blinking and pointer changing. ; ; The writable dialogue block consists of: ; ; Size Meaning ; ~~~~ ~~~~~~~ ; 4 Flags (see below) ; n Validation string to use, may be null ; m Title string (message tag) to display ; ; The flags are: ; ; Bit Meaning ; ~~~ ~~~~~~~ ; 0-7 Maximum string length ; 8 Right align text in writable icon ; 9-31 Reserved; must be 0 ; ; The routine returns a dialogue handle because you may want ; to attach a numWrite control to the writable icon, which ; is icon number 0. ; ; The handler routine is passed: ; ; R0 == pointer to string typed in ; R1 == dialogue box handle (for numWrite again) ; R10, R12 as set up here ; ; It must preserve all registers. If the carry flag is set ; on exit, the dialogue box will not be closed. If it is ; clear, the dialogue may be closed depending on the button ; status. ; ; Note that this routine does *not* require a template -- ; a suitable window is generated at run-time. EXPORT writable writable ROUT STMFD R13!,{R1-R3,R12,R14} ;Save some registers away WSPACE wrt__wSpace ;Find my workspace pointer ; --- Save the handler information --- ADR R14,wrt__proc ;Point to the handler stuff STMIA R14,{R2-R4} ;Save the handler info away MOV R3,R0 ;Keep the description block ; --- Save the default string away --- ADR R0,wrt__buffer ;Point to writable buffer CMP R1,#0 ;Is there a default string? STREQB R1,[R0,#0] ;No -- save a null string BLNE str_cpy ;Otherwise copy the string ; --- Set up the dialogue box sizes --- LDR R1,[R3,#0] ;Load the string length/flags AND R0,R1,#&FF ;Just get the bottom byte ADD R0,R0,#1 ;Allow for the terminator STR R0,wrt__dbDef+wOff__writeData+8 CMP R0,#41 ;Is the string really big? MOVGT R0,#41 ;Yes -- make it sane at least MOV R0,R0,LSL #4 ;Multiply up to pixels ADD R0,R0,#106 ;Get the left of the icon RSB R0,R0,#0 ;And make it negative STR R0,wrt__dbDef+wOff__writeBox SUB R0,R0,#24 ;Get left side of the window STR R0,wrt__dbDef+wOff__open STR R0,wrt__dbDef+wOff__extent ; --- Fix up string alignment --- LDR R14,wrt__dbDef+wOff__writeFlag TST R1,#wrtFlag_rAlign ;Do we right align text? ORRNE R14,R14,#&200 ;Yes -- set the bit then BICEQ R14,R14,#&200 ;No -- clear it instead STR R14,wrt__dbDef+wOff__writeFlag ; --- Fill in the validation string --- ADR R0,wrt__valid ;Point to validation buffer ADR R1,wrt__x7 ;Point to base validation BL str_cpy ;Copy it onto the end ADD R1,R3,#4 ;Point to validation string LDRB R14,[R1],#1 ;Load the first byte CMP R14,#32 ;Is this an empty string? BLO %20writable ;Yes -- miss this bit out MOV R2,#';' ;Put a delimiter string in STRB R2,[R0],#1 ;Save in validation buffer 10writable STRB R14,[R0],#1 ;Save the valid character LDRB R14,[R1],#1 ;Load another byte CMP R14,#32 ;Is this the string end? BHS %10writable ;No -- go round again MOV R14,#0 ;Null terminate nicely STRB R14,[R0],#1 ;Save it in the buffer ; --- Finally, fill in the title string --- 20writable MOV R0,R1 ;Point to title message tag BL msgs_lookup ;Find the message string MOV R1,R0 ;Point to the message ADR R0,wrt__title ;Point to the title buffer BL str_cpy ;And copy that over nicely ; --- Build the dialogue box --- ADR R0,wrt__dbDef ;Point to the dialogue defn BL dbox_fromDefn ;Create a dialogue box BVS %90writable ;Return if it failed ADR R1,wrt__handler ;Point to the handler MOV R2,R0 ;Pass dialogue handle in R10 MOV R3,R12 ;Pass workspace in R12 BL dbox_eventHandler ;Set up the event handler MOV R1,#dbOpen_pointer+dbOpen_trans BL dbox_open ;Display the dialogue box LDMFD R13!,{R1-R3,R12,R14} ;Restore all the registers BICS PC,R14,#V_flag ;Return without an error ; --- Couldn't create the dialogue box --- 90writable LDMFD R13!,{R1-R3,R12,R14} ;Restore all the registers ORRS PC,R14,#V_flag ;Return the error pointer wrt__x7 DCB "x7",0 ;Tim's neat writable border LTORG ; --- wrt__handler --- ; ; On entry: R0 == dialogue box event code ; R1-R7 == depend on the event type ; R10 == dialogue box handle ; R12 == pointer to my workspace ; ; On exit: -- ; ; Use: Handles events for the writable dialogue box. wrt__handler ROUT CMP R0,#dbEvent_close ;Someone closed my dialogue? BEQ %10wrt__handler ;Yes -- destroy it then CMP R0,#dbEvent_OK ;Is it an OK click? CMPNE R0,#wrtIcon__ok ;Or a click on the OK button? MOVNES PC,R14 ;No -- then return to caller ; --- Handle an OK click --- STMFD R13!,{R0-R3,R10,R12,R14} ;Save loads of registers MOV R2,R1 ;Look after the button state MOV R0,R10 ;Get the dialogue handle MOV R1,#wrtIcon__ok ;And the OK button handle BL dbox_slab ;Slab the button in ; --- Call the user's handler --- ADR R0,wrt__buffer ;Point to the string MOV R1,R10 ;Get the dialogue box handle ADR R14,wrt__proc ;Find his event handler LDMIA R14,{R3,R10,R12} ;Load all the handler stuff ADDS R0,R0,#0 ;Clear C flag cunningly MOV R14,PC ;Set up return address MOV PC,R3 ;And call the handler ; --- Find out what to do next --- TSTCS R2,#0 ;Set Z flag if carry set TSTCC R2,#1 ;Otherwise, test Adjustness MOV R0,R1 ;Get the dialogue handle BLEQ dbox_close ;If Select then close dbox BL dbox_unslab ;Unslab the OK button BLEQ dbox_destroy ;If Select then trash dbox LDMFD R13!,{R0-R3,R10,R12,PC}^ ;And return to caller ; --- The dialogue box closed --- 10wrt__handler STMFD R13!,{R0,R14} ;Save some registers MOV R0,R10 ;Get the dialogue handle BL dbox_destroy ;Kill the dialogue box LDMFD R13!,{R0,PC}^ ;Return to caller LTORG ; --- wrt_init --- ; ; On entry: -- ; ; On exit: -- ; ; Use: Initialises the writable dialogue box for use. EXPORT wrt_init wrt_init ROUT STMFD R13!,{R12,R14} ;Save some registers WSPACE wrt__wSpace ;Load my workspace pointer LDR R14,wrt__flags ;Load the flags word nicely TST R14,#wFlag__inited ;Have we done this already? LDMNEFD R13!,{R12,PC}^ ;Yes -- return to caller ; --- Set up the flags nicely --- STMFD R13!,{R0-R2} ;Save some more registers ORR R14,R14,#wFlag__inited ;Set the initialised flag STR R14,wrt__flags ;Save the flags back again BL dbox_init ;Make sure dboxes are going ; --- Now copy the window definition over --- ADR R0,wrt__dbDef ;Point to the workspace block ADR R1,wrt__window ;Point to the window def MOV R2,#wrt__windSize ;Get the size of the block BL fastMove ;Copy the block over nicely ; --- Fill in bits of the window definition --- ADR R14,wrt__title ;Point to the title buffer STR R14,[R0,#wOff__titleData] ADR R14,wrt__buffer STR R14,[R0,#wOff__writeData] ADR R14,wrt__valid STR R14,[R0,#wOff__writeData+4] LDMFD R13!,{R0-R2,R12,PC}^ ;Return to caller LTORG wrt__wSpace DCD 0 ;----- Constants ------------------------------------------------------------ ; --- Icon numbers --- wrtIcon__write EQU 0 ;The writable icon wrtIcon__ok EQU 1 ;The OK button ; --- Flags --- wrtFlag_rAlign EQU (1<<8) ;Align text to right side ;----- Window definition ---------------------------------------------------- ; --- Note --- ; ; The main window definition here gets copied into workspace so that I can ; modify it nicely at runtime, to change the width of the window etc. ; --- Macro: WOFF --- ; ; Arguments: label == symbol to assign with current offset into window def ; ; Use: Sets a symbol to an offset in the window definition MACRO $label WOFF $label EQU {PC}-wrt__window MEND ; --- The main window block --- wrt__window wOff__open WOFF DCD -324,-96,0,0 ;Width dynamically adjusted DCD 0,0 ;Window doesn't scroll (hope) DCD -1 ;Always open on the top DCD &84170002 ;Window flags word (various) DCB 7,2,7,1,3,1,2,0 ;Window colours words wOff__extent WOFF DCD -324,-96,0,0 ;Dynamically adjust width DCD &00000109 ;Window title bar flags DCD &00000000 ;Work area button type DCD 1 ;Wimp sprite area, I think DCD 0 ;Default minimum sizes wOff__titleData WOFF DCD 0,-1,24 ;Title bar icon data DCD 2 ;2 icons following ; --- The writable area icon --- wOff__writeBox WOFF DCD -300,-68,-110,-28 ;24 in from the left wOff__writeFlag WOFF DCD &0700F131 ;Icon flags word wOff__writeData WOFF DCD 0,0,0 ;Fill in all the data later ; --- The OK button --- DCD -72,-72,-24,-24 ;Icon bounding box DCD &17003139 ;Icon flags word DCD wrt__ok,wrt__x2,3 ;Icon data strings wrt__windSize WOFF ; --- Indirected text for OK button --- wrt__ok DCB "OK",0 ;Button text string wrt__x2 DCB "x2",0 ;Button border command ;----- Workspace ------------------------------------------------------------ ^ 0,R12 wrt__wStart # 0 wrt__flags # 4 ;Various flags ; --- The user's handler routine --- wrt__proc # 4 ;The routine to call wrt__R10 # 4 ;Value to pass in R10 wrt__R12 # 4 ;Value to pass in R12 ; --- The copy of the window definition --- wrt__dbDef # wrt__windSize ;The window definition copy wrt__valid # 24 ;Icon validation string wrt__title # 24 ;Window title text string wrt__buffer # 256 ;The actual data string wrt__wSize EQU {VAR}-wrt__wStart wFlag__inited EQU (1<<0) ;Have we initialised yet? AREA |Sapphire$$LibData|,CODE,READONLY DCD wrt__wSize DCD wrt__wSpace DCD 0 DCD wrt_init ;----- That's all, folks ---------------------------------------------------- END