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.5 2004/06/16 20:16:48 verhaegs
15 * Use METHODPROTO, METHOD_END and REGFUNCPROTOn where needed.
17 * Revision 42.4 2003/01/18 19:10:00 chodorowski
18 * Instead of using the _AROS or __AROS preprocessor symbols, use __AROS__.
20 * Revision 42.3 2000/05/29 00:40:24 bergers
21 * Update to compile with AROS now. Should also still compile with SASC etc since I only made changes that test the define __AROS__. The compilation is still very noisy but it does the trick for the main directory. Maybe members of the BGUI team should also have a look at the compiler warnings because some could also cause problems on other systems... (Comparison always TRUE due to datatype (or something like that)). And please compile it on an Amiga to see whether it still works... Thanks.
23 * Revision 42.2 2000/05/15 19:27:02 stegerg
24 * another hundreds of REG() macro replacements in func headers/protos.
26 * Revision 42.1 2000/05/14 23:32:48 stegerg
27 * changed over 200 function headers which all use register
28 * parameters (oh boy ...), because the simple REG() macro
29 * doesn't work with AROS. And there are still hundreds
30 * of headers left to be fixed :(
32 * Many of these functions would also work with stack
33 * params, but since i have fixed every single one
34 * I encountered up to now, I guess will have to do
35 * the same for the rest.
37 * Revision 42.0 2000/05/09 22:09:48 mlemos
38 * Bumped to revision 42.0 before handing BGUI to AROS team
40 * Revision 41.11 2000/05/09 19:54:49 mlemos
41 * Merged with the branch Manuel_Lemos_fixes.
43 * Revision 41.10.2.1 1998/11/22 00:31:42 mlemos
44 * Made the radio buttons notifications map GA_Selected into TAG_IGNORE to not
45 * set the MX class group selected attribute.
47 * Revision 41.10 1998/02/25 21:12:45 mlemos
50 * Revision 1.1 1998/02/25 17:09:16 mlemos
56 #include "include/classdefs.h"
58 /// Class definitions.
60 * Object instance data.
63 UBYTE
**md_LabelStrings
; /* MX button labels. */
64 ULONG md_LabelStringsID
; /* Starting string ID label. */
65 ULONG md_ActiveLabel
; /* Currently active selection. */
66 ULONG md_MaxLabel
; /* Number of available labels. */
67 ULONG md_Place
; /* Place of the labels. */
68 Object
**md_Objects
; /* MX buttons. */
69 struct TextAttr
*md_TabsFont
; /* Font for the buttons. */
70 UWORD md_Type
; /* MX Type. */
71 ULONG md_BackFill
[2]; /* Back fill tag. */
77 STATIC
struct TagItem id2act
[] = {
78 { GA_UserData
, MX_Active
, },
79 { GA_Selected
, TAG_IGNORE
, },
92 STATIC ASM BOOL
AddMXObjects(REG(a0
) Object
*target
, REG(a1
) MD
*md
)
94 UBYTE
**labels
= md
->md_LabelStrings
;
96 ULONG id
= md
->md_LabelStringsID
;
98 struct TagItem tags
[16], *t
= &tags
[0];
100 static const struct TagItem tags_fix
[] = {
101 { LGO_FixMinWidth
, TRUE
},
102 { LGO_FixMinHeight
, TRUE
},
106 t
->ti_Tag
= GA_ToggleSelect
; t
->ti_Data
= TRUE
; t
++;
107 t
->ti_Tag
= GA_ID
; t
->ti_Data
= GADGET(target
)->GadgetID
; t
++;
108 t
->ti_Tag
= GA_Disabled
; t
->ti_Data
= GADGET(target
)->Flags
& GFLG_DISABLED
; t
++;
109 t
->ti_Tag
= LAB_SelectedDriPen
; t
->ti_Data
= TEXTPEN
; t
++;
113 case MXTYPE_RADIOBUTTON
:
114 t
->ti_Tag
= LAB_Place
; t
->ti_Data
= md
->md_Place
; t
++;
120 t
->ti_Tag
= FRM_Type
; t
->ti_Data
= FRTYPE_TAB_TOP
; t
++;
123 case MXTYPE_TAB_BOTTOM
:
124 t
->ti_Tag
= FRM_Type
; t
->ti_Data
= FRTYPE_TAB_BOTTOM
; t
++;
127 case MXTYPE_TAB_LEFT
:
128 t
->ti_Tag
= FRM_Type
; t
->ti_Data
= FRTYPE_TAB_LEFT
; t
++;
131 case MXTYPE_TAB_RIGHT
:
132 t
->ti_Tag
= FRM_Type
; t
->ti_Data
= FRTYPE_TAB_RIGHT
; t
++;
135 t
->ti_Tag
= BUTTON_SelectOnly
; t
->ti_Data
= TRUE
; t
++;
136 t
->ti_Tag
= LAB_Place
; t
->ti_Data
= PLACE_IN
; t
++;
137 t
->ti_Tag
= LAB_SelectedStyle
; t
->ti_Data
= FSF_BOLD
; t
++;
138 t
->ti_Tag
= LAB_TextAttr
; t
->ti_Data
= (IPTR
)md
->md_TabsFont
; t
++;
139 t
->ti_Tag
= md
->md_BackFill
[0]; t
->ti_Data
= md
->md_BackFill
[1]; t
++;
147 t
->ti_Tag
= TAG_DONE
;
151 * Allocate an array to hold the object pointers.
153 if ((md
->md_Objects
= (Object
**)BGUI_AllocPoolMem((md
->md_MaxLabel
+ 1) * sizeof(Object
*))))
156 * Loop through all labels.
161 * Create a toggle object.
163 if ((md
->md_Objects
[i
] = BGUI_NewObject(tab
? BGUI_BUTTON_GADGET
: BGUI_RADIOBUTTON_GADGET
,
167 GA_Selected
, (i
== md
->md_ActiveLabel
),
171 * Add it to the parent group.
173 if (AsmDoMethod(target
, GRM_ADDMEMBER
, md
->md_Objects
[i
], tab
? TAG_DONE
: TAG_MORE
, &tags_fix
))
175 if (AsmDoMethod(md
->md_Objects
[i
], BASE_ADDMAP
, target
, id2act
))
190 DisposeObject(md
->md_Objects
[i
]);
206 * Create a shiny new object.
208 STATIC
METHOD(MXClassNew
, struct opSet
*, ops
)
212 struct TagItem
*tstate
;
213 struct TagItem
*tags
= ops
->ops_AttrList
, *tag
;
214 int type
= MXTYPE_RADIOBUTTON
;
217 * No labels? No gadget!
219 if (!FindTagItem(MX_Labels
, tags
))
222 tags
= DefTagList(BGUI_MX_GADGET
, tags
);
224 if (GetTagData(MX_TabsObject
, FALSE
, tags
))
226 if (GetTagData(MX_TabsUpsideDown
, FALSE
, tags
))
227 type
= MXTYPE_TAB_BOTTOM
;
229 type
= MXTYPE_TAB_TOP
;
231 type
= GetTagData(MX_Type
, type
, tags
);
234 * Let the superclass setup an object for us.
236 if ((rc
= NewSuperObject(cl
, obj
, tags
)))
239 * Initialize instance data.
241 md
= INST_DATA(cl
, rc
);
243 md
->md_BackFill
[0] = TAG_IGNORE
;
244 md
->md_Place
= PLACE_RIGHT
;
247 while ((tag
= NextTagItem(&tstate
)))
254 * If we are a regular mx object we need a default spacing.
256 if (type
== MXTYPE_RADIOBUTTON
)
257 DoSuperSetMethodNG(cl
, (Object
*)rc
, GROUP_Spacing
, data
, TAG_DONE
);
262 * Only PLACE_LEFT & PLACE_RIGHT are supported.
264 if ((md
->md_Place
== PLACE_LEFT
) || (md
->md_Place
== PLACE_RIGHT
))
269 md
->md_LabelStrings
= (UBYTE
**)data
;
273 md
->md_LabelStringsID
= data
;
276 case MX_TabsTextAttr
:
277 md
->md_TabsFont
= (struct TextAttr
*)data
;
280 case MX_TabsBackFill
:
281 md
->md_BackFill
[0] = FRM_BackFill
;
282 md
->md_BackFill
[1] = data
;
286 md
->md_BackFill
[0] = FRM_BackPen
;
287 md
->md_BackFill
[1] = data
;
290 case MX_TabsBackDriPen
:
291 md
->md_BackFill
[0] = FRM_BackDriPen
;
292 md
->md_BackFill
[1] = data
;
295 case MX_TabsBackFillHook
:
296 md
->md_BackFill
[0] = FRM_BackFillHook
;
297 md
->md_BackFill
[1] = data
;
300 case MX_TabsFillPattern
:
301 md
->md_BackFill
[0] = FRM_FillPattern
;
302 md
->md_BackFill
[1] = data
;
308 * Count the number of labels.
310 md
->md_MaxLabel
= CountLabels(md
->md_LabelStrings
);
315 if (md
->md_ActiveLabel
> md
->md_MaxLabel
)
317 if (type
) md
->md_ActiveLabel
= 0;
318 else md
->md_ActiveLabel
= md
->md_MaxLabel
;
321 if (AddMXObjects((Object
*)rc
, md
))
323 AsmCoerceMethod(cl
, (Object
*)rc
, OM_SET
, tags
, NULL
);
328 * Oops, something screwed up.
330 AsmCoerceMethod(cl
, (Object
*)rc
, OM_DISPOSE
);
340 /// OM_SET, OM_UPDATE
342 * Change the object attributes.
344 STATIC
METHOD(MXClassSetUpdate
, struct opUpdate
*, opu
)
346 MD
*md
= INST_DATA(cl
, obj
);
347 struct GadgetInfo
*gi
= opu
->opu_GInfo
;
348 struct TagItem
*tstate
= opu
->opu_AttrList
;
349 struct TagItem
*tag
, ttag
[2];
353 set
.MethodID
= OM_SET
;
354 set
.ops_AttrList
= ttag
;
356 ttag
[1].ti_Tag
= TAG_DONE
;
359 * First let the superclass do its thing.
361 AsmDoSuperMethodA(cl
, obj
, (Msg
)opu
);
364 * Make sure that we are GACT_IMMEDIATE.
366 GADGET(obj
)->Activation
|= GACT_IMMEDIATE
;
367 GADGET(obj
)->Activation
&= ~GACT_RELVERIFY
;
372 if (FindTagItem(BT_TextAttr
, tstate
) && md
->md_TabsFont
)
374 for (i
= 0; i
<= md
->md_MaxLabel
; i
++)
375 DoSetMethodNG(md
->md_Objects
[i
], BT_TextAttr
, md
->md_TabsFont
, TAG_END
);
378 while ((tag
= NextTagItem(&tstate
)))
392 for (i
= 0; i
<= md
->md_MaxLabel
; i
++)
394 AsmDoMethodA(md
->md_Objects
[i
], (Msg
)&set
);
398 case MX_DisableButton
:
399 case MX_EnableButton
:
400 if ((data
>= 0) && (data
<= md
->md_MaxLabel
))
401 DoSetMethod(md
->md_Objects
[data
], gi
, GA_Disabled
, (tag
->ti_Tag
== MX_DisableButton
), TAG_DONE
);
408 if (data
> md
->md_MaxLabel
)
410 if (md
->md_Type
) data
= 0;
411 else data
= md
->md_MaxLabel
;
413 if (data
!= md
->md_ActiveLabel
)
416 * De-select the previous active object if
417 * it's different from the current active one.
419 DoSetMethod(md
->md_Objects
[md
->md_ActiveLabel
], gi
, GA_Selected
, FALSE
, TAG_DONE
);
420 DoSetMethod(md
->md_Objects
[data
], gi
, GA_Selected
, TRUE
, TAG_DONE
);
421 DoNotifyMethod(obj
, gi
, 0, GA_ID
, GADGET(obj
)->GadgetID
, MX_Active
, data
, TAG_DONE
);
422 md
->md_ActiveLabel
= data
;
435 STATIC
METHOD(MXClassGet
, struct opGet
*, opg
)
437 MD
*md
= INST_DATA(cl
, obj
);
440 switch (opg
->opg_AttrID
)
443 *opg
->opg_Storage
= md
->md_ActiveLabel
;
447 rc
= AsmDoSuperMethodA(cl
, obj
, (Msg
)opg
);
456 * Dispose of the object.
458 STATIC
METHOD(MXClassDispose
, Msg
, msg
)
460 MD
*md
= INST_DATA(cl
, obj
);
463 BGUI_FreePoolMem(md
->md_Objects
);
465 return AsmDoSuperMethodA(cl
, obj
, msg
);
473 STATIC
METHOD(MXClassKeyActive
, struct wmKeyInput
*, wmki
)
475 MD
*md
= INST_DATA(cl
, obj
);
476 UWORD qual
= wmki
->wmki_IEvent
->ie_Qualifier
;
477 ULONG num
= md
->md_ActiveLabel
;
478 ULONG max
= md
->md_MaxLabel
;
482 * Shifted activation?
484 dir
= (qual
& (IEQUALIFIER_LSHIFT
|IEQUALIFIER_RSHIFT
)) ? -1 : 1;
487 * Scan through the button list for the
488 * next or previous enabled button.
493 if (num
< 0) num
= max
;
494 if (num
> max
) num
= 0;
495 if (!(GADGET(md
->md_Objects
[num
])->Flags
& GFLG_DISABLED
)) break;
500 * Setup the new button.
502 if (num
!= md
->md_ActiveLabel
)
503 DoSetMethod(obj
, wmki
->wmki_GInfo
, MX_Active
, num
, TAG_END
);
508 *(wmki
->wmki_ID
) = GADGET(obj
)->GadgetID
;
514 /// Class initialization.
516 * Class function table.
518 STATIC DPFUNC ClassFunc
[] = {
519 { OM_NEW
, MXClassNew
, },
520 { OM_SET
, MXClassSetUpdate
, },
521 { OM_UPDATE
, MXClassSetUpdate
, },
522 { OM_GET
, MXClassGet
, },
523 { OM_DISPOSE
, MXClassDispose
, },
524 { WM_KEYACTIVE
, MXClassKeyActive
, },
529 * Initialize the mx class.
531 makeproto Class
*InitMxClass(void)
533 return BGUI_MakeClass(CLASS_SuperClassBGUI
, BGUI_GROUP_GADGET
,
534 CLASS_ObjectSize
, sizeof(MD
),
535 CLASS_DFTable
, ClassFunc
,