2 Copyright © 1999, David Le Corfec.
3 Copyright © 2002-2006, The AROS Development Team.
11 #include <exec/types.h>
13 #include <clib/alib_protos.h>
14 #include <proto/intuition.h>
15 #include <proto/graphics.h>
16 #include <proto/utility.h>
17 #include <proto/exec.h>
18 #include <proto/muimaster.h>
21 #include "muimaster_intern.h"
23 #include "textengine.h"
26 /* #define MYDEBUG 1 */
29 extern struct Library
*MUIMasterBase
;
31 static const int __version
= 1;
32 static const int __revision
= 1;
41 #define RECTANGLE_TYPE_NORMAL 0
42 #define RECTANGLE_TYPE_HBAR 1
43 #define RECTANGLE_TYPE_VBAR 2
45 static void draw_line(struct RastPort
*rp
, int xa
, int ya
, int xb
, int yb
)
52 IPTR
Rectangle__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
54 struct Rectangle_DATA
*data
;
55 struct TagItem
*tags
,*tag
;
57 obj
= (Object
*)DoSuperNewTags(cl
, obj
, NULL
,
58 MUIA_Font
, MUIV_Font_Title
,
59 TAG_MORE
, (IPTR
) msg
->ops_AttrList
);
64 /* Initial local instance data */
65 data
= INST_DATA(cl
, obj
);
67 data
->Type
= RECTANGLE_TYPE_NORMAL
;
69 /* parse initial taglist */
71 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem((const struct TagItem
**)&tags
)); )
75 case MUIA_Rectangle_BarTitle
:
76 data
->BarTitle
= StrDup((STRPTR
)tag
->ti_Data
);
78 case MUIA_Rectangle_HBar
:
79 data
->Type
= RECTANGLE_TYPE_HBAR
;
81 case MUIA_Rectangle_VBar
:
82 data
->Type
= RECTANGLE_TYPE_VBAR
;
87 D(bug("muimaster.library/rectangle.c: New Rectangle Object at 0x%lx\n",obj
));
92 IPTR
Rectangle__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
94 struct Rectangle_DATA
*data
= INST_DATA(cl
, obj
);
96 if (data
->BarTitle
) mui_free(data
->BarTitle
);
98 return DoSuperMethodA(cl
, obj
, msg
);
102 IPTR
Rectangle__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
104 /*----------------------------------------------------------------------------*/
105 /* small macro to simplify return value storage */
106 /*----------------------------------------------------------------------------*/
107 #define STORE *(msg->opg_Storage)
109 struct Rectangle_DATA
*data
= INST_DATA(cl
, obj
);
111 switch(msg
->opg_AttrID
)
121 case MUIA_Rectangle_BarTitle
:
122 STORE
= (IPTR
)data
->BarTitle
;
125 case MUIA_Rectangle_HBar
:
126 STORE
= (data
->Type
== RECTANGLE_TYPE_HBAR
);
129 case MUIA_Rectangle_VBar
:
130 STORE
= (data
->Type
== RECTANGLE_TYPE_VBAR
);
134 /* our handler didn't understand the attribute, we simply pass
135 ** it to our superclass now
137 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
141 IPTR
Rectangle__MUIM_Setup(struct IClass
*cl
, Object
*obj
, struct MUIP_Setup
*msg
)
143 struct Rectangle_DATA
*data
= INST_DATA(cl
, obj
);
145 if (!(DoSuperMethodA(cl
, obj
, (Msg
) msg
)))
150 data
->ztext
= zune_text_new(NULL
, data
->BarTitle
,
157 IPTR
Rectangle__MUIM_Cleanup(struct IClass
*cl
, Object
*obj
, struct MUIP_Cleanup
*msg
)
159 struct Rectangle_DATA
*data
= INST_DATA(cl
, obj
);
162 zune_text_destroy(data
->ztext
);
164 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
167 /**************************************************************************
170 AskMinMax method will be called before the window is opened
171 and before layout takes place. We need to tell MUI the
172 minimum, maximum and default size of our object.
173 **************************************************************************/
174 IPTR
Rectangle__MUIM_AskMinMax(struct IClass
*cl
, Object
*obj
, struct MUIP_AskMinMax
*msg
)
176 struct Rectangle_DATA
*data
= INST_DATA(cl
, obj
);
179 ** let our superclass first fill in what it thinks about sizes.
180 ** this will e.g. add the size of frame and inner spacing.
182 DoSuperMethodA(cl
, obj
, (Msg
)msg
);
185 ** now add the values specific to our object. note that we
186 ** indeed need to *add* these values, not just set them!
191 /* msg->MinMaxInfo->MinWidth += 1; */
192 /* msg->MinMaxInfo->MinHeight += 1; */
193 if (data
->Type
== RECTANGLE_TYPE_HBAR
)
195 msg
->MinMaxInfo
->MinHeight
+= 2;
197 else if (data
->Type
== RECTANGLE_TYPE_VBAR
)
199 msg
->MinMaxInfo
->MinWidth
+= 2;
204 zune_text_get_bounds(data
->ztext
, obj
);
205 msg
->MinMaxInfo
->MinWidth
+= data
->ztext
->width
;
206 msg
->MinMaxInfo
->MinHeight
+= data
->ztext
->height
;
207 D(bug("rect: minheight %ld\n",data
->ztext
->height
));
208 if (muiGlobalInfo(obj
)->mgi_Prefs
->group_title_color
== GROUP_TITLE_COLOR_3D
)
210 msg
->MinMaxInfo
->MinWidth
+= 1;
211 msg
->MinMaxInfo
->MinHeight
+= 1;
215 msg
->MinMaxInfo
->DefWidth
= msg
->MinMaxInfo
->MinWidth
;
216 msg
->MinMaxInfo
->DefHeight
= msg
->MinMaxInfo
->MinHeight
;
218 msg
->MinMaxInfo
->MaxWidth
= MUI_MAXMAX
;
219 msg
->MinMaxInfo
->MaxHeight
= MUI_MAXMAX
;
225 /**************************************************************************
228 Draw method is called whenever MUI feels we should render
229 our object. This usually happens after layout is finished
230 or when we need to refresh in a simplerefresh window.
231 Note: You may only render within the rectangle
232 _mleft(obj), _mtop(obj), _mwidth(obj), _mheight(obj).
233 **************************************************************************/
234 IPTR
Rectangle__MUIM_Draw(struct IClass
*cl
, Object
*obj
, struct MUIP_Draw
*msg
)
236 struct Rectangle_DATA
*data
= INST_DATA(cl
, obj
);
237 struct MUI_RenderInfo
*mri
;
240 ** let our superclass draw itself first, area class would
241 ** e.g. draw the frame and clear the whole region. What
242 ** it does exactly depends on msg->flags.
245 DoSuperMethodA(cl
, obj
, (Msg
)msg
);
248 ** if MADF_DRAWOBJECT isn't set, we shouldn't draw anything.
249 ** MUI just wanted to update the frame or something like that.
252 if (!(msg
->flags
& MADF_DRAWOBJECT
))
256 D(bug("Draw Rectangle(0x%lx) %ldx%ldx%ldx%ld mw=%ld mh=%ld\n",obj
,_left(obj
),_top(obj
),_right(obj
),_bottom(obj
), _mwidth(obj
), _mheight(obj
)));
258 if (_mwidth(obj
) < 1 || _mheight(obj
) < 1)
261 mri
= muiRenderInfo(obj
);
264 * ok, everything ready to render...
269 * Rewrite me, I'm ugly ! (but right :)
277 /* D(bug("muimaster.library/rectangle.c: Draw Rectangle Object at 0x%lx %ldx%ldx%ldx%ld\n mw=%ld mh=%ld\n",obj,_left(obj),_top(obj),_right(obj),_bottom(obj), _mwidth(obj), _mheight(obj))); */
279 SetAPen(_rp(obj
), _pens(obj
)[MPEN_SHADOW
]);
280 if (muiGlobalInfo(obj
)->mgi_Prefs
->group_title_color
== GROUP_TITLE_COLOR_3D
)
282 tw
= data
->ztext
->width
+ 1;
283 th
= data
->ztext
->height
+ 1;
284 x1
= _mleft(obj
) + (_mwidth(obj
) - tw
) / 2;
287 yt
= _mtop(obj
) + (_mheight(obj
) - th
) / 2;
288 zune_text_draw(data
->ztext
, obj
, x1
+ 1, x2
, yt
+ 1);
289 SetAPen(_rp(obj
), _pens(obj
)[MPEN_SHINE
]);
290 zune_text_draw(data
->ztext
, obj
, x1
, x2
- 1, yt
);
292 if (data
->Type
== RECTANGLE_TYPE_HBAR
)
294 int y
= yt
+ data
->ztext
->height
/ 2;
296 if ((x1
- 2) > _mleft(obj
)
297 && (x2
+ 2) < _mright(obj
))
299 SetAPen(_rp(obj
), _pens(obj
)[MPEN_SHADOW
]);
300 draw_line(_rp(obj
), _mleft(obj
), y
, x1
- 2, y
);
301 draw_line(_rp(obj
), x2
+ 3, y
, _mright(obj
), y
);
303 SetAPen(_rp(obj
), _pens(obj
)[MPEN_SHINE
]);
304 draw_line(_rp(obj
), _mleft(obj
), y
+1, x1
- 2, y
+1);
305 draw_line(_rp(obj
), x2
+ 3, y
+1, _mright(obj
), y
+1);
309 else /* black or white */
311 if (muiGlobalInfo(obj
)->mgi_Prefs
->group_title_color
== GROUP_TITLE_COLOR_HILITE
)
312 SetAPen(_rp(obj
), _pens(obj
)[MPEN_SHINE
]);
314 tw
= data
->ztext
->width
;
315 th
= data
->ztext
->height
;
316 x1
= _mleft(obj
) + (_mwidth(obj
) - tw
) / 2;
318 yt
= _mtop(obj
) + (_mheight(obj
) - th
) / 2;
320 zune_text_draw(data
->ztext
, obj
, x1
, x2
- 1, yt
);
322 if (data
->Type
== RECTANGLE_TYPE_HBAR
)
324 int y
= yt
+ data
->ztext
->height
/ 2;
326 if ((x1
- 2) > _mleft(obj
)
327 && (x2
+ 2) < _mright(obj
))
329 SetAPen(_rp(obj
), _pens(obj
)[MPEN_SHADOW
]);
330 draw_line(_rp(obj
), _mleft(obj
), y
, x1
- 3, y
);
331 draw_line(_rp(obj
), x2
+ 2, y
, _mright(obj
), y
);
333 SetAPen(_rp(obj
), _pens(obj
)[MPEN_SHINE
]);
334 draw_line(_rp(obj
), _mleft(obj
), y
+1, x1
- 3, y
+1);
335 draw_line(_rp(obj
), x2
+ 2, y
+1, _mright(obj
), y
+1);
340 else /* no bar title */
342 if (data
->Type
== RECTANGLE_TYPE_HBAR
)
344 int y
= _mtop(obj
) + _mheight(obj
) / 2 - 1;
346 SetAPen(_rp(obj
), _pens(obj
)[MPEN_SHADOW
]);
347 draw_line(_rp(obj
), _mleft(obj
), y
, _mright(obj
), y
);
349 SetAPen(_rp(obj
), _pens(obj
)[MPEN_SHINE
]);
350 draw_line(_rp(obj
), _mleft(obj
), y
+1, _mright(obj
), y
+1);
352 else if (data
->Type
== RECTANGLE_TYPE_VBAR
)
354 int x
= _mleft(obj
) + _mwidth(obj
) / 2 - 1;
356 SetAPen(_rp(obj
), _pens(obj
)[MPEN_SHADOW
]);
357 draw_line(_rp(obj
), x
, _mtop(obj
), x
, _mbottom(obj
));
359 SetAPen(_rp(obj
), _pens(obj
)[MPEN_SHINE
]);
360 draw_line(_rp(obj
), x
+1, _mtop(obj
), x
+1, _mbottom(obj
));
365 WORD pnts
[] = { _mleft(obj
), _mtop(obj
), _mleft(obj
), _mbottom(obj
),
366 _mright(obj
), _mbottom(obj
), _mright(obj
), _mtop(obj
) };
367 SetAPen(_rp(obj
), _pens(obj
)[MPEN_SHADOW
]);
368 Move(_rp(obj
), _mright(obj
), _mtop(obj
));
369 PolyDraw(_rp(obj
), 4, pnts
);
377 BOOPSI_DISPATCHER(IPTR
, Rectangle_Dispatcher
, cl
, obj
, msg
)
379 switch (msg
->MethodID
)
381 case OM_NEW
: return Rectangle__OM_NEW(cl
, obj
, (struct opSet
*) msg
);
382 case OM_DISPOSE
: return Rectangle__OM_DISPOSE(cl
, obj
, msg
);
383 case OM_GET
: return Rectangle__OM_GET(cl
, obj
, (struct opGet
*)msg
);
384 case MUIM_Setup
: return Rectangle__MUIM_Setup(cl
, obj
, (APTR
)msg
);
385 case MUIM_Cleanup
: return Rectangle__MUIM_Cleanup(cl
, obj
, (APTR
)msg
);
386 case MUIM_AskMinMax
: return Rectangle__MUIM_AskMinMax(cl
, obj
, (APTR
)msg
);
387 case MUIM_Draw
: return Rectangle__MUIM_Draw(cl
, obj
, (APTR
)msg
);
388 default: return DoSuperMethodA(cl
, obj
, msg
);
391 BOOPSI_DISPATCHER_END
393 const struct __MUIBuiltinClass _MUI_Rectangle_desc
=
397 sizeof(struct Rectangle_DATA
),
398 (void*)Rectangle_Dispatcher