2 Copyright © 2002-2003, The AROS Development Team. All rights reserved.
6 #define MUIMASTER_YES_INLINE_STDARG
8 #include <exec/memory.h>
9 #include <clib/alib_protos.h>
10 #include <proto/exec.h>
11 #include <proto/dos.h>
12 #include <proto/intuition.h>
13 #include <proto/graphics.h>
14 #include <proto/utility.h>
15 #include <proto/muimaster.h>
21 #include "muimaster_intern.h"
24 #include "support_classes.h"
28 #include "numericbutton_private.h"
30 extern struct Library
*MUIMasterBase
;
32 #define longget(obj,attr,var) \
35 IPTR _iptr_var = *(var); \
36 get(obj,attr,&_iptr_var); \
37 *var = (LONG)_iptr_var; \
40 IPTR
Numericbutton__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
42 obj
= (Object
*)DoSuperNewTags
45 MUIA_Background
, MUII_ButtonBack
,
46 MUIA_Frame
, MUIV_Frame_Button
,
47 TAG_MORE
, (IPTR
) msg
->ops_AttrList
52 struct Numericbutton_DATA
*data
= INST_DATA(cl
, obj
);
54 data
->ehn
.ehn_Events
= IDCMP_MOUSEBUTTONS
;
55 data
->ehn
.ehn_Priority
= 0;
56 data
->ehn
.ehn_Flags
= 0;
57 data
->ehn
.ehn_Object
= obj
;
58 data
->ehn
.ehn_Class
= cl
;
64 /**************************************************************************
66 **************************************************************************/
67 static ULONG
Numericbutton__OM_SET(struct IClass
*cl
, Object
* obj
, struct opSet
*msg
)
69 struct Numericbutton_DATA
*data
= INST_DATA(cl
, obj
);
70 struct TagItem
*tags
, *tag
;
72 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
));)
76 case MUIA_Numeric_Max
:
77 if (tag
->ti_Data
!= XGET(obj
, MUIA_Numeric_Max
))
78 data
->needs_to_recalculate_sizes
= TRUE
;
80 case MUIA_Numeric_Min
:
81 if (tag
->ti_Data
!= XGET(obj
, MUIA_Numeric_Min
))
82 data
->needs_to_recalculate_sizes
= TRUE
;
84 case MUIA_Numeric_Format
:
85 if (tag
->ti_Data
!= XGET(obj
, MUIA_Numeric_Format
))
86 data
->needs_to_recalculate_sizes
= TRUE
;
91 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
94 IPTR
Numericbutton__MUIM_Setup(struct IClass
*cl
, Object
*obj
, struct MUIP_Setup
*msg
)
96 struct Numericbutton_DATA
*data
= INST_DATA(cl
, obj
);
97 // const struct ZuneFrameGfx *knob_frame;
100 retval
= DoSuperMethodA(cl
, obj
, (Msg
)msg
);
103 //knob_frame = zune_zframe_get(&muiGlobalInfo(obj)->mgi_Prefs->frames[MUIV_Frame_Knob]);
105 data
->knob_bg
= zune_imspec_setup(MUII_ButtonBack
, muiRenderInfo(obj
));
107 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
109 data
->needs_to_recalculate_sizes
= TRUE
;
115 IPTR
Numericbutton__MUIM_Cleanup(struct IClass
*cl
, Object
*obj
, struct MUIP_Cleanup
*msg
)
117 struct Numericbutton_DATA
*data
= INST_DATA(cl
, obj
);
121 zune_imspec_cleanup(data
->knob_bg
);
122 data
->knob_bg
= NULL
;
125 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
127 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
130 /**************************************************************************
132 **************************************************************************/
133 IPTR
Numericbutton__MUIM_AskMinMax(struct IClass
*cl
, Object
*obj
, struct MUIP_AskMinMax
*msg
)
135 struct Numericbutton_DATA
*data
= INST_DATA(cl
, obj
);
137 DoSuperMethodA(cl
, obj
, (Msg
)msg
);
139 if (data
->needs_to_recalculate_sizes
)
142 LONG min
, max
, val
, width
;
145 SetFont(&rp
,_font(obj
));
149 longget(obj
, MUIA_Numeric_Min
, &min
);
150 longget(obj
, MUIA_Numeric_Max
, &max
);
152 /* Determine the width of the knob */
153 for (val
=min
;val
<=max
;val
++)
158 buf
= (char*)DoMethod(obj
, MUIM_Numeric_Stringify
, val
);
159 nw
= TextLength(&rp
, buf
, strlen(buf
));
165 data
->max_text_width
= width
;
166 data
->text_height
= _font(obj
)->tf_YSize
;
168 data
->needs_to_recalculate_sizes
= FALSE
;
171 msg
->MinMaxInfo
->MinWidth
+= data
->max_text_width
;
172 msg
->MinMaxInfo
->MinHeight
+= data
->text_height
;
173 msg
->MinMaxInfo
->DefWidth
+= data
->max_text_width
;
174 msg
->MinMaxInfo
->DefHeight
+= data
->text_height
;
175 msg
->MinMaxInfo
->MaxWidth
+= data
->max_text_width
;
176 msg
->MinMaxInfo
->MaxHeight
+= data
->text_height
;
181 static void DrawKnob(Object
*obj
, struct Numericbutton_DATA
*data
, BOOL force
)
183 struct RastPort
*rp
, *saverp
;
184 LONG x
, val
, pixeloffset
, textlen
, pixellen
;
187 pixeloffset
= data
->popwin
->MouseX
- data
->pop_innerx
- 2 - data
->knob_clickoffset_x
;
189 val
= DoMethod(obj
, MUIM_Numeric_ScaleToValue
, 0,
190 data
->pop_innerw
- data
->knob_width
, pixeloffset
);
192 data
->knob_left
= data
->pop_innerx
+ pixeloffset
;
193 data
->knob_top
= data
->pop_innery
;
194 data
->knob_val
= val
;
196 if (!force
&& (data
->knob_left
== data
->knob_prev_left
))
200 data
->knob_prev_left
= data
->knob_left
;
202 if (data
->knob_left
< data
->pop_innerx
)
204 data
->knob_left
= data
->pop_innerx
;
206 else if (data
->knob_left
> data
->pop_innerx
+ data
->pop_innerw
- data
->knob_width
)
208 data
->knob_left
= data
->pop_innerx
+ data
->pop_innerw
- data
->knob_width
;
212 _rp(obj
) = rp
= data
->popwin
->RPort
;
214 SetABPenDrMd(rp
, _pens(obj
)[MPEN_SHINE
], 0, JAM1
);
215 RectFill(rp
, data
->knob_left
, data
->knob_top
,
216 data
->knob_left
, data
->knob_top
+ data
->knob_height
- 1);
217 RectFill(rp
, data
->knob_left
+ 1, data
->knob_top
,
218 data
->knob_left
+ data
->knob_width
- 1, data
->knob_top
);
219 SetAPen(rp
, _pens(obj
)[MPEN_SHADOW
]);
220 RectFill(rp
, data
->knob_left
+ data
->knob_width
- 1, data
->knob_top
+ 1,
221 data
->knob_left
+ data
->knob_width
- 1, data
->knob_top
+ data
->knob_height
- 1);
222 RectFill(rp
, data
->knob_left
+ 1, data
->knob_top
+ data
->knob_height
- 1,
223 data
->knob_left
+ data
->knob_width
- 2, data
->knob_top
+ data
->knob_height
- 1);
227 #warning "Ugly hack?"
229 struct IBox old_mad_Box
= muiAreaData(obj
)->mad_Box
;
231 muiAreaData(obj
)->mad_Box
.Left
= data
->knob_left
+ 1;
232 muiAreaData(obj
)->mad_Box
.Top
= data
->knob_top
+ 1;
233 muiAreaData(obj
)->mad_Box
.Width
= data
->knob_width
- 2;
234 muiAreaData(obj
)->mad_Box
.Height
= data
->knob_height
- 2;
236 zune_imspec_draw(data
->knob_bg
, muiRenderInfo(obj
),
239 data
->knob_width
- 2,
240 data
->knob_height
- 2,
245 muiAreaData(obj
)->mad_Box
= old_mad_Box
;
249 SetAPen(rp
, _pens(obj
)[MPEN_BACKGROUND
]);
250 RectFill(rp
, data
->knob_left
+ 1, data
->knob_top
+ 1,
251 data
->knob_left
+ data
->knob_width
- 2,
252 data
->knob_top
+ data
->knob_height
- 2);
255 SetFont(rp
, _font(obj
));
257 text
= (STRPTR
)DoMethod(obj
, MUIM_Numeric_Stringify
, val
);
258 textlen
= strlen(text
);
259 pixellen
= TextLength(_rp(obj
), text
, textlen
);
261 SetAPen(rp
, _pens(obj
)[MPEN_TEXT
]);
262 Move(rp
, data
->knob_left
+ 2 + (data
->knob_width
- 4 - pixellen
) / 2,
263 data
->knob_top
+ 1 + rp
->TxBaseline
);
264 Text(rp
, text
, textlen
);
266 SetAPen(rp
, _pens(obj
)[MPEN_BACKGROUND
]);
268 if (data
->knob_left
- 1 >= data
->pop_innerx
)
270 RectFill(rp
, data
->pop_innerx
, data
->pop_innery
,
271 data
->knob_left
- 1, data
->pop_innery
+ data
->pop_innerh
- 1);
274 x
= data
->knob_left
+ data
->knob_width
;
275 if (x
<= data
->pop_innerx
+ data
->pop_innerw
- 1)
277 RectFill(rp
, x
, data
->pop_innery
,
278 data
->pop_innerx
+ data
->pop_innerw
- 1,
279 data
->pop_innery
+ data
->pop_innerh
- 1);
285 static void KillPopupWin(Object
*obj
, struct Numericbutton_DATA
*data
)
289 CloseWindow(data
->popwin
);
293 if (data
->ehn
.ehn_Events
& IDCMP_MOUSEMOVE
)
295 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
296 data
->ehn
.ehn_Events
&= ~IDCMP_MOUSEMOVE
;
297 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
302 static BOOL
MakePopupWin(Object
*obj
, struct Numericbutton_DATA
*data
)
304 const struct ZuneFrameGfx
*zframe
;
305 struct RastPort
*rp
, *saverp
;
306 LONG winx
, winy
, winw
, winh
;
310 zframe
= zune_zframe_get_with_state(&muiGlobalInfo(obj
)->mgi_Prefs
->frames
[MUIV_Frame_Slider
],
311 muiGlobalInfo(obj
)->mgi_Prefs
->frames
[MUIV_Frame_Slider
].state
);
313 data
->pop_innerx
= zframe
->ileft
;
314 data
->pop_innery
= zframe
->itop
;
316 data
->knob_width
= data
->max_text_width
+ 4;
317 data
->knob_height
= data
->text_height
+ 2;
319 framew
= data
->pop_innerx
+ zframe
->iright
;
320 frameh
= data
->pop_innery
+ zframe
->ibottom
;
322 longget(obj
, MUIA_Numeric_Min
, &min
);
323 longget(obj
, MUIA_Numeric_Max
, &max
);
325 winw
= max
- min
+ data
->knob_width
+ framew
;
326 winh
= data
->knob_height
+ frameh
;
328 if (winw
> _screen(obj
)->Width
)
330 winw
= _screen(obj
)->Width
;
333 if ((winw
< data
->knob_width
+ framew
) || (winh
> _screen(obj
)->Height
))
338 data
->pop_innerw
= winw
- framew
;
339 data
->pop_innerh
= winh
- frameh
;
341 data
->knob_left
= DoMethod(obj
, MUIM_Numeric_ValueToScale
, 0, data
->pop_innerw
- data
->knob_width
);
343 winx
= _window(obj
)->LeftEdge
+ _mleft(obj
) -
344 data
->pop_innerx
- 2 -
346 winy
= _window(obj
)->TopEdge
+ _mtop(obj
) - 1-
349 data
->popwin
= OpenWindowTags(NULL
, WA_CustomScreen
, (IPTR
)_screen(obj
),
357 WA_BackFill
, (IPTR
)LAYERS_NOBACKFILL
,
365 rp
= data
->popwin
->RPort
;
369 zframe
->draw(muiRenderInfo(obj
), 0, 0, winw
, winh
);
371 DrawKnob(obj
, data
, TRUE
);
380 /**************************************************************************
382 **************************************************************************/
383 IPTR
Numericbutton__MUIM_Show(struct IClass
*cl
, Object
*obj
, struct MUIP_Show
*msg
)
385 struct Numericbutton_DATA
*data
= INST_DATA(cl
, obj
);
388 retval
= DoSuperMethodA(cl
, obj
, (Msg
)msg
);
391 zune_imspec_show(data
->knob_bg
, obj
);
396 /**************************************************************************
398 **************************************************************************/
399 IPTR
Numericbutton__MUIM_Hide(struct IClass
*cl
, Object
*obj
, struct MUIP_Hide
*msg
)
401 struct Numericbutton_DATA
*data
= INST_DATA(cl
, obj
);
405 KillPopupWin(obj
, data
);
409 zune_imspec_hide(data
->knob_bg
);
411 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
415 /**************************************************************************
417 **************************************************************************/
418 IPTR
Numericbutton__MUIM_Draw(struct IClass
*cl
, Object
*obj
, struct MUIP_Draw
*msg
)
424 DoSuperMethodA(cl
,obj
,(Msg
)msg
);
426 if (!(msg
->flags
& (MADF_DRAWOBJECT
| MADF_DRAWUPDATE
)))
429 DoMethod(obj
,MUIM_DrawBackground
,_mleft(obj
),_mtop(obj
),_mwidth(obj
),_mheight(obj
),
430 _mleft(obj
),_mtop(obj
),0);
432 SetFont(_rp(obj
),_font(obj
));
433 SetABPenDrMd(_rp(obj
),_pens(obj
)[MPEN_TEXT
],_pens(obj
)[MPEN_BACKGROUND
],JAM1
);
435 get(obj
, MUIA_Numeric_Value
, &val
);
436 buf
= (char*)DoMethod(obj
,MUIM_Numeric_Stringify
,val
);
437 width
= TextLength(_rp(obj
),buf
,strlen(buf
));
439 Move(_rp(obj
), _mleft(obj
) + (_mwidth(obj
) - width
) / 2,
440 _mtop(obj
) + _font(obj
)->tf_Baseline
);
442 Text(_rp(obj
), buf
, strlen(buf
));
447 /**************************************************************************
449 **************************************************************************/
450 IPTR
Numericbutton__MUIM_HandleEvent(struct IClass
*cl
, Object
*obj
, struct MUIP_HandleEvent
*msg
)
452 struct Numericbutton_DATA
*data
= INST_DATA(cl
, obj
);
459 switch(msg
->imsg
->Class
)
461 case IDCMP_MOUSEBUTTONS
:
462 switch(msg
->imsg
->Code
)
465 if (_between(_left(obj
), msg
->imsg
->MouseX
, _right(obj
)) &&
466 _between(_top(obj
), msg
->imsg
->MouseY
, _bottom(obj
)) &&
467 (muiAreaData(obj
)->mad_Flags
& MADF_CANDRAW
) &&
470 data
->knob_clickoffset_x
= msg
->imsg
->MouseX
- _mleft(obj
);
472 if (MakePopupWin(obj
, data
))
474 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
475 data
->ehn
.ehn_Events
|= IDCMP_MOUSEMOVE
;
476 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
489 KillPopupWin(obj
, data
);
490 if ((msg
->imsg
->Code
== SELECTUP
))
492 set(obj
, MUIA_Numeric_Value
, data
->knob_val
);
499 } /* switch(msg->imsg->Code) */
502 case IDCMP_MOUSEMOVE
:
505 DrawKnob(obj
, data
, FALSE
);
511 } /* switch(msg->imsg->Class) */
517 #if ZUNE_BUILTIN_NUMERICBUTTON
518 BOOPSI_DISPATCHER(IPTR
, Numericbutton_Dispatcher
, cl
, obj
, msg
)
520 switch (msg
->MethodID
)
522 case OM_NEW
: return Numericbutton__OM_NEW(cl
, obj
, (struct opSet
*)msg
);
523 case OM_SET
: return Numericbutton__OM_SET(cl
, obj
, (struct opSet
*)msg
);
525 case MUIM_Setup
: return Numericbutton__MUIM_Setup(cl
, obj
, (struct MUIP_Setup
*)msg
);
526 case MUIM_Cleanup
: return Numericbutton__MUIM_Cleanup(cl
, obj
, (struct MUIP_Cleanup
*)msg
);
527 case MUIM_Show
: return Numericbutton__MUIM_Show(cl
, obj
, (struct MUIP_Show
*)msg
);
528 case MUIM_Hide
: return Numericbutton__MUIM_Hide(cl
, obj
, (struct MUIP_Hide
*)msg
);
529 case MUIM_AskMinMax
: return Numericbutton__MUIM_AskMinMax(cl
, obj
, (struct MUIP_AskMinMax
*)msg
);
530 case MUIM_Draw
: return Numericbutton__MUIM_Draw(cl
, obj
, (struct MUIP_Draw
*)msg
);
531 case MUIM_HandleEvent
: return Numericbutton__MUIM_HandleEvent(cl
, obj
, (struct MUIP_HandleEvent
*)msg
);
532 default: return DoSuperMethodA(cl
, obj
, msg
);
535 BOOPSI_DISPATCHER_END
537 const struct __MUIBuiltinClass _MUI_Numericbutton_desc
=
541 sizeof(struct Numericbutton_DATA
),
542 (void*)Numericbutton_Dispatcher
544 #endif /* ZUNE_BUILTIN_NUMERICBUTTON */