2 Copyright © 1995-2005, The AROS Development Team. All rights reserved.
9 #include <proto/exec.h>
10 #include <proto/dos.h>
11 #include <proto/utility.h>
12 #include <proto/intuition.h>
13 #include <proto/graphics.h>
14 #include <proto/cybergraphics.h>
15 #include <exec/memory.h>
16 #include <intuition/screens.h>
17 #include <intuition/icclass.h>
18 #include <intuition/cghooks.h>
19 #include <intuition/imageclass.h>
20 #include <intuition/gadgetclass.h>
21 #include <graphics/gfx.h>
22 #include <cybergraphx/cybergraphics.h>
26 #include "asl_intern.h"
29 #if USE_SHARED_COOLIMAGES
30 #include <libraries/coolimages.h>
32 #include "coolimages.h"
38 #include <aros/debug.h>
40 #define CLASS_ASLBASE ((struct AslBase_intern *)cl->cl_UserData)
41 #define HOOK_ASLBASE ((struct AslBase_intern *)hook->h_Data)
43 #define AslBase CLASS_ASLBASE
45 /********************** ASL BUTTON CLASS **************************************************/
47 IPTR
AslButton__OM_NEW(Class
* cl
, Object
* o
, struct opSet
* msg
)
49 struct AslButtonData
*data
;
50 struct TagItem fitags
[] =
52 {IA_FrameType
, FRAME_BUTTON
},
53 {IA_EdgesOnly
, TRUE
},
57 struct Gadget
*g
= (struct Gadget
*)DoSuperMethodA(cl
, o
, (Msg
)msg
);
61 data
= INST_DATA(cl
, g
);
63 /* {GA_Image, whatever} means, a frame shall be created */
65 if (FindTagItem(GA_Image
, msg
->ops_AttrList
))
67 if (g
->GadgetText
) fitags
[1].ti_Tag
= TAG_IGNORE
;
68 data
->frame
= NewObjectA(NULL
, FRAMEICLASS
, fitags
);
71 data
->coolimage
= (struct CoolImage
*)GetTagData(ASLBT_CoolImage
, 0, msg
->ops_AttrList
);
73 data
->ld
= (struct LayoutData
*)GetTagData(GA_UserData
, 0, msg
->ops_AttrList
);
77 CoerceMethod(cl
, (Object
*)g
, OM_DISPOSE
);
80 if (data
->coolimage
&& data
->ld
->ld_TrueColor
&& CyberGfxBase
)
82 #if SHARED_COOLIMAGES_LIBRARY
83 WORD numcols
= data
->coolimage
->numcolors
;
85 WORD numcols
= 1 << data
->coolimage
->depth
;
88 if ((data
->coolimagepal
= AllocVec(numcols
* sizeof(ULONG
), MEMF_PUBLIC
)))
90 ULONG
*p
= data
->coolimagepal
;
93 for(i
= 0; i
< numcols
; i
++)
95 *p
++ = (data
->coolimage
->pal
[i
* 3] << 16) |
96 (data
->coolimage
->pal
[i
* 3 + 1] << 8) |
97 (data
->coolimage
->pal
[i
* 3 + 2]);
101 data
->coolimage
= NULL
;
104 data
->coolimage
= NULL
;
113 /***********************************************************************************/
115 IPTR
AslButton__OM_DISPOSE(Class
* cl
, Object
* o
, Msg msg
)
117 struct AslButtonData
*data
;
120 data
= INST_DATA(cl
, o
);
121 if (data
->frame
) DisposeObject(data
->frame
);
122 if (data
->coolimagepal
) FreeVec(data
->coolimagepal
);
124 retval
= DoSuperMethodA(cl
, o
, msg
);
129 /***********************************************************************************/
131 IPTR
AslButton__GM_HITTEST(Class
*cl
, struct Gadget
*g
, struct gpHitTest
*msg
)
133 WORD gadx
, gady
, gadw
, gadh
;
135 getgadgetcoords(g
, msg
->gpht_GInfo
, &gadx
, &gady
, &gadw
, &gadh
);
137 return ((msg
->gpht_Mouse
.X
>= 0) &&
138 (msg
->gpht_Mouse
.Y
>= 0) &&
139 (msg
->gpht_Mouse
.X
< gadw
) &&
140 (msg
->gpht_Mouse
.Y
< gadh
)) ? GMR_GADGETHIT
: 0;
143 /***********************************************************************************/
145 #if BUTTON_OWN_INPUT_HANDLING
147 /***********************************************************************************/
149 IPTR
AslButton__GM_GOACTIVE(Class
*cl
, struct Gadget
*g
, struct gpInput
*msg
)
151 struct GadgetInfo
*gi
= msg
->gpi_GInfo
;
152 IPTR retval
= GMR_NOREUSE
;
156 struct RastPort
*rp
= ObtainGIRPort(gi
);
160 g
->Flags
|= GFLG_SELECTED
;
162 DoMethod((Object
*)g
, GM_RENDER
, (IPTR
) gi
, (IPTR
) rp
, GREDRAW_REDRAW
);
165 retval
= GMR_MEACTIVE
;
172 /***********************************************************************************/
174 IPTR
AslButton__GM_HANDLEINPUT(Class
*cl
, struct Gadget
*g
, struct gpInput
*msg
)
176 struct GadgetInfo
*gi
= msg
->gpi_GInfo
;
177 IPTR retval
= GMR_MEACTIVE
;
181 struct InputEvent
*ie
= ((struct gpInput
*)msg
)->gpi_IEvent
;
185 case IECLASS_RAWMOUSE
:
186 switch( ie
->ie_Code
)
189 if( g
->Flags
& GFLG_SELECTED
)
193 /* mouse is over gadget */
194 g
->Flags
&= ~GFLG_SELECTED
;
196 if ((rp
= ObtainGIRPort(gi
)))
198 DoMethod((Object
*)g
, GM_RENDER
, (IPTR
) gi
, (IPTR
) rp
, GREDRAW_UPDATE
);
201 retval
= GMR_NOREUSE
| GMR_VERIFY
;
202 *msg
->gpi_Termination
= IDCMP_GADGETUP
;
206 retval
= GMR_NOREUSE
;
210 case IECODE_NOBUTTON
:
212 struct gpHitTest gpht
;
214 gpht
.MethodID
= GM_HITTEST
;
215 gpht
.gpht_GInfo
= gi
;
216 gpht
.gpht_Mouse
.X
= ((struct gpInput
*)msg
)->gpi_Mouse
.X
;
217 gpht
.gpht_Mouse
.Y
= ((struct gpInput
*)msg
)->gpi_Mouse
.Y
;
220 This case handles selection state toggling when the
221 left button is depressed and the mouse is moved
222 around on/off the gadget bounds.
224 if ( DoMethodA((Object
*)g
, (Msg
)&gpht
) == GMR_GADGETHIT
)
226 if ( (g
->Flags
& GFLG_SELECTED
) == 0 )
230 /* mouse is over gadget */
231 g
->Flags
|= GFLG_SELECTED
;
233 if ((rp
= ObtainGIRPort(gi
)))
235 DoMethod((Object
*)g
, GM_RENDER
, (IPTR
) gi
, (IPTR
) rp
, GREDRAW_UPDATE
);
242 if ( (g
->Flags
& GFLG_SELECTED
) != 0 )
246 /* mouse is not over gadget */
247 g
->Flags
&= ~GFLG_SELECTED
;
249 if ((rp
= ObtainGIRPort(gi
)))
251 DoMethod((Object
*)g
, GM_RENDER
, (IPTR
) gi
, (IPTR
) rp
, GREDRAW_UPDATE
);
261 *((struct gpInput
*)msg
)->gpi_Termination
= 0UL;
264 } /* switch(ie->ie_Code) */
267 } /* switch(ie->ie_Class) */
272 retval
= GMR_NOREUSE
;
278 /***********************************************************************************/
280 IPTR
AslButton__GM_GOINACTIVE(Class
*cl
, struct Gadget
*g
, struct gpGoInactive
*msg
)
282 struct GadgetInfo
*gi
= msg
->gpgi_GInfo
;
284 g
->Flags
&= ~GFLG_SELECTED
;
288 struct RastPort
*rp
= ObtainGIRPort(gi
);
292 DoMethod((Object
*)g
, GM_RENDER
, (IPTR
) gi
, (IPTR
) rp
, GREDRAW_REDRAW
);
300 /***********************************************************************************/
302 #else /* BUTTON_OWN_INPUT_HANDLING */
304 IPTR
AslButton__GM_GOACTIVE(Class
*cl
, Object
*o
, Msg msg
)
306 return DoSuperMethodA(cl
, o
, msg
);
308 IPTR
AslButton__GM_HANDLEINPUT(Class
*cl
, Object
*o
, Msg msg
)
310 return DoSuperMethodA(cl
, o
, msg
);
312 IPTR
AslButton__GM_GOINACTIVE(Class
*cl
, Object
*o
, Msg msg
)
314 return DoSuperMethodA(cl
, o
, msg
);
317 #endif /* BUTTON_OWN_INPUT_HANDLING */
319 /***********************************************************************************/
321 IPTR
AslButton__GM_RENDER(Class
*cl
, struct Gadget
*g
, struct gpRender
*msg
)
323 struct AslButtonData
*data
;
324 char *text
= (STRPTR
)g
->GadgetText
;
325 struct TagItem im_tags
[] =
333 getgadgetcoords(g
, msg
->gpr_GInfo
, &x
, &y
, &w
, &h
);
335 data
= INST_DATA(cl
, g
);
339 im_tags
[0].ti_Data
= w
;
340 im_tags
[1].ti_Data
= h
;
342 SetAttrsA(data
->frame
, im_tags
);
344 DrawImageState(msg
->gpr_RPort
,
345 (struct Image
*)data
->frame
,
348 (!text
|| (g
->Flags
& GFLG_SELECTED
)) ? IDS_SELECTED
: IDS_NORMAL
,
349 msg
->gpr_GInfo
->gi_DrInfo
);
354 WORD len
= strlen(text
);
357 SetFont(msg
->gpr_RPort
, data
->ld
->ld_Font
);
361 tx
+= BORDERIMAGESPACINGX
+ data
->coolimage
->width
+ BORDERIMAGESPACINGX
;
362 w
-= (BORDERIMAGESPACINGX
+ data
->coolimage
->width
+ BORDERIMAGESPACINGX
+ BORDERIMAGESPACINGX
);
365 tx
+= (w
- TextLength(msg
->gpr_RPort
, text
, len
)) / 2;
366 ty
+= (h
- msg
->gpr_RPort
->TxHeight
) / 2 + msg
->gpr_RPort
->TxBaseline
;
370 SetABPenDrMd(msg
->gpr_RPort
,
371 data
->ld
->ld_Dri
->dri_Pens
[(g
->Flags
& GFLG_SELECTED
) ? FILLTEXTPEN
: TEXTPEN
],
378 struct TextExtent te
;
379 struct IBox obox
, ibox
;
381 getgadgetcoords(g
, msg
->gpr_GInfo
, &obox
.Left
, &obox
.Top
, &obox
.Width
, &obox
.Height
);
383 TextExtent(msg
->gpr_RPort
, text
, len
, &te
);
385 ibox
.Width
= te
.te_Extent
.MaxX
- te
.te_Extent
.MinX
+ 1;
386 ibox
.Height
= te
.te_Extent
.MaxY
- te
.te_Extent
.MinY
+ 1;
387 ibox
.Left
= te
.te_Extent
.MinX
+ tx
;
388 ibox
.Top
= te
.te_Extent
.MinY
+ ty
;
390 PaintBoxFrame(msg
->gpr_RPort
,
393 data
->ld
->ld_Dri
->dri_Pens
[BACKGROUNDPEN
],
397 SetABPenDrMd(msg
->gpr_RPort
,
398 data
->ld
->ld_Dri
->dri_Pens
[(g
->Flags
& GFLG_SELECTED
) ? FILLTEXTPEN
: TEXTPEN
],
399 data
->ld
->ld_Dri
->dri_Pens
[BACKGROUNDPEN
],
404 Move(msg
->gpr_RPort
, tx
, ty
);
405 Text(msg
->gpr_RPort
, text
, len
);
415 struct IBox ibox
, fbox
;
417 getgadgetcoords(g
, msg
->gpr_GInfo
, &fbox
.Left
, &fbox
.Top
, &fbox
.Width
, &fbox
.Height
);
424 PaintInnerFrame(msg
->gpr_RPort
,
429 data
->ld
->ld_Dri
->dri_Pens
[BACKGROUNDPEN
],
435 SetABPenDrMd(msg
->gpr_RPort
,
436 data
->ld
->ld_Dri
->dri_Pens
[(g
->Flags
& GFLG_SELECTED
) ? FILLPEN
: BACKGROUNDPEN
],
440 RectFill(msg
->gpr_RPort
, x
, y
, x
+ w
- 1, y
+ h
- 1);
445 struct ColorMap
*cm
= msg
->gpr_GInfo
->gi_Screen
->ViewPort
.ColorMap
;
448 GetRGB32(cm
, data
->ld
->ld_Dri
->dri_Pens
[(g
->Flags
& GFLG_SELECTED
) ? FILLPEN
: BACKGROUNDPEN
], 1, bg
);
449 data
->coolimagepal
[0] = ((bg
[0] & 0xFF000000) >> 8) + ((bg
[1] & 0xFF000000) >> 16) + ((bg
[2] & 0xFF000000) >> 24);
451 WriteLUTPixelArray((APTR
)data
->coolimage
->data
,
454 data
->coolimage
->width
,
457 x
+ BORDERIMAGESPACINGX
,
458 y
+ (h
- data
->coolimage
->height
) / 2,
459 data
->coolimage
->width
,
460 data
->coolimage
->height
,
468 /***********************************************************************************/
470 IPTR
AslButton__GM_LAYOUT(Class
* cl
, struct Gadget
* g
, struct gpLayout
* msg
)
472 struct AslButtonData
*data
;
478 data
= INST_DATA(cl
, g
);
480 retval
= DoSuperMethodA(cl
, (Object
*)g
, (Msg
)msg
);
484 case ID_MAINBUTTON_OK
:
485 case ID_MAINBUTTON_MIDDLELEFT
:
486 case ID_MAINBUTTON_MIDDLERIGHT
:
487 case ID_MAINBUTTON_CANCEL
:
489 /* multiply width 16 for sub-pixel accuracy */
491 x
= (data
->ld
->ld_WBorLeft
+ OUTERSPACINGX
) * 16 + 8;
493 innerwidth
= msg
->gpl_GInfo
->gi_Window
->Width
-
494 msg
->gpl_GInfo
->gi_Window
->BorderLeft
-
495 msg
->gpl_GInfo
->gi_Window
->BorderRight
-
498 /* multiply width 16 for sub-pixel accuracy */
500 spacing
= (innerwidth
- data
->ld
->ld_ButWidth
* data
->ld
->ld_NumButtons
) * 16 /
501 (data
->ld
->ld_NumButtons
- 1);
503 x
+= (g
->GadgetID
- ID_MAINBUTTON_OK
) * (data
->ld
->ld_ButWidth
* 16 + spacing
);
504 g
->LeftEdge
= x
/ 16;
511 /***********************************************************************************/