Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/gui/src/orxonox/gui/GUIManager.cc @ 2840

Last change on this file since 2840 was 2840, checked in by bknecht, 15 years ago

GUIManager now behaves how it should. Most things seem to work fine.

However I guess with the new media all other branches stopped working. Sorry if that's the case.

  • Property svn:eol-style set to native
File size: 14.2 KB
RevLine 
[1638]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 *      Reto Grieder
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/**
30    @file
[1653]31    @brief
32        Implementation of the GUIManager class.
[1638]33*/
34
35#include "OrxonoxStableHeaders.h"
36#include "GUIManager.h"
37
[2710]38#include <boost/filesystem.hpp>
[1638]39#include <OgreRenderWindow.h>
40#include <OgreRoot.h>
41#include <CEGUI.h>
[2710]42#include <CEGUIDefaultLogger.h>
43#include <ogreceguirenderer/OgreCEGUIRenderer.h>
44#include "SpecialConfig.h" // Configures the macro below
45#ifdef CEGUILUA_USE_INTERNAL_LIBRARY
46#   include <ceguilua/CEGUILua.h>
47#else
48#   include <CEGUILua.h>
49#endif
50
[1764]51#include "util/Exception.h"
[1638]52#include "core/input/InputManager.h"
53#include "core/input/SimpleInputState.h"
54#include "core/ConsoleCommand.h"
55#include "core/Core.h"
[2710]56#include "ToluaBindCore.h"
57#include "ToluaBindOrxonox.h"
[1638]58
[2710]59extern "C" {
60#include <lua.h>
61}
[1638]62
63namespace orxonox
64{
[2808]65    SetConsoleCommandShortcut(GUIManager, toggleGUI).keybindMode(KeybindMode::OnPress);
[1638]66
[1646]67    GUIManager* GUIManager::singletonRef_s = 0;
68
[1638]69    GUIManager::GUIManager()
[1640]70        //: emptySceneManager_(0)
71        : backgroundSceneManager_(0)
72        //, emptyCamera_(0)
[1638]73        , backgroundCamera_(0)
[1640]74        //, viewport_(0)
[1638]75        , renderWindow_(0)
76        , guiRenderer_(0)
77        , resourceProvider_(0)
78        , scriptModule_(0)
79        , guiSystem_(0)
80        , state_(Uninitialised)
81    {
[1646]82        assert(singletonRef_s == 0);
83        singletonRef_s = this;
[1638]84    }
85
86    GUIManager::~GUIManager()
87    {
[1646]88        if (backgroundCamera_)
89            backgroundSceneManager_->destroyCamera(backgroundCamera_);
90
91        if (backgroundSceneManager_)
[1661]92        {
93            // We have to make sure the SceneManager is not anymore referenced.
94            // For the case that the target SceneManager was yet another one, it
95            // wouldn't matter anyway since this is the destructor.
96            guiRenderer_->setTargetSceneManager(0);
[1646]97            Ogre::Root::getSingleton().destroySceneManager(backgroundSceneManager_);
[1661]98        }
[1646]99
[1670]100        InputManager::getInstance().requestDestroyState("gui");
[1646]101
102        if (guiSystem_)
103            delete guiSystem_;
104
105        if (scriptModule_)
106        {
107            // destroy our own tolua interfaces
[2662]108                lua_pushnil(luaState_);
109                lua_setglobal(luaState_, "Orxonox");
110                lua_pushnil(luaState_);
111                lua_setglobal(luaState_, "Core");
[2710]112            // TODO: deleting the script module fails an assertion.
[1646]113            // However there is not much we can do about it since it occurs too when
114            // we don't open Core or Orxonox. Might be a CEGUI issue.
115            // The memory leak is not a problem anyway..
[2662]116            delete scriptModule_;
[1646]117        }
118
119        if (guiRenderer_)
120            delete guiRenderer_;
121
122        singletonRef_s = 0;
[1638]123    }
124
[1686]125    bool GUIManager::initialise(Ogre::RenderWindow* renderWindow)
[1638]126    {
127        using namespace CEGUI;
128        if (state_ == Uninitialised)
129        {
[1776]130            COUT(3) << "Initialising CEGUI." << std::endl;
[1638]131
132            try
133            {
[1686]134                // save the render window
135                renderWindow_ = renderWindow;
[1638]136
137                // Full screen viewport with Z order = 0 (top most). Don't yet feed a camera (so nothing gets rendered)
[1640]138                //this->viewport_ = renderWindow_->addViewport(0, 3);
139                //this->viewport_->setOverlaysEnabled(false);
140                //this->viewport_->setShadowsEnabled(false);
141                //this->viewport_->setSkiesEnabled(false);
142                //this->viewport_->setClearEveryFrame(false);
[1638]143
144                // Note: No SceneManager specified yet
[2808]145                this->guiRenderer_ = new OgreCEGUIRenderer(renderWindow_, Ogre::RENDER_QUEUE_OVERLAY, true, 3000);
[1638]146                this->resourceProvider_ = guiRenderer_->createResourceProvider();
147                this->resourceProvider_->setDefaultResourceGroup("GUI");
[1776]148
[1638]149                // setup scripting
150                this->scriptModule_ = new LuaScriptModule();
[1646]151                this->luaState_ = this->scriptModule_->getLuaState();
[1638]152
[2710]153                // Create our own logger to specify the filepath
154                boost::filesystem::path ceguiLogFilepath(Core::getLogPath() / "cegui.log");
155                this->ceguiLogger_ = new DefaultLogger();
[2759]156                this->ceguiLogger_->setLogFilename(ceguiLogFilepath.string());
[2710]157                // set the log level according to ours (translate by subtracting 1)
158                this->ceguiLogger_->setLoggingLevel(
159                    (LoggingLevel)(Core::getSoftDebugLevel(OutputHandler::LD_Logfile) - 1));
160
[1638]161                // create the CEGUI system singleton
162                this->guiSystem_ = new System(this->guiRenderer_, this->resourceProvider_, 0, this->scriptModule_);
[1776]163
[1638]164                // do this after 'new CEGUI::Sytem' because that creates the lua state in the first place
165                tolua_Core_open(this->scriptModule_->getLuaState());
166                tolua_Orxonox_open(this->scriptModule_->getLuaState());
167
168                // register us as input handler
[2814]169                SimpleInputState* state = InputManager::getInstance().createInputState<SimpleInputState>("gui");
[1638]170                state->setHandler(this);
[1878]171                state->setJoyStickHandler(&InputManager::EMPTY_HANDLER);
[1638]172
173                // load the background scene
[2808]174                loadScenes();
[1662]175                //CEGUI::KeyEventArgs e;
176                //e.codepoint
[1638]177            }
178            catch (CEGUI::Exception& ex)
179            {
[1653]180#if CEGUI_VERSION_MAJOR == 0 && CEGUI_VERSION_MINOR < 6
[1645]181                throw GeneralException(ex.getMessage().c_str());
182#else
[1638]183                throw GeneralException(ex.getMessage().c_str(), ex.getLine(),
184                    ex.getFileName().c_str(), ex.getName().c_str());
[1645]185#endif
[1638]186            }
187
188            state_ = Ready;
[2840]189
[1638]190        }
[1776]191
[1638]192        return true;
193    }
194
[2790]195    void GUIManager::loadScene(const std::string& name)
196    {
197        if (name.compare("IngameMenu") == 0)
198        {
199            try
200            {
201                /*this->scriptModule_ = new LuaScriptModule();
202                this->luaState_ = this->scriptModule_->getLuaState();
203                this->guiSystem_ = new System(this->guiRenderer_, this->resourceProvider_, 0, this->scriptModule_);
204                tolua_Core_open(this->scriptModule_->getLuaState());
205                tolua_Orxonox_open(this->scriptModule_->getLuaState());
206                */
[2808]207                this->scriptModule_->executeScriptFile("loadGUI.lua", "GUI");
[2790]208            }
209            catch (CEGUI::Exception& ex)
210            {
211#if CEGUI_VERSION_MINOR < 6
212                throw GeneralException(ex.getMessage().c_str());
213#else
214                throw GeneralException(ex.getMessage().c_str(), ex.getLine(),
215                                       ex.getFileName().c_str(), ex.getName().c_str());
216#endif
217            }
218        }
219        else
220        {
221            loadScenes();
222        }
223    }
224
[1638]225    void GUIManager::loadScenes()
226    {
227        // first of all, we need to have our own SceneManager for the GUI. The reason
228        // is that we might have multiple viewports when in play mode (e.g. the view of
229        // a camera fixed at the back of the ship). That forces us to create our own
230        // full screen viewport that is on top of all the others, but doesn't clear the
231        // port before rendering, so everything from the GUI gets on top eventually.
232        // But in order to realise that, we also need a SceneManager with an empty scene,
233        // because the SceneManager is responsible for the render queue.
[1640]234        //this->emptySceneManager_ = Ogre::Root::getSingleton()
235        //    .createSceneManager(Ogre::ST_GENERIC, "GUI/EmptySceneManager");
[1638]236
237        // we also need a camera or we won't see anything at all.
238        // The camera settings don't matter at all for an empty scene since the GUI
239        // gets rendered on top of the screen rather than into the scene.
[1640]240        //this->emptyCamera_ = this->emptySceneManager_->createCamera("GUI/EmptyCamera");
[1638]241
242        // Create another SceneManager that enables to display some 3D
243        // scene in the background of the main menu.
244        this->backgroundSceneManager_ = Ogre::Root::getSingleton()
245            .createSceneManager(Ogre::ST_GENERIC, "GUI/BackgroundSceneManager");
246        this->backgroundCamera_ = backgroundSceneManager_->createCamera("GUI/BackgroundCamera");
247
248        // TODO: create something 3D
249        try
250        {
251            this->scriptModule_->executeScriptFile("loadGUI.lua", "GUI");
[2840]252            lua_pushfstring(this->scriptModule_->getLuaState(), Core::getMediaPathString().c_str());
253            lua_setglobal(this->scriptModule_->getLuaState(), "datapath");
[1638]254        }
255        catch (CEGUI::Exception& ex)
256        {
[1645]257#if CEGUI_VERSION_MINOR < 6
258            throw GeneralException(ex.getMessage().c_str());
259#else
[1638]260            throw GeneralException(ex.getMessage().c_str(), ex.getLine(),
261                ex.getFileName().c_str(), ex.getName().c_str());
[1645]262#endif
[1638]263        }
264    }
265
[2808]266    void GUIManager::toggleGUI()
267    {
268        //COUT(0) << "********* TOGGLE TOGGLE **********" << std::endl;
[2840]269        if (getInstance().scriptModule_->executeScriptGlobal("toggleGUI"))
270            InputManager::getInstance().requestEnterState("gui");
271        else
272            InputManager::getInstance().requestLeaveState("gui");
[2808]273    }
274
[2834]275    void GUIManager::setCamera(Ogre::Camera* camera)
276    {
[2840]277        this->guiRenderer_->setTargetSceneManager(camera->getSceneManager());
[2834]278    }
279
[1640]280    void GUIManager::showGUI(const std::string& name, Ogre::SceneManager* sceneManager)// bool showBackground)
[1638]281    {
282        if (state_ != Uninitialised)
283        {
284            if (state_ == OnDisplay)
[1661]285                hideGUI();
[1638]286
287            COUT(3) << "Loading GUI " << name << std::endl;
288            try
289            {
[2808]290                // COUT (0) << "************* sceneManager: " << sceneManager << std::endl;
[1640]291                if (!sceneManager)
[1638]292                {
293                    // currently, only an image is loaded. We could do 3D, see loadBackground.
[1640]294                    //this->viewport_->setClearEveryFrame(true);
[1638]295                    this->guiRenderer_->setTargetSceneManager(this->backgroundSceneManager_);
[1640]296                    //this->viewport_->setCamera(this->backgroundCamera_);
[1638]297
298                    lua_pushboolean(this->scriptModule_->getLuaState(), true);
299                    lua_setglobal(this->scriptModule_->getLuaState(), "showBackground");
300                }
301                else
302                {
[1640]303                    //this->viewport_->setClearEveryFrame(false);
304                    this->guiRenderer_->setTargetSceneManager(sceneManager);
[2808]305                    currentSceneManager_ = sceneManager;
[1640]306                    //this->viewport_->setCamera(this->emptyCamera_);
[1638]307
308                    lua_pushboolean(this->scriptModule_->getLuaState(), false);
309                    lua_setglobal(this->scriptModule_->getLuaState(), "showBackground");
310                }
311
[2840]312                lua_pushfstring(this->scriptModule_->getLuaState(), "mainmenu.lua");
313                lua_setglobal(this->scriptModule_->getLuaState(), "filename");
[1638]314
[2840]315                this->scriptModule_->executeScriptGlobal("showGUI");
316
[1642]317                InputManager::getInstance().requestEnterState("gui");
[1638]318
319                this->state_ = OnDisplay;
320            }
321            catch (CEGUI::Exception& ex)
322            {
323                COUT(2) << "Error while executing lua script. Message:\n" << ex.getMessage() << std::endl;
324            }
325            catch (...)
326            {
327                COUT(2) << "Could show a menu due to unknown reasons." << std::endl;
328            }
329        }
330        else
331        {
332            COUT(2) << "Warning: GUI Manager not yet initialised, cannot load a GUI" << std::endl;
333        }
334    }
335
[2840]336    /*void GUIManager::testFct()
[2808]337    {
338        //COUT(0) << "**** " << currentSceneManager_ << std::endl;
339        this->showGUI("IngameMenu", currentSceneManager_);
340    }
341
342    void GUIManager::testOutput(const std::string& str)
343    {
344        COUT(0) << "***" << str << "***" << std::endl;
[2840]345    }*/
[2808]346
[1661]347    void GUIManager::hideGUI()
[1638]348    {
349        if (this->state_ != OnDisplay)
350            return;
[1640]351        //this->viewport_->setCamera(0);
[2790]352        // has no effect since you cannot assign 0 as SceneManager
353        //this->guiRenderer_->setTargetSceneManager(0);
[1638]354        this->state_ = Ready;
[1642]355        InputManager::getInstance().requestLeaveState("gui");
[1638]356    }
357
[1887]358    void GUIManager::mouseButtonPressed(MouseButtonCode::ByEnum id)
[1638]359    {
360        try
361        {
362            guiSystem_->injectMouseButtonDown(convertButton(id));
363        }
364        catch (CEGUI::ScriptException& ex)
365        {
366            // We simply ignore the exception and proceed
367            COUT(1) << ex.getMessage() << std::endl;
368        }
369    }
370
[1887]371    void GUIManager::mouseButtonReleased(MouseButtonCode::ByEnum id)
[1638]372    {
373        try
374        {
375            guiSystem_->injectMouseButtonUp(convertButton(id));
376        }
377        catch (CEGUI::ScriptException& ex)
378        {
379            // We simply ignore the exception and proceed
380            COUT(1) << ex.getMessage() << std::endl;
381        }
382    }
383
384
[1887]385    inline CEGUI::MouseButton GUIManager::convertButton(MouseButtonCode::ByEnum button)
[1638]386    {
387        switch (button)
388        {
[1887]389        case MouseButtonCode::Left:
[1638]390            return CEGUI::LeftButton;
391
[1887]392        case MouseButtonCode::Right:
[1638]393            return CEGUI::RightButton;
394
[1887]395        case MouseButtonCode::Middle:
[1638]396            return CEGUI::MiddleButton;
397
[1887]398        case MouseButtonCode::Button3:
[1638]399            return CEGUI::X1Button;
400
[1887]401        case MouseButtonCode::Button4:
[1638]402            return CEGUI::X2Button;
403
404        default:
405            return CEGUI::NoButton;
406        }
407    }
408}
Note: See TracBrowser for help on using the repository browser.