Initial revision
[ssr] / StraySrc / Libraries / Sapphire / sh / dbox
1 ;
2 ; dbox.sh
3 ;
4 ; Dialogue box handling
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 ;----- Overview -------------------------------------------------------------
28 ;
29 ; Functions provided:
30 ;
31 ; dbox_create
32 ; dbox_fromEmbedded
33 ; dbox_fromDefn
34 ; dbox_destroy
35 ; dbox_init
36 ; dbox_open
37 ; dbox_close
38 ; dbox_writePos
39 ; dbox_select
40 ; dbox_shade
41 ; dbox_selectMany
42 ; dbox_shadeMany
43 ; dbox_isSelected
44 ; dbox_radio
45 ; dbox_slab
46 ; dbox_unslab
47 ; dbox_setField
48 ; dbox_getField
49 ; dbox_eventHandler
50 ; dbox_renderTitle
51 ; dbox_setEmbeddedTitle
52 ; dbox_setClickDrag
53 ; dbox_hasTitle
54 ; dbox_window
55 ; dbox_help
56
57 [ :LNOT::DEF:dbox__dfn
58 GBLL dbox__dfn
59
60 ; --- dbox_create ---
61 ;
62 ; On entry: R0 == pointer to dialogue template name
63 ;
64 ; On exit: R0 == dialogue box handle for the dialogue
65 ; May return an error
66 ;
67 ; Use: Creates a dialogue box from a template definition.
68
69 IMPORT dbox_create
70
71 ; --- dbox_fromEmbedded ---
72 ;
73 ; On entry: R0 == pointer to an embedded template
74 ;
75 ; On exit: R0 == dialogue box handle
76 ; May return an error
77 ;
78 ; Use: Creates a dialogue box from an embedded template definition.
79
80 IMPORT dbox_fromEmbedded
81
82 ; --- dbox_fromDefn ---
83 ;
84 ; On entry: R0 == pointer to a window definition
85 ;
86 ; On exit: R0 == dialogue box handle for the dialogue
87 ; May return an error
88 ;
89 ; Use: Creates a dialogue box from an immediate window definition,
90 ; rather than a template. There are several things you need
91 ; to be aware of when you use this call to create a dialogue
92 ; box:
93 ;
94 ; * The window definition is not copied, but used directly
95 ; for the duration the dialogue box exists. It must
96 ; not move for this duration. When the dialogue is
97 ; destroyed, you can release the memory for the definition,
98 ; although this is your responsibility.
99 ;
100 ; * The indirected data is not copied either, so you'll have
101 ; to copy it yourself if you want multiple dialogues from
102 ; the same window definition.
103 ;
104 ; * The window definition and the indirected data must both
105 ; be writable.
106
107 IMPORT dbox_fromDefn
108
109 ; --- dbox_destroy ---
110 ;
111 ; On entry: R0 == dialogue box handle
112 ;
113 ; On exit: --
114 ;
115 ; Use: Destroys a dialogue box, freeing all the memory it took
116 ; up etc.
117
118 IMPORT dbox_destroy
119
120 ; --- dbox_init ---
121 ;
122 ; On entry: --
123 ;
124 ; On exit: --
125 ;
126 ; Use: Initialises the dbox system.
127
128 IMPORT dbox_init
129
130 ; --- dbox_open ---
131 ;
132 ; On entry: R0 == dialogue box handle
133 ; R1 == how to open the dialogue box
134 ; Other registers depend on R1, and are described at the end
135 ; of this header file
136 ;
137 ; On exit: --
138 ;
139 ; Use: Displays the dialogue box on the screen in the given manner.
140
141 IMPORT dbox_open
142
143 ; --- dbox_close ---
144 ;
145 ; On entry: R0 == dialogue box handle
146 ;
147 ; On exit: --
148 ;
149 ; Use: Closes a dialogue box, by clearing the current menu if
150 ; necessary.
151
152 IMPORT dbox_close
153
154 ; --- dbox_writePos ---
155 ;
156 ; On entry: R0 == dialogue box handle
157 ;
158 ; On exit: --
159 ;
160 ; Use: Saves the dialogue's current position so that it will be
161 ; opened here the next time it is created. If the dialogue
162 ; box was created from a template, the template is updated.
163 ; Otherwise, the new state is written back to the definition
164 ; supplied to dbox_fromDefn.
165
166 IMPORT dbox_writePos
167
168 ; --- dbox_select ---
169 ;
170 ; On entry: R0 == dialogue box handle
171 ; R1 == icon number
172 ; R2 == 0 to deselect the icon, 1 to select it, 2 to toggle
173 ; its current selected state
174 ;
175 ; On exit: --
176 ;
177 ; Use: Selects or deselects the specified icon in the Acorn sense
178 ; (i.e. by flipping its selected bit). The state is only
179 ; changed if required, to reduce flicker.
180
181 IMPORT dbox_select
182
183 ; --- dbox_shade ---
184 ;
185 ; On entry: R0 == dialogue box handle
186 ; R1 == icon number
187 ; R2 == 0 to unshade the icon, 1 to shade it, 2 to toggle its
188 ; current shaded state
189 ;
190 ; On exit: --
191 ;
192 ; Use: Makes the icon look dimmer, to indicate that it is not
193 ; available. It uses its own shading algorithms, rather than
194 ; the WindowManager's, so there are some things you must watch
195 ; out for:
196 ;
197 ; * Don't use any other method of shading icons
198 ;
199 ; * Don't assume that a shaded icon isn't going to give you
200 ; events. At the user level, this should have been tidied
201 ; up, but at the Sapphire level, it's still a problem.
202 ; There is a routine in winUtils which will tell you if an
203 ; icon is shaded.
204 ;
205 ; This routine has been written so that it only flickers icons
206 ; when they actually need it.
207
208 IMPORT dbox_shade
209
210 ; --- dbox_selectMany ---
211 ;
212 ; On entry: R0 == dialogue box handle
213 ; R1 == pointer to icon handle list, -1 terminated
214 ; R2 == select action (0 == unselect, 1 == select, 2 == toggle)
215 ;
216 ; On exit: --
217 ;
218 ; Use: Changes the select state of a group of icons.
219
220 IMPORT dbox_selectMany
221
222 ; --- dbox_shadeMany ---
223 ;
224 ; On entry: R0 == dialogue box handle
225 ; R1 == pointer to icon handle list, -1 terminated
226 ; R2 == shade action (0 == unshade, 1 == shade, 2 == toggle)
227 ;
228 ; On exit: --
229 ;
230 ; Use: Changes the shade state of a group of icons.
231
232 IMPORT dbox_shadeMany
233
234 ; --- dbox_isSelected ---
235 ;
236 ; On entry: R0 == dialogue box handle
237 ; R1 == icon number
238 ;
239 ; On exit: CS if the icon is selected, CC otherwise
240 ;
241 ; Use: Returns whether an icon is currently selected.
242
243 IMPORT dbox_isSelected
244
245 ; --- dbox_radio ---
246 ;
247 ; On entry: R0 == dialogue box handle
248 ; R1 == icon handle
249 ;
250 ; On exit: --
251 ;
252 ; Use: Checks to see if the icon is a radio button as defined by
253 ; Sapphire, i.e. button type 3 (debounced) and non-zero ESG.
254 ; If it is, it selects it, and deselects all other icons with
255 ; this ESG.
256
257 IMPORT dbox_radio
258
259 ; --- dbox_slab ---
260 ;
261 ; On entry: R0 == dialogue box handle
262 ; R1 == icon handle
263 ;
264 ; On exit: May return an error
265 ;
266 ; Use: Slabs an icon in properly, to give visual feedback when you
267 ; click it.
268
269 IMPORT dbox_slab
270
271 ; --- dbox_unslab ---
272 ;
273 ; On entry: --
274 ;
275 ; On exit: CS if there are no more slabbed icons after this one, CC
276 ; if there are more left.
277 ;
278 ; Use: Unslabs an icon slabbed with dbox_slab. Icons are unslabbed
279 ; in reverse order to that in which they were slabbed. The
280 ; carry flag is returned as an indication of whether there
281 ; are any more icons left in the list -- you can unslab all
282 ; icons in one go by doing:
283 ;
284 ; BL dbox_unslab
285 ; SUBCC PC,PC,#12 ;Avoids a label!
286 ;
287 ; It is recommended that, if you are going to close a window,
288 ; you unslab icons within it *after* you close, but before you
289 ; actually destroy it, e.g.
290 ;
291 ; LDR R0,my_dbox
292 ; BL dbox_close
293 ; BL dbox_unslab
294 ; BL dbox_destroy
295
296 IMPORT dbox_unslab
297
298 ; --- dbox_setField ---
299 ;
300 ; On entry: R0 == dialogue box handle
301 ; R1 == icon number to write to (may be -1 for title)
302 ; flags in top byte if not -1:
303 ; dbFlag_dots (bit 31) == add `...' if text overflows
304 ; R2 == pointer to string to use
305 ;
306 ; On exit: --
307 ;
308 ; Use: Writes the string specified into the indirection buffer
309 ; for the given icon. If the icon is not indirected, an
310 ; error is generated. If the indirected buffer is too small,
311 ; the string is shortened by chopping off the beginning or
312 ; the end, according to the setting of the icon's right
313 ; justify flag.
314 ;
315 ; The icon is only flickered if the text has actually changed.
316 ; The caret is moved correctly if it is within the icon to
317 ; prevent it `falling off' the end and deleting the validation
318 ; string, or being positioned incorrectly in centred icons if
319 ; the length changes.
320 ;
321 ; Note that this routine requires a string to already be in
322 ; the buffer, and doesn't perform any substitution or other
323 ; transformations. This helps to prevent buffer full errors
324 ; and similar problems.
325
326 IMPORT dbox_setField
327
328 ; --- dbox_getField ---
329 ;
330 ; On entry: R0 == dialogue box handle
331 ; R1 == icon number to interrogate
332 ;
333 ; On exit: R0, R1 preserved
334 ; R2 == pointer to the icon text
335 ;
336 ; Use: Returns a pointer to the text associated with an icon.
337 ; Note that if the icon is *not* indirected, the text will
338 ; be copied into the scratchpad. Otherwise you get a pointer
339 ; to the actual indirected data. You shouldn't write to the
340 ; string returned at all -- dbox_setField is specially
341 ; designed to do that sort of thing very well (i.e. not
342 ; flickering the text unless it has to, truncating if it's too
343 ; long, and handling the caret correctly). You *are* allowed
344 ; to zero terminate the string if you want to, though.
345 ;
346 ; Despite all the PRM's assurances to the contrary, chances
347 ; are the text will be terminated by some weird control char,
348 ; so you'll have to handle this, and not just assume it's
349 ; going to be null-terminated.
350 ;
351 ; Note: The indirected case is immensely quick -- just load a
352 ; pointer. The non-indirected case has been optimised as much
353 ; as possible.
354
355 IMPORT dbox_getField
356
357 ; --- dbox_eventHandler ---
358 ;
359 ; On entry: R0 == dialogue box handle
360 ; R1 == pointer to handler routine
361 ; R2 == value to pass to handler in R10
362 ; R3 == value to pass to handler in R12
363 ;
364 ; On exit: R0 preserved
365 ; R1 == pointer to old handler
366 ; R2 == old R10 value
367 ; R3 == old R12 value
368 ;
369 ; Use: Sets up an event handler for a dialogue box, and returns
370 ; the previous one. If the pointer to handler is 0, there is
371 ; no dialogue box event handler.
372
373 IMPORT dbox_eventHandler
374
375 ; --- dbox_renderTitle ---
376 ;
377 ; On entry: R0 == dialogue box handle
378 ; R1 == pointer to redraw block
379 ;
380 ; On exit: --
381 ;
382 ; Use: Renders a dialogue box's embedded title if there is one.
383
384 IMPORT dbox_renderTitle
385
386 ; --- dbox_setEmbeddedTitle ---
387 ;
388 ; On entry: R0 == dialogue box handle
389 ; R1 == icon which should contain the embedded title
390 ;
391 ; On exit: --
392 ;
393 ; Use: Declares a given dialogue box as requiring an embedded title
394 ; (rather than the one the WindowManager put on).
395
396 IMPORT dbox_setEmbeddedTitle
397
398 ; --- dbox_setClickDrag ---
399 ;
400 ; On entry: R0 == dialogue box handle
401 ;
402 ; On exit: --
403 ;
404 ; Use: Sets a given dialogue box so that the user can move it by
405 ; dragging from any part of the window, not just the title
406 ; bar.
407
408 IMPORT dbox_setClickDrag
409
410 ; --- dbox_hasTitle ---
411 ;
412 ; On entry: R0 == dialogue box handle
413 ;
414 ; On exit: CS if the dialogue box has a title bar, CC if not
415 ;
416 ; Use: Informs the caller whether the dialogue box has a title bar.
417 ; This is mainly useful for other library sections which
418 ; conditionally add in embedded titles etc.
419
420 IMPORT dbox_hasTitle
421
422 ; --- dbox_window ---
423 ;
424 ; On entry: R0 == dialogue box handle
425 ;
426 ; On exit: R0 == the dialogue box's window handle
427 ;
428 ; Use: Returns the Wimp window handle associated with a dialogue
429 ; box. This may be useful if you want to perform lowlevel
430 ; Wimp operation on it, or to subclass it using win.
431
432 IMPORT dbox_window
433
434 ; --- dbox_help ---
435 ;
436 ; On entry: --
437 ;
438 ; On exit: --
439 ;
440 ; Use: Adds a help line to the current help message, read by
441 ; scanning the icon to which the help was sent for an `H'
442 ; validation string.
443
444 IMPORT dbox_help
445
446 ;----- Useful constants -----------------------------------------------------
447
448 ; --- Ways of opening dialogue boxes ---
449
450 ^ 0
451 dbOpen_current # 1 ;In its current position
452 dbOpen_centre # 1 ;Centred on the screen
453 dbOpen_pointer # 1 ;Centred over the pointer
454 dbOpen_givenY # 1 ;At a given height on screen
455 ; R2 == y coordinate to open
456 dbOpen_givenXY # 1 ;At a given position
457 ; R2 == x coordinate
458 ; R3 == y coordinate
459
460 dbOpen_trans EQU &00 ;Make the dbox transient
461 dbOpen_persist EQU &80 ;Make the dbox persistent
462 dbOpen_nonSub EQU &40 ;Don't open as a submenu
463
464 ; --- Dialogue box event codes ---
465
466 dbEvent_close EQU -2 ;The user closed the dialogue
467 ;C flag ignored on exit
468
469 dbEvent_help EQU -3 ;The user wants some help
470 ;R1 == icon number
471 ;C flag ignored on exit
472
473 dbEvent_OK EQU -4 ;The user clicked OK
474 ;R1 == mouse button status
475 ;C flag ignored on exit
476
477 dbEvent_cancel EQU -5 ;The user clicked Cancel
478 ;R1 == mouse button status
479 ;C flag ignored on exit
480
481 dbEvent_redraw EQU -6 ;Redraw a single rectangle
482 ;R1 == pointer to redraw blk
483 ;R2,R3 == coords of origin
484 ;CS => don't do default draw
485
486 dbEvent_menu EQU -7 ;User clicked Menu button
487 ;R1 == icon handle clicked
488 ;C flag ignored on exit
489
490 dbEvent_drag EQU -8 ;User dragged an icon
491 ;R1 == mouse button status
492 ;R2 == icon handle dragged
493 ;C flag ignored on exit
494
495 dbEvent_save EQU -9 ;User wants to import data
496 ;R1 == icon handle dropped on
497 ;R2 == filetype of data
498 ;R3 == pointer to filename
499 ;R4 == estimated file size
500 ;C flag ignored on exit
501
502 dbEvent_load EQU -10 ;User wants to load data
503 ;R1 == icon handle dropped on
504 ;R2 == filetype of data
505 ;R3 == pointer to filename
506 ;R4 == estimated file size
507 ;C flag ignored on exit
508
509 dbEvent_key EQU -11 ;User pressed a key
510 ;R1 == key code received
511 ;R2 == icon handle with caret
512 ;CC => unknown keypress
513 ;Key code has been translated
514
515 dbEvent_hint EQU -12 ;Received a hint message
516 ;R2 == pointer to hint string
517
518 dbEvent_enter EQU -13 ;Pointer has entered window
519
520 dbEvent_leave EQU -14 ;Pointer has left window
521
522 dbEvent_lifeCycle EQU -15 ;Interesting points in cycle
523 ;R1 == life cycle code
524
525 ; --- Life cycle codes ---
526
527 ^ 0
528 dblc_create # 1 ;Creation (used by dbx)
529 dblc_open # 1 ;Opening
530 dblc_close # 1 ;Closing
531 dblc_destroy # 1 ;Destruction
532
533 ; --- Other values ---
534
535 dbFlag_dots EQU (1<<31) ;Add dots if text overflows
536 ; in dbox_setField
537
538 ]
539
540 ;----- That's all, folks ----------------------------------------------------
541
542 END