How does the JUCE team expect us to use ColourIds?

Could the JUCE team share their thoughts on devs making custom components that mimic the ‘JUCE’ way of tying in with the LookAndFeel conventions?

It appears to me, that inhouse, you are keeping a list of used ColourIds across all classes to avoid future conflict. Is there anything in place for us to create custom entries, through? How do we prevent a future scenario of new JUCE components conflicting with our own? Is there a designated ‘safe’ range?

Any words of caution/general advice here would be great. I am somewhat worried of shooting myself in the foot by taking this approach.

Thanks!

2 Likes

IIRC, all the JUCE colour IDs start with 0x1000000. So, you could simply start yours at 0x2000000 and they won’t conflict with the JUCE IDs. In fact you could start at 0, which is perhaps the intension behind the JUCE ones starting at 0x1000000?

1 Like

The trouble starts when you add modules of other developers, and they might also start at 0x2000000…
Since you need your colour defined to avoid a jassert in findColour, it is wise to do so in lookAndFeelChanged(), there could be a check maybe?

I didn’t come to a satisfactory conclusion myself.

The best solution I’ve found is to not use JUCE’s colour ID system. It could be massively improved by using strings for keys rather than ints - I’m sure there’s some technical reason why that wasn’t done though, performance possibly? If ints is the way to go, some way to register a set of colour IDs with a LaF where you just provide IDs starting at 0 and the LaF internally prepends a unique prefix to avoid conflicts.

I tend to use Component::getProperties() to specify colours rather than faffing about adding new colour IDs - or just use a design language where colour is infered from a widget’s type/role rather than explicity specified.

I think the performance is really not a good excuse anymore. I think if they would make Identifier a constexpr type and implement a hashCode function, they could pretty much stay with integers but have descriptive keys.

You can already do that with a crc32 function. So your keys would become “background”_crc32, and the string would become an int during compile time. And unless you have unfortunate color names, the chance of a collision is minimal.

Could you not just use juce::String::hashCode()?

I made a proposal a few years ago (Proposal improve of look and feel of Juce's applications - #63 by Qfactor). This is what I use in LoopRecorder VST/AU (I have recreated all the widgets with the Styled base class). I use it to create a UI from a SVG file. If you run it you can tell it doesn’t really slow down things that much.