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.

216 lines
7.0KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE 6 technical preview.
  4. Copyright (c) 2017 - ROLI Ltd.
  5. You may use this code under the terms of the GPL v3
  6. (see www.gnu.org/licenses).
  7. For this technical preview, this file is not subject to commercial licensing.
  8. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  9. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  10. DISCLAIMED.
  11. ==============================================================================
  12. */
  13. #pragma once
  14. //==============================================================================
  15. struct ColourPropertyComponent : public PropertyComponent
  16. {
  17. ColourPropertyComponent (UndoManager* undoManager, const String& name, const Value& colour,
  18. Colour defaultColour, bool canResetToDefault)
  19. : PropertyComponent (name),
  20. colourEditor (undoManager, colour, defaultColour, canResetToDefault)
  21. {
  22. addAndMakeVisible (colourEditor);
  23. }
  24. void resized() override
  25. {
  26. colourEditor.setBounds (getLookAndFeel().getPropertyComponentContentPosition (*this));
  27. }
  28. void refresh() override {}
  29. private:
  30. /**
  31. A component that shows a colour swatch with hex ARGB value, and which pops up
  32. a colour selector when you click it.
  33. */
  34. struct ColourEditorComponent : public Component,
  35. public Value::Listener
  36. {
  37. ColourEditorComponent (UndoManager* um, const Value& colour,
  38. Colour defaultCol, const bool canReset)
  39. : undoManager (um), colourValue (colour), defaultColour (defaultCol),
  40. canResetToDefault (canReset)
  41. {
  42. colourValue.addListener (this);
  43. }
  44. void paint (Graphics& g) override
  45. {
  46. const Colour colour (getColour());
  47. g.fillAll (Colours::grey);
  48. g.fillCheckerBoard (getLocalBounds().reduced (2).toFloat(),
  49. 10.0f, 10.0f,
  50. Colour (0xffdddddd).overlaidWith (colour),
  51. Colour (0xffffffff).overlaidWith (colour));
  52. g.setColour (Colours::white.overlaidWith (colour).contrasting());
  53. g.setFont (Font (getHeight() * 0.6f, Font::bold));
  54. g.drawFittedText (colour.toDisplayString (true), getLocalBounds().reduced (2, 1),
  55. Justification::centred, 1);
  56. }
  57. Colour getColour() const
  58. {
  59. if (colourValue.toString().isEmpty())
  60. return defaultColour;
  61. return Colour::fromString (colourValue.toString());
  62. }
  63. void setColour (Colour newColour)
  64. {
  65. if (getColour() != newColour)
  66. {
  67. if (newColour == defaultColour && canResetToDefault)
  68. colourValue = var();
  69. else
  70. colourValue = newColour.toDisplayString (true);
  71. }
  72. }
  73. void resetToDefault()
  74. {
  75. setColour (defaultColour);
  76. }
  77. void refresh()
  78. {
  79. const Colour col (getColour());
  80. if (col != lastColour)
  81. {
  82. lastColour = col;
  83. repaint();
  84. }
  85. }
  86. void mouseDown (const MouseEvent&) override
  87. {
  88. if (undoManager != nullptr)
  89. undoManager->beginNewTransaction();
  90. CallOutBox::launchAsynchronously (new PopupColourSelector (colourValue,
  91. defaultColour,
  92. canResetToDefault),
  93. getScreenBounds(), nullptr);
  94. }
  95. void valueChanged (Value&) override
  96. {
  97. refresh();
  98. }
  99. UndoManager* undoManager;
  100. Value colourValue;
  101. Colour lastColour;
  102. const Colour defaultColour;
  103. const bool canResetToDefault;
  104. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ColourEditorComponent)
  105. };
  106. //==============================================================================
  107. struct PopupColourSelector : public Component,
  108. public ChangeListener,
  109. public Value::Listener
  110. {
  111. PopupColourSelector (const Value& colour,
  112. Colour defaultCol,
  113. const bool canResetToDefault)
  114. : defaultButton ("Reset to Default"),
  115. colourValue (colour),
  116. defaultColour (defaultCol)
  117. {
  118. addAndMakeVisible (selector);
  119. selector.setName ("Colour");
  120. selector.setCurrentColour (getColour());
  121. selector.addChangeListener (this);
  122. if (canResetToDefault)
  123. {
  124. addAndMakeVisible (defaultButton);
  125. defaultButton.onClick = [this]
  126. {
  127. setColour (defaultColour);
  128. selector.setCurrentColour (defaultColour);
  129. };
  130. }
  131. colourValue.addListener (this);
  132. setSize (300, 400);
  133. }
  134. void resized() override
  135. {
  136. if (defaultButton.isVisible())
  137. {
  138. selector.setBounds (0, 0, getWidth(), getHeight() - 30);
  139. defaultButton.changeWidthToFitText (22);
  140. defaultButton.setTopLeftPosition (10, getHeight() - 26);
  141. }
  142. else
  143. {
  144. selector.setBounds (getLocalBounds());
  145. }
  146. }
  147. Colour getColour() const
  148. {
  149. if (colourValue.toString().isEmpty())
  150. return defaultColour;
  151. return Colour::fromString (colourValue.toString());
  152. }
  153. void setColour (Colour newColour)
  154. {
  155. if (getColour() != newColour)
  156. {
  157. if (newColour == defaultColour && defaultButton.isVisible())
  158. colourValue = var();
  159. else
  160. colourValue = newColour.toDisplayString (true);
  161. }
  162. }
  163. void changeListenerCallback (ChangeBroadcaster*) override
  164. {
  165. if (selector.getCurrentColour() != getColour())
  166. setColour (selector.getCurrentColour());
  167. }
  168. void valueChanged (Value&) override
  169. {
  170. selector.setCurrentColour (getColour());
  171. }
  172. private:
  173. StoredSettings::ColourSelectorWithSwatches selector;
  174. TextButton defaultButton;
  175. Value colourValue;
  176. Colour defaultColour;
  177. };
  178. ColourEditorComponent colourEditor;
  179. };