release the pen in MUIM_Hide
[AROS.git] / compiler / coolimages / buttonclass.c
blob0c47dcf39d59e391af9edba6e8cc931aed2fd45a
1 /*
2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: english
7 */
9 /****************************************************************************************/
11 #define USE_BOOPSI_STUBS
13 #include <exec/execbase.h>
14 #include <exec/memory.h>
15 #include <intuition/intuition.h>
16 #include <intuition/classes.h>
17 #include <intuition/classusr.h>
18 #include <intuition/imageclass.h>
19 #include <intuition/gadgetclass.h>
20 #include <intuition/cghooks.h>
21 #include <graphics/gfx.h>
22 #include <cybergraphx/cybergraphics.h>
23 #include <proto/exec.h>
24 #include <proto/intuition.h>
25 #include <proto/graphics.h>
26 #include <proto/cybergraphics.h>
27 #include <proto/utility.h>
28 #include <aros/asmcall.h>
29 #include <clib/boopsistubs.h>
30 #include <string.h>
32 #include "coolimages.h"
34 /****************************************************************************************/
36 struct CoolButtonData
38 struct CoolImage *image;
39 ULONG *pal;
40 Object *frame;
41 ULONG bgcol;
42 ULONG selcol;
45 /****************************************************************************************/
47 extern struct IntuitionBase *IntuitionBase;
48 extern struct GfxBase *GfxBase;
49 extern struct UtilityBase *UtilityBase;
51 struct IClass *cool_buttonclass;
53 /****************************************************************************************/
55 #define CyberGfxBase cool_cybergfxbase
56 #define G(x) ((struct Gadget *)(x))
58 #define BORDERIMAGESPACINGX 4
60 /****************************************************************************************/
62 static struct Library *cool_cybergfxbase;
64 /****************************************************************************************/
66 static void getgadgetcoords(struct Gadget *gad, struct GadgetInfo *gi,
67 WORD *x, WORD *y, WORD *w, WORD *h)
69 *x = gad->LeftEdge + ((gad->Flags & GFLG_RELRIGHT) ? gi->gi_Domain.Width - 1 : 0);
70 *y = gad->TopEdge + ((gad->Flags & GFLG_RELBOTTOM) ? gi->gi_Domain.Height - 1 : 0);
71 *w = gad->Width + ((gad->Flags & GFLG_RELWIDTH) ? gi->gi_Domain.Width : 0);
72 *h = gad->Height + ((gad->Flags & GFLG_RELHEIGHT) ? gi->gi_Domain.Height : 0);
75 /****************************************************************************************/
77 static IPTR coolbutton_new(Class * cl, Object * o, struct opSet * msg)
79 struct CoolButtonData *data;
80 struct TagItem fitags[] =
82 { IA_FrameType , FRAME_BUTTON },
83 { IA_EdgesOnly , FALSE },
84 { TAG_DONE }
87 o = (Object *)DoSuperMethodA(cl, o, (Msg)msg);
89 if (o)
91 data = INST_DATA(cl, o);
93 data->image = (struct CoolImage *)GetTagData(COOLBT_CoolImage, 0, msg->ops_AttrList);
94 data->frame = NewObjectA(NULL, FRAMEICLASS, fitags);
96 if (!data->frame)
98 CoerceMethod(cl, o, OM_DISPOSE);
99 o = NULL;
100 } else {
101 if (CyberGfxBase && data->image)
103 if ((data->pal = AllocVec(data->image->numcolors * sizeof(ULONG), MEMF_PUBLIC)))
105 ULONG *p = data->pal;
106 WORD i;
108 for(i = 0; i < data->image->numcolors; i++)
110 *p++ = (data->image->pal[i * 3] << 16) |
111 (data->image->pal[i * 3 + 1] << 8) |
112 (data->image->pal[i * 3 + 2]);
115 } else {
116 data->image = NULL;
118 } else {
119 data->image = NULL;
123 } /* if (o) */
125 return (IPTR)o;
128 /****************************************************************************************/
130 static IPTR coolbutton_dispose(Class * cl, Object * o, Msg msg)
132 struct CoolButtonData *data;
134 data = INST_DATA(cl, o);
136 if (data->frame) DisposeObject(data->frame);
137 FreeVec(data->pal);
139 return DoSuperMethodA(cl, o, msg);
142 /****************************************************************************************/
144 static IPTR coolbutton_hittest(Class *cl, Object *o, struct gpHitTest *msg)
146 WORD gadx, gady, gadw, gadh;
148 getgadgetcoords(G(o), msg->gpht_GInfo, &gadx, &gady, &gadw, &gadh);
150 return ((msg->gpht_Mouse.X >= 0) &&
151 (msg->gpht_Mouse.Y >= 0) &&
152 (msg->gpht_Mouse.X < gadw) &&
153 (msg->gpht_Mouse.Y < gadh)) ? GMR_GADGETHIT : 0;
156 /****************************************************************************************/
158 static IPTR coolbutton_render(Class *cl, Object *o, struct gpRender *msg)
160 struct CoolButtonData *data;
161 STRPTR text = (STRPTR)G(o)->GadgetText;
162 struct TagItem im_tags[] =
164 {IA_Width , 0 },
165 {IA_Height , 0 },
166 {TAG_DONE }
168 WORD x, y, w, h;
170 getgadgetcoords(G(o), msg->gpr_GInfo, &x, &y, &w, &h);
172 data = INST_DATA(cl, o);
174 im_tags[0].ti_Data = w;
175 im_tags[1].ti_Data = h;
177 SetAttrsA(data->frame, im_tags);
179 DrawImageState(msg->gpr_RPort,
180 (struct Image *)data->frame,
183 (G(o)->Flags & GFLG_SELECTED) ? IDS_SELECTED : IDS_NORMAL,
184 msg->gpr_GInfo->gi_DrInfo);
186 if (GetBitMapAttr(msg->gpr_RPort->BitMap, BMA_DEPTH) < 15)
188 data->image = NULL;
191 if (text)
193 WORD len = strlen(text);
194 WORD tx = x, ty = y;
196 SetFont(msg->gpr_RPort, msg->gpr_GInfo->gi_DrInfo->dri_Font);
198 if (data->image)
200 tx += BORDERIMAGESPACINGX + data->image->width + BORDERIMAGESPACINGX;
201 w -= (BORDERIMAGESPACINGX + data->image->width + BORDERIMAGESPACINGX + BORDERIMAGESPACINGX);
204 tx += (w - TextLength(msg->gpr_RPort, text, len)) / 2;
205 ty += (h - msg->gpr_RPort->TxHeight) / 2 + msg->gpr_RPort->TxBaseline;
207 SetABPenDrMd(msg->gpr_RPort,
208 msg->gpr_GInfo->gi_DrInfo->dri_Pens[(G(o)->Flags & GFLG_SELECTED) ? FILLTEXTPEN : TEXTPEN],
210 JAM1);
211 Move(msg->gpr_RPort, tx, ty);
212 Text(msg->gpr_RPort, text, len);
213 } else {
214 x += 3; w -= 6;
215 y += 3; h -= 6;
217 SetABPenDrMd(msg->gpr_RPort,
218 msg->gpr_GInfo->gi_DrInfo->dri_Pens[(G(o)->Flags & GFLG_SELECTED) ? FILLPEN : BACKGROUNDPEN],
220 JAM1);
222 RectFill(msg->gpr_RPort, x, y, x + w - 1, y + h - 1);
225 if (data->image)
227 if ((data->selcol == 0) && (data->bgcol == 0))
229 ULONG col[3];
231 GetRGB32(msg->gpr_GInfo->gi_Screen->ViewPort.ColorMap,
232 msg->gpr_GInfo->gi_DrInfo->dri_Pens[FILLPEN],
234 col);
236 data->selcol = ((col[0] & 0xFF000000) >> 8) +
237 ((col[1] & 0xFF000000) >> 16) +
238 ((col[2] & 0xFF000000) >> 24);
241 GetRGB32(msg->gpr_GInfo->gi_Screen->ViewPort.ColorMap,
242 msg->gpr_GInfo->gi_DrInfo->dri_Pens[BACKGROUNDPEN],
244 col);
246 data->bgcol = ((col[0] & 0xFF000000) >> 8) +
247 ((col[1] & 0xFF000000) >> 16) +
248 ((col[2] & 0xFF000000) >> 24);
253 data->pal[0] = (G(o)->Flags & GFLG_SELECTED) ? data->selcol : data->bgcol;
255 WriteLUTPixelArray((APTR)data->image->data,
258 data->image->width,
259 msg->gpr_RPort,
260 data->pal,
261 x + BORDERIMAGESPACINGX,
262 y + (h - data->image->height) / 2,
263 data->image->width,
264 data->image->height,
265 CTABFMT_XRGB8);
269 return 0;
272 /****************************************************************************************/
273 /****************************************************************************************/
274 /****************************************************************************************/
276 AROS_UFH3S(IPTR, cool_buttonclass_dispatcher,
277 AROS_UFHA(Class *, cl, A0),
278 AROS_UFHA(Object *, obj, A2),
279 AROS_UFHA(Msg, msg, A1))
281 AROS_USERFUNC_INIT
283 IPTR retval;
285 switch (msg->MethodID)
287 case OM_NEW:
288 retval = coolbutton_new(cl, obj, (struct opSet *)msg);
289 break;
291 case OM_DISPOSE:
292 retval = coolbutton_dispose(cl, obj, msg);
293 break;
295 case GM_HITTEST:
296 retval = coolbutton_hittest(cl, obj, (struct gpHitTest *)msg);
297 break;
299 case GM_RENDER:
300 retval = coolbutton_render(cl, obj, (struct gpRender *)msg);
301 break;
303 default:
304 retval = DoSuperMethodA(cl, obj, msg);
305 break;
307 } /* switch (msg->MethodID) */
309 return retval;
311 AROS_USERFUNC_EXIT
314 /****************************************************************************************/
316 #undef CyberGfxBase
318 /****************************************************************************************/
320 BOOL InitCoolButtonClass(struct Library *CyberGfxBase)
322 BOOL retval = FALSE;
324 cool_cybergfxbase = CyberGfxBase;
326 if (IntuitionBase && GfxBase && UtilityBase) // && SysBase)
328 if (!cool_buttonclass)
330 cool_buttonclass = MakeClass(NULL, BUTTONGCLASS, NULL, sizeof(struct CoolButtonData), 0UL);
333 if (cool_buttonclass)
335 cool_buttonclass->cl_Dispatcher.h_Entry = (HOOKFUNC)cool_buttonclass_dispatcher;
336 retval = TRUE;
340 return retval;
343 /****************************************************************************************/
345 void CleanupCoolButtonClass(void)
347 if (cool_buttonclass)
349 FreeClass(cool_buttonclass);
350 cool_buttonclass = NULL;
354 /****************************************************************************************/