7 * (C) Copyright 1998 Manuel Lemos.
8 * (C) Copyright 1996-1997 Ian J. Einman.
9 * (C) Copyright 1993-1996 Jaba Development.
10 * (C) Copyright 1993-1996 Jan van den Baard.
11 * All Rights Reserved.
14 * Revision 42.8 2004/06/16 20:16:48 verhaegs
15 * Use METHODPROTO, METHOD_END and REGFUNCPROTOn where needed.
17 * Revision 42.7 2002/09/17 17:11:16 stegerg
18 * inversvid drawmode together with Text() works now, so no
21 * Revision 42.6 2000/08/17 15:09:18 chodorowski
22 * Fixed compiler warnings.
24 * Revision 42.5 2000/07/18 18:32:38 stegerg
25 * The AllocBaseInfo/AllocBaseInfoDebug calls in OpenPopUpWindow method
26 * missed a TAG_DONE. Manuel, if you read this: this is a real (also in AmigaOS)
27 * bug, not just AROS!!!
29 * Revision 42.4 2000/07/11 17:04:41 stegerg
30 * temp fix for small gfx bug which happens because of INVERSVID
31 * drawmode not yet working in AROS.
33 * Revision 42.3 2000/05/29 15:42:49 stegerg
34 * fixed some "comparison is always 1 due to limited range of data type"
37 * Revision 42.2 2000/05/15 19:27:01 stegerg
38 * another hundreds of REG() macro replacements in func headers/protos.
40 * Revision 42.1 2000/05/14 23:32:47 stegerg
41 * changed over 200 function headers which all use register
42 * parameters (oh boy ...), because the simple REG() macro
43 * doesn't work with AROS. And there are still hundreds
44 * of headers left to be fixed :(
46 * Many of these functions would also work with stack
47 * params, but since i have fixed every single one
48 * I encountered up to now, I guess will have to do
49 * the same for the rest.
51 * Revision 42.0 2000/05/09 22:08:45 mlemos
52 * Bumped to revision 42.0 before handing BGUI to AROS team
54 * Revision 41.11 2000/05/09 19:54:08 mlemos
55 * Merged with the branch Manuel_Lemos_fixes.
57 * Revision 41.10.2.3 1998/12/07 03:06:57 mlemos
58 * Replaced OpenFont and CloseFont calls by the respective BGUI debug macros.
60 * Revision 41.10.2.2 1998/03/01 23:06:01 mlemos
61 * Corrected RastPort tag where GadgetInfo was being passed.
63 * Revision 41.10.2.1 1998/03/01 15:37:32 mlemos
64 * Added support to track BaseInfo memory leaks.
66 * Revision 41.10 1998/02/25 21:11:52 mlemos
69 * Revision 1.1 1998/02/25 17:07:59 mlemos
75 /// Class definitions.
77 #include "include/classdefs.h"
80 * Object instance data.
83 struct Window
*cd_PopWindow
; /* Popup window pointer. */
84 Object
*cd_ArrayLabel
; /* Label object for active label. */
85 Object
*cd_Image
; /* Image for the popcycle. */
86 UBYTE
**cd_Labels
; /* Array of object labels. */
87 ULONG cd_Active
; /* Active label. */
88 ULONG cd_NumLabels
; /* Amount of labels. */
89 struct TextAttr
*cd_PopupFont
; /* Font for pop window. */
90 struct TextFont
*cd_Font
; /* General font. */
91 UWORD cd_Flags
; /* See below. */
92 UWORD cd_Previous
; /* Previously selected label. */
93 UWORD cd_ImageWidth
; /* Width of area for clicking. */
96 #define CDF_POPUP (1<<0) /* Popup mode. */
97 #define CDF_NOTIFY (1<<1) /* Notify change. */
98 #define CDF_THIN (1<<2) /* Thin frames. */
99 #define CDF_POPACTIVE (1<<3) /* Pop on active entry. */
105 * Create a new object.
107 METHOD(CycleClassNew
, struct opSet
*, ops
)
110 struct TagItem
*tags
;
113 tags
= DefTagList(BGUI_CYCLE_GADGET
, ops
->ops_AttrList
);
116 * First we let the superclass
119 if ((rc
= NewSuperObject(cl
, obj
, tags
)))
124 cd
= INST_DATA(cl
, rc
);
129 cd
->cd_ImageWidth
= 18;
131 cd
->cd_Image
= BGUI_NewObject(BGUI_VECTOR_IMAGE
, VIT_BuiltIn
, BUILTIN_CYCLE
,
135 * Setup a Label class object used to render the active label.
137 cd
->cd_ArrayLabel
= BGUI_NewObject(BGUI_LABEL_IMAGE
, LAB_Place
, PLACE_IN
,
138 LAB_Highlight
, FALSE
,
143 AsmCoerceMethod(cl
, (Object
*)rc
, OM_SET
, tags
, NULL
);
145 if (cd
->cd_ArrayLabel
&& cd
->cd_Image
&& cd
->cd_Labels
)
151 AsmCoerceMethod(cl
, (Object
*)rc
, OM_DISPOSE
);
163 * Change the object attributes.
165 METHOD(CycleClassSetUpdate
, struct opUpdate
*, opu
)
167 CD
*cd
= INST_DATA(cl
, obj
);
168 ULONG oact
= cd
->cd_Active
;
170 struct TagItem
*tstate
= opu
->opu_AttrList
;
172 WORD dis
= GADGET(obj
)->Flags
& GFLG_DISABLED
;
173 UBYTE
**new_labels
= NULL
;
176 struct GadgetInfo
*gi
= opu
->opu_GInfo
;
179 * First let the superclass do its thing.
181 AsmDoSuperMethodA(cl
, obj
, (Msg
)opu
);
184 * Force the correct activation method.
186 GADGET(obj
)->Activation
|= GACT_RELVERIFY
;
187 GADGET(obj
)->Activation
&= ~GACT_IMMEDIATE
;
189 while ((tag
= NextTagItem(&tstate
)))
195 cd
->cd_PopupFont
= (struct TextAttr
*)data
;
197 * Let the label know.
199 DoSetMethodNG(cd
->cd_ArrayLabel
, LAB_TextAttr
, data
, TAG_DONE
);
203 if (data
) cd
->cd_Flags
|= CDF_THIN
;
204 else cd
->cd_Flags
&= ~CDF_THIN
;
208 cd
->cd_Active
= data
;
213 * Count the number of labels in the array (offset by 1).
215 num_labels
= data
? CountLabels((UBYTE
**)data
) : -1;
219 if ((new_labels
= BGUI_AllocPoolMem((num_labels
+ 2) * sizeof(UBYTE
*))))
221 if (cd
->cd_Labels
) BGUI_FreePoolMem(cd
->cd_Labels
);
222 cd
->cd_Labels
= new_labels
;
223 cd
->cd_NumLabels
= num_labels
;
224 CopyMem((UBYTE
*)data
, (UBYTE
*)new_labels
, (num_labels
+ 1) * sizeof(UBYTE
*));
231 if (data
) cd
->cd_Flags
|= CDF_POPUP
;
232 else cd
->cd_Flags
&= ~CDF_POPUP
;
236 if (data
) cd
->cd_Flags
|= CDF_POPACTIVE
;
237 else cd
->cd_Flags
&= ~CDF_POPACTIVE
;
242 if ((GADGET(obj
)->Flags
& GFLG_DISABLED
) != dis
)
244 * Re-render when the gadget disabled state changed.
249 * Here's that sanity check again.
251 if (cd
->cd_Active
> cd
->cd_NumLabels
)
252 cd
->cd_Active
= cd
->cd_NumLabels
;
254 if ((oact
!= cd
->cd_Active
) || new_labels
)
259 DoSetMethodNG(cd
->cd_ArrayLabel
, LAB_Label
, cd
->cd_Labels
[cd
->cd_Active
], LAB_Place
, PLACE_IN
, TAG_DONE
);
263 if (render
) DoRenderMethod(obj
, gi
, GREDRAW_REDRAW
);
266 * Notify the target when necessary.
268 if (oact
!= cd
->cd_Active
)
270 DoNotifyMethod(obj
, gi
, 0, GA_ID
, GADGET(obj
)->GadgetID
, CYC_Active
, cd
->cd_Active
, TAG_DONE
);
279 * Render the cycle arrow.
281 STATIC VOID
RenderArrow(struct BaseInfo
*bi
, struct IBox
*ib
, ULONG state
, CD
*cd
)
283 Object
*image
= cd
->cd_Image
;
289 int w
= cd
->cd_ImageWidth
;
291 int l
= ib
->Left
- w
;
295 * Render the small seperator.
299 BSetDPenA(bi
, (state
!= IDS_SELECTED
) ? SHINEPEN
: SHADOWPEN
);
300 VLine(bi
->bi_RPort
, l
+ w
+ 1, t
+ 2, t
+ h
- 3);
302 BSetDPenA(bi
, (state
!= IDS_SELECTED
) ? SHADOWPEN
: SHINEPEN
);
303 VLine(bi
->bi_RPort
, l
+ w
, t
+ 2, t
+ h
- 3);
305 if (state
== IDS_SELECTED
)
307 type
= BUILTIN_CYCLE2
;
311 type
= (cd
->cd_Flags
& CDF_POPUP
) ? BUILTIN_POPUP
: BUILTIN_CYCLE
;
315 * Setup and render the image.
317 DoSetMethodNG(image
, VIT_BuiltIn
, type
, IA_Left
, l
, IA_Top
, t
, IA_Width
, w
, IA_Height
, h
, TAG_END
);
318 BDrawImageState(bi
, image
, 0, 0, state
);
323 * Render an entry in the popup-list.
325 STATIC VOID
RenderPopupEntry(struct BaseInfo
*bi
, CD
*cd
, ULONG num
, BOOL sel
)
327 UWORD ypos
, xpos
, tlen
, pix
= cd
->cd_Flags
& CDF_THIN
? 2 : 4;
328 UBYTE
*name
= cd
->cd_Labels
[num
];
329 struct RastPort
*rp
= bi
->bi_RPort
;
332 * Compute text length.
334 tlen
= TextWidth(rp
, name
);
339 xpos
= (cd
->cd_PopWindow
->Width
- tlen
) >> 1;
340 ypos
= (num
* rp
->TxHeight
) + 2;
343 * Setup pens for filling.
346 BSetDPenA(bi
, sel
? BARDETAILPEN
: BARBLOCKPEN
);
348 if (OS30
) BSetDPenA(bi
, sel
? BARDETAILPEN
: BARBLOCKPEN
);
349 else BSetDPenA(bi
, BLOCKPEN
);
356 BRectFill(bi
, pix
, ypos
, cd
->cd_PopWindow
->Width
- pix
- 1, ypos
+ rp
->TxHeight
- 1);
362 BSetDrMd(bi
, sel
? JAM2
|INVERSVID
: JAM2
);
364 if (OS30
) BSetDrMd(bi
, sel
? JAM2
|INVERSVID
: JAM2
);
365 else BSetDrMd(bi
, JAM2
);
369 * Setup pens for text.
371 BSetDPenA(bi
, BARDETAILPEN
);
372 BSetDPenB(bi
, BARBLOCKPEN
);
375 * Move to the desired location and render.
377 Move(rp
, xpos
, ypos
+ rp
->TxBaseline
);
378 Text(rp
, name
, strlen(name
));
382 * < OS 3.0 will get the entry
383 * complemented if it is selected.
387 BSetDrMd(bi
, JAM2
|COMPLEMENT
);
388 BRectFill(bi
, pix
, ypos
, cd
->cd_PopWindow
->Width
- pix
- 1, ypos
+ rp
->TxHeight
- 1);
397 METHOD(CycleClassRenderX
, struct gpRender
*, gpr
)
399 CD
*cd
= INST_DATA(cl
, obj
);
401 DoSuperSetMethodNG(cl
, obj
, BT_LeftOffset
, cd
->cd_ImageWidth
, TAG_DONE
);
403 return AsmDoSuperMethodA(cl
, obj
, (Msg
)gpr
);
411 METHOD(CycleClassRender
, struct bmRender
*, bmr
)
413 CD
*cd
= INST_DATA(cl
, obj
);
414 BC
*bc
= BASE_DATA(obj
);
415 struct BaseInfo
*bi
= bmr
->bmr_BInfo
;
416 int state
= GADGET(obj
)->Flags
& GFLG_SELECTED
? IDS_SELECTED
: IDS_NORMAL
;
419 * Render the baseclass.
421 AsmDoSuperMethodA(cl
, obj
, (Msg
)bmr
);
426 *IMAGEBOX(cd
->cd_ArrayLabel
) = bc
->bc_InnerBox
;
431 RenderArrow(bi
, &bc
->bc_InnerBox
, state
, cd
);
434 * We always render the active gadget label.
436 BDrawImageState(bi
, cd
->cd_ArrayLabel
, 0, 0, state
);
439 * Ghost the gadget when it is disabled.
441 if (GADGET(obj
)->Flags
& GFLG_DISABLED
)
442 BDisableBox(bi
, &bc
->bc_HitBox
);
451 * Open the popup-window.
453 STATIC ASM IPTR
OpenPopupWindow(REG(a0
) Class
*cl
, REG(a2
) Object
*obj
, REG(a1
) struct gpInput
*gpi
)
455 CD
*cd
= INST_DATA(cl
, obj
);
456 BC
*bc
= BASE_DATA(obj
);
457 UWORD max_items
, num_items
, wleft
, wtop
, wwi
, wwh
, i
;
460 struct GadgetInfo
*gi
= gpi
->gpi_GInfo
;
463 ULONG rc
= GMR_NOREUSE
;
466 * Get the gadget hitbox bounds.
468 Get_SuperAttr(cl
, obj
, BT_HitBox
, (IPTR
*)&ibox
);
473 if (cd
->cd_PopupFont
)
474 cd
->cd_Font
= BGUI_OpenFont(cd
->cd_PopupFont
);
476 /* BAD CODE! Does not check OpenFont result! */
478 ysize
= cd
->cd_Font
->tf_YSize
;
481 * How many items will fit?
483 max_items
= (gi
->gi_Screen
->Height
- 4) / ysize
;
486 * How many do we have?
488 num_items
= (cd
->cd_NumLabels
+ 1) > max_items
? max_items
: (cd
->cd_NumLabels
+ 1);
491 * Compute window position and dimensions.
493 wleft
= bc
->bc_HitBox
.Left
+ gi
->gi_Window
->LeftEdge
;
494 wwi
= bc
->bc_HitBox
.Width
;
495 wwh
= (num_items
* ysize
) + 4;
497 if (cd
->cd_Flags
& CDF_POPACTIVE
)
498 wtop
= gi
->gi_Screen
->MouseY
- (2 + ((cd
->cd_Active
* ysize
) + (ysize
>> 1)));
500 wtop
= bc
->bc_HitBox
.Top
+ bc
->bc_HitBox
.Height
+ gi
->gi_Window
->TopEdge
;
505 cd
->cd_PopWindow
= OpenWindowTags(NULL
, WA_Left
, wleft
, WA_Top
, wtop
,
506 WA_Width
, wwi
, WA_Height
, wwh
,
507 WA_Flags
, 0, WA_IDCMP
, 0,
508 WA_Borderless
, TRUE
, WA_AutoAdjust
, TRUE
,
509 WA_SmartRefresh
, TRUE
, WA_NoCareRefresh
, TRUE
,
510 WA_RMBTrap
, TRUE
, WA_CustomScreen
, gi
->gi_Screen
,
515 if (cd
->cd_PopWindow
)
518 * No previous selected item.
520 cd
->cd_Previous
= (UWORD
)~0;
522 /* AROS BUGFIX --> AMIGAOS BUGFIX: TAG_DONE missed in both AllocBaseInfoDebug and AllocBaseInfo call below */
524 if ((bi
= AllocBaseInfoDebug(__FILE__
,__LINE__
,BI_Screen
, gi
->gi_Screen
, BI_RastPort
, rp
= cd
->cd_PopWindow
->RPort
, TAG_DONE
)))
526 if ((bi
= AllocBaseInfo(BI_Screen
, gi
->gi_Screen
, BI_RastPort
, rp
= cd
->cd_PopWindow
->RPort
, TAG_DONE
)))
532 if (cd
->cd_Font
) BSetFont(bi
, cd
->cd_Font
);
535 * Setup pop window rastport.
537 BSetDPenA(bi
, BARBLOCKPEN
);
543 BBoxFill(bi
, 0, 0, wwi
, wwh
);
546 * Setup pop window rastport.
548 BSetDPenA(bi
, BARDETAILPEN
);
554 Draw(rp
, wwi
- 1, 0);
555 Draw(rp
, wwi
- 1, wwh
- 1 );
556 Draw(rp
, 0, wwh
- 1 );
559 if (!(cd
->cd_Flags
& CDF_THIN
))
562 Draw(rp
, 1, wwh
- 1 );
563 Move(rp
, wwi
- 2, 0 );
564 Draw(rp
, wwi
- 2, wwh
- 1 );
568 * Render list-entries.
570 for (i
= 0; i
< num_items
; i
++)
571 RenderPopupEntry(bi
, cd
, i
, FALSE
);
586 METHOD(CycleClassGoActive
, struct gpInput
*, gpi
)
588 CD
*cd
= INST_DATA(cl
, obj
);
589 BC
*bc
= BASE_DATA(obj
);
590 ULONG rc
= GMR_NOREUSE
;
593 * We don't go active when we are disabled.
595 if ( GADGET( obj
)->Flags
& GFLG_DISABLED
)
596 return( GMR_NOREUSE
);
599 * We only go active when triggered by a mouse click.
604 * Let the superclass have a go...
606 AsmDoSuperMethodA(cl
, obj
, (Msg
)gpi
);
611 if (cd
->cd_Flags
& CDF_POPUP
)
613 if (gpi
->gpi_GInfo
->gi_Window
->MouseX
> (bc
->bc_HitBox
.Left
+ cd
->cd_ImageWidth
))
616 * Open the popup window.
617 * Do normal selection if the popup window will not open.
619 if (OpenPopupWindow(cl
, obj
, gpi
) == 0) return 0;
622 GADGET(obj
)->Flags
|= GFLG_SELECTED
;
623 DoRenderMethod(obj
, gpi
->gpi_GInfo
, GREDRAW_REDRAW
);
632 * Which entry is selected?
634 STATIC ASM UWORD
Selected(REG(a0
) CD
*cd
, REG(a1
) struct RastPort
*rp
)
636 WORD mx
= cd
->cd_PopWindow
->MouseX
, my
= cd
->cd_PopWindow
->MouseY
;
640 * Mouse in the window?
642 if ( mx
>= 4 && mx
< ( cd
->cd_PopWindow
->Width
- 4 ) && my
>= 2 && my
< ( cd
->cd_PopWindow
->Height
- 2 )) {
644 * Find the entry the mouse is over.
646 item
= ( my
- 2 ) / rp
->TxHeight
;
648 if ( item
> cd
->cd_NumLabels
) item
= ~0;
650 return(( UWORD
)item
);
655 * Handle the gadget input.
657 METHOD(CycleClassHandleInput
, struct gpInput
*, gpi
)
659 CD
*cd
= INST_DATA(cl
, obj
);
660 struct gpHitTest gph
;
662 struct GadgetInfo
*gi
= gpi
->gpi_GInfo
;
664 ULONG rc
= GMR_MEACTIVE
;
669 if (cd
->cd_PopWindow
)
672 * Is the parent window still activated?
673 * If not we return immediatly.
675 * Security. Intuition should do this already.
677 if (!(gi
->gi_Window
->Flags
& WFLG_WINDOWACTIVE
))
681 if ((bi
= AllocBaseInfoDebug(__FILE__
,__LINE__
,BI_GadgetInfo
, gi
, BI_RastPort
, cd
->cd_PopWindow
->RPort
, TAG_DONE
)))
683 if ((bi
= AllocBaseInfo(BI_GadgetInfo
, gi
, BI_RastPort
, cd
->cd_PopWindow
->RPort
, TAG_DONE
)))
687 * Where is the mouse?
689 item
= Selected(cd
, bi
->bi_RPort
);
694 if (item
!= cd
->cd_Previous
)
697 * Previous selected item?
699 if (cd
->cd_Previous
!= (UWORD
)~0) RenderPopupEntry(bi
, cd
, cd
->cd_Previous
, FALSE
);
702 * Render current entry.
704 if (item
!= ~0) RenderPopupEntry(bi
, cd
, item
, TRUE
);
709 cd
->cd_Previous
= item
;
716 if (gpi
->gpi_IEvent
->ie_Class
== IECLASS_RAWMOUSE
)
718 switch (gpi
->gpi_IEvent
->ie_Code
)
722 * Setup the new label and return VERIFY.
724 if (cd
->cd_Previous
!= (UWORD
)~0)
726 if (cd
->cd_Active
!= cd
->cd_Previous
)
729 * We need notification.
731 cd
->cd_Flags
|= CDF_NOTIFY
;
736 cd
->cd_Active
= cd
->cd_Previous
;
739 * Setup the new label.
741 DoSetMethodNG(cd
->cd_ArrayLabel
, LAB_Label
, cd
->cd_Labels
[cd
->cd_Active
], LAB_Place
, PLACE_IN
, TAG_END
);
744 * Re-render to show the change.
746 DoRenderMethod(obj
, gi
, GREDRAW_REDRAW
);
749 * We want to notify about the attribute change.
751 rc
= GMR_NOREUSE
| GMR_VERIFY
;
768 * Mouse over the object?
770 gph
.MethodID
= GM_HITTEST
;
771 gph
.gpht_GInfo
= gpi
->gpi_GInfo
;
772 gph
.gpht_Mouse
.X
= gpi
->gpi_Mouse
.X
;
773 gph
.gpht_Mouse
.Y
= gpi
->gpi_Mouse
.Y
;
775 if ( AsmDoMethodA( obj
, ( Msg
)&gph
) == GMR_GADGETHIT
)
778 if ( gpi
->gpi_IEvent
->ie_Class
== IECLASS_RAWMOUSE
) {
779 switch ( gpi
->gpi_IEvent
->ie_Code
) {
783 * When we are selected we setup a new label
788 * Clicked with the shift key down cycles backward.
790 if ( gpi
->gpi_IEvent
->ie_Qualifier
& ( IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
)) {
791 if ( cd
->cd_Active
) cd
->cd_Active
--;
792 else cd
->cd_Active
= cd
->cd_NumLabels
;
794 if ( cd
->cd_Active
< cd
->cd_NumLabels
) cd
->cd_Active
++;
795 else cd
->cd_Active
= 0;
799 * Setup the new label.
801 DoSetMethodNG( cd
->cd_ArrayLabel
, LAB_Label
, cd
->cd_Labels
[ cd
->cd_Active
], LAB_Place
, PLACE_IN
, TAG_END
);
804 * We want to notify about the attribute change.
806 rc
= GMR_NOREUSE
| GMR_VERIFY
;
807 cd
->cd_Flags
|= CDF_NOTIFY
;
810 * We are not selected anymore.
825 * Do we need a visual change?
827 if ((GADGET(obj
)->Flags
& GFLG_SELECTED
) != sel
)
830 * Toggle the selected bit.
832 GADGET(obj
)->Flags
^= GFLG_SELECTED
;
835 * Re-render the gadget.
837 DoRenderMethod(obj
, gi
, GREDRAW_REDRAW
);
846 METHOD(CycleClassGoInactive
, struct gpGoInactive
*, gpgi
)
848 CD
*cd
= INST_DATA( cl
, obj
);
853 if ( cd
->cd_PopWindow
) {
857 CloseWindow( cd
->cd_PopWindow
);
858 cd
->cd_PopWindow
= NULL
;
865 BGUI_CloseFont( cd
->cd_Font
);
872 if ( cd
->cd_Flags
& CDF_NOTIFY
) {
873 DoNotifyMethod( obj
, gpgi
->gpgi_GInfo
, 0L, GA_ID
, GADGET( obj
)->GadgetID
, CYC_Active
, cd
->cd_Active
, TAG_END
);
874 cd
->cd_Flags
&= ~CDF_NOTIFY
;
877 return( AsmDoSuperMethodA( cl
, obj
, ( Msg
)gpgi
));
885 METHOD(CycleClassGet
, struct opGet
*, opg
)
887 CD
*cd
= INST_DATA(cl
, obj
);
889 IPTR
*store
= opg
->opg_Storage
;
891 switch (opg
->opg_AttrID
)
898 STORE cd
->cd_Flags
& CDF_POPUP
;
902 STORE cd
->cd_Flags
& CDF_POPACTIVE
;
906 rc
= AsmDoSuperMethodA(cl
, obj
, (Msg
)opg
);
915 * Dispose of the object.
917 METHOD(CycleClassDispose
, Msg
, msg
)
919 CD
*cd
= INST_DATA(cl
, obj
);
921 if (cd
->cd_ArrayLabel
)
922 DisposeObject(cd
->cd_ArrayLabel
);
924 DisposeObject(cd
->cd_Image
);
927 BGUI_FreePoolMem(cd
->cd_Labels
);
929 return AsmDoSuperMethodA(cl
, obj
, msg
);
935 * The object size is requested.
937 METHOD(CycleClassDimensions
, struct bmDimensions
*, bmd
)
939 CD
*cd
= INST_DATA(cl
, obj
);
940 struct BaseInfo
*bi
= bmd
->bmd_BInfo
;
941 UBYTE
**labels
= cd
->cd_Labels
, *label
;
943 struct TextExtent te
;
946 * Find out the size of the largest label.
948 while ((label
= *labels
++))
951 * Call TextExtent to find out the text width.
953 TextExtent(bi
->bi_RPort
, label
, strlen(label
), &te
);
954 if (te
.te_Width
> mw
) mw
= te
.te_Width
;
955 if (te
.te_Height
> mh
) mh
= te
.te_Height
;
959 * Include cycle/popup image width.
961 return CalcDimensions(cl
, obj
, bmd
, mw
+ 30, mh
+ 2);
969 METHOD(CycleClassKeyActive
, struct wmKeyInput
*, wmki
)
971 CD
*cd
= INST_DATA(cl
, obj
);
972 UWORD qual
= wmki
->wmki_IEvent
->ie_Qualifier
;
975 * Shifted is backwards, normal is forward.
977 if (qual
& (IEQUALIFIER_LSHIFT
|IEQUALIFIER_RSHIFT
))
982 if (cd
->cd_Active
< 0) cd
->cd_Active
= cd
->cd_NumLabels
;
983 if (cd
->cd_Active
> cd
->cd_NumLabels
) cd
->cd_Active
= 0;
986 * Setup and re-render.
988 DoSetMethodNG(cd
->cd_ArrayLabel
, LAB_Label
, cd
->cd_Labels
[cd
->cd_Active
], LAB_Place
, PLACE_IN
, TAG_END
);
989 DoNotifyMethod(obj
, wmki
->wmki_GInfo
, 0, GA_ID
, GADGET(obj
)->GadgetID
, CYC_Active
, cd
->cd_Active
, TAG_END
);
990 DoRenderMethod(obj
, wmki
->wmki_GInfo
, GREDRAW_REDRAW
);
995 *(wmki
->wmki_ID
) = GADGET(obj
)->GadgetID
;
1002 /// Class initialization.
1006 STATIC DPFUNC ClassFunc
[] = {
1007 { BASE_RENDER
, CycleClassRender
, },
1008 { GM_RENDER
, CycleClassRenderX
, },
1009 { BASE_DIMENSIONS
, CycleClassDimensions
, },
1011 { OM_NEW
, CycleClassNew
, },
1012 { OM_SET
, CycleClassSetUpdate
, },
1013 { OM_UPDATE
, CycleClassSetUpdate
, },
1014 { OM_GET
, CycleClassGet
, },
1015 { OM_DISPOSE
, CycleClassDispose
, },
1016 { GM_GOACTIVE
, CycleClassGoActive
, },
1017 { GM_HANDLEINPUT
, CycleClassHandleInput
, },
1018 { GM_GOINACTIVE
, CycleClassGoInactive
, },
1019 { WM_KEYACTIVE
, CycleClassKeyActive
, },
1024 * Simple class initialization.
1026 makeproto Class
*InitCycleClass(void)
1028 return BGUI_MakeClass(CLASS_SuperClassBGUI
, BGUI_BASE_GADGET
,
1029 CLASS_ObjectSize
, sizeof(CD
),
1030 CLASS_DFTable
, ClassFunc
,