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_tabButtonPane(NULL),
00062 d_tabContentPane(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(getName() + "__auto_TabPane__");
00087 d_tabButtonPane = createTabButtonPane(getName() + "__auto_TabPane__Buttons");
00088
00089 addChildWindow(d_tabContentPane);
00090 addChildWindow(d_tabButtonPane);
00091
00092 performChildWindowLayout();
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_tabButtonIndexMap.find(index)->second->getTargetWindow();
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;
00138 TabButtonIndexMap::const_iterator i, iend;
00139 iend = d_tabButtonIndexMap.end();
00140 for (i = d_tabButtonIndexMap.begin(); i != iend; ++i)
00141 {
00142
00143 TabButton* tb = i->second;
00144 if (tb->isSelected())
00145 {
00146 index = i->first;
00147 break;
00148 }
00149 }
00150 return index;
00151 }
00152
00153
00154
00155
00156 void TabControl::setSelectedTab(const String &name)
00157 {
00158
00159 Window* wnd = d_tabContentPane->getChild(name);
00160
00161 selectTab_impl(wnd);
00162 }
00163
00164
00165
00166 void TabControl::setSelectedTab(uint ID)
00167 {
00168
00169 Window* wnd = d_tabContentPane->getChild(ID);
00170
00171 selectTab_impl(wnd);
00172 }
00173
00174
00175
00176 void TabControl::setSelectedTabAtIndex(uint index)
00177 {
00178 Window* wnd = getTabContentsAtIndex(index);
00179 selectTab_impl(wnd);
00180 }
00181
00182
00183
00184 float TabControl::getTabHeight(void) const
00185 {
00186 MetricsMode mode = getMetricsMode();
00187 if (mode == Relative)
00188 {
00189 return d_rel_tabHeight;
00190 }
00191 else
00192 {
00193 return d_abs_tabHeight;
00194 }
00195 }
00196
00197
00198
00199
00200 void TabControl::setRelativeTabHeight(float height)
00201 {
00202 d_rel_tabHeight = height;
00203 d_abs_tabHeight = relativeToAbsoluteY(height);
00204
00205 performChildWindowLayout();
00206 }
00207
00208
00209
00210 void TabControl::setAbsoluteTabHeight(float height)
00211 {
00212 d_abs_tabHeight = height;
00213 d_rel_tabHeight = absoluteToRelativeY(height);
00214
00215 performChildWindowLayout();
00216 }
00217
00218
00219
00220 void TabControl::setTabHeight(float height)
00221 {
00222 if (getMetricsMode() == Relative)
00223 {
00224 setRelativeTabHeight(height);
00225 }
00226 else
00227 {
00228 setAbsoluteTabHeight(height);
00229 }
00230 }
00231
00232
00233
00234 float TabControl::getTabTextPadding(void) const
00235 {
00236 MetricsMode mode = getMetricsMode();
00237 if (mode == Relative)
00238 {
00239 return d_rel_tabPadding;
00240 }
00241 else
00242 {
00243 return d_abs_tabPadding;
00244 }
00245 }
00246
00247
00248
00249
00250 void TabControl::setRelativeTabTextPadding(float height)
00251 {
00252 d_rel_tabPadding = height;
00253 d_abs_tabPadding = relativeToAbsoluteY(height);
00254
00255 performChildWindowLayout();
00256 }
00257
00258
00259
00260 void TabControl::setAbsoluteTabTextPadding(float height)
00261 {
00262 d_abs_tabPadding = height;
00263 d_rel_tabPadding = absoluteToRelativeY(height);
00264
00265 performChildWindowLayout();
00266 }
00267
00268
00269
00270 void TabControl::setTabTextPadding(float height)
00271 {
00272 if (getMetricsMode() == Relative)
00273 {
00274 setRelativeTabTextPadding(height);
00275 }
00276 else
00277 {
00278 setAbsoluteTabTextPadding(height);
00279 }
00280 }
00281
00282
00283
00284
00285 void TabControl::addTab(Window* wnd)
00286 {
00287
00288 addButtonForTabContent(wnd);
00289
00290 d_tabContentPane->addChildWindow(wnd);
00291
00292 if (getTabCount() == 1)
00293 {
00294 setSelectedTab(wnd->getName());
00295 }
00296 else
00297 {
00298
00299 wnd->setVisible(false);
00300 }
00301
00302 performChildWindowLayout();
00303 requestRedraw();
00304
00305 wnd->subscribeEvent(Window::EventTextChanged,
00306 Event::Subscriber(&TabControl::handleContentWindowTextChanged, this));
00307
00308 }
00309
00310
00311
00312 void TabControl::removeTab(const String& name)
00313 {
00314 Window* wnd = d_tabContentPane->getChild(name);
00315
00316 bool reselect = wnd->isVisible();
00317
00318 d_tabContentPane->removeChildWindow(name);
00319
00320
00321 removeButtonForTabContent(wnd);
00322
00323 if (reselect)
00324 {
00325
00326 if (getTabCount() > 0)
00327 {
00328 setSelectedTab(d_tabContentPane->getChildAtIdx(0)->getName());
00329 }
00330 }
00331
00332 performChildWindowLayout();
00333
00334 requestRedraw();
00335
00336 }
00337
00338
00339
00340 void TabControl::removeTab(uint ID)
00341 {
00342 Window* wnd = d_tabContentPane->getChild(ID);
00343
00344 bool reselect = wnd->isVisible();
00345
00346 d_tabContentPane->removeChildWindow(ID);
00347
00348
00349 removeButtonForTabContent(wnd);
00350
00351 if (reselect)
00352 {
00353
00354 if (getTabCount() > 0)
00355 {
00356 setSelectedTab(d_tabContentPane->getChildAtIdx(0)->getName());
00357 }
00358 }
00359
00360 performChildWindowLayout();
00361
00362 requestRedraw();
00363
00364 }
00365
00366
00367
00368 void TabControl::addButtonForTabContent(Window* wnd)
00369 {
00370
00371 TabButton* tb = createTabButton(makeButtonName(wnd));
00372
00373 tb->setFont(getFont());
00374
00375 tb->setTargetWindow(wnd);
00376
00377 tb->setTabIndex(d_nextTabIndex++);
00378
00379 d_tabButtonIndexMap.insert(
00380 TabButtonIndexMap::value_type(tb->getTabIndex(), tb));
00381
00382 d_tabButtonPane->addChildWindow(tb);
00383
00384 tb->subscribeEvent(TabButton::EventClicked,
00385 Event::Subscriber(&TabControl::handleTabButtonClicked, this));
00386
00387 }
00388
00389
00390
00391
00392 TabButton* TabControl::getButtonForTabContents(Window* wnd) const
00393 {
00394 TabButtonIndexMap::const_iterator i, iend;
00395 iend = d_tabButtonIndexMap.end();
00396 for (i = d_tabButtonIndexMap.begin(); i != iend; ++i)
00397 {
00398
00399 TabButton* tb = i->second;
00400 Window* child = tb->getTargetWindow();
00401 if (child == wnd)
00402 {
00403 return tb;
00404 }
00405 }
00406 throw UnknownObjectException((utf8*)"TabControl::getButtonForTabContents - The Window object is not a tab contents.");
00407 }
00408
00409
00410
00411 void TabControl::calculateTabButtonSizePosition(TabButton* btn, uint targetIndex)
00412 {
00413
00414
00415 btn->setHeight(Relative, 1.0f);
00416 btn->setYPosition(Relative, 0.0f);
00417
00418 if (targetIndex > 0)
00419 {
00420 TabButtonIndexMap::iterator iter = d_tabButtonIndexMap.begin();
00421 std::advance(iter, targetIndex - 1);
00422 Window* prevButton = iter->second;
00423
00424
00425 btn->setXPosition(Relative,
00426 prevButton->getXPosition(Relative)
00427 + prevButton->getWidth(Relative));
00428 }
00429 else
00430 {
00431
00432 btn->setXPosition(Relative, 0);
00433 }
00434
00435 const Font* fnt = btn->getFont();
00436 btn->setWidth(Absolute,
00437 fnt->getTextExtent(btn->getText()) + getAbsoluteTabTextPadding()*2);
00438 btn->requestRedraw();
00439 }
00440
00441
00442
00443 void TabControl::removeButtonForTabContent(Window* wnd)
00444 {
00445
00446 TabButton* tb = static_cast<TabButton*>(
00447 d_tabButtonPane->getChild(makeButtonName(wnd)));
00448
00449 d_tabButtonIndexMap.erase(tb->getTabIndex());
00450 d_tabButtonPane->removeChildWindow(tb);
00451
00452 WindowManager::getSingleton().destroyWindow(tb);
00453 }
00454
00455
00456
00457 String TabControl::makeButtonName(Window* wnd)
00458 {
00459
00460 String buttonName = (utf8*)"__auto_btn";
00461 buttonName.append(wnd->getName());
00462 return buttonName;
00463 }
00464
00465
00466
00467 void TabControl::selectTab_impl(Window* wnd)
00468 {
00469 bool modified = false;
00470 bool foundSelected = false;
00471
00472 TabButtonIndexMap::iterator i, iend;
00473 iend = d_tabButtonIndexMap.end();
00474 for (i = d_tabButtonIndexMap.begin(); i != iend; ++i)
00475 {
00476
00477 TabButton* tb = i->second;
00478 Window* child = tb->getTargetWindow();
00479
00480 bool selectThis = (child == wnd);
00481
00482 modified = modified || (tb->isSelected() != selectThis);
00483 foundSelected = foundSelected || selectThis;
00484
00485 tb->setSelected(selectThis);
00486 tb->setRightOfSelected(foundSelected);
00487 child->setVisible(selectThis);
00488 }
00489
00490 if (modified)
00491 {
00492 WindowEventArgs args(this);
00493 onSelectionChanged(args);
00494 }
00495 }
00496
00497
00498
00499 void TabControl::addTabControlProperties(void)
00500 {
00501 addProperty(&d_tabHeightProperty);
00502 addProperty(&d_relativeTabHeightProperty);
00503 addProperty(&d_absoluteTabHeightProperty);
00504 addProperty(&d_tabTextPaddingProperty);
00505 addProperty(&d_relativeTabTextPaddingProperty);
00506 addProperty(&d_absoluteTabTextPaddingProperty);
00507 }
00508
00509
00510
00511 void TabControl::addChild_impl(Window* wnd)
00512 {
00513
00514 if (wnd->getName().find((const utf8*)"__auto_TabPane__") != String::npos)
00515 {
00516
00517 Window::addChild_impl(wnd);
00518 }
00519 else
00520 {
00521
00522 addTab(wnd);
00523 }
00524 }
00525
00526
00527
00528 void TabControl::onSelectionChanged(WindowEventArgs& e)
00529 {
00530 requestRedraw();
00531 fireEvent(EventSelectionChanged, e, EventNamespace);
00532 }
00533
00534
00535
00536 void TabControl::onFontChanged(WindowEventArgs& e)
00537 {
00538
00539 TabButtonIndexMap::iterator i, iend;
00540 iend = d_tabButtonIndexMap.end();
00541 for (i = d_tabButtonIndexMap.end(); i != iend; ++i)
00542 {
00543 i->second->setFont(getFont());
00544 }
00545 }
00546
00547
00548
00549 void TabControl::addTabControlEvents(void)
00550 {
00551 addEvent(EventSelectionChanged);
00552 }
00553
00554
00555
00556 void TabControl::performChildWindowLayout()
00557 {
00558 Window::performChildWindowLayout();
00559
00560 if (d_tabButtonPane)
00561 {
00562
00563 d_tabButtonPane->setSize(Relative, Size(1.0f, d_rel_tabHeight) );
00564 d_tabButtonPane->setPosition(Relative, Point(0.0f, 0.0f) );
00565
00566 TabButtonIndexMap::iterator i, iend;
00567 iend = d_tabButtonIndexMap.end();
00568 uint x = 0;
00569 for (i = d_tabButtonIndexMap.begin(); i != iend; ++i, ++x)
00570 {
00571 TabButton* btn = i->second;
00572 calculateTabButtonSizePosition(btn, x);
00573 }
00574 }
00575 if (d_tabContentPane)
00576 {
00577
00578 d_tabContentPane->setSize(Relative, Size(1.0f, 1.0f - d_rel_tabHeight) );
00579 d_tabContentPane->setPosition(Relative, Point(0.0f, d_rel_tabHeight) );
00580 }
00581
00582 }
00583
00584
00585
00586 Window* TabControl::createTabButtonPane(const String& name) const
00587 {
00588 return WindowManager::getSingleton().createWindow(GUISheet::WidgetTypeName, name);
00589 }
00590
00591
00592
00593 bool TabControl::handleContentWindowTextChanged(const EventArgs& args)
00594 {
00595
00596 const WindowEventArgs& wargs = static_cast<const WindowEventArgs&>(args);
00597 Window* tabButton = d_tabButtonPane->getChild(
00598 makeButtonName(wargs.window));
00599 tabButton->setText(wargs.window->getText());
00600
00601 performChildWindowLayout();
00602 requestRedraw();
00603
00604 return true;
00605 }
00606
00607
00608
00609 bool TabControl::handleTabButtonClicked(const EventArgs& args)
00610 {
00611 const WindowEventArgs& wargs = static_cast<const WindowEventArgs&>(args);
00612 TabButton* tabButton = static_cast<TabButton*>(wargs.window);
00613 setSelectedTab(tabButton->getTargetWindow()->getName());
00614
00615 return true;
00616 }
00617
00618 int TabControl::writeChildWindowsXML(OutStream& out_stream) const
00619 {
00620 int childOutputCount = Window::writeChildWindowsXML(out_stream);
00621
00622
00623
00624
00625 for (uint i = 0; i < getTabCount(); ++i)
00626 {
00627 getTabContentsAtIndex(i)->writeXMLToStream(out_stream);
00628 ++childOutputCount;
00629 }
00630
00631 return childOutputCount;
00632 }
00633
00634 }