2 Copyright © 2002-2015, The AROS Development Team. All rights reserved.
6 /* Dtpic.mui. Source based on the one from MUIUndoc */
8 #define MUIMASTER_YES_INLINE_STDARG
13 #include <graphics/gfx.h>
14 #include <graphics/view.h>
15 #include <clib/alib_protos.h>
17 #include <datatypes/datatypesclass.h>
18 #include <datatypes/pictureclass.h>
19 #include <cybergraphx/cybergraphics.h>
21 #include <proto/exec.h>
22 #include <proto/graphics.h>
23 #include <proto/cybergraphics.h>
24 #include <proto/utility.h>
25 #include <proto/intuition.h>
26 #include <proto/muimaster.h>
27 #include <proto/datatypes.h>
31 /* #define MYDEBUG 1 */
35 #include "muimaster_intern.h"
37 #include "support_classes.h"
38 #include "dtpic_private.h"
40 extern struct Library
*MUIMasterBase
;
46 #define DataTypesBase data->datatypesbase
48 static void killdto(struct Dtpic_DATA
*data
)
50 if (data
->bm_selected
) FreeBitMap(data
->bm_selected
);
51 if (data
->bm_highlighted
) FreeBitMap(data
->bm_highlighted
);
54 data
->bm_selected
= NULL
;
55 data
->bm_highlighted
= NULL
;
59 DisposeDTObject(data
->dto
);
63 if (data
->datatypesbase
)
65 CloseLibrary(data
->datatypesbase
);
69 static void change_event_handler(Object
*obj
, struct Dtpic_DATA
*data
)
71 // enable only events which we really need
74 if (data
->darkenselstate
)
76 events
|= IDCMP_MOUSEBUTTONS
;
80 // disable pending selected state
81 data
->selected
= FALSE
;
84 if (data
->lightenonmouse
)
86 // FIXME: change to IDCMP_MOUSEOBJECT if available
87 events
|= IDCMP_MOUSEMOVE
;
91 // disable highlighting mode
92 data
->highlighted
= FALSE
;
97 events
|= IDCMP_INTUITICKS
;
100 if (events
!= data
->ehn
.ehn_Events
)
102 // remove event handler if it was installed
105 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, &data
->ehn
);
107 // enable event handler for changed events
108 data
->ehn
.ehn_Events
= events
;
109 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, &data
->ehn
);
110 data
->eh_active
= TRUE
;
114 static void update_alpha(struct Dtpic_DATA
*data
)
118 // immediately set alpha to end value
119 data
->currentalpha
= data
->alpha
;
120 data
->deltaalpha
= 0;
125 if (data
->alpha
> data
->currentalpha
)
127 // fading should happen every 1/20 sec.
128 // Because we're using Intuiticks we must
129 // convert the value.
130 data
->deltaalpha
= data
->fade
* 50 / 20;
132 else if (data
->alpha
< data
->currentalpha
)
134 data
->deltaalpha
= -data
->fade
* 50 / 20;
138 data
->deltaalpha
= 0;
141 D(bug("[Dtpic/update_alpha] alpha %d delta %d current %d\n",
142 data
->alpha
, data
->deltaalpha
, data
->currentalpha
));
145 static struct BitMap
*clone_bitmap(struct BitMap
*from_bm
, ULONG operation
,
151 struct BitMap
*to_bm
= NULL
;
154 UWORD width
= GetBitMapAttr(from_bm
, BMA_WIDTH
);
155 UWORD height
= GetBitMapAttr(from_bm
, BMA_HEIGHT
);
156 UWORD depth
= GetBitMapAttr(from_bm
, BMA_DEPTH
);
159 to_bm
= AllocBitMap(width
, height
, depth
, BMF_MINPLANES
, from_bm
);
160 D(bug("[clone_bitmap] %p width %d height %d depth %d\n", to_bm
, width
,
165 BltBitMapRastPort(from_bm
, 0, 0, &rp
, 0, 0, width
, height
, 0xC0);
166 ProcessPixelArray(&rp
, 0, 0, width
, height
, operation
, value
, NULL
);
171 IPTR
setup_datatype(struct IClass
*cl
, Object
*obj
)
173 struct Dtpic_DATA
*data
= INST_DATA(cl
, obj
);
176 killdto(data
); /* Object already existed */
180 if ((data
->datatypesbase
= OpenLibrary("datatypes.library", 39)))
182 /* Prevent DOS Requesters from showing up */
184 struct Process
*me
= (struct Process
*)FindTask(0);
185 APTR oldwinptr
= me
->pr_WindowPtr
;
187 me
->pr_WindowPtr
= (APTR
) - 1;
189 data
->dto
= NewDTObject(data
->name
, DTA_GroupID
, GID_PICTURE
,
190 OBP_Precision
, PRECISION_IMAGE
,
191 PDTA_Screen
, _screen(obj
),
192 PDTA_DestMode
, PMODE_V43
,
193 PDTA_UseFriendBitMap
, TRUE
, TAG_DONE
);
194 me
->pr_WindowPtr
= oldwinptr
;
198 struct FrameInfo fri
= { 0 };
200 DoMethod(data
->dto
, DTM_FRAMEBOX
, 0, &fri
, &fri
,
201 sizeof(struct FrameInfo
), 0);
203 if (fri
.fri_Dimensions
.Depth
> 0)
205 if (DoMethod(data
->dto
, DTM_PROCLAYOUT
, 0, 1))
207 get(data
->dto
, PDTA_BitMapHeader
, &data
->bmhd
);
211 if (data
->bmhd
->bmh_Masking
!= mskNone
)
212 set(obj
, MUIA_FillArea
, TRUE
);
214 set(obj
, MUIA_FillArea
, FALSE
);
216 GetDTAttrs(data
->dto
, PDTA_DestBitMap
,
217 &data
->bm
, TAG_DONE
);
221 GetDTAttrs(data
->dto
, PDTA_BitMap
,
222 &data
->bm
, TAG_DONE
);
227 /* create BitMaps for selected and
228 * highlighted state */
230 clone_bitmap(data
->bm
, POP_DARKEN
, 127);
231 data
->bm_highlighted
=
232 clone_bitmap(data
->bm
, POP_BRIGHTEN
, 50);
247 IPTR
Dtpic__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
249 obj
= (Object
*) DoSuperMethodA(cl
, obj
, (Msg
) msg
);
253 struct Dtpic_DATA
*data
= INST_DATA(cl
, obj
);
254 struct TagItem
*tags
= msg
->ops_AttrList
;
258 data
->currentalpha
= data
->alpha
= 0xff;
260 while ((tag
= NextTagItem(&tags
)) != NULL
)
264 case MUIA_Dtpic_Name
:
265 // acc. to AOS4-MUI4 autodoc the string isn't copied
266 data
->name
= (STRPTR
)tag
->ti_Data
;
268 case MUIA_Dtpic_Alpha
:
269 data
->alpha
= tag
->ti_Data
;
271 case MUIA_Dtpic_DarkenSelState
:
272 data
->darkenselstate
= tag
->ti_Data
? TRUE
: FALSE
;
274 case MUIA_Dtpic_Fade
:
275 data
->fade
= tag
->ti_Data
;
277 case MUIA_Dtpic_LightenOnMouse
:
278 data
->lightenonmouse
= tag
->ti_Data
? TRUE
: FALSE
;
283 data
->ehn
.ehn_Events
= 0;
284 data
->ehn
.ehn_Priority
= 0;
285 data
->ehn
.ehn_Flags
= 0;
286 data
->ehn
.ehn_Object
= obj
;
287 data
->ehn
.ehn_Class
= cl
;
295 IPTR
Dtpic__MUIM_Setup(struct IClass
*cl
, Object
*obj
,
296 struct MUIP_Setup
*msg
)
298 if (!DoSuperMethodA(cl
, obj
, (Msg
) msg
))
301 return setup_datatype(cl
, obj
);
304 IPTR
Dtpic__MUIM_Cleanup(struct IClass
*cl
, Object
*obj
,
305 struct MUIP_Cleanup
*msg
)
307 struct Dtpic_DATA
*data
= INST_DATA(cl
, obj
);
311 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, &data
->ehn
);
316 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
319 IPTR
Dtpic__MUIM_AskMinMax(struct IClass
*cl
, Object
*obj
,
320 struct MUIP_AskMinMax
*msg
)
322 struct Dtpic_DATA
*data
= INST_DATA(cl
, obj
);
325 retval
= DoSuperMethodA(cl
, obj
, (Msg
) msg
);
329 msg
->MinMaxInfo
->MinWidth
+= data
->bmhd
->bmh_Width
;
330 msg
->MinMaxInfo
->MinHeight
+= data
->bmhd
->bmh_Height
;
331 msg
->MinMaxInfo
->DefWidth
+= data
->bmhd
->bmh_Width
;
332 msg
->MinMaxInfo
->DefHeight
+= data
->bmhd
->bmh_Height
;
333 msg
->MinMaxInfo
->MaxWidth
+= data
->bmhd
->bmh_Width
;
334 msg
->MinMaxInfo
->MaxHeight
+= data
->bmhd
->bmh_Height
;
340 IPTR
Dtpic__MUIM_Draw(struct IClass
*cl
, Object
*obj
,
341 struct MUIP_Draw
*msg
)
343 struct Dtpic_DATA
*data
= INST_DATA(cl
, obj
);
345 // TODO: rendering of different states
347 D(bug("[Dtpic/MUIM_Draw] selected %d highlighted %d alpha %d\n",
348 data
->selected
, data
->highlighted
, data
->currentalpha
));
350 DoSuperMethodA(cl
, obj
, (Msg
) msg
);
352 if ((msg
->flags
& (MADF_DRAWOBJECT
| MADF_DRAWUPDATE
)) && data
->bm
)
354 /* Note: codes taken from picture.datatype GM_RENDER routine */
355 ULONG depth
= (ULONG
) GetBitMapAttr(_rp(obj
)->BitMap
, BMA_DEPTH
);
357 if ((depth
>= 15) && (data
->bmhd
->bmh_Masking
== mskHasAlpha
))
359 /* Transparency on high color rast port with alpha channel in
362 AllocVec(_mwidth(obj
) * _mheight(obj
) * 4, MEMF_ANY
);
365 struct pdtBlitPixelArray pa
;
366 pa
.MethodID
= PDTM_READPIXELARRAY
;
367 pa
.pbpa_PixelData
= (UBYTE
*) img
;
368 pa
.pbpa_PixelFormat
= PBPAFMT_ARGB
;
369 pa
.pbpa_PixelArrayMod
= _mwidth(obj
) * 4;
372 pa
.pbpa_Width
= _mwidth(obj
);
373 pa
.pbpa_Height
= _mheight(obj
);
374 if (DoMethodA(data
->dto
, (Msg
) & pa
))
375 WritePixelArrayAlpha(img
, 0, 0, _mwidth(obj
) * 4,
376 _rp(obj
), _mleft(obj
), _mtop(obj
), _mwidth(obj
),
377 _mheight(obj
), 0xffffffff);
383 if (data
->bmhd
->bmh_Masking
== mskHasMask
)
385 /* Transparency with mask */
388 GetDTAttrs(data
->dto
, PDTA_MaskPlane
, (IPTR
) & mask
,
392 BltMaskBitMapRastPort(data
->bm
, 0, 0, _rp(obj
),
393 _mleft(obj
), _mtop(obj
), _mwidth(obj
),
394 _mheight(obj
), 0xE0, (PLANEPTR
) mask
);
398 /* All other cases */
400 struct BitMap
*bm
= data
->bm
;
403 bm
= data
->bm_selected
;
404 D(bug("render selected\n"));
406 else if (data
->highlighted
)
408 D(bug("render highlighted\n"));
409 bm
= data
->bm_highlighted
;
413 D(bug("render normal\n"));
416 BltBitMapRastPort(bm
, 0, 0, _rp(obj
), _mleft(obj
),
417 _mtop(obj
), _mwidth(obj
), _mheight(obj
), 0xC0);
425 IPTR
Dtpic__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
427 //struct Dtpic_DATA *data = INST_DATA(cl, obj);
429 return DoSuperMethodA(cl
, obj
, msg
);
432 IPTR
Dtpic__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
434 struct Dtpic_DATA
*data
= INST_DATA(cl
, obj
);
435 struct TagItem
*tags
= msg
->ops_AttrList
;
437 ULONG needs_redraw
= 0;
439 while ((tag
= NextTagItem(&tags
)) != NULL
)
443 case MUIA_Dtpic_Name
:
444 /* If no filename or different filenames */
445 if (!data
->name
|| strcmp(data
->name
, (char *)tag
->ti_Data
))
447 data
->name
= (STRPTR
)tag
->ti_Data
;
449 /* Run immediate setup only if base class is setup up */
450 if (_flags(obj
) & MADF_SETUP
)
451 setup_datatype(cl
, obj
);
455 case MUIA_Dtpic_Alpha
:
456 data
->alpha
= tag
->ti_Data
;
458 case MUIA_Dtpic_Fade
:
459 data
->fade
= tag
->ti_Data
;
465 if (_flags(obj
) & MADF_SETUP
)
466 change_event_handler(obj
, data
);
470 MUI_Redraw(obj
, MADF_DRAWOBJECT
);
473 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
476 IPTR
Dtpic__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
478 struct Dtpic_DATA
*data
= INST_DATA(cl
, obj
);
480 switch (msg
->opg_AttrID
)
482 case MUIA_Dtpic_Name
:
483 *(msg
->opg_Storage
) = (IPTR
) data
->name
;
485 case MUIA_Dtpic_Alpha
:
486 *(msg
->opg_Storage
) = data
->alpha
;
488 case MUIA_Dtpic_DarkenSelState
:
489 *(msg
->opg_Storage
) = data
->darkenselstate
;
491 case MUIA_Dtpic_Fade
:
492 *(msg
->opg_Storage
) = data
->fade
;
494 case MUIA_Dtpic_LightenOnMouse
:
495 *(msg
->opg_Storage
) = data
->lightenonmouse
;
499 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
502 IPTR
Dtpic__MUIM_HandleEvent(struct IClass
*cl
, Object
*obj
,
503 struct MUIP_HandleEvent
*msg
)
505 struct Dtpic_DATA
*data
= INST_DATA(cl
, obj
);
509 switch (msg
->imsg
->Class
)
511 case IDCMP_INTUITICKS
:
512 data
->currentalpha
+= data
->deltaalpha
;
513 if (data
->deltaalpha
> 0)
515 if (data
->currentalpha
> data
->alpha
)
517 // reached target alpha, no more incrementing
518 data
->currentalpha
= data
->alpha
;
519 data
->deltaalpha
= 0;
522 else if (data
->deltaalpha
< 0)
524 if (data
->currentalpha
< data
->alpha
)
526 // reached target alpha, no more decrementing
527 data
->currentalpha
= data
->alpha
;
528 data
->deltaalpha
= 0;
531 D(bug("intuitick %d %d\n", msg
->imsg
->MouseX
, msg
->imsg
->MouseY
));
533 change_event_handler(obj
, data
);
534 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
538 case IDCMP_MOUSEBUTTONS
:
539 if (msg
->imsg
->Code
==SELECTDOWN
)
541 if (_isinobject(obj
, msg
->imsg
->MouseX
, msg
->imsg
->MouseY
))
543 data
->selected
= TRUE
;
544 D(bug("selectdown %d %d\n", msg
->imsg
->MouseX
,
546 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
549 else if (msg
->imsg
->Code
==SELECTUP
)
551 if (_isinobject(obj
, msg
->imsg
->MouseX
, msg
->imsg
->MouseY
))
553 data
->selected
= FALSE
;
554 D(bug("selectup %d %d\n", msg
->imsg
->MouseX
,
556 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
561 case IDCMP_MOUSEMOVE
:
562 if (_isinobject(obj
, msg
->imsg
->MouseX
, msg
->imsg
->MouseY
))
564 data
->highlighted
= TRUE
;
565 D(bug("mouse move %d %d\n", msg
->imsg
->MouseX
,
570 data
->highlighted
= FALSE
;
572 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
580 IPTR
Dtpic__MUIM_Show(struct IClass
*cl
, Object
*obj
,
581 struct MUIP_Show
*msg
)
583 struct Dtpic_DATA
*data
= INST_DATA(cl
, obj
);
586 retval
= DoSuperMethodA(cl
, obj
, (Msg
) msg
);
588 change_event_handler(obj
, data
);
593 IPTR
Dtpic__MUIM_Hide(struct IClass
*cl
, Object
*obj
,
594 struct MUIP_Hide
*msg
)
596 struct Dtpic_DATA
*data
= INST_DATA(cl
, obj
);
598 // remove event handler if it was installed
601 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, &data
->ehn
);
602 data
->eh_active
= FALSE
;
605 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
609 #if ZUNE_BUILTIN_DTPIC
610 BOOPSI_DISPATCHER(IPTR
, Dtpic_Dispatcher
, cl
, obj
, msg
)
612 switch (msg
->MethodID
)
615 return Dtpic__OM_NEW(cl
, obj
, (APTR
)msg
);
617 return Dtpic__OM_DISPOSE(cl
, obj
, (APTR
)msg
);
619 return Dtpic__OM_SET(cl
, obj
, (APTR
)msg
);
621 return Dtpic__OM_GET(cl
, obj
, (APTR
)msg
);
624 return Dtpic__MUIM_Setup(cl
, obj
, (APTR
)msg
);
626 return Dtpic__MUIM_Cleanup(cl
, obj
, (APTR
)msg
);
629 return Dtpic__MUIM_Show(cl
, obj
, (APTR
)msg
);
631 return Dtpic__MUIM_Show(cl
, obj
, (APTR
)msg
);
634 return Dtpic__MUIM_AskMinMax(cl
, obj
, (APTR
)msg
);
636 return Dtpic__MUIM_Draw(cl
, obj
, (APTR
)msg
);
637 case MUIM_HandleEvent
:
638 return Dtpic__MUIM_HandleEvent(cl
, obj
, (APTR
)msg
);
641 return DoSuperMethodA(cl
, obj
, msg
);
644 BOOPSI_DISPATCHER_END
646 const struct __MUIBuiltinClass _MUI_Dtpic_desc
=
650 sizeof(struct Dtpic_DATA
),
651 (void *) Dtpic_Dispatcher
653 #endif /* ZUNE_BUILTIN_DTPIC */