The Battle for Wesnoth  1.15.1+dev
repeating_button.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 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 
19 #include "gui/core/log.hpp"
20 #include "gui/core/timer.hpp"
22 #include "gui/widgets/settings.hpp"
23 #include "gui/widgets/window.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(repeating_button)
37 
38 repeating_button::repeating_button(const implementation::builder_repeating_button& builder)
39  : styled_widget(builder, type())
40  , clickable_item()
41  , state_(ENABLED)
42  , repeat_timer_(0)
43 {
44  connect_signal<event::MOUSE_ENTER>(std::bind(
46  connect_signal<event::MOUSE_LEAVE>(std::bind(
48 
49  connect_signal<event::LEFT_BUTTON_DOWN>(std::bind(
51  connect_signal<event::LEFT_BUTTON_UP>(std::bind(
53 }
54 
56 {
57  if(repeat_timer_) {
59  }
60 }
61 
63  const event::signal_function& signal)
64 {
65  connect_signal<event::LEFT_BUTTON_DOWN>(signal);
66 }
67 
69  const event::signal_function& signal)
70 {
71  disconnect_signal<event::LEFT_BUTTON_DOWN>(signal);
72 }
73 
74 void repeating_button::set_active(const bool active)
75 {
76  if(get_active() != active) {
77  set_state(active ? ENABLED : DISABLED);
78  }
79 }
80 
82 {
83  return state_ != DISABLED;
84 }
85 
87 {
88  return state_;
89 }
90 
92 {
93  if(state != state_) {
94  state_ = state;
95  set_is_dirty(true);
96 
97  if(state_ == DISABLED && repeat_timer_) {
99  repeat_timer_ = 0;
100  }
101  }
102 }
103 
105  bool& handled)
106 {
107  DBG_GUI_E << LOG_HEADER << ' ' << event << ".\n";
108 
110  handled = true;
111 }
112 
114  bool& handled)
115 {
116  DBG_GUI_E << LOG_HEADER << ' ' << event << ".\n";
117 
119  handled = true;
120 }
121 
122 void
124  bool& handled)
125 {
126  DBG_GUI_E << LOG_HEADER << ' ' << event << ".\n";
127 
128  // If the timer isn't set it's the initial down event.
129  if(!repeat_timer_) {
130 
131  // mimic the old gui and only play the sound once.
133 
134  window* window = get_window();
135  if(window) {
137  [this, window](unsigned int) {
138  window->fire(event::LEFT_BUTTON_DOWN, *this);
139  },true);
140 
141  window->mouse_capture();
142  }
143 
145  }
146 
147  handled = true;
148 }
149 
151  bool& handled)
152 {
153  DBG_GUI_E << LOG_HEADER << ' ' << event << ".\n";
154 
155  if(repeat_timer_) {
157  repeat_timer_ = 0;
158  }
159 
160  if(get_active()) {
162  }
163  handled = true;
164 }
165 
166 // }---------- DEFINITION ---------{
167 
170 {
171  DBG_GUI_P << "Parsing repeating button " << id << '\n';
172 
173  load_resolutions<resolution>(cfg);
174 }
175 
176 /*WIKI
177  * @page = GUIWidgetDefinitionWML
178  * @order = 1_repeating_button
179  *
180  * == Repeating button ==
181  *
182  * @macro = repeating_button_description
183  *
184  * The following states exist:
185  * * state_enabled, the repeating_button is enabled.
186  * * state_disabled, the repeating_button is disabled.
187  * * state_pressed, the left mouse repeating_button is down.
188  * * state_focused, the mouse is over the repeating_button.
189  * @begin{parent}{name="gui/"}
190  * @begin{tag}{name="repeating_button_definition"}{min=0}{max=-1}{super="generic/widget_definition"}
191  * @begin{tag}{name="resolution"}{min=0}{max=-1}{super="generic/widget_definition/resolution"}
192  * @begin{tag}{name="state_enabled"}{min=0}{max=1}{super="generic/state"}
193  * @end{tag}{name="state_enabled"}
194  * @begin{tag}{name="state_disabled"}{min=0}{max=1}{super="generic/state"}
195  * @end{tag}{name="state_disabled"}
196  * @begin{tag}{name="state_pressed"}{min=0}{max=1}{super="generic/state"}
197  * @end{tag}{name="state_pressed"}
198  * @begin{tag}{name="state_focused"}{min=0}{max=1}{super="generic/state"}
199  * @end{tag}{name="state_focused"}
200  * @end{tag}{name="resolution"}
201  * @end{tag}{name="repeating_button_definition"}
202  * @end{parent}{name="gui/"}
203  */
205  : resolution_definition(cfg)
206 {
207  // Note the order should be the same as the enum state_t in
208  // repeating_button.hpp.
209  state.emplace_back(cfg.child("state_enabled"));
210  state.emplace_back(cfg.child("state_disabled"));
211  state.emplace_back(cfg.child("state_pressed"));
212  state.emplace_back(cfg.child("state_focused"));
213 }
214 
215 // }---------- BUILDER -----------{
216 
217 /*WIKI_MACRO
218  * @begin{macro}{repeating_button_description}
219  *
220  * A repeating_button is a styled_widget that can be pushed down and repeat a
221  * certain action. Once the button is down every x milliseconds it is
222  * down a new down event is triggered.
223  * @end{macro}
224  */
225 
226 /*WIKI
227  * @page = GUIWidgetInstanceWML
228  * @order = 2_repeating_button
229  *
230  * == Repeating button ==
231  *
232  * @macro = repeating_button_description
233  * @begin{parent}{name="gui/window/resolution/grid/row/column/"}
234  * @begin{tag}{name="repeating_button"}{min=0}{max=-1}{super="gui/window/resolution/grid/row/column/button"}
235  * @end{tag}{name="repeating_button"}
236  * @end{parent}{name="gui/window/resolution/grid/row/column/"}
237  */
238 
239 namespace implementation
240 {
241 
242 builder_repeating_button::builder_repeating_button(const config& cfg)
243  : builder_styled_widget(cfg)
244 {
245 }
246 
248 {
250 
251  DBG_GUI_G << "Window builder: placed repeating button '" << id
252  << "' with definition '" << definition << "'.\n";
253 
254  return widget;
255 }
256 
257 } // namespace implementation
258 
259 // }------------ END --------------
260 
261 } // namespace gui2
virtual bool get_active() const override
See styled_widget::get_active.
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
void signal_handler_left_button_up(const event::ui_event event, bool &handled)
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
A left mouse button down event for a widget.
Definition: handler.hpp:68
virtual void set_active(const bool active) override
See styled_widget::set_active.
state_t
Possible states of the widget.
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
virtual unsigned get_state() const override
See styled_widget::get_state.
void signal_handler_left_button_down(const event::ui_event event, bool &handled)
state_t state_
Current state of the widget.
Generic file dialog.
Definition: field-fwd.hpp:22
unsigned repeat_button_repeat_time
Definition: settings.cpp:37
std::string definition
Parameters for the styled_widget.
void connect_signal_mouse_left_down(const event::signal_function &signal)
Connects a signal handler for a left mouse button down.
#define LOG_HEADER
repeating_button_definition(const config &cfg)
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.
std::size_t repeat_timer_
The timer for the repeating events.
void set_state(const state_t state)
#define DBG_GUI_E
Definition: log.hpp:34
window * get_window()
Get the parent window.
Definition: widget.cpp:114
void signal_handler_mouse_leave(const event::ui_event event, bool &handled)
Contains the gui2 timer routines.
std::size_t add_timer(const uint32_t interval, const std::function< void(std::size_t id)> &callback, const bool repeat)
Adds a new timer.
Definition: timer.cpp:126
Base class for all visible items.
std::function< void(widget &dispatcher, const ui_event event, bool &handled, bool &halt)> signal_function
Callback function signature.
Definition: dispatcher.hpp:42
void mouse_capture(const bool capture=true)
Definition: window.cpp:1276
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
Small concept class.
void signal_handler_mouse_enter(const event::ui_event event, bool &handled)
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:92
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
void disconnect_signal_mouse_left_down(const event::signal_function &signal)
Disconnects a signal handler for a left mouse button down.
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
bool remove_timer(const std::size_t id)
Removes a timer.
Definition: timer.cpp:167