How to set color attribute in Min Devkit?

Joe Kaplan's icon

Hi!
One of the cool things about min is that you can easily set the value of an attribute.

if you have

myIntAttr<int> .....

you can write

myIntAttr = 12;

I'm trying to the same with

myCollorAttr<color> ...

But this:

c74::min::color myColor{1, 1, 1, 1};
myColorAttr = myColor;

gives a stack overflow error.

So I tried using the .set() function of the attribute class. But I'm having trouble composing the atoms argument.

c74::max::t_atom myColor[4]; 
c74::max::atom_setfloat(myColor, styleColor.red); 
c74::max::atom_setfloat(myColor + 2, styleColor.red); 
c74::max::atom_setfloat(myColor + 3, styleColor.red); 
c74::max::atom_setfloat(myColor + 4, styleColor.red); 
textcolor.set(atoms(atom(myColor)), 1);  

I got this idea from the Max SDK Docs. But it gives a "vector subscript out of range" error.

What is the right way to set a color attribute in Min? Thanks!

Rob Ramirez's icon

doesn't look like there's a way to set a color attribute equal to a color type. you can do something like this though:

atoms newcolor = { 1, 0, 0, 1 }; 
mycolor = newcolor; 

In your second attempt it looks like you are attempting to access the 5th element of a 4 element array: myColor + 4 is the 5th element and myColor + 0 is the first.

Joe Kaplan's icon

Thanks Rob! I got this to compile.

Should setting attributes this way work in the constructor?

If I add those lines in any message it works fine. But if I use it in the constructor the color doesn't update from the default value specified in the attribute declaration.

Starting to get off topic a bit:
But how does the constructor interact with attribute values?
How can I programmatically set attribute values when the object loads? I tried using a lambda as the default value for the attribute, but the object just loaded with color{0 0 0 0}

I noticed some other behaviour previously where if I set an attribute value when instantiating the object in max eg [myObj @myattr 1], the value of myattr in the constructor is still the attr default, not the value that was set. I wonder if this is related.

Appreciate your input!

JBG's icon

Hi Joe,

The full procedure when the non-dummy object is created is this:

  1. The attributes are created and initialized to their default value

  2. The constructor is called

  3. The attributes are assigned their actual value if attributes are passed to the box (e.g. [myobj @someattr 1]) or if stored in the object through attribute freezing (when patcher is reopened)

  4. The special setup function is called

If you need to interact with the attributes after they are fully initialized, you should put that logic in the setup function rather than the constructor, i.e.

message<> setup{this, "setup", MIN_FUNCTION {  
    // do something with the fully initialized attribute
    return {};  
}};

Joe Kaplan's icon

This is awesome! It's so helpful to understand how this works. This setup message should solve a number of things that have been challenging me! I'm always happy to learn about new secret MIN messages.

I got the setup message to fire. My Print statement appears. But the attribute value doesn't update. Updating the attribute in any other message works fine. :(

attribute and message.
console log
attribute in inspector.

Joe Kaplan's icon

hm... i got this to behave properly in min.hello-world. But not in my code. stay tuned.

Joe Kaplan's icon

Does this work differently in UI objects?

JBG's icon

Sorry, it seems I was wrong on this, setup is called before the attributes are assigned their actual value. I guess the only upside of setup compared to the normal ctor is that it won't be called by the dummy.

If you really need to do something in the construction process but after the attributes are assigned their values, you could always modify the min-api and add your own function call at the end of the wrapper_new function, i.e. after this and this line add something like

self->m_min_object.try_call("post_attribute_setup");

Then you can use this in your own class in the same way you'd use setup or maxclass_setup

Joe Kaplan's icon

apparenlty so.

I added the following code to min.textslider, and the "anumber" attribute is 0 when the object gets created. File attached.

attribute<int> anumber{ this, "anumber", 0,  title {"anumber"} };
message<> setup { this, "setup",
    MIN_FUNCTION {
        cout << "hello from the setup message" << endl;
        anumber = 12;
        return {};
    }
};
min.textslider.txt
txt 9.48 KB
Joe Kaplan's icon

Thanks JBG! That worked like a charm!

I dropped those lines in and now I have the object behaving exactly as I hoped.

I went ahead and made a pull request:
https://github.com/Cycling74/min-api/pull/208

If C74 was willing to accept this it would be a huge help! I'd prefer not to have to maintain my own fork of Min if I can avoid it. Especially just for these two lines.