The Battle for Wesnoth  1.19.2+dev
button.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2024
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 
18 #include "gui/widgets/button.hpp"
19 
20 #include "gui/core/log.hpp"
21 
24 
26 #include "gui/widgets/settings.hpp"
27 #include "gui/widgets/window.hpp"
28 #include "wml_exception.hpp"
29 
30 #include "sound.hpp"
31 
32 #include <functional>
33 
34 #define LOG_SCOPE_HEADER get_control_type() + " [" + id() + "] " + __func__
35 #define LOG_HEADER LOG_SCOPE_HEADER + ':'
36 
37 namespace gui2
38 {
39 
40 // ------------ WIDGET -----------{
41 
42 REGISTER_WIDGET(button)
43 
44 button::button(const implementation::builder_button& builder)
45  : styled_widget(builder, type())
46  , clickable_item()
47  , state_(ENABLED)
48  , retval_(retval::NONE)
49  , success_(false)
50 {
51  connect_signal<event::MOUSE_ENTER>(
52  std::bind(&button::signal_handler_mouse_enter, this, std::placeholders::_2, std::placeholders::_3));
53  connect_signal<event::MOUSE_LEAVE>(
54  std::bind(&button::signal_handler_mouse_leave, this, std::placeholders::_2, std::placeholders::_3));
55 
56  connect_signal<event::LEFT_BUTTON_DOWN>(std::bind(
57  &button::signal_handler_left_button_down, this, std::placeholders::_2, std::placeholders::_3));
58  connect_signal<event::LEFT_BUTTON_UP>(
59  std::bind(&button::signal_handler_left_button_up, this, std::placeholders::_2, std::placeholders::_3));
60  connect_signal<event::LEFT_BUTTON_CLICK>(std::bind(
61  &button::signal_handler_left_button_click, this, std::placeholders::_2, std::placeholders::_3));
62 }
63 
64 void button::set_active(const bool active)
65 {
66  if(get_active() != active) {
67  set_state(active ? ENABLED : DISABLED);
68  }
69 }
70 
71 bool button::get_active() const
72 {
73  return state_ != DISABLED;
74 }
75 
76 unsigned button::get_state() const
77 {
78  return state_;
79 }
80 
81 void button::set_state(const state_t state)
82 {
83  if(state != state_) {
84  state_ = state;
85  queue_redraw();
86  }
87 }
88 
89 void button::set_success(bool success) {
90  success_ = success;
91  if (success) {
93  }
94 }
95 
97  bool& handled)
98 {
99  DBG_GUI_E << LOG_HEADER << ' ' << event << ".";
100 
102  handled = true;
103 }
104 
106  bool& handled)
107 {
108  DBG_GUI_E << LOG_HEADER << ' ' << event << ".";
109 
110  if (success_) {
112  } else {
114  }
115  handled = true;
116 }
117 
119  bool& handled)
120 {
121  DBG_GUI_E << LOG_HEADER << ' ' << event << ".";
122 
123  window* window = get_window();
124  if(window) {
126  }
127 
129  handled = true;
130 }
131 
133  bool& handled)
134 {
135  DBG_GUI_E << LOG_HEADER << ' ' << event << ".";
136 
138  handled = true;
139 }
140 
142  bool& handled)
143 {
144  DBG_GUI_E << LOG_HEADER << ' ' << event << ".";
145 
147 
148  // If a button has a retval do the default handling.
149  if(retval_ != retval::NONE) {
150  window* window = get_window();
151  if(window) {
153  return;
154  }
155  }
156 
157  handled = true;
158 }
159 
160 // }---------- DEFINITION ---------{
161 
164 {
165  DBG_GUI_P << "Parsing button " << id;
166 
167  load_resolutions<resolution>(cfg);
168 }
169 
171  : resolution_definition(cfg)
172 {
173  // Note the order should be the same as the enum state_t in button.hpp.
174  state.emplace_back(VALIDATE_WML_CHILD(cfg, "state_enabled", missing_mandatory_wml_tag("button_definition][resolution", "state_enabled")));
175  state.emplace_back(VALIDATE_WML_CHILD(cfg, "state_disabled", missing_mandatory_wml_tag("button_definition][resolution", "state_disabled")));
176  state.emplace_back(VALIDATE_WML_CHILD(cfg, "state_pressed", missing_mandatory_wml_tag("button_definition][resolution", "state_pressed")));
177  state.emplace_back(VALIDATE_WML_CHILD(cfg, "state_focused", missing_mandatory_wml_tag("button_definition][resolution", "state_focused")));
178  // state_success is optional, so error message not needed.
179  if (cfg.optional_child("state_success")) {
180  state.emplace_back(cfg.mandatory_child("state_success"));
181  }
182 
183 }
184 
185 // }---------- BUILDER -----------{
186 
187 namespace implementation
188 {
189 
190 builder_button::builder_button(const config& cfg)
191  : builder_styled_widget(cfg)
192  , retval_id_(cfg["return_value_id"])
193  , retval_(cfg["return_value"])
194 {
195 }
196 
197 std::unique_ptr<widget> builder_button::build() const
198 {
199  auto widget = std::make_unique<button>(*this);
200 
201  widget->set_retval(get_retval(retval_id_, retval_, id));
202 
203  DBG_GUI_G << "Window builder: placed button '" << id
204  << "' with definition '" << definition << "'.";
205 
206  return widget;
207 }
208 
209 } // namespace implementation
210 
211 // }------------ END --------------
212 
213 } // namespace gui2
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:159
config & mandatory_child(config_key_type key, int n=0)
Returns the nth child with the given key, or throws an error if there is none.
Definition: config.cpp:367
optional_config_impl< config > optional_child(config_key_type key, int n=0)
Euivalent to mandatory_child, but returns an empty optional if the nth child was not found.
Definition: config.cpp:385
Simple push button.
Definition: button.hpp:36
int retval_
The return value of the button.
Definition: button.hpp:101
state_t state_
Current state of the widget.
Definition: button.hpp:93
bool success_
Action performed by this button succeeded.
Definition: button.hpp:106
virtual bool get_active() const override
See styled_widget::get_active.
Definition: button.cpp:71
void signal_handler_mouse_enter(const event::ui_event event, bool &handled)
Definition: button.cpp:96
state_t
Possible states of the widget.
Definition: button.hpp:78
virtual unsigned get_state() const override
See styled_widget::get_state.
Definition: button.cpp:76
void set_state(const state_t state)
Definition: button.cpp:81
void signal_handler_left_button_down(const event::ui_event event, bool &handled)
Definition: button.cpp:118
void signal_handler_left_button_up(const event::ui_event event, bool &handled)
Definition: button.cpp:132
virtual void set_active(const bool active) override
See styled_widget::set_active.
Definition: button.cpp:64
void signal_handler_mouse_leave(const event::ui_event event, bool &handled)
Definition: button.cpp:105
void set_success(bool success)
Definition: button.cpp:89
void signal_handler_left_button_click(const event::ui_event event, bool &handled)
Definition: button.cpp:141
Small concept class.
Base class for all widgets.
Definition: widget.hpp:53
void queue_redraw()
Indicates that this widget should be redrawn.
Definition: widget.cpp:454
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:61
void set_retval(const int retval, const bool close_window=true)
Sets there return value of the window.
Definition: window.hpp:397
void mouse_capture(const bool capture=true)
Definition: window.cpp:1215
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
#define LOG_HEADER
Definition: button.cpp: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_button_click
Definition: settings.cpp:48
Generic file dialog.
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:1066
#define REGISTER_WIDGET(id)
Wrapper for REGISTER_WIDGET3.
This file contains the settings handling of the widget library.
resolution(const config &cfg)
Definition: button.cpp:170
button_definition(const config &cfg)
Definition: button.cpp:162
virtual std::unique_ptr< widget > build() const override
Definition: button.cpp:197
std::string definition
Parameters for the styled_widget.
std::vector< state_definition > state
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)