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