Merge pull request #110893 from Kazox61/basebutton-multitouch
`BaseButton`: multitouch support
This commit is contained in:
@@ -33,7 +33,7 @@
|
||||
[/csharp]
|
||||
[/codeblocks]
|
||||
See also [BaseButton] which contains common properties and methods associated with this node.
|
||||
[b]Note:[/b] Buttons do not detect touch input and therefore don't support multitouch, since mouse emulation can only press one button at a given time. Use [TouchScreenButton] for buttons that trigger gameplay movement or actions.
|
||||
[b]Note:[/b] Buttons support multitouch via touch input, allowing multiple buttons to be pressed at the same time. Otherwise, mouse input is used, limiting interaction to one button press at a time.
|
||||
</description>
|
||||
<tutorials>
|
||||
<link title="2D Dodge The Creeps Demo">https://godotengine.org/asset-library/asset/2712</link>
|
||||
|
||||
@@ -63,6 +63,45 @@ void BaseButton::gui_input(const Ref<InputEvent> &p_event) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (p_event->get_device() == InputEvent::DEVICE_ID_EMULATION) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (p_event->is_pressed()) {
|
||||
status.device_id = p_event->get_device();
|
||||
}
|
||||
|
||||
if (p_event->get_device() != status.device_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
Ref<InputEventScreenTouch> touch = p_event;
|
||||
if (touch.is_valid()) {
|
||||
if (status.touch_index == -1) {
|
||||
if (touch->is_pressed()) {
|
||||
status.touch_index = touch->get_index();
|
||||
status.press_attempt = true;
|
||||
status.pressing_inside = has_point(touch->get_position());
|
||||
on_action_event(p_event);
|
||||
}
|
||||
} else if (touch->get_index() == status.touch_index) {
|
||||
if (!touch->is_pressed()) {
|
||||
status.touch_index = -1;
|
||||
on_action_event(p_event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ref<InputEventScreenDrag> drag = p_event;
|
||||
if (drag.is_valid() && drag->get_index() == status.touch_index && status.press_attempt) {
|
||||
bool last_press_inside = status.pressing_inside;
|
||||
status.pressing_inside = has_point(drag->get_position());
|
||||
|
||||
if (last_press_inside != status.pressing_inside) {
|
||||
queue_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
Ref<InputEventMouseButton> mouse_button = p_event;
|
||||
bool ui_accept = p_event->is_action("ui_accept", true) && !p_event->is_echo();
|
||||
|
||||
@@ -154,6 +193,7 @@ void BaseButton::_notification(int p_what) {
|
||||
case NOTIFICATION_SCROLL_BEGIN: {
|
||||
if (status.press_attempt) {
|
||||
status.press_attempt = false;
|
||||
status.touch_index = -1;
|
||||
queue_redraw();
|
||||
}
|
||||
} break;
|
||||
@@ -165,6 +205,7 @@ void BaseButton::_notification(int p_what) {
|
||||
case NOTIFICATION_FOCUS_EXIT: {
|
||||
if (status.press_attempt) {
|
||||
status.press_attempt = false;
|
||||
status.touch_index = -1;
|
||||
queue_redraw();
|
||||
} else if (status.hovering) {
|
||||
queue_redraw();
|
||||
@@ -187,6 +228,7 @@ void BaseButton::_notification(int p_what) {
|
||||
status.hovering = false;
|
||||
status.press_attempt = false;
|
||||
status.pressing_inside = false;
|
||||
status.touch_index = -1;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
@@ -205,8 +247,11 @@ void BaseButton::_toggled(bool p_pressed) {
|
||||
|
||||
void BaseButton::on_action_event(Ref<InputEvent> p_event) {
|
||||
Ref<InputEventMouseButton> mouse_button = p_event;
|
||||
Ref<InputEventScreenTouch> screen_touch = p_event;
|
||||
Ref<InputEventScreenDrag> screen_drag = p_event;
|
||||
|
||||
if (p_event->is_pressed() && (mouse_button.is_null() || status.hovering)) {
|
||||
bool is_accept_event = mouse_button.is_null() && screen_touch.is_null() && screen_drag.is_null();
|
||||
if (p_event->is_pressed() && (is_accept_event || status.hovering)) {
|
||||
status.press_attempt = true;
|
||||
status.pressing_inside = true;
|
||||
if (!status.pressed_down_with_focus) {
|
||||
|
||||
@@ -63,7 +63,8 @@ private:
|
||||
bool pressing_inside = false;
|
||||
bool pressed_down_with_focus = false;
|
||||
bool disabled = false;
|
||||
|
||||
int touch_index = -1;
|
||||
int device_id = InputEvent::DEVICE_ID_EMULATION;
|
||||
} status;
|
||||
|
||||
Ref<ButtonGroup> button_group;
|
||||
|
||||
Reference in New Issue
Block a user