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 
34 class OSystem;
35 
36 namespace Graphics {
37 class Font;
38 }
39 
40 namespace Common {
41 	struct Event;
42 }
43 
44 namespace GUI {
45 
46 class Dialog;
47 class ThemeEval;
48 class GuiObject;
49 
50 #define g_gui	(GUI::GuiManager::instance())
51 
52 
53 // Height of a single text line
54 #define kLineHeight	(g_gui.getFontHeight() + 2)
55 
56 
57 
58 // Simple dialog stack class
59 // Anybody nesting dialogs deeper than 4 is mad anyway
60 typedef Common::FixedStack<Dialog *> DialogStack;
61 
62 
63 /**
64  * GUI manager singleton.
65  */
66 class GuiManager : public Common::Singleton<GuiManager> {
67 	friend class Dialog;
68 	friend class Common::Singleton<SingletonBaseType>;
69 	GuiManager();
70 	~GuiManager();
71 public:
72 
73 	// Main entry for the GUI: this will start an event loop that keeps running
74 	// until no dialogs are active anymore.
75 	void runLoop();
76 
77 	void processEvent(const Common::Event &event, Dialog *const activeDialog);
78 	void doFullRedraw();
79 
isActive()80 	bool isActive() const	{ return ! _dialogStack.empty(); }
81 
82 	bool loadNewTheme(Common::String id, ThemeEngine::GraphicsMode gfx = ThemeEngine::kGfxDisabled, bool force = false);
theme()83 	ThemeEngine *theme() { return _theme; }
84 
xmlEval()85 	ThemeEval *xmlEval() { return _theme->getEvaluator(); }
86 
getWidth()87 	int getWidth() const { return _width; }
getHeight()88 	int getHeight() const { return _height; }
89 
90 	const Graphics::Font &getFont(ThemeEngine::FontStyle style = ThemeEngine::kFontStyleBold) const { return *(_theme->getFont(style)); }
91 	int getFontHeight(ThemeEngine::FontStyle style = ThemeEngine::kFontStyleBold) const { return _theme->getFontHeight(style); }
92 	int getStringWidth(const Common::String &str, ThemeEngine::FontStyle style = ThemeEngine::kFontStyleBold) const { return _theme->getStringWidth(str, style); }
93 	int getCharWidth(byte c, ThemeEngine::FontStyle style = ThemeEngine::kFontStyleBold) const { return _theme->getCharWidth(c, style); }
94 	int getKerningOffset(byte left, byte right, ThemeEngine::FontStyle font = ThemeEngine::kFontStyleBold) const { return _theme->getKerningOffset(left, right, font); }
95 
96 	/**
97 	 * Tell the GuiManager to check whether the screen resolution has changed.
98 	 * If that is the case, the GuiManager will reload/refresh the active theme.
99 	 *
100 	 * @return true if the a screen change indeed occurred, false otherwise
101 	 */
102 	bool checkScreenChange();
103 
104 	/**
105 	 * Tell the GuiManager to delete the given GuiObject later. If a parent
106 	 * dialog is provided and is present in the DialogStack, the object will
107 	 * only be deleted when that dialog is the top level dialog.
108 	 */
109 	void addToTrash(GuiObject*, Dialog* parent = 0);
110 
111 	bool _launched;
112 
113 protected:
114 	enum RedrawStatus {
115 		kRedrawDisabled = 0,
116 		kRedrawOpenDialog,
117 		kRedrawCloseDialog,
118 		kRedrawTopDialog,
119 		kRedrawFull
120 	};
121 
122 	OSystem			*_system;
123 
124 	ThemeEngine		*_theme;
125 
126 //	bool		_needRedraw;
127 	RedrawStatus _redrawStatus;
128 	int			_lastScreenChangeID;
129 	int			_width, _height;
130 	DialogStack	_dialogStack;
131 
132 	bool		_stateIsSaved;
133 
134 	bool		_useStdCursor;
135 
136 	// position and time of last mouse click (used to detect double clicks)
137 	struct MousePos {
MousePosMousePos138 		MousePos() : x(-1), y(-1), count(0) { time = 0; }
139 		int16 x, y;	// Position of mouse when the click occurred
140 		uint32 time;	// Time
141 		int count;	// How often was it already pressed?
142 	} _lastClick, _lastMousePosition, _globalMousePosition;
143 
144 	// mouse cursor state
145 	int		_cursorAnimateCounter;
146 	int		_cursorAnimateTimer;
147 	byte	_cursor[2048];
148 
149 	// delayed deletion of GuiObject
150 	struct GuiObjectTrashItem {
151 		GuiObject* object;
152 		Dialog* parent;
153 	};
154 	Common::List<GuiObjectTrashItem> _guiObjectTrash;
155 
156 	void initKeymap();
157 	void pushKeymap();
158 	void popKeymap();
159 
160 	void saveState();
161 	void restoreState();
162 
163 	void openDialog(Dialog *dialog);
164 	void closeTopDialog();
165 
166 	void redraw();
167 
168 	void loop();
169 
170 	void setupCursor();
171 	void animateCursor();
172 
173 	Dialog *getTopDialog() const;
174 
175 	void screenChange();
176 
177 	void giveFocusToDialog(Dialog *dialog);
178 	void setLastMousePos(int16 x, int16 y);
179 };
180 
181 } // End of namespace GUI
182 
183 #endif
184