DISTRHO Plugin Framework
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.

157 lines
3.4KB

  1. #ifndef KEYBOARD_WIDGET_H_INCLUDED
  2. #define KEYBOARD_WIDGET_H_INCLUDED
  3. #include "Widget.hpp"
  4. #include "Image.hpp"
  5. #include "SVG.hpp"
  6. #include "PianoKey.hpp"
  7. START_NAMESPACE_DISTRHO
  8. class KeyboardWidget : public Widget
  9. {
  10. public:
  11. class Callback
  12. {
  13. public:
  14. virtual ~Callback() {}
  15. virtual void keyboardKeyPressed(const uint keyIndex) = 0;
  16. virtual void keyboardKeyReleased(const uint keyIndex) = 0;
  17. };
  18. KeyboardWidget(Window& parent);
  19. /**
  20. Set the 'pressed' state of a key in the keyboard.
  21. */
  22. void setKeyPressed(const int keyIndex, const bool pressed, const bool sendCallback = false);
  23. void setCallback(Callback* callback);
  24. protected:
  25. /**
  26. Draw the piano keys.
  27. */
  28. void onDisplay() override;
  29. /**
  30. Handle mouse events.
  31. */
  32. bool onMouse(const MouseEvent& ev) override;
  33. /**
  34. Handle mouse motion.
  35. */
  36. bool onMotion(const MotionEvent& ev) override;
  37. private:
  38. /**
  39. Get the key that is under the specified point.
  40. Return nullptr if the point is not hovering any key.
  41. */
  42. PianoKey* tryGetHoveredKey(const Point<int>& point);
  43. void setupKeyLookupTable();
  44. /**
  45. Associate every key with its proper images.
  46. */
  47. void setKeyImages();
  48. /**
  49. Put the keys at their proper position in the keyboard.
  50. */
  51. void positionKeys();
  52. /**
  53. Determine if a note at a certain index is associated with a white key.
  54. */
  55. bool isWhiteKey(const uint noteIndex);
  56. /**
  57. Determine if a note at a certain index is associated with a black key.
  58. */
  59. bool isBlackKey(const uint noteIndex);
  60. /**
  61. Identifiers used for accessing the graphical resources of the widget.
  62. */
  63. enum Resources
  64. {
  65. kWhiteKeyResourceIndex = 0,
  66. kWhiteKeyPressedResourceIndex,
  67. kBlackKeyResourceIndex,
  68. kBlackKeyPressedResourceIndex,
  69. kResourcesCount
  70. };
  71. /**
  72. The number of octaves displayed in the keyboard.
  73. */
  74. static const int kOctaves = 2;
  75. /**
  76. The number of white keys displayed in the keyboard.
  77. */
  78. static const int kWhiteKeysCount = 7 * kOctaves + 1;
  79. /**
  80. The spacing in pixels between the white keys.
  81. */
  82. static const int kWhiteKeySpacing = 3;
  83. /**
  84. The number of black keys in the keyboard.
  85. */
  86. static const int kBlackKeysCount = 5 * kOctaves;
  87. /**
  88. The number of keys in the keyboard.
  89. */
  90. static const int kKeyCount = kWhiteKeysCount + kBlackKeysCount;
  91. /**
  92. The keyboard's white keys.
  93. */
  94. PianoKey fWhiteKeys[kWhiteKeysCount];
  95. /**
  96. The keyboard's black keys.
  97. */
  98. PianoKey fBlackKeys[kBlackKeysCount];
  99. /**
  100. Zero-indexed lookup table that maps notes to piano keys.
  101. In this example, 0 is equal to C4.
  102. */
  103. PianoKey* fKeysLookup[kKeyCount];
  104. /**
  105. Graphical resources.
  106. */
  107. SVG fSVGs[kResourcesCount];
  108. Image fImages[kResourcesCount];
  109. /**
  110. The callback pointer, used for notifying the UI of piano key presses and releases.
  111. */
  112. Callback* fCallback;
  113. /**
  114. Whether or not the left mouse button is currently pressed.
  115. */
  116. bool fMouseDown;
  117. /**
  118. The piano key that is currently being pressed with the mouse.
  119. It is a nullptr if no key is currently being held down.
  120. */
  121. PianoKey* fHeldKey;
  122. DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(KeyboardWidget)
  123. };
  124. END_NAMESPACE_DISTRHO
  125. #endif