Cannot access protected member declared in class 'juce::MidiKeyboardComponent'

Hi everyone, I am stuck a bit on something probably simple. I want to use the functions .drawWhiteNote() and getRectangleForKey() in the juce MidiKeyboardComponent Class. I am trying to write a function to change the key colours on the midi keyboard so if there is another way to do it I am all ears. What would I need to do to access these protected members?

It sounds like you could simply use setColour() on the component using MidiKeyboardComponent::ColourIds

2 Likes

That would work if I wanted to change all the key colours but I want to change specific key colours not all of them. This is why I need to use the functions I mentioned…

Gotcha!

You’ll have to make your own subclass of MidiKeyboardComponent. My advice would be to keep it simple by doing something like:

class MyCustomKeyboard : public MidiKeyboardComponent
{
protected:
    void drawWhiteNote(
        int midiNoteNumber, 
        Graphics &g, 
        Rectangle<float> area, 
        bool isDown, bool isOver, 
        Colour lineColour, Colour textColour) override 
    {
        if (/** whatever your custom-colour condition is **/) 
        {
            /** do your custom drawing here **/
        }
        else
        {
            /** fallback to the default implementation **/
            MidiKeyboardComponent::drawWhiteNote(
                midiNoteNumber,
                g,
                area,
                isDown, isOver,
                lineColour, textColour
            );
        }
    }
}

The same would apply to other methods you need to override, you can simply call the base class’ implementation when you just want the “default” behaviour

2 Likes

Thank you so much for that! You’ve saved me a lot of time.This solves the protected issue (I had to use ‘public’ instead of ‘protected’ to access this though but now I am getting error C2512 no appropriate default constructor available. I tried adding a constructor MyCustomKeyboard(){} but it still leads to the same error. In the original MidiKeyboardComponent class in the C:\JUCE\modules\juce_audio_utils…folder there is no default constructor. How do I get around this? Code so far is:
lass MyCustomKeyboard : public MidiKeyboardComponent
{
public:

MyCustomKeyboard()
{
    MidiKeyboardComponent::MidiKeyboardComponent();
}

MyCustomKeyboard(MidiKeyboardState& s, Orientation o)
: state(s), orientation(o)

{
    
    MidiKeyboardComponent::MidiKeyboardComponent (s, o);
    
}

void drawWhiteNote(
    int midiNoteNumber, 
    Graphics &g, 
    Rectangle<float> area, 
    bool isDown, bool isOver, 
    Colour lineColour, Colour textColour) override 
{
    
        MidiKeyboardComponent::drawWhiteNote(
            midiNoteNumber,
            g,
            area,
            isDown, isOver,
            lineColour, textColour
        );
    
}

Rectangle<float> getRectangleForKey (int note) 
{
    return MidiKeyboardComponent::getRectangleForKey 	(note);
}

};

I have decided to do copy and paste the whole MidiKeyboardComponent and make the changes I need to my copy. That way I can make the permissions whatever I want them to be. Thanks everyone for the people, moving on…

You need to call that constructor from the constructor of your subclass.

class MyCustomComponent : public MidiKeyboardComponent
{
    MyCustomComponent(/** args here if you even need any **/) : MidiKeyboardComponent(/** args to construct a MidiKeyboardComponent with **/) {}
}

If you don’t need arguments for your custom component you can just create a default constructor, but that default constructor must call the base class’ constructor since MidiKeyboardComponent does not supply a default constructor.

1 Like