summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/os/os.cpp31
-rw-r--r--core/variant/array.cpp44
-rw-r--r--core/variant/array.h2
-rw-r--r--core/variant/dictionary.cpp8
-rw-r--r--core/variant/dictionary.h1
-rw-r--r--core/variant/variant_call.cpp3
-rw-r--r--doc/classes/Array.xml45
-rw-r--r--doc/classes/Dictionary.xml8
-rw-r--r--doc/classes/Viewport.xml2
-rw-r--r--doc/classes/VisualShaderNodeFloatFunc.xml2
-rw-r--r--doc/classes/VisualShaderNodeVectorFunc.xml2
-rw-r--r--editor/plugins/path_3d_editor_plugin.cpp45
-rw-r--r--editor/plugins/tiles/tile_data_editors.cpp12
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp8
-rw-r--r--scene/gui/line_edit.cpp16
-rw-r--r--scene/gui/rich_text_label.cpp5
-rw-r--r--scene/main/viewport.cpp16
-rw-r--r--scene/main/viewport.h2
-rw-r--r--scene/resources/visual_shader_nodes.cpp8
-rw-r--r--scene/resources/visual_shader_nodes.h4
20 files changed, 206 insertions, 58 deletions
diff --git a/core/os/os.cpp b/core/os/os.cpp
index 4f7095b0fc..327f1c95f2 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -413,19 +413,29 @@ bool OS::has_feature(const String &p_feature) {
if (sizeof(void *) == 4 && p_feature == "32") {
return true;
}
-#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__)
+#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(_M_X64)
+#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(_M_X64)
if (p_feature == "x86_64") {
return true;
}
-#elif (defined(__i386) || defined(__i386__))
+#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
+ if (p_feature == "x86_32") {
+ return true;
+ }
+#endif
if (p_feature == "x86") {
return true;
}
-#elif defined(__aarch64__)
+#elif defined(__arm__) || defined(__aarch64__) || defined(_M_ARM) || defined(_M_ARM64)
+#if defined(__aarch64__) || defined(_M_ARM64)
if (p_feature == "arm64") {
return true;
}
-#elif defined(__arm__)
+#elif defined(__arm__) || defined(_M_ARM)
+ if (p_feature == "arm32") {
+ return true;
+ }
+#endif
#if defined(__ARM_ARCH_7A__)
if (p_feature == "armv7a" || p_feature == "armv7") {
return true;
@@ -457,6 +467,19 @@ bool OS::has_feature(const String &p_feature) {
if (p_feature == "ppc") {
return true;
}
+#elif defined(__wasm__)
+#if defined(__wasm64__)
+ if (p_feature == "wasm64") {
+ return true;
+ }
+#elif defined(__wasm32__)
+ if (p_feature == "wasm32") {
+ return true;
+ }
+#endif
+ if (p_feature == "wasm") {
+ return true;
+ }
#endif
if (_check_internal_feature_support(p_feature)) {
diff --git a/core/variant/array.cpp b/core/variant/array.cpp
index 7551350c95..b1e142d239 100644
--- a/core/variant/array.cpp
+++ b/core/variant/array.cpp
@@ -501,6 +501,50 @@ Variant Array::reduce(const Callable &p_callable, const Variant &p_accum) const
return ret;
}
+bool Array::any(const Callable &p_callable) const {
+ const Variant *argptrs[1];
+ for (int i = 0; i < size(); i++) {
+ argptrs[0] = &get(i);
+
+ Variant result;
+ Callable::CallError ce;
+ p_callable.call(argptrs, 1, result, ce);
+ if (ce.error != Callable::CallError::CALL_OK) {
+ ERR_FAIL_V_MSG(false, "Error calling method from 'any': " + Variant::get_callable_error_text(p_callable, argptrs, 1, ce));
+ }
+
+ if (result.operator bool()) {
+ // Return as early as possible when one of the conditions is `true`.
+ // This improves performance compared to relying on `filter(...).size() >= 1`.
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool Array::all(const Callable &p_callable) const {
+ const Variant *argptrs[1];
+ for (int i = 0; i < size(); i++) {
+ argptrs[0] = &get(i);
+
+ Variant result;
+ Callable::CallError ce;
+ p_callable.call(argptrs, 1, result, ce);
+ if (ce.error != Callable::CallError::CALL_OK) {
+ ERR_FAIL_V_MSG(false, "Error calling method from 'all': " + Variant::get_callable_error_text(p_callable, argptrs, 1, ce));
+ }
+
+ if (!(result.operator bool())) {
+ // Return as early as possible when one of the inverted conditions is `false`.
+ // This improves performance compared to relying on `filter(...).size() >= array_size().`.
+ return false;
+ }
+ }
+
+ return true;
+}
+
struct _ArrayVariantSort {
_FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const {
bool valid = false;
diff --git a/core/variant/array.h b/core/variant/array.h
index f537700f99..c007376734 100644
--- a/core/variant/array.h
+++ b/core/variant/array.h
@@ -108,6 +108,8 @@ public:
Array filter(const Callable &p_callable) const;
Array map(const Callable &p_callable) const;
Variant reduce(const Callable &p_callable, const Variant &p_accum) const;
+ bool any(const Callable &p_callable) const;
+ bool all(const Callable &p_callable) const;
bool operator<(const Array &p_array) const;
bool operator<=(const Array &p_array) const;
diff --git a/core/variant/dictionary.cpp b/core/variant/dictionary.cpp
index bda8c93a79..822021f440 100644
--- a/core/variant/dictionary.cpp
+++ b/core/variant/dictionary.cpp
@@ -269,6 +269,14 @@ void Dictionary::clear() {
_p->variant_map.clear();
}
+void Dictionary::merge(const Dictionary &p_dictionary, bool p_overwrite) {
+ for (const KeyValue<Variant, Variant> &E : p_dictionary._p->variant_map) {
+ if (p_overwrite || !has(E.key)) {
+ this->operator[](E.key) = E.value;
+ }
+ }
+}
+
void Dictionary::_unref() const {
ERR_FAIL_COND(!_p);
if (_p->refcount.unref()) {
diff --git a/core/variant/dictionary.h b/core/variant/dictionary.h
index 1224a4ff6f..2632893e8d 100644
--- a/core/variant/dictionary.h
+++ b/core/variant/dictionary.h
@@ -62,6 +62,7 @@ public:
int size() const;
bool is_empty() const;
void clear();
+ void merge(const Dictionary &p_dictionary, bool p_overwrite = false);
bool has(const Variant &p_key) const;
bool has_all(const Array &p_keys) const;
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index 6b1868df68..027517f8dc 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -1813,6 +1813,7 @@ static void _register_variant_builtin_methods() {
bind_method(Dictionary, size, sarray(), varray());
bind_method(Dictionary, is_empty, sarray(), varray());
bind_method(Dictionary, clear, sarray(), varray());
+ bind_method(Dictionary, merge, sarray("dictionary", "overwrite"), varray(false));
bind_method(Dictionary, has, sarray("key"), varray());
bind_method(Dictionary, has_all, sarray("keys"), varray());
bind_method(Dictionary, erase, sarray("key"), varray());
@@ -1858,6 +1859,8 @@ static void _register_variant_builtin_methods() {
bind_method(Array, filter, sarray("method"), varray());
bind_method(Array, map, sarray("method"), varray());
bind_method(Array, reduce, sarray("method", "accum"), varray(Variant()));
+ bind_method(Array, any, sarray("method"), varray());
+ bind_method(Array, all, sarray("method"), varray());
bind_method(Array, max, sarray(), varray());
bind_method(Array, min, sarray(), varray());
diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml
index ef4f86f1a9..94181db95f 100644
--- a/doc/classes/Array.xml
+++ b/doc/classes/Array.xml
@@ -123,6 +123,48 @@
</constructor>
</constructors>
<methods>
+ <method name="all" qualifiers="const">
+ <return type="bool" />
+ <argument index="0" name="method" type="Callable" />
+ <description>
+ Calls the provided [Callable] on each element in the array and returns [code]true[/code] if the [Callable] returns [code]true[/code] for [i]all[/i] elements in the array. If the [Callable] returns [code]false[/code] for one array element or more, this method returns [code]false[/code].
+ The callable's method should take one [Variant] parameter (the current array element) and return a boolean value.
+ [codeblock]
+ func _ready():
+ print([6, 10, 6].all(greater_than_5)) # Prints True (3 elements evaluate to `true`).
+ print([4, 10, 4].all(greater_than_5)) # Prints False (1 elements evaluate to `true`).
+ print([4, 4, 4].all(greater_than_5)) # Prints False (0 elements evaluate to `true`).
+
+ print([6, 10, 6].all(func(number): return number &gt; 5)) # Prints True. Same as the first line above, but using lambda function.
+
+ func greater_than_5(number):
+ return number &gt; 5
+ [/codeblock]
+ See also [method any], [method filter], [method map] and [method reduce].
+ [b]Note:[/b] Unlike relying on the size of an array returned by [method filter], this method will return as early as possible to improve performance (especially with large arrays).
+ </description>
+ </method>
+ <method name="any" qualifiers="const">
+ <return type="bool" />
+ <argument index="0" name="method" type="Callable" />
+ <description>
+ Calls the provided [Callable] on each element in the array and returns [code]true[/code] if the [Callable] returns [code]true[/code] for [i]one or more[/i] elements in the array. If the [Callable] returns [code]false[/code] for all elements in the array, this method returns [code]false[/code].
+ The callable's method should take one [Variant] parameter (the current array element) and return a boolean value.
+ [codeblock]
+ func _ready():
+ print([6, 10, 6].any(greater_than_5)) # Prints True (3 elements evaluate to `true`).
+ print([4, 10, 4].any(greater_than_5)) # Prints True (1 elements evaluate to `true`).
+ print([4, 4, 4].any(greater_than_5)) # Prints False (0 elements evaluate to `true`).
+
+ print([6, 10, 6].any(func(number): return number &gt; 5)) # Prints True. Same as the first line above, but using lambda function.
+
+ func greater_than_5(number):
+ return number &gt; 5
+ [/codeblock]
+ See also [method all], [method filter], [method map] and [method reduce].
+ [b]Note:[/b] Unlike relying on the size of an array returned by [method filter], this method will return as early as possible to improve performance (especially with large arrays).
+ </description>
+ </method>
<method name="append">
<return type="void" />
<argument index="0" name="value" type="Variant" />
@@ -232,6 +274,7 @@
func remove_1(number):
return number != 1
[/codeblock]
+ See also [method any], [method all], [method map] and [method reduce].
</description>
</method>
<method name="find" qualifiers="const">
@@ -333,6 +376,7 @@
func negate(number):
return -number
[/codeblock]
+ See also [method filter], [method reduce], [method any] and [method all].
</description>
</method>
<method name="max" qualifiers="const">
@@ -398,6 +442,7 @@
func sum(accum, number):
return accum + number
[/codeblock]
+ See also [method map], [method filter], [method any] and [method all].
</description>
</method>
<method name="remove_at">
diff --git a/doc/classes/Dictionary.xml b/doc/classes/Dictionary.xml
index b46719c758..6f2ad5205c 100644
--- a/doc/classes/Dictionary.xml
+++ b/doc/classes/Dictionary.xml
@@ -291,6 +291,14 @@
Returns the list of keys in the [Dictionary].
</description>
</method>
+ <method name="merge">
+ <return type="void" />
+ <argument index="0" name="dictionary" type="Dictionary" />
+ <argument index="1" name="overwrite" type="bool" default="false" />
+ <description>
+ Adds elements from [code]dictionary[/code] to this [Dictionary]. By default, duplicate keys will not be copied over, unless [code]overwrite[/code] is [code]true[/code].
+ </description>
+ </method>
<method name="size" qualifiers="const">
<return type="int" />
<description>
diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml
index 148c6d7064..def99b8a7a 100644
--- a/doc/classes/Viewport.xml
+++ b/doc/classes/Viewport.xml
@@ -227,7 +227,7 @@
The multisample anti-aliasing mode. A higher number results in smoother edges at the cost of significantly worse performance. A value of 2 or 4 is best unless targeting very high-end systems. See also bilinear scaling 3d [member scaling_3d_mode] for supersampling, which provides higher quality but is much more expensive.
</member>
<member name="own_world_3d" type="bool" setter="set_use_own_world_3d" getter="is_using_own_world_3d" default="false">
- If [code]true[/code], the viewport will use the [World3D] defined in [member world_3d].
+ If [code]true[/code], the viewport will use a unique copy of the [World3D] defined in [member world_3d].
</member>
<member name="physics_object_picking" type="bool" setter="set_physics_object_picking" getter="get_physics_object_picking" default="false">
If [code]true[/code], the objects rendered by viewport become subjects of mouse picking process.
diff --git a/doc/classes/VisualShaderNodeFloatFunc.xml b/doc/classes/VisualShaderNodeFloatFunc.xml
index 0f057b2e6d..1226013c67 100644
--- a/doc/classes/VisualShaderNodeFloatFunc.xml
+++ b/doc/classes/VisualShaderNodeFloatFunc.xml
@@ -65,7 +65,7 @@
<constant name="FUNC_CEIL" value="16" enum="Function">
Finds the nearest integer that is greater than or equal to the parameter. Translates to [code]ceil(x)[/code] in the Godot Shader Language.
</constant>
- <constant name="FUNC_FRAC" value="17" enum="Function">
+ <constant name="FUNC_FRACT" value="17" enum="Function">
Computes the fractional part of the argument. Translates to [code]fract(x)[/code] in the Godot Shader Language.
</constant>
<constant name="FUNC_SATURATE" value="18" enum="Function">
diff --git a/doc/classes/VisualShaderNodeVectorFunc.xml b/doc/classes/VisualShaderNodeVectorFunc.xml
index bc4e12c0b3..7524025f21 100644
--- a/doc/classes/VisualShaderNodeVectorFunc.xml
+++ b/doc/classes/VisualShaderNodeVectorFunc.xml
@@ -68,7 +68,7 @@
<constant name="FUNC_FLOOR" value="17" enum="Function">
Finds the nearest integer less than or equal to the parameter.
</constant>
- <constant name="FUNC_FRAC" value="18" enum="Function">
+ <constant name="FUNC_FRACT" value="18" enum="Function">
Computes the fractional part of the argument.
</constant>
<constant name="FUNC_INVERSE_SQRT" value="19" enum="Function">
diff --git a/editor/plugins/path_3d_editor_plugin.cpp b/editor/plugins/path_3d_editor_plugin.cpp
index 467af8c34b..36f559b2ae 100644
--- a/editor/plugins/path_3d_editor_plugin.cpp
+++ b/editor/plugins/path_3d_editor_plugin.cpp
@@ -37,6 +37,19 @@
#include "node_3d_editor_plugin.h"
#include "scene/resources/curve.h"
+static bool _is_in_handle(int p_id, int p_num_points) {
+ int t = (p_id + 1) % 2;
+ int idx = (p_id + 1) / 2;
+ // order of points is [out_0, out_1, in_1, out_2, in_2, ... out_n-1, in_n-1, in_n]
+ if (idx == 0) {
+ return false;
+ } else if (idx == (p_num_points - 1)) {
+ return true;
+ } else {
+ return (t == 1);
+ }
+}
+
String Path3DGizmo::get_handle_name(int p_id, bool p_secondary) const {
Ref<Curve3D> c = path->get_curve();
if (c.is_null()) {
@@ -47,12 +60,10 @@ String Path3DGizmo::get_handle_name(int p_id, bool p_secondary) const {
return TTR("Curve Point #") + itos(p_id);
}
- p_id += 1; // Account for the first point only having an "out" handle
-
- int idx = p_id / 2;
- int t = p_id % 2;
+ // (p_id + 1) Accounts for the first point only having an "out" handle
+ int idx = (p_id + 1) / 2;
String n = TTR("Curve Point #") + itos(idx);
- if (t == 1) {
+ if (_is_in_handle(p_id, c->get_point_count())) {
n += " In";
} else {
n += " Out";
@@ -72,13 +83,11 @@ Variant Path3DGizmo::get_handle_value(int p_id, bool p_secondary) const {
return original;
}
- p_id += 1; // Account for the first point only having an "out" handle
-
- int idx = p_id / 2;
- int t = p_id % 2;
+ // (p_id + 1) Accounts for the first point only having an "out" handle
+ int idx = (p_id + 1) / 2;
Vector3 ofs;
- if (t == 1) {
+ if (_is_in_handle(p_id, c->get_point_count())) {
ofs = c->get_point_in(idx);
} else {
ofs = c->get_point_out(idx);
@@ -119,10 +128,8 @@ void Path3DGizmo::set_handle(int p_id, bool p_secondary, Camera3D *p_camera, con
return;
}
- p_id += 1; // Account for the first point only having an "out" handle
-
- int idx = p_id / 2;
- int t = p_id % 2;
+ // (p_id + 1) Accounts for the first point only having an "out" handle
+ int idx = (p_id + 1) / 2;
Vector3 base = c->get_point_position(idx);
@@ -144,7 +151,7 @@ void Path3DGizmo::set_handle(int p_id, bool p_secondary, Camera3D *p_camera, con
local.snap(Vector3(snap, snap, snap));
}
- if (t == 1) {
+ if (_is_in_handle(p_id, c->get_point_count())) {
c->set_point_in(idx, local);
if (Path3DEditorPlugin::singleton->mirror_angle_enabled()) {
c->set_point_out(idx, Path3DEditorPlugin::singleton->mirror_length_enabled() ? -local : (-local.normalized() * orig_out_length));
@@ -179,12 +186,10 @@ void Path3DGizmo::commit_handle(int p_id, bool p_secondary, const Variant &p_res
return;
}
- p_id += 1; // Account for the first point only having an "out" handle
-
- int idx = p_id / 2;
- int t = p_id % 2;
+ // (p_id + 1) Accounts for the first point only having an "out" handle
+ int idx = (p_id + 1) / 2;
- if (t == 1) {
+ if (_is_in_handle(p_id, c->get_point_count())) {
if (p_cancel) {
c->set_point_in(p_id, p_restore);
return;
diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp
index 244c718ebe..d035c038d3 100644
--- a/editor/plugins/tiles/tile_data_editors.cpp
+++ b/editor/plugins/tiles/tile_data_editors.cpp
@@ -776,13 +776,13 @@ GenericTilePolygonEditor::GenericTilePolygonEditor() {
button_advanced_menu = memnew(MenuButton);
button_advanced_menu->set_flat(true);
button_advanced_menu->set_toggle_mode(true);
- button_advanced_menu->get_popup()->add_item(TTR("Reset to default tile shape"), RESET_TO_DEFAULT_TILE);
- button_advanced_menu->get_popup()->add_item(TTR("Clear"), CLEAR_TILE);
+ button_advanced_menu->get_popup()->add_item(TTR("Reset to default tile shape"), RESET_TO_DEFAULT_TILE, Key::F);
+ button_advanced_menu->get_popup()->add_item(TTR("Clear"), CLEAR_TILE, Key::C);
button_advanced_menu->get_popup()->add_separator();
- button_advanced_menu->get_popup()->add_icon_item(get_theme_icon(SNAME("RotateRight"), SNAME("EditorIcons")), TTR("Rotate Right"), ROTATE_RIGHT);
- button_advanced_menu->get_popup()->add_icon_item(get_theme_icon(SNAME("RotateLeft"), SNAME("EditorIcons")), TTR("Rotate Left"), ROTATE_LEFT);
- button_advanced_menu->get_popup()->add_icon_item(get_theme_icon(SNAME("MirrorX"), SNAME("EditorIcons")), TTR("Flip Horizontally"), FLIP_HORIZONTALLY);
- button_advanced_menu->get_popup()->add_icon_item(get_theme_icon(SNAME("MirrorY"), SNAME("EditorIcons")), TTR("Flip Vertically"), FLIP_VERTICALLY);
+ button_advanced_menu->get_popup()->add_icon_item(get_theme_icon(SNAME("RotateRight"), SNAME("EditorIcons")), TTR("Rotate Right"), ROTATE_RIGHT, Key::R);
+ button_advanced_menu->get_popup()->add_icon_item(get_theme_icon(SNAME("RotateLeft"), SNAME("EditorIcons")), TTR("Rotate Left"), ROTATE_LEFT, Key::E);
+ button_advanced_menu->get_popup()->add_icon_item(get_theme_icon(SNAME("MirrorX"), SNAME("EditorIcons")), TTR("Flip Horizontally"), FLIP_HORIZONTALLY, Key::H);
+ button_advanced_menu->get_popup()->add_icon_item(get_theme_icon(SNAME("MirrorY"), SNAME("EditorIcons")), TTR("Flip Vertically"), FLIP_VERTICALLY, Key::V);
button_advanced_menu->get_popup()->connect("id_pressed", callable_mp(this, &GenericTilePolygonEditor::_advanced_menu_item_pressed));
button_advanced_menu->set_focus_mode(FOCUS_ALL);
toolbar->add_child(button_advanced_menu);
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 642973648e..19cd354eaf 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -5329,7 +5329,7 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Exp", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Base-e Exponential."), { VisualShaderNodeFloatFunc::FUNC_EXP }, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Exp2", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Base-2 Exponential."), { VisualShaderNodeFloatFunc::FUNC_EXP2 }, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Floor", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Finds the nearest integer less than or equal to the parameter."), { VisualShaderNodeFloatFunc::FUNC_FLOOR }, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Fract", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Computes the fractional part of the argument."), { VisualShaderNodeFloatFunc::FUNC_FRAC }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Fract", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Computes the fractional part of the argument."), { VisualShaderNodeFloatFunc::FUNC_FRACT }, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("InverseSqrt", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the inverse of the square root of the parameter."), { VisualShaderNodeFloatFunc::FUNC_INVERSE_SQRT }, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Log", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Natural logarithm."), { VisualShaderNodeFloatFunc::FUNC_LOG }, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Log2", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Base-2 logarithm."), { VisualShaderNodeFloatFunc::FUNC_LOG2 }, VisualShaderNode::PORT_TYPE_SCALAR));
@@ -5513,9 +5513,9 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Floor", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer less than or equal to the parameter."), { VisualShaderNodeVectorFunc::FUNC_FLOOR, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
add_options.push_back(AddOption("Floor", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer less than or equal to the parameter."), { VisualShaderNodeVectorFunc::FUNC_FLOOR, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Floor", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer less than or equal to the parameter."), { VisualShaderNodeVectorFunc::FUNC_FLOOR, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D));
- add_options.push_back(AddOption("Fract", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Computes the fractional part of the argument."), { VisualShaderNodeVectorFunc::FUNC_FRAC, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Fract", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Computes the fractional part of the argument."), { VisualShaderNodeVectorFunc::FUNC_FRAC, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
- add_options.push_back(AddOption("Fract", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Computes the fractional part of the argument."), { VisualShaderNodeVectorFunc::FUNC_FRAC, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D));
+ add_options.push_back(AddOption("Fract", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Computes the fractional part of the argument."), { VisualShaderNodeVectorFunc::FUNC_FRACT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Fract", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Computes the fractional part of the argument."), { VisualShaderNodeVectorFunc::FUNC_FRACT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
+ add_options.push_back(AddOption("Fract", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Computes the fractional part of the argument."), { VisualShaderNodeVectorFunc::FUNC_FRACT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D));
add_options.push_back(AddOption("Fresnel", "Vector", "Functions", "VisualShaderNodeFresnel", TTR("Returns falloff based on the dot product of surface normal and view direction of camera (pass associated inputs to it)."), {}, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("InverseSqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse of the square root of the parameter."), { VisualShaderNodeVectorFunc::FUNC_INVERSE_SQRT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
add_options.push_back(AddOption("InverseSqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse of the square root of the parameter."), { VisualShaderNodeVectorFunc::FUNC_INVERSE_SQRT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index fd9db4ea1b..fa600d24ef 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -1686,13 +1686,17 @@ Size2 LineEdit::get_minimum_size() const {
min_size.height = MAX(TS->shaped_text_get_size(text_rid).y + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM), font->get_height(font_size));
// Take icons into account.
- bool using_placeholder = text.is_empty() && ime_text.is_empty();
- bool display_clear_icon = !using_placeholder && is_editable() && clear_button_enabled;
- if (right_icon.is_valid() || display_clear_icon) {
- Ref<Texture2D> r_icon = display_clear_icon ? Control::get_theme_icon(SNAME("clear")) : right_icon;
- min_size.width += r_icon->get_width();
- min_size.height = MAX(min_size.height, r_icon->get_height());
+ int icon_max_width = 0;
+ if (right_icon.is_valid()) {
+ min_size.height = MAX(min_size.height, right_icon->get_height());
+ icon_max_width = right_icon->get_width();
+ }
+ if (clear_button_enabled) {
+ Ref<Texture2D> clear_icon = Control::get_theme_icon(SNAME("clear"));
+ min_size.height = MAX(min_size.height, clear_icon->get_height());
+ icon_max_width = MAX(icon_max_width, clear_icon->get_width());
}
+ min_size.width += icon_max_width;
return style->get_minimum_size() + min_size;
}
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 0a35b8ecc8..cf7bf930a5 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -1613,6 +1613,7 @@ void RichTextLabel::_notification(int p_what) {
update();
} break;
+ case NOTIFICATION_PREDELETE:
case NOTIFICATION_EXIT_TREE: {
_stop_thread();
} break;
@@ -2555,6 +2556,10 @@ bool RichTextLabel::_validate_line_caches() {
void RichTextLabel::_process_line_caches() {
// Shape invalid lines.
+ if (!is_inside_tree()) {
+ return;
+ }
+
MutexLock data_lock(data_mutex);
Rect2 text_rect = _get_text_rect();
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 590c73de0b..7c7809fd75 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -3458,8 +3458,8 @@ void Viewport::_own_world_3d_changed() {
_update_audio_listener_3d();
}
-void Viewport::set_use_own_world_3d(bool p_world_3d) {
- if (p_world_3d == own_world_3d.is_valid()) {
+void Viewport::set_use_own_world_3d(bool p_use_own_world_3d) {
+ if (p_use_own_world_3d == own_world_3d.is_valid()) {
return;
}
@@ -3467,18 +3467,18 @@ void Viewport::set_use_own_world_3d(bool p_world_3d) {
_propagate_exit_world_3d(this);
}
- if (!p_world_3d) {
- own_world_3d = Ref<World3D>();
- if (world_3d.is_valid()) {
- world_3d->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Viewport::_own_world_3d_changed));
- }
- } else {
+ if (p_use_own_world_3d) {
if (world_3d.is_valid()) {
own_world_3d = world_3d->duplicate();
world_3d->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Viewport::_own_world_3d_changed));
} else {
own_world_3d = Ref<World3D>(memnew(World3D));
}
+ } else {
+ own_world_3d = Ref<World3D>();
+ if (world_3d.is_valid()) {
+ world_3d->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Viewport::_own_world_3d_changed));
+ }
}
if (is_inside_tree()) {
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 5bca5a2dda..833b302e97 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -676,7 +676,7 @@ public:
Ref<World3D> get_world_3d() const;
Ref<World3D> find_world_3d() const;
void _own_world_3d_changed();
- void set_use_own_world_3d(bool p_world_3d);
+ void set_use_own_world_3d(bool p_use_own_world_3d);
bool is_using_own_world_3d() const;
void _propagate_enter_world_3d(Node *p_node);
void _propagate_exit_world_3d(Node *p_node);
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index 5c0f36ca92..b8667f07fe 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -2462,7 +2462,7 @@ void VisualShaderNodeFloatFunc::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeFloatFunc::set_function);
ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeFloatFunc::get_function);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Sin,Cos,Tan,ASin,ACos,ATan,SinH,CosH,TanH,Log,Exp,Sqrt,Abs,Sign,Floor,Round,Ceil,Frac,Saturate,Negate,ACosH,ASinH,ATanH,Degrees,Exp2,InverseSqrt,Log2,Radians,Reciprocal,RoundEven,Trunc,OneMinus"), "set_function", "get_function");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Sin,Cos,Tan,ASin,ACos,ATan,SinH,CosH,TanH,Log,Exp,Sqrt,Abs,Sign,Floor,Round,Ceil,Fract,Saturate,Negate,ACosH,ASinH,ATanH,Degrees,Exp2,InverseSqrt,Log2,Radians,Reciprocal,RoundEven,Trunc,OneMinus"), "set_function", "get_function");
BIND_ENUM_CONSTANT(FUNC_SIN);
BIND_ENUM_CONSTANT(FUNC_COS);
@@ -2481,7 +2481,7 @@ void VisualShaderNodeFloatFunc::_bind_methods() {
BIND_ENUM_CONSTANT(FUNC_FLOOR);
BIND_ENUM_CONSTANT(FUNC_ROUND);
BIND_ENUM_CONSTANT(FUNC_CEIL);
- BIND_ENUM_CONSTANT(FUNC_FRAC);
+ BIND_ENUM_CONSTANT(FUNC_FRACT);
BIND_ENUM_CONSTANT(FUNC_SATURATE);
BIND_ENUM_CONSTANT(FUNC_NEGATE);
BIND_ENUM_CONSTANT(FUNC_ACOSH);
@@ -2713,7 +2713,7 @@ void VisualShaderNodeVectorFunc::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeVectorFunc::set_function);
ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeVectorFunc::get_function);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Normalize,Saturate,Negate,Reciprocal,Abs,ACos,ACosH,ASin,ASinH,ATan,ATanH,Ceil,Cos,CosH,Degrees,Exp,Exp2,Floor,Frac,InverseSqrt,Log,Log2,Radians,Round,RoundEven,Sign,Sin,SinH,Sqrt,Tan,TanH,Trunc,OneMinus"), "set_function", "get_function");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Normalize,Saturate,Negate,Reciprocal,Abs,ACos,ACosH,ASin,ASinH,ATan,ATanH,Ceil,Cos,CosH,Degrees,Exp,Exp2,Floor,Fract,InverseSqrt,Log,Log2,Radians,Round,RoundEven,Sign,Sin,SinH,Sqrt,Tan,TanH,Trunc,OneMinus"), "set_function", "get_function");
BIND_ENUM_CONSTANT(FUNC_NORMALIZE);
BIND_ENUM_CONSTANT(FUNC_SATURATE);
@@ -2733,7 +2733,7 @@ void VisualShaderNodeVectorFunc::_bind_methods() {
BIND_ENUM_CONSTANT(FUNC_EXP);
BIND_ENUM_CONSTANT(FUNC_EXP2);
BIND_ENUM_CONSTANT(FUNC_FLOOR);
- BIND_ENUM_CONSTANT(FUNC_FRAC);
+ BIND_ENUM_CONSTANT(FUNC_FRACT);
BIND_ENUM_CONSTANT(FUNC_INVERSE_SQRT);
BIND_ENUM_CONSTANT(FUNC_LOG);
BIND_ENUM_CONSTANT(FUNC_LOG2);
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
index b159d25eba..1eb7b7240f 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -934,7 +934,7 @@ public:
FUNC_FLOOR,
FUNC_ROUND,
FUNC_CEIL,
- FUNC_FRAC,
+ FUNC_FRACT,
FUNC_SATURATE,
FUNC_NEGATE,
FUNC_ACOSH,
@@ -1053,7 +1053,7 @@ public:
FUNC_EXP,
FUNC_EXP2,
FUNC_FLOOR,
- FUNC_FRAC,
+ FUNC_FRACT,
FUNC_INVERSE_SQRT,
FUNC_LOG,
FUNC_LOG2,