Dave Chambers
Dave Chambers

Reputation: 2563

C++: Is there a simple way of 'mapping' the hex colour `0xff2a2620` to a more readable string 'lovelyBrown'?

I'm using the Juce Framework that has a setColour method like so:

g.setColour (Colour (0xff2a2620));

I instead would like to write something like more readable like:

g.setColour (Colour (lovelyBrown));, 'mapping' 0xff2a2620 to 'lovelyBrown'.

The method's prototype is:

explicit Colour (uint32 argb) noexcept; where uint32 is:

/** A platform-independent 32-bit unsigned integer type. */ typedef unsigned int uint32;

Juce has nice readable colour names already such as:

const Colour Colours::tomato (0xffff6347);, using a method to find the colour given a name:

static JUCE_API Colour findColourForName (const String& colourName, const Colour& defaultColour);

However, I don't want to modify or subclass their Colours class. I am wondering if there is a simpler way of 'mapping' 0xff2a2620 to 'lovelyBrown'?

Upvotes: 3

Views: 261

Answers (3)

Tony Delroy
Tony Delroy

Reputation: 106156

Just as you say Juce provides...

const Colour Colours::tomato (0xffff6347);

...you can add colours of your own:

const Colour lovelyBrown (0xff2a2620);

If you want a function to map from colour names to values at runtime, an easy and robust way is:

std::map<std::string, Colour> colourMap;
colourMap["lovelyBrown"] = lovelyBrown;
// add more here...

A slightly faster alternative is to have a contiguous array or vector of sorted colour names and use lower_bound to search. If you're not sure how to do that, you probably shouldn't... ;-P. (You'd either need to trust yourself/others to keep the list sorted in the source code, or do a runtime sort before first use, so there's a bit more risk/hassle+delocalisation respectively).


Note:

  • a problem with using enum class Colours is that when you use the contained colour names, they must be prefixed by Colours::, so there's a discrepancy with the Juce-provided colour names:
    g.setColour (Colour (tomato));  // ok for provided colours
    g.setColour (Colour (Colours::lovelyBrown));  // oops, one of yours
  • more generally, using enum or enum class makes the colours a distinct type, which has subtle consequences: e.g. you can't just stream them a la cout << lovelyBrown without writing your own operator<<, you can't invert the red component a la lovelyBrown ^ 0xFF0000 etc. - again, these things can be done for the Juce-provided colours.

Upvotes: 2

Dave Chambers
Dave Chambers

Reputation: 2563

enum MyColour {
lovelyBrown = 0xff2a2620,
};

This works but I ended up following Tony's advise for a cleaner (and easy!) solution. See his answer

Upvotes: 0

syntagma
syntagma

Reputation: 24334

Use C++11 enums (that way your enum will be an uint32_t):

#include <cstdint>
enum class Colours : std::uint32_t {
    lovelyBrown = 0xff2a2620,
    lovelyOther = 0xff2a26FF
};

Upvotes: 2

Related Questions