summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/animated_sprite_2d.cpp1
-rw-r--r--scene/gui/control.cpp24
-rw-r--r--scene/gui/graph_edit.cpp16
-rw-r--r--scene/gui/grid_container.cpp55
-rw-r--r--scene/gui/popup.cpp16
-rw-r--r--scene/gui/popup.h4
-rw-r--r--scene/resources/curve.cpp10
-rw-r--r--scene/resources/curve.h4
-rw-r--r--scene/resources/material.cpp2
-rw-r--r--scene/resources/navigation_mesh.cpp4
-rw-r--r--scene/resources/theme.cpp8
11 files changed, 110 insertions, 34 deletions
diff --git a/scene/2d/animated_sprite_2d.cpp b/scene/2d/animated_sprite_2d.cpp
index 4734f97e23..b33c2f43d4 100644
--- a/scene/2d/animated_sprite_2d.cpp
+++ b/scene/2d/animated_sprite_2d.cpp
@@ -388,6 +388,7 @@ void AnimatedSprite2D::play(const StringName &p_animation, const bool p_backward
}
}
+ is_over = false;
set_playing(true);
}
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 54fa726260..a0104387c9 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -712,35 +712,25 @@ void Control::_notification(int p_notification) {
data.parent_window = Object::cast_to<Window>(get_parent());
data.is_rtl_dirty = true;
- Node *parent = this; //meh
+ CanvasItem *node = this;
Control *parent_control = nullptr;
- bool subwindow = false;
-
- while (parent) {
- parent = parent->get_parent();
+ while (!node->is_set_as_top_level()) {
+ CanvasItem *parent = Object::cast_to<CanvasItem>(node->get_parent());
if (!parent) {
break;
}
- CanvasItem *ci = Object::cast_to<CanvasItem>(parent);
- if (ci && ci->is_set_as_top_level()) {
- subwindow = true;
- break;
- }
-
parent_control = Object::cast_to<Control>(parent);
-
if (parent_control) {
break;
- } else if (ci) {
- } else {
- break;
}
+
+ node = parent;
}
- if (parent_control && !subwindow) {
- //do nothing, has a parent control and not top_level
+ if (parent_control) {
+ // Do nothing, has a parent control.
if (data.theme.is_null() && parent_control->data.theme_owner) {
data.theme_owner = parent_control->data.theme_owner;
notification(NOTIFICATION_THEME_CHANGED);
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index 6f3a361e82..0ed9a4e989 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -1343,7 +1343,19 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
emit_signal(SNAME("paste_nodes_request"));
accept_event();
} else if (p_ev->is_action("ui_graph_delete")) {
- emit_signal(SNAME("delete_nodes_request"));
+ TypedArray<StringName> nodes;
+
+ for (int i = 0; i < get_child_count(); i++) {
+ GraphNode *gn = Object::cast_to<GraphNode>(get_child(i));
+ if (!gn) {
+ continue;
+ }
+ if (gn->is_selected() && gn->is_close_button_visible()) {
+ nodes.push_back(gn->get_name());
+ }
+ }
+
+ emit_signal(SNAME("delete_nodes_request"), nodes);
accept_event();
}
}
@@ -2290,7 +2302,7 @@ void GraphEdit::_bind_methods() {
ADD_SIGNAL(MethodInfo("node_deselected", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
ADD_SIGNAL(MethodInfo("connection_to_empty", PropertyInfo(Variant::STRING_NAME, "from"), PropertyInfo(Variant::INT, "from_slot"), PropertyInfo(Variant::VECTOR2, "release_position")));
ADD_SIGNAL(MethodInfo("connection_from_empty", PropertyInfo(Variant::STRING_NAME, "to"), PropertyInfo(Variant::INT, "to_slot"), PropertyInfo(Variant::VECTOR2, "release_position")));
- ADD_SIGNAL(MethodInfo("delete_nodes_request"));
+ ADD_SIGNAL(MethodInfo("delete_nodes_request", PropertyInfo(Variant::ARRAY, "nodes", PROPERTY_HINT_ARRAY_TYPE, "StringName")));
ADD_SIGNAL(MethodInfo("begin_node_move"));
ADD_SIGNAL(MethodInfo("end_node_move"));
ADD_SIGNAL(MethodInfo("scroll_offset_changed", PropertyInfo(Variant::VECTOR2, "offset")));
diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp
index b2cf2f66a9..ec33018da0 100644
--- a/scene/gui/grid_container.cpp
+++ b/scene/gui/grid_container.cpp
@@ -142,13 +142,47 @@ void GridContainer::_notification(int p_what) {
}
// Finally, fit the nodes.
- int col_expand = col_expanded.size() > 0 ? remaining_space.width / col_expanded.size() : 0;
- int row_expand = row_expanded.size() > 0 ? remaining_space.height / row_expanded.size() : 0;
+ int col_remaining_pixel = 0;
+ int col_expand = 0;
+ if (col_expanded.size() > 0) {
+ col_expand = remaining_space.width / col_expanded.size();
+ col_remaining_pixel = remaining_space.width - col_expanded.size() * col_expand;
+ }
+
+ int row_remaining_pixel = 0;
+ int row_expand = 0;
+ if (row_expanded.size() > 0) {
+ row_expand = remaining_space.height / row_expanded.size();
+ row_remaining_pixel = remaining_space.height - row_expanded.size() * row_expand;
+ }
+
bool rtl = is_layout_rtl();
int col_ofs = 0;
int row_ofs = 0;
+ // Calculate the index of rows and columns that receive the remaining pixel.
+ int col_remaining_pixel_index = 0;
+ for (int i = 0; i < max_col; i++) {
+ if (col_remaining_pixel == 0) {
+ break;
+ }
+ if (col_expanded.has(i)) {
+ col_remaining_pixel_index = i + 1;
+ col_remaining_pixel--;
+ }
+ }
+ int row_remaining_pixel_index = 0;
+ for (int i = 0; i < max_row; i++) {
+ if (row_remaining_pixel == 0) {
+ break;
+ }
+ if (row_expanded.has(i)) {
+ row_remaining_pixel_index = i + 1;
+ row_remaining_pixel--;
+ }
+ }
+
valid_controls_index = 0;
for (int i = 0; i < get_child_count(); i++) {
Control *c = Object::cast_to<Control>(get_child(i));
@@ -167,17 +201,30 @@ void GridContainer::_notification(int p_what) {
}
if (row > 0) {
row_ofs += (row_expanded.has(row - 1) ? row_expand : row_minh[row - 1]) + vsep;
+
+ if (row_expanded.has(row - 1) && row - 1 < row_remaining_pixel_index) {
+ // Apply the remaining pixel of the previous row.
+ row_ofs++;
+ }
}
}
+ Size2 s(col_expanded.has(col) ? col_expand : col_minw[col], row_expanded.has(row) ? row_expand : row_minh[row]);
+
+ // Add the remaining pixel to the expanding columns and rows, starting from left and top.
+ if (col_expanded.has(col) && col < col_remaining_pixel_index) {
+ s.x++;
+ }
+ if (row_expanded.has(row) && row < row_remaining_pixel_index) {
+ s.y++;
+ }
+
if (rtl) {
- Size2 s(col_expanded.has(col) ? col_expand : col_minw[col], row_expanded.has(row) ? row_expand : row_minh[row]);
Point2 p(col_ofs - s.width, row_ofs);
fit_child_in_rect(c, Rect2(p, s));
col_ofs -= s.width + hsep;
} else {
Point2 p(col_ofs, row_ofs);
- Size2 s(col_expanded.has(col) ? col_expand : col_minw[col], row_expanded.has(row) ? row_expand : row_minh[row]);
fit_child_in_rect(c, Rect2(p, s));
col_ofs += s.width + hsep;
}
diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp
index b9e3e7814e..6532fc5934 100644
--- a/scene/gui/popup.cpp
+++ b/scene/gui/popup.cpp
@@ -108,11 +108,25 @@ void Popup::_close_pressed() {
_deinitialize_visible_parents();
- call_deferred(SNAME("hide"));
+ // Hide after returning to process events, but only if we don't
+ // get popped up in the interim.
+ call_deferred(SNAME("_popup_conditional_hide"));
+}
+
+void Popup::_post_popup() {
+ Window::_post_popup();
+ popped_up = true;
+}
+
+void Popup::_popup_conditional_hide() {
+ if (!popped_up) {
+ hide();
+ }
}
void Popup::_bind_methods() {
ADD_SIGNAL(MethodInfo("popup_hide"));
+ ClassDB::bind_method(D_METHOD("_popup_conditional_hide"), &Popup::_popup_conditional_hide);
}
Rect2i Popup::_popup_adjust_rect() const {
diff --git a/scene/gui/popup.h b/scene/gui/popup.h
index 6211af4d20..27f46d4a97 100644
--- a/scene/gui/popup.h
+++ b/scene/gui/popup.h
@@ -57,6 +57,10 @@ protected:
void _notification(int p_what);
static void _bind_methods();
+ void _popup_conditional_hide();
+
+ virtual void _post_popup() override;
+
public:
Popup();
~Popup();
diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp
index 34cbd3a360..9ea7bb464a 100644
--- a/scene/resources/curve.cpp
+++ b/scene/resources/curve.cpp
@@ -632,7 +632,7 @@ Vector2 Curve2D::interpolatef(real_t p_findex) const {
return interpolate((int)p_findex, Math::fmod(p_findex, (real_t)1.0));
}
-void Curve2D::_bake_segment2d(HashMap<real_t, Vector2> &r_bake, real_t p_begin, real_t p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_max_depth, real_t p_tol) const {
+void Curve2D::_bake_segment2d(RBMap<real_t, Vector2> &r_bake, real_t p_begin, real_t p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_max_depth, real_t p_tol) const {
real_t mp = p_begin + (p_end - p_begin) * 0.5;
Vector2 beg = _bezier_interp(p_begin, p_a, p_a + p_out, p_b + p_in, p_b);
Vector2 mid = _bezier_interp(mp, p_a, p_a + p_out, p_b + p_in, p_b);
@@ -954,7 +954,9 @@ PackedVector2Array Curve2D::tessellate(int p_max_stages, real_t p_tolerance) con
if (points.size() == 0) {
return tess;
}
- Vector<HashMap<real_t, Vector2>> midpoints;
+
+ // The current implementation requires a sorted map.
+ Vector<RBMap<real_t, Vector2>> midpoints;
midpoints.resize(points.size() - 1);
@@ -1137,7 +1139,7 @@ Vector3 Curve3D::interpolatef(real_t p_findex) const {
return interpolate((int)p_findex, Math::fmod(p_findex, (real_t)1.0));
}
-void Curve3D::_bake_segment3d(HashMap<real_t, Vector3> &r_bake, real_t p_begin, real_t p_end, const Vector3 &p_a, const Vector3 &p_out, const Vector3 &p_b, const Vector3 &p_in, int p_depth, int p_max_depth, real_t p_tol) const {
+void Curve3D::_bake_segment3d(RBMap<real_t, Vector3> &r_bake, real_t p_begin, real_t p_end, const Vector3 &p_a, const Vector3 &p_out, const Vector3 &p_b, const Vector3 &p_in, int p_depth, int p_max_depth, real_t p_tol) const {
real_t mp = p_begin + (p_end - p_begin) * 0.5;
Vector3 beg = _bezier_interp(p_begin, p_a, p_a + p_out, p_b + p_in, p_b);
Vector3 mid = _bezier_interp(mp, p_a, p_a + p_out, p_b + p_in, p_b);
@@ -1668,7 +1670,7 @@ PackedVector3Array Curve3D::tessellate(int p_max_stages, real_t p_tolerance) con
if (points.size() == 0) {
return tess;
}
- Vector<HashMap<real_t, Vector3>> midpoints;
+ Vector<RBMap<real_t, Vector3>> midpoints;
midpoints.resize(points.size() - 1);
diff --git a/scene/resources/curve.h b/scene/resources/curve.h
index f9b172f175..398f64cabe 100644
--- a/scene/resources/curve.h
+++ b/scene/resources/curve.h
@@ -168,7 +168,7 @@ class Curve2D : public Resource {
real_t bake_interval = 5.0;
- void _bake_segment2d(HashMap<real_t, Vector2> &r_bake, real_t p_begin, real_t p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_max_depth, real_t p_tol) const;
+ void _bake_segment2d(RBMap<real_t, Vector2> &r_bake, real_t p_begin, real_t p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_max_depth, real_t p_tol) const;
Dictionary _get_data() const;
void _set_data(const Dictionary &p_data);
@@ -233,7 +233,7 @@ class Curve3D : public Resource {
real_t bake_interval = 0.2;
bool up_vector_enabled = true;
- void _bake_segment3d(HashMap<real_t, Vector3> &r_bake, real_t p_begin, real_t p_end, const Vector3 &p_a, const Vector3 &p_out, const Vector3 &p_b, const Vector3 &p_in, int p_depth, int p_max_depth, real_t p_tol) const;
+ void _bake_segment3d(RBMap<real_t, Vector3> &r_bake, real_t p_begin, real_t p_end, const Vector3 &p_a, const Vector3 &p_out, const Vector3 &p_b, const Vector3 &p_in, int p_depth, int p_max_depth, real_t p_tol) const;
Dictionary _get_data() const;
void _set_data(const Dictionary &p_data);
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 8abdfe713f..b8171ca4bd 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -1788,8 +1788,6 @@ void BaseMaterial3D::_validate_property(PropertyInfo &property) const {
_validate_high_end("refraction", property);
_validate_high_end("subsurf_scatter", property);
- _validate_high_end("anisotropy", property);
- _validate_high_end("clearcoat", property);
_validate_high_end("heightmap", property);
if (property.name.begins_with("particles_anim_") && billboard_mode != BILLBOARD_PARTICLES) {
diff --git a/scene/resources/navigation_mesh.cpp b/scene/resources/navigation_mesh.cpp
index b1270e9dd6..7813de94ca 100644
--- a/scene/resources/navigation_mesh.cpp
+++ b/scene/resources/navigation_mesh.cpp
@@ -229,7 +229,7 @@ float NavigationMesh::get_verts_per_poly() const {
}
void NavigationMesh::set_detail_sample_distance(float p_value) {
- ERR_FAIL_COND(p_value < 0);
+ ERR_FAIL_COND(p_value < 0.1);
detail_sample_distance = p_value;
}
@@ -501,7 +501,7 @@ void NavigationMesh::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "edge/max_length", PROPERTY_HINT_RANGE, "0.0,50.0,0.01,or_greater"), "set_edge_max_length", "get_edge_max_length");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "edge/max_error", PROPERTY_HINT_RANGE, "0.1,3.0,0.01,or_greater"), "set_edge_max_error", "get_edge_max_error");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "polygon/verts_per_poly", PROPERTY_HINT_RANGE, "3.0,12.0,1.0,or_greater"), "set_verts_per_poly", "get_verts_per_poly");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "detail/sample_distance", PROPERTY_HINT_RANGE, "0.0,16.0,0.01,or_greater"), "set_detail_sample_distance", "get_detail_sample_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "detail/sample_distance", PROPERTY_HINT_RANGE, "0.1,16.0,0.01,or_greater"), "set_detail_sample_distance", "get_detail_sample_distance");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "detail/sample_max_error", PROPERTY_HINT_RANGE, "0.0,16.0,0.01,or_greater"), "set_detail_sample_max_error", "get_detail_sample_max_error");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter/low_hanging_obstacles"), "set_filter_low_hanging_obstacles", "get_filter_low_hanging_obstacles");
diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp
index 10806aef45..1e57933000 100644
--- a/scene/resources/theme.cpp
+++ b/scene/resources/theme.cpp
@@ -172,7 +172,15 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
// Sort and store properties.
list.sort();
+ String prev_type;
for (const PropertyInfo &E : list) {
+ // Add groups for types so that their names are left unchanged in the inspector.
+ String current_type = E.name.get_slice("/", 0);
+ if (prev_type != current_type) {
+ p_list->push_back(PropertyInfo(Variant::NIL, current_type, PROPERTY_HINT_NONE, current_type + "/", PROPERTY_USAGE_GROUP));
+ prev_type = current_type;
+ }
+
p_list->push_back(E);
}
}