Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation/src/libraries/core/GUIManager.cc @ 8637

Last change on this file since 8637 was 8637, checked in by dafrick, 13 years ago

Merging tutoriallevel3 branch into presentation branch.

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