2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
9 #include <proto/alib.h>
10 #include <proto/exec.h>
11 #include <proto/dos.h>
12 #include <proto/utility.h>
13 #include <proto/intuition.h>
14 #include <proto/graphics.h>
15 #include <proto/cybergraphics.h>
16 #include <exec/memory.h>
17 #include <intuition/screens.h>
18 #include <intuition/icclass.h>
19 #include <intuition/cghooks.h>
20 #include <intuition/imageclass.h>
21 #include <intuition/gadgetclass.h>
22 #include <graphics/gfx.h>
23 #include <cybergraphx/cybergraphics.h>
27 #include "asl_intern.h"
30 #if USE_SHARED_COOLIMAGES
31 #include <libraries/coolimages.h>
33 #include "coolimages.h"
39 #include <aros/debug.h>
41 #define CLASS_ASLBASE ((struct AslBase_intern *)cl->cl_UserData)
42 #define HOOK_ASLBASE ((struct AslBase_intern *)hook->h_Data)
44 #define AslBase CLASS_ASLBASE
46 /********************** ASL BUTTON CLASS **************************************************/
48 IPTR
AslButton__OM_NEW(Class
* cl
, Object
* o
, struct opSet
* msg
)
50 struct AslButtonData
*data
;
51 struct TagItem fitags
[] =
53 {IA_FrameType
, FRAME_BUTTON
},
54 {IA_EdgesOnly
, TRUE
},
58 struct Gadget
*g
= (struct Gadget
*)DoSuperMethodA(cl
, o
, (Msg
)msg
);
62 data
= INST_DATA(cl
, g
);
64 /* {GA_Image, whatever} means, a frame shall be created */
66 if (FindTagItem(GA_Image
, msg
->ops_AttrList
))
68 if (g
->GadgetText
) fitags
[1].ti_Tag
= TAG_IGNORE
;
69 data
->frame
= NewObjectA(NULL
, FRAMEICLASS
, fitags
);
72 data
->coolimage
= (struct CoolImage
*)GetTagData(ASLBT_CoolImage
, 0, msg
->ops_AttrList
);
74 data
->ld
= (struct LayoutData
*)GetTagData(GA_UserData
, 0, msg
->ops_AttrList
);
78 CoerceMethod(cl
, (Object
*)g
, OM_DISPOSE
);
81 if (data
->coolimage
&& data
->ld
->ld_TrueColor
&& CyberGfxBase
)
83 #if SHARED_COOLIMAGES_LIBRARY
84 WORD numcols
= data
->coolimage
->numcolors
;
86 WORD numcols
= 1 << data
->coolimage
->depth
;
89 if ((data
->coolimagepal
= AllocVec(numcols
* sizeof(ULONG
), MEMF_PUBLIC
)))
91 ULONG
*p
= data
->coolimagepal
;
94 for(i
= 0; i
< numcols
; i
++)
96 *p
++ = (data
->coolimage
->pal
[i
* 3] << 16) |
97 (data
->coolimage
->pal
[i
* 3 + 1] << 8) |
98 (data
->coolimage
->pal
[i
* 3 + 2]);
102 data
->coolimage
= NULL
;
105 data
->coolimage
= NULL
;
114 /***********************************************************************************/
116 IPTR
AslButton__OM_DISPOSE(Class
* cl
, Object
* o
, Msg msg
)
118 struct AslButtonData
*data
;
121 data
= INST_DATA(cl
, o
);
122 if (data
->frame
) DisposeObject(data
->frame
);
123 if (data
->coolimagepal
) FreeVec(data
->coolimagepal
);
125 retval
= DoSuperMethodA(cl
, o
, msg
);
130 /***********************************************************************************/
132 IPTR
AslButton__GM_HITTEST(Class
*cl
, struct Gadget
*g
, struct gpHitTest
*msg
)
134 WORD gadx
, gady
, gadw
, gadh
;
136 getgadgetcoords(g
, msg
->gpht_GInfo
, &gadx
, &gady
, &gadw
, &gadh
);
138 return ((msg
->gpht_Mouse
.X
>= 0) &&
139 (msg
->gpht_Mouse
.Y
>= 0) &&
140 (msg
->gpht_Mouse
.X
< gadw
) &&
141 (msg
->gpht_Mouse
.Y
< gadh
)) ? GMR_GADGETHIT
: 0;
144 /***********************************************************************************/
146 #if BUTTON_OWN_INPUT_HANDLING
148 /***********************************************************************************/
150 IPTR
AslButton__GM_GOACTIVE(Class
*cl
, struct Gadget
*g
, struct gpInput
*msg
)
152 struct GadgetInfo
*gi
= msg
->gpi_GInfo
;
153 IPTR retval
= GMR_NOREUSE
;
157 struct RastPort
*rp
= ObtainGIRPort(gi
);
161 g
->Flags
|= GFLG_SELECTED
;
163 DoMethod((Object
*)g
, GM_RENDER
, (IPTR
) gi
, (IPTR
) rp
, GREDRAW_REDRAW
);
166 retval
= GMR_MEACTIVE
;
173 /***********************************************************************************/
175 IPTR
AslButton__GM_HANDLEINPUT(Class
*cl
, struct Gadget
*g
, struct gpInput
*msg
)
177 struct GadgetInfo
*gi
= msg
->gpi_GInfo
;
178 IPTR retval
= GMR_MEACTIVE
;
182 struct InputEvent
*ie
= ((struct gpInput
*)msg
)->gpi_IEvent
;
186 case IECLASS_RAWMOUSE
:
187 switch( ie
->ie_Code
)
190 if( g
->Flags
& GFLG_SELECTED
)
194 /* mouse is over gadget */
195 g
->Flags
&= ~GFLG_SELECTED
;
197 if ((rp
= ObtainGIRPort(gi
)))
199 DoMethod((Object
*)g
, GM_RENDER
, (IPTR
) gi
, (IPTR
) rp
, GREDRAW_UPDATE
);
202 retval
= GMR_NOREUSE
| GMR_VERIFY
;
203 *msg
->gpi_Termination
= IDCMP_GADGETUP
;
207 retval
= GMR_NOREUSE
;
211 case IECODE_NOBUTTON
:
213 struct gpHitTest gpht
;
215 gpht
.MethodID
= GM_HITTEST
;
216 gpht
.gpht_GInfo
= gi
;
217 gpht
.gpht_Mouse
.X
= ((struct gpInput
*)msg
)->gpi_Mouse
.X
;
218 gpht
.gpht_Mouse
.Y
= ((struct gpInput
*)msg
)->gpi_Mouse
.Y
;
221 This case handles selection state toggling when the
222 left button is depressed and the mouse is moved
223 around on/off the gadget bounds.
225 if ( DoMethodA((Object
*)g
, (Msg
)&gpht
) == GMR_GADGETHIT
)
227 if ( (g
->Flags
& GFLG_SELECTED
) == 0 )
231 /* mouse is over gadget */
232 g
->Flags
|= GFLG_SELECTED
;
234 if ((rp
= ObtainGIRPort(gi
)))
236 DoMethod((Object
*)g
, GM_RENDER
, (IPTR
) gi
, (IPTR
) rp
, GREDRAW_UPDATE
);
243 if ( (g
->Flags
& GFLG_SELECTED
) != 0 )
247 /* mouse is not over gadget */
248 g
->Flags
&= ~GFLG_SELECTED
;
250 if ((rp
= ObtainGIRPort(gi
)))
252 DoMethod((Object
*)g
, GM_RENDER
, (IPTR
) gi
, (IPTR
) rp
, GREDRAW_UPDATE
);
262 *((struct gpInput
*)msg
)->gpi_Termination
= 0UL;
265 } /* switch(ie->ie_Code) */
268 } /* switch(ie->ie_Class) */
273 retval
= GMR_NOREUSE
;
279 /***********************************************************************************/
281 IPTR
AslButton__GM_GOINACTIVE(Class
*cl
, struct Gadget
*g
, struct gpGoInactive
*msg
)
283 struct GadgetInfo
*gi
= msg
->gpgi_GInfo
;
285 g
->Flags
&= ~GFLG_SELECTED
;
289 struct RastPort
*rp
= ObtainGIRPort(gi
);
293 DoMethod((Object
*)g
, GM_RENDER
, (IPTR
) gi
, (IPTR
) rp
, GREDRAW_REDRAW
);
301 /***********************************************************************************/
303 #else /* BUTTON_OWN_INPUT_HANDLING */
305 IPTR
AslButton__GM_GOACTIVE(Class
*cl
, Object
*o
, Msg msg
)
307 return DoSuperMethodA(cl
, o
, msg
);
309 IPTR
AslButton__GM_HANDLEINPUT(Class
*cl
, Object
*o
, Msg msg
)
311 return DoSuperMethodA(cl
, o
, msg
);
313 IPTR
AslButton__GM_GOINACTIVE(Class
*cl
, Object
*o
, Msg msg
)
315 return DoSuperMethodA(cl
, o
, msg
);
318 #endif /* BUTTON_OWN_INPUT_HANDLING */
320 /***********************************************************************************/
322 IPTR
AslButton__GM_RENDER(Class
*cl
, struct Gadget
*g
, struct gpRender
*msg
)
324 struct AslButtonData
*data
;
325 char *text
= (STRPTR
)g
->GadgetText
;
326 struct TagItem im_tags
[] =
334 getgadgetcoords(g
, msg
->gpr_GInfo
, &x
, &y
, &w
, &h
);
336 data
= INST_DATA(cl
, g
);
340 im_tags
[0].ti_Data
= w
;
341 im_tags
[1].ti_Data
= h
;
343 SetAttrsA(data
->frame
, im_tags
);
345 DrawImageState(msg
->gpr_RPort
,
346 (struct Image
*)data
->frame
,
349 (!text
|| (g
->Flags
& GFLG_SELECTED
)) ? IDS_SELECTED
: IDS_NORMAL
,
350 msg
->gpr_GInfo
->gi_DrInfo
);
355 WORD len
= strlen(text
);
358 SetFont(msg
->gpr_RPort
, data
->ld
->ld_Font
);
362 tx
+= BORDERIMAGESPACINGX
+ data
->coolimage
->width
+ BORDERIMAGESPACINGX
;
363 w
-= (BORDERIMAGESPACINGX
+ data
->coolimage
->width
+ BORDERIMAGESPACINGX
+ BORDERIMAGESPACINGX
);
366 tx
+= (w
- TextLength(msg
->gpr_RPort
, text
, len
)) / 2;
367 ty
+= (h
- msg
->gpr_RPort
->TxHeight
) / 2 + msg
->gpr_RPort
->TxBaseline
;
371 SetABPenDrMd(msg
->gpr_RPort
,
372 data
->ld
->ld_Dri
->dri_Pens
[(g
->Flags
& GFLG_SELECTED
) ? FILLTEXTPEN
: TEXTPEN
],
379 struct TextExtent te
;
380 struct IBox obox
, ibox
;
382 getgadgetcoords(g
, msg
->gpr_GInfo
, &obox
.Left
, &obox
.Top
, &obox
.Width
, &obox
.Height
);
384 TextExtent(msg
->gpr_RPort
, text
, len
, &te
);
386 ibox
.Width
= te
.te_Extent
.MaxX
- te
.te_Extent
.MinX
+ 1;
387 ibox
.Height
= te
.te_Extent
.MaxY
- te
.te_Extent
.MinY
+ 1;
388 ibox
.Left
= te
.te_Extent
.MinX
+ tx
;
389 ibox
.Top
= te
.te_Extent
.MinY
+ ty
;
391 PaintBoxFrame(msg
->gpr_RPort
,
394 data
->ld
->ld_Dri
->dri_Pens
[BACKGROUNDPEN
],
398 SetABPenDrMd(msg
->gpr_RPort
,
399 data
->ld
->ld_Dri
->dri_Pens
[(g
->Flags
& GFLG_SELECTED
) ? FILLTEXTPEN
: TEXTPEN
],
400 data
->ld
->ld_Dri
->dri_Pens
[BACKGROUNDPEN
],
405 Move(msg
->gpr_RPort
, tx
, ty
);
406 Text(msg
->gpr_RPort
, text
, len
);
416 struct IBox ibox
, fbox
;
418 getgadgetcoords(g
, msg
->gpr_GInfo
, &fbox
.Left
, &fbox
.Top
, &fbox
.Width
, &fbox
.Height
);
425 PaintInnerFrame(msg
->gpr_RPort
,
430 data
->ld
->ld_Dri
->dri_Pens
[BACKGROUNDPEN
],
436 SetABPenDrMd(msg
->gpr_RPort
,
437 data
->ld
->ld_Dri
->dri_Pens
[(g
->Flags
& GFLG_SELECTED
) ? FILLPEN
: BACKGROUNDPEN
],
441 RectFill(msg
->gpr_RPort
, x
, y
, x
+ w
- 1, y
+ h
- 1);
446 struct ColorMap
*cm
= msg
->gpr_GInfo
->gi_Screen
->ViewPort
.ColorMap
;
449 GetRGB32(cm
, data
->ld
->ld_Dri
->dri_Pens
[(g
->Flags
& GFLG_SELECTED
) ? FILLPEN
: BACKGROUNDPEN
], 1, bg
);
450 data
->coolimagepal
[0] = ((bg
[0] & 0xFF000000) >> 8) + ((bg
[1] & 0xFF000000) >> 16) + ((bg
[2] & 0xFF000000) >> 24);
452 WriteLUTPixelArray((APTR
)data
->coolimage
->data
,
455 data
->coolimage
->width
,
458 x
+ BORDERIMAGESPACINGX
,
459 y
+ (h
- data
->coolimage
->height
) / 2,
460 data
->coolimage
->width
,
461 data
->coolimage
->height
,
469 /***********************************************************************************/
471 IPTR
AslButton__GM_LAYOUT(Class
* cl
, struct Gadget
* g
, struct gpLayout
* msg
)
473 struct AslButtonData
*data
;
479 data
= INST_DATA(cl
, g
);
481 retval
= DoSuperMethodA(cl
, (Object
*)g
, (Msg
)msg
);
485 case ID_MAINBUTTON_OK
:
486 case ID_MAINBUTTON_MIDDLELEFT
:
487 case ID_MAINBUTTON_MIDDLERIGHT
:
488 case ID_MAINBUTTON_CANCEL
:
490 /* multiply width 16 for sub-pixel accuracy */
492 x
= (data
->ld
->ld_WBorLeft
+ OUTERSPACINGX
) * 16 + 8;
494 innerwidth
= msg
->gpl_GInfo
->gi_Window
->Width
-
495 msg
->gpl_GInfo
->gi_Window
->BorderLeft
-
496 msg
->gpl_GInfo
->gi_Window
->BorderRight
-
499 /* multiply width 16 for sub-pixel accuracy */
501 spacing
= (innerwidth
- data
->ld
->ld_ButWidth
* data
->ld
->ld_NumButtons
) * 16 /
502 (data
->ld
->ld_NumButtons
- 1);
504 x
+= (g
->GadgetID
- ID_MAINBUTTON_OK
) * (data
->ld
->ld_ButWidth
* 16 + spacing
);
505 g
->LeftEdge
= x
/ 16;
512 /***********************************************************************************/