2 Copyright © 2002-2013, The AROS Development Team. All rights reserved.
6 #include <devices/rawkeycodes.h>
9 #include <clib/alib_protos.h>
10 #include <proto/exec.h>
11 #include <proto/intuition.h>
12 #include <proto/graphics.h>
13 #include <proto/utility.h>
14 #include <proto/muimaster.h>
18 #include "muimaster_intern.h"
21 struct MUI_NumericData
29 struct MUI_EventHandlerNode ehn
;
35 NUMERIC_REVERSE
= (1 << 0),
36 NUMERIC_REVLEFTRIGHT
= (1 << 1),
37 NUMERIC_REVUPDOWN
= (1 << 2),
38 NUMERIC_CHECKALLSIZES
= (1 << 3),
41 extern struct Library
*MUIMasterBase
;
43 /**************************************************************************
45 **************************************************************************/
46 IPTR
Numeric__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
48 struct MUI_NumericData
*data
;
49 struct TagItem
*tags
, *tag
;
51 BOOL value_set
= FALSE
;
53 obj
= (Object
*) DoSuperMethodA(cl
, obj
, (Msg
) msg
);
57 data
= INST_DATA(cl
, obj
);
63 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
));)
67 case MUIA_Numeric_CheckAllSizes
:
68 _handle_bool_tag(data
->flags
, tag
->ti_Data
,
69 NUMERIC_CHECKALLSIZES
);
71 case MUIA_Numeric_Default
:
72 /* data->defvalue = CLAMP(tag->ti_Data, data->min, data->max); */
73 data
->defvalue
= tag
->ti_Data
;
75 case MUIA_Numeric_Format
:
76 data
->format
= (STRPTR
) tag
->ti_Data
;
78 case MUIA_Numeric_Max
:
79 data
->max
= tag
->ti_Data
;
81 case MUIA_Numeric_Min
:
82 data
->min
= tag
->ti_Data
;
84 case MUIA_Numeric_Reverse
:
85 _handle_bool_tag(data
->flags
, tag
->ti_Data
, NUMERIC_REVERSE
);
87 case MUIA_Numeric_RevLeftRight
:
88 _handle_bool_tag(data
->flags
, tag
->ti_Data
,
89 NUMERIC_REVLEFTRIGHT
);
91 case MUIA_Numeric_RevUpDown
:
92 _handle_bool_tag(data
->flags
, tag
->ti_Data
, NUMERIC_REVUPDOWN
);
94 case MUIA_Numeric_Value
:
96 data
->value
= (LONG
) tag
->ti_Data
;
102 CLAMP(value_set
? data
->value
: data
->defvalue
, data
->min
,
108 /**************************************************************************
110 **************************************************************************/
111 IPTR
Numeric__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
113 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
114 struct TagItem
*tags
, *tag
;
115 LONG oldval
, oldmin
, oldmax
;
118 BOOL values_changed
= FALSE
;
120 oldval
= data
->value
;
121 oldfmt
= data
->format
;
125 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
));)
129 case MUIA_Numeric_CheckAllSizes
:
130 _handle_bool_tag(data
->flags
, tag
->ti_Data
,
131 NUMERIC_CHECKALLSIZES
);
133 case MUIA_Numeric_Default
:
134 /* data->defvalue = CLAMP(tag->ti_Data, data->min, data->max); */
135 data
->defvalue
= tag
->ti_Data
;
137 case MUIA_Numeric_Format
:
138 data
->format
= (STRPTR
) tag
->ti_Data
;
140 case MUIA_Numeric_Max
:
141 data
->max
= tag
->ti_Data
;
142 data
->value
= CLAMP(data
->value
, data
->min
, data
->max
);
144 case MUIA_Numeric_Min
:
145 data
->min
= tag
->ti_Data
;
146 data
->value
= CLAMP(data
->value
, data
->min
, data
->max
);
148 case MUIA_Numeric_Reverse
:
149 _handle_bool_tag(data
->flags
, tag
->ti_Data
, NUMERIC_REVERSE
);
151 case MUIA_Numeric_RevLeftRight
:
152 _handle_bool_tag(data
->flags
, tag
->ti_Data
,
153 NUMERIC_REVLEFTRIGHT
);
155 case MUIA_Numeric_RevUpDown
:
156 _handle_bool_tag(data
->flags
, tag
->ti_Data
, NUMERIC_REVUPDOWN
);
158 case MUIA_Numeric_Value
:
159 tag
->ti_Data
= CLAMP((LONG
) tag
->ti_Data
, data
->min
, data
->max
);
161 if (data
->value
== (LONG
) tag
->ti_Data
)
162 tag
->ti_Tag
= TAG_IGNORE
;
164 data
->value
= (LONG
) tag
->ti_Data
;
170 /* If the max, min or format values changed, then the minimum and maximum
171 sizes of the string output by MUIM_Numeric_Stringify may have changed,
172 so give the subclass a chance to recalculate them and relayout the group
173 accordingly. Basically, the subclass will have to react on changes to
174 these values as well (by setting a notification on them, or by
175 overriding OM_SET) and then recalculate the minimum and maximum sizes
177 if (data
->format
!= oldfmt
|| data
->min
!= oldmin
178 || data
->max
!= oldmax
)
180 values_changed
= TRUE
;
181 Object
*parent
= _parent(obj
);
184 DoMethod(parent
, MUIM_Group_InitChange
);
185 DoMethod(parent
, MUIM_Group_ExitChange
);
189 ret
= DoSuperMethodA(cl
, obj
, (Msg
) msg
);
191 if (data
->value
!= oldval
|| values_changed
)
193 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
199 /**************************************************************************
201 **************************************************************************/
202 IPTR
Numeric__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
204 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
205 IPTR
*store
= msg
->opg_Storage
;
206 ULONG tag
= msg
->opg_AttrID
;
210 case MUIA_Numeric_CheckAllSizes
:
211 *store
= ((data
->flags
& NUMERIC_CHECKALLSIZES
) != 0);
214 case MUIA_Numeric_Default
:
215 *store
= data
->defvalue
;
218 case MUIA_Numeric_Format
:
219 *store
= (IPTR
) data
->format
;
222 case MUIA_Numeric_Max
:
226 case MUIA_Numeric_Min
:
230 case MUIA_Numeric_Reverse
:
231 *store
= ((data
->flags
& NUMERIC_REVERSE
) != 0);
234 case MUIA_Numeric_RevLeftRight
:
235 *store
= ((data
->flags
& NUMERIC_REVLEFTRIGHT
) != 0);
238 case MUIA_Numeric_RevUpDown
:
239 *store
= ((data
->flags
& NUMERIC_REVUPDOWN
) != 0);
242 case MUIA_Numeric_Value
:
243 *store
= data
->value
;
247 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
250 /**************************************************************************
252 **************************************************************************/
253 IPTR
Numeric__MUIM_Setup(struct IClass
*cl
, Object
*obj
,
254 struct MUIP_Setup
*msg
)
256 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
258 if (!DoSuperMethodA(cl
, obj
, (Msg
) msg
))
261 data
->ehn
.ehn_Events
= IDCMP_RAWKEY
;
262 data
->ehn
.ehn_Priority
= 0;
263 data
->ehn
.ehn_Flags
= 0;
264 data
->ehn
.ehn_Object
= obj
;
265 data
->ehn
.ehn_Class
= cl
;
266 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
) (&data
->ehn
));
271 /**************************************************************************
273 **************************************************************************/
274 IPTR
Numeric__MUIM_Cleanup(struct IClass
*cl
, Object
*obj
,
275 struct MUIP_Cleanup
*msg
)
277 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
279 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
) (&data
->ehn
));
280 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
283 /**************************************************************************
285 **************************************************************************/
286 IPTR
Numeric__MUIM_HandleEvent(struct IClass
*cl
, Object
*obj
,
287 struct MUIP_HandleEvent
*msg
)
289 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
291 BOOL increase
, change
;
293 if (msg
->muikey
!= MUIKEY_NONE
)
296 BOOL use_absolute
= FALSE
, is_horizontal
= FALSE
;
298 result
= MUI_EventHandlerRC_Eat
;
300 if (data
->max
- data
->min
< 10)
308 return MUI_EventHandlerRC_Eat
;
311 DoMethod(obj
, MUIM_Numeric_SetDefault
);
312 return MUI_EventHandlerRC_Eat
;
315 return MUI_EventHandlerRC_Eat
;
318 case MUIKEY_LINESTART
:
320 is_horizontal
= TRUE
;
327 is_horizontal
= TRUE
;
332 is_horizontal
= TRUE
;
337 is_horizontal
= TRUE
;
349 case MUIKEY_PAGEDOWN
:
350 case MUIKEY_WORDRIGHT
:
354 case MUIKEY_WORDLEFT
:
362 /* Send gadget in proper direction */
365 if (data
->flags
& NUMERIC_REVERSE
)
368 if ((is_horizontal
&& (data
->flags
& NUMERIC_REVLEFTRIGHT
) != 0)
369 || (!is_horizontal
&& (data
->flags
& NUMERIC_REVUPDOWN
) != 0))
381 DoMethod(obj
, MUIM_Numeric_Increase
, step
);
384 else if (msg
->imsg
->Class
== IDCMP_RAWKEY
385 && _isinobject(obj
, msg
->imsg
->MouseX
, msg
->imsg
->MouseY
))
388 switch (msg
->imsg
->Code
)
390 case RAWKEY_NM_WHEEL_UP
:
393 case RAWKEY_NM_WHEEL_DOWN
:
401 if (data
->flags
& NUMERIC_REVERSE
)
402 increase
= !increase
;
403 DoMethod(obj
, increase
?
404 MUIM_Numeric_Increase
: MUIM_Numeric_Decrease
, 1);
405 result
= MUI_EventHandlerRC_Eat
;
413 /**************************************************************************
414 MUIM_Numeric_Decrease
415 **************************************************************************/
416 IPTR
Numeric__MUIM_Decrease(struct IClass
*cl
, Object
*obj
,
417 struct MUIP_Numeric_Decrease
*msg
)
419 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
420 LONG newval
= CLAMP(data
->value
- msg
->amount
, data
->min
, data
->max
);
421 if (newval
!= data
->value
)
422 set(obj
, MUIA_Numeric_Value
, newval
);
427 /**************************************************************************
428 MUIM_Numeric_Increase
429 **************************************************************************/
430 IPTR
Numeric__MUIM_Increase(struct IClass
*cl
, Object
*obj
,
431 struct MUIP_Numeric_Increase
*msg
)
433 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
434 LONG newval
= CLAMP(data
->value
+ msg
->amount
, data
->min
, data
->max
);
436 if (newval
!= data
->value
)
437 set(obj
, MUIA_Numeric_Value
, newval
);
443 /**************************************************************************
444 MUIM_Numeric_ScaleToValue
445 **************************************************************************/
446 IPTR
Numeric__MUIM_ScaleToValue(struct IClass
*cl
, Object
*obj
,
447 struct MUIP_Numeric_ScaleToValue
*msg
)
449 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
454 min
= (data
->flags
& NUMERIC_REVERSE
) ? data
->max
: data
->min
;
455 max
= (data
->flags
& NUMERIC_REVERSE
) ? data
->min
: data
->max
;
457 val
= CLAMP(msg
->scale
- msg
->scalemin
, msg
->scalemin
, msg
->scalemax
);
458 d
= msg
->scalemax
- msg
->scalemin
;
460 // FIXME: watch out for overflow here.
461 val
= val
* (max
- min
);
471 /**************************************************************************
472 MUIM_Numeric_SetDefault
473 **************************************************************************/
474 IPTR
Numeric__MUIM_SetDefault(struct IClass
*cl
, Object
*obj
, Msg msg
)
476 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
478 set(obj
, MUIA_Numeric_Value
, CLAMP(data
->defvalue
, data
->min
,
484 /**************************************************************************
485 MUIM_Numeric_Stringify
486 **************************************************************************/
487 IPTR
Numeric__MUIM_Stringify(struct IClass
*cl
, Object
*obj
,
488 struct MUIP_Numeric_Stringify
*msg
)
490 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
492 /* TODO: use RawDoFmt() and buffer overrun */
493 snprintf(data
->buf
, 49, data
->format
, (long)msg
->value
);
496 return (IPTR
) data
->buf
;
499 /**************************************************************************
500 MUIM_Numeric_ValueToScale
501 **************************************************************************/
502 IPTR
Numeric__MUIM_ValueToScale(struct IClass
*cl
, Object
*obj
,
503 struct MUIP_Numeric_ValueToScale
*msg
)
506 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
509 min
= (data
->flags
& NUMERIC_REVERSE
) ? msg
->scalemax
: msg
->scalemin
;
510 max
= (data
->flags
& NUMERIC_REVERSE
) ? msg
->scalemin
: msg
->scalemax
;
512 if (data
->max
!= data
->min
)
515 min
+ ((data
->value
- data
->min
) * (max
- min
) + (data
->max
-
516 data
->min
) / 2) / (data
->max
- data
->min
);
523 val
= CLAMP(val
, msg
->scalemin
, msg
->scalemax
);
528 /**************************************************************************
529 MUIM_Numeric_ValueToScaleExt
530 **************************************************************************/
531 IPTR
Numeric__MUIM_ValueToScaleExt(struct IClass
*cl
, Object
*obj
,
532 struct MUIP_Numeric_ValueToScaleExt
*msg
)
536 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
539 value
= CLAMP(msg
->value
, data
->min
, data
->max
);
540 min
= (data
->flags
& NUMERIC_REVERSE
) ? msg
->scalemax
: msg
->scalemin
;
541 max
= (data
->flags
& NUMERIC_REVERSE
) ? msg
->scalemin
: msg
->scalemax
;
543 if (data
->max
!= data
->min
)
546 min
+ ((value
- data
->min
) * (max
- min
) + (data
->max
-
547 data
->min
) / 2) / (data
->max
- data
->min
);
554 scale
= CLAMP(scale
, msg
->scalemin
, msg
->scalemax
);
559 /**************************************************************************
560 MUIM_Export - to export an object's "contents" to a dataspace object.
561 **************************************************************************/
562 IPTR
Numeric__MUIM_Export(struct IClass
*cl
, Object
*obj
,
563 struct MUIP_Export
*msg
)
565 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
568 if ((id
= muiNotifyData(obj
)->mnd_ObjectID
))
570 LONG value
= data
->value
;
571 DoMethod(msg
->dataspace
, MUIM_Dataspace_Add
,
572 (IPTR
) & value
, sizeof(value
), (IPTR
) id
);
577 /**************************************************************************
578 MUIM_Import - to import an object's "contents" from a dataspace object.
579 **************************************************************************/
580 IPTR
Numeric__MUIM_Import(struct IClass
*cl
, Object
*obj
,
581 struct MUIP_Import
*msg
)
586 if ((id
= muiNotifyData(obj
)->mnd_ObjectID
))
588 if ((s
= (LONG
*) DoMethod(msg
->dataspace
, MUIM_Dataspace_Find
,
591 set(obj
, MUIA_Numeric_Value
, *s
);
599 BOOPSI_DISPATCHER(IPTR
, Numeric_Dispatcher
, cl
, obj
, msg
)
601 switch (msg
->MethodID
)
604 return Numeric__OM_NEW(cl
, obj
, (APTR
) msg
);
606 return Numeric__OM_SET(cl
, obj
, (APTR
) msg
);
608 return Numeric__OM_GET(cl
, obj
, (APTR
) msg
);
611 return Numeric__MUIM_Setup(cl
, obj
, (APTR
) msg
);
613 return Numeric__MUIM_Cleanup(cl
, obj
, (APTR
) msg
);
614 case MUIM_HandleEvent
:
615 return Numeric__MUIM_HandleEvent(cl
, obj
, (APTR
) msg
);
616 case MUIM_Numeric_Decrease
:
617 return Numeric__MUIM_Decrease(cl
, obj
, (APTR
) msg
);
618 case MUIM_Numeric_Increase
:
619 return Numeric__MUIM_Increase(cl
, obj
, (APTR
) msg
);
620 case MUIM_Numeric_ScaleToValue
:
621 return Numeric__MUIM_ScaleToValue(cl
, obj
, (APTR
) msg
);
622 case MUIM_Numeric_SetDefault
:
623 return Numeric__MUIM_SetDefault(cl
, obj
, (APTR
) msg
);
624 case MUIM_Numeric_Stringify
:
625 return Numeric__MUIM_Stringify(cl
, obj
, (APTR
) msg
);
626 case MUIM_Numeric_ValueToScale
:
627 return Numeric__MUIM_ValueToScale(cl
, obj
, (APTR
) msg
);
628 case MUIM_Numeric_ValueToScaleExt
:
629 return Numeric__MUIM_ValueToScaleExt(cl
, obj
, (APTR
) msg
);
631 return Numeric__MUIM_Export(cl
, obj
, (APTR
) msg
);
633 return Numeric__MUIM_Import(cl
, obj
, (APTR
) msg
);
636 return DoSuperMethodA(cl
, obj
, msg
);
638 BOOPSI_DISPATCHER_END
643 const struct __MUIBuiltinClass _MUI_Numeric_desc
=
647 sizeof(struct MUI_NumericData
),
648 (void *) Numeric_Dispatcher