1 /***********************************************************************
2     created:    27/6/2006
3     author:     Andrew Zabolotny
4 *************************************************************************/
5 /***************************************************************************
6  *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
7  *
8  *   Permission is hereby granted, free of charge, to any person obtaining
9  *   a copy of this software and associated documentation files (the
10  *   "Software"), to deal in the Software without restriction, including
11  *   without limitation the rights to use, copy, modify, merge, publish,
12  *   distribute, sublicense, and/or sell copies of the Software, and to
13  *   permit persons to whom the Software is furnished to do so, subject to
14  *   the following conditions:
15  *
16  *   The above copyright notice and this permission notice shall be
17  *   included in all copies or substantial portions of the Software.
18  *
19  *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20  *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21  *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22  *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23  *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24  *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25  *   OTHER DEALINGS IN THE SOFTWARE.
26  ***************************************************************************/
27 #include "SampleBase.h"
28 #include "CEGUI/CEGUI.h"
29 
30 using namespace CEGUI;
31 
32 #define SKIN "TaharezLook"
33 // for this to work you'll have to change the .layout files
34 //#define SKIN "WindowsLook"
35 
36 static const char* PageText [] =
37 {
38     "This is page three",
39     "And this is page four, it's not too different from page three, isn't it?",
40     "Yep, you guessed, this is page five",
41     "And this is page six",
42     "Seven",
43     "Eight",
44     "Nine. Quite boring, isn't it?",
45     "Ten",
46     "Eleven",
47     "Twelve",
48     "Thirteen",
49     "Fourteen",
50     "Fifteen",
51     "And, finally, sixteen. Congrats, you found the last page!",
52 };
53 
54 // Sample sub-class for ListboxTextItem that auto-sets the selection brush
55 // image.  This saves doing it manually every time in the code.
56 class MyListItem : public ListboxTextItem
57 {
58 public:
MyListItem(const String & text)59     MyListItem(const String& text) : ListboxTextItem(text)
60     {
61         setSelectionBrushImage(SKIN "/MultiListSelectionBrush");
62     }
63 };
64 
65 // Sample class
66 class TabControlDemo : public Sample
67 {
68 public:
69     // method to initialse the samples windows and events.
initialise(CEGUI::GUIContext * guiContext)70     bool initialise(CEGUI::GUIContext* guiContext)
71     {
72         d_guiContext = guiContext;
73         d_usedFiles = CEGUI::String(__FILE__);
74 
75         // load font and setup default if not loaded via scheme
76         Font& defaultFont = FontManager::getSingleton().createFromFile("DejaVuSans-12.font");
77         // Set default font for the gui context
78         guiContext->setDefaultFont(&defaultFont);
79 
80         // we will use of the WindowManager.
81         WindowManager& winMgr = WindowManager::getSingleton();
82 
83         // load scheme and set up defaults
84         SchemeManager::getSingleton().createFromFile(SKIN ".scheme");
85         d_guiContext->getMouseCursor().setDefaultImage(SKIN "/MouseArrow");
86 
87         // load an image to use as a background
88         if( !ImageManager::getSingleton().isDefined("SpaceBackgroundImage") )
89             ImageManager::getSingleton().addFromImageFile("SpaceBackgroundImage", "SpaceBackground.jpg");
90 
91         // here we will use a StaticImage as the root, then we can use it to place a background image
92         Window* background = winMgr.createWindow(SKIN "/StaticImage");
93         // set area rectangle
94         background->setArea(URect(cegui_reldim(0), cegui_reldim(0),
95                                   cegui_reldim(1), cegui_reldim(1)));
96         // disable frame and standard background
97         background->setProperty("FrameEnabled", "false");
98         background->setProperty("BackgroundEnabled", "false");
99         // set the background image
100         background->setProperty("Image", "SpaceBackgroundImage");
101         // install this as the root GUI sheet
102         d_guiContext->setRootWindow(background);
103 
104         // set tooltip styles (by default there is none)
105         d_guiContext->setDefaultTooltipType(SKIN "/Tooltip");
106 
107         // load some demo windows and attach to the background 'root'
108         background->addChild(winMgr.loadLayoutFromFile("TabControlDemo.layout"));
109 
110         TabControl* tc = static_cast<TabControl*>(background->getChild("Frame/TabControl"));
111 
112         // Add some pages to tab control
113         tc->addTab(winMgr.loadLayoutFromFile("TabPage1.layout"));
114         tc->addTab(winMgr.loadLayoutFromFile("TabPage2.layout"));
115 
116         WindowManager::getSingleton().DEBUG_dumpWindowNames("asd");
117 
118         static_cast<PushButton*>(
119             background->getChild("Frame/TabControl/Page1/AddTab"))->subscribeEvent(
120                 PushButton::EventClicked,
121                 Event::Subscriber(&TabControlDemo::handleAddTab, this));
122 
123         // Click to visit this tab
124         static_cast<PushButton*>(
125             background->getChild("Frame/TabControl/Page1/Go"))->subscribeEvent(
126                 PushButton::EventClicked,
127                 Event::Subscriber(&TabControlDemo::handleGoto, this));
128 
129         // Click to make this tab button visible (when scrolling is required)
130         static_cast<PushButton*>(
131             background->getChild("Frame/TabControl/Page1/Show"))->subscribeEvent(
132                 PushButton::EventClicked,
133                 Event::Subscriber(&TabControlDemo::handleShow, this));
134 
135         static_cast<PushButton*>(
136             background->getChild("Frame/TabControl/Page1/Del"))->subscribeEvent(
137                 PushButton::EventClicked,
138                 Event::Subscriber(&TabControlDemo::handleDel, this));
139 
140         RadioButton* rb = static_cast<RadioButton*>(
141                               background->getChild("Frame/TabControl/Page1/TabPaneTop"));
142         rb->setSelected(tc->getTabPanePosition() == TabControl::Top);
143         rb->subscribeEvent(
144             RadioButton::EventSelectStateChanged,
145             Event::Subscriber(&TabControlDemo::handleTabPanePos, this));
146 
147         rb = static_cast<RadioButton*>(
148                  background->getChild("Frame/TabControl/Page1/TabPaneBottom"));
149         rb->setSelected(tc->getTabPanePosition() == TabControl::Bottom);
150         rb->subscribeEvent(
151             RadioButton::EventSelectStateChanged,
152             Event::Subscriber(&TabControlDemo::handleTabPanePos, this));
153 
154         Scrollbar* sb = static_cast<Scrollbar*>(
155                             background->getChild("Frame/TabControl/Page1/TabHeight"));
156         sb->setScrollPosition(tc->getTabHeight().d_offset);
157         sb->subscribeEvent(
158             Scrollbar::EventScrollPositionChanged,
159             Event::Subscriber(&TabControlDemo::handleTabHeight, this));
160 
161         sb = static_cast<Scrollbar*>(
162                  background->getChild("Frame/TabControl/Page1/TabPadding"));
163         sb->setScrollPosition(tc->getTabTextPadding().d_offset);
164         sb->subscribeEvent(
165             Scrollbar::EventScrollPositionChanged,
166             Event::Subscriber(&TabControlDemo::handleTabPadding, this));
167 
168         refreshPageList();
169 
170         // From now on, we don't rely on the exceptions anymore, but perform nice (and recommended) checks
171         // ourselves.
172 
173         return true;
174     }
175 
176     // method to perform any required cleanup operations.
deinitialise()177     void deinitialise()
178     {
179     }
180 
refreshPageList()181     void refreshPageList()
182     {
183         Window* root = d_guiContext->getRootWindow();
184         // Check if the windows exists
185         Listbox* lbox = 0;
186         TabControl* tc = 0;
187 
188         if (root->isChild("Frame/TabControl/Page1/PageList"))
189         {
190             lbox = static_cast<Listbox*>(root->getChild(
191                                              "Frame/TabControl/Page1/PageList"));
192         }
193 
194         if (root->isChild("Frame/TabControl"))
195         {
196             tc = static_cast<TabControl*>(root->getChild(
197                                               "Frame/TabControl"));
198         }
199 
200         if (lbox && tc)
201         {
202             lbox->resetList();
203 
204             for (size_t i = 0; i < tc->getTabCount(); i++)
205             {
206                 lbox->addItem(new MyListItem(
207                                   tc->getTabContentsAtIndex(i)->getName()));
208             }
209         }
210     }
211 
handleTabPanePos(const EventArgs & e)212     bool handleTabPanePos(const EventArgs& e)
213     {
214         TabControl::TabPanePosition tpp;
215 
216         switch (static_cast<const WindowEventArgs&>(e).window->getID())
217         {
218         case 0:
219             tpp = TabControl::Top;
220             break;
221         case 1:
222             tpp = TabControl::Bottom;
223             break;
224         default:
225             return false;
226         }
227 
228         // Check if the window exists
229         Window* root = d_guiContext->getRootWindow();
230 
231         if (root->isChild("Frame/TabControl"))
232         {
233             static_cast<TabControl*>(root->getChild(
234                                          "Frame/TabControl"))->setTabPanePosition(tpp);
235         }
236 
237         return true;
238     }
239 
handleTabHeight(const EventArgs & e)240     bool handleTabHeight(const EventArgs& e)
241     {
242         Scrollbar* sb = static_cast<Scrollbar*>(
243                             static_cast<const WindowEventArgs&>(e).window);
244 
245         // Check if the window exists
246         Window* root = d_guiContext->getRootWindow();
247 
248         if (root->isChild("Frame/TabControl"))
249         {
250             static_cast<TabControl*>(root->getChild(
251                                          "Frame/TabControl"))->setTabHeight(
252                                              UDim(0, sb->getScrollPosition()));
253         }
254 
255         // The return value mainly sais that we handled it, not if something failed.
256         return true;
257     }
258 
handleTabPadding(const EventArgs & e)259     bool handleTabPadding(const EventArgs& e)
260     {
261         Scrollbar* sb = static_cast<Scrollbar*>(
262                             static_cast<const WindowEventArgs&>(e).window);
263 
264         // Check if the window exists
265         Window* root = d_guiContext->getRootWindow();
266 
267         if (root->isChild("Frame/TabControl"))
268         {
269             static_cast<TabControl*>(root->getChild(
270                                          "Frame/TabControl"))->setTabTextPadding(
271                                              UDim(0, sb->getScrollPosition()));
272         }
273 
274         return true;
275     }
276 
handleAddTab(const EventArgs &)277     bool handleAddTab(const EventArgs&)
278     {
279         Window* root = d_guiContext->getRootWindow();
280 
281         // Check if the window exists
282         if (root->isChild("Frame/TabControl"))
283         {
284             TabControl* tc = static_cast<TabControl*>(root->getChild(
285                                  "Frame/TabControl"));
286 
287             // Add some tab buttons once
288             for (int num = 3; num <= 16; num++)
289             {
290                 std::stringstream pgname;
291                 pgname << "Page" << num;
292 
293                 if (root->isChild(String("Frame/TabControl/") + pgname.str().c_str()))
294                     // Next
295                     continue;
296 
297                 Window* pg = 0;
298 
299                 pg = WindowManager::getSingleton().loadLayoutFromFile("TabPage.layout");
300                 CEGUI_TRY
301                 {
302                     pg = WindowManager::getSingleton().loadLayoutFromFile("TabPage.layout");
303                     pg->setName(String(pgname.str().c_str()));
304                 }
305                 CEGUI_CATCH(CEGUI::Exception&)
306                 {
307                     Logger::getSingleton().logEvent("Some error occured while adding a tabpage. Please see the logfile.");
308                     break;
309                 }
310 
311                 // This window has just been created while loading the layout
312                 if (pg->isChild("Text"))
313                 {
314                     Window* txt = pg->getChild("Text");
315                     txt->setText(PageText [num - 3]);
316 
317                     pg->setText(pgname.str().c_str());
318                     tc->addTab(pg);
319 
320                     refreshPageList();
321                     break;
322                 }
323             }
324         }
325 
326         return true;
327     }
328 
handleGoto(const EventArgs &)329     bool handleGoto(const EventArgs&)
330     {
331         Window* root = d_guiContext->getRootWindow();
332         // Check if the windows exists
333         Listbox* lbox = 0;
334         TabControl* tc = 0;
335 
336         if (root->isChild("Frame/TabControl/Page1/PageList"))
337         {
338             lbox = static_cast<Listbox*>(root->getChild(
339                                              "Frame/TabControl/Page1/PageList"));
340         }
341 
342         if (root->isChild("Frame/TabControl"))
343         {
344             tc = static_cast<TabControl*>(root->getChild(
345                                               "Frame/TabControl"));
346         }
347 
348         if (lbox && tc)
349         {
350             ListboxItem* lbi = lbox->getFirstSelectedItem();
351 
352             if (lbi)
353             {
354                 tc->setSelectedTab(lbi->getText());
355             }
356         }
357 
358         return true;
359     }
360 
handleShow(const EventArgs &)361     bool handleShow(const EventArgs&)
362     {
363         Window* root = d_guiContext->getRootWindow();
364         // Check if the windows exists
365         Listbox* lbox = 0;
366         TabControl* tc = 0;
367 
368         if (root->isChild("Frame/TabControl/Page1/PageList"))
369         {
370             lbox = static_cast<Listbox*>(root->getChild(
371                                              "Frame/TabControl/Page1/PageList"));
372         }
373 
374         if (root->isChild("Frame/TabControl"))
375         {
376             tc = static_cast<TabControl*>(root->getChild(
377                                               "Frame/TabControl"));
378         }
379 
380         if (lbox && tc)
381         {
382             ListboxItem* lbi = lbox->getFirstSelectedItem();
383 
384             if (lbi)
385             {
386                 tc->makeTabVisible(lbi->getText());
387             }
388         }
389 
390         return true;
391     }
392 
handleDel(const EventArgs &)393     bool handleDel(const EventArgs&)
394     {
395         Window* root = d_guiContext->getRootWindow();
396         // Check if the windows exists
397         Listbox* lbox = 0;
398         TabControl* tc = 0;
399 
400         if (root->isChild("Frame/TabControl/Page1/PageList"))
401         {
402             lbox = static_cast<Listbox*>(root->getChild(
403                                              "Frame/TabControl/Page1/PageList"));
404         }
405 
406         if (root->isChild("Frame/TabControl"))
407         {
408             tc = static_cast<TabControl*>(root->getChild(
409                                               "Frame/TabControl"));
410         }
411 
412         if (lbox && tc)
413         {
414             ListboxItem* lbi = lbox->getFirstSelectedItem();
415 
416             if (lbi)
417             {
418                 Window* content = tc->getTabContents(lbi->getText());
419                 tc->removeTab(lbi->getText());
420                 // Remove the actual window from Cegui
421                 WindowManager::getSingleton().destroyWindow(content);
422 
423                 refreshPageList();
424             }
425         }
426 
427         return true;
428     }
429 
430 
431     protected:
432         CEGUI::GUIContext* d_guiContext;
433 };
434 
435 /*************************************************************************
436     Define the module function that returns an instance of the sample
437 *************************************************************************/
getSampleInstance()438 extern "C" SAMPLE_EXPORT Sample& getSampleInstance()
439 {
440     static TabControlDemo sample;
441     return sample;
442 }
443