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.

256 lines
7.7KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-10 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. #ifndef __JUCER_COLOUREDITORCOMPONENT_JUCEHEADER__
  19. #define __JUCER_COLOUREDITORCOMPONENT_JUCEHEADER__
  20. //==============================================================================
  21. /**
  22. A component that shows a colour swatch with hex ARGB value, and which pops up
  23. a colour selector when you click it.
  24. */
  25. class ColourEditorComponent : public Component,
  26. public ChangeListener,
  27. public Value::Listener
  28. {
  29. public:
  30. ColourEditorComponent (ComponentDocument& document_, const Value& colourValue_,
  31. const Colour& defaultColour_, const bool canResetToDefault_)
  32. : document (document_), colourValue (colourValue_), defaultColour (defaultColour_),
  33. canResetToDefault (canResetToDefault_)
  34. {
  35. colourValue.addListener (this);
  36. }
  37. ~ColourEditorComponent()
  38. {
  39. colourValue.removeListener (this);
  40. }
  41. void paint (Graphics& g)
  42. {
  43. const Colour colour (getColour());
  44. g.fillAll (Colours::grey);
  45. g.fillCheckerBoard (2, 2, getWidth() - 4, getHeight() - 4,
  46. 10, 10,
  47. Colour (0xffdddddd).overlaidWith (colour),
  48. Colour (0xffffffff).overlaidWith (colour));
  49. g.setColour (Colours::white.overlaidWith (colour).contrasting());
  50. g.setFont (getHeight() * 0.6f, Font::bold);
  51. g.drawFittedText (colour.toDisplayString (true),
  52. 2, 1, getWidth() - 4, getHeight() - 1,
  53. Justification::centred, 1);
  54. }
  55. const Colour getColour() const
  56. {
  57. if (colourValue.toString().isEmpty())
  58. return defaultColour;
  59. return Colour::fromString (colourValue.toString());
  60. }
  61. void setColour (const Colour& newColour)
  62. {
  63. if (getColour() != newColour)
  64. {
  65. if (newColour == defaultColour && canResetToDefault)
  66. colourValue = var();
  67. else
  68. colourValue = newColour.toDisplayString (true);
  69. }
  70. }
  71. void resetToDefault()
  72. {
  73. setColour (defaultColour);
  74. }
  75. void refresh()
  76. {
  77. const Colour col (getColour());
  78. if (col != lastColour)
  79. {
  80. lastColour = col;
  81. repaint();
  82. }
  83. }
  84. void mouseDown (const MouseEvent& e)
  85. {
  86. SafePointer<Component> deletionChecker (this);
  87. {
  88. ColourSelectorComp colourSelector (this, canResetToDefault);
  89. PopupMenu m;
  90. m.addCustomItem (1234, &colourSelector, 300, 400, false);
  91. m.showAt (this);
  92. if (deletionChecker == 0)
  93. return;
  94. }
  95. const Colour newColour (getColour());
  96. document.getUndoManager()->undoCurrentTransactionOnly();
  97. setColour (newColour);
  98. }
  99. void valueChanged (Value&)
  100. {
  101. refresh();
  102. }
  103. void changeListenerCallback (void* source)
  104. {
  105. ColourSelector* cs = static_cast <ColourSelector*> (source);
  106. if (cs->getCurrentColour() != getColour())
  107. {
  108. document.getUndoManager()->undoCurrentTransactionOnly();
  109. setColour (cs->getCurrentColour());
  110. }
  111. }
  112. juce_UseDebuggingNewOperator
  113. private:
  114. ComponentDocument& document;
  115. Value colourValue;
  116. Colour lastColour;
  117. const Colour defaultColour;
  118. const bool canResetToDefault;
  119. class ColourSelectorComp : public Component,
  120. public ButtonListener
  121. {
  122. public:
  123. ColourSelectorComp (ColourEditorComponent* owner_,
  124. const bool canResetToDefault)
  125. : owner (owner_),
  126. defaultButton ("Reset to Default")
  127. {
  128. addAndMakeVisible (&selector);
  129. selector.setName ("Colour");
  130. selector.setCurrentColour (owner->getColour());
  131. selector.addChangeListener (owner);
  132. if (canResetToDefault)
  133. {
  134. addAndMakeVisible (&defaultButton);
  135. defaultButton.addButtonListener (this);
  136. }
  137. }
  138. ~ColourSelectorComp()
  139. {
  140. }
  141. void resized()
  142. {
  143. if (defaultButton.isVisible())
  144. {
  145. selector.setBounds (0, 0, getWidth(), getHeight() - 30);
  146. defaultButton.changeWidthToFitText (22);
  147. defaultButton.setTopLeftPosition (10, getHeight() - 26);
  148. }
  149. else
  150. {
  151. selector.setBounds (0, 0, getWidth(), getHeight());
  152. }
  153. }
  154. void buttonClicked (Button*)
  155. {
  156. owner->resetToDefault();
  157. owner->refresh();
  158. selector.setCurrentColour (owner->getColour());
  159. }
  160. private:
  161. class ColourSelectorWithSwatches : public ColourSelector
  162. {
  163. public:
  164. ColourSelectorWithSwatches()
  165. {
  166. }
  167. int getNumSwatches() const
  168. {
  169. return StoredSettings::getInstance()->swatchColours.size();
  170. }
  171. const Colour getSwatchColour (const int index) const
  172. {
  173. return StoredSettings::getInstance()->swatchColours [index];
  174. }
  175. void setSwatchColour (const int index, const Colour& newColour) const
  176. {
  177. StoredSettings::getInstance()->swatchColours.set (index, newColour);
  178. }
  179. };
  180. ColourEditorComponent* owner;
  181. ColourSelectorWithSwatches selector;
  182. TextButton defaultButton;
  183. };
  184. };
  185. //==============================================================================
  186. class ColourPropertyComponent : public PropertyComponent
  187. {
  188. public:
  189. //==============================================================================
  190. ColourPropertyComponent (ComponentDocument& document, const String& name, const Value& colour,
  191. const Colour& defaultColour, bool canResetToDefault)
  192. : PropertyComponent (name),
  193. colourEditor (document, colour, defaultColour, canResetToDefault)
  194. {
  195. addAndMakeVisible (&colourEditor);
  196. }
  197. ~ColourPropertyComponent()
  198. {
  199. }
  200. void resized()
  201. {
  202. colourEditor.setBounds (getLookAndFeel().getPropertyComponentContentPosition (*this));
  203. }
  204. void refresh() {}
  205. protected:
  206. ColourEditorComponent colourEditor;
  207. };
  208. #endif // __JUCER_COLOUREDITORCOMPONENT_JUCEHEADER__