Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Code related to config values for output is now implemented in BaseWriter.
There's a config value for the normal output level, a vector with additional contexts, and a config value for the level of these additional contexts.
ioconsole and standard console use the same values.

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