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