Some fix for scrolling with lasso.
[tangerine.git] / workbench / libs / muimaster / classes / levelmeter.c
bloba585d4ee1e8ddb1569bb975cf4c5994ec4a534f2
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 + LEVEL_HEIGHT + LEVEL_LABEL_SPACING + LABEL_HEIGHT
56 IPTR Levelmeter__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
58 obj = (Object *)DoSuperNewTags
60 cl, obj, NULL,
61 MUIA_FillArea, FALSE,
62 TAG_MORE, (IPTR) msg->ops_AttrList
65 if (obj)
67 struct Levelmeter_DATA *data = INST_DATA(cl, obj);
69 data->levelbgpen = -1;
72 return (IPTR)obj;
75 IPTR Levelmeter__MUIM_Setup(struct IClass *cl, Object *obj, struct MUIP_Setup *msg)
77 struct Levelmeter_DATA *data = INST_DATA(cl, obj);
78 //struct RastPort rp;
79 IPTR retval;
81 retval = DoSuperMethodA(cl, obj, (Msg)msg);
82 if (retval)
84 #if 0
85 InitRastPort(&rp);
86 SetFont(&rp,_font(obj));
88 DeinitRastPort(&rp);
89 #endif
90 data->levelbgpen = ObtainBestPen(_screen(obj)->ViewPort.ColorMap,
91 0x4b4b4b4b,
92 0x39393939,
93 0x93939393,
94 OBP_FailIfBad, FALSE,
95 OBP_Precision, PRECISION_GUI,
96 TAG_DONE);
99 return retval;
102 IPTR Levelmeter__MUIM_Cleanup(struct IClass *cl, Object *obj, struct MUIP_Cleanup *msg)
104 struct Levelmeter_DATA *data = INST_DATA(cl, obj);
106 if (data->levelbgpen != -1)
108 ReleasePen(_screen(obj)->ViewPort.ColorMap, data->levelbgpen);
109 data->levelbgpen = -1;
112 return DoSuperMethodA(cl, obj, (Msg)msg);
115 /**************************************************************************
116 MUIM_AskMinMax
117 **************************************************************************/
118 IPTR Levelmeter__MUIM_AskMinMax(struct IClass *cl, Object *obj, struct MUIP_AskMinMax *msg)
120 //struct Levelmeter_DATA *data = INST_DATA(cl, obj);
122 DoSuperMethodA(cl, obj, (Msg)msg);
124 msg->MinMaxInfo->MinWidth += TOTAL_WIDTH;
125 msg->MinMaxInfo->MinHeight += TOTAL_HEIGHT;
126 msg->MinMaxInfo->DefWidth += TOTAL_WIDTH;
127 msg->MinMaxInfo->DefHeight += TOTAL_HEIGHT;
128 msg->MinMaxInfo->MaxWidth += TOTAL_WIDTH;
129 msg->MinMaxInfo->MaxHeight += TOTAL_HEIGHT;
131 return TRUE;
134 static void DrawScale(struct RastPort *rp, LONG x1, LONG y1, LONG x2, 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] =
157 {-1,0 },
158 {-1,1 },
159 {0 ,1 },
160 { 1,1 },
161 { 1,0 }
164 WritePixel(rp, a + offtable[g / 45][0], b + offtable[g / 45][1]);
171 static void DrawNeedle(struct RastPort *rp, LONG x1, LONG y1, LONG x2, LONG y2, double angle, LONG pen)
173 LONG cx = (x1 + x2 + 1) / 2;
174 LONG cy = y2 - 1;
175 LONG rx = cx - x1 - 4;
176 LONG ry = cy - y1 - 4;
177 LONG a, b;
179 SetABPenDrMd(rp, pen, 0, JAM1);
180 Move(rp, cx, cy);
182 if ((angle < 0.0) | (angle > 180.0)) angle = 0.0;
183 angle = 180.0 - angle;
185 a = cx + (LONG)(cos(angle * 3.14159265358979323846 / 180.0) * rx);
186 b = cy - (LONG)(sin(angle * 3.14159265358979323846 / 180.0) * ry);
188 Draw(rp, a, b);
192 /**************************************************************************
193 MUIM_Draw
194 **************************************************************************/
195 IPTR Levelmeter__MUIM_Draw(struct IClass *cl, Object *obj, struct MUIP_Draw *msg)
197 struct Levelmeter_DATA *data = INST_DATA(cl, obj);
198 struct RastPort *rp;
199 WORD x1, y1, x2, y2;
201 DoSuperMethodA(cl,obj,(Msg)msg);
203 if (!(msg->flags & (MADF_DRAWOBJECT | MADF_DRAWUPDATE)))
204 return FALSE;
206 x1 = _mleft(obj);
207 y1 = _mtop(obj);
208 x2 = _mright(obj);
209 y2 = _mbottom(obj);
211 rp = _rp(obj);
213 if (msg->flags & MADF_DRAWOBJECT)
215 /* Transparent edges */
217 DoMethod(obj, MUIM_DrawParentBackground, x1, y1, 2, 1, x1, y1, 0);
218 DoMethod(obj, MUIM_DrawParentBackground, x1, y1 + 1, 1, 1, x1, y1 + 1, 0);
220 DoMethod(obj, MUIM_DrawParentBackground, x2 - 1, y1, 2, 1, x2 - 1, y1, 0);
221 DoMethod(obj, MUIM_DrawParentBackground, x2, y1 + 1, 1, 1, x2, y1 + 1, 0);
223 DoMethod(obj, MUIM_DrawParentBackground, x1, y2, 2, 1, x1, y2, 0);
224 DoMethod(obj, MUIM_DrawParentBackground, x1, y2 - 1, 1, 1, x1, y2 - 1, 0);
226 DoMethod(obj, MUIM_DrawParentBackground, x2 - 1, y2, 2, 1, x2 - 1, y2, 0);
227 DoMethod(obj, MUIM_DrawParentBackground, x2, y2 - 1, 1, 1, x2, y2 - 1, 0);
229 /* Outer frame */
231 SetABPenDrMd(rp, _pens(obj)[MPEN_SHINE], 0, JAM1);
232 Move(rp, x1 + 1, y2 - 1);
233 Draw(rp, x1, y2 - 2);
234 Draw(rp, x1, y1 + 2);
235 Draw(rp, x1 + 2, y1);
236 Draw(rp, x2 - 2, y1);
237 Draw(rp, x2 - 1, y1 + 1);
239 SetAPen(rp, _pens(obj)[MPEN_SHADOW]);
240 Move(rp, x2, y1 + 2);
241 Draw(rp, x2, y2 - 2);
242 Draw(rp, x2 - 2, y2);
243 Draw(rp, x1 + 2, y2);
245 SetAPen(rp, _pens(obj)[MPEN_HALFSHINE]);
246 Move(rp, x1 + 1, y2 - 2);
247 Draw(rp, x1 + 1, y1 + 2);
248 Draw(rp, x1 + 2, y1 + 1);
249 Draw(rp, x2 - 2, y1 + 1);
251 SetAPen(rp, _pens(obj)[MPEN_HALFSHADOW]);
252 Move(rp, x2 - 1, y1 + 2);
253 Draw(rp, x2 - 1, y2 - 2);
254 Draw(rp, x2 - 2, y2 - 1);
255 Draw(rp, x1 + 2, y2 - 1);
257 /* Border */
259 x1 += OUTERFRAME_X; x2 -= OUTERFRAME_X;
260 y1 += OUTERFRAME_X; y2 -= OUTERFRAME_Y;
262 SetAPen(rp, _pens(obj)[MPEN_HALFSHINE]);
263 RectFill(rp, x1, y1, x2, y1 + BORDERSIZE_Y - 1);
264 RectFill(rp, x1, y1 + BORDERSIZE_Y, x1 + BORDERSIZE_X - 1, y2);
265 RectFill(rp, x1 + BORDERSIZE_X - 1, y2 - BORDERSIZE_Y + 1, x2, y2);
266 RectFill(rp, x2 - BORDERSIZE_X + 1, y1 + BORDERSIZE_Y, x2, y2 - BORDERSIZE_Y);
268 /* Inner Frame */
270 x1 += BORDERSIZE_X; x2 -= BORDERSIZE_X;
271 y1 += BORDERSIZE_Y; y2 = y1 + LEVEL_HEIGHT + INNERFRAME_H - 1;
273 Move(rp, x1, y1);
274 Draw(rp, x1 + 2, y1);
275 Draw(rp, x1, y1 + 2);
276 Draw(rp, x1, y1 + 1);
278 Move(rp, x2, y1);
279 Draw(rp, x2 - 2, y1);
280 Draw(rp, x2, y1 + 2);
281 Draw(rp, x2, y1 + 1);
283 Move(rp, x1, y2);
284 Draw(rp, x1 + 2, y2);
285 Draw(rp, x1, y2 - 2);
286 Draw(rp, x1, y2 - 1);
288 Move(rp, x2, y2);
289 Draw(rp, x2 - 2, y2);
290 Draw(rp, x2, y2 - 2);
291 Draw(rp, x2, y2 - 1);
293 SetAPen(rp, _pens(obj)[MPEN_HALFSHADOW]);
294 Move(rp, x1 + 2, y2 - 1);
295 Draw(rp, x1, y2 - 3);
296 Draw(rp, x1, y1 + 3);
297 Draw(rp, x1 + 3, y1);
298 Draw(rp, x2 - 3, y1);
299 Draw(rp, x2 - 1, y1 + 2);
301 SetAPen(rp, _pens(obj)[MPEN_SHINE]);
302 Move(rp, x2, y1 + 3);
303 Draw(rp, x2, y2 - 3);
304 Draw(rp, x2 - 3, y2);
305 Draw(rp, x1 + 3, y2);
307 SetAPen(rp, _pens(obj)[MPEN_SHADOW]);
308 Move(rp, x1 + 3, y1 + 1);
309 Draw(rp, x2 - 3, y1 + 1);
310 Move(rp, x1 + 1, y1 + 3);
311 Draw(rp, x1 + 1, y2 - 3);
312 Move(rp, x1 + 3, y2 - 1);
313 Draw(rp, x2 - 3, y2 - 1);
314 Move(rp, x2 - 1, y1 + 3),
315 Draw(rp, x2 - 1, y2 - 3);
317 /* Levelmeter bg */
319 x1 += INNERFRAME_X; x2 -= INNERFRAME_X;
320 y1 += INNERFRAME_Y; y2 -= INNERFRAME_Y;
322 SetAPen(rp, data->levelbgpen);
323 RectFill(rp, x1 + 1, y1, x2 - 1, y1);
324 RectFill(rp, x1, y1 + 1, x2, y2 - 1);
325 RectFill(rp, x1 + 1, y2, x2 - 1, y2);
327 SetAPen(rp, _pens(obj)[MPEN_SHADOW]);
328 WritePixel(rp, x1, y1);
329 WritePixel(rp, x2, y1);
330 WritePixel(rp, x1, y2);
331 WritePixel(rp, x2, y2);
333 /* Levelmeter scale */
335 DrawScale(rp, x1, y1, x2, y2, _pens(obj)[MPEN_SHINE]);
337 /* Level-Label spacing */
339 x1 -= INNERFRAME_X; x2 += INNERFRAME_X;
340 y1 = y2 + INNERFRAME_Y + 1;
342 SetAPen(rp, _pens(obj)[MPEN_HALFSHINE]);
343 RectFill(rp, x1, y1, x2, y1 + LEVEL_LABEL_SPACING - 1);
345 /* Label Frame */
347 y1 += LEVEL_LABEL_SPACING;
348 y2 = _mbottom(obj) - OUTERFRAME_Y - BORDERSIZE_Y;
350 SetAPen(rp, _pens(obj)[MPEN_HALFSHINE]);
351 Move(rp, x1, y1); Draw(rp, x1 + 1, y1); Draw(rp, x1, y1 + 1);
352 Move(rp, x2, y1); Draw(rp, x2 - 1, y1); Draw(rp, x2, y1 + 1);
353 Move(rp, x1, y2); Draw(rp, x1 + 1, y2); Draw(rp, x1, y2 - 1);
354 Move(rp, x2, y2); Draw(rp, x2 - 1, y2); Draw(rp, x2, y2 - 1);
356 SetAPen(rp, _pens(obj)[MPEN_HALFSHADOW]);
357 Move(rp, x1 + 1, y2 - 1);
358 Draw(rp, x1, y2 - 2);
359 Draw(rp, x1, y1 + 2);
360 Draw(rp, x1 + 2, y1);
361 Draw(rp, x2 - 2, y1);
362 Draw(rp, x2 - 1, y1 + 1);
364 SetAPen(rp, _pens(obj)[MPEN_SHINE]);
365 Move(rp, x2, y1 + 2);
366 Draw(rp, x2, y2 - 2);
367 Draw(rp, x2 - 2, y2);
368 Draw(rp, x1 + 2, y2);
370 SetAPen(rp, _pens(obj)[MPEN_SHADOW]);
371 RectFill(rp, x1 + 1, y1 + 2, x1 + 1, y2 - 2);
372 RectFill(rp, x2 - 1, y1 + 2, x2 - 1, y2 - 2);
373 RectFill(rp, x1 + 2, y1 + 1, x2 - 2, y1 + 1);
374 RectFill(rp, x1 + 2, y2 - 1, x2 - 2, y2 - 1);
376 /* Label Bg */
378 RectFill(rp, x1 + 2, y1 +2, x2 - 2, y2 - 2);
382 x1 = _mleft(obj) + OUTERFRAME_X + BORDERSIZE_X + INNERFRAME_X;
383 x2 = _mright(obj) - OUTERFRAME_X - BORDERSIZE_X - INNERFRAME_X;
384 y1 = _mtop(obj) + OUTERFRAME_Y + BORDERSIZE_Y + INNERFRAME_Y;
385 y2 = y1 + LEVEL_HEIGHT - 1;
387 if (msg->flags & MADF_DRAWUPDATE)
389 DrawNeedle(rp, x1, y1, x2, y2, data->prevangle, data->levelbgpen);
392 data->prevangle = (double)DoMethod(obj, MUIM_Numeric_ValueToScale, 0, 180);
394 DrawNeedle(rp, x1, y1, x2, y2, data->prevangle, _pens(obj)[MPEN_SHINE]);
396 return TRUE;
399 #if ZUNE_BUILTIN_LEVELMETER
400 BOOPSI_DISPATCHER(IPTR, Levelmeter_Dispatcher, cl, obj, msg)
402 switch (msg->MethodID)
404 case OM_NEW: return Levelmeter__OM_NEW(cl, obj, (struct opSet *)msg);
405 case MUIM_Setup: return Levelmeter__MUIM_Setup(cl, obj, (struct MUIP_Setup *)msg);
406 case MUIM_Cleanup: return Levelmeter__MUIM_Cleanup(cl, obj, (struct MUIP_Cleanup *)msg);
407 case MUIM_AskMinMax: return Levelmeter__MUIM_AskMinMax(cl, obj, (struct MUIP_AskMinMax *)msg);
408 case MUIM_Draw: return Levelmeter__MUIM_Draw(cl, obj, (struct MUIP_Draw *)msg);
409 default: return DoSuperMethodA(cl, obj, msg);
412 BOOPSI_DISPATCHER_END
414 const struct __MUIBuiltinClass _MUI_Levelmeter_desc =
416 MUIC_Levelmeter,
417 MUIC_Numeric,
418 sizeof(struct Levelmeter_DATA),
419 (void*)Levelmeter_Dispatcher
421 #endif /* ZUNE_BUILTIN_LEVELMETER */