Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/gamestate/src/modules/questsystem/QuestGUINode.cc @ 6772

Last change on this file since 6772 was 6564, checked in by rgrieder, 15 years ago

Changed use of CEGUI widgets: Instead of addressing a type with "TaharezLook/Button" I changed it to "MenuWidgets/MyWidget".
That allows to define multiple skins for the menu and simply load the one we like.
Furthermore the idea is to use "HUDWidgets/MyWidget" for HUD elements. But I haven't added that.

  • Property svn:eol-style set to native
File size: 14.8 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Damian 'Mozork' Frick
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "QuestGUINode.h"
30
31#include <sstream>
32
33#include <CEGUIWindowManager.h>
34#include <elements/CEGUIFrameWindow.h>
35#include <elements/CEGUIPushButton.h>
36#include <falagard/CEGUIFalWidgetLookFeel.h>
37#include <falagard/CEGUIFalWidgetLookManager.h>
38
39#include "core/CoreIncludes.h"
40#include "Quest.h"
41#include "QuestHint.h"
42#include "QuestItem.h"
43#include "QuestDescription.h"
44#include "QuestGUI.h"
45
46namespace orxonox {
47
48    /**
49    @brief
50        Default Constructor. Registers and initializes the object.
51    */
52    QuestGUINode::QuestGUINode(void)
53    {
54        this->initialize();
55    }
56
57    /**
58    @brief
59        Constructor. Registers and initializes the object.
60    @param gui
61        The QuestGUi the node beongs to.
62    @param parent
63        The parent node of the newly created node.
64    @param item
65        The QuestItem the  newly created node is for.
66    @param depth
67        Parameter to define how much the list item has to be indented.
68    @param index
69        "Counter" for Quests and Hints.
70    */
71    QuestGUINode::QuestGUINode(QuestGUI* gui, QuestGUINode* parent, QuestItem* item, int depth, int index)
72    {
73        this->initialize();
74
75        this->gui_ = gui;
76        this->parent_ = parent;
77        this->item_ = item;
78        this->depth_ = depth;
79        this->index_ = index;
80
81        this->createWindow();
82
83        COUT(3) << "New QuestGUINode '" << this->window_->getName() << "' created." << std::endl;
84    }
85
86    /**
87    @brief
88        Destructor.
89    @todo
90        Destroying everything?
91    */
92    QuestGUINode::~QuestGUINode(void)
93    {
94        if(this->window_ != NULL)
95            this->window_->destroy();
96        if(this->details_ != NULL)
97        {
98            this->details_->destroy();
99        }
100    }
101
102    /**
103    @brief
104        Initialize the object.
105    */
106    void QuestGUINode::initialize(void)
107    {
108        RegisterRootObject(QuestGUINode);
109
110        this->parent_ = NULL;
111        this->item_ = NULL;
112        this->window_ = NULL;
113        this->details_ = NULL;
114        this->depth_ = 0;
115        this->index_ = 0;
116        this->visible_ = true;
117    }
118
119    void QuestGUINode::toggleVisibility(void)
120    {
121
122    }
123
124    /**
125    @brief
126        Sets the input buffer to the name of the node.
127    @param buffer
128        The buffer that is set to the name of the node.
129    @todo
130        Needed?
131    */
132    void QuestGUINode::getName(std::string & buffer)
133    {
134        if(this->window_ != NULL)
135        {
136            buffer = this->window_->getName().c_str();
137        }
138        else
139        {
140            buffer.erase();
141        }
142    }
143
144    /**
145    @brief
146        Creates the details window.
147    @return
148        Returns the details window.
149    @todo
150        Return necessary?
151    */
152    CEGUI::Window* QuestGUINode::getDetails(void)
153    {
154
155        if(this->details_ == NULL) //!< If the details window was not already created.
156        {
157            std::ostringstream stream;
158
159            //! Create the main window for the details.
160            stream << this->window_->getName() << "/Details";
161            const QuestDescription* description = this->item_->getDescription();
162            this->details_ = this->gui_->getWindowManager()->createWindow("MenuWidgets/FrameWindow", stream.str());
163            this->details_->setSize(CEGUI::UVector2(CEGUI::UDim(0.7, 0),CEGUI::UDim(0.7, 0)));
164            this->details_->setPosition(CEGUI::UVector2(CEGUI::UDim(0.1, 0),CEGUI::UDim(0.1, 0)));
165            this->details_->setText(description->getTitle());
166            this->details_->setAlpha(1.0);
167            this->details_->setInheritsAlpha(false);
168            this->details_->setProperty("CloseButtonEnabled", "True");
169            this->details_->subscribeEvent(CEGUI::FrameWindow::EventCloseClicked, CEGUI::Event::Subscriber(&QuestGUINode::closeDetails, this));
170
171            //! Create a ScrollablePane.
172            stream << "/Scrollable";
173            CEGUI::Window* window = this->gui_->getWindowManager()->createWindow("MenuWidgets/ScrollablePane", stream.str());
174            window->setSize(CEGUI::UVector2(CEGUI::UDim(1.0, -2*QuestGUINode::BORDER_WIDTH),CEGUI::UDim(1.0, -QuestGUINode::TITLE_HEIGHT)));
175            window->setPosition(CEGUI::UVector2(CEGUI::UDim(0, QuestGUINode::BORDER_WIDTH),CEGUI::UDim(0, QuestGUINode::TITLE_HEIGHT)));
176            this->details_->addChildWindow(window);
177
178            int height;
179            int offset = 0;
180
181            //! Display the status of the QuestItem if it is a Quest.
182            Quest* quest = dynamic_cast<Quest*>(this->item_);
183            if(quest != NULL) //!< If the QuestItem is a Quest
184            {
185                stream.str("");
186                stream << this->details_->getName() << "/Status";
187                CEGUI::Window* statusWindow = this->gui_->getWindowManager()->createWindow("MenuWidgets/StaticText", stream.str());
188                window->addChildWindow(statusWindow);
189                std::string status;
190                if(quest->isActive(this->gui_->getPlayer()))
191                {
192                    status = "This quest is active.";
193                }
194                else if(quest->isCompleted(this->gui_->getPlayer()))
195                {
196                    status = "This quest was completed.";
197                }
198                else if(quest->isFailed(this->gui_->getPlayer()))
199                {
200                    status = "This quest was failed.";
201                }
202                statusWindow->setProperty("HorzFormatting", "WordWrapLeftAligned");
203                statusWindow->setProperty("VertFormatting", "TopAligned");
204                statusWindow->setText(status);
205                statusWindow->setPosition(CEGUI::UVector2(CEGUI::UDim(0, 0),CEGUI::UDim(0, offset)));
206                statusWindow->setSize(CEGUI::UVector2(CEGUI::UDim(1.0, -QuestGUINode::SCROLLBAR_WIDTH),CEGUI::UDim(1.0, 0)));
207                height = setHeight(statusWindow);
208
209                offset += height;
210            }
211
212            //! Create title pane for the description.
213            stream.str("");
214            stream << this->details_->getName() << "/Description";
215            stream << "/Title";
216            CEGUI::Window* descriptionWindowTitle = this->gui_->getWindowManager()->createWindow("MenuWidgets/StaticText", stream.str());
217            window->addChildWindow(descriptionWindowTitle);
218            descriptionWindowTitle->setProperty("HorzFormatting", "HorzCentred");
219            descriptionWindowTitle->setProperty("VertFormatting", "TopAligned");
220            descriptionWindowTitle->setText("Description:");
221            descriptionWindowTitle->setPosition(CEGUI::UVector2(CEGUI::UDim(0, 0),CEGUI::UDim(0, offset)));
222            descriptionWindowTitle->setSize(CEGUI::UVector2(CEGUI::UDim(1.0, -QuestGUINode::SCROLLBAR_WIDTH),CEGUI::UDim(1.0, 0)));
223
224            offset += setHeight(descriptionWindowTitle);
225
226            //! Display the Description of the QuestItem.
227            stream.str("");
228            stream << this->details_->getName() << "/Description";
229            CEGUI::Window* descriptionWindow = this->gui_->getWindowManager()->createWindow("MenuWidgets/StaticText", stream.str());
230            window->addChildWindow(descriptionWindow);
231            descriptionWindow->setProperty("HorzFormatting", "WordWrapLeftAligned");
232            descriptionWindow->setProperty("VertFormatting", "TopAligned");
233            descriptionWindow->setText(description->getDescription());
234            descriptionWindow->setPosition(CEGUI::UVector2(CEGUI::UDim(0, 0),CEGUI::UDim(0, offset)));
235            descriptionWindow->setSize(CEGUI::UVector2(CEGUI::UDim(1.0, -QuestGUINode::SCROLLBAR_WIDTH),CEGUI::UDim(1.0, 0)));
236            height = setHeight(descriptionWindow);
237
238            offset += height;
239
240            //! Display a list of hints if the QuestItem is a Quest.
241            bool title = true;
242            if(quest != NULL)
243            {
244                for(std::list<QuestGUINode*>::iterator it = this->subNodes_.begin(); it != this->subNodes_.end(); it++)
245                {
246                    if(dynamic_cast<QuestHint*>((*it)->item_) != NULL) //!< If the subNode belongs to a QuestHint.
247                    {
248                        if(title) //!< If no title pane for the QuestHints has been created, create one.
249                        {
250                            stream.str("");
251                            stream << this->details_->getName() << "/Hints/Title";
252                            CEGUI::Window* hintsTitle = this->gui_->getWindowManager()->createWindow("MenuWidgets/StaticText", stream.str());
253                            window->addChildWindow(hintsTitle);
254                            hintsTitle->setProperty("HorzFormatting", "HorzCentred");
255                            hintsTitle->setProperty("VertFormatting", "TopAligned");
256                            hintsTitle->setText("Hints:");
257                            hintsTitle->setPosition(CEGUI::UVector2(CEGUI::UDim(0, 0),CEGUI::UDim(0, offset)));
258                            hintsTitle->setSize(CEGUI::UVector2(CEGUI::UDim(1.0, -QuestGUINode::SCROLLBAR_WIDTH),CEGUI::UDim(1.0, 0)));
259                            offset += setHeight(hintsTitle);;
260                            title = false;
261                        }
262                        QuestGUINode* node = *it;
263                        node->window_->setSize(CEGUI::UVector2(CEGUI::UDim(1.0, -QuestGUINode::SCROLLBAR_WIDTH),CEGUI::UDim(0, QuestGUINode::BUTTON_HEIGHT)));
264                        node->window_->setPosition(CEGUI::UVector2(CEGUI::UDim(0, 0),CEGUI::UDim(0, offset)));
265                        window->addChildWindow(node->window_);
266                        offset += QuestGUINode::BUTTON_HEIGHT;
267                    }
268                }
269            }
270
271            COUT(3) << "Show Details: " << this->details_->getName() << std::endl;
272        }
273
274        return this->details_;
275    }
276
277    /**
278    @brief
279        Opens the details window for the Quest/QuestHint clicked on.
280    */
281    bool QuestGUINode::openDetails(const CEGUI::EventArgs& e)
282    {
283        COUT(3) << "Open QuestItem..." << std::endl;
284
285        //CEGUI::Window* window = this->gui_->getRootWindow();
286        CEGUI::Window* window = this->gui_->getWindowManager()->getWindow("orxonox/QuestGUI/Background");
287
288        if(window != NULL)
289            window->addChildWindow(this->getDetails());
290
291        return true;
292    }
293
294    /**
295    @brief
296        Close the details window.
297    */
298    bool QuestGUINode::closeDetails(const CEGUI::EventArgs& e)
299    {
300        //CEGUI::Window* window = this->gui_->getRootWindow();
301        CEGUI::Window* window = this->gui_->getWindowManager()->getWindow("orxonox/QuestGUI/Background");
302        window->removeChildWindow(this->details_);
303
304        return true;
305    }
306
307    /**
308    @brief
309        Helper method for setHeight(). Gets the StaticTextArea for an input CEGUI Window.
310    @param window
311        The CEGUI window.
312    @return
313        Returns a CEGUI Rect.
314    */
315    /*static*/ CEGUI::Rect QuestGUINode::getStaticTextArea(const CEGUI::Window* window)
316    {
317        const CEGUI::WidgetLookFeel& lookAndFeel = CEGUI::WidgetLookManager::getSingleton().getWidgetLook(window->getLookNFeel());
318
319        return lookAndFeel.getNamedArea("WithFrameTextRenderArea").getArea().getPixelRect(*window);
320    }
321
322    /**
323    @brief
324        Helper method to adjust the height of an input Window (of type StaticText) to the text it holds.
325    @param window
326        The  CEGUI Window (of type StaticText) for which the height is to be adjusted to the text.
327    @return
328        Returns the set height.
329    */
330    /*static*/ int QuestGUINode::setHeight(CEGUI::Window* window)
331    {
332        //! Get the area the text is formatted and drawn into.
333        const CEGUI::Rect formattedArea = getStaticTextArea(window);
334
335        //! Calculate the pixel height of the frame by subtracting the height of the area above from the total height of the window.
336        const float frameHeight = window->getUnclippedPixelRect().getHeight() - formattedArea.getHeight();
337
338        //! Get the formatted line count - using the formatting area obtained above.
339        const float lines = window->getFont()->getFormattedLineCount(window->getText(), formattedArea, CEGUI::WordWrapLeftAligned);
340
341        //! Calculate pixel height of window, which is the number of formatted lines multiplied by the spacing of the font, plus the pixel height of the frame.
342        const float height = lines * window->getFont()->getLineSpacing() + frameHeight;
343
344        //! Set the height to the window.
345        window->setHeight(CEGUI::UDim(0, height));
346
347        //Debug
348        const CEGUI::Rect newArea = getStaticTextArea(window);
349
350        return static_cast<int>(height);
351    }
352
353    /**
354    @brief
355        Update the position list item.
356    */
357    void QuestGUINode::updatePosition(void)
358    {
359        this->window_->setPosition(CEGUI::UVector2(CEGUI::UDim(0, QuestGUINode::INDENT_WIDTH*this->depth_),CEGUI::UDim(0, QuestGUINode::BUTTON_HEIGHT*this->index_)));
360        this->window_->setSize(CEGUI::UVector2(CEGUI::UDim(1, -QuestGUINode::INDENT_WIDTH*this->depth_-QuestGUINode::SCROLLBAR_WIDTH),CEGUI::UDim(0, QuestGUINode::BUTTON_HEIGHT)));
361    }
362
363    /**
364    @brief
365        Helper method to create the CEGUI Window the node.
366    */
367    void QuestGUINode::createWindow(void)
368    {
369        Quest* quest = dynamic_cast<Quest*>(this->item_);
370
371        this->window_ = this->gui_->getWindow();
372        std::ostringstream stream;
373        stream << "QuestGUI/Quests/";
374        if(quest == NULL)
375        {
376            stream << this->parent_->index_ << "/Hints/";
377        }
378        stream << this->index_;
379
380        this->window_->rename(stream.str());
381        this->window_->setText(this->item_->getDescription()->getTitle());
382
383        this->parent_->subNodes_.push_back(this);
384
385        if(dynamic_cast<Quest*>(this->item_) != NULL)
386        {
387            this->gui_->getRootWindow()->addChildWindow(this->window_);
388            this->updatePosition();
389        }
390        else
391        {
392            this->window_->setDestroyedByParent(false);
393        }
394
395        this->window_->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&QuestGUINode::openDetails, this));
396    }
397
398}
399
Note: See TracBrowser for help on using the repository browser.