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 const struct TagItem
*tags
;
73 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
));)
77 case MUIA_Numeric_Max
:
78 if (tag
->ti_Data
!= XGET(obj
, MUIA_Numeric_Max
))
79 data
->needs_to_recalculate_sizes
= TRUE
;
81 case MUIA_Numeric_Min
:
82 if (tag
->ti_Data
!= XGET(obj
, MUIA_Numeric_Min
))
83 data
->needs_to_recalculate_sizes
= TRUE
;
85 case MUIA_Numeric_Format
:
86 if (tag
->ti_Data
!= XGET(obj
, MUIA_Numeric_Format
))
87 data
->needs_to_recalculate_sizes
= TRUE
;
92 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
95 IPTR
Numericbutton__MUIM_Setup(struct IClass
*cl
, Object
*obj
, struct MUIP_Setup
*msg
)
97 struct Numericbutton_DATA
*data
= INST_DATA(cl
, obj
);
98 // const struct ZuneFrameGfx *knob_frame;
101 retval
= DoSuperMethodA(cl
, obj
, (Msg
)msg
);
104 //knob_frame = zune_zframe_get(obj, &muiGlobalInfo(obj)->mgi_Prefs->frames[MUIV_Frame_Knob]);
106 data
->knob_bg
= zune_imspec_setup(MUII_ButtonBack
, muiRenderInfo(obj
));
108 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
110 data
->needs_to_recalculate_sizes
= TRUE
;
116 IPTR
Numericbutton__MUIM_Cleanup(struct IClass
*cl
, Object
*obj
, struct MUIP_Cleanup
*msg
)
118 struct Numericbutton_DATA
*data
= INST_DATA(cl
, obj
);
122 zune_imspec_cleanup(data
->knob_bg
);
123 data
->knob_bg
= NULL
;
126 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
128 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
131 /**************************************************************************
133 **************************************************************************/
134 IPTR
Numericbutton__MUIM_AskMinMax(struct IClass
*cl
, Object
*obj
, struct MUIP_AskMinMax
*msg
)
136 struct Numericbutton_DATA
*data
= INST_DATA(cl
, obj
);
138 DoSuperMethodA(cl
, obj
, (Msg
)msg
);
140 if (data
->needs_to_recalculate_sizes
)
143 LONG min
, max
, val
, width
;
146 SetFont(&rp
,_font(obj
));
150 longget(obj
, MUIA_Numeric_Min
, &min
);
151 longget(obj
, MUIA_Numeric_Max
, &max
);
153 /* Determine the width of the knob */
154 for (val
=min
;val
<=max
;val
++)
159 buf
= (char*)DoMethod(obj
, MUIM_Numeric_Stringify
, val
);
160 nw
= TextLength(&rp
, buf
, strlen(buf
));
166 data
->max_text_width
= width
;
167 data
->text_height
= _font(obj
)->tf_YSize
;
169 data
->needs_to_recalculate_sizes
= FALSE
;
172 msg
->MinMaxInfo
->MinWidth
+= data
->max_text_width
;
173 msg
->MinMaxInfo
->MinHeight
+= data
->text_height
;
174 msg
->MinMaxInfo
->DefWidth
+= data
->max_text_width
;
175 msg
->MinMaxInfo
->DefHeight
+= data
->text_height
;
176 msg
->MinMaxInfo
->MaxWidth
+= data
->max_text_width
;
177 msg
->MinMaxInfo
->MaxHeight
+= data
->text_height
;
182 static void DrawKnob(Object
*obj
, struct Numericbutton_DATA
*data
, BOOL force
)
184 struct RastPort
*rp
, *saverp
;
185 LONG x
, val
, pixeloffset
, textlen
, pixellen
;
188 pixeloffset
= data
->popwin
->MouseX
- data
->pop_innerx
- 2 - data
->knob_clickoffset_x
;
190 val
= DoMethod(obj
, MUIM_Numeric_ScaleToValue
, 0,
191 data
->pop_innerw
- data
->knob_width
, pixeloffset
);
193 data
->knob_left
= data
->pop_innerx
+ pixeloffset
;
194 data
->knob_top
= data
->pop_innery
;
195 data
->knob_val
= val
;
197 if (!force
&& (data
->knob_left
== data
->knob_prev_left
))
201 data
->knob_prev_left
= data
->knob_left
;
203 if (data
->knob_left
< data
->pop_innerx
)
205 data
->knob_left
= data
->pop_innerx
;
207 else if (data
->knob_left
> data
->pop_innerx
+ data
->pop_innerw
- data
->knob_width
)
209 data
->knob_left
= data
->pop_innerx
+ data
->pop_innerw
- data
->knob_width
;
213 _rp(obj
) = rp
= data
->popwin
->RPort
;
215 SetABPenDrMd(rp
, _pens(obj
)[MPEN_SHINE
], 0, JAM1
);
216 RectFill(rp
, data
->knob_left
, data
->knob_top
,
217 data
->knob_left
, data
->knob_top
+ data
->knob_height
- 1);
218 RectFill(rp
, data
->knob_left
+ 1, data
->knob_top
,
219 data
->knob_left
+ data
->knob_width
- 1, data
->knob_top
);
220 SetAPen(rp
, _pens(obj
)[MPEN_SHADOW
]);
221 RectFill(rp
, data
->knob_left
+ data
->knob_width
- 1, data
->knob_top
+ 1,
222 data
->knob_left
+ data
->knob_width
- 1, data
->knob_top
+ data
->knob_height
- 1);
223 RectFill(rp
, data
->knob_left
+ 1, data
->knob_top
+ data
->knob_height
- 1,
224 data
->knob_left
+ data
->knob_width
- 2, data
->knob_top
+ data
->knob_height
- 1);
228 #warning "Ugly hack?"
230 struct IBox old_mad_Box
= muiAreaData(obj
)->mad_Box
;
232 muiAreaData(obj
)->mad_Box
.Left
= data
->knob_left
+ 1;
233 muiAreaData(obj
)->mad_Box
.Top
= data
->knob_top
+ 1;
234 muiAreaData(obj
)->mad_Box
.Width
= data
->knob_width
- 2;
235 muiAreaData(obj
)->mad_Box
.Height
= data
->knob_height
- 2;
237 zune_imspec_draw(data
->knob_bg
, muiRenderInfo(obj
),
240 data
->knob_width
- 2,
241 data
->knob_height
- 2,
246 muiAreaData(obj
)->mad_Box
= old_mad_Box
;
250 SetAPen(rp
, _pens(obj
)[MPEN_BACKGROUND
]);
251 RectFill(rp
, data
->knob_left
+ 1, data
->knob_top
+ 1,
252 data
->knob_left
+ data
->knob_width
- 2,
253 data
->knob_top
+ data
->knob_height
- 2);
256 SetFont(rp
, _font(obj
));
258 text
= (STRPTR
)DoMethod(obj
, MUIM_Numeric_Stringify
, val
);
259 textlen
= strlen(text
);
260 pixellen
= TextLength(_rp(obj
), text
, textlen
);
262 SetAPen(rp
, _pens(obj
)[MPEN_TEXT
]);
263 Move(rp
, data
->knob_left
+ 2 + (data
->knob_width
- 4 - pixellen
) / 2,
264 data
->knob_top
+ 1 + rp
->TxBaseline
);
265 Text(rp
, text
, textlen
);
267 SetAPen(rp
, _pens(obj
)[MPEN_BACKGROUND
]);
269 if (data
->knob_left
- 1 >= data
->pop_innerx
)
271 RectFill(rp
, data
->pop_innerx
, data
->pop_innery
,
272 data
->knob_left
- 1, data
->pop_innery
+ data
->pop_innerh
- 1);
275 x
= data
->knob_left
+ data
->knob_width
;
276 if (x
<= data
->pop_innerx
+ data
->pop_innerw
- 1)
278 RectFill(rp
, x
, data
->pop_innery
,
279 data
->pop_innerx
+ data
->pop_innerw
- 1,
280 data
->pop_innery
+ data
->pop_innerh
- 1);
286 static void KillPopupWin(Object
*obj
, struct Numericbutton_DATA
*data
)
290 CloseWindow(data
->popwin
);
294 if (data
->ehn
.ehn_Events
& IDCMP_MOUSEMOVE
)
296 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
297 data
->ehn
.ehn_Events
&= ~IDCMP_MOUSEMOVE
;
298 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
303 static BOOL
MakePopupWin(Object
*obj
, struct Numericbutton_DATA
*data
)
305 const struct ZuneFrameGfx
*zframe
;
306 struct RastPort
*rp
, *saverp
;
307 LONG winx
, winy
, winw
, winh
;
311 zframe
= zune_zframe_get_with_state(obj
, &muiGlobalInfo(obj
)->mgi_Prefs
->frames
[MUIV_Frame_Slider
],
312 muiGlobalInfo(obj
)->mgi_Prefs
->frames
[MUIV_Frame_Slider
].state
);
314 data
->pop_innerx
= zframe
->ileft
;
315 data
->pop_innery
= zframe
->itop
;
317 data
->knob_width
= data
->max_text_width
+ 4;
318 data
->knob_height
= data
->text_height
+ 2;
320 framew
= data
->pop_innerx
+ zframe
->iright
;
321 frameh
= data
->pop_innery
+ zframe
->ibottom
;
323 longget(obj
, MUIA_Numeric_Min
, &min
);
324 longget(obj
, MUIA_Numeric_Max
, &max
);
326 winw
= max
- min
+ data
->knob_width
+ framew
;
327 winh
= data
->knob_height
+ frameh
;
329 if (winw
> _screen(obj
)->Width
)
331 winw
= _screen(obj
)->Width
;
334 if ((winw
< data
->knob_width
+ framew
) || (winh
> _screen(obj
)->Height
))
339 data
->pop_innerw
= winw
- framew
;
340 data
->pop_innerh
= winh
- frameh
;
342 data
->knob_left
= DoMethod(obj
, MUIM_Numeric_ValueToScale
, 0, data
->pop_innerw
- data
->knob_width
);
344 winx
= _window(obj
)->LeftEdge
+ _mleft(obj
) -
345 data
->pop_innerx
- 2 -
347 winy
= _window(obj
)->TopEdge
+ _mtop(obj
) - 1-
350 data
->popwin
= OpenWindowTags(NULL
, WA_CustomScreen
, (IPTR
)_screen(obj
),
358 WA_BackFill
, (IPTR
)LAYERS_NOBACKFILL
,
366 rp
= data
->popwin
->RPort
;
370 zframe
->draw(zframe
->customframe
, muiRenderInfo(obj
), 0, 0, winw
, winh
, 0, 0, winw
, winh
);
372 DrawKnob(obj
, data
, TRUE
);
381 /**************************************************************************
383 **************************************************************************/
384 IPTR
Numericbutton__MUIM_Show(struct IClass
*cl
, Object
*obj
, struct MUIP_Show
*msg
)
386 struct Numericbutton_DATA
*data
= INST_DATA(cl
, obj
);
389 retval
= DoSuperMethodA(cl
, obj
, (Msg
)msg
);
392 zune_imspec_show(data
->knob_bg
, obj
);
397 /**************************************************************************
399 **************************************************************************/
400 IPTR
Numericbutton__MUIM_Hide(struct IClass
*cl
, Object
*obj
, struct MUIP_Hide
*msg
)
402 struct Numericbutton_DATA
*data
= INST_DATA(cl
, obj
);
406 KillPopupWin(obj
, data
);
410 zune_imspec_hide(data
->knob_bg
);
412 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
416 /**************************************************************************
418 **************************************************************************/
419 IPTR
Numericbutton__MUIM_Draw(struct IClass
*cl
, Object
*obj
, struct MUIP_Draw
*msg
)
425 DoSuperMethodA(cl
,obj
,(Msg
)msg
);
427 if (!(msg
->flags
& (MADF_DRAWOBJECT
| MADF_DRAWUPDATE
)))
430 DoMethod(obj
,MUIM_DrawBackground
,_mleft(obj
),_mtop(obj
),_mwidth(obj
),_mheight(obj
),
431 _mleft(obj
),_mtop(obj
),0);
433 SetFont(_rp(obj
),_font(obj
));
434 SetABPenDrMd(_rp(obj
),_pens(obj
)[MPEN_TEXT
],_pens(obj
)[MPEN_BACKGROUND
],JAM1
);
436 get(obj
, MUIA_Numeric_Value
, &val
);
437 buf
= (char*)DoMethod(obj
,MUIM_Numeric_Stringify
,val
);
438 width
= TextLength(_rp(obj
),buf
,strlen(buf
));
440 Move(_rp(obj
), _mleft(obj
) + (_mwidth(obj
) - width
) / 2,
441 _mtop(obj
) + _font(obj
)->tf_Baseline
);
443 Text(_rp(obj
), buf
, strlen(buf
));
448 /**************************************************************************
450 **************************************************************************/
451 IPTR
Numericbutton__MUIM_HandleEvent(struct IClass
*cl
, Object
*obj
, struct MUIP_HandleEvent
*msg
)
453 struct Numericbutton_DATA
*data
= INST_DATA(cl
, obj
);
460 switch(msg
->imsg
->Class
)
462 case IDCMP_MOUSEBUTTONS
:
463 switch(msg
->imsg
->Code
)
466 if (_between(_left(obj
), msg
->imsg
->MouseX
, _right(obj
)) &&
467 _between(_top(obj
), msg
->imsg
->MouseY
, _bottom(obj
)) &&
468 (muiAreaData(obj
)->mad_Flags
& MADF_CANDRAW
) &&
471 data
->knob_clickoffset_x
= msg
->imsg
->MouseX
- _mleft(obj
);
473 if (MakePopupWin(obj
, data
))
475 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
476 data
->ehn
.ehn_Events
|= IDCMP_MOUSEMOVE
;
477 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
490 KillPopupWin(obj
, data
);
491 if ((msg
->imsg
->Code
== SELECTUP
))
493 set(obj
, MUIA_Numeric_Value
, data
->knob_val
);
500 } /* switch(msg->imsg->Code) */
503 case IDCMP_MOUSEMOVE
:
506 DrawKnob(obj
, data
, FALSE
);
512 } /* switch(msg->imsg->Class) */
518 #if ZUNE_BUILTIN_NUMERICBUTTON
519 BOOPSI_DISPATCHER(IPTR
, Numericbutton_Dispatcher
, cl
, obj
, msg
)
521 switch (msg
->MethodID
)
523 case OM_NEW
: return Numericbutton__OM_NEW(cl
, obj
, (struct opSet
*)msg
);
524 case OM_SET
: return Numericbutton__OM_SET(cl
, obj
, (struct opSet
*)msg
);
526 case MUIM_Setup
: return Numericbutton__MUIM_Setup(cl
, obj
, (struct MUIP_Setup
*)msg
);
527 case MUIM_Cleanup
: return Numericbutton__MUIM_Cleanup(cl
, obj
, (struct MUIP_Cleanup
*)msg
);
528 case MUIM_Show
: return Numericbutton__MUIM_Show(cl
, obj
, (struct MUIP_Show
*)msg
);
529 case MUIM_Hide
: return Numericbutton__MUIM_Hide(cl
, obj
, (struct MUIP_Hide
*)msg
);
530 case MUIM_AskMinMax
: return Numericbutton__MUIM_AskMinMax(cl
, obj
, (struct MUIP_AskMinMax
*)msg
);
531 case MUIM_Draw
: return Numericbutton__MUIM_Draw(cl
, obj
, (struct MUIP_Draw
*)msg
);
532 case MUIM_HandleEvent
: return Numericbutton__MUIM_HandleEvent(cl
, obj
, (struct MUIP_HandleEvent
*)msg
);
533 default: return DoSuperMethodA(cl
, obj
, msg
);
536 BOOPSI_DISPATCHER_END
538 const struct __MUIBuiltinClass _MUI_Numericbutton_desc
=
542 sizeof(struct Numericbutton_DATA
),
543 (void*)Numericbutton_Dispatcher
545 #endif /* ZUNE_BUILTIN_NUMERICBUTTON */