Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/libs/src/libraries/core/GUIManager.cc @ 9670

Last change on this file since 9670 was 9670, checked in by landauf, 11 years ago

adjusted build-system and include-paths for cegui 0.8 (doesn't compile yet)

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