Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 8491 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
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 *      Reto Grieder
24 *      Benjamin Knecht
25 *   Co-authors:
26 *      ...
27 *
28 */
29
30#include "GUIManager.h"
31
32#include <fstream>
33#include <memory>
34#include <boost/bind.hpp>
35#include <OgreRenderQueue.h>
36#include <OgreRenderWindow.h>
37
38#include <CEGUIDefaultLogger.h>
39#include <CEGUIExceptions.h>
40#include <CEGUIInputEvent.h>
41#include <CEGUIMouseCursor.h>
42#include <CEGUIResourceProvider.h>
43#include <CEGUISystem.h>
44#include <CEGUIWindow.h>
45#include <CEGUIWindowManager.h>
46#include <elements/CEGUIListbox.h>
47#include <elements/CEGUIListboxItem.h>
48
49#ifdef ORXONOX_OLD_CEGUI
50#  include <CEGUILua.h>
51#  include <ogreceguirenderer/OgreCEGUIRenderer.h>
52extern "C" {
53#  include <lauxlib.h>
54}
55#else
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>
62#  include <OgreRenderSystem.h>
63#  include <OgreRoot.h>
64#  include <OgreSceneManager.h>
65#endif
66
67#ifdef ORXONOX_PLATFORM_WINDOWS
68#  include <windows.h>
69#endif
70
71#include "util/Clock.h"
72#include "util/Convert.h"
73#include "util/Debug.h"
74#include "util/Exception.h"
75#include "util/OrxAssert.h"
76#include "ConfigValueIncludes.h"
77#include "Core.h"
78#include "CoreIncludes.h"
79#include "Game.h"
80#include "GraphicsManager.h"
81#include "LuaState.h"
82#include "PathConfig.h"
83#include "Resource.h"
84#include "command/ConsoleCommand.h"
85#include "input/InputManager.h"
86#include "input/InputState.h"
87#include "input/KeyBinderManager.h"
88
89namespace orxonox
90{
91    static void key_esc()
92        { GUIManager::getInstance().keyESC(); }
93    SetConsoleCommand("keyESC", &key_esc);
94
95    class CEGUILogger : public CEGUI::DefaultLogger
96    {
97    public:
98        void logEvent(const CEGUI::String& message, CEGUI::LoggingLevel level = CEGUI::Standard)
99        {
100            int orxonoxLevel = CEGUI::Standard;
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;
108                default: OrxAssert(false, "CEGUI log level out of range, inspect immediately!");
109            }
110            OutputHandler::getOutStream(orxonoxLevel)
111                << "CEGUI: " << message << std::endl;
112
113            CEGUI::DefaultLogger::logEvent(message, level);
114        }
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
174    };
175
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
202        void renderQueueStarted(Ogre::uint8 id, const Ogre::String& invocation, bool& skipThisQueue)
203        {
204            if (id == Ogre::RENDER_QUEUE_OVERLAY && invocation.empty())
205            {
206                CEGUI::System::getSingleton().renderGUI();
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            }
214        }
215    };
216#endif
217
218    static CEGUI::MouseButton convertButton(MouseButtonCode::ByEnum button);
219
220    GUIManager* GUIManager::singletonPtr_s = 0;
221    /*static*/ const std::string GUIManager::defaultScheme_ = "TaharezGreen";
222
223    SetConsoleCommand("showGUI", &GUIManager::showGUI).defaultValue(1, false).defaultValue(2, false);
224    SetConsoleCommand("hideGUI", &GUIManager::hideGUI);
225    SetConsoleCommand("toggleGUI", &GUIManager::toggleGUI).defaultValue(1, false).defaultValue(2, false);
226
227    /**
228    @brief
229        Constructs the GUIManager by starting up CEGUI
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).
235    @return true if success, otherwise false
236    */
237    GUIManager::GUIManager(const std::pair<int, int>& mousePosition)
238        : guiRenderer_(NULL)
239        , resourceProvider_(NULL)
240#ifndef ORXONOX_OLD_CEGUI
241        , rqListener_(NULL)
242        , imageCodec_(NULL)
243#endif
244        , luaState_(NULL)
245        , scriptModule_(NULL)
246        , guiSystem_(NULL)
247        , ceguiLogger_(NULL)
248        , rootWindow_(NULL)
249        , hudRootWindow_(NULL)
250        , menuRootWindow_(NULL)
251        , camera_(NULL)
252        , destructionHelper_(this)
253    {
254        RegisterRootObject(GUIManager);
255        this->setConfigValues();
256
257        using namespace CEGUI;
258
259        COUT(3) << "Initialising CEGUI." << std::endl;
260
261        // Note: No SceneManager specified yet
262#ifdef ORXONOX_OLD_CEGUI
263        guiRenderer_ = new OgreCEGUIRenderer(GraphicsManager::getInstance().getRenderWindow(), Ogre::RENDER_QUEUE_OVERLAY, false, 3000);
264        resourceProvider_ = guiRenderer_->createResourceProvider();
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
273        resourceProvider_->setDefaultResourceGroup("General");
274
275        // Setup scripting
276        luaState_ = new LuaState();
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_);
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
291        scriptModule_->setDefaultPCallErrorHandler(LuaState::ERROR_HANDLER_NAME);
292
293        // Create our own logger to specify the filepath
294        std::auto_ptr<CEGUILogger> ceguiLogger(new CEGUILogger());
295        ceguiLogger->setLogFilename(PathConfig::getLogPathString() + "cegui.log");
296        // Set the log level according to ours (translate by subtracting 1)
297        ceguiLogger->setLoggingLevel(
298            static_cast<LoggingLevel>(OutputHandler::getInstance().getSoftDebugLevel("logFile") - 1));
299        this->ceguiLogger_ = ceguiLogger.release();
300
301        // Create the CEGUI system singleton
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
310
311        // Align CEGUI mouse with OIS mouse
312        guiSystem_->injectMousePosition((float)mousePosition.first, (float)mousePosition.second);
313
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
327        // No background to start with (sets the alpha value to 0)
328        this->setBackgroundImage("");
329
330        // Set up the sheet manager in the Lua framework
331        this->luaState_->doFile("SheetManager.lua");
332    }
333
334    void GUIManager::destroy()
335    {
336        using namespace CEGUI;
337
338#ifdef ORXONOX_OLD_CEGUI
339        safeObjectDelete(&guiSystem_);
340        safeObjectDelete(&guiRenderer_);
341        safeObjectDelete(&scriptModule_);
342#else
343        System::destroy();
344        OgreRenderer::destroyOgreResourceProvider(*resourceProvider_);
345        OgreRenderer::destroyOgreImageCodec(*imageCodec_);
346        OgreRenderer::destroy(*guiRenderer_);
347        LuaScriptModule::destroy(*scriptModule_);
348        safeObjectDelete(&ceguiLogger_);
349        safeObjectDelete(&rqListener_);
350#endif
351        safeObjectDelete(&luaState_);
352    }
353
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
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    */
373    void GUIManager::preUpdate(const Clock& time)
374    {
375        assert(guiSystem_);
376        this->protectedCall(boost::bind(&CEGUI::System::injectTimePulse, _1, time.getDeltaTime()));
377    }
378
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.
387        Hiding the GUI when needed can therefore not be resolved by just NOT setting the current camera.
388    */
389    void GUIManager::setCamera(Ogre::Camera* camera)
390    {
391#ifdef ORXONOX_OLD_CEGUI
392        if (camera == NULL)
393            this->guiRenderer_->setTargetSceneManager(0);
394        else
395            this->guiRenderer_->setTargetSceneManager(camera->getSceneManager());
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;
403    }
404
405    /**
406    @brief
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    {
413        this->luaState_->doString(str, rootFileInfo_);
414    }
415
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
425    /**
426    @brief
427        Displays specified GUI on screen
428    @param name
429        The name of the GUI
430    @param bHidePrevious
431        If true all displayed GUIs on the stack, that are below this GUI are hidden.
432    @param bNoInput
433        If true the GUI is transparent to input.
434
435        The function executes the Lua function with the same name in case the GUIManager is ready.
436    */
437    /*static*/ void GUIManager::showGUI(const std::string& name, bool bHidePrevious, bool bNoInput)
438    {
439        GUIManager::getInstance().executeCode("showMenuSheet(\"" + name + "\", " + multi_cast<std::string>(bHidePrevious) + ", " + multi_cast<std::string>(bNoInput) + ")");
440    }
441
442    /**
443    @brief
444        Hack-ish. Needed for GUIOverlay.
445    */
446    void GUIManager::showGUIExtra(const std::string& name, const std::string& ptr, bool bHidePrevious, bool bNoInput)
447    {
448        this->executeCode("showMenuSheet(\"" + name + "\", " + multi_cast<std::string>(bHidePrevious) + ", " + multi_cast<std::string>(bNoInput) + ", " + ptr + ")");
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    {
459        GUIManager::getInstance().executeCode("hideMenuSheet(\"" + name + "\")");
460    }
461
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
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);
488        if (!state)
489            return BLANKSTRING;
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        */
498
499#ifdef ORXONOX_PLATFORM_APPLE
500        // There is no non exclusive mode on OS X yet
501        state->setMouseExclusive(TriBool::True);
502#else
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);
509#endif
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
527    void GUIManager::keyESC()
528    {
529        this->executeCode("keyESC()");
530    }
531
532    void GUIManager::setBackgroundImage(const std::string& imageSet, const std::string imageName)
533    {
534        if (imageSet.empty() || imageName.empty())
535            this->setBackgroundImage("");
536        else
537            this->setBackgroundImage("set: " + imageSet + " image: " + imageName);
538    }
539
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
549    void GUIManager::buttonPressed(const KeyEvent& evt)
550    {
551        this->protectedCall(boost::bind(&CEGUI::System::injectKeyDown, _1, evt.getKeyCode()));
552        this->protectedCall(boost::bind(&CEGUI::System::injectChar, _1, evt.getText()));
553    }
554
555    void GUIManager::buttonReleased(const KeyEvent& evt)
556    {
557        this->protectedCall(boost::bind(&CEGUI::System::injectKeyUp, _1, evt.getKeyCode()));
558    }
559
560    /**
561    @brief
562        Function receiving a mouse button pressed event.
563    @param id
564        ID of the mouse button which got pressed
565
566        This function is inherited by MouseHandler and injects the event into CEGUI.
567        It is for CEGUI to process the event.
568    */
569    void GUIManager::buttonPressed(MouseButtonCode::ByEnum id)
570    {
571        this->protectedCall(boost::bind(&CEGUI::System::injectMouseButtonDown, _1, convertButton(id)));
572    }
573
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    */
583    void GUIManager::buttonReleased(MouseButtonCode::ByEnum id)
584    {
585        this->protectedCall(boost::bind(&CEGUI::System::injectMouseButtonUp, _1, convertButton(id)));
586    }
587
588    void GUIManager::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize)
589    {
590        this->protectedCall(boost::bind(&CEGUI::System::injectMousePosition, _1, (float)abs.x, (float)abs.y));
591    }
592
593    void GUIManager::mouseScrolled(int abs, int rel)
594    {
595        this->protectedCall(boost::bind(&CEGUI::System::injectMouseWheelChange, _1, (float)rel));
596    }
597
598    /**
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    /**
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
613
614        Simple conversion from mouse event code in Orxonox to the one used in CEGUI.
615     */
616    static inline CEGUI::MouseButton convertButton(MouseButtonCode::ByEnum button)
617    {
618        switch (button)
619        {
620        case MouseButtonCode::Left:
621            return CEGUI::LeftButton;
622
623        case MouseButtonCode::Right:
624            return CEGUI::RightButton;
625
626        case MouseButtonCode::Middle:
627            return CEGUI::MiddleButton;
628
629        case MouseButtonCode::Button3:
630            return CEGUI::X1Button;
631
632        case MouseButtonCode::Button4:
633            return CEGUI::X2Button;
634
635        default:
636            return CEGUI::NoButton;
637        }
638    }
639
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
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    */
681    void GUIManager::subscribeEventHelper(CEGUI::Window* window, const std::string& event, const std::string& function)
682    {
683        window->subscribeScriptedEvent(event, function);
684    }
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
705        Whether to enable or disable the tooltips.
706    */
707    void GUIManager::setItemTooltipsEnabledHelper(CEGUI::Listbox* listbox, bool enabled)
708    {
709        listbox->setItemTooltipsEnabled(enabled);
710    }
711
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    {
717        this->guiRenderer_->setDisplaySize(CEGUI::Size((float)newWidth, (float)newHeight));
718    }
719
720    /**
721        @brief Notify CEGUI if the windows loses the focus (stops highlighting of menu items, etc).
722    */
723    void GUIManager::windowFocusChanged(bool bFocus)
724    {
725        if (!bFocus)
726            this->mouseLeft();
727    }
728
729}
Note: See TracBrowser for help on using the repository browser.