Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/libraries/core/GUIManager.cc @ 8526

Last change on this file since 8526 was 8467, checked in by rgrieder, 14 years ago

Bugfix for log file paths containing non ASCII characters.
Only works for Western European Codepage 1252 because it's mostly identical to UTF-32 used in CEGUI.

  • Property svn:eol-style set to native
File size: 25.8 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
[2896]24 *      Benjamin Knecht
[1638]25 *   Co-authors:
[3196]26 *      ...
[1638]27 *
28 */
29
30#include "GUIManager.h"
31
[8467]32#include <fstream>
[8351]33#include <memory>
[6746]34#include <boost/bind.hpp>
[8351]35#include <OgreRenderQueue.h>
36#include <OgreRenderWindow.h>
[8079]37
[2710]38#include <CEGUIDefaultLogger.h>
[3196]39#include <CEGUIExceptions.h>
40#include <CEGUIInputEvent.h>
[5695]41#include <CEGUIMouseCursor.h>
[3196]42#include <CEGUIResourceProvider.h>
43#include <CEGUISystem.h>
[6417]44#include <CEGUIWindow.h>
[6746]45#include <CEGUIWindowManager.h>
[7648]46#include <elements/CEGUIListbox.h>
47#include <elements/CEGUIListboxItem.h>
[3196]48
[8351]49#ifdef ORXONOX_OLD_CEGUI
50#  include <CEGUILua.h>
51#  include <ogreceguirenderer/OgreCEGUIRenderer.h>
52extern "C" {
53#  include <lauxlib.h>
54}
[2710]55#else
[8351]56#  include <ScriptingModules/LuaScriptModule/CEGUILua.h>
57#  include <RendererModules/Ogre/CEGUIOgreImageCodec.h>
58#  include <RendererModules/Ogre/CEGUIOgreRenderer.h>
59#  include <RendererModules/Ogre/CEGUIOgreResourceProvider.h>
60#  include <OgreCamera.h>
61#  include <OgreRenderQueueListener.h>
[8439]62#  include <OgreRenderSystem.h>
63#  include <OgreRoot.h>
[8351]64#  include <OgreSceneManager.h>
[2710]65#endif
66
[8467]67#ifdef ORXONOX_PLATFORM_WINDOWS
68#  include <windows.h>
69#endif
70
[5929]71#include "util/Clock.h"
[6417]72#include "util/Convert.h"
[3280]73#include "util/Debug.h"
[1764]74#include "util/Exception.h"
[3280]75#include "util/OrxAssert.h"
[7801]76#include "ConfigValueIncludes.h"
[6417]77#include "Core.h"
[7801]78#include "CoreIncludes.h"
[7876]79#include "Game.h"
[6746]80#include "GraphicsManager.h"
[5695]81#include "LuaState.h"
[5929]82#include "PathConfig.h"
[5695]83#include "Resource.h"
[7284]84#include "command/ConsoleCommand.h"
[6746]85#include "input/InputManager.h"
86#include "input/InputState.h"
87#include "input/KeyBinderManager.h"
[1638]88
89namespace orxonox
90{
[6417]91    static void key_esc()
92        { GUIManager::getInstance().keyESC(); }
[7284]93    SetConsoleCommand("keyESC", &key_esc);
[6417]94
[3280]95    class CEGUILogger : public CEGUI::DefaultLogger
96    {
97    public:
[5929]98        void logEvent(const CEGUI::String& message, CEGUI::LoggingLevel level = CEGUI::Standard)
[3280]99        {
[3327]100            int orxonoxLevel = CEGUI::Standard;
[3280]101            switch (level)
102            {
103                case CEGUI::Errors:      orxonoxLevel = 1; break;
104                case CEGUI::Warnings:    orxonoxLevel = 2; break;
105                case CEGUI::Standard:    orxonoxLevel = 4; break;
106                case CEGUI::Informative: orxonoxLevel = 5; break;
107                case CEGUI::Insane:      orxonoxLevel = 6; break;
[8351]108                default: OrxAssert(false, "CEGUI log level out of range, inspect immediately!");
[3280]109            }
[6105]110            OutputHandler::getOutStream(orxonoxLevel)
[3280]111                << "CEGUI: " << message << std::endl;
112
113            CEGUI::DefaultLogger::logEvent(message, level);
114        }
[8467]115
116        /// Carbon copy from CEGUIDefaultLogger.cpp with a bugfix for Windows
117        void setLogFilename(const CEGUI::String& filename, bool append = false)
118        {
119            // Close current log file (if any)
120            if (d_ostream.is_open())
121                d_ostream.close();
122
123#ifdef ORXONOX_PLATFORM_WINDOWS
124            // filename.c_str() is UTF-8 encoded, but Windows expects characters
125            // according to the current codepage or UTF-16 (wchar)
126            d_ostream.open(utf8ToUtf16(filename.c_str()).c_str(), std::ios_base::out | (append ? std::ios_base::app : std::ios_base::trunc));
127#else
128            d_ostream.open(filename.c_str(), std::ios_base::out | (append ? std::ios_base::app : std::ios_base::trunc));
129#endif
130            if (!d_ostream)
131                ThrowException(General, "Setting the CEGUI log filename failed");
132
133            // Initialise width for date & time alignment.
134            d_ostream.width(2);
135
136            // Write out cached log strings.
137            if (d_caching)
138            {
139                d_caching = false;
140
141                std::vector<std::pair<CEGUI::String, CEGUI::LoggingLevel> >::iterator it = d_cache.begin();
142
143                while (it != d_cache.end())
144                {
145                    if (d_level >= it->second)
146                    {
147                        d_ostream << it->first;
148                        // Ensure new event is written to the file, rather than just being buffered.
149                        d_ostream.flush();
150                    }
151                    ++it;
152                }
153
154                d_cache.clear();
155            }
156        }
157
158#ifdef ORXONOX_PLATFORM_WINDOWS
159        /// Converts a UTF-8 character sequence to Windows UTF-16
160        static std::wstring utf8ToUtf16(const std::string& utf8text)
161        {
162            const int textLen = MultiByteToWideChar(CP_UTF8, 0, utf8text.c_str(),
163                utf8text.size() + 1, 0, 0);
164
165            if (textLen == 0)
166                ThrowException(General, "Utf8ToUtf16 - MultiByteToWideChar failed");
167
168            std::wstring wideStr(textLen, 0);
169            MultiByteToWideChar(CP_UTF8, 0, utf8text.c_str(), utf8text.size() + 1,
170                &wideStr[0], wideStr.size());
171            return wideStr;
172        }
173#endif
[3280]174    };
175
[8351]176#ifdef ORXONOX_OLD_CEGUI
177    /** Class with the same memory layout as CEGUI::LuaScriptModule. <br>
178        We need this to fix a problem with an uninitialised member variable
179        in CEGUI < 0.7 <br>
180        Notice the "public" modifier for the otherwise private variables.
181    */
182    class LuaScriptModuleWorkaround : public CEGUI::ScriptModule
183    {
184    public:
185        LuaScriptModuleWorkaround();
186        ~LuaScriptModuleWorkaround();
187
188    public:
189        bool d_ownsState;
190        lua_State* d_state;
191        CEGUI::String d_errFuncName;
192        int d_errFuncIndex;
193        CEGUI::String d_activeErrFuncName;
194        int d_activeErrFuncIndex;
195    };
196#else
197    /// RenderQueueListener based class used to hook into the ogre rendering system
198    class RQListener : public Ogre::RenderQueueListener
199    {
200    public:
201        /// Callback from Ogre invoked before other stuff in our target queue is rendered
[8419]202        void renderQueueStarted(Ogre::uint8 id, const Ogre::String& invocation, bool& skipThisQueue)
[8351]203        {
[8419]204            if (id == Ogre::RENDER_QUEUE_OVERLAY && invocation.empty())
[8439]205            {
[8351]206                CEGUI::System::getSingleton().renderGUI();
[8439]207
208                // Important workaround! (at least required by CEGUI 0.7.5)
209                // If we don't reset the scissor test, OGRE will only render overlays
210                // in the area where CEGUI last drew, which is usually nothing
211                // or a little box where the focused element is.
212                Ogre::Root::getSingleton().getRenderSystem()->setScissorTest(false);
213            }
[8351]214        }
215    };
216#endif
217
[3196]218    static CEGUI::MouseButton convertButton(MouseButtonCode::ByEnum button);
[3339]219
[3366]220    GUIManager* GUIManager::singletonPtr_s = 0;
[7801]221    /*static*/ const std::string GUIManager::defaultScheme_ = "TaharezGreen";
[1646]222
[7403]223    SetConsoleCommand("showGUI", &GUIManager::showGUI).defaultValue(1, false).defaultValue(2, false);
[7284]224    SetConsoleCommand("hideGUI", &GUIManager::hideGUI);
[8079]225    SetConsoleCommand("toggleGUI", &GUIManager::toggleGUI).defaultValue(1, false).defaultValue(2, false);
[6417]226
[2896]227    /**
228    @brief
[3338]229        Constructs the GUIManager by starting up CEGUI
[2896]230
231        Creates the interface to Ogre, sets up the CEGUI renderer and the Lua script module together with the Lua engine.
232        The log is set up and connected to the CEGUILogger.
233        After Lua setup tolua++-elements are linked to Lua-state to give Lua access to C++-code.
234        Finally initial Lua code is executed (maybe we can do this with the CEGUI startup script automatically).
[3338]235    @return true if success, otherwise false
[2896]236    */
[6746]237    GUIManager::GUIManager(const std::pair<int, int>& mousePosition)
[8423]238        : guiRenderer_(NULL)
[8351]239        , resourceProvider_(NULL)
240#ifndef ORXONOX_OLD_CEGUI
[8411]241        , rqListener_(NULL)
[8351]242        , imageCodec_(NULL)
243#endif
244        , luaState_(NULL)
245        , scriptModule_(NULL)
246        , guiSystem_(NULL)
[8411]247        , ceguiLogger_(NULL)
248        , rootWindow_(NULL)
249        , hudRootWindow_(NULL)
250        , menuRootWindow_(NULL)
[5929]251        , camera_(NULL)
[8423]252        , destructionHelper_(this)
[1638]253    {
[7801]254        RegisterRootObject(GUIManager);
255        this->setConfigValues();
256
[1638]257        using namespace CEGUI;
258
[3338]259        COUT(3) << "Initialising CEGUI." << std::endl;
[1638]260
[5695]261        // Note: No SceneManager specified yet
[8351]262#ifdef ORXONOX_OLD_CEGUI
263        guiRenderer_ = new OgreCEGUIRenderer(GraphicsManager::getInstance().getRenderWindow(), Ogre::RENDER_QUEUE_OVERLAY, false, 3000);
[5695]264        resourceProvider_ = guiRenderer_->createResourceProvider();
[8351]265#else
266        guiRenderer_ = &OgreRenderer::create(*GraphicsManager::getInstance().getRenderWindow());
267        // We use our own RenderQueueListener so we can draw UNDER overlays
268        guiRenderer_->setFrameControlExecutionEnabled(false);
269        rqListener_ = new RQListener();
270        resourceProvider_ = &OgreRenderer::createOgreResourceProvider();
271        imageCodec_ = &OgreRenderer::createOgreImageCodec();
272#endif
[7709]273        resourceProvider_->setDefaultResourceGroup("General");
[1776]274
[6749]275        // Setup scripting
[8351]276        luaState_ = new LuaState();
[6417]277        rootFileInfo_ = Resource::getInfo("InitialiseGUI.lua");
278        // This is necessary to ensure that input events also use the right resource info when triggering lua functions
279        luaState_->setDefaultResourceInfo(this->rootFileInfo_);
[8351]280#ifdef ORXONOX_OLD_CEGUI
281        scriptModule_ = new LuaScriptModule(luaState_->getInternalLuaState());
282        // Ugly workaround: older CEGUILua versions don't initialise the member
283        // d_activeErrFuncIndex at all. That leads to "error in error handling"
284        // problems when a Lua error occurs.
285        // We fix this by setting the member manually.
286        reinterpret_cast<LuaScriptModuleWorkaround*>(scriptModule_)->d_activeErrFuncIndex = LUA_NOREF;
287        luaState_->doString("ORXONOX_OLD_CEGUI = true");
288#else
289        scriptModule_ = &LuaScriptModule::create(luaState_->getInternalLuaState());
290#endif
[6763]291        scriptModule_->setDefaultPCallErrorHandler(LuaState::ERROR_HANDLER_NAME);
[1638]292
[5695]293        // Create our own logger to specify the filepath
294        std::auto_ptr<CEGUILogger> ceguiLogger(new CEGUILogger());
[5929]295        ceguiLogger->setLogFilename(PathConfig::getLogPathString() + "cegui.log");
[8351]296        // Set the log level according to ours (translate by subtracting 1)
[5695]297        ceguiLogger->setLoggingLevel(
[6105]298            static_cast<LoggingLevel>(OutputHandler::getInstance().getSoftDebugLevel("logFile") - 1));
[5695]299        this->ceguiLogger_ = ceguiLogger.release();
[2710]300
[6749]301        // Create the CEGUI system singleton
[8351]302#ifdef ORXONOX_OLD_CEGUI
303        guiSystem_ = new System(guiRenderer_, resourceProvider_, 0, scriptModule_);
304        // Add functions that have been renamed in newer versions
305        luaState_->doString("CEGUI.SchemeManager.create = CEGUI.SchemeManager.loadScheme");
306        luaState_->doString("CEGUI.Window.getUnclippedOuterRect = CEGUI.Window.getUnclippedPixelRect");
307#else
308        guiSystem_ = &System::create(*guiRenderer_, resourceProvider_, 0, imageCodec_, scriptModule_);
309#endif
[1776]310
[5695]311        // Align CEGUI mouse with OIS mouse
[6502]312        guiSystem_->injectMousePosition((float)mousePosition.first, (float)mousePosition.second);
[5695]313
[6746]314        // Initialise the Lua framework and load the schemes
315        this->luaState_->doFile("InitialiseGUI.lua");
316
317        // Create the root nodes
318        this->rootWindow_ = CEGUI::WindowManager::getSingleton().createWindow("MenuWidgets/StaticImage", "AbsoluteRootWindow");
319        this->rootWindow_->setProperty("FrameEnabled", "False");
320        this->hudRootWindow_ = CEGUI::WindowManager::getSingleton().createWindow("DefaultWindow", "HUDRootWindow");
321        this->menuRootWindow_ = CEGUI::WindowManager::getSingleton().createWindow("DefaultWindow", "MenuRootWindow");
322        // And connect them
323        CEGUI::System::getSingleton().setGUISheet(this->rootWindow_);
324        this->rootWindow_->addChildWindow(this->hudRootWindow_);
325        this->rootWindow_->addChildWindow(this->menuRootWindow_);
326
[6749]327        // No background to start with (sets the alpha value to 0)
328        this->setBackgroundImage("");
329
[6746]330        // Set up the sheet manager in the Lua framework
331        this->luaState_->doFile("SheetManager.lua");
[3338]332    }
[1776]333
[8423]334    void GUIManager::destroy()
[3338]335    {
[8351]336        using namespace CEGUI;
337
338#ifdef ORXONOX_OLD_CEGUI
[8423]339        safeObjectDelete(&guiSystem_);
340        safeObjectDelete(&guiRenderer_);
341        safeObjectDelete(&scriptModule_);
[8351]342#else
343        System::destroy();
344        OgreRenderer::destroyOgreResourceProvider(*resourceProvider_);
345        OgreRenderer::destroyOgreImageCodec(*imageCodec_);
346        OgreRenderer::destroy(*guiRenderer_);
347        LuaScriptModule::destroy(*scriptModule_);
[8423]348        safeObjectDelete(&ceguiLogger_);
349        safeObjectDelete(&rqListener_);
[8351]350#endif
[8423]351        safeObjectDelete(&luaState_);
[1638]352    }
353
[7801]354    void GUIManager::setConfigValues(void)
355    {
356        SetConfigValue(guiScheme_, GUIManager::defaultScheme_) .description("Changes the current GUI scheme.") .callback(this, &GUIManager::changedGUIScheme);
357    }
358
359    void GUIManager::changedGUIScheme(void)
360    {
361    }
362
[2896]363    /**
364    @brief
365        used to tick the GUI
366    @param time
367        clock which provides time value for the GUI System
368
369        Ticking the GUI means updating it with a certain regularity.
370        The elapsed time since the last call is given in the time value provided by the clock.
371        This time value is then used to provide a fluent animation of the GUI.
372    */
[6417]373    void GUIManager::preUpdate(const Clock& time)
[1638]374    {
[2896]375        assert(guiSystem_);
[6746]376        this->protectedCall(boost::bind(&CEGUI::System::injectTimePulse, _1, time.getDeltaTime()));
[2896]377    }
[1638]378
[2896]379    /**
380    @brief
381        Tells the GUIManager which SceneManager to use
382    @param camera
383        The current camera on which the GUI should be displayed on.
384
385        In fact the GUIManager needs the SceneManager and not the Camera to display the GUI.
386        This means the GUI is not bound to a camera but rather to the SceneManager.
[3337]387        Hiding the GUI when needed can therefore not be resolved by just NOT setting the current camera.
[2896]388    */
389    void GUIManager::setCamera(Ogre::Camera* camera)
[1638]390    {
[8351]391#ifdef ORXONOX_OLD_CEGUI
[2927]392        if (camera == NULL)
393            this->guiRenderer_->setTargetSceneManager(0);
394        else
395            this->guiRenderer_->setTargetSceneManager(camera->getSceneManager());
[8351]396#else
397        if (camera_ != NULL && camera_->getSceneManager() != NULL)
398            camera_->getSceneManager()->removeRenderQueueListener(rqListener_);
399        if (camera != NULL && camera->getSceneManager() != NULL)
400            camera->getSceneManager()->addRenderQueueListener(rqListener_);
401#endif
402        this->camera_ = camera;
[2896]403    }
404
405    /**
406    @brief
[3338]407        Executes Lua code
408    @param str
409        reference to string object holding the Lua code which is to be executed
410    */
411    void GUIManager::executeCode(const std::string& str)
412    {
[5695]413        this->luaState_->doString(str, rootFileInfo_);
[3338]414    }
415
[6746]416    /** Loads a GUI sheet by Lua script
417    @param name
418        The name of the GUI (like the script name, but without the extension)
419    */
420    void GUIManager::loadGUI(const std::string& name)
421    {
422        this->executeCode("loadSheet(\"" + name + "\")");
423    }
424
[3338]425    /**
426    @brief
[2896]427        Displays specified GUI on screen
428    @param name
429        The name of the GUI
[7401]430    @param bHidePrevious
431        If true all displayed GUIs on the stack, that are below this GUI are hidden.
[7403]432    @param bNoInput
433        If true the GUI is transparent to input.
[2896]434
435        The function executes the Lua function with the same name in case the GUIManager is ready.
436    */
[7403]437    /*static*/ void GUIManager::showGUI(const std::string& name, bool bHidePrevious, bool bNoInput)
[2896]438    {
[7403]439        GUIManager::getInstance().executeCode("showMenuSheet(\"" + name + "\", " + multi_cast<std::string>(bHidePrevious) + ", " + multi_cast<std::string>(bNoInput) + ")");
[1638]440    }
441
[6417]442    /**
443    @brief
444        Hack-ish. Needed for GUIOverlay.
445    */
[7403]446    void GUIManager::showGUIExtra(const std::string& name, const std::string& ptr, bool bHidePrevious, bool bNoInput)
[6417]447    {
[7403]448        this->executeCode("showMenuSheet(\"" + name + "\", " + multi_cast<std::string>(bHidePrevious) + ", " + multi_cast<std::string>(bNoInput) + ", " + ptr + ")");
[6417]449    }
450
451    /**
452    @brief
453        Hides specified GUI.
454    @param name
455        The name of the GUI.
456    */
457    /*static*/ void GUIManager::hideGUI(const std::string& name)
458    {
[6746]459        GUIManager::getInstance().executeCode("hideMenuSheet(\"" + name + "\")");
[6417]460    }
461
[8079]462    /**
463    @brief
464        Toggles specified GUI.
465        If the GUI with the input name is already shown and on the top, it is hidden, else it is shown.
466    */
467    /*static*/ void GUIManager::toggleGUI(const std::string& name, bool bHidePrevious, bool bNoInput)
468    {
469        GUIManager::getInstance().executeCode("getGUIFirstActive(\"" + name + "\", " + multi_cast<std::string>(bHidePrevious) + ", " + multi_cast<std::string>(bNoInput) + ")");
470    }
471
472    /**
473    @brief
474        Helper method to toggle a specified GUI.
475        Is called by lua.
476    */
477    void GUIManager::toggleGUIHelper(const std::string& name, bool bHidePrevious, bool bNoInput, bool show)
478    {
479        if(show)
480            GUIManager::showGUI(name, bHidePrevious, bNoInput);
481        else
482            GUIManager::hideGUI(name);
483    }
484
[6746]485    const std::string& GUIManager::createInputState(const std::string& name, TriBool::Value showCursor, TriBool::Value useKeyboard, bool bBlockJoyStick)
486    {
487        InputState* state = InputManager::getInstance().createInputState(name);
[7811]488        if (!state)
489            return BLANKSTRING;
[6746]490
491        /* Table that maps isFullScreen() and showCursor to mouseExclusive
492        isFullscreen / showCursor | True  | False | Dontcare
493        ----------------------------------------------------
494        true                      | True  | True  | Dontcare
495        ----------------------------------------------------
496        false                     | False | True  | Dontcare
497        */
[8351]498
499#ifdef ORXONOX_PLATFORM_APPLE
500        // There is no non exclusive mode on OS X yet
501        state->setMouseExclusive(TriBool::True);
502#else
[6746]503        if (showCursor == TriBool::Dontcare)
504            state->setMouseExclusive(TriBool::Dontcare);
505        else if (GraphicsManager::getInstance().isFullScreen() || showCursor == TriBool::False)
506            state->setMouseExclusive(TriBool::True);
507        else
508            state->setMouseExclusive(TriBool::False);
[8351]509#endif
[6746]510
511        if (showCursor == TriBool::True)
512            state->setMouseHandler(this);
513        else if (showCursor == TriBool::False)
514            state->setMouseHandler(&InputHandler::EMPTY);
515
516        if (useKeyboard == TriBool::True)
517            state->setKeyHandler(this);
518        else if (useKeyboard == TriBool::False)
519            state->setKeyHandler(&InputHandler::EMPTY);
520
521        if (bBlockJoyStick)
522            state->setJoyStickHandler(&InputHandler::EMPTY);
523
524        return state->getName();
525    }
526
[6417]527    void GUIManager::keyESC()
528    {
529        this->executeCode("keyESC()");
530    }
531
[6746]532    void GUIManager::setBackgroundImage(const std::string& imageSet, const std::string imageName)
[6417]533    {
[6746]534        if (imageSet.empty() || imageName.empty())
535            this->setBackgroundImage("");
536        else
537            this->setBackgroundImage("set: " + imageSet + " image: " + imageName);
[6417]538    }
539
[6746]540    void GUIManager::setBackgroundImage(const std::string& image)
541    {
542        if (image.empty())
543            this->rootWindow_->setProperty("Alpha", "0.0");
544        else
545            this->rootWindow_->setProperty("Alpha", "1.0");
546        this->rootWindow_->setProperty("Image", image);
547    }
548
[7163]549    void GUIManager::buttonPressed(const KeyEvent& evt)
[3196]550    {
[6746]551        this->protectedCall(boost::bind(&CEGUI::System::injectKeyDown, _1, evt.getKeyCode()));
552        this->protectedCall(boost::bind(&CEGUI::System::injectChar, _1, evt.getText()));
[3196]553    }
[6746]554
[7163]555    void GUIManager::buttonReleased(const KeyEvent& evt)
[3196]556    {
[6746]557        this->protectedCall(boost::bind(&CEGUI::System::injectKeyUp, _1, evt.getKeyCode()));
[3196]558    }
559
[2896]560    /**
561    @brief
562        Function receiving a mouse button pressed event.
563    @param id
564        ID of the mouse button which got pressed
[1638]565
[2896]566        This function is inherited by MouseHandler and injects the event into CEGUI.
567        It is for CEGUI to process the event.
568    */
[3327]569    void GUIManager::buttonPressed(MouseButtonCode::ByEnum id)
[1638]570    {
[6746]571        this->protectedCall(boost::bind(&CEGUI::System::injectMouseButtonDown, _1, convertButton(id)));
[1638]572    }
573
[2896]574    /**
575    @brief
576        Function receiving a mouse button released event.
577    @param id
578        ID of the mouse button which got released
579
580        This function is inherited by MouseHandler and injects the event into CEGUI.
581        It is for CEGUI to process the event.
582    */
[3327]583    void GUIManager::buttonReleased(MouseButtonCode::ByEnum id)
[1638]584    {
[6746]585        this->protectedCall(boost::bind(&CEGUI::System::injectMouseButtonUp, _1, convertButton(id)));
[1638]586    }
587
[3196]588    void GUIManager::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize)
589    {
[6746]590        this->protectedCall(boost::bind(&CEGUI::System::injectMousePosition, _1, (float)abs.x, (float)abs.y));
[3196]591    }
[6746]592
[3196]593    void GUIManager::mouseScrolled(int abs, int rel)
594    {
[6746]595        this->protectedCall(boost::bind(&CEGUI::System::injectMouseWheelChange, _1, (float)rel));
[3196]596    }
597
[2896]598    /**
[7874]599        @brief Indicates that the mouse left the application's window.
600    */
601    void GUIManager::mouseLeft()
602    {
603        this->protectedCall(boost::bind(&CEGUI::System::injectMouseLeaves, _1));
604    }
605
606    /**
[2896]607    @brief
608        converts mouse event code to CEGUI event code
609    @param button
610        code of the mouse button as we use it in Orxonox
611    @return
612        code of the mouse button as it is used by CEGUI
[1638]613
[6105]614        Simple conversion from mouse event code in Orxonox to the one used in CEGUI.
[2896]615     */
[3196]616    static inline CEGUI::MouseButton convertButton(MouseButtonCode::ByEnum button)
[1638]617    {
618        switch (button)
619        {
[1887]620        case MouseButtonCode::Left:
[1638]621            return CEGUI::LeftButton;
622
[1887]623        case MouseButtonCode::Right:
[1638]624            return CEGUI::RightButton;
625
[1887]626        case MouseButtonCode::Middle:
[1638]627            return CEGUI::MiddleButton;
628
[1887]629        case MouseButtonCode::Button3:
[1638]630            return CEGUI::X1Button;
631
[1887]632        case MouseButtonCode::Button4:
[1638]633            return CEGUI::X2Button;
634
635        default:
636            return CEGUI::NoButton;
637        }
638    }
[6417]639
[6746]640    /** Executes a CEGUI function normally, but catches CEGUI::ScriptException.
641        When a ScriptException occurs, the error message will be displayed and
642        the program carries on.
643    @remarks
644        The exception behaviour may pose problems if the code is not written
645        exception-safe (and you can forget about that in Lua). The program might
646        be left in an undefined state. But otherwise one script error would
647        terminate the whole program...
648    @note
649        Your life gets easier if you use boost::bind to create the object/function.
650    @param function
651        Any callable object/function that takes this->guiSystem_ as its only parameter.
652    @return
653        True if input was handled, false otherwise. A caught exception yields true.
654    */
655    template <typename FunctionType>
656    bool GUIManager::protectedCall(FunctionType function)
657    {
658        try
659        {
660            return function(this->guiSystem_);
661        }
662        catch (CEGUI::ScriptException& ex)
663        {
664            // Display the error and proceed. See @remarks why this can be dangerous.
665            COUT(1) << ex.getMessage() << std::endl;
666            return true;
667        }
668    }
669
[7648]670    /**
671    @brief
672        Subscribe the input function to the input event for the input window.
673        This is a helper to be used in lua, because subscribeScriptedEvent() doesn't work in lua.
674    @param window
675        The window for which the event is subscribed.
676    @param event
677        The type of event to which we subscribe.
678    @param function
679        The function that is called when the event occurs.
680    */
[6417]681    void GUIManager::subscribeEventHelper(CEGUI::Window* window, const std::string& event, const std::string& function)
682    {
683        window->subscribeScriptedEvent(event, function);
684    }
[7648]685
686    /**
687    @brief
688        Set the input tooltip text for the input ListboxItem.
689    @param item
690        The ListboxItem for which the tooltip should be set.
691    @param tooltip
692        The tooltip text that should be set.
693    */
694    void GUIManager::setTooltipTextHelper(CEGUI::ListboxItem* item, const std::string& tooltip)
695    {
696        item->setTooltipText(tooltip);
697    }
698
699    /**
700    @brief
701        Set whether the tooltips for the input Listbox are enabled.
702    @param listbox
703        The Listbox for which to enable (or disable) tooltips.
704    @param enabled
[8351]705        Whether to enable or disable the tooltips.
[7648]706    */
707    void GUIManager::setItemTooltipsEnabledHelper(CEGUI::Listbox* listbox, bool enabled)
708    {
709        listbox->setItemTooltipsEnabled(enabled);
710    }
711
[7873]712    /**
713        @brief Callback of window event listener, called if the window is resized. Sets the display size of CEGUI.
714    */
715    void GUIManager::windowResized(unsigned int newWidth, unsigned int newHeight)
716    {
[8079]717        this->guiRenderer_->setDisplaySize(CEGUI::Size((float)newWidth, (float)newHeight));
[7873]718    }
[7874]719
720    /**
[8079]721        @brief Notify CEGUI if the windows loses the focus (stops highlighting of menu items, etc).
[7874]722    */
723    void GUIManager::windowFocusChanged(bool bFocus)
724    {
725        if (!bFocus)
726            this->mouseLeft();
727    }
[7876]728
[1638]729}
Note: See TracBrowser for help on using the repository browser.