The Battle for Wesnoth  1.15.2+dev
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 
17 #include "gui/widgets/button.hpp"
18 
19 #include "gui/core/log.hpp"
20 
24 
26 #include "gui/widgets/settings.hpp"
27 #include "gui/widgets/window.hpp"
28 
29 #include "sound.hpp"
30 
31 #include "utils/functional.hpp"
32 
33 #define LOG_SCOPE_HEADER get_control_type() + " [" + id() + "] " + __func__
34 #define LOG_HEADER LOG_SCOPE_HEADER + ':'
35 
36 namespace gui2
37 {
38 
39 // ------------ WIDGET -----------{
40 
41 REGISTER_WIDGET(button)
42 
43 button::button(const implementation::builder_button& builder)
44  : styled_widget(builder, type())
45  , clickable_item()
46  , state_(ENABLED)
47  , retval_(retval::NONE)
48 {
49  connect_signal<event::MOUSE_ENTER>(
50  std::bind(&button::signal_handler_mouse_enter, this, _2, _3));
51  connect_signal<event::MOUSE_LEAVE>(
52  std::bind(&button::signal_handler_mouse_leave, this, _2, _3));
53 
54  connect_signal<event::LEFT_BUTTON_DOWN>(std::bind(
56  connect_signal<event::LEFT_BUTTON_UP>(
57  std::bind(&button::signal_handler_left_button_up, this, _2, _3));
58  connect_signal<event::LEFT_BUTTON_CLICK>(std::bind(
60 }
61 
62 void button::set_active(const bool active)
63 {
64  if(get_active() != active) {
65  set_state(active ? ENABLED : DISABLED);
66  }
67 }
68 
69 bool button::get_active() const
70 {
71  return state_ != DISABLED;
72 }
73 
74 unsigned button::get_state() const
75 {
76  return state_;
77 }
78 
79 void button::set_state(const state_t state)
80 {
81  if(state != state_) {
82  state_ = state;
83  set_is_dirty(true);
84  }
85 }
86 
88  bool& handled)
89 {
90  DBG_GUI_E << LOG_HEADER << ' ' << event << ".\n";
91 
93  handled = true;
94 }
95 
97  bool& handled)
98 {
99  DBG_GUI_E << LOG_HEADER << ' ' << event << ".\n";
100 
102  handled = true;
103 }
104 
106  bool& handled)
107 {
108  DBG_GUI_E << LOG_HEADER << ' ' << event << ".\n";
109 
110  window* window = get_window();
111  if(window) {
112  window->mouse_capture();
113  }
114 
116  handled = true;
117 }
118 
120  bool& handled)
121 {
122  DBG_GUI_E << LOG_HEADER << ' ' << event << ".\n";
123 
125  handled = true;
126 }
127 
129  bool& handled)
130 {
131  DBG_GUI_E << LOG_HEADER << ' ' << event << ".\n";
132 
134 
135  // If a button has a retval do the default handling.
136  if(retval_ != retval::NONE) {
137  window* window = get_window();
138  if(window) {
139  window->set_retval(retval_);
140  return;
141  }
142  }
143 
144  handled = true;
145 }
146 
147 // }---------- DEFINITION ---------{
148 
151 {
152  DBG_GUI_P << "Parsing button " << id << '\n';
153 
154  load_resolutions<resolution>(cfg);
155 }
156 
157 /*WIKI
158  * @page = GUIWidgetDefinitionWML
159  * @order = 1_button
160  *
161  * == Button ==
162  *
163  * @macro = button_description
164  *
165  * The following states exist:
166  * * state_enabled, the button is enabled.
167  * * state_disabled, the button is disabled.
168  * * state_pressed, the left mouse button is down.
169  * * state_focused, the mouse is over the button.
170  * @begin{parent}{name="gui/"}
171  * @begin{tag}{name="button_definition"}{min=0}{max=-1}{super="generic/widget_definition"}
172  * @begin{tag}{name="resolution"}{min=0}{max=-1}{super="generic/widget_definition/resolution"}
173  * @begin{tag}{name="state_enabled"}{min=0}{max=1}{super="generic/state"}
174  * @end{tag}{name="state_enabled"}
175  * @begin{tag}{name="state_disabled"}{min=0}{max=1}{super="generic/state"}
176  * @end{tag}{name="state_disabled"}
177  * @begin{tag}{name="state_pressed"}{min=0}{max=1}{super="generic/state"}
178  * @end{tag}{name="state_pressed"}
179  * @begin{tag}{name="state_focused"}{min=0}{max=1}{super="generic/state"}
180  * @end{tag}{name="state_focused"}
181  * @end{tag}{name="resolution"}
182  * @end{tag}{name="button_definition"}
183  * @end{parent}{name="gui/"}
184  */
186  : resolution_definition(cfg)
187 {
188  // Note the order should be the same as the enum state_t in button.hpp.
189  state.emplace_back(cfg.child("state_enabled"));
190  state.emplace_back(cfg.child("state_disabled"));
191  state.emplace_back(cfg.child("state_pressed"));
192  state.emplace_back(cfg.child("state_focused"));
193 }
194 
195 // }---------- BUILDER -----------{
196 
197 /*WIKI_MACRO
198  * @begin{macro}{button_description}
199  *
200  * A button is a styled_widget that can be pushed to start an action or close
201  * a dialog.
202  * @end{macro}
203  */
204 
205 /*WIKI
206  * @page = GUIWidgetInstanceWML
207  * @order = 2_button
208  * @begin{parent}{name="gui/window/resolution/grid/row/column/"}
209  * @begin{tag}{name="button"}{min=0}{max=-1}{super="generic/widget_instance"}
210  * == Button ==
211  *
212  * @macro = button_description
213  *
214  * Instance of a button. When a button has a return value it sets the
215  * return value for the window. Normally this closes the window and returns
216  * this value to the caller. The return value can either be defined by the
217  * user or determined from the id of the button. The return value has a
218  * higher precedence as the one defined by the id. (Of course it's weird to
219  * give a button an id and then override its return value.)
220  *
221  * When the button doesn't have a standard id, but you still want to use the
222  * return value of that id, use return_value_id instead. This has a higher
223  * precedence as return_value.
224  *
225  * List with the button specific variables:
226  * @begin{table}{config}
227  * return_value_id & string & "" & The return value id. $
228  * return_value & int & 0 & The return value. $
229  *
230  * @end{table}
231  * @end{tag}{name="button"}
232  * @end{parent}{name="gui/window/resolution/grid/row/column/"}
233  */
234 
235 namespace implementation
236 {
237 
238 builder_button::builder_button(const config& cfg)
239  : builder_styled_widget(cfg)
240  , retval_id_(cfg["return_value_id"])
241  , retval_(cfg["return_value"])
242 {
243 }
244 
246 {
247  button* widget = new button(*this);
248 
249  widget->set_retval(get_retval(retval_id_, retval_, id));
250 
251  DBG_GUI_G << "Window builder: placed button '" << id
252  << "' with definition '" << definition << "'.\n";
253 
254  return widget;
255 }
256 
257 } // namespace implementation
258 
259 // }------------ END --------------
260 
261 } // 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
config & child(config_key_type key, int n=0)
Returns the nth child with the given key, or a reference to an invalid config if there is none...
Definition: config.cpp:420
std::vector< state_definition > state
void signal_handler_mouse_enter(const event::ui_event event, bool &handled)
Definition: button.cpp:87
void set_retval(const int retval)
Definition: button.hpp:65
void signal_handler_left_button_down(const event::ui_event event, bool &handled)
Definition: button.cpp:105
This file contains the window object, this object is a top level container which has the event manage...
Base class for all widgets.
Definition: widget.hpp:47
std::string sound_button_click
Definition: settings.cpp:39
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
virtual unsigned get_state() const override
See styled_widget::get_state.
Definition: button.cpp:74
void signal_handler_left_button_click(const event::ui_event event, bool &handled)
Definition: button.cpp:128
void set_state(const state_t state)
Definition: button.cpp:79
state_t
Possible states of the widget.
Definition: button.hpp:76
Generic file dialog.
Definition: field-fwd.hpp:22
std::string definition
Parameters for the styled_widget.
This file contains the settings handling of the widget library.
void set_is_dirty(const bool is_dirty)
Definition: widget.cpp:463
#define REGISTER_WIDGET(id)
Wrapper for REGISTER_WIDGET3.
void signal_handler_left_button_up(const event::ui_event event, bool &handled)
Definition: button.cpp:119
#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
void set_retval(const int retval, const bool close_window=true)
Sets there return value of the window.
Definition: window.hpp:363
Base class for all visible items.
virtual bool get_active() const override
See styled_widget::get_active.
Definition: button.cpp:69
int retval_
The return value of the button.
Definition: button.hpp:98
virtual void set_active(const bool active) override
See styled_widget::set_active.
Definition: button.cpp:62
state_t state_
Current state of the widget.
Definition: button.hpp:90
void mouse_capture(const bool capture=true)
Definition: window.cpp:1275
void play_UI_sound(const std::string &files)
Definition: sound.cpp:1019
Simple push button.
Definition: button.hpp:35
Small concept class.
void signal_handler_mouse_leave(const event::ui_event event, bool &handled)
Definition: button.cpp:96
retval
Default window/dialog return values.
Definition: retval.hpp:28
#define LOG_HEADER
Definition: button.cpp:34
resolution(const config &cfg)
Definition: button.cpp:185
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:68
base class of top level items, the only item which needs to store the final canvases to draw on ...
Definition: window.hpp:62
#define DBG_GUI_G
Definition: log.hpp:40
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
button_definition(const config &cfg)
Definition: button.cpp:149