Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 8530 was 8530, checked in by landauf, 14 years ago

added config value to define the scroll speed in CEGUI listboxes. default 1 line.

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