2 Copyright © 2002-2006, The AROS Development Team. All rights reserved.
8 #include <clib/alib_protos.h>
9 #include <proto/exec.h>
10 #include <proto/intuition.h>
11 #include <proto/graphics.h>
12 #include <proto/utility.h>
13 #include <proto/muimaster.h>
17 #include "muimaster_intern.h"
20 struct MUI_NumericData
28 struct MUI_EventHandlerNode ehn
;
34 NUMERIC_REVERSE
= (1 << 0),
35 NUMERIC_REVLEFTRIGHT
= (1 << 1),
36 NUMERIC_REVUPDOWN
= (1 << 2),
37 NUMERIC_CHECKALLSIZES
= (1 << 3),
40 extern struct Library
*MUIMasterBase
;
42 /**************************************************************************
44 **************************************************************************/
45 IPTR
Numeric__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
47 struct MUI_NumericData
*data
;
48 struct TagItem
*tags
, *tag
;
50 BOOL value_set
= FALSE
;
52 obj
= (Object
*) DoSuperMethodA(cl
, obj
, (Msg
) msg
);
56 data
= INST_DATA(cl
, obj
);
62 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
));)
66 case MUIA_Numeric_CheckAllSizes
:
67 _handle_bool_tag(data
->flags
, tag
->ti_Data
,
68 NUMERIC_CHECKALLSIZES
);
70 case MUIA_Numeric_Default
:
71 /* data->defvalue = CLAMP(tag->ti_Data, data->min, data->max); */
72 data
->defvalue
= tag
->ti_Data
;
74 case MUIA_Numeric_Format
:
75 data
->format
= (STRPTR
) tag
->ti_Data
;
77 case MUIA_Numeric_Max
:
78 data
->max
= tag
->ti_Data
;
80 case MUIA_Numeric_Min
:
81 data
->min
= tag
->ti_Data
;
83 case MUIA_Numeric_Reverse
:
84 _handle_bool_tag(data
->flags
, tag
->ti_Data
, NUMERIC_REVERSE
);
86 case MUIA_Numeric_RevLeftRight
:
87 _handle_bool_tag(data
->flags
, tag
->ti_Data
,
88 NUMERIC_REVLEFTRIGHT
);
90 case MUIA_Numeric_RevUpDown
:
91 _handle_bool_tag(data
->flags
, tag
->ti_Data
, NUMERIC_REVUPDOWN
);
93 case MUIA_Numeric_Value
:
95 data
->value
= (LONG
) tag
->ti_Data
;
101 CLAMP(value_set
? data
->value
: data
->defvalue
, data
->min
,
107 /**************************************************************************
109 **************************************************************************/
110 IPTR
Numeric__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
112 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
113 struct TagItem
*tags
, *tag
;
114 LONG oldval
, oldmin
, oldmax
;
117 BOOL values_changed
= FALSE
;
119 oldval
= data
->value
;
120 oldfmt
= data
->format
;
124 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
));)
128 case MUIA_Numeric_CheckAllSizes
:
129 _handle_bool_tag(data
->flags
, tag
->ti_Data
,
130 NUMERIC_CHECKALLSIZES
);
132 case MUIA_Numeric_Default
:
133 /* data->defvalue = CLAMP(tag->ti_Data, data->min, data->max); */
134 data
->defvalue
= tag
->ti_Data
;
136 case MUIA_Numeric_Format
:
137 data
->format
= (STRPTR
) tag
->ti_Data
;
139 case MUIA_Numeric_Max
:
140 data
->max
= tag
->ti_Data
;
142 case MUIA_Numeric_Min
:
143 data
->min
= tag
->ti_Data
;
145 case MUIA_Numeric_Reverse
:
146 _handle_bool_tag(data
->flags
, tag
->ti_Data
, NUMERIC_REVERSE
);
148 case MUIA_Numeric_RevLeftRight
:
149 _handle_bool_tag(data
->flags
, tag
->ti_Data
,
150 NUMERIC_REVLEFTRIGHT
);
152 case MUIA_Numeric_RevUpDown
:
153 _handle_bool_tag(data
->flags
, tag
->ti_Data
, NUMERIC_REVUPDOWN
);
155 case MUIA_Numeric_Value
:
156 tag
->ti_Data
= CLAMP((LONG
) tag
->ti_Data
, data
->min
, data
->max
);
158 if (data
->value
== (LONG
) tag
->ti_Data
)
159 tag
->ti_Tag
= TAG_IGNORE
;
161 data
->value
= (LONG
) tag
->ti_Data
;
167 /* If the max, min or format values changed, then the minimum and maximum
168 sizes of the string output by MUIM_Numeric_Stringify may have changed,
169 so give the subclass a chance to recalculate them and relayout the group
170 accordingly. Basically, the subclass will have to react on changes to
171 these values as well (by setting a notification on them, or by
172 overriding OM_SET) and then recalculate the minimum and maximum sizes
174 if (data
->format
!= oldfmt
|| data
->min
!= oldmin
175 || data
->max
!= oldmax
)
177 values_changed
= TRUE
;
178 Object
*parent
= _parent(obj
);
181 DoMethod(parent
, MUIM_Group_InitChange
);
182 DoMethod(parent
, MUIM_Group_ExitChange
);
186 ret
= DoSuperMethodA(cl
, obj
, (Msg
) msg
);
188 if (data
->value
!= oldval
|| values_changed
)
190 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
196 /**************************************************************************
198 **************************************************************************/
199 IPTR
Numeric__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
201 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
202 IPTR
*store
= msg
->opg_Storage
;
203 ULONG tag
= msg
->opg_AttrID
;
207 case MUIA_Numeric_CheckAllSizes
:
208 *store
= ((data
->flags
& NUMERIC_CHECKALLSIZES
) != 0);
211 case MUIA_Numeric_Default
:
212 *store
= data
->defvalue
;
215 case MUIA_Numeric_Format
:
216 *store
= (IPTR
) data
->format
;
219 case MUIA_Numeric_Max
:
223 case MUIA_Numeric_Min
:
227 case MUIA_Numeric_Reverse
:
228 *store
= ((data
->flags
& NUMERIC_REVERSE
) != 0);
231 case MUIA_Numeric_RevLeftRight
:
232 *store
= ((data
->flags
& NUMERIC_REVLEFTRIGHT
) != 0);
235 case MUIA_Numeric_RevUpDown
:
236 *store
= ((data
->flags
& NUMERIC_REVUPDOWN
) != 0);
239 case MUIA_Numeric_Value
:
240 *store
= data
->value
;
244 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
247 /**************************************************************************
249 **************************************************************************/
250 IPTR
Numeric__MUIM_Setup(struct IClass
*cl
, Object
*obj
,
251 struct MUIP_Setup
*msg
)
253 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
255 if (!DoSuperMethodA(cl
, obj
, (Msg
) msg
))
258 data
->ehn
.ehn_Events
= IDCMP_RAWKEY
;
259 data
->ehn
.ehn_Priority
= 0;
260 data
->ehn
.ehn_Flags
= 0;
261 data
->ehn
.ehn_Object
= obj
;
262 data
->ehn
.ehn_Class
= cl
;
263 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
) (&data
->ehn
));
268 /**************************************************************************
270 **************************************************************************/
271 IPTR
Numeric__MUIM_Cleanup(struct IClass
*cl
, Object
*obj
,
272 struct MUIP_Cleanup
*msg
)
274 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
276 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
) (&data
->ehn
));
277 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
280 /**************************************************************************
282 **************************************************************************/
283 IPTR
Numeric__MUIM_HandleEvent(struct IClass
*cl
, Object
*obj
,
284 struct MUIP_HandleEvent
*msg
)
286 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
288 if (msg
->muikey
!= MUIKEY_NONE
)
292 if (data
->max
- data
->min
< 10)
300 return MUI_EventHandlerRC_Eat
;
303 DoMethod(obj
, MUIM_Numeric_SetDefault
);
304 return MUI_EventHandlerRC_Eat
;
307 return MUI_EventHandlerRC_Eat
;
311 if (data
->flags
& NUMERIC_REVUPDOWN
)
312 set(obj
, MUIA_Numeric_Value
, data
->min
);
314 set(obj
, MUIA_Numeric_Value
, data
->max
);
315 return MUI_EventHandlerRC_Eat
;
318 case MUIKEY_LINESTART
:
319 if (data
->flags
& NUMERIC_REVUPDOWN
)
320 set(obj
, MUIA_Numeric_Value
, data
->max
);
322 set(obj
, MUIA_Numeric_Value
, data
->min
);
323 return MUI_EventHandlerRC_Eat
;
326 if (data
->flags
& NUMERIC_REVLEFTRIGHT
)
327 DoMethod(obj
, MUIM_Numeric_Increase
, 1);
329 DoMethod(obj
, MUIM_Numeric_Decrease
, 1);
330 return MUI_EventHandlerRC_Eat
;
333 if (data
->flags
& NUMERIC_REVLEFTRIGHT
)
334 DoMethod(obj
, MUIM_Numeric_Decrease
, 1);
336 DoMethod(obj
, MUIM_Numeric_Increase
, 1);
337 return MUI_EventHandlerRC_Eat
;
340 if (data
->flags
& NUMERIC_REVUPDOWN
)
341 DoMethod(obj
, MUIM_Numeric_Increase
, 1);
343 DoMethod(obj
, MUIM_Numeric_Decrease
, 1);
344 return MUI_EventHandlerRC_Eat
;
347 if (data
->flags
& NUMERIC_REVUPDOWN
)
348 DoMethod(obj
, MUIM_Numeric_Decrease
, 1);
350 DoMethod(obj
, MUIM_Numeric_Increase
, 1);
351 return MUI_EventHandlerRC_Eat
;
353 case MUIKEY_PAGEDOWN
:
354 case MUIKEY_WORDRIGHT
:
355 if (data
->flags
& NUMERIC_REVUPDOWN
)
356 DoMethod(obj
, MUIM_Numeric_Decrease
, step
);
358 DoMethod(obj
, MUIM_Numeric_Increase
, step
);
359 return MUI_EventHandlerRC_Eat
;
362 case MUIKEY_WORDLEFT
:
363 if (data
->flags
& NUMERIC_REVUPDOWN
)
364 DoMethod(obj
, MUIM_Numeric_Increase
, step
);
366 DoMethod(obj
, MUIM_Numeric_Decrease
, step
);
367 return MUI_EventHandlerRC_Eat
;
378 /**************************************************************************
379 MUIM_Numeric_Decrease
380 **************************************************************************/
381 IPTR
Numeric__MUIM_Decrease(struct IClass
*cl
, Object
*obj
,
382 struct MUIP_Numeric_Decrease
*msg
)
384 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
385 LONG newval
= CLAMP(data
->value
- msg
->amount
, data
->min
, data
->max
);
386 if (newval
!= data
->value
)
387 set(obj
, MUIA_Numeric_Value
, newval
);
392 /**************************************************************************
393 MUIM_Numeric_Increase
394 **************************************************************************/
395 IPTR
Numeric__MUIM_Increase(struct IClass
*cl
, Object
*obj
,
396 struct MUIP_Numeric_Increase
*msg
)
398 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
399 LONG newval
= CLAMP(data
->value
+ msg
->amount
, data
->min
, data
->max
);
401 if (newval
!= data
->value
)
402 set(obj
, MUIA_Numeric_Value
, newval
);
408 /**************************************************************************
409 MUIM_Numeric_ScaleToValue
410 **************************************************************************/
411 IPTR
Numeric__MUIM_ScaleToValue(struct IClass
*cl
, Object
*obj
,
412 struct MUIP_Numeric_ScaleToValue
*msg
)
414 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
419 min
= (data
->flags
& NUMERIC_REVERSE
) ? data
->max
: data
->min
;
420 max
= (data
->flags
& NUMERIC_REVERSE
) ? data
->min
: data
->max
;
422 val
= CLAMP(msg
->scale
- msg
->scalemin
, msg
->scalemin
, msg
->scalemax
);
423 d
= msg
->scalemax
- msg
->scalemin
;
425 // FIXME: watch out for overflow here.
426 val
= val
* (max
- min
);
436 /**************************************************************************
437 MUIM_Numeric_SetDefault
438 **************************************************************************/
439 IPTR
Numeric__MUIM_SetDefault(struct IClass
*cl
, Object
*obj
, Msg msg
)
441 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
443 set(obj
, MUIA_Numeric_Value
, CLAMP(data
->defvalue
, data
->min
,
449 /**************************************************************************
450 MUIM_Numeric_Stringify
451 **************************************************************************/
452 IPTR
Numeric__MUIM_Stringify(struct IClass
*cl
, Object
*obj
,
453 struct MUIP_Numeric_Stringify
*msg
)
455 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
457 /* TODO: use RawDoFmt() and buffer overrun */
458 snprintf(data
->buf
, 49, data
->format
, (long)msg
->value
);
461 return (IPTR
) data
->buf
;
464 /**************************************************************************
465 MUIM_Numeric_ValueToScale
466 **************************************************************************/
467 IPTR
Numeric__MUIM_ValueToScale(struct IClass
*cl
, Object
*obj
,
468 struct MUIP_Numeric_ValueToScale
*msg
)
471 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
474 min
= (data
->flags
& NUMERIC_REVERSE
) ? msg
->scalemax
: msg
->scalemin
;
475 max
= (data
->flags
& NUMERIC_REVERSE
) ? msg
->scalemin
: msg
->scalemax
;
477 if (data
->max
!= data
->min
)
480 min
+ ((data
->value
- data
->min
) * (max
- min
) + (data
->max
-
481 data
->min
) / 2) / (data
->max
- data
->min
);
488 val
= CLAMP(val
, min
, max
);
493 /**************************************************************************
494 MUIM_Numeric_ValueToScaleExt
495 **************************************************************************/
496 IPTR
Numeric__MUIM_ValueToScaleExt(struct IClass
*cl
, Object
*obj
,
497 struct MUIP_Numeric_ValueToScaleExt
*msg
)
501 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
504 value
= CLAMP(msg
->value
, data
->min
, data
->max
);
505 min
= (data
->flags
& NUMERIC_REVERSE
) ? msg
->scalemax
: msg
->scalemin
;
506 max
= (data
->flags
& NUMERIC_REVERSE
) ? msg
->scalemin
: msg
->scalemax
;
508 if (data
->max
!= data
->min
)
511 min
+ ((value
- data
->min
) * (max
- min
) + (data
->max
-
512 data
->min
) / 2) / (data
->max
- data
->min
);
519 scale
= CLAMP(scale
, min
, max
);
524 /**************************************************************************
525 MUIM_Export - to export an objects "contents" to a dataspace object.
526 **************************************************************************/
527 IPTR
Numeric__MUIM_Export(struct IClass
*cl
, Object
*obj
,
528 struct MUIP_Export
*msg
)
530 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
533 if ((id
= muiNotifyData(obj
)->mnd_ObjectID
))
535 LONG value
= data
->value
;
536 DoMethod(msg
->dataspace
, MUIM_Dataspace_Add
,
537 (IPTR
) & value
, sizeof(value
), (IPTR
) id
);
542 /**************************************************************************
543 MUIM_Import - to import an object's "contents" from a dataspace object.
544 **************************************************************************/
545 IPTR
Numeric__MUIM_Import(struct IClass
*cl
, Object
*obj
,
546 struct MUIP_Import
*msg
)
551 if ((id
= muiNotifyData(obj
)->mnd_ObjectID
))
553 if ((s
= (LONG
*) DoMethod(msg
->dataspace
, MUIM_Dataspace_Find
,
556 set(obj
, MUIA_Numeric_Value
, *s
);
564 BOOPSI_DISPATCHER(IPTR
, Numeric_Dispatcher
, cl
, obj
, msg
)
566 switch (msg
->MethodID
)
569 return Numeric__OM_NEW(cl
, obj
, (APTR
) msg
);
571 return Numeric__OM_SET(cl
, obj
, (APTR
) msg
);
573 return Numeric__OM_GET(cl
, obj
, (APTR
) msg
);
576 return Numeric__MUIM_Setup(cl
, obj
, (APTR
) msg
);
578 return Numeric__MUIM_Cleanup(cl
, obj
, (APTR
) msg
);
579 case MUIM_HandleEvent
:
580 return Numeric__MUIM_HandleEvent(cl
, obj
, (APTR
) msg
);
581 case MUIM_Numeric_Decrease
:
582 return Numeric__MUIM_Decrease(cl
, obj
, (APTR
) msg
);
583 case MUIM_Numeric_Increase
:
584 return Numeric__MUIM_Increase(cl
, obj
, (APTR
) msg
);
585 case MUIM_Numeric_ScaleToValue
:
586 return Numeric__MUIM_ScaleToValue(cl
, obj
, (APTR
) msg
);
587 case MUIM_Numeric_SetDefault
:
588 return Numeric__MUIM_SetDefault(cl
, obj
, (APTR
) msg
);
589 case MUIM_Numeric_Stringify
:
590 return Numeric__MUIM_Stringify(cl
, obj
, (APTR
) msg
);
591 case MUIM_Numeric_ValueToScale
:
592 return Numeric__MUIM_ValueToScale(cl
, obj
, (APTR
) msg
);
593 case MUIM_Numeric_ValueToScaleExt
:
594 return Numeric__MUIM_ValueToScaleExt(cl
, obj
, (APTR
) msg
);
596 return Numeric__MUIM_Export(cl
, obj
, (APTR
) msg
);
598 return Numeric__MUIM_Import(cl
, obj
, (APTR
) msg
);
601 return DoSuperMethodA(cl
, obj
, msg
);
603 BOOPSI_DISPATCHER_END
608 const struct __MUIBuiltinClass _MUI_Numeric_desc
=
612 sizeof(struct MUI_NumericData
),
613 (void *) Numeric_Dispatcher