Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/output/src/libraries/core/GUIManager.cc @ 9098

Last change on this file since 9098 was 8830, checked in by landauf, 13 years ago

added some output (user and internal) throughout the initialization of the game, graphics, and game states

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