29constexpr uint8 whiteNotes[] = { 0, 2, 4, 5, 7, 9, 11 };
30constexpr uint8 blackNotes[] = { 1, 3, 6, 8, 10 };
36 :
Button ({}), owner (c), delta (d)
44 note = delta < 0 ? (note - 1) / 12 : note / 12 + 1;
68 scrollDown = std::make_unique<UpDownButton> (*
this, -1);
69 scrollUp = std::make_unique<UpDownButton> (*
this, 1);
119 firstKey =
jlimit ((
float) rangeStart, (
float) rangeEnd, firstKey);
126 setLowestVisibleKeyFloat ((
float)
noteNumber);
129void KeyboardComponentBase::setLowestVisibleKeyFloat (
float noteNumber)
152 jassert (ratio >= 0.0f && ratio <= 1.0f);
156 blackNoteLengthRatio = ratio;
169 jassert (ratio >= 0.0f && ratio <= 1.0f);
173 blackNoteWidthRatio = ratio;
202 return getKeyPos (rangeEnd).
getEnd();
212 if (orientation != horizontalKeyboard)
216 if (orientation == verticalKeyboardFacingLeft)
222 return remappedXYToNote (p +
Point<float> (xOffset, 0));
233 for (
int i = 0; i < 5; ++i)
237 if (rangeStart <= note && note <= rangeEnd)
239 if (getKeyPos (note).
contains (pos.
x - xOffset))
250 for (
int i = 0; i < 7; ++i)
254 if (note >= rangeStart && note <= rangeEnd)
256 if (getKeyPos (note).
contains (pos.
x - xOffset))
270 jassert (note >= rangeStart && note <= rangeEnd);
272 auto pos = getKeyPos (note);
273 auto x = pos.getStart();
274 auto w = pos.getLength();
293 case verticalKeyboardFacingLeft:
return { 0, x, (
float)
getWidth(), w };
325 path.
addTriangle (0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f);
329 .withAlpha (buttonDown ? 1.0f : (
mouseOver ? 0.6f : 0.4f)));
338 static const float notePos[] = { 0.0f, 1 - ratio * 0.6f,
339 1.0f, 2 - ratio * 0.4f,
341 3.0f, 4 - ratio * 0.7f,
342 4.0f, 5 - ratio * 0.5f,
343 5.0f, 6 - ratio * 0.3f,
352 return { start, start + width };
362 for (
auto noteNum : whiteNotes)
366 if (rangeStart <= key && key <= rangeEnd)
370 for (
auto noteNum : blackNotes)
374 if (rangeStart <= key && key <= rangeEnd)
387 if (orientation != horizontalKeyboard)
390 auto kx2 = getKeyPos (rangeEnd).
getEnd();
392 if ((
int) firstKey != rangeStart)
396 if (
kx2 -
kx1 <= (
float) w)
398 firstKey = (
float) rangeStart;
404 scrollDown->setVisible (canScroll && firstKey > (
float) rangeStart);
413 if (orientation == horizontalKeyboard)
418 else if (orientation == verticalKeyboardFacingLeft)
440 xOffset = getKeyPos ((
int) firstKey).
getStart();
444 firstKey = (
float) rangeStart;
447 scrollUp->setVisible (canScroll && getKeyPos (rangeEnd).
getStart() > (
float) w);
456 ?
wheel.deltaX : (orientation == verticalKeyboardFacingLeft ?
wheel.deltaY
459 setLowestVisibleKeyFloat (firstKey -
amount * keyWidth);
void sendChangeMessage()
Causes an asynchronous change message to be sent to all the registered listeners.
bool contains(Point< int > localPoint)
Returns true if a given point lies within this component or one of its children.
bool reallyContains(Point< int > localPoint, bool returnTrueIfWithinAChild)
Returns true if a given point lies in this component, taking any overlapping siblings into account.
int getHeight() const noexcept
Returns the component's height in pixels.
void repaint()
Marks the whole component as needing to be redrawn.
Colour findColour(int colourID, bool inheritFromParent=false) const
Looks for a colour that has been registered with the given colour ID number.
int getWidth() const noexcept
Returns the component's width in pixels.
Rectangle< int > getLocalBounds() const noexcept
Returns the component's bounds, relative to its own origin.
virtual void colourChanged()
This method is called when a colour is changed by the setColour() method, or when the look-and-feel i...
void addChildComponent(Component *child, int zOrder=-1)
Adds a child component to this one.
A graphics context, used for drawing a component or image.
void fillPath(const Path &path) const
Fills a path using the currently selected colour or brush.
void setColour(Colour newColour)
Changes the current drawing colour.
void fillAll() const
Fills the context's entire clip region with the current colour or brush.
A base class for drawing a custom MIDI keyboard component.
void setBlackNoteLengthProportion(float ratio) noexcept
Sets the length of the black notes as a proportion of the white note length.
void setLowestVisibleKey(int noteNumber)
If the keyboard extends beyond the size of the component, this will scroll it to show the given key a...
virtual void drawKeyboardBackground(Graphics &g, Rectangle< float > area)=0
Use this method to draw the background of the keyboard that will be drawn under the white and black n...
virtual void drawUpDownButton(Graphics &g, int w, int h, bool isMouseOver, bool isButtonPressed, bool movesOctavesUp)
This can be overridden to draw the up and down buttons that scroll the keyboard up/down in octaves.
virtual void drawWhiteKey(int midiNoteNumber, Graphics &g, Rectangle< float > area)=0
Use this method to draw a white key of the keyboard in a given rectangle.
void setOctaveForMiddleC(int octaveNumForMiddleC)
This sets the octave number which is shown as the octave number for middle C.
void resized() override
Called when this component's size has been changed.
void setScrollButtonWidth(int widthInPixels)
Changes the width used to draw the buttons that scroll the keyboard up/down in octaves.
void mouseWheelMove(const MouseEvent &, const MouseWheelDetails &) override
Called when the mouse-wheel is moved.
void setBlackNoteWidthProportion(float ratio) noexcept
Sets the width of the black notes as a proportion of the white note width.
virtual void drawBlackKey(int midiNoteNumber, Graphics &g, Rectangle< float > area)=0
Use this method to draw a black key of the keyboard in a given rectangle.
float getKeyStartPosition(int midiNoteNumber) const
Returns the position within the component of the left-hand edge of a key.
void setAvailableRange(int lowestNote, int highestNote)
Sets the range of midi notes that the keyboard will be limited to.
float getBlackNoteLength() const noexcept
Returns the absolute length of the black notes.
void setKeyWidth(float widthInPixels)
Changes the width used to draw the white keys.
void paint(Graphics &) override
Components can override this method to draw their content.
int getLowestVisibleKey() const noexcept
Returns the number of the first key shown in the component.
Rectangle< float > getRectangleForKey(int midiNoteNumber) const
Returns the rectangle for a given key.
virtual Range< float > getKeyPosition(int midiNoteNumber, float keyWidth) const
Calculates the position of a given midi-note.
KeyboardComponentBase(Orientation orientation)
Constructor.
void setScrollButtonsVisible(bool canScroll)
If set to true, then scroll buttons will appear at either end of the keyboard if there are too many n...
NoteAndVelocity getNoteAndVelocityAtPosition(Point< float > position, bool includeChildComponents=false)
Returns the note number and velocity for a given position within the component.
Orientation getOrientation() const noexcept
Returns the keyboard's current direction.
Orientation
The direction of the keyboard.
float getTotalKeyboardWidth() const noexcept
Returns the total width needed to fit all the keys in the available range.
void setOrientation(Orientation newOrientation)
Changes the keyboard's current direction.
float getWhiteNoteLength() const noexcept
Returns the absolute length of the white notes.
float getBlackNoteWidthProportion() const noexcept
Returns the width of the black notes as a proportion of the white note width.
This structure is returned by the getNoteAndVelocityAtPosition() method.
static bool isMidiNoteBlack(int noteNumber) noexcept
Returns true if the given midi note number is a black key.
Contains position and status information about a mouse event.
A path is a sequence of lines and curves that may either form a closed shape or be open-ended.
void addTriangle(float x1, float y1, float x2, float y2, float x3, float y3)
Adds a triangle to the path.
AffineTransform getTransformToScaleToFit(float x, float y, float width, float height, bool preserveProportions, Justification justificationType=Justification::centred) const
Returns a transform that can be used to rescale the path to fit into a given space.
void applyTransform(const AffineTransform &transform) noexcept
Applies a 2D transform to all the vertices in the path.
A pair of (x, y) coordinates.
constexpr ValueType getY() const noexcept
Returns the point's y coordinate.
ValueType y
The point's Y coordinate.
ValueType x
The point's X coordinate.
A general-purpose range object, that simply represents any linear range with a start and end point.
constexpr ValueType getStart() const noexcept
Returns the start of the range.
constexpr ValueType getEnd() const noexcept
Returns the end of the range.
Manages a rectangle and allows geometric operations to be performed on it.
constexpr bool approximatelyEqual(Type a, Type b, Tolerance< Type > tolerance=Tolerance< Type >{} .withAbsolute(std::numeric_limits< Type >::min()) .withRelative(std::numeric_limits< Type >::epsilon()))
Returns true if the two floating-point numbers are approximately equal.
constexpr Type jmin(Type a, Type b)
Returns the smaller of two values.
constexpr Type jmax(Type a, Type b)
Returns the larger of two values.
Type jlimit(Type lowerLimit, Type upperLimit, Type valueToConstrain) noexcept
Constrains a value to keep it within a given range.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
unsigned char uint8
A platform-independent 8-bit unsigned integer type.
Contains status information about a mouse wheel event.
Commonly used mathematical constants.