revert 213 commits (to 56092) from the last month. 10 still need work to resolve...
[AROS.git] / workbench / classes / zune / clock / clock.c
blobc97d4c12ac8d37ec1e7b70fa993f2e220ad80cff
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define MUIMASTER_YES_INLINE_STDARG
8 #include <exec/types.h>
9 #include <utility/date.h>
11 #include <aros/debug.h>
12 #include <aros/asmcall.h>
14 #include <proto/alib.h>
15 #include <proto/muimaster.h>
16 #include <proto/graphics.h>
17 #include <proto/intuition.h>
18 #include <proto/utility.h>
19 #include <proto/timer.h>
21 #include <string.h>
22 #include <stdio.h>
23 #include <math.h>
25 #include "clock.h"
26 #include "clock_private.h"
28 #define SHADOW_OFFX 4
29 #define SHADOW_OFFY 4
32 /*** Methods ****************************************************************/
33 IPTR Clock__OM_NEW(Class *cl, Object *obj, struct opSet *msg)
35 struct Clock_DATA *data;
36 struct TagItem *ti;
38 obj = (Object *) DoSuperNewTags
40 cl, obj, NULL,
42 MUIA_InnerLeft, 4,
43 MUIA_InnerTop, 4,
44 MUIA_InnerRight, 4,
45 MUIA_InnerBottom, 4,
47 TAG_MORE, (IPTR) msg->ops_AttrList
50 if (!obj) return 0;
52 data = INST_DATA(cl, obj);
53 data->frozen = GetTagData(MUIA_Clock_Frozen, FALSE, msg->ops_AttrList) ? TRUE : FALSE;
54 data->edithand = (WORD)GetTagData(MUIA_Clock_EditHand, (IPTR)-1, msg->ops_AttrList);
55 data->editpen = -1;
57 if ((ti = FindTagItem(MUIA_Clock_Time, msg->ops_AttrList)))
59 struct ClockData *cd = (struct ClockData *)ti->ti_Data;
61 data->clockdata = *cd;
63 else
65 struct timeval tv;
67 GetSysTime(&tv);
68 Amiga2Date(tv.tv_secs, &data->clockdata);
71 data->ihn.ihn_Flags = MUIIHNF_TIMER;
72 data->ihn.ihn_Method = MUIM_Clock_Timer;
73 data->ihn.ihn_Object = obj;
74 data->ihn.ihn_Millis = 1000;
76 return (IPTR)obj;
80 IPTR Clock__OM_DISPOSE(Class *cl, Object *obj, Msg msg)
82 return DoSuperMethodA(cl, obj, msg);
86 IPTR Clock__OM_SET(Class *cl, Object *obj, struct opSet *msg)
88 struct Clock_DATA *data = INST_DATA(cl, obj);
89 struct TagItem *tags = msg->ops_AttrList;
90 struct TagItem *tag;
91 BOOL redraw = FALSE;
93 while ((tag = NextTagItem(&tags)) != NULL)
95 switch(tag->ti_Tag)
97 case MUIA_Clock_Time:
98 data->clockdata = *(struct ClockData *)tag->ti_Data;
99 redraw = TRUE;
100 break;
102 case MUIA_Clock_Hour:
103 data->clockdata.hour = tag->ti_Data;
104 redraw = TRUE;
105 break;
107 case MUIA_Clock_Min:
108 data->clockdata.min = tag->ti_Data;
109 redraw = TRUE;
110 break;
112 case MUIA_Clock_Sec:
113 data->clockdata.sec = tag->ti_Data;
114 redraw = TRUE;
115 break;
117 case MUIA_Clock_Frozen:
118 data->frozen = tag->ti_Data ? TRUE : FALSE;
119 break;
121 case MUIA_Clock_EditHand:
122 data->edithand = tag->ti_Data;
123 redraw = TRUE;
124 break;
126 } /* switch(tag->ti_Tag) */
128 } /* while ((tag = NextTagItem(&tags)) != NULL) */
130 if (redraw)
132 MUI_Redraw(obj, MADF_DRAWUPDATE);
135 return DoSuperMethodA(cl, obj, (Msg)msg);
139 IPTR Clock__OM_GET(Class *cl, Object *obj, struct opGet *msg)
141 struct Clock_DATA *data = INST_DATA(cl, obj);
142 IPTR retval = TRUE;
144 switch(msg->opg_AttrID)
146 case MUIA_Clock_Time:
147 *(struct ClockData **)msg->opg_Storage = &data->clockdata;
148 break;
150 case MUIA_Clock_Hour:
151 *msg->opg_Storage = data->clockdata.hour;
152 break;
154 case MUIA_Clock_Min:
155 *msg->opg_Storage = data->clockdata.min;
156 break;
158 case MUIA_Clock_Sec:
159 *msg->opg_Storage = data->clockdata.sec;
160 break;
162 case MUIA_Clock_Frozen:
163 *msg->opg_Storage = data->frozen;
164 break;
166 case MUIA_Clock_EditHand:
167 *msg->opg_Storage = data->edithand;
168 break;
170 default:
171 retval = DoSuperMethodA(cl, obj, (Msg)msg);
172 break;
175 return retval;
179 IPTR Clock__MUIM_Setup(Class *cl, Object *obj, struct MUIP_Setup *msg)
181 struct Clock_DATA *data = INST_DATA(cl, obj);
183 if (!DoSuperMethodA(cl, obj, (Msg)msg)) return FALSE;
185 DoMethod(_app(obj), MUIM_Application_AddInputHandler, (IPTR) &data->ihn);
187 data->editpen = ObtainBestPen(_screen(obj)->ViewPort.ColorMap,
188 0xFFFFFFFF,
189 0xD8D8D8D8,
190 0x00000000,
191 OBP_Precision, PRECISION_GUI,
192 OBP_FailIfBad, FALSE,
193 TAG_DONE);
194 return TRUE;
198 IPTR Clock__MUIM_Cleanup(Class *cl, Object *obj, struct MUIP_Cleanup *msg)
200 struct Clock_DATA *data = INST_DATA(cl, obj);
202 if (data->editpen != -1)
204 ReleasePen(_screen(obj)->ViewPort.ColorMap, data->editpen);
205 data->editpen = -1;
208 if (data->clockbm)
210 FreeBitMap(data->clockbm);
211 FreeRaster(data->clockraster, data->clockbmw, data->clockbmh);
212 data->clockbm = NULL;
213 data->clockraster = NULL;
215 DoMethod(_app(obj), MUIM_Application_RemInputHandler, (IPTR) &data->ihn);
217 return DoSuperMethodA(cl, obj, (Msg)msg);
221 IPTR Clock__MUIM_AskMinMax(Class *cl, Object *obj, struct MUIP_AskMinMax *msg)
223 DoSuperMethodA(cl, obj, (Msg)msg);
225 msg->MinMaxInfo->MinWidth += 31;
226 msg->MinMaxInfo->MinHeight += 31;
227 msg->MinMaxInfo->DefWidth += 31;
228 msg->MinMaxInfo->DefHeight += 31;
229 msg->MinMaxInfo->MaxWidth = MUI_MAXMAX;
230 msg->MinMaxInfo->MaxHeight = MUI_MAXMAX;
232 return TRUE;
236 #define MY_PI 3.14159265358979323846
238 static void DrawHand
240 struct RastPort *rp, WORD cx, WORD cy, DOUBLE angle,
241 WORD radius1, WORD radius2
244 WORD x, y;
246 x = cx + (WORD)(cos(angle + MY_PI) * radius1);
247 y = cy - (WORD)(sin(angle + MY_PI) * radius1);
249 AreaMove(rp, x, y);
251 x = cx + (WORD)(cos(angle + MY_PI / 2.0) * radius1);
252 y = cy - (WORD)(sin(angle + MY_PI / 2.0) * radius1);
254 AreaDraw(rp, x, y);
256 x = cx + (WORD)(cos(angle) * radius2);
257 y = cy - (WORD)(sin(angle) * radius2);
259 AreaDraw(rp, x, y);
261 x = cx + (WORD)(cos(angle - MY_PI / 2.0) * radius1);
262 y = cy - (WORD)(sin(angle - MY_PI / 2.0) * radius1);
264 AreaDraw(rp, x, y);
266 x = cx + (WORD)(cos(angle + MY_PI) * radius1);
267 y = cy - (WORD)(sin(angle + MY_PI) * radius1);
269 AreaDraw(rp, x, y);
271 AreaEnd(rp);
275 static void DrawThinHand(struct RastPort *rp, WORD cx, WORD cy, DOUBLE angle, WORD radius)
277 WORD x, y;
279 Move(rp, cx, cy);
281 x = cx + (WORD)(cos(angle) * radius);
282 y = cy - (WORD)(sin(angle) * radius);
284 Draw(rp, x, y);
287 IPTR Clock__MUIM_Draw(Class *cl, Object *obj, struct MUIP_Draw *msg)
289 struct Clock_DATA *data = INST_DATA(cl, obj);
290 struct RastPort *obj_rp;
291 struct Region *region;
292 struct Rectangle rect;
293 APTR clip = NULL;
294 WORD r, x, y, x2, y2, i, cx, cy, c;
295 WORD new_clockbmw, new_clockbmh;
296 WORD clock_posx, clock_posy;
297 DOUBLE angle;
299 r = (_mwidth(obj) - SHADOW_OFFX) / 2;
300 y = (_mheight(obj) - SHADOW_OFFY) / 2;
302 r = (r < y) ? r : y;
304 new_clockbmw = r * 2 + 1 + SHADOW_OFFX;
305 new_clockbmh = r * 2 + 1 + SHADOW_OFFY;
307 clock_posx = _mleft(obj) + (_mwidth(obj) - new_clockbmw) / 2;
308 clock_posy = _mtop(obj) + (_mheight(obj) - new_clockbmh) / 2;
310 region = NewRegion();
311 if (region)
313 rect.MinX = _left(obj);
314 rect.MinY = _top(obj);
315 rect.MaxX = _right(obj);
316 rect.MaxY = _bottom(obj);
318 OrRectRegion(region, &rect);
320 rect.MinX = clock_posx;
321 rect.MinY = clock_posy;
322 rect.MaxX = clock_posx + new_clockbmw - 1;
323 rect.MaxY = clock_posy + new_clockbmh - 1;
325 ClearRectRegion(region, &rect);
327 clip = MUI_AddClipRegion(muiRenderInfo(obj), region);
330 DoSuperMethodA(cl, obj, (Msg)msg);
332 if (region)
334 MUI_RemoveClipRegion(muiRenderInfo(obj), clip);
337 if (!(msg->flags & (MADF_DRAWOBJECT | MADF_DRAWUPDATE))) return 0;
339 if (!data->clockbm || (data->clockbmr != r))
341 if (data->clockbm)
343 FreeBitMap(data->clockbm);
344 FreeRaster(data->clockraster, data->clockbmw, data->clockbmh);
345 data->clockraster = NULL;
348 data->clockbmw = new_clockbmw;
349 data->clockbmh = new_clockbmh;
351 data->clockbm = AllocBitMap(data->clockbmw,
352 data->clockbmh,
353 GetBitMapAttr(_rp(obj)->BitMap, BMA_DEPTH),
354 BMF_MINPLANES,
355 _rp(obj)->BitMap);
357 if (!data->clockbm) return 0;
359 data->clockraster = AllocRaster(data->clockbmw, data->clockbmh);
360 if (!data->clockraster)
362 FreeBitMap(data->clockbm);
363 data->clockbm = 0;
364 return 0;
367 InitRastPort(&data->clockrp);
368 data->clockrp.BitMap = data->clockbm;
370 InitArea(&data->clockai, data->areabuf, sizeof(data->areabuf) / 5);
371 data->clockrp.AreaInfo = &data->clockai;
373 InitTmpRas(&data->clocktr, data->clockraster, RASSIZE(data->clockbmw, data->clockbmh));
374 data->clockrp.TmpRas = &data->clocktr;
376 data->clockbmr = r;
379 obj_rp = _rp(obj);
380 _rp(obj) = &data->clockrp;
382 DoMethod(obj, MUIM_DrawBackground, 0, 0, data->clockbmw , data->clockbmh, clock_posx, clock_posy, 0);
384 cx = r + SHADOW_OFFX;
385 cy = r + SHADOW_OFFY;
387 SetDrMd(_rp(obj), JAM1);
388 SetAPen(_rp(obj), _pens(obj)[MPEN_HALFSHADOW]);
390 for(c = 0; c < 2; c++)
392 for(angle = 0.0, i = 0; angle < 2.0 * MY_PI; angle += 2 * MY_PI / 60.0, i++)
394 x = cx + (WORD)(cos(angle) * r);
395 y = cy - (WORD)(sin(angle) * r);
397 if ((i % 5) == 0)
399 x2 = cx + (WORD)(cos(angle) * (r * 90 / 100));
400 y2 = cy - (WORD)(sin(angle) * (r * 90 / 100));
401 Move(_rp(obj), x, y); Draw(_rp(obj), x2, y2);
403 else
405 WritePixel(_rp(obj), x, y);
409 cx -= SHADOW_OFFX;
410 cy -= SHADOW_OFFY;
411 SetAPen(_rp(obj), _dri(obj)->dri_Pens[SHADOWPEN]);
414 cx += SHADOW_OFFX * 2;
415 cy += SHADOW_OFFY * 2;
417 SetAPen(_rp(obj), _pens(obj)[MPEN_HALFSHADOW]);
419 for(c = 0; c < 2; c++)
421 DOUBLE angle, h;
423 h = data->clockdata.hour + (data->clockdata.min / 60.0);
424 if (h > 12.0) h -= 12.0;
426 angle = MY_PI / 2.0 + MY_PI * 2.0 * (12.0 - h) / 12.0;
428 if (c == 1)
430 if ((data->edithand == MUIV_Clock_EditHand_Hour) && data->frozen)
432 SetAPen(_rp(obj), (data->editpen == -1) ? _dri(obj)->dri_Pens[SHINEPEN] : data->editpen);
434 else
436 SetAPen(_rp(obj), _dri(obj)->dri_Pens[SHADOWPEN]);
440 DrawHand(_rp(obj),
443 angle,
444 r * 6 / 100,
445 r * 60 / 100);
447 angle = MY_PI / 2.0 + MY_PI * 2.0 * ((double)60 - data->clockdata.min) / 60.0;
449 if (c == 1)
451 if ((data->edithand == MUIV_Clock_EditHand_Minute) && data->frozen)
453 SetAPen(_rp(obj), (data->editpen == -1) ? _dri(obj)->dri_Pens[SHINEPEN] : data->editpen);
455 else
457 SetAPen(_rp(obj), _dri(obj)->dri_Pens[SHADOWPEN]);
461 DrawHand(_rp(obj),
464 angle,
465 r * 4 / 100,
466 r * 85 / 100);
468 angle = MY_PI / 2.0 + MY_PI * 2.0 * ((double)60 - data->clockdata.sec) / 60.0;
470 if (c == 1)
472 if ((data->edithand == MUIV_Clock_EditHand_Second) && data->frozen)
474 SetAPen(_rp(obj), (data->editpen == -1) ? _dri(obj)->dri_Pens[SHINEPEN] : data->editpen);
476 else
478 SetAPen(_rp(obj), _dri(obj)->dri_Pens[SHADOWPEN]);
482 DrawThinHand(_rp(obj), cx, cy, angle, r * 85 / 100);
484 cx -= SHADOW_OFFX;
485 cy -= SHADOW_OFFY;
489 _rp(obj) = obj_rp;
491 BltBitMapRastPort(data->clockbm,
494 _rp(obj),
495 clock_posx,
496 clock_posy,
497 data->clockbmw,
498 data->clockbmh, 192);
500 return 0;
504 IPTR Clock__MUIM_Clock_Timer(Class *cl, Object *obj, Msg msg)
506 struct Clock_DATA *data;
507 struct ClockData cd;
508 struct timeval tv;
510 data = INST_DATA(cl, obj);
512 if (!data->frozen)
514 GetSysTime(&tv);
515 Amiga2Date(tv.tv_secs, &cd);
517 set(obj, MUIA_Clock_Time, &cd);
518 set(obj, MUIA_Clock_Ticked, TRUE);
521 return 0;