Forums > Dev

Attrui Doesn't Get Attribute Correctly

February 28, 2014 | 5:03 am

I have a float attribute in a UI object which implements a custom getter and setter. Internally, the float is stored as an atom (it’s part of a structure which is reused amongst multiple objects and can represent other data types), but the getter and setter handles the conversion. This all works fine in the object inspector, but attrui doesn’t seem to be able to get the value, it displays zero for this attribute.

t_max_err hnpf_attrvalue_get(t_hn_pin_float *x, t_object *attr, long *argc, t_atom **argv)
{
	char alloc;
	long size = 0;
	atom_alloc(argc, argv, &alloc);

	if (alloc == true)
		**argv = x->pinStruct_.value;

	return MAX_ERR_NONE;
}

t_max_err hnpf_attrvalue_set(t_hn_pin_float *x, t_object *attr, long argc, t_atom *argv)
{
	float newValue;
	float minimum = atom_getfloat(&x->pinStruct_.minimum);
	float maximum = atom_getfloat(&x->pinStruct_.maximum);

	switch (atom_gettype(argv))
	{
	case (A_FLOAT) :
		newValue = atom_getfloat(argv);
		break;
	case (A_LONG) :
		newValue = (float)atom_getlong(argv);
		break;
	default:
		return MAX_ERR_NONE;
	}

	newValue = max(minimum, newValue);
	newValue = min(maximum, newValue);

	atom_setfloat(&x->pinStruct_.value, newValue);

	return MAX_ERR_NONE;

Attribute declaration:

CLASS_ATTR_FLOAT(c, "value", 0, t_hn_pin_float, pinStruct_.value);
	CLASS_ATTR_ACCESSORS(c, "value", hnpf_attrvalue_get, hnpf_attrvalue_set);
	CLASS_ATTR_DEFAULT_SAVE_PAINT(c, "value", 0, "0");

February 28, 2014 | 8:34 am

Try changing you attribute declaration to CLASS_ATTR_ATOM(c, "value", 0, t_hn_pin_float, pinStruct_.value). You can use CLASS_ATTR_FLOAT if the structure member is a float.


February 28, 2014 | 8:54 am

Thanks Emmanuel. I tried this but attrui then doesn’t refresh when the value changes.


February 28, 2014 | 11:31 am

attrui needs to know when the value changes (it doesn’t poll for value changes). You can either use the object_attr_set* methods to set the value of your attribute (this will call your settr, or the default settr, and notify). Or you can call object_notify on the attribute whenever you need (which has the advantage of not going through the settr (it just depends what you want to do). For the later, there’s also a 2 methods that you can use to simplify the notification process:
object_attr_touch(your_object, gensym("theattribtue"));
or
object_attr_touch_parse(your_object, "theattribbute");


March 1, 2014 | 12:32 pm

Hi there,

you don’t actually need a custom getter…

Since your final data type is an atom I would do something like this:

CLASS_ATTR_ATOM(c, "value", 0, t_hn_pin_float, pinStruct_.value);
CLASS_ATTR_ACCESSORS(c, "value", NULL, hnpf_attrvalue_set);
CLASS_ATTR_DEFAULT_SAVE_PAINT(c, "value", 0, "0.0");

Here is how I would write the setter:
[no need to check atom type as it's implicitly done in atom_getfloat()]

t_max_err hnpf_attrvalue_set(t_hn_pin_float *x, t_object *attr, long argc, t_atom *argv)
{
	float minimum = atom_getfloat(&x->pinStruct_.minimum);
	float maximum = atom_getfloat(&x->pinStruct_.maximum);
	float newValue = atom_getfloat(argv);

	newValue = max(minimum, newValue);
	newValue = min(maximum, newValue);

	atom_setfloat(&x->pinStruct_.value, newValue);

	return MAX_ERR_NONE;
}

Now AttrUI should be able to get the value correctly.
Hope this helps…

- Luigi


March 2, 2014 | 4:05 pm

Thanks all. The getters originally performed a function but are unnecessary now so I’ve removed them.

The only slight downside of declaring the attribute as an atom is that the UI in attrui doesn’t display as a floatbox type, but I suppose I can live with that!


Viewing 6 posts - 1 through 6 (of 6 total)