chiark / gitweb /
Initial revision
[ssr] / StraySrc / Libraries / Sapphire / dbx / s / slider
1 ;
2 ; dbx.slider.s
3 ;
4 ; Implementation of sliders as a dbx control
5 ;
6 ; © 1994 Straylight
7 ;
8
9 ;----- Standard header ------------------------------------------------------
10
11                 GET     libs:header
12                 GET     libs:swis
13
14 ;----- External dependencies ------------------------------------------------
15
16                 GET     sapphire:dbox
17                 GET     sapphire:divide
18                 GET     sapphire:idle
19                 GET     sapphire:win
20                 GET     sapphire:msgs
21                 GET     sapphire:screen
22                 GET     sapphire:winUtils
23
24                 GET     sapphire:dbx.dbx
25                 GET     sapphire:dbx._dbxMacs
26
27 ;----- Main code ------------------------------------------------------------
28
29                 AREA    |Sapphire$$Code|,CODE,READONLY
30
31 slFlag_vertical EQU     (1<<8)
32 slFlag_horizontal EQU   0
33 slFlag_colData  EQU     (1<<9)
34
35 ; --- slider ---
36 ;
37 ; Control data: +0 == slider colour (if flags bit 9 clear)
38 ;               +1 == background colour
39 ;               +2 == separator colour
40 ;               +3 == reserved
41 ;               +4 == maximum slider value
42 ;               +8
43 ;
44 ; Workspace:    +0 == current slider value
45 ;               +4 == slider colour (if flags bit 9 set)
46 ;               +5 == reserved, must be 0
47 ;               +8
48 ;
49 ; Flags:        Bit 8 == slider is horizontal if clear, vertical is set
50 ;
51 ; Use:          Control type for a slider.
52
53                 EXPORT  slider
54 slider          ROUT
55
56                 DBXWS   slider__wSpace
57                 DCD     dbxMask_click + dbxMask_redraw
58
59                 CMP     R0,#0                   ;Is this a click event?
60                 BEQ     %50slider               ;Yes -- handle it
61
62                 ; --- Handle a whole slider redraw operation ---
63
64                 STMFD   R13!,{R0-R2,R6-R8,R10,R14}
65
66                 ; --- Get a colour mask ---
67                 ;
68                 ; We use RISC OS 3.5's peculiar shading algorithm -- clear
69                 ; all the colour bits except 1!  This is easy -- we just
70                 ; set up an AND mask in R10 at the start.
71
72                 MOV     R0,R10                  ;Get the dialogue box handle
73                 BL      dbox_window             ;Translate to window handle
74                 BL      winUtils_shaded         ;Is the icon shaded, please?
75                 MOVCS   R10,#2                  ;Yes -- leave only bit 1
76                 MOVCC   R10,#&FF                ;Otherwise leave colour alone
77
78                 ; --- Sort out what needs doing ---
79
80                 LDR     R6,[R9,#-12]            ;Locate the flags word
81                 TST     R6,#slFlag_vertical     ;Is the slider vertical?
82                 SUBNE   R7,R5,R3                ;Yes -- calculate the height
83                 SUBEQ   R7,R4,R2                ;No -- calculate the width
84
85                 ; --- Work out the length to draw out ---
86
87                 LDR     R0,[R8,#0]              ;Load the slider value
88                 MUL     R0,R7,R0                ;Multiply the value up
89                 LDR     R1,[R9,#4]              ;Get the slider maximum val
90                 BL      div_round               ;Calculate correct length
91                 MOV     R6,R0                   ;Look after the quotient
92                 MOV     R7,R2                   ;Keep the left hand edge
93                 BEQ     %10slider               ;If slider not vert, skip
94
95                 ; --- Now draw a vertical slider ---
96
97                 LDR     R14,[R9,#-12]           ;Locate the flags word
98                 TST     R14,#slFlag_colData     ;Is the colour writable?
99                 LDREQB  R0,[R9,#0]              ;Get the slider colour...
100                 LDRNEB  R0,[R8,#4]              ;... from wherever it is
101                 AND     R0,R0,R10               ;Mask colour for shading
102                 SWI     Wimp_SetColour          ;Start in this colour
103
104                 BL      screen_getInfo          ;Get some screen information
105                 LDR     R8,[R0,#screen_dy]      ;Load the y pixel size
106
107                 MOV     R0,#4                   ;Move absolute coordinates
108                 MOV     R1,R7                   ;Left hand side of control
109                 MOV     R2,R3                   ;Bottom edge of control
110                 SWI     OS_Plot                 ;Move graphics cursor there
111                 MOV     R0,#&65                 ;Rectangle fill absolute
112                 MOV     R1,R4                   ;Right hand side of control
113                 ADD     R2,R3,R6                ;Top of the slider bar
114                 SUB     R2,R2,R8                ;Allow a bit for the crossbar
115                 CMP     R2,R3                   ;Is there any slider bar?
116                 SWIGE   OS_Plot                 ;Fill in the slider bar
117
118                 LDRB    R0,[R9,#2]              ;Get the separator colour
119                 AND     R0,R0,R10               ;Mask colour for shading
120                 SWI     Wimp_SetColour          ;Use this colour now
121                 MOV     R0,#4                   ;Move cursor absolute
122                 ADD     R2,R2,R8                ;Top edge of slider bar
123                 SWI     OS_Plot                 ;Move the cursor there
124                 MOV     R0,#5                   ;Draw line absolute
125                 MOV     R1,R7                   ;Left hand side of control
126                 SWI     OS_Plot                 ;Fill in the middle bit
127
128                 LDRB    R0,[R9,#1]              ;Get the background colour
129                 AND     R0,R0,R10               ;Mask colour for shading
130                 SWI     Wimp_SetColour          ;Use this colour now
131                 MOV     R0,#4                   ;Move cursor absolute
132                 ADD     R2,R2,R8                ;Top edge of slider bar
133                 SWI     OS_Plot                 ;Move the cursor there
134                 MOV     R0,#&65                 ;Rectangle fill absolute
135                 MOV     R1,R4                   ;Left hand side of control
136                 CMP     R2,R5                   ;Is there anything to draw?
137                 MOV     R2,R5                   ;Top of the control
138                 SWILE   OS_Plot                 ;Fill in the background bit
139
140                 B       %90slider               ;Skip to the end now
141
142                 ; --- Now draw a horizontal slider ---
143
144 10slider        LDR     R14,[R9,#-12]           ;Locate the flags word
145                 TST     R14,#slFlag_colData     ;Is the colour writable?
146                 LDREQB  R0,[R9,#0]              ;Get the slider colour...
147                 LDRNEB  R0,[R8,#4]              ;... from wherever it is
148                 AND     R0,R0,R10               ;Mask colour for shading
149                 SWI     Wimp_SetColour          ;Start in this colour
150
151                 BL      screen_getInfo          ;Get some screen information
152                 LDR     R8,[R0,#screen_dx]      ;Load the x pixel size
153
154                 MOV     R0,#4                   ;Move absolute coordinates
155                 MOV     R1,R7                   ;Left hand side of control
156                 MOV     R2,R3                   ;Bottom edge of control
157                 SWI     OS_Plot                 ;Move graphics cursor there
158                 MOV     R0,#&65                 ;Rectangle fill absolute
159                 ADD     R1,R7,R6                ;Right of the slider bar
160                 SUB     R1,R1,R8                ;Allow for the crossbar
161                 MOV     R2,R5                   ;Top edge of the control
162                 CMP     R1,R7                   ;Is there anything to draw?
163                 SWIGE   OS_Plot                 ;Fill in the slider bar
164
165                 LDRB    R0,[R9,#2]              ;Get the separator colour
166                 AND     R0,R0,R10               ;Mask colour for shading
167                 SWI     Wimp_SetColour          ;Use this colour now
168                 MOV     R0,#4                   ;Move cursor absolute
169                 ADD     R1,R1,R8                ;Top edge of slider bar
170                 SWI     OS_Plot                 ;Move the cursor there
171                 MOV     R0,#5                   ;Draw line absolute
172                 MOV     R2,R3                   ;Bottom edge of the control
173                 SWI     OS_Plot                 ;Fill in the middle bit
174
175                 LDRB    R0,[R9,#1]              ;Get the background colour
176                 AND     R0,R0,R10               ;Mask colour for shading
177                 SWI     Wimp_SetColour          ;Use this colour now
178                 MOV     R0,#4                   ;Move cursor absolute
179                 ADD     R1,R1,R8                ;Top edge of slider bar
180                 SWI     OS_Plot                 ;Move the cursor there
181                 MOV     R0,#&65                 ;Rectangle fill absolute
182                 CMP     R1,R4                   ;Is there anything to draw?
183                 MOV     R1,R4                   ;Right hand side of control
184                 MOV     R2,R5                   ;Top of the control
185                 SWILE   OS_Plot                 ;Fill in the background bit
186
187 90slider        LDMFD   R13!,{R0-R2,R6-R8,R10,PC}^
188
189                 ; --- Handle a mouse click event ---
190                 ;
191                 ; We start a slider drag operation
192
193 50slider        TST     R2,#5                   ;Is this a real mouse click?
194                 MOVEQS  PC,R14                  ;No -- then ignore it
195                 STMFD   R13!,{R0-R3,R14}        ;Save a few registers
196
197                 ; --- Save the slider information away ---
198
199                 MOV     R0,R10                  ;Get dialogue handle in R0
200                 BL      dbx_controlBBox         ;Get the control position
201                 STMIA   R12,{R1-R5,R8,R9}       ;Save the state in workspace
202
203                 ; --- Start a drag operation ---
204
205                 SUB     R13,R13,#56             ;Make way for a drag block
206                 MOV     R1,R13                  ;Point to the block
207                 SWI     Wimp_GetPointerInfo     ;Get the pointer position
208                 LDR     R7,[R9,#-12]            ;Get the control flags
209                 TST     R7,#slFlag_vertical     ;Is the slider vertical?
210                 LDRNE   R0,[R13,#0]             ;Yes -- read mouse x position
211                 LDREQ   R0,[R13,#4]             ;No -- read mouse y position
212
213                 MOVNE   R2,R0                   ;Force mouse to straight line
214                 MOVNE   R4,R0
215                 MOVEQ   R3,R0
216                 MOVEQ   R5,R0
217
218                 MOV     R0,R10                  ;Get the dialogue handle
219                 BL      dbox_window             ;Get the dbox's window handle
220                 MOV     R1,#7                   ;Drag type is user-defined
221                 STMIA   R13,{R0,R1}             ;Store them in the block
222                 ADD     R14,R13,#24             ;Point to parent box posn
223                 STMIA   R14,{R2-R5}             ;Save them in the block
224                 MOV     R1,R13                  ;Point to the block
225                 SWI     Wimp_DragBox            ;Start a drag operation
226                 ADD     R13,R13,#56             ;Reclaim all that stack space
227
228                 ADR     R0,sl__ukEvents         ;Point to unknown handler
229                 MOV     R1,#0                   ;Don't care about R4
230                 MOV     R2,R10                  ;Pass dialogue box in R10
231                 MOV     R3,R12                  ;Pass workspace in R12
232                 BL      win_unknownHandler      ;Add the handler
233                 MOVVC   R0,#2                   ;Call me every TV frame
234                 ADRVC   R1,sl__idles            ;Point to idle handler
235                 BLVC    idle_handler            ;Add in the idle handler
236                 BL      sl__idles               ;Do one now for luck
237
238 60slider        LDMIA   R13!,{R0-R3,R14}        ;Load the registers back
239                 ORRS    PC,R14,#C_flag          ;Claim this event
240
241 slider__wSpace  DCD     0
242
243                 LTORG
244
245 ; --- sl__idles ---
246 ;
247 ; On entry:     R10 == dialogue box handle for dbox
248 ;               R12 == my workspace
249 ;
250 ; On exit:      --
251 ;
252 ; Use:          Handles idle events during a slider drag
253
254 sl__idles       ROUT
255
256                 STMFD   R13!,{R0-R5,R8,R9,R14}  ;Save a barrelload of regs
257                 LDMIB   R12,{R2-R5,R8,R9}       ;Load registers for readVal
258                 MOV     R0,#slider_event        ;My very own event code
259                 MOV     R1,#slider_sliding      ;Indicate it's still going
260                 BL      sl__readVal             ;Perform the update
261                 BLCS    dbx_sendEvent           ;Send the event if it changed
262                 LDMFD   R13!,{R0-R5,R8,R9,PC}^  ;Return to caller
263
264                 LTORG
265
266 ; --- sl__ukEvents ---
267 ;
268 ; On entry:     R0 == event code
269 ;               R1 == pointer to event data
270 ;               R4 == 0!
271 ;               R10 == dialogue box handle
272 ;               R12 == my workspace
273 ;
274 ; On exit:      If R0 == 7 on entry, C set, otherwise all preserved
275 ;
276 ; Use:          Handles unknown events for sliders.
277
278 sl__ukEvents    ROUT
279
280                 CMP     R0,#7                   ;Is this a drag event?
281                 MOVNES  PC,R14                  ;No -- not interested then
282                 STMFD   R13!,{R0-R5,R8,R9,R14}  ;Save a bucketload of regs
283
284                 ; --- Update the slider one last time ---
285
286                 LDMIB   R12,{R2-R5,R8,R9}       ;Load registers for readVal
287                 MOV     R0,#slider_event        ;My very own event code
288                 MOV     R1,#slider_slid         ;Indicate it's over now
289                 BL      sl__readVal             ;Perform the update
290                 BL      dbx_sendEvent           ;Send the event regardless
291
292                 ; --- Close down the idle and unknown handlers ---
293
294                 ADR     R0,sl__ukEvents         ;Point to unknown handler
295                 MOV     R1,#0                   ;Don't care about R4
296                 MOV     R2,R10                  ;Pass dialogue box in R10
297                 MOV     R3,R12                  ;Pass workspace in R12
298                 BL      win_removeUnknownHandler;Add the handler
299                 MOV     R0,#2                   ;Call me every TV frame
300                 ADR     R1,sl__idles            ;Point to idle handler
301                 BL      idle_removeHandler      ;Add in the idle handler
302
303                 LDMFD   R13!,{R0-R5,R8,R9,PC}^  ;Return to caller at last
304
305                 LTORG
306
307 ; --- sl__readVal ---
308 ;
309 ; On entry:     R0 == event code for dialogue box (slider_event)
310 ;               R1 == subreason code to send (slider_sliding or slider_slid)
311 ;               R2-R5 == position of icon on screen
312 ;               R8 == pointer to control workspace
313 ;               R9 == pointer to control definition
314 ;               R10 == dialogue box handle
315 ;
316 ; On exit:      R2,R3 set up for slider event
317 ;               CS if the slider position has changed
318 ;
319 ; Use:          Reads a slider value from mouse position, and sends the
320 ;               dialogue box an event
321
322 sl__readVal     ROUT
323
324                 STMFD   R13!,{R0,R1,R6,R14}     ;Save some registers
325
326                 ; --- Read the mouse position ---
327
328                 SUB     R13,R13,#20             ;Make space for a mouse blk
329                 MOV     R1,R13                  ;Point to the block
330                 SWI     Wimp_GetPointerInfo     ;Get the pointer position
331                 LDR     R14,[R9,#-12]           ;Load the control flags
332                 TST     R14,#slFlag_vertical    ;Is the control vertical?
333                 LDRNE   R0,[R1,#4]              ;Yes -- get the y coordinate
334                 SUBNE   R0,R0,R3                ;And chop off bottom posn
335                 LDREQ   R0,[R1,#0]              ;No -- get the x coordinate
336                 SUBEQ   R0,R0,R2                ;And chop of the left posn
337                 ADD     R13,R13,#20             ;Reclaimt the stack now
338
339                 ; --- Scale this value to user's units ---
340
341                 LDR     R6,[R9,#4]              ;Get user's maximum value
342                 MUL     R0,R6,R0                ;Multiply position up nicely
343                 SUBNE   R1,R5,R3                ;Vertical -- get height
344                 SUBEQ   R1,R4,R2                ;Horizontal -- get width
345                 BL      div_round               ;Divide and round to nearest
346                 CMP     R0,R6                   ;Is the value too large?
347                 MOVGT   R0,R6                   ;Yes -- force it down then
348                 CMP     R0,#0                   ;Is it too small?
349                 MOVLT   R0,#0                   ;Yes -- force it up then
350                 LDR     R3,[R8,#0]              ;Get the old slider value
351                 CMP     R0,R3                   ;Is this the same as then?
352                 STRNE   R0,[R8,#0]              ;No -- Store the new value
353                 MOVNE   R3,R0                   ;Keep a copy for later
354
355                 ; --- Update the picture of the slider ---
356
357                 MOV     R0,R10                  ;Get the dialogue handle
358                 LDR     R1,slider__icon         ;Get the icon handle
359                 BLNE    dbx_update              ;Update the slider display
360
361                 MOV     R2,R1                   ;Get icon handle in R2
362                 LDMFD   R13!,{R0,R1,R6,R14}     ;Restore registers
363                 ORRNES  PC,R14,#C_flag          ;If new value, set C on exit
364                 BICEQS  PC,R14,#C_flag          ;Otherwise clear it
365
366                 LTORG
367
368 ;----- Slider event codes ---------------------------------------------------
369
370 slider_event    EQU     &80000001
371 slider_sliding  EQU     0
372 slider_slid     EQU     1
373
374 ;----- Workspace ------------------------------------------------------------
375
376                 ^       0,R12
377 slider__wStart  #       0
378
379 slider__icon    #       4                       ;Icon handle for slider
380 slider__iconPos #       16                      ;Icon coordinates on screen
381 slider__work    #       4                       ;Pointer to user's workarea
382 slider__defn    #       4                       ;Pointer to slider definition
383
384 slider__wSize   EQU     {VAR}-slider__wStart
385
386                 AREA    |Sapphire$$LibData|,CODE,READONLY
387
388                 DCD     slider__wSize
389                 DCD     slider__wSpace
390                 DCD     0
391                 DCD     0
392
393 ;----- That's all, folks ----------------------------------------------------
394
395                 END