2 Copyright © 2002-2003, The AROS Development Team. All rights reserved.
6 #define MUIMASTER_YES_INLINE_STDARG
8 #include <exec/memory.h>
9 #include <clib/alib_protos.h>
10 #include <proto/exec.h>
11 #include <proto/dos.h>
12 #include <proto/intuition.h>
13 #include <proto/graphics.h>
14 #include <proto/utility.h>
15 #include <proto/muimaster.h>
22 #include "muimaster_intern.h"
24 #include "support_classes.h"
27 #include "knob_private.h"
29 extern struct Library
*MUIMasterBase
;
31 #define OUTERFRAME_X 2
32 #define OUTERFRAME_Y 2
33 #define OUTERFRAME_W (OUTERFRAME_X * 2)
34 #define OUTERFRAME_H (OUTERFRAME_Y * 2)
36 #define INNERFRAME_X 2
37 #define INNERFRAME_Y 2
38 #define INNERFRAME_W (INNERFRAME_X * 2)
39 #define INNERFRAME_H (INNERFRAME_Y * 2)
41 #define BORDERSIZE_X 2
42 #define BORDERSIZE_Y 2
43 #define BORDERSIZE_W (BORDERSIZE_X * 2)
44 #define BORDERSIZE_H (BORDERSIZE_Y * 2)
46 #define KNOB_LABEL_SPACING 2
49 #define KNOB_HEIGHT 25
51 #define LABEL_HEIGHT 8
53 #define TOTAL_WIDTH OUTERFRAME_W + BORDERSIZE_W + KNOB_WIDTH
54 #define TOTAL_HEIGHT OUTERFRAME_H + BORDERSIZE_H + INNERFRAME_H + KNOB_HEIGHT + KNOB_LABEL_SPACING + LABEL_HEIGHT
62 #define RLE_REP(count, val) (((count - 1) << 4) | val)
64 static const UBYTE knob_rle
[] = /* hand-encoded, BTW ;-) */
66 RLE_REP(8,0), RLE_REP(9,1), RLE_REP(8,0),
67 RLE_REP(6,0), RLE_REP(2,1), RLE_REP(9,2), RLE_REP(2,1), RLE_REP(6,0),
68 RLE_REP(5,0), 1, RLE_REP(2,2), RLE_REP(9,3), RLE_REP(2,2), 1, RLE_REP(5,0),
69 RLE_REP(4,0), 1, 2, RLE_REP(13,3), 2, 1, RLE_REP(4,0),
70 RLE_REP(3,0), 1, 2, RLE_REP(3,3), RLE_REP(9,0), RLE_REP(3,3), 2, 3, RLE_REP(3,0),
71 RLE_REP(2,0), 1, 2, RLE_REP(2,3), RLE_REP(13,0), 3, 1, 2, 3, RLE_REP(2,0),
72 0, 1, 2, RLE_REP(2,3), RLE_REP(15,0), RLE_REP(2,1), 2, 3, 0,
73 0, 1, 2, RLE_REP(2,3), RLE_REP(15,0), RLE_REP(2,1), 2, 3, 0,
74 1, 2, RLE_REP(2,3), 0, RLE_REP(16,0), RLE_REP(2,1), 2, 3,
75 1, 2, RLE_REP(2,3), 0, RLE_REP(16,0), RLE_REP(2,1), 2, 3,
76 1, 2, RLE_REP(2,3), 0, RLE_REP(16,0), RLE_REP(2,1), 2, 3,
77 1, 2, RLE_REP(2,3), 0, RLE_REP(16,0), RLE_REP(2,1), 2, 3,
78 1, 2, RLE_REP(2,3), 0, RLE_REP(16,0), RLE_REP(2,1), 2, 3,
79 1, 2, RLE_REP(2,3), 0, RLE_REP(16,0), RLE_REP(2,1), 2, 3,
80 1, 2, RLE_REP(2,3), 0, RLE_REP(16,0), RLE_REP(2,1), 2, 3,
81 1, 2, RLE_REP(2,3), 0, RLE_REP(16,0), RLE_REP(2,1), 2, 3,
82 1, 2, RLE_REP(2,3), 0, RLE_REP(16,0), RLE_REP(2,1), 2, 3,
83 0, 1, 2, RLE_REP(2,3), RLE_REP(15,0), RLE_REP(2,1), 2, 3, 0,
84 0, 1, 2, RLE_REP(2,3), RLE_REP(15,0), RLE_REP(2,1), 2, 3, 0,
85 RLE_REP(2,0), 1, 2, RLE_REP(2,3), RLE_REP(13,0), RLE_REP(2,1), 2, 3, RLE_REP(2,0),
86 RLE_REP(3,0), 1, 2, RLE_REP(3,1), RLE_REP(9,0), RLE_REP(3,1), 2, 3, RLE_REP(3,0),
87 RLE_REP(4,0), 3, 2, RLE_REP(13,1), 2, 3, RLE_REP(4,0),
88 RLE_REP(5,0), 3, RLE_REP(2,2), RLE_REP(9,1), RLE_REP(2,2), 3, RLE_REP(5,0),
89 RLE_REP(6,0), RLE_REP(2,3), RLE_REP(9,2), RLE_REP(2,3), RLE_REP(6,0),
90 RLE_REP(8,0), RLE_REP(9,3), RLE_REP(8,0),
94 IPTR
Knob__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
96 obj
= (Object
*)DoSuperNewTags
100 TAG_MORE
, (IPTR
) msg
->ops_AttrList
105 struct Knob_DATA
*data
= INST_DATA(cl
, obj
);
107 data
->ehn
.ehn_Events
= IDCMP_MOUSEBUTTONS
;
108 data
->ehn
.ehn_Priority
= 0;
109 data
->ehn
.ehn_Flags
= 0;
110 data
->ehn
.ehn_Object
= obj
;
111 data
->ehn
.ehn_Class
= cl
;
118 IPTR
Knob__MUIM_Setup(struct IClass
*cl
, Object
*obj
, struct MUIP_Setup
*msg
)
120 //struct RastPort rp;
123 retval
= DoSuperMethodA(cl
, obj
, (Msg
)msg
);
126 struct Knob_DATA
*data
= INST_DATA(cl
, obj
);
129 SetFont(&rp
,_font(obj
));
134 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
141 IPTR
Knob__MUIM_Cleanup(struct IClass
*cl
, Object
*obj
, struct MUIP_Cleanup
*msg
)
143 struct Knob_DATA
*data
= INST_DATA(cl
, obj
);
145 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
147 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
150 /**************************************************************************
152 **************************************************************************/
153 IPTR
Knob__MUIM_AskMinMax(struct IClass
*cl
, Object
*obj
, struct MUIP_AskMinMax
*msg
)
155 //struct Knob_DATA *data = INST_DATA(cl, obj);
157 DoSuperMethodA(cl
, obj
, (Msg
)msg
);
159 msg
->MinMaxInfo
->MinWidth
+= TOTAL_WIDTH
;
160 msg
->MinMaxInfo
->MinHeight
+= TOTAL_HEIGHT
;
161 msg
->MinMaxInfo
->DefWidth
+= TOTAL_WIDTH
;
162 msg
->MinMaxInfo
->DefHeight
+= TOTAL_HEIGHT
;
163 msg
->MinMaxInfo
->MaxWidth
+= TOTAL_WIDTH
;
164 msg
->MinMaxInfo
->MaxHeight
+= TOTAL_HEIGHT
;
169 static void DrawNeedle(Object
*obj
, struct RastPort
*rp
, LONG x1
, LONG y1
,
170 LONG x2
, LONG y2
, double angle
, BOOL clear
)
172 LONG cx
= (x1
+ x2
) / 2;
173 LONG cy
= (y1
+ y2
) / 2;
174 LONG rx
= cx
- x1
- 4;
175 LONG ry
= cy
- y1
- 4;
180 if ((angle
< 0.0) | (angle
> 270.0)) angle
= 0.0;
181 angle
= 270.0 - 45.0 - angle
;
183 a
= cx
+ (LONG
)(cos(angle
* 3.14159265358979323846 / 180.0) * rx
);
184 b
= cy
- (LONG
)(sin(angle
* 3.14159265358979323846 / 180.0) * ry
);
188 SetAPen(rp
, _pens(obj
)[MPEN_HALFSHINE
]);
189 RectFill(rp
, a
- 1, b
- 1, a
+ 1, b
+ 1);
193 SetAPen(rp
, _pens(obj
)[MPEN_SHADOW
]);
194 Move(rp
, a
, b
- 1); Draw(rp
, a
- 1, b
);
195 SetAPen(rp
, _pens(obj
)[MPEN_HALFSHADOW
]);
196 Move(rp
, a
- 1, b
- 1); Draw(rp
, a
, b
);
197 SetAPen(rp
, _pens(obj
)[MPEN_SHINE
]);
198 Move(rp
, a
+ 1, b
); Draw(rp
, a
, b
+ 1);
199 SetAPen(rp
, _pens(obj
)[MPEN_HALFSHINE
]);
200 WritePixel(rp
, a
+ 1, b
- 1);
201 WritePixel(rp
, a
+ 1, b
+ 1);
202 WritePixel(rp
, a
- 1, b
+ 1);
208 /**************************************************************************
210 **************************************************************************/
211 IPTR
Knob__MUIM_Draw(struct IClass
*cl
, Object
*obj
, struct MUIP_Draw
*msg
)
213 struct Knob_DATA
*data
= INST_DATA(cl
, obj
);
217 DoSuperMethodA(cl
,obj
,(Msg
)msg
);
219 if (!(msg
->flags
& (MADF_DRAWOBJECT
| MADF_DRAWUPDATE
)))
229 if (msg
->flags
& MADF_DRAWOBJECT
)
231 /* Transparent edges */
233 DoMethod(obj
, MUIM_DrawParentBackground
, x1
, y1
, 2, 1, x1
, y1
, 0);
234 DoMethod(obj
, MUIM_DrawParentBackground
, x1
, y1
+ 1, 1, 1, x1
, y1
+ 1, 0);
236 DoMethod(obj
, MUIM_DrawParentBackground
, x2
- 1, y1
, 2, 1, x2
- 1, y1
, 0);
237 DoMethod(obj
, MUIM_DrawParentBackground
, x2
, y1
+ 1, 1, 1, x2
, y1
+ 1, 0);
239 DoMethod(obj
, MUIM_DrawParentBackground
, x1
, y2
, 2, 1, x1
, y2
, 0);
240 DoMethod(obj
, MUIM_DrawParentBackground
, x1
, y2
- 1, 1, 1, x1
, y2
- 1, 0);
242 DoMethod(obj
, MUIM_DrawParentBackground
, x2
- 1, y2
, 2, 1, x2
- 1, y2
, 0);
243 DoMethod(obj
, MUIM_DrawParentBackground
, x2
, y2
- 1, 1, 1, x2
, y2
- 1, 0);
247 SetABPenDrMd(rp
, _pens(obj
)[MPEN_SHINE
], 0, JAM1
);
248 Move(rp
, x1
+ 1, y2
- 1);
249 Draw(rp
, x1
, y2
- 2);
250 Draw(rp
, x1
, y1
+ 2);
251 Draw(rp
, x1
+ 2, y1
);
252 Draw(rp
, x2
- 2, y1
);
253 Draw(rp
, x2
- 1, y1
+ 1);
255 SetAPen(rp
, _pens(obj
)[MPEN_SHADOW
]);
256 Move(rp
, x2
, y1
+ 2);
257 Draw(rp
, x2
, y2
- 2);
258 Draw(rp
, x2
- 2, y2
);
259 Draw(rp
, x1
+ 2, y2
);
261 SetAPen(rp
, _pens(obj
)[MPEN_HALFSHINE
]);
262 Move(rp
, x1
+ 1, y2
- 2);
263 Draw(rp
, x1
+ 1, y1
+ 2);
264 Draw(rp
, x1
+ 2, y1
+ 1);
265 Draw(rp
, x2
- 2, y1
+ 1);
267 SetAPen(rp
, _pens(obj
)[MPEN_HALFSHADOW
]);
268 Move(rp
, x2
- 1, y1
+ 2);
269 Draw(rp
, x2
- 1, y2
- 2);
270 Draw(rp
, x2
- 2, y2
- 1);
271 Draw(rp
, x1
+ 2, y2
- 1);
275 x1
+= OUTERFRAME_X
; x2
-= OUTERFRAME_X
;
276 y1
+= OUTERFRAME_X
; y2
-= OUTERFRAME_Y
;
278 SetAPen(rp
, _pens(obj
)[MPEN_HALFSHINE
]);
279 RectFill(rp
, x1
, y1
, x2
, y1
+ BORDERSIZE_Y
- 1);
280 RectFill(rp
, x1
, y1
+ BORDERSIZE_Y
, x1
+ BORDERSIZE_X
- 1, y2
);
281 RectFill(rp
, x1
+ BORDERSIZE_X
- 1, y2
- BORDERSIZE_Y
+ 1, x2
, y2
);
282 RectFill(rp
, x2
- BORDERSIZE_X
+ 1, y1
+ BORDERSIZE_Y
, x2
, y2
- BORDERSIZE_Y
);
286 x1
+= BORDERSIZE_X
; x2
-= BORDERSIZE_X
;
287 y1
+= BORDERSIZE_Y
; y2
= y1
+ KNOB_HEIGHT
-1;
292 static const UBYTE pen_mapping
[] =
294 MPEN_HALFSHINE
, MPEN_HALFSHADOW
, MPEN_SHADOW
, MPEN_SHINE
298 WORD x
= 0, y
= 0, count
;
300 for(rleptr
= knob_rle
; ;)
303 count
= (rle
>> 4) + 1;
304 SetAPen(_rp(obj
), _pens(obj
)[pen_mapping
[rle
& 15]]);
305 RectFill(_rp(obj
), x1
+ x
, y1
+ y
, x1
+ x
+ count
- 1, y1
+ y
);
311 if (y
>= KNOB_HEIGHT
) break;
316 /* Knob-Label spacing */
320 SetAPen(rp
, _pens(obj
)[MPEN_HALFSHINE
]);
321 RectFill(rp
, x1
, y1
, x2
, y1
+ KNOB_LABEL_SPACING
- 1);
325 y1
+= KNOB_LABEL_SPACING
;
326 y2
= _mbottom(obj
) - OUTERFRAME_Y
- BORDERSIZE_Y
;
328 SetAPen(rp
, _pens(obj
)[MPEN_HALFSHINE
]);
329 Move(rp
, x1
, y1
); Draw(rp
, x1
+ 1, y1
); Draw(rp
, x1
, y1
+ 1);
330 Move(rp
, x2
, y1
); Draw(rp
, x2
- 1, y1
); Draw(rp
, x2
, y1
+ 1);
331 Move(rp
, x1
, y2
); Draw(rp
, x1
+ 1, y2
); Draw(rp
, x1
, y2
- 1);
332 Move(rp
, x2
, y2
); Draw(rp
, x2
- 1, y2
); Draw(rp
, x2
, y2
- 1);
334 SetAPen(rp
, _pens(obj
)[MPEN_HALFSHADOW
]);
335 Move(rp
, x1
+ 1, y2
- 1);
336 Draw(rp
, x1
, y2
- 2);
337 Draw(rp
, x1
, y1
+ 2);
338 Draw(rp
, x1
+ 2, y1
);
339 Draw(rp
, x2
- 2, y1
);
340 Draw(rp
, x2
- 1, y1
+ 1);
342 SetAPen(rp
, _pens(obj
)[MPEN_SHINE
]);
343 Move(rp
, x2
, y1
+ 2);
344 Draw(rp
, x2
, y2
- 2);
345 Draw(rp
, x2
- 2, y2
);
346 Draw(rp
, x1
+ 2, y2
);
348 SetAPen(rp
, _pens(obj
)[MPEN_SHADOW
]);
349 RectFill(rp
, x1
+ 1, y1
+ 2, x1
+ 1, y2
- 2);
350 RectFill(rp
, x2
- 1, y1
+ 2, x2
- 1, y2
- 2);
351 RectFill(rp
, x1
+ 2, y1
+ 1, x2
- 2, y1
+ 1);
352 RectFill(rp
, x1
+ 2, y2
- 1, x2
- 2, y2
- 1);
356 RectFill(rp
, x1
+ 2, y1
+2, x2
- 2, y2
- 2);
360 x1
= _mleft(obj
) + OUTERFRAME_X
+ BORDERSIZE_X
;
361 x2
= _mright(obj
) - OUTERFRAME_X
- BORDERSIZE_X
;
362 y1
= _mtop(obj
) + OUTERFRAME_Y
+ BORDERSIZE_Y
;
363 y2
= y1
+ KNOB_HEIGHT
- 1;
365 if (msg
->flags
& MADF_DRAWUPDATE
)
367 DrawNeedle(obj
, rp
, x1
, y1
, x2
, y2
, data
->prevangle
, TRUE
);
370 data
->prevangle
= (double)DoMethod(obj
, MUIM_Numeric_ValueToScale
, 0, 270);
372 DrawNeedle(obj
, rp
, x1
, y1
, x2
, y2
, data
->prevangle
, FALSE
);
377 /**************************************************************************
379 **************************************************************************/
380 IPTR
Knob__MUIM_HandleEvent(struct IClass
*cl
, Object
*obj
, struct MUIP_HandleEvent
*msg
)
382 struct Knob_DATA
*data
= INST_DATA(cl
, obj
);
389 switch(msg
->imsg
->Class
)
391 case IDCMP_MOUSEBUTTONS
:
392 switch(msg
->imsg
->Code
)
395 if (_between(_left(obj
), msg
->imsg
->MouseX
, _right(obj
)) &&
396 _between(_top(obj
), msg
->imsg
->MouseY
, _bottom(obj
)))
398 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
399 data
->ehn
.ehn_Events
|= IDCMP_MOUSEMOVE
;
400 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
409 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
410 data
->ehn
.ehn_Events
&= ~IDCMP_MOUSEMOVE
;
411 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
415 } /* switch(msg->imsg->Code) */
418 case IDCMP_MOUSEMOVE
:
421 WORD x1
, y1
, x2
, y2
, cx
, cy
, dx
, dy
;
424 x1
= _mleft(obj
) + OUTERFRAME_X
+ BORDERSIZE_X
;
425 x2
= _mright(obj
) - OUTERFRAME_X
- BORDERSIZE_X
;
426 y1
= _mtop(obj
) + OUTERFRAME_Y
+ BORDERSIZE_Y
;
427 y2
= y1
+ KNOB_HEIGHT
- 1;
430 dx
= msg
->imsg
->MouseX
- cx
;
431 dy
= cy
- msg
->imsg
->MouseY
;
433 angle
= 180.0 - 45.0 + 180.0 * atan2((double)dx
, (double)dy
) / 3.14159265358979323846;
434 if (angle
< 0.0) angle
= 0.0; else if (angle
> 270.0) angle
= 270.0;
436 val
= DoMethod(obj
, MUIM_Numeric_ScaleToValue
, 0, 270, (LONG
)angle
);
437 set(obj
, MUIA_Numeric_Value
, val
);
442 } /* switch(msg->imsg->Class) */
447 #if ZUNE_BUILTIN_KNOB
448 BOOPSI_DISPATCHER(IPTR
, Knob_Dispatcher
, cl
, obj
, msg
)
450 switch (msg
->MethodID
)
452 case OM_NEW
: return Knob__OM_NEW(cl
, obj
, (struct opSet
*)msg
);
453 case MUIM_Setup
: return Knob__MUIM_Setup(cl
, obj
, (struct MUIP_Setup
*)msg
);
454 case MUIM_Cleanup
: return Knob__MUIM_Cleanup(cl
, obj
, (struct MUIP_Cleanup
*)msg
);
455 case MUIM_AskMinMax
: return Knob__MUIM_AskMinMax(cl
, obj
, (struct MUIP_AskMinMax
*)msg
);
456 case MUIM_Draw
: return Knob__MUIM_Draw(cl
, obj
, (struct MUIP_Draw
*)msg
);
457 case MUIM_HandleEvent
: return Knob__MUIM_HandleEvent(cl
, obj
, (struct MUIP_HandleEvent
*)msg
);
458 default: return DoSuperMethodA(cl
, obj
, msg
);
461 BOOPSI_DISPATCHER_END
463 const struct __MUIBuiltinClass _MUI_Knob_desc
=
467 sizeof(struct Knob_DATA
),
468 (void*)Knob_Dispatcher
470 #endif /* ZUNE_BUILTIN_KNOB */