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
;
33 NUMERIC_REVERSE
= (1<<0),
34 NUMERIC_REVLEFTRIGHT
= (1<<1),
35 NUMERIC_REVUPDOWN
= (1<<2),
36 NUMERIC_CHECKALLSIZES
= (1<<3),
39 extern struct Library
*MUIMasterBase
;
41 /**************************************************************************
43 **************************************************************************/
44 IPTR
Numeric__OM_NEW(struct IClass
*cl
, Object
* obj
, struct opSet
*msg
)
46 struct MUI_NumericData
*data
;
47 struct TagItem
*tags
, *tag
;
49 BOOL value_set
= FALSE
;
51 obj
= (Object
*)DoSuperMethodA(cl
, obj
, (Msg
)msg
);
55 data
= INST_DATA(cl
, obj
);
61 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem((const struct TagItem
**)&tags
));)
65 case MUIA_Numeric_CheckAllSizes
:
66 _handle_bool_tag(data
->flags
, tag
->ti_Data
, NUMERIC_CHECKALLSIZES
);
68 case MUIA_Numeric_Default
:
69 /* data->defvalue = CLAMP(tag->ti_Data, data->min, data->max); */
70 data
->defvalue
= tag
->ti_Data
;
72 case MUIA_Numeric_Format
:
73 data
->format
= (STRPTR
)tag
->ti_Data
;
75 case MUIA_Numeric_Max
:
76 data
->max
= tag
->ti_Data
;
78 case MUIA_Numeric_Min
:
79 data
->min
= tag
->ti_Data
;
81 case MUIA_Numeric_Reverse
:
82 _handle_bool_tag(data
->flags
, tag
->ti_Data
, NUMERIC_REVERSE
);
84 case MUIA_Numeric_RevLeftRight
:
85 _handle_bool_tag(data
->flags
, tag
->ti_Data
, NUMERIC_REVLEFTRIGHT
);
87 case MUIA_Numeric_RevUpDown
:
88 _handle_bool_tag(data
->flags
, tag
->ti_Data
, NUMERIC_REVUPDOWN
);
90 case MUIA_Numeric_Value
:
92 data
->value
= (LONG
)tag
->ti_Data
;
97 data
->value
= CLAMP(value_set
? data
->value
: data
->defvalue
, data
->min
, data
->max
);
102 /**************************************************************************
104 **************************************************************************/
105 IPTR
Numeric__OM_SET(struct IClass
*cl
, Object
* obj
, struct opSet
*msg
)
107 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
108 struct TagItem
*tags
, *tag
;
109 LONG oldval
, oldmin
, oldmax
;
112 BOOL values_changed
= FALSE
;
114 oldval
= data
->value
;
115 oldfmt
= data
->format
;
119 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem((const struct TagItem
**)&tags
));)
123 case MUIA_Numeric_CheckAllSizes
:
124 _handle_bool_tag(data
->flags
, tag
->ti_Data
, NUMERIC_CHECKALLSIZES
);
126 case MUIA_Numeric_Default
:
127 /* data->defvalue = CLAMP(tag->ti_Data, data->min, data->max); */
128 data
->defvalue
= tag
->ti_Data
;
130 case MUIA_Numeric_Format
:
131 data
->format
= (STRPTR
)tag
->ti_Data
;
133 case MUIA_Numeric_Max
:
134 data
->max
= tag
->ti_Data
;
136 case MUIA_Numeric_Min
:
137 data
->min
= tag
->ti_Data
;
139 case MUIA_Numeric_Reverse
:
140 _handle_bool_tag(data
->flags
, tag
->ti_Data
, NUMERIC_REVERSE
);
142 case MUIA_Numeric_RevLeftRight
:
143 _handle_bool_tag(data
->flags
, tag
->ti_Data
, NUMERIC_REVLEFTRIGHT
);
145 case MUIA_Numeric_RevUpDown
:
146 _handle_bool_tag(data
->flags
, tag
->ti_Data
, NUMERIC_REVUPDOWN
);
148 case MUIA_Numeric_Value
:
149 tag
->ti_Data
= CLAMP((LONG
)tag
->ti_Data
, data
->min
, data
->max
);
151 if (data
->value
== (LONG
)tag
->ti_Data
)
152 tag
->ti_Tag
= TAG_IGNORE
;
154 data
->value
= (LONG
)tag
->ti_Data
;
160 /* If the max, min or format values changed, then the minimum and maximum sizes
161 of the string output by MUIM_Numeric_Strigify maye have changed, so
162 give the subclass a chance to recalculate them and relayout the group
163 accordingly. Basically, the subclass will have to react on changes to
164 these values as well (by setting a notification on them, or by overriding
165 OM_SET) and then recalculate the minimum and maximum sizes for the object. */
166 if (data
->format
!= oldfmt
|| data
->min
!= oldmin
|| data
->max
!= oldmax
)
168 values_changed
= TRUE
;
169 DoMethod(_parent(obj
), MUIM_Group_InitChange
);
170 DoMethod(_parent(obj
), MUIM_Group_ExitChange
);
174 ret
= DoSuperMethodA(cl
, obj
, (Msg
)msg
);
176 if (data
->value
!= oldval
|| values_changed
)
178 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
184 /**************************************************************************
186 **************************************************************************/
187 IPTR
Numeric__OM_GET(struct IClass
*cl
, Object
* obj
, struct opGet
*msg
)
189 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
190 IPTR
*store
= msg
->opg_Storage
;
191 ULONG tag
= msg
->opg_AttrID
;
195 case MUIA_Numeric_CheckAllSizes
:
196 *store
= ((data
->flags
& NUMERIC_CHECKALLSIZES
) != 0);
199 case MUIA_Numeric_Default
:
200 *store
= data
->defvalue
;
203 case MUIA_Numeric_Format
:
204 *store
= (IPTR
)data
->format
;
207 case MUIA_Numeric_Max
:
211 case MUIA_Numeric_Min
:
215 case MUIA_Numeric_Reverse
:
216 *store
= ((data
->flags
& NUMERIC_REVERSE
) != 0);
219 case MUIA_Numeric_RevLeftRight
:
220 *store
= ((data
->flags
& NUMERIC_REVLEFTRIGHT
) != 0);
223 case MUIA_Numeric_RevUpDown
:
224 *store
= ((data
->flags
& NUMERIC_REVUPDOWN
) != 0);
227 case MUIA_Numeric_Value
:
228 *store
= data
->value
;
232 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
235 /**************************************************************************
237 **************************************************************************/
238 IPTR
Numeric__MUIM_Setup(struct IClass
*cl
, Object
*obj
, struct MUIP_Setup
*msg
)
240 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
242 if (!DoSuperMethodA(cl
,obj
,(Msg
)msg
))
245 data
->ehn
.ehn_Events
= IDCMP_RAWKEY
;
246 data
->ehn
.ehn_Priority
= 0;
247 data
->ehn
.ehn_Flags
= 0;
248 data
->ehn
.ehn_Object
= obj
;
249 data
->ehn
.ehn_Class
= cl
;
250 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)(&data
->ehn
));
255 /**************************************************************************
257 **************************************************************************/
258 IPTR
Numeric__MUIM_Cleanup(struct IClass
*cl
, Object
*obj
, struct MUIP_Cleanup
*msg
)
260 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
262 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)(&data
->ehn
));
263 return DoSuperMethodA(cl
,obj
,(Msg
)msg
);
266 /**************************************************************************
268 **************************************************************************/
269 IPTR
Numeric__MUIM_HandleEvent(struct IClass
*cl
, Object
*obj
, struct MUIP_HandleEvent
*msg
)
271 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
273 if (msg
->muikey
!= MUIKEY_NONE
)
277 if (data
->max
- data
->min
< 10)
285 return MUI_EventHandlerRC_Eat
;
288 DoMethod(obj
, MUIM_Numeric_SetDefault
);
289 return MUI_EventHandlerRC_Eat
;
292 return MUI_EventHandlerRC_Eat
;
296 if (data
->flags
& NUMERIC_REVUPDOWN
)
297 set(obj
, MUIA_Numeric_Value
, data
->min
);
299 set(obj
, MUIA_Numeric_Value
, data
->max
);
300 return MUI_EventHandlerRC_Eat
;
303 case MUIKEY_LINESTART
:
304 if (data
->flags
& NUMERIC_REVUPDOWN
)
305 set(obj
, MUIA_Numeric_Value
, data
->max
);
307 set(obj
, MUIA_Numeric_Value
, data
->min
);
308 return MUI_EventHandlerRC_Eat
;
311 if (data
->flags
& NUMERIC_REVLEFTRIGHT
)
312 DoMethod(obj
, MUIM_Numeric_Increase
, 1);
314 DoMethod(obj
, MUIM_Numeric_Decrease
, 1);
315 return MUI_EventHandlerRC_Eat
;
318 if (data
->flags
& NUMERIC_REVLEFTRIGHT
)
319 DoMethod(obj
, MUIM_Numeric_Decrease
, 1);
321 DoMethod(obj
, MUIM_Numeric_Increase
, 1);
322 return MUI_EventHandlerRC_Eat
;
325 if (data
->flags
& NUMERIC_REVUPDOWN
)
326 DoMethod(obj
, MUIM_Numeric_Increase
, 1);
328 DoMethod(obj
, MUIM_Numeric_Decrease
, 1);
329 return MUI_EventHandlerRC_Eat
;
332 if (data
->flags
& NUMERIC_REVUPDOWN
)
333 DoMethod(obj
, MUIM_Numeric_Decrease
, 1);
335 DoMethod(obj
, MUIM_Numeric_Increase
, 1);
336 return MUI_EventHandlerRC_Eat
;
338 case MUIKEY_PAGEDOWN
:
339 case MUIKEY_WORDRIGHT
:
340 if (data
->flags
& NUMERIC_REVUPDOWN
)
341 DoMethod(obj
, MUIM_Numeric_Decrease
, step
);
343 DoMethod(obj
, MUIM_Numeric_Increase
, step
);
344 return MUI_EventHandlerRC_Eat
;
347 case MUIKEY_WORDLEFT
:
348 if (data
->flags
& NUMERIC_REVUPDOWN
)
349 DoMethod(obj
, MUIM_Numeric_Increase
, step
);
351 DoMethod(obj
, MUIM_Numeric_Decrease
, step
);
352 return MUI_EventHandlerRC_Eat
;
363 /**************************************************************************
364 MUIM_Numeric_Decrease
365 **************************************************************************/
366 IPTR
Numeric__MUIM_Decrease(struct IClass
*cl
, Object
* obj
, struct MUIP_Numeric_Decrease
*msg
)
368 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
369 LONG newval
= CLAMP(data
->value
- msg
->amount
, data
->min
, data
->max
);
370 if (newval
!= data
->value
) set(obj
,MUIA_Numeric_Value
, newval
);
374 /**************************************************************************
375 MUIM_Numeric_Increase
376 **************************************************************************/
377 IPTR
Numeric__MUIM_Increase(struct IClass
*cl
, Object
* obj
, struct MUIP_Numeric_Increase
*msg
)
379 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
380 LONG newval
= CLAMP(data
->value
+ msg
->amount
, data
->min
, data
->max
);
382 if (newval
!= data
->value
) set(obj
,MUIA_Numeric_Value
, newval
);
387 /**************************************************************************
388 MUIM_Numeric_ScaleToValue
389 **************************************************************************/
390 IPTR
Numeric__MUIM_ScaleToValue(struct IClass
*cl
, Object
* obj
, struct MUIP_Numeric_ScaleToValue
*msg
)
392 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
397 min
= (data
->flags
& NUMERIC_REVERSE
) ? data
->max
: data
->min
;
398 max
= (data
->flags
& NUMERIC_REVERSE
) ? data
->min
: data
->max
;
400 val
= CLAMP(msg
->scale
- msg
->scalemin
, msg
->scalemin
, msg
->scalemax
);
401 d
= msg
->scalemax
- msg
->scalemin
;
403 #warning FIXME: watch out for overflow here.
404 val
= val
* (max
- min
);
414 /**************************************************************************
415 MUIM_Numeric_SetDefault
416 **************************************************************************/
417 IPTR
Numeric__MUIM_SetDefault(struct IClass
*cl
, Object
* obj
, Msg msg
)
419 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
421 set(obj
, MUIA_Numeric_Value
, CLAMP(data
->defvalue
, data
->min
, data
->max
));
426 /**************************************************************************
427 MUIM_Numeric_Stringify
428 **************************************************************************/
429 IPTR
Numeric__MUIM_Stringify(struct IClass
*cl
, Object
* obj
, struct MUIP_Numeric_Stringify
*msg
)
431 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
433 /* TODO: use RawDoFmt() and buffer overrun */
434 snprintf(data
->buf
, 49, data
->format
, msg
->value
);
437 return (IPTR
)data
->buf
;
440 /**************************************************************************
441 MUIM_Numeric_ValueToScale
442 **************************************************************************/
443 IPTR
Numeric__MUIM_ValueToScale(struct IClass
*cl
, Object
* obj
, struct MUIP_Numeric_ValueToScale
*msg
)
446 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
449 min
= (data
->flags
& NUMERIC_REVERSE
) ? msg
->scalemax
: msg
->scalemin
;
450 max
= (data
->flags
& NUMERIC_REVERSE
) ? msg
->scalemin
: msg
->scalemax
;
452 if (data
->max
!= data
->min
)
454 val
= min
+ ((data
->value
- data
->min
) * (max
- min
) + (data
->max
- data
->min
)/2) / (data
->max
- data
->min
);
461 val
= CLAMP(val
, min
, max
);
466 /**************************************************************************
467 MUIM_Numeric_ValueToScaleExt
468 **************************************************************************/
469 IPTR
Numeric__MUIM_ValueToScaleExt(struct IClass
*cl
, Object
* obj
, struct MUIP_Numeric_ValueToScaleExt
*msg
)
473 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
476 value
= CLAMP(msg
->value
,data
->min
,data
->max
);
477 min
= (data
->flags
& NUMERIC_REVERSE
) ? msg
->scalemax
: msg
->scalemin
;
478 max
= (data
->flags
& NUMERIC_REVERSE
) ? msg
->scalemin
: msg
->scalemax
;
480 if (data
->max
!= data
->min
)
482 scale
= min
+ ((value
- data
->min
) * (max
- min
) + (data
->max
- data
->min
)/2) / (data
->max
- data
->min
);
489 scale
= CLAMP(scale
, min
, max
);
494 /**************************************************************************
495 MUIM_Export - to export an objects "contents" to a dataspace object.
496 **************************************************************************/
497 IPTR
Numeric__MUIM_Export(struct IClass
*cl
, Object
*obj
, struct MUIP_Export
*msg
)
499 struct MUI_NumericData
*data
= INST_DATA(cl
, obj
);
502 if ((id
= muiNotifyData(obj
)->mnd_ObjectID
))
504 LONG value
= data
->value
;
505 DoMethod(msg
->dataspace
, MUIM_Dataspace_Add
,
513 /**************************************************************************
514 MUIM_Import - to import an objects "contents" from a dataspace object.
515 **************************************************************************/
516 IPTR
Numeric__MUIM_Import(struct IClass
*cl
, Object
*obj
, struct MUIP_Import
*msg
)
521 if ((id
= muiNotifyData(obj
)->mnd_ObjectID
))
523 if ((s
= (LONG
*) DoMethod(msg
->dataspace
, MUIM_Dataspace_Find
, (IPTR
) id
)))
525 set(obj
, MUIA_Numeric_Value
, *s
);
532 BOOPSI_DISPATCHER(IPTR
, Numeric_Dispatcher
, cl
, obj
, msg
)
534 switch (msg
->MethodID
)
536 case OM_NEW
: return Numeric__OM_NEW(cl
, obj
, (APTR
)msg
);
537 case OM_SET
: return Numeric__OM_SET(cl
, obj
, (APTR
)msg
);
538 case OM_GET
: return Numeric__OM_GET(cl
, obj
, (APTR
)msg
);
540 case MUIM_Setup
: return Numeric__MUIM_Setup(cl
, obj
, (APTR
)msg
);
541 case MUIM_Cleanup
: return Numeric__MUIM_Cleanup(cl
, obj
, (APTR
)msg
);
542 case MUIM_HandleEvent
: return Numeric__MUIM_HandleEvent(cl
, obj
, (APTR
)msg
);
543 case MUIM_Numeric_Decrease
: return Numeric__MUIM_Decrease(cl
, obj
, (APTR
)msg
);
544 case MUIM_Numeric_Increase
: return Numeric__MUIM_Increase(cl
, obj
, (APTR
)msg
);
545 case MUIM_Numeric_ScaleToValue
: return Numeric__MUIM_ScaleToValue(cl
, obj
, (APTR
)msg
);
546 case MUIM_Numeric_SetDefault
: return Numeric__MUIM_SetDefault(cl
, obj
, (APTR
)msg
);
547 case MUIM_Numeric_Stringify
: return Numeric__MUIM_Stringify(cl
, obj
, (APTR
)msg
);
548 case MUIM_Numeric_ValueToScale
: return Numeric__MUIM_ValueToScale(cl
, obj
, (APTR
)msg
);
549 case MUIM_Numeric_ValueToScaleExt
: return Numeric__MUIM_ValueToScaleExt(cl
, obj
, (APTR
)msg
);
550 case MUIM_Export
: return Numeric__MUIM_Export(cl
, obj
, (APTR
)msg
);
551 case MUIM_Import
: return Numeric__MUIM_Import(cl
, obj
, (APTR
)msg
);
554 return DoSuperMethodA(cl
, obj
, msg
);
556 BOOPSI_DISPATCHER_END
562 const struct __MUIBuiltinClass _MUI_Numeric_desc
= {
565 sizeof(struct MUI_NumericData
),
566 (void*)Numeric_Dispatcher