summaryrefslogtreecommitdiff
path: root/src/gui/widgets/tabbedarea.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/widgets/tabbedarea.cpp')
-rw-r--r--src/gui/widgets/tabbedarea.cpp147
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);
+ }
}