void MidiKeyboardComponent::paint (Graphics& g)
{
    g.fillAll (findColour (whiteNoteColourId));

    auto lineColour = findColour (keySeparatorLineColourId);
    auto textColour = findColour (textLabelColourId);

    for (int octave = 0; octave < 128; octave += 12)
    {
        for (int white = 0; white < 7; ++white)
        {
            auto noteNum = octave + whiteNotes[white];

            if (noteNum >= rangeStart && noteNum <= rangeEnd)
                drawWhiteNote (noteNum, g, getRectangleForKey (noteNum),
                               state.isNoteOnForChannels (midiInChannelMask, noteNum),
                               mouseOverNotes.contains (noteNum), lineColour, textColour);
        }
    }

    float x1 = 0.0f, y1 = 0.0f, x2 = 0.0f, y2 = 0.0f;
    auto width = getWidth();
    auto height = getHeight();

    if (orientation == verticalKeyboardFacingLeft)
    {
        x1 = width - 1.0f;
        x2 = width - 5.0f;
    }
    else if (orientation == verticalKeyboardFacingRight)
        x2 = 5.0f;
    else
        y2 = 5.0f;

    auto x = getKeyPos (rangeEnd).getEnd();
    auto shadowCol = findColour (shadowColourId);

    if (! shadowCol.isTransparent())
    {
        g.setGradientFill (ColourGradient (shadowCol, x1, y1, shadowCol.withAlpha (0.0f), x2, y2, false));

        switch (orientation)
        {
            case horizontalKeyboard:            g.fillRect (0.0f, 0.0f, x, 5.0f); break;
            case verticalKeyboardFacingLeft:    g.fillRect (width - 5.0f, 0.0f, 5.0f, x); break;
            case verticalKeyboardFacingRight:   g.fillRect (0.0f, 0.0f, 5.0f, x); break;
            default: break;
        }
    }

    if (! lineColour.isTransparent())
    {
        g.setColour (lineColour);

        switch (orientation)
        {
            case horizontalKeyboard:            g.fillRect (0.0f, height - 1.0f, x, 1.0f); break;
            case verticalKeyboardFacingLeft:    g.fillRect (0.0f, 0.0f, 1.0f, x); break;
            case verticalKeyboardFacingRight:   g.fillRect (width - 1.0f, 0.0f, 1.0f, x); break;
            default: break;
        }
    }

    auto blackNoteColour = findColour (blackNoteColourId);

    for (int octave = 0; octave < 128; octave += 12)
    {
        for (int black = 0; black < 5; ++black)
        {
            auto noteNum = octave + blackNotes[black];

            if (noteNum >= rangeStart && noteNum <= rangeEnd)
                drawBlackNote (noteNum, g, getRectangleForKey (noteNum),
                               state.isNoteOnForChannels (midiInChannelMask, noteNum),
                               mouseOverNotes.contains (noteNum), blackNoteColour);
        }
    }
}
void MidiKeyboardComponent::paint (Graphics& g)
{
    g.fillAll (Colours::white.overlaidWith (findColour (whiteNoteColourId)));

    const Colour lineColour (findColour (keySeparatorLineColourId));
    const Colour textColour (findColour (textLabelColourId));

    int x, w, octave;

    for (octave = 0; octave < 128; octave += 12)
    {
        for (int white = 0; white < 7; ++white)
        {
            const int noteNum = octave + whiteNotes [white];

            if (noteNum >= rangeStart && noteNum <= rangeEnd)
            {
                getKeyPos (noteNum, x, w);

                if (orientation == horizontalKeyboard)
                    drawWhiteNote (noteNum, g, x, 0, w, getHeight(),
                                   state.isNoteOnForChannels (midiInChannelMask, noteNum),
                                   noteUnderMouse == noteNum,
                                   lineColour, textColour);
                else if (orientation == verticalKeyboardFacingLeft)
                    drawWhiteNote (noteNum, g, 0, x, getWidth(), w,
                                   state.isNoteOnForChannels (midiInChannelMask, noteNum),
                                   noteUnderMouse == noteNum,
                                   lineColour, textColour);
                else if (orientation == verticalKeyboardFacingRight)
                    drawWhiteNote (noteNum, g, 0, getHeight() - x - w, getWidth(), w,
                                   state.isNoteOnForChannels (midiInChannelMask, noteNum),
                                   noteUnderMouse == noteNum,
                                   lineColour, textColour);
            }
        }
    }

    float x1 = 0.0f, y1 = 0.0f, x2 = 0.0f, y2 = 0.0f;

    if (orientation == verticalKeyboardFacingLeft)
    {
        x1 = getWidth() - 1.0f;
        x2 = getWidth() - 5.0f;
    }
    else if (orientation == verticalKeyboardFacingRight)
        x2 = 5.0f;
    else
        y2 = 5.0f;

    g.setGradientFill (ColourGradient (Colours::black.withAlpha (0.3f), x1, y1,
                                       Colours::transparentBlack, x2, y2, false));

    getKeyPos (rangeEnd, x, w);
    x += w;

    if (orientation == verticalKeyboardFacingLeft)
        g.fillRect (getWidth() - 5, 0, 5, x);
    else if (orientation == verticalKeyboardFacingRight)
        g.fillRect (0, 0, 5, x);
    else
        g.fillRect (0, 0, x, 5);

    g.setColour (lineColour);

    if (orientation == verticalKeyboardFacingLeft)
        g.fillRect (0, 0, 1, x);
    else if (orientation == verticalKeyboardFacingRight)
        g.fillRect (getWidth() - 1, 0, 1, x);
    else
        g.fillRect (0, getHeight() - 1, x, 1);

    const Colour blackNoteColour (findColour (blackNoteColourId));

    for (octave = 0; octave < 128; octave += 12)
    {
        for (int black = 0; black < 5; ++black)
        {
            const int noteNum = octave + blackNotes [black];

            if (noteNum >= rangeStart && noteNum <= rangeEnd)
            {
                getKeyPos (noteNum, x, w);

                if (orientation == horizontalKeyboard)
                    drawBlackNote (noteNum, g, x, 0, w, blackNoteLength,
                                   state.isNoteOnForChannels (midiInChannelMask, noteNum),
                                   noteUnderMouse == noteNum,
                                   blackNoteColour);
                else if (orientation == verticalKeyboardFacingLeft)
                    drawBlackNote (noteNum, g, getWidth() - blackNoteLength, x, blackNoteLength, w,
                                   state.isNoteOnForChannels (midiInChannelMask, noteNum),
                                   noteUnderMouse == noteNum,
                                   blackNoteColour);
                else if (orientation == verticalKeyboardFacingRight)
                    drawBlackNote (noteNum, g, 0, getHeight() - x - w, blackNoteLength, w,
                                   state.isNoteOnForChannels (midiInChannelMask, noteNum),
                                   noteUnderMouse == noteNum,
                                   blackNoteColour);
            }
        }
    }
}
void MidiKeyboardComponent::paint (Graphics& g)
{
    g.fillAll (Colours::white.overlaidWith (findColour (whiteNoteColourId)));

    const Colour lineColour (findColour (keySeparatorLineColourId));
    const Colour textColour (findColour (textLabelColourId));

    int x, w, octave;

    for (octave = 0; octave < 128; octave += 12)
    {
        for (int white = 0; white < 7; ++white)
        {
            const int noteNum = octave + whiteNotes [white];

            if (noteNum >= rangeStart && noteNum <= rangeEnd)
            {
                const Rectangle<int> pos (getWhiteNotePos (noteNum));

                drawWhiteNote (noteNum, g, pos.getX(), pos.getY(), pos.getWidth(), pos.getHeight(),
                               state.isNoteOnForChannels (midiInChannelMask, noteNum),
                               mouseOverNotes.contains (noteNum), lineColour, textColour);
            }
        }
    }

    float x1 = 0.0f, y1 = 0.0f, x2 = 0.0f, y2 = 0.0f;

    if (orientation == verticalKeyboardFacingLeft)
    {
        x1 = getWidth() - 1.0f;
        x2 = getWidth() - 5.0f;
    }
    else if (orientation == verticalKeyboardFacingRight)
        x2 = 5.0f;
    else
        y2 = 5.0f;

    g.setGradientFill (ColourGradient (Colours::black.withAlpha (0.3f), x1, y1,
                                       Colours::transparentBlack, x2, y2, false));

    getKeyPos (rangeEnd, x, w);
    x += w;

    switch (orientation)
    {
        case horizontalKeyboard:            g.fillRect (0, 0, x, 5); break;
        case verticalKeyboardFacingLeft:    g.fillRect (getWidth() - 5, 0, 5, x); break;
        case verticalKeyboardFacingRight:   g.fillRect (0, 0, 5, x); break;
        default: break;
    }

    g.setColour (lineColour);

    switch (orientation)
    {
        case horizontalKeyboard:            g.fillRect (0, getHeight() - 1, x, 1); break;
        case verticalKeyboardFacingLeft:    g.fillRect (0, 0, 1, x); break;
        case verticalKeyboardFacingRight:   g.fillRect (getWidth() - 1, 0, 1, x); break;
        default: break;
    }

    const Colour blackNoteColour (findColour (blackNoteColourId));

    for (octave = 0; octave < 128; octave += 12)
    {
        for (int black = 0; black < 5; ++black)
        {
            const int noteNum = octave + blackNotes [black];

            if (noteNum >= rangeStart && noteNum <= rangeEnd)
            {
                getKeyPos (noteNum, x, w);
                Rectangle<int> pos;

                switch (orientation)
                {
                    case horizontalKeyboard:            pos.setBounds (x, 0, w, blackNoteLength); break;
                    case verticalKeyboardFacingLeft:    pos.setBounds (getWidth() - blackNoteLength, x, blackNoteLength, w); break;
                    case verticalKeyboardFacingRight:   pos.setBounds (0, getHeight() - x - w, blackNoteLength, w); break;
                    default: break;
                }

                drawBlackNote (noteNum, g, pos.getX(), pos.getY(), pos.getWidth(), pos.getHeight(),
                               state.isNoteOnForChannels (midiInChannelMask, noteNum),
                               mouseOverNotes.contains (noteNum), blackNoteColour);
            }
        }
    }
}