MidiKeyboardComponent request

I've been racking my brain trying to figure out how to get the MidiKeyboardComponent to display multiple colors for noteOn's simultaneously.  the scenario: 

You press down a key  (midikeyboardstate.note = on )

you press down a sustain pedal

you release the key (midikeyboardstate.note = off )

the note turns off on the MidiKeyboardComponent, as expected.  

Ideally, the note in the midikeyboardcomponent would stay lit, but maybe with a different color, until a sustainOff message arrived.   Other note-on presses would be drawn with the normal keyDownOverlayColourId

I tried subclassing MidiKeyboardComponent, and exposing repaintNote() as a protected member: 

class ExtraMidiKeyboardComponent : public MidiKeyboardComponent
{

public:
    ExtraMidiKeyboardComponent( MidiKeyboardState& state, Orientation orientation) : MidiKeyboardComponent( state, orientation) {
        sustainedColor = Colour( UInt32( 0xFF79E2FF) );
    }
    ~ExtraMidiKeyboardComponent(  ) {}

    void drawSustainedNote (int note ) {
        const MessageManagerLock mmLock;
        state->noteOn(1, note, 1);
        setColour( MidiKeyboardComponent::keyDownOverlayColourId, Colours::black );
        repaintIndividualNote( note );
    }

private:
    SharedResourcePointer<MidiKeyboardState> state;
    Colour sustainedColor;
};

and then in my class that uses the MidiKeyboardComponent, I had this: 

    void handleNoteOff( MidiKeyboardState* source, int, int ) {
        if( sustain ) {
            std::cout << "handleNoteOff \n";
            std::vector<int> curNotes = detector->getCurrentOnNotes();
            for( int i = 0; i < curNotes.size(); i++ )
                keyboard->drawSustainedNote( curNotes[i] );
        }
    }

    void setSustain( bool s, const MidiMessage &message ) {
        sustain = s;
        postMessageToList( message );   //triggers repaint()
        if( sustain == false && detector->getCurrentOnNotes().size() == 0) {
            //turn off everything that's still on
            state->allNotesOff(0);
            setKeyboardNoteOnColor(defaultNoteOnColor); //because drawSustainedNotes changes it
        }
    }

What i'm hoping to achieve is that any noteOns are drawn with the color they're always drawn with, and any notes that are sustained after a note-Off occurs, are drawn with a different color. 

I was able to implement this by adding the functionality to MidiKeyboardState.h/cpp and MidiKeyboardComponent.h/cpp, and LookAndFeel_V2.cpp (adding the overlay code) 

 

I can post the code if anyone is interested. 

Sorry for bumping this older thread.

I’m trying to do something similar, that is defining different keyDownOverlay colours for different key ranges.

I’ve found

.setColour(MidiKeyboardComponent::keyDownOverlayColourId, Colour )

but this seems only be suitable for the whole keyboard range.

Is there a straightforward way to do this ?
If not - yes, I’d certainly be interested in the code the OP came up with.

Subclass the class and write your own versions of drawWhite/BlackNote

Thanks.
That’s what I thought about doing but figured rather asking before if there’s another way.
I got it working with overriding the drawing methods meanwhile.

simple example:

void CustomMidiKeyboardComponent::drawBlackNote(int midiNoteNumber, Graphics & g, int x, int y, int w, int h, bool isDown, bool isOver, const Colour & noteFillColour)
{
	if (midiNoteNumber <= splitNote) {
		Colour c(noteFillColour);
                // define keyDownOverlayColour for lower range
		if (isDown)  c = c.overlaidWith(Colours::yellow);
		if (isOver)  c = c.overlaidWith(findColour(mouseOverKeyOverlayColourId));

		g.setColour(c);
		g.fillRect(x, y, w, h);

		if (isDown)
		{
			g.setColour(noteFillColour);
			g.drawRect(x, y, w, h);
		}
		else
		{
			g.setColour(c.brighter());
			const int xIndent = jmax(1, jmin(w, h) / 8);

			g.fillRect(x + xIndent, y, w - xIndent * 2, 7 * h / 8); 
			}
		}

	if (midiNoteNumber > splitNote) {
		Colour c(noteFillColour);
                // define keyDownOverlayColour for upper range
		if (isDown)  c = c.overlaidWith(Colours::navy);
		if (isOver)  c = c.overlaidWith(findColour(mouseOverKeyOverlayColourId));

		g.setColour(c);
		g.fillRect(x, y, w, h);

		if (isDown)
		{
			g.setColour(noteFillColour);
			g.drawRect(x, y, w, h);
		}
		else
		{
			g.setColour(c.brighter());
			const int xIndent = jmax(1, jmin(w, h) / 8);

			g.fillRect(x + xIndent, y, w - xIndent * 2, 7 * h / 8);
		}
	}
}

edit:
shorter version is to set overlay color directly

        // ...
	if (isDown) {
		if (midiNoteNumber <= splitNote) {
			c = c.overlaidWith(Colours::yellow);
		}
		if (midiNoteNumber > splitNote) {
			c = c.overlaidWith(Colours::navy);
		}
		
	}
        // ...