1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef GUIMANAGER_H 24 #define GUIMANAGER_H 25 26 #include "common/scummsys.h" 27 #include "common/singleton.h" 28 #include "common/stack.h" 29 #include "common/str.h" 30 #include "common/list.h" 31 32 #include "gui/ThemeEngine.h" 33 #include "gui/widget.h" 34 35 class OSystem; 36 37 namespace Graphics { 38 class Font; 39 } 40 41 namespace Common { 42 struct Event; 43 class Keymap; 44 } 45 46 namespace GUI { 47 48 class Dialog; 49 class ThemeEval; 50 class GuiObject; 51 52 #define g_gui (GUI::GuiManager::instance()) 53 54 55 // Height of a single text line 56 #define kLineHeight (g_gui.getFontHeight() + 2) 57 58 59 60 // Simple dialog stack class 61 // Anybody nesting dialogs deeper than 4 is mad anyway 62 typedef Common::FixedStack<Dialog *> DialogStack; 63 64 65 /** 66 * GUI manager singleton. 67 */ 68 class GuiManager : public Common::Singleton<GuiManager> { 69 friend class Dialog; 70 friend class Common::Singleton<SingletonBaseType>; 71 GuiManager(); 72 ~GuiManager() override; 73 public: 74 75 // Main entry for the GUI: this will start an event loop that keeps running 76 // until no dialogs are active anymore. 77 void runLoop(); 78 79 // If the GUI loop is running close all the dialogs causing the loop to finish. 80 // Typically you may want to use it after setting the ConfMan active domain to 81 // a game domain to cause the game to start. 82 void exitLoop(); 83 84 void processEvent(const Common::Event &event, Dialog *const activeDialog); 85 Common::Keymap *getKeymap() const; 86 void scheduleTopDialogRedraw(); 87 isActive()88 bool isActive() const { return ! _dialogStack.empty(); } 89 90 bool loadNewTheme(Common::String id, ThemeEngine::GraphicsMode gfx = ThemeEngine::kGfxDisabled, bool force = false); theme()91 ThemeEngine *theme() { return _theme; } 92 xmlEval()93 ThemeEval *xmlEval() { return _theme->getEvaluator(); } 94 getGUIWidth()95 int16 getGUIWidth() const { return _baseWidth; } getGUIHeight()96 int16 getGUIHeight() const { return _baseHeight; } getScaleFactor()97 float getScaleFactor() const { return _scaleFactor; } 98 void computeScaleFactor(); 99 useRTL()100 bool useRTL() const { return _useRTL; } 101 void setLanguageRTL(); 102 103 void setDialogPaddings(int l, int r); getOverlayOffset()104 int getOverlayOffset() { return _topDialogRightPadding - _topDialogLeftPadding; } 105 106 const Graphics::Font &getFont(ThemeEngine::FontStyle style = ThemeEngine::kFontStyleBold) const { return *(_theme->getFont(style)); } 107 int getFontHeight(ThemeEngine::FontStyle style = ThemeEngine::kFontStyleBold) const { return _theme->getFontHeight(style); } 108 int getStringWidth(const Common::String &str, ThemeEngine::FontStyle style = ThemeEngine::kFontStyleBold) const { return _theme->getStringWidth(str, style); } 109 int getStringWidth(const Common::U32String &str, ThemeEngine::FontStyle style = ThemeEngine::kFontStyleBold) const { return _theme->getStringWidth(str, style); } 110 int getCharWidth(byte c, ThemeEngine::FontStyle style = ThemeEngine::kFontStyleBold) const { return _theme->getCharWidth(c, style); } 111 int getKerningOffset(byte left, byte right, ThemeEngine::FontStyle font = ThemeEngine::kFontStyleBold) const { return _theme->getKerningOffset(left, right, font); } 112 113 /** 114 * Tell the GuiManager to check whether the screen resolution has changed. 115 * If that is the case, the GuiManager will reload/refresh the active theme. 116 * 117 * @return true if the a screen change indeed occurred, false otherwise 118 */ 119 bool checkScreenChange(); 120 121 /** 122 * Tell the GuiManager to delete the given GuiObject later. If a parent 123 * dialog is provided and is present in the DialogStack, the object will 124 * only be deleted when that dialog is the top level dialog. 125 */ 126 void addToTrash(GuiObject*, Dialog* parent = nullptr); 127 void initTextToSpeech(); 128 129 bool _launched; 130 131 void redrawFull(); 132 133 protected: 134 enum RedrawStatus { 135 kRedrawDisabled = 0, 136 kRedrawOpenDialog, 137 kRedrawCloseDialog, 138 kRedrawTopDialog, 139 kRedrawFull 140 }; 141 142 OSystem *_system; 143 144 ThemeEngine *_theme; 145 146 // bool _needRedraw; 147 RedrawStatus _redrawStatus; 148 int _lastScreenChangeID; 149 int16 _baseWidth, _baseHeight; 150 float _scaleFactor; 151 DialogStack _dialogStack; 152 153 bool _stateIsSaved; 154 155 bool _useStdCursor; 156 157 bool _useRTL; 158 159 int _topDialogLeftPadding; 160 int _topDialogRightPadding; 161 162 // position and time of last mouse click (used to detect double clicks) 163 struct MousePos { MousePosMousePos164 MousePos() : x(-1), y(-1), count(0) { time = 0; } 165 int16 x, y; // Position of mouse when the click occurred 166 uint32 time; // Time 167 int count; // How often was it already pressed? 168 } _lastClick, _lastMousePosition, _globalMousePosition; 169 170 struct TooltipData { TooltipDataTooltipData171 TooltipData() : x(-1), y(-1) { time = 0; wdg = nullptr; } 172 uint32 time; // Time 173 Widget *wdg; // Widget that had its tooltip shown 174 int16 x, y; // Position of mouse before tooltip was focused 175 } _lastTooltipShown; 176 177 // mouse cursor state 178 int _cursorAnimateCounter; 179 int _cursorAnimateTimer; 180 byte _cursor[2048]; 181 182 // delayed deletion of GuiObject 183 struct GuiObjectTrashItem { 184 GuiObject* object; 185 Dialog* parent; 186 }; 187 Common::List<GuiObjectTrashItem> _guiObjectTrash; 188 189 void initKeymap(); 190 void enableKeymap(bool enabled); 191 192 void saveState(); 193 void restoreState(); 194 195 void openDialog(Dialog *dialog); 196 void closeTopDialog(); 197 198 void redraw(); 199 200 void setupCursor(); 201 void animateCursor(); 202 203 Dialog *getTopDialog() const; 204 205 void screenChange(); 206 207 void giveFocusToDialog(Dialog *dialog); 208 void setLastMousePos(int16 x, int16 y); 209 }; 210 211 } // End of namespace GUI 212 213 #endif 214