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 struct TagItem
*tstate
= opu
->opu_AttrList
, *tag
;
169 ULONG oact
= cd
->cd_Active
, data
;
170 WORD dis
= GADGET(obj
)->Flags
& GFLG_DISABLED
;
171 UBYTE
**new_labels
= NULL
;
174 struct GadgetInfo
*gi
= opu
->opu_GInfo
;
177 * First let the superclass do its thing.
179 AsmDoSuperMethodA(cl
, obj
, (Msg
)opu
);
182 * Force the correct activation method.
184 GADGET(obj
)->Activation
|= GACT_RELVERIFY
;
185 GADGET(obj
)->Activation
&= ~GACT_IMMEDIATE
;
187 while (tag
= NextTagItem(&tstate
))
193 cd
->cd_PopupFont
= (struct TextAttr
*)data
;
195 * Let the label know.
197 DoSetMethodNG(cd
->cd_ArrayLabel
, LAB_TextAttr
, data
, TAG_DONE
);
201 if (data
) cd
->cd_Flags
|= CDF_THIN
;
202 else cd
->cd_Flags
&= ~CDF_THIN
;
206 cd
->cd_Active
= data
;
211 * Count the number of labels in the array (offset by 1).
213 num_labels
= data
? CountLabels((UBYTE
**)data
) : -1;
217 if (new_labels
= BGUI_AllocPoolMem((num_labels
+ 2) * sizeof(UBYTE
*)))
219 if (cd
->cd_Labels
) BGUI_FreePoolMem(cd
->cd_Labels
);
220 cd
->cd_Labels
= new_labels
;
221 cd
->cd_NumLabels
= num_labels
;
222 CopyMem((UBYTE
*)data
, (UBYTE
*)new_labels
, (num_labels
+ 1) * sizeof(UBYTE
*));
229 if (data
) cd
->cd_Flags
|= CDF_POPUP
;
230 else cd
->cd_Flags
&= ~CDF_POPUP
;
234 if (data
) cd
->cd_Flags
|= CDF_POPACTIVE
;
235 else cd
->cd_Flags
&= ~CDF_POPACTIVE
;
240 if ((GADGET(obj
)->Flags
& GFLG_DISABLED
) != dis
)
242 * Re-render when the gadget disabled state changed.
247 * Here's that sanity check again.
249 if (cd
->cd_Active
> cd
->cd_NumLabels
)
250 cd
->cd_Active
= cd
->cd_NumLabels
;
252 if ((oact
!= cd
->cd_Active
) || new_labels
)
257 DoSetMethodNG(cd
->cd_ArrayLabel
, LAB_Label
, cd
->cd_Labels
[cd
->cd_Active
], LAB_Place
, PLACE_IN
, TAG_DONE
);
261 if (render
) DoRenderMethod(obj
, gi
, GREDRAW_REDRAW
);
264 * Notify the target when necessary.
266 if (oact
!= cd
->cd_Active
)
268 DoNotifyMethod(obj
, gi
, 0, GA_ID
, GADGET(obj
)->GadgetID
, CYC_Active
, cd
->cd_Active
, TAG_DONE
);
277 * Render the cycle arrow.
279 STATIC VOID
RenderArrow(struct BaseInfo
*bi
, struct IBox
*ib
, ULONG state
, CD
*cd
)
281 Object
*image
= cd
->cd_Image
;
287 int w
= cd
->cd_ImageWidth
;
289 int l
= ib
->Left
- w
;
293 * Render the small seperator.
297 BSetDPenA(bi
, (state
!= IDS_SELECTED
) ? SHINEPEN
: SHADOWPEN
);
298 VLine(bi
->bi_RPort
, l
+ w
+ 1, t
+ 2, t
+ h
- 3);
300 BSetDPenA(bi
, (state
!= IDS_SELECTED
) ? SHADOWPEN
: SHINEPEN
);
301 VLine(bi
->bi_RPort
, l
+ w
, t
+ 2, t
+ h
- 3);
303 if (state
== IDS_SELECTED
)
305 type
= BUILTIN_CYCLE2
;
309 type
= (cd
->cd_Flags
& CDF_POPUP
) ? BUILTIN_POPUP
: BUILTIN_CYCLE
;
313 * Setup and render the image.
315 DoSetMethodNG(image
, VIT_BuiltIn
, type
, IA_Left
, l
, IA_Top
, t
, IA_Width
, w
, IA_Height
, h
, TAG_END
);
316 BDrawImageState(bi
, image
, 0, 0, state
);
321 * Render an entry in the popup-list.
323 STATIC VOID
RenderPopupEntry(struct BaseInfo
*bi
, CD
*cd
, ULONG num
, BOOL sel
)
325 UWORD ypos
, xpos
, tlen
, pix
= cd
->cd_Flags
& CDF_THIN
? 2 : 4;
326 UBYTE
*name
= cd
->cd_Labels
[num
];
327 struct RastPort
*rp
= bi
->bi_RPort
;
330 * Compute text length.
332 tlen
= TextWidth(rp
, name
);
337 xpos
= (cd
->cd_PopWindow
->Width
- tlen
) >> 1;
338 ypos
= (num
* rp
->TxHeight
) + 2;
341 * Setup pens for filling.
344 BSetDPenA(bi
, sel
? BARDETAILPEN
: BARBLOCKPEN
);
346 if (OS30
) BSetDPenA(bi
, sel
? BARDETAILPEN
: BARBLOCKPEN
);
347 else BSetDPenA(bi
, BLOCKPEN
);
354 BRectFill(bi
, pix
, ypos
, cd
->cd_PopWindow
->Width
- pix
- 1, ypos
+ rp
->TxHeight
- 1);
360 BSetDrMd(bi
, sel
? JAM2
|INVERSVID
: JAM2
);
362 if (OS30
) BSetDrMd(bi
, sel
? JAM2
|INVERSVID
: JAM2
);
363 else BSetDrMd(bi
, JAM2
);
367 * Setup pens for text.
369 BSetDPenA(bi
, BARDETAILPEN
);
370 BSetDPenB(bi
, BARBLOCKPEN
);
373 * Move to the desired location and render.
375 Move(rp
, xpos
, ypos
+ rp
->TxBaseline
);
376 Text(rp
, name
, strlen(name
));
380 * < OS 3.0 will get the entry
381 * complemented if it is selected.
385 BSetDrMd(bi
, JAM2
|COMPLEMENT
);
386 BRectFill(bi
, pix
, ypos
, cd
->cd_PopWindow
->Width
- pix
- 1, ypos
+ rp
->TxHeight
- 1);
395 METHOD(CycleClassRenderX
, struct gpRender
*, gpr
)
397 CD
*cd
= INST_DATA(cl
, obj
);
399 DoSuperSetMethodNG(cl
, obj
, BT_LeftOffset
, cd
->cd_ImageWidth
, TAG_DONE
);
401 return AsmDoSuperMethodA(cl
, obj
, (Msg
)gpr
);
409 METHOD(CycleClassRender
, struct bmRender
*, bmr
)
411 CD
*cd
= INST_DATA(cl
, obj
);
412 BC
*bc
= BASE_DATA(obj
);
413 struct BaseInfo
*bi
= bmr
->bmr_BInfo
;
414 int state
= GADGET(obj
)->Flags
& GFLG_SELECTED
? IDS_SELECTED
: IDS_NORMAL
;
417 * Render the baseclass.
419 AsmDoSuperMethodA(cl
, obj
, (Msg
)bmr
);
424 *IMAGEBOX(cd
->cd_ArrayLabel
) = bc
->bc_InnerBox
;
429 RenderArrow(bi
, &bc
->bc_InnerBox
, state
, cd
);
432 * We always render the active gadget label.
434 BDrawImageState(bi
, cd
->cd_ArrayLabel
, 0, 0, state
);
437 * Ghost the gadget when it is disabled.
439 if (GADGET(obj
)->Flags
& GFLG_DISABLED
)
440 BDisableBox(bi
, &bc
->bc_HitBox
);
449 * Open the popup-window.
451 METHOD(OpenPopupWindow
, struct gpInput
*, gpi
)
453 CD
*cd
= INST_DATA(cl
, obj
);
454 BC
*bc
= BASE_DATA(obj
);
455 UWORD max_items
, num_items
, wleft
, wtop
, wwi
, wwh
, bg
, i
;
458 struct GadgetInfo
*gi
= gpi
->gpi_GInfo
;
461 ULONG rc
= GMR_NOREUSE
;
464 * Get the gadget hitbox bounds.
466 Get_SuperAttr(cl
, obj
, BT_HitBox
, &ibox
);
471 if (cd
->cd_PopupFont
)
472 cd
->cd_Font
= BGUI_OpenFont(cd
->cd_PopupFont
);
474 /* BAD CODE! Does not check OpenFont result! */
476 ysize
= cd
->cd_Font
->tf_YSize
;
479 * How many items will fit?
481 max_items
= (gi
->gi_Screen
->Height
- 4) / ysize
;
484 * How many do we have?
486 num_items
= (cd
->cd_NumLabels
+ 1) > max_items
? max_items
: (cd
->cd_NumLabels
+ 1);
489 * Compute window position and dimensions.
491 wleft
= bc
->bc_HitBox
.Left
+ gi
->gi_Window
->LeftEdge
;
492 wwi
= bc
->bc_HitBox
.Width
;
493 wwh
= (num_items
* ysize
) + 4;
495 if (cd
->cd_Flags
& CDF_POPACTIVE
)
496 wtop
= gi
->gi_Screen
->MouseY
- (2 + ((cd
->cd_Active
* ysize
) + (ysize
>> 1)));
498 wtop
= bc
->bc_HitBox
.Top
+ bc
->bc_HitBox
.Height
+ gi
->gi_Window
->TopEdge
;
503 cd
->cd_PopWindow
= OpenWindowTags(NULL
, WA_Left
, wleft
, WA_Top
, wtop
,
504 WA_Width
, wwi
, WA_Height
, wwh
,
505 WA_Flags
, 0, WA_IDCMP
, 0,
506 WA_Borderless
, TRUE
, WA_AutoAdjust
, TRUE
,
507 WA_SmartRefresh
, TRUE
, WA_NoCareRefresh
, TRUE
,
508 WA_RMBTrap
, TRUE
, WA_CustomScreen
, gi
->gi_Screen
,
513 if (cd
->cd_PopWindow
)
516 * No previous selected item.
518 cd
->cd_Previous
= (UWORD
)~0;
520 /* AROS BUGFIX --> AMIGAOS BUGFIX: TAG_DONE missed in both AllocBaseInfoDebug and AllocBaseInfo call below */
522 if (bi
= AllocBaseInfoDebug(__FILE__
,__LINE__
,BI_Screen
, gi
->gi_Screen
, BI_RastPort
, rp
= cd
->cd_PopWindow
->RPort
, TAG_DONE
))
524 if (bi
= AllocBaseInfo(BI_Screen
, gi
->gi_Screen
, BI_RastPort
, rp
= cd
->cd_PopWindow
->RPort
, TAG_DONE
))
530 if (cd
->cd_Font
) BSetFont(bi
, cd
->cd_Font
);
533 * Setup pop window rastport.
535 BSetDPenA(bi
, BARBLOCKPEN
);
541 BBoxFill(bi
, 0, 0, wwi
, wwh
);
544 * Setup pop window rastport.
546 BSetDPenA(bi
, BARDETAILPEN
);
552 Draw(rp
, wwi
- 1, 0);
553 Draw(rp
, wwi
- 1, wwh
- 1 );
554 Draw(rp
, 0, wwh
- 1 );
557 if (!(cd
->cd_Flags
& CDF_THIN
))
560 Draw(rp
, 1, wwh
- 1 );
561 Move(rp
, wwi
- 2, 0 );
562 Draw(rp
, wwi
- 2, wwh
- 1 );
566 * Render list-entries.
568 for (i
= 0; i
< num_items
; i
++)
569 RenderPopupEntry(bi
, cd
, i
, FALSE
);
585 METHOD(CycleClassGoActive
, struct gpInput
*, gpi
)
587 CD
*cd
= INST_DATA(cl
, obj
);
588 BC
*bc
= BASE_DATA(obj
);
589 ULONG rc
= GMR_NOREUSE
;
592 * We don't go active when we are disabled.
594 if ( GADGET( obj
)->Flags
& GFLG_DISABLED
)
595 return( GMR_NOREUSE
);
598 * We only go active when triggered by a mouse click.
603 * Let the superclass have a go...
605 AsmDoSuperMethodA(cl
, obj
, (Msg
)gpi
);
610 if (cd
->cd_Flags
& CDF_POPUP
)
612 if (gpi
->gpi_GInfo
->gi_Window
->MouseX
> (bc
->bc_HitBox
.Left
+ cd
->cd_ImageWidth
))
615 * Open the popup window.
616 * Do normal selection if the popup window will not open.
618 if (OpenPopupWindow(cl
, obj
, gpi
) == 0) return 0;
621 GADGET(obj
)->Flags
|= GFLG_SELECTED
;
622 DoRenderMethod(obj
, gpi
->gpi_GInfo
, GREDRAW_REDRAW
);
631 * Which entry is selected?
633 //STATIC ASM UWORD Selected(REG(a0) CD *cd, REG(a1) struct RastPort *rp)
634 STATIC ASM
REGFUNC2(UWORD
, Selected
,
635 REGPARAM(A0
, CD
*, cd
),
636 REGPARAM(A1
, struct RastPort
*, rp
))
638 WORD mx
= cd
->cd_PopWindow
->MouseX
, my
= cd
->cd_PopWindow
->MouseY
;
642 * Mouse in the window?
644 if ( mx
>= 4 && mx
< ( cd
->cd_PopWindow
->Width
- 4 ) && my
>= 2 && my
< ( cd
->cd_PopWindow
->Height
- 2 )) {
646 * Find the entry the mouse is over.
648 item
= ( my
- 2 ) / rp
->TxHeight
;
650 if ( item
> cd
->cd_NumLabels
) item
= ~0;
652 return(( UWORD
)item
);
657 * Handle the gadget input.
659 METHOD(CycleClassHandleInput
, struct gpInput
*, gpi
)
661 CD
*cd
= INST_DATA(cl
, obj
);
662 struct gpHitTest gph
;
664 struct GadgetInfo
*gi
= gpi
->gpi_GInfo
;
666 ULONG rc
= GMR_MEACTIVE
;
671 if (cd
->cd_PopWindow
)
674 * Is the parent window still activated?
675 * If not we return immediatly.
677 * Security. Intuition should do this already.
679 if (!(gi
->gi_Window
->Flags
& WFLG_WINDOWACTIVE
))
683 if (bi
= AllocBaseInfoDebug(__FILE__
,__LINE__
,BI_GadgetInfo
, gi
, BI_RastPort
, cd
->cd_PopWindow
->RPort
, TAG_DONE
))
685 if (bi
= AllocBaseInfo(BI_GadgetInfo
, gi
, BI_RastPort
, cd
->cd_PopWindow
->RPort
, TAG_DONE
))
689 * Where is the mouse?
691 item
= Selected(cd
, bi
->bi_RPort
);
696 if (item
!= cd
->cd_Previous
)
699 * Previous selected item?
701 if (cd
->cd_Previous
!= (UWORD
)~0) RenderPopupEntry(bi
, cd
, cd
->cd_Previous
, FALSE
);
704 * Render current entry.
706 if (item
!= ~0) RenderPopupEntry(bi
, cd
, item
, TRUE
);
711 cd
->cd_Previous
= item
;
718 if (gpi
->gpi_IEvent
->ie_Class
== IECLASS_RAWMOUSE
)
720 switch (gpi
->gpi_IEvent
->ie_Code
)
724 * Setup the new label and return VERIFY.
726 if (cd
->cd_Previous
!= (UWORD
)~0)
728 if (cd
->cd_Active
!= cd
->cd_Previous
)
731 * We need notification.
733 cd
->cd_Flags
|= CDF_NOTIFY
;
738 cd
->cd_Active
= cd
->cd_Previous
;
741 * Setup the new label.
743 DoSetMethodNG(cd
->cd_ArrayLabel
, LAB_Label
, cd
->cd_Labels
[cd
->cd_Active
], LAB_Place
, PLACE_IN
, TAG_END
);
746 * Re-render to show the change.
748 DoRenderMethod(obj
, gi
, GREDRAW_REDRAW
);
751 * We want to notify about the attribute change.
753 rc
= GMR_NOREUSE
| GMR_VERIFY
;
770 * Mouse over the object?
772 gph
.MethodID
= GM_HITTEST
;
773 gph
.gpht_GInfo
= gpi
->gpi_GInfo
;
774 gph
.gpht_Mouse
.X
= gpi
->gpi_Mouse
.X
;
775 gph
.gpht_Mouse
.Y
= gpi
->gpi_Mouse
.Y
;
777 if ( AsmDoMethodA( obj
, ( Msg
)&gph
) == GMR_GADGETHIT
)
780 if ( gpi
->gpi_IEvent
->ie_Class
== IECLASS_RAWMOUSE
) {
781 switch ( gpi
->gpi_IEvent
->ie_Code
) {
785 * When we are selected we setup a new label
790 * Clicked with the shift key down cycles backward.
792 if ( gpi
->gpi_IEvent
->ie_Qualifier
& ( IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
)) {
793 if ( cd
->cd_Active
) cd
->cd_Active
--;
794 else cd
->cd_Active
= cd
->cd_NumLabels
;
796 if ( cd
->cd_Active
< cd
->cd_NumLabels
) cd
->cd_Active
++;
797 else cd
->cd_Active
= 0;
801 * Setup the new label.
803 DoSetMethodNG( cd
->cd_ArrayLabel
, LAB_Label
, cd
->cd_Labels
[ cd
->cd_Active
], LAB_Place
, PLACE_IN
, TAG_END
);
806 * We want to notify about the attribute change.
808 rc
= GMR_NOREUSE
| GMR_VERIFY
;
809 cd
->cd_Flags
|= CDF_NOTIFY
;
812 * We are not selected anymore.
827 * Do we need a visual change?
829 if ((GADGET(obj
)->Flags
& GFLG_SELECTED
) != sel
)
832 * Toggle the selected bit.
834 GADGET(obj
)->Flags
^= GFLG_SELECTED
;
837 * Re-render the gadget.
839 DoRenderMethod(obj
, gi
, GREDRAW_REDRAW
);
848 METHOD(CycleClassGoInactive
, struct gpGoInactive
*, gpgi
)
850 CD
*cd
= INST_DATA( cl
, obj
);
855 if ( cd
->cd_PopWindow
) {
859 CloseWindow( cd
->cd_PopWindow
);
860 cd
->cd_PopWindow
= NULL
;
867 BGUI_CloseFont( cd
->cd_Font
);
874 if ( cd
->cd_Flags
& CDF_NOTIFY
) {
875 DoNotifyMethod( obj
, gpgi
->gpgi_GInfo
, 0L, GA_ID
, GADGET( obj
)->GadgetID
, CYC_Active
, cd
->cd_Active
, TAG_END
);
876 cd
->cd_Flags
&= ~CDF_NOTIFY
;
879 return( AsmDoSuperMethodA( cl
, obj
, ( Msg
)gpgi
));
887 METHOD(CycleClassGet
, struct opGet
*, opg
)
889 CD
*cd
= INST_DATA(cl
, obj
);
890 ULONG rc
= 1, *store
= opg
->opg_Storage
;
892 switch (opg
->opg_AttrID
)
899 STORE cd
->cd_Flags
& CDF_POPUP
;
903 STORE cd
->cd_Flags
& CDF_POPACTIVE
;
907 rc
= AsmDoSuperMethodA(cl
, obj
, (Msg
)opg
);
916 * Dispose of the object.
918 METHOD(CycleClassDispose
, Msg
, msg
)
920 CD
*cd
= INST_DATA(cl
, obj
);
922 if (cd
->cd_ArrayLabel
)
923 DisposeObject(cd
->cd_ArrayLabel
);
925 DisposeObject(cd
->cd_Image
);
928 BGUI_FreePoolMem(cd
->cd_Labels
);
930 return AsmDoSuperMethodA(cl
, obj
, msg
);
936 * The object size is requested.
938 METHOD(CycleClassDimensions
, struct bmDimensions
*, bmd
)
940 CD
*cd
= INST_DATA(cl
, obj
);
941 struct BaseInfo
*bi
= bmd
->bmd_BInfo
;
942 UBYTE
**labels
= cd
->cd_Labels
, *label
;
944 struct TextExtent te
;
947 * Find out the size of the largest label.
949 while (label
= *labels
++)
952 * Call TextExtent to find out the text width.
954 TextExtent(bi
->bi_RPort
, label
, strlen(label
), &te
);
955 if (te
.te_Width
> mw
) mw
= te
.te_Width
;
956 if (te
.te_Height
> mh
) mh
= te
.te_Height
;
960 * Include cycle/popup image width.
962 return CalcDimensions(cl
, obj
, bmd
, mw
+ 30, mh
+ 2);
970 METHOD(CycleClassKeyActive
, struct wmKeyInput
*, wmki
)
972 CD
*cd
= INST_DATA(cl
, obj
);
973 UWORD qual
= wmki
->wmki_IEvent
->ie_Qualifier
;
976 * Shifted is backwards, normal is forward.
978 if (qual
& (IEQUALIFIER_LSHIFT
|IEQUALIFIER_RSHIFT
))
983 if (cd
->cd_Active
< 0) cd
->cd_Active
= cd
->cd_NumLabels
;
984 if (cd
->cd_Active
> cd
->cd_NumLabels
) cd
->cd_Active
= 0;
987 * Setup and re-render.
989 DoSetMethodNG(cd
->cd_ArrayLabel
, LAB_Label
, cd
->cd_Labels
[cd
->cd_Active
], LAB_Place
, PLACE_IN
, TAG_END
);
990 DoNotifyMethod(obj
, wmki
->wmki_GInfo
, 0, GA_ID
, GADGET(obj
)->GadgetID
, CYC_Active
, cd
->cd_Active
, TAG_END
);
991 DoRenderMethod(obj
, wmki
->wmki_GInfo
, GREDRAW_REDRAW
);
996 *(wmki
->wmki_ID
) = GADGET(obj
)->GadgetID
;
1003 /// Class initialization.
1007 STATIC DPFUNC ClassFunc
[] = {
1008 BASE_RENDER
, (FUNCPTR
)CycleClassRender
,
1009 GM_RENDER
, (FUNCPTR
)CycleClassRenderX
,
1010 BASE_DIMENSIONS
, (FUNCPTR
)CycleClassDimensions
,
1012 OM_NEW
, (FUNCPTR
)CycleClassNew
,
1013 OM_SET
, (FUNCPTR
)CycleClassSetUpdate
,
1014 OM_UPDATE
, (FUNCPTR
)CycleClassSetUpdate
,
1015 OM_GET
, (FUNCPTR
)CycleClassGet
,
1016 OM_DISPOSE
, (FUNCPTR
)CycleClassDispose
,
1017 GM_GOACTIVE
, (FUNCPTR
)CycleClassGoActive
,
1018 GM_HANDLEINPUT
, (FUNCPTR
)CycleClassHandleInput
,
1019 GM_GOINACTIVE
, (FUNCPTR
)CycleClassGoInactive
,
1020 WM_KEYACTIVE
, (FUNCPTR
)CycleClassKeyActive
,
1025 * Simple class initialization.
1027 makeproto Class
*InitCycleClass(void)
1029 return BGUI_MakeClass(CLASS_SuperClassBGUI
, BGUI_BASE_GADGET
,
1030 CLASS_ObjectSize
, sizeof(CD
),
1031 CLASS_DFTable
, ClassFunc
,