diff options
Diffstat (limited to 'src/gui/widgets/tabbedarea.cpp')
-rw-r--r-- | src/gui/widgets/tabbedarea.cpp | 147 |
1 files changed, 146 insertions, 1 deletions
diff --git a/src/gui/widgets/tabbedarea.cpp b/src/gui/widgets/tabbedarea.cpp index 101c9546..412d3ddc 100644 --- a/src/gui/widgets/tabbedarea.cpp +++ b/src/gui/widgets/tabbedarea.cpp @@ -25,11 +25,20 @@ #include <guichan/widgets/container.hpp> -TabbedArea::TabbedArea() : gcn::TabbedArea() +TabbedArea::TabbedArea() : gcn::TabbedArea(), + mTabsWidth(0), + mVisibleTabsWidth(0), + mTabScrollIndex(0) { mWidgetContainer->setOpaque(false); addWidgetListener(this); + mArrowButton[0] = new Button("<", "shift_left", this); + mArrowButton[1] = new Button(">", "shift_right", this); + + add(mArrowButton[0]); + add(mArrowButton[1]); + widgetResized(NULL); } @@ -90,6 +99,9 @@ void TabbedArea::addTab(gcn::Tab* tab, gcn::Widget* widget) int width = getWidth() - 2 * getFrameSize(); int height = getHeight() - 2 * getFrameSize() - mTabContainer->getHeight(); widget->setSize(width, height); + + updateTabsWidth(); + updateArrowEnableState(); } void TabbedArea::addTab(const std::string &caption, gcn::Widget *widget) @@ -134,6 +146,7 @@ void TabbedArea::removeTab(Tab *tab) } adjustSize(); + updateTabsWidth(); adjustTabPositions(); } @@ -184,4 +197,136 @@ void TabbedArea::widgetResized(const gcn::Event &event) gcn::Widget *w = getCurrentWidget(); if (w) w->setSize(width, height); + + // Check whether there is room to show more tabs now. + int innerWidth = getWidth() - 4 - mArrowButton[0]->getWidth() + - mArrowButton[1]->getWidth(); + int newWidth = mVisibleTabsWidth; + while (mTabScrollIndex && newWidth < innerWidth) + { + newWidth += mTabs[mTabScrollIndex - 1].first->getWidth(); + if (newWidth < innerWidth) + --mTabScrollIndex; + } + + // Move the right arrow to fit the windows content. + mArrowButton[1]->setPosition(width - mArrowButton[1]->getWidth(), 0); + + updateArrowEnableState(); + adjustTabPositions(); +} + +void TabbedArea::updateTabsWidth() +{ + mTabsWidth = 0; + for (TabContainer::const_iterator itr = mTabs.begin(), itr_end = mTabs.end(); + itr != itr_end; ++itr) + { + mTabsWidth += (*itr).first->getWidth(); + } + updateVisibleTabsWidth(); +} + +void TabbedArea::updateVisibleTabsWidth() +{ + mVisibleTabsWidth = 0; + for (unsigned int i = mTabScrollIndex; i < mTabs.size(); ++i) + { + mVisibleTabsWidth += mTabs[i].first->getWidth(); + } +} + +void TabbedArea::adjustTabPositions() +{ + int maxTabHeight = 0; + for (unsigned i = 0; i < mTabs.size(); ++i) + { + if (mTabs[i].first->getHeight() > maxTabHeight) + { + maxTabHeight = mTabs[i].first->getHeight(); + } + } + + int x = mArrowButton[0]->isVisible() ? mArrowButton[0]->getWidth() : 0; + for (unsigned i = mTabScrollIndex; i < mTabs.size(); ++i) + { + gcn::Tab* tab = mTabs[i].first; + tab->setPosition(x, maxTabHeight - tab->getHeight()); + x += tab->getWidth(); + } + + // If the tabs are scrolled, we hide them away. + if (mTabScrollIndex > 0) + { + x = 0; + for (unsigned i = 0; i < mTabScrollIndex; ++i) + { + gcn::Tab* tab = mTabs[i].first; + x -= tab->getWidth(); + tab->setPosition(x, maxTabHeight - tab->getHeight()); + } + } +} + +void TabbedArea::action(const gcn::ActionEvent& actionEvent) +{ + Widget* source = actionEvent.getSource(); + Tab* tab = dynamic_cast<Tab*>(source); + + if (tab) + { + setSelectedTab(tab); + } + else + { + if (actionEvent.getId() == "shift_left") + { + if (mTabScrollIndex) + --mTabScrollIndex; + } + else if (actionEvent.getId() == "shift_right") + { + if (mTabScrollIndex < mTabs.size() - 1) + ++mTabScrollIndex; + } + adjustTabPositions(); + + updateArrowEnableState(); + } +} + +void TabbedArea::updateArrowEnableState() +{ + updateTabsWidth(); + if (mTabsWidth > getWidth() - 4 + - mArrowButton[0]->getWidth() + - mArrowButton[1]->getWidth()) + { + mArrowButton[0]->setVisible(true); + mArrowButton[1]->setVisible(true); + } + else + { + mArrowButton[0]->setVisible(false); + mArrowButton[1]->setVisible(false); + mTabScrollIndex = 0; + } + + // Left arrow consistency check + if (!mTabScrollIndex) + mArrowButton[0]->setEnabled(false); + else + mArrowButton[0]->setEnabled(true); + + // Right arrow consistency check + if (mVisibleTabsWidth < getWidth() - 4 + - mArrowButton[0]->getWidth() + - mArrowButton[1]->getWidth()) + { + mArrowButton[1]->setEnabled(false); + } + else + { + mArrowButton[1]->setEnabled(true); + } } |