The Battle for Wesnoth  1.17.0-dev
toggle_button.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2021
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 
21 #include "gui/widgets/settings.hpp"
22 #include "gui/widgets/window.hpp"
23 #include "gui/core/log.hpp"
25 #include "sound.hpp"
26 
27 #include <functional>
28 
29 #define LOG_SCOPE_HEADER get_control_type() + " [" + id() + "] " + __func__
30 #define LOG_HEADER LOG_SCOPE_HEADER + ':'
31 
32 namespace gui2
33 {
34 
35 // ------------ WIDGET -----------{
36 
37 REGISTER_WIDGET(toggle_button)
38 
39 toggle_button::toggle_button(const implementation::builder_toggle_button& builder)
40  : styled_widget(builder, type())
41  , state_(ENABLED)
42  , state_num_(0)
43  , retval_(retval::NONE)
44  , icon_name_()
45 {
46  connect_signal<event::MOUSE_ENTER>(std::bind(
47  &toggle_button::signal_handler_mouse_enter, this, std::placeholders::_2, std::placeholders::_3));
48  connect_signal<event::MOUSE_LEAVE>(std::bind(
49  &toggle_button::signal_handler_mouse_leave, this, std::placeholders::_2, std::placeholders::_3));
50 
51  connect_signal<event::LEFT_BUTTON_CLICK>(std::bind(
52  &toggle_button::signal_handler_left_button_click, this, std::placeholders::_2, std::placeholders::_3));
53  connect_signal<event::LEFT_BUTTON_DOUBLE_CLICK>(std::bind(
55  this,
56  std::placeholders::_2,
57  std::placeholders::_3));
58 }
59 
60 unsigned toggle_button::num_states() const
61 {
62  std::div_t res = std::div(this->config()->state.size(), COUNT);
63  assert(res.rem == 0);
64  assert(res.quot > 0);
65  return res.quot;
66 }
67 
69 {
70  // Inherit
72 
73  string_map::const_iterator itor = data.find("icon");
74  if(itor != data.end()) {
75  set_icon_name(itor->second);
76  }
77 }
78 
79 void toggle_button::set_active(const bool active)
80 {
81  if(active) {
83  } else {
85  }
86 }
87 
89 {
90  return state_ != DISABLED;
91 }
92 
93 unsigned toggle_button::get_state() const
94 {
95  return state_ + COUNT * state_num_;
96 }
97 
99 {
100  // Inherit.
102 
103  // set icon in canvases
104  std::vector<canvas>& canvases = styled_widget::get_canvases();
105  for(auto & canvas : canvases)
106  {
108  }
109 
110  set_is_dirty(true);
111 }
112 
114 {
115  selected = selected % num_states();
116  if(selected == get_value()) {
117  return;
118  }
120  set_is_dirty(true);
121 
122  // Check for get_window() is here to prevent the callback from
123  // being called when the initial value is set.
124  if(!get_window()) {
125  return;
126  }
127  if (fire_event) {
128  fire(event::NOTIFY_MODIFIED, *this, nullptr);
129  }
130 }
131 
133 {
134  if(retval == retval_) {
135  return;
136  }
137 
138  retval_ = retval;
140 }
141 
143 {
144  if(state != state_) {
145  state_ = state;
146  set_is_dirty(true);
147  }
148 }
149 
151  bool& handled)
152 {
153  DBG_GUI_E << LOG_HEADER << ' ' << event << ".\n";
155  handled = true;
156 }
157 
159  bool& handled)
160 {
161  DBG_GUI_E << LOG_HEADER << ' ' << event << ".\n";
163  handled = true;
164 }
165 
167  bool& handled)
168 {
169  DBG_GUI_E << LOG_HEADER << ' ' << event << ".\n";
170 
172 
173  set_value(get_value() + 1, true);
174 
175  handled = true;
176 }
177 
179  const event::ui_event event, bool& handled)
180 {
181  DBG_GUI_E << LOG_HEADER << ' ' << event << ".\n";
182 
183  if(retval_ == retval::NONE) {
184  return;
185  }
186 
187  window* window = get_window();
188  assert(window);
189 
190  window->set_retval(retval_);
191 
192  handled = true;
193 }
194 
195 // }---------- DEFINITION ---------{
196 
199 {
200  DBG_GUI_P << "Parsing toggle button " << id << '\n';
201 
202  load_resolutions<resolution>(cfg);
203 }
204 
206  : resolution_definition(cfg)
207 {
208  // Note the order should be the same as the enum state_t in
209  // toggle_button.hpp.
210  for(const auto& c : cfg.child_range("state"))
211  {
212  state.emplace_back(c.child("enabled"));
213  state.emplace_back(c.child("disabled"));
214  state.emplace_back(c.child("focused"));
215  }
216 }
217 
218 // }---------- BUILDER -----------{
219 
220 namespace implementation
221 {
222 
223 builder_toggle_button::builder_toggle_button(const config& cfg)
224  : builder_styled_widget(cfg)
225  , icon_name_(cfg["icon"])
226  , retval_id_(cfg["return_value_id"])
227  , retval_(cfg["return_value"])
228 {
229 }
230 
232 {
233  toggle_button* widget = new toggle_button(*this);
234 
235  widget->set_icon_name(icon_name_);
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 << "'.\n";
240 
241  return widget;
242 }
243 
244 } // namespace implementation
245 
246 // }------------ END --------------
247 
248 } // namespace gui2
Define the common log macros for the gui toolkit.
Base class of a resolution, contains the common keys for a resolution.
#define DBG_GUI_P
Definition: log.hpp:66
virtual void set_value(unsigned selected, bool fire_event=false) override
Inherited from selectable_item.
std::vector< state_definition > state
virtual unsigned num_states() const override
Inherited from selectable_item.
void signal_handler_mouse_enter(const event::ui_event event, bool &handled)
virtual void update_canvas() override
Inherited from styled_widget.
void set_variable(const std::string &key, wfl::variant &&value)
Definition: canvas.hpp:168
void signal_handler_left_button_double_click(const event::ui_event event, bool &handled)
virtual void set_members(const string_map &data)
Sets the members of the styled_widget.
void set_state(const state_t state)
This file contains the window object, this object is a top level container which has the event manage...
child_itors child_range(config_key_type key)
Definition: config.cpp:344
Base class for all widgets.
Definition: widget.hpp:49
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
void set_retval(const int retval)
virtual unsigned get_state() const override
See styled_widget::get_state.
state_t state_
Current state of the widget.
Generic file dialog.
Definition: field-fwd.hpp:23
Sent by a widget to notify others its contents or state are modified.
Definition: handler.hpp:89
void signal_handler_left_button_click(const event::ui_event event, bool &handled)
state_t
Possible states of the widget.
std::string definition
Parameters for the styled_widget.
virtual bool get_active() const override
See styled_widget::get_active.
This file contains the settings handling of the widget library.
void set_members(const string_map &data) override
See styled_widget::set_members.
void set_is_dirty(const bool is_dirty)
Definition: widget.cpp:466
std::string selected
virtual void update_canvas()
Updates the canvas(ses).
std::vector< canvas > & get_canvases()
void set_wants_mouse_left_double_click(const bool click=true)
void signal_handler_mouse_leave(const event::ui_event event, bool &handled)
toggle_button_definition(const config &cfg)
#define REGISTER_WIDGET(id)
Wrapper for REGISTER_WIDGET3.
A simple canvas which can be drawn upon.
Definition: canvas.hpp:42
resolution_definition_ptr config()
bool fire_event(const ui_event event, std::vector< std::pair< widget *, ui_event >> &event_chain, widget *dispatcher, widget *w, F &&... params)
Helper function for fire_event.
unsigned state_num_
Usually 1 for selected and 0 for not selected, can also have higher values in tristate buttons...
#define DBG_GUI_E
Definition: log.hpp:35
Default, unset return value.
Definition: retval.hpp:32
window * get_window()
Get the parent window.
Definition: widget.cpp:117
#define LOG_HEADER
std::string icon_name_
The toggle button can contain an icon next to the text.
std::map< std::string, t_string > string_map
Definition: widget.hpp:26
void set_retval(const int retval, const bool close_window=true)
Sets there return value of the window.
Definition: window.hpp:358
Base class for all visible items.
int retval_
The return value of the button.
void play_UI_sound(const std::string &files)
Definition: sound.cpp:1052
bool fire(const ui_event event, widget &target)
Fires an event which has no extra parameters.
Definition: dispatcher.cpp:69
retval
Default window/dialog return values.
Definition: retval.hpp:29
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:61
virtual widget * build() const override
mock_char c
std::string sound_toggle_button_click
Definition: settings.cpp:44
base class of top level items, the only item which needs to store the final canvases to draw on...
Definition: window.hpp:65
#define DBG_GUI_G
Definition: log.hpp:41
Class for a toggle button.
Contains the implementation details for lexical_cast and shouldn&#39;t be used directly.
ui_event
The event send to the dispatcher.
Definition: handler.hpp:48
virtual unsigned get_value() const override
Inherited from selectable_item.
virtual void set_active(const bool active) override
See styled_widget::set_active.
void set_icon_name(const std::string &icon_name)