recalculateScrollBar();\r
}\r
\r
-s32 CGUITabControl::calcTabWidth(s32 pos, IGUIFont* font, const wchar_t* text, bool withScrollControl) const\r
+s32 CGUITabControl::calcTabWidth(IGUIFont* font, const wchar_t* text) const\r
{\r
if ( !font )\r
return 0;\r
if ( TabMaxWidth > 0 && len > TabMaxWidth )\r
len = TabMaxWidth;\r
\r
- // check if we miss the place to draw the tab-button\r
- if ( withScrollControl && ScrollControl && pos+len > UpButton->getAbsolutePosition().UpperLeftCorner.X - 2 )\r
- {\r
- s32 tabMinWidth = font->getDimension(L"A").Width;\r
- if ( TabExtraWidth > 0 && TabExtraWidth > tabMinWidth )\r
- tabMinWidth = TabExtraWidth;\r
-\r
- if ( ScrollControl && pos+tabMinWidth <= UpButton->getAbsolutePosition().UpperLeftCorner.X - 2 )\r
- {\r
- len = UpButton->getAbsolutePosition().UpperLeftCorner.X - 2 - pos;\r
- }\r
- }\r
return len;\r
}\r
\r
-bool CGUITabControl::needScrollControl(s32 startIndex, bool withScrollControl)\r
+bool CGUITabControl::needScrollControl(s32 startIndex, bool withScrollControl, s32 *pos_rightmost)\r
{\r
- if ( startIndex >= (s32)Tabs.size() )\r
- startIndex -= 1;\r
-\r
if ( startIndex < 0 )\r
startIndex = 0;\r
\r
\r
IGUIFont* font = skin->getFont();\r
\r
- core::rect<s32> frameRect(AbsoluteRect);\r
-\r
if (Tabs.empty())\r
return false;\r
\r
if (!font)\r
return false;\r
\r
- s32 pos = frameRect.UpperLeftCorner.X + 2;\r
+ s32 pos = AbsoluteRect.UpperLeftCorner.X + 2;\r
+ const s32 pos_right = withScrollControl ?\r
+ UpButton->getAbsolutePosition().UpperLeftCorner.X - 2 :\r
+ AbsoluteRect.LowerRightCorner.X;\r
\r
- for (s32 i=startIndex; i<(s32)Tabs.size(); ++i)\r
+ for (s32 i = startIndex; i < (s32)Tabs.size(); ++i)\r
{\r
// get Text\r
const wchar_t* text = 0;\r
text = Tabs[i]->getText();\r
\r
// get text length\r
- s32 len = calcTabWidth(pos, font, text, false); // always without withScrollControl here or len would be shortened\r
-\r
- frameRect.LowerRightCorner.X += len;\r
-\r
- frameRect.UpperLeftCorner.X = pos;\r
- frameRect.LowerRightCorner.X = frameRect.UpperLeftCorner.X + len;\r
+ s32 len = calcTabWidth(font, text); // always without withScrollControl here or len would be shortened\r
pos += len;\r
}\r
\r
- if ( withScrollControl && pos > UpButton->getAbsolutePosition().UpperLeftCorner.X - 2)\r
- return true;\r
-\r
- if ( !withScrollControl && pos > AbsoluteRect.LowerRightCorner.X )\r
+ if (pos > pos_right)\r
return true;\r
}\r
\r
+ if (pos_rightmost)\r
+ *pos_rightmost = pos;\r
return false;\r
}\r
\r
\r
+s32 CGUITabControl::calculateScrollIndexFromActive()\r
+{\r
+ if (!ScrollControl || Tabs.empty())\r
+ return 0;\r
+\r
+ IGUISkin *skin = Environment->getSkin();\r
+ if (!skin)\r
+ return false;\r
+\r
+ IGUIFont *font = skin->getFont();\r
+ if (!font)\r
+ return false;\r
+\r
+ const s32 pos_left = AbsoluteRect.UpperLeftCorner.X + 2;\r
+ const s32 pos_right = UpButton->getAbsolutePosition().UpperLeftCorner.X - 2;\r
+\r
+ // Move from center to the left border left until it is reached\r
+ s32 pos_cl = (pos_left + pos_right) / 2;\r
+ s32 i = ActiveTabIndex;\r
+ for (; i > 0; --i) {\r
+ if (!Tabs[i])\r
+ continue;\r
+\r
+ s32 len = calcTabWidth(font, Tabs[i]->getText());\r
+ if (i == ActiveTabIndex)\r
+ len /= 2;\r
+ if (pos_cl - len < pos_left)\r
+ break;\r
+\r
+ pos_cl -= len;\r
+ }\r
+ if (i == 0)\r
+ return i;\r
+\r
+ // Is scrolling to right still possible?\r
+ s32 pos_rr = 0;\r
+ if (needScrollControl(i, true, &pos_rr))\r
+ return i; // Yes? -> OK\r
+\r
+ // No? -> Decrease "i" more. Append tabs until scrolling becomes necessary\r
+ for (--i; i > 0; --i) {\r
+ if (!Tabs[i])\r
+ continue;\r
+\r
+ pos_rr += calcTabWidth(font, Tabs[i]->getText());\r
+ if (pos_rr > pos_right)\r
+ break;\r
+ }\r
+ return i + 1;\r
+}\r
+\r
core::rect<s32> CGUITabControl::calcTabPos()\r
{\r
core::rect<s32> r;\r
IGUITab *activeTab = 0;\r
\r
// Draw all tab-buttons except the active one\r
- for (u32 i=CurrentScrollTabIndex; i<Tabs.size(); ++i)\r
+ for (u32 i = CurrentScrollTabIndex; i < Tabs.size() && !needRightScroll; ++i)\r
{\r
// get Text\r
const wchar_t* text = 0;\r
text = Tabs[i]->getText();\r
\r
// get text length\r
- s32 len = calcTabWidth(pos, font, text, true);\r
- if ( ScrollControl && pos+len > UpButton->getAbsolutePosition().UpperLeftCorner.X - 2 )\r
- {\r
- needRightScroll = true;\r
- break;\r
+ s32 len = calcTabWidth(font, text);\r
+ if (ScrollControl) {\r
+ s32 space = UpButton->getAbsolutePosition().UpperLeftCorner.X - 2 - pos;\r
+ if (space < len) {\r
+ needRightScroll = true;\r
+ len = space;\r
+ }\r
}\r
\r
frameRect.LowerRightCorner.X += len;\r
\r
void CGUITabControl::recalculateScrollBar()\r
{\r
+ // Down: to right, Up: to left\r
if (!UpButton || !DownButton)\r
return;\r
\r
if (!frameRect.isPointInside(p))\r
return -1;\r
\r
- for (s32 i=CurrentScrollTabIndex; i<(s32)Tabs.size(); ++i)\r
+ bool abort = false;\r
+ for (s32 i = CurrentScrollTabIndex; i < (s32)Tabs.size() && !abort; ++i)\r
{\r
// get Text\r
const wchar_t* text = 0;\r
text = Tabs[i]->getText();\r
\r
// get text length\r
- s32 len = calcTabWidth(pos, font, text, true);\r
- if ( ScrollControl && pos+len > UpButton->getAbsolutePosition().UpperLeftCorner.X - 2 )\r
- return -1;\r
+ s32 len = calcTabWidth(font, text);\r
+ if (ScrollControl) {\r
+ // TODO: merge this with draw() ?\r
+ s32 space = UpButton->getAbsolutePosition().UpperLeftCorner.X - 2 - pos;\r
+ if (space < len) {\r
+ abort = true;\r
+ len = space;\r
+ }\r
+ }\r
\r
frameRect.UpperLeftCorner.X = pos;\r
frameRect.LowerRightCorner.X = frameRect.UpperLeftCorner.X + len;\r
{\r
return i;\r
}\r
+\r
}\r
return -1;\r
}\r
Parent->OnEvent(event);\r
}\r
\r
+ if (ScrollControl) {\r
+ CurrentScrollTabIndex = calculateScrollIndexFromActive();\r
+ recalculateScrollBar();\r
+ }\r
+\r
return true;\r
}\r
\r