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.

226 lines
7.2KB

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