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 #pragma once
16 
17 #include "gui/widgets/styled_widget.hpp"
18 #include "gui/widgets/clickable_item.hpp"
19 
20 #include "gui/core/widget_definition.hpp"
21 #include "gui/core/window_builder.hpp"
22 
23 namespace gui2
24 {
25 namespace implementation
26 {
27 struct builder_repeating_button;
28 }
29 
30 // ------------ WIDGET -----------{
31 
32 class repeating_button : public styled_widget, public clickable_item
33 {
34 public:
35 	explicit repeating_button(const implementation::builder_repeating_button& builder);
36 	~repeating_button();
37 
38 	/**
39 	 * Connects a signal handler for a left mouse button down.
40 	 *
41 	 * This event is triggered when the button is pressed and, as long as the
42 	 * button stays down, every x ms afterwards.
43 	 *
44 	 * @param signal              The signal to connect.
45 	 */
46 	void connect_signal_mouse_left_down(const event::signal_function& signal);
47 
48 	/**
49 	 * Disconnects a signal handler for a left mouse button down.
50 	 *
51 	 * @param signal              The signal to disconnect (should be the same
52 	 *                            as send to the connect call.
53 	 */
54 	void
55 	disconnect_signal_mouse_left_down(const event::signal_function& signal);
56 
57 	/***** ***** ***** ***** Inherited ***** ***** ***** *****/
58 
59 	/** See @ref styled_widget::set_active. */
60 	virtual void set_active(const bool active) override;
61 
62 	/** See @ref styled_widget::get_active. */
63 	virtual bool get_active() const override;
64 
65 	/** See @ref styled_widget::get_state. */
66 	virtual unsigned get_state() const override;
67 
68 	/** Inherited from clickable_item. */
connect_click_handler(const event::signal_function & signal)69 	virtual void connect_click_handler(const event::signal_function& signal) override
70 	{
71 		connect_signal_mouse_left_down(signal);
72 	}
73 
74 	/** Inherited from clickable_item. */
disconnect_click_handler(const event::signal_function & signal)75 	virtual void disconnect_click_handler(const event::signal_function& signal) override
76 	{
77 		disconnect_signal_mouse_left_down(signal);
78 	}
79 
80 private:
81 	/**
82 	 * Possible states of the widget.
83 	 *
84 	 * Note the order of the states must be the same as defined in settings.hpp.
85 	 */
86 	enum state_t {
87 		ENABLED,
88 		DISABLED,
89 		PRESSED,
90 		FOCUSED,
91 	};
92 
93 	void set_state(const state_t state);
94 	/**
95 	 * Current state of the widget.
96 	 *
97 	 * The state of the widget determines what to render and how the widget
98 	 * reacts to certain 'events'.
99 	 */
100 	state_t state_;
101 
102 	/** The timer for the repeating events. */
103 	size_t repeat_timer_;
104 
105 public:
106 	/** Static type getter that does not rely on the widget being constructed. */
107 	static const std::string& type();
108 
109 private:
110 	/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
111 	virtual const std::string& get_control_type() const override;
112 
113 	/***** ***** ***** signal handlers ***** ****** *****/
114 
115 	void signal_handler_mouse_enter(const event::ui_event event, bool& handled);
116 
117 	void signal_handler_mouse_leave(const event::ui_event event, bool& handled);
118 
119 	void signal_handler_left_button_down(const event::ui_event event,
120 										 bool& handled);
121 
122 	void signal_handler_left_button_up(const event::ui_event event,
123 									   bool& handled);
124 };
125 
126 // }---------- DEFINITION ---------{
127 
128 struct repeating_button_definition : public styled_widget_definition
129 {
130 	explicit repeating_button_definition(const config& cfg);
131 
132 	struct resolution : public resolution_definition
133 	{
134 		explicit resolution(const config& cfg);
135 	};
136 };
137 
138 // }---------- BUILDER -----------{
139 
140 namespace implementation
141 {
142 
143 struct builder_repeating_button : public builder_styled_widget
144 {
145 public:
146 	explicit builder_repeating_button(const config& cfg);
147 
148 	using builder_styled_widget::build;
149 
150 	widget* build() const;
151 };
152 
153 } // namespace implementation
154 
155 // }------------ END --------------
156 
157 } // namespace gui2
158