summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
authorYuri Sizov <11782833+YuriSizov@users.noreply.github.com>2023-03-27 20:14:47 +0200
committerGitHub <noreply@github.com>2023-03-27 20:14:47 +0200
commit19501f8eb19481b029f67ecf78e711d42f2fc431 (patch)
tree933ea3320b35bce6ba65ab1e1d1aa8ad662c90d4 /scene
parentcacf49999e3fb37281d66cc591ca8bebc5712d4d (diff)
parent843f5adbc523ad2511322b4f09b5ce5a3fb9e225 (diff)
Merge pull request #75397 from YuriSizov/4.0-cherrypicks
Cherry-picks for the 4.0 branch (future 4.0.2) - 1st batch
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/animated_sprite_2d.cpp4
-rw-r--r--scene/2d/shape_cast_2d.cpp13
-rw-r--r--scene/2d/shape_cast_2d.h2
-rw-r--r--scene/3d/shape_cast_3d.cpp6
-rw-r--r--scene/gui/code_edit.h2
-rw-r--r--scene/gui/control.cpp55
-rw-r--r--scene/gui/graph_edit.cpp42
-rw-r--r--scene/gui/graph_node.cpp8
-rw-r--r--scene/gui/line_edit.cpp19
-rw-r--r--scene/gui/rich_text_label.cpp5
-rw-r--r--scene/gui/scroll_bar.cpp12
-rw-r--r--scene/gui/subviewport_container.cpp22
-rw-r--r--scene/gui/subviewport_container.h1
-rw-r--r--scene/gui/text_edit.cpp17
-rw-r--r--scene/main/canvas_item.cpp3
-rw-r--r--scene/main/viewport.cpp16
-rw-r--r--scene/main/viewport.h1
-rw-r--r--scene/main/window.cpp47
-rw-r--r--scene/resources/gradient.cpp1
-rw-r--r--scene/resources/shape_3d.cpp2
-rw-r--r--scene/resources/texture.cpp7
-rw-r--r--scene/resources/texture.h1
-rw-r--r--scene/resources/visual_shader_nodes.cpp7
23 files changed, 197 insertions, 96 deletions
diff --git a/scene/2d/animated_sprite_2d.cpp b/scene/2d/animated_sprite_2d.cpp
index 8f7006caca..7de6219b10 100644
--- a/scene/2d/animated_sprite_2d.cpp
+++ b/scene/2d/animated_sprite_2d.cpp
@@ -301,13 +301,13 @@ void AnimatedSprite2D::set_sprite_frames(const Ref<SpriteFrames> &p_frames) {
frames->get_animation_list(&al);
if (al.size() == 0) {
set_animation(StringName());
- set_autoplay(String());
+ autoplay = String();
} else {
if (!frames->has_animation(animation)) {
set_animation(al[0]);
}
if (!frames->has_animation(autoplay)) {
- set_autoplay(String());
+ autoplay = String();
}
}
}
diff --git a/scene/2d/shape_cast_2d.cpp b/scene/2d/shape_cast_2d.cpp
index bafb83361a..5b743e0b31 100644
--- a/scene/2d/shape_cast_2d.cpp
+++ b/scene/2d/shape_cast_2d.cpp
@@ -151,11 +151,18 @@ bool ShapeCast2D::is_enabled() const {
}
void ShapeCast2D::set_shape(const Ref<Shape2D> &p_shape) {
+ if (p_shape == shape) {
+ return;
+ }
+ if (shape.is_valid()) {
+ shape->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &ShapeCast2D::_shape_changed));
+ }
shape = p_shape;
- if (p_shape.is_valid()) {
- shape->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &ShapeCast2D::_redraw_shape));
+ if (shape.is_valid()) {
+ shape->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &ShapeCast2D::_shape_changed));
shape_rid = shape->get_rid();
}
+
update_configuration_warnings();
queue_redraw();
}
@@ -186,7 +193,7 @@ bool ShapeCast2D::get_exclude_parent_body() const {
return exclude_parent_body;
}
-void ShapeCast2D::_redraw_shape() {
+void ShapeCast2D::_shape_changed() {
queue_redraw();
}
diff --git a/scene/2d/shape_cast_2d.h b/scene/2d/shape_cast_2d.h
index 8a62b799f8..a577c351fd 100644
--- a/scene/2d/shape_cast_2d.h
+++ b/scene/2d/shape_cast_2d.h
@@ -61,7 +61,7 @@ class ShapeCast2D : public Node2D {
real_t collision_unsafe_fraction = 1.0;
Array _get_collision_result() const;
- void _redraw_shape();
+ void _shape_changed();
protected:
void _notification(int p_what);
diff --git a/scene/3d/shape_cast_3d.cpp b/scene/3d/shape_cast_3d.cpp
index d880e422f0..602eb664dd 100644
--- a/scene/3d/shape_cast_3d.cpp
+++ b/scene/3d/shape_cast_3d.cpp
@@ -331,16 +331,14 @@ void ShapeCast3D::set_shape(const Ref<Shape3D> &p_shape) {
if (p_shape == shape) {
return;
}
- if (!shape.is_null()) {
+ if (shape.is_valid()) {
shape->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &ShapeCast3D::_shape_changed));
shape->unregister_owner(this);
}
shape = p_shape;
- if (!shape.is_null()) {
+ if (shape.is_valid()) {
shape->register_owner(this);
shape->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &ShapeCast3D::_shape_changed));
- }
- if (p_shape.is_valid()) {
shape_rid = shape->get_rid();
}
diff --git a/scene/gui/code_edit.h b/scene/gui/code_edit.h
index 55fc5aa2ae..fe4b8d4809 100644
--- a/scene/gui/code_edit.h
+++ b/scene/gui/code_edit.h
@@ -108,7 +108,7 @@ private:
/* Line numbers */
int line_number_gutter = -1;
- int line_number_digits = 0;
+ int line_number_digits = 1;
String line_number_padding = " ";
Color line_number_color = Color(1, 1, 1);
void _line_number_draw_callback(int p_line, int p_gutter, const Rect2 &p_region);
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index ec75fcb665..3ecb9c47c0 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -360,7 +360,7 @@ bool Control::_get(const StringName &p_name, Variant &r_ret) const {
void Control::_get_property_list(List<PropertyInfo> *p_list) const {
Ref<Theme> default_theme = ThemeDB::get_singleton()->get_default_theme();
- p_list->push_back(PropertyInfo(Variant::NIL, TTRC("Theme Overrides"), PROPERTY_HINT_NONE, "theme_override_", PROPERTY_USAGE_GROUP));
+ p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Theme Overrides", "theme_override_"), PROPERTY_HINT_NONE, "theme_override_", PROPERTY_USAGE_GROUP));
{
List<StringName> names;
@@ -371,7 +371,7 @@ void Control::_get_property_list(List<PropertyInfo> *p_list) const {
usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
}
- p_list->push_back(PropertyInfo(Variant::COLOR, "theme_override_colors/" + E, PROPERTY_HINT_NONE, "", usage));
+ p_list->push_back(PropertyInfo(Variant::COLOR, PNAME("theme_override_colors") + String("/") + E, PROPERTY_HINT_NONE, "", usage));
}
}
{
@@ -383,7 +383,7 @@ void Control::_get_property_list(List<PropertyInfo> *p_list) const {
usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
}
- p_list->push_back(PropertyInfo(Variant::INT, "theme_override_constants/" + E, PROPERTY_HINT_RANGE, "-16384,16384", usage));
+ p_list->push_back(PropertyInfo(Variant::INT, PNAME("theme_override_constants") + String("/") + E, PROPERTY_HINT_RANGE, "-16384,16384", usage));
}
}
{
@@ -395,7 +395,7 @@ void Control::_get_property_list(List<PropertyInfo> *p_list) const {
usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
}
- p_list->push_back(PropertyInfo(Variant::OBJECT, "theme_override_fonts/" + E, PROPERTY_HINT_RESOURCE_TYPE, "Font", usage));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, PNAME("theme_override_fonts") + String("/") + E, PROPERTY_HINT_RESOURCE_TYPE, "Font", usage));
}
}
{
@@ -407,7 +407,7 @@ void Control::_get_property_list(List<PropertyInfo> *p_list) const {
usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
}
- p_list->push_back(PropertyInfo(Variant::INT, "theme_override_font_sizes/" + E, PROPERTY_HINT_RANGE, "1,256,1,or_greater,suffix:px", usage));
+ p_list->push_back(PropertyInfo(Variant::INT, PNAME("theme_override_font_sizes") + String("/") + E, PROPERTY_HINT_RANGE, "1,256,1,or_greater,suffix:px", usage));
}
}
{
@@ -419,7 +419,7 @@ void Control::_get_property_list(List<PropertyInfo> *p_list) const {
usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
}
- p_list->push_back(PropertyInfo(Variant::OBJECT, "theme_override_icons/" + E, PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", usage));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, PNAME("theme_override_icons") + String("/") + E, PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", usage));
}
}
{
@@ -431,7 +431,7 @@ void Control::_get_property_list(List<PropertyInfo> *p_list) const {
usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
}
- p_list->push_back(PropertyInfo(Variant::OBJECT, "theme_override_styles/" + E, PROPERTY_HINT_RESOURCE_TYPE, "StyleBox", usage));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, PNAME("theme_override_styles") + String("/") + E, PROPERTY_HINT_RESOURCE_TYPE, "StyleBox", usage));
}
}
}
@@ -2793,19 +2793,34 @@ bool Control::is_layout_rtl() const {
if (data.is_rtl_dirty) {
const_cast<Control *>(this)->data.is_rtl_dirty = false;
if (data.layout_dir == LAYOUT_DIRECTION_INHERITED) {
- Window *parent_window = get_parent_window();
- Control *parent_control = get_parent_control();
- if (parent_control) {
- const_cast<Control *>(this)->data.is_rtl = parent_control->is_layout_rtl();
- } else if (parent_window) {
- const_cast<Control *>(this)->data.is_rtl = parent_window->is_layout_rtl();
- } else {
- if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) {
- const_cast<Control *>(this)->data.is_rtl = true;
- } else {
- String locale = TranslationServer::get_singleton()->get_tool_locale();
- const_cast<Control *>(this)->data.is_rtl = TS->is_locale_right_to_left(locale);
+ if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) {
+ const_cast<Control *>(this)->data.is_rtl = true;
+ return data.is_rtl;
+ }
+ Node *parent_node = get_parent();
+ while (parent_node) {
+ Control *parent_control = Object::cast_to<Control>(parent_node);
+ if (parent_control) {
+ const_cast<Control *>(this)->data.is_rtl = parent_control->is_layout_rtl();
+ return data.is_rtl;
}
+
+ Window *parent_window = Object::cast_to<Window>(parent_node);
+ if (parent_window) {
+ const_cast<Control *>(this)->data.is_rtl = parent_window->is_layout_rtl();
+ return data.is_rtl;
+ }
+ parent_node = parent_node->get_parent();
+ }
+
+ int root_dir = GLOBAL_GET(SNAME("internationalization/rendering/root_node_layout_direction"));
+ if (root_dir == 1) {
+ const_cast<Control *>(this)->data.is_rtl = false;
+ } else if (root_dir == 2) {
+ const_cast<Control *>(this)->data.is_rtl = true;
+ } else {
+ String locale = TranslationServer::get_singleton()->get_tool_locale();
+ const_cast<Control *>(this)->data.is_rtl = TS->is_locale_right_to_left(locale);
}
} else if (data.layout_dir == LAYOUT_DIRECTION_LOCALE) {
if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) {
@@ -3230,7 +3245,7 @@ void Control::_bind_methods() {
ADD_GROUP("Layout", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_contents"), "set_clip_contents", "is_clipping_contents");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "custom_minimum_size", PROPERTY_HINT_NONE, "suffix:px"), "set_custom_minimum_size", "get_custom_minimum_size");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "layout_direction", PROPERTY_HINT_ENUM, "Inherited,Locale,Left-to-Right,Right-to-Left"), "set_layout_direction", "get_layout_direction");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "layout_direction", PROPERTY_HINT_ENUM, "Inherited,Based on Locale,Left-to-Right,Right-to-Left"), "set_layout_direction", "get_layout_direction");
ADD_PROPERTY(PropertyInfo(Variant::INT, "layout_mode", PROPERTY_HINT_ENUM, "Position,Anchors,Container,Uncontrolled", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "_set_layout_mode", "_get_layout_mode");
ADD_PROPERTY_DEFAULT("layout_mode", LayoutMode::LAYOUT_MODE_POSITION);
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index 58b820c31f..9c0c25b1ac 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -839,6 +839,14 @@ bool GraphEdit::is_in_input_hotzone(GraphNode *p_node, int p_port, const Vector2
}
bool GraphEdit::is_in_output_hotzone(GraphNode *p_node, int p_port, const Vector2 &p_mouse_pos, const Vector2i &p_port_size) {
+ if (p_node->is_resizable()) {
+ Ref<Texture2D> resizer = p_node->get_theme_icon(SNAME("resizer"));
+ Rect2 resizer_rect = Rect2(p_node->get_position() / zoom + p_node->get_size() - resizer->get_size(), resizer->get_size());
+ if (resizer_rect.has_point(p_mouse_pos)) {
+ return false;
+ }
+ }
+
bool success;
if (GDVIRTUAL_CALL(_is_in_output_hotzone, p_node, p_port, p_mouse_pos, success)) {
return success;
@@ -848,10 +856,10 @@ bool GraphEdit::is_in_output_hotzone(GraphNode *p_node, int p_port, const Vector
}
}
-bool GraphEdit::is_in_port_hotzone(const Vector2 &pos, const Vector2 &p_mouse_pos, const Vector2i &p_port_size, bool p_left) {
+bool GraphEdit::is_in_port_hotzone(const Vector2 &p_pos, const Vector2 &p_mouse_pos, const Vector2i &p_port_size, bool p_left) {
Rect2 hotzone = Rect2(
- pos.x - (p_left ? port_hotzone_outer_extent : port_hotzone_inner_extent),
- pos.y - p_port_size.height / 2.0,
+ p_pos.x - (p_left ? port_hotzone_outer_extent : port_hotzone_inner_extent),
+ p_pos.y - p_port_size.height / 2.0,
port_hotzone_inner_extent + port_hotzone_outer_extent,
p_port_size.height);
@@ -1175,9 +1183,9 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
minimap->queue_redraw();
}
- Ref<InputEventMouseButton> b = p_ev;
- if (b.is_valid()) {
- if (b->get_button_index() == MouseButton::RIGHT && b->is_pressed()) {
+ Ref<InputEventMouseButton> mb = p_ev;
+ if (mb.is_valid()) {
+ if (mb->get_button_index() == MouseButton::RIGHT && mb->is_pressed()) {
if (box_selecting) {
box_selecting = false;
for (int i = get_child_count() - 1; i >= 0; i--) {
@@ -1194,12 +1202,12 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
if (connecting) {
force_connection_drag_end();
} else {
- emit_signal(SNAME("popup_request"), b->get_position());
+ emit_signal(SNAME("popup_request"), mb->get_position());
}
}
}
- if (b->get_button_index() == MouseButton::LEFT && !b->is_pressed() && dragging) {
+ if (mb->get_button_index() == MouseButton::LEFT && !mb->is_pressed() && dragging) {
if (!just_selected && drag_accum == Vector2() && Input::get_singleton()->is_key_pressed(Key::CTRL)) {
//deselect current node
for (int i = get_child_count() - 1; i >= 0; i--) {
@@ -1208,7 +1216,7 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
if (gn) {
Rect2 r = gn->get_rect();
r.size *= zoom;
- if (r.has_point(b->get_position())) {
+ if (r.has_point(mb->get_position())) {
gn->set_selected(false);
}
}
@@ -1240,7 +1248,7 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
connections_layer->queue_redraw();
}
- if (b->get_button_index() == MouseButton::LEFT && b->is_pressed()) {
+ if (mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) {
GraphNode *gn = nullptr;
// Find node which was clicked on.
@@ -1255,14 +1263,14 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
continue;
}
- if (gn_selected->has_point((b->get_position() - gn_selected->get_position()) / zoom)) {
+ if (gn_selected->has_point((mb->get_position() - gn_selected->get_position()) / zoom)) {
gn = gn_selected;
break;
}
}
if (gn) {
- if (_filter_input(b->get_position())) {
+ if (_filter_input(mb->get_position())) {
return;
}
@@ -1297,7 +1305,7 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
}
} else {
- if (_filter_input(b->get_position())) {
+ if (_filter_input(mb->get_position())) {
return;
}
if (panner->is_panning()) {
@@ -1306,8 +1314,8 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
// Left-clicked on empty space, start box select.
box_selecting = true;
- box_selecting_from = b->get_position();
- if (b->is_ctrl_pressed()) {
+ box_selecting_from = mb->get_position();
+ if (mb->is_ctrl_pressed()) {
box_selection_mode_additive = true;
previous_selected.clear();
for (int i = get_child_count() - 1; i >= 0; i--) {
@@ -1318,7 +1326,7 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
previous_selected.push_back(gn2);
}
- } else if (b->is_shift_pressed()) {
+ } else if (mb->is_shift_pressed()) {
box_selection_mode_additive = false;
previous_selected.clear();
for (int i = get_child_count() - 1; i >= 0; i--) {
@@ -1344,7 +1352,7 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
}
}
- if (b->get_button_index() == MouseButton::LEFT && !b->is_pressed() && box_selecting) {
+ if (mb->get_button_index() == MouseButton::LEFT && !mb->is_pressed() && box_selecting) {
// Box selection ended. Nodes were selected during mouse movement.
box_selecting = false;
box_selecting_rect = Rect2();
diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp
index f8d2ff0d2c..7d9cdd62ff 100644
--- a/scene/gui/graph_node.cpp
+++ b/scene/gui/graph_node.cpp
@@ -805,13 +805,13 @@ void GraphNode::_connpos_update() {
Size2i size = c->get_rect().size;
int y = sb->get_margin(SIDE_TOP) + vofs;
- int h = size.y;
+ int h = size.height;
if (slot_info.has(idx)) {
if (slot_info[idx].enable_left) {
PortCache cc;
cc.position = Point2i(edgeofs, y + h / 2);
- cc.height = size.height;
+ cc.height = h;
cc.slot_idx = idx;
cc.type = slot_info[idx].type_left;
@@ -822,7 +822,7 @@ void GraphNode::_connpos_update() {
if (slot_info[idx].enable_right) {
PortCache cc;
cc.position = Point2i(get_size().width - edgeofs, y + h / 2);
- cc.height = size.height;
+ cc.height = h;
cc.slot_idx = idx;
cc.type = slot_info[idx].type_right;
@@ -833,7 +833,7 @@ void GraphNode::_connpos_update() {
}
vofs += sep;
- vofs += size.y;
+ vofs += h;
idx++;
}
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index a57dccd5c8..6b2faf1a40 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -638,6 +638,11 @@ HorizontalAlignment LineEdit::get_horizontal_alignment() const {
}
Variant LineEdit::get_drag_data(const Point2 &p_point) {
+ Variant ret = Control::get_drag_data(p_point);
+ if (ret != Variant()) {
+ return ret;
+ }
+
if (selection.drag_attempt && selection.enabled) {
String t = text.substr(selection.begin, selection.end - selection.begin);
Label *l = memnew(Label);
@@ -1068,8 +1073,11 @@ void LineEdit::_notification(int p_what) {
if (has_focus()) {
if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_IME)) {
DisplayServer::get_singleton()->window_set_ime_active(true, get_viewport()->get_window_id());
- Point2 pos = Point2(get_caret_pixel_pos().x, (get_size().y + theme_cache.font->get_height(theme_cache.font_size)) / 2);
- DisplayServer::get_singleton()->window_set_ime_position(get_global_position() + pos, get_viewport()->get_window_id());
+ Point2 pos = Point2(get_caret_pixel_pos().x, (get_size().y + theme_cache.font->get_height(theme_cache.font_size)) / 2) + get_global_position();
+ if (get_window()->get_embedder()) {
+ pos += get_viewport()->get_popup_base_transform().get_origin();
+ }
+ DisplayServer::get_singleton()->window_set_ime_position(pos, get_viewport()->get_window_id());
}
}
} break;
@@ -1088,8 +1096,11 @@ void LineEdit::_notification(int p_what) {
if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_IME)) {
DisplayServer::get_singleton()->window_set_ime_active(true, get_viewport()->get_window_id());
- Point2 pos = Point2(get_caret_pixel_pos().x, (get_size().y + theme_cache.font->get_height(theme_cache.font_size)) / 2);
- DisplayServer::get_singleton()->window_set_ime_position(get_global_position() + pos, get_viewport()->get_window_id());
+ Point2 pos = Point2(get_caret_pixel_pos().x, (get_size().y + theme_cache.font->get_height(theme_cache.font_size)) / 2) + get_global_position();
+ if (get_window()->get_embedder()) {
+ pos += get_viewport()->get_popup_base_transform().get_origin();
+ }
+ DisplayServer::get_singleton()->window_set_ime_position(pos, get_viewport()->get_window_id());
}
show_virtual_keyboard();
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index ec1fbb7e28..68e12b9bb5 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -4735,6 +4735,11 @@ void RichTextLabel::set_deselect_on_focus_loss_enabled(const bool p_enabled) {
}
Variant RichTextLabel::get_drag_data(const Point2 &p_point) {
+ Variant ret = Control::get_drag_data(p_point);
+ if (ret != Variant()) {
+ return ret;
+ }
+
if (selection.drag_attempt && selection.enabled) {
String t = get_selected_text();
Label *l = memnew(Label);
diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp
index b8faf22a59..fcf9302953 100644
--- a/scene/gui/scroll_bar.cpp
+++ b/scene/gui/scroll_bar.cpp
@@ -55,12 +55,14 @@ void ScrollBar::gui_input(const Ref<InputEvent> &p_event) {
accept_event();
if (b->get_button_index() == MouseButton::WHEEL_DOWN && b->is_pressed()) {
- set_value(get_value() + get_page() / 4.0);
+ double change = get_page() != 0.0 ? get_page() / 4.0 : (get_max() - get_min()) / 16.0;
+ set_value(get_value() + MAX(change, get_step()));
accept_event();
}
if (b->get_button_index() == MouseButton::WHEEL_UP && b->is_pressed()) {
- set_value(get_value() - get_page() / 4.0);
+ double change = get_page() != 0.0 ? get_page() / 4.0 : (get_max() - get_min()) / 16.0;
+ set_value(get_value() - MAX(change, get_step()));
accept_event();
}
@@ -99,7 +101,8 @@ void ScrollBar::gui_input(const Ref<InputEvent> &p_event) {
if (scrolling) {
target_scroll = CLAMP(target_scroll - get_page(), get_min(), get_max() - get_page());
} else {
- target_scroll = CLAMP(get_value() - get_page(), get_min(), get_max() - get_page());
+ double change = get_page() != 0.0 ? get_page() : (get_max() - get_min()) / 16.0;
+ target_scroll = CLAMP(get_value() - change, get_min(), get_max() - get_page());
}
if (smooth_scroll_enabled) {
@@ -122,7 +125,8 @@ void ScrollBar::gui_input(const Ref<InputEvent> &p_event) {
if (scrolling) {
target_scroll = CLAMP(target_scroll + get_page(), get_min(), get_max() - get_page());
} else {
- target_scroll = CLAMP(get_value() + get_page(), get_min(), get_max() - get_page());
+ double change = get_page() != 0.0 ? get_page() : (get_max() - get_min()) / 16.0;
+ target_scroll = CLAMP(get_value() + change, get_min(), get_max() - get_page());
}
if (smooth_scroll_enabled) {
diff --git a/scene/gui/subviewport_container.cpp b/scene/gui/subviewport_container.cpp
index f10e1c2cd1..f9e96a44ed 100644
--- a/scene/gui/subviewport_container.cpp
+++ b/scene/gui/subviewport_container.cpp
@@ -58,6 +58,7 @@ void SubViewportContainer::set_stretch(bool p_enable) {
}
stretch = p_enable;
+ recalc_force_viewport_sizes();
update_minimum_size();
queue_sort();
queue_redraw();
@@ -75,10 +76,16 @@ void SubViewportContainer::set_stretch_shrink(int p_shrink) {
shrink = p_shrink;
+ recalc_force_viewport_sizes();
+ queue_redraw();
+}
+
+void SubViewportContainer::recalc_force_viewport_sizes() {
if (!stretch) {
return;
}
+ // If stretch is enabled, make sure that all child SubViwewports have the correct size.
for (int i = 0; i < get_child_count(); i++) {
SubViewport *c = Object::cast_to<SubViewport>(get_child(i));
if (!c) {
@@ -87,8 +94,6 @@ void SubViewportContainer::set_stretch_shrink(int p_shrink) {
c->set_size_force(get_size() / shrink);
}
-
- queue_redraw();
}
int SubViewportContainer::get_stretch_shrink() const {
@@ -106,18 +111,7 @@ Vector<int> SubViewportContainer::get_allowed_size_flags_vertical() const {
void SubViewportContainer::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_RESIZED: {
- if (!stretch) {
- return;
- }
-
- for (int i = 0; i < get_child_count(); i++) {
- SubViewport *c = Object::cast_to<SubViewport>(get_child(i));
- if (!c) {
- continue;
- }
-
- c->set_size_force(get_size() / shrink);
- }
+ recalc_force_viewport_sizes();
} break;
case NOTIFICATION_ENTER_TREE:
diff --git a/scene/gui/subviewport_container.h b/scene/gui/subviewport_container.h
index d3236b0c4e..c1a74e5b98 100644
--- a/scene/gui/subviewport_container.h
+++ b/scene/gui/subviewport_container.h
@@ -58,6 +58,7 @@ public:
virtual void unhandled_input(const Ref<InputEvent> &p_event) override;
void set_stretch_shrink(int p_shrink);
int get_stretch_shrink() const;
+ void recalc_force_viewport_sizes();
virtual Size2 get_minimum_size() const override;
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 8f425436b7..30bac0f58c 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -1480,7 +1480,11 @@ void TextEdit::_notification(int p_what) {
if (has_focus()) {
if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_IME)) {
DisplayServer::get_singleton()->window_set_ime_active(true, get_viewport()->get_window_id());
- DisplayServer::get_singleton()->window_set_ime_position(get_global_position() + get_caret_draw_pos(), get_viewport()->get_window_id());
+ Point2 pos = get_global_position() + get_caret_draw_pos();
+ if (get_window()->get_embedder()) {
+ pos += get_viewport()->get_popup_base_transform().get_origin();
+ }
+ DisplayServer::get_singleton()->window_set_ime_position(pos, get_viewport()->get_window_id());
}
}
} break;
@@ -1494,7 +1498,11 @@ void TextEdit::_notification(int p_what) {
if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_IME)) {
DisplayServer::get_singleton()->window_set_ime_active(true, get_viewport()->get_window_id());
- DisplayServer::get_singleton()->window_set_ime_position(get_global_position() + get_caret_draw_pos(), get_viewport()->get_window_id());
+ Point2 pos = get_global_position() + get_caret_draw_pos();
+ if (get_window()->get_embedder()) {
+ pos += get_viewport()->get_popup_base_transform().get_origin();
+ }
+ DisplayServer::get_singleton()->window_set_ime_position(pos, get_viewport()->get_window_id());
}
if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD) && virtual_keyboard_enabled) {
@@ -3027,6 +3035,11 @@ bool TextEdit::is_text_field() const {
}
Variant TextEdit::get_drag_data(const Point2 &p_point) {
+ Variant ret = Control::get_drag_data(p_point);
+ if (ret != Variant()) {
+ return ret;
+ }
+
if (has_selection() && selection_drag_attempt) {
String t = get_selected_text();
Label *l = memnew(Label);
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp
index b36353158b..72fb838732 100644
--- a/scene/main/canvas_item.cpp
+++ b/scene/main/canvas_item.cpp
@@ -289,11 +289,12 @@ void CanvasItem::_notification(int p_what) {
}
}
+ _enter_canvas();
+
RenderingServer::get_singleton()->canvas_item_set_visible(canvas_item, is_visible_in_tree()); // The visibility of the parent may change.
if (is_visible_in_tree()) {
notification(NOTIFICATION_VISIBILITY_CHANGED); // Considered invisible until entered.
}
- _enter_canvas();
_update_texture_filter_changed(false);
_update_texture_repeat_changed(false);
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 244e0d5b93..8cd57536bf 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -4281,6 +4281,11 @@ void SubViewport::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
RS::get_singleton()->viewport_set_active(get_viewport_rid(), true);
+
+ SubViewportContainer *parent_svc = Object::cast_to<SubViewportContainer>(get_parent());
+ if (parent_svc) {
+ parent_svc->recalc_force_viewport_sizes();
+ }
} break;
case NOTIFICATION_EXIT_TREE: {
@@ -4323,6 +4328,17 @@ void SubViewport::_bind_methods() {
BIND_ENUM_CONSTANT(UPDATE_ALWAYS);
}
+void SubViewport::_validate_property(PropertyInfo &p_property) const {
+ if (p_property.name == "size") {
+ SubViewportContainer *parent_svc = Object::cast_to<SubViewportContainer>(get_parent());
+ if (parent_svc && parent_svc->is_stretch_enabled()) {
+ p_property.usage = PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_READ_ONLY;
+ } else {
+ p_property.usage = PROPERTY_USAGE_DEFAULT;
+ }
+ }
+}
+
SubViewport::SubViewport() {
RS::get_singleton()->viewport_set_size(get_viewport_rid(), get_size().width, get_size().height);
}
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 055fad5369..5213c0db01 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -784,6 +784,7 @@ public:
virtual Transform2D get_screen_transform_internal(bool p_absolute_position = false) const override;
virtual Transform2D get_popup_base_transform() const override;
+ void _validate_property(PropertyInfo &p_property) const;
SubViewport();
~SubViewport();
};
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index 9fb4ed458f..9bbb91fe1b 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -146,7 +146,7 @@ bool Window::_get(const StringName &p_name, Variant &r_ret) const {
void Window::_get_property_list(List<PropertyInfo> *p_list) const {
Ref<Theme> default_theme = ThemeDB::get_singleton()->get_default_theme();
- p_list->push_back(PropertyInfo(Variant::NIL, TTRC("Theme Overrides"), PROPERTY_HINT_NONE, "theme_override_", PROPERTY_USAGE_GROUP));
+ p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Theme Overrides", "theme_override_"), PROPERTY_HINT_NONE, "theme_override_", PROPERTY_USAGE_GROUP));
{
List<StringName> names;
@@ -157,7 +157,7 @@ void Window::_get_property_list(List<PropertyInfo> *p_list) const {
usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
}
- p_list->push_back(PropertyInfo(Variant::COLOR, "theme_override_colors/" + E, PROPERTY_HINT_NONE, "", usage));
+ p_list->push_back(PropertyInfo(Variant::COLOR, PNAME("theme_override_colors") + String("/") + E, PROPERTY_HINT_NONE, "", usage));
}
}
{
@@ -169,7 +169,7 @@ void Window::_get_property_list(List<PropertyInfo> *p_list) const {
usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
}
- p_list->push_back(PropertyInfo(Variant::INT, "theme_override_constants/" + E, PROPERTY_HINT_RANGE, "-16384,16384", usage));
+ p_list->push_back(PropertyInfo(Variant::INT, PNAME("theme_override_constants") + String("/") + E, PROPERTY_HINT_RANGE, "-16384,16384", usage));
}
}
{
@@ -181,7 +181,7 @@ void Window::_get_property_list(List<PropertyInfo> *p_list) const {
usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
}
- p_list->push_back(PropertyInfo(Variant::OBJECT, "theme_override_fonts/" + E, PROPERTY_HINT_RESOURCE_TYPE, "Font", usage));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, PNAME("theme_override_fonts") + String("/") + E, PROPERTY_HINT_RESOURCE_TYPE, "Font", usage));
}
}
{
@@ -193,7 +193,7 @@ void Window::_get_property_list(List<PropertyInfo> *p_list) const {
usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
}
- p_list->push_back(PropertyInfo(Variant::INT, "theme_override_font_sizes/" + E, PROPERTY_HINT_RANGE, "1,256,1,or_greater,suffix:px", usage));
+ p_list->push_back(PropertyInfo(Variant::INT, PNAME("theme_override_font_sizes") + String("/") + E, PROPERTY_HINT_RANGE, "1,256,1,or_greater,suffix:px", usage));
}
}
{
@@ -205,7 +205,7 @@ void Window::_get_property_list(List<PropertyInfo> *p_list) const {
usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
}
- p_list->push_back(PropertyInfo(Variant::OBJECT, "theme_override_icons/" + E, PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", usage));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, PNAME("theme_override_icons") + String("/") + E, PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", usage));
}
}
{
@@ -217,7 +217,7 @@ void Window::_get_property_list(List<PropertyInfo> *p_list) const {
usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
}
- p_list->push_back(PropertyInfo(Variant::OBJECT, "theme_override_styles/" + E, PROPERTY_HINT_RESOURCE_TYPE, "StyleBox", usage));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, PNAME("theme_override_styles") + String("/") + E, PROPERTY_HINT_RESOURCE_TYPE, "StyleBox", usage));
}
}
}
@@ -2116,22 +2116,39 @@ Window::LayoutDirection Window::get_layout_direction() const {
bool Window::is_layout_rtl() const {
if (layout_dir == LAYOUT_DIRECTION_INHERITED) {
- Window *parent_w = Object::cast_to<Window>(get_parent());
- if (parent_w) {
- return parent_w->is_layout_rtl();
- } else {
- if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) {
- return true;
+ if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) {
+ return true;
+ }
+ Node *parent_node = get_parent();
+ while (parent_node) {
+ Control *parent_control = Object::cast_to<Control>(parent_node);
+ if (parent_control) {
+ return parent_control->is_layout_rtl();
}
+
+ Window *parent_window = Object::cast_to<Window>(parent_node);
+ if (parent_window) {
+ return parent_window->is_layout_rtl();
+ }
+ parent_node = parent_node->get_parent();
+ }
+
+ int root_dir = GLOBAL_GET(SNAME("internationalization/rendering/root_node_layout_direction"));
+ if (root_dir == 1) {
+ return false;
+ } else if (root_dir == 2) {
+ return true;
+ } else {
String locale = TranslationServer::get_singleton()->get_tool_locale();
return TS->is_locale_right_to_left(locale);
}
} else if (layout_dir == LAYOUT_DIRECTION_LOCALE) {
if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) {
return true;
+ } else {
+ String locale = TranslationServer::get_singleton()->get_tool_locale();
+ return TS->is_locale_right_to_left(locale);
}
- String locale = TranslationServer::get_singleton()->get_tool_locale();
- return TS->is_locale_right_to_left(locale);
} else {
return (layout_dir == LAYOUT_DIRECTION_RTL);
}
diff --git a/scene/resources/gradient.cpp b/scene/resources/gradient.cpp
index 0209bf9aec..eafc4bec7d 100644
--- a/scene/resources/gradient.cpp
+++ b/scene/resources/gradient.cpp
@@ -153,6 +153,7 @@ void Gradient::reverse() {
points.write[i].offset = 1.0 - points[i].offset;
}
+ is_sorted = false;
_update_sorting();
emit_signal(CoreStringNames::get_singleton()->changed);
}
diff --git a/scene/resources/shape_3d.cpp b/scene/resources/shape_3d.cpp
index 18a4001f38..5a79392ba5 100644
--- a/scene/resources/shape_3d.cpp
+++ b/scene/resources/shape_3d.cpp
@@ -117,7 +117,7 @@ void Shape3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_debug_mesh"), &Shape3D::get_debug_mesh);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "custom_solver_bias", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_custom_solver_bias", "get_custom_solver_bias");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin", PROPERTY_HINT_RANGE, "0.001,10,0.001,suffix:m"), "set_margin", "get_margin");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin", PROPERTY_HINT_RANGE, "0,10,0.001,or_greater,suffix:m"), "set_margin", "get_margin");
}
Shape3D::Shape3D() {
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 651bad1aa7..282c531555 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -2935,6 +2935,10 @@ TypedArray<Image> ImageTextureLayered::_get_images() const {
return images;
}
+void ImageTextureLayered::_set_images(const TypedArray<Image> &p_images) {
+ ERR_FAIL_COND(_create_from_images(p_images) != OK);
+}
+
Error ImageTextureLayered::create_from_images(Vector<Ref<Image>> p_images) {
int new_layers = p_images.size();
ERR_FAIL_COND_V(new_layers == 0, ERR_INVALID_PARAMETER);
@@ -3014,8 +3018,9 @@ void ImageTextureLayered::_bind_methods() {
ClassDB::bind_method(D_METHOD("update_layer", "image", "layer"), &ImageTextureLayered::update_layer);
ClassDB::bind_method(D_METHOD("_get_images"), &ImageTextureLayered::_get_images);
+ ClassDB::bind_method(D_METHOD("_set_images", "images"), &ImageTextureLayered::_set_images);
- ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_images", PROPERTY_HINT_ARRAY_TYPE, "Image", PROPERTY_USAGE_INTERNAL), "create_from_images", "_get_images");
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_images", PROPERTY_HINT_ARRAY_TYPE, "Image", PROPERTY_USAGE_INTERNAL), "_set_images", "_get_images");
}
ImageTextureLayered::ImageTextureLayered(LayeredType p_layered_type) {
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index 7c4d479da8..50bcec58f6 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -427,6 +427,7 @@ class ImageTextureLayered : public TextureLayered {
Error _create_from_images(const TypedArray<Image> &p_images);
TypedArray<Image> _get_images() const;
+ void _set_images(const TypedArray<Image> &p_images);
protected:
static void _bind_methods();
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index 9f5a64597a..7fdad8e930 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -1709,8 +1709,11 @@ String VisualShaderNodeLinearSceneDepth::generate_code(Shader::Mode p_mode, Visu
code += " {\n";
code += " float __log_depth = textureLod(" + make_unique_id(p_type, p_id, "depth_tex") + ", SCREEN_UV, 0.0).x;\n";
- code += " vec3 __depth_ndc = vec3(SCREEN_UV * 2.0 - 1.0, __log_depth);\n";
- code += " vec4 __depth_view = INV_PROJECTION_MATRIX * vec4(__depth_ndc, 1.0);\n";
+ if (!RenderingServer::get_singleton()->is_low_end()) {
+ code += " vec4 __depth_view = INV_PROJECTION_MATRIX * vec4(SCREEN_UV * 2.0 - 1.0, __log_depth, 1.0);\n";
+ } else {
+ code += " vec4 __depth_view = INV_PROJECTION_MATRIX * vec4(vec3(SCREEN_UV, __log_depth) * 2.0 - 1.0, 1.0);\n";
+ }
code += " __depth_view.xyz /= __depth_view.w;\n";
code += vformat(" %s = -__depth_view.z;\n", p_output_vars[0]);