2 Copyright 2002-2003, The AROS Development Team. All rights reserved.
6 #include <exec/memory.h>
7 #include <intuition/icclass.h>
8 #include <intuition/gadgetclass.h>
9 #include <clib/alib_protos.h>
10 #include <proto/exec.h>
11 #include <proto/graphics.h>
12 #include <proto/intuition.h>
13 #include <proto/utility.h>
14 #include <proto/muimaster.h>
15 #include <proto/cybergraphics.h>
18 #include <intuition/windecorclass.h>
20 #include <cybergraphx/cybergraphics.h>
21 #include <graphics/rpattr.h>
23 #include "../datatypescache.h"
24 #include "../imspec_intern.h"
27 #include "muimaster_intern.h"
31 /* #define MYDEBUG 1 */
34 extern struct Library
*MUIMasterBase
;
36 #define SCALE16_METHOD 2 /* 1 or 2 */
38 #if SCALE16_METHOD != 1
39 #define calcscale16(x)
48 #if SCALE16_METHOD == 1
56 UWORD minwidth
, minheight
;
57 UWORD maxwidth
, maxheight
;
58 UWORD defwidth
, defheight
;
59 UWORD propwidth
, propheight
;
62 struct MUI_EventHandlerNode ehn
;
66 struct NewImage
*buffer
;
67 struct NewImage
*temp
;
68 struct BitMap
*mapbuffer
;
69 struct BitMap
*maptemp
;
70 struct RastPort
*tmprp
;
73 #if SCALE16_METHOD == 1
74 static void calcscale16(struct Prop_DATA
*data
)
76 if (data
->entries
< 65535)
78 data
->scale16
= 0x10000;
82 unsigned long long v
= ((unsigned long long)data
->entries
) * 0x10000 / 65535;
84 data
->scale16
= (ULONG
)v
;
89 static ULONG
downscale(struct Prop_DATA
*data
, ULONG val
)
91 #if SCALE16_METHOD == 1
92 if (data
->scale16
!= 0x10000)
94 unsigned long long v
= ((unsigned long long)val
) * 0x10000 / data
->scale16
;
98 if (data
->entries
>= 0x10000)
100 unsigned long long v
= ((unsigned long long)val
) * 65535 / data
->entries
;
108 static ULONG
upscale(struct Prop_DATA
*data
, ULONG val
)
110 #if SCALE16_METHOD == 1
111 if (data
->scale16
!= 0x10000)
113 unsigned long long v
= ((unsigned long long)val
) * data
->scale16
/ 0x10000;
117 if (data
->entries
>= 0x10000)
119 unsigned long long v
= ((unsigned long long)val
) * data
->entries
/ 65535;
126 IPTR
Prop__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
128 struct Prop_DATA
*data
;
129 struct TagItem
*tags
,*tag
;
131 obj
= (Object
*)DoSuperNewTags(cl
, obj
, NULL
,
132 MUIA_Background
, MUII_PropBack
,
133 TAG_MORE
, (IPTR
) msg
->ops_AttrList
);
138 data
= INST_DATA(cl
, obj
);
139 data
->deltafactor
= 1;
141 /* parse initial taglist */
142 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem((const struct TagItem
**)&tags
)); )
146 case MUIA_Prop_Entries
:
147 data
->entries
= tag
->ti_Data
;
149 case MUIA_Prop_First
:
150 data
->first
= tag
->ti_Data
;
152 case MUIA_Prop_Horiz
:
153 data
->horiz
= tag
->ti_Data
;
155 case MUIA_Prop_Slider
:
157 case MUIA_Prop_UseWinBorder
:
158 data
->usewinborder
= tag
->ti_Data
;
160 case MUIA_Prop_Visible
:
161 data
->visible
= tag
->ti_Data
;
164 case MUIA_Prop_DeltaFactor
:
165 data
->deltafactor
= tag
->ti_Data
;
170 if (data
->horiz
== TRUE
)
174 data
->maxwidth
= MUI_MAXMAX
;
175 data
->maxheight
= MUI_MAXMAX
;
183 data
->maxwidth
= MUI_MAXMAX
;
184 data
->maxheight
= MUI_MAXMAX
;
186 data
->defheight
= 50;
192 data
->ehn
.ehn_Events
= IDCMP_IDCMPUPDATE
;
193 data
->ehn
.ehn_Priority
= 0;
194 data
->ehn
.ehn_Flags
= 0;
195 data
->ehn
.ehn_Object
= obj
;
196 data
->ehn
.ehn_Class
= cl
;
198 if (data
->usewinborder
)
199 _flags(obj
) |= MADF_BORDERGADGET
;
206 IPTR
Prop__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
208 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
210 if (data
->prop_object
&& !data
->usewinborder
) {
211 RemoveGadget(_window(obj
), (struct Gadget
*) data
->prop_object
);
212 DisposeObject(data
->prop_object
);
215 DisposeImageContainer(data
->buffer
);
216 DisposeImageContainer(data
->temp
);
217 if (data
->mapbuffer
!= NULL
) FreeBitMap(data
->mapbuffer
);
218 if (data
->maptemp
!= NULL
) FreeBitMap(data
->maptemp
);
219 if (data
->tmprp
!= NULL
) FreeRastPort(data
->tmprp
);
223 data
->mapbuffer
= NULL
;
224 data
->maptemp
= NULL
;
227 return DoSuperMethodA(cl
, obj
, msg
);
230 IPTR
Prop__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
232 struct TagItem
*tags
,*tag
;
233 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
235 int only_trigger
= 0;
237 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem((const struct TagItem
**)&tags
)); )
241 case MUIA_Prop_Entries
:
242 data
->entries
= tag
->ti_Data
;
246 case MUIA_Prop_First
:
247 data
->first
= tag
->ti_Data
;
251 case MUIA_Prop_Slider
:
254 case MUIA_Prop_Visible
:
255 data
->visible
= tag
->ti_Data
;
259 case MUIA_Prop_OnlyTrigger
:
260 only_trigger
= tag
->ti_Data
;
263 case MUIA_Prop_DeltaFactor
:
264 data
->deltafactor
= tag
->ti_Data
;
272 if (data
->prop_object
&& refresh
&& !only_trigger
)
276 /* Rendering will happen here!! This could make problems with virtual groups, forward this to MUIM_Draw??? */
277 SetAttrs(data
->prop_object
, ICA_TARGET
, NULL
, TAG_DONE
);
278 if (SetGadgetAttrs((struct Gadget
*)data
->prop_object
,_window(obj
),NULL
,
279 PGA_Top
,downscale(data
, data
->first
),
280 PGA_Visible
,downscale(data
, data
->visible
),
281 PGA_Total
,downscale(data
, data
->entries
),
283 RefreshGList((struct Gadget
*)data
->prop_object
, _window(obj
), NULL
, 1);
284 SetAttrs(data
->prop_object
, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
287 return DoSuperMethodA(cl
,obj
,(Msg
)msg
);
290 #define STORE *(msg->opg_Storage)
291 IPTR
Prop__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
293 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
294 switch (msg
->opg_AttrID
)
296 case MUIA_Prop_First
:
298 if (data
->prop_object
)
301 /* So we can get a more current value */
302 GetAttr(PGA_Top
,data
->prop_object
,&v
);
303 data
->first
= upscale(data
, v
);
308 case MUIA_Prop_Entries
: STORE
= data
->entries
; return 1;
309 case MUIA_Prop_Visible
: STORE
= data
->visible
; return 1;
312 return DoSuperMethodA(cl
,obj
,(Msg
)msg
);
319 IPTR
Prop__MUIM_AskMinMax(struct IClass
*cl
, Object
*obj
, struct MUIP_AskMinMax
*msg
)
321 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
324 ** let our superclass first fill in what it thinks about sizes.
325 ** this will e.g. add the size of frame and inner spacing.
327 DoSuperMethodA(cl
, obj
, (Msg
)msg
);
329 msg
->MinMaxInfo
->MinWidth
+= data
->minwidth
;
330 msg
->MinMaxInfo
->DefWidth
+= data
->defwidth
;
331 msg
->MinMaxInfo
->MaxWidth
= data
->maxwidth
;
333 msg
->MinMaxInfo
->MinHeight
+= data
->minheight
;
334 msg
->MinMaxInfo
->DefHeight
+= data
->defheight
;
335 msg
->MinMaxInfo
->MaxHeight
= data
->maxheight
;
337 D(bug("Prop %p minheigh=%d\n",
338 obj
, msg
->MinMaxInfo
->MinHeight
));
343 IPTR
Prop__MUIM_Setup(struct IClass
*cl
, Object
*obj
, struct MUIP_Setup
*msg
)
345 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
346 ULONG rc
= DoSuperMethodA(cl
, obj
, (Msg
)msg
);
349 DoMethod(_win(obj
),MUIM_Window_AddEventHandler
,(IPTR
)&data
->ehn
);
353 data
->mapbuffer
= NULL
;
354 data
->maptemp
= NULL
;
357 if (!data
->usewinborder
)
359 data
->gadgetid
= DoMethod(_win(obj
),MUIM_Window_AllocGadgetID
);
360 if (data
->horiz
== TRUE
)
364 data
->maxwidth
= MUI_MAXMAX
;
365 data
->maxheight
= MUI_MAXMAX
;
373 data
->maxwidth
= MUI_MAXMAX
;
374 data
->maxheight
= MUI_MAXMAX
;
376 data
->defheight
= 50;
379 struct MUI_AreaData
*adata
= muiAreaData(obj
);
380 struct MUI_ImageSpec_intern
*spec
= adata
->mad_Background
;
384 if (spec
->type
== IST_BITMAP
)
386 struct dt_node
*node
= spec
->u
.bitmap
.dt
;
389 if (node
->mode
== MODE_PROP
)
391 set(obj
, MUIA_Frame
, MUIV_Frame_None
);
393 if (data
->horiz
== TRUE
)
395 data
->minheight
= node
->img_horizontalcontainer
->h
>> 1;
396 data
->defheight
= data
->minheight
;
397 data
->maxheight
= data
->minheight
;
401 data
->minwidth
= node
->img_verticalcontainer
->w
>> 1;
402 data
->defwidth
= data
->minwidth
;
403 data
->maxwidth
= data
->minwidth
;
414 IPTR
Prop__MUIM_Cleanup(struct IClass
*cl
, Object
*obj
, struct MUIP_Cleanup
*msg
)
416 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
417 if (!data
->usewinborder
)
419 DoMethod(_win(obj
),MUIM_Window_FreeGadgetID
,data
->gadgetid
);
421 DoMethod(_win(obj
),MUIM_Window_RemEventHandler
,(IPTR
)&data
->ehn
);
422 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
425 void WritePixelArrayAlphaToImage(struct NewImage
*in
, UWORD sx
, UWORD sy
, struct NewImage
*out
, UWORD xp
, UWORD yp
, UWORD w
, UWORD h
)
428 UBYTE rs
, gs
, bs
, as
, rd
, gd
, bd
;
431 for (y
= 0; y
< h
; y
++)
433 for (x
= 0; x
< w
; x
++)
435 argb
= in
->data
[x
+ sx
+ (y
+ sy
) * in
->w
];
442 rgb
= out
->data
[x
+xp
+(y
+yp
)*out
->w
];
449 r
= ((rs
* as
) >> 8) + ((rd
* (255 - as
)) >> 8);
450 g
= ((gs
* as
) >> 8) + ((gd
* (255 - as
)) >> 8);
451 b
= ((bs
* as
) >> 8) + ((bd
* (255 - as
)) >> 8);
453 out
->data
[x
+xp
+(y
+yp
)*out
->w
] = SET_ARGB(255, r
, g
, b
);
459 int WriteTiledImageHorizontal(struct NewImage
*dst
, struct RastPort
*maprp
, struct NewImage
*ni
, int sx
, int sy
, int sw
, int sh
, int xp
, int yp
, int dw
, int dh
) {
463 if ((sw
== 0) || (dw
== 0)) return xp
;
467 if (w
< ddw
) ddw
= w
;
469 if (dst
!= NULL
) WritePixelArrayAlphaToImage(ni
, sx
, sy
, dst
, x
, yp
, ddw
, dh
);
470 if ((maprp
!= NULL
) && (ni
->bitmap
!= NULL
))
474 BltMaskBitMapRastPort(ni
->bitmap
, sx
, sy
, maprp
, x
, yp
, ddw
, dh
, 0xe0, (PLANEPTR
) ni
->mask
);
476 else BltBitMapRastPort(ni
->bitmap
, sx
, sy
, maprp
, x
, yp
, ddw
, dh
, 0xc0);
484 int WriteTiledImageVertical(struct NewImage
*dst
, struct RastPort
*maprp
, struct NewImage
*ni
, int sx
, int sy
, int sw
, int sh
, int xp
, int yp
, int dw
, int dh
) {
488 if ((sh
== 0) || (dh
== 0)) return yp
;
491 if (h
< ddh
) ddh
= h
;
493 if (dst
!= NULL
) WritePixelArrayAlphaToImage(ni
, sx
, sy
, dst
, xp
, y
, dw
, ddh
);
494 if ((maprp
!= NULL
) && (ni
->bitmap
!= NULL
))
498 BltMaskBitMapRastPort(ni
->bitmap
, sx
, sy
, maprp
, xp
, y
, dw
, ddh
, 0xe0, (PLANEPTR
) ni
->mask
);
500 else BltBitMapRastPort(ni
->bitmap
, sx
, sy
, maprp
, xp
, y
, dw
, ddh
, 0xc0);
511 void, CustomPropRenderFunc
,
512 AROS_UFHA(struct Hook
*, h
, A0
),
513 AROS_UFHA(Object
*, obj
, A2
),
514 AROS_UFHA(struct wdpDrawBorderPropKnob
*, msg
, A1
)
519 struct Prop_DATA
*node
= h
->h_Data
;
521 struct dt_node
*data
= node
->node
;
524 if (msg
->MethodID
== WDM_DRAW_BORDERPROPKNOB
)
526 struct Window
*window
= msg
->wdp_Window
;
527 struct NewImage
*temp
;
528 struct BitMap
*maptemp
;
529 struct RastPort
*winrp
= msg
->wdp_RPort
;
530 struct RastPort
*maprp
;
531 struct Gadget
*gadget
= msg
->wdp_Gadget
;
532 struct Rectangle
*r
= msg
->wdp_RenderRect
;
533 struct PropInfo
*pi
= ((struct PropInfo
*)gadget
->SpecialInfo
);
534 BOOL hit
= (msg
->wdp_Flags
& WDF_DBPK_HIT
) ? TRUE
: FALSE
;
537 UWORD MinX
, MinY
, MaxX
, MaxY
, StartX
, StartY
;
543 maptemp
= node
->maptemp
;
546 depth
= (ULONG
) GetBitMapAttr(winrp
->BitMap
, BMA_DEPTH
);
548 if (node
->buffer
) for (i
= 0; i
< (node
->buffer
->w
* node
->buffer
->h
); i
++) node
->temp
->data
[i
] = node
->buffer
->data
[i
];
549 if (node
->mapbuffer
) BltBitMap(node
->mapbuffer
, 0, 0, node
->maptemp
, 0, 0, node
->propwidth
, node
->propheight
, 0xc0, 0xff, NULL
);
552 r
= msg
->wdp_PropRect
;
557 MaxX
= r
->MaxX
- r
->MinX
;
558 MaxY
= r
->MaxY
- r
->MinY
;
560 if ((pi
->Flags
& FREEVERT
) != 0)
562 is
= data
->img_verticalcontainer
->w
>> 1;
563 if (window
->Flags
& WFLG_WINDOWACTIVE
) pos
= 0; else pos
= is
;
565 size
= MaxY
- MinY
- data
->ContainerTop_s
- data
->ContainerBottom_s
+ 1;
566 y
= WriteTiledImageVertical(temp
, maprp
, data
->img_verticalcontainer
, pos
, data
->ContainerTop_o
, is
, data
->ContainerTop_s
, MinX
, y
, is
, data
->ContainerTop_s
);
567 if (size
> 0) y
= WriteTiledImageVertical(temp
, maprp
, data
->img_verticalcontainer
, pos
, data
->ContainerVertTile_o
, is
, data
->ContainerVertTile_s
, MinX
, y
, is
, size
);
568 y
= WriteTiledImageVertical(temp
, maprp
, data
->img_verticalcontainer
, pos
, data
->ContainerBottom_o
, is
, data
->ContainerBottom_s
, MinX
, y
, is
, data
->ContainerBottom_s
);
570 else if ((pi
->Flags
& FREEHORIZ
) != 0)
572 is
= data
->img_horizontalcontainer
->h
>> 1;
573 if (window
->Flags
& WFLG_WINDOWACTIVE
) pos
= 0; else pos
= is
;
575 size
= MaxX
- MinX
- data
->ContainerLeft_s
- data
->ContainerRight_s
+ 1;
576 x
= WriteTiledImageHorizontal(temp
, maprp
, data
->img_horizontalcontainer
, data
->ContainerLeft_o
, pos
, data
->ContainerLeft_s
, is
, x
, MinY
, data
->ContainerLeft_s
, is
);
577 if (size
> 0) x
= WriteTiledImageHorizontal(temp
, maprp
, data
->img_horizontalcontainer
, data
->ContainerHorTile_o
, pos
, data
->ContainerHorTile_s
, is
, x
, MinY
, size
, is
);
578 x
= WriteTiledImageHorizontal(temp
, maprp
, data
->img_horizontalcontainer
, data
->ContainerRight_o
, pos
, data
->ContainerRight_s
, is
, x
, MinY
, data
->ContainerRight_s
, is
);
581 r
= msg
->wdp_RenderRect
;
582 MinX
= r
->MinX
- StartX
;
583 MinY
= r
->MinY
- StartY
;
584 MaxX
= r
->MaxX
- StartX
;
585 MaxY
= r
->MaxY
- StartY
;
587 if ((pi
->Flags
& FREEVERT
) != 0)
589 is
= data
->img_verticalknob
->w
/ 3;
590 if (hit
) pos
= is
; else if (window
->Flags
& WFLG_WINDOWACTIVE
) pos
= 0; else pos
= is
* 2;
592 size
= MaxY
- MinY
- data
->KnobTop_s
- data
->KnobBottom_s
+ 1;
593 y
= WriteTiledImageVertical(temp
, maprp
, data
->img_verticalknob
, pos
, data
->KnobTop_o
, is
, data
->KnobTop_s
, MinX
, y
, is
, data
->KnobTop_s
);
595 if (size
> data
->KnobVertGripper_s
) {
596 size
= size
- data
->KnobVertGripper_s
;
599 if (size
> 0) y
= WriteTiledImageVertical(temp
, maprp
, data
->img_verticalknob
, pos
, data
->KnobTileTop_o
, is
, data
->KnobTileTop_s
, MinX
, y
, is
, size
);
600 y
= WriteTiledImageVertical(temp
, maprp
, data
->img_verticalknob
, pos
, data
->KnobVertGripper_o
, is
, data
->KnobVertGripper_s
, MinX
, y
, is
, data
->KnobVertGripper_s
);
601 size
= size_bak
- size
;
602 if (size
> 0) y
= WriteTiledImageVertical(temp
, maprp
, data
->img_verticalknob
, pos
, data
->KnobTileBottom_o
, is
, data
->KnobTileBottom_s
, MinX
, y
, is
, size
);
604 y
= WriteTiledImageVertical(temp
, maprp
, data
->img_verticalknob
, pos
, data
->KnobTileTop_o
, is
, data
->KnobTileTop_s
, MinX
, y
, is
, size
);
607 y
= WriteTiledImageVertical(temp
, maprp
, data
->img_verticalknob
, pos
, data
->KnobBottom_o
, is
, data
->KnobBottom_s
, MinX
, y
, is
, data
->KnobBottom_s
);
609 else if ((pi
->Flags
& FREEHORIZ
) != 0)
611 is
= data
->img_horizontalknob
->h
/ 3;
612 if (hit
) pos
= is
; else if (window
->Flags
& WFLG_WINDOWACTIVE
) pos
= 0; else pos
= is
* 2;
614 size
= MaxX
- MinX
- data
->KnobLeft_s
- data
->KnobRight_s
+ 1;
615 x
= WriteTiledImageHorizontal(temp
, maprp
, data
->img_horizontalknob
, data
->KnobLeft_o
, pos
, data
->KnobLeft_s
, is
, x
, MinY
, data
->KnobLeft_s
, is
);
617 if (size
> data
->KnobHorGripper_s
) {
618 size
= size
- data
->KnobHorGripper_s
;
621 if (size
> 0) x
= WriteTiledImageHorizontal(temp
, maprp
, data
->img_horizontalknob
, data
->KnobTileLeft_o
, pos
, data
->KnobTileLeft_s
, is
, x
, MinY
, size
, is
);
622 x
= WriteTiledImageHorizontal(temp
, maprp
, data
->img_horizontalknob
, data
->KnobHorGripper_o
, pos
, data
->KnobHorGripper_s
, is
, x
, MinY
, data
->KnobHorGripper_s
, is
);
623 size
= size_bak
- size
;
624 if (size
> 0) x
= WriteTiledImageHorizontal(temp
, maprp
, data
->img_horizontalknob
, data
->KnobTileRight_o
, pos
, data
->KnobTileRight_s
, is
, x
, MinY
, size
, is
);
626 x
= WriteTiledImageHorizontal(temp
, maprp
, data
->img_horizontalknob
, data
->KnobTileRight_o
, pos
, data
->KnobTileRight_s
, is
, x
, MinY
, size
, is
);
629 x
= WriteTiledImageHorizontal(temp
, maprp
, data
->img_horizontalknob
, data
->KnobRight_o
, pos
, data
->KnobRight_s
, is
, x
, MinY
, data
->KnobRight_s
, is
);
632 if (node
->temp
) WritePixelArray(node
->temp
->data
, 0, 0, node
->temp
->w
*4, winrp
, _left(node
->obj
), _top(node
->obj
), node
->temp
->w
, node
->temp
->h
, RECTFMT_ARGB
);
633 if (node
->maptemp
) BltBitMapRastPort(node
->maptemp
, 0, 0, winrp
, _left(node
->obj
), _top(node
->obj
), node
->propwidth
, node
->propheight
, 0xc0);
641 IPTR
Prop__MUIM_Show(struct IClass
*cl
, Object
*obj
, struct MUIP_Show
*msg
)
643 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
644 struct MUI_AreaData
*adata
= muiAreaData(obj
);
645 struct MUI_ImageSpec_intern
*spec
= adata
->mad_Background
;
647 ULONG rc
= DoSuperMethodA(cl
, obj
, (Msg
)msg
);
649 data
->dhook
.h_Entry
= (HOOKFUNC
) CustomPropRenderFunc
;
651 if (!data
->usewinborder
)
653 BOOL isnewlook
, completely_visible
= TRUE
;;
655 if (_flags(obj
) & MADF_INVIRTUALGROUP
)
657 Object
*wnd
, *parent
;
659 get(obj
, MUIA_WindowObject
,&wnd
);
661 while (get(parent
,MUIA_Parent
,&parent
))
664 if (parent
== wnd
) break;
666 if (_flags(parent
) & MADF_ISVIRTUALGROUP
)
668 if ((_mleft(obj
) < _mleft(parent
)) ||
669 (_mright(obj
) > _mright(parent
)) ||
670 (_mtop(obj
) < _mtop(parent
)) ||
671 (_mbottom(obj
) > _mbottom(parent
)))
673 completely_visible
= FALSE
;
674 D(bug("=== prop object: completely visible FALSE for obj %x at %d,%d - %d,%d\n",
675 obj
, _mleft(obj
), _mtop(obj
), _mright(obj
), _mbottom(obj
)));
682 if (completely_visible
)
684 if (muiGlobalInfo(obj
)->mgi_Prefs
->scrollbar_type
== SCROLLBAR_TYPE_NEWLOOK
)
689 ULONG width
= _mwidth(obj
);
690 ULONG height
= _mheight(obj
);
692 struct Hook
*dhook
= NULL
;
694 ULONG depth
= (ULONG
) GetBitMapAttr(_window(obj
)->RPort
->BitMap
, BMA_DEPTH
);
695 if (muiGlobalInfo(obj
)->mgi_Prefs
->scrollbar_type
== SCROLLBAR_TYPE_CUSTOM
)
699 if (spec
->type
== IST_BITMAP
)
701 struct dt_node
*node
= spec
->u
.bitmap
.dt
;
704 if (node
->mode
== MODE_PROP
)
706 data
->dhook
.h_Entry
= (HOOKFUNC
) CustomPropRenderFunc
;
708 data
->dhook
.h_Data
= data
;
710 dhook
= &data
->dhook
;
712 if (data
->horiz
== TRUE
) height
= node
->img_horizontalcontainer
->h
>> 1; else width
= node
->img_verticalcontainer
->w
>> 1;
713 DisposeImageContainer(data
->buffer
);
714 DisposeImageContainer(data
->temp
);
715 data
->propwidth
= width
;
716 data
->propheight
= height
;
717 if (data
->mapbuffer
) FreeBitMap(data
->mapbuffer
);
718 if (data
->maptemp
) FreeBitMap(data
->maptemp
);
721 data
->buffer
= NewImageContainer(width
, height
);
722 data
->temp
= NewImageContainer(width
, height
);
723 data
->mapbuffer
= NULL
;
724 data
->maptemp
= NULL
;
725 if ((data
->buffer
== NULL
) || (data
->temp
== NULL
))
728 DisposeImageContainer(data
->buffer
);
729 DisposeImageContainer(data
->temp
);
739 data
->mapbuffer
= AllocBitMap(width
, height
, 1, BMF_MINPLANES
, _window(obj
)->RPort
->BitMap
);
740 data
->maptemp
= AllocBitMap(width
, height
, 1, BMF_MINPLANES
, _window(obj
)->RPort
->BitMap
);
741 data
->tmprp
= CreateRastPort();
742 if ((data
->mapbuffer
== NULL
) || (data
->maptemp
== NULL
) || (data
->tmprp
== NULL
))
745 if (data
->mapbuffer
) FreeBitMap(data
->mapbuffer
);
746 if (data
->maptemp
) FreeBitMap(data
->maptemp
);
747 if (data
->tmprp
) FreeRastPort(data
->tmprp
);
748 data
->mapbuffer
= NULL
;
749 data
->maptemp
= NULL
;
751 } else data
->tmprp
->BitMap
= data
->maptemp
;
760 if (data
->prop_object
) {
761 RemoveGadget(_window(obj
), (struct Gadget
*) data
->prop_object
);
762 DisposeObject(data
->prop_object
);
765 if ((data
->prop_object
= NewObject(NULL
, "propgclass",
766 GA_Left
, _mleft(obj
),
770 GA_ID
, data
->gadgetid
,
772 PGA_DisplayHook
, dhook
, /* custom prop gadget impementation (not yet finished) */
774 PGA_Freedom
, data
->horiz
?FREEHORIZ
:FREEVERT
,
775 PGA_Total
, downscale(data
, data
->entries
),
776 PGA_Visible
, downscale(data
, data
->visible
),
777 PGA_Top
, downscale(data
, data
->first
),
778 PGA_NewLook
, isnewlook
,
779 PGA_Borderless
, TRUE
,
780 ICA_TARGET
, ICTARGET_IDCMP
, /* needed for notification */
783 AddGadget(_window(obj
),(struct Gadget
*)data
->prop_object
,~0);
788 switch (data
->usewinborder
)
790 case MUIV_Prop_UseWinBorder_Right
:
791 data
->prop_object
= muiRenderInfo(obj
)->mri_VertProp
;
792 if (data
->prop_object
)
794 /* Store pointer to this propclass object in propgadget->UserData,
795 so that window class when receiving IDCMP_IDCMUPDATE from
796 arrow gadgets can notify propclass object */
798 ((struct Gadget
*)data
->prop_object
)->UserData
= obj
;
802 case MUIV_Prop_UseWinBorder_Bottom
:
803 data
->prop_object
= muiRenderInfo(obj
)->mri_HorizProp
;
804 if (data
->prop_object
)
806 /* Store pointer to this propclass object in propgadget->UserData,
807 so that window class when receiving IDCMP_IDCMUPDATE from
808 arrow gadgets can notify propclass object */
810 ((struct Gadget
*)data
->prop_object
)->UserData
= obj
;
814 if (data
->prop_object
)
816 data
->gadgetid
= ((struct Gadget
*)data
->prop_object
)->GadgetID
;
818 SetAttrs(data
->prop_object
, ICA_TARGET
, NULL
, TAG_DONE
);
819 if (SetGadgetAttrs((struct Gadget
*)data
->prop_object
,_window(obj
),NULL
,
820 PGA_Top
,downscale(data
, data
->first
),
821 PGA_Visible
,downscale(data
, data
->visible
),
822 PGA_Total
,downscale(data
, data
->entries
),
825 RefreshGList((struct Gadget
*)data
->prop_object
, _window(obj
), NULL
, 1);
827 SetAttrs(data
->prop_object
, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
834 IPTR
Prop__MUIM_Draw(struct IClass
*cl
, Object
*obj
, struct MUIP_Draw
*msg
)
836 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
838 /* No drawings if own border */
839 if (data
->usewinborder
) return 0;
841 DoSuperMethodA(cl
, obj
, (Msg
)msg
);
843 if (!(msg
->flags
& MADF_DRAWOBJECT
)) return 1;
845 if (data
->buffer
|| data
->mapbuffer
)
848 // get(obj, MUIA_Parent, &p);
849 //if (p) DoMethod(p, MUIM_DrawParentBackground, _left(obj), _top(obj), _width(obj), _height(obj), _left(obj), _top(obj), 0);
851 DoMethod(obj
, MUIM_DrawParentBackground
, _left(obj
), _top(obj
), _width(obj
), _height(obj
), _left(obj
), _top(obj
), 0);
853 if (data
->buffer
) ReadPixelArray(data
->buffer
->data
, 0, 0, data
->buffer
->w
*4, _rp(data
->obj
), _mleft(data
->obj
), _mtop(data
->obj
), data
->buffer
->w
, data
->buffer
->h
, RECTFMT_ARGB
);
854 if (data
->mapbuffer
) BltBitMap(_window(data
->obj
)->RPort
->BitMap
, _window(data
->obj
)->LeftEdge
+ _mleft(data
->obj
), _window(data
->obj
)->TopEdge
+ _mtop(data
->obj
), data
->mapbuffer
, 0, 0, data
->propwidth
, data
->propheight
, 0xc0, 0xff, NULL
);
857 if (data
->prop_object
) RefreshGList((struct Gadget
*)data
->prop_object
, _window(obj
), NULL
, 1);
861 IPTR
Prop__MUIM_Hide(struct IClass
*cl
, Object
*obj
, struct MUIP_Hide
*msg
)
863 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
865 if (data
->prop_object
)
867 if (!data
->usewinborder
)
869 RemoveGadget(_window(obj
),(struct Gadget
*)data
->prop_object
);
870 DisposeObject(data
->prop_object
);
875 data
->prop_object
= NULL
;
878 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
881 IPTR
Prop__MUIM_HandleEvent(struct IClass
*cl
, Object
*obj
, struct MUIP_HandleEvent
*msg
)
883 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
886 if (msg
->imsg
->Class
== IDCMP_IDCMPUPDATE
)
891 /* Check if we are meant */
892 tag
= FindTagItem(GA_ID
,(struct TagItem
*)msg
->imsg
->IAddress
);
894 if (tag
->ti_Data
!= data
->gadgetid
) return 0;
896 /* Check if we PGA_Top has really changed */
897 tag
= FindTagItem(PGA_Top
,(struct TagItem
*)msg
->imsg
->IAddress
);
899 v
= upscale(data
, tag
->ti_Data
);
901 //kprintf("PROP_HandleEvent: PGA_Top %d upscaled %d entries %d\n", tag->ti_Data, v, data->entries);
903 if ((v
== data
->first
) && (msg
->imsg
->Qualifier
& IEQUALIFIER_REPEAT
)) return 0;
907 SetAttrs(obj
, MUIA_Prop_First
, data
->first
, MUIA_Prop_OnlyTrigger
, TRUE
,
908 MUIA_Prop_Release
, ((msg
->imsg
->Qualifier
& IEQUALIFIER_REPEAT
) ? FALSE
: TRUE
),
916 IPTR
Prop__MUIM_Prop_Increase(struct IClass
*cl
, Object
*obj
, struct MUIP_Prop_Increase
*msg
)
918 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
921 newfirst
= data
->first
+ msg
->amount
* data
->deltafactor
;
923 if (newfirst
+ data
->visible
> data
->entries
)
924 newfirst
= data
->entries
- data
->visible
;
925 if (newfirst
!= data
->first
)
926 set(obj
, MUIA_Prop_First
, newfirst
);
930 IPTR
Prop__MUIM_Prop_Decrease(struct IClass
*cl
, Object
*obj
, struct MUIP_Prop_Decrease
*msg
)
932 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
935 /* We cannot decrease if if are on the top */
936 if (data
->first
<= 0)
939 newfirst
= data
->first
- msg
->amount
* data
->deltafactor
;
942 set(obj
, MUIA_Prop_First
, 0);
943 else if (newfirst
!= data
->first
)
944 set(obj
, MUIA_Prop_First
, newfirst
);
949 BOOPSI_DISPATCHER(IPTR
, Prop_Dispatcher
, cl
, obj
, msg
)
951 switch (msg
->MethodID
)
953 case OM_NEW
: return Prop__OM_NEW(cl
, obj
, (struct opSet
*) msg
);
954 case OM_DISPOSE
: return Prop__OM_DISPOSE(cl
, obj
, msg
);
955 case OM_GET
: return Prop__OM_GET(cl
, obj
, (struct opGet
*)msg
);
956 case OM_SET
: return Prop__OM_SET(cl
, obj
, (struct opSet
*)msg
);
957 case MUIM_Setup
: return Prop__MUIM_Setup(cl
, obj
, (APTR
)msg
);
958 case MUIM_Cleanup
: return Prop__MUIM_Cleanup(cl
, obj
, (APTR
)msg
);
959 case MUIM_Show
: return Prop__MUIM_Show(cl
, obj
, (APTR
)msg
);
960 case MUIM_Hide
: return Prop__MUIM_Hide(cl
, obj
, (APTR
)msg
);
961 case MUIM_AskMinMax
: return Prop__MUIM_AskMinMax(cl
, obj
, (APTR
)msg
);
962 case MUIM_Draw
: return Prop__MUIM_Draw(cl
, obj
, (APTR
)msg
);
963 case MUIM_HandleEvent
: return Prop__MUIM_HandleEvent(cl
, obj
, (APTR
)msg
);
964 case MUIM_Prop_Decrease
: return Prop__MUIM_Prop_Decrease(cl
, obj
, (APTR
)msg
);
965 case MUIM_Prop_Increase
: return Prop__MUIM_Prop_Increase(cl
, obj
, (APTR
)msg
);
966 default: return DoSuperMethodA(cl
, obj
, msg
);
970 BOOPSI_DISPATCHER_END
972 const struct __MUIBuiltinClass _MUI_Prop_desc
=
976 sizeof(struct Prop_DATA
),
977 (void*)Prop_Dispatcher