Tabs to spaces, more consistent formatting.
[AROS.git] / workbench / libs / muimaster / classes / levelmeter.c
blob326439852c08079d003f038e23405d27527296aa
1 /*
2 Copyright © 2002-2003, The AROS Development Team. All rights reserved.
3 $Id$
4 */
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>
17 #include <string.h>
18 #include <stdio.h>
19 #include <math.h>
21 #include "mui.h"
22 #include "muimaster_intern.h"
23 #include "support.h"
24 #include "support_classes.h"
25 #include "prefs.h"
26 #include "debug.h"
27 #include "levelmeter_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 3
42 #define BORDERSIZE_Y 2
43 #define BORDERSIZE_W (BORDERSIZE_X * 2)
44 #define BORDERSIZE_H (BORDERSIZE_Y * 2)
46 #define LEVEL_LABEL_SPACING 2
48 #define LEVEL_WIDTH 39
49 #define LEVEL_HEIGHT 20
51 #define LABEL_HEIGHT 8
53 #define TOTAL_WIDTH OUTERFRAME_W + BORDERSIZE_W + INNERFRAME_W + LEVEL_WIDTH
54 #define TOTAL_HEIGHT OUTERFRAME_H + BORDERSIZE_H + INNERFRAME_H * 2 \
55 + LEVEL_HEIGHT + LEVEL_LABEL_SPACING + LABEL_HEIGHT
57 IPTR Levelmeter__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
59 obj = (Object *) DoSuperNewTags
60 (cl, obj, NULL,
61 MUIA_FillArea, FALSE, TAG_MORE, (IPTR) msg->ops_AttrList);
63 if (obj)
65 struct Levelmeter_DATA *data = INST_DATA(cl, obj);
67 data->levelbgpen = -1;
70 return (IPTR) obj;
73 IPTR Levelmeter__MUIM_Setup(struct IClass *cl, Object *obj,
74 struct MUIP_Setup *msg)
76 struct Levelmeter_DATA *data = INST_DATA(cl, obj);
77 //struct RastPort rp;
78 IPTR retval;
80 retval = DoSuperMethodA(cl, obj, (Msg) msg);
81 if (retval)
83 #if 0
84 InitRastPort(&rp);
85 SetFont(&rp, _font(obj));
87 DeinitRastPort(&rp);
88 #endif
89 data->levelbgpen = ObtainBestPen(_screen(obj)->ViewPort.ColorMap,
90 0x4b4b4b4b,
91 0x39393939,
92 0x93939393,
93 OBP_FailIfBad, FALSE, OBP_Precision, PRECISION_GUI, TAG_DONE);
96 return retval;
99 IPTR Levelmeter__MUIM_Cleanup(struct IClass *cl, Object *obj,
100 struct MUIP_Cleanup *msg)
102 struct Levelmeter_DATA *data = INST_DATA(cl, obj);
104 if (data->levelbgpen != -1)
106 ReleasePen(_screen(obj)->ViewPort.ColorMap, data->levelbgpen);
107 data->levelbgpen = -1;
110 return DoSuperMethodA(cl, obj, (Msg) msg);
113 /**************************************************************************
114 MUIM_AskMinMax
115 **************************************************************************/
116 IPTR Levelmeter__MUIM_AskMinMax(struct IClass *cl, Object *obj,
117 struct MUIP_AskMinMax *msg)
119 //struct Levelmeter_DATA *data = INST_DATA(cl, obj);
121 DoSuperMethodA(cl, obj, (Msg) msg);
123 msg->MinMaxInfo->MinWidth += TOTAL_WIDTH;
124 msg->MinMaxInfo->MinHeight += TOTAL_HEIGHT;
125 msg->MinMaxInfo->DefWidth += TOTAL_WIDTH;
126 msg->MinMaxInfo->DefHeight += TOTAL_HEIGHT;
127 msg->MinMaxInfo->MaxWidth += TOTAL_WIDTH;
128 msg->MinMaxInfo->MaxHeight += TOTAL_HEIGHT;
130 return TRUE;
133 static void DrawScale(struct RastPort *rp, LONG x1, LONG y1, LONG x2,
134 LONG y2, LONG pen)
136 LONG cx = (x1 + x2 + 1) / 2;
137 LONG cy = y2 - 1;
138 LONG rx = cx - x1 - 1;
139 LONG ry = cy - y1 - 1;
140 LONG a, b, g;
142 SetABPenDrMd(rp, pen, 0, JAM1);
144 for (g = 0; g <= 180; g += 15)
146 double angle = ((double)g) * 3.14159265358979323846 / 180.0;
148 a = cx + (LONG) (cos(angle) * rx);
149 b = cy - (LONG) (sin(angle) * ry);
151 WritePixel(rp, a, b);
153 if ((g % 45) == 0)
155 static WORD offtable[][2] = {
156 {-1, 0},
157 {-1, 1},
158 {0, 1},
159 {1, 1},
160 {1, 0}
163 WritePixel(rp, a + offtable[g / 45][0],
164 b + offtable[g / 45][1]);
171 static void DrawNeedle(struct RastPort *rp, LONG x1, LONG y1, LONG x2,
172 LONG y2, double angle, LONG pen)
174 LONG cx = (x1 + x2 + 1) / 2;
175 LONG cy = y2 - 1;
176 LONG rx = cx - x1 - 4;
177 LONG ry = cy - y1 - 4;
178 LONG a, b;
180 SetABPenDrMd(rp, pen, 0, JAM1);
181 Move(rp, cx, cy);
183 if ((angle < 0.0) | (angle > 180.0))
184 angle = 0.0;
185 angle = 180.0 - angle;
187 a = cx + (LONG) (cos(angle * 3.14159265358979323846 / 180.0) * rx);
188 b = cy - (LONG) (sin(angle * 3.14159265358979323846 / 180.0) * ry);
190 Draw(rp, a, b);
194 /**************************************************************************
195 MUIM_Draw
196 **************************************************************************/
197 IPTR Levelmeter__MUIM_Draw(struct IClass *cl, Object *obj,
198 struct MUIP_Draw *msg)
200 struct Levelmeter_DATA *data = INST_DATA(cl, obj);
201 struct RastPort *rp;
202 WORD x1, y1, x2, y2;
204 DoSuperMethodA(cl, obj, (Msg) msg);
206 if (!(msg->flags & (MADF_DRAWOBJECT | MADF_DRAWUPDATE)))
207 return FALSE;
209 x1 = _mleft(obj);
210 y1 = _mtop(obj);
211 x2 = _mright(obj);
212 y2 = _mbottom(obj);
214 rp = _rp(obj);
216 if (msg->flags & MADF_DRAWOBJECT)
218 /* Transparent edges */
220 DoMethod(obj, MUIM_DrawParentBackground, x1, y1, 2, 1, x1, y1, 0);
221 DoMethod(obj, MUIM_DrawParentBackground, x1, y1 + 1, 1, 1, x1,
222 y1 + 1, 0);
224 DoMethod(obj, MUIM_DrawParentBackground, x2 - 1, y1, 2, 1, x2 - 1,
225 y1, 0);
226 DoMethod(obj, MUIM_DrawParentBackground, x2, y1 + 1, 1, 1, x2,
227 y1 + 1, 0);
229 DoMethod(obj, MUIM_DrawParentBackground, x1, y2, 2, 1, x1, y2, 0);
230 DoMethod(obj, MUIM_DrawParentBackground, x1, y2 - 1, 1, 1, x1,
231 y2 - 1, 0);
233 DoMethod(obj, MUIM_DrawParentBackground, x2 - 1, y2, 2, 1, x2 - 1,
234 y2, 0);
235 DoMethod(obj, MUIM_DrawParentBackground, x2, y2 - 1, 1, 1, x2,
236 y2 - 1, 0);
238 /* Outer frame */
240 SetABPenDrMd(rp, _pens(obj)[MPEN_SHINE], 0, JAM1);
241 Move(rp, x1 + 1, y2 - 1);
242 Draw(rp, x1, y2 - 2);
243 Draw(rp, x1, y1 + 2);
244 Draw(rp, x1 + 2, y1);
245 Draw(rp, x2 - 2, y1);
246 Draw(rp, x2 - 1, y1 + 1);
248 SetAPen(rp, _pens(obj)[MPEN_SHADOW]);
249 Move(rp, x2, y1 + 2);
250 Draw(rp, x2, y2 - 2);
251 Draw(rp, x2 - 2, y2);
252 Draw(rp, x1 + 2, y2);
254 SetAPen(rp, _pens(obj)[MPEN_HALFSHINE]);
255 Move(rp, x1 + 1, y2 - 2);
256 Draw(rp, x1 + 1, y1 + 2);
257 Draw(rp, x1 + 2, y1 + 1);
258 Draw(rp, x2 - 2, y1 + 1);
260 SetAPen(rp, _pens(obj)[MPEN_HALFSHADOW]);
261 Move(rp, x2 - 1, y1 + 2);
262 Draw(rp, x2 - 1, y2 - 2);
263 Draw(rp, x2 - 2, y2 - 1);
264 Draw(rp, x1 + 2, y2 - 1);
266 /* Border */
268 x1 += OUTERFRAME_X;
269 x2 -= OUTERFRAME_X;
270 y1 += OUTERFRAME_X;
271 y2 -= OUTERFRAME_Y;
273 SetAPen(rp, _pens(obj)[MPEN_HALFSHINE]);
274 RectFill(rp, x1, y1, x2, y1 + BORDERSIZE_Y - 1);
275 RectFill(rp, x1, y1 + BORDERSIZE_Y, x1 + BORDERSIZE_X - 1, y2);
276 RectFill(rp, x1 + BORDERSIZE_X - 1, y2 - BORDERSIZE_Y + 1, x2, y2);
277 RectFill(rp, x2 - BORDERSIZE_X + 1, y1 + BORDERSIZE_Y, x2,
278 y2 - BORDERSIZE_Y);
280 /* Inner Frame */
282 x1 += BORDERSIZE_X;
283 x2 -= BORDERSIZE_X;
284 y1 += BORDERSIZE_Y;
285 y2 = y1 + LEVEL_HEIGHT + INNERFRAME_H - 1;
287 Move(rp, x1, y1);
288 Draw(rp, x1 + 2, y1);
289 Draw(rp, x1, y1 + 2);
290 Draw(rp, x1, y1 + 1);
292 Move(rp, x2, y1);
293 Draw(rp, x2 - 2, y1);
294 Draw(rp, x2, y1 + 2);
295 Draw(rp, x2, y1 + 1);
297 Move(rp, x1, y2);
298 Draw(rp, x1 + 2, y2);
299 Draw(rp, x1, y2 - 2);
300 Draw(rp, x1, y2 - 1);
302 Move(rp, x2, y2);
303 Draw(rp, x2 - 2, y2);
304 Draw(rp, x2, y2 - 2);
305 Draw(rp, x2, y2 - 1);
307 SetAPen(rp, _pens(obj)[MPEN_HALFSHADOW]);
308 Move(rp, x1 + 2, y2 - 1);
309 Draw(rp, x1, y2 - 3);
310 Draw(rp, x1, y1 + 3);
311 Draw(rp, x1 + 3, y1);
312 Draw(rp, x2 - 3, y1);
313 Draw(rp, x2 - 1, y1 + 2);
315 SetAPen(rp, _pens(obj)[MPEN_SHINE]);
316 Move(rp, x2, y1 + 3);
317 Draw(rp, x2, y2 - 3);
318 Draw(rp, x2 - 3, y2);
319 Draw(rp, x1 + 3, y2);
321 SetAPen(rp, _pens(obj)[MPEN_SHADOW]);
322 Move(rp, x1 + 3, y1 + 1);
323 Draw(rp, x2 - 3, y1 + 1);
324 Move(rp, x1 + 1, y1 + 3);
325 Draw(rp, x1 + 1, y2 - 3);
326 Move(rp, x1 + 3, y2 - 1);
327 Draw(rp, x2 - 3, y2 - 1);
328 Move(rp, x2 - 1, y1 + 3), Draw(rp, x2 - 1, y2 - 3);
330 /* Levelmeter bg */
332 x1 += INNERFRAME_X;
333 x2 -= INNERFRAME_X;
334 y1 += INNERFRAME_Y;
335 y2 -= INNERFRAME_Y;
337 SetAPen(rp, data->levelbgpen);
338 RectFill(rp, x1 + 1, y1, x2 - 1, y1);
339 RectFill(rp, x1, y1 + 1, x2, y2 - 1);
340 RectFill(rp, x1 + 1, y2, x2 - 1, y2);
342 SetAPen(rp, _pens(obj)[MPEN_SHADOW]);
343 WritePixel(rp, x1, y1);
344 WritePixel(rp, x2, y1);
345 WritePixel(rp, x1, y2);
346 WritePixel(rp, x2, y2);
348 /* Levelmeter scale */
350 DrawScale(rp, x1, y1, x2, y2, _pens(obj)[MPEN_SHINE]);
352 /* Level-Label spacing */
354 x1 -= INNERFRAME_X;
355 x2 += INNERFRAME_X;
356 y1 = y2 + INNERFRAME_Y + 1;
358 SetAPen(rp, _pens(obj)[MPEN_HALFSHINE]);
359 RectFill(rp, x1, y1, x2, y1 + LEVEL_LABEL_SPACING - 1);
361 /* Label Frame */
363 y1 += LEVEL_LABEL_SPACING;
364 y2 = _mbottom(obj) - OUTERFRAME_Y - BORDERSIZE_Y;
366 SetAPen(rp, _pens(obj)[MPEN_HALFSHINE]);
367 Move(rp, x1, y1);
368 Draw(rp, x1 + 1, y1);
369 Draw(rp, x1, y1 + 1);
370 Move(rp, x2, y1);
371 Draw(rp, x2 - 1, y1);
372 Draw(rp, x2, y1 + 1);
373 Move(rp, x1, y2);
374 Draw(rp, x1 + 1, y2);
375 Draw(rp, x1, y2 - 1);
376 Move(rp, x2, y2);
377 Draw(rp, x2 - 1, y2);
378 Draw(rp, x2, y2 - 1);
380 SetAPen(rp, _pens(obj)[MPEN_HALFSHADOW]);
381 Move(rp, x1 + 1, y2 - 1);
382 Draw(rp, x1, y2 - 2);
383 Draw(rp, x1, y1 + 2);
384 Draw(rp, x1 + 2, y1);
385 Draw(rp, x2 - 2, y1);
386 Draw(rp, x2 - 1, y1 + 1);
388 SetAPen(rp, _pens(obj)[MPEN_SHINE]);
389 Move(rp, x2, y1 + 2);
390 Draw(rp, x2, y2 - 2);
391 Draw(rp, x2 - 2, y2);
392 Draw(rp, x1 + 2, y2);
394 SetAPen(rp, _pens(obj)[MPEN_SHADOW]);
395 RectFill(rp, x1 + 1, y1 + 2, x1 + 1, y2 - 2);
396 RectFill(rp, x2 - 1, y1 + 2, x2 - 1, y2 - 2);
397 RectFill(rp, x1 + 2, y1 + 1, x2 - 2, y1 + 1);
398 RectFill(rp, x1 + 2, y2 - 1, x2 - 2, y2 - 1);
400 /* Label Bg */
402 RectFill(rp, x1 + 2, y1 + 2, x2 - 2, y2 - 2);
406 x1 = _mleft(obj) + OUTERFRAME_X + BORDERSIZE_X + INNERFRAME_X;
407 x2 = _mright(obj) - OUTERFRAME_X - BORDERSIZE_X - INNERFRAME_X;
408 y1 = _mtop(obj) + OUTERFRAME_Y + BORDERSIZE_Y + INNERFRAME_Y;
409 y2 = y1 + LEVEL_HEIGHT - 1;
411 if (msg->flags & MADF_DRAWUPDATE)
413 DrawNeedle(rp, x1, y1, x2, y2, data->prevangle, data->levelbgpen);
416 data->prevangle =
417 (double)DoMethod(obj, MUIM_Numeric_ValueToScale, 0, 180);
419 DrawNeedle(rp, x1, y1, x2, y2, data->prevangle, _pens(obj)[MPEN_SHINE]);
421 return TRUE;
424 #if ZUNE_BUILTIN_LEVELMETER
425 BOOPSI_DISPATCHER(IPTR, Levelmeter_Dispatcher, cl, obj, msg)
427 switch (msg->MethodID)
429 case OM_NEW:
430 return Levelmeter__OM_NEW(cl, obj, (struct opSet *)msg);
431 case MUIM_Setup:
432 return Levelmeter__MUIM_Setup(cl, obj, (struct MUIP_Setup *)msg);
433 case MUIM_Cleanup:
434 return Levelmeter__MUIM_Cleanup(cl, obj,
435 (struct MUIP_Cleanup *)msg);
436 case MUIM_AskMinMax:
437 return Levelmeter__MUIM_AskMinMax(cl, obj,
438 (struct MUIP_AskMinMax *)msg);
439 case MUIM_Draw:
440 return Levelmeter__MUIM_Draw(cl, obj, (struct MUIP_Draw *)msg);
441 default:
442 return DoSuperMethodA(cl, obj, msg);
445 BOOPSI_DISPATCHER_END
447 const struct __MUIBuiltinClass _MUI_Levelmeter_desc =
449 MUIC_Levelmeter,
450 MUIC_Numeric,
451 sizeof(struct Levelmeter_DATA),
452 (void *) Levelmeter_Dispatcher
454 #endif /* ZUNE_BUILTIN_LEVELMETER */