From 9fc29dad53af284aaa2ffd897df41becefcf80fc Mon Sep 17 00:00:00 2001 From: jules Date: Thu, 12 Jul 2012 18:33:43 +0100 Subject: [PATCH] More tabbed component work. --- .../layout/juce_TabbedButtonBar.cpp | 49 +++++-------------- .../layout/juce_TabbedButtonBar.h | 6 +++ .../lookandfeel/juce_LookAndFeel.cpp | 44 ++++++++++++++++- .../lookandfeel/juce_LookAndFeel.h | 1 + 4 files changed, 62 insertions(+), 38 deletions(-) diff --git a/modules/juce_gui_basics/layout/juce_TabbedButtonBar.cpp b/modules/juce_gui_basics/layout/juce_TabbedButtonBar.cpp index db96707407..1f945c2c42 100644 --- a/modules/juce_gui_basics/layout/juce_TabbedButtonBar.cpp +++ b/modules/juce_gui_basics/layout/juce_TabbedButtonBar.cpp @@ -74,50 +74,27 @@ bool TabBarButton::hitTest (int mx, int my) int TabBarButton::getBestTabLength (const int depth) { - int textWidth = getLookAndFeel().getTabButtonBestWidth (*this, depth); - int extraCompSize = extraComponent != nullptr ? (owner.isVertical() ? extraComponent->getHeight() - : extraComponent->getWidth()) : 0; - - return jlimit (depth * 2, depth * 8, textWidth + extraCompSize); + return getLookAndFeel().getTabButtonBestWidth (*this, depth); } void TabBarButton::calcAreas (Rectangle& extraComp, Rectangle& text) const { + LookAndFeel& lf = getLookAndFeel(); text = getActiveArea(); const int depth = owner.isVertical() ? text.getWidth() : text.getHeight(); - const int indent = getLookAndFeel().getTabButtonOverlap (depth); - - if (owner.isVertical()) - text.reduce (0, indent); - else - text.reduce (indent, 0); + const int overlap = lf.getTabButtonOverlap (depth); - if (extraComponent != nullptr) + if (overlap > 0) { - if (extraCompPlacement == beforeText) - { - switch (owner.getOrientation()) - { - case TabbedButtonBar::TabsAtLeft: extraComp = text.removeFromBottom (extraComponent->getHeight()); break; - case TabbedButtonBar::TabsAtRight: extraComp = text.removeFromTop (extraComponent->getHeight()); break; - case TabbedButtonBar::TabsAtBottom: - case TabbedButtonBar::TabsAtTop: extraComp = text.removeFromLeft (extraComponent->getWidth()); break; - default: jassertfalse; break; - } - } + if (owner.isVertical()) + text.reduce (0, overlap); else - { - switch (owner.getOrientation()) - { - case TabbedButtonBar::TabsAtLeft: extraComp = text.removeFromTop (extraComponent->getHeight()); break; - case TabbedButtonBar::TabsAtRight: extraComp = text.removeFromBottom (extraComponent->getHeight()); break; - case TabbedButtonBar::TabsAtBottom: - case TabbedButtonBar::TabsAtTop: extraComp = text.removeFromRight (extraComponent->getWidth()); break; - default: jassertfalse; break; - } - } + text.reduce (overlap, 0); } + + if (extraComponent != nullptr) + extraComp = lf.getTabButtonExtraComponentBounds (*this, text, *extraComponent); } Rectangle TabBarButton::getTextArea() const @@ -389,7 +366,7 @@ void TabbedButtonBar::resized() const int overlap = lf.getTabButtonOverlap (depth) + lf.getTabButtonSpaceAroundImage() * 2; - int totalLength = overlap; + int totalLength = jmax (0, overlap); int numVisibleButtons = tabs.size(); for (int i = 0; i < tabs.size(); ++i) @@ -397,7 +374,7 @@ void TabbedButtonBar::resized() TabBarButton* const tb = tabs.getUnchecked(i)->button; totalLength += tb->getBestTabLength (depth) - overlap; - tb->overlapPixels = overlap / 2; + tb->overlapPixels = jmax (0, overlap / 2); } double scale = 1.0; @@ -405,7 +382,7 @@ void TabbedButtonBar::resized() if (totalLength > length) scale = jmax (minimumScale, length / (double) totalLength); - const bool isTooBig = totalLength * scale > length; + const bool isTooBig = (int) (totalLength * scale) > length; int tabsButtonPos = 0; if (isTooBig) diff --git a/modules/juce_gui_basics/layout/juce_TabbedButtonBar.h b/modules/juce_gui_basics/layout/juce_TabbedButtonBar.h index 7d9ad9af7b..a45d00536c 100644 --- a/modules/juce_gui_basics/layout/juce_TabbedButtonBar.h +++ b/modules/juce_gui_basics/layout/juce_TabbedButtonBar.h @@ -71,6 +71,12 @@ public: void setExtraComponent (Component* extraTabComponent, ExtraComponentPlacement extraComponentPlacement); + /** Returns the custom component, if there is one. */ + Component* getExtraComponent() const noexcept { return extraComponent; } + + /** Returns the placement of the custom component, if there is one. */ + ExtraComponentPlacement getExtraComponentPlacement() const noexcept { return extraCompPlacement; } + /** Returns an area of the component that's safe to draw in. This deals with the orientation of the tabs, which affects which side is diff --git a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp index 3267b96908..fdeee99f39 100644 --- a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp +++ b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp @@ -2076,8 +2076,48 @@ int LookAndFeel::getTabButtonSpaceAroundImage() int LookAndFeel::getTabButtonBestWidth (TabBarButton& button, int tabDepth) { - return Font (tabDepth * 0.6f).getStringWidth (button.getButtonText().trim()) - + getTabButtonOverlap (tabDepth) * 2; + int width = Font (tabDepth * 0.6f).getStringWidth (button.getButtonText().trim()) + + getTabButtonOverlap (tabDepth) * 2; + + Component* const extraComponent = button.getExtraComponent(); + + if (extraComponent != nullptr) + width += button.getTabbedButtonBar().isVertical() ? extraComponent->getHeight() + : extraComponent->getWidth(); + + return jlimit (tabDepth * 2, tabDepth * 8, width); +} + +Rectangle LookAndFeel::getTabButtonExtraComponentBounds (const TabBarButton& button, Rectangle& textArea, Component& comp) +{ + Rectangle extraComp; + + const TabbedButtonBar::Orientation orientation = button.getTabbedButtonBar().getOrientation(); + + if (button.getExtraComponentPlacement() == TabBarButton::beforeText) + { + switch (orientation) + { + case TabbedButtonBar::TabsAtBottom: + case TabbedButtonBar::TabsAtTop: extraComp = textArea.removeFromLeft (comp.getWidth()); break; + case TabbedButtonBar::TabsAtLeft: extraComp = textArea.removeFromBottom (comp.getHeight()); break; + case TabbedButtonBar::TabsAtRight: extraComp = textArea.removeFromTop (comp.getHeight()); break; + default: jassertfalse; break; + } + } + else + { + switch (orientation) + { + case TabbedButtonBar::TabsAtBottom: + case TabbedButtonBar::TabsAtTop: extraComp = textArea.removeFromRight (comp.getWidth()); break; + case TabbedButtonBar::TabsAtLeft: extraComp = textArea.removeFromTop (comp.getHeight()); break; + case TabbedButtonBar::TabsAtRight: extraComp = textArea.removeFromBottom (comp.getHeight()); break; + default: jassertfalse; break; + } + } + + return extraComp; } void LookAndFeel::createTabButtonShape (TabBarButton& button, Path& p, bool /*isMouseOver*/, bool /*isMouseDown*/) diff --git a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.h b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.h index caea1b086a..8dd1cac0a1 100644 --- a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.h +++ b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.h @@ -516,6 +516,7 @@ public: virtual int getTabButtonSpaceAroundImage(); virtual int getTabButtonOverlap (int tabDepth); virtual int getTabButtonBestWidth (TabBarButton&, int tabDepth); + virtual Rectangle getTabButtonExtraComponentBounds (const TabBarButton&, Rectangle& textArea, Component& extraComp); virtual void drawTabButton (TabBarButton&, Graphics& g, bool isMouseOver, bool isMouseDown); virtual void drawTabButtonText (TabBarButton&, Graphics& g, bool isMouseOver, bool isMouseDown);