The Battle for Wesnoth  1.17.0-dev
repeating_button.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2021
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 
19 
20 #include "gui/core/log.hpp"
21 #include "gui/core/timer.hpp"
23 #include "gui/widgets/settings.hpp"
24 #include "gui/widgets/window.hpp"
25 #include "sound.hpp"
26 
27 #include <functional>
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(repeating_button)
38 
39 repeating_button::repeating_button(const implementation::builder_repeating_button& builder)
40  : styled_widget(builder, type())
41  , clickable_item()
42  , state_(ENABLED)
43  , repeat_timer_(0)
44 {
45  connect_signal<event::MOUSE_ENTER>(std::bind(
46  &repeating_button::signal_handler_mouse_enter, this, std::placeholders::_2, std::placeholders::_3));
47  connect_signal<event::MOUSE_LEAVE>(std::bind(
48  &repeating_button::signal_handler_mouse_leave, this, std::placeholders::_2, std::placeholders::_3));
49 
50  connect_signal<event::LEFT_BUTTON_DOWN>(std::bind(
51  &repeating_button::signal_handler_left_button_down, this, std::placeholders::_2, std::placeholders::_3));
52  connect_signal<event::LEFT_BUTTON_UP>(std::bind(
53  &repeating_button::signal_handler_left_button_up, this, std::placeholders::_2, std::placeholders::_3));
54 }
55 
57 {
58  if(repeat_timer_) {
60  }
61 }
62 
64  const event::signal_function& signal)
65 {
66  connect_signal<event::LEFT_BUTTON_DOWN>(signal);
67 }
68 
70  const event::signal_function& signal)
71 {
72  disconnect_signal<event::LEFT_BUTTON_DOWN>(signal);
73 }
74 
75 void repeating_button::set_active(const bool active)
76 {
77  if(get_active() != active) {
78  set_state(active ? ENABLED : DISABLED);
79  }
80 }
81 
83 {
84  return state_ != DISABLED;
85 }
86 
88 {
89  return state_;
90 }
91 
93 {
94  if(state != state_) {
95  state_ = state;
96  set_is_dirty(true);
97 
98  if(state_ == DISABLED && repeat_timer_) {
100  repeat_timer_ = 0;
101  }
102  }
103 }
104 
106  bool& handled)
107 {
108  DBG_GUI_E << LOG_HEADER << ' ' << event << ".\n";
109 
111  handled = true;
112 }
113 
115  bool& handled)
116 {
117  DBG_GUI_E << LOG_HEADER << ' ' << event << ".\n";
118 
120  handled = true;
121 }
122 
123 void
125  bool& handled)
126 {
127  DBG_GUI_E << LOG_HEADER << ' ' << event << ".\n";
128 
129  // If the timer isn't set it's the initial down event.
130  if(!repeat_timer_) {
131 
132  // mimic the old gui and only play the sound once.
134 
135  window* window = get_window();
136  if(window) {
138  [this, window](unsigned int) {
139  window->fire(event::LEFT_BUTTON_DOWN, *this);
140  },true);
141 
142  window->mouse_capture();
143  }
144 
146  }
147 
148  handled = true;
149 }
150 
152  bool& handled)
153 {
154  DBG_GUI_E << LOG_HEADER << ' ' << event << ".\n";
155 
156  if(repeat_timer_) {
158  repeat_timer_ = 0;
159  }
160 
161  if(get_active()) {
163  }
164  handled = true;
165 }
166 
167 // }---------- DEFINITION ---------{
168 
171 {
172  DBG_GUI_P << "Parsing repeating button " << id << '\n';
173 
174  load_resolutions<resolution>(cfg);
175 }
176 
178  : resolution_definition(cfg)
179 {
180  // Note the order should be the same as the enum state_t in
181  // repeating_button.hpp.
182  state.emplace_back(cfg.child("state_enabled"));
183  state.emplace_back(cfg.child("state_disabled"));
184  state.emplace_back(cfg.child("state_pressed"));
185  state.emplace_back(cfg.child("state_focused"));
186 }
187 
188 // }---------- BUILDER -----------{
189 
190 namespace implementation
191 {
192 
193 builder_repeating_button::builder_repeating_button(const config& cfg)
194  : builder_styled_widget(cfg)
195 {
196 }
197 
199 {
201 
202  DBG_GUI_G << "Window builder: placed repeating button '" << id
203  << "' with definition '" << definition << "'.\n";
204 
205  return widget;
206 }
207 
208 } // namespace implementation
209 
210 // }------------ END --------------
211 
212 } // 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:66
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:402
std::vector< state_definition > state
A left mouse button down event for a widget.
Definition: handler.hpp:61
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:49
std::string sound_button_click
Definition: settings.cpp:43
virtual unsigned get_state() const override
See styled_widget::get_state.
void signal_handler_left_button_down(const event::ui_event event, bool &handled)
dispatcher_callback_func<> signal_function
Callback function signature.
Definition: dispatcher.hpp:198
state_t state_
Current state of the widget.
Generic file dialog.
Definition: field-fwd.hpp:23
unsigned repeat_button_repeat_time
Definition: settings.cpp:41
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:466
#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:35
window * get_window()
Get the parent window.
Definition: widget.cpp:117
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:127
Base class for all visible items.
void mouse_capture(const bool capture=true)
Definition: window.cpp:1270
void play_UI_sound(const std::string &files)
Definition: sound.cpp:1052
bool fire(const ui_event event, widget &target)
Fires an event which has no extra parameters.
Definition: dispatcher.cpp:69
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:61
A repeating_button is a control that can be pushed down and repeat a certain action.
base class of top level items, the only item which needs to store the final canvases to draw on...
Definition: window.hpp:65
#define DBG_GUI_G
Definition: log.hpp:41
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:48
bool remove_timer(const std::size_t id)
Removes a timer.
Definition: timer.cpp:168