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.

224 lines
7.3KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2020 - Raw Material Software Limited
  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 6 End-User License
  8. Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
  9. End User License Agreement: www.juce.com/juce-6-licence
  10. Privacy Policy: www.juce.com/juce-privacy-policy
  11. Or: You may also use this code under the terms of the GPL v3 (see
  12. www.gnu.org/licenses).
  13. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  14. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  15. DISCLAIMED.
  16. ==============================================================================
  17. */
  18. #pragma once
  19. //==============================================================================
  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. private 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).toFloat(),
  54. 10.0f, 10.0f,
  55. Colour (0xffdddddd).overlaidWith (colour),
  56. Colour (0xffffffff).overlaidWith (colour));
  57. g.setColour (Colours::white.overlaidWith (colour).contrasting());
  58. g.setFont (Font ((float) 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. private:
  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. private ChangeListener,
  115. private Value::Listener
  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.onClick = [this]
  132. {
  133. setColour (defaultColour);
  134. selector.setCurrentColour (defaultColour);
  135. };
  136. }
  137. colourValue.addListener (this);
  138. setSize (300, 400);
  139. }
  140. void resized() override
  141. {
  142. if (defaultButton.isVisible())
  143. {
  144. selector.setBounds (0, 0, getWidth(), getHeight() - 30);
  145. defaultButton.changeWidthToFitText (22);
  146. defaultButton.setTopLeftPosition (10, getHeight() - 26);
  147. }
  148. else
  149. {
  150. selector.setBounds (getLocalBounds());
  151. }
  152. }
  153. Colour getColour() const
  154. {
  155. if (colourValue.toString().isEmpty())
  156. return defaultColour;
  157. return Colour::fromString (colourValue.toString());
  158. }
  159. void setColour (Colour newColour)
  160. {
  161. if (getColour() != newColour)
  162. {
  163. if (newColour == defaultColour && defaultButton.isVisible())
  164. colourValue = var();
  165. else
  166. colourValue = newColour.toDisplayString (true);
  167. }
  168. }
  169. private:
  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. StoredSettings::ColourSelectorWithSwatches selector;
  180. TextButton defaultButton;
  181. Value colourValue;
  182. Colour defaultColour;
  183. };
  184. ColourEditorComponent colourEditor;
  185. };