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
,
43 obj
= (Object
*) DoSuperNewTags(cl
, obj
, NULL
,
44 MUIA_Background
, MUII_ButtonBack
,
45 MUIA_Frame
, MUIV_Frame_Button
,
46 TAG_MORE
, (IPTR
) msg
->ops_AttrList
);
50 struct Numericbutton_DATA
*data
= INST_DATA(cl
, obj
);
52 data
->ehn
.ehn_Events
= IDCMP_MOUSEBUTTONS
;
53 data
->ehn
.ehn_Priority
= 0;
54 data
->ehn
.ehn_Flags
= 0;
55 data
->ehn
.ehn_Object
= obj
;
56 data
->ehn
.ehn_Class
= cl
;
62 /**************************************************************************
64 **************************************************************************/
65 static ULONG
Numericbutton__OM_SET(struct IClass
*cl
, Object
*obj
,
68 struct Numericbutton_DATA
*data
= INST_DATA(cl
, obj
);
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
,
95 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,
105 // &muiGlobalInfo(obj)->mgi_Prefs->frames[MUIV_Frame_Knob]);
108 zune_imspec_setup(MUII_ButtonBack
, muiRenderInfo(obj
));
110 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
,
113 data
->needs_to_recalculate_sizes
= TRUE
;
119 IPTR
Numericbutton__MUIM_Cleanup(struct IClass
*cl
, Object
*obj
,
120 struct MUIP_Cleanup
*msg
)
122 struct Numericbutton_DATA
*data
= INST_DATA(cl
, obj
);
126 zune_imspec_cleanup(data
->knob_bg
);
127 data
->knob_bg
= NULL
;
130 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
) & data
->ehn
);
132 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
135 /**************************************************************************
137 **************************************************************************/
138 IPTR
Numericbutton__MUIM_AskMinMax(struct IClass
*cl
, Object
*obj
,
139 struct MUIP_AskMinMax
*msg
)
141 struct Numericbutton_DATA
*data
= INST_DATA(cl
, obj
);
143 DoSuperMethodA(cl
, obj
, (Msg
) msg
);
145 if (data
->needs_to_recalculate_sizes
)
148 LONG min
= 0, max
= 0, val
, width
;
151 SetFont(&rp
, _font(obj
));
155 longget(obj
, MUIA_Numeric_Min
, &min
);
156 longget(obj
, MUIA_Numeric_Max
, &max
);
158 /* Determine the width of the knob */
159 for (val
= min
; val
<= max
; val
++)
164 buf
= (char *)DoMethod(obj
, MUIM_Numeric_Stringify
, val
);
165 nw
= TextLength(&rp
, buf
, strlen(buf
));
171 data
->max_text_width
= width
;
172 data
->text_height
= _font(obj
)->tf_YSize
;
174 data
->needs_to_recalculate_sizes
= FALSE
;
177 msg
->MinMaxInfo
->MinWidth
+= data
->max_text_width
;
178 msg
->MinMaxInfo
->MinHeight
+= data
->text_height
;
179 msg
->MinMaxInfo
->DefWidth
+= data
->max_text_width
;
180 msg
->MinMaxInfo
->DefHeight
+= data
->text_height
;
181 msg
->MinMaxInfo
->MaxWidth
+= data
->max_text_width
;
182 msg
->MinMaxInfo
->MaxHeight
+= data
->text_height
;
187 static void DrawKnob(Object
*obj
, struct Numericbutton_DATA
*data
,
190 struct RastPort
*rp
, *saverp
;
191 LONG x
, val
, pixeloffset
, textlen
, pixellen
;
195 data
->popwin
->MouseX
- data
->pop_innerx
- 2 -
196 data
->knob_clickoffset_x
;
198 val
= DoMethod(obj
, MUIM_Numeric_ScaleToValue
, 0,
199 data
->pop_innerw
- data
->knob_width
, pixeloffset
);
201 data
->knob_left
= data
->pop_innerx
+ pixeloffset
;
202 data
->knob_top
= data
->pop_innery
;
203 data
->knob_val
= val
;
205 if (!force
&& (data
->knob_left
== data
->knob_prev_left
))
209 data
->knob_prev_left
= data
->knob_left
;
211 if (data
->knob_left
< data
->pop_innerx
)
213 data
->knob_left
= data
->pop_innerx
;
215 else if (data
->knob_left
>
216 data
->pop_innerx
+ data
->pop_innerw
- data
->knob_width
)
219 data
->pop_innerx
+ data
->pop_innerw
- data
->knob_width
;
223 _rp(obj
) = rp
= data
->popwin
->RPort
;
225 SetABPenDrMd(rp
, _pens(obj
)[MPEN_SHINE
], 0, JAM1
);
226 RectFill(rp
, data
->knob_left
, data
->knob_top
,
227 data
->knob_left
, data
->knob_top
+ data
->knob_height
- 1);
228 RectFill(rp
, data
->knob_left
+ 1, data
->knob_top
,
229 data
->knob_left
+ data
->knob_width
- 1, data
->knob_top
);
230 SetAPen(rp
, _pens(obj
)[MPEN_SHADOW
]);
231 RectFill(rp
, data
->knob_left
+ data
->knob_width
- 1, data
->knob_top
+ 1,
232 data
->knob_left
+ data
->knob_width
- 1,
233 data
->knob_top
+ data
->knob_height
- 1);
234 RectFill(rp
, data
->knob_left
+ 1,
235 data
->knob_top
+ data
->knob_height
- 1,
236 data
->knob_left
+ data
->knob_width
- 2,
237 data
->knob_top
+ data
->knob_height
- 1);
243 struct IBox old_mad_Box
= muiAreaData(obj
)->mad_Box
;
245 muiAreaData(obj
)->mad_Box
.Left
= data
->knob_left
+ 1;
246 muiAreaData(obj
)->mad_Box
.Top
= data
->knob_top
+ 1;
247 muiAreaData(obj
)->mad_Box
.Width
= data
->knob_width
- 2;
248 muiAreaData(obj
)->mad_Box
.Height
= data
->knob_height
- 2;
250 zune_imspec_draw(data
->knob_bg
, muiRenderInfo(obj
),
253 data
->knob_width
- 2, data
->knob_height
- 2, 0, 0, 0);
255 muiAreaData(obj
)->mad_Box
= old_mad_Box
;
259 SetAPen(rp
, _pens(obj
)[MPEN_BACKGROUND
]);
260 RectFill(rp
, data
->knob_left
+ 1, data
->knob_top
+ 1,
261 data
->knob_left
+ data
->knob_width
- 2,
262 data
->knob_top
+ data
->knob_height
- 2);
265 SetFont(rp
, _font(obj
));
267 text
= (STRPTR
) DoMethod(obj
, MUIM_Numeric_Stringify
, val
);
268 textlen
= strlen(text
);
269 pixellen
= TextLength(_rp(obj
), text
, textlen
);
271 SetAPen(rp
, _pens(obj
)[MPEN_TEXT
]);
272 Move(rp
, data
->knob_left
+ 2 + (data
->knob_width
- 4 - pixellen
) / 2,
273 data
->knob_top
+ 1 + rp
->TxBaseline
);
274 Text(rp
, text
, textlen
);
276 SetAPen(rp
, _pens(obj
)[MPEN_BACKGROUND
]);
278 if (data
->knob_left
- 1 >= data
->pop_innerx
)
280 RectFill(rp
, data
->pop_innerx
, data
->pop_innery
,
281 data
->knob_left
- 1, data
->pop_innery
+ data
->pop_innerh
- 1);
284 x
= data
->knob_left
+ data
->knob_width
;
285 if (x
<= data
->pop_innerx
+ data
->pop_innerw
- 1)
287 RectFill(rp
, x
, data
->pop_innery
,
288 data
->pop_innerx
+ data
->pop_innerw
- 1,
289 data
->pop_innery
+ data
->pop_innerh
- 1);
295 static void KillPopupWin(Object
*obj
, struct Numericbutton_DATA
*data
)
299 CloseWindow(data
->popwin
);
303 if (data
->ehn
.ehn_Events
& IDCMP_MOUSEMOVE
)
305 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
,
307 data
->ehn
.ehn_Events
&= ~IDCMP_MOUSEMOVE
;
308 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
,
314 static BOOL
MakePopupWin(Object
*obj
, struct Numericbutton_DATA
*data
)
316 const struct ZuneFrameGfx
*zframe
;
317 struct RastPort
*rp
, *saverp
;
318 LONG winx
, winy
, winw
, winh
;
320 LONG min
= 0, max
= 0;
323 zune_zframe_get_with_state(obj
,
324 &muiGlobalInfo(obj
)->mgi_Prefs
->frames
[MUIV_Frame_Slider
],
325 muiGlobalInfo(obj
)->mgi_Prefs
->frames
[MUIV_Frame_Slider
].state
);
327 data
->pop_innerx
= zframe
->ileft
;
328 data
->pop_innery
= zframe
->itop
;
330 data
->knob_width
= data
->max_text_width
+ 4;
331 data
->knob_height
= data
->text_height
+ 2;
333 framew
= data
->pop_innerx
+ zframe
->iright
;
334 frameh
= data
->pop_innery
+ zframe
->ibottom
;
336 longget(obj
, MUIA_Numeric_Min
, &min
);
337 longget(obj
, MUIA_Numeric_Max
, &max
);
339 winw
= max
- min
+ data
->knob_width
+ framew
;
340 winh
= data
->knob_height
+ frameh
;
342 if (winw
> _screen(obj
)->Width
)
344 winw
= _screen(obj
)->Width
;
347 if ((winw
< data
->knob_width
+ framew
) || (winh
> _screen(obj
)->Height
))
352 data
->pop_innerw
= winw
- framew
;
353 data
->pop_innerh
= winh
- frameh
;
356 DoMethod(obj
, MUIM_Numeric_ValueToScale
, 0,
357 data
->pop_innerw
- data
->knob_width
);
359 winx
= _window(obj
)->LeftEdge
+ _mleft(obj
) -
360 data
->pop_innerx
- 2 - data
->knob_left
;
361 winy
= _window(obj
)->TopEdge
+ _mtop(obj
) - 1 - data
->pop_innery
;
364 OpenWindowTags(NULL
, WA_CustomScreen
, (IPTR
) _screen(obj
), WA_Left
,
365 winx
, WA_Top
, winy
, WA_Width
, winw
, WA_Height
, winh
, WA_AutoAdjust
,
366 TRUE
, WA_Borderless
, TRUE
, WA_Activate
, FALSE
, WA_BackFill
,
367 (IPTR
) LAYERS_NOBACKFILL
, TAG_DONE
);
374 rp
= data
->popwin
->RPort
;
378 zframe
->draw(zframe
->customframe
, muiRenderInfo(obj
), 0, 0, winw
, winh
,
381 DrawKnob(obj
, data
, TRUE
);
390 /**************************************************************************
392 **************************************************************************/
393 IPTR
Numericbutton__MUIM_Show(struct IClass
*cl
, Object
*obj
,
394 struct MUIP_Show
*msg
)
396 struct Numericbutton_DATA
*data
= INST_DATA(cl
, obj
);
399 retval
= DoSuperMethodA(cl
, obj
, (Msg
) msg
);
402 zune_imspec_show(data
->knob_bg
, obj
);
407 /**************************************************************************
409 **************************************************************************/
410 IPTR
Numericbutton__MUIM_Hide(struct IClass
*cl
, Object
*obj
,
411 struct MUIP_Hide
*msg
)
413 struct Numericbutton_DATA
*data
= INST_DATA(cl
, obj
);
417 KillPopupWin(obj
, data
);
421 zune_imspec_hide(data
->knob_bg
);
423 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
427 /**************************************************************************
429 **************************************************************************/
430 IPTR
Numericbutton__MUIM_Draw(struct IClass
*cl
, Object
*obj
,
431 struct MUIP_Draw
*msg
)
437 DoSuperMethodA(cl
, obj
, (Msg
) msg
);
439 if (!(msg
->flags
& (MADF_DRAWOBJECT
| MADF_DRAWUPDATE
)))
442 DoMethod(obj
, MUIM_DrawBackground
, _mleft(obj
), _mtop(obj
),
443 _mwidth(obj
), _mheight(obj
), _mleft(obj
), _mtop(obj
), 0);
445 SetFont(_rp(obj
), _font(obj
));
446 SetABPenDrMd(_rp(obj
), _pens(obj
)[MPEN_TEXT
],
447 _pens(obj
)[MPEN_BACKGROUND
], JAM1
);
449 get(obj
, MUIA_Numeric_Value
, &val
);
450 buf
= (char *)DoMethod(obj
, MUIM_Numeric_Stringify
, val
);
451 width
= TextLength(_rp(obj
), buf
, strlen(buf
));
453 Move(_rp(obj
), _mleft(obj
) + (_mwidth(obj
) - width
) / 2,
454 _mtop(obj
) + _font(obj
)->tf_Baseline
);
456 Text(_rp(obj
), buf
, strlen(buf
));
461 /**************************************************************************
463 **************************************************************************/
464 IPTR
Numericbutton__MUIM_HandleEvent(struct IClass
*cl
, Object
*obj
,
465 struct MUIP_HandleEvent
*msg
)
467 struct Numericbutton_DATA
*data
= INST_DATA(cl
, obj
);
474 switch (msg
->imsg
->Class
)
476 case IDCMP_MOUSEBUTTONS
:
477 switch (msg
->imsg
->Code
)
480 if (_between(_left(obj
), msg
->imsg
->MouseX
, _right(obj
)) &&
481 _between(_top(obj
), msg
->imsg
->MouseY
, _bottom(obj
)) &&
482 (muiAreaData(obj
)->mad_Flags
& MADF_CANDRAW
) &&
485 data
->knob_clickoffset_x
= msg
->imsg
->MouseX
- _mleft(obj
);
487 if (MakePopupWin(obj
, data
))
489 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
,
491 data
->ehn
.ehn_Events
|= IDCMP_MOUSEMOVE
;
492 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
,
506 KillPopupWin(obj
, data
);
507 if ((msg
->imsg
->Code
== SELECTUP
))
509 set(obj
, MUIA_Numeric_Value
, data
->knob_val
);
516 } /* switch(msg->imsg->Code) */
519 case IDCMP_MOUSEMOVE
:
522 DrawKnob(obj
, data
, FALSE
);
528 } /* switch(msg->imsg->Class) */
534 #if ZUNE_BUILTIN_NUMERICBUTTON
535 BOOPSI_DISPATCHER(IPTR
, Numericbutton_Dispatcher
, cl
, obj
, msg
)
537 switch (msg
->MethodID
)
540 return Numericbutton__OM_NEW(cl
, obj
, (struct opSet
*)msg
);
542 return Numericbutton__OM_SET(cl
, obj
, (struct opSet
*)msg
);
545 return Numericbutton__MUIM_Setup(cl
, obj
, (struct MUIP_Setup
*)msg
);
547 return Numericbutton__MUIM_Cleanup(cl
, obj
,
548 (struct MUIP_Cleanup
*)msg
);
550 return Numericbutton__MUIM_Show(cl
, obj
, (struct MUIP_Show
*)msg
);
552 return Numericbutton__MUIM_Hide(cl
, obj
, (struct MUIP_Hide
*)msg
);
554 return Numericbutton__MUIM_AskMinMax(cl
, obj
,
555 (struct MUIP_AskMinMax
*)msg
);
557 return Numericbutton__MUIM_Draw(cl
, obj
, (struct MUIP_Draw
*)msg
);
558 case MUIM_HandleEvent
:
559 return Numericbutton__MUIM_HandleEvent(cl
, obj
,
560 (struct MUIP_HandleEvent
*)msg
);
562 return DoSuperMethodA(cl
, obj
, msg
);
565 BOOPSI_DISPATCHER_END
567 const struct __MUIBuiltinClass _MUI_Numericbutton_desc
=
571 sizeof(struct Numericbutton_DATA
),
572 (void *) Numericbutton_Dispatcher
574 #endif /* ZUNE_BUILTIN_NUMERICBUTTON */