2 Copyright 2002-2019, The AROS Development Team. All rights reserved.
8 #include <intuition/imageclass.h>
9 #include <datatypes/pictureclass.h>
11 #include <graphics/gfx.h>
12 #include <graphics/view.h>
13 #include <clib/alib_protos.h>
14 #include <proto/exec.h>
15 #include <proto/graphics.h>
16 #include <proto/utility.h>
17 #include <proto/intuition.h>
18 #include <proto/muimaster.h>
19 #include <proto/cybergraphics.h>
20 #include <proto/datatypes.h>
24 /* #define MYDEBUG 1 */
26 #include "../datatypescache.h"
27 #include "../imspec_intern.h"
31 #include "muimaster_intern.h"
35 // FIXME: quick hack to not draw the background for gradients. It should really be generalized
36 #include "imspec_intern.h"
38 extern struct Library
*MUIMasterBase
;
40 #define MIF_FREEVERT (1<<0)
41 #define MIF_FREEHORIZ (1<<1)
42 #define MIF_FONTMATCHWIDTH (1<<3)
43 #define MIF_FONTMATCHHEIGHT (1<<4)
49 struct MUI_ImageSpec_intern
*img
;
50 struct NewImage
*propimage
;
51 struct Image
*old_image
;
52 Object
*prop
; /* private hack to use prop images */
53 LONG state
; /* see IDS_* in intuition/imageclass.h */
58 /**************************************************************************
60 **************************************************************************/
61 IPTR
Image__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
63 struct MUI_ImageData
*data
;
68 /* D(bug("Image_New starts\n")); */
70 prop
= (Object
*)GetTagData(MUIA_Image_Prop
, 0, msg
->ops_AttrList
);
73 obj
= (Object
*)DoSuperMethodA(cl
, obj
, (Msg
)msg
);
74 if (!obj
) return FALSE
;
76 data
= INST_DATA(cl
, obj
);
77 data
->state
= IDS_NORMAL
;
79 /* parse initial taglist */
81 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
)); )
87 data
->state
= IDS_SELECTED
;
89 case MUIA_Image_FontMatch
:
90 _handle_bool_tag(data
->flags
, tag
->ti_Data
, MIF_FONTMATCHWIDTH
);
91 _handle_bool_tag(data
->flags
, tag
->ti_Data
, MIF_FONTMATCHHEIGHT
);
93 case MUIA_Image_FontMatchWidth
:
94 _handle_bool_tag(data
->flags
, tag
->ti_Data
, MIF_FONTMATCHWIDTH
);
96 case MUIA_Image_FontMatchHeight
:
97 _handle_bool_tag(data
->flags
, tag
->ti_Data
, MIF_FONTMATCHHEIGHT
);
99 case MUIA_Image_FreeHoriz
:
100 _handle_bool_tag(data
->flags
, tag
->ti_Data
, MIF_FREEHORIZ
);
102 case MUIA_Image_FreeVert
:
103 _handle_bool_tag(data
->flags
, tag
->ti_Data
, MIF_FREEVERT
);
105 case MUIA_Image_Spec
:
110 data
->specnr
= tag
->ti_Data
;
112 if (tag
->ti_Data
>= MUII_WindowBack
&& tag
->ti_Data
< MUII_BACKGROUND
)
114 sprintf(spec_buf
,"6:%ld",tag
->ti_Data
);
117 else if (tag
->ti_Data
>= MUII_BACKGROUND
&& tag
->ti_Data
< MUII_LASTPAT
)
119 sprintf(spec_buf
,"0:%ld",tag
->ti_Data
);
124 spec
= (char*)tag
->ti_Data
;
126 data
->spec
= StrDup(spec
);
130 case MUIA_Image_OldImage
:
131 data
->old_image
= (struct Image
*)tag
->ti_Data
;
133 case MUIA_Image_State
:
134 data
->state
= (LONG
)tag
->ti_Data
;
141 /* if (!data->spec && !data->old_image) */
143 /* data->spec = StrDup("0:128"); */
146 /* if (!data->spec && !data->old_image) */
148 /* CoerceMethod(cl,obj,OM_DISPOSE); */
152 /* D(bug("Image_New(%lx) spec=%lx\n", obj, data->img)); */
156 /**************************************************************************
158 **************************************************************************/
159 IPTR
Image__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
161 struct MUI_ImageData
*data
= INST_DATA(cl
, obj
);
164 zune_image_spec_free(data
->spec
);
165 DoSuperMethodA(cl
,obj
,(Msg
)msg
);
169 /**************************************************************************
171 **************************************************************************/
172 IPTR
Image__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
174 struct MUI_ImageData
*data
= INST_DATA(cl
, obj
);
175 struct TagItem
*tag
, *tags
;
177 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
)); )
183 data
->state
= IDS_SELECTED
;
185 data
->state
= IDS_NORMAL
;
186 D(bug("Image_Set(%p): state=%ld\n", obj
, data
->state
));
188 case MUIA_Image_State
:
189 if (data
->state
!= (LONG
)tag
->ti_Data
)
191 data
->state
= (LONG
)tag
->ti_Data
;
192 MUI_Redraw(obj
,MADF_DRAWOBJECT
);
195 case MUIA_Image_Spec
:
196 data
->specnr
= tag
->ti_Data
;
198 zune_image_spec_free(data
->spec
);
199 data
->spec
= zune_image_spec_duplicate(tag
->ti_Data
);
201 if ((_flags(obj
) & MADF_CANDRAW
) && data
->img
)
202 zune_imspec_hide(data
->img
);
204 if (_flags(obj
) & MADF_SETUP
)
207 zune_imspec_cleanup(data
->img
);
208 data
->img
= zune_imspec_setup((IPTR
)data
->spec
, muiRenderInfo(obj
));
209 // FIXME: quick hack to not draw the background for gradients. It should really be generalized
212 if (data
->img
->type
== IST_SCALED_GRADIENT
213 || data
->img
->type
== IST_TILED_GRADIENT
)
214 set(obj
, MUIA_FillArea
, FALSE
);
216 set(obj
, MUIA_FillArea
, TRUE
);
220 if (_flags(obj
) & MADF_CANDRAW
)
221 zune_imspec_show(data
->img
, obj
);
223 MUI_Redraw(obj
,MADF_DRAWOBJECT
);
228 return (IPTR
)DoSuperMethodA(cl
,obj
,(Msg
)msg
);
231 /**************************************************************************
233 **************************************************************************/
234 IPTR
Image__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
236 struct MUI_ImageData
*data
= INST_DATA(cl
, obj
);
237 switch (msg
->opg_AttrID
)
239 case MUIA_Image_Spec
:
240 *msg
->opg_Storage
= (IPTR
)data
->spec
;
244 return (IPTR
)DoSuperMethodA(cl
,obj
,(Msg
)msg
);
247 struct NewImage
*GetPropImage(struct MUI_ImageData
*data
, Object
*prop
)
249 struct MUI_AreaData
*adata
= muiAreaData(prop
);
250 struct MUI_ImageSpec_intern
*spec
= adata
->mad_Background
;
254 if (spec
->type
== IST_BITMAP
)
256 struct dt_node
*node
= spec
->u
.bitmap
.dt
;
259 if (node
->mode
== MODE_PROP
)
261 if (data
->specnr
== MUII_ArrowDown
) return node
->img_down
;
262 if (data
->specnr
== MUII_ArrowUp
) return node
->img_up
;
263 if (data
->specnr
== MUII_ArrowLeft
) return node
->img_left
;
264 if (data
->specnr
== MUII_ArrowRight
) return node
->img_right
;
272 /**************************************************************************
274 **************************************************************************/
275 IPTR
Image__MUIM_Setup(struct IClass
*cl
, Object
*obj
, struct MUIP_Setup
*msg
)
277 struct MUI_ImageData
*data
= INST_DATA(cl
, obj
);
278 if (!DoSuperMethodA(cl
, obj
, (Msg
)msg
))
280 data
->propimage
= NULL
;
284 if (muiGlobalInfo(obj
)->mgi_Prefs
->scrollbar_type
== SCROLLBAR_TYPE_CUSTOM
)
286 struct NewImage
*ni
= GetPropImage(data
, data
->prop
);
289 set(obj
, MUIA_Frame
, MUIV_Frame_None
);
302 data
->img
= zune_imspec_setup((IPTR
)data
->spec
, muiRenderInfo(obj
));
303 // FIXME: quick hack to not draw the background for gradients. It should really be generalized
306 if (data
->img
->type
== IST_SCALED_GRADIENT
307 || data
->img
->type
== IST_TILED_GRADIENT
)
308 set(obj
, MUIA_FillArea
, FALSE
);
310 set(obj
, MUIA_FillArea
, TRUE
);
313 if ((data
->img
!= NULL
) && (data
->img
->type
== IST_BRUSH
))
315 set(obj
, MUIA_Frame
, MUIV_Frame_None
);
321 /**************************************************************************
323 **************************************************************************/
324 IPTR
Image__MUIM_Cleanup(struct IClass
*cl
, Object
*obj
, struct MUIP_Cleanup
*msg
)
326 struct MUI_ImageData
*data
= INST_DATA(cl
, obj
);
330 zune_imspec_cleanup(data
->img
);
333 return DoSuperMethodA(cl
,obj
,(Msg
)msg
);
337 /**************************************************************************
339 **************************************************************************/
340 IPTR
Image__MUIM_AskMinMax(struct IClass
*cl
, Object
*obj
, struct MUIP_AskMinMax
*msg
)
342 struct MUI_ImageData
*data
= INST_DATA(cl
, obj
);
344 DoSuperMethodA(cl
, obj
, (Msg
)msg
);
347 if (data
->prop
!= NULL
)
349 struct NewImage
*ni
= GetPropImage(data
, data
->prop
);
352 msg
->MinMaxInfo
->MinWidth
= ni
->w
>> 2;
353 msg
->MinMaxInfo
->MaxWidth
= ni
->w
>> 2;
354 msg
->MinMaxInfo
->DefWidth
= ni
->w
>> 2;
356 msg
->MinMaxInfo
->MinHeight
= ni
->h
;
357 msg
->MinMaxInfo
->MaxHeight
= ni
->h
;
358 msg
->MinMaxInfo
->DefHeight
= ni
->h
;
359 data
->propimage
= ni
;
366 struct MUI_MinMax minmax
;
368 zune_imspec_askminmax(data
->img
, &minmax
);
370 if (data
->flags
& MIF_FREEHORIZ
)
372 msg
->MinMaxInfo
->MinWidth
+= minmax
.MinWidth
;
373 msg
->MinMaxInfo
->MaxWidth
+= minmax
.MaxWidth
;
374 msg
->MinMaxInfo
->DefWidth
+= minmax
.DefWidth
;
378 msg
->MinMaxInfo
->MinWidth
+= minmax
.DefWidth
;
379 msg
->MinMaxInfo
->MaxWidth
+= minmax
.DefWidth
;
380 msg
->MinMaxInfo
->DefWidth
+= minmax
.DefWidth
;
383 if (data
->flags
& MIF_FONTMATCHWIDTH
)
385 msg
->MinMaxInfo
->DefWidth
*= _font(obj
)->tf_XSize
/ 8;
389 if (data
->flags
& MIF_FREEVERT
)
391 msg
->MinMaxInfo
->MinHeight
+= minmax
.MinHeight
;
392 msg
->MinMaxInfo
->MaxHeight
+= minmax
.MaxHeight
;
393 msg
->MinMaxInfo
->DefHeight
+= minmax
.DefHeight
;
397 msg
->MinMaxInfo
->MinHeight
+= minmax
.DefHeight
;
398 msg
->MinMaxInfo
->MaxHeight
+= minmax
.DefHeight
;
399 msg
->MinMaxInfo
->DefHeight
+= minmax
.DefHeight
;
402 if (data
->flags
& MIF_FONTMATCHHEIGHT
)
404 msg
->MinMaxInfo
->DefHeight
*= _font(obj
)->tf_YSize
/ 8;
407 else if (data
->old_image
)
409 msg
->MinMaxInfo
->MinWidth
+= data
->old_image
->Width
;
410 msg
->MinMaxInfo
->DefWidth
= msg
->MinMaxInfo
->MinWidth
;
411 msg
->MinMaxInfo
->MaxWidth
= msg
->MinMaxInfo
->MinWidth
;
413 msg
->MinMaxInfo
->MinHeight
+= data
->old_image
->Height
;
414 msg
->MinMaxInfo
->DefHeight
= msg
->MinMaxInfo
->MinHeight
;
415 msg
->MinMaxInfo
->MaxHeight
= msg
->MinMaxInfo
->MinHeight
;
417 else /* no imagespec specified */
419 /* D(bug("*** Image_AskMinMax : no img, no old_img\n")); */
420 /* msg->MinMaxInfo->MinWidth += 8; */
421 /* msg->MinMaxInfo->DefWidth = msg->MinMaxInfo->MinWidth; */
422 /* msg->MinMaxInfo->MaxWidth = msg->MinMaxInfo->MinWidth; */
424 /* msg->MinMaxInfo->MinHeight += 8; */
425 /* msg->MinMaxInfo->DefHeight = msg->MinMaxInfo->MinHeight; */
426 /* msg->MinMaxInfo->MaxHeight = msg->MinMaxInfo->MinHeight; */
431 /**************************************************************************
433 **************************************************************************/
434 IPTR
Image__MUIM_Show(struct IClass
*cl
, Object
*obj
, struct MUIP_Show
*msg
)
436 struct MUI_ImageData
*data
= INST_DATA(cl
, obj
);
438 DoSuperMethodA(cl
,obj
,(Msg
)msg
);
440 zune_imspec_show(data
->img
, obj
);
444 /**************************************************************************
446 **************************************************************************/
447 IPTR
Image__MUIM_Hide(struct IClass
*cl
, Object
*obj
,struct MUIP_Hide
*msg
)
449 struct MUI_ImageData
*data
= INST_DATA(cl
, obj
);
452 zune_imspec_hide(data
->img
);
453 return DoSuperMethodA(cl
,obj
,(Msg
)msg
);
456 /**************************************************************************
458 **************************************************************************/
460 void DrawAlphaStateImageToRP(struct RastPort
*rp
, struct NewImage
*ni
, ULONG state
, UWORD xp
, UWORD yp
) {
462 /* Function: draw an Image to a specific RastPort using AlphaValues
463 * Input: RastPortd rp:
464 * RastPort to draw to
468 * location where to draw the Image
469 * Bugs: Not known, throught the lack of AlphaHandling in cgfx/p96 there
470 * must all be done by hand so it's recommended to use this for small Images.
471 * NOTES: a temporary Buffer must be allocated to store the Background
482 depth
= (ULONG
) GetBitMapAttr(rp
->BitMap
, BMA_DEPTH
);
484 d
= (UBYTE
*) ni
->data
;
493 case IDS_INACTIVENORMAL
:
500 WritePixelArrayAlpha(d
, 0 , 0, ix
*4, rp
, xp
, yp
, ix
>> 2, iy
, 0xffffffff);
502 else if (ni
->bitmap
!= NULL
)
506 BltMaskBitMapRastPort(ni
->bitmap
, 0, 0, rp
, xp
, yp
, ix
>> 2, iy
, 0xe0, (PLANEPTR
) ni
->mask
);
508 else BltBitMapRastPort(ni
->bitmap
, 0, 0, rp
, xp
, yp
, ix
>> 2, iy
, 0xc0);
514 IPTR
Image__MUIM_Draw(struct IClass
*cl
, Object
*obj
,struct MUIP_Draw
*msg
)
516 struct MUI_ImageData
*data
= INST_DATA(cl
, obj
);
518 D(bug("Image_Draw(%p): msg=0x%08lx state=%ld sss=%ld\n",
519 obj
, ((struct MUIP_Draw
*)msg
)->flags
, data
->state
,
520 !!(_flags(obj
) & MADF_SHOWSELSTATE
)));
522 if (data
->propimage
== NULL
)
524 DoSuperMethodA(cl
,obj
,(Msg
)msg
);
526 if (!(msg
->flags
& (MADF_DRAWOBJECT
|MADF_DRAWUPDATE
)))
533 //get(obj, MUIA_Parent, &p);
534 //if (p) DoMethod(p, MUIM_DrawParentBackground, _left(obj), _top(obj), _width(obj), _height(obj), _left(obj), _top(obj), 0);
536 DoMethod(obj
, MUIM_DrawParentBackground
, _left(obj
), _top(obj
), _width(obj
), _height(obj
), _left(obj
), _top(obj
), 0);
538 DrawAlphaStateImageToRP(_rp(obj
), data
->propimage
, data
->state
, _left(obj
), _top(obj
));
542 zune_imspec_draw(data
->img
, muiRenderInfo(obj
),
543 _mleft(obj
),_mtop(obj
),_mwidth(obj
),_mheight(obj
),
546 else if (data
->old_image
)
548 DrawImage(_rp(obj
), data
->old_image
, _mleft(obj
),_mtop(obj
));
554 BOOPSI_DISPATCHER(IPTR
, Image_Dispatcher
, cl
, obj
, msg
)
556 switch (msg
->MethodID
)
558 case OM_NEW
: return Image__OM_NEW(cl
, obj
, (struct opSet
*)msg
);
559 case OM_DISPOSE
: return Image__OM_DISPOSE(cl
, obj
, msg
);
560 case OM_SET
: return Image__OM_SET(cl
, obj
, (APTR
)msg
);
561 case OM_GET
: return Image__OM_GET(cl
, obj
, (APTR
)msg
);
562 case MUIM_AskMinMax
: return Image__MUIM_AskMinMax(cl
,obj
,(APTR
)msg
);
563 case MUIM_Setup
: return Image__MUIM_Setup(cl
,obj
,(APTR
)msg
);
564 case MUIM_Cleanup
: return Image__MUIM_Cleanup(cl
,obj
,(APTR
)msg
);
565 case MUIM_Show
: return Image__MUIM_Show(cl
,obj
,(APTR
)msg
);
566 case MUIM_Hide
: return Image__MUIM_Hide(cl
,obj
,(APTR
)msg
);
567 case MUIM_Draw
: return Image__MUIM_Draw(cl
,obj
,(APTR
)msg
);
570 return DoSuperMethodA(cl
, obj
, msg
);
572 BOOPSI_DISPATCHER_END
577 const struct __MUIBuiltinClass _MUI_Image_desc
= {
580 sizeof(struct MUI_ImageData
),
581 (void*)Image_Dispatcher