2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
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/muimaster.h>
15 #include <proto/graphics.h>
16 #include <proto/intuition.h>
17 #include <proto/utility.h>
18 #include <proto/timer.h>
25 #include "clock_private.h"
31 /*** Methods ****************************************************************/
32 IPTR
Clock__OM_NEW(Class
*cl
, Object
*obj
, struct opSet
*msg
)
34 struct Clock_DATA
*data
;
37 obj
= (Object
*) DoSuperNewTags
46 TAG_MORE
, (IPTR
) msg
->ops_AttrList
51 data
= INST_DATA(cl
, obj
);
52 data
->frozen
= GetTagData(MUIA_Clock_Frozen
, FALSE
, msg
->ops_AttrList
) ? TRUE
: FALSE
;
53 data
->edithand
= (WORD
)GetTagData(MUIA_Clock_EditHand
, (IPTR
)-1, msg
->ops_AttrList
);
56 if ((ti
= FindTagItem(MUIA_Clock_Time
, msg
->ops_AttrList
)))
58 struct ClockData
*cd
= (struct ClockData
*)ti
->ti_Data
;
60 data
->clockdata
= *cd
;
67 Amiga2Date(tv
.tv_secs
, &data
->clockdata
);
70 data
->ihn
.ihn_Flags
= MUIIHNF_TIMER
;
71 data
->ihn
.ihn_Method
= MUIM_Clock_Timer
;
72 data
->ihn
.ihn_Object
= obj
;
73 data
->ihn
.ihn_Millis
= 1000;
79 IPTR
Clock__OM_DISPOSE(Class
*cl
, Object
*obj
, Msg msg
)
81 return DoSuperMethodA(cl
, obj
, msg
);
85 IPTR
Clock__OM_SET(Class
*cl
, Object
*obj
, struct opSet
*msg
)
87 struct Clock_DATA
*data
= INST_DATA(cl
, obj
);
88 struct ClockData old_clockdata
;
89 const struct TagItem
*tags
= msg
->ops_AttrList
;
93 old_clockdata
= data
->clockdata
;
95 while ((tag
= NextTagItem(&tags
)) != NULL
)
100 data
->clockdata
= *(struct ClockData
*)tag
->ti_Data
;
104 case MUIA_Clock_Hour
:
105 data
->clockdata
.hour
= tag
->ti_Data
;
110 data
->clockdata
.min
= tag
->ti_Data
;
115 data
->clockdata
.sec
= tag
->ti_Data
;
119 case MUIA_Clock_Frozen
:
120 data
->frozen
= tag
->ti_Data
? TRUE
: FALSE
;
123 case MUIA_Clock_EditHand
:
124 data
->edithand
= tag
->ti_Data
;
128 } /* switch(tag->ti_Tag) */
130 } /* while ((tag = NextTagItem(&tags)) != NULL) */
134 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
137 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
141 IPTR
Clock__OM_GET(Class
*cl
, Object
*obj
, struct opGet
*msg
)
143 struct Clock_DATA
*data
= INST_DATA(cl
, obj
);
146 switch(msg
->opg_AttrID
)
148 case MUIA_Clock_Time
:
149 *(struct ClockData
**)msg
->opg_Storage
= &data
->clockdata
;
152 case MUIA_Clock_Hour
:
153 *msg
->opg_Storage
= data
->clockdata
.hour
;
157 *msg
->opg_Storage
= data
->clockdata
.min
;
161 *msg
->opg_Storage
= data
->clockdata
.sec
;
164 case MUIA_Clock_Frozen
:
165 *msg
->opg_Storage
= data
->frozen
;
168 case MUIA_Clock_EditHand
:
169 *msg
->opg_Storage
= data
->edithand
;
173 retval
= DoSuperMethodA(cl
, obj
, (Msg
)msg
);
181 IPTR
Clock__MUIM_Setup(Class
*cl
, Object
*obj
, struct MUIP_Setup
*msg
)
183 struct Clock_DATA
*data
= INST_DATA(cl
, obj
);
185 if (!DoSuperMethodA(cl
, obj
, (Msg
)msg
)) return FALSE
;
187 DoMethod(_app(obj
), MUIM_Application_AddInputHandler
, (IPTR
) &data
->ihn
);
189 data
->editpen
= ObtainBestPen(_screen(obj
)->ViewPort
.ColorMap
,
193 OBP_Precision
, PRECISION_GUI
,
194 OBP_FailIfBad
, FALSE
,
200 IPTR
Clock__MUIM_Cleanup(Class
*cl
, Object
*obj
, struct MUIP_Cleanup
*msg
)
202 struct Clock_DATA
*data
= INST_DATA(cl
, obj
);
204 if (data
->editpen
!= -1)
206 ReleasePen(_screen(obj
)->ViewPort
.ColorMap
, data
->editpen
);
212 DeinitRastPort(&data
->clockrp
);
213 FreeBitMap(data
->clockbm
);
214 FreeRaster(data
->clockraster
, data
->clockbmw
, data
->clockbmh
);
215 data
->clockbm
= NULL
;
216 data
->clockraster
= NULL
;
218 DoMethod(_app(obj
), MUIM_Application_RemInputHandler
, (IPTR
) &data
->ihn
);
220 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
224 IPTR
Clock__MUIM_AskMinMax(Class
*cl
, Object
*obj
, struct MUIP_AskMinMax
*msg
)
226 DoSuperMethodA(cl
, obj
, (Msg
)msg
);
228 msg
->MinMaxInfo
->MinWidth
+= 31;
229 msg
->MinMaxInfo
->MinHeight
+= 31;
230 msg
->MinMaxInfo
->DefWidth
+= 31;
231 msg
->MinMaxInfo
->DefHeight
+= 31;
232 msg
->MinMaxInfo
->MaxWidth
= MUI_MAXMAX
;
233 msg
->MinMaxInfo
->MaxHeight
= MUI_MAXMAX
;
239 #define MY_PI 3.14159265358979323846
243 struct RastPort
*rp
, WORD cx
, WORD cy
, DOUBLE angle
,
244 WORD radius1
, WORD radius2
249 x
= cx
+ (WORD
)(cos(angle
+ MY_PI
) * radius1
);
250 y
= cy
- (WORD
)(sin(angle
+ MY_PI
) * radius1
);
254 x
= cx
+ (WORD
)(cos(angle
+ MY_PI
/ 2.0) * radius1
);
255 y
= cy
- (WORD
)(sin(angle
+ MY_PI
/ 2.0) * radius1
);
259 x
= cx
+ (WORD
)(cos(angle
) * radius2
);
260 y
= cy
- (WORD
)(sin(angle
) * radius2
);
264 x
= cx
+ (WORD
)(cos(angle
- MY_PI
/ 2.0) * radius1
);
265 y
= cy
- (WORD
)(sin(angle
- MY_PI
/ 2.0) * radius1
);
269 x
= cx
+ (WORD
)(cos(angle
+ MY_PI
) * radius1
);
270 y
= cy
- (WORD
)(sin(angle
+ MY_PI
) * radius1
);
278 static void DrawThinHand(struct RastPort
*rp
, WORD cx
, WORD cy
, DOUBLE angle
, WORD radius
)
284 x
= cx
+ (WORD
)(cos(angle
) * radius
);
285 y
= cy
- (WORD
)(sin(angle
) * radius
);
290 IPTR
Clock__MUIM_Draw(Class
*cl
, Object
*obj
, struct MUIP_Draw
*msg
)
292 struct Clock_DATA
*data
= INST_DATA(cl
, obj
);
293 struct RastPort
*obj_rp
;
294 struct Region
*region
;
295 struct Rectangle rect
;
297 WORD r
, x
, y
, x2
, y2
, i
, cx
, cy
, c
;
298 WORD new_clockbmw
, new_clockbmh
;
299 WORD clock_posx
, clock_posy
;
302 r
= (_mwidth(obj
) - SHADOW_OFFX
) / 2;
303 y
= (_mheight(obj
) - SHADOW_OFFY
) / 2;
307 new_clockbmw
= r
* 2 + 1 + SHADOW_OFFX
;
308 new_clockbmh
= r
* 2 + 1 + SHADOW_OFFY
;
310 clock_posx
= _mleft(obj
) + (_mwidth(obj
) - new_clockbmw
) / 2;
311 clock_posy
= _mtop(obj
) + (_mheight(obj
) - new_clockbmh
) / 2;
313 region
= NewRegion();
316 rect
.MinX
= _left(obj
);
317 rect
.MinY
= _top(obj
);
318 rect
.MaxX
= _right(obj
);
319 rect
.MaxY
= _bottom(obj
);
321 OrRectRegion(region
, &rect
);
323 rect
.MinX
= clock_posx
;
324 rect
.MinY
= clock_posy
;
325 rect
.MaxX
= clock_posx
+ new_clockbmw
- 1;
326 rect
.MaxY
= clock_posy
+ new_clockbmh
- 1;
328 ClearRectRegion(region
, &rect
);
330 clip
= MUI_AddClipRegion(muiRenderInfo(obj
), region
);
333 DoSuperMethodA(cl
, obj
, (Msg
)msg
);
337 MUI_RemoveClipRegion(muiRenderInfo(obj
), clip
);
340 if (!(msg
->flags
& (MADF_DRAWOBJECT
| MADF_DRAWUPDATE
))) return 0;
342 if (!data
->clockbm
|| (data
->clockbmr
!= r
))
346 DeinitRastPort(&data
->clockrp
);
347 FreeBitMap(data
->clockbm
);
348 FreeRaster(data
->clockraster
, data
->clockbmw
, data
->clockbmh
);
349 data
->clockraster
= NULL
;
352 data
->clockbmw
= new_clockbmw
;
353 data
->clockbmh
= new_clockbmh
;
355 data
->clockbm
= AllocBitMap(data
->clockbmw
,
357 GetBitMapAttr(_rp(obj
)->BitMap
, BMA_DEPTH
),
361 if (!data
->clockbm
) return 0;
363 data
->clockraster
= AllocRaster(data
->clockbmw
, data
->clockbmh
);
364 if (!data
->clockraster
)
366 FreeBitMap(data
->clockbm
);
371 InitRastPort(&data
->clockrp
);
372 data
->clockrp
.BitMap
= data
->clockbm
;
374 InitArea(&data
->clockai
, data
->areabuf
, sizeof(data
->areabuf
) / 5);
375 data
->clockrp
.AreaInfo
= &data
->clockai
;
377 InitTmpRas(&data
->clocktr
, data
->clockraster
, RASSIZE(data
->clockbmw
, data
->clockbmh
));
378 data
->clockrp
.TmpRas
= &data
->clocktr
;
384 _rp(obj
) = &data
->clockrp
;
386 DoMethod(obj
, MUIM_DrawBackground
, 0, 0, data
->clockbmw
, data
->clockbmh
, clock_posx
, clock_posy
, 0);
388 cx
= r
+ SHADOW_OFFX
;
389 cy
= r
+ SHADOW_OFFY
;
391 SetDrMd(_rp(obj
), JAM1
);
392 SetAPen(_rp(obj
), _pens(obj
)[MPEN_HALFSHADOW
]);
394 for(c
= 0; c
< 2; c
++)
396 for(angle
= 0.0, i
= 0; angle
< 2.0 * MY_PI
; angle
+= 2 * MY_PI
/ 60.0, i
++)
398 x
= cx
+ (WORD
)(cos(angle
) * r
);
399 y
= cy
- (WORD
)(sin(angle
) * r
);
403 x2
= cx
+ (WORD
)(cos(angle
) * (r
* 90 / 100));
404 y2
= cy
- (WORD
)(sin(angle
) * (r
* 90 / 100));
405 Move(_rp(obj
), x
, y
); Draw(_rp(obj
), x2
, y2
);
409 WritePixel(_rp(obj
), x
, y
);
415 SetAPen(_rp(obj
), _dri(obj
)->dri_Pens
[SHADOWPEN
]);
418 cx
+= SHADOW_OFFX
* 2;
419 cy
+= SHADOW_OFFY
* 2;
421 SetAPen(_rp(obj
), _pens(obj
)[MPEN_HALFSHADOW
]);
423 for(c
= 0; c
< 2; c
++)
427 h
= data
->clockdata
.hour
+ (data
->clockdata
.min
/ 60.0);
428 if (h
> 12.0) h
-= 12.0;
430 angle
= MY_PI
/ 2.0 + MY_PI
* 2.0 * (12.0 - h
) / 12.0;
434 if ((data
->edithand
== MUIV_Clock_EditHand_Hour
) && data
->frozen
)
436 SetAPen(_rp(obj
), (data
->editpen
== -1) ? _dri(obj
)->dri_Pens
[SHINEPEN
] : data
->editpen
);
440 SetAPen(_rp(obj
), _dri(obj
)->dri_Pens
[SHADOWPEN
]);
451 angle
= MY_PI
/ 2.0 + MY_PI
* 2.0 * ((double)60 - data
->clockdata
.min
) / 60.0;
455 if ((data
->edithand
== MUIV_Clock_EditHand_Minute
) && data
->frozen
)
457 SetAPen(_rp(obj
), (data
->editpen
== -1) ? _dri(obj
)->dri_Pens
[SHINEPEN
] : data
->editpen
);
461 SetAPen(_rp(obj
), _dri(obj
)->dri_Pens
[SHADOWPEN
]);
472 angle
= MY_PI
/ 2.0 + MY_PI
* 2.0 * ((double)60 - data
->clockdata
.sec
) / 60.0;
476 if ((data
->edithand
== MUIV_Clock_EditHand_Second
) && data
->frozen
)
478 SetAPen(_rp(obj
), (data
->editpen
== -1) ? _dri(obj
)->dri_Pens
[SHINEPEN
] : data
->editpen
);
482 SetAPen(_rp(obj
), _dri(obj
)->dri_Pens
[SHADOWPEN
]);
486 DrawThinHand(_rp(obj
), cx
, cy
, angle
, r
* 85 / 100);
495 BltBitMapRastPort(data
->clockbm
,
502 data
->clockbmh
, 192);
508 IPTR
Clock__MUIM_Clock_Timer(Class
*cl
, Object
*obj
, Msg msg
)
510 struct Clock_DATA
*data
;
514 data
= INST_DATA(cl
, obj
);
519 Amiga2Date(tv
.tv_secs
, &cd
);
521 set(obj
, MUIA_Clock_Time
, &cd
);
522 set(obj
, MUIA_Clock_Ticked
, TRUE
);