123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- /*
- ==============================================================================
- This file is part of the JUCE library.
- Copyright (c) 2017 - ROLI Ltd.
- JUCE is an open source library subject to commercial or open-source
- licensing.
- By using JUCE, you agree to the terms of both the JUCE 5 End-User License
- Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
- 27th April 2017).
- End User License Agreement: www.juce.com/juce-5-licence
- Privacy Policy: www.juce.com/juce-5-privacy-policy
- Or: You may also use this code under the terms of the GPL v3 (see
- www.gnu.org/licenses).
- JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
- EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
- DISCLAIMED.
- ==============================================================================
- */
- namespace juce
- {
- SidePanel::SidePanel (StringRef title, int width, bool positionOnLeft,
- Component* contentToDisplay, bool deleteComponentWhenNoLongerNeeded)
- : titleLabel ("titleLabel", title),
- isOnLeft (positionOnLeft),
- panelWidth (width)
- {
- lookAndFeelChanged();
- addAndMakeVisible (titleLabel);
- dismissButton.onClick = [this] { showOrHide (false); };
- addAndMakeVisible (dismissButton);
- Desktop::getInstance().addGlobalMouseListener (this);
- if (contentToDisplay != nullptr)
- setContent (contentToDisplay, deleteComponentWhenNoLongerNeeded);
- setOpaque (false);
- }
- SidePanel::~SidePanel()
- {
- Desktop::getInstance().removeGlobalMouseListener (this);
- if (parent != nullptr)
- parent->removeComponentListener (this);
- }
- void SidePanel::setContent (Component* newContent, bool deleteComponentWhenNoLongerNeeded)
- {
- if (contentComponent.get() != newContent)
- {
- if (deleteComponentWhenNoLongerNeeded)
- contentComponent.setOwned (newContent);
- else
- contentComponent.setNonOwned (newContent);
- addAndMakeVisible (contentComponent);
- resized();
- }
- }
- void SidePanel::setTitleBarComponent (Component* titleBarComponentToUse,
- bool keepDismissButton,
- bool deleteComponentWhenNoLongerNeeded)
- {
- if (titleBarComponent.get() != titleBarComponentToUse)
- {
- if (deleteComponentWhenNoLongerNeeded)
- titleBarComponent.setOwned (titleBarComponentToUse);
- else
- titleBarComponent.setNonOwned (titleBarComponentToUse);
- addAndMakeVisible (titleBarComponent);
- resized();
- }
- shouldShowDismissButton = keepDismissButton;
- }
- void SidePanel::showOrHide (bool show)
- {
- if (parent != nullptr)
- {
- isShowing = show;
- Desktop::getInstance().getAnimator().animateComponent (this, calculateBoundsInParent (*parent),
- 1.0f, 250, true, 1.0, 0.0);
- if (onPanelShowHide != nullptr)
- onPanelShowHide (isShowing);
- }
- }
- void SidePanel::moved()
- {
- if (onPanelMove != nullptr)
- onPanelMove();
- }
- void SidePanel::resized()
- {
- auto bounds = getLocalBounds();
- calculateAndRemoveShadowBounds (bounds);
- auto titleBounds = bounds.removeFromTop (titleBarHeight);
- if (titleBarComponent != nullptr)
- {
- if (shouldShowDismissButton)
- dismissButton.setBounds (isOnLeft ? titleBounds.removeFromRight (30).withTrimmedRight (10)
- : titleBounds.removeFromLeft (30).withTrimmedLeft (10));
- titleBarComponent->setBounds (titleBounds);
- }
- else
- {
- dismissButton.setBounds (isOnLeft ? titleBounds.removeFromRight (30).withTrimmedRight (10)
- : titleBounds.removeFromLeft (30).withTrimmedLeft (10));
- titleLabel.setBounds (isOnLeft ? titleBounds.withTrimmedRight (40)
- : titleBounds.withTrimmedLeft (40));
- }
- if (contentComponent != nullptr)
- contentComponent->setBounds (bounds);
- }
- void SidePanel::paint (Graphics& g)
- {
- auto& lf = getLookAndFeel();
- auto bgColour = lf.findColour (SidePanel::backgroundColour);
- auto shadowColour = lf.findColour (SidePanel::shadowBaseColour);
- g.setGradientFill (ColourGradient (shadowColour.withAlpha (0.7f), (isOnLeft ? shadowArea.getTopLeft()
- : shadowArea.getTopRight()).toFloat(),
- shadowColour.withAlpha (0.0f), (isOnLeft ? shadowArea.getTopRight()
- : shadowArea.getTopLeft()).toFloat(), false));
- g.fillRect (shadowArea);
- g.excludeClipRegion (shadowArea);
- g.fillAll (bgColour);
- }
- void SidePanel::parentHierarchyChanged()
- {
- auto* newParent = getParentComponent();
- if ((newParent != nullptr) && (parent != newParent))
- {
- if (parent != nullptr)
- parent->removeComponentListener (this);
- parent = newParent;
- parent->addComponentListener (this);
- }
- }
- void SidePanel::mouseDrag (const MouseEvent& e)
- {
- if (shouldResize)
- {
- Point<int> convertedPoint;
- if (getParentComponent() == nullptr)
- convertedPoint = e.eventComponent->localPointToGlobal (e.getPosition());
- else
- convertedPoint = getParentComponent()->getLocalPoint (e.eventComponent, e.getPosition());
- auto currentMouseDragX = convertedPoint.x;
- if (isOnLeft)
- {
- amountMoved = startingBounds.getRight() - currentMouseDragX;
- setBounds (getBounds().withX (startingBounds.getX() - jmax (amountMoved, 0)));
- }
- else
- {
- amountMoved = currentMouseDragX - startingBounds.getX();
- setBounds (getBounds().withX (startingBounds.getX() + jmax (amountMoved, 0)));
- }
- }
- else if (isShowing)
- {
- auto relativeMouseDownPosition = getLocalPoint (e.eventComponent, e.getMouseDownPosition());
- auto relativeMouseDragPosition = getLocalPoint (e.eventComponent, e.getPosition());
- if (! getLocalBounds().contains (relativeMouseDownPosition)
- && getLocalBounds().contains (relativeMouseDragPosition))
- {
- shouldResize = true;
- startingBounds = getBounds();
- }
- }
- }
- void SidePanel::mouseUp (const MouseEvent&)
- {
- if (shouldResize)
- {
- showOrHide (amountMoved < (panelWidth / 2));
- amountMoved = 0;
- shouldResize = false;
- }
- }
- //==============================================================================
- void SidePanel::lookAndFeelChanged()
- {
- auto& lf = getLookAndFeel();
- dismissButton.setShape (lf.getSidePanelDismissButtonShape (*this), false, true, false);
- dismissButton.setColours (lf.findColour (SidePanel::dismissButtonNormalColour),
- lf.findColour (SidePanel::dismissButtonOverColour),
- lf.findColour (SidePanel::dismissButtonDownColour));
- titleLabel.setFont (lf.getSidePanelTitleFont (*this));
- titleLabel.setColour (Label::textColourId, findColour (SidePanel::titleTextColour));
- titleLabel.setJustificationType (lf.getSidePanelTitleJustification (*this));
- }
- void SidePanel::componentMovedOrResized (Component& component, bool wasMoved, bool wasResized)
- {
- ignoreUnused (wasMoved);
- if (wasResized && (&component == parent))
- setBounds (calculateBoundsInParent (component));
- }
- Rectangle<int> SidePanel::calculateBoundsInParent (Component& parentComp) const
- {
- auto parentBounds = parentComp.getLocalBounds();
- if (isOnLeft)
- {
- return isShowing ? parentBounds.removeFromLeft (panelWidth)
- : parentBounds.withX (parentBounds.getX() - panelWidth).withWidth (panelWidth);
- }
- return isShowing ? parentBounds.removeFromRight (panelWidth)
- : parentBounds.withX (parentBounds.getRight()).withWidth (panelWidth);
- }
- void SidePanel::calculateAndRemoveShadowBounds (Rectangle<int>& bounds)
- {
- shadowArea = isOnLeft ? bounds.removeFromRight (shadowWidth)
- : bounds.removeFromLeft (shadowWidth);
- }
- bool SidePanel::isMouseEventInThisOrChildren (Component* eventComponent)
- {
- if (eventComponent == this)
- return true;
- for (auto& child : getChildren())
- if (eventComponent == child)
- return true;
- return false;
- }
- } // namespace juce
|