1 // SuperTuxKart - a fun racing game with go-kart 2 // Copyright (C) 2010-2015 Marianne Gagnon 3 // 4 // This program is free software; you can redistribute it and/or 5 // modify it under the terms of the GNU General Public License 6 // as published by the Free Software Foundation; either version 3 7 // of the License, or (at your option) any later version. 8 // 9 // This program is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with this program; if not, write to the Free Software 16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 18 19 #ifndef HEADER_ENGINE_HPP 20 #define HEADER_ENGINE_HPP 21 22 /** 23 * \defgroup guiengine 24 * Contains the generic GUI engine (contains the widgets and the backing logic 25 * for event handling, the skin, screens and dialogs). See module @ref states_screens 26 * for the actual STK GUI screens. Note that all input comes through this module 27 * too. 28 */ 29 30 namespace irr 31 { 32 class IrrlichtDevice; 33 namespace gui { class IGUIEnvironment; class ScalableFont; } 34 namespace video { class IVideoDriver; class ITexture; } 35 } 36 37 #include <functional> 38 #include <string> 39 40 #include "utils/constants.hpp" 41 #include "utils/ptr_vector.hpp" 42 43 #include "irrString.h" 44 45 /** 46 * \ingroup guiengine 47 * \brief Contains all GUI engine related classes and functions 48 * 49 * See \ref gui_overview for more information. 50 */ 51 namespace GUIEngine 52 { 53 class Screen; 54 class Widget; 55 class Skin; 56 class AbstractStateManager; 57 58 /** \brief Returns the widget currently focused by given player, or NULL if none. 59 * \note Do NOT use irrLicht's GUI focus facilities; it's too limited for our 60 * needs, so we use ours. (i.e. always call these functions, never those 61 * in IGUIEnvironment) 62 */ 63 Widget* getFocusForPlayer(const unsigned int playerID); 64 65 /** \brief Focuses nothing for given player (removes any selection for this player). 66 * \note Do NOT use irrLicht's GUI focus facilities; it's too limited for our 67 * needs, so we use ours. (i.e. always call these functions, never those 68 * in IGUIEnvironment) 69 */ 70 void focusNothingForPlayer(const unsigned int playerID); 71 72 /** \brief Returns whether given the widget is currently focused by given player. 73 * \note Do NOT use irrLicht's GUI focus facilities; it's too limited for our 74 * needs, so we use ours. (i.e. always call these functions, never those 75 * in IGUIEnvironment) 76 */ 77 bool isFocusedForPlayer(const Widget*w, const unsigned int playerID); 78 79 /** 80 * In an attempt to make getters as fast as possible, by possibly still allowing inlining 81 * These fields should never be accessed outside of the GUI engine. 82 */ 83 namespace Private 84 { 85 extern irr::gui::IGUIEnvironment* g_env; 86 extern Skin* g_skin; 87 extern irr::gui::ScalableFont* g_small_font; 88 extern irr::gui::ScalableFont* g_font; 89 extern irr::gui::ScalableFont* g_outline_font; 90 extern irr::gui::ScalableFont* g_large_font; 91 extern irr::gui::ScalableFont* g_title_font; 92 extern irr::gui::ScalableFont* g_small_title_font; 93 extern irr::gui::ScalableFont* g_tiny_title_font; 94 extern irr::gui::ScalableFont* g_digit_font; 95 96 extern irr::IrrlichtDevice* g_device; 97 extern irr::video::IVideoDriver* g_driver; 98 extern Screen* g_current_screen; 99 extern AbstractStateManager* g_state_manager; 100 extern Widget* g_focus_for_player[MAX_PLAYER_COUNT]; 101 } 102 103 /** Widgets that need to be notified at every frame can add themselves there (FIXME: unclean) */ 104 extern PtrVector<Widget, REF> needsUpdate; 105 106 /** 107 * \brief Call this method to init the GUI engine. 108 * \pre A irrlicht device and its corresponding video drivers must have been created 109 * \param device An initialized irrlicht device object 110 * \param driver An initialized irrlicht driver object 111 * \param state_manager An instance of a class derived from abstract base AbstractStateManager 112 * \param loading if it's (re-)loading the GUIEngine 113 */ 114 void init(irr::IrrlichtDevice* device, irr::video::IVideoDriver* driver, 115 AbstractStateManager* state_manager, bool loading = true); 116 117 void cleanUp(); 118 119 void deallocate(); 120 121 void resetGlobalVariables(); 122 123 /** 124 * \return the irrlicht device object 125 */ getDevice()126 inline irr::IrrlichtDevice* getDevice() { return Private::g_device; } 127 128 /** 129 * \return the irrlicht GUI environment object 130 */ getGUIEnv()131 inline irr::gui::IGUIEnvironment* getGUIEnv() { return Private::g_env; } 132 133 /** 134 * \return the irrlicht video driver object 135 */ getDriver()136 inline irr::video::IVideoDriver* getDriver() { return Private::g_driver; } 137 138 /** 139 * \return the smaller font (useful for less important messages) 140 */ getSmallFont()141 inline irr::gui::ScalableFont* getSmallFont() { return Private::g_small_font; } 142 143 /** 144 * \return the "normal" font (useful for text) 145 */ getFont()146 inline irr::gui::ScalableFont* getFont() { return Private::g_font; } 147 getOutlineFont()148 inline irr::gui::ScalableFont* getOutlineFont() { return Private::g_outline_font; } 149 150 /** 151 * \return the "large" font (useful for text) 152 */ getLargeFont()153 inline irr::gui::ScalableFont* getLargeFont() { return Private::g_large_font; } 154 155 /** 156 * \return the "high-res digits" font (useful for big numbers) 157 */ getHighresDigitFont()158 inline irr::gui::ScalableFont* getHighresDigitFont() { return Private::g_digit_font; } 159 160 /** 161 * \return the "title" font (it's bigger and orange, useful for headers/captions) 162 */ getTitleFont()163 inline irr::gui::ScalableFont* getTitleFont() { return Private::g_title_font; } 164 165 /** 166 * \return the "small title" font (it's bigger and orange, useful for sub headers/captions) 167 */ getSmallTitleFont()168 inline irr::gui::ScalableFont* getSmallTitleFont() { return Private::g_small_title_font; } 169 170 /** 171 * \return the "tiny title" font (it's bigger and orange, useful for sub headers/captions) 172 */ getTinyTitleFont()173 inline irr::gui::ScalableFont* getTinyTitleFont() { return Private::g_tiny_title_font; } 174 175 /** 176 * \return the currently shown screen, or NULL if none 177 */ getCurrentScreen()178 inline Screen* getCurrentScreen() { return Private::g_current_screen; } 179 180 /** 181 * \return the state manager being used, as passed to GUIEngine::init 182 */ getStateManager()183 inline AbstractStateManager* getStateManager() { return Private::g_state_manager; } 184 185 void clearScreenCache(); 186 187 /** 188 * \pre GUIEngine::init must have been called first 189 * \return the skin object used to render widgets 190 */ getSkin()191 inline Skin* getSkin() { return Private::g_skin; } 192 setSkin(Skin * skin)193 inline void setSkin(Skin* skin) { Private::g_skin = skin; } 194 Screen* getScreenNamed(const char* name); 195 196 /** \return the height of the title font in pixels */ 197 int getTitleFontHeight(); 198 199 /** \return the height of the font in pixels */ 200 int getFontHeight(); 201 202 /** \return the height of the small font in pixels */ 203 int getSmallFontHeight(); 204 205 /** 206 * \pre the value returned by this function is only valid when invoked from GUIEngine::render 207 * \return the time delta between the last two frames 208 */ 209 float getLatestDt(); 210 211 /** 212 * \brief shows a message at the bottom of the screen for a while 213 * \param message the message to display 214 * \param time the time to display the message, in seconds 215 */ 216 void showMessage(const irr::core::stringw& message, const float time=5.0f); 217 218 /** \brief Add a screen to the list of screens known by the gui engine */ 219 void addScreenToList(Screen* screen); 220 /** \brief Remove a screen from the list of screens known by the gui engine */ 221 void removeScreen(Screen* screen); 222 223 /** \brief Low-level mean to change current screen. 224 * \note Do not use directly. Use a state manager instead to get higher-level functionnality. 225 */ 226 void switchToScreen(Screen* screen); 227 228 /** \brief erases the currently displayed screen, removing all added irrLicht widgets 229 * \note Do not use directly. Use a state manager instead to get higher-level functionnality. 230 */ 231 void clear(); 232 233 void update(float dt); 234 235 /** \brief like GUIEngine::clear, but to be called before going into game */ 236 void cleanForGame(); 237 238 /** \brief to be called after e.g. a resolution switch */ 239 void reshowCurrentScreen(); 240 241 /** 242 * \brief called on every frame to trigger the rendering of the GUI 243 */ 244 void render(float dt, bool is_loading = false); 245 246 void clearLoadingTips(); 247 248 /** \brief renders a "loading" screen */ 249 void renderLoading(bool clearIcons = true, bool launching = false, bool update_tips = true); 250 251 /** \brief to spice up a bit the loading icon : add icons to the loading screen */ 252 void addLoadingIcon(irr::video::ITexture* icon); 253 254 /** \brief Finds a widget from its name (PROP_ID) in the current screen/dialog 255 * \param name the name (PROP_ID) of the widget to search for 256 * \return the widget that bears that name, or NULL if it was not found 257 */ 258 Widget* getWidget(const char* name); 259 260 /** \brief Finds a widget from its irrlicht widget ID in the current screen/dialog 261 * \param name the irrlicht widget ID (not to be confused with PROP_ID, which is a string) 262 * of the widget to search for 263 * \return the widget that bears that irrlicht ID, or NULL if it was not found 264 */ 265 Widget* getWidget(const int id); 266 267 /** 268 * \brief call when skin in user config was updated 269 */ 270 void reloadSkin(); 271 272 /** 273 * \brief call when screen size changed 274 */ 275 void reloadForNewSize(); 276 277 /** 278 * \brief Add gui-related function before rendering GUI (from other thread) 279 */ 280 void addGUIFunctionBeforeRendering(std::function<void()> func); 281 282 #ifdef SERVER_ONLY disableGraphics()283 inline void disableGraphics() {} isNoGraphics()284 constexpr bool isNoGraphics() { return true; } 285 #else 286 void disableGraphics(); 287 bool isNoGraphics(); 288 #endif 289 } 290 291 #endif 292