The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
toggle_button.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2016 by Mark de Wever <[email protected]>
3  Part of the Battle for Wesnoth Project http://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 #include "wml_exception.hpp"
26 
27 #include "utils/functional.hpp"
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 
40  : tcontrol(COUNT)
41  , state_(ENABLED)
42  , state_num_(0)
43  , retval_(0)
44  , callback_state_change_()
45  , icon_name_()
46 {
47  connect_signal<event::MOUSE_ENTER>(std::bind(
49  connect_signal<event::MOUSE_LEAVE>(std::bind(
51 
52  connect_signal<event::LEFT_BUTTON_CLICK>(std::bind(
54  connect_signal<event::LEFT_BUTTON_DOUBLE_CLICK>(std::bind(
56  this,
57  _2,
58  _3));
59 }
60 
62 {
63  std::div_t res = std::div(this->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  string_map::const_iterator itor = data.find("icon");
75  if(itor != data.end()) {
76  set_icon_name(itor->second);
77  }
78 }
79 
80 void ttoggle_button::set_active(const bool active)
81 {
82  if(active) {
84  } else {
86  }
87 }
88 
90 {
91  return state_ != DISABLED;
92 }
93 
94 unsigned ttoggle_button::get_state() const
95 {
96  return state_ + COUNT * state_num_;
97 }
98 
100 {
101  // Inherit.
103 
104  // set icon in canvases
105  std::vector<tcanvas>& canvases = tcontrol::canvas();
106  for(auto & canvas : canvases)
107  {
108  canvas.set_variable("icon", variant(icon_name_));
109  }
110 
111  set_is_dirty(true);
112 }
113 
115 {
116  if(selected == get_value()) {
117  return;
118  }
119  state_num_ = selected % num_states();
120  set_is_dirty(true);
121 
122 }
123 
124 void ttoggle_button::set_retval(const int retval)
125 {
126  if(retval == retval_) {
127  return;
128  }
129 
130  retval_ = retval;
132 }
133 
135 {
136  if(state != state_) {
137  state_ = state;
138  set_is_dirty(true);
139  }
140 }
141 
143 {
144  static const std::string type = "toggle_button";
145  return type;
146 }
147 
149  bool& handled)
150 {
151  DBG_GUI_E << LOG_HEADER << ' ' << event << ".\n";
153  handled = true;
154 }
155 
157  bool& handled)
158 {
159  DBG_GUI_E << LOG_HEADER << ' ' << event << ".\n";
161  handled = true;
162 }
163 
165  bool& handled)
166 {
167  DBG_GUI_E << LOG_HEADER << ' ' << event << ".\n";
168 
170 
171  set_value(get_value() + 1);
172 
174  callback_state_change_(*this);
175  }
176  handled = true;
177 }
178 
180  const event::tevent event, bool& handled)
181 {
182  DBG_GUI_E << LOG_HEADER << ' ' << event << ".\n";
183 
184  if(retval_ == 0) {
185  return;
186  }
187 
188  twindow* window = get_window();
189  assert(window);
190 
191  window->set_retval(retval_);
192 
193  handled = true;
194 }
195 
196 // }---------- DEFINITION ---------{
197 
199  : tcontrol_definition(cfg)
200 {
201  DBG_GUI_P << "Parsing toggle button " << id << '\n';
202 
203  load_resolutions<tresolution>(cfg);
204 }
205 
206 /*WIKI
207  * @page = GUIWidgetDefinitionWML
208  * @order = 1_toggle_button
209  *
210  * == Toggle button ==
211  *
212  * The definition of a toggle button.
213  *
214  * The following states exist:
215  * * state_enabled, the button is enabled and not selected.
216  * * state_disabled, the button is disabled and not selected.
217  * * state_focused, the mouse is over the button and not selected.
218  *
219  * * state_enabled_selected, the button is enabled and selected.
220  * * state_disabled_selected, the button is disabled and selected.
221  * * state_focused_selected, the mouse is over the button and selected.
222  * @begin{parent}{name="gui/"}
223  * @begin{tag}{name="toggle_button_definition"}{min=0}{max=-1}{super="generic/widget_definition"}
224  * @begin{tag}{name="resolution"}{min=0}{max=-1}{super="generic/widget_definition/resolution"}
225  * @begin{tag}{name="state_enabled"}{min=0}{max=1}{super="generic/state"}
226  * @end{tag}{name="state_enabled"}
227  * @begin{tag}{name="state_disabled"}{min=0}{max=1}{super="generic/state"}
228  * @end{tag}{name="state_disabled"}
229  * @begin{tag}{name="state_focused"}{min=0}{max=1}{super="generic/state"}
230  * @end{tag}{name="state_focused"}
231  * @begin{tag}{name="state_enabled_selected"}{min=0}{max=1}{super="generic/state"}
232  * @end{tag}{name="state_enabled_selected"}
233  * @begin{tag}{name="state_disabled_selected"}{min=0}{max=1}{super="generic/state"}
234  * @end{tag}{name="state_disabled_selected"}
235  * @begin{tag}{name="state_focused_selected"}{min=0}{max=1}{super="generic/state"}
236  * @end{tag}{name="state_focused_selected"}
237  * @end{tag}{name="resolution"}
238  * @end{tag}{name="toggle_button_definition"}
239  * @end{parent}{name="gui/"}
240  */
243 {
244  // Note the order should be the same as the enum tstate in
245  // toggle_button.hpp.
246  for(const auto& c : cfg.child_range("state"))
247  {
248  state.push_back(tstate_definition(c.child("enabled")));
249  state.push_back(tstate_definition(c.child("disabled")));
250  state.push_back(tstate_definition(c.child("focused")));
251  }
252 }
253 
254 // }---------- BUILDER -----------{
255 
256 /*WIKI
257  * @page = GUIToolkitWML
258  * @order = 2_toggle_button
259  * @begin{parent}{name="gui/window/resolution/grid/row/column/"}
260  * @begin{tag}{name="toggle_button"}{min=0}{max=-1}{super="generic/widget_instance"}
261  * == Toggle button ==
262  *
263  * @begin{table}{config}
264  * icon & f_string & "" & The name of the icon file to show. $
265  * return_value_id & string & "" & The return value id, see
266  * [[GUIToolkitWML#Button]] for more
267  * information. $
268  * return_value & int & 0 & The return value, see
269  * [[GUIToolkitWML#Button]] for more
270  * information. $
271  * @end{table}
272  * @end{tag}{name="toggle_button"}
273  * @end{parent}{name="gui/window/resolution/grid/row/column/"}
274  */
275 
276 namespace implementation
277 {
278 
279 tbuilder_toggle_button::tbuilder_toggle_button(const config& cfg)
280  : tbuilder_control(cfg)
281  , icon_name_(cfg["icon"])
282  , retval_id_(cfg["return_value_id"])
283  , retval_(cfg["return_value"])
284 {
285 }
286 
288 {
289  ttoggle_button* widget = new ttoggle_button();
290 
291  init_control(widget);
292 
293  widget->set_icon_name(icon_name_);
294  widget->set_retval(get_retval(retval_id_, retval_, id));
295 
296  DBG_GUI_G << "Window builder: placed toggle button '" << id
297  << "' with definition '" << definition << "'.\n";
298 
299  return widget;
300 }
301 
302 } // namespace implementation
303 
304 // }------------ END --------------
305 
306 } // namespace gui2
Define the common log macros for the gui toolkit.
virtual void set_active(const bool active) override
See tcontrol::set_active.
#define DBG_GUI_P
Definition: log.hpp:69
child_itors child_range(const std::string &key)
Definition: config.cpp:613
virtual unsigned get_state() const override
See tcontrol::get_state.
const GLfloat * c
Definition: glew.h:12741
unsigned num_states() const override
Inherited from tselectable_.
void set_icon_name(const std::string &icon_name)
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
GLuint GLuint GLsizei GLenum type
Definition: glew.h:1221
virtual const std::string & get_control_type() const override
See tcontrol::get_control_type.
void signal_handler_left_button_double_click(const event::tevent event, bool &handled)
tresolution_definition_ptr config()
Definition: control.hpp:299
This file contains the window object, this object is a top level container which has the event manage...
tstate state_
Current state of the widget.
void signal_handler_mouse_leave(const event::tevent event, bool &handled)
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:131
GLint GLenum GLsizei GLint GLsizei const GLvoid * data
Definition: glew.h:1347
void set_is_dirty(const bool is_dirty)
Definition: widget.cpp:435
Base class of a resolution, contains the common keys for a resolution.
base class of top level items, the only item which needs to store the final canvases to draw on ...
Definition: window.hpp:62
Class for a toggle button.
A class inherited from ttext_box that displays its input as stars.
Definition: field-fwd.hpp:23
void init_control(tcontrol *control) const
Definition: control.cpp:675
std::string definition
Parameters for the control.
Definition: control.hpp:530
void set_state(const tstate state)
tstate
Possible states of the widget.
This file contains the settings handling of the widget library.
void update_canvas()
Inherited from tcontrol.
std::string icon_name_
The toggle button can contain an icon next to the text.
unsigned state_num_
Usually 1 for selected and 0 for not selected, can also have higher values in tristate buttons...
std::string selected
Definition: game_config.cpp:84
void set_retval(const int retval, const bool close_window=true)
Sets there return value of the window.
Definition: window.hpp:422
tevent
The event send to the dispatcher.
Definition: handler.hpp:54
void set_wants_mouse_left_double_click(const bool click=true)
unsigned get_value() const override
Inherited from tselectable_.
std::function< void(twidget &)> callback_state_change_
See tselectable_::set_callback_state_change.
Contains the state info for a resolution.
#define REGISTER_WIDGET(id)
Wrapper for REGISTER_WIDGET3.
std::map< std::string, t_string > string_map
Definition: generator.hpp:23
virtual void update_canvas()
Updates the canvas(ses).
Definition: control.cpp:364
GLuint res
Definition: glew.h:9258
void signal_handler_left_button_click(const event::tevent event, bool &handled)
std::map< std::string, tfilter >::iterator itor
Definition: filter.cpp:199
#define DBG_GUI_E
Definition: log.hpp:35
void set_members(const string_map &data)
See tcontrol::set_members.
void set_retval(const int retval)
#define LOG_HEADER
virtual bool get_active() const override
See tcontrol::get_active.
std::vector< tcanvas > & canvas()
Definition: control.hpp:282
Base class for all visible items.
Definition: control.hpp:34
std::vector< tstate_definition > state
cl_event event
Definition: glew.h:3070
void signal_handler_mouse_enter(const event::tevent event, bool &handled)
virtual void set_members(const string_map &data)
Sets the members of the control.
Definition: control.cpp:99
ttoggle_button_definition(const config &cfg)
Base class for all widgets.
Definition: widget.hpp:49
void play_UI_sound(const std::string &files)
Definition: sound.cpp:842
int retval_
The return value of the button.
twindow * get_window()
Get the parent window.
Definition: widget.cpp:116
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
void set_value(const unsigned selected)
Inherited from tselectable_.
std::string sound_toggle_button_click
Definition: settings.cpp:59
#define DBG_GUI_G
Definition: log.hpp:41
GLsizei const GLcharARB ** string
Definition: glew.h:4503
Contains the implementation details for lexical_cast and shouldn't be used directly.