| 
							- /*
 -   ==============================================================================
 - 
 -    This file is part of the JUCE library - "Jules' Utility Class Extensions"
 -    Copyright 2004-11 by Raw Material Software Ltd.
 - 
 -   ------------------------------------------------------------------------------
 - 
 -    JUCE can be redistributed and/or modified under the terms of the GNU General
 -    Public License (Version 2), as published by the Free Software Foundation.
 -    A copy of the license is included in the JUCE distribution, or can be found
 -    online at www.gnu.org/licenses.
 - 
 -    JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
 -    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 -    A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
 - 
 -   ------------------------------------------------------------------------------
 - 
 -    To release a closed-source product which uses JUCE, commercial licenses are
 -    available: visit www.rawmaterialsoftware.com/juce for more information.
 - 
 -   ==============================================================================
 - */
 - 
 - BEGIN_JUCE_NAMESPACE
 - 
 - //==============================================================================
 - TabBarButton::TabBarButton (const String& name, TabbedButtonBar& owner_)
 -     : Button (name),
 -       owner (owner_),
 -       overlapPixels (0)
 - {
 -     shadow.setShadowProperties (2.2f, 0.7f, 0, 0);
 -     setComponentEffect (&shadow);
 -     setWantsKeyboardFocus (false);
 - }
 - 
 - TabBarButton::~TabBarButton()
 - {
 - }
 - 
 - int TabBarButton::getIndex() const
 - {
 -     return owner.indexOfTabButton (this);
 - }
 - 
 - void TabBarButton::paintButton (Graphics& g,
 -                                 bool isMouseOverButton,
 -                                 bool isButtonDown)
 - {
 -     const Rectangle<int> area (getActiveArea());
 -     g.setOrigin (area.getX(), area.getY());
 - 
 -     getLookAndFeel()
 -         .drawTabButton (g, area.getWidth(), area.getHeight(),
 -                         owner.getTabBackgroundColour (getIndex()),
 -                         getIndex(), getButtonText(), *this,
 -                         owner.getOrientation(),
 -                         isMouseOverButton, isButtonDown,
 -                         getToggleState());
 - }
 - 
 - void TabBarButton::clicked (const ModifierKeys& mods)
 - {
 -     if (mods.isPopupMenu())
 -         owner.popupMenuClickOnTab (getIndex(), getButtonText());
 -     else
 -         owner.setCurrentTabIndex (getIndex());
 - }
 - 
 - bool TabBarButton::hitTest (int mx, int my)
 - {
 -     const Rectangle<int> area (getActiveArea());
 - 
 -     if (owner.getOrientation() == TabbedButtonBar::TabsAtLeft
 -          || owner.getOrientation() == TabbedButtonBar::TabsAtRight)
 -     {
 -         if (isPositiveAndBelow (mx, getWidth())
 -              && my >= area.getY() + overlapPixels
 -              && my < area.getBottom() - overlapPixels)
 -             return true;
 -     }
 -     else
 -     {
 -         if (mx >= area.getX() + overlapPixels && mx < area.getRight() - overlapPixels
 -              && isPositiveAndBelow (my, getHeight()))
 -             return true;
 -     }
 - 
 -     Path p;
 -     getLookAndFeel()
 -         .createTabButtonShape (p, area.getWidth(), area.getHeight(), getIndex(), getButtonText(), *this,
 -                                owner.getOrientation(), false, false, getToggleState());
 - 
 -     return p.contains ((float) (mx - area.getX()),
 -                        (float) (my - area.getY()));
 - }
 - 
 - int TabBarButton::getBestTabLength (const int depth)
 - {
 -     return jlimit (depth * 2,
 -                    depth * 7,
 -                    getLookAndFeel().getTabButtonBestWidth (getIndex(), getButtonText(), depth, *this));
 - }
 - 
 - const Rectangle<int> TabBarButton::getActiveArea()
 - {
 -     Rectangle<int> r (getLocalBounds());
 -     const int spaceAroundImage = getLookAndFeel().getTabButtonSpaceAroundImage();
 - 
 -     if (owner.getOrientation() != TabbedButtonBar::TabsAtLeft)      r.removeFromRight (spaceAroundImage);
 -     if (owner.getOrientation() != TabbedButtonBar::TabsAtRight)     r.removeFromLeft (spaceAroundImage);
 -     if (owner.getOrientation() != TabbedButtonBar::TabsAtBottom)    r.removeFromTop (spaceAroundImage);
 -     if (owner.getOrientation() != TabbedButtonBar::TabsAtTop)       r.removeFromBottom (spaceAroundImage);
 - 
 -     return r;
 - }
 - 
 - 
 - //==============================================================================
 - class TabbedButtonBar::BehindFrontTabComp  : public Component,
 -                                              public ButtonListener // (can't use Button::Listener due to idiotic VC2005 bug)
 - {
 - public:
 -     BehindFrontTabComp (TabbedButtonBar& owner_)
 -         : owner (owner_)
 -     {
 -         setInterceptsMouseClicks (false, false);
 -     }
 - 
 -     void paint (Graphics& g)
 -     {
 -         getLookAndFeel().drawTabAreaBehindFrontButton (g, getWidth(), getHeight(),
 -                                                        owner, owner.getOrientation());
 -     }
 - 
 -     void enablementChanged()
 -     {
 -         repaint();
 -     }
 - 
 -     void buttonClicked (Button*)
 -     {
 -         owner.showExtraItemsMenu();
 -     }
 - 
 - private:
 -     TabbedButtonBar& owner;
 - 
 -     JUCE_DECLARE_NON_COPYABLE (BehindFrontTabComp);
 - };
 - 
 - 
 - //==============================================================================
 - TabbedButtonBar::TabbedButtonBar (const Orientation orientation_)
 -     : orientation (orientation_),
 -       minimumScale (0.7),
 -       currentTabIndex (-1)
 - {
 -     setInterceptsMouseClicks (false, true);
 -     addAndMakeVisible (behindFrontTab = new BehindFrontTabComp (*this));
 -     setFocusContainer (true);
 - }
 - 
 - TabbedButtonBar::~TabbedButtonBar()
 - {
 -     tabs.clear();
 -     extraTabsButton = nullptr;
 - }
 - 
 - //==============================================================================
 - void TabbedButtonBar::setOrientation (const Orientation newOrientation)
 - {
 -     orientation = newOrientation;
 - 
 -     for (int i = getNumChildComponents(); --i >= 0;)
 -         getChildComponent (i)->resized();
 - 
 -     resized();
 - }
 - 
 - TabBarButton* TabbedButtonBar::createTabButton (const String& name, const int /*index*/)
 - {
 -     return new TabBarButton (name, *this);
 - }
 - 
 - void TabbedButtonBar::setMinimumTabScaleFactor (double newMinimumScale)
 - {
 -     minimumScale = newMinimumScale;
 -     resized();
 - }
 - 
 - //==============================================================================
 - void TabbedButtonBar::clearTabs()
 - {
 -     tabs.clear();
 -     extraTabsButton = nullptr;
 -     setCurrentTabIndex (-1);
 - }
 - 
 - void TabbedButtonBar::addTab (const String& tabName,
 -                               const Colour& tabBackgroundColour,
 -                               int insertIndex)
 - {
 -     jassert (tabName.isNotEmpty()); // you have to give them all a name..
 - 
 -     if (tabName.isNotEmpty())
 -     {
 -         if (! isPositiveAndBelow (insertIndex, tabs.size()))
 -             insertIndex = tabs.size();
 - 
 -         TabInfo* newTab = new TabInfo();
 -         newTab->name = tabName;
 -         newTab->colour = tabBackgroundColour;
 -         newTab->component = createTabButton (tabName, insertIndex);
 - 
 -         jassert (newTab->component != nullptr);
 - 
 -         tabs.insert (insertIndex, newTab);
 -         addAndMakeVisible (newTab->component, insertIndex);
 - 
 -         resized();
 - 
 -         if (currentTabIndex < 0)
 -             setCurrentTabIndex (0);
 -     }
 - }
 - 
 - void TabbedButtonBar::setTabName (const int tabIndex, const String& newName)
 - {
 -     TabInfo* const tab = tabs [tabIndex];
 - 
 -     if (tab != nullptr && tab->name != newName)
 -     {
 -         tab->name = newName;
 -         tab->component->setButtonText (newName);
 -         resized();
 -     }
 - }
 - 
 - void TabbedButtonBar::removeTab (const int tabIndex)
 - {
 -     if (tabs [tabIndex] != nullptr)
 -     {
 -         const int oldTabIndex = currentTabIndex;
 -         if (currentTabIndex == tabIndex)
 -             currentTabIndex = -1;
 - 
 -         tabs.remove (tabIndex);
 -         resized();
 - 
 -         setCurrentTabIndex (jlimit (0, jmax (0, tabs.size() - 1), oldTabIndex));
 -     }
 - }
 - 
 - void TabbedButtonBar::moveTab (const int currentIndex, const int newIndex)
 - {
 -     tabs.move (currentIndex, newIndex);
 -     resized();
 - }
 - 
 - int TabbedButtonBar::getNumTabs() const
 - {
 -     return tabs.size();
 - }
 - 
 - String TabbedButtonBar::getCurrentTabName() const
 - {
 -     TabInfo* tab = tabs [currentTabIndex];
 -     return tab == nullptr ? String::empty : tab->name;
 - }
 - 
 - StringArray TabbedButtonBar::getTabNames() const
 - {
 -     StringArray names;
 - 
 -     for (int i = 0; i < tabs.size(); ++i)
 -         names.add (tabs.getUnchecked(i)->name);
 - 
 -     return names;
 - }
 - 
 - void TabbedButtonBar::setCurrentTabIndex (int newIndex, const bool sendChangeMessage_)
 - {
 -     if (currentTabIndex != newIndex)
 -     {
 -         if (! isPositiveAndBelow (newIndex, tabs.size()))
 -             newIndex = -1;
 - 
 -         currentTabIndex = newIndex;
 - 
 -         for (int i = 0; i < tabs.size(); ++i)
 -         {
 -             TabBarButton* tb = tabs.getUnchecked(i)->component;
 -             tb->setToggleState (i == newIndex, false);
 -         }
 - 
 -         resized();
 - 
 -         if (sendChangeMessage_)
 -             sendChangeMessage();
 - 
 -         currentTabChanged (newIndex, getCurrentTabName());
 -     }
 - }
 - 
 - TabBarButton* TabbedButtonBar::getTabButton (const int index) const
 - {
 -     TabInfo* const tab = tabs[index];
 -     return tab == nullptr ? nullptr : static_cast <TabBarButton*> (tab->component);
 - }
 - 
 - int TabbedButtonBar::indexOfTabButton (const TabBarButton* button) const
 - {
 -     for (int i = tabs.size(); --i >= 0;)
 -         if (tabs.getUnchecked(i)->component == button)
 -             return i;
 - 
 -     return -1;
 - }
 - 
 - void TabbedButtonBar::lookAndFeelChanged()
 - {
 -     extraTabsButton = nullptr;
 -     resized();
 - }
 - 
 - void TabbedButtonBar::resized()
 - {
 -     int depth = getWidth();
 -     int length = getHeight();
 - 
 -     if (orientation == TabsAtTop || orientation == TabsAtBottom)
 -         std::swap (depth, length);
 - 
 -     const int overlap = getLookAndFeel().getTabButtonOverlap (depth)
 -                             + getLookAndFeel().getTabButtonSpaceAroundImage() * 2;
 - 
 -     int i, totalLength = overlap;
 -     int numVisibleButtons = tabs.size();
 - 
 -     for (i = 0; i < tabs.size(); ++i)
 -     {
 -         TabBarButton* const tb = tabs.getUnchecked(i)->component;
 - 
 -         totalLength += tb->getBestTabLength (depth) - overlap;
 -         tb->overlapPixels = overlap / 2;
 -     }
 - 
 -     double scale = 1.0;
 - 
 -     if (totalLength > length)
 -         scale = jmax (minimumScale, length / (double) totalLength);
 - 
 -     const bool isTooBig = totalLength * scale > length;
 -     int tabsButtonPos = 0;
 - 
 -     if (isTooBig)
 -     {
 -         if (extraTabsButton == nullptr)
 -         {
 -             addAndMakeVisible (extraTabsButton = getLookAndFeel().createTabBarExtrasButton());
 -             extraTabsButton->addListener (behindFrontTab);
 -             extraTabsButton->setAlwaysOnTop (true);
 -             extraTabsButton->setTriggeredOnMouseDown (true);
 -         }
 - 
 -         const int buttonSize = jmin (proportionOfWidth (0.7f), proportionOfHeight (0.7f));
 -         extraTabsButton->setSize (buttonSize, buttonSize);
 - 
 -         if (orientation == TabsAtTop || orientation == TabsAtBottom)
 -         {
 -             tabsButtonPos = getWidth() - buttonSize / 2 - 1;
 -             extraTabsButton->setCentrePosition (tabsButtonPos, getHeight() / 2);
 -         }
 -         else
 -         {
 -             tabsButtonPos = getHeight() - buttonSize / 2 - 1;
 -             extraTabsButton->setCentrePosition (getWidth() / 2, tabsButtonPos);
 -         }
 - 
 -         totalLength = 0;
 - 
 -         for (i = 0; i < tabs.size(); ++i)
 -         {
 -             TabBarButton* const tb = tabs.getUnchecked(i)->component;
 - 
 -             const int newLength = totalLength + tb->getBestTabLength (depth);
 - 
 -             if (i > 0 && newLength * minimumScale > tabsButtonPos)
 -             {
 -                 totalLength += overlap;
 -                 break;
 -             }
 - 
 -             numVisibleButtons = i + 1;
 -             totalLength = newLength - overlap;
 -         }
 - 
 -         scale = jmax (minimumScale, tabsButtonPos / (double) totalLength);
 -     }
 -     else
 -     {
 -         extraTabsButton = nullptr;
 -     }
 - 
 -     int pos = 0;
 - 
 -     TabBarButton* frontTab = nullptr;
 - 
 -     for (i = 0; i < tabs.size(); ++i)
 -     {
 -         TabBarButton* const tb = getTabButton (i);
 - 
 -         if (tb != nullptr)
 -         {
 -             const int bestLength = roundToInt (scale * tb->getBestTabLength (depth));
 - 
 -             if (i < numVisibleButtons)
 -             {
 -                 if (orientation == TabsAtTop || orientation == TabsAtBottom)
 -                     tb->setBounds (pos, 0, bestLength, getHeight());
 -                 else
 -                     tb->setBounds (0, pos, getWidth(), bestLength);
 - 
 -                 tb->toBack();
 - 
 -                 if (i == currentTabIndex)
 -                     frontTab = tb;
 - 
 -                 tb->setVisible (true);
 -             }
 -             else
 -             {
 -                 tb->setVisible (false);
 -             }
 - 
 -             pos += bestLength - overlap;
 -         }
 -     }
 - 
 -     behindFrontTab->setBounds (getLocalBounds());
 - 
 -     if (frontTab != nullptr)
 -     {
 -         frontTab->toFront (false);
 -         behindFrontTab->toBehind (frontTab);
 -     }
 - }
 - 
 - //==============================================================================
 - const Colour TabbedButtonBar::getTabBackgroundColour (const int tabIndex)
 - {
 -     TabInfo* const tab = tabs [tabIndex];
 -     return tab == nullptr ? Colours::white : tab->colour;
 - }
 - 
 - void TabbedButtonBar::setTabBackgroundColour (const int tabIndex, const Colour& newColour)
 - {
 -     TabInfo* const tab = tabs [tabIndex];
 - 
 -     if (tab != nullptr && tab->colour != newColour)
 -     {
 -         tab->colour = newColour;
 -         repaint();
 -     }
 - }
 - 
 - void TabbedButtonBar::extraItemsMenuCallback (int result, TabbedButtonBar* bar)
 - {
 -     if (bar != nullptr && result > 0)
 -         bar->setCurrentTabIndex (result - 1);
 - }
 - 
 - void TabbedButtonBar::showExtraItemsMenu()
 - {
 -     PopupMenu m;
 - 
 -     for (int i = 0; i < tabs.size(); ++i)
 -     {
 -         const TabInfo* const tab = tabs.getUnchecked(i);
 - 
 -         if (! tab->component->isVisible())
 -             m.addItem (i + 1, tab->name, true, i == currentTabIndex);
 -     }
 - 
 -     m.showMenuAsync (PopupMenu::Options().withTargetComponent (extraTabsButton),
 -                      ModalCallbackFunction::forComponent (extraItemsMenuCallback, this));
 - }
 - 
 - //==============================================================================
 - void TabbedButtonBar::currentTabChanged (const int, const String&)
 - {
 - }
 - 
 - void TabbedButtonBar::popupMenuClickOnTab (const int, const String&)
 - {
 - }
 - 
 - END_JUCE_NAMESPACE
 
 
  |