2 Copyright 2002-2012, 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
=
83 ((unsigned long long)data
->entries
) * 0x10000 / 65535;
85 data
->scale16
= (ULONG
) v
;
90 static ULONG
downscale(struct Prop_DATA
*data
, ULONG val
)
92 #if SCALE16_METHOD == 1
93 if (data
->scale16
!= 0x10000)
95 unsigned long long v
=
96 ((unsigned long long)val
) * 0x10000 / data
->scale16
;
100 if (data
->entries
>= 0x10000)
102 unsigned long long v
=
103 ((unsigned long long)val
) * 65535 / data
->entries
;
111 static ULONG
upscale(struct Prop_DATA
*data
, ULONG val
)
113 #if SCALE16_METHOD == 1
114 if (data
->scale16
!= 0x10000)
116 unsigned long long v
=
117 ((unsigned long long)val
) * data
->scale16
/ 0x10000;
121 if (data
->entries
>= 0x10000)
123 unsigned long long v
=
124 ((unsigned long long)val
) * data
->entries
/ 65535;
131 IPTR
Prop__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
133 struct Prop_DATA
*data
;
134 struct TagItem
*tags
, *tag
;
136 obj
= (Object
*) DoSuperNewTags(cl
, obj
, NULL
,
137 MUIA_Background
, MUII_PropBack
, TAG_MORE
, (IPTR
) msg
->ops_AttrList
);
142 data
= INST_DATA(cl
, obj
);
143 data
->deltafactor
= 1;
145 /* parse initial taglist */
146 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
));)
150 case MUIA_Prop_Entries
:
151 data
->entries
= tag
->ti_Data
;
153 case MUIA_Prop_First
:
154 data
->first
= tag
->ti_Data
;
156 case MUIA_Prop_Horiz
:
157 data
->horiz
= tag
->ti_Data
!= 0;
159 case MUIA_Prop_Slider
:
161 case MUIA_Prop_UseWinBorder
:
162 data
->usewinborder
= tag
->ti_Data
;
164 case MUIA_Prop_Visible
:
165 data
->visible
= tag
->ti_Data
;
168 case MUIA_Prop_DeltaFactor
:
169 data
->deltafactor
= tag
->ti_Data
;
178 data
->maxwidth
= MUI_MAXMAX
;
179 data
->maxheight
= MUI_MAXMAX
;
187 data
->maxwidth
= MUI_MAXMAX
;
188 data
->maxheight
= MUI_MAXMAX
;
190 data
->defheight
= 50;
196 data
->ehn
.ehn_Events
= IDCMP_IDCMPUPDATE
;
197 data
->ehn
.ehn_Priority
= 0;
198 data
->ehn
.ehn_Flags
= 0;
199 data
->ehn
.ehn_Object
= obj
;
200 data
->ehn
.ehn_Class
= cl
;
202 if (data
->usewinborder
)
203 _flags(obj
) |= MADF_BORDERGADGET
;
210 IPTR
Prop__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
212 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
214 if (data
->prop_object
&& !data
->usewinborder
)
216 RemoveGadget(_window(obj
), (struct Gadget
*)data
->prop_object
);
217 DisposeObject(data
->prop_object
);
220 DisposeImageContainer(data
->buffer
);
221 DisposeImageContainer(data
->temp
);
222 if (data
->mapbuffer
!= NULL
)
223 FreeBitMap(data
->mapbuffer
);
224 if (data
->maptemp
!= NULL
)
225 FreeBitMap(data
->maptemp
);
226 if (data
->tmprp
!= NULL
)
227 FreeRastPort(data
->tmprp
);
231 data
->mapbuffer
= NULL
;
232 data
->maptemp
= NULL
;
235 return DoSuperMethodA(cl
, obj
, msg
);
238 IPTR
Prop__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
240 struct TagItem
*tags
, *tag
;
241 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
243 int only_trigger
= 0;
245 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
));)
249 case MUIA_Prop_Entries
:
250 if ((IPTR
) data
->entries
!= tag
->ti_Data
)
252 data
->entries
= tag
->ti_Data
;
257 tag
->ti_Tag
= TAG_IGNORE
;
261 case MUIA_Prop_First
:
262 if ((IPTR
) data
->first
!= tag
->ti_Data
)
264 data
->first
= tag
->ti_Data
;
269 tag
->ti_Tag
= TAG_IGNORE
;
273 case MUIA_Prop_Slider
:
276 case MUIA_Prop_Visible
:
277 if ((IPTR
) data
->visible
!= tag
->ti_Data
)
279 data
->visible
= tag
->ti_Data
;
284 tag
->ti_Tag
= TAG_IGNORE
;
288 case MUIA_Prop_OnlyTrigger
:
289 only_trigger
= tag
->ti_Data
;
292 case MUIA_Prop_DeltaFactor
:
293 data
->deltafactor
= tag
->ti_Data
;
301 if (data
->prop_object
&& refresh
&& !only_trigger
)
305 /* Rendering will happen here! This could make problems with
306 * virtual groups, forward this to MUIM_Draw??? */
307 SetAttrs(data
->prop_object
, ICA_TARGET
, NULL
, TAG_DONE
);
308 if (SetGadgetAttrs((struct Gadget
*)data
->prop_object
, _window(obj
),
309 NULL
, PGA_Top
, downscale(data
, data
->first
), PGA_Visible
,
310 downscale(data
, data
->visible
), PGA_Total
, downscale(data
,
311 data
->entries
), TAG_DONE
))
312 RefreshGList((struct Gadget
*)data
->prop_object
, _window(obj
),
314 SetAttrs(data
->prop_object
, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
317 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
320 #define STORE *(msg->opg_Storage)
321 IPTR
Prop__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
323 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
324 switch (msg
->opg_AttrID
)
326 case MUIA_Prop_First
:
328 if (data
->prop_object
)
331 /* So we can get a more current value */
332 GetAttr(PGA_Top
, data
->prop_object
, &v
);
333 data
->first
= upscale(data
, v
);
338 case MUIA_Prop_Entries
:
339 STORE
= data
->entries
;
341 case MUIA_Prop_Visible
:
342 STORE
= data
->visible
;
345 /* CHECKME: MUIA_Prop_Release
347 TextEditor.mcc sets up notification on slider obj which is subclass
348 of group and notification on group children (the prop object) will
349 be dropped if the child does not return TRUE on OM_GET.
351 It may be that MUI handles this differently, because a quick check
352 with UAE/MUI showed that a GetAttr() of MUIA_Prop_Release on alider
353 object does not work (returns FALSE). Maybe MUI slider class is
354 similiar to for exampe NListview.mcc which overrides MUIM_Notify
355 where it checks for known attributes and forwards the Method to
356 the correct child of the group.
358 case MUIA_Prop_Release
:
362 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
369 IPTR
Prop__MUIM_AskMinMax(struct IClass
*cl
, Object
*obj
,
370 struct MUIP_AskMinMax
*msg
)
372 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
375 ** let our superclass first fill in what it thinks about sizes.
376 ** this will e.g. add the size of frame and inner spacing.
378 DoSuperMethodA(cl
, obj
, (Msg
) msg
);
380 msg
->MinMaxInfo
->MinWidth
+= data
->minwidth
;
381 msg
->MinMaxInfo
->DefWidth
+= data
->defwidth
;
382 msg
->MinMaxInfo
->MaxWidth
= data
->maxwidth
;
384 msg
->MinMaxInfo
->MinHeight
+= data
->minheight
;
385 msg
->MinMaxInfo
->DefHeight
+= data
->defheight
;
386 msg
->MinMaxInfo
->MaxHeight
= data
->maxheight
;
388 D(bug("Prop %p minheigh=%d\n", obj
, msg
->MinMaxInfo
->MinHeight
));
393 IPTR
Prop__MUIM_Setup(struct IClass
*cl
, Object
*obj
,
394 struct MUIP_Setup
*msg
)
396 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
397 ULONG rc
= DoSuperMethodA(cl
, obj
, (Msg
) msg
);
401 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
) & data
->ehn
);
405 data
->mapbuffer
= NULL
;
406 data
->maptemp
= NULL
;
409 if (!data
->usewinborder
)
411 data
->gadgetid
= DoMethod(_win(obj
), MUIM_Window_AllocGadgetID
);
416 data
->maxwidth
= MUI_MAXMAX
;
417 data
->maxheight
= MUI_MAXMAX
;
425 data
->maxwidth
= MUI_MAXMAX
;
426 data
->maxheight
= MUI_MAXMAX
;
428 data
->defheight
= 50;
431 struct MUI_AreaData
*adata
= muiAreaData(obj
);
432 struct MUI_ImageSpec_intern
*spec
= adata
->mad_Background
;
436 if (spec
->type
== IST_BITMAP
)
438 struct dt_node
*node
= spec
->u
.bitmap
.dt
;
441 if (node
->mode
== MODE_PROP
)
443 set(obj
, MUIA_Frame
, MUIV_Frame_None
);
448 node
->img_horizontalcontainer
->h
>> 1;
449 data
->defheight
= data
->minheight
;
450 data
->maxheight
= data
->minheight
;
455 node
->img_verticalcontainer
->w
>> 1;
456 data
->defwidth
= data
->minwidth
;
457 data
->maxwidth
= data
->minwidth
;
468 IPTR
Prop__MUIM_Cleanup(struct IClass
*cl
, Object
*obj
,
469 struct MUIP_Cleanup
*msg
)
471 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
472 if (!data
->usewinborder
)
474 DoMethod(_win(obj
), MUIM_Window_FreeGadgetID
, data
->gadgetid
);
478 data
->prop_object
= NULL
;
482 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
) & data
->ehn
);
483 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
486 void WritePixelArrayAlphaToImage(struct NewImage
*in
, UWORD sx
, UWORD sy
,
487 struct NewImage
*out
, UWORD xp
, UWORD yp
, UWORD w
, UWORD h
)
490 UBYTE rs
, gs
, bs
, as
, rd
, gd
, bd
;
493 for (y
= 0; y
< h
; y
++)
495 for (x
= 0; x
< w
; x
++)
497 argb
= in
->data
[x
+ sx
+ (y
+ sy
) * in
->w
];
504 rgb
= out
->data
[x
+ xp
+ (y
+ yp
) * out
->w
];
511 r
= ((rs
* as
) >> 8) + ((rd
* (255 - as
)) >> 8);
512 g
= ((gs
* as
) >> 8) + ((gd
* (255 - as
)) >> 8);
513 b
= ((bs
* as
) >> 8) + ((bd
* (255 - as
)) >> 8);
515 out
->data
[x
+ xp
+ (y
+ yp
) * out
->w
] = SET_ARGB(255, r
, g
, b
);
521 int WriteTiledImageHorizontal(struct NewImage
*dst
, struct RastPort
*maprp
,
522 struct NewImage
*ni
, int sx
, int sy
, int sw
, int sh
, int xp
, int yp
,
528 if ((sw
== 0) || (dw
== 0))
538 WritePixelArrayAlphaToImage(ni
, sx
, sy
, dst
, x
, yp
, ddw
, dh
);
539 if ((maprp
!= NULL
) && (ni
->bitmap
!= NULL
))
543 BltMaskBitMapRastPort(ni
->bitmap
, sx
, sy
, maprp
, x
, yp
, ddw
,
544 dh
, 0xe0, (PLANEPTR
) ni
->mask
);
547 BltBitMapRastPort(ni
->bitmap
, sx
, sy
, maprp
, x
, yp
, ddw
, dh
,
556 int WriteTiledImageVertical(struct NewImage
*dst
, struct RastPort
*maprp
,
557 struct NewImage
*ni
, int sx
, int sy
, int sw
, int sh
, int xp
, int yp
,
563 if ((sh
== 0) || (dh
== 0))
572 WritePixelArrayAlphaToImage(ni
, sx
, sy
, dst
, xp
, y
, dw
, ddh
);
573 if ((maprp
!= NULL
) && (ni
->bitmap
!= NULL
))
577 BltMaskBitMapRastPort(ni
->bitmap
, sx
, sy
, maprp
, xp
, y
, dw
,
578 ddh
, 0xe0, (PLANEPTR
) ni
->mask
);
581 BltBitMapRastPort(ni
->bitmap
, sx
, sy
, maprp
, xp
, y
, dw
, ddh
,
592 (void, CustomPropRenderFunc
,
593 AROS_UFHA(struct Hook
*, h
, A0
),
594 AROS_UFHA(Object
*, obj
, A2
),
595 AROS_UFHA(struct wdpDrawBorderPropKnob
*, msg
, A1
))
599 struct Prop_DATA
*node
= h
->h_Data
;
600 struct dt_node
*data
= node
->node
;
602 if (msg
->MethodID
== WDM_DRAW_BORDERPROPKNOB
)
604 struct Window
*window
= msg
->wdp_Window
;
605 struct NewImage
*temp
;
606 struct RastPort
*winrp
= msg
->wdp_RPort
;
607 struct RastPort
*maprp
;
608 struct Gadget
*gadget
= msg
->wdp_Gadget
;
609 struct Rectangle
*r
= msg
->wdp_RenderRect
;
610 struct PropInfo
*pi
= ((struct PropInfo
*)gadget
->SpecialInfo
);
611 BOOL hit
= (msg
->wdp_Flags
& WDF_DBPK_HIT
) ? TRUE
: FALSE
;
614 UWORD MinX
, MinY
, MaxX
, MaxY
, StartX
, StartY
;
623 for (i
= 0; i
< (node
->buffer
->w
* node
->buffer
->h
); i
++)
624 node
->temp
->data
[i
] = node
->buffer
->data
[i
];
626 BltBitMap(node
->mapbuffer
, 0, 0, node
->maptemp
, 0, 0,
627 node
->propwidth
, node
->propheight
, 0xc0, 0xff, NULL
);
630 r
= msg
->wdp_PropRect
;
635 MaxX
= r
->MaxX
- r
->MinX
;
636 MaxY
= r
->MaxY
- r
->MinY
;
638 if ((pi
->Flags
& FREEVERT
) != 0)
640 is
= data
->img_verticalcontainer
->w
>> 1;
641 if (window
->Flags
& WFLG_WINDOWACTIVE
)
647 MaxY
- MinY
- data
->ContainerTop_s
-
648 data
->ContainerBottom_s
+ 1;
649 y
= WriteTiledImageVertical(temp
, maprp
,
650 data
->img_verticalcontainer
, pos
, data
->ContainerTop_o
, is
,
651 data
->ContainerTop_s
, MinX
, y
, is
, data
->ContainerTop_s
);
653 y
= WriteTiledImageVertical(temp
, maprp
,
654 data
->img_verticalcontainer
, pos
,
655 data
->ContainerVertTile_o
, is
,
656 data
->ContainerVertTile_s
, MinX
, y
, is
, size
);
657 y
= WriteTiledImageVertical(temp
, maprp
,
658 data
->img_verticalcontainer
, pos
, data
->ContainerBottom_o
,
659 is
, data
->ContainerBottom_s
, MinX
, y
, is
,
660 data
->ContainerBottom_s
);
662 else if ((pi
->Flags
& FREEHORIZ
) != 0)
664 is
= data
->img_horizontalcontainer
->h
>> 1;
665 if (window
->Flags
& WFLG_WINDOWACTIVE
)
671 MaxX
- MinX
- data
->ContainerLeft_s
-
672 data
->ContainerRight_s
+ 1;
673 x
= WriteTiledImageHorizontal(temp
, maprp
,
674 data
->img_horizontalcontainer
, data
->ContainerLeft_o
, pos
,
675 data
->ContainerLeft_s
, is
, x
, MinY
, data
->ContainerLeft_s
,
678 x
= WriteTiledImageHorizontal(temp
, maprp
,
679 data
->img_horizontalcontainer
, data
->ContainerHorTile_o
,
680 pos
, data
->ContainerHorTile_s
, is
, x
, MinY
, size
, is
);
681 x
= WriteTiledImageHorizontal(temp
, maprp
,
682 data
->img_horizontalcontainer
, data
->ContainerRight_o
, pos
,
683 data
->ContainerRight_s
, is
, x
, MinY
, data
->ContainerRight_s
,
687 r
= msg
->wdp_RenderRect
;
688 MinX
= r
->MinX
- StartX
;
689 MinY
= r
->MinY
- StartY
;
690 MaxX
= r
->MaxX
- StartX
;
691 MaxY
= r
->MaxY
- StartY
;
693 if ((pi
->Flags
& FREEVERT
) != 0)
695 is
= data
->img_verticalknob
->w
/ 3;
698 else if (window
->Flags
& WFLG_WINDOWACTIVE
)
703 size
= MaxY
- MinY
- data
->KnobTop_s
- data
->KnobBottom_s
+ 1;
704 y
= WriteTiledImageVertical(temp
, maprp
, data
->img_verticalknob
,
705 pos
, data
->KnobTop_o
, is
, data
->KnobTop_s
, MinX
, y
, is
,
709 if (size
> data
->KnobVertGripper_s
)
711 size
= size
- data
->KnobVertGripper_s
;
715 y
= WriteTiledImageVertical(temp
, maprp
,
716 data
->img_verticalknob
, pos
,
717 data
->KnobTileTop_o
, is
, data
->KnobTileTop_s
,
719 y
= WriteTiledImageVertical(temp
, maprp
,
720 data
->img_verticalknob
, pos
,
721 data
->KnobVertGripper_o
, is
,
722 data
->KnobVertGripper_s
, MinX
, y
, is
,
723 data
->KnobVertGripper_s
);
724 size
= size_bak
- size
;
726 y
= WriteTiledImageVertical(temp
, maprp
,
727 data
->img_verticalknob
, pos
,
728 data
->KnobTileBottom_o
, is
,
729 data
->KnobTileBottom_s
, MinX
, y
, is
, size
);
733 y
= WriteTiledImageVertical(temp
, maprp
,
734 data
->img_verticalknob
, pos
, data
->KnobTileTop_o
,
735 is
, data
->KnobTileTop_s
, MinX
, y
, is
, size
);
738 y
= WriteTiledImageVertical(temp
, maprp
, data
->img_verticalknob
,
739 pos
, data
->KnobBottom_o
, is
, data
->KnobBottom_s
, MinX
, y
,
740 is
, data
->KnobBottom_s
);
742 else if ((pi
->Flags
& FREEHORIZ
) != 0)
744 is
= data
->img_horizontalknob
->h
/ 3;
747 else if (window
->Flags
& WFLG_WINDOWACTIVE
)
752 size
= MaxX
- MinX
- data
->KnobLeft_s
- data
->KnobRight_s
+ 1;
753 x
= WriteTiledImageHorizontal(temp
, maprp
,
754 data
->img_horizontalknob
, data
->KnobLeft_o
, pos
,
755 data
->KnobLeft_s
, is
, x
, MinY
, data
->KnobLeft_s
, is
);
758 if (size
> data
->KnobHorGripper_s
)
760 size
= size
- data
->KnobHorGripper_s
;
764 x
= WriteTiledImageHorizontal(temp
, maprp
,
765 data
->img_horizontalknob
, data
->KnobTileLeft_o
,
766 pos
, data
->KnobTileLeft_s
, is
, x
, MinY
, size
,
768 x
= WriteTiledImageHorizontal(temp
, maprp
,
769 data
->img_horizontalknob
, data
->KnobHorGripper_o
,
770 pos
, data
->KnobHorGripper_s
, is
, x
, MinY
,
771 data
->KnobHorGripper_s
, is
);
772 size
= size_bak
- size
;
774 x
= WriteTiledImageHorizontal(temp
, maprp
,
775 data
->img_horizontalknob
, data
->KnobTileRight_o
,
776 pos
, data
->KnobTileRight_s
, is
, x
, MinY
, size
,
781 x
= WriteTiledImageHorizontal(temp
, maprp
,
782 data
->img_horizontalknob
, data
->KnobTileRight_o
,
783 pos
, data
->KnobTileRight_s
, is
, x
, MinY
, size
, is
);
786 x
= WriteTiledImageHorizontal(temp
, maprp
,
787 data
->img_horizontalknob
, data
->KnobRight_o
, pos
,
788 data
->KnobRight_s
, is
, x
, MinY
, data
->KnobRight_s
, is
);
792 WritePixelArray(node
->temp
->data
, 0, 0, node
->temp
->w
* 4,
793 winrp
, _left(node
->obj
), _top(node
->obj
), node
->temp
->w
,
794 node
->temp
->h
, RECTFMT_ARGB
);
796 BltBitMapRastPort(node
->maptemp
, 0, 0, winrp
, _left(node
->obj
),
797 _top(node
->obj
), node
->propwidth
, node
->propheight
, 0xc0);
805 IPTR
Prop__MUIM_Show(struct IClass
*cl
, Object
*obj
, struct MUIP_Show
*msg
)
807 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
808 struct MUI_AreaData
*adata
= muiAreaData(obj
);
809 struct MUI_ImageSpec_intern
*spec
= adata
->mad_Background
;
811 ULONG rc
= DoSuperMethodA(cl
, obj
, (Msg
) msg
);
813 data
->dhook
.h_Entry
= (HOOKFUNC
) CustomPropRenderFunc
;
815 if (!data
->usewinborder
)
817 BOOL isnewlook
, completely_visible
= TRUE
;;
819 if (_flags(obj
) & MADF_INVIRTUALGROUP
)
821 Object
*wnd
= NULL
, *parent
;
823 get(obj
, MUIA_WindowObject
, &wnd
);
825 while (get(parent
, MUIA_Parent
, &parent
))
832 if (_flags(parent
) & MADF_ISVIRTUALGROUP
)
834 if ((_mleft(obj
) < _mleft(parent
)) ||
835 (_mright(obj
) > _mright(parent
)) ||
836 (_mtop(obj
) < _mtop(parent
)) ||
837 (_mbottom(obj
) > _mbottom(parent
)))
839 completely_visible
= FALSE
;
840 D(bug("=== prop object: completely visible FALSE "
841 "for obj %x at %d,%d - %d,%d\n",
842 obj
, _mleft(obj
), _mtop(obj
), _mright(obj
),
850 if (completely_visible
)
852 if (muiGlobalInfo(obj
)->mgi_Prefs
->scrollbar_type
==
853 SCROLLBAR_TYPE_NEWLOOK
)
858 ULONG width
= _mwidth(obj
);
859 ULONG height
= _mheight(obj
);
861 struct Hook
*dhook
= NULL
;
864 (ULONG
) GetBitMapAttr(_window(obj
)->RPort
->BitMap
,
866 if (muiGlobalInfo(obj
)->mgi_Prefs
->scrollbar_type
==
867 SCROLLBAR_TYPE_CUSTOM
)
871 if (spec
->type
== IST_BITMAP
)
873 struct dt_node
*node
= spec
->u
.bitmap
.dt
;
876 if (node
->mode
== MODE_PROP
)
878 data
->dhook
.h_Entry
=
879 (HOOKFUNC
) CustomPropRenderFunc
;
881 data
->dhook
.h_Data
= data
;
883 dhook
= &data
->dhook
;
887 node
->img_horizontalcontainer
->
891 node
->img_verticalcontainer
->w
>> 1;
892 DisposeImageContainer(data
->buffer
);
893 DisposeImageContainer(data
->temp
);
894 data
->propwidth
= width
;
895 data
->propheight
= height
;
897 FreeBitMap(data
->mapbuffer
);
899 FreeBitMap(data
->maptemp
);
903 NewImageContainer(width
, height
);
905 NewImageContainer(width
, height
);
906 data
->mapbuffer
= NULL
;
907 data
->maptemp
= NULL
;
908 if ((data
->buffer
== NULL
)
909 || (data
->temp
== NULL
))
912 DisposeImageContainer(data
->buffer
);
913 DisposeImageContainer(data
->temp
);
924 AllocBitMap(width
, height
, 1,
926 _window(obj
)->RPort
->BitMap
);
928 AllocBitMap(width
, height
, 1,
930 _window(obj
)->RPort
->BitMap
);
931 data
->tmprp
= CreateRastPort();
932 if ((data
->mapbuffer
== NULL
)
933 || (data
->maptemp
== NULL
)
934 || (data
->tmprp
== NULL
))
938 FreeBitMap(data
->mapbuffer
);
940 FreeBitMap(data
->maptemp
);
942 FreeRastPort(data
->tmprp
);
943 data
->mapbuffer
= NULL
;
944 data
->maptemp
= NULL
;
948 data
->tmprp
->BitMap
= data
->maptemp
;
957 if (data
->prop_object
)
959 RemoveGadget(_window(obj
),
960 (struct Gadget
*)data
->prop_object
);
961 DisposeObject(data
->prop_object
);
964 if ((data
->prop_object
= NewObject(NULL
, "propgclass",
965 GA_Left
, _mleft(obj
),
968 GA_Height
, height
, GA_ID
, data
->gadgetid
,
970 /* custom prop gadget implementation (not finished) */
971 PGA_DisplayHook
, dhook
,
973 PGA_Freedom
, data
->horiz
? FREEHORIZ
: FREEVERT
,
974 PGA_Total
, downscale(data
, data
->entries
),
975 PGA_Visible
, downscale(data
, data
->visible
),
976 PGA_Top
, downscale(data
, data
->first
),
977 PGA_NewLook
, isnewlook
,
978 PGA_Borderless
, TRUE
,
979 ICA_TARGET
, ICTARGET_IDCMP
, /* for notification */
982 AddGadget(_window(obj
), (struct Gadget
*)data
->prop_object
,
987 else if (!data
->prop_object
)
989 switch (data
->usewinborder
)
991 case MUIV_Prop_UseWinBorder_Right
:
992 data
->prop_object
= muiRenderInfo(obj
)->mri_VertProp
;
993 if (data
->prop_object
)
995 /* Store pointer to this propclass object in
996 propgadget->UserData,
997 so that window class when receiving IDCMP_IDCMUPDATE from
998 arrow gadgets can notify propclass object */
1000 ((struct Gadget
*)data
->prop_object
)->UserData
= obj
;
1004 case MUIV_Prop_UseWinBorder_Bottom
:
1005 data
->prop_object
= muiRenderInfo(obj
)->mri_HorizProp
;
1006 if (data
->prop_object
)
1008 /* Store pointer to this propclass object in
1009 propgadget->UserData,
1010 so that window class when receiving IDCMP_IDCMUPDATE from
1011 arrow gadgets can notify propclass object */
1013 ((struct Gadget
*)data
->prop_object
)->UserData
= obj
;
1017 if (data
->prop_object
)
1019 data
->gadgetid
= ((struct Gadget
*)data
->prop_object
)->GadgetID
;
1021 SetAttrs(data
->prop_object
, ICA_TARGET
, NULL
, TAG_DONE
);
1022 if (SetGadgetAttrs((struct Gadget
*)data
->prop_object
,
1023 _window(obj
), NULL
, PGA_Top
, downscale(data
,
1024 data
->first
), PGA_Visible
, downscale(data
,
1025 data
->visible
), PGA_Total
, downscale(data
,
1026 data
->entries
), TAG_DONE
))
1028 RefreshGList((struct Gadget
*)data
->prop_object
,
1029 _window(obj
), NULL
, 1);
1031 SetAttrs(data
->prop_object
, ICA_TARGET
, ICTARGET_IDCMP
,
1039 IPTR
Prop__MUIM_Draw(struct IClass
*cl
, Object
*obj
,
1040 struct MUIP_Draw
*msg
)
1042 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
1044 /* No drawings if own border */
1045 if (data
->usewinborder
)
1048 DoSuperMethodA(cl
, obj
, (Msg
) msg
);
1050 if (!(msg
->flags
& MADF_DRAWOBJECT
))
1053 if (data
->buffer
|| data
->mapbuffer
)
1055 // Object *p = NULL;
1056 // get(obj, MUIA_Parent, &p);
1058 // DoMethod(p, MUIM_DrawParentBackground, _left(obj), _top(obj),
1059 // _width(obj), _height(obj), _left(obj), _top(obj), 0);
1061 DoMethod(obj
, MUIM_DrawParentBackground
, _left(obj
), _top(obj
),
1062 _width(obj
), _height(obj
), _left(obj
), _top(obj
), 0);
1065 ReadPixelArray(data
->buffer
->data
, 0, 0, data
->buffer
->w
* 4,
1066 _rp(data
->obj
), _mleft(data
->obj
), _mtop(data
->obj
),
1067 data
->buffer
->w
, data
->buffer
->h
, RECTFMT_ARGB
);
1068 if (data
->mapbuffer
)
1069 BltBitMap(_window(data
->obj
)->RPort
->BitMap
,
1070 _window(data
->obj
)->LeftEdge
+ _mleft(data
->obj
),
1071 _window(data
->obj
)->TopEdge
+ _mtop(data
->obj
),
1072 data
->mapbuffer
, 0, 0, data
->propwidth
, data
->propheight
,
1076 if (data
->prop_object
)
1077 RefreshGList((struct Gadget
*)data
->prop_object
, _window(obj
), NULL
,
1082 IPTR
Prop__MUIM_Hide(struct IClass
*cl
, Object
*obj
,
1083 struct MUIP_Hide
*msg
)
1085 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
1087 if (data
->prop_object
)
1089 if (!data
->usewinborder
)
1091 RemoveGadget(_window(obj
), (struct Gadget
*)data
->prop_object
);
1092 DisposeObject(data
->prop_object
);
1093 data
->prop_object
= NULL
;
1097 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
1100 IPTR
Prop__MUIM_HandleEvent(struct IClass
*cl
, Object
*obj
,
1101 struct MUIP_HandleEvent
*msg
)
1103 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
1107 if (msg
->imsg
->Class
== IDCMP_IDCMPUPDATE
)
1109 struct TagItem
*tag
;
1112 /* Check if we are meant */
1113 tag
= FindTagItem(GA_ID
, (struct TagItem
*)msg
->imsg
->IAddress
);
1116 if (tag
->ti_Data
!= data
->gadgetid
)
1119 /* Check if we PGA_Top has really changed */
1121 FindTagItem(PGA_Top
, (struct TagItem
*)msg
->imsg
->IAddress
);
1124 v
= upscale(data
, tag
->ti_Data
);
1126 //kprintf("PROP_HandleEvent: PGA_Top %d upscaled %d entries %d\n",
1127 // tag->ti_Data, v, data->entries);
1129 if ((v
== data
->first
)
1130 && (msg
->imsg
->Qualifier
& IEQUALIFIER_REPEAT
))
1136 SetAttrs(obj
, MUIA_Prop_First
, v
, MUIA_Prop_OnlyTrigger
, TRUE
,
1139 Qualifier
& IEQUALIFIER_REPEAT
) ? FALSE
: TRUE
),
1147 IPTR
Prop__MUIM_Prop_Increase(struct IClass
*cl
, Object
*obj
,
1148 struct MUIP_Prop_Increase
*msg
)
1150 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
1153 newfirst
= data
->first
+ msg
->amount
* data
->deltafactor
;
1155 if (newfirst
+ data
->visible
> data
->entries
)
1156 newfirst
= data
->entries
- data
->visible
;
1157 if (newfirst
!= data
->first
)
1158 set(obj
, MUIA_Prop_First
, newfirst
);
1162 IPTR
Prop__MUIM_Prop_Decrease(struct IClass
*cl
, Object
*obj
,
1163 struct MUIP_Prop_Decrease
*msg
)
1165 struct Prop_DATA
*data
= INST_DATA(cl
, obj
);
1168 /* We cannot decrease if if are on the top */
1169 if (data
->first
<= 0)
1172 newfirst
= data
->first
- msg
->amount
* data
->deltafactor
;
1175 set(obj
, MUIA_Prop_First
, 0);
1176 else if (newfirst
!= data
->first
)
1177 set(obj
, MUIA_Prop_First
, newfirst
);
1182 BOOPSI_DISPATCHER(IPTR
, Prop_Dispatcher
, cl
, obj
, msg
)
1184 switch (msg
->MethodID
)
1187 return Prop__OM_NEW(cl
, obj
, (struct opSet
*)msg
);
1189 return Prop__OM_DISPOSE(cl
, obj
, msg
);
1191 return Prop__OM_GET(cl
, obj
, (struct opGet
*)msg
);
1193 return Prop__OM_SET(cl
, obj
, (struct opSet
*)msg
);
1195 return Prop__MUIM_Setup(cl
, obj
, (APTR
) msg
);
1197 return Prop__MUIM_Cleanup(cl
, obj
, (APTR
) msg
);
1199 return Prop__MUIM_Show(cl
, obj
, (APTR
) msg
);
1201 return Prop__MUIM_Hide(cl
, obj
, (APTR
) msg
);
1202 case MUIM_AskMinMax
:
1203 return Prop__MUIM_AskMinMax(cl
, obj
, (APTR
) msg
);
1205 return Prop__MUIM_Draw(cl
, obj
, (APTR
) msg
);
1206 case MUIM_HandleEvent
:
1207 return Prop__MUIM_HandleEvent(cl
, obj
, (APTR
) msg
);
1208 case MUIM_Prop_Decrease
:
1209 return Prop__MUIM_Prop_Decrease(cl
, obj
, (APTR
) msg
);
1210 case MUIM_Prop_Increase
:
1211 return Prop__MUIM_Prop_Increase(cl
, obj
, (APTR
) msg
);
1213 return DoSuperMethodA(cl
, obj
, msg
);
1217 BOOPSI_DISPATCHER_END
1219 const struct __MUIBuiltinClass _MUI_Prop_desc
=
1223 sizeof(struct Prop_DATA
),
1224 (void *) Prop_Dispatcher