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 if ((IPTR
)data
->entries
!= tag
->ti_Data
)
244 data
->entries
= tag
->ti_Data
;
249 tag
->ti_Tag
= TAG_IGNORE
;
253 case MUIA_Prop_First
:
254 if ((IPTR
)data
->first
!= tag
->ti_Data
)
256 data
->first
= tag
->ti_Data
;
261 tag
->ti_Tag
= TAG_IGNORE
;
265 case MUIA_Prop_Slider
:
268 case MUIA_Prop_Visible
:
269 if ((IPTR
)data
->visible
!= tag
->ti_Data
)
271 data
->visible
= tag
->ti_Data
;
276 tag
->ti_Tag
= TAG_IGNORE
;
280 case MUIA_Prop_OnlyTrigger
:
281 only_trigger
= tag
->ti_Data
;
284 case MUIA_Prop_DeltaFactor
:
285 data
->deltafactor
= tag
->ti_Data
;
293 if (data
->prop_object
&& refresh
&& !only_trigger
)
297 /* Rendering will happen here!! This could make problems with virtual groups, forward this to MUIM_Draw??? */
298 SetAttrs(data
->prop_object
, ICA_TARGET
, NULL
, TAG_DONE
);
299 if (SetGadgetAttrs((struct Gadget
*)data
->prop_object
,_window(obj
),NULL
,
300 PGA_Top
,downscale(data
, data
->first
),
301 PGA_Visible
,downscale(data
, data
->visible
),
302 PGA_Total
,downscale(data
, data
->entries
),
304 RefreshGList((struct Gadget
*)data
->prop_object
, _window(obj
), NULL
, 1);
305 SetAttrs(data
->prop_object
, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
308 return DoSuperMethodA(cl
,obj
,(Msg
)msg
);
311 #define STORE *(msg->opg_Storage)
312 IPTR
Prop__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
314 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
315 switch (msg
->opg_AttrID
)
317 case MUIA_Prop_First
:
319 if (data
->prop_object
)
322 /* So we can get a more current value */
323 GetAttr(PGA_Top
,data
->prop_object
,&v
);
324 data
->first
= upscale(data
, v
);
329 case MUIA_Prop_Entries
: STORE
= data
->entries
; return 1;
330 case MUIA_Prop_Visible
: STORE
= data
->visible
; return 1;
332 /* CHECKME: MUIA_Prop_Release
334 TextEditor.mcc sets up notification on slider obj which is subclass
335 of group and notification on group children (the prop object) will be
336 dropped if the child does not return TRUE on OM_GET.
338 It may be that MUI handles this differently, because a quick check
339 with UAE/MUI showed that a GetAttr() of MUIA_Prop_Release on alider
340 object does not work (returns FALSE). Maybe MUI slider class is
341 similiar to for exampe NListview.mcc which overrides MUIM_Notify where
342 it checks for known attributes and forwards the Method to the correct child
345 case MUIA_Prop_Release
: STORE
= 0; return 1;
347 return DoSuperMethodA(cl
,obj
,(Msg
)msg
);
354 IPTR
Prop__MUIM_AskMinMax(struct IClass
*cl
, Object
*obj
, struct MUIP_AskMinMax
*msg
)
356 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
359 ** let our superclass first fill in what it thinks about sizes.
360 ** this will e.g. add the size of frame and inner spacing.
362 DoSuperMethodA(cl
, obj
, (Msg
)msg
);
364 msg
->MinMaxInfo
->MinWidth
+= data
->minwidth
;
365 msg
->MinMaxInfo
->DefWidth
+= data
->defwidth
;
366 msg
->MinMaxInfo
->MaxWidth
= data
->maxwidth
;
368 msg
->MinMaxInfo
->MinHeight
+= data
->minheight
;
369 msg
->MinMaxInfo
->DefHeight
+= data
->defheight
;
370 msg
->MinMaxInfo
->MaxHeight
= data
->maxheight
;
372 D(bug("Prop %p minheigh=%d\n",
373 obj
, msg
->MinMaxInfo
->MinHeight
));
378 IPTR
Prop__MUIM_Setup(struct IClass
*cl
, Object
*obj
, struct MUIP_Setup
*msg
)
380 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
381 ULONG rc
= DoSuperMethodA(cl
, obj
, (Msg
)msg
);
384 DoMethod(_win(obj
),MUIM_Window_AddEventHandler
,(IPTR
)&data
->ehn
);
388 data
->mapbuffer
= NULL
;
389 data
->maptemp
= NULL
;
392 if (!data
->usewinborder
)
394 data
->gadgetid
= DoMethod(_win(obj
),MUIM_Window_AllocGadgetID
);
395 if (data
->horiz
== TRUE
)
399 data
->maxwidth
= MUI_MAXMAX
;
400 data
->maxheight
= MUI_MAXMAX
;
408 data
->maxwidth
= MUI_MAXMAX
;
409 data
->maxheight
= MUI_MAXMAX
;
411 data
->defheight
= 50;
414 struct MUI_AreaData
*adata
= muiAreaData(obj
);
415 struct MUI_ImageSpec_intern
*spec
= adata
->mad_Background
;
419 if (spec
->type
== IST_BITMAP
)
421 struct dt_node
*node
= spec
->u
.bitmap
.dt
;
424 if (node
->mode
== MODE_PROP
)
426 set(obj
, MUIA_Frame
, MUIV_Frame_None
);
428 if (data
->horiz
== TRUE
)
430 data
->minheight
= node
->img_horizontalcontainer
->h
>> 1;
431 data
->defheight
= data
->minheight
;
432 data
->maxheight
= data
->minheight
;
436 data
->minwidth
= node
->img_verticalcontainer
->w
>> 1;
437 data
->defwidth
= data
->minwidth
;
438 data
->maxwidth
= data
->minwidth
;
449 IPTR
Prop__MUIM_Cleanup(struct IClass
*cl
, Object
*obj
, struct MUIP_Cleanup
*msg
)
451 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
452 if (!data
->usewinborder
)
454 DoMethod(_win(obj
),MUIM_Window_FreeGadgetID
,data
->gadgetid
);
458 data
->prop_object
= NULL
;
462 DoMethod(_win(obj
),MUIM_Window_RemEventHandler
,(IPTR
)&data
->ehn
);
463 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
466 void WritePixelArrayAlphaToImage(struct NewImage
*in
, UWORD sx
, UWORD sy
, struct NewImage
*out
, UWORD xp
, UWORD yp
, UWORD w
, UWORD h
)
469 UBYTE rs
, gs
, bs
, as
, rd
, gd
, bd
;
472 for (y
= 0; y
< h
; y
++)
474 for (x
= 0; x
< w
; x
++)
476 argb
= in
->data
[x
+ sx
+ (y
+ sy
) * in
->w
];
483 rgb
= out
->data
[x
+xp
+(y
+yp
)*out
->w
];
490 r
= ((rs
* as
) >> 8) + ((rd
* (255 - as
)) >> 8);
491 g
= ((gs
* as
) >> 8) + ((gd
* (255 - as
)) >> 8);
492 b
= ((bs
* as
) >> 8) + ((bd
* (255 - as
)) >> 8);
494 out
->data
[x
+xp
+(y
+yp
)*out
->w
] = SET_ARGB(255, r
, g
, b
);
500 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
) {
504 if ((sw
== 0) || (dw
== 0)) return xp
;
508 if (w
< ddw
) ddw
= w
;
510 if (dst
!= NULL
) WritePixelArrayAlphaToImage(ni
, sx
, sy
, dst
, x
, yp
, ddw
, dh
);
511 if ((maprp
!= NULL
) && (ni
->bitmap
!= NULL
))
515 BltMaskBitMapRastPort(ni
->bitmap
, sx
, sy
, maprp
, x
, yp
, ddw
, dh
, 0xe0, (PLANEPTR
) ni
->mask
);
517 else BltBitMapRastPort(ni
->bitmap
, sx
, sy
, maprp
, x
, yp
, ddw
, dh
, 0xc0);
525 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
) {
529 if ((sh
== 0) || (dh
== 0)) return yp
;
532 if (h
< ddh
) ddh
= h
;
534 if (dst
!= NULL
) WritePixelArrayAlphaToImage(ni
, sx
, sy
, dst
, xp
, y
, dw
, ddh
);
535 if ((maprp
!= NULL
) && (ni
->bitmap
!= NULL
))
539 BltMaskBitMapRastPort(ni
->bitmap
, sx
, sy
, maprp
, xp
, y
, dw
, ddh
, 0xe0, (PLANEPTR
) ni
->mask
);
541 else BltBitMapRastPort(ni
->bitmap
, sx
, sy
, maprp
, xp
, y
, dw
, ddh
, 0xc0);
552 void, CustomPropRenderFunc
,
553 AROS_UFHA(struct Hook
*, h
, A0
),
554 AROS_UFHA(Object
*, obj
, A2
),
555 AROS_UFHA(struct wdpDrawBorderPropKnob
*, msg
, A1
)
560 struct Prop_DATA
*node
= h
->h_Data
;
562 struct dt_node
*data
= node
->node
;
565 if (msg
->MethodID
== WDM_DRAW_BORDERPROPKNOB
)
567 struct Window
*window
= msg
->wdp_Window
;
568 struct NewImage
*temp
;
569 struct BitMap
*maptemp
;
570 struct RastPort
*winrp
= msg
->wdp_RPort
;
571 struct RastPort
*maprp
;
572 struct Gadget
*gadget
= msg
->wdp_Gadget
;
573 struct Rectangle
*r
= msg
->wdp_RenderRect
;
574 struct PropInfo
*pi
= ((struct PropInfo
*)gadget
->SpecialInfo
);
575 BOOL hit
= (msg
->wdp_Flags
& WDF_DBPK_HIT
) ? TRUE
: FALSE
;
578 UWORD MinX
, MinY
, MaxX
, MaxY
, StartX
, StartY
;
584 maptemp
= node
->maptemp
;
587 depth
= (ULONG
) GetBitMapAttr(winrp
->BitMap
, BMA_DEPTH
);
589 if (node
->buffer
) for (i
= 0; i
< (node
->buffer
->w
* node
->buffer
->h
); i
++) node
->temp
->data
[i
] = node
->buffer
->data
[i
];
590 if (node
->mapbuffer
) BltBitMap(node
->mapbuffer
, 0, 0, node
->maptemp
, 0, 0, node
->propwidth
, node
->propheight
, 0xc0, 0xff, NULL
);
593 r
= msg
->wdp_PropRect
;
598 MaxX
= r
->MaxX
- r
->MinX
;
599 MaxY
= r
->MaxY
- r
->MinY
;
601 if ((pi
->Flags
& FREEVERT
) != 0)
603 is
= data
->img_verticalcontainer
->w
>> 1;
604 if (window
->Flags
& WFLG_WINDOWACTIVE
) pos
= 0; else pos
= is
;
606 size
= MaxY
- MinY
- data
->ContainerTop_s
- data
->ContainerBottom_s
+ 1;
607 y
= WriteTiledImageVertical(temp
, maprp
, data
->img_verticalcontainer
, pos
, data
->ContainerTop_o
, is
, data
->ContainerTop_s
, MinX
, y
, is
, data
->ContainerTop_s
);
608 if (size
> 0) y
= WriteTiledImageVertical(temp
, maprp
, data
->img_verticalcontainer
, pos
, data
->ContainerVertTile_o
, is
, data
->ContainerVertTile_s
, MinX
, y
, is
, size
);
609 y
= WriteTiledImageVertical(temp
, maprp
, data
->img_verticalcontainer
, pos
, data
->ContainerBottom_o
, is
, data
->ContainerBottom_s
, MinX
, y
, is
, data
->ContainerBottom_s
);
611 else if ((pi
->Flags
& FREEHORIZ
) != 0)
613 is
= data
->img_horizontalcontainer
->h
>> 1;
614 if (window
->Flags
& WFLG_WINDOWACTIVE
) pos
= 0; else pos
= is
;
616 size
= MaxX
- MinX
- data
->ContainerLeft_s
- data
->ContainerRight_s
+ 1;
617 x
= WriteTiledImageHorizontal(temp
, maprp
, data
->img_horizontalcontainer
, data
->ContainerLeft_o
, pos
, data
->ContainerLeft_s
, is
, x
, MinY
, data
->ContainerLeft_s
, is
);
618 if (size
> 0) x
= WriteTiledImageHorizontal(temp
, maprp
, data
->img_horizontalcontainer
, data
->ContainerHorTile_o
, pos
, data
->ContainerHorTile_s
, is
, x
, MinY
, size
, is
);
619 x
= WriteTiledImageHorizontal(temp
, maprp
, data
->img_horizontalcontainer
, data
->ContainerRight_o
, pos
, data
->ContainerRight_s
, is
, x
, MinY
, data
->ContainerRight_s
, is
);
622 r
= msg
->wdp_RenderRect
;
623 MinX
= r
->MinX
- StartX
;
624 MinY
= r
->MinY
- StartY
;
625 MaxX
= r
->MaxX
- StartX
;
626 MaxY
= r
->MaxY
- StartY
;
628 if ((pi
->Flags
& FREEVERT
) != 0)
630 is
= data
->img_verticalknob
->w
/ 3;
631 if (hit
) pos
= is
; else if (window
->Flags
& WFLG_WINDOWACTIVE
) pos
= 0; else pos
= is
* 2;
633 size
= MaxY
- MinY
- data
->KnobTop_s
- data
->KnobBottom_s
+ 1;
634 y
= WriteTiledImageVertical(temp
, maprp
, data
->img_verticalknob
, pos
, data
->KnobTop_o
, is
, data
->KnobTop_s
, MinX
, y
, is
, data
->KnobTop_s
);
636 if (size
> data
->KnobVertGripper_s
) {
637 size
= size
- data
->KnobVertGripper_s
;
640 if (size
> 0) y
= WriteTiledImageVertical(temp
, maprp
, data
->img_verticalknob
, pos
, data
->KnobTileTop_o
, is
, data
->KnobTileTop_s
, MinX
, y
, is
, size
);
641 y
= WriteTiledImageVertical(temp
, maprp
, data
->img_verticalknob
, pos
, data
->KnobVertGripper_o
, is
, data
->KnobVertGripper_s
, MinX
, y
, is
, data
->KnobVertGripper_s
);
642 size
= size_bak
- size
;
643 if (size
> 0) y
= WriteTiledImageVertical(temp
, maprp
, data
->img_verticalknob
, pos
, data
->KnobTileBottom_o
, is
, data
->KnobTileBottom_s
, MinX
, y
, is
, size
);
645 y
= WriteTiledImageVertical(temp
, maprp
, data
->img_verticalknob
, pos
, data
->KnobTileTop_o
, is
, data
->KnobTileTop_s
, MinX
, y
, is
, size
);
648 y
= WriteTiledImageVertical(temp
, maprp
, data
->img_verticalknob
, pos
, data
->KnobBottom_o
, is
, data
->KnobBottom_s
, MinX
, y
, is
, data
->KnobBottom_s
);
650 else if ((pi
->Flags
& FREEHORIZ
) != 0)
652 is
= data
->img_horizontalknob
->h
/ 3;
653 if (hit
) pos
= is
; else if (window
->Flags
& WFLG_WINDOWACTIVE
) pos
= 0; else pos
= is
* 2;
655 size
= MaxX
- MinX
- data
->KnobLeft_s
- data
->KnobRight_s
+ 1;
656 x
= WriteTiledImageHorizontal(temp
, maprp
, data
->img_horizontalknob
, data
->KnobLeft_o
, pos
, data
->KnobLeft_s
, is
, x
, MinY
, data
->KnobLeft_s
, is
);
658 if (size
> data
->KnobHorGripper_s
) {
659 size
= size
- data
->KnobHorGripper_s
;
662 if (size
> 0) x
= WriteTiledImageHorizontal(temp
, maprp
, data
->img_horizontalknob
, data
->KnobTileLeft_o
, pos
, data
->KnobTileLeft_s
, is
, x
, MinY
, size
, is
);
663 x
= WriteTiledImageHorizontal(temp
, maprp
, data
->img_horizontalknob
, data
->KnobHorGripper_o
, pos
, data
->KnobHorGripper_s
, is
, x
, MinY
, data
->KnobHorGripper_s
, is
);
664 size
= size_bak
- size
;
665 if (size
> 0) x
= WriteTiledImageHorizontal(temp
, maprp
, data
->img_horizontalknob
, data
->KnobTileRight_o
, pos
, data
->KnobTileRight_s
, is
, x
, MinY
, size
, is
);
667 x
= WriteTiledImageHorizontal(temp
, maprp
, data
->img_horizontalknob
, data
->KnobTileRight_o
, pos
, data
->KnobTileRight_s
, is
, x
, MinY
, size
, is
);
670 x
= WriteTiledImageHorizontal(temp
, maprp
, data
->img_horizontalknob
, data
->KnobRight_o
, pos
, data
->KnobRight_s
, is
, x
, MinY
, data
->KnobRight_s
, is
);
673 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
);
674 if (node
->maptemp
) BltBitMapRastPort(node
->maptemp
, 0, 0, winrp
, _left(node
->obj
), _top(node
->obj
), node
->propwidth
, node
->propheight
, 0xc0);
682 IPTR
Prop__MUIM_Show(struct IClass
*cl
, Object
*obj
, struct MUIP_Show
*msg
)
684 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
685 struct MUI_AreaData
*adata
= muiAreaData(obj
);
686 struct MUI_ImageSpec_intern
*spec
= adata
->mad_Background
;
688 ULONG rc
= DoSuperMethodA(cl
, obj
, (Msg
)msg
);
690 data
->dhook
.h_Entry
= (HOOKFUNC
) CustomPropRenderFunc
;
692 if (!data
->usewinborder
)
694 BOOL isnewlook
, completely_visible
= TRUE
;;
696 if (_flags(obj
) & MADF_INVIRTUALGROUP
)
698 Object
*wnd
, *parent
;
700 get(obj
, MUIA_WindowObject
,&wnd
);
702 while (get(parent
,MUIA_Parent
,&parent
))
705 if (parent
== wnd
) break;
707 if (_flags(parent
) & MADF_ISVIRTUALGROUP
)
709 if ((_mleft(obj
) < _mleft(parent
)) ||
710 (_mright(obj
) > _mright(parent
)) ||
711 (_mtop(obj
) < _mtop(parent
)) ||
712 (_mbottom(obj
) > _mbottom(parent
)))
714 completely_visible
= FALSE
;
715 D(bug("=== prop object: completely visible FALSE for obj %x at %d,%d - %d,%d\n",
716 obj
, _mleft(obj
), _mtop(obj
), _mright(obj
), _mbottom(obj
)));
723 if (completely_visible
)
725 if (muiGlobalInfo(obj
)->mgi_Prefs
->scrollbar_type
== SCROLLBAR_TYPE_NEWLOOK
)
730 ULONG width
= _mwidth(obj
);
731 ULONG height
= _mheight(obj
);
733 struct Hook
*dhook
= NULL
;
735 ULONG depth
= (ULONG
) GetBitMapAttr(_window(obj
)->RPort
->BitMap
, BMA_DEPTH
);
736 if (muiGlobalInfo(obj
)->mgi_Prefs
->scrollbar_type
== SCROLLBAR_TYPE_CUSTOM
)
740 if (spec
->type
== IST_BITMAP
)
742 struct dt_node
*node
= spec
->u
.bitmap
.dt
;
745 if (node
->mode
== MODE_PROP
)
747 data
->dhook
.h_Entry
= (HOOKFUNC
) CustomPropRenderFunc
;
749 data
->dhook
.h_Data
= data
;
751 dhook
= &data
->dhook
;
753 if (data
->horiz
== TRUE
) height
= node
->img_horizontalcontainer
->h
>> 1; else width
= node
->img_verticalcontainer
->w
>> 1;
754 DisposeImageContainer(data
->buffer
);
755 DisposeImageContainer(data
->temp
);
756 data
->propwidth
= width
;
757 data
->propheight
= height
;
758 if (data
->mapbuffer
) FreeBitMap(data
->mapbuffer
);
759 if (data
->maptemp
) FreeBitMap(data
->maptemp
);
762 data
->buffer
= NewImageContainer(width
, height
);
763 data
->temp
= NewImageContainer(width
, height
);
764 data
->mapbuffer
= NULL
;
765 data
->maptemp
= NULL
;
766 if ((data
->buffer
== NULL
) || (data
->temp
== NULL
))
769 DisposeImageContainer(data
->buffer
);
770 DisposeImageContainer(data
->temp
);
780 data
->mapbuffer
= AllocBitMap(width
, height
, 1, BMF_MINPLANES
, _window(obj
)->RPort
->BitMap
);
781 data
->maptemp
= AllocBitMap(width
, height
, 1, BMF_MINPLANES
, _window(obj
)->RPort
->BitMap
);
782 data
->tmprp
= CreateRastPort();
783 if ((data
->mapbuffer
== NULL
) || (data
->maptemp
== NULL
) || (data
->tmprp
== NULL
))
786 if (data
->mapbuffer
) FreeBitMap(data
->mapbuffer
);
787 if (data
->maptemp
) FreeBitMap(data
->maptemp
);
788 if (data
->tmprp
) FreeRastPort(data
->tmprp
);
789 data
->mapbuffer
= NULL
;
790 data
->maptemp
= NULL
;
792 } else data
->tmprp
->BitMap
= data
->maptemp
;
801 if (data
->prop_object
) {
802 RemoveGadget(_window(obj
), (struct Gadget
*) data
->prop_object
);
803 DisposeObject(data
->prop_object
);
806 if ((data
->prop_object
= NewObject(NULL
, "propgclass",
807 GA_Left
, _mleft(obj
),
811 GA_ID
, data
->gadgetid
,
813 PGA_DisplayHook
, dhook
, /* custom prop gadget impementation (not yet finished) */
815 PGA_Freedom
, data
->horiz
?FREEHORIZ
:FREEVERT
,
816 PGA_Total
, downscale(data
, data
->entries
),
817 PGA_Visible
, downscale(data
, data
->visible
),
818 PGA_Top
, downscale(data
, data
->first
),
819 PGA_NewLook
, isnewlook
,
820 PGA_Borderless
, TRUE
,
821 ICA_TARGET
, ICTARGET_IDCMP
, /* needed for notification */
824 AddGadget(_window(obj
),(struct Gadget
*)data
->prop_object
,~0);
827 } else if (!data
->prop_object
)
829 switch (data
->usewinborder
)
831 case MUIV_Prop_UseWinBorder_Right
:
832 data
->prop_object
= muiRenderInfo(obj
)->mri_VertProp
;
833 if (data
->prop_object
)
835 /* Store pointer to this propclass object in propgadget->UserData,
836 so that window class when receiving IDCMP_IDCMUPDATE from
837 arrow gadgets can notify propclass object */
839 ((struct Gadget
*)data
->prop_object
)->UserData
= obj
;
843 case MUIV_Prop_UseWinBorder_Bottom
:
844 data
->prop_object
= muiRenderInfo(obj
)->mri_HorizProp
;
845 if (data
->prop_object
)
847 /* Store pointer to this propclass object in propgadget->UserData,
848 so that window class when receiving IDCMP_IDCMUPDATE from
849 arrow gadgets can notify propclass object */
851 ((struct Gadget
*)data
->prop_object
)->UserData
= obj
;
855 if (data
->prop_object
)
857 data
->gadgetid
= ((struct Gadget
*)data
->prop_object
)->GadgetID
;
859 SetAttrs(data
->prop_object
, ICA_TARGET
, NULL
, TAG_DONE
);
860 if (SetGadgetAttrs((struct Gadget
*)data
->prop_object
,_window(obj
),NULL
,
861 PGA_Top
,downscale(data
, data
->first
),
862 PGA_Visible
,downscale(data
, data
->visible
),
863 PGA_Total
,downscale(data
, data
->entries
),
866 RefreshGList((struct Gadget
*)data
->prop_object
, _window(obj
), NULL
, 1);
868 SetAttrs(data
->prop_object
, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
875 IPTR
Prop__MUIM_Draw(struct IClass
*cl
, Object
*obj
, struct MUIP_Draw
*msg
)
877 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
879 /* No drawings if own border */
880 if (data
->usewinborder
) return 0;
882 DoSuperMethodA(cl
, obj
, (Msg
)msg
);
884 if (!(msg
->flags
& MADF_DRAWOBJECT
)) return 1;
886 if (data
->buffer
|| data
->mapbuffer
)
889 // get(obj, MUIA_Parent, &p);
890 //if (p) DoMethod(p, MUIM_DrawParentBackground, _left(obj), _top(obj), _width(obj), _height(obj), _left(obj), _top(obj), 0);
892 DoMethod(obj
, MUIM_DrawParentBackground
, _left(obj
), _top(obj
), _width(obj
), _height(obj
), _left(obj
), _top(obj
), 0);
894 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
);
895 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
);
898 if (data
->prop_object
) RefreshGList((struct Gadget
*)data
->prop_object
, _window(obj
), NULL
, 1);
902 IPTR
Prop__MUIM_Hide(struct IClass
*cl
, Object
*obj
, struct MUIP_Hide
*msg
)
904 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
906 if (data
->prop_object
)
908 if (!data
->usewinborder
)
910 RemoveGadget(_window(obj
),(struct Gadget
*)data
->prop_object
);
911 DisposeObject(data
->prop_object
);
912 data
->prop_object
= NULL
;
916 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
919 IPTR
Prop__MUIM_HandleEvent(struct IClass
*cl
, Object
*obj
, struct MUIP_HandleEvent
*msg
)
921 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
925 if (msg
->imsg
->Class
== IDCMP_IDCMPUPDATE
)
930 /* Check if we are meant */
931 tag
= FindTagItem(GA_ID
,(struct TagItem
*)msg
->imsg
->IAddress
);
933 if (tag
->ti_Data
!= data
->gadgetid
) return 0;
935 /* Check if we PGA_Top has really changed */
936 tag
= FindTagItem(PGA_Top
,(struct TagItem
*)msg
->imsg
->IAddress
);
938 v
= upscale(data
, tag
->ti_Data
);
940 //kprintf("PROP_HandleEvent: PGA_Top %d upscaled %d entries %d\n", tag->ti_Data, v, data->entries);
942 if ((v
== data
->first
) && (msg
->imsg
->Qualifier
& IEQUALIFIER_REPEAT
)) return 0;
944 if ((LONG
)v
< 0) v
= 0;
946 SetAttrs(obj
, MUIA_Prop_First
, v
, MUIA_Prop_OnlyTrigger
, TRUE
,
947 MUIA_Prop_Release
, ((msg
->imsg
->Qualifier
& IEQUALIFIER_REPEAT
) ? FALSE
: TRUE
),
955 IPTR
Prop__MUIM_Prop_Increase(struct IClass
*cl
, Object
*obj
, struct MUIP_Prop_Increase
*msg
)
957 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
960 newfirst
= data
->first
+ msg
->amount
* data
->deltafactor
;
962 if (newfirst
+ data
->visible
> data
->entries
)
963 newfirst
= data
->entries
- data
->visible
;
964 if (newfirst
!= data
->first
)
965 set(obj
, MUIA_Prop_First
, newfirst
);
969 IPTR
Prop__MUIM_Prop_Decrease(struct IClass
*cl
, Object
*obj
, struct MUIP_Prop_Decrease
*msg
)
971 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
974 /* We cannot decrease if if are on the top */
975 if (data
->first
<= 0)
978 newfirst
= data
->first
- msg
->amount
* data
->deltafactor
;
981 set(obj
, MUIA_Prop_First
, 0);
982 else if (newfirst
!= data
->first
)
983 set(obj
, MUIA_Prop_First
, newfirst
);
988 BOOPSI_DISPATCHER(IPTR
, Prop_Dispatcher
, cl
, obj
, msg
)
990 switch (msg
->MethodID
)
992 case OM_NEW
: return Prop__OM_NEW(cl
, obj
, (struct opSet
*) msg
);
993 case OM_DISPOSE
: return Prop__OM_DISPOSE(cl
, obj
, msg
);
994 case OM_GET
: return Prop__OM_GET(cl
, obj
, (struct opGet
*)msg
);
995 case OM_SET
: return Prop__OM_SET(cl
, obj
, (struct opSet
*)msg
);
996 case MUIM_Setup
: return Prop__MUIM_Setup(cl
, obj
, (APTR
)msg
);
997 case MUIM_Cleanup
: return Prop__MUIM_Cleanup(cl
, obj
, (APTR
)msg
);
998 case MUIM_Show
: return Prop__MUIM_Show(cl
, obj
, (APTR
)msg
);
999 case MUIM_Hide
: return Prop__MUIM_Hide(cl
, obj
, (APTR
)msg
);
1000 case MUIM_AskMinMax
: return Prop__MUIM_AskMinMax(cl
, obj
, (APTR
)msg
);
1001 case MUIM_Draw
: return Prop__MUIM_Draw(cl
, obj
, (APTR
)msg
);
1002 case MUIM_HandleEvent
: return Prop__MUIM_HandleEvent(cl
, obj
, (APTR
)msg
);
1003 case MUIM_Prop_Decrease
: return Prop__MUIM_Prop_Decrease(cl
, obj
, (APTR
)msg
);
1004 case MUIM_Prop_Increase
: return Prop__MUIM_Prop_Increase(cl
, obj
, (APTR
)msg
);
1005 default: return DoSuperMethodA(cl
, obj
, msg
);
1009 BOOPSI_DISPATCHER_END
1011 const struct __MUIBuiltinClass _MUI_Prop_desc
=
1015 sizeof(struct Prop_DATA
),
1016 (void*)Prop_Dispatcher