summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/navigation_region_2d.cpp8
-rw-r--r--scene/3d/node_3d.cpp128
-rw-r--r--scene/3d/node_3d.h21
-rw-r--r--scene/3d/visual_instance_3d.cpp13
-rw-r--r--scene/3d/visual_instance_3d.h4
-rw-r--r--scene/animation/animation_player.cpp20
-rw-r--r--scene/gui/button.cpp5
-rw-r--r--scene/gui/code_edit.cpp103
-rw-r--r--scene/gui/control.cpp52
-rw-r--r--scene/gui/graph_edit.cpp31
-rw-r--r--scene/gui/graph_edit.h1
-rw-r--r--scene/gui/subviewport_container.cpp1
-rw-r--r--scene/gui/tab_container.cpp25
-rw-r--r--scene/gui/tree.cpp17
-rw-r--r--scene/main/node.cpp59
-rw-r--r--scene/main/node.h1
-rw-r--r--scene/main/viewport.cpp6
-rw-r--r--scene/property_utils.cpp33
-rw-r--r--scene/register_scene_types.cpp2
-rw-r--r--scene/resources/animation.cpp1
-rw-r--r--scene/resources/default_theme/default_theme.cpp16
-rw-r--r--scene/resources/material.cpp12
-rw-r--r--scene/resources/skin.h6
-rw-r--r--scene/resources/theme.cpp138
-rw-r--r--scene/resources/theme.h56
-rw-r--r--scene/resources/visual_shader.cpp4
-rw-r--r--scene/resources/visual_shader.h2
27 files changed, 484 insertions, 281 deletions
diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp
index cf966573ee..34f5830d8d 100644
--- a/scene/2d/navigation_region_2d.cpp
+++ b/scene/2d/navigation_region_2d.cpp
@@ -363,10 +363,10 @@ void NavigationRegion2D::set_enabled(bool p_enabled) {
if (!enabled) {
NavigationServer2D::get_singleton()->region_set_map(region, RID());
- NavigationServer2D::get_singleton()->disconnect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
+ NavigationServer2D::get_singleton_mut()->disconnect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
} else {
NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map());
- NavigationServer2D::get_singleton()->connect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
+ NavigationServer2D::get_singleton_mut()->connect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
}
if (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()) {
@@ -402,7 +402,7 @@ void NavigationRegion2D::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
if (enabled) {
NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map());
- NavigationServer2D::get_singleton()->connect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
+ NavigationServer2D::get_singleton_mut()->connect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
}
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
@@ -411,7 +411,7 @@ void NavigationRegion2D::_notification(int p_what) {
case NOTIFICATION_EXIT_TREE: {
NavigationServer2D::get_singleton()->region_set_map(region, RID());
if (enabled) {
- NavigationServer2D::get_singleton()->disconnect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
+ NavigationServer2D::get_singleton_mut()->disconnect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
}
} break;
case NOTIFICATION_DRAW: {
diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp
index 2a611d9ce7..a992d2aaf2 100644
--- a/scene/3d/node_3d.cpp
+++ b/scene/3d/node_3d.cpp
@@ -33,6 +33,7 @@
#include "core/object/message_queue.h"
#include "scene/3d/visual_instance_3d.h"
#include "scene/main/viewport.h"
+#include "scene/property_utils.h"
#include "scene/scene_string_names.h"
/*
@@ -84,6 +85,9 @@ void Node3D::_notify_dirty() {
}
void Node3D::_update_local_transform() const {
+ if (this->get_rotation_edit_mode() != ROTATION_EDIT_MODE_BASIS) {
+ data.local_transform = data.local_transform.orthogonalized();
+ }
data.local_transform.basis.set_euler_scale(data.rotation, data.scale);
data.dirty &= ~DIRTY_LOCAL;
@@ -172,6 +176,7 @@ void Node3D::_notification(int p_what) {
if (get_script_instance()) {
get_script_instance()->call(SceneStringNames::get_singleton()->_enter_world);
}
+
#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint() && get_tree()->is_node_being_edited(this)) {
get_tree()->call_group_flags(0, SceneStringNames::get_singleton()->_spatial_editor_group, SceneStringNames::get_singleton()->_request_gizmo, this);
@@ -186,7 +191,6 @@ void Node3D::_notification(int p_what) {
}
}
#endif
-
} break;
case NOTIFICATION_EXIT_WORLD: {
#ifdef TOOLS_ENABLED
@@ -321,6 +325,14 @@ void Node3D::set_rotation_edit_mode(RotationEditMode p_mode) {
return;
}
data.rotation_edit_mode = p_mode;
+
+ // Shearing is not allowed except in ROTATION_EDIT_MODE_BASIS.
+ data.dirty |= DIRTY_LOCAL;
+ _propagate_transform_changed(this);
+ if (data.notify_local_transform) {
+ notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED);
+ }
+
notify_property_list_changed();
}
@@ -456,7 +468,6 @@ void Node3D::clear_subgizmo_selection() {
void Node3D::add_gizmo(Ref<Node3DGizmo> p_gizmo) {
#ifdef TOOLS_ENABLED
-
if (data.gizmos_disabled || p_gizmo.is_null()) {
return;
}
@@ -474,7 +485,6 @@ void Node3D::add_gizmo(Ref<Node3DGizmo> p_gizmo) {
void Node3D::remove_gizmo(Ref<Node3DGizmo> p_gizmo) {
#ifdef TOOLS_ENABLED
-
int idx = data.gizmos.find(p_gizmo);
if (idx != -1) {
p_gizmo->free();
@@ -506,10 +516,8 @@ Array Node3D::get_gizmos_bind() const {
Vector<Ref<Node3DGizmo>> Node3D::get_gizmos() const {
#ifdef TOOLS_ENABLED
-
return data.gizmos;
#else
-
return Vector<Ref<Node3DGizmo>>();
#endif
}
@@ -561,7 +569,6 @@ void Node3D::set_as_top_level(bool p_enabled) {
data.top_level = p_enabled;
data.top_level_active = p_enabled;
-
} else {
data.top_level = p_enabled;
}
@@ -581,6 +588,7 @@ Ref<World3D> Node3D::get_world_3d() const {
void Node3D::_propagate_visibility_changed() {
notification(NOTIFICATION_VISIBILITY_CHANGED);
emit_signal(SceneStringNames::get_singleton()->visibility_changed);
+
#ifdef TOOLS_ENABLED
if (!data.gizmos.is_empty()) {
data.gizmos_dirty = true;
@@ -597,33 +605,30 @@ void Node3D::_propagate_visibility_changed() {
}
void Node3D::show() {
- if (data.visible) {
- return;
- }
-
- data.visible = true;
-
- if (!is_inside_tree()) {
- return;
- }
-
- _propagate_visibility_changed();
+ set_visible(true);
}
void Node3D::hide() {
- if (!data.visible) {
+ set_visible(false);
+}
+
+void Node3D::set_visible(bool p_visible) {
+ if (data.visible == p_visible) {
return;
}
- data.visible = false;
+ data.visible = p_visible;
if (!is_inside_tree()) {
return;
}
-
_propagate_visibility_changed();
}
+bool Node3D::is_visible() const {
+ return data.visible;
+}
+
bool Node3D::is_visible_in_tree() const {
const Node3D *s = this;
@@ -637,18 +642,6 @@ bool Node3D::is_visible_in_tree() const {
return true;
}
-void Node3D::set_visible(bool p_visible) {
- if (p_visible) {
- show();
- } else {
- hide();
- }
-}
-
-bool Node3D::is_visible() const {
- return data.visible;
-}
-
void Node3D::rotate_object_local(const Vector3 &p_axis, real_t p_angle) {
Transform3D t = get_transform();
t.basis.rotate_local(p_axis, p_angle);
@@ -757,16 +750,16 @@ Vector3 Node3D::to_global(Vector3 p_local) const {
return get_global_transform().xform(p_local);
}
-void Node3D::set_notify_transform(bool p_enable) {
- data.notify_transform = p_enable;
+void Node3D::set_notify_transform(bool p_enabled) {
+ data.notify_transform = p_enabled;
}
bool Node3D::is_transform_notification_enabled() const {
return data.notify_transform;
}
-void Node3D::set_notify_local_transform(bool p_enable) {
- data.notify_local_transform = p_enable;
+void Node3D::set_notify_local_transform(bool p_enabled) {
+ data.notify_local_transform = p_enabled;
}
bool Node3D::is_local_transform_notification_enabled() const {
@@ -845,6 +838,64 @@ void Node3D::_validate_property(PropertyInfo &property) const {
}
}
+bool Node3D::property_can_revert(const String &p_name) {
+ if (p_name == "basis") {
+ return true;
+ } else if (p_name == "scale") {
+ return true;
+ } else if (p_name == "quaternion") {
+ return true;
+ } else if (p_name == "rotation") {
+ return true;
+ } else if (p_name == "position") {
+ return true;
+ }
+ return false;
+}
+
+Variant Node3D::property_get_revert(const String &p_name) {
+ Variant r_ret;
+ bool valid = false;
+
+ if (p_name == "basis") {
+ Variant variant = PropertyUtils::get_property_default_value(this, "transform", &valid);
+ if (valid && variant.get_type() == Variant::Type::TRANSFORM3D) {
+ r_ret = Transform3D(variant).get_basis();
+ } else {
+ r_ret = Basis();
+ }
+ } else if (p_name == "scale") {
+ Variant variant = PropertyUtils::get_property_default_value(this, "transform", &valid);
+ if (valid && variant.get_type() == Variant::Type::TRANSFORM3D) {
+ r_ret = Transform3D(variant).get_basis().get_scale();
+ } else {
+ return Vector3(1.0, 1.0, 1.0);
+ }
+ } else if (p_name == "quaternion") {
+ Variant variant = PropertyUtils::get_property_default_value(this, "transform", &valid);
+ if (valid && variant.get_type() == Variant::Type::TRANSFORM3D) {
+ r_ret = Quaternion(Transform3D(variant).get_basis());
+ } else {
+ return Quaternion();
+ }
+ } else if (p_name == "rotation") {
+ Variant variant = PropertyUtils::get_property_default_value(this, "transform", &valid);
+ if (valid && variant.get_type() == Variant::Type::TRANSFORM3D) {
+ r_ret = Transform3D(variant).get_basis().get_euler_normalized(data.rotation_order);
+ } else {
+ return Vector3();
+ }
+ } else if (p_name == "position") {
+ Variant variant = PropertyUtils::get_property_default_value(this, "transform", &valid);
+ if (valid) {
+ r_ret = Transform3D(variant).get_origin();
+ } else {
+ return Vector3();
+ }
+ }
+ return r_ret;
+}
+
void Node3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_transform", "local"), &Node3D::set_transform);
ClassDB::bind_method(D_METHOD("get_transform"), &Node3D::get_transform);
@@ -916,6 +967,9 @@ void Node3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("to_local", "global_point"), &Node3D::to_local);
ClassDB::bind_method(D_METHOD("to_global", "local_point"), &Node3D::to_global);
+ ClassDB::bind_method(D_METHOD("property_can_revert", "name"), &Node3D::property_can_revert);
+ ClassDB::bind_method(D_METHOD("property_get_revert", "name"), &Node3D::property_get_revert);
+
BIND_CONSTANT(NOTIFICATION_TRANSFORM_CHANGED);
BIND_CONSTANT(NOTIFICATION_ENTER_WORLD);
BIND_CONSTANT(NOTIFICATION_EXIT_WORLD);
@@ -934,6 +988,7 @@ void Node3D::_bind_methods() {
//ADD_PROPERTY( PropertyInfo(Variant::TRANSFORM3D,"transform/global",PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR ), "set_global_transform", "get_global_transform") ;
ADD_GROUP("Transform", "");
+ ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_transform", "get_transform");
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "global_transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_global_transform", "get_global_transform");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "position", PROPERTY_HINT_RANGE, "-99999,99999,0,or_greater,or_lesser,noslider,suffix:m", PROPERTY_USAGE_EDITOR), "set_position", "get_position");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians", PROPERTY_USAGE_EDITOR), "set_rotation", "get_rotation");
@@ -943,7 +998,6 @@ void Node3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "rotation_edit_mode", PROPERTY_HINT_ENUM, "Euler,Quaternion,Basis"), "set_rotation_edit_mode", "get_rotation_edit_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "rotation_order", PROPERTY_HINT_ENUM, "XYZ,XZY,YXZ,YZX,ZXY,ZYX"), "set_rotation_order", "get_rotation_order");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "top_level"), "set_as_top_level", "is_set_as_top_level");
- ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_transform", "get_transform");
ADD_GROUP("Visibility", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible");
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "visibility_parent", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "GeometryInstance3D"), "set_visibility_parent", "get_visibility_parent");
diff --git a/scene/3d/node_3d.h b/scene/3d/node_3d.h
index 31f7d45797..4abda66187 100644
--- a/scene/3d/node_3d.h
+++ b/scene/3d/node_3d.h
@@ -137,6 +137,9 @@ protected:
virtual void _validate_property(PropertyInfo &property) const override;
+ bool property_can_revert(const String &p_name);
+ Variant property_get_revert(const String &p_name);
+
public:
enum {
NOTIFICATION_TRANSFORM_CHANGED = SceneTree::NOTIFICATION_TRANSFORM_CHANGED,
@@ -182,12 +185,6 @@ public:
virtual bool is_transform_gizmo_visible() const { return data.transform_gizmo_visible; };
#endif
- void set_as_top_level(bool p_enabled);
- bool is_set_as_top_level() const;
-
- void set_disable_scale(bool p_enabled);
- bool is_scale_disabled() const;
-
void set_disable_gizmos(bool p_enabled);
void update_gizmos();
void set_subgizmo_selection(Ref<Node3DGizmo> p_gizmo, int p_id, Transform3D p_transform = Transform3D());
@@ -198,6 +195,12 @@ public:
void remove_gizmo(Ref<Node3DGizmo> p_gizmo);
void clear_gizmos();
+ void set_as_top_level(bool p_enabled);
+ bool is_set_as_top_level() const;
+
+ void set_disable_scale(bool p_enabled);
+ bool is_scale_disabled() const;
+
_FORCE_INLINE_ bool is_inside_world() const { return data.inside_world; }
Transform3D get_relative_transform(const Node *p_parent) const;
@@ -223,19 +226,19 @@ public:
Vector3 to_local(Vector3 p_global) const;
Vector3 to_global(Vector3 p_local) const;
- void set_notify_transform(bool p_enable);
+ void set_notify_transform(bool p_enabled);
bool is_transform_notification_enabled() const;
- void set_notify_local_transform(bool p_enable);
+ void set_notify_local_transform(bool p_enabled);
bool is_local_transform_notification_enabled() const;
void orthonormalize();
void set_identity();
void set_visible(bool p_visible);
- bool is_visible() const;
void show();
void hide();
+ bool is_visible() const;
bool is_visible_in_tree() const;
void force_update_transform();
diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp
index 13729db618..0db2fe9fc6 100644
--- a/scene/3d/visual_instance_3d.cpp
+++ b/scene/3d/visual_instance_3d.cpp
@@ -152,6 +152,15 @@ Ref<Material> GeometryInstance3D::get_material_override() const {
return material_override;
}
+void GeometryInstance3D::set_material_overlay(const Ref<Material> &p_material) {
+ material_overlay = p_material;
+ RS::get_singleton()->instance_geometry_set_material_overlay(get_instance(), p_material.is_valid() ? p_material->get_rid() : RID());
+}
+
+Ref<Material> GeometryInstance3D::get_material_overlay() const {
+ return material_overlay;
+}
+
void GeometryInstance3D::set_transparecy(float p_transparency) {
transparency = CLAMP(p_transparency, 0.0f, 1.0f);
RS::get_singleton()->instance_geometry_set_transparency(get_instance(), transparency);
@@ -398,6 +407,9 @@ void GeometryInstance3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_material_override", "material"), &GeometryInstance3D::set_material_override);
ClassDB::bind_method(D_METHOD("get_material_override"), &GeometryInstance3D::get_material_override);
+ ClassDB::bind_method(D_METHOD("set_material_overlay", "material"), &GeometryInstance3D::set_material_overlay);
+ ClassDB::bind_method(D_METHOD("get_material_overlay"), &GeometryInstance3D::get_material_overlay);
+
ClassDB::bind_method(D_METHOD("set_cast_shadows_setting", "shadow_casting_setting"), &GeometryInstance3D::set_cast_shadows_setting);
ClassDB::bind_method(D_METHOD("get_cast_shadows_setting"), &GeometryInstance3D::get_cast_shadows_setting);
@@ -443,6 +455,7 @@ void GeometryInstance3D::_bind_methods() {
ADD_GROUP("Geometry", "");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material_override", PROPERTY_HINT_RESOURCE_TYPE, "BaseMaterial3D,ShaderMaterial", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE), "set_material_override", "get_material_override");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material_overlay", PROPERTY_HINT_RESOURCE_TYPE, "BaseMaterial3D,ShaderMaterial", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE), "set_material_overlay", "get_material_overlay");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "transparency", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_transparency", "get_transparency");
ADD_PROPERTY(PropertyInfo(Variant::INT, "cast_shadow", PROPERTY_HINT_ENUM, "Off,On,Double-Sided,Shadows Only"), "set_cast_shadows_setting", "get_cast_shadows_setting");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "extra_cull_margin", PROPERTY_HINT_RANGE, "0,16384,0.01"), "set_extra_cull_margin", "get_extra_cull_margin");
diff --git a/scene/3d/visual_instance_3d.h b/scene/3d/visual_instance_3d.h
index b08f54b3ec..dd0eb25001 100644
--- a/scene/3d/visual_instance_3d.h
+++ b/scene/3d/visual_instance_3d.h
@@ -110,6 +110,7 @@ public:
private:
ShadowCastingSetting shadow_casting_setting = SHADOW_CASTING_SETTING_ON;
Ref<Material> material_override;
+ Ref<Material> material_overlay;
float visibility_range_begin = 0.0;
float visibility_range_end = 0.0;
@@ -164,6 +165,9 @@ public:
void set_material_override(const Ref<Material> &p_material);
Ref<Material> get_material_override() const;
+ void set_material_overlay(const Ref<Material> &p_material);
+ Ref<Material> get_material_overlay() const;
+
void set_extra_cull_margin(float p_margin);
float get_extra_cull_margin() const;
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index a942fc90aa..128c6cae8b 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -625,7 +625,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
pa->object->set_indexed(pa->subpath, value, &valid); //you are not speshul
#ifdef DEBUG_ENABLED
if (!valid) {
- ERR_PRINT("Failed setting track value '" + String(pa->owner->path) + "'. Check if property exists or the type of key is valid. Animation '" + a->get_name() + "' at node '" + get_path() + "'.");
+ ERR_PRINT("Failed setting track value '" + String(pa->owner->path) + "'. Check if the property exists or the type of key is valid. Animation '" + a->get_name() + "' at node '" + get_path() + "'.");
}
#endif
@@ -1070,8 +1070,24 @@ void AnimationPlayer::_animation_update_transforms() {
bool valid;
pa->object->set_indexed(pa->subpath, pa->value_accum, &valid); //you are not speshul
#ifdef DEBUG_ENABLED
+
if (!valid) {
- ERR_PRINT("Failed setting key at time " + rtos(playback.current.pos) + " in Animation '" + get_current_animation() + "' at Node '" + get_path() + "', Track '" + String(pa->owner->path) + "'. Check if property exists or the type of key is right for the property");
+ // Get subpath as string for printing the error
+ // Cannot use `String::join(Vector<String>)` because this is a vector of StringName
+ String key_debug;
+ if (pa->subpath.size() > 0) {
+ key_debug = pa->subpath[0];
+ for (int subpath_index = 1; subpath_index < pa->subpath.size(); ++subpath_index) {
+ key_debug += ".";
+ key_debug += pa->subpath[subpath_index];
+ }
+ }
+ ERR_PRINT("Failed setting key '" + key_debug +
+ "' at time " + rtos(playback.current.pos) +
+ " in Animation '" + get_current_animation() +
+ "' at Node '" + get_path() +
+ "', Track '" + String(pa->owner->path) +
+ "'. Check if the property exists or the type of key is right for the property.");
}
#endif
diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp
index 0c58ec0c60..25e931c287 100644
--- a/scene/gui/button.cpp
+++ b/scene/gui/button.cpp
@@ -126,7 +126,8 @@ void Button::_notification(int p_what) {
}
} break;
case DRAW_HOVER_PRESSED: {
- if (has_theme_stylebox(SNAME("hover_pressed")) && has_theme_stylebox_override("hover_pressed")) {
+ // Edge case for CheckButton and CheckBox.
+ if (has_theme_stylebox("hover_pressed")) {
if (rtl && has_theme_stylebox(SNAME("hover_pressed_mirrored"))) {
style = get_theme_stylebox(SNAME("hover_pressed_mirrored"));
} else {
@@ -138,8 +139,6 @@ void Button::_notification(int p_what) {
}
if (has_theme_color(SNAME("font_hover_pressed_color"))) {
color = get_theme_color(SNAME("font_hover_pressed_color"));
- } else {
- color = get_theme_color(SNAME("font_color"));
}
if (has_theme_color(SNAME("icon_hover_pressed_color"))) {
color_icon = get_theme_color(SNAME("icon_hover_pressed_color"));
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp
index eb3dafa2b1..398b909195 100644
--- a/scene/gui/code_edit.cpp
+++ b/scene/gui/code_edit.cpp
@@ -143,7 +143,6 @@ void CodeEdit::_notification(int p_what) {
code_completion_line_ofs = CLAMP(code_completion_current_selected - lines / 2, 0, code_completion_options_count - lines);
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(code_completion_rect.position.x, code_completion_rect.position.y + (code_completion_current_selected - code_completion_line_ofs) * row_height), Size2(code_completion_rect.size.width, row_height)), code_completion_selected_color);
- draw_rect(Rect2(code_completion_rect.position + Vector2(icon_area_size.x + icon_hsep, 0), Size2(MIN(code_completion_base_width, code_completion_rect.size.width - (icon_area_size.x + icon_hsep)), code_completion_rect.size.height)), code_completion_existing_color);
for (int i = 0; i < lines; i++) {
int l = code_completion_line_ofs + i;
@@ -177,6 +176,17 @@ void CodeEdit::_notification(int p_what) {
}
tl->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_LEFT);
}
+
+ Point2 match_pos = Point2(code_completion_rect.position.x + icon_area_size.x + icon_hsep, code_completion_rect.position.y + i * row_height);
+
+ for (int j = 0; j < code_completion_options[l].matches.size(); j++) {
+ Pair<int, int> match = code_completion_options[l].matches[j];
+ int match_offset = font->get_string_size(code_completion_options[l].display.substr(0, match.first), font_size).width;
+ int match_len = font->get_string_size(code_completion_options[l].display.substr(match.first, match.second), font_size).width;
+
+ draw_rect(Rect2(match_pos + Point2(match_offset, 0), Size2(match_len, row_height)), code_completion_existing_color);
+ }
+
tl->draw(ci, title_pos, code_completion_options[l].font_color);
}
@@ -2808,6 +2818,8 @@ void CodeEdit::_filter_code_completion_candidates_impl() {
code_completion_base = string_to_complete;
Vector<ScriptCodeCompletionOption> completion_options_casei;
+ Vector<ScriptCodeCompletionOption> completion_options_substr;
+ Vector<ScriptCodeCompletionOption> completion_options_substr_casei;
Vector<ScriptCodeCompletionOption> completion_options_subseq;
Vector<ScriptCodeCompletionOption> completion_options_subseq_casei;
@@ -2862,35 +2874,100 @@ void CodeEdit::_filter_code_completion_candidates_impl() {
const char32_t *tgt = &option.display[0];
const char32_t *tgt_lower = &display_lower[0];
- const char32_t *ssq_last_tgt = nullptr;
- const char32_t *ssq_lower_last_tgt = nullptr;
+ const char32_t *sst = &string_to_complete[0];
+ const char32_t *sst_lower = &display_lower[0];
+
+ Vector<Pair<int, int>> ssq_matches;
+ int ssq_match_start = 0;
+ int ssq_match_len = 0;
+
+ Vector<Pair<int, int>> ssq_lower_matches;
+ int ssq_lower_match_start = 0;
+ int ssq_lower_match_len = 0;
+
+ int sst_start = -1;
+ int sst_lower_start = -1;
+
+ for (int i = 0; *tgt; tgt++, tgt_lower++, i++) {
+ // Check substring.
+ if (*sst == *tgt) {
+ sst++;
+ if (sst_start == -1) {
+ sst_start = i;
+ }
+ } else if (sst_start != -1 && *sst) {
+ sst = &string_to_complete[0];
+ sst_start = -1;
+ }
- for (; *tgt; tgt++, tgt_lower++) {
+ // Check subsequence.
if (*ssq == *tgt) {
ssq++;
- ssq_last_tgt = tgt;
+ if (ssq_match_len == 0) {
+ ssq_match_start = i;
+ }
+ ssq_match_len++;
+ } else if (ssq_match_len > 0) {
+ ssq_matches.push_back(Pair<int, int>(ssq_match_start, ssq_match_len));
+ ssq_match_len = 0;
}
+
+ // Check lower substring.
+ if (*sst_lower == *tgt) {
+ sst_lower++;
+ if (sst_lower_start == -1) {
+ sst_lower_start = i;
+ }
+ } else if (sst_lower_start != -1 && *sst_lower) {
+ sst_lower = &string_to_complete[0];
+ sst_lower_start = -1;
+ }
+
+ // Check lower subsequence.
if (*ssq_lower == *tgt_lower) {
ssq_lower++;
- ssq_lower_last_tgt = tgt;
+ if (ssq_lower_match_len == 0) {
+ ssq_lower_match_start = i;
+ }
+ ssq_lower_match_len++;
+ } else if (ssq_lower_match_len > 0) {
+ ssq_lower_matches.push_back(Pair<int, int>(ssq_lower_match_start, ssq_lower_match_len));
+ ssq_lower_match_len = 0;
}
}
/* Matched the whole subsequence in s. */
- if (!*ssq) {
- /* Finished matching in the first s.length() characters. */
- if (ssq_last_tgt == &option.display[string_to_complete.length() - 1]) {
+ if (!*ssq) { // Matched the whole subsequence in s.
+ option.matches.clear();
+
+ if (sst_start == 0) { // Matched substring in beginning of s.
+ option.matches.push_back(Pair<int, int>(sst_start, string_to_complete.length()));
code_completion_options.push_back(option);
+ } else if (sst_start > 0) { // Matched substring in s.
+ option.matches.push_back(Pair<int, int>(sst_start, string_to_complete.length()));
+ completion_options_substr.push_back(option);
} else {
+ if (ssq_match_len > 0) {
+ ssq_matches.push_back(Pair<int, int>(ssq_match_start, ssq_match_len));
+ }
+ option.matches.append_array(ssq_matches);
completion_options_subseq.push_back(option);
}
max_width = MAX(max_width, font->get_string_size(option.display, font_size).width + offset);
- /* Matched the whole subsequence in s_lower. */
- } else if (!*ssq_lower) {
- /* Finished matching in the first s.length() characters. */
- if (ssq_lower_last_tgt == &option.display[string_to_complete.length() - 1]) {
+ } else if (!*ssq_lower) { // Matched the whole subsequence in s_lower.
+ option.matches.clear();
+
+ if (sst_lower_start == 0) { // Matched substring in beginning of s_lower.
+ option.matches.push_back(Pair<int, int>(sst_lower_start, string_to_complete.length()));
completion_options_casei.push_back(option);
+ } else if (sst_lower_start > 0) { // Matched substring in s_lower.
+ option.matches.push_back(Pair<int, int>(sst_lower_start, string_to_complete.length()));
+ completion_options_substr_casei.push_back(option);
} else {
+ if (ssq_lower_match_len > 0) {
+ ssq_lower_matches.push_back(Pair<int, int>(ssq_lower_match_start, ssq_lower_match_len));
+ }
+ option.matches.append_array(ssq_lower_matches);
completion_options_subseq_casei.push_back(option);
}
max_width = MAX(max_width, font->get_string_size(option.display, font_size).width + offset);
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index bc0e0e9eee..69e6d74292 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -589,6 +589,7 @@ void Control::_notification(int p_notification) {
_size_changed();
} break;
case NOTIFICATION_EXIT_TREE: {
+ release_focus();
get_viewport()->_gui_remove_control(this);
} break;
case NOTIFICATION_READY: {
@@ -1148,12 +1149,12 @@ float Control::fetch_theme_default_base_scale(Control *p_theme_owner, Window *p_
Window *theme_owner_window = p_theme_owner_window;
while (theme_owner || theme_owner_window) {
- if (theme_owner && theme_owner->data.theme->has_default_theme_base_scale()) {
- return theme_owner->data.theme->get_default_theme_base_scale();
+ if (theme_owner && theme_owner->data.theme->has_default_base_scale()) {
+ return theme_owner->data.theme->get_default_base_scale();
}
- if (theme_owner_window && theme_owner_window->theme->has_default_theme_base_scale()) {
- return theme_owner_window->theme->get_default_theme_base_scale();
+ if (theme_owner_window && theme_owner_window->theme->has_default_base_scale()) {
+ return theme_owner_window->theme->get_default_base_scale();
}
Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent();
@@ -1175,13 +1176,16 @@ float Control::fetch_theme_default_base_scale(Control *p_theme_owner, Window *p_
// Secondly, check the project-defined Theme resource.
if (Theme::get_project_default().is_valid()) {
- if (Theme::get_project_default()->has_default_theme_base_scale()) {
- return Theme::get_project_default()->get_default_theme_base_scale();
+ if (Theme::get_project_default()->has_default_base_scale()) {
+ return Theme::get_project_default()->get_default_base_scale();
}
}
// Lastly, fall back on the default Theme.
- return Theme::get_default()->get_default_theme_base_scale();
+ if (Theme::get_default()->has_default_base_scale()) {
+ return Theme::get_default()->get_default_base_scale();
+ }
+ return Theme::get_fallback_base_scale();
}
float Control::get_theme_default_base_scale() const {
@@ -1196,12 +1200,12 @@ Ref<Font> Control::fetch_theme_default_font(Control *p_theme_owner, Window *p_th
Window *theme_owner_window = p_theme_owner_window;
while (theme_owner || theme_owner_window) {
- if (theme_owner && theme_owner->data.theme->has_default_theme_font()) {
- return theme_owner->data.theme->get_default_theme_font();
+ if (theme_owner && theme_owner->data.theme->has_default_font()) {
+ return theme_owner->data.theme->get_default_font();
}
- if (theme_owner_window && theme_owner_window->theme->has_default_theme_font()) {
- return theme_owner_window->theme->get_default_theme_font();
+ if (theme_owner_window && theme_owner_window->theme->has_default_font()) {
+ return theme_owner_window->theme->get_default_font();
}
Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent();
@@ -1223,13 +1227,16 @@ Ref<Font> Control::fetch_theme_default_font(Control *p_theme_owner, Window *p_th
// Secondly, check the project-defined Theme resource.
if (Theme::get_project_default().is_valid()) {
- if (Theme::get_project_default()->has_default_theme_font()) {
- return Theme::get_project_default()->get_default_theme_font();
+ if (Theme::get_project_default()->has_default_font()) {
+ return Theme::get_project_default()->get_default_font();
}
}
// Lastly, fall back on the default Theme.
- return Theme::get_default()->get_default_theme_font();
+ if (Theme::get_default()->has_default_font()) {
+ return Theme::get_default()->get_default_font();
+ }
+ return Theme::get_fallback_font();
}
Ref<Font> Control::get_theme_default_font() const {
@@ -1244,12 +1251,12 @@ int Control::fetch_theme_default_font_size(Control *p_theme_owner, Window *p_the
Window *theme_owner_window = p_theme_owner_window;
while (theme_owner || theme_owner_window) {
- if (theme_owner && theme_owner->data.theme->has_default_theme_font_size()) {
- return theme_owner->data.theme->get_default_theme_font_size();
+ if (theme_owner && theme_owner->data.theme->has_default_font_size()) {
+ return theme_owner->data.theme->get_default_font_size();
}
- if (theme_owner_window && theme_owner_window->theme->has_default_theme_font_size()) {
- return theme_owner_window->theme->get_default_theme_font_size();
+ if (theme_owner_window && theme_owner_window->theme->has_default_font_size()) {
+ return theme_owner_window->theme->get_default_font_size();
}
Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent();
@@ -1271,13 +1278,16 @@ int Control::fetch_theme_default_font_size(Control *p_theme_owner, Window *p_the
// Secondly, check the project-defined Theme resource.
if (Theme::get_project_default().is_valid()) {
- if (Theme::get_project_default()->has_default_theme_font_size()) {
- return Theme::get_project_default()->get_default_theme_font_size();
+ if (Theme::get_project_default()->has_default_font_size()) {
+ return Theme::get_project_default()->get_default_font_size();
}
}
// Lastly, fall back on the default Theme.
- return Theme::get_default()->get_default_theme_font_size();
+ if (Theme::get_default()->has_default_font_size()) {
+ return Theme::get_default()->get_default_font_size();
+ }
+ return Theme::get_fallback_font_size();
}
int Control::get_theme_default_font_size() const {
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index 1ddec4f587..92c770429b 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -600,6 +600,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
to = get_node(String(connecting_from)); //maybe it was erased
if (Object::cast_to<GraphNode>(to)) {
connecting = true;
+ emit_signal(SNAME("connection_drag_begun"), connecting_from, connecting_index, false);
}
return;
}
@@ -616,6 +617,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
connecting_target = false;
connecting_to = pos;
just_disconnected = false;
+ emit_signal(SNAME("connection_drag_begun"), connecting_from, connecting_index, true);
return;
}
}
@@ -642,6 +644,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
fr = get_node(String(connecting_from)); //maybe it was erased
if (Object::cast_to<GraphNode>(fr)) {
connecting = true;
+ emit_signal(SNAME("connection_drag_begun"), connecting_from, connecting_index, true);
}
return;
}
@@ -658,7 +661,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
connecting_target = false;
connecting_to = pos;
just_disconnected = false;
-
+ emit_signal(SNAME("connection_drag_begun"), connecting_from, connecting_index, false);
return;
}
}
@@ -740,11 +743,9 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
}
}
- connecting = false;
- top_layer->update();
- minimap->update();
- update();
- connections_layer->update();
+ if (connecting) {
+ force_connection_drag_end();
+ }
}
}
@@ -1162,9 +1163,7 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
minimap->update();
} else {
if (connecting) {
- connecting = false;
- top_layer->update();
- minimap->update();
+ force_connection_drag_end();
} else {
emit_signal(SNAME("popup_request"), get_screen_position() + b->get_position());
}
@@ -1394,6 +1393,17 @@ void GraphEdit::clear_connections() {
connections_layer->update();
}
+void GraphEdit::force_connection_drag_end() {
+ ERR_FAIL_COND_MSG(!connecting, "Drag end requested without active drag!");
+ connecting = false;
+ connecting_valid = false;
+ top_layer->update();
+ minimap->update();
+ update();
+ connections_layer->update();
+ emit_signal(SNAME("connection_drag_ended"));
+}
+
void GraphEdit::set_zoom(float p_zoom) {
set_zoom_custom(p_zoom, get_size() / 2);
}
@@ -2165,6 +2175,7 @@ void GraphEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_connection_activity", "from", "from_port", "to", "to_port", "amount"), &GraphEdit::set_connection_activity);
ClassDB::bind_method(D_METHOD("get_connection_list"), &GraphEdit::_get_connection_list);
ClassDB::bind_method(D_METHOD("clear_connections"), &GraphEdit::clear_connections);
+ ClassDB::bind_method(D_METHOD("force_connection_drag_end"), &GraphEdit::force_connection_drag_end);
ClassDB::bind_method(D_METHOD("get_scroll_ofs"), &GraphEdit::get_scroll_ofs);
ClassDB::bind_method(D_METHOD("set_scroll_ofs", "ofs"), &GraphEdit::set_scroll_ofs);
@@ -2262,6 +2273,8 @@ void GraphEdit::_bind_methods() {
ADD_SIGNAL(MethodInfo("begin_node_move"));
ADD_SIGNAL(MethodInfo("end_node_move"));
ADD_SIGNAL(MethodInfo("scroll_offset_changed", PropertyInfo(Variant::VECTOR2, "ofs")));
+ ADD_SIGNAL(MethodInfo("connection_drag_begun", PropertyInfo(Variant::STRING, "from"), PropertyInfo(Variant::STRING, "slot"), PropertyInfo(Variant::BOOL, "is_output")));
+ ADD_SIGNAL(MethodInfo("connection_drag_ended"));
}
GraphEdit::GraphEdit() {
diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h
index 7cbd0d179d..f1c4e95e38 100644
--- a/scene/gui/graph_edit.h
+++ b/scene/gui/graph_edit.h
@@ -267,6 +267,7 @@ public:
bool is_node_connected(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port);
void disconnect_node(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port);
void clear_connections();
+ void force_connection_drag_end();
void set_connection_activity(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port, float p_activity);
diff --git a/scene/gui/subviewport_container.cpp b/scene/gui/subviewport_container.cpp
index 6cc64e7ada..760144591e 100644
--- a/scene/gui/subviewport_container.cpp
+++ b/scene/gui/subviewport_container.cpp
@@ -54,6 +54,7 @@ Size2 SubViewportContainer::get_minimum_size() const {
void SubViewportContainer::set_stretch(bool p_enable) {
stretch = p_enable;
+ update_minimum_size();
queue_sort();
update();
}
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index e5614ff728..c3fc08731e 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -703,30 +703,16 @@ void TabContainer::add_child_notify(Node *p_child) {
return;
}
- Vector<Control *> tabs = _get_tabs();
_refresh_texts();
+ call_deferred("_repaint");
+ update();
- bool first = false;
-
- if (tabs.size() != 1) {
- c->hide();
- } else {
- c->show();
- //call_deferred(SNAME("set_current_tab"),0);
- first = true;
+ bool first = (_get_tabs().size() == 1);
+ if (first) {
current = 0;
previous = 0;
}
- c->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
- if (tabs_visible) {
- c->set_offset(SIDE_TOP, _get_top_margin());
- }
- Ref<StyleBox> sb = get_theme_stylebox(SNAME("panel"));
- c->set_offset(SIDE_TOP, c->get_offset(SIDE_TOP) + sb->get_margin(SIDE_TOP));
- c->set_offset(SIDE_LEFT, c->get_offset(SIDE_LEFT) + sb->get_margin(SIDE_LEFT));
- c->set_offset(SIDE_RIGHT, c->get_offset(SIDE_RIGHT) - sb->get_margin(SIDE_RIGHT));
- c->set_offset(SIDE_BOTTOM, c->get_offset(SIDE_BOTTOM) - sb->get_margin(SIDE_BOTTOM));
- update();
+
p_child->connect("renamed", callable_mp(this, &TabContainer::_child_renamed_callback));
if (first && is_inside_tree()) {
emit_signal(SNAME("tab_changed"), current);
@@ -1223,6 +1209,7 @@ void TabContainer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_use_hidden_tabs_for_min_size", "enabled"), &TabContainer::set_use_hidden_tabs_for_min_size);
ClassDB::bind_method(D_METHOD("get_use_hidden_tabs_for_min_size"), &TabContainer::get_use_hidden_tabs_for_min_size);
+ ClassDB::bind_method(D_METHOD("_repaint"), &TabContainer::_repaint);
ClassDB::bind_method(D_METHOD("_on_theme_changed"), &TabContainer::_on_theme_changed);
ClassDB::bind_method(D_METHOD("_update_current_tab"), &TabContainer::_update_current_tab);
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 69ac36ff99..73d39aee8a 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -2195,8 +2195,10 @@ void Tree::select_single_item(TreeItem *p_selected, TreeItem *p_current, int p_c
*/
} else if (c.selected) {
- c.selected = false;
- //p_current->deselected_signal.call(p_col);
+ if (p_selected != p_current) {
+ // Deselect other rows.
+ c.selected = false;
+ }
}
} else if (select_mode == SELECT_SINGLE || select_mode == SELECT_MULTI) {
if (!r_in_range && &selected_cell == &c) {
@@ -2316,12 +2318,9 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int
return -1;
}
- if (!p_item->disable_folding && !hide_folding && (p_pos.x >= x_ofs && p_pos.x < (x_ofs + cache.item_margin))) {
- if (p_item->first_child) {
- p_item->set_collapsed(!p_item->is_collapsed());
- }
-
- return -1; //handled!
+ if (!p_item->disable_folding && !hide_folding && p_item->first_child && (p_pos.x >= x_ofs && p_pos.x < (x_ofs + cache.item_margin))) {
+ p_item->set_collapsed(!p_item->is_collapsed());
+ return -1;
}
int x = p_pos.x;
@@ -4827,7 +4826,7 @@ void Tree::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_allow_reselect"), &Tree::get_allow_reselect);
ADD_PROPERTY(PropertyInfo(Variant::INT, "columns"), "set_columns", "get_columns");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "column_titles_visible"), "set_column_titles_visible", "are_column_titles_visible");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "column_titles_visible"), "set_column_titles_visible", "are_column_titles_visible");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_reselect"), "set_allow_reselect", "get_allow_reselect");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_rmb_select"), "set_allow_rmb_select", "get_allow_rmb_select");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_folding"), "set_hide_folding", "is_folding_hidden");
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 442d7ae6e6..8b5883a742 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -152,12 +152,6 @@ void Node::_notification(int p_notification) {
data.in_constructor = false;
} break;
case NOTIFICATION_PREDELETE: {
- set_owner(nullptr);
-
- while (data.owned.size()) {
- data.owned.front()->get()->set_owner(nullptr);
- }
-
if (data.parent) {
data.parent->remove_child(this);
}
@@ -165,10 +159,8 @@ void Node::_notification(int p_notification) {
// kill children as cleanly as possible
while (data.children.size()) {
Node *child = data.children[data.children.size() - 1]; //begin from the end because its faster and more consistent with creation
- remove_child(child);
memdelete(child);
}
-
} break;
}
}
@@ -237,11 +229,32 @@ void Node::_propagate_enter_tree() {
}
void Node::_propagate_after_exit_tree() {
+ // Clear owner if it was not part of the pruned branch
+ if (data.owner) {
+ bool found = false;
+ Node *parent = data.parent;
+
+ while (parent) {
+ if (parent == data.owner) {
+ found = true;
+ break;
+ }
+
+ parent = parent->data.parent;
+ }
+
+ if (!found) {
+ data.owner->data.owned.erase(data.OW);
+ data.owner = nullptr;
+ }
+ }
+
data.blocked++;
- for (int i = 0; i < data.children.size(); i++) {
+ for (int i = data.children.size() - 1; i >= 0; i--) {
data.children[i]->_propagate_after_exit_tree();
}
data.blocked--;
+
emit_signal(SceneStringNames::get_singleton()->tree_exited);
}
@@ -1144,31 +1157,6 @@ void Node::add_sibling(Node *p_sibling, bool p_legible_unique_name) {
data.parent->_move_child(p_sibling, get_index() + 1);
}
-void Node::_propagate_validate_owner() {
- if (data.owner) {
- bool found = false;
- Node *parent = data.parent;
-
- while (parent) {
- if (parent == data.owner) {
- found = true;
- break;
- }
-
- parent = parent->data.parent;
- }
-
- if (!found) {
- data.owner->data.owned.erase(data.OW);
- data.owner = nullptr;
- }
- }
-
- for (int i = 0; i < data.children.size(); i++) {
- data.children[i]->_propagate_validate_owner();
- }
-}
-
void Node::remove_child(Node *p_child) {
ERR_FAIL_NULL(p_child);
ERR_FAIL_COND_MSG(data.blocked > 0, "Parent node is busy setting up children, remove_node() failed. Consider using call_deferred(\"remove_child\", child) instead.");
@@ -1222,9 +1210,6 @@ void Node::remove_child(Node *p_child) {
p_child->data.parent = nullptr;
p_child->data.pos = -1;
- // validate owner
- p_child->_propagate_validate_owner();
-
if (data.inside_tree) {
p_child->_propagate_after_exit_tree();
}
diff --git a/scene/main/node.h b/scene/main/node.h
index 8613c4736c..a1fc672a15 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -172,7 +172,6 @@ private:
void _propagate_ready();
void _propagate_exit_tree();
void _propagate_after_exit_tree();
- void _propagate_validate_owner();
void _print_stray_nodes();
void _propagate_process_owner(Node *p_owner, int p_pause_notification, int p_enabled_notification);
Array _get_node_and_resource(const NodePath &p_path);
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 0a9f98bb2f..3e63ba7869 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -48,6 +48,7 @@
#include "scene/gui/label.h"
#include "scene/gui/popup.h"
#include "scene/gui/popup_menu.h"
+#include "scene/gui/subviewport_container.h"
#include "scene/main/canvas_layer.h"
#include "scene/main/window.h"
#include "scene/resources/mesh.h"
@@ -3865,6 +3866,11 @@ Viewport::~Viewport() {
void SubViewport::set_size(const Size2i &p_size) {
_set_size(p_size, _get_size_2d_override(), Rect2i(), _stretch_transform(), true);
+
+ SubViewportContainer *c = Object::cast_to<SubViewportContainer>(get_parent());
+ if (c) {
+ c->update_minimum_size();
+ }
}
Size2i SubViewport::get_size() const {
diff --git a/scene/property_utils.cpp b/scene/property_utils.cpp
index e2f1ac8224..2540a633a9 100644
--- a/scene/property_utils.cpp
+++ b/scene/property_utils.cpp
@@ -111,10 +111,37 @@ Variant PropertyUtils::get_property_default_value(const Object *p_object, const
}
// Fall back to the default from the native class
- if (r_is_class_default) {
- *r_is_class_default = true;
+ {
+ if (r_is_class_default) {
+ *r_is_class_default = true;
+ }
+ bool valid = false;
+ Variant value = ClassDB::class_get_default_property_value(p_object->get_class_name(), p_property, &valid);
+ if (valid) {
+ if (r_is_valid) {
+ *r_is_valid = true;
+ }
+ return value;
+ } else {
+ // Heuristically check if this is a synthetic property (whatever/0, whatever/1, etc.)
+ // because they are not in the class DB yet must have a default (null).
+ String prop_str = String(p_property);
+ int p = prop_str.rfind("/");
+ if (p != -1 && p < prop_str.length() - 1) {
+ bool all_digits = true;
+ for (int i = p + 1; i < prop_str.length(); i++) {
+ if (prop_str[i] < '0' || prop_str[i] > '9') {
+ all_digits = false;
+ break;
+ }
+ }
+ if (r_is_valid) {
+ *r_is_valid = all_digits;
+ }
+ }
+ return Variant();
+ }
}
- return ClassDB::class_get_default_property_value(p_object->get_class_name(), p_property, r_is_valid);
}
// Like SceneState::PackState, but using a raw pointer to avoid the cost of
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 933021db75..e6b73b7780 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -1071,7 +1071,7 @@ void initialize_theme() {
if (theme.is_valid()) {
Theme::set_project_default(theme);
if (font.is_valid()) {
- Theme::set_default_font(font);
+ Theme::set_fallback_font(font);
}
} else {
ERR_PRINT("Error loading custom theme '" + theme_path + "'");
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index ed956d1ab0..44d3e4af19 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -2715,6 +2715,7 @@ void Animation::value_track_set_update_mode(int p_track, UpdateMode p_mode) {
ValueTrack *vt = static_cast<ValueTrack *>(t);
vt->update_mode = p_mode;
+ emit_changed();
}
Animation::UpdateMode Animation::value_track_get_update_mode(int p_track) const {
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 48d36ff2f7..549bd3ba12 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -1053,17 +1053,17 @@ void make_default_theme(bool p_hidpi, Ref<Font> p_font) {
fill_default_theme(t, default_font, large_font, default_icon, default_style, default_scale);
Theme::set_default(t);
- Theme::set_default_base_scale(default_scale);
- Theme::set_default_icon(default_icon);
- Theme::set_default_style(default_style);
- Theme::set_default_font(default_font);
- Theme::set_default_font_size(default_font_size);
+ Theme::set_fallback_base_scale(default_scale);
+ Theme::set_fallback_icon(default_icon);
+ Theme::set_fallback_style(default_style);
+ Theme::set_fallback_font(default_font);
+ Theme::set_fallback_font_size(default_font_size);
}
void clear_default_theme() {
Theme::set_project_default(nullptr);
Theme::set_default(nullptr);
- Theme::set_default_icon(nullptr);
- Theme::set_default_style(nullptr);
- Theme::set_default_font(nullptr);
+ Theme::set_fallback_icon(nullptr);
+ Theme::set_fallback_style(nullptr);
+ Theme::set_fallback_font(nullptr);
}
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index b36204241a..f3e5ece1f9 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -1659,18 +1659,6 @@ bool BaseMaterial3D::get_feature(Feature p_feature) const {
void BaseMaterial3D::set_texture(TextureParam p_param, const Ref<Texture2D> &p_texture) {
ERR_FAIL_INDEX(p_param, TEXTURE_MAX);
- if (get_texture(TEXTURE_ROUGHNESS).is_null() && p_texture.is_valid() && p_param == TEXTURE_ROUGHNESS) {
- // If no roughness texture is currently set, automatically set the recommended value
- // for roughness when using a roughness map.
- set_roughness(1.0);
- }
-
- if (get_texture(TEXTURE_METALLIC).is_null() && p_texture.is_valid() && p_param == TEXTURE_METALLIC) {
- // If no metallic texture is currently set, automatically set the recommended value
- // for metallic when using a metallic map.
- set_metallic(1.0);
- }
-
textures[p_param] = p_texture;
RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
RS::get_singleton()->material_set_param(_get_material(), shader_names->texture_names[p_param], rid);
diff --git a/scene/resources/skin.h b/scene/resources/skin.h
index 906a2783b4..6ade9dbed1 100644
--- a/scene/resources/skin.h
+++ b/scene/resources/skin.h
@@ -67,23 +67,17 @@ public:
void set_bind_name(int p_index, const StringName &p_name);
inline int get_bind_bone(int p_index) const {
-#ifdef DEBUG_ENABLED
ERR_FAIL_INDEX_V(p_index, bind_count, -1);
-#endif
return binds_ptr[p_index].bone;
}
inline StringName get_bind_name(int p_index) const {
-#ifdef DEBUG_ENABLED
ERR_FAIL_INDEX_V(p_index, bind_count, StringName());
-#endif
return binds_ptr[p_index].name;
}
inline Transform3D get_bind_pose(int p_index) const {
-#ifdef DEBUG_ENABLED
ERR_FAIL_INDEX_V(p_index, bind_count, Transform3D());
-#endif
return binds_ptr[p_index].pose;
}
diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp
index 186bbab689..8da287042e 100644
--- a/scene/resources/theme.cpp
+++ b/scene/resources/theme.cpp
@@ -36,11 +36,11 @@ Ref<Theme> Theme::default_theme;
Ref<Theme> Theme::project_default_theme;
// Universal default values, final fallback for every theme.
-float Theme::default_base_scale = 1.0;
-Ref<Texture2D> Theme::default_icon;
-Ref<StyleBox> Theme::default_style;
-Ref<Font> Theme::default_font;
-int Theme::default_font_size = 16;
+float Theme::fallback_base_scale = 1.0;
+Ref<Texture2D> Theme::fallback_icon;
+Ref<StyleBox> Theme::fallback_style;
+Ref<Font> Theme::fallback_font;
+int Theme::fallback_font_size = 16;
// Dynamic properties.
bool Theme::_set(const StringName &p_name, const Variant &p_value) {
@@ -220,87 +220,107 @@ void Theme::set_project_default(const Ref<Theme> &p_project_default) {
}
// Universal fallback values for theme item types.
-void Theme::set_default_base_scale(float p_base_scale) {
- default_base_scale = p_base_scale;
+void Theme::set_fallback_base_scale(float p_base_scale) {
+ fallback_base_scale = p_base_scale;
}
-void Theme::set_default_icon(const Ref<Texture2D> &p_icon) {
- default_icon = p_icon;
+void Theme::set_fallback_icon(const Ref<Texture2D> &p_icon) {
+ fallback_icon = p_icon;
}
-void Theme::set_default_style(const Ref<StyleBox> &p_style) {
- default_style = p_style;
+void Theme::set_fallback_style(const Ref<StyleBox> &p_style) {
+ fallback_style = p_style;
}
-void Theme::set_default_font(const Ref<Font> &p_font) {
- default_font = p_font;
+void Theme::set_fallback_font(const Ref<Font> &p_font) {
+ fallback_font = p_font;
}
-void Theme::set_default_font_size(int p_font_size) {
- default_font_size = p_font_size;
+void Theme::set_fallback_font_size(int p_font_size) {
+ fallback_font_size = p_font_size;
+}
+
+float Theme::get_fallback_base_scale() {
+ return fallback_base_scale;
+}
+
+Ref<Texture2D> Theme::get_fallback_icon() {
+ return fallback_icon;
+}
+
+Ref<StyleBox> Theme::get_fallback_style() {
+ return fallback_style;
+}
+
+Ref<Font> Theme::get_fallback_font() {
+ return fallback_font;
+}
+
+int Theme::get_fallback_font_size() {
+ return fallback_font_size;
}
// Fallback values for theme item types, configurable per theme.
-void Theme::set_default_theme_base_scale(float p_base_scale) {
- if (default_theme_base_scale == p_base_scale) {
+void Theme::set_default_base_scale(float p_base_scale) {
+ if (default_base_scale == p_base_scale) {
return;
}
- default_theme_base_scale = p_base_scale;
+ default_base_scale = p_base_scale;
_emit_theme_changed();
}
-float Theme::get_default_theme_base_scale() const {
- return default_theme_base_scale;
+float Theme::get_default_base_scale() const {
+ return default_base_scale;
}
-bool Theme::has_default_theme_base_scale() const {
- return default_theme_base_scale > 0.0;
+bool Theme::has_default_base_scale() const {
+ return default_base_scale > 0.0;
}
-void Theme::set_default_theme_font(const Ref<Font> &p_default_font) {
- if (default_theme_font == p_default_font) {
+void Theme::set_default_font(const Ref<Font> &p_default_font) {
+ if (default_font == p_default_font) {
return;
}
- if (default_theme_font.is_valid()) {
- default_theme_font->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed));
+ if (default_font.is_valid()) {
+ default_font->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed));
}
- default_theme_font = p_default_font;
+ default_font = p_default_font;
- if (default_theme_font.is_valid()) {
- default_theme_font->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(false), CONNECT_REFERENCE_COUNTED);
+ if (default_font.is_valid()) {
+ default_font->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(false), CONNECT_REFERENCE_COUNTED);
}
_emit_theme_changed();
}
-Ref<Font> Theme::get_default_theme_font() const {
- return default_theme_font;
+Ref<Font> Theme::get_default_font() const {
+ return default_font;
}
-bool Theme::has_default_theme_font() const {
- return default_theme_font.is_valid();
+bool Theme::has_default_font() const {
+ return default_font.is_valid();
}
-void Theme::set_default_theme_font_size(int p_font_size) {
- if (default_theme_font_size == p_font_size) {
+void Theme::set_default_font_size(int p_font_size) {
+ if (default_font_size == p_font_size) {
return;
}
- default_theme_font_size = p_font_size;
+ default_font_size = p_font_size;
_emit_theme_changed();
}
-int Theme::get_default_theme_font_size() const {
- return default_theme_font_size;
+int Theme::get_default_font_size() const {
+ return default_font_size;
}
-bool Theme::has_default_theme_font_size() const {
- return default_theme_font_size > 0;
+bool Theme::has_default_font_size() const {
+ return default_font_size > 0;
}
// Icons.
@@ -324,7 +344,7 @@ Ref<Texture2D> Theme::get_icon(const StringName &p_name, const StringName &p_the
if (icon_map.has(p_theme_type) && icon_map[p_theme_type].has(p_name) && icon_map[p_theme_type][p_name].is_valid()) {
return icon_map[p_theme_type][p_name];
} else {
- return default_icon;
+ return fallback_icon;
}
}
@@ -411,7 +431,7 @@ Ref<StyleBox> Theme::get_stylebox(const StringName &p_name, const StringName &p_
if (style_map.has(p_theme_type) && style_map[p_theme_type].has(p_name) && style_map[p_theme_type][p_name].is_valid()) {
return style_map[p_theme_type][p_name];
} else {
- return default_style;
+ return fallback_style;
}
}
@@ -497,15 +517,15 @@ void Theme::set_font(const StringName &p_name, const StringName &p_theme_type, c
Ref<Font> Theme::get_font(const StringName &p_name, const StringName &p_theme_type) const {
if (font_map.has(p_theme_type) && font_map[p_theme_type].has(p_name) && font_map[p_theme_type][p_name].is_valid()) {
return font_map[p_theme_type][p_name];
- } else if (has_default_theme_font()) {
- return default_theme_font;
- } else {
+ } else if (has_default_font()) {
return default_font;
+ } else {
+ return fallback_font;
}
}
bool Theme::has_font(const StringName &p_name, const StringName &p_theme_type) const {
- return ((font_map.has(p_theme_type) && font_map[p_theme_type].has(p_name) && font_map[p_theme_type][p_name].is_valid()) || has_default_theme_font());
+ return ((font_map.has(p_theme_type) && font_map[p_theme_type].has(p_name) && font_map[p_theme_type][p_name].is_valid()) || has_default_font());
}
bool Theme::has_font_nocheck(const StringName &p_name, const StringName &p_theme_type) const {
@@ -577,15 +597,15 @@ void Theme::set_font_size(const StringName &p_name, const StringName &p_theme_ty
int Theme::get_font_size(const StringName &p_name, const StringName &p_theme_type) const {
if (font_size_map.has(p_theme_type) && font_size_map[p_theme_type].has(p_name) && (font_size_map[p_theme_type][p_name] > 0)) {
return font_size_map[p_theme_type][p_name];
- } else if (has_default_theme_font_size()) {
- return default_theme_font_size;
- } else {
+ } else if (has_default_font_size()) {
return default_font_size;
+ } else {
+ return fallback_font_size;
}
}
bool Theme::has_font_size(const StringName &p_name, const StringName &p_theme_type) const {
- return ((font_size_map.has(p_theme_type) && font_size_map[p_theme_type].has(p_name) && (font_size_map[p_theme_type][p_name] > 0)) || has_default_theme_font_size());
+ return ((font_size_map.has(p_theme_type) && font_size_map[p_theme_type].has(p_name) && (font_size_map[p_theme_type][p_name] > 0)) || has_default_font_size());
}
bool Theme::has_font_size_nocheck(const StringName &p_name, const StringName &p_theme_type) const {
@@ -1622,17 +1642,17 @@ void Theme::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_constant_list", "theme_type"), &Theme::_get_constant_list);
ClassDB::bind_method(D_METHOD("get_constant_type_list"), &Theme::_get_constant_type_list);
- ClassDB::bind_method(D_METHOD("set_default_base_scale", "font_size"), &Theme::set_default_theme_base_scale);
- ClassDB::bind_method(D_METHOD("get_default_base_scale"), &Theme::get_default_theme_base_scale);
- ClassDB::bind_method(D_METHOD("has_default_base_scale"), &Theme::has_default_theme_base_scale);
+ ClassDB::bind_method(D_METHOD("set_default_base_scale", "base_scale"), &Theme::set_default_base_scale);
+ ClassDB::bind_method(D_METHOD("get_default_base_scale"), &Theme::get_default_base_scale);
+ ClassDB::bind_method(D_METHOD("has_default_base_scale"), &Theme::has_default_base_scale);
- ClassDB::bind_method(D_METHOD("set_default_font", "font"), &Theme::set_default_theme_font);
- ClassDB::bind_method(D_METHOD("get_default_font"), &Theme::get_default_theme_font);
- ClassDB::bind_method(D_METHOD("has_default_font"), &Theme::has_default_theme_font);
+ ClassDB::bind_method(D_METHOD("set_default_font", "font"), &Theme::set_default_font);
+ ClassDB::bind_method(D_METHOD("get_default_font"), &Theme::get_default_font);
+ ClassDB::bind_method(D_METHOD("has_default_font"), &Theme::has_default_font);
- ClassDB::bind_method(D_METHOD("set_default_font_size", "font_size"), &Theme::set_default_theme_font_size);
- ClassDB::bind_method(D_METHOD("get_default_font_size"), &Theme::get_default_theme_font_size);
- ClassDB::bind_method(D_METHOD("has_default_font_size"), &Theme::has_default_theme_font_size);
+ ClassDB::bind_method(D_METHOD("set_default_font_size", "font_size"), &Theme::set_default_font_size);
+ ClassDB::bind_method(D_METHOD("get_default_font_size"), &Theme::get_default_font_size);
+ ClassDB::bind_method(D_METHOD("has_default_font_size"), &Theme::has_default_font_size);
ClassDB::bind_method(D_METHOD("set_theme_item", "data_type", "name", "theme_type", "value"), &Theme::set_theme_item);
ClassDB::bind_method(D_METHOD("get_theme_item", "data_type", "name", "theme_type"), &Theme::get_theme_item);
diff --git a/scene/resources/theme.h b/scene/resources/theme.h
index 2e0a645005..822743a1fe 100644
--- a/scene/resources/theme.h
+++ b/scene/resources/theme.h
@@ -101,16 +101,16 @@ protected:
static Ref<Theme> project_default_theme;
// Universal default values, final fallback for every theme.
- static float default_base_scale;
- static Ref<Texture2D> default_icon;
- static Ref<StyleBox> default_style;
- static Ref<Font> default_font;
- static int default_font_size;
+ static float fallback_base_scale;
+ static Ref<Texture2D> fallback_icon;
+ static Ref<StyleBox> fallback_style;
+ static Ref<Font> fallback_font;
+ static int fallback_font_size;
// Default values configurable for each individual theme.
- float default_theme_base_scale = 0.0;
- Ref<Font> default_theme_font;
- int default_theme_font_size = -1;
+ float default_base_scale = 0.0;
+ Ref<Font> default_font;
+ int default_font_size = -1;
static void _bind_methods();
@@ -126,23 +126,29 @@ public:
static Ref<Theme> get_project_default();
static void set_project_default(const Ref<Theme> &p_project_default);
- static void set_default_base_scale(float p_base_scale);
- static void set_default_icon(const Ref<Texture2D> &p_icon);
- static void set_default_style(const Ref<StyleBox> &p_style);
- static void set_default_font(const Ref<Font> &p_font);
- static void set_default_font_size(int p_font_size);
-
- void set_default_theme_base_scale(float p_base_scale);
- float get_default_theme_base_scale() const;
- bool has_default_theme_base_scale() const;
-
- void set_default_theme_font(const Ref<Font> &p_default_font);
- Ref<Font> get_default_theme_font() const;
- bool has_default_theme_font() const;
-
- void set_default_theme_font_size(int p_font_size);
- int get_default_theme_font_size() const;
- bool has_default_theme_font_size() const;
+ static void set_fallback_base_scale(float p_base_scale);
+ static void set_fallback_icon(const Ref<Texture2D> &p_icon);
+ static void set_fallback_style(const Ref<StyleBox> &p_style);
+ static void set_fallback_font(const Ref<Font> &p_font);
+ static void set_fallback_font_size(int p_font_size);
+
+ static float get_fallback_base_scale();
+ static Ref<Texture2D> get_fallback_icon();
+ static Ref<StyleBox> get_fallback_style();
+ static Ref<Font> get_fallback_font();
+ static int get_fallback_font_size();
+
+ void set_default_base_scale(float p_base_scale);
+ float get_default_base_scale() const;
+ bool has_default_base_scale() const;
+
+ void set_default_font(const Ref<Font> &p_default_font);
+ Ref<Font> get_default_font() const;
+ bool has_default_font() const;
+
+ void set_default_font_size(int p_font_size);
+ int get_default_font_size() const;
+ bool has_default_font_size() const;
void set_icon(const StringName &p_name, const StringName &p_theme_type, const Ref<Texture2D> &p_icon);
Ref<Texture2D> get_icon(const StringName &p_name, const StringName &p_theme_type) const;
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index ed34c906a1..57b73c1234 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -349,11 +349,11 @@ String VisualShaderNodeCustom::get_output_port_name(int p_port) const {
String VisualShaderNodeCustom::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
ERR_FAIL_COND_V(!GDVIRTUAL_IS_OVERRIDDEN(_get_code), "");
- Vector<String> input_vars;
+ TypedArray<String> input_vars;
for (int i = 0; i < get_input_port_count(); i++) {
input_vars.push_back(p_input_vars[i]);
}
- Array output_vars;
+ TypedArray<String> output_vars;
for (int i = 0; i < get_output_port_count(); i++) {
output_vars.push_back(p_output_vars[i]);
}
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index c8b577088d..066c18e3bc 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -326,7 +326,7 @@ protected:
GDVIRTUAL0RC(int, _get_output_port_count)
GDVIRTUAL1RC(int, _get_output_port_type, int)
GDVIRTUAL1RC(String, _get_output_port_name, int)
- GDVIRTUAL4RC(String, _get_code, Vector<String>, TypedArray<String>, Shader::Mode, VisualShader::Type)
+ GDVIRTUAL4RC(String, _get_code, TypedArray<String>, TypedArray<String>, Shader::Mode, VisualShader::Type)
GDVIRTUAL1RC(String, _get_global_code, Shader::Mode)
GDVIRTUAL0RC(bool, _is_highend)