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/widgets/helper.hpp"
18 #include "gui/widgets/widget.hpp"
19 #include "utils/const_clone.hpp"
20 #include "wml_exception.hpp"
21 
22 namespace gui2
23 {
24 
25 /**
26  * Returns the first parent of a widget with a certain type.
27  *
28  * @param child                   The widget to get the parent from,
29  * @tparam T                      The class of the widget to return.
30  *
31  * @returns                       The parent widget.
32  */
33 template <class T>
get_parent(widget & child)34 T& get_parent(widget& child)
35 {
36 	T* result;
37 	widget* w = &child;
38 	do {
39 		w = w->parent();
40 		result = dynamic_cast<T*>(w);
41 
42 	} while(w && !result);
43 
44 	assert(result);
45 	return *result;
46 }
47 
48 /**
49  * Gets a widget with the wanted id.
50  *
51  * This template function doesn't return a pointer to a generic widget but
52  * returns the wanted type and tests for its existence if required.
53  *
54  * @param widget              The widget test or find a child with the wanted
55  *                            id.
56  * @param id                  The id of the widget to find.
57  * @param must_be_active      The widget should be active, not all widgets
58  *                            have an active flag, those who don't ignore
59  *                            flag.
60  * @param must_exist          The widget should be exist, the function will
61  *                            fail if the widget doesn't exist or is
62  *                            inactive and must be active. Upon failure a
63  *                            wml_error is thrown.
64  *
65  * @returns                   The widget with the id.
66  */
67 template <class T>
find_widget(utils::const_clone_ptr<widget,T> widget,const std::string & id,const bool must_be_active,const bool must_exist)68 T* find_widget(utils::const_clone_ptr<widget, T> widget,
69 			   const std::string& id,
70 			   const bool must_be_active,
71 			   const bool must_exist)
72 {
73 	T* result = dynamic_cast<T*>(widget->find(id, must_be_active));
74 	VALIDATE(!must_exist || result, missing_widget(id));
75 
76 	return result;
77 }
78 
79 /**
80  * Gets a widget with the wanted id.
81  *
82  * This template function doesn't return a reference to a generic widget but
83  * returns a reference to the wanted type
84  *
85  * @param widget              The widget test or find a child with the wanted
86  *                            id.
87  * @param id                  The id of the widget to find.
88  * @param must_be_active      The widget should be active, not all widgets
89  *                            have an active flag, those who don't ignore
90  *                            flag.
91  *
92  * @returns                   The widget with the id.
93  */
94 template <class T>
find_widget(utils::const_clone_ptr<widget,T> widget,const std::string & id,const bool must_be_active)95 T& find_widget(utils::const_clone_ptr<widget, T> widget,
96 			   const std::string& id,
97 			   const bool must_be_active)
98 {
99 	return *find_widget<T>(widget, id, must_be_active, true);
100 }
101 
102 } // namespace gui2
103