The Battle for Wesnoth  1.15.2+dev
toggle_button.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 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 #define GETTEXT_DOMAIN "wesnoth-lib"
16 
18 
20 #include "gui/widgets/settings.hpp"
21 #include "gui/widgets/window.hpp"
22 #include "gui/core/log.hpp"
24 #include "sound.hpp"
25 
26 #include "utils/functional.hpp"
27 
28 #define LOG_SCOPE_HEADER get_control_type() + " [" + id() + "] " + __func__
29 #define LOG_HEADER LOG_SCOPE_HEADER + ':'
30 
31 namespace gui2
32 {
33 
34 // ------------ WIDGET -----------{
35 
36 REGISTER_WIDGET(toggle_button)
37 
38 toggle_button::toggle_button(const implementation::builder_toggle_button& builder)
39  : styled_widget(builder, type())
40  , state_(ENABLED)
41  , state_num_(0)
42  , retval_(retval::NONE)
43  , icon_name_()
44 {
45  connect_signal<event::MOUSE_ENTER>(std::bind(
47  connect_signal<event::MOUSE_LEAVE>(std::bind(
49 
50  connect_signal<event::LEFT_BUTTON_CLICK>(std::bind(
52  connect_signal<event::LEFT_BUTTON_DOUBLE_CLICK>(std::bind(
54  this,
55  _2,
56  _3));
57 }
58 
59 unsigned toggle_button::num_states() const
60 {
61  std::div_t res = std::div(this->config()->state.size(), COUNT);
62  assert(res.rem == 0);
63  assert(res.quot > 0);
64  return res.quot;
65 }
66 
68 {
69  // Inherit
71 
72  string_map::const_iterator itor = data.find("icon");
73  if(itor != data.end()) {
74  set_icon_name(itor->second);
75  }
76 }
77 
78 void toggle_button::set_active(const bool active)
79 {
80  if(active) {
82  } else {
84  }
85 }
86 
88 {
89  return state_ != DISABLED;
90 }
91 
92 unsigned toggle_button::get_state() const
93 {
94  return state_ + COUNT * state_num_;
95 }
96 
98 {
99  // Inherit.
101 
102  // set icon in canvases
103  std::vector<canvas>& canvases = styled_widget::get_canvases();
104  for(auto & canvas : canvases)
105  {
107  }
108 
109  set_is_dirty(true);
110 }
111 
113 {
114  selected = selected % num_states();
115  if(selected == get_value()) {
116  return;
117  }
119  set_is_dirty(true);
120 
121  // Check for get_window() is here to prevent the callback from
122  // being called when the initial value is set.
123  if(!get_window()) {
124  return;
125  }
126  if (fire_event) {
127  fire(event::NOTIFY_MODIFIED, *this, nullptr);
128  }
129 }
130 
132 {
133  if(retval == retval_) {
134  return;
135  }
136 
137  retval_ = retval;
139 }
140 
142 {
143  if(state != state_) {
144  state_ = state;
145  set_is_dirty(true);
146  }
147 }
148 
150  bool& handled)
151 {
152  DBG_GUI_E << LOG_HEADER << ' ' << event << ".\n";
154  handled = true;
155 }
156 
158  bool& handled)
159 {
160  DBG_GUI_E << LOG_HEADER << ' ' << event << ".\n";
162  handled = true;
163 }
164 
166  bool& handled)
167 {
168  DBG_GUI_E << LOG_HEADER << ' ' << event << ".\n";
169 
171 
172  set_value(get_value() + 1, true);
173 
174  handled = true;
175 }
176 
178  const event::ui_event event, bool& handled)
179 {
180  DBG_GUI_E << LOG_HEADER << ' ' << event << ".\n";
181 
182  if(retval_ == retval::NONE) {
183  return;
184  }
185 
186  window* window = get_window();
187  assert(window);
188 
189  window->set_retval(retval_);
190 
191  handled = true;
192 }
193 
194 // }---------- DEFINITION ---------{
195 
198 {
199  DBG_GUI_P << "Parsing toggle button " << id << '\n';
200 
201  load_resolutions<resolution>(cfg);
202 }
203 
204 /*WIKI
205  * @page = GUIWidgetDefinitionWML
206  * @order = 1_toggle_button
207  *
208  * == Toggle button ==
209  *
210  * The definition of a toggle button.
211  *
212  * The following states exist:
213  * * state_enabled, the button is enabled and not selected.
214  * * state_disabled, the button is disabled and not selected.
215  * * state_focused, the mouse is over the button and not selected.
216  *
217  * * state_enabled_selected, the button is enabled and selected.
218  * * state_disabled_selected, the button is disabled and selected.
219  * * state_focused_selected, the mouse is over the button and selected.
220  * @begin{parent}{name="gui/"}
221  * @begin{tag}{name="oggle_button_definition"}{min=0}{max=-1}{super="generic/widget_definition"}
222  * @begin{tag}{name="resolution"}{min=0}{max=-1}{super="generic/widget_definition/resolution"}
223  * @begin{tag}{name="state_enabled"}{min=0}{max=1}{super="generic/state"}
224  * @end{tag}{name="state_enabled"}
225  * @begin{tag}{name="state_disabled"}{min=0}{max=1}{super="generic/state"}
226  * @end{tag}{name="state_disabled"}
227  * @begin{tag}{name="state_focused"}{min=0}{max=1}{super="generic/state"}
228  * @end{tag}{name="state_focused"}
229  * @begin{tag}{name="state_enabled_selected"}{min=0}{max=1}{super="generic/state"}
230  * @end{tag}{name="state_enabled_selected"}
231  * @begin{tag}{name="state_disabled_selected"}{min=0}{max=1}{super="generic/state"}
232  * @end{tag}{name="state_disabled_selected"}
233  * @begin{tag}{name="state_focused_selected"}{min=0}{max=1}{super="generic/state"}
234  * @end{tag}{name="state_focused_selected"}
235  * @end{tag}{name="resolution"}
236  * @end{tag}{name="oggle_button_definition"}
237  * @end{parent}{name="gui/"}
238  */
240  : resolution_definition(cfg)
241 {
242  // Note the order should be the same as the enum state_t in
243  // toggle_button.hpp.
244  for(const auto& c : cfg.child_range("state"))
245  {
246  state.emplace_back(c.child("enabled"));
247  state.emplace_back(c.child("disabled"));
248  state.emplace_back(c.child("focused"));
249  }
250 }
251 
252 // }---------- BUILDER -----------{
253 
254 /*WIKI
255  * @page = GUIToolkitWML
256  * @order = 2_toggle_button
257  * @begin{parent}{name="gui/window/resolution/grid/row/column/"}
258  * @begin{tag}{name="toggle_button"}{min=0}{max=-1}{super="generic/widget_instance"}
259  * == Toggle button ==
260  *
261  * @begin{table}{config}
262  * icon & f_string & "" & The name of the icon file to show. $
263  * return_value_id & string & "" & The return value id, see
264  * [[GUIToolkitWML#Button]] for more
265  * information. $
266  * return_value & int & 0 & The return value, see
267  * [[GUIToolkitWML#Button]] for more
268  * information. $
269  * @end{table}
270  * @end{tag}{name="toggle_button"}
271  * @end{parent}{name="gui/window/resolution/grid/row/column/"}
272  */
273 
274 namespace implementation
275 {
276 
277 builder_toggle_button::builder_toggle_button(const config& cfg)
278  : builder_styled_widget(cfg)
279  , icon_name_(cfg["icon"])
280  , retval_id_(cfg["return_value_id"])
281  , retval_(cfg["return_value"])
282 {
283 }
284 
286 {
287  toggle_button* widget = new toggle_button(*this);
288 
289  widget->set_icon_name(icon_name_);
290  widget->set_retval(get_retval(retval_id_, retval_, id));
291 
292  DBG_GUI_G << "Window builder: placed toggle button '" << id
293  << "' with definition '" << definition << "'.\n";
294 
295  return widget;
296 }
297 
298 } // namespace implementation
299 
300 // }------------ END --------------
301 
302 } // 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:68
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 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)
void set_variable(const std::string &key, const wfl::variant &value)
Definition: canvas.hpp:171
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:362
Base class for all widgets.
Definition: widget.hpp:47
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:136
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:22
Sent by a widget to notify others its contents or state are modified.
Definition: handler.hpp:96
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:463
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:41
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:34
Default, unset return value.
Definition: retval.hpp:31
window * get_window()
Get the parent window.
Definition: widget.cpp:114
#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:24
void set_retval(const int retval, const bool close_window=true)
Sets there return value of the window.
Definition: window.hpp:364
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:1019
bool fire(const ui_event event, widget &target)
Fires an event which has no extra parameters.
Definition: dispatcher.cpp:130
retval
Default window/dialog return values.
Definition: retval.hpp:28
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:68
mock_char c
std::string sound_toggle_button_click
Definition: settings.cpp:40
base class of top level items, the only item which needs to store the final canvases to draw on ...
Definition: window.hpp:63
#define DBG_GUI_G
Definition: log.hpp:40
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:55
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)