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 \
55 + KNOB_HEIGHT + KNOB_LABEL_SPACING + LABEL_HEIGHT
63 #define RLE_REP(count, val) (((count - 1) << 4) | val)
65 static const UBYTE knob_rle
[] = /* hand-encoded, BTW ;-) */
67 RLE_REP(8,0), RLE_REP(9,1), RLE_REP(8,0),
68 RLE_REP(6,0), RLE_REP(2,1), RLE_REP(9,2), RLE_REP(2,1), RLE_REP(6,0),
69 RLE_REP(5,0), 1, RLE_REP(2,2), RLE_REP(9,3), RLE_REP(2,2), 1, RLE_REP(5,0),
70 RLE_REP(4,0), 1, 2, RLE_REP(13,3), 2, 1, RLE_REP(4,0),
71 RLE_REP(3,0), 1, 2, RLE_REP(3,3), RLE_REP(9,0), RLE_REP(3,3), 2, 3, RLE_REP(3,0),
72 RLE_REP(2,0), 1, 2, RLE_REP(2,3), RLE_REP(13,0), 3, 1, 2, 3, RLE_REP(2,0),
73 0, 1, 2, RLE_REP(2,3), RLE_REP(15,0), RLE_REP(2,1), 2, 3, 0,
74 0, 1, 2, RLE_REP(2,3), RLE_REP(15,0), RLE_REP(2,1), 2, 3, 0,
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 1, 2, RLE_REP(2,3), 0, RLE_REP(16,0), RLE_REP(2,1), 2, 3,
84 0, 1, 2, RLE_REP(2,3), RLE_REP(15,0), RLE_REP(2,1), 2, 3, 0,
85 0, 1, 2, RLE_REP(2,3), RLE_REP(15,0), RLE_REP(2,1), 2, 3, 0,
86 RLE_REP(2,0), 1, 2, RLE_REP(2,3), RLE_REP(13,0), RLE_REP(2,1), 2, 3, RLE_REP(2,0),
87 RLE_REP(3,0), 1, 2, RLE_REP(3,1), RLE_REP(9,0), RLE_REP(3,1), 2, 3, RLE_REP(3,0),
88 RLE_REP(4,0), 3, 2, RLE_REP(13,1), 2, 3, RLE_REP(4,0),
89 RLE_REP(5,0), 3, RLE_REP(2,2), RLE_REP(9,1), RLE_REP(2,2), 3, RLE_REP(5,0),
90 RLE_REP(6,0), RLE_REP(2,3), RLE_REP(9,2), RLE_REP(2,3), RLE_REP(6,0),
91 RLE_REP(8,0), RLE_REP(9,3), RLE_REP(8,0),
95 IPTR
Knob__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
97 obj
= (Object
*) DoSuperNewTags
99 MUIA_FillArea
, FALSE
, TAG_MORE
, (IPTR
) msg
->ops_AttrList
);
103 struct Knob_DATA
*data
= INST_DATA(cl
, obj
);
105 data
->ehn
.ehn_Events
= IDCMP_MOUSEBUTTONS
;
106 data
->ehn
.ehn_Priority
= 0;
107 data
->ehn
.ehn_Flags
= 0;
108 data
->ehn
.ehn_Object
= obj
;
109 data
->ehn
.ehn_Class
= cl
;
116 IPTR
Knob__MUIM_Setup(struct IClass
*cl
, Object
*obj
,
117 struct MUIP_Setup
*msg
)
119 //struct RastPort rp;
122 retval
= DoSuperMethodA(cl
, obj
, (Msg
) msg
);
125 struct Knob_DATA
*data
= INST_DATA(cl
, obj
);
128 SetFont(&rp
, _font(obj
));
133 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
,
141 IPTR
Knob__MUIM_Cleanup(struct IClass
*cl
, Object
*obj
,
142 struct MUIP_Cleanup
*msg
)
144 struct Knob_DATA
*data
= INST_DATA(cl
, obj
);
146 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
) & data
->ehn
);
148 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
151 /**************************************************************************
153 **************************************************************************/
154 IPTR
Knob__MUIM_AskMinMax(struct IClass
*cl
, Object
*obj
,
155 struct MUIP_AskMinMax
*msg
)
157 //struct Knob_DATA *data = INST_DATA(cl, obj);
159 DoSuperMethodA(cl
, obj
, (Msg
) msg
);
161 msg
->MinMaxInfo
->MinWidth
+= TOTAL_WIDTH
;
162 msg
->MinMaxInfo
->MinHeight
+= TOTAL_HEIGHT
;
163 msg
->MinMaxInfo
->DefWidth
+= TOTAL_WIDTH
;
164 msg
->MinMaxInfo
->DefHeight
+= TOTAL_HEIGHT
;
165 msg
->MinMaxInfo
->MaxWidth
+= TOTAL_WIDTH
;
166 msg
->MinMaxInfo
->MaxHeight
+= TOTAL_HEIGHT
;
171 static void DrawNeedle(Object
*obj
, struct RastPort
*rp
, LONG x1
, LONG y1
,
172 LONG x2
, LONG y2
, double angle
, BOOL clear
)
174 LONG cx
= (x1
+ x2
) / 2;
175 LONG cy
= (y1
+ y2
) / 2;
176 LONG rx
= cx
- x1
- 4;
177 LONG ry
= cy
- y1
- 4;
182 if ((angle
< 0.0) | (angle
> 270.0))
184 angle
= 270.0 - 45.0 - angle
;
186 a
= cx
+ (LONG
) (cos(angle
* 3.14159265358979323846 / 180.0) * rx
);
187 b
= cy
- (LONG
) (sin(angle
* 3.14159265358979323846 / 180.0) * ry
);
191 SetAPen(rp
, _pens(obj
)[MPEN_HALFSHINE
]);
192 RectFill(rp
, a
- 1, b
- 1, a
+ 1, b
+ 1);
196 SetAPen(rp
, _pens(obj
)[MPEN_SHADOW
]);
199 SetAPen(rp
, _pens(obj
)[MPEN_HALFSHADOW
]);
200 Move(rp
, a
- 1, b
- 1);
202 SetAPen(rp
, _pens(obj
)[MPEN_SHINE
]);
205 SetAPen(rp
, _pens(obj
)[MPEN_HALFSHINE
]);
206 WritePixel(rp
, a
+ 1, b
- 1);
207 WritePixel(rp
, a
+ 1, b
+ 1);
208 WritePixel(rp
, a
- 1, b
+ 1);
214 /**************************************************************************
216 **************************************************************************/
217 IPTR
Knob__MUIM_Draw(struct IClass
*cl
, Object
*obj
, struct MUIP_Draw
*msg
)
219 struct Knob_DATA
*data
= INST_DATA(cl
, obj
);
223 DoSuperMethodA(cl
, obj
, (Msg
) msg
);
225 if (!(msg
->flags
& (MADF_DRAWOBJECT
| MADF_DRAWUPDATE
)))
235 if (msg
->flags
& MADF_DRAWOBJECT
)
237 /* Transparent edges */
239 DoMethod(obj
, MUIM_DrawParentBackground
, x1
, y1
, 2, 1, x1
, y1
, 0);
240 DoMethod(obj
, MUIM_DrawParentBackground
, x1
, y1
+ 1, 1, 1, x1
,
243 DoMethod(obj
, MUIM_DrawParentBackground
, x2
- 1, y1
, 2, 1, x2
- 1,
245 DoMethod(obj
, MUIM_DrawParentBackground
, x2
, y1
+ 1, 1, 1, x2
,
248 DoMethod(obj
, MUIM_DrawParentBackground
, x1
, y2
, 2, 1, x1
, y2
, 0);
249 DoMethod(obj
, MUIM_DrawParentBackground
, x1
, y2
- 1, 1, 1, x1
,
252 DoMethod(obj
, MUIM_DrawParentBackground
, x2
- 1, y2
, 2, 1, x2
- 1,
254 DoMethod(obj
, MUIM_DrawParentBackground
, x2
, y2
- 1, 1, 1, x2
,
259 SetABPenDrMd(rp
, _pens(obj
)[MPEN_SHINE
], 0, JAM1
);
260 Move(rp
, x1
+ 1, y2
- 1);
261 Draw(rp
, x1
, y2
- 2);
262 Draw(rp
, x1
, y1
+ 2);
263 Draw(rp
, x1
+ 2, y1
);
264 Draw(rp
, x2
- 2, y1
);
265 Draw(rp
, x2
- 1, y1
+ 1);
267 SetAPen(rp
, _pens(obj
)[MPEN_SHADOW
]);
268 Move(rp
, x2
, y1
+ 2);
269 Draw(rp
, x2
, y2
- 2);
270 Draw(rp
, x2
- 2, y2
);
271 Draw(rp
, x1
+ 2, y2
);
273 SetAPen(rp
, _pens(obj
)[MPEN_HALFSHINE
]);
274 Move(rp
, x1
+ 1, y2
- 2);
275 Draw(rp
, x1
+ 1, y1
+ 2);
276 Draw(rp
, x1
+ 2, y1
+ 1);
277 Draw(rp
, x2
- 2, y1
+ 1);
279 SetAPen(rp
, _pens(obj
)[MPEN_HALFSHADOW
]);
280 Move(rp
, x2
- 1, y1
+ 2);
281 Draw(rp
, x2
- 1, y2
- 2);
282 Draw(rp
, x2
- 2, y2
- 1);
283 Draw(rp
, x1
+ 2, y2
- 1);
292 SetAPen(rp
, _pens(obj
)[MPEN_HALFSHINE
]);
293 RectFill(rp
, x1
, y1
, x2
, y1
+ BORDERSIZE_Y
- 1);
294 RectFill(rp
, x1
, y1
+ BORDERSIZE_Y
, x1
+ BORDERSIZE_X
- 1, y2
);
295 RectFill(rp
, x1
+ BORDERSIZE_X
- 1, y2
- BORDERSIZE_Y
+ 1, x2
, y2
);
296 RectFill(rp
, x2
- BORDERSIZE_X
+ 1, y1
+ BORDERSIZE_Y
, x2
,
304 y2
= y1
+ KNOB_HEIGHT
- 1;
309 static const UBYTE pen_mapping
[] = {
310 MPEN_HALFSHINE
, MPEN_HALFSHADOW
, MPEN_SHADOW
, MPEN_SHINE
314 WORD x
= 0, y
= 0, count
;
316 for (rleptr
= knob_rle
;;)
319 count
= (rle
>> 4) + 1;
320 SetAPen(_rp(obj
), _pens(obj
)[pen_mapping
[rle
& 15]]);
321 RectFill(_rp(obj
), x1
+ x
, y1
+ y
, x1
+ x
+ count
- 1,
328 if (y
>= KNOB_HEIGHT
)
334 /* Knob-Label spacing */
338 SetAPen(rp
, _pens(obj
)[MPEN_HALFSHINE
]);
339 RectFill(rp
, x1
, y1
, x2
, y1
+ KNOB_LABEL_SPACING
- 1);
343 y1
+= KNOB_LABEL_SPACING
;
344 y2
= _mbottom(obj
) - OUTERFRAME_Y
- BORDERSIZE_Y
;
346 SetAPen(rp
, _pens(obj
)[MPEN_HALFSHINE
]);
348 Draw(rp
, x1
+ 1, y1
);
349 Draw(rp
, x1
, y1
+ 1);
351 Draw(rp
, x2
- 1, y1
);
352 Draw(rp
, x2
, y1
+ 1);
354 Draw(rp
, x1
+ 1, y2
);
355 Draw(rp
, x1
, y2
- 1);
357 Draw(rp
, x2
- 1, y2
);
358 Draw(rp
, x2
, y2
- 1);
360 SetAPen(rp
, _pens(obj
)[MPEN_HALFSHADOW
]);
361 Move(rp
, x1
+ 1, y2
- 1);
362 Draw(rp
, x1
, y2
- 2);
363 Draw(rp
, x1
, y1
+ 2);
364 Draw(rp
, x1
+ 2, y1
);
365 Draw(rp
, x2
- 2, y1
);
366 Draw(rp
, x2
- 1, y1
+ 1);
368 SetAPen(rp
, _pens(obj
)[MPEN_SHINE
]);
369 Move(rp
, x2
, y1
+ 2);
370 Draw(rp
, x2
, y2
- 2);
371 Draw(rp
, x2
- 2, y2
);
372 Draw(rp
, x1
+ 2, y2
);
374 SetAPen(rp
, _pens(obj
)[MPEN_SHADOW
]);
375 RectFill(rp
, x1
+ 1, y1
+ 2, x1
+ 1, y2
- 2);
376 RectFill(rp
, x2
- 1, y1
+ 2, x2
- 1, y2
- 2);
377 RectFill(rp
, x1
+ 2, y1
+ 1, x2
- 2, y1
+ 1);
378 RectFill(rp
, x1
+ 2, y2
- 1, x2
- 2, y2
- 1);
382 RectFill(rp
, x1
+ 2, y1
+ 2, x2
- 2, y2
- 2);
386 x1
= _mleft(obj
) + OUTERFRAME_X
+ BORDERSIZE_X
;
387 x2
= _mright(obj
) - OUTERFRAME_X
- BORDERSIZE_X
;
388 y1
= _mtop(obj
) + OUTERFRAME_Y
+ BORDERSIZE_Y
;
389 y2
= y1
+ KNOB_HEIGHT
- 1;
391 if (msg
->flags
& MADF_DRAWUPDATE
)
393 DrawNeedle(obj
, rp
, x1
, y1
, x2
, y2
, data
->prevangle
, TRUE
);
397 (double)DoMethod(obj
, MUIM_Numeric_ValueToScale
, 0, 270);
399 DrawNeedle(obj
, rp
, x1
, y1
, x2
, y2
, data
->prevangle
, FALSE
);
404 /**************************************************************************
406 **************************************************************************/
407 IPTR
Knob__MUIM_HandleEvent(struct IClass
*cl
, Object
*obj
,
408 struct MUIP_HandleEvent
*msg
)
410 struct Knob_DATA
*data
= INST_DATA(cl
, obj
);
417 switch (msg
->imsg
->Class
)
419 case IDCMP_MOUSEBUTTONS
:
420 switch (msg
->imsg
->Code
)
423 if (_between(_left(obj
), msg
->imsg
->MouseX
, _right(obj
)) &&
424 _between(_top(obj
), msg
->imsg
->MouseY
, _bottom(obj
)))
426 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
,
428 data
->ehn
.ehn_Events
|= IDCMP_MOUSEMOVE
;
429 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
,
439 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
,
441 data
->ehn
.ehn_Events
&= ~IDCMP_MOUSEMOVE
;
442 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
,
447 } /* switch(msg->imsg->Code) */
450 case IDCMP_MOUSEMOVE
:
453 WORD x1
, y1
, x2
, y2
, cx
, cy
, dx
, dy
;
456 x1
= _mleft(obj
) + OUTERFRAME_X
+ BORDERSIZE_X
;
457 x2
= _mright(obj
) - OUTERFRAME_X
- BORDERSIZE_X
;
458 y1
= _mtop(obj
) + OUTERFRAME_Y
+ BORDERSIZE_Y
;
459 y2
= y1
+ KNOB_HEIGHT
- 1;
462 dx
= msg
->imsg
->MouseX
- cx
;
463 dy
= cy
- msg
->imsg
->MouseY
;
466 180.0 - 45.0 + 180.0 * atan2((double)dx
,
467 (double)dy
) / 3.14159265358979323846;
470 else if (angle
> 270.0)
474 DoMethod(obj
, MUIM_Numeric_ScaleToValue
, 0, 270,
476 set(obj
, MUIA_Numeric_Value
, val
);
481 } /* switch(msg->imsg->Class) */
486 #if ZUNE_BUILTIN_KNOB
487 BOOPSI_DISPATCHER(IPTR
, Knob_Dispatcher
, cl
, obj
, msg
)
489 switch (msg
->MethodID
)
492 return Knob__OM_NEW(cl
, obj
, (struct opSet
*)msg
);
494 return Knob__MUIM_Setup(cl
, obj
, (struct MUIP_Setup
*)msg
);
496 return Knob__MUIM_Cleanup(cl
, obj
, (struct MUIP_Cleanup
*)msg
);
498 return Knob__MUIM_AskMinMax(cl
, obj
, (struct MUIP_AskMinMax
*)msg
);
500 return Knob__MUIM_Draw(cl
, obj
, (struct MUIP_Draw
*)msg
);
501 case MUIM_HandleEvent
:
502 return Knob__MUIM_HandleEvent(cl
, obj
,
503 (struct MUIP_HandleEvent
*)msg
);
505 return DoSuperMethodA(cl
, obj
, msg
);
508 BOOPSI_DISPATCHER_END
510 const struct __MUIBuiltinClass _MUI_Knob_desc
=
514 sizeof(struct Knob_DATA
),
515 (void *) Knob_Dispatcher
517 #endif /* ZUNE_BUILTIN_KNOB */