feat: updated engine

This commit is contained in:
Sara Gerretsen 2026-07-10 17:04:34 +02:00
parent cbe99774ff
commit f4cf6b3999
6607 changed files with 910135 additions and 430025 deletions

View file

@ -31,9 +31,12 @@
#include "base_button.h"
#include "core/config/project_settings.h"
#include "core/object/callable_mp.h"
#include "core/object/class_db.h"
#include "scene/gui/label.h"
#include "scene/main/timer.h"
#include "scene/main/window.h"
#include "scene/theme/theme_db.h"
#include "servers/display/accessibility_server.h"
void BaseButton::_unpress_group() {
if (button_group.is_null()) {
@ -61,6 +64,37 @@ void BaseButton::gui_input(const Ref<InputEvent> &p_event) {
return;
}
if (p_event->get_device() == InputEvent::DEVICE_ID_EMULATION) {
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();
@ -69,17 +103,15 @@ void BaseButton::gui_input(const Ref<InputEvent> &p_event) {
was_mouse_pressed = button_masked;
on_action_event(p_event);
was_mouse_pressed = false;
return;
}
Ref<InputEventMouseMotion> mouse_motion = p_event;
if (mouse_motion.is_valid()) {
if (status.press_attempt) {
bool last_press_inside = status.pressing_inside;
status.pressing_inside = has_point(mouse_motion->get_position());
if (last_press_inside != status.pressing_inside) {
queue_redraw();
} else {
Ref<InputEventMouseMotion> mouse_motion = p_event;
if (mouse_motion.is_valid()) {
if (status.press_attempt) {
bool last_press_inside = status.pressing_inside;
status.pressing_inside = has_point(mouse_motion->get_position());
if (last_press_inside != status.pressing_inside) {
queue_redraw();
}
}
}
}
@ -111,19 +143,19 @@ void BaseButton::_notification(int p_what) {
RID ae = get_accessibility_element();
ERR_FAIL_COND(ae.is_null());
DisplayServer::get_singleton()->accessibility_update_set_role(ae, DisplayServer::AccessibilityRole::ROLE_BUTTON);
AccessibilityServer::get_singleton()->update_set_role(ae, AccessibilityServerEnums::AccessibilityRole::ROLE_BUTTON);
DisplayServer::get_singleton()->accessibility_update_add_action(ae, DisplayServer::AccessibilityAction::ACTION_CLICK, callable_mp(this, &BaseButton::_accessibility_action_click));
DisplayServer::get_singleton()->accessibility_update_set_flag(ae, DisplayServer::AccessibilityFlags::FLAG_DISABLED, status.disabled);
AccessibilityServer::get_singleton()->update_add_action(ae, AccessibilityServerEnums::AccessibilityAction::ACTION_CLICK, callable_mp(this, &BaseButton::_accessibility_action_click));
AccessibilityServer::get_singleton()->update_set_flag(ae, AccessibilityServerEnums::AccessibilityFlags::FLAG_DISABLED, status.disabled);
if (toggle_mode) {
DisplayServer::get_singleton()->accessibility_update_set_checked(ae, status.pressed);
AccessibilityServer::get_singleton()->update_set_checked(ae, status.pressed);
}
if (button_group.is_valid()) {
for (const BaseButton *btn : button_group->buttons) {
if (btn->is_part_of_edited_scene()) {
continue;
}
DisplayServer::get_singleton()->accessibility_update_add_related_radio_group(ae, btn->get_accessibility_element());
AccessibilityServer::get_singleton()->update_add_related_radio_group(ae, btn->get_accessibility_element());
}
}
if (shortcut_in_tooltip && shortcut.is_valid() && shortcut->has_valid_event()) {
@ -132,7 +164,7 @@ void BaseButton::_notification(int p_what) {
if (!tooltip.is_empty() && shortcut->get_name().nocasecmp_to(tooltip) != 0) {
text += "\n" + atr(tooltip);
}
DisplayServer::get_singleton()->accessibility_update_set_tooltip(ae, text);
AccessibilityServer::get_singleton()->update_set_tooltip(ae, text);
}
} break;
@ -152,6 +184,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;
@ -163,6 +196,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();
@ -185,6 +219,7 @@ void BaseButton::_notification(int p_what) {
status.hovering = false;
status.press_attempt = false;
status.pressing_inside = false;
status.touch_index = -1;
} break;
}
}
@ -203,8 +238,12 @@ 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();
bool is_touch_press_inside = screen_touch.is_valid() && screen_touch->is_pressed() && status.pressing_inside;
if (p_event->is_pressed() && (is_accept_event || status.hovering || is_touch_press_inside)) {
status.press_attempt = true;
status.pressing_inside = true;
if (!status.pressed_down_with_focus) {
@ -220,6 +259,7 @@ void BaseButton::on_action_event(Ref<InputEvent> p_event) {
if (action_mode == ACTION_MODE_BUTTON_PRESS) {
status.press_attempt = false;
status.pressing_inside = false;
status.touch_index = -1; // Action completed, release matching touch so later taps aren't dropped if a modal consumes the release.
}
status.pressed = !status.pressed;
_unpress_group();
@ -357,6 +397,16 @@ BaseButton::DrawMode BaseButton::get_draw_mode() const {
}
}
bool BaseButton::has_point(const Point2 &p_point) const {
ERR_READ_THREAD_GUARD_V(false);
bool ret;
if (GDVIRTUAL_CALL(_has_point, p_point, ret)) {
return ret;
}
Rect2 rect = Rect2(Point2(), get_size()).grow(theme_cache.click_margin);
return rect.has_area() && rect.has_point(p_point);
}
void BaseButton::set_toggle_mode(bool p_on) {
// Make sure to set 'pressed' to false if we are not in toggle mode
if (!p_on) {
@ -457,6 +507,7 @@ void BaseButton::shortcut_input(const Ref<InputEvent> &p_event) {
if (shortcut_feedback_timer == nullptr) {
shortcut_feedback_timer = memnew(Timer);
shortcut_feedback_timer->set_one_shot(true);
shortcut_feedback_timer->set_ignore_time_scale(true);
add_child(shortcut_feedback_timer, false, INTERNAL_MODE_BACK);
shortcut_feedback_timer->set_wait_time(GLOBAL_GET_CACHED(double, "gui/timers/button_shortcut_feedback_highlight_time"));
shortcut_feedback_timer->connect("timeout", callable_mp(this, &BaseButton::_shortcut_feedback_timeout));
@ -473,11 +524,21 @@ Control *BaseButton::make_custom_tooltip(const String &p_text) const {
if (control) {
return control;
}
if (!shortcut_in_tooltip || shortcut.is_null() || !shortcut->has_valid_event()) {
if (!shortcut_in_tooltip || shortcut.is_null()) {
return nullptr; // Use the default tooltip label.
}
String text = atr(shortcut->get_name()) + " (" + shortcut->get_as_text() + ")";
bool shortcut_has_events = shortcut->has_valid_event();
if (!shortcut_has_events && shortcut->get_name().is_empty()) {
return nullptr;
}
String text = atr(shortcut->get_name());
if (shortcut_has_events) {
text += " (" + shortcut->get_as_text() + ")";
}
if (!p_text.is_empty() && shortcut->get_name().nocasecmp_to(p_text) != 0) {
text += "\n" + atr(p_text);
}
@ -570,13 +631,15 @@ void BaseButton::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "action_mode", PROPERTY_HINT_ENUM, "Button Press,Button Release"), "set_action_mode", "get_action_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "button_mask", PROPERTY_HINT_FLAGS, "Mouse Left, Mouse Right, Mouse Middle"), "set_button_mask", "get_button_mask");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_pressed_outside"), "set_keep_pressed_outside", "is_keep_pressed_outside");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "button_group", PROPERTY_HINT_RESOURCE_TYPE, "ButtonGroup"), "set_button_group", "get_button_group");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "button_group", PROPERTY_HINT_RESOURCE_TYPE, ButtonGroup::get_class_static()), "set_button_group", "get_button_group");
ADD_GROUP("Shortcut", "");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shortcut", PROPERTY_HINT_RESOURCE_TYPE, "Shortcut"), "set_shortcut", "get_shortcut");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shortcut", PROPERTY_HINT_RESOURCE_TYPE, Shortcut::get_class_static()), "set_shortcut", "get_shortcut");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shortcut_feedback"), "set_shortcut_feedback", "is_shortcut_feedback");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shortcut_in_tooltip"), "set_shortcut_in_tooltip", "is_shortcut_in_tooltip_enabled");
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, BaseButton, click_margin);
BIND_ENUM_CONSTANT(DRAW_NORMAL);
BIND_ENUM_CONSTANT(DRAW_PRESSED);
BIND_ENUM_CONSTANT(DRAW_HOVER);
@ -639,7 +702,7 @@ void ButtonGroup::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_unpress"), "set_allow_unpress", "is_allow_unpress");
ADD_SIGNAL(MethodInfo("pressed", PropertyInfo(Variant::OBJECT, "button", PROPERTY_HINT_RESOURCE_TYPE, "BaseButton")));
ADD_SIGNAL(MethodInfo("pressed", PropertyInfo(Variant::OBJECT, "button", PROPERTY_HINT_RESOURCE_TYPE, BaseButton::get_class_static())));
}
ButtonGroup::ButtonGroup() {