The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
toggle_button.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2008 - 2025
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#define GETTEXT_DOMAIN "wesnoth-lib"
17
19
23#include "gui/core/log.hpp"
25#include "sound.hpp"
26#include "wml_exception.hpp"
27
28#include <functional>
29
30#define LOG_SCOPE_HEADER get_control_type() + " [" + id() + "] " + __func__
31#define LOG_HEADER LOG_SCOPE_HEADER + ':'
32
33namespace gui2
34{
35
36// ------------ WIDGET -----------{
37
38REGISTER_WIDGET(toggle_button)
39
40toggle_button::toggle_button(const implementation::builder_toggle_button& builder)
41 : styled_widget(builder, type())
42 , state_(ENABLED)
43 , state_num_(0)
44 , retval_(retval::NONE)
45 , icon_name_(builder.icon_name)
46{
47 connect_signal<event::MOUSE_ENTER>(std::bind(
48 &toggle_button::signal_handler_mouse_enter, this, std::placeholders::_2, std::placeholders::_3));
49 connect_signal<event::MOUSE_LEAVE>(std::bind(
50 &toggle_button::signal_handler_mouse_leave, this, std::placeholders::_2, std::placeholders::_3));
51
52 connect_signal<event::LEFT_BUTTON_CLICK>(std::bind(
53 &toggle_button::signal_handler_left_button_click, this, std::placeholders::_2, std::placeholders::_3));
54 connect_signal<event::LEFT_BUTTON_DOUBLE_CLICK>(std::bind(
56 this,
57 std::placeholders::_2,
58 std::placeholders::_3));
59}
60
62{
63 std::div_t res = std::div(this->get_config()->state.size(), COUNT);
64 assert(res.rem == 0);
65 assert(res.quot > 0);
66 return res.quot;
67}
68
70{
71 // Inherit
73
74 widget_item::const_iterator itor = data.find("icon");
75 if(itor != data.end()) {
76 set_icon_name(itor->second);
77 }
78}
79
80void toggle_button::set_active(const bool active)
81{
82 if(active) {
84 } else {
86 }
87}
88
90{
91 return state_ != DISABLED;
92}
93
95{
96 return state_ + COUNT * state_num_;
97}
98
100{
101 // Inherit.
103
104 // set icon in canvases
105 std::vector<canvas>& canvases = styled_widget::get_canvases();
106 for(auto & canvas : canvases)
107 {
109 }
110
111 queue_redraw();
112}
113
114void toggle_button::set_value(unsigned selected, bool fire_event)
115{
116 selected = selected % num_states();
117 if(selected == get_value()) {
118 return;
119 }
120 state_num_ = selected;
121 queue_redraw();
122
123 // Check for get_window() is here to prevent the callback from
124 // being called when the initial value is set.
125 if(!get_window()) {
126 return;
127 }
128 if (fire_event) {
129 fire(event::NOTIFY_MODIFIED, *this, nullptr);
130 }
131}
132
134{
135 if(retval == retval_) {
136 return;
137 }
138
139 retval_ = retval;
141}
142
144{
145 if(state != state_) {
146 state_ = state;
147 queue_redraw();
148 }
149}
150
152 bool& handled)
153{
154 DBG_GUI_E << LOG_HEADER << ' ' << event << ".";
156 handled = true;
157}
158
160 bool& handled)
161{
162 DBG_GUI_E << LOG_HEADER << ' ' << event << ".";
164 handled = true;
165}
166
168 bool& handled)
169{
170 DBG_GUI_E << LOG_HEADER << ' ' << event << ".";
171
173
174 set_value(get_value() + 1, true);
175
176 handled = true;
177}
178
180 const event::ui_event event, bool& handled)
181{
182 DBG_GUI_E << LOG_HEADER << ' ' << event << ".";
183
184 if(retval_ == retval::NONE) {
185 return;
186 }
187
189 assert(window);
190
192
193 handled = true;
194}
195
196// }---------- DEFINITION ---------{
197
200{
201 DBG_GUI_P << "Parsing toggle button " << id;
202
203 load_resolutions<resolution>(cfg);
204}
205
208{
209 // Note the order should be the same as the enum state_t in
210 // toggle_button.hpp.
211 for(const auto& c : cfg.child_range("state"))
212 {
213 state.emplace_back(VALIDATE_WML_CHILD(c, "enabled", missing_mandatory_wml_tag("toggle_button_definition][resolution][state", "enabled")));
214 state.emplace_back(VALIDATE_WML_CHILD(c, "disabled", missing_mandatory_wml_tag("toggle_button_definition][resolution][state", "disabled")));
215 state.emplace_back(VALIDATE_WML_CHILD(c, "focused", missing_mandatory_wml_tag("toggle_button_definition][resolution][state", "focused")));
216 }
217}
218
219// }---------- BUILDER -----------{
220
221namespace implementation
222{
223
224builder_toggle_button::builder_toggle_button(const config& cfg)
226 , icon_name(cfg["icon"])
227 , retval_id_(cfg["return_value_id"])
228 , retval_(cfg["return_value"].to_int())
229{
230}
231
232std::unique_ptr<widget> builder_toggle_button::build() const
233{
234 auto widget = std::make_unique<toggle_button>(*this);
235
236 widget->set_retval(get_retval(retval_id_, retval_, id));
237
238 DBG_GUI_G << "Window builder: placed toggle button '" << id
239 << "' with definition '" << definition << "'.";
240
241 return widget;
242}
243
244} // namespace implementation
245
246// }------------ END --------------
247
248} // namespace gui2
A config object defines a single node in a WML file, with access to child nodes.
Definition config.hpp:157
child_itors child_range(std::string_view key)
Definition config.cpp:268
A simple canvas which can be drawn upon.
Definition canvas.hpp:45
void set_variable(const std::string &key, wfl::variant &&value)
Definition canvas.hpp:165
bool fire(const ui_event event, widget &target)
Fires an event which has no extra parameters.
void set_wants_mouse_left_double_click(const bool click=true)
virtual void update_canvas()
Updates the canvas(ses).
virtual void set_members(const widget_item &data)
Sets the members of the styled_widget.
std::vector< canvas > & get_canvases()
resolution_definition_ptr get_config()
void set_state(const state_t state)
virtual void set_value(unsigned selected, bool fire_event=false) override
Inherited from selectable_item.
void signal_handler_mouse_enter(const event::ui_event event, bool &handled)
void signal_handler_mouse_leave(const event::ui_event event, bool &handled)
virtual void set_active(const bool active) override
See styled_widget::set_active.
virtual unsigned get_state() const override
See styled_widget::get_state.
void set_members(const widget_item &data) override
See styled_widget::set_members.
unsigned state_num_
Usually 1 for selected and 0 for not selected, can also have higher values in tristate buttons.
state_t
Possible states of the widget.
virtual void update_canvas() override
Inherited from styled_widget.
virtual unsigned get_value() const override
Inherited from selectable_item.
void signal_handler_left_button_click(const event::ui_event event, bool &handled)
std::string icon_name_
The toggle button can contain an icon next to the text.
int retval_
The return value of the button.
void signal_handler_left_button_double_click(const event::ui_event event, bool &handled)
virtual unsigned num_states() const override
Inherited from selectable_item.
void set_retval(const int retval)
virtual bool get_active() const override
See styled_widget::get_active.
state_t state_
Current state of the widget.
void set_icon_name(const std::string &icon_name)
Base class for all widgets.
Definition widget.hpp:55
void queue_redraw()
Indicates that this widget should be redrawn.
Definition widget.cpp:464
window * get_window()
Get the parent window.
Definition widget.cpp:117
base class of top level items, the only item which needs to store the final canvases to draw on.
Definition window.hpp:59
void set_retval(const int retval, const bool close_window=true)
Sets there return value of the window.
Definition window.hpp:387
#define LOG_HEADER
const config * cfg
Define the common log macros for the gui toolkit.
#define DBG_GUI_G
Definition log.hpp:41
#define DBG_GUI_P
Definition log.hpp:66
#define DBG_GUI_E
Definition log.hpp:35
This file contains the window object, this object is a top level container which has the event manage...
ui_event
The event sent to the dispatcher.
Definition handler.hpp:115
int get_retval(const std::string &retval_id, const int retval, const std::string &id)
Returns the return value for a widget.
Definition helper.cpp:137
std::string sound_toggle_button_click
Definition settings.cpp:51
Generic file dialog.
std::map< std::string, t_string > widget_item
Definition widget.hpp:33
retval
Default window/dialog return values.
Definition retval.hpp:30
@ NONE
Default, unset return value.
Definition retval.hpp:32
Contains the implementation details for lexical_cast and shouldn't be used directly.
void play_UI_sound(const std::string &files)
Definition sound.cpp:1009
std::string_view data
Definition picture.cpp:188
#define REGISTER_WIDGET(id)
Wrapper for REGISTER_WIDGET3.
This file contains the settings handling of the widget library.
std::string definition
Parameters for the styled_widget.
virtual std::unique_ptr< widget > build() const override
std::vector< state_definition > state
toggle_button_definition(const config &cfg)
std::string missing_mandatory_wml_tag(const std::string &section, const std::string &tag)
Returns a standard message for a missing wml child (tag).
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
#define VALIDATE_WML_CHILD(cfg, key, message)
#define c