1 /*
2    Copyright (C) 2007 - 2018 by Mark de Wever <koraq@xs4all.nl>
3    Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY.
11 
12    See the COPYING file for more details.
13 */
14 
15 #pragma once
16 
17 #include "gui/core/event/dispatcher.hpp"
18 #include "sdl/point.hpp"
19 #include "gui/widgets/event_executor.hpp"
20 #include "color.hpp"
21 
22 #include <string>
23 
24 class surface;
25 
26 typedef std::map<std::string, t_string> string_map;
27 
28 namespace gui2
29 {
30 
31 struct builder_widget;
32 class window;
33 class grid;
34 
35 namespace iteration
36 {
37 class walker_base;
38 } // namespace iteration
39 
40 /**
41  * Base class for all widgets.
42  *
43  * From this abstract all other widgets should derive. It contains the minimal
44  * info needed for a real widget and some pure abstract functions which need to
45  * be implemented by classes deriving from this class.
46  */
47 class widget : public event_executor, public event::dispatcher
48 {
49 	friend class debug_layout_graph;
50 	friend class window; // needed for modifying the layout_size.
51 
52 
53 	/***** ***** ***** ***** ***** Types. ***** ***** ***** ***** *****/
54 
55 public:
56 	/** Visibility settings done by the user. */
57 	enum class visibility
58 	{
59 		/**
60 		 * The user sets the widget visible, that means:
61 		 * * The widget is visible.
62 		 * * @ref find_at always 'sees' the widget (the active flag is
63 		 *   tested later).
64 		 * * The widget (if active) handles events (and sends events to
65 		 *   its children).
66 		 * * The widget is drawn (and sends the call to
67 		 *   @ref populate_dirty_list to children).
68 		 */
69 		visible,
70 
71 		/**
72 		 * The user sets the widget hidden, that means:
73 		 * * The widget is invisible but keeps its size.
74 		 * * @ref find_at 'sees' the widget if active is @c false.
75 		 * * The widget doesn't handle events (and doesn't send events to
76 		 *   its children).
77 		 * * The widget doesn't add itself @ref window::dirty_list_ when
78 		 *   @ref populate_dirty_list is called (nor does it send the
79 		 *   request to its children).
80 		 */
81 		hidden,
82 
83 		/**
84 		 * The user set the widget invisible, that means:
85 		 * * The widget is invisible and its grid cell has size 0,0.
86 		 * * @ref find_at never 'sees' the widget.
87 		 * * The widget doesn't handle events (and doesn't send events to
88 		 *   its children).
89 		 * * The widget doesn't add itself @ref window::dirty_list_ when
90 		 *   @ref populate_dirty_list is called (nor does it send the
91 		 *   request to its children).
92 		 */
93 		invisible
94 	};
95 
96 	/**
97 	 * Visibility set by the engine.
98 	 *
99 	 * This state only will be used if @ref visible_ is @ref visibility::visible
100 	 * depending on this state the widget might not be visible after all.
101 	 */
102 	enum class redraw_action
103 	{
104 		/**
105 		 * The widget is fully visible.
106 		 *
107 		 * The widget should be drawn if @ref dirty_ is @c true. The entire
108 		 * widget's rectangle should be redrawn.
109 		 */
110 		full,
111 
112 		/**
113 		 * The widget is partly visible.
114 		 *
115 		 * The should be drawn if @ref dirty_ is @c true. The rectangle to
116 		 * redraw in determined by @ref clipping_rectangle_
117 		 */
118 		partly,
119 
120 		/**
121 		 * The widget is not visible.
122 		 *
123 		 * The widget should not be drawn if @ref dirty_ is @c true.
124 		 */
125 		none
126 	};
127 
128 
129 	/***** ***** ***** Constructor and destructor. ***** ***** *****/
130 
131 public:
132 	widget(const widget&) = delete;
133 	widget& operator=(const widget&) = delete;
134 
135 	/** @deprecated use the second overload. */
136 	widget();
137 
138 	/**
139 	 * Constructor.
140 	 *
141 	 * @param builder             The builder object with the settings for the
142 	 *                            object.
143 	 */
144 	explicit widget(const builder_widget& builder);
145 
146 	virtual ~widget() override;
147 
148 
149 	/***** ***** ***** ***** ID functions. ***** ***** ***** *****/
150 
151 public:
152 	/*** *** *** *** *** *** Setters and getters. *** *** *** *** *** ***/
153 
154 	void set_id(const std::string& id);
155 	const std::string& id() const;
156 
157 	/*** *** *** *** *** *** *** *** Members. *** *** *** *** *** *** *** ***/
158 
159 private:
160 	/**
161 	 * The id is the unique name of the widget in a certain context.
162 	 *
163 	 * This is needed for certain widgets so the engine knows which widget is
164 	 * which. E.g. it knows which button is pressed and thus which engine action
165 	 * is connected to the button. This doesn't mean that the id is unique in a
166 	 * window, e.g. a listbox can have the same id for every row.
167 	 */
168 	std::string id_;
169 
170 
171 	/***** ***** ***** ***** Parent functions ***** ***** ***** *****/
172 
173 public:
174 	/**
175 	 * Get the parent window.
176 	 *
177 	 * @returns                   Pointer to parent window.
178 	 * @retval nullptr            No parent window found.
179 	 */
180 	window* get_window();
181 
182 	/** The constant version of @ref get_window. */
183 	const window* get_window() const;
184 
185 	/**
186 	 * Get the parent grid.
187 	 *
188 	 * @returns                 Pointer to parent grid.
189 	 * @retval nullptr          No parent grid found.
190 	 */
191 	grid* get_parent_grid();
192 
193 	/*** *** *** *** *** *** Setters and getters. *** *** *** *** *** ***/
194 
195 	void set_parent(widget* parent);
196 	widget* parent();
197 
198 	/*** *** *** *** *** *** *** *** Members. *** *** *** *** *** *** *** ***/
199 
200 private:
201 	/**
202 	 * The parent widget.
203 	 *
204 	 * If the widget has a parent it contains a pointer to the parent, else it
205 	 * is set to @c nullptr.
206 	 */
207 	widget* parent_;
208 
209 
210 	/***** ***** ***** ***** Size and layout functions. ***** ***** ***** *****/
211 
212 public:
213 	/**
214 	 * How the layout engine works.
215 	 *
216 	 * Every widget has a member @ref layout_size_ which holds the best size in
217 	 * the current layout phase. When the windows starts the layout phase it
218 	 * calls @ref layout_initialize which resets this value.
219 	 *
220 	 * Every widget has two function to get the best size. @ref get_best_size
221 	 * tests whether layout_size_ is set and if so returns that value otherwise
222 	 * it calls @ref calculate_best_size so the size can be updated.
223 	 *
224 	 * During the layout phase some functions can modify layout_size_ so the
225 	 * next call to @ref get_best_size returns the currently best size. This
226 	 * means that after the layout phase @ref get_best_size still returns this
227 	 * value.
228 	 */
229 
230 	/**
231 	 * Initialises the layout phase.
232 	 *
233 	 * Clears the initial best size for the widgets.
234 	 *
235 	 * See @ref layout_algorithm for more information.
236 	 *
237 	 * @param full_initialization For widgets with scrollbars it hides them
238 	 *                            unless the mode is
239 	 *                            @ref scrollbar_mode::ALWAYS_VISIBLE. For
240 	 *                            other widgets this flag is a @em NOP.
241 	 */
242 	virtual void layout_initialize(const bool full_initialization);
243 
244 	/**
245 	 * Tries to reduce the width of a widget.
246 	 *
247 	 * This function tries to do it 'friendly' and only use scrollbars or
248 	 * tries to wrap the widget.
249 	 *
250 	 * See @ref layout_algorithm for more information.
251 	 *
252 	 * @param maximum_width       The wanted maximum width.
253 	 */
254 	virtual void request_reduce_width(const unsigned maximum_width) = 0;
255 
256 	/**
257 	 * Tries to reduce the width of a widget.
258 	 *
259 	 * This function does it more aggressively and should only be used when
260 	 * using scrollbars and wrapping failed.
261 	 *
262 	 * @todo Make pure virtual.
263 	 *
264 	 * See @ref layout_algorithm for more information.
265 	 *
266 	 * @param maximum_width       The wanted maximum width.
267 	 */
268 	virtual void demand_reduce_width(const unsigned maximum_width);
269 
270 	/**
271 	 * Tries to reduce the height of a widget.
272 	 *
273 	 * This function tries to do it 'friendly' and only use scrollbars.
274 	 *
275 	 * @todo Make pure virtual.
276 	 *
277 	 * See @ref layout_algorithm for more information.
278 	 *
279 	 * @param maximum_height      The wanted maximum height.
280 	 */
281 	virtual void request_reduce_height(const unsigned maximum_height);
282 
283 	/**
284 	 * Tries to reduce the height of a widget.
285 	 *
286 	 * This function does it more aggressively and should only be used when
287 	 * using scrollbars failed.
288 	 *
289 	 * @todo Make pure virtual.
290 	 *
291 	 * See @ref layout_algorithm for more information.
292 	 *
293 	 * @param maximum_height      The wanted maximum height.
294 	 */
295 	virtual void demand_reduce_height(const unsigned maximum_height);
296 
297 	/**
298 	 * Gets the best size for the widget.
299 	 *
300 	 * During the layout phase a best size will be determined, several stages
301 	 * might change the best size. This function will return the currently best
302 	 * size as determined during the layout phase.
303 	 *
304 	 * @returns                      The best size for the widget.
305 	 * @retval 0,0                   The best size is 0,0.
306 	 */
307 	point get_best_size() const;
308 
309 private:
310 	/**
311 	 * Calculates the best size.
312 	 *
313 	 * This function calculates the best size and ignores the current values in
314 	 * the layout phase. Note containers can call the @ref get_best_size() of
315 	 * their children since it is meant to update itself.
316 	 *
317 	 * @returns                      The best size for the widget.
318 	 * @retval 0,0                   The best size is 0,0.
319 	 */
320 	virtual point calculate_best_size() const = 0;
321 
322 public:
323 	/**
324 	 * Whether the mouse move/click event go 'through' this widget.
325 	 */
can_mouse_focus() const326 	virtual bool can_mouse_focus() const { return true; }
327 	/**
328 	 * Can the widget wrap.
329 	 *
330 	 * When a widget can wrap it can reduce its width by increasing its
331 	 * height. When a layout is too wide it should first try to wrap and if
332 	 * that fails it should check the vertical scrollbar status. After wrapping
333 	 * the height might (probably will) change so the layout engine needs to
334 	 * recalculate the height after wrapping.
335 	 */
336 	virtual bool can_wrap() const;
337 
338 	/**
339 	 * Sets the origin of the widget.
340 	 *
341 	 * This function can be used to move the widget without dirtying it. The
342 	 * location is an absolute position, if a relative more is required use
343 	 * @ref move.
344 	 *
345 	 *
346 	 * @param origin              The new origin.
347 	 */
348 	virtual void set_origin(const point& origin);
349 
350 	/**
351 	 * Sets the size of the widget.
352 	 *
353 	 * This version is meant to resize a widget, since the origin isn't
354 	 * modified. This can be used if a widget needs to change its size and the
355 	 * layout will be fixed later.
356 	 *
357 	 * @param size                The size of the widget.
358 	 */
359 	virtual void set_size(const point& size);
360 
361 	/**
362 	 * Places the widget.
363 	 *
364 	 * This function is normally called by a layout function to do the
365 	 * placement of a widget.
366 	 *
367 	 * @param origin              The position of top left of the widget.
368 	 * @param size                The size of the widget.
369 	 */
370 	virtual void place(const point& origin, const point& size);
371 
372 	/**
373 	 * Moves a widget.
374 	 *
375 	 * This function can be used to move the widget without dirtying it.
376 	 *
377 	 * @todo Implement the function to all derived classes.
378 	 *
379 	 * @param x_offset            The amount of pixels to move the widget in
380 	 *                            the x-direction.
381 	 * @param y_offset            The amount of pixels to move the widget in
382 	 *                            the y-direction.
383 	 */
384 	virtual void move(const int x_offset, const int y_offset);
385 
386 	/**
387 	 * Sets the horizontal alignment of the widget within its parent grid.
388 	 *
389 	 * @param alignment           The new alignment.
390 	 */
391 	virtual void set_horizontal_alignment(const std::string& alignment);
392 
393 	/**
394 	 * Sets the horizontal alignment of the widget within its parent grid.
395 	 *
396 	 * @param alignment           The new alignment.
397 	 */
398 	virtual void set_vertical_alignment(const std::string& alignment);
399 
400 	/**
401 	 * Allows a widget to update its children.
402 	 *
403 	 * Before the window is populating the dirty list the widgets can update
404 	 * their content, which allows delayed initialization. This delayed
405 	 * initialization is only allowed if the widget resizes itself, not when
406 	 * being placed.
407 	 */
408 	virtual void layout_children();
409 
410 	/**
411 	 * Returns the screen origin of the widget.
412 	 *
413 	 * @returns                   The origin of the widget.
414 	 */
415 	point get_origin() const;
416 
417 	/**
418 	 * Returns the size of the widget.
419 	 *
420 	 * @returns                   The size of the widget.
421 	 */
422 	point get_size() const;
423 
424 	/**
425 	 * Gets the bounding rectangle of the widget on the screen.
426 	 *
427 	 * @returns                   The bounding rectangle of the widget.
428 	 */
429 	SDL_Rect get_rectangle() const;
430 
431 	/*** *** *** *** *** *** Setters and getters. *** *** *** *** *** ***/
432 
433 	int get_x() const;
434 
435 	int get_y() const;
436 
437 	unsigned get_width() const;
438 
439 	unsigned get_height() const;
440 
441 protected:
442 	void set_layout_size(const point& size);
443 	const point& layout_size() const;
444 
445 	/**
446 	* Throws away @ref layout_size_.
447 	*
448 	* Use with care: this function does not recurse to child widgets.
449 	*
450 	* See @ref layout_algorithm for more information.
451 	*/
clear_layout_size()452 	void clear_layout_size() { set_layout_size(point()); }
453 
454 public:
455 	void set_linked_group(const std::string& linked_group);
456 
457 	/*** *** *** *** *** *** *** *** Members. *** *** *** *** *** *** *** ***/
458 
459 private:
460 	/** The x-coordinate of the widget on the screen. */
461 	int x_;
462 
463 	/** The y-coordinate of the widget on the screen. */
464 	int y_;
465 
466 	/** The width of the widget. */
467 	unsigned width_;
468 
469 	/** The height of the widget. */
470 	unsigned height_;
471 
472 	/**
473 	 * The best size for the widget.
474 	 *
475 	 * When 0,0 the real best size is returned, but in the layout phase a
476 	 * wrapping or a scrollbar might change the best size for that widget.
477 	 * This variable holds that best value.
478 	 *
479 	 * If the widget size hasn't been changed from the default that
480 	 * calculate_best_size() returns, layout_size_ is (0,0).
481 	 */
482 	point layout_size_;
483 
484 #ifdef DEBUG_WINDOW_LAYOUT_GRAPHS
485 
486 	/**
487 	 * Debug helper to store last value of get_best_size().
488 	 *
489 	 * We're mutable so calls can stay const and this is disabled in
490 	 * production code.
491 	 */
492 	mutable point last_best_size_;
493 
494 #endif
495 
496 	/**
497 	 * The linked group the widget belongs to.
498 	 *
499 	 * @todo For now the linked group is initialized when the layout of the
500 	 * widget is initialized. The best time to set it would be upon adding the
501 	 * widget in the window. Need to look whether it is possible in a clean way.
502 	 * Maybe a signal just prior to showing a window where the widget can do
503 	 * some of it's on things, would also be nice for widgets that need a
504 	 * finalizer function.
505 	 */
506 	std::string linked_group_;
507 
508 
509 	/***** ***** ***** ***** Drawing functions. ***** ***** ***** *****/
510 
511 public:
512 	/**
513 	 * Calculates the blitting rectangle of the widget.
514 	 *
515 	 * The blitting rectangle is the entire widget rectangle, but offsetted for
516 	 * drawing position.
517 	 *
518 	 * @param x_offset            The offset in the x-direction when drawn.
519 	 * @param y_offset            The offset in the y-direction when drawn.
520 	 *
521 	 * @returns                   The drawing rectangle.
522 	 */
523 	SDL_Rect calculate_blitting_rectangle(const int x_offset,
524 										  const int y_offset);
525 
526 	/**
527 	 * Calculates the clipping rectangle of the widget.
528 	 *
529 	 * The clipping rectangle is used then the @ref redraw_action_ is
530 	 * @ref redraw_action::partly. Since the drawing can be offsetted it also
531 	 * needs offset parameters.
532 	 *
533 	 * @param x_offset            The offset in the x-direction when drawn.
534 	 * @param y_offset            The offset in the y-direction when drawn.
535 	 *
536 	 * @returns                   The clipping rectangle.
537 	 */
538 	SDL_Rect calculate_clipping_rectangle(const int x_offset,
539 										  const int y_offset);
540 
541 	/**
542 	 * Draws the background of a widget.
543 	 *
544 	 * Derived should override @ref impl_draw_background instead of changing
545 	 * this function.
546 	 *
547 	 * @param frame_buffer        The surface to draw upon.
548 	 * @param x_offset            The offset in the x-direction in the
549 	 *                            @p frame_buffer to draw.
550 	 * @param y_offset            The offset in the y-direction in the
551 	 *                            @p frame_buffer to draw.
552 	 */
553 	void draw_background(surface& frame_buffer, int x_offset, int y_offset);
554 
555 	/**
556 	 * Draws the children of a widget.
557 	 *
558 	 * Containers should draw their children when they get this request.
559 	 *
560 	 * Derived should override @ref impl_draw_children instead of changing
561 	 * this function.
562 	 *
563 	 * @param frame_buffer        The surface to draw upon.
564 	 * @param x_offset            The offset in the x-direction in the
565 	 *                            @p frame_buffer to draw.
566 	 * @param y_offset            The offset in the y-direction in the
567 	 *                            @p frame_buffer to draw.
568 	 */
569 	void draw_children(surface& frame_buffer, int x_offset, int y_offset);
570 
571 	/**
572 	 * Draws the foreground of the widget.
573 	 *
574 	 * Some widgets e.g. panel and window have a back and foreground layer this
575 	 * function requests the drawing of the foreground.
576 	 *
577 	 * Derived should override @ref impl_draw_foreground instead of changing
578 	 * this function.
579 	 *
580 	 * @param frame_buffer        The surface to draw upon.
581 	 * @param x_offset            The offset in the x-direction in the
582 	 *                            @p frame_buffer to draw.
583 	 * @param y_offset            The offset in the y-direction in the
584 	 *                            @p frame_buffer to draw.
585 	 */
586 	void draw_foreground(surface& frame_buffer, int x_offset, int y_offset);
587 
588 private:
589 	/** See @ref draw_background. */
impl_draw_background(surface &)590 	virtual void impl_draw_background(surface& /*frame_buffer*/)
591 	{
592 	}
impl_draw_background(surface &,int,int)593 	virtual void impl_draw_background(surface& /*frame_buffer*/
594 									  ,
595 									  int /*x_offset*/
596 									  ,
597 									  int /*y_offset*/)
598 	{
599 	}
600 
601 	/** See @ref draw_children. */
impl_draw_children(surface &,int,int)602 	virtual void impl_draw_children(surface& /*frame_buffer*/
603 									,
604 									int /*x_offset*/
605 									,
606 									int /*y_offset*/)
607 	{
608 	}
609 
610 	/** See @ref draw_foreground. */
impl_draw_foreground(surface &,int,int)611 	virtual void impl_draw_foreground(surface& /*frame_buffer*/
612 									  ,
613 									  int /*x_offset*/
614 									  ,
615 									  int /*y_offset*/)
616 	{
617 	}
618 
619 public:
620 	/**
621 	 * Adds a widget to the dirty list if it is dirty.
622 	 *
623 	 * See @ref window::dirty_list_ for more information regarding the dirty
624 	 * list.
625 	 *
626 	 * If the widget is not dirty and has children it should add itself to the
627 	 * call_stack and call child_populate_dirty_list with the new call_stack.
628 	 *
629 	 * @param caller              The parent window, if dirty it should
630 	 *                            register itself to this window.
631 	 * @param call_stack          The call-stack of widgets traversed to reach
632 	 *                            this function.
633 	 */
634 	void populate_dirty_list(window& caller,
635 							 std::vector<widget*>& call_stack);
636 
637 private:
638 	/**
639 	 * Tries to add all children of a container to the dirty list.
640 	 *
641 	 * @note The function is private since everybody should call
642 	 * @ref populate_dirty_list instead.
643 	 *
644 	 * @param caller              The parent window, if dirty it should
645 	 *                            register itself to this window.
646 	 * @param call_stack          The call-stack of widgets traversed to reach
647 	 *                            this function.
648 	 */
649 	virtual void
650 	child_populate_dirty_list(window& caller,
651 							  const std::vector<widget*>& call_stack);
652 
653 public:
654 	/**
655 	 * Gets the dirty rectangle of the widget.
656 	 *
657 	 * Depending on the @ref redraw_action_ it returns the rectangle this
658 	 * widget dirties while redrawing.
659 	 *
660 	 * @returns                   The dirty rectangle.
661 	 */
662 	SDL_Rect get_dirty_rectangle() const;
663 
664 	/**
665 	 * Sets the visible rectangle for a widget.
666 	 *
667 	 * This function sets the @ref redraw_action_ and the
668 	 * @ref clipping_rectangle_.
669 	 *
670 	 * @param rectangle           The visible rectangle in screen coordinates.
671 	 */
672 	virtual void set_visible_rectangle(const SDL_Rect& rectangle);
673 
674 	/*** *** *** *** *** *** Setters and getters. *** *** *** *** *** ***/
675 
676 	void set_is_dirty(const bool is_dirty);
677 	bool get_is_dirty() const;
678 
679 	void set_visible(const visibility visible);
680 	visibility get_visible() const;
681 
682 	redraw_action get_drawing_action() const;
683 
684 	void set_debug_border_mode(const unsigned debug_border_mode);
685 
686 	void set_debug_border_color(const color_t debug_border_color);
687 
688 	/*** *** *** *** *** *** *** *** Members. *** *** *** *** *** *** *** ***/
689 
690 private:
691 	/**
692 	 * Is the widget dirty?
693 	 *
694 	 * When a widget is dirty it needs to be redrawn at the next drawing cycle.
695 	 *
696 	 * The top-level window will use @ref populate_dirty_list and
697 	 * @ref child_populate_dirty_list to find al dirty widgets, so the widget
698 	 * doesn't need to inform its parent regarding it being marked dirty.
699 	 */
700 	bool is_dirty_;
701 
702 	/** Field for the status of the visibility. */
703 	visibility visible_;
704 
705 	/** Field for the action to do on a drawing request. */
706 	redraw_action redraw_action_;
707 
708 	/** The clipping rectangle if a widget is partly visible. */
709 	SDL_Rect clipping_rectangle_;
710 
711 	/**
712 	 * Mode for drawing the debug border.
713 	 *
714 	 * The debug border is a helper border to determine where a widget is
715 	 * placed. It is only intended for debugging purposes.
716 	 *
717 	 * Possible values:
718 	 * - 0 no border
719 	 * - 1 single pixel border
720 	 * - 2 flood-filled rectangle
721 	 */
722 	unsigned debug_border_mode_;
723 
724 	/** The color for the debug border. */
725 	color_t debug_border_color_;
726 
727 	void draw_debug_border();
728 	void draw_debug_border(int x_offset, int y_offset);
729 
730 	/***** ***** ***** ***** Query functions ***** ***** ***** *****/
731 
732 public:
733 	/**
734 	 * Returns the widget at the wanted coordinates.
735 	 *
736 	 * @param coordinate          The coordinate which should be inside the
737 	 *                            widget.
738 	 * @param must_be_active      The widget should be active, not all widgets
739 	 *                            have an active flag, those who don't ignore
740 	 *                            flag.
741 	 *
742 	 * @returns                   The widget with the id.
743 	 * @retval nullptr               No widget at the wanted coordinate found (or
744 	 *                            not active if must_be_active was set).
745 	 */
746 	virtual widget* find_at(const point& coordinate,
747 							 const bool must_be_active);
748 
749 	/** The constant version of @ref find_at. */
750 	virtual const widget* find_at(const point& coordinate,
751 								   const bool must_be_active) const;
752 
753 	/**
754 	 * Returns @em a widget with the wanted id.
755 	 *
756 	 * @note Since the id might not be unique inside a container there is no
757 	 * guarantee which widget is returned.
758 	 *
759 	 * @param id                  The id of the widget to find.
760 	 * @param must_be_active      The widget should be active, not all widgets
761 	 *                            have an active flag, those who don't ignore
762 	 *                            flag.
763 	 *
764 	 * @returns                   The widget with the id.
765 	 * @retval nullptr               No widget with the id found (or not active if
766 	 *                            must_be_active was set).
767 	 */
768 	virtual widget* find(const std::string& id, const bool must_be_active);
769 
770 	/** The constant version of @ref find. */
771 	virtual const widget* find(const std::string& id,
772 								const bool must_be_active) const;
773 
774 	/**
775 	 * Does the widget contain the widget.
776 	 *
777 	 * Widgets can be containers which have more widgets inside them, this
778 	 * function will traverse in those child widgets and tries to find the
779 	 * wanted widget.
780 	 *
781 	 * @param widget              Pointer to the widget to find.
782 	 *
783 	 * @returns                   Whether or not the @p widget was found.
784 	 */
785 	virtual bool has_widget(const widget& widget) const;
786 
787 private:
788 	/** See @ref event::dispatcher::is_at. */
789 	virtual bool is_at(const point& coordinate) const override;
790 
791 	/**
792 	 * Is the coordinate inside our area.
793 	 *
794 	 * Helper for find_at so also looks at our visibility.
795 	 *
796 	 * @param coordinate          The coordinate which should be inside the
797 	 *                            widget.
798 	 * @param must_be_active      The widget should be active, not all widgets
799 	 *                            have an active flag, those who don't ignore
800 	 *                            flag.
801 	 *
802 	 * @returns                   Status.
803 	 */
804 	bool is_at(const point& coordinate, const bool must_be_active) const;
805 
806 	/**
807 	 * Is the widget and every single one of its parents visible?
808 	 *
809 	 * @param widget              Widget where to start the check.
810 	 * @param must_be_active      The widget should be active, not all widgets
811 	 *                            have an active flag, those who don't ignore
812 	 *                            flag.
813 	 *
814 	 * @returns                   Status.
815 	 */
816 	bool recursive_is_visible(const widget* widget, const bool must_be_active) const;
817 
818 	/***** ***** ***** ***** Miscellaneous ***** ***** ****** *****/
819 
820 public:
821 	/** Does the widget disable easy close? */
822 	virtual bool disable_click_dismiss() const = 0;
823 
824 	/** Creates a new walker object on the heap. */
825 	virtual iteration::walker_base* create_walker() = 0;
826 };
827 
828 } // namespace gui2
829