2 Copyright © 1995-2005, The AROS Development Team. All rights reserved.
5 Desc: Internal GadTools mx class.
10 #include <proto/exec.h>
11 #include <exec/libraries.h>
12 #include <exec/memory.h>
13 #include <proto/dos.h>
14 #include <intuition/classes.h>
15 #include <intuition/classusr.h>
16 #include <intuition/gadgetclass.h>
17 #include <intuition/imageclass.h>
18 #include <intuition/intuition.h>
19 #include <intuition/cghooks.h>
20 #include <graphics/rastport.h>
21 #include <graphics/text.h>
22 #include <utility/tagitem.h>
23 #include <devices/inputevent.h>
24 #include <proto/alib.h>
25 #include <proto/utility.h>
26 #include <gadgets/arosmx.h>
28 #include <string.h> /* memset() */
32 #include <aros/debug.h>
34 #include "gadtools_intern.h"
36 /**********************************************************************************************/
38 #define GadToolsBase ((struct GadToolsBase_intern *)cl->cl_UserData)
40 /**********************************************************************************************/
42 STATIC VOID
mx_setnew(Class
*cl
, Object
*o
, struct opSet
*msg
)
44 struct MXData
*data
= INST_DATA(cl
, o
);
46 const struct TagItem
*taglist
= msg
->ops_AttrList
;
48 while ((tag
= NextTagItem(&taglist
)))
53 data
->dri
= (struct DrawInfo
*) tag
->ti_Data
;
57 data
->tattr
= (struct TextAttr
*) tag
->ti_Data
;
61 data
->labelplace
= (LONG
) tag
->ti_Data
;
65 data
->active
= tag
->ti_Data
;
69 data
->labels
= (STRPTR
*) tag
->ti_Data
;
71 while (data
->labels
[data
->numlabels
])
76 data
->spacing
= tag
->ti_Data
;
79 case GTMX_TickLabelPlace
:
80 data
->ticklabelplace
= (LONG
) tag
->ti_Data
;
86 /**********************************************************************************************/
88 IPTR
GTMX__OM_NEW(Class
*cl
, Object
*objcl
, struct opSet
*msg
)
91 struct TagItem tags
[] =
95 {SYSIA_DrawInfo
, (IPTR
) NULL
},
96 {SYSIA_Which
, MXIMAGE
},
101 g
= (struct Gadget
*) DoSuperMethodA(cl
, objcl
, (Msg
)msg
);
105 g
->Activation
= GACT_IMMEDIATE
;
107 data
= INST_DATA(cl
, g
);
114 data
->labelplace
= GV_LabelPlace_Above
;
115 data
->ticklabelplace
= GV_LabelPlace_Right
;
117 mx_setnew(cl
, (Object
*)g
, msg
);
120 data
->font
= OpenFont(data
->tattr
);
122 /* Calculate fontheight */
124 data
->fontheight
= data
->tattr
->ta_YSize
;
125 else if ((g
->Flags
& GFLG_LABELITEXT
) && (g
->GadgetText
))
126 data
->fontheight
= g
->GadgetText
->ITextFont
->ta_YSize
;
128 data
->fontheight
= g
->Height
;
130 /* Calculate gadget size */
134 g
->Height
= (data
->fontheight
+ data
->spacing
) *data
->numlabels
-
137 tags
[0].ti_Data
= g
->Width
;
138 tags
[1].ti_Data
= GetTagData(GTMX_TickHeight
, MX_HEIGHT
, msg
->ops_AttrList
);
139 tags
[2].ti_Data
= (IPTR
) data
->dri
;
140 data
->mximage
= (struct Image
*) NewObjectA(NULL
, SYSICLASS
, tags
);
142 if ((!data
->dri
) || (!data
->labels
) || (!data
->mximage
) || (!data
->numlabels
))
144 CoerceMethod(cl
, (Object
*)g
, OM_DISPOSE
);
151 /**********************************************************************************************/
153 IPTR
GTMX__OM_DISPOSE(Class
*cl
, Object
*o
, Msg msg
)
155 struct MXData
*data
= INST_DATA(cl
, o
);
158 if (data
->font
) CloseFont(data
->font
);
159 if (data
->mximage
) DisposeObject(data
->mximage
);
161 retval
= DoSuperMethodA(cl
, o
, msg
);
166 /**********************************************************************************************/
168 IPTR
GTMX__OM_SET(Class
*cl
, Object
*o
, struct opSet
*msg
)
170 struct MXData
*data
= INST_DATA(cl
, o
);
172 const struct TagItem
*taglist
= msg
->ops_AttrList
;
175 if (msg
->MethodID
!= OM_NEW
)
176 retval
= DoSuperMethodA(cl
, o
, (Msg
)msg
);
178 while ((tag
= NextTagItem(&taglist
)))
187 if ((tag
->ti_Data
>= 0) && (tag
->ti_Data
< data
->numlabels
))
189 data
->active
= tag
->ti_Data
;
196 if ((retval
) && ((msg
->MethodID
!= OM_UPDATE
) || (cl
== OCLASS(o
))))
200 rp
= ObtainGIRPort(msg
->ops_GInfo
);
203 DoMethod(o
, GM_RENDER
, (IPTR
)msg
->ops_GInfo
, (IPTR
)rp
, GREDRAW_REDRAW
);
212 /**********************************************************************************************/
214 IPTR
GTMX__OM_GET(Class
*cl
, Object
*o
, struct opGet
*msg
)
219 data
= INST_DATA(cl
, o
);
221 switch (msg
->opg_AttrID
)
224 case GTA_ChildGadgetKind
:
225 *(msg
->opg_Storage
) = MX_KIND
;
230 *(msg
->opg_Storage
) = data
->active
;
235 retval
= DoSuperMethodA(cl
, o
, (Msg
)msg
);
242 /**********************************************************************************************/
244 IPTR
GTMX__GM_RENDER(Class
*cl
, struct ExtGadget
*g
, struct gpRender
*msg
)
246 struct MXData
*data
= INST_DATA(cl
, g
);
247 WORD ypos
= g
->TopEdge
;
251 if (msg
->gpr_Redraw
== GREDRAW_UPDATE
)
253 /* Only redraw the current and the last tick activated */
254 DrawImageState(msg
->gpr_RPort
, data
->mximage
,
255 g
->LeftEdge
, ypos
+ data
->active
*(data
->fontheight
+ data
->spacing
),
256 IDS_NORMAL
, data
->dri
);
258 DrawImageState(msg
->gpr_RPort
, data
->mximage
,
259 g
->LeftEdge
, ypos
+ data
->newactive
*(data
->fontheight
+ data
->spacing
),
260 IDS_SELECTED
, data
->dri
);
266 WORD minx
, miny
, maxx
, maxy
;
269 SetFont(msg
->gpr_RPort
, data
->font
);
271 SetFont(msg
->gpr_RPort
, msg
->gpr_GInfo
->gi_DrInfo
->dri_Font
);
274 for (y
=0; y
<data
->numlabels
; y
++)
278 if (y
== data
->active
)
279 state
= IDS_SELECTED
;
282 DrawImageState(msg
->gpr_RPort
, data
->mximage
,
285 ypos
+= data
->fontheight
+ data
->spacing
;
289 SetABPenDrMd(msg
->gpr_RPort
,
290 data
->dri
->dri_Pens
[TEXTPEN
],
291 data
->dri
->dri_Pens
[BACKGROUNDPEN
],
300 maxx
= minx
+ g
->Width
- 1;
301 maxy
= miny
+ g
->Height
- 1;
303 for (labels
= data
->labels
; *labels
; labels
++)
305 struct TextExtent te
;
306 WORD x
, y
, width
, height
, len
;
311 len
= strlen(*labels
);
312 TextExtent(msg
->gpr_RPort
, *labels
, len
, &te
);
314 height
= te
.te_Height
;
316 if (width
> maxtextwidth
) maxtextwidth
= width
;
318 switch(data
->ticklabelplace
)
320 case GV_LabelPlace_Right
:
321 x
+= data
->mximage
->Width
+ 5;
322 y
+= (data
->mximage
->Height
- height
) / 2 + 1;
325 case GV_LabelPlace_Above
:
326 x
+= (data
->mximage
->Width
- width
) / 2;
330 case GV_LabelPlace_Below
:
331 x
+= (data
->mximage
->Width
- width
) / 2;
332 y
+= (data
->mximage
->Height
+ 3);
335 case GV_LabelPlace_In
:
336 x
+= (data
->mximage
->Width
- width
) / 2;
337 y
+= (data
->mximage
->Height
- height
) / 2;
340 default: /* GV_LabelPlace_Left: */
342 y
+= (data
->mximage
->Height
- height
) / 2 + 1;
346 Move(msg
->gpr_RPort
, x
, y
+ msg
->gpr_RPort
->Font
->tf_Baseline
);
347 Text(msg
->gpr_RPort
, *labels
, len
);
349 if (x
< minx
) minx
= x
;
350 if (y
< miny
) miny
= y
;
351 if (x
+ width
- 1 > maxx
) maxx
= x
+ width
- 1;
352 if (y
+ height
- 1 > maxy
) maxy
= y
+ height
- 1;
354 ypos
+= data
->fontheight
+ data
->spacing
;
357 g
->BoundsLeftEdge
= minx
;
358 g
->BoundsTopEdge
= miny
;
359 g
->BoundsWidth
= maxx
- minx
+ 1;
360 g
->BoundsHeight
= maxy
- miny
+ 1;
361 g
->MoreFlags
|= GMORE_BOUNDS
;
363 data
->maxtextwidth
= maxtextwidth
;
365 /* Draw main label */
367 /* bug: this will not be rendered at the correct
368 position if ticklabel place and labelplace
369 are the same. I don't think any app will
378 renderlabel(GadToolsBase
,
385 /* Draw disabled pattern */
386 if (g
->Flags
& GFLG_DISABLED
)
387 DoDisabledPattern(msg
->gpr_RPort
,
390 g
->LeftEdge
+ g
->Width
- 1,
391 g
->TopEdge
+ g
->Height
- 1,
392 data
->dri
->dri_Pens
[SHADOWPEN
],
398 /**********************************************************************************************/
400 IPTR
GTMX__GM_GOACTIVE(Class
*cl
, Object
*o
, struct gpInput
*msg
)
402 struct MXData
*data
= INST_DATA(cl
, o
);
403 int y
, blobheight
= data
->spacing
+ data
->fontheight
;
404 IPTR retval
= GMR_NOREUSE
;
406 D(bug("blobheight: %d\n", blobheight
));
408 for (y
= 0; y
< data
->numlabels
; y
++)
410 D(bug("Mouse.Y: %d, y: %d\n", msg
->gpi_Mouse
.Y
, y
));
411 if (msg
->gpi_Mouse
.Y
< blobheight
*(y
+ 1))
413 if (y
!= data
->active
)
417 rp
= ObtainGIRPort(msg
->gpi_GInfo
);
421 DoMethod(o
, GM_RENDER
, (IPTR
)msg
->gpi_GInfo
, (IPTR
)rp
, GREDRAW_UPDATE
);
423 *msg
->gpi_Termination
= data
->active
= y
;
424 retval
|= GMR_VERIFY
;
434 /**********************************************************************************************/