1 // -*- C++ -*-
2 /* GG is a GUI for OpenGL.
3 Copyright (C) 2003-2008 T. Zachary Laine
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public License
7 as published by the Free Software Foundation; either version 2.1
8 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA
19
20 If you do not wish to comply with the terms of the LGPL please
21 contact the author as other terms are available for a fee.
22
23 Zach Laine
24 whatwasthataddress@gmail.com */
25
26 /** \file GUI.h \brief Contains GUI class, which encapsulates the state and
27 behavior of the entire GG GUI. */
28
29 #ifndef _GG_GUI_h_
30 #define _GG_GUI_h_
31
32 #include <GG/Font.h>
33 #include <GG/WndEvent.h>
34
35 #include <boost/signals2/signal.hpp>
36
37 #include <chrono>
38
39
40 namespace boost { namespace archive {
41 class xml_oarchive;
42 class xml_iarchive;
43 } }
44
45 namespace GG {
46
47 class Cursor;
48 class Wnd;
49 class StyleFactory;
50 class Texture;
51 class Timer;
52 struct GUIImpl;
53
54 template <typename T>
LockAndResetIfExpired(std::weak_ptr<T> & ptr)55 std::shared_ptr<T> LockAndResetIfExpired(std::weak_ptr<T>& ptr) {
56 auto locked = ptr.lock();
57 if (!locked)
58 ptr.reset();
59 return locked;
60 }
61
62 /** \brief An abstract base for an GUI framework class to drive the GG GUI.
63
64 This class has all the essential services that GG requires:
65 - GUI initialization and emergency exit
66 - GG event handling
67 - rendering of GUI windows
68 - entry into and cleanup after a "2D" mode, in case the app also uses non-orthographic 3D projections
69 - registration into, removal from, and movement within a z-ordering of windows, including handling of "always-on-top" windows
70 - handling of modal windows
71 - drag-and-drop support
72 - inter-frame time updates and FPS calculations
73 - limits on FPS speed
74 - access to the dimensions of the application window or screen
75 - mouse state information
76 - keyboard accelerators
77 - management of fonts and textures
78
79 <p>The user is required to provide several functions. The most vital
80 functions the user is required to provide are: Enter2DMode(),
81 Exit2DMode() and Run()[virtual private]. Without these, GUI is pretty
82 useless. In addition, HandleEvent() must be driven from Run(). The
83 code driving HandleEvent() must interact with the hardware and/or operating
84 system, and supply the appropriate EventType's, key presses, and mouse
85 position info to HandleEvent().
86
87 <p>Keyboard accelerators may be defined, as mentioned above. Each defined
88 accelerator has its own signal which is emitted each time the accelerator
89 is detected. Client code should listen to the appropriate signal to act
90 on an accelerator invocation. Each slot that is signalled with a keyboard
91 accelerator should return true if it processed the accelerator, or false
92 otherwise. This lets GUI know whether or not it should create a keystroke
93 event and process it normally, sending it to the Wnd that currently has
94 focus. Note that since signals can be connected to multiple slots, if
95 even one slot returns true, no kestroke event is created. It is perfectly
96 legal to return false even if an accelerator is processed, as long as you
97 also then want the focus Wnd to receive a keystroke event. Also, note
98 that all accelerators are processed before, and possbily instead of, any
99 key events. So setting a plain "h" as a keyboard accelerator can (if it
100 is processed normally by a slot) prevent any Wnd anywhere in your
101 application from receiving "h" keystrokes. To avoid this:
102 - Define accelerators with modifier keys like CTRL and ALT, or
103 - Have slots that process these accelerators return false, or
104 - Do not connect anything to such an accelerator, in which case it will return false.
105
106 <p>A GUI-wide StyleFactory can be set; this controls the actual types of
107 controls and dialogs that are created when a control or dialog creates one
108 (e.g. when FileDlg encounters an error and creates a ThreeButtonDlg).
109 This is overridden by any StyleFactory that may be installed in an
110 individual Wnd.
111
112 <p>A note about "button-down-repeat". When you click on the down-button
113 on a scroll-bar, you probably expect the the button's action (scrolling
114 down one increment) to repeat when you hold down the button, much like the
115 way kestrokes are repeated when you hold down a keyboard key. This is in
116 fact what happens, and it is accomplished by having the scroll and its
117 buttons respond to extra LButtonDown events generated by the GUI. These
118 extra messages, occur ButtonDownRepeatDelay() milliseconds after the
119 button is first depressed, repeating every ButtonDownRepeatInterval()
120 milliseconds thereafter. Only Wnds created with the REPEAT_BUTTON_DOWN
121 flag receive such extra messages.
122 */
123 class GG_API GUI
124 {
125 private:
126 struct OrCombiner
127 {
128 typedef bool result_type;
129 template <typename InIt> bool operator()(InIt first, InIt last) const;
130 };
131
132 public:
133 /** \name Signal Types */ ///@{
134 /** Emitted when a keyboard accelerator is invoked. A return value of true
135 indicates that the accelerator was processed by some slot; otherwise,
136 a keystroke event is processed instead. */
137 typedef boost::signals2::signal<bool (), OrCombiner> AcceleratorSignalType;
138 //@}
139
140 /// These are the only events absolutely necessary for GG to function
141 /// properly
142 enum EventType : int {
143 IDLE, ///< nothing has changed since the last message, but the GUI might want to update some things anyway
144 KEYPRESS, ///< a down key press or key repeat, with or without modifiers like Alt, Ctrl, Meta, etc.
145 KEYRELEASE, ///< a key release, with or without modifiers like Alt, Ctrl, Meta, etc.
146 TEXTINPUT, ///< user inputted unicode text using some method
147 LPRESS, ///< a left mouse button press
148 MPRESS, ///< a middle mouse button press
149 RPRESS, ///< a right mouse button press
150 LRELEASE, ///< a left mouse button release
151 MRELEASE, ///< a middle mouse button release
152 RRELEASE, ///< a right mouse button release
153 MOUSEMOVE, ///< movement of the mouse; may include relative motion in addition to absolute position
154 MOUSEWHEEL ///< rolling of the mouse wheel; this event is accompanied by the amount of roll in the y-component of the mouse's relative position (+ is up, - is down)
155 };
156
157 /** The type of iterator returned by non-const accel_begin() and
158 accel_end(). */
159 typedef std::set<std::pair<Key, Flags<ModKey>>>::iterator accel_iterator;
160
161 /** The type of iterator returned by const accel_begin() and
162 accel_end(). */
163 typedef std::set<std::pair<Key, Flags<ModKey>>>::const_iterator const_accel_iterator;
164
165 /** \name Structors */ ///@{
166 virtual ~GUI();
167 //@}
168
169 /** \name Accessors */ ///@{
170 const std::string& AppName() const; ///< returns the user-defined name of the application
171 std::shared_ptr<Wnd> FocusWnd() const; ///< returns the GG::Wnd that currently has the input focus
172 bool FocusWndAcceptsTypingInput() const; ///< returns true iff the current focus GG::Wnd accepts typing input
173 std::shared_ptr<Wnd> PrevFocusInteractiveWnd() const; ///< returns the previous Wnd to the current FocusWnd. Cycles through INTERACTIVE Wnds, in order determined by parent-child relationships
174 std::shared_ptr<Wnd> NextFocusInteractiveWnd() const; ///< returns the next Wnd to the current FocusWnd.
175 std::shared_ptr<Wnd> GetWindowUnder(const Pt& pt) const; ///< returns the GG::Wnd under the point pt
176 virtual unsigned int Ticks() const = 0; ///< returns milliseconds since the app started running
177 bool RenderingDragDropWnds() const; ///< returns true iff drag-and-drop Wnds are currently being rendered
178 bool FPSEnabled() const; ///< returns true iff FPS calulations are turned on
179 double FPS() const; ///< returns the frames per second at which the GUI is rendering
180 std::string FPSString() const; ///< returns a string of the form "[m_FPS] frames per second"
181 double MaxFPS() const; ///< returns the maximum allowed frames per second of rendering speed. 0 indicates no limit.
182 virtual X AppWidth() const = 0; ///< returns the width of the application window/screen
183 virtual Y AppHeight() const = 0; ///< returns the height of the application window/screen
184 unsigned int KeyPressRepeatDelay() const; ///< returns the \a delay value set by EnableKeyPressRepeat()
185 unsigned int KeyPressRepeatInterval() const; ///< returns the \a interval value set by EnableKeyPressRepeat()
186 unsigned int ButtonDownRepeatDelay() const; ///< returns the \a delay value set by EnableMouseButtonDownRepeat()
187 unsigned int ButtonDownRepeatInterval() const; ///< returns the \a interval value set by EnableMouseButtonDownRepeat()
188 unsigned int DoubleClickInterval() const; ///< returns the maximum interval allowed between clicks that is still considered a double-click, in ms
189 unsigned int MinDragTime() const; ///< returns the minimum time (in ms) an item must be dragged before it is a valid drag
190 unsigned int MinDragDistance() const; ///< returns the minimum distance an item must be dragged before it is a valid drag
191 bool DragWnd(const Wnd* wnd, unsigned int mouse_button) const; ///< returns true if \a wnd is currently being dragged with button \a mouse_button
192 bool DragDropWnd(const Wnd* wnd) const; ///< returns true if \a wnd is currently begin dragged as part of a drag-and-drop operation
193 bool AcceptedDragDropWnd(const Wnd* wnd) const; ///< returns true if \a wnd is currently begin dragged as part of a drag-and-drop operation, and it is over a drop target that will accept it
194 bool MouseButtonDown(unsigned int bn) const; ///< returns the up/down states of the mouse buttons
195 Pt MousePosition() const; ///< returns the absolute position of mouse, based on the last mouse motion event
196 Pt MouseMovement() const; ///< returns the relative position of mouse, based on the last mouse motion event
197 Flags<ModKey> ModKeys() const; ///< returns the set of modifier keys that are currently depressed, based on the last event
198 bool MouseLRSwapped() const; ///< returns true if the left and right mouse button press events are set to be swapped before event handling. This is to facilitate left-handed mouse users semi-automatically.
199 virtual std::string ClipboardText() const; ///< returns text stored in a clipboard
200
201 /** Returns the (begin, end) indices of the code points of all the
202 word-tokens in the given string. This is perhaps an odd place for
203 this function to exist, but the notion of what a "word" is is so
204 application-specific that it was placed here so that users can
205 customize this behavior. */
206 virtual std::set<std::pair<CPSize, CPSize>> FindWords(const std::string& str) const;
207 virtual std::set<std::pair<StrSize, StrSize>> FindWordsStringIndices(const std::string& str) const;
208 /** Returns true if \a word is a word that appears in \a str */
209 virtual bool ContainsWord(const std::string& str, const std::string& word) const;
210
211 /** Returns the currently-installed style factory. */
212 const std::shared_ptr<StyleFactory>& GetStyleFactory() const;
213
214 bool RenderCursor() const; ///< returns true iff the GUI is responsible for rendering the cursor
215
216 /* Returns the currently-installed cursor. */
217 const std::shared_ptr<Cursor>& GetCursor() const;
218
219 /** Returns an iterator to one past the first defined keyboard accelerator. */
220 const_accel_iterator accel_begin() const;
221
222 /** Returns an iterator to one past the last defined keyboard accelerator. */
223 const_accel_iterator accel_end() const;
224
225 /** Returns the signal that is emitted when the requested keyboard accelerator is invoked. */
226 AcceleratorSignalType& AcceleratorSignal(Key key, Flags<ModKey> mod_keys = MOD_KEY_NONE) const;
227
228 /** Returns true iff keyboard accelerator signals fire while modal windows are open. */
229 bool ModalAcceleratorSignalsEnabled() const;
230
231 /** Returns true iff any modal Wnds are open. */
232 bool ModalWndsOpen() const;
233
234 /** Saves \a wnd to file \a filename during the next render cycle. If \a
235 wnd is not rendered during the render cycle, or PNG support is not
236 enabled, this is a no-op. */
237 void SaveWndAsPNG(const Wnd* wnd, const std::string& filename) const;
238 //@}
239
240 /** \name Mutators */ ///@{
241 //! Executes main event handler/render loop
242 virtual void Run() = 0;
243
244 virtual void ExitApp(int code = 0) = 0; ///< does basic clean-up, then calls exit(); callable from anywhere in user code via GetGUI()
245
246 /** Handles all waiting system events (from SDL, DirectInput, etc.). This
247 function should only be called from custom RunModal event
248 handlers. */
249 virtual void HandleSystemEvents() = 0;
250
251 /** Event handler for GG events. */
252 void HandleGGEvent(EventType event, Key key, std::uint32_t key_code_point, Flags<ModKey> mod_keys, const Pt& pos, const Pt& rel, const std::string* text = nullptr);
253
254 void ClearEventState();
255
256 void SetFocusWnd(const std::shared_ptr<Wnd>& wnd); ///< sets the input focus window to \a wnd
257 /** Suspend the GUI thread for \p us microseconds. Singlethreaded GUI subclasses may do
258 nothing here, or may pause for \p us microseconds. */
259 virtual void Wait(std::chrono::microseconds us);
260 virtual void Wait(unsigned int ms); ///< suspends the GUI thread for \a ms milliseconds. Singlethreaded GUI subclasses may do nothing here, or may pause for \a ms milliseconds.
261
262 /** Adds \p wnd into the z-list. A registered window is owned by the GUI as a top level
263 window. Registering a null pointer or registering the same window multiple times is a no-op. */
264 void Register(std::shared_ptr<Wnd> wnd);
265 /** Adds \p wnd onto the modal windows "stack". Modal windows are owned by the GUI as a
266 top-level window. */
267 void RegisterModal(std::shared_ptr<Wnd> wnd);
268 void RunModal(std::shared_ptr<Wnd> wnd, bool& done);
269 void Remove(const std::shared_ptr<Wnd>& wnd); ///< removes \a wnd from the z-list. Removing a null pointer or removing the same window multiple times is a no-op.
270 void MoveUp(const std::shared_ptr<Wnd>& wnd); ///< moves \a wnd to the top of the z-list
271 void MoveDown(const std::shared_ptr<Wnd>& wnd); ///< moves \a wnd to the bottom of the z-list
272
273 /** Adds \a wnd to the set of current drag-and-drop Wnds, to be rendered
274 \a offset pixels from the cursor position. \a originating_wnd
275 indicates the original owner of \a wnd before the drag-and-drop.
276 \throw std::runtime_error May throw std::runtime_error if there are
277 already other Wnds registered that belong to a window other than \a
278 originating_wnd. */
279 void RegisterDragDropWnd(std::shared_ptr<Wnd> wnd, const Pt& offset, std::shared_ptr<Wnd> originating_wnd);
280 void CancelDragDrop(); ///< clears the set of current drag-and-drop Wnds
281
282 void RegisterTimer(Timer& timer); ///< adds \a timer to the list of active timers
283 void RemoveTimer(Timer& timer); ///< removes \a timer from the list of active timers
284
285 virtual void Enter2DMode() = 0; ///< saves any current GL state, sets up GG-friendly 2D drawing mode. GG expects an orthographic projection, with the origin in the upper left corner, and with one unit of GL space equal to one pixel on the screen.
286 virtual void Exit2DMode() = 0; ///< restores GL to its condition prior to Enter2DMode() call
287 void EnableFPS(bool b = true); ///< turns FPS calulations on or off
288 void SetMaxFPS(double max); ///< sets the maximum allowed FPS, so the render loop does not act as a spinlock when it runs very quickly. 0 indicates no limit.
289 void EnableKeyPressRepeat(unsigned int delay, unsigned int interval); ///< delay and interval are in ms; Setting delay to 0 disables key press repeating completely.
290 void EnableMouseButtonDownRepeat(unsigned int delay, unsigned int interval); ///< delay and interval are in ms; Setting delay to 0 disables mouse button-down repeating completely.
291 void SetDoubleClickInterval(unsigned int interval); ///< sets the maximum interval allowed between clicks that is still considered a double-click, in ms
292 void SetMinDragTime(unsigned int time); ///< sets the minimum time (in ms) an item must be dragged before it is a valid drag
293 void SetMinDragDistance(unsigned int distance); ///< sets the minimum distance an item must be dragged before it is a valid drag
294
295 /** Returns an iterator to the first defined keyboard accelerator. */
296 accel_iterator accel_begin();
297
298 /** Returns an iterator to one past the last defined keyboard accelerator. */
299 accel_iterator accel_end();
300
301 /** Establishes a keyboard accelerator. Any key modifiers may be
302 specified, or none at all. */
303 void SetAccelerator(Key key, Flags<ModKey> mod_keys = MOD_KEY_NONE);
304
305 /** Removes a keyboard accelerator. Any key modifiers may be specified,
306 or none at all. */
307 void RemoveAccelerator(Key key, Flags<ModKey> mod_keys = MOD_KEY_NONE);
308
309 /** Removes a keyboard accelerator. */
310 void RemoveAccelerator(accel_iterator it);
311
312 /** Sets whether to emit keyboard accelerator signals while modal windows are open. */
313 void EnableModalAcceleratorSignals(bool allow = true);
314
315 /** Sets whether to swap left and right mouse button events. */
316 void SetMouseLRSwapped(bool swapped = true);
317
318 /** Returns a shared_ptr to the desired font, supporting all printable
319 ASCII characters. */
320 std::shared_ptr<Font> GetFont(const std::string& font_filename, unsigned int pts);
321
322 /** Returns a shared_ptr to the desired font, supporting all printable
323 ASCII characters, from the in-memory contents \a file_contents. */
324 std::shared_ptr<Font> GetFont(const std::string& font_filename, unsigned int pts,
325 const std::vector<unsigned char>& file_contents);
326
327 /** Returns a shared_ptr to the desired font, supporting all the
328 characters in the UnicodeCharsets in the range [first, last). */
329 template <typename CharSetIter>
330 std::shared_ptr<Font> GetFont(const std::string& font_filename, unsigned int pts,
331 CharSetIter first, CharSetIter last);
332
333 /** Returns a shared_ptr to the desired font, supporting all the
334 characters in the UnicodeCharsets in the range [first, last), from the
335 in-memory contents \a file_contents. */
336 template <typename CharSetIter>
337 std::shared_ptr<Font> GetFont(const std::string& font_filename, unsigned int pts,
338 const std::vector<unsigned char>& file_contents,
339 CharSetIter first, CharSetIter last);
340
341 /** Returns a shared_ptr to existing font \a font in a new size, \a pts. */
342 std::shared_ptr<Font> GetFont(const std::shared_ptr<Font>& font, unsigned int pts);
343
344 /** Removes the desired font from the managed pool; since shared_ptr's are
345 used, the font may be deleted much later. */
346 void FreeFont(const std::string& font_filename, unsigned int pts);
347
348 /** Adds an already-constructed texture to the managed pool \warning
349 calling code <b>must not</b> delete \a texture; the texture pool will
350 do that. */
351 std::shared_ptr<Texture> StoreTexture(Texture* texture, const std::string& texture_name);
352
353 /** Adds an already-constructed texture to the managed pool. */
354 std::shared_ptr<Texture> StoreTexture(const std::shared_ptr<Texture> &texture, const std::string& texture_name);
355
356 /** Loads the requested texture from file \a name; mipmap textures are
357 * generated if \a mipmap is true. */
358 std::shared_ptr<Texture> GetTexture(const std::string& name, bool mipmap = false);
359
360 /** Loads the requested texture from file \a name; mipmap textures are
361 * generated if \a mipmap is true. */
362 std::shared_ptr<Texture> GetTexture(const boost::filesystem::path& path, bool mipmap = false);
363
364 /** Removes the desired texture from the managed pool; since shared_ptr's
365 * are used, the texture may be deleted much later. */
366 void FreeTexture(const std::string& name);
367
368 /** Removes the desired texture from the managed pool; since shared_ptr's
369 * are used, the texture may be deleted much later. */
370 void FreeTexture(const boost::filesystem::path& path);
371
372 /** Sets the currently-installed style factory. */
373 void SetStyleFactory(const std::shared_ptr<StyleFactory>& factory);
374
375 void RenderCursor(bool render); ///< set this to true iff the GUI should render the cursor
376
377 /** Sets the currently-installed cursor. */
378 void SetCursor(const std::shared_ptr<Cursor>& cursor);
379
380 virtual bool SetClipboardText(const std::string& text); ///< sets text stored in clipboard
381 bool CopyFocusWndText(); ///< copies current focus Wnd as text to clipboard
382 bool CopyWndText(const Wnd* wnd); ///< copies \a wnd as text to clipboard
383 bool PasteFocusWndText(const std::string& text); ///< attempts to paste \a text into the current focus Wnd
384 bool PasteWndText(Wnd* wnd, const std::string& text); ///< attempts to paste \a text into the Wnd \a wnd
385 bool PasteFocusWndClipboardText(); ///< attempts to paste clipboard contents into the current focus Wnd
386 bool CutFocusWndText(); ///< copies current focus Wnd as text to clipboard, then pastes an empty string into that Wnd
387 bool CutWndText(Wnd* wnd); ///< copies \a wnd as text to clipboard, then pastes an empty string to that Wnd
388 bool FocusWndSelectAll(); ///< selects all of anything selectable in the current focus Wnd
389 bool WndSelectAll(Wnd* wnd); ///< selects all of anything selectable in the Wnd \a wnd
390 bool FocusWndDeselect(); ///< deselects anything selected in the current focus Wnd
391 bool WndDeselect(Wnd* wnd); ///< deselects all of anything selectable in the Wnd \a wnd
392
393 bool SetPrevFocusWndInCycle(); ///< sets the focus Wnd to the next INTERACTIVE Wnd in a cycle determined by Wnd parent-child relationships
394 bool SetNextFocusWndInCycle(); ///< sets the focus Wnd to the next in the cycle.
395 //@}
396
397 static GUI* GetGUI(); ///< allows any GG code access to GUI framework by calling GUI::GetGUI()
398
399 /** If \p wnd is visible recursively call PreRenderWindow() on all \p wnd's children and then
400 call \p wnd->PreRender(). The order guarantees that when wnd->PreRender() is called all
401 of \p wnd's children have already been prerendered.*/
402 static void PreRenderWindow(const std::shared_ptr<Wnd>& wnd);
403 static void PreRenderWindow(Wnd* wnd);
404 static void RenderWindow(const std::shared_ptr<Wnd>& wnd); ///< renders a window (if it is visible) and all its visible descendents recursively
405 static void RenderWindow(Wnd* wnd); ///< renders a window (if it is visible) and all its visible descendents recursively
406 virtual void RenderDragDropWnds(); ///< renders Wnds currently being drag-dropped
407
408
409 /** Emitted whenever the GUI's AppWidth() and/or AppHeight() change. */
410 boost::signals2::signal<void (X, Y)> WindowResizedSignal;
411
412 /** Emitted whenever the GUI's window's left and top positions change. */
413 boost::signals2::signal<void (X, Y)> WindowMovedSignal;
414
415 /** Emitted when the Window in which the GUI is operating gains or loses
416 * focus. bool parameter is true when gaining focus, and false otherwise.*/
417 boost::signals2::signal<void (bool)> FocusChangedSignal;
418
419 /** Emitted whenever the window manager requests the window close. */
420 boost::signals2::signal<void ()> WindowClosingSignal;
421
422 /** Emitted whenever the app is requested to close. */
423 boost::signals2::signal<void ()> AppQuittingSignal;
424
425 /** \name Exceptions */ ///@{
426 /** The base class for GUI exceptions. */
427 GG_ABSTRACT_EXCEPTION(Exception);
428
429 /** Thrown when an attempt is made to invoke either of the save- or
430 load-window functions before they have been set. */
431 GG_CONCRETE_EXCEPTION(BadFunctionPointer, GG::GUI, Exception);
432 //@}
433
434 /** Returns a list of resolutions that are supported for full-screen.
435 * The format is [width]x[height] @ [bits per pixel].
436 * This is not a conceptually ideal place for this function, but it needs to be
437 * implemented using the underlying graphics system,
438 * and deriving GUI is the way to connect GiGi to a graphics system, so here it is.
439 */
440 virtual std::vector<std::string> GetSupportedResolutions() const = 0;
441
442 /** Returns the default resolution of the display */
443 virtual Pt GetDefaultResolution(int display_id) const = 0;
444
445 protected:
446 /** \name Structors */ ///@{
447 GUI(const std::string& app_name); ///< protected ctor, called by derived classes
448 //@}
449
450 /** \name Mutators */ ///@{
451 void ProcessBrowseInfo(); ///< determines the current browse info mode, if any
452 /** Allow all windows in the z-list to update data before rendering. */
453 virtual void PreRender();
454 virtual void RenderBegin() = 0; ///< clears the backbuffer, etc.
455 virtual void Render(); ///< renders the windows in the z-list
456 virtual void RenderEnd() = 0; ///< swaps buffers, etc.
457 //@}
458
459 /** Determine if the app has the mouse focus. */
AppHasMouseFocus()460 virtual bool AppHasMouseFocus() const { return true; };
461
462 private:
463 bool ProcessBrowseInfoImpl(Wnd* wnd);
464 std::shared_ptr<Wnd> ModalWindow() const; ///< returns the current modal window, if any
465
466 // Returns the window under \a pt, sending Mouse{Enter|Leave} or
467 // DragDrop{Enter|Leave} as appropriate
468 std::shared_ptr<Wnd> CheckedGetWindowUnder(const Pt& pt, Flags<ModKey> mod_keys);
469
470 static GUI* s_gui;
471 std::unique_ptr<GUIImpl> m_impl;
472
473 friend struct GUIImpl;
474 };
475
476 /** Returns true if lwnd == rwnd or if lwnd contains rwnd */
477 GG_API bool MatchesOrContains(const Wnd* lwnd, const Wnd* rwnd);
478 GG_API bool MatchesOrContains(const std::shared_ptr<Wnd>& lwnd, const Wnd* rwnd);
479 GG_API bool MatchesOrContains(const Wnd* lwnd, const std::shared_ptr<Wnd>& rwnd);
480 GG_API bool MatchesOrContains(const std::shared_ptr<Wnd>& lwnd, const std::shared_ptr<Wnd>& rwnd);
481
482 /* returns the storage value of mod_keys that should be used with keyboard
483 accelerators the accelerators don't care which side of the keyboard you
484 use for CTRL, SHIFT, etc., and whether or not the numlock or capslock are
485 engaged.*/
486 GG_API Flags<ModKey> MassagedAccelModKeys(Flags<ModKey> mod_keys);
487
488
489 // template implementations
490 template <typename InIt>
operator()491 bool GUI::OrCombiner::operator()(InIt first, InIt last) const
492 {
493 bool retval = false;
494 while (first != last)
495 retval |= static_cast<bool>(*first++);
496 return retval;
497 }
498
499 template <typename CharSetIter>
GetFont(const std::string & font_filename,unsigned int pts,CharSetIter first,CharSetIter last)500 std::shared_ptr<Font> GUI::GetFont(const std::string& font_filename, unsigned int pts,
501 CharSetIter first, CharSetIter last)
502 { return GetFontManager().GetFont(font_filename, pts, first, last); }
503
504 template <typename CharSetIter>
GetFont(const std::string & font_filename,unsigned int pts,const std::vector<unsigned char> & file_contents,CharSetIter first,CharSetIter last)505 std::shared_ptr<Font> GUI::GetFont(const std::string& font_filename, unsigned int pts,
506 const std::vector<unsigned char>& file_contents,
507 CharSetIter first, CharSetIter last)
508 { return GetFontManager().GetFont(font_filename, pts, file_contents, first, last); }
509
510 } // namespace GG
511
512 #endif
513