void TabbedButtonBar::removeTab (const int tabIndex)
{
    if (((unsigned int) tabIndex) < (unsigned int) tabs.size())
    {
        const int oldTabIndex = currentTabIndex;
        if (currentTabIndex == tabIndex)
            currentTabIndex = -1;

        tabs.remove (tabIndex);
        tabColours.remove (tabIndex);

        delete getTabButton (tabIndex);

        for (int i = tabIndex + 1; i <= tabs.size(); ++i)
        {
            TabBarButton* const tb = getTabButton (i);

            if (tb != 0)
                tb->tabIndex--;
        }

        resized();

        setCurrentTabIndex (jlimit (0, jmax (0, tabs.size() - 1), oldTabIndex));
    }
}
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 (((unsigned int) insertIndex) > (unsigned int) tabs.size())
            insertIndex = tabs.size();

        for (int i = tabs.size(); --i >= insertIndex;)
        {
            TabBarButton* const tb = getTabButton (i);

            if (tb != 0)
                tb->tabIndex++;
        }

        tabs.insert (insertIndex, tabName);
        tabColours.insert (insertIndex, tabBackgroundColour);

        TabBarButton* const tb = createTabButton (tabName, insertIndex);
        jassert (tb != 0); // your createTabButton() mustn't return zero!

        addAndMakeVisible (tb, insertIndex);

        resized();

        if (currentTabIndex < 0)
            setCurrentTabIndex (0);
    }
}
void TabbedButtonBar::setTabName (const int tabIndex,
                                  const String& newName)
{
    if (((unsigned int) tabIndex) < (unsigned int) tabs.size()
         && tabs[tabIndex] != newName)
    {
        tabs.set (tabIndex, newName);

        TabBarButton* const tb = getTabButton (tabIndex);

        if (tb != 0)
            tb->setButtonText (newName);

        resized();
    }
}
void TabbedButtonBar::buttonClicked (Button* button)
{
    if (extraTabsButton == button)
    {
        PopupMenu m;

        for (int i = 0; i < tabs.size(); ++i)
        {
            TabBarButton* const tb = getTabButton (i);

            if (tb != 0 && ! tb->isVisible())
                m.addItem (tb->tabIndex + 1, tabs[i], true, i == currentTabIndex);
        }

        const int res = m.showAt (extraTabsButton);

        if (res != 0)
            setCurrentTabIndex (res - 1);
    }
}
Exemplo n.º 5
0
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);
    }
}
//==============================================================================
void TabbedButtonBar::updateTabPositions (bool animate)
{
    LookAndFeel& lf = getLookAndFeel();

    int depth = getWidth();
    int length = getHeight();

    if (! isVertical())
        std::swap (depth, length);

    const int overlap = lf.getTabButtonOverlap (depth) + lf.getTabButtonSpaceAroundImage() * 2;

    int totalLength = jmax (0, overlap);
    int numVisibleButtons = tabs.size();

    for (int i = 0; i < tabs.size(); ++i)
    {
        TabBarButton* const tb = tabs.getUnchecked(i)->button;

        totalLength += tb->getBestTabLength (depth) - overlap;
        tb->overlapPixels = jmax (0, overlap / 2);
    }

    double scale = 1.0;

    if (totalLength > length)
        scale = jmax (minimumScale, length / (double) totalLength);

    const bool isTooBig = (int) (totalLength * scale) > length;
    int tabsButtonPos = 0;

    if (isTooBig)
    {
        if (extraTabsButton == nullptr)
        {
            addAndMakeVisible (extraTabsButton = lf.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 (isVertical())
        {
            tabsButtonPos = getHeight() - buttonSize / 2 - 1;
            extraTabsButton->setCentrePosition (getWidth() / 2, tabsButtonPos);
        }
        else
        {
            tabsButtonPos = getWidth() - buttonSize / 2 - 1;
            extraTabsButton->setCentrePosition (tabsButtonPos, getHeight() / 2);
        }

        totalLength = 0;

        for (int i = 0; i < tabs.size(); ++i)
        {
            TabBarButton* const tb = tabs.getUnchecked(i)->button;
            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;
    ComponentAnimator& animator = Desktop::getInstance().getAnimator();

    for (int i = 0; i < tabs.size(); ++i)
    {
        if (TabBarButton* const tb = getTabButton (i))
        {
            const int bestLength = roundToInt (scale * tb->getBestTabLength (depth));

            if (i < numVisibleButtons)
            {
                const Rectangle<int> newBounds (isVertical() ? Rectangle<int> (0, pos, getWidth(), bestLength)
                                                             : Rectangle<int> (pos, 0, bestLength, getHeight()));

                if (animate)
                {
                    animator.animateComponent (tb, newBounds, 1.0f, 200, false, 3.0, 0.0);
                }
                else
                {
                    animator.cancelAnimation (tb, false);
                    tb->setBounds (newBounds);
                }

                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);
    }
}