1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-14 00:14:18 +00:00

Fix for text editor line heights with mixed font sizes. Added mouse position velocity to the midi keyboard. Internationalised some text used in the Button class.

This commit is contained in:
Julian Storer 2009-12-27 13:12:28 +00:00
parent df5f73910b
commit 2f8eaf9183
6 changed files with 221 additions and 225 deletions

View file

@ -42701,7 +42701,7 @@ const String Button::getTooltip()
const String key (keyPresses.getReference(i).getTextDescription());
if (key.length() == 1)
tt << " [shortcut: '" << key << "']";
tt << " [" << TRANS("shortcut") << ": '" << key << "']";
else
tt << " [" << key << ']';
}
@ -51610,8 +51610,6 @@ END_JUCE_NAMESPACE
BEGIN_JUCE_NAMESPACE
#define SHOULD_WRAP(x, wrapwidth) (((x) - 0.0001f) >= (wrapwidth))
// a word or space that can't be broken down any further
struct TextAtom
{
@ -51976,12 +51974,11 @@ public:
jassert (wordWrapWidth_ > 0);
if (sections.size() > 0)
{
currentSection = (const UniformTextSection*) sections.getUnchecked (sectionIndex);
if (currentSection != 0)
{
lineHeight = currentSection->font.getHeight();
maxDescent = currentSection->font.getDescent();
if (currentSection != 0)
beginNewLine();
}
}
@ -52029,7 +52026,7 @@ public:
int split;
for (split = 0; split < g.getNumGlyphs(); ++split)
if (SHOULD_WRAP (g.getGlyph (split).getRight(), wordWrapWidth))
if (shouldWrap (g.getGlyph (split).getRight()))
break;
if (split > 0 && split <= numRemaining)
@ -52061,9 +52058,6 @@ public:
atomIndex = 0;
currentSection = (const UniformTextSection*) sections.getUnchecked (sectionIndex);
lineHeight = jmax (lineHeight, currentSection->font.getHeight());
maxDescent = jmax (maxDescent, currentSection->font.getDescent());
}
else
{
@ -52094,7 +52088,7 @@ public:
lineHeight2 = jmax (lineHeight2, s->font.getHeight());
maxDescent2 = jmax (maxDescent2, s->font.getDescent());
if (SHOULD_WRAP (right, wordWrapWidth))
if (shouldWrap (right))
{
lineHeight = lineHeight2;
maxDescent = maxDescent2;
@ -52116,17 +52110,14 @@ public:
indexInText += atom->numChars;
if (atom->isNewLine())
{
atomX = 0;
lineY += lineHeight;
}
beginNewLine();
}
atom = currentSection->getAtom (atomIndex);
atomRight = atomX + atom->width;
++atomIndex;
if (SHOULD_WRAP (atomRight, wordWrapWidth) || forceNewLine)
if (shouldWrap (atomRight) || forceNewLine)
{
if (atom->isWhitespace())
{
@ -52135,36 +52126,78 @@ public:
}
else
{
return wrapCurrentAtom();
atomRight = atom->width;
if (shouldWrap (atomRight)) // atom too big to fit on a line, so break it up..
{
tempAtom = *atom;
tempAtom.width = 0;
tempAtom.numChars = 0;
atom = &tempAtom;
if (atomX > 0)
beginNewLine();
return next();
}
beginNewLine();
return true;
}
}
return true;
}
bool wrapCurrentAtom() throw()
void beginNewLine() throw()
{
atomRight = atom->width;
if (SHOULD_WRAP (atomRight, wordWrapWidth)) // atom too big to fit on a line, so break it up..
{
tempAtom = *atom;
tempAtom.width = 0;
tempAtom.numChars = 0;
atom = &tempAtom;
if (atomX > 0)
{
atomX = 0;
lineY += lineHeight;
}
return next();
}
atomX = 0;
lineY += lineHeight;
return true;
int tempSectionIndex = sectionIndex;
int tempAtomIndex = atomIndex;
const UniformTextSection* section = (const UniformTextSection*) sections.getUnchecked (tempSectionIndex);
lineHeight = section->font.getHeight();
maxDescent = section->font.getDescent();
float x = (atom != 0) ? atom->width : 0;
while (! shouldWrap (x))
{
if (tempSectionIndex >= sections.size())
break;
bool checkSize = false;
if (tempAtomIndex >= section->getNumAtoms())
{
if (++tempSectionIndex >= sections.size())
break;
tempAtomIndex = 0;
section = (const UniformTextSection*) sections.getUnchecked (tempSectionIndex);
checkSize = true;
}
const TextAtom* const nextAtom = section->getAtom (tempAtomIndex);
if (nextAtom == 0)
break;
x += nextAtom->width;
if (shouldWrap (x) || nextAtom->isNewLine())
break;
if (checkSize)
{
lineHeight = jmax (lineHeight, section->font.getHeight());
maxDescent = jmax (maxDescent, section->font.getDescent());
}
++tempAtomIndex;
}
}
void draw (Graphics& g, const UniformTextSection*& lastSection) const throw()
@ -52280,66 +52313,16 @@ public:
return indexInText + j;
}
void updateLineHeight() throw()
{
float x = atomRight;
int tempSectionIndex = sectionIndex;
int tempAtomIndex = atomIndex;
const UniformTextSection* currentSection = (const UniformTextSection*) sections.getUnchecked (tempSectionIndex);
while (! SHOULD_WRAP (x, wordWrapWidth))
{
if (tempSectionIndex >= sections.size())
break;
bool checkSize = false;
if (tempAtomIndex >= currentSection->getNumAtoms())
{
if (++tempSectionIndex >= sections.size())
break;
tempAtomIndex = 0;
currentSection = (const UniformTextSection*) sections.getUnchecked (tempSectionIndex);
checkSize = true;
}
const TextAtom* const atom = currentSection->getAtom (tempAtomIndex);
if (atom == 0)
break;
x += atom->width;
if (SHOULD_WRAP (x, wordWrapWidth) || atom->isNewLine())
break;
if (checkSize)
{
lineHeight = jmax (lineHeight, currentSection->font.getHeight());
maxDescent = jmax (maxDescent, currentSection->font.getDescent());
}
++tempAtomIndex;
}
}
bool getCharPosition (const int index, float& cx, float& cy, float& lineHeight_) throw()
{
while (next())
{
if (indexInText + atom->numChars >= index)
if (indexInText + atom->numChars > index)
{
updateLineHeight();
if (indexInText + atom->numChars > index)
{
cx = indexToX (index);
cy = lineY;
lineHeight_ = lineHeight;
return true;
}
cx = indexToX (index);
cy = lineY;
lineHeight_ = lineHeight;
return true;
}
}
@ -52379,6 +52362,11 @@ private:
}
}
}
bool shouldWrap (const float x) const throw()
{
return (x - 0.0001f) >= wordWrapWidth;
}
};
class TextEditorInsertAction : public UndoableAction
@ -53263,8 +53251,6 @@ void TextEditor::drawContent (Graphics& g)
while (i2.next() && i2.lineY < clip.getBottom())
{
i2.updateLineHeight();
if (i2.lineY + i2.lineHeight >= clip.getY()
&& selectionEnd >= i2.indexInText
&& selectionStart <= i2.indexInText + i2.atom->numChars)
@ -53278,8 +53264,6 @@ void TextEditor::drawContent (Graphics& g)
while (i.next() && i.lineY < clip.getBottom())
{
i.updateLineHeight();
if (i.lineY + i.lineHeight >= clip.getY())
{
if (selectionEnd >= i.indexInText
@ -54093,9 +54077,6 @@ int TextEditor::indexAtPosition (const float x, const float y) throw()
while (i.next())
{
if (i.lineY + getHeight() > y)
i.updateLineHeight();
if (i.lineY + i.lineHeight > y)
{
if (i.lineY > y)
@ -74576,6 +74557,7 @@ MidiKeyboardComponent::MidiKeyboardComponent (MidiKeyboardState& state_,
firstKey (12 * 4),
canScroll (true),
mouseDragging (false),
useMousePositionForVelocity (true),
keyPresses (4),
keyPressNotes (16),
keyMappingOctave (6),
@ -74678,9 +74660,10 @@ void MidiKeyboardComponent::setMidiChannelsToDisplay (const int midiChannelMask)
triggerAsyncUpdate();
}
void MidiKeyboardComponent::setVelocity (const float velocity_)
void MidiKeyboardComponent::setVelocity (const float velocity_, const bool useMousePositionForVelocity_)
{
velocity = jlimit (0.0f, 1.0f, velocity_);
useMousePositionForVelocity = useMousePositionForVelocity_;
}
void MidiKeyboardComponent::getKeyPosition (int midiNoteNumber, const float keyWidth, int& x, int& w) const
@ -74730,7 +74713,7 @@ int MidiKeyboardComponent::getKeyStartPosition (const int midiNoteNumber) const
static const uint8 whiteNotes[] = { 0, 2, 4, 5, 7, 9, 11 };
static const uint8 blackNotes[] = { 1, 3, 6, 8, 10 };
int MidiKeyboardComponent::xyToNote (int x, int y)
int MidiKeyboardComponent::xyToNote (int x, int y, float& mousePositionVelocity)
{
if (! reallyContains (x, y, false))
return -1;
@ -74745,10 +74728,10 @@ int MidiKeyboardComponent::xyToNote (int x, int y)
x = getHeight() - x;
}
return remappedXYToNote (x + xOffset, y);
return remappedXYToNote (x + xOffset, y, mousePositionVelocity);
}
int MidiKeyboardComponent::remappedXYToNote (int x, int y) const
int MidiKeyboardComponent::remappedXYToNote (int x, int y, float& mousePositionVelocity) const
{
if (y < blackNoteLength)
{
@ -74765,7 +74748,10 @@ int MidiKeyboardComponent::remappedXYToNote (int x, int y) const
kx += xOffset;
if (x >= kx && x < kx + kw)
{
mousePositionVelocity = y / (float) blackNoteLength;
return note;
}
}
}
}
@ -74784,11 +74770,15 @@ int MidiKeyboardComponent::remappedXYToNote (int x, int y) const
kx += xOffset;
if (x >= kx && x < kx + kw)
{
mousePositionVelocity = y / (float) getHeight();
return note;
}
}
}
}
mousePositionVelocity = 0;
return -1;
}
@ -75111,8 +75101,9 @@ void MidiKeyboardComponent::resized()
getKeyPos (rangeEnd, endOfLastKey, kw);
endOfLastKey += kw;
float mousePositionVelocity;
const int spaceAvailable = w - scrollButtonW * 2;
const int lastStartKey = remappedXYToNote (endOfLastKey - spaceAvailable, 0) + 1;
const int lastStartKey = remappedXYToNote (endOfLastKey - spaceAvailable, 0, mousePositionVelocity) + 1;
if (lastStartKey >= 0 && firstKey > lastStartKey)
{
@ -75168,8 +75159,9 @@ void MidiKeyboardComponent::resetAnyKeysInUse()
void MidiKeyboardComponent::updateNoteUnderMouse (int x, int y)
{
float mousePositionVelocity;
const int newNote = (mouseDragging || isMouseOver())
? xyToNote (x, y) : -1;
? xyToNote (x, y, mousePositionVelocity) : -1;
if (noteUnderMouse != newNote)
{
@ -75181,7 +75173,10 @@ void MidiKeyboardComponent::updateNoteUnderMouse (int x, int y)
if (mouseDragging && newNote >= 0)
{
state.noteOn (midiChannel, newNote, velocity);
if (! useMousePositionForVelocity)
mousePositionVelocity = 1.0f;
state.noteOn (midiChannel, newNote, mousePositionVelocity * velocity);
mouseDownNote = newNote;
}
@ -75204,7 +75199,8 @@ void MidiKeyboardComponent::mouseMove (const MouseEvent& e)
void MidiKeyboardComponent::mouseDrag (const MouseEvent& e)
{
const int newNote = xyToNote (e.x, e.y);
float mousePositionVelocity;
const int newNote = xyToNote (e.x, e.y, mousePositionVelocity);
if (newNote >= 0)
mouseDraggedToKey (newNote, e);
@ -75223,7 +75219,8 @@ void MidiKeyboardComponent::mouseDraggedToKey (int /*midiNoteNumber*/, const Mou
void MidiKeyboardComponent::mouseDown (const MouseEvent& e)
{
const int newNote = xyToNote (e.x, e.y);
float mousePositionVelocity;
const int newNote = xyToNote (e.x, e.y, mousePositionVelocity);
mouseDragging = false;
if (newNote >= 0 && mouseDownOnKey (newNote, e))

View file

@ -53878,7 +53878,7 @@ public:
@see setMidiChannel
*/
void setVelocity (const float velocity);
void setVelocity (const float velocity, const bool useMousePositionForVelocity);
/** Changes the midi channel number that will be used for events triggered by clicking
on the component.
@ -54178,7 +54178,7 @@ private:
BitArray keysPressed, keysCurrentlyDrawnDown;
int rangeStart, rangeEnd, firstKey;
bool canScroll, mouseDragging;
bool canScroll, mouseDragging, useMousePositionForVelocity;
Button* scrollDown;
Button* scrollUp;
@ -54188,8 +54188,8 @@ private:
int octaveNumForMiddleC;
void getKeyPos (int midiNoteNumber, int& x, int& w) const;
int xyToNote (int x, int y);
int remappedXYToNote (int x, int y) const;
int xyToNote (int x, int y, float& mousePositionVelocity);
int remappedXYToNote (int x, int y, float& mousePositionVelocity) const;
void resetAnyKeysInUse();
void updateNoteUnderMouse (int x, int y);
void repaintNote (const int midiNoteNumber);

View file

@ -30,6 +30,7 @@ BEGIN_JUCE_NAMESPACE
#include "juce_Button.h"
#include "../juce_ComponentDeletionWatcher.h"
#include "../keyboard/juce_KeyPressMappingSet.h"
#include "../../../text/juce_LocalisedStrings.h"
//==============================================================================
@ -99,7 +100,7 @@ const String Button::getTooltip()
const String key (keyPresses.getReference(i).getTextDescription());
if (key.length() == 1)
tt << " [shortcut: '" << key << "']";
tt << " [" << TRANS("shortcut") << ": '" << key << "']";
else
tt << " [" << key << ']';
}

View file

@ -34,7 +34,6 @@ BEGIN_JUCE_NAMESPACE
#include "../../../text/juce_LocalisedStrings.h"
#include "../lookandfeel/juce_LookAndFeel.h"
#define SHOULD_WRAP(x, wrapwidth) (((x) - 0.0001f) >= (wrapwidth))
//==============================================================================
// a word or space that can't be broken down any further
@ -406,12 +405,11 @@ public:
jassert (wordWrapWidth_ > 0);
if (sections.size() > 0)
{
currentSection = (const UniformTextSection*) sections.getUnchecked (sectionIndex);
if (currentSection != 0)
{
lineHeight = currentSection->font.getHeight();
maxDescent = currentSection->font.getDescent();
if (currentSection != 0)
beginNewLine();
}
}
@ -460,7 +458,7 @@ public:
int split;
for (split = 0; split < g.getNumGlyphs(); ++split)
if (SHOULD_WRAP (g.getGlyph (split).getRight(), wordWrapWidth))
if (shouldWrap (g.getGlyph (split).getRight()))
break;
if (split > 0 && split <= numRemaining)
@ -492,9 +490,6 @@ public:
atomIndex = 0;
currentSection = (const UniformTextSection*) sections.getUnchecked (sectionIndex);
lineHeight = jmax (lineHeight, currentSection->font.getHeight());
maxDescent = jmax (maxDescent, currentSection->font.getDescent());
}
else
{
@ -525,7 +520,7 @@ public:
lineHeight2 = jmax (lineHeight2, s->font.getHeight());
maxDescent2 = jmax (maxDescent2, s->font.getDescent());
if (SHOULD_WRAP (right, wordWrapWidth))
if (shouldWrap (right))
{
lineHeight = lineHeight2;
maxDescent = maxDescent2;
@ -547,17 +542,14 @@ public:
indexInText += atom->numChars;
if (atom->isNewLine())
{
atomX = 0;
lineY += lineHeight;
}
beginNewLine();
}
atom = currentSection->getAtom (atomIndex);
atomRight = atomX + atom->width;
++atomIndex;
if (SHOULD_WRAP (atomRight, wordWrapWidth) || forceNewLine)
if (shouldWrap (atomRight) || forceNewLine)
{
if (atom->isWhitespace())
{
@ -566,36 +558,78 @@ public:
}
else
{
return wrapCurrentAtom();
atomRight = atom->width;
if (shouldWrap (atomRight)) // atom too big to fit on a line, so break it up..
{
tempAtom = *atom;
tempAtom.width = 0;
tempAtom.numChars = 0;
atom = &tempAtom;
if (atomX > 0)
beginNewLine();
return next();
}
beginNewLine();
return true;
}
}
return true;
}
bool wrapCurrentAtom() throw()
void beginNewLine() throw()
{
atomRight = atom->width;
if (SHOULD_WRAP (atomRight, wordWrapWidth)) // atom too big to fit on a line, so break it up..
{
tempAtom = *atom;
tempAtom.width = 0;
tempAtom.numChars = 0;
atom = &tempAtom;
if (atomX > 0)
{
atomX = 0;
lineY += lineHeight;
}
return next();
}
atomX = 0;
lineY += lineHeight;
return true;
int tempSectionIndex = sectionIndex;
int tempAtomIndex = atomIndex;
const UniformTextSection* section = (const UniformTextSection*) sections.getUnchecked (tempSectionIndex);
lineHeight = section->font.getHeight();
maxDescent = section->font.getDescent();
float x = (atom != 0) ? atom->width : 0;
while (! shouldWrap (x))
{
if (tempSectionIndex >= sections.size())
break;
bool checkSize = false;
if (tempAtomIndex >= section->getNumAtoms())
{
if (++tempSectionIndex >= sections.size())
break;
tempAtomIndex = 0;
section = (const UniformTextSection*) sections.getUnchecked (tempSectionIndex);
checkSize = true;
}
const TextAtom* const nextAtom = section->getAtom (tempAtomIndex);
if (nextAtom == 0)
break;
x += nextAtom->width;
if (shouldWrap (x) || nextAtom->isNewLine())
break;
if (checkSize)
{
lineHeight = jmax (lineHeight, section->font.getHeight());
maxDescent = jmax (maxDescent, section->font.getDescent());
}
++tempAtomIndex;
}
}
//==============================================================================
@ -714,66 +748,16 @@ public:
}
//==============================================================================
void updateLineHeight() throw()
{
float x = atomRight;
int tempSectionIndex = sectionIndex;
int tempAtomIndex = atomIndex;
const UniformTextSection* currentSection = (const UniformTextSection*) sections.getUnchecked (tempSectionIndex);
while (! SHOULD_WRAP (x, wordWrapWidth))
{
if (tempSectionIndex >= sections.size())
break;
bool checkSize = false;
if (tempAtomIndex >= currentSection->getNumAtoms())
{
if (++tempSectionIndex >= sections.size())
break;
tempAtomIndex = 0;
currentSection = (const UniformTextSection*) sections.getUnchecked (tempSectionIndex);
checkSize = true;
}
const TextAtom* const atom = currentSection->getAtom (tempAtomIndex);
if (atom == 0)
break;
x += atom->width;
if (SHOULD_WRAP (x, wordWrapWidth) || atom->isNewLine())
break;
if (checkSize)
{
lineHeight = jmax (lineHeight, currentSection->font.getHeight());
maxDescent = jmax (maxDescent, currentSection->font.getDescent());
}
++tempAtomIndex;
}
}
bool getCharPosition (const int index, float& cx, float& cy, float& lineHeight_) throw()
{
while (next())
{
if (indexInText + atom->numChars >= index)
if (indexInText + atom->numChars > index)
{
updateLineHeight();
if (indexInText + atom->numChars > index)
{
cx = indexToX (index);
cy = lineY;
lineHeight_ = lineHeight;
return true;
}
cx = indexToX (index);
cy = lineY;
lineHeight_ = lineHeight;
return true;
}
}
@ -814,6 +798,11 @@ private:
}
}
}
bool shouldWrap (const float x) const throw()
{
return (x - 0.0001f) >= wordWrapWidth;
}
};
@ -1716,8 +1705,6 @@ void TextEditor::drawContent (Graphics& g)
while (i2.next() && i2.lineY < clip.getBottom())
{
i2.updateLineHeight();
if (i2.lineY + i2.lineHeight >= clip.getY()
&& selectionEnd >= i2.indexInText
&& selectionStart <= i2.indexInText + i2.atom->numChars)
@ -1731,8 +1718,6 @@ void TextEditor::drawContent (Graphics& g)
while (i.next() && i.lineY < clip.getBottom())
{
i.updateLineHeight();
if (i.lineY + i.lineHeight >= clip.getY())
{
if (selectionEnd >= i.indexInText
@ -2553,9 +2538,6 @@ int TextEditor::indexAtPosition (const float x, const float y) throw()
while (i.next())
{
if (i.lineY + getHeight() > y)
i.updateLineHeight();
if (i.lineY + i.lineHeight > y)
{
if (i.lineY > y)

View file

@ -94,6 +94,7 @@ MidiKeyboardComponent::MidiKeyboardComponent (MidiKeyboardState& state_,
firstKey (12 * 4),
canScroll (true),
mouseDragging (false),
useMousePositionForVelocity (true),
keyPresses (4),
keyPressNotes (16),
keyMappingOctave (6),
@ -198,9 +199,10 @@ void MidiKeyboardComponent::setMidiChannelsToDisplay (const int midiChannelMask)
triggerAsyncUpdate();
}
void MidiKeyboardComponent::setVelocity (const float velocity_)
void MidiKeyboardComponent::setVelocity (const float velocity_, const bool useMousePositionForVelocity_)
{
velocity = jlimit (0.0f, 1.0f, velocity_);
useMousePositionForVelocity = useMousePositionForVelocity_;
}
//==============================================================================
@ -251,7 +253,7 @@ int MidiKeyboardComponent::getKeyStartPosition (const int midiNoteNumber) const
static const uint8 whiteNotes[] = { 0, 2, 4, 5, 7, 9, 11 };
static const uint8 blackNotes[] = { 1, 3, 6, 8, 10 };
int MidiKeyboardComponent::xyToNote (int x, int y)
int MidiKeyboardComponent::xyToNote (int x, int y, float& mousePositionVelocity)
{
if (! reallyContains (x, y, false))
return -1;
@ -266,10 +268,10 @@ int MidiKeyboardComponent::xyToNote (int x, int y)
x = getHeight() - x;
}
return remappedXYToNote (x + xOffset, y);
return remappedXYToNote (x + xOffset, y, mousePositionVelocity);
}
int MidiKeyboardComponent::remappedXYToNote (int x, int y) const
int MidiKeyboardComponent::remappedXYToNote (int x, int y, float& mousePositionVelocity) const
{
if (y < blackNoteLength)
{
@ -286,7 +288,10 @@ int MidiKeyboardComponent::remappedXYToNote (int x, int y) const
kx += xOffset;
if (x >= kx && x < kx + kw)
{
mousePositionVelocity = y / (float) blackNoteLength;
return note;
}
}
}
}
@ -305,11 +310,15 @@ int MidiKeyboardComponent::remappedXYToNote (int x, int y) const
kx += xOffset;
if (x >= kx && x < kx + kw)
{
mousePositionVelocity = y / (float) getHeight();
return note;
}
}
}
}
mousePositionVelocity = 0;
return -1;
}
@ -633,8 +642,9 @@ void MidiKeyboardComponent::resized()
getKeyPos (rangeEnd, endOfLastKey, kw);
endOfLastKey += kw;
float mousePositionVelocity;
const int spaceAvailable = w - scrollButtonW * 2;
const int lastStartKey = remappedXYToNote (endOfLastKey - spaceAvailable, 0) + 1;
const int lastStartKey = remappedXYToNote (endOfLastKey - spaceAvailable, 0, mousePositionVelocity) + 1;
if (lastStartKey >= 0 && firstKey > lastStartKey)
{
@ -692,8 +702,9 @@ void MidiKeyboardComponent::resetAnyKeysInUse()
void MidiKeyboardComponent::updateNoteUnderMouse (int x, int y)
{
float mousePositionVelocity;
const int newNote = (mouseDragging || isMouseOver())
? xyToNote (x, y) : -1;
? xyToNote (x, y, mousePositionVelocity) : -1;
if (noteUnderMouse != newNote)
{
@ -705,7 +716,10 @@ void MidiKeyboardComponent::updateNoteUnderMouse (int x, int y)
if (mouseDragging && newNote >= 0)
{
state.noteOn (midiChannel, newNote, velocity);
if (! useMousePositionForVelocity)
mousePositionVelocity = 1.0f;
state.noteOn (midiChannel, newNote, mousePositionVelocity * velocity);
mouseDownNote = newNote;
}
@ -728,7 +742,8 @@ void MidiKeyboardComponent::mouseMove (const MouseEvent& e)
void MidiKeyboardComponent::mouseDrag (const MouseEvent& e)
{
const int newNote = xyToNote (e.x, e.y);
float mousePositionVelocity;
const int newNote = xyToNote (e.x, e.y, mousePositionVelocity);
if (newNote >= 0)
mouseDraggedToKey (newNote, e);
@ -747,7 +762,8 @@ void MidiKeyboardComponent::mouseDraggedToKey (int /*midiNoteNumber*/, const Mou
void MidiKeyboardComponent::mouseDown (const MouseEvent& e)
{
const int newNote = xyToNote (e.x, e.y);
float mousePositionVelocity;
const int newNote = xyToNote (e.x, e.y, mousePositionVelocity);
mouseDragging = false;
if (newNote >= 0 && mouseDownOnKey (newNote, e))

View file

@ -89,7 +89,7 @@ public:
@see setMidiChannel
*/
void setVelocity (const float velocity);
void setVelocity (const float velocity, const bool useMousePositionForVelocity);
/** Changes the midi channel number that will be used for events triggered by clicking
on the component.
@ -395,7 +395,7 @@ private:
BitArray keysPressed, keysCurrentlyDrawnDown;
int rangeStart, rangeEnd, firstKey;
bool canScroll, mouseDragging;
bool canScroll, mouseDragging, useMousePositionForVelocity;
Button* scrollDown;
Button* scrollUp;
@ -405,8 +405,8 @@ private:
int octaveNumForMiddleC;
void getKeyPos (int midiNoteNumber, int& x, int& w) const;
int xyToNote (int x, int y);
int remappedXYToNote (int x, int y) const;
int xyToNote (int x, int y, float& mousePositionVelocity);
int remappedXYToNote (int x, int y, float& mousePositionVelocity) const;
void resetAnyKeysInUse();
void updateNoteUnderMouse (int x, int y);
void repaintNote (const int midiNoteNumber);