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.

139 lines
4.0KB

  1. #ifndef LIGHTPADCOMPONENT_H_INCLUDED
  2. #define LIGHTPADCOMPONENT_H_INCLUDED
  3. //==============================================================================
  4. /**
  5. Represents a single LED on a Lightpad
  6. */
  7. struct LEDComponent : public Component
  8. {
  9. LEDComponent() : ledColour (Colours::black) { setInterceptsMouseClicks (false, false); }
  10. void setColour (Colour newColour)
  11. {
  12. ledColour = newColour;
  13. repaint();
  14. }
  15. void paint (Graphics& g) override
  16. {
  17. g.setColour (ledColour);
  18. g.fillEllipse (getLocalBounds().toFloat());
  19. }
  20. Colour ledColour;
  21. };
  22. //==============================================================================
  23. /**
  24. A component that is used to represent a Lightpad on-screen
  25. */
  26. class LightpadComponent : public Component
  27. {
  28. public:
  29. LightpadComponent ()
  30. {
  31. for (int x = 0; x < 15; ++x)
  32. for (int y = 0; y < 15; ++y)
  33. addAndMakeVisible (leds.add (new LEDComponent()));
  34. }
  35. void paint (Graphics& g) override
  36. {
  37. auto r = getLocalBounds().toFloat();
  38. // Clip the drawing area to only draw in the block area
  39. {
  40. Path clipArea;
  41. clipArea.addRoundedRectangle (r, r.getWidth() / 20.0f);
  42. g.reduceClipRegion (clipArea);
  43. }
  44. // Fill a black square for the Lightpad
  45. g.fillAll (Colours::black);
  46. }
  47. void resized() override
  48. {
  49. Rectangle<int> r = getLocalBounds().reduced (10);
  50. int circleWidth = r.getWidth() / 15;
  51. int circleHeight = r.getHeight() / 15;
  52. for (int x = 0; x < 15; ++x)
  53. for (int y = 0; y < 15; ++y)
  54. leds.getUnchecked ((x * 15) + y)->setBounds (r.getX() + (x * circleWidth),
  55. r.getY() + (y * circleHeight),
  56. circleWidth, circleHeight);
  57. }
  58. void mouseDown (const MouseEvent& e) override
  59. {
  60. for (int x = 0; x < 15; ++x)
  61. {
  62. for (int y = 0; y < 15; ++y)
  63. {
  64. if (leds.getUnchecked ((x * 15) + y)->getBounds().contains (e.position.toInt()))
  65. {
  66. listeners.call (&Listener::ledClicked, x, y, e.pressure);
  67. }
  68. }
  69. }
  70. }
  71. void mouseDrag (const MouseEvent& e) override
  72. {
  73. for (int x = 0; x < 15; ++x)
  74. {
  75. for (int y = 0; y < 15; ++y)
  76. {
  77. if (leds.getUnchecked ((x * 15) + y)->getBounds().contains (e.position.toInt()))
  78. {
  79. const Time t = e.eventTime;
  80. if (lastLED == Point<int> (x, y) && t.toMilliseconds() - lastMouseEventTime.toMilliseconds() < 50)
  81. return;
  82. listeners.call (&Listener::ledClicked, x, y, e.pressure);
  83. lastLED = Point<int> (x, y);
  84. lastMouseEventTime = t;
  85. }
  86. }
  87. }
  88. }
  89. //==============================================================================
  90. /** Sets the colour of one of the LEDComponents */
  91. void setLEDColour (int x, int y, Colour c)
  92. {
  93. x = jmin (x, 14);
  94. y = jmin (y, 14);
  95. leds.getUnchecked ((x * 15) + y)->setColour (c);
  96. }
  97. //==============================================================================
  98. struct Listener
  99. {
  100. virtual ~Listener() {}
  101. /** Called when an LEDComponent has been clicked */
  102. virtual void ledClicked (int x, int y, float z) = 0;
  103. };
  104. void addListener (Listener* l) { listeners.add (l); }
  105. void removeListener (Listener* l) { listeners.remove (l); }
  106. private:
  107. OwnedArray<LEDComponent> leds;
  108. ListenerList<Listener> listeners;
  109. Time lastMouseEventTime;
  110. Point<int> lastLED;
  111. };
  112. #endif // LIGHTPADCOMPONENT_H_INCLUDED