Replaced System by SYS because on "native" the volume name of the system partition...
[AROS-Contrib.git] / bgui / buttonclass.c
blobdd562a4c4b6cbe7ca4ec56cfd20e6903cd59f452
1 /*
2 * @(#) $Header$
4 * BGUI library
5 * buttonclass.c
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.
13 * $Log$
14 * Revision 42.3 2004/06/16 20:16:48 verhaegs
15 * Use METHODPROTO, METHOD_END and REGFUNCPROTOn where needed.
17 * Revision 42.2 2000/05/15 19:27:00 stegerg
18 * another hundreds of REG() macro replacements in func headers/protos.
20 * Revision 42.1 2000/05/14 23:32:46 stegerg
21 * changed over 200 function headers which all use register
22 * parameters (oh boy ...), because the simple REG() macro
23 * doesn't work with AROS. And there are still hundreds
24 * of headers left to be fixed :(
26 * Many of these functions would also work with stack
27 * params, but since i have fixed every single one
28 * I encountered up to now, I guess will have to do
29 * the same for the rest.
31 * Revision 42.0 2000/05/09 22:08:32 mlemos
32 * Bumped to revision 42.0 before handing BGUI to AROS team
34 * Revision 41.11 2000/05/09 19:53:59 mlemos
35 * Merged with the branch Manuel_Lemos_fixes.
37 * Revision 41.10.2.3 1999/07/31 01:54:49 mlemos
38 * Ensured that the base object frame is restored before the object is
39 * disposed if the frame object was overwritte by the button class.
41 * Revision 41.10.2.2 1998/12/06 23:01:41 mlemos
42 * Fixed bug of select only buttons being deselected by keyboard activation.
44 * Revision 41.10.2.1 1998/11/17 16:05:36 mlemos
45 * Fixed the return value of BASE_RENDER to always reflect image changes.
47 * Revision 41.10 1998/02/25 21:11:42 mlemos
48 * Bumping to 41.10
50 * Revision 1.1 1998/02/25 17:07:43 mlemos
51 * Ian sources
56 /// Class definitions.
57 #include "include/classdefs.h"
60 * Object instance data.
62 typedef struct {
63 ULONG bd_Flags; /* See below. */
64 struct Image *bd_Image; /* Intuition image. */
65 struct Image *bd_SelImage; /* Selected intuition image. */
66 Object *bd_Vector; /* Vector image. */
67 Object *bd_SelVector; /* Selected vector image. */
68 Object *bd_StoreFrame; /* Storage for frame object. */
69 UWORD bd_ScaleWidth; /* Design width of the vector. */
70 UWORD bd_ScaleHeight; /* Design height of the vector. */
71 } BD;
73 #define BDF_NO_DESELECT (1<<0) /* Don't deselect when selected. */
74 #define BDF_ENCLOSE (1<<1) /* Enclose image in frame. */
75 #define BDF_SYSIMAGE (1<<2) /* This is a system image. */
76 #define BDF_STORED_FRAME (1<<3) /* Stored base instance frame. */
77 ///
78 /// ButtonSetAttrs
80 * Change the object's attributes.
82 METHOD(ButtonSetAttrs, struct opSet *, ops)
84 BD *bd = INST_DATA(cl, obj);
85 BC *bc = BASE_DATA(obj);
86 struct TagItem *tstate = ops->ops_AttrList, *tag;
87 ULONG data, attr;
88 BOOL vis = FALSE;
91 * Evaluate tags.
93 while (tag = NextTagItem(&tstate))
95 data = tag->ti_Data;
96 switch (attr = tag->ti_Tag)
98 case VIT_VectorArray:
99 case VIT_BuiltIn:
100 case VIT_Pen:
101 case VIT_DriPen:
102 if (bd->bd_Vector)
104 DoSetMethodNG(bd->bd_Vector, attr, data, TAG_DONE);
105 vis = TRUE;
107 break;
109 case SYSIA_Which:
110 if (bd->bd_Flags & BDF_SYSIMAGE)
112 DoSetMethodNG((Object *)bd->bd_Image, SYSIA_Which, data, TAG_DONE);
113 break;
115 bd->bd_Image = (struct Image *)BGUI_NewObject(BGUI_SYSTEM_IMAGE, SYSIA_Which, data, TAG_DONE);
116 bd->bd_StoreFrame = bc->bc_Frame;
117 bd->bd_Flags |= BDF_STORED_FRAME;
118 bc->bc_Frame = NULL;
119 bd->bd_SelImage = NULL;
120 bd->bd_Flags |= BDF_SYSIMAGE;
121 vis = TRUE;
122 break;
124 case BUTTON_Image:
125 case BUTTON_SelectedImage:
126 if (bd->bd_Flags & BDF_SYSIMAGE)
128 bc->bc_Frame = bd->bd_StoreFrame;
129 bd->bd_StoreFrame = NULL;
130 bd->bd_Flags &= ~BDF_STORED_FRAME;
131 if (bd->bd_Image) DisposeObject(bd->bd_Image);
132 bd->bd_Flags &= ~BDF_SYSIMAGE;
134 if (attr == BUTTON_Image)
136 bd->bd_Image = (struct Image *)data;
137 vis = TRUE;
139 else
141 bd->bd_SelImage = (struct Image *)data;
142 vis = TRUE;
144 break;
146 case BUTTON_Vector:
147 if (bd->bd_Vector) DisposeObject(bd->bd_Vector);
148 bd->bd_Vector = (Object *)data;
149 vis = TRUE;
150 break;
152 case BUTTON_SelectedVector:
153 if (bd->bd_SelVector) DisposeObject(bd->bd_SelVector);
154 bd->bd_SelVector = (Object *)data;
155 vis = TRUE;
156 break;
158 case BUTTON_ScaleMinWidth:
159 bd->bd_ScaleWidth = data;
160 break;
162 case BUTTON_ScaleMinHeight:
163 bd->bd_ScaleHeight = data;
164 break;
166 case BUTTON_SelectOnly:
167 if (data) bd->bd_Flags |= BDF_NO_DESELECT;
168 else bd->bd_Flags &= ~BDF_NO_DESELECT;
169 break;
171 case BUTTON_EncloseImage:
172 if (data) bd->bd_Flags |= BDF_ENCLOSE;
173 else bd->bd_Flags &= ~BDF_ENCLOSE;
174 break;
179 * Force the correct activation flags.
181 if (GADGET(obj)->Activation & GACT_TOGGLESELECT)
183 GADGET(obj)->Activation |= GACT_IMMEDIATE;
184 GADGET(obj)->Activation &= ~GACT_RELVERIFY;
186 else
188 GADGET(obj)->Activation &= ~GACT_IMMEDIATE;
189 GADGET(obj)->Activation |= GACT_RELVERIFY;
191 return vis;
193 METHOD_END
195 /// OM_NEW
197 * Create a new object.
199 METHOD(ButtonClassNew, struct opSet *, ops)
201 BD *bd;
202 struct TagItem *tags;
203 ULONG rc;
204 struct opSet opn = *ops;
206 tags = DefTagList(BGUI_BUTTON_GADGET, ops->ops_AttrList);
209 * First we let the superclass
210 * create an object.
212 if (rc = NewSuperObject(cl, obj, tags))
215 * Get the instance data.
217 bd = INST_DATA(cl, rc);
219 opn.ops_AttrList = tags;
220 ButtonSetAttrs(cl, (Object *)rc, &opn);
223 * See if we get a vector image.
225 if (!bd->bd_Image && !bd->bd_Vector)
226 bd->bd_Vector = CreateVector(tags);
228 FreeTagItems(tags);
230 return rc;
232 METHOD_END
234 /// OM_SET, OM_UPDATE
236 * Change the object's attributes.
238 METHOD(ButtonClassSetUpdate, struct opUpdate *, opu)
240 BD *bd = INST_DATA(cl, obj);
241 WORD dis = GADGET(obj)->Flags & GFLG_DISABLED;
242 WORD sel = GADGET(obj)->Flags & GFLG_SELECTED;
243 BOOL vis;
246 * First we let the superclass do it's thing.
248 AsmDoSuperMethodA(cl, obj, (Msg)opu);
251 * F*ck interim messages.
253 if (opu->MethodID == OM_UPDATE && (opu->opu_Flags & OPUF_INTERIM))
254 return 1;
256 vis = ButtonSetAttrs(cl, obj, (struct opSet *)opu);
259 * Visual change necessary?
261 if (((GADGET(obj)->Flags & GFLG_DISABLED) != dis) ||
262 ((GADGET(obj)->Flags & GFLG_SELECTED) != sel) || vis)
264 DoRenderMethod(obj, opu->opu_GInfo, GREDRAW_REDRAW);
268 * Notify target when a toggle gadget's selected state changed.
270 if (GADGET(obj)->Activation & GACT_TOGGLESELECT)
272 if ((GADGET(obj)->Flags & GFLG_SELECTED) != sel)
275 * Special MX magic...
277 if (!(sel && (bd->bd_Flags & BDF_NO_DESELECT)))
279 DoNotifyMethod(obj, opu->opu_GInfo, 0, GA_ID, GADGET(obj)->GadgetID,
280 GA_Selected, !sel, GA_UserData, GADGET(obj)->UserData, TAG_END);
285 return 1;
287 METHOD_END
289 /// BASE_RENDER
291 * Render the object.
293 METHOD(ButtonClassRender, struct bmRender *, bmr)
295 BD *bd = INST_DATA(cl, obj);
296 BC *bc = BASE_DATA(obj);
297 struct BaseInfo *bi = bmr->bmr_BInfo;
298 struct Image *image = NULL;
299 Object *vector = NULL;
300 int x, y;
301 ULONG rc;
302 ULONG state = GadgetState(bi, obj, FALSE);
305 * Render the baseclass.
307 rc=AsmDoSuperMethodA(cl, obj, (Msg)bmr);
310 * Pick up the image to render.
312 if (GADGET(obj)->Flags & GFLG_SELECTED)
314 image = bd->bd_SelImage;
315 vector = bd->bd_SelVector;
317 if (!image) image = bd->bd_Image;
318 if (!vector) vector = bd->bd_Vector;
321 * Setup and render the gadget.
323 if (image)
325 if (bd->bd_Flags & BDF_SYSIMAGE)
328 * Setup the image dimensions.
330 image->LeftEdge = bc->bc_OuterBox.Left;
331 image->TopEdge = bc->bc_OuterBox.Top;
332 image->Width = bc->bc_OuterBox.Width;
333 image->Height = bc->bc_OuterBox.Height;
335 x = y = 0;
337 else
340 * Setup the left and top edge.
342 image->LeftEdge = bc->bc_InnerBox.Left;
343 image->TopEdge = bc->bc_InnerBox.Top;
346 * Center it in the hitbox.
348 x = (bc->bc_InnerBox.Width - image->Width ) >> 1;
349 y = (bc->bc_InnerBox.Height - image->Height) >> 1;
352 * Render it.
354 BDrawImageState(bi, (Object *)image, x, y, state);
356 rc = 1;
358 else if (vector)
361 * Setup vector bounds.
363 DoSetMethodNG(vector,
364 IA_Left, bc->bc_InnerBox.Left - 1, IA_Top, bc->bc_InnerBox.Top - 1,
365 IA_Width, bc->bc_InnerBox.Width + 2, IA_Height, bc->bc_InnerBox.Height + 2,
366 TAG_END);
369 * Render it.
371 rc = AsmDoMethod(vector, BASE_RENDER, bi, state);
375 * Disabled?
377 if (GADGET(obj)->Flags & GFLG_DISABLED)
378 BDisableBox(bi, &bc->bc_HitBox);
380 return rc;
382 METHOD_END
384 /// GM_GOACTIVE
386 * We must go active.
388 //STATIC ASM ULONG ButtonClassGoActive( REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) struct gpInput *gpi )
389 STATIC ASM REGFUNC3(ULONG, ButtonClassGoActive,
390 REGPARAM(A0, Class *, cl),
391 REGPARAM(A2, Object *, obj),
392 REGPARAM(A1, struct gpInput *, gpi))
394 BD *bd = INST_DATA(cl, obj);
395 ULONG rc;
396 struct GadgetInfo *gi = gpi->gpi_GInfo;
399 * We cannot go active when
400 * we are disabled.
402 if (GADGET(obj)->Flags & GFLG_DISABLED)
403 return GMR_NOREUSE;
406 * We must be triggered by a mouse click
407 * or something simular.
409 if (gpi->gpi_IEvent)
412 * Let the superclass have a go...
414 AsmDoSuperMethodA(cl, obj, (Msg)gpi);
417 * Toggle gadget?
419 if (GADGET(obj)->Activation & GACT_TOGGLESELECT)
422 * Special MX magic...
424 if ((bd->bd_Flags & BDF_NO_DESELECT) && (GADGET( obj )->Flags & GFLG_SELECTED))
425 return GMR_NOREUSE;
428 * Toggle selected bit.
430 GADGET(obj)->Flags ^= GFLG_SELECTED;
433 * Redraw and notify.
435 DoRenderMethod(obj, gi, GREDRAW_REDRAW);
436 DoNotifyMethod(obj, gi, 0, GA_ID, GADGET(obj)->GadgetID,
437 GA_Selected, GADGET(obj)->Flags & GFLG_SELECTED,
438 GA_UserData, GADGET(obj)->UserData, TAG_DONE);
440 rc = GMR_NOREUSE | GMR_VERIFY;
442 else
445 * Normal buttons require input.
447 GADGET(obj)->Flags |= GFLG_SELECTED;
448 DoRenderMethod(obj, gpi->gpi_GInfo, GREDRAW_REDRAW);
449 rc = GMR_MEACTIVE;
451 } else
452 rc = GMR_NOREUSE;
454 return rc;
456 REGFUNC_END
459 /// GM_HANDLEINPUT
461 * Handle button gadget input.
463 //STATIC ASM ULONG ButtonClassHandleInput( REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) struct gpInput *gpi )
464 STATIC ASM REGFUNC3(ULONG, ButtonClassHandleInput,
465 REGPARAM(A0, Class *, cl),
466 REGPARAM(A2, Object *, obj),
467 REGPARAM(A1, struct gpInput *,gpi))
469 WORD sel = 0;
470 struct gpHitTest gph;
471 struct GadgetInfo *gi = gpi->gpi_GInfo;
472 ULONG rc = GMR_MEACTIVE;
475 * Mouse over the object?
477 gph.MethodID = GM_HITTEST;
478 gph.gpht_GInfo = gi;
479 gph.gpht_Mouse.X = gpi->gpi_Mouse.X;
480 gph.gpht_Mouse.Y = gpi->gpi_Mouse.Y;
482 if (AsmDoMethodA(obj, (Msg)&gph) == GMR_GADGETHIT)
483 sel = GFLG_SELECTED;
486 * Check mouse input.
488 if (gpi->gpi_IEvent->ie_Class == IECLASS_RAWMOUSE)
490 switch (gpi->gpi_IEvent->ie_Code)
492 case MIDDLEUP:
493 case MENUUP:
494 case SELECTUP:
496 * When we are selected we verify.
498 if (sel)
501 * Send final notification.
503 DoNotifyMethod(obj, gi, 0, GA_ID, GADGET(obj)->GadgetID, GA_UserData, GADGET(obj)->UserData, TAG_END);
504 rc = GMR_NOREUSE|GMR_VERIFY;
506 else
508 rc = GMR_NOREUSE;
510 sel = 0;
511 break;
513 case MIDDLEDOWN:
514 case MENUDOWN:
515 case SELECTDOWN:
517 * Another button aborts the selection.
519 DoSetMethodNG(obj, BT_ReportID, FALSE, TAG_DONE);
520 rc = GMR_NOREUSE;
521 sel = 0;
522 break;
524 } else if ( gpi->gpi_IEvent->ie_Class == IECLASS_TIMER ) {
526 * Every timer tick will result in an interim
527 * notification while the object is selected.
529 if (sel)
530 DoNotifyMethod(obj, gi, OPUF_INTERIM, GA_ID, GADGET(obj)->GadgetID, GA_UserData, GADGET(obj)->UserData, TAG_END);
534 * Visual change?
536 if ((GADGET(obj)->Flags & GFLG_SELECTED) != sel)
539 * Flip selected bit and redraw.
541 GADGET(obj)->Flags ^= GFLG_SELECTED;
542 DoRenderMethod(obj, gi, GREDRAW_REDRAW);
545 return rc;
547 REGFUNC_END
549 /// OM_GET
551 * They want to know something.
553 METHOD(ButtonClassGet, struct opGet *, opg)
555 ULONG rc = 1, *store = opg->opg_Storage;
557 switch (opg->opg_AttrID)
560 * We make GA_Selected OM_GET'able.
562 case GA_Selected:
563 STORE (GADGET(obj)->Flags & GFLG_SELECTED);
564 break;
566 default:
567 rc = AsmDoSuperMethodA(cl, obj, (Msg)opg);
568 break;
570 return rc;
572 METHOD_END
574 /// OM_DISPOSE
576 * Dispose of ourselves.
578 METHOD(ButtonClassDispose, Msg, msg)
580 BD *bd = INST_DATA(cl, obj);
581 BC *bc = BASE_DATA(obj);
583 if ((bd->bd_Flags & BDF_SYSIMAGE) && bd->bd_Image)
584 DisposeObject(bd->bd_Image);
586 if(bd->bd_Flags & BDF_STORED_FRAME)
587 bc->bc_Frame = bd->bd_StoreFrame;
589 if (bd->bd_Vector)
590 DisposeObject(bd->bd_Vector);
592 if (bd->bd_SelVector)
593 DisposeObject(bd->bd_SelVector);
595 return AsmDoSuperMethodA(cl, obj, msg);
597 METHOD_END
599 /// WM_KEYACTIVE
601 * We are activated by a key.
603 METHOD(ButtonClassKeyActive, struct wmKeyInput *, wmki)
605 ULONG rc = WMKF_MEACTIVE;
606 struct GadgetInfo *gi = wmki->wmki_GInfo;
607 BD *bd = INST_DATA(cl, obj);
609 * If we are toggle-select we do not
610 * need to go active.
612 if (GADGET(obj)->Activation & GACT_TOGGLESELECT)
615 * Toggle-select buttons do not
616 * respond to repeated keys.
618 if (!(wmki->wmki_IEvent->ie_Qualifier & IEQUALIFIER_REPEAT)
619 && (!(bd->bd_Flags & BDF_NO_DESELECT))
620 || !(GADGET(obj)->Flags & GFLG_SELECTED))
623 * Flip selected bit.
625 GADGET(obj)->Flags ^= GFLG_SELECTED;
628 * Re-render.
630 DoRenderMethod(obj, gi, GREDRAW_REDRAW );
633 * Notify our state change.
635 DoNotifyMethod(obj, gi, 0, GA_ID, GADGET( obj )->GadgetID, GA_Selected, GADGET( obj )->Flags & GFLG_SELECTED ? TRUE : FALSE, GA_UserData, GADGET( obj )->UserData, TAG_END );
638 * Setup our ID.
640 *(wmki->wmki_ID) = GADGET(obj)->GadgetID;
642 rc = WMKF_VERIFY;
644 else
645 rc = WMKF_CANCEL;
647 else
650 * Flip to selected.
652 GADGET(obj)->Flags |= GFLG_SELECTED;
655 * Re-render.
657 DoRenderMethod(obj, gi, GREDRAW_REDRAW);
659 return rc;
661 METHOD_END
663 /// WM_KEYINPUT
665 * Handle key input messages.
667 METHOD(ButtonClassKeyInput, struct wmKeyInput *, wmki)
669 ULONG rc = WMKF_MEACTIVE;
670 UWORD qual = wmki->wmki_IEvent->ie_Qualifier;
671 UWORD code = wmki->wmki_IEvent->ie_Code, key;
672 struct GadgetInfo *gi = wmki->wmki_GInfo;
675 * Repeat mode?
677 if (!(qual & IEQUALIFIER_REPEAT))
680 * A key released?
682 if (code & IECODE_UP_PREFIX)
685 * Check which key is released.
687 key = MapKey(code & ~IECODE_UP_PREFIX, qual, &wmki->wmki_IEvent->ie_EventAddress);
690 * Is it the one that activated us?
692 if (*wmki->wmki_Key == key || *wmki->wmki_Key == tolower(key))
695 * Notify our target.
697 DoNotifyMethod(obj, gi, 0, GA_ID, GADGET(obj)->GadgetID, GA_UserData, GADGET(obj)->UserData, TAG_END );
700 * Setup our ID.
702 *(wmki->wmki_ID) = GADGET(obj)->GadgetID;
703 rc = WMKF_VERIFY;
706 else if ((qual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) || wmki->wmki_IEvent->ie_Code == 0x45)
709 * We have been cancelled by either a SHIFT key
710 * or the ESC key.
712 rc = WMKF_CANCEL;
715 else
717 * Repeated key messages will trigger
718 * an interim notification.
720 DoNotifyMethod( obj, gi, OPUF_INTERIM, GA_ID, GADGET(obj)->GadgetID, GA_Selected, GADGET(obj)->Flags & GFLG_SELECTED ? TRUE : FALSE, GA_UserData, GADGET( obj )->UserData, TAG_END );
722 return rc;
724 METHOD_END
726 /// WM_KEYINACTIVE
728 * We are forced to de-activate.
730 METHOD(ButtonClassKeyInActive, struct wmKeyInActive *, wmkia)
733 * Change visuals to un-selected when
734 * necessary.
736 if (!(GADGET(obj)->Activation & GACT_TOGGLESELECT))
738 if (GADGET(obj)->Flags & GFLG_SELECTED)
740 GADGET(obj)->Flags &= ~GFLG_SELECTED;
741 DoRenderMethod( obj, wmkia->wmkia_GInfo, GREDRAW_REDRAW );
745 return 0;
747 METHOD_END
749 /// BASE_DIMENSIONS
751 * They want our minimum dimensions.
753 METHOD(ButtonClassDimensions, struct bmDimensions *, bmd)
755 BD *bd = INST_DATA(cl, obj);
756 struct BaseInfo *bi = bmd->bmd_BInfo;
757 Object *temp;
758 int rx, ry;
759 UWORD mx = 1, my = 1;
760 ULONG tmp;
762 if (bd->bd_Image || bd->bd_SelImage)
765 * Get minimum sizes of the available images.
767 if (bd->bd_Image)
769 if (mx < bd->bd_Image->Width) mx = bd->bd_Image->Width;
770 if (my < bd->bd_Image->Height) my = bd->bd_Image->Height;
774 * Did we get a selected image?
776 if (bd->bd_SelImage)
778 if (mx < bd->bd_SelImage->Width) mx = bd->bd_SelImage->Width;
779 if (my < bd->bd_SelImage->Height) my = bd->bd_SelImage->Height;
782 if (!(bd->bd_Flags & BDF_ENCLOSE))
784 mx += 4;
785 my += 2;
788 if (bd->bd_Flags & BDF_SYSIMAGE)
790 mx = my = 8;
792 Get_Attr((Object *)bd->bd_Image, SYSIA_Which, &tmp);
794 temp = NewObject(NULL, "sysiclass", SYSIA_Which, tmp, SYSIA_DrawInfo, bi->bi_DrInfo,
795 SYSIA_Size, (bi->bi_IScreen->Flags & SCREENHIRES) ? SYSISIZE_MEDRES : SYSISIZE_LOWRES, TAG_DONE);
797 if (temp)
799 if (mx < IMAGE(temp)->Width) mx = IMAGE(temp)->Width;
800 if (my < IMAGE(temp)->Height) my = IMAGE(temp)->Height;
802 DisposeObject(temp);
806 else if (bd->bd_Vector || bd->bd_SelVector)
809 * Scaled button?
811 if (bd->bd_ScaleWidth && bd->bd_ScaleHeight)
813 if (bi->bi_DrInfo)
815 rx = bi->bi_DrInfo->dri_Resolution.X;
816 ry = bi->bi_DrInfo->dri_Resolution.Y;
818 else
820 rx = ry = 22;
823 my = bi->bi_RPort->TxHeight;
824 mx = (my * ry * bd->bd_ScaleWidth) / (rx * bd->bd_ScaleHeight);
826 else
829 * Get minimum vector sizes.
831 if (bd->bd_Vector)
833 Get_Attr(bd->bd_Vector, VIT_MinWidth, &tmp);
834 if (mx < tmp) mx = tmp;
835 Get_Attr(bd->bd_Vector, VIT_MinHeight, &tmp);
836 if (my < tmp) my = tmp;
839 if (bd->bd_SelVector)
841 Get_Attr(bd->bd_SelVector, VIT_MinWidth, &tmp);
842 if (mx < tmp) mx = tmp;
843 Get_Attr(bd->bd_SelVector, VIT_MinHeight, &tmp);
844 if (my < tmp) my = tmp;
846 mx -= 2;
847 my -= 2;
850 else
853 * Normal button. When BUTTON_EncloseImage is
854 * specified we make the label enclosed in the frame.
856 mx = (bd->bd_Flags & BDF_ENCLOSE) ? 0 : 4;
857 my = (bd->bd_Flags & BDF_ENCLOSE) ? 0 : 2;
861 * Compute dimensions and add our values.
863 return CalcDimensions(cl, obj, bmd, mx, my);
865 METHOD_END
867 /// BASE_FINDKEY
868 METHOD(ButtonClassFindKey, struct bmFindKey *, bmfk)
870 if (bmfk->bmfk_Key.Qual & IEQUALIFIER_REPEAT)
871 return 0;
872 else
873 return AsmDoSuperMethodA(cl, obj, (Msg)bmfk);
875 METHOD_END
877 /// Class initialization.
879 * Class function table.
881 STATIC DPFUNC ClassFunc[] = {
882 BASE_RENDER, (FUNCPTR)ButtonClassRender,
883 GM_GOACTIVE, (FUNCPTR)ButtonClassGoActive,
884 GM_HANDLEINPUT, (FUNCPTR)ButtonClassHandleInput,
886 OM_SET, (FUNCPTR)ButtonClassSetUpdate,
887 OM_UPDATE, (FUNCPTR)ButtonClassSetUpdate,
888 OM_GET, (FUNCPTR)ButtonClassGet,
889 OM_NEW, (FUNCPTR)ButtonClassNew,
890 OM_DISPOSE, (FUNCPTR)ButtonClassDispose,
892 WM_KEYACTIVE, (FUNCPTR)ButtonClassKeyActive,
893 WM_KEYINPUT, (FUNCPTR)ButtonClassKeyInput,
894 WM_KEYINACTIVE, (FUNCPTR)ButtonClassKeyInActive,
896 BASE_DIMENSIONS, (FUNCPTR)ButtonClassDimensions,
897 BASE_FINDKEY, (FUNCPTR)ButtonClassFindKey,
898 DF_END, NULL,
902 * Simple class initialization.
904 makeproto Class *InitButtonClass(void)
906 return BGUI_MakeClass(CLASS_SuperClassBGUI, BGUI_BASE_GADGET,
907 CLASS_ObjectSize, sizeof(BD),
908 CLASS_DFTable, ClassFunc,
909 TAG_DONE);