00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "CEGUIExceptions.h"
00027 #include "elements/CEGUITabControl.h"
00028 #include "elements/CEGUITabButton.h"
00029 #include "elements/CEGUIStatic.h"
00030 #include "elements/CEGUIGUISheet.h"
00031 #include "CEGUIFont.h"
00032 #include "CEGUIWindowManager.h"
00033
00034
00035 namespace CEGUI
00036 {
00037 const String TabControl::EventNamespace("TabControl");
00038
00039
00040
00041
00042 TabControlProperties::TabHeight TabControl::d_tabHeightProperty;
00043 TabControlProperties::AbsoluteTabHeight TabControl::d_absoluteTabHeightProperty;
00044 TabControlProperties::RelativeTabHeight TabControl::d_relativeTabHeightProperty;
00045 TabControlProperties::TabTextPadding TabControl::d_tabTextPaddingProperty;
00046 TabControlProperties::AbsoluteTabTextPadding TabControl::d_absoluteTabTextPaddingProperty;
00047 TabControlProperties::RelativeTabTextPadding TabControl::d_relativeTabTextPaddingProperty;
00048
00049
00050
00051
00052
00053 const String TabControl::EventSelectionChanged( (utf8*)"TabSelectionChanged" );
00054
00055
00056
00057
00058
00059 TabControl::TabControl(const String& type, const String& name)
00060 : Window(type, name),
00061 d_tabContentPane(NULL),
00062 d_tabButtonPane(NULL),
00063 d_nextTabIndex(0)
00064 {
00065 addTabControlEvents();
00066 addTabControlProperties();
00067 setRelativeTabHeight(0.05f);
00068 setAbsoluteTabTextPadding(5);
00069 }
00070
00071
00072
00073
00074
00075 TabControl::~TabControl(void)
00076 {
00077
00078 }
00079
00080
00081
00082
00083 void TabControl::initialise(void)
00084 {
00085
00086 d_tabContentPane = createTabContentPane();
00087 d_tabButtonPane = createTabButtonPane();
00088
00089 addChildWindow(d_tabContentPane);
00090 addChildWindow(d_tabButtonPane);
00091
00092 layoutComponentWidgets();
00093 }
00094
00095
00096
00097 uint TabControl::getTabCount(void) const
00098 {
00099 return d_tabContentPane->getChildCount();
00100 }
00101
00102
00103
00104 Window* TabControl::getTabContents(const String& name) const
00105 {
00106 return d_tabContentPane->getChild(name);
00107 }
00108
00109
00110
00111 Window* TabControl::getTabContents(uint ID) const
00112 {
00113 return d_tabContentPane->getChild(ID);
00114 }
00115
00116
00117
00118 Window* TabControl::getTabContentsAtIndex(uint index) const
00119 {
00120 return d_tabContentPane->getChildAtIdx(index);
00121 }
00122
00123
00124
00125
00126 bool TabControl::isTabContentsSelected(Window* wnd) const
00127 {
00128 TabButton* button = getButtonForTabContents(wnd);
00129 return button->isSelected();
00130 }
00131
00132
00133
00134
00135 uint TabControl::getSelectedTabIndex() const
00136 {
00137 uint index = 0;
00138 TabButtonIndexMap::const_iterator i, iend;
00139 iend = d_tabButtonIndexMap.end();
00140 for (i = d_tabButtonIndexMap.begin(); i != iend; ++i, ++index)
00141 {
00142
00143 TabButton* tb = i->second;
00144 if (tb->isSelected())
00145 {
00146 break;
00147 }
00148 }
00149 return index;
00150 }
00151
00152
00153
00154
00155 void TabControl::setSelectedTab(const String &name)
00156 {
00157
00158 Window* wnd = d_tabContentPane->getChild(name);
00159
00160 selectTab_impl(wnd);
00161 }
00162
00163
00164
00165 void TabControl::setSelectedTab(uint ID)
00166 {
00167
00168 Window* wnd = d_tabContentPane->getChild(ID);
00169
00170 selectTab_impl(wnd);
00171 }
00172
00173
00174
00175 void TabControl::setSelectedTabAtIndex(uint index)
00176 {
00177 Window* wnd = getTabContentsAtIndex(index);
00178 selectTab_impl(wnd);
00179 }
00180
00181
00182
00183 float TabControl::getTabHeight(void) const
00184 {
00185 MetricsMode mode = getMetricsMode();
00186 if (mode == Relative)
00187 {
00188 return d_rel_tabHeight;
00189 }
00190 else
00191 {
00192 return d_abs_tabHeight;
00193 }
00194 }
00195
00196
00197
00198
00199 void TabControl::setRelativeTabHeight(float height)
00200 {
00201 d_rel_tabHeight = height;
00202 d_abs_tabHeight = relativeToAbsoluteY(height);
00203
00204 layoutComponentWidgets();
00205 }
00206
00207
00208
00209 void TabControl::setAbsoluteTabHeight(float height)
00210 {
00211 d_abs_tabHeight = height;
00212 d_rel_tabHeight = absoluteToRelativeY(height);
00213
00214 layoutComponentWidgets();
00215 }
00216
00217
00218
00219 void TabControl::setTabHeight(float height)
00220 {
00221 if (getMetricsMode() == Relative)
00222 {
00223 setRelativeTabHeight(height);
00224 }
00225 else
00226 {
00227 setAbsoluteTabHeight(height);
00228 }
00229 }
00230
00231
00232
00233 float TabControl::getTabTextPadding(void) const
00234 {
00235 MetricsMode mode = getMetricsMode();
00236 if (mode == Relative)
00237 {
00238 return d_rel_tabPadding;
00239 }
00240 else
00241 {
00242 return d_abs_tabPadding;
00243 }
00244 }
00245
00246
00247
00248
00249 void TabControl::setRelativeTabTextPadding(float height)
00250 {
00251 d_rel_tabPadding = height;
00252 d_abs_tabPadding = relativeToAbsoluteY(height);
00253
00254 layoutComponentWidgets();
00255 }
00256
00257
00258
00259 void TabControl::setAbsoluteTabTextPadding(float height)
00260 {
00261 d_abs_tabPadding = height;
00262 d_rel_tabPadding = absoluteToRelativeY(height);
00263
00264 layoutComponentWidgets();
00265 }
00266
00267
00268
00269 void TabControl::setTabTextPadding(float height)
00270 {
00271 if (getMetricsMode() == Relative)
00272 {
00273 setRelativeTabTextPadding(height);
00274 }
00275 else
00276 {
00277 setAbsoluteTabTextPadding(height);
00278 }
00279 }
00280
00281
00282
00283
00284 void TabControl::addTab(Window* wnd)
00285 {
00286
00287 addButtonForTabContent(wnd);
00288
00289 d_tabContentPane->addChildWindow(wnd);
00290
00291 if (getTabCount() == 1)
00292 {
00293 setSelectedTab(wnd->getName());
00294 }
00295 else
00296 {
00297
00298 wnd->setVisible(false);
00299 }
00300
00301 layoutComponentWidgets();
00302 requestRedraw();
00303
00304 wnd->subscribeEvent(Window::EventTextChanged,
00305 Event::Subscriber(&TabControl::handleContentWindowTextChanged, this));
00306
00307 }
00308
00309
00310
00311 void TabControl::removeTab(const String& name)
00312 {
00313 Window* wnd = d_tabContentPane->getChild(name);
00314
00315 bool reselect = wnd->isVisible();
00316
00317 d_tabContentPane->removeChildWindow(name);
00318
00319
00320 removeButtonForTabContent(wnd);
00321
00322 if (reselect)
00323 {
00324
00325 if (getTabCount() > 0)
00326 {
00327 setSelectedTab(d_tabContentPane->getChildAtIdx(0)->getName());
00328 }
00329 }
00330
00331 layoutComponentWidgets();
00332
00333 requestRedraw();
00334
00335 }
00336
00337
00338
00339 void TabControl::removeTab(uint ID)
00340 {
00341 Window* wnd = d_tabContentPane->getChild(ID);
00342
00343 bool reselect = wnd->isVisible();
00344
00345 d_tabContentPane->removeChildWindow(ID);
00346
00347
00348 removeButtonForTabContent(wnd);
00349
00350 if (reselect)
00351 {
00352
00353 if (getTabCount() > 0)
00354 {
00355 setSelectedTab(d_tabContentPane->getChildAtIdx(0)->getName());
00356 }
00357 }
00358
00359 layoutComponentWidgets();
00360
00361 requestRedraw();
00362
00363 }
00364
00365
00366
00367 void TabControl::addButtonForTabContent(Window* wnd)
00368 {
00369
00370 TabButton* tb = createTabButton(makeButtonName(wnd));
00371
00372 tb->setFont(getFont());
00373
00374 tb->setTargetWindow(wnd);
00375
00376 tb->setTabIndex(d_nextTabIndex++);
00377
00378 d_tabButtonIndexMap.insert(
00379 TabButtonIndexMap::value_type(tb->getTabIndex(), tb));
00380
00381 d_tabButtonPane->addChildWindow(tb);
00382
00383 tb->subscribeEvent(TabButton::EventClicked,
00384 Event::Subscriber(&TabControl::handleTabButtonClicked, this));
00385
00386 }
00387
00388
00389
00390
00391 TabButton* TabControl::getButtonForTabContents(Window* wnd) const
00392 {
00393 TabButtonIndexMap::const_iterator i, iend;
00394 iend = d_tabButtonIndexMap.end();
00395 for (i = d_tabButtonIndexMap.begin(); i != iend; ++i)
00396 {
00397
00398 TabButton* tb = i->second;
00399 Window* child = tb->getTargetWindow();
00400 if (child == wnd)
00401 {
00402 return tb;
00403 }
00404 }
00405 throw UnknownObjectException((utf8*)"TabControl::getButtonForTabContents - The Window object is not a tab contents.");
00406 }
00407
00408
00409
00410 void TabControl::calculateTabButtonSizePosition(TabButton* btn, uint targetIndex)
00411 {
00412
00413
00414 btn->setHeight(Relative, 1.0f);
00415 btn->setYPosition(Relative, 0.0f);
00416
00417 if (targetIndex > 0)
00418 {
00419 TabButtonIndexMap::iterator iter = d_tabButtonIndexMap.begin();
00420 std::advance(iter, targetIndex - 1);
00421 Window* prevButton = iter->second;
00422
00423
00424 btn->setXPosition(Relative,
00425 prevButton->getXPosition(Relative)
00426 + prevButton->getWidth(Relative));
00427 }
00428 else
00429 {
00430
00431 btn->setXPosition(Relative, 0);
00432 }
00433
00434 const Font* fnt = btn->getFont();
00435 btn->setWidth(Absolute,
00436 fnt->getTextExtent(btn->getText()) + getAbsoluteTabTextPadding()*2);
00437 btn->requestRedraw();
00438 }
00439
00440
00441
00442 void TabControl::removeButtonForTabContent(Window* wnd)
00443 {
00444
00445 TabButton* tb = static_cast<TabButton*>(
00446 d_tabButtonPane->getChild(makeButtonName(wnd)));
00447
00448 d_tabButtonIndexMap.erase(tb->getTabIndex());
00449 d_tabButtonPane->removeChildWindow(tb);
00450
00451 WindowManager::getSingleton().destroyWindow(tb);
00452 }
00453
00454
00455
00456 String TabControl::makeButtonName(Window* wnd)
00457 {
00458
00459 String buttonName = (utf8*)"__auto_btn";
00460 buttonName.append(wnd->getName());
00461 return buttonName;
00462 }
00463
00464
00465
00466 void TabControl::selectTab_impl(Window* wnd)
00467 {
00468 bool modified = false;
00469 bool foundSelected = false;
00470
00471 TabButtonIndexMap::iterator i, iend;
00472 iend = d_tabButtonIndexMap.end();
00473 for (i = d_tabButtonIndexMap.begin(); i != iend; ++i)
00474 {
00475
00476 TabButton* tb = i->second;
00477 Window* child = tb->getTargetWindow();
00478
00479 bool selectThis = (child == wnd);
00480
00481 modified = modified || (tb->isSelected() != selectThis);
00482 foundSelected = foundSelected || selectThis;
00483
00484 tb->setSelected(selectThis);
00485 tb->setRightOfSelected(foundSelected);
00486 child->setVisible(selectThis);
00487 }
00488
00489 if (modified)
00490 {
00491 WindowEventArgs args(this);
00492 onSelectionChanged(args);
00493 }
00494 }
00495
00496
00497
00498 void TabControl::addTabControlProperties(void)
00499 {
00500 addProperty(&d_tabHeightProperty);
00501 addProperty(&d_relativeTabHeightProperty);
00502 addProperty(&d_absoluteTabHeightProperty);
00503 addProperty(&d_tabTextPaddingProperty);
00504 addProperty(&d_relativeTabTextPaddingProperty);
00505 addProperty(&d_absoluteTabTextPaddingProperty);
00506 }
00507
00508
00509
00510 void TabControl::addChild_impl(Window* wnd)
00511 {
00512
00513 if (wnd->getName().find((const utf8*)"__auto_TabPane__") != String::npos)
00514 {
00515
00516 Window::addChild_impl(wnd);
00517 }
00518 else
00519 {
00520
00521 addTab(wnd);
00522 }
00523 }
00524
00525
00526
00527 void TabControl::onSelectionChanged(WindowEventArgs& e)
00528 {
00529 requestRedraw();
00530 fireEvent(EventSelectionChanged, e, EventNamespace);
00531 }
00532
00533
00534
00535 void TabControl::onFontChanged(WindowEventArgs& e)
00536 {
00537
00538 TabButtonIndexMap::iterator i, iend;
00539 iend = d_tabButtonIndexMap.end();
00540 for (i = d_tabButtonIndexMap.end(); i != iend; ++i)
00541 {
00542 i->second->setFont(getFont());
00543 }
00544 }
00545
00546
00547
00548 void TabControl::addTabControlEvents(void)
00549 {
00550 addEvent(EventSelectionChanged);
00551 }
00552
00553
00554
00555 void TabControl::onSized(WindowEventArgs& e)
00556 {
00557
00558 Window::onSized(e);
00559
00560 layoutComponentWidgets();
00561
00562 e.handled = true;
00563 }
00564
00565
00566
00567 void TabControl::layoutComponentWidgets(void)
00568 {
00569 if (d_tabButtonPane)
00570 {
00571
00572 d_tabButtonPane->setSize(Relative, Size(1.0f, d_rel_tabHeight) );
00573 d_tabButtonPane->setPosition(Relative, Point(0.0f, 0.0f) );
00574
00575 TabButtonIndexMap::iterator i, iend;
00576 iend = d_tabButtonIndexMap.end();
00577 uint x = 0;
00578 for (i = d_tabButtonIndexMap.begin(); i != iend; ++i, ++x)
00579 {
00580 TabButton* btn = i->second;
00581 calculateTabButtonSizePosition(btn, x);
00582 }
00583 }
00584 if (d_tabContentPane)
00585 {
00586
00587 d_tabContentPane->setSize(Relative, Size(1.0f, 1.0f - d_rel_tabHeight) );
00588 d_tabContentPane->setPosition(Relative, Point(0.0f, d_rel_tabHeight) );
00589 }
00590
00591 }
00592
00593
00594
00595 Window* TabControl::createTabButtonPane(void) const
00596 {
00597
00598 String newName = getName() + (utf8*)"__auto_TabPane__Buttons";
00599 return WindowManager::getSingleton().createWindow(GUISheet::WidgetTypeName, newName);
00600 }
00601
00602
00603
00604 bool TabControl::handleContentWindowTextChanged(const EventArgs& args)
00605 {
00606
00607 const WindowEventArgs& wargs = static_cast<const WindowEventArgs&>(args);
00608 Window* tabButton = d_tabButtonPane->getChild(
00609 makeButtonName(wargs.window));
00610 tabButton->setText(wargs.window->getText());
00611
00612 layoutComponentWidgets();
00613 requestRedraw();
00614
00615 return true;
00616 }
00617
00618
00619
00620 bool TabControl::handleTabButtonClicked(const EventArgs& args)
00621 {
00622 const WindowEventArgs& wargs = static_cast<const WindowEventArgs&>(args);
00623 TabButton* tabButton = static_cast<TabButton*>(wargs.window);
00624 setSelectedTab(tabButton->getTargetWindow()->getName());
00625
00626 return true;
00627 }
00628 }