chiark / gitweb /
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