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.

161 lines
4.8KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2017 - ROLI Ltd.
  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 5 End-User License
  8. Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
  9. 27th April 2017).
  10. End User License Agreement: www.juce.com/juce-5-licence
  11. Privacy Policy: www.juce.com/juce-5-privacy-policy
  12. Or: You may also use this code under the terms of the GPL v3 (see
  13. www.gnu.org/licenses).
  14. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  15. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  16. DISCLAIMED.
  17. ==============================================================================
  18. */
  19. #pragma once
  20. //==============================================================================
  21. /**
  22. Represents a single LED on a Lightpad
  23. */
  24. struct LEDComponent : public Component
  25. {
  26. LEDComponent() : ledColour (Colours::black) { setInterceptsMouseClicks (false, false); }
  27. void setColour (Colour newColour)
  28. {
  29. ledColour = newColour;
  30. repaint();
  31. }
  32. void paint (Graphics& g) override
  33. {
  34. g.setColour (ledColour);
  35. g.fillEllipse (getLocalBounds().toFloat());
  36. }
  37. Colour ledColour;
  38. };
  39. //==============================================================================
  40. /**
  41. A component that is used to represent a Lightpad on-screen
  42. */
  43. class LightpadComponent : public Component
  44. {
  45. public:
  46. LightpadComponent ()
  47. {
  48. for (int x = 0; x < 15; ++x)
  49. for (int y = 0; y < 15; ++y)
  50. addAndMakeVisible (leds.add (new LEDComponent()));
  51. }
  52. void paint (Graphics& g) override
  53. {
  54. auto r = getLocalBounds().toFloat();
  55. // Clip the drawing area to only draw in the block area
  56. {
  57. Path clipArea;
  58. clipArea.addRoundedRectangle (r, r.getWidth() / 20.0f);
  59. g.reduceClipRegion (clipArea);
  60. }
  61. // Fill a black square for the Lightpad
  62. g.fillAll (Colours::black);
  63. }
  64. void resized() override
  65. {
  66. Rectangle<int> r = getLocalBounds().reduced (10);
  67. int circleWidth = r.getWidth() / 15;
  68. int circleHeight = r.getHeight() / 15;
  69. for (int x = 0; x < 15; ++x)
  70. for (int y = 0; y < 15; ++y)
  71. leds.getUnchecked ((x * 15) + y)->setBounds (r.getX() + (x * circleWidth),
  72. r.getY() + (y * circleHeight),
  73. circleWidth, circleHeight);
  74. }
  75. void mouseDown (const MouseEvent& e) override
  76. {
  77. for (int x = 0; x < 15; ++x)
  78. {
  79. for (int y = 0; y < 15; ++y)
  80. {
  81. if (leds.getUnchecked ((x * 15) + y)->getBounds().contains (e.position.toInt()))
  82. {
  83. listeners.call (&Listener::ledClicked, x, y, e.pressure);
  84. }
  85. }
  86. }
  87. }
  88. void mouseDrag (const MouseEvent& e) override
  89. {
  90. for (int x = 0; x < 15; ++x)
  91. {
  92. for (int y = 0; y < 15; ++y)
  93. {
  94. if (leds.getUnchecked ((x * 15) + y)->getBounds().contains (e.position.toInt()))
  95. {
  96. const Time t = e.eventTime;
  97. if (lastLED == Point<int> (x, y) && t.toMilliseconds() - lastMouseEventTime.toMilliseconds() < 50)
  98. return;
  99. listeners.call (&Listener::ledClicked, x, y, e.pressure);
  100. lastLED = Point<int> (x, y);
  101. lastMouseEventTime = t;
  102. }
  103. }
  104. }
  105. }
  106. //==============================================================================
  107. /** Sets the colour of one of the LEDComponents */
  108. void setLEDColour (int x, int y, Colour c)
  109. {
  110. x = jmin (x, 14);
  111. y = jmin (y, 14);
  112. leds.getUnchecked ((x * 15) + y)->setColour (c);
  113. }
  114. //==============================================================================
  115. struct Listener
  116. {
  117. virtual ~Listener() {}
  118. /** Called when an LEDComponent has been clicked */
  119. virtual void ledClicked (int x, int y, float z) = 0;
  120. };
  121. void addListener (Listener* l) { listeners.add (l); }
  122. void removeListener (Listener* l) { listeners.remove (l); }
  123. private:
  124. OwnedArray<LEDComponent> leds;
  125. ListenerList<Listener> listeners;
  126. Time lastMouseEventTime;
  127. Point<int> lastLED;
  128. };