1/**************************************************************************/
2/* base_button.h */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#ifndef BASE_BUTTON_H
32#define BASE_BUTTON_H
33
34#include "core/input/shortcut.h"
35#include "scene/gui/control.h"
36
37class ButtonGroup;
38
39class BaseButton : public Control {
40 GDCLASS(BaseButton, Control);
41
42public:
43 enum ActionMode {
44 ACTION_MODE_BUTTON_PRESS,
45 ACTION_MODE_BUTTON_RELEASE,
46 };
47
48private:
49 BitField<MouseButtonMask> button_mask = MouseButtonMask::LEFT;
50 bool toggle_mode = false;
51 bool shortcut_in_tooltip = true;
52 bool was_mouse_pressed = false;
53 bool keep_pressed_outside = false;
54 bool shortcut_feedback = true;
55 Ref<Shortcut> shortcut;
56 ObjectID shortcut_context;
57
58 ActionMode action_mode = ACTION_MODE_BUTTON_RELEASE;
59 struct Status {
60 bool pressed = false;
61 bool hovering = false;
62 bool press_attempt = false;
63 bool pressing_inside = false;
64
65 bool disabled = false;
66
67 } status;
68
69 Ref<ButtonGroup> button_group;
70
71 void _unpress_group();
72 void _pressed();
73 void _toggled(bool p_pressed);
74
75 void on_action_event(Ref<InputEvent> p_event);
76
77 Timer *shortcut_feedback_timer = nullptr;
78 bool in_shortcut_feedback = false;
79 void _shortcut_feedback_timeout();
80
81protected:
82 virtual void pressed();
83 virtual void toggled(bool p_pressed);
84 static void _bind_methods();
85 virtual void gui_input(const Ref<InputEvent> &p_event) override;
86 virtual void shortcut_input(const Ref<InputEvent> &p_event) override;
87 void _notification(int p_what);
88
89 bool _was_pressed_by_mouse() const;
90
91 GDVIRTUAL0(_pressed)
92 GDVIRTUAL1(_toggled, bool)
93
94public:
95 enum DrawMode {
96 DRAW_NORMAL,
97 DRAW_PRESSED,
98 DRAW_HOVER,
99 DRAW_DISABLED,
100 DRAW_HOVER_PRESSED,
101 };
102
103 DrawMode get_draw_mode() const;
104
105 /* Signals */
106
107 bool is_pressed() const; ///< return whether button is pressed (toggled in)
108 bool is_pressing() const; ///< return whether button is pressed (toggled in)
109 bool is_hovered() const;
110
111 void set_pressed(bool p_pressed); // Only works in toggle mode.
112 void set_pressed_no_signal(bool p_pressed);
113 void set_toggle_mode(bool p_on);
114 bool is_toggle_mode() const;
115
116 void set_shortcut_in_tooltip(bool p_on);
117 bool is_shortcut_in_tooltip_enabled() const;
118
119 void set_disabled(bool p_disabled);
120 bool is_disabled() const;
121
122 void set_action_mode(ActionMode p_mode);
123 ActionMode get_action_mode() const;
124
125 void set_keep_pressed_outside(bool p_on);
126 bool is_keep_pressed_outside() const;
127
128 void set_shortcut_feedback(bool p_enable);
129 bool is_shortcut_feedback() const;
130
131 void set_button_mask(BitField<MouseButtonMask> p_mask);
132 BitField<MouseButtonMask> get_button_mask() const;
133
134 void set_shortcut(const Ref<Shortcut> &p_shortcut);
135 Ref<Shortcut> get_shortcut() const;
136
137 virtual String get_tooltip(const Point2 &p_pos) const override;
138
139 void set_button_group(const Ref<ButtonGroup> &p_group);
140 Ref<ButtonGroup> get_button_group() const;
141
142 PackedStringArray get_configuration_warnings() const override;
143
144 BaseButton();
145 ~BaseButton();
146};
147
148VARIANT_ENUM_CAST(BaseButton::DrawMode)
149VARIANT_ENUM_CAST(BaseButton::ActionMode)
150
151class ButtonGroup : public Resource {
152 GDCLASS(ButtonGroup, Resource);
153 friend class BaseButton;
154 HashSet<BaseButton *> buttons;
155 bool allow_unpress = false;
156
157protected:
158 static void _bind_methods();
159
160public:
161 BaseButton *get_pressed_button();
162 void get_buttons(List<BaseButton *> *r_buttons);
163 TypedArray<BaseButton> _get_buttons();
164 void set_allow_unpress(bool p_enabled);
165 bool is_allow_unpress();
166 ButtonGroup();
167};
168
169#endif // BASE_BUTTON_H
170