Initial commit
[amiga/OpenBoopsi.git] / gadgets / SliderBar / FrPropGClass.c
1 /*
2 **      $Id: FrPropGClass.c,v 1.1 1999/02/07 14:24:42 bernie Exp $
3 **
4 **      Copyright (C) 1999,2000 Bernardo Innocenti
5 **      All rights reserved.
6 **
7 **      Use 4 chars wide TABs to read this file
8 **
9 **      A simple subclass of the propgclass which can be surrounded
10 **      by a boopsi frame image specified through the GA_LabelImage tag.
11 */
12
13 #define USE_BUILTIN_MATH
14 #define INTUI_V36_NAMES_ONLY
15 #define __USE_SYSBASE
16 #define  CLIB_ALIB_PROTOS_H             /* Avoid dupe defs of boopsi funcs */
17
18
19 #include <intuition/gadgetclass.h>
20 #include <intuition/imageclass.h>
21 #include <proto/intuition.h>
22
23 #ifdef __STORM__
24         #pragma header
25 #endif
26
27 #include "CompilerSpecific.h"
28 #include "DebugMacros.h"
29 #include "BoopsiStubs.h"
30
31 #include "FrPropGClass.h"
32
33
34
35
36 /* Per object instance data */
37 struct FrPropData
38 {
39         Object *        Frame;
40         struct IBox FrameBox;
41 };
42
43
44
45 /* ScrollButton Class Dispatcher entrypoint.
46  * Handle boopsi messages.
47  */
48 static ULONG HOOKCALL FrPropDispatcher (
49         REG(a0, Class * cl),
50         REG(a2, struct Gadget * g),
51         REG(a1, Msg msg))
52 {
53         struct FrPropData *fpd;
54
55         switch (msg->MethodID)
56         {
57                 case OM_NEW:
58                         DB2(DBPRINTF("FrPropGClass: OM_NEW\n");)
59
60                         if (g = (struct Gadget *)DoSuperMethodA (cl, (Object *)g, (Msg)msg))
61                         {
62                                 fpd = (struct FrPropData *) INST_DATA(cl, g);
63
64                                 /* HACK: the gadgetclass copies the contents
65                                  * of the GA_LabelImage tag into the Gadget structure.
66                                  * We steal the frame from there and then clear it,
67                                  * otherwise the gadgetclass will try to draw the frame
68                                  * itself.
69                                  */
70                                 fpd->Frame = (Object *) g->GadgetText;
71                                 g->GadgetText = NULL;
72                                 g->Flags &= ~GFLG_LABELIMAGE;
73
74                                 /* Ask Intuition to send us GM_LAYOUT messages */
75                                 g->Flags |= GFLG_RELSPECIAL;
76                         }
77                         return (ULONG)g;
78
79                 case GM_LAYOUT:
80                         DB2(DBPRINTF("FrPropGClass: GM_LAYOUT\n");)
81
82                         fpd = (struct FrPropData *) INST_DATA(cl, g);
83
84                         if (fpd->Frame)
85                         {
86                                 struct IBox gbox;
87
88                                 /* Compute current gadget size */
89                                 GetGadgetBox(((struct gpLayout *)msg)->gpl_GInfo, g, &gbox);
90
91                                 DB2(DBPRINTF("FrPropGClass:   GBox :%ld t:%ld w:%ld h:%ld\n",
92                                                 fpd->FrameBox.Left, fpd->FrameBox.Top,
93                                                 fpd->FrameBox.Width, fpd->FrameBox.Height);)
94
95                                 /* Calculate dimensions of our framing image */
96                                 DoMethod(fpd->Frame, IM_FRAMEBOX, &gbox, &fpd->FrameBox,
97                                         ((struct gpLayout *)msg)->gpl_GInfo->gi_DrInfo, 0);
98                         }
99                         break; /* go to DoSuperMethod() below */
100
101                 case GM_RENDER:
102                         if (((struct gpRender *)msg)->gpr_Redraw == GREDRAW_REDRAW)
103                         {
104                                 fpd = (struct FrPropData *) INST_DATA(cl, g);
105                                 DB2(DBPRINTF("FrPropGClass: GM_RENDER - GREDRAW_REDRAW\n");)
106                                 ASSERT_VALID_PTR(fpd)
107
108                                 if (fpd->Frame)
109                                 {
110                                         ASSERT_VALID_PTR(fpd->Frame)
111                                         DB2(DBPRINTF("FrPropGClass:   Frame l:%ld t:%ld w:%ld h:%ld\n",
112                                                 fpd->FrameBox.Left, fpd->FrameBox.Top,
113                                                 fpd->FrameBox.Width, fpd->FrameBox.Height);)
114
115                                         DoMethod(fpd->Frame, IM_DRAWFRAME,
116                                                 ((struct gpRender *)msg)->gpr_RPort,                                    /* imp_RPort            */
117                                                 (fpd->FrameBox.Left << 16) | (fpd->FrameBox.Top),               /* imp_Offset           */
118                                                 IDS_NORMAL,                                                                                             /* imp_State            */
119                                                 ((struct gpRender *)msg)->gpr_GInfo->gi_DrInfo,                 /* imp_DrInfo           */
120                                                 (fpd->FrameBox.Width << 16) | (fpd->FrameBox.Height));  /* imp_Dimensions       */
121                                 }
122                         }
123                         break; /* go to DoSuperMethod() below */
124
125                 case OM_UPDATE:
126                 {
127                         ULONG result;
128                         Class *oldclass;
129
130                         /* This is a dirty workaround for a bug in the propgclass.
131                          *
132                          * It appears that the dispatcher of the propgclass detects
133                          * when an object is made from a subclass. In this case,
134                          * it stops sending itself the GM_REDRAW message when the
135                          * PGA_#? attributes are updated. The result is that the
136                          * prop does not update its visual when the attributes are
137                          * changed.
138                          *
139                          * The workaround we use here is to temporarly switch the
140                          * object true class to propgclass before passing the
141                          * OM_UPDATE method to our superclass.
142                          */
143                         oldclass = OCLASS(g);
144                         OCLASS(g) = cl->cl_Super;
145                         result = CoerceMethodA (cl->cl_Super, (Object *)g, msg);
146                         OCLASS(g) = oldclass;
147                         return result;
148                 }
149
150                 default:
151                         break; /* go to DoSuperMethod() below */
152         }
153
154         /* Super class handles everything */
155         return (DoSuperMethodA (cl, (Object *)g, msg));
156 }
157
158
159
160 Class * MakeFrPropGClass(void)
161 {
162         Class * class;
163
164         if (class = MakeClass (NULL, PROPGCLASS, NULL, sizeof(struct FrPropData), 0))
165                 class->cl_Dispatcher.h_Entry = (ULONG (*)()) FrPropDispatcher;
166
167         return class;
168 }
169
170
171
172 BOOL FreeFrPropGClass(Class *cl)
173 {
174         return (FreeClass(cl));
175 }