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.

227 lines
7.3KB

  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. struct ColourPropertyComponent : public PropertyComponent
  22. {
  23. ColourPropertyComponent (UndoManager* undoManager, const String& name, const Value& colour,
  24. Colour defaultColour, bool canResetToDefault)
  25. : PropertyComponent (name),
  26. colourEditor (undoManager, colour, defaultColour, canResetToDefault)
  27. {
  28. addAndMakeVisible (colourEditor);
  29. }
  30. void resized() override
  31. {
  32. colourEditor.setBounds (getLookAndFeel().getPropertyComponentContentPosition (*this));
  33. }
  34. void refresh() override {}
  35. private:
  36. /**
  37. A component that shows a colour swatch with hex ARGB value, and which pops up
  38. a colour selector when you click it.
  39. */
  40. struct ColourEditorComponent : public Component,
  41. public Value::Listener
  42. {
  43. ColourEditorComponent (UndoManager* um, const Value& colour,
  44. Colour defaultCol, const bool canReset)
  45. : undoManager (um), colourValue (colour), defaultColour (defaultCol),
  46. canResetToDefault (canReset)
  47. {
  48. colourValue.addListener (this);
  49. }
  50. void paint (Graphics& g) override
  51. {
  52. const Colour colour (getColour());
  53. g.fillAll (Colours::grey);
  54. g.fillCheckerBoard (getLocalBounds().reduced (2),
  55. 10, 10,
  56. Colour (0xffdddddd).overlaidWith (colour),
  57. Colour (0xffffffff).overlaidWith (colour));
  58. g.setColour (Colours::white.overlaidWith (colour).contrasting());
  59. g.setFont (Font (getHeight() * 0.6f, Font::bold));
  60. g.drawFittedText (colour.toDisplayString (true), getLocalBounds().reduced (2, 1),
  61. Justification::centred, 1);
  62. }
  63. Colour getColour() const
  64. {
  65. if (colourValue.toString().isEmpty())
  66. return defaultColour;
  67. return Colour::fromString (colourValue.toString());
  68. }
  69. void setColour (Colour newColour)
  70. {
  71. if (getColour() != newColour)
  72. {
  73. if (newColour == defaultColour && canResetToDefault)
  74. colourValue = var();
  75. else
  76. colourValue = newColour.toDisplayString (true);
  77. }
  78. }
  79. void resetToDefault()
  80. {
  81. setColour (defaultColour);
  82. }
  83. void refresh()
  84. {
  85. const Colour col (getColour());
  86. if (col != lastColour)
  87. {
  88. lastColour = col;
  89. repaint();
  90. }
  91. }
  92. void mouseDown (const MouseEvent&) override
  93. {
  94. if (undoManager != nullptr)
  95. undoManager->beginNewTransaction();
  96. CallOutBox::launchAsynchronously (new PopupColourSelector (colourValue,
  97. defaultColour,
  98. canResetToDefault),
  99. getScreenBounds(), nullptr);
  100. }
  101. void valueChanged (Value&) override
  102. {
  103. refresh();
  104. }
  105. UndoManager* undoManager;
  106. Value colourValue;
  107. Colour lastColour;
  108. const Colour defaultColour;
  109. const bool canResetToDefault;
  110. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ColourEditorComponent)
  111. };
  112. //==============================================================================
  113. struct PopupColourSelector : public Component,
  114. public ChangeListener,
  115. public Value::Listener,
  116. public Button::Listener
  117. {
  118. PopupColourSelector (const Value& colour,
  119. Colour defaultCol,
  120. const bool canResetToDefault)
  121. : defaultButton ("Reset to Default"),
  122. colourValue (colour),
  123. defaultColour (defaultCol)
  124. {
  125. addAndMakeVisible (selector);
  126. selector.setName ("Colour");
  127. selector.setCurrentColour (getColour());
  128. selector.addChangeListener (this);
  129. if (canResetToDefault)
  130. {
  131. addAndMakeVisible (defaultButton);
  132. defaultButton.addListener (this);
  133. }
  134. colourValue.addListener (this);
  135. setSize (300, 400);
  136. }
  137. void resized() override
  138. {
  139. if (defaultButton.isVisible())
  140. {
  141. selector.setBounds (0, 0, getWidth(), getHeight() - 30);
  142. defaultButton.changeWidthToFitText (22);
  143. defaultButton.setTopLeftPosition (10, getHeight() - 26);
  144. }
  145. else
  146. {
  147. selector.setBounds (getLocalBounds());
  148. }
  149. }
  150. Colour getColour() const
  151. {
  152. if (colourValue.toString().isEmpty())
  153. return defaultColour;
  154. return Colour::fromString (colourValue.toString());
  155. }
  156. void setColour (Colour newColour)
  157. {
  158. if (getColour() != newColour)
  159. {
  160. if (newColour == defaultColour && defaultButton.isVisible())
  161. colourValue = var();
  162. else
  163. colourValue = newColour.toDisplayString (true);
  164. }
  165. }
  166. void buttonClicked (Button*) override
  167. {
  168. setColour (defaultColour);
  169. selector.setCurrentColour (defaultColour);
  170. }
  171. void changeListenerCallback (ChangeBroadcaster*) override
  172. {
  173. if (selector.getCurrentColour() != getColour())
  174. setColour (selector.getCurrentColour());
  175. }
  176. void valueChanged (Value&) override
  177. {
  178. selector.setCurrentColour (getColour());
  179. }
  180. private:
  181. StoredSettings::ColourSelectorWithSwatches selector;
  182. TextButton defaultButton;
  183. Value colourValue;
  184. Colour defaultColour;
  185. };
  186. ColourEditorComponent colourEditor;
  187. };