The Battle for Wesnoth  1.19.0-dev
find_widget.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2007 - 2024
3  by Mark de Wever <koraq@xs4all.nl>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #pragma once
17 
18 #include "gui/widgets/helper.hpp"
19 #include "gui/widgets/widget.hpp"
20 #include "utils/const_clone.hpp"
21 #include "wml_exception.hpp"
22 
23 namespace gui2
24 {
25 
26 /**
27  * Returns the first parent of a widget with a certain type.
28  *
29  * @param child The widget to get the parent from,
30  * @tparam T The class of the widget to return.
31  *
32  * @returns The parent widget.
33  */
34 template <class T>
35 T& get_parent(widget& child)
36 {
37  T* result;
38  widget* w = &child;
39  do {
40  w = w->parent();
41  result = dynamic_cast<T*>(w);
42 
43  } while(w && !result);
44 
45  assert(result);
46  return *result;
47 }
48 
49 /**
50  * Gets a widget with the wanted id.
51  *
52  * This template function doesn't return a pointer to a generic widget but
53  * returns the wanted type and tests for its existence if required.
54  *
55  * @param widget The widget test or find a child with the wanted
56  * id.
57  * @param id The id of the widget to find.
58  * @param must_be_active The widget should be active, not all widgets
59  * have an active flag, those who don't ignore
60  * flag.
61  * @param must_exist The widget should be exist, the function will
62  * fail if the widget doesn't exist or is
63  * inactive and must be active. Upon failure a
64  * wml_error is thrown.
65  *
66  * @returns The widget with the id.
67  */
68 template <class T>
70  const std::string& id,
71  const bool must_be_active,
72  const bool must_exist)
73 {
74  T* result = dynamic_cast<T*>(widget->find(id, must_be_active));
75  VALIDATE(!must_exist || result, missing_widget(id));
76 
77  return result;
78 }
79 
80 /**
81  * Gets a widget with the wanted id.
82  *
83  * This template function doesn't return a reference to a generic widget but
84  * returns a reference to the wanted type
85  *
86  * @param widget The widget test or find a child with the wanted
87  * id.
88  * @param id The id of the widget to find.
89  * @param must_be_active The widget should be active, not all widgets
90  * have an active flag, those who don't ignore
91  * flag.
92  *
93  * @returns The widget with the id.
94  */
95 template <class T>
97  const std::string& id,
98  const bool must_be_active)
99 {
100  return *find_widget<T>(widget, id, must_be_active, true);
101 }
102 
103 template<typename T>
104 void on_widget(utils::const_clone_ptr<widget, T> parent, const std::string& id, std::function<void(T&)> func)
105 {
106  if(auto widget = find_widget<T>(parent, id, false, false)) {
107  func(*widget);
108  }
109 }
110 } // namespace gui2
Base class for all widgets.
Definition: widget.hpp:53
virtual widget * find(const std::string &id, const bool must_be_active)
Returns a widget with the wanted id.
Definition: widget.cpp:555
int w
Generic file dialog.
T & get_parent(widget &child)
Returns the first parent of a widget with a certain type.
Definition: find_widget.hpp:35
t_string missing_widget(const std::string &id)
Returns a default error message if a mandatory widget is omitted.
Definition: helper.cpp:89
void on_widget(utils::const_clone_ptr< widget, T > parent, const std::string &id, std::function< void(T &)> func)
T * find_widget(utils::const_clone_ptr< widget, T > widget, const std::string &id, const bool must_be_active, const bool must_exist)
Gets a widget with the wanted id.
Definition: find_widget.hpp:69
typename const_clone< D, S >::pointer const_clone_ptr
Definition: const_clone.hpp:66
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
#define VALIDATE(cond, message)
The macro to use for the validation of WML.