diff options
254 files changed, 2448 insertions, 1545 deletions
diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp index 9d5d84a508..46f07fe041 100644 --- a/core/input/input_event.cpp +++ b/core/input/input_event.cpp @@ -33,6 +33,7 @@ #include "core/input/input_map.h" #include "core/input/shortcut.h" #include "core/os/keyboard.h" +#include "core/os/os.h" const int InputEvent::DEVICE_ID_EMULATION = -1; const int InputEvent::DEVICE_ID_INTERNAL = -2; @@ -145,13 +146,13 @@ int64_t InputEventFromWindow::get_window_id() const { void InputEventWithModifiers::set_command_or_control_autoremap(bool p_enabled) { command_or_control_autoremap = p_enabled; if (command_or_control_autoremap) { -#ifdef MACOS_ENABLED - ctrl_pressed = false; - meta_pressed = true; -#else - ctrl_pressed = true; - meta_pressed = false; -#endif + if (OS::get_singleton()->has_feature("macos") || OS::get_singleton()->has_feature("web_macos") || OS::get_singleton()->has_feature("web_ios")) { + ctrl_pressed = false; + meta_pressed = true; + } else { + ctrl_pressed = true; + meta_pressed = false; + } } else { ctrl_pressed = false; meta_pressed = false; @@ -164,11 +165,11 @@ bool InputEventWithModifiers::is_command_or_control_autoremap() const { } bool InputEventWithModifiers::is_command_or_control_pressed() const { -#ifdef MACOS_ENABLED - return meta_pressed; -#else - return ctrl_pressed; -#endif + if (OS::get_singleton()->has_feature("macos") || OS::get_singleton()->has_feature("web_macos") || OS::get_singleton()->has_feature("web_ios")) { + return meta_pressed; + } else { + return ctrl_pressed; + } } void InputEventWithModifiers::set_shift_pressed(bool p_enabled) { @@ -231,11 +232,11 @@ BitField<KeyModifierMask> InputEventWithModifiers::get_modifiers_mask() const { mask.set_flag(KeyModifierMask::META); } if (is_command_or_control_autoremap()) { -#ifdef MACOS_ENABLED - mask.set_flag(KeyModifierMask::META); -#else - mask.set_flag(KeyModifierMask::CTRL); -#endif + if (OS::get_singleton()->has_feature("macos") || OS::get_singleton()->has_feature("web_macos") || OS::get_singleton()->has_feature("web_ios")) { + mask.set_flag(KeyModifierMask::META); + } else { + mask.set_flag(KeyModifierMask::CTRL); + } } return mask; } diff --git a/core/math/delaunay_2d.h b/core/math/delaunay_2d.h index 8d602da241..cf7ba8d48e 100644 --- a/core/math/delaunay_2d.h +++ b/core/math/delaunay_2d.h @@ -38,7 +38,8 @@ class Delaunay2D { public: struct Triangle { int points[3]; - bool bad = false; + Vector2 circum_center; + real_t circum_radius_squared; Triangle() {} Triangle(int p_a, int p_b, int p_c) { points[0] = p_a; @@ -48,117 +49,109 @@ public: }; struct Edge { - int edge[2]; + int points[2]; bool bad = false; Edge() {} Edge(int p_a, int p_b) { - edge[0] = p_a; - edge[1] = p_b; + // Store indices in a sorted manner to avoid having to check both orientations later. + if (p_a > p_b) { + points[0] = p_b; + points[1] = p_a; + } else { + points[0] = p_a; + points[1] = p_b; + } } }; - static bool circum_circle_contains(const Vector<Vector2> &p_vertices, const Triangle &p_triangle, int p_vertex) { - Vector2 p1 = p_vertices[p_triangle.points[0]]; - Vector2 p2 = p_vertices[p_triangle.points[1]]; - Vector2 p3 = p_vertices[p_triangle.points[2]]; + static Triangle create_triangle(const Vector<Vector2> &p_vertices, const int &p_a, const int &p_b, const int &p_c) { + Triangle triangle = Triangle(p_a, p_b, p_c); - real_t ab = p1.x * p1.x + p1.y * p1.y; - real_t cd = p2.x * p2.x + p2.y * p2.y; - real_t ef = p3.x * p3.x + p3.y * p3.y; + // Get the values of the circumcircle and store them inside the triangle object. + Vector2 a = p_vertices[p_b] - p_vertices[p_a]; + Vector2 b = p_vertices[p_c] - p_vertices[p_a]; - Vector2 circum( - (ab * (p3.y - p2.y) + cd * (p1.y - p3.y) + ef * (p2.y - p1.y)) / (p1.x * (p3.y - p2.y) + p2.x * (p1.y - p3.y) + p3.x * (p2.y - p1.y)), - (ab * (p3.x - p2.x) + cd * (p1.x - p3.x) + ef * (p2.x - p1.x)) / (p1.y * (p3.x - p2.x) + p2.y * (p1.x - p3.x) + p3.y * (p2.x - p1.x))); + Vector2 O = (b * a.length_squared() - a * b.length_squared()).orthogonal() / (a.cross(b) * 2.0f); - circum *= 0.5; - float r = p1.distance_squared_to(circum); - float d = p_vertices[p_vertex].distance_squared_to(circum); - return d <= r; - } + triangle.circum_radius_squared = O.length_squared(); + triangle.circum_center = O + p_vertices[p_a]; - static bool edge_compare(const Vector<Vector2> &p_vertices, const Edge &p_a, const Edge &p_b) { - if (p_vertices[p_a.edge[0]].is_equal_approx(p_vertices[p_b.edge[0]]) && p_vertices[p_a.edge[1]].is_equal_approx(p_vertices[p_b.edge[1]])) { - return true; - } - - if (p_vertices[p_a.edge[0]].is_equal_approx(p_vertices[p_b.edge[1]]) && p_vertices[p_a.edge[1]].is_equal_approx(p_vertices[p_b.edge[0]])) { - return true; - } - - return false; + return triangle; } static Vector<Triangle> triangulate(const Vector<Vector2> &p_points) { Vector<Vector2> points = p_points; Vector<Triangle> triangles; - Rect2 rect; - for (int i = 0; i < p_points.size(); i++) { - if (i == 0) { - rect.position = p_points[i]; - } else { - rect.expand_to(p_points[i]); - } + int point_count = p_points.size(); + if (point_count <= 2) { + return triangles; } - float delta_max = MAX(rect.size.width, rect.size.height); + // Get a bounding rectangle. + Rect2 rect = Rect2(p_points[0], Size2()); + for (int i = 1; i < point_count; i++) { + rect.expand_to(p_points[i]); + } + + real_t delta_max = MAX(rect.size.width, rect.size.height); Vector2 center = rect.get_center(); - points.push_back(Vector2(center.x - 20 * delta_max, center.y - delta_max)); - points.push_back(Vector2(center.x, center.y + 20 * delta_max)); - points.push_back(Vector2(center.x + 20 * delta_max, center.y - delta_max)); + // Construct a bounding triangle around the rectangle. + points.push_back(Vector2(center.x - delta_max * 16, center.y - delta_max)); + points.push_back(Vector2(center.x, center.y + delta_max * 16)); + points.push_back(Vector2(center.x + delta_max * 16, center.y - delta_max)); - triangles.push_back(Triangle(p_points.size() + 0, p_points.size() + 1, p_points.size() + 2)); + Triangle bounding_triangle = create_triangle(points, point_count + 0, point_count + 1, point_count + 2); + triangles.push_back(bounding_triangle); - for (int i = 0; i < p_points.size(); i++) { + for (int i = 0; i < point_count; i++) { Vector<Edge> polygon; - for (int j = 0; j < triangles.size(); j++) { - if (circum_circle_contains(points, triangles[j], i)) { - triangles.write[j].bad = true; + // Save the edges of the triangles whose circumcircles contain the i-th vertex. Delete the triangles themselves. + for (int j = triangles.size() - 1; j >= 0; j--) { + if (points[i].distance_squared_to(triangles[j].circum_center) < triangles[j].circum_radius_squared) { polygon.push_back(Edge(triangles[j].points[0], triangles[j].points[1])); polygon.push_back(Edge(triangles[j].points[1], triangles[j].points[2])); polygon.push_back(Edge(triangles[j].points[2], triangles[j].points[0])); - } - } - for (int j = 0; j < triangles.size(); j++) { - if (triangles[j].bad) { triangles.remove_at(j); - j--; } } + // Create a triangle for every unique edge. for (int j = 0; j < polygon.size(); j++) { + if (polygon[j].bad) { + continue; + } + for (int k = j + 1; k < polygon.size(); k++) { - if (edge_compare(points, polygon[j], polygon[k])) { + // Compare the edges. + if (polygon[k].points[0] == polygon[j].points[0] && polygon[k].points[1] == polygon[j].points[1]) { polygon.write[j].bad = true; polygon.write[k].bad = true; + + break; // Since no more than two triangles can share an edge, no more than two edges can share vertices. } } - } - for (int j = 0; j < polygon.size(); j++) { - if (polygon[j].bad) { - continue; + // Create triangles out of good edges. + if (!polygon[j].bad) { + triangles.push_back(create_triangle(points, polygon[j].points[0], polygon[j].points[1], i)); } - triangles.push_back(Triangle(polygon[j].edge[0], polygon[j].edge[1], i)); } } - for (int i = 0; i < triangles.size(); i++) { - bool invalid = false; - for (int j = 0; j < 3; j++) { - if (triangles[i].points[j] >= p_points.size()) { - invalid = true; - break; - } - } - if (invalid) { - triangles.remove_at(i); - i--; + // Filter out the triangles containing vertices of the bounding triangle. + int preserved_count = 0; + Triangle *triangles_ptrw = triangles.ptrw(); + for (int i = 0; i < triangles.size() - 1; i++) { + if (!(triangles[i].points[0] >= point_count || triangles[i].points[1] >= point_count || triangles[i].points[2] >= point_count)) { + triangles_ptrw[preserved_count] = triangles[i]; + preserved_count++; } } + triangles.resize(preserved_count); return triangles; } diff --git a/core/object/message_queue.cpp b/core/object/message_queue.cpp index decf030e27..1542decc6f 100644 --- a/core/object/message_queue.cpp +++ b/core/object/message_queue.cpp @@ -55,7 +55,7 @@ Error MessageQueue::push_set(ObjectID p_id, const StringName &p_prop, const Vari if (ObjectDB::get_instance(p_id)) { type = ObjectDB::get_instance(p_id)->get_class(); } - ERR_PRINT("Failed set: " + type + ":" + p_prop + " target ID: " + itos(p_id) + ". Message queue out of memory. Try increasing 'memory/limits/message_queue/max_size_kb' in project settings."); + ERR_PRINT("Failed set: " + type + ":" + p_prop + " target ID: " + itos(p_id) + ". Message queue out of memory. Try increasing \"memory/limits/message_queue/max_size_kb\" in project settings."); statistics(); return ERR_OUT_OF_MEMORY; } @@ -82,7 +82,7 @@ Error MessageQueue::push_notification(ObjectID p_id, int p_notification) { uint8_t room_needed = sizeof(Message); if ((buffer_end + room_needed) >= buffer_size) { - ERR_PRINT("Failed notification: " + itos(p_notification) + " target ID: " + itos(p_id) + ". Message queue out of memory. Try increasing 'memory/limits/message_queue/max_size_kb' in project settings."); + ERR_PRINT("Failed notification: " + itos(p_notification) + " target ID: " + itos(p_id) + ". Message queue out of memory. Try increasing \"memory/limits/message_queue/max_size_kb\" in project settings."); statistics(); return ERR_OUT_OF_MEMORY; } @@ -117,7 +117,7 @@ Error MessageQueue::push_callablep(const Callable &p_callable, const Variant **p int room_needed = sizeof(Message) + sizeof(Variant) * p_argcount; if ((buffer_end + room_needed) >= buffer_size) { - ERR_PRINT("Failed method: " + p_callable + ". Message queue out of memory. Try increasing 'memory/limits/message_queue/max_size_kb' in project settings."); + ERR_PRINT("Failed method: " + p_callable + ". Message queue out of memory. Try increasing \"memory/limits/message_queue/max_size_kb\" in project settings."); statistics(); return ERR_OUT_OF_MEMORY; } diff --git a/core/object/object.cpp b/core/object/object.cpp index c324eab9bb..39cae7c5bd 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -195,14 +195,15 @@ bool Object::_predelete() { _predelete_ok = 1; notification(NOTIFICATION_PREDELETE, true); if (_predelete_ok) { - _class_ptr = nullptr; //must restore so destructors can access class ptr correctly + _class_name_ptr = nullptr; // Must restore, so constructors/destructors have proper class name access at each stage. } return _predelete_ok; } void Object::_postinitialize() { - _class_ptr = _get_class_namev(); + _class_name_ptr = _get_class_namev(); // Set the direct pointer, which is much faster to obtain, but can only happen after postinitialize. _initialize_classv(); + _class_name_ptr = nullptr; // May have been called from a constructor. notification(NOTIFICATION_POSTINITIALIZE); } diff --git a/core/object/object.h b/core/object/object.h index 5ec69a371b..4226b5e67b 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -376,7 +376,6 @@ private: #define GDCLASS(m_class, m_inherits) \ private: \ void operator=(const m_class &p_rval) {} \ - mutable StringName _class_name; \ friend class ::ClassDB; \ \ public: \ @@ -388,13 +387,11 @@ public: return String(#m_class); \ } \ virtual const StringName *_get_class_namev() const override { \ - if (_get_extension()) { \ - return &_get_extension()->class_name; \ - } \ - if (!_class_name) { \ - _class_name = get_class_static(); \ + static StringName _class_name_static; \ + if (unlikely(!_class_name_static)) { \ + StringName::assign_static_unique_class_name(&_class_name_static, #m_class); \ } \ - return &_class_name; \ + return &_class_name_static; \ } \ static _FORCE_INLINE_ void *get_class_ptr_static() { \ static int ptr; \ @@ -614,8 +611,7 @@ private: Variant script; // Reference does not exist yet, store it in a Variant. HashMap<StringName, Variant> metadata; HashMap<StringName, Variant *> metadata_properties; - mutable StringName _class_name; - mutable const StringName *_class_ptr = nullptr; + mutable const StringName *_class_name_ptr = nullptr; void _add_user_signal(const String &p_name, const Array &p_args = Array()); bool _has_user_signal(const StringName &p_name) const; @@ -714,10 +710,11 @@ protected: Variant _call_deferred_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); virtual const StringName *_get_class_namev() const { - if (!_class_name) { - _class_name = get_class_static(); + static StringName _class_name_static; + if (unlikely(!_class_name_static)) { + StringName::assign_static_unique_class_name(&_class_name_static, "Object"); } - return &_class_name; + return &_class_name_static; } Vector<StringName> _get_meta_list_bind() const; @@ -788,13 +785,16 @@ public: _FORCE_INLINE_ const StringName &get_class_name() const { if (_extension) { + // Can't put inside the unlikely as constructor can run it return _extension->class_name; } - if (!_class_ptr) { + + if (unlikely(!_class_name_ptr)) { + // While class is initializing / deinitializing, constructors and destructurs + // need access to the proper class at the proper stage. return *_get_class_namev(); - } else { - return *_class_ptr; } + return *_class_name_ptr; } /* IAPI */ diff --git a/core/os/keyboard.cpp b/core/os/keyboard.cpp index 25a4b320cd..1e32e6e096 100644 --- a/core/os/keyboard.cpp +++ b/core/os/keyboard.cpp @@ -367,11 +367,11 @@ String keycode_get_string(Key p_code) { codestr += "+"; } if ((p_code & KeyModifierMask::CMD_OR_CTRL) != Key::NONE) { -#ifdef MACOS_ENABLED - codestr += find_keycode_name(Key::META); -#else - codestr += find_keycode_name(Key::CTRL); -#endif + if (OS::get_singleton()->has_feature("macos") || OS::get_singleton()->has_feature("web_macos") || OS::get_singleton()->has_feature("web_ios")) { + codestr += find_keycode_name(Key::META); + } else { + codestr += find_keycode_name(Key::CTRL); + } codestr += "+"; } if ((p_code & KeyModifierMask::CTRL) != Key::NONE) { diff --git a/core/string/string_name.cpp b/core/string/string_name.cpp index df9b6b3f1a..6099fea13f 100644 --- a/core/string/string_name.cpp +++ b/core/string/string_name.cpp @@ -201,6 +201,14 @@ StringName::StringName(const StringName &p_name) { } } +void StringName::assign_static_unique_class_name(StringName *ptr, const char *p_name) { + mutex.lock(); + if (*ptr == StringName()) { + *ptr = StringName(p_name, true); + } + mutex.unlock(); +} + StringName::StringName(const char *p_name, bool p_static) { _data = nullptr; diff --git a/core/string/string_name.h b/core/string/string_name.h index 177e82896d..07abc781a2 100644 --- a/core/string/string_name.h +++ b/core/string/string_name.h @@ -177,6 +177,8 @@ public: StringName(const String &p_name, bool p_static = false); StringName(const StaticCString &p_static_string, bool p_static = false); StringName() {} + + static void assign_static_unique_class_name(StringName *ptr, const char *p_name); _FORCE_INLINE_ ~StringName() { if (likely(configured) && _data) { //only free if configured unref(); diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index 773445edb6..73b5bc2d56 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -2593,6 +2593,23 @@ double String::to_float(const wchar_t *p_str, const wchar_t **r_end) { return built_in_strtod<wchar_t>(p_str, (wchar_t **)r_end); } +uint32_t String::num_characters(int64_t p_int) { + int r = 1; + if (p_int < 0) { + r += 1; + if (p_int == INT64_MIN) { + p_int = INT64_MAX; + } else { + p_int = -p_int; + } + } + while (p_int >= 10) { + p_int /= 10; + r++; + } + return r; +} + int64_t String::to_int(const char32_t *p_str, int p_len, bool p_clamp) { if (p_len == 0 || !p_str[0]) { return 0; @@ -4561,15 +4578,65 @@ String String::property_name_encode() const { } // Changes made to the set of invalid characters must also be reflected in the String documentation. -const String String::invalid_node_name_characters = ". : @ / \" " UNIQUE_NODE_PREFIX; + +static const char32_t invalid_node_name_characters[] = { '.', ':', '@', '/', '\"', UNIQUE_NODE_PREFIX[0], 0 }; + +String String::get_invalid_node_name_characters() { + // Do not use this function for critical validation. + String r; + const char32_t *c = invalid_node_name_characters; + while (*c) { + if (c != invalid_node_name_characters) { + r += " "; + } + r += String::chr(*c); + c++; + } + return r; +} String String::validate_node_name() const { - Vector<String> chars = String::invalid_node_name_characters.split(" "); - String name = this->replace(chars[0], ""); - for (int i = 1; i < chars.size(); i++) { - name = name.replace(chars[i], ""); + // This is a critical validation in node addition, so it must be optimized. + const char32_t *cn = ptr(); + if (cn == nullptr) { + return String(); } - return name; + bool valid = true; + uint32_t idx = 0; + while (cn[idx]) { + const char32_t *c = invalid_node_name_characters; + while (*c) { + if (cn[idx] == *c) { + valid = false; + break; + } + c++; + } + if (!valid) { + break; + } + idx++; + } + + if (valid) { + return *this; + } + + String validated = *this; + char32_t *nn = validated.ptrw(); + while (nn[idx]) { + const char32_t *c = invalid_node_name_characters; + while (*c) { + if (nn[idx] == *c) { + nn[idx] = '_'; + break; + } + c++; + } + idx++; + } + + return validated; } String String::get_basename() const { diff --git a/core/string/ustring.h b/core/string/ustring.h index 90034b1b07..e1512cfb26 100644 --- a/core/string/ustring.h +++ b/core/string/ustring.h @@ -337,6 +337,7 @@ public: static double to_float(const char *p_str); static double to_float(const wchar_t *p_str, const wchar_t **r_end = nullptr); static double to_float(const char32_t *p_str, const char32_t **r_end = nullptr); + static uint32_t num_characters(int64_t p_int); String capitalize() const; String to_camel_case() const; @@ -432,7 +433,7 @@ public: String property_name_encode() const; // node functions - static const String invalid_node_name_characters; + static String get_invalid_node_name_characters(); String validate_node_name() const; String validate_identifier() const; String validate_filename() const; diff --git a/doc/classes/AESContext.xml b/doc/classes/AESContext.xml index 110c50cf0f..aa205ef32a 100644 --- a/doc/classes/AESContext.xml +++ b/doc/classes/AESContext.xml @@ -15,27 +15,27 @@ var key = "My secret key!!!" # Key must be either 16 or 32 bytes. var data = "My secret text!!" # Data size must be multiple of 16 bytes, apply padding if needed. # Encrypt ECB - aes.start(AESContext.MODE_ECB_ENCRYPT, key.to_utf8()) - var encrypted = aes.update(data.to_utf8()) + aes.start(AESContext.MODE_ECB_ENCRYPT, key.to_utf8_buffer()) + var encrypted = aes.update(data.to_utf8_buffer()) aes.finish() # Decrypt ECB - aes.start(AESContext.MODE_ECB_DECRYPT, key.to_utf8()) + aes.start(AESContext.MODE_ECB_DECRYPT, key.to_utf8_buffer()) var decrypted = aes.update(encrypted) aes.finish() # Check ECB - assert(decrypted == data.to_utf8()) + assert(decrypted == data.to_utf8_buffer()) var iv = "My secret iv!!!!" # IV must be of exactly 16 bytes. # Encrypt CBC - aes.start(AESContext.MODE_CBC_ENCRYPT, key.to_utf8(), iv.to_utf8()) - encrypted = aes.update(data.to_utf8()) + aes.start(AESContext.MODE_CBC_ENCRYPT, key.to_utf8_buffer(), iv.to_utf8_buffer()) + encrypted = aes.update(data.to_utf8_buffer()) aes.finish() # Decrypt CBC - aes.start(AESContext.MODE_CBC_DECRYPT, key.to_utf8(), iv.to_utf8()) + aes.start(AESContext.MODE_CBC_DECRYPT, key.to_utf8_buffer(), iv.to_utf8_buffer()) decrypted = aes.update(encrypted) aes.finish() # Check CBC - assert(decrypted == data.to_utf8()) + assert(decrypted == data.to_utf8_buffer()) [/gdscript] [csharp] using Godot; @@ -50,27 +50,27 @@ string key = "My secret key!!!"; // Key must be either 16 or 32 bytes. string data = "My secret text!!"; // Data size must be multiple of 16 bytes, apply padding if needed. // Encrypt ECB - _aes.Start(AesContext.Mode.EcbEncrypt, key.ToUtf8()); - byte[] encrypted = _aes.Update(data.ToUtf8()); + _aes.Start(AesContext.Mode.EcbEncrypt, key.ToUtf8Buffer()); + byte[] encrypted = _aes.Update(data.ToUtf8Buffer()); _aes.Finish(); // Decrypt ECB - _aes.Start(AesContext.Mode.EcbDecrypt, key.ToUtf8()); + _aes.Start(AesContext.Mode.EcbDecrypt, key.ToUtf8Buffer()); byte[] decrypted = _aes.Update(encrypted); _aes.Finish(); // Check ECB - Debug.Assert(decrypted == data.ToUtf8()); + Debug.Assert(decrypted == data.ToUtf8Buffer()); string iv = "My secret iv!!!!"; // IV must be of exactly 16 bytes. // Encrypt CBC - _aes.Start(AesContext.Mode.EcbEncrypt, key.ToUtf8(), iv.ToUtf8()); - encrypted = _aes.Update(data.ToUtf8()); + _aes.Start(AesContext.Mode.EcbEncrypt, key.ToUtf8Buffer(), iv.ToUtf8Buffer()); + encrypted = _aes.Update(data.ToUtf8Buffer()); _aes.Finish(); // Decrypt CBC - _aes.Start(AesContext.Mode.EcbDecrypt, key.ToUtf8(), iv.ToUtf8()); + _aes.Start(AesContext.Mode.EcbDecrypt, key.ToUtf8Buffer(), iv.ToUtf8Buffer()); decrypted = _aes.Update(encrypted); _aes.Finish(); // Check CBC - Debug.Assert(decrypted == data.ToUtf8()); + Debug.Assert(decrypted == data.ToUtf8Buffer()); } } [/csharp] diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml index cf542f333b..1c761f9f1a 100644 --- a/doc/classes/Array.xml +++ b/doc/classes/Array.xml @@ -441,12 +441,23 @@ <return type="Variant" /> <description> Returns the maximum value contained in the array if all elements are of comparable types. If the elements can't be compared, [code]null[/code] is returned. + To find the maximum value using a custom comparator, you can use [method reduce]. In this example every array element is checked and the first maximum value is returned: + [codeblock] + func _ready(): + var arr = [Vector2(0, 1), Vector2(2, 0), Vector2(1, 1), Vector2(1, 0), Vector2(0, 2)] + # In this example we compare the lengths. + print(arr.reduce(func(max, val): return val if is_length_greater(val, max) else max)) + + func is_length_greater(a, b): + return a.length() > b.length() + [/codeblock] </description> </method> <method name="min" qualifiers="const"> <return type="Variant" /> <description> Returns the minimum value contained in the array if all elements are of comparable types. If the elements can't be compared, [code]null[/code] is returned. + See also [method max] for an example of using a custom comparator. </description> </method> <method name="pick_random" qualifiers="const"> diff --git a/doc/classes/CompressedCubemap.xml b/doc/classes/CompressedCubemap.xml index 745e9c87e3..f98dfc61a3 100644 --- a/doc/classes/CompressedCubemap.xml +++ b/doc/classes/CompressedCubemap.xml @@ -5,10 +5,11 @@ </brief_description> <description> A cubemap that is loaded from a [code].ccube[/code] file. This file format is internal to Godot; it is created by importing other image formats with the import system. [CompressedCubemap] can use one of 4 compresson methods: - - Uncompressed (uncompressed on the GPU) - Lossless (WebP or PNG, uncompressed on the GPU) - Lossy (WebP, uncompressed on the GPU) - VRAM Compressed (compressed on the GPU) + - VRAM Uncompressed (uncompressed on the GPU) + - Basis Universal (compressed on the GPU. Lower file sizes than VRAM Compressed, but slower to compress and lower quality than VRAM Compressed) Only [b]VRAM Compressed[/b] actually reduces the memory usage on the GPU. The [b]Lossless[/b] and [b]Lossy[/b] compression methods will reduce the required storage on disk, but they will not reduce memory usage on the GPU as the texture is sent to the GPU uncompressed. Using [b]VRAM Compressed[/b] also improves loading times, as VRAM-compressed textures are faster to load compared to textures using lossless or lossy compression. VRAM compression can exhibit noticeable artifacts and is intended to be used for 3D rendering, not 2D. See [Cubemap] for a general description of cubemaps. diff --git a/doc/classes/CompressedCubemapArray.xml b/doc/classes/CompressedCubemapArray.xml index 8606027242..75e9b3d513 100644 --- a/doc/classes/CompressedCubemapArray.xml +++ b/doc/classes/CompressedCubemapArray.xml @@ -5,10 +5,11 @@ </brief_description> <description> A cubemap array that is loaded from a [code].ccubearray[/code] file. This file format is internal to Godot; it is created by importing other image formats with the import system. [CompressedCubemapArray] can use one of 4 compresson methods: - - Uncompressed (uncompressed on the GPU) - Lossless (WebP or PNG, uncompressed on the GPU) - Lossy (WebP, uncompressed on the GPU) - VRAM Compressed (compressed on the GPU) + - VRAM Uncompressed (uncompressed on the GPU) + - Basis Universal (compressed on the GPU. Lower file sizes than VRAM Compressed, but slower to compress and lower quality than VRAM Compressed) Only [b]VRAM Compressed[/b] actually reduces the memory usage on the GPU. The [b]Lossless[/b] and [b]Lossy[/b] compression methods will reduce the required storage on disk, but they will not reduce memory usage on the GPU as the texture is sent to the GPU uncompressed. Using [b]VRAM Compressed[/b] also improves loading times, as VRAM-compressed textures are faster to load compared to textures using lossless or lossy compression. VRAM compression can exhibit noticeable artifacts and is intended to be used for 3D rendering, not 2D. See [CubemapArray] for a general description of cubemap arrays. diff --git a/doc/classes/CompressedTexture2D.xml b/doc/classes/CompressedTexture2D.xml index f4e7398d6e..9fde9ebeea 100644 --- a/doc/classes/CompressedTexture2D.xml +++ b/doc/classes/CompressedTexture2D.xml @@ -5,10 +5,11 @@ </brief_description> <description> A texture that is loaded from a [code].ctex[/code] file. This file format is internal to Godot; it is created by importing other image formats with the import system. [CompressedTexture2D] can use one of 4 compression methods (including a lack of any compression): - - Uncompressed (uncompressed on the GPU) - Lossless (WebP or PNG, uncompressed on the GPU) - Lossy (WebP, uncompressed on the GPU) - VRAM Compressed (compressed on the GPU) + - VRAM Uncompressed (uncompressed on the GPU) + - Basis Universal (compressed on the GPU. Lower file sizes than VRAM Compressed, but slower to compress and lower quality than VRAM Compressed) Only [b]VRAM Compressed[/b] actually reduces the memory usage on the GPU. The [b]Lossless[/b] and [b]Lossy[/b] compression methods will reduce the required storage on disk, but they will not reduce memory usage on the GPU as the texture is sent to the GPU uncompressed. Using [b]VRAM Compressed[/b] also improves loading times, as VRAM-compressed textures are faster to load compared to textures using lossless or lossy compression. VRAM compression can exhibit noticeable artifacts and is intended to be used for 3D rendering, not 2D. </description> diff --git a/doc/classes/CompressedTexture2DArray.xml b/doc/classes/CompressedTexture2DArray.xml index bfb3cabe05..71888bf824 100644 --- a/doc/classes/CompressedTexture2DArray.xml +++ b/doc/classes/CompressedTexture2DArray.xml @@ -5,10 +5,11 @@ </brief_description> <description> A texture array that is loaded from a [code].ctexarray[/code] file. This file format is internal to Godot; it is created by importing other image formats with the import system. [CompressedTexture2DArray] can use one of 4 compresson methods: - - Uncompressed (uncompressed on the GPU) - Lossless (WebP or PNG, uncompressed on the GPU) - Lossy (WebP, uncompressed on the GPU) - VRAM Compressed (compressed on the GPU) + - VRAM Uncompressed (uncompressed on the GPU) + - Basis Universal (compressed on the GPU. Lower file sizes than VRAM Compressed, but slower to compress and lower quality than VRAM Compressed) Only [b]VRAM Compressed[/b] actually reduces the memory usage on the GPU. The [b]Lossless[/b] and [b]Lossy[/b] compression methods will reduce the required storage on disk, but they will not reduce memory usage on the GPU as the texture is sent to the GPU uncompressed. Using [b]VRAM Compressed[/b] also improves loading times, as VRAM-compressed textures are faster to load compared to textures using lossless or lossy compression. VRAM compression can exhibit noticeable artifacts and is intended to be used for 3D rendering, not 2D. See [Texture2DArray] for a general description of texture arrays. diff --git a/doc/classes/CompressedTextureLayered.xml b/doc/classes/CompressedTextureLayered.xml index 43ce8f5df7..da34180c93 100644 --- a/doc/classes/CompressedTextureLayered.xml +++ b/doc/classes/CompressedTextureLayered.xml @@ -4,13 +4,7 @@ Base class for texture arrays that can optionally be compressed. </brief_description> <description> - A texture array that is loaded from a [code].ctexarray[/code] file. This file format is internal to Godot; it is created by importing other image formats with the import system. [CompressedTexture2D] can use one of 4 compresson methods: - - Uncompressed (uncompressed on the GPU) - - Lossless (WebP or PNG, uncompressed on the GPU) - - Lossy (WebP, uncompressed on the GPU) - - VRAM Compressed (compressed on the GPU) - Only [b]VRAM Compressed[/b] actually reduces the memory usage on the GPU. The [b]Lossless[/b] and [b]Lossy[/b] compression methods will reduce the required storage on disk, but they will not reduce memory usage on the GPU as the texture is sent to the GPU uncompressed. - Using [b]VRAM Compressed[/b] also improves loading times, as VRAM-compressed textures are faster to load compared to textures using lossless or lossy compression. VRAM compression can exhibit noticeable artifacts and is intended to be used for 3D rendering, not 2D. + Base class for [CompressedTexture2DArray] and [CompressedTexture3D]. Cannot be used directly, but contains all the functions necessary for accessing the derived resource types. See also [TextureLayered]. </description> <tutorials> </tutorials> diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml index b26c4029be..a52cdf7207 100644 --- a/doc/classes/Control.xml +++ b/doc/classes/Control.xml @@ -946,10 +946,10 @@ Tells Godot which node it should give focus to if the user presses the left arrow on the keyboard or left on a gamepad by default. You can change the key by editing the [member ProjectSettings.input/ui_left] input action. The node must be a [Control]. If this property is not set, Godot will give focus to the closest [Control] to the left of this one. </member> <member name="focus_neighbor_right" type="NodePath" setter="set_focus_neighbor" getter="get_focus_neighbor" default="NodePath("")"> - Tells Godot which node it should give focus to if the user presses the right arrow on the keyboard or right on a gamepad by default. You can change the key by editing the [member ProjectSettings.input/ui_right] input action. The node must be a [Control]. If this property is not set, Godot will give focus to the closest [Control] to the bottom of this one. + Tells Godot which node it should give focus to if the user presses the right arrow on the keyboard or right on a gamepad by default. You can change the key by editing the [member ProjectSettings.input/ui_right] input action. The node must be a [Control]. If this property is not set, Godot will give focus to the closest [Control] to the right of this one. </member> <member name="focus_neighbor_top" type="NodePath" setter="set_focus_neighbor" getter="get_focus_neighbor" default="NodePath("")"> - Tells Godot which node it should give focus to if the user presses the top arrow on the keyboard or top on a gamepad by default. You can change the key by editing the [member ProjectSettings.input/ui_up] input action. The node must be a [Control]. If this property is not set, Godot will give focus to the closest [Control] to the bottom of this one. + Tells Godot which node it should give focus to if the user presses the top arrow on the keyboard or top on a gamepad by default. You can change the key by editing the [member ProjectSettings.input/ui_up] input action. The node must be a [Control]. If this property is not set, Godot will give focus to the closest [Control] to the top of this one. </member> <member name="focus_next" type="NodePath" setter="set_focus_next" getter="get_focus_next" default="NodePath("")"> Tells Godot which node it should give focus to if the user presses [kbd]Tab[/kbd] on a keyboard by default. You can change the key by editing the [member ProjectSettings.input/ui_focus_next] input action. diff --git a/doc/classes/Crypto.xml b/doc/classes/Crypto.xml index 8356da4b04..d4898055d9 100644 --- a/doc/classes/Crypto.xml +++ b/doc/classes/Crypto.xml @@ -24,7 +24,7 @@ cert.save("user://generated.crt") # Encryption var data = "Some data" - var encrypted = crypto.encrypt(key, data.to_utf8()) + var encrypted = crypto.encrypt(key, data.to_utf8_buffer()) # Decryption var decrypted = crypto.decrypt(key, encrypted) # Signing @@ -33,7 +33,7 @@ var verified = crypto.verify(HashingContext.HASH_SHA256, data.sha256_buffer(), signature, key) # Checks assert(verified) - assert(data.to_utf8() == decrypted) + assert(data.to_utf8_buffer() == decrypted) [/gdscript] [csharp] using Godot; @@ -56,7 +56,7 @@ _cert.Save("user://generated.crt"); // Encryption string data = "Some data"; - byte[] encrypted = _crypto.Encrypt(_key, data.ToUtf8()); + byte[] encrypted = _crypto.Encrypt(_key, data.ToUtf8Buffer()); // Decryption byte[] decrypted = _crypto.Decrypt(_key, encrypted); // Signing @@ -65,7 +65,7 @@ bool verified = _crypto.Verify(HashingContext.HashType.Sha256, Data.Sha256Buffer(), signature, _key); // Checks Debug.Assert(verified); - Debug.Assert(data.ToUtf8() == decrypted); + Debug.Assert(data.ToUtf8Buffer() == decrypted); } } [/csharp] diff --git a/doc/classes/DTLSServer.xml b/doc/classes/DTLSServer.xml index 47b4063cf8..da452de946 100644 --- a/doc/classes/DTLSServer.xml +++ b/doc/classes/DTLSServer.xml @@ -35,7 +35,7 @@ if p.get_status() == PacketPeerDTLS.STATUS_CONNECTED: while p.get_available_packet_count() > 0: print("Received message from client: %s" % p.get_packet().get_string_from_utf8()) - p.put_packet("Hello DTLS client".to_utf8()) + p.put_packet("Hello DTLS client".to_utf8_buffer()) [/gdscript] [csharp] // ServerNode.cs @@ -77,7 +77,7 @@ while (p.GetAvailablePacketCount() > 0) { GD.Print($"Received Message From Client: {p.GetPacket().GetStringFromUtf8()}"); - p.PutPacket("Hello DTLS Client".ToUtf8()); + p.PutPacket("Hello DTLS Client".ToUtf8Buffer()); } } } @@ -103,7 +103,7 @@ if dtls.get_status() == PacketPeerDTLS.STATUS_CONNECTED: if !connected: # Try to contact server - dtls.put_packet("The answer is... 42!".to_utf8()) + dtls.put_packet("The answer is... 42!".to_utf8_buffer()) while dtls.get_available_packet_count() > 0: print("Connected: %s" % dtls.get_packet().get_string_from_utf8()) connected = true @@ -133,7 +133,7 @@ if (!_connected) { // Try to contact server - _dtls.PutPacket("The Answer Is..42!".ToUtf8()); + _dtls.PutPacket("The Answer Is..42!".ToUtf8Buffer()); } while (_dtls.GetAvailablePacketCount() > 0) { diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml index 285b58edbb..996af71c3b 100644 --- a/doc/classes/EditorSettings.xml +++ b/doc/classes/EditorSettings.xml @@ -329,7 +329,7 @@ [b]Note:[/b] On certain window managers on Linux, the [kbd]Alt[/kbd] key will be intercepted by the window manager when clicking a mouse button at the same time. This means Godot will not see the modifier key as being pressed. </member> <member name="editors/3d/navigation/warped_mouse_panning" type="bool" setter="" getter=""> - If [code]true[/code], warps the mouse around the 3D viewport while panning in the 3D editor. This makes it possible to pan over a large area without having to exit panning then mouse the mouse back constantly. + If [code]true[/code], warps the mouse around the 3D viewport while panning in the 3D editor. This makes it possible to pan over a large area without having to exit panning and adjust the mouse cursor. </member> <member name="editors/3d/navigation/zoom_modifier" type="int" setter="" getter=""> The modifier key that must be held to zoom in the 3D editor. @@ -408,7 +408,7 @@ Controls whether the mouse wheel scroll zooms or pans in subeditors. The list of affected subeditors is: animation blend tree editor, [Polygon2D] editor, tileset editor, texture region editor and visual shader editor. See also [member editors/panning/2d_editor_panning_scheme] and [member editors/panning/animation_editors_panning_scheme]. </member> <member name="editors/panning/warped_mouse_panning" type="bool" setter="" getter=""> - If [code]true[/code], warps the mouse around the 2D viewport while panning in the 2D editor. This makes it possible to pan over a large area without having to exit panning then mouse the mouse back constantly. + If [code]true[/code], warps the mouse around the 2D viewport while panning in the 2D editor. This makes it possible to pan over a large area without having to exit panning and adjust the mouse cursor. </member> <member name="editors/polygon_editor/point_grab_radius" type="int" setter="" getter=""> The radius in which points can be selected in the [Polygon2D] and [CollisionPolygon2D] editors (in pixels). Higher values make it easier to select points quickly, but can make it more difficult to select the expected point when several points are located close to each other. @@ -686,7 +686,7 @@ If [code]true[/code], makes the caret blink according to [member text_editor/appearance/caret/caret_blink_interval]. Disabling this setting can improve battery life on laptops if you spend long amounts of time in the script editor, since it will reduce the frequency at which the editor needs to be redrawn. </member> <member name="text_editor/appearance/caret/caret_blink_interval" type="float" setter="" getter=""> - The interval at which to blink the caret (in seconds). See also [member text_editor/appearance/caret/caret_blink]. + The interval at which the caret will blink (in seconds). See also [member text_editor/appearance/caret/caret_blink]. </member> <member name="text_editor/appearance/caret/highlight_all_occurrences" type="bool" setter="" getter=""> If [code]true[/code], highlights all occurrences of the currently selected text in the script editor. See also [member text_editor/theme/highlighting/word_highlighted_color]. diff --git a/doc/classes/FileDialog.xml b/doc/classes/FileDialog.xml index 803d3a792a..f09040cc76 100644 --- a/doc/classes/FileDialog.xml +++ b/doc/classes/FileDialog.xml @@ -54,7 +54,7 @@ </methods> <members> <member name="access" type="int" setter="set_access" getter="get_access" enum="FileDialog.Access" default="0"> - The file system access scope. See enum [code]Access[/code] constants. + The file system access scope. See [enum Access] constants. [b]Warning:[/b] Currently, in sandboxed environments such as Web builds or sandboxed macOS apps, FileDialog cannot access the host file system. See [url=https://github.com/godotengine/godot-proposals/issues/1123]godot-proposals#1123[/url]. </member> <member name="current_dir" type="String" setter="set_current_dir" getter="get_current_dir"> @@ -74,7 +74,7 @@ The available file type filters. For example, this shows only [code].png[/code] and [code].gd[/code] files: [code]set_filters(PackedStringArray(["*.png ; PNG Images","*.gd ; GDScript Files"]))[/code]. Multiple file types can also be specified in a single filter. [code]"*.png, *.jpg, *.jpeg ; Supported Images"[/code] will show both PNG and JPEG files when selected. </member> <member name="mode_overrides_title" type="bool" setter="set_mode_overrides_title" getter="is_mode_overriding_title" default="true"> - If [code]true[/code], changing the [code]Mode[/code] property will set the window title accordingly (e.g. setting mode to [constant FILE_MODE_OPEN_FILE] will change the window title to "Open a File"). + If [code]true[/code], changing the [member file_mode] property will set the window title accordingly (e.g. setting [member file_mode] to [constant FILE_MODE_OPEN_FILE] will change the window title to "Open a File"). </member> <member name="root_subfolder" type="String" setter="set_root_subfolder" getter="get_root_subfolder" default=""""> If non-empty, the given sub-folder will be "root" of this [FileDialog], i.e. user won't be able to go to its parent directory. diff --git a/doc/classes/HMACContext.xml b/doc/classes/HMACContext.xml index 825d3b24ed..ed80488e04 100644 --- a/doc/classes/HMACContext.xml +++ b/doc/classes/HMACContext.xml @@ -11,11 +11,11 @@ var ctx = HMACContext.new() func _ready(): - var key = "supersecret".to_utf8() + var key = "supersecret".to_utf8_buffer() var err = ctx.start(HashingContext.HASH_SHA256, key) assert(err == OK) - var msg1 = "this is ".to_utf8() - var msg2 = "super duper secret".to_utf8() + var msg1 = "this is ".to_utf8_buffer() + var msg2 = "super duper secret".to_utf8_buffer() err = ctx.update(msg1) assert(err == OK) err = ctx.update(msg2) @@ -34,11 +34,11 @@ public override void _Ready() { - byte[] key = "supersecret".ToUtf8(); + byte[] key = "supersecret".ToUtf8Buffer(); Error err = _ctx.Start(HashingContext.HashType.Sha256, key); Debug.Assert(err == Error.Ok); - byte[] msg1 = "this is ".ToUtf8(); - byte[] msg2 = "super duper secret".ToUtf8(); + byte[] msg1 = "this is ".ToUtf8Buffer(); + byte[] msg2 = "super duper secret".ToUtf8Buffer(); err = _ctx.Update(msg1); Debug.Assert(err == Error.Ok); err = _ctx.Update(msg2); diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml index f546d9c833..f63243e8d4 100644 --- a/doc/classes/LineEdit.xml +++ b/doc/classes/LineEdit.xml @@ -187,10 +187,10 @@ Text alignment as defined in the [enum HorizontalAlignment] enum. </member> <member name="caret_blink" type="bool" setter="set_caret_blink_enabled" getter="is_caret_blink_enabled" default="false"> - If [code]true[/code], the caret (text cursor) blinks. + If [code]true[/code], makes the caret blink. </member> <member name="caret_blink_interval" type="float" setter="set_caret_blink_interval" getter="get_caret_blink_interval" default="0.65"> - Duration (in seconds) of a caret's blinking cycle. + The interval at which the caret blinks (in seconds). </member> <member name="caret_column" type="int" setter="set_caret_column" getter="get_caret_column" default="0"> The caret's column position inside the [LineEdit]. When set, the text may scroll to accommodate it. diff --git a/doc/classes/MeshConvexDecompositionSettings.xml b/doc/classes/MeshConvexDecompositionSettings.xml new file mode 100644 index 0000000000..a2784c4485 --- /dev/null +++ b/doc/classes/MeshConvexDecompositionSettings.xml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="MeshConvexDecompositionSettings" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + Parameters to be used with a [Mesh] convex decomposition operation. + </brief_description> + <description> + Parameters to be used with a [Mesh] convex decomposition operation. + </description> + <tutorials> + </tutorials> + <members> + <member name="convex_hull_approximation" type="bool" setter="set_convex_hull_approximation" getter="get_convex_hull_approximation" default="true"> + If enabled uses approximation for computing convex hulls. + </member> + <member name="convex_hull_downsampling" type="int" setter="set_convex_hull_downsampling" getter="get_convex_hull_downsampling" default="4"> + Controls the precision of the convex-hull generation process during the clipping plane selection stage. Ranges from [code]1[/code] to [code]16[/code]. + </member> + <member name="max_concavity" type="float" setter="set_max_concavity" getter="get_max_concavity" default="1.0"> + Maximum concavity. Ranges from [code]0.0[/code] to [code]1.0[/code]. + </member> + <member name="max_convex_hulls" type="int" setter="set_max_convex_hulls" getter="get_max_convex_hulls" default="1"> + The maximum number of convex hulls to produce from the merge operation. + </member> + <member name="max_num_vertices_per_convex_hull" type="int" setter="set_max_num_vertices_per_convex_hull" getter="get_max_num_vertices_per_convex_hull" default="32"> + Controls the maximum number of triangles per convex-hull. Ranges from [code]4[/code] to [code]1024[/code]. + </member> + <member name="min_volume_per_convex_hull" type="float" setter="set_min_volume_per_convex_hull" getter="get_min_volume_per_convex_hull" default="0.0001"> + Controls the adaptive sampling of the generated convex-hulls. Ranges from [code]0.0[/code] to [code]0.01[/code]. + </member> + <member name="mode" type="int" setter="set_mode" getter="get_mode" enum="MeshConvexDecompositionSettings.Mode" default="0"> + Mode for the approximate convex decomposition. + </member> + <member name="normalize_mesh" type="bool" setter="set_normalize_mesh" getter="get_normalize_mesh" default="false"> + If enabled normalizes the mesh before applying the convex decomposition. + </member> + <member name="plane_downsampling" type="int" setter="set_plane_downsampling" getter="get_plane_downsampling" default="4"> + Controls the granularity of the search for the "best" clipping plane. Ranges from [code]1[/code] to [code]16[/code]. + </member> + <member name="project_hull_vertices" type="bool" setter="set_project_hull_vertices" getter="get_project_hull_vertices" default="true"> + If enabled projects output convex hull vertices onto original source mesh to increase floating point accuracy of the results. + </member> + <member name="resolution" type="int" setter="set_resolution" getter="get_resolution" default="10000"> + Maximum number of voxels generated during the voxelization stage. + </member> + <member name="revolution_axes_clipping_bias" type="float" setter="set_revolution_axes_clipping_bias" getter="get_revolution_axes_clipping_bias" default="0.05"> + Controls the bias toward clipping along revolution axes. Ranges from [code]0.0[/code] to [code]1.0[/code]. + </member> + <member name="symmetry_planes_clipping_bias" type="float" setter="set_symmetry_planes_clipping_bias" getter="get_symmetry_planes_clipping_bias" default="0.05"> + Controls the bias toward clipping along symmetry planes. Ranges from [code]0.0[/code] to [code]1.0[/code]. + </member> + </members> + <constants> + <constant name="CONVEX_DECOMPOSITION_MODE_VOXEL" value="0" enum="Mode"> + Constant for voxel-based approximate convex decomposition. + </constant> + <constant name="CONVEX_DECOMPOSITION_MODE_TETRAHEDRON" value="1" enum="Mode"> + Constant for tetrahedron-based approximate convex decomposition. + </constant> + </constants> +</class> diff --git a/doc/classes/MeshInstance3D.xml b/doc/classes/MeshInstance3D.xml index 187f2510c5..fb6702263e 100644 --- a/doc/classes/MeshInstance3D.xml +++ b/doc/classes/MeshInstance3D.xml @@ -31,8 +31,9 @@ </method> <method name="create_multiple_convex_collisions"> <return type="void" /> + <param index="0" name="settings" type="MeshConvexDecompositionSettings" default="null" /> <description> - This helper creates a [StaticBody3D] child node with multiple [ConvexPolygonShape3D] collision shapes calculated from the mesh geometry via convex decomposition. It's mainly used for testing. + This helper creates a [StaticBody3D] child node with multiple [ConvexPolygonShape3D] collision shapes calculated from the mesh geometry via convex decomposition. The convex decomposition operation can be controlled with parameters from the optional [param settings]. </description> </method> <method name="create_trimesh_collision"> diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index cb829ae183..42418b3e8d 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -830,6 +830,11 @@ When this signal is received, the child [param node] is still in the tree and valid. This signal is emitted [i]after[/i] the child node's own [signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]. </description> </signal> + <signal name="child_order_changed"> + <description> + Emitted when the list of children is changed. This happens when child nodes are added, moved or removed. + </description> + </signal> <signal name="ready"> <description> Emitted when the node is ready. Comes after [method _ready] callback and follows the same rules. @@ -867,8 +872,8 @@ Notification received when the node is about to exit a [SceneTree]. This notification is emitted [i]after[/i] the related [signal tree_exiting]. </constant> - <constant name="NOTIFICATION_MOVED_IN_PARENT" value="12"> - Notification received when the node is moved in the parent. + <constant name="NOTIFICATION_MOVED_IN_PARENT" value="12" is_deprecated="true"> + This notification is deprecated and is no longer emitted. Use [constant NOTIFICATION_CHILD_ORDER_CHANGED] instead. </constant> <constant name="NOTIFICATION_READY" value="13"> Notification received when the node is ready. See [method _ready]. @@ -907,6 +912,9 @@ <constant name="NOTIFICATION_PATH_RENAMED" value="23"> Notification received when the node's name or one of its parents' name is changed. This notification is [i]not[/i] received when the node is removed from the scene tree to be added to another parent later on. </constant> + <constant name="NOTIFICATION_CHILD_ORDER_CHANGED" value="24"> + Notification received when the list of children is changed. This happens when child nodes are added, moved or removed. + </constant> <constant name="NOTIFICATION_INTERNAL_PROCESS" value="25"> Notification received every frame when the internal process flag is set (see [method set_process_internal]). </constant> diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml index 1b98d357ae..28c6247338 100644 --- a/doc/classes/OS.xml +++ b/doc/classes/OS.xml @@ -491,6 +491,7 @@ <description> Returns [code]true[/code] if the feature for the given feature tag is supported in the currently running instance, depending on the platform, build, etc. Can be used to check whether you're currently running a debug build, on a certain platform or arch, etc. Refer to the [url=$DOCS_URL/tutorials/export/feature_tags.html]Feature Tags[/url] documentation for more details. [b]Note:[/b] Tag names are case-sensitive. + [b]Note:[/b] On the web platform, one of the following additional tags is defined to indicate host platform: [code]web_android[/code], [code]web_ios[/code], [code]web_linuxbsd[/code], [code]web_macos[/code], or [code]web_windows[/code]. </description> </method> <method name="is_debug_build" qualifiers="const"> diff --git a/doc/classes/PacketPeerUDP.xml b/doc/classes/PacketPeerUDP.xml index c520bc6699..cc8eee97b1 100644 --- a/doc/classes/PacketPeerUDP.xml +++ b/doc/classes/PacketPeerUDP.xml @@ -112,7 +112,7 @@ socket = PacketPeerUDP.new() # Server socket.set_dest_address("127.0.0.1", 789) - socket.put_packet("Time to stop".to_ascii()) + socket.put_packet("Time to stop".to_ascii_buffer()) # Client while socket.wait() == OK: @@ -124,7 +124,7 @@ var socket = new PacketPeerUDP(); // Server socket.SetDestAddress("127.0.0.1", 789); - socket.PutPacket("Time to stop".ToAscii()); + socket.PutPacket("Time to stop".ToAsciiBuffer()); // Client while (socket.Wait() == OK) diff --git a/doc/classes/StreamPeer.xml b/doc/classes/StreamPeer.xml index 6e52016a1a..e93b95617c 100644 --- a/doc/classes/StreamPeer.xml +++ b/doc/classes/StreamPeer.xml @@ -177,10 +177,10 @@ [b]Note:[/b] To put an ASCII string without prepending its size, you can use [method put_data]: [codeblocks] [gdscript] - put_data("Hello world".to_ascii()) + put_data("Hello world".to_ascii_buffer()) [/gdscript] [csharp] - PutData("Hello World".ToAscii()); + PutData("Hello World".ToAsciiBuffer()); [/csharp] [/codeblocks] </description> @@ -221,10 +221,10 @@ [b]Note:[/b] To put an UTF-8 string without prepending its size, you can use [method put_data]: [codeblocks] [gdscript] - put_data("Hello world".to_utf8()) + put_data("Hello world".to_utf8_buffer()) [/gdscript] [csharp] - PutData("Hello World".ToUtf8()); + PutData("Hello World".ToUtf8Buffer()); [/csharp] [/codeblocks] </description> diff --git a/doc/classes/SyntaxHighlighter.xml b/doc/classes/SyntaxHighlighter.xml index 76f98f9edb..79f4944bae 100644 --- a/doc/classes/SyntaxHighlighter.xml +++ b/doc/classes/SyntaxHighlighter.xml @@ -58,7 +58,7 @@ This will color columns 0-4 red, and columns 5-eol in green. </description> </method> - <method name="get_text_edit"> + <method name="get_text_edit" qualifiers="const"> <return type="TextEdit" /> <description> Returns the associated [TextEdit] node. diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml index a292c594cf..633e1b4e74 100644 --- a/doc/classes/TextEdit.xml +++ b/doc/classes/TextEdit.xml @@ -1088,10 +1088,13 @@ </methods> <members> <member name="caret_blink" type="bool" setter="set_caret_blink_enabled" getter="is_caret_blink_enabled" default="false"> - Sets if the caret should blink. + If [code]true[/code], makes the caret blink. </member> <member name="caret_blink_interval" type="float" setter="set_caret_blink_interval" getter="get_caret_blink_interval" default="0.65"> - Duration (in seconds) of a caret's blinking cycle. + The interval at which the caret blinks (in seconds). + </member> + <member name="caret_draw_when_editable_disabled" type="bool" setter="set_draw_caret_when_editable_disabled" getter="is_drawing_caret_when_editable_disabled" default="false"> + If [code]true[/code], caret will be visible when [member editable] is disabled. </member> <member name="caret_mid_grapheme" type="bool" setter="set_caret_mid_grapheme_enabled" getter="is_caret_mid_grapheme_enabled" default="true"> Allow moving caret, selecting and removing the individual composite character components. diff --git a/doc/classes/TextureLayered.xml b/doc/classes/TextureLayered.xml index adf391841f..52f3b9aca2 100644 --- a/doc/classes/TextureLayered.xml +++ b/doc/classes/TextureLayered.xml @@ -4,7 +4,7 @@ Base class for texture types which contain the data of multiple [Image]s. Each image is of the same size and format. </brief_description> <description> - Base class for [ImageTextureLayered]. Cannot be used directly, but contains all the functions necessary for accessing the derived resource types. See also [Texture3D]. + Base class for [ImageTextureLayered] and [CompressedTextureLayered]. Cannot be used directly, but contains all the functions necessary for accessing the derived resource types. See also [Texture3D]. Data is set on a per-layer basis. For [Texture2DArray]s, the layer specifies the array layer. All images need to have the same width, height and number of mipmap levels. A [TextureLayered] can be loaded with [method ResourceLoader.load]. diff --git a/doc/classes/Tree.xml b/doc/classes/Tree.xml index 9c60ba1b37..1e4282cd0b 100644 --- a/doc/classes/Tree.xml +++ b/doc/classes/Tree.xml @@ -558,6 +558,24 @@ <theme_item name="scroll_speed" data_type="constant" type="int" default="12"> The speed of border scrolling. </theme_item> + <theme_item name="scrollbar_h_separation" data_type="constant" type="int" default="4"> + The horizontal separation of tree content and scrollbar. + </theme_item> + <theme_item name="scrollbar_margin_bottom" data_type="constant" type="int" default="-1"> + The bottom margin of the scrollbars. When negative, uses [theme_item panel] bottom margin. + </theme_item> + <theme_item name="scrollbar_margin_left" data_type="constant" type="int" default="-1"> + The left margin of the horizontal scrollbar. When negative, uses [theme_item panel] left margin. + </theme_item> + <theme_item name="scrollbar_margin_right" data_type="constant" type="int" default="-1"> + The right margin of the scrollbars. When negative, uses [theme_item panel] right margin. + </theme_item> + <theme_item name="scrollbar_margin_top" data_type="constant" type="int" default="-1"> + The right margin of the vertical scrollbar. When negative, uses [theme_item panel] top margin. + </theme_item> + <theme_item name="scrollbar_v_separation" data_type="constant" type="int" default="4"> + The vertical separation of tree content and scrollbar. + </theme_item> <theme_item name="v_separation" data_type="constant" type="int" default="4"> The vertical padding inside each item, i.e. the distance between the item's content and top/bottom border. </theme_item> diff --git a/doc/classes/UDPServer.xml b/doc/classes/UDPServer.xml index e3901336a5..91277ee5fd 100644 --- a/doc/classes/UDPServer.xml +++ b/doc/classes/UDPServer.xml @@ -86,7 +86,7 @@ func _process(delta): if !connected: # Try to contact server - udp.put_packet("The answer is... 42!".to_utf8()) + udp.put_packet("The answer is... 42!".to_utf8_buffer()) if udp.get_available_packet_count() > 0: print("Connected: %s" % udp.get_packet().get_string_from_utf8()) connected = true @@ -110,7 +110,7 @@ if (!_connected) { // Try to contact server - _udp.PutPacket("The Answer Is..42!".ToUtf8()); + _udp.PutPacket("The Answer Is..42!".ToUtf8Buffer()); } if (_udp.GetAvailablePacketCount() > 0) { diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp index fc6c2f3a26..f00124ab13 100644 --- a/drivers/gles3/storage/material_storage.cpp +++ b/drivers/gles3/storage/material_storage.cpp @@ -1489,7 +1489,7 @@ MaterialStorage::MaterialStorage() { global_shader_uniforms.buffer_size = MAX(4096, (int)GLOBAL_GET("rendering/limits/global_shader_variables/buffer_size")); if (global_shader_uniforms.buffer_size > uint32_t(Config::get_singleton()->max_uniform_buffer_size)) { global_shader_uniforms.buffer_size = uint32_t(Config::get_singleton()->max_uniform_buffer_size); - WARN_PRINT("Project setting: rendering/limits/global_shader_variables/buffer_size exceeds maximum uniform buffer size of: " + itos(Config::get_singleton()->max_uniform_buffer_size)); + WARN_PRINT("Project setting \"rendering/limits/global_shader_variables/buffer_size\" exceeds maximum uniform buffer size of: " + itos(Config::get_singleton()->max_uniform_buffer_size)); } global_shader_uniforms.buffer_values = memnew_arr(GlobalShaderUniforms::Value, global_shader_uniforms.buffer_size); diff --git a/editor/SCsub b/editor/SCsub index dddec55ed6..d1781487ca 100644 --- a/editor/SCsub +++ b/editor/SCsub @@ -119,7 +119,7 @@ if env.editor_build: SConscript("debugger/SCsub") SConscript("export/SCsub") - SConscript("fileserver/SCsub") + SConscript("gui/SCsub") SConscript("icons/SCsub") SConscript("import/SCsub") SConscript("plugins/SCsub") diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index c27417f037..e87c381e32 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -37,12 +37,20 @@ #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/gui/editor_spin_slider.h" +#include "editor/gui/scene_tree_editor.h" #include "editor/inspector_dock.h" #include "editor/plugins/animation_player_editor_plugin.h" #include "scene/animation/animation_player.h" #include "scene/animation/tween.h" +#include "scene/gui/check_box.h" #include "scene/gui/grid_container.h" +#include "scene/gui/option_button.h" +#include "scene/gui/panel_container.h" #include "scene/gui/separator.h" +#include "scene/gui/slider.h" +#include "scene/gui/spin_box.h" +#include "scene/gui/texture_rect.h" #include "scene/gui/view_panner.h" #include "scene/main/window.h" #include "scene/scene_string_names.h" diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h index c733f397e3..cef726f6c0 100644 --- a/editor/animation_track_editor.h +++ b/editor/animation_track_editor.h @@ -33,25 +33,24 @@ #include "editor/editor_data.h" #include "editor/editor_properties.h" -#include "editor/editor_spin_slider.h" #include "editor/property_selector.h" - #include "scene/3d/node_3d.h" -#include "scene/gui/check_box.h" #include "scene/gui/control.h" #include "scene/gui/menu_button.h" -#include "scene/gui/option_button.h" -#include "scene/gui/panel_container.h" #include "scene/gui/scroll_bar.h" -#include "scene/gui/slider.h" -#include "scene/gui/spin_box.h" -#include "scene/gui/tab_container.h" -#include "scene/gui/texture_rect.h" +#include "scene/gui/tree.h" #include "scene/resources/animation.h" -#include "scene_tree_editor.h" class AnimationTrackEditor; class AnimationTrackEdit; +class CheckBox; +class EditorSpinSlider; +class HSlider; +class OptionButton; +class PanelContainer; +class SceneTreeDialog; +class SpinBox; +class TextureRect; class ViewPanner; class AnimationTrackKeyEdit : public Object { diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index befe84f311..c788fee7f8 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -33,12 +33,21 @@ #include "core/config/project_settings.h" #include "editor/doc_tools.h" #include "editor/editor_help.h" +#include "editor/editor_inspector.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/gui/scene_tree_editor.h" #include "editor/scene_tree_dock.h" #include "plugins/script_editor_plugin.h" +#include "scene/gui/button.h" +#include "scene/gui/check_box.h" +#include "scene/gui/label.h" +#include "scene/gui/line_edit.h" +#include "scene/gui/option_button.h" +#include "scene/gui/popup_menu.h" +#include "scene/gui/spin_box.h" #include "scene/resources/packed_scene.h" static Node *_find_first_script(Node *p_root, Node *p_node) { @@ -119,7 +128,7 @@ void ConnectDialog::ok_pressed() { return; } - if (!method_name.strip_edges().is_valid_identifier()) { + if (!TS->is_valid_identifier(method_name.strip_edges())) { error->set_text(TTR("Method name must be a valid identifier.")); error->popup_centered(); return; @@ -228,7 +237,7 @@ StringName ConnectDialog::generate_method_callback_name(Node *p_source, String p String node_name = p_source->get_name(); for (int i = 0; i < node_name.length(); i++) { // TODO: Regex filter may be cleaner. char32_t c = node_name[i]; - if (!is_ascii_identifier_char(c)) { + if ((i == 0 && !is_unicode_identifier_start(c)) || (i > 0 && !is_unicode_identifier_continue(c))) { if (c == ' ') { // Replace spaces with underlines. c = '_'; @@ -338,11 +347,6 @@ void ConnectDialog::_update_method_tree() { // If a script is attached, get methods from it. ScriptInstance *si = target->get_script_instance(); if (si) { - TreeItem *si_item = method_tree->create_item(root_item); - si_item->set_text(0, TTR("Attached Script")); - si_item->set_icon(0, get_theme_icon(SNAME("Script"), SNAME("EditorIcons"))); - si_item->set_selectable(0, false); - if (si->get_script()->is_built_in()) { si->get_script()->reload(); } @@ -350,9 +354,12 @@ void ConnectDialog::_update_method_tree() { si->get_method_list(&methods); methods = _filter_method_list(methods, signal_info, search_string); - if (methods.is_empty()) { - si_item->set_custom_color(0, disabled_color); - } else { + if (!methods.is_empty()) { + TreeItem *si_item = method_tree->create_item(root_item); + si_item->set_text(0, TTR("Attached Script")); + si_item->set_icon(0, get_theme_icon(SNAME("Script"), SNAME("EditorIcons"))); + si_item->set_selectable(0, false); + _create_method_tree_items(methods, si_item); } } @@ -687,8 +694,10 @@ ConnectDialog::ConnectDialog() { method_tree->connect("item_activated", callable_mp((Window *)method_popup, &Window::hide)); empty_tree_label = memnew(Label(TTR("No method found matching given filters."))); - method_tree->add_child(empty_tree_label); - empty_tree_label->set_anchors_and_offsets_preset(Control::PRESET_CENTER); + method_popup->add_child(empty_tree_label); + empty_tree_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); + empty_tree_label->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER); + empty_tree_label->set_autowrap_mode(TextServer::AUTOWRAP_WORD); script_methods_only = memnew(CheckButton(TTR("Script Methods Only"))); method_vbc->add_child(script_methods_only); diff --git a/editor/connections_dialog.h b/editor/connections_dialog.h index e5375a3fc8..003d4125af 100644 --- a/editor/connections_dialog.h +++ b/editor/connections_dialog.h @@ -31,22 +31,20 @@ #ifndef CONNECTIONS_DIALOG_H #define CONNECTIONS_DIALOG_H -#include "editor/editor_inspector.h" -#include "editor/scene_tree_editor.h" -#include "scene/gui/button.h" -#include "scene/gui/check_box.h" #include "scene/gui/check_button.h" #include "scene/gui/dialogs.h" -#include "scene/gui/label.h" -#include "scene/gui/line_edit.h" -#include "scene/gui/menu_button.h" -#include "scene/gui/option_button.h" -#include "scene/gui/popup.h" -#include "scene/gui/popup_menu.h" -#include "scene/gui/spin_box.h" #include "scene/gui/tree.h" +class Button; +class CheckBox; class ConnectDialogBinds; +class EditorInspector; +class Label; +class LineEdit; +class OptionButton; +class PopupMenu; +class SceneTreeEditor; +class SpinBox; class ConnectDialog : public ConfirmationDialog { GDCLASS(ConnectDialog, ConfirmationDialog); diff --git a/editor/debugger/debug_adapter/debug_adapter_protocol.cpp b/editor/debugger/debug_adapter/debug_adapter_protocol.cpp index e5f74762f6..4a95047a71 100644 --- a/editor/debugger/debug_adapter/debug_adapter_protocol.cpp +++ b/editor/debugger/debug_adapter/debug_adapter_protocol.cpp @@ -970,6 +970,7 @@ void DebugAdapterProtocol::poll() { List<Ref<DAPeer>> to_delete; for (List<Ref<DAPeer>>::Element *E = clients.front(); E; E = E->next()) { Ref<DAPeer> peer = E->get(); + peer->connection->poll(); StreamPeerTCP::Status status = peer->connection->get_status(); if (status == StreamPeerTCP::STATUS_NONE || status == StreamPeerTCP::STATUS_ERROR) { to_delete.push_back(peer); diff --git a/editor/debugger/editor_debugger_tree.cpp b/editor/debugger/editor_debugger_tree.cpp index c67ac69946..65f8951c30 100644 --- a/editor/debugger/editor_debugger_tree.cpp +++ b/editor/debugger/editor_debugger_tree.cpp @@ -30,8 +30,8 @@ #include "editor_debugger_tree.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_node.h" +#include "editor/gui/editor_file_dialog.h" #include "editor/scene_tree_dock.h" #include "scene/debugger/scene_debugger.h" #include "scene/gui/texture_rect.h" diff --git a/editor/fileserver/editor_file_server.cpp b/editor/debugger/editor_file_server.cpp index ba5dd9e6e2..ba5dd9e6e2 100644 --- a/editor/fileserver/editor_file_server.cpp +++ b/editor/debugger/editor_file_server.cpp diff --git a/editor/fileserver/editor_file_server.h b/editor/debugger/editor_file_server.h index ff2742e73f..ff2742e73f 100644 --- a/editor/fileserver/editor_file_server.h +++ b/editor/debugger/editor_file_server.h diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp index f805a4aecd..a696e1ff1f 100644 --- a/editor/debugger/script_editor_debugger.cpp +++ b/editor/debugger/script_editor_debugger.cpp @@ -40,13 +40,13 @@ #include "editor/debugger/editor_performance_profiler.h" #include "editor/debugger/editor_profiler.h" #include "editor/debugger/editor_visual_profiler.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_file_system.h" #include "editor/editor_log.h" #include "editor/editor_node.h" #include "editor/editor_property_name_processor.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/gui/editor_file_dialog.h" #include "editor/inspector_dock.h" #include "editor/plugins/canvas_item_editor_plugin.h" #include "editor/plugins/editor_debugger_plugin.h" diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp index c98ec7b2d5..9cff7e3771 100644 --- a/editor/dependency_editor.cpp +++ b/editor/dependency_editor.cpp @@ -33,11 +33,11 @@ #include "core/config/project_settings.h" #include "core/io/file_access.h" #include "core/io/resource_loader.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_file_system.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/gui/editor_file_dialog.h" #include "scene/gui/margin_container.h" void DependencyEditor::_searched(const String &p_path) { diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index f2a0ec901f..9ed8cf7c21 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -34,12 +34,12 @@ #include "core/input/input.h" #include "core/io/resource_saver.h" #include "core/os/keyboard.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" -#include "filesystem_dock.h" +#include "editor/filesystem_dock.h" +#include "editor/gui/editor_file_dialog.h" #include "scene/gui/separator.h" #include "scene/resources/font.h" #include "servers/audio_server.h" diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp index a6defd0e14..7a1dc2e33b 100644 --- a/editor/editor_autoload_settings.cpp +++ b/editor/editor_autoload_settings.cpp @@ -32,12 +32,12 @@ #include "core/config/project_settings.h" #include "core/core_constants.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_undo_redo_manager.h" #include "editor/filesystem_dock.h" -#include "project_settings_editor.h" +#include "editor/gui/editor_file_dialog.h" +#include "editor/project_settings_editor.h" #include "scene/main/window.h" #include "scene/resources/packed_scene.h" diff --git a/editor/editor_build_profile.cpp b/editor/editor_build_profile.cpp index b112818e83..1377537245 100644 --- a/editor/editor_build_profile.cpp +++ b/editor/editor_build_profile.cpp @@ -32,13 +32,13 @@ #include "core/io/dir_access.h" #include "core/io/json.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_file_system.h" #include "editor/editor_node.h" #include "editor/editor_paths.h" #include "editor/editor_property_name_processor.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/gui/editor_file_dialog.h" const char *EditorBuildProfile::build_option_identifiers[BUILD_OPTION_MAX] = { // This maps to SCons build options. diff --git a/editor/editor_feature_profile.cpp b/editor/editor_feature_profile.cpp index f8bc37798a..7c77fec81a 100644 --- a/editor/editor_feature_profile.cpp +++ b/editor/editor_feature_profile.cpp @@ -32,12 +32,12 @@ #include "core/io/dir_access.h" #include "core/io/json.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_paths.h" #include "editor/editor_property_name_processor.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/gui/editor_file_dialog.h" const char *EditorFeatureProfile::feature_names[FEATURE_MAX] = { TTRC("3D Editor"), diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 87c4dabd8d..cd762002b2 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -2735,7 +2735,8 @@ void EditorInspector::update_tree() { List<PropertyInfo>::Element *N = E_property->next(); bool valid = true; while (N) { - if (!N->get().name.begins_with("metadata/_") && N->get().usage & PROPERTY_USAGE_EDITOR && (!restrict_to_basic || (N->get().usage & PROPERTY_USAGE_EDITOR_BASIC_SETTING))) { + if (!N->get().name.begins_with("metadata/_") && N->get().usage & PROPERTY_USAGE_EDITOR && + (!filter.is_empty() || !restrict_to_basic || (N->get().usage & PROPERTY_USAGE_EDITOR_BASIC_SETTING))) { break; } if (N->get().usage & PROPERTY_USAGE_CATEGORY) { @@ -2758,26 +2759,30 @@ void EditorInspector::update_tree() { doc_name = p.name; // Use category's owner script to update some of its information. - if (!EditorNode::get_editor_data().is_type_recognized(type) && p.hint_string.length() && FileAccess::exists(p.hint_string)) { - StringName script_name; - + if (!EditorNode::get_editor_data().is_type_recognized(type) && p.hint_string.length() && ResourceLoader::exists(p.hint_string)) { Ref<Script> scr = ResourceLoader::load(p.hint_string, "Script"); if (scr.is_valid()) { - script_name = EditorNode::get_editor_data().script_class_get_name(scr->get_path()); + StringName script_name = EditorNode::get_editor_data().script_class_get_name(scr->get_path()); // Update the docs reference and the label based on the script. Vector<DocData::ClassDoc> docs = scr->get_documentation(); if (!docs.is_empty()) { doc_name = docs[0].name; } - if (script_name != StringName() && label != script_name) { + if (script_name != StringName()) { label = script_name; } + + // Find the icon corresponding to the script. + if (script_name != StringName()) { + category->icon = EditorNode::get_singleton()->get_class_icon(script_name, "Object"); + } else { + category->icon = EditorNode::get_singleton()->get_object_icon(scr.ptr(), "Object"); + } } + } - // Find the corresponding icon. - category->icon = EditorNode::get_singleton()->get_class_icon(script_name, "Object"); - } else if (!type.is_empty()) { + if (category->icon.is_null() && !type.is_empty()) { category->icon = EditorNode::get_singleton()->get_class_icon(type, "Object"); } @@ -2807,7 +2812,8 @@ void EditorInspector::update_tree() { continue; - } else if (p.name.begins_with("metadata/_") || !(p.usage & PROPERTY_USAGE_EDITOR) || _is_property_disabled_by_feature_profile(p.name) || (restrict_to_basic && !(p.usage & PROPERTY_USAGE_EDITOR_BASIC_SETTING))) { + } else if (p.name.begins_with("metadata/_") || !(p.usage & PROPERTY_USAGE_EDITOR) || _is_property_disabled_by_feature_profile(p.name) || + (filter.is_empty() && restrict_to_basic && !(p.usage & PROPERTY_USAGE_EDITOR_BASIC_SETTING))) { // Ignore properties that are not supposed to be in the inspector. continue; } diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp index 1f43ee53fa..8d199ad989 100644 --- a/editor/editor_log.cpp +++ b/editor/editor_log.cpp @@ -91,8 +91,11 @@ void EditorLog::_update_theme() { log->add_theme_font_override("mono_font", mono_font); } - log->add_theme_font_size_override("normal_font_size", get_theme_font_size(SNAME("output_source_size"), SNAME("EditorFonts"))); - log->add_theme_color_override("selection_color", get_theme_color(SNAME("accent_color"), SNAME("Editor")) * Color(1, 1, 1, 0.4)); + const int font_size = get_theme_font_size(SNAME("output_source_size"), SNAME("EditorFonts")); + log->add_theme_font_size_override("normal_font_size", font_size); + log->add_theme_font_size_override("bold_font_size", font_size); + log->add_theme_font_size_override("italics_font_size", font_size); + log->add_theme_font_size_override("mono_font_size", font_size); type_filter_map[MSG_TYPE_STD]->toggle_button->set_icon(get_theme_icon(SNAME("Popup"), SNAME("EditorIcons"))); type_filter_map[MSG_TYPE_ERROR]->toggle_button->set_icon(get_theme_icon(SNAME("StatusError"), SNAME("EditorIcons"))); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 2fc229f9f2..057f8e4ce4 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -72,12 +72,12 @@ #include "editor/editor_command_palette.h" #include "editor/editor_data.h" #include "editor/editor_feature_profile.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_folding.h" #include "editor/editor_help.h" #include "editor/editor_inspector.h" #include "editor/editor_layouts_dialog.h" #include "editor/editor_log.h" +#include "editor/editor_native_shader_source_visualizer.h" #include "editor/editor_paths.h" #include "editor/editor_plugin.h" #include "editor/editor_properties.h" @@ -90,7 +90,6 @@ #include "editor/editor_settings.h" #include "editor/editor_settings_dialog.h" #include "editor/editor_themes.h" -#include "editor/editor_toaster.h" #include "editor/editor_translation_parser.h" #include "editor/editor_undo_redo_manager.h" #include "editor/export/editor_export.h" @@ -98,6 +97,9 @@ #include "editor/export/project_export.h" #include "editor/fbx_importer_manager.h" #include "editor/filesystem_dock.h" +#include "editor/gui/editor_file_dialog.h" +#include "editor/gui/editor_title_bar.h" +#include "editor/gui/editor_toaster.h" #include "editor/history_dock.h" #include "editor/import/audio_stream_import_settings.h" #include "editor/import/dynamic_font_import_settings.h" @@ -1143,7 +1145,7 @@ void EditorNode::_scan_external_changes() { } if (need_reload) { - disk_changed->call_deferred(SNAME("popup_centered_ratio"), 0.5); + disk_changed->call_deferred(SNAME("popup_centered_ratio"), 0.3); } } @@ -3011,6 +3013,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { save_confirmation->set_ok_button_text(TTR("Save & Quit")); save_confirmation->set_text(TTR("Save modified resources before closing?")); } + save_confirmation->reset_size(); save_confirmation->popup_centered(); break; } @@ -3039,6 +3042,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { save_confirmation->set_ok_button_text(TTR("Save & Quit")); save_confirmation->set_text((p_option == FILE_QUIT ? TTR("Save changes to the following scene(s) before quitting?") : TTR("Save changes to the following scene(s) before opening Project Manager?")) + unsaved_scenes); } + save_confirmation->reset_size(); save_confirmation->popup_centered(); } @@ -5471,6 +5475,7 @@ void EditorNode::_scene_tab_closed(int p_tab, int p_option) { save_confirmation->set_ok_button_text(TTR("Save & Close")); save_confirmation->set_text(vformat(TTR("Save changes to '%s' before closing?"), !scene_filename.is_empty() ? scene_filename : "unsaved scene")); } + save_confirmation->reset_size(); save_confirmation->popup_centered(); } else { _discard_changes(); @@ -7770,6 +7775,7 @@ EditorNode::EditorNode() { save_confirmation = memnew(ConfirmationDialog); save_confirmation->add_button(TTR("Don't Save"), DisplayServer::get_singleton()->get_swap_cancel_ok(), "discard"); gui_base->add_child(save_confirmation); + save_confirmation->set_min_size(Vector2(450.0 * EDSCALE, 0)); save_confirmation->connect("confirmed", callable_mp(this, &EditorNode::_menu_confirm_current)); save_confirmation->connect("custom_action", callable_mp(this, &EditorNode::_discard_changes)); diff --git a/editor/editor_node.h b/editor/editor_node.h index f9ba2b8b17..8f17932cb0 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -34,10 +34,8 @@ #include "core/templates/safe_refcount.h" #include "editor/editor_data.h" #include "editor/editor_folding.h" -#include "editor/editor_native_shader_source_visualizer.h" #include "editor/editor_plugin.h" #include "editor/editor_run.h" -#include "editor/editor_title_bar.h" #include "editor/export/editor_export.h" typedef void (*EditorNodeInitCallback)(); @@ -46,71 +44,73 @@ typedef bool (*EditorBuildCallback)(); class AcceptDialog; class AcceptDialogAutoReparent; -class AudioStreamPreviewGenerator; -class BackgroundProgress; class CenterContainer; class CheckBox; class ColorPicker; class ConfirmationDialog; class Control; +class FileDialog; +class HBoxContainer; +class HSplitContainer; +class LinkButton; +class MenuBar; +class MenuButton; +class Node2D; +class OptionButton; +class Panel; +class PanelContainer; +class SubViewport; +class TabBar; +class TabContainer; +class TextureRect; +class TextureProgressBar; +class Tree; +class VSplitContainer; +class Window; + +class AudioStreamImportSettings; +class AudioStreamPreviewGenerator; +class BackgroundProgress; class DependencyEditor; class DependencyErrorDialog; class DynamicFontImportSettings; class EditorAbout; +class EditorBuildProfileManager; class EditorCommandPalette; class EditorExport; class EditorExtensionManager; class EditorFeatureProfileManager; class EditorFileDialog; -class EditorFileServer; class EditorFolding; class EditorInspector; class EditorLayoutsDialog; class EditorLog; +class EditorNativeShaderSourceVisualizer; class EditorPluginList; class EditorQuickOpen; class EditorPropertyResource; class EditorResourcePreview; class EditorResourceConversionPlugin; -class EditorRun; class EditorRunNative; class EditorSelectionHistory; class EditorSettingsDialog; +class EditorTitleBar; class EditorToaster; class EditorUndoRedoManager; class ExportTemplateManager; class FBXImporterManager; -class FileDialog; class FileSystemDock; class HistoryDock; -class HSplitContainer; class ImportDock; -class LinkButton; -class MenuBar; -class MenuButton; -class Node2D; class NodeDock; -class OptionButton; class OrphanResourcesDialog; -class Panel; -class PanelContainer; class PluginConfigDialog; class ProgressDialog; class ProjectExportDialog; class ProjectSettingsEditor; class RunSettingsDialog; class SceneImportSettings; -class AudioStreamImportSettings; class ScriptCreateDialog; -class SubViewport; -class TabBar; -class TabContainer; -class TextureRect; -class TextureProgressBar; -class Tree; -class VSplitContainer; -class Window; -class EditorBuildProfileManager; class EditorNode : public Node { GDCLASS(EditorNode, Node); @@ -738,7 +738,7 @@ public: static EditorData &get_editor_data() { return singleton->editor_data; } static EditorFolding &get_editor_folding() { return singleton->editor_folding; } - static HBoxContainer *get_menu_hb() { return singleton->menu_hb; } + static EditorTitleBar *get_menu_hb() { return singleton->menu_hb; } static VSplitContainer *get_top_split() { return singleton->top_split; } static String adjust_scene_name_casing(const String &root_name); diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index fb2110dea3..9281965e6f 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -40,6 +40,7 @@ #include "editor/editor_undo_redo_manager.h" #include "editor/export/editor_export.h" #include "editor/filesystem_dock.h" +#include "editor/gui/editor_title_bar.h" #include "editor/import/editor_import_plugin.h" #include "editor/import/resource_importer_scene.h" #include "editor/inspector_dock.h" diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index 5147237ac2..9f8b12e029 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -33,17 +33,18 @@ #include "core/config/project_settings.h" #include "core/core_string_names.h" #include "editor/create_dialog.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_properties_array_dict.h" #include "editor/editor_resource_picker.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/gui/editor_file_dialog.h" +#include "editor/gui/editor_spin_slider.h" +#include "editor/gui/scene_tree_editor.h" #include "editor/inspector_dock.h" #include "editor/plugins/script_editor_plugin.h" #include "editor/project_settings_editor.h" #include "editor/property_selector.h" -#include "editor/scene_tree_editor.h" #include "scene/2d/gpu_particles_2d.h" #include "scene/3d/fog_volume.h" #include "scene/3d/gpu_particles_3d.h" diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp index 80ebd32295..f7c789a453 100644 --- a/editor/editor_properties_array_dict.cpp +++ b/editor/editor_properties_array_dict.cpp @@ -35,7 +35,9 @@ #include "editor/editor_properties.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/gui/editor_spin_slider.h" #include "editor/inspector_dock.h" +#include "scene/gui/button.h" bool EditorPropertyArrayObject::_set(const StringName &p_name, const Variant &p_value) { String name = p_name; diff --git a/editor/editor_properties_array_dict.h b/editor/editor_properties_array_dict.h index 3b880c60a8..2ca1931f85 100644 --- a/editor/editor_properties_array_dict.h +++ b/editor/editor_properties_array_dict.h @@ -33,9 +33,10 @@ #include "editor/editor_inspector.h" #include "editor/editor_locale_dialog.h" -#include "editor/editor_spin_slider.h" #include "editor/filesystem_dock.h" -#include "scene/gui/button.h" + +class Button; +class EditorSpinSlider; class EditorPropertyArrayObject : public RefCounted { GDCLASS(EditorPropertyArrayObject, RefCounted); diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp index 4e7b7a8434..2d6feac007 100644 --- a/editor/editor_resource_picker.cpp +++ b/editor/editor_resource_picker.cpp @@ -31,13 +31,13 @@ #include "editor_resource_picker.h" #include "editor/audio_stream_preview.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_quick_open.h" #include "editor/editor_resource_preview.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/filesystem_dock.h" +#include "editor/gui/editor_file_dialog.h" #include "editor/plugins/editor_resource_conversion_plugin.h" #include "editor/plugins/script_editor_plugin.h" #include "editor/scene_tree_dock.h" diff --git a/editor/editor_sectioned_inspector.cpp b/editor/editor_sectioned_inspector.cpp index 3988d356b3..8716a75efd 100644 --- a/editor/editor_sectioned_inspector.cpp +++ b/editor/editor_sectioned_inspector.cpp @@ -239,7 +239,8 @@ void SectionedInspector::update_category_list() { for (PropertyInfo &pi : pinfo) { if (pi.usage & PROPERTY_USAGE_CATEGORY) { continue; - } else if (!(pi.usage & PROPERTY_USAGE_EDITOR) || (restrict_to_basic && !(pi.usage & PROPERTY_USAGE_EDITOR_BASIC_SETTING))) { + } else if (!(pi.usage & PROPERTY_USAGE_EDITOR) || + (filter_text.is_empty() && restrict_to_basic && !(pi.usage & PROPERTY_USAGE_EDITOR_BASIC_SETTING))) { continue; } diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 25c84e7447..835eecdeb3 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -1488,7 +1488,9 @@ void ED_SHORTCUT_OVERRIDE_ARRAY(const String &p_path, const String &p_feature, c // Only add the override if the OS supports the provided feature. if (!OS::get_singleton()->has_feature(p_feature)) { - return; + if (!(p_feature == "macos" && (OS::get_singleton()->has_feature("web_macos") || OS::get_singleton()->has_feature("web_ios")))) { + return; + } } Array events; @@ -1496,12 +1498,12 @@ void ED_SHORTCUT_OVERRIDE_ARRAY(const String &p_path, const String &p_feature, c for (int i = 0; i < p_keycodes.size(); i++) { Key keycode = (Key)p_keycodes[i]; -#ifdef MACOS_ENABLED - // Use Cmd+Backspace as a general replacement for Delete shortcuts on macOS - if (keycode == Key::KEY_DELETE) { - keycode = KeyModifierMask::META | Key::BACKSPACE; + if (OS::get_singleton()->has_feature("macos") || OS::get_singleton()->has_feature("web_macos") || OS::get_singleton()->has_feature("web_ios")) { + // Use Cmd+Backspace as a general replacement for Delete shortcuts on macOS + if (keycode == Key::KEY_DELETE) { + keycode = KeyModifierMask::META | Key::BACKSPACE; + } } -#endif Ref<InputEventKey> ie; if (keycode != Key::NONE) { @@ -1530,12 +1532,12 @@ Ref<Shortcut> ED_SHORTCUT_ARRAY(const String &p_path, const String &p_name, cons for (int i = 0; i < p_keycodes.size(); i++) { Key keycode = (Key)p_keycodes[i]; -#ifdef MACOS_ENABLED - // Use Cmd+Backspace as a general replacement for Delete shortcuts on macOS - if (keycode == Key::KEY_DELETE) { - keycode = KeyModifierMask::META | Key::BACKSPACE; + if (OS::get_singleton()->has_feature("macos") || OS::get_singleton()->has_feature("web_macos") || OS::get_singleton()->has_feature("web_ios")) { + // Use Cmd+Backspace as a general replacement for Delete shortcuts on macOS + if (keycode == Key::KEY_DELETE) { + keycode = KeyModifierMask::META | Key::BACKSPACE; + } } -#endif Ref<InputEventKey> ie; if (keycode != Key::NONE) { diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 8ae1185923..43c5d1d6cd 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -836,7 +836,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("font_focus_color", "MenuButton", font_focus_color); theme->set_color("font_outline_color", "MenuButton", font_outline_color); - theme->set_constant("outline_size", "MenuButton", 0 * EDSCALE); + theme->set_constant("outline_size", "MenuButton", 0); theme->set_stylebox("MenuHover", "EditorStyles", style_widget_hover); @@ -862,7 +862,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("icon_disabled_color", "Button", icon_disabled_color); theme->set_constant("h_separation", "Button", 2 * EDSCALE); - theme->set_constant("outline_size", "Button", 0 * EDSCALE); + theme->set_constant("outline_size", "Button", 0); const float ACTION_BUTTON_EXTRA_MARGIN = 32 * EDSCALE; @@ -919,7 +919,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("icon_disabled_color", "MenuBar", icon_disabled_color); theme->set_constant("h_separation", "MenuBar", 4 * EDSCALE); - theme->set_constant("outline_size", "MenuBar", 0 * EDSCALE); + theme->set_constant("outline_size", "MenuBar", 0); // OptionButton Ref<StyleBoxFlat> style_option_button_focus = style_widget_focus->duplicate(); @@ -963,7 +963,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_constant("arrow_margin", "OptionButton", widget_default_margin.x - 2 * EDSCALE); theme->set_constant("modulate_arrow", "OptionButton", true); theme->set_constant("h_separation", "OptionButton", 4 * EDSCALE); - theme->set_constant("outline_size", "OptionButton", 0 * EDSCALE); + theme->set_constant("outline_size", "OptionButton", 0); // CheckButton theme->set_stylebox("normal", "CheckButton", style_menu); @@ -997,8 +997,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("icon_disabled_color", "CheckButton", icon_disabled_color); theme->set_constant("h_separation", "CheckButton", 8 * EDSCALE); - theme->set_constant("check_v_offset", "CheckButton", 0 * EDSCALE); - theme->set_constant("outline_size", "CheckButton", 0 * EDSCALE); + theme->set_constant("check_v_offset", "CheckButton", 0); + theme->set_constant("outline_size", "CheckButton", 0); // Checkbox Ref<StyleBoxFlat> sb_checkbox = style_menu->duplicate(); @@ -1033,8 +1033,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("icon_disabled_color", "CheckBox", icon_disabled_color); theme->set_constant("h_separation", "CheckBox", 8 * EDSCALE); - theme->set_constant("check_v_offset", "CheckBox", 0 * EDSCALE); - theme->set_constant("outline_size", "CheckBox", 0 * EDSCALE); + theme->set_constant("check_v_offset", "CheckBox", 0); + theme->set_constant("outline_size", "CheckBox", 0); // PopupDialog theme->set_stylebox("panel", "PopupDialog", style_popup); @@ -1089,7 +1089,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { const int vsep_base = extra_spacing + default_margin_size + 6; const int force_even_vsep = vsep_base + (vsep_base % 2); theme->set_constant("v_separation", "PopupMenu", force_even_vsep * EDSCALE); - theme->set_constant("outline_size", "PopupMenu", 0 * EDSCALE); + theme->set_constant("outline_size", "PopupMenu", 0); theme->set_constant("item_start_padding", "PopupMenu", default_margin_size * 1.5 * EDSCALE); theme->set_constant("item_end_padding", "PopupMenu", default_margin_size * 1.5 * EDSCALE); @@ -1208,7 +1208,13 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_constant("button_margin", "Tree", default_margin_size * EDSCALE); theme->set_constant("scroll_border", "Tree", 40 * EDSCALE); theme->set_constant("scroll_speed", "Tree", 12); - theme->set_constant("outline_size", "Tree", 0 * EDSCALE); + theme->set_constant("outline_size", "Tree", 0); + theme->set_constant("scrollbar_margin_left", "Tree", 0); + theme->set_constant("scrollbar_margin_top", "Tree", 0); + theme->set_constant("scrollbar_margin_right", "Tree", 0); + theme->set_constant("scrollbar_margin_bottom", "Tree", 0); + theme->set_constant("scrollbar_h_separation", "Tree", 1 * EDSCALE); + theme->set_constant("scrollbar_v_separation", "Tree", 1 * EDSCALE); const Color guide_color = mono_color * Color(1, 1, 1, 0.05); Color relationship_line_color = mono_color * Color(1, 1, 1, relationship_line_opacity); @@ -1304,7 +1310,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_constant("h_separation", "ItemList", 6 * EDSCALE); theme->set_constant("icon_margin", "ItemList", 6 * EDSCALE); theme->set_constant("line_separation", "ItemList", 3 * EDSCALE); - theme->set_constant("outline_size", "ItemList", 0 * EDSCALE); + theme->set_constant("outline_size", "ItemList", 0); // TabBar & TabContainer Ref<StyleBoxFlat> style_tabbar_background = make_flat_stylebox(dark_color_1, 0, 0, 0, 0, corner_radius * EDSCALE); @@ -1342,9 +1348,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_icon("drop_mark", "TabContainer", theme->get_icon(SNAME("GuiTabDropMark"), SNAME("EditorIcons"))); theme->set_icon("drop_mark", "TabBar", theme->get_icon(SNAME("GuiTabDropMark"), SNAME("EditorIcons"))); theme->set_constant("side_margin", "TabContainer", 0); - theme->set_constant("outline_size", "TabContainer", 0 * EDSCALE); + theme->set_constant("outline_size", "TabContainer", 0); theme->set_constant("h_separation", "TabBar", 4 * EDSCALE); - theme->set_constant("outline_size", "TabBar", 0 * EDSCALE); + theme->set_constant("outline_size", "TabBar", 0); // Content of each tab. Ref<StyleBoxFlat> style_content_panel = style_default->duplicate(); @@ -1409,9 +1415,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // so this compensates for that. style_line_edit->set_content_margin(SIDE_TOP, style_line_edit->get_content_margin(SIDE_TOP) - 1 * EDSCALE); - // Don't round the bottom corner to make the line look sharper. - style_tab_selected->set_corner_radius(CORNER_BOTTOM_LEFT, 0); - style_tab_selected->set_corner_radius(CORNER_BOTTOM_RIGHT, 0); + // Don't round the bottom corners to make the line look sharper. + style_line_edit->set_corner_radius(CORNER_BOTTOM_LEFT, 0); + style_line_edit->set_corner_radius(CORNER_BOTTOM_RIGHT, 0); if (draw_extra_borders) { style_line_edit->set_border_width_all(Math::round(EDSCALE)); @@ -1440,7 +1446,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("selection_color", "LineEdit", selection_color); theme->set_color("clear_button_color", "LineEdit", font_color); theme->set_color("clear_button_color_pressed", "LineEdit", accent_color); - theme->set_constant("outline_size", "LineEdit", 0 * EDSCALE); + theme->set_constant("outline_size", "LineEdit", 0); // TextEdit theme->set_stylebox("normal", "TextEdit", style_line_edit); @@ -1457,7 +1463,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("background_color", "TextEdit", Color(0, 0, 0, 0)); theme->set_constant("line_spacing", "TextEdit", 4 * EDSCALE); - theme->set_constant("outline_size", "TextEdit", 0 * EDSCALE); + theme->set_constant("outline_size", "TextEdit", 0); theme->set_icon("h_grabber", "SplitContainer", theme->get_icon(SNAME("GuiHsplitter"), SNAME("EditorIcons"))); theme->set_icon("v_grabber", "SplitContainer", theme->get_icon(SNAME("GuiVsplitter"), SNAME("EditorIcons"))); @@ -1591,10 +1597,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("default_color", "RichTextLabel", font_color); theme->set_color("font_shadow_color", "RichTextLabel", Color(0, 0, 0, 0)); theme->set_color("font_outline_color", "RichTextLabel", font_outline_color); + theme->set_color("selection_color", "RichTextLabel", selection_color); theme->set_constant("shadow_offset_x", "RichTextLabel", 1 * EDSCALE); theme->set_constant("shadow_offset_y", "RichTextLabel", 1 * EDSCALE); theme->set_constant("shadow_outline_size", "RichTextLabel", 1 * EDSCALE); - theme->set_constant("outline_size", "RichTextLabel", 0 * EDSCALE); + theme->set_constant("outline_size", "RichTextLabel", 0); theme->set_stylebox("focus", "RichTextLabel", make_empty_stylebox()); theme->set_stylebox("normal", "RichTextLabel", style_tree_bg); @@ -1612,7 +1619,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("value_color", "EditorHelp", font_color * Color(1, 1, 1, 0.6)); theme->set_color("qualifier_color", "EditorHelp", font_color * Color(1, 1, 1, 0.8)); theme->set_color("type_color", "EditorHelp", accent_color.lerp(font_color, 0.5)); - theme->set_color("selection_color", "EditorHelp", accent_color * Color(1, 1, 1, 0.4)); + theme->set_color("selection_color", "EditorHelp", selection_color); theme->set_color("link_color", "EditorHelp", accent_color.lerp(mono_color, 0.8)); theme->set_color("code_color", "EditorHelp", accent_color.lerp(mono_color, 0.6)); theme->set_color("kbd_color", "EditorHelp", accent_color.lerp(property_color, 0.6)); @@ -1638,7 +1645,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_constant("shadow_offset_y", "Label", 1 * EDSCALE); theme->set_constant("shadow_outline_size", "Label", 1 * EDSCALE); theme->set_constant("line_spacing", "Label", 3 * EDSCALE); - theme->set_constant("outline_size", "Label", 0 * EDSCALE); + theme->set_constant("outline_size", "Label", 0); // LinkButton theme->set_stylebox("focus", "LinkButton", style_empty); @@ -1650,7 +1657,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("font_disabled_color", "LinkButton", font_disabled_color); theme->set_color("font_outline_color", "LinkButton", font_outline_color); - theme->set_constant("outline_size", "LinkButton", 0 * EDSCALE); + theme->set_constant("outline_size", "LinkButton", 0); // TooltipPanel + TooltipLabel // TooltipPanel is also used for custom tooltips, while TooltipLabel @@ -1687,7 +1694,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("fill", "ProgressBar", make_stylebox(theme->get_icon(SNAME("GuiProgressFill"), SNAME("EditorIcons")), 6, 6, 6, 6, 2, 1, 2, 1)); theme->set_color("font_color", "ProgressBar", font_color); theme->set_color("font_outline_color", "ProgressBar", font_outline_color); - theme->set_constant("outline_size", "ProgressBar", 0 * EDSCALE); + theme->set_constant("outline_size", "ProgressBar", 0); // GraphEdit theme->set_stylebox("bg", "GraphEdit", style_tree_bg); diff --git a/editor/event_listener_line_edit.cpp b/editor/event_listener_line_edit.cpp index ee401810ad..fa494636ea 100644 --- a/editor/event_listener_line_edit.cpp +++ b/editor/event_listener_line_edit.cpp @@ -65,11 +65,11 @@ String EventListenerLineEdit::get_event_text(const Ref<InputEvent> &p_event, boo String mods_text = key->InputEventWithModifiers::as_text(); mods_text = mods_text.is_empty() ? mods_text : mods_text + "+"; if (key->is_command_or_control_autoremap()) { -#ifdef MACOS_ENABLED - mods_text = mods_text.replace("Command", "Command/Ctrl"); -#else - mods_text = mods_text.replace("Ctrl", "Command/Ctrl"); -#endif + if (OS::get_singleton()->has_feature("macos") || OS::get_singleton()->has_feature("web_macos") || OS::get_singleton()->has_feature("web_ios")) { + mods_text = mods_text.replace("Command", "Command/Ctrl"); + } else { + mods_text = mods_text.replace("Ctrl", "Command/Ctrl"); + } } if (key->get_keycode() != Key::NONE) { diff --git a/editor/export/project_export.cpp b/editor/export/project_export.cpp index 2516e5df96..95c79ab58c 100644 --- a/editor/export/project_export.cpp +++ b/editor/export/project_export.cpp @@ -32,13 +32,13 @@ #include "core/config/project_settings.h" #include "core/version.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_file_system.h" #include "editor/editor_node.h" #include "editor/editor_properties.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/export/editor_export.h" +#include "editor/gui/editor_file_dialog.h" #include "scene/gui/check_box.h" #include "scene/gui/check_button.h" #include "scene/gui/item_list.h" @@ -47,6 +47,7 @@ #include "scene/gui/option_button.h" #include "scene/gui/popup_menu.h" #include "scene/gui/split_container.h" +#include "scene/gui/tab_container.h" #include "scene/gui/texture_rect.h" #include "scene/gui/tree.h" diff --git a/editor/fbx_importer_manager.h b/editor/fbx_importer_manager.h index dd5fcfd16e..55061c041a 100644 --- a/editor/fbx_importer_manager.h +++ b/editor/fbx_importer_manager.h @@ -31,7 +31,7 @@ #ifndef FBX_IMPORTER_MANAGER_H #define FBX_IMPORTER_MANAGER_H -#include "editor/editor_file_dialog.h" +#include "editor/gui/editor_file_dialog.h" #include "scene/gui/dialogs.h" #include "scene/gui/line_edit.h" diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index e96f902b64..066e8cb84e 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -37,17 +37,22 @@ #include "core/os/keyboard.h" #include "core/os/os.h" #include "core/templates/list.h" +#include "editor/create_dialog.h" #include "editor/editor_feature_profile.h" #include "editor/editor_node.h" #include "editor/editor_resource_preview.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/gui/editor_dir_dialog.h" #include "editor/import/resource_importer_scene.h" #include "editor/import_dock.h" #include "editor/scene_create_dialog.h" #include "editor/scene_tree_dock.h" #include "editor/shader_create_dialog.h" +#include "scene/gui/item_list.h" #include "scene/gui/label.h" +#include "scene/gui/line_edit.h" +#include "scene/gui/progress_bar.h" #include "scene/main/window.h" #include "scene/resources/packed_scene.h" #include "servers/display_server.h" diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index 35ca3eaccb..7c67be44be 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -31,22 +31,22 @@ #ifndef FILESYSTEM_DOCK_H #define FILESYSTEM_DOCK_H -#include "editor/create_dialog.h" #include "editor/dependency_editor.h" -#include "editor/editor_dir_dialog.h" #include "editor/editor_file_system.h" #include "editor/plugins/script_editor_plugin.h" #include "editor/script_create_dialog.h" #include "scene/gui/box_container.h" #include "scene/gui/control.h" #include "scene/gui/dialogs.h" -#include "scene/gui/item_list.h" -#include "scene/gui/line_edit.h" #include "scene/gui/menu_button.h" -#include "scene/gui/progress_bar.h" #include "scene/gui/split_container.h" #include "scene/gui/tree.h" +class CreateDialog; +class EditorDirDialog; +class ItemList; +class LineEdit; +class ProgressBar; class SceneCreateDialog; class ShaderCreateDialog; diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp index 7f0417ea29..37b4654113 100644 --- a/editor/groups_editor.cpp +++ b/editor/groups_editor.cpp @@ -33,10 +33,12 @@ #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/gui/scene_tree_editor.h" #include "editor/scene_tree_dock.h" -#include "editor/scene_tree_editor.h" -#include "scene/gui/box_container.h" +#include "scene/gui/button.h" #include "scene/gui/label.h" +#include "scene/gui/line_edit.h" +#include "scene/gui/tree.h" #include "scene/resources/packed_scene.h" static bool can_edit(Node *p_node, String p_group) { diff --git a/editor/groups_editor.h b/editor/groups_editor.h index cd9d458f4b..27322b63da 100644 --- a/editor/groups_editor.h +++ b/editor/groups_editor.h @@ -31,13 +31,12 @@ #ifndef GROUPS_EDITOR_H #define GROUPS_EDITOR_H -#include "editor/scene_tree_editor.h" -#include "scene/gui/button.h" #include "scene/gui/dialogs.h" -#include "scene/gui/item_list.h" -#include "scene/gui/line_edit.h" -#include "scene/gui/popup.h" -#include "scene/gui/tree.h" + +class Button; +class LineEdit; +class Tree; +class TreeItem; class GroupDialog : public AcceptDialog { GDCLASS(GroupDialog, AcceptDialog); diff --git a/editor/fileserver/SCsub b/editor/gui/SCsub index 359d04e5df..359d04e5df 100644 --- a/editor/fileserver/SCsub +++ b/editor/gui/SCsub diff --git a/editor/editor_dir_dialog.cpp b/editor/gui/editor_dir_dialog.cpp index 9da592d639..9da592d639 100644 --- a/editor/editor_dir_dialog.cpp +++ b/editor/gui/editor_dir_dialog.cpp diff --git a/editor/editor_dir_dialog.h b/editor/gui/editor_dir_dialog.h index 9f2b48c164..9f2b48c164 100644 --- a/editor/editor_dir_dialog.h +++ b/editor/gui/editor_dir_dialog.h diff --git a/editor/editor_file_dialog.cpp b/editor/gui/editor_file_dialog.cpp index 192f4b2edb..62e0520799 100644 --- a/editor/editor_file_dialog.cpp +++ b/editor/gui/editor_file_dialog.cpp @@ -34,7 +34,7 @@ #include "core/io/file_access.h" #include "core/os/keyboard.h" #include "core/os/os.h" -#include "dependency_editor.h" +#include "editor/dependency_editor.h" #include "editor/editor_file_system.h" #include "editor/editor_node.h" #include "editor/editor_resource_preview.h" diff --git a/editor/editor_file_dialog.h b/editor/gui/editor_file_dialog.h index 923c7080c5..923c7080c5 100644 --- a/editor/editor_file_dialog.h +++ b/editor/gui/editor_file_dialog.h diff --git a/editor/editor_path.cpp b/editor/gui/editor_object_selector.cpp index bb464ee366..9988e285c7 100644 --- a/editor/editor_path.cpp +++ b/editor/gui/editor_object_selector.cpp @@ -1,5 +1,5 @@ /**************************************************************************/ -/* editor_path.cpp */ +/* editor_object_selector.cpp */ /**************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,20 +28,20 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#include "editor_path.h" +#include "editor_object_selector.h" #include "editor/editor_data.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/multi_node_edit.h" -Size2 EditorPath::get_minimum_size() const { +Size2 EditorObjectSelector::get_minimum_size() const { Ref<Font> font = get_theme_font(SNAME("font")); int font_size = get_theme_font_size(SNAME("font_size")); return Button::get_minimum_size() + Size2(0, font->get_height(font_size)); } -void EditorPath::_add_children_to_popup(Object *p_obj, int p_depth) { +void EditorObjectSelector::_add_children_to_popup(Object *p_obj, int p_depth) { if (p_depth > 8) { return; } @@ -86,7 +86,7 @@ void EditorPath::_add_children_to_popup(Object *p_obj, int p_depth) { } } -void EditorPath::_show_popup() { +void EditorObjectSelector::_show_popup() { if (sub_objects_menu->is_visible()) { sub_objects_menu->hide(); return; @@ -106,7 +106,7 @@ void EditorPath::_show_popup() { sub_objects_menu->popup(); } -void EditorPath::_about_to_show() { +void EditorObjectSelector::_about_to_show() { Object *obj = ObjectDB::get_instance(history->get_path_object(history->get_path_size() - 1)); if (!obj) { return; @@ -121,7 +121,7 @@ void EditorPath::_about_to_show() { } } -void EditorPath::update_path() { +void EditorObjectSelector::update_path() { for (int i = 0; i < history->get_path_size(); i++) { Object *obj = ObjectDB::get_instance(history->get_path_object(i)); if (!obj) { @@ -170,7 +170,7 @@ void EditorPath::update_path() { } } -void EditorPath::clear_path() { +void EditorObjectSelector::clear_path() { set_disabled(true); set_tooltip_text(""); @@ -179,12 +179,12 @@ void EditorPath::clear_path() { sub_objects_icon->hide(); } -void EditorPath::enable_path() { +void EditorObjectSelector::enable_path() { set_disabled(false); sub_objects_icon->show(); } -void EditorPath::_id_pressed(int p_idx) { +void EditorObjectSelector::_id_pressed(int p_idx) { ERR_FAIL_INDEX(p_idx, objects.size()); Object *obj = ObjectDB::get_instance(objects[p_idx]); @@ -195,7 +195,7 @@ void EditorPath::_id_pressed(int p_idx) { EditorNode::get_singleton()->push_item(obj); } -void EditorPath::_notification(int p_what) { +void EditorObjectSelector::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { @@ -210,15 +210,15 @@ void EditorPath::_notification(int p_what) { } break; case NOTIFICATION_READY: { - connect("pressed", callable_mp(this, &EditorPath::_show_popup)); + connect("pressed", callable_mp(this, &EditorObjectSelector::_show_popup)); } break; } } -void EditorPath::_bind_methods() { +void EditorObjectSelector::_bind_methods() { } -EditorPath::EditorPath(EditorSelectionHistory *p_history) { +EditorObjectSelector::EditorObjectSelector(EditorSelectionHistory *p_history) { history = p_history; MarginContainer *main_mc = memnew(MarginContainer); @@ -249,8 +249,8 @@ EditorPath::EditorPath(EditorSelectionHistory *p_history) { sub_objects_menu = memnew(PopupMenu); sub_objects_menu->set_auto_translate(false); add_child(sub_objects_menu); - sub_objects_menu->connect("about_to_popup", callable_mp(this, &EditorPath::_about_to_show)); - sub_objects_menu->connect("id_pressed", callable_mp(this, &EditorPath::_id_pressed)); + sub_objects_menu->connect("about_to_popup", callable_mp(this, &EditorObjectSelector::_about_to_show)); + sub_objects_menu->connect("id_pressed", callable_mp(this, &EditorObjectSelector::_id_pressed)); set_tooltip_text(TTR("Open a list of sub-resources.")); } diff --git a/editor/editor_path.h b/editor/gui/editor_object_selector.h index b6778b682e..72ff285cf6 100644 --- a/editor/editor_path.h +++ b/editor/gui/editor_object_selector.h @@ -1,5 +1,5 @@ /**************************************************************************/ -/* editor_path.h */ +/* editor_object_selector.h */ /**************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef EDITOR_PATH_H -#define EDITOR_PATH_H +#ifndef EDITOR_OBJECT_SELECTOR_H +#define EDITOR_OBJECT_SELECTOR_H #include "scene/gui/box_container.h" #include "scene/gui/button.h" @@ -39,8 +39,8 @@ class EditorSelectionHistory; -class EditorPath : public Button { - GDCLASS(EditorPath, Button); +class EditorObjectSelector : public Button { + GDCLASS(EditorObjectSelector, Button); EditorSelectionHistory *history = nullptr; @@ -67,7 +67,7 @@ public: void clear_path(); void enable_path(); - EditorPath(EditorSelectionHistory *p_history); + EditorObjectSelector(EditorSelectionHistory *p_history); }; -#endif // EDITOR_PATH_H +#endif // EDITOR_OBJECT_SELECTOR_H diff --git a/editor/editor_spin_slider.cpp b/editor/gui/editor_spin_slider.cpp index 2d3ec437c6..2e67893fac 100644 --- a/editor/editor_spin_slider.cpp +++ b/editor/gui/editor_spin_slider.cpp @@ -37,11 +37,7 @@ String EditorSpinSlider::get_tooltip(const Point2 &p_pos) const { if (grabber->is_visible()) { -#ifdef MACOS_ENABLED - Key key = Key::META; -#else - Key key = Key::CTRL; -#endif + Key key = (OS::get_singleton()->has_feature("macos") || OS::get_singleton()->has_feature("web_macos") || OS::get_singleton()->has_feature("web_ios")) ? Key::META : Key::CTRL; return TS->format_number(rtos(get_value())) + "\n\n" + vformat(TTR("Hold %s to round to integers.\nHold Shift for more precise changes."), find_keycode_name(key)); } return TS->format_number(rtos(get_value())); diff --git a/editor/editor_spin_slider.h b/editor/gui/editor_spin_slider.h index a4d810b18b..a4d810b18b 100644 --- a/editor/editor_spin_slider.h +++ b/editor/gui/editor_spin_slider.h diff --git a/editor/editor_title_bar.cpp b/editor/gui/editor_title_bar.cpp index ae5cdfd72b..c251c70c6d 100644 --- a/editor/editor_title_bar.cpp +++ b/editor/gui/editor_title_bar.cpp @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#include "editor/editor_title_bar.h" +#include "editor_title_bar.h" void EditorTitleBar::gui_input(const Ref<InputEvent> &p_event) { if (!can_move) { diff --git a/editor/editor_title_bar.h b/editor/gui/editor_title_bar.h index 4055476b82..4055476b82 100644 --- a/editor/editor_title_bar.h +++ b/editor/gui/editor_title_bar.h diff --git a/editor/editor_toaster.cpp b/editor/gui/editor_toaster.cpp index 10c3e963af..10c3e963af 100644 --- a/editor/editor_toaster.cpp +++ b/editor/gui/editor_toaster.cpp diff --git a/editor/editor_toaster.h b/editor/gui/editor_toaster.h index 6b834f8288..6b834f8288 100644 --- a/editor/editor_toaster.h +++ b/editor/gui/editor_toaster.h diff --git a/editor/editor_zoom_widget.cpp b/editor/gui/editor_zoom_widget.cpp index 3998b33a53..3998b33a53 100644 --- a/editor/editor_zoom_widget.cpp +++ b/editor/gui/editor_zoom_widget.cpp diff --git a/editor/editor_zoom_widget.h b/editor/gui/editor_zoom_widget.h index be54043d93..be54043d93 100644 --- a/editor/editor_zoom_widget.h +++ b/editor/gui/editor_zoom_widget.h diff --git a/editor/scene_tree_editor.cpp b/editor/gui/scene_tree_editor.cpp index 8ba6a1e610..5b9f2c3b21 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/gui/scene_tree_editor.cpp @@ -42,6 +42,8 @@ #include "editor/plugins/canvas_item_editor_plugin.h" #include "editor/plugins/script_editor_plugin.h" #include "scene/gui/label.h" +#include "scene/gui/tab_container.h" +#include "scene/gui/texture_rect.h" #include "scene/main/window.h" #include "scene/resources/packed_scene.h" @@ -983,7 +985,7 @@ void SceneTreeEditor::_renamed() { String new_name = raw_new_name.validate_node_name(); if (new_name != raw_new_name) { - error->set_text(TTR("Invalid node name, the following characters are not allowed:") + "\n" + String::invalid_node_name_characters); + error->set_text(TTR("Invalid node name, the following characters are not allowed:") + "\n" + String::get_invalid_node_name_characters()); error->popup_centered(); if (new_name.is_empty()) { diff --git a/editor/scene_tree_editor.h b/editor/gui/scene_tree_editor.h index 6a3213f8e4..6a3213f8e4 100644 --- a/editor/scene_tree_editor.h +++ b/editor/gui/scene_tree_editor.h diff --git a/editor/import/dynamic_font_import_settings.cpp b/editor/import/dynamic_font_import_settings.cpp index 6be6682232..65fc79a7a5 100644 --- a/editor/import/dynamic_font_import_settings.cpp +++ b/editor/import/dynamic_font_import_settings.cpp @@ -31,7 +31,6 @@ #include "dynamic_font_import_settings.h" #include "core/config/project_settings.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_file_system.h" #include "editor/editor_inspector.h" #include "editor/editor_locale_dialog.h" @@ -39,6 +38,7 @@ #include "editor/editor_property_name_processor.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/gui/editor_file_dialog.h" /*************************************************************************/ /* Settings data */ diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index 038a16f566..c052f92508 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -1604,22 +1604,23 @@ void ResourceImporterScene::get_internal_import_options(InternalImportCategory p r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "physics/shape_type", PROPERTY_HINT_ENUM, "Decompose Convex,Simple Convex,Trimesh,Box,Sphere,Cylinder,Capsule", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 0)); // Decomposition - Mesh::ConvexDecompositionSettings decomposition_default; + Ref<MeshConvexDecompositionSettings> decomposition_default = Ref<MeshConvexDecompositionSettings>(); + decomposition_default.instantiate(); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "decomposition/advanced", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/precision", PROPERTY_HINT_RANGE, "1,10,1"), 5)); - r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "decomposition/max_concavity", PROPERTY_HINT_RANGE, "0.0,1.0,0.001", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.max_concavity)); - r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "decomposition/symmetry_planes_clipping_bias", PROPERTY_HINT_RANGE, "0.0,1.0,0.001", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.symmetry_planes_clipping_bias)); - r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "decomposition/revolution_axes_clipping_bias", PROPERTY_HINT_RANGE, "0.0,1.0,0.001", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.revolution_axes_clipping_bias)); - r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "decomposition/min_volume_per_convex_hull", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.min_volume_per_convex_hull)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/resolution", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.resolution)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/max_num_vertices_per_convex_hull", PROPERTY_HINT_RANGE, "5,512,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.max_num_vertices_per_convex_hull)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/plane_downsampling", PROPERTY_HINT_RANGE, "1,16,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.plane_downsampling)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/convexhull_downsampling", PROPERTY_HINT_RANGE, "1,16,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.convexhull_downsampling)); - r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "decomposition/normalize_mesh", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.normalize_mesh)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/mode", PROPERTY_HINT_ENUM, "Voxel,Tetrahedron", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), static_cast<int>(decomposition_default.mode))); - r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "decomposition/convexhull_approximation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.convexhull_approximation)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/max_convex_hulls", PROPERTY_HINT_RANGE, "1,100,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.max_convex_hulls)); - r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "decomposition/project_hull_vertices", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.project_hull_vertices)); + r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "decomposition/max_concavity", PROPERTY_HINT_RANGE, "0.0,1.0,0.001", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default->get_max_concavity())); + r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "decomposition/symmetry_planes_clipping_bias", PROPERTY_HINT_RANGE, "0.0,1.0,0.001", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default->get_symmetry_planes_clipping_bias())); + r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "decomposition/revolution_axes_clipping_bias", PROPERTY_HINT_RANGE, "0.0,1.0,0.001", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default->get_revolution_axes_clipping_bias())); + r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "decomposition/min_volume_per_convex_hull", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default->get_min_volume_per_convex_hull())); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/resolution", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default->get_resolution())); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/max_num_vertices_per_convex_hull", PROPERTY_HINT_RANGE, "5,512,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default->get_max_num_vertices_per_convex_hull())); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/plane_downsampling", PROPERTY_HINT_RANGE, "1,16,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default->get_plane_downsampling())); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/convexhull_downsampling", PROPERTY_HINT_RANGE, "1,16,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default->get_convex_hull_downsampling())); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "decomposition/normalize_mesh", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default->get_normalize_mesh())); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/mode", PROPERTY_HINT_ENUM, "Voxel,Tetrahedron", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), static_cast<int>(decomposition_default->get_mode()))); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "decomposition/convexhull_approximation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default->get_convex_hull_approximation())); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/max_convex_hulls", PROPERTY_HINT_RANGE, "1,100,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default->get_max_convex_hulls())); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "decomposition/project_hull_vertices", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default->get_project_hull_vertices())); // Primitives: Box, Sphere, Cylinder, Capsule. r_options->push_back(ImportOption(PropertyInfo(Variant::VECTOR3, "primitive/size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), Vector3(2.0, 2.0, 2.0))); diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index 520ccd1070..a66fd034f8 100644 --- a/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h @@ -323,7 +323,8 @@ Vector<Ref<Shape3D>> ResourceImporterScene::get_collision_shapes(const Ref<Impor } if (generate_shape_type == SHAPE_TYPE_DECOMPOSE_CONVEX) { - Mesh::ConvexDecompositionSettings decomposition_settings; + Ref<MeshConvexDecompositionSettings> decomposition_settings = Ref<MeshConvexDecompositionSettings>(); + decomposition_settings.instantiate(); bool advanced = false; if (p_options.has(SNAME("decomposition/advanced"))) { advanced = p_options[SNAME("decomposition/advanced")]; @@ -331,55 +332,55 @@ Vector<Ref<Shape3D>> ResourceImporterScene::get_collision_shapes(const Ref<Impor if (advanced) { if (p_options.has(SNAME("decomposition/max_concavity"))) { - decomposition_settings.max_concavity = p_options[SNAME("decomposition/max_concavity")]; + decomposition_settings->set_max_concavity(p_options[SNAME("decomposition/max_concavity")]); } if (p_options.has(SNAME("decomposition/symmetry_planes_clipping_bias"))) { - decomposition_settings.symmetry_planes_clipping_bias = p_options[SNAME("decomposition/symmetry_planes_clipping_bias")]; + decomposition_settings->set_symmetry_planes_clipping_bias(p_options[SNAME("decomposition/symmetry_planes_clipping_bias")]); } if (p_options.has(SNAME("decomposition/revolution_axes_clipping_bias"))) { - decomposition_settings.revolution_axes_clipping_bias = p_options[SNAME("decomposition/revolution_axes_clipping_bias")]; + decomposition_settings->set_revolution_axes_clipping_bias(p_options[SNAME("decomposition/revolution_axes_clipping_bias")]); } if (p_options.has(SNAME("decomposition/min_volume_per_convex_hull"))) { - decomposition_settings.min_volume_per_convex_hull = p_options[SNAME("decomposition/min_volume_per_convex_hull")]; + decomposition_settings->set_min_volume_per_convex_hull(p_options[SNAME("decomposition/min_volume_per_convex_hull")]); } if (p_options.has(SNAME("decomposition/resolution"))) { - decomposition_settings.resolution = p_options[SNAME("decomposition/resolution")]; + decomposition_settings->set_resolution(p_options[SNAME("decomposition/resolution")]); } if (p_options.has(SNAME("decomposition/max_num_vertices_per_convex_hull"))) { - decomposition_settings.max_num_vertices_per_convex_hull = p_options[SNAME("decomposition/max_num_vertices_per_convex_hull")]; + decomposition_settings->set_max_num_vertices_per_convex_hull(p_options[SNAME("decomposition/max_num_vertices_per_convex_hull")]); } if (p_options.has(SNAME("decomposition/plane_downsampling"))) { - decomposition_settings.plane_downsampling = p_options[SNAME("decomposition/plane_downsampling")]; + decomposition_settings->set_plane_downsampling(p_options[SNAME("decomposition/plane_downsampling")]); } if (p_options.has(SNAME("decomposition/convexhull_downsampling"))) { - decomposition_settings.convexhull_downsampling = p_options[SNAME("decomposition/convexhull_downsampling")]; + decomposition_settings->set_convex_hull_downsampling(p_options[SNAME("decomposition/convexhull_downsampling")]); } if (p_options.has(SNAME("decomposition/normalize_mesh"))) { - decomposition_settings.normalize_mesh = p_options[SNAME("decomposition/normalize_mesh")]; + decomposition_settings->set_normalize_mesh(p_options[SNAME("decomposition/normalize_mesh")]); } if (p_options.has(SNAME("decomposition/mode"))) { - decomposition_settings.mode = (Mesh::ConvexDecompositionSettings::Mode)p_options[SNAME("decomposition/mode")].operator int(); + decomposition_settings->set_mode((MeshConvexDecompositionSettings::Mode)p_options[SNAME("decomposition/mode")].operator int()); } if (p_options.has(SNAME("decomposition/convexhull_approximation"))) { - decomposition_settings.convexhull_approximation = p_options[SNAME("decomposition/convexhull_approximation")]; + decomposition_settings->set_convex_hull_approximation(p_options[SNAME("decomposition/convexhull_approximation")]); } if (p_options.has(SNAME("decomposition/max_convex_hulls"))) { - decomposition_settings.max_convex_hulls = MAX(1, (int)p_options[SNAME("decomposition/max_convex_hulls")]); + decomposition_settings->set_max_convex_hulls(MAX(1, (int)p_options[SNAME("decomposition/max_convex_hulls")])); } if (p_options.has(SNAME("decomposition/project_hull_vertices"))) { - decomposition_settings.project_hull_vertices = p_options[SNAME("decomposition/project_hull_vertices")]; + decomposition_settings->set_project_hull_vertices(p_options[SNAME("decomposition/project_hull_vertices")]); } } else { int precision_level = 5; @@ -389,13 +390,13 @@ Vector<Ref<Shape3D>> ResourceImporterScene::get_collision_shapes(const Ref<Impor const real_t precision = real_t(precision_level - 1) / 9.0; - decomposition_settings.max_concavity = Math::lerp(real_t(1.0), real_t(0.001), precision); - decomposition_settings.min_volume_per_convex_hull = Math::lerp(real_t(0.01), real_t(0.0001), precision); - decomposition_settings.resolution = Math::lerp(10'000, 100'000, precision); - decomposition_settings.max_num_vertices_per_convex_hull = Math::lerp(32, 64, precision); - decomposition_settings.plane_downsampling = Math::lerp(3, 16, precision); - decomposition_settings.convexhull_downsampling = Math::lerp(3, 16, precision); - decomposition_settings.max_convex_hulls = Math::lerp(1, 32, precision); + decomposition_settings->set_max_concavity(Math::lerp(real_t(1.0), real_t(0.001), precision)); + decomposition_settings->set_min_volume_per_convex_hull(Math::lerp(real_t(0.01), real_t(0.0001), precision)); + decomposition_settings->set_resolution(Math::lerp(10'000, 100'000, precision)); + decomposition_settings->set_max_num_vertices_per_convex_hull(Math::lerp(32, 64, precision)); + decomposition_settings->set_plane_downsampling(Math::lerp(3, 16, precision)); + decomposition_settings->set_convex_hull_downsampling(Math::lerp(3, 16, precision)); + decomposition_settings->set_max_convex_hulls(Math::lerp(1, 32, precision)); } return p_mesh->convex_decompose(decomposition_settings); diff --git a/editor/import/scene_import_settings.cpp b/editor/import/scene_import_settings.cpp index 4dd3de8ca2..e7ba47e2a1 100644 --- a/editor/import/scene_import_settings.cpp +++ b/editor/import/scene_import_settings.cpp @@ -31,12 +31,12 @@ #include "scene_import_settings.h" #include "core/config/project_settings.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_file_system.h" #include "editor/editor_inspector.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/gui/editor_file_dialog.h" #include "scene/3d/importer_mesh_instance_3d.h" #include "scene/animation/animation_player.h" #include "scene/resources/importer_mesh.h" diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp index f7bbeb92c6..2acc83cead 100644 --- a/editor/inspector_dock.cpp +++ b/editor/inspector_dock.cpp @@ -30,12 +30,13 @@ #include "inspector_dock.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" #include "editor/filesystem_dock.h" +#include "editor/gui/editor_file_dialog.h" +#include "editor/gui/editor_object_selector.h" #include "editor/plugins/script_editor_plugin.h" InspectorDock *InspectorDock::singleton = nullptr; @@ -510,7 +511,7 @@ void InspectorDock::update(Object *p_object) { if (editor_history->get_history_len() > 0) { history_menu->set_disabled(false); } - editor_path->update_path(); + object_selector->update_path(); current = p_object; @@ -530,11 +531,11 @@ void InspectorDock::update(Object *p_object) { if (!is_object || is_text_file) { info->hide(); - editor_path->clear_path(); + object_selector->clear_path(); return; } - editor_path->enable_path(); + object_selector->enable_path(); PopupMenu *p = object_menu->get_popup(); @@ -689,9 +690,9 @@ InspectorDock::InspectorDock(EditorData &p_editor_data) { HBoxContainer *subresource_hb = memnew(HBoxContainer); add_child(subresource_hb); - editor_path = memnew(EditorPath(EditorNode::get_singleton()->get_editor_selection_history())); - editor_path->set_h_size_flags(Control::SIZE_EXPAND_FILL); - subresource_hb->add_child(editor_path); + object_selector = memnew(EditorObjectSelector(EditorNode::get_singleton()->get_editor_selection_history())); + object_selector->set_h_size_flags(Control::SIZE_EXPAND_FILL); + subresource_hb->add_child(object_selector); open_docs_button = memnew(Button); open_docs_button->set_flat(true); diff --git a/editor/inspector_dock.h b/editor/inspector_dock.h index c2c1b55fb1..622a2521b3 100644 --- a/editor/inspector_dock.h +++ b/editor/inspector_dock.h @@ -34,7 +34,6 @@ #include "editor/create_dialog.h" #include "editor/editor_data.h" #include "editor/editor_inspector.h" -#include "editor/editor_path.h" #include "scene/gui/box_container.h" #include "scene/gui/button.h" #include "scene/gui/dialogs.h" @@ -43,6 +42,7 @@ #include "scene/gui/tree.h" class EditorFileDialog; +class EditorObjectSelector; class InspectorDock : public VBoxContainer { GDCLASS(InspectorDock, VBoxContainer); @@ -92,7 +92,7 @@ class InspectorDock : public VBoxContainer { Button *open_docs_button = nullptr; MenuButton *object_menu = nullptr; - EditorPath *editor_path = nullptr; + EditorObjectSelector *object_selector = nullptr; bool info_is_warning = false; // Display in yellow and use warning icon if true. Button *info = nullptr; diff --git a/editor/localization_editor.cpp b/editor/localization_editor.cpp index fac1ec3523..351986a80b 100644 --- a/editor/localization_editor.cpp +++ b/editor/localization_editor.cpp @@ -32,11 +32,11 @@ #include "core/config/project_settings.h" #include "core/string/translation.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_scale.h" #include "editor/editor_translation_parser.h" #include "editor/editor_undo_redo_manager.h" #include "editor/filesystem_dock.h" +#include "editor/gui/editor_file_dialog.h" #include "editor/pot_generator.h" #include "scene/gui/control.h" diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp index 7c23e19564..4375a33b4f 100644 --- a/editor/plugins/abstract_polygon_2d_editor.cpp +++ b/editor/plugins/abstract_polygon_2d_editor.cpp @@ -37,6 +37,8 @@ #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "scene/gui/button.h" +#include "scene/gui/dialogs.h" #include "scene/gui/separator.h" bool AbstractPolygon2DEditor::Vertex::operator==(const AbstractPolygon2DEditor::Vertex &p_vertex) const { diff --git a/editor/plugins/abstract_polygon_2d_editor.h b/editor/plugins/abstract_polygon_2d_editor.h index 832972c398..31c20ac146 100644 --- a/editor/plugins/abstract_polygon_2d_editor.h +++ b/editor/plugins/abstract_polygon_2d_editor.h @@ -35,6 +35,7 @@ #include "scene/2d/polygon_2d.h" #include "scene/gui/box_container.h" +class Button; class CanvasItemEditor; class ConfirmationDialog; diff --git a/editor/plugins/animation_blend_space_1d_editor.cpp b/editor/plugins/animation_blend_space_1d_editor.cpp index df94815105..15fa60f11b 100644 --- a/editor/plugins/animation_blend_space_1d_editor.cpp +++ b/editor/plugins/animation_blend_space_1d_editor.cpp @@ -31,11 +31,11 @@ #include "animation_blend_space_1d_editor.h" #include "core/os/keyboard.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/gui/editor_file_dialog.h" #include "scene/animation/animation_blend_tree.h" #include "scene/gui/check_box.h" #include "scene/gui/option_button.h" diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp index 0daf934e17..e96cd5770c 100644 --- a/editor/plugins/animation_blend_space_2d_editor.cpp +++ b/editor/plugins/animation_blend_space_2d_editor.cpp @@ -35,11 +35,11 @@ #include "core/io/resource_loader.h" #include "core/math/geometry_2d.h" #include "core/os/keyboard.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/gui/editor_file_dialog.h" #include "scene/animation/animation_blend_tree.h" #include "scene/animation/animation_player.h" #include "scene/gui/check_box.h" diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp index 77785b15ca..9dff5127ae 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.cpp +++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp @@ -34,12 +34,12 @@ #include "core/input/input.h" #include "core/io/resource_loader.h" #include "core/os/keyboard.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_inspector.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/gui/editor_file_dialog.h" #include "scene/animation/animation_player.h" #include "scene/gui/check_box.h" #include "scene/gui/menu_button.h" diff --git a/editor/plugins/animation_library_editor.cpp b/editor/plugins/animation_library_editor.cpp index bf7e419fe4..4db4f870ca 100644 --- a/editor/plugins/animation_library_editor.cpp +++ b/editor/plugins/animation_library_editor.cpp @@ -29,11 +29,11 @@ /**************************************************************************/ #include "animation_library_editor.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/gui/editor_file_dialog.h" void AnimationLibraryEditor::set_animation_player(Object *p_player) { player = p_player; diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index 2abb74d9e9..d9d057d0e8 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -35,11 +35,11 @@ #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" #include "core/os/keyboard.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/gui/editor_file_dialog.h" #include "editor/inspector_dock.h" #include "editor/plugins/canvas_item_editor_plugin.h" // For onion skinning. #include "editor/plugins/node_3d_editor_plugin.h" // For onion skinning. diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp index 9632670658..715f2b9ad4 100644 --- a/editor/plugins/animation_state_machine_editor.cpp +++ b/editor/plugins/animation_state_machine_editor.cpp @@ -35,11 +35,11 @@ #include "core/io/resource_loader.h" #include "core/math/geometry_2d.h" #include "core/os/keyboard.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/gui/editor_file_dialog.h" #include "scene/animation/animation_blend_tree.h" #include "scene/animation/animation_player.h" #include "scene/gui/menu_button.h" diff --git a/editor/plugins/animation_tree_editor_plugin.cpp b/editor/plugins/animation_tree_editor_plugin.cpp index ab46e8f04a..80e9bf7eda 100644 --- a/editor/plugins/animation_tree_editor_plugin.cpp +++ b/editor/plugins/animation_tree_editor_plugin.cpp @@ -39,9 +39,9 @@ #include "core/io/resource_loader.h" #include "core/math/delaunay_2d.h" #include "core/os/keyboard.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/gui/editor_file_dialog.h" #include "scene/animation/animation_blend_tree.h" #include "scene/animation/animation_player.h" #include "scene/gui/menu_button.h" diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp index a80d57d272..eeb0fd5f66 100644 --- a/editor/plugins/asset_library_editor_plugin.cpp +++ b/editor/plugins/asset_library_editor_plugin.cpp @@ -35,11 +35,11 @@ #include "core/io/stream_peer_tls.h" #include "core/os/keyboard.h" #include "core/version.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_paths.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/gui/editor_file_dialog.h" #include "editor/project_settings_editor.h" #include "scene/gui/menu_button.h" diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index e969f9ab30..592f42c5b8 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -37,9 +37,9 @@ #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" -#include "editor/editor_toaster.h" #include "editor/editor_undo_redo_manager.h" -#include "editor/editor_zoom_widget.h" +#include "editor/gui/editor_toaster.h" +#include "editor/gui/editor_zoom_widget.h" #include "editor/plugins/animation_player_editor_plugin.h" #include "editor/plugins/script_editor_plugin.h" #include "editor/scene_tree_dock.h" @@ -56,6 +56,7 @@ #include "scene/gui/separator.h" #include "scene/gui/split_container.h" #include "scene/gui/subviewport_container.h" +#include "scene/gui/texture_rect.h" #include "scene/gui/view_panner.h" #include "scene/main/canvas_layer.h" #include "scene/main/window.h" @@ -5407,6 +5408,7 @@ CanvasItemEditor::CanvasItemEditor() { singleton = this; set_process_shortcut_input(true); + clear(); // Make sure values are initialized. // Update the menus' checkboxes. callable_mp(this, &CanvasItemEditor::set_state).bind(get_state()).call_deferred(); diff --git a/editor/plugins/cpu_particles_2d_editor_plugin.cpp b/editor/plugins/cpu_particles_2d_editor_plugin.cpp index 85897742fb..ef00af592f 100644 --- a/editor/plugins/cpu_particles_2d_editor_plugin.cpp +++ b/editor/plugins/cpu_particles_2d_editor_plugin.cpp @@ -32,8 +32,8 @@ #include "canvas_item_editor_plugin.h" #include "core/io/image_loader.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_node.h" +#include "editor/gui/editor_file_dialog.h" #include "scene/2d/cpu_particles_2d.h" #include "scene/gui/check_box.h" #include "scene/gui/menu_button.h" diff --git a/editor/plugins/cpu_particles_3d_editor_plugin.cpp b/editor/plugins/cpu_particles_3d_editor_plugin.cpp index 61702493da..6edfc2ef2e 100644 --- a/editor/plugins/cpu_particles_3d_editor_plugin.cpp +++ b/editor/plugins/cpu_particles_3d_editor_plugin.cpp @@ -31,8 +31,8 @@ #include "cpu_particles_3d_editor_plugin.h" #include "editor/editor_node.h" +#include "editor/gui/scene_tree_editor.h" #include "editor/plugins/node_3d_editor_plugin.h" -#include "editor/scene_tree_editor.h" #include "scene/gui/menu_button.h" void CPUParticles3DEditor::_node_removed(Node *p_node) { diff --git a/editor/plugins/debugger_editor_plugin.cpp b/editor/plugins/debugger_editor_plugin.cpp index 224d221d9a..7863e6d19e 100644 --- a/editor/plugins/debugger_editor_plugin.cpp +++ b/editor/plugins/debugger_editor_plugin.cpp @@ -33,10 +33,10 @@ #include "core/os/keyboard.h" #include "editor/debugger/editor_debugger_node.h" #include "editor/debugger/editor_debugger_server.h" +#include "editor/debugger/editor_file_server.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" -#include "editor/fileserver/editor_file_server.h" #include "editor/plugins/script_editor_plugin.h" #include "scene/gui/menu_button.h" diff --git a/editor/plugins/gpu_particles_2d_editor_plugin.cpp b/editor/plugins/gpu_particles_2d_editor_plugin.cpp index 04b2a9337e..8631ee05c8 100644 --- a/editor/plugins/gpu_particles_2d_editor_plugin.cpp +++ b/editor/plugins/gpu_particles_2d_editor_plugin.cpp @@ -32,9 +32,9 @@ #include "canvas_item_editor_plugin.h" #include "core/io/image_loader.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/gui/editor_file_dialog.h" #include "editor/scene_tree_dock.h" #include "scene/2d/cpu_particles_2d.h" #include "scene/gui/menu_button.h" diff --git a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp index 477a094d01..abecba144c 100644 --- a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp +++ b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp @@ -30,8 +30,8 @@ #include "gpu_particles_collision_sdf_editor_plugin.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_node.h" +#include "editor/gui/editor_file_dialog.h" void GPUParticlesCollisionSDF3DEditorPlugin::_bake() { if (col_sdf) { diff --git a/editor/plugins/gradient_texture_2d_editor_plugin.cpp b/editor/plugins/gradient_texture_2d_editor_plugin.cpp index 7bd159a5b8..e91afe28ee 100644 --- a/editor/plugins/gradient_texture_2d_editor_plugin.cpp +++ b/editor/plugins/gradient_texture_2d_editor_plugin.cpp @@ -33,7 +33,9 @@ #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/gui/editor_spin_slider.h" #include "scene/gui/box_container.h" +#include "scene/gui/button.h" #include "scene/gui/flow_container.h" #include "scene/gui/separator.h" diff --git a/editor/plugins/gradient_texture_2d_editor_plugin.h b/editor/plugins/gradient_texture_2d_editor_plugin.h index 724ec63b4e..0b496b210e 100644 --- a/editor/plugins/gradient_texture_2d_editor_plugin.h +++ b/editor/plugins/gradient_texture_2d_editor_plugin.h @@ -33,7 +33,9 @@ #include "editor/editor_inspector.h" #include "editor/editor_plugin.h" -#include "editor/editor_spin_slider.h" + +class Button; +class EditorSpinSlider; class GradientTexture2DEditorRect : public Control { GDCLASS(GradientTexture2DEditorRect, Control); diff --git a/editor/plugins/lightmap_gi_editor_plugin.cpp b/editor/plugins/lightmap_gi_editor_plugin.cpp index 519cfcaa94..6ba2072f72 100644 --- a/editor/plugins/lightmap_gi_editor_plugin.cpp +++ b/editor/plugins/lightmap_gi_editor_plugin.cpp @@ -30,8 +30,8 @@ #include "lightmap_gi_editor_plugin.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_node.h" +#include "editor/gui/editor_file_dialog.h" void LightmapGIEditorPlugin::_bake_select_file(const String &p_file) { if (lightmap) { diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp index 36c143ca8d..328fe9b950 100644 --- a/editor/plugins/material_editor_plugin.cpp +++ b/editor/plugins/material_editor_plugin.cpp @@ -35,7 +35,13 @@ #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "scene/3d/camera_3d.h" +#include "scene/3d/light_3d.h" +#include "scene/3d/mesh_instance_3d.h" +#include "scene/gui/box_container.h" +#include "scene/gui/color_rect.h" #include "scene/gui/subviewport_container.h" +#include "scene/gui/texture_button.h" #include "scene/resources/fog_material.h" #include "scene/resources/particle_process_material.h" #include "scene/resources/sky_material.h" diff --git a/editor/plugins/material_editor_plugin.h b/editor/plugins/material_editor_plugin.h index 63ee053b1d..deb1211c54 100644 --- a/editor/plugins/material_editor_plugin.h +++ b/editor/plugins/material_editor_plugin.h @@ -34,13 +34,14 @@ #include "editor/editor_inspector.h" #include "editor/editor_plugin.h" #include "editor/plugins/editor_resource_conversion_plugin.h" -#include "scene/3d/camera_3d.h" -#include "scene/3d/light_3d.h" -#include "scene/3d/mesh_instance_3d.h" -#include "scene/gui/color_rect.h" #include "scene/resources/material.h" #include "scene/resources/primitive_meshes.h" +class Camera3D; +class ColorRect; +class DirectionalLight3D; +class HBoxContainer; +class MeshInstance3D; class SubViewport; class SubViewportContainer; class TextureButton; diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.cpp b/editor/plugins/mesh_instance_3d_editor_plugin.cpp index e8976667dd..a53e254dcc 100644 --- a/editor/plugins/mesh_instance_3d_editor_plugin.cpp +++ b/editor/plugins/mesh_instance_3d_editor_plugin.cpp @@ -33,12 +33,14 @@ #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_undo_redo_manager.h" -#include "node_3d_editor_plugin.h" +#include "editor/plugins/node_3d_editor_plugin.h" #include "scene/3d/collision_shape_3d.h" #include "scene/3d/navigation_region_3d.h" #include "scene/3d/physics_body_3d.h" #include "scene/gui/box_container.h" +#include "scene/gui/dialogs.h" #include "scene/gui/menu_button.h" +#include "scene/gui/spin_box.h" #include "scene/resources/concave_polygon_shape_3d.h" #include "scene/resources/convex_polygon_shape_3d.h" #include "scene/scene_string_names.h" @@ -214,7 +216,11 @@ void MeshInstance3DEditor::_menu_option(int p_option) { return; } - Mesh::ConvexDecompositionSettings settings; + Ref<MeshConvexDecompositionSettings> settings = Ref<MeshConvexDecompositionSettings>(); + settings.instantiate(); + settings->set_max_convex_hulls(32); + settings->set_max_concavity(0.001); + Vector<Ref<Shape3D>> shapes = mesh->convex_decompose(settings); if (!shapes.size()) { diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.h b/editor/plugins/mesh_instance_3d_editor_plugin.h index aa72d4fa33..ea67d1aae9 100644 --- a/editor/plugins/mesh_instance_3d_editor_plugin.h +++ b/editor/plugins/mesh_instance_3d_editor_plugin.h @@ -33,11 +33,11 @@ #include "editor/editor_plugin.h" #include "scene/3d/mesh_instance_3d.h" -#include "scene/gui/spin_box.h" class AcceptDialog; class ConfirmationDialog; class MenuButton; +class SpinBox; class MeshInstance3DEditor : public Control { GDCLASS(MeshInstance3DEditor, Control); diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp index cf8555d07d..3959ed2976 100644 --- a/editor/plugins/mesh_library_editor_plugin.cpp +++ b/editor/plugins/mesh_library_editor_plugin.cpp @@ -30,12 +30,12 @@ #include "mesh_library_editor_plugin.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" +#include "editor/gui/editor_file_dialog.h" #include "editor/inspector_dock.h" +#include "editor/plugins/node_3d_editor_plugin.h" #include "main/main.h" -#include "node_3d_editor_plugin.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/3d/navigation_region_3d.h" #include "scene/3d/physics_body_3d.h" diff --git a/editor/plugins/multimesh_editor_plugin.cpp b/editor/plugins/multimesh_editor_plugin.cpp index 9845e8a9c3..15647e1364 100644 --- a/editor/plugins/multimesh_editor_plugin.cpp +++ b/editor/plugins/multimesh_editor_plugin.cpp @@ -31,8 +31,8 @@ #include "multimesh_editor_plugin.h" #include "editor/editor_node.h" -#include "editor/scene_tree_editor.h" -#include "node_3d_editor_plugin.h" +#include "editor/gui/scene_tree_editor.h" +#include "editor/plugins/node_3d_editor_plugin.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/gui/box_container.h" #include "scene/gui/menu_button.h" diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 27c97ff9f4..7225c1b658 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -40,6 +40,7 @@ #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/gui/editor_spin_slider.h" #include "editor/plugins/animation_player_editor_plugin.h" #include "editor/plugins/node_3d_editor_gizmos.h" #include "editor/scene_tree_dock.h" @@ -5162,10 +5163,10 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p position_control->set_navigation_mode(Node3DEditorViewport::NAVIGATION_MOVE); position_control->set_custom_minimum_size(Size2(navigation_control_size, navigation_control_size) * EDSCALE); position_control->set_h_size_flags(SIZE_SHRINK_END); - position_control->set_anchor_and_offset(SIDE_LEFT, ANCHOR_BEGIN, 0 * EDSCALE); + position_control->set_anchor_and_offset(SIDE_LEFT, ANCHOR_BEGIN, 0); position_control->set_anchor_and_offset(SIDE_TOP, ANCHOR_END, -navigation_control_size * EDSCALE); position_control->set_anchor_and_offset(SIDE_RIGHT, ANCHOR_BEGIN, navigation_control_size * EDSCALE); - position_control->set_anchor_and_offset(SIDE_BOTTOM, ANCHOR_END, 0 * EDSCALE); + position_control->set_anchor_and_offset(SIDE_BOTTOM, ANCHOR_END, 0); position_control->set_viewport(this); surface->add_child(position_control); @@ -5175,8 +5176,8 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p look_control->set_h_size_flags(SIZE_SHRINK_END); look_control->set_anchor_and_offset(SIDE_LEFT, ANCHOR_END, -navigation_control_size * EDSCALE); look_control->set_anchor_and_offset(SIDE_TOP, ANCHOR_END, -navigation_control_size * EDSCALE); - look_control->set_anchor_and_offset(SIDE_RIGHT, ANCHOR_END, 0 * EDSCALE); - look_control->set_anchor_and_offset(SIDE_BOTTOM, ANCHOR_END, 0 * EDSCALE); + look_control->set_anchor_and_offset(SIDE_RIGHT, ANCHOR_END, 0); + look_control->set_anchor_and_offset(SIDE_BOTTOM, ANCHOR_END, 0); look_control->set_viewport(this); surface->add_child(look_control); @@ -7866,7 +7867,10 @@ void Node3DEditor::clear() { viewports[i]->reset(); } - RenderingServer::get_singleton()->instance_set_visible(origin_instance, true); + if (origin_instance.is_valid()) { + RenderingServer::get_singleton()->instance_set_visible(origin_instance, true); + } + view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_ORIGIN), true); for (int i = 0; i < 3; ++i) { if (grid_enable[i]) { @@ -8654,6 +8658,7 @@ void fragment() { _load_default_preview_settings(); _preview_settings_changed(); } + clear(); // Make sure values are initialized. } Node3DEditor::~Node3DEditor() { memdelete(preview_node); diff --git a/editor/plugins/occluder_instance_3d_editor_plugin.cpp b/editor/plugins/occluder_instance_3d_editor_plugin.cpp index cfe95f1cfa..9e9e602841 100644 --- a/editor/plugins/occluder_instance_3d_editor_plugin.cpp +++ b/editor/plugins/occluder_instance_3d_editor_plugin.cpp @@ -30,8 +30,8 @@ #include "occluder_instance_3d_editor_plugin.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_node.h" +#include "editor/gui/editor_file_dialog.h" void OccluderInstance3DEditorPlugin::_bake_select_file(const String &p_file) { if (occluder_instance) { diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp index e5e77be7aa..a2549c7376 100644 --- a/editor/plugins/polygon_2d_editor_plugin.cpp +++ b/editor/plugins/polygon_2d_editor_plugin.cpp @@ -39,7 +39,10 @@ #include "editor/plugins/canvas_item_editor_plugin.h" #include "scene/2d/skeleton_2d.h" #include "scene/gui/check_box.h" +#include "scene/gui/dialogs.h" +#include "scene/gui/label.h" #include "scene/gui/menu_button.h" +#include "scene/gui/panel.h" #include "scene/gui/scroll_container.h" #include "scene/gui/separator.h" #include "scene/gui/slider.h" diff --git a/editor/plugins/polygon_2d_editor_plugin.h b/editor/plugins/polygon_2d_editor_plugin.h index 2c55a5f631..3547c03120 100644 --- a/editor/plugins/polygon_2d_editor_plugin.h +++ b/editor/plugins/polygon_2d_editor_plugin.h @@ -37,6 +37,7 @@ class AcceptDialog; class ButtonGroup; class HScrollBar; class HSlider; +class Label; class MenuButton; class Panel; class ScrollContainer; diff --git a/editor/plugins/polygon_3d_editor_plugin.cpp b/editor/plugins/polygon_3d_editor_plugin.cpp index f4d97a5427..efbb2b0d2b 100644 --- a/editor/plugins/polygon_3d_editor_plugin.cpp +++ b/editor/plugins/polygon_3d_editor_plugin.cpp @@ -30,7 +30,6 @@ #include "polygon_3d_editor_plugin.h" -#include "canvas_item_editor_plugin.h" #include "core/core_string_names.h" #include "core/input/input.h" #include "core/io/file_access.h" @@ -39,7 +38,8 @@ #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" -#include "node_3d_editor_plugin.h" +#include "editor/plugins/canvas_item_editor_plugin.h" +#include "editor/plugins/node_3d_editor_plugin.h" #include "scene/3d/camera_3d.h" #include "scene/gui/separator.h" diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp index dcbff2c756..a057bbe05e 100644 --- a/editor/plugins/resource_preloader_editor_plugin.cpp +++ b/editor/plugins/resource_preloader_editor_plugin.cpp @@ -32,11 +32,11 @@ #include "core/config/project_settings.h" #include "core/io/resource_loader.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/gui/editor_file_dialog.h" void ResourcePreloaderEditor::_notification(int p_what) { switch (p_what) { diff --git a/editor/plugins/root_motion_editor_plugin.cpp b/editor/plugins/root_motion_editor_plugin.cpp index e8abecd115..6094b5bef6 100644 --- a/editor/plugins/root_motion_editor_plugin.cpp +++ b/editor/plugins/root_motion_editor_plugin.cpp @@ -32,6 +32,8 @@ #include "editor/editor_node.h" #include "scene/animation/animation_player.h" #include "scene/animation/animation_tree.h" +#include "scene/gui/button.h" +#include "scene/gui/dialogs.h" #include "scene/gui/tree.h" #include "scene/main/window.h" diff --git a/editor/plugins/root_motion_editor_plugin.h b/editor/plugins/root_motion_editor_plugin.h index d27f0d30cc..5befdb6006 100644 --- a/editor/plugins/root_motion_editor_plugin.h +++ b/editor/plugins/root_motion_editor_plugin.h @@ -33,10 +33,13 @@ #include "editor/editor_inspector.h" +class Button; +class ConfirmationDialog; class Tree; class EditorPropertyRootMotion : public EditorProperty { GDCLASS(EditorPropertyRootMotion, EditorProperty); + Button *assign = nullptr; Button *clear = nullptr; NodePath base_hint; diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index a749e6de41..a0ffa5ca0e 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -40,7 +40,6 @@ #include "core/version.h" #include "editor/debugger/editor_debugger_node.h" #include "editor/debugger/script_editor_debugger.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_help_search.h" #include "editor/editor_node.h" #include "editor/editor_paths.h" @@ -49,6 +48,7 @@ #include "editor/editor_settings.h" #include "editor/filesystem_dock.h" #include "editor/find_in_files.h" +#include "editor/gui/editor_file_dialog.h" #include "editor/inspector_dock.h" #include "editor/node_dock.h" #include "editor/plugins/shader_editor_plugin.h" @@ -1060,7 +1060,7 @@ bool ScriptEditor::_test_script_times_on_disk(Ref<Resource> p_for_script) { script_editor->reload_scripts(); need_reload = false; } else { - disk_changed->call_deferred(SNAME("popup_centered_ratio"), 0.5); + disk_changed->call_deferred(SNAME("popup_centered_ratio"), 0.3); } } diff --git a/editor/plugins/skeleton_2d_editor_plugin.cpp b/editor/plugins/skeleton_2d_editor_plugin.cpp index 06db696330..6cf73fc48d 100644 --- a/editor/plugins/skeleton_2d_editor_plugin.cpp +++ b/editor/plugins/skeleton_2d_editor_plugin.cpp @@ -30,11 +30,11 @@ #include "skeleton_2d_editor_plugin.h" -#include "canvas_item_editor_plugin.h" #include "editor/editor_node.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/plugins/canvas_item_editor_plugin.h" #include "scene/2d/mesh_instance_2d.h" -#include "scene/gui/box_container.h" +#include "scene/gui/dialogs.h" #include "scene/gui/menu_button.h" #include "thirdparty/misc/clipper.hpp" diff --git a/editor/plugins/skeleton_2d_editor_plugin.h b/editor/plugins/skeleton_2d_editor_plugin.h index e4551593f3..9f3f1c3b34 100644 --- a/editor/plugins/skeleton_2d_editor_plugin.h +++ b/editor/plugins/skeleton_2d_editor_plugin.h @@ -33,7 +33,6 @@ #include "editor/editor_plugin.h" #include "scene/2d/skeleton_2d.h" -#include "scene/gui/spin_box.h" class AcceptDialog; class MenuButton; diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp index 120cfbdefb..85906ef9d3 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.cpp +++ b/editor/plugins/skeleton_3d_editor_plugin.cpp @@ -43,6 +43,7 @@ #include "scene/3d/mesh_instance_3d.h" #include "scene/3d/physics_body_3d.h" #include "scene/gui/separator.h" +#include "scene/gui/texture_rect.h" #include "scene/resources/capsule_shape_3d.h" #include "scene/resources/skeleton_profile.h" #include "scene/resources/sphere_shape_3d.h" diff --git a/editor/plugins/skeleton_3d_editor_plugin.h b/editor/plugins/skeleton_3d_editor_plugin.h index 3eb840cfa9..7b924d1e9b 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.h +++ b/editor/plugins/skeleton_3d_editor_plugin.h @@ -31,10 +31,10 @@ #ifndef SKELETON_3D_EDITOR_PLUGIN_H #define SKELETON_3D_EDITOR_PLUGIN_H -#include "editor/editor_file_dialog.h" #include "editor/editor_plugin.h" #include "editor/editor_properties.h" -#include "node_3d_editor_plugin.h" +#include "editor/gui/editor_file_dialog.h" +#include "editor/plugins/node_3d_editor_plugin.h" #include "scene/3d/camera_3d.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/3d/skeleton_3d.h" diff --git a/editor/plugins/skeleton_ik_3d_editor_plugin.cpp b/editor/plugins/skeleton_ik_3d_editor_plugin.cpp index 1b78293a87..6331209281 100644 --- a/editor/plugins/skeleton_ik_3d_editor_plugin.cpp +++ b/editor/plugins/skeleton_ik_3d_editor_plugin.cpp @@ -32,6 +32,7 @@ #include "editor/editor_node.h" #include "scene/3d/skeleton_ik_3d.h" +#include "scene/gui/button.h" void SkeletonIK3DEditorPlugin::_play() { if (!skeleton_ik) { diff --git a/editor/plugins/skeleton_ik_3d_editor_plugin.h b/editor/plugins/skeleton_ik_3d_editor_plugin.h index 86d883f9fe..3d311e581e 100644 --- a/editor/plugins/skeleton_ik_3d_editor_plugin.h +++ b/editor/plugins/skeleton_ik_3d_editor_plugin.h @@ -33,6 +33,7 @@ #include "editor/editor_plugin.h" +class Button; class SkeletonIK3D; class SkeletonIK3DEditorPlugin : public EditorPlugin { diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index 20b3cf3618..8d0eac38c4 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -33,15 +33,16 @@ #include "core/config/project_settings.h" #include "core/io/resource_loader.h" #include "core/os/keyboard.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_file_system.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/gui/editor_file_dialog.h" #include "editor/scene_tree_dock.h" #include "scene/gui/center_container.h" #include "scene/gui/margin_container.h" +#include "scene/gui/option_button.h" #include "scene/gui/panel_container.h" #include "scene/gui/separator.h" @@ -131,8 +132,14 @@ void SpriteFramesEditor::_sheet_preview_draw() { Color accent = get_theme_color("accent_color", "Editor"); - for (const int &E : frames_selected) { - const int idx = E; + _sheet_sort_frames(); + + Ref<Font> font = get_theme_font(SNAME("bold"), SNAME("EditorFonts")); + int font_size = get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts")); + + for (int i = 0; i < frames_ordered.size(); ++i) { + const int idx = frames_ordered[i].second; + const int x = idx % frame_count.x; const int y = idx / frame_count.x; const Point2 pos = draw_offset + Point2(x, y) * (draw_frame_size + draw_sep); @@ -143,6 +150,15 @@ void SpriteFramesEditor::_sheet_preview_draw() { split_sheet_preview->draw_rect(Rect2(pos + Size2(3, 3), draw_frame_size - Size2(6, 6)), accent, false); split_sheet_preview->draw_rect(Rect2(pos + Size2(4, 4), draw_frame_size - Size2(8, 8)), Color(0, 0, 0, 1), false); split_sheet_preview->draw_rect(Rect2(pos + Size2(5, 5), draw_frame_size - Size2(10, 10)), Color(0, 0, 0, 1), false); + + const String text = itos(i); + const Vector2 string_size = font->get_string_size(text, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size); + + // Stop rendering text if too large. + if (string_size.x + 6 < draw_frame_size.x && string_size.y / 2 + 10 < draw_frame_size.y) { + split_sheet_preview->draw_string_outline(font, pos + Size2(5, 7) + Size2(0, string_size.y / 2), text, HORIZONTAL_ALIGNMENT_LEFT, string_size.x, font_size, 1, Color(0, 0, 0, 1)); + split_sheet_preview->draw_string(font, pos + Size2(5, 7) + Size2(0, string_size.y / 2), text, HORIZONTAL_ALIGNMENT_LEFT, string_size.x, font_size, Color(1, 1, 1)); + } } split_sheet_dialog->get_ok_button()->set_disabled(false); @@ -156,21 +172,24 @@ void SpriteFramesEditor::_sheet_preview_input(const Ref<InputEvent> &p_event) { if (idx != -1) { if (mb->is_shift_pressed() && last_frame_selected >= 0) { - //select multiple - int from = idx; - int to = last_frame_selected; - if (from > to) { - SWAP(from, to); - } + // Select multiple frames. + const int from = last_frame_selected; + const int to = idx; + + const int diff = ABS(to - from); + const int dir = SIGN(to - from); + + for (int i = 0; i <= diff; i++) { + const int this_idx = from + i * dir; - for (int i = from; i <= to; i++) { // Prevent double-toggling the same frame when moving the mouse when the mouse button is still held. - frames_toggled_by_mouse_hover.insert(idx); + frames_toggled_by_mouse_hover.insert(this_idx); if (mb->is_ctrl_pressed()) { - frames_selected.erase(i); - } else { - frames_selected.insert(i); + frames_selected.erase(this_idx); + } else if (!frames_selected.has(this_idx)) { + frames_selected.insert(this_idx, selected_count); + selected_count++; } } } else { @@ -180,13 +199,15 @@ void SpriteFramesEditor::_sheet_preview_input(const Ref<InputEvent> &p_event) { if (frames_selected.has(idx)) { frames_selected.erase(idx); } else { - frames_selected.insert(idx); + frames_selected.insert(idx, selected_count); + selected_count++; } } } if (last_frame_selected != idx || idx != -1) { last_frame_selected = idx; + frames_need_sort = true; split_sheet_preview->queue_redraw(); } } @@ -209,13 +230,19 @@ void SpriteFramesEditor::_sheet_preview_input(const Ref<InputEvent> &p_event) { if (frames_selected.has(idx)) { frames_selected.erase(idx); } else { - frames_selected.insert(idx); + frames_selected.insert(idx, selected_count); + selected_count++; } last_frame_selected = idx; + frames_need_sort = true; split_sheet_preview->queue_redraw(); } } + + if (frames_selected.is_empty()) { + selected_count = 0; + } } void SpriteFramesEditor::_sheet_scroll_input(const Ref<InputEvent> &p_event) { @@ -254,8 +281,11 @@ void SpriteFramesEditor::_sheet_add_frames() { undo_redo->create_action(TTR("Add Frame"), UndoRedo::MERGE_DISABLE, EditorNode::get_singleton()->get_edited_scene()); int fc = frames->get_frame_count(edited_anim); - for (const int &E : frames_selected) { - int idx = E; + _sheet_sort_frames(); + + for (const Pair<int, int> &pair : frames_ordered) { + const int idx = pair.second; + const Point2 frame_coords(idx % frame_count.x, idx / frame_count.x); Ref<AtlasTexture> at; @@ -300,21 +330,103 @@ void SpriteFramesEditor::_sheet_zoom_reset() { split_sheet_preview->set_custom_minimum_size(texture_size * sheet_zoom); } -void SpriteFramesEditor::_sheet_select_clear_all_frames() { - bool should_clear = true; +void SpriteFramesEditor::_sheet_order_selected(int p_option) { + frames_need_sort = true; + split_sheet_preview->queue_redraw(); +} + +void SpriteFramesEditor::_sheet_select_all_frames() { for (int i = 0; i < split_sheet_h->get_value() * split_sheet_v->get_value(); i++) { if (!frames_selected.has(i)) { - frames_selected.insert(i); - should_clear = false; + frames_selected.insert(i, selected_count); + selected_count++; + frames_need_sort = true; } } - if (should_clear) { - frames_selected.clear(); - } split_sheet_preview->queue_redraw(); } +void SpriteFramesEditor::_sheet_clear_all_frames() { + frames_selected.clear(); + selected_count = 0; + + split_sheet_preview->queue_redraw(); +} + +void SpriteFramesEditor::_sheet_sort_frames() { + if (!frames_need_sort) { + return; + } + frames_need_sort = false; + frames_ordered.resize(frames_selected.size()); + if (frames_selected.is_empty()) { + return; + } + + const Size2i frame_count = _get_frame_count(); + const int frame_order = split_sheet_order->get_selected_id(); + int index = 0; + + // Fill based on order. + for (const KeyValue<int, int> &from_pair : frames_selected) { + const int idx = from_pair.key; + + const int selection_order = from_pair.value; + + // Default to using selection order. + int order_by = selection_order; + + // Extract coordinates for sorting. + const int pos_frame_x = idx % frame_count.x; + const int pos_frame_y = idx / frame_count.x; + + const int neg_frame_x = frame_count.x - (pos_frame_x + 1); + const int neg_frame_y = frame_count.y - (pos_frame_y + 1); + + switch (frame_order) { + case FRAME_ORDER_LEFT_RIGHT_TOP_BOTTOM: { + order_by = frame_count.x * pos_frame_y + pos_frame_x; + } break; + + case FRAME_ORDER_LEFT_RIGHT_BOTTOM_TOP: { + order_by = frame_count.x * neg_frame_y + pos_frame_x; + } break; + + case FRAME_ORDER_RIGHT_LEFT_TOP_BOTTOM: { + order_by = frame_count.x * pos_frame_y + neg_frame_x; + } break; + + case FRAME_ORDER_RIGHT_LEFT_BOTTOM_TOP: { + order_by = frame_count.x * neg_frame_y + neg_frame_x; + } break; + + case FRAME_ORDER_TOP_BOTTOM_LEFT_RIGHT: { + order_by = pos_frame_y + frame_count.y * pos_frame_x; + } break; + + case FRAME_ORDER_TOP_BOTTOM_RIGHT_LEFT: { + order_by = pos_frame_y + frame_count.y * neg_frame_x; + } break; + + case FRAME_ORDER_BOTTOM_TOP_LEFT_RIGHT: { + order_by = neg_frame_y + frame_count.y * pos_frame_x; + } break; + + case FRAME_ORDER_BOTTOM_TOP_RIGHT_LEFT: { + order_by = neg_frame_y + frame_count.y * neg_frame_x; + } break; + } + + // Assign in vector. + frames_ordered.set(index, Pair<int, int>(order_by, idx)); + index++; + } + + // Sort frames. + frames_ordered.sort_custom<PairSort<int, int>>(); +} + void SpriteFramesEditor::_sheet_spin_changed(double p_value, int p_dominant_param) { if (updating_split_settings) { return; @@ -367,10 +479,25 @@ void SpriteFramesEditor::_sheet_spin_changed(double p_value, int p_dominant_para updating_split_settings = false; frames_selected.clear(); + selected_count = 0; last_frame_selected = -1; split_sheet_preview->queue_redraw(); } +void SpriteFramesEditor::_toggle_show_settings() { + split_sheet_settings_vb->set_visible(!split_sheet_settings_vb->is_visible()); + + _update_show_settings(); +} + +void SpriteFramesEditor::_update_show_settings() { + if (is_layout_rtl()) { + toggle_settings_button->set_icon(get_theme_icon(split_sheet_settings_vb->is_visible() ? SNAME("Back") : SNAME("Forward"), SNAME("EditorIcons"))); + } else { + toggle_settings_button->set_icon(get_theme_icon(split_sheet_settings_vb->is_visible() ? SNAME("Forward") : SNAME("Back"), SNAME("EditorIcons"))); + } +} + void SpriteFramesEditor::_prepare_sprite_sheet(const String &p_file) { Ref<Texture2D> texture = ResourceLoader::load(p_file); if (texture.is_null()) { @@ -378,6 +505,7 @@ void SpriteFramesEditor::_prepare_sprite_sheet(const String &p_file) { ERR_FAIL_COND(texture.is_null()); } frames_selected.clear(); + selected_count = 0; last_frame_selected = -1; bool new_texture = texture != split_sheet_preview->get_texture(); @@ -408,6 +536,7 @@ void SpriteFramesEditor::_prepare_sprite_sheet(const String &p_file) { // Reset zoom. _sheet_zoom_reset(); } + split_sheet_dialog->popup_centered_ratio(0.65); } @@ -450,6 +579,8 @@ void SpriteFramesEditor::_notification(int p_what) { split_sheet_zoom_reset->set_icon(get_theme_icon(SNAME("ZoomReset"), SNAME("EditorIcons"))); split_sheet_zoom_in->set_icon(get_theme_icon(SNAME("ZoomMore"), SNAME("EditorIcons"))); split_sheet_scroll->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("Tree"))); + + _update_show_settings(); } break; case NOTIFICATION_READY: { @@ -1769,82 +1900,58 @@ SpriteFramesEditor::SpriteFramesEditor() { split_sheet_dialog = memnew(ConfirmationDialog); add_child(split_sheet_dialog); - VBoxContainer *split_sheet_vb = memnew(VBoxContainer); - split_sheet_dialog->add_child(split_sheet_vb); split_sheet_dialog->set_title(TTR("Select Frames")); split_sheet_dialog->connect("confirmed", callable_mp(this, &SpriteFramesEditor::_sheet_add_frames)); HBoxContainer *split_sheet_hb = memnew(HBoxContainer); + split_sheet_dialog->add_child(split_sheet_hb); + split_sheet_hb->set_h_size_flags(SIZE_EXPAND_FILL); + split_sheet_hb->set_v_size_flags(SIZE_EXPAND_FILL); - split_sheet_hb->add_child(memnew(Label(TTR("Horizontal:")))); - split_sheet_h = memnew(SpinBox); - split_sheet_h->set_min(1); - split_sheet_h->set_max(128); - split_sheet_h->set_step(1); - split_sheet_hb->add_child(split_sheet_h); - split_sheet_h->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_FRAME_COUNT)); - - split_sheet_hb->add_child(memnew(Label(TTR("Vertical:")))); - split_sheet_v = memnew(SpinBox); - split_sheet_v->set_min(1); - split_sheet_v->set_max(128); - split_sheet_v->set_step(1); - split_sheet_hb->add_child(split_sheet_v); - split_sheet_v->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_FRAME_COUNT)); - - split_sheet_hb->add_child(memnew(VSeparator)); - split_sheet_hb->add_child(memnew(Label(TTR("Size:")))); - split_sheet_size_x = memnew(SpinBox); - split_sheet_size_x->set_min(1); - split_sheet_size_x->set_step(1); - split_sheet_size_x->set_suffix("px"); - split_sheet_size_x->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_SIZE)); - split_sheet_hb->add_child(split_sheet_size_x); - split_sheet_size_y = memnew(SpinBox); - split_sheet_size_y->set_min(1); - split_sheet_size_y->set_step(1); - split_sheet_size_y->set_suffix("px"); - split_sheet_size_y->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_SIZE)); - split_sheet_hb->add_child(split_sheet_size_y); - - split_sheet_hb->add_child(memnew(VSeparator)); - split_sheet_hb->add_child(memnew(Label(TTR("Separation:")))); - split_sheet_sep_x = memnew(SpinBox); - split_sheet_sep_x->set_min(0); - split_sheet_sep_x->set_step(1); - split_sheet_sep_x->set_suffix("px"); - split_sheet_sep_x->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_USE_CURRENT)); - split_sheet_hb->add_child(split_sheet_sep_x); - split_sheet_sep_y = memnew(SpinBox); - split_sheet_sep_y->set_min(0); - split_sheet_sep_y->set_step(1); - split_sheet_sep_y->set_suffix("px"); - split_sheet_sep_y->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_USE_CURRENT)); - split_sheet_hb->add_child(split_sheet_sep_y); - - split_sheet_hb->add_child(memnew(VSeparator)); - split_sheet_hb->add_child(memnew(Label(TTR("Offset:")))); - split_sheet_offset_x = memnew(SpinBox); - split_sheet_offset_x->set_min(0); - split_sheet_offset_x->set_step(1); - split_sheet_offset_x->set_suffix("px"); - split_sheet_offset_x->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_USE_CURRENT)); - split_sheet_hb->add_child(split_sheet_offset_x); - split_sheet_offset_y = memnew(SpinBox); - split_sheet_offset_y->set_min(0); - split_sheet_offset_y->set_step(1); - split_sheet_offset_y->set_suffix("px"); - split_sheet_offset_y->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_USE_CURRENT)); - split_sheet_hb->add_child(split_sheet_offset_y); - - split_sheet_hb->add_spacer(); - - Button *select_clear_all = memnew(Button); - select_clear_all->set_text(TTR("Select/Clear All Frames")); - select_clear_all->connect("pressed", callable_mp(this, &SpriteFramesEditor::_sheet_select_clear_all_frames)); - split_sheet_hb->add_child(select_clear_all); - - split_sheet_vb->add_child(split_sheet_hb); + VBoxContainer *split_sheet_vb = memnew(VBoxContainer); + split_sheet_hb->add_child(split_sheet_vb); + split_sheet_vb->set_h_size_flags(SIZE_EXPAND_FILL); + split_sheet_vb->set_v_size_flags(SIZE_EXPAND_FILL); + + HBoxContainer *split_sheet_menu_hb = memnew(HBoxContainer); + + split_sheet_menu_hb->add_child(memnew(Label(TTR("Frame Order")))); + + split_sheet_order = memnew(OptionButton); + split_sheet_order->add_item(TTR("As Selected"), FRAME_ORDER_SELECTION); + split_sheet_order->add_separator(TTR("By Row")); + split_sheet_order->add_item(TTR("Left to Right, Top to Bottom"), FRAME_ORDER_LEFT_RIGHT_TOP_BOTTOM); + split_sheet_order->add_item(TTR("Left to Right, Bottom to Top"), FRAME_ORDER_LEFT_RIGHT_BOTTOM_TOP); + split_sheet_order->add_item(TTR("Right to Left, Top to Bottom"), FRAME_ORDER_RIGHT_LEFT_TOP_BOTTOM); + split_sheet_order->add_item(TTR("Right to Left, Bottom to Top"), FRAME_ORDER_RIGHT_LEFT_BOTTOM_TOP); + split_sheet_order->add_separator(TTR("By Column")); + split_sheet_order->add_item(TTR("Top to Bottom, Left to Right"), FRAME_ORDER_TOP_BOTTOM_LEFT_RIGHT); + split_sheet_order->add_item(TTR("Top to Bottom, Right to Left"), FRAME_ORDER_TOP_BOTTOM_RIGHT_LEFT); + split_sheet_order->add_item(TTR("Bottom to Top, Left to Right"), FRAME_ORDER_BOTTOM_TOP_LEFT_RIGHT); + split_sheet_order->add_item(TTR("Bottom to Top, Right to Left"), FRAME_ORDER_BOTTOM_TOP_RIGHT_LEFT); + split_sheet_order->connect("item_selected", callable_mp(this, &SpriteFramesEditor::_sheet_order_selected)); + split_sheet_menu_hb->add_child(split_sheet_order); + + Button *select_all = memnew(Button); + select_all->set_text(TTR("Select All")); + select_all->connect("pressed", callable_mp(this, &SpriteFramesEditor::_sheet_select_all_frames)); + split_sheet_menu_hb->add_child(select_all); + + Button *clear_all = memnew(Button); + clear_all->set_text(TTR("Select None")); + clear_all->connect("pressed", callable_mp(this, &SpriteFramesEditor::_sheet_clear_all_frames)); + split_sheet_menu_hb->add_child(clear_all); + + split_sheet_menu_hb->add_spacer(); + + toggle_settings_button = memnew(Button); + toggle_settings_button->set_h_size_flags(SIZE_SHRINK_END); + toggle_settings_button->set_flat(true); + toggle_settings_button->connect("pressed", callable_mp(this, &SpriteFramesEditor::_toggle_show_settings)); + toggle_settings_button->set_tooltip_text(TTR("Toggle Settings Panel")); + split_sheet_menu_hb->add_child(toggle_settings_button); + + split_sheet_vb->add_child(split_sheet_menu_hb); PanelContainer *split_sheet_panel = memnew(PanelContainer); split_sheet_panel->set_h_size_flags(SIZE_EXPAND_FILL); @@ -1896,6 +2003,120 @@ SpriteFramesEditor::SpriteFramesEditor() { split_sheet_zoom_in->connect("pressed", callable_mp(this, &SpriteFramesEditor::_sheet_zoom_in)); split_sheet_zoom_hb->add_child(split_sheet_zoom_in); + split_sheet_settings_vb = memnew(VBoxContainer); + split_sheet_settings_vb->set_v_size_flags(SIZE_EXPAND_FILL); + + HBoxContainer *split_sheet_h_hb = memnew(HBoxContainer); + split_sheet_h_hb->set_h_size_flags(SIZE_EXPAND_FILL); + + Label *split_sheet_h_label = memnew(Label(TTR("Horizontal"))); + split_sheet_h_label->set_h_size_flags(SIZE_EXPAND_FILL); + split_sheet_h_hb->add_child(split_sheet_h_label); + + split_sheet_h = memnew(SpinBox); + split_sheet_h->set_h_size_flags(SIZE_EXPAND_FILL); + split_sheet_h->set_min(1); + split_sheet_h->set_max(128); + split_sheet_h->set_step(1); + split_sheet_h_hb->add_child(split_sheet_h); + split_sheet_h->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_FRAME_COUNT)); + split_sheet_settings_vb->add_child(split_sheet_h_hb); + + HBoxContainer *split_sheet_v_hb = memnew(HBoxContainer); + split_sheet_v_hb->set_h_size_flags(SIZE_EXPAND_FILL); + + Label *split_sheet_v_label = memnew(Label(TTR("Vertical"))); + split_sheet_v_label->set_h_size_flags(SIZE_EXPAND_FILL); + split_sheet_v_hb->add_child(split_sheet_v_label); + + split_sheet_v = memnew(SpinBox); + split_sheet_v->set_h_size_flags(SIZE_EXPAND_FILL); + split_sheet_v->set_min(1); + split_sheet_v->set_max(128); + split_sheet_v->set_step(1); + split_sheet_v_hb->add_child(split_sheet_v); + split_sheet_v->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_FRAME_COUNT)); + split_sheet_settings_vb->add_child(split_sheet_v_hb); + + HBoxContainer *split_sheet_size_hb = memnew(HBoxContainer); + split_sheet_size_hb->set_h_size_flags(SIZE_EXPAND_FILL); + + Label *split_sheet_size_label = memnew(Label(TTR("Size"))); + split_sheet_size_label->set_h_size_flags(SIZE_EXPAND_FILL); + split_sheet_size_label->set_v_size_flags(SIZE_SHRINK_BEGIN); + split_sheet_size_hb->add_child(split_sheet_size_label); + + VBoxContainer *split_sheet_size_vb = memnew(VBoxContainer); + split_sheet_size_vb->set_h_size_flags(SIZE_EXPAND_FILL); + split_sheet_size_x = memnew(SpinBox); + split_sheet_size_x->set_h_size_flags(SIZE_EXPAND_FILL); + split_sheet_size_x->set_min(1); + split_sheet_size_x->set_step(1); + split_sheet_size_x->set_suffix("px"); + split_sheet_size_x->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_SIZE)); + split_sheet_size_vb->add_child(split_sheet_size_x); + split_sheet_size_y = memnew(SpinBox); + split_sheet_size_y->set_h_size_flags(SIZE_EXPAND_FILL); + split_sheet_size_y->set_min(1); + split_sheet_size_y->set_step(1); + split_sheet_size_y->set_suffix("px"); + split_sheet_size_y->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_SIZE)); + split_sheet_size_vb->add_child(split_sheet_size_y); + split_sheet_size_hb->add_child(split_sheet_size_vb); + split_sheet_settings_vb->add_child(split_sheet_size_hb); + + HBoxContainer *split_sheet_sep_hb = memnew(HBoxContainer); + split_sheet_sep_hb->set_h_size_flags(SIZE_EXPAND_FILL); + + Label *split_sheet_sep_label = memnew(Label(TTR("Separation"))); + split_sheet_sep_label->set_h_size_flags(SIZE_EXPAND_FILL); + split_sheet_sep_label->set_v_size_flags(SIZE_SHRINK_BEGIN); + split_sheet_sep_hb->add_child(split_sheet_sep_label); + + VBoxContainer *split_sheet_sep_vb = memnew(VBoxContainer); + split_sheet_sep_vb->set_h_size_flags(SIZE_EXPAND_FILL); + split_sheet_sep_x = memnew(SpinBox); + split_sheet_sep_x->set_min(0); + split_sheet_sep_x->set_step(1); + split_sheet_sep_x->set_suffix("px"); + split_sheet_sep_x->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_USE_CURRENT)); + split_sheet_sep_vb->add_child(split_sheet_sep_x); + split_sheet_sep_y = memnew(SpinBox); + split_sheet_sep_y->set_min(0); + split_sheet_sep_y->set_step(1); + split_sheet_sep_y->set_suffix("px"); + split_sheet_sep_y->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_USE_CURRENT)); + split_sheet_sep_vb->add_child(split_sheet_sep_y); + split_sheet_sep_hb->add_child(split_sheet_sep_vb); + split_sheet_settings_vb->add_child(split_sheet_sep_hb); + + HBoxContainer *split_sheet_offset_hb = memnew(HBoxContainer); + split_sheet_offset_hb->set_h_size_flags(SIZE_EXPAND_FILL); + + Label *split_sheet_offset_label = memnew(Label(TTR("Offset"))); + split_sheet_offset_label->set_h_size_flags(SIZE_EXPAND_FILL); + split_sheet_offset_label->set_v_size_flags(SIZE_SHRINK_BEGIN); + split_sheet_offset_hb->add_child(split_sheet_offset_label); + + VBoxContainer *split_sheet_offset_vb = memnew(VBoxContainer); + split_sheet_offset_vb->set_h_size_flags(SIZE_EXPAND_FILL); + split_sheet_offset_x = memnew(SpinBox); + split_sheet_offset_x->set_min(0); + split_sheet_offset_x->set_step(1); + split_sheet_offset_x->set_suffix("px"); + split_sheet_offset_x->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_USE_CURRENT)); + split_sheet_offset_vb->add_child(split_sheet_offset_x); + split_sheet_offset_y = memnew(SpinBox); + split_sheet_offset_y->set_min(0); + split_sheet_offset_y->set_step(1); + split_sheet_offset_y->set_suffix("px"); + split_sheet_offset_y->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_sheet_spin_changed).bind(PARAM_USE_CURRENT)); + split_sheet_offset_vb->add_child(split_sheet_offset_y); + split_sheet_offset_hb->add_child(split_sheet_offset_vb); + split_sheet_settings_vb->add_child(split_sheet_offset_hb); + + split_sheet_hb->add_child(split_sheet_settings_vb); + file_split_sheet = memnew(EditorFileDialog); file_split_sheet->set_title(TTR("Create Frames from Sprite Sheet")); file_split_sheet->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); diff --git a/editor/plugins/sprite_frames_editor_plugin.h b/editor/plugins/sprite_frames_editor_plugin.h index 1dfb909388..9317e94be0 100644 --- a/editor/plugins/sprite_frames_editor_plugin.h +++ b/editor/plugins/sprite_frames_editor_plugin.h @@ -45,6 +45,7 @@ #include "scene/gui/texture_rect.h" #include "scene/gui/tree.h" +class OptionButton; class EditorFileDialog; class EditorSpriteFramesFrame : public Resource { @@ -68,6 +69,22 @@ class SpriteFramesEditor : public HSplitContainer { }; int dominant_param = PARAM_FRAME_COUNT; + enum { + FRAME_ORDER_SELECTION, // Order frames were selected in. + + // By Row. + FRAME_ORDER_LEFT_RIGHT_TOP_BOTTOM, + FRAME_ORDER_LEFT_RIGHT_BOTTOM_TOP, + FRAME_ORDER_RIGHT_LEFT_TOP_BOTTOM, + FRAME_ORDER_RIGHT_LEFT_BOTTOM_TOP, + + // By Column. + FRAME_ORDER_TOP_BOTTOM_LEFT_RIGHT, + FRAME_ORDER_TOP_BOTTOM_RIGHT_LEFT, + FRAME_ORDER_BOTTOM_TOP_LEFT_RIGHT, + FRAME_ORDER_BOTTOM_TOP_RIGHT_LEFT, + }; + bool read_only = false; Ref<Texture2D> autoplay_icon; @@ -121,6 +138,7 @@ class SpriteFramesEditor : public HSplitContainer { ConfirmationDialog *split_sheet_dialog = nullptr; ScrollContainer *split_sheet_scroll = nullptr; TextureRect *split_sheet_preview = nullptr; + VBoxContainer *split_sheet_settings_vb = nullptr; SpinBox *split_sheet_h = nullptr; SpinBox *split_sheet_v = nullptr; SpinBox *split_sheet_size_x = nullptr; @@ -132,9 +150,14 @@ class SpriteFramesEditor : public HSplitContainer { Button *split_sheet_zoom_out = nullptr; Button *split_sheet_zoom_reset = nullptr; Button *split_sheet_zoom_in = nullptr; + Button *toggle_settings_button = nullptr; + OptionButton *split_sheet_order = nullptr; EditorFileDialog *file_split_sheet = nullptr; - HashSet<int> frames_selected; + HashMap<int, int> frames_selected; // Key is frame index. Value is selection order. HashSet<int> frames_toggled_by_mouse_hover; + Vector<Pair<int, int>> frames_ordered; // First is the index to be ordered by. Second is the actual frame index. + int selected_count = 0; + bool frames_need_sort = false; int last_frame_selected = 0; float scale_ratio; @@ -206,7 +229,12 @@ class SpriteFramesEditor : public HSplitContainer { void _sheet_zoom_in(); void _sheet_zoom_out(); void _sheet_zoom_reset(); - void _sheet_select_clear_all_frames(); + void _sheet_order_selected(int p_option); + void _sheet_select_all_frames(); + void _sheet_clear_all_frames(); + void _sheet_sort_frames(); + void _toggle_show_settings(); + void _update_show_settings(); void _edit(); void _regist_scene_undo(EditorUndoRedoManager *undo_redo); diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index c91d653692..715db9cf51 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -31,15 +31,22 @@ #include "theme_editor_plugin.h" #include "core/os/keyboard.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_resource_picker.h" #include "editor/editor_scale.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/gui/editor_file_dialog.h" #include "editor/progress_dialog.h" +#include "scene/gui/check_button.h" #include "scene/gui/color_picker.h" +#include "scene/gui/item_list.h" +#include "scene/gui/option_button.h" #include "scene/gui/panel_container.h" +#include "scene/gui/scroll_container.h" #include "scene/gui/split_container.h" +#include "scene/gui/tab_bar.h" +#include "scene/gui/tab_container.h" +#include "scene/gui/texture_rect.h" #include "scene/theme/theme_db.h" void ThemeItemImportTree::_update_items_tree() { diff --git a/editor/plugins/theme_editor_plugin.h b/editor/plugins/theme_editor_plugin.h index c8c944118c..077ce8e8f7 100644 --- a/editor/plugins/theme_editor_plugin.h +++ b/editor/plugins/theme_editor_plugin.h @@ -33,20 +33,21 @@ #include "editor/editor_plugin.h" #include "editor/plugins/theme_editor_preview.h" -#include "scene/gui/check_button.h" #include "scene/gui/dialogs.h" -#include "scene/gui/item_list.h" #include "scene/gui/margin_container.h" -#include "scene/gui/option_button.h" -#include "scene/gui/scroll_container.h" -#include "scene/gui/tab_bar.h" -#include "scene/gui/texture_rect.h" #include "scene/gui/tree.h" #include "scene/resources/theme.h" +class Button; +class CheckButton; class EditorFileDialog; +class ItemList; +class Label; +class OptionButton; class PanelContainer; +class TabBar; class TabContainer; +class TextureRect; class ThemeItemImportTree : public VBoxContainer { GDCLASS(ThemeItemImportTree, VBoxContainer); diff --git a/editor/plugins/theme_editor_preview.cpp b/editor/plugins/theme_editor_preview.cpp index 5218ef67c5..f4a6c4af2d 100644 --- a/editor/plugins/theme_editor_preview.cpp +++ b/editor/plugins/theme_editor_preview.cpp @@ -39,7 +39,11 @@ #include "scene/gui/check_box.h" #include "scene/gui/check_button.h" #include "scene/gui/color_picker.h" +#include "scene/gui/color_rect.h" +#include "scene/gui/margin_container.h" #include "scene/gui/progress_bar.h" +#include "scene/gui/scroll_container.h" +#include "scene/gui/tab_container.h" #include "scene/gui/text_edit.h" #include "scene/gui/tree.h" #include "scene/resources/packed_scene.h" diff --git a/editor/plugins/theme_editor_preview.h b/editor/plugins/theme_editor_preview.h index 640a931c99..bd9663904a 100644 --- a/editor/plugins/theme_editor_preview.h +++ b/editor/plugins/theme_editor_preview.h @@ -32,13 +32,13 @@ #define THEME_EDITOR_PREVIEW_H #include "scene/gui/box_container.h" -#include "scene/gui/button.h" -#include "scene/gui/color_rect.h" -#include "scene/gui/margin_container.h" -#include "scene/gui/scroll_container.h" #include "scene/resources/theme.h" +class Button; class ColorPickerButton; +class ColorRect; +class MarginContainer; +class ScrollContainer; class ThemeEditorPreview : public VBoxContainer { GDCLASS(ThemeEditorPreview, VBoxContainer); diff --git a/editor/plugins/tiles/atlas_merging_dialog.cpp b/editor/plugins/tiles/atlas_merging_dialog.cpp index ce5da811c1..274d52da47 100644 --- a/editor/plugins/tiles/atlas_merging_dialog.cpp +++ b/editor/plugins/tiles/atlas_merging_dialog.cpp @@ -30,10 +30,9 @@ #include "atlas_merging_dialog.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_scale.h" #include "editor/editor_undo_redo_manager.h" - +#include "editor/gui/editor_file_dialog.h" #include "scene/gui/control.h" #include "scene/gui/split_container.h" diff --git a/editor/plugins/tiles/tile_atlas_view.h b/editor/plugins/tiles/tile_atlas_view.h index 2be3fadd21..0e2ae49f0a 100644 --- a/editor/plugins/tiles/tile_atlas_view.h +++ b/editor/plugins/tiles/tile_atlas_view.h @@ -31,7 +31,7 @@ #ifndef TILE_ATLAS_VIEW_H #define TILE_ATLAS_VIEW_H -#include "editor/editor_zoom_widget.h" +#include "editor/gui/editor_zoom_widget.h" #include "scene/gui/box_container.h" #include "scene/gui/button.h" #include "scene/gui/center_container.h" diff --git a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp index 101ec5f66c..9350467176 100644 --- a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp @@ -38,7 +38,9 @@ #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "scene/gui/button.h" #include "scene/gui/item_list.h" +#include "scene/gui/label.h" #include "scene/gui/split_container.h" #include "core/core_string_names.h" diff --git a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.h b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.h index 2a0e8595c4..dd9ec3228d 100644 --- a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.h +++ b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.h @@ -33,10 +33,12 @@ #include "editor/editor_inspector.h" #include "scene/gui/box_container.h" -#include "scene/gui/button.h" -#include "scene/gui/item_list.h" #include "scene/resources/tile_set.h" +class Button; +class ItemList; +class Label; + class TileSetScenesCollectionSourceEditor : public HBoxContainer { GDCLASS(TileSetScenesCollectionSourceEditor, HBoxContainer); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index af761a2cea..a563d17c57 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -5931,7 +5931,7 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("ATanH", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ATANH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); add_options.push_back(AddOption("ATanH", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ATANH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("ATanH", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ATANH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); - add_options.push_back(AddOption("Ceil", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), { VisualShaderNodeVectorFunc::FUNC_CEIL }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); + add_options.push_back(AddOption("Ceil", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), { VisualShaderNodeVectorFunc::FUNC_CEIL, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); add_options.push_back(AddOption("Ceil", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), { VisualShaderNodeVectorFunc::FUNC_CEIL, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Ceil", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), { VisualShaderNodeVectorFunc::FUNC_CEIL, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); add_options.push_back(AddOption("Clamp", "Vector/Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), { VisualShaderNodeClamp::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); diff --git a/editor/plugins/voxel_gi_editor_plugin.cpp b/editor/plugins/voxel_gi_editor_plugin.cpp index 1087a50df6..9906399d67 100644 --- a/editor/plugins/voxel_gi_editor_plugin.cpp +++ b/editor/plugins/voxel_gi_editor_plugin.cpp @@ -30,8 +30,8 @@ #include "voxel_gi_editor_plugin.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_node.h" +#include "editor/gui/editor_file_dialog.h" void VoxelGIEditorPlugin::_bake() { if (voxel_gi) { diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 9776104028..e8cea14ce6 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -41,12 +41,12 @@ #include "core/os/os.h" #include "core/string/translation.h" #include "core/version.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_paths.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_themes.h" #include "editor/editor_vcs_interface.h" +#include "editor/gui/editor_file_dialog.h" #include "editor/plugins/asset_library_editor_plugin.h" #include "main/main.h" #include "scene/gui/center_container.h" @@ -2172,7 +2172,7 @@ void ProjectManager::_open_selected_projects_ask() { return; } - const Size2i popup_min_size = Size2i(600.0 * EDSCALE, 400.0 * EDSCALE); + const Size2i popup_min_size = Size2i(600.0 * EDSCALE, 0); if (selected_list.size() > 1) { multi_open_ask->set_text(vformat(TTR("You requested to open %d projects in parallel. Do you confirm?\nNote that usual checks for engine version compatibility will be bypassed."), selected_list.size())); @@ -2257,7 +2257,7 @@ void ProjectManager::_open_selected_projects_ask() { void ProjectManager::_full_convert_button_pressed() { ask_update_settings->hide(); - ask_full_convert_dialog->popup_centered(Size2i(600.0 * EDSCALE, 400.0 * EDSCALE)); + ask_full_convert_dialog->popup_centered(Size2i(600.0 * EDSCALE, 0)); ask_full_convert_dialog->get_cancel_button()->grab_focus(); } diff --git a/editor/register_editor_types.cpp b/editor/register_editor_types.cpp index 44624d201b..d0c441b027 100644 --- a/editor/register_editor_types.cpp +++ b/editor/register_editor_types.cpp @@ -34,7 +34,6 @@ #include "editor/debugger/debug_adapter/debug_adapter_server.h" #include "editor/editor_command_palette.h" #include "editor/editor_feature_profile.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_file_system.h" #include "editor/editor_node.h" #include "editor/editor_paths.h" @@ -45,6 +44,8 @@ #include "editor/editor_translation_parser.h" #include "editor/editor_undo_redo_manager.h" #include "editor/filesystem_dock.h" +#include "editor/gui/editor_file_dialog.h" +#include "editor/gui/editor_spin_slider.h" #include "editor/import/editor_import_plugin.h" #include "editor/import/resource_importer_scene.h" #include "editor/plugins/animation_tree_editor_plugin.h" diff --git a/editor/rename_dialog.cpp b/editor/rename_dialog.cpp index c3a99e96ef..f42f34e110 100644 --- a/editor/rename_dialog.cpp +++ b/editor/rename_dialog.cpp @@ -41,10 +41,14 @@ #include "editor/editor_undo_redo_manager.h" #include "modules/regex/regex.h" #include "plugins/script_editor_plugin.h" +#include "scene/gui/check_box.h" +#include "scene/gui/check_button.h" #include "scene/gui/control.h" #include "scene/gui/grid_container.h" #include "scene/gui/label.h" +#include "scene/gui/option_button.h" #include "scene/gui/separator.h" +#include "scene/gui/spin_box.h" #include "scene/gui/tab_container.h" RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor) { diff --git a/editor/rename_dialog.h b/editor/rename_dialog.h index 47ff51f52a..6821cab982 100644 --- a/editor/rename_dialog.h +++ b/editor/rename_dialog.h @@ -34,13 +34,17 @@ #include "modules/modules_enabled.gen.h" // For regex. #ifdef MODULE_REGEX_ENABLED -#include "editor/scene_tree_editor.h" -#include "scene/gui/check_box.h" -#include "scene/gui/check_button.h" +#include "editor/gui/scene_tree_editor.h" #include "scene/gui/dialogs.h" -#include "scene/gui/option_button.h" -#include "scene/gui/spin_box.h" -#include "scene/gui/tab_container.h" +#include "scene/gui/line_edit.h" + +class Button; +class CheckBox; +class CheckButton; +class Label; +class OptionButton; +class SpinBox; +class TabContainer; class RenameDialog : public ConfirmationDialog { GDCLASS(RenameDialog, ConfirmationDialog); diff --git a/editor/reparent_dialog.cpp b/editor/reparent_dialog.cpp index 9f61d63a80..ec5208b549 100644 --- a/editor/reparent_dialog.cpp +++ b/editor/reparent_dialog.cpp @@ -31,9 +31,9 @@ #include "reparent_dialog.h" #include "core/string/print_string.h" +#include "editor/gui/scene_tree_editor.h" #include "scene/gui/box_container.h" -#include "scene/gui/label.h" -#include "scene/gui/tree.h" +#include "scene/gui/check_box.h" void ReparentDialog::_notification(int p_what) { switch (p_what) { diff --git a/editor/reparent_dialog.h b/editor/reparent_dialog.h index af26eada3d..2ca26fcde3 100644 --- a/editor/reparent_dialog.h +++ b/editor/reparent_dialog.h @@ -31,12 +31,10 @@ #ifndef REPARENT_DIALOG_H #define REPARENT_DIALOG_H -#include "editor/scene_tree_editor.h" -#include "scene/gui/button.h" -#include "scene/gui/check_box.h" -#include "scene/gui/check_button.h" #include "scene/gui/dialogs.h" -#include "scene/gui/line_edit.h" + +class CheckBox; +class SceneTreeEditor; class ReparentDialog : public ConfirmationDialog { GDCLASS(ReparentDialog, ConfirmationDialog); diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 7e5d85e1a8..968cd5ab23 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -38,13 +38,13 @@ #include "core/os/keyboard.h" #include "editor/debugger/editor_debugger_node.h" #include "editor/editor_feature_profile.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_paths.h" #include "editor/editor_quick_open.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/gui/editor_file_dialog.h" #include "editor/inspector_dock.h" #include "editor/multi_node_edit.h" #include "editor/plugins/animation_player_editor_plugin.h" diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h index 52a7d6d6c1..779bfd53e3 100644 --- a/editor/scene_tree_dock.h +++ b/editor/scene_tree_dock.h @@ -31,9 +31,8 @@ #ifndef SCENE_TREE_DOCK_H #define SCENE_TREE_DOCK_H -#include "scene_tree_editor.h" - #include "editor/editor_data.h" +#include "editor/gui/scene_tree_editor.h" #include "editor/script_create_dialog.h" #include "scene/gui/box_container.h" #include "scene/resources/animation.h" diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index 599f2ea6d2..f3f0e7308c 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -35,12 +35,12 @@ #include "core/io/resource_saver.h" #include "core/string/string_builder.h" #include "editor/create_dialog.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_file_system.h" #include "editor/editor_node.h" #include "editor/editor_paths.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/gui/editor_file_dialog.h" static String _get_parent_class_of_script(String p_path) { if (!ResourceLoader::exists(p_path, "Script")) { diff --git a/editor/shader_create_dialog.cpp b/editor/shader_create_dialog.cpp index 443237b448..7d7ea2f509 100644 --- a/editor/shader_create_dialog.cpp +++ b/editor/shader_create_dialog.cpp @@ -31,8 +31,8 @@ #include "shader_create_dialog.h" #include "core/config/project_settings.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_scale.h" +#include "editor/gui/editor_file_dialog.h" #include "scene/resources/shader_include.h" #include "scene/resources/visual_shader.h" #include "servers/rendering/shader_types.h" diff --git a/logo_outlined.png b/logo_outlined.png Binary files differindex 44b85cde57..f834ec395c 100644 --- a/logo_outlined.png +++ b/logo_outlined.png diff --git a/logo_outlined.svg b/logo_outlined.svg index 4079a1dd56..8ddc564295 100644 --- a/logo_outlined.svg +++ b/logo_outlined.svg @@ -1,23 +1,23 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" id="svg2" version="1.1" - inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)" + inkscape:version="1.2.2 (b0a8486541, 2022-12-01)" xml:space="preserve" width="1024" height="414" viewBox="0 0 960.00002 388.12499" sodipodi:docname="logo_outlined.svg" - inkscape:export-filename="/home/riteo/srg/godot-riteo/logo_outlined.png" + inkscape:export-filename="logo_outlined.png" inkscape:export-xdpi="48" - inkscape:export-ydpi="48"><metadata + inkscape:export-ydpi="48" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"><metadata id="metadata8"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs @@ -36,14 +36,14 @@ inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-width="1916" - inkscape:window-height="1025" + inkscape:window-height="1036" id="namedview4" showgrid="false" inkscape:zoom="1.2041016" - inkscape:cx="512" - inkscape:cy="207" - inkscape:window-x="1360" - inkscape:window-y="53" + inkscape:cx="519.88968" + inkscape:cy="232.95376" + inkscape:window-x="1920" + inkscape:window-y="20" inkscape:window-maximized="1" inkscape:current-layer="g14" fit-margin-top="48" @@ -62,7 +62,9 @@ inkscape:snap-bbox-midpoints="false" inkscape:object-nodes="true" inkscape:snap-others="false" - units="px" /><g + units="px" + inkscape:showpageshadow="2" + inkscape:deskcolor="#d1d1d1" /><g id="g10" inkscape:groupmode="layer" inkscape:label="godot_engine_logo_2017_curves-01" @@ -92,10 +94,14 @@ style="stroke:none;stroke-width:10.60874228;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill" /><g id="g36" transform="matrix(1.1310535,0,0,1.1310535,468.26549,336.71278)" - style="stroke:none;stroke-width:10.60874228;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"><path - id="path38" - style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:15.5885606;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill" - d="m 0,0 c -6.078,0.094 -13.034,-1.173 -13.034,-1.173 v -11.863 h 6.995 l -0.078,-5.288 c 0,-1.959 -1.942,-2.943 -5.815,-2.943 -3.878,0 -7.303,1.642 -10.274,4.917 -2.978,3.279 -4.459,8.072 -4.459,14.388 0,6.329 1.447,10.995 4.345,14.006 2.892,3.008 6.683,4.517 11.346,4.517 1.959,0 3.987,-0.316 6.096,-0.961 2.11,-0.639 3.519,-1.238 4.238,-1.799 0.713,-0.577 1.391,-0.85 2.032,-0.85 0.638,0 1.671,0.746 3.1,2.255 1.431,1.505 2.713,3.786 3.844,6.827 1.126,3.057 1.69,5.4 1.69,7.062 0,1.649 -0.036,2.786 -0.109,3.386 -1.581,1.73 -4.499,3.102 -8.755,4.122 -4.248,1.017 -9.011,1.522 -14.28,1.522 -11.594,0 -20.66,-3.65 -27.207,-10.95 -6.552,-7.303 -9.822,-16.783 -9.822,-28.452 0,-13.701 3.347,-24.087 10.041,-31.162 6.706,-7.074 15.51,-10.607 26.425,-10.607 5.87,0 11.08,0.505 15.632,1.522 4.557,1.013 7.586,2.053 9.093,3.105 l 0.452,35.33 C 11.496,-1.036 6.078,-0.104 0,0 m 283.58148,-40.1198 c 0,-1.496 -3.721,-2.255 -11.176,-2.255 -7.448,0 -11.18,0.759 -11.18,2.255 v 56.681 h -13.545 c -1.281,0 -2.185,1.727 -2.71,5.198 -0.226,1.652 -0.334,3.343 -0.334,5.077 0,1.724 0.108,3.422 0.334,5.077 0.525,3.462 1.429,5.202 2.71,5.202 h 49.112 c 1.279,0 2.179,-1.74 2.712,-5.202 0.221,-1.655 0.335,-3.353 0.335,-5.077 0,-1.734 -0.114,-3.425 -0.335,-5.077 -0.533,-3.471 -1.433,-5.198 -2.712,-5.198 h -13.211 z M 205.6005,16.447401 c -3.612,0 -6.645,-1.659 -9.095,-4.967 -2.44,-3.3110004 -3.662,-7.9580004 -3.662,-13.9380004 0,-5.993 1.169,-10.5809996 3.499,-13.7779996 2.33,-3.207 5.398,-4.804 9.2,-4.804 3.801,0 6.89,1.617 9.258,4.862 2.372,3.233 3.56,7.8609996 3.56,13.8859996 0,6.02 -1.225,10.654 -3.671,13.8900004 -2.447,3.232 -5.473,4.849 -9.089,4.849 m -0.058,-59.493 c -10.577,0 -19.193,3.46 -25.851,10.379 -6.663,6.925 -9.993,17.03 -9.993,30.3139996 0,13.2920004 3.367,23.3560004 10.1,30.2090004 6.741,6.844 15.431,10.269 26.086,10.269 10.651,0 19.246,-3.363 25.797,-10.109 6.55,-6.733 9.822,-16.94 9.822,-30.5910004 0,-13.6609996 -3.349,-23.8219996 -10.05,-30.4899996 -6.699,-6.654 -15.338,-9.981 -25.911,-9.981 m -82.13011,58.710808 v -33.768 c 0,-1.577 0.116,-2.571 0.342,-2.988 0.224,-0.415 0.903,-0.623 2.029,-0.623 4.144,0 7.283,1.548 9.429,4.634 2.151,3.083 3.215,8.2160005 3.215,15.4050005 0,7.192 -1.113,11.8779995 -3.325,14.0549995 -2.223,2.183 -5.744,3.285 -10.561,3.285 z m -21.675,-52.392 v 67.735 c 0,1.883 0.468,3.369 1.413,4.471 0.939,1.085 2.161,1.636 3.671,1.636 h 18.854 c 11.965,0 21.053,-3.018 27.257,-9.04 6.215,-6.02 9.322,-15.499 9.322,-28.44699953 0,-27.70000047 -11.821,-41.54700047 -35.456,-41.54700047 h -19.302 c -3.836,0 -5.759,1.727 -5.759,5.192 M 55.862999,16.447401 c -3.611,0 -6.636,-1.659 -9.09,-4.967 -2.441,-3.3110004 -3.668,-7.9580004 -3.668,-13.9380004 0,-5.993 1.166,-10.5809996 3.503,-13.7779996 2.333,-3.207 5.398,-4.804 9.2,-4.804 3.8,0 6.887,1.617 9.258,4.862 2.371,3.233 3.559,7.8609996 3.559,13.8859996 0,6.02 -1.227,10.654 -3.673,13.8900004 -2.443,3.232 -5.473,4.849 -9.089,4.849 m -0.055,-59.493 c -10.573,0 -19.195,3.46 -25.859,10.379 -6.655,6.925 -9.984,17.03 -9.984,30.3139996 0,13.2920004 3.367,23.3560004 10.101,30.2090004 6.736,6.844 15.431,10.269 26.082,10.269 10.649,0 19.251,-3.363 25.794,-10.109 6.555,-6.733 9.827,-16.94 9.827,-30.5910004 0,-13.6609996 -3.348,-23.8219996 -10.05,-30.4899996 -6.702,-6.654 -15.333,-9.981 -25.911,-9.981" /></g><g + style="stroke-width:10.60874228;stroke-linejoin:round;paint-order:markers stroke fill"><g + id="path38"><path + style="color:#000000;fill:#ffffff;-inkscape-stroke:none" + d="m -13.681641,-50.839844 c -12.596904,0 -23.922227,4.43354 -32.080078,13.039063 a 7.79506,7.79506 0 0 0 -0.0059,0.0059 c -8.419793,8.89902 -12.173828,21.547223 -12.173828,36.5175783 0,13.1245257 3.885011,24.8172657 11.814453,33.6562497 8.072696,9.001174 19.779925,13.541016 33.009765,13.541016 5.7670161,0 11.130982,-0.548208 16.0937505,-1.736328 a 7.79506,7.79506 0 0 0 0.00195,0 C 7.9897789,42.982586 12.251503,41.478866 15.669922,37.738281 a 7.79506,7.79506 0 0 0 1.984375,-4.316406 c 0.178476,-1.466931 0.166015,-2.563734 0.166015,-4.326172 0,-3.425323 -0.889241,-6.278915 -2.169921,-9.755859 a 7.79506,7.79506 0 0 0 -0.0098,-0.02344 C 14.283054,15.666208 12.680545,12.507843 10.142578,9.8378906 9.2271105,8.8715838 8.3606463,8.0299624 7.2246094,7.2050781 7.2197468,7.2015474 7.2119011,7.1969043 7.2070312,7.1933594 8.0837303,7.0601219 8.9770024,6.9723347 9.8300781,6.7695312 10.775034,6.544885 11.736616,6.2312768 12.738281,5.8125 c 1.225424,11.0403 4.918921,20.536176 11.767578,27.505859 a 7.79506,7.79506 0 0 0 0.0059,0.0059 c 8.176259,8.307351 19.314813,12.595703 31.636718,12.595703 12.285007,0 23.361037,-4.205988 31.378907,-12.466797 l 0.0059,-0.0059 c 2.599207,-2.671035 4.689876,-5.754167 6.410156,-9.125 v 6.685546 c 0,3.174455 0.919882,6.779853 3.291016,9.544922 a 7.79506,7.79506 0 0 0 0.02148,0.02734 c 2.274218,2.627823 6.160321,4.330078 9.566411,4.330078 h 18.85351 c 13.27236,0 24.68019,-3.475272 32.67969,-11.236328 l 0.004,-0.0039 c 3.50739,-3.398515 6.103,-7.548801 7.98047,-12.251953 1.95158,4.481627 4.55037,8.492643 7.89844,11.90039 a 7.79506,7.79506 0 0 0 0.008,0.0078 c 8.17873,8.303689 19.3134,12.59375 31.63868,12.59375 12.28913,0 23.36042,-4.210522 31.38281,-12.46875 0.0204,-0.02093 0.0363,-0.04543 0.0566,-0.06641 0.32316,2.067188 0.71217,3.928778 1.80469,6.027343 1.14745,2.204109 4.38126,5.498047 8.55078,5.498047 h 49.11328 c 4.17404,0 7.40475,-3.301165 8.54883,-5.5 1.14408,-2.198835 1.52822,-4.121552 1.86523,-6.310547 a 7.79506,7.79506 0 0 0 0.0234,-0.154297 c 0.26703,-1.999711 0.40234,-4.041777 0.40234,-6.109375 0,-2.075615 -0.13536,-4.113677 -0.40234,-6.109375 a 7.79506,7.79506 0 0 0 -0.0215,-0.15039 c -0.33695,-2.194334 -0.72026,-4.119614 -1.86914,-6.322266 -1.14887,-2.202652 -4.39924,-5.4863279 -8.54687,-5.4863279 H 291.375 V -40.119141 c 0,-3.605114 -2.68219,-6.578534 -4.45703,-7.652343 -1.77484,-1.07381 -3.15956,-1.387588 -4.58399,-1.675782 -2.84884,-0.576386 -5.93572,-0.722656 -9.92773,-0.722656 -3.98876,0 -7.07885,0.146842 -9.92773,0.722656 -1.42445,0.287907 -2.80774,0.600519 -4.58204,1.671875 -1.77429,1.071357 -4.46484,4.041584 -4.46484,7.65625 V 8.7675781 h -4.97852 c 0.53826,-3.6028951 0.84375,-7.3707461 0.84375,-11.3417969 0,-14.9348322 -3.75874,-27.4709582 -12.3457,-36.0156252 a 7.79506,7.79506 0 0 0 -0.006,-0.0039 c -8.15443,-8.099651 -19.19427,-12.246094 -31.40234,-12.246094 -12.27679,0 -23.37947,4.365172 -31.4668,12.769532 a 7.79506,7.79506 0 0 0 -0.002,0 c -3.5928,3.734075 -6.17519,8.26351 -8.14258,13.232421 -1.67232,-4.343171 -3.73029,-8.375933 -6.61328,-11.753906 -7.57526,-8.875856 -19.1799,-13.121094 -32.51953,-13.121094 h -19.30274 c -3.08768,0 -6.65269,0.704423 -9.533199,3.298829 -2.880507,2.594405 -4.019532,6.513117 -4.019532,9.6875 v 7.521484 c -1.791465,-3.486279 -3.986908,-6.65901 -6.726562,-9.384766 a 7.79506,7.79506 0 0 0 -0.0059,-0.0059 c -8.154482,-8.09608 -19.190047,-12.244141 -31.402343,-12.244141 -12.273433,0 -23.379088,4.362353 -31.472657,12.765625 a 7.79506,7.79506 0 0 0 -0.0059,0.0078 c -2.078078,2.162387 -3.869846,4.553494 -5.394531,7.146484 l -0.09766,-7.599609 a 7.79506,7.79506 0 0 0 -3.332032,-6.291016 C 11.958498,-47.286873 8.591407,-48.032498 3.6503906,-49.130859 -1.60087,-50.304087 -7.3646155,-50.839844 -13.681641,-50.839844 Z m 0,15.587891 c 5.4229635,0 10.0808639,0.473214 13.93359413,1.333984 a 7.79506,7.79506 0 0 0 0.007813,0.002 c 2.01650327,0.44826 1.93180777,0.514397 3.05859377,0.914063 l 0.3183594,24.8515624 c -1.224922,0.1426094 -2.1780924,0.3300847 -3.76562505,0.3574219 -0.001256,1.91e-5 -0.00265,-1.9e-5 -0.003906,0 -0.0813889,0.00123 -0.16966434,-0.018157 -0.25195313,-0.017578 A 7.79506,7.79506 0 0 0 1.7539062,-13.150391 l -0.076172,-5.173828 v -0.002 c -0.001,-3.554641 -2.8946805,-7.723567 -5.7285156,-9.158203 -2.8343262,-1.434884 -5.2842732,-1.576172 -7.8808598,-1.576172 -6.078133,0 -11.944075,2.950048 -16.046875,7.472656 -4.653417,5.125077 -6.480468,12.0915876 -6.480468,19.6250004 0,7.5149768 1.733481,14.4327846 6.519531,19.4082026 6.4e-4,6.66e-4 0.0013,0.0013 0.002,0.002 6.44e-4,6.68e-4 0.0013,0.0013 0.002,0.002 4.347809,4.519769 10.618265,6.90625 16.960938,6.90625 2.7971771,0 5.6124765,-0.457269 8.3769527,-1.302735 0.8560969,-0.258987 1.586871,-0.510088 2.33789067,-0.767578 0.42775588,0.707203 0.75217426,1.027967 1.28320313,2.451172 0.7495552,2.038994 0.8358563,2.835556 0.9375,3.382813 -0.7507405,0.304508 -1.41639152,0.61698 -2.61523437,0.904296 -3.53284813,0.845612 -7.69270203,1.306641 -12.46289113,1.306641 -9.958136,0 -16.384959,-2.760563 -21.406249,-8.359375 -5.173829,-5.76686 -7.830079,-13.0351827 -7.830079,-23.2480467 0,-12.4270673 2.939406,-20.5476823 7.904297,-25.7988283 l 0.0039,-0.0039 c 6.06e-4,-6.41e-4 0.0013,-0.0013 0.002,-0.002 5.252936,-5.538205 11.532106,-8.169922 20.761718,-8.169922 z m 69.490235,0 c 8.943682,0 15.168464,2.506843 20.417968,7.71875 4.812153,4.791517 7.748047,12.576276 7.748047,24.9589842 0,12.4055171 -2.904345,20.3134788 -7.617187,25.1542968 a 7.79506,7.79506 0 0 0 -0.0098,0.0098 c -5.067351,5.224568 -11.191206,7.742187 -20.199219,7.742187 -8.977809,0 -15.228563,-2.561596 -20.523437,-7.939453 l -0.002,-0.002 c -6.68e-4,-6.78e-4 -0.0013,-0.0013 -0.002,-0.002 -4.968267,-5.058458 -7.861328,-12.7694566 -7.861328,-24.7421876 0,-11.9773224 2.87616,-19.7762004 7.802734,-24.9062504 l 0.0039,-0.0039 c 6.16e-4,-6.41e-4 0.0013,-0.0013 0.002,-0.002 5.233116,-5.430463 11.37106,-7.986328 20.240235,-7.986328 z m 149.734376,0 c 8.93499,0 15.16961,2.50802 20.41211,7.712891 4.81503,4.79132 7.7539,12.577704 7.7539,24.9648432 0,12.4055171 -2.90594,20.3153858 -7.61523,25.1562498 a 7.79506,7.79506 0 0 0 -0.004,0.0039 c -5.0792,5.230396 -11.19475,7.746094 -20.20507,7.746094 -8.98471,0 -15.22994,-2.561015 -20.53321,-7.945312 -4.96574,-5.058518 -7.85937,-12.7698598 -7.85937,-24.7402346 0,-11.9814204 2.88042,-19.7781244 7.8164,-24.9082034 5.22866,-5.433626 11.35719,-7.990234 20.23438,-7.990234 z m 66.86328,0.671875 c 1.71218,0 2.21956,0.12373 3.38086,0.203125 v 50.9375 a 7.79506,7.79506 0 0 0 7.79492,7.794922 h 8.30078 c 0.0669,0.820409 0.16211,1.626225 0.16211,2.480468 0,0.847857 -0.0969,1.660257 -0.16406,2.484375 h -39.28711 c -0.0667,-0.819921 -0.16211,-1.620834 -0.16211,-2.484375 0,-0.870352 0.0956,-1.663833 0.16211,-2.480468 h 8.63086 a 7.79506,7.79506 0 0 0 7.79492,-7.794922 v -50.9375 c 1.16227,-0.07957 1.67392,-0.203125 3.38672,-0.203125 z m -162.875,0.455078 h 17.26758 c 10.29535,0 16.41813,2.679714 20.66211,7.652344 4.24398,4.97263 7,13.360313 7,26.10156225 0,11.70111175 -2.74067,18.76925975 -6.95117,22.84765575 a 7.79506,7.79506 0 0 0 -0.006,0.0059 c -4.4082,4.278877 -11.1738,6.837891 -21.82813,6.83789 h -16.14453 z m 16.25195,4.617188 c -1.04293,0 -2.14036,0.03826 -3.63867,0.498046 -1.49578,0.459009 -3.82446,1.589227 -5.24219,4.205079 -3.5e-4,6.58e-4 3.6e-4,0.0013 0,0.002 -2.16464,3.994843 -1.28515,4.740325 -1.28515,6.699218 v 33.769532 a 7.79506,7.79506 0 0 0 7.79492,7.792968 h 1.12891 c 6.00574,0 11.80043,-1.370564 16.02343,-5.517578 a 7.79506,7.79506 0 0 0 0.006,-0.0059 c 5.26572,-5.182403 5.65039,-11.6132457 5.65039,-19.6093751 0,-7.9533895 -0.83122,-14.4341049 -4.60937,-19.8554689 l -0.002,-0.002 c -3.48276,-5.006481 -9.74205,-7.976563 -15.82617,-7.976562 z m -69.974606,0.673828 c -5.98094,0 -11.975929,3.17317 -15.496094,8.005859 -3.700679,5.066737 -5.001953,11.370405 -5.001953,18.3710937 0,7.0461672 1.421733,13.4519213 5.189453,18.5625003 a 7.79506,7.79506 0 0 0 0.01367,0.01953 c 3.537144,4.768082 9.351334,8.117188 15.349609,8.117187 5.939621,0 11.748344,-3.235861 15.306641,-7.943359 3.848276,-5.091179 5.25,-11.5107608 5.25,-18.5898436 0,-7.0442837 -1.332446,-13.3940924 -5.060547,-18.4843754 l -0.002,-0.002 c -3.544799,-4.849958 -9.538638,-8.05664 -15.548828,-8.05664 z m 149.734376,0 c -5.98461,0 -11.98672,3.173848 -15.50586,8.017578 -3.6845,5.061033 -4.98828,11.3570994 -4.98828,18.3593747 0,7.0418225 1.41272,13.4462443 5.18164,18.5605473 a 7.79506,7.79506 0 0 0 0.0117,0.01563 c 3.5393,4.778774 9.3588,8.123046 15.35742,8.123046 5.93962,0 11.74626,-3.239478 15.30469,-7.939453 a 7.79506,7.79506 0 0 0 0.004,-0.0039 c 3.84951,-5.092809 5.2461,-11.5124871 5.2461,-18.5898436 0,-7.0416455 -1.33184,-13.3907654 -5.0586,-18.4804684 l -0.004,-0.0039 c -3.54423,-4.853783 -9.53914,-8.058593 -15.54883,-8.058593 z m -149.734376,15.58789 c 1.588884,0 1.76744,0.02722 2.964843,1.666016 a 7.79506,7.79506 0 0 0 0.0078,0.01172 c 1.007497,1.373782 2.048828,4.2769243 2.048828,9.2773434 0,4.9609051 -1.051984,7.8086375 -2.095703,9.1894531 -1.327698,1.7564959 -1.578722,1.7539063 -2.871094,1.7539063 -1.219834,0 -1.460971,0.023539 -2.820312,-1.8066407 -1.112458,-1.513176 -2.144532,-4.3959018 -2.144532,-9.3027344 0,-4.9820232 1.032618,-7.8536437 2.001954,-9.1796877 a 7.79506,7.79506 0 0 0 0.0098,-0.01367 c 1.146711,-1.576297 1.279057,-1.595703 2.898438,-1.595703 z m 149.734376,0 c 1.59046,0 1.76875,0.02839 2.96094,1.66211 a 7.79506,7.79506 0 0 0 0.0117,0.01758 c 1.00765,1.373399 2.05079,4.2749713 2.05079,9.2753904 0,4.9626314 -1.05322,7.8102679 -2.09571,9.1894531 -1.33099,1.7571181 -1.5804,1.7539063 -2.87109,1.7539063 -1.22304,0 -1.47037,0.021921 -2.82422,-1.8046876 -1.10926,-1.5094721 -2.13672,-4.3935246 -2.13672,-9.3046875 0,-4.979422 1.03164,-7.8561267 2.00195,-9.1874997 a 7.79506,7.79506 0 0 0 0.008,-0.0098 c 1.14085,-1.570264 1.27515,-1.591797 2.89453,-1.591797 z M 0,0 0.09179687,5.4179687 c -0.0027192,3.84e-4 -0.0050943,0.00157 -0.0078125,0.00195 z m -17.826172,4.515625 a 7.79506,7.79506 0 0 0 3.394531,1.9785156 c 0,0 4.16777,0.597219 9.0292973,0.9628906 -0.364549,0.1693785 -0.9404306,0.4431528 -1.734375,0.6835938 a 7.79506,7.79506 0 0 0 -0.021484,0.00586 c -1.4535196,0.444533 -2.6955876,0.6210937 -3.8164059,0.6210937 -2.981452,0 -4.290525,-0.631362 -5.726563,-2.125 a 7.79506,7.79506 0 0 0 -0.0039,-0.00391 c -0.38649,-0.4015606 -0.76386,-1.2417621 -1.121094,-2.1230469 z m 12.5351564,2.9492187 c 0.065836,0.00486 0.1291125,0.007 0.1953125,0.011719 -0.1310168,0.097798 -0.3245375,0.1663064 -0.4472656,0.265625 L -5.4355469,7.65625 C -5.0520181,7.3570016 -5.190514,7.4289003 -5.2910156,7.4648437 Z" + id="path205" /><path + style="color:#000000;fill:#414042;stroke-width:15.5886;-inkscape-stroke:none" + d="m 0,0 c -6.078,0.094 -13.034,-1.173 -13.034,-1.173 v -11.863 h 6.995 l -0.078,-5.288 c 0,-1.959 -1.942,-2.943 -5.815,-2.943 -3.878,0 -7.303,1.642 -10.274,4.917 -2.978,3.279 -4.459,8.072 -4.459,14.388 0,6.329 1.447,10.995 4.345,14.006 2.892,3.008 6.683,4.517 11.346,4.517 1.959,0 3.987,-0.316 6.096,-0.961 2.11,-0.639 3.519,-1.238 4.238,-1.799 0.713,-0.577 1.391,-0.85 2.032,-0.85 0.638,0 1.671,0.746 3.1,2.255 1.431,1.505 2.713,3.786 3.844,6.827 1.126,3.057 1.69,5.4 1.69,7.062 0,1.649 -0.036,2.786 -0.109,3.386 -1.581,1.73 -4.499,3.102 -8.755,4.122 -4.248,1.017 -9.011,1.522 -14.28,1.522 -11.594,0 -20.66,-3.65 -27.207,-10.95 -6.552,-7.303 -9.822,-16.783 -9.822,-28.452 0,-13.701 3.347,-24.087 10.041,-31.162 6.706,-7.074 15.51,-10.607 26.425,-10.607 5.87,0 11.08,0.505 15.632,1.522 4.557,1.013 7.586,2.053 9.093,3.105 l 0.452,35.33 C 11.496,-1.036 6.078,-0.104 0,0 m 283.58148,-40.1198 c 0,-1.496 -3.721,-2.255 -11.176,-2.255 -7.448,0 -11.18,0.759 -11.18,2.255 v 56.681 h -13.545 c -1.281,0 -2.185,1.727 -2.71,5.198 -0.226,1.652 -0.334,3.343 -0.334,5.077 0,1.724 0.108,3.422 0.334,5.077 0.525,3.462 1.429,5.202 2.71,5.202 h 49.112 c 1.279,0 2.179,-1.74 2.712,-5.202 0.221,-1.655 0.335,-3.353 0.335,-5.077 0,-1.734 -0.114,-3.425 -0.335,-5.077 -0.533,-3.471 -1.433,-5.198 -2.712,-5.198 h -13.211 z M 205.6005,16.447401 c -3.612,0 -6.645,-1.659 -9.095,-4.967 -2.44,-3.3110004 -3.662,-7.9580004 -3.662,-13.9380004 0,-5.993 1.169,-10.5809996 3.499,-13.7779996 2.33,-3.207 5.398,-4.804 9.2,-4.804 3.801,0 6.89,1.617 9.258,4.862 2.372,3.233 3.56,7.8609996 3.56,13.8859996 0,6.02 -1.225,10.654 -3.671,13.8900004 -2.447,3.232 -5.473,4.849 -9.089,4.849 m -0.058,-59.493 c -10.577,0 -19.193,3.46 -25.851,10.379 -6.663,6.925 -9.993,17.03 -9.993,30.3139996 0,13.2920004 3.367,23.3560004 10.1,30.2090004 6.741,6.844 15.431,10.269 26.086,10.269 10.651,0 19.246,-3.363 25.797,-10.109 6.55,-6.733 9.822,-16.94 9.822,-30.5910004 0,-13.6609996 -3.349,-23.8219996 -10.05,-30.4899996 -6.699,-6.654 -15.338,-9.981 -25.911,-9.981 m -82.13011,58.710808 v -33.768 c 0,-1.577 0.116,-2.571 0.342,-2.988 0.224,-0.415 0.903,-0.623 2.029,-0.623 4.144,0 7.283,1.548 9.429,4.634 2.151,3.083 3.215,8.2160005 3.215,15.4050005 0,7.192 -1.113,11.8779995 -3.325,14.0549995 -2.223,2.183 -5.744,3.285 -10.561,3.285 z m -21.675,-52.392 v 67.735 c 0,1.883 0.468,3.369 1.413,4.471 0.939,1.085 2.161,1.636 3.671,1.636 h 18.854 c 11.965,0 21.053,-3.018 27.257,-9.04 6.215,-6.02 9.322,-15.499 9.322,-28.44699953 0,-27.70000047 -11.821,-41.54700047 -35.456,-41.54700047 h -19.302 c -3.836,0 -5.759,1.727 -5.759,5.192 M 55.862999,16.447401 c -3.611,0 -6.636,-1.659 -9.09,-4.967 -2.441,-3.3110004 -3.668,-7.9580004 -3.668,-13.9380004 0,-5.993 1.166,-10.5809996 3.503,-13.7779996 2.333,-3.207 5.398,-4.804 9.2,-4.804 3.8,0 6.887,1.617 9.258,4.862 2.371,3.233 3.559,7.8609996 3.559,13.8859996 0,6.02 -1.227,10.654 -3.673,13.8900004 -2.443,3.232 -5.473,4.849 -9.089,4.849 m -0.055,-59.493 c -10.573,0 -19.195,3.46 -25.859,10.379 -6.655,6.925 -9.984,17.03 -9.984,30.3139996 0,13.2920004 3.367,23.3560004 10.101,30.2090004 6.736,6.844 15.431,10.269 26.082,10.269 10.649,0 19.251,-3.363 25.794,-10.109 6.555,-6.733 9.827,-16.94 9.827,-30.5910004 0,-13.6609996 -3.348,-23.8219996 -10.05,-30.4899996 -6.702,-6.654 -15.333,-9.981 -25.911,-9.981" + id="path207" /></g></g><g id="g40" transform="matrix(1.1310535,0,0,1.1310535,441.34721,235.75121)" style="stroke:none;stroke-width:4.31066306;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill" /><g @@ -122,10 +128,15 @@ style="stroke:none;stroke-width:4.31066306;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill" /><g id="g74" transform="matrix(1.1310535,0,0,1.1310535,669.70883,256.83868)" - style="stroke:none;stroke-width:4.31066306;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"><path - id="path76" - style="fill:#6d6e71;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:15.5885606;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill" - d="M 0,0 C -1.763,0 -3.208,-0.802 -4.334,-2.402 -5.463,-4.008 -6.052,-5.987 -6.102,-8.346 H 5.56 v 1.082 c 0,2.086 -0.486,3.823 -1.47,5.201 C 3.109,-0.684 1.747,0 0,0 m 0.401,-23.76 c -2.733,0 -4.958,1.026 -6.681,3.073 -1.73,2.043 -2.595,4.657 -2.595,7.841 v 4.197 c 0,3.19 0.865,5.85 2.6,7.965 1.739,2.105 3.831,3.158 6.275,3.158 2.646,0 4.706,-0.939 6.172,-2.823 1.462,-1.887 2.195,-4.422 2.195,-7.603 v -2.773 H -6.102 v -2.102 c 0,-2.447 0.59,-4.484 1.757,-6.11 1.166,-1.63 2.748,-2.438 4.746,-2.438 1.382,0 2.579,0.244 3.578,0.724 1.012,0.491 1.869,1.179 2.591,2.082 l 1.147,-1.988 c -0.769,-0.968 -1.755,-1.75 -2.962,-2.33 -1.203,-0.577 -2.658,-0.873 -4.354,-0.873 m -28.299804,25.7639105 0.23,-4.178 c 0.676,1.48300001 1.562,2.63400001 2.678,3.435 1.115,0.805 2.422,1.213 3.916,1.213 2.258,0 3.995,-0.835 5.199,-2.51299999 1.211,-1.67500001 1.807,-4.27900001 1.807,-7.81200001 V -23.271089 h -2.825 v 15.3939995 c 0,2.888 -0.422,4.905 -1.261,6.075 -0.843,1.17000001 -2.063,1.75300001 -3.668,1.75300001 -1.434,0 -2.635,-0.466 -3.599,-1.41400001 -0.967,-0.939 -1.692,-2.19 -2.171,-3.767 V -23.271089 h -2.809 V 2.0039105 Z m -9.133591,-25.2752055 h -2.830008 V 2.0037072 h 2.830008 z m 0,32.4710013 h -2.830008 v 3.9819957 h 2.830008 z M -60.863903,-12.846289 c 0,-2.565 0.486,-4.605 1.472,-6.123 0.974,-1.532 2.457,-2.288 4.436,-2.288 1.356,0 2.498,0.361 3.435,1.101 0.934,0.74 1.672,1.77 2.218,3.077 v 12.5200001 c -0.525,1.346 -1.246,2.434 -2.157,3.272 -0.91,0.82400002 -2.062,1.23800002 -3.448,1.23800002 -1.975,0 -3.468,-0.86 -4.46,-2.58700002 -0.999,-1.73 -1.496,-3.986 -1.496,-6.756 z m -2.833,3.4540001 c 0,3.582 0.723,6.459 2.177,8.62700002 1.442,2.15699998 3.448,3.23899998 6.004,3.23899998 1.419,0 2.664,-0.346 3.728,-1.04 1.066,-0.68099998 1.947,-1.67799998 2.654,-2.946 l 0.274,3.516 h 2.381 V -23.294289 c 0,-3.239 -0.751,-5.749 -2.26,-7.525 -1.511,-1.769 -3.657,-2.665 -6.428,-2.665 -0.996,0 -2.067,0.156 -3.212,0.459 -1.147,0.303 -2.162,0.701 -3.052,1.2 l 0.776,2.463 c 0.759,-0.492 1.608,-0.873 2.548,-1.141 0.932,-0.277 1.895,-0.41 2.894,-0.41 2.009,0 3.498,0.645 4.46,1.932 0.966,1.304 1.45,3.19 1.45,5.687 v 3.057 c -0.717,-1.138 -1.597,-2.011 -2.64,-2.614 -1.039,-0.606 -2.253,-0.909 -3.622,-0.909 -2.539,0 -4.53,0.994 -5.968,2.982 -1.441,1.984 -2.164,4.631 -2.164,7.932 z m -19.227592,11.3961994 0.23,-4.178 c 0.674,1.48300001 1.564,2.63400001 2.682,3.435 1.108,0.805 2.413,1.213 3.914,1.213 2.258,0 3.988,-0.835 5.189,-2.51299999 1.214,-1.67500001 1.815,-4.27900001 1.815,-7.81200001 V -23.271089 h -2.825 v 15.3939995 c 0,2.888 -0.423,4.905 -1.264,6.075 -0.836,1.17000001 -2.065,1.75300001 -3.665,1.75300001 -1.435,0 -2.638,-0.466 -3.603,-1.41400001 -0.969,-0.939 -1.691,-2.19 -2.172,-3.767 V -23.271089 h -2.805 V 2.0039105 Z M -98.69412,0 c -1.763,0 -3.21,-0.802 -4.341,-2.402 -1.126,-1.606 -1.712,-3.585 -1.763,-5.944 h 11.663 v 1.082 c 0,2.086 -0.488,3.823 -1.474,5.201 -0.981,1.379 -2.341,2.063 -4.085,2.063 m 0.394,-23.76 c -2.726,0 -4.951,1.026 -6.679,3.073 -1.733,2.043 -2.6,4.657 -2.6,7.841 v 4.197 c 0,3.19 0.871,5.85 2.602,7.965 1.744,2.105 3.834,3.158 6.283,3.158 2.643,0 4.703,-0.939 6.164,-2.823 1.463,-1.887 2.197,-4.422 2.197,-7.603 v -2.773 h -14.465 v -2.102 c 0,-2.447 0.587,-4.484 1.76,-6.11 1.162,-1.63 2.742,-2.438 4.738,-2.438 1.387,0 2.585,0.244 3.585,0.724 1.007,0.491 1.866,1.179 2.589,2.082 l 1.141,-1.988 c -0.764,-0.968 -1.75,-1.75 -2.959,-2.33 -1.204,-0.577 -2.658,-0.873 -4.356,-0.873 M -129.86659,0 c -1.758,0 -3.202,-0.802 -4.334,-2.402 -1.133,-1.606 -1.718,-3.585 -1.765,-5.944 h 11.66 v 1.082 c 0,2.086 -0.489,3.823 -1.469,5.201 -0.986,1.379 -2.347,2.063 -4.092,2.063 m 0.397,-23.76 c -2.725,0 -4.954,1.026 -6.685,3.073 -1.726,2.043 -2.591,4.657 -2.591,7.841 v 4.197 c 0,3.19 0.867,5.85 2.602,7.965 1.739,2.105 3.828,3.158 6.277,3.158 2.648,0 4.699,-0.939 6.164,-2.823 1.468,-1.887 2.201,-4.422 2.201,-7.603 v -2.773 h -14.464 v -2.102 c 0,-2.447 0.586,-4.484 1.752,-6.11 1.168,-1.63 2.755,-2.438 4.744,-2.438 1.382,0 2.585,0.244 3.588,0.724 1.003,0.491 1.863,1.179 2.578,2.082 l 1.149,-1.988 c -0.763,-0.968 -1.752,-1.75 -2.959,-2.33 -1.204,-0.577 -2.659,-0.873 -4.356,-0.873 m -41.1488,25.7639105 0.24,-3.923 c 0.664,1.40400001 1.554,2.48600001 2.657,3.255 1.107,0.759 2.41,1.138 3.906,1.138 1.527,0 2.814,-0.444 3.852,-1.343 1.039,-0.89599999 1.805,-2.252 2.292,-4.074 0.623,1.682 1.505,3.01100001 2.65,3.973 1.145,0.964 2.534,1.444 4.143,1.444 2.217,0 3.937,-0.897 5.156,-2.69199999 1.224,-1.79900001 1.834,-4.55900001 1.834,-8.28800001 V -23.271089 h -2.823 v 14.8139995 c 0,3.1 -0.429,5.283 -1.263,6.538 -0.839,1.25700001 -2.042,1.89000001 -3.598,1.89000001 -1.637,0 -2.915,-0.691 -3.834,-2.09600001 -0.914,-1.405 -1.478,-3.161 -1.683,-5.282 v -0.655 -15.2089995 h -2.809 v 14.7979995 c 0,3.027 -0.424,5.194 -1.292,6.488 -0.864,1.29400001 -2.066,1.93600001 -3.609,1.93600001 -1.475,0 -2.668,-0.45 -3.562,-1.34200001 -0.9,-0.897 -1.54,-2.125 -1.928,-3.683 V -23.271089 h -2.806 V 2.0039105 Z M -188.9332,-21.231295 c 1.553,0 2.936,0.44 4.144,1.336 1.21,0.9 2.058,2.037 2.561,3.422 v 5.468 h -4.492 c -1.91,0 -3.44,-0.541 -4.585,-1.623 -1.148,-1.075 -1.716,-2.418 -1.716,-4.015 0,-1.349 0.355,-2.457 1.074,-3.311 0.718,-0.857 1.722,-1.277 3.014,-1.277 m 7.124,-2.04 c -0.14,0.876 -0.249,1.587 -0.318,2.144 -0.067,0.567 -0.101,1.131 -0.101,1.704 -0.767,-1.254 -1.757,-2.294 -2.98,-3.109 -1.221,-0.821 -2.579,-1.228 -4.075,-1.228 -2.092,0 -3.701,0.648 -4.84,1.946 -1.132,1.303 -1.704,3.059 -1.704,5.276 0,2.343 0.823,4.223 2.473,5.618 1.649,1.3950005 3.89,2.0920005 6.709,2.0920005 h 4.417 v 3.106 c 0,1.786 -0.456,3.193 -1.351,4.21 -0.914,1.00399996 -2.17,1.51199995911 -3.791,1.51199995911 -1.508,0 -2.752,-0.47899999911 -3.728,-1.44999995911 -0.973,-0.965 -1.456,-2.144 -1.456,-3.549 l -2.623,0.023 -0.046,0.137 c -0.074,1.906 0.647,3.591 2.168,5.08399996 1.515,1.48900004 3.459,2.22900004 5.825,2.22900004 2.338,0 4.22,-0.711 5.657,-2.12800004 1.429,-1.43099996 2.146,-3.47099996 2.146,-6.12399996 V -18.174295 c 0,-0.903 0.042,-1.78 0.121,-2.617 0.081,-0.848 0.212,-1.665 0.417,-2.48 z m -20.0925,4.627199 c -0.624,-1.28 -1.771,-2.454 -3.449,-3.516 -1.676,-1.069 -3.805,-1.6 -6.391,-1.6 -3.412,0 -6.156,1.075 -8.24,3.249 -2.076,2.157 -3.116,5.266 -3.116,9.323 v 10.116 c 0,3.969 0.98,7.013 2.946,9.138 1.962,2.108 4.59,3.177 7.872,3.177 3.208,0 5.695,-0.844 7.455,-2.513 1.755,-1.675 2.677,-4.015 2.757,-7.003 l -0.044,-0.133 h -2.619 c -0.094,2.29 -0.759,4.057 -2.01,5.305 -1.244,1.238 -3.095,1.864 -5.539,1.864 -2.473,0 -4.432,-0.837 -5.866,-2.516 -1.43,-1.675 -2.143,-4.103 -2.143,-7.293 v -10.174 c 0,-3.308 0.771,-5.83 2.311,-7.567 1.54,-1.724 3.616,-2.588 6.236,-2.588 1.913,0 3.451,0.339 4.602,1.033 1.155,0.684 1.956,1.519 2.409,2.51 v 8.861 h -7.06 v 2.463 h 9.889 z" /></g><g + style="stroke-width:4.31066306;stroke-linejoin:round;paint-order:markers stroke fill"><g + id="path76"><path + style="color:#000000;fill:#ffffff;-inkscape-stroke:none" + d="m -55.166016,-41.279297 c -1.808526,0 -3.536849,0.278071 -5.203125,0.71875 -1.678722,0.443464 -3.320167,1.066841 -4.873046,1.9375 -2.596787,1.63317 -3.994246,4.637553 -3.570313,7.675781 -0.09298,-0.04089 -0.186745,-0.07996 -0.28125,-0.117187 h -2.826172 c -2.002104,0.02358 -3.918364,0.816659 -5.351562,2.214844 -1.433198,-1.398185 -3.349459,-2.191265 -5.351563,-2.214844 h -2.804687 c -1.542011,0.14908 -3.004629,0.754254 -4.201172,1.738281 -0.32252,-0.182255 -0.611512,-0.428692 -0.94336,-0.58789 l -0.0039,-0.002 c -2.472567,-1.184943 -5.120798,-1.638671 -7.724609,-1.638671 -4.678985,-1e-6 -9.601215,2.251543 -12.628905,5.833984 -2.6704,3.151849 -4.02447,7.203314 -4.31836,11.27539 -0.15077,-0.501332 -0.35165,-0.986202 -0.59961,-1.447265 l 0.44141,-0.763672 c 1.59705,-2.762944 1.34866,-6.220292 -0.62695,-8.726562 -1.5267,-1.936879 -3.53107,-3.484621 -5.70508,-4.529297 l -0.008,-0.0039 c -2.47409,-1.18567 -5.11932,-1.638672 -7.72266,-1.638671 -3.09586,-1e-6 -6.25097,1.054638 -8.94141,2.757812 -1.45619,-1.447996 -3.42495,-2.262872 -5.47851,-2.267578 h -2.82227 c -1.93669,0.04642 -3.7867,0.812326 -5.18945,2.148437 -1.40276,-1.336111 -3.25277,-2.102017 -5.18945,-2.148437 h -2.8086 c -1.93899,0.0455 -3.79137,0.812222 -5.19531,2.150391 -1.40394,-1.338169 -3.25633,-2.104889 -5.19531,-2.150391 h -2.80664 c -0.81079,0.191731 -1.58559,0.512204 -2.29492,0.949219 -1.07507,-0.587545 -2.27349,-0.913413 -3.49805,-0.951172 h -2.91992 c -0.67325,0.151008 -1.32346,0.390732 -1.9336,0.71289 -1.795,-0.706205 -3.66929,-1.201171 -5.54101,-1.201171 -3.50013,0 -7.49664,1.420164 -10.20117,4.162109 -0.567,-0.443355 -1.08741,-0.964665 -1.68555,-1.34375 -3.21038,-2.04466 -6.92275,-2.818359 -10.57227,-2.818359 -5.04822,-1e-6 -10.30237,1.935015 -13.86328,5.648437 -6.4e-4,6.65e-4 -0.001,0.0013 -0.002,0.002 -3.76116,3.915201 -5.28516,9.332898 -5.28516,14.716797 v 10.1152344 c 0,5.2520039 1.41057,10.530801 5.01953,14.4316406 0.005,0.0059 0.0104,0.01173 0.0156,0.01758 3.43151,3.686867 8.60365,5.660156 13.57812,5.660156 4.57508,0 9.35017,-1.363472 12.81836,-4.652343 0.006,-0.0052 0.0117,-0.01041 0.0176,-0.01563 1.84606,-1.761905 3.13464,-3.974261 3.98438,-6.3359379 2.53321,1.4403465 5.4497,2.2343749 8.22851,2.2343749 3.02219,0 6.24428,-0.9011821 8.91211,-2.6308593 1.40906,1.3487442 3.27257,2.1202136 5.22266,2.1621094 h 2.47656 c 0.53252,-0.1480547 1.04779,-0.3523286 1.53711,-0.609375 1.73031,0.643973 3.51943,1.0781249 5.26758,1.0781249 2.13316,0 4.35253,-0.730485 6.41015,-1.7968749 2.08238,1.0593742 4.32324,1.7968749 6.52539,1.7968749 3.64342,0 7.56291,-1.8298717 10.20118,-4.5546874 2.88192,2.6877619 6.82494,4.5546874 10.81054,4.5546874 4.48972,0 9.45756,-2.1552464 12.31641,-5.830078 1.60293,-2.0604476 2.51241,-4.43830193884 3.09961,-6.9042969 0.71465,2.43454664 1.82624,4.7452784 3.4414,6.71875 0.0104,0.012402 0.0208,0.024772 0.0312,0.037109 2.88105,3.477408 7.60195,5.9785159 12.285157,5.9785159 2.833994,0 5.804706,-0.9358347 8.371093,-2.496094 1.344793,1.2264745 3.07637,1.9437037 4.894532,2.0273437 h 2.503906 c 0.545292,-0.1512945 1.072488,-0.361518 1.572266,-0.6269531 1.716131,0.6544598 3.499698,1.0957034 5.253906,1.0957034 3.56251,0 7.487652,-1.6692823 10.173828,-4.3496097 2.794016,2.6236811 6.685243,4.3496097 10.408203,4.3496097 1.716056,0 3.475139,-0.4203695 5.179688,-1.0468753 0.471256,0.242399 0.966003,0.4361093 1.476562,0.578125 h 1.203125 v 3.3828133 c 7.7e-5,4.304222 3.488747,7.793766 7.792969,7.794921 h 2.830078 c 4.304985,-7.7e-5 7.794845,-3.489937 7.794922,-7.794921 V 9.7988281 h 1.339844 c 0.545292,-0.1512946 1.072488,-0.361518 1.572265,-0.6269531 1.713658,0.6532826 3.495541,1.095703 5.251953,1.095703 3.629954,0 7.633696,-1.7251239 10.324219,-4.4980468 2.8782652,2.658651 6.792122,4.4980468 10.75,4.4980468 4.4899939,0 9.4557947,-2.1437813 12.324219,-5.830078 0.0033,-0.00455 0.0065,-0.00911 0.0098,-0.013672 2.759395,-3.56154471 3.828125,-7.9966434 3.828125,-12.375 v -2.773437 c -0.05002,-1.926545 -0.811929,-3.766268 -2.138671,-5.164063 l 0.445312,-0.773437 c 1.5981,-2.771071 1.341005,-6.237217 -0.648437,-8.742188 -1.515701,-1.90793 -3.510901,-3.460952 -5.6894536,-4.507812 l -0.00586,-0.002 c -2.4753832,-1.187279 -5.1217303,-1.640625 -7.72460937,-1.640625 -3.10147653,-1e-6 -6.26458173,1.060157 -8.95898443,2.771484 -1.4616306,-1.460639 -3.4434086,-2.28117 -5.5097656,-2.28125 h -2.826172 c -2.001426,0.02408 -3.916898,0.817122 -5.34961,2.214844 -1.432711,-1.397722 -3.348182,-2.190765 -5.349609,-2.214844 h -2.808594 c -1.196545,0.193759 -2.331416,0.663891 -3.314453,1.373047 -0.983426,-0.710129 -2.11901,-1.180949 -3.316406,-1.375 h -2.830078 c -0.06152,0.02461 -0.122722,0.05 -0.183594,0.07617 -0.648488,-1.735391 -1.5001,-3.401647 -2.751953,-4.875 -0.0045,-0.0052 -0.0091,-0.01043 -0.01367,-0.01563 -3.033908,-3.551942 -7.902338,-5.398438 -12.353516,-5.398438 z m -5.078125,3.28125 c -0.01306,0.0037 -0.02405,0.01382 -0.03711,0.01758 -0.01541,0.0045 -0.03148,0.0013 -0.04687,0.0059 z m -120.642579,8.980469 0.0273,0.01758 c -0.004,-0.0027 -0.01,-0.0031 -0.0137,-0.0059 -0.005,-0.0033 -0.009,-0.0084 -0.0137,-0.01172 z m -22.28125,1.96875 0.0527,0.03125 c -0.009,-0.0053 -0.0185,-0.0045 -0.0274,-0.0098 -0.009,-0.0054 -0.0163,-0.01609 -0.0254,-0.02148 z m 93.80859,3.550781 c -0.006,0.0086 -0.009,0.01874 -0.0156,0.02734 -0.003,0.0037 -0.007,0.0061 -0.01,0.0098 z m 44.787114,27.9960939 -0.02539,0.037109 c 0.0061,-0.00841 0.0096,-0.016978 0.01563,-0.025391 0.0029,-0.00408 0.0068,-0.00763 0.0098,-0.011719 z m 55.0292972,0.00586 -0.015625,0.023437 c 0.00411,-0.00568 0.00567,-0.011895 0.00977,-0.017578 0.0016,-0.00222 0.00426,-0.00364 0.00586,-0.00586 z m -75.0507812,3.0625 c 0.0054,0.00393 0.01216,0.00584 0.01758,0.00977 0.0088,0.00635 0.01459,0.015149 0.02344,0.021484 z m 55.041016,0.013672 c 0.0024,0.0017 0.0055,0.00221 0.0078,0.00391 0.0038,0.00276 0.0059,0.00701 0.0098,0.00977 z m -17.976563,0.3828125 -0.0625,0.039063 c 0.01045,-0.00668 0.01692,-0.016737 0.02734,-0.023437 0.01087,-0.00704 0.02431,-0.00855 0.03516,-0.015625 z" + id="path211" + sodipodi:nodetypes="ccccccccccccscccssssscccccccccccccsccsscssccscccsccccscscsscccsccccscscccscsscccscsccsccccccscsccccccccsccccscccccccccsccccccccsscccssccscccsccccssc" /><path + style="color:#000000;fill:#6d6e71;stroke-width:15.5886;-inkscape-stroke:none" + d="M 0,0 C -1.763,0 -3.208,-0.802 -4.334,-2.402 -5.463,-4.008 -6.052,-5.987 -6.102,-8.346 H 5.56 v 1.082 c 0,2.086 -0.486,3.823 -1.47,5.201 C 3.109,-0.684 1.747,0 0,0 m 0.401,-23.76 c -2.733,0 -4.958,1.026 -6.681,3.073 -1.73,2.043 -2.595,4.657 -2.595,7.841 v 4.197 c 0,3.19 0.865,5.85 2.6,7.965 1.739,2.105 3.831,3.158 6.275,3.158 2.646,0 4.706,-0.939 6.172,-2.823 1.462,-1.887 2.195,-4.422 2.195,-7.603 v -2.773 H -6.102 v -2.102 c 0,-2.447 0.59,-4.484 1.757,-6.11 1.166,-1.63 2.748,-2.438 4.746,-2.438 1.382,0 2.579,0.244 3.578,0.724 1.012,0.491 1.869,1.179 2.591,2.082 l 1.147,-1.988 c -0.769,-0.968 -1.755,-1.75 -2.962,-2.33 -1.203,-0.577 -2.658,-0.873 -4.354,-0.873 m -28.299804,25.7639105 0.23,-4.178 c 0.676,1.48300001 1.562,2.63400001 2.678,3.435 1.115,0.805 2.422,1.213 3.916,1.213 2.258,0 3.995,-0.835 5.199,-2.51299999 1.211,-1.67500001 1.807,-4.27900001 1.807,-7.81200001 V -23.271089 h -2.825 v 15.3939995 c 0,2.888 -0.422,4.905 -1.261,6.075 -0.843,1.17000001 -2.063,1.75300001 -3.668,1.75300001 -1.434,0 -2.635,-0.466 -3.599,-1.41400001 -0.967,-0.939 -1.692,-2.19 -2.171,-3.767 V -23.271089 h -2.809 V 2.0039105 Z m -9.133591,-25.2752055 h -2.830008 V 2.0037072 h 2.830008 z m 0,32.4710013 h -2.830008 v 3.9819957 h 2.830008 z M -60.863903,-12.846289 c 0,-2.565 0.486,-4.605 1.472,-6.123 0.974,-1.532 2.457,-2.288 4.436,-2.288 1.356,0 2.498,0.361 3.435,1.101 0.934,0.74 1.672,1.77 2.218,3.077 v 12.5200001 c -0.525,1.346 -1.246,2.434 -2.157,3.272 -0.91,0.82400002 -2.062,1.23800002 -3.448,1.23800002 -1.975,0 -3.468,-0.86 -4.46,-2.58700002 -0.999,-1.73 -1.496,-3.986 -1.496,-6.756 z m -2.833,3.4540001 c 0,3.582 0.723,6.459 2.177,8.62700002 1.442,2.15699998 3.448,3.23899998 6.004,3.23899998 1.419,0 2.664,-0.346 3.728,-1.04 1.066,-0.68099998 1.947,-1.67799998 2.654,-2.946 l 0.274,3.516 h 2.381 V -23.294289 c 0,-3.239 -0.751,-5.749 -2.26,-7.525 -1.511,-1.769 -3.657,-2.665 -6.428,-2.665 -0.996,0 -2.067,0.156 -3.212,0.459 -1.147,0.303 -2.162,0.701 -3.052,1.2 l 0.776,2.463 c 0.759,-0.492 1.608,-0.873 2.548,-1.141 0.932,-0.277 1.895,-0.41 2.894,-0.41 2.009,0 3.498,0.645 4.46,1.932 0.966,1.304 1.45,3.19 1.45,5.687 v 3.057 c -0.717,-1.138 -1.597,-2.011 -2.64,-2.614 -1.039,-0.606 -2.253,-0.909 -3.622,-0.909 -2.539,0 -4.53,0.994 -5.968,2.982 -1.441,1.984 -2.164,4.631 -2.164,7.932 z m -19.227592,11.3961994 0.23,-4.178 c 0.674,1.48300001 1.564,2.63400001 2.682,3.435 1.108,0.805 2.413,1.213 3.914,1.213 2.258,0 3.988,-0.835 5.189,-2.51299999 1.214,-1.67500001 1.815,-4.27900001 1.815,-7.81200001 V -23.271089 h -2.825 v 15.3939995 c 0,2.888 -0.423,4.905 -1.264,6.075 -0.836,1.17000001 -2.065,1.75300001 -3.665,1.75300001 -1.435,0 -2.638,-0.466 -3.603,-1.41400001 -0.969,-0.939 -1.691,-2.19 -2.172,-3.767 V -23.271089 h -2.805 V 2.0039105 Z M -98.69412,0 c -1.763,0 -3.21,-0.802 -4.341,-2.402 -1.126,-1.606 -1.712,-3.585 -1.763,-5.944 h 11.663 v 1.082 c 0,2.086 -0.488,3.823 -1.474,5.201 -0.981,1.379 -2.341,2.063 -4.085,2.063 m 0.394,-23.76 c -2.726,0 -4.951,1.026 -6.679,3.073 -1.733,2.043 -2.6,4.657 -2.6,7.841 v 4.197 c 0,3.19 0.871,5.85 2.602,7.965 1.744,2.105 3.834,3.158 6.283,3.158 2.643,0 4.703,-0.939 6.164,-2.823 1.463,-1.887 2.197,-4.422 2.197,-7.603 v -2.773 h -14.465 v -2.102 c 0,-2.447 0.587,-4.484 1.76,-6.11 1.162,-1.63 2.742,-2.438 4.738,-2.438 1.387,0 2.585,0.244 3.585,0.724 1.007,0.491 1.866,1.179 2.589,2.082 l 1.141,-1.988 c -0.764,-0.968 -1.75,-1.75 -2.959,-2.33 -1.204,-0.577 -2.658,-0.873 -4.356,-0.873 M -129.86659,0 c -1.758,0 -3.202,-0.802 -4.334,-2.402 -1.133,-1.606 -1.718,-3.585 -1.765,-5.944 h 11.66 v 1.082 c 0,2.086 -0.489,3.823 -1.469,5.201 -0.986,1.379 -2.347,2.063 -4.092,2.063 m 0.397,-23.76 c -2.725,0 -4.954,1.026 -6.685,3.073 -1.726,2.043 -2.591,4.657 -2.591,7.841 v 4.197 c 0,3.19 0.867,5.85 2.602,7.965 1.739,2.105 3.828,3.158 6.277,3.158 2.648,0 4.699,-0.939 6.164,-2.823 1.468,-1.887 2.201,-4.422 2.201,-7.603 v -2.773 h -14.464 v -2.102 c 0,-2.447 0.586,-4.484 1.752,-6.11 1.168,-1.63 2.755,-2.438 4.744,-2.438 1.382,0 2.585,0.244 3.588,0.724 1.003,0.491 1.863,1.179 2.578,2.082 l 1.149,-1.988 c -0.763,-0.968 -1.752,-1.75 -2.959,-2.33 -1.204,-0.577 -2.659,-0.873 -4.356,-0.873 m -41.1488,25.7639105 0.24,-3.923 c 0.664,1.40400001 1.554,2.48600001 2.657,3.255 1.107,0.759 2.41,1.138 3.906,1.138 1.527,0 2.814,-0.444 3.852,-1.343 1.039,-0.89599999 1.805,-2.252 2.292,-4.074 0.623,1.682 1.505,3.01100001 2.65,3.973 1.145,0.964 2.534,1.444 4.143,1.444 2.217,0 3.937,-0.897 5.156,-2.69199999 1.224,-1.79900001 1.834,-4.55900001 1.834,-8.28800001 V -23.271089 h -2.823 v 14.8139995 c 0,3.1 -0.429,5.283 -1.263,6.538 -0.839,1.25700001 -2.042,1.89000001 -3.598,1.89000001 -1.637,0 -2.915,-0.691 -3.834,-2.09600001 -0.914,-1.405 -1.478,-3.161 -1.683,-5.282 v -0.655 -15.2089995 h -2.809 v 14.7979995 c 0,3.027 -0.424,5.194 -1.292,6.488 -0.864,1.29400001 -2.066,1.93600001 -3.609,1.93600001 -1.475,0 -2.668,-0.45 -3.562,-1.34200001 -0.9,-0.897 -1.54,-2.125 -1.928,-3.683 V -23.271089 h -2.806 V 2.0039105 Z M -188.9332,-21.231295 c 1.553,0 2.936,0.44 4.144,1.336 1.21,0.9 2.058,2.037 2.561,3.422 v 5.468 h -4.492 c -1.91,0 -3.44,-0.541 -4.585,-1.623 -1.148,-1.075 -1.716,-2.418 -1.716,-4.015 0,-1.349 0.355,-2.457 1.074,-3.311 0.718,-0.857 1.722,-1.277 3.014,-1.277 m 7.124,-2.04 c -0.14,0.876 -0.249,1.587 -0.318,2.144 -0.067,0.567 -0.101,1.131 -0.101,1.704 -0.767,-1.254 -1.757,-2.294 -2.98,-3.109 -1.221,-0.821 -2.579,-1.228 -4.075,-1.228 -2.092,0 -3.701,0.648 -4.84,1.946 -1.132,1.303 -1.704,3.059 -1.704,5.276 0,2.343 0.823,4.223 2.473,5.618 1.649,1.3950005 3.89,2.0920005 6.709,2.0920005 h 4.417 v 3.106 c 0,1.786 -0.456,3.193 -1.351,4.21 -0.914,1.00399996 -2.17,1.51199995911 -3.791,1.51199995911 -1.508,0 -2.752,-0.47899999911 -3.728,-1.44999995911 -0.973,-0.965 -1.456,-2.144 -1.456,-3.549 l -2.623,0.023 -0.046,0.137 c -0.074,1.906 0.647,3.591 2.168,5.08399996 1.515,1.48900004 3.459,2.22900004 5.825,2.22900004 2.338,0 4.22,-0.711 5.657,-2.12800004 1.429,-1.43099996 2.146,-3.47099996 2.146,-6.12399996 V -18.174295 c 0,-0.903 0.042,-1.78 0.121,-2.617 0.081,-0.848 0.212,-1.665 0.417,-2.48 z m -20.0925,4.627199 c -0.624,-1.28 -1.771,-2.454 -3.449,-3.516 -1.676,-1.069 -3.805,-1.6 -6.391,-1.6 -3.412,0 -6.156,1.075 -8.24,3.249 -2.076,2.157 -3.116,5.266 -3.116,9.323 v 10.116 c 0,3.969 0.98,7.013 2.946,9.138 1.962,2.108 4.59,3.177 7.872,3.177 3.208,0 5.695,-0.844 7.455,-2.513 1.755,-1.675 2.677,-4.015 2.757,-7.003 l -0.044,-0.133 h -2.619 c -0.094,2.29 -0.759,4.057 -2.01,5.305 -1.244,1.238 -3.095,1.864 -5.539,1.864 -2.473,0 -4.432,-0.837 -5.866,-2.516 -1.43,-1.675 -2.143,-4.103 -2.143,-7.293 v -10.174 c 0,-3.308 0.771,-5.83 2.311,-7.567 1.54,-1.724 3.616,-2.588 6.236,-2.588 1.913,0 3.451,0.339 4.602,1.033 1.155,0.684 1.956,1.519 2.409,2.51 v 8.861 h -7.06 v 2.463 h 9.889 z" + id="path213" /></g></g><g id="g78" transform="matrix(1.1310535,0,0,1.1310535,348.13109,279.2668)" style="stroke-width:0.884131"><path diff --git a/methods.py b/methods.py index 7654e6e86d..33ab894f92 100644 --- a/methods.py +++ b/methods.py @@ -50,7 +50,7 @@ def disable_warnings(self): def force_optimization_on_debug(self): # 'self' is the environment - if self["target"] != "template-release": + if self["target"] == "template_release": return if self.msvc: diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index e2a37ab6e9..d1d50351d0 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -1343,7 +1343,7 @@ void GDScriptParser::parse_function_signature(FunctionNode *p_function, SuiteNod default_used = true; } else { if (default_used) { - push_error("Cannot have a mandatory parameters after optional parameters."); + push_error("Cannot have mandatory parameters after optional parameters."); continue; } } @@ -1475,7 +1475,7 @@ GDScriptParser::AnnotationNode *GDScriptParser::parse_annotation(uint32_t p_vali void GDScriptParser::clear_unused_annotations() { for (const AnnotationNode *annotation : annotation_stack) { - push_error(vformat(R"(Annotation "%s" does not precedes a valid target, so it will have no effect.)", annotation->name), annotation); + push_error(vformat(R"(Annotation "%s" does not precede a valid target, so it will have no effect.)", annotation->name), annotation); } annotation_stack.clear(); @@ -1817,7 +1817,7 @@ GDScriptParser::ForNode *GDScriptParser::parse_for() { n_for->list = parse_expression(false); if (!n_for->list) { - push_error(R"(Expected a list or range after "in".)"); + push_error(R"(Expected iterable after "in".)"); } consume(GDScriptTokenizer::Token::COLON, R"(Expected ":" after "for" condition.)"); @@ -3856,7 +3856,7 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node variable->export_info.hint = PROPERTY_HINT_NODE_TYPE; variable->export_info.hint_string = export_type.to_string(); } else { - push_error(R"(Export type can only be built-in, a resource, a node or an enum.)", variable); + push_error(R"(Export type can only be built-in, a resource, a node, or an enum.)", variable); return false; } @@ -3901,8 +3901,7 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node variable->export_info.hint_string = enum_hint_string; } break; default: - // TODO: Allow custom user resources. - push_error(R"(Export type can only be built-in, a resource, or an enum.)", variable); + push_error(R"(Export type can only be built-in, a resource, a node, or an enum.)", variable); break; } diff --git a/modules/gdscript/gdscript_warning.cpp b/modules/gdscript/gdscript_warning.cpp index ef59a07f1a..0cb8e3a2af 100644 --- a/modules/gdscript/gdscript_warning.cpp +++ b/modules/gdscript/gdscript_warning.cpp @@ -183,7 +183,7 @@ String GDScriptWarning::get_message() const { return vformat(R"*(The default value is using "%s" which won't return nodes in the scene tree before "_ready()" is called. Use the "@onready" annotation to solve this.)*", symbols[0]); } case ONREADY_WITH_EXPORT: { - return R"(The "@onready" annotation will make the default value to be set after the "@export" takes effect and will override it.)"; + return R"("@onready" will set the default value after "@export" takes effect and will override it.)"; } case WARNING_MAX: break; // Can't happen, but silences warning diff --git a/modules/gdscript/language_server/gdscript_language_protocol.cpp b/modules/gdscript/language_server/gdscript_language_protocol.cpp index acd75f039a..0aa53c1dbe 100644 --- a/modules/gdscript/language_server/gdscript_language_protocol.cpp +++ b/modules/gdscript/language_server/gdscript_language_protocol.cpp @@ -237,6 +237,7 @@ void GDScriptLanguageProtocol::poll() { HashMap<int, Ref<LSPeer>>::Iterator E = clients.begin(); while (E != clients.end()) { Ref<LSPeer> peer = E->value; + peer->connection->poll(); StreamPeerTCP::Status status = peer->connection->get_status(); if (status == StreamPeerTCP::STATUS_NONE || status == StreamPeerTCP::STATUS_ERROR) { on_client_disconnected(E->key); diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/onready_with_export.out b/modules/gdscript/tests/scripts/analyzer/warnings/onready_with_export.out index ff184f9f04..f861d52f2b 100644 --- a/modules/gdscript/tests/scripts/analyzer/warnings/onready_with_export.out +++ b/modules/gdscript/tests/scripts/analyzer/warnings/onready_with_export.out @@ -2,5 +2,5 @@ GDTEST_OK >> WARNING >> Line: 3 >> ONREADY_WITH_EXPORT ->> The "@onready" annotation will make the default value to be set after the "@export" takes effect and will override it. +>> "@onready" will set the default value after "@export" takes effect and will override it. warn diff --git a/modules/gltf/editor/editor_scene_exporter_gltf_plugin.cpp b/modules/gltf/editor/editor_scene_exporter_gltf_plugin.cpp index 3b8d2cc701..5f6ec5904c 100644 --- a/modules/gltf/editor/editor_scene_exporter_gltf_plugin.cpp +++ b/modules/gltf/editor/editor_scene_exporter_gltf_plugin.cpp @@ -34,9 +34,9 @@ #include "../gltf_document.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_file_system.h" #include "editor/editor_node.h" +#include "editor/gui/editor_file_dialog.h" String SceneExporterGLTFPlugin::get_name() const { return "ConvertGLTF2"; diff --git a/modules/gltf/editor/editor_scene_importer_blend.cpp b/modules/gltf/editor/editor_scene_importer_blend.cpp index a736e36c6a..2efaaa7d4d 100644 --- a/modules/gltf/editor/editor_scene_importer_blend.cpp +++ b/modules/gltf/editor/editor_scene_importer_blend.cpp @@ -37,10 +37,10 @@ #include "editor_import_blend_runner.h" #include "core/config/project_settings.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/gui/editor_file_dialog.h" #include "main/main.h" #include "scene/gui/line_edit.h" diff --git a/modules/gridmap/editor/grid_map_editor_plugin.cpp b/modules/gridmap/editor/grid_map_editor_plugin.cpp index bb5eb8e643..20f1aa357b 100644 --- a/modules/gridmap/editor/grid_map_editor_plugin.cpp +++ b/modules/gridmap/editor/grid_map_editor_plugin.cpp @@ -40,6 +40,8 @@ #include "editor/editor_undo_redo_manager.h" #include "editor/plugins/node_3d_editor_plugin.h" #include "scene/3d/camera_3d.h" +#include "scene/gui/dialogs.h" +#include "scene/gui/label.h" #include "scene/gui/menu_button.h" #include "scene/gui/separator.h" #include "scene/main/window.h" diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs index 6c5c61acb9..b7e5b058c6 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs @@ -317,16 +317,6 @@ namespace GodotTools.Build if (!File.Exists(GodotSharpDirs.ProjectSlnPath)) return true; // No solution to build - try - { - // Make sure our packages are added to the fallback folder - NuGetUtils.AddBundledPackagesToFallbackFolder(NuGetUtils.GodotFallbackFolderPath); - } - catch (Exception e) - { - GD.PushError("Failed to setup Godot NuGet Offline Packages: " + e.Message); - } - if (GodotSharpEditor.Instance.SkipBuildBeforePlaying) return true; // Requested play from an external editor/IDE which already built the project diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs index cf1b84e37f..8fe7d3c2d7 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs @@ -34,16 +34,6 @@ namespace GodotTools.Build if (!File.Exists(GodotSharpDirs.ProjectSlnPath)) return; // No solution to build - try - { - // Make sure our packages are added to the fallback folder - NuGetUtils.AddBundledPackagesToFallbackFolder(NuGetUtils.GodotFallbackFolderPath); - } - catch (Exception e) - { - GD.PushError("Failed to setup Godot NuGet Offline Packages: " + e.Message); - } - if (!BuildManager.BuildProjectBlocking("Debug")) return; // Build failed @@ -62,16 +52,6 @@ namespace GodotTools.Build if (!File.Exists(GodotSharpDirs.ProjectSlnPath)) return; // No solution to build - try - { - // Make sure our packages are added to the fallback folder - NuGetUtils.AddBundledPackagesToFallbackFolder(NuGetUtils.GodotFallbackFolderPath); - } - catch (Exception e) - { - GD.PushError("Failed to setup Godot NuGet Offline Packages: " + e.Message); - } - if (!BuildManager.BuildProjectBlocking("Debug", rebuild: true)) return; // Build failed diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/NuGetUtils.cs b/modules/mono/editor/GodotTools/GodotTools/Build/NuGetUtils.cs deleted file mode 100644 index fe309b8102..0000000000 --- a/modules/mono/editor/GodotTools/GodotTools/Build/NuGetUtils.cs +++ /dev/null @@ -1,253 +0,0 @@ -using System; -using System.Globalization; -using System.IO; -using System.IO.Compression; -using System.Linq; -using System.Security.Cryptography; -using System.Text; -using System.Xml; -using Godot; -using GodotTools.Internals; -using GodotTools.Shared; -using Directory = GodotTools.Utils.Directory; -using Environment = System.Environment; -using File = GodotTools.Utils.File; - -namespace GodotTools.Build -{ - public static class NuGetUtils - { - public const string GodotFallbackFolderName = "Godot Offline Packages"; - - public static string GodotFallbackFolderPath - => Path.Combine(GodotSharpDirs.MonoUserDir, "GodotNuGetFallbackFolder"); - - /// <summary> - /// Returns all the paths where the Godot.Offline.Config files can be found. - /// Does not determine whether the returned files exist or not. - /// </summary> - private static string[] GetAllGodotNuGetConfigFilePaths() - { - // Where to find 'NuGet/config/Godot.Offline.Config': - // - // - Mono/.NETFramework (standalone NuGet): - // Uses Environment.SpecialFolder.ApplicationData - // - Windows: '%APPDATA%' - // - Linux/macOS: '$HOME/.config' - // - CoreCLR (dotnet CLI NuGet): - // - Windows: '%APPDATA%' - // - Linux/macOS: '$DOTNET_CLI_HOME/.nuget' otherwise '$HOME/.nuget' - - string applicationData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); - - const string configFileName = "Godot.Offline.Config"; - - if (Utils.OS.IsWindows) - { - // %APPDATA% for both - return new[] { Path.Combine(applicationData, "NuGet", "config", configFileName) }; - } - - var paths = new string[2]; - - // CoreCLR (dotnet CLI NuGet) - - string dotnetCliHome = Environment.GetEnvironmentVariable("DOTNET_CLI_HOME"); - if (!string.IsNullOrEmpty(dotnetCliHome)) - { - paths[0] = Path.Combine(dotnetCliHome, ".nuget", "NuGet", "config", configFileName); - } - else - { - string home = Environment.GetEnvironmentVariable("HOME"); - if (string.IsNullOrEmpty(home)) - throw new InvalidOperationException("Required environment variable 'HOME' is not set."); - paths[0] = Path.Combine(home, ".nuget", "NuGet", "config", configFileName); - } - - // Mono/.NETFramework (standalone NuGet) - - // ApplicationData is $HOME/.config on Linux/macOS - paths[1] = Path.Combine(applicationData, "NuGet", "config", configFileName); - - return paths; - } - - // nupkg extraction - // - // Exclude: (NuGet.Client -> NuGet.Packaging.PackageHelper.ExcludePaths) - // package/ - // _rels/ - // [Content_Types].xml - // - // Don't ignore files that begin with a dot (.) - // - // The nuspec is not lower case inside the nupkg but must be made lower case when extracted. - - /// <summary> - /// Adds the specified fallback folder to the Godot.Offline.Config files, - /// for both standalone NuGet (Mono/.NETFramework) and dotnet CLI NuGet. - /// </summary> - public static void AddFallbackFolderToGodotNuGetConfigs(string name, string path) - { - // Make sure the fallback folder exists to avoid error: - // MSB4018: The "ResolvePackageAssets" task failed unexpectedly. - System.IO.Directory.CreateDirectory(path); - - foreach (string nuGetConfigPath in GetAllGodotNuGetConfigFilePaths()) - { - string defaultConfig = @$"<?xml version=""1.0"" encoding=""utf-8""?> -<configuration> - <fallbackPackageFolders> - <add key=""{name}"" value=""{path}"" /> - </fallbackPackageFolders> -</configuration> -"; - System.IO.Directory.CreateDirectory(Path.GetDirectoryName(nuGetConfigPath)); - System.IO.File.WriteAllText(nuGetConfigPath, defaultConfig, Encoding.UTF8); // UTF-8 with BOM - } - } - - private static void AddPackageToFallbackFolder(string fallbackFolder, - string nupkgPath, string packageId, string packageVersion) - { - // dotnet CLI provides no command for this, but we can do it manually. - // - // - The expected structure is as follows: - // fallback_folder/ - // <package.name>/<version>/ - // <package.name>.<version>.nupkg - // <package.name>.<version>.nupkg.sha512 - // <package.name>.nuspec - // ... extracted nupkg files (check code for excluded files) ... - // - // - <package.name> and <version> must be in lower case. - // - The sha512 of the nupkg is base64 encoded. - // - We can get the nuspec from the nupkg which is a Zip file. - - string packageIdLower = packageId.ToLowerInvariant(); - string packageVersionLower = packageVersion.ToLowerInvariant(); - - string destDir = Path.Combine(fallbackFolder, packageIdLower, packageVersionLower); - string nupkgDestPath = Path.Combine(destDir, $"{packageIdLower}.{packageVersionLower}.nupkg"); - string nupkgSha512DestPath = Path.Combine(destDir, $"{packageIdLower}.{packageVersionLower}.nupkg.sha512"); - string nupkgMetadataDestPath = Path.Combine(destDir, ".nupkg.metadata"); - - if (File.Exists(nupkgDestPath) && File.Exists(nupkgSha512DestPath)) - return; // Already added (for speed we don't check if every file is properly extracted) - - Directory.CreateDirectory(destDir); - - // Generate .nupkg.sha512 file - - byte[] hash = SHA512.HashData(File.ReadAllBytes(nupkgPath)); - string base64Hash = Convert.ToBase64String(hash); - File.WriteAllText(nupkgSha512DestPath, base64Hash); - - // Generate .nupkg.metadata file - // Spec: https://github.com/NuGet/Home/wiki/Nupkg-Metadata-File - - File.WriteAllText(nupkgMetadataDestPath, @$"{{ - ""version"": 2, - ""contentHash"": ""{base64Hash}"", - ""source"": null -}}"); - - // Extract nupkg - ExtractNupkg(destDir, nupkgPath, packageId, packageVersion); - - // Copy .nupkg - File.Copy(nupkgPath, nupkgDestPath); - } - - private static readonly string[] NupkgExcludePaths = - { - "_rels/", - "package/", - "[Content_Types].xml" - }; - - private static void ExtractNupkg(string destDir, string nupkgPath, string packageId, string packageVersion) - { - // NOTE: Must use SimplifyGodotPath to make sure we don't extract files outside the destination directory. - - using (var archive = ZipFile.OpenRead(nupkgPath)) - { - // Extract .nuspec manually as it needs to be in lower case - - var nuspecEntry = archive.GetEntry(packageId + ".nuspec"); - - if (nuspecEntry == null) - throw new InvalidOperationException( - $"Failed to extract package {packageId}.{packageVersion}. Could not find the nuspec file."); - - nuspecEntry.ExtractToFile(Path.Combine(destDir, nuspecEntry.Name - .ToLowerInvariant().SimplifyGodotPath())); - - // Extract the other package files - - foreach (var entry in archive.Entries) - { - // NOTE: SimplifyGodotPath() removes trailing slash and backslash, - // so we can't use the result to check if the entry is a directory. - - string entryFullName = entry.FullName.Replace('\\', '/'); - - // Check if the file must be ignored - if ( // Excluded files. - NupkgExcludePaths.Any(e => entryFullName.StartsWith(e, StringComparison.OrdinalIgnoreCase)) || - // Nupkg hash files and nupkg metadata files on all directory. - entryFullName.EndsWith(".nupkg.sha512", StringComparison.OrdinalIgnoreCase) || - entryFullName.EndsWith(".nupkg.metadata", StringComparison.OrdinalIgnoreCase) || - // Nuspec at root level. We already extracted it previously but in lower case. - !entryFullName.Contains('/') && entryFullName.EndsWith(".nuspec")) - { - continue; - } - - string entryFullNameSimplified = entryFullName.SimplifyGodotPath(); - string destFilePath = Path.Combine(destDir, entryFullNameSimplified); - bool isDir = entryFullName.EndsWith("/"); - - if (isDir) - { - Directory.CreateDirectory(destFilePath); - } - else - { - Directory.CreateDirectory(Path.GetDirectoryName(destFilePath)); - entry.ExtractToFile(destFilePath, overwrite: true); - } - } - } - } - - /// <summary> - /// Copies and extracts all the Godot bundled packages to the Godot NuGet fallback folder. - /// Does nothing if the packages were already copied. - /// </summary> - public static void AddBundledPackagesToFallbackFolder(string fallbackFolder) - { - GD.Print("Copying Godot Offline Packages..."); - - string nupkgsLocation = Path.Combine(GodotSharpDirs.DataEditorToolsDir, "nupkgs"); - - void AddPackage(string packageId, string packageVersion) - { - string nupkgPath = Path.Combine(nupkgsLocation, $"{packageId}.{packageVersion}.nupkg"); - AddPackageToFallbackFolder(fallbackFolder, nupkgPath, packageId, packageVersion); - } - - foreach (var (packageId, packageVersion) in PackagesToAdd) - AddPackage(packageId, packageVersion); - } - - private static readonly (string packageId, string packageVersion)[] PackagesToAdd = - { - ("Godot.NET.Sdk", GeneratedGodotNupkgsVersions.GodotNETSdk), - ("Godot.SourceGenerators", GeneratedGodotNupkgsVersions.GodotSourceGenerators), - ("GodotSharp", GeneratedGodotNupkgsVersions.GodotSharp), - ("GodotSharpEditor", GeneratedGodotNupkgsVersions.GodotSharp), - }; - } -} diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs index f50803af95..9eefa3c386 100644 --- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs +++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs @@ -133,22 +133,6 @@ namespace GodotTools } break; } - case MenuOptions.SetupGodotNugetFallbackFolder: - { - try - { - string fallbackFolder = NuGetUtils.GodotFallbackFolderPath; - NuGetUtils.AddFallbackFolderToGodotNuGetConfigs(NuGetUtils.GodotFallbackFolderName, - fallbackFolder); - NuGetUtils.AddBundledPackagesToFallbackFolder(fallbackFolder); - } - catch (Exception e) - { - ShowErrorDialog("Failed to setup Godot NuGet Offline Packages: " + e.Message); - } - - break; - } default: throw new ArgumentOutOfRangeException(nameof(id), id, "Invalid menu option"); } @@ -168,7 +152,6 @@ namespace GodotTools private enum MenuOptions { CreateSln, - SetupGodotNugetFallbackFolder, } public void ShowErrorDialog(string message, string title = "Error") @@ -533,17 +516,6 @@ namespace GodotTools exportPlugin.RegisterExportSettings(); _exportPluginWeak = WeakRef(exportPlugin); - try - { - // At startup we make sure NuGet.Config files have our Godot NuGet fallback folder included - NuGetUtils.AddFallbackFolderToGodotNuGetConfigs(NuGetUtils.GodotFallbackFolderName, - NuGetUtils.GodotFallbackFolderPath); - } - catch (Exception e) - { - GD.PushError("Failed to add Godot NuGet Offline Packages to NuGet.Config: " + e.Message); - } - BuildManager.Initialize(); RiderPathManager.Initialize(); diff --git a/modules/multiplayer/editor/replication_editor.cpp b/modules/multiplayer/editor/replication_editor.cpp index 9e542828ee..1f707f1192 100644 --- a/modules/multiplayer/editor/replication_editor.cpp +++ b/modules/multiplayer/editor/replication_editor.cpp @@ -36,9 +36,9 @@ #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/gui/scene_tree_editor.h" #include "editor/inspector_dock.h" #include "editor/property_selector.h" -#include "editor/scene_tree_editor.h" #include "scene/gui/dialogs.h" #include "scene/gui/separator.h" #include "scene/gui/tree.h" diff --git a/modules/navigation/editor/navigation_mesh_editor_plugin.cpp b/modules/navigation/editor/navigation_mesh_editor_plugin.cpp index 557d45b386..dd2c539c95 100644 --- a/modules/navigation/editor/navigation_mesh_editor_plugin.cpp +++ b/modules/navigation/editor/navigation_mesh_editor_plugin.cpp @@ -38,6 +38,9 @@ #include "editor/editor_node.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/gui/box_container.h" +#include "scene/gui/button.h" +#include "scene/gui/dialogs.h" +#include "scene/gui/label.h" void NavigationMeshEditor::_node_removed(Node *p_node) { if (p_node == node) { diff --git a/modules/navigation/editor/navigation_mesh_editor_plugin.h b/modules/navigation/editor/navigation_mesh_editor_plugin.h index 010be411d6..b73d8d2e69 100644 --- a/modules/navigation/editor/navigation_mesh_editor_plugin.h +++ b/modules/navigation/editor/navigation_mesh_editor_plugin.h @@ -36,7 +36,9 @@ #include "editor/editor_plugin.h" class AcceptDialog; +class Button; class HBoxContainer; +class Label; class NavigationRegion3D; class NavigationMeshEditor : public Control { diff --git a/modules/openxr/doc_classes/OpenXRInterface.xml b/modules/openxr/doc_classes/OpenXRInterface.xml index 16a16a7f24..b6d52464c0 100644 --- a/modules/openxr/doc_classes/OpenXRInterface.xml +++ b/modules/openxr/doc_classes/OpenXRInterface.xml @@ -43,6 +43,9 @@ <member name="display_refresh_rate" type="float" setter="set_display_refresh_rate" getter="get_display_refresh_rate" default="0.0"> The display refresh rate for the current HMD. Only functional if this feature is supported by the OpenXR runtime and after the interface has been initialized. </member> + <member name="render_target_size_multiplier" type="float" setter="set_render_target_size_multiplier" getter="get_render_target_size_multiplier" default="1.0"> + The render size multiplier for the current HMD. Must be set before the interface has been initialized. + </member> </members> <signals> <signal name="pose_recentered"> diff --git a/modules/openxr/editor/openxr_action_map_editor.cpp b/modules/openxr/editor/openxr_action_map_editor.cpp index ad5a515a01..64e07eff21 100644 --- a/modules/openxr/editor/openxr_action_map_editor.cpp +++ b/modules/openxr/editor/openxr_action_map_editor.cpp @@ -31,10 +31,10 @@ #include "openxr_action_map_editor.h" #include "core/config/project_settings.h" -#include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/gui/editor_file_dialog.h" // TODO implement redo/undo system diff --git a/modules/openxr/openxr_api.cpp b/modules/openxr/openxr_api.cpp index 4b39a6295c..d1680612d9 100644 --- a/modules/openxr/openxr_api.cpp +++ b/modules/openxr/openxr_api.cpp @@ -1423,8 +1423,8 @@ Size2 OpenXRAPI::get_recommended_target_size() { Size2 target_size; - target_size.width = view_configuration_views[0].recommendedImageRectWidth; - target_size.height = view_configuration_views[0].recommendedImageRectHeight; + target_size.width = view_configuration_views[0].recommendedImageRectWidth * render_target_size_multiplier; + target_size.height = view_configuration_views[0].recommendedImageRectHeight * render_target_size_multiplier; return target_size; } @@ -1964,6 +1964,14 @@ Array OpenXRAPI::get_available_display_refresh_rates() const { return Array(); } +double OpenXRAPI::get_render_target_size_multiplier() const { + return render_target_size_multiplier; +} + +void OpenXRAPI::set_render_target_size_multiplier(double multiplier) { + render_target_size_multiplier = multiplier; +} + OpenXRAPI::OpenXRAPI() { // OpenXRAPI is only constructed if OpenXR is enabled. singleton = this; diff --git a/modules/openxr/openxr_api.h b/modules/openxr/openxr_api.h index c8bef5d420..292e54228d 100644 --- a/modules/openxr/openxr_api.h +++ b/modules/openxr/openxr_api.h @@ -120,6 +120,7 @@ private: XrSessionState session_state = XR_SESSION_STATE_UNKNOWN; bool running = false; XrFrameState frame_state = { XR_TYPE_FRAME_STATE, NULL, 0, 0, false }; + double render_target_size_multiplier = 1.0; OpenXRGraphicsExtensionWrapper *graphics_extension = nullptr; XrSystemGraphicsProperties graphics_properties; @@ -368,6 +369,10 @@ public: void set_display_refresh_rate(float p_refresh_rate); Array get_available_display_refresh_rates() const; + // Render Target size multiplier + double get_render_target_size_multiplier() const; + void set_render_target_size_multiplier(double multiplier); + // action map String get_default_action_map_resource_name(); diff --git a/modules/openxr/openxr_interface.cpp b/modules/openxr/openxr_interface.cpp index 27344c9da7..933148da87 100644 --- a/modules/openxr/openxr_interface.cpp +++ b/modules/openxr/openxr_interface.cpp @@ -47,6 +47,11 @@ void OpenXRInterface::_bind_methods() { ClassDB::bind_method(D_METHOD("set_display_refresh_rate", "refresh_rate"), &OpenXRInterface::set_display_refresh_rate); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "display_refresh_rate"), "set_display_refresh_rate", "get_display_refresh_rate"); + // Render Target size multiplier + ClassDB::bind_method(D_METHOD("get_render_target_size_multiplier"), &OpenXRInterface::get_render_target_size_multiplier); + ClassDB::bind_method(D_METHOD("set_render_target_size_multiplier", "multiplier"), &OpenXRInterface::set_render_target_size_multiplier); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "render_target_size_multiplier"), "set_render_target_size_multiplier", "get_render_target_size_multiplier"); + ClassDB::bind_method(D_METHOD("is_action_set_active", "name"), &OpenXRInterface::is_action_set_active); ClassDB::bind_method(D_METHOD("set_action_set_active", "name", "active"), &OpenXRInterface::set_action_set_active); ClassDB::bind_method(D_METHOD("get_action_sets"), &OpenXRInterface::get_action_sets); @@ -668,6 +673,22 @@ Array OpenXRInterface::get_action_sets() const { return arr; } +double OpenXRInterface::get_render_target_size_multiplier() const { + if (openxr_api == nullptr) { + return 1.0; + } else { + return openxr_api->get_render_target_size_multiplier(); + } +} + +void OpenXRInterface::set_render_target_size_multiplier(double multiplier) { + if (openxr_api == nullptr) { + return; + } else { + openxr_api->set_render_target_size_multiplier(multiplier); + } +} + Size2 OpenXRInterface::get_render_target_size() { if (openxr_api == nullptr) { return Size2(); diff --git a/modules/openxr/openxr_interface.h b/modules/openxr/openxr_interface.h index de758a8c2d..f36318530c 100644 --- a/modules/openxr/openxr_interface.h +++ b/modules/openxr/openxr_interface.h @@ -128,6 +128,9 @@ public: void set_action_set_active(const String &p_action_set, bool p_active); Array get_action_sets() const; + double get_render_target_size_multiplier() const; + void set_render_target_size_multiplier(double multiplier); + virtual Size2 get_render_target_size() override; virtual uint32_t get_view_count() override; virtual Transform3D get_camera_transform() override; diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index c6a21aeefe..43c7f49395 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -4182,22 +4182,37 @@ bool TextServerAdvanced::_shape_substr(ShapedTextDataAdvanced *p_new_sd, const S ERR_FAIL_COND_V_MSG((start < 0 || end - start > p_new_sd->utf16.length()), false, "Invalid BiDi override range."); // Create temporary line bidi & shape. - UBiDi *bidi_iter = ubidi_openSized(end - start, 0, &err); - ERR_FAIL_COND_V_MSG(U_FAILURE(err), false, u_errorName(err)); - ubidi_setLine(p_sd->bidi_iter[ov], start, end, bidi_iter, &err); - if (U_FAILURE(err)) { - ubidi_close(bidi_iter); - ERR_FAIL_V_MSG(false, u_errorName(err)); + UBiDi *bidi_iter = nullptr; + if (p_sd->bidi_iter[ov]) { + bidi_iter = ubidi_openSized(end - start, 0, &err); + if (U_SUCCESS(err)) { + ubidi_setLine(p_sd->bidi_iter[ov], start, end, bidi_iter, &err); + if (U_FAILURE(err)) { + ubidi_close(bidi_iter); + bidi_iter = nullptr; + ERR_PRINT(vformat("BiDi reordering for the line failed: %s", u_errorName(err))); + } + } else { + bidi_iter = nullptr; + ERR_PRINT(vformat("BiDi iterator allocation for the line failed: %s", u_errorName(err))); + } } p_new_sd->bidi_iter.push_back(bidi_iter); err = U_ZERO_ERROR; - int bidi_run_count = ubidi_countRuns(bidi_iter, &err); - ERR_FAIL_COND_V_MSG(U_FAILURE(err), false, u_errorName(err)); + int bidi_run_count = 1; + if (bidi_iter) { + bidi_run_count = ubidi_countRuns(bidi_iter, &err); + if (U_FAILURE(err)) { + ERR_PRINT(u_errorName(err)); + } + } for (int i = 0; i < bidi_run_count; i++) { int32_t _bidi_run_start = 0; - int32_t _bidi_run_length = 0; - ubidi_getVisualRun(bidi_iter, i, &_bidi_run_start, &_bidi_run_length); + int32_t _bidi_run_length = end - start; + if (bidi_iter) { + ubidi_getVisualRun(bidi_iter, i, &_bidi_run_start, &_bidi_run_length); + } int32_t bidi_run_start = _convert_pos(p_sd, ov_start + start + _bidi_run_start); int32_t bidi_run_end = _convert_pos(p_sd, ov_start + start + _bidi_run_start + _bidi_run_length); @@ -5642,38 +5657,53 @@ bool TextServerAdvanced::_shaped_text_shape(const RID &p_shaped) { UErrorCode err = U_ZERO_ERROR; UBiDi *bidi_iter = ubidi_openSized(end - start, 0, &err); - ERR_FAIL_COND_V_MSG(U_FAILURE(err), false, u_errorName(err)); - - switch (static_cast<TextServer::Direction>(sd->bidi_override[ov].z)) { - case DIRECTION_LTR: { - ubidi_setPara(bidi_iter, data + start, end - start, UBIDI_LTR, nullptr, &err); - } break; - case DIRECTION_RTL: { - ubidi_setPara(bidi_iter, data + start, end - start, UBIDI_RTL, nullptr, &err); - } break; - case DIRECTION_INHERITED: { - ubidi_setPara(bidi_iter, data + start, end - start, base_para_direction, nullptr, &err); - } break; - case DIRECTION_AUTO: { - UBiDiDirection direction = ubidi_getBaseDirection(data + start, end - start); - if (direction != UBIDI_NEUTRAL) { - ubidi_setPara(bidi_iter, data + start, end - start, direction, nullptr, &err); - } else { + if (U_SUCCESS(err)) { + switch (static_cast<TextServer::Direction>(sd->bidi_override[ov].z)) { + case DIRECTION_LTR: { + ubidi_setPara(bidi_iter, data + start, end - start, UBIDI_LTR, nullptr, &err); + } break; + case DIRECTION_RTL: { + ubidi_setPara(bidi_iter, data + start, end - start, UBIDI_RTL, nullptr, &err); + } break; + case DIRECTION_INHERITED: { ubidi_setPara(bidi_iter, data + start, end - start, base_para_direction, nullptr, &err); - } - } break; + } break; + case DIRECTION_AUTO: { + UBiDiDirection direction = ubidi_getBaseDirection(data + start, end - start); + if (direction != UBIDI_NEUTRAL) { + ubidi_setPara(bidi_iter, data + start, end - start, direction, nullptr, &err); + } else { + ubidi_setPara(bidi_iter, data + start, end - start, base_para_direction, nullptr, &err); + } + } break; + } + if (U_FAILURE(err)) { + ubidi_close(bidi_iter); + bidi_iter = nullptr; + ERR_PRINT(vformat("BiDi reordering for the paragraph failed: %s", u_errorName(err))); + } + } else { + bidi_iter = nullptr; + ERR_PRINT(vformat("BiDi iterator allocation for the paragraph failed: %s", u_errorName(err))); } - ERR_FAIL_COND_V_MSG(U_FAILURE(err), false, u_errorName(err)); sd->bidi_iter.push_back(bidi_iter); err = U_ZERO_ERROR; - int bidi_run_count = ubidi_countRuns(bidi_iter, &err); - ERR_FAIL_COND_V_MSG(U_FAILURE(err), false, u_errorName(err)); + int bidi_run_count = 1; + if (bidi_iter) { + bidi_run_count = ubidi_countRuns(bidi_iter, &err); + if (U_FAILURE(err)) { + ERR_PRINT(u_errorName(err)); + } + } for (int i = 0; i < bidi_run_count; i++) { int32_t _bidi_run_start = 0; - int32_t _bidi_run_length = 0; + int32_t _bidi_run_length = end - start; + bool is_rtl = false; hb_direction_t bidi_run_direction = HB_DIRECTION_INVALID; - bool is_rtl = (ubidi_getVisualRun(bidi_iter, i, &_bidi_run_start, &_bidi_run_length) == UBIDI_LTR); + if (bidi_iter) { + is_rtl = (ubidi_getVisualRun(bidi_iter, i, &_bidi_run_start, &_bidi_run_length) == UBIDI_LTR); + } switch (sd->orientation) { case ORIENTATION_HORIZONTAL: { if (is_rtl) { diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index b959dd8544..af3a0c7876 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -515,7 +515,9 @@ class TextServerAdvanced : public TextServerExtension { ~ShapedTextDataAdvanced() { for (int i = 0; i < bidi_iter.size(); i++) { - ubidi_close(bidi_iter[i]); + if (bidi_iter[i]) { + ubidi_close(bidi_iter[i]); + } } if (script_iter) { memdelete(script_iter); diff --git a/modules/vhacd/register_types.cpp b/modules/vhacd/register_types.cpp index 6310becf1b..088f03ebe8 100644 --- a/modules/vhacd/register_types.cpp +++ b/modules/vhacd/register_types.cpp @@ -32,22 +32,22 @@ #include "scene/resources/mesh.h" #include "thirdparty/vhacd/public/VHACD.h" -static Vector<Vector<Vector3>> convex_decompose(const real_t *p_vertices, int p_vertex_count, const uint32_t *p_triangles, int p_triangle_count, const Mesh::ConvexDecompositionSettings &p_settings, Vector<Vector<uint32_t>> *r_convex_indices) { +static Vector<Vector<Vector3>> convex_decompose(const real_t *p_vertices, int p_vertex_count, const uint32_t *p_triangles, int p_triangle_count, const Ref<MeshConvexDecompositionSettings> &p_settings, Vector<Vector<uint32_t>> *r_convex_indices) { VHACD::IVHACD::Parameters params; - params.m_concavity = p_settings.max_concavity; - params.m_alpha = p_settings.symmetry_planes_clipping_bias; - params.m_beta = p_settings.revolution_axes_clipping_bias; - params.m_minVolumePerCH = p_settings.min_volume_per_convex_hull; - params.m_resolution = p_settings.resolution; - params.m_maxNumVerticesPerCH = p_settings.max_num_vertices_per_convex_hull; - params.m_planeDownsampling = p_settings.plane_downsampling; - params.m_convexhullDownsampling = p_settings.convexhull_downsampling; - params.m_pca = p_settings.normalize_mesh; - params.m_mode = p_settings.mode; - params.m_convexhullApproximation = p_settings.convexhull_approximation; + params.m_concavity = p_settings->get_max_concavity(); + params.m_alpha = p_settings->get_symmetry_planes_clipping_bias(); + params.m_beta = p_settings->get_revolution_axes_clipping_bias(); + params.m_minVolumePerCH = p_settings->get_min_volume_per_convex_hull(); + params.m_resolution = p_settings->get_resolution(); + params.m_maxNumVerticesPerCH = p_settings->get_max_num_vertices_per_convex_hull(); + params.m_planeDownsampling = p_settings->get_plane_downsampling(); + params.m_convexhullDownsampling = p_settings->get_convex_hull_downsampling(); + params.m_pca = p_settings->get_normalize_mesh(); + params.m_mode = p_settings->get_mode(); + params.m_convexhullApproximation = p_settings->get_convex_hull_approximation(); params.m_oclAcceleration = true; - params.m_maxConvexHulls = p_settings.max_convex_hulls; - params.m_projectHullVertices = p_settings.project_hull_vertices; + params.m_maxConvexHulls = p_settings->get_max_convex_hulls(); + params.m_projectHullVertices = p_settings->get_project_hull_vertices(); VHACD::IVHACD *decomposer = VHACD::CreateVHACD(); decomposer->Compute(p_vertices, p_vertex_count, p_triangles, p_triangle_count, params); diff --git a/modules/webxr/doc_classes/WebXRInterface.xml b/modules/webxr/doc_classes/WebXRInterface.xml index 758c37e2ad..ed162b1da2 100644 --- a/modules/webxr/doc_classes/WebXRInterface.xml +++ b/modules/webxr/doc_classes/WebXRInterface.xml @@ -93,6 +93,18 @@ <link title="How to make a VR game for WebXR with Godot 4">https://www.snopekgames.com/tutorial/2023/how-make-vr-game-webxr-godot-4</link> </tutorials> <methods> + <method name="get_available_display_refresh_rates" qualifiers="const"> + <return type="Array" /> + <description> + Returns display refresh rates supported by the current HMD. Only returned if this feature is supported by the web browser and after the interface has been initialized. + </description> + </method> + <method name="get_display_refresh_rate" qualifiers="const"> + <return type="float" /> + <description> + Returns the display refresh rate for the current HMD. Not supported on all HMDs and browsers. It may not report an accurate value until after using [method set_display_refresh_rate]. + </description> + </method> <method name="get_input_source_target_ray_mode" qualifiers="const"> <return type="int" enum="WebXRInterface.TargetRayMode" /> <param index="0" name="input_source_id" type="int" /> @@ -132,6 +144,13 @@ This method returns nothing, instead it emits the [signal session_supported] signal with the result. </description> </method> + <method name="set_display_refresh_rate"> + <return type="void" /> + <param index="0" name="refresh_rate" type="float" /> + <description> + Sets the display refresh rate for the current HMD. Not supported on all HMDs and browsers. It won't take effect right away until after [signal display_refresh_rate_changed] is emitted. + </description> + </method> </methods> <members> <member name="optional_features" type="String" setter="set_optional_features" getter="get_optional_features"> @@ -167,6 +186,11 @@ </member> </members> <signals> + <signal name="display_refresh_rate_changed"> + <description> + Emitted after the display's refresh rate has changed. + </description> + </signal> <signal name="reference_space_reset"> <description> Emitted to indicate that the reference space has been reset or reconfigured. diff --git a/modules/webxr/godot_webxr.h b/modules/webxr/godot_webxr.h index c636be1576..554ca0398b 100644 --- a/modules/webxr/godot_webxr.h +++ b/modules/webxr/godot_webxr.h @@ -90,6 +90,10 @@ extern bool godot_webxr_update_input_source( extern char *godot_webxr_get_visibility_state(); extern int godot_webxr_get_bounds_geometry(float **r_points); +extern float godot_webxr_get_frame_rate(); +extern void godot_webxr_update_target_frame_rate(float p_frame_rate); +extern int godot_webxr_get_supported_frame_rates(float **r_frame_rates); + #ifdef __cplusplus } #endif diff --git a/modules/webxr/native/library_godot_webxr.js b/modules/webxr/native/library_godot_webxr.js index 5c01d88a30..fe47de02b0 100644 --- a/modules/webxr/native/library_godot_webxr.js +++ b/modules/webxr/native/library_godot_webxr.js @@ -42,6 +42,7 @@ const GodotWebXR = { view_count: 1, input_sources: new Array(16), touches: new Array(5), + onsimpleevent: null, // Monkey-patch the requestAnimationFrame() used by Emscripten for the main // loop, so that we can swap it out for XRSession.requestAnimationFrame() @@ -283,6 +284,9 @@ const GodotWebXR = { GodotRuntime.free(c_str); }); + // Store onsimpleevent so we can use it later. + GodotWebXR.onsimpleevent = onsimpleevent; + const gl_context_handle = _emscripten_webgl_get_current_context(); // eslint-disable-line no-undef const gl = GL.getContext(gl_context_handle).GLctx; GodotWebXR.gl = gl; @@ -368,6 +372,7 @@ const GodotWebXR = { GodotWebXR.view_count = 1; GodotWebXR.input_sources = new Array(16); GodotWebXR.touches = new Array(5); + GodotWebXR.onsimpleevent = null; // Disable the monkey-patched window.requestAnimationFrame() and // pause/restart the main loop to activate it on all platforms. @@ -594,6 +599,51 @@ const GodotWebXR = { return point_count; }, + + godot_webxr_get_frame_rate__proxy: 'sync', + godot_webxr_get_frame_rate__sig: 'i', + godot_webxr_get_frame_rate: function () { + if (!GodotWebXR.session || GodotWebXR.session.frameRate === undefined) { + return 0; + } + return GodotWebXR.session.frameRate; + }, + + godot_webxr_update_target_frame_rate__proxy: 'sync', + godot_webxr_update_target_frame_rate__sig: 'vi', + godot_webxr_update_target_frame_rate: function (p_frame_rate) { + if (!GodotWebXR.session || GodotWebXR.session.updateTargetFrameRate === undefined) { + return; + } + + GodotWebXR.session.updateTargetFrameRate(p_frame_rate).then(() => { + const c_str = GodotRuntime.allocString('display_refresh_rate_changed'); + GodotWebXR.onsimpleevent(c_str); + GodotRuntime.free(c_str); + }); + }, + + godot_webxr_get_supported_frame_rates__proxy: 'sync', + godot_webxr_get_supported_frame_rates__sig: 'ii', + godot_webxr_get_supported_frame_rates: function (r_frame_rates) { + if (!GodotWebXR.session || GodotWebXR.session.supportedFrameRates === undefined) { + return 0; + } + + const frame_rate_count = GodotWebXR.session.supportedFrameRates.length; + if (frame_rate_count === 0) { + return 0; + } + + const buf = GodotRuntime.malloc(frame_rate_count * 4); + for (let i = 0; i < frame_rate_count; i++) { + GodotRuntime.setHeapValue(buf + (i * 4), GodotWebXR.session.supportedFrameRates[i], 'float'); + } + GodotRuntime.setHeapValue(r_frame_rates, buf, 'i32'); + + return frame_rate_count; + }, + }; autoAddDeps(GodotWebXR, '$GodotWebXR'); diff --git a/modules/webxr/native/webxr.externs.js b/modules/webxr/native/webxr.externs.js index 4b88820b19..7f7c297acc 100644 --- a/modules/webxr/native/webxr.externs.js +++ b/modules/webxr/native/webxr.externs.js @@ -68,6 +68,16 @@ XRSession.prototype.inputSources; XRSession.prototype.visibilityState; /** + * @type {?number} + */ +XRSession.prototype.frameRate; + +/** + * @type {?Float32Array} + */ +XRSession.prototype.supportedFrameRates; + +/** * @type {?function (Event)} */ XRSession.prototype.onend; @@ -142,6 +152,12 @@ XRSession.prototype.end = function () {}; XRSession.prototype.requestReferenceSpace = function (referenceSpaceType) {}; /** + * @param {number} rate + * @return {Promise<undefined>} + */ +XRSession.prototype.updateTargetFrameRate = function (rate) {}; + +/** * @typedef {function(number, XRFrame): undefined} */ var XRFrameRequestCallback; diff --git a/modules/webxr/webxr_interface.cpp b/modules/webxr/webxr_interface.cpp index d7f4247768..5e30d0c996 100644 --- a/modules/webxr/webxr_interface.cpp +++ b/modules/webxr/webxr_interface.cpp @@ -46,6 +46,9 @@ void WebXRInterface::_bind_methods() { ClassDB::bind_method(D_METHOD("get_input_source_tracker", "input_source_id"), &WebXRInterface::get_input_source_tracker); ClassDB::bind_method(D_METHOD("get_input_source_target_ray_mode", "input_source_id"), &WebXRInterface::get_input_source_target_ray_mode); ClassDB::bind_method(D_METHOD("get_visibility_state"), &WebXRInterface::get_visibility_state); + ClassDB::bind_method(D_METHOD("get_display_refresh_rate"), &WebXRInterface::get_display_refresh_rate); + ClassDB::bind_method(D_METHOD("set_display_refresh_rate", "refresh_rate"), &WebXRInterface::set_display_refresh_rate); + ClassDB::bind_method(D_METHOD("get_available_display_refresh_rates"), &WebXRInterface::get_available_display_refresh_rates); ADD_PROPERTY(PropertyInfo(Variant::STRING, "session_mode", PROPERTY_HINT_NONE), "set_session_mode", "get_session_mode"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "required_features", PROPERTY_HINT_NONE), "set_required_features", "get_required_features"); @@ -68,6 +71,7 @@ void WebXRInterface::_bind_methods() { ADD_SIGNAL(MethodInfo("visibility_state_changed")); ADD_SIGNAL(MethodInfo("reference_space_reset")); + ADD_SIGNAL(MethodInfo("display_refresh_rate_changed")); BIND_ENUM_CONSTANT(TARGET_RAY_MODE_UNKNOWN); BIND_ENUM_CONSTANT(TARGET_RAY_MODE_GAZE); diff --git a/modules/webxr/webxr_interface.h b/modules/webxr/webxr_interface.h index f18b4b40e6..abaa8c01f8 100644 --- a/modules/webxr/webxr_interface.h +++ b/modules/webxr/webxr_interface.h @@ -66,6 +66,9 @@ public: virtual Ref<XRPositionalTracker> get_input_source_tracker(int p_input_source_id) const = 0; virtual TargetRayMode get_input_source_target_ray_mode(int p_input_source_id) const = 0; virtual String get_visibility_state() const = 0; + virtual float get_display_refresh_rate() const = 0; + virtual void set_display_refresh_rate(float p_refresh_rate) = 0; + virtual Array get_available_display_refresh_rates() const = 0; }; VARIANT_ENUM_CAST(WebXRInterface::TargetRayMode); diff --git a/modules/webxr/webxr_interface_js.cpp b/modules/webxr/webxr_interface_js.cpp index d3710bd0df..e1df2ea94e 100644 --- a/modules/webxr/webxr_interface_js.cpp +++ b/modules/webxr/webxr_interface_js.cpp @@ -202,6 +202,30 @@ PackedVector3Array WebXRInterfaceJS::get_play_area() const { return ret; } +float WebXRInterfaceJS::get_display_refresh_rate() const { + return godot_webxr_get_frame_rate(); +} + +void WebXRInterfaceJS::set_display_refresh_rate(float p_refresh_rate) { + godot_webxr_update_target_frame_rate(p_refresh_rate); +} + +Array WebXRInterfaceJS::get_available_display_refresh_rates() const { + Array ret; + + float *rates; + int rate_count = godot_webxr_get_supported_frame_rates(&rates); + if (rate_count > 0) { + ret.resize(rate_count); + for (int i = 0; i < rate_count; i++) { + ret[i] = rates[i]; + } + free(rates); + } + + return ret; +} + StringName WebXRInterfaceJS::get_name() const { return "WebXR"; }; diff --git a/modules/webxr/webxr_interface_js.h b/modules/webxr/webxr_interface_js.h index 20516e89e2..d85eb8cad7 100644 --- a/modules/webxr/webxr_interface_js.h +++ b/modules/webxr/webxr_interface_js.h @@ -102,6 +102,10 @@ public: virtual String get_visibility_state() const override; virtual PackedVector3Array get_play_area() const override; + virtual float get_display_refresh_rate() const override; + virtual void set_display_refresh_rate(float p_refresh_rate) override; + virtual Array get_available_display_refresh_rates() const override; + virtual StringName get_name() const override; virtual uint32_t get_capabilities() const override; diff --git a/platform/android/tts_android.h b/platform/android/tts_android.h index 8e3bfccbdb..8e00ac5000 100644 --- a/platform/android/tts_android.h +++ b/platform/android/tts_android.h @@ -32,6 +32,7 @@ #define TTS_ANDROID_H #include "core/string/ustring.h" +#include "core/templates/hash_map.h" #include "core/variant/array.h" #include "servers/display_server.h" diff --git a/platform/ios/tts_ios.h b/platform/ios/tts_ios.h index 2d104de8ae..7f9d30b22b 100644 --- a/platform/ios/tts_ios.h +++ b/platform/ios/tts_ios.h @@ -38,8 +38,8 @@ #endif #include "core/string/ustring.h" +#include "core/templates/hash_map.h" #include "core/templates/list.h" -#include "core/templates/rb_map.h" #include "core/variant/array.h" #include "servers/display_server.h" diff --git a/platform/linuxbsd/tts_linux.h b/platform/linuxbsd/tts_linux.h index 4134f8fa2f..651a64d9d6 100644 --- a/platform/linuxbsd/tts_linux.h +++ b/platform/linuxbsd/tts_linux.h @@ -34,8 +34,8 @@ #include "core/os/thread.h" #include "core/os/thread_safe.h" #include "core/string/ustring.h" +#include "core/templates/hash_map.h" #include "core/templates/list.h" -#include "core/templates/rb_map.h" #include "core/variant/array.h" #include "servers/display_server.h" diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index 4c5d9552e6..0972bf700e 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -2654,16 +2654,12 @@ void DisplayServerX11::cursor_set_custom_image(const Ref<Resource> &p_cursor, Cu } Ref<Texture2D> texture = p_cursor; + ERR_FAIL_COND(!texture.is_valid()); Ref<AtlasTexture> atlas_texture = p_cursor; - Ref<Image> image; Size2i texture_size; Rect2i atlas_rect; - if (texture.is_valid()) { - image = texture->get_image(); - } - - if (!image.is_valid() && atlas_texture.is_valid()) { + if (atlas_texture.is_valid()) { texture = atlas_texture->get_atlas(); atlas_rect.size.width = texture->get_width(); @@ -2673,17 +2669,16 @@ void DisplayServerX11::cursor_set_custom_image(const Ref<Resource> &p_cursor, Cu texture_size.width = atlas_texture->get_region().size.x; texture_size.height = atlas_texture->get_region().size.y; - } else if (image.is_valid()) { + } else { texture_size.width = texture->get_width(); texture_size.height = texture->get_height(); } - ERR_FAIL_COND(!texture.is_valid()); ERR_FAIL_COND(p_hotspot.x < 0 || p_hotspot.y < 0); ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256); ERR_FAIL_COND(p_hotspot.x > texture_size.width || p_hotspot.y > texture_size.height); - image = texture->get_image(); + Ref<Image> image = texture->get_image(); ERR_FAIL_COND(!image.is_valid()); diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index 9ef1446ea3..ac3a861d84 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -3328,16 +3328,12 @@ void DisplayServerMacOS::cursor_set_custom_image(const Ref<Resource> &p_cursor, } Ref<Texture2D> texture = p_cursor; + ERR_FAIL_COND(!texture.is_valid()); Ref<AtlasTexture> atlas_texture = p_cursor; - Ref<Image> image; Size2 texture_size; Rect2 atlas_rect; - if (texture.is_valid()) { - image = texture->get_image(); - } - - if (!image.is_valid() && atlas_texture.is_valid()) { + if (atlas_texture.is_valid()) { texture = atlas_texture->get_atlas(); atlas_rect.size.width = texture->get_width(); @@ -3347,17 +3343,16 @@ void DisplayServerMacOS::cursor_set_custom_image(const Ref<Resource> &p_cursor, texture_size.width = atlas_texture->get_region().size.x; texture_size.height = atlas_texture->get_region().size.y; - } else if (image.is_valid()) { + } else { texture_size.width = texture->get_width(); texture_size.height = texture->get_height(); } - ERR_FAIL_COND(!texture.is_valid()); ERR_FAIL_COND(p_hotspot.x < 0 || p_hotspot.y < 0); ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256); ERR_FAIL_COND(p_hotspot.x > texture_size.width || p_hotspot.y > texture_size.height); - image = texture->get_image(); + Ref<Image> image = texture->get_image(); ERR_FAIL_COND(!image.is_valid()); diff --git a/platform/macos/export/export_plugin.cpp b/platform/macos/export/export_plugin.cpp index 5a097adf39..ab76d9b273 100644 --- a/platform/macos/export/export_plugin.cpp +++ b/platform/macos/export/export_plugin.cpp @@ -768,7 +768,7 @@ Error EditorExportPlatformMacOS::_code_sign(const Ref<EditorExportPreset> &p_pre String certificate_file = p_preset->get("codesign/certificate_file"); String certificate_pass = p_preset->get("codesign/certificate_password"); - if (!certificate_file.is_empty() && !certificate_file.is_empty()) { + if (!certificate_file.is_empty() && !certificate_pass.is_empty()) { args.push_back("--p12-file"); args.push_back(certificate_file); args.push_back("--p12-password"); diff --git a/platform/macos/tts_macos.h b/platform/macos/tts_macos.h index 2153a4c692..35205bd1ae 100644 --- a/platform/macos/tts_macos.h +++ b/platform/macos/tts_macos.h @@ -32,8 +32,8 @@ #define TTS_MACOS_H #include "core/string/ustring.h" +#include "core/templates/hash_map.h" #include "core/templates/list.h" -#include "core/templates/rb_map.h" #include "core/variant/array.h" #include "servers/display_server.h" diff --git a/platform/web/display_server_web.cpp b/platform/web/display_server_web.cpp index 565d439a92..da55e8560a 100644 --- a/platform/web/display_server_web.cpp +++ b/platform/web/display_server_web.cpp @@ -398,16 +398,12 @@ void DisplayServerWeb::cursor_set_custom_image(const Ref<Resource> &p_cursor, Cu ERR_FAIL_INDEX(p_shape, CURSOR_MAX); if (p_cursor.is_valid()) { Ref<Texture2D> texture = p_cursor; + ERR_FAIL_COND(!texture.is_valid()); Ref<AtlasTexture> atlas_texture = p_cursor; - Ref<Image> image; Size2 texture_size; Rect2 atlas_rect; - if (texture.is_valid()) { - image = texture->get_image(); - } - - if (!image.is_valid() && atlas_texture.is_valid()) { + if (atlas_texture.is_valid()) { texture = atlas_texture->get_atlas(); atlas_rect.size.width = texture->get_width(); @@ -417,17 +413,16 @@ void DisplayServerWeb::cursor_set_custom_image(const Ref<Resource> &p_cursor, Cu texture_size.width = atlas_texture->get_region().size.x; texture_size.height = atlas_texture->get_region().size.y; - } else if (image.is_valid()) { + } else { texture_size.width = texture->get_width(); texture_size.height = texture->get_height(); } - ERR_FAIL_COND(!texture.is_valid()); ERR_FAIL_COND(p_hotspot.x < 0 || p_hotspot.y < 0); ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256); ERR_FAIL_COND(p_hotspot.x > texture_size.width || p_hotspot.y > texture_size.height); - image = texture->get_image(); + Ref<Image> image = texture->get_image(); ERR_FAIL_COND(!image.is_valid()); diff --git a/platform/web/dom_keys.inc b/platform/web/dom_keys.inc index ae3b2fc1a5..cd94b779c0 100644 --- a/platform/web/dom_keys.inc +++ b/platform/web/dom_keys.inc @@ -33,7 +33,7 @@ // See https://w3c.github.io/uievents-code/#code-value-tables Key dom_code2godot_scancode(EM_UTF8 const p_code[32], EM_UTF8 const p_key[32], bool p_physical) { #define DOM2GODOT(p_str, p_godot_code) \ - if (memcmp((const void *)p_str, (void *)(p_physical ? p_key : p_code), strlen(p_str) + 1) == 0) { \ + if (memcmp((const void *)p_str, (void *)(p_physical ? p_code : p_key), strlen(p_str) + 1) == 0) { \ return Key::p_godot_code; \ } diff --git a/platform/web/godot_js.h b/platform/web/godot_js.h index 3a41f63fa3..660822e291 100644 --- a/platform/web/godot_js.h +++ b/platform/web/godot_js.h @@ -49,6 +49,7 @@ extern void godot_js_os_fs_sync(void (*p_callback)()); extern int godot_js_os_execute(const char *p_json); extern void godot_js_os_shell_open(const char *p_uri); extern int godot_js_os_hw_concurrency_get(); +extern int godot_js_os_has_feature(const char *p_ftr); extern int godot_js_pwa_cb(void (*p_callback)()); extern int godot_js_pwa_update(); diff --git a/platform/web/js/libs/library_godot_os.js b/platform/web/js/libs/library_godot_os.js index c4c45a3036..00ae399583 100644 --- a/platform/web/js/libs/library_godot_os.js +++ b/platform/web/js/libs/library_godot_os.js @@ -291,6 +291,28 @@ const GodotOS = { }); }, + godot_js_os_has_feature__sig: 'ii', + godot_js_os_has_feature: function (p_ftr) { + const ftr = GodotRuntime.parseString(p_ftr); + const ua = navigator.userAgent; + if (ftr === 'web_macos') { + return (ua.indexOf('Mac') !== -1) ? 1 : 0; + } + if (ftr === 'web_windows') { + return (ua.indexOf('Windows') !== -1) ? 1 : 0; + } + if (ftr === 'web_android') { + return (ua.indexOf('Android') !== -1) ? 1 : 0; + } + if (ftr === 'web_ios') { + return ((ua.indexOf('iPhone') !== -1) || (ua.indexOf('iPad') !== -1) || (ua.indexOf('iPod') !== -1)) ? 1 : 0; + } + if (ftr === 'web_linuxbsd') { + return ((ua.indexOf('CrOS') !== -1) || (ua.indexOf('BSD') !== -1) || (ua.indexOf('Linux') !== -1) || (ua.indexOf('X11') !== -1)) ? 1 : 0; + } + return 0; + }, + godot_js_os_execute__sig: 'ii', godot_js_os_execute: function (p_json) { const json_args = GodotRuntime.parseString(p_json); diff --git a/platform/web/os_web.cpp b/platform/web/os_web.cpp index 964bce01da..0f84e7e841 100644 --- a/platform/web/os_web.cpp +++ b/platform/web/os_web.cpp @@ -136,6 +136,9 @@ bool OS_Web::_check_internal_feature_support(const String &p_feature) { if (p_feature == "web") { return true; } + if (godot_js_os_has_feature(p_feature.utf8().get_data())) { + return true; + } return false; } diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 388a799c1c..6ff928580a 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -1755,36 +1755,30 @@ void DisplayServerWindows::cursor_set_custom_image(const Ref<Resource> &p_cursor } Ref<Texture2D> texture = p_cursor; + ERR_FAIL_COND(!texture.is_valid()); Ref<AtlasTexture> atlas_texture = p_cursor; - Ref<Image> image; Size2 texture_size; Rect2 atlas_rect; - if (texture.is_valid()) { - image = texture->get_image(); - } - - if (!image.is_valid() && atlas_texture.is_valid()) { + if (atlas_texture.is_valid()) { texture = atlas_texture->get_atlas(); atlas_rect.size.width = texture->get_width(); atlas_rect.size.height = texture->get_height(); atlas_rect.position.x = atlas_texture->get_region().position.x; atlas_rect.position.y = atlas_texture->get_region().position.y; - texture_size.width = atlas_texture->get_region().size.x; texture_size.height = atlas_texture->get_region().size.y; - } else if (image.is_valid()) { + } else { texture_size.width = texture->get_width(); texture_size.height = texture->get_height(); } - ERR_FAIL_COND(!texture.is_valid()); ERR_FAIL_COND(p_hotspot.x < 0 || p_hotspot.y < 0); ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256); ERR_FAIL_COND(p_hotspot.x > texture_size.width || p_hotspot.y > texture_size.height); - image = texture->get_image(); + Ref<Image> image = texture->get_image(); ERR_FAIL_COND(!image.is_valid()); diff --git a/platform/windows/tts_windows.cpp b/platform/windows/tts_windows.cpp index 3a143d0ecb..54ab93ee01 100644 --- a/platform/windows/tts_windows.cpp +++ b/platform/windows/tts_windows.cpp @@ -36,15 +36,16 @@ void __stdcall TTS_Windows::speech_event_callback(WPARAM wParam, LPARAM lParam) TTS_Windows *tts = TTS_Windows::get_singleton(); SPEVENT event; while (tts->synth->GetEvents(1, &event, NULL) == S_OK) { - if (tts->ids.has(event.ulStreamNum)) { + uint32_t stream_num = (uint32_t)event.ulStreamNum; + if (tts->ids.has(stream_num)) { if (event.eEventId == SPEI_START_INPUT_STREAM) { - DisplayServer::get_singleton()->tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_STARTED, tts->ids[event.ulStreamNum].id); + DisplayServer::get_singleton()->tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_STARTED, tts->ids[stream_num].id); } else if (event.eEventId == SPEI_END_INPUT_STREAM) { - DisplayServer::get_singleton()->tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_ENDED, tts->ids[event.ulStreamNum].id); - tts->ids.erase(event.ulStreamNum); + DisplayServer::get_singleton()->tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_ENDED, tts->ids[stream_num].id); + tts->ids.erase(stream_num); tts->_update_tts(); } else if (event.eEventId == SPEI_WORD_BOUNDARY) { - const Char16String &string = tts->ids[event.ulStreamNum].string; + const Char16String &string = tts->ids[stream_num].string; int pos = 0; for (int i = 0; i < MIN(event.lParam, string.length()); i++) { char16_t c = string[i]; @@ -53,7 +54,7 @@ void __stdcall TTS_Windows::speech_event_callback(WPARAM wParam, LPARAM lParam) } pos++; } - DisplayServer::get_singleton()->tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_BOUNDARY, tts->ids[event.ulStreamNum].id, pos - tts->ids[event.ulStreamNum].offset); + DisplayServer::get_singleton()->tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_BOUNDARY, tts->ids[stream_num].id, pos - tts->ids[stream_num].offset); } } } @@ -106,7 +107,7 @@ void TTS_Windows::_update_tts() { synth->SetRate(10.f * log10(message.rate) / log10(3.f)); synth->Speak((LPCWSTR)ut.string.get_data(), flags, &stream_number); - ids[stream_number] = ut; + ids[(uint32_t)stream_number] = ut; queue.pop_front(); } @@ -230,9 +231,10 @@ void TTS_Windows::stop() { SPVOICESTATUS status; synth->GetStatus(&status, nullptr); - if (ids.has(status.ulCurrentStream)) { - DisplayServer::get_singleton()->tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_CANCELED, ids[status.ulCurrentStream].id); - ids.erase(status.ulCurrentStream); + uint32_t current_stream = (uint32_t)status.ulCurrentStream; + if (ids.has(current_stream)) { + DisplayServer::get_singleton()->tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_CANCELED, ids[current_stream].id); + ids.erase(current_stream); } for (DisplayServer::TTSUtterance &message : queue) { DisplayServer::get_singleton()->tts_post_utterance_event(DisplayServer::TTS_UTTERANCE_CANCELED, message.id); diff --git a/platform/windows/tts_windows.h b/platform/windows/tts_windows.h index f0538a097c..33b597c612 100644 --- a/platform/windows/tts_windows.h +++ b/platform/windows/tts_windows.h @@ -32,8 +32,8 @@ #define TTS_WINDOWS_H #include "core/string/ustring.h" +#include "core/templates/hash_map.h" #include "core/templates/list.h" -#include "core/templates/rb_map.h" #include "core/variant/array.h" #include "servers/display_server.h" @@ -54,7 +54,7 @@ class TTS_Windows { int offset; int id; }; - RBMap<ULONG, UTData> ids; + HashMap<uint32_t, UTData> ids; static void __stdcall speech_event_callback(WPARAM wParam, LPARAM lParam); void _update_tts(); diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp index c175edb6cb..466ffad951 100644 --- a/scene/2d/audio_stream_player_2d.cpp +++ b/scene/2d/audio_stream_player_2d.cpp @@ -68,7 +68,8 @@ void AudioStreamPlayer2D::_notification(int p_what) { case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { // Update anything related to position first, if possible of course. - if (setplay.get() > 0 || (active.is_set() && last_mix_count != AudioServer::get_singleton()->get_mix_count())) { + if (setplay.get() > 0 || (active.is_set() && last_mix_count != AudioServer::get_singleton()->get_mix_count()) || force_update_panning) { + force_update_panning = false; _update_panning(); } @@ -109,6 +110,7 @@ void AudioStreamPlayer2D::_notification(int p_what) { } } +// Interacts with PhysicsServer2D, so can only be called during _physics_process StringName AudioStreamPlayer2D::_get_actual_bus() { Vector2 global_pos = get_global_position(); @@ -117,6 +119,7 @@ StringName AudioStreamPlayer2D::_get_actual_bus() { ERR_FAIL_COND_V(world_2d.is_null(), SNAME("Master")); PhysicsDirectSpaceState2D *space_state = PhysicsServer2D::get_singleton()->space_get_direct_state(world_2d->get_space()); + ERR_FAIL_COND_V(space_state == nullptr, SNAME("Master")); PhysicsDirectSpaceState2D::ShapeResult sr[MAX_INTERSECT_AREAS]; PhysicsDirectSpaceState2D::PointParameters point_params; @@ -142,6 +145,7 @@ StringName AudioStreamPlayer2D::_get_actual_bus() { return default_bus; } +// Interacts with PhysicsServer2D, so can only be called during _physics_process void AudioStreamPlayer2D::_update_panning() { if (!active.is_set() || stream.is_null()) { return; diff --git a/scene/2d/audio_stream_player_2d.h b/scene/2d/audio_stream_player_2d.h index 79a026fed2..9b23fd3943 100644 --- a/scene/2d/audio_stream_player_2d.h +++ b/scene/2d/audio_stream_player_2d.h @@ -61,6 +61,7 @@ private: Vector<AudioFrame> volume_vector; uint64_t last_mix_count = -1; + bool force_update_panning = false; float volume_db = 0.0; float pitch_scale = 1.0; @@ -75,7 +76,7 @@ private: void _update_panning(); void _bus_layout_changed(); - static void _listener_changed_cb(void *self) { reinterpret_cast<AudioStreamPlayer2D *>(self)->_update_panning(); } + static void _listener_changed_cb(void *self) { reinterpret_cast<AudioStreamPlayer2D *>(self)->force_update_panning = true; } uint32_t area_mask = 1; diff --git a/scene/2d/navigation_obstacle_2d.cpp b/scene/2d/navigation_obstacle_2d.cpp index d7ef77e25b..2366cb696e 100644 --- a/scene/2d/navigation_obstacle_2d.cpp +++ b/scene/2d/navigation_obstacle_2d.cpp @@ -196,13 +196,20 @@ void NavigationObstacle2D::set_agent_parent(Node *p_agent_parent) { } else { NavigationServer2D::get_singleton()->agent_set_map(get_rid(), parent_node2d->get_world_2d()->get_navigation_map()); } + // Need to register Callback as obstacle requires a valid Callback to be added to avoidance simulation. + NavigationServer2D::get_singleton()->agent_set_callback(get_rid(), callable_mp(this, &NavigationObstacle2D::_avoidance_done)); reevaluate_agent_radius(); } else { parent_node2d = nullptr; NavigationServer2D::get_singleton()->agent_set_map(get_rid(), RID()); + NavigationServer2D::get_singleton()->agent_set_callback(agent, Callable()); } } +void NavigationObstacle2D::_avoidance_done(Vector3 p_new_velocity) { + // Dummy function as obstacle requires a valid Callback to be added to avoidance simulation. +} + void NavigationObstacle2D::set_navigation_map(RID p_navigation_map) { if (map_override == p_navigation_map) { return; diff --git a/scene/2d/navigation_obstacle_2d.h b/scene/2d/navigation_obstacle_2d.h index 12ddcaf219..f856c481b0 100644 --- a/scene/2d/navigation_obstacle_2d.h +++ b/scene/2d/navigation_obstacle_2d.h @@ -75,6 +75,8 @@ public: PackedStringArray get_configuration_warnings() const override; + void _avoidance_done(Vector3 p_new_velocity); // Dummy + private: void initialize_agent(); void reevaluate_agent_radius(); diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index 1c0efe773f..43a2f62163 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -385,9 +385,14 @@ Point2 Node2D::to_global(Point2 p_local) const { void Node2D::_notification(int p_notification) { switch (p_notification) { - case NOTIFICATION_MOVED_IN_PARENT: { + case NOTIFICATION_ENTER_TREE: { if (get_viewport()) { - get_viewport()->gui_set_root_order_dirty(); + get_parent()->connect(SNAME("child_order_changed"), callable_mp(get_viewport(), &Viewport::gui_set_root_order_dirty), CONNECT_REFERENCE_COUNTED); + } + } break; + case NOTIFICATION_EXIT_TREE: { + if (get_viewport()) { + get_parent()->disconnect(SNAME("child_order_changed"), callable_mp(get_viewport(), &Viewport::gui_set_root_order_dirty)); } } break; } diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp index 4fdc7b3584..f2270d2b18 100644 --- a/scene/2d/skeleton_2d.cpp +++ b/scene/2d/skeleton_2d.cpp @@ -115,6 +115,7 @@ void Bone2D::_notification(int p_what) { bone.bone = this; skeleton->bones.push_back(bone); skeleton->_make_bone_setup_dirty(); + get_parent()->connect(SNAME("child_order_changed"), callable_mp(skeleton, &Skeleton2D::_make_bone_setup_dirty), CONNECT_REFERENCE_COUNTED); } cache_transform = get_transform(); @@ -154,15 +155,6 @@ void Bone2D::_notification(int p_what) { #endif // TOOLS_ENABLED } break; - case NOTIFICATION_MOVED_IN_PARENT: { - if (skeleton) { - skeleton->_make_bone_setup_dirty(); - } - if (copy_transform_to_cache) { - cache_transform = get_transform(); - } - } break; - case NOTIFICATION_EXIT_TREE: { if (skeleton) { for (int i = 0; i < skeleton->bones.size(); i++) { @@ -172,7 +164,7 @@ void Bone2D::_notification(int p_what) { } } skeleton->_make_bone_setup_dirty(); - skeleton = nullptr; + get_parent()->disconnect(SNAME("child_order_changed"), callable_mp(skeleton, &Skeleton2D::_make_bone_setup_dirty)); } parent_bone = nullptr; set_transform(cache_transform); diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp index 86301ee53f..0f7db64f5c 100644 --- a/scene/3d/mesh_instance_3d.cpp +++ b/scene/3d/mesh_instance_3d.cpp @@ -284,12 +284,18 @@ void MeshInstance3D::create_convex_collision(bool p_clean, bool p_simplify) { } } -Node *MeshInstance3D::create_multiple_convex_collisions_node() { +Node *MeshInstance3D::create_multiple_convex_collisions_node(const Ref<MeshConvexDecompositionSettings> &p_settings) { if (mesh.is_null()) { return nullptr; } - Mesh::ConvexDecompositionSettings settings; + Ref<MeshConvexDecompositionSettings> settings; + if (p_settings.is_valid()) { + settings = p_settings; + } else { + settings.instantiate(); + } + Vector<Ref<Shape3D>> shapes = mesh->convex_decompose(settings); if (!shapes.size()) { return nullptr; @@ -304,8 +310,8 @@ Node *MeshInstance3D::create_multiple_convex_collisions_node() { return static_body; } -void MeshInstance3D::create_multiple_convex_collisions() { - StaticBody3D *static_body = Object::cast_to<StaticBody3D>(create_multiple_convex_collisions_node()); +void MeshInstance3D::create_multiple_convex_collisions(const Ref<MeshConvexDecompositionSettings> &p_settings) { + StaticBody3D *static_body = Object::cast_to<StaticBody3D>(create_multiple_convex_collisions_node(p_settings)); ERR_FAIL_COND(!static_body); static_body->set_name(String(get_name()) + "_col"); @@ -504,7 +510,7 @@ void MeshInstance3D::_bind_methods() { ClassDB::set_method_flags("MeshInstance3D", "create_trimesh_collision", METHOD_FLAGS_DEFAULT); ClassDB::bind_method(D_METHOD("create_convex_collision", "clean", "simplify"), &MeshInstance3D::create_convex_collision, DEFVAL(true), DEFVAL(false)); ClassDB::set_method_flags("MeshInstance3D", "create_convex_collision", METHOD_FLAGS_DEFAULT); - ClassDB::bind_method(D_METHOD("create_multiple_convex_collisions"), &MeshInstance3D::create_multiple_convex_collisions); + ClassDB::bind_method(D_METHOD("create_multiple_convex_collisions", "settings"), &MeshInstance3D::create_multiple_convex_collisions, DEFVAL(Ref<MeshConvexDecompositionSettings>())); ClassDB::set_method_flags("MeshInstance3D", "create_multiple_convex_collisions", METHOD_FLAGS_DEFAULT); ClassDB::bind_method(D_METHOD("get_blend_shape_count"), &MeshInstance3D::get_blend_shape_count); diff --git a/scene/3d/mesh_instance_3d.h b/scene/3d/mesh_instance_3d.h index 4a6d7dd95d..0a7ffa0bee 100644 --- a/scene/3d/mesh_instance_3d.h +++ b/scene/3d/mesh_instance_3d.h @@ -88,8 +88,8 @@ public: Node *create_convex_collision_node(bool p_clean = true, bool p_simplify = false); void create_convex_collision(bool p_clean = true, bool p_simplify = false); - Node *create_multiple_convex_collisions_node(); - void create_multiple_convex_collisions(); + Node *create_multiple_convex_collisions_node(const Ref<MeshConvexDecompositionSettings> &p_settings = Ref<MeshConvexDecompositionSettings>()); + void create_multiple_convex_collisions(const Ref<MeshConvexDecompositionSettings> &p_settings = Ref<MeshConvexDecompositionSettings>()); MeshInstance3D *create_debug_tangents_node(); void create_debug_tangents(); diff --git a/scene/3d/navigation_obstacle_3d.cpp b/scene/3d/navigation_obstacle_3d.cpp index 85b3c164cc..14d93fb0e0 100644 --- a/scene/3d/navigation_obstacle_3d.cpp +++ b/scene/3d/navigation_obstacle_3d.cpp @@ -203,13 +203,20 @@ void NavigationObstacle3D::set_agent_parent(Node *p_agent_parent) { } else { NavigationServer3D::get_singleton()->agent_set_map(get_rid(), parent_node3d->get_world_3d()->get_navigation_map()); } + // Need to register Callback as obstacle requires a valid Callback to be added to avoidance simulation. + NavigationServer3D::get_singleton()->agent_set_callback(get_rid(), callable_mp(this, &NavigationObstacle3D::_avoidance_done)); reevaluate_agent_radius(); } else { parent_node3d = nullptr; NavigationServer3D::get_singleton()->agent_set_map(get_rid(), RID()); + NavigationServer3D::get_singleton()->agent_set_callback(agent, Callable()); } } +void NavigationObstacle3D::_avoidance_done(Vector3 p_new_velocity) { + // Dummy function as obstacle requires a valid Callback to be added to avoidance simulation. +} + void NavigationObstacle3D::set_navigation_map(RID p_navigation_map) { if (map_override == p_navigation_map) { return; diff --git a/scene/3d/navigation_obstacle_3d.h b/scene/3d/navigation_obstacle_3d.h index 416b32c026..c5a9d737f6 100644 --- a/scene/3d/navigation_obstacle_3d.h +++ b/scene/3d/navigation_obstacle_3d.h @@ -74,6 +74,8 @@ public: PackedStringArray get_configuration_warnings() const override; + void _avoidance_done(Vector3 p_new_velocity); // Dummy + private: void initialize_agent(); void reevaluate_agent_radius(); diff --git a/scene/animation/animation_blend_space_1d.cpp b/scene/animation/animation_blend_space_1d.cpp index 0e9e02f247..1467939426 100644 --- a/scene/animation/animation_blend_space_1d.cpp +++ b/scene/animation/animation_blend_space_1d.cpp @@ -288,8 +288,6 @@ double AnimationNodeBlendSpace1D::process(double p_time, bool p_seek, bool p_is_ double max_time_remaining = 0.0; if (blend_mode == BLEND_MODE_INTERPOLATED) { - float weights[MAX_BLEND_POINTS] = {}; - int point_lower = -1; float pos_lower = 0.0; int point_higher = -1; @@ -300,26 +298,18 @@ double AnimationNodeBlendSpace1D::process(double p_time, bool p_seek, bool p_is_ float pos = blend_points[i].position; if (pos <= blend_pos) { - if (point_lower == -1) { - point_lower = i; - pos_lower = pos; - } else if ((blend_pos - pos) < (blend_pos - pos_lower)) { + if (point_lower == -1 || pos > pos_lower) { point_lower = i; pos_lower = pos; } - } else { - if (point_higher == -1) { - point_higher = i; - pos_higher = pos; - } else if ((pos - blend_pos) < (pos_higher - blend_pos)) { - point_higher = i; - pos_higher = pos; - } + } else if (point_higher == -1 || pos < pos_higher) { + point_higher = i; + pos_higher = pos; } } // fill in weights - + float weights[MAX_BLEND_POINTS] = {}; if (point_lower == -1 && point_higher != -1) { // we are on the left side, no other point to the left // we just play the next point. diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp index 60fe0c32b6..443f633969 100644 --- a/scene/gui/code_edit.cpp +++ b/scene/gui/code_edit.cpp @@ -451,11 +451,8 @@ void CodeEdit::gui_input(const Ref<InputEvent> &p_gui_input) { } /* Ctrl + Hover symbols */ -#ifdef MACOS_ENABLED - if (k->get_keycode() == Key::META) { -#else - if (k->get_keycode() == Key::CTRL) { -#endif + bool mac_keys = OS::get_singleton()->has_feature("macos") || OS::get_singleton()->has_feature("web_macos") || OS::get_singleton()->has_feature("web_ios"); + if ((mac_keys && k->get_keycode() == Key::META) || (!mac_keys && k->get_keycode() == Key::CTRL)) { if (symbol_lookup_on_click_enabled) { if (k->is_pressed() && !is_dragging_cursor()) { symbol_lookup_new_word = get_word_at_pos(get_local_mouse_pos()); @@ -2002,7 +1999,7 @@ void CodeEdit::confirm_code_completion(bool p_replace) { return; } - char32_t caret_last_completion_char; + char32_t caret_last_completion_char = 0; begin_complex_operation(); Vector<int> caret_edit_order = get_caret_index_edit_order(); for (const int &i : caret_edit_order) { diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 23b5bb2c7b..7f9095c2a2 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -543,8 +543,9 @@ void ColorPicker::_html_submitted(const String &p_html) { return; } - Color previous_color = color; - color = Color::html(p_html); + const Color previous_color = color; + color = Color::from_string(p_html, previous_color); + if (!is_editing_alpha()) { color.a = previous_color.a; } @@ -644,13 +645,13 @@ void ColorPicker::_text_type_toggled() { text_type->set_icon(get_theme_icon(SNAME("Script"), SNAME("EditorIcons"))); c_text->set_editable(false); - c_text->set_h_size_flags(SIZE_EXPAND_FILL); + c_text->set_tooltip_text(RTR("Copy this constructor in a script.")); } else { text_type->set_text("#"); text_type->set_icon(nullptr); c_text->set_editable(true); - c_text->set_h_size_flags(SIZE_FILL); + c_text->set_tooltip_text(RTR("Enter a hex code (\"#ff0000\") or named color (\"red\").")); } _update_color(); } @@ -1793,7 +1794,10 @@ ColorPicker::ColorPicker() { c_text = memnew(LineEdit); hex_hbc->add_child(c_text); + c_text->set_h_size_flags(SIZE_EXPAND_FILL); c_text->set_select_all_on_focus(true); + c_text->set_tooltip_text(RTR("Enter a hex code (\"#ff0000\") or named color (\"red\").")); + c_text->set_placeholder(RTR("Hex code or named color")); c_text->connect("text_submitted", callable_mp(this, &ColorPicker::_html_submitted)); c_text->connect("text_changed", callable_mp(this, &ColorPicker::_text_changed)); c_text->connect("focus_exited", callable_mp(this, &ColorPicker::_html_focus_exit)); diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 569b89f688..8957a9492e 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -3021,6 +3021,8 @@ void Control::_notification(int p_notification) { Viewport *viewport = get_viewport(); ERR_FAIL_COND(!viewport); data.RI = viewport->_gui_add_root_control(this); + + get_parent()->connect(SNAME("child_order_changed"), callable_mp(get_viewport(), &Viewport::gui_set_root_order_dirty), CONNECT_REFERENCE_COUNTED); } data.parent_canvas_item = get_parent_item(); @@ -3049,24 +3051,17 @@ void Control::_notification(int p_notification) { if (data.RI) { get_viewport()->_gui_remove_root_control(data.RI); data.RI = nullptr; + get_parent()->disconnect(SNAME("child_order_changed"), callable_mp(get_viewport(), &Viewport::gui_set_root_order_dirty)); } data.parent_canvas_item = nullptr; data.is_rtl_dirty = true; } break; - case NOTIFICATION_MOVED_IN_PARENT: { + case NOTIFICATION_CHILD_ORDER_CHANGED: { // Some parents need to know the order of the children to draw (like TabContainer), // so we update them just in case. - Control *parent_control = get_parent_control(); - if (parent_control) { - parent_control->queue_redraw(); - } queue_redraw(); - - if (data.RI) { - get_viewport()->gui_set_root_order_dirty(); - } } break; case NOTIFICATION_RESIZED: { diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 4e24c9ba06..1ae24b6d70 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -34,6 +34,7 @@ #include "core/math/math_defs.h" #include "core/os/keyboard.h" #include "core/os/os.h" +#include "core/string/translation.h" #include "label.h" #include "scene/scene_string_names.h" #include "servers/display_server.h" @@ -1469,7 +1470,16 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V } } break; } - + // Adjust for dropcap. + int dc_lines = l.text_buf->get_dropcap_lines(); + float h_off = l.text_buf->get_dropcap_size().x; + if (line <= dc_lines) { + if (rtl) { + off.x -= h_off; + } else { + off.x += h_off; + } + } off.y += TS->shaped_text_get_ascent(rid); Array objects = TS->shaped_text_get_objects(rid); @@ -1509,7 +1519,7 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V } if (crect.has_point(p_click)) { for (int j = 0; j < (int)frame->lines.size(); j++) { - _find_click_in_line(frame, j, rect.position + Vector2(0, frame->lines[j].offset.y), rect.size.x, p_click, &table_click_frame, &table_click_line, &table_click_item, &table_click_char, true, p_meta); + _find_click_in_line(frame, j, rect.position + Vector2(frame->padding.position.x, frame->lines[j].offset.y), rect.size.x, p_click, &table_click_frame, &table_click_line, &table_click_item, &table_click_char, true, p_meta); if (table_click_frame && table_click_item) { // Save cell detected cell hit data. table_range = Vector2i(INT32_MAX, 0); @@ -1790,8 +1800,7 @@ void RichTextLabel::_notification(int p_what) { case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: case NOTIFICATION_TRANSLATION_CHANGED: { - _stop_thread(); - main->first_invalid_line.store(0); //invalidate ALL + _apply_translation(); queue_redraw(); } break; @@ -5114,13 +5123,17 @@ void RichTextLabel::set_text(const String &p_bbcode) { if (text == p_bbcode) { return; } - text = p_bbcode; + _apply_translation(); +} + +void RichTextLabel::_apply_translation() { + String xl_text = atr(text); if (use_bbcode) { - parse_bbcode(p_bbcode); + parse_bbcode(xl_text); } else { // raw text clear(); - add_text(p_bbcode); + add_text(xl_text); } } @@ -5135,13 +5148,7 @@ void RichTextLabel::set_use_bbcode(bool p_enable) { use_bbcode = p_enable; notify_property_list_changed(); - const String current_text = text; - if (use_bbcode) { - parse_bbcode(current_text); - } else { // raw text - clear(); - add_text(current_text); - } + _apply_translation(); } bool RichTextLabel::is_using_bbcode() const { @@ -5276,7 +5283,7 @@ float RichTextLabel::get_visible_ratio() const { void RichTextLabel::set_effects(Array p_effects) { custom_effects = p_effects; if ((!text.is_empty()) && use_bbcode) { - parse_bbcode(text); + parse_bbcode(atr(text)); } } @@ -5291,7 +5298,7 @@ void RichTextLabel::install_effect(const Variant effect) { ERR_FAIL_COND_MSG(rteffect.is_null(), "Invalid RichTextEffect resource."); custom_effects.push_back(effect); if ((!text.is_empty()) && use_bbcode) { - parse_bbcode(text); + parse_bbcode(atr(text)); } } diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index e3f1e11e71..fef34f7260 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -527,6 +527,7 @@ private: #endif bool use_bbcode = false; String text; + void _apply_translation(); bool fit_content = false; diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 02dbb086ee..0839e4066d 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -526,7 +526,7 @@ void TextEdit::_notification(int p_what) { theme_cache.style_normal->draw(ci, Rect2(Point2(), size)); if (!editable) { theme_cache.style_readonly->draw(ci, Rect2(Point2(), size)); - draw_caret = false; + draw_caret = is_drawing_caret_when_editable_disabled(); } if (has_focus()) { theme_cache.style_focus->draw(ci, Rect2(Point2(), size)); @@ -4489,6 +4489,18 @@ void TextEdit::set_caret_blink_interval(const float p_interval) { caret_blink_timer->set_wait_time(p_interval); } +void TextEdit::set_draw_caret_when_editable_disabled(bool p_enable) { + if (draw_caret_when_editable_disabled == p_enable) { + return; + } + draw_caret_when_editable_disabled = p_enable; + queue_redraw(); +} + +bool TextEdit::is_drawing_caret_when_editable_disabled() const { + return draw_caret_when_editable_disabled; +} + void TextEdit::set_move_caret_on_right_click_enabled(const bool p_enabled) { move_caret_on_right_click = p_enabled; } @@ -6195,6 +6207,9 @@ void TextEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("set_caret_blink_interval", "interval"), &TextEdit::set_caret_blink_interval); ClassDB::bind_method(D_METHOD("get_caret_blink_interval"), &TextEdit::get_caret_blink_interval); + ClassDB::bind_method(D_METHOD("set_draw_caret_when_editable_disabled", "enable"), &TextEdit::set_draw_caret_when_editable_disabled); + ClassDB::bind_method(D_METHOD("is_drawing_caret_when_editable_disabled"), &TextEdit::is_drawing_caret_when_editable_disabled); + ClassDB::bind_method(D_METHOD("set_move_caret_on_right_click_enabled", "enable"), &TextEdit::set_move_caret_on_right_click_enabled); ClassDB::bind_method(D_METHOD("is_move_caret_on_right_click_enabled"), &TextEdit::is_move_caret_on_right_click_enabled); @@ -6436,6 +6451,7 @@ void TextEdit::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "caret_type", PROPERTY_HINT_ENUM, "Line,Block"), "set_caret_type", "get_caret_type"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_blink"), "set_caret_blink_enabled", "is_caret_blink_enabled"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "caret_blink_interval", PROPERTY_HINT_RANGE, "0.1,10,0.01,suffix:s"), "set_caret_blink_interval", "get_caret_blink_interval"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_draw_when_editable_disabled"), "set_draw_caret_when_editable_disabled", "is_drawing_caret_when_editable_disabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_move_on_right_click"), "set_move_caret_on_right_click_enabled", "is_move_caret_on_right_click_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_mid_grapheme"), "set_caret_mid_grapheme_enabled", "is_caret_mid_grapheme_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_multiple"), "set_multiple_carets_enabled", "is_multiple_carets_enabled"); diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index 6b710ae26f..6eed200a28 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -413,6 +413,7 @@ private: CaretType caret_type = CaretType::CARET_TYPE_LINE; bool draw_caret = true; + bool draw_caret_when_editable_disabled = false; bool caret_blink_enabled = false; Timer *caret_blink_timer = nullptr; @@ -821,6 +822,9 @@ public: void set_caret_blink_interval(const float p_interval); float get_caret_blink_interval() const; + void set_draw_caret_when_editable_disabled(bool p_enable); + bool is_drawing_caret_when_editable_disabled() const; + void set_move_caret_on_right_click_enabled(const bool p_enabled); bool is_move_caret_on_right_click_enabled() const; diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 738f0033d8..e71c236dc7 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -1644,6 +1644,13 @@ void Tree::_update_theme_item_cache() { theme_cache.scroll_border = get_theme_constant(SNAME("scroll_border")); theme_cache.scroll_speed = get_theme_constant(SNAME("scroll_speed")); + theme_cache.scrollbar_margin_top = get_theme_constant(SNAME("scrollbar_margin_top")); + theme_cache.scrollbar_margin_right = get_theme_constant(SNAME("scrollbar_margin_right")); + theme_cache.scrollbar_margin_bottom = get_theme_constant(SNAME("scrollbar_margin_bottom")); + theme_cache.scrollbar_margin_left = get_theme_constant(SNAME("scrollbar_margin_left")); + theme_cache.scrollbar_h_separation = get_theme_constant(SNAME("scrollbar_h_separation")); + theme_cache.scrollbar_v_separation = get_theme_constant(SNAME("scrollbar_v_separation")); + theme_cache.title_button = get_theme_stylebox(SNAME("title_button_normal")); theme_cache.title_button_pressed = get_theme_stylebox(SNAME("title_button_pressed")); theme_cache.title_button_hover = get_theme_stylebox(SNAME("title_button_hover")); @@ -1936,72 +1943,54 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 continue; } - int w = get_column_width(i); + int item_width = get_column_width(i); if (i == 0) { - w -= ofs; + item_width -= ofs; - if (w <= 0) { + if (item_width <= 0) { ofs = get_column_width(0); continue; } } else { ofs += theme_cache.h_separation; - w -= theme_cache.h_separation; + item_width -= theme_cache.h_separation; } if (p_item->cells[i].expand_right) { int plus = 1; while (i + plus < columns.size() && !p_item->cells[i + plus].editable && p_item->cells[i + plus].mode == TreeItem::CELL_MODE_STRING && p_item->cells[i + plus].text.is_empty() && p_item->cells[i + plus].icon.is_null()) { - w += get_column_width(i + plus); + item_width += get_column_width(i + plus); plus++; skip2++; } } if (!rtl && p_item->cells[i].buttons.size()) { - int button_w = 0; + int buttons_width = 0; for (int j = p_item->cells[i].buttons.size() - 1; j >= 0; j--) { - Ref<Texture2D> b = p_item->cells[i].buttons[j].texture; - button_w += b->get_size().width + theme_cache.button_pressed->get_minimum_size().width + theme_cache.button_margin; + Ref<Texture2D> button_texture = p_item->cells[i].buttons[j].texture; + buttons_width += button_texture->get_size().width + theme_cache.button_pressed->get_minimum_size().width + theme_cache.button_margin; } int total_ofs = ofs - theme_cache.offset.x; - if (total_ofs + w > p_draw_size.width) { - w = MAX(button_w, p_draw_size.width - total_ofs); + if (total_ofs + item_width > p_draw_size.width) { + item_width = MAX(buttons_width, p_draw_size.width - total_ofs); } } - int bw = 0; + int item_width_with_buttons = item_width; // used later for drawing buttons + int buttons_width = 0; for (int j = p_item->cells[i].buttons.size() - 1; j >= 0; j--) { - Ref<Texture2D> b = p_item->cells[i].buttons[j].texture; - Size2 s = b->get_size() + theme_cache.button_pressed->get_minimum_size(); - - Point2i o = Point2i(ofs + w - s.width, p_pos.y) - theme_cache.offset + p_draw_ofs; + Ref<Texture2D> button_texture = p_item->cells[i].buttons[j].texture; + Size2 button_size = button_texture->get_size() + theme_cache.button_pressed->get_minimum_size(); - if (cache.click_type == Cache::CLICK_BUTTON && cache.click_item == p_item && cache.click_column == i && cache.click_index == j && !p_item->cells[i].buttons[j].disabled) { - // Being pressed. - Point2 od = o; - if (rtl) { - od.x = get_size().width - od.x - s.x; - } - theme_cache.button_pressed->draw(get_canvas_item(), Rect2(od.x, od.y, s.width, MAX(s.height, label_h))); - } - - o.y += (label_h - s.height) / 2; - o += theme_cache.button_pressed->get_offset(); - - if (rtl) { - o.x = get_size().width - o.x - b->get_width(); - } - - b->draw(ci, o, p_item->cells[i].buttons[j].disabled ? Color(1, 1, 1, 0.5) : p_item->cells[i].buttons[j].color); - w -= s.width + theme_cache.button_margin; - bw += s.width + theme_cache.button_margin; + item_width -= button_size.width + theme_cache.button_margin; + buttons_width += button_size.width + theme_cache.button_margin; } - Rect2i item_rect = Rect2i(Point2i(ofs, p_pos.y) - theme_cache.offset + p_draw_ofs, Size2i(w, label_h)); + Rect2i item_rect = Rect2i(Point2i(ofs, p_pos.y) - theme_cache.offset + p_draw_ofs, Size2i(item_width, label_h)); Rect2i cell_rect = item_rect; if (i != 0) { cell_rect.position.x -= theme_cache.h_separation; @@ -2018,9 +2007,8 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 if (i == 0) { if (p_item->cells[0].selected && select_mode == SELECT_ROW) { - Rect2i row_rect = Rect2i(Point2i(theme_cache.panel_style->get_margin(SIDE_LEFT), item_rect.position.y), Size2i(get_size().width - theme_cache.panel_style->get_minimum_size().width, item_rect.size.y)); - //Rect2 r = Rect2i(row_rect.pos,row_rect.size); - //r.grow(cache.selected->get_margin(SIDE_LEFT)); + const Rect2 content_rect = _get_content_rect(); + Rect2i row_rect = Rect2i(Point2i(content_rect.position.x, item_rect.position.y), Size2i(content_rect.size.x, item_rect.size.y)); if (rtl) { row_rect.position.x = get_size().width - row_rect.position.x - row_rect.size.x; } @@ -2055,7 +2043,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 Rect2 r = cell_rect; if (i == 0) { r.position.x = p_draw_ofs.x; - r.size.x = w + ofs; + r.size.x = item_width + ofs; } else { r.position.x -= theme_cache.h_separation; r.size.x += theme_cache.h_separation; @@ -2100,11 +2088,11 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 } } - Color col; + Color cell_color; if (p_item->cells[i].custom_color) { - col = p_item->cells[i].color; + cell_color = p_item->cells[i].color; } else { - col = p_item->cells[i].selected ? theme_cache.font_selected_color : theme_cache.font_color; + cell_color = p_item->cells[i].selected ? theme_cache.font_selected_color : theme_cache.font_color; } Color font_outline_color = theme_cache.font_outline_color; @@ -2125,7 +2113,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 switch (p_item->cells[i].mode) { case TreeItem::CELL_MODE_STRING: { - draw_item_rect(p_item->cells.write[i], item_rect, col, icon_col, outline_size, font_outline_color); + draw_item_rect(p_item->cells.write[i], item_rect, cell_color, icon_col, outline_size, font_outline_color); } break; case TreeItem::CELL_MODE_CHECK: { Ref<Texture2D> checked = theme_cache.checked; @@ -2149,7 +2137,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 item_rect.size.x -= check_w; item_rect.position.x += check_w; - draw_item_rect(p_item->cells.write[i], item_rect, col, icon_col, outline_size, font_outline_color); + draw_item_rect(p_item->cells.write[i], item_rect, cell_color, icon_col, outline_size, font_outline_color); } break; case TreeItem::CELL_MODE_RANGE: { @@ -2166,12 +2154,12 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 if (outline_size > 0 && font_outline_color.a > 0) { p_item->cells[i].text_buf->draw_outline(ci, text_pos + Vector2(cell_width - text_width, 0), outline_size, font_outline_color); } - p_item->cells[i].text_buf->draw(ci, text_pos + Vector2(cell_width - text_width, 0), col); + p_item->cells[i].text_buf->draw(ci, text_pos + Vector2(cell_width - text_width, 0), cell_color); } else { if (outline_size > 0 && font_outline_color.a > 0) { p_item->cells[i].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color); } - p_item->cells[i].text_buf->draw(ci, text_pos, col); + p_item->cells[i].text_buf->draw(ci, text_pos, cell_color); } Point2i arrow_pos = item_rect.position; @@ -2188,12 +2176,12 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 if (outline_size > 0 && font_outline_color.a > 0) { p_item->cells[i].text_buf->draw_outline(ci, text_pos + Vector2(cell_width - text_width, 0), outline_size, font_outline_color); } - p_item->cells[i].text_buf->draw(ci, text_pos + Vector2(cell_width - text_width, 0), col); + p_item->cells[i].text_buf->draw(ci, text_pos + Vector2(cell_width - text_width, 0), cell_color); } else { if (outline_size > 0 && font_outline_color.a > 0) { p_item->cells[i].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color); } - p_item->cells[i].text_buf->draw(ci, text_pos, col); + p_item->cells[i].text_buf->draw(ci, text_pos, cell_color); } if (!p_item->cells[i].editable) { @@ -2228,7 +2216,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 } if (!p_item->cells[i].editable) { - draw_item_rect(p_item->cells.write[i], item_rect, col, icon_col, outline_size, font_outline_color); + draw_item_rect(p_item->cells.write[i], item_rect, cell_color, icon_col, outline_size, font_outline_color); break; } @@ -2247,7 +2235,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 draw_style_box(theme_cache.custom_button_pressed, ir); } else { draw_style_box(theme_cache.custom_button_hover, ir); - col = theme_cache.custom_button_font_highlight; + cell_color = theme_cache.custom_button_font_highlight; } } else { draw_style_box(theme_cache.custom_button, ir); @@ -2256,17 +2244,42 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 ir.position += theme_cache.custom_button->get_offset(); } - draw_item_rect(p_item->cells.write[i], ir, col, icon_col, outline_size, font_outline_color); + draw_item_rect(p_item->cells.write[i], ir, cell_color, icon_col, outline_size, font_outline_color); downarrow->draw(ci, arrow_pos); } break; } + for (int j = p_item->cells[i].buttons.size() - 1; j >= 0; j--) { + Ref<Texture2D> button_texture = p_item->cells[i].buttons[j].texture; + Size2 button_size = button_texture->get_size() + theme_cache.button_pressed->get_minimum_size(); + + Point2i button_ofs = Point2i(ofs + item_width_with_buttons - button_size.width, p_pos.y) - theme_cache.offset + p_draw_ofs; + + if (cache.click_type == Cache::CLICK_BUTTON && cache.click_item == p_item && cache.click_column == i && cache.click_index == j && !p_item->cells[i].buttons[j].disabled) { + // Being pressed. + Point2 od = button_ofs; + if (rtl) { + od.x = get_size().width - od.x - button_size.x; + } + theme_cache.button_pressed->draw(get_canvas_item(), Rect2(od.x, od.y, button_size.width, MAX(button_size.height, label_h))); + } + + button_ofs.y += (label_h - button_size.height) / 2; + button_ofs += theme_cache.button_pressed->get_offset(); + + if (rtl) { + button_ofs.x = get_size().width - button_ofs.x - button_texture->get_width(); + } + button_texture->draw(ci, button_ofs, p_item->cells[i].buttons[j].disabled ? Color(1, 1, 1, 0.5) : p_item->cells[i].buttons[j].color); + item_width_with_buttons -= button_size.width + theme_cache.button_margin; + } + if (i == 0) { ofs = get_column_width(0); } else { - ofs += w + bw; + ofs += item_width + buttons_width; } if (select_mode == SELECT_MULTI && selected_item == p_item && selected_col == i) { @@ -3188,6 +3201,42 @@ bool Tree::_scroll(bool p_horizontal, float p_pages) { return scroll->get_value() != prev_value; } +Rect2 Tree::_get_scrollbar_layout_rect() const { + const Size2 control_size = get_size(); + const Ref<StyleBox> background = theme_cache.panel_style; + + // This is the background stylebox's content rect. + const real_t width = control_size.x - background->get_margin(SIDE_LEFT) - background->get_margin(SIDE_RIGHT); + const real_t height = control_size.y - background->get_margin(SIDE_TOP) - background->get_margin(SIDE_BOTTOM); + const Rect2 content_rect = Rect2(background->get_offset(), Size2(width, height)); + + // Use the stylebox's margins by default. Can be overridden by `scrollbar_margin_*`. + const real_t top = theme_cache.scrollbar_margin_top < 0 ? content_rect.get_position().y : theme_cache.scrollbar_margin_top; + const real_t right = theme_cache.scrollbar_margin_right < 0 ? content_rect.get_end().x : (control_size.x - theme_cache.scrollbar_margin_right); + const real_t bottom = theme_cache.scrollbar_margin_bottom < 0 ? content_rect.get_end().y : (control_size.y - theme_cache.scrollbar_margin_bottom); + const real_t left = theme_cache.scrollbar_margin_left < 0 ? content_rect.get_position().x : theme_cache.scrollbar_margin_left; + + return Rect2(left, top, right - left, bottom - top); +} + +Rect2 Tree::_get_content_rect() const { + const Size2 control_size = get_size(); + const Ref<StyleBox> background = theme_cache.panel_style; + + // This is the background stylebox's content rect. + const real_t width = control_size.x - background->get_margin(SIDE_LEFT) - background->get_margin(SIDE_RIGHT); + const real_t height = control_size.y - background->get_margin(SIDE_TOP) - background->get_margin(SIDE_BOTTOM); + const Rect2 content_rect = Rect2(background->get_offset(), Size2(width, height)); + + // Scrollbars won't affect Tree's content rect if they're not visible or placed inside the stylebox margin area. + const real_t v_size = v_scroll->is_visible() ? (v_scroll->get_combined_minimum_size().x + theme_cache.scrollbar_h_separation) : 0; + const real_t h_size = h_scroll->is_visible() ? (h_scroll->get_combined_minimum_size().y + theme_cache.scrollbar_v_separation) : 0; + const Point2 scroll_begin = _get_scrollbar_layout_rect().get_end() - Vector2(v_size, h_size); + const Size2 offset = (content_rect.get_end() - scroll_begin).max(Vector2(0, 0)); + + return content_rect.grow_individual(0, 0, -offset.x, -offset.y); +} + void Tree::gui_input(const Ref<InputEvent> &p_event) { ERR_FAIL_COND(p_event.is_null()); @@ -3837,7 +3886,7 @@ bool Tree::is_editing() { } Size2 Tree::get_internal_min_size() const { - Size2i size = theme_cache.panel_style->get_offset(); + Size2i size; if (root) { size.height += get_item_height(root); } @@ -3849,16 +3898,17 @@ Size2 Tree::get_internal_min_size() const { } void Tree::update_scrollbars() { - const Size2 size = get_size(); + const Size2 control_size = get_size(); + const Ref<StyleBox> background = theme_cache.panel_style; + + // This is the background stylebox's content rect. + const real_t width = control_size.x - background->get_margin(SIDE_LEFT) - background->get_margin(SIDE_RIGHT); + const real_t height = control_size.y - background->get_margin(SIDE_TOP) - background->get_margin(SIDE_BOTTOM); + const Rect2 content_rect = Rect2(background->get_offset(), Size2(width, height)); + const Size2 hmin = h_scroll->get_combined_minimum_size(); const Size2 vmin = v_scroll->get_combined_minimum_size(); - const Rect2 content_rect = Rect2(theme_cache.panel_style->get_offset(), size - theme_cache.panel_style->get_minimum_size()); - v_scroll->set_begin(content_rect.get_position() + Vector2(content_rect.get_size().x - vmin.width, 0)); - v_scroll->set_end(content_rect.get_end() - Vector2(0, hmin.height)); - h_scroll->set_begin(content_rect.get_position() + Vector2(0, content_rect.get_size().y - hmin.height)); - h_scroll->set_end(content_rect.get_end() - Vector2(vmin.width, 0)); - const Size2 internal_min_size = get_internal_min_size(); const int title_button_height = _get_title_button_height(); @@ -3896,6 +3946,12 @@ void Tree::update_scrollbars() { h_scroll->hide(); theme_cache.offset.x = 0; } + + const Rect2 scroll_rect = _get_scrollbar_layout_rect(); + v_scroll->set_begin(scroll_rect.get_position() + Vector2(scroll_rect.get_size().x - vmin.width, 0)); + v_scroll->set_end(scroll_rect.get_end() - Vector2(0, display_hscroll ? hmin.height : 0)); + h_scroll->set_begin(scroll_rect.get_position() + Vector2(0, scroll_rect.get_size().y - hmin.height)); + h_scroll->set_end(scroll_rect.get_end() - Vector2(display_vscroll ? vmin.width : 0, 0)); } int Tree::_get_title_button_height() const { @@ -4010,13 +4066,10 @@ void Tree::_notification(int p_what) { RID ci = get_canvas_item(); Ref<StyleBox> bg = theme_cache.panel_style; + const Rect2 content_rect = _get_content_rect(); - Point2 draw_ofs; - draw_ofs += bg->get_offset(); - Size2 draw_size = get_size() - bg->get_minimum_size(); - if (v_scroll->is_visible()) { - draw_size.width -= v_scroll->get_minimum_size().width; - } + Point2 draw_ofs = content_rect.position; + Size2 draw_size = content_rect.size; bg->draw(ci, Rect2(Point2(), get_size())); @@ -4475,18 +4528,7 @@ int Tree::get_column_width(int p_column) const { int column_width = get_column_minimum_width(p_column); if (columns[p_column].expand) { - int expand_area = get_size().width; - - Ref<StyleBox> bg = theme_cache.panel_style; - - if (bg.is_valid()) { - expand_area -= bg->get_margin(SIDE_LEFT) + bg->get_margin(SIDE_RIGHT); - } - - if (v_scroll->is_visible_in_tree()) { - expand_area -= v_scroll->get_combined_minimum_size().width; - } - + int expand_area = _get_content_rect().size.width; int expanding_total = 0; for (int i = 0; i < columns.size(); i++) { @@ -4586,7 +4628,7 @@ void Tree::ensure_cursor_is_visible() { } // Note: Code below similar to Tree::scroll_to_item(), in case of bug fix both. - const Size2 area_size = get_size() - theme_cache.panel_style->get_minimum_size(); + const Size2 area_size = _get_content_rect().size; int y_offset = get_item_offset(selected_item); if (y_offset != -1) { @@ -4595,9 +4637,6 @@ void Tree::ensure_cursor_is_visible() { const int cell_h = compute_item_height(selected_item) + theme_cache.v_separation; int screen_h = area_size.height - tbh; - if (h_scroll->is_visible()) { - screen_h -= h_scroll->get_combined_minimum_size().height; - } if (cell_h > screen_h) { // Screen size is too small, maybe it was not resized yet. v_scroll->set_value(y_offset); @@ -4615,7 +4654,7 @@ void Tree::ensure_cursor_is_visible() { } const int cell_w = get_column_width(selected_col); - const int screen_w = area_size.width - v_scroll->get_combined_minimum_size().width; + const int screen_w = area_size.width; if (cell_w > screen_w) { h_scroll->set_value(x_offset); @@ -4773,7 +4812,7 @@ void Tree::scroll_to_item(TreeItem *p_item, bool p_center_on_item) { update_scrollbars(); // Note: Code below similar to Tree::ensure_cursor_is_visible(), in case of bug fix both. - const Size2 area_size = get_size() - theme_cache.panel_style->get_minimum_size(); + const Size2 area_size = _get_content_rect().size; int y_offset = get_item_offset(p_item); if (y_offset != -1) { @@ -4782,9 +4821,6 @@ void Tree::scroll_to_item(TreeItem *p_item, bool p_center_on_item) { const int cell_h = compute_item_height(p_item) + theme_cache.v_separation; int screen_h = area_size.height - tbh; - if (h_scroll->is_visible()) { - screen_h -= h_scroll->get_combined_minimum_size().height; - } if (p_center_on_item) { v_scroll->set_value(y_offset - (screen_h - cell_h) / 2.0f); diff --git a/scene/gui/tree.h b/scene/gui/tree.h index f125c4a781..42fc719f46 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -549,6 +549,13 @@ private: int scroll_border = 0; int scroll_speed = 0; + + int scrollbar_margin_top = -1; + int scrollbar_margin_right = -1; + int scrollbar_margin_bottom = -1; + int scrollbar_margin_left = -1; + int scrollbar_h_separation = 0; + int scrollbar_v_separation = 0; } theme_cache; struct Cache { @@ -635,6 +642,9 @@ private: bool _scroll(bool p_horizontal, float p_pages); + Rect2 _get_scrollbar_layout_rect() const; + Rect2 _get_content_rect() const; // Considering the background stylebox and scrollbars. + protected: virtual void _update_theme_item_cache() override; diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index 72fb838732..4eabc4916c 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -188,10 +188,13 @@ void CanvasItem::_enter_canvas() { // Resolves to nullptr if the node is top_level. CanvasItem *parent_item = get_parent_item(); + if (get_parent()) { + get_viewport()->canvas_parent_mark_dirty(get_parent()); + } + if (parent_item) { canvas_layer = parent_item->canvas_layer; RenderingServer::get_singleton()->canvas_item_set_parent(canvas_item, parent_item->get_canvas_item()); - RenderingServer::get_singleton()->canvas_item_set_draw_index(canvas_item, get_index()); RenderingServer::get_singleton()->canvas_item_set_visibility_layer(canvas_item, visibility_layer); } else { Node *n = this; @@ -227,8 +230,6 @@ void CanvasItem::_enter_canvas() { } else { get_viewport()->gui_reset_canvas_sort_index(); } - - get_tree()->call_group_flags(SceneTree::GROUP_CALL_UNIQUE | SceneTree::GROUP_CALL_DEFERRED, canvas_group, SNAME("_top_level_raise_self")); } pending_update = false; @@ -302,21 +303,12 @@ void CanvasItem::_notification(int p_what) { if (!block_transform_notify && !xform_change.in_list()) { get_tree()->xform_change_list.add(&xform_change); } - } break; - case NOTIFICATION_MOVED_IN_PARENT: { - if (!is_inside_tree()) { - break; + if (get_viewport()) { + get_parent()->connect(SNAME("child_order_changed"), callable_mp(get_viewport(), &Viewport::canvas_parent_mark_dirty).bind(get_parent()), CONNECT_REFERENCE_COUNTED); } - if (canvas_group != StringName()) { - get_tree()->call_group_flags(SceneTree::GROUP_CALL_UNIQUE | SceneTree::GROUP_CALL_DEFERRED, canvas_group, "_top_level_raise_self"); - } else { - ERR_FAIL_COND_MSG(!get_parent_item(), "Moved child is in incorrect state (no canvas group, no canvas item parent)."); - RenderingServer::get_singleton()->canvas_item_set_draw_index(canvas_item, get_index()); - } } break; - case NOTIFICATION_EXIT_TREE: { if (xform_change.in_list()) { get_tree()->xform_change_list.remove(&xform_change); @@ -332,6 +324,10 @@ void CanvasItem::_notification(int p_what) { } global_invalid = true; parent_visible_in_tree = false; + + if (get_viewport()) { + get_parent()->disconnect(SNAME("child_order_changed"), callable_mp(get_viewport(), &Viewport::canvas_parent_mark_dirty).bind(get_parent())); + } } break; case NOTIFICATION_VISIBILITY_CHANGED: { @@ -340,6 +336,19 @@ void CanvasItem::_notification(int p_what) { } } +void CanvasItem::update_draw_order() { + if (!is_inside_tree()) { + return; + } + + if (canvas_group != StringName()) { + get_tree()->call_group_flags(SceneTree::GROUP_CALL_UNIQUE | SceneTree::GROUP_CALL_DEFERRED, canvas_group, "_top_level_raise_self"); + } else { + ERR_FAIL_COND_MSG(!get_parent_item(), "Moved child is in incorrect state (no canvas group, no canvas item parent)."); + RenderingServer::get_singleton()->canvas_item_set_draw_index(canvas_item, get_index()); + } +} + void CanvasItem::_window_visibility_changed() { if (visible) { _propagate_visibility_changed(window->is_visible()); diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h index 5fbf043159..ea1e666b08 100644 --- a/scene/main/canvas_item.h +++ b/scene/main/canvas_item.h @@ -212,6 +212,8 @@ public: virtual Transform2D _edit_get_transform() const; #endif + void update_draw_order(); + /* VISIBILITY */ void set_visible(bool p_visible); diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp index 76cc17922a..274bd1ad68 100644 --- a/scene/main/canvas_layer.cpp +++ b/scene/main/canvas_layer.cpp @@ -180,25 +180,30 @@ void CanvasLayer::_notification(int p_what) { viewport = vp->get_viewport_rid(); RenderingServer::get_singleton()->viewport_attach_canvas(viewport, canvas); - RenderingServer::get_singleton()->viewport_set_canvas_stacking(viewport, canvas, layer, get_index()); RenderingServer::get_singleton()->viewport_set_canvas_transform(viewport, canvas, transform); _update_follow_viewport(); + + if (vp) { + get_parent()->connect(SNAME("child_order_changed"), callable_mp(vp, &Viewport::canvas_parent_mark_dirty).bind(get_parent()), CONNECT_REFERENCE_COUNTED); + vp->canvas_parent_mark_dirty(get_parent()); + } } break; case NOTIFICATION_EXIT_TREE: { ERR_FAIL_NULL_MSG(vp, "Viewport is not initialized."); + get_parent()->disconnect(SNAME("child_order_changed"), callable_mp(vp, &Viewport::canvas_parent_mark_dirty).bind(get_parent())); vp->_canvas_layer_remove(this); RenderingServer::get_singleton()->viewport_remove_canvas(viewport, canvas); viewport = RID(); _update_follow_viewport(false); } break; + } +} - case NOTIFICATION_MOVED_IN_PARENT: { - if (is_inside_tree()) { - RenderingServer::get_singleton()->viewport_set_canvas_stacking(viewport, canvas, layer, get_index()); - } - } break; +void CanvasLayer::update_draw_order() { + if (is_inside_tree()) { + RenderingServer::get_singleton()->viewport_set_canvas_stacking(viewport, canvas, layer, get_index()); } } diff --git a/scene/main/canvas_layer.h b/scene/main/canvas_layer.h index 47077dc7fd..be1a377a14 100644 --- a/scene/main/canvas_layer.h +++ b/scene/main/canvas_layer.h @@ -67,6 +67,8 @@ protected: void _validate_property(PropertyInfo &p_property) const; public: + void update_draw_order(); + void set_layer(int p_xform); int get_layer() const; diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 22bcfc947b..b27123da06 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -166,7 +166,7 @@ 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 + Node *child = data.children.last()->value; // begin from the end because its faster and more consistent with creation memdelete(child); } } break; @@ -176,9 +176,10 @@ void Node::_notification(int p_notification) { void Node::_propagate_ready() { data.ready_notified = true; data.blocked++; - for (int i = 0; i < data.children.size(); i++) { - data.children[i]->_propagate_ready(); + for (KeyValue<StringName, Node *> &K : data.children) { + K.value->_propagate_ready(); } + data.blocked--; notification(NOTIFICATION_POST_ENTER_TREE); @@ -228,9 +229,9 @@ void Node::_propagate_enter_tree() { data.blocked++; //block while adding children - for (int i = 0; i < data.children.size(); i++) { - if (!data.children[i]->is_inside_tree()) { // could have been added in enter_tree - data.children[i]->_propagate_enter_tree(); + for (KeyValue<StringName, Node *> &K : data.children) { + if (!K.value->is_inside_tree()) { // could have been added in enter_tree + K.value->_propagate_enter_tree(); } } @@ -267,9 +268,11 @@ void Node::_propagate_after_exit_tree() { } data.blocked++; - for (int i = data.children.size() - 1; i >= 0; i--) { - data.children[i]->_propagate_after_exit_tree(); + + for (HashMap<StringName, Node *>::Iterator I = data.children.last(); I; --I) { + I->value->_propagate_after_exit_tree(); } + data.blocked--; emit_signal(SceneStringNames::get_singleton()->tree_exited); @@ -286,8 +289,8 @@ void Node::_propagate_exit_tree() { #endif data.blocked++; - for (int i = data.children.size() - 1; i >= 0; i--) { - data.children[i]->_propagate_exit_tree(); + for (HashMap<StringName, Node *>::Iterator I = data.children.last(); I; --I) { + I->value->_propagate_exit_tree(); } data.blocked--; @@ -329,25 +332,26 @@ void Node::move_child(Node *p_child, int p_index) { ERR_FAIL_NULL(p_child); ERR_FAIL_COND_MSG(p_child->data.parent != this, "Child is not a child of this node."); + _update_children_cache(); // We need to check whether node is internal and move it only in the relevant node range. - if (p_child->_is_internal_front()) { + if (p_child->data.internal_mode == INTERNAL_MODE_FRONT) { if (p_index < 0) { - p_index += data.internal_children_front; + p_index += data.internal_children_front_count_cache; } - ERR_FAIL_INDEX_MSG(p_index, data.internal_children_front, vformat("Invalid new child index: %d. Child is internal.", p_index)); + ERR_FAIL_INDEX_MSG(p_index, data.internal_children_front_count_cache, vformat("Invalid new child index: %d. Child is internal.", p_index)); _move_child(p_child, p_index); - } else if (p_child->_is_internal_back()) { + } else if (p_child->data.internal_mode == INTERNAL_MODE_BACK) { if (p_index < 0) { - p_index += data.internal_children_back; + p_index += data.internal_children_back_count_cache; } - ERR_FAIL_INDEX_MSG(p_index, data.internal_children_back, vformat("Invalid new child index: %d. Child is internal.", p_index)); - _move_child(p_child, data.children.size() - data.internal_children_back + p_index); + ERR_FAIL_INDEX_MSG(p_index, data.internal_children_back_count_cache, vformat("Invalid new child index: %d. Child is internal.", p_index)); + _move_child(p_child, (int)data.children_cache.size() - data.internal_children_back_count_cache + p_index); } else { if (p_index < 0) { p_index += get_child_count(false); } - ERR_FAIL_INDEX_MSG(p_index, data.children.size() + 1 - data.internal_children_front - data.internal_children_back, vformat("Invalid new child index: %d.", p_index)); - _move_child(p_child, p_index + data.internal_children_front); + ERR_FAIL_INDEX_MSG(p_index, (int)data.children_cache.size() + 1 - data.internal_children_front_count_cache - data.internal_children_back_count_cache, vformat("Invalid new child index: %d.", p_index)); + _move_child(p_child, p_index + data.internal_children_front_count_cache); } } @@ -357,30 +361,32 @@ void Node::_move_child(Node *p_child, int p_index, bool p_ignore_end) { // Specifying one place beyond the end // means the same as moving to the last index if (!p_ignore_end) { // p_ignore_end is a little hack to make back internal children work properly. - if (p_child->_is_internal_front()) { - if (p_index == data.internal_children_front) { + if (p_child->data.internal_mode == INTERNAL_MODE_FRONT) { + if (p_index == data.internal_children_front_count_cache) { p_index--; } - } else if (p_child->_is_internal_back()) { - if (p_index == data.children.size()) { + } else if (p_child->data.internal_mode == INTERNAL_MODE_BACK) { + if (p_index == (int)data.children_cache.size()) { p_index--; } } else { - if (p_index == data.children.size() - data.internal_children_back) { + if (p_index == (int)data.children_cache.size() - data.internal_children_back_count_cache) { p_index--; } } } - if (p_child->data.index == p_index) { + int child_index = p_child->get_index(); + + if (child_index == p_index) { return; //do nothing } - int motion_from = MIN(p_index, p_child->data.index); - int motion_to = MAX(p_index, p_child->data.index); + int motion_from = MIN(p_index, child_index); + int motion_to = MAX(p_index, child_index); - data.children.remove_at(p_child->data.index); - data.children.insert(p_index, p_child); + data.children_cache.remove_at(child_index); + data.children_cache.insert(p_index, p_child); if (data.tree) { data.tree->tree_changed(); @@ -389,13 +395,18 @@ void Node::_move_child(Node *p_child, int p_index, bool p_ignore_end) { data.blocked++; //new pos first for (int i = motion_from; i <= motion_to; i++) { - data.children[i]->data.index = i; + if (data.children_cache[i]->data.internal_mode == INTERNAL_MODE_DISABLED) { + data.children_cache[i]->data.index = i - data.internal_children_front_count_cache; + } else if (data.children_cache[i]->data.internal_mode == INTERNAL_MODE_BACK) { + data.children_cache[i]->data.index = i - data.internal_children_front_count_cache - data.external_children_count_cache; + } else { + data.children_cache[i]->data.index = i; + } } // notification second move_child_notify(p_child); - for (int i = motion_from; i <= motion_to; i++) { - data.children[i]->notification(NOTIFICATION_MOVED_IN_PARENT); - } + notification(NOTIFICATION_CHILD_ORDER_CHANGED); + emit_signal(SNAME("child_order_changed")); p_child->_propagate_groups_dirty(); data.blocked--; @@ -408,8 +419,8 @@ void Node::_propagate_groups_dirty() { } } - for (int i = 0; i < data.children.size(); i++) { - data.children[i]->_propagate_groups_dirty(); + for (KeyValue<StringName, Node *> &K : data.children) { + K.value->_propagate_groups_dirty(); } } @@ -529,8 +540,8 @@ void Node::_propagate_pause_notification(bool p_enable) { notification(NOTIFICATION_UNPAUSED); } - for (int i = 0; i < data.children.size(); i++) { - data.children[i]->_propagate_pause_notification(p_enable); + for (KeyValue<StringName, Node *> &K : data.children) { + K.value->_propagate_pause_notification(p_enable); } } @@ -549,8 +560,8 @@ void Node::_propagate_process_owner(Node *p_owner, int p_pause_notification, int notification(p_enabled_notification); } - for (int i = 0; i < data.children.size(); i++) { - Node *c = data.children[i]; + for (KeyValue<StringName, Node *> &K : data.children) { + Node *c = K.value; if (c->data.process_mode == PROCESS_MODE_INHERIT) { c->_propagate_process_owner(p_owner, p_pause_notification, p_enabled_notification); } @@ -561,8 +572,8 @@ void Node::set_multiplayer_authority(int p_peer_id, bool p_recursive) { data.multiplayer_authority = p_peer_id; if (p_recursive) { - for (int i = 0; i < data.children.size(); i++) { - data.children[i]->set_multiplayer_authority(p_peer_id, true); + for (KeyValue<StringName, Node *> &K : data.children) { + K.value->set_multiplayer_authority(p_peer_id, true); } } } @@ -912,10 +923,13 @@ void Node::set_name(const String &p_name) { if (data.unique_name_in_owner && data.owner) { _release_unique_name_in_owner(); } + String old_name = data.name; data.name = name; if (data.parent) { + data.parent->data.children.erase(old_name); data.parent->_validate_child_name(this, true); + data.parent->data.children.insert(data.name, this); } if (data.unique_name_in_owner && data.owner) { @@ -977,25 +991,35 @@ void Node::_validate_child_name(Node *p_child, bool p_force_human_readable) { //new unique name must be assigned unique = false; } else { - //check if exists - Node **children = data.children.ptrw(); - int cc = data.children.size(); - - for (int i = 0; i < cc; i++) { - if (children[i] == p_child) { - continue; - } - if (children[i]->data.name == p_child->data.name) { - unique = false; - break; - } - } + const Node *const *existing = data.children.getptr(p_child->data.name); + unique = !existing || *existing == p_child; } if (!unique) { ERR_FAIL_COND(!node_hrcr_count.ref()); - String name = "@" + String(p_child->get_name()) + "@" + itos(node_hrcr_count.get()); - p_child->data.name = name; + // Optimized version of the code below: + // String name = "@" + String(p_child->get_name()) + "@" + itos(node_hrcr_count.get()); + uint32_t c = node_hrcr_count.get(); + String cn = p_child->get_class_name().operator String(); + const char32_t *cn_ptr = cn.ptr(); + uint32_t cn_length = cn.length(); + uint32_t c_chars = String::num_characters(c); + uint32_t len = 2 + cn_length + c_chars; + char32_t *str = (char32_t *)alloca(sizeof(char32_t) * (len + 1)); + uint32_t idx = 0; + str[idx++] = '@'; + for (uint32_t i = 0; i < cn_length; i++) { + str[idx++] = cn_ptr[i]; + } + str[idx++] = '@'; + idx += c_chars; + ERR_FAIL_COND(idx != len); + str[idx] = 0; + while (c) { + str[--idx] = '0' + (c % 10); + c /= 10; + } + p_child->data.name = String(str); } } } @@ -1032,25 +1056,9 @@ void Node::_generate_serial_child_name(const Node *p_child, StringName &name) co name = p_child->get_class(); } - //quickly test if proposed name exists - int cc = data.children.size(); //children count - const Node *const *children_ptr = data.children.ptr(); - - { - bool exists = false; - - for (int i = 0; i < cc; i++) { - if (children_ptr[i] == p_child) { //exclude self in renaming if it's already a child - continue; - } - if (children_ptr[i]->data.name == name) { - exists = true; - } - } - - if (!exists) { - return; //if it does not exist, it does not need validation - } + const Node *const *existing = data.children.getptr(name); + if (!existing || *existing == p_child) { // Unused, or is current node. + return; } // Extract trailing number @@ -1077,16 +1085,9 @@ void Node::_generate_serial_child_name(const Node *p_child, StringName &name) co for (;;) { StringName attempt = name_string + nums; - bool exists = false; - for (int i = 0; i < cc; i++) { - if (children_ptr[i] == p_child) { - continue; - } - if (children_ptr[i]->data.name == attempt) { - exists = true; - } - } + existing = data.children.getptr(attempt); + bool exists = existing != nullptr && *existing != p_child; if (!exists) { name = attempt; @@ -1103,17 +1104,34 @@ void Node::_generate_serial_child_name(const Node *p_child, StringName &name) co } } -void Node::_add_child_nocheck(Node *p_child, const StringName &p_name) { +void Node::_add_child_nocheck(Node *p_child, const StringName &p_name, InternalMode p_internal_mode) { //add a child node quickly, without name validation p_child->data.name = p_name; - p_child->data.index = data.children.size(); - data.children.push_back(p_child); + data.children.insert(p_name, p_child); + + p_child->data.internal_mode = p_internal_mode; + switch (p_internal_mode) { + case INTERNAL_MODE_FRONT: { + p_child->data.index = data.internal_children_front_count_cache++; + } break; + case INTERNAL_MODE_BACK: { + p_child->data.index = data.internal_children_back_count_cache++; + } break; + case INTERNAL_MODE_DISABLED: { + p_child->data.index = data.external_children_count_cache++; + } break; + } + p_child->data.parent = this; - if (data.internal_children_back > 0) { - _move_child(p_child, data.children.size() - data.internal_children_back - 1); + if (!data.children_cache_dirty && p_internal_mode == INTERNAL_MODE_DISABLED && data.internal_children_back_count_cache == 0) { + // Special case, also add to the cached children array since its cheap. + data.children_cache.push_back(p_child); + } else { + data.children_cache_dirty = true; } + p_child->notification(NOTIFICATION_PARENTED); if (data.tree) { @@ -1124,6 +1142,8 @@ void Node::_add_child_nocheck(Node *p_child, const StringName &p_name) { //recognize children created in this node constructor p_child->data.parent_owned = data.in_constructor; add_child_notify(p_child); + notification(NOTIFICATION_CHILD_ORDER_CHANGED); + emit_signal(SNAME("child_order_changed")); } void Node::add_child(Node *p_child, bool p_force_readable_name, InternalMode p_internal) { @@ -1136,17 +1156,7 @@ void Node::add_child(Node *p_child, bool p_force_readable_name, InternalMode p_i ERR_FAIL_COND_MSG(data.blocked > 0, "Parent node is busy setting up children, `add_child()` failed. Consider using `add_child.call_deferred(child)` instead."); _validate_child_name(p_child, p_force_readable_name); - _add_child_nocheck(p_child, p_child->data.name); - - if (p_internal == INTERNAL_MODE_FRONT) { - _move_child(p_child, data.internal_children_front); - data.internal_children_front++; - } else if (p_internal == INTERNAL_MODE_BACK) { - if (data.internal_children_back > 0) { - _move_child(p_child, data.children.size() - 1, true); - } - data.internal_children_back++; - } + _add_child_nocheck(p_child, p_child->data.name, p_internal); } void Node::add_sibling(Node *p_sibling, bool p_force_readable_name) { @@ -1155,49 +1165,25 @@ void Node::add_sibling(Node *p_sibling, bool p_force_readable_name) { ERR_FAIL_COND_MSG(p_sibling == this, vformat("Can't add sibling '%s' to itself.", p_sibling->get_name())); // adding to itself! ERR_FAIL_COND_MSG(data.blocked > 0, "Parent node is busy setting up children, `add_sibling()` failed. Consider using `add_sibling.call_deferred(sibling)` instead."); - InternalMode internal = INTERNAL_MODE_DISABLED; - if (_is_internal_front()) { // The sibling will have the same internal status. - internal = INTERNAL_MODE_FRONT; - } else if (_is_internal_back()) { - internal = INTERNAL_MODE_BACK; - } - - data.parent->add_child(p_sibling, p_force_readable_name, internal); + data.parent->add_child(p_sibling, p_force_readable_name, data.internal_mode); + data.parent->_update_children_cache(); data.parent->_move_child(p_sibling, get_index() + 1); } void Node::remove_child(Node *p_child) { ERR_FAIL_NULL(p_child); ERR_FAIL_COND_MSG(data.blocked > 0, "Parent node is busy adding/removing children, `remove_child()` can't be called at this time. Consider using `remove_child.call_deferred(child)` instead."); - - int child_count = data.children.size(); - Node **children = data.children.ptrw(); - int idx = -1; - - if (p_child->data.index >= 0 && p_child->data.index < child_count) { - if (children[p_child->data.index] == p_child) { - idx = p_child->data.index; - } - } - - if (idx == -1) { //maybe removed while unparenting or something and index was not updated, so just in case the above fails, try this. - for (int i = 0; i < child_count; i++) { - if (children[i] == p_child) { - idx = i; - break; - } - } - } - - ERR_FAIL_COND_MSG(idx == -1, vformat("Cannot remove child node '%s' as it is not a child of this node.", p_child->get_name())); - //ERR_FAIL_COND( p_child->data.blocked > 0 ); - - // If internal child, update the counter. - if (p_child->_is_internal_front()) { - data.internal_children_front--; - } else if (p_child->_is_internal_back()) { - data.internal_children_back--; - } + ERR_FAIL_COND(p_child->data.parent != this); + + /** + * Do not change the data.internal_children*cache counters here. + * Because if nodes are re-added, the indices can remain + * greater-than-everything indices and children added remain + * properly ordered. + * + * All children indices and counters will be updated next time the + * cache is re-generated. + */ data.blocked++; p_child->_set_tree(nullptr); @@ -1205,18 +1191,15 @@ void Node::remove_child(Node *p_child) { remove_child_notify(p_child); p_child->notification(NOTIFICATION_UNPARENTED); - data.blocked--; - data.children.remove_at(idx); + data.blocked--; - //update pointer and size - child_count = data.children.size(); - children = data.children.ptrw(); + data.children_cache_dirty = true; + bool success = data.children.erase(p_child->data.name); + ERR_FAIL_COND_MSG(!success, "Children name does not match parent name in hashtable, this is a bug."); - for (int i = idx; i < child_count; i++) { - children[i]->data.index = i; - children[i]->notification(NOTIFICATION_MOVED_IN_PARENT); - } + notification(NOTIFICATION_CHILD_ORDER_CHANGED); + emit_signal(SNAME("child_order_changed")); p_child->data.parent = nullptr; p_child->data.index = -1; @@ -1226,42 +1209,73 @@ void Node::remove_child(Node *p_child) { } } +void Node::_update_children_cache_impl() const { + // Assign children + data.children_cache.resize(data.children.size()); + int idx = 0; + for (const KeyValue<StringName, Node *> &K : data.children) { + data.children_cache[idx] = K.value; + idx++; + } + // Sort them + data.children_cache.sort_custom<ComparatorByIndex>(); + // Update indices + data.external_children_count_cache = 0; + data.internal_children_back_count_cache = 0; + data.internal_children_front_count_cache = 0; + + for (uint32_t i = 0; i < data.children_cache.size(); i++) { + switch (data.children_cache[i]->data.internal_mode) { + case INTERNAL_MODE_DISABLED: { + data.children_cache[i]->data.index = data.external_children_count_cache++; + } break; + case INTERNAL_MODE_FRONT: { + data.children_cache[i]->data.index = data.internal_children_front_count_cache++; + } break; + case INTERNAL_MODE_BACK: { + data.children_cache[i]->data.index = data.internal_children_back_count_cache++; + } break; + } + } + data.children_cache_dirty = false; +} + int Node::get_child_count(bool p_include_internal) const { + _update_children_cache(); + if (p_include_internal) { - return data.children.size(); + return data.children_cache.size(); } else { - return data.children.size() - data.internal_children_front - data.internal_children_back; + return data.children_cache.size() - data.internal_children_front_count_cache - data.internal_children_back_count_cache; } } Node *Node::get_child(int p_index, bool p_include_internal) const { + _update_children_cache(); + if (p_include_internal) { if (p_index < 0) { - p_index += data.children.size(); + p_index += data.children_cache.size(); } - ERR_FAIL_INDEX_V(p_index, data.children.size(), nullptr); - return data.children[p_index]; + ERR_FAIL_INDEX_V(p_index, (int)data.children_cache.size(), nullptr); + return data.children_cache[p_index]; } else { if (p_index < 0) { - p_index += data.children.size() - data.internal_children_front - data.internal_children_back; + p_index += (int)data.children_cache.size() - data.internal_children_front_count_cache - data.internal_children_back_count_cache; } - ERR_FAIL_INDEX_V(p_index, data.children.size() - data.internal_children_front - data.internal_children_back, nullptr); - p_index += data.internal_children_front; - return data.children[p_index]; + ERR_FAIL_INDEX_V(p_index, (int)data.children_cache.size() - data.internal_children_front_count_cache - data.internal_children_back_count_cache, nullptr); + p_index += data.internal_children_front_count_cache; + return data.children_cache[p_index]; } } Node *Node::_get_child_by_name(const StringName &p_name) const { - int cc = data.children.size(); - Node *const *cd = data.children.ptr(); - - for (int i = 0; i < cc; i++) { - if (cd[i]->data.name == p_name) { - return cd[i]; - } + const Node *const *node = data.children.getptr(p_name); + if (node) { + return const_cast<Node *>(*node); + } else { + return nullptr; } - - return nullptr; } Node *Node::get_node_or_null(const NodePath &p_path) const { @@ -1323,18 +1337,12 @@ Node *Node::get_node_or_null(const NodePath &p_path) const { } else { next = nullptr; - - for (int j = 0; j < current->data.children.size(); j++) { - Node *child = current->data.children[j]; - - if (child->data.name == name) { - next = child; - break; - } - } - if (next == nullptr) { + const Node *const *node = current->data.children.getptr(name); + if (node) { + next = const_cast<Node *>(*node); + } else { return nullptr; - }; + } } current = next; } @@ -1377,9 +1385,9 @@ bool Node::has_node(const NodePath &p_path) const { // Can be recursive or not, and limited to owned nodes. Node *Node::find_child(const String &p_pattern, bool p_recursive, bool p_owned) const { ERR_FAIL_COND_V(p_pattern.is_empty(), nullptr); - - Node *const *cptr = data.children.ptr(); - int ccount = data.children.size(); + _update_children_cache(); + Node *const *cptr = data.children_cache.ptr(); + int ccount = data.children_cache.size(); for (int i = 0; i < ccount; i++) { if (p_owned && !cptr[i]->data.owner) { continue; @@ -1406,9 +1414,9 @@ Node *Node::find_child(const String &p_pattern, bool p_recursive, bool p_owned) TypedArray<Node> Node::find_children(const String &p_pattern, const String &p_type, bool p_recursive, bool p_owned) const { TypedArray<Node> ret; ERR_FAIL_COND_V(p_pattern.is_empty() && p_type.is_empty(), ret); - - Node *const *cptr = data.children.ptr(); - int ccount = data.children.size(); + _update_children_cache(); + Node *const *cptr = data.children_cache.ptr(); + int ccount = data.children_cache.size(); for (int i = 0; i < ccount; i++) { if (p_owned && !cptr[i]->data.owner) { continue; @@ -1501,6 +1509,8 @@ bool Node::is_greater_than(const Node *p_node) const { ERR_FAIL_COND_V(data.depth < 0, false); ERR_FAIL_COND_V(p_node->data.depth < 0, false); + _update_children_cache(); + int *this_stack = (int *)alloca(sizeof(int) * data.depth); int *that_stack = (int *)alloca(sizeof(int) * p_node->data.depth); @@ -1509,15 +1519,16 @@ bool Node::is_greater_than(const Node *p_node) const { int idx = data.depth - 1; while (n) { ERR_FAIL_INDEX_V(idx, data.depth, false); - this_stack[idx--] = n->data.index; + this_stack[idx--] = n->get_index(); n = n->data.parent; } + ERR_FAIL_COND_V(idx != -1, false); n = p_node; idx = p_node->data.depth - 1; while (n) { ERR_FAIL_INDEX_V(idx, p_node->data.depth, false); - that_stack[idx--] = n->data.index; + that_stack[idx--] = n->get_index(); n = n->data.parent; } @@ -1551,8 +1562,8 @@ void Node::get_owned_by(Node *p_by, List<Node *> *p_owned) { p_owned->push_back(this); } - for (int i = 0; i < get_child_count(); i++) { - get_child(i)->get_owned_by(p_by, p_owned); + for (KeyValue<StringName, Node *> &K : data.children) { + K.value->get_owned_by(p_by, p_owned); } } @@ -1870,9 +1881,10 @@ int Node::get_persistent_group_count() const { void Node::_print_tree_pretty(const String &prefix, const bool last) { String new_prefix = last ? String::utf8(" ┖╴") : String::utf8(" ┠╴"); print_line(prefix + new_prefix + String(get_name())); - for (int i = 0; i < data.children.size(); i++) { + _update_children_cache(); + for (uint32_t i = 0; i < data.children_cache.size(); i++) { new_prefix = last ? String::utf8(" ") : String::utf8(" ┃ "); - data.children[i]->_print_tree_pretty(prefix + new_prefix, i == data.children.size() - 1); + data.children_cache[i]->_print_tree_pretty(prefix + new_prefix, i == data.children_cache.size() - 1); } } @@ -1886,15 +1898,17 @@ void Node::print_tree() { void Node::_print_tree(const Node *p_node) { print_line(String(p_node->get_path_to(this))); - for (int i = 0; i < data.children.size(); i++) { - data.children[i]->_print_tree(p_node); + _update_children_cache(); + for (uint32_t i = 0; i < data.children_cache.size(); i++) { + data.children_cache[i]->_print_tree(p_node); } } void Node::_propagate_reverse_notification(int p_notification) { data.blocked++; - for (int i = data.children.size() - 1; i >= 0; i--) { - data.children[i]->_propagate_reverse_notification(p_notification); + + for (HashMap<StringName, Node *>::Iterator I = data.children.last(); I; --I) { + I->value->_propagate_reverse_notification(p_notification); } notification(p_notification, true); @@ -1910,8 +1924,8 @@ void Node::_propagate_deferred_notification(int p_notification, bool p_reverse) MessageQueue::get_singleton()->push_notification(this, p_notification); } - for (int i = 0; i < data.children.size(); i++) { - data.children[i]->_propagate_deferred_notification(p_notification, p_reverse); + for (KeyValue<StringName, Node *> &K : data.children) { + K.value->_propagate_deferred_notification(p_notification, p_reverse); } if (p_reverse) { @@ -1925,8 +1939,8 @@ void Node::propagate_notification(int p_notification) { data.blocked++; notification(p_notification); - for (int i = 0; i < data.children.size(); i++) { - data.children[i]->propagate_notification(p_notification); + for (KeyValue<StringName, Node *> &K : data.children) { + K.value->propagate_notification(p_notification); } data.blocked--; } @@ -1938,8 +1952,8 @@ void Node::propagate_call(const StringName &p_method, const Array &p_args, const callv(p_method, p_args); } - for (int i = 0; i < data.children.size(); i++) { - data.children[i]->propagate_call(p_method, p_args, p_parent_first); + for (KeyValue<StringName, Node *> &K : data.children) { + K.value->propagate_call(p_method, p_args, p_parent_first); } if (!p_parent_first && has_method(p_method)) { @@ -1955,22 +1969,12 @@ void Node::_propagate_replace_owner(Node *p_owner, Node *p_by_owner) { } data.blocked++; - for (int i = 0; i < data.children.size(); i++) { - data.children[i]->_propagate_replace_owner(p_owner, p_by_owner); + for (KeyValue<StringName, Node *> &K : data.children) { + K.value->_propagate_replace_owner(p_owner, p_by_owner); } data.blocked--; } -int Node::get_index(bool p_include_internal) const { - // p_include_internal = false doesn't make sense if the node is internal. - ERR_FAIL_COND_V_MSG(!p_include_internal && (_is_internal_front() || _is_internal_back()), -1, "Node is internal. Can't get index with 'include_internal' being false."); - - if (data.parent && !p_include_internal) { - return data.index - data.parent->data.internal_children_front; - } - return data.index; -} - Ref<Tween> Node::create_tween() { ERR_FAIL_COND_V_MSG(!data.tree, nullptr, "Can't create Tween when not inside scene tree."); Ref<Tween> tween = get_tree()->create_tween(); @@ -2477,7 +2481,7 @@ void Node::replace_by(Node *p_node, bool p_keep_groups) { } Node *parent = data.parent; - int index_in_parent = data.index; + int index_in_parent = get_index(); if (data.parent) { parent->remove_child(this); @@ -2729,8 +2733,8 @@ void Node::get_argument_options(const StringName &p_function, int p_idx, List<St void Node::clear_internal_tree_resource_paths() { clear_internal_resource_paths(); - for (int i = 0; i < data.children.size(); i++) { - data.children[i]->clear_internal_tree_resource_paths(); + for (KeyValue<StringName, Node *> &K : data.children) { + K.value->clear_internal_tree_resource_paths(); } } @@ -2974,6 +2978,7 @@ void Node::_bind_methods() { BIND_CONSTANT(NOTIFICATION_DRAG_BEGIN); BIND_CONSTANT(NOTIFICATION_DRAG_END); BIND_CONSTANT(NOTIFICATION_PATH_RENAMED); + BIND_CONSTANT(NOTIFICATION_CHILD_ORDER_CHANGED); BIND_CONSTANT(NOTIFICATION_INTERNAL_PROCESS); BIND_CONSTANT(NOTIFICATION_INTERNAL_PHYSICS_PROCESS); BIND_CONSTANT(NOTIFICATION_POST_ENTER_TREE); @@ -3027,6 +3032,7 @@ void Node::_bind_methods() { ADD_SIGNAL(MethodInfo("tree_exited")); ADD_SIGNAL(MethodInfo("child_entered_tree", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT, "Node"))); ADD_SIGNAL(MethodInfo("child_exiting_tree", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT, "Node"))); + ADD_SIGNAL(MethodInfo("child_order_changed")); ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_name", "get_name"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "unique_name_in_owner", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_unique_name_in_owner", "is_unique_name_in_owner"); @@ -3075,9 +3081,10 @@ Node::~Node() { data.grouped.clear(); data.owned.clear(); data.children.clear(); + data.children_cache.clear(); ERR_FAIL_COND(data.parent); - ERR_FAIL_COND(data.children.size()); + ERR_FAIL_COND(data.children_cache.size()); orphan_node_count--; } diff --git a/scene/main/node.h b/scene/main/node.h index 8ce42d04bd..8b3c07b39b 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -92,6 +92,18 @@ private: SceneTree::Group *group = nullptr; }; + struct ComparatorByIndex { + bool operator()(const Node *p_left, const Node *p_right) const { + static const uint32_t order[3] = { 1, 0, 2 }; + uint32_t order_left = order[p_left->data.internal_mode]; + uint32_t order_right = order[p_right->data.internal_mode]; + if (order_left == order_right) { + return p_left->data.index < p_right->data.index; + } + return order_left < order_right; + } + }; + // This Data struct is to avoid namespace pollution in derived classes. struct Data { String scene_file_path; @@ -100,13 +112,16 @@ private: Node *parent = nullptr; Node *owner = nullptr; - Vector<Node *> children; + HashMap<StringName, Node *> children; + mutable bool children_cache_dirty = true; + mutable LocalVector<Node *> children_cache; HashMap<StringName, Node *> owned_unique_nodes; bool unique_name_in_owner = false; - - int internal_children_front = 0; - int internal_children_back = 0; - int index = -1; + InternalMode internal_mode = INTERNAL_MODE_DISABLED; + mutable int internal_children_front_count_cache = 0; + mutable int internal_children_back_count_cache = 0; + mutable int external_children_count_cache = 0; + mutable int index = -1; // relative to front, normal or back. int depth = -1; int blocked = 0; // Safeguard that throws an error when attempting to modify the tree in a harmful way while being traversed. StringName name; @@ -187,9 +202,6 @@ private: Error _rpc_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); Error _rpc_id_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); - _FORCE_INLINE_ bool _is_internal_front() const { return data.parent && data.index < data.parent->data.internal_children_front; } - _FORCE_INLINE_ bool _is_internal_back() const { return data.parent && data.index >= data.parent->data.children.size() - data.parent->data.internal_children_back; } - friend class SceneTree; void _set_tree(SceneTree *p_tree); @@ -201,6 +213,14 @@ private: void _release_unique_name_in_owner(); void _acquire_unique_name_in_owner(); + _FORCE_INLINE_ void _update_children_cache() const { + if (unlikely(data.children_cache_dirty)) { + _update_children_cache_impl(); + } + } + + void _update_children_cache_impl() const; + protected: void _block() { data.blocked++; } void _unblock() { data.blocked--; } @@ -219,7 +239,7 @@ protected: friend class SceneState; - void _add_child_nocheck(Node *p_child, const StringName &p_name); + void _add_child_nocheck(Node *p_child, const StringName &p_name, InternalMode p_internal_mode = INTERNAL_MODE_DISABLED); void _set_owner_nocheck(Node *p_owner); void _set_name_nocheck(const StringName &p_name); @@ -264,7 +284,7 @@ public: NOTIFICATION_DRAG_BEGIN = 21, NOTIFICATION_DRAG_END = 22, NOTIFICATION_PATH_RENAMED = 23, - //NOTIFICATION_TRANSLATION_CHANGED = 24, moved below + NOTIFICATION_CHILD_ORDER_CHANGED = 24, NOTIFICATION_INTERNAL_PROCESS = 25, NOTIFICATION_INTERNAL_PHYSICS_PROCESS = 26, NOTIFICATION_POST_ENTER_TREE = 27, @@ -361,7 +381,31 @@ public: void set_unique_name_in_owner(bool p_enabled); bool is_unique_name_in_owner() const; - int get_index(bool p_include_internal = true) const; + _FORCE_INLINE_ int get_index(bool p_include_internal = true) const { + // p_include_internal = false doesn't make sense if the node is internal. + ERR_FAIL_COND_V_MSG(!p_include_internal && data.internal_mode != INTERNAL_MODE_DISABLED, -1, "Node is internal. Can't get index with 'include_internal' being false."); + if (!data.parent) { + return data.index; + } + data.parent->_update_children_cache(); + + if (!p_include_internal) { + return data.index; + } else { + switch (data.internal_mode) { + case INTERNAL_MODE_DISABLED: { + return data.parent->data.internal_children_front_count_cache + data.index; + } break; + case INTERNAL_MODE_FRONT: { + return data.index; + } break; + case INTERNAL_MODE_BACK: { + return data.parent->data.internal_children_front_count_cache + data.parent->data.external_children_count_cache + data.index; + } break; + } + return -1; + } + } Ref<Tween> create_tween(); diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 9327102cc8..a232354fae 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -825,7 +825,6 @@ void SceneTree::set_pause(bool p_enabled) { return; } paused = p_enabled; - NavigationServer3D::get_singleton()->set_active(!p_enabled); PhysicsServer3D::get_singleton()->set_active(!p_enabled); PhysicsServer2D::get_singleton()->set_active(!p_enabled); if (get_root()) { @@ -1519,7 +1518,7 @@ SceneTree::SceneTree() { ProjectSettings::get_singleton()->set("rendering/environment/defaults/default_environment", ""); } else { // File was erased, notify user. - ERR_PRINT(RTR("Default Environment as specified in Project Settings (Rendering -> Environment -> Default Environment) could not be loaded.")); + ERR_PRINT(RTR("Default Environment as specified in the project setting \"rendering/environment/defaults/default_environment\" could not be loaded.")); } } } diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index feddb1e779..9f9a2eeb18 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -165,6 +165,31 @@ ViewportTexture::~ViewportTexture() { } } +void Viewport::_process_dirty_canvas_parent_orders() { + for (const ObjectID &id : gui.canvas_parents_with_dirty_order) { + Object *obj = ObjectDB::get_instance(id); + if (!obj) { + continue; // May have been deleted. + } + + Node *n = static_cast<Node *>(obj); + for (int i = 0; i < n->get_child_count(); i++) { + Node *c = n->get_child(i); + CanvasItem *ci = Object::cast_to<CanvasItem>(c); + if (ci) { + ci->update_draw_order(); + continue; + } + CanvasLayer *cl = Object::cast_to<CanvasLayer>(c); + if (cl) { + cl->update_draw_order(); + } + } + } + + gui.canvas_parents_with_dirty_order.clear(); +} + void Viewport::_sub_window_update_order() { if (gui.sub_windows.size() < 2) { return; @@ -929,6 +954,14 @@ Rect2 Viewport::get_visible_rect() const { return r; } +void Viewport::canvas_parent_mark_dirty(Node *p_node) { + bool request_update = gui.canvas_parents_with_dirty_order.is_empty(); + gui.canvas_parents_with_dirty_order.insert(p_node->get_instance_id()); + if (request_update) { + MessageQueue::get_singleton()->push_callable(callable_mp(this, &Viewport::_process_dirty_canvas_parent_orders)); + } +} + void Viewport::_update_audio_listener_2d() { if (AudioServer::get_singleton()) { AudioServer::get_singleton()->notify_listener_changed(); diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 5213c0db01..f12e7921a3 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -376,6 +376,7 @@ private: double tooltip_delay = 0.0; bool roots_order_dirty = false; List<Control *> roots; + HashSet<ObjectID> canvas_parents_with_dirty_order; int canvas_sort_index = 0; //for sorting items with canvas as root bool dragging = false; bool drag_successful = false; @@ -468,6 +469,8 @@ private: virtual bool _can_consume_input_events() const { return true; } uint64_t event_count = 0; + void _process_dirty_canvas_parent_orders(); + protected: void _set_size(const Size2i &p_size, const Size2i &p_size_2d_override, bool p_allocated); @@ -480,6 +483,8 @@ protected: static void _bind_methods(); public: + void canvas_parent_mark_dirty(Node *p_node); + uint64_t get_processed_events_count() const { return event_count; } AudioListener2D *get_audio_listener_2d() const; diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index b13b8a41af..feff4a6dc9 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -781,6 +781,7 @@ void register_scene_types() { ParticleProcessMaterial::init_shaders(); GDREGISTER_VIRTUAL_CLASS(Mesh); + GDREGISTER_CLASS(MeshConvexDecompositionSettings); GDREGISTER_CLASS(ArrayMesh); GDREGISTER_CLASS(PlaceholderMesh); GDREGISTER_CLASS(ImmediateMesh); diff --git a/scene/resources/convex_polygon_shape_2d.cpp b/scene/resources/convex_polygon_shape_2d.cpp index 7f19dd63e6..0d9e570149 100644 --- a/scene/resources/convex_polygon_shape_2d.cpp +++ b/scene/resources/convex_polygon_shape_2d.cpp @@ -38,11 +38,41 @@ bool ConvexPolygonShape2D::_edit_is_selected_on_click(const Point2 &p_point, dou return Geometry2D::is_point_in_polygon(p_point, points); } +#ifdef DEBUG_ENABLED +// Check if point p3 is to the left of [p1, p2] segment or on it. +bool left_test(const Vector2 &p1, const Vector2 &p2, const Vector2 &p3) { + Vector2 p12 = p2 - p1; + Vector2 p13 = p3 - p1; + // If the value of the cross product is positive or zero; p3 is to the left or on the segment, respectively. + return p12.cross(p13) >= 0; +} + +bool is_convex(const Vector<Vector2> &p_points) { + // Pre-condition: Polygon is in counter-clockwise order. + int polygon_size = p_points.size(); + for (int i = 0; i < polygon_size && polygon_size > 3; i++) { + int j = (i + 1) % polygon_size; + int k = (j + 1) % polygon_size; + // If any consecutive three points fail left-test, then there is a concavity. + if (!left_test(p_points[i], p_points[j], p_points[k])) { + return false; + } + } + + return true; +} +#endif + void ConvexPolygonShape2D::_update_shape() { Vector<Vector2> final_points = points; if (Geometry2D::is_polygon_clockwise(final_points)) { //needs to be counter clockwise final_points.reverse(); } +#ifdef DEBUG_ENABLED + if (!is_convex(final_points)) { + WARN_PRINT("Concave polygon is assigned to ConvexPolygonShape2D."); + } +#endif PhysicsServer2D::get_singleton()->shape_set_data(get_rid(), final_points); emit_changed(); } diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 4c7525c745..8addcea215 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -162,7 +162,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_font("font", "Button", Ref<Font>()); theme->set_font_size("font_size", "Button", -1); - theme->set_constant("outline_size", "Button", 0 * scale); + theme->set_constant("outline_size", "Button", 0); theme->set_color("font_color", "Button", control_font_color); theme->set_color("font_pressed_color", "Button", control_font_pressed_color); @@ -191,7 +191,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_font("font", "MenuBar", Ref<Font>()); theme->set_font_size("font_size", "MenuBar", -1); - theme->set_constant("outline_size", "MenuBar", 0 * scale); + theme->set_constant("outline_size", "MenuBar", 0); theme->set_color("font_color", "MenuBar", control_font_color); theme->set_color("font_pressed_color", "MenuBar", control_font_pressed_color); @@ -316,7 +316,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_color("font_outline_color", "CheckBox", Color(1, 1, 1)); theme->set_constant("h_separation", "CheckBox", 4 * scale); - theme->set_constant("check_v_offset", "CheckBox", 0 * scale); + theme->set_constant("check_v_offset", "CheckBox", 0); theme->set_constant("outline_size", "CheckBox", 0); // CheckButton @@ -353,7 +353,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_color("font_outline_color", "CheckButton", Color(1, 1, 1)); theme->set_constant("h_separation", "CheckButton", 4 * scale); - theme->set_constant("check_v_offset", "CheckButton", 0 * scale); + theme->set_constant("check_v_offset", "CheckButton", 0); theme->set_constant("outline_size", "CheckButton", 0); // Label @@ -783,6 +783,12 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("scroll_speed", "Tree", 12); theme->set_constant("outline_size", "Tree", 0); theme->set_constant("icon_max_width", "Tree", 0); + theme->set_constant("scrollbar_margin_left", "Tree", -1); + theme->set_constant("scrollbar_margin_top", "Tree", -1); + theme->set_constant("scrollbar_margin_right", "Tree", -1); + theme->set_constant("scrollbar_margin_bottom", "Tree", -1); + theme->set_constant("scrollbar_h_separation", "Tree", 4 * scale); + theme->set_constant("scrollbar_v_separation", "Tree", 4 * scale); // ItemList @@ -1039,7 +1045,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("shadow_offset_y", "RichTextLabel", 1 * scale); theme->set_constant("shadow_outline_size", "RichTextLabel", 1 * scale); - theme->set_constant("line_separation", "RichTextLabel", 0 * scale); + theme->set_constant("line_separation", "RichTextLabel", 0); theme->set_constant("table_h_separation", "RichTextLabel", 3 * scale); theme->set_constant("table_v_separation", "RichTextLabel", 3 * scale); @@ -1062,10 +1068,10 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("separation", "BoxContainer", 4 * scale); theme->set_constant("separation", "HBoxContainer", 4 * scale); theme->set_constant("separation", "VBoxContainer", 4 * scale); - theme->set_constant("margin_left", "MarginContainer", 0 * scale); - theme->set_constant("margin_top", "MarginContainer", 0 * scale); - theme->set_constant("margin_right", "MarginContainer", 0 * scale); - theme->set_constant("margin_bottom", "MarginContainer", 0 * scale); + theme->set_constant("margin_left", "MarginContainer", 0); + theme->set_constant("margin_top", "MarginContainer", 0); + theme->set_constant("margin_right", "MarginContainer", 0); + theme->set_constant("margin_bottom", "MarginContainer", 0); theme->set_constant("h_separation", "GridContainer", 4 * scale); theme->set_constant("v_separation", "GridContainer", 4 * scale); theme->set_constant("separation", "SplitContainer", 12 * scale); diff --git a/scene/resources/importer_mesh.cpp b/scene/resources/importer_mesh.cpp index 0fc72ca90f..09738757fd 100644 --- a/scene/resources/importer_mesh.cpp +++ b/scene/resources/importer_mesh.cpp @@ -938,7 +938,7 @@ Vector<Face3> ImporterMesh::get_faces() const { return faces; } -Vector<Ref<Shape3D>> ImporterMesh::convex_decompose(const Mesh::ConvexDecompositionSettings &p_settings) const { +Vector<Ref<Shape3D>> ImporterMesh::convex_decompose(const Ref<MeshConvexDecompositionSettings> &p_settings) const { ERR_FAIL_COND_V(!Mesh::convex_decomposition_function, Vector<Ref<Shape3D>>()); const Vector<Face3> faces = get_faces(); @@ -987,8 +987,9 @@ Vector<Ref<Shape3D>> ImporterMesh::convex_decompose(const Mesh::ConvexDecomposit Ref<ConvexPolygonShape3D> ImporterMesh::create_convex_shape(bool p_clean, bool p_simplify) const { if (p_simplify) { - Mesh::ConvexDecompositionSettings settings; - settings.max_convex_hulls = 1; + Ref<MeshConvexDecompositionSettings> settings; + settings.instantiate(); + settings->set_max_convex_hulls(1); Vector<Ref<Shape3D>> decomposed = convex_decompose(settings); if (decomposed.size() == 1) { return decomposed[0]; diff --git a/scene/resources/importer_mesh.h b/scene/resources/importer_mesh.h index 33d0864342..69becc46a3 100644 --- a/scene/resources/importer_mesh.h +++ b/scene/resources/importer_mesh.h @@ -118,7 +118,7 @@ public: Ref<ImporterMesh> get_shadow_mesh() const; Vector<Face3> get_faces() const; - Vector<Ref<Shape3D>> convex_decompose(const Mesh::ConvexDecompositionSettings &p_settings) const; + Vector<Ref<Shape3D>> convex_decompose(const Ref<MeshConvexDecompositionSettings> &p_settings) const; Ref<ConvexPolygonShape3D> create_convex_shape(bool p_clean = true, bool p_simplify = false) const; Ref<ConcavePolygonShape3D> create_trimesh_shape() const; Ref<NavigationMesh> create_navigation_mesh(); diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index a7b53244e2..8a91e9f6e0 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -37,6 +37,168 @@ #include "scene/resources/concave_polygon_shape_3d.h" #include "scene/resources/convex_polygon_shape_3d.h" +void MeshConvexDecompositionSettings::set_max_concavity(real_t p_max_concavity) { + max_concavity = CLAMP(p_max_concavity, 0.001, 1.0); +} + +real_t MeshConvexDecompositionSettings::get_max_concavity() const { + return max_concavity; +}; + +void MeshConvexDecompositionSettings::set_symmetry_planes_clipping_bias(real_t p_symmetry_planes_clipping_bias) { + symmetry_planes_clipping_bias = CLAMP(p_symmetry_planes_clipping_bias, 0.0, 1.0); +}; + +real_t MeshConvexDecompositionSettings::get_symmetry_planes_clipping_bias() const { + return symmetry_planes_clipping_bias; +}; + +void MeshConvexDecompositionSettings::set_revolution_axes_clipping_bias(real_t p_revolution_axes_clipping_bias) { + revolution_axes_clipping_bias = CLAMP(p_revolution_axes_clipping_bias, 0.0, 1.0); +}; + +real_t MeshConvexDecompositionSettings::get_revolution_axes_clipping_bias() const { + return revolution_axes_clipping_bias; +}; + +void MeshConvexDecompositionSettings::set_min_volume_per_convex_hull(real_t p_min_volume_per_convex_hull) { + min_volume_per_convex_hull = CLAMP(p_min_volume_per_convex_hull, 0.0001, 0.01); +} + +real_t MeshConvexDecompositionSettings::get_min_volume_per_convex_hull() const { + return min_volume_per_convex_hull; +} + +void MeshConvexDecompositionSettings::set_resolution(uint32_t p_resolution) { + resolution = p_resolution < 10'000 ? 10'000 : (p_resolution > 100'000 ? 100'000 : p_resolution); +} + +uint32_t MeshConvexDecompositionSettings::get_resolution() const { + return resolution; +} + +void MeshConvexDecompositionSettings::set_max_num_vertices_per_convex_hull(uint32_t p_max_num_vertices_per_convex_hull) { + max_num_vertices_per_convex_hull = p_max_num_vertices_per_convex_hull < 4 ? 4 : (p_max_num_vertices_per_convex_hull > 1024 ? 1024 : p_max_num_vertices_per_convex_hull); +} + +uint32_t MeshConvexDecompositionSettings::get_max_num_vertices_per_convex_hull() const { + return max_num_vertices_per_convex_hull; +} + +void MeshConvexDecompositionSettings::set_plane_downsampling(uint32_t p_plane_downsampling) { + plane_downsampling = p_plane_downsampling < 1 ? 1 : (p_plane_downsampling > 16 ? 16 : p_plane_downsampling); +} + +uint32_t MeshConvexDecompositionSettings::get_plane_downsampling() const { + return plane_downsampling; +} + +void MeshConvexDecompositionSettings::set_convex_hull_downsampling(uint32_t p_convex_hull_downsampling) { + convex_hull_downsampling = p_convex_hull_downsampling < 1 ? 1 : (p_convex_hull_downsampling > 16 ? 16 : p_convex_hull_downsampling); +} + +uint32_t MeshConvexDecompositionSettings::get_convex_hull_downsampling() const { + return convex_hull_downsampling; +} + +void MeshConvexDecompositionSettings::set_normalize_mesh(bool p_normalize_mesh) { + normalize_mesh = p_normalize_mesh; +} + +bool MeshConvexDecompositionSettings::get_normalize_mesh() const { + return normalize_mesh; +} + +void MeshConvexDecompositionSettings::set_mode(Mode p_mode) { + mode = p_mode; +} + +MeshConvexDecompositionSettings::Mode MeshConvexDecompositionSettings::get_mode() const { + return mode; +} + +void MeshConvexDecompositionSettings::set_convex_hull_approximation(bool p_convex_hull_approximation) { + convex_hull_approximation = p_convex_hull_approximation; +} + +bool MeshConvexDecompositionSettings::get_convex_hull_approximation() const { + return convex_hull_approximation; +} + +void MeshConvexDecompositionSettings::set_max_convex_hulls(uint32_t p_max_convex_hulls) { + max_convex_hulls = p_max_convex_hulls < 1 ? 1 : (p_max_convex_hulls > 32 ? 32 : p_max_convex_hulls); +} + +uint32_t MeshConvexDecompositionSettings::get_max_convex_hulls() const { + return max_convex_hulls; +} + +void MeshConvexDecompositionSettings::set_project_hull_vertices(bool p_project_hull_vertices) { + project_hull_vertices = p_project_hull_vertices; +} + +bool MeshConvexDecompositionSettings::get_project_hull_vertices() const { + return project_hull_vertices; +} + +void MeshConvexDecompositionSettings::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_max_concavity", "max_concavity"), &MeshConvexDecompositionSettings::set_max_concavity); + ClassDB::bind_method(D_METHOD("get_max_concavity"), &MeshConvexDecompositionSettings::get_max_concavity); + + ClassDB::bind_method(D_METHOD("set_symmetry_planes_clipping_bias", "symmetry_planes_clipping_bias"), &MeshConvexDecompositionSettings::set_symmetry_planes_clipping_bias); + ClassDB::bind_method(D_METHOD("get_symmetry_planes_clipping_bias"), &MeshConvexDecompositionSettings::get_symmetry_planes_clipping_bias); + + ClassDB::bind_method(D_METHOD("set_revolution_axes_clipping_bias", "revolution_axes_clipping_bias"), &MeshConvexDecompositionSettings::set_revolution_axes_clipping_bias); + ClassDB::bind_method(D_METHOD("get_revolution_axes_clipping_bias"), &MeshConvexDecompositionSettings::get_revolution_axes_clipping_bias); + + ClassDB::bind_method(D_METHOD("set_min_volume_per_convex_hull", "min_volume_per_convex_hull"), &MeshConvexDecompositionSettings::set_min_volume_per_convex_hull); + ClassDB::bind_method(D_METHOD("get_min_volume_per_convex_hull"), &MeshConvexDecompositionSettings::get_min_volume_per_convex_hull); + + ClassDB::bind_method(D_METHOD("set_resolution", "min_volume_per_convex_hull"), &MeshConvexDecompositionSettings::set_resolution); + ClassDB::bind_method(D_METHOD("get_resolution"), &MeshConvexDecompositionSettings::get_resolution); + + ClassDB::bind_method(D_METHOD("set_max_num_vertices_per_convex_hull", "max_num_vertices_per_convex_hull"), &MeshConvexDecompositionSettings::set_max_num_vertices_per_convex_hull); + ClassDB::bind_method(D_METHOD("get_max_num_vertices_per_convex_hull"), &MeshConvexDecompositionSettings::get_max_num_vertices_per_convex_hull); + + ClassDB::bind_method(D_METHOD("set_plane_downsampling", "plane_downsampling"), &MeshConvexDecompositionSettings::set_plane_downsampling); + ClassDB::bind_method(D_METHOD("get_plane_downsampling"), &MeshConvexDecompositionSettings::get_plane_downsampling); + + ClassDB::bind_method(D_METHOD("set_convex_hull_downsampling", "convex_hull_downsampling"), &MeshConvexDecompositionSettings::set_convex_hull_downsampling); + ClassDB::bind_method(D_METHOD("get_convex_hull_downsampling"), &MeshConvexDecompositionSettings::get_convex_hull_downsampling); + + ClassDB::bind_method(D_METHOD("set_normalize_mesh", "normalize_mesh"), &MeshConvexDecompositionSettings::set_normalize_mesh); + ClassDB::bind_method(D_METHOD("get_normalize_mesh"), &MeshConvexDecompositionSettings::get_normalize_mesh); + + ClassDB::bind_method(D_METHOD("set_mode", "mode"), &MeshConvexDecompositionSettings::set_mode); + ClassDB::bind_method(D_METHOD("get_mode"), &MeshConvexDecompositionSettings::get_mode); + + ClassDB::bind_method(D_METHOD("set_convex_hull_approximation", "convex_hull_approximation"), &MeshConvexDecompositionSettings::set_convex_hull_approximation); + ClassDB::bind_method(D_METHOD("get_convex_hull_approximation"), &MeshConvexDecompositionSettings::get_convex_hull_approximation); + + ClassDB::bind_method(D_METHOD("set_max_convex_hulls", "max_convex_hulls"), &MeshConvexDecompositionSettings::set_max_convex_hulls); + ClassDB::bind_method(D_METHOD("get_max_convex_hulls"), &MeshConvexDecompositionSettings::get_max_convex_hulls); + + ClassDB::bind_method(D_METHOD("set_project_hull_vertices", "project_hull_vertices"), &MeshConvexDecompositionSettings::set_project_hull_vertices); + ClassDB::bind_method(D_METHOD("get_project_hull_vertices"), &MeshConvexDecompositionSettings::get_project_hull_vertices); + + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_concavity", PROPERTY_HINT_RANGE, "0.001,1.0,0.001"), "set_max_concavity", "get_max_concavity"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "symmetry_planes_clipping_bias", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_symmetry_planes_clipping_bias", "get_symmetry_planes_clipping_bias"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "revolution_axes_clipping_bias", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_revolution_axes_clipping_bias", "get_revolution_axes_clipping_bias"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "min_volume_per_convex_hull", PROPERTY_HINT_RANGE, "0.0001,0.01,0.0001"), "set_min_volume_per_convex_hull", "get_min_volume_per_convex_hull"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "resolution"), "set_resolution", "get_resolution"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "max_num_vertices_per_convex_hull"), "set_max_num_vertices_per_convex_hull", "get_max_num_vertices_per_convex_hull"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "plane_downsampling", PROPERTY_HINT_RANGE, "1,16,1"), "set_plane_downsampling", "get_plane_downsampling"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "convex_hull_downsampling", PROPERTY_HINT_RANGE, "1,16,1"), "set_convex_hull_downsampling", "get_convex_hull_downsampling"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "normalize_mesh"), "set_normalize_mesh", "get_normalize_mesh"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Voxel,Tetrahedron"), "set_mode", "get_mode"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "convex_hull_approximation"), "set_convex_hull_approximation", "get_convex_hull_approximation"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "max_convex_hulls"), "set_max_convex_hulls", "get_max_convex_hulls"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "project_hull_vertices"), "set_project_hull_vertices", "get_project_hull_vertices"); + + BIND_ENUM_CONSTANT(CONVEX_DECOMPOSITION_MODE_VOXEL); + BIND_ENUM_CONSTANT(CONVEX_DECOMPOSITION_MODE_TETRAHEDRON); +} + Mesh::ConvexDecompositionFunc Mesh::convex_decomposition_function = nullptr; int Mesh::get_surface_count() const { @@ -355,8 +517,10 @@ Vector<Face3> Mesh::get_surface_faces(int p_surface) const { Ref<ConvexPolygonShape3D> Mesh::create_convex_shape(bool p_clean, bool p_simplify) const { if (p_simplify) { - ConvexDecompositionSettings settings; - settings.max_convex_hulls = 1; + Ref<MeshConvexDecompositionSettings> settings = Ref<MeshConvexDecompositionSettings>(); + settings.instantiate(); + settings->set_max_convex_hulls(1); + settings->set_max_concavity(1.0); Vector<Ref<Shape3D>> decomposed = convex_decompose(settings); if (decomposed.size() == 1) { return decomposed[0]; @@ -725,7 +889,7 @@ void Mesh::clear_cache() const { debug_lines.clear(); } -Vector<Ref<Shape3D>> Mesh::convex_decompose(const ConvexDecompositionSettings &p_settings) const { +Vector<Ref<Shape3D>> Mesh::convex_decompose(const Ref<MeshConvexDecompositionSettings> &p_settings) const { ERR_FAIL_COND_V(!convex_decomposition_function, Vector<Ref<Shape3D>>()); Ref<TriangleMesh> tm = generate_triangle_mesh(); diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index 1b870d996a..4d9b9b4087 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -39,6 +39,7 @@ class ConcavePolygonShape3D; class ConvexPolygonShape3D; +class MeshConvexDecompositionSettings; class Shape3D; class Mesh : public Resource { @@ -178,42 +179,11 @@ public: Size2i get_lightmap_size_hint() const; void clear_cache() const; - struct ConvexDecompositionSettings { - enum Mode : int { - CONVEX_DECOMPOSITION_MODE_VOXEL = 0, - CONVEX_DECOMPOSITION_MODE_TETRAHEDRON - }; - - /// Maximum concavity. [Range: 0.0 -> 1.0] - real_t max_concavity = 1.0; - /// Controls the bias toward clipping along symmetry planes. [Range: 0.0 -> 1.0] - real_t symmetry_planes_clipping_bias = 0.05; - /// Controls the bias toward clipping along revolution axes. [Range: 0.0 -> 1.0] - real_t revolution_axes_clipping_bias = 0.05; - real_t min_volume_per_convex_hull = 0.0001; - /// Maximum number of voxels generated during the voxelization stage. - uint32_t resolution = 10'000; - uint32_t max_num_vertices_per_convex_hull = 32; - /// Controls the granularity of the search for the "best" clipping plane. - /// [Range: 1 -> 16] - uint32_t plane_downsampling = 4; - /// Controls the precision of the convex-hull generation process during the - /// clipping plane selection stage. - /// [Range: 1 -> 16] - uint32_t convexhull_downsampling = 4; - /// enable/disable normalizing the mesh before applying the convex decomposition. - bool normalize_mesh = false; - Mode mode = CONVEX_DECOMPOSITION_MODE_VOXEL; - bool convexhull_approximation = true; - /// This is the maximum number of convex hulls to produce from the merge operation. - uint32_t max_convex_hulls = 1; - bool project_hull_vertices = true; - }; - typedef Vector<Vector<Vector3>> (*ConvexDecompositionFunc)(const real_t *p_vertices, int p_vertex_count, const uint32_t *p_triangles, int p_triangle_count, const ConvexDecompositionSettings &p_settings, Vector<Vector<uint32_t>> *r_convex_indices); + typedef Vector<Vector<Vector3>> (*ConvexDecompositionFunc)(const real_t *p_vertices, int p_vertex_count, const uint32_t *p_triangles, int p_triangle_count, const Ref<MeshConvexDecompositionSettings> &p_settings, Vector<Vector<uint32_t>> *r_convex_indices); static ConvexDecompositionFunc convex_decomposition_function; - Vector<Ref<Shape3D>> convex_decompose(const ConvexDecompositionSettings &p_settings) const; + Vector<Ref<Shape3D>> convex_decompose(const Ref<MeshConvexDecompositionSettings> &p_settings) const; Ref<ConvexPolygonShape3D> create_convex_shape(bool p_clean = true, bool p_simplify = false) const; Ref<ConcavePolygonShape3D> create_trimesh_shape() const; @@ -225,6 +195,89 @@ public: Mesh(); }; +class MeshConvexDecompositionSettings : public RefCounted { + GDCLASS(MeshConvexDecompositionSettings, RefCounted); + +public: + enum Mode : int { + CONVEX_DECOMPOSITION_MODE_VOXEL = 0, + CONVEX_DECOMPOSITION_MODE_TETRAHEDRON = 1 + }; + +private: + Mode mode = CONVEX_DECOMPOSITION_MODE_VOXEL; + + /// Maximum concavity. [Range: 0.0 -> 1.0] + real_t max_concavity = 1.0; + /// Controls the bias toward clipping along symmetry planes. [Range: 0.0 -> 1.0] + real_t symmetry_planes_clipping_bias = 0.05; + /// Controls the bias toward clipping along revolution axes. [Range: 0.0 -> 1.0] + real_t revolution_axes_clipping_bias = 0.05; + real_t min_volume_per_convex_hull = 0.0001; + /// Maximum number of voxels generated during the voxelization stage. + uint32_t resolution = 10'000; + uint32_t max_num_vertices_per_convex_hull = 32; + /// Controls the granularity of the search for the "best" clipping plane. + /// [Range: 1 -> 16] + uint32_t plane_downsampling = 4; + /// Controls the precision of the convex-hull generation process during the + /// clipping plane selection stage. + /// [Range: 1 -> 16] + uint32_t convex_hull_downsampling = 4; + /// enable/disable normalizing the mesh before applying the convex decomposition. + bool normalize_mesh = false; + + bool convex_hull_approximation = true; + /// This is the maximum number of convex hulls to produce from the merge operation. + uint32_t max_convex_hulls = 1; + bool project_hull_vertices = true; + +protected: + static void _bind_methods(); + +public: + void set_max_concavity(real_t p_max_concavity); + real_t get_max_concavity() const; + + void set_symmetry_planes_clipping_bias(real_t p_symmetry_planes_clipping_bias); + real_t get_symmetry_planes_clipping_bias() const; + + void set_revolution_axes_clipping_bias(real_t p_revolution_axes_clipping_bias); + real_t get_revolution_axes_clipping_bias() const; + + void set_min_volume_per_convex_hull(real_t p_min_volume_per_convex_hull); + real_t get_min_volume_per_convex_hull() const; + + void set_resolution(uint32_t p_resolution); + uint32_t get_resolution() const; + + void set_max_num_vertices_per_convex_hull(uint32_t p_max_num_vertices_per_convex_hull); + uint32_t get_max_num_vertices_per_convex_hull() const; + + void set_plane_downsampling(uint32_t p_plane_downsampling); + uint32_t get_plane_downsampling() const; + + void set_convex_hull_downsampling(uint32_t p_convex_hull_downsampling); + uint32_t get_convex_hull_downsampling() const; + + void set_normalize_mesh(bool p_normalize_mesh); + bool get_normalize_mesh() const; + + void set_mode(Mode p_mode); + Mode get_mode() const; + + void set_convex_hull_approximation(bool p_convex_hull_approximation); + bool get_convex_hull_approximation() const; + + void set_max_convex_hulls(uint32_t p_max_convex_hulls); + uint32_t get_max_convex_hulls() const; + + void set_project_hull_vertices(bool p_project_hull_vertices); + bool get_project_hull_vertices() const; +}; + +VARIANT_ENUM_CAST(MeshConvexDecompositionSettings::Mode); + class ArrayMesh : public Mesh { GDCLASS(ArrayMesh, Mesh); RES_BASE_EXTENSION("mesh"); diff --git a/scene/resources/syntax_highlighter.cpp b/scene/resources/syntax_highlighter.cpp index 05a8cf2dc7..903be41c26 100644 --- a/scene/resources/syntax_highlighter.cpp +++ b/scene/resources/syntax_highlighter.cpp @@ -99,7 +99,7 @@ void SyntaxHighlighter::set_text_edit(TextEdit *p_text_edit) { update_cache(); } -TextEdit *SyntaxHighlighter::get_text_edit() { +TextEdit *SyntaxHighlighter::get_text_edit() const { return text_edit; } diff --git a/scene/resources/syntax_highlighter.h b/scene/resources/syntax_highlighter.h index 7cc58cbbda..bf263f9490 100644 --- a/scene/resources/syntax_highlighter.h +++ b/scene/resources/syntax_highlighter.h @@ -64,7 +64,7 @@ public: virtual void _update_cache() {} void set_text_edit(TextEdit *p_text_edit); - TextEdit *get_text_edit(); + TextEdit *get_text_edit() const; SyntaxHighlighter() {} virtual ~SyntaxHighlighter() {} diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp index 32ee650f8d..70496ee65b 100644 --- a/servers/audio/audio_stream.cpp +++ b/servers/audio/audio_stream.cpp @@ -361,7 +361,7 @@ void AudioStreamPlaybackMicrophone::start(double p_from_pos) { } if (!GLOBAL_GET("audio/driver/enable_input")) { - WARN_PRINT("Need to enable Project settings > Audio > Enable Audio Input option to use capturing."); + WARN_PRINT("You must enable the project setting \"audio/driver/enable_input\" to use audio capture."); return; } diff --git a/servers/physics_3d/godot_collision_solver_3d_sat.cpp b/servers/physics_3d/godot_collision_solver_3d_sat.cpp index 2cb29b3dd0..92a4d47cd3 100644 --- a/servers/physics_3d/godot_collision_solver_3d_sat.cpp +++ b/servers/physics_3d/godot_collision_solver_3d_sat.cpp @@ -2065,7 +2065,7 @@ static void _collision_convex_polygon_convex_polygon(const GodotShape3D *p_a, co int vertex_count_B = mesh_B.vertices.size(); // Precalculating this makes the transforms faster. - Basis a_xform_normal = p_transform_b.basis.inverse().transposed(); + Basis a_xform_normal = p_transform_a.basis.inverse().transposed(); // faces of A for (int i = 0; i < face_count_A; i++) { diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp index 4ad83ef327..fb5092e498 100644 --- a/servers/physics_server_2d.cpp +++ b/servers/physics_server_2d.cpp @@ -893,7 +893,7 @@ PhysicsServer2D::PhysicsServer2D() { GLOBAL_DEF(PropertyInfo(Variant::INT, "physics/2d/solver/solver_iterations", PROPERTY_HINT_RANGE, "1,32,1,or_greater"), 16); GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/2d/solver/contact_recycle_radius", PROPERTY_HINT_RANGE, "0,10,0.01,or_greater"), 1.0); GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/2d/solver/contact_max_separation", PROPERTY_HINT_RANGE, "0,10,0.01,or_greater"), 1.5); - GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/2d/solver/contact_max_allowed_penetration", PROPERTY_HINT_RANGE, "0,10,0.01,or_greater"), 0.3); + GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/2d/solver/contact_max_allowed_penetration", PROPERTY_HINT_RANGE, "0.01,10,0.01,or_greater"), 0.3); GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/2d/solver/default_contact_bias", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.8); GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/2d/solver/default_constraint_bias", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.2); } diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp index 9495ce2262..ee749de1c6 100644 --- a/servers/physics_server_3d.cpp +++ b/servers/physics_server_3d.cpp @@ -1059,9 +1059,9 @@ PhysicsServer3D::PhysicsServer3D() { GLOBAL_DEF("physics/3d/sleep_threshold_angular", Math::deg_to_rad(8.0)); GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/3d/time_before_sleep", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater"), 0.5); GLOBAL_DEF(PropertyInfo(Variant::INT, "physics/3d/solver/solver_iterations", PROPERTY_HINT_RANGE, "1,32,1,or_greater"), 16); - GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/3d/solver/contact_recycle_radius", PROPERTY_HINT_RANGE, "0,0.1,0.01,or_greater"), 0.01); - GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/3d/solver/contact_max_separation", PROPERTY_HINT_RANGE, "0,0.1,0.01,or_greater"), 0.05); - GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/3d/solver/contact_max_allowed_penetration", PROPERTY_HINT_RANGE, "0,0.1,0.01,or_greater"), 0.01); + GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/3d/solver/contact_recycle_radius", PROPERTY_HINT_RANGE, "0,0.1,0.001,or_greater"), 0.01); + GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/3d/solver/contact_max_separation", PROPERTY_HINT_RANGE, "0,0.1,0.001,or_greater"), 0.05); + GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/3d/solver/contact_max_allowed_penetration", PROPERTY_HINT_RANGE, "0.001,0.1,0.001,or_greater"), 0.01); GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/3d/solver/default_contact_bias", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.8); } diff --git a/servers/rendering/renderer_rd/environment/sky.cpp b/servers/rendering/renderer_rd/environment/sky.cpp index ed0a67f72a..f79d6d311e 100644 --- a/servers/rendering/renderer_rd/environment/sky.cpp +++ b/servers/rendering/renderer_rd/environment/sky.cpp @@ -1619,7 +1619,7 @@ void SkyRD::update_dirty_skys() { if (sky->mode == RS::SKY_MODE_REALTIME) { layers = 8; if (roughness_layers != 8) { - WARN_PRINT("When using REALTIME skies, roughness_layers should be set to 8 in the project settings for best quality reflections"); + WARN_PRINT("When using the Real-Time sky update mode (or Automatic with a sky shader using \"TIME\"), \"rendering/reflections/sky_reflections/roughness_layers\" should be set to 8 in the project settings for best quality reflections."); } } diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index f49d8be37a..5c6f630355 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -1866,7 +1866,7 @@ void RendererCanvasRenderRD::occluder_polygon_set_shape(RID p_occluder, const Ve } } - if (oc->line_point_count != lines.size() && oc->vertex_array.is_valid()) { + if ((oc->line_point_count != lines.size() || lines.size() == 0) && oc->vertex_array.is_valid()) { RD::get_singleton()->free(oc->vertex_array); RD::get_singleton()->free(oc->vertex_buffer); RD::get_singleton()->free(oc->index_array); @@ -1881,6 +1881,7 @@ void RendererCanvasRenderRD::occluder_polygon_set_shape(RID p_occluder, const Ve } if (lines.size()) { + oc->line_point_count = lines.size(); Vector<uint8_t> geometry; Vector<uint8_t> indices; int lc = lines.size(); @@ -1971,7 +1972,7 @@ void RendererCanvasRenderRD::occluder_polygon_set_shape(RID p_occluder, const Ve } } - if (oc->sdf_index_count != sdf_indices.size() && oc->sdf_point_count != p_points.size() && oc->sdf_vertex_array.is_valid()) { + if (((oc->sdf_index_count != sdf_indices.size() && oc->sdf_point_count != p_points.size()) || p_points.size() == 0) && oc->sdf_vertex_array.is_valid()) { RD::get_singleton()->free(oc->sdf_vertex_array); RD::get_singleton()->free(oc->sdf_vertex_buffer); RD::get_singleton()->free(oc->sdf_index_array); diff --git a/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl index 631d1968b0..1626244b0a 100644 --- a/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl @@ -263,9 +263,8 @@ void main() { // Schlick term. float metallic = texelFetch(source_metallic, ssC << 1, 0).w; - float f0 = mix(0.04, 1.0, metallic); // Assume a "specular" amount of 0.5 - normal.y = -normal.y; - float m = clamp(1.0 - dot(normalize(normal), -view_dir), 0.0, 1.0); + float f0 = mix(0.04, 0.37, metallic); // The default value of R0 is 0.04 and the maximum value is considered to be Germanium with R0 value of 0.37 + float m = clamp(1.0 - dot(normal, -view_dir), 0.0, 1.0); float m2 = m * m; m = m2 * m2 * m; // pow(m,5) final_color.a *= f0 + (1.0 - f0) * m; // Fresnel Schlick term. diff --git a/servers/rendering/renderer_rd/shaders/environment/sky.glsl b/servers/rendering/renderer_rd/shaders/environment/sky.glsl index bf974a3fd5..e8e5de7020 100644 --- a/servers/rendering/renderer_rd/shaders/environment/sky.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/sky.glsl @@ -260,6 +260,10 @@ void main() { frag_color.rgb = color; frag_color.a = alpha; + // For mobile renderer we're multiplying by 0.5 as we're using a UNORM buffer. + // For both mobile and clustered, we also bake in the exposure value for the environment and camera. + frag_color.rgb = frag_color.rgb * params.luminance_multiplier; + #if !defined(DISABLE_FOG) && !defined(USE_CUBEMAP_PASS) // Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky. @@ -285,10 +289,6 @@ void main() { frag_color.a = 0.0; } - // For mobile renderer we're multiplying by 0.5 as we're using a UNORM buffer. - // For both mobile and clustered, we also bake in the exposure value for the environment and camera. - frag_color.rgb = frag_color.rgb * params.luminance_multiplier; - #ifdef USE_DEBANDING frag_color.rgb += interleaved_gradient_noise(gl_FragCoord.xy); #endif diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 084fb64a53..12e99ba606 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -10529,36 +10529,42 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_ r_options->push_back(option); } - } else if ((int(completion_base) > int(TYPE_MAT4) && int(completion_base) < int(TYPE_STRUCT)) && !completion_base_array) { + } else if ((int(completion_base) > int(TYPE_MAT4) && int(completion_base) < int(TYPE_STRUCT))) { Vector<String> options; - if (current_uniform_filter == FILTER_DEFAULT) { - options.push_back("filter_linear"); - options.push_back("filter_linear_mipmap"); - options.push_back("filter_linear_mipmap_anisotropic"); - options.push_back("filter_nearest"); - options.push_back("filter_nearest_mipmap"); - options.push_back("filter_nearest_mipmap_anisotropic"); - } - if (current_uniform_hint == ShaderNode::Uniform::HINT_NONE) { - options.push_back("hint_anisotropy"); - options.push_back("hint_default_black"); - options.push_back("hint_default_white"); - options.push_back("hint_default_transparent"); - options.push_back("hint_normal"); - options.push_back("hint_roughness_a"); - options.push_back("hint_roughness_b"); - options.push_back("hint_roughness_g"); - options.push_back("hint_roughness_gray"); - options.push_back("hint_roughness_normal"); - options.push_back("hint_roughness_r"); - options.push_back("hint_screen_texture"); - options.push_back("hint_normal_roughness_texture"); - options.push_back("hint_depth_texture"); - options.push_back("source_color"); - } - if (current_uniform_repeat == REPEAT_DEFAULT) { - options.push_back("repeat_enable"); - options.push_back("repeat_disable"); + if (completion_base_array) { + if (current_uniform_hint == ShaderNode::Uniform::HINT_NONE) { + options.push_back("source_color"); + } + } else { + if (current_uniform_filter == FILTER_DEFAULT) { + options.push_back("filter_linear"); + options.push_back("filter_linear_mipmap"); + options.push_back("filter_linear_mipmap_anisotropic"); + options.push_back("filter_nearest"); + options.push_back("filter_nearest_mipmap"); + options.push_back("filter_nearest_mipmap_anisotropic"); + } + if (current_uniform_hint == ShaderNode::Uniform::HINT_NONE) { + options.push_back("hint_anisotropy"); + options.push_back("hint_default_black"); + options.push_back("hint_default_white"); + options.push_back("hint_default_transparent"); + options.push_back("hint_normal"); + options.push_back("hint_roughness_a"); + options.push_back("hint_roughness_b"); + options.push_back("hint_roughness_g"); + options.push_back("hint_roughness_gray"); + options.push_back("hint_roughness_normal"); + options.push_back("hint_roughness_r"); + options.push_back("hint_screen_texture"); + options.push_back("hint_normal_roughness_texture"); + options.push_back("hint_depth_texture"); + options.push_back("source_color"); + } + if (current_uniform_repeat == REPEAT_DEFAULT) { + options.push_back("repeat_enable"); + options.push_back("repeat_disable"); + } } for (int i = 0; i < options.size(); i++) { diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index d88cbec13b..36bc36e011 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -140,9 +140,9 @@ RID RenderingServer::get_test_texture() { c.b = y; } - w[(y * TEST_TEXTURE_SIZE + x) * 3 + 0] = uint8_t(CLAMP(c.r * 255, 0, 255)); - w[(y * TEST_TEXTURE_SIZE + x) * 3 + 1] = uint8_t(CLAMP(c.g * 255, 0, 255)); - w[(y * TEST_TEXTURE_SIZE + x) * 3 + 2] = uint8_t(CLAMP(c.b * 255, 0, 255)); + w[(y * TEST_TEXTURE_SIZE + x) * 3 + 0] = uint8_t(CLAMP(c.r, 0, 255)); + w[(y * TEST_TEXTURE_SIZE + x) * 3 + 1] = uint8_t(CLAMP(c.g, 0, 255)); + w[(y * TEST_TEXTURE_SIZE + x) * 3 + 2] = uint8_t(CLAMP(c.b, 0, 255)); } } } diff --git a/tests/core/string/test_string.h b/tests/core/string/test_string.h index 5d19b5a164..abe9f78ccc 100644 --- a/tests/core/string/test_string.h +++ b/tests/core/string/test_string.h @@ -1678,8 +1678,8 @@ TEST_CASE("[String] validate_node_name") { String name_with_kana = U"Name with kana ゴドツ"; CHECK(name_with_kana.validate_node_name() == U"Name with kana ゴドツ"); - String name_with_invalid_chars = "Name with invalid characters :.@removed!"; - CHECK(name_with_invalid_chars.validate_node_name() == "Name with invalid characters removed!"); + String name_with_invalid_chars = "Name with invalid characters :.@%removed!"; + CHECK(name_with_invalid_chars.validate_node_name() == "Name with invalid characters ____removed!"); } TEST_CASE("[String] validate_identifier") { |