summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/animation/animation_player.cpp15
-rw-r--r--scene/animation/animation_tree.cpp4
-rw-r--r--scene/gui/control.cpp8
-rw-r--r--scene/gui/option_button.cpp8
-rw-r--r--scene/main/canvas_item.cpp11
-rw-r--r--scene/main/canvas_item.h1
-rw-r--r--scene/main/viewport.cpp42
-rw-r--r--scene/main/viewport.h3
-rw-r--r--scene/main/window.cpp1
-rw-r--r--scene/resources/font.cpp32
10 files changed, 100 insertions, 25 deletions
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index 2e25d685d6..8087ac6250 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -857,7 +857,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
HashMap<int, TrackNodeCache::PlayingAudioStreamInfo> &map = aa->playing_streams;
// Find stream.
int idx = -1;
- if (p_seeked) {
+ if (p_seeked || p_started) {
idx = a->track_find_key(i, p_time);
// Discard previous stream when seeking.
if (map.has(idx)) {
@@ -866,12 +866,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
}
} else {
List<int> to_play;
- if (p_started) {
- int first_key = a->track_find_key(i, p_prev_time, Animation::FIND_MODE_EXACT);
- if (first_key >= 0) {
- to_play.push_back(first_key);
- }
- }
+
a->track_get_key_indices_in_range(i, p_time, p_delta, &to_play, p_looped_flag);
if (to_play.size()) {
idx = to_play.back()->get();
@@ -888,6 +883,10 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
double end_ofs = a->audio_track_get_key_end_offset(i, idx);
double len = stream->get_length();
+ if (p_seeked || p_started) {
+ start_ofs += p_time - a->track_get_key_time(i, idx);
+ }
+
if (aa->object->call(SNAME("get_stream")) != aa->audio_stream) {
aa->object->call(SNAME("set_stream"), aa->audio_stream);
aa->audio_stream_playback.unref();
@@ -1286,6 +1285,8 @@ void AnimationPlayer::_animation_process(double p_delta) {
_animation_update_transforms();
if (end_reached) {
+ _clear_audio_streams();
+ _stop_playing_caches(false);
if (queued.size()) {
String old = playback.assigned;
play(queued.front()->get());
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp
index e14aa32dfb..7c2edef1de 100644
--- a/scene/animation/animation_tree.cpp
+++ b/scene/animation/animation_tree.cpp
@@ -1566,6 +1566,10 @@ void AnimationTree::_process_graph(double p_delta) {
double end_ofs = a->audio_track_get_key_end_offset(i, idx);
double len = stream->get_length();
+ if (seeked) {
+ start_ofs += time - a->track_get_key_time(i, idx);
+ }
+
if (t->object->call(SNAME("get_stream")) != t->audio_stream) {
t->object->call(SNAME("set_stream"), t->audio_stream);
t->audio_stream_playback.unref();
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index f09e4962a9..ec75fcb665 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -644,8 +644,10 @@ Rect2 Control::get_parent_anchorable_rect() const {
parent_rect = data.parent_canvas_item->get_anchorable_rect();
} else {
#ifdef TOOLS_ENABLED
- Node *edited_root = get_tree()->get_edited_scene_root();
- if (edited_root && (this == edited_root || edited_root->is_ancestor_of(this))) {
+ Node *edited_scene_root = get_tree()->get_edited_scene_root();
+ Node *scene_root_parent = edited_scene_root ? edited_scene_root->get_parent() : nullptr;
+
+ if (scene_root_parent && get_viewport() == scene_root_parent->get_viewport()) {
parent_rect.size = Size2(GLOBAL_GET("display/window/size/viewport_width"), GLOBAL_GET("display/window/size/viewport_height"));
} else {
parent_rect = get_viewport()->get_visible_rect();
@@ -3390,7 +3392,7 @@ void Control::_bind_methods() {
ADD_SIGNAL(MethodInfo("minimum_size_changed"));
ADD_SIGNAL(MethodInfo("theme_changed"));
- GDVIRTUAL_BIND(_has_point, "position");
+ GDVIRTUAL_BIND(_has_point, "point");
GDVIRTUAL_BIND(_structured_text_parser, "args", "text");
GDVIRTUAL_BIND(_get_minimum_size);
diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp
index 027c97b383..dc1d6cc73e 100644
--- a/scene/gui/option_button.cpp
+++ b/scene/gui/option_button.cpp
@@ -491,9 +491,11 @@ void OptionButton::show_popup() {
return;
}
- Size2 button_size = get_global_transform_with_canvas().get_scale() * get_size();
- popup->set_position(get_screen_position() + Size2(0, button_size.height));
- popup->set_size(Size2i(button_size.width, 0));
+ Rect2 rect = get_screen_rect();
+ rect.position.y += rect.size.height;
+ rect.size.height = 0;
+ popup->set_position(rect.position);
+ popup->set_size(rect.size);
// If not triggered by the mouse, start the popup with the checked item (or the first enabled one) focused.
if (current != NONE_SELECTED && !popup->is_item_disabled(current)) {
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp
index 0ea8f6c5f1..906b478eb3 100644
--- a/scene/main/canvas_item.cpp
+++ b/scene/main/canvas_item.cpp
@@ -491,6 +491,17 @@ int CanvasItem::get_z_index() const {
return z_index;
}
+int CanvasItem::get_effective_z_index() const {
+ int effective_z_index = z_index;
+ if (is_z_relative()) {
+ CanvasItem *p = get_parent_item();
+ if (p) {
+ effective_z_index += p->get_effective_z_index();
+ }
+ }
+ return effective_z_index;
+}
+
void CanvasItem::set_y_sort_enabled(bool p_enabled) {
y_sort_enabled = p_enabled;
RS::get_singleton()->canvas_item_set_sort_children_by_y(canvas_item, y_sort_enabled);
diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h
index 2fa1d56667..5fbf043159 100644
--- a/scene/main/canvas_item.h
+++ b/scene/main/canvas_item.h
@@ -246,6 +246,7 @@ public:
void set_z_index(int p_z);
int get_z_index() const;
+ int get_effective_z_index() const;
void set_z_as_relative(bool p_enabled);
bool is_z_relative() const;
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 28521c5bbe..cbb34a480b 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -36,6 +36,7 @@
#include "core/object/message_queue.h"
#include "core/string/translation.h"
#include "core/templates/pair.h"
+#include "core/templates/sort_array.h"
#include "scene/2d/audio_listener_2d.h"
#include "scene/2d/camera_2d.h"
#include "scene/2d/collision_object_2d.h"
@@ -613,7 +614,7 @@ void Viewport::_process_picking() {
physics_last_mouse_state.mouse_mask.clear_flag(mouse_button_to_mask(mb->get_button_index()));
// If touch mouse raised, assume we don't know last mouse pos until new events come
- if (mb->get_device() == InputEvent::DEVICE_ID_TOUCH_MOUSE) {
+ if (mb->get_device() == InputEvent::DEVICE_ID_EMULATION) {
physics_has_last_mousepos = false;
}
}
@@ -669,6 +670,25 @@ void Viewport::_process_picking() {
point_params.pick_point = true;
int rc = ss2d->intersect_point(point_params, res, 64);
+ if (physics_object_picking_sort) {
+ struct ComparatorCollisionObjects {
+ bool operator()(const PhysicsDirectSpaceState2D::ShapeResult &p_a, const PhysicsDirectSpaceState2D::ShapeResult &p_b) const {
+ CollisionObject2D *a = Object::cast_to<CollisionObject2D>(p_a.collider);
+ CollisionObject2D *b = Object::cast_to<CollisionObject2D>(p_b.collider);
+ if (!a || !b) {
+ return false;
+ }
+ int za = a->get_effective_z_index();
+ int zb = b->get_effective_z_index();
+ if (za != zb) {
+ return zb < za;
+ }
+ return a->is_greater_than(b);
+ }
+ };
+ SortArray<PhysicsDirectSpaceState2D::ShapeResult, ComparatorCollisionObjects> sorter;
+ sorter.sort(res, rc);
+ }
for (int i = 0; i < rc; i++) {
if (res[i].collider_id.is_valid() && res[i].collider) {
CollisionObject2D *co = Object::cast_to<CollisionObject2D>(res[i].collider);
@@ -1328,7 +1348,7 @@ bool Viewport::_gui_call_input(Control *p_control, const Ref<InputEvent> &p_inpu
Ref<InputEvent> ev = p_input;
// Returns true if an event should be impacted by a control's mouse filter.
- bool is_mouse_event = Ref<InputEventMouse>(p_input).is_valid();
+ bool is_pointer_event = Ref<InputEventMouse>(p_input).is_valid() || Ref<InputEventScreenDrag>(p_input).is_valid() || Ref<InputEventScreenTouch>(p_input).is_valid();
Ref<InputEventMouseButton> mb = p_input;
bool is_scroll_event = mb.is_valid() &&
@@ -1352,8 +1372,8 @@ bool Viewport::_gui_call_input(Control *p_control, const Ref<InputEvent> &p_inpu
stopped = true;
break;
}
- if (control->data.mouse_filter == Control::MOUSE_FILTER_STOP && is_mouse_event && !(is_scroll_event && control->data.force_pass_scroll_events)) {
- // Mouse events are stopped by default with MOUSE_FILTER_STOP, unless we have a scroll event and force_pass_scroll_events set to true
+ if (control->data.mouse_filter == Control::MOUSE_FILTER_STOP && is_pointer_event && !(is_scroll_event && control->data.force_pass_scroll_events)) {
+ // Mouse, ScreenDrag and ScreenTouch events are stopped by default with MOUSE_FILTER_STOP, unless we have a scroll event and force_pass_scroll_events set to true
stopped = true;
break;
}
@@ -2270,6 +2290,7 @@ void Viewport::_drop_mouse_focus() {
mb->set_global_position(c->get_local_mouse_position());
mb->set_button_index(MouseButton(i + 1));
mb->set_pressed(false);
+ mb->set_device(InputEvent::DEVICE_ID_INTERNAL);
c->_call_gui_input(mb);
}
}
@@ -2381,6 +2402,7 @@ void Viewport::_post_gui_grab_click_focus() {
mb->set_position(click);
mb->set_button_index(MouseButton(i + 1));
mb->set_pressed(false);
+ mb->set_device(InputEvent::DEVICE_ID_INTERNAL);
gui.mouse_focus->_call_gui_input(mb);
}
}
@@ -2398,6 +2420,7 @@ void Viewport::_post_gui_grab_click_focus() {
mb->set_position(click);
mb->set_button_index(MouseButton(i + 1));
mb->set_pressed(true);
+ mb->set_device(InputEvent::DEVICE_ID_INTERNAL);
MessageQueue::get_singleton()->push_callable(callable_mp(gui.mouse_focus, &Control::_call_gui_input), mb);
}
}
@@ -2864,6 +2887,14 @@ bool Viewport::get_physics_object_picking() {
return physics_object_picking;
}
+void Viewport::set_physics_object_picking_sort(bool p_enable) {
+ physics_object_picking_sort = p_enable;
+}
+
+bool Viewport::get_physics_object_picking_sort() {
+ return physics_object_picking_sort;
+}
+
Vector2 Viewport::get_camera_coords(const Vector2 &p_viewport_coords) const {
Transform2D xf = stretch_transform * global_canvas_transform;
return xf.xform(p_viewport_coords);
@@ -3798,6 +3829,8 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_physics_object_picking", "enable"), &Viewport::set_physics_object_picking);
ClassDB::bind_method(D_METHOD("get_physics_object_picking"), &Viewport::get_physics_object_picking);
+ ClassDB::bind_method(D_METHOD("set_physics_object_picking_sort", "enable"), &Viewport::set_physics_object_picking_sort);
+ ClassDB::bind_method(D_METHOD("get_physics_object_picking_sort"), &Viewport::get_physics_object_picking_sort);
ClassDB::bind_method(D_METHOD("get_viewport_rid"), &Viewport::get_viewport_rid);
ClassDB::bind_method(D_METHOD("push_text_input", "text"), &Viewport::push_text_input);
@@ -3949,6 +3982,7 @@ void Viewport::_bind_methods() {
#endif
ADD_GROUP("Physics", "physics_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "physics_object_picking"), "set_physics_object_picking", "get_physics_object_picking");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "physics_object_picking_sort"), "set_physics_object_picking_sort", "get_physics_object_picking_sort");
ADD_GROUP("GUI", "gui_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gui_disable_input"), "set_disable_input", "is_input_disabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gui_snap_controls_to_pixels"), "set_snap_controls_to_pixels", "is_snap_controls_to_pixels_enabled");
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 2142aaaaef..4144eaabb9 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -246,6 +246,7 @@ private:
bool snap_2d_vertices_to_pixel = false;
bool physics_object_picking = false;
+ bool physics_object_picking_sort = false;
List<Ref<InputEvent>> physics_picking_events;
ObjectID physics_object_capture;
ObjectID physics_object_over;
@@ -574,6 +575,8 @@ public:
void set_physics_object_picking(bool p_enable);
bool get_physics_object_picking();
+ void set_physics_object_picking_sort(bool p_enable);
+ bool get_physics_object_picking_sort();
Variant gui_get_drag_data() const;
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index 33946246b0..9fcfb29ef7 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -647,6 +647,7 @@ void Window::update_mouse_cursor_shape() {
mm.instantiate();
mm->set_position(pos);
mm->set_global_position(xform.xform(pos));
+ mm->set_device(InputEvent::DEVICE_ID_INTERNAL);
push_input(mm);
}
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp
index e5a1adff20..0f7985bee6 100644
--- a/scene/resources/font.cpp
+++ b/scene/resources/font.cpp
@@ -2712,6 +2712,9 @@ Ref<Font> FontVariation::_get_base_font_or_default() const {
for (const StringName &E : theme_types) {
if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
Ref<Font> f = ThemeDB::get_singleton()->get_project_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
+ if (f == this) {
+ continue;
+ }
if (f.is_valid()) {
theme_font = f;
theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
@@ -2729,6 +2732,9 @@ Ref<Font> FontVariation::_get_base_font_or_default() const {
for (const StringName &E : theme_types) {
if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
Ref<Font> f = ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
+ if (f == this) {
+ continue;
+ }
if (f.is_valid()) {
theme_font = f;
theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
@@ -2739,11 +2745,13 @@ Ref<Font> FontVariation::_get_base_font_or_default() const {
// If they don't exist, use any type to return the default/empty value.
Ref<Font> f = ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName());
- if (f.is_valid()) {
- theme_font = f;
- theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
+ if (f != this) {
+ if (f.is_valid()) {
+ theme_font = f;
+ theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
+ }
+ return f;
}
- return f;
}
return Ref<Font>();
@@ -3061,6 +3069,9 @@ Ref<Font> SystemFont::_get_base_font_or_default() const {
for (const StringName &E : theme_types) {
if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
Ref<Font> f = ThemeDB::get_singleton()->get_project_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
+ if (f == this) {
+ continue;
+ }
if (f.is_valid()) {
theme_font = f;
theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
@@ -3078,6 +3089,9 @@ Ref<Font> SystemFont::_get_base_font_or_default() const {
for (const StringName &E : theme_types) {
if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
Ref<Font> f = ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
+ if (f == this) {
+ continue;
+ }
if (f.is_valid()) {
theme_font = f;
theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
@@ -3088,11 +3102,13 @@ Ref<Font> SystemFont::_get_base_font_or_default() const {
// If they don't exist, use any type to return the default/empty value.
Ref<Font> f = ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName());
- if (f.is_valid()) {
- theme_font = f;
- theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
+ if (f != this) {
+ if (f.is_valid()) {
+ theme_font = f;
+ theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
+ }
+ return f;
}
- return f;
}
return Ref<Font>();