2 Copyright © 2016, The AROS Development Team. All rights reserved.
9 #include <aros/debug.h>
11 #define USE_BOOPSI_STUBS
12 #include <exec/libraries.h>
13 #include <proto/dos.h>
14 #include <proto/intuition.h>
15 #include <intuition/intuition.h>
16 #include <intuition/screens.h>
17 #include <intuition/classes.h>
18 #include <intuition/classusr.h>
19 #include <intuition/gadgetclass.h>
20 #include <intuition/imageclass.h>
21 #include <proto/graphics.h>
22 #include <graphics/rastport.h>
23 #include <graphics/text.h>
24 #include <proto/utility.h>
25 #include <utility/tagitem.h>
26 #include <devices/inputevent.h>
27 #include <gadgets/aroscycle.h>
28 #include <proto/alib.h>
30 #include <gadgets/tapedeck.h>
32 #include "tapedeck_intern.h"
34 /***********************************************************************************/
36 #define IM(o) ((struct Image *)(o))
37 #define EG(o) ((struct Gadget *)(o))
39 #define POSPROP_HEIGHT 5
40 #define TDGADGET_HEIGHT 20
42 #include <clib/boopsistubs.h>
44 #define TAPEDECK_FLAG_INIT (TDECK_Dummy + 100-1)
46 static UBYTE templateRewind
[] =
48 0x03, 0x03, // 0000001100000011
49 0x0F, 0x0f, // 0000111100001111
50 0x3F, 0x3F, // 0011111100011111
51 0xFF, 0xFF, // 1111111111111111
52 0x3F, 0x3F, // 0011111100111111
53 0x0F, 0x0F, // 0000111100001111
54 0x03, 0x03, // 0000001100000011
56 static UBYTE templatePlay
[] =
66 static UBYTE templatePause
[] =
76 static UBYTE templateFForward
[] =
78 0xC0, 0xC0, // 1100000011000000
79 0xF0, 0xF0, // 1111000011110000
80 0xFC, 0xFC, // 1111110011111100
81 0xFF, 0xFF, // 1111111111111111
82 0xFC, 0xFC, // 1111110011111100
83 0xF0, 0xF0, // 1111000011110000
84 0xC0, 0xC0, // 1100000011000000
87 /***********************************************************************************/
89 IPTR
TapeDeck__OM_GET(Class
*cl
, Object
*o
, struct opGet
*msg
)
91 struct TapeDeckData
*data
= INST_DATA(cl
, o
);
94 D(bug("[tapedeck.gadget]: %s()\n", __PRETTY_FUNCTION__
));
96 switch(msg
->opg_AttrID
)
99 *msg
->opg_Storage
= (IPTR
)data
->tdd_Mode
;
103 *msg
->opg_Storage
= (IPTR
)data
->tdd_FrameCount
;
106 case TDECK_CurrentFrame
:
107 *msg
->opg_Storage
= (IPTR
)data
->tdd_FrameCurrent
;
111 *msg
->opg_Storage
= TDGADGET_HEIGHT
;
115 retval
= DoSuperMethodA(cl
, o
, (Msg
)msg
);
122 /***********************************************************************************/
124 IPTR
TapeDeck__OM_SET(Class
*cl
, Object
*o
, struct opSet
*msg
)
126 struct TapeDeckData
*data
= INST_DATA(cl
, o
);
127 struct TagItem
*tag
, *taglist
= msg
->ops_AttrList
;
128 BOOL rerender
= FALSE
, tdinit
= FALSE
;
131 D(bug("[tapedeck.gadget]: %s()\n", __PRETTY_FUNCTION__
));
133 result
= DoSuperMethodA(cl
, o
, (Msg
)msg
);
135 while((tag
= NextTagItem(&taglist
)))
139 case TAPEDECK_FLAG_INIT
:
140 D(bug("[tapedeck.gadget] %s: performing initial setup\n", __PRETTY_FUNCTION__
));
145 D(bug("[tapedeck.gadget] %s: TDECK_Mode %08x\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
146 data
->tdd_Mode
= (ULONG
)tag
->ti_Data
;
150 D(bug("[tapedeck.gadget] %s: TDECK_Frames - %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
151 data
->tdd_FrameCount
= (ULONG
)tag
->ti_Data
;
154 case TDECK_CurrentFrame
:
155 D(bug("[tapedeck.gadget] %s: TDECK_CurrentFrame - %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
156 data
->tdd_FrameCurrent
= (ULONG
)tag
->ti_Data
;
164 D(bug("[tapedeck.gadget] %s: GA_Height - %d (ignored)\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
165 tag
->ti_Data
= TDGADGET_HEIGHT
;
170 bug("[tapedeck.gadget] %s: GA_Left - %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
);
174 bug("[tapedeck.gadget] %s: GA_Top - %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
);
178 bug("[tapedeck.gadget] %s: GA_Width - %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
);
186 if (!(tdinit
) && (rerender
))
188 struct RastPort
*rport
;
190 rport
= ObtainGIRPort(msg
->ops_GInfo
);
193 DoMethod(o
, GM_RENDER
, (IPTR
)msg
->ops_GInfo
, (IPTR
)rport
, GREDRAW_REDRAW
);
194 ReleaseGIRPort(rport
);
202 /***********************************************************************************/
204 Object
*TapeDeck__OM_NEW(Class
*cl
, Class
*rootcl
, struct opSet
*msg
)
206 struct TapeDeckData
*data
;
207 struct TagItem pproptags
[] =
211 { PGA_Freedom
, FREEHORIZ
},
212 { PGA_Borderless
, TRUE
},
217 struct TagItem frametags
[] =
219 { IA_EdgesOnly
, FALSE
},
220 { IA_FrameType
, FRAME_BUTTON
},
223 struct TagItem tdinittags
[] =
225 { TAPEDECK_FLAG_INIT
, 0 },
226 { TAG_MORE
, (IPTR
)msg
->ops_AttrList
},
231 D(bug("[tapedeck.gadget]: %s()\n", __PRETTY_FUNCTION__
));
233 o
= (Object
*)DoSuperMethodA(cl
, (Object
*)rootcl
, (Msg
)msg
);
236 data
= INST_DATA(cl
, o
);
238 EG(o
)->GadgetRender
= NewObjectA(NULL
, FRAMEICLASS
, frametags
);
239 D(bug("[tapedeck.gadget] %s: frame @ 0x%p\n", __PRETTY_FUNCTION__
, EG(o
)->GadgetRender
));
241 data
->tdd_ButtonPen
[0] = SHADOWPEN
;
242 data
->tdd_ButtonPen
[1] = SHADOWPEN
;
243 data
->tdd_ButtonPen
[2] = SHADOWPEN
;
245 pproptags
[3].ti_Data
= data
->tdd_FrameCount
;
246 pproptags
[4].ti_Data
= data
->tdd_FrameCurrent
;
247 data
->tdd_PosProp
= NewObjectA(NULL
, "propgclass", pproptags
);
249 D(bug("[tapedeck.gadget] %s: playback position prop @ 0x%p\n", __PRETTY_FUNCTION__
, data
->tdd_PosProp
));
251 if (msg
->ops_AttrList
)
253 msg
->ops_AttrList
= tdinittags
;
254 TapeDeck__OM_SET(cl
, o
, msg
);
261 /***********************************************************************************/
263 VOID
TapeDeck__OM_DISPOSE(Class
*cl
, Object
*o
, Msg msg
)
265 struct TapeDeckData
*data
= INST_DATA(cl
, o
);
267 D(bug("[tapedeck.gadget]: %s()\n", __PRETTY_FUNCTION__
));
269 if (data
->tdd_PosProp
)
270 DisposeObject((Object
*)data
->tdd_PosProp
);
272 if (EG(o
)->GadgetRender
)
273 DisposeObject((Object
*)EG(o
)->GadgetRender
);
275 DoSuperMethodA(cl
,o
,msg
);
278 /***********************************************************************************/
280 IPTR
TapeDeck__GM_LAYOUT(Class
*cl
, struct Gadget
*g
, struct gpLayout
*msg
)
282 struct TapeDeckData
*data
= INST_DATA(cl
, g
);
283 struct TagItem frametags
[] = {
284 { GA_Left
, g
->LeftEdge
},
285 { GA_Top
, g
->TopEdge
},
286 { IA_Width
, g
->Width
},
287 { IA_Height
, g
->Height
},
292 D(bug("[tapedeck.gadget]: %s()\n", __PRETTY_FUNCTION__
));
294 RetVal
= DoSuperMethodA(cl
, (Object
*)g
, (Msg
)msg
);
296 SetAttrsA((Object
*)g
->GadgetRender
, frametags
);
297 DoMethodA((Object
*)g
->GadgetRender
, msg
);
299 frametags
[0].ti_Data
= g
->LeftEdge
+ 1;
300 frametags
[2].ti_Tag
= GA_Width
;
301 frametags
[2].ti_Data
= g
->Width
- 2;
302 frametags
[3].ti_Tag
= GA_Height
;
303 frametags
[3].ti_Data
= POSPROP_HEIGHT
;
305 SetAttrsA((Object
*)data
->tdd_PosProp
, frametags
);
306 DoMethodA((Object
*)data
->tdd_PosProp
, msg
);
311 IPTR
TapeDeck__GM_RENDER(Class
*cl
, Object
*o
, struct gpRender
*msg
)
313 struct TapeDeckData
*data
= INST_DATA(cl
, o
);
314 struct TagItem proptags
[] = {
315 { PGA_Total
, data
->tdd_FrameCount
},
316 { PGA_Top
, data
->tdd_FrameCurrent
},
322 D(bug("[tapedeck.gadget]: %s()\n", __PRETTY_FUNCTION__
));
324 if ((msg
->gpr_Redraw
!= GREDRAW_UPDATE
) && (EG(o
)->GadgetRender
))
326 /* Full redraw: clear and draw border */
327 DrawImageState(msg
->gpr_RPort
, IM(EG(o
)->GadgetRender
),
328 EG(o
)->LeftEdge
, EG(o
)->TopEdge
,
330 msg
->gpr_GInfo
->gi_DrInfo
);
333 GetAttr (PGA_Top
, (Object
*)data
->tdd_PosProp
, &propTop
);
334 if (propTop
!= data
->tdd_FrameCurrent
)
336 SetAttrsA((Object
*)data
->tdd_PosProp
, proptags
);
337 SetAPen(msg
->gpr_RPort
, msg
->gpr_GInfo
->gi_DrInfo
->dri_Pens
[BACKGROUNDPEN
]);
338 RectFill(msg
->gpr_RPort
,
339 EG(o
)->LeftEdge
+ 2, EG(o
)->TopEdge
+ 1,
340 EG(o
)->LeftEdge
+ EG(o
)->Width
- 2, EG(o
)->TopEdge
+ POSPROP_HEIGHT
);
342 DoMethodA((Object
*)data
->tdd_PosProp
, (Msg
)msg
);
344 rend_x
= EG(o
)->LeftEdge
+ ((EG(o
)->Width
- 50) >> 1);
345 rend_y
= EG(o
)->TopEdge
+ 4 + ((EG(o
)->Height
- 11) >> 1);
347 if ((msg
->gpr_Redraw
!= GREDRAW_UPDATE
) || (data
->tdd_ButtonPen
[0] != data
->tdd_LastPen
[0]))
349 SetAPen(msg
->gpr_RPort
, msg
->gpr_GInfo
->gi_DrInfo
->dri_Pens
[data
->tdd_ButtonPen
[0]]);
351 BltTemplate ((void *) templateRewind
,
353 msg
->gpr_RPort
, rend_x
, rend_y
,
356 data
->tdd_LastPen
[0] = data
->tdd_ButtonPen
[0];
359 if ((msg
->gpr_Redraw
!= GREDRAW_UPDATE
) || (data
->tdd_ButtonPen
[1] != data
->tdd_LastPen
[1]))
361 if (data
->tdd_Mode
!= data
->tdd_ModeLast
)
363 SetAPen(msg
->gpr_RPort
, msg
->gpr_GInfo
->gi_DrInfo
->dri_Pens
[BACKGROUNDPEN
]);
364 RectFill(msg
->gpr_RPort
,
366 rend_x
+ 28, rend_y
+ 6);
369 SetAPen(msg
->gpr_RPort
, msg
->gpr_GInfo
->gi_DrInfo
->dri_Pens
[data
->tdd_ButtonPen
[1]]);
371 if (data
->tdd_Mode
== BUT_PLAY
)
373 BltTemplate ((void *) templatePause
,
375 msg
->gpr_RPort
, rend_x
+ 21, rend_y
,
380 BltTemplate ((void *) templatePlay
,
382 msg
->gpr_RPort
, rend_x
+ 21, rend_y
,
386 data
->tdd_LastPen
[1] = data
->tdd_ButtonPen
[1];
389 if ((msg
->gpr_Redraw
!= GREDRAW_UPDATE
) || (data
->tdd_ButtonPen
[2] != data
->tdd_LastPen
[2]))
391 SetAPen(msg
->gpr_RPort
, msg
->gpr_GInfo
->gi_DrInfo
->dri_Pens
[data
->tdd_ButtonPen
[2]]);
393 BltTemplate ((void *) templateFForward
,
395 msg
->gpr_RPort
, rend_x
+ 34, rend_y
,
398 data
->tdd_LastPen
[2] = data
->tdd_ButtonPen
[2];
404 /***********************************************************************************/
406 IPTR
TapeDeck__GM_HANDLEINPUT(Class
*cl
, Object
*o
, struct gpInput
*msg
)
408 struct RastPort
*rport
;
409 struct TapeDeckData
*data
= INST_DATA(cl
, o
);
410 struct InputEvent
*ie
= msg
->gpi_IEvent
;
411 IPTR retval
= GMR_MEACTIVE
;
414 D(bug("[tapedeck.gadget]: %s()\n", __PRETTY_FUNCTION__
));
416 if (ie
->ie_Code
== SELECTDOWN
)
418 D(bug("[tapedeck.gadget]: %s: SELECTDOWN\n", __PRETTY_FUNCTION__
));
419 EG(o
)->Flags
|= GFLG_SELECTED
;
422 if ((data
->tdd_PosProp
) &&
423 ((((struct Gadget
*)data
->tdd_PosProp
)->Flags
& GFLG_SELECTED
) || (msg
->gpi_Mouse
.Y
< POSPROP_HEIGHT
)))
427 D(bug("[tapedeck.gadget]: %s: input event is for the prop gadget ...\n", __PRETTY_FUNCTION__
));
429 if (ie
->ie_Code
== SELECTDOWN
)
431 GetAttr (PGA_Top
, (Object
*)data
->tdd_PosProp
, &data
->tdd_TopLast
);
432 data
->tdd_ModeLast
= data
->tdd_Mode
;
433 data
->tdd_Mode
= BUT_FRAME
;
436 /* pass it to the prop gadget .. */
437 DoMethodA((Object
*)data
->tdd_PosProp
, (Msg
)msg
);
439 if (data
->tdd_Mode
== BUT_FRAME
)
441 GetAttr (PGA_Top
, (Object
*)data
->tdd_PosProp
, &topCurrent
);
442 if (data
->tdd_TopLast
!= topCurrent
)
444 D(bug("[tapedeck.gadget]: %s: position moved ...(%d)\n", __PRETTY_FUNCTION__
, topCurrent
));
445 data
->tdd_FrameCurrent
= topCurrent
;
447 if (ie
->ie_Code
== SELECTUP
)
448 data
->tdd_Mode
= data
->tdd_ModeLast
;
452 if ((msg
->gpi_Mouse
.Y
> ((EG(o
)->Height
- 11) >> 1)) &&
453 (msg
->gpi_Mouse
.Y
< (EG(o
)->Height
- ((EG(o
)->Height
- 11) >> 1))) &&
454 (msg
->gpi_Mouse
.X
> ((EG(o
)->Width
- 50) >> 1)))
456 ULONG offset_x
= msg
->gpi_Mouse
.X
- ((EG(o
)->Width
- 50) >> 1);
460 D(bug("[tapedeck.gadget]: %s: <<\n", __PRETTY_FUNCTION__
));
461 if (ie
->ie_Code
== SELECTDOWN
)
463 data
->tdd_ButtonActive
= 1;
464 data
->tdd_ButtonPen
[0] = SHINEPEN
;
465 data
->tdd_ModeLast
= data
->tdd_Mode
;
466 data
->tdd_Mode
= BUT_REWIND
;
469 else if (ie
->ie_Code
== SELECTUP
)
471 data
->tdd_ButtonPen
[0] = SHADOWPEN
;
472 data
->tdd_Mode
= data
->tdd_ModeLast
;
475 else if ((offset_x
> 20) && (offset_x
< 29))
477 D(bug("[tapedeck.gadget]: %s: PLAY/PAUSE\n", __PRETTY_FUNCTION__
));
478 if (ie
->ie_Code
== SELECTDOWN
)
480 data
->tdd_ButtonActive
= 2;
481 data
->tdd_ButtonPen
[1] = SHINEPEN
;
484 else if (ie
->ie_Code
== SELECTUP
)
486 data
->tdd_ButtonPen
[1] = SHADOWPEN
;
487 data
->tdd_ModeLast
= data
->tdd_Mode
;
488 if (data
->tdd_Mode
!= BUT_PLAY
)
489 data
->tdd_Mode
= BUT_PLAY
;
491 data
->tdd_Mode
= BUT_PAUSE
;
494 else if ((offset_x
> 33) && (offset_x
< 50))
496 D(bug("[tapedeck.gadget]: %s: >>\n", __PRETTY_FUNCTION__
));
497 if (ie
->ie_Code
== SELECTDOWN
)
499 data
->tdd_ButtonActive
= 3;
500 data
->tdd_ButtonPen
[2] = SHINEPEN
;
501 data
->tdd_ModeLast
= data
->tdd_Mode
;
502 data
->tdd_Mode
= BUT_FORWARD
;
505 else if (ie
->ie_Code
== SELECTUP
)
507 data
->tdd_ButtonPen
[2] = SHADOWPEN
;
508 data
->tdd_Mode
= data
->tdd_ModeLast
;
513 if (ie
->ie_Code
== SELECTUP
)
515 D(bug("[tapedeck.gadget]: %s: SELECTUP\n", __PRETTY_FUNCTION__
));
516 if (data
->tdd_ButtonActive
> 0)
518 data
->tdd_ButtonPen
[data
->tdd_ButtonActive
- 1] = SHADOWPEN
;
521 EG(o
)->Flags
&= ~GFLG_SELECTED
;
522 data
->tdd_ButtonActive
= 0;
523 retval
= GMR_NOREUSE
;
527 (rport
= ObtainGIRPort (msg
->gpi_GInfo
)))
531 gpr
.MethodID
= GM_RENDER
;
532 gpr
.gpr_GInfo
= msg
->gpi_GInfo
;
533 gpr
.gpr_RPort
= rport
;
534 gpr
.gpr_Redraw
= GREDRAW_UPDATE
;
537 ReleaseGIRPort (rport
);
543 /***********************************************************************************/
545 IPTR
TapeDeck__GM_GOINACTIVE(Class
*cl
, Object
*o
, struct gpGoInactive
*msg
)
547 struct RastPort
*rport
;
549 D(bug("[tapedeck.gadget]: %s()\n", __PRETTY_FUNCTION__
));
551 EG(o
)->Flags
&= ~GFLG_SELECTED
;
553 rport
= ObtainGIRPort(msg
->gpgi_GInfo
);
556 struct gpRender rmsg
= { GM_RENDER
, msg
->gpgi_GInfo
, rport
, GREDRAW_UPDATE
}, *p_rmsg
= &rmsg
;
558 DoMethodA(o
, (Msg
)p_rmsg
);
559 ReleaseGIRPort(rport
);