Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/modules/questsystem/QuestGUINode.cc @ 5746

Last change on this file since 5746 was 5746, checked in by dafrick, 15 years ago

Forgot to add files…

File size: 13.0 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 "core/CoreIncludes.h"
34#include "infos/PlayerInfo.h"
35#include "Quest.h"
36#include "QuestHint.h"
37#include "QuestItem.h"
38#include "QuestDescription.h"
39#include "QuestGUI.h"
40
41#include <CEGUIWindow.h>
42#include <CEGUIWindowManager.h>
43#include <CEGUIFont.h>
44#include <CEGUI.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    int 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 = (std::string)(this->window_->getName().c_str());
137        }
138        else
139        {
140            buffer = "";
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_ = CEGUI::WindowManager::getSingleton().createWindow("TaharezLook/FrameWindow", stream.str());
163            this->details_->setSize(CEGUI::UVector2(CEGUI::UDim(0.8, 0),CEGUI::UDim(0.8, 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 = CEGUI::WindowManager::getSingleton().createWindow("TaharezLook/ScrollablePane", stream.str());
174            window->setSize(CEGUI::UVector2(CEGUI::UDim(1.0, -10),CEGUI::UDim(1.0, -26)));
175            window->setPosition(CEGUI::UVector2(CEGUI::UDim(0, 5),CEGUI::UDim(0, 26)));
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 = CEGUI::WindowManager::getSingleton().createWindow("TaharezLook/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, -13),CEGUI::UDim(1.0, 0)));
207                height = setHeight(statusWindow);
208
209                offset += height;
210            }
211
212            //! Display the Description of the QuestItem.
213            stream.str("");
214            stream << this->details_->getName() << "/Description";
215            CEGUI::Window* descriptionWindow = CEGUI::WindowManager::getSingleton().createWindow("TaharezLook/StaticText", stream.str());
216            window->addChildWindow(descriptionWindow);
217            descriptionWindow->setProperty("HorzFormatting", "WordWrapLeftAligned");
218            descriptionWindow->setProperty("VertFormatting", "TopAligned");
219            descriptionWindow->setText(description->getDescription());
220            descriptionWindow->setPosition(CEGUI::UVector2(CEGUI::UDim(0, 0),CEGUI::UDim(0, offset)));
221            descriptionWindow->setSize(CEGUI::UVector2(CEGUI::UDim(1.0, -13),CEGUI::UDim(1.0, 0)));
222            height = setHeight(descriptionWindow);
223
224            offset += height;
225
226            //! Display a list of hints if the QuestItem is a Quest.
227            if(quest != NULL)
228            {
229                for(std::list<QuestGUINode*>::iterator it = this->subNodes_.begin(); it != this->subNodes_.end(); it++)
230                {
231                    if(dynamic_cast<QuestHint*>((*it)->item_) != NULL) //!< If the subNode belongs to a QuestHint.
232                    {
233                        QuestGUINode* node = *it;
234                        node->window_->setSize(CEGUI::UVector2(CEGUI::UDim(1.0, -13),CEGUI::UDim(0, 30)));
235                        node->window_->setPosition(CEGUI::UVector2(CEGUI::UDim(0, 0),CEGUI::UDim(0, offset)));
236                        node->window_->setProperty("HorizontalAlignment", "Left"); // TDO: Get this working.
237                        window->addChildWindow(node->window_);
238                        offset += 30;
239                    }
240                }
241            }
242
243            COUT(3) << "Show Details: " << this->details_->getName() << std::endl;
244        }
245
246        return this->details_;
247    }
248
249    /**
250    @brief
251        Opens the details window for the Quest/QuestHint clicked on.
252    */
253    bool QuestGUINode::openDetails(const CEGUI::EventArgs& e)
254    {
255        COUT(3) << "Open QuestItem..." << std::endl;
256       
257        CEGUI::Window* window = this->gui_->getRootWindow();
258
259        if(window != NULL)
260            window->addChildWindow(this->getDetails());
261
262        return true;
263    }
264
265    /**
266    @brief
267        Close the details window.
268    */
269    bool QuestGUINode::closeDetails(const CEGUI::EventArgs& e)
270    {       
271        CEGUI::Window* questsList = this->gui_->getRootWindow();
272        questsList->removeChildWindow(this->details_);
273
274        return true;
275    }
276
277    /*static*/ CEGUI::Rect QuestGUINode::getStaticTextArea(const CEGUI::Window* window)
278    {
279        const CEGUI::WidgetLookFeel& lookAndFeel = CEGUI::WidgetLookManager::getSingleton().getWidgetLook(window->getLookNFeel());
280
281        return lookAndFeel.getNamedArea("WithFrameTextRenderArea").getArea().getPixelRect(*window);
282    }
283
284    /*static*/ int QuestGUINode::setHeight(CEGUI::Window* window)
285    {
286        //! Get the area the text is formatted and drawn into.
287        const CEGUI::Rect formattedArea = getStaticTextArea(window);
288        COUT(1) << "PixelRect before setHeight(): " << formattedArea.getHeight() << "x" << formattedArea.getWidth() << std::endl; //Debug
289
290        //! Calculate the pixel height of the frame by subtracting the height of the area above from the total height of the window.
291        const float frameHeight = window->getUnclippedPixelRect().getHeight() - formattedArea.getHeight();
292
293        //! Get the formatted line count - using the formatting area obtained above.
294        const float lines = window->getFont()->getFormattedLineCount(window->getText(), formattedArea, CEGUI::WordWrapLeftAligned);
295        COUT(1) << "Lines: " << lines << std::endl; //Debug
296
297        //! 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.
298        const float height = lines * window->getFont()->getLineSpacing() + frameHeight;
299
300        //! Set the height to the window.
301        window->setHeight(CEGUI::UDim(0, height));
302       
303        //Debug
304        const CEGUI::Rect newArea = getStaticTextArea(window);
305        COUT(1) << "PixelRect after setHeight(): " << newArea.getHeight() << "x" << newArea.getWidth() << std::endl; //Debug
306
307        return static_cast<int>(height);
308    }
309
310    //int QuestGUINode::setHeight(CEGUI::Window* window)
311    //{
312    //    COUT(1) << "PixelRect before setHeight(): " << window->getPixelRect().getHeight() << "x" << window->getPixelRect().getWidth() << std::endl; //Debug
313    //    int lines = window->getFont()->getFormattedLineCount(window->getText(), window->getPixelRect(), CEGUI::WordWrapLeftAligned);
314    //    int height = 2*lines*window->getFont()->getLineSpacing();
315    //    COUT(1) << "Lines: " << lines << ", LineSpacing: " << window->getFont()->getLineSpacing() << std::endl; //Debug
316    //    window->setHeight(CEGUI::UDim(0, height));
317    //    COUT(1) << "PixelRect after setHeight(): " << window->getPixelRect().getHeight() << "x" << window->getPixelRect().getWidth() << std::endl; //Debug
318    //    return height;
319    //}
320
321    /**
322    @brief
323        Update the position list item.
324    */
325    void QuestGUINode::updatePosition(void)
326    {
327        this->window_->setPosition(CEGUI::UVector2(CEGUI::UDim(0, 20*this->depth_),CEGUI::UDim(0, 30*this->index_)));
328        this->window_->setSize(CEGUI::UVector2(CEGUI::UDim(1, -20*this->depth_-13),CEGUI::UDim(0, 30)));
329    }
330
331    /**
332    @brief
333        Helper method to create the CEGUI Window the node.
334    */
335    void QuestGUINode::createWindow(void)
336    {
337        Quest* quest = dynamic_cast<Quest*>(this->item_);
338       
339        this->window_ = this->gui_->getWindow();
340        std::ostringstream stream;
341        stream << "QuestGUI/Quests/";
342        if(quest == NULL)
343        {
344            stream << this->parent_->index_ << "/Hints/";
345        }
346        stream << this->index_;
347       
348        this->window_->rename(stream.str());
349        this->window_->setText(this->item_->getDescription()->getTitle());
350
351        this->parent_->subNodes_.push_back(this);
352
353        if(dynamic_cast<Quest*>(this->item_) != NULL)
354        {
355            this->gui_->getRootWindow()->addChildWindow(this->window_);
356            this->updatePosition();
357        }
358        else
359        {
360            this->window_->setDestroyedByParent(false);
361        }
362
363        this->window_->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&QuestGUINode::openDetails, this));
364    }
365
366}
367
Note: See TracBrowser for help on using the repository browser.