The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
status_label_helper.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2010 - 2025
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 "gettext.hpp"
22
23#include <functional>
24
25namespace gui2
26{
27namespace implementation
28{
29template<typename T>
31{
32 // Menu Buttons
33 if constexpr(std::is_same_v<menu_button, T>) {
34 return w.get_value_string();
35 }
36
37 // Selectable widgets (like toggle buttons)
38 if constexpr(std::is_base_of_v<selectable_item, T>) {
39 return w.get_value_bool() ? _("yes") : _("no");
40 }
41
42 // Sliders
43 if constexpr(std::is_same_v<slider, T>) {
44 return w.get_value_label();
45 }
46
47 return w.get_label();
48}
49
50/**
51 * Searches for the status target, starting with the source widget's parent.
52 * and walking backwards up the parent tree until the target is found.
53 *
54 * @todo this is a more powerful version of find_widget. Investigate whether
55 * we want this behavior exposed more broadly.
56 */
57inline auto& find_target(std::string_view target_id, widget& source)
58{
59 widget* parent = source.parent();
60 widget* target = nullptr;
61
62 while(parent) {
63 target = parent->find(target_id, false);
64 parent = parent->parent();
65
66 if(target) {
67 break;
68 }
69 }
70
71 VALIDATE(target, missing_widget(std::string(target_id)));
72 return dynamic_cast<styled_widget&>(*target);
73}
74
75/** Returns the dereferenced target pointer if valid, else the default target. */
76inline auto& validate_target(styled_widget* target, widget& source)
77{
78 if(target) {
79 return *target;
80 }
81
82 return find_target(source.id() + "_label", source);
83}
84
85} // namespace implementation
86
87/**
88 * Binds a given target widget to reflect another widget's label.
89 *
90 * The initial status label value will be set here and updated whenever the source
91 * widget is modified (specifically, when a NOTIFY_MODIFIED event is fired).
92 *
93 * @param source The widget whose value will be represented in the target.
94 * @param value_getter Functor to process the value of the source widget.
95 * The expected signature is [](const W&) -> [t_]string.
96 * @param target_ptr Pointer to the status widget. If no target is specified,
97 * the default with ID [sourceID + "_label"] will be used.
98 */
99template<typename W, typename F>
100void bind_status_label(W& source, const F& value_getter, styled_widget* target_ptr = nullptr)
101{
102 // Get fallback if necessary.
103 styled_widget& target = implementation::validate_target(target_ptr, source);
104
105 connect_signal_notify_modified(source,
106 [&, value_getter](auto&&...) { target.set_label(value_getter(source)); });
107
108 // Set initial value.
109 source.fire(event::NOTIFY_MODIFIED, source, nullptr);
110}
111
112/**
113 * Binds a status label using the default value getter and default target ID.
114 */
115template<typename W>
117{
118 bind_status_label(source, implementation::get_status_label<W>, nullptr);
119}
120
121/**
122 * Binds a status label using the default value getter and the given ID.
123 */
124template<typename W>
125void bind_default_status_label(W& source, std::string_view target_id)
126{
127 auto& target = implementation::find_target(target_id, source);
128 bind_status_label(source, implementation::get_status_label<W>, &target);
129}
130
131} // namespace gui2
virtual void set_label(const t_string &text)
Base class for all widgets.
Definition widget.hpp:55
virtual widget * find(const std::string_view id, const bool must_be_active)
Returns a widget with the wanted id.
Definition widget.cpp:560
const std::string & id() const
Definition widget.cpp:110
widget * parent()
Definition widget.cpp:170
static std::string _(const char *str)
Definition gettext.hpp:100
t_string get_status_label(const T &w)
auto & validate_target(styled_widget *target, widget &source)
Returns the dereferenced target pointer if valid, else the default target.
auto & find_target(std::string_view target_id, widget &source)
Searches for the status target, starting with the source widget's parent.
Generic file dialog.
void bind_default_status_label(W &source)
Binds a status label using the default value getter and default target ID.
t_string missing_widget(const std::string &id)
Returns a default error message if a mandatory widget is omitted.
Definition helper.cpp:145
void bind_status_label(W &source, const F &value_getter, styled_widget *target_ptr=nullptr)
Binds a given target widget to reflect another widget's label.
Contains the implementation details for lexical_cast and shouldn't be used directly.
int w
Definition pathfind.cpp:188
#define VALIDATE(cond, message)
The macro to use for the validation of WML.