diff --git a/examples/GUI/WidgetsDemo.h b/examples/GUI/WidgetsDemo.h index 27a6220038..4aaa20ed65 100644 --- a/examples/GUI/WidgetsDemo.h +++ b/examples/GUI/WidgetsDemo.h @@ -87,7 +87,12 @@ public: void clicked() override { - auto* colourSelector = new ColourSelector(); + auto* colourSelector = new ColourSelector (ColourSelector::showAlphaChannel + | ColourSelector::showColourAtTop + | ColourSelector::editableColour + | ColourSelector::showSliders + | ColourSelector::showColourspace); + colourSelector->setName ("background"); colourSelector->setCurrentColour (findColour (TextButton::buttonColourId)); colourSelector->addChangeListener (this); diff --git a/modules/juce_gui_extra/misc/juce_ColourSelector.cpp b/modules/juce_gui_extra/misc/juce_ColourSelector.cpp index 976b598226..5c98a4e6c1 100644 --- a/modules/juce_gui_extra/misc/juce_ColourSelector.cpp +++ b/modules/juce_gui_extra/misc/juce_ColourSelector.cpp @@ -302,6 +302,85 @@ private: JUCE_DECLARE_NON_COPYABLE (SwatchComponent) }; +//============================================================================== +class ColourSelector::ColourPreviewComp : public Component +{ +public: + ColourPreviewComp (ColourSelector& cs, bool isEditable) + : owner (cs) + { + colourLabel.setFont (labelFont); + colourLabel.setJustificationType (Justification::centred); + + if (isEditable) + { + colourLabel.setEditable (true); + + colourLabel.onEditorShow = [this] + { + if (auto* ed = colourLabel.getCurrentTextEditor()) + ed->setInputRestrictions ((owner.flags & showAlphaChannel) ? 8 : 6, "1234567890ABCDEFabcdef"); + }; + + colourLabel.onEditorHide = [this] + { + updateColourIfNecessary (colourLabel.getText()); + }; + } + + addAndMakeVisible (colourLabel); + } + + void updateIfNeeded() + { + auto newColour = owner.getCurrentColour(); + + if (currentColour != newColour) + { + currentColour = newColour; + auto textColour = (Colours::white.overlaidWith (currentColour).contrasting()); + + colourLabel.setColour (Label::textColourId, textColour); + colourLabel.setColour (Label::textWhenEditingColourId, textColour); + colourLabel.setText (currentColour.toDisplayString ((owner.flags & showAlphaChannel) != 0), dontSendNotification); + + labelWidth = labelFont.getStringWidth (colourLabel.getText()); + + repaint(); + } + } + + void paint (Graphics& g) override + { + g.fillCheckerBoard (getLocalBounds().toFloat(), 10.0f, 10.0f, + Colour (0xffdddddd).overlaidWith (currentColour), + Colour (0xffffffff).overlaidWith (currentColour)); + } + + void resized() override + { + colourLabel.centreWithSize (labelWidth + 10, (int) labelFont.getHeight() + 10); + } + +private: + void updateColourIfNecessary (const String& newColourString) + { + auto newColour = Colour::fromString (newColourString); + + if (newColour != currentColour) + owner.setCurrentColour (newColour); + } + + ColourSelector& owner; + + Colour currentColour; + Font labelFont { 14.0f, Font::bold }; + int labelWidth = 0; + Label colourLabel; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ColourPreviewComp) +}; + //============================================================================== ColourSelector::ColourSelector (int sectionsToShow, int edge, int gapAroundColourSpaceComponent) : colour (Colours::white), @@ -313,6 +392,12 @@ ColourSelector::ColourSelector (int sectionsToShow, int edge, int gapAroundColou updateHSV(); + if ((flags & showColourAtTop) != 0) + { + previewComponent.reset (new ColourPreviewComp (*this, (flags & editableColour) != 0)); + addAndMakeVisible (previewComponent.get()); + } + if ((flags & showSliders) != 0) { sliders[0].reset (new ColourComponentSlider (TRANS ("red"))); @@ -418,8 +503,8 @@ void ColourSelector::update (NotificationType notification) hueSelector->updateIfNeeded(); } - if ((flags & showColourAtTop) != 0) - repaint (previewArea); + if (previewComponent != nullptr) + previewComponent->updateIfNeeded(); if (notification != dontSendNotification) sendChangeMessage(); @@ -433,20 +518,6 @@ void ColourSelector::paint (Graphics& g) { g.fillAll (findColour (backgroundColourId)); - if ((flags & showColourAtTop) != 0) - { - auto currentColour = getCurrentColour(); - - g.fillCheckerBoard (previewArea.toFloat(), 10.0f, 10.0f, - Colour (0xffdddddd).overlaidWith (currentColour), - Colour (0xffffffff).overlaidWith (currentColour)); - - g.setColour (Colours::white.overlaidWith (currentColour).contrasting()); - g.setFont (Font (14.0f, Font::bold)); - g.drawText (currentColour.toDisplayString ((flags & showAlphaChannel) != 0), - previewArea, Justification::centred, false); - } - if ((flags & showSliders) != 0) { g.setColour (findColour (labelTextColourId)); @@ -475,7 +546,8 @@ void ColourSelector::resized() const int sliderSpace = ((flags & showSliders) != 0) ? jmin (22 * numSliders + edgeGap, proportionOfHeight (0.3f)) : 0; const int topSpace = ((flags & showColourAtTop) != 0) ? jmin (30 + edgeGap * 2, proportionOfHeight (0.2f)) : edgeGap; - previewArea.setBounds (edgeGap, edgeGap, getWidth() - edgeGap * 2, topSpace - edgeGap * 2); + if (previewComponent != nullptr) + previewComponent->setBounds (edgeGap, edgeGap, getWidth() - edgeGap * 2, topSpace - edgeGap * 2); int y = topSpace; diff --git a/modules/juce_gui_extra/misc/juce_ColourSelector.h b/modules/juce_gui_extra/misc/juce_ColourSelector.h index fb233ec32a..a7c62fe05b 100644 --- a/modules/juce_gui_extra/misc/juce_ColourSelector.h +++ b/modules/juce_gui_extra/misc/juce_ColourSelector.h @@ -49,8 +49,9 @@ public: showAlphaChannel = 1 << 0, /**< if set, the colour's alpha channel can be changed as well as its RGB. */ showColourAtTop = 1 << 1, /**< if set, a swatch of the colour is shown at the top of the component. */ - showSliders = 1 << 2, /**< if set, RGB sliders are shown at the bottom of the component. */ - showColourspace = 1 << 3 /**< if set, a big HSV selector is shown. */ + editableColour = 1 << 2, /**< if set, the colour shows at the top of the component is editable. */ + showSliders = 1 << 3, /**< if set, RGB sliders are shown at the bottom of the component. */ + showColourspace = 1 << 4 /**< if set, a big HSV selector is shown. */ }; //============================================================================== @@ -137,6 +138,7 @@ public: // These need to be public otherwise the Projucer's live-build engine will complain class ColourSpaceView; class HueSelectorComp; + class ColourPreviewComp; private: //============================================================================== @@ -147,10 +149,10 @@ private: std::unique_ptr sliders[4]; std::unique_ptr colourSpace; std::unique_ptr hueSelector; + std::unique_ptr previewComponent; OwnedArray swatchComponents; const int flags; int edgeGap; - Rectangle previewArea; void setHue (float newH); void setSV (float newS, float newV);