The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

154 lines
6.2KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2022 - Raw Material Software Limited
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 7 End-User License
  8. Agreement and JUCE Privacy Policy.
  9. End User License Agreement: www.juce.com/juce-7-licence
  10. Privacy Policy: www.juce.com/juce-privacy-policy
  11. Or: You may also use this code under the terms of the GPL v3 (see
  12. www.gnu.org/licenses).
  13. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  14. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  15. DISCLAIMED.
  16. ==============================================================================
  17. */
  18. namespace juce
  19. {
  20. //==============================================================================
  21. /**
  22. A component that displays an MPE-compatible keyboard, whose notes can be clicked on.
  23. This component will mimic a physical MPE-compatible keyboard, showing the current state
  24. of an MPEInstrument object. When the on-screen keys are clicked on, it will play these
  25. notes by calling the noteOn() and noteOff() methods of its MPEInstrument object. Moving
  26. the mouse will update the pitchbend and timbre dimensions of the MPEInstrument.
  27. @see MPEInstrument
  28. @tags{Audio}
  29. */
  30. class JUCE_API MPEKeyboardComponent : public KeyboardComponentBase,
  31. private MPEInstrument::Listener,
  32. private Timer
  33. {
  34. public:
  35. //==============================================================================
  36. /** Creates an MPEKeyboardComponent.
  37. @param instrument the MPEInstrument that this component represents
  38. @param orientation whether the keyboard is horizontal or vertical
  39. */
  40. MPEKeyboardComponent (MPEInstrument& instrument, Orientation orientation);
  41. /** Destructor. */
  42. virtual ~MPEKeyboardComponent() override;
  43. //==============================================================================
  44. /** Sets the note-on velocity, or "strike", value that will be used when triggering new notes. */
  45. void setVelocity (float newVelocity) { velocity = jlimit (0.0f, 1.0f, newVelocity); }
  46. /** Sets the pressure value that will be used for new notes. */
  47. void setPressure (float newPressure) { pressure = jlimit (0.0f, 1.0f, newPressure); }
  48. /** Sets the note-off velocity, or "lift", value that will be used when notes are released. */
  49. void setLift (float newLift) { lift = jlimit (0.0f, 1.0f, newLift); }
  50. /** Use this to enable the mouse source pressure to be used for the initial note-on
  51. velocity, or "strike", value if the mouse source supports it.
  52. */
  53. void setUseMouseSourcePressureForStrike (bool usePressureForStrike) { useMouseSourcePressureForStrike = usePressureForStrike; }
  54. //==============================================================================
  55. /** A set of colour IDs to use to change the colour of various aspects of the keyboard.
  56. These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
  57. methods.
  58. @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
  59. */
  60. enum ColourIds
  61. {
  62. whiteNoteColourId = 0x1006000,
  63. blackNoteColourId = 0x1006001,
  64. textLabelColourId = 0x1006002,
  65. noteCircleFillColourId = 0x1006003,
  66. noteCircleOutlineColourId = 0x1006004
  67. };
  68. //==============================================================================
  69. /** @internal */
  70. void mouseDrag (const MouseEvent&) override;
  71. /** @internal */
  72. void mouseDown (const MouseEvent&) override;
  73. /** @internal */
  74. void mouseUp (const MouseEvent&) override;
  75. /** @internal */
  76. void focusLost (FocusChangeType) override;
  77. /** @internal */
  78. void colourChanged() override;
  79. private:
  80. //==========================================================================
  81. struct MPENoteComponent;
  82. //==============================================================================
  83. void drawKeyboardBackground (Graphics& g, Rectangle<float> area) override;
  84. void drawWhiteKey (int midiNoteNumber, Graphics& g, Rectangle<float> area) override;
  85. void drawBlackKey (int midiNoteNumber, Graphics& g, Rectangle<float> area) override;
  86. void updateNoteData (MPENote&);
  87. void noteAdded (MPENote) override;
  88. void notePressureChanged (MPENote) override;
  89. void notePitchbendChanged (MPENote) override;
  90. void noteTimbreChanged (MPENote) override;
  91. void noteReleased (MPENote) override;
  92. void zoneLayoutChanged() override;
  93. void timerCallback() override;
  94. //==============================================================================
  95. MPEValue mousePositionToPitchbend (int, Point<float>);
  96. MPEValue mousePositionToTimbre (Point<float>);
  97. void addNewNote (MPENote);
  98. void removeNote (MPENote);
  99. void handleNoteOns (std::set<MPENote>&);
  100. void handleNoteOffs (std::set<MPENote>&);
  101. void updateNoteComponentBounds (const MPENote&, MPENoteComponent&);
  102. void updateNoteComponents();
  103. void updateZoneLayout();
  104. //==============================================================================
  105. MPEInstrument& instrument;
  106. std::unique_ptr<MPEChannelAssigner> channelAssigner;
  107. CriticalSection activeNotesLock;
  108. std::vector<std::pair<MPENote, bool>> activeNotes;
  109. std::vector<std::unique_ptr<MPENoteComponent>> noteComponents;
  110. std::map<int, uint16> sourceIDMap;
  111. float velocity = 0.7f, pressure = 1.0f, lift = 0.0f;
  112. bool useMouseSourcePressureForStrike = false;
  113. int perNotePitchbendRange = 48;
  114. //==============================================================================
  115. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MPEKeyboardComponent)
  116. };
  117. } // namespace juce