How can I create a static LookAndFeel after Colours initializes?


#1

I’m trying to create some global styling functions.

namespace ComponentStyling {
	Slider::RotaryParameters throttleRange = {3.1415*8/6, 3.1415*(12 +4)/6, true};
	ThrottleKnobLookAndFeel throttleLookAnFeel;
	
	void setupCommonThrottle(Slider &setMeUp) {
		setMeUp.setRotaryParameters(throttleRange);
		setMeUp.setSliderStyle(Slider::RotaryVerticalDrag);
		setMeUp.setLookAndFeel(&throttleLookAnFeel);
		setMeUp.setTextBoxStyle(Slider::NoTextBox, false, 90, 0);
	}
};

But I get the following error:

How can I get Colours to initialize before creating this LookAndFeel?


#2

You could make a static LookAndFeel inside of another class that isn’t static, for instance that’s possible to do for plugins by making the static LookAndFeel a member of the AudioProcessorEditor


#3

I’d really like to have this global LookAndFeel class so I can make a global knob setup function.


#4

There is actually a more clever way with LookAndFeel. You don’t create a static one, but you set one to the top level component, which can be a member there. Every child component will automatically use that lookAndFeel, unless a different one was set.

The algorithm works as follows:

  1. if a LookAndFeel was set, use it
  2. retrieve the parent’s LookAndFeel and use it
  3. if it has no parent, use the defaultLookAndFeel, which is automatically set as a fallback.

#5

Got it. Thank you!

I knew I must be missing some simple way of going about this.


#6

I’d like to do some custom ColourId’s. Is there a table which lists what ids are taken already?

I’ve noticed things like Slider using custom defined ids, but I don’t know how to avoid collision like this.


#7

Unfortunately there isn’t any. I once created a Component, that I added to the LookAndFeel, but unfortunately it’s not designed to be extended by anybody. You pick a number somewhere in high ranges, but there is always the danger for collisions later :frowning:


#8

kk. that’s fine. I’ll just modify look and feel to have an optional boolean shouldBeUnique, then assert that it’s not predefined.


#9

#10

FYI, for sharing a unique instance of a LookAndFeel and don’t incur in static initialization problems, I usually do something like this:

class MyCoolLookAndFeel : public LookAndFeel_V4
{
    static MyCoolLookAndFeel& getInstance()
    {
          static MyCoolLookAndFeel instance;
          return instance;
    }

   // here goes the usual implementation of the LnF
}

At that point, you can set the look and feel to the components that you want with

component.setLookAndFeel (&MyCoolLookAndFeel::getInstance());

And this will ensure that the single instance will be created only upon first usage (i.e. avoiding the static initialization happening in undetermined order)