Using Theme Colors in Custom Externals?
I'm playing around with the default colors of my custom UI object made in Min Devkit. The shift from light background to dark background in the default theme from Max 8 to Max 9 makes my object look terrible by default in Max 9.
I recently added attributes to customize the colors of various elements in my UI Object.
But I noticed in [attrui] that various theme colors are available. Is there a way to access these theme colors from the External Code?
So I can set the default color of my text to the theme's "Object Text Color"? Then my object will be responsive to the theme and I won't have to commit to a Max 8 or a Max 9 color scheme.

I found this post. So it looks like this is possible for M4L themes. But what about native max? Is there a way to make my external Theme Aware when running natively in Max?
Looks like it is possible in a JS object. But I'm not clear on how to do this with the Max SDK or, preferably, Min Devkit. Is there an equivalent of max.getcolor() that is available to the Max SDK or Min?
Hi Joe,
You can use theme colors if necessary, but I'd recommend using "style" colors (Object Text Color for example is a style color), which are well suited for in patcher color usage. Themes provide default style colors which is where this comes from.
A good SDK example of using style colors is the jslider object:
For object text color you would want to use the following to map your color:
class_attr_stylemap(c, "yourcolorname", "textcolor_inverse");
and in your paint method, you should look up the color dynamically to properly inherit the style's color, rather than accessing your struct member variable directly.
object_attr_getjrgba((t_object*)x, gensym("yourcolorname"), &c);
Style API functions are documented here:
As for a C based workalike to max.getcolor, there is the following undocumented function (we'll be working on an updated SDK in the not too distant future and I'll add this to the list).
long jcolor_getcolor(t_symbol* name, t_jrgba* on, t_jrgba* off);
Use jcolor_getcolor to return a theme color with the theme name in the on t_jrgba pointer (some colors have an "off" color but you can basically ignore that).
I hope this helps point you in the right direction.
-Joshua
This is great! Thanks Joshua! A new SDK coming soon is very exciting!
It looks like the jslider is exactly what I'd like to achieve. The only challenge now is mixing Min and Max SDK. I've been able to make this work in all the instances I've needed it for so far. I'm hoping this is not an exception.
It looks like the class_attr_stylemap() requires a t_class * that pertains to the present object. In Min, I have tried "this" and maxobj(). But I'm not sure how to produce the argument the function is looking for here. Any thoughts?
Much appreciated!
I spent some time with this. By declaring an arbitrary, empty t_class* c and a few other variables I was able to get the relevant functions to pass the linter at least. But I wasn't able to return a color that I could use inside MINs paint function.
It's tough to make complete sense of jslider.c without having full understanding of Max SDK, especially how it handles UI and Paint. I think implementing this in Min is beyond my ability right now.
I guess if I'm desperate to theme my object, I can handle this in the patcher with assistance from [themecolor]. I'm very curious about this new SDK you speak of. Hopefully it will make this a bit easier.
Thanks again for your response!
Okay. Yeah it'll be a bit before I have a chance to see if this is easily possible with the Min SDK. Someone else with more experience with Min might be able to translate what I reference above from the standard Max SDK.
Hi,
Anything that lives in the ext_main
of a max-sdk class should be in the maxclass_setup
function in a min-api class. The max::t_class*
is the first argument passed (see source), i.e.
message<> maxclass_setup { this, "maxclass_setup",
MIN_FUNCTION {
c74::max::t_class* c = args[0];
// ...
return {};
}
};
Thank you both! I think I see a path to making this work!
I added the maxclass_setup message and everything compiled without a problem. However, I don't think object_attr_getjrgba is working for me.
I don't think the function is actually updating my t_jrgba object. The code below outputs the same result even if I comment out the object_attr_getjrgba function. Which means that function is not updating the rgba values of the class.
Most importantly, my text is not being painted because all the rgba values are still 0.
Reasons I can think of that this could be happening:
1) I'm not initializing / referring to my styleColor variable properly in the two functions.
2) "textcolor_invert" is not actually in the stylemap so it's not returning anything. Is there a reference for the proper values that can go into the 3rd argument of this function? Ultimately I will need to refer to other styles besides "texcolor_invert" from Joshua's example.





I noticed Joshua mentioned object_attr_getjrgba() needs to be called inside the Paint method.
I made this change. Now my print statement shows the values as being 0 0 0 0 instead of the random numbers it was showing previously. But I don't don't think it's actually working.
I've tried a few different values for the 3rd argument to stylemap, but none of them seem to actually be mapping a color to my tsymbol and then writing it to my t_jrgba.
Holy cow guys! I almost got it to work.
In looking at the MaxAPI docs, I noticed that the second argument to Stylemap needs to be the name of my attribute that I want to associate with the given style. Then, in paint, all i have to do is use get_jrgba to get the color of that attribute.
This seems to almost be working. If i examine the attribute, I see stylemap found the Style! Awesome. But the color seems broken in the inspector window. When I fetch the attribute color in paint using get_jrgba, the color is 0, 0, 0, 0.
Oddly, if i manually modify the color then the color fetched by get_jrgba is correct, and my text displays with that color.
I know I am mapping the style because if a use "asdf" as the third argument to stylemep, then I don't see the style name in the inspector with a broken color. Instead the object just renders normally with the default color I set for the attribute.
So... it looks like stylemap is finding the style and mapping it to the attribute. And get_jrgba is getting the attribute's color. But for some reason the style color is not being applied when the object is initializes.
Soo... very... close.




So sorry to spam this thread. It's a brain worm I'm having trouble letting go of. I have reverted the error significantly.
After further examination, now I understand what you were referring to Joshua, with respect to styles and themes.
The goal of stylemap is not to use the Dynamic Colors from Max's default theme. But to instead use the fixed colors defined by the styles. The Format Pallete toolbar shows the available styles and their system names that can be reffered to in the stylemap function. Great!
This is almost, almost, almost working.
If I call stylemap in the maxclass_setup message and map my attribute to the "color" style.
I can then get the color of the attribute using the get_jrgba function.
The problem is the color associated with the function seems to get messed up somewhere along the way.
I noticed if I call get_jrgba in my object's constructor it returns the expected values.
But if I call get_jrgb in my paint function i get junk values.
My object winds up painting with color 0 0 0 0 everything that uses that attribute.
If I check out what's going on for the object in the Format palette I see that the style defaults have been overridden.
If I revert back to the style defaults then my object paints according to the style color.
So it seems like somewhere between the constructor and the the first paint a bogus t_rgba value is getting assigned to the attribute. I wonder if this is an artifact of how MIN initializes attributes.
Here are some screenshots:







Seems really weird, doesn't it?
I tried validating the behaviour against jslider in the Max SDK, but I cannot get the object to build. It just highlights red and does not initialize. I was able to build a bunch of other objects from Max SDK, but jslider seems broken.
It's cool to dive so deep into how max handles styles and colors. I just wish I could make this work at the end of the day.
Alright, last post on this today. I used some breakpoints to figure out what's going on.
When instantiating the object for the first time in a max session the following is the order of operations:
attributes get created
object constructor executes
max_class setup executes (on first instantiation only)
create attributes
run the constructor
paint
I presume the redundancy here is from creating the dummy instance.
Looking at this order of operations, both the constructor and paint only runs after the attributes are created. Which only happens after max_class setup.
Based on this, I don't see any way to retain the default values of the style. I associate my attribute with the style, and then I am forced to immediately overwrite the value of the attribute with the defaults required in the attribute declaration.
So by the time we get to Paint, the style defaults are gone.
I think a solution here would be to fetch the value of the style defaults in maxclass_setup and persist them and then use them as the attribute defaults.
But I can't do that because get_jrbga() doesn't return anything useful if calls in maxclass_setup. I think it's because this function executes in a nebulous space between the dummy and the actual object, and so there is no true maxobj() to reference.
It seems like this may not be possible in MIN due to the way max_class setup is handled. I'm open to any suggestions! Thanks!