Initial revision
[ssr] / StraySrc / Libraries / Sapphire / s / writable
1 ;
2 ; writable.s
3 ;
4 ; Writable dialogue boxes (MDW)
5 ;
6 ; © 1994-1998 Straylight
7 ;
8
9 ;----- Licensing note -------------------------------------------------------
10 ;
11 ; This file is part of Straylight's Sapphire library.
12 ;
13 ; Sapphire is free software; you can redistribute it and/or modify
14 ; it under the terms of the GNU General Public License as published by
15 ; the Free Software Foundation; either version 2, or (at your option)
16 ; any later version.
17 ;
18 ; Sapphire is distributed in the hope that it will be useful,
19 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ; GNU General Public License for more details.
22 ;
23 ; You should have received a copy of the GNU General Public License
24 ; along with Sapphire. If not, write to the Free Software Foundation,
25 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
27 ;----- Standard header ------------------------------------------------------
28
29 GET libs:header
30 GET libs:swis
31
32 ;----- External dependencies ------------------------------------------------
33
34 GET sapphire:dbox
35 GET sapphire:fastMove
36 GET sapphire:msgs
37 GET sapphire:sapphire
38 GET sapphire:string
39
40 ;----- Main code ------------------------------------------------------------
41
42 AREA |Sapphire$$Code|,CODE,READONLY
43
44 ; --- writable ---
45 ;
46 ; On entry: R0 == pointer to writable dialogue block
47 ; R1 == pointer to default string to display, or 0 for null
48 ; R2 == pointer to routine to call when string set
49 ; R3 == value to pass to routine in R10
50 ; R4 == value to pass to routine in R12
51 ;
52 ; On exit: R0 == dialogue handle of created dialogue box
53 ; May return an error
54 ;
55 ; Use: Displays a writable dialogue box, i.e. one with a writable
56 ; icon and OK button, used instead of writable menu items,
57 ; for reasons to do with caret blinking and pointer changing.
58 ;
59 ; The writable dialogue block consists of:
60 ;
61 ; Size Meaning
62 ; ~~~~ ~~~~~~~
63 ; 4 Flags (see below)
64 ; n Validation string to use, may be null
65 ; m Title string (message tag) to display
66 ;
67 ; The flags are:
68 ;
69 ; Bit Meaning
70 ; ~~~ ~~~~~~~
71 ; 0-7 Maximum string length
72 ; 8 Right align text in writable icon
73 ; 9-31 Reserved; must be 0
74 ;
75 ; The routine returns a dialogue handle because you may want
76 ; to attach a numWrite control to the writable icon, which
77 ; is icon number 0.
78 ;
79 ; The handler routine is passed:
80 ;
81 ; R0 == pointer to string typed in
82 ; R1 == dialogue box handle (for numWrite again)
83 ; R10, R12 as set up here
84 ;
85 ; It must preserve all registers. If the carry flag is set
86 ; on exit, the dialogue box will not be closed. If it is
87 ; clear, the dialogue may be closed depending on the button
88 ; status.
89 ;
90 ; Note that this routine does *not* require a template --
91 ; a suitable window is generated at run-time.
92
93 EXPORT writable
94 writable ROUT
95
96 STMFD R13!,{R1-R3,R12,R14} ;Save some registers away
97 WSPACE wrt__wSpace ;Find my workspace pointer
98
99 ; --- Save the handler information ---
100
101 ADR R14,wrt__proc ;Point to the handler stuff
102 STMIA R14,{R2-R4} ;Save the handler info away
103 MOV R3,R0 ;Keep the description block
104
105 ; --- Save the default string away ---
106
107 ADR R0,wrt__buffer ;Point to writable buffer
108 CMP R1,#0 ;Is there a default string?
109 STREQB R1,[R0,#0] ;No -- save a null string
110 BLNE str_cpy ;Otherwise copy the string
111
112 ; --- Set up the dialogue box sizes ---
113
114 LDR R1,[R3,#0] ;Load the string length/flags
115 AND R0,R1,#&FF ;Just get the bottom byte
116 ADD R0,R0,#1 ;Allow for the terminator
117 STR R0,wrt__dbDef+wOff__writeData+8
118 CMP R0,#41 ;Is the string really big?
119 MOVGT R0,#41 ;Yes -- make it sane at least
120 MOV R0,R0,LSL #4 ;Multiply up to pixels
121 ADD R0,R0,#106 ;Get the left of the icon
122 RSB R0,R0,#0 ;And make it negative
123 STR R0,wrt__dbDef+wOff__writeBox
124 SUB R0,R0,#24 ;Get left side of the window
125 STR R0,wrt__dbDef+wOff__open
126 STR R0,wrt__dbDef+wOff__extent
127
128 ; --- Fix up string alignment ---
129
130 LDR R14,wrt__dbDef+wOff__writeFlag
131 TST R1,#wrtFlag_rAlign ;Do we right align text?
132 ORRNE R14,R14,#&200 ;Yes -- set the bit then
133 BICEQ R14,R14,#&200 ;No -- clear it instead
134 STR R14,wrt__dbDef+wOff__writeFlag
135
136 ; --- Fill in the validation string ---
137
138 ADR R0,wrt__valid ;Point to validation buffer
139 ADR R1,wrt__x7 ;Point to base validation
140 BL str_cpy ;Copy it onto the end
141 ADD R1,R3,#4 ;Point to validation string
142 LDRB R14,[R1],#1 ;Load the first byte
143 CMP R14,#32 ;Is this an empty string?
144 BLO %20writable ;Yes -- miss this bit out
145
146 MOV R2,#';' ;Put a delimiter string in
147 STRB R2,[R0],#1 ;Save in validation buffer
148 10writable STRB R14,[R0],#1 ;Save the valid character
149 LDRB R14,[R1],#1 ;Load another byte
150 CMP R14,#32 ;Is this the string end?
151 BHS %10writable ;No -- go round again
152 MOV R14,#0 ;Null terminate nicely
153 STRB R14,[R0],#1 ;Save it in the buffer
154
155 ; --- Finally, fill in the title string ---
156
157 20writable MOV R0,R1 ;Point to title message tag
158 BL msgs_lookup ;Find the message string
159 MOV R1,R0 ;Point to the message
160 ADR R0,wrt__title ;Point to the title buffer
161 BL str_cpy ;And copy that over nicely
162
163 ; --- Build the dialogue box ---
164
165 ADR R0,wrt__dbDef ;Point to the dialogue defn
166 BL dbox_fromDefn ;Create a dialogue box
167 BVS %90writable ;Return if it failed
168
169 ADR R1,wrt__handler ;Point to the handler
170 MOV R2,R0 ;Pass dialogue handle in R10
171 MOV R3,R12 ;Pass workspace in R12
172 BL dbox_eventHandler ;Set up the event handler
173
174 MOV R1,#dbOpen_pointer+dbOpen_trans
175 BL dbox_open ;Display the dialogue box
176 LDMFD R13!,{R1-R3,R12,R14} ;Restore all the registers
177 BICS PC,R14,#V_flag ;Return without an error
178
179 ; --- Couldn't create the dialogue box ---
180
181 90writable LDMFD R13!,{R1-R3,R12,R14} ;Restore all the registers
182 ORRS PC,R14,#V_flag ;Return the error pointer
183
184 wrt__x7 DCB "x7",0 ;Tim's neat writable border
185
186 LTORG
187
188 ; --- wrt__handler ---
189 ;
190 ; On entry: R0 == dialogue box event code
191 ; R1-R7 == depend on the event type
192 ; R10 == dialogue box handle
193 ; R12 == pointer to my workspace
194 ;
195 ; On exit: --
196 ;
197 ; Use: Handles events for the writable dialogue box.
198
199 wrt__handler ROUT
200
201 CMP R0,#dbEvent_close ;Someone closed my dialogue?
202 BEQ %10wrt__handler ;Yes -- destroy it then
203 CMP R0,#dbEvent_OK ;Is it an OK click?
204 CMPNE R0,#wrtIcon__ok ;Or a click on the OK button?
205 MOVNES PC,R14 ;No -- then return to caller
206
207 ; --- Handle an OK click ---
208
209 STMFD R13!,{R0-R3,R10,R12,R14} ;Save loads of registers
210 MOV R2,R1 ;Look after the button state
211 MOV R0,R10 ;Get the dialogue handle
212 MOV R1,#wrtIcon__ok ;And the OK button handle
213 BL dbox_slab ;Slab the button in
214
215 ; --- Call the user's handler ---
216
217 ADR R0,wrt__buffer ;Point to the string
218 MOV R1,R10 ;Get the dialogue box handle
219 ADR R14,wrt__proc ;Find his event handler
220 LDMIA R14,{R3,R10,R12} ;Load all the handler stuff
221 ADDS R0,R0,#0 ;Clear C flag cunningly
222 MOV R14,PC ;Set up return address
223 MOV PC,R3 ;And call the handler
224
225 ; --- Find out what to do next ---
226
227 TSTCS R2,#0 ;Set Z flag if carry set
228 TSTCC R2,#1 ;Otherwise, test Adjustness
229 MOV R0,R1 ;Get the dialogue handle
230 BLEQ dbox_close ;If Select then close dbox
231 BL dbox_unslab ;Unslab the OK button
232 BLEQ dbox_destroy ;If Select then trash dbox
233 LDMFD R13!,{R0-R3,R10,R12,PC}^ ;And return to caller
234
235 ; --- The dialogue box closed ---
236
237 10wrt__handler STMFD R13!,{R0,R14} ;Save some registers
238 MOV R0,R10 ;Get the dialogue handle
239 BL dbox_destroy ;Kill the dialogue box
240 LDMFD R13!,{R0,PC}^ ;Return to caller
241
242 LTORG
243
244 ; --- wrt_init ---
245 ;
246 ; On entry: --
247 ;
248 ; On exit: --
249 ;
250 ; Use: Initialises the writable dialogue box for use.
251
252 EXPORT wrt_init
253 wrt_init ROUT
254
255 STMFD R13!,{R12,R14} ;Save some registers
256 WSPACE wrt__wSpace ;Load my workspace pointer
257 LDR R14,wrt__flags ;Load the flags word nicely
258 TST R14,#wFlag__inited ;Have we done this already?
259 LDMNEFD R13!,{R12,PC}^ ;Yes -- return to caller
260
261 ; --- Set up the flags nicely ---
262
263 STMFD R13!,{R0-R2} ;Save some more registers
264 ORR R14,R14,#wFlag__inited ;Set the initialised flag
265 STR R14,wrt__flags ;Save the flags back again
266 BL dbox_init ;Make sure dboxes are going
267
268 ; --- Now copy the window definition over ---
269
270 ADR R0,wrt__dbDef ;Point to the workspace block
271 ADR R1,wrt__window ;Point to the window def
272 MOV R2,#wrt__windSize ;Get the size of the block
273 BL fastMove ;Copy the block over nicely
274
275 ; --- Fill in bits of the window definition ---
276
277 ADR R14,wrt__title ;Point to the title buffer
278 STR R14,[R0,#wOff__titleData]
279 ADR R14,wrt__buffer
280 STR R14,[R0,#wOff__writeData]
281 ADR R14,wrt__valid
282 STR R14,[R0,#wOff__writeData+4]
283
284 LDMFD R13!,{R0-R2,R12,PC}^ ;Return to caller
285
286 LTORG
287
288 wrt__wSpace DCD 0
289
290 ;----- Constants ------------------------------------------------------------
291
292 ; --- Icon numbers ---
293
294 wrtIcon__write EQU 0 ;The writable icon
295 wrtIcon__ok EQU 1 ;The OK button
296
297 ; --- Flags ---
298
299 wrtFlag_rAlign EQU (1<<8) ;Align text to right side
300
301 ;----- Window definition ----------------------------------------------------
302
303 ; --- Note ---
304 ;
305 ; The main window definition here gets copied into workspace so that I can
306 ; modify it nicely at runtime, to change the width of the window etc.
307
308 ; --- Macro: WOFF ---
309 ;
310 ; Arguments: label == symbol to assign with current offset into window def
311 ;
312 ; Use: Sets a symbol to an offset in the window definition
313
314 MACRO
315 $label WOFF
316 $label EQU {PC}-wrt__window
317 MEND
318
319 ; --- The main window block ---
320
321 wrt__window
322
323 wOff__open WOFF
324 DCD -324,-96,0,0 ;Width dynamically adjusted
325 DCD 0,0 ;Window doesn't scroll (hope)
326 DCD -1 ;Always open on the top
327 DCD &84170002 ;Window flags word (various)
328 DCB 7,2,7,1,3,1,2,0 ;Window colours words
329
330 wOff__extent WOFF
331 DCD -324,-96,0,0 ;Dynamically adjust width
332 DCD &00000109 ;Window title bar flags
333 DCD &00000000 ;Work area button type
334 DCD 1 ;Wimp sprite area, I think
335 DCD 0 ;Default minimum sizes
336
337 wOff__titleData WOFF
338 DCD 0,-1,24 ;Title bar icon data
339 DCD 2 ;2 icons following
340
341 ; --- The writable area icon ---
342
343 wOff__writeBox WOFF
344 DCD -300,-68,-110,-28 ;24 in from the left
345
346 wOff__writeFlag WOFF
347 DCD &0700F131 ;Icon flags word
348
349 wOff__writeData WOFF
350 DCD 0,0,0 ;Fill in all the data later
351
352 ; --- The OK button ---
353
354 DCD -72,-72,-24,-24 ;Icon bounding box
355 DCD &17003139 ;Icon flags word
356 DCD wrt__ok,wrt__x2,3 ;Icon data strings
357
358 wrt__windSize WOFF
359
360 ; --- Indirected text for OK button ---
361
362 wrt__ok DCB "OK",0 ;Button text string
363 wrt__x2 DCB "x2",0 ;Button border command
364
365 ;----- Workspace ------------------------------------------------------------
366
367 ^ 0,R12
368 wrt__wStart # 0
369
370 wrt__flags # 4 ;Various flags
371
372 ; --- The user's handler routine ---
373
374 wrt__proc # 4 ;The routine to call
375 wrt__R10 # 4 ;Value to pass in R10
376 wrt__R12 # 4 ;Value to pass in R12
377
378 ; --- The copy of the window definition ---
379
380 wrt__dbDef # wrt__windSize ;The window definition copy
381 wrt__valid # 24 ;Icon validation string
382 wrt__title # 24 ;Window title text string
383 wrt__buffer # 256 ;The actual data string
384
385 wrt__wSize EQU {VAR}-wrt__wStart
386
387 wFlag__inited EQU (1<<0) ;Have we initialised yet?
388
389 AREA |Sapphire$$LibData|,CODE,READONLY
390
391 DCD wrt__wSize
392 DCD wrt__wSpace
393 DCD 0
394 DCD wrt_init
395
396 ;----- That's all, folks ----------------------------------------------------
397
398 END