diff options
416 files changed, 10498 insertions, 4816 deletions
diff --git a/SConstruct b/SConstruct index 4972b21421..46942ca3b4 100644 --- a/SConstruct +++ b/SConstruct @@ -444,9 +444,12 @@ if selected_platform in platform_list: scons_ver = env._get_major_minor_revision(scons_raw_version) - if scons_ver >= (4, 0, 0): - env.Tool("compilation_db") - env.Alias("compiledb", env.CompilationDatabase()) + if scons_ver < (4, 0, 0): + print("The `compiledb=yes` option requires SCons 4.0 or later, but your version is %s." % scons_raw_version) + Exit(255) + + env.Tool("compilation_db") + env.Alias("compiledb", env.CompilationDatabase()) # 'dev' and 'production' are aliases to set default options if they haven't been set # manually by the user. diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 74c06123e1..6275502378 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -41,7 +41,10 @@ #include "core/os/keyboard.h" #include "core/variant/variant_parser.h" #include "core/version.h" + +#ifdef TOOLS_ENABLED #include "modules/modules_enabled.gen.h" // For mono. +#endif // TOOLS_ENABLED const String ProjectSettings::PROJECT_DATA_DIR_NAME_SUFFIX = "godot"; @@ -75,6 +78,7 @@ String ProjectSettings::get_imported_files_path() const { return get_project_data_path().path_join("imported"); } +#ifdef TOOLS_ENABLED // Returns the features that a project must have when opened with this build of Godot. // This is used by the project manager to provide the initial_settings for config/features. const PackedStringArray ProjectSettings::get_required_features() { @@ -137,6 +141,7 @@ const PackedStringArray ProjectSettings::_trim_to_supported_features(const Packe features.sort(); return features; } +#endif // TOOLS_ENABLED String ProjectSettings::localize_path(const String &p_path) const { if (resource_path.is_empty() || p_path.begins_with("res://") || p_path.begins_with("user://") || @@ -897,6 +902,7 @@ Error ProjectSettings::_save_custom_bnd(const String &p_file) { // add other par Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_custom, const Vector<String> &p_custom_features, bool p_merge_with_current) { ERR_FAIL_COND_V_MSG(p_path.is_empty(), ERR_INVALID_PARAMETER, "Project settings save path cannot be empty."); +#ifdef TOOLS_ENABLED PackedStringArray project_features = get_setting("application/config/features"); // If there is no feature list currently present, force one to generate. if (project_features.is_empty()) { @@ -924,6 +930,7 @@ Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_cust } project_features = _trim_to_supported_features(project_features); set_setting("application/config/features", project_features); +#endif // TOOLS_ENABLED RBSet<_VCSort> vclist; diff --git a/core/config/project_settings.h b/core/config/project_settings.h index c845120a26..a9af63ee39 100644 --- a/core/config/project_settings.h +++ b/core/config/project_settings.h @@ -48,8 +48,10 @@ public: //properties that are not for built in values begin from this value, so builtin ones are displayed first NO_BUILTIN_ORDER_BASE = 1 << 16 }; +#ifdef TOOLS_ENABLED const static PackedStringArray get_required_features(); const static PackedStringArray get_unsupported_features(const PackedStringArray &p_project_features); +#endif // TOOLS_ENABLED struct AutoloadInfo { StringName name; @@ -116,8 +118,10 @@ protected: Error _save_custom_bnd(const String &p_file); +#ifdef TOOLS_ENABLED const static PackedStringArray _get_supported_features(); const static PackedStringArray _trim_to_supported_features(const PackedStringArray &p_project_features); +#endif // TOOLS_ENABLED void _convert_to_last_version(int p_from_version); diff --git a/core/io/config_file.cpp b/core/io/config_file.cpp index ae421654ca..f84a95347a 100644 --- a/core/io/config_file.cpp +++ b/core/io/config_file.cpp @@ -32,6 +32,7 @@ #include "core/io/file_access_encrypted.h" #include "core/os/keyboard.h" +#include "core/string/string_builder.h" #include "core/variant/variant_parser.h" PackedStringArray ConfigFile::_get_sections() const { @@ -130,6 +131,28 @@ void ConfigFile::erase_section_key(const String &p_section, const String &p_key) } } +String ConfigFile::encode_to_text() const { + StringBuilder sb; + bool first = true; + for (const KeyValue<String, HashMap<String, Variant>> &E : values) { + if (first) { + first = false; + } else { + sb.append("\n"); + } + if (!E.key.is_empty()) { + sb.append("[" + E.key + "]\n\n"); + } + + for (const KeyValue<String, Variant> &F : E.value) { + String vstr; + VariantWriter::write_to_string(F.value, vstr); + sb.append(F.key.property_name_encode() + "=" + vstr + "\n"); + } + } + return sb.as_string(); +} + Error ConfigFile::save(const String &p_path) { Error err; Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::WRITE, &err); @@ -295,6 +318,7 @@ Error ConfigFile::_parse(const String &p_path, VariantParser::Stream *p_stream) void ConfigFile::clear() { values.clear(); } + void ConfigFile::_bind_methods() { ClassDB::bind_method(D_METHOD("set_value", "section", "key", "value"), &ConfigFile::set_value); ClassDB::bind_method(D_METHOD("get_value", "section", "key", "default"), &ConfigFile::get_value, DEFVAL(Variant())); @@ -312,6 +336,8 @@ void ConfigFile::_bind_methods() { ClassDB::bind_method(D_METHOD("parse", "data"), &ConfigFile::parse); ClassDB::bind_method(D_METHOD("save", "path"), &ConfigFile::save); + ClassDB::bind_method(D_METHOD("encode_to_text"), &ConfigFile::encode_to_text); + BIND_METHOD_ERR_RETURN_DOC("load", ERR_FILE_CANT_OPEN); ClassDB::bind_method(D_METHOD("load_encrypted", "path", "key"), &ConfigFile::load_encrypted); diff --git a/core/io/config_file.h b/core/io/config_file.h index 3b07ec52f5..f6209492b7 100644 --- a/core/io/config_file.h +++ b/core/io/config_file.h @@ -68,6 +68,8 @@ public: Error load(const String &p_path); Error parse(const String &p_data); + String encode_to_text() const; // used by exporter + void clear(); Error load_encrypted(const String &p_path, const Vector<uint8_t> &p_key); diff --git a/core/io/image.cpp b/core/io/image.cpp index 2d87523ca4..dee751eec5 100644 --- a/core/io/image.cpp +++ b/core/io/image.cpp @@ -416,8 +416,8 @@ int Image::get_height() const { return height; } -Vector2i Image::get_size() const { - return Vector2i(width, height); +Size2i Image::get_size() const { + return Size2i(width, height); } bool Image::has_mipmaps() const { diff --git a/core/io/image.h b/core/io/image.h index 9d415423be..fd264a7a38 100644 --- a/core/io/image.h +++ b/core/io/image.h @@ -209,7 +209,7 @@ private: public: int get_width() const; ///< Get image width int get_height() const; ///< Get image height - Vector2i get_size() const; + Size2i get_size() const; bool has_mipmaps() const; int get_mipmap_count() const; diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index 2f69c10218..b24c49f58d 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -510,7 +510,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int (*r_len) += sizeof(double) * 16; } } else { - ERR_FAIL_COND_V((size_t)len < sizeof(float) * 62, ERR_INVALID_DATA); + ERR_FAIL_COND_V((size_t)len < sizeof(float) * 16, ERR_INVALID_DATA); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { val.matrix[i][j] = decode_float(&buf[(i * 4 + j) * sizeof(float)]); diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp index 0af236f766..1df779d034 100644 --- a/core/io/packet_peer.cpp +++ b/core/io/packet_peer.cpp @@ -152,42 +152,24 @@ void PacketPeer::_bind_methods() { /***************/ -int PacketPeerExtension::get_available_packet_count() const { - int count; - if (GDVIRTUAL_CALL(_get_available_packet_count, count)) { - return count; - } - WARN_PRINT_ONCE("PacketPeerExtension::_get_available_packet_count is unimplemented!"); - return -1; -} - Error PacketPeerExtension::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { - int err; + Error err; if (GDVIRTUAL_CALL(_get_packet, r_buffer, &r_buffer_size, err)) { - return (Error)err; + return err; } WARN_PRINT_ONCE("PacketPeerExtension::_get_packet_native is unimplemented!"); return FAILED; } Error PacketPeerExtension::put_packet(const uint8_t *p_buffer, int p_buffer_size) { - int err; + Error err; if (GDVIRTUAL_CALL(_put_packet, p_buffer, p_buffer_size, err)) { - return (Error)err; + return err; } WARN_PRINT_ONCE("PacketPeerExtension::_put_packet_native is unimplemented!"); return FAILED; } -int PacketPeerExtension::get_max_packet_size() const { - int size; - if (GDVIRTUAL_CALL(_get_max_packet_size, size)) { - return size; - } - WARN_PRINT_ONCE("PacketPeerExtension::_get_max_packet_size is unimplemented!"); - return 0; -} - void PacketPeerExtension::_bind_methods() { GDVIRTUAL_BIND(_get_packet, "r_buffer", "r_buffer_size"); GDVIRTUAL_BIND(_put_packet, "p_buffer", "p_buffer_size"); diff --git a/core/io/packet_peer.h b/core/io/packet_peer.h index ec9d33aa5a..07045e62a6 100644 --- a/core/io/packet_peer.h +++ b/core/io/packet_peer.h @@ -35,6 +35,7 @@ #include "core/object/class_db.h" #include "core/templates/ring_buffer.h" +#include "core/extension/ext_wrappers.gen.inc" #include "core/object/gdvirtual.gen.inc" #include "core/object/script_language.h" #include "core/variant/native_ptr.h" @@ -84,16 +85,14 @@ protected: static void _bind_methods(); public: - virtual int get_available_packet_count() const override; virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size) override; ///< buffer is GONE after next get_packet + GDVIRTUAL2R(Error, _get_packet, GDNativeConstPtr<const uint8_t *>, GDNativePtr<int>); + virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size) override; - virtual int get_max_packet_size() const override; + GDVIRTUAL2R(Error, _put_packet, GDNativeConstPtr<const uint8_t>, int); - /* GDExtension */ - GDVIRTUAL0RC(int, _get_available_packet_count); - GDVIRTUAL2R(int, _get_packet, GDNativeConstPtr<const uint8_t *>, GDNativePtr<int>); - GDVIRTUAL2R(int, _put_packet, GDNativeConstPtr<const uint8_t>, int); - GDVIRTUAL0RC(int, _get_max_packet_size); + EXBIND0RC(int, get_available_packet_count); + EXBIND0RC(int, get_max_packet_size); }; class PacketPeerStream : public PacketPeer { diff --git a/core/io/stream_peer.cpp b/core/io/stream_peer.cpp index c65968ef03..053ff64069 100644 --- a/core/io/stream_peer.cpp +++ b/core/io/stream_peer.cpp @@ -410,48 +410,39 @@ void StreamPeer::_bind_methods() { //////////////////////////////// -int StreamPeerExtension::get_available_bytes() const { - int count; - if (GDVIRTUAL_CALL(_get_available_bytes, count)) { - return count; - } - WARN_PRINT_ONCE("StreamPeerExtension::_get_available_bytes is unimplemented!"); - return -1; -} - Error StreamPeerExtension::get_data(uint8_t *r_buffer, int p_bytes) { - int err; + Error err; int received = 0; if (GDVIRTUAL_CALL(_get_data, r_buffer, p_bytes, &received, err)) { - return (Error)err; + return err; } WARN_PRINT_ONCE("StreamPeerExtension::_get_data is unimplemented!"); return FAILED; } Error StreamPeerExtension::get_partial_data(uint8_t *r_buffer, int p_bytes, int &r_received) { - int err; + Error err; if (GDVIRTUAL_CALL(_get_partial_data, r_buffer, p_bytes, &r_received, err)) { - return (Error)err; + return err; } WARN_PRINT_ONCE("StreamPeerExtension::_get_partial_data is unimplemented!"); return FAILED; } Error StreamPeerExtension::put_data(const uint8_t *p_data, int p_bytes) { - int err; + Error err; int sent = 0; if (GDVIRTUAL_CALL(_put_data, p_data, p_bytes, &sent, err)) { - return (Error)err; + return err; } WARN_PRINT_ONCE("StreamPeerExtension::_put_data is unimplemented!"); return FAILED; } Error StreamPeerExtension::put_partial_data(const uint8_t *p_data, int p_bytes, int &r_sent) { - int err; + Error err; if (GDVIRTUAL_CALL(_put_data, p_data, p_bytes, &r_sent, err)) { - return (Error)err; + return err; } WARN_PRINT_ONCE("StreamPeerExtension::_put_partial_data is unimplemented!"); return FAILED; diff --git a/core/io/stream_peer.h b/core/io/stream_peer.h index 4609e52aa2..108a8ce9d9 100644 --- a/core/io/stream_peer.h +++ b/core/io/stream_peer.h @@ -33,6 +33,7 @@ #include "core/object/ref_counted.h" +#include "core/extension/ext_wrappers.gen.inc" #include "core/object/gdvirtual.gen.inc" #include "core/object/script_language.h" #include "core/variant/native_ptr.h" @@ -104,16 +105,18 @@ protected: public: virtual Error put_data(const uint8_t *p_data, int p_bytes) override; + GDVIRTUAL3R(Error, _put_data, GDNativeConstPtr<const uint8_t>, int, GDNativePtr<int>); + virtual Error put_partial_data(const uint8_t *p_data, int p_bytes, int &r_sent) override; + GDVIRTUAL3R(Error, _put_partial_data, GDNativeConstPtr<const uint8_t>, int, GDNativePtr<int>); + virtual Error get_data(uint8_t *p_buffer, int p_bytes) override; + GDVIRTUAL3R(Error, _get_data, GDNativePtr<uint8_t>, int, GDNativePtr<int>); + virtual Error get_partial_data(uint8_t *p_buffer, int p_bytes, int &r_received) override; - virtual int get_available_bytes() const override; + GDVIRTUAL3R(Error, _get_partial_data, GDNativePtr<uint8_t>, int, GDNativePtr<int>); - GDVIRTUAL3R(int, _put_data, GDNativeConstPtr<const uint8_t>, int, GDNativePtr<int>); - GDVIRTUAL3R(int, _put_partial_data, GDNativeConstPtr<const uint8_t>, int, GDNativePtr<int>); - GDVIRTUAL3R(int, _get_data, GDNativePtr<uint8_t>, int, GDNativePtr<int>); - GDVIRTUAL3R(int, _get_partial_data, GDNativePtr<uint8_t>, int, GDNativePtr<int>); - GDVIRTUAL0RC(int, _get_available_bytes); + EXBIND0RC(int, get_available_bytes); }; class StreamPeerBuffer : public StreamPeer { diff --git a/core/math/a_star_grid_2d.cpp b/core/math/a_star_grid_2d.cpp index 8db33bde6f..23d7e379ee 100644 --- a/core/math/a_star_grid_2d.cpp +++ b/core/math/a_star_grid_2d.cpp @@ -57,7 +57,7 @@ static real_t heuristic_chebyshev(const Vector2i &p_from, const Vector2i &p_to) static real_t (*heuristics[AStarGrid2D::HEURISTIC_MAX])(const Vector2i &, const Vector2i &) = { heuristic_manhattan, heuristic_euclidian, heuristic_octile, heuristic_chebyshev }; -void AStarGrid2D::set_size(const Vector2i &p_size) { +void AStarGrid2D::set_size(const Size2i &p_size) { ERR_FAIL_COND(p_size.x < 0 || p_size.y < 0); if (p_size != size) { size = p_size; @@ -65,7 +65,7 @@ void AStarGrid2D::set_size(const Vector2i &p_size) { } } -Vector2i AStarGrid2D::get_size() const { +Size2i AStarGrid2D::get_size() const { return size; } @@ -80,14 +80,14 @@ Vector2 AStarGrid2D::get_offset() const { return offset; } -void AStarGrid2D::set_cell_size(const Vector2 &p_cell_size) { +void AStarGrid2D::set_cell_size(const Size2 &p_cell_size) { if (!cell_size.is_equal_approx(p_cell_size)) { cell_size = p_cell_size; dirty = true; } } -Vector2 AStarGrid2D::get_cell_size() const { +Size2 AStarGrid2D::get_cell_size() const { return cell_size; } diff --git a/core/math/a_star_grid_2d.h b/core/math/a_star_grid_2d.h index 66312d10ac..bf6363aa01 100644 --- a/core/math/a_star_grid_2d.h +++ b/core/math/a_star_grid_2d.h @@ -58,9 +58,9 @@ public: }; private: - Vector2i size; + Size2i size; Vector2 offset; - Vector2 cell_size = Vector2(1, 1); + Size2 cell_size = Size2(1, 1); bool dirty = false; bool jumping_enabled = false; @@ -136,14 +136,14 @@ protected: GDVIRTUAL2RC(real_t, _compute_cost, Vector2i, Vector2i) public: - void set_size(const Vector2i &p_size); - Vector2i get_size() const; + void set_size(const Size2i &p_size); + Size2i get_size() const; void set_offset(const Vector2 &p_offset); Vector2 get_offset() const; - void set_cell_size(const Vector2 &p_cell_size); - Vector2 get_cell_size() const; + void set_cell_size(const Size2 &p_cell_size); + Size2 get_cell_size() const; void update(); diff --git a/core/math/basis.cpp b/core/math/basis.cpp index bc50d0e64c..0eb6320ac6 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -1033,13 +1033,13 @@ void Basis::rotate_sh(real_t *p_values) { Basis Basis::looking_at(const Vector3 &p_target, const Vector3 &p_up) { #ifdef MATH_CHECKS - ERR_FAIL_COND_V_MSG(p_target.is_equal_approx(Vector3()), Basis(), "The target vector can't be zero."); - ERR_FAIL_COND_V_MSG(p_up.is_equal_approx(Vector3()), Basis(), "The up vector can't be zero."); + ERR_FAIL_COND_V_MSG(p_target.is_zero_approx(), Basis(), "The target vector can't be zero."); + ERR_FAIL_COND_V_MSG(p_up.is_zero_approx(), Basis(), "The up vector can't be zero."); #endif Vector3 v_z = -p_target.normalized(); Vector3 v_x = p_up.cross(v_z); #ifdef MATH_CHECKS - ERR_FAIL_COND_V_MSG(v_x.is_equal_approx(Vector3()), Basis(), "The target vector and up vector can't be parallel to each other."); + ERR_FAIL_COND_V_MSG(v_x.is_zero_approx(), Basis(), "The target vector and up vector can't be parallel to each other."); #endif v_x.normalize(); Vector3 v_y = v_z.cross(v_x); diff --git a/core/math/geometry_3d.cpp b/core/math/geometry_3d.cpp index ec96753c79..9238293b48 100644 --- a/core/math/geometry_3d.cpp +++ b/core/math/geometry_3d.cpp @@ -35,6 +35,111 @@ #include "thirdparty/misc/clipper.hpp" #include "thirdparty/misc/polypartition.h" +void Geometry3D::get_closest_points_between_segments(const Vector3 &p_p0, const Vector3 &p_p1, const Vector3 &p_q0, const Vector3 &p_q1, Vector3 &r_ps, Vector3 &r_qt) { + // Based on David Eberly's Computation of Distance Between Line Segments algorithm. + + Vector3 p = p_p1 - p_p0; + Vector3 q = p_q1 - p_q0; + Vector3 r = p_p0 - p_q0; + + real_t a = p.dot(p); + real_t b = p.dot(q); + real_t c = q.dot(q); + real_t d = p.dot(r); + real_t e = q.dot(r); + + real_t s = 0.0f; + real_t t = 0.0f; + + real_t det = a * c - b * b; + if (det > CMP_EPSILON) { + // Non-parallel segments + real_t bte = b * e; + real_t ctd = c * d; + + if (bte <= ctd) { + // s <= 0.0f + if (e <= 0.0f) { + // t <= 0.0f + s = (-d >= a ? 1 : (-d > 0.0f ? -d / a : 0.0f)); + t = 0.0f; + } else if (e < c) { + // 0.0f < t < 1 + s = 0.0f; + t = e / c; + } else { + // t >= 1 + s = (b - d >= a ? 1 : (b - d > 0.0f ? (b - d) / a : 0.0f)); + t = 1; + } + } else { + // s > 0.0f + s = bte - ctd; + if (s >= det) { + // s >= 1 + if (b + e <= 0.0f) { + // t <= 0.0f + s = (-d <= 0.0f ? 0.0f : (-d < a ? -d / a : 1)); + t = 0.0f; + } else if (b + e < c) { + // 0.0f < t < 1 + s = 1; + t = (b + e) / c; + } else { + // t >= 1 + s = (b - d <= 0.0f ? 0.0f : (b - d < a ? (b - d) / a : 1)); + t = 1; + } + } else { + // 0.0f < s < 1 + real_t ate = a * e; + real_t btd = b * d; + + if (ate <= btd) { + // t <= 0.0f + s = (-d <= 0.0f ? 0.0f : (-d >= a ? 1 : -d / a)); + t = 0.0f; + } else { + // t > 0.0f + t = ate - btd; + if (t >= det) { + // t >= 1 + s = (b - d <= 0.0f ? 0.0f : (b - d >= a ? 1 : (b - d) / a)); + t = 1; + } else { + // 0.0f < t < 1 + s /= det; + t /= det; + } + } + } + } + } else { + // Parallel segments + if (e <= 0.0f) { + s = (-d <= 0.0f ? 0.0f : (-d >= a ? 1 : -d / a)); + t = 0.0f; + } else if (e >= c) { + s = (b - d <= 0.0f ? 0.0f : (b - d >= a ? 1 : (b - d) / a)); + t = 1; + } else { + s = 0.0f; + t = e / c; + } + } + + r_ps = (1 - s) * p_p0 + s * p_p1; + r_qt = (1 - t) * p_q0 + t * p_q1; +} + +real_t Geometry3D::get_closest_distance_between_segments(const Vector3 &p_p0, const Vector3 &p_p1, const Vector3 &p_q0, const Vector3 &p_q1) { + Vector3 ps; + Vector3 qt; + get_closest_points_between_segments(p_p0, p_p1, p_q0, p_q1, ps, qt); + Vector3 st = qt - ps; + return st.length(); +} + void Geometry3D::MeshData::optimize_vertices() { HashMap<int, int> vtx_remap; diff --git a/core/math/geometry_3d.h b/core/math/geometry_3d.h index 59c56906f4..e5ace9db72 100644 --- a/core/math/geometry_3d.h +++ b/core/math/geometry_3d.h @@ -37,96 +37,8 @@ class Geometry3D { public: - static void get_closest_points_between_segments(const Vector3 &p1, const Vector3 &p2, const Vector3 &q1, const Vector3 &q2, Vector3 &c1, Vector3 &c2) { -// Do the function 'd' as defined by pb. I think it's a dot product of some sort. -#define d_of(m, n, o, p) ((m.x - n.x) * (o.x - p.x) + (m.y - n.y) * (o.y - p.y) + (m.z - n.z) * (o.z - p.z)) - - // Calculate the parametric position on the 2 curves, mua and mub. - real_t mua = (d_of(p1, q1, q2, q1) * d_of(q2, q1, p2, p1) - d_of(p1, q1, p2, p1) * d_of(q2, q1, q2, q1)) / (d_of(p2, p1, p2, p1) * d_of(q2, q1, q2, q1) - d_of(q2, q1, p2, p1) * d_of(q2, q1, p2, p1)); - real_t mub = (d_of(p1, q1, q2, q1) + mua * d_of(q2, q1, p2, p1)) / d_of(q2, q1, q2, q1); - - // Clip the value between [0..1] constraining the solution to lie on the original curves. - if (mua < 0) { - mua = 0; - } - if (mub < 0) { - mub = 0; - } - if (mua > 1) { - mua = 1; - } - if (mub > 1) { - mub = 1; - } - c1 = p1.lerp(p2, mua); - c2 = q1.lerp(q2, mub); - } - - static real_t get_closest_distance_between_segments(const Vector3 &p_from_a, const Vector3 &p_to_a, const Vector3 &p_from_b, const Vector3 &p_to_b) { - Vector3 u = p_to_a - p_from_a; - Vector3 v = p_to_b - p_from_b; - Vector3 w = p_from_a - p_to_a; - real_t a = u.dot(u); // Always >= 0 - real_t b = u.dot(v); - real_t c = v.dot(v); // Always >= 0 - real_t d = u.dot(w); - real_t e = v.dot(w); - real_t D = a * c - b * b; // Always >= 0 - real_t sc, sN, sD = D; // sc = sN / sD, default sD = D >= 0 - real_t tc, tN, tD = D; // tc = tN / tD, default tD = D >= 0 - - // Compute the line parameters of the two closest points. - if (D < (real_t)CMP_EPSILON) { // The lines are almost parallel. - sN = 0.0f; // Force using point P0 on segment S1 - sD = 1.0f; // to prevent possible division by 0.0 later. - tN = e; - tD = c; - } else { // Get the closest points on the infinite lines - sN = (b * e - c * d); - tN = (a * e - b * d); - if (sN < 0.0f) { // sc < 0 => the s=0 edge is visible. - sN = 0.0f; - tN = e; - tD = c; - } else if (sN > sD) { // sc > 1 => the s=1 edge is visible. - sN = sD; - tN = e + b; - tD = c; - } - } - - if (tN < 0.0f) { // tc < 0 => the t=0 edge is visible. - tN = 0.0f; - // Recompute sc for this edge. - if (-d < 0.0f) { - sN = 0.0f; - } else if (-d > a) { - sN = sD; - } else { - sN = -d; - sD = a; - } - } else if (tN > tD) { // tc > 1 => the t=1 edge is visible. - tN = tD; - // Recompute sc for this edge. - if ((-d + b) < 0.0f) { - sN = 0; - } else if ((-d + b) > a) { - sN = sD; - } else { - sN = (-d + b); - sD = a; - } - } - // Finally do the division to get sc and tc. - sc = (Math::is_zero_approx(sN) ? 0.0f : sN / sD); - tc = (Math::is_zero_approx(tN) ? 0.0f : tN / tD); - - // Get the difference of the two closest points. - Vector3 dP = w + (sc * u) - (tc * v); // = S1(sc) - S2(tc) - - return dP.length(); // Return the closest distance. - } + static void get_closest_points_between_segments(const Vector3 &p_p0, const Vector3 &p_p1, const Vector3 &p_q0, const Vector3 &p_q1, Vector3 &r_ps, Vector3 &r_qt); + static real_t get_closest_distance_between_segments(const Vector3 &p_p0, const Vector3 &p_p1, const Vector3 &p_q0, const Vector3 &p_q1); static inline bool ray_intersects_triangle(const Vector3 &p_from, const Vector3 &p_dir, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2, Vector3 *r_res = nullptr) { Vector3 e1 = p_v1 - p_v0; diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp index d9b5d55454..56dbba393a 100644 --- a/core/math/vector2.cpp +++ b/core/math/vector2.cpp @@ -182,6 +182,10 @@ bool Vector2::is_equal_approx(const Vector2 &p_v) const { return Math::is_equal_approx(x, p_v.x) && Math::is_equal_approx(y, p_v.y); } +bool Vector2::is_zero_approx() const { + return Math::is_zero_approx(x) && Math::is_zero_approx(y); +} + Vector2::operator String() const { return "(" + String::num_real(x, false) + ", " + String::num_real(y, false) + ")"; } diff --git a/core/math/vector2.h b/core/math/vector2.h index caa6b226e7..9441f84087 100644 --- a/core/math/vector2.h +++ b/core/math/vector2.h @@ -124,6 +124,7 @@ struct _NO_DISCARD_ Vector2 { Vector2 reflect(const Vector2 &p_normal) const; bool is_equal_approx(const Vector2 &p_v) const; + bool is_zero_approx() const; Vector2 operator+(const Vector2 &p_v) const; void operator+=(const Vector2 &p_v); diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp index f8eefa4f18..4db45fe798 100644 --- a/core/math/vector3.cpp +++ b/core/math/vector3.cpp @@ -145,6 +145,10 @@ bool Vector3::is_equal_approx(const Vector3 &p_v) const { return Math::is_equal_approx(x, p_v.x) && Math::is_equal_approx(y, p_v.y) && Math::is_equal_approx(z, p_v.z); } +bool Vector3::is_zero_approx() const { + return Math::is_zero_approx(x) && Math::is_zero_approx(y) && Math::is_zero_approx(z); +} + Vector3::operator String() const { return "(" + String::num_real(x, false) + ", " + String::num_real(y, false) + ", " + String::num_real(z, false) + ")"; } diff --git a/core/math/vector3.h b/core/math/vector3.h index 7cae6e2481..3944afa92e 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -142,6 +142,7 @@ struct _NO_DISCARD_ Vector3 { _FORCE_INLINE_ Vector3 reflect(const Vector3 &p_normal) const; bool is_equal_approx(const Vector3 &p_v) const; + bool is_zero_approx() const; /* Operators */ diff --git a/core/math/vector4.cpp b/core/math/vector4.cpp index 273a111891..fb651fafce 100644 --- a/core/math/vector4.cpp +++ b/core/math/vector4.cpp @@ -71,6 +71,10 @@ bool Vector4::is_equal_approx(const Vector4 &p_vec4) const { return Math::is_equal_approx(x, p_vec4.x) && Math::is_equal_approx(y, p_vec4.y) && Math::is_equal_approx(z, p_vec4.z) && Math::is_equal_approx(w, p_vec4.w); } +bool Vector4::is_zero_approx() const { + return Math::is_zero_approx(x) && Math::is_zero_approx(y) && Math::is_zero_approx(z) && Math::is_zero_approx(w); +} + real_t Vector4::length() const { return Math::sqrt(length_squared()); } diff --git a/core/math/vector4.h b/core/math/vector4.h index 17d0de18e1..f964264108 100644 --- a/core/math/vector4.h +++ b/core/math/vector4.h @@ -73,6 +73,7 @@ struct _NO_DISCARD_ Vector4 { _FORCE_INLINE_ real_t length_squared() const; bool is_equal_approx(const Vector4 &p_vec4) const; + bool is_zero_approx() const; real_t length() const; void normalize(); Vector4 normalized() const; diff --git a/core/object/object.h b/core/object/object.h index 1784c1fe70..97608c7938 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -50,7 +50,7 @@ class TypedArray; enum PropertyHint { PROPERTY_HINT_NONE, ///< no hint provided. - PROPERTY_HINT_RANGE, ///< hint_text = "min,max[,step][,or_greater][,or_lesser][,no_slider][,radians][,degrees][,exp][,suffix:<keyword>] range. + PROPERTY_HINT_RANGE, ///< hint_text = "min,max[,step][,or_greater][,or_less][,no_slider][,radians][,degrees][,exp][,suffix:<keyword>] range. PROPERTY_HINT_ENUM, ///< hint_text= "val1,val2,val3,etc" PROPERTY_HINT_ENUM_SUGGESTION, ///< hint_text= "val1,val2,val3,etc" PROPERTY_HINT_EXP_EASING, /// exponential easing function (Math::ease) use "attenuation" hint string to revert (flip h), "positive_only" to exclude in-out and out-in. (ie: "attenuation,positive_only") diff --git a/core/string/ustring.h b/core/string/ustring.h index 31de7cc464..b8ae3c2392 100644 --- a/core/string/ustring.h +++ b/core/string/ustring.h @@ -376,8 +376,6 @@ public: String path_join(const String &p_file) const; char32_t unicode_at(int p_idx) const; - void erase(int p_pos, int p_chars); - CharString ascii(bool p_allow_extended = false) const; CharString utf8() const; Error parse_utf8(const char *p_utf8, int p_len = -1, bool p_skip_cr = false); diff --git a/core/variant/dictionary.cpp b/core/variant/dictionary.cpp index d9f4359ee5..c1cb782a57 100644 --- a/core/variant/dictionary.cpp +++ b/core/variant/dictionary.cpp @@ -195,6 +195,15 @@ bool Dictionary::has_all(const Array &p_keys) const { return true; } +Variant Dictionary::find_key(const Variant &p_value) const { + for (const KeyValue<Variant, Variant> &E : _p->variant_map) { + if (E.value == p_value) { + return E.key; + } + } + return Variant(); +} + bool Dictionary::erase(const Variant &p_key) { ERR_FAIL_COND_V_MSG(_p->read_only, false, "Dictionary is in read-only state."); if (p_key.get_type() == Variant::STRING_NAME) { diff --git a/core/variant/dictionary.h b/core/variant/dictionary.h index 2632893e8d..d9c9db56cf 100644 --- a/core/variant/dictionary.h +++ b/core/variant/dictionary.h @@ -66,6 +66,7 @@ public: bool has(const Variant &p_key) const; bool has_all(const Array &p_keys) const; + Variant find_key(const Variant &p_value) const; bool erase(const Variant &p_key); diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index a4bce979fe..8f15a62f79 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -1605,6 +1605,7 @@ static void _register_variant_builtin_methods() { bind_method(Vector2, normalized, sarray(), varray()); bind_method(Vector2, is_normalized, sarray(), varray()); bind_method(Vector2, is_equal_approx, sarray("to"), varray()); + bind_method(Vector2, is_zero_approx, sarray(), varray()); bind_method(Vector2, posmod, sarray("mod"), varray()); bind_method(Vector2, posmodv, sarray("modv"), varray()); bind_method(Vector2, project, sarray("b"), varray()); @@ -1693,6 +1694,7 @@ static void _register_variant_builtin_methods() { bind_method(Vector3, normalized, sarray(), varray()); bind_method(Vector3, is_normalized, sarray(), varray()); bind_method(Vector3, is_equal_approx, sarray("to"), varray()); + bind_method(Vector3, is_zero_approx, sarray(), varray()); bind_method(Vector3, inverse, sarray(), varray()); bind_method(Vector3, clamp, sarray("min", "max"), varray()); bind_method(Vector3, snapped, sarray("step"), varray()); @@ -1756,6 +1758,7 @@ static void _register_variant_builtin_methods() { bind_method(Vector4, dot, sarray("with"), varray()); bind_method(Vector4, inverse, sarray(), varray()); bind_method(Vector4, is_equal_approx, sarray("with"), varray()); + bind_method(Vector4, is_zero_approx, sarray(), varray()); /* Vector4i */ @@ -2014,6 +2017,7 @@ static void _register_variant_builtin_methods() { bind_method(Dictionary, merge, sarray("dictionary", "overwrite"), varray(false)); bind_method(Dictionary, has, sarray("key"), varray()); bind_method(Dictionary, has_all, sarray("keys"), varray()); + bind_method(Dictionary, find_key, sarray("value"), varray()); bind_method(Dictionary, erase, sarray("key"), varray()); bind_method(Dictionary, hash, sarray(), varray()); bind_method(Dictionary, keys, sarray(), varray()); diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index 71b0901b3d..10229bdb0e 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -2614,7 +2614,7 @@ No hint for the edited property. </constant> <constant name="PROPERTY_HINT_RANGE" value="1" enum="PropertyHint"> - Hints that an integer or float property should be within a range specified via the hint string [code]"min,max"[/code] or [code]"min,max,step"[/code]. The hint string can optionally include [code]"or_greater"[/code] and/or [code]"or_lesser"[/code] to allow manual input going respectively above the max or below the min values. Example: [code]"-360,360,1,or_greater,or_lesser"[/code]. + Hints that an integer or float property should be within a range specified via the hint string [code]"min,max"[/code] or [code]"min,max,step"[/code]. The hint string can optionally include [code]"or_greater"[/code] and/or [code]"or_less"[/code] to allow manual input going respectively above the max or below the min values. Example: [code]"-360,360,1,or_greater,or_less"[/code]. Additionally, other keywords can be included: [code]"exp"[/code] for exponential range editing, [code]"radians"[/code] for editing radian angles in degrees, [code]"degrees"[/code] to hint at an angle and [code]"no_slider"[/code] to hide the slider. </constant> <constant name="PROPERTY_HINT_ENUM" value="2" enum="PropertyHint"> diff --git a/doc/classes/AcceptDialog.xml b/doc/classes/AcceptDialog.xml index c83ea8c60a..ee49523c90 100644 --- a/doc/classes/AcceptDialog.xml +++ b/doc/classes/AcceptDialog.xml @@ -99,6 +99,12 @@ </signal> </signals> <theme_items> + <theme_item name="button_margin" data_type="constant" type="int" default="32"> + Offset that is applied to the content of the window on the bottom, effectively moving the button row. + </theme_item> + <theme_item name="margin" data_type="constant" type="int" default="8"> + Offset that is applied to the content of the window on top, left, and right. + </theme_item> <theme_item name="panel" data_type="style" type="StyleBox"> Panel that fills up the background of the window. </theme_item> diff --git a/doc/classes/AnimatedSprite3D.xml b/doc/classes/AnimatedSprite3D.xml index 68354f092c..0bc5484e3a 100644 --- a/doc/classes/AnimatedSprite3D.xml +++ b/doc/classes/AnimatedSprite3D.xml @@ -10,12 +10,6 @@ <link title="2D Sprite animation (also applies to 3D)">$DOCS_URL/tutorials/2d/2d_sprite_animation.html</link> </tutorials> <methods> - <method name="is_playing" qualifiers="const"> - <return type="bool" /> - <description> - Returns [code]true[/code] if an animation is currently being played. - </description> - </method> <method name="play"> <return type="void" /> <param index="0" name="anim" type="StringName" default="&""" /> @@ -40,7 +34,7 @@ <member name="frames" type="SpriteFrames" setter="set_sprite_frames" getter="get_sprite_frames"> The [SpriteFrames] resource containing the animation(s). </member> - <member name="playing" type="bool" setter="_set_playing" getter="_is_playing" default="false"> + <member name="playing" type="bool" setter="set_playing" getter="is_playing" default="false"> If [code]true[/code], the [member animation] is currently playing. </member> </members> diff --git a/doc/classes/ArrayMesh.xml b/doc/classes/ArrayMesh.xml index c766becce2..ab948dd0de 100644 --- a/doc/classes/ArrayMesh.xml +++ b/doc/classes/ArrayMesh.xml @@ -61,7 +61,7 @@ <return type="void" /> <param index="0" name="primitive" type="int" enum="Mesh.PrimitiveType" /> <param index="1" name="arrays" type="Array" /> - <param index="2" name="blend_shapes" type="Array" default="[]" /> + <param index="2" name="blend_shapes" type="Array[]" default="[]" /> <param index="3" name="lods" type="Dictionary" default="{}" /> <param index="4" name="compress_flags" type="int" default="0" /> <description> diff --git a/doc/classes/AudioEffectCapture.xml b/doc/classes/AudioEffectCapture.xml index c2a5ec3b45..bac9167223 100644 --- a/doc/classes/AudioEffectCapture.xml +++ b/doc/classes/AudioEffectCapture.xml @@ -5,10 +5,12 @@ </brief_description> <description> AudioEffectCapture is an AudioEffect which copies all audio frames from the attached audio effect bus into its internal ring buffer. - Application code should consume these audio frames from this ring buffer using [method get_buffer] and process it as needed, for example to capture data from a microphone, implement application defined effects, or to transmit audio over the network. When capturing audio data from a microphone, the format of the samples will be stereo 32-bit floating point PCM. + Application code should consume these audio frames from this ring buffer using [method get_buffer] and process it as needed, for example to capture data from an [AudioStreamMicrophone], implement application-defined effects, or to transmit audio over the network. When capturing audio data from a microphone, the format of the samples will be stereo 32-bit floating point PCM. + [b]Note:[/b] [member ProjectSettings.audio/driver/enable_input] must be [code]true[/code] for audio input to work. See also that setting's description for caveats related to permissions and operating system privacy settings. </description> <tutorials> <link title="Audio buses">$DOCS_URL/tutorials/audio/audio_buses.html</link> + <link title="Audio Mic Record Demo">https://github.com/godotengine/godot-demo-projects/tree/master/audio/mic_record</link> </tutorials> <methods> <method name="can_get_buffer" qualifiers="const"> diff --git a/doc/classes/AudioServer.xml b/doc/classes/AudioServer.xml index 8dc80e3bdc..36f12dd5c4 100644 --- a/doc/classes/AudioServer.xml +++ b/doc/classes/AudioServer.xml @@ -33,6 +33,7 @@ <return type="PackedStringArray" /> <description> Returns the names of all audio input devices detected on the system. + [b]Note:[/b] [member ProjectSettings.audio/driver/enable_input] must be [code]true[/code] for audio input to work. See also that setting's description for caveats related to permissions and operating system privacy settings. </description> </method> <method name="generate_bus_layout" qualifiers="const"> @@ -302,7 +303,8 @@ Number of available audio buses. </member> <member name="capture_device" type="String" setter="capture_set_device" getter="capture_get_device" default=""Default""> - Name of the current device for audio input (see [method get_device_list]). On systems with multiple audio inputs (such as analog, USB and HDMI audio), this can be used to select the audio input device. The value [code]"Default"[/code] will record audio on the system-wide default audio input. If an invalid device name is set, the value will be reverted back to [code]"Default"[/code]. + Name of the current device for audio input (see [method capture_get_device_list]). On systems with multiple audio inputs (such as analog, USB and HDMI audio), this can be used to select the audio input device. The value [code]"Default"[/code] will record audio on the system-wide default audio input. If an invalid device name is set, the value will be reverted back to [code]"Default"[/code]. + [b]Note:[/b] [member ProjectSettings.audio/driver/enable_input] must be [code]true[/code] for audio input to work. See also that setting's description for caveats related to permissions and operating system privacy settings. </member> <member name="device" type="String" setter="set_device" getter="get_device" default=""Default""> Name of the current device for audio output (see [method get_device_list]). On systems with multiple audio outputs (such as analog, USB and HDMI audio), this can be used to select the audio output device. The value [code]"Default"[/code] will play audio on the system-wide default audio output. If an invalid device name is set, the value will be reverted back to [code]"Default"[/code]. diff --git a/doc/classes/AudioStreamMicrophone.xml b/doc/classes/AudioStreamMicrophone.xml index e760bd526a..be3e91e037 100644 --- a/doc/classes/AudioStreamMicrophone.xml +++ b/doc/classes/AudioStreamMicrophone.xml @@ -1,9 +1,13 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="AudioStreamMicrophone" inherits="AudioStream" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> + Plays real-time audio input data. </brief_description> <description> + When used directly in an [AudioStreamPlayer] node, [AudioStreamMicrophone] plays back microphone input in real-time. This can be used in conjunction with [AudioEffectCapture] to process the data or save it. + [b]Note:[/b] [member ProjectSettings.audio/driver/enable_input] must be [code]true[/code] for audio input to work. See also that setting's description for caveats related to permissions and operating system privacy settings. </description> <tutorials> + <link title="Audio Mic Record Demo">https://github.com/godotengine/godot-demo-projects/tree/master/audio/mic_record</link> </tutorials> </class> diff --git a/doc/classes/BitMap.xml b/doc/classes/BitMap.xml index 9323642274..b3fa55f154 100644 --- a/doc/classes/BitMap.xml +++ b/doc/classes/BitMap.xml @@ -17,7 +17,7 @@ </method> <method name="create"> <return type="void" /> - <param index="0" name="size" type="Vector2" /> + <param index="0" name="size" type="Vector2i" /> <description> Creates a bitmap with the specified size, filled with [code]false[/code]. </description> @@ -32,13 +32,21 @@ </method> <method name="get_bit" qualifiers="const"> <return type="bool" /> - <param index="0" name="position" type="Vector2" /> + <param index="0" name="x" type="int" /> + <param index="1" name="y" type="int" /> + <description> + Returns bitmap's value at the specified position. + </description> + </method> + <method name="get_bitv" qualifiers="const"> + <return type="bool" /> + <param index="0" name="position" type="Vector2i" /> <description> Returns bitmap's value at the specified position. </description> </method> <method name="get_size" qualifiers="const"> - <return type="Vector2" /> + <return type="Vector2i" /> <description> Returns bitmap's dimensions. </description> @@ -52,14 +60,14 @@ <method name="grow_mask"> <return type="void" /> <param index="0" name="pixels" type="int" /> - <param index="1" name="rect" type="Rect2" /> + <param index="1" name="rect" type="Rect2i" /> <description> Applies morphological dilation or erosion to the bitmap. If [param pixels] is positive, dilation is applied to the bitmap. If [param pixels] is negative, erosion is applied to the bitmap. [param rect] defines the area where the morphological operation is applied. Pixels located outside the [param rect] are unaffected by [method grow_mask]. </description> </method> <method name="opaque_to_polygons" qualifiers="const"> <return type="PackedVector2Array[]" /> - <param index="0" name="rect" type="Rect2" /> + <param index="0" name="rect" type="Rect2i" /> <param index="1" name="epsilon" type="float" default="2.0" /> <description> Creates an [Array] of polygons covering a rectangular portion of the bitmap. It uses a marching squares algorithm, followed by Ramer-Douglas-Peucker (RDP) reduction of the number of vertices. Each polygon is described as a [PackedVector2Array] of its vertices. @@ -72,26 +80,35 @@ </method> <method name="resize"> <return type="void" /> - <param index="0" name="new_size" type="Vector2" /> + <param index="0" name="new_size" type="Vector2i" /> <description> Resizes the image to [param new_size]. </description> </method> <method name="set_bit"> <return type="void" /> - <param index="0" name="position" type="Vector2" /> - <param index="1" name="bit" type="bool" /> + <param index="0" name="x" type="int" /> + <param index="1" name="y" type="int" /> + <param index="2" name="bit" type="bool" /> <description> Sets the bitmap's element at the specified position, to the specified value. </description> </method> <method name="set_bit_rect"> <return type="void" /> - <param index="0" name="rect" type="Rect2" /> + <param index="0" name="rect" type="Rect2i" /> <param index="1" name="bit" type="bool" /> <description> Sets a rectangular portion of the bitmap to the specified value. </description> </method> + <method name="set_bitv"> + <return type="void" /> + <param index="0" name="position" type="Vector2i" /> + <param index="1" name="bit" type="bool" /> + <description> + Sets the bitmap's element at the specified position, to the specified value. + </description> + </method> </methods> </class> diff --git a/doc/classes/BoxContainer.xml b/doc/classes/BoxContainer.xml index 65ceab3e30..a06b0e9c4b 100644 --- a/doc/classes/BoxContainer.xml +++ b/doc/classes/BoxContainer.xml @@ -22,13 +22,25 @@ <member name="alignment" type="int" setter="set_alignment" getter="get_alignment" enum="BoxContainer.AlignmentMode" default="0"> The alignment of the container's children (must be one of [constant ALIGNMENT_BEGIN], [constant ALIGNMENT_CENTER], or [constant ALIGNMENT_END]). </member> + <member name="vertical" type="bool" setter="set_vertical" getter="is_vertical" default="false"> + If [code]true[/code], the [BoxContainer] will arrange its children vertically, rather than horizontally. + Can't be changed when using [HBoxContainer] and [VBoxContainer]. + </member> </members> <constants> <constant name="ALIGNMENT_BEGIN" value="0" enum="AlignmentMode"> + The child controls will be arranged at the beginning of the container, i.e. top if orientation is vertical, left if orientation is horizontal (right for RTL layout). </constant> <constant name="ALIGNMENT_CENTER" value="1" enum="AlignmentMode"> + The child controls will be centered in the container. </constant> <constant name="ALIGNMENT_END" value="2" enum="AlignmentMode"> + The child controls will be arranged at the end of the container, i.e. bottom if orientation is vertical, right if orientation is horizontal (left for RTL layout). </constant> </constants> + <theme_items> + <theme_item name="separation" data_type="constant" type="int" default="4"> + The space between the [BoxContainer]'s elements, in pixels. + </theme_item> + </theme_items> </class> diff --git a/doc/classes/ColorPicker.xml b/doc/classes/ColorPicker.xml index 705d2282c1..e992d6f9d4 100644 --- a/doc/classes/ColorPicker.xml +++ b/doc/classes/ColorPicker.xml @@ -55,6 +55,7 @@ <member name="presets_visible" type="bool" setter="set_presets_visible" getter="are_presets_visible" default="true"> If [code]true[/code], saved color presets are visible. </member> + <member name="vertical" type="bool" setter="set_vertical" getter="is_vertical" overrides="BoxContainer" default="true" /> </members> <signals> <signal name="color_changed"> diff --git a/doc/classes/ConfigFile.xml b/doc/classes/ConfigFile.xml index d3ad4e6e4b..7ba53f852b 100644 --- a/doc/classes/ConfigFile.xml +++ b/doc/classes/ConfigFile.xml @@ -98,6 +98,12 @@ Removes the entire contents of the config. </description> </method> + <method name="encode_to_text" qualifiers="const"> + <return type="String" /> + <description> + Obtain the text version of this config file (the same text that would be written to a file). + </description> + </method> <method name="erase_section"> <return type="void" /> <param index="0" name="section" type="String" /> diff --git a/doc/classes/Dictionary.xml b/doc/classes/Dictionary.xml index 40b5e88fff..9dbeeb360c 100644 --- a/doc/classes/Dictionary.xml +++ b/doc/classes/Dictionary.xml @@ -4,7 +4,7 @@ Dictionary type. </brief_description> <description> - Dictionary type. Associative container which contains values referenced by unique keys. Dictionaries are composed of pairs of keys (which must be unique) and values. Dictionaries will preserve the insertion order when adding elements, even though this may not be reflected when printing the dictionary. In other programming languages, this data structure is sometimes referred to as a hash map or associative array. + Dictionary type. Associative container which contains values referenced by unique keys. Dictionaries are composed of pairs of keys (which must be unique) and values. Dictionaries will preserve the insertion order when adding elements. In other programming languages, this data structure is sometimes referred to as a hash map or associative array. You can define a dictionary by placing a comma-separated list of [code]key: value[/code] pairs in curly braces [code]{}[/code]. Erasing elements while iterating over them [b]is not supported[/b] and will result in undefined behavior. [b]Note:[/b] Dictionaries are always passed by reference. To get a copy of a dictionary which can be modified independently of the original dictionary, use [method duplicate]. @@ -218,6 +218,14 @@ [b]Note:[/b] Don't erase elements while iterating over the dictionary. You can iterate over the [method keys] array instead. </description> </method> + <method name="find_key" qualifiers="const"> + <return type="Variant" /> + <param index="0" name="value" type="Variant" /> + <description> + Returns the first key whose associated value is equal to [param value], or [code]null[/code] if no such value is found. + [b]Node:[/b] [code]null[/code] is also a valid key. I you have it in your [Dictionary], the [method find_key] method can give misleading results. + </description> + </method> <method name="get" qualifiers="const"> <return type="Variant" /> <param index="0" name="key" type="Variant" /> diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml index 35a2861c54..d22d64c276 100644 --- a/doc/classes/DisplayServer.xml +++ b/doc/classes/DisplayServer.xml @@ -104,6 +104,13 @@ <description> </description> </method> + <method name="get_accent_color" qualifiers="const"> + <return type="Color" /> + <description> + Returns OS theme accent color. Returns [code]Color(0, 0, 0, 0)[/code], if accent color is unknown. + [b]Note:[/b] This method is implemented on macOS and Windows. + </description> + </method> <method name="get_display_cutouts" qualifiers="const"> <return type="Rect2[]" /> <description> @@ -148,9 +155,10 @@ <param index="0" name="menu_root" type="String" /> <param index="1" name="label" type="String" /> <param index="2" name="callback" type="Callable" /> - <param index="3" name="tag" type="Variant" default="null" /> - <param index="4" name="accelerator" type="int" enum="Key" default="0" /> - <param index="5" name="index" type="int" default="-1" /> + <param index="3" name="key_callback" type="Callable" /> + <param index="4" name="tag" type="Variant" default="null" /> + <param index="5" name="accelerator" type="int" enum="Key" default="0" /> + <param index="6" name="index" type="int" default="-1" /> <description> Adds a new checkable item with text [param label] to the global menu with ID [param menu_root]. Returns index of the inserted item, it's not guaranteed to be the same as [param index] value. @@ -168,9 +176,10 @@ <param index="1" name="icon" type="Texture2D" /> <param index="2" name="label" type="String" /> <param index="3" name="callback" type="Callable" /> - <param index="4" name="tag" type="Variant" default="null" /> - <param index="5" name="accelerator" type="int" enum="Key" default="0" /> - <param index="6" name="index" type="int" default="-1" /> + <param index="4" name="key_callback" type="Callable" /> + <param index="5" name="tag" type="Variant" default="null" /> + <param index="6" name="accelerator" type="int" enum="Key" default="0" /> + <param index="7" name="index" type="int" default="-1" /> <description> Adds a new checkable item with text [param label] and icon [param icon] to the global menu with ID [param menu_root]. Returns index of the inserted item, it's not guaranteed to be the same as [param index] value. @@ -188,9 +197,10 @@ <param index="1" name="icon" type="Texture2D" /> <param index="2" name="label" type="String" /> <param index="3" name="callback" type="Callable" /> - <param index="4" name="tag" type="Variant" default="null" /> - <param index="5" name="accelerator" type="int" enum="Key" default="0" /> - <param index="6" name="index" type="int" default="-1" /> + <param index="4" name="key_callback" type="Callable" /> + <param index="5" name="tag" type="Variant" default="null" /> + <param index="6" name="accelerator" type="int" enum="Key" default="0" /> + <param index="7" name="index" type="int" default="-1" /> <description> Adds a new item with text [param label] and icon [param icon] to the global menu with ID [param menu_root]. Returns index of the inserted item, it's not guaranteed to be the same as [param index] value. @@ -208,9 +218,10 @@ <param index="1" name="icon" type="Texture2D" /> <param index="2" name="label" type="String" /> <param index="3" name="callback" type="Callable" /> - <param index="4" name="tag" type="Variant" default="null" /> - <param index="5" name="accelerator" type="int" enum="Key" default="0" /> - <param index="6" name="index" type="int" default="-1" /> + <param index="4" name="key_callback" type="Callable" /> + <param index="5" name="tag" type="Variant" default="null" /> + <param index="6" name="accelerator" type="int" enum="Key" default="0" /> + <param index="7" name="index" type="int" default="-1" /> <description> Adds a new radio-checkable item with text [param label] and icon [param icon] to the global menu with ID [param menu_root]. Returns index of the inserted item, it's not guaranteed to be the same as [param index] value. @@ -228,9 +239,10 @@ <param index="0" name="menu_root" type="String" /> <param index="1" name="label" type="String" /> <param index="2" name="callback" type="Callable" /> - <param index="3" name="tag" type="Variant" default="null" /> - <param index="4" name="accelerator" type="int" enum="Key" default="0" /> - <param index="5" name="index" type="int" default="-1" /> + <param index="3" name="key_callback" type="Callable" /> + <param index="4" name="tag" type="Variant" default="null" /> + <param index="5" name="accelerator" type="int" enum="Key" default="0" /> + <param index="6" name="index" type="int" default="-1" /> <description> Adds a new item with text [param label] to the global menu with ID [param menu_root]. Returns index of the inserted item, it's not guaranteed to be the same as [param index] value. @@ -249,9 +261,10 @@ <param index="2" name="max_states" type="int" /> <param index="3" name="default_state" type="int" /> <param index="4" name="callback" type="Callable" /> - <param index="5" name="tag" type="Variant" default="null" /> - <param index="6" name="accelerator" type="int" enum="Key" default="0" /> - <param index="7" name="index" type="int" default="-1" /> + <param index="5" name="key_callback" type="Callable" /> + <param index="6" name="tag" type="Variant" default="null" /> + <param index="7" name="accelerator" type="int" enum="Key" default="0" /> + <param index="8" name="index" type="int" default="-1" /> <description> Adds a new item with text [param labe] to the global menu with ID [param menu_root]. Contrarily to normal binary items, multistate items can have more than two states, as defined by [param max_states]. Each press or activate of the item will increase the state by one. The default value is defined by [param default_state]. @@ -270,9 +283,10 @@ <param index="0" name="menu_root" type="String" /> <param index="1" name="label" type="String" /> <param index="2" name="callback" type="Callable" /> - <param index="3" name="tag" type="Variant" default="null" /> - <param index="4" name="accelerator" type="int" enum="Key" default="0" /> - <param index="5" name="index" type="int" default="-1" /> + <param index="3" name="key_callback" type="Callable" /> + <param index="4" name="tag" type="Variant" default="null" /> + <param index="5" name="accelerator" type="int" enum="Key" default="0" /> + <param index="6" name="index" type="int" default="-1" /> <description> Adds a new radio-checkable item with text [param label] to the global menu with ID [param menu_root]. Returns index of the inserted item, it's not guaranteed to be the same as [param index] value. @@ -384,6 +398,15 @@ [b]Note:[/b] This method is implemented on macOS. </description> </method> + <method name="global_menu_get_item_key_callback" qualifiers="const"> + <return type="Callable" /> + <param index="0" name="menu_root" type="String" /> + <param index="1" name="idx" type="int" /> + <description> + Returns the callback of the item accelerator at index [param idx]. + [b]Note:[/b] This method is implemented on macOS. + </description> + </method> <method name="global_menu_get_item_max_states" qualifiers="const"> <return type="int" /> <param index="0" name="menu_root" type="String" /> @@ -502,7 +525,7 @@ <param index="1" name="idx" type="int" /> <param index="2" name="callback" type="Callable" /> <description> - Sets the callback of the item at index [param idx]. Callback is emitted when an item is pressed or its accelerator is activated. + Sets the callback of the item at index [param idx]. Callback is emitted when an item is pressed. [b]Note:[/b] This method is implemented on macOS. </description> </method> @@ -557,6 +580,16 @@ [b]Note:[/b] This method is implemented on macOS. </description> </method> + <method name="global_menu_set_item_key_callback"> + <return type="void" /> + <param index="0" name="menu_root" type="String" /> + <param index="1" name="idx" type="int" /> + <param index="2" name="key_callback" type="Callable" /> + <description> + Sets the callback of the item at index [param idx]. Callback is emitted when its accelerator is activated. + [b]Note:[/b] This method is implemented on macOS. + </description> + </method> <method name="global_menu_set_item_max_states"> <return type="void" /> <param index="0" name="menu_root" type="String" /> @@ -644,6 +677,20 @@ <description> </description> </method> + <method name="is_dark_mode" qualifiers="const"> + <return type="bool" /> + <description> + Returns [code]true[/code] if OS is using dark mode. + [b]Note:[/b] This method is implemented on macOS, Windows and Linux. + </description> + </method> + <method name="is_dark_mode_supported" qualifiers="const"> + <return type="bool" /> + <description> + Returns [code]true[/code] if OS supports dark mode. + [b]Note:[/b] This method is implemented on macOS, Windows and Linux. + </description> + </method> <method name="keyboard_get_current_layout" qualifiers="const"> <return type="int" /> <description> diff --git a/doc/classes/EditorExportPlatform.xml b/doc/classes/EditorExportPlatform.xml new file mode 100644 index 0000000000..1d63af9233 --- /dev/null +++ b/doc/classes/EditorExportPlatform.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="EditorExportPlatform" inherits="RefCounted" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> +</class> diff --git a/doc/classes/EditorExportPlugin.xml b/doc/classes/EditorExportPlugin.xml index 091bac7d8e..3e8ce10aa5 100644 --- a/doc/classes/EditorExportPlugin.xml +++ b/doc/classes/EditorExportPlugin.xml @@ -10,6 +10,51 @@ <tutorials> </tutorials> <methods> + <method name="_begin_customize_resources" qualifiers="virtual const"> + <return type="bool" /> + <param index="0" name="platform" type="EditorExportPlatform" /> + <param index="1" name="features" type="PackedStringArray" /> + <description> + Return true if this plugin will customize resources based on the platform and features used. + </description> + </method> + <method name="_begin_customize_scenes" qualifiers="virtual const"> + <return type="bool" /> + <param index="0" name="platform" type="EditorExportPlatform" /> + <param index="1" name="features" type="PackedStringArray" /> + <description> + Return true if this plugin will customize scenes based on the platform and features used. + </description> + </method> + <method name="_customize_resource" qualifiers="virtual"> + <return type="Resource" /> + <param index="0" name="resource" type="Resource" /> + <param index="1" name="path" type="String" /> + <description> + Customize a resource. If changes are made to it, return the same or a new resource. Otherwise, return [code]null[/code]. + The [i]path[/i] argument is only used when customizing an actual file, otherwise this means that this resource is part of another one and it will be empty. + </description> + </method> + <method name="_customize_scene" qualifiers="virtual"> + <return type="Node" /> + <param index="0" name="scene" type="Node" /> + <param index="1" name="path" type="String" /> + <description> + Customize a scene. If changes are made to it, return the same or a new scene. Otherwise, return [code]null[/code]. If a new scene is returned, it is up to you to dispose of the old one. + </description> + </method> + <method name="_end_customize_resources" qualifiers="virtual"> + <return type="void" /> + <description> + This is called when the customization process for resources ends. + </description> + </method> + <method name="_end_customize_scenes" qualifiers="virtual"> + <return type="void" /> + <description> + This is called when the customization process for scenes ends. + </description> + </method> <method name="_export_begin" qualifiers="virtual"> <return type="void" /> <param index="0" name="features" type="PackedStringArray" /> @@ -36,6 +81,18 @@ Calling [method skip] inside this callback will make the file not included in the export. </description> </method> + <method name="_get_customization_configuration_hash" qualifiers="virtual const"> + <return type="int" /> + <description> + Return a hash based on the configuration passed (for both scenes and resources). This helps keep separate caches for separate export configurations. + </description> + </method> + <method name="_get_name" qualifiers="virtual const"> + <return type="String" /> + <description> + Return the name identifier of this plugin (for future identification by the exporter). + </description> + </method> <method name="add_file"> <return type="void" /> <param index="0" name="path" type="String" /> diff --git a/doc/classes/EditorImportPlugin.xml b/doc/classes/EditorImportPlugin.xml index f7f1d456d0..348347c4ef 100644 --- a/doc/classes/EditorImportPlugin.xml +++ b/doc/classes/EditorImportPlugin.xml @@ -214,8 +214,8 @@ <param index="0" name="source_file" type="String" /> <param index="1" name="save_path" type="String" /> <param index="2" name="options" type="Dictionary" /> - <param index="3" name="platform_variants" type="Array" /> - <param index="4" name="gen_files" type="Array" /> + <param index="3" name="platform_variants" type="String[]" /> + <param index="4" name="gen_files" type="String[]" /> <description> Imports [param source_file] into [param save_path] with the import [param options] specified. The [param platform_variants] and [param gen_files] arrays will be modified by this function. This method must be overridden to do the actual importing work. See this class' description for an example of overriding this method. diff --git a/doc/classes/EditorInterface.xml b/doc/classes/EditorInterface.xml index 49cd715f5e..c4bbc7c108 100644 --- a/doc/classes/EditorInterface.xml +++ b/doc/classes/EditorInterface.xml @@ -167,7 +167,7 @@ </method> <method name="make_mesh_previews"> <return type="Texture2D[]" /> - <param index="0" name="meshes" type="Array" /> + <param index="0" name="meshes" type="Mesh[]" /> <param index="1" name="preview_size" type="int" /> <description> Returns mesh previews rendered at the given size as an [Array] of [Texture2D]s. diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml index 56c1f6e55a..6a7bb96e0f 100644 --- a/doc/classes/EditorSettings.xml +++ b/doc/classes/EditorSettings.xml @@ -135,7 +135,7 @@ <method name="set_builtin_action_override"> <return type="void" /> <param index="0" name="name" type="String" /> - <param index="1" name="actions_list" type="Array" /> + <param index="1" name="actions_list" type="InputEvent[]" /> <description> Overrides the built-in editor action [param name] with the input actions defined in [param actions_list]. </description> diff --git a/doc/classes/EditorTranslationParserPlugin.xml b/doc/classes/EditorTranslationParserPlugin.xml index bbae06899c..d028996db8 100644 --- a/doc/classes/EditorTranslationParserPlugin.xml +++ b/doc/classes/EditorTranslationParserPlugin.xml @@ -112,8 +112,8 @@ <method name="_parse_file" qualifiers="virtual"> <return type="void" /> <param index="0" name="path" type="String" /> - <param index="1" name="msgids" type="Array" /> - <param index="2" name="msgids_context_plural" type="Array" /> + <param index="1" name="msgids" type="String[]" /> + <param index="2" name="msgids_context_plural" type="Array[]" /> <description> Override this method to define a custom parsing logic to extract the translatable strings. </description> diff --git a/doc/classes/EditorVCSInterface.xml b/doc/classes/EditorVCSInterface.xml index cca6a0591f..b766978c04 100644 --- a/doc/classes/EditorVCSInterface.xml +++ b/doc/classes/EditorVCSInterface.xml @@ -53,7 +53,7 @@ </description> </method> <method name="_get_branch_list" qualifiers="virtual"> - <return type="Array" /> + <return type="Dictionary[]" /> <description> Gets an instance of an [Array] of [String]s containing available branch names in the VCS. </description> @@ -73,7 +73,7 @@ </description> </method> <method name="_get_line_diff" qualifiers="virtual"> - <return type="Array" /> + <return type="Dictionary[]" /> <param index="0" name="file_path" type="String" /> <param index="1" name="text" type="String" /> <description> @@ -81,20 +81,20 @@ </description> </method> <method name="_get_modified_files_data" qualifiers="virtual"> - <return type="Array" /> + <return type="Dictionary[]" /> <description> Returns an [Array] of [Dictionary] items (see [method create_status_file]), each containing the status data of every modified file in the project folder. </description> </method> <method name="_get_previous_commits" qualifiers="virtual"> - <return type="Array" /> + <return type="Dictionary[]" /> <param index="0" name="max_commits" type="int" /> <description> Returns an [Array] of [Dictionary] items (see [method create_commit]), each containing the data for a past commit. </description> </method> <method name="_get_remotes" qualifiers="virtual"> - <return type="Array" /> + <return type="Dictionary[]" /> <description> Returns an [Array] of [String]s, each containing the name of a remote configured in the VCS. </description> @@ -175,7 +175,7 @@ <method name="add_diff_hunks_into_diff_file"> <return type="Dictionary" /> <param index="0" name="diff_file" type="Dictionary" /> - <param index="1" name="diff_hunks" type="Array" /> + <param index="1" name="diff_hunks" type="Dictionary[]" /> <description> Helper function to add an array of [code]diff_hunks[/code] into a [code]diff_file[/code]. </description> @@ -183,7 +183,7 @@ <method name="add_line_diffs_into_diff_hunk"> <return type="Dictionary" /> <param index="0" name="diff_hunk" type="Dictionary" /> - <param index="1" name="line_diffs" type="Array" /> + <param index="1" name="line_diffs" type="Dictionary[]" /> <description> Helper function to add an array of [code]line_diffs[/code] into a [code]diff_hunk[/code]. </description> diff --git a/doc/classes/Environment.xml b/doc/classes/Environment.xml index 0182d543e1..695f2cbc66 100644 --- a/doc/classes/Environment.xml +++ b/doc/classes/Environment.xml @@ -82,7 +82,7 @@ The background mode. See [enum BGMode] for possible values. </member> <member name="fog_aerial_perspective" type="float" setter="set_fog_aerial_perspective" getter="get_fog_aerial_perspective" default="0.0"> - Blend factor between the fog's color and the color of the background [Sky]. Must have [member background_mode] set to [constant BG_SKY]. + If set above [code]0.0[/code] (exclusive), blends between the fog's color and the color of the background [Sky]. This has a small performance cost when set above [code]0.0[/code]. Must have [member background_mode] set to [constant BG_SKY]. This is useful to simulate [url=https://en.wikipedia.org/wiki/Aerial_perspective]aerial perspective[/url] in large scenes with low density fog. However, it is not very useful for high-density fog, as the sky will shine through. When set to [code]1.0[/code], the fog color comes completely from the [Sky]. If set to [code]0.0[/code], aerial perspective is disabled. </member> <member name="fog_density" type="float" setter="set_fog_density" getter="get_fog_density" default="0.01"> @@ -103,6 +103,10 @@ <member name="fog_light_energy" type="float" setter="set_fog_light_energy" getter="get_fog_light_energy" default="1.0"> The fog's brightness. Higher values result in brighter fog. </member> + <member name="fog_sky_affect" type="float" setter="set_fog_sky_affect" getter="get_fog_sky_affect" default="1.0"> + The factor to use when affecting the sky with non-volumetric fog. [code]1.0[/code] means that fog can fully obscure the sky. Lower values reduce the impact of fog on sky rendering, with [code]0.0[/code] not affecting sky rendering at all. + [b]Note:[/b] [member fog_sky_affect] has no visual effect if [member fog_aerial_perspective] is [code]1.0[/code]. + </member> <member name="fog_sun_scatter" type="float" setter="set_fog_sun_scatter" getter="get_fog_sun_scatter" default="0.0"> If set above [code]0.0[/code], renders the scene's directional light(s) in the fog color depending on the view angle. This can be used to give the impression that the sun is "piercing" through the fog. </member> @@ -315,6 +319,9 @@ <member name="volumetric_fog_length" type="float" setter="set_volumetric_fog_length" getter="get_volumetric_fog_length" default="64.0"> The distance over which the volumetric fog is computed. Increase to compute fog over a greater range, decrease to add more detail when a long range is not needed. For best quality fog, keep this as low as possible. </member> + <member name="volumetric_fog_sky_affect" type="float" setter="set_volumetric_fog_sky_affect" getter="get_volumetric_fog_sky_affect" default="1.0"> + The factor to use when affecting the sky with volumetric fog. [code]1.0[/code] means that volumetric fog can fully obscure the sky. Lower values reduce the impact of volumetric fog on sky rendering, with [code]0.0[/code] not affecting sky rendering at all. + </member> <member name="volumetric_fog_temporal_reprojection_amount" type="float" setter="set_volumetric_fog_temporal_reprojection_amount" getter="get_volumetric_fog_temporal_reprojection_amount" default="0.9"> The amount by which to blend the last frame with the current frame. A higher number results in smoother volumetric fog, but makes "ghosting" much worse. A lower value reduces ghosting but can result in the per-frame temporal jitter becoming visible. </member> diff --git a/doc/classes/FlowContainer.xml b/doc/classes/FlowContainer.xml index 256e20447b..d449049ef1 100644 --- a/doc/classes/FlowContainer.xml +++ b/doc/classes/FlowContainer.xml @@ -17,4 +17,18 @@ </description> </method> </methods> + <members> + <member name="vertical" type="bool" setter="set_vertical" getter="is_vertical" default="false"> + If [code]true[/code], the [FlowContainer] will arrange its children vertically, rather than horizontally. + Can't be changed when using [HFlowContainer] and [VFlowContainer]. + </member> + </members> + <theme_items> + <theme_item name="h_separation" data_type="constant" type="int" default="4"> + The horizontal separation of children nodes. + </theme_item> + <theme_item name="v_separation" data_type="constant" type="int" default="4"> + The vertical separation of children nodes. + </theme_item> + </theme_items> </class> diff --git a/doc/classes/GeometryInstance3D.xml b/doc/classes/GeometryInstance3D.xml index 79a60a9e62..4d8ab91718 100644 --- a/doc/classes/GeometryInstance3D.xml +++ b/doc/classes/GeometryInstance3D.xml @@ -9,9 +9,9 @@ <tutorials> </tutorials> <methods> - <method name="get_instance_shader_uniform" qualifiers="const"> + <method name="get_instance_shader_parameter" qualifiers="const"> <return type="Variant" /> - <param index="0" name="uniform" type="StringName" /> + <param index="0" name="name" type="StringName" /> <description> </description> </method> @@ -22,9 +22,9 @@ Overrides the bounding box of this node with a custom one. To remove it, set an [AABB] with all fields set to zero. </description> </method> - <method name="set_instance_shader_uniform"> + <method name="set_instance_shader_parameter"> <return type="void" /> - <param index="0" name="uniform" type="StringName" /> + <param index="0" name="name" type="StringName" /> <param index="1" name="value" type="Variant" /> <description> </description> diff --git a/doc/classes/ImageTextureLayered.xml b/doc/classes/ImageTextureLayered.xml index c0ad19ddd7..f5b338542b 100644 --- a/doc/classes/ImageTextureLayered.xml +++ b/doc/classes/ImageTextureLayered.xml @@ -9,7 +9,7 @@ <methods> <method name="create_from_images"> <return type="int" enum="Error" /> - <param index="0" name="images" type="Array" /> + <param index="0" name="images" type="Image[]" /> <description> </description> </method> diff --git a/doc/classes/ImporterMesh.xml b/doc/classes/ImporterMesh.xml index e15cfcd2c0..3c3dbe4d87 100644 --- a/doc/classes/ImporterMesh.xml +++ b/doc/classes/ImporterMesh.xml @@ -22,7 +22,7 @@ <return type="void" /> <param index="0" name="primitive" type="int" enum="Mesh.PrimitiveType" /> <param index="1" name="arrays" type="Array" /> - <param index="2" name="blend_shapes" type="Array" default="[]" /> + <param index="2" name="blend_shapes" type="Array[]" default="[]" /> <param index="3" name="lods" type="Dictionary" default="{}" /> <param index="4" name="material" type="Material" default="null" /> <param index="5" name="name" type="String" default="""" /> diff --git a/doc/classes/MultiplayerPeerExtension.xml b/doc/classes/MultiplayerPeerExtension.xml index 3a193abd7d..18bc18e6e7 100644 --- a/doc/classes/MultiplayerPeerExtension.xml +++ b/doc/classes/MultiplayerPeerExtension.xml @@ -16,7 +16,7 @@ </description> </method> <method name="_get_connection_status" qualifiers="virtual const"> - <return type="int" /> + <return type="int" enum="MultiplayerPeer.ConnectionStatus" /> <description> Called when the connection status is requested on the [MultiplayerPeer] (see [method MultiplayerPeer.get_connection_status]). </description> @@ -28,7 +28,7 @@ </description> </method> <method name="_get_packet" qualifiers="virtual"> - <return type="int" /> + <return type="int" enum="Error" /> <param index="0" name="r_buffer" type="const uint8_t **" /> <param index="1" name="r_buffer_size" type="int32_t*" /> <description> @@ -54,7 +54,7 @@ </description> </method> <method name="_get_transfer_mode" qualifiers="virtual const"> - <return type="int" /> + <return type="int" enum="MultiplayerPeer.TransferMode" /> <description> Called when the transfer mode to use is read on this [MultiplayerPeer] (see [member MultiplayerPeer.transfer_mode]). </description> @@ -78,13 +78,13 @@ </description> </method> <method name="_poll" qualifiers="virtual"> - <return type="int" /> + <return type="void" /> <description> Called when the [MultiplayerAPI] is polled. See [method MultiplayerAPI.poll]. </description> </method> <method name="_put_packet" qualifiers="virtual"> - <return type="int" /> + <return type="int" enum="Error" /> <param index="0" name="p_buffer" type="const uint8_t*" /> <param index="1" name="p_buffer_size" type="int" /> <description> @@ -92,7 +92,7 @@ </description> </method> <method name="_put_packet_script" qualifiers="virtual"> - <return type="int" /> + <return type="int" enum="Error" /> <param index="0" name="p_buffer" type="PackedByteArray" /> <description> Called when a packet needs to be sent by the [MultiplayerAPI], if [method _put_packet] isn't implemented. Use this when extending this class via GDScript. @@ -121,7 +121,7 @@ </method> <method name="_set_transfer_mode" qualifiers="virtual"> <return type="void" /> - <param index="0" name="p_mode" type="int" /> + <param index="0" name="p_mode" type="int" enum="MultiplayerPeer.TransferMode" /> <description> Called when the transfer mode is set on this [MultiplayerPeer] (see [member MultiplayerPeer.transfer_mode]). </description> diff --git a/doc/classes/NavigationAgent2D.xml b/doc/classes/NavigationAgent2D.xml index bf3aff2c58..3437e0eca4 100644 --- a/doc/classes/NavigationAgent2D.xml +++ b/doc/classes/NavigationAgent2D.xml @@ -165,7 +165,7 @@ <signal name="velocity_computed"> <param index="0" name="safe_velocity" type="Vector3" /> <description> - Notifies when the collision avoidance velocity is calculated. Emitted by [method set_velocity]. + Notifies when the collision avoidance velocity is calculated. Emitted by [method set_velocity]. Only emitted when [member avoidance_enabled] is true. </description> </signal> </signals> diff --git a/doc/classes/NavigationAgent3D.xml b/doc/classes/NavigationAgent3D.xml index 7c48f0b52b..3bb5b361ca 100644 --- a/doc/classes/NavigationAgent3D.xml +++ b/doc/classes/NavigationAgent3D.xml @@ -171,7 +171,7 @@ <signal name="velocity_computed"> <param index="0" name="safe_velocity" type="Vector3" /> <description> - Notifies when the collision avoidance velocity is calculated. Emitted by [method set_velocity]. + Notifies when the collision avoidance velocity is calculated. Emitted by [method set_velocity]. Only emitted when [member avoidance_enabled] is true. </description> </signal> </signals> diff --git a/doc/classes/NavigationLink2D.xml b/doc/classes/NavigationLink2D.xml new file mode 100644 index 0000000000..1e086fb730 --- /dev/null +++ b/doc/classes/NavigationLink2D.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="NavigationLink2D" inherits="Node2D" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + Creates a link between two locations that [NavigationServer2D] can route agents through. + </brief_description> + <description> + Creates a link between two locations that [NavigationServer2D] can route agents through. Links can be used to express navigation methods that aren't just traveling along the surface of the navigation mesh, like zip-lines, teleporters, or jumping across gaps. + </description> + <tutorials> + </tutorials> + <methods> + <method name="get_navigation_layer_value" qualifiers="const"> + <return type="bool" /> + <param index="0" name="layer_number" type="int" /> + <description> + Returns whether or not the specified layer of the [member navigation_layers] bitmask is enabled, given a [code]layer_number[/code] between 1 and 32. + </description> + </method> + <method name="set_navigation_layer_value"> + <return type="void" /> + <param index="0" name="layer_number" type="int" /> + <param index="1" name="value" type="bool" /> + <description> + Based on [code]value[/code], enables or disables the specified layer in the [member navigation_layers] bitmask, given a [code]layer_number[/code] between 1 and 32. + </description> + </method> + </methods> + <members> + <member name="bidirectional" type="bool" setter="set_bidirectional" getter="is_bidirectional" default="true"> + Whether this link can be traveled in both directions or only from [member start_location] to [member end_location]. + </member> + <member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" default="true"> + Whether this link is currently active. If [code]false[/code], [method NavigationServer2D.map_get_path] will ignore this link. + </member> + <member name="end_location" type="Vector2" setter="set_end_location" getter="get_end_location" default="Vector2(0, 0)"> + Ending position of the link. + This position will search out the nearest polygon in the navigation mesh to attach to. + The distance the link will search is controlled by [method NavigationServer2D.map_set_link_connection_radius]. + </member> + <member name="enter_cost" type="float" setter="set_enter_cost" getter="get_enter_cost" default="0.0"> + When pathfinding enters this link from another regions navmesh the [code]enter_cost[/code] value is added to the path distance for determining the shortest path. + </member> + <member name="navigation_layers" type="int" setter="set_navigation_layers" getter="get_navigation_layers" default="1"> + A bitfield determining all navigation layers the link belongs to. These navigation layers will be checked when requesting a path with [method NavigationServer2D.map_get_path]. + </member> + <member name="start_location" type="Vector2" setter="set_start_location" getter="get_start_location" default="Vector2(0, 0)"> + Starting position of the link. + This position will search out the nearest polygon in the navigation mesh to attach to. + The distance the link will search is controlled by [method NavigationServer2D.map_set_link_connection_radius]. + </member> + <member name="travel_cost" type="float" setter="set_travel_cost" getter="get_travel_cost" default="1.0"> + When pathfinding moves along the link the traveled distance is multiplied with [code]travel_cost[/code] for determining the shortest path. + </member> + </members> +</class> diff --git a/doc/classes/NavigationLink3D.xml b/doc/classes/NavigationLink3D.xml new file mode 100644 index 0000000000..4d5d81bec5 --- /dev/null +++ b/doc/classes/NavigationLink3D.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="NavigationLink3D" inherits="Node3D" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + Creates a link between two locations that [NavigationServer3D] can route agents through. + </brief_description> + <description> + Creates a link between two locations that [NavigationServer3D] can route agents through. Links can be used to express navigation methods that aren't just traveling along the surface of the navigation mesh, like zip-lines, teleporters, or jumping across gaps. + </description> + <tutorials> + </tutorials> + <methods> + <method name="get_navigation_layer_value" qualifiers="const"> + <return type="bool" /> + <param index="0" name="layer_number" type="int" /> + <description> + Returns whether or not the specified layer of the [member navigation_layers] bitmask is enabled, given a [code]layer_number[/code] between 1 and 32. + </description> + </method> + <method name="set_navigation_layer_value"> + <return type="void" /> + <param index="0" name="layer_number" type="int" /> + <param index="1" name="value" type="bool" /> + <description> + Based on [code]value[/code], enables or disables the specified layer in the [member navigation_layers] bitmask, given a [code]layer_number[/code] between 1 and 32. + </description> + </method> + </methods> + <members> + <member name="bidirectional" type="bool" setter="set_bidirectional" getter="is_bidirectional" default="true"> + Whether this link can be traveled in both directions or only from [member start_location] to [member end_location]. + </member> + <member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" default="true"> + Whether this link is currently active. If [code]false[/code], [method NavigationServer3D.map_get_path] will ignore this link. + </member> + <member name="end_location" type="Vector3" setter="set_end_location" getter="get_end_location" default="Vector3(0, 0, 0)"> + Ending position of the link. + This position will search out the nearest polygon in the navigation mesh to attach to. + The distance the link will search is controlled by [method NavigationServer3D.map_set_link_connection_radius]. + </member> + <member name="enter_cost" type="float" setter="set_enter_cost" getter="get_enter_cost" default="0.0"> + When pathfinding enters this link from another regions navmesh the [code]enter_cost[/code] value is added to the path distance for determining the shortest path. + </member> + <member name="navigation_layers" type="int" setter="set_navigation_layers" getter="get_navigation_layers" default="1"> + A bitfield determining all navigation layers the link belongs to. These navigation layers will be checked when requesting a path with [method NavigationServer3D.map_get_path]. + </member> + <member name="start_location" type="Vector3" setter="set_start_location" getter="get_start_location" default="Vector3(0, 0, 0)"> + Starting position of the link. + This position will search out the nearest polygon in the navigation mesh to attach to. + The distance the link will search is controlled by [method NavigationServer3D.map_set_link_connection_radius]. + </member> + <member name="travel_cost" type="float" setter="set_travel_cost" getter="get_travel_cost" default="1.0"> + When pathfinding moves along the link the traveled distance is multiplied with [code]travel_cost[/code] for determining the shortest path. + </member> + </members> +</class> diff --git a/doc/classes/NavigationServer2D.xml b/doc/classes/NavigationServer2D.xml index b85c1c6649..0874e183e4 100644 --- a/doc/classes/NavigationServer2D.xml +++ b/doc/classes/NavigationServer2D.xml @@ -133,6 +133,117 @@ Returns all created navigation map [RID]s on the NavigationServer. This returns both 2D and 3D created navigation maps as there is technically no distinction between them. </description> </method> + <method name="link_create" qualifiers="const"> + <return type="RID" /> + <description> + Create a new link between two locations on a map. + </description> + </method> + <method name="link_get_end_location" qualifiers="const"> + <return type="Vector2" /> + <param index="0" name="link" type="RID" /> + <description> + Returns the ending location of this [code]link[/code]. + </description> + </method> + <method name="link_get_enter_cost" qualifiers="const"> + <return type="float" /> + <param index="0" name="link" type="RID" /> + <description> + Returns the [code]enter_cost[/code] of this [code]link[/code]. + </description> + </method> + <method name="link_get_map" qualifiers="const"> + <return type="RID" /> + <param index="0" name="link" type="RID" /> + <description> + Returns the navigation map [RID] the requested [code]link[/code] is currently assigned to. + </description> + </method> + <method name="link_get_navigation_layers" qualifiers="const"> + <return type="int" /> + <param index="0" name="link" type="RID" /> + <description> + Returns the navigation layers for this [code]link[/code]. + </description> + </method> + <method name="link_get_start_location" qualifiers="const"> + <return type="Vector2" /> + <param index="0" name="link" type="RID" /> + <description> + Returns the starting location of this [code]link[/code]. + </description> + </method> + <method name="link_get_travel_cost" qualifiers="const"> + <return type="float" /> + <param index="0" name="link" type="RID" /> + <description> + Returns the [code]travel_cost[/code] of this [code]link[/code]. + </description> + </method> + <method name="link_is_bidirectional" qualifiers="const"> + <return type="bool" /> + <param index="0" name="link" type="RID" /> + <description> + Returns whether this [code]link[/code] can be travelled in both directions. + </description> + </method> + <method name="link_set_bidirectional" qualifiers="const"> + <return type="void" /> + <param index="0" name="link" type="RID" /> + <param index="1" name="bidirectional" type="bool" /> + <description> + Sets whether this [code]link[/code] can be travelled in both directions. + </description> + </method> + <method name="link_set_end_location" qualifiers="const"> + <return type="void" /> + <param index="0" name="link" type="RID" /> + <param index="1" name="location" type="Vector2" /> + <description> + Sets the exit location for the [code]link[/code]. + </description> + </method> + <method name="link_set_enter_cost" qualifiers="const"> + <return type="void" /> + <param index="0" name="link" type="RID" /> + <param index="1" name="enter_cost" type="float" /> + <description> + Sets the [code]enter_cost[/code] for this [code]link[/code]. + </description> + </method> + <method name="link_set_map" qualifiers="const"> + <return type="void" /> + <param index="0" name="link" type="RID" /> + <param index="1" name="map" type="RID" /> + <description> + Sets the navigation map [RID] for the link. + </description> + </method> + <method name="link_set_navigation_layers" qualifiers="const"> + <return type="void" /> + <param index="0" name="link" type="RID" /> + <param index="1" name="navigation_layers" type="int" /> + <description> + Set the links's navigation layers. This allows selecting links from a path request (when using [method NavigationServer2D.map_get_path]). + </description> + </method> + <method name="link_set_start_location" qualifiers="const"> + <return type="void" /> + <param index="0" name="link" type="RID" /> + <param index="1" name="location" type="Vector2" /> + <description> + Sets the entry location for this [code]link[/code]. + </description> + </method> + <method name="link_set_travel_cost" qualifiers="const"> + <return type="void" /> + <param index="0" name="link" type="RID" /> + <param index="1" name="travel_cost" type="float" /> + <description> + Sets the [code]travel_cost[/code] for this [code]link[/code]. + </description> + </method> <method name="map_create" qualifiers="const"> <return type="RID" /> <description> @@ -186,6 +297,20 @@ Returns the edge connection margin of the map. The edge connection margin is a distance used to connect two regions. </description> </method> + <method name="map_get_link_connection_radius" qualifiers="const"> + <return type="float" /> + <param index="0" name="map" type="RID" /> + <description> + Returns the link connection radius of the map. This distance is the maximum range any link will search for navigation mesh polygons to connect to. + </description> + </method> + <method name="map_get_links" qualifiers="const"> + <return type="RID[]" /> + <param index="0" name="map" type="RID" /> + <description> + Returns all navigation link [RID]s that are currently assigned to the requested navigation [code]map[/code]. + </description> + </method> <method name="map_get_path" qualifiers="const"> <return type="PackedVector2Array" /> <param index="0" name="map" type="RID" /> @@ -235,6 +360,14 @@ Set the map edge connection margin used to weld the compatible region edges. </description> </method> + <method name="map_set_link_connection_radius" qualifiers="const"> + <return type="void" /> + <param index="0" name="map" type="RID" /> + <param index="1" name="radius" type="float" /> + <description> + Set the map's link connection radius used to connect links to navigation polygons. + </description> + </method> <method name="region_create" qualifiers="const"> <return type="RID" /> <description> diff --git a/doc/classes/NavigationServer3D.xml b/doc/classes/NavigationServer3D.xml index 5b2a8fc08b..255f2a902c 100644 --- a/doc/classes/NavigationServer3D.xml +++ b/doc/classes/NavigationServer3D.xml @@ -133,6 +133,117 @@ Returns all created navigation map [RID]s on the NavigationServer. This returns both 2D and 3D created navigation maps as there is technically no distinction between them. </description> </method> + <method name="link_create" qualifiers="const"> + <return type="RID" /> + <description> + Create a new link between two locations on a map. + </description> + </method> + <method name="link_get_end_location" qualifiers="const"> + <return type="Vector3" /> + <param index="0" name="link" type="RID" /> + <description> + Returns the ending location of this [code]link[/code]. + </description> + </method> + <method name="link_get_enter_cost" qualifiers="const"> + <return type="float" /> + <param index="0" name="link" type="RID" /> + <description> + Returns the [code]enter_cost[/code] of this [code]link[/code]. + </description> + </method> + <method name="link_get_map" qualifiers="const"> + <return type="RID" /> + <param index="0" name="link" type="RID" /> + <description> + Returns the navigation map [RID] the requested [code]link[/code] is currently assigned to. + </description> + </method> + <method name="link_get_navigation_layers" qualifiers="const"> + <return type="int" /> + <param index="0" name="link" type="RID" /> + <description> + Returns the navigation layers for this [code]link[/code]. + </description> + </method> + <method name="link_get_start_location" qualifiers="const"> + <return type="Vector3" /> + <param index="0" name="link" type="RID" /> + <description> + Returns the starting location of this [code]link[/code]. + </description> + </method> + <method name="link_get_travel_cost" qualifiers="const"> + <return type="float" /> + <param index="0" name="link" type="RID" /> + <description> + Returns the [code]travel_cost[/code] of this [code]link[/code]. + </description> + </method> + <method name="link_is_bidirectional" qualifiers="const"> + <return type="bool" /> + <param index="0" name="link" type="RID" /> + <description> + Returns whether this [code]link[/code] can be travelled in both directions. + </description> + </method> + <method name="link_set_bidirectional" qualifiers="const"> + <return type="void" /> + <param index="0" name="link" type="RID" /> + <param index="1" name="bidirectional" type="bool" /> + <description> + Sets whether this [code]link[/code] can be travelled in both directions. + </description> + </method> + <method name="link_set_end_location" qualifiers="const"> + <return type="void" /> + <param index="0" name="link" type="RID" /> + <param index="1" name="location" type="Vector3" /> + <description> + Sets the exit location for the [code]link[/code]. + </description> + </method> + <method name="link_set_enter_cost" qualifiers="const"> + <return type="void" /> + <param index="0" name="link" type="RID" /> + <param index="1" name="enter_cost" type="float" /> + <description> + Sets the [code]enter_cost[/code] for this [code]link[/code]. + </description> + </method> + <method name="link_set_map" qualifiers="const"> + <return type="void" /> + <param index="0" name="link" type="RID" /> + <param index="1" name="map" type="RID" /> + <description> + Sets the navigation map [RID] for the link. + </description> + </method> + <method name="link_set_navigation_layers" qualifiers="const"> + <return type="void" /> + <param index="0" name="link" type="RID" /> + <param index="1" name="navigation_layers" type="int" /> + <description> + Set the links's navigation layers. This allows selecting links from a path request (when using [method NavigationServer3D.map_get_path]). + </description> + </method> + <method name="link_set_start_location" qualifiers="const"> + <return type="void" /> + <param index="0" name="link" type="RID" /> + <param index="1" name="location" type="Vector3" /> + <description> + Sets the entry location for this [code]link[/code]. + </description> + </method> + <method name="link_set_travel_cost" qualifiers="const"> + <return type="void" /> + <param index="0" name="link" type="RID" /> + <param index="1" name="travel_cost" type="float" /> + <description> + Sets the [code]travel_cost[/code] for this [code]link[/code]. + </description> + </method> <method name="map_create" qualifiers="const"> <return type="RID" /> <description> @@ -204,6 +315,20 @@ Returns the edge connection margin of the map. This distance is the minimum vertex distance needed to connect two edges from different regions. </description> </method> + <method name="map_get_link_connection_radius" qualifiers="const"> + <return type="float" /> + <param index="0" name="map" type="RID" /> + <description> + Returns the link connection radius of the map. This distance is the maximum range any link will search for navigation mesh polygons to connect to. + </description> + </method> + <method name="map_get_links" qualifiers="const"> + <return type="RID[]" /> + <param index="0" name="map" type="RID" /> + <description> + Returns all navigation link [RID]s that are currently assigned to the requested navigation [code]map[/code]. + </description> + </method> <method name="map_get_path" qualifiers="const"> <return type="PackedVector3Array" /> <param index="0" name="map" type="RID" /> @@ -260,6 +385,14 @@ Set the map edge connection margin used to weld the compatible region edges. </description> </method> + <method name="map_set_link_connection_radius" qualifiers="const"> + <return type="void" /> + <param index="0" name="map" type="RID" /> + <param index="1" name="radius" type="float" /> + <description> + Set the map's link connection radius used to connect links to navigation polygons. + </description> + </method> <method name="map_set_up" qualifiers="const"> <return type="void" /> <param index="0" name="map" type="RID" /> diff --git a/doc/classes/PacketPeerExtension.xml b/doc/classes/PacketPeerExtension.xml index 28263b3f59..afb1aa4016 100644 --- a/doc/classes/PacketPeerExtension.xml +++ b/doc/classes/PacketPeerExtension.xml @@ -18,14 +18,14 @@ </description> </method> <method name="_get_packet" qualifiers="virtual"> - <return type="int" /> + <return type="int" enum="Error" /> <param index="0" name="r_buffer" type="const uint8_t **" /> <param index="1" name="r_buffer_size" type="int32_t*" /> <description> </description> </method> <method name="_put_packet" qualifiers="virtual"> - <return type="int" /> + <return type="int" enum="Error" /> <param index="0" name="p_buffer" type="const uint8_t*" /> <param index="1" name="p_buffer_size" type="int" /> <description> diff --git a/doc/classes/PhysicsPointQueryParameters2D.xml b/doc/classes/PhysicsPointQueryParameters2D.xml index c1005f02a3..a6cbe2d574 100644 --- a/doc/classes/PhysicsPointQueryParameters2D.xml +++ b/doc/classes/PhysicsPointQueryParameters2D.xml @@ -21,7 +21,7 @@ <member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="4294967295"> The physics layers the query will detect (as a bitmask). By default, all collision layers are detected. See [url=$DOCS_URL/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information. </member> - <member name="exclude" type="Array" setter="set_exclude" getter="get_exclude" default="[]"> + <member name="exclude" type="RID[]" setter="set_exclude" getter="get_exclude" default="[]"> The list of objects or object [RID]s that will be excluded from collisions. </member> <member name="position" type="Vector2" setter="set_position" getter="get_position" default="Vector2(0, 0)"> diff --git a/doc/classes/PhysicsRayQueryParameters2D.xml b/doc/classes/PhysicsRayQueryParameters2D.xml index 5afd3973a0..d6a2662adc 100644 --- a/doc/classes/PhysicsRayQueryParameters2D.xml +++ b/doc/classes/PhysicsRayQueryParameters2D.xml @@ -14,7 +14,7 @@ <param index="0" name="from" type="Vector2" /> <param index="1" name="to" type="Vector2" /> <param index="2" name="collision_mask" type="int" default="4294967295" /> - <param index="3" name="exclude" type="Array" default="[]" /> + <param index="3" name="exclude" type="RID[]" default="[]" /> <description> Returns a new, pre-configured [PhysicsRayQueryParameters2D] object. Use it to quickly create query parameters using the most common options. [codeblock] @@ -34,7 +34,7 @@ <member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="4294967295"> The physics layers the query will detect (as a bitmask). By default, all collision layers are detected. See [url=$DOCS_URL/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information. </member> - <member name="exclude" type="Array" setter="set_exclude" getter="get_exclude" default="[]"> + <member name="exclude" type="RID[]" setter="set_exclude" getter="get_exclude" default="[]"> The list of objects or object [RID]s that will be excluded from collisions. </member> <member name="from" type="Vector2" setter="set_from" getter="get_from" default="Vector2(0, 0)"> diff --git a/doc/classes/PhysicsShapeQueryParameters2D.xml b/doc/classes/PhysicsShapeQueryParameters2D.xml index 3fbb0c0ed0..8dcb329e7e 100644 --- a/doc/classes/PhysicsShapeQueryParameters2D.xml +++ b/doc/classes/PhysicsShapeQueryParameters2D.xml @@ -18,7 +18,7 @@ <member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="4294967295"> The physics layers the query will detect (as a bitmask). By default, all collision layers are detected. See [url=$DOCS_URL/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information. </member> - <member name="exclude" type="Array" setter="set_exclude" getter="get_exclude" default="[]"> + <member name="exclude" type="RID[]" setter="set_exclude" getter="get_exclude" default="[]"> The list of objects or object [RID]s that will be excluded from collisions. </member> <member name="margin" type="float" setter="set_margin" getter="get_margin" default="0.0"> diff --git a/doc/classes/PhysicsTestMotionParameters2D.xml b/doc/classes/PhysicsTestMotionParameters2D.xml index 00f21a2058..4f2b62f2d9 100644 --- a/doc/classes/PhysicsTestMotionParameters2D.xml +++ b/doc/classes/PhysicsTestMotionParameters2D.xml @@ -13,7 +13,7 @@ If set to [code]true[/code], shapes of type [constant PhysicsServer2D.SHAPE_SEPARATION_RAY] are used to detect collisions and can stop the motion. Can be useful when snapping to the ground. If set to [code]false[/code], shapes of type [constant PhysicsServer2D.SHAPE_SEPARATION_RAY] are only used for separation when overlapping with other bodies. That's the main use for separation ray shapes. </member> - <member name="exclude_bodies" type="Array" setter="set_exclude_bodies" getter="get_exclude_bodies" default="[]"> + <member name="exclude_bodies" type="RID[]" setter="set_exclude_bodies" getter="get_exclude_bodies" default="[]"> Optional array of body [RID] to exclude from collision. </member> <member name="exclude_objects" type="Array" setter="set_exclude_objects" getter="get_exclude_objects" default="[]"> diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index ffafff0ff4..47837cd9e1 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -283,6 +283,7 @@ </member> <member name="audio/driver/enable_input" type="bool" setter="" getter="" default="false"> If [code]true[/code], microphone input will be allowed. This requires appropriate permissions to be set when exporting to Android or iOS. + [b]Note:[/b] If the operating system blocks access to audio input devices (due to the user's privacy settings), audio capture will only return silence. On Windows 10 and later, make sure that apps are allowed to access the microphone in the OS' privacy settings. </member> <member name="audio/driver/mix_rate" type="int" setter="" getter="" default="44100"> The mixing rate used for audio (in Hz). In general, it's better to not touch this and leave it to the host operating system. @@ -497,6 +498,12 @@ <member name="debug/shapes/navigation/enable_geometry_face_random_color" type="bool" setter="" getter="" default="true"> If enabled, colorizes each navigation mesh polygon face with a random color when "Visible Navigation" is enabled in the Debug menu. </member> + <member name="debug/shapes/navigation/enable_link_connections" type="bool" setter="" getter="" default="true"> + If enabled, displays navigation link connections when "Visible Navigation" is enabled in the Debug menu. + </member> + <member name="debug/shapes/navigation/enable_link_connections_xray" type="bool" setter="" getter="" default="true"> + If enabled, displays navigation link connections through geometry when "Visible Navigation" is enabled in the Debug menu. + </member> <member name="debug/shapes/navigation/geometry_color" type="Color" setter="" getter="" default="Color(0.1, 1, 0.7, 0.4)"> Color of the navigation geometry, visible when "Visible Navigation" is enabled in the Debug menu. </member> @@ -512,6 +519,12 @@ <member name="debug/shapes/navigation/geometry_face_disabled_color" type="Color" setter="" getter="" default="Color(0.5, 0.5, 0.5, 0.4)"> Color to display disabled navigation mesh polygon faces, visible when "Visible Navigation" is enabled in the Debug menu. </member> + <member name="debug/shapes/navigation/link_connection_color" type="Color" setter="" getter="" default="Color(1, 0.5, 1, 1)"> + Color to use to display navigation link connections, visible when "Visible Navigation" is enabled in the Debug menu. + </member> + <member name="debug/shapes/navigation/link_connection_disabled_color" type="Color" setter="" getter="" default="Color(0.5, 0.5, 0.5, 1)"> + Color to use to display disabled navigation link connections, visible when "Visible Navigation" is enabled in the Debug menu. + </member> <member name="debug/shapes/paths/geometry_color" type="Color" setter="" getter="" default="Color(0.1, 1, 0.7, 0.4)"> Color of the curve path geometry, visible when "Visible Paths" is enabled in the Debug menu. </member> @@ -1439,12 +1452,18 @@ <member name="navigation/2d/default_edge_connection_margin" type="int" setter="" getter="" default="1"> Default edge connection margin for 2D navigation maps. See [method NavigationServer2D.map_set_edge_connection_margin]. </member> + <member name="navigation/2d/default_link_connection_radius" type="int" setter="" getter="" default="4"> + Default link connection radius for 2D navigation maps. See [method NavigationServer2D.map_set_link_connection_radius]. + </member> <member name="navigation/3d/default_cell_size" type="float" setter="" getter="" default="0.25"> Default cell size for 3D navigation maps. See [method NavigationServer3D.map_set_cell_size]. </member> <member name="navigation/3d/default_edge_connection_margin" type="float" setter="" getter="" default="0.25"> Default edge connection margin for 3D navigation maps. See [method NavigationServer3D.map_set_edge_connection_margin]. </member> + <member name="navigation/3d/default_link_connection_radius" type="float" setter="" getter="" default="1.0"> + Default link connection radius for 3D navigation maps. See [method NavigationServer3D.map_set_link_connection_radius]. + </member> <member name="network/limits/debugger/max_chars_per_second" type="int" setter="" getter="" default="32768"> Maximum number of characters allowed to send as output from the debugger. Over this value, content is dropped. This helps not to stall the debugger connection. </member> diff --git a/doc/classes/RenderingDevice.xml b/doc/classes/RenderingDevice.xml index 718a161323..eb85a4adb4 100644 --- a/doc/classes/RenderingDevice.xml +++ b/doc/classes/RenderingDevice.xml @@ -631,7 +631,7 @@ </method> <method name="uniform_set_create"> <return type="RID" /> - <param index="0" name="uniforms" type="Array" /> + <param index="0" name="uniforms" type="RDUniform[]" /> <param index="1" name="shader" type="RID" /> <param index="2" name="shader_set" type="int" /> <description> diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 1366099e75..6aa9237385 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -21,7 +21,7 @@ <method name="bake_render_uv2"> <return type="Image[]" /> <param index="0" name="base" type="RID" /> - <param index="1" name="material_overrides" type="Array" /> + <param index="1" name="material_overrides" type="RID[]" /> <param index="2" name="image_size" type="Vector2i" /> <description> </description> @@ -1025,6 +1025,7 @@ <param index="6" name="height" type="float" /> <param index="7" name="height_density" type="float" /> <param index="8" name="aerial_perspective" type="float" /> + <param index="9" name="sky_affect" type="float" /> <description> </description> </method> @@ -1187,6 +1188,7 @@ <param index="10" name="temporal_reprojection" type="bool" /> <param index="11" name="temporal_reprojection_amount" type="float" /> <param index="12" name="ambient_inject" type="float" /> + <param index="13" name="sky_affect" type="float" /> <description> </description> </method> @@ -1270,6 +1272,13 @@ <description> </description> </method> + <method name="get_shader_parameter_list" qualifiers="const"> + <return type="Dictionary[]" /> + <param index="0" name="shader" type="RID" /> + <description> + Returns the parameters of a shader. + </description> + </method> <method name="get_test_cube"> <return type="RID" /> <description> @@ -1323,45 +1332,45 @@ If [param half_resolution] is [code]true[/code], renders [VoxelGI] and SDFGI ([member Environment.sdfgi_enabled]) buffers at halved resolution (e.g. 960×540 when the viewport size is 1920×1080). This improves performance significantly when VoxelGI or SDFGI is enabled, at the cost of artifacts that may be visible on polygon edges. The loss in quality becomes less noticeable as the viewport resolution increases. [LightmapGI] rendering is not affected by this setting. See also [member ProjectSettings.rendering/global_illumination/gi/use_half_resolution]. </description> </method> - <method name="global_shader_uniform_add"> + <method name="global_shader_parameter_add"> <return type="void" /> <param index="0" name="name" type="StringName" /> - <param index="1" name="type" type="int" enum="RenderingServer.GlobalShaderUniformType" /> + <param index="1" name="type" type="int" enum="RenderingServer.GlobalShaderParameterType" /> <param index="2" name="default_value" type="Variant" /> <description> </description> </method> - <method name="global_shader_uniform_get" qualifiers="const"> + <method name="global_shader_parameter_get" qualifiers="const"> <return type="Variant" /> <param index="0" name="name" type="StringName" /> <description> </description> </method> - <method name="global_shader_uniform_get_list" qualifiers="const"> + <method name="global_shader_parameter_get_list" qualifiers="const"> <return type="PackedStringArray" /> <description> </description> </method> - <method name="global_shader_uniform_get_type" qualifiers="const"> - <return type="int" enum="RenderingServer.GlobalShaderUniformType" /> + <method name="global_shader_parameter_get_type" qualifiers="const"> + <return type="int" enum="RenderingServer.GlobalShaderParameterType" /> <param index="0" name="name" type="StringName" /> <description> </description> </method> - <method name="global_shader_uniform_remove"> + <method name="global_shader_parameter_remove"> <return type="void" /> <param index="0" name="name" type="StringName" /> <description> </description> </method> - <method name="global_shader_uniform_set"> + <method name="global_shader_parameter_set"> <return type="void" /> <param index="0" name="name" type="StringName" /> <param index="1" name="value" type="Variant" /> <description> </description> </method> - <method name="global_shader_uniform_set_override"> + <method name="global_shader_parameter_set_override"> <return type="void" /> <param index="0" name="name" type="StringName" /> <param index="1" name="value" type="Variant" /> @@ -1421,21 +1430,21 @@ Once finished with your RID, you will want to free the RID using the RenderingServer's [method free_rid] static method. </description> </method> - <method name="instance_geometry_get_shader_uniform" qualifiers="const"> + <method name="instance_geometry_get_shader_parameter" qualifiers="const"> <return type="Variant" /> <param index="0" name="instance" type="RID" /> <param index="1" name="parameter" type="StringName" /> <description> </description> </method> - <method name="instance_geometry_get_shader_uniform_default_value" qualifiers="const"> + <method name="instance_geometry_get_shader_parameter_default_value" qualifiers="const"> <return type="Variant" /> <param index="0" name="instance" type="RID" /> <param index="1" name="parameter" type="StringName" /> <description> </description> </method> - <method name="instance_geometry_get_shader_uniform_list" qualifiers="const"> + <method name="instance_geometry_get_shader_parameter_list" qualifiers="const"> <return type="Dictionary[]" /> <param index="0" name="instance" type="RID" /> <description> @@ -1490,7 +1499,7 @@ Sets a material that will override the material for all surfaces on the mesh associated with this instance. Equivalent to [member GeometryInstance3D.material_override]. </description> </method> - <method name="instance_geometry_set_shader_uniform"> + <method name="instance_geometry_set_shader_parameter"> <return type="void" /> <param index="0" name="instance" type="RID" /> <param index="1" name="parameter" type="StringName" /> @@ -1621,7 +1630,7 @@ </method> <method name="instances_cull_convex" qualifiers="const"> <return type="PackedInt64Array" /> - <param index="0" name="convex" type="Array" /> + <param index="0" name="convex" type="Plane[]" /> <param index="1" name="scenario" type="RID" /> <description> Returns an array of object IDs intersecting with the provided convex shape. Only visual 3D nodes are considered, such as [MeshInstance3D] or [DirectionalLight3D]. Use [method @GlobalScope.instance_from_id] to obtain the actual nodes. A scenario RID must be provided, which is available in the [World3D] you want to query. This forces an update for all resources queued to update. @@ -2762,30 +2771,23 @@ Returns a shader's code. </description> </method> - <method name="shader_get_default_texture_param" qualifiers="const"> + <method name="shader_get_default_texture_parameter" qualifiers="const"> <return type="RID" /> <param index="0" name="shader" type="RID" /> - <param index="1" name="param" type="StringName" /> + <param index="1" name="name" type="StringName" /> <param index="2" name="index" type="int" default="0" /> <description> Returns a default texture from a shader searched by name. [b]Note:[/b] If the sampler array is used use [param index] to access the specified texture. </description> </method> - <method name="shader_get_param_default" qualifiers="const"> + <method name="shader_get_parameter_default" qualifiers="const"> <return type="Variant" /> <param index="0" name="shader" type="RID" /> - <param index="1" name="param" type="StringName" /> + <param index="1" name="name" type="StringName" /> <description> </description> </method> - <method name="shader_get_shader_uniform_list" qualifiers="const"> - <return type="Dictionary[]" /> - <param index="0" name="shader" type="RID" /> - <description> - Returns the parameters of a shader. - </description> - </method> <method name="shader_set_code"> <return type="void" /> <param index="0" name="shader" type="RID" /> @@ -2793,10 +2795,10 @@ <description> </description> </method> - <method name="shader_set_default_texture_param"> + <method name="shader_set_default_texture_parameter"> <return type="void" /> <param index="0" name="shader" type="RID" /> - <param index="1" name="param" type="StringName" /> + <param index="1" name="name" type="StringName" /> <param index="2" name="texture" type="RID" /> <param index="3" name="index" type="int" default="0" /> <description> @@ -4612,63 +4614,63 @@ <constant name="CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE" value="2" enum="CanvasOccluderPolygonCullMode"> Culling of the canvas occluder is counterclockwise. </constant> - <constant name="GLOBAL_VAR_TYPE_BOOL" value="0" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_BOOL" value="0" enum="GlobalShaderParameterType"> </constant> - <constant name="GLOBAL_VAR_TYPE_BVEC2" value="1" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_BVEC2" value="1" enum="GlobalShaderParameterType"> </constant> - <constant name="GLOBAL_VAR_TYPE_BVEC3" value="2" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_BVEC3" value="2" enum="GlobalShaderParameterType"> </constant> - <constant name="GLOBAL_VAR_TYPE_BVEC4" value="3" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_BVEC4" value="3" enum="GlobalShaderParameterType"> </constant> - <constant name="GLOBAL_VAR_TYPE_INT" value="4" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_INT" value="4" enum="GlobalShaderParameterType"> </constant> - <constant name="GLOBAL_VAR_TYPE_IVEC2" value="5" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_IVEC2" value="5" enum="GlobalShaderParameterType"> </constant> - <constant name="GLOBAL_VAR_TYPE_IVEC3" value="6" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_IVEC3" value="6" enum="GlobalShaderParameterType"> </constant> - <constant name="GLOBAL_VAR_TYPE_IVEC4" value="7" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_IVEC4" value="7" enum="GlobalShaderParameterType"> </constant> - <constant name="GLOBAL_VAR_TYPE_RECT2I" value="8" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_RECT2I" value="8" enum="GlobalShaderParameterType"> </constant> - <constant name="GLOBAL_VAR_TYPE_UINT" value="9" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_UINT" value="9" enum="GlobalShaderParameterType"> </constant> - <constant name="GLOBAL_VAR_TYPE_UVEC2" value="10" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_UVEC2" value="10" enum="GlobalShaderParameterType"> </constant> - <constant name="GLOBAL_VAR_TYPE_UVEC3" value="11" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_UVEC3" value="11" enum="GlobalShaderParameterType"> </constant> - <constant name="GLOBAL_VAR_TYPE_UVEC4" value="12" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_UVEC4" value="12" enum="GlobalShaderParameterType"> </constant> - <constant name="GLOBAL_VAR_TYPE_FLOAT" value="13" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_FLOAT" value="13" enum="GlobalShaderParameterType"> </constant> - <constant name="GLOBAL_VAR_TYPE_VEC2" value="14" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_VEC2" value="14" enum="GlobalShaderParameterType"> </constant> - <constant name="GLOBAL_VAR_TYPE_VEC3" value="15" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_VEC3" value="15" enum="GlobalShaderParameterType"> </constant> - <constant name="GLOBAL_VAR_TYPE_VEC4" value="16" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_VEC4" value="16" enum="GlobalShaderParameterType"> </constant> - <constant name="GLOBAL_VAR_TYPE_COLOR" value="17" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_COLOR" value="17" enum="GlobalShaderParameterType"> </constant> - <constant name="GLOBAL_VAR_TYPE_RECT2" value="18" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_RECT2" value="18" enum="GlobalShaderParameterType"> </constant> - <constant name="GLOBAL_VAR_TYPE_MAT2" value="19" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_MAT2" value="19" enum="GlobalShaderParameterType"> </constant> - <constant name="GLOBAL_VAR_TYPE_MAT3" value="20" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_MAT3" value="20" enum="GlobalShaderParameterType"> </constant> - <constant name="GLOBAL_VAR_TYPE_MAT4" value="21" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_MAT4" value="21" enum="GlobalShaderParameterType"> </constant> - <constant name="GLOBAL_VAR_TYPE_TRANSFORM_2D" value="22" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_TRANSFORM_2D" value="22" enum="GlobalShaderParameterType"> </constant> - <constant name="GLOBAL_VAR_TYPE_TRANSFORM" value="23" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_TRANSFORM" value="23" enum="GlobalShaderParameterType"> </constant> - <constant name="GLOBAL_VAR_TYPE_SAMPLER2D" value="24" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_SAMPLER2D" value="24" enum="GlobalShaderParameterType"> </constant> - <constant name="GLOBAL_VAR_TYPE_SAMPLER2DARRAY" value="25" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_SAMPLER2DARRAY" value="25" enum="GlobalShaderParameterType"> </constant> - <constant name="GLOBAL_VAR_TYPE_SAMPLER3D" value="26" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_SAMPLER3D" value="26" enum="GlobalShaderParameterType"> </constant> - <constant name="GLOBAL_VAR_TYPE_SAMPLERCUBE" value="27" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_SAMPLERCUBE" value="27" enum="GlobalShaderParameterType"> </constant> - <constant name="GLOBAL_VAR_TYPE_MAX" value="28" enum="GlobalShaderUniformType"> + <constant name="GLOBAL_VAR_TYPE_MAX" value="28" enum="GlobalShaderParameterType"> </constant> <constant name="RENDERING_INFO_TOTAL_OBJECTS_IN_FRAME" value="0" enum="RenderingInfo"> </constant> diff --git a/doc/classes/SceneTree.xml b/doc/classes/SceneTree.xml index 417703ff01..221e627e35 100644 --- a/doc/classes/SceneTree.xml +++ b/doc/classes/SceneTree.xml @@ -58,8 +58,13 @@ <return type="SceneTreeTimer" /> <param index="0" name="time_sec" type="float" /> <param index="1" name="process_always" type="bool" default="true" /> + <param index="2" name="process_in_physics" type="bool" default="false" /> + <param index="3" name="ignore_time_scale" type="bool" default="false" /> <description> - Returns a [SceneTreeTimer] which will [signal SceneTreeTimer.timeout] after the given time in seconds elapsed in this [SceneTree]. If [param process_always] is set to [code]false[/code], pausing the [SceneTree] will also pause the timer. + Returns a [SceneTreeTimer] which will [signal SceneTreeTimer.timeout] after the given time in seconds elapsed in this [SceneTree]. + If [code]process_always[/code] is set to [code]false[/code], pausing the [SceneTree] will also pause the timer. + If [code]process_in_physics[/code] is set to [code]true[/code], will update the [SceneTreeTimer] during the physics frame instead of the process frame (fixed framerate processing). + If [code]ignore_time_scale[/code] is set to [code]true[/code], will ignore [member Engine.time_scale] and update the [SceneTreeTimer] with the actual frame delta. Commonly used to create a one-shot delay timer as in the following example: [codeblocks] [gdscript] diff --git a/doc/classes/Shader.xml b/doc/classes/Shader.xml index b7e6d80ccb..75f835260a 100644 --- a/doc/classes/Shader.xml +++ b/doc/classes/Shader.xml @@ -10,13 +10,13 @@ <link title="Shaders documentation index">$DOCS_URL/tutorials/shaders/index.html</link> </tutorials> <methods> - <method name="get_default_texture_param" qualifiers="const"> + <method name="get_default_texture_parameter" qualifiers="const"> <return type="Texture2D" /> - <param index="0" name="param" type="StringName" /> + <param index="0" name="name" type="StringName" /> <param index="1" name="index" type="int" default="0" /> <description> Returns the texture that is set as default for the specified parameter. - [b]Note:[/b] [param param] must match the name of the uniform in the code exactly. + [b]Note:[/b] [param name] must match the name of the uniform in the code exactly. [b]Note:[/b] If the sampler array is used use [param index] to access the specified texture. </description> </method> @@ -26,7 +26,7 @@ Returns the shader mode for the shader, either [constant MODE_CANVAS_ITEM], [constant MODE_SPATIAL] or [constant MODE_PARTICLES]. </description> </method> - <method name="has_uniform" qualifiers="const"> + <method name="has_parameter" qualifiers="const"> <return type="bool" /> <param index="0" name="name" type="StringName" /> <description> @@ -34,14 +34,14 @@ [b]Note:[/b] [param name] must match the name of the uniform in the code exactly. </description> </method> - <method name="set_default_texture_param"> + <method name="set_default_texture_parameter"> <return type="void" /> - <param index="0" name="param" type="StringName" /> + <param index="0" name="name" type="StringName" /> <param index="1" name="texture" type="Texture2D" /> <param index="2" name="index" type="int" default="0" /> <description> Sets the default texture to be used with a texture uniform. The default is used if a texture is not set in the [ShaderMaterial]. - [b]Note:[/b] [param param] must match the name of the uniform in the code exactly. + [b]Note:[/b] [param name] must match the name of the uniform in the code exactly. [b]Note:[/b] If the sampler array is used use [param index] to access the specified texture. </description> </method> diff --git a/doc/classes/ShaderMaterial.xml b/doc/classes/ShaderMaterial.xml index 8d4df87b39..1af7ac4fc5 100644 --- a/doc/classes/ShaderMaterial.xml +++ b/doc/classes/ShaderMaterial.xml @@ -10,14 +10,14 @@ <link title="Shaders documentation index">$DOCS_URL/tutorials/shaders/index.html</link> </tutorials> <methods> - <method name="get_shader_uniform" qualifiers="const"> + <method name="get_shader_parameter" qualifiers="const"> <return type="Variant" /> <param index="0" name="param" type="StringName" /> <description> Returns the current value set for this material of a uniform in the shader. </description> </method> - <method name="set_shader_uniform"> + <method name="set_shader_parameter"> <return type="void" /> <param index="0" name="param" type="StringName" /> <param index="1" name="value" type="Variant" /> diff --git a/doc/classes/SplitContainer.xml b/doc/classes/SplitContainer.xml index fb4b9466b5..f5646e9e97 100644 --- a/doc/classes/SplitContainer.xml +++ b/doc/classes/SplitContainer.xml @@ -27,6 +27,10 @@ <member name="split_offset" type="int" setter="set_split_offset" getter="get_split_offset" default="0"> The initial offset of the splitting between the two [Control]s, with [code]0[/code] being at the end of the first [Control]. </member> + <member name="vertical" type="bool" setter="set_vertical" getter="is_vertical" default="false"> + If [code]true[/code], the [SplitContainer] will arrange its children vertically, rather than horizontally. + Can't be changed when using [HSplitContainer] and [VSplitContainer]. + </member> </members> <signals> <signal name="dragged"> @@ -47,4 +51,18 @@ The split dragger is never visible and its space collapsed. </constant> </constants> + <theme_items> + <theme_item name="autohide" data_type="constant" type="int" default="1"> + Boolean value. If 1 ([code]true[/code]), the grabber will hide automatically when it isn't under the cursor. If 0 ([code]false[/code]), it's always visible. + </theme_item> + <theme_item name="separation" data_type="constant" type="int" default="12"> + The space between sides of the container. + </theme_item> + <theme_item name="h_grabber" data_type="icon" type="Texture2D"> + The icon used for the grabber drawn in the middle area when [member vertical] is [code]false[/code]. + </theme_item> + <theme_item name="v_grabber" data_type="icon" type="Texture2D"> + The icon used for the grabber drawn in the middle area when [member vertical] is [code]true[/code]. + </theme_item> + </theme_items> </class> diff --git a/doc/classes/StreamPeerExtension.xml b/doc/classes/StreamPeerExtension.xml index 46783de275..ab4bcfd17c 100644 --- a/doc/classes/StreamPeerExtension.xml +++ b/doc/classes/StreamPeerExtension.xml @@ -13,7 +13,7 @@ </description> </method> <method name="_get_data" qualifiers="virtual"> - <return type="int" /> + <return type="int" enum="Error" /> <param index="0" name="r_buffer" type="uint8_t*" /> <param index="1" name="r_bytes" type="int" /> <param index="2" name="r_received" type="int32_t*" /> @@ -21,7 +21,7 @@ </description> </method> <method name="_get_partial_data" qualifiers="virtual"> - <return type="int" /> + <return type="int" enum="Error" /> <param index="0" name="r_buffer" type="uint8_t*" /> <param index="1" name="r_bytes" type="int" /> <param index="2" name="r_received" type="int32_t*" /> @@ -29,7 +29,7 @@ </description> </method> <method name="_put_data" qualifiers="virtual"> - <return type="int" /> + <return type="int" enum="Error" /> <param index="0" name="p_data" type="const uint8_t*" /> <param index="1" name="p_bytes" type="int" /> <param index="2" name="r_sent" type="int32_t*" /> @@ -37,7 +37,7 @@ </description> </method> <method name="_put_partial_data" qualifiers="virtual"> - <return type="int" /> + <return type="int" enum="Error" /> <param index="0" name="p_data" type="const uint8_t*" /> <param index="1" name="p_bytes" type="int" /> <param index="2" name="r_sent" type="int32_t*" /> diff --git a/doc/classes/TextServer.xml b/doc/classes/TextServer.xml index 1aec6d2c0e..0db16b491d 100644 --- a/doc/classes/TextServer.xml +++ b/doc/classes/TextServer.xml @@ -1035,7 +1035,7 @@ <return type="void" /> <param index="0" name="shaped" type="RID" /> <param index="1" name="index" type="int" /> - <param index="2" name="fonts" type="Array" /> + <param index="2" name="fonts" type="RID[]" /> <param index="3" name="size" type="int" /> <param index="4" name="opentype_features" type="Dictionary" default="{}" /> <description> @@ -1057,7 +1057,7 @@ <return type="bool" /> <param index="0" name="shaped" type="RID" /> <param index="1" name="text" type="String" /> - <param index="2" name="fonts" type="Array" /> + <param index="2" name="fonts" type="RID[]" /> <param index="3" name="size" type="int" /> <param index="4" name="opentype_features" type="Dictionary" default="{}" /> <param index="5" name="language" type="String" default="""" /> diff --git a/doc/classes/TextServerExtension.xml b/doc/classes/TextServerExtension.xml index 23eb25dc10..4886bf0757 100644 --- a/doc/classes/TextServerExtension.xml +++ b/doc/classes/TextServerExtension.xml @@ -1020,7 +1020,7 @@ <return type="void" /> <param index="0" name="shaped" type="RID" /> <param index="1" name="index" type="int" /> - <param index="2" name="fonts" type="Array" /> + <param index="2" name="fonts" type="RID[]" /> <param index="3" name="size" type="int" /> <param index="4" name="opentype_features" type="Dictionary" /> <description> @@ -1042,7 +1042,7 @@ <return type="bool" /> <param index="0" name="shaped" type="RID" /> <param index="1" name="text" type="String" /> - <param index="2" name="fonts" type="Array" /> + <param index="2" name="fonts" type="RID[]" /> <param index="3" name="size" type="int" /> <param index="4" name="opentype_features" type="Dictionary" /> <param index="5" name="language" type="String" /> diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml index 2197947126..e1852340c0 100644 --- a/doc/classes/Vector2.xml +++ b/doc/classes/Vector2.xml @@ -212,6 +212,13 @@ Returns [code]true[/code] if the vector is normalized, [code]false[/code] otherwise. </description> </method> + <method name="is_zero_approx" qualifiers="const"> + <return type="bool" /> + <description> + Returns [code]true[/code] if this vector's values are approximately zero, by running [method @GlobalScope.is_zero_approx] on each component. + This method is faster than using [method is_equal_approx] with one value as a zero vector. + </description> + </method> <method name="length" qualifiers="const"> <return type="float" /> <description> diff --git a/doc/classes/Vector3.xml b/doc/classes/Vector3.xml index 150d53845c..1ef84050cd 100644 --- a/doc/classes/Vector3.xml +++ b/doc/classes/Vector3.xml @@ -180,6 +180,13 @@ Returns [code]true[/code] if the vector is normalized, [code]false[/code] otherwise. </description> </method> + <method name="is_zero_approx" qualifiers="const"> + <return type="bool" /> + <description> + Returns [code]true[/code] if this vector's values are approximately zero, by running [method @GlobalScope.is_zero_approx] on each component. + This method is faster than using [method is_equal_approx] with one value as a zero vector. + </description> + </method> <method name="length" qualifiers="const"> <return type="float" /> <description> diff --git a/doc/classes/Vector4.xml b/doc/classes/Vector4.xml index b9f509cfe7..fdc93f82ec 100644 --- a/doc/classes/Vector4.xml +++ b/doc/classes/Vector4.xml @@ -28,7 +28,7 @@ <return type="Vector4" /> <param index="0" name="from" type="Vector4i" /> <description> - Constructs a new [Vector4] from [Vector4i]. + Constructs a new [Vector4] from the given [Vector4i]. </description> </constructor> <constructor name="Vector4"> @@ -141,6 +141,13 @@ Returns [code]true[/code] if the vector is normalized, i.e. its length is equal to 1. </description> </method> + <method name="is_zero_approx" qualifiers="const"> + <return type="bool" /> + <description> + Returns [code]true[/code] if this vector's values are approximately zero, by running [method @GlobalScope.is_zero_approx] on each component. + This method is faster than using [method is_equal_approx] with one value as a zero vector. + </description> + </method> <method name="length" qualifiers="const"> <return type="float" /> <description> diff --git a/doc/classes/Vector4i.xml b/doc/classes/Vector4i.xml index 9a36c3c4fa..3eea93ce1f 100644 --- a/doc/classes/Vector4i.xml +++ b/doc/classes/Vector4i.xml @@ -1,8 +1,11 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="Vector4i" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> + Vector used for 4D math using integer coordinates. </brief_description> <description> + 4-element structure that can be used to represent 4D grid coordinates or sets of integers. + It uses integer coordinates. See [Vector4] for its floating-point counterpart. </description> <tutorials> </tutorials> @@ -10,18 +13,21 @@ <constructor name="Vector4i"> <return type="Vector4i" /> <description> + Constructs a default-initialized [Vector4i] with all components set to [code]0[/code]. </description> </constructor> <constructor name="Vector4i"> <return type="Vector4i" /> <param index="0" name="from" type="Vector4i" /> <description> + Constructs a [Vector4i] as a copy of the given [Vector4i]. </description> </constructor> <constructor name="Vector4i"> <return type="Vector4i" /> <param index="0" name="from" type="Vector4" /> <description> + Constructs a new [Vector4i] from the given [Vector4]. </description> </constructor> <constructor name="Vector4i"> @@ -31,6 +37,7 @@ <param index="2" name="z" type="int" /> <param index="3" name="w" type="int" /> <description> + Returns a [Vector4i] with the given components. </description> </constructor> </constructors> @@ -38,6 +45,7 @@ <method name="abs" qualifiers="const"> <return type="Vector4i" /> <description> + Returns a new vector with all components in absolute values (i.e. positive). </description> </method> <method name="clamp" qualifiers="const"> @@ -45,56 +53,72 @@ <param index="0" name="min" type="Vector4i" /> <param index="1" name="max" type="Vector4i" /> <description> + Returns a new vector with all components clamped between the components of [param min] and [param max], by running [method @GlobalScope.clamp] on each component. </description> </method> <method name="length" qualifiers="const"> <return type="float" /> <description> + Returns the length (magnitude) of this vector. </description> </method> <method name="length_squared" qualifiers="const"> <return type="int" /> <description> + Returns the squared length (squared magnitude) of this vector. This method runs faster than [method length]. </description> </method> <method name="max_axis_index" qualifiers="const"> <return type="int" /> <description> + Returns the axis of the vector's highest value. See [code]AXIS_*[/code] constants. If all components are equal, this method returns [constant AXIS_X]. </description> </method> <method name="min_axis_index" qualifiers="const"> <return type="int" /> <description> + Returns the axis of the vector's lowest value. See [code]AXIS_*[/code] constants. If all components are equal, this method returns [constant AXIS_W]. </description> </method> <method name="sign" qualifiers="const"> <return type="Vector4i" /> <description> + Returns a new vector with each component set to one or negative one, depending on the signs of the components, or zero if the component is zero, by calling [method @GlobalScope.sign] on each component. </description> </method> </methods> <members> <member name="w" type="int" setter="" getter="" default="0"> + The vector's W component. Also accessible by using the index position [code][3][/code]. </member> <member name="x" type="int" setter="" getter="" default="0"> + The vector's X component. Also accessible by using the index position [code][0][/code]. </member> <member name="y" type="int" setter="" getter="" default="0"> + The vector's Y component. Also accessible by using the index position [code][1][/code]. </member> <member name="z" type="int" setter="" getter="" default="0"> + The vector's Z component. Also accessible by using the index position [code][2][/code]. </member> </members> <constants> <constant name="AXIS_X" value="0"> + Enumerated value for the X axis. Returned by [method max_axis_index] and [method min_axis_index]. </constant> <constant name="AXIS_Y" value="1"> + Enumerated value for the Y axis. Returned by [method max_axis_index] and [method min_axis_index]. </constant> <constant name="AXIS_Z" value="2"> + Enumerated value for the Z axis. Returned by [method max_axis_index] and [method min_axis_index]. </constant> <constant name="AXIS_W" value="3"> + Enumerated value for the W axis. Returned by [method max_axis_index] and [method min_axis_index]. </constant> <constant name="ZERO" value="Vector4i(0, 0, 0, 0)"> + Zero vector, a vector with all components set to [code]0[/code]. </constant> <constant name="ONE" value="Vector4i(1, 1, 1, 1)"> + One vector, a vector with all components set to [code]1[/code]. </constant> </constants> <operators> @@ -102,6 +126,7 @@ <return type="bool" /> <param index="0" name="right" type="Vector4i" /> <description> + Returns [code]true[/code] if the vectors are not equal. </description> </operator> <operator name="operator %"> @@ -120,94 +145,130 @@ <return type="Vector4i" /> <param index="0" name="right" type="Vector4i" /> <description> + Multiplies each component of the [Vector4i] by the components of the given [Vector4i]. + [codeblock] + print(Vector4i(10, 20, 30, 40) * Vector4i(3, 4, 5, 6)) # Prints "(30, 80, 150, 240)" + [/codeblock] </description> </operator> <operator name="operator *"> <return type="Vector4" /> <param index="0" name="right" type="float" /> <description> + Multiplies each component of the [Vector4i] by the given [float]. + Returns a Vector4 value due to floating-point operations. + [codeblock] + print(Vector4i(10, 20, 30, 40) * 2) # Prints "(20, 40, 60, 80)" + [/codeblock] </description> </operator> <operator name="operator *"> <return type="Vector4i" /> <param index="0" name="right" type="int" /> <description> + Multiplies each component of the [Vector4i] by the given [int]. </description> </operator> <operator name="operator +"> <return type="Vector4i" /> <param index="0" name="right" type="Vector4i" /> <description> + Adds each component of the [Vector4i] by the components of the given [Vector4i]. + [codeblock] + print(Vector4i(10, 20, 30, 40) + Vector4i(3, 4, 5, 6)) # Prints "(13, 24, 35, 46)" + [/codeblock] </description> </operator> <operator name="operator -"> <return type="Vector4i" /> <param index="0" name="right" type="Vector4i" /> <description> + Subtracts each component of the [Vector4i] by the components of the given [Vector4i]. + [codeblock] + print(Vector4i(10, 20, 30, 40) - Vector4i(3, 4, 5, 6)) # Prints "(7, 16, 25, 34)" + [/codeblock] </description> </operator> <operator name="operator /"> <return type="Vector4i" /> <param index="0" name="right" type="Vector4i" /> <description> + Divides each component of the [Vector4i] by the components of the given [Vector4i]. + [codeblock] + print(Vector4i(10, 20, 30, 40) / Vector4i(2, 5, 3, 4)) # Prints "(5, 4, 10, 10)" + [/codeblock] </description> </operator> <operator name="operator /"> <return type="Vector4" /> <param index="0" name="right" type="float" /> <description> + Divides each component of the [Vector4i] by the given [float]. + Returns a Vector4 value due to floating-point operations. + [codeblock] + print(Vector4i(10, 20, 30, 40) / 2 # Prints "(5, 10, 15, 20)" + [/codeblock] </description> </operator> <operator name="operator /"> <return type="Vector4i" /> <param index="0" name="right" type="int" /> <description> + Divides each component of the [Vector4i] by the given [int]. </description> </operator> <operator name="operator <"> <return type="bool" /> <param index="0" name="right" type="Vector4i" /> <description> + Compares two [Vector4i] vectors by first checking if the X value of the left vector is less than the X value of the [param right] vector. If the X values are exactly equal, then it repeats this check with the Y values of the two vectors, Z values of the two vectors, and then with the W values. This operator is useful for sorting vectors. </description> </operator> <operator name="operator <="> <return type="bool" /> <param index="0" name="right" type="Vector4i" /> <description> + Compares two [Vector4i] vectors by first checking if the X value of the left vector is less than or equal to the X value of the [param right] vector. If the X values are exactly equal, then it repeats this check with the Y values of the two vectors, Z values of the two vectors, and then with the W values. This operator is useful for sorting vectors. </description> </operator> <operator name="operator =="> <return type="bool" /> <param index="0" name="right" type="Vector4i" /> <description> + Returns [code]true[/code] if the vectors are exactly equal. </description> </operator> <operator name="operator >"> <return type="bool" /> <param index="0" name="right" type="Vector4i" /> <description> + Compares two [Vector4i] vectors by first checking if the X value of the left vector is greater than the X value of the [param right] vector. If the X values are exactly equal, then it repeats this check with the Y values of the two vectors, Z values of the two vectors, and then with the W values. This operator is useful for sorting vectors. </description> </operator> <operator name="operator >="> <return type="bool" /> <param index="0" name="right" type="Vector4i" /> <description> + Compares two [Vector4i] vectors by first checking if the X value of the left vector is greater than or equal to the X value of the [param right] vector. If the X values are exactly equal, then it repeats this check with the Y values of the two vectors, Z values of the two vectors, and then with the W values. This operator is useful for sorting vectors. </description> </operator> <operator name="operator []"> <return type="int" /> <param index="0" name="index" type="int" /> <description> + Access vector components using their [param index]. [code]v[0][/code] is equivalent to [code]v.x[/code], [code]v[1][/code] is equivalent to [code]v.y[/code], [code]v[2][/code] is equivalent to [code]v.z[/code], and [code]v[3][/code] is equivalent to [code]v.w[/code]. </description> </operator> <operator name="operator unary+"> <return type="Vector4i" /> <description> + Returns the same value as if the [code]+[/code] was not there. Unary [code]+[/code] does nothing, but sometimes it can make your code more readable. </description> </operator> <operator name="operator unary-"> <return type="Vector4i" /> <description> + Returns the negative value of the [Vector4i]. This is the same as writing [code]Vector4i(-v.x, -v.y, -v.z, -v.w)[/code]. This operation flips the direction of the vector while keeping the same magnitude. </description> </operator> </operators> diff --git a/doc/classes/VisualShaderNodeBooleanUniform.xml b/doc/classes/VisualShaderNodeBooleanParameter.xml index 59b331aed2..47dae17dba 100644 --- a/doc/classes/VisualShaderNodeBooleanUniform.xml +++ b/doc/classes/VisualShaderNodeBooleanParameter.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeBooleanUniform" inherits="VisualShaderNodeUniform" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> +<class name="VisualShaderNodeBooleanParameter" inherits="VisualShaderNodeParameter" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> - A boolean uniform to be used within the visual shader graph. + A boolean parameter to be used within the visual shader graph. </brief_description> <description> Translated to [code]uniform bool[/code] in the shader language. diff --git a/doc/classes/VisualShaderNodeColorUniform.xml b/doc/classes/VisualShaderNodeColorParameter.xml index 5ca96dc285..0cc2285ed4 100644 --- a/doc/classes/VisualShaderNodeColorUniform.xml +++ b/doc/classes/VisualShaderNodeColorParameter.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeColorUniform" inherits="VisualShaderNodeUniform" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> +<class name="VisualShaderNodeColorParameter" inherits="VisualShaderNodeParameter" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> - A [Color] uniform to be used within the visual shader graph. + A [Color] parameter to be used within the visual shader graph. </brief_description> <description> Translated to [code]uniform vec4[/code] in the shader language. diff --git a/doc/classes/VisualShaderNodeCubemapUniform.xml b/doc/classes/VisualShaderNodeCubemapParameter.xml index 3f6addd16a..d0d3c79d03 100644 --- a/doc/classes/VisualShaderNodeCubemapUniform.xml +++ b/doc/classes/VisualShaderNodeCubemapParameter.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeCubemapUniform" inherits="VisualShaderNodeTextureUniform" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> +<class name="VisualShaderNodeCubemapParameter" inherits="VisualShaderNodeTextureParameter" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> - A [Cubemap] uniform node to be used within the visual shader graph. + A [Cubemap] parameter node to be used within the visual shader graph. </brief_description> <description> Translated to [code]uniform samplerCube[/code] in the shader language. The output value can be used as port for [VisualShaderNodeCubemap]. diff --git a/doc/classes/VisualShaderNodeFloatUniform.xml b/doc/classes/VisualShaderNodeFloatParameter.xml index 1616964edb..c0fd88294a 100644 --- a/doc/classes/VisualShaderNodeFloatUniform.xml +++ b/doc/classes/VisualShaderNodeFloatParameter.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeFloatUniform" inherits="VisualShaderNodeUniform" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> +<class name="VisualShaderNodeFloatParameter" inherits="VisualShaderNodeParameter" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> - A scalar float uniform to be used within the visual shader graph. + A scalar float parameter to be used within the visual shader graph. </brief_description> <description> Translated to [code]uniform float[/code] in the shader language. @@ -15,7 +15,7 @@ <member name="default_value_enabled" type="bool" setter="set_default_value_enabled" getter="is_default_value_enabled" default="false"> Enables usage of the [member default_value]. </member> - <member name="hint" type="int" setter="set_hint" getter="get_hint" enum="VisualShaderNodeFloatUniform.Hint" default="0"> + <member name="hint" type="int" setter="set_hint" getter="get_hint" enum="VisualShaderNodeFloatParameter.Hint" default="0"> A hint applied to the uniform, which controls the values it can take when set through the inspector. </member> <member name="max" type="float" setter="set_max" getter="get_max" default="1.0"> diff --git a/doc/classes/VisualShaderNodeIntParameter.xml b/doc/classes/VisualShaderNodeIntParameter.xml new file mode 100644 index 0000000000..70335b0c77 --- /dev/null +++ b/doc/classes/VisualShaderNodeIntParameter.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeIntParameter" inherits="VisualShaderNodeParameter" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <members> + <member name="default_value" type="int" setter="set_default_value" getter="get_default_value" default="0"> + </member> + <member name="default_value_enabled" type="bool" setter="set_default_value_enabled" getter="is_default_value_enabled" default="false"> + </member> + <member name="hint" type="int" setter="set_hint" getter="get_hint" enum="VisualShaderNodeIntParameter.Hint" default="0"> + </member> + <member name="max" type="int" setter="set_max" getter="get_max" default="100"> + </member> + <member name="min" type="int" setter="set_min" getter="get_min" default="0"> + </member> + <member name="step" type="int" setter="set_step" getter="get_step" default="1"> + </member> + </members> + <constants> + <constant name="HINT_NONE" value="0" enum="Hint"> + </constant> + <constant name="HINT_RANGE" value="1" enum="Hint"> + </constant> + <constant name="HINT_RANGE_STEP" value="2" enum="Hint"> + </constant> + <constant name="HINT_MAX" value="3" enum="Hint"> + </constant> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeIntUniform.xml b/doc/classes/VisualShaderNodeIntUniform.xml deleted file mode 100644 index c83bdb5ad6..0000000000 --- a/doc/classes/VisualShaderNodeIntUniform.xml +++ /dev/null @@ -1,45 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeIntUniform" inherits="VisualShaderNodeUniform" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> - <brief_description> - A scalar integer uniform to be used within the visual shader graph. - </brief_description> - <description> - Translated to [code]uniform int[/code] in the shader language. - </description> - <tutorials> - </tutorials> - <members> - <member name="default_value" type="int" setter="set_default_value" getter="get_default_value" default="0"> - A default value to be assigned within the shader. - </member> - <member name="default_value_enabled" type="bool" setter="set_default_value_enabled" getter="is_default_value_enabled" default="false"> - Enables usage of the [member default_value]. - </member> - <member name="hint" type="int" setter="set_hint" getter="get_hint" enum="VisualShaderNodeIntUniform.Hint" default="0"> - A hint applied to the uniform, which controls the values it can take when set through the inspector. - </member> - <member name="max" type="int" setter="set_max" getter="get_max" default="100"> - Minimum value for range hints. Used if [member hint] is set to [constant HINT_RANGE] or [constant HINT_RANGE_STEP]. - </member> - <member name="min" type="int" setter="set_min" getter="get_min" default="0"> - Maximum value for range hints. Used if [member hint] is set to [constant HINT_RANGE] or [constant HINT_RANGE_STEP]. - </member> - <member name="step" type="int" setter="set_step" getter="get_step" default="1"> - Step (increment) value for the range hint with step. Used if [member hint] is set to [constant HINT_RANGE_STEP]. - </member> - </members> - <constants> - <constant name="HINT_NONE" value="0" enum="Hint"> - No hint used. - </constant> - <constant name="HINT_RANGE" value="1" enum="Hint"> - A range hint for scalar value, which limits possible input values between [member min] and [member max]. Translated to [code]hint_range(min, max)[/code] in shader code. - </constant> - <constant name="HINT_RANGE_STEP" value="2" enum="Hint"> - A range hint for scalar value with step, which limits possible input values between [member min] and [member max], with a step (increment) of [member step]). Translated to [code]hint_range(min, max, step)[/code] in shader code. - </constant> - <constant name="HINT_MAX" value="3" enum="Hint"> - Represents the size of the [enum Hint] enum. - </constant> - </constants> -</class> diff --git a/doc/classes/VisualShaderNodeParameter.xml b/doc/classes/VisualShaderNodeParameter.xml new file mode 100644 index 0000000000..c66022f77d --- /dev/null +++ b/doc/classes/VisualShaderNodeParameter.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeParameter" inherits="VisualShaderNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + A base type for the parameters within the visual shader graph. + </brief_description> + <description> + A parameter represents a variable in the shader which is set externally, i.e. from the [ShaderMaterial]. Parameters are exposed as properties in the [ShaderMaterial] and can be assigned from the inspector or from a script. + </description> + <tutorials> + </tutorials> + <members> + <member name="parameter_name" type="String" setter="set_parameter_name" getter="get_parameter_name" default=""""> + Name of the parameter, by which it can be accessed through the [ShaderMaterial] properties. + </member> + <member name="qualifier" type="int" setter="set_qualifier" getter="get_qualifier" enum="VisualShaderNodeParameter.Qualifier" default="0"> + </member> + </members> + <constants> + <constant name="QUAL_NONE" value="0" enum="Qualifier"> + </constant> + <constant name="QUAL_GLOBAL" value="1" enum="Qualifier"> + </constant> + <constant name="QUAL_INSTANCE" value="2" enum="Qualifier"> + </constant> + <constant name="QUAL_MAX" value="3" enum="Qualifier"> + Represents the size of the [enum Qualifier] enum. + </constant> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeParameterRef.xml b/doc/classes/VisualShaderNodeParameterRef.xml new file mode 100644 index 0000000000..b2801183ed --- /dev/null +++ b/doc/classes/VisualShaderNodeParameterRef.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeParameterRef" inherits="VisualShaderNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + A reference to an existing [VisualShaderNodeParameter]. + </brief_description> + <description> + Creating a reference to a [VisualShaderNodeParameter] allows you to reuse this parameter in different shaders or shader stages easily. + </description> + <tutorials> + </tutorials> + <members> + <member name="parameter_name" type="String" setter="set_parameter_name" getter="get_parameter_name" default=""[None]""> + The name of the parameter which this reference points to. + </member> + </members> +</class> diff --git a/doc/classes/VisualShaderNodeTexture2DArrayParameter.xml b/doc/classes/VisualShaderNodeTexture2DArrayParameter.xml new file mode 100644 index 0000000000..2afaa8e219 --- /dev/null +++ b/doc/classes/VisualShaderNodeTexture2DArrayParameter.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeTexture2DArrayParameter" inherits="VisualShaderNodeTextureParameter" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> +</class> diff --git a/doc/classes/VisualShaderNodeTexture2DArrayUniform.xml b/doc/classes/VisualShaderNodeTexture2DArrayUniform.xml deleted file mode 100644 index f8ba796c2e..0000000000 --- a/doc/classes/VisualShaderNodeTexture2DArrayUniform.xml +++ /dev/null @@ -1,9 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeTexture2DArrayUniform" inherits="VisualShaderNodeTextureUniform" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> - <brief_description> - </brief_description> - <description> - </description> - <tutorials> - </tutorials> -</class> diff --git a/doc/classes/VisualShaderNodeTexture2DParameter.xml b/doc/classes/VisualShaderNodeTexture2DParameter.xml new file mode 100644 index 0000000000..5049a63a0e --- /dev/null +++ b/doc/classes/VisualShaderNodeTexture2DParameter.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeTexture2DParameter" inherits="VisualShaderNodeTextureParameter" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + Provides a 2D texture parameter within the visual shader graph. + </brief_description> + <description> + Translated to [code]uniform sampler2D[/code] in the shader language. + </description> + <tutorials> + </tutorials> +</class> diff --git a/doc/classes/VisualShaderNodeTexture3DParameter.xml b/doc/classes/VisualShaderNodeTexture3DParameter.xml new file mode 100644 index 0000000000..8ad4de9a22 --- /dev/null +++ b/doc/classes/VisualShaderNodeTexture3DParameter.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeTexture3DParameter" inherits="VisualShaderNodeTextureParameter" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + Provides a 3D texture parameter within the visual shader graph. + </brief_description> + <description> + Translated to [code]uniform sampler3D[/code] in the shader language. + </description> + <tutorials> + </tutorials> +</class> diff --git a/doc/classes/VisualShaderNodeTexture3DUniform.xml b/doc/classes/VisualShaderNodeTexture3DUniform.xml deleted file mode 100644 index 365c7db02e..0000000000 --- a/doc/classes/VisualShaderNodeTexture3DUniform.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeTexture3DUniform" inherits="VisualShaderNodeTextureUniform" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> - <brief_description> - Provides a 3D texture uniform within the visual shader graph. - </brief_description> - <description> - Translated to [code]uniform sampler3D[/code] in the shader language. - </description> - <tutorials> - </tutorials> -</class> diff --git a/doc/classes/VisualShaderNodeTextureUniform.xml b/doc/classes/VisualShaderNodeTextureParameter.xml index 9014f79f54..ad21c4e990 100644 --- a/doc/classes/VisualShaderNodeTextureUniform.xml +++ b/doc/classes/VisualShaderNodeTextureParameter.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeTextureUniform" inherits="VisualShaderNodeUniform" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> +<class name="VisualShaderNodeTextureParameter" inherits="VisualShaderNodeParameter" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> Performs a uniform texture lookup within the visual shader graph. </brief_description> @@ -9,16 +9,16 @@ <tutorials> </tutorials> <members> - <member name="color_default" type="int" setter="set_color_default" getter="get_color_default" enum="VisualShaderNodeTextureUniform.ColorDefault" default="0"> + <member name="color_default" type="int" setter="set_color_default" getter="get_color_default" enum="VisualShaderNodeTextureParameter.ColorDefault" default="0"> Sets the default color if no texture is assigned to the uniform. </member> - <member name="texture_filter" type="int" setter="set_texture_filter" getter="get_texture_filter" enum="VisualShaderNodeTextureUniform.TextureFilter" default="0"> + <member name="texture_filter" type="int" setter="set_texture_filter" getter="get_texture_filter" enum="VisualShaderNodeTextureParameter.TextureFilter" default="0"> Sets the texture filtering mode. See [enum TextureFilter] for options. </member> - <member name="texture_repeat" type="int" setter="set_texture_repeat" getter="get_texture_repeat" enum="VisualShaderNodeTextureUniform.TextureRepeat" default="0"> + <member name="texture_repeat" type="int" setter="set_texture_repeat" getter="get_texture_repeat" enum="VisualShaderNodeTextureParameter.TextureRepeat" default="0"> Sets the texture repeating mode. See [enum TextureRepeat] for options. </member> - <member name="texture_type" type="int" setter="set_texture_type" getter="get_texture_type" enum="VisualShaderNodeTextureUniform.TextureType" default="0"> + <member name="texture_type" type="int" setter="set_texture_type" getter="get_texture_type" enum="VisualShaderNodeTextureParameter.TextureType" default="0"> Defines the type of data provided by the source texture. See [enum TextureType] for options. </member> </members> diff --git a/doc/classes/VisualShaderNodeTextureUniformTriplanar.xml b/doc/classes/VisualShaderNodeTextureParameterTriplanar.xml index 72082ef04d..2b019e08d5 100644 --- a/doc/classes/VisualShaderNodeTextureUniformTriplanar.xml +++ b/doc/classes/VisualShaderNodeTextureParameterTriplanar.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeTextureUniformTriplanar" inherits="VisualShaderNodeTextureUniform" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> +<class name="VisualShaderNodeTextureParameterTriplanar" inherits="VisualShaderNodeTextureParameter" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> Performs a uniform texture lookup with triplanar within the visual shader graph. </brief_description> diff --git a/doc/classes/VisualShaderNodeTransformUniform.xml b/doc/classes/VisualShaderNodeTransformParameter.xml index 60678c09e5..92aadc4d7c 100644 --- a/doc/classes/VisualShaderNodeTransformUniform.xml +++ b/doc/classes/VisualShaderNodeTransformParameter.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeTransformUniform" inherits="VisualShaderNodeUniform" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> +<class name="VisualShaderNodeTransformParameter" inherits="VisualShaderNodeParameter" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> - A [Transform3D] uniform for use within the visual shader graph. + A [Transform3D] parameter for use within the visual shader graph. </brief_description> <description> Translated to [code]uniform mat4[/code] in the shader language. diff --git a/doc/classes/VisualShaderNodeUniform.xml b/doc/classes/VisualShaderNodeUniform.xml deleted file mode 100644 index 58d194e9d4..0000000000 --- a/doc/classes/VisualShaderNodeUniform.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeUniform" inherits="VisualShaderNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> - <brief_description> - A base type for the uniforms within the visual shader graph. - </brief_description> - <description> - A uniform represents a variable in the shader which is set externally, i.e. from the [ShaderMaterial]. Uniforms are exposed as properties in the [ShaderMaterial] and can be assigned from the inspector or from a script. - </description> - <tutorials> - </tutorials> - <members> - <member name="qualifier" type="int" setter="set_qualifier" getter="get_qualifier" enum="VisualShaderNodeUniform.Qualifier" default="0"> - </member> - <member name="uniform_name" type="String" setter="set_uniform_name" getter="get_uniform_name" default=""""> - Name of the uniform, by which it can be accessed through the [ShaderMaterial] properties. - </member> - </members> - <constants> - <constant name="QUAL_NONE" value="0" enum="Qualifier"> - </constant> - <constant name="QUAL_GLOBAL" value="1" enum="Qualifier"> - </constant> - <constant name="QUAL_INSTANCE" value="2" enum="Qualifier"> - </constant> - <constant name="QUAL_MAX" value="3" enum="Qualifier"> - Represents the size of the [enum Qualifier] enum. - </constant> - </constants> -</class> diff --git a/doc/classes/VisualShaderNodeUniformRef.xml b/doc/classes/VisualShaderNodeUniformRef.xml deleted file mode 100644 index 4b12c6e649..0000000000 --- a/doc/classes/VisualShaderNodeUniformRef.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeUniformRef" inherits="VisualShaderNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> - <brief_description> - A reference to an existing [VisualShaderNodeUniform]. - </brief_description> - <description> - Creating a reference to a [VisualShaderNodeUniform] allows you to reuse this uniform in different shaders or shader stages easily. - </description> - <tutorials> - </tutorials> - <members> - <member name="uniform_name" type="String" setter="set_uniform_name" getter="get_uniform_name" default=""[None]""> - The name of the uniform which this reference points to. - </member> - </members> -</class> diff --git a/doc/classes/VisualShaderNodeVec2Uniform.xml b/doc/classes/VisualShaderNodeVec2Parameter.xml index 4ad6279475..19cf1baa86 100644 --- a/doc/classes/VisualShaderNodeVec2Uniform.xml +++ b/doc/classes/VisualShaderNodeVec2Parameter.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeVec2Uniform" inherits="VisualShaderNodeUniform" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> +<class name="VisualShaderNodeVec2Parameter" inherits="VisualShaderNodeParameter" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> - A [Vector2] uniform to be used within the visual shader graph. + A [Vector2] parameter to be used within the visual shader graph. </brief_description> <description> Translated to [code]uniform vec2[/code] in the shader language. diff --git a/doc/classes/VisualShaderNodeVec3Uniform.xml b/doc/classes/VisualShaderNodeVec3Parameter.xml index f712c89463..17d4b31d1a 100644 --- a/doc/classes/VisualShaderNodeVec3Uniform.xml +++ b/doc/classes/VisualShaderNodeVec3Parameter.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeVec3Uniform" inherits="VisualShaderNodeUniform" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> +<class name="VisualShaderNodeVec3Parameter" inherits="VisualShaderNodeParameter" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> - A [Vector3] uniform to be used within the visual shader graph. + A [Vector3] parameter to be used within the visual shader graph. </brief_description> <description> Translated to [code]uniform vec3[/code] in the shader language. diff --git a/doc/classes/VisualShaderNodeVec4Constant.xml b/doc/classes/VisualShaderNodeVec4Constant.xml index ed3d8a673d..ddd2f38fb9 100644 --- a/doc/classes/VisualShaderNodeVec4Constant.xml +++ b/doc/classes/VisualShaderNodeVec4Constant.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualShaderNodeVec4Constant" inherits="VisualShaderNodeConstant" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> - A 4D vector (represented as a [Quaternion]) constant to be used within the visual shader graph. + A 4D vector constant to be used within the visual shader graph. </brief_description> <description> - A constant 4D vector (represented as a [Quaternion]), which can be used as an input node. + A constant 4D vector, which can be used as an input node. </description> <tutorials> </tutorials> diff --git a/doc/classes/VisualShaderNodeVec4Uniform.xml b/doc/classes/VisualShaderNodeVec4Parameter.xml index 5bd13a440b..0e9e7c6b6f 100644 --- a/doc/classes/VisualShaderNodeVec4Uniform.xml +++ b/doc/classes/VisualShaderNodeVec4Parameter.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeVec4Uniform" inherits="VisualShaderNodeUniform" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> +<class name="VisualShaderNodeVec4Parameter" inherits="VisualShaderNodeParameter" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> - A 4D vector (represented as a [Quaternion]) uniform to be used within the visual shader graph. + A 4D vector parameter to be used within the visual shader graph. </brief_description> <description> Translated to [code]uniform vec4[/code] in the shader language. @@ -9,7 +9,7 @@ <tutorials> </tutorials> <members> - <member name="default_value" type="Quaternion" setter="set_default_value" getter="get_default_value" default="Quaternion(0, 0, 0, 1)"> + <member name="default_value" type="Vector4" setter="set_default_value" getter="get_default_value" default="Vector4(0, 0, 0, 0)"> A default value to be assigned within the shader. </member> <member name="default_value_enabled" type="bool" setter="set_default_value_enabled" getter="is_default_value_enabled" default="false"> diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index a960fced1f..c1d203be28 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -183,7 +183,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ glBindBufferBase(GL_UNIFORM_BUFFER, BASE_UNIFORM_LOCATION, state.canvas_state_buffer); glBufferData(GL_UNIFORM_BUFFER, sizeof(StateBuffer), &state_buffer, GL_STREAM_DRAW); - GLuint global_buffer = material_storage->global_shader_uniforms_get_uniform_buffer(); + GLuint global_buffer = material_storage->global_shader_parameters_get_uniform_buffer(); glBindBufferBase(GL_UNIFORM_BUFFER, GLOBAL_UNIFORM_LOCATION, global_buffer); glBindBuffer(GL_UNIFORM_BUFFER, 0); diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 333688db5f..dae26b1e5f 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -1783,7 +1783,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ // Fill Light lists here ////////// - GLuint global_buffer = GLES3::MaterialStorage::get_singleton()->global_shader_uniforms_get_uniform_buffer(); + GLuint global_buffer = GLES3::MaterialStorage::get_singleton()->global_shader_parameters_get_uniform_buffer(); glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_GLOBALS_UNIFORM_LOCATION, global_buffer); Color clear_color; @@ -2378,7 +2378,7 @@ void RasterizerSceneGLES3::sub_surface_scattering_set_quality(RS::SubSurfaceScat void RasterizerSceneGLES3::sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) { } -TypedArray<Image> RasterizerSceneGLES3::bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) { +TypedArray<Image> RasterizerSceneGLES3::bake_render_uv2(RID p_base, const TypedArray<RID> &p_material_overrides, const Size2i &p_image_size) { return TypedArray<Image>(); } diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index 820f3ff9c2..04658b10ad 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -738,7 +738,7 @@ public: void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) override; void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) override; - TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) override; + TypedArray<Image> bake_render_uv2(RID p_base, const TypedArray<RID> &p_material_overrides, const Size2i &p_image_size) override; bool free(RID p_rid) override; void update() override; diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp index a64c7f7200..3dbc75392c 100644 --- a/drivers/gles3/storage/material_storage.cpp +++ b/drivers/gles3/storage/material_storage.cpp @@ -978,7 +978,7 @@ void MaterialData::update_uniform_buffer(const HashMap<StringName, ShaderLanguag if (gv) { index = gv->buffer_index; } else { - WARN_PRINT("Shader uses global uniform '" + E.key + "', but it was removed at some point. Material will not display correctly."); + WARN_PRINT("Shader uses global parameter '" + E.key + "', but it was removed at some point. Material will not display correctly."); } uint32_t offset = p_uniform_offsets[E.value.order]; @@ -1095,7 +1095,7 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet GlobalShaderUniforms::Variable *v = material_storage->global_shader_uniforms.variables.getptr(uniform_name); if (v) { if (v->buffer_index >= 0) { - WARN_PRINT("Shader uses global uniform texture '" + String(uniform_name) + "', but it changed type and is no longer a texture!."); + WARN_PRINT("Shader uses global parameter texture '" + String(uniform_name) + "', but it changed type and is no longer a texture!."); } else { HashMap<StringName, uint64_t>::Iterator E = used_global_textures.find(uniform_name); @@ -1110,7 +1110,7 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet } } else { - WARN_PRINT("Shader uses global uniform texture '" + String(uniform_name) + "', but it was removed at some point. Material will not display correctly."); + WARN_PRINT("Shader uses global parameter texture '" + String(uniform_name) + "', but it was removed at some point. Material will not display correctly."); } } else { HashMap<StringName, Variant>::ConstIterator V = p_parameters.find(uniform_name); @@ -1762,7 +1762,7 @@ int32_t MaterialStorage::_global_shader_uniform_allocate(uint32_t p_elements) { return -1; } -void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS::GlobalShaderUniformType p_type, const Variant &p_value) { +void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS::GlobalShaderParameterType p_type, const Variant &p_value) { switch (p_type) { case RS::GLOBAL_VAR_TYPE_BOOL: { GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; @@ -2055,7 +2055,7 @@ void MaterialStorage::_global_shader_uniform_mark_buffer_dirty(int32_t p_index, } } -void MaterialStorage::global_shader_uniform_add(const StringName &p_name, RS::GlobalShaderUniformType p_type, const Variant &p_value) { +void MaterialStorage::global_shader_parameter_add(const StringName &p_name, RS::GlobalShaderParameterType p_type, const Variant &p_value) { ERR_FAIL_COND(global_shader_uniforms.variables.has(p_name)); GlobalShaderUniforms::Variable gv; gv.type = p_type; @@ -2093,7 +2093,7 @@ void MaterialStorage::global_shader_uniform_add(const StringName &p_name, RS::Gl global_shader_uniforms.variables[p_name] = gv; } -void MaterialStorage::global_shader_uniform_remove(const StringName &p_name) { +void MaterialStorage::global_shader_parameter_remove(const StringName &p_name) { if (!global_shader_uniforms.variables.has(p_name)) { return; } @@ -2109,7 +2109,7 @@ void MaterialStorage::global_shader_uniform_remove(const StringName &p_name) { global_shader_uniforms.variables.erase(p_name); } -Vector<StringName> MaterialStorage::global_shader_uniform_get_list() const { +Vector<StringName> MaterialStorage::global_shader_parameter_get_list() const { if (!Engine::get_singleton()->is_editor_hint()) { ERR_FAIL_V_MSG(Vector<StringName>(), "This function should never be used outside the editor, it can severely damage performance."); } @@ -2122,7 +2122,7 @@ Vector<StringName> MaterialStorage::global_shader_uniform_get_list() const { return names; } -void MaterialStorage::global_shader_uniform_set(const StringName &p_name, const Variant &p_value) { +void MaterialStorage::global_shader_parameter_set(const StringName &p_name, const Variant &p_value) { ERR_FAIL_COND(!global_shader_uniforms.variables.has(p_name)); GlobalShaderUniforms::Variable &gv = global_shader_uniforms.variables[p_name]; gv.value = p_value; @@ -2143,7 +2143,7 @@ void MaterialStorage::global_shader_uniform_set(const StringName &p_name, const } } -void MaterialStorage::global_shader_uniform_set_override(const StringName &p_name, const Variant &p_value) { +void MaterialStorage::global_shader_parameter_set_override(const StringName &p_name, const Variant &p_value) { if (!global_shader_uniforms.variables.has(p_name)) { return; //variable may not exist } @@ -2174,7 +2174,7 @@ void MaterialStorage::global_shader_uniform_set_override(const StringName &p_nam } } -Variant MaterialStorage::global_shader_uniform_get(const StringName &p_name) const { +Variant MaterialStorage::global_shader_parameter_get(const StringName &p_name) const { if (!Engine::get_singleton()->is_editor_hint()) { ERR_FAIL_V_MSG(Variant(), "This function should never be used outside the editor, it can severely damage performance."); } @@ -2186,7 +2186,7 @@ Variant MaterialStorage::global_shader_uniform_get(const StringName &p_name) con return global_shader_uniforms.variables[p_name].value; } -RS::GlobalShaderUniformType MaterialStorage::global_shader_uniform_get_type_internal(const StringName &p_name) const { +RS::GlobalShaderParameterType MaterialStorage::global_shader_parameter_get_type_internal(const StringName &p_name) const { if (!global_shader_uniforms.variables.has(p_name)) { return RS::GLOBAL_VAR_TYPE_MAX; } @@ -2194,15 +2194,15 @@ RS::GlobalShaderUniformType MaterialStorage::global_shader_uniform_get_type_inte return global_shader_uniforms.variables[p_name].type; } -RS::GlobalShaderUniformType MaterialStorage::global_shader_uniform_get_type(const StringName &p_name) const { +RS::GlobalShaderParameterType MaterialStorage::global_shader_parameter_get_type(const StringName &p_name) const { if (!Engine::get_singleton()->is_editor_hint()) { ERR_FAIL_V_MSG(RS::GLOBAL_VAR_TYPE_MAX, "This function should never be used outside the editor, it can severely damage performance."); } - return global_shader_uniform_get_type_internal(p_name); + return global_shader_parameter_get_type_internal(p_name); } -void MaterialStorage::global_shader_uniforms_load_settings(bool p_load_textures) { +void MaterialStorage::global_shader_parameters_load_settings(bool p_load_textures) { List<PropertyInfo> settings; ProjectSettings::get_singleton()->get_property_list(&settings); @@ -2247,11 +2247,11 @@ void MaterialStorage::global_shader_uniforms_load_settings(bool p_load_textures) "samplerCube", }; - RS::GlobalShaderUniformType gvtype = RS::GLOBAL_VAR_TYPE_MAX; + RS::GlobalShaderParameterType gvtype = RS::GLOBAL_VAR_TYPE_MAX; for (int i = 0; i < RS::GLOBAL_VAR_TYPE_MAX; i++) { if (global_var_type_names[i] == type) { - gvtype = RS::GlobalShaderUniformType(i); + gvtype = RS::GlobalShaderParameterType(i); break; } } @@ -2275,23 +2275,23 @@ void MaterialStorage::global_shader_uniforms_load_settings(bool p_load_textures) if (global_shader_uniforms.variables.has(name)) { //has it, update it - global_shader_uniform_set(name, value); + global_shader_parameter_set(name, value); } else { - global_shader_uniform_add(name, gvtype, value); + global_shader_parameter_add(name, gvtype, value); } } } } -void MaterialStorage::global_shader_uniforms_clear() { +void MaterialStorage::global_shader_parameters_clear() { global_shader_uniforms.variables.clear(); } -GLuint MaterialStorage::global_shader_uniforms_get_uniform_buffer() const { +GLuint MaterialStorage::global_shader_parameters_get_uniform_buffer() const { return global_shader_uniforms.buffer; } -int32_t MaterialStorage::global_shader_uniforms_instance_allocate(RID p_instance) { +int32_t MaterialStorage::global_shader_parameters_instance_allocate(RID p_instance) { ERR_FAIL_COND_V(global_shader_uniforms.instance_buffer_pos.has(p_instance), -1); int32_t pos = _global_shader_uniform_allocate(ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES); global_shader_uniforms.instance_buffer_pos[p_instance] = pos; //save anyway @@ -2300,7 +2300,7 @@ int32_t MaterialStorage::global_shader_uniforms_instance_allocate(RID p_instance return pos; } -void MaterialStorage::global_shader_uniforms_instance_free(RID p_instance) { +void MaterialStorage::global_shader_parameters_instance_free(RID p_instance) { ERR_FAIL_COND(!global_shader_uniforms.instance_buffer_pos.has(p_instance)); int32_t pos = global_shader_uniforms.instance_buffer_pos[p_instance]; if (pos >= 0) { @@ -2309,7 +2309,7 @@ void MaterialStorage::global_shader_uniforms_instance_free(RID p_instance) { global_shader_uniforms.instance_buffer_pos.erase(p_instance); } -void MaterialStorage::global_shader_uniforms_instance_update(RID p_instance, int p_index, const Variant &p_value) { +void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value) { if (!global_shader_uniforms.instance_buffer_pos.has(p_instance)) { return; //just not allocated, ignore } @@ -2498,7 +2498,7 @@ void MaterialStorage::shader_set_code(RID p_shader, const String &p_code) { if (shader->data) { for (const KeyValue<StringName, HashMap<int, RID>> &E : shader->default_texture_parameter) { for (const KeyValue<int, RID> &E2 : E.value) { - shader->data->set_default_texture_param(E.key, E2.value, E2.key); + shader->data->set_default_texture_parameter(E.key, E2.value, E2.key); } } } @@ -2528,7 +2528,7 @@ String MaterialStorage::shader_get_code(RID p_shader) const { return shader->code; } -void MaterialStorage::shader_get_shader_uniform_list(RID p_shader, List<PropertyInfo> *p_param_list) const { +void MaterialStorage::get_shader_parameter_list(RID p_shader, List<PropertyInfo> *p_param_list) const { GLES3::Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND(!shader); if (shader->data) { @@ -2536,7 +2536,7 @@ void MaterialStorage::shader_get_shader_uniform_list(RID p_shader, List<Property } } -void MaterialStorage::shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) { +void MaterialStorage::shader_set_default_texture_parameter(RID p_shader, const StringName &p_name, RID p_texture, int p_index) { GLES3::Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND(!shader); @@ -2555,7 +2555,7 @@ void MaterialStorage::shader_set_default_texture_param(RID p_shader, const Strin } } if (shader->data) { - shader->data->set_default_texture_param(p_name, p_texture, p_index); + shader->data->set_default_texture_parameter(p_name, p_texture, p_index); } for (Material *E : shader->owners) { Material *material = E; @@ -2563,7 +2563,7 @@ void MaterialStorage::shader_set_default_texture_param(RID p_shader, const Strin } } -RID MaterialStorage::shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const { +RID MaterialStorage::shader_get_default_texture_parameter(RID p_shader, const StringName &p_name, int p_index) const { const GLES3::Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND_V(!shader, RID()); if (shader->default_texture_parameter.has(p_name) && shader->default_texture_parameter[p_name].has(p_index)) { @@ -2573,7 +2573,7 @@ RID MaterialStorage::shader_get_default_texture_param(RID p_shader, const String return RID(); } -Variant MaterialStorage::shader_get_param_default(RID p_shader, const StringName &p_param) const { +Variant MaterialStorage::shader_get_parameter_default(RID p_shader, const StringName &p_param) const { Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND_V(!shader, Variant()); if (shader->data) { @@ -2693,7 +2693,7 @@ void MaterialStorage::material_set_param(RID p_material, const StringName &p_par } if (material->shader && material->shader->data) { //shader is valid - bool is_texture = material->shader->data->is_param_texture(p_param); + bool is_texture = material->shader->data->is_parameter_texture(p_param); _material_queue_update(material, !is_texture, is_texture); } else { _material_queue_update(material, true, true); @@ -2764,14 +2764,14 @@ bool MaterialStorage::material_casts_shadows(RID p_material) { return true; //by default everything casts shadows } -void MaterialStorage::material_get_instance_shader_uniforms(RID p_material, List<InstanceShaderParam> *r_parameters) { +void MaterialStorage::material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) { GLES3::Material *material = material_owner.get_or_null(p_material); ERR_FAIL_COND(!material); if (material->shader && material->shader->data) { material->shader->data->get_instance_param_list(r_parameters); if (material->next_pass.is_valid()) { - material_get_instance_shader_uniforms(material->next_pass, r_parameters); + material_get_instance_shader_parameters(material->next_pass, r_parameters); } } } @@ -2867,7 +2867,7 @@ void CanvasShaderData::set_code(const String &p_code) { valid = true; } -void CanvasShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) { +void CanvasShaderData::set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) { if (!p_texture.is_valid()) { if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { default_texture_params[p_name].erase(p_index); @@ -2938,7 +2938,7 @@ void CanvasShaderData::get_instance_param_list(List<RendererMaterialStorage::Ins } } -bool CanvasShaderData::is_param_texture(const StringName &p_param) const { +bool CanvasShaderData::is_parameter_texture(const StringName &p_param) const { if (!uniforms.has(p_param)) { return false; } @@ -3111,7 +3111,7 @@ void SkyShaderData::set_code(const String &p_code) { valid = true; } -void SkyShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) { +void SkyShaderData::set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) { if (!p_texture.is_valid()) { if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { default_texture_params[p_name].erase(p_index); @@ -3180,7 +3180,7 @@ void SkyShaderData::get_instance_param_list(List<RendererMaterialStorage::Instan } } -bool SkyShaderData::is_param_texture(const StringName &p_param) const { +bool SkyShaderData::is_parameter_texture(const StringName &p_param) const { if (!uniforms.has(p_param)) { return false; } @@ -3435,7 +3435,7 @@ void SceneShaderData::set_code(const String &p_code) { valid = true; } -void SceneShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) { +void SceneShaderData::set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) { if (!p_texture.is_valid()) { if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { default_texture_params[p_name].erase(p_index); @@ -3507,7 +3507,7 @@ void SceneShaderData::get_instance_param_list(List<RendererMaterialStorage::Inst } } -bool SceneShaderData::is_param_texture(const StringName &p_param) const { +bool SceneShaderData::is_parameter_texture(const StringName &p_param) const { if (!uniforms.has(p_param)) { return false; } diff --git a/drivers/gles3/storage/material_storage.h b/drivers/gles3/storage/material_storage.h index a2a7554821..65c46631ed 100644 --- a/drivers/gles3/storage/material_storage.h +++ b/drivers/gles3/storage/material_storage.h @@ -53,11 +53,11 @@ namespace GLES3 { struct ShaderData { virtual void set_code(const String &p_Code) = 0; - virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) = 0; + virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) = 0; virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const = 0; virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const = 0; - virtual bool is_param_texture(const StringName &p_param) const = 0; + virtual bool is_parameter_texture(const StringName &p_param) const = 0; virtual bool is_animated() const = 0; virtual bool casts_shadows() const = 0; virtual Variant get_default_parameter(const StringName &p_parameter) const = 0; @@ -165,11 +165,11 @@ struct CanvasShaderData : public ShaderData { bool uses_time = false; virtual void set_code(const String &p_Code); - virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); + virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index); virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; - virtual bool is_param_texture(const StringName &p_param) const; + virtual bool is_parameter_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; virtual Variant get_default_parameter(const StringName &p_parameter) const; @@ -216,10 +216,10 @@ struct SkyShaderData : public ShaderData { bool uses_light; virtual void set_code(const String &p_Code); - virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); + virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index); virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; - virtual bool is_param_texture(const StringName &p_param) const; + virtual bool is_parameter_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; virtual Variant get_default_parameter(const StringName &p_parameter) const; @@ -337,11 +337,11 @@ struct SceneShaderData : public ShaderData { uint32_t index = 0; virtual void set_code(const String &p_Code); - virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); + virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index); virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; - virtual bool is_param_texture(const StringName &p_param) const; + virtual bool is_parameter_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; virtual Variant get_default_parameter(const StringName &p_parameter) const; @@ -376,7 +376,7 @@ struct GlobalShaderUniforms { struct Variable { HashSet<RID> texture_materials; // materials using this - RS::GlobalShaderUniformType type; + RS::GlobalShaderParameterType type; Variant value; Variant override; int32_t buffer_index; //for vectors @@ -437,7 +437,7 @@ private: GlobalShaderUniforms global_shader_uniforms; int32_t _global_shader_uniform_allocate(uint32_t p_elements); - void _global_shader_uniform_store_in_buffer(int32_t p_index, RS::GlobalShaderUniformType p_type, const Variant &p_value); + void _global_shader_uniform_store_in_buffer(int32_t p_index, RS::GlobalShaderParameterType p_type, const Variant &p_value); void _global_shader_uniform_mark_buffer_dirty(int32_t p_index, int32_t p_elements); /* SHADER API */ @@ -515,24 +515,24 @@ public: void _update_global_shader_uniforms(); - virtual void global_shader_uniform_add(const StringName &p_name, RS::GlobalShaderUniformType p_type, const Variant &p_value) override; - virtual void global_shader_uniform_remove(const StringName &p_name) override; - virtual Vector<StringName> global_shader_uniform_get_list() const override; + virtual void global_shader_parameter_add(const StringName &p_name, RS::GlobalShaderParameterType p_type, const Variant &p_value) override; + virtual void global_shader_parameter_remove(const StringName &p_name) override; + virtual Vector<StringName> global_shader_parameter_get_list() const override; - virtual void global_shader_uniform_set(const StringName &p_name, const Variant &p_value) override; - virtual void global_shader_uniform_set_override(const StringName &p_name, const Variant &p_value) override; - virtual Variant global_shader_uniform_get(const StringName &p_name) const override; - virtual RS::GlobalShaderUniformType global_shader_uniform_get_type(const StringName &p_name) const override; - RS::GlobalShaderUniformType global_shader_uniform_get_type_internal(const StringName &p_name) const; + virtual void global_shader_parameter_set(const StringName &p_name, const Variant &p_value) override; + virtual void global_shader_parameter_set_override(const StringName &p_name, const Variant &p_value) override; + virtual Variant global_shader_parameter_get(const StringName &p_name) const override; + virtual RS::GlobalShaderParameterType global_shader_parameter_get_type(const StringName &p_name) const override; + RS::GlobalShaderParameterType global_shader_parameter_get_type_internal(const StringName &p_name) const; - virtual void global_shader_uniforms_load_settings(bool p_load_textures = true) override; - virtual void global_shader_uniforms_clear() override; + virtual void global_shader_parameters_load_settings(bool p_load_textures = true) override; + virtual void global_shader_parameters_clear() override; - virtual int32_t global_shader_uniforms_instance_allocate(RID p_instance) override; - virtual void global_shader_uniforms_instance_free(RID p_instance) override; - virtual void global_shader_uniforms_instance_update(RID p_instance, int p_index, const Variant &p_value) override; + virtual int32_t global_shader_parameters_instance_allocate(RID p_instance) override; + virtual void global_shader_parameters_instance_free(RID p_instance) override; + virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value) override; - GLuint global_shader_uniforms_get_uniform_buffer() const; + GLuint global_shader_parameters_get_uniform_buffer() const; /* SHADER API */ @@ -548,11 +548,11 @@ public: virtual void shader_set_code(RID p_shader, const String &p_code) override; virtual void shader_set_path_hint(RID p_shader, const String &p_path) override; virtual String shader_get_code(RID p_shader) const override; - virtual void shader_get_shader_uniform_list(RID p_shader, List<PropertyInfo> *p_param_list) const override; + virtual void get_shader_parameter_list(RID p_shader, List<PropertyInfo> *p_param_list) const override; - virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) override; - virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const override; - virtual Variant shader_get_param_default(RID p_shader, const StringName &p_param) const override; + virtual void shader_set_default_texture_parameter(RID p_shader, const StringName &p_name, RID p_texture, int p_index) override; + virtual RID shader_get_default_texture_parameter(RID p_shader, const StringName &p_name, int p_index) const override; + virtual Variant shader_get_parameter_default(RID p_shader, const StringName &p_name) const override; virtual RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const override; @@ -579,7 +579,7 @@ public: virtual bool material_is_animated(RID p_material) override; virtual bool material_casts_shadows(RID p_material) override; - virtual void material_get_instance_shader_uniforms(RID p_material, List<InstanceShaderParam> *r_parameters) override; + virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override; virtual void material_update_dependency(RID p_material, DependencyTracker *p_instance) override; diff --git a/editor/editor_atlas_packer.cpp b/editor/editor_atlas_packer.cpp index 9c6bcd769a..7f4bd8cc89 100644 --- a/editor/editor_atlas_packer.cpp +++ b/editor/editor_atlas_packer.cpp @@ -81,7 +81,7 @@ void EditorAtlasPacker::chart_pack(Vector<Chart> &charts, int &r_width, int &r_h int l = k == 0 ? 2 : k - 1; Vector<Point2i> points = Geometry2D::bresenham_line(v[k], v[l]); for (Point2i point : points) { - src_bitmap->set_bit(point, true); + src_bitmap->set_bitv(point, true); } } } @@ -128,7 +128,7 @@ void EditorAtlasPacker::chart_pack(Vector<Chart> &charts, int &r_width, int &r_h continue; } - if (src_bitmap->get_bit(Vector2(px, py))) { + if (src_bitmap->get_bit(px, py)) { found_pixel = true; } } diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp index fca9907c20..c953efc528 100644 --- a/editor/editor_file_dialog.cpp +++ b/editor/editor_file_dialog.cpp @@ -69,13 +69,49 @@ VBoxContainer *EditorFileDialog::get_vbox() { return vbox; } +void EditorFileDialog::_update_theme_item_cache() { + ConfirmationDialog::_update_theme_item_cache(); + + theme_cache.parent_folder = get_theme_icon(SNAME("ArrowUp"), SNAME("EditorIcons")); + theme_cache.forward_folder = get_theme_icon(SNAME("Forward"), SNAME("EditorIcons")); + theme_cache.back_folder = get_theme_icon(SNAME("Back"), SNAME("EditorIcons")); + theme_cache.reload = get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")); + theme_cache.toggle_hidden = get_theme_icon(SNAME("GuiVisibilityVisible"), SNAME("EditorIcons")); + theme_cache.favorite = get_theme_icon(SNAME("Favorites"), SNAME("EditorIcons")); + theme_cache.mode_thumbnails = get_theme_icon(SNAME("FileThumbnail"), SNAME("EditorIcons")); + theme_cache.mode_list = get_theme_icon(SNAME("FileList"), SNAME("EditorIcons")); + theme_cache.favorites_up = get_theme_icon(SNAME("MoveUp"), SNAME("EditorIcons")); + theme_cache.favorites_down = get_theme_icon(SNAME("MoveDown"), SNAME("EditorIcons")); + + theme_cache.folder = get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")); + theme_cache.folder_icon_modulate = get_theme_color(SNAME("folder_icon_modulate"), SNAME("FileDialog")); + + theme_cache.action_copy = get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")); + theme_cache.action_delete = get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")); + theme_cache.filesystem = get_theme_icon(SNAME("Filesystem"), SNAME("EditorIcons")); + + theme_cache.folder_medium_thumbnail = get_theme_icon(SNAME("FolderMediumThumb"), SNAME("EditorIcons")); + theme_cache.file_medium_thumbnail = get_theme_icon(SNAME("FileMediumThumb"), SNAME("EditorIcons")); + theme_cache.folder_big_thumbnail = get_theme_icon(SNAME("FolderBigThumb"), SNAME("EditorIcons")); + theme_cache.file_big_thumbnail = get_theme_icon(SNAME("FileBigThumb"), SNAME("EditorIcons")); + + theme_cache.progress[0] = get_theme_icon("Progress1", SNAME("EditorIcons")); + theme_cache.progress[1] = get_theme_icon("Progress2", SNAME("EditorIcons")); + theme_cache.progress[2] = get_theme_icon("Progress3", SNAME("EditorIcons")); + theme_cache.progress[3] = get_theme_icon("Progress4", SNAME("EditorIcons")); + theme_cache.progress[4] = get_theme_icon("Progress5", SNAME("EditorIcons")); + theme_cache.progress[5] = get_theme_icon("Progress6", SNAME("EditorIcons")); + theme_cache.progress[6] = get_theme_icon("Progress7", SNAME("EditorIcons")); + theme_cache.progress[7] = get_theme_icon("Progress8", SNAME("EditorIcons")); +} + void EditorFileDialog::_notification(int p_what) { switch (p_what) { - case NOTIFICATION_READY: case NOTIFICATION_THEME_CHANGED: case Control::NOTIFICATION_LAYOUT_DIRECTION_CHANGED: case NOTIFICATION_TRANSLATION_CHANGED: { _update_icons(); + invalidate(); } break; case NOTIFICATION_PROCESS: { @@ -86,7 +122,8 @@ void EditorFileDialog::_notification(int p_what) { if (preview_wheel_index >= 8) { preview_wheel_index = 0; } - Ref<Texture2D> frame = item_list->get_theme_icon("Progress" + itos(preview_wheel_index + 1), SNAME("EditorIcons")); + + Ref<Texture2D> frame = theme_cache.progress[preview_wheel_index]; preview->set_texture(frame); preview_wheel_timeout = 0.1; } @@ -100,7 +137,6 @@ void EditorFileDialog::_notification(int p_what) { } set_display_mode((DisplayMode)EditorSettings::get_singleton()->get("filesystem/file_dialog/display_mode").operator int()); - _update_icons(); // DO NOT CALL UPDATE FILE LIST HERE, ALL HUNDREDS OF HIDDEN DIALOGS WILL RESPOND, CALL INVALIDATE INSTEAD invalidate(); } break; @@ -289,49 +325,7 @@ void EditorFileDialog::_post_popup() { } if (is_visible()) { - Ref<Texture2D> folder = item_list->get_theme_icon(SNAME("folder"), SNAME("FileDialog")); - const Color folder_color = item_list->get_theme_color(SNAME("folder_icon_modulate"), SNAME("FileDialog")); - recent->clear(); - - bool res = (access == ACCESS_RESOURCES); - Vector<String> recentd = EditorSettings::get_singleton()->get_recent_dirs(); - Vector<String> recentd_paths; - Vector<String> recentd_names; - - for (int i = 0; i < recentd.size(); i++) { - bool cres = recentd[i].begins_with("res://"); - if (cres != res) { - continue; - } - - if (!dir_access->dir_exists(recentd[i])) { - // Remove invalid directory from the list of Recent directories. - recentd.remove_at(i--); - continue; - } - - // Compute recent directory display text. - String name = recentd[i]; - if (res && name == "res://") { - name = "/"; - } else { - if (name.ends_with("/")) { - name = name.substr(0, name.length() - 1); - } - name = name.get_file(); - } - recentd_paths.append(recentd[i]); - recentd_names.append(name); - } - - EditorNode::disambiguate_filenames(recentd_paths, recentd_names); - - for (int i = 0; i < recentd_paths.size(); i++) { - recent->add_item(recentd_names[i], folder); - recent->set_item_metadata(-1, recentd_paths[i]); - recent->set_item_icon_modulate(-1, folder_color); - } - EditorSettings::get_singleton()->set_recent_dirs(recentd); + _update_recent(); local_history.clear(); local_history_pos = -1; @@ -626,16 +620,16 @@ void EditorFileDialog::_item_list_item_rmb_clicked(int p_item, const Vector2 &p_ } if (single_item_selected) { - item_menu->add_icon_item(item_list->get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")), TTR("Copy Path"), ITEM_MENU_COPY_PATH); + item_menu->add_icon_item(theme_cache.action_copy, TTR("Copy Path"), ITEM_MENU_COPY_PATH); } if (allow_delete) { - item_menu->add_icon_item(item_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), TTR("Delete"), ITEM_MENU_DELETE, Key::KEY_DELETE); + item_menu->add_icon_item(theme_cache.action_delete, TTR("Delete"), ITEM_MENU_DELETE, Key::KEY_DELETE); } if (single_item_selected) { item_menu->add_separator(); Dictionary item_meta = item_list->get_item_metadata(p_item); String item_text = item_meta["dir"] ? TTR("Open in File Manager") : TTR("Show in File Manager"); - item_menu->add_icon_item(item_list->get_theme_icon(SNAME("Filesystem"), SNAME("EditorIcons")), item_text, ITEM_MENU_SHOW_IN_EXPLORER); + item_menu->add_icon_item(theme_cache.filesystem, item_text, ITEM_MENU_SHOW_IN_EXPLORER); } if (item_menu->get_item_count() > 0) { @@ -663,11 +657,11 @@ void EditorFileDialog::_item_list_empty_clicked(const Vector2 &p_pos, MouseButto item_menu->reset_size(); if (can_create_dir) { - item_menu->add_icon_item(item_list->get_theme_icon(SNAME("folder"), SNAME("FileDialog")), TTR("New Folder..."), ITEM_MENU_NEW_FOLDER, KeyModifierMask::CMD | Key::N); + item_menu->add_icon_item(theme_cache.folder, TTR("New Folder..."), ITEM_MENU_NEW_FOLDER, KeyModifierMask::CMD | Key::N); } - item_menu->add_icon_item(item_list->get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")), TTR("Refresh"), ITEM_MENU_REFRESH, Key::F5); + item_menu->add_icon_item(theme_cache.reload, TTR("Refresh"), ITEM_MENU_REFRESH, Key::F5); item_menu->add_separator(); - item_menu->add_icon_item(item_list->get_theme_icon(SNAME("Filesystem"), SNAME("EditorIcons")), TTR("Open in File Manager"), ITEM_MENU_SHOW_IN_EXPLORER); + item_menu->add_icon_item(theme_cache.filesystem, TTR("Open in File Manager"), ITEM_MENU_SHOW_IN_EXPLORER); item_menu->set_position(item_list->get_screen_position() + p_pos); item_menu->reset_size(); @@ -773,11 +767,11 @@ void EditorFileDialog::update_file_list() { item_list->set_fixed_icon_size(Size2(thumbnail_size, thumbnail_size)); if (thumbnail_size < 64) { - folder_thumbnail = item_list->get_theme_icon(SNAME("FolderMediumThumb"), SNAME("EditorIcons")); - file_thumbnail = item_list->get_theme_icon(SNAME("FileMediumThumb"), SNAME("EditorIcons")); + folder_thumbnail = theme_cache.folder_medium_thumbnail; + file_thumbnail = theme_cache.file_medium_thumbnail; } else { - folder_thumbnail = item_list->get_theme_icon(SNAME("FolderBigThumb"), SNAME("EditorIcons")); - file_thumbnail = item_list->get_theme_icon(SNAME("FileBigThumb"), SNAME("EditorIcons")); + folder_thumbnail = theme_cache.folder_big_thumbnail; + file_thumbnail = theme_cache.file_big_thumbnail; } preview_vb->hide(); @@ -797,8 +791,6 @@ void EditorFileDialog::update_file_list() { dir_access->list_dir_begin(); - Ref<Texture2D> folder = item_list->get_theme_icon(SNAME("folder"), SNAME("FileDialog")); - const Color folder_color = item_list->get_theme_color(SNAME("folder_icon_modulate"), SNAME("FileDialog")); List<String> files; List<String> dirs; @@ -838,7 +830,7 @@ void EditorFileDialog::update_file_list() { if (display_mode == DISPLAY_THUMBNAILS) { item_list->set_item_icon(-1, folder_thumbnail); } else { - item_list->set_item_icon(-1, folder); + item_list->set_item_icon(-1, theme_cache.folder); } Dictionary d; @@ -847,7 +839,7 @@ void EditorFileDialog::update_file_list() { d["dir"] = true; item_list->set_item_metadata(-1, d); - item_list->set_item_icon_modulate(-1, folder_color); + item_list->set_item_icon_modulate(-1, theme_cache.folder_icon_modulate); dirs.pop_front(); } @@ -1120,6 +1112,7 @@ void EditorFileDialog::invalidate() { if (is_visible()) { update_file_list(); _update_favorites(); + _update_recent(); invalidated = false; } else { invalidated = true; @@ -1235,22 +1228,25 @@ void EditorFileDialog::_update_drives(bool p_select) { void EditorFileDialog::_update_icons() { // Update icons. - mode_thumbnails->set_icon(item_list->get_theme_icon(SNAME("FileThumbnail"), SNAME("EditorIcons"))); - mode_list->set_icon(item_list->get_theme_icon(SNAME("FileList"), SNAME("EditorIcons"))); + + mode_thumbnails->set_icon(theme_cache.mode_thumbnails); + mode_list->set_icon(theme_cache.mode_list); + if (is_layout_rtl()) { - dir_prev->set_icon(item_list->get_theme_icon(SNAME("Forward"), SNAME("EditorIcons"))); - dir_next->set_icon(item_list->get_theme_icon(SNAME("Back"), SNAME("EditorIcons"))); + dir_prev->set_icon(theme_cache.forward_folder); + dir_next->set_icon(theme_cache.back_folder); } else { - dir_prev->set_icon(item_list->get_theme_icon(SNAME("Back"), SNAME("EditorIcons"))); - dir_next->set_icon(item_list->get_theme_icon(SNAME("Forward"), SNAME("EditorIcons"))); + dir_prev->set_icon(theme_cache.back_folder); + dir_next->set_icon(theme_cache.forward_folder); } - dir_up->set_icon(item_list->get_theme_icon(SNAME("ArrowUp"), SNAME("EditorIcons"))); - refresh->set_icon(item_list->get_theme_icon(SNAME("Reload"), SNAME("EditorIcons"))); - favorite->set_icon(item_list->get_theme_icon(SNAME("Favorites"), SNAME("EditorIcons"))); - show_hidden->set_icon(item_list->get_theme_icon(SNAME("GuiVisibilityVisible"), SNAME("EditorIcons"))); + dir_up->set_icon(theme_cache.parent_folder); - fav_up->set_icon(item_list->get_theme_icon(SNAME("MoveUp"), SNAME("EditorIcons"))); - fav_down->set_icon(item_list->get_theme_icon(SNAME("MoveDown"), SNAME("EditorIcons"))); + refresh->set_icon(theme_cache.reload); + favorite->set_icon(theme_cache.favorite); + show_hidden->set_icon(theme_cache.toggle_hidden); + + fav_up->set_icon(theme_cache.favorites_up); + fav_down->set_icon(theme_cache.favorites_down); } void EditorFileDialog::_favorite_selected(int p_idx) { @@ -1335,8 +1331,6 @@ void EditorFileDialog::_update_favorites() { bool res = (access == ACCESS_RESOURCES); String current = get_current_dir(); - Ref<Texture2D> folder_icon = item_list->get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")); - const Color folder_color = item_list->get_theme_color(SNAME("folder_icon_modulate"), SNAME("FileDialog")); favorites->clear(); favorite->set_pressed(false); @@ -1389,9 +1383,9 @@ void EditorFileDialog::_update_favorites() { EditorNode::disambiguate_filenames(favorited_paths, favorited_names); for (int i = 0; i < favorited_paths.size(); i++) { - favorites->add_item(favorited_names[i], folder_icon); + favorites->add_item(favorited_names[i], theme_cache.folder); favorites->set_item_metadata(-1, favorited_paths[i]); - favorites->set_item_icon_modulate(-1, folder_color); + favorites->set_item_icon_modulate(-1, theme_cache.folder_icon_modulate); if (i == current_favorite) { favorite->set_pressed(true); @@ -1435,6 +1429,50 @@ void EditorFileDialog::_favorite_pressed() { _update_favorites(); } +void EditorFileDialog::_update_recent() { + recent->clear(); + + bool res = (access == ACCESS_RESOURCES); + Vector<String> recentd = EditorSettings::get_singleton()->get_recent_dirs(); + Vector<String> recentd_paths; + Vector<String> recentd_names; + + for (int i = 0; i < recentd.size(); i++) { + bool cres = recentd[i].begins_with("res://"); + if (cres != res) { + continue; + } + + if (!dir_access->dir_exists(recentd[i])) { + // Remove invalid directory from the list of Recent directories. + recentd.remove_at(i--); + continue; + } + + // Compute recent directory display text. + String name = recentd[i]; + if (res && name == "res://") { + name = "/"; + } else { + if (name.ends_with("/")) { + name = name.substr(0, name.length() - 1); + } + name = name.get_file(); + } + recentd_paths.append(recentd[i]); + recentd_names.append(name); + } + + EditorNode::disambiguate_filenames(recentd_paths, recentd_names); + + for (int i = 0; i < recentd_paths.size(); i++) { + recent->add_item(recentd_names[i], theme_cache.folder); + recent->set_item_metadata(-1, recentd_paths[i]); + recent->set_item_icon_modulate(-1, theme_cache.folder_icon_modulate); + } + EditorSettings::get_singleton()->set_recent_dirs(recentd); +} + void EditorFileDialog::_recent_selected(int p_idx) { Vector<String> recentd = EditorSettings::get_singleton()->get_recent_dirs(); ERR_FAIL_INDEX(p_idx, recentd.size()); diff --git a/editor/editor_file_dialog.h b/editor/editor_file_dialog.h index 51629f2682..528050ba4f 100644 --- a/editor/editor_file_dialog.h +++ b/editor/editor_file_dialog.h @@ -148,6 +148,33 @@ private: bool disable_overwrite_warning = false; bool invalidated = true; + struct ThemeCache { + Ref<Texture2D> parent_folder; + Ref<Texture2D> forward_folder; + Ref<Texture2D> back_folder; + Ref<Texture2D> reload; + Ref<Texture2D> toggle_hidden; + Ref<Texture2D> favorite; + Ref<Texture2D> mode_thumbnails; + Ref<Texture2D> mode_list; + Ref<Texture2D> favorites_up; + Ref<Texture2D> favorites_down; + + Ref<Texture2D> folder; + Color folder_icon_modulate; + + Ref<Texture2D> action_copy; + Ref<Texture2D> action_delete; + Ref<Texture2D> filesystem; + + Ref<Texture2D> folder_medium_thumbnail; + Ref<Texture2D> file_medium_thumbnail; + Ref<Texture2D> folder_big_thumbnail; + Ref<Texture2D> file_big_thumbnail; + + Ref<Texture2D> progress[8]{}; + } theme_cache; + void update_dir(); void update_file_name(); void update_file_list(); @@ -161,6 +188,7 @@ private: void _favorite_move_up(); void _favorite_move_down(); + void _update_recent(); void _recent_selected(int p_idx); void _item_selected(int p_item); @@ -206,6 +234,8 @@ private: bool _is_open_should_be_disabled(); protected: + virtual void _update_theme_item_cache() override; + void _notification(int p_what); static void _bind_methods(); diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index 97f5363bb8..de89cd8df4 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -567,6 +567,8 @@ void EditorHelp::_update_doc() { class_desc->pop(); // font class_desc->add_newline(); + const String non_breaking_space = String::chr(160); + // Inheritance tree // Ascendents @@ -579,7 +581,7 @@ void EditorHelp::_update_doc() { while (!inherits.is_empty()) { _add_type_icon(inherits); - class_desc->add_text(" "); // Extra space, otherwise icon borrows hyperlink from _add_type(). + class_desc->add_text(non_breaking_space); // Otherwise icon borrows hyperlink from _add_type(). _add_type(inherits); inherits = doc->class_list[inherits].inherits; @@ -612,7 +614,7 @@ void EditorHelp::_update_doc() { class_desc->add_text(" , "); } _add_type_icon(E.value.name); - class_desc->add_text(" "); // Extra space, otherwise icon borrows hyperlink from _add_type(). + class_desc->add_text(non_breaking_space); // Otherwise icon borrows hyperlink from _add_type(). _add_type(E.value.name); prev = true; } diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 6aa0bd3f99..bdf1c314f8 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -3949,16 +3949,22 @@ void EditorInspector::_add_meta_confirm() { undo_redo->commit_action(); } -void EditorInspector::_check_meta_name(String name) { +void EditorInspector::_check_meta_name(const String &p_name) { String error; - if (name == "") { - error = TTR("Metadata can't be empty."); - } else if (!name.is_valid_identifier()) { - error = TTR("Invalid metadata identifier."); - } else if (object->has_meta(name)) { - error = TTR("Metadata already exists."); - } else if (name[0] == '_') { + if (p_name == "") { + error = TTR("Metadata name can't be empty."); + } else if (!p_name.is_valid_identifier()) { + error = TTR("Metadata name must be a valid identifier."); + } else if (object->has_meta(p_name)) { + Node *node = Object::cast_to<Node>(object); + if (node) { + error = vformat(TTR("Metadata with name \"%s\" already exists on \"%s\"."), p_name, node->get_name()); + } else { + // This should normally never be reached, but the error is set just in case. + error = vformat(TTR("Metadata with name \"%s\" already exists."), p_name, node->get_name()); + } + } else if (p_name[0] == '_') { error = TTR("Names starting with _ are reserved for editor-only metadata."); } @@ -3976,7 +3982,15 @@ void EditorInspector::_check_meta_name(String name) { void EditorInspector::_show_add_meta_dialog() { if (!add_meta_dialog) { add_meta_dialog = memnew(ConfirmationDialog); - add_meta_dialog->set_title(TTR("Add Metadata Property")); + + Node *node = Object::cast_to<Node>(object); + if (node) { + add_meta_dialog->set_title(vformat(TTR("Add Metadata Property for \"%s\""), node->get_name())); + } else { + // This should normally never be reached, but the title is set just in case. + add_meta_dialog->set_title(vformat(TTR("Add Metadata Property"), node->get_name())); + } + VBoxContainer *vbc = memnew(VBoxContainer); add_meta_dialog->add_child(vbc); HBoxContainer *hbc = memnew(HBoxContainer); diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h index 474078853a..d634eae23f 100644 --- a/editor/editor_inspector.h +++ b/editor/editor_inspector.h @@ -538,7 +538,7 @@ class EditorInspector : public ScrollContainer { void _add_meta_confirm(); void _show_add_meta_dialog(); - void _check_meta_name(String name); + void _check_meta_name(const String &p_name); protected: static void _bind_methods(); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 877581a93b..58377eef0f 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -170,6 +170,7 @@ #include "editor/plugins/mesh_instance_3d_editor_plugin.h" #include "editor/plugins/mesh_library_editor_plugin.h" #include "editor/plugins/multimesh_editor_plugin.h" +#include "editor/plugins/navigation_link_2d_editor_plugin.h" #include "editor/plugins/navigation_polygon_editor_plugin.h" #include "editor/plugins/node_3d_editor_plugin.h" #include "editor/plugins/occluder_instance_3d_editor_plugin.h" @@ -366,7 +367,7 @@ void EditorNode::_update_scene_tabs() { scene_tabs->add_tab(disambiguated_scene_names[i] + (unsaved ? "(*)" : ""), icon); if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_GLOBAL_MENU)) { - DisplayServer::get_singleton()->global_menu_add_item("_dock", editor_data.get_scene_title(i) + (unsaved ? "(*)" : ""), callable_mp(this, &EditorNode::_global_menu_scene), i); + DisplayServer::get_singleton()->global_menu_add_item("_dock", editor_data.get_scene_title(i) + (unsaved ? "(*)" : ""), callable_mp(this, &EditorNode::_global_menu_scene), Callable(), i); } if (show_rb && editor_data.get_scene_root_script(i).is_valid()) { @@ -1070,7 +1071,7 @@ void EditorNode::_sources_changed(bool p_exist) { // Reload the global shader variables, but this time // loading textures, as they are now properly imported. - RenderingServer::get_singleton()->global_shader_uniforms_load_settings(true); + RenderingServer::get_singleton()->global_shader_parameters_load_settings(true); // Start preview thread now that it's safe. if (!singleton->cmdline_export_mode) { @@ -4110,6 +4111,7 @@ void EditorNode::register_editor_types() { GDREGISTER_CLASS(EditorSyntaxHighlighter); GDREGISTER_ABSTRACT_CLASS(EditorInterface); GDREGISTER_CLASS(EditorExportPlugin); + GDREGISTER_ABSTRACT_CLASS(EditorExportPlatform); GDREGISTER_CLASS(EditorResourceConversionPlugin); GDREGISTER_CLASS(EditorSceneFormatImporter); GDREGISTER_CLASS(EditorScenePostImportPlugin); @@ -7348,6 +7350,7 @@ EditorNode::EditorNode() { add_editor_plugin(memnew(GPUParticles2DEditorPlugin)); add_editor_plugin(memnew(LightOccluder2DEditorPlugin)); add_editor_plugin(memnew(Line2DEditorPlugin)); + add_editor_plugin(memnew(NavigationLink2DEditorPlugin)); add_editor_plugin(memnew(NavigationPolygonEditorPlugin)); add_editor_plugin(memnew(Path2DEditorPlugin)); add_editor_plugin(memnew(Polygon2DEditorPlugin)); @@ -7421,11 +7424,6 @@ EditorNode::EditorNode() { editor_plugins_force_over = memnew(EditorPluginList); editor_plugins_force_input_forwarding = memnew(EditorPluginList); - Ref<EditorExportTextSceneToBinaryPlugin> export_text_to_binary_plugin; - export_text_to_binary_plugin.instantiate(); - - EditorExport::get_singleton()->add_export_plugin(export_text_to_binary_plugin); - Ref<GDExtensionExportPlugin> gdextension_export_plugin; gdextension_export_plugin.instantiate(); diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index 4fc6947636..1efbb7e40f 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -48,7 +48,7 @@ #include "scene/gui/popup_menu.h" #include "servers/rendering_server.h" -TypedArray<Texture2D> EditorInterface::_make_mesh_previews(const Array &p_meshes, int p_preview_size) { +TypedArray<Texture2D> EditorInterface::_make_mesh_previews(const TypedArray<Mesh> &p_meshes, int p_preview_size) { Vector<Ref<Mesh>> meshes; for (int i = 0; i < p_meshes.size(); i++) { diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h index 8357f0960a..1d6f48caa3 100644 --- a/editor/editor_plugin.h +++ b/editor/editor_plugin.h @@ -67,7 +67,7 @@ protected: static void _bind_methods(); static EditorInterface *singleton; - TypedArray<Texture2D> _make_mesh_previews(const Array &p_meshes, int p_preview_size); + TypedArray<Texture2D> _make_mesh_previews(const TypedArray<Mesh> &p_meshes, int p_preview_size); public: static EditorInterface *get_singleton() { return singleton; } diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index d78fee6ad6..7364258a07 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -4182,8 +4182,8 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, const Varian } struct EditorPropertyRangeHint { - bool greater = true; - bool lesser = true; + bool or_greater = true; + bool or_less = true; double min = -99999.0; double max = 99999.0; double step = 1.0; @@ -4201,8 +4201,8 @@ static EditorPropertyRangeHint _parse_range_hint(PropertyHint p_hint, const Stri ERR_FAIL_COND_V_MSG(slices.size() < 2, hint, vformat("Invalid PROPERTY_HINT_RANGE with hint \"%s\": Missing required min and/or max values.", p_hint_text)); - hint.greater = false; // If using ranged, assume false by default. - hint.lesser = false; + hint.or_greater = false; // If using ranged, assume false by default. + hint.or_less = false; hint.min = slices[0].to_float(); hint.max = slices[1].to_float(); @@ -4215,9 +4215,9 @@ static EditorPropertyRangeHint _parse_range_hint(PropertyHint p_hint, const Stri for (int i = 2; i < slices.size(); i++) { String slice = slices[i].strip_edges(); if (slice == "or_greater") { - hint.greater = true; - } else if (slice == "or_lesser") { - hint.lesser = true; + hint.or_greater = true; + } else if (slice == "or_less") { + hint.or_less = true; } else if (slice == "no_slider") { hint.hide_slider = true; } else if (slice == "exp") { @@ -4314,7 +4314,7 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_ EditorPropertyInteger *editor = memnew(EditorPropertyInteger); EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, 1); - editor->setup(hint.min, hint.max, hint.step, hint.greater, hint.lesser, hint.suffix); + editor->setup(hint.min, hint.max, hint.step, hint.or_greater, hint.or_less, hint.suffix); return editor; } @@ -4342,7 +4342,7 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_ EditorPropertyFloat *editor = memnew(EditorPropertyFloat); EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, default_float_step); - editor->setup(hint.min, hint.max, hint.step, hint.hide_slider, hint.exp_range, hint.greater, hint.lesser, hint.suffix, hint.radians); + editor->setup(hint.min, hint.max, hint.step, hint.hide_slider, hint.exp_range, hint.or_greater, hint.or_less, hint.suffix, hint.radians); return editor; } diff --git a/editor/editor_sectioned_inspector.cpp b/editor/editor_sectioned_inspector.cpp index 94ee741db5..e078bea037 100644 --- a/editor/editor_sectioned_inspector.cpp +++ b/editor/editor_sectioned_inspector.cpp @@ -113,18 +113,13 @@ class SectionedInspectorFilter : public Object { } } - bool property_can_revert(const StringName &p_name) { + bool _property_can_revert(const StringName &p_name) const { return edited->property_can_revert(section + "/" + p_name); } - Variant property_get_revert(const StringName &p_name) { - return edited->property_get_revert(section + "/" + p_name); - } - -protected: - static void _bind_methods() { - ClassDB::bind_method("property_can_revert", &SectionedInspectorFilter::property_can_revert); - ClassDB::bind_method("property_get_revert", &SectionedInspectorFilter::property_get_revert); + bool _property_get_revert(const StringName &p_name, Variant &r_property) const { + r_property = edited->property_get_revert(section + "/" + p_name); + return true; } public: diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index edd44b0a3a..73acab3876 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -1536,7 +1536,7 @@ Ref<Shortcut> ED_SHORTCUT_ARRAY(const String &p_path, const String &p_name, cons return sc; } -void EditorSettings::set_builtin_action_override(const String &p_name, const Array &p_events) { +void EditorSettings::set_builtin_action_override(const String &p_name, const TypedArray<InputEvent> &p_events) { List<Ref<InputEvent>> event_list; // Override the whole list, since events may have their order changed or be added, removed or edited. diff --git a/editor/editor_settings.h b/editor/editor_settings.h index 09bc4caa22..4dcf3a9cad 100644 --- a/editor/editor_settings.h +++ b/editor/editor_settings.h @@ -175,7 +175,7 @@ public: Ref<Shortcut> get_shortcut(const String &p_name) const; void get_shortcut_list(List<String> *r_shortcuts); - void set_builtin_action_override(const String &p_name, const Array &p_events); + void set_builtin_action_override(const String &p_name, const TypedArray<InputEvent> &p_events); const Array get_builtin_action_overrides(const String &p_name) const; void notify_changes(); diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index af0e40d1d4..76d5daadfb 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -182,7 +182,7 @@ static Ref<StyleBoxFlat> make_flat_stylebox(Color p_color, float p_margin_left = Ref<StyleBoxFlat> style(memnew(StyleBoxFlat)); style->set_bg_color(p_color); // Adjust level of detail based on the corners' effective sizes. - style->set_corner_detail(Math::ceil(1.5 * p_corner_width * EDSCALE)); + style->set_corner_detail(Math::ceil(0.8 * p_corner_width * EDSCALE)); style->set_corner_radius_all(p_corner_width * EDSCALE); style->set_default_margin(SIDE_LEFT, p_margin_left * EDSCALE); style->set_default_margin(SIDE_RIGHT, p_margin_right * EDSCALE); @@ -593,7 +593,6 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Ref<StyleBoxFlat> style_default = make_flat_stylebox(base_color, default_margin_size, default_margin_size, default_margin_size, default_margin_size, corner_width); style_default->set_border_width_all(border_width); style_default->set_border_color(base_color); - style_default->set_draw_center(true); // Button and widgets const float extra_spacing = EDITOR_GET("interface/theme/additional_spacing"); @@ -635,6 +634,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { const Color shadow_color = Color(0, 0, 0, dark_theme ? 0.3 : 0.1); style_popup->set_shadow_color(shadow_color); style_popup->set_shadow_size(4 * EDSCALE); + // Popups are separate windows by default in the editor. Windows currently don't support per-pixel transparency + // in 4.0, and even if it was, it may not always work in practice (e.g. running with compositing disabled). + style_popup->set_corner_radius_all(0); Ref<StyleBoxLine> style_popup_separator(memnew(StyleBoxLine)); style_popup_separator->set_color(separator_color); @@ -661,10 +663,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_tab_base->set_border_width_all(0); // Don't round the top corners to avoid creating a small blank space between the tabs and the main panel. // This also makes the top highlight look better. - style_tab_base->set_corner_detail(corner_width); - style_tab_base->set_corner_radius_all(0); - style_tab_base->set_corner_radius(CORNER_TOP_LEFT, corner_radius * EDSCALE); - style_tab_base->set_corner_radius(CORNER_TOP_RIGHT, corner_radius * EDSCALE); + style_tab_base->set_corner_radius(CORNER_BOTTOM_LEFT, 0); + style_tab_base->set_corner_radius(CORNER_BOTTOM_RIGHT, 0); // Prevent visible artifacts and cover the top-left rounded corner of the panel below the tab if selected // We can't prevent them with both rounded corners and non-zero border width, though @@ -975,9 +975,6 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // Always display a border for PopupMenus so they can be distinguished from their background. style_popup_menu->set_border_width_all(EDSCALE); style_popup_menu->set_border_color(dark_color_2); - // Popups are separate windows by default in the editor. Windows currently don't support per-pixel transparency - // in 4.0, and even if it was, it may not always work in practice (e.g. running with compositing disabled). - style_popup_menu->set_corner_radius_all(0); theme->set_stylebox("panel", "PopupMenu", style_popup_menu); Ref<StyleBoxFlat> style_menu_hover = style_widget_hover->duplicate(); @@ -1358,6 +1355,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("selection_color", "TextEdit", selection_color); theme->set_constant("line_spacing", "TextEdit", 4 * EDSCALE); + 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"))); theme->set_icon("grabber", "VSplitContainer", theme->get_icon(SNAME("GuiVsplitter"), SNAME("EditorIcons"))); theme->set_icon("grabber", "HSplitContainer", theme->get_icon(SNAME("GuiHsplitter"), SNAME("EditorIcons"))); @@ -1651,6 +1650,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { graphsbcomment->set_border_width(SIDE_TOP, 24 * EDSCALE); graphsbcommentselected->set_border_width(SIDE_TOP, 24 * EDSCALE); + graphsb->set_corner_detail(corner_radius * EDSCALE); + graphsbselected->set_corner_detail(corner_radius * EDSCALE); + graphsbcomment->set_corner_detail(corner_radius * EDSCALE); + graphsbcommentselected->set_corner_detail(corner_radius * EDSCALE); + theme->set_stylebox("frame", "GraphNode", graphsb); theme->set_stylebox("selected_frame", "GraphNode", graphsbselected); theme->set_stylebox("comment", "GraphNode", graphsbcomment); diff --git a/editor/editor_translation_parser.cpp b/editor/editor_translation_parser.cpp index eb4df3b630..eb38e203a5 100644 --- a/editor/editor_translation_parser.cpp +++ b/editor/editor_translation_parser.cpp @@ -38,8 +38,8 @@ EditorTranslationParser *EditorTranslationParser::singleton = nullptr; Error EditorTranslationParserPlugin::parse_file(const String &p_path, Vector<String> *r_ids, Vector<Vector<String>> *r_ids_ctx_plural) { - Array ids; - Array ids_ctx_plural; + TypedArray<String> ids; + TypedArray<Array> ids_ctx_plural; if (GDVIRTUAL_CALL(_parse_file, p_path, ids, ids_ctx_plural)) { // Add user's extracted translatable messages. diff --git a/editor/editor_translation_parser.h b/editor/editor_translation_parser.h index bd770250f9..0fe166a0b0 100644 --- a/editor/editor_translation_parser.h +++ b/editor/editor_translation_parser.h @@ -35,6 +35,7 @@ #include "core/object/gdvirtual.gen.inc" #include "core/object/ref_counted.h" #include "core/object/script_language.h" +#include "core/variant/typed_array.h" class EditorTranslationParserPlugin : public RefCounted { GDCLASS(EditorTranslationParserPlugin, RefCounted); @@ -42,7 +43,7 @@ class EditorTranslationParserPlugin : public RefCounted { protected: static void _bind_methods(); - GDVIRTUAL3(_parse_file, String, Array, Array) + GDVIRTUAL3(_parse_file, String, TypedArray<String>, TypedArray<Array>) GDVIRTUAL0RC(Vector<String>, _get_recognized_extensions) public: diff --git a/editor/editor_vcs_interface.cpp b/editor/editor_vcs_interface.cpp index 0c6c876b2f..d22c7bd149 100644 --- a/editor/editor_vcs_interface.cpp +++ b/editor/editor_vcs_interface.cpp @@ -57,7 +57,7 @@ void EditorVCSInterface::set_credentials(String p_username, String p_password, S } List<String> EditorVCSInterface::get_remotes() { - Array result; + TypedArray<Dictionary> result; if (!GDVIRTUAL_CALL(_get_remotes, result)) { UNIMPLEMENTED(); return {}; @@ -71,7 +71,7 @@ List<String> EditorVCSInterface::get_remotes() { } List<EditorVCSInterface::StatusFile> EditorVCSInterface::get_modified_files_data() { - Array result; + TypedArray<Dictionary> result; if (!GDVIRTUAL_CALL(_get_modified_files_data, result)) { UNIMPLEMENTED(); return {}; @@ -123,7 +123,7 @@ List<EditorVCSInterface::DiffFile> EditorVCSInterface::get_diff(String p_identif } List<EditorVCSInterface::Commit> EditorVCSInterface::get_previous_commits(int p_max_commits) { - Array result; + TypedArray<Dictionary> result; if (!GDVIRTUAL_CALL(_get_previous_commits, p_max_commits, result)) { UNIMPLEMENTED(); return {}; @@ -137,7 +137,7 @@ List<EditorVCSInterface::Commit> EditorVCSInterface::get_previous_commits(int p_ } List<String> EditorVCSInterface::get_branch_list() { - Array result; + TypedArray<Dictionary> result; if (!GDVIRTUAL_CALL(_get_branch_list, result)) { UNIMPLEMENTED(); return {}; @@ -210,7 +210,7 @@ void EditorVCSInterface::fetch(String p_remote) { } List<EditorVCSInterface::DiffHunk> EditorVCSInterface::get_line_diff(String p_file_path, String p_text) { - Array result; + TypedArray<Dictionary> result; if (!GDVIRTUAL_CALL(_get_line_diff, p_file_path, p_text, result)) { UNIMPLEMENTED(); return {}; @@ -257,11 +257,11 @@ Dictionary EditorVCSInterface::create_diff_hunk(int p_old_start, int p_new_start diff_hunk["old_lines"] = p_old_lines; diff_hunk["new_start"] = p_new_start; diff_hunk["old_start"] = p_old_start; - diff_hunk["diff_lines"] = Array(); + diff_hunk["diff_lines"] = TypedArray<Dictionary>(); return diff_hunk; } -Dictionary EditorVCSInterface::add_line_diffs_into_diff_hunk(Dictionary p_diff_hunk, Array p_line_diffs) { +Dictionary EditorVCSInterface::add_line_diffs_into_diff_hunk(Dictionary p_diff_hunk, TypedArray<Dictionary> p_line_diffs) { p_diff_hunk["diff_lines"] = p_line_diffs; return p_diff_hunk; } @@ -270,7 +270,7 @@ Dictionary EditorVCSInterface::create_diff_file(String p_new_file, String p_old_ Dictionary file_diff; file_diff["new_file"] = p_new_file; file_diff["old_file"] = p_old_file; - file_diff["diff_hunks"] = Array(); + file_diff["diff_hunks"] = TypedArray<Dictionary>(); return file_diff; } @@ -284,7 +284,7 @@ Dictionary EditorVCSInterface::create_commit(String p_msg, String p_author, Stri return commit_info; } -Dictionary EditorVCSInterface::add_diff_hunks_into_diff_file(Dictionary p_diff_file, Array p_diff_hunks) { +Dictionary EditorVCSInterface::add_diff_hunks_into_diff_file(Dictionary p_diff_file, TypedArray<Dictionary> p_diff_hunks) { p_diff_file["diff_hunks"] = p_diff_hunks; return p_diff_file; } @@ -312,7 +312,7 @@ EditorVCSInterface::DiffHunk EditorVCSInterface::_convert_diff_hunk(Dictionary p dh.old_lines = p_diff_hunk["old_lines"]; dh.new_start = p_diff_hunk["new_start"]; dh.old_start = p_diff_hunk["old_start"]; - Array diff_lines = p_diff_hunk["diff_lines"]; + TypedArray<Dictionary> diff_lines = p_diff_hunk["diff_lines"]; for (int i = 0; i < diff_lines.size(); i++) { DiffLine dl = _convert_diff_line(diff_lines[i]); dh.diff_lines.push_back(dl); @@ -324,7 +324,7 @@ EditorVCSInterface::DiffFile EditorVCSInterface::_convert_diff_file(Dictionary p DiffFile df; df.new_file = p_diff_file["new_file"]; df.old_file = p_diff_file["old_file"]; - Array diff_hunks = p_diff_file["diff_hunks"]; + TypedArray<Dictionary> diff_hunks = p_diff_file["diff_hunks"]; for (int i = 0; i < diff_hunks.size(); i++) { DiffHunk dh = _convert_diff_hunk(diff_hunks[i]); df.diff_hunks.push_back(dh); diff --git a/editor/editor_vcs_interface.h b/editor/editor_vcs_interface.h index e23e032ab9..5d4901cefa 100644 --- a/editor/editor_vcs_interface.h +++ b/editor/editor_vcs_interface.h @@ -108,7 +108,7 @@ protected: // Proxy endpoints for extensions to implement GDVIRTUAL1R(bool, _initialize, String); GDVIRTUAL5(_set_credentials, String, String, String, String, String); - GDVIRTUAL0R(Array, _get_modified_files_data); + GDVIRTUAL0R(TypedArray<Dictionary>, _get_modified_files_data); GDVIRTUAL1(_stage_file, String); GDVIRTUAL1(_unstage_file, String); GDVIRTUAL1(_discard_file, String); @@ -116,9 +116,9 @@ protected: GDVIRTUAL2R(TypedArray<Dictionary>, _get_diff, String, int); GDVIRTUAL0R(bool, _shut_down); GDVIRTUAL0R(String, _get_vcs_name); - GDVIRTUAL1R(Array, _get_previous_commits, int); - GDVIRTUAL0R(Array, _get_branch_list); - GDVIRTUAL0R(Array, _get_remotes); + GDVIRTUAL1R(TypedArray<Dictionary>, _get_previous_commits, int); + GDVIRTUAL0R(TypedArray<Dictionary>, _get_branch_list); + GDVIRTUAL0R(TypedArray<Dictionary>, _get_remotes); GDVIRTUAL1(_create_branch, String); GDVIRTUAL1(_remove_branch, String); GDVIRTUAL2(_create_remote, String, String); @@ -128,7 +128,7 @@ protected: GDVIRTUAL1(_pull, String); GDVIRTUAL2(_push, String, bool); GDVIRTUAL1(_fetch, String); - GDVIRTUAL2R(Array, _get_line_diff, String, String); + GDVIRTUAL2R(TypedArray<Dictionary>, _get_line_diff, String, String); public: static EditorVCSInterface *get_singleton(); @@ -171,8 +171,8 @@ public: Dictionary create_diff_file(String p_new_file, String p_old_file); Dictionary create_commit(String p_msg, String p_author, String p_id, int64_t p_unix_timestamp, int64_t p_offset_minutes); Dictionary create_status_file(String p_file_path, ChangeType p_change, TreeArea p_area); - Dictionary add_line_diffs_into_diff_hunk(Dictionary p_diff_hunk, Array p_line_diffs); - Dictionary add_diff_hunks_into_diff_file(Dictionary p_diff_file, Array p_diff_hunks); + Dictionary add_line_diffs_into_diff_hunk(Dictionary p_diff_hunk, TypedArray<Dictionary> p_line_diffs); + Dictionary add_diff_hunks_into_diff_file(Dictionary p_diff_file, TypedArray<Dictionary> p_diff_hunks); void popup_error(String p_msg); }; diff --git a/editor/export/editor_export.cpp b/editor/export/editor_export.cpp index d291040bd2..29b6a5e546 100644 --- a/editor/export/editor_export.cpp +++ b/editor/export/editor_export.cpp @@ -351,6 +351,8 @@ EditorExport::EditorExport() { singleton = this; set_process(true); + + GLOBAL_DEF("editor/export/convert_text_resources_to_binary", true); } EditorExport::~EditorExport() { diff --git a/editor/export/editor_export_platform.cpp b/editor/export/editor_export_platform.cpp index e07b5e4cdb..525a962222 100644 --- a/editor/export/editor_export_platform.cpp +++ b/editor/export/editor_export_platform.cpp @@ -44,6 +44,7 @@ #include "editor/editor_settings.h" #include "editor/plugins/script_editor_plugin.h" #include "editor_export_plugin.h" +#include "scene/resources/packed_scene.h" static int _get_pad(int p_alignment, int p_n) { int rest = p_n % p_alignment; @@ -488,6 +489,295 @@ EditorExportPlatform::ExportNotifier::~ExportNotifier() { } } +bool EditorExportPlatform::_export_customize_dictionary(Dictionary &dict, LocalVector<Ref<EditorExportPlugin>> &customize_resources_plugins) { + bool changed = false; + + List<Variant> keys; + dict.get_key_list(&keys); + for (const Variant &K : keys) { + Variant v = dict[K]; + switch (v.get_type()) { + case Variant::OBJECT: { + Ref<Resource> res = v; + if (res.is_valid()) { + for (uint32_t j = 0; j < customize_resources_plugins.size(); j++) { + Ref<Resource> new_res = customize_resources_plugins[j]->_customize_resource(res, ""); + if (new_res.is_valid()) { + changed = true; + if (new_res != res) { + dict[K] = new_res; + res = new_res; + } + break; + } + } + + // If it was not replaced, go through and see if there is something to replace. + if (res.is_valid() && !res->get_path().is_resource_file() && _export_customize_object(res.ptr(), customize_resources_plugins), true) { + changed = true; + } + } + + } break; + case Variant::DICTIONARY: { + Dictionary d = v; + if (_export_customize_dictionary(d, customize_resources_plugins)) { + changed = true; + } + } break; + case Variant::ARRAY: { + Array a = v; + if (_export_customize_array(a, customize_resources_plugins)) { + changed = true; + } + } break; + default: { + } + } + } + return changed; +} + +bool EditorExportPlatform::_export_customize_array(Array &arr, LocalVector<Ref<EditorExportPlugin>> &customize_resources_plugins) { + bool changed = false; + + for (int i = 0; i < arr.size(); i++) { + Variant v = arr.get(i); + switch (v.get_type()) { + case Variant::OBJECT: { + Ref<Resource> res = v; + if (res.is_valid()) { + for (uint32_t j = 0; j < customize_resources_plugins.size(); j++) { + Ref<Resource> new_res = customize_resources_plugins[j]->_customize_resource(res, ""); + if (new_res.is_valid()) { + changed = true; + if (new_res != res) { + arr.set(i, new_res); + res = new_res; + } + break; + } + } + + // If it was not replaced, go through and see if there is something to replace. + if (res.is_valid() && !res->get_path().is_resource_file() && _export_customize_object(res.ptr(), customize_resources_plugins), true) { + changed = true; + } + } + } break; + case Variant::DICTIONARY: { + Dictionary d = v; + if (_export_customize_dictionary(d, customize_resources_plugins)) { + changed = true; + } + } break; + case Variant::ARRAY: { + Array a = v; + if (_export_customize_array(a, customize_resources_plugins)) { + changed = true; + } + } break; + default: { + } + } + } + return changed; +} + +bool EditorExportPlatform::_export_customize_object(Object *p_object, LocalVector<Ref<EditorExportPlugin>> &customize_resources_plugins) { + bool changed = false; + + List<PropertyInfo> props; + p_object->get_property_list(&props); + for (const PropertyInfo &E : props) { + switch (E.type) { + case Variant::OBJECT: { + Ref<Resource> res = p_object->get(E.name); + if (res.is_valid()) { + for (uint32_t j = 0; j < customize_resources_plugins.size(); j++) { + Ref<Resource> new_res = customize_resources_plugins[j]->_customize_resource(res, ""); + if (new_res.is_valid()) { + changed = true; + if (new_res != res) { + p_object->set(E.name, new_res); + res = new_res; + } + break; + } + } + + // If it was not replaced, go through and see if there is something to replace. + if (res.is_valid() && !res->get_path().is_resource_file() && _export_customize_object(res.ptr(), customize_resources_plugins), true) { + changed = true; + } + } + + } break; + case Variant::DICTIONARY: { + Dictionary d = p_object->get(E.name); + if (_export_customize_dictionary(d, customize_resources_plugins)) { + // May have been generated, so set back just in case + p_object->set(E.name, d); + changed = true; + } + } break; + case Variant::ARRAY: { + Array a = p_object->get(E.name); + if (_export_customize_array(a, customize_resources_plugins)) { + // May have been generated, so set back just in case + p_object->set(E.name, a); + changed = true; + } + } break; + default: { + } + } + } + return changed; +} + +bool EditorExportPlatform::_export_customize_scene_resources(Node *p_root, Node *p_node, LocalVector<Ref<EditorExportPlugin>> &customize_resources_plugins) { + bool changed = false; + + if (p_node == p_root || p_node->get_owner() == p_root) { + if (_export_customize_object(p_node, customize_resources_plugins)) { + changed = true; + } + } + + for (int i = 0; i < p_node->get_child_count(); i++) { + if (_export_customize_scene_resources(p_root, p_node->get_child(i), customize_resources_plugins)) { + changed = true; + } + } + + return changed; +} + +String EditorExportPlatform::_export_customize(const String &p_path, LocalVector<Ref<EditorExportPlugin>> &customize_resources_plugins, LocalVector<Ref<EditorExportPlugin>> &customize_scenes_plugins, HashMap<String, FileExportCache> &export_cache, const String &export_base_path, bool p_force_save) { + if (!p_force_save && customize_resources_plugins.is_empty() && customize_scenes_plugins.is_empty()) { + return p_path; // do none + } + + // Check if a cache exists + if (export_cache.has(p_path)) { + FileExportCache &fec = export_cache[p_path]; + + if (fec.saved_path.is_empty() || FileAccess::exists(fec.saved_path)) { + // Destination file exists (was not erased) or not needed + + uint64_t mod_time = FileAccess::get_modified_time(p_path); + if (fec.source_modified_time == mod_time) { + // Cached (modified time matches). + fec.used = true; + return fec.saved_path.is_empty() ? p_path : fec.saved_path; + } + + String md5 = FileAccess::get_md5(p_path); + if (FileAccess::exists(p_path + ".import")) { + // Also consider the import file in the string + md5 += FileAccess::get_md5(p_path + ".import"); + } + if (fec.source_md5 == md5) { + // Cached (md5 matches). + fec.source_modified_time = mod_time; + fec.used = true; + return fec.saved_path.is_empty() ? p_path : fec.saved_path; + } + } + } + + FileExportCache fec; + fec.used = true; + fec.source_modified_time = FileAccess::get_modified_time(p_path); + + String md5 = FileAccess::get_md5(p_path); + if (FileAccess::exists(p_path + ".import")) { + // Also consider the import file in the string + md5 += FileAccess::get_md5(p_path + ".import"); + } + + fec.source_md5 = md5; + + // Check if it should convert + + String type = ResourceLoader::get_resource_type(p_path); + + bool modified = false; + + String save_path; + + if (type == "PackedScene") { // Its a scene. + Ref<PackedScene> ps = ResourceLoader::load(p_path, "PackedScene", ResourceFormatLoader::CACHE_MODE_IGNORE); + ERR_FAIL_COND_V(ps.is_null(), p_path); + Node *node = ps->instantiate(); + ERR_FAIL_COND_V(node == nullptr, p_path); + if (customize_scenes_plugins.size()) { + for (uint32_t i = 0; i < customize_scenes_plugins.size(); i++) { + Node *customized = customize_scenes_plugins[i]->_customize_scene(node, p_path); + if (customized != nullptr) { + node = customized; + modified = true; + } + } + } + if (customize_resources_plugins.size()) { + if (_export_customize_scene_resources(node, node, customize_resources_plugins)) { + modified = true; + } + } + + if (modified || p_force_save) { + // If modified, save it again. This is also used for TSCN -> SCN conversion on export. + + String base_file = p_path.get_file().get_basename() + ".scn"; // use SCN for saving (binary) and repack (If conversting, TSCN PackedScene representation is inefficient, so repacking is also desired). + save_path = export_base_path.path_join("export-" + p_path.md5_text() + "-" + base_file); + + Ref<PackedScene> s; + s.instantiate(); + s->pack(node); + Error err = ResourceSaver::save(s, save_path); + ERR_FAIL_COND_V_MSG(err != OK, p_path, "Unable to save export scene file to: " + save_path); + } + } else { + Ref<Resource> res = ResourceLoader::load(p_path, "", ResourceFormatLoader::CACHE_MODE_IGNORE); + ERR_FAIL_COND_V(res.is_null(), p_path); + + if (customize_resources_plugins.size()) { + for (uint32_t i = 0; i < customize_resources_plugins.size(); i++) { + Ref<Resource> new_res = customize_resources_plugins[i]->_customize_resource(res, p_path); + if (new_res.is_valid()) { + modified = true; + if (new_res != res) { + res = new_res; + } + break; + } + } + + if (_export_customize_object(res.ptr(), customize_resources_plugins)) { + modified = true; + } + } + + if (modified || p_force_save) { + // If modified, save it again. This is also used for TRES -> RES conversion on export. + + String base_file = p_path.get_file().get_basename() + ".res"; // use RES for saving (binary) + save_path = export_base_path.path_join("export-" + p_path.md5_text() + "-" + base_file); + + Error err = ResourceSaver::save(res, save_path); + ERR_FAIL_COND_V_MSG(err != OK, p_path, "Unable to save export resource file to: " + save_path); + } + } + + fec.saved_path = save_path; + + export_cache[p_path] = fec; + + return save_path.is_empty() ? p_path : save_path; +} + Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &p_preset, bool p_debug, EditorExportSaveFunction p_func, void *p_udata, EditorExportSaveSharedObject p_so_func) { //figure out paths of files that will be exported HashSet<String> paths; @@ -601,6 +891,15 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & Error err = OK; Vector<Ref<EditorExportPlugin>> export_plugins = EditorExport::get_singleton()->get_export_plugins(); + struct SortByName { + bool operator()(const Ref<EditorExportPlugin> &left, const Ref<EditorExportPlugin> &right) const { + return left->_get_name() < right->_get_name(); + } + }; + + // Always sort by name, to so if for some reason theya are re-arranged, it still works. + export_plugins.sort_custom<SortByName>(); + for (int i = 0; i < export_plugins.size(); i++) { export_plugins.write[i]->set_export_preset(p_preset); @@ -623,6 +922,65 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & } HashSet<String> features = get_features(p_preset, p_debug); + PackedStringArray features_psa; + for (const String &feature : features) { + features_psa.push_back(feature); + } + + // Check if custom processing is needed + uint32_t custom_resources_hash = HASH_MURMUR3_SEED; + uint32_t custom_scene_hash = HASH_MURMUR3_SEED; + + LocalVector<Ref<EditorExportPlugin>> customize_resources_plugins; + LocalVector<Ref<EditorExportPlugin>> customize_scenes_plugins; + + for (int i = 0; i < export_plugins.size(); i++) { + if (export_plugins[i]->_begin_customize_resources(Ref<EditorExportPlatform>(this), features_psa)) { + customize_resources_plugins.push_back(export_plugins[i]); + + custom_resources_hash = hash_murmur3_one_64(export_plugins[i]->_get_name().hash64(), custom_resources_hash); + uint64_t hash = export_plugins[i]->_get_customization_configuration_hash(); + custom_resources_hash = hash_murmur3_one_64(hash, custom_resources_hash); + } + if (export_plugins[i]->_begin_customize_scenes(Ref<EditorExportPlatform>(this), features_psa)) { + customize_scenes_plugins.push_back(export_plugins[i]); + + custom_resources_hash = hash_murmur3_one_64(export_plugins[i]->_get_name().hash64(), custom_resources_hash); + uint64_t hash = export_plugins[i]->_get_customization_configuration_hash(); + custom_scene_hash = hash_murmur3_one_64(hash, custom_scene_hash); + } + } + + HashMap<String, FileExportCache> export_cache; + String export_base_path = ProjectSettings::get_singleton()->get_project_data_path().path_join("exported/") + itos(custom_resources_hash); + + bool convert_text_to_binary = GLOBAL_GET("editor/export/convert_text_resources_to_binary"); + + if (convert_text_to_binary || customize_resources_plugins.size() || customize_scenes_plugins.size()) { + // See if we have something to open + Ref<FileAccess> f = FileAccess::open(export_base_path.path_join("file_cache"), FileAccess::READ); + if (f.is_valid()) { + String l = f->get_line(); + while (l != String()) { + Vector<String> fields = l.split("::"); + if (fields.size() == 4) { + FileExportCache fec; + String path = fields[0]; + fec.source_md5 = fields[1].strip_edges(); + fec.source_modified_time = fields[2].strip_edges().to_int(); + fec.saved_path = fields[3]; + fec.used = false; // Assume unused until used. + export_cache[path] = fec; + } + l = f->get_line(); + } + } else { + // create the path + Ref<DirAccess> d = DirAccess::create(DirAccess::ACCESS_RESOURCES); + d->change_dir(ProjectSettings::get_singleton()->get_project_data_path()); + d->make_dir_recursive("exported/" + itos(custom_resources_hash)); + } + } //store everything in the export medium int idx = 0; @@ -633,85 +991,133 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & String type = ResourceLoader::get_resource_type(path); if (FileAccess::exists(path + ".import")) { - //file is imported, replace by what it imports - Ref<ConfigFile> config; - config.instantiate(); - err = config->load(path + ".import"); - if (err != OK) { - ERR_PRINT("Could not parse: '" + path + "', not exported."); - continue; - } + // Before doing this, try to see if it can be customized - String importer_type = config->get_value("remap", "importer"); + String export_path = _export_customize(path, customize_resources_plugins, customize_scenes_plugins, export_cache, export_base_path, false); - if (importer_type == "keep") { - //just keep file as-is - Vector<uint8_t> array = FileAccess::get_file_as_array(path); - err = p_func(p_udata, path, array, idx, total, enc_in_filters, enc_ex_filters, key); + if (export_path != path) { + // It was actually customized.. + // Since the original file is likely not recognized, just use the import system + Ref<ConfigFile> config; + config.instantiate(); + err = config->load(path + ".import"); + if (err != OK) { + ERR_PRINT("Could not parse: '" + path + "', not exported."); + continue; + } + config->set_value("remap", "type", ResourceLoader::get_resource_type(export_path)); + + // Erase all PAths + List<String> keys; + config->get_section_keys("remap", &keys); + for (const String &K : keys) { + if (E.begins_with("path")) { + config->erase_section_key("remap", K); + } + } + // Set actual converted path. + config->set_value("remap", "path", export_path); + + // erase useless sections + config->erase_section("deps"); + config->erase_section("params"); + + String import_text = config->encode_to_text(); + CharString cs = import_text.utf8(); + Vector<uint8_t> sarr; + sarr.resize(cs.size()); + memcpy(sarr.ptrw(), cs.ptr(), sarr.size()); + + err = p_func(p_udata, path + ".import", sarr, idx, total, enc_in_filters, enc_ex_filters, key); if (err != OK) { return err; } + // Now actual remapped file: + sarr = FileAccess::get_file_as_array(export_path); + err = p_func(p_udata, export_path, sarr, idx, total, enc_in_filters, enc_ex_filters, key); + if (err != OK) { + return err; + } + } else { + // file is imported and not customized, replace by what it imports + Ref<ConfigFile> config; + config.instantiate(); + err = config->load(path + ".import"); + if (err != OK) { + ERR_PRINT("Could not parse: '" + path + "', not exported."); + continue; + } - continue; - } + String importer_type = config->get_value("remap", "importer"); - List<String> remaps; - config->get_section_keys("remap", &remaps); + if (importer_type == "keep") { + //just keep file as-is + Vector<uint8_t> array = FileAccess::get_file_as_array(path); + err = p_func(p_udata, path, array, idx, total, enc_in_filters, enc_ex_filters, key); - HashSet<String> remap_features; + if (err != OK) { + return err; + } - for (const String &F : remaps) { - String remap = F; - String feature = remap.get_slice(".", 1); - if (features.has(feature)) { - remap_features.insert(feature); + continue; } - } - if (remap_features.size() > 1) { - this->resolve_platform_feature_priorities(p_preset, remap_features); - } + List<String> remaps; + config->get_section_keys("remap", &remaps); - err = OK; + HashSet<String> remap_features; - for (const String &F : remaps) { - String remap = F; - if (remap == "path") { - String remapped_path = config->get_value("remap", remap); - Vector<uint8_t> array = FileAccess::get_file_as_array(remapped_path); - err = p_func(p_udata, remapped_path, array, idx, total, enc_in_filters, enc_ex_filters, key); - } else if (remap.begins_with("path.")) { + for (const String &F : remaps) { + String remap = F; String feature = remap.get_slice(".", 1); + if (features.has(feature)) { + remap_features.insert(feature); + } + } - if (remap_features.has(feature)) { + if (remap_features.size() > 1) { + this->resolve_platform_feature_priorities(p_preset, remap_features); + } + + err = OK; + + for (const String &F : remaps) { + String remap = F; + if (remap == "path") { String remapped_path = config->get_value("remap", remap); Vector<uint8_t> array = FileAccess::get_file_as_array(remapped_path); err = p_func(p_udata, remapped_path, array, idx, total, enc_in_filters, enc_ex_filters, key); + } else if (remap.begins_with("path.")) { + String feature = remap.get_slice(".", 1); + + if (remap_features.has(feature)) { + String remapped_path = config->get_value("remap", remap); + Vector<uint8_t> array = FileAccess::get_file_as_array(remapped_path); + err = p_func(p_udata, remapped_path, array, idx, total, enc_in_filters, enc_ex_filters, key); + } } } - } - if (err != OK) { - return err; - } + if (err != OK) { + return err; + } - //also save the .import file - Vector<uint8_t> array = FileAccess::get_file_as_array(path + ".import"); - err = p_func(p_udata, path + ".import", array, idx, total, enc_in_filters, enc_ex_filters, key); + //also save the .import file + Vector<uint8_t> array = FileAccess::get_file_as_array(path + ".import"); + err = p_func(p_udata, path + ".import", array, idx, total, enc_in_filters, enc_ex_filters, key); - if (err != OK) { - return err; + if (err != OK) { + return err; + } } } else { + // Customize + bool do_export = true; for (int i = 0; i < export_plugins.size(); i++) { if (export_plugins[i]->get_script_instance()) { //script based - PackedStringArray features_psa; - for (const String &feature : features) { - features_psa.push_back(feature); - } export_plugins.write[i]->_export_file_script(path, type, features_psa); } else { export_plugins.write[i]->_export_file(path, type, features); @@ -748,8 +1154,18 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & } //just store it as it comes if (do_export) { - Vector<uint8_t> array = FileAccess::get_file_as_array(path); - err = p_func(p_udata, path, array, idx, total, enc_in_filters, enc_ex_filters, key); + // Customization only happens if plugins did not take care of it before + bool force_binary = convert_text_to_binary && (path.get_extension().to_lower() == "tres" || path.get_extension().to_lower() == "tscn"); + String export_path = _export_customize(path, customize_resources_plugins, customize_scenes_plugins, export_cache, export_base_path, force_binary); + + if (export_path != path) { + // Add a remap entry + path_remaps.push_back(path); + path_remaps.push_back(export_path); + } + + Vector<uint8_t> array = FileAccess::get_file_as_array(export_path); + err = p_func(p_udata, export_path, array, idx, total, enc_in_filters, enc_ex_filters, key); if (err != OK) { return err; } @@ -759,6 +1175,31 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & idx++; } + if (convert_text_to_binary || customize_resources_plugins.size() || customize_scenes_plugins.size()) { + // End scene customization + + String fcache = export_base_path.path_join("file_cache"); + Ref<FileAccess> f = FileAccess::open(fcache, FileAccess::WRITE); + + if (f.is_valid()) { + for (const KeyValue<String, FileExportCache> &E : export_cache) { + if (E.value.used) { // May be old, unused + String l = E.key + "::" + E.value.source_md5 + "::" + itos(E.value.source_modified_time) + "::" + E.value.saved_path; + f->store_line(l); + } + } + } else { + ERR_PRINT("Error opening export file cache: " + fcache); + } + + for (uint32_t i = 0; i < customize_resources_plugins.size(); i++) { + customize_resources_plugins[i]->_end_customize_resources(); + } + + for (uint32_t i = 0; i < customize_scenes_plugins.size(); i++) { + customize_scenes_plugins[i]->_end_customize_scenes(); + } + } //save config! Vector<String> custom_list; diff --git a/editor/export/editor_export_platform.h b/editor/export/editor_export_platform.h index bbdb47e041..93bc54284f 100644 --- a/editor/export/editor_export_platform.h +++ b/editor/export/editor_export_platform.h @@ -40,6 +40,8 @@ struct EditorProgress; #include "scene/gui/rich_text_label.h" #include "scene/main/node.h" +class EditorExportPlugin; + class EditorExportPlatform : public RefCounted { GDCLASS(EditorExportPlatform, RefCounted); @@ -99,6 +101,20 @@ private: static Error _add_shared_object(void *p_userdata, const SharedObject &p_so); + struct FileExportCache { + uint64_t source_modified_time = 0; + String source_md5; + String saved_path; + bool used = false; + }; + + bool _export_customize_dictionary(Dictionary &dict, LocalVector<Ref<EditorExportPlugin>> &customize_resources_plugins); + bool _export_customize_array(Array &array, LocalVector<Ref<EditorExportPlugin>> &customize_resources_plugins); + bool _export_customize_object(Object *p_object, LocalVector<Ref<EditorExportPlugin>> &customize_resources_plugins); + bool _export_customize_scene_resources(Node *p_root, Node *p_node, LocalVector<Ref<EditorExportPlugin>> &customize_resources_plugins); + + String _export_customize(const String &p_path, LocalVector<Ref<EditorExportPlugin>> &customize_resources_plugins, LocalVector<Ref<EditorExportPlugin>> &customize_scenes_plugins, HashMap<String, FileExportCache> &export_cache, const String &export_base_path, bool p_force_save); + protected: struct ExportNotifier { ExportNotifier(EditorExportPlatform &p_platform, const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags); diff --git a/editor/export/editor_export_plugin.cpp b/editor/export/editor_export_plugin.cpp index 27a671a919..971ea579cc 100644 --- a/editor/export/editor_export_plugin.cpp +++ b/editor/export/editor_export_plugin.cpp @@ -138,6 +138,64 @@ void EditorExportPlugin::_export_end_script() { GDVIRTUAL_CALL(_export_end); } +// Customization + +bool EditorExportPlugin::_begin_customize_resources(const Ref<EditorExportPlatform> &p_platform, const Vector<String> &p_features) const { + bool ret = false; + if (GDVIRTUAL_CALL(_begin_customize_resources, p_platform, p_features, ret)) { + return ret; + } + return false; +} + +Ref<Resource> EditorExportPlugin::_customize_resource(const Ref<Resource> &p_resource, const String &p_path) { + Ref<Resource> ret; + if (GDVIRTUAL_REQUIRED_CALL(_customize_resource, p_resource, p_path, ret)) { + return ret; + } + return Ref<Resource>(); +} + +bool EditorExportPlugin::_begin_customize_scenes(const Ref<EditorExportPlatform> &p_platform, const Vector<String> &p_features) const { + bool ret = false; + if (GDVIRTUAL_CALL(_begin_customize_scenes, p_platform, p_features, ret)) { + return ret; + } + return false; +} + +Node *EditorExportPlugin::_customize_scene(Node *p_root, const String &p_path) { + Node *ret = nullptr; + if (GDVIRTUAL_REQUIRED_CALL(_customize_scene, p_root, p_path, ret)) { + return ret; + } + return nullptr; +} + +uint64_t EditorExportPlugin::_get_customization_configuration_hash() const { + uint64_t ret = 0; + if (GDVIRTUAL_REQUIRED_CALL(_get_customization_configuration_hash, ret)) { + return ret; + } + return 0; +} + +void EditorExportPlugin::_end_customize_scenes() { + GDVIRTUAL_CALL(_end_customize_scenes); +} + +void EditorExportPlugin::_end_customize_resources() { + GDVIRTUAL_CALL(_end_customize_resources); +} + +String EditorExportPlugin::_get_name() const { + String ret; + if (GDVIRTUAL_REQUIRED_CALL(_get_name, ret)) { + return ret; + } + return ""; +} + void EditorExportPlugin::_export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features) { } @@ -164,38 +222,20 @@ void EditorExportPlugin::_bind_methods() { GDVIRTUAL_BIND(_export_file, "path", "type", "features"); GDVIRTUAL_BIND(_export_begin, "features", "is_debug", "path", "flags"); GDVIRTUAL_BIND(_export_end); -} -EditorExportPlugin::EditorExportPlugin() { -} + GDVIRTUAL_BIND(_begin_customize_resources, "platform", "features"); + GDVIRTUAL_BIND(_customize_resource, "resource", "path"); -/////////////////////// + GDVIRTUAL_BIND(_begin_customize_scenes, "platform", "features"); + GDVIRTUAL_BIND(_customize_scene, "scene", "path"); -void EditorExportTextSceneToBinaryPlugin::_export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features) { - String extension = p_path.get_extension().to_lower(); - if (extension != "tres" && extension != "tscn") { - return; - } + GDVIRTUAL_BIND(_get_customization_configuration_hash); - bool convert = GLOBAL_GET("editor/export/convert_text_resources_to_binary"); - if (!convert) { - return; - } - String tmp_path = EditorPaths::get_singleton()->get_cache_dir().path_join("tmpfile.res"); - Error err = ResourceFormatLoaderText::convert_file_to_binary(p_path, tmp_path); - if (err != OK) { - DirAccess::remove_file_or_error(tmp_path); - ERR_FAIL(); - } - Vector<uint8_t> data = FileAccess::get_file_as_array(tmp_path); - if (data.size() == 0) { - DirAccess::remove_file_or_error(tmp_path); - ERR_FAIL(); - } - DirAccess::remove_file_or_error(tmp_path); - add_file(p_path + ".converted.res", data, true); + GDVIRTUAL_BIND(_end_customize_scenes); + GDVIRTUAL_BIND(_end_customize_resources); + + GDVIRTUAL_BIND(_get_name); } -EditorExportTextSceneToBinaryPlugin::EditorExportTextSceneToBinaryPlugin() { - GLOBAL_DEF("editor/export/convert_text_resources_to_binary", false); +EditorExportPlugin::EditorExportPlugin() { } diff --git a/editor/export/editor_export_plugin.h b/editor/export/editor_export_plugin.h index 04ebc1dfed..3f37ed40be 100644 --- a/editor/export/editor_export_plugin.h +++ b/editor/export/editor_export_plugin.h @@ -34,6 +34,7 @@ #include "core/extension/native_extension.h" #include "editor_export_preset.h" #include "editor_export_shared_object.h" +#include "scene/main/node.h" class EditorExportPlugin : public RefCounted { GDCLASS(EditorExportPlugin, RefCounted); @@ -77,6 +78,7 @@ class EditorExportPlugin : public RefCounted { macos_plugin_files.clear(); } + // Export void _export_file_script(const String &p_path, const String &p_type, const Vector<String> &p_features); void _export_begin_script(const Vector<String> &p_features, bool p_debug, const String &p_path, int p_flags); void _export_end_script(); @@ -108,6 +110,31 @@ protected: GDVIRTUAL4(_export_begin, Vector<String>, bool, String, uint32_t) GDVIRTUAL0(_export_end) + GDVIRTUAL2RC(bool, _begin_customize_resources, const Ref<EditorExportPlatform> &, const Vector<String> &) + GDVIRTUAL2R(Ref<Resource>, _customize_resource, const Ref<Resource> &, String) + + GDVIRTUAL2RC(bool, _begin_customize_scenes, const Ref<EditorExportPlatform> &, const Vector<String> &) + GDVIRTUAL2R(Node *, _customize_scene, Node *, String) + GDVIRTUAL0RC(uint64_t, _get_customization_configuration_hash) + + GDVIRTUAL0(_end_customize_scenes) + GDVIRTUAL0(_end_customize_resources) + + GDVIRTUAL0RC(String, _get_name) + + bool _begin_customize_resources(const Ref<EditorExportPlatform> &p_platform, const Vector<String> &p_features) const; // Return true if this plugin does property export customization + Ref<Resource> _customize_resource(const Ref<Resource> &p_resource, const String &p_path); // If nothing is returned, it means do not touch (nothing changed). If something is returned (either the same or a different resource) it means changes are made. + + bool _begin_customize_scenes(const Ref<EditorExportPlatform> &p_platform, const Vector<String> &p_features) const; // Return true if this plugin does property export customization + Node *_customize_scene(Node *p_root, const String &p_path); // Return true if a change was made + + uint64_t _get_customization_configuration_hash() const; // Hash used for caching customized resources and scenes. + + void _end_customize_scenes(); + void _end_customize_resources(); + + virtual String _get_name() const; + public: Vector<String> get_ios_frameworks() const; Vector<String> get_ios_embedded_frameworks() const; @@ -121,12 +148,4 @@ public: EditorExportPlugin(); }; -class EditorExportTextSceneToBinaryPlugin : public EditorExportPlugin { - GDCLASS(EditorExportTextSceneToBinaryPlugin, EditorExportPlugin); - -public: - virtual void _export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features) override; - EditorExportTextSceneToBinaryPlugin(); -}; - #endif // EDITOR_EXPORT_PLUGIN_H diff --git a/editor/icons/BoxContainer.svg b/editor/icons/BoxContainer.svg new file mode 100644 index 0000000000..03b918d9cf --- /dev/null +++ b/editor/icons/BoxContainer.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1.4520481 6.9086748c-.60273897.602739-.60272261 1.5799281 0 2.1826507l5.4566267 5.4566265c.602739.602739 1.5799281.602723 2.1826507 0l5.4566265-5.4566265c.602739-.602739.602723-1.5799281 0-2.1826507l-5.4566265-5.4566265c-.602739-.60273904-1.5799281-.60272304-2.1826507 0zm1.0913253 1.0913253 1.0913254-1.0913253 5.4566267 5.4566262-1.0913253 1.091326zm2.1826507-2.1826498 1.0913254-1.091326 5.4566265 5.4566267-1.091326 1.091325zm2.1826507-2.182651 1.0913254-1.091325 5.4566258 5.4566258-1.091325 1.0913254z" fill="#8eef97" stroke-width=".771684"/></svg> diff --git a/editor/icons/FlowContainer.svg b/editor/icons/FlowContainer.svg new file mode 100644 index 0000000000..57699ce874 --- /dev/null +++ b/editor/icons/FlowContainer.svg @@ -0,0 +1 @@ +<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m1.4491431 6.9081906c-.59885747.5988575-.59885747 1.5847615 0 2.1836189l5.4590474 5.4590465c.5988576.598858 1.5847616.598858 2.183619.000001l5.4590465-5.4590475c.598858-.5988574.598858-1.5847614.000001-2.183619l-5.4590475-5.4590474c-.5988574-.59885747-1.5847614-.59885747-2.183619 0zm1.0918095 1.0918091 5.4590471-5.4590471 5.4590473 5.4590471-5.4590473 5.4590473zm1.6377142-.5459043c-.3024312.3024312-.3024312.7893781 0 1.0918092.3024313.3024311.7893783.3024311 1.0918095 0l1.0918095-1.0918093c.3024312-.3024312.3024312-.7893782 0-1.0918094-.3024312-.3024313-.7893782-.3024313-1.0918095 0zm2.7273401-2.7273401c-.3024312.3024311-.3024312.7893782 0 1.0918094.3024313.3024313.7893783.3024313 1.0918095 0l.5480882-.5480884c.3024311-.3024311.3024319-.7893783 0-1.0918094-.3024311-.3024313-.789378-.3024313-1.0918093 0zm-1.0896258 4.3650542c-.3024313.3024311-.3024313.7893779 0 1.0918095.3024312.302431.7893781.302431 1.0918094 0 .3024312-.3024316.3024313-.7893784 0-1.0918095-.3024311-.3024311-.7893781-.3024311-1.0918094 0zm1.6377142-1.6377142c-.3024313.3024313-.3024313.7893782 0 1.0918093s.7893782.3024311 1.0918093 0l1.6377144-1.637714c.302431-.3024312.302431-.7893783 0-1.0918096-.3024316-.3024312-.7893784-.3024311-1.0918095.0000002zm-.00218 3.2776127c-.3024312.302431-.3024313.789377-.0000001 1.091809.3024312.302431.7893782.302431 1.0918093 0l2.1858035-2.1858026c.302431-.3024311.302431-.7893787 0-1.0918098s-.7893792-.3024311-1.0918103 0z" fill="#8eef97" fill-rule="nonzero" stroke-width=".772026"/></svg> diff --git a/editor/icons/NavigationLink2D.svg b/editor/icons/NavigationLink2D.svg new file mode 100644 index 0000000000..6c5f17e256 --- /dev/null +++ b/editor/icons/NavigationLink2D.svg @@ -0,0 +1,4 @@ +<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> +<path d="m12.386 5.3097c-0.69157-0.021112-1.3071 0.36382-1.7492 0.86685-0.58 0.58-1.16 1.16-1.74 1.74 0.4588-0.28502 1.0599-0.064948 1.4771-0.037996 0.45549-0.44357 0.89024-0.91006 1.3596-1.3383 0.56256-0.44564 1.4906-0.15731 1.7028 0.52802 0.18967 0.4871-0.049221 1.0098-0.43284 1.3208-0.70048 0.68896-1.3789 1.4022-2.0935 2.0755-0.47999 0.3725-1.2044 0.226-1.5679-0.24034-0.38763-0.38194-1.0641 0.16031-0.78317 0.6241 0.6767 0.94379 2.1573 1.1282 3.0411 0.36751 0.80287-0.7704 1.5793-1.5696 2.3665-2.3564 0.79925-0.83719 0.70104-2.3112-0.19552-3.0393-0.38108-0.32877-0.8822-0.5119-1.385-0.51049zm-3.051 3.051c-0.69157-0.021106-1.3071 0.36382-1.7492 0.86685-0.67513 0.68452-1.37 1.3506-2.0319 2.0474-0.75433 0.87744-0.58087 2.3428 0.34933 3.0252 0.84748 0.68613 2.192 0.54839 2.8998-0.27341 0.63032-0.63031 1.2606-1.2606 1.8909-1.8909-0.4587 0.28554-1.0602 0.0659-1.477 0.038069-0.45445 0.44348-0.88773 0.91034-1.3564 1.3383-0.56256 0.44565-1.4906 0.15731-1.7028-0.52802-0.18967-0.4871 0.049229-1.0098 0.43284-1.3208 0.70048-0.68896 1.3789-1.4022 2.0935-2.0755 0.48-0.3725 1.2044-0.22601 1.5679 0.24036 0.38733 0.38325 1.064-0.16067 0.78313-0.6241-0.39353-0.52481-1.0429-0.84871-1.7002-0.8434z" fill="#8ea6f4" fill-opacity=".99608" stroke-linecap="round" stroke-linejoin="round" stroke-width=".013911"/> +<path d="m2 1c-0.61942-0.0066969-1.0877 0.60314-1 1.198 0.00345 3.968-0.006897 7.9364 0.00517 11.904 0.043388 0.62851 0.69346 0.98513 1.272 0.89776h2.5896c-0.77174-0.5015-1.2078-1.2613-1.3143-2.3356-0.11601-1.1701 0.63729-2.024 1.6748-3.1566 0.65335-0.71326 1.4757-1.5822 2.3587-2.3316 0.76308-0.64765 1.7509-1.679 2.9376-2.578 0.91259-0.69136 2.2893-0.74691 3.1014-0.33143 0.91184 0.46649 1.2635 1.1209 1.4067 1.3826-0.0052-2.335-0.02135-1.3526-0.03955-3.6863 5e-3 -0.64349-0.67497-1.0568-1.2694-0.96289z" fill="#8ea6f4" fill-opacity=".99608"/> +</svg> diff --git a/editor/icons/NavigationLink3D.svg b/editor/icons/NavigationLink3D.svg new file mode 100644 index 0000000000..ea4092c2c7 --- /dev/null +++ b/editor/icons/NavigationLink3D.svg @@ -0,0 +1,4 @@ +<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> +<path d="m12.386 5.3097c-0.69157-0.021112-1.3071 0.36382-1.7492 0.86685-0.58 0.58-1.16 1.16-1.74 1.74 0.4588-0.28502 1.0599-0.064948 1.4771-0.037996 0.45549-0.44357 0.89024-0.91006 1.3596-1.3383 0.56256-0.44564 1.4906-0.15731 1.7028 0.52802 0.18967 0.4871-0.049221 1.0098-0.43284 1.3208-0.70048 0.68896-1.3789 1.4022-2.0935 2.0755-0.47999 0.3725-1.2044 0.226-1.5679-0.24034-0.38763-0.38194-1.0641 0.16031-0.78317 0.6241 0.6767 0.94379 2.1573 1.1282 3.0411 0.36751 0.80287-0.7704 1.5793-1.5696 2.3665-2.3564 0.79925-0.83719 0.70104-2.3112-0.19552-3.0393-0.38108-0.32877-0.8822-0.5119-1.385-0.51049zm-3.051 3.051c-0.69157-0.021106-1.3071 0.36382-1.7492 0.86685-0.67513 0.68452-1.37 1.3506-2.0319 2.0474-0.75433 0.87744-0.58087 2.3428 0.34933 3.0252 0.84748 0.68613 2.192 0.54839 2.8998-0.27341 0.63032-0.63031 1.2606-1.2606 1.8909-1.8909-0.4587 0.28554-1.0602 0.0659-1.477 0.038069-0.45445 0.44348-0.88773 0.91034-1.3564 1.3383-0.56256 0.44565-1.4906 0.15731-1.7028-0.52802-0.18967-0.4871 0.049229-1.0098 0.43284-1.3208 0.70048-0.68896 1.3789-1.4022 2.0935-2.0755 0.48-0.3725 1.2044-0.22601 1.5679 0.24036 0.38733 0.38325 1.064-0.16067 0.78313-0.6241-0.39353-0.52481-1.0429-0.84871-1.7002-0.8434z" fill="#fc7e7e" fill-opacity=".99608" stroke-linecap="round" stroke-linejoin="round" stroke-width=".013911"/> +<path d="m2 1c-0.61942-0.0066969-1.0877 0.60314-1 1.198 0.00345 3.968-0.006897 7.9364 0.00517 11.904 0.043388 0.62851 0.69346 0.98513 1.272 0.89776h2.5896c-0.77174-0.5015-1.2078-1.2613-1.3143-2.3356-0.11601-1.1701 0.63729-2.024 1.6748-3.1566 0.65335-0.71326 1.4757-1.5822 2.3587-2.3316 0.76308-0.64765 1.7509-1.679 2.9376-2.578 0.91259-0.69136 2.2893-0.74691 3.1014-0.33143 0.91184 0.46649 1.2635 1.1209 1.4067 1.3826-0.0052-2.335-0.02135-1.3526-0.03955-3.6863 5e-3 -0.64349-0.67497-1.0568-1.2694-0.96289z" fill="#fc7d7d" fill-opacity=".99608"/> +</svg> diff --git a/editor/icons/SplitContainer.svg b/editor/icons/SplitContainer.svg new file mode 100644 index 0000000000..bb03350166 --- /dev/null +++ b/editor/icons/SplitContainer.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1.452048 6.9086746c-.60273888.6027391-.60272252 1.5799284 0 2.1826511l5.4566266 5.4566263c.6027391.602739 1.5799284.602722 2.1826511 0l5.4566263-5.4566263c.602739-.6027397.602722-1.5799284 0-2.1826511l-5.4566263-5.4566266c-.6027397-.60273888-1.5799284-.60272252-2.1826511 0zm1.0913254 1.0913254 2.1826506-2.1826506 1.636988 1.6369879v2.1826504h2.1826508l1.6369882 1.6369883-2.182651 2.182651zm3.273976-3.273976 2.1826506-2.1826506 5.456627 5.4566266-2.182651 2.182651-1.6369883-1.6369882v-2.1826508h-2.1826504z" fill="#8eef97" stroke-width=".771683"/></svg> diff --git a/editor/import/editor_import_plugin.cpp b/editor/import/editor_import_plugin.cpp index 3305f241c0..5211f003c1 100644 --- a/editor/import/editor_import_plugin.cpp +++ b/editor/import/editor_import_plugin.cpp @@ -164,7 +164,7 @@ bool EditorImportPlugin::get_option_visibility(const String &p_path, const Strin Error EditorImportPlugin::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { Dictionary options; - Array platform_variants, gen_files; + TypedArray<String> platform_variants, gen_files; HashMap<StringName, Variant>::ConstIterator E = p_options.begin(); while (E) { diff --git a/editor/import/editor_import_plugin.h b/editor/import/editor_import_plugin.h index e9749c240f..1468ed082b 100644 --- a/editor/import/editor_import_plugin.h +++ b/editor/import/editor_import_plugin.h @@ -51,7 +51,7 @@ protected: GDVIRTUAL0RC(float, _get_priority) GDVIRTUAL0RC(int, _get_import_order) GDVIRTUAL3RC(bool, _get_option_visibility, String, StringName, Dictionary) - GDVIRTUAL5RC(int, _import, String, String, Dictionary, Array, Array) + GDVIRTUAL5RC(int, _import, String, String, Dictionary, TypedArray<String>, TypedArray<String>) public: EditorImportPlugin(); diff --git a/editor/import/resource_importer_bitmask.cpp b/editor/import/resource_importer_bitmask.cpp index c03962b8a4..577a4c32b3 100644 --- a/editor/import/resource_importer_bitmask.cpp +++ b/editor/import/resource_importer_bitmask.cpp @@ -99,7 +99,7 @@ Error ResourceImporterBitMap::import(const String &p_source_file, const String & bit = c.a > threshold; } - bitmap->set_bit(Vector2(j, i), bit); + bitmap->set_bit(j, i, bit); } } diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index 1ab60e8fc8..5ac63ce4db 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -1524,19 +1524,19 @@ void AnimationPlayerEditor::_prepare_onion_layers_2() { // Render every past/future step with the capture shader. RS::get_singleton()->canvas_item_set_material(onion.capture.canvas_item, onion.capture.material->get_rid()); - onion.capture.material->set_shader_uniform("bkg_color", GLOBAL_GET("rendering/environment/defaults/default_clear_color")); - onion.capture.material->set_shader_uniform("differences_only", onion.differences_only); - onion.capture.material->set_shader_uniform("present", onion.differences_only ? RS::get_singleton()->viewport_get_texture(present_rid) : RID()); + onion.capture.material->set_shader_parameter("bkg_color", GLOBAL_GET("rendering/environment/defaults/default_clear_color")); + onion.capture.material->set_shader_parameter("differences_only", onion.differences_only); + onion.capture.material->set_shader_parameter("present", onion.differences_only ? RS::get_singleton()->viewport_get_texture(present_rid) : RID()); int step_off_a = onion.past ? -onion.steps : 0; int step_off_b = onion.future ? onion.steps : 0; int cidx = 0; - onion.capture.material->set_shader_uniform("dir_color", onion.force_white_modulate ? Color(1, 1, 1) : Color(EDITOR_GET("editors/animation/onion_layers_past_color"))); + onion.capture.material->set_shader_parameter("dir_color", onion.force_white_modulate ? Color(1, 1, 1) : Color(EDITOR_GET("editors/animation/onion_layers_past_color"))); for (int step_off = step_off_a; step_off <= step_off_b; step_off++) { if (step_off == 0) { // Skip present step and switch to the color of future. if (!onion.force_white_modulate) { - onion.capture.material->set_shader_uniform("dir_color", EDITOR_GET("editors/animation/onion_layers_future_color")); + onion.capture.material->set_shader_parameter("dir_color", EDITOR_GET("editors/animation/onion_layers_future_color")); } continue; } diff --git a/editor/plugins/bone_map_editor_plugin.cpp b/editor/plugins/bone_map_editor_plugin.cpp index 988f9cc394..46e2fe41af 100644 --- a/editor/plugins/bone_map_editor_plugin.cpp +++ b/editor/plugins/bone_map_editor_plugin.cpp @@ -681,7 +681,7 @@ void BoneMapper::auto_mapping_process(Ref<BoneMap> &p_bone_map) { } if (!found) { for (int i = 0; i < search_path.size(); i++) { - if (Vector3(0, 0, 0).is_equal_approx(skeleton->get_bone_global_rest(search_path[i]).origin)) { + if (skeleton->get_bone_global_rest(search_path[i]).origin.is_zero_approx()) { bone_idx = search_path[i]; // The bone existing at the origin is appropriate as a root. found = true; break; diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index 369ab0745e..0ec36736bd 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -201,7 +201,7 @@ Ref<Texture2D> EditorBitmapPreviewPlugin::generate(const Ref<Resource> &p_from, for (int i = 0; i < bm->get_size().width; i++) { for (int j = 0; j < bm->get_size().height; j++) { - if (bm->get_bit(Point2i(i, j))) { + if (bm->get_bit(i, j)) { w[j * (int)bm->get_size().width + i] = 255; } else { w[j * (int)bm->get_size().width + i] = 0; diff --git a/editor/plugins/gdextension_export_plugin.h b/editor/plugins/gdextension_export_plugin.h index b5eca46ad3..e1d68d97b5 100644 --- a/editor/plugins/gdextension_export_plugin.h +++ b/editor/plugins/gdextension_export_plugin.h @@ -36,6 +36,7 @@ class GDExtensionExportPlugin : public EditorExportPlugin { protected: virtual void _export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features); + virtual String _get_name() const { return "GDExtension"; } }; void GDExtensionExportPlugin::_export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features) { diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp index d204873f92..76d05624d6 100644 --- a/editor/plugins/material_editor_plugin.cpp +++ b/editor/plugins/material_editor_plugin.cpp @@ -40,33 +40,39 @@ #include "scene/resources/particle_process_material.h" #include "scene/resources/sky_material.h" -void MaterialEditor::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_READY: { - //get_scene()->connect("node_removed",this,"_node_removed"); +void MaterialEditor::_update_theme_item_cache() { + Control::_update_theme_item_cache(); - if (first_enter) { - //it's in propertyeditor so.. could be moved around + theme_cache.light_1_on = get_theme_icon(SNAME("MaterialPreviewLight1"), SNAME("EditorIcons")); + theme_cache.light_1_off = get_theme_icon(SNAME("MaterialPreviewLight1Off"), SNAME("EditorIcons")); + theme_cache.light_2_on = get_theme_icon(SNAME("MaterialPreviewLight2"), SNAME("EditorIcons")); + theme_cache.light_2_off = get_theme_icon(SNAME("MaterialPreviewLight2Off"), SNAME("EditorIcons")); - light_1_switch->set_normal_texture(get_theme_icon(SNAME("MaterialPreviewLight1"), SNAME("EditorIcons"))); - light_1_switch->set_pressed_texture(get_theme_icon(SNAME("MaterialPreviewLight1Off"), SNAME("EditorIcons"))); - light_2_switch->set_normal_texture(get_theme_icon(SNAME("MaterialPreviewLight2"), SNAME("EditorIcons"))); - light_2_switch->set_pressed_texture(get_theme_icon(SNAME("MaterialPreviewLight2Off"), SNAME("EditorIcons"))); + theme_cache.sphere_on = get_theme_icon(SNAME("MaterialPreviewSphere"), SNAME("EditorIcons")); + theme_cache.sphere_off = get_theme_icon(SNAME("MaterialPreviewSphereOff"), SNAME("EditorIcons")); + theme_cache.box_on = get_theme_icon(SNAME("MaterialPreviewCube"), SNAME("EditorIcons")); + theme_cache.box_off = get_theme_icon(SNAME("MaterialPreviewCubeOff"), SNAME("EditorIcons")); - sphere_switch->set_normal_texture(get_theme_icon(SNAME("MaterialPreviewSphereOff"), SNAME("EditorIcons"))); - sphere_switch->set_pressed_texture(get_theme_icon(SNAME("MaterialPreviewSphere"), SNAME("EditorIcons"))); - box_switch->set_normal_texture(get_theme_icon(SNAME("MaterialPreviewCubeOff"), SNAME("EditorIcons"))); - box_switch->set_pressed_texture(get_theme_icon(SNAME("MaterialPreviewCube"), SNAME("EditorIcons"))); + theme_cache.checkerboard = get_theme_icon(SNAME("Checkerboard"), SNAME("EditorIcons")); +} - first_enter = false; - } +void MaterialEditor::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_THEME_CHANGED: { + light_1_switch->set_normal_texture(theme_cache.light_1_on); + light_1_switch->set_pressed_texture(theme_cache.light_1_off); + light_2_switch->set_normal_texture(theme_cache.light_2_on); + light_2_switch->set_pressed_texture(theme_cache.light_2_off); + + sphere_switch->set_normal_texture(theme_cache.sphere_off); + sphere_switch->set_pressed_texture(theme_cache.sphere_on); + box_switch->set_normal_texture(theme_cache.box_off); + box_switch->set_pressed_texture(theme_cache.box_on); } break; case NOTIFICATION_DRAW: { - Ref<Texture2D> checkerboard = get_theme_icon(SNAME("Checkerboard"), SNAME("EditorIcons")); Size2 size = get_size(); - - draw_texture_rect(checkerboard, Rect2(Point2(), size), true); + draw_texture_rect(theme_cache.checkerboard, Rect2(Point2(), size), true); } break; } } @@ -231,8 +237,6 @@ MaterialEditor::MaterialEditor() { vb_light->add_child(light_2_switch); light_2_switch->connect("pressed", callable_mp(this, &MaterialEditor::_button_pressed).bind(light_2_switch)); - first_enter = true; - if (EditorSettings::get_singleton()->get_project_metadata("inspector_options", "material_preview_on_sphere", true)) { box_instance->hide(); } else { @@ -344,17 +348,17 @@ Ref<Resource> StandardMaterial3DConversionPlugin::convert(const Ref<Resource> &p smat->set_shader(shader); List<PropertyInfo> params; - RS::get_singleton()->shader_get_shader_uniform_list(mat->get_shader_rid(), ¶ms); + RS::get_singleton()->get_shader_parameter_list(mat->get_shader_rid(), ¶ms); for (const PropertyInfo &E : params) { // Texture parameter has to be treated specially since StandardMaterial3D saved it // as RID but ShaderMaterial needs Texture itself Ref<Texture2D> texture = mat->get_texture_by_name(E.name); if (texture.is_valid()) { - smat->set_shader_uniform(E.name, texture); + smat->set_shader_parameter(E.name, texture); } else { Variant value = RS::get_singleton()->material_get_param(mat->get_rid(), E.name); - smat->set_shader_uniform(E.name, value); + smat->set_shader_parameter(E.name, value); } } @@ -390,17 +394,17 @@ Ref<Resource> ORMMaterial3DConversionPlugin::convert(const Ref<Resource> &p_reso smat->set_shader(shader); List<PropertyInfo> params; - RS::get_singleton()->shader_get_shader_uniform_list(mat->get_shader_rid(), ¶ms); + RS::get_singleton()->get_shader_parameter_list(mat->get_shader_rid(), ¶ms); for (const PropertyInfo &E : params) { // Texture parameter has to be treated specially since ORMMaterial3D saved it // as RID but ShaderMaterial needs Texture itself Ref<Texture2D> texture = mat->get_texture_by_name(E.name); if (texture.is_valid()) { - smat->set_shader_uniform(E.name, texture); + smat->set_shader_parameter(E.name, texture); } else { Variant value = RS::get_singleton()->material_get_param(mat->get_rid(), E.name); - smat->set_shader_uniform(E.name, value); + smat->set_shader_parameter(E.name, value); } } @@ -436,11 +440,11 @@ Ref<Resource> ParticleProcessMaterialConversionPlugin::convert(const Ref<Resourc smat->set_shader(shader); List<PropertyInfo> params; - RS::get_singleton()->shader_get_shader_uniform_list(mat->get_shader_rid(), ¶ms); + RS::get_singleton()->get_shader_parameter_list(mat->get_shader_rid(), ¶ms); for (const PropertyInfo &E : params) { Variant value = RS::get_singleton()->material_get_param(mat->get_rid(), E.name); - smat->set_shader_uniform(E.name, value); + smat->set_shader_parameter(E.name, value); } smat->set_render_priority(mat->get_render_priority()); @@ -475,11 +479,11 @@ Ref<Resource> CanvasItemMaterialConversionPlugin::convert(const Ref<Resource> &p smat->set_shader(shader); List<PropertyInfo> params; - RS::get_singleton()->shader_get_shader_uniform_list(mat->get_shader_rid(), ¶ms); + RS::get_singleton()->get_shader_parameter_list(mat->get_shader_rid(), ¶ms); for (const PropertyInfo &E : params) { Variant value = RS::get_singleton()->material_get_param(mat->get_rid(), E.name); - smat->set_shader_uniform(E.name, value); + smat->set_shader_parameter(E.name, value); } smat->set_render_priority(mat->get_render_priority()); @@ -514,11 +518,11 @@ Ref<Resource> ProceduralSkyMaterialConversionPlugin::convert(const Ref<Resource> smat->set_shader(shader); List<PropertyInfo> params; - RS::get_singleton()->shader_get_shader_uniform_list(mat->get_shader_rid(), ¶ms); + RS::get_singleton()->get_shader_parameter_list(mat->get_shader_rid(), ¶ms); for (const PropertyInfo &E : params) { Variant value = RS::get_singleton()->material_get_param(mat->get_rid(), E.name); - smat->set_shader_uniform(E.name, value); + smat->set_shader_parameter(E.name, value); } smat->set_render_priority(mat->get_render_priority()); @@ -553,11 +557,11 @@ Ref<Resource> PanoramaSkyMaterialConversionPlugin::convert(const Ref<Resource> & smat->set_shader(shader); List<PropertyInfo> params; - RS::get_singleton()->shader_get_shader_uniform_list(mat->get_shader_rid(), ¶ms); + RS::get_singleton()->get_shader_parameter_list(mat->get_shader_rid(), ¶ms); for (const PropertyInfo &E : params) { Variant value = RS::get_singleton()->material_get_param(mat->get_rid(), E.name); - smat->set_shader_uniform(E.name, value); + smat->set_shader_parameter(E.name, value); } smat->set_render_priority(mat->get_render_priority()); @@ -592,11 +596,11 @@ Ref<Resource> PhysicalSkyMaterialConversionPlugin::convert(const Ref<Resource> & smat->set_shader(shader); List<PropertyInfo> params; - RS::get_singleton()->shader_get_shader_uniform_list(mat->get_shader_rid(), ¶ms); + RS::get_singleton()->get_shader_parameter_list(mat->get_shader_rid(), ¶ms); for (const PropertyInfo &E : params) { Variant value = RS::get_singleton()->material_get_param(mat->get_rid(), E.name); - smat->set_shader_uniform(E.name, value); + smat->set_shader_parameter(E.name, value); } smat->set_render_priority(mat->get_render_priority()); @@ -631,11 +635,11 @@ Ref<Resource> FogMaterialConversionPlugin::convert(const Ref<Resource> &p_resour smat->set_shader(shader); List<PropertyInfo> params; - RS::get_singleton()->shader_get_shader_uniform_list(mat->get_shader_rid(), ¶ms); + RS::get_singleton()->get_shader_parameter_list(mat->get_shader_rid(), ¶ms); for (const PropertyInfo &E : params) { Variant value = RS::get_singleton()->material_get_param(mat->get_rid(), E.name); - smat->set_shader_uniform(E.name, value); + smat->set_shader_parameter(E.name, value); } smat->set_render_priority(mat->get_render_priority()); diff --git a/editor/plugins/material_editor_plugin.h b/editor/plugins/material_editor_plugin.h index 828dd9f972..7ce6deee65 100644 --- a/editor/plugins/material_editor_plugin.h +++ b/editor/plugins/material_editor_plugin.h @@ -70,12 +70,23 @@ class MaterialEditor : public Control { Ref<Material> material; + struct ThemeCache { + Ref<Texture2D> light_1_on; + Ref<Texture2D> light_1_off; + Ref<Texture2D> light_2_on; + Ref<Texture2D> light_2_off; + Ref<Texture2D> sphere_on; + Ref<Texture2D> sphere_off; + Ref<Texture2D> box_on; + Ref<Texture2D> box_off; + Ref<Texture2D> checkerboard; + } theme_cache; + void _button_pressed(Node *p_button); - bool first_enter; protected: + virtual void _update_theme_item_cache() override; void _notification(int p_what); - static void _bind_methods(); public: diff --git a/editor/plugins/mesh_editor_plugin.cpp b/editor/plugins/mesh_editor_plugin.cpp index d8977ea6fc..be26baaea5 100644 --- a/editor/plugins/mesh_editor_plugin.cpp +++ b/editor/plugins/mesh_editor_plugin.cpp @@ -49,20 +49,22 @@ void MeshEditor::gui_input(const Ref<InputEvent> &p_event) { } } +void MeshEditor::_update_theme_item_cache() { + SubViewportContainer::_update_theme_item_cache(); + + theme_cache.light_1_on = get_theme_icon(SNAME("MaterialPreviewLight1"), SNAME("EditorIcons")); + theme_cache.light_1_off = get_theme_icon(SNAME("MaterialPreviewLight1Off"), SNAME("EditorIcons")); + theme_cache.light_2_on = get_theme_icon(SNAME("MaterialPreviewLight2"), SNAME("EditorIcons")); + theme_cache.light_2_off = get_theme_icon(SNAME("MaterialPreviewLight2Off"), SNAME("EditorIcons")); +} + void MeshEditor::_notification(int p_what) { switch (p_what) { - case NOTIFICATION_READY: { - //get_scene()->connect("node_removed",this,"_node_removed"); - - if (first_enter) { - //it's in propertyeditor so. could be moved around - - light_1_switch->set_normal_texture(get_theme_icon(SNAME("MaterialPreviewLight1"), SNAME("EditorIcons"))); - light_1_switch->set_pressed_texture(get_theme_icon(SNAME("MaterialPreviewLight1Off"), SNAME("EditorIcons"))); - light_2_switch->set_normal_texture(get_theme_icon(SNAME("MaterialPreviewLight2"), SNAME("EditorIcons"))); - light_2_switch->set_pressed_texture(get_theme_icon(SNAME("MaterialPreviewLight2Off"), SNAME("EditorIcons"))); - first_enter = false; - } + case NOTIFICATION_THEME_CHANGED: { + light_1_switch->set_normal_texture(theme_cache.light_1_on); + light_1_switch->set_pressed_texture(theme_cache.light_1_off); + light_2_switch->set_normal_texture(theme_cache.light_2_on); + light_2_switch->set_pressed_texture(theme_cache.light_2_off); } break; } } @@ -160,8 +162,6 @@ MeshEditor::MeshEditor() { vb_light->add_child(light_2_switch); light_2_switch->connect("pressed", callable_mp(this, &MeshEditor::_button_pressed).bind(light_2_switch)); - first_enter = true; - rot_x = 0; rot_y = 0; } diff --git a/editor/plugins/mesh_editor_plugin.h b/editor/plugins/mesh_editor_plugin.h index ab7b5db7c4..6394cb1171 100644 --- a/editor/plugins/mesh_editor_plugin.h +++ b/editor/plugins/mesh_editor_plugin.h @@ -58,12 +58,18 @@ class MeshEditor : public SubViewportContainer { TextureButton *light_1_switch = nullptr; TextureButton *light_2_switch = nullptr; - void _button_pressed(Node *p_button); - bool first_enter; + struct ThemeCache { + Ref<Texture2D> light_1_on; + Ref<Texture2D> light_1_off; + Ref<Texture2D> light_2_on; + Ref<Texture2D> light_2_off; + } theme_cache; + void _button_pressed(Node *p_button); void _update_rotation(); protected: + virtual void _update_theme_item_cache() override; void _notification(int p_what); void gui_input(const Ref<InputEvent> &p_event) override; diff --git a/editor/plugins/navigation_link_2d_editor_plugin.cpp b/editor/plugins/navigation_link_2d_editor_plugin.cpp new file mode 100644 index 0000000000..b72f639fbf --- /dev/null +++ b/editor/plugins/navigation_link_2d_editor_plugin.cpp @@ -0,0 +1,191 @@ +/*************************************************************************/ +/* navigation_link_2d_editor_plugin.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "navigation_link_2d_editor_plugin.h" + +#include "canvas_item_editor_plugin.h" +#include "editor/editor_node.h" +#include "editor/editor_settings.h" +#include "editor/editor_undo_redo_manager.h" +#include "servers/navigation_server_3d.h" + +void NavigationLink2DEditor::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: { + get_tree()->connect("node_removed", callable_mp(this, &NavigationLink2DEditor::_node_removed)); + } break; + + case NOTIFICATION_EXIT_TREE: { + get_tree()->disconnect("node_removed", callable_mp(this, &NavigationLink2DEditor::_node_removed)); + } break; + } +} + +void NavigationLink2DEditor::_node_removed(Node *p_node) { + if (p_node == node) { + node = nullptr; + } +} + +bool NavigationLink2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_event) { + if (!node || !node->is_visible_in_tree()) { + return false; + } + + real_t grab_threshold = EDITOR_GET("editors/polygon_editor/point_grab_radius"); + Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); + + Ref<InputEventMouseButton> mb = p_event; + if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT) { + if (mb->is_pressed()) { + // Start location + if (xform.xform(node->get_start_location()).distance_to(mb->get_position()) < grab_threshold) { + start_grabbed = true; + original_start_location = node->get_start_location(); + + return true; + } else { + start_grabbed = false; + } + + // End location + if (xform.xform(node->get_end_location()).distance_to(mb->get_position()) < grab_threshold) { + end_grabbed = true; + original_end_location = node->get_end_location(); + + return true; + } else { + end_grabbed = false; + } + } else { + if (start_grabbed) { + undo_redo->create_action(TTR("Set start_location")); + undo_redo->add_do_method(node, "set_start_location", node->get_start_location()); + undo_redo->add_do_method(canvas_item_editor, "update_viewport"); + undo_redo->add_undo_method(node, "set_start_location", original_start_location); + undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); + undo_redo->commit_action(); + + start_grabbed = false; + + return true; + } + + if (end_grabbed) { + undo_redo->create_action(TTR("Set end_location")); + undo_redo->add_do_method(node, "set_end_location", node->get_end_location()); + undo_redo->add_do_method(canvas_item_editor, "update_viewport"); + undo_redo->add_undo_method(node, "set_end_location", original_end_location); + undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); + undo_redo->commit_action(); + + end_grabbed = false; + + return true; + } + } + } + + Ref<InputEventMouseMotion> mm = p_event; + if (mm.is_valid()) { + Vector2 point = canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(mm->get_position())); + point = node->get_global_transform().affine_inverse().xform(point); + + if (start_grabbed) { + node->set_start_location(point); + canvas_item_editor->update_viewport(); + + return true; + } + + if (end_grabbed) { + node->set_end_location(point); + canvas_item_editor->update_viewport(); + + return true; + } + } + + return false; +} + +void NavigationLink2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) { + if (!node || !node->is_visible_in_tree()) { + return; + } + + Transform2D gt = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); + Vector2 global_start_location = gt.xform(node->get_start_location()); + Vector2 global_end_location = gt.xform(node->get_end_location()); + + // Only drawing the handles here, since the debug rendering will fill in the rest. + const Ref<Texture2D> handle = get_theme_icon(SNAME("EditorHandle"), SNAME("EditorIcons")); + p_overlay->draw_texture(handle, global_start_location - handle->get_size() / 2); + p_overlay->draw_texture(handle, global_end_location - handle->get_size() / 2); +} + +void NavigationLink2DEditor::edit(NavigationLink2D *p_node) { + if (!canvas_item_editor) { + canvas_item_editor = CanvasItemEditor::get_singleton(); + } + + if (p_node) { + node = p_node; + } else { + node = nullptr; + } + + canvas_item_editor->update_viewport(); +} + +NavigationLink2DEditor::NavigationLink2DEditor() { + undo_redo = EditorNode::get_undo_redo(); +} + +/////////////////////// + +void NavigationLink2DEditorPlugin::edit(Object *p_object) { + editor->edit(Object::cast_to<NavigationLink2D>(p_object)); +} + +bool NavigationLink2DEditorPlugin::handles(Object *p_object) const { + return Object::cast_to<NavigationLink2D>(p_object) != nullptr; +} + +void NavigationLink2DEditorPlugin::make_visible(bool p_visible) { + if (!p_visible) { + edit(nullptr); + } +} + +NavigationLink2DEditorPlugin::NavigationLink2DEditorPlugin() { + editor = memnew(NavigationLink2DEditor); + EditorNode::get_singleton()->get_gui_base()->add_child(editor); +} diff --git a/editor/plugins/navigation_link_2d_editor_plugin.h b/editor/plugins/navigation_link_2d_editor_plugin.h new file mode 100644 index 0000000000..1c1251bec7 --- /dev/null +++ b/editor/plugins/navigation_link_2d_editor_plugin.h @@ -0,0 +1,83 @@ +/*************************************************************************/ +/* navigation_link_2d_editor_plugin.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef NAVIGATION_LINK_2D_EDITOR_PLUGIN_H +#define NAVIGATION_LINK_2D_EDITOR_PLUGIN_H + +#include "editor/editor_plugin.h" +#include "scene/2d/navigation_link_2d.h" + +class CanvasItemEditor; +class EditorUndoRedoManager; + +class NavigationLink2DEditor : public Control { + GDCLASS(NavigationLink2DEditor, Control); + + Ref<EditorUndoRedoManager> undo_redo; + CanvasItemEditor *canvas_item_editor = nullptr; + NavigationLink2D *node; + + bool start_grabbed = false; + Vector2 original_start_location; + + bool end_grabbed = false; + Vector2 original_end_location; + +protected: + void _notification(int p_what); + void _node_removed(Node *p_node); + +public: + bool forward_canvas_gui_input(const Ref<InputEvent> &p_event); + void forward_canvas_draw_over_viewport(Control *p_overlay); + void edit(NavigationLink2D *p_node); + + NavigationLink2DEditor(); +}; + +class NavigationLink2DEditorPlugin : public EditorPlugin { + GDCLASS(NavigationLink2DEditorPlugin, EditorPlugin); + + NavigationLink2DEditor *editor = nullptr; + +public: + virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) override { return editor->forward_canvas_gui_input(p_event); } + virtual void forward_canvas_draw_over_viewport(Control *p_overlay) override { editor->forward_canvas_draw_over_viewport(p_overlay); } + + virtual String get_name() const override { return "NavigationLink2D"; } + bool has_main_screen() const override { return false; } + virtual void edit(Object *p_object) override; + virtual bool handles(Object *p_object) const override; + virtual void make_visible(bool p_visible) override; + + NavigationLink2DEditorPlugin(); +}; + +#endif // NAVIGATION_LINK_2D_EDITOR_PLUGIN_H diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp index 0c27ed46c5..ec6ea7f39b 100644 --- a/editor/plugins/node_3d_editor_gizmos.cpp +++ b/editor/plugins/node_3d_editor_gizmos.cpp @@ -54,6 +54,7 @@ #include "scene/3d/lightmap_probe.h" #include "scene/3d/marker_3d.h" #include "scene/3d/mesh_instance_3d.h" +#include "scene/3d/navigation_link_3d.h" #include "scene/3d/navigation_region_3d.h" #include "scene/3d/occluder_instance_3d.h" #include "scene/3d/ray_cast_3d.h" @@ -4999,6 +5000,175 @@ void NavigationRegion3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { } } +//// + +NavigationLink3DGizmoPlugin::NavigationLink3DGizmoPlugin() { + create_material("navigation_link_material", NavigationServer3D::get_singleton()->get_debug_navigation_link_connection_color()); + create_material("navigation_link_material_disabled", NavigationServer3D::get_singleton()->get_debug_navigation_link_connection_disabled_color()); + create_handle_material("handles"); +} + +bool NavigationLink3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { + return Object::cast_to<NavigationLink3D>(p_spatial) != nullptr; +} + +String NavigationLink3DGizmoPlugin::get_gizmo_name() const { + return "NavigationLink3D"; +} + +int NavigationLink3DGizmoPlugin::get_priority() const { + return -1; +} + +void NavigationLink3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { + NavigationLink3D *link = Object::cast_to<NavigationLink3D>(p_gizmo->get_spatial_node()); + + RID nav_map = link->get_world_3d()->get_navigation_map(); + real_t search_radius = NavigationServer3D::get_singleton()->map_get_link_connection_radius(nav_map); + Vector3 up_vector = NavigationServer3D::get_singleton()->map_get_up(nav_map); + Vector3::Axis up_axis = up_vector.max_axis_index(); + + Vector3 start_location = link->get_start_location(); + Vector3 end_location = link->get_end_location(); + + Ref<Material> link_material = get_material("navigation_link_material", p_gizmo); + Ref<Material> link_material_disabled = get_material("navigation_link_material_disabled", p_gizmo); + Ref<Material> handles_material = get_material("handles"); + + p_gizmo->clear(); + + // Draw line between the points. + Vector<Vector3> lines; + lines.append(start_location); + lines.append(end_location); + + // Draw start location search radius + for (int i = 0; i < 30; i++) { + // Create a circle + const float ra = Math::deg_to_rad((float)(i * 12)); + const float rb = Math::deg_to_rad((float)((i + 1) * 12)); + const Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * search_radius; + const Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * search_radius; + + // Draw axis-aligned circle + switch (up_axis) { + case Vector3::AXIS_X: + lines.append(start_location + Vector3(0, a.x, a.y)); + lines.append(start_location + Vector3(0, b.x, b.y)); + break; + case Vector3::AXIS_Y: + lines.append(start_location + Vector3(a.x, 0, a.y)); + lines.append(start_location + Vector3(b.x, 0, b.y)); + break; + case Vector3::AXIS_Z: + lines.append(start_location + Vector3(a.x, a.y, 0)); + lines.append(start_location + Vector3(b.x, b.y, 0)); + break; + } + } + + // Draw end location search radius + for (int i = 0; i < 30; i++) { + // Create a circle + const float ra = Math::deg_to_rad((float)(i * 12)); + const float rb = Math::deg_to_rad((float)((i + 1) * 12)); + const Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * search_radius; + const Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * search_radius; + + // Draw axis-aligned circle + switch (up_axis) { + case Vector3::AXIS_X: + lines.append(end_location + Vector3(0, a.x, a.y)); + lines.append(end_location + Vector3(0, b.x, b.y)); + break; + case Vector3::AXIS_Y: + lines.append(end_location + Vector3(a.x, 0, a.y)); + lines.append(end_location + Vector3(b.x, 0, b.y)); + break; + case Vector3::AXIS_Z: + lines.append(end_location + Vector3(a.x, a.y, 0)); + lines.append(end_location + Vector3(b.x, b.y, 0)); + break; + } + } + + p_gizmo->add_lines(lines, link->is_enabled() ? link_material : link_material_disabled); + p_gizmo->add_collision_segments(lines); + + Vector<Vector3> handles; + handles.append(start_location); + handles.append(end_location); + p_gizmo->add_handles(handles, handles_material); +} + +String NavigationLink3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { + return p_id == 0 ? TTR("Start Location") : TTR("End Location"); +} + +Variant NavigationLink3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { + NavigationLink3D *link = Object::cast_to<NavigationLink3D>(p_gizmo->get_spatial_node()); + return p_id == 0 ? link->get_start_location() : link->get_end_location(); +} + +void NavigationLink3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { + NavigationLink3D *link = Object::cast_to<NavigationLink3D>(p_gizmo->get_spatial_node()); + + Transform3D gt = link->get_global_transform(); + Transform3D gi = gt.affine_inverse(); + + Transform3D ct = p_camera->get_global_transform(); + Vector3 cam_dir = ct.basis.get_column(Vector3::AXIS_Z); + + Vector3 ray_from = p_camera->project_ray_origin(p_point); + Vector3 ray_dir = p_camera->project_ray_normal(p_point); + + Vector3 location = p_id == 0 ? link->get_start_location() : link->get_end_location(); + Plane move_plane = Plane(cam_dir, gt.xform(location)); + + Vector3 intersection; + if (!move_plane.intersects_ray(ray_from, ray_dir, &intersection)) { + return; + } + + if (Node3DEditor::get_singleton()->is_snap_enabled()) { + double snap = Node3DEditor::get_singleton()->get_translate_snap(); + intersection.snap(Vector3(snap, snap, snap)); + } + + location = gi.xform(intersection); + if (p_id == 0) { + link->set_start_location(location); + } else if (p_id == 1) { + link->set_end_location(location); + } +} + +void NavigationLink3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { + NavigationLink3D *link = Object::cast_to<NavigationLink3D>(p_gizmo->get_spatial_node()); + + if (p_cancel) { + if (p_id == 0) { + link->set_start_location(p_restore); + } else { + link->set_end_location(p_restore); + } + return; + } + + Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo(); + if (p_id == 0) { + ur->create_action(TTR("Change Start Location")); + ur->add_do_method(link, "set_start_location", link->get_start_location()); + ur->add_undo_method(link, "set_start_location", p_restore); + } else { + ur->create_action(TTR("Change End Location")); + ur->add_do_method(link, "set_end_location", link->get_end_location()); + ur->add_undo_method(link, "set_end_location", p_restore); + } + + ur->commit_action(); +} + ////// #define BODY_A_RADIUS 0.25 diff --git a/editor/plugins/node_3d_editor_gizmos.h b/editor/plugins/node_3d_editor_gizmos.h index 1b6485ac4e..5924f8571a 100644 --- a/editor/plugins/node_3d_editor_gizmos.h +++ b/editor/plugins/node_3d_editor_gizmos.h @@ -631,6 +631,23 @@ public: NavigationRegion3DGizmoPlugin(); }; +class NavigationLink3DGizmoPlugin : public EditorNode3DGizmoPlugin { + GDCLASS(NavigationLink3DGizmoPlugin, EditorNode3DGizmoPlugin); + +public: + bool has_gizmo(Node3D *p_spatial) override; + String get_gizmo_name() const override; + int get_priority() const override; + void redraw(EditorNode3DGizmo *p_gizmo) override; + + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override; + void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override; + + NavigationLink3DGizmoPlugin(); +}; + class JointGizmosDrawer { public: static Basis look_body(const Transform3D &p_joint_transform, const Transform3D &p_body_transform); diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 1a704a5777..03cf9abed9 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -6408,7 +6408,7 @@ void fragment() { Ref<ShaderMaterial> rotate_mat = memnew(ShaderMaterial); rotate_mat->set_render_priority(Material::RENDER_PRIORITY_MAX); rotate_mat->set_shader(rotate_shader); - rotate_mat->set_shader_uniform("albedo", col); + rotate_mat->set_shader_parameter("albedo", col); rotate_gizmo_color[i] = rotate_mat; Array arrays = surftool->commit_to_arrays(); @@ -6416,7 +6416,7 @@ void fragment() { rotate_gizmo[i]->surface_set_material(0, rotate_mat); Ref<ShaderMaterial> rotate_mat_hl = rotate_mat->duplicate(); - rotate_mat_hl->set_shader_uniform("albedo", albedo); + rotate_mat_hl->set_shader_parameter("albedo", albedo); rotate_gizmo_color_hl[i] = rotate_mat_hl; if (i == 2) { // Rotation white outline @@ -6457,7 +6457,7 @@ void fragment() { )"); border_mat->set_shader(border_shader); - border_mat->set_shader_uniform("albedo", Color(0.75, 0.75, 0.75, col.a / 3.0)); + border_mat->set_shader_parameter("albedo", Color(0.75, 0.75, 0.75, col.a / 3.0)); rotate_gizmo[3] = Ref<ArrayMesh>(memnew(ArrayMesh)); rotate_gizmo[3]->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, arrays); @@ -6710,8 +6710,8 @@ void Node3DEditor::_init_grid() { fade_size = CLAMP(fade_size, min_fade_size, max_fade_size); real_t grid_fade_size = (grid_size - primary_grid_steps) * fade_size; - grid_mat[c]->set_shader_uniform("grid_size", grid_fade_size); - grid_mat[c]->set_shader_uniform("orthogonal", orthogonal); + grid_mat[c]->set_shader_parameter("grid_size", grid_fade_size); + grid_mat[c]->set_shader_parameter("orthogonal", orthogonal); // Cache these so we don't have to re-access memory. Vector<Vector3> &ref_grid = grid_points[c]; @@ -7523,6 +7523,7 @@ void Node3DEditor::_register_all_gizmos() { add_gizmo_plugin(Ref<CollisionObject3DGizmoPlugin>(memnew(CollisionObject3DGizmoPlugin))); add_gizmo_plugin(Ref<CollisionShape3DGizmoPlugin>(memnew(CollisionShape3DGizmoPlugin))); add_gizmo_plugin(Ref<CollisionPolygon3DGizmoPlugin>(memnew(CollisionPolygon3DGizmoPlugin))); + add_gizmo_plugin(Ref<NavigationLink3DGizmoPlugin>(memnew(NavigationLink3DGizmoPlugin))); add_gizmo_plugin(Ref<NavigationRegion3DGizmoPlugin>(memnew(NavigationRegion3DGizmoPlugin))); add_gizmo_plugin(Ref<Joint3DGizmoPlugin>(memnew(Joint3DGizmoPlugin))); add_gizmo_plugin(Ref<PhysicalBone3DGizmoPlugin>(memnew(PhysicalBone3DGizmoPlugin))); @@ -7570,9 +7571,9 @@ void Node3DEditor::_sun_direction_draw() { sun_direction->draw_rect(Rect2(Vector2(), sun_direction->get_size()), Color(1, 1, 1, 1)); Vector3 z_axis = preview_sun->get_transform().basis.get_column(Vector3::AXIS_Z); z_axis = get_editor_viewport(0)->camera->get_camera_transform().basis.xform_inv(z_axis); - sun_direction_material->set_shader_uniform("sun_direction", Vector3(z_axis.x, -z_axis.y, z_axis.z)); + sun_direction_material->set_shader_parameter("sun_direction", Vector3(z_axis.x, -z_axis.y, z_axis.z)); Color color = sun_color->get_pick_color() * sun_energy->get_value(); - sun_direction_material->set_shader_uniform("sun_color", Vector3(color.r, color.g, color.b)); + sun_direction_material->set_shader_parameter("sun_color", Vector3(color.r, color.g, color.b)); } void Node3DEditor::_preview_settings_changed() { @@ -8173,8 +8174,8 @@ void fragment() { )"); sun_direction_material.instantiate(); sun_direction_material->set_shader(sun_direction_shader); - sun_direction_material->set_shader_uniform("sun_direction", Vector3(0, 0, 1)); - sun_direction_material->set_shader_uniform("sun_color", Vector3(1, 1, 1)); + sun_direction_material->set_shader_parameter("sun_direction", Vector3(0, 0, 1)); + sun_direction_material->set_shader_parameter("sun_color", Vector3(1, 1, 1)); sun_direction->set_material(sun_direction_material); HBoxContainer *sun_angle_hbox = memnew(HBoxContainer); diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index 6674d15268..246bc4b183 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -355,7 +355,7 @@ void ShaderTextEditor::_check_shader_mode() { } static ShaderLanguage::DataType _get_global_shader_uniform_type(const StringName &p_variable) { - RS::GlobalShaderUniformType gvt = RS::get_singleton()->global_shader_uniform_get_type(p_variable); + RS::GlobalShaderParameterType gvt = RS::get_singleton()->global_shader_parameter_get_type(p_variable); return (ShaderLanguage::DataType)RS::global_shader_uniform_type_get_shader_datatype(gvt); } diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp index b85e44e106..15ae4ffcff 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.cpp +++ b/editor/plugins/skeleton_3d_editor_plugin.cpp @@ -433,7 +433,7 @@ PhysicalBone3D *Skeleton3DEditor::create_physical_bone(int bone_id, int bone_chi /// Get an up vector not collinear with child rest origin Vector3 up = Vector3(0, 1, 0); - if (up.cross(child_rest.origin).is_equal_approx(Vector3())) { + if (up.cross(child_rest.origin).is_zero_approx()) { up = Vector3(0, 0, 1); } @@ -711,7 +711,6 @@ void Skeleton3DEditor::create_editors() { ne->add_control_to_menu_panel(skeleton_options); skeleton_options->set_text(TTR("Skeleton3D")); - skeleton_options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Skeleton3D"), SNAME("EditorIcons"))); // Skeleton options. PopupMenu *p = skeleton_options->get_popup(); @@ -824,7 +823,6 @@ void Skeleton3DEditor::create_editors() { void Skeleton3DEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { - create_editors(); update_joint_tree(); update_editors(); @@ -844,6 +842,7 @@ void Skeleton3DEditor::_notification(int p_what) { add_theme_constant_override("separation", 0); } break; case NOTIFICATION_THEME_CHANGED: { + skeleton_options->set_icon(get_theme_icon(SNAME("Skeleton3D"), SNAME("EditorIcons"))); edit_mode_button->set_icon(get_theme_icon(SNAME("ToolBoneSelect"), SNAME("EditorIcons"))); key_loc_button->set_icon(get_theme_icon(SNAME("KeyPosition"), SNAME("EditorIcons"))); key_rot_button->set_icon(get_theme_icon(SNAME("KeyRotation"), SNAME("EditorIcons"))); @@ -921,13 +920,15 @@ void fragment() { )"); handle_material->set_shader(handle_shader); Ref<Texture2D> handle = EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("EditorBoneHandle"), SNAME("EditorIcons")); - handle_material->set_shader_uniform("point_size", handle->get_width()); - handle_material->set_shader_uniform("texture_albedo", handle); + handle_material->set_shader_parameter("point_size", handle->get_width()); + handle_material->set_shader_parameter("texture_albedo", handle); handles_mesh_instance = memnew(MeshInstance3D); handles_mesh_instance->set_cast_shadows_setting(GeometryInstance3D::SHADOW_CASTING_SETTING_OFF); handles_mesh.instantiate(); handles_mesh_instance->set_mesh(handles_mesh); + + create_editors(); } void Skeleton3DEditor::update_bone_original() { diff --git a/editor/plugins/texture_3d_editor_plugin.cpp b/editor/plugins/texture_3d_editor_plugin.cpp index c2517b4b79..3ea62184c6 100644 --- a/editor/plugins/texture_3d_editor_plugin.cpp +++ b/editor/plugins/texture_3d_editor_plugin.cpp @@ -57,8 +57,8 @@ void Texture3DEditor::_texture_changed() { } void Texture3DEditor::_update_material() { - material->set_shader_uniform("layer", (layer->get_value() + 0.5) / texture->get_depth()); - material->set_shader_uniform("tex", texture->get_rid()); + material->set_shader_parameter("layer", (layer->get_value() + 0.5) / texture->get_depth()); + material->set_shader_parameter("tex", texture->get_rid()); String format = Image::get_format_name(texture->get_format()); diff --git a/editor/plugins/texture_layered_editor_plugin.cpp b/editor/plugins/texture_layered_editor_plugin.cpp index 1118f18605..dd8633360e 100644 --- a/editor/plugins/texture_layered_editor_plugin.cpp +++ b/editor/plugins/texture_layered_editor_plugin.cpp @@ -68,9 +68,9 @@ void TextureLayeredEditor::_texture_changed() { } void TextureLayeredEditor::_update_material() { - materials[0]->set_shader_uniform("layer", layer->get_value()); - materials[2]->set_shader_uniform("layer", layer->get_value()); - materials[texture->get_layered_type()]->set_shader_uniform("tex", texture->get_rid()); + materials[0]->set_shader_parameter("layer", layer->get_value()); + materials[2]->set_shader_parameter("layer", layer->get_value()); + materials[texture->get_layered_type()]->set_shader_parameter("tex", texture->get_rid()); Vector3 v(1, 1, 1); v.normalize(); @@ -79,10 +79,10 @@ void TextureLayeredEditor::_update_material() { b.rotate(Vector3(1, 0, 0), x_rot); b.rotate(Vector3(0, 1, 0), y_rot); - materials[1]->set_shader_uniform("normal", v); - materials[1]->set_shader_uniform("rot", b); - materials[2]->set_shader_uniform("normal", v); - materials[2]->set_shader_uniform("rot", b); + materials[1]->set_shader_parameter("normal", v); + materials[1]->set_shader_parameter("rot", b); + materials[2]->set_shader_parameter("normal", v); + materials[2]->set_shader_parameter("rot", b); String format = Image::get_format_name(texture->get_format()); diff --git a/editor/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp index 5f0576a675..d9291503cb 100644 --- a/editor/plugins/tiles/tile_atlas_view.cpp +++ b/editor/plugins/tiles/tile_atlas_view.cpp @@ -139,7 +139,7 @@ void TileAtlasView::_update_zoom_and_panning(bool p_zoom_on_mouse_pos) { // Center of panel. panning = panning * zoom / previous_zoom; } - button_center_view->set_disabled(panning.is_equal_approx(Vector2())); + button_center_view->set_disabled(panning.is_zero_approx()); previous_zoom = zoom; diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp index 1bfbd342c2..1dce41e4c7 100644 --- a/editor/plugins/tiles/tile_data_editors.cpp +++ b/editor/plugins/tiles/tile_data_editors.cpp @@ -448,7 +448,7 @@ void GenericTilePolygonEditor::_base_control_gui_input(Ref<InputEvent> p_event) } else if (drag_type == DRAG_TYPE_PAN) { panning += mm->get_position() - drag_last_pos; drag_last_pos = mm->get_position(); - button_center_view->set_disabled(panning.is_equal_approx(Vector2())); + button_center_view->set_disabled(panning.is_zero_approx()); } else { // Update hovered point. _grab_polygon_point(mm->get_position(), xform, hovered_polygon_index, hovered_point_index); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 2fb8bbe86b..804db726a2 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -111,7 +111,7 @@ void VisualShaderGraphPlugin::_bind_methods() { ClassDB::bind_method("update_node", &VisualShaderGraphPlugin::update_node); ClassDB::bind_method("update_node_deferred", &VisualShaderGraphPlugin::update_node_deferred); ClassDB::bind_method("set_input_port_default_value", &VisualShaderGraphPlugin::set_input_port_default_value); - ClassDB::bind_method("set_uniform_name", &VisualShaderGraphPlugin::set_uniform_name); + ClassDB::bind_method("set_parameter_name", &VisualShaderGraphPlugin::set_parameter_name); ClassDB::bind_method("set_expression", &VisualShaderGraphPlugin::set_expression); ClassDB::bind_method("update_curve", &VisualShaderGraphPlugin::update_curve); ClassDB::bind_method("update_curve_xyz", &VisualShaderGraphPlugin::update_curve_xyz); @@ -223,9 +223,9 @@ void VisualShaderGraphPlugin::set_input_port_default_value(VisualShader::Type p_ } } -void VisualShaderGraphPlugin::set_uniform_name(VisualShader::Type p_type, int p_node_id, const String &p_name) { - if (visual_shader->get_shader_type() == p_type && links.has(p_node_id) && links[p_node_id].uniform_name != nullptr) { - links[p_node_id].uniform_name->set_text(p_name); +void VisualShaderGraphPlugin::set_parameter_name(VisualShader::Type p_type, int p_node_id, const String &p_name) { + if (visual_shader->get_shader_type() == p_type && links.has(p_node_id) && links[p_node_id].parameter_name != nullptr) { + links[p_node_id].parameter_name->set_text(p_name); } } @@ -290,9 +290,9 @@ void VisualShaderGraphPlugin::register_curve_editor(int p_node_id, int p_index, links[p_node_id].curve_editors[p_index] = p_curve_editor; } -void VisualShaderGraphPlugin::update_uniform_refs() { +void VisualShaderGraphPlugin::update_parameter_refs() { for (KeyValue<int, Link> &E : links) { - VisualShaderNodeUniformRef *ref = Object::cast_to<VisualShaderNodeUniformRef>(E.value.visual_node); + VisualShaderNodeParameterRef *ref = Object::cast_to<VisualShaderNodeParameterRef>(E.value.visual_node); if (ref) { remove_node(E.value.type, E.key); add_node(E.value.type, E.key); @@ -334,8 +334,8 @@ void VisualShaderGraphPlugin::register_output_port(int p_node_id, int p_port, Te links[p_node_id].output_ports.insert(p_port, { p_button }); } -void VisualShaderGraphPlugin::register_uniform_name(int p_node_id, LineEdit *p_uniform_name) { - links[p_node_id].uniform_name = p_uniform_name; +void VisualShaderGraphPlugin::register_parameter_name(int p_node_id, LineEdit *p_parameter_name) { + links[p_node_id].parameter_name = p_parameter_name; } void VisualShaderGraphPlugin::update_theme() { @@ -466,29 +466,29 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { node->set_custom_minimum_size(Size2(200 * EDSCALE, 0)); } - Ref<VisualShaderNodeUniformRef> uniform_ref = vsnode; - if (uniform_ref.is_valid()) { - uniform_ref->set_shader_rid(visual_shader->get_rid()); - uniform_ref->update_uniform_type(); + Ref<VisualShaderNodeParameterRef> parameter_ref = vsnode; + if (parameter_ref.is_valid()) { + parameter_ref->set_shader_rid(visual_shader->get_rid()); + parameter_ref->update_parameter_type(); } - Ref<VisualShaderNodeUniform> uniform = vsnode; + Ref<VisualShaderNodeParameter> parameter = vsnode; HBoxContainer *hb = nullptr; - if (uniform.is_valid()) { - LineEdit *uniform_name = memnew(LineEdit); - register_uniform_name(p_id, uniform_name); - uniform_name->set_h_size_flags(Control::SIZE_EXPAND_FILL); - uniform_name->set_text(uniform->get_uniform_name()); - uniform_name->connect("text_submitted", callable_mp(editor, &VisualShaderEditor::_uniform_line_edit_changed).bind(p_id)); - uniform_name->connect("focus_exited", callable_mp(editor, &VisualShaderEditor::_uniform_line_edit_focus_out).bind(uniform_name, p_id)); + if (parameter.is_valid()) { + LineEdit *parameter_name = memnew(LineEdit); + register_parameter_name(p_id, parameter_name); + parameter_name->set_h_size_flags(Control::SIZE_EXPAND_FILL); + parameter_name->set_text(parameter->get_parameter_name()); + parameter_name->connect("text_submitted", callable_mp(editor, &VisualShaderEditor::_parameter_line_edit_changed).bind(p_id)); + parameter_name->connect("focus_exited", callable_mp(editor, &VisualShaderEditor::_parameter_line_edit_focus_out).bind(parameter_name, p_id)); if (vsnode->get_output_port_count() == 1 && vsnode->get_output_port_name(0) == "") { hb = memnew(HBoxContainer); - hb->add_child(uniform_name); + hb->add_child(parameter_name); node->add_child(hb); } else { - node->add_child(uniform_name); + node->add_child(parameter_name); } port_offset++; } @@ -1409,13 +1409,13 @@ void VisualShaderEditor::_update_options_menu() { } } - Ref<VisualShaderNodeUniformRef> uniform_ref = Object::cast_to<VisualShaderNodeUniformRef>(vsn.ptr()); - if (uniform_ref.is_valid()) { + Ref<VisualShaderNodeParameterRef> parameter_ref = Object::cast_to<VisualShaderNodeParameterRef>(vsn.ptr()); + if (parameter_ref.is_valid()) { check_result = -1; if (members_input_port_type != VisualShaderNode::PORT_TYPE_MAX) { - for (int j = 0; j < uniform_ref->get_uniforms_count(); j++) { - if (visual_shader->is_port_types_compatible(uniform_ref->get_port_type_by_index(j), members_input_port_type)) { + for (int j = 0; j < parameter_ref->get_parameters_count(); j++) { + if (visual_shader->is_port_types_compatible(parameter_ref->get_port_type_by_index(j), members_input_port_type)) { check_result = 1; break; } @@ -1612,66 +1612,66 @@ void VisualShaderEditor::_update_created_node(GraphNode *node) { node->add_theme_color_override("resizer_color", c); } -void VisualShaderEditor::_update_uniforms(bool p_update_refs) { - VisualShaderNodeUniformRef::clear_uniforms(visual_shader->get_rid()); +void VisualShaderEditor::_update_parameters(bool p_update_refs) { + VisualShaderNodeParameterRef::clear_parameters(visual_shader->get_rid()); for (int t = 0; t < VisualShader::TYPE_MAX; t++) { Vector<int> tnodes = visual_shader->get_node_list((VisualShader::Type)t); for (int i = 0; i < tnodes.size(); i++) { Ref<VisualShaderNode> vsnode = visual_shader->get_node((VisualShader::Type)t, tnodes[i]); - Ref<VisualShaderNodeUniform> uniform = vsnode; - - if (uniform.is_valid()) { - Ref<VisualShaderNodeFloatUniform> float_uniform = vsnode; - Ref<VisualShaderNodeIntUniform> int_uniform = vsnode; - Ref<VisualShaderNodeVec2Uniform> vec2_uniform = vsnode; - Ref<VisualShaderNodeVec3Uniform> vec3_uniform = vsnode; - Ref<VisualShaderNodeVec4Uniform> vec4_uniform = vsnode; - Ref<VisualShaderNodeColorUniform> color_uniform = vsnode; - Ref<VisualShaderNodeBooleanUniform> bool_uniform = vsnode; - Ref<VisualShaderNodeTransformUniform> transform_uniform = vsnode; - - VisualShaderNodeUniformRef::UniformType uniform_type; - if (float_uniform.is_valid()) { - uniform_type = VisualShaderNodeUniformRef::UniformType::UNIFORM_TYPE_FLOAT; - } else if (int_uniform.is_valid()) { - uniform_type = VisualShaderNodeUniformRef::UniformType::UNIFORM_TYPE_INT; - } else if (bool_uniform.is_valid()) { - uniform_type = VisualShaderNodeUniformRef::UniformType::UNIFORM_TYPE_BOOLEAN; - } else if (vec2_uniform.is_valid()) { - uniform_type = VisualShaderNodeUniformRef::UniformType::UNIFORM_TYPE_VECTOR2; - } else if (vec3_uniform.is_valid()) { - uniform_type = VisualShaderNodeUniformRef::UniformType::UNIFORM_TYPE_VECTOR3; - } else if (vec4_uniform.is_valid()) { - uniform_type = VisualShaderNodeUniformRef::UniformType::UNIFORM_TYPE_VECTOR4; - } else if (transform_uniform.is_valid()) { - uniform_type = VisualShaderNodeUniformRef::UniformType::UNIFORM_TYPE_TRANSFORM; - } else if (color_uniform.is_valid()) { - uniform_type = VisualShaderNodeUniformRef::UniformType::UNIFORM_TYPE_COLOR; + Ref<VisualShaderNodeParameter> parameter = vsnode; + + if (parameter.is_valid()) { + Ref<VisualShaderNodeFloatParameter> float_parameter = vsnode; + Ref<VisualShaderNodeIntParameter> int_parameter = vsnode; + Ref<VisualShaderNodeVec2Parameter> vec2_parameter = vsnode; + Ref<VisualShaderNodeVec3Parameter> vec3_parameter = vsnode; + Ref<VisualShaderNodeVec4Parameter> vec4_parameter = vsnode; + Ref<VisualShaderNodeColorParameter> color_parameter = vsnode; + Ref<VisualShaderNodeBooleanParameter> boolean_parameter = vsnode; + Ref<VisualShaderNodeTransformParameter> transform_parameter = vsnode; + + VisualShaderNodeParameterRef::ParameterType parameter_type; + if (float_parameter.is_valid()) { + parameter_type = VisualShaderNodeParameterRef::PARAMETER_TYPE_FLOAT; + } else if (int_parameter.is_valid()) { + parameter_type = VisualShaderNodeParameterRef::PARAMETER_TYPE_INT; + } else if (boolean_parameter.is_valid()) { + parameter_type = VisualShaderNodeParameterRef::PARAMETER_TYPE_BOOLEAN; + } else if (vec2_parameter.is_valid()) { + parameter_type = VisualShaderNodeParameterRef::PARAMETER_TYPE_VECTOR2; + } else if (vec3_parameter.is_valid()) { + parameter_type = VisualShaderNodeParameterRef::PARAMETER_TYPE_VECTOR3; + } else if (vec4_parameter.is_valid()) { + parameter_type = VisualShaderNodeParameterRef::PARAMETER_TYPE_VECTOR4; + } else if (transform_parameter.is_valid()) { + parameter_type = VisualShaderNodeParameterRef::PARAMETER_TYPE_TRANSFORM; + } else if (color_parameter.is_valid()) { + parameter_type = VisualShaderNodeParameterRef::PARAMETER_TYPE_COLOR; } else { - uniform_type = VisualShaderNodeUniformRef::UniformType::UNIFORM_TYPE_SAMPLER; + parameter_type = VisualShaderNodeParameterRef::UNIFORM_TYPE_SAMPLER; } - VisualShaderNodeUniformRef::add_uniform(visual_shader->get_rid(), uniform->get_uniform_name(), uniform_type); + VisualShaderNodeParameterRef::add_parameter(visual_shader->get_rid(), parameter->get_parameter_name(), parameter_type); } } } if (p_update_refs) { - graph_plugin->update_uniform_refs(); + graph_plugin->update_parameter_refs(); } } -void VisualShaderEditor::_update_uniform_refs(HashSet<String> &p_deleted_names) { +void VisualShaderEditor::_update_parameter_refs(HashSet<String> &p_deleted_names) { for (int i = 0; i < VisualShader::TYPE_MAX; i++) { VisualShader::Type type = VisualShader::Type(i); Vector<int> nodes = visual_shader->get_node_list(type); for (int j = 0; j < nodes.size(); j++) { if (j > 0) { - Ref<VisualShaderNodeUniformRef> ref = visual_shader->get_node(type, nodes[j]); + Ref<VisualShaderNodeParameterRef> ref = visual_shader->get_node(type, nodes[j]); if (ref.is_valid()) { - if (p_deleted_names.has(ref->get_uniform_name())) { - undo_redo->add_do_method(ref.ptr(), "set_uniform_name", "[None]"); - undo_redo->add_undo_method(ref.ptr(), "set_uniform_name", ref->get_uniform_name()); + if (p_deleted_names.has(ref->get_parameter_name())) { + undo_redo->add_do_method(ref.ptr(), "set_parameter_name", "[None]"); + undo_redo->add_undo_method(ref.ptr(), "set_parameter_name", ref->get_parameter_name()); undo_redo->add_do_method(graph_plugin.ptr(), "update_node", VisualShader::Type(i), nodes[j]); undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", VisualShader::Type(i), nodes[j]); } @@ -1711,7 +1711,7 @@ void VisualShaderEditor::_update_graph() { Vector<int> nodes = visual_shader->get_node_list(type); - _update_uniforms(false); + _update_parameters(false); _update_varyings(); graph_plugin->clear_links(); @@ -2257,38 +2257,38 @@ void VisualShaderEditor::_comment_desc_popup_hide() { undo_redo->commit_action(); } -void VisualShaderEditor::_uniform_line_edit_changed(const String &p_text, int p_node_id) { +void VisualShaderEditor::_parameter_line_edit_changed(const String &p_text, int p_node_id) { VisualShader::Type type = get_current_shader_type(); - Ref<VisualShaderNodeUniform> node = visual_shader->get_node(type, p_node_id); + Ref<VisualShaderNodeParameter> node = visual_shader->get_node(type, p_node_id); ERR_FAIL_COND(!node.is_valid()); - String validated_name = visual_shader->validate_uniform_name(p_text, node); + String validated_name = visual_shader->validate_parameter_name(p_text, node); - if (validated_name == node->get_uniform_name()) { + if (validated_name == node->get_parameter_name()) { return; } - undo_redo->create_action(TTR("Set Uniform Name")); - undo_redo->add_do_method(node.ptr(), "set_uniform_name", validated_name); - undo_redo->add_undo_method(node.ptr(), "set_uniform_name", node->get_uniform_name()); - undo_redo->add_do_method(graph_plugin.ptr(), "set_uniform_name", type, p_node_id, validated_name); - undo_redo->add_undo_method(graph_plugin.ptr(), "set_uniform_name", type, p_node_id, node->get_uniform_name()); + undo_redo->create_action(TTR("Set Parameter Name")); + undo_redo->add_do_method(node.ptr(), "set_parameter_name", validated_name); + undo_redo->add_undo_method(node.ptr(), "set_parameter_name", node->get_parameter_name()); + undo_redo->add_do_method(graph_plugin.ptr(), "set_parameter_name", type, p_node_id, validated_name); + undo_redo->add_undo_method(graph_plugin.ptr(), "set_parameter_name", type, p_node_id, node->get_parameter_name()); undo_redo->add_do_method(graph_plugin.ptr(), "update_node_deferred", type, p_node_id); undo_redo->add_undo_method(graph_plugin.ptr(), "update_node_deferred", type, p_node_id); - undo_redo->add_do_method(this, "_update_uniforms", true); - undo_redo->add_undo_method(this, "_update_uniforms", true); + undo_redo->add_do_method(this, "_update_parameters", true); + undo_redo->add_undo_method(this, "_update_parameters", true); HashSet<String> changed_names; - changed_names.insert(node->get_uniform_name()); - _update_uniform_refs(changed_names); + changed_names.insert(node->get_parameter_name()); + _update_parameter_refs(changed_names); undo_redo->commit_action(); } -void VisualShaderEditor::_uniform_line_edit_focus_out(Object *line_edit, int p_node_id) { - _uniform_line_edit_changed(Object::cast_to<LineEdit>(line_edit)->get_text(), p_node_id); +void VisualShaderEditor::_parameter_line_edit_focus_out(Object *line_edit, int p_node_id) { + _parameter_line_edit_changed(Object::cast_to<LineEdit>(line_edit)->get_text(), p_node_id); } void VisualShaderEditor::_port_name_focus_out(Object *line_edit, int p_node_id, int p_port_id, bool p_output) { @@ -2674,22 +2674,22 @@ void VisualShaderEditor::_add_node(int p_idx, const Vector<Variant> &p_ops, Stri if (!p_ops.is_empty()) { _setup_node(vsn, p_ops); } - VisualShaderNodeUniformRef *uniform_ref = Object::cast_to<VisualShaderNodeUniformRef>(vsn); - if (uniform_ref && to_node != -1 && to_slot != -1) { + VisualShaderNodeParameterRef *parameter_ref = Object::cast_to<VisualShaderNodeParameterRef>(vsn); + if (parameter_ref && to_node != -1 && to_slot != -1) { VisualShaderNode::PortType input_port_type = visual_shader->get_node(type, to_node)->get_input_port_type(to_slot); bool success = false; - for (int i = 0; i < uniform_ref->get_uniforms_count(); i++) { - if (uniform_ref->get_port_type_by_index(i) == input_port_type) { - uniform_ref->set_uniform_name(uniform_ref->get_uniform_name_by_index(i)); + for (int i = 0; i < parameter_ref->get_parameters_count(); i++) { + if (parameter_ref->get_port_type_by_index(i) == input_port_type) { + parameter_ref->set_parameter_name(parameter_ref->get_parameter_name_by_index(i)); success = true; break; } } if (!success) { - for (int i = 0; i < uniform_ref->get_uniforms_count(); i++) { - if (visual_shader->is_port_types_compatible(uniform_ref->get_port_type_by_index(i), input_port_type)) { - uniform_ref->set_uniform_name(uniform_ref->get_uniform_name_by_index(i)); + for (int i = 0; i < parameter_ref->get_parameters_count(); i++) { + if (visual_shader->is_port_types_compatible(parameter_ref->get_port_type_by_index(i), input_port_type)) { + parameter_ref->set_parameter_name(parameter_ref->get_parameter_name_by_index(i)); break; } } @@ -2712,7 +2712,7 @@ void VisualShaderEditor::_add_node(int p_idx, const Vector<Variant> &p_ops, Stri bool is_cubemap = (Object::cast_to<VisualShaderNodeCubemap>(vsnode.ptr()) != nullptr); bool is_curve = (Object::cast_to<VisualShaderNodeCurveTexture>(vsnode.ptr()) != nullptr); bool is_curve_xyz = (Object::cast_to<VisualShaderNodeCurveXYZTexture>(vsnode.ptr()) != nullptr); - bool is_uniform = (Object::cast_to<VisualShaderNodeUniform>(vsnode.ptr()) != nullptr); + bool is_parameter = (Object::cast_to<VisualShaderNodeParameter>(vsnode.ptr()) != nullptr); Point2 position = graph->get_scroll_ofs(); @@ -2861,9 +2861,9 @@ void VisualShaderEditor::_add_node(int p_idx, const Vector<Variant> &p_ops, Stri } _member_cancel(); - if (is_uniform) { - undo_redo->add_do_method(this, "_update_uniforms", true); - undo_redo->add_undo_method(this, "_update_uniforms", true); + if (is_parameter) { + undo_redo->add_do_method(this, "_update_parameters", true); + undo_redo->add_undo_method(this, "_update_parameters", true); } if (is_curve) { @@ -3118,7 +3118,7 @@ void VisualShaderEditor::_delete_nodes(int p_type, const List<int> &p_nodes) { } } - HashSet<String> uniform_names; + HashSet<String> parameter_names; for (const int &F : p_nodes) { Ref<VisualShaderNode> node = visual_shader->get_node(type, F); @@ -3141,9 +3141,9 @@ void VisualShaderEditor::_delete_nodes(int p_type, const List<int> &p_nodes) { undo_redo->add_undo_method(expression, "set_expression", expression->get_expression()); } - VisualShaderNodeUniform *uniform = Object::cast_to<VisualShaderNodeUniform>(node.ptr()); - if (uniform) { - uniform_names.insert(uniform->get_uniform_name()); + VisualShaderNodeParameter *parameter = Object::cast_to<VisualShaderNodeParameter>(node.ptr()); + if (parameter) { + parameter_names.insert(parameter->get_parameter_name()); } } @@ -3172,12 +3172,12 @@ void VisualShaderEditor::_delete_nodes(int p_type, const List<int> &p_nodes) { undo_redo->add_do_method(graph_plugin.ptr(), "remove_node", type, F); } - // update uniform refs if any uniform has been deleted - if (uniform_names.size() > 0) { - undo_redo->add_do_method(this, "_update_uniforms", true); - undo_redo->add_undo_method(this, "_update_uniforms", true); + // update parameter refs if any parameter has been deleted + if (parameter_names.size() > 0) { + undo_redo->add_do_method(this, "_update_parameters", true); + undo_redo->add_undo_method(this, "_update_parameters", true); - _update_uniform_refs(uniform_names); + _update_parameter_refs(parameter_names); } } @@ -3196,33 +3196,33 @@ void VisualShaderEditor::_update_constant(VisualShader::Type p_type_id, int p_no } } -void VisualShaderEditor::_update_uniform(VisualShader::Type p_type_id, int p_node_id, Variant p_var, int p_preview_port) { - Ref<VisualShaderNodeUniform> uniform = visual_shader->get_node(p_type_id, p_node_id); - ERR_FAIL_COND(!uniform.is_valid()); +void VisualShaderEditor::_update_parameter(VisualShader::Type p_type_id, int p_node_id, Variant p_var, int p_preview_port) { + Ref<VisualShaderNodeParameter> parameter = visual_shader->get_node(p_type_id, p_node_id); + ERR_FAIL_COND(!parameter.is_valid()); - String valid_name = visual_shader->validate_uniform_name(uniform->get_uniform_name(), uniform); - uniform->set_uniform_name(valid_name); - graph_plugin->set_uniform_name(p_type_id, p_node_id, valid_name); + String valid_name = visual_shader->validate_parameter_name(parameter->get_parameter_name(), parameter); + parameter->set_parameter_name(valid_name); + graph_plugin->set_parameter_name(p_type_id, p_node_id, valid_name); - if (uniform->has_method("set_default_value_enabled")) { - uniform->call("set_default_value_enabled", true); - uniform->call("set_default_value", p_var); + if (parameter->has_method("set_default_value_enabled")) { + parameter->call("set_default_value_enabled", true); + parameter->call("set_default_value", p_var); } if (p_preview_port != -1) { - uniform->set_output_port_for_preview(p_preview_port); + parameter->set_output_port_for_preview(p_preview_port); } } -void VisualShaderEditor::_convert_constants_to_uniforms(bool p_vice_versa) { +void VisualShaderEditor::_convert_constants_to_parameters(bool p_vice_versa) { VisualShader::Type type_id = get_current_shader_type(); if (!p_vice_versa) { - undo_redo->create_action(TTR("Convert Constant Node(s) To Uniform(s)")); + undo_redo->create_action(TTR("Convert Constant Node(s) To Parameter(s)")); } else { - undo_redo->create_action(TTR("Convert Uniform Node(s) To Constant(s)")); + undo_redo->create_action(TTR("Convert Parameter Node(s) To Constant(s)")); } - const HashSet<int> ¤t_set = p_vice_versa ? selected_uniforms : selected_constants; + const HashSet<int> ¤t_set = p_vice_versa ? selected_parameters : selected_constants; HashSet<String> deleted_names; for (const int &E : current_set) { @@ -3235,15 +3235,15 @@ void VisualShaderEditor::_convert_constants_to_uniforms(bool p_vice_versa) { if (!p_vice_versa) { Ref<VisualShaderNodeFloatConstant> float_const = Object::cast_to<VisualShaderNodeFloatConstant>(node.ptr()); if (float_const.is_valid()) { - _replace_node(type_id, node_id, "VisualShaderNodeFloatConstant", "VisualShaderNodeFloatUniform"); + _replace_node(type_id, node_id, "VisualShaderNodeFloatConstant", "VisualShaderNodeFloatParameter"); var = float_const->get_constant(); caught = true; } } else { - Ref<VisualShaderNodeFloatUniform> float_uniform = Object::cast_to<VisualShaderNodeFloatUniform>(node.ptr()); - if (float_uniform.is_valid()) { - _replace_node(type_id, node_id, "VisualShaderNodeFloatUniform", "VisualShaderNodeFloatConstant"); - var = float_uniform->get_default_value(); + Ref<VisualShaderNodeFloatParameter> float_parameter = Object::cast_to<VisualShaderNodeFloatParameter>(node.ptr()); + if (float_parameter.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeFloatParameter", "VisualShaderNodeFloatConstant"); + var = float_parameter->get_default_value(); caught = true; } } @@ -3253,15 +3253,15 @@ void VisualShaderEditor::_convert_constants_to_uniforms(bool p_vice_versa) { if (!p_vice_versa) { Ref<VisualShaderNodeIntConstant> int_const = Object::cast_to<VisualShaderNodeIntConstant>(node.ptr()); if (int_const.is_valid()) { - _replace_node(type_id, node_id, "VisualShaderNodeIntConstant", "VisualShaderNodeIntUniform"); + _replace_node(type_id, node_id, "VisualShaderNodeIntConstant", "VisualShaderNodeIntParameter"); var = int_const->get_constant(); caught = true; } } else { - Ref<VisualShaderNodeIntUniform> int_uniform = Object::cast_to<VisualShaderNodeIntUniform>(node.ptr()); - if (int_uniform.is_valid()) { - _replace_node(type_id, node_id, "VisualShaderNodeIntUniform", "VisualShaderNodeIntConstant"); - var = int_uniform->get_default_value(); + Ref<VisualShaderNodeIntParameter> int_parameter = Object::cast_to<VisualShaderNodeIntParameter>(node.ptr()); + if (int_parameter.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeIntParameter", "VisualShaderNodeIntConstant"); + var = int_parameter->get_default_value(); caught = true; } } @@ -3272,15 +3272,15 @@ void VisualShaderEditor::_convert_constants_to_uniforms(bool p_vice_versa) { if (!p_vice_versa) { Ref<VisualShaderNodeBooleanConstant> boolean_const = Object::cast_to<VisualShaderNodeBooleanConstant>(node.ptr()); if (boolean_const.is_valid()) { - _replace_node(type_id, node_id, "VisualShaderNodeBooleanConstant", "VisualShaderNodeBooleanUniform"); + _replace_node(type_id, node_id, "VisualShaderNodeBooleanConstant", "VisualShaderNodeBooleanParameter"); var = boolean_const->get_constant(); caught = true; } } else { - Ref<VisualShaderNodeBooleanUniform> boolean_uniform = Object::cast_to<VisualShaderNodeBooleanUniform>(node.ptr()); - if (boolean_uniform.is_valid()) { - _replace_node(type_id, node_id, "VisualShaderNodeBooleanUniform", "VisualShaderNodeBooleanConstant"); - var = boolean_uniform->get_default_value(); + Ref<VisualShaderNodeBooleanParameter> boolean_parameter = Object::cast_to<VisualShaderNodeBooleanParameter>(node.ptr()); + if (boolean_parameter.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeBooleanParameter", "VisualShaderNodeBooleanConstant"); + var = boolean_parameter->get_default_value(); caught = true; } } @@ -3291,15 +3291,15 @@ void VisualShaderEditor::_convert_constants_to_uniforms(bool p_vice_versa) { if (!p_vice_versa) { Ref<VisualShaderNodeVec2Constant> vec2_const = Object::cast_to<VisualShaderNodeVec2Constant>(node.ptr()); if (vec2_const.is_valid()) { - _replace_node(type_id, node_id, "VisualShaderNodeVec2Constant", "VisualShaderNodeVec2Uniform"); + _replace_node(type_id, node_id, "VisualShaderNodeVec2Constant", "VisualShaderNodeVec2Parameter"); var = vec2_const->get_constant(); caught = true; } } else { - Ref<VisualShaderNodeVec2Uniform> vec2_uniform = Object::cast_to<VisualShaderNodeVec2Uniform>(node.ptr()); - if (vec2_uniform.is_valid()) { - _replace_node(type_id, node_id, "VisualShaderNodeVec2Uniform", "VisualShaderNodeVec2Constant"); - var = vec2_uniform->get_default_value(); + Ref<VisualShaderNodeVec2Parameter> vec2_parameter = Object::cast_to<VisualShaderNodeVec2Parameter>(node.ptr()); + if (vec2_parameter.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeVec2Parameter", "VisualShaderNodeVec2Constant"); + var = vec2_parameter->get_default_value(); caught = true; } } @@ -3310,15 +3310,15 @@ void VisualShaderEditor::_convert_constants_to_uniforms(bool p_vice_versa) { if (!p_vice_versa) { Ref<VisualShaderNodeVec3Constant> vec3_const = Object::cast_to<VisualShaderNodeVec3Constant>(node.ptr()); if (vec3_const.is_valid()) { - _replace_node(type_id, node_id, "VisualShaderNodeVec3Constant", "VisualShaderNodeVec3Uniform"); + _replace_node(type_id, node_id, "VisualShaderNodeVec3Constant", "VisualShaderNodeVec3Parameter"); var = vec3_const->get_constant(); caught = true; } } else { - Ref<VisualShaderNodeVec3Uniform> vec3_uniform = Object::cast_to<VisualShaderNodeVec3Uniform>(node.ptr()); - if (vec3_uniform.is_valid()) { - _replace_node(type_id, node_id, "VisualShaderNodeVec3Uniform", "VisualShaderNodeVec3Constant"); - var = vec3_uniform->get_default_value(); + Ref<VisualShaderNodeVec3Parameter> vec3_parameter = Object::cast_to<VisualShaderNodeVec3Parameter>(node.ptr()); + if (vec3_parameter.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeVec3Parameter", "VisualShaderNodeVec3Constant"); + var = vec3_parameter->get_default_value(); caught = true; } } @@ -3329,15 +3329,15 @@ void VisualShaderEditor::_convert_constants_to_uniforms(bool p_vice_versa) { if (!p_vice_versa) { Ref<VisualShaderNodeVec4Constant> vec4_const = Object::cast_to<VisualShaderNodeVec4Constant>(node.ptr()); if (vec4_const.is_valid()) { - _replace_node(type_id, node_id, "VisualShaderNodeVec4Constant", "VisualShaderNodeVec4Uniform"); + _replace_node(type_id, node_id, "VisualShaderNodeVec4Constant", "VisualShaderNodeVec4Parameter"); var = vec4_const->get_constant(); caught = true; } } else { - Ref<VisualShaderNodeVec4Uniform> vec4_uniform = Object::cast_to<VisualShaderNodeVec4Uniform>(node.ptr()); - if (vec4_uniform.is_valid()) { - _replace_node(type_id, node_id, "VisualShaderNodeVec4Uniform", "VisualShaderNodeVec4Constant"); - var = vec4_uniform->get_default_value(); + Ref<VisualShaderNodeVec4Parameter> vec4_parameter = Object::cast_to<VisualShaderNodeVec4Parameter>(node.ptr()); + if (vec4_parameter.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeVec4Parameter", "VisualShaderNodeVec4Constant"); + var = vec4_parameter->get_default_value(); caught = true; } } @@ -3348,15 +3348,15 @@ void VisualShaderEditor::_convert_constants_to_uniforms(bool p_vice_versa) { if (!p_vice_versa) { Ref<VisualShaderNodeColorConstant> color_const = Object::cast_to<VisualShaderNodeColorConstant>(node.ptr()); if (color_const.is_valid()) { - _replace_node(type_id, node_id, "VisualShaderNodeColorConstant", "VisualShaderNodeColorUniform"); + _replace_node(type_id, node_id, "VisualShaderNodeColorConstant", "VisualShaderNodeColorParameter"); var = color_const->get_constant(); caught = true; } } else { - Ref<VisualShaderNodeColorUniform> color_uniform = Object::cast_to<VisualShaderNodeColorUniform>(node.ptr()); - if (color_uniform.is_valid()) { - _replace_node(type_id, node_id, "VisualShaderNodeColorUniform", "VisualShaderNodeColorConstant"); - var = color_uniform->get_default_value(); + Ref<VisualShaderNodeColorParameter> color_parameter = Object::cast_to<VisualShaderNodeColorParameter>(node.ptr()); + if (color_parameter.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeColorParameter", "VisualShaderNodeColorConstant"); + var = color_parameter->get_default_value(); caught = true; } } @@ -3367,15 +3367,15 @@ void VisualShaderEditor::_convert_constants_to_uniforms(bool p_vice_versa) { if (!p_vice_versa) { Ref<VisualShaderNodeTransformConstant> transform_const = Object::cast_to<VisualShaderNodeTransformConstant>(node.ptr()); if (transform_const.is_valid()) { - _replace_node(type_id, node_id, "VisualShaderNodeTransformConstant", "VisualShaderNodeTransformUniform"); + _replace_node(type_id, node_id, "VisualShaderNodeTransformConstant", "VisualShaderNodeTransformParameter"); var = transform_const->get_constant(); caught = true; } } else { - Ref<VisualShaderNodeTransformUniform> transform_uniform = Object::cast_to<VisualShaderNodeTransformUniform>(node.ptr()); - if (transform_uniform.is_valid()) { - _replace_node(type_id, node_id, "VisualShaderNodeTransformUniform", "VisualShaderNodeTransformConstant"); - var = transform_uniform->get_default_value(); + Ref<VisualShaderNodeTransformParameter> transform_parameter = Object::cast_to<VisualShaderNodeTransformParameter>(node.ptr()); + if (transform_parameter.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeTransformParameter", "VisualShaderNodeTransformConstant"); + var = transform_parameter->get_default_value(); caught = true; } } @@ -3384,27 +3384,27 @@ void VisualShaderEditor::_convert_constants_to_uniforms(bool p_vice_versa) { int preview_port = node->get_output_port_for_preview(); if (!p_vice_versa) { - undo_redo->add_do_method(this, "_update_uniform", type_id, node_id, var, preview_port); + undo_redo->add_do_method(this, "_update_parameter", type_id, node_id, var, preview_port); undo_redo->add_undo_method(this, "_update_constant", type_id, node_id, var, preview_port); } else { undo_redo->add_do_method(this, "_update_constant", type_id, node_id, var, preview_port); - undo_redo->add_undo_method(this, "_update_uniform", type_id, node_id, var, preview_port); + undo_redo->add_undo_method(this, "_update_parameter", type_id, node_id, var, preview_port); - Ref<VisualShaderNodeUniform> uniform = Object::cast_to<VisualShaderNodeUniform>(node.ptr()); - ERR_CONTINUE(!uniform.is_valid()); + Ref<VisualShaderNodeParameter> parameter = Object::cast_to<VisualShaderNodeParameter>(node.ptr()); + ERR_CONTINUE(!parameter.is_valid()); - deleted_names.insert(uniform->get_uniform_name()); + deleted_names.insert(parameter->get_parameter_name()); } undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type_id, node_id); undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", type_id, node_id); } - undo_redo->add_do_method(this, "_update_uniforms", true); - undo_redo->add_undo_method(this, "_update_uniforms", true); + undo_redo->add_do_method(this, "_update_parameters", true); + undo_redo->add_undo_method(this, "_update_parameters", true); if (deleted_names.size() > 0) { - _update_uniform_refs(deleted_names); + _update_parameter_refs(deleted_names); } undo_redo->commit_action(); @@ -3468,7 +3468,7 @@ void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) { if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::RIGHT) { selected_constants.clear(); - selected_uniforms.clear(); + selected_parameters.clear(); selected_comment = -1; selected_float_constant = -1; @@ -3494,9 +3494,9 @@ void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) { if (float_constant_node != nullptr) { selected_float_constant = id; } - VisualShaderNodeUniform *uniform_node = Object::cast_to<VisualShaderNodeUniform>(node.ptr()); - if (uniform_node != nullptr && uniform_node->is_convertible_to_constant()) { - selected_uniforms.insert(id); + VisualShaderNodeParameter *parameter_node = Object::cast_to<VisualShaderNodeParameter>(node.ptr()); + if (parameter_node != nullptr && parameter_node->is_convertible_to_constant()) { + selected_parameters.insert(id); } } } @@ -3533,11 +3533,11 @@ void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) { if (temp != -1) { popup_menu->remove_item(temp); } - temp = popup_menu->get_item_index(NodeMenuOptions::CONVERT_CONSTANTS_TO_UNIFORMS); + temp = popup_menu->get_item_index(NodeMenuOptions::CONVERT_CONSTANTS_TO_PARAMETERS); if (temp != -1) { popup_menu->remove_item(temp); } - temp = popup_menu->get_item_index(NodeMenuOptions::CONVERT_UNIFORMS_TO_CONSTANTS); + temp = popup_menu->get_item_index(NodeMenuOptions::CONVERT_PARAMETERS_TO_CONSTANTS); if (temp != -1) { popup_menu->remove_item(temp); } @@ -3554,7 +3554,7 @@ void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) { popup_menu->remove_item(temp); } - if (selected_constants.size() > 0 || selected_uniforms.size() > 0) { + if (selected_constants.size() > 0 || selected_parameters.size() > 0) { popup_menu->add_separator("", NodeMenuOptions::SEPARATOR2); if (selected_float_constant != -1) { @@ -3573,11 +3573,11 @@ void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) { } if (selected_constants.size() > 0) { - popup_menu->add_item(TTR("Convert Constant(s) to Uniform(s)"), NodeMenuOptions::CONVERT_CONSTANTS_TO_UNIFORMS); + popup_menu->add_item(TTR("Convert Constant(s) to Parameter(s)"), NodeMenuOptions::CONVERT_CONSTANTS_TO_PARAMETERS); } - if (selected_uniforms.size() > 0) { - popup_menu->add_item(TTR("Convert Uniform(s) to Constant(s)"), NodeMenuOptions::CONVERT_UNIFORMS_TO_CONSTANTS); + if (selected_parameters.size() > 0) { + popup_menu->add_item(TTR("Convert Parameter(s) to Constant(s)"), NodeMenuOptions::CONVERT_PARAMETERS_TO_CONSTANTS); } } @@ -4124,32 +4124,32 @@ void VisualShaderEditor::_input_select_item(Ref<VisualShaderNodeInput> p_input, undo_redo->commit_action(); } -void VisualShaderEditor::_uniform_select_item(Ref<VisualShaderNodeUniformRef> p_uniform_ref, String p_name) { - String prev_name = p_uniform_ref->get_uniform_name(); +void VisualShaderEditor::_parameter_ref_select_item(Ref<VisualShaderNodeParameterRef> p_parameter_ref, String p_name) { + String prev_name = p_parameter_ref->get_parameter_name(); if (p_name == prev_name) { return; } - bool type_changed = p_uniform_ref->get_uniform_type_by_name(p_name) != p_uniform_ref->get_uniform_type_by_name(prev_name); + bool type_changed = p_parameter_ref->get_parameter_type_by_name(p_name) != p_parameter_ref->get_parameter_type_by_name(prev_name); Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo(); - undo_redo->create_action(TTR("UniformRef Name Changed")); + undo_redo->create_action(TTR("ParameterRef Name Changed")); - undo_redo->add_do_method(p_uniform_ref.ptr(), "set_uniform_name", p_name); - undo_redo->add_undo_method(p_uniform_ref.ptr(), "set_uniform_name", prev_name); + undo_redo->add_do_method(p_parameter_ref.ptr(), "set_parameter_name", p_name); + undo_redo->add_undo_method(p_parameter_ref.ptr(), "set_parameter_name", prev_name); // update output port for (int type_id = 0; type_id < VisualShader::TYPE_MAX; type_id++) { VisualShader::Type type = VisualShader::Type(type_id); - int id = visual_shader->find_node_id(type, p_uniform_ref); + int id = visual_shader->find_node_id(type, p_parameter_ref); if (id != VisualShader::NODE_ID_INVALID) { if (type_changed) { List<VisualShader::Connection> conns; visual_shader->get_node_connections(type, &conns); for (const VisualShader::Connection &E : conns) { if (E.from_node == id) { - if (visual_shader->is_port_types_compatible(p_uniform_ref->get_uniform_type_by_name(p_name), visual_shader->get_node(type, E.to_node)->get_input_port_type(E.to_port))) { + if (visual_shader->is_port_types_compatible(p_parameter_ref->get_parameter_type_by_name(p_name), visual_shader->get_node(type, E.to_node)->get_input_port_type(E.to_port))) { continue; } undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); @@ -4442,11 +4442,11 @@ void VisualShaderEditor::_node_menu_id_pressed(int p_idx) { case NodeMenuOptions::CLEAR_COPY_BUFFER: _clear_copy_buffer(); break; - case NodeMenuOptions::CONVERT_CONSTANTS_TO_UNIFORMS: - _convert_constants_to_uniforms(false); + case NodeMenuOptions::CONVERT_CONSTANTS_TO_PARAMETERS: + _convert_constants_to_parameters(false); break; - case NodeMenuOptions::CONVERT_UNIFORMS_TO_CONSTANTS: - _convert_constants_to_uniforms(true); + case NodeMenuOptions::CONVERT_PARAMETERS_TO_CONSTANTS: + _convert_constants_to_parameters(true); break; case NodeMenuOptions::SET_COMMENT_TITLE: _comment_title_popup_show(get_screen_position() + get_local_mouse_position(), selected_comment); @@ -4598,7 +4598,7 @@ void VisualShaderEditor::_preview_size_changed() { } static ShaderLanguage::DataType _get_global_shader_uniform_type(const StringName &p_variable) { - RS::GlobalShaderUniformType gvt = RS::get_singleton()->global_shader_uniform_get_type(p_variable); + RS::GlobalShaderParameterType gvt = RS::get_singleton()->global_shader_parameter_get_type(p_variable); return (ShaderLanguage::DataType)RS::global_shader_uniform_type_get_shader_datatype(gvt); } @@ -4655,18 +4655,18 @@ void VisualShaderEditor::_bind_methods() { ClassDB::bind_method("_add_node", &VisualShaderEditor::_add_node); ClassDB::bind_method("_node_changed", &VisualShaderEditor::_node_changed); ClassDB::bind_method("_input_select_item", &VisualShaderEditor::_input_select_item); - ClassDB::bind_method("_uniform_select_item", &VisualShaderEditor::_uniform_select_item); + ClassDB::bind_method("_parameter_ref_select_item", &VisualShaderEditor::_parameter_ref_select_item); ClassDB::bind_method("_varying_select_item", &VisualShaderEditor::_varying_select_item); ClassDB::bind_method("_set_node_size", &VisualShaderEditor::_set_node_size); ClassDB::bind_method("_clear_copy_buffer", &VisualShaderEditor::_clear_copy_buffer); - ClassDB::bind_method("_update_uniforms", &VisualShaderEditor::_update_uniforms); + ClassDB::bind_method("_update_parameters", &VisualShaderEditor::_update_parameters); ClassDB::bind_method("_update_varyings", &VisualShaderEditor::_update_varyings); ClassDB::bind_method("_update_varying_tree", &VisualShaderEditor::_update_varying_tree); ClassDB::bind_method("_set_mode", &VisualShaderEditor::_set_mode); ClassDB::bind_method("_nodes_dragged", &VisualShaderEditor::_nodes_dragged); ClassDB::bind_method("_float_constant_selected", &VisualShaderEditor::_float_constant_selected); ClassDB::bind_method("_update_constant", &VisualShaderEditor::_update_constant); - ClassDB::bind_method("_update_uniform", &VisualShaderEditor::_update_uniform); + ClassDB::bind_method("_update_parameter", &VisualShaderEditor::_update_parameter); ClassDB::bind_method("_expand_output_port", &VisualShaderEditor::_expand_output_port); ClassDB::bind_method(D_METHOD("_get_drag_data_fw"), &VisualShaderEditor::get_drag_data_fw); @@ -5077,7 +5077,7 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("SoftLight", "Color", "Operators", "VisualShaderNodeColorOp", TTR("SoftLight operator."), { VisualShaderNodeColorOp::OP_SOFT_LIGHT }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("ColorConstant", "Color", "Variables", "VisualShaderNodeColorConstant", TTR("Color constant."), {}, VisualShaderNode::PORT_TYPE_VECTOR_4D)); - add_options.push_back(AddOption("ColorUniform", "Color", "Variables", "VisualShaderNodeColorUniform", TTR("Color uniform."), {}, VisualShaderNode::PORT_TYPE_VECTOR_4D)); + add_options.push_back(AddOption("ColorParameter", "Color", "Variables", "VisualShaderNodeColorParameter", TTR("Color parameter."), {}, VisualShaderNode::PORT_TYPE_VECTOR_4D)); // COMMON @@ -5107,7 +5107,7 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Is", "Conditional", "Common", "VisualShaderNodeIs", TTR("Returns the boolean result of the comparison between INF (or NaN) and a scalar parameter."), {}, VisualShaderNode::PORT_TYPE_BOOLEAN)); add_options.push_back(AddOption("BooleanConstant", "Conditional", "Variables", "VisualShaderNodeBooleanConstant", TTR("Boolean constant."), {}, VisualShaderNode::PORT_TYPE_BOOLEAN)); - add_options.push_back(AddOption("BooleanUniform", "Conditional", "Variables", "VisualShaderNodeBooleanUniform", TTR("Boolean uniform."), {}, VisualShaderNode::PORT_TYPE_BOOLEAN)); + add_options.push_back(AddOption("BooleanParameter", "Conditional", "Variables", "VisualShaderNodeBooleanParameter", TTR("Boolean parameter."), {}, VisualShaderNode::PORT_TYPE_BOOLEAN)); // INPUT @@ -5396,8 +5396,8 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("FloatConstant", "Scalar", "Variables", "VisualShaderNodeFloatConstant", TTR("Scalar floating-point constant."), {}, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("IntConstant", "Scalar", "Variables", "VisualShaderNodeIntConstant", TTR("Scalar integer constant."), {}, VisualShaderNode::PORT_TYPE_SCALAR_INT)); - add_options.push_back(AddOption("FloatUniform", "Scalar", "Variables", "VisualShaderNodeFloatUniform", TTR("Scalar floating-point uniform."), {}, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("IntUniform", "Scalar", "Variables", "VisualShaderNodeIntUniform", TTR("Scalar integer uniform."), {}, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("FloatParameter", "Scalar", "Variables", "VisualShaderNodeFloatParameter", TTR("Scalar floating-point parameter."), {}, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("IntParameter", "Scalar", "Variables", "VisualShaderNodeIntParameter", TTR("Scalar integer parameter."), {}, VisualShaderNode::PORT_TYPE_SCALAR_INT)); // SDF { @@ -5429,11 +5429,11 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("UVPanning", "Textures", "Functions", "VisualShaderNodeUVFunc", TTR("Apply panning function on texture coordinates."), { VisualShaderNodeUVFunc::FUNC_PANNING }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); add_options.push_back(AddOption("UVScaling", "Textures", "Functions", "VisualShaderNodeUVFunc", TTR("Apply scaling function on texture coordinates."), { VisualShaderNodeUVFunc::FUNC_SCALING }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("CubeMapUniform", "Textures", "Variables", "VisualShaderNodeCubemapUniform", TTR("Cubic texture uniform lookup."), {}, VisualShaderNode::PORT_TYPE_SAMPLER)); - add_options.push_back(AddOption("TextureUniform", "Textures", "Variables", "VisualShaderNodeTextureUniform", TTR("2D texture uniform lookup."), {}, VisualShaderNode::PORT_TYPE_SAMPLER)); - add_options.push_back(AddOption("TextureUniformTriplanar", "Textures", "Variables", "VisualShaderNodeTextureUniformTriplanar", TTR("2D texture uniform lookup with triplanar."), {}, -1, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Texture2DArrayUniform", "Textures", "Variables", "VisualShaderNodeTexture2DArrayUniform", TTR("2D array of textures uniform lookup."), {}, VisualShaderNode::PORT_TYPE_SAMPLER)); - add_options.push_back(AddOption("Texture3DUniform", "Textures", "Variables", "VisualShaderNodeTexture3DUniform", TTR("3D texture uniform lookup."), {}, VisualShaderNode::PORT_TYPE_SAMPLER)); + add_options.push_back(AddOption("CubeMapParameter", "Textures", "Variables", "VisualShaderNodeCubemapParameter", TTR("Cubic texture parameter lookup."), {}, VisualShaderNode::PORT_TYPE_SAMPLER)); + add_options.push_back(AddOption("Texture2DParameter", "Textures", "Variables", "VisualShaderNodeTexture2DParameter", TTR("2D texture parameter lookup."), {}, VisualShaderNode::PORT_TYPE_SAMPLER)); + add_options.push_back(AddOption("TextureParameterTriplanar", "Textures", "Variables", "VisualShaderNodeTextureParameterTriplanar", TTR("2D texture parameter lookup with triplanar."), {}, -1, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Texture2DArrayParameter", "Textures", "Variables", "VisualShaderNodeTexture2DArrayParameter", TTR("2D array of textures parameter lookup."), {}, VisualShaderNode::PORT_TYPE_SAMPLER)); + add_options.push_back(AddOption("Texture3DParameter", "Textures", "Variables", "VisualShaderNodeTexture3DParameter", TTR("3D texture parameter lookup."), {}, VisualShaderNode::PORT_TYPE_SAMPLER)); // TRANSFORM @@ -5457,7 +5457,7 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("TransformVectorMult", "Transform", "Operators", "VisualShaderNodeTransformVecMult", TTR("Multiplies vector by transform."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("TransformConstant", "Transform", "Variables", "VisualShaderNodeTransformConstant", TTR("Transform constant."), {}, VisualShaderNode::PORT_TYPE_TRANSFORM)); - add_options.push_back(AddOption("TransformUniform", "Transform", "Variables", "VisualShaderNodeTransformUniform", TTR("Transform uniform."), {}, VisualShaderNode::PORT_TYPE_TRANSFORM)); + add_options.push_back(AddOption("TransformParameter", "Transform", "Variables", "VisualShaderNodeTransformParameter", TTR("Transform parameter."), {}, VisualShaderNode::PORT_TYPE_TRANSFORM)); // UTILITY @@ -5659,18 +5659,18 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Subtract", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Subtracts 4D vector from 4D vector."), { VisualShaderNodeVectorOp::OP_SUB, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); add_options.push_back(AddOption("Vector2Constant", "Vector", "Variables", "VisualShaderNodeVec2Constant", TTR("2D vector constant."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Vector2Uniform", "Vector", "Variables", "VisualShaderNodeVec2Uniform", TTR("2D vector uniform."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D)); + add_options.push_back(AddOption("Vector2Parameter", "Vector", "Variables", "VisualShaderNodeVec2Parameter", TTR("2D vector parameter."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D)); add_options.push_back(AddOption("Vector3Constant", "Vector", "Variables", "VisualShaderNodeVec3Constant", TTR("3D vector constant."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D)); - add_options.push_back(AddOption("Vector3Uniform", "Vector", "Variables", "VisualShaderNodeVec3Uniform", TTR("3D vector uniform."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("Vector3Parameter", "Vector", "Variables", "VisualShaderNodeVec3Parameter", TTR("3D vector parameter."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Vector4Constant", "Vector", "Variables", "VisualShaderNodeVec4Constant", TTR("4D vector constant."), {}, VisualShaderNode::PORT_TYPE_VECTOR_4D)); - add_options.push_back(AddOption("Vector4Uniform", "Vector", "Variables", "VisualShaderNodeVec4Uniform", TTR("4D vector uniform."), {}, VisualShaderNode::PORT_TYPE_VECTOR_4D)); + add_options.push_back(AddOption("Vector4Parameter", "Vector", "Variables", "VisualShaderNodeVec4Parameter", TTR("4D vector parameter."), {}, VisualShaderNode::PORT_TYPE_VECTOR_4D)); // SPECIAL add_options.push_back(AddOption("Comment", "Special", "", "VisualShaderNodeComment", TTR("A rectangular area with a description string for better graph organization."))); add_options.push_back(AddOption("Expression", "Special", "", "VisualShaderNodeExpression", TTR("Custom Godot Shader Language expression, with custom amount of input and output ports. This is a direct injection of code into the vertex/fragment/light function, do not use it to write the function declarations inside."))); - add_options.push_back(AddOption("GlobalExpression", "Special", "", "VisualShaderNodeGlobalExpression", TTR("Custom Godot Shader Language expression, which is placed on top of the resulted shader. You can place various function definitions inside and call it later in the Expressions. You can also declare varyings, uniforms and constants."))); - add_options.push_back(AddOption("UniformRef", "Special", "", "VisualShaderNodeUniformRef", TTR("A reference to an existing uniform."))); + add_options.push_back(AddOption("GlobalExpression", "Special", "", "VisualShaderNodeGlobalExpression", TTR("Custom Godot Shader Language expression, which is placed on top of the resulted shader. You can place various function definitions inside and call it later in the Expressions. You can also declare varyings, parameters and constants."))); + add_options.push_back(AddOption("ParameterRef", "Special", "", "VisualShaderNodeParameterRef", TTR("A reference to an existing parameter."))); add_options.push_back(AddOption("VaryingGetter", "Special", "", "VisualShaderNodeVaryingGetter", TTR("Get varying parameter."), {}, -1, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("VaryingSetter", "Special", "", "VisualShaderNodeVaryingSetter", TTR("Set varying parameter."), {}, -1, TYPE_FLAGS_VERTEX | TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("VaryingGetter", "Special", "", "VisualShaderNodeVaryingGetter", TTR("Get varying parameter."), {}, -1, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); @@ -5826,28 +5826,28 @@ public: //////////////// -class VisualShaderNodePluginUniformRefEditor : public OptionButton { - GDCLASS(VisualShaderNodePluginUniformRefEditor, OptionButton); +class VisualShaderNodePluginParameterRefEditor : public OptionButton { + GDCLASS(VisualShaderNodePluginParameterRefEditor, OptionButton); VisualShaderEditor *editor = nullptr; - Ref<VisualShaderNodeUniformRef> uniform_ref; + Ref<VisualShaderNodeParameterRef> parameter_ref; public: void _notification(int p_what) { switch (p_what) { case NOTIFICATION_READY: { - connect("item_selected", callable_mp(this, &VisualShaderNodePluginUniformRefEditor::_item_selected)); + connect("item_selected", callable_mp(this, &VisualShaderNodePluginParameterRefEditor::_item_selected)); } break; } } void _item_selected(int p_item) { - editor->call_deferred(SNAME("_uniform_select_item"), uniform_ref, get_item_text(p_item)); + editor->call_deferred(SNAME("_parameter_ref_select_item"), parameter_ref, get_item_text(p_item)); } - void setup(VisualShaderEditor *p_editor, const Ref<VisualShaderNodeUniformRef> &p_uniform_ref) { + void setup(VisualShaderEditor *p_editor, const Ref<VisualShaderNodeParameterRef> &p_parameter_ref) { editor = p_editor; - uniform_ref = p_uniform_ref; + parameter_ref = p_parameter_ref; Ref<Texture2D> type_icon[] = { EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("float"), SNAME("EditorIcons")), @@ -5863,11 +5863,11 @@ public: add_item("[None]"); int to_select = -1; - for (int i = 0; i < p_uniform_ref->get_uniforms_count(); i++) { - if (p_uniform_ref->get_uniform_name() == p_uniform_ref->get_uniform_name_by_index(i)) { + for (int i = 0; i < p_parameter_ref->get_parameters_count(); i++) { + if (p_parameter_ref->get_parameter_name() == p_parameter_ref->get_parameter_name_by_index(i)) { to_select = i + 1; } - add_icon_item(type_icon[p_uniform_ref->get_uniform_type_by_index(i)], p_uniform_ref->get_uniform_name_by_index(i)); + add_icon_item(type_icon[p_parameter_ref->get_parameter_type_by_index(i)], p_parameter_ref->get_parameter_name_by_index(i)); } if (to_select >= 0) { @@ -6011,8 +6011,8 @@ Control *VisualShaderNodePluginDefault::create_editor(const Ref<Resource> &p_par return editor; } - if (p_node->is_class("VisualShaderNodeUniformRef")) { - VisualShaderNodePluginUniformRefEditor *editor = memnew(VisualShaderNodePluginUniformRefEditor); + if (p_node->is_class("VisualShaderNodeParameterRef")) { + VisualShaderNodePluginParameterRefEditor *editor = memnew(VisualShaderNodePluginParameterRefEditor); editor->setup(vseditor, p_node); return editor; } @@ -6222,7 +6222,7 @@ void VisualShaderNodePortPreview::_shader_changed() { preview_shader->set_code(shader_code); for (int i = 0; i < default_textures.size(); i++) { for (int j = 0; j < default_textures[i].params.size(); j++) { - preview_shader->set_default_texture_param(default_textures[i].name, default_textures[i].params[j], j); + preview_shader->set_default_texture_parameter(default_textures[i].name, default_textures[i].params[j], j); } } diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index ede6513b83..869e00ca5d 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -89,7 +89,7 @@ private: HashMap<int, InputPort> input_ports; HashMap<int, Port> output_ports; VBoxContainer *preview_box = nullptr; - LineEdit *uniform_name = nullptr; + LineEdit *parameter_name = nullptr; CodeEdit *expression_edit = nullptr; CurveEditor *curve_editors[3] = { nullptr, nullptr, nullptr }; }; @@ -110,7 +110,7 @@ public: void set_connections(const List<VisualShader::Connection> &p_connections); void register_link(VisualShader::Type p_type, int p_id, VisualShaderNode *p_visual_node, GraphNode *p_graph_node); void register_output_port(int p_id, int p_port, TextureButton *p_button); - void register_uniform_name(int p_id, LineEdit *p_uniform_name); + void register_parameter_name(int p_id, LineEdit *p_parameter_name); void register_default_input_button(int p_node_id, int p_port_id, Button *p_button); void register_expression_edit(int p_node_id, CodeEdit *p_expression_edit); void register_curve_editor(int p_node_id, int p_index, CurveEditor *p_curve_editor); @@ -129,8 +129,8 @@ public: void set_node_position(VisualShader::Type p_type, int p_id, const Vector2 &p_position); void refresh_node_ports(VisualShader::Type p_type, int p_node); void set_input_port_default_value(VisualShader::Type p_type, int p_node_id, int p_port_id, Variant p_value); - void update_uniform_refs(); - void set_uniform_name(VisualShader::Type p_type, int p_node_id, const String &p_name); + void update_parameter_refs(); + void set_parameter_name(VisualShader::Type p_type, int p_node_id, const String &p_name); void update_curve(int p_node_id); void update_curve_xyz(int p_node_id); void set_expression(VisualShader::Type p_type, int p_node_id, const String &p_expression); @@ -269,8 +269,8 @@ class VisualShaderEditor : public VBoxContainer { CLEAR_COPY_BUFFER, SEPARATOR2, // ignore FLOAT_CONSTANTS, - CONVERT_CONSTANTS_TO_UNIFORMS, - CONVERT_UNIFORMS_TO_CONSTANTS, + CONVERT_CONSTANTS_TO_PARAMETERS, + CONVERT_PARAMETERS_TO_CONSTANTS, SEPARATOR3, // ignore SET_COMMENT_TITLE, SET_COMMENT_DESCRIPTION, @@ -340,7 +340,7 @@ class VisualShaderEditor : public VBoxContainer { int curve_xyz_node_option_idx; List<String> keyword_list; - List<VisualShaderNodeUniformRef> uniform_refs; + List<VisualShaderNodeParameterRef> uniform_refs; void _draw_color_over_button(Object *obj, Color p_color); @@ -390,14 +390,14 @@ class VisualShaderEditor : public VBoxContainer { int from_slot = -1; HashSet<int> selected_constants; - HashSet<int> selected_uniforms; + HashSet<int> selected_parameters; int selected_comment = -1; int selected_float_constant = -1; - void _convert_constants_to_uniforms(bool p_vice_versa); + void _convert_constants_to_parameters(bool p_vice_versa); void _replace_node(VisualShader::Type p_type_id, int p_node_id, const StringName &p_from, const StringName &p_to); void _update_constant(VisualShader::Type p_type_id, int p_node_id, Variant p_var, int p_preview_port); - void _update_uniform(VisualShader::Type p_type_id, int p_node_id, Variant p_var, int p_preview_port); + void _update_parameter(VisualShader::Type p_type_id, int p_node_id, Variant p_var, int p_preview_port); void _connection_to_empty(const String &p_from, int p_from_slot, const Vector2 &p_release_position); void _connection_from_empty(const String &p_to, int p_to_slot, const Vector2 &p_release_position); @@ -413,8 +413,8 @@ class VisualShaderEditor : public VBoxContainer { void _comment_desc_confirm(); void _comment_desc_text_changed(); - void _uniform_line_edit_changed(const String &p_text, int p_node_id); - void _uniform_line_edit_focus_out(Object *line_edit, int p_node_id); + void _parameter_line_edit_changed(const String &p_text, int p_node_id); + void _parameter_line_edit_focus_out(Object *line_edit, int p_node_id); void _port_name_focus_out(Object *line_edit, int p_node_id, int p_port_id, bool p_output); @@ -449,7 +449,7 @@ class VisualShaderEditor : public VBoxContainer { void _custom_mode_toggled(bool p_enabled); void _input_select_item(Ref<VisualShaderNodeInput> input, String name); - void _uniform_select_item(Ref<VisualShaderNodeUniformRef> p_uniform, String p_name); + void _parameter_ref_select_item(Ref<VisualShaderNodeParameterRef> p_parameter_ref, String p_name); void _varying_select_item(Ref<VisualShaderNodeVarying> p_varying, String p_name); void _float_constant_selected(int p_which); @@ -498,8 +498,8 @@ class VisualShaderEditor : public VBoxContainer { bool _is_available(int p_mode); void _update_created_node(GraphNode *node); - void _update_uniforms(bool p_update_refs); - void _update_uniform_refs(HashSet<String> &p_names); + void _update_parameters(bool p_update_refs); + void _update_parameter_refs(HashSet<String> &p_names); void _update_varyings(); void _visibility_changed(); diff --git a/editor/project_converter_3_to_4.cpp b/editor/project_converter_3_to_4.cpp index dbd2a7555d..9c717a0518 100644 --- a/editor/project_converter_3_to_4.cpp +++ b/editor/project_converter_3_to_4.cpp @@ -513,7 +513,6 @@ static const char *gdscript_function_renames[][2] = { { "set_region_filter_clip", "set_region_filter_clip_enabled" }, // Sprite2D { "set_rotate", "set_rotates" }, // PathFollow2D { "set_scancode", "set_keycode" }, // InputEventKey - { "set_shader_param", "set_shader_uniform" }, // ShaderMaterial { "set_shift", "set_shift_pressed" }, // InputEventWithModifiers { "set_size_override", "set_size_2d_override" }, // SubViewport broke ImageTexture { "set_size_override_stretch", "set_size_2d_override_stretch" }, // SubViewport @@ -548,6 +547,10 @@ static const char *gdscript_function_renames[][2] = { { "update_gizmo", "update_gizmos" }, // Node3D { "viewport_set_use_arvr", "viewport_set_use_xr" }, // RenderingServer { "warp_mouse_position", "warp_mouse" }, // Input + { "set_shader_param", "set_shader_parameter" }, // ShaderMaterial + { "get_shader_param", "get_shader_parameter" }, // ShaderMaterial + { "set_uniform_name", "set_parameter_name" }, // ParameterRef + { "get_uniform_name", "get_parameter_name" }, // ParameterRef // Builtin types // Remember to add them to builtin_types_excluded_functions variable, because for now this functions cannot be listed @@ -955,6 +958,10 @@ static const char *csharp_function_renames[][2] = { { "UpdateGizmo", "UpdateGizmos" }, // Node3D { "ViewportSetUseArvr", "ViewportSetUseXr" }, // RenderingServer { "WarpMousePosition", "WarpMouse" }, // Input + { "SetShaderParam", "SetShaderParameter" }, // ShaderMaterial + { "GetShaderParam", "GetShaderParameter" }, // ShaderMaterial + { "SetUniformName", "SetParameterName" }, // ParameterRef + { "GetUniformName", "GetParameterName" }, // ParameterRef // Builtin types // { "Empty", "IsEmpty" }, // Array - Used as custom rule // Be careful, this will be used everywhere @@ -1473,7 +1480,6 @@ static const char *class_renames[][2] = { { "VisualInstance", "VisualInstance3D" }, { "VisualServer", "RenderingServer" }, { "VisualShaderNodeCubeMap", "VisualShaderNodeCubemap" }, - { "VisualShaderNodeCubeMapUniform", "VisualShaderNodeCubemapUniform" }, { "VisualShaderNodeScalarClamp", "VisualShaderNodeClamp" }, { "VisualShaderNodeScalarConstant", "VisualShaderNodeFloatConstant" }, { "VisualShaderNodeScalarFunc", "VisualShaderNodeFloatFunc" }, @@ -1482,7 +1488,6 @@ static const char *class_renames[][2] = { { "VisualShaderNodeScalarSmoothStep", "VisualShaderNodeSmoothStep" }, { "VisualShaderNodeScalarSwitch", "VisualShaderNodeSwitch" }, { "VisualShaderNodeScalarTransformMult", "VisualShaderNodeTransformOp" }, - { "VisualShaderNodeScalarUniform", "VisualShaderNodeFloatUniform" }, { "VisualShaderNodeTransformMult", "VisualShaderNode" }, { "VisualShaderNodeVectorClamp", "VisualShaderNodeClamp" }, { "VisualShaderNodeVectorInterp", "VisualShaderNodeMix" }, @@ -1490,6 +1495,16 @@ static const char *class_renames[][2] = { { "VisualShaderNodeVectorScalarSmoothStep", "VisualShaderNodeSmoothStep" }, { "VisualShaderNodeVectorScalarStep", "VisualShaderNodeStep" }, { "VisualShaderNodeVectorSmoothStep", "VisualShaderNodeSmoothStep" }, + { "VisualShaderNodeBooleanUniform", "VisualShaderNodeBooleanParameter" }, + { "VisualShaderNodeColorUniform", "VisualShaderNodeColorParameter" }, + { "VisualShaderNodeScalarUniform", "VisualShaderNodeFloatParameter" }, + { "VisualShaderNodeCubemapUniform", "VisualShaderNodeCubemapParameter" }, + { "VisualShaderNodeTextureUniform", "VisualShaderNodeTexture2DParameter" }, + { "VisualShaderNodeTextureUniformTriplanar", "VisualShaderNodeTextureParameterTriplanar" }, + { "VisualShaderNodeTransformUniform", "VisualShaderNodeTransformParameter" }, + { "VisualShaderNodeVec3Uniform", "VisualShaderNodeVec3Parameter" }, + { "VisualShaderNodeUniform", "VisualShaderNodeParameter" }, + { "VisualShaderNodeUniformRef", "VisualShaderNodeParameterRef" }, { "WebRTCDataChannelGDNative", "WebRTCDataChannelExtension" }, { "WebRTCMultiplayer", "WebRTCMultiplayerPeer" }, { "WebRTCPeerConnectionGDNative", "WebRTCPeerConnectionExtension" }, diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 9909ab378a..ed8c7b14c8 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -1321,7 +1321,7 @@ void ProjectList::update_dock_menu() { } favs_added = 0; } - DisplayServer::get_singleton()->global_menu_add_item("_dock", _projects[i].project_name + " ( " + _projects[i].path + " )", callable_mp(this, &ProjectList::_global_menu_open_project), i); + DisplayServer::get_singleton()->global_menu_add_item("_dock", _projects[i].project_name + " ( " + _projects[i].path + " )", callable_mp(this, &ProjectList::_global_menu_open_project), Callable(), i); total_added++; } } diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index 88ca371fac..c120468ecb 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -386,10 +386,18 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { Ref<Script> script = p_node->get_script(); if (!script.is_null()) { - item->add_button(0, get_theme_icon(SNAME("Script"), SNAME("EditorIcons")), BUTTON_SCRIPT, false, TTR("Open Script:") + " " + script->get_path()); + String additional_notes; + // Can't set tooltip after adding button, need to do it before. + if (script->is_tool()) { + additional_notes += "\n" + TTR("This script is currently running in the editor."); + } + item->add_button(0, get_theme_icon(SNAME("Script"), SNAME("EditorIcons")), BUTTON_SCRIPT, false, TTR("Open Script:") + " " + script->get_path() + additional_notes); if (EditorNode::get_singleton()->get_object_custom_type_base(p_node) == script) { item->set_button_color(0, item->get_button_count(0) - 1, Color(1, 1, 1, 0.5)); } + if (script->is_tool()) { + item->set_button_color(0, item->get_button_count(0) - 1, get_theme_color(SNAME("accent_color"), SNAME("Editor"))); + } } if (p_node->is_class("CanvasItem")) { diff --git a/editor/shader_globals_editor.cpp b/editor/shader_globals_editor.cpp index 9058596830..eef0f3eae1 100644 --- a/editor/shader_globals_editor.cpp +++ b/editor/shader_globals_editor.cpp @@ -80,7 +80,7 @@ protected: } bool _set(const StringName &p_name, const Variant &p_value) { - Variant existing = RS::get_singleton()->global_shader_uniform_get(p_name); + Variant existing = RS::get_singleton()->global_shader_parameter_get(p_name); if (existing.get_type() == Variant::NIL) { return false; @@ -89,9 +89,9 @@ protected: Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Set Shader Global Variable")); - undo_redo->add_do_method(RS::get_singleton(), "global_shader_uniform_set", p_name, p_value); - undo_redo->add_undo_method(RS::get_singleton(), "global_shader_uniform_set", p_name, existing); - RS::GlobalShaderUniformType type = RS::get_singleton()->global_shader_uniform_get_type(p_name); + undo_redo->add_do_method(RS::get_singleton(), "global_shader_parameter_set", p_name, p_value); + undo_redo->add_undo_method(RS::get_singleton(), "global_shader_parameter_set", p_name, existing); + RS::GlobalShaderParameterType type = RS::get_singleton()->global_shader_parameter_get_type(p_name); Dictionary gv; gv["type"] = global_var_type_names[type]; if (type >= RS::GLOBAL_VAR_TYPE_SAMPLER2D) { @@ -118,17 +118,17 @@ protected: } bool _get(const StringName &p_name, Variant &r_ret) const { - r_ret = RS::get_singleton()->global_shader_uniform_get(p_name); + r_ret = RS::get_singleton()->global_shader_parameter_get(p_name); return r_ret.get_type() != Variant::NIL; } void _get_property_list(List<PropertyInfo> *p_list) const { Vector<StringName> variables; - variables = RS::get_singleton()->global_shader_uniform_get_list(); + variables = RS::get_singleton()->global_shader_parameter_get_list(); for (int i = 0; i < variables.size(); i++) { PropertyInfo pinfo; pinfo.name = variables[i]; - switch (RS::get_singleton()->global_shader_uniform_get_type(variables[i])) { + switch (RS::get_singleton()->global_shader_parameter_get_type(variables[i])) { case RS::GLOBAL_VAR_TYPE_BOOL: { pinfo.type = Variant::BOOL; } break; @@ -242,7 +242,7 @@ public: } }; -static Variant create_var(RS::GlobalShaderUniformType p_type) { +static Variant create_var(RS::GlobalShaderParameterType p_type) { switch (p_type) { case RS::GLOBAL_VAR_TYPE_BOOL: { return false; @@ -381,8 +381,8 @@ void ShaderGlobalsEditor::_variable_added() { return; } - if (RenderingServer::get_singleton()->global_shader_uniform_get(var).get_type() != Variant::NIL) { - EditorNode::get_singleton()->show_warning(vformat(TTR("Global shader uniform '%s' already exists'"), var)); + if (RenderingServer::get_singleton()->global_shader_parameter_get(var).get_type() != Variant::NIL) { + EditorNode::get_singleton()->show_warning(vformat(TTR("Global shader parameter '%s' already exists'"), var)); return; } @@ -396,11 +396,11 @@ void ShaderGlobalsEditor::_variable_added() { Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo(); - Variant value = create_var(RS::GlobalShaderUniformType(variable_type->get_selected())); + Variant value = create_var(RS::GlobalShaderParameterType(variable_type->get_selected())); - undo_redo->create_action(TTR("Add Shader Global Uniform")); - undo_redo->add_do_method(RS::get_singleton(), "global_shader_uniform_add", var, RS::GlobalShaderUniformType(variable_type->get_selected()), value); - undo_redo->add_undo_method(RS::get_singleton(), "global_shader_uniform_remove", var); + undo_redo->create_action(TTR("Add Shader Global Parameter")); + undo_redo->add_do_method(RS::get_singleton(), "global_shader_parameter_add", var, RS::GlobalShaderParameterType(variable_type->get_selected()), value); + undo_redo->add_undo_method(RS::get_singleton(), "global_shader_parameter_remove", var); Dictionary gv; gv["type"] = global_var_type_names[variable_type->get_selected()]; gv["value"] = value; @@ -415,9 +415,9 @@ void ShaderGlobalsEditor::_variable_added() { void ShaderGlobalsEditor::_variable_deleted(const String &p_variable) { Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo(); - undo_redo->create_action(TTR("Add Shader Global Uniform")); - undo_redo->add_do_method(RS::get_singleton(), "global_shader_uniform_remove", p_variable); - undo_redo->add_undo_method(RS::get_singleton(), "global_shader_uniform_add", p_variable, RS::get_singleton()->global_shader_uniform_get_type(p_variable), RS::get_singleton()->global_shader_uniform_get(p_variable)); + undo_redo->create_action(TTR("Add Shader Global Parameter")); + undo_redo->add_do_method(RS::get_singleton(), "global_shader_parameter_remove", p_variable); + undo_redo->add_undo_method(RS::get_singleton(), "global_shader_parameter_add", p_variable, RS::get_singleton()->global_shader_parameter_get_type(p_variable), RS::get_singleton()->global_shader_parameter_get(p_variable)); undo_redo->add_do_property(ProjectSettings::get_singleton(), "shader_globals/" + p_variable, Variant()); undo_redo->add_undo_property(ProjectSettings::get_singleton(), "shader_globals/" + p_variable, ProjectSettings::get_singleton()->get("shader_globals/" + p_variable)); diff --git a/main/main.cpp b/main/main.cpp index d0170d8093..a0d2f594ac 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -2209,7 +2209,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) { // able to load resources, load the global shader variables. // If running on editor, don't load the textures because the editor // may want to import them first. Editor will reload those later. - rendering_server->global_shader_uniforms_load_settings(!editor); + rendering_server->global_shader_parameters_load_settings(!editor); } _start_success = true; @@ -3136,7 +3136,7 @@ void Main::cleanup(bool p_force) { RenderingServer::get_singleton()->sync(); //clear global shader variables before scene and other graphics stuff are deinitialized. - rendering_server->global_shader_uniforms_clear(); + rendering_server->global_shader_parameters_clear(); if (xr_server) { // Now that we're unregistering properly in plugins we need to keep access to xr_server for a little longer diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index c2301c3e27..4a38caea52 100644 --- a/modules/gdscript/doc_classes/@GDScript.xml +++ b/modules/gdscript/doc_classes/@GDScript.xml @@ -505,7 +505,7 @@ <param index="3" name="extra_hints" type="String" default="""" /> <description> Export a numeric property as a range value. The range must be defined by [param min] and [param max], as well as an optional [param step] and a variety of extra hints. The [param step] defaults to [code]1[/code] for integer properties. For floating-point numbers this value depends on your [code]EditorSettings.interface/inspector/default_float_step[/code] setting. - If hints [code]"or_greater"[/code] and [code]"or_lesser"[/code] are provided, the editor widget will not cap the value at range boundaries. The [code]"exp"[/code] hint will make the edited values on range to change exponentially. The [code]"no_slider"[/code] hint will hide the slider element of the editor widget. + If hints [code]"or_greater"[/code] and [code]"or_less"[/code] are provided, the editor widget will not cap the value at range boundaries. The [code]"exp"[/code] hint will make the edited values on range to change exponentially. The [code]"no_slider"[/code] hint will hide the slider element of the editor widget. Hints also allow to indicate the units for the edited value. Using [code]"radians"[/code] you can specify that the actual value is in radians, but should be displayed in degrees in the Inspector dock. [code]"degrees"[/code] allows to add a degree sign as a unit suffix. Finally, a custom suffix can be provided using [code]"suffix:unit"[/code], where "unit" can be any string. See also [constant PROPERTY_HINT_RANGE]. [codeblock] @@ -514,7 +514,7 @@ @export_range(-10, 20, 0.2) var number: float @export_range(0, 100, 1, "or_greater") var power_percent - @export_range(0, 100, 1, "or_greater", "or_lesser") var health_delta + @export_range(0, 100, 1, "or_greater", "or_less") var health_delta @export_range(-3.14, 3.14, 0.001, "radians") var angle_radians @export_range(0, 360, 1, "degrees") var angle_degrees diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 4c908166df..c00036c9f0 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -763,7 +763,7 @@ static void _find_annotation_arguments(const GDScriptParser::AnnotationNode *p_a ScriptLanguage::CodeCompletionOption slider1("or_greater", ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT); slider1.insert_text = slider1.display.quote(p_quote_style); r_result.insert(slider1.display, slider1); - ScriptLanguage::CodeCompletionOption slider2("or_lesser", ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT); + ScriptLanguage::CodeCompletionOption slider2("or_less", ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT); slider2.insert_text = slider2.display.quote(p_quote_style); r_result.insert(slider2.display, slider2); ScriptLanguage::CodeCompletionOption slider3("no_slider", ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT); diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 6b6ad427a7..888cd782fb 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -686,17 +686,6 @@ void GDScriptParser::parse_class_name() { current_class->identifier = parse_identifier(); } - // TODO: Move this to annotation - if (match(GDScriptTokenizer::Token::COMMA)) { - // Icon path. - if (consume(GDScriptTokenizer::Token::LITERAL, R"(Expected class icon path string after ",".)")) { - if (previous.literal.get_type() != Variant::STRING) { - push_error(vformat(R"(Only strings can be used for the class icon path, found "%s" instead.)", Variant::get_type_name(previous.literal.get_type()))); - } - current_class->icon_path = previous.literal; - } - } - if (match(GDScriptTokenizer::Token::EXTENDS)) { // Allow extends on the same line. parse_extends(); diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp index 059ca703ab..19a8b59c6f 100644 --- a/modules/gdscript/register_types.cpp +++ b/modules/gdscript/register_types.cpp @@ -88,6 +88,8 @@ public: // TODO: Re-add compiled GDScript on export. return; } + + virtual String _get_name() const override { return "GDScript"; } }; static void _editor_init() { diff --git a/modules/gltf/doc_classes/GLTFMesh.xml b/modules/gltf/doc_classes/GLTFMesh.xml index bac351cc20..4d2df872ea 100644 --- a/modules/gltf/doc_classes/GLTFMesh.xml +++ b/modules/gltf/doc_classes/GLTFMesh.xml @@ -9,7 +9,7 @@ <members> <member name="blend_weights" type="PackedFloat32Array" setter="set_blend_weights" getter="get_blend_weights" default="PackedFloat32Array()"> </member> - <member name="instance_materials" type="Array" setter="set_instance_materials" getter="get_instance_materials" default="[]"> + <member name="instance_materials" type="Material[]" setter="set_instance_materials" getter="get_instance_materials" default="[]"> </member> <member name="mesh" type="ImporterMesh" setter="set_mesh" getter="get_mesh"> </member> diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 0ed212e21f..61af58bda7 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -435,7 +435,7 @@ Error GLTFDocument::_serialize_nodes(Ref<GLTFState> state) { node["scale"] = _vec3_to_arr(n->scale); } - if (!n->position.is_equal_approx(Vector3())) { + if (!n->position.is_zero_approx()) { node["translation"] = _vec3_to_arr(n->position); } if (n->children.size()) { @@ -5007,7 +5007,7 @@ GLTFMeshIndex GLTFDocument::_convert_mesh_to_gltf(Ref<GLTFState> state, MeshInst Ref<GLTFMesh> gltf_mesh; gltf_mesh.instantiate(); - Array instance_materials; + TypedArray<Material> instance_materials; for (int32_t surface_i = 0; surface_i < current_mesh->get_surface_count(); surface_i++) { Ref<Material> mat = current_mesh->get_surface_material(surface_i); if (p_mesh_instance->get_surface_override_material(surface_i).is_valid()) { diff --git a/modules/gltf/structures/gltf_mesh.cpp b/modules/gltf/structures/gltf_mesh.cpp index 3add8304b1..3893f56626 100644 --- a/modules/gltf/structures/gltf_mesh.cpp +++ b/modules/gltf/structures/gltf_mesh.cpp @@ -53,11 +53,11 @@ void GLTFMesh::set_mesh(Ref<ImporterMesh> p_mesh) { mesh = p_mesh; } -Array GLTFMesh::get_instance_materials() { +TypedArray<Material> GLTFMesh::get_instance_materials() { return instance_materials; } -void GLTFMesh::set_instance_materials(Array p_instance_materials) { +void GLTFMesh::set_instance_materials(TypedArray<Material> p_instance_materials) { instance_materials = p_instance_materials; } diff --git a/modules/gltf/structures/gltf_mesh.h b/modules/gltf/structures/gltf_mesh.h index dc26120b48..2fa37fd727 100644 --- a/modules/gltf/structures/gltf_mesh.h +++ b/modules/gltf/structures/gltf_mesh.h @@ -42,7 +42,7 @@ class GLTFMesh : public Resource { private: Ref<ImporterMesh> mesh; Vector<float> blend_weights; - Array instance_materials; + TypedArray<Material> instance_materials; protected: static void _bind_methods(); @@ -52,8 +52,8 @@ public: void set_mesh(Ref<ImporterMesh> p_mesh); Vector<float> get_blend_weights(); void set_blend_weights(Vector<float> p_blend_weights); - Array get_instance_materials(); - void set_instance_materials(Array p_instance_materials); + TypedArray<Material> get_instance_materials(); + void set_instance_materials(TypedArray<Material> p_instance_materials); }; #endif // GLTF_MESH_H diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index f207d4a741..8486e2c58b 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -638,7 +638,9 @@ bool GridMap::_octant_update(const OctantKey &p_key) { NavigationServer3D::get_singleton()->region_set_navigation_layers(region, navigation_layers); NavigationServer3D::get_singleton()->region_set_navmesh(region, navmesh); NavigationServer3D::get_singleton()->region_set_transform(region, get_global_transform() * nm.xform); - NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map()); + if (is_inside_tree()) { + NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map()); + } nm.region = region; // add navigation debugmesh visual instances if debug is enabled @@ -661,6 +663,12 @@ bool GridMap::_octant_update(const OctantKey &p_key) { } } +#ifdef DEBUG_ENABLED + if (bake_navigation) { + _update_octant_navigation_debug_edge_connections_mesh(p_key); + } +#endif // DEBUG_ENABLED + //update multimeshes, only if not baked if (baked_meshes.size() == 0) { for (const KeyValue<int, List<Pair<Transform3D, IndexKey>>> &E : multimesh_items) { @@ -755,6 +763,19 @@ void GridMap::_octant_enter_world(const OctantKey &p_key) { } } } + +#ifdef DEBUG_ENABLED + if (bake_navigation) { + if (!g.navigation_debug_edge_connections_instance.is_valid()) { + g.navigation_debug_edge_connections_instance = RenderingServer::get_singleton()->instance_create(); + } + if (!g.navigation_debug_edge_connections_mesh.is_valid()) { + g.navigation_debug_edge_connections_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); + } + + _update_octant_navigation_debug_edge_connections_mesh(p_key); + } +#endif // DEBUG_ENABLED } } @@ -782,6 +803,18 @@ void GridMap::_octant_exit_world(const OctantKey &p_key) { F.value.navmesh_debug_instance = RID(); } } + +#ifdef DEBUG_ENABLED + if (bake_navigation) { + if (g.navigation_debug_edge_connections_instance.is_valid()) { + RenderingServer::get_singleton()->free(g.navigation_debug_edge_connections_instance); + g.navigation_debug_edge_connections_instance = RID(); + } + if (g.navigation_debug_edge_connections_mesh.is_valid()) { + RenderingServer::get_singleton()->free(g.navigation_debug_edge_connections_mesh->get_rid()); + } + } +#endif // DEBUG_ENABLED } void GridMap::_octant_clean_up(const OctantKey &p_key) { @@ -808,6 +841,18 @@ void GridMap::_octant_clean_up(const OctantKey &p_key) { } g.navmesh_ids.clear(); +#ifdef DEBUG_ENABLED + if (bake_navigation) { + if (g.navigation_debug_edge_connections_instance.is_valid()) { + RenderingServer::get_singleton()->free(g.navigation_debug_edge_connections_instance); + g.navigation_debug_edge_connections_instance = RID(); + } + if (g.navigation_debug_edge_connections_mesh.is_valid()) { + RenderingServer::get_singleton()->free(g.navigation_debug_edge_connections_mesh->get_rid()); + } + } +#endif // DEBUG_ENABLED + //erase multimeshes for (int i = 0; i < g.multimesh_instances.size(); i++) { @@ -832,6 +877,14 @@ void GridMap::_notification(int p_what) { } } break; +#ifdef DEBUG_ENABLED + case NOTIFICATION_ENTER_TREE: { + if (bake_navigation && NavigationServer3D::get_singleton()->get_debug_enabled()) { + _update_navigation_debug_edge_connections(); + } + } break; +#endif // DEBUG_ENABLED + case NOTIFICATION_TRANSFORM_CHANGED: { Transform3D new_xform = get_global_transform(); if (new_xform == last_transform) { @@ -1231,12 +1284,136 @@ RID GridMap::get_bake_mesh_instance(int p_idx) { GridMap::GridMap() { set_notify_transform(true); +#ifdef DEBUG_ENABLED + NavigationServer3D::get_singleton_mut()->connect("map_changed", callable_mp(this, &GridMap::_navigation_map_changed)); + NavigationServer3D::get_singleton_mut()->connect("navigation_debug_changed", callable_mp(this, &GridMap::_update_navigation_debug_edge_connections)); +#endif // DEBUG_ENABLED +} + +#ifdef DEBUG_ENABLED +void GridMap::_update_navigation_debug_edge_connections() { + if (bake_navigation) { + for (const KeyValue<OctantKey, Octant *> &E : octant_map) { + _update_octant_navigation_debug_edge_connections_mesh(E.key); + } + } } +void GridMap::_navigation_map_changed(RID p_map) { + if (bake_navigation && is_inside_tree() && p_map == get_world_3d()->get_navigation_map()) { + _update_navigation_debug_edge_connections(); + } +} +#endif // DEBUG_ENABLED + GridMap::~GridMap() { if (!mesh_library.is_null()) { mesh_library->unregister_owner(this); } clear(); +#ifdef DEBUG_ENABLED + NavigationServer3D::get_singleton_mut()->disconnect("map_changed", callable_mp(this, &GridMap::_navigation_map_changed)); + NavigationServer3D::get_singleton_mut()->disconnect("navigation_debug_changed", callable_mp(this, &GridMap::_update_navigation_debug_edge_connections)); +#endif // DEBUG_ENABLED +} + +#ifdef DEBUG_ENABLED +void GridMap::_update_octant_navigation_debug_edge_connections_mesh(const OctantKey &p_key) { + ERR_FAIL_COND(!octant_map.has(p_key)); + Octant &g = *octant_map[p_key]; + + if (!NavigationServer3D::get_singleton()->get_debug_enabled()) { + if (g.navigation_debug_edge_connections_instance.is_valid()) { + RS::get_singleton()->instance_set_visible(g.navigation_debug_edge_connections_instance, false); + } + return; + } + + if (!is_inside_tree()) { + return; + } + + if (!bake_navigation) { + if (g.navigation_debug_edge_connections_instance.is_valid()) { + RS::get_singleton()->instance_set_visible(g.navigation_debug_edge_connections_instance, false); + } + return; + } + + if (!g.navigation_debug_edge_connections_instance.is_valid()) { + g.navigation_debug_edge_connections_instance = RenderingServer::get_singleton()->instance_create(); + } + + if (!g.navigation_debug_edge_connections_mesh.is_valid()) { + g.navigation_debug_edge_connections_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); + } + + g.navigation_debug_edge_connections_mesh->clear_surfaces(); + + float edge_connection_margin = NavigationServer3D::get_singleton()->map_get_edge_connection_margin(get_world_3d()->get_navigation_map()); + float half_edge_connection_margin = edge_connection_margin * 0.5; + + Vector<Vector3> vertex_array; + + for (KeyValue<IndexKey, Octant::NavMesh> &F : g.navmesh_ids) { + if (cell_map.has(F.key) && F.value.region.is_valid()) { + int connections_count = NavigationServer3D::get_singleton()->region_get_connections_count(F.value.region); + if (connections_count == 0) { + continue; + } + + for (int i = 0; i < connections_count; i++) { + Vector3 connection_pathway_start = NavigationServer3D::get_singleton()->region_get_connection_pathway_start(F.value.region, i); + Vector3 connection_pathway_end = NavigationServer3D::get_singleton()->region_get_connection_pathway_end(F.value.region, i); + + Vector3 direction_start_end = connection_pathway_start.direction_to(connection_pathway_end); + Vector3 direction_end_start = connection_pathway_end.direction_to(connection_pathway_start); + + Vector3 start_right_dir = direction_start_end.cross(Vector3(0, 1, 0)); + Vector3 start_left_dir = -start_right_dir; + + Vector3 end_right_dir = direction_end_start.cross(Vector3(0, 1, 0)); + Vector3 end_left_dir = -end_right_dir; + + Vector3 left_start_pos = connection_pathway_start + (start_left_dir * half_edge_connection_margin); + Vector3 right_start_pos = connection_pathway_start + (start_right_dir * half_edge_connection_margin); + Vector3 left_end_pos = connection_pathway_end + (end_right_dir * half_edge_connection_margin); + Vector3 right_end_pos = connection_pathway_end + (end_left_dir * half_edge_connection_margin); + + vertex_array.push_back(right_end_pos); + vertex_array.push_back(left_start_pos); + vertex_array.push_back(right_start_pos); + + vertex_array.push_back(left_end_pos); + vertex_array.push_back(right_end_pos); + vertex_array.push_back(right_start_pos); + } + } + } + + if (vertex_array.size() == 0) { + return; + } + + Ref<StandardMaterial3D> edge_connections_material = NavigationServer3D::get_singleton_mut()->get_debug_navigation_edge_connections_material(); + + Array mesh_array; + mesh_array.resize(Mesh::ARRAY_MAX); + mesh_array[Mesh::ARRAY_VERTEX] = vertex_array; + + g.navigation_debug_edge_connections_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, mesh_array); + g.navigation_debug_edge_connections_mesh->surface_set_material(0, edge_connections_material); + + RS::get_singleton()->instance_set_base(g.navigation_debug_edge_connections_instance, g.navigation_debug_edge_connections_mesh->get_rid()); + RS::get_singleton()->instance_set_visible(g.navigation_debug_edge_connections_instance, is_visible_in_tree()); + if (is_inside_tree()) { + RS::get_singleton()->instance_set_scenario(g.navigation_debug_edge_connections_instance, get_world_3d()->get_scenario()); + } + + bool enable_edge_connections = NavigationServer3D::get_singleton()->get_debug_navigation_enable_edge_connections(); + if (!enable_edge_connections) { + RS::get_singleton()->instance_set_visible(g.navigation_debug_edge_connections_instance, false); + } } +#endif // DEBUG_ENABLED diff --git a/modules/gridmap/grid_map.h b/modules/gridmap/grid_map.h index 0ed4695fb9..f83ce68b09 100644 --- a/modules/gridmap/grid_map.h +++ b/modules/gridmap/grid_map.h @@ -117,6 +117,10 @@ class GridMap : public Node3D { HashSet<IndexKey> cells; RID collision_debug; RID collision_debug_instance; +#ifdef DEBUG_ENABLED + RID navigation_debug_edge_connections_instance; + Ref<ArrayMesh> navigation_debug_edge_connections_mesh; +#endif // DEBUG_ENABLED bool dirty = false; RID static_body; @@ -186,6 +190,11 @@ class GridMap : public Node3D { bool _octant_update(const OctantKey &p_key); void _octant_clean_up(const OctantKey &p_key); void _octant_transform(const OctantKey &p_key); +#ifdef DEBUG_ENABLED + void _update_octant_navigation_debug_edge_connections_mesh(const OctantKey &p_key); + void _navigation_map_changed(RID p_map); + void _update_navigation_debug_edge_connections(); +#endif // DEBUG_ENABLED bool awaiting_update = false; void _queue_octants_dirty(); diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ScriptBoilerplate.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ScriptBoilerplate.cs index a1667dbb8f..e43a3469ae 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ScriptBoilerplate.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ScriptBoilerplate.cs @@ -7,7 +7,7 @@ namespace Godot.SourceGenerators.Sample private NodePath _nodePath; private int _velocity; - public override void _Process(float delta) + public override void _Process(double delta) { _ = delta; diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs index 180cc3cf14..ad4fce8daa 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs @@ -117,13 +117,13 @@ namespace GodotTools.Build } } - private void IssueActivated(int idx) + private void IssueActivated(long idx) { if (idx < 0 || idx >= _issuesList.ItemCount) throw new ArgumentOutOfRangeException(nameof(idx), "Item list index out of range."); // Get correct issue idx from issue list - int issueIndex = (int)_issuesList.GetItemMetadata(idx); + int issueIndex = (int)_issuesList.GetItemMetadata((int)idx); if (issueIndex < 0 || issueIndex >= _issues.Count) throw new InvalidOperationException("Issue index out of range."); @@ -311,7 +311,7 @@ namespace GodotTools.Build Copy } - private void IssuesListContextOptionPressed(int id) + private void IssuesListContextOptionPressed(long id) { switch ((IssuesContextMenuOption)id) { @@ -336,9 +336,9 @@ namespace GodotTools.Build } } - private void IssuesListClicked(int index, Vector2 atPosition, int mouseButtonIndex) + private void IssuesListClicked(long index, Vector2 atPosition, long mouseButtonIndex) { - if (mouseButtonIndex != (int)MouseButton.Right) + if (mouseButtonIndex != (long)MouseButton.Right) { return; } diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs index d05995c495..4041026426 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs @@ -93,7 +93,7 @@ namespace GodotTools.Build private void ViewLogToggled(bool pressed) => BuildOutputView.LogVisible = pressed; - private void BuildMenuOptionPressed(int id) + private void BuildMenuOptionPressed(long id) { switch ((BuildMenuOptions)id) { @@ -175,7 +175,7 @@ namespace GodotTools.Build AddChild(BuildOutputView); } - public override void _Notification(int what) + public override void _Notification(long what) { base._Notification(what); diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs index 851a8b3689..0d2bea2363 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs @@ -67,7 +67,7 @@ namespace GodotTools.Export } } - public override void _ExportBegin(string[] features, bool isDebug, string path, int flags) + public override void _ExportBegin(string[] features, bool isDebug, string path, long flags) { base._ExportBegin(features, isDebug, path, flags); @@ -90,7 +90,7 @@ namespace GodotTools.Export } } - private void _ExportBeginImpl(string[] features, bool isDebug, string path, int flags) + private void _ExportBeginImpl(string[] features, bool isDebug, string path, long flags) { _ = flags; // Unused diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs index 994c11fa72..1cfaea3ec9 100644 --- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs +++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs @@ -111,7 +111,7 @@ namespace GodotTools _toolBarBuildButton.Show(); } - private void _MenuOptionPressed(int id) + private void _MenuOptionPressed(long id) { switch ((MenuOptions)id) { diff --git a/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs b/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs index 260d13a714..89ac8058b9 100644 --- a/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs +++ b/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs @@ -9,7 +9,7 @@ namespace GodotTools { private Timer _watchTimer; - public override void _Notification(int what) + public override void _Notification(long what) { if (what == Node.NotificationWmWindowFocusIn) { diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 0e496454a1..15a40c8ca5 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -2585,6 +2585,16 @@ const String BindingsGenerator::_get_generic_type_parameters(const TypeInterface return params; } +StringName BindingsGenerator::_get_type_name_from_meta(Variant::Type p_type, GodotTypeInfo::Metadata p_meta) { + if (p_type == Variant::INT) { + return _get_int_type_name_from_meta(p_meta); + } else if (p_type == Variant::FLOAT) { + return _get_float_type_name_from_meta(p_meta); + } else { + return Variant::get_type_name(p_type); + } +} + StringName BindingsGenerator::_get_int_type_name_from_meta(GodotTypeInfo::Metadata p_meta) { switch (p_meta) { case GodotTypeInfo::METADATA_INT_IS_INT8: @@ -2612,8 +2622,8 @@ StringName BindingsGenerator::_get_int_type_name_from_meta(GodotTypeInfo::Metada return "ulong"; break; default: - // Assume INT32 - return "int"; + // Assume INT64 + return "long"; } } @@ -2626,12 +2636,8 @@ StringName BindingsGenerator::_get_float_type_name_from_meta(GodotTypeInfo::Meta return "double"; break; default: - // Assume real_t (float or double depending of REAL_T_IS_DOUBLE) -#ifdef REAL_T_IS_DOUBLE + // Assume FLOAT64 return "double"; -#else - return "float"; -#endif } } @@ -2922,13 +2928,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() { } else if (return_info.type == Variant::NIL) { imethod.return_type.cname = name_cache.type_void; } else { - if (return_info.type == Variant::INT) { - imethod.return_type.cname = _get_int_type_name_from_meta(m ? m->get_argument_meta(-1) : GodotTypeInfo::METADATA_NONE); - } else if (return_info.type == Variant::FLOAT) { - imethod.return_type.cname = _get_float_type_name_from_meta(m ? m->get_argument_meta(-1) : GodotTypeInfo::METADATA_NONE); - } else { - imethod.return_type.cname = Variant::get_type_name(return_info.type); - } + imethod.return_type.cname = _get_type_name_from_meta(return_info.type, m ? m->get_argument_meta(-1) : GodotTypeInfo::METADATA_NONE); } for (int i = 0; i < argc; i++) { @@ -2952,13 +2952,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() { } else if (arginfo.type == Variant::NIL) { iarg.type.cname = name_cache.type_Variant; } else { - if (arginfo.type == Variant::INT) { - iarg.type.cname = _get_int_type_name_from_meta(m ? m->get_argument_meta(i) : GodotTypeInfo::METADATA_NONE); - } else if (arginfo.type == Variant::FLOAT) { - iarg.type.cname = _get_float_type_name_from_meta(m ? m->get_argument_meta(i) : GodotTypeInfo::METADATA_NONE); - } else { - iarg.type.cname = Variant::get_type_name(arginfo.type); - } + iarg.type.cname = _get_type_name_from_meta(arginfo.type, m ? m->get_argument_meta(i) : GodotTypeInfo::METADATA_NONE); } iarg.name = escape_csharp_keyword(snake_to_camel_case(iarg.name)); @@ -3060,13 +3054,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() { } else if (arginfo.type == Variant::NIL) { iarg.type.cname = name_cache.type_Variant; } else { - if (arginfo.type == Variant::INT) { - iarg.type.cname = _get_int_type_name_from_meta(GodotTypeInfo::METADATA_NONE); - } else if (arginfo.type == Variant::FLOAT) { - iarg.type.cname = _get_float_type_name_from_meta(GodotTypeInfo::METADATA_NONE); - } else { - iarg.type.cname = Variant::get_type_name(arginfo.type); - } + iarg.type.cname = _get_type_name_from_meta(arginfo.type, GodotTypeInfo::METADATA_NONE); } iarg.name = escape_csharp_keyword(snake_to_camel_case(iarg.name)); diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h index c1295385dc..a479c44368 100644 --- a/modules/mono/editor/bindings_generator.h +++ b/modules/mono/editor/bindings_generator.h @@ -703,6 +703,7 @@ class BindingsGenerator { const String _get_generic_type_parameters(const TypeInterface &p_itype, const List<TypeReference> &p_generic_type_parameters); + StringName _get_type_name_from_meta(Variant::Type p_type, GodotTypeInfo::Metadata p_meta); StringName _get_int_type_name_from_meta(GodotTypeInfo::Metadata p_meta); StringName _get_float_type_name_from_meta(GodotTypeInfo::Metadata p_meta); diff --git a/modules/mono/editor/script_templates/CharacterBody2D/basic_movement.cs b/modules/mono/editor/script_templates/CharacterBody2D/basic_movement.cs index 1f5ea7532d..fbad482cf6 100644 --- a/modules/mono/editor/script_templates/CharacterBody2D/basic_movement.cs +++ b/modules/mono/editor/script_templates/CharacterBody2D/basic_movement.cs @@ -11,13 +11,13 @@ public partial class _CLASS_ : _BASE_ // Get the gravity from the project settings to be synced with RigidBody nodes. public float gravity = ProjectSettings.GetSetting("physics/2d/default_gravity").AsSingle(); - public override void _PhysicsProcess(float delta) + public override void _PhysicsProcess(double delta) { Vector2 velocity = Velocity; // Add the gravity. if (!IsOnFloor()) - velocity.y += gravity * delta; + velocity.y += gravity * (float)delta; // Handle Jump. if (Input.IsActionJustPressed("ui_accept") && IsOnFloor()) diff --git a/modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs b/modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs index 4e978b7549..abed246a1e 100644 --- a/modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs +++ b/modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs @@ -11,17 +11,17 @@ public partial class _CLASS_ : _BASE_ // Get the gravity from the project settings to be synced with RigidBody nodes. public float gravity = ProjectSettings.GetSetting("physics/3d/default_gravity").AsSingle(); - public override void _PhysicsProcess(float delta) + public override void _PhysicsProcess(double delta) { Vector3 velocity = Velocity; // Add the gravity. if (!IsOnFloor()) - velocity.y -= gravity * delta; + velocity.y -= gravity * (float)delta; // Handle Jump. if (Input.IsActionJustPressed("ui_accept") && IsOnFloor()) - velocity.y = JumpVelocity; + velocity.y = JumpVelocity; // Get the input direction and handle the movement/deceleration. // As good practice, you should replace UI actions with custom gameplay actions. diff --git a/modules/mono/editor/script_templates/Node/default.cs b/modules/mono/editor/script_templates/Node/default.cs index 4c86d1666f..74ece028fc 100644 --- a/modules/mono/editor/script_templates/Node/default.cs +++ b/modules/mono/editor/script_templates/Node/default.cs @@ -11,7 +11,7 @@ public partial class _CLASS_ : _BASE_ } // Called every frame. 'delta' is the elapsed time since the previous frame. - public override void _Process(float delta) + public override void _Process(double delta) { } } diff --git a/modules/mono/editor/script_templates/VisualShaderNodeCustom/basic.cs b/modules/mono/editor/script_templates/VisualShaderNodeCustom/basic.cs index bb482e0d6a..cd335934db 100644 --- a/modules/mono/editor/script_templates/VisualShaderNodeCustom/basic.cs +++ b/modules/mono/editor/script_templates/VisualShaderNodeCustom/basic.cs @@ -20,37 +20,37 @@ public partial class VisualShaderNode_CLASS_ : _BASE_ return ""; } - public override int _GetReturnIconType() + public override long _GetReturnIconType() { return 0; } - public override int _GetInputPortCount() + public override long _GetInputPortCount() { return 0; } - public override string _GetInputPortName(int port) + public override string _GetInputPortName(long port) { return ""; } - public override int _GetInputPortType(int port) + public override long _GetInputPortType(long port) { return 0; } - public override int _GetOutputPortCount() + public override long _GetOutputPortCount() { return 1; } - public override string _GetOutputPortName(int port) + public override string _GetOutputPortName(long port) { return "result"; } - public override int _GetOutputPortType(int port) + public override long _GetOutputPortType(long port) { return 0; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs index 33d8aef1a9..3483a04c83 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs @@ -333,14 +333,14 @@ namespace Godot /// <param name="to">The destination color for interpolation.</param> /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> /// <returns>The resulting color of the interpolation.</returns> - public Color Lerp(Color to, float weight) + public Color Lerp(Color to, real_t weight) { return new Color ( - Mathf.Lerp(r, to.r, weight), - Mathf.Lerp(g, to.g, weight), - Mathf.Lerp(b, to.b, weight), - Mathf.Lerp(a, to.a, weight) + (float)Mathf.Lerp(r, to.r, weight), + (float)Mathf.Lerp(g, to.g, weight), + (float)Mathf.Lerp(b, to.b, weight), + (float)Mathf.Lerp(a, to.a, weight) ); } @@ -355,10 +355,10 @@ namespace Godot { return new Color ( - Mathf.Lerp(r, to.r, weight.r), - Mathf.Lerp(g, to.g, weight.g), - Mathf.Lerp(b, to.b, weight.b), - Mathf.Lerp(a, to.a, weight.a) + (float)Mathf.Lerp(r, to.r, weight.r), + (float)Mathf.Lerp(g, to.g, weight.g), + (float)Mathf.Lerp(b, to.b, weight.b), + (float)Mathf.Lerp(a, to.a, weight.a) ); } diff --git a/modules/navigation/godot_navigation_server.cpp b/modules/navigation/godot_navigation_server.cpp index 4191e46f62..9e5d666a51 100644 --- a/modules/navigation/godot_navigation_server.cpp +++ b/modules/navigation/godot_navigation_server.cpp @@ -210,6 +210,20 @@ real_t GodotNavigationServer::map_get_edge_connection_margin(RID p_map) const { return map->get_edge_connection_margin(); } +COMMAND_2(map_set_link_connection_radius, RID, p_map, real_t, p_connection_radius) { + NavMap *map = map_owner.get_or_null(p_map); + ERR_FAIL_COND(map == nullptr); + + map->set_link_connection_radius(p_connection_radius); +} + +real_t GodotNavigationServer::map_get_link_connection_radius(RID p_map) const { + const NavMap *map = map_owner.get_or_null(p_map); + ERR_FAIL_COND_V(map == nullptr, 0); + + return map->get_link_connection_radius(); +} + Vector<Vector3> GodotNavigationServer::map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_navigation_layers) const { const NavMap *map = map_owner.get_or_null(p_map); ERR_FAIL_COND_V(map == nullptr, Vector<Vector3>()); @@ -245,6 +259,20 @@ RID GodotNavigationServer::map_get_closest_point_owner(RID p_map, const Vector3 return map->get_closest_point_owner(p_point); } +TypedArray<RID> GodotNavigationServer::map_get_links(RID p_map) const { + TypedArray<RID> link_rids; + const NavMap *map = map_owner.get_or_null(p_map); + ERR_FAIL_COND_V(map == nullptr, link_rids); + + const LocalVector<NavLink *> links = map->get_links(); + link_rids.resize(links.size()); + + for (uint32_t i = 0; i < links.size(); i++) { + link_rids[i] = links[i]->get_self(); + } + return link_rids; +} + TypedArray<RID> GodotNavigationServer::map_get_regions(RID p_map) const { TypedArray<RID> regions_rids; const NavMap *map = map_owner.get_or_null(p_map); @@ -417,6 +445,131 @@ Vector3 GodotNavigationServer::region_get_connection_pathway_end(RID p_region, i return region->get_connection_pathway_end(p_connection_id); } +RID GodotNavigationServer::link_create() const { + GodotNavigationServer *mut_this = const_cast<GodotNavigationServer *>(this); + MutexLock lock(mut_this->operations_mutex); + RID rid = link_owner.make_rid(); + NavLink *link = link_owner.get_or_null(rid); + link->set_self(rid); + return rid; +} + +COMMAND_2(link_set_map, RID, p_link, RID, p_map) { + NavLink *link = link_owner.get_or_null(p_link); + ERR_FAIL_COND(link == nullptr); + + if (link->get_map() != nullptr) { + if (link->get_map()->get_self() == p_map) { + return; // Pointless + } + + link->get_map()->remove_link(link); + link->set_map(nullptr); + } + + if (p_map.is_valid()) { + NavMap *map = map_owner.get_or_null(p_map); + ERR_FAIL_COND(map == nullptr); + + map->add_link(link); + link->set_map(map); + } +} + +RID GodotNavigationServer::link_get_map(const RID p_link) const { + const NavLink *link = link_owner.get_or_null(p_link); + ERR_FAIL_COND_V(link == nullptr, RID()); + + if (link->get_map()) { + return link->get_map()->get_self(); + } + return RID(); +} + +COMMAND_2(link_set_bidirectional, RID, p_link, bool, p_bidirectional) { + NavLink *link = link_owner.get_or_null(p_link); + ERR_FAIL_COND(link == nullptr); + + link->set_bidirectional(p_bidirectional); +} + +bool GodotNavigationServer::link_is_bidirectional(RID p_link) const { + const NavLink *link = link_owner.get_or_null(p_link); + ERR_FAIL_COND_V(link == nullptr, false); + + return link->is_bidirectional(); +} + +COMMAND_2(link_set_navigation_layers, RID, p_link, uint32_t, p_navigation_layers) { + NavLink *link = link_owner.get_or_null(p_link); + ERR_FAIL_COND(link == nullptr); + + link->set_navigation_layers(p_navigation_layers); +} + +uint32_t GodotNavigationServer::link_get_navigation_layers(const RID p_link) const { + const NavLink *link = link_owner.get_or_null(p_link); + ERR_FAIL_COND_V(link == nullptr, 0); + + return link->get_navigation_layers(); +} + +COMMAND_2(link_set_start_location, RID, p_link, Vector3, p_location) { + NavLink *link = link_owner.get_or_null(p_link); + ERR_FAIL_COND(link == nullptr); + + link->set_start_location(p_location); +} + +Vector3 GodotNavigationServer::link_get_start_location(RID p_link) const { + const NavLink *link = link_owner.get_or_null(p_link); + ERR_FAIL_COND_V(link == nullptr, Vector3()); + + return link->get_start_location(); +} + +COMMAND_2(link_set_end_location, RID, p_link, Vector3, p_location) { + NavLink *link = link_owner.get_or_null(p_link); + ERR_FAIL_COND(link == nullptr); + + link->set_end_location(p_location); +} + +Vector3 GodotNavigationServer::link_get_end_location(RID p_link) const { + const NavLink *link = link_owner.get_or_null(p_link); + ERR_FAIL_COND_V(link == nullptr, Vector3()); + + return link->get_end_location(); +} + +COMMAND_2(link_set_enter_cost, RID, p_link, real_t, p_enter_cost) { + NavLink *link = link_owner.get_or_null(p_link); + ERR_FAIL_COND(link == nullptr); + + link->set_enter_cost(p_enter_cost); +} + +real_t GodotNavigationServer::link_get_enter_cost(const RID p_link) const { + const NavLink *link = link_owner.get_or_null(p_link); + ERR_FAIL_COND_V(link == nullptr, 0); + + return link->get_enter_cost(); +} + +COMMAND_2(link_set_travel_cost, RID, p_link, real_t, p_travel_cost) { + NavLink *link = link_owner.get_or_null(p_link); + ERR_FAIL_COND(link == nullptr); + + link->set_travel_cost(p_travel_cost); +} + +real_t GodotNavigationServer::link_get_travel_cost(const RID p_link) const { + const NavLink *link = link_owner.get_or_null(p_link); + ERR_FAIL_COND_V(link == nullptr, 0); + + return link->get_travel_cost(); +} + RID GodotNavigationServer::agent_create() const { GodotNavigationServer *mut_this = const_cast<GodotNavigationServer *>(this); MutexLock lock(mut_this->operations_mutex); @@ -549,6 +702,13 @@ COMMAND_1(free, RID, p_object) { regions[i]->set_map(nullptr); } + // Removes any assigned links + LocalVector<NavLink *> links = map->get_links(); + for (uint32_t i = 0; i < links.size(); i++) { + map->remove_link(links[i]); + links[i]->set_map(nullptr); + } + // Remove any assigned agent LocalVector<RvoAgent *> agents = map->get_agents(); for (uint32_t i = 0; i < agents.size(); i++) { @@ -572,6 +732,17 @@ COMMAND_1(free, RID, p_object) { region_owner.free(p_object); + } else if (link_owner.owns(p_object)) { + NavLink *link = link_owner.get_or_null(p_object); + + // Removes this link from the map if assigned + if (link->get_map() != nullptr) { + link->get_map()->remove_link(link); + link->set_map(nullptr); + } + + link_owner.free(p_object); + } else if (agent_owner.owns(p_object)) { RvoAgent *agent = agent_owner.get_or_null(p_object); diff --git a/modules/navigation/godot_navigation_server.h b/modules/navigation/godot_navigation_server.h index 05ba46ede1..e6ef7e3bb1 100644 --- a/modules/navigation/godot_navigation_server.h +++ b/modules/navigation/godot_navigation_server.h @@ -36,6 +36,7 @@ #include "core/templates/rid_owner.h" #include "servers/navigation_server_3d.h" +#include "nav_link.h" #include "nav_map.h" #include "nav_region.h" #include "rvo_agent.h" @@ -71,6 +72,7 @@ class GodotNavigationServer : public NavigationServer3D { LocalVector<SetCommand *> commands; + mutable RID_Owner<NavLink> link_owner; mutable RID_Owner<NavMap> map_owner; mutable RID_Owner<NavRegion> region_owner; mutable RID_Owner<RvoAgent> agent_owner; @@ -100,6 +102,9 @@ public: COMMAND_2(map_set_edge_connection_margin, RID, p_map, real_t, p_connection_margin); virtual real_t map_get_edge_connection_margin(RID p_map) const override; + COMMAND_2(map_set_link_connection_radius, RID, p_map, real_t, p_connection_radius); + virtual real_t map_get_link_connection_radius(RID p_map) const override; + virtual Vector<Vector3> map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_navigation_layers = 1) const override; virtual Vector3 map_get_closest_point_to_segment(RID p_map, const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision = false) const override; @@ -107,6 +112,7 @@ public: virtual Vector3 map_get_closest_point_normal(RID p_map, const Vector3 &p_point) const override; virtual RID map_get_closest_point_owner(RID p_map, const Vector3 &p_point) const override; + virtual TypedArray<RID> map_get_links(RID p_map) const override; virtual TypedArray<RID> map_get_regions(RID p_map) const override; virtual TypedArray<RID> map_get_agents(RID p_map) const override; @@ -132,6 +138,22 @@ public: virtual Vector3 region_get_connection_pathway_start(RID p_region, int p_connection_id) const override; virtual Vector3 region_get_connection_pathway_end(RID p_region, int p_connection_id) const override; + virtual RID link_create() const override; + COMMAND_2(link_set_map, RID, p_link, RID, p_map); + virtual RID link_get_map(RID p_link) const override; + COMMAND_2(link_set_bidirectional, RID, p_link, bool, p_bidirectional); + virtual bool link_is_bidirectional(RID p_link) const override; + COMMAND_2(link_set_navigation_layers, RID, p_link, uint32_t, p_navigation_layers); + virtual uint32_t link_get_navigation_layers(RID p_link) const override; + COMMAND_2(link_set_start_location, RID, p_link, Vector3, p_location); + virtual Vector3 link_get_start_location(RID p_link) const override; + COMMAND_2(link_set_end_location, RID, p_link, Vector3, p_location); + virtual Vector3 link_get_end_location(RID p_link) const override; + COMMAND_2(link_set_enter_cost, RID, p_link, real_t, p_enter_cost); + virtual real_t link_get_enter_cost(RID p_link) const override; + COMMAND_2(link_set_travel_cost, RID, p_link, real_t, p_travel_cost); + virtual real_t link_get_travel_cost(RID p_link) const override; + virtual RID agent_create() const override; COMMAND_2(agent_set_map, RID, p_agent, RID, p_map); virtual RID agent_get_map(RID p_agent) const override; diff --git a/modules/navigation/nav_base.h b/modules/navigation/nav_base.h new file mode 100644 index 0000000000..6dfaaf9af4 --- /dev/null +++ b/modules/navigation/nav_base.h @@ -0,0 +1,56 @@ +/*************************************************************************/ +/* nav_base.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef NAV_BASE_H +#define NAV_BASE_H + +#include "nav_rid.h" +#include "nav_utils.h" + +class NavMap; + +class NavBase : public NavRid { +protected: + uint32_t navigation_layers = 1; + float enter_cost = 0.0; + float travel_cost = 1.0; + +public: + void set_navigation_layers(uint32_t p_navigation_layers) { navigation_layers = p_navigation_layers; } + uint32_t get_navigation_layers() const { return navigation_layers; } + + void set_enter_cost(float p_enter_cost) { enter_cost = MAX(p_enter_cost, 0.0); } + float get_enter_cost() const { return enter_cost; } + + void set_travel_cost(float p_travel_cost) { travel_cost = MAX(p_travel_cost, 0.0); } + float get_travel_cost() const { return travel_cost; } +}; + +#endif // NAV_BASE_H diff --git a/modules/navigation/nav_link.cpp b/modules/navigation/nav_link.cpp new file mode 100644 index 0000000000..828b131ec6 --- /dev/null +++ b/modules/navigation/nav_link.cpp @@ -0,0 +1,60 @@ +/*************************************************************************/ +/* nav_link.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "nav_link.h" + +#include "nav_map.h" + +void NavLink::set_map(NavMap *p_map) { + map = p_map; + link_dirty = true; +} + +void NavLink::set_bidirectional(bool p_bidirectional) { + bidirectional = p_bidirectional; + link_dirty = true; +} + +void NavLink::set_start_location(const Vector3 p_location) { + start_location = p_location; + link_dirty = true; +} + +void NavLink::set_end_location(const Vector3 p_location) { + end_location = p_location; + link_dirty = true; +} + +bool NavLink::check_dirty() { + const bool was_dirty = link_dirty; + + link_dirty = false; + return was_dirty; +} diff --git a/modules/navigation/nav_link.h b/modules/navigation/nav_link.h new file mode 100644 index 0000000000..8d57f076c0 --- /dev/null +++ b/modules/navigation/nav_link.h @@ -0,0 +1,69 @@ +/*************************************************************************/ +/* nav_link.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef NAV_LINK_H +#define NAV_LINK_H + +#include "nav_base.h" +#include "nav_utils.h" + +class NavLink : public NavBase { + NavMap *map = nullptr; + bool bidirectional = true; + Vector3 start_location = Vector3(); + Vector3 end_location = Vector3(); + + bool link_dirty = true; + +public: + void set_map(NavMap *p_map); + NavMap *get_map() const { + return map; + } + + void set_bidirectional(bool p_bidirectional); + bool is_bidirectional() const { + return bidirectional; + } + + void set_start_location(Vector3 p_location); + Vector3 get_start_location() const { + return start_location; + } + + void set_end_location(Vector3 p_location); + Vector3 get_end_location() const { + return end_location; + } + + bool check_dirty(); +}; + +#endif // NAV_LINK_H diff --git a/modules/navigation/nav_map.cpp b/modules/navigation/nav_map.cpp index 49029b5513..100db9bc82 100644 --- a/modules/navigation/nav_map.cpp +++ b/modules/navigation/nav_map.cpp @@ -31,6 +31,7 @@ #include "nav_map.h" #include "core/object/worker_thread_pool.h" +#include "nav_link.h" #include "nav_region.h" #include "rvo_agent.h" #include <algorithm> @@ -52,6 +53,11 @@ void NavMap::set_edge_connection_margin(float p_edge_connection_margin) { regenerate_links = true; } +void NavMap::set_link_connection_radius(float p_link_connection_radius) { + link_connection_radius = p_link_connection_radius; + regenerate_links = true; +} + gd::PointKey NavMap::get_point_key(const Vector3 &p_pos) const { const int x = int(Math::floor(p_pos.x / cell_size)); const int y = int(Math::floor(p_pos.y / cell_size)); @@ -158,17 +164,17 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p continue; } - float region_enter_cost = 0.0; - float region_travel_cost = least_cost_poly->poly->owner->get_travel_cost(); + float poly_enter_cost = 0.0; + float poly_travel_cost = least_cost_poly->poly->owner->get_travel_cost(); - if (prev_least_cost_poly != nullptr && !(prev_least_cost_poly->poly->owner->get_self() == least_cost_poly->poly->owner->get_self())) { - region_enter_cost = least_cost_poly->poly->owner->get_enter_cost(); + if (prev_least_cost_poly != nullptr && (prev_least_cost_poly->poly->owner->get_self() != least_cost_poly->poly->owner->get_self())) { + poly_enter_cost = least_cost_poly->poly->owner->get_enter_cost(); } prev_least_cost_poly = least_cost_poly; Vector3 pathway[2] = { connection.pathway_start, connection.pathway_end }; const Vector3 new_entry = Geometry3D::get_closest_point_to_segment(least_cost_poly->entry, pathway); - const float new_distance = (least_cost_poly->entry.distance_to(new_entry) * region_travel_cost) + region_enter_cost + least_cost_poly->traveled_distance; + const float new_distance = (least_cost_poly->entry.distance_to(new_entry) * poly_travel_cost) + poly_enter_cost + least_cost_poly->traveled_distance; int64_t already_visited_polygon_index = navigation_polys.find(gd::NavigationPoly(connection.polygon)); @@ -360,10 +366,15 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p // Add mid points int np_id = least_cost_id; while (np_id != -1 && navigation_polys[np_id].back_navigation_poly_id != -1) { - int prev = navigation_polys[np_id].back_navigation_edge; - int prev_n = (navigation_polys[np_id].back_navigation_edge + 1) % navigation_polys[np_id].poly->points.size(); - Vector3 point = (navigation_polys[np_id].poly->points[prev].pos + navigation_polys[np_id].poly->points[prev_n].pos) * 0.5; - path.push_back(point); + if (navigation_polys[np_id].back_navigation_edge != -1) { + int prev = navigation_polys[np_id].back_navigation_edge; + int prev_n = (navigation_polys[np_id].back_navigation_edge + 1) % navigation_polys[np_id].poly->points.size(); + Vector3 point = (navigation_polys[np_id].poly->points[prev].pos + navigation_polys[np_id].poly->points[prev_n].pos) * 0.5; + path.push_back(point); + } else { + path.push_back(navigation_polys[np_id].entry); + } + np_id = navigation_polys[np_id].back_navigation_poly_id; } @@ -475,6 +486,19 @@ void NavMap::remove_region(NavRegion *p_region) { } } +void NavMap::add_link(NavLink *p_link) { + links.push_back(p_link); + regenerate_links = true; +} + +void NavMap::remove_link(NavLink *p_link) { + int64_t link_index = links.find(p_link); + if (link_index != -1) { + links.remove_at_unordered(link_index); + regenerate_links = true; + } +} + bool NavMap::has_agent(RvoAgent *agent) const { return (agents.find(agent) != -1); } @@ -526,6 +550,12 @@ void NavMap::sync() { } } + for (uint32_t l = 0; l < links.size(); l++) { + if (links[l]->check_dirty()) { + regenerate_links = true; + } + } + if (regenerate_links) { // Remove regions connections. for (uint32_t r = 0; r < regions.size(); r++) { @@ -651,7 +681,121 @@ void NavMap::sync() { free_edge.polygon->edges[free_edge.edge].connections.push_back(new_connection); // Add the connection to the region_connection map. - free_edge.polygon->owner->get_connections().push_back(new_connection); + ((NavRegion *)free_edge.polygon->owner)->get_connections().push_back(new_connection); + } + } + + uint32_t link_poly_idx = 0; + link_polygons.resize(links.size()); + + // Search for polygons within range of a nav link. + for (uint32_t l = 0; l < links.size(); l++) { + const NavLink *link = links[l]; + const Vector3 start = link->get_start_location(); + const Vector3 end = link->get_end_location(); + + gd::Polygon *closest_start_polygon = nullptr; + real_t closest_start_distance = link_connection_radius; + Vector3 closest_start_point; + + gd::Polygon *closest_end_polygon = nullptr; + real_t closest_end_distance = link_connection_radius; + Vector3 closest_end_point; + + // Create link to any polygons within the search radius of the start point. + for (uint32_t start_index = 0; start_index < polygons.size(); start_index++) { + gd::Polygon &start_poly = polygons[start_index]; + + // For each face check the distance to the start + for (uint32_t start_point_id = 2; start_point_id < start_poly.points.size(); start_point_id += 1) { + const Face3 start_face(start_poly.points[0].pos, start_poly.points[start_point_id - 1].pos, start_poly.points[start_point_id].pos); + const Vector3 start_point = start_face.get_closest_point_to(start); + const real_t start_distance = start_point.distance_to(start); + + // Pick the polygon that is within our radius and is closer than anything we've seen yet. + if (start_distance <= link_connection_radius && start_distance < closest_start_distance) { + closest_start_distance = start_distance; + closest_start_point = start_point; + closest_start_polygon = &start_poly; + } + } + } + + // Find any polygons within the search radius of the end point. + for (uint32_t end_index = 0; end_index < polygons.size(); end_index++) { + gd::Polygon &end_poly = polygons[end_index]; + + // For each face check the distance to the end + for (uint32_t end_point_id = 2; end_point_id < end_poly.points.size(); end_point_id += 1) { + const Face3 end_face(end_poly.points[0].pos, end_poly.points[end_point_id - 1].pos, end_poly.points[end_point_id].pos); + const Vector3 end_point = end_face.get_closest_point_to(end); + const real_t end_distance = end_point.distance_to(end); + + // Pick the polygon that is within our radius and is closer than anything we've seen yet. + if (end_distance <= link_connection_radius && end_distance < closest_end_distance) { + closest_end_distance = end_distance; + closest_end_point = end_point; + closest_end_polygon = &end_poly; + } + } + } + + // If we have both a start and end point, then create a synthetic polygon to route through. + if (closest_start_polygon && closest_end_polygon) { + gd::Polygon &new_polygon = link_polygons[link_poly_idx++]; + new_polygon.owner = link; + + new_polygon.edges.clear(); + new_polygon.edges.resize(4); + new_polygon.points.clear(); + new_polygon.points.reserve(4); + + // Build a set of vertices that create a thin polygon going from the start to the end point. + new_polygon.points.push_back({ closest_start_point, get_point_key(closest_start_point) }); + new_polygon.points.push_back({ closest_start_point, get_point_key(closest_start_point) }); + new_polygon.points.push_back({ closest_end_point, get_point_key(closest_end_point) }); + new_polygon.points.push_back({ closest_end_point, get_point_key(closest_end_point) }); + + Vector3 center; + for (int p = 0; p < 4; ++p) { + center += new_polygon.points[p].pos; + } + new_polygon.center = center / real_t(new_polygon.points.size()); + new_polygon.clockwise = true; + + // Setup connections to go forward in the link. + { + gd::Edge::Connection entry_connection; + entry_connection.polygon = &new_polygon; + entry_connection.edge = -1; + entry_connection.pathway_start = new_polygon.points[0].pos; + entry_connection.pathway_end = new_polygon.points[1].pos; + closest_start_polygon->edges[0].connections.push_back(entry_connection); + + gd::Edge::Connection exit_connection; + exit_connection.polygon = closest_end_polygon; + exit_connection.edge = -1; + exit_connection.pathway_start = new_polygon.points[2].pos; + exit_connection.pathway_end = new_polygon.points[3].pos; + new_polygon.edges[2].connections.push_back(exit_connection); + } + + // If the link is bi-directional, create connections from the end to the start. + if (link->is_bidirectional()) { + gd::Edge::Connection entry_connection; + entry_connection.polygon = &new_polygon; + entry_connection.edge = -1; + entry_connection.pathway_start = new_polygon.points[2].pos; + entry_connection.pathway_end = new_polygon.points[3].pos; + closest_end_polygon->edges[0].connections.push_back(entry_connection); + + gd::Edge::Connection exit_connection; + exit_connection.polygon = closest_start_polygon; + exit_connection.edge = -1; + exit_connection.pathway_start = new_polygon.points[0].pos; + exit_connection.pathway_end = new_polygon.points[1].pos; + new_polygon.edges[0].connections.push_back(exit_connection); + } } } diff --git a/modules/navigation/nav_map.h b/modules/navigation/nav_map.h index e50a1afbe9..a3da9fa727 100644 --- a/modules/navigation/nav_map.h +++ b/modules/navigation/nav_map.h @@ -40,9 +40,9 @@ #include <KdTree.h> +class NavLink; class NavRegion; class RvoAgent; -class NavRegion; class NavMap : public NavRid { /// Map Up @@ -55,11 +55,19 @@ class NavMap : public NavRid { /// This value is used to detect the near edges to connect. real_t edge_connection_margin = 0.25; + /// This value is used to limit how far links search to find polygons to connect to. + real_t link_connection_radius = 1.0; + bool regenerate_polygons = true; bool regenerate_links = true; + /// Map regions LocalVector<NavRegion *> regions; + /// Map links + LocalVector<NavLink *> links; + LocalVector<gd::Polygon> link_polygons; + /// Map polygons LocalVector<gd::Polygon> polygons; @@ -100,6 +108,11 @@ public: return edge_connection_margin; } + void set_link_connection_radius(float p_link_connection_radius); + float get_link_connection_radius() const { + return link_connection_radius; + } + gd::PointKey get_point_key(const Vector3 &p_pos) const; Vector<Vector3> get_path(Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_navigation_layers = 1) const; @@ -115,6 +128,12 @@ public: return regions; } + void add_link(NavLink *p_link); + void remove_link(NavLink *p_link); + const LocalVector<NavLink *> &get_links() const { + return links; + } + bool has_agent(RvoAgent *agent) const; void add_agent(RvoAgent *agent); void remove_agent(RvoAgent *agent); diff --git a/modules/navigation/nav_region.cpp b/modules/navigation/nav_region.cpp index 88740807eb..d43f53d1c0 100644 --- a/modules/navigation/nav_region.cpp +++ b/modules/navigation/nav_region.cpp @@ -40,14 +40,6 @@ void NavRegion::set_map(NavMap *p_map) { } } -void NavRegion::set_navigation_layers(uint32_t p_navigation_layers) { - navigation_layers = p_navigation_layers; -} - -uint32_t NavRegion::get_navigation_layers() const { - return navigation_layers; -} - void NavRegion::set_transform(Transform3D p_transform) { transform = p_transform; polygons_dirty = true; diff --git a/modules/navigation/nav_region.h b/modules/navigation/nav_region.h index c9d2d80f6c..8d2b5aa9eb 100644 --- a/modules/navigation/nav_region.h +++ b/modules/navigation/nav_region.h @@ -33,21 +33,13 @@ #include "scene/resources/navigation_mesh.h" -#include "nav_rid.h" +#include "nav_base.h" #include "nav_utils.h" -#include <vector> - -class NavMap; -class NavRegion; - -class NavRegion : public NavRid { +class NavRegion : public NavBase { NavMap *map = nullptr; Transform3D transform; Ref<NavigationMesh> mesh; - uint32_t navigation_layers = 1; - float enter_cost = 0.0; - float travel_cost = 1.0; Vector<gd::Edge::Connection> connections; bool polygons_dirty = true; @@ -67,15 +59,6 @@ public: return map; } - void set_enter_cost(float p_enter_cost) { enter_cost = MAX(p_enter_cost, 0.0); } - float get_enter_cost() const { return enter_cost; } - - void set_travel_cost(float p_travel_cost) { travel_cost = MAX(p_travel_cost, 0.0); } - float get_travel_cost() const { return travel_cost; } - - void set_navigation_layers(uint32_t p_navigation_layers); - uint32_t get_navigation_layers() const; - void set_transform(Transform3D transform); const Transform3D &get_transform() const { return transform; diff --git a/modules/navigation/nav_utils.h b/modules/navigation/nav_utils.h index 47f04b6a75..16b96dcfe9 100644 --- a/modules/navigation/nav_utils.h +++ b/modules/navigation/nav_utils.h @@ -35,9 +35,8 @@ #include "core/templates/hash_map.h" #include "core/templates/hashfuncs.h" #include "core/templates/local_vector.h" -#include <vector> -class NavRegion; +class NavBase; namespace gd { struct Polygon; @@ -79,26 +78,33 @@ struct Point { }; struct Edge { - /// This edge ID - int this_edge = -1; - /// The gateway in the edge, as, in some case, the whole edge might not be navigable. struct Connection { + /// Polygon that this connection leads to. Polygon *polygon = nullptr; + + /// Edge of the source polygon where this connection starts from. int edge = -1; + + /// Point on the edge where the gateway leading to the poly starts. Vector3 pathway_start; + + /// Point on the edge where the gateway leading to the poly ends. Vector3 pathway_end; }; + + /// Connections from this edge to other polygons. Vector<Connection> connections; }; struct Polygon { - NavRegion *owner = nullptr; + /// Navigation region or link that contains this polygon. + const NavBase *owner = nullptr; /// The points of this `Polygon` LocalVector<Point> points; - /// Are the points clockwise ? + /// Are the points clockwise? bool clockwise; /// The edges of this `Polygon` @@ -115,7 +121,7 @@ struct NavigationPoly { /// Those 4 variables are used to travel the path backwards. int back_navigation_poly_id = -1; - uint32_t back_navigation_edge = UINT32_MAX; + int back_navigation_edge = -1; Vector3 back_navigation_edge_pathway_start; Vector3 back_navigation_edge_pathway_end; diff --git a/modules/ogg/doc_classes/OggPacketSequence.xml b/modules/ogg/doc_classes/OggPacketSequence.xml index d3bd4455d8..1148b38602 100644 --- a/modules/ogg/doc_classes/OggPacketSequence.xml +++ b/modules/ogg/doc_classes/OggPacketSequence.xml @@ -17,10 +17,10 @@ </method> </methods> <members> - <member name="granule_positions" type="Array" setter="set_packet_granule_positions" getter="get_packet_granule_positions" default="[]"> + <member name="granule_positions" type="PackedInt64Array" setter="set_packet_granule_positions" getter="get_packet_granule_positions" default="PackedInt64Array()"> Contains the granule positions for each page in this packet sequence. </member> - <member name="packet_data" type="Array" setter="set_packet_data" getter="get_packet_data" default="[]"> + <member name="packet_data" type="Array[]" setter="set_packet_data" getter="get_packet_data" default="[]"> Contains the raw packets that make up this OggPacketSequence. </member> <member name="sampling_rate" type="float" setter="set_sampling_rate" getter="get_sampling_rate" default="0.0"> diff --git a/modules/ogg/ogg_packet_sequence.cpp b/modules/ogg/ogg_packet_sequence.cpp index de8bf4a087..b9e48191e1 100644 --- a/modules/ogg/ogg_packet_sequence.cpp +++ b/modules/ogg/ogg_packet_sequence.cpp @@ -41,7 +41,7 @@ void OggPacketSequence::push_page(int64_t p_granule_pos, const Vector<PackedByte data_version++; } -void OggPacketSequence::set_packet_data(const Array &p_data) { +void OggPacketSequence::set_packet_data(const TypedArray<Array> &p_data) { data_version++; // Update the data version so old playbacks know that they can't rely on us anymore. page_data.clear(); for (int page_idx = 0; page_idx < p_data.size(); page_idx++) { @@ -54,8 +54,8 @@ void OggPacketSequence::set_packet_data(const Array &p_data) { } } -Array OggPacketSequence::get_packet_data() const { - Array ret; +TypedArray<Array> OggPacketSequence::get_packet_data() const { + TypedArray<Array> ret; for (const Vector<PackedByteArray> &page : page_data) { Array page_variant; for (const PackedByteArray &packet : page) { @@ -66,7 +66,7 @@ Array OggPacketSequence::get_packet_data() const { return ret; } -void OggPacketSequence::set_packet_granule_positions(const Array &p_granule_positions) { +void OggPacketSequence::set_packet_granule_positions(const PackedInt64Array &p_granule_positions) { data_version++; // Update the data version so old playbacks know that they can't rely on us anymore. page_granule_positions.clear(); for (int page_idx = 0; page_idx < p_granule_positions.size(); page_idx++) { @@ -75,8 +75,8 @@ void OggPacketSequence::set_packet_granule_positions(const Array &p_granule_posi } } -Array OggPacketSequence::get_packet_granule_positions() const { - Array ret; +PackedInt64Array OggPacketSequence::get_packet_granule_positions() const { + PackedInt64Array ret; for (int64_t granule_pos : page_granule_positions) { ret.push_back(granule_pos); } @@ -127,8 +127,8 @@ void OggPacketSequence::_bind_methods() { ClassDB::bind_method(D_METHOD("get_length"), &OggPacketSequence::get_length); - ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "packet_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_packet_data", "get_packet_data"); - ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "granule_positions", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_packet_granule_positions", "get_packet_granule_positions"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "packet_data", PROPERTY_HINT_ARRAY_TYPE, "PackedByteArray", PROPERTY_USAGE_NO_EDITOR), "set_packet_data", "get_packet_data"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_INT64_ARRAY, "granule_positions", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_packet_granule_positions", "get_packet_granule_positions"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sampling_rate", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_sampling_rate", "get_sampling_rate"); } diff --git a/modules/ogg/ogg_packet_sequence.h b/modules/ogg/ogg_packet_sequence.h index efd3b64a39..c275f0c639 100644 --- a/modules/ogg/ogg_packet_sequence.h +++ b/modules/ogg/ogg_packet_sequence.h @@ -67,11 +67,11 @@ public: // This should be called for each page, even for pages that no packets ended on. void push_page(int64_t p_granule_pos, const Vector<PackedByteArray> &p_data); - void set_packet_data(const Array &p_data); - Array get_packet_data() const; + void set_packet_data(const TypedArray<Array> &p_data); + TypedArray<Array> get_packet_data() const; - void set_packet_granule_positions(const Array &p_granule_positions); - Array get_packet_granule_positions() const; + void set_packet_granule_positions(const PackedInt64Array &p_granule_positions); + PackedInt64Array get_packet_granule_positions() const; // Sets a sampling rate associated with this object. OggPacketSequence doesn't understand codecs, // so this value is naively stored as a convenience. diff --git a/modules/regex/doc_classes/RegExMatch.xml b/modules/regex/doc_classes/RegExMatch.xml index 5bcf070e82..31e2207d84 100644 --- a/modules/regex/doc_classes/RegExMatch.xml +++ b/modules/regex/doc_classes/RegExMatch.xml @@ -44,7 +44,7 @@ <member name="names" type="Dictionary" setter="" getter="get_names" default="{}"> A dictionary of named groups and its corresponding group number. Only groups that were matched are included. If multiple groups have the same name, that name would refer to the first matching one. </member> - <member name="strings" type="Array" setter="" getter="get_strings" default="[]"> + <member name="strings" type="PackedStringArray" setter="" getter="get_strings" default="PackedStringArray()"> An [Array] of the match and its capturing groups. </member> <member name="subject" type="String" setter="" getter="get_subject" default=""""> diff --git a/modules/regex/regex.cpp b/modules/regex/regex.cpp index b2e6ea1004..c808211d68 100644 --- a/modules/regex/regex.cpp +++ b/modules/regex/regex.cpp @@ -82,8 +82,8 @@ Dictionary RegExMatch::get_names() const { return result; } -Array RegExMatch::get_strings() const { - Array result; +PackedStringArray RegExMatch::get_strings() const { + PackedStringArray result; int size = data.size(); diff --git a/modules/regex/regex.h b/modules/regex/regex.h index 6920d2634d..ac518f16df 100644 --- a/modules/regex/regex.h +++ b/modules/regex/regex.h @@ -63,7 +63,7 @@ public: int get_group_count() const; Dictionary get_names() const; - Array get_strings() const; + PackedStringArray get_strings() const; String get_string(const Variant &p_name) const; int get_start(const Variant &p_name) const; int get_end(const Variant &p_name) const; diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index abef48e2a1..7aebeafe70 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -3823,7 +3823,7 @@ Variant TextServerAdvanced::shaped_get_span_meta(const RID &p_shaped, int64_t p_ return sd->spans[p_index].meta; } -void TextServerAdvanced::shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features) { +void TextServerAdvanced::shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features) { ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND(!sd); ERR_FAIL_INDEX(p_index, sd->spans.size()); @@ -3844,7 +3844,7 @@ void TextServerAdvanced::shaped_set_span_update_font(const RID &p_shaped, int64_ } } -bool TextServerAdvanced::shaped_text_add_string(const RID &p_shaped, const String &p_text, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features, const String &p_language, const Variant &p_meta) { +bool TextServerAdvanced::shaped_text_add_string(const RID &p_shaped, const String &p_text, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features, const String &p_language, const Variant &p_meta) { ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, false); ERR_FAIL_COND_V(p_size <= 0, false); @@ -5048,7 +5048,7 @@ _FORCE_INLINE_ void TextServerAdvanced::_add_featuers(const Dictionary &p_source } } -void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_start, int64_t p_end, hb_script_t p_script, hb_direction_t p_direction, Array p_fonts, int64_t p_span, int64_t p_fb_index) { +void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_start, int64_t p_end, hb_script_t p_script, hb_direction_t p_direction, TypedArray<RID> p_fonts, int64_t p_span, int64_t p_fb_index) { int fs = p_sd->spans[p_span].font_size; if (p_fb_index >= p_fonts.size()) { // Add fallback glyphs. diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index 02abc31c55..1db95d153b 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -407,7 +407,7 @@ class TextServerAdvanced : public TextServerExtension { int64_t _convert_pos(const ShapedTextDataAdvanced *p_sd, int64_t p_pos) const; int64_t _convert_pos_inv(const ShapedTextDataAdvanced *p_sd, int64_t p_pos) const; bool _shape_substr(ShapedTextDataAdvanced *p_new_sd, const ShapedTextDataAdvanced *p_sd, int64_t p_start, int64_t p_length) const; - void _shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_start, int64_t p_end, hb_script_t p_script, hb_direction_t p_direction, Array p_fonts, int64_t p_span, int64_t p_fb_index); + void _shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_start, int64_t p_end, hb_script_t p_script, hb_direction_t p_direction, TypedArray<RID> p_fonts, int64_t p_span, int64_t p_fb_index); Glyph _shape_single_glyph(ShapedTextDataAdvanced *p_sd, char32_t p_char, hb_script_t p_script, hb_direction_t p_direction, const RID &p_font, int64_t p_font_size); _FORCE_INLINE_ void _add_featuers(const Dictionary &p_source, Vector<hb_feature_t> &r_ftrs); @@ -656,13 +656,13 @@ public: virtual void shaped_text_set_spacing(const RID &p_shaped, SpacingType p_spacing, int64_t p_value) override; virtual int64_t shaped_text_get_spacing(const RID &p_shaped, SpacingType p_spacing) const override; - virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) override; + virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) override; virtual bool shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int64_t p_length = 1) override; virtual bool shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) override; virtual int64_t shaped_get_span_count(const RID &p_shaped) const override; virtual Variant shaped_get_span_meta(const RID &p_shaped, int64_t p_index) const override; - virtual void shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary()) override; + virtual void shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary()) override; virtual RID shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const override; virtual RID shaped_text_get_parent(const RID &p_shaped) const override; diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index 359bb056a8..4d599dbcb5 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -2792,7 +2792,7 @@ Variant TextServerFallback::shaped_get_span_meta(const RID &p_shaped, int64_t p_ return sd->spans[p_index].meta; } -void TextServerFallback::shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features) { +void TextServerFallback::shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features) { ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND(!sd); ERR_FAIL_INDEX(p_index, sd->spans.size()); @@ -2816,7 +2816,7 @@ void TextServerFallback::shaped_set_span_update_font(const RID &p_shaped, int64_ sd->valid = false; } -bool TextServerFallback::shaped_text_add_string(const RID &p_shaped, const String &p_text, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features, const String &p_language, const Variant &p_meta) { +bool TextServerFallback::shaped_text_add_string(const RID &p_shaped, const String &p_text, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features, const String &p_language, const Variant &p_meta) { ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, false); diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h index 940c57a354..cbb2fb03f2 100644 --- a/modules/text_server_fb/text_server_fb.h +++ b/modules/text_server_fb/text_server_fb.h @@ -535,13 +535,13 @@ public: virtual void shaped_text_set_spacing(const RID &p_shaped, SpacingType p_spacing, int64_t p_value) override; virtual int64_t shaped_text_get_spacing(const RID &p_shaped, SpacingType p_spacing) const override; - virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) override; + virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) override; virtual bool shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int64_t p_length = 1) override; virtual bool shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) override; virtual int64_t shaped_get_span_count(const RID &p_shaped) const override; virtual Variant shaped_get_span_meta(const RID &p_shaped, int64_t p_index) const override; - virtual void shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary()) override; + virtual void shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary()) override; virtual RID shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const override; virtual RID shaped_text_get_parent(const RID &p_shaped) const override; diff --git a/modules/webrtc/doc_classes/WebRTCDataChannelExtension.xml b/modules/webrtc/doc_classes/WebRTCDataChannelExtension.xml index 5387deaa47..a10ea25b8c 100644 --- a/modules/webrtc/doc_classes/WebRTCDataChannelExtension.xml +++ b/modules/webrtc/doc_classes/WebRTCDataChannelExtension.xml @@ -48,7 +48,7 @@ </description> </method> <method name="_get_packet" qualifiers="virtual"> - <return type="int" /> + <return type="int" enum="Error" /> <param index="0" name="r_buffer" type="const uint8_t **" /> <param index="1" name="r_buffer_size" type="int32_t*" /> <description> @@ -60,12 +60,12 @@ </description> </method> <method name="_get_ready_state" qualifiers="virtual const"> - <return type="int" /> + <return type="int" enum="WebRTCDataChannel.ChannelState" /> <description> </description> </method> <method name="_get_write_mode" qualifiers="virtual const"> - <return type="int" /> + <return type="int" enum="WebRTCDataChannel.WriteMode" /> <description> </description> </method> @@ -80,12 +80,12 @@ </description> </method> <method name="_poll" qualifiers="virtual"> - <return type="int" /> + <return type="int" enum="Error" /> <description> </description> </method> <method name="_put_packet" qualifiers="virtual"> - <return type="int" /> + <return type="int" enum="Error" /> <param index="0" name="p_buffer" type="const uint8_t*" /> <param index="1" name="p_buffer_size" type="int" /> <description> @@ -93,7 +93,7 @@ </method> <method name="_set_write_mode" qualifiers="virtual"> <return type="void" /> - <param index="0" name="p_write_mode" type="int" /> + <param index="0" name="p_write_mode" type="int" enum="WebRTCDataChannel.WriteMode" /> <description> </description> </method> diff --git a/modules/webrtc/doc_classes/WebRTCPeerConnectionExtension.xml b/modules/webrtc/doc_classes/WebRTCPeerConnectionExtension.xml index e22e939a66..3c4bf18a76 100644 --- a/modules/webrtc/doc_classes/WebRTCPeerConnectionExtension.xml +++ b/modules/webrtc/doc_classes/WebRTCPeerConnectionExtension.xml @@ -8,7 +8,7 @@ </tutorials> <methods> <method name="_add_ice_candidate" qualifiers="virtual"> - <return type="int" /> + <return type="int" enum="Error" /> <param index="0" name="p_sdp_mid_name" type="String" /> <param index="1" name="p_sdp_mline_index" type="int" /> <param index="2" name="p_sdp_name" type="String" /> @@ -28,35 +28,35 @@ </description> </method> <method name="_create_offer" qualifiers="virtual"> - <return type="int" /> + <return type="int" enum="Error" /> <description> </description> </method> <method name="_get_connection_state" qualifiers="virtual const"> - <return type="int" /> + <return type="int" enum="WebRTCPeerConnection.ConnectionState" /> <description> </description> </method> <method name="_initialize" qualifiers="virtual"> - <return type="int" /> + <return type="int" enum="Error" /> <param index="0" name="p_config" type="Dictionary" /> <description> </description> </method> <method name="_poll" qualifiers="virtual"> - <return type="int" /> + <return type="int" enum="Error" /> <description> </description> </method> <method name="_set_local_description" qualifiers="virtual"> - <return type="int" /> + <return type="int" enum="Error" /> <param index="0" name="p_type" type="String" /> <param index="1" name="p_sdp" type="String" /> <description> </description> </method> <method name="_set_remote_description" qualifiers="virtual"> - <return type="int" /> + <return type="int" enum="Error" /> <param index="0" name="p_type" type="String" /> <param index="1" name="p_sdp" type="String" /> <description> diff --git a/modules/webrtc/webrtc_data_channel_extension.cpp b/modules/webrtc/webrtc_data_channel_extension.cpp index b7ea8d22bb..4e16b77e81 100644 --- a/modules/webrtc/webrtc_data_channel_extension.cpp +++ b/modules/webrtc/webrtc_data_channel_extension.cpp @@ -56,160 +56,20 @@ void WebRTCDataChannelExtension::_bind_methods() { GDVIRTUAL_BIND(_get_buffered_amount); } -int WebRTCDataChannelExtension::get_available_packet_count() const { - int count; - if (GDVIRTUAL_CALL(_get_available_packet_count, count)) { - return count; - } - WARN_PRINT_ONCE("WebRTCDataChannelExtension::_get_available_packet_count is unimplemented!"); - return -1; -} - Error WebRTCDataChannelExtension::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { - int err; + Error err; if (GDVIRTUAL_CALL(_get_packet, r_buffer, &r_buffer_size, err)) { - return (Error)err; + return err; } WARN_PRINT_ONCE("WebRTCDataChannelExtension::_get_packet_native is unimplemented!"); return FAILED; } Error WebRTCDataChannelExtension::put_packet(const uint8_t *p_buffer, int p_buffer_size) { - int err; + Error err; if (GDVIRTUAL_CALL(_put_packet, p_buffer, p_buffer_size, err)) { - return (Error)err; + return err; } WARN_PRINT_ONCE("WebRTCDataChannelExtension::_put_packet_native is unimplemented!"); return FAILED; } - -int WebRTCDataChannelExtension::get_max_packet_size() const { - int size; - if (GDVIRTUAL_CALL(_get_max_packet_size, size)) { - return size; - } - WARN_PRINT_ONCE("WebRTCDataChannelExtension::_get_max_packet_size is unimplemented!"); - return 0; -} - -Error WebRTCDataChannelExtension::poll() { - int err; - if (GDVIRTUAL_CALL(_poll, err)) { - return (Error)err; - } - WARN_PRINT_ONCE("WebRTCDataChannelExtension::_poll is unimplemented!"); - return ERR_UNCONFIGURED; -} - -void WebRTCDataChannelExtension::close() { - if (GDVIRTUAL_CALL(_close)) { - return; - } - WARN_PRINT_ONCE("WebRTCDataChannelExtension::_close is unimplemented!"); -} - -void WebRTCDataChannelExtension::set_write_mode(WriteMode p_mode) { - if (GDVIRTUAL_CALL(_set_write_mode, p_mode)) { - return; - } - WARN_PRINT_ONCE("WebRTCDataChannelExtension::_set_write_mode is unimplemented!"); -} - -WebRTCDataChannel::WriteMode WebRTCDataChannelExtension::get_write_mode() const { - int mode; - if (GDVIRTUAL_CALL(_get_write_mode, mode)) { - return (WriteMode)mode; - } - WARN_PRINT_ONCE("WebRTCDataChannelExtension::_get_write_mode is unimplemented!"); - return WRITE_MODE_BINARY; -} - -bool WebRTCDataChannelExtension::was_string_packet() const { - bool was_string; - if (GDVIRTUAL_CALL(_was_string_packet, was_string)) { - return was_string; - } - WARN_PRINT_ONCE("WebRTCDataChannelExtension::_was_string_packet is unimplemented!"); - return false; -} - -WebRTCDataChannel::ChannelState WebRTCDataChannelExtension::get_ready_state() const { - int state; - if (GDVIRTUAL_CALL(_get_ready_state, state)) { - return (ChannelState)state; - } - WARN_PRINT_ONCE("WebRTCDataChannelExtension::_get_ready_state is unimplemented!"); - return STATE_CLOSED; -} - -String WebRTCDataChannelExtension::get_label() const { - String label; - if (GDVIRTUAL_CALL(_get_label, label)) { - return label; - } - WARN_PRINT_ONCE("WebRTCDataChannelExtension::_get_label is unimplemented!"); - return label; -} - -bool WebRTCDataChannelExtension::is_ordered() const { - bool ordered; - if (GDVIRTUAL_CALL(_is_ordered, ordered)) { - return ordered; - } - WARN_PRINT_ONCE("WebRTCDataChannelExtension::_is_ordered is unimplemented!"); - return false; -} - -int WebRTCDataChannelExtension::get_id() const { - int id; - if (GDVIRTUAL_CALL(_get_id, id)) { - return id; - } - WARN_PRINT_ONCE("WebRTCDataChannelExtension::_get_id is unimplemented!"); - return -1; -} - -int WebRTCDataChannelExtension::get_max_packet_life_time() const { - int lifetime; - if (GDVIRTUAL_CALL(_get_max_packet_life_time, lifetime)) { - return lifetime; - } - WARN_PRINT_ONCE("WebRTCDataChannelExtension::_get_max_packet_life_time is unimplemented!"); - return -1; -} - -int WebRTCDataChannelExtension::get_max_retransmits() const { - int retransmits; - if (GDVIRTUAL_CALL(_get_max_retransmits, retransmits)) { - return retransmits; - } - WARN_PRINT_ONCE("WebRTCDataChannelExtension::_get_max_retransmits is unimplemented!"); - return -1; -} - -String WebRTCDataChannelExtension::get_protocol() const { - String protocol; - if (GDVIRTUAL_CALL(_get_protocol, protocol)) { - return protocol; - } - WARN_PRINT_ONCE("WebRTCDataChannelExtension::_get_protocol is unimplemented!"); - return protocol; -} - -bool WebRTCDataChannelExtension::is_negotiated() const { - bool negotiated; - if (GDVIRTUAL_CALL(_is_negotiated, negotiated)) { - return negotiated; - } - WARN_PRINT_ONCE("WebRTCDataChannelExtension::_is_negotiated is unimplemented!"); - return false; -} - -int WebRTCDataChannelExtension::get_buffered_amount() const { - int amount; - if (GDVIRTUAL_CALL(_get_buffered_amount, amount)) { - return amount; - } - WARN_PRINT_ONCE("WebRTCDataChannelExtension::_get_buffered_amount is unimplemented!"); - return -1; -} diff --git a/modules/webrtc/webrtc_data_channel_extension.h b/modules/webrtc/webrtc_data_channel_extension.h index 83bb627815..467163ed93 100644 --- a/modules/webrtc/webrtc_data_channel_extension.h +++ b/modules/webrtc/webrtc_data_channel_extension.h @@ -33,6 +33,7 @@ #include "webrtc_data_channel.h" +#include "core/extension/ext_wrappers.gen.inc" #include "core/object/gdvirtual.gen.inc" #include "core/object/script_language.h" #include "core/variant/native_ptr.h" @@ -44,53 +45,33 @@ protected: static void _bind_methods(); public: - virtual void set_write_mode(WriteMode mode) override; - virtual WriteMode get_write_mode() const override; - virtual bool was_string_packet() const override; + EXBIND0R(Error, poll); + EXBIND0(close); - virtual ChannelState get_ready_state() const override; - virtual String get_label() const override; - virtual bool is_ordered() const override; - virtual int get_id() const override; - virtual int get_max_packet_life_time() const override; - virtual int get_max_retransmits() const override; - virtual String get_protocol() const override; - virtual bool is_negotiated() const override; - virtual int get_buffered_amount() const override; + EXBIND1(set_write_mode, WriteMode); + EXBIND0RC(WriteMode, get_write_mode); - virtual Error poll() override; - virtual void close() override; + EXBIND0RC(bool, was_string_packet); + + EXBIND0RC(ChannelState, get_ready_state); + EXBIND0RC(String, get_label); + EXBIND0RC(bool, is_ordered); + EXBIND0RC(int, get_id); + EXBIND0RC(int, get_max_packet_life_time); + EXBIND0RC(int, get_max_retransmits); + EXBIND0RC(String, get_protocol); + EXBIND0RC(bool, is_negotiated); + EXBIND0RC(int, get_buffered_amount); /** Inherited from PacketPeer: **/ - virtual int get_available_packet_count() const override; + EXBIND0RC(int, get_available_packet_count); + EXBIND0RC(int, get_max_packet_size); virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size) override; ///< buffer is GONE after next get_packet virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size) override; - virtual int get_max_packet_size() const override; - /** GDExtension **/ - GDVIRTUAL0RC(int, _get_available_packet_count); - GDVIRTUAL2R(int, _get_packet, GDNativeConstPtr<const uint8_t *>, GDNativePtr<int>); - GDVIRTUAL2R(int, _put_packet, GDNativeConstPtr<const uint8_t>, int); - GDVIRTUAL0RC(int, _get_max_packet_size); - - GDVIRTUAL0R(int, _poll); - GDVIRTUAL0(_close); - - GDVIRTUAL1(_set_write_mode, int); - GDVIRTUAL0RC(int, _get_write_mode); - - GDVIRTUAL0RC(bool, _was_string_packet); - - GDVIRTUAL0RC(int, _get_ready_state); - GDVIRTUAL0RC(String, _get_label); - GDVIRTUAL0RC(bool, _is_ordered); - GDVIRTUAL0RC(int, _get_id); - GDVIRTUAL0RC(int, _get_max_packet_life_time); - GDVIRTUAL0RC(int, _get_max_retransmits); - GDVIRTUAL0RC(String, _get_protocol); - GDVIRTUAL0RC(bool, _is_negotiated); - GDVIRTUAL0RC(int, _get_buffered_amount); + GDVIRTUAL2R(Error, _get_packet, GDNativeConstPtr<const uint8_t *>, GDNativePtr<int>); + GDVIRTUAL2R(Error, _put_packet, GDNativeConstPtr<const uint8_t>, int); WebRTCDataChannelExtension() {} }; diff --git a/modules/webrtc/webrtc_peer_connection_extension.cpp b/modules/webrtc/webrtc_peer_connection_extension.cpp index 85c04b3b19..54143e4b79 100644 --- a/modules/webrtc/webrtc_peer_connection_extension.cpp +++ b/modules/webrtc/webrtc_peer_connection_extension.cpp @@ -42,24 +42,6 @@ void WebRTCPeerConnectionExtension::_bind_methods() { GDVIRTUAL_BIND(_close); } -WebRTCPeerConnection::ConnectionState WebRTCPeerConnectionExtension::get_connection_state() const { - int state; - if (GDVIRTUAL_CALL(_get_connection_state, state)) { - return (ConnectionState)state; - } - WARN_PRINT_ONCE("WebRTCPeerConnectionExtension::_get_connection_state is unimplemented!"); - return STATE_DISCONNECTED; -} - -Error WebRTCPeerConnectionExtension::initialize(Dictionary p_config) { - int err; - if (GDVIRTUAL_CALL(_initialize, p_config, err)) { - return (Error)err; - } - WARN_PRINT_ONCE("WebRTCPeerConnectionExtension::_initialize is unimplemented!"); - return ERR_UNCONFIGURED; -} - Ref<WebRTCDataChannel> WebRTCPeerConnectionExtension::create_data_channel(String p_label, Dictionary p_options) { Object *ret = nullptr; if (GDVIRTUAL_CALL(_create_data_channel, p_label, p_options, ret)) { @@ -70,55 +52,3 @@ Ref<WebRTCDataChannel> WebRTCPeerConnectionExtension::create_data_channel(String WARN_PRINT_ONCE("WebRTCPeerConnectionExtension::_create_data_channel is unimplemented!"); return nullptr; } - -Error WebRTCPeerConnectionExtension::create_offer() { - int err; - if (GDVIRTUAL_CALL(_create_offer, err)) { - return (Error)err; - } - WARN_PRINT_ONCE("WebRTCPeerConnectionExtension::_create_offer is unimplemented!"); - return ERR_UNCONFIGURED; -} - -Error WebRTCPeerConnectionExtension::set_local_description(String p_type, String p_sdp) { - int err; - if (GDVIRTUAL_CALL(_set_local_description, p_type, p_sdp, err)) { - return (Error)err; - } - WARN_PRINT_ONCE("WebRTCPeerConnectionExtension::_set_local_description is unimplemented!"); - return ERR_UNCONFIGURED; -} - -Error WebRTCPeerConnectionExtension::set_remote_description(String p_type, String p_sdp) { - int err; - if (GDVIRTUAL_CALL(_set_remote_description, p_type, p_sdp, err)) { - return (Error)err; - } - WARN_PRINT_ONCE("WebRTCPeerConnectionExtension::_set_remote_description is unimplemented!"); - return ERR_UNCONFIGURED; -} - -Error WebRTCPeerConnectionExtension::add_ice_candidate(String p_sdp_mid_name, int p_sdp_mline_index, String p_sdp_name) { - int err; - if (GDVIRTUAL_CALL(_add_ice_candidate, p_sdp_mid_name, p_sdp_mline_index, p_sdp_name, err)) { - return (Error)err; - } - WARN_PRINT_ONCE("WebRTCPeerConnectionExtension::_add_ice_candidate is unimplemented!"); - return ERR_UNCONFIGURED; -} - -Error WebRTCPeerConnectionExtension::poll() { - int err; - if (GDVIRTUAL_CALL(_poll, err)) { - return (Error)err; - } - WARN_PRINT_ONCE("WebRTCPeerConnectionExtension::_poll is unimplemented!"); - return ERR_UNCONFIGURED; -} - -void WebRTCPeerConnectionExtension::close() { - if (GDVIRTUAL_CALL(_close)) { - return; - } - WARN_PRINT_ONCE("WebRTCPeerConnectionExtension::_close is unimplemented!"); -} diff --git a/modules/webrtc/webrtc_peer_connection_extension.h b/modules/webrtc/webrtc_peer_connection_extension.h index bde19c173b..0c324ca45f 100644 --- a/modules/webrtc/webrtc_peer_connection_extension.h +++ b/modules/webrtc/webrtc_peer_connection_extension.h @@ -33,6 +33,7 @@ #include "webrtc_peer_connection.h" +#include "core/extension/ext_wrappers.gen.inc" #include "core/object/gdvirtual.gen.inc" #include "core/object/script_language.h" #include "core/variant/native_ptr.h" @@ -44,27 +45,21 @@ protected: static void _bind_methods(); public: - virtual ConnectionState get_connection_state() const override; - - virtual Error initialize(Dictionary p_config = Dictionary()) override; + // FIXME Can't be directly exposed due to issues in exchanging Ref(s) between godot and extensions. + // See godot-cpp GH-652 . virtual Ref<WebRTCDataChannel> create_data_channel(String p_label, Dictionary p_options = Dictionary()) override; - virtual Error create_offer() override; - virtual Error set_remote_description(String type, String sdp) override; - virtual Error set_local_description(String type, String sdp) override; - virtual Error add_ice_candidate(String p_sdp_mid_name, int p_sdp_mline_index, String p_sdp_name) override; - virtual Error poll() override; - virtual void close() override; + GDVIRTUAL2R(Object *, _create_data_channel, String, Dictionary); + // EXBIND2R(Ref<WebRTCDataChannel>, create_data_channel, String, Dictionary); /** GDExtension **/ - GDVIRTUAL0RC(int, _get_connection_state); - GDVIRTUAL1R(int, _initialize, Dictionary); - GDVIRTUAL2R(Object *, _create_data_channel, String, Dictionary); - GDVIRTUAL0R(int, _create_offer); - GDVIRTUAL2R(int, _set_remote_description, String, String); - GDVIRTUAL2R(int, _set_local_description, String, String); - GDVIRTUAL3R(int, _add_ice_candidate, String, int, String); - GDVIRTUAL0R(int, _poll); - GDVIRTUAL0(_close); + EXBIND0RC(ConnectionState, get_connection_state); + EXBIND1R(Error, initialize, Dictionary); + EXBIND0R(Error, create_offer); + EXBIND2R(Error, set_remote_description, String, String); + EXBIND2R(Error, set_local_description, String, String); + EXBIND3R(Error, add_ice_candidate, String, int, String); + EXBIND0R(Error, poll); + EXBIND0(close); WebRTCPeerConnectionExtension() {} }; diff --git a/platform/linuxbsd/SCsub b/platform/linuxbsd/SCsub index 35c41556ee..91d45627b9 100644 --- a/platform/linuxbsd/SCsub +++ b/platform/linuxbsd/SCsub @@ -9,6 +9,7 @@ common_linuxbsd = [ "crash_handler_linuxbsd.cpp", "os_linuxbsd.cpp", "joypad_linux.cpp", + "freedesktop_portal_desktop.cpp", "freedesktop_screensaver.cpp", ] diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py index dd829bdb9b..f5f7e65417 100644 --- a/platform/linuxbsd/detect.py +++ b/platform/linuxbsd/detect.py @@ -40,7 +40,7 @@ def get_opts(): BoolVariable("use_tsan", "Use LLVM/GCC compiler thread sanitizer (TSAN)", False), BoolVariable("use_msan", "Use LLVM compiler memory sanitizer (MSAN)", False), BoolVariable("pulseaudio", "Detect and use PulseAudio", True), - BoolVariable("dbus", "Detect and use D-Bus to handle screensaver", True), + BoolVariable("dbus", "Detect and use D-Bus to handle screensaver and portal desktop settings", True), BoolVariable("speechd", "Detect and use Speech Dispatcher for Text-to-Speech support", True), BoolVariable("fontconfig", "Detect and use fontconfig for system fonts support", True), BoolVariable("udev", "Use udev for gamepad connection callbacks", True), diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index de92d7a75b..3979cab084 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -349,6 +349,28 @@ void DisplayServerX11::tts_stop() { #endif +#ifdef DBUS_ENABLED + +bool DisplayServerX11::is_dark_mode_supported() const { + return portal_desktop->is_supported(); +} + +bool DisplayServerX11::is_dark_mode() const { + switch (portal_desktop->get_appearance_color_scheme()) { + case 1: + // Prefers dark theme. + return true; + case 2: + // Prefers light theme. + return false; + default: + // Preference unknown. + return false; + } +} + +#endif + void DisplayServerX11::mouse_set_mode(MouseMode p_mode) { _THREAD_SAFE_METHOD_ @@ -5016,6 +5038,8 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode #ifdef DBUS_ENABLED screensaver = memnew(FreeDesktopScreenSaver); screen_set_keep_on(GLOBAL_GET("display/window/energy_saving/keep_screen_on")); + + portal_desktop = memnew(FreeDesktopPortalDesktop); #endif r_error = OK; @@ -5101,6 +5125,7 @@ DisplayServerX11::~DisplayServerX11() { #ifdef DBUS_ENABLED memdelete(screensaver); + memdelete(portal_desktop); #endif } diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h index 650598d243..dd9ac088d9 100644 --- a/platform/linuxbsd/display_server_x11.h +++ b/platform/linuxbsd/display_server_x11.h @@ -60,6 +60,7 @@ #endif #if defined(DBUS_ENABLED) +#include "freedesktop_portal_desktop.h" #include "freedesktop_screensaver.h" #endif @@ -120,6 +121,10 @@ class DisplayServerX11 : public DisplayServer { TTS_Linux *tts = nullptr; #endif +#if defined(DBUS_ENABLED) + FreeDesktopPortalDesktop *portal_desktop = nullptr; +#endif + struct WindowData { Window x11_window; ::XIC xic; @@ -320,6 +325,11 @@ public: virtual void tts_stop() override; #endif +#if defined(DBUS_ENABLED) + virtual bool is_dark_mode_supported() const override; + virtual bool is_dark_mode() const override; +#endif + virtual void mouse_set_mode(MouseMode p_mode) override; virtual MouseMode mouse_get_mode() const override; diff --git a/platform/linuxbsd/freedesktop_portal_desktop.cpp b/platform/linuxbsd/freedesktop_portal_desktop.cpp new file mode 100644 index 0000000000..ed54084694 --- /dev/null +++ b/platform/linuxbsd/freedesktop_portal_desktop.cpp @@ -0,0 +1,135 @@ +/*************************************************************************/ +/* freedesktop_portal_desktop.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "freedesktop_portal_desktop.h" + +#ifdef DBUS_ENABLED + +#include "core/error/error_macros.h" +#include "core/os/os.h" +#include "core/string/ustring.h" + +#include "dbus-so_wrap.h" + +#include "core/variant/variant.h" + +#define BUS_OBJECT_NAME "org.freedesktop.portal.Desktop" +#define BUS_OBJECT_PATH "/org/freedesktop/portal/desktop" + +#define BUS_INTERFACE_SETTINGS "org.freedesktop.portal.Settings" + +static bool try_parse_variant(DBusMessage *p_reply_message, int p_type, void *r_value) { + DBusMessageIter iter[3]; + + dbus_message_iter_init(p_reply_message, &iter[0]); + if (dbus_message_iter_get_arg_type(&iter[0]) != DBUS_TYPE_VARIANT) { + return false; + } + + dbus_message_iter_recurse(&iter[0], &iter[1]); + if (dbus_message_iter_get_arg_type(&iter[1]) != DBUS_TYPE_VARIANT) { + return false; + } + + dbus_message_iter_recurse(&iter[1], &iter[2]); + if (dbus_message_iter_get_arg_type(&iter[2]) != p_type) { + return false; + } + + dbus_message_iter_get_basic(&iter[2], r_value); + return true; +} + +bool FreeDesktopPortalDesktop::read_setting(const char *p_namespace, const char *p_key, int p_type, void *r_value) { + if (unsupported) { + return false; + } + + DBusError error; + dbus_error_init(&error); + + DBusConnection *bus = dbus_bus_get(DBUS_BUS_SESSION, &error); + if (dbus_error_is_set(&error)) { + dbus_error_free(&error); + unsupported = true; + if (OS::get_singleton()->is_stdout_verbose()) { + ERR_PRINT(String() + "Error opening D-Bus connection: " + error.message); + } + return false; + } + + DBusMessage *message = dbus_message_new_method_call( + BUS_OBJECT_NAME, BUS_OBJECT_PATH, BUS_INTERFACE_SETTINGS, + "Read"); + dbus_message_append_args( + message, + DBUS_TYPE_STRING, &p_namespace, + DBUS_TYPE_STRING, &p_key, + DBUS_TYPE_INVALID); + + DBusMessage *reply = dbus_connection_send_with_reply_and_block(bus, message, 50, &error); + dbus_message_unref(message); + if (dbus_error_is_set(&error)) { + dbus_error_free(&error); + dbus_connection_unref(bus); + if (OS::get_singleton()->is_stdout_verbose()) { + ERR_PRINT(String() + "Error on D-Bus communication: " + error.message); + } + return false; + } + + bool success = try_parse_variant(reply, p_type, r_value); + + dbus_message_unref(reply); + dbus_connection_unref(bus); + + return success; +} + +uint32_t FreeDesktopPortalDesktop::get_appearance_color_scheme() { + if (unsupported) { + return 0; + } + + uint32_t value = 0; + read_setting("org.freedesktop.appearance", "color-scheme", DBUS_TYPE_UINT32, &value); + return value; +} + +FreeDesktopPortalDesktop::FreeDesktopPortalDesktop() { +#ifdef DEBUG_ENABLED + int dylibloader_verbose = 1; +#else + int dylibloader_verbose = 0; +#endif + unsupported = (initialize_dbus(dylibloader_verbose) != 0); +} + +#endif // DBUS_ENABLED diff --git a/platform/linuxbsd/freedesktop_portal_desktop.h b/platform/linuxbsd/freedesktop_portal_desktop.h new file mode 100644 index 0000000000..3d976b1ede --- /dev/null +++ b/platform/linuxbsd/freedesktop_portal_desktop.h @@ -0,0 +1,59 @@ +/*************************************************************************/ +/* freedesktop_portal_desktop.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef FREEDESKTOP_PORTAL_DESKTOP_H +#define FREEDESKTOP_PORTAL_DESKTOP_H + +#ifdef DBUS_ENABLED + +#include <stdint.h> + +class FreeDesktopPortalDesktop { +private: + bool unsupported = false; + + // Read a setting from org.freekdesktop.portal.Settings + bool read_setting(const char *p_namespace, const char *p_key, int p_type, void *r_value); + +public: + FreeDesktopPortalDesktop(); + + bool is_supported() { return !unsupported; } + + // Retrieve the system's preferred color scheme. + // 0: No preference or unknown. + // 1: Prefer dark appearance. + // 2: Prefer light appearance. + uint32_t get_appearance_color_scheme(); +}; + +#endif // DBUS_ENABLED + +#endif // FREEDESKTOP_PORTAL_DESKTOP_H diff --git a/platform/macos/SCsub b/platform/macos/SCsub index d0856c709a..bbd461fba9 100644 --- a/platform/macos/SCsub +++ b/platform/macos/SCsub @@ -17,6 +17,8 @@ files = [ "godot_window.mm", "key_mapping_macos.mm", "godot_main_macos.mm", + "godot_menu_delegate.mm", + "godot_menu_item.mm", "dir_access_macos.mm", "tts_macos.mm", "joypad_macos.cpp", diff --git a/platform/macos/display_server_macos.h b/platform/macos/display_server_macos.h index a08667a259..769cba2de5 100644 --- a/platform/macos/display_server_macos.h +++ b/platform/macos/display_server_macos.h @@ -140,6 +140,7 @@ private: int key_event_pos = 0; id tts = nullptr; + id menu_delegate = nullptr; Point2i im_selection; String im_text; @@ -227,14 +228,14 @@ public: virtual bool has_feature(Feature p_feature) const override; virtual String get_name() const override; - virtual int global_menu_add_item(const String &p_menu_root, const String &p_label, const Callable &p_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override; - virtual int global_menu_add_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override; - virtual int global_menu_add_icon_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override; - virtual int global_menu_add_icon_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override; - virtual int global_menu_add_radio_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override; - virtual int global_menu_add_icon_radio_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override; - virtual int global_menu_add_multistate_item(const String &p_menu_root, const String &p_label, int p_max_states, int p_default_state, const Callable &p_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override; virtual int global_menu_add_submenu_item(const String &p_menu_root, const String &p_label, const String &p_submenu, int p_index = -1) override; + virtual int global_menu_add_item(const String &p_menu_root, const String &p_label, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override; + virtual int global_menu_add_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override; + virtual int global_menu_add_icon_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override; + virtual int global_menu_add_icon_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override; + virtual int global_menu_add_radio_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override; + virtual int global_menu_add_icon_radio_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override; + virtual int global_menu_add_multistate_item(const String &p_menu_root, const String &p_label, int p_max_states, int p_default_state, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1) override; virtual int global_menu_add_separator(const String &p_menu_root, int p_index = -1) override; virtual int global_menu_get_item_index_from_text(const String &p_menu_root, const String &p_text) const override; @@ -244,6 +245,7 @@ public: virtual bool global_menu_is_item_checkable(const String &p_menu_root, int p_idx) const override; virtual bool global_menu_is_item_radio_checkable(const String &p_menu_root, int p_idx) const override; virtual Callable global_menu_get_item_callback(const String &p_menu_root, int p_idx) const override; + virtual Callable global_menu_get_item_key_callback(const String &p_menu_root, int p_idx) const override; virtual Variant global_menu_get_item_tag(const String &p_menu_root, int p_idx) const override; virtual String global_menu_get_item_text(const String &p_menu_root, int p_idx) const override; virtual String global_menu_get_item_submenu(const String &p_menu_root, int p_idx) const override; @@ -259,6 +261,7 @@ public: virtual void global_menu_set_item_checkable(const String &p_menu_root, int p_idx, bool p_checkable) override; virtual void global_menu_set_item_radio_checkable(const String &p_menu_root, int p_idx, bool p_checkable) override; virtual void global_menu_set_item_callback(const String &p_menu_root, int p_idx, const Callable &p_callback) override; + virtual void global_menu_set_item_key_callback(const String &p_menu_root, int p_idx, const Callable &p_key_callback) override; virtual void global_menu_set_item_tag(const String &p_menu_root, int p_idx, const Variant &p_tag) override; virtual void global_menu_set_item_text(const String &p_menu_root, int p_idx, const String &p_text) override; virtual void global_menu_set_item_submenu(const String &p_menu_root, int p_idx, const String &p_submenu) override; @@ -284,6 +287,10 @@ public: virtual void tts_resume() override; virtual void tts_stop() override; + virtual bool is_dark_mode_supported() const override; + virtual bool is_dark_mode() const override; + virtual Color get_accent_color() const override; + virtual Error dialog_show(String p_title, String p_description, Vector<String> p_buttons, const Callable &p_callback) override; virtual Error dialog_input_text(String p_title, String p_description, String p_partial, const Callable &p_callback) override; diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index b06ae9f27c..b009007d73 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -31,6 +31,7 @@ #include "display_server_macos.h" #include "godot_content_view.h" +#include "godot_menu_delegate.h" #include "godot_menu_item.h" #include "godot_window.h" #include "godot_window_delegate.h" @@ -95,6 +96,7 @@ NSMenu *DisplayServerMacOS::_get_menu_root(const String &p_menu_root) { if (!submenu.has(p_menu_root)) { NSMenu *n_menu = [[NSMenu alloc] initWithTitle:[NSString stringWithUTF8String:p_menu_root.utf8().get_data()]]; [n_menu setAutoenablesItems:NO]; + [n_menu setDelegate:menu_delegate]; submenu[p_menu_root] = n_menu; } menu = submenu[p_menu_root]; @@ -754,7 +756,7 @@ NSMenuItem *DisplayServerMacOS::_menu_add_item(const String &p_menu_root, const return nullptr; } -int DisplayServerMacOS::global_menu_add_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +int DisplayServerMacOS::global_menu_add_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Callable &p_key_callback, const Variant &p_tag, Key p_accel, int p_index) { _THREAD_SAFE_METHOD_ int out = -1; @@ -762,6 +764,7 @@ int DisplayServerMacOS::global_menu_add_item(const String &p_menu_root, const St if (menu_item) { GodotMenuItem *obj = [[GodotMenuItem alloc] init]; obj->callback = p_callback; + obj->key_callback = p_key_callback; obj->meta = p_tag; obj->checkable_type = CHECKABLE_TYPE_NONE; obj->max_states = 0; @@ -772,7 +775,7 @@ int DisplayServerMacOS::global_menu_add_item(const String &p_menu_root, const St return out; } -int DisplayServerMacOS::global_menu_add_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +int DisplayServerMacOS::global_menu_add_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Callable &p_key_callback, const Variant &p_tag, Key p_accel, int p_index) { _THREAD_SAFE_METHOD_ int out = -1; @@ -780,6 +783,7 @@ int DisplayServerMacOS::global_menu_add_check_item(const String &p_menu_root, co if (menu_item) { GodotMenuItem *obj = [[GodotMenuItem alloc] init]; obj->callback = p_callback; + obj->key_callback = p_key_callback; obj->meta = p_tag; obj->checkable_type = CHECKABLE_TYPE_CHECK_BOX; obj->max_states = 0; @@ -790,7 +794,7 @@ int DisplayServerMacOS::global_menu_add_check_item(const String &p_menu_root, co return out; } -int DisplayServerMacOS::global_menu_add_icon_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +int DisplayServerMacOS::global_menu_add_icon_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Callable &p_key_callback, const Variant &p_tag, Key p_accel, int p_index) { _THREAD_SAFE_METHOD_ int out = -1; @@ -798,6 +802,7 @@ int DisplayServerMacOS::global_menu_add_icon_item(const String &p_menu_root, con if (menu_item) { GodotMenuItem *obj = [[GodotMenuItem alloc] init]; obj->callback = p_callback; + obj->key_callback = p_key_callback; obj->meta = p_tag; obj->checkable_type = CHECKABLE_TYPE_NONE; obj->max_states = 0; @@ -817,7 +822,7 @@ int DisplayServerMacOS::global_menu_add_icon_item(const String &p_menu_root, con return out; } -int DisplayServerMacOS::global_menu_add_icon_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +int DisplayServerMacOS::global_menu_add_icon_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Callable &p_key_callback, const Variant &p_tag, Key p_accel, int p_index) { _THREAD_SAFE_METHOD_ int out = -1; @@ -825,6 +830,7 @@ int DisplayServerMacOS::global_menu_add_icon_check_item(const String &p_menu_roo if (menu_item) { GodotMenuItem *obj = [[GodotMenuItem alloc] init]; obj->callback = p_callback; + obj->key_callback = p_key_callback; obj->meta = p_tag; obj->checkable_type = CHECKABLE_TYPE_CHECK_BOX; obj->max_states = 0; @@ -844,7 +850,7 @@ int DisplayServerMacOS::global_menu_add_icon_check_item(const String &p_menu_roo return out; } -int DisplayServerMacOS::global_menu_add_radio_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +int DisplayServerMacOS::global_menu_add_radio_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Callable &p_key_callback, const Variant &p_tag, Key p_accel, int p_index) { _THREAD_SAFE_METHOD_ int out = -1; @@ -852,6 +858,7 @@ int DisplayServerMacOS::global_menu_add_radio_check_item(const String &p_menu_ro if (menu_item) { GodotMenuItem *obj = [[GodotMenuItem alloc] init]; obj->callback = p_callback; + obj->key_callback = p_key_callback; obj->meta = p_tag; obj->checkable_type = CHECKABLE_TYPE_RADIO_BUTTON; obj->max_states = 0; @@ -862,7 +869,7 @@ int DisplayServerMacOS::global_menu_add_radio_check_item(const String &p_menu_ro return out; } -int DisplayServerMacOS::global_menu_add_icon_radio_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +int DisplayServerMacOS::global_menu_add_icon_radio_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Callable &p_key_callback, const Variant &p_tag, Key p_accel, int p_index) { _THREAD_SAFE_METHOD_ int out = -1; @@ -870,6 +877,7 @@ int DisplayServerMacOS::global_menu_add_icon_radio_check_item(const String &p_me if (menu_item) { GodotMenuItem *obj = [[GodotMenuItem alloc] init]; obj->callback = p_callback; + obj->key_callback = p_key_callback; obj->meta = p_tag; obj->checkable_type = CHECKABLE_TYPE_RADIO_BUTTON; obj->max_states = 0; @@ -889,30 +897,15 @@ int DisplayServerMacOS::global_menu_add_icon_radio_check_item(const String &p_me return out; } -int DisplayServerMacOS::global_menu_add_multistate_item(const String &p_menu_root, const String &p_label, int p_max_states, int p_default_state, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +int DisplayServerMacOS::global_menu_add_multistate_item(const String &p_menu_root, const String &p_label, int p_max_states, int p_default_state, const Callable &p_callback, const Callable &p_key_callback, const Variant &p_tag, Key p_accel, int p_index) { _THREAD_SAFE_METHOD_ - NSMenu *menu = _get_menu_root(p_menu_root); int out = -1; - if (menu) { - String keycode = KeyMappingMacOS::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK); - NSMenuItem *menu_item; - int item_count = ((menu == [NSApp mainMenu]) && _has_help_menu()) ? [menu numberOfItems] - 1 : [menu numberOfItems]; - if ((menu == [NSApp mainMenu]) && (p_label == "Help" || p_label == RTR("Help"))) { - p_index = [menu numberOfItems]; - } else if (p_index < 0) { - p_index = item_count; - } else { - if (menu == [NSApp mainMenu]) { // Skip Apple menu. - p_index++; - } - p_index = CLAMP(p_index, 0, item_count); - } - menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index]; - out = (menu == [NSApp mainMenu]) ? p_index - 1 : p_index; - + NSMenuItem *menu_item = _menu_add_item(p_menu_root, p_label, p_accel, p_index, &out); + if (menu_item) { GodotMenuItem *obj = [[GodotMenuItem alloc] init]; obj->callback = p_callback; + obj->key_callback = p_key_callback; obj->meta = p_tag; obj->checkable_type = CHECKABLE_TYPE_NONE; obj->max_states = p_max_states; @@ -1104,6 +1097,27 @@ Callable DisplayServerMacOS::global_menu_get_item_callback(const String &p_menu_ return Callable(); } +Callable DisplayServerMacOS::global_menu_get_item_key_callback(const String &p_menu_root, int p_idx) const { + _THREAD_SAFE_METHOD_ + + const NSMenu *menu = _get_menu_root(p_menu_root); + if (menu) { + ERR_FAIL_COND_V(p_idx < 0, Callable()); + if (menu == [NSApp mainMenu]) { // Skip Apple menu. + p_idx++; + } + ERR_FAIL_COND_V(p_idx >= [menu numberOfItems], Callable()); + const NSMenuItem *menu_item = [menu itemAtIndex:p_idx]; + if (menu_item) { + GodotMenuItem *obj = [menu_item representedObject]; + if (obj) { + return obj->key_callback; + } + } + } + return Callable(); +} + Variant DisplayServerMacOS::global_menu_get_item_tag(const String &p_menu_root, int p_idx) const { _THREAD_SAFE_METHOD_ @@ -1401,6 +1415,25 @@ void DisplayServerMacOS::global_menu_set_item_callback(const String &p_menu_root } } +void DisplayServerMacOS::global_menu_set_item_key_callback(const String &p_menu_root, int p_idx, const Callable &p_key_callback) { + _THREAD_SAFE_METHOD_ + + NSMenu *menu = _get_menu_root(p_menu_root); + if (menu) { + ERR_FAIL_COND(p_idx < 0); + if (menu == [NSApp mainMenu]) { // Skip Apple menu. + p_idx++; + } + ERR_FAIL_COND(p_idx >= [menu numberOfItems]); + NSMenuItem *menu_item = [menu itemAtIndex:p_idx]; + if (menu_item) { + GodotMenuItem *obj = [menu_item representedObject]; + ERR_FAIL_COND(!obj); + obj->key_callback = p_key_callback; + } + } +} + void DisplayServerMacOS::global_menu_set_item_tag(const String &p_menu_root, int p_idx, const Variant &p_tag) { _THREAD_SAFE_METHOD_ @@ -1682,6 +1715,41 @@ void DisplayServerMacOS::tts_stop() { [tts stopSpeaking]; } +bool DisplayServerMacOS::is_dark_mode_supported() const { + if (@available(macOS 10.14, *)) { + return true; + } else { + return false; + } +} + +bool DisplayServerMacOS::is_dark_mode() const { + if (@available(macOS 10.14, *)) { + if (![[NSUserDefaults standardUserDefaults] objectForKey:@"AppleInterfaceStyle"]) { + return false; + } else { + return ([[[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"] isEqual:@"Dark"]); + } + } else { + return false; + } +} + +Color DisplayServerMacOS::get_accent_color() const { + if (@available(macOS 10.14, *)) { + NSColor *color = [[NSColor controlAccentColor] colorUsingColorSpace:[NSColorSpace genericRGBColorSpace]]; + if (color) { + CGFloat components[4]; + [color getRed:&components[0] green:&components[1] blue:&components[2] alpha:&components[3]]; + return Color(components[0], components[1], components[2], components[3]); + } else { + return Color(0, 0, 0, 0); + } + } else { + return Color(0, 0, 0, 0); + } +} + Error DisplayServerMacOS::dialog_show(String p_title, String p_description, Vector<String> p_buttons, const Callable &p_callback) { _THREAD_SAFE_METHOD_ @@ -3477,6 +3545,8 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM [main_menu setSubmenu:apple_menu forItem:menu_item]; [main_menu setAutoenablesItems:NO]; + menu_delegate = [[GodotMenuDelegate alloc] init]; + //!!!!!!!!!!!!!!!!!!!!!!!!!! //TODO - do Vulkan and OpenGL support checks, driver selection and fallback rendering_driver = p_rendering_driver; diff --git a/platform/macos/godot_menu_delegate.h b/platform/macos/godot_menu_delegate.h new file mode 100644 index 0000000000..805ac0c4a3 --- /dev/null +++ b/platform/macos/godot_menu_delegate.h @@ -0,0 +1,44 @@ +/*************************************************************************/ +/* godot_menu_delegate.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GODOT_MENU_DELEGATE_H +#define GODOT_MENU_DELEGATE_H + +#import <AppKit/AppKit.h> +#import <Foundation/Foundation.h> + +@interface GodotMenuDelegate : NSObject <NSMenuDelegate> { +} + +- (void)doNothing:(id)sender; + +@end + +#endif // GODOT_MENU_DELEGATE_H diff --git a/platform/macos/godot_menu_delegate.mm b/platform/macos/godot_menu_delegate.mm new file mode 100644 index 0000000000..376f28d1d0 --- /dev/null +++ b/platform/macos/godot_menu_delegate.mm @@ -0,0 +1,76 @@ +/*************************************************************************/ +/* godot_menu_delegate.mm */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "godot_menu_delegate.h" + +#include "display_server_macos.h" +#include "godot_menu_item.h" +#include "key_mapping_macos.h" + +@implementation GodotMenuDelegate + +- (void)doNothing:(id)sender { +} + +- (BOOL)menuHasKeyEquivalent:(NSMenu *)menu forEvent:(NSEvent *)event target:(id *)target action:(SEL *)action { + NSString *ev_key = [[event charactersIgnoringModifiers] lowercaseString]; + NSUInteger ev_modifiers = [event modifierFlags] & NSDeviceIndependentModifierFlagsMask; + for (int i = 0; i < [menu numberOfItems]; i++) { + const NSMenuItem *menu_item = [menu itemAtIndex:i]; + if ([menu_item isEnabled] && [[menu_item keyEquivalent] compare:ev_key] == NSOrderedSame) { + NSUInteger item_modifiers = [menu_item keyEquivalentModifierMask]; + + if (ev_modifiers == item_modifiers) { + GodotMenuItem *value = [menu_item representedObject]; + if (value->key_callback != Callable()) { + // If custom callback is set, use it. + Variant tag = value->meta; + Variant *tagp = &tag; + Variant ret; + Callable::CallError ce; + value->key_callback.callp((const Variant **)&tagp, 1, ret, ce); + } else { + // Otherwise redirect event to the engine. + if (DisplayServer::get_singleton()) { + [[[NSApplication sharedApplication] keyWindow] sendEvent:event]; + } + } + + // Suppress default menu action. + *target = self; + *action = @selector(doNothing:); + return YES; + } + } + } + return NO; +} + +@end diff --git a/platform/macos/godot_menu_item.h b/platform/macos/godot_menu_item.h index e0b9f41632..e96f5dc1cf 100644 --- a/platform/macos/godot_menu_item.h +++ b/platform/macos/godot_menu_item.h @@ -45,6 +45,7 @@ enum GlobalMenuCheckType { @interface GodotMenuItem : NSObject { @public Callable callback; + Callable key_callback; Variant meta; GlobalMenuCheckType checkable_type; int max_states; @@ -54,7 +55,4 @@ enum GlobalMenuCheckType { @end -@implementation GodotMenuItem -@end - #endif // GODOT_MENU_ITEM_H diff --git a/platform/macos/godot_menu_item.mm b/platform/macos/godot_menu_item.mm new file mode 100644 index 0000000000..ea35e35d19 --- /dev/null +++ b/platform/macos/godot_menu_item.mm @@ -0,0 +1,34 @@ +/*************************************************************************/ +/* godot_menu_item.mm */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "godot_menu_item.h" + +@implementation GodotMenuItem +@end diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 7eb61b3038..6530846c15 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -37,6 +37,11 @@ #include "scene/resources/texture.h" #include <avrt.h> +#include <dwmapi.h> + +#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE +#define DWMWA_USE_IMMERSIVE_DARK_MODE 20 +#endif #if defined(GLES3_ENABLED) #include "drivers/gles3/rasterizer_gles3.h" @@ -2391,6 +2396,20 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA case WM_PAINT: { Main::force_redraw(); } break; + case WM_SETTINGCHANGE: { + if (lParam && CompareStringOrdinal(reinterpret_cast<LPCWCH>(lParam), -1, L"ImmersiveColorSet", -1, true) == CSTR_EQUAL) { + if (is_dark_mode_supported()) { + BOOL value = is_dark_mode(); + ::DwmSetWindowAttribute(windows[window_id].hWnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &value, sizeof(value)); + } + } + } break; + case WM_THEMECHANGED: { + if (is_dark_mode_supported()) { + BOOL value = is_dark_mode(); + ::DwmSetWindowAttribute(windows[window_id].hWnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &value, sizeof(value)); + } + } break; case WM_SYSCOMMAND: // Intercept system commands. { switch (wParam) // Check system calls. @@ -3501,6 +3520,11 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, wd.pre_fs_valid = true; } + if (is_dark_mode_supported()) { + BOOL value = is_dark_mode(); + ::DwmSetWindowAttribute(wd.hWnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &value, sizeof(value)); + } + #ifdef VULKAN_ENABLED if (context_vulkan) { if (context_vulkan->window_create(id, p_vsync_mode, wd.hWnd, hInstance, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top) == -1) { @@ -3587,6 +3611,14 @@ WTInfoPtr DisplayServerWindows::wintab_WTInfo = nullptr; WTPacketPtr DisplayServerWindows::wintab_WTPacket = nullptr; WTEnablePtr DisplayServerWindows::wintab_WTEnable = nullptr; +// UXTheme API. +bool DisplayServerWindows::ux_theme_available = false; +IsDarkModeAllowedForAppPtr DisplayServerWindows::IsDarkModeAllowedForApp = nullptr; +ShouldAppsUseDarkModePtr DisplayServerWindows::ShouldAppsUseDarkMode = nullptr; +GetImmersiveColorFromColorSetExPtr DisplayServerWindows::GetImmersiveColorFromColorSetEx = nullptr; +GetImmersiveColorTypeFromNamePtr DisplayServerWindows::GetImmersiveColorTypeFromName = nullptr; +GetImmersiveUserColorSetPreferencePtr DisplayServerWindows::GetImmersiveUserColorSetPreference = nullptr; + // Windows Ink API. bool DisplayServerWindows::winink_available = false; GetPointerTypePtr DisplayServerWindows::win8p_GetPointerType = nullptr; @@ -3598,6 +3630,23 @@ typedef enum _SHC_PROCESS_DPI_AWARENESS { SHC_PROCESS_PER_MONITOR_DPI_AWARE = 2 } SHC_PROCESS_DPI_AWARENESS; +bool DisplayServerWindows::is_dark_mode_supported() const { + return ux_theme_available && IsDarkModeAllowedForApp(); +} + +bool DisplayServerWindows::is_dark_mode() const { + return ux_theme_available && ShouldAppsUseDarkMode(); +} + +Color DisplayServerWindows::get_accent_color() const { + if (!ux_theme_available) { + return Color(0, 0, 0, 0); + } + + int argb = GetImmersiveColorFromColorSetEx((UINT)GetImmersiveUserColorSetPreference(false, false), GetImmersiveColorTypeFromName(L"ImmersiveSystemAccent"), false, 0); + return Color((argb & 0xFF) / 255.f, ((argb & 0xFF00) >> 8) / 255.f, ((argb & 0xFF0000) >> 16) / 255.f, ((argb & 0xFF000000) >> 24) / 255.f); +} + int DisplayServerWindows::tablet_get_driver_count() const { return tablet_drivers.size(); } @@ -3655,6 +3704,18 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win // Enforce default keep screen on value. screen_set_keep_on(GLOBAL_GET("display/window/energy_saving/keep_screen_on")); + // Load UXTheme + HMODULE ux_theme_lib = LoadLibraryW(L"uxtheme.dll"); + if (ux_theme_lib) { + IsDarkModeAllowedForApp = (IsDarkModeAllowedForAppPtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(136)); + ShouldAppsUseDarkMode = (ShouldAppsUseDarkModePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(132)); + GetImmersiveColorFromColorSetEx = (GetImmersiveColorFromColorSetExPtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(95)); + GetImmersiveColorTypeFromName = (GetImmersiveColorTypeFromNamePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(96)); + GetImmersiveUserColorSetPreference = (GetImmersiveUserColorSetPreferencePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(98)); + + ux_theme_available = IsDarkModeAllowedForApp && ShouldAppsUseDarkMode && GetImmersiveColorFromColorSetEx && GetImmersiveColorTypeFromName && GetImmersiveUserColorSetPreference; + } + // Note: Wacom WinTab driver API for pen input, for devices incompatible with Windows Ink. HMODULE wintab_lib = LoadLibraryW(L"wintab32.dll"); if (wintab_lib) { diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index 556ce9ff5d..afdf78b380 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -152,6 +152,12 @@ typedef UINT(WINAPI *WTInfoPtr)(UINT p_category, UINT p_index, LPVOID p_output); typedef BOOL(WINAPI *WTPacketPtr)(HANDLE p_ctx, UINT p_param, LPVOID p_packets); typedef BOOL(WINAPI *WTEnablePtr)(HANDLE p_ctx, BOOL p_enable); +typedef bool(WINAPI *IsDarkModeAllowedForAppPtr)(); +typedef bool(WINAPI *ShouldAppsUseDarkModePtr)(); +typedef DWORD(WINAPI *GetImmersiveColorFromColorSetExPtr)(UINT dwImmersiveColorSet, UINT dwImmersiveColorType, bool bIgnoreHighContrast, UINT dwHighContrastCacheMode); +typedef int(WINAPI *GetImmersiveColorTypeFromNamePtr)(const WCHAR *name); +typedef int(WINAPI *GetImmersiveUserColorSetPreferencePtr)(bool bForceCheckRegistry, bool bSkipCheckOnFail); + // Windows Ink API #ifndef POINTER_STRUCTURES @@ -278,6 +284,14 @@ class DisplayServerWindows : public DisplayServer { _THREAD_SAFE_CLASS_ + // UXTheme API + static bool ux_theme_available; + static IsDarkModeAllowedForAppPtr IsDarkModeAllowedForApp; + static ShouldAppsUseDarkModePtr ShouldAppsUseDarkMode; + static GetImmersiveColorFromColorSetExPtr GetImmersiveColorFromColorSetEx; + static GetImmersiveColorTypeFromNamePtr GetImmersiveColorTypeFromName; + static GetImmersiveUserColorSetPreferencePtr GetImmersiveUserColorSetPreference; + // WinTab API static bool wintab_available; static WTOpenPtr wintab_WTOpen; @@ -485,6 +499,10 @@ public: virtual void tts_resume() override; virtual void tts_stop() override; + virtual bool is_dark_mode_supported() const override; + virtual bool is_dark_mode() const override; + virtual Color get_accent_color() const override; + virtual void mouse_set_mode(MouseMode p_mode) override; virtual MouseMode mouse_get_mode() const override; diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index 75f1497edc..3def41eaa5 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -426,36 +426,36 @@ bool Area2D::is_monitorable() const { } TypedArray<Node2D> Area2D::get_overlapping_bodies() const { - ERR_FAIL_COND_V_MSG(!monitoring, Array(), "Can't find overlapping bodies when monitoring is off."); TypedArray<Node2D> ret; + ERR_FAIL_COND_V_MSG(!monitoring, ret, "Can't find overlapping bodies when monitoring is off."); ret.resize(body_map.size()); int idx = 0; for (const KeyValue<ObjectID, BodyState> &E : body_map) { Object *obj = ObjectDB::get_instance(E.key); - if (!obj) { - ret.resize(ret.size() - 1); //ops - } else { - ret[idx++] = obj; + if (obj) { + ret[idx] = obj; + idx++; } } + ret.resize(idx); return ret; } TypedArray<Area2D> Area2D::get_overlapping_areas() const { - ERR_FAIL_COND_V_MSG(!monitoring, Array(), "Can't find overlapping bodies when monitoring is off."); TypedArray<Area2D> ret; + ERR_FAIL_COND_V_MSG(!monitoring, ret, "Can't find overlapping areas when monitoring is off."); ret.resize(area_map.size()); int idx = 0; for (const KeyValue<ObjectID, AreaState> &E : area_map) { Object *obj = ObjectDB::get_instance(E.key); - if (!obj) { - ret.resize(ret.size() - 1); //ops - } else { - ret[idx++] = obj; + if (obj) { + ret[idx] = obj; + idx++; } } + ret.resize(idx); return ret; } @@ -607,7 +607,7 @@ void Area2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_point_distance_scale", PROPERTY_HINT_RANGE, "0,1024,0.001,or_greater,exp"), "set_gravity_point_distance_scale", "get_gravity_point_distance_scale"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "gravity_point_center", PROPERTY_HINT_NONE, "suffix:px"), "set_gravity_point_center", "get_gravity_point_center"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "gravity_direction"), "set_gravity_direction", "get_gravity_direction"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity", PROPERTY_HINT_RANGE, U"-4096,4096,0.001,or_lesser,or_greater,suffix:px/s\u00B2"), "set_gravity", "get_gravity"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity", PROPERTY_HINT_RANGE, U"-4096,4096,0.001,or_less,or_greater,suffix:px/s\u00B2"), "set_gravity", "get_gravity"); ADD_GROUP("Linear Damp", "linear_damp_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "linear_damp_space_override", PROPERTY_HINT_ENUM, "Disabled,Combine,Combine-Replace,Replace,Replace-Combine", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_linear_damp_space_override_mode", "get_linear_damp_space_override_mode"); diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index 58e357ab5f..4523e5dfe9 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -1383,32 +1383,32 @@ void CPUParticles2D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_min", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater,suffix:px/s"), "set_param_min", "get_param_min", PARAM_INITIAL_LINEAR_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_max", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater,suffix:px/s"), "set_param_max", "get_param_max", PARAM_INITIAL_LINEAR_VELOCITY); ADD_GROUP("Angular Velocity", "angular_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_min", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_ANGULAR_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_max", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_ANGULAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_min", PROPERTY_HINT_RANGE, "-720,720,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_ANGULAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_max", PROPERTY_HINT_RANGE, "-720,720,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_ANGULAR_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angular_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANGULAR_VELOCITY); ADD_GROUP("Orbit Velocity", "orbit_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_min", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_ORBIT_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_max", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_ORBIT_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_min", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_ORBIT_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_max", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_ORBIT_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "orbit_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ORBIT_VELOCITY); ADD_GROUP("Linear Accel", "linear_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_LINEAR_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_LINEAR_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_LINEAR_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_LINEAR_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "linear_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_LINEAR_ACCEL); ADD_GROUP("Radial Accel", "radial_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_RADIAL_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_RADIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_RADIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_RADIAL_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "radial_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_RADIAL_ACCEL); ADD_GROUP("Tangential Accel", "tangential_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_TANGENTIAL_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_TANGENTIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_TANGENTIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_TANGENTIAL_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "tangential_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_TANGENTIAL_ACCEL); ADD_GROUP("Damping", ""); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_min", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_param_min", "get_param_min", PARAM_DAMPING); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_max", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_param_max", "get_param_max", PARAM_DAMPING); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "damping_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_DAMPING); ADD_GROUP("Angle", ""); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_min", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater,degrees"), "set_param_min", "get_param_min", PARAM_ANGLE); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_max", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater,degrees"), "set_param_max", "get_param_max", PARAM_ANGLE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_min", PROPERTY_HINT_RANGE, "-720,720,0.1,or_less,or_greater,degrees"), "set_param_min", "get_param_min", PARAM_ANGLE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_max", PROPERTY_HINT_RANGE, "-720,720,0.1,or_less,or_greater,degrees"), "set_param_max", "get_param_max", PARAM_ANGLE); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angle_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANGLE); ADD_GROUP("Scale", ""); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "scale_amount_min", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param_min", "get_param_min", PARAM_SCALE); @@ -1428,8 +1428,8 @@ void CPUParticles2D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation_max", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param_max", "get_param_max", PARAM_HUE_VARIATION); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "hue_variation_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_HUE_VARIATION); ADD_GROUP("Animation", "anim_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_min", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater,or_lesser"), "set_param_min", "get_param_min", PARAM_ANIM_SPEED); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_max", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater,or_lesser"), "set_param_max", "get_param_max", PARAM_ANIM_SPEED); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_min", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater,or_less"), "set_param_min", "get_param_min", PARAM_ANIM_SPEED); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_max", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater,or_less"), "set_param_max", "get_param_max", PARAM_ANIM_SPEED); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_speed_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANIM_SPEED); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_min", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_min", "get_param_min", PARAM_ANIM_OFFSET); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_max", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_max", "get_param_max", PARAM_ANIM_OFFSET); diff --git a/scene/2d/navigation_link_2d.cpp b/scene/2d/navigation_link_2d.cpp new file mode 100644 index 0000000000..38a03aaf97 --- /dev/null +++ b/scene/2d/navigation_link_2d.cpp @@ -0,0 +1,284 @@ +/*************************************************************************/ +/* navigation_link_2d.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "navigation_link_2d.h" + +#include "core/math/geometry_2d.h" +#include "scene/resources/world_2d.h" +#include "servers/navigation_server_2d.h" +#include "servers/navigation_server_3d.h" + +void NavigationLink2D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationLink2D::set_enabled); + ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationLink2D::is_enabled); + + ClassDB::bind_method(D_METHOD("set_bidirectional", "bidirectional"), &NavigationLink2D::set_bidirectional); + ClassDB::bind_method(D_METHOD("is_bidirectional"), &NavigationLink2D::is_bidirectional); + + ClassDB::bind_method(D_METHOD("set_navigation_layers", "navigation_layers"), &NavigationLink2D::set_navigation_layers); + ClassDB::bind_method(D_METHOD("get_navigation_layers"), &NavigationLink2D::get_navigation_layers); + + ClassDB::bind_method(D_METHOD("set_navigation_layer_value", "layer_number", "value"), &NavigationLink2D::set_navigation_layer_value); + ClassDB::bind_method(D_METHOD("get_navigation_layer_value", "layer_number"), &NavigationLink2D::get_navigation_layer_value); + + ClassDB::bind_method(D_METHOD("set_start_location", "location"), &NavigationLink2D::set_start_location); + ClassDB::bind_method(D_METHOD("get_start_location"), &NavigationLink2D::get_start_location); + + ClassDB::bind_method(D_METHOD("set_end_location", "location"), &NavigationLink2D::set_end_location); + ClassDB::bind_method(D_METHOD("get_end_location"), &NavigationLink2D::get_end_location); + + ClassDB::bind_method(D_METHOD("set_enter_cost", "enter_cost"), &NavigationLink2D::set_enter_cost); + ClassDB::bind_method(D_METHOD("get_enter_cost"), &NavigationLink2D::get_enter_cost); + + ClassDB::bind_method(D_METHOD("set_travel_cost", "travel_cost"), &NavigationLink2D::set_travel_cost); + ClassDB::bind_method(D_METHOD("get_travel_cost"), &NavigationLink2D::get_travel_cost); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bidirectional"), "set_bidirectional", "is_bidirectional"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_2D_NAVIGATION), "set_navigation_layers", "get_navigation_layers"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "start_location"), "set_start_location", "get_start_location"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "end_location"), "set_end_location", "get_end_location"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "enter_cost"), "set_enter_cost", "get_enter_cost"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "travel_cost"), "set_travel_cost", "get_travel_cost"); +} + +void NavigationLink2D::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: { + if (enabled) { + NavigationServer2D::get_singleton()->link_set_map(link, get_world_2d()->get_navigation_map()); + + // Update global positions for the link. + Transform2D gt = get_global_transform(); + NavigationServer2D::get_singleton()->link_set_start_location(link, gt.xform(start_location)); + NavigationServer2D::get_singleton()->link_set_end_location(link, gt.xform(end_location)); + } + } break; + case NOTIFICATION_TRANSFORM_CHANGED: { + // Update global positions for the link. + Transform2D gt = get_global_transform(); + NavigationServer2D::get_singleton()->link_set_start_location(link, gt.xform(start_location)); + NavigationServer2D::get_singleton()->link_set_end_location(link, gt.xform(end_location)); + } break; + case NOTIFICATION_EXIT_TREE: { + NavigationServer2D::get_singleton()->link_set_map(link, RID()); + } break; + case NOTIFICATION_DRAW: { +#ifdef DEBUG_ENABLED + if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || NavigationServer2D::get_singleton()->get_debug_enabled())) { + Color color; + if (enabled) { + color = NavigationServer2D::get_singleton()->get_debug_navigation_link_connection_color(); + } else { + color = NavigationServer2D::get_singleton()->get_debug_navigation_link_connection_disabled_color(); + } + + real_t radius = NavigationServer2D::get_singleton()->map_get_link_connection_radius(get_world_2d()->get_navigation_map()); + + draw_line(get_start_location(), get_end_location(), color); + draw_arc(get_start_location(), radius, 0, Math_TAU, 10, color); + draw_arc(get_end_location(), radius, 0, Math_TAU, 10, color); + } +#endif // DEBUG_ENABLED + } break; + } +} + +#ifdef TOOLS_ENABLED +Rect2 NavigationLink2D::_edit_get_rect() const { + real_t radius = NavigationServer2D::get_singleton()->map_get_link_connection_radius(get_world_2d()->get_navigation_map()); + + Rect2 rect(get_start_location(), Size2()); + rect.expand_to(get_end_location()); + rect.grow_by(radius); + return rect; +} + +bool NavigationLink2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { + Point2 segment[2] = { get_start_location(), get_end_location() }; + + Vector2 closest_point = Geometry2D::get_closest_point_to_segment(p_point, segment); + return p_point.distance_to(closest_point) < p_tolerance; +} +#endif // TOOLS_ENABLED + +void NavigationLink2D::set_enabled(bool p_enabled) { + if (enabled == p_enabled) { + return; + } + + enabled = p_enabled; + + if (!is_inside_tree()) { + return; + } + + if (!enabled) { + NavigationServer2D::get_singleton()->link_set_map(link, RID()); + } else { + NavigationServer2D::get_singleton()->link_set_map(link, get_world_2d()->get_navigation_map()); + } + +#ifdef DEBUG_ENABLED + if (Engine::get_singleton()->is_editor_hint() || NavigationServer2D::get_singleton()->get_debug_enabled()) { + queue_redraw(); + } +#endif // DEBUG_ENABLED +} + +void NavigationLink2D::set_bidirectional(bool p_bidirectional) { + if (bidirectional == p_bidirectional) { + return; + } + + bidirectional = p_bidirectional; + + NavigationServer2D::get_singleton()->link_set_bidirectional(link, bidirectional); +} + +void NavigationLink2D::set_navigation_layers(uint32_t p_navigation_layers) { + if (navigation_layers == p_navigation_layers) { + return; + } + + navigation_layers = p_navigation_layers; + + NavigationServer2D::get_singleton()->link_set_navigation_layers(link, navigation_layers); +} + +void NavigationLink2D::set_navigation_layer_value(int p_layer_number, bool p_value) { + ERR_FAIL_COND_MSG(p_layer_number < 1, "Navigation layer number must be between 1 and 32 inclusive."); + ERR_FAIL_COND_MSG(p_layer_number > 32, "Navigation layer number must be between 1 and 32 inclusive."); + + uint32_t _navigation_layers = get_navigation_layers(); + + if (p_value) { + _navigation_layers |= 1 << (p_layer_number - 1); + } else { + _navigation_layers &= ~(1 << (p_layer_number - 1)); + } + + set_navigation_layers(_navigation_layers); +} + +bool NavigationLink2D::get_navigation_layer_value(int p_layer_number) const { + ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Navigation layer number must be between 1 and 32 inclusive."); + ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Navigation layer number must be between 1 and 32 inclusive."); + + return get_navigation_layers() & (1 << (p_layer_number - 1)); +} + +void NavigationLink2D::set_start_location(Vector2 p_location) { + if (start_location.is_equal_approx(p_location)) { + return; + } + + start_location = p_location; + + if (!is_inside_tree()) { + return; + } + + Transform2D gt = get_global_transform(); + NavigationServer2D::get_singleton()->link_set_start_location(link, gt.xform(start_location)); + + update_configuration_warnings(); + +#ifdef DEBUG_ENABLED + if (Engine::get_singleton()->is_editor_hint() || NavigationServer2D::get_singleton()->get_debug_enabled()) { + queue_redraw(); + } +#endif // DEBUG_ENABLED +} + +void NavigationLink2D::set_end_location(Vector2 p_location) { + if (end_location.is_equal_approx(p_location)) { + return; + } + + end_location = p_location; + + if (!is_inside_tree()) { + return; + } + + Transform2D gt = get_global_transform(); + NavigationServer2D::get_singleton()->link_set_end_location(link, gt.xform(end_location)); + + update_configuration_warnings(); + +#ifdef DEBUG_ENABLED + if (Engine::get_singleton()->is_editor_hint() || NavigationServer2D::get_singleton()->get_debug_enabled()) { + queue_redraw(); + } +#endif // DEBUG_ENABLED +} + +void NavigationLink2D::set_enter_cost(real_t p_enter_cost) { + ERR_FAIL_COND_MSG(p_enter_cost < 0.0, "The enter_cost must be positive."); + if (Math::is_equal_approx(enter_cost, p_enter_cost)) { + return; + } + + enter_cost = p_enter_cost; + + NavigationServer2D::get_singleton()->link_set_enter_cost(link, enter_cost); +} + +void NavigationLink2D::set_travel_cost(real_t p_travel_cost) { + ERR_FAIL_COND_MSG(p_travel_cost < 0.0, "The travel_cost must be positive."); + if (Math::is_equal_approx(travel_cost, p_travel_cost)) { + return; + } + + travel_cost = p_travel_cost; + + NavigationServer2D::get_singleton()->link_set_travel_cost(link, travel_cost); +} + +TypedArray<String> NavigationLink2D::get_configuration_warnings() const { + TypedArray<String> warnings = Node::get_configuration_warnings(); + + if (start_location.is_equal_approx(end_location)) { + warnings.push_back(RTR("NavigationLink2D start location should be different than the end location to be useful.")); + } + + return warnings; +} + +NavigationLink2D::NavigationLink2D() { + link = NavigationServer2D::get_singleton()->link_create(); + set_notify_transform(true); +} + +NavigationLink2D::~NavigationLink2D() { + NavigationServer2D::get_singleton()->free(link); + link = RID(); +} diff --git a/scene/2d/navigation_link_2d.h b/scene/2d/navigation_link_2d.h new file mode 100644 index 0000000000..5990ea082c --- /dev/null +++ b/scene/2d/navigation_link_2d.h @@ -0,0 +1,88 @@ +/*************************************************************************/ +/* navigation_link_2d.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef NAVIGATION_LINK_2D_H +#define NAVIGATION_LINK_2D_H + +#include "scene/2d/node_2d.h" + +class NavigationLink2D : public Node2D { + GDCLASS(NavigationLink2D, Node2D); + + bool enabled = true; + RID link = RID(); + bool bidirectional = true; + uint32_t navigation_layers = 1; + Vector2 end_location = Vector2(); + Vector2 start_location = Vector2(); + real_t enter_cost = 0.0; + real_t travel_cost = 1.0; + +protected: + static void _bind_methods(); + void _notification(int p_what); + +public: +#ifdef TOOLS_ENABLED + virtual Rect2 _edit_get_rect() const override; + virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const override; +#endif + + void set_enabled(bool p_enabled); + bool is_enabled() const { return enabled; } + + void set_bidirectional(bool p_bidirectional); + bool is_bidirectional() const { return bidirectional; } + + void set_navigation_layers(uint32_t p_navigation_layers); + uint32_t get_navigation_layers() const { return navigation_layers; } + + void set_navigation_layer_value(int p_layer_number, bool p_value); + bool get_navigation_layer_value(int p_layer_number) const; + + void set_start_location(Vector2 p_location); + Vector2 get_start_location() const { return start_location; } + + void set_end_location(Vector2 p_location); + Vector2 get_end_location() const { return end_location; } + + void set_enter_cost(real_t p_enter_cost); + real_t get_enter_cost() const { return enter_cost; } + + void set_travel_cost(real_t p_travel_cost); + real_t get_travel_cost() const { return travel_cost; } + + TypedArray<String> get_configuration_warnings() const override; + + NavigationLink2D(); + ~NavigationLink2D(); +}; + +#endif // NAVIGATION_LINK_2D_H diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index 4599785ce4..7765533016 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -437,8 +437,8 @@ void Node2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_relative_transform_to_parent", "parent"), &Node2D::get_relative_transform_to_parent); ADD_GROUP("Transform", ""); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position", PROPERTY_HINT_RANGE, "-99999,99999,0.001,or_lesser,or_greater,no_slider,suffix:px"), "set_position", "get_position"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians"), "set_rotation", "get_rotation"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position", PROPERTY_HINT_RANGE, "-99999,99999,0.001,or_less,or_greater,no_slider,suffix:px"), "set_position", "get_position"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_less,or_greater,radians"), "set_rotation", "get_rotation"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scale", PROPERTY_HINT_LINK), "set_scale", "get_scale"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "skew", PROPERTY_HINT_RANGE, "-89.9,89.9,0.1,radians"), "set_skew", "get_skew"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "transform", PROPERTY_HINT_NONE, "suffix:px", PROPERTY_USAGE_NONE), "set_transform", "get_transform"); diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index be17299f07..90b2e3d460 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -252,7 +252,7 @@ void PathFollow2D::_validate_property(PropertyInfo &p_property) const { max = path->get_curve()->get_baked_length(); } - p_property.hint_string = "0," + rtos(max) + ",0.01,or_lesser,or_greater"; + p_property.hint_string = "0," + rtos(max) + ",0.01,or_less,or_greater"; } } @@ -293,8 +293,8 @@ void PathFollow2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_lookahead", "lookahead"), &PathFollow2D::set_lookahead); ClassDB::bind_method(D_METHOD("get_lookahead"), &PathFollow2D::get_lookahead); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "progress", PROPERTY_HINT_RANGE, "0,10000,0.01,or_lesser,or_greater,suffix:px"), "set_progress", "get_progress"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "progress_ratio", PROPERTY_HINT_RANGE, "0,1,0.0001,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_progress_ratio", "get_progress_ratio"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "progress", PROPERTY_HINT_RANGE, "0,10000,0.01,or_less,or_greater,suffix:px"), "set_progress", "get_progress"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "progress_ratio", PROPERTY_HINT_RANGE, "0,1,0.0001,or_less,or_greater", PROPERTY_USAGE_EDITOR), "set_progress_ratio", "get_progress_ratio"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "h_offset"), "set_h_offset", "get_h_offset"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "v_offset"), "set_v_offset", "get_v_offset"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rotates"), "set_rotates", "is_rotating"); diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 43158344b4..714d196779 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -1024,7 +1024,7 @@ void RigidBody2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mass", PROPERTY_HINT_RANGE, "0.01,1000,0.01,or_greater,exp,suffix:kg"), "set_mass", "get_mass"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "inertia", PROPERTY_HINT_RANGE, U"0,1000,0.01,or_greater,exp,suffix:kg\u22C5px\u00B2"), "set_inertia", "get_inertia"); ADD_PROPERTY(PropertyInfo(Variant::INT, "center_of_mass_mode", PROPERTY_HINT_ENUM, "Auto,Custom", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_center_of_mass_mode", "get_center_of_mass_mode"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "center_of_mass", PROPERTY_HINT_RANGE, "-10,10,0.01,or_lesser,or_greater,suffix:px"), "set_center_of_mass", "get_center_of_mass"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "center_of_mass", PROPERTY_HINT_RANGE, "-10,10,0.01,or_less,or_greater,suffix:px"), "set_center_of_mass", "get_center_of_mass"); ADD_LINKED_PROPERTY("center_of_mass_mode", "center_of_mass"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_scale", PROPERTY_HINT_RANGE, "-128,128,0.01"), "set_gravity_scale", "get_gravity_scale"); @@ -1142,7 +1142,7 @@ bool CharacterBody2D::move_and_slide() { on_ceiling = false; on_wall = false; - if (!current_platform_velocity.is_equal_approx(Vector2())) { + if (!current_platform_velocity.is_zero_approx()) { PhysicsServer2D::MotionParameters parameters(get_global_transform(), current_platform_velocity * delta, margin); parameters.recovery_as_collision = true; // Also report collisions generated only from recovery. parameters.exclude_bodies.insert(platform_rid); @@ -1241,7 +1241,7 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo break; } - if (result.remainder.is_equal_approx(Vector2())) { + if (result.remainder.is_zero_approx()) { motion = Vector2(); break; } @@ -1325,7 +1325,7 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo sliding_enabled = true; first_slide = false; - if (!collided || motion.is_equal_approx(Vector2())) { + if (!collided || motion.is_zero_approx()) { break; } } @@ -1371,7 +1371,7 @@ void CharacterBody2D::_move_and_slide_floating(double p_delta) { motion_results.push_back(result); _set_collision_direction(result); - if (result.remainder.is_equal_approx(Vector2())) { + if (result.remainder.is_zero_approx()) { motion = Vector2(); break; } @@ -1390,7 +1390,7 @@ void CharacterBody2D::_move_and_slide_floating(double p_delta) { } } - if (!collided || motion.is_equal_approx(Vector2())) { + if (!collided || motion.is_zero_approx()) { break; } diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp index 111a0df89a..5e77902977 100644 --- a/scene/2d/polygon_2d.cpp +++ b/scene/2d/polygon_2d.cpp @@ -640,7 +640,7 @@ void Polygon2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "texture_offset", PROPERTY_HINT_NONE, "suffix:px"), "set_texture_offset", "get_texture_offset"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "texture_scale", PROPERTY_HINT_LINK), "set_texture_scale", "get_texture_scale"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "texture_rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians"), "set_texture_rotation", "get_texture_rotation"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "texture_rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_less,or_greater,radians"), "set_texture_rotation", "get_texture_rotation"); ADD_GROUP("Skeleton", ""); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "skeleton", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Skeleton2D"), "set_skeleton", "get_skeleton"); diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp index b620f58ed7..a02f322ef1 100644 --- a/scene/2d/touch_screen_button.cpp +++ b/scene/2d/touch_screen_button.cpp @@ -264,7 +264,7 @@ bool TouchScreenButton::_is_point_inside(const Point2 &p_point) { if (bitmask.is_valid()) { check_rect = false; if (!touched && Rect2(Point2(), bitmask->get_size()).has_point(coord)) { - if (bitmask->get_bit(coord)) { + if (bitmask->get_bitv(coord)) { touched = true; } } diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp index db7c3233f6..f118080009 100644 --- a/scene/3d/area_3d.cpp +++ b/scene/3d/area_3d.cpp @@ -473,19 +473,19 @@ bool Area3D::is_monitoring() const { } TypedArray<Node3D> Area3D::get_overlapping_bodies() const { - ERR_FAIL_COND_V(!monitoring, Array()); - Array ret; + TypedArray<Node3D> ret; + ERR_FAIL_COND_V_MSG(!monitoring, ret, "Can't find overlapping bodies when monitoring is off."); ret.resize(body_map.size()); int idx = 0; for (const KeyValue<ObjectID, BodyState> &E : body_map) { Object *obj = ObjectDB::get_instance(E.key); - if (!obj) { - ret.resize(ret.size() - 1); //ops - } else { - ret[idx++] = obj; + if (obj) { + ret[idx] = obj; + idx++; } } + ret.resize(idx); return ret; } @@ -506,19 +506,18 @@ bool Area3D::is_monitorable() const { } TypedArray<Area3D> Area3D::get_overlapping_areas() const { - ERR_FAIL_COND_V(!monitoring, Array()); - Array ret; + TypedArray<Area3D> ret; + ERR_FAIL_COND_V_MSG(!monitoring, ret, "Can't find overlapping areas when monitoring is off."); ret.resize(area_map.size()); int idx = 0; for (const KeyValue<ObjectID, AreaState> &E : area_map) { Object *obj = ObjectDB::get_instance(E.key); - if (!obj) { - ret.resize(ret.size() - 1); //ops - } else { - ret[idx++] = obj; + if (obj) { + ret[idx] = obj; + idx++; } } - + ret.resize(idx); return ret; } @@ -728,7 +727,7 @@ void Area3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_point_distance_scale", PROPERTY_HINT_RANGE, "0,1024,0.001,or_greater,exp"), "set_gravity_point_distance_scale", "get_gravity_point_distance_scale"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "gravity_point_center", PROPERTY_HINT_NONE, "suffix:m"), "set_gravity_point_center", "get_gravity_point_center"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "gravity_direction"), "set_gravity_direction", "get_gravity_direction"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity", PROPERTY_HINT_RANGE, U"-32,32,0.001,or_lesser,or_greater,suffix:m/s\u00B2"), "set_gravity", "get_gravity"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity", PROPERTY_HINT_RANGE, U"-32,32,0.001,or_less,or_greater,suffix:m/s\u00B2"), "set_gravity", "get_gravity"); ADD_GROUP("Linear Damp", "linear_damp_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "linear_damp_space_override", PROPERTY_HINT_ENUM, "Disabled,Combine,Combine-Replace,Replace,Replace-Combine", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_linear_damp_space_override_mode", "get_linear_damp_space_override_mode"); diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp index e14bb1aa94..d7bf76a6f6 100644 --- a/scene/3d/cpu_particles_3d.cpp +++ b/scene/3d/cpu_particles_3d.cpp @@ -1568,32 +1568,32 @@ void CPUParticles3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_min", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param_min", "get_param_min", PARAM_INITIAL_LINEAR_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_max", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param_max", "get_param_max", PARAM_INITIAL_LINEAR_VELOCITY); ADD_GROUP("Angular Velocity", "angular_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_min", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_ANGULAR_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_max", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_ANGULAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_min", PROPERTY_HINT_RANGE, "-720,720,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_ANGULAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_max", PROPERTY_HINT_RANGE, "-720,720,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_ANGULAR_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angular_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANGULAR_VELOCITY); ADD_GROUP("Orbit Velocity", "orbit_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_min", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_ORBIT_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_max", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_ORBIT_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_min", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_ORBIT_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_max", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_ORBIT_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "orbit_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ORBIT_VELOCITY); ADD_GROUP("Linear Accel", "linear_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_LINEAR_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_LINEAR_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_LINEAR_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_LINEAR_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "linear_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_LINEAR_ACCEL); ADD_GROUP("Radial Accel", "radial_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_RADIAL_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_RADIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_RADIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_RADIAL_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "radial_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_RADIAL_ACCEL); ADD_GROUP("Tangential Accel", "tangential_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_TANGENTIAL_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_TANGENTIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_TANGENTIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_TANGENTIAL_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "tangential_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_TANGENTIAL_ACCEL); ADD_GROUP("Damping", ""); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_min", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_param_min", "get_param_min", PARAM_DAMPING); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_max", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_param_max", "get_param_max", PARAM_DAMPING); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "damping_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_DAMPING); ADD_GROUP("Angle", ""); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_min", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater,degrees"), "set_param_min", "get_param_min", PARAM_ANGLE); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_max", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater,degrees"), "set_param_max", "get_param_max", PARAM_ANGLE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_min", PROPERTY_HINT_RANGE, "-720,720,0.1,or_less,or_greater,degrees"), "set_param_min", "get_param_min", PARAM_ANGLE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_max", PROPERTY_HINT_RANGE, "-720,720,0.1,or_less,or_greater,degrees"), "set_param_max", "get_param_max", PARAM_ANGLE); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angle_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANGLE); ADD_GROUP("Scale", ""); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "scale_amount_min", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param_min", "get_param_min", PARAM_SCALE); @@ -1613,8 +1613,8 @@ void CPUParticles3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation_max", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param_max", "get_param_max", PARAM_HUE_VARIATION); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "hue_variation_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_HUE_VARIATION); ADD_GROUP("Animation", "anim_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_min", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater,or_lesser"), "set_param_min", "get_param_min", PARAM_ANIM_SPEED); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_max", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater,or_lesser"), "set_param_max", "get_param_max", PARAM_ANIM_SPEED); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_min", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater,or_less"), "set_param_min", "get_param_min", PARAM_ANIM_SPEED); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_max", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater,or_less"), "set_param_max", "get_param_max", PARAM_ANIM_SPEED); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_speed_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANIM_SPEED); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_min", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_min", "get_param_min", PARAM_ANIM_OFFSET); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_max", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_max", "get_param_max", PARAM_ANIM_OFFSET); diff --git a/scene/3d/gpu_particles_collision_3d.cpp b/scene/3d/gpu_particles_collision_3d.cpp index 1cfd889272..24bfa7b6de 100644 --- a/scene/3d/gpu_particles_collision_3d.cpp +++ b/scene/3d/gpu_particles_collision_3d.cpp @@ -807,7 +807,7 @@ void GPUParticlesAttractor3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_directionality", "amount"), &GPUParticlesAttractor3D::set_directionality); ClassDB::bind_method(D_METHOD("get_directionality"), &GPUParticlesAttractor3D::get_directionality); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "strength", PROPERTY_HINT_RANGE, "-128,128,0.01,or_greater,or_lesser"), "set_strength", "get_strength"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "strength", PROPERTY_HINT_RANGE, "-128,128,0.01,or_greater,or_less"), "set_strength", "get_strength"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "attenuation", PROPERTY_HINT_EXP_EASING, "0,8,0.01"), "set_attenuation", "get_attenuation"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "directionality", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_directionality", "get_directionality"); ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_cull_mask", "get_cull_mask"); diff --git a/scene/3d/joint_3d.cpp b/scene/3d/joint_3d.cpp index d5cab6728a..7dc094062b 100644 --- a/scene/3d/joint_3d.cpp +++ b/scene/3d/joint_3d.cpp @@ -309,7 +309,7 @@ void HingeJoint3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit/relaxation", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param", "get_param", PARAM_LIMIT_RELAXATION); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "motor/enable"), "set_flag", "get_flag", FLAG_ENABLE_MOTOR); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "motor/target_velocity", PROPERTY_HINT_RANGE, "-200,200,0.01,or_greater,or_lesser,suffix:m/s"), "set_param", "get_param", PARAM_MOTOR_TARGET_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "motor/target_velocity", PROPERTY_HINT_RANGE, "-200,200,0.01,or_greater,or_less,suffix:m/s"), "set_param", "get_param", PARAM_MOTOR_TARGET_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "motor/max_impulse", PROPERTY_HINT_RANGE, "0.01,1024,0.01"), "set_param", "get_param", PARAM_MOTOR_MAX_IMPULSE); BIND_ENUM_CONSTANT(PARAM_BIAS); diff --git a/scene/3d/lightmap_gi.cpp b/scene/3d/lightmap_gi.cpp index 41a537f7cb..32c112d21f 100644 --- a/scene/3d/lightmap_gi.cpp +++ b/scene/3d/lightmap_gi.cpp @@ -765,11 +765,11 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa MeshesFound &mf = meshes_found.write[m_i]; Size2i lightmap_size = mf.mesh->get_lightmap_size_hint() * mf.lightmap_scale; - Vector<RID> overrides; + TypedArray<RID> overrides; overrides.resize(mf.overrides.size()); for (int i = 0; i < mf.overrides.size(); i++) { if (mf.overrides[i].is_valid()) { - overrides.write[i] = mf.overrides[i]->get_rid(); + overrides[i] = mf.overrides[i]->get_rid(); } } TypedArray<Image> images = RS::get_singleton()->bake_render_uv2(mf.mesh->get_rid(), overrides, lightmap_size); diff --git a/scene/3d/navigation_link_3d.cpp b/scene/3d/navigation_link_3d.cpp new file mode 100644 index 0000000000..47b602c966 --- /dev/null +++ b/scene/3d/navigation_link_3d.cpp @@ -0,0 +1,389 @@ +/*************************************************************************/ +/* navigation_link_3d.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "navigation_link_3d.h" + +#include "mesh_instance_3d.h" +#include "servers/navigation_server_3d.h" + +#ifdef DEBUG_ENABLED +void NavigationLink3D::_update_debug_mesh() { + if (!is_inside_tree()) { + return; + } + + if (Engine::get_singleton()->is_editor_hint()) { + // don't update inside Editor as node 3d gizmo takes care of this + // as collisions and selections for Editor Viewport need to be updated + return; + } + + if (!NavigationServer3D::get_singleton()->get_debug_enabled()) { + if (debug_instance.is_valid()) { + RS::get_singleton()->instance_set_visible(debug_instance, false); + } + return; + } + + if (!debug_instance.is_valid()) { + debug_instance = RenderingServer::get_singleton()->instance_create(); + } + + if (!debug_mesh.is_valid()) { + debug_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); + } + + RID nav_map = get_world_3d()->get_navigation_map(); + real_t search_radius = NavigationServer3D::get_singleton()->map_get_link_connection_radius(nav_map); + Vector3 up_vector = NavigationServer3D::get_singleton()->map_get_up(nav_map); + Vector3::Axis up_axis = up_vector.max_axis_index(); + + debug_mesh->clear_surfaces(); + + Vector<Vector3> lines; + + // Draw line between the points. + lines.push_back(start_location); + lines.push_back(end_location); + + // Draw start location search radius + for (int i = 0; i < 30; i++) { + // Create a circle + const float ra = Math::deg_to_rad((float)(i * 12)); + const float rb = Math::deg_to_rad((float)((i + 1) * 12)); + const Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * search_radius; + const Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * search_radius; + + // Draw axis-aligned circle + switch (up_axis) { + case Vector3::AXIS_X: + lines.append(start_location + Vector3(0, a.x, a.y)); + lines.append(start_location + Vector3(0, b.x, b.y)); + break; + case Vector3::AXIS_Y: + lines.append(start_location + Vector3(a.x, 0, a.y)); + lines.append(start_location + Vector3(b.x, 0, b.y)); + break; + case Vector3::AXIS_Z: + lines.append(start_location + Vector3(a.x, a.y, 0)); + lines.append(start_location + Vector3(b.x, b.y, 0)); + break; + } + } + + // Draw end location search radius + for (int i = 0; i < 30; i++) { + // Create a circle + const float ra = Math::deg_to_rad((float)(i * 12)); + const float rb = Math::deg_to_rad((float)((i + 1) * 12)); + const Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * search_radius; + const Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * search_radius; + + // Draw axis-aligned circle + switch (up_axis) { + case Vector3::AXIS_X: + lines.append(end_location + Vector3(0, a.x, a.y)); + lines.append(end_location + Vector3(0, b.x, b.y)); + break; + case Vector3::AXIS_Y: + lines.append(end_location + Vector3(a.x, 0, a.y)); + lines.append(end_location + Vector3(b.x, 0, b.y)); + break; + case Vector3::AXIS_Z: + lines.append(end_location + Vector3(a.x, a.y, 0)); + lines.append(end_location + Vector3(b.x, b.y, 0)); + break; + } + } + + Array mesh_array; + mesh_array.resize(Mesh::ARRAY_MAX); + mesh_array[Mesh::ARRAY_VERTEX] = lines; + + debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, mesh_array); + + RS::get_singleton()->instance_set_base(debug_instance, debug_mesh->get_rid()); + RS::get_singleton()->instance_set_scenario(debug_instance, get_world_3d()->get_scenario()); + RS::get_singleton()->instance_set_visible(debug_instance, is_visible_in_tree()); + + Ref<StandardMaterial3D> link_material = NavigationServer3D::get_singleton_mut()->get_debug_navigation_link_connections_material(); + Ref<StandardMaterial3D> disabled_link_material = NavigationServer3D::get_singleton_mut()->get_debug_navigation_link_connections_disabled_material(); + + if (enabled) { + RS::get_singleton()->instance_set_surface_override_material(debug_instance, 0, link_material->get_rid()); + } else { + RS::get_singleton()->instance_set_surface_override_material(debug_instance, 0, disabled_link_material->get_rid()); + } +} +#endif // DEBUG_ENABLED + +void NavigationLink3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationLink3D::set_enabled); + ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationLink3D::is_enabled); + + ClassDB::bind_method(D_METHOD("set_bidirectional", "bidirectional"), &NavigationLink3D::set_bidirectional); + ClassDB::bind_method(D_METHOD("is_bidirectional"), &NavigationLink3D::is_bidirectional); + + ClassDB::bind_method(D_METHOD("set_navigation_layers", "navigation_layers"), &NavigationLink3D::set_navigation_layers); + ClassDB::bind_method(D_METHOD("get_navigation_layers"), &NavigationLink3D::get_navigation_layers); + + ClassDB::bind_method(D_METHOD("set_navigation_layer_value", "layer_number", "value"), &NavigationLink3D::set_navigation_layer_value); + ClassDB::bind_method(D_METHOD("get_navigation_layer_value", "layer_number"), &NavigationLink3D::get_navigation_layer_value); + + ClassDB::bind_method(D_METHOD("set_start_location", "location"), &NavigationLink3D::set_start_location); + ClassDB::bind_method(D_METHOD("get_start_location"), &NavigationLink3D::get_start_location); + + ClassDB::bind_method(D_METHOD("set_end_location", "location"), &NavigationLink3D::set_end_location); + ClassDB::bind_method(D_METHOD("get_end_location"), &NavigationLink3D::get_end_location); + + ClassDB::bind_method(D_METHOD("set_enter_cost", "enter_cost"), &NavigationLink3D::set_enter_cost); + ClassDB::bind_method(D_METHOD("get_enter_cost"), &NavigationLink3D::get_enter_cost); + + ClassDB::bind_method(D_METHOD("set_travel_cost", "travel_cost"), &NavigationLink3D::set_travel_cost); + ClassDB::bind_method(D_METHOD("get_travel_cost"), &NavigationLink3D::get_travel_cost); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bidirectional"), "set_bidirectional", "is_bidirectional"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_3D_NAVIGATION), "set_navigation_layers", "get_navigation_layers"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "start_location"), "set_start_location", "get_start_location"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "end_location"), "set_end_location", "get_end_location"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "enter_cost"), "set_enter_cost", "get_enter_cost"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "travel_cost"), "set_travel_cost", "get_travel_cost"); +} + +void NavigationLink3D::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: { + if (enabled) { + NavigationServer3D::get_singleton()->link_set_map(link, get_world_3d()->get_navigation_map()); + + // Update global positions for the link. + Transform3D gt = get_global_transform(); + NavigationServer3D::get_singleton()->link_set_start_location(link, gt.xform(start_location)); + NavigationServer3D::get_singleton()->link_set_end_location(link, gt.xform(end_location)); + } + +#ifdef DEBUG_ENABLED + _update_debug_mesh(); +#endif // DEBUG_ENABLED + } break; + case NOTIFICATION_TRANSFORM_CHANGED: { + // Update global positions for the link. + Transform3D gt = get_global_transform(); + NavigationServer3D::get_singleton()->link_set_start_location(link, gt.xform(start_location)); + NavigationServer3D::get_singleton()->link_set_end_location(link, gt.xform(end_location)); + +#ifdef DEBUG_ENABLED + if (is_inside_tree() && debug_instance.is_valid()) { + RS::get_singleton()->instance_set_transform(debug_instance, get_global_transform()); + } +#endif // DEBUG_ENABLED + } break; + case NOTIFICATION_EXIT_TREE: { + NavigationServer3D::get_singleton()->link_set_map(link, RID()); + +#ifdef DEBUG_ENABLED + if (debug_instance.is_valid()) { + RS::get_singleton()->instance_set_scenario(debug_instance, RID()); + RS::get_singleton()->instance_set_visible(debug_instance, false); + } +#endif // DEBUG_ENABLED + } break; + } +} + +NavigationLink3D::NavigationLink3D() { + link = NavigationServer3D::get_singleton()->link_create(); + set_notify_transform(true); +} + +NavigationLink3D::~NavigationLink3D() { + NavigationServer3D::get_singleton()->free(link); + link = RID(); + +#ifdef DEBUG_ENABLED + if (debug_instance.is_valid()) { + RenderingServer::get_singleton()->free(debug_instance); + } + if (debug_mesh.is_valid()) { + RenderingServer::get_singleton()->free(debug_mesh->get_rid()); + } +#endif // DEBUG_ENABLED +} + +void NavigationLink3D::set_enabled(bool p_enabled) { + if (enabled == p_enabled) { + return; + } + + enabled = p_enabled; + + if (!is_inside_tree()) { + return; + } + + if (enabled) { + NavigationServer3D::get_singleton()->link_set_map(link, get_world_3d()->get_navigation_map()); + } else { + NavigationServer3D::get_singleton()->link_set_map(link, RID()); + } + +#ifdef DEBUG_ENABLED + if (debug_instance.is_valid() && debug_mesh.is_valid()) { + if (enabled) { + Ref<StandardMaterial3D> link_material = NavigationServer3D::get_singleton_mut()->get_debug_navigation_link_connections_material(); + RS::get_singleton()->instance_set_surface_override_material(debug_instance, 0, link_material->get_rid()); + } else { + Ref<StandardMaterial3D> disabled_link_material = NavigationServer3D::get_singleton_mut()->get_debug_navigation_link_connections_disabled_material(); + RS::get_singleton()->instance_set_surface_override_material(debug_instance, 0, disabled_link_material->get_rid()); + } + } +#endif // DEBUG_ENABLED + + update_gizmos(); +} + +void NavigationLink3D::set_bidirectional(bool p_bidirectional) { + if (bidirectional == p_bidirectional) { + return; + } + + bidirectional = p_bidirectional; + + NavigationServer3D::get_singleton()->link_set_bidirectional(link, bidirectional); +} + +void NavigationLink3D::set_navigation_layers(uint32_t p_navigation_layers) { + if (navigation_layers == p_navigation_layers) { + return; + } + + navigation_layers = p_navigation_layers; + + NavigationServer3D::get_singleton()->link_set_navigation_layers(link, navigation_layers); +} + +void NavigationLink3D::set_navigation_layer_value(int p_layer_number, bool p_value) { + ERR_FAIL_COND_MSG(p_layer_number < 1, "Navigation layer number must be between 1 and 32 inclusive."); + ERR_FAIL_COND_MSG(p_layer_number > 32, "Navigation layer number must be between 1 and 32 inclusive."); + + uint32_t _navigation_layers = get_navigation_layers(); + + if (p_value) { + _navigation_layers |= 1 << (p_layer_number - 1); + } else { + _navigation_layers &= ~(1 << (p_layer_number - 1)); + } + + set_navigation_layers(_navigation_layers); +} + +bool NavigationLink3D::get_navigation_layer_value(int p_layer_number) const { + ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Navigation layer number must be between 1 and 32 inclusive."); + ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Navigation layer number must be between 1 and 32 inclusive."); + + return get_navigation_layers() & (1 << (p_layer_number - 1)); +} + +void NavigationLink3D::set_start_location(Vector3 p_location) { + if (start_location.is_equal_approx(p_location)) { + return; + } + + start_location = p_location; + + if (!is_inside_tree()) { + return; + } + + Transform3D gt = get_global_transform(); + NavigationServer3D::get_singleton()->link_set_start_location(link, gt.xform(start_location)); + +#ifdef DEBUG_ENABLED + _update_debug_mesh(); +#endif // DEBUG_ENABLED + + update_gizmos(); + update_configuration_warnings(); +} + +void NavigationLink3D::set_end_location(Vector3 p_location) { + if (end_location.is_equal_approx(p_location)) { + return; + } + + end_location = p_location; + + if (!is_inside_tree()) { + return; + } + + Transform3D gt = get_global_transform(); + NavigationServer3D::get_singleton()->link_set_end_location(link, gt.xform(end_location)); + +#ifdef DEBUG_ENABLED + _update_debug_mesh(); +#endif // DEBUG_ENABLED + + update_gizmos(); + update_configuration_warnings(); +} + +void NavigationLink3D::set_enter_cost(real_t p_enter_cost) { + ERR_FAIL_COND_MSG(p_enter_cost < 0.0, "The enter_cost must be positive."); + if (Math::is_equal_approx(enter_cost, p_enter_cost)) { + return; + } + + enter_cost = p_enter_cost; + + NavigationServer3D::get_singleton()->link_set_enter_cost(link, enter_cost); +} + +void NavigationLink3D::set_travel_cost(real_t p_travel_cost) { + ERR_FAIL_COND_MSG(p_travel_cost < 0.0, "The travel_cost must be positive."); + if (Math::is_equal_approx(travel_cost, p_travel_cost)) { + return; + } + + travel_cost = p_travel_cost; + + NavigationServer3D::get_singleton()->link_set_travel_cost(link, travel_cost); +} + +TypedArray<String> NavigationLink3D::get_configuration_warnings() const { + TypedArray<String> warnings = Node::get_configuration_warnings(); + + if (start_location.is_equal_approx(end_location)) { + warnings.push_back(RTR("NavigationLink3D start location should be different than the end location to be useful.")); + } + + return warnings; +} diff --git a/scene/3d/navigation_link_3d.h b/scene/3d/navigation_link_3d.h new file mode 100644 index 0000000000..1f88075527 --- /dev/null +++ b/scene/3d/navigation_link_3d.h @@ -0,0 +1,90 @@ +/*************************************************************************/ +/* navigation_link_3d.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef NAVIGATION_LINK_3D_H +#define NAVIGATION_LINK_3D_H + +#include "scene/3d/node_3d.h" + +class NavigationLink3D : public Node3D { + GDCLASS(NavigationLink3D, Node3D); + + bool enabled = true; + RID link = RID(); + bool bidirectional = true; + uint32_t navigation_layers = 1; + Vector3 end_location = Vector3(); + Vector3 start_location = Vector3(); + real_t enter_cost = 0.0; + real_t travel_cost = 1.0; + +#ifdef DEBUG_ENABLED + RID debug_instance; + Ref<ArrayMesh> debug_mesh; + + void _update_debug_mesh(); +#endif // DEBUG_ENABLED + +protected: + static void _bind_methods(); + void _notification(int p_what); + +public: + NavigationLink3D(); + ~NavigationLink3D(); + + void set_enabled(bool p_enabled); + bool is_enabled() const { return enabled; } + + void set_bidirectional(bool p_bidirectional); + bool is_bidirectional() const { return bidirectional; } + + void set_navigation_layers(uint32_t p_navigation_layers); + uint32_t get_navigation_layers() const { return navigation_layers; } + + void set_navigation_layer_value(int p_layer_number, bool p_value); + bool get_navigation_layer_value(int p_layer_number) const; + + void set_start_location(Vector3 p_location); + Vector3 get_start_location() const { return start_location; } + + void set_end_location(Vector3 p_location); + Vector3 get_end_location() const { return end_location; } + + void set_enter_cost(real_t p_enter_cost); + real_t get_enter_cost() const { return enter_cost; } + + void set_travel_cost(real_t p_travel_cost); + real_t get_travel_cost() const { return travel_cost; } + + TypedArray<String> get_configuration_warnings() const override; +}; + +#endif // NAVIGATION_LINK_3D_H diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index 426a8c1684..59ec036558 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -792,8 +792,8 @@ void Node3D::look_at(const Vector3 &p_target, const Vector3 &p_up) { void Node3D::look_at_from_position(const Vector3 &p_pos, const Vector3 &p_target, const Vector3 &p_up) { ERR_FAIL_COND_MSG(p_pos.is_equal_approx(p_target), "Node origin and target are in the same position, look_at() failed."); - ERR_FAIL_COND_MSG(p_up.is_equal_approx(Vector3()), "The up vector can't be zero, look_at() failed."); - ERR_FAIL_COND_MSG(p_up.cross(p_target - p_pos).is_equal_approx(Vector3()), "Up vector and direction between node origin and target are aligned, look_at() failed."); + ERR_FAIL_COND_MSG(p_up.is_zero_approx(), "The up vector can't be zero, look_at() failed."); + ERR_FAIL_COND_MSG(p_up.cross(p_target - p_pos).is_zero_approx(), "Up vector and direction between node origin and target are aligned, look_at() failed."); Transform3D lookat = Transform3D(Basis::looking_at(p_target - p_pos, p_up), p_pos); Vector3 original_scale = get_scale(); @@ -1052,8 +1052,8 @@ void Node3D::_bind_methods() { ADD_GROUP("Transform", ""); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "transform", PROPERTY_HINT_NONE, "suffix:m", PROPERTY_USAGE_NO_EDITOR), "set_transform", "get_transform"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "global_transform", PROPERTY_HINT_NONE, "suffix:m", PROPERTY_USAGE_NONE), "set_global_transform", "get_global_transform"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "position", PROPERTY_HINT_RANGE, "-99999,99999,0.001,or_greater,or_lesser,no_slider,suffix:m", PROPERTY_USAGE_EDITOR), "set_position", "get_position"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians", PROPERTY_USAGE_EDITOR), "set_rotation", "get_rotation"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "position", PROPERTY_HINT_RANGE, "-99999,99999,0.001,or_greater,or_less,no_slider,suffix:m", PROPERTY_USAGE_EDITOR), "set_position", "get_position"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_less,or_greater,radians", PROPERTY_USAGE_EDITOR), "set_rotation", "get_rotation"); ADD_PROPERTY(PropertyInfo(Variant::QUATERNION, "quaternion", PROPERTY_HINT_HIDE_QUATERNION_EDIT, "", PROPERTY_USAGE_EDITOR), "set_quaternion", "get_quaternion"); ADD_PROPERTY(PropertyInfo(Variant::BASIS, "basis", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_basis", "get_basis"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "scale", PROPERTY_HINT_LINK, "", PROPERTY_USAGE_EDITOR), "set_scale", "get_scale"); diff --git a/scene/3d/occluder_instance_3d.cpp b/scene/3d/occluder_instance_3d.cpp index c1c309fdbe..015cb9a21d 100644 --- a/scene/3d/occluder_instance_3d.cpp +++ b/scene/3d/occluder_instance_3d.cpp @@ -186,21 +186,21 @@ ArrayOccluder3D::~ArrayOccluder3D() { ///////////////////////////////////////////////// -void QuadOccluder3D::set_size(const Vector2 &p_size) { +void QuadOccluder3D::set_size(const Size2 &p_size) { if (size == p_size) { return; } - size = p_size.max(Vector2()); + size = p_size.max(Size2()); _update(); } -Vector2 QuadOccluder3D::get_size() const { +Size2 QuadOccluder3D::get_size() const { return size; } void QuadOccluder3D::_update_arrays(PackedVector3Array &r_vertices, PackedInt32Array &r_indices) { - Vector2 _size = Vector2(size.x / 2.0f, size.y / 2.0f); + Size2 _size = Size2(size.x / 2.0f, size.y / 2.0f); r_vertices = { Vector3(-_size.x, -_size.y, 0), diff --git a/scene/3d/occluder_instance_3d.h b/scene/3d/occluder_instance_3d.h index 11d731b989..69a80e63fc 100644 --- a/scene/3d/occluder_instance_3d.h +++ b/scene/3d/occluder_instance_3d.h @@ -88,15 +88,15 @@ class QuadOccluder3D : public Occluder3D { GDCLASS(QuadOccluder3D, Occluder3D); private: - Vector2 size = Vector2(1.0f, 1.0f); + Size2 size = Vector2(1.0f, 1.0f); protected: virtual void _update_arrays(PackedVector3Array &r_vertices, PackedInt32Array &r_indices) override; static void _bind_methods(); public: - Vector2 get_size() const; - void set_size(const Vector2 &p_size); + Size2 get_size() const; + void set_size(const Size2 &p_size); QuadOccluder3D(); ~QuadOccluder3D(); diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp index 3d23206e6b..2d1f4a579b 100644 --- a/scene/3d/path_3d.cpp +++ b/scene/3d/path_3d.cpp @@ -337,7 +337,7 @@ void PathFollow3D::_validate_property(PropertyInfo &p_property) const { max = path->get_curve()->get_baked_length(); } - p_property.hint_string = "0," + rtos(max) + ",0.01,or_lesser,or_greater"; + p_property.hint_string = "0," + rtos(max) + ",0.01,or_less,or_greater"; } } @@ -380,8 +380,8 @@ void PathFollow3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_loop", "loop"), &PathFollow3D::set_loop); ClassDB::bind_method(D_METHOD("has_loop"), &PathFollow3D::has_loop); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "progress", PROPERTY_HINT_RANGE, "0,10000,0.01,or_lesser,or_greater,suffix:m"), "set_progress", "get_progress"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "progress_ratio", PROPERTY_HINT_RANGE, "0,1,0.0001,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_progress_ratio", "get_progress_ratio"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "progress", PROPERTY_HINT_RANGE, "0,10000,0.01,or_less,or_greater,suffix:m"), "set_progress", "get_progress"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "progress_ratio", PROPERTY_HINT_RANGE, "0,1,0.0001,or_less,or_greater", PROPERTY_USAGE_EDITOR), "set_progress_ratio", "get_progress_ratio"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "h_offset", PROPERTY_HINT_NONE, "suffix:m"), "set_h_offset", "get_h_offset"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "v_offset", PROPERTY_HINT_NONE, "suffix:m"), "set_v_offset", "get_v_offset"); ADD_PROPERTY(PropertyInfo(Variant::INT, "rotation_mode", PROPERTY_HINT_ENUM, "None,Y,XY,XYZ,Oriented"), "set_rotation_mode", "get_rotation_mode"); diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index 5534bc28f1..8888aa183a 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -1088,7 +1088,7 @@ void RigidBody3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mass", PROPERTY_HINT_RANGE, "0.01,1000,0.01,or_greater,exp,suffix:kg"), "set_mass", "get_mass"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "inertia", PROPERTY_HINT_RANGE, U"0,1000,0.01,or_greater,exp,suffix:kg\u22C5m\u00B2"), "set_inertia", "get_inertia"); ADD_PROPERTY(PropertyInfo(Variant::INT, "center_of_mass_mode", PROPERTY_HINT_ENUM, "Auto,Custom", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_center_of_mass_mode", "get_center_of_mass_mode"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "center_of_mass", PROPERTY_HINT_RANGE, "-10,10,0.01,or_lesser,or_greater,suffix:m"), "set_center_of_mass", "get_center_of_mass"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "center_of_mass", PROPERTY_HINT_RANGE, "-10,10,0.01,or_less,or_greater,suffix:m"), "set_center_of_mass", "get_center_of_mass"); ADD_LINKED_PROPERTY("center_of_mass_mode", "center_of_mass"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_scale", PROPERTY_HINT_RANGE, "-128,128,0.01"), "set_gravity_scale", "get_gravity_scale"); @@ -1208,7 +1208,7 @@ bool CharacterBody3D::move_and_slide() { last_motion = Vector3(); - if (!current_platform_velocity.is_equal_approx(Vector3())) { + if (!current_platform_velocity.is_zero_approx()) { PhysicsServer3D::MotionParameters parameters(get_global_transform(), current_platform_velocity * delta, margin); parameters.recovery_as_collision = true; // Also report collisions generated only from recovery. @@ -1315,7 +1315,7 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo break; } - if (result.remainder.is_equal_approx(Vector3())) { + if (result.remainder.is_zero_approx()) { motion = Vector3(); break; } @@ -1428,7 +1428,7 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo const PhysicsServer3D::MotionCollision &collision = result.collisions[0]; Vector3 slide_motion = result.remainder.slide(collision.normal); - if (collision_state.floor && !collision_state.wall && !motion_slide_up.is_equal_approx(Vector3())) { + if (collision_state.floor && !collision_state.wall && !motion_slide_up.is_zero_approx()) { // Slide using the intersection between the motion plane and the floor plane, // in order to keep the direction intact. real_t motion_length = slide_motion.length(); @@ -1469,7 +1469,7 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo total_travel += result.travel; // Apply Constant Speed. - if (p_was_on_floor && floor_constant_speed && can_apply_constant_speed && collision_state.floor && !motion.is_equal_approx(Vector3())) { + if (p_was_on_floor && floor_constant_speed && can_apply_constant_speed && collision_state.floor && !motion.is_zero_approx()) { Vector3 travel_slide_up = total_travel.slide(up_direction); motion = motion.normalized() * MAX(0, (motion_slide_up.length() - travel_slide_up.length())); } @@ -1492,7 +1492,7 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo collided = true; } - if (!collided || motion.is_equal_approx(Vector3())) { + if (!collided || motion.is_zero_approx()) { break; } @@ -1533,7 +1533,7 @@ void CharacterBody3D::_move_and_slide_floating(double p_delta) { CollisionState result_state; _set_collision_direction(result, result_state); - if (result.remainder.is_equal_approx(Vector3())) { + if (result.remainder.is_zero_approx()) { motion = Vector3(); break; } @@ -1557,7 +1557,7 @@ void CharacterBody3D::_move_and_slide_floating(double p_delta) { } } - if (!collided || motion.is_equal_approx(Vector3())) { + if (!collided || motion.is_zero_approx()) { break; } @@ -2346,7 +2346,7 @@ void PhysicalBone3D::ConeJointData::_get_property_list(List<PropertyInfo> *p_lis JointData::_get_property_list(p_list); p_list->push_back(PropertyInfo(Variant::FLOAT, PNAME("joint_constraints/swing_span"), PROPERTY_HINT_RANGE, "-180,180,0.01")); - p_list->push_back(PropertyInfo(Variant::FLOAT, PNAME("joint_constraints/twist_span"), PROPERTY_HINT_RANGE, "-40000,40000,0.1,or_lesser,or_greater")); + p_list->push_back(PropertyInfo(Variant::FLOAT, PNAME("joint_constraints/twist_span"), PROPERTY_HINT_RANGE, "-40000,40000,0.1,or_less,or_greater")); p_list->push_back(PropertyInfo(Variant::FLOAT, PNAME("joint_constraints/bias"), PROPERTY_HINT_RANGE, "0.01,16.0,0.01")); p_list->push_back(PropertyInfo(Variant::FLOAT, PNAME("joint_constraints/softness"), PROPERTY_HINT_RANGE, "0.01,16.0,0.01")); p_list->push_back(PropertyInfo(Variant::FLOAT, PNAME("joint_constraints/relaxation"), PROPERTY_HINT_RANGE, "0.01,16.0,0.01")); @@ -2997,7 +2997,7 @@ void PhysicalBone3D::_bind_methods() { ADD_GROUP("Joint", "joint_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "joint_type", PROPERTY_HINT_ENUM, "None,PinJoint,ConeJoint,HingeJoint,SliderJoint,6DOFJoint"), "set_joint_type", "get_joint_type"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "joint_offset", PROPERTY_HINT_NONE, "suffix:m"), "set_joint_offset", "get_joint_offset"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "joint_rotation", PROPERTY_HINT_RANGE, "-360,360,0.01,or_lesser,or_greater,radians"), "set_joint_rotation", "get_joint_rotation"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "joint_rotation", PROPERTY_HINT_RANGE, "-360,360,0.01,or_less,or_greater,radians"), "set_joint_rotation", "get_joint_rotation"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "body_offset", PROPERTY_HINT_NONE, "suffix:m"), "set_body_offset", "get_body_offset"); diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index 669c3eb7fd..4515277dc3 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -1174,7 +1174,7 @@ void AnimatedSprite3D::_res_changed() { _queue_update(); } -void AnimatedSprite3D::_set_playing(bool p_playing) { +void AnimatedSprite3D::set_playing(bool p_playing) { if (playing == p_playing) { return; } @@ -1183,7 +1183,7 @@ void AnimatedSprite3D::_set_playing(bool p_playing) { set_process_internal(playing); } -bool AnimatedSprite3D::_is_playing() const { +bool AnimatedSprite3D::is_playing() const { return playing; } @@ -1191,15 +1191,11 @@ void AnimatedSprite3D::play(const StringName &p_animation) { if (p_animation) { set_animation(p_animation); } - _set_playing(true); + set_playing(true); } void AnimatedSprite3D::stop() { - _set_playing(false); -} - -bool AnimatedSprite3D::is_playing() const { - return playing; + set_playing(false); } void AnimatedSprite3D::_reset_timeout() { @@ -1262,12 +1258,11 @@ void AnimatedSprite3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_animation", "animation"), &AnimatedSprite3D::set_animation); ClassDB::bind_method(D_METHOD("get_animation"), &AnimatedSprite3D::get_animation); - ClassDB::bind_method(D_METHOD("_set_playing", "playing"), &AnimatedSprite3D::_set_playing); - ClassDB::bind_method(D_METHOD("_is_playing"), &AnimatedSprite3D::_is_playing); + ClassDB::bind_method(D_METHOD("set_playing", "playing"), &AnimatedSprite3D::set_playing); + ClassDB::bind_method(D_METHOD("is_playing"), &AnimatedSprite3D::is_playing); ClassDB::bind_method(D_METHOD("play", "anim"), &AnimatedSprite3D::play, DEFVAL(StringName())); ClassDB::bind_method(D_METHOD("stop"), &AnimatedSprite3D::stop); - ClassDB::bind_method(D_METHOD("is_playing"), &AnimatedSprite3D::is_playing); ClassDB::bind_method(D_METHOD("set_frame", "frame"), &AnimatedSprite3D::set_frame); ClassDB::bind_method(D_METHOD("get_frame"), &AnimatedSprite3D::get_frame); @@ -1280,7 +1275,7 @@ void AnimatedSprite3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "frames", PROPERTY_HINT_RESOURCE_TYPE, "SpriteFrames"), "set_sprite_frames", "get_sprite_frames"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "animation"), "set_animation", "get_animation"); ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing"), "_set_playing", "_is_playing"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing"), "set_playing", "is_playing"); } AnimatedSprite3D::AnimatedSprite3D() { diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h index 03688cf787..84244a2476 100644 --- a/scene/3d/sprite_3d.h +++ b/scene/3d/sprite_3d.h @@ -219,8 +219,6 @@ class AnimatedSprite3D : public SpriteBase3D { void _res_changed(); void _reset_timeout(); - void _set_playing(bool p_playing); - bool _is_playing() const; RID last_shader; RID last_texture; @@ -237,6 +235,8 @@ public: void play(const StringName &p_animation = StringName()); void stop(); + + void set_playing(bool p_playing); bool is_playing() const; void set_animation(const StringName &p_animation); diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp index 5af06cff29..db9f68544b 100644 --- a/scene/3d/visual_instance_3d.cpp +++ b/scene/3d/visual_instance_3d.cpp @@ -242,7 +242,7 @@ const StringName *GeometryInstance3D::_instance_uniform_get_remap(const StringNa bool GeometryInstance3D::_set(const StringName &p_name, const Variant &p_value) { const StringName *r = _instance_uniform_get_remap(p_name); if (r) { - set_instance_shader_uniform(*r, p_value); + set_instance_shader_parameter(*r, p_value); return true; } #ifndef DISABLE_DEPRECATED @@ -262,7 +262,7 @@ bool GeometryInstance3D::_set(const StringName &p_name, const Variant &p_value) bool GeometryInstance3D::_get(const StringName &p_name, Variant &r_ret) const { const StringName *r = _instance_uniform_get_remap(p_name); if (r) { - r_ret = get_instance_shader_uniform(*r); + r_ret = get_instance_shader_parameter(*r); return true; } @@ -271,10 +271,10 @@ bool GeometryInstance3D::_get(const StringName &p_name, Variant &r_ret) const { void GeometryInstance3D::_get_property_list(List<PropertyInfo> *p_list) const { List<PropertyInfo> pinfo; - RS::get_singleton()->instance_geometry_get_shader_uniform_list(get_instance(), &pinfo); + RS::get_singleton()->instance_geometry_get_shader_parameter_list(get_instance(), &pinfo); for (PropertyInfo &pi : pinfo) { bool has_def_value = false; - Variant def_value = RS::get_singleton()->instance_geometry_get_shader_uniform_default_value(get_instance(), pi.name); + Variant def_value = RS::get_singleton()->instance_geometry_get_shader_parameter_default_value(get_instance(), pi.name); if (def_value.get_type() != Variant::NIL) { has_def_value = true; } @@ -319,24 +319,24 @@ float GeometryInstance3D::get_lod_bias() const { return lod_bias; } -void GeometryInstance3D::set_instance_shader_uniform(const StringName &p_uniform, const Variant &p_value) { +void GeometryInstance3D::set_instance_shader_parameter(const StringName &p_name, const Variant &p_value) { if (p_value.get_type() == Variant::NIL) { - Variant def_value = RS::get_singleton()->instance_geometry_get_shader_uniform_default_value(get_instance(), p_uniform); - RS::get_singleton()->instance_geometry_set_shader_uniform(get_instance(), p_uniform, def_value); + Variant def_value = RS::get_singleton()->instance_geometry_get_shader_parameter_default_value(get_instance(), p_name); + RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_name, def_value); instance_uniforms.erase(p_value); } else { - instance_uniforms[p_uniform] = p_value; + instance_uniforms[p_name] = p_value; if (p_value.get_type() == Variant::OBJECT) { RID tex_id = p_value; - RS::get_singleton()->instance_geometry_set_shader_uniform(get_instance(), p_uniform, tex_id); + RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_name, tex_id); } else { - RS::get_singleton()->instance_geometry_set_shader_uniform(get_instance(), p_uniform, p_value); + RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_name, p_value); } } } -Variant GeometryInstance3D::get_instance_shader_uniform(const StringName &p_uniform) const { - return RS::get_singleton()->instance_geometry_get_shader_uniform(get_instance(), p_uniform); +Variant GeometryInstance3D::get_instance_shader_parameter(const StringName &p_name) const { + return RS::get_singleton()->instance_geometry_get_shader_parameter(get_instance(), p_name); } void GeometryInstance3D::set_custom_aabb(AABB aabb) { @@ -434,8 +434,8 @@ void GeometryInstance3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_visibility_range_fade_mode", "mode"), &GeometryInstance3D::set_visibility_range_fade_mode); ClassDB::bind_method(D_METHOD("get_visibility_range_fade_mode"), &GeometryInstance3D::get_visibility_range_fade_mode); - ClassDB::bind_method(D_METHOD("set_instance_shader_uniform", "uniform", "value"), &GeometryInstance3D::set_instance_shader_uniform); - ClassDB::bind_method(D_METHOD("get_instance_shader_uniform", "uniform"), &GeometryInstance3D::get_instance_shader_uniform); + ClassDB::bind_method(D_METHOD("set_instance_shader_parameter", "name", "value"), &GeometryInstance3D::set_instance_shader_parameter); + ClassDB::bind_method(D_METHOD("get_instance_shader_parameter", "name"), &GeometryInstance3D::get_instance_shader_parameter); ClassDB::bind_method(D_METHOD("set_extra_cull_margin", "margin"), &GeometryInstance3D::set_extra_cull_margin); ClassDB::bind_method(D_METHOD("get_extra_cull_margin"), &GeometryInstance3D::get_extra_cull_margin); diff --git a/scene/3d/visual_instance_3d.h b/scene/3d/visual_instance_3d.h index f7cdcbf411..100d8d8836 100644 --- a/scene/3d/visual_instance_3d.h +++ b/scene/3d/visual_instance_3d.h @@ -178,8 +178,8 @@ public: void set_lightmap_scale(LightmapScale p_scale); LightmapScale get_lightmap_scale() const; - void set_instance_shader_uniform(const StringName &p_uniform, const Variant &p_value); - Variant get_instance_shader_uniform(const StringName &p_uniform) const; + void set_instance_shader_parameter(const StringName &p_name, const Variant &p_value); + Variant get_instance_shader_parameter(const StringName &p_name) const; void set_custom_aabb(AABB aabb); diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp index 3d81b6b9e8..99f17a1eef 100644 --- a/scene/animation/animation_blend_tree.cpp +++ b/scene/animation/animation_blend_tree.cpp @@ -542,7 +542,7 @@ AnimationNodeBlend3::AnimationNodeBlend3() { ///////////////////////////////// void AnimationNodeTimeScale::get_parameter_list(List<PropertyInfo> *r_list) const { - r_list->push_back(PropertyInfo(Variant::FLOAT, scale, PROPERTY_HINT_RANGE, "-32,32,0.01,or_lesser,or_greater")); + r_list->push_back(PropertyInfo(Variant::FLOAT, scale, PROPERTY_HINT_RANGE, "-32,32,0.01,or_less,or_greater")); } Variant AnimationNodeTimeScale::get_parameter_default_value(const StringName &p_parameter) const { diff --git a/scene/gui/box_container.cpp b/scene/gui/box_container.cpp index a56a51a547..151b0b93d4 100644 --- a/scene/gui/box_container.cpp +++ b/scene/gui/box_container.cpp @@ -44,7 +44,6 @@ void BoxContainer::_resort() { Size2i new_size = get_size(); - int sep = get_theme_constant(SNAME("separation")); //,vertical?"VBoxContainer":"HBoxContainer"); bool rtl = is_layout_rtl(); bool first = true; @@ -90,7 +89,7 @@ void BoxContainer::_resort() { return; } - int stretch_max = (vertical ? new_size.height : new_size.width) - (children_count - 1) * sep; + int stretch_max = (vertical ? new_size.height : new_size.width) - (children_count - 1) * theme_cache.separation; int stretch_diff = stretch_max - stretch_min; if (stretch_diff < 0) { //avoid negative stretch space @@ -214,7 +213,7 @@ void BoxContainer::_resort() { if (first) { first = false; } else { - ofs += sep; + ofs += theme_cache.separation; } int from = ofs; @@ -248,7 +247,6 @@ Size2 BoxContainer::get_minimum_size() const { /* Calculate MINIMUM SIZE */ Size2i minimum; - int sep = get_theme_constant(SNAME("separation")); //,vertical?"VBoxContainer":"HBoxContainer"); bool first = true; @@ -273,7 +271,7 @@ Size2 BoxContainer::get_minimum_size() const { minimum.width = size.width; } - minimum.height += size.height + (first ? 0 : sep); + minimum.height += size.height + (first ? 0 : theme_cache.separation); } else { /* HORIZONTAL */ @@ -281,7 +279,7 @@ Size2 BoxContainer::get_minimum_size() const { minimum.height = size.height; } - minimum.width += size.width + (first ? 0 : sep); + minimum.width += size.width + (first ? 0 : theme_cache.separation); } first = false; @@ -290,6 +288,12 @@ Size2 BoxContainer::get_minimum_size() const { return minimum; } +void BoxContainer::_update_theme_item_cache() { + Container::_update_theme_item_cache(); + + theme_cache.separation = get_theme_constant(SNAME("separation")); +} + void BoxContainer::_notification(int p_what) { switch (p_what) { case NOTIFICATION_SORT_CHILDREN: { @@ -307,6 +311,12 @@ void BoxContainer::_notification(int p_what) { } } +void BoxContainer::_validate_property(PropertyInfo &p_property) const { + if (is_fixed && p_property.name == "vertical") { + p_property.usage = PROPERTY_USAGE_NONE; + } +} + void BoxContainer::set_alignment(AlignmentMode p_alignment) { if (alignment == p_alignment) { return; @@ -319,6 +329,17 @@ BoxContainer::AlignmentMode BoxContainer::get_alignment() const { return alignment; } +void BoxContainer::set_vertical(bool p_vertical) { + ERR_FAIL_COND_MSG(is_fixed, "Can't change orientation of " + get_class() + "."); + vertical = p_vertical; + update_minimum_size(); + _resort(); +} + +bool BoxContainer::is_vertical() const { + return vertical; +} + Control *BoxContainer::add_spacer(bool p_begin) { Control *c = memnew(Control); c->set_mouse_filter(MOUSE_FILTER_PASS); //allow spacer to pass mouse events @@ -367,14 +388,17 @@ BoxContainer::BoxContainer(bool p_vertical) { void BoxContainer::_bind_methods() { ClassDB::bind_method(D_METHOD("add_spacer", "begin"), &BoxContainer::add_spacer); - ClassDB::bind_method(D_METHOD("get_alignment"), &BoxContainer::get_alignment); ClassDB::bind_method(D_METHOD("set_alignment", "alignment"), &BoxContainer::set_alignment); + ClassDB::bind_method(D_METHOD("get_alignment"), &BoxContainer::get_alignment); + ClassDB::bind_method(D_METHOD("set_vertical", "vertical"), &BoxContainer::set_vertical); + ClassDB::bind_method(D_METHOD("is_vertical"), &BoxContainer::is_vertical); BIND_ENUM_CONSTANT(ALIGNMENT_BEGIN); BIND_ENUM_CONSTANT(ALIGNMENT_CENTER); BIND_ENUM_CONSTANT(ALIGNMENT_END); ADD_PROPERTY(PropertyInfo(Variant::INT, "alignment", PROPERTY_HINT_ENUM, "Begin,Center,End"), "set_alignment", "get_alignment"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "vertical"), "set_vertical", "is_vertical"); } MarginContainer *VBoxContainer::add_margin_child(const String &p_label, Control *p_control, bool p_expand) { diff --git a/scene/gui/box_container.h b/scene/gui/box_container.h index 3043c3ea45..0ee5bd1772 100644 --- a/scene/gui/box_container.h +++ b/scene/gui/box_container.h @@ -47,11 +47,19 @@ private: bool vertical = false; AlignmentMode alignment = ALIGNMENT_BEGIN; + struct ThemeCache { + int separation = 0; + } theme_cache; + void _resort(); protected: - void _notification(int p_what); + bool is_fixed = false; + + virtual void _update_theme_item_cache() override; + void _notification(int p_what); + void _validate_property(PropertyInfo &p_property) const; static void _bind_methods(); public: @@ -60,6 +68,9 @@ public: void set_alignment(AlignmentMode p_alignment); AlignmentMode get_alignment() const; + void set_vertical(bool p_vertical); + bool is_vertical() const; + virtual Size2 get_minimum_size() const override; virtual Vector<int> get_allowed_size_flags_horizontal() const override; @@ -73,7 +84,7 @@ class HBoxContainer : public BoxContainer { public: HBoxContainer() : - BoxContainer(false) {} + BoxContainer(false) { is_fixed = true; } }; class MarginContainer; @@ -84,7 +95,7 @@ public: MarginContainer *add_margin_child(const String &p_label, Control *p_control, bool p_expand = false); VBoxContainer() : - BoxContainer(true) {} + BoxContainer(true) { is_fixed = true; } }; VARIANT_ENUM_CAST(BoxContainer::AlignmentMode); diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index c7b64ba6c6..c2b82e01d1 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -36,7 +36,7 @@ Size2 Button::get_minimum_size() const { Ref<Texture2D> _icon = icon; if (_icon.is_null() && has_theme_icon(SNAME("icon"))) { - _icon = Control::get_theme_icon(SNAME("icon")); + _icon = theme_cache.icon; } return get_minimum_size_for_text_and_icon("", _icon); @@ -46,6 +46,45 @@ void Button::_set_internal_margin(Side p_side, float p_value) { _internal_margin[p_side] = p_value; } +void Button::_update_theme_item_cache() { + BaseButton::_update_theme_item_cache(); + + theme_cache.normal = get_theme_stylebox(SNAME("normal")); + theme_cache.normal_mirrored = get_theme_stylebox(SNAME("normal_mirrored")); + theme_cache.pressed = get_theme_stylebox(SNAME("pressed")); + theme_cache.pressed_mirrored = get_theme_stylebox(SNAME("pressed_mirrored")); + theme_cache.hover = get_theme_stylebox(SNAME("hover")); + theme_cache.hover_mirrored = get_theme_stylebox(SNAME("hover_mirrored")); + theme_cache.hover_pressed = get_theme_stylebox(SNAME("hover_pressed")); + theme_cache.hover_pressed_mirrored = get_theme_stylebox(SNAME("hover_pressed_mirrored")); + theme_cache.disabled = get_theme_stylebox(SNAME("disabled")); + theme_cache.disabled_mirrored = get_theme_stylebox(SNAME("disabled_mirrored")); + theme_cache.focus = get_theme_stylebox(SNAME("focus")); + + theme_cache.font_color = get_theme_color(SNAME("font_color")); + theme_cache.font_focus_color = get_theme_color(SNAME("font_focus_color")); + theme_cache.font_pressed_color = get_theme_color(SNAME("font_pressed_color")); + theme_cache.font_hover_color = get_theme_color(SNAME("font_hover_color")); + theme_cache.font_hover_pressed_color = get_theme_color(SNAME("font_hover_pressed_color")); + theme_cache.font_disabled_color = get_theme_color(SNAME("font_disabled_color")); + + theme_cache.font = get_theme_font(SNAME("font")); + theme_cache.font_size = get_theme_font_size(SNAME("font_size")); + theme_cache.outline_size = get_theme_constant(SNAME("outline_size")); + theme_cache.font_outline_color = get_theme_color(SNAME("font_outline_color")); + + theme_cache.icon_normal_color = get_theme_color(SNAME("icon_normal_color")); + theme_cache.icon_focus_color = get_theme_color(SNAME("icon_focus_color")); + theme_cache.icon_pressed_color = get_theme_color(SNAME("icon_pressed_color")); + theme_cache.icon_hover_color = get_theme_color(SNAME("icon_hover_color")); + theme_cache.icon_hover_pressed_color = get_theme_color(SNAME("icon_hover_pressed_color")); + theme_cache.icon_disabled_color = get_theme_color(SNAME("icon_disabled_color")); + + theme_cache.icon = get_theme_icon(SNAME("icon")); + + theme_cache.h_separation = get_theme_constant(SNAME("h_separation")); +} + void Button::_notification(int p_what) { switch (p_what) { case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: { @@ -73,15 +112,15 @@ void Button::_notification(int p_what) { Color color; Color color_icon(1, 1, 1, 1); - Ref<StyleBox> style = get_theme_stylebox(SNAME("normal")); + Ref<StyleBox> style = theme_cache.normal; bool rtl = is_layout_rtl(); switch (get_draw_mode()) { case DRAW_NORMAL: { if (rtl && has_theme_stylebox(SNAME("normal_mirrored"))) { - style = get_theme_stylebox(SNAME("normal_mirrored")); + style = theme_cache.normal_mirrored; } else { - style = get_theme_stylebox(SNAME("normal")); + style = theme_cache.normal; } if (!flat) { @@ -90,14 +129,14 @@ void Button::_notification(int p_what) { // Focus colors only take precedence over normal state. if (has_focus()) { - color = get_theme_color(SNAME("font_focus_color")); + color = theme_cache.font_focus_color; if (has_theme_color(SNAME("icon_focus_color"))) { - color_icon = get_theme_color(SNAME("icon_focus_color")); + color_icon = theme_cache.icon_focus_color; } } else { - color = get_theme_color(SNAME("font_color")); + color = theme_cache.font_color; if (has_theme_color(SNAME("icon_normal_color"))) { - color_icon = get_theme_color(SNAME("icon_normal_color")); + color_icon = theme_cache.icon_normal_color; } } } break; @@ -105,19 +144,19 @@ void Button::_notification(int p_what) { // Edge case for CheckButton and CheckBox. if (has_theme_stylebox("hover_pressed")) { if (rtl && has_theme_stylebox(SNAME("hover_pressed_mirrored"))) { - style = get_theme_stylebox(SNAME("hover_pressed_mirrored")); + style = theme_cache.hover_pressed_mirrored; } else { - style = get_theme_stylebox(SNAME("hover_pressed")); + style = theme_cache.hover_pressed; } if (!flat) { style->draw(ci, Rect2(Point2(0, 0), size)); } if (has_theme_color(SNAME("font_hover_pressed_color"))) { - color = get_theme_color(SNAME("font_hover_pressed_color")); + color = theme_cache.font_hover_pressed_color; } if (has_theme_color(SNAME("icon_hover_pressed_color"))) { - color_icon = get_theme_color(SNAME("icon_hover_pressed_color")); + color_icon = theme_cache.icon_hover_pressed_color; } break; @@ -126,53 +165,53 @@ void Button::_notification(int p_what) { } case DRAW_PRESSED: { if (rtl && has_theme_stylebox(SNAME("pressed_mirrored"))) { - style = get_theme_stylebox(SNAME("pressed_mirrored")); + style = theme_cache.pressed_mirrored; } else { - style = get_theme_stylebox(SNAME("pressed")); + style = theme_cache.pressed; } if (!flat) { style->draw(ci, Rect2(Point2(0, 0), size)); } if (has_theme_color(SNAME("font_pressed_color"))) { - color = get_theme_color(SNAME("font_pressed_color")); + color = theme_cache.font_pressed_color; } else { - color = get_theme_color(SNAME("font_color")); + color = theme_cache.font_color; } if (has_theme_color(SNAME("icon_pressed_color"))) { - color_icon = get_theme_color(SNAME("icon_pressed_color")); + color_icon = theme_cache.icon_pressed_color; } } break; case DRAW_HOVER: { if (rtl && has_theme_stylebox(SNAME("hover_mirrored"))) { - style = get_theme_stylebox(SNAME("hover_mirrored")); + style = theme_cache.hover_mirrored; } else { - style = get_theme_stylebox(SNAME("hover")); + style = theme_cache.hover; } if (!flat) { style->draw(ci, Rect2(Point2(0, 0), size)); } - color = get_theme_color(SNAME("font_hover_color")); + color = theme_cache.font_hover_color; if (has_theme_color(SNAME("icon_hover_color"))) { - color_icon = get_theme_color(SNAME("icon_hover_color")); + color_icon = theme_cache.icon_hover_color; } } break; case DRAW_DISABLED: { if (rtl && has_theme_stylebox(SNAME("disabled_mirrored"))) { - style = get_theme_stylebox(SNAME("disabled_mirrored")); + style = theme_cache.disabled_mirrored; } else { - style = get_theme_stylebox(SNAME("disabled")); + style = theme_cache.disabled; } if (!flat) { style->draw(ci, Rect2(Point2(0, 0), size)); } - color = get_theme_color(SNAME("font_disabled_color")); + color = theme_cache.font_disabled_color; if (has_theme_color(SNAME("icon_disabled_color"))) { - color_icon = get_theme_color(SNAME("icon_disabled_color")); + color_icon = theme_cache.icon_disabled_color; } else { color_icon.a = 0.4; } @@ -181,13 +220,13 @@ void Button::_notification(int p_what) { } if (has_focus()) { - Ref<StyleBox> style2 = get_theme_stylebox(SNAME("focus")); + Ref<StyleBox> style2 = theme_cache.focus; style2->draw(ci, Rect2(Point2(), size)); } Ref<Texture2D> _icon; if (icon.is_null() && has_theme_icon(SNAME("icon"))) { - _icon = Control::get_theme_icon(SNAME("icon")); + _icon = theme_cache.icon; } else { _icon = icon; } @@ -217,21 +256,21 @@ void Button::_notification(int p_what) { if (icon_align_rtl_checked == HORIZONTAL_ALIGNMENT_LEFT) { style_offset.x = style->get_margin(SIDE_LEFT); if (_internal_margin[SIDE_LEFT] > 0) { - icon_ofs_region = _internal_margin[SIDE_LEFT] + get_theme_constant(SNAME("h_separation")); + icon_ofs_region = _internal_margin[SIDE_LEFT] + theme_cache.h_separation; } } else if (icon_align_rtl_checked == HORIZONTAL_ALIGNMENT_CENTER) { style_offset.x = 0.0; } else if (icon_align_rtl_checked == HORIZONTAL_ALIGNMENT_RIGHT) { style_offset.x = -style->get_margin(SIDE_RIGHT); if (_internal_margin[SIDE_RIGHT] > 0) { - icon_ofs_region = -_internal_margin[SIDE_RIGHT] - get_theme_constant(SNAME("h_separation")); + icon_ofs_region = -_internal_margin[SIDE_RIGHT] - theme_cache.h_separation; } } style_offset.y = style->get_margin(SIDE_TOP); if (expand_icon) { Size2 _size = get_size() - style->get_offset() * 2; - int icon_text_separation = text.is_empty() ? 0 : get_theme_constant(SNAME("h_separation")); + int icon_text_separation = text.is_empty() ? 0 : theme_cache.h_separation; _size.width -= icon_text_separation + icon_ofs_region; if (!clip_text && icon_align_rtl_checked != HORIZONTAL_ALIGNMENT_CENTER) { _size.width -= text_buf->get_size().width; @@ -261,7 +300,7 @@ void Button::_notification(int p_what) { } } - Point2 icon_ofs = !_icon.is_null() ? Point2(icon_region.size.width + get_theme_constant(SNAME("h_separation")), 0) : Point2(); + Point2 icon_ofs = !_icon.is_null() ? Point2(icon_region.size.width + theme_cache.h_separation, 0) : Point2(); if (align_rtl_checked == HORIZONTAL_ALIGNMENT_CENTER && icon_align_rtl_checked == HORIZONTAL_ALIGNMENT_CENTER) { icon_ofs.x = 0.0; } @@ -271,10 +310,10 @@ void Button::_notification(int p_what) { int text_width = MAX(1, (clip_text || overrun_behavior != TextServer::OVERRUN_NO_TRIMMING) ? MIN(text_clip, text_buf->get_size().x) : text_buf->get_size().x); if (_internal_margin[SIDE_LEFT] > 0) { - text_clip -= _internal_margin[SIDE_LEFT] + get_theme_constant(SNAME("h_separation")); + text_clip -= _internal_margin[SIDE_LEFT] + theme_cache.h_separation; } if (_internal_margin[SIDE_RIGHT] > 0) { - text_clip -= _internal_margin[SIDE_RIGHT] + get_theme_constant(SNAME("h_separation")); + text_clip -= _internal_margin[SIDE_RIGHT] + theme_cache.h_separation; } Point2 text_ofs = (size - style->get_minimum_size() - icon_ofs - text_buf->get_size() - Point2(_internal_margin[SIDE_RIGHT] - _internal_margin[SIDE_LEFT], 0)) / 2.0; @@ -288,7 +327,7 @@ void Button::_notification(int p_what) { icon_ofs.x = 0.0; } if (_internal_margin[SIDE_LEFT] > 0) { - text_ofs.x = style->get_margin(SIDE_LEFT) + icon_ofs.x + _internal_margin[SIDE_LEFT] + get_theme_constant(SNAME("h_separation")); + text_ofs.x = style->get_margin(SIDE_LEFT) + icon_ofs.x + _internal_margin[SIDE_LEFT] + theme_cache.h_separation; } else { text_ofs.x = style->get_margin(SIDE_LEFT) + icon_ofs.x; } @@ -305,7 +344,7 @@ void Button::_notification(int p_what) { } break; case HORIZONTAL_ALIGNMENT_RIGHT: { if (_internal_margin[SIDE_RIGHT] > 0) { - text_ofs.x = size.x - style->get_margin(SIDE_RIGHT) - text_width - _internal_margin[SIDE_RIGHT] - get_theme_constant(SNAME("h_separation")); + text_ofs.x = size.x - style->get_margin(SIDE_RIGHT) - text_width - _internal_margin[SIDE_RIGHT] - theme_cache.h_separation; } else { text_ofs.x = size.x - style->get_margin(SIDE_RIGHT) - text_width; } @@ -316,8 +355,8 @@ void Button::_notification(int p_what) { } break; } - Color font_outline_color = get_theme_color(SNAME("font_outline_color")); - int outline_size = get_theme_constant(SNAME("outline_size")); + Color font_outline_color = theme_cache.font_outline_color; + int outline_size = theme_cache.outline_size; if (outline_size > 0 && font_outline_color.a > 0) { text_buf->draw_outline(ci, text_ofs, outline_size, font_outline_color); } @@ -346,7 +385,7 @@ Size2 Button::get_minimum_size_for_text_and_icon(const String &p_text, Ref<Textu if (icon_alignment != HORIZONTAL_ALIGNMENT_CENTER) { minsize.width += p_icon->get_width(); if (!xl_text.is_empty() || !p_text.is_empty()) { - minsize.width += MAX(0, get_theme_constant(SNAME("h_separation"))); + minsize.width += MAX(0, theme_cache.h_separation); } } else { minsize.width = MAX(minsize.width, p_icon->get_width()); @@ -354,12 +393,12 @@ Size2 Button::get_minimum_size_for_text_and_icon(const String &p_text, Ref<Textu } if (!xl_text.is_empty() || !p_text.is_empty()) { - Ref<Font> font = get_theme_font(SNAME("font")); - float font_height = font->get_height(get_theme_font_size(SNAME("font_size"))); + Ref<Font> font = theme_cache.font; + float font_height = font->get_height(theme_cache.font_size); minsize.height = MAX(font_height, minsize.height); } - return get_theme_stylebox(SNAME("normal"))->get_minimum_size() + minsize; + return theme_cache.normal->get_minimum_size() + minsize; } void Button::_shape(Ref<TextParagraph> p_paragraph, String p_text) { @@ -371,10 +410,15 @@ void Button::_shape(Ref<TextParagraph> p_paragraph, String p_text) { p_text = xl_text; } - Ref<Font> font = get_theme_font(SNAME("font")); - int font_size = get_theme_font_size(SNAME("font_size")); - p_paragraph->clear(); + + Ref<Font> font = theme_cache.font; + int font_size = theme_cache.font_size; + if (font.is_null() || font_size == 0) { + // Can't shape without a valid font and a non-zero size. + return; + } + if (text_direction == Control::TEXT_DIRECTION_INHERITED) { p_paragraph->set_direction(is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR); } else { diff --git a/scene/gui/button.h b/scene/gui/button.h index 23b5c78166..9d9f9763db 100644 --- a/scene/gui/button.h +++ b/scene/gui/button.h @@ -54,10 +54,48 @@ private: HorizontalAlignment icon_alignment = HORIZONTAL_ALIGNMENT_LEFT; float _internal_margin[4] = {}; + struct ThemeCache { + Ref<StyleBox> normal; + Ref<StyleBox> normal_mirrored; + Ref<StyleBox> pressed; + Ref<StyleBox> pressed_mirrored; + Ref<StyleBox> hover; + Ref<StyleBox> hover_mirrored; + Ref<StyleBox> hover_pressed; + Ref<StyleBox> hover_pressed_mirrored; + Ref<StyleBox> disabled; + Ref<StyleBox> disabled_mirrored; + Ref<StyleBox> focus; + + Color font_color; + Color font_focus_color; + Color font_pressed_color; + Color font_hover_color; + Color font_hover_pressed_color; + Color font_disabled_color; + + Ref<Font> font; + int font_size = 0; + int outline_size = 0; + Color font_outline_color; + + Color icon_normal_color; + Color icon_focus_color; + Color icon_pressed_color; + Color icon_hover_color; + Color icon_hover_pressed_color; + Color icon_disabled_color; + + Ref<Texture2D> icon; + + int h_separation = 0; + } theme_cache; + void _shape(Ref<TextParagraph> p_paragraph = Ref<TextParagraph>(), String p_text = ""); protected: void _set_internal_margin(Side p_side, float p_value); + virtual void _update_theme_item_cache() override; void _notification(int p_what); static void _bind_methods(); diff --git a/scene/gui/check_box.cpp b/scene/gui/check_box.cpp index 26edc1f1b0..37db7d53f0 100644 --- a/scene/gui/check_box.cpp +++ b/scene/gui/check_box.cpp @@ -33,39 +33,30 @@ #include "servers/rendering_server.h" Size2 CheckBox::get_icon_size() const { - Ref<Texture2D> checked = Control::get_theme_icon(SNAME("checked")); - Ref<Texture2D> unchecked = Control::get_theme_icon(SNAME("unchecked")); - Ref<Texture2D> radio_checked = Control::get_theme_icon(SNAME("radio_checked")); - Ref<Texture2D> radio_unchecked = Control::get_theme_icon(SNAME("radio_unchecked")); - Ref<Texture2D> checked_disabled = Control::get_theme_icon(SNAME("checked_disabled")); - Ref<Texture2D> unchecked_disabled = Control::get_theme_icon(SNAME("unchecked_disabled")); - Ref<Texture2D> radio_checked_disabled = Control::get_theme_icon(SNAME("radio_checked_disabled")); - Ref<Texture2D> radio_unchecked_disabled = Control::get_theme_icon(SNAME("radio_unchecked_disabled")); - Size2 tex_size = Size2(0, 0); - if (!checked.is_null()) { - tex_size = Size2(checked->get_width(), checked->get_height()); + if (!theme_cache.checked.is_null()) { + tex_size = Size2(theme_cache.checked->get_width(), theme_cache.checked->get_height()); } - if (!unchecked.is_null()) { - tex_size = Size2(MAX(tex_size.width, unchecked->get_width()), MAX(tex_size.height, unchecked->get_height())); + if (!theme_cache.unchecked.is_null()) { + tex_size = Size2(MAX(tex_size.width, theme_cache.unchecked->get_width()), MAX(tex_size.height, theme_cache.unchecked->get_height())); } - if (!radio_checked.is_null()) { - tex_size = Size2(MAX(tex_size.width, radio_checked->get_width()), MAX(tex_size.height, radio_checked->get_height())); + if (!theme_cache.radio_checked.is_null()) { + tex_size = Size2(MAX(tex_size.width, theme_cache.radio_checked->get_width()), MAX(tex_size.height, theme_cache.radio_checked->get_height())); } - if (!radio_unchecked.is_null()) { - tex_size = Size2(MAX(tex_size.width, radio_unchecked->get_width()), MAX(tex_size.height, radio_unchecked->get_height())); + if (!theme_cache.radio_unchecked.is_null()) { + tex_size = Size2(MAX(tex_size.width, theme_cache.radio_unchecked->get_width()), MAX(tex_size.height, theme_cache.radio_unchecked->get_height())); } - if (!checked_disabled.is_null()) { - tex_size = Size2(MAX(tex_size.width, checked_disabled->get_width()), MAX(tex_size.height, checked_disabled->get_height())); + if (!theme_cache.checked_disabled.is_null()) { + tex_size = Size2(MAX(tex_size.width, theme_cache.checked_disabled->get_width()), MAX(tex_size.height, theme_cache.checked_disabled->get_height())); } - if (!unchecked_disabled.is_null()) { - tex_size = Size2(MAX(tex_size.width, unchecked_disabled->get_width()), MAX(tex_size.height, unchecked_disabled->get_height())); + if (!theme_cache.unchecked_disabled.is_null()) { + tex_size = Size2(MAX(tex_size.width, theme_cache.unchecked_disabled->get_width()), MAX(tex_size.height, theme_cache.unchecked_disabled->get_height())); } - if (!radio_checked_disabled.is_null()) { - tex_size = Size2(MAX(tex_size.width, radio_checked_disabled->get_width()), MAX(tex_size.height, radio_checked_disabled->get_height())); + if (!theme_cache.radio_checked_disabled.is_null()) { + tex_size = Size2(MAX(tex_size.width, theme_cache.radio_checked_disabled->get_width()), MAX(tex_size.height, theme_cache.radio_checked_disabled->get_height())); } - if (!radio_unchecked_disabled.is_null()) { - tex_size = Size2(MAX(tex_size.width, radio_unchecked_disabled->get_width()), MAX(tex_size.height, radio_unchecked_disabled->get_height())); + if (!theme_cache.radio_unchecked_disabled.is_null()) { + tex_size = Size2(MAX(tex_size.width, theme_cache.radio_unchecked_disabled->get_width()), MAX(tex_size.height, theme_cache.radio_unchecked_disabled->get_height())); } return tex_size; } @@ -75,14 +66,30 @@ Size2 CheckBox::get_minimum_size() const { Size2 tex_size = get_icon_size(); minsize.width += tex_size.width; if (get_text().length() > 0) { - minsize.width += MAX(0, get_theme_constant(SNAME("h_separation"))); + minsize.width += MAX(0, theme_cache.h_separation); } - Ref<StyleBox> sb = get_theme_stylebox(SNAME("normal")); - minsize.height = MAX(minsize.height, tex_size.height + sb->get_margin(SIDE_TOP) + sb->get_margin(SIDE_BOTTOM)); + minsize.height = MAX(minsize.height, tex_size.height + theme_cache.normal_style->get_margin(SIDE_TOP) + theme_cache.normal_style->get_margin(SIDE_BOTTOM)); return minsize; } +void CheckBox::_update_theme_item_cache() { + Button::_update_theme_item_cache(); + + theme_cache.h_separation = get_theme_constant(SNAME("h_separation")); + theme_cache.check_v_adjust = get_theme_constant(SNAME("check_v_adjust")); + theme_cache.normal_style = get_theme_stylebox(SNAME("normal")); + + theme_cache.checked = get_theme_icon(SNAME("checked")); + theme_cache.unchecked = get_theme_icon(SNAME("unchecked")); + theme_cache.radio_checked = get_theme_icon(SNAME("radio_checked")); + theme_cache.radio_unchecked = get_theme_icon(SNAME("radio_unchecked")); + theme_cache.checked_disabled = get_theme_icon(SNAME("checked_disabled")); + theme_cache.unchecked_disabled = get_theme_icon(SNAME("unchecked_disabled")); + theme_cache.radio_checked_disabled = get_theme_icon(SNAME("radio_checked_disabled")); + theme_cache.radio_unchecked_disabled = get_theme_icon(SNAME("radio_unchecked_disabled")); +} + void CheckBox::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: @@ -100,22 +107,39 @@ void CheckBox::_notification(int p_what) { case NOTIFICATION_DRAW: { RID ci = get_canvas_item(); - Ref<Texture2D> on = Control::get_theme_icon(vformat("%s%s", is_radio() ? "radio_checked" : "checked", is_disabled() ? "_disabled" : "")); - Ref<Texture2D> off = Control::get_theme_icon(vformat("%s%s", is_radio() ? "radio_unchecked" : "unchecked", is_disabled() ? "_disabled" : "")); - Ref<StyleBox> sb = get_theme_stylebox(SNAME("normal")); + Ref<Texture2D> on_tex; + Ref<Texture2D> off_tex; + + if (is_radio()) { + if (is_disabled()) { + on_tex = theme_cache.radio_checked_disabled; + off_tex = theme_cache.radio_unchecked_disabled; + } else { + on_tex = theme_cache.radio_checked; + off_tex = theme_cache.radio_unchecked; + } + } else { + if (is_disabled()) { + on_tex = theme_cache.checked_disabled; + off_tex = theme_cache.unchecked_disabled; + } else { + on_tex = theme_cache.checked; + off_tex = theme_cache.unchecked; + } + } Vector2 ofs; if (is_layout_rtl()) { - ofs.x = get_size().x - sb->get_margin(SIDE_RIGHT) - get_icon_size().width; + ofs.x = get_size().x - theme_cache.normal_style->get_margin(SIDE_RIGHT) - get_icon_size().width; } else { - ofs.x = sb->get_margin(SIDE_LEFT); + ofs.x = theme_cache.normal_style->get_margin(SIDE_LEFT); } - ofs.y = int((get_size().height - get_icon_size().height) / 2) + get_theme_constant(SNAME("check_v_adjust")); + ofs.y = int((get_size().height - get_icon_size().height) / 2) + theme_cache.check_v_adjust; if (is_pressed()) { - on->draw(ci, ofs); + on_tex->draw(ci, ofs); } else { - off->draw(ci, ofs); + off_tex->draw(ci, ofs); } } break; } diff --git a/scene/gui/check_box.h b/scene/gui/check_box.h index fcdb2ce08c..beafece3dc 100644 --- a/scene/gui/check_box.h +++ b/scene/gui/check_box.h @@ -36,9 +36,26 @@ class CheckBox : public Button { GDCLASS(CheckBox, Button); + struct ThemeCache { + int h_separation = 0; + int check_v_adjust = 0; + Ref<StyleBox> normal_style; + + Ref<Texture2D> checked; + Ref<Texture2D> unchecked; + Ref<Texture2D> radio_checked; + Ref<Texture2D> radio_unchecked; + Ref<Texture2D> checked_disabled; + Ref<Texture2D> unchecked_disabled; + Ref<Texture2D> radio_checked_disabled; + Ref<Texture2D> radio_unchecked_disabled; + } theme_cache; + protected: Size2 get_icon_size() const; Size2 get_minimum_size() const override; + + virtual void _update_theme_item_cache() override; void _notification(int p_what); bool is_radio(); diff --git a/scene/gui/check_button.cpp b/scene/gui/check_button.cpp index b9674ca41e..b01081e31b 100644 --- a/scene/gui/check_button.cpp +++ b/scene/gui/check_button.cpp @@ -34,14 +34,33 @@ #include "servers/rendering_server.h" Size2 CheckButton::get_icon_size() const { - Ref<Texture2D> on = Control::get_theme_icon(is_disabled() ? "on_disabled" : "on"); - Ref<Texture2D> off = Control::get_theme_icon(is_disabled() ? "off_disabled" : "off"); + Ref<Texture2D> on_tex; + Ref<Texture2D> off_tex; + + if (is_layout_rtl()) { + if (is_disabled()) { + on_tex = theme_cache.checked_disabled_mirrored; + off_tex = theme_cache.unchecked_disabled_mirrored; + } else { + on_tex = theme_cache.checked_mirrored; + off_tex = theme_cache.unchecked_mirrored; + } + } else { + if (is_disabled()) { + on_tex = theme_cache.checked_disabled; + off_tex = theme_cache.unchecked_disabled; + } else { + on_tex = theme_cache.checked; + off_tex = theme_cache.unchecked; + } + } + Size2 tex_size = Size2(0, 0); - if (!on.is_null()) { - tex_size = Size2(on->get_width(), on->get_height()); + if (!on_tex.is_null()) { + tex_size = Size2(on_tex->get_width(), on_tex->get_height()); } - if (!off.is_null()) { - tex_size = Size2(MAX(tex_size.width, off->get_width()), MAX(tex_size.height, off->get_height())); + if (!off_tex.is_null()) { + tex_size = Size2(MAX(tex_size.width, off_tex->get_width()), MAX(tex_size.height, off_tex->get_height())); } return tex_size; @@ -52,14 +71,30 @@ Size2 CheckButton::get_minimum_size() const { Size2 tex_size = get_icon_size(); minsize.width += tex_size.width; if (get_text().length() > 0) { - minsize.width += MAX(0, get_theme_constant(SNAME("h_separation"))); + minsize.width += MAX(0, theme_cache.h_separation); } - Ref<StyleBox> sb = get_theme_stylebox(SNAME("normal")); - minsize.height = MAX(minsize.height, tex_size.height + sb->get_margin(SIDE_TOP) + sb->get_margin(SIDE_BOTTOM)); + minsize.height = MAX(minsize.height, tex_size.height + theme_cache.normal_style->get_margin(SIDE_TOP) + theme_cache.normal_style->get_margin(SIDE_BOTTOM)); return minsize; } +void CheckButton::_update_theme_item_cache() { + Button::_update_theme_item_cache(); + + theme_cache.h_separation = get_theme_constant(SNAME("h_separation")); + theme_cache.check_v_adjust = get_theme_constant(SNAME("check_v_adjust")); + theme_cache.normal_style = get_theme_stylebox(SNAME("normal")); + + theme_cache.checked = get_theme_icon(SNAME("on")); + theme_cache.unchecked = get_theme_icon(SNAME("off")); + theme_cache.checked_disabled = get_theme_icon(SNAME("on_disabled")); + theme_cache.unchecked_disabled = get_theme_icon(SNAME("off_disabled")); + theme_cache.checked_mirrored = get_theme_icon(SNAME("on_mirrored")); + theme_cache.unchecked_mirrored = get_theme_icon(SNAME("off_mirrored")); + theme_cache.checked_disabled_mirrored = get_theme_icon(SNAME("on_disabled_mirrored")); + theme_cache.unchecked_disabled_mirrored = get_theme_icon(SNAME("off_disabled_mirrored")); +} + void CheckButton::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: @@ -78,34 +113,41 @@ void CheckButton::_notification(int p_what) { RID ci = get_canvas_item(); bool rtl = is_layout_rtl(); - Ref<Texture2D> on; - if (rtl) { - on = Control::get_theme_icon(is_disabled() ? "on_disabled_mirrored" : "on_mirrored"); - } else { - on = Control::get_theme_icon(is_disabled() ? "on_disabled" : "on"); - } - Ref<Texture2D> off; + Ref<Texture2D> on_tex; + Ref<Texture2D> off_tex; + if (rtl) { - off = Control::get_theme_icon(is_disabled() ? "off_disabled_mirrored" : "off_mirrored"); + if (is_disabled()) { + on_tex = theme_cache.checked_disabled_mirrored; + off_tex = theme_cache.unchecked_disabled_mirrored; + } else { + on_tex = theme_cache.checked_mirrored; + off_tex = theme_cache.unchecked_mirrored; + } } else { - off = Control::get_theme_icon(is_disabled() ? "off_disabled" : "off"); + if (is_disabled()) { + on_tex = theme_cache.checked_disabled; + off_tex = theme_cache.unchecked_disabled; + } else { + on_tex = theme_cache.checked; + off_tex = theme_cache.unchecked; + } } - Ref<StyleBox> sb = get_theme_stylebox(SNAME("normal")); Vector2 ofs; Size2 tex_size = get_icon_size(); if (rtl) { - ofs.x = sb->get_margin(SIDE_LEFT); + ofs.x = theme_cache.normal_style->get_margin(SIDE_LEFT); } else { - ofs.x = get_size().width - (tex_size.width + sb->get_margin(SIDE_RIGHT)); + ofs.x = get_size().width - (tex_size.width + theme_cache.normal_style->get_margin(SIDE_RIGHT)); } - ofs.y = (get_size().height - tex_size.height) / 2 + get_theme_constant(SNAME("check_v_adjust")); + ofs.y = (get_size().height - tex_size.height) / 2 + theme_cache.check_v_adjust; if (is_pressed()) { - on->draw(ci, ofs); + on_tex->draw(ci, ofs); } else { - off->draw(ci, ofs); + off_tex->draw(ci, ofs); } } break; } diff --git a/scene/gui/check_button.h b/scene/gui/check_button.h index 7d4bb8bdfc..e71472c870 100644 --- a/scene/gui/check_button.h +++ b/scene/gui/check_button.h @@ -36,9 +36,26 @@ class CheckButton : public Button { GDCLASS(CheckButton, Button); + struct ThemeCache { + int h_separation = 0; + int check_v_adjust = 0; + Ref<StyleBox> normal_style; + + Ref<Texture2D> checked; + Ref<Texture2D> unchecked; + Ref<Texture2D> checked_disabled; + Ref<Texture2D> unchecked_disabled; + Ref<Texture2D> checked_mirrored; + Ref<Texture2D> unchecked_mirrored; + Ref<Texture2D> checked_disabled_mirrored; + Ref<Texture2D> unchecked_disabled_mirrored; + } theme_cache; + protected: Size2 get_icon_size() const; virtual Size2 get_minimum_size() const override; + + virtual void _update_theme_item_cache() override; void _notification(int p_what); public: diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 3030fdff8d..41ed1d16c4 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -853,7 +853,7 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) { } else if (p_which == 2) { c->draw_rect(Rect2(Point2(), c->get_size()), Color(1, 1, 1)); if (actual_shape == SHAPE_VHS_CIRCLE || actual_shape == SHAPE_OKHSL_CIRCLE) { - circle_mat->set_shader_uniform("v", v); + circle_mat->set_shader_parameter("v", v); } } } diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 5e8d5a567f..bcf5a8a47f 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -44,6 +44,7 @@ #include "scene/main/window.h" #include "scene/scene_string_names.h" #include "scene/theme/theme_db.h" +#include "scene/theme/theme_owner.h" #include "servers/rendering_server.h" #include "servers/text_server.h" @@ -2261,57 +2262,9 @@ bool Control::is_clipping_contents() { // Theming. -void Control::_propagate_theme_changed(Node *p_at, Control *p_owner, Window *p_owner_window, bool p_notify, bool p_assign) { - Control *c = Object::cast_to<Control>(p_at); - Window *w = c == nullptr ? Object::cast_to<Window>(p_at) : nullptr; - - if (!c && !w) { - // Theme inheritance chains are broken by nodes that aren't Control or Window. - return; - } - - bool assign = p_assign; - if (c) { - if (c != p_owner && c->data.theme.is_valid()) { - // Has a theme, so we don't want to change the theme owner, - // but we still want to propagate in case this child has theme items - // it inherits from the theme this node uses. - // See https://github.com/godotengine/godot/issues/62844. - assign = false; - } - - if (assign) { - c->data.theme_owner = p_owner; - c->data.theme_owner_window = p_owner_window; - } - - if (p_notify) { - c->notification(Control::NOTIFICATION_THEME_CHANGED); - } - } else if (w) { - if (w != p_owner_window && w->theme.is_valid()) { - // Same as above. - assign = false; - } - - if (assign) { - w->theme_owner = p_owner; - w->theme_owner_window = p_owner_window; - } - - if (p_notify) { - w->notification(Window::NOTIFICATION_THEME_CHANGED); - } - } - - for (int i = 0; i < p_at->get_child_count(); i++) { - _propagate_theme_changed(p_at->get_child(i), p_owner, p_owner_window, p_notify, assign); - } -} - void Control::_theme_changed() { if (is_inside_tree()) { - _propagate_theme_changed(this, this, nullptr, true, false); + data.theme_owner->propagate_theme_changed(this, this, true, false); } } @@ -2330,6 +2283,21 @@ void Control::_invalidate_theme_cache() { data.theme_constant_cache.clear(); } +void Control::_update_theme_item_cache() { +} + +void Control::set_theme_owner_node(Node *p_node) { + data.theme_owner->set_owner_node(p_node); +} + +Node *Control::get_theme_owner_node() const { + return data.theme_owner->get_owner_node(); +} + +bool Control::has_theme_owner_node() const { + return data.theme_owner->has_owner_node(); +} + void Control::set_theme(const Ref<Theme> &p_theme) { if (data.theme == p_theme) { return; @@ -2341,24 +2309,24 @@ void Control::set_theme(const Ref<Theme> &p_theme) { data.theme = p_theme; if (data.theme.is_valid()) { - _propagate_theme_changed(this, this, nullptr, is_inside_tree(), true); + data.theme_owner->propagate_theme_changed(this, this, is_inside_tree(), true); data.theme->connect("changed", callable_mp(this, &Control::_theme_changed), CONNECT_DEFERRED); return; } Control *parent_c = Object::cast_to<Control>(get_parent()); - if (parent_c && (parent_c->data.theme_owner || parent_c->data.theme_owner_window)) { - _propagate_theme_changed(this, parent_c->data.theme_owner, parent_c->data.theme_owner_window, is_inside_tree(), true); + if (parent_c && parent_c->has_theme_owner_node()) { + data.theme_owner->propagate_theme_changed(this, parent_c->get_theme_owner_node(), is_inside_tree(), true); return; } Window *parent_w = cast_to<Window>(get_parent()); - if (parent_w && (parent_w->theme_owner || parent_w->theme_owner_window)) { - _propagate_theme_changed(this, parent_w->theme_owner, parent_w->theme_owner_window, is_inside_tree(), true); + if (parent_w && parent_w->has_theme_owner_node()) { + data.theme_owner->propagate_theme_changed(this, parent_w->get_theme_owner_node(), is_inside_tree(), true); return; } - _propagate_theme_changed(this, nullptr, nullptr, is_inside_tree(), true); + data.theme_owner->propagate_theme_changed(this, nullptr, is_inside_tree(), true); } Ref<Theme> Control::get_theme() const { @@ -2381,130 +2349,6 @@ StringName Control::get_theme_type_variation() const { /// Theme property lookup. -template <class T> -T Control::get_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner_window, Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types) { - ERR_FAIL_COND_V_MSG(p_theme_types.size() == 0, T(), "At least one theme type must be specified."); - - // First, look through each control or window node in the branch, until no valid parent can be found. - // Only nodes with a theme resource attached are considered. - Control *theme_owner = p_theme_owner; - Window *theme_owner_window = p_theme_owner_window; - - while (theme_owner || theme_owner_window) { - // For each theme resource check the theme types provided and see if p_name exists with any of them. - for (const StringName &E : p_theme_types) { - if (theme_owner && theme_owner->data.theme->has_theme_item(p_data_type, p_name, E)) { - return theme_owner->data.theme->get_theme_item(p_data_type, p_name, E); - } - - if (theme_owner_window && theme_owner_window->theme->has_theme_item(p_data_type, p_name, E)) { - return theme_owner_window->theme->get_theme_item(p_data_type, p_name, E); - } - } - - Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); - Control *parent_c = Object::cast_to<Control>(parent); - if (parent_c) { - theme_owner = parent_c->data.theme_owner; - theme_owner_window = parent_c->data.theme_owner_window; - } else { - Window *parent_w = Object::cast_to<Window>(parent); - if (parent_w) { - theme_owner = parent_w->theme_owner; - theme_owner_window = parent_w->theme_owner_window; - } else { - theme_owner = nullptr; - theme_owner_window = nullptr; - } - } - } - - // Secondly, check the project-defined Theme resource. - if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { - for (const StringName &E : p_theme_types) { - if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(p_data_type, p_name, E)) { - return ThemeDB::get_singleton()->get_project_theme()->get_theme_item(p_data_type, p_name, E); - } - } - } - - // Lastly, fall back on the items defined in the default Theme, if they exist. - for (const StringName &E : p_theme_types) { - if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(p_data_type, p_name, E)) { - return ThemeDB::get_singleton()->get_default_theme()->get_theme_item(p_data_type, p_name, E); - } - } - // If they don't exist, use any type to return the default/empty value. - return ThemeDB::get_singleton()->get_default_theme()->get_theme_item(p_data_type, p_name, p_theme_types[0]); -} - -bool Control::has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner_window, Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types) { - ERR_FAIL_COND_V_MSG(p_theme_types.size() == 0, false, "At least one theme type must be specified."); - - // First, look through each control or window node in the branch, until no valid parent can be found. - // Only nodes with a theme resource attached are considered. - Control *theme_owner = p_theme_owner; - Window *theme_owner_window = p_theme_owner_window; - - while (theme_owner || theme_owner_window) { - // For each theme resource check the theme types provided and see if p_name exists with any of them. - for (const StringName &E : p_theme_types) { - if (theme_owner && theme_owner->data.theme->has_theme_item(p_data_type, p_name, E)) { - return true; - } - - if (theme_owner_window && theme_owner_window->theme->has_theme_item(p_data_type, p_name, E)) { - return true; - } - } - - Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); - Control *parent_c = Object::cast_to<Control>(parent); - if (parent_c) { - theme_owner = parent_c->data.theme_owner; - theme_owner_window = parent_c->data.theme_owner_window; - } else { - Window *parent_w = Object::cast_to<Window>(parent); - if (parent_w) { - theme_owner = parent_w->theme_owner; - theme_owner_window = parent_w->theme_owner_window; - } else { - theme_owner = nullptr; - theme_owner_window = nullptr; - } - } - } - - // Secondly, check the project-defined Theme resource. - if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { - for (const StringName &E : p_theme_types) { - if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(p_data_type, p_name, E)) { - return true; - } - } - } - - // Lastly, fall back on the items defined in the default Theme, if they exist. - for (const StringName &E : p_theme_types) { - if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(p_data_type, p_name, E)) { - return true; - } - } - return false; -} - -void Control::_get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - if (ThemeDB::get_singleton()->get_project_theme().is_valid() && ThemeDB::get_singleton()->get_project_theme()->get_type_variation_base(data.theme_type_variation) != StringName()) { - ThemeDB::get_singleton()->get_project_theme()->get_type_dependencies(get_class_name(), data.theme_type_variation, p_list); - } else { - ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(get_class_name(), data.theme_type_variation, p_list); - } - } else { - ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(p_theme_type, StringName(), p_list); - } -} - Ref<Texture2D> Control::get_theme_icon(const StringName &p_name, const StringName &p_theme_type) const { if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { const Ref<Texture2D> *tex = data.icon_override.getptr(p_name); @@ -2518,8 +2362,8 @@ Ref<Texture2D> Control::get_theme_icon(const StringName &p_name, const StringNam } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - Ref<Texture2D> icon = get_theme_item_in_types<Ref<Texture2D>>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_ICON, p_name, theme_types); + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Ref<Texture2D> icon = data.theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_ICON, p_name, theme_types); data.theme_icon_cache[p_theme_type][p_name] = icon; return icon; } @@ -2537,8 +2381,8 @@ Ref<StyleBox> Control::get_theme_stylebox(const StringName &p_name, const String } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - Ref<StyleBox> style = get_theme_item_in_types<Ref<StyleBox>>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Ref<StyleBox> style = data.theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); data.theme_style_cache[p_theme_type][p_name] = style; return style; } @@ -2556,8 +2400,8 @@ Ref<Font> Control::get_theme_font(const StringName &p_name, const StringName &p_ } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - Ref<Font> font = get_theme_item_in_types<Ref<Font>>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT, p_name, theme_types); + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Ref<Font> font = data.theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_FONT, p_name, theme_types); data.theme_font_cache[p_theme_type][p_name] = font; return font; } @@ -2575,8 +2419,8 @@ int Control::get_theme_font_size(const StringName &p_name, const StringName &p_t } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - int font_size = get_theme_item_in_types<int>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + int font_size = data.theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); data.theme_font_size_cache[p_theme_type][p_name] = font_size; return font_size; } @@ -2594,8 +2438,8 @@ Color Control::get_theme_color(const StringName &p_name, const StringName &p_the } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - Color color = get_theme_item_in_types<Color>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_COLOR, p_name, theme_types); + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Color color = data.theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_COLOR, p_name, theme_types); data.theme_color_cache[p_theme_type][p_name] = color; return color; } @@ -2613,8 +2457,8 @@ int Control::get_theme_constant(const StringName &p_name, const StringName &p_th } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - int constant = get_theme_item_in_types<int>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_CONSTANT, p_name, theme_types); + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + int constant = data.theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_CONSTANT, p_name, theme_types); data.theme_constant_cache[p_theme_type][p_name] = constant; return constant; } @@ -2627,8 +2471,8 @@ bool Control::has_theme_icon(const StringName &p_name, const StringName &p_theme } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_ICON, p_name, theme_types); + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + return data.theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_ICON, p_name, theme_types); } bool Control::has_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const { @@ -2639,8 +2483,8 @@ bool Control::has_theme_stylebox(const StringName &p_name, const StringName &p_t } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + return data.theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); } bool Control::has_theme_font(const StringName &p_name, const StringName &p_theme_type) const { @@ -2651,8 +2495,8 @@ bool Control::has_theme_font(const StringName &p_name, const StringName &p_theme } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT, p_name, theme_types); + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + return data.theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_FONT, p_name, theme_types); } bool Control::has_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const { @@ -2663,8 +2507,8 @@ bool Control::has_theme_font_size(const StringName &p_name, const StringName &p_ } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + return data.theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); } bool Control::has_theme_color(const StringName &p_name, const StringName &p_theme_type) const { @@ -2675,8 +2519,8 @@ bool Control::has_theme_color(const StringName &p_name, const StringName &p_them } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_COLOR, p_name, theme_types); + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + return data.theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_COLOR, p_name, theme_types); } bool Control::has_theme_constant(const StringName &p_name, const StringName &p_theme_type) const { @@ -2687,8 +2531,8 @@ bool Control::has_theme_constant(const StringName &p_name, const StringName &p_t } List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_CONSTANT, p_name, theme_types); + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + return data.theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_CONSTANT, p_name, theme_types); } /// Local property overrides. @@ -2818,157 +2662,16 @@ bool Control::has_theme_constant_override(const StringName &p_name) const { /// Default theme properties. -float Control::fetch_theme_default_base_scale(Control *p_theme_owner, Window *p_theme_owner_window) { - // First, look through each control or window node in the branch, until no valid parent can be found. - // Only nodes with a theme resource attached are considered. - // For each theme resource see if their assigned theme has the default value defined and valid. - Control *theme_owner = p_theme_owner; - Window *theme_owner_window = p_theme_owner_window; - - while (theme_owner || theme_owner_window) { - if (theme_owner && theme_owner->data.theme->has_default_base_scale()) { - return theme_owner->data.theme->get_default_base_scale(); - } - - if (theme_owner_window && theme_owner_window->theme->has_default_base_scale()) { - return theme_owner_window->theme->get_default_base_scale(); - } - - Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); - Control *parent_c = Object::cast_to<Control>(parent); - if (parent_c) { - theme_owner = parent_c->data.theme_owner; - theme_owner_window = parent_c->data.theme_owner_window; - } else { - Window *parent_w = Object::cast_to<Window>(parent); - if (parent_w) { - theme_owner = parent_w->theme_owner; - theme_owner_window = parent_w->theme_owner_window; - } else { - theme_owner = nullptr; - theme_owner_window = nullptr; - } - } - } - - // Secondly, check the project-defined Theme resource. - if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { - if (ThemeDB::get_singleton()->get_project_theme()->has_default_base_scale()) { - return ThemeDB::get_singleton()->get_project_theme()->get_default_base_scale(); - } - } - - // Lastly, fall back on the default Theme. - if (ThemeDB::get_singleton()->get_default_theme()->has_default_base_scale()) { - return ThemeDB::get_singleton()->get_default_theme()->get_default_base_scale(); - } - return ThemeDB::get_singleton()->get_fallback_base_scale(); -} - float Control::get_theme_default_base_scale() const { - return fetch_theme_default_base_scale(data.theme_owner, data.theme_owner_window); -} - -Ref<Font> Control::fetch_theme_default_font(Control *p_theme_owner, Window *p_theme_owner_window) { - // First, look through each control or window node in the branch, until no valid parent can be found. - // Only nodes with a theme resource attached are considered. - // For each theme resource see if their assigned theme has the default value defined and valid. - Control *theme_owner = p_theme_owner; - Window *theme_owner_window = p_theme_owner_window; - - while (theme_owner || theme_owner_window) { - if (theme_owner && theme_owner->data.theme->has_default_font()) { - return theme_owner->data.theme->get_default_font(); - } - - if (theme_owner_window && theme_owner_window->theme->has_default_font()) { - return theme_owner_window->theme->get_default_font(); - } - - Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); - Control *parent_c = Object::cast_to<Control>(parent); - if (parent_c) { - theme_owner = parent_c->data.theme_owner; - theme_owner_window = parent_c->data.theme_owner_window; - } else { - Window *parent_w = Object::cast_to<Window>(parent); - if (parent_w) { - theme_owner = parent_w->theme_owner; - theme_owner_window = parent_w->theme_owner_window; - } else { - theme_owner = nullptr; - theme_owner_window = nullptr; - } - } - } - - // Secondly, check the project-defined Theme resource. - if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { - if (ThemeDB::get_singleton()->get_project_theme()->has_default_font()) { - return ThemeDB::get_singleton()->get_project_theme()->get_default_font(); - } - } - - // Lastly, fall back on the default Theme. - if (ThemeDB::get_singleton()->get_default_theme()->has_default_font()) { - return ThemeDB::get_singleton()->get_default_theme()->get_default_font(); - } - return ThemeDB::get_singleton()->get_fallback_font(); + return data.theme_owner->get_theme_default_base_scale(); } Ref<Font> Control::get_theme_default_font() const { - return fetch_theme_default_font(data.theme_owner, data.theme_owner_window); -} - -int Control::fetch_theme_default_font_size(Control *p_theme_owner, Window *p_theme_owner_window) { - // First, look through each control or window node in the branch, until no valid parent can be found. - // Only nodes with a theme resource attached are considered. - // For each theme resource see if their assigned theme has the default value defined and valid. - Control *theme_owner = p_theme_owner; - Window *theme_owner_window = p_theme_owner_window; - - while (theme_owner || theme_owner_window) { - if (theme_owner && theme_owner->data.theme->has_default_font_size()) { - return theme_owner->data.theme->get_default_font_size(); - } - - if (theme_owner_window && theme_owner_window->theme->has_default_font_size()) { - return theme_owner_window->theme->get_default_font_size(); - } - - Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); - Control *parent_c = Object::cast_to<Control>(parent); - if (parent_c) { - theme_owner = parent_c->data.theme_owner; - theme_owner_window = parent_c->data.theme_owner_window; - } else { - Window *parent_w = Object::cast_to<Window>(parent); - if (parent_w) { - theme_owner = parent_w->theme_owner; - theme_owner_window = parent_w->theme_owner_window; - } else { - theme_owner = nullptr; - theme_owner_window = nullptr; - } - } - } - - // Secondly, check the project-defined Theme resource. - if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { - if (ThemeDB::get_singleton()->get_project_theme()->has_default_font_size()) { - return ThemeDB::get_singleton()->get_project_theme()->get_default_font_size(); - } - } - - // Lastly, fall back on the default Theme. - if (ThemeDB::get_singleton()->get_default_theme()->has_default_font_size()) { - return ThemeDB::get_singleton()->get_default_theme()->get_default_font_size(); - } - return ThemeDB::get_singleton()->get_fallback_font_size(); + return data.theme_owner->get_theme_default_font(); } int Control::get_theme_default_font_size() const { - return fetch_theme_default_font_size(data.theme_owner, data.theme_owner_window); + return data.theme_owner->get_theme_default_font_size(); } /// Bulk actions. @@ -3086,27 +2789,23 @@ Control *Control::make_custom_tooltip(const String &p_text) const { // Base object overrides. -void Control::add_child_notify(Node *p_child) { - // We propagate when this node uses a custom theme, so it can pass it on to its children. - if (data.theme_owner || data.theme_owner_window) { - // `p_notify` is false here as `NOTIFICATION_THEME_CHANGED` will be handled by `NOTIFICATION_ENTER_TREE`. - _propagate_theme_changed(p_child, data.theme_owner, data.theme_owner_window, false, true); - } -} - -void Control::remove_child_notify(Node *p_child) { - // If the removed child isn't inheriting any theme items through this node, then there's no need to propagate. - if (data.theme_owner || data.theme_owner_window) { - _propagate_theme_changed(p_child, nullptr, nullptr, false, true); - } -} - void Control::_notification(int p_notification) { switch (p_notification) { + case NOTIFICATION_POSTINITIALIZE: { + _invalidate_theme_cache(); + _update_theme_item_cache(); + } break; + + case NOTIFICATION_PARENTED: { + data.theme_owner->assign_theme_on_parented(this); + } break; + + case NOTIFICATION_UNPARENTED: { + data.theme_owner->clear_theme_on_unparented(this); + } break; + case NOTIFICATION_ENTER_TREE: { - // Need to defer here, because theme owner information might be set in - // add_child_notify, which doesn't get called until right after this. - call_deferred(SNAME("notification"), NOTIFICATION_THEME_CHANGED); + notification(NOTIFICATION_THEME_CHANGED); } break; case NOTIFICATION_POST_ENTER_TREE: { @@ -3236,6 +2935,7 @@ void Control::_notification(int p_notification) { case NOTIFICATION_THEME_CHANGED: { emit_signal(SceneStringNames::get_singleton()->theme_changed); _invalidate_theme_cache(); + _update_theme_item_cache(); update_minimum_size(); queue_redraw(); } break; @@ -3257,6 +2957,7 @@ void Control::_notification(int p_notification) { if (is_inside_tree()) { data.is_rtl_dirty = true; _invalidate_theme_cache(); + _update_theme_item_cache(); _size_changed(); } } break; @@ -3445,10 +3146,10 @@ void Control::_bind_methods() { ADD_PROPERTY_DEFAULT("anchors_preset", -1); ADD_SUBGROUP_INDENT("Anchor Points", "anchor_", 1); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anchor_left", PROPERTY_HINT_RANGE, "0,1,0.001,or_lesser,or_greater"), "_set_anchor", "get_anchor", SIDE_LEFT); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anchor_top", PROPERTY_HINT_RANGE, "0,1,0.001,or_lesser,or_greater"), "_set_anchor", "get_anchor", SIDE_TOP); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anchor_right", PROPERTY_HINT_RANGE, "0,1,0.001,or_lesser,or_greater"), "_set_anchor", "get_anchor", SIDE_RIGHT); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anchor_bottom", PROPERTY_HINT_RANGE, "0,1,0.001,or_lesser,or_greater"), "_set_anchor", "get_anchor", SIDE_BOTTOM); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anchor_left", PROPERTY_HINT_RANGE, "0,1,0.001,or_less,or_greater"), "_set_anchor", "get_anchor", SIDE_LEFT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anchor_top", PROPERTY_HINT_RANGE, "0,1,0.001,or_less,or_greater"), "_set_anchor", "get_anchor", SIDE_TOP); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anchor_right", PROPERTY_HINT_RANGE, "0,1,0.001,or_less,or_greater"), "_set_anchor", "get_anchor", SIDE_RIGHT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anchor_bottom", PROPERTY_HINT_RANGE, "0,1,0.001,or_less,or_greater"), "_set_anchor", "get_anchor", SIDE_BOTTOM); ADD_SUBGROUP_INDENT("Anchor Offsets", "offset_", 1); ADD_PROPERTYI(PropertyInfo(Variant::INT, "offset_left", PROPERTY_HINT_RANGE, "-4096,4096,suffix:px"), "set_offset", "get_offset", SIDE_LEFT); @@ -3464,7 +3165,7 @@ void Control::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size", PROPERTY_HINT_NONE, "suffix:px", PROPERTY_USAGE_EDITOR), "_set_size", "get_size"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position", PROPERTY_HINT_NONE, "suffix:px", PROPERTY_USAGE_EDITOR), "_set_position", "get_position"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "global_position", PROPERTY_HINT_NONE, "suffix:px", PROPERTY_USAGE_NONE), "_set_global_position", "get_global_position"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians"), "set_rotation", "get_rotation"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_less,or_greater,radians"), "set_rotation", "get_rotation"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scale"), "set_scale", "get_scale"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "pivot_offset", PROPERTY_HINT_NONE, "suffix:px"), "set_pivot_offset", "get_pivot_offset"); @@ -3601,7 +3302,13 @@ void Control::_bind_methods() { GDVIRTUAL_BIND(_gui_input, "event"); } +Control::Control() { + data.theme_owner = memnew(ThemeOwner); +} + Control::~Control() { + memdelete(data.theme_owner); + // Resources need to be disconnected. for (KeyValue<StringName, Ref<Texture2D>> &E : data.icon_override) { E.value->disconnect("changed", callable_mp(this, &Control::_notify_theme_override_changed)); diff --git a/scene/gui/control.h b/scene/gui/control.h index 6215594ae0..3fb1494d66 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -41,6 +41,7 @@ class Viewport; class Label; class Panel; +class ThemeOwner; class Control : public CanvasItem { GDCLASS(Control, CanvasItem); @@ -219,9 +220,8 @@ private: // Theming. + ThemeOwner *theme_owner = nullptr; Ref<Theme> theme; - Control *theme_owner = nullptr; - Window *theme_owner_window = nullptr; StringName theme_type_variation; bool bulk_theme_override = false; @@ -261,7 +261,6 @@ private: // Global relations. friend class Viewport; - friend class Window; // Positioning and sizing. @@ -303,13 +302,6 @@ private: void _notify_theme_override_changed(); void _invalidate_theme_cache(); - static void _propagate_theme_changed(Node *p_at, Control *p_owner, Window *p_owner_window, bool p_notify, bool p_assign); - - template <class T> - static T get_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner_window, Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types); - static bool has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner_window, Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types); - _FORCE_INLINE_ void _get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const; - // Extra properties. String get_tooltip_text() const; @@ -325,15 +317,16 @@ protected: bool _property_can_revert(const StringName &p_name) const; bool _property_get_revert(const StringName &p_name, Variant &r_property) const; + // Theming. + + virtual void _update_theme_item_cache(); + // Internationalization. virtual TypedArray<Vector2i> structured_text_parser(TextServer::StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const; // Base object overrides. - virtual void add_child_notify(Node *p_child) override; - virtual void remove_child_notify(Node *p_child) override; - void _notification(int p_notification); static void _bind_methods(); @@ -538,6 +531,10 @@ public: // Theming. + void set_theme_owner_node(Node *p_node); + Node *get_theme_owner_node() const; + bool has_theme_owner_node() const; + void set_theme(const Ref<Theme> &p_theme); Ref<Theme> get_theme() const; @@ -582,10 +579,6 @@ public: bool has_theme_color(const StringName &p_name, const StringName &p_theme_type = StringName()) const; bool has_theme_constant(const StringName &p_name, const StringName &p_theme_type = StringName()) const; - static float fetch_theme_default_base_scale(Control *p_theme_owner, Window *p_theme_owner_window); - static Ref<Font> fetch_theme_default_font(Control *p_theme_owner, Window *p_theme_owner_window); - static int fetch_theme_default_font_size(Control *p_theme_owner, Window *p_theme_owner_window); - float get_theme_default_base_scale() const; Ref<Font> get_theme_default_font() const; int get_theme_default_font_size() const; @@ -608,7 +601,7 @@ public: virtual String get_tooltip(const Point2 &p_pos) const; virtual Control *make_custom_tooltip(const String &p_text) const; - Control() {} + Control(); ~Control(); }; diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp index b4e0747ab8..0a1aeeda71 100644 --- a/scene/gui/dialogs.cpp +++ b/scene/gui/dialogs.cpp @@ -50,6 +50,14 @@ void AcceptDialog::_parent_focused() { } } +void AcceptDialog::_update_theme_item_cache() { + Window::_update_theme_item_cache(); + + theme_cache.panel_style = get_theme_stylebox(SNAME("panel")); + theme_cache.margin = get_theme_constant(SNAME("margin")); + theme_cache.button_margin = get_theme_constant(SNAME("button_margin")); +} + void AcceptDialog::_notification(int p_what) { switch (p_what) { case NOTIFICATION_VISIBILITY_CHANGED: { @@ -69,7 +77,10 @@ void AcceptDialog::_notification(int p_what) { } break; case NOTIFICATION_THEME_CHANGED: { - bg->add_theme_style_override("panel", bg->get_theme_stylebox(SNAME("panel"), SNAME("AcceptDialog"))); + bg->add_theme_style_override("panel", theme_cache.panel_style); + + label->set_begin(Point2(theme_cache.margin, theme_cache.margin)); + label->set_end(Point2(-theme_cache.margin, -theme_cache.button_margin - 10)); } break; case NOTIFICATION_EXIT_TREE: { @@ -185,12 +196,12 @@ void AcceptDialog::_update_child_rects() { if (label->get_text().is_empty()) { label_size.height = 0; } - int margin = hbc->get_theme_constant(SNAME("margin"), SNAME("Dialogs")); + Size2 size = get_size(); Size2 hminsize = hbc->get_combined_minimum_size(); - Vector2 cpos(margin, margin + label_size.height); - Vector2 csize(size.x - margin * 2, size.y - margin * 3 - hminsize.y - label_size.height); + Vector2 cpos(theme_cache.margin, theme_cache.margin + label_size.height); + Vector2 csize(size.x - theme_cache.margin * 2, size.y - theme_cache.margin * 3 - hminsize.y - label_size.height); for (int i = 0; i < get_child_count(); i++) { Control *c = Object::cast_to<Control>(get_child(i)); @@ -206,7 +217,7 @@ void AcceptDialog::_update_child_rects() { c->set_size(csize); } - cpos.y += csize.y + margin; + cpos.y += csize.y + theme_cache.margin; csize.y = hminsize.y; hbc->set_position(cpos); @@ -217,7 +228,6 @@ void AcceptDialog::_update_child_rects() { } Size2 AcceptDialog::_get_contents_minimum_size() const { - int margin = hbc->get_theme_constant(SNAME("margin"), SNAME("Dialogs")); Size2 minsize = label->get_combined_minimum_size(); for (int i = 0; i < get_child_count(); i++) { @@ -238,8 +248,8 @@ Size2 AcceptDialog::_get_contents_minimum_size() const { Size2 hminsize = hbc->get_combined_minimum_size(); minsize.x = MAX(hminsize.x, minsize.x); minsize.y += hminsize.y; - minsize.x += margin * 2; - minsize.y += margin * 3; //one as separation between hbc and child + minsize.x += theme_cache.margin * 2; + minsize.y += theme_cache.margin * 3; //one as separation between hbc and child Size2 wmsize = get_min_size(); minsize.x = MAX(wmsize.x, minsize.x); @@ -350,14 +360,9 @@ AcceptDialog::AcceptDialog() { hbc = memnew(HBoxContainer); - int margin = hbc->get_theme_constant(SNAME("margin"), SNAME("Dialogs")); - int button_margin = hbc->get_theme_constant(SNAME("button_margin"), SNAME("Dialogs")); - label = memnew(Label); label->set_anchor(SIDE_RIGHT, Control::ANCHOR_END); label->set_anchor(SIDE_BOTTOM, Control::ANCHOR_END); - label->set_begin(Point2(margin, margin)); - label->set_end(Point2(-margin, -button_margin - 10)); add_child(label, false, INTERNAL_MODE_FRONT); add_child(hbc, false, INTERNAL_MODE_FRONT); diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h index 9ebf5ddfb2..8ba9c93861 100644 --- a/scene/gui/dialogs.h +++ b/scene/gui/dialogs.h @@ -52,6 +52,12 @@ class AcceptDialog : public Window { bool hide_on_ok = true; bool close_on_escape = true; + struct ThemeCache { + Ref<StyleBox> panel_style; + int margin = 0; + int button_margin = 0; + } theme_cache; + void _custom_action(const String &p_action); void _update_child_rects(); @@ -62,6 +68,7 @@ class AcceptDialog : public Window { protected: virtual Size2 _get_contents_minimum_size() const override; + virtual void _update_theme_item_cache() override; void _notification(int p_what); static void _bind_methods(); diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 2a56d6d222..a0cf5f5970 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -59,36 +59,26 @@ VBoxContainer *FileDialog::get_vbox() { return vbox; } -void FileDialog::_theme_changed() { - Color font_color = vbox->get_theme_color(SNAME("font_color"), SNAME("Button")); - Color font_hover_color = vbox->get_theme_color(SNAME("font_hover_color"), SNAME("Button")); - Color font_focus_color = vbox->get_theme_color(SNAME("font_focus_color"), SNAME("Button")); - Color font_pressed_color = vbox->get_theme_color(SNAME("font_pressed_color"), SNAME("Button")); - - dir_up->add_theme_color_override("icon_normal_color", font_color); - dir_up->add_theme_color_override("icon_hover_color", font_hover_color); - dir_up->add_theme_color_override("icon_focus_color", font_focus_color); - dir_up->add_theme_color_override("icon_pressed_color", font_pressed_color); - - dir_prev->add_theme_color_override("icon_color_normal", font_color); - dir_prev->add_theme_color_override("icon_color_hover", font_hover_color); - dir_prev->add_theme_color_override("icon_focus_color", font_focus_color); - dir_prev->add_theme_color_override("icon_color_pressed", font_pressed_color); - - dir_next->add_theme_color_override("icon_color_normal", font_color); - dir_next->add_theme_color_override("icon_color_hover", font_hover_color); - dir_next->add_theme_color_override("icon_focus_color", font_focus_color); - dir_next->add_theme_color_override("icon_color_pressed", font_pressed_color); - - refresh->add_theme_color_override("icon_normal_color", font_color); - refresh->add_theme_color_override("icon_hover_color", font_hover_color); - refresh->add_theme_color_override("icon_focus_color", font_focus_color); - refresh->add_theme_color_override("icon_pressed_color", font_pressed_color); - - show_hidden->add_theme_color_override("icon_normal_color", font_color); - show_hidden->add_theme_color_override("icon_hover_color", font_hover_color); - show_hidden->add_theme_color_override("icon_focus_color", font_focus_color); - show_hidden->add_theme_color_override("icon_pressed_color", font_pressed_color); +void FileDialog::_update_theme_item_cache() { + ConfirmationDialog::_update_theme_item_cache(); + + theme_cache.parent_folder = get_theme_icon(SNAME("parent_folder")); + theme_cache.forward_folder = get_theme_icon(SNAME("forward_folder")); + theme_cache.back_folder = get_theme_icon(SNAME("back_folder")); + theme_cache.reload = get_theme_icon(SNAME("reload")); + theme_cache.toggle_hidden = get_theme_icon(SNAME("toggle_hidden")); + theme_cache.folder = get_theme_icon(SNAME("folder")); + theme_cache.file = get_theme_icon(SNAME("file")); + + theme_cache.folder_icon_modulate = get_theme_color(SNAME("folder_icon_modulate")); + theme_cache.file_icon_modulate = get_theme_color(SNAME("file_icon_modulate")); + theme_cache.files_disabled = get_theme_color(SNAME("files_disabled")); + + // TODO: Define own colors? + theme_cache.icon_normal_color = get_theme_color(SNAME("font_color"), SNAME("Button")); + theme_cache.icon_hover_color = get_theme_color(SNAME("font_hover_color"), SNAME("Button")); + theme_cache.icon_focus_color = get_theme_color(SNAME("font_focus_color"), SNAME("Button")); + theme_cache.icon_pressed_color = get_theme_color(SNAME("font_pressed_color"), SNAME("Button")); } void FileDialog::_notification(int p_what) { @@ -99,18 +89,42 @@ void FileDialog::_notification(int p_what) { } } break; - case NOTIFICATION_ENTER_TREE: { - dir_up->set_icon(vbox->get_theme_icon(SNAME("parent_folder"), SNAME("FileDialog"))); + case NOTIFICATION_THEME_CHANGED: { + dir_up->set_icon(theme_cache.parent_folder); if (vbox->is_layout_rtl()) { - dir_prev->set_icon(vbox->get_theme_icon(SNAME("forward_folder"), SNAME("FileDialog"))); - dir_next->set_icon(vbox->get_theme_icon(SNAME("back_folder"), SNAME("FileDialog"))); + dir_prev->set_icon(theme_cache.forward_folder); + dir_next->set_icon(theme_cache.back_folder); } else { - dir_prev->set_icon(vbox->get_theme_icon(SNAME("back_folder"), SNAME("FileDialog"))); - dir_next->set_icon(vbox->get_theme_icon(SNAME("forward_folder"), SNAME("FileDialog"))); + dir_prev->set_icon(theme_cache.back_folder); + dir_next->set_icon(theme_cache.forward_folder); } - refresh->set_icon(vbox->get_theme_icon(SNAME("reload"), SNAME("FileDialog"))); - show_hidden->set_icon(vbox->get_theme_icon(SNAME("toggle_hidden"), SNAME("FileDialog"))); - _theme_changed(); + refresh->set_icon(theme_cache.reload); + show_hidden->set_icon(theme_cache.toggle_hidden); + + dir_up->add_theme_color_override("icon_normal_color", theme_cache.icon_normal_color); + dir_up->add_theme_color_override("icon_hover_color", theme_cache.icon_hover_color); + dir_up->add_theme_color_override("icon_focus_color", theme_cache.icon_focus_color); + dir_up->add_theme_color_override("icon_pressed_color", theme_cache.icon_pressed_color); + + dir_prev->add_theme_color_override("icon_color_normal", theme_cache.icon_normal_color); + dir_prev->add_theme_color_override("icon_color_hover", theme_cache.icon_hover_color); + dir_prev->add_theme_color_override("icon_focus_color", theme_cache.icon_focus_color); + dir_prev->add_theme_color_override("icon_color_pressed", theme_cache.icon_pressed_color); + + dir_next->add_theme_color_override("icon_color_normal", theme_cache.icon_normal_color); + dir_next->add_theme_color_override("icon_color_hover", theme_cache.icon_hover_color); + dir_next->add_theme_color_override("icon_focus_color", theme_cache.icon_focus_color); + dir_next->add_theme_color_override("icon_color_pressed", theme_cache.icon_pressed_color); + + refresh->add_theme_color_override("icon_normal_color", theme_cache.icon_normal_color); + refresh->add_theme_color_override("icon_hover_color", theme_cache.icon_hover_color); + refresh->add_theme_color_override("icon_focus_color", theme_cache.icon_focus_color); + refresh->add_theme_color_override("icon_pressed_color", theme_cache.icon_pressed_color); + + show_hidden->add_theme_color_override("icon_normal_color", theme_cache.icon_normal_color); + show_hidden->add_theme_color_override("icon_hover_color", theme_cache.icon_hover_color); + show_hidden->add_theme_color_override("icon_focus_color", theme_cache.icon_focus_color); + show_hidden->add_theme_color_override("icon_pressed_color", theme_cache.icon_pressed_color); } break; case NOTIFICATION_TRANSLATION_CHANGED: { @@ -506,10 +520,6 @@ void FileDialog::update_file_list() { } TreeItem *root = tree->create_item(); - Ref<Texture2D> folder = vbox->get_theme_icon(SNAME("folder"), SNAME("FileDialog")); - Ref<Texture2D> file_icon = vbox->get_theme_icon(SNAME("file"), SNAME("FileDialog")); - const Color folder_color = vbox->get_theme_color(SNAME("folder_icon_modulate"), SNAME("FileDialog")); - const Color file_color = vbox->get_theme_color(SNAME("file_icon_modulate"), SNAME("FileDialog")); List<String> files; List<String> dirs; @@ -541,8 +551,8 @@ void FileDialog::update_file_list() { String &dir_name = dirs.front()->get(); TreeItem *ti = tree->create_item(root); ti->set_text(0, dir_name); - ti->set_icon(0, folder); - ti->set_icon_modulate(0, folder_color); + ti->set_icon(0, theme_cache.folder); + ti->set_icon_modulate(0, theme_cache.folder_icon_modulate); Dictionary d; d["name"] = dir_name; @@ -601,12 +611,12 @@ void FileDialog::update_file_list() { Ref<Texture2D> icon = get_icon_func(base_dir.path_join(files.front()->get())); ti->set_icon(0, icon); } else { - ti->set_icon(0, file_icon); + ti->set_icon(0, theme_cache.file); } - ti->set_icon_modulate(0, file_color); + ti->set_icon_modulate(0, theme_cache.file_icon_modulate); if (mode == FILE_MODE_OPEN_DIR) { - ti->set_custom_color(0, vbox->get_theme_color(SNAME("files_disabled"), SNAME("FileDialog"))); + ti->set_custom_color(0, theme_cache.files_disabled); ti->set_selectable(0, false); } Dictionary d; @@ -1006,7 +1016,6 @@ FileDialog::FileDialog() { vbox = memnew(VBoxContainer); add_child(vbox, false, INTERNAL_MODE_FRONT); - vbox->connect("theme_changed", callable_mp(this, &FileDialog::_theme_changed)); mode = FILE_MODE_SAVE_FILE; set_title(TTRC("Save a File")); diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h index 4945094086..5c892288b5 100644 --- a/scene/gui/file_dialog.h +++ b/scene/gui/file_dialog.h @@ -109,6 +109,25 @@ private: bool invalidated = true; + struct ThemeCache { + Ref<Texture2D> parent_folder; + Ref<Texture2D> forward_folder; + Ref<Texture2D> back_folder; + Ref<Texture2D> reload; + Ref<Texture2D> toggle_hidden; + Ref<Texture2D> folder; + Ref<Texture2D> file; + + Color folder_icon_modulate; + Color file_icon_modulate; + Color files_disabled; + + Color icon_normal_color; + Color icon_hover_color; + Color icon_focus_color; + Color icon_pressed_color; + } theme_cache; + void update_dir(); void update_file_name(); void update_file_list(); @@ -143,7 +162,7 @@ private: virtual void _post_popup() override; protected: - void _theme_changed(); + virtual void _update_theme_item_cache() override; void _notification(int p_what); static void _bind_methods(); diff --git a/scene/gui/flow_container.cpp b/scene/gui/flow_container.cpp index 30b694da76..b0d15aa7f4 100644 --- a/scene/gui/flow_container.cpp +++ b/scene/gui/flow_container.cpp @@ -44,9 +44,6 @@ void FlowContainer::_resort() { return; } - int separation_horizontal = get_theme_constant(SNAME("h_separation")); - int separation_vertical = get_theme_constant(SNAME("v_separation")); - bool rtl = is_layout_rtl(); HashMap<Control *, Size2i> children_minsize_cache; @@ -74,14 +71,14 @@ void FlowContainer::_resort() { if (vertical) { /* VERTICAL */ if (children_in_current_line > 0) { - ofs.y += separation_vertical; + ofs.y += theme_cache.v_separation; } if (ofs.y + child_msc.y > current_container_size) { - line_length = ofs.y - separation_vertical; + line_length = ofs.y - theme_cache.v_separation; lines_data.push_back(_LineData{ children_in_current_line, line_height, line_length, current_container_size - line_length, line_stretch_ratio_total }); // Move in new column (vertical line). - ofs.x += line_height + separation_horizontal; + ofs.x += line_height + theme_cache.h_separation; ofs.y = 0; line_height = 0; line_stretch_ratio_total = 0; @@ -96,14 +93,14 @@ void FlowContainer::_resort() { } else { /* HORIZONTAL */ if (children_in_current_line > 0) { - ofs.x += separation_horizontal; + ofs.x += theme_cache.h_separation; } if (ofs.x + child_msc.x > current_container_size) { - line_length = ofs.x - separation_horizontal; + line_length = ofs.x - theme_cache.h_separation; lines_data.push_back(_LineData{ children_in_current_line, line_height, line_length, current_container_size - line_length, line_stretch_ratio_total }); // Move in new line. - ofs.y += line_height + separation_vertical; + ofs.y += line_height + theme_cache.v_separation; ofs.x = 0; line_height = 0; line_stretch_ratio_total = 0; @@ -146,11 +143,11 @@ void FlowContainer::_resort() { current_line_idx++; child_idx_in_line = 0; if (vertical) { - ofs.x += line_data.min_line_height + separation_horizontal; + ofs.x += line_data.min_line_height + theme_cache.h_separation; ofs.y = 0; } else { ofs.x = 0; - ofs.y += line_data.min_line_height + separation_vertical; + ofs.y += line_data.min_line_height + theme_cache.v_separation; } line_data = lines_data[current_line_idx]; } @@ -184,9 +181,9 @@ void FlowContainer::_resort() { fit_child_in_rect(child, child_rect); if (vertical) { /* VERTICAL */ - ofs.y += child_size.height + separation_vertical; + ofs.y += child_size.height + theme_cache.v_separation; } else { /* HORIZONTAL */ - ofs.x += child_size.width + separation_horizontal; + ofs.x += child_size.width + theme_cache.h_separation; } child_idx_in_line++; @@ -250,6 +247,13 @@ Vector<int> FlowContainer::get_allowed_size_flags_vertical() const { return flags; } +void FlowContainer::_update_theme_item_cache() { + Container::_update_theme_item_cache(); + + theme_cache.h_separation = get_theme_constant(SNAME("h_separation")); + theme_cache.v_separation = get_theme_constant(SNAME("v_separation")); +} + void FlowContainer::_notification(int p_what) { switch (p_what) { case NOTIFICATION_SORT_CHILDREN: { @@ -268,14 +272,36 @@ void FlowContainer::_notification(int p_what) { } } +void FlowContainer::_validate_property(PropertyInfo &p_property) const { + if (is_fixed && p_property.name == "vertical") { + p_property.usage = PROPERTY_USAGE_NONE; + } +} + int FlowContainer::get_line_count() const { return cached_line_count; } +void FlowContainer::set_vertical(bool p_vertical) { + ERR_FAIL_COND_MSG(is_fixed, "Can't change orientation of " + get_class() + "."); + vertical = p_vertical; + update_minimum_size(); + _resort(); +} + +bool FlowContainer::is_vertical() const { + return vertical; +} + FlowContainer::FlowContainer(bool p_vertical) { vertical = p_vertical; } void FlowContainer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_line_count"), &FlowContainer::get_line_count); + + ClassDB::bind_method(D_METHOD("set_vertical", "vertical"), &FlowContainer::set_vertical); + ClassDB::bind_method(D_METHOD("is_vertical"), &FlowContainer::is_vertical); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "vertical"), "set_vertical", "is_vertical"); } diff --git a/scene/gui/flow_container.h b/scene/gui/flow_container.h index a2da43e071..536df27ad6 100644 --- a/scene/gui/flow_container.h +++ b/scene/gui/flow_container.h @@ -42,16 +42,28 @@ private: bool vertical = false; + struct ThemeCache { + int h_separation = 0; + int v_separation = 0; + } theme_cache; + void _resort(); protected: - void _notification(int p_what); + bool is_fixed = false; + + virtual void _update_theme_item_cache() override; + void _notification(int p_what); + void _validate_property(PropertyInfo &p_property) const; static void _bind_methods(); public: int get_line_count() const; + void set_vertical(bool p_vertical); + bool is_vertical() const; + virtual Size2 get_minimum_size() const override; virtual Vector<int> get_allowed_size_flags_horizontal() const override; @@ -65,7 +77,7 @@ class HFlowContainer : public FlowContainer { public: HFlowContainer() : - FlowContainer(false) {} + FlowContainer(false) { is_fixed = true; } }; class VFlowContainer : public FlowContainer { @@ -73,7 +85,7 @@ class VFlowContainer : public FlowContainer { public: VFlowContainer() : - FlowContainer(true) {} + FlowContainer(true) { is_fixed = true; } }; #endif // FLOW_CONTAINER_H diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp index 3163d17846..8dc890eccb 100644 --- a/scene/gui/grid_container.cpp +++ b/scene/gui/grid_container.cpp @@ -31,6 +31,13 @@ #include "grid_container.h" #include "core/templates/rb_set.h" +void GridContainer::_update_theme_item_cache() { + Container::_update_theme_item_cache(); + + theme_cache.h_separation = get_theme_constant(SNAME("h_separation")); + theme_cache.v_separation = get_theme_constant(SNAME("v_separation")); +} + void GridContainer::_notification(int p_what) { switch (p_what) { case NOTIFICATION_SORT_CHILDREN: { @@ -39,9 +46,6 @@ void GridContainer::_notification(int p_what) { RBSet<int> col_expanded; // Columns which have the SIZE_EXPAND flag set. RBSet<int> row_expanded; // Rows which have the SIZE_EXPAND flag set. - int hsep = get_theme_constant(SNAME("h_separation")); - int vsep = get_theme_constant(SNAME("v_separation")); - // Compute the per-column/per-row data. int valid_controls_index = 0; for (int i = 0; i < get_child_count(); i++) { @@ -98,8 +102,8 @@ void GridContainer::_notification(int p_what) { remaining_space.height -= E.value; } } - remaining_space.height -= vsep * MAX(max_row - 1, 0); - remaining_space.width -= hsep * MAX(max_col - 1, 0); + remaining_space.height -= theme_cache.v_separation * MAX(max_row - 1, 0); + remaining_space.width -= theme_cache.h_separation * MAX(max_col - 1, 0); bool can_fit = false; while (!can_fit && col_expanded.size() > 0) { @@ -202,7 +206,7 @@ void GridContainer::_notification(int p_what) { col_ofs = 0; } if (row > 0) { - row_ofs += (row_expanded.has(row - 1) ? row_expand : row_minh[row - 1]) + vsep; + row_ofs += (row_expanded.has(row - 1) ? row_expand : row_minh[row - 1]) + theme_cache.v_separation; if (row_expanded.has(row - 1) && row - 1 < row_remaining_pixel_index) { // Apply the remaining pixel of the previous row. @@ -224,11 +228,11 @@ void GridContainer::_notification(int p_what) { if (rtl) { Point2 p(col_ofs - s.width, row_ofs); fit_child_in_rect(c, Rect2(p, s)); - col_ofs -= s.width + hsep; + col_ofs -= s.width + theme_cache.h_separation; } else { Point2 p(col_ofs, row_ofs); fit_child_in_rect(c, Rect2(p, s)); - col_ofs += s.width + hsep; + col_ofs += s.width + theme_cache.h_separation; } } } break; @@ -271,9 +275,6 @@ Size2 GridContainer::get_minimum_size() const { RBMap<int, int> col_minw; RBMap<int, int> row_minh; - int hsep = get_theme_constant(SNAME("h_separation")); - int vsep = get_theme_constant(SNAME("v_separation")); - int max_row = 0; int max_col = 0; @@ -313,8 +314,8 @@ Size2 GridContainer::get_minimum_size() const { ms.height += E.value; } - ms.height += vsep * max_row; - ms.width += hsep * max_col; + ms.height += theme_cache.v_separation * max_row; + ms.width += theme_cache.h_separation * max_col; return ms; } diff --git a/scene/gui/grid_container.h b/scene/gui/grid_container.h index 9d77f90ab3..522046f694 100644 --- a/scene/gui/grid_container.h +++ b/scene/gui/grid_container.h @@ -38,7 +38,14 @@ class GridContainer : public Container { int columns = 1; + struct ThemeCache { + int h_separation = 0; + int v_separation = 0; + } theme_cache; + protected: + virtual void _update_theme_item_cache() override; + void _notification(int p_what); static void _bind_methods(); diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index 308dbe33f2..8c49353105 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -43,7 +43,7 @@ void ItemList::_shape(int p_idx) { } else { item.text_buf->set_direction((TextServer::Direction)item.text_direction); } - item.text_buf->add_string(item.text, get_theme_font(SNAME("font")), get_theme_font_size(SNAME("font_size")), item.language); + item.text_buf->add_string(item.text, theme_cache.font, theme_cache.font_size, item.language); if (icon_mode == ICON_MODE_TOP && max_text_lines > 0) { item.text_buf->set_break_flags(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::BREAK_GRAPHEME_BOUND | TextServer::BREAK_TRIM_EDGE_SPACES); } else { @@ -655,8 +655,7 @@ void ItemList::gui_input(const Ref<InputEvent> &p_event) { if (mb.is_valid() && mb->is_pressed()) { search_string = ""; //any mousepress cancels Vector2 pos = mb->get_position(); - Ref<StyleBox> bg = get_theme_stylebox(SNAME("bg")); - pos -= bg->get_offset(); + pos -= theme_cache.bg_style->get_offset(); pos.y += scroll_bar->get_value(); if (is_layout_rtl()) { @@ -980,6 +979,31 @@ static Rect2 _adjust_to_max_size(Size2 p_size, Size2 p_max_size) { return Rect2(ofs_x, ofs_y, tex_width, tex_height); } +void ItemList::_update_theme_item_cache() { + Control::_update_theme_item_cache(); + + theme_cache.h_separation = get_theme_constant(SNAME("h_separation")); + theme_cache.v_separation = get_theme_constant(SNAME("v_separation")); + + theme_cache.bg_style = get_theme_stylebox(SNAME("bg")); + theme_cache.bg_focus_style = get_theme_stylebox(SNAME("bg_focus")); + + theme_cache.font = get_theme_font(SNAME("font")); + theme_cache.font_size = get_theme_font_size(SNAME("font_size")); + theme_cache.font_color = get_theme_color(SNAME("font_color")); + theme_cache.font_selected_color = get_theme_color(SNAME("font_selected_color")); + theme_cache.font_outline_size = get_theme_constant(SNAME("outline_size")); + theme_cache.font_outline_color = get_theme_color(SNAME("font_outline_color")); + + theme_cache.line_separation = get_theme_constant(SNAME("line_separation")); + theme_cache.icon_margin = get_theme_constant(SNAME("icon_margin")); + theme_cache.selected_style = get_theme_stylebox(SNAME("selected")); + theme_cache.selected_focus_style = get_theme_stylebox(SNAME("selected_focus")); + theme_cache.cursor_style = get_theme_stylebox(SNAME("cursor_unfocused")); + theme_cache.cursor_focus_style = get_theme_stylebox(SNAME("cursor")); + theme_cache.guide_color = get_theme_color(SNAME("guide_color")); +} + void ItemList::_notification(int p_what) { switch (p_what) { case NOTIFICATION_RESIZED: { @@ -998,37 +1022,32 @@ void ItemList::_notification(int p_what) { } break; case NOTIFICATION_DRAW: { - Ref<StyleBox> bg = get_theme_stylebox(SNAME("bg")); - int mw = scroll_bar->get_minimum_size().x; scroll_bar->set_anchor_and_offset(SIDE_LEFT, ANCHOR_END, -mw); scroll_bar->set_anchor_and_offset(SIDE_RIGHT, ANCHOR_END, 0); - scroll_bar->set_anchor_and_offset(SIDE_TOP, ANCHOR_BEGIN, bg->get_margin(SIDE_TOP)); - scroll_bar->set_anchor_and_offset(SIDE_BOTTOM, ANCHOR_END, -bg->get_margin(SIDE_BOTTOM)); + scroll_bar->set_anchor_and_offset(SIDE_TOP, ANCHOR_BEGIN, theme_cache.bg_style->get_margin(SIDE_TOP)); + scroll_bar->set_anchor_and_offset(SIDE_BOTTOM, ANCHOR_END, -theme_cache.bg_style->get_margin(SIDE_BOTTOM)); Size2 size = get_size(); - int width = size.width - bg->get_minimum_size().width; + int width = size.width - theme_cache.bg_style->get_minimum_size().width; - draw_style_box(bg, Rect2(Point2(), size)); + draw_style_box(theme_cache.bg_style, Rect2(Point2(), size)); - int hseparation = get_theme_constant(SNAME("h_separation")); - int vseparation = get_theme_constant(SNAME("v_separation")); - int icon_margin = get_theme_constant(SNAME("icon_margin")); - int line_separation = get_theme_constant(SNAME("line_separation")); - Color font_outline_color = get_theme_color(SNAME("font_outline_color")); - int outline_size = get_theme_constant(SNAME("outline_size")); + Ref<StyleBox> sbsel; + Ref<StyleBox> cursor; - Ref<StyleBox> sbsel = has_focus() ? get_theme_stylebox(SNAME("selected_focus")) : get_theme_stylebox(SNAME("selected")); - Ref<StyleBox> cursor = has_focus() ? get_theme_stylebox(SNAME("cursor")) : get_theme_stylebox(SNAME("cursor_unfocused")); + if (has_focus()) { + sbsel = theme_cache.selected_focus_style; + cursor = theme_cache.cursor_focus_style; + } else { + sbsel = theme_cache.selected_style; + cursor = theme_cache.cursor_style; + } bool rtl = is_layout_rtl(); - Color guide_color = get_theme_color(SNAME("guide_color")); - Color font_color = get_theme_color(SNAME("font_color")); - Color font_selected_color = get_theme_color(SNAME("font_selected_color")); - if (has_focus()) { RenderingServer::get_singleton()->canvas_item_add_clip_ignore(get_canvas_item(), true); - draw_style_box(get_theme_stylebox(SNAME("bg_focus")), Rect2(Point2(), size)); + draw_style_box(theme_cache.bg_focus_style, Rect2(Point2(), size)); RenderingServer::get_singleton()->canvas_item_add_clip_ignore(get_canvas_item(), false); } @@ -1047,9 +1066,9 @@ void ItemList::_notification(int p_what) { if (!items[i].text.is_empty()) { if (icon_mode == ICON_MODE_TOP) { - minsize.y += icon_margin; + minsize.y += theme_cache.icon_margin; } else { - minsize.x += icon_margin; + minsize.x += theme_cache.icon_margin; } } } @@ -1067,7 +1086,7 @@ void ItemList::_notification(int p_what) { if (icon_mode == ICON_MODE_TOP) { minsize.x = MAX(minsize.x, s.width); if (max_text_lines > 0) { - minsize.y += s.height + line_separation * max_text_lines; + minsize.y += s.height + theme_cache.line_separation * max_text_lines; } else { minsize.y += s.height; } @@ -1084,13 +1103,13 @@ void ItemList::_notification(int p_what) { max_column_width = MAX(max_column_width, minsize.x); // elements need to adapt to the selected size - minsize.y += vseparation; - minsize.x += hseparation; + minsize.y += theme_cache.v_separation; + minsize.x += theme_cache.h_separation; items.write[i].rect_cache.size = minsize; items.write[i].min_rect_cache.size = minsize; } - int fit_size = size.x - bg->get_minimum_size().width - mw; + int fit_size = size.x - theme_cache.bg_style->get_minimum_size().width - mw; //2-attempt best fit current_columns = 0x7FFFFFFF; @@ -1118,11 +1137,11 @@ void ItemList::_notification(int p_what) { } items.write[i].rect_cache.position = ofs; max_h = MAX(max_h, items[i].rect_cache.size.y); - ofs.x += items[i].rect_cache.size.x + hseparation; + ofs.x += items[i].rect_cache.size.x + theme_cache.h_separation; col++; if (col == current_columns) { if (i < items.size() - 1) { - separators.push_back(ofs.y + max_h + vseparation / 2); + separators.push_back(ofs.y + max_h + theme_cache.v_separation / 2); } for (int j = i; j >= 0 && col > 0; j--, col--) { @@ -1130,7 +1149,7 @@ void ItemList::_notification(int p_what) { } ofs.x = 0; - ofs.y += max_h + vseparation; + ofs.y += max_h + theme_cache.v_separation; col = 0; max_h = 0; } @@ -1141,10 +1160,10 @@ void ItemList::_notification(int p_what) { } if (all_fit) { - float page = MAX(0, size.height - bg->get_minimum_size().height); + float page = MAX(0, size.height - theme_cache.bg_style->get_minimum_size().height); float max = MAX(page, ofs.y + max_h); if (auto_height) { - auto_height_value = ofs.y + max_h + bg->get_minimum_size().height; + auto_height_value = ofs.y + max_h + theme_cache.bg_style->get_minimum_size().height; } scroll_bar->set_max(max); scroll_bar->set_page(page); @@ -1185,7 +1204,7 @@ void ItemList::_notification(int p_what) { ensure_selected_visible = false; - Vector2 base_ofs = bg->get_offset(); + Vector2 base_ofs = theme_cache.bg_style->get_offset(); base_ofs.y -= int(scroll_bar->get_value()); const Rect2 clip(-base_ofs, size); // visible frame, don't need to draw outside of there @@ -1229,10 +1248,10 @@ void ItemList::_notification(int p_what) { if (items[i].selected) { Rect2 r = rcache; r.position += base_ofs; - r.position.y -= vseparation / 2; - r.size.y += vseparation; - r.position.x -= hseparation / 2; - r.size.x += hseparation; + r.position.y -= theme_cache.v_separation / 2; + r.size.y += theme_cache.v_separation; + r.position.x -= theme_cache.h_separation / 2; + r.size.x += theme_cache.h_separation; if (rtl) { r.position.x = size.width - r.position.x - r.size.x; @@ -1245,10 +1264,10 @@ void ItemList::_notification(int p_what) { r.position += base_ofs; // Size rect to make the align the temperature colors - r.position.y -= vseparation / 2; - r.size.y += vseparation; - r.position.x -= hseparation / 2; - r.size.x += hseparation; + r.position.y -= theme_cache.v_separation / 2; + r.size.y += theme_cache.v_separation; + r.position.x -= theme_cache.h_separation / 2; + r.size.x += theme_cache.h_separation; if (rtl) { r.position.x = size.width - r.position.x - r.size.x; @@ -1274,11 +1293,11 @@ void ItemList::_notification(int p_what) { if (icon_mode == ICON_MODE_TOP) { pos.x += Math::floor((items[i].rect_cache.size.width - icon_size.width) / 2); - pos.y += icon_margin; - text_ofs.y = icon_size.height + icon_margin * 2; + pos.y += theme_cache.icon_margin; + text_ofs.y = icon_size.height + theme_cache.icon_margin * 2; } else { pos.y += Math::floor((items[i].rect_cache.size.height - icon_size.height) / 2); - text_ofs.x = icon_size.width + icon_margin; + text_ofs.x = icon_size.width + theme_cache.icon_margin; } Rect2 draw_rect = Rect2(pos, icon_size); @@ -1329,7 +1348,7 @@ void ItemList::_notification(int p_what) { max_len = size2.x; } - Color modulate = items[i].selected ? font_selected_color : (items[i].custom_fg != Color() ? items[i].custom_fg : font_color); + Color modulate = items[i].selected ? theme_cache.font_selected_color : (items[i].custom_fg != Color() ? items[i].custom_fg : theme_cache.font_color); if (items[i].disabled) { modulate.a *= 0.5; } @@ -1344,8 +1363,8 @@ void ItemList::_notification(int p_what) { items.write[i].text_buf->set_alignment(HORIZONTAL_ALIGNMENT_CENTER); - if (outline_size > 0 && font_outline_color.a > 0) { - items[i].text_buf->draw_outline(get_canvas_item(), text_ofs, outline_size, font_outline_color); + if (theme_cache.font_outline_size > 0 && theme_cache.font_outline_color.a > 0) { + items[i].text_buf->draw_outline(get_canvas_item(), text_ofs, theme_cache.font_outline_size, theme_cache.font_outline_color); } items[i].text_buf->draw(get_canvas_item(), text_ofs, modulate); @@ -1375,8 +1394,8 @@ void ItemList::_notification(int p_what) { items.write[i].text_buf->set_alignment(HORIZONTAL_ALIGNMENT_LEFT); } - if (outline_size > 0 && font_outline_color.a > 0) { - items[i].text_buf->draw_outline(get_canvas_item(), text_ofs, outline_size, font_outline_color); + if (theme_cache.font_outline_size > 0 && theme_cache.font_outline_color.a > 0) { + items[i].text_buf->draw_outline(get_canvas_item(), text_ofs, theme_cache.font_outline_size, theme_cache.font_outline_color); } if (width - text_ofs.x > 0) { @@ -1388,10 +1407,10 @@ void ItemList::_notification(int p_what) { if (select_mode == SELECT_MULTI && i == current) { Rect2 r = rcache; r.position += base_ofs; - r.position.y -= vseparation / 2; - r.size.y += vseparation; - r.position.x -= hseparation / 2; - r.size.x += hseparation; + r.position.y -= theme_cache.v_separation / 2; + r.size.y += theme_cache.v_separation; + r.position.x -= theme_cache.h_separation / 2; + r.size.x += theme_cache.h_separation; if (rtl) { r.position.x = size.width - r.position.x - r.size.x; @@ -1423,7 +1442,7 @@ void ItemList::_notification(int p_what) { } const int y = base_ofs.y + separators[i]; - draw_line(Vector2(bg->get_margin(SIDE_LEFT), y), Vector2(width, y), guide_color); + draw_line(Vector2(theme_cache.bg_style->get_margin(SIDE_LEFT), y), Vector2(width, y), theme_cache.guide_color); } } break; } @@ -1435,8 +1454,7 @@ void ItemList::_scroll_changed(double) { int ItemList::get_item_at_position(const Point2 &p_pos, bool p_exact) const { Vector2 pos = p_pos; - Ref<StyleBox> bg = get_theme_stylebox(SNAME("bg")); - pos -= bg->get_offset(); + pos -= theme_cache.bg_style->get_offset(); pos.y += scroll_bar->get_value(); if (is_layout_rtl()) { @@ -1473,8 +1491,7 @@ bool ItemList::is_pos_at_end_of_items(const Point2 &p_pos) const { } Vector2 pos = p_pos; - Ref<StyleBox> bg = get_theme_stylebox(SNAME("bg")); - pos -= bg->get_offset(); + pos -= theme_cache.bg_style->get_offset(); pos.y += scroll_bar->get_value(); if (is_layout_rtl()) { diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h index 21bd22759c..63bc771185 100644 --- a/scene/gui/item_list.h +++ b/scene/gui/item_list.h @@ -109,23 +109,45 @@ private: int max_columns = 1; Size2 fixed_icon_size; - Size2 max_item_size_cache; int defer_select_single = -1; - bool allow_rmb_select = false; - bool allow_reselect = false; real_t icon_scale = 1.0; bool do_autoscroll_to_bottom = false; + struct ThemeCache { + int h_separation = 0; + int v_separation = 0; + + Ref<StyleBox> bg_style; + Ref<StyleBox> bg_focus_style; + + Ref<Font> font; + int font_size = 0; + Color font_color; + Color font_selected_color; + int font_outline_size = 0; + Color font_outline_color; + + int line_separation = 0; + int icon_margin = 0; + Ref<StyleBox> selected_style; + Ref<StyleBox> selected_focus_style; + Ref<StyleBox> cursor_style; + Ref<StyleBox> cursor_focus_style; + Color guide_color; + } theme_cache; + void _scroll_changed(double); void _shape(int p_idx); protected: + virtual void _update_theme_item_cache() override; + void _notification(int p_what); bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index fd174619d5..306ca3d340 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -71,7 +71,7 @@ bool Label::is_uppercase() const { } int Label::get_line_height(int p_line) const { - Ref<Font> font = (settings.is_valid() && settings->get_font().is_valid()) ? settings->get_font() : get_theme_font(SNAME("font")); + Ref<Font> font = (settings.is_valid() && settings->get_font().is_valid()) ? settings->get_font() : theme_cache.font; if (p_line >= 0 && p_line < lines_rid.size()) { return TS->shaped_text_get_size(lines_rid[p_line]).y; } else if (lines_rid.size() > 0) { @@ -81,13 +81,13 @@ int Label::get_line_height(int p_line) const { } return h; } else { - int font_size = settings.is_valid() ? settings->get_font_size() : get_theme_font_size(SNAME("font_size")); + int font_size = settings.is_valid() ? settings->get_font_size() : theme_cache.font_size; return font->get_height(font_size); } } void Label::_shape() { - Ref<StyleBox> style = get_theme_stylebox(SNAME("normal"), SNAME("Label")); + Ref<StyleBox> style = theme_cache.normal_style; int width = (get_size().width - style->get_minimum_size().width); if (dirty || font_dirty) { @@ -99,8 +99,8 @@ void Label::_shape() { } else { TS->shaped_text_set_direction(text_rid, (TextServer::Direction)text_direction); } - const Ref<Font> &font = (settings.is_valid() && settings->get_font().is_valid()) ? settings->get_font() : get_theme_font(SNAME("font")); - int font_size = settings.is_valid() ? settings->get_font_size() : get_theme_font_size(SNAME("font_size")); + const Ref<Font> &font = (settings.is_valid() && settings->get_font().is_valid()) ? settings->get_font() : theme_cache.font; + int font_size = settings.is_valid() ? settings->get_font_size() : theme_cache.font_size; ERR_FAIL_COND(font.is_null()); String text = (uppercase) ? TS->string_to_upper(xl_text, language) : xl_text; if (visible_chars >= 0 && visible_chars_behavior == TextServer::VC_CHARS_BEFORE_SHAPING) { @@ -232,8 +232,8 @@ void Label::_shape() { } void Label::_update_visible() { - int line_spacing = settings.is_valid() ? settings->get_line_spacing() : get_theme_constant(SNAME("line_spacing"), SNAME("Label")); - Ref<StyleBox> style = get_theme_stylebox(SNAME("normal"), SNAME("Label")); + int line_spacing = settings.is_valid() ? settings->get_line_spacing() : theme_cache.line_spacing; + Ref<StyleBox> style = theme_cache.normal_style; int lines_visible = lines_rid.size(); if (max_lines_visible >= 0 && lines_visible > max_lines_visible) { @@ -272,6 +272,22 @@ inline void draw_glyph_outline(const Glyph &p_gl, const RID &p_canvas, const Col } } +void Label::_update_theme_item_cache() { + Control::_update_theme_item_cache(); + + theme_cache.normal_style = get_theme_stylebox(SNAME("normal")); + theme_cache.font = get_theme_font(SNAME("font")); + + theme_cache.font_size = get_theme_font_size(SNAME("font_size")); + theme_cache.line_spacing = get_theme_constant(SNAME("line_spacing")); + theme_cache.font_color = get_theme_color(SNAME("font_color")); + theme_cache.font_shadow_color = get_theme_color(SNAME("font_shadow_color")); + theme_cache.font_shadow_offset = Point2(get_theme_constant(SNAME("shadow_offset_x")), get_theme_constant(SNAME("shadow_offset_y"))); + theme_cache.font_outline_color = get_theme_color(SNAME("font_outline_color")); + theme_cache.font_outline_size = get_theme_constant(SNAME("outline_size")); + theme_cache.font_shadow_outline_size = get_theme_constant(SNAME("shadow_outline_size")); +} + void Label::_notification(int p_what) { switch (p_what) { case NOTIFICATION_TRANSLATION_CHANGED: { @@ -307,15 +323,15 @@ void Label::_notification(int p_what) { Size2 string_size; Size2 size = get_size(); - Ref<StyleBox> style = get_theme_stylebox(SNAME("normal")); - Ref<Font> font = (has_settings && settings->get_font().is_valid()) ? settings->get_font() : get_theme_font(SNAME("font")); - Color font_color = has_settings ? settings->get_font_color() : get_theme_color(SNAME("font_color")); - Color font_shadow_color = has_settings ? settings->get_shadow_color() : get_theme_color(SNAME("font_shadow_color")); - Point2 shadow_ofs = has_settings ? settings->get_shadow_offset() : Point2(get_theme_constant(SNAME("shadow_offset_x")), get_theme_constant(SNAME("shadow_offset_y"))); - int line_spacing = has_settings ? settings->get_line_spacing() : get_theme_constant(SNAME("line_spacing")); - Color font_outline_color = has_settings ? settings->get_outline_color() : get_theme_color(SNAME("font_outline_color")); - int outline_size = has_settings ? settings->get_outline_size() : get_theme_constant(SNAME("outline_size")); - int shadow_outline_size = has_settings ? settings->get_shadow_size() : get_theme_constant(SNAME("shadow_outline_size")); + Ref<StyleBox> style = theme_cache.normal_style; + Ref<Font> font = (has_settings && settings->get_font().is_valid()) ? settings->get_font() : theme_cache.font; + Color font_color = has_settings ? settings->get_font_color() : theme_cache.font_color; + Color font_shadow_color = has_settings ? settings->get_shadow_color() : theme_cache.font_shadow_color; + Point2 shadow_ofs = has_settings ? settings->get_shadow_offset() : theme_cache.font_shadow_offset; + int line_spacing = has_settings ? settings->get_line_spacing() : theme_cache.line_spacing; + Color font_outline_color = has_settings ? settings->get_outline_color() : theme_cache.font_outline_color; + int outline_size = has_settings ? settings->get_outline_size() : theme_cache.font_outline_size; + int shadow_outline_size = has_settings ? settings->get_shadow_size() : theme_cache.font_shadow_outline_size; bool rtl = (TS->shaped_text_get_inferred_direction(text_rid) == TextServer::DIRECTION_RTL); bool rtl_layout = is_layout_rtl(); @@ -562,12 +578,12 @@ Size2 Label::get_minimum_size() const { Size2 min_size = minsize; - const Ref<Font> &font = (settings.is_valid() && settings->get_font().is_valid()) ? settings->get_font() : get_theme_font(SNAME("font")); - int font_size = settings.is_valid() ? settings->get_font_size() : get_theme_font_size(SNAME("font_size")); + const Ref<Font> &font = (settings.is_valid() && settings->get_font().is_valid()) ? settings->get_font() : theme_cache.font; + int font_size = settings.is_valid() ? settings->get_font_size() : theme_cache.font_size; min_size.height = MAX(min_size.height, font->get_height(font_size) + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM)); - Size2 min_style = get_theme_stylebox(SNAME("normal"))->get_minimum_size(); + Size2 min_style = theme_cache.normal_style->get_minimum_size(); if (autowrap_mode != TextServer::AUTOWRAP_OFF) { return Size2(1, (clip || overrun_behavior != TextServer::OVERRUN_NO_TRIMMING) ? 1 : min_size.height) + min_style; } else { @@ -590,8 +606,8 @@ int Label::get_line_count() const { } int Label::get_visible_line_count() const { - Ref<StyleBox> style = get_theme_stylebox(SNAME("normal")); - int line_spacing = settings.is_valid() ? settings->get_line_spacing() : get_theme_constant(SNAME("line_spacing")); + Ref<StyleBox> style = theme_cache.normal_style; + int line_spacing = settings.is_valid() ? settings->get_line_spacing() : theme_cache.line_spacing; int lines_visible = 0; float total_h = 0.0; for (int64_t i = lines_skipped; i < lines_rid.size(); i++) { @@ -789,10 +805,10 @@ int Label::get_visible_characters() const { void Label::set_visible_ratio(float p_ratio) { if (visible_ratio != p_ratio) { - if (visible_ratio >= 1.0) { + if (p_ratio >= 1.0) { visible_chars = -1; visible_ratio = 1.0; - } else if (visible_ratio < 0.0) { + } else if (p_ratio < 0.0) { visible_chars = 0; visible_ratio = 0.0; } else { diff --git a/scene/gui/label.h b/scene/gui/label.h index 65831cab6e..b79c94a5ba 100644 --- a/scene/gui/label.h +++ b/scene/gui/label.h @@ -67,13 +67,28 @@ private: Ref<LabelSettings> settings; + struct ThemeCache { + Ref<StyleBox> normal_style; + Ref<Font> font; + + int font_size = 0; + int line_spacing = 0; + Color font_color; + Color font_shadow_color; + Point2 font_shadow_offset; + Color font_outline_color; + int font_outline_size; + int font_shadow_outline_size; + } theme_cache; + void _update_visible(); void _shape(); void _invalidate(); protected: - void _notification(int p_what); + virtual void _update_theme_item_cache() override; + void _notification(int p_what); static void _bind_methods(); public: diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index aa8a825014..c2ce4bdb83 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -448,7 +448,7 @@ void LineEdit::gui_input(const Ref<InputEvent> &p_event) { if (context_menu_enabled) { if (k->is_action("ui_menu", true)) { _ensure_menu(); - Point2 pos = Point2(get_caret_pixel_pos().x, (get_size().y + get_theme_font(SNAME("font"))->get_height(get_theme_font_size(SNAME("font_size")))) / 2); + Point2 pos = Point2(get_caret_pixel_pos().x, (get_size().y + theme_cache.font->get_height(theme_cache.font_size)) / 2); menu->set_position(get_screen_position() + pos); menu->reset_size(); menu->popup(); @@ -696,11 +696,38 @@ bool LineEdit::_is_over_clear_button(const Point2 &p_pos) const { if (!clear_button_enabled || !has_point(p_pos)) { return false; } - Ref<Texture2D> icon = Control::get_theme_icon(SNAME("clear")); - int x_ofs = get_theme_stylebox(SNAME("normal"))->get_margin(SIDE_RIGHT); + Ref<Texture2D> icon = theme_cache.clear_icon; + int x_ofs = theme_cache.normal->get_margin(SIDE_RIGHT); return p_pos.x > get_size().width - icon->get_width() - x_ofs; } +void LineEdit::_update_theme_item_cache() { + Control::_update_theme_item_cache(); + + theme_cache.normal = get_theme_stylebox(SNAME("normal")); + theme_cache.read_only = get_theme_stylebox(SNAME("read_only")); + theme_cache.focus = get_theme_stylebox(SNAME("focus")); + + theme_cache.font = get_theme_font(SNAME("font")); + theme_cache.font_size = get_theme_font_size(SNAME("font_size")); + theme_cache.font_color = get_theme_color(SNAME("font_color")); + theme_cache.font_uneditable_color = get_theme_color(SNAME("font_uneditable_color")); + theme_cache.font_selected_color = get_theme_color(SNAME("font_selected_color")); + theme_cache.font_outline_size = get_theme_constant(SNAME("outline_size")); + theme_cache.font_outline_color = get_theme_color(SNAME("font_outline_color")); + theme_cache.font_placeholder_color = get_theme_color(SNAME("font_placeholder_color")); + theme_cache.caret_width = get_theme_constant(SNAME("caret_width")); + theme_cache.caret_color = get_theme_color(SNAME("caret_color")); + theme_cache.minimum_character_width = get_theme_constant(SNAME("minimum_character_width")); + theme_cache.selection_color = get_theme_color(SNAME("selection_color")); + + theme_cache.clear_icon = get_theme_icon(SNAME("clear")); + theme_cache.clear_button_color = get_theme_color(SNAME("clear_button_color")); + theme_cache.clear_button_color_pressed = get_theme_color(SNAME("clear_button_color_pressed")); + + theme_cache.base_scale = get_theme_default_base_scale(); +} + void LineEdit::_notification(int p_what) { switch (p_what) { #ifdef TOOLS_ENABLED @@ -771,19 +798,19 @@ void LineEdit::_notification(int p_what) { RID ci = get_canvas_item(); - Ref<StyleBox> style = get_theme_stylebox(SNAME("normal")); + Ref<StyleBox> style = theme_cache.normal; if (!is_editable()) { - style = get_theme_stylebox(SNAME("read_only")); + style = theme_cache.read_only; draw_caret = false; } - Ref<Font> font = get_theme_font(SNAME("font")); + Ref<Font> font = theme_cache.font; if (!flat) { style->draw(ci, Rect2(Point2(), size)); } if (has_focus()) { - get_theme_stylebox(SNAME("focus"))->draw(ci, Rect2(Point2(), size)); + theme_cache.focus->draw(ci, Rect2(Point2(), size)); } int x_ofs = 0; @@ -821,25 +848,30 @@ void LineEdit::_notification(int p_what) { int y_area = height - style->get_minimum_size().height; int y_ofs = style->get_offset().y + (y_area - text_height) / 2; - Color selection_color = get_theme_color(SNAME("selection_color")); - Color font_color = get_theme_color(is_editable() ? SNAME("font_color") : SNAME("font_uneditable_color")); - Color font_selected_color = get_theme_color(SNAME("font_selected_color")); - Color caret_color = get_theme_color(SNAME("caret_color")); + Color selection_color = theme_cache.selection_color; + Color font_color; + if (is_editable()) { + font_color = theme_cache.font_color; + } else { + font_color = theme_cache.font_uneditable_color; + } + Color font_selected_color = theme_cache.font_selected_color; + Color caret_color = theme_cache.caret_color; // Draw placeholder color. if (using_placeholder) { - font_color = get_theme_color(SNAME("font_placeholder_color")); + font_color = theme_cache.font_placeholder_color; } bool display_clear_icon = !using_placeholder && is_editable() && clear_button_enabled; if (right_icon.is_valid() || display_clear_icon) { - Ref<Texture2D> r_icon = display_clear_icon ? Control::get_theme_icon(SNAME("clear")) : right_icon; + Ref<Texture2D> r_icon = display_clear_icon ? theme_cache.clear_icon : right_icon; Color color_icon(1, 1, 1, !is_editable() ? .5 * .9 : .9); if (display_clear_icon) { if (clear_button_status.press_attempt && clear_button_status.pressing_inside) { - color_icon = get_theme_color(SNAME("clear_button_color_pressed")); + color_icon = theme_cache.clear_button_color_pressed; } else { - color_icon = get_theme_color(SNAME("clear_button_color")); + color_icon = theme_cache.clear_button_color; } } @@ -879,8 +911,8 @@ void LineEdit::_notification(int p_what) { // Draw text. ofs.y += TS->shaped_text_get_ascent(text_rid); - Color font_outline_color = get_theme_color(SNAME("font_outline_color")); - int outline_size = get_theme_constant(SNAME("outline_size")); + Color font_outline_color = theme_cache.font_outline_color; + int outline_size = theme_cache.font_outline_size; if (outline_size > 0 && font_outline_color.a > 0) { Vector2 oofs = ofs; for (int i = 0; i < gl_size; i++) { @@ -918,7 +950,7 @@ void LineEdit::_notification(int p_what) { ofs.x = x_ofs + scroll_offset; if (draw_caret || drag_caret_force_displayed) { // Prevent carets from disappearing at theme scales below 1.0 (if the caret width is 1). - const int caret_width = get_theme_constant(SNAME("caret_width")) * MAX(1, get_theme_default_base_scale()); + const int caret_width = theme_cache.caret_width * MAX(1, theme_cache.base_scale); if (ime_text.length() == 0) { // Normal caret. @@ -926,7 +958,7 @@ void LineEdit::_notification(int p_what) { if (caret.l_caret == Rect2() && caret.t_caret == Rect2()) { // No carets, add one at the start. - int h = get_theme_font(SNAME("font"))->get_height(get_theme_font_size(SNAME("font_size"))); + int h = theme_cache.font->get_height(theme_cache.font_size); int y = style->get_offset().y + (y_area - h) / 2; if (rtl) { caret.l_dir = TextServer::DIRECTION_RTL; @@ -1193,7 +1225,7 @@ void LineEdit::shift_selection_check_post(bool p_shift) { } void LineEdit::set_caret_at_pixel_pos(int p_x) { - Ref<StyleBox> style = get_theme_stylebox(SNAME("normal")); + Ref<StyleBox> style = theme_cache.normal; bool rtl = is_layout_rtl(); int x_ofs = 0; @@ -1226,7 +1258,7 @@ void LineEdit::set_caret_at_pixel_pos(int p_x) { bool using_placeholder = text.is_empty() && ime_text.is_empty(); bool display_clear_icon = !using_placeholder && is_editable() && clear_button_enabled; if (right_icon.is_valid() || display_clear_icon) { - Ref<Texture2D> r_icon = display_clear_icon ? Control::get_theme_icon(SNAME("clear")) : right_icon; + Ref<Texture2D> r_icon = display_clear_icon ? theme_cache.clear_icon : right_icon; if (alignment == HORIZONTAL_ALIGNMENT_CENTER) { if (Math::is_zero_approx(scroll_offset)) { x_ofs = MAX(style->get_margin(SIDE_LEFT), int(get_size().width - text_width - r_icon->get_width() - style->get_margin(SIDE_RIGHT) * 2) / 2); @@ -1241,7 +1273,7 @@ void LineEdit::set_caret_at_pixel_pos(int p_x) { } Vector2 LineEdit::get_caret_pixel_pos() { - Ref<StyleBox> style = get_theme_stylebox(SNAME("normal")); + Ref<StyleBox> style = theme_cache.normal; bool rtl = is_layout_rtl(); int x_ofs = 0; @@ -1274,7 +1306,7 @@ Vector2 LineEdit::get_caret_pixel_pos() { bool using_placeholder = text.is_empty() && ime_text.is_empty(); bool display_clear_icon = !using_placeholder && is_editable() && clear_button_enabled; if (right_icon.is_valid() || display_clear_icon) { - Ref<Texture2D> r_icon = display_clear_icon ? Control::get_theme_icon(SNAME("clear")) : right_icon; + Ref<Texture2D> r_icon = display_clear_icon ? theme_cache.clear_icon : right_icon; if (alignment == HORIZONTAL_ALIGNMENT_CENTER) { if (Math::is_zero_approx(scroll_offset)) { x_ofs = MAX(style->get_margin(SIDE_LEFT), int(get_size().width - text_width - r_icon->get_width() - style->get_margin(SIDE_RIGHT) * 2) / 2); @@ -1559,7 +1591,7 @@ void LineEdit::set_caret_column(int p_column) { return; } - Ref<StyleBox> style = get_theme_stylebox(SNAME("normal")); + Ref<StyleBox> style = theme_cache.normal; bool rtl = is_layout_rtl(); int x_ofs = 0; @@ -1593,7 +1625,7 @@ void LineEdit::set_caret_column(int p_column) { bool using_placeholder = text.is_empty() && ime_text.is_empty(); bool display_clear_icon = !using_placeholder && is_editable() && clear_button_enabled; if (right_icon.is_valid() || display_clear_icon) { - Ref<Texture2D> r_icon = display_clear_icon ? Control::get_theme_icon(SNAME("clear")) : right_icon; + Ref<Texture2D> r_icon = display_clear_icon ? theme_cache.clear_icon : right_icon; if (alignment == HORIZONTAL_ALIGNMENT_CENTER) { if (Math::is_zero_approx(scroll_offset)) { x_ofs = MAX(style->get_margin(SIDE_LEFT), int(get_size().width - text_width - r_icon->get_width() - style->get_margin(SIDE_RIGHT) * 2) / 2); @@ -1664,15 +1696,15 @@ void LineEdit::clear_internal() { } Size2 LineEdit::get_minimum_size() const { - Ref<StyleBox> style = get_theme_stylebox(SNAME("normal")); - Ref<Font> font = get_theme_font(SNAME("font")); - int font_size = get_theme_font_size(SNAME("font_size")); + Ref<StyleBox> style = theme_cache.normal; + Ref<Font> font = theme_cache.font; + int font_size = theme_cache.font_size; Size2 min_size; // Minimum size of text. float em_space_size = font->get_char_size('M', font_size).x; - min_size.width = get_theme_constant(SNAME("minimum_character_width")) * em_space_size; + min_size.width = theme_cache.minimum_character_width * em_space_size; if (expand_to_text_length) { // Add a space because some fonts are too exact, and because caret needs a bit more when at the end. @@ -1688,9 +1720,8 @@ Size2 LineEdit::get_minimum_size() const { icon_max_width = right_icon->get_width(); } if (clear_button_enabled) { - Ref<Texture2D> clear_icon = Control::get_theme_icon(SNAME("clear")); - min_size.height = MAX(min_size.height, clear_icon->get_height()); - icon_max_width = MAX(icon_max_width, clear_icon->get_width()); + min_size.height = MAX(min_size.height, theme_cache.clear_icon->get_height()); + icon_max_width = MAX(icon_max_width, theme_cache.clear_icon->get_width()); } min_size.width += icon_max_width; @@ -2155,8 +2186,8 @@ void LineEdit::_shape() { } TS->shaped_text_set_preserve_control(text_rid, draw_control_chars); - const Ref<Font> &font = get_theme_font(SNAME("font")); - int font_size = get_theme_font_size(SNAME("font_size")); + const Ref<Font> &font = theme_cache.font; + int font_size = theme_cache.font_size; ERR_FAIL_COND(font.is_null()); TS->shaped_text_add_string(text_rid, t, font->get_rids(), font_size, font->get_opentype_features(), language); for (int i = 0; i < TextServer::SPACING_MAX; i++) { @@ -2176,12 +2207,12 @@ void LineEdit::_shape() { void LineEdit::_fit_to_width() { if (alignment == HORIZONTAL_ALIGNMENT_FILL) { - Ref<StyleBox> style = get_theme_stylebox(SNAME("normal")); + Ref<StyleBox> style = theme_cache.normal; int t_width = get_size().width - style->get_margin(SIDE_RIGHT) - style->get_margin(SIDE_LEFT); bool using_placeholder = text.is_empty() && ime_text.is_empty(); bool display_clear_icon = !using_placeholder && is_editable() && clear_button_enabled; if (right_icon.is_valid() || display_clear_icon) { - Ref<Texture2D> r_icon = display_clear_icon ? Control::get_theme_icon(SNAME("clear")) : right_icon; + Ref<Texture2D> r_icon = display_clear_icon ? theme_cache.clear_icon : right_icon; t_width -= r_icon->get_width(); } TS->shaped_text_fit_to_width(text_rid, MAX(t_width, full_width)); diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h index dabdaa3395..0122a5da69 100644 --- a/scene/gui/line_edit.h +++ b/scene/gui/line_edit.h @@ -174,6 +174,31 @@ private: double caret_blink_timer = 0.0; bool caret_blinking = false; + struct ThemeCache { + Ref<StyleBox> normal; + Ref<StyleBox> read_only; + Ref<StyleBox> focus; + + Ref<Font> font; + int font_size = 0; + Color font_color; + Color font_uneditable_color; + Color font_selected_color; + int font_outline_size; + Color font_outline_color; + Color font_placeholder_color; + int caret_width = 0; + Color caret_color; + int minimum_character_width = 0; + Color selection_color; + + Ref<Texture2D> clear_icon; + Color clear_button_color; + Color clear_button_color_pressed; + + float base_scale = 1.0; + } theme_cache; + bool _is_over_clear_button(const Point2 &p_pos) const; void _clear_undo_stack(); @@ -215,6 +240,7 @@ private: void _ensure_menu(); protected: + virtual void _update_theme_item_cache() override; void _notification(int p_what); static void _bind_methods(); virtual void unhandled_key_input(const Ref<InputEvent> &p_event) override; diff --git a/scene/gui/link_button.cpp b/scene/gui/link_button.cpp index b0252ac685..7219e86f52 100644 --- a/scene/gui/link_button.cpp +++ b/scene/gui/link_button.cpp @@ -33,8 +33,8 @@ #include "core/string/translation.h" void LinkButton::_shape() { - Ref<Font> font = get_theme_font(SNAME("font")); - int font_size = get_theme_font_size(SNAME("font_size")); + Ref<Font> font = theme_cache.font; + int font_size = theme_cache.font_size; text_buf->clear(); if (text_direction == Control::TEXT_DIRECTION_INHERITED) { @@ -125,6 +125,26 @@ Size2 LinkButton::get_minimum_size() const { return text_buf->get_size(); } +void LinkButton::_update_theme_item_cache() { + BaseButton::_update_theme_item_cache(); + + theme_cache.focus = get_theme_stylebox(SNAME("focus")); + + theme_cache.font_color = get_theme_color(SNAME("font_color")); + theme_cache.font_focus_color = get_theme_color(SNAME("font_focus_color")); + theme_cache.font_pressed_color = get_theme_color(SNAME("font_pressed_color")); + theme_cache.font_hover_color = get_theme_color(SNAME("font_hover_color")); + theme_cache.font_hover_pressed_color = get_theme_color(SNAME("font_hover_pressed_color")); + theme_cache.font_disabled_color = get_theme_color(SNAME("font_disabled_color")); + + theme_cache.font = get_theme_font(SNAME("font")); + theme_cache.font_size = get_theme_font_size(SNAME("font_size")); + theme_cache.outline_size = get_theme_constant(SNAME("outline_size")); + theme_cache.font_outline_color = get_theme_color(SNAME("font_outline_color")); + + theme_cache.underline_spacing = get_theme_constant(SNAME("underline_spacing")); +} + void LinkButton::_notification(int p_what) { switch (p_what) { case NOTIFICATION_TRANSLATION_CHANGED: { @@ -153,9 +173,9 @@ void LinkButton::_notification(int p_what) { switch (get_draw_mode()) { case DRAW_NORMAL: { if (has_focus()) { - color = get_theme_color(SNAME("font_focus_color")); + color = theme_cache.font_focus_color; } else { - color = get_theme_color(SNAME("font_color")); + color = theme_cache.font_color; } do_underline = underline_mode == UNDERLINE_MODE_ALWAYS; @@ -163,35 +183,35 @@ void LinkButton::_notification(int p_what) { case DRAW_HOVER_PRESSED: case DRAW_PRESSED: { if (has_theme_color(SNAME("font_pressed_color"))) { - color = get_theme_color(SNAME("font_pressed_color")); + color = theme_cache.font_pressed_color; } else { - color = get_theme_color(SNAME("font_color")); + color = theme_cache.font_color; } do_underline = underline_mode != UNDERLINE_MODE_NEVER; } break; case DRAW_HOVER: { - color = get_theme_color(SNAME("font_hover_color")); + color = theme_cache.font_hover_color; do_underline = underline_mode != UNDERLINE_MODE_NEVER; } break; case DRAW_DISABLED: { - color = get_theme_color(SNAME("font_disabled_color")); + color = theme_cache.font_disabled_color; do_underline = underline_mode == UNDERLINE_MODE_ALWAYS; } break; } if (has_focus()) { - Ref<StyleBox> style = get_theme_stylebox(SNAME("focus")); + Ref<StyleBox> style = theme_cache.focus; style->draw(ci, Rect2(Point2(), size)); } int width = text_buf->get_line_width(); - Color font_outline_color = get_theme_color(SNAME("font_outline_color")); - int outline_size = get_theme_constant(SNAME("outline_size")); + Color font_outline_color = theme_cache.font_outline_color; + int outline_size = theme_cache.outline_size; if (is_layout_rtl()) { if (outline_size > 0 && font_outline_color.a > 0) { text_buf->draw_outline(get_canvas_item(), Vector2(size.width - width, 0), outline_size, font_outline_color); @@ -205,7 +225,7 @@ void LinkButton::_notification(int p_what) { } if (do_underline) { - int underline_spacing = get_theme_constant(SNAME("underline_spacing")) + text_buf->get_line_underline_position(); + int underline_spacing = theme_cache.underline_spacing + text_buf->get_line_underline_position(); int y = text_buf->get_line_ascent() + underline_spacing; if (is_layout_rtl()) { diff --git a/scene/gui/link_button.h b/scene/gui/link_button.h index 12a6a7618f..accd848163 100644 --- a/scene/gui/link_button.h +++ b/scene/gui/link_button.h @@ -55,10 +55,29 @@ private: TextServer::StructuredTextParser st_parser = TextServer::STRUCTURED_TEXT_DEFAULT; Array st_args; + struct ThemeCache { + Ref<StyleBox> focus; + + Color font_color; + Color font_focus_color; + Color font_pressed_color; + Color font_hover_color; + Color font_hover_pressed_color; + Color font_disabled_color; + + Ref<Font> font; + int font_size = 0; + int outline_size = 0; + Color font_outline_color; + + int underline_spacing = 0; + } theme_cache; + void _shape(); protected: virtual Size2 get_minimum_size() const override; + virtual void _update_theme_item_cache() override; void _notification(int p_what); static void _bind_methods(); diff --git a/scene/gui/margin_container.cpp b/scene/gui/margin_container.cpp index fac37a8634..60fe681824 100644 --- a/scene/gui/margin_container.cpp +++ b/scene/gui/margin_container.cpp @@ -30,12 +30,16 @@ #include "margin_container.h" -Size2 MarginContainer::get_minimum_size() const { - int margin_left = get_theme_constant(SNAME("margin_left")); - int margin_top = get_theme_constant(SNAME("margin_top")); - int margin_right = get_theme_constant(SNAME("margin_right")); - int margin_bottom = get_theme_constant(SNAME("margin_bottom")); +void MarginContainer::_update_theme_item_cache() { + Container::_update_theme_item_cache(); + + theme_cache.margin_left = get_theme_constant(SNAME("margin_left")); + theme_cache.margin_top = get_theme_constant(SNAME("margin_top")); + theme_cache.margin_right = get_theme_constant(SNAME("margin_right")); + theme_cache.margin_bottom = get_theme_constant(SNAME("margin_bottom")); +} +Size2 MarginContainer::get_minimum_size() const { Size2 max; for (int i = 0; i < get_child_count(); i++) { @@ -59,8 +63,8 @@ Size2 MarginContainer::get_minimum_size() const { } } - max.width += (margin_left + margin_right); - max.height += (margin_top + margin_bottom); + max.width += (theme_cache.margin_left + theme_cache.margin_right); + max.height += (theme_cache.margin_top + theme_cache.margin_bottom); return max; } @@ -86,11 +90,6 @@ Vector<int> MarginContainer::get_allowed_size_flags_vertical() const { void MarginContainer::_notification(int p_what) { switch (p_what) { case NOTIFICATION_SORT_CHILDREN: { - int margin_left = get_theme_constant(SNAME("margin_left")); - int margin_top = get_theme_constant(SNAME("margin_top")); - int margin_right = get_theme_constant(SNAME("margin_right")); - int margin_bottom = get_theme_constant(SNAME("margin_bottom")); - Size2 s = get_size(); for (int i = 0; i < get_child_count(); i++) { @@ -102,9 +101,9 @@ void MarginContainer::_notification(int p_what) { continue; } - int w = s.width - margin_left - margin_right; - int h = s.height - margin_top - margin_bottom; - fit_child_in_rect(c, Rect2(margin_left, margin_top, w, h)); + int w = s.width - theme_cache.margin_left - theme_cache.margin_right; + int h = s.height - theme_cache.margin_top - theme_cache.margin_bottom; + fit_child_in_rect(c, Rect2(theme_cache.margin_left, theme_cache.margin_top, w, h)); } } break; diff --git a/scene/gui/margin_container.h b/scene/gui/margin_container.h index f8a3c5bb11..5c33785170 100644 --- a/scene/gui/margin_container.h +++ b/scene/gui/margin_container.h @@ -36,7 +36,16 @@ class MarginContainer : public Container { GDCLASS(MarginContainer, Container); + struct ThemeCache { + int margin_left = 0; + int margin_top = 0; + int margin_right = 0; + int margin_bottom = 0; + } theme_cache; + protected: + virtual void _update_theme_item_cache() override; + void _notification(int p_what); public: diff --git a/scene/gui/menu_bar.cpp b/scene/gui/menu_bar.cpp index db06fca587..0613652bdf 100644 --- a/scene/gui/menu_bar.cpp +++ b/scene/gui/menu_bar.cpp @@ -149,10 +149,6 @@ void MenuBar::_open_popup(int p_index, bool p_focus_item) { void MenuBar::shortcut_input(const Ref<InputEvent> &p_event) { ERR_FAIL_COND(p_event.is_null()); - if (is_native_menu()) { - return; - } - if (!_is_focus_owner_in_shortcut_context()) { return; } @@ -253,7 +249,7 @@ void MenuBar::_update_submenu(const String &p_menu_name, PopupMenu *p_child) { DisplayServer::get_singleton()->global_menu_add_submenu_item(p_menu_name, p_child->get_item_text(i), p_menu_name + "/" + itos(i)); _update_submenu(p_menu_name + "/" + itos(i), pm); } else { - int index = DisplayServer::get_singleton()->global_menu_add_item(p_menu_name, p_child->get_item_text(i), callable_mp(p_child, &PopupMenu::activate_item), i); + int index = DisplayServer::get_singleton()->global_menu_add_item(p_menu_name, p_child->get_item_text(i), callable_mp(p_child, &PopupMenu::activate_item), Callable(), i); if (p_child->is_item_checkable(i)) { DisplayServer::get_singleton()->global_menu_set_item_checkable(p_menu_name, index, true); @@ -340,6 +336,35 @@ void MenuBar::_update_menu() { queue_redraw(); } +void MenuBar::_update_theme_item_cache() { + Control::_update_theme_item_cache(); + + theme_cache.normal = get_theme_stylebox(SNAME("normal")); + theme_cache.normal_mirrored = get_theme_stylebox(SNAME("normal_mirrored")); + theme_cache.disabled = get_theme_stylebox(SNAME("disabled")); + theme_cache.disabled_mirrored = get_theme_stylebox(SNAME("disabled_mirrored")); + theme_cache.pressed = get_theme_stylebox(SNAME("pressed")); + theme_cache.pressed_mirrored = get_theme_stylebox(SNAME("pressed_mirrored")); + theme_cache.hover = get_theme_stylebox(SNAME("hover")); + theme_cache.hover_mirrored = get_theme_stylebox(SNAME("hover_mirrored")); + theme_cache.hover_pressed = get_theme_stylebox(SNAME("hover_pressed")); + theme_cache.hover_pressed_mirrored = get_theme_stylebox(SNAME("hover_pressed_mirrored")); + + theme_cache.font = get_theme_font(SNAME("font")); + theme_cache.font_size = get_theme_font_size(SNAME("font_size")); + theme_cache.outline_size = get_theme_constant(SNAME("outline_size")); + theme_cache.font_outline_color = get_theme_color(SNAME("font_outline_color")); + + theme_cache.font_color = get_theme_color(SNAME("font_color")); + theme_cache.font_disabled_color = get_theme_color(SNAME("font_disabled_color")); + theme_cache.font_pressed_color = get_theme_color(SNAME("font_pressed_color")); + theme_cache.font_hover_color = get_theme_color(SNAME("font_hover_color")); + theme_cache.font_hover_pressed_color = get_theme_color(SNAME("font_hover_pressed_color")); + theme_cache.font_focus_color = get_theme_color(SNAME("font_focus_color")); + + theme_cache.h_separation = get_theme_constant(SNAME("h_separation")); +} + void MenuBar::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { @@ -376,6 +401,11 @@ void MenuBar::_notification(int p_what) { case NOTIFICATION_INTERNAL_PROCESS: { MutexLock lock(mutex); + if (is_native_menu()) { + // Handled by OS. + return; + } + Vector2 pos = DisplayServer::get_singleton()->mouse_get_position() - mouse_pos_adjusted - get_global_position(); if (pos == old_mouse_pos) { return; @@ -386,7 +416,9 @@ void MenuBar::_notification(int p_what) { if (index >= 0 && index != active_menu) { selected_menu = index; focused_menu = selected_menu; - get_menu_popup(active_menu)->hide(); + if (active_menu >= 0) { + get_menu_popup(active_menu)->hide(); + } _open_popup(index); } } break; @@ -394,8 +426,7 @@ void MenuBar::_notification(int p_what) { } int MenuBar::_get_index_at_point(const Point2 &p_point) const { - Ref<StyleBox> style = get_theme_stylebox(SNAME("normal")); - int hsep = get_theme_constant(SNAME("h_separation")); + Ref<StyleBox> style = theme_cache.normal; int offset = 0; for (int i = 0; i < menu_cache.size(); i++) { if (menu_cache[i].hidden) { @@ -407,7 +438,7 @@ int MenuBar::_get_index_at_point(const Point2 &p_point) const { return i; } } - offset += size.x + hsep; + offset += size.x + theme_cache.h_separation; } return -1; } @@ -415,8 +446,7 @@ int MenuBar::_get_index_at_point(const Point2 &p_point) const { Rect2 MenuBar::_get_menu_item_rect(int p_index) const { ERR_FAIL_INDEX_V(p_index, menu_cache.size(), Rect2()); - Ref<StyleBox> style = get_theme_stylebox(SNAME("normal")); - int hsep = get_theme_constant(SNAME("h_separation")); + Ref<StyleBox> style = theme_cache.normal; int offset = 0; for (int i = 0; i < p_index; i++) { @@ -424,7 +454,7 @@ Rect2 MenuBar::_get_menu_item_rect(int p_index) const { continue; } Size2 size = menu_cache[i].text_buf->get_size() + style->get_minimum_size(); - offset += size.x + hsep; + offset += size.x + theme_cache.h_separation; } return Rect2(Point2(offset, 0), menu_cache[p_index].text_buf->get_size() + style->get_minimum_size()); @@ -443,76 +473,76 @@ void MenuBar::_draw_menu_item(int p_index) { } Color color; - Ref<StyleBox> style = get_theme_stylebox(SNAME("normal")); + Ref<StyleBox> style = theme_cache.normal; Rect2 item_rect = _get_menu_item_rect(p_index); if (menu_cache[p_index].disabled) { if (rtl && has_theme_stylebox(SNAME("disabled_mirrored"))) { - style = get_theme_stylebox(SNAME("disabled_mirrored")); + style = theme_cache.disabled_mirrored; } else { - style = get_theme_stylebox(SNAME("disabled")); + style = theme_cache.disabled; } if (!flat) { style->draw(ci, item_rect); } - color = get_theme_color(SNAME("font_disabled_color")); + color = theme_cache.font_disabled_color; } else if (hovered && pressed && has_theme_stylebox("hover_pressed")) { if (rtl && has_theme_stylebox(SNAME("hover_pressed_mirrored"))) { - style = get_theme_stylebox(SNAME("hover_pressed_mirrored")); + style = theme_cache.hover_pressed_mirrored; } else { - style = get_theme_stylebox(SNAME("hover_pressed")); + style = theme_cache.hover_pressed; } if (!flat) { style->draw(ci, item_rect); } if (has_theme_color(SNAME("font_hover_pressed_color"))) { - color = get_theme_color(SNAME("font_hover_pressed_color")); + color = theme_cache.font_hover_pressed_color; } } else if (pressed) { if (rtl && has_theme_stylebox(SNAME("pressed_mirrored"))) { - style = get_theme_stylebox(SNAME("pressed_mirrored")); + style = theme_cache.pressed_mirrored; } else { - style = get_theme_stylebox(SNAME("pressed")); + style = theme_cache.pressed; } if (!flat) { style->draw(ci, item_rect); } if (has_theme_color(SNAME("font_pressed_color"))) { - color = get_theme_color(SNAME("font_pressed_color")); + color = theme_cache.font_pressed_color; } else { - color = get_theme_color(SNAME("font_color")); + color = theme_cache.font_color; } } else if (hovered) { if (rtl && has_theme_stylebox(SNAME("hover_mirrored"))) { - style = get_theme_stylebox(SNAME("hover_mirrored")); + style = theme_cache.hover_mirrored; } else { - style = get_theme_stylebox(SNAME("hover")); + style = theme_cache.hover; } if (!flat) { style->draw(ci, item_rect); } - color = get_theme_color(SNAME("font_hover_color")); + color = theme_cache.font_hover_color; } else { if (rtl && has_theme_stylebox(SNAME("normal_mirrored"))) { - style = get_theme_stylebox(SNAME("normal_mirrored")); + style = theme_cache.normal_mirrored; } else { - style = get_theme_stylebox(SNAME("normal")); + style = theme_cache.normal; } if (!flat) { style->draw(ci, item_rect); } // Focus colors only take precedence over normal state. if (has_focus()) { - color = get_theme_color(SNAME("font_focus_color")); + color = theme_cache.font_focus_color; } else { - color = get_theme_color(SNAME("font_color")); + color = theme_cache.font_color; } } Point2 text_ofs = item_rect.position + Point2(style->get_margin(SIDE_LEFT), style->get_margin(SIDE_TOP)); - Color font_outline_color = get_theme_color(SNAME("font_outline_color")); - int outline_size = get_theme_constant(SNAME("outline_size")); + Color font_outline_color = theme_cache.font_outline_color; + int outline_size = theme_cache.outline_size; if (outline_size > 0 && font_outline_color.a > 0) { menu_cache[p_index].text_buf->draw_outline(ci, text_ofs, outline_size, font_outline_color); } @@ -520,16 +550,13 @@ void MenuBar::_draw_menu_item(int p_index) { } void MenuBar::shape(Menu &p_menu) { - Ref<Font> font = get_theme_font(SNAME("font")); - int font_size = get_theme_font_size(SNAME("font_size")); - p_menu.text_buf->clear(); if (text_direction == Control::TEXT_DIRECTION_INHERITED) { p_menu.text_buf->set_direction(is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR); } else { p_menu.text_buf->set_direction((TextServer::Direction)text_direction); } - p_menu.text_buf->add_string(p_menu.name, font, font_size, language); + p_menu.text_buf->add_string(p_menu.name, theme_cache.font, theme_cache.font_size, language); } void MenuBar::_refresh_menu_names() { @@ -759,7 +786,7 @@ Size2 MenuBar::get_minimum_size() const { return Size2(); } - Ref<StyleBox> style = get_theme_stylebox(SNAME("normal")); + Ref<StyleBox> style = theme_cache.normal; Vector2 size; for (int i = 0; i < menu_cache.size(); i++) { @@ -771,7 +798,7 @@ Size2 MenuBar::get_minimum_size() const { size.x += sz.x; } if (menu_cache.size() > 1) { - size.x += get_theme_constant(SNAME("h_separation")) * (menu_cache.size() - 1); + size.x += theme_cache.h_separation * (menu_cache.size() - 1); } return size; } diff --git a/scene/gui/menu_bar.h b/scene/gui/menu_bar.h index 5aa8ac7324..f7ef19e98b 100644 --- a/scene/gui/menu_bar.h +++ b/scene/gui/menu_bar.h @@ -76,6 +76,33 @@ class MenuBar : public Control { Vector2i old_mouse_pos; ObjectID shortcut_context; + struct ThemeCache { + Ref<StyleBox> normal; + Ref<StyleBox> normal_mirrored; + Ref<StyleBox> disabled; + Ref<StyleBox> disabled_mirrored; + Ref<StyleBox> pressed; + Ref<StyleBox> pressed_mirrored; + Ref<StyleBox> hover; + Ref<StyleBox> hover_mirrored; + Ref<StyleBox> hover_pressed; + Ref<StyleBox> hover_pressed_mirrored; + + Ref<Font> font; + int font_size = 0; + int outline_size = 0; + Color font_outline_color; + + Color font_color; + Color font_disabled_color; + Color font_pressed_color; + Color font_hover_color; + Color font_hover_pressed_color; + Color font_focus_color; + + int h_separation = 0; + } theme_cache; + int _get_index_at_point(const Point2 &p_point) const; Rect2 _get_menu_item_rect(int p_index) const; void _draw_menu_item(int p_index); @@ -96,6 +123,7 @@ class MenuBar : public Control { protected: virtual void shortcut_input(const Ref<InputEvent> &p_event) override; + virtual void _update_theme_item_cache() override; void _notification(int p_what); virtual void add_child_notify(Node *p_child) override; virtual void move_child_notify(Node *p_child) override; diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index a87c46e8ac..0dd9666858 100644 --- a/scene/gui/option_button.cpp +++ b/scene/gui/option_button.cpp @@ -43,11 +43,11 @@ Size2 OptionButton::get_minimum_size() const { } if (has_theme_icon(SNAME("arrow"))) { - const Size2 padding = get_theme_stylebox(SNAME("normal"))->get_minimum_size(); - const Size2 arrow_size = Control::get_theme_icon(SNAME("arrow"))->get_size(); + const Size2 padding = theme_cache.normal->get_minimum_size(); + const Size2 arrow_size = theme_cache.arrow_icon->get_size(); Size2 content_size = minsize - padding; - content_size.width += arrow_size.width + MAX(0, get_theme_constant(SNAME("h_separation"))); + content_size.width += arrow_size.width + MAX(0, theme_cache.h_separation); content_size.height = MAX(content_size.height, arrow_size.height); minsize = content_size + padding; @@ -56,35 +56,63 @@ Size2 OptionButton::get_minimum_size() const { return minsize; } +void OptionButton::_update_theme_item_cache() { + Button::_update_theme_item_cache(); + + theme_cache.normal = get_theme_stylebox(SNAME("normal")); + + theme_cache.font_color = get_theme_color(SNAME("font_color")); + theme_cache.font_focus_color = get_theme_color(SNAME("font_focus_color")); + theme_cache.font_pressed_color = get_theme_color(SNAME("font_pressed_color")); + theme_cache.font_hover_color = get_theme_color(SNAME("font_hover_color")); + theme_cache.font_hover_pressed_color = get_theme_color(SNAME("font_hover_pressed_color")); + theme_cache.font_disabled_color = get_theme_color(SNAME("font_disabled_color")); + + theme_cache.h_separation = get_theme_constant(SNAME("h_separation")); + + theme_cache.arrow_icon = get_theme_icon(SNAME("arrow")); + theme_cache.arrow_margin = get_theme_constant(SNAME("arrow_margin")); + theme_cache.modulate_arrow = get_theme_constant(SNAME("modulate_arrow")); +} + void OptionButton::_notification(int p_what) { switch (p_what) { + case NOTIFICATION_POSTINITIALIZE: { + if (has_theme_icon(SNAME("arrow"))) { + if (is_layout_rtl()) { + _set_internal_margin(SIDE_LEFT, theme_cache.arrow_icon->get_width()); + } else { + _set_internal_margin(SIDE_RIGHT, theme_cache.arrow_icon->get_width()); + } + } + } break; + case NOTIFICATION_DRAW: { if (!has_theme_icon(SNAME("arrow"))) { return; } RID ci = get_canvas_item(); - Ref<Texture2D> arrow = Control::get_theme_icon(SNAME("arrow")); Color clr = Color(1, 1, 1); - if (get_theme_constant(SNAME("modulate_arrow"))) { + if (theme_cache.modulate_arrow) { switch (get_draw_mode()) { case DRAW_PRESSED: - clr = get_theme_color(SNAME("font_pressed_color")); + clr = theme_cache.font_pressed_color; break; case DRAW_HOVER: - clr = get_theme_color(SNAME("font_hover_color")); + clr = theme_cache.font_hover_color; break; case DRAW_HOVER_PRESSED: - clr = get_theme_color(SNAME("font_hover_pressed_color")); + clr = theme_cache.font_hover_pressed_color; break; case DRAW_DISABLED: - clr = get_theme_color(SNAME("font_disabled_color")); + clr = theme_cache.font_disabled_color; break; default: if (has_focus()) { - clr = get_theme_color(SNAME("font_focus_color")); + clr = theme_cache.font_focus_color; } else { - clr = get_theme_color(SNAME("font_color")); + clr = theme_cache.font_color; } } } @@ -93,11 +121,11 @@ void OptionButton::_notification(int p_what) { Point2 ofs; if (is_layout_rtl()) { - ofs = Point2(get_theme_constant(SNAME("arrow_margin")), int(Math::abs((size.height - arrow->get_height()) / 2))); + ofs = Point2(theme_cache.arrow_margin, int(Math::abs((size.height - theme_cache.arrow_icon->get_height()) / 2))); } else { - ofs = Point2(size.width - arrow->get_width() - get_theme_constant(SNAME("arrow_margin")), int(Math::abs((size.height - arrow->get_height()) / 2))); + ofs = Point2(size.width - theme_cache.arrow_icon->get_width() - theme_cache.arrow_margin, int(Math::abs((size.height - theme_cache.arrow_icon->get_height()) / 2))); } - arrow->draw(ci, ofs, clr); + theme_cache.arrow_icon->draw(ci, ofs, clr); } break; case NOTIFICATION_TRANSLATION_CHANGED: @@ -108,11 +136,11 @@ void OptionButton::_notification(int p_what) { case NOTIFICATION_THEME_CHANGED: { if (has_theme_icon(SNAME("arrow"))) { if (is_layout_rtl()) { - _set_internal_margin(SIDE_LEFT, Control::get_theme_icon(SNAME("arrow"))->get_width()); + _set_internal_margin(SIDE_LEFT, theme_cache.arrow_icon->get_width()); _set_internal_margin(SIDE_RIGHT, 0.f); } else { _set_internal_margin(SIDE_LEFT, 0.f); - _set_internal_margin(SIDE_RIGHT, Control::get_theme_icon(SNAME("arrow"))->get_width()); + _set_internal_margin(SIDE_RIGHT, theme_cache.arrow_icon->get_width()); } } _refresh_size_cache(); @@ -540,15 +568,6 @@ OptionButton::OptionButton(const String &p_text) : Button(p_text) { set_toggle_mode(true); set_text_alignment(HORIZONTAL_ALIGNMENT_LEFT); - if (is_layout_rtl()) { - if (has_theme_icon(SNAME("arrow"))) { - _set_internal_margin(SIDE_LEFT, Control::get_theme_icon(SNAME("arrow"))->get_width()); - } - } else { - if (has_theme_icon(SNAME("arrow"))) { - _set_internal_margin(SIDE_RIGHT, Control::get_theme_icon(SNAME("arrow"))->get_width()); - } - } set_action_mode(ACTION_MODE_BUTTON_PRESS); popup = memnew(PopupMenu); diff --git a/scene/gui/option_button.h b/scene/gui/option_button.h index cd709b8f5f..2c7e0510f5 100644 --- a/scene/gui/option_button.h +++ b/scene/gui/option_button.h @@ -43,6 +43,23 @@ class OptionButton : public Button { Vector2 _cached_size; bool cache_refresh_pending = false; + struct ThemeCache { + Ref<StyleBox> normal; + + Color font_color; + Color font_focus_color; + Color font_pressed_color; + Color font_hover_color; + Color font_hover_pressed_color; + Color font_disabled_color; + + int h_separation = 0; + + Ref<Texture2D> arrow_icon; + int arrow_margin = 0; + int modulate_arrow = 0; + } theme_cache; + void _focused(int p_which); void _selected(int p_which); void _select(int p_which, bool p_emit = false); @@ -54,6 +71,7 @@ class OptionButton : public Button { protected: Size2 get_minimum_size() const override; + virtual void _update_theme_item_cache() override; void _notification(int p_what); bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; diff --git a/scene/gui/panel.cpp b/scene/gui/panel.cpp index 1ac6cf57ab..09bc295513 100644 --- a/scene/gui/panel.cpp +++ b/scene/gui/panel.cpp @@ -30,12 +30,17 @@ #include "panel.h" +void Panel::_update_theme_item_cache() { + Control::_update_theme_item_cache(); + + theme_cache.panel_style = get_theme_stylebox(SNAME("panel")); +} + void Panel::_notification(int p_what) { switch (p_what) { case NOTIFICATION_DRAW: { RID ci = get_canvas_item(); - Ref<StyleBox> style = get_theme_stylebox(SNAME("panel")); - style->draw(ci, Rect2(Point2(), get_size())); + theme_cache.panel_style->draw(ci, Rect2(Point2(), get_size())); } break; } } diff --git a/scene/gui/panel.h b/scene/gui/panel.h index 5d2e912680..f9bd721681 100644 --- a/scene/gui/panel.h +++ b/scene/gui/panel.h @@ -36,7 +36,13 @@ class Panel : public Control { GDCLASS(Panel, Control); + struct ThemeCache { + Ref<StyleBox> panel_style; + } theme_cache; + protected: + virtual void _update_theme_item_cache() override; + void _notification(int p_what); public: diff --git a/scene/gui/panel_container.cpp b/scene/gui/panel_container.cpp index fe01712a89..eeaded1788 100644 --- a/scene/gui/panel_container.cpp +++ b/scene/gui/panel_container.cpp @@ -31,14 +31,6 @@ #include "panel_container.h" Size2 PanelContainer::get_minimum_size() const { - Ref<StyleBox> style; - - if (has_theme_stylebox(SNAME("panel"))) { - style = get_theme_stylebox(SNAME("panel")); - } else { - style = get_theme_stylebox(SNAME("panel"), SNAME("PanelContainer")); - } - Size2 ms; for (int i = 0; i < get_child_count(); i++) { Control *c = Object::cast_to<Control>(get_child(i)); @@ -54,8 +46,8 @@ Size2 PanelContainer::get_minimum_size() const { ms.height = MAX(ms.height, minsize.height); } - if (style.is_valid()) { - ms += style->get_minimum_size(); + if (theme_cache.panel_style.is_valid()) { + ms += theme_cache.panel_style->get_minimum_size(); } return ms; } @@ -78,35 +70,25 @@ Vector<int> PanelContainer::get_allowed_size_flags_vertical() const { return flags; } +void PanelContainer::_update_theme_item_cache() { + Container::_update_theme_item_cache(); + + theme_cache.panel_style = get_theme_stylebox(SNAME("panel")); +} + void PanelContainer::_notification(int p_what) { switch (p_what) { case NOTIFICATION_DRAW: { RID ci = get_canvas_item(); - Ref<StyleBox> style; - - if (has_theme_stylebox(SNAME("panel"))) { - style = get_theme_stylebox(SNAME("panel")); - } else { - style = get_theme_stylebox(SNAME("panel"), SNAME("PanelContainer")); - } - - style->draw(ci, Rect2(Point2(), get_size())); + theme_cache.panel_style->draw(ci, Rect2(Point2(), get_size())); } break; case NOTIFICATION_SORT_CHILDREN: { - Ref<StyleBox> style; - - if (has_theme_stylebox(SNAME("panel"))) { - style = get_theme_stylebox(SNAME("panel")); - } else { - style = get_theme_stylebox(SNAME("panel"), SNAME("PanelContainer")); - } - Size2 size = get_size(); Point2 ofs; - if (style.is_valid()) { - size -= style->get_minimum_size(); - ofs += style->get_offset(); + if (theme_cache.panel_style.is_valid()) { + size -= theme_cache.panel_style->get_minimum_size(); + ofs += theme_cache.panel_style->get_offset(); } for (int i = 0; i < get_child_count(); i++) { diff --git a/scene/gui/panel_container.h b/scene/gui/panel_container.h index 8f07ce38eb..97d0cdc872 100644 --- a/scene/gui/panel_container.h +++ b/scene/gui/panel_container.h @@ -36,7 +36,12 @@ class PanelContainer : public Container { GDCLASS(PanelContainer, Container); + struct ThemeCache { + Ref<StyleBox> panel_style; + } theme_cache; + protected: + virtual void _update_theme_item_cache() override; void _notification(int p_what); public: diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp index c4396f636a..ceae3791f3 100644 --- a/scene/gui/popup.cpp +++ b/scene/gui/popup.cpp @@ -68,6 +68,12 @@ void Popup::_deinitialize_visible_parents() { } } +void Popup::_update_theme_item_cache() { + Window::_update_theme_item_cache(); + + theme_cache.panel_style = get_theme_stylebox(SNAME("panel")); +} + void Popup::_notification(int p_what) { switch (p_what) { case NOTIFICATION_VISIBILITY_CHANGED: { @@ -186,8 +192,6 @@ Popup::~Popup() { } Size2 PopupPanel::_get_contents_minimum_size() const { - Ref<StyleBox> p = get_theme_stylebox(SNAME("panel"), get_class_name()); - Size2 ms; for (int i = 0; i < get_child_count(); i++) { @@ -205,14 +209,12 @@ Size2 PopupPanel::_get_contents_minimum_size() const { ms.y = MAX(cms.y, ms.y); } - return ms + p->get_minimum_size(); + return ms + theme_cache.panel_style->get_minimum_size(); } void PopupPanel::_update_child_rects() { - Ref<StyleBox> p = get_theme_stylebox(SNAME("panel"), get_class_name()); - - Vector2 cpos(p->get_offset()); - Vector2 csize(get_size() - p->get_minimum_size()); + Vector2 cpos(theme_cache.panel_style->get_offset()); + Vector2 csize(get_size() - theme_cache.panel_style->get_minimum_size()); for (int i = 0; i < get_child_count(); i++) { Control *c = Object::cast_to<Control>(get_child(i)); @@ -234,15 +236,17 @@ void PopupPanel::_update_child_rects() { } } +void PopupPanel::_update_theme_item_cache() { + Popup::_update_theme_item_cache(); + + theme_cache.panel_style = get_theme_stylebox(SNAME("panel")); +} + void PopupPanel::_notification(int p_what) { switch (p_what) { + case NOTIFICATION_READY: case NOTIFICATION_THEME_CHANGED: { - panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), get_class_name())); - } break; - - case NOTIFICATION_ENTER_TREE: - case NOTIFICATION_READY: { - panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), get_class_name())); + panel->add_theme_style_override("panel", theme_cache.panel_style); _update_child_rects(); } break; diff --git a/scene/gui/popup.h b/scene/gui/popup.h index 70eb8722d0..0d6ca25c18 100644 --- a/scene/gui/popup.h +++ b/scene/gui/popup.h @@ -43,6 +43,10 @@ class Popup : public Window { LocalVector<Window *> visible_parents; bool popped_up = false; + struct ThemeCache { + Ref<StyleBox> panel_style; + } theme_cache; + void _input_from_window(const Ref<InputEvent> &p_event); void _initialize_visible_parents(); @@ -52,6 +56,7 @@ protected: void _close_pressed(); virtual Rect2i _popup_adjust_rect() const override; + virtual void _update_theme_item_cache() override; void _notification(int p_what); static void _bind_methods(); @@ -69,8 +74,14 @@ class PopupPanel : public Popup { Panel *panel = nullptr; + struct ThemeCache { + Ref<StyleBox> panel_style; + } theme_cache; + protected: void _update_child_rects(); + + virtual void _update_theme_item_cache() override; void _notification(int p_what); virtual Size2 _get_contents_minimum_size() const override; diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index c3060bf242..9afcd566b9 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -48,15 +48,12 @@ String PopupMenu::_get_accel_text(const Item &p_item) const { } Size2 PopupMenu::_get_contents_minimum_size() const { - int vseparation = get_theme_constant(SNAME("v_separation")); - int hseparation = get_theme_constant(SNAME("h_separation")); - - Size2 minsize = get_theme_stylebox(SNAME("panel"))->get_minimum_size(); // Accounts for margin in the margin container + Size2 minsize = theme_cache.panel_style->get_minimum_size(); // Accounts for margin in the margin container minsize.x += scroll_container->get_v_scroll_bar()->get_size().width * 2; // Adds a buffer so that the scrollbar does not render over the top of content float max_w = 0.0; float icon_w = 0.0; - int check_w = MAX(get_theme_icon(SNAME("checked"))->get_width(), get_theme_icon(SNAME("radio_checked"))->get_width()) + hseparation; + int check_w = MAX(theme_cache.checked->get_width(), theme_cache.radio_checked->get_width()) + theme_cache.h_separation; int accel_max_w = 0; bool has_check = false; @@ -67,23 +64,23 @@ Size2 PopupMenu::_get_contents_minimum_size() const { size.height = _get_item_height(i); icon_w = MAX(icon_size.width, icon_w); - size.width += items[i].indent * get_theme_constant(SNAME("indent")); + size.width += items[i].indent * theme_cache.indent; if (items[i].checkable_type && !items[i].separator) { has_check = true; } size.width += items[i].text_buf->get_size().x; - size.height += vseparation; + size.height += theme_cache.v_separation; if (items[i].accel != Key::NONE || (items[i].shortcut.is_valid() && items[i].shortcut->has_valid_event())) { - int accel_w = hseparation * 2; + int accel_w = theme_cache.h_separation * 2; accel_w += items[i].accel_text_buf->get_size().x; accel_max_w = MAX(accel_w, accel_max_w); } if (!items[i].submenu.is_empty()) { - size.width += get_theme_icon(SNAME("submenu"))->get_width(); + size.width += theme_cache.submenu->get_width(); } max_w = MAX(max_w, size.width); @@ -91,7 +88,7 @@ Size2 PopupMenu::_get_contents_minimum_size() const { minsize.height += size.height; } - int item_side_padding = get_theme_constant(SNAME("item_start_padding")) + get_theme_constant(SNAME("item_end_padding")); + int item_side_padding = theme_cache.item_start_padding + theme_cache.item_end_padding; minsize.width += max_w + icon_w + accel_max_w + item_side_padding; if (has_check) { @@ -113,33 +110,31 @@ int PopupMenu::_get_item_height(int p_item) const { int icon_height = items[p_item].get_icon_size().height; if (items[p_item].checkable_type && !items[p_item].separator) { - icon_height = MAX(icon_height, MAX(get_theme_icon(SNAME("checked"))->get_height(), get_theme_icon(SNAME("radio_checked"))->get_height())); + icon_height = MAX(icon_height, MAX(theme_cache.checked->get_height(), theme_cache.radio_checked->get_height())); } int text_height = items[p_item].text_buf->get_size().height; if (text_height == 0 && !items[p_item].separator) { - text_height = get_theme_font(SNAME("font"))->get_height(get_theme_font_size(SNAME("font_size"))); + text_height = theme_cache.font->get_height(theme_cache.font_size); } int separator_height = 0; if (items[p_item].separator) { - separator_height = MAX(get_theme_stylebox(SNAME("separator"))->get_minimum_size().height, MAX(get_theme_stylebox(SNAME("labeled_separator_left"))->get_minimum_size().height, get_theme_stylebox(SNAME("labeled_separator_right"))->get_minimum_size().height)); + separator_height = MAX(theme_cache.separator_style->get_minimum_size().height, MAX(theme_cache.labeled_separator_left->get_minimum_size().height, theme_cache.labeled_separator_right->get_minimum_size().height)); } return MAX(separator_height, MAX(text_height, icon_height)); } int PopupMenu::_get_items_total_height() const { - int vsep = get_theme_constant(SNAME("v_separation")); - // Get total height of all items by taking max of icon height and font height int items_total_height = 0; for (int i = 0; i < items.size(); i++) { - items_total_height += _get_item_height(i) + vsep; + items_total_height += _get_item_height(i) + theme_cache.v_separation; } // Subtract a separator which is not needed for the last item. - return items_total_height - vsep; + return items_total_height - theme_cache.v_separation; } int PopupMenu::_get_mouse_over(const Point2 &p_over) const { @@ -147,18 +142,15 @@ int PopupMenu::_get_mouse_over(const Point2 &p_over) const { return -1; } - Ref<StyleBox> style = get_theme_stylebox(SNAME("panel")); // Accounts for margin in the margin container - - int vseparation = get_theme_constant(SNAME("v_separation")); - - Point2 ofs = style->get_offset() + Point2(0, vseparation / 2); + // Accounts for margin in the margin container + Point2 ofs = theme_cache.panel_style->get_offset() + Point2(0, theme_cache.v_separation / 2); if (ofs.y > p_over.y) { return -1; } for (int i = 0; i < items.size(); i++) { - ofs.y += i > 0 ? vseparation : (float)vseparation / 2; + ofs.y += i > 0 ? theme_cache.v_separation : (float)theme_cache.v_separation / 2; ofs.y += _get_item_height(i); @@ -179,9 +171,6 @@ void PopupMenu::_activate_submenu(int p_over, bool p_by_keyboard) { return; // Already visible. } - Ref<StyleBox> style = get_theme_stylebox(SNAME("panel")); - int vsep = get_theme_constant(SNAME("v_separation")); - Point2 this_pos = get_position(); Rect2 this_rect(this_pos, get_size()); @@ -231,7 +220,7 @@ void PopupMenu::_activate_submenu(int p_over, bool p_by_keyboard) { // Set autohide areas. Rect2 safe_area = this_rect; - safe_area.position.y += items[p_over]._ofs_cache + scroll_offset + style->get_offset().height - vsep / 2; + safe_area.position.y += items[p_over]._ofs_cache + scroll_offset + theme_cache.panel_style->get_offset().height - theme_cache.v_separation / 2; safe_area.size.y = items[p_over]._height_cache; DisplayServer::get_singleton()->window_set_popup_safe_rect(submenu_popup->get_window_id(), safe_area); @@ -240,11 +229,11 @@ void PopupMenu::_activate_submenu(int p_over, bool p_by_keyboard) { // Autohide area above the submenu item. submenu_pum->clear_autohide_areas(); - submenu_pum->add_autohide_area(Rect2(this_rect.position.x, this_rect.position.y, this_rect.size.x, items[p_over]._ofs_cache + scroll_offset + style->get_offset().height - vsep / 2)); + submenu_pum->add_autohide_area(Rect2(this_rect.position.x, this_rect.position.y, this_rect.size.x, items[p_over]._ofs_cache + scroll_offset + theme_cache.panel_style->get_offset().height - theme_cache.v_separation / 2)); // If there is an area below the submenu item, add an autohide area there. if (items[p_over]._ofs_cache + items[p_over]._height_cache + scroll_offset <= control->get_size().height) { - int from = items[p_over]._ofs_cache + items[p_over]._height_cache + scroll_offset + vsep / 2 + style->get_offset().height; + int from = items[p_over]._ofs_cache + items[p_over]._height_cache + scroll_offset + theme_cache.v_separation / 2 + theme_cache.panel_style->get_offset().height; submenu_pum->add_autohide_area(Rect2(this_rect.position.x, this_rect.position.y + from, this_rect.size.x, this_rect.size.y - from)); } } @@ -442,7 +431,7 @@ void PopupMenu::gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseMotion> m = p_event; if (m.is_valid()) { - if (m->get_velocity().is_equal_approx(Vector2())) { + if (m->get_velocity().is_zero_approx()) { return; } activated_by_keyboard = false; @@ -528,34 +517,17 @@ void PopupMenu::_draw_items() { margin_size.height = margin_container->get_theme_constant(SNAME("margin_top")) + margin_container->get_theme_constant(SNAME("margin_bottom")); // Space between the item content and the sides of popup menu. - int item_start_padding = get_theme_constant(SNAME("item_start_padding")); - int item_end_padding = get_theme_constant(SNAME("item_end_padding")); - bool rtl = control->is_layout_rtl(); - Ref<StyleBox> style = get_theme_stylebox(SNAME("panel")); - Ref<StyleBox> hover = get_theme_stylebox(SNAME("hover")); // In Item::checkable_type enum order (less the non-checkable member), with disabled repeated at the end. - Ref<Texture2D> check[] = { get_theme_icon(SNAME("checked")), get_theme_icon(SNAME("radio_checked")), get_theme_icon(SNAME("checked_disabled")), get_theme_icon(SNAME("radio_checked_disabled")) }; - Ref<Texture2D> uncheck[] = { get_theme_icon(SNAME("unchecked")), get_theme_icon(SNAME("radio_unchecked")), get_theme_icon(SNAME("unchecked_disabled")), get_theme_icon(SNAME("radio_unchecked_disabled")) }; + Ref<Texture2D> check[] = { theme_cache.checked, theme_cache.radio_checked, theme_cache.checked_disabled, theme_cache.radio_checked_disabled }; + Ref<Texture2D> uncheck[] = { theme_cache.unchecked, theme_cache.radio_unchecked, theme_cache.unchecked_disabled, theme_cache.radio_unchecked_disabled }; Ref<Texture2D> submenu; if (rtl) { - submenu = get_theme_icon(SNAME("submenu_mirrored")); + submenu = theme_cache.submenu_mirrored; } else { - submenu = get_theme_icon(SNAME("submenu")); + submenu = theme_cache.submenu; } - Ref<StyleBox> separator = get_theme_stylebox(SNAME("separator")); - Ref<StyleBox> labeled_separator_left = get_theme_stylebox(SNAME("labeled_separator_left")); - Ref<StyleBox> labeled_separator_right = get_theme_stylebox(SNAME("labeled_separator_right")); - - int vseparation = get_theme_constant(SNAME("v_separation")); - int hseparation = get_theme_constant(SNAME("h_separation")); - Color font_color = get_theme_color(SNAME("font_color")); - Color font_disabled_color = get_theme_color(SNAME("font_disabled_color")); - Color font_accelerator_color = get_theme_color(SNAME("font_accelerator_color")); - Color font_hover_color = get_theme_color(SNAME("font_hover_color")); - Color font_separator_color = get_theme_color(SNAME("font_separator_color")); - float scroll_width = scroll_container->get_v_scroll_bar()->is_visible_in_tree() ? scroll_container->get_v_scroll_bar()->get_size().width : 0; float display_width = control->get_size().width - scroll_width; @@ -574,7 +546,7 @@ void PopupMenu::_draw_items() { } } if (icon_ofs > 0.0) { - icon_ofs += hseparation; + icon_ofs += theme_cache.h_separation; } float check_ofs = 0.0; @@ -583,7 +555,7 @@ void PopupMenu::_draw_items() { check_ofs = MAX(check_ofs, check[i]->get_width()); check_ofs = MAX(check_ofs, uncheck[i]->get_width()); } - check_ofs += hseparation; + check_ofs += theme_cache.h_separation; } Point2 ofs = Point2(); @@ -591,7 +563,7 @@ void PopupMenu::_draw_items() { // Loop through all items and draw each. for (int i = 0; i < items.size(); i++) { // For the first item only add half a separation. For all other items, add a whole separation to the offset. - ofs.y += i > 0 ? vseparation : (float)vseparation / 2; + ofs.y += i > 0 ? theme_cache.v_separation : (float)theme_cache.v_separation / 2; _shape_item(i); @@ -601,47 +573,47 @@ void PopupMenu::_draw_items() { if (i == mouse_over) { if (rtl) { - hover->draw(ci, Rect2(item_ofs + Point2(scroll_width, -vseparation / 2), Size2(display_width, h + vseparation))); + theme_cache.hover_style->draw(ci, Rect2(item_ofs + Point2(scroll_width, -theme_cache.v_separation / 2), Size2(display_width, h + theme_cache.v_separation))); } else { - hover->draw(ci, Rect2(item_ofs + Point2(0, -vseparation / 2), Size2(display_width, h + vseparation))); + theme_cache.hover_style->draw(ci, Rect2(item_ofs + Point2(0, -theme_cache.v_separation / 2), Size2(display_width, h + theme_cache.v_separation))); } } String text = items[i].xl_text; // Separator - item_ofs.x += items[i].indent * get_theme_constant(SNAME("indent")); + item_ofs.x += items[i].indent * theme_cache.indent; if (items[i].separator) { if (!text.is_empty() || !items[i].icon.is_null()) { - int content_size = items[i].text_buf->get_size().width + hseparation * 2; + int content_size = items[i].text_buf->get_size().width + theme_cache.h_separation * 2; if (!items[i].icon.is_null()) { - content_size += icon_size.width + hseparation; + content_size += icon_size.width + theme_cache.h_separation; } int content_center = display_width / 2; int content_left = content_center - content_size / 2; int content_right = content_center + content_size / 2; if (content_left > item_ofs.x) { - int sep_h = labeled_separator_left->get_center_size().height + labeled_separator_left->get_minimum_size().height; + int sep_h = theme_cache.labeled_separator_left->get_center_size().height + theme_cache.labeled_separator_left->get_minimum_size().height; int sep_ofs = Math::floor((h - sep_h) / 2.0); - labeled_separator_left->draw(ci, Rect2(item_ofs + Point2(0, sep_ofs), Size2(MAX(0, content_left - item_ofs.x), sep_h))); + theme_cache.labeled_separator_left->draw(ci, Rect2(item_ofs + Point2(0, sep_ofs), Size2(MAX(0, content_left - item_ofs.x), sep_h))); } if (content_right < display_width) { - int sep_h = labeled_separator_right->get_center_size().height + labeled_separator_right->get_minimum_size().height; + int sep_h = theme_cache.labeled_separator_right->get_center_size().height + theme_cache.labeled_separator_right->get_minimum_size().height; int sep_ofs = Math::floor((h - sep_h) / 2.0); - labeled_separator_right->draw(ci, Rect2(Point2(content_right, item_ofs.y + sep_ofs), Size2(MAX(0, display_width - content_right), sep_h))); + theme_cache.labeled_separator_right->draw(ci, Rect2(Point2(content_right, item_ofs.y + sep_ofs), Size2(MAX(0, display_width - content_right), sep_h))); } } else { - int sep_h = separator->get_center_size().height + separator->get_minimum_size().height; + int sep_h = theme_cache.separator_style->get_center_size().height + theme_cache.separator_style->get_minimum_size().height; int sep_ofs = Math::floor((h - sep_h) / 2.0); - separator->draw(ci, Rect2(item_ofs + Point2(0, sep_ofs), Size2(display_width, sep_h))); + theme_cache.separator_style->draw(ci, Rect2(item_ofs + Point2(0, sep_ofs), Size2(display_width, sep_h))); } } Color icon_color(1, 1, 1, items[i].disabled && !items[i].separator ? 0.5 : 1); // For non-separator items, add some padding for the content. - item_ofs.x += item_start_padding; + item_ofs.x += theme_cache.item_start_padding; // Checkboxes if (items[i].checkable_type && !items[i].separator) { @@ -659,7 +631,7 @@ void PopupMenu::_draw_items() { // Icon if (!items[i].icon.is_null()) { if (items[i].separator) { - separator_ofs -= (icon_size.width + hseparation) / 2; + separator_ofs -= (icon_size.width + theme_cache.h_separation) / 2; if (rtl) { items[i].icon->draw(ci, Size2(control->get_size().width - item_ofs.x - separator_ofs - icon_size.width, item_ofs.y) + Point2(0, Math::floor((h - icon_size.height) / 2.0)), icon_color); @@ -678,61 +650,55 @@ void PopupMenu::_draw_items() { // Submenu arrow on right hand side. if (!items[i].submenu.is_empty()) { if (rtl) { - submenu->draw(ci, Point2(scroll_width + style->get_margin(SIDE_LEFT) + item_end_padding, item_ofs.y + Math::floor(h - submenu->get_height()) / 2), icon_color); + submenu->draw(ci, Point2(scroll_width + theme_cache.panel_style->get_margin(SIDE_LEFT) + theme_cache.item_end_padding, item_ofs.y + Math::floor(h - submenu->get_height()) / 2), icon_color); } else { - submenu->draw(ci, Point2(display_width - style->get_margin(SIDE_RIGHT) - submenu->get_width() - item_end_padding, item_ofs.y + Math::floor(h - submenu->get_height()) / 2), icon_color); + submenu->draw(ci, Point2(display_width - theme_cache.panel_style->get_margin(SIDE_RIGHT) - submenu->get_width() - theme_cache.item_end_padding, item_ofs.y + Math::floor(h - submenu->get_height()) / 2), icon_color); } } - Color font_outline_color = get_theme_color(SNAME("font_outline_color")); - int outline_size = get_theme_constant(SNAME("outline_size")); - // Text if (items[i].separator) { - Color font_separator_outline_color = get_theme_color(SNAME("font_separator_outline_color")); - int separator_outline_size = get_theme_constant(SNAME("separator_outline_size")); - if (!text.is_empty()) { Vector2 text_pos = Point2(separator_ofs, item_ofs.y + Math::floor((h - items[i].text_buf->get_size().y) / 2.0)); if (!rtl && !items[i].icon.is_null()) { - text_pos.x += icon_size.width + hseparation; + text_pos.x += icon_size.width + theme_cache.h_separation; } - if (separator_outline_size > 0 && font_separator_outline_color.a > 0) { - items[i].text_buf->draw_outline(ci, text_pos, separator_outline_size, font_separator_outline_color); + if (theme_cache.font_separator_outline_size > 0 && theme_cache.font_separator_outline_color.a > 0) { + items[i].text_buf->draw_outline(ci, text_pos, theme_cache.font_separator_outline_size, theme_cache.font_separator_outline_color); } - items[i].text_buf->draw(ci, text_pos, font_separator_color); + items[i].text_buf->draw(ci, text_pos, theme_cache.font_separator_color); } } else { item_ofs.x += icon_ofs + check_ofs; if (rtl) { Vector2 text_pos = Size2(control->get_size().width - items[i].text_buf->get_size().width - item_ofs.x, item_ofs.y) + Point2(0, Math::floor((h - items[i].text_buf->get_size().y) / 2.0)); - if (outline_size > 0 && font_outline_color.a > 0) { - items[i].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color); + if (theme_cache.font_outline_size > 0 && theme_cache.font_outline_color.a > 0) { + items[i].text_buf->draw_outline(ci, text_pos, theme_cache.font_outline_size, theme_cache.font_outline_color); } - items[i].text_buf->draw(ci, text_pos, items[i].disabled ? font_disabled_color : (i == mouse_over ? font_hover_color : font_color)); + items[i].text_buf->draw(ci, text_pos, items[i].disabled ? theme_cache.font_disabled_color : (i == mouse_over ? theme_cache.font_hover_color : theme_cache.font_color)); } else { Vector2 text_pos = item_ofs + Point2(0, Math::floor((h - items[i].text_buf->get_size().y) / 2.0)); - if (outline_size > 0 && font_outline_color.a > 0) { - items[i].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color); + if (theme_cache.font_outline_size > 0 && theme_cache.font_outline_color.a > 0) { + items[i].text_buf->draw_outline(ci, text_pos, theme_cache.font_outline_size, theme_cache.font_outline_color); } - items[i].text_buf->draw(ci, text_pos, items[i].disabled ? font_disabled_color : (i == mouse_over ? font_hover_color : font_color)); + items[i].text_buf->draw(ci, text_pos, items[i].disabled ? theme_cache.font_disabled_color : (i == mouse_over ? theme_cache.font_hover_color : theme_cache.font_color)); } } // Accelerator / Shortcut if (items[i].accel != Key::NONE || (items[i].shortcut.is_valid() && items[i].shortcut->has_valid_event())) { if (rtl) { - item_ofs.x = scroll_width + style->get_margin(SIDE_LEFT) + item_end_padding; + item_ofs.x = scroll_width + theme_cache.panel_style->get_margin(SIDE_LEFT) + theme_cache.item_end_padding; } else { - item_ofs.x = display_width - style->get_margin(SIDE_RIGHT) - items[i].accel_text_buf->get_size().x - item_end_padding; + item_ofs.x = display_width - theme_cache.panel_style->get_margin(SIDE_RIGHT) - items[i].accel_text_buf->get_size().x - theme_cache.item_end_padding; } Vector2 text_pos = item_ofs + Point2(0, Math::floor((h - items[i].text_buf->get_size().y) / 2.0)); - if (outline_size > 0 && font_outline_color.a > 0) { - items[i].accel_text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color); + if (theme_cache.font_outline_size > 0 && theme_cache.font_outline_color.a > 0) { + items[i].accel_text_buf->draw_outline(ci, text_pos, theme_cache.font_outline_size, theme_cache.font_outline_color); } - items[i].accel_text_buf->draw(ci, text_pos, i == mouse_over ? font_hover_color : font_accelerator_color); + items[i].accel_text_buf->draw(ci, text_pos, i == mouse_over ? theme_cache.font_hover_color : theme_cache.font_accelerator_color); } // Cache the item vertical offset from the first item and the height. @@ -744,9 +710,8 @@ void PopupMenu::_draw_items() { } void PopupMenu::_draw_background() { - Ref<StyleBox> style = get_theme_stylebox(SNAME("panel")); RID ci2 = margin_container->get_canvas_item(); - style->draw(ci2, Rect2(Point2(), margin_container->get_size())); + theme_cache.panel_style->draw(ci2, Rect2(Point2(), margin_container->get_size())); } void PopupMenu::_minimum_lifetime_timeout() { @@ -778,8 +743,8 @@ void PopupMenu::_shape_item(int p_item) { if (items.write[p_item].dirty) { items.write[p_item].text_buf->clear(); - Ref<Font> font = get_theme_font(items[p_item].separator ? SNAME("font_separator") : SNAME("font")); - int font_size = get_theme_font_size(items[p_item].separator ? SNAME("font_separator_size") : SNAME("font_size")); + Ref<Font> font = items[p_item].separator ? theme_cache.font_separator : theme_cache.font; + int font_size = items[p_item].separator ? theme_cache.font_separator_size : theme_cache.font_size; if (items[p_item].text_direction == Control::TEXT_DIRECTION_INHERITED) { items.write[p_item].text_buf->set_direction(is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR); @@ -821,6 +786,51 @@ void PopupMenu::remove_child_notify(Node *p_child) { _menu_changed(); } +void PopupMenu::_update_theme_item_cache() { + Popup::_update_theme_item_cache(); + + theme_cache.panel_style = get_theme_stylebox(SNAME("panel")); + theme_cache.hover_style = get_theme_stylebox(SNAME("hover")); + + theme_cache.separator_style = get_theme_stylebox(SNAME("separator")); + theme_cache.labeled_separator_left = get_theme_stylebox(SNAME("labeled_separator_left")); + theme_cache.labeled_separator_right = get_theme_stylebox(SNAME("labeled_separator_right")); + + theme_cache.v_separation = get_theme_constant(SNAME("v_separation")); + theme_cache.h_separation = get_theme_constant(SNAME("h_separation")); + theme_cache.indent = get_theme_constant(SNAME("indent")); + theme_cache.item_start_padding = get_theme_constant(SNAME("item_start_padding")); + theme_cache.item_end_padding = get_theme_constant(SNAME("item_end_padding")); + + theme_cache.checked = get_theme_icon(SNAME("checked")); + theme_cache.checked_disabled = get_theme_icon(SNAME("checked_disabled")); + theme_cache.unchecked = get_theme_icon(SNAME("unchecked")); + theme_cache.unchecked_disabled = get_theme_icon(SNAME("unchecked_disabled")); + theme_cache.radio_checked = get_theme_icon(SNAME("radio_checked")); + theme_cache.radio_checked_disabled = get_theme_icon(SNAME("radio_checked_disabled")); + theme_cache.radio_unchecked = get_theme_icon(SNAME("radio_unchecked")); + theme_cache.radio_unchecked_disabled = get_theme_icon(SNAME("radio_unchecked_disabled")); + + theme_cache.submenu = get_theme_icon(SNAME("submenu")); + theme_cache.submenu_mirrored = get_theme_icon(SNAME("submenu_mirrored")); + + theme_cache.font = get_theme_font(SNAME("font")); + theme_cache.font_size = get_theme_font_size(SNAME("font_size")); + theme_cache.font_separator = get_theme_font(SNAME("font_separator")); + theme_cache.font_separator_size = get_theme_font_size(SNAME("font_separator_size")); + + theme_cache.font_color = get_theme_color(SNAME("font_color")); + theme_cache.font_hover_color = get_theme_color(SNAME("font_hover_color")); + theme_cache.font_disabled_color = get_theme_color(SNAME("font_disabled_color")); + theme_cache.font_accelerator_color = get_theme_color(SNAME("font_accelerator_color")); + theme_cache.font_outline_size = get_theme_constant(SNAME("outline_size")); + theme_cache.font_outline_color = get_theme_color(SNAME("font_outline_color")); + + theme_cache.font_separator_color = get_theme_color(SNAME("font_separator_color")); + theme_cache.font_separator_outline_size = get_theme_constant(SNAME("separator_outline_size")); + theme_cache.font_separator_outline_color = get_theme_color(SNAME("font_separator_outline_color")); +} + void PopupMenu::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { @@ -909,11 +919,10 @@ void PopupMenu::_notification(int p_what) { } // Set margin on the margin container - Ref<StyleBox> panel_style = get_theme_stylebox(SNAME("panel")); - margin_container->add_theme_constant_override("margin_left", panel_style->get_margin(Side::SIDE_LEFT)); - margin_container->add_theme_constant_override("margin_top", panel_style->get_margin(Side::SIDE_TOP)); - margin_container->add_theme_constant_override("margin_right", panel_style->get_margin(Side::SIDE_RIGHT)); - margin_container->add_theme_constant_override("margin_bottom", panel_style->get_margin(Side::SIDE_BOTTOM)); + margin_container->add_theme_constant_override("margin_left", theme_cache.panel_style->get_margin(Side::SIDE_LEFT)); + margin_container->add_theme_constant_override("margin_top", theme_cache.panel_style->get_margin(Side::SIDE_TOP)); + margin_container->add_theme_constant_override("margin_right", theme_cache.panel_style->get_margin(Side::SIDE_RIGHT)); + margin_container->add_theme_constant_override("margin_bottom", theme_cache.panel_style->get_margin(Side::SIDE_BOTTOM)); } } break; } diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h index d3ad0762e4..c8c598bd50 100644 --- a/scene/gui/popup_menu.h +++ b/scene/gui/popup_menu.h @@ -129,6 +129,49 @@ class PopupMenu : public Popup { ScrollContainer *scroll_container = nullptr; Control *control = nullptr; + struct ThemeCache { + Ref<StyleBox> panel_style; + Ref<StyleBox> hover_style; + + Ref<StyleBox> separator_style; + Ref<StyleBox> labeled_separator_left; + Ref<StyleBox> labeled_separator_right; + + int v_separation = 0; + int h_separation = 0; + int indent = 0; + int item_start_padding = 0; + int item_end_padding = 0; + + Ref<Texture2D> checked; + Ref<Texture2D> checked_disabled; + Ref<Texture2D> unchecked; + Ref<Texture2D> unchecked_disabled; + Ref<Texture2D> radio_checked; + Ref<Texture2D> radio_checked_disabled; + Ref<Texture2D> radio_unchecked; + Ref<Texture2D> radio_unchecked_disabled; + + Ref<Texture2D> submenu; + Ref<Texture2D> submenu_mirrored; + + Ref<Font> font; + int font_size = 0; + Ref<Font> font_separator; + int font_separator_size = 0; + + Color font_color; + Color font_hover_color; + Color font_disabled_color; + Color font_accelerator_color; + int font_outline_size = 0; + Color font_outline_color; + + Color font_separator_color; + int font_separator_outline_size = 0; + Color font_separator_outline_color; + } theme_cache; + void _draw_items(); void _draw_background(); @@ -137,6 +180,8 @@ class PopupMenu : public Popup { void _menu_changed(); protected: + virtual void _update_theme_item_cache() override; + virtual void add_child_notify(Node *p_child) override; virtual void remove_child_notify(Node *p_child) override; void _notification(int p_what); diff --git a/scene/gui/progress_bar.cpp b/scene/gui/progress_bar.cpp index 63a2db4569..fe609dd834 100644 --- a/scene/gui/progress_bar.cpp +++ b/scene/gui/progress_bar.cpp @@ -33,18 +33,13 @@ #include "scene/resources/text_line.h" Size2 ProgressBar::get_minimum_size() const { - Ref<StyleBox> bg = get_theme_stylebox(SNAME("bg")); - Ref<StyleBox> fg = get_theme_stylebox(SNAME("fg")); - Ref<Font> font = get_theme_font(SNAME("font")); - int font_size = get_theme_font_size(SNAME("font_size")); - - Size2 minimum_size = bg->get_minimum_size(); - minimum_size.height = MAX(minimum_size.height, fg->get_minimum_size().height); - minimum_size.width = MAX(minimum_size.width, fg->get_minimum_size().width); + Size2 minimum_size = theme_cache.bg_style->get_minimum_size(); + minimum_size.height = MAX(minimum_size.height, theme_cache.fg_style->get_minimum_size().height); + minimum_size.width = MAX(minimum_size.width, theme_cache.fg_style->get_minimum_size().width); if (percent_visible) { String txt = "100%"; - TextLine tl = TextLine(txt, font, font_size); - minimum_size.height = MAX(minimum_size.height, bg->get_minimum_size().height + tl.get_size().y); + TextLine tl = TextLine(txt, theme_cache.font, theme_cache.font_size); + minimum_size.height = MAX(minimum_size.height, theme_cache.bg_style->get_minimum_size().height + tl.get_size().y); } else { // this is needed, else the progressbar will collapse minimum_size.width = MAX(minimum_size.width, 1); minimum_size.height = MAX(minimum_size.height, 1); @@ -52,23 +47,30 @@ Size2 ProgressBar::get_minimum_size() const { return minimum_size; } +void ProgressBar::_update_theme_item_cache() { + Range::_update_theme_item_cache(); + + theme_cache.bg_style = get_theme_stylebox(SNAME("bg")); + theme_cache.fg_style = get_theme_stylebox(SNAME("fg")); + + theme_cache.font = get_theme_font(SNAME("font")); + theme_cache.font_size = get_theme_font_size(SNAME("font_size")); + theme_cache.font_color = get_theme_color(SNAME("font_color")); + theme_cache.font_outline_size = get_theme_constant(SNAME("outline_size")); + theme_cache.font_outline_color = get_theme_color(SNAME("font_outline_color")); +} + void ProgressBar::_notification(int p_what) { switch (p_what) { case NOTIFICATION_DRAW: { - Ref<StyleBox> bg = get_theme_stylebox(SNAME("bg")); - Ref<StyleBox> fg = get_theme_stylebox(SNAME("fg")); - Ref<Font> font = get_theme_font(SNAME("font")); - int font_size = get_theme_font_size(SNAME("font_size")); - Color font_color = get_theme_color(SNAME("font_color")); - - draw_style_box(bg, Rect2(Point2(), get_size())); + draw_style_box(theme_cache.bg_style, Rect2(Point2(), get_size())); float r = get_as_ratio(); switch (mode) { case FILL_BEGIN_TO_END: case FILL_END_TO_BEGIN: { - int mp = fg->get_minimum_size().width; + int mp = theme_cache.fg_style->get_minimum_size().width; int p = round(r * (get_size().width - mp)); // We want FILL_BEGIN_TO_END to map to right to left when UI layout is RTL, // and left to right otherwise. And likewise for FILL_END_TO_BEGIN. @@ -76,23 +78,23 @@ void ProgressBar::_notification(int p_what) { if (p > 0) { if (right_to_left) { int p_remaining = round((1.0 - r) * (get_size().width - mp)); - draw_style_box(fg, Rect2(Point2(p_remaining, 0), Size2(p + fg->get_minimum_size().width, get_size().height))); + draw_style_box(theme_cache.fg_style, Rect2(Point2(p_remaining, 0), Size2(p + theme_cache.fg_style->get_minimum_size().width, get_size().height))); } else { - draw_style_box(fg, Rect2(Point2(0, 0), Size2(p + fg->get_minimum_size().width, get_size().height))); + draw_style_box(theme_cache.fg_style, Rect2(Point2(0, 0), Size2(p + theme_cache.fg_style->get_minimum_size().width, get_size().height))); } } } break; case FILL_TOP_TO_BOTTOM: case FILL_BOTTOM_TO_TOP: { - int mp = fg->get_minimum_size().height; + int mp = theme_cache.fg_style->get_minimum_size().height; int p = round(r * (get_size().height - mp)); if (p > 0) { if (mode == FILL_TOP_TO_BOTTOM) { - draw_style_box(fg, Rect2(Point2(0, 0), Size2(get_size().width, p + fg->get_minimum_size().height))); + draw_style_box(theme_cache.fg_style, Rect2(Point2(0, 0), Size2(get_size().width, p + theme_cache.fg_style->get_minimum_size().height))); } else { int p_remaining = round((1.0 - r) * (get_size().height - mp)); - draw_style_box(fg, Rect2(Point2(0, p_remaining), Size2(get_size().width, p + fg->get_minimum_size().height))); + draw_style_box(theme_cache.fg_style, Rect2(Point2(0, p_remaining), Size2(get_size().width, p + theme_cache.fg_style->get_minimum_size().height))); } } } break; @@ -102,14 +104,14 @@ void ProgressBar::_notification(int p_what) { if (percent_visible) { String txt = TS->format_number(itos(int(get_as_ratio() * 100))) + TS->percent_sign(); - TextLine tl = TextLine(txt, font, font_size); + TextLine tl = TextLine(txt, theme_cache.font, theme_cache.font_size); Vector2 text_pos = (Point2(get_size().width - tl.get_size().x, get_size().height - tl.get_size().y) / 2).round(); - Color font_outline_color = get_theme_color(SNAME("font_outline_color")); - int outline_size = get_theme_constant(SNAME("outline_size")); - if (outline_size > 0 && font_outline_color.a > 0) { - tl.draw_outline(get_canvas_item(), text_pos, outline_size, font_outline_color); + + if (theme_cache.font_outline_size > 0 && theme_cache.font_outline_color.a > 0) { + tl.draw_outline(get_canvas_item(), text_pos, theme_cache.font_outline_size, theme_cache.font_outline_color); } - tl.draw(get_canvas_item(), text_pos, font_color); + + tl.draw(get_canvas_item(), text_pos, theme_cache.font_color); } } break; } diff --git a/scene/gui/progress_bar.h b/scene/gui/progress_bar.h index 5ba21ad7d5..c79b901928 100644 --- a/scene/gui/progress_bar.h +++ b/scene/gui/progress_bar.h @@ -38,7 +38,20 @@ class ProgressBar : public Range { bool percent_visible = true; + struct ThemeCache { + Ref<StyleBox> bg_style; + Ref<StyleBox> fg_style; + + Ref<Font> font; + int font_size = 0; + Color font_color; + int font_outline_size = 0; + Color font_outline_color; + } theme_cache; + protected: + virtual void _update_theme_item_cache() override; + void _notification(int p_what); static void _bind_methods(); diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index c5fe218a15..99cad80cde 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -134,8 +134,7 @@ RichTextLabel::Item *RichTextLabel::_get_prev_item(Item *p_item, bool p_free) co } Rect2 RichTextLabel::_get_text_rect() { - Ref<StyleBox> style = get_theme_stylebox(SNAME("normal")); - return Rect2(style->get_offset(), get_size() - style->get_minimum_size()); + return Rect2(theme_cache.normal_style->get_offset(), get_size() - theme_cache.normal_style->get_minimum_size()); } RichTextLabel::Item *RichTextLabel::_get_item_at_pos(RichTextLabel::Item *p_item_from, RichTextLabel::Item *p_item_to, int p_position) { @@ -287,8 +286,6 @@ float RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font switch (it->type) { case ITEM_TABLE: { ItemTable *table = static_cast<ItemTable *>(it); - int hseparation = get_theme_constant(SNAME("table_h_separation")); - int vseparation = get_theme_constant(SNAME("table_v_separation")); int col_count = table->columns.size(); for (int i = 0; i < col_count; i++) { @@ -309,12 +306,12 @@ float RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font } // Compute minimum width for each cell. - const int available_width = p_width - hseparation * (col_count - 1); + const int available_width = p_width - theme_cache.table_h_separation * (col_count - 1); // Compute available width and total ratio (for expanders). int total_ratio = 0; int remaining_width = available_width; - table->total_width = hseparation; + table->total_width = theme_cache.table_h_separation; for (int i = 0; i < col_count; i++) { remaining_width -= table->columns[i].min_width; @@ -332,7 +329,7 @@ float RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font if (table->columns[i].expand && total_ratio > 0 && remaining_width > 0) { table->columns[i].width += table->columns[i].expand_ratio * remaining_width / total_ratio; } - table->total_width += table->columns[i].width + hseparation; + table->total_width += table->columns[i].width + theme_cache.table_h_separation; } // Resize to max_width if needed and distribute the remaining space. @@ -394,9 +391,9 @@ float RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font frame->lines[i].offset.y = prev_h; frame->lines[i].offset += offset; - float h = frame->lines[i].text_buf->get_size().y + (frame->lines[i].text_buf->get_line_count() - 1) * get_theme_constant(SNAME("line_separation")); + float h = frame->lines[i].text_buf->get_size().y + (frame->lines[i].text_buf->get_line_count() - 1) * theme_cache.line_separation; if (i > 0) { - h += get_theme_constant(SNAME("line_separation")); + h += theme_cache.line_separation; } if (frame->min_size_over.y > 0) { h = MAX(h, frame->min_size_over.y); @@ -405,15 +402,15 @@ float RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font h = MIN(h, frame->max_size_over.y); } yofs += h; - prev_h = frame->lines[i].offset.y + frame->lines[i].text_buf->get_size().y + frame->lines[i].text_buf->get_line_count() * get_theme_constant(SNAME("line_separation")); + prev_h = frame->lines[i].offset.y + frame->lines[i].text_buf->get_size().y + frame->lines[i].text_buf->get_line_count() * theme_cache.line_separation; } yofs += frame->padding.size.y; - offset.x += table->columns[column].width + hseparation + frame->padding.size.x; + offset.x += table->columns[column].width + theme_cache.table_h_separation + frame->padding.size.x; row_height = MAX(yofs, row_height); if (column == col_count - 1) { offset.x = 0; - row_height += vseparation; + row_height += theme_cache.table_v_separation; table->total_height += row_height; offset.y += row_height; table->rows.push_back(row_height); @@ -551,8 +548,6 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> } break; case ITEM_TABLE: { ItemTable *table = static_cast<ItemTable *>(it); - int hseparation = get_theme_constant(SNAME("table_h_separation")); - int vseparation = get_theme_constant(SNAME("table_v_separation")); int col_count = table->columns.size(); int t_char_count = 0; // Set minimums to zero. @@ -562,7 +557,7 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> table->columns[i].width = 0; } // Compute minimum width for each cell. - const int available_width = p_width - hseparation * (col_count - 1); + const int available_width = p_width - theme_cache.table_h_separation * (col_count - 1); int idx = 0; for (Item *E : table->subitems) { @@ -591,7 +586,7 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> // Compute available width and total ratio (for expanders). int total_ratio = 0; int remaining_width = available_width; - table->total_width = hseparation; + table->total_width = theme_cache.table_h_separation; for (int i = 0; i < col_count; i++) { remaining_width -= table->columns[i].min_width; @@ -609,7 +604,7 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> if (table->columns[i].expand && total_ratio > 0 && remaining_width > 0) { table->columns[i].width += table->columns[i].expand_ratio * remaining_width / total_ratio; } - table->total_width += table->columns[i].width + hseparation; + table->total_width += table->columns[i].width + theme_cache.table_h_separation; } // Resize to max_width if needed and distribute the remaining space. @@ -672,9 +667,9 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> frame->lines[i].offset.y = prev_h; frame->lines[i].offset += offset; - float h = frame->lines[i].text_buf->get_size().y + (frame->lines[i].text_buf->get_line_count() - 1) * get_theme_constant(SNAME("line_separation")); + float h = frame->lines[i].text_buf->get_size().y + (frame->lines[i].text_buf->get_line_count() - 1) * theme_cache.line_separation; if (i > 0) { - h += get_theme_constant(SNAME("line_separation")); + h += theme_cache.line_separation; } if (frame->min_size_over.y > 0) { h = MAX(h, frame->min_size_over.y); @@ -683,16 +678,16 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> h = MIN(h, frame->max_size_over.y); } yofs += h; - prev_h = frame->lines[i].offset.y + frame->lines[i].text_buf->get_size().y + frame->lines[i].text_buf->get_line_count() * get_theme_constant(SNAME("line_separation")); + prev_h = frame->lines[i].offset.y + frame->lines[i].text_buf->get_size().y + frame->lines[i].text_buf->get_line_count() * theme_cache.line_separation; } yofs += frame->padding.size.y; - offset.x += table->columns[column].width + hseparation + frame->padding.size.x; + offset.x += table->columns[column].width + theme_cache.table_h_separation + frame->padding.size.x; row_height = MAX(yofs, row_height); // Add row height after last column of the row or last cell of the table. if (column == col_count - 1 || E->next() == nullptr) { offset.x = 0; - row_height += vseparation; + row_height += theme_cache.table_v_separation; table->total_height += row_height; offset.y += row_height; table->rows.push_back(row_height); @@ -723,7 +718,6 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o ERR_FAIL_COND_V(p_line < 0 || p_line >= (int)p_frame->lines.size(), 0); Vector2 off; - int line_spacing = get_theme_constant(SNAME("line_separation")); Line &l = p_frame->lines[p_line]; MutexLock lock(l.text_buf->get_mutex()); @@ -775,8 +769,8 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o } } if (!prefix.is_empty()) { - Ref<Font> font = get_theme_font(SNAME("normal_font")); - int font_size = get_theme_font_size(SNAME("normal_font_size")); + Ref<Font> font = theme_cache.normal_font; + int font_size = theme_cache.normal_font_size; ItemFont *font_it = _find_font(l.from); if (font_it) { @@ -819,7 +813,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o // Draw text. for (int line = 0; line < l.text_buf->get_line_count(); line++) { if (line > 0) { - off.y += line_spacing; + off.y += theme_cache.line_separation; } if (p_ofs.y + off.y >= ctrl_size.height) { @@ -894,10 +888,11 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o } break; case ITEM_TABLE: { ItemTable *table = static_cast<ItemTable *>(it); - Color odd_row_bg = get_theme_color(SNAME("table_odd_row_bg")); - Color even_row_bg = get_theme_color(SNAME("table_even_row_bg")); - Color border = get_theme_color(SNAME("table_border")); - int hseparation = get_theme_constant(SNAME("table_h_separation")); + Color odd_row_bg = theme_cache.table_odd_row_bg; + Color even_row_bg = theme_cache.table_even_row_bg; + Color border = theme_cache.table_border; + int hseparation = theme_cache.table_h_separation; + int col_count = table->columns.size(); int row_count = table->rows.size(); @@ -1093,8 +1088,8 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o _draw_fbg_boxes(ci, rid, fbg_line_off, it_from, it_to, chr_range.x, chr_range.y, 0); // Draw main text. - Color selection_fg = get_theme_color(SNAME("font_selected_color")); - Color selection_bg = get_theme_color(SNAME("selection_color")); + Color selection_fg = theme_cache.font_selected_color; + Color selection_bg = theme_cache.selection_color; int sel_start = -1; int sel_end = -1; @@ -1136,7 +1131,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o } else if (ul_started) { ul_started = false; float y_off = TS->shaped_text_get_underline_position(rid); - float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale(); + float underline_width = TS->shaped_text_get_underline_thickness(rid) * theme_cache.base_scale; draw_line(ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), ul_color, underline_width); } if (_find_hint(it, nullptr) && underline_hint) { @@ -1149,7 +1144,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o } else if (dot_ul_started) { dot_ul_started = false; float y_off = TS->shaped_text_get_underline_position(rid); - float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale(); + float underline_width = TS->shaped_text_get_underline_thickness(rid) * theme_cache.base_scale; draw_dashed_line(dot_ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), dot_ul_color, underline_width, underline_width * 2); } if (_find_strikethrough(it)) { @@ -1162,7 +1157,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o } else if (st_started) { st_started = false; float y_off = -TS->shaped_text_get_ascent(rid) + TS->shaped_text_get_size(rid).y / 2; - float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale(); + float underline_width = TS->shaped_text_get_underline_thickness(rid) * theme_cache.base_scale; draw_line(st_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), st_color, underline_width); } @@ -1301,19 +1296,19 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o if (ul_started) { ul_started = false; float y_off = TS->shaped_text_get_underline_position(rid); - float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale(); + float underline_width = TS->shaped_text_get_underline_thickness(rid) * theme_cache.base_scale; draw_line(ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), ul_color, underline_width); } if (dot_ul_started) { dot_ul_started = false; float y_off = TS->shaped_text_get_underline_position(rid); - float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale(); + float underline_width = TS->shaped_text_get_underline_thickness(rid) * theme_cache.base_scale; draw_dashed_line(dot_ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), dot_ul_color, underline_width, underline_width * 2); } if (st_started) { st_started = false; float y_off = -TS->shaped_text_get_ascent(rid) + TS->shaped_text_get_size(rid).y / 2; - float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale(); + float underline_width = TS->shaped_text_get_underline_thickness(rid) * theme_cache.base_scale; draw_line(st_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), st_color, underline_width); } } @@ -1323,19 +1318,19 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o if (ul_started) { ul_started = false; float y_off = TS->shaped_text_get_underline_position(rid); - float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale(); + float underline_width = TS->shaped_text_get_underline_thickness(rid) * theme_cache.base_scale; draw_line(ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), ul_color, underline_width); } if (dot_ul_started) { dot_ul_started = false; float y_off = TS->shaped_text_get_underline_position(rid); - float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale(); + float underline_width = TS->shaped_text_get_underline_thickness(rid) * theme_cache.base_scale; draw_dashed_line(dot_ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), dot_ul_color, underline_width, underline_width * 2); } if (st_started) { st_started = false; float y_off = -TS->shaped_text_get_ascent(rid) + TS->shaped_text_get_size(rid).y / 2; - float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale(); + float underline_width = TS->shaped_text_get_underline_thickness(rid) * theme_cache.base_scale; draw_line(st_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), st_color, underline_width); } // Draw foreground color box @@ -1371,7 +1366,7 @@ void RichTextLabel::_find_click(ItemFrame *p_frame, const Point2i &p_click, Item while (ofs.y < size.height && from_line < to_line) { MutexLock lock(main->lines[from_line].text_buf->get_mutex()); _find_click_in_line(p_frame, from_line, ofs, text_rect.size.x, p_click, r_click_frame, r_click_line, r_click_item, r_click_char, false, p_meta); - ofs.y += main->lines[from_line].text_buf->get_size().y + main->lines[from_line].text_buf->get_line_count() * get_theme_constant(SNAME("line_separation")); + ofs.y += main->lines[from_line].text_buf->get_size().y + main->lines[from_line].text_buf->get_line_count() * theme_cache.line_separation; if (((r_click_item != nullptr) && ((*r_click_item) != nullptr)) || ((r_click_frame != nullptr) && ((*r_click_frame) != nullptr))) { if (r_outside != nullptr) { *r_outside = false; @@ -1449,9 +1444,6 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V if (p_click.y >= rect.position.y && p_click.y <= rect.position.y + rect.size.y) { switch (it->type) { case ITEM_TABLE: { - int hseparation = get_theme_constant(SNAME("table_h_separation")); - int vseparation = get_theme_constant(SNAME("table_v_separation")); - ItemTable *table = static_cast<ItemTable *>(it); int idx = 0; @@ -1469,7 +1461,7 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V if (rtl) { coff.x = rect.size.width - table->columns[col].width - coff.x; } - Rect2 crect = Rect2(rect.position + coff - frame->padding.position, Size2(table->columns[col].width + hseparation, table->rows[row] + vseparation) + frame->padding.position + frame->padding.size); + Rect2 crect = Rect2(rect.position + coff - frame->padding.position, Size2(table->columns[col].width + theme_cache.table_h_separation, table->rows[row] + theme_cache.table_v_separation) + frame->padding.position + frame->padding.size); if (col == col_count - 1) { if (rtl) { crect.size.x = crect.position.x + crect.size.x; @@ -1508,7 +1500,7 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V } Rect2 rect = Rect2(p_ofs + off - Vector2(0, TS->shaped_text_get_ascent(rid)) - p_frame->padding.position, TS->shaped_text_get_size(rid) + p_frame->padding.position + p_frame->padding.size); if (p_table) { - rect.size.y += get_theme_constant(SNAME("table_v_separation")); + rect.size.y += theme_cache.table_v_separation; } if (p_click.y >= rect.position.y && p_click.y <= rect.position.y + rect.size.y) { @@ -1547,7 +1539,7 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V return table_offy; } - off.y += TS->shaped_text_get_descent(rid) + get_theme_constant(SNAME("line_separation")); + off.y += TS->shaped_text_get_descent(rid) + theme_cache.line_separation; } // Text line hit. @@ -1562,8 +1554,8 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V int stop = text_rect_begin; *r_click_item = _find_indentable(it); while (*r_click_item) { - Ref<Font> font = get_theme_font(SNAME("normal_font")); - int font_size = get_theme_font_size(SNAME("normal_font_size")); + Ref<Font> font = theme_cache.normal_font; + int font_size = theme_cache.normal_font_size; ItemFont *font_it = _find_font(*r_click_item); if (font_it) { if (font_it->font.is_valid()) { @@ -1676,7 +1668,49 @@ int RichTextLabel::_find_first_line(int p_from, int p_to, int p_vofs) const { } _FORCE_INLINE_ float RichTextLabel::_calculate_line_vertical_offset(const RichTextLabel::Line &line) const { - return line.get_height(get_theme_constant(SNAME("line_separation"))); + return line.get_height(theme_cache.line_separation); +} + +void RichTextLabel::_update_theme_item_cache() { + Control::_update_theme_item_cache(); + + theme_cache.normal_style = get_theme_stylebox(SNAME("normal")); + theme_cache.focus_style = get_theme_stylebox(SNAME("focus")); + theme_cache.progress_bg_style = get_theme_stylebox(SNAME("bg"), SNAME("ProgressBar")); + theme_cache.progress_fg_style = get_theme_stylebox(SNAME("fg"), SNAME("ProgressBar")); + + theme_cache.line_separation = get_theme_constant(SNAME("line_separation")); + + theme_cache.normal_font = get_theme_font(SNAME("normal_font")); + theme_cache.normal_font_size = get_theme_font_size(SNAME("normal_font_size")); + + theme_cache.default_color = get_theme_color(SNAME("default_color")); + theme_cache.font_selected_color = get_theme_color(SNAME("font_selected_color")); + theme_cache.selection_color = get_theme_color(SNAME("selection_color")); + theme_cache.font_outline_color = get_theme_color(SNAME("font_outline_color")); + theme_cache.font_shadow_color = get_theme_color(SNAME("font_shadow_color")); + theme_cache.shadow_outline_size = get_theme_constant(SNAME("shadow_outline_size")); + theme_cache.shadow_offset_x = get_theme_constant(SNAME("shadow_offset_x")); + theme_cache.shadow_offset_y = get_theme_constant(SNAME("shadow_offset_y")); + theme_cache.outline_size = get_theme_constant(SNAME("outline_size")); + theme_cache.outline_color = get_theme_color(SNAME("outline_color")); + + theme_cache.bold_font = get_theme_font(SNAME("bold_font")); + theme_cache.bold_font_size = get_theme_font_size(SNAME("bold_font_size")); + theme_cache.bold_italics_font = get_theme_font(SNAME("bold_italics_font")); + theme_cache.bold_italics_font_size = get_theme_font_size(SNAME("bold_italics_font_size")); + theme_cache.italics_font = get_theme_font(SNAME("italics_font")); + theme_cache.italics_font_size = get_theme_font_size(SNAME("italics_font_size")); + theme_cache.mono_font = get_theme_font(SNAME("mono_font")); + theme_cache.mono_font_size = get_theme_font_size(SNAME("mono_font_size")); + + theme_cache.table_h_separation = get_theme_constant(SNAME("table_h_separation")); + theme_cache.table_v_separation = get_theme_constant(SNAME("table_v_separation")); + theme_cache.table_odd_row_bg = get_theme_color(SNAME("table_odd_row_bg")); + theme_cache.table_even_row_bg = get_theme_color(SNAME("table_even_row_bg")); + theme_cache.table_border = get_theme_color(SNAME("table_border")); + + theme_cache.base_scale = get_theme_default_base_scale(); } void RichTextLabel::_notification(int p_what) { @@ -1732,11 +1766,11 @@ void RichTextLabel::_notification(int p_what) { RID ci = get_canvas_item(); Size2 size = get_size(); - draw_style_box(get_theme_stylebox(SNAME("normal")), Rect2(Point2(), size)); + draw_style_box(theme_cache.normal_style, Rect2(Point2(), size)); if (has_focus()) { RenderingServer::get_singleton()->canvas_item_add_clip_ignore(ci, true); - draw_style_box(get_theme_stylebox(SNAME("focus")), Rect2(Point2(), size)); + draw_style_box(theme_cache.focus_style, Rect2(Point2(), size)); RenderingServer::get_singleton()->canvas_item_add_clip_ignore(ci, false); } @@ -1746,24 +1780,20 @@ void RichTextLabel::_notification(int p_what) { } else { // Draw loading progress bar. if ((progress_delay > 0) && (OS::get_singleton()->get_ticks_msec() - loading_started >= (uint64_t)progress_delay)) { - Ref<StyleBox> bg = get_theme_stylebox(SNAME("bg"), SNAME("ProgressBar")); - Ref<StyleBox> fg = get_theme_stylebox(SNAME("fg"), SNAME("ProgressBar")); - Ref<StyleBox> style = get_theme_stylebox(SNAME("normal")); - - Vector2 p_size = Vector2(size.width - (style->get_offset().x + vscroll->get_combined_minimum_size().width) * 2, vscroll->get_combined_minimum_size().width); - Vector2 p_pos = Vector2(style->get_offset().x, size.height - style->get_offset().y - vscroll->get_combined_minimum_size().width); + Vector2 p_size = Vector2(size.width - (theme_cache.normal_style->get_offset().x + vscroll->get_combined_minimum_size().width) * 2, vscroll->get_combined_minimum_size().width); + Vector2 p_pos = Vector2(theme_cache.normal_style->get_offset().x, size.height - theme_cache.normal_style->get_offset().y - vscroll->get_combined_minimum_size().width); - draw_style_box(bg, Rect2(p_pos, p_size)); + draw_style_box(theme_cache.progress_bg_style, Rect2(p_pos, p_size)); bool right_to_left = is_layout_rtl(); double r = loaded.load(); - int mp = fg->get_minimum_size().width; + int mp = theme_cache.progress_fg_style->get_minimum_size().width; int p = round(r * (p_size.width - mp)); if (right_to_left) { int p_remaining = round((1.0 - r) * (p_size.width - mp)); - draw_style_box(fg, Rect2(p_pos + Point2(p_remaining, 0), Size2(p + fg->get_minimum_size().width, p_size.height))); + draw_style_box(theme_cache.progress_fg_style, Rect2(p_pos + Point2(p_remaining, 0), Size2(p + theme_cache.progress_fg_style->get_minimum_size().width, p_size.height))); } else { - draw_style_box(fg, Rect2(p_pos, Size2(p + fg->get_minimum_size().width, p_size.height))); + draw_style_box(theme_cache.progress_fg_style, Rect2(p_pos, Size2(p + theme_cache.progress_fg_style->get_minimum_size().width, p_size.height))); } } } @@ -1776,13 +1806,7 @@ void RichTextLabel::_notification(int p_what) { int to_line = main->first_invalid_line.load(); int from_line = _find_first_line(0, to_line, vofs); - Ref<Font> base_font = get_theme_font(SNAME("normal_font")); - Color base_color = get_theme_color(SNAME("default_color")); - Color outline_color = get_theme_color(SNAME("font_outline_color")); - int outline_size = get_theme_constant(SNAME("outline_size")); - Color font_shadow_color = get_theme_color(SNAME("font_shadow_color")); - int shadow_outline_size = get_theme_constant(SNAME("shadow_outline_size")); - Point2 shadow_ofs(get_theme_constant(SNAME("shadow_offset_x")), get_theme_constant(SNAME("shadow_offset_y"))); + Point2 shadow_ofs(theme_cache.shadow_offset_x, theme_cache.shadow_offset_y); visible_paragraph_count = 0; visible_line_count = 0; @@ -1794,8 +1818,8 @@ void RichTextLabel::_notification(int p_what) { MutexLock lock(main->lines[from_line].text_buf->get_mutex()); visible_paragraph_count++; - visible_line_count += _draw_line(main, from_line, ofs, text_rect.size.x, base_color, outline_size, outline_color, font_shadow_color, shadow_outline_size, shadow_ofs, processed_glyphs); - ofs.y += main->lines[from_line].text_buf->get_size().y + main->lines[from_line].text_buf->get_line_count() * get_theme_constant(SNAME("line_separation")); + visible_line_count += _draw_line(main, from_line, ofs, text_rect.size.x, theme_cache.default_color, theme_cache.outline_size, theme_cache.font_outline_color, theme_cache.font_shadow_color, theme_cache.shadow_outline_size, shadow_ofs, processed_glyphs); + ofs.y += main->lines[from_line].text_buf->get_size().y + main->lines[from_line].text_buf->get_line_count() * theme_cache.line_separation; from_line++; } } break; @@ -2003,11 +2027,11 @@ void RichTextLabel::gui_input(const Ref<InputEvent> &p_event) { handled = true; } if (k->is_action("ui_up") && vscroll->is_visible_in_tree()) { - vscroll->set_value(vscroll->get_value() - get_theme_font(SNAME("normal_font"))->get_height(get_theme_font_size(SNAME("normal_font_size")))); + vscroll->set_value(vscroll->get_value() - theme_cache.normal_font->get_height(theme_cache.normal_font_size)); handled = true; } if (k->is_action("ui_down") && vscroll->is_visible_in_tree()) { - vscroll->set_value(vscroll->get_value() + get_theme_font(SNAME("normal_font"))->get_height(get_theme_font_size(SNAME("normal_font_size")))); + vscroll->set_value(vscroll->get_value() + theme_cache.normal_font->get_height(theme_cache.normal_font_size)); handled = true; } if (k->is_action("ui_home") && vscroll->is_visible_in_tree()) { @@ -2587,14 +2611,12 @@ bool RichTextLabel::_validate_line_caches() { MutexLock data_lock(data_mutex); Rect2 text_rect = _get_text_rect(); - Ref<Font> base_font = get_theme_font(SNAME("normal_font")); - int base_font_size = get_theme_font_size(SNAME("normal_font_size")); int ctrl_height = get_size().height; // Update fonts. if (main->first_invalid_font_line.load() != (int)main->lines.size()) { for (int i = main->first_invalid_font_line.load(); i < (int)main->lines.size(); i++) { - _update_line_font(main, i, base_font, base_font_size); + _update_line_font(main, i, theme_cache.normal_font, theme_cache.normal_font_size); } main->first_resized_line.store(main->first_invalid_font_line.load()); main->first_invalid_font_line.store(main->lines.size()); @@ -2609,7 +2631,7 @@ bool RichTextLabel::_validate_line_caches() { float total_height = (fi == 0) ? 0 : _calculate_line_vertical_offset(main->lines[fi - 1]); for (int i = fi; i < (int)main->lines.size(); i++) { - total_height = _resize_line(main, i, base_font, base_font_size, text_rect.get_size().width - scroll_w, total_height); + total_height = _resize_line(main, i, theme_cache.normal_font, theme_cache.normal_font_size, text_rect.get_size().width - scroll_w, total_height); updating_scroll = true; bool exceeds = total_height > ctrl_height && scroll_active; @@ -2629,7 +2651,7 @@ bool RichTextLabel::_validate_line_caches() { total_height = 0; for (int j = 0; j <= i; j++) { - total_height = _resize_line(main, j, base_font, base_font_size, text_rect.get_size().width - scroll_w, total_height); + total_height = _resize_line(main, j, theme_cache.normal_font, theme_cache.normal_font_size, text_rect.get_size().width - scroll_w, total_height); main->first_resized_line.store(j); } @@ -2676,15 +2698,13 @@ void RichTextLabel::_process_line_caches() { MutexLock data_lock(data_mutex); Rect2 text_rect = _get_text_rect(); - int base_font_size = get_theme_font_size(SNAME("normal_font_size")); - Ref<Font> base_font = get_theme_font(SNAME("normal_font")); int ctrl_height = get_size().height; int fi = main->first_invalid_line.load(); int total_chars = (fi == 0) ? 0 : (main->lines[fi].char_offset + main->lines[fi].char_count); float total_height = (fi == 0) ? 0 : _calculate_line_vertical_offset(main->lines[fi - 1]); for (int i = fi; i < (int)main->lines.size(); i++) { - total_height = _shape_line(main, i, base_font, base_font_size, text_rect.get_size().width - scroll_w, total_height, &total_chars); + total_height = _shape_line(main, i, theme_cache.normal_font, theme_cache.normal_font_size, text_rect.get_size().width - scroll_w, total_height, &total_chars); updating_scroll = true; bool exceeds = total_height > ctrl_height && scroll_active; if (exceeds != scroll_visible) { @@ -2705,7 +2725,7 @@ void RichTextLabel::_process_line_caches() { // since scroll was added or removed we need to resize all lines total_height = 0; for (int j = 0; j <= i; j++) { - total_height = _resize_line(main, j, base_font, base_font_size, text_rect.get_size().width - scroll_w, total_height); + total_height = _resize_line(main, j, theme_cache.normal_font, theme_cache.normal_font_size, text_rect.get_size().width - scroll_w, total_height); main->first_invalid_line.store(j); main->first_resized_line.store(j); @@ -2998,38 +3018,33 @@ void RichTextLabel::push_font(const Ref<Font> &p_font, int p_size) { } void RichTextLabel::push_normal() { - Ref<Font> normal_font = get_theme_font(SNAME("normal_font")); - ERR_FAIL_COND(normal_font.is_null()); + ERR_FAIL_COND(theme_cache.normal_font.is_null()); - push_font(normal_font, get_theme_font_size(SNAME("normal_font_size"))); + push_font(theme_cache.normal_font, theme_cache.normal_font_size); } void RichTextLabel::push_bold() { - Ref<Font> bold_font = get_theme_font(SNAME("bold_font")); - ERR_FAIL_COND(bold_font.is_null()); + ERR_FAIL_COND(theme_cache.bold_font.is_null()); - push_font(bold_font, get_theme_font_size(SNAME("bold_font_size"))); + push_font(theme_cache.bold_font, theme_cache.bold_font_size); } void RichTextLabel::push_bold_italics() { - Ref<Font> bold_italics_font = get_theme_font(SNAME("bold_italics_font")); - ERR_FAIL_COND(bold_italics_font.is_null()); + ERR_FAIL_COND(theme_cache.bold_italics_font.is_null()); - push_font(bold_italics_font, get_theme_font_size(SNAME("bold_italics_font_size"))); + push_font(theme_cache.bold_italics_font, theme_cache.bold_italics_font_size); } void RichTextLabel::push_italics() { - Ref<Font> italics_font = get_theme_font(SNAME("italics_font")); - ERR_FAIL_COND(italics_font.is_null()); + ERR_FAIL_COND(theme_cache.italics_font.is_null()); - push_font(italics_font, get_theme_font_size(SNAME("italics_font_size"))); + push_font(theme_cache.italics_font, theme_cache.italics_font_size); } void RichTextLabel::push_mono() { - Ref<Font> mono_font = get_theme_font(SNAME("mono_font")); - ERR_FAIL_COND(mono_font.is_null()); + ERR_FAIL_COND(theme_cache.mono_font.is_null()); - push_font(mono_font, get_theme_font_size(SNAME("mono_font_size"))); + push_font(theme_cache.mono_font, theme_cache.mono_font_size); } void RichTextLabel::push_font_size(int p_font_size) { @@ -3476,13 +3491,6 @@ void RichTextLabel::append_text(const String &p_bbcode) { int pos = 0; List<String> tag_stack; - Ref<Font> normal_font = get_theme_font(SNAME("normal_font")); - Ref<Font> bold_font = get_theme_font(SNAME("bold_font")); - Ref<Font> italics_font = get_theme_font(SNAME("italics_font")); - Ref<Font> bold_italics_font = get_theme_font(SNAME("bold_italics_font")); - Ref<Font> mono_font = get_theme_font(SNAME("mono_font")); - - Color base_color = get_theme_color(SNAME("default_color")); int indent_level = 0; @@ -3627,9 +3635,9 @@ void RichTextLabel::append_text(const String &p_bbcode) { //use bold font in_bold = true; if (in_italics) { - push_font(bold_italics_font, get_theme_font_size(SNAME("bold_italics_font_size"))); + push_font(theme_cache.bold_italics_font, theme_cache.bold_italics_font_size); } else { - push_font(bold_font, get_theme_font_size(SNAME("bold_font_size"))); + push_font(theme_cache.bold_font, theme_cache.bold_font_size); } pos = brk_end + 1; tag_stack.push_front(tag); @@ -3637,15 +3645,15 @@ void RichTextLabel::append_text(const String &p_bbcode) { //use italics font in_italics = true; if (in_bold) { - push_font(bold_italics_font, get_theme_font_size(SNAME("bold_italics_font_size"))); + push_font(theme_cache.bold_italics_font, theme_cache.bold_italics_font_size); } else { - push_font(italics_font, get_theme_font_size(SNAME("italics_font_size"))); + push_font(theme_cache.italics_font, theme_cache.italics_font_size); } pos = brk_end + 1; tag_stack.push_front(tag); } else if (tag == "code") { //use monospace font - push_font(mono_font, get_theme_font_size(SNAME("mono_font_size"))); + push_font(theme_cache.mono_font, theme_cache.mono_font_size); pos = brk_end + 1; tag_stack.push_front(tag); } else if (tag.begins_with("table=")) { @@ -3930,11 +3938,11 @@ void RichTextLabel::append_text(const String &p_bbcode) { tag_stack.push_front("hint"); } else if (tag.begins_with("dropcap")) { Vector<String> subtag = tag.substr(5, tag.length()).split(" "); - int fs = get_theme_font_size(SNAME("normal_font_size")) * 3; - Ref<Font> f = get_theme_font(SNAME("normal_font")); - Color color = get_theme_color(SNAME("default_color")); - Color outline_color = get_theme_color(SNAME("outline_color")); - int outline_size = get_theme_constant(SNAME("outline_size")); + int fs = theme_cache.normal_font_size * 3; + Ref<Font> f = theme_cache.normal_font; + Color color = theme_cache.default_color; + Color outline_color = theme_cache.outline_color; + int outline_size = theme_cache.outline_size; Rect2 dropcap_margins = Rect2(); for (int i = 0; i < subtag.size(); i++) { @@ -4052,14 +4060,14 @@ void RichTextLabel::append_text(const String &p_bbcode) { tag_stack.push_front(bbcode_name); } else if (tag.begins_with("color=")) { String color_str = tag.substr(6, tag.length()); - Color color = Color::from_string(color_str, base_color); + Color color = Color::from_string(color_str, theme_cache.default_color); push_color(color); pos = brk_end + 1; tag_stack.push_front("color"); } else if (tag.begins_with("outline_color=")) { String color_str = tag.substr(14, tag.length()); - Color color = Color::from_string(color_str, base_color); + Color color = Color::from_string(color_str, theme_cache.default_color); push_outline_color(color); pos = brk_end + 1; tag_stack.push_front("outline_color"); @@ -4074,7 +4082,7 @@ void RichTextLabel::append_text(const String &p_bbcode) { String fnt_ftr = tag.substr(18, tag.length()); Vector<String> subtag = fnt_ftr.split(","); if (subtag.size() > 0) { - Ref<Font> font = normal_font; + Ref<Font> font = theme_cache.normal_font; int font_size = 0; ItemFont *font_it = _find_font(current); if (font_it) { @@ -4286,7 +4294,7 @@ void RichTextLabel::append_text(const String &p_bbcode) { } else if (tag.begins_with("bgcolor=")) { String color_str = tag.substr(8, tag.length()); - Color color = Color::from_string(color_str, base_color); + Color color = Color::from_string(color_str, theme_cache.default_color); push_bgcolor(color); pos = brk_end + 1; @@ -4294,7 +4302,7 @@ void RichTextLabel::append_text(const String &p_bbcode) { } else if (tag.begins_with("fgcolor=")) { String color_str = tag.substr(8, tag.length()); - Color color = Color::from_string(color_str, base_color); + Color color = Color::from_string(color_str, theme_cache.default_color); push_fgcolor(color); pos = brk_end + 1; @@ -4373,7 +4381,7 @@ void RichTextLabel::scroll_to_line(int p_line) { if ((line_count <= p_line) && (line_count + main->lines[i].text_buf->get_line_count() >= p_line)) { float line_offset = 0.f; for (int j = 0; j < p_line - line_count; j++) { - line_offset += main->lines[i].text_buf->get_line_size(j).y + get_theme_constant(SNAME("line_separation")); + line_offset += main->lines[i].text_buf->get_line_size(j).y + theme_cache.line_separation; } vscroll->set_value(main->lines[i].offset.y + line_offset); return; @@ -4391,7 +4399,7 @@ float RichTextLabel::get_line_offset(int p_line) { if ((line_count <= p_line) && (p_line <= line_count + main->lines[i].text_buf->get_line_count())) { float line_offset = 0.f; for (int j = 0; j < p_line - line_count; j++) { - line_offset += main->lines[i].text_buf->get_line_size(j).y + get_theme_constant(SNAME("line_separation")); + line_offset += main->lines[i].text_buf->get_line_size(j).y + theme_cache.line_separation; } return main->lines[i].offset.y + line_offset; } @@ -4945,10 +4953,10 @@ void RichTextLabel::set_visible_ratio(float p_ratio) { if (visible_ratio != p_ratio) { _stop_thread(); - if (visible_ratio >= 1.0) { + if (p_ratio >= 1.0) { visible_characters = -1; visible_ratio = 1.0; - } else if (visible_ratio < 0.0) { + } else if (p_ratio < 0.0) { visible_characters = 0; visible_ratio = 0.0; } else { @@ -4997,7 +5005,7 @@ int RichTextLabel::get_content_height() const { int to_line = main->first_invalid_line.load(); if (to_line) { MutexLock lock(main->lines[to_line - 1].text_buf->get_mutex()); - total_height = main->lines[to_line - 1].offset.y + main->lines[to_line - 1].text_buf->get_size().y + main->lines[to_line - 1].text_buf->get_line_count() * get_theme_constant(SNAME("line_separation")); + total_height = main->lines[to_line - 1].offset.y + main->lines[to_line - 1].text_buf->get_size().y + main->lines[to_line - 1].text_buf->get_line_count() * theme_cache.line_separation; } return total_height; } @@ -5367,8 +5375,7 @@ void RichTextLabel::set_fixed_size_to_width(int p_width) { } Size2 RichTextLabel::get_minimum_size() const { - Ref<StyleBox> style = get_theme_stylebox(SNAME("normal")); - Size2 size = style->get_minimum_size(); + Size2 size = theme_cache.normal_style->get_minimum_size(); if (fixed_width != -1) { size.x += fixed_width; diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index 79f9c62539..8bc28a9ecf 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -83,6 +83,7 @@ public: }; protected: + virtual void _update_theme_item_cache() override; void _notification(int p_what); static void _bind_methods(); @@ -512,6 +513,46 @@ private: bool fit_content_height = false; + struct ThemeCache { + Ref<StyleBox> normal_style; + Ref<StyleBox> focus_style; + Ref<StyleBox> progress_bg_style; + Ref<StyleBox> progress_fg_style; + + int line_separation; + + Ref<Font> normal_font; + int normal_font_size; + + Color default_color; + Color font_selected_color; + Color selection_color; + Color font_outline_color; + Color font_shadow_color; + int shadow_outline_size; + int shadow_offset_x; + int shadow_offset_y; + int outline_size; + Color outline_color; + + Ref<Font> bold_font; + int bold_font_size; + Ref<Font> bold_italics_font; + int bold_italics_font_size; + Ref<Font> italics_font; + int italics_font_size; + Ref<Font> mono_font; + int mono_font_size; + + int table_h_separation; + int table_v_separation; + Color table_odd_row_bg; + Color table_even_row_bg; + Color table_border; + + float base_scale = 1.0; + } theme_cache; + public: String get_parsed_text() const; void add_text(const String &p_text); diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp index 2555318f39..374ce6feea 100644 --- a/scene/gui/scroll_bar.cpp +++ b/scene/gui/scroll_bar.cpp @@ -70,8 +70,8 @@ void ScrollBar::gui_input(const Ref<InputEvent> &p_event) { if (b->is_pressed()) { double ofs = orientation == VERTICAL ? b->get_position().y : b->get_position().x; - Ref<Texture2D> decr = get_theme_icon(SNAME("decrement")); - Ref<Texture2D> incr = get_theme_icon(SNAME("increment")); + Ref<Texture2D> decr = theme_cache.decrement_icon; + Ref<Texture2D> incr = theme_cache.increment_icon; double decr_size = orientation == VERTICAL ? decr->get_height() : decr->get_width(); double incr_size = orientation == VERTICAL ? incr->get_height() : incr->get_width(); @@ -146,7 +146,7 @@ void ScrollBar::gui_input(const Ref<InputEvent> &p_event) { if (drag.active) { double ofs = orientation == VERTICAL ? m->get_position().y : m->get_position().x; - Ref<Texture2D> decr = get_theme_icon(SNAME("decrement")); + Ref<Texture2D> decr = theme_cache.decrement_icon; double decr_size = orientation == VERTICAL ? decr->get_height() : decr->get_width(); ofs -= decr_size; @@ -156,8 +156,8 @@ void ScrollBar::gui_input(const Ref<InputEvent> &p_event) { set_as_ratio(drag.value_at_click + diff); } else { double ofs = orientation == VERTICAL ? m->get_position().y : m->get_position().x; - Ref<Texture2D> decr = get_theme_icon(SNAME("decrement")); - Ref<Texture2D> incr = get_theme_icon(SNAME("increment")); + Ref<Texture2D> decr = theme_cache.decrement_icon; + Ref<Texture2D> incr = theme_cache.increment_icon; double decr_size = orientation == VERTICAL ? decr->get_height() : decr->get_width(); double incr_size = orientation == VERTICAL ? incr->get_height() : incr->get_width(); @@ -217,6 +217,24 @@ void ScrollBar::gui_input(const Ref<InputEvent> &p_event) { } } +void ScrollBar::_update_theme_item_cache() { + Range::_update_theme_item_cache(); + + theme_cache.scroll_style = get_theme_stylebox(SNAME("scroll")); + theme_cache.scroll_focus_style = get_theme_stylebox(SNAME("scroll_focus")); + theme_cache.scroll_offset_style = get_theme_stylebox(SNAME("hscroll")); + theme_cache.grabber_style = get_theme_stylebox(SNAME("grabber")); + theme_cache.grabber_hl_style = get_theme_stylebox(SNAME("grabber_highlight")); + theme_cache.grabber_pressed_style = get_theme_stylebox(SNAME("grabber_pressed")); + + theme_cache.increment_icon = get_theme_icon(SNAME("increment")); + theme_cache.increment_hl_icon = get_theme_icon(SNAME("increment_highlight")); + theme_cache.increment_pressed_icon = get_theme_icon(SNAME("increment_pressed")); + theme_cache.decrement_icon = get_theme_icon(SNAME("decrement")); + theme_cache.decrement_hl_icon = get_theme_icon(SNAME("decrement_highlight")); + theme_cache.decrement_pressed_icon = get_theme_icon(SNAME("decrement_pressed")); +} + void ScrollBar::_notification(int p_what) { switch (p_what) { case NOTIFICATION_DRAW: { @@ -225,30 +243,30 @@ void ScrollBar::_notification(int p_what) { Ref<Texture2D> decr, incr; if (decr_active) { - decr = get_theme_icon(SNAME("decrement_pressed")); + decr = theme_cache.decrement_pressed_icon; } else if (highlight == HIGHLIGHT_DECR) { - decr = get_theme_icon(SNAME("decrement_highlight")); + decr = theme_cache.decrement_hl_icon; } else { - decr = get_theme_icon(SNAME("decrement")); + decr = theme_cache.decrement_icon; } if (incr_active) { - incr = get_theme_icon(SNAME("increment_pressed")); + incr = theme_cache.increment_pressed_icon; } else if (highlight == HIGHLIGHT_INCR) { - incr = get_theme_icon(SNAME("increment_highlight")); + incr = theme_cache.increment_hl_icon; } else { - incr = get_theme_icon(SNAME("increment")); + incr = theme_cache.increment_icon; } - Ref<StyleBox> bg = has_focus() ? get_theme_stylebox(SNAME("scroll_focus")) : get_theme_stylebox(SNAME("scroll")); + Ref<StyleBox> bg = has_focus() ? theme_cache.scroll_focus_style : theme_cache.scroll_style; Ref<StyleBox> grabber; if (drag.active) { - grabber = get_theme_stylebox(SNAME("grabber_pressed")); + grabber = theme_cache.grabber_pressed_style; } else if (highlight == HIGHLIGHT_RANGE) { - grabber = get_theme_stylebox(SNAME("grabber_highlight")); + grabber = theme_cache.grabber_hl_style; } else { - grabber = get_theme_stylebox(SNAME("grabber")); + grabber = theme_cache.grabber_style; } Point2 ofs; @@ -414,7 +432,7 @@ void ScrollBar::_notification(int p_what) { } double ScrollBar::get_grabber_min_size() const { - Ref<StyleBox> grabber = get_theme_stylebox(SNAME("grabber")); + Ref<StyleBox> grabber = theme_cache.grabber_style; Size2 gminsize = grabber->get_minimum_size() + grabber->get_center_size(); return (orientation == VERTICAL) ? gminsize.height : gminsize.width; } @@ -435,17 +453,17 @@ double ScrollBar::get_area_size() const { switch (orientation) { case VERTICAL: { double area = get_size().height; - area -= get_theme_stylebox(SNAME("scroll"))->get_minimum_size().height; - area -= get_theme_icon(SNAME("increment"))->get_height(); - area -= get_theme_icon(SNAME("decrement"))->get_height(); + area -= theme_cache.scroll_style->get_minimum_size().height; + area -= theme_cache.increment_icon->get_height(); + area -= theme_cache.decrement_icon->get_height(); area -= get_grabber_min_size(); return area; } break; case HORIZONTAL: { double area = get_size().width; - area -= get_theme_stylebox(SNAME("scroll"))->get_minimum_size().width; - area -= get_theme_icon(SNAME("increment"))->get_width(); - area -= get_theme_icon(SNAME("decrement"))->get_width(); + area -= theme_cache.scroll_style->get_minimum_size().width; + area -= theme_cache.increment_icon->get_width(); + area -= theme_cache.decrement_icon->get_width(); area -= get_grabber_min_size(); return area; } break; @@ -459,13 +477,13 @@ double ScrollBar::get_area_offset() const { double ofs = 0.0; if (orientation == VERTICAL) { - ofs += get_theme_stylebox(SNAME("hscroll"))->get_margin(SIDE_TOP); - ofs += get_theme_icon(SNAME("decrement"))->get_height(); + ofs += theme_cache.scroll_offset_style->get_margin(SIDE_TOP); + ofs += theme_cache.decrement_icon->get_height(); } if (orientation == HORIZONTAL) { - ofs += get_theme_stylebox(SNAME("hscroll"))->get_margin(SIDE_LEFT); - ofs += get_theme_icon(SNAME("decrement"))->get_width(); + ofs += theme_cache.scroll_offset_style->get_margin(SIDE_LEFT); + ofs += theme_cache.decrement_icon->get_width(); } return ofs; @@ -476,9 +494,9 @@ double ScrollBar::get_grabber_offset() const { } Size2 ScrollBar::get_minimum_size() const { - Ref<Texture2D> incr = get_theme_icon(SNAME("increment")); - Ref<Texture2D> decr = get_theme_icon(SNAME("decrement")); - Ref<StyleBox> bg = get_theme_stylebox(SNAME("scroll")); + Ref<Texture2D> incr = theme_cache.increment_icon; + Ref<Texture2D> decr = theme_cache.decrement_icon; + Ref<StyleBox> bg = theme_cache.scroll_style; Size2 minsize; if (orientation == VERTICAL) { diff --git a/scene/gui/scroll_bar.h b/scene/gui/scroll_bar.h index 1823f86a67..13ca62d7ff 100644 --- a/scene/gui/scroll_bar.h +++ b/scene/gui/scroll_bar.h @@ -86,14 +86,31 @@ class ScrollBar : public Range { double target_scroll = 0.0; bool smooth_scroll_enabled = false; + struct ThemeCache { + Ref<StyleBox> scroll_style; + Ref<StyleBox> scroll_focus_style; + Ref<StyleBox> scroll_offset_style; + Ref<StyleBox> grabber_style; + Ref<StyleBox> grabber_hl_style; + Ref<StyleBox> grabber_pressed_style; + + Ref<Texture2D> increment_icon; + Ref<Texture2D> increment_hl_icon; + Ref<Texture2D> increment_pressed_icon; + Ref<Texture2D> decrement_icon; + Ref<Texture2D> decrement_hl_icon; + Ref<Texture2D> decrement_pressed_icon; + } theme_cache; + void _drag_node_exit(); void _drag_node_input(const Ref<InputEvent> &p_input); virtual void gui_input(const Ref<InputEvent> &p_event) override; protected: - void _notification(int p_what); + virtual void _update_theme_item_cache() override; + void _notification(int p_what); static void _bind_methods(); public: diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp index cd595446bb..f68cebd657 100644 --- a/scene/gui/scroll_container.cpp +++ b/scene/gui/scroll_container.cpp @@ -35,7 +35,6 @@ #include "scene/main/window.h" Size2 ScrollContainer::get_minimum_size() const { - Ref<StyleBox> sb = get_theme_stylebox(SNAME("bg")); Size2 min_size; // Calculated in this function, as it needs to traverse all child controls once to calculate; @@ -77,10 +76,16 @@ Size2 ScrollContainer::get_minimum_size() const { min_size.x += v_scroll->get_minimum_size().x; } - min_size += sb->get_minimum_size(); + min_size += theme_cache.bg_style->get_minimum_size(); return min_size; } +void ScrollContainer::_update_theme_item_cache() { + Container::_update_theme_item_cache(); + + theme_cache.bg_style = get_theme_stylebox(SNAME("bg")); +} + void ScrollContainer::_cancel_drag() { set_physics_process_internal(false); drag_touching_deaccel = false; @@ -271,9 +276,8 @@ void ScrollContainer::_reposition_children() { Size2 size = get_size(); Point2 ofs; - Ref<StyleBox> sb = get_theme_stylebox(SNAME("bg")); - size -= sb->get_minimum_size(); - ofs += sb->get_offset(); + size -= theme_cache.bg_style->get_minimum_size(); + ofs += theme_cache.bg_style->get_offset(); bool rtl = is_layout_rtl(); if (h_scroll->is_visible_in_tree() && h_scroll->get_parent() == this) { //scrolls may have been moved out for reasons @@ -337,8 +341,7 @@ void ScrollContainer::_notification(int p_what) { } break; case NOTIFICATION_DRAW: { - Ref<StyleBox> sb = get_theme_stylebox(SNAME("bg")); - draw_style_box(sb, Rect2(Vector2(), get_size())); + draw_style_box(theme_cache.bg_style, Rect2(Vector2(), get_size())); } break; case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { @@ -413,8 +416,7 @@ void ScrollContainer::_notification(int p_what) { void ScrollContainer::update_scrollbars() { Size2 size = get_size(); - Ref<StyleBox> sb = get_theme_stylebox(SNAME("bg")); - size -= sb->get_minimum_size(); + size -= theme_cache.bg_style->get_minimum_size(); Size2 hmin = h_scroll->get_combined_minimum_size(); Size2 vmin = v_scroll->get_combined_minimum_size(); diff --git a/scene/gui/scroll_container.h b/scene/gui/scroll_container.h index bfa74cfd0f..fa1f09ab3f 100644 --- a/scene/gui/scroll_container.h +++ b/scene/gui/scroll_container.h @@ -69,9 +69,14 @@ private: int deadzone = 0; bool follow_focus = false; + struct ThemeCache { + Ref<StyleBox> bg_style; + } theme_cache; + void _cancel_drag(); protected: + virtual void _update_theme_item_cache() override; Size2 get_minimum_size() const override; void _gui_focus_changed(Control *p_control); diff --git a/scene/gui/separator.cpp b/scene/gui/separator.cpp index e3400d9c8f..8177c1e469 100644 --- a/scene/gui/separator.cpp +++ b/scene/gui/separator.cpp @@ -33,24 +33,30 @@ Size2 Separator::get_minimum_size() const { Size2 ms(3, 3); if (orientation == VERTICAL) { - ms.x = get_theme_constant(SNAME("separation")); + ms.x = theme_cache.separation; } else { // HORIZONTAL - ms.y = get_theme_constant(SNAME("separation")); + ms.y = theme_cache.separation; } return ms; } +void Separator::_update_theme_item_cache() { + Control::_update_theme_item_cache(); + + theme_cache.separation = get_theme_constant(SNAME("separation")); + theme_cache.separator_style = get_theme_stylebox(SNAME("separator")); +} + void Separator::_notification(int p_what) { switch (p_what) { case NOTIFICATION_DRAW: { Size2i size = get_size(); - Ref<StyleBox> style = get_theme_stylebox(SNAME("separator")); - Size2i ssize = style->get_minimum_size() + style->get_center_size(); + Size2i ssize = theme_cache.separator_style->get_minimum_size() + theme_cache.separator_style->get_center_size(); if (orientation == VERTICAL) { - style->draw(get_canvas_item(), Rect2((size.x - ssize.x) / 2, 0, ssize.x, size.y)); + theme_cache.separator_style->draw(get_canvas_item(), Rect2((size.x - ssize.x) / 2, 0, ssize.x, size.y)); } else { - style->draw(get_canvas_item(), Rect2(0, (size.y - ssize.y) / 2, size.x, ssize.y)); + theme_cache.separator_style->draw(get_canvas_item(), Rect2(0, (size.y - ssize.y) / 2, size.x, ssize.y)); } } break; } diff --git a/scene/gui/separator.h b/scene/gui/separator.h index e6578a4d04..44e18a3f00 100644 --- a/scene/gui/separator.h +++ b/scene/gui/separator.h @@ -35,8 +35,16 @@ class Separator : public Control { GDCLASS(Separator, Control); + struct ThemeCache { + int separation = 0; + Ref<StyleBox> separator_style; + } theme_cache; + protected: Orientation orientation = Orientation::HORIZONTAL; + + virtual void _update_theme_item_cache() override; + void _notification(int p_what); public: diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp index 7bf61e3541..ff3adfb9ac 100644 --- a/scene/gui/slider.cpp +++ b/scene/gui/slider.cpp @@ -33,11 +33,8 @@ #include "core/os/keyboard.h" Size2 Slider::get_minimum_size() const { - Ref<StyleBox> style = get_theme_stylebox(SNAME("slider")); - Size2i ss = style->get_minimum_size() + style->get_center_size(); - - Ref<Texture2D> grabber = get_theme_icon(SNAME("grabber")); - Size2i rs = grabber->get_size(); + Size2i ss = theme_cache.slider_style->get_minimum_size() + theme_cache.slider_style->get_center_size(); + Size2i rs = theme_cache.grabber_icon->get_size(); if (orientation == HORIZONTAL) { return Size2i(ss.width, MAX(ss.height, rs.height)); @@ -58,7 +55,13 @@ void Slider::gui_input(const Ref<InputEvent> &p_event) { if (mb.is_valid()) { if (mb->get_button_index() == MouseButton::LEFT) { if (mb->is_pressed()) { - Ref<Texture2D> grabber = get_theme_icon(mouse_inside || has_focus() ? "grabber_highlight" : "grabber"); + Ref<Texture2D> grabber; + if (mouse_inside || has_focus()) { + grabber = theme_cache.grabber_hl_icon; + } else { + grabber = theme_cache.grabber_icon; + } + grab.pos = orientation == VERTICAL ? mb->get_position().y : mb->get_position().x; double grab_width = (double)grabber->get_size().width; @@ -95,7 +98,7 @@ void Slider::gui_input(const Ref<InputEvent> &p_event) { if (mm.is_valid()) { if (grab.active) { Size2i size = get_size(); - Ref<Texture2D> grabber = get_theme_icon(SNAME("grabber")); + Ref<Texture2D> grabber = theme_cache.grabber_icon; double motion = (orientation == VERTICAL ? mm->get_position().y : mm->get_position().x) - grab.pos; if (orientation == VERTICAL) { motion = -motion; @@ -145,6 +148,19 @@ void Slider::gui_input(const Ref<InputEvent> &p_event) { } } +void Slider::_update_theme_item_cache() { + Range::_update_theme_item_cache(); + + theme_cache.slider_style = get_theme_stylebox(SNAME("slider")); + theme_cache.grabber_area_style = get_theme_stylebox(SNAME("grabber_area")); + theme_cache.grabber_area_hl_style = get_theme_stylebox(SNAME("grabber_area_highlight")); + + theme_cache.grabber_icon = get_theme_icon(SNAME("grabber")); + theme_cache.grabber_hl_icon = get_theme_icon(SNAME("grabber_highlight")); + theme_cache.grabber_disabled_icon = get_theme_icon(SNAME("grabber_disabled")); + theme_cache.tick_icon = get_theme_icon(SNAME("tick")); +} + void Slider::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: { @@ -171,13 +187,30 @@ void Slider::_notification(int p_what) { case NOTIFICATION_DRAW: { RID ci = get_canvas_item(); Size2i size = get_size(); - Ref<StyleBox> style = get_theme_stylebox(SNAME("slider")); - bool highlighted = mouse_inside || has_focus(); - Ref<StyleBox> grabber_area = get_theme_stylebox(highlighted ? "grabber_area_highlight" : "grabber_area"); - Ref<Texture2D> grabber = get_theme_icon(editable ? (highlighted ? "grabber_highlight" : "grabber") : "grabber_disabled"); - Ref<Texture2D> tick = get_theme_icon(SNAME("tick")); double ratio = Math::is_nan(get_as_ratio()) ? 0 : get_as_ratio(); + Ref<StyleBox> style = theme_cache.slider_style; + Ref<Texture2D> tick = theme_cache.tick_icon; + + bool highlighted = mouse_inside || has_focus(); + Ref<Texture2D> grabber; + if (editable) { + if (highlighted) { + grabber = theme_cache.grabber_hl_icon; + } else { + grabber = theme_cache.grabber_icon; + } + } else { + grabber = theme_cache.grabber_disabled_icon; + } + + Ref<StyleBox> grabber_area; + if (highlighted) { + grabber_area = theme_cache.grabber_area_hl_style; + } else { + grabber_area = theme_cache.grabber_area_style; + } + if (orientation == VERTICAL) { int widget_width = style->get_minimum_size().width + style->get_center_size().width; double areasize = size.height - grabber->get_size().height; diff --git a/scene/gui/slider.h b/scene/gui/slider.h index 5abaee27aa..51adb354fb 100644 --- a/scene/gui/slider.h +++ b/scene/gui/slider.h @@ -49,11 +49,24 @@ class Slider : public Range { bool editable = true; bool scrollable = true; + struct ThemeCache { + Ref<StyleBox> slider_style; + Ref<StyleBox> grabber_area_style; + Ref<StyleBox> grabber_area_hl_style; + + Ref<Texture2D> grabber_icon; + Ref<Texture2D> grabber_hl_icon; + Ref<Texture2D> grabber_disabled_icon; + Ref<Texture2D> tick_icon; + } theme_cache; + protected: + bool ticks_on_borders = false; + virtual void gui_input(const Ref<InputEvent> &p_event) override; + virtual void _update_theme_item_cache() override; void _notification(int p_what); static void _bind_methods(); - bool ticks_on_borders = false; public: virtual Size2 get_minimum_size() const override; diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp index 900249ddd9..fe14049d93 100644 --- a/scene/gui/spin_box.cpp +++ b/scene/gui/spin_box.cpp @@ -210,25 +210,29 @@ inline void SpinBox::_adjust_width_for_icon(const Ref<Texture2D> &icon) { } } +void SpinBox::_update_theme_item_cache() { + Range::_update_theme_item_cache(); + + theme_cache.updown_icon = get_theme_icon(SNAME("updown")); +} + void SpinBox::_notification(int p_what) { switch (p_what) { case NOTIFICATION_DRAW: { - Ref<Texture2D> updown = get_theme_icon(SNAME("updown")); - - _adjust_width_for_icon(updown); + _adjust_width_for_icon(theme_cache.updown_icon); RID ci = get_canvas_item(); Size2i size = get_size(); if (is_layout_rtl()) { - updown->draw(ci, Point2i(0, (size.height - updown->get_height()) / 2)); + theme_cache.updown_icon->draw(ci, Point2i(0, (size.height - theme_cache.updown_icon->get_height()) / 2)); } else { - updown->draw(ci, Point2i(size.width - updown->get_width(), (size.height - updown->get_height()) / 2)); + theme_cache.updown_icon->draw(ci, Point2i(size.width - theme_cache.updown_icon->get_width(), (size.height - theme_cache.updown_icon->get_height()) / 2)); } } break; case NOTIFICATION_ENTER_TREE: { - _adjust_width_for_icon(get_theme_icon(SNAME("updown"))); + _adjust_width_for_icon(theme_cache.updown_icon); _value_changed(0); } break; diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h index 3fcb85ac99..c2f2ac3f5a 100644 --- a/scene/gui/spin_box.h +++ b/scene/gui/spin_box.h @@ -69,9 +69,14 @@ class SpinBox : public Range { inline void _adjust_width_for_icon(const Ref<Texture2D> &icon); + struct ThemeCache { + Ref<Texture2D> updown_icon; + } theme_cache; + protected: virtual void gui_input(const Ref<InputEvent> &p_event) override; + virtual void _update_theme_item_cache() override; void _notification(int p_what); static void _bind_methods(); diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp index b7e1f2a914..04bd5b3282 100644 --- a/scene/gui/split_container.cpp +++ b/scene/gui/split_container.cpp @@ -55,6 +55,18 @@ Control *SplitContainer::_getch(int p_idx) const { return nullptr; } +Ref<Texture2D> SplitContainer::_get_grabber_icon() const { + if (is_fixed) { + return theme_cache.grabber_icon; + } else { + if (vertical) { + return theme_cache.grabber_icon_v; + } else { + return theme_cache.grabber_icon_h; + } + } +} + void SplitContainer::_resort() { int axis = vertical ? 1 : 0; @@ -76,9 +88,8 @@ void SplitContainer::_resort() { bool second_expanded = (vertical ? second->get_v_size_flags() : second->get_h_size_flags()) & SIZE_EXPAND; // Determine the separation between items - Ref<Texture2D> g = get_theme_icon(SNAME("grabber")); - int sep = get_theme_constant(SNAME("separation")); - sep = (dragger_visibility != DRAGGER_HIDDEN_COLLAPSED) ? MAX(sep, vertical ? g->get_height() : g->get_width()) : 0; + Ref<Texture2D> g = _get_grabber_icon(); + int sep = (dragger_visibility != DRAGGER_HIDDEN_COLLAPSED) ? MAX(theme_cache.separation, vertical ? g->get_height() : g->get_width()) : 0; // Compute the minimum size Size2 ms_first = first->get_combined_minimum_size(); @@ -128,12 +139,9 @@ void SplitContainer::_resort() { } Size2 SplitContainer::get_minimum_size() const { - /* Calculate MINIMUM SIZE */ - Size2i minimum; - Ref<Texture2D> g = get_theme_icon(SNAME("grabber")); - int sep = get_theme_constant(SNAME("separation")); - sep = (dragger_visibility != DRAGGER_HIDDEN_COLLAPSED) ? MAX(sep, vertical ? g->get_height() : g->get_width()) : 0; + Ref<Texture2D> g = _get_grabber_icon(); + int sep = (dragger_visibility != DRAGGER_HIDDEN_COLLAPSED) ? MAX(theme_cache.separation, vertical ? g->get_height() : g->get_width()) : 0; for (int i = 0; i < 2; i++) { if (!_getch(i)) { @@ -162,6 +170,16 @@ Size2 SplitContainer::get_minimum_size() const { return minimum; } +void SplitContainer::_update_theme_item_cache() { + Container::_update_theme_item_cache(); + + theme_cache.separation = get_theme_constant(SNAME("separation")); + theme_cache.autohide = get_theme_constant(SNAME("autohide")); + theme_cache.grabber_icon = get_theme_icon(SNAME("grabber")); + theme_cache.grabber_icon_h = get_theme_icon(SNAME("h_grabber")); + theme_cache.grabber_icon_v = get_theme_icon(SNAME("v_grabber")); +} + void SplitContainer::_notification(int p_what) { switch (p_what) { case NOTIFICATION_TRANSLATION_CHANGED: @@ -175,7 +193,7 @@ void SplitContainer::_notification(int p_what) { case NOTIFICATION_MOUSE_EXIT: { mouse_inside = false; - if (get_theme_constant(SNAME("autohide"))) { + if (theme_cache.autohide) { queue_redraw(); } } break; @@ -185,7 +203,7 @@ void SplitContainer::_notification(int p_what) { return; } - if (collapsed || (!dragging && !mouse_inside && get_theme_constant(SNAME("autohide")))) { + if (collapsed || (!dragging && !mouse_inside && theme_cache.autohide)) { return; } @@ -193,8 +211,8 @@ void SplitContainer::_notification(int p_what) { return; } - int sep = dragger_visibility != DRAGGER_HIDDEN_COLLAPSED ? get_theme_constant(SNAME("separation")) : 0; - Ref<Texture2D> tex = get_theme_icon(SNAME("grabber")); + int sep = dragger_visibility != DRAGGER_HIDDEN_COLLAPSED ? theme_cache.separation : 0; + Ref<Texture2D> tex = theme_cache.grabber_icon; Size2 size = get_size(); if (vertical) { @@ -210,6 +228,12 @@ void SplitContainer::_notification(int p_what) { } } +void SplitContainer::_validate_property(PropertyInfo &p_property) const { + if (is_fixed && p_property.name == "vertical") { + p_property.usage = PROPERTY_USAGE_NONE; + } +} + void SplitContainer::gui_input(const Ref<InputEvent> &p_event) { ERR_FAIL_COND(p_event.is_null()); @@ -222,16 +246,14 @@ void SplitContainer::gui_input(const Ref<InputEvent> &p_event) { if (mb.is_valid()) { if (mb->get_button_index() == MouseButton::LEFT) { if (mb->is_pressed()) { - int sep = get_theme_constant(SNAME("separation")); - if (vertical) { - if (mb->get_position().y > middle_sep && mb->get_position().y < middle_sep + sep) { + if (mb->get_position().y > middle_sep && mb->get_position().y < middle_sep + theme_cache.separation) { dragging = true; drag_from = mb->get_position().y; drag_ofs = split_offset; } } else { - if (mb->get_position().x > middle_sep && mb->get_position().x < middle_sep + sep) { + if (mb->get_position().x > middle_sep && mb->get_position().x < middle_sep + theme_cache.separation) { dragging = true; drag_from = mb->get_position().x; drag_ofs = split_offset; @@ -248,14 +270,14 @@ void SplitContainer::gui_input(const Ref<InputEvent> &p_event) { if (mm.is_valid()) { bool mouse_inside_state = false; if (vertical) { - mouse_inside_state = mm->get_position().y > middle_sep && mm->get_position().y < middle_sep + get_theme_constant(SNAME("separation")); + mouse_inside_state = mm->get_position().y > middle_sep && mm->get_position().y < middle_sep + theme_cache.separation; } else { - mouse_inside_state = mm->get_position().x > middle_sep && mm->get_position().x < middle_sep + get_theme_constant(SNAME("separation")); + mouse_inside_state = mm->get_position().x > middle_sep && mm->get_position().x < middle_sep + theme_cache.separation; } if (mouse_inside != mouse_inside_state) { mouse_inside = mouse_inside_state; - if (get_theme_constant(SNAME("autohide"))) { + if (theme_cache.autohide) { queue_redraw(); } } @@ -281,14 +303,12 @@ Control::CursorShape SplitContainer::get_cursor_shape(const Point2 &p_pos) const } if (!collapsed && _getch(0) && _getch(1) && dragger_visibility == DRAGGER_VISIBLE) { - int sep = get_theme_constant(SNAME("separation")); - if (vertical) { - if (p_pos.y > middle_sep && p_pos.y < middle_sep + sep) { + if (p_pos.y > middle_sep && p_pos.y < middle_sep + theme_cache.separation) { return CURSOR_VSPLIT; } } else { - if (p_pos.x > middle_sep && p_pos.x < middle_sep + sep) { + if (p_pos.x > middle_sep && p_pos.x < middle_sep + theme_cache.separation) { return CURSOR_HSPLIT; } } @@ -344,6 +364,17 @@ bool SplitContainer::is_collapsed() const { return collapsed; } +void SplitContainer::set_vertical(bool p_vertical) { + ERR_FAIL_COND_MSG(is_fixed, "Can't change orientation of " + get_class() + "."); + vertical = p_vertical; + update_minimum_size(); + _resort(); +} + +bool SplitContainer::is_vertical() const { + return vertical; +} + Vector<int> SplitContainer::get_allowed_size_flags_horizontal() const { Vector<int> flags; flags.append(SIZE_FILL); @@ -379,11 +410,15 @@ void SplitContainer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_dragger_visibility", "mode"), &SplitContainer::set_dragger_visibility); ClassDB::bind_method(D_METHOD("get_dragger_visibility"), &SplitContainer::get_dragger_visibility); + ClassDB::bind_method(D_METHOD("set_vertical", "vertical"), &SplitContainer::set_vertical); + ClassDB::bind_method(D_METHOD("is_vertical"), &SplitContainer::is_vertical); + ADD_SIGNAL(MethodInfo("dragged", PropertyInfo(Variant::INT, "offset"))); ADD_PROPERTY(PropertyInfo(Variant::INT, "split_offset", PROPERTY_HINT_NONE, "suffix:px"), "set_split_offset", "get_split_offset"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collapsed"), "set_collapsed", "is_collapsed"); ADD_PROPERTY(PropertyInfo(Variant::INT, "dragger_visibility", PROPERTY_HINT_ENUM, "Visible,Hidden,Hidden and Collapsed"), "set_dragger_visibility", "get_dragger_visibility"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "vertical"), "set_vertical", "is_vertical"); BIND_ENUM_CONSTANT(DRAGGER_VISIBLE); BIND_ENUM_CONSTANT(DRAGGER_HIDDEN); diff --git a/scene/gui/split_container.h b/scene/gui/split_container.h index a69ffe4de9..8ab0779d4b 100644 --- a/scene/gui/split_container.h +++ b/scene/gui/split_container.h @@ -55,13 +55,27 @@ private: DraggerVisibility dragger_visibility = DRAGGER_VISIBLE; bool mouse_inside = false; + struct ThemeCache { + int separation = 0; + int autohide = 0; + Ref<Texture2D> grabber_icon; + Ref<Texture2D> grabber_icon_h; + Ref<Texture2D> grabber_icon_v; + } theme_cache; + Control *_getch(int p_idx) const; + Ref<Texture2D> _get_grabber_icon() const; void _resort(); protected: + bool is_fixed = false; + virtual void gui_input(const Ref<InputEvent> &p_event) override; + virtual void _update_theme_item_cache() override; + void _notification(int p_what); + void _validate_property(PropertyInfo &p_property) const; static void _bind_methods(); public: @@ -75,6 +89,9 @@ public: void set_dragger_visibility(DraggerVisibility p_visibility); DraggerVisibility get_dragger_visibility() const; + void set_vertical(bool p_vertical); + bool is_vertical() const; + virtual CursorShape get_cursor_shape(const Point2 &p_pos = Point2i()) const override; virtual Size2 get_minimum_size() const override; @@ -92,7 +109,7 @@ class HSplitContainer : public SplitContainer { public: HSplitContainer() : - SplitContainer(false) {} + SplitContainer(false) { is_fixed = true; } }; class VSplitContainer : public SplitContainer { @@ -100,7 +117,7 @@ class VSplitContainer : public SplitContainer { public: VSplitContainer() : - SplitContainer(true) {} + SplitContainer(true) { is_fixed = true; } }; #endif // SPLIT_CONTAINER_H diff --git a/scene/gui/tab_bar.cpp b/scene/gui/tab_bar.cpp index 61cf8e8a86..4d18af7743 100644 --- a/scene/gui/tab_bar.cpp +++ b/scene/gui/tab_bar.cpp @@ -44,14 +44,7 @@ Size2 TabBar::get_minimum_size() const { return ms; } - Ref<StyleBox> tab_unselected = get_theme_stylebox(SNAME("tab_unselected")); - Ref<StyleBox> tab_selected = get_theme_stylebox(SNAME("tab_selected")); - Ref<StyleBox> tab_disabled = get_theme_stylebox(SNAME("tab_disabled")); - Ref<StyleBox> button_highlight = get_theme_stylebox(SNAME("button_highlight")); - Ref<Texture2D> close = get_theme_icon(SNAME("close")); - int hseparation = get_theme_constant(SNAME("h_separation")); - - int y_margin = MAX(MAX(tab_unselected->get_minimum_size().height, tab_selected->get_minimum_size().height), tab_disabled->get_minimum_size().height); + int y_margin = MAX(MAX(theme_cache.tab_unselected_style->get_minimum_size().height, theme_cache.tab_selected_style->get_minimum_size().height), theme_cache.tab_disabled_style->get_minimum_size().height); for (int i = 0; i < tabs.size(); i++) { if (tabs[i].hidden) { @@ -62,22 +55,22 @@ Size2 TabBar::get_minimum_size() const { Ref<StyleBox> style; if (tabs[i].disabled) { - style = tab_disabled; + style = theme_cache.tab_disabled_style; } else if (current == i) { - style = tab_selected; + style = theme_cache.tab_selected_style; } else { - style = tab_unselected; + style = theme_cache.tab_unselected_style; } ms.width += style->get_minimum_size().width; Ref<Texture2D> tex = tabs[i].icon; if (tex.is_valid()) { ms.height = MAX(ms.height, tex->get_size().height + y_margin); - ms.width += tex->get_size().width + hseparation; + ms.width += tex->get_size().width + theme_cache.h_separation; } if (!tabs[i].text.is_empty()) { - ms.width += tabs[i].size_text + hseparation; + ms.width += tabs[i].size_text + theme_cache.h_separation; } ms.height = MAX(ms.height, tabs[i].text_buf->get_size().y + y_margin); @@ -87,22 +80,22 @@ Size2 TabBar::get_minimum_size() const { Ref<Texture2D> rb = tabs[i].right_button; if (close_visible) { - ms.width += button_highlight->get_minimum_size().width + rb->get_width(); + ms.width += theme_cache.button_hl_style->get_minimum_size().width + rb->get_width(); } else { - ms.width += button_highlight->get_margin(SIDE_LEFT) + rb->get_width() + hseparation; + ms.width += theme_cache.button_hl_style->get_margin(SIDE_LEFT) + rb->get_width() + theme_cache.h_separation; } ms.height = MAX(ms.height, rb->get_height() + y_margin); } if (close_visible) { - ms.width += button_highlight->get_margin(SIDE_LEFT) + close->get_width() + hseparation; + ms.width += theme_cache.button_hl_style->get_margin(SIDE_LEFT) + theme_cache.close_icon->get_width() + theme_cache.h_separation; - ms.height = MAX(ms.height, close->get_height() + y_margin); + ms.height = MAX(ms.height, theme_cache.close_icon->get_height() + y_margin); } if (ms.width - ofs > style->get_minimum_size().width) { - ms.width -= hseparation; + ms.width -= theme_cache.h_separation; } } @@ -122,16 +115,13 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) { Point2 pos = mm->get_position(); if (buttons_visible) { - Ref<Texture2D> incr = get_theme_icon(SNAME("increment")); - Ref<Texture2D> decr = get_theme_icon(SNAME("decrement")); - if (is_layout_rtl()) { - if (pos.x < decr->get_width()) { + if (pos.x < theme_cache.decrement_icon->get_width()) { if (highlight_arrow != 1) { highlight_arrow = 1; queue_redraw(); } - } else if (pos.x < incr->get_width() + decr->get_width()) { + } else if (pos.x < theme_cache.increment_icon->get_width() + theme_cache.decrement_icon->get_width()) { if (highlight_arrow != 0) { highlight_arrow = 0; queue_redraw(); @@ -141,8 +131,8 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) { queue_redraw(); } } else { - int limit_minus_buttons = get_size().width - incr->get_width() - decr->get_width(); - if (pos.x > limit_minus_buttons + decr->get_width()) { + int limit_minus_buttons = get_size().width - theme_cache.increment_icon->get_width() - theme_cache.decrement_icon->get_width(); + if (pos.x > limit_minus_buttons + theme_cache.decrement_icon->get_width()) { if (highlight_arrow != 1) { highlight_arrow = 1; queue_redraw(); @@ -214,18 +204,15 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) { Point2 pos = mb->get_position(); if (buttons_visible) { - Ref<Texture2D> incr = get_theme_icon(SNAME("increment")); - Ref<Texture2D> decr = get_theme_icon(SNAME("decrement")); - if (is_layout_rtl()) { - if (pos.x < decr->get_width()) { + if (pos.x < theme_cache.decrement_icon->get_width()) { if (missing_right) { offset++; _update_cache(); queue_redraw(); } return; - } else if (pos.x < incr->get_width() + decr->get_width()) { + } else if (pos.x < theme_cache.increment_icon->get_width() + theme_cache.decrement_icon->get_width()) { if (offset > 0) { offset--; _update_cache(); @@ -234,8 +221,8 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) { return; } } else { - int limit = get_size().width - incr->get_width() - decr->get_width(); - if (pos.x > limit + decr->get_width()) { + int limit = get_size().width - theme_cache.increment_icon->get_width() - theme_cache.decrement_icon->get_width(); + if (pos.x > limit + theme_cache.decrement_icon->get_width()) { if (missing_right) { offset++; _update_cache(); @@ -299,9 +286,6 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) { } void TabBar::_shape(int p_tab) { - Ref<Font> font = get_theme_font(SNAME("font")); - int font_size = get_theme_font_size(SNAME("font_size")); - tabs.write[p_tab].xl_text = atr(tabs[p_tab].text); tabs.write[p_tab].text_buf->clear(); tabs.write[p_tab].text_buf->set_width(-1); @@ -311,7 +295,37 @@ void TabBar::_shape(int p_tab) { tabs.write[p_tab].text_buf->set_direction((TextServer::Direction)tabs[p_tab].text_direction); } - tabs.write[p_tab].text_buf->add_string(tabs[p_tab].xl_text, font, font_size, tabs[p_tab].language); + tabs.write[p_tab].text_buf->add_string(tabs[p_tab].xl_text, theme_cache.font, theme_cache.font_size, tabs[p_tab].language); +} + +void TabBar::_update_theme_item_cache() { + Control::_update_theme_item_cache(); + + theme_cache.h_separation = get_theme_constant(SNAME("h_separation")); + + theme_cache.tab_unselected_style = get_theme_stylebox(SNAME("tab_unselected")); + theme_cache.tab_selected_style = get_theme_stylebox(SNAME("tab_selected")); + theme_cache.tab_disabled_style = get_theme_stylebox(SNAME("tab_disabled")); + + theme_cache.increment_icon = get_theme_icon(SNAME("increment")); + theme_cache.increment_hl_icon = get_theme_icon(SNAME("increment_highlight")); + theme_cache.decrement_icon = get_theme_icon(SNAME("decrement")); + theme_cache.decrement_hl_icon = get_theme_icon(SNAME("decrement_highlight")); + theme_cache.drop_mark_icon = get_theme_icon(SNAME("drop_mark")); + theme_cache.drop_mark_color = get_theme_color(SNAME("drop_mark_color")); + + theme_cache.font = get_theme_font(SNAME("font")); + theme_cache.font_size = get_theme_font_size(SNAME("font_size")); + theme_cache.outline_size = get_theme_constant(SNAME("outline_size")); + + theme_cache.font_selected_color = get_theme_color(SNAME("font_selected_color")); + theme_cache.font_unselected_color = get_theme_color(SNAME("font_unselected_color")); + theme_cache.font_disabled_color = get_theme_color(SNAME("font_disabled_color")); + theme_cache.font_outline_color = get_theme_color(SNAME("font_outline_color")); + + theme_cache.close_icon = get_theme_icon(SNAME("close")); + theme_cache.button_pressed_style = get_theme_stylebox(SNAME("button_pressed")); + theme_cache.button_hl_style = get_theme_stylebox(SNAME("button_highlight")); } void TabBar::_notification(int p_what) { @@ -352,18 +366,9 @@ void TabBar::_notification(int p_what) { return; } - Ref<StyleBox> tab_unselected = get_theme_stylebox(SNAME("tab_unselected")); - Ref<StyleBox> tab_selected = get_theme_stylebox(SNAME("tab_selected")); - Ref<StyleBox> tab_disabled = get_theme_stylebox(SNAME("tab_disabled")); - Color font_selected_color = get_theme_color(SNAME("font_selected_color")); - Color font_unselected_color = get_theme_color(SNAME("font_unselected_color")); - Color font_disabled_color = get_theme_color(SNAME("font_disabled_color")); - Ref<Texture2D> incr = get_theme_icon(SNAME("increment")); - Ref<Texture2D> decr = get_theme_icon(SNAME("decrement")); - bool rtl = is_layout_rtl(); Vector2 size = get_size(); - int limit_minus_buttons = size.width - incr->get_width() - decr->get_width(); + int limit_minus_buttons = size.width - theme_cache.increment_icon->get_width() - theme_cache.decrement_icon->get_width(); int ofs = tabs[offset].ofs_cache; @@ -378,14 +383,14 @@ void TabBar::_notification(int p_what) { Color col; if (tabs[i].disabled) { - sb = tab_disabled; - col = font_disabled_color; + sb = theme_cache.tab_disabled_style; + col = theme_cache.font_disabled_color; } else if (i == current) { - sb = tab_selected; - col = font_selected_color; + sb = theme_cache.tab_selected_style; + col = theme_cache.font_selected_color; } else { - sb = tab_unselected; - col = font_unselected_color; + sb = theme_cache.tab_unselected_style; + col = theme_cache.font_unselected_color; } _draw_tab(sb, col, i, rtl ? size.width - ofs - tabs[i].size_cache : ofs); @@ -396,41 +401,38 @@ void TabBar::_notification(int p_what) { // Draw selected tab in the front, but only if it's visible. if (current >= offset && current <= max_drawn_tab && !tabs[current].hidden) { - Ref<StyleBox> sb = tabs[current].disabled ? tab_disabled : tab_selected; + Ref<StyleBox> sb = tabs[current].disabled ? theme_cache.tab_disabled_style : theme_cache.tab_selected_style; float x = rtl ? size.width - tabs[current].ofs_cache - tabs[current].size_cache : tabs[current].ofs_cache; - _draw_tab(sb, font_selected_color, current, x); + _draw_tab(sb, theme_cache.font_selected_color, current, x); } if (buttons_visible) { - Ref<Texture2D> incr_hl = get_theme_icon(SNAME("increment_highlight")); - Ref<Texture2D> decr_hl = get_theme_icon(SNAME("decrement_highlight")); - - int vofs = (size.height - incr->get_size().height) / 2; + int vofs = (size.height - theme_cache.increment_icon->get_size().height) / 2; if (rtl) { if (missing_right) { - draw_texture(highlight_arrow == 1 ? decr_hl : decr, Point2(0, vofs)); + draw_texture(highlight_arrow == 1 ? theme_cache.decrement_hl_icon : theme_cache.decrement_icon, Point2(0, vofs)); } else { - draw_texture(decr, Point2(0, vofs), Color(1, 1, 1, 0.5)); + draw_texture(theme_cache.decrement_icon, Point2(0, vofs), Color(1, 1, 1, 0.5)); } if (offset > 0) { - draw_texture(highlight_arrow == 0 ? incr_hl : incr, Point2(incr->get_size().width, vofs)); + draw_texture(highlight_arrow == 0 ? theme_cache.increment_hl_icon : theme_cache.increment_icon, Point2(theme_cache.increment_icon->get_size().width, vofs)); } else { - draw_texture(incr, Point2(incr->get_size().width, vofs), Color(1, 1, 1, 0.5)); + draw_texture(theme_cache.increment_icon, Point2(theme_cache.increment_icon->get_size().width, vofs), Color(1, 1, 1, 0.5)); } } else { if (offset > 0) { - draw_texture(highlight_arrow == 0 ? decr_hl : decr, Point2(limit_minus_buttons, vofs)); + draw_texture(highlight_arrow == 0 ? theme_cache.decrement_hl_icon : theme_cache.decrement_icon, Point2(limit_minus_buttons, vofs)); } else { - draw_texture(decr, Point2(limit_minus_buttons, vofs), Color(1, 1, 1, 0.5)); + draw_texture(theme_cache.decrement_icon, Point2(limit_minus_buttons, vofs), Color(1, 1, 1, 0.5)); } if (missing_right) { - draw_texture(highlight_arrow == 1 ? incr_hl : incr, Point2(limit_minus_buttons + decr->get_size().width, vofs)); + draw_texture(highlight_arrow == 1 ? theme_cache.increment_hl_icon : theme_cache.increment_icon, Point2(limit_minus_buttons + theme_cache.decrement_icon->get_size().width, vofs)); } else { - draw_texture(incr, Point2(limit_minus_buttons + decr->get_size().width, vofs), Color(1, 1, 1, 0.5)); + draw_texture(theme_cache.increment_icon, Point2(limit_minus_buttons + theme_cache.decrement_icon->get_size().width, vofs), Color(1, 1, 1, 0.5)); } } } @@ -462,10 +464,7 @@ void TabBar::_notification(int p_what) { } } - Ref<Texture2D> drop_mark = get_theme_icon(SNAME("drop_mark")); - Color drop_mark_color = get_theme_color(SNAME("drop_mark_color")); - - drop_mark->draw(get_canvas_item(), Point2(x - drop_mark->get_width() / 2, (size.height - drop_mark->get_height()) / 2), drop_mark_color); + theme_cache.drop_mark_icon->draw(get_canvas_item(), Point2(x - theme_cache.drop_mark_icon->get_width() / 2, (size.height - theme_cache.drop_mark_icon->get_height()) / 2), theme_cache.drop_mark_color); } } break; } @@ -475,10 +474,6 @@ void TabBar::_draw_tab(Ref<StyleBox> &p_tab_style, Color &p_font_color, int p_in RID ci = get_canvas_item(); bool rtl = is_layout_rtl(); - Color font_outline_color = get_theme_color(SNAME("font_outline_color")); - int outline_size = get_theme_constant(SNAME("outline_size")); - int hseparation = get_theme_constant(SNAME("h_separation")); - Rect2 sb_rect = Rect2(p_x, 0, tabs[p_index].size_cache, get_size().height); p_tab_style->draw(ci, sb_rect); @@ -491,7 +486,7 @@ void TabBar::_draw_tab(Ref<StyleBox> &p_tab_style, Color &p_font_color, int p_in if (icon.is_valid()) { icon->draw(ci, Point2i(rtl ? p_x - icon->get_width() : p_x, p_tab_style->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - icon->get_height()) / 2)); - p_x = rtl ? p_x - icon->get_width() - hseparation : p_x + icon->get_width() + hseparation; + p_x = rtl ? p_x - icon->get_width() - theme_cache.h_separation : p_x + icon->get_width() + theme_cache.h_separation; } // Draw the text. @@ -499,17 +494,17 @@ void TabBar::_draw_tab(Ref<StyleBox> &p_tab_style, Color &p_font_color, int p_in Point2i text_pos = Point2i(rtl ? p_x - tabs[p_index].size_text : p_x, p_tab_style->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - tabs[p_index].text_buf->get_size().y) / 2); - if (outline_size > 0 && font_outline_color.a > 0) { - tabs[p_index].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color); + if (theme_cache.outline_size > 0 && theme_cache.font_outline_color.a > 0) { + tabs[p_index].text_buf->draw_outline(ci, text_pos, theme_cache.outline_size, theme_cache.font_outline_color); } tabs[p_index].text_buf->draw(ci, text_pos, p_font_color); - p_x = rtl ? p_x - tabs[p_index].size_text - hseparation : p_x + tabs[p_index].size_text + hseparation; + p_x = rtl ? p_x - tabs[p_index].size_text - theme_cache.h_separation : p_x + tabs[p_index].size_text + theme_cache.h_separation; } // Draw and calculate rect of the right button. if (tabs[p_index].right_button.is_valid()) { - Ref<StyleBox> style = get_theme_stylebox(SNAME("button_highlight")); + Ref<StyleBox> style = theme_cache.button_hl_style; Ref<Texture2D> rb = tabs[p_index].right_button; Rect2 rb_rect; @@ -521,7 +516,7 @@ void TabBar::_draw_tab(Ref<StyleBox> &p_tab_style, Color &p_font_color, int p_in if (rb_hover == p_index) { if (rb_pressing) { - get_theme_stylebox(SNAME("button_pressed"))->draw(ci, rb_rect); + theme_cache.button_pressed_style->draw(ci, rb_rect); } else { style->draw(ci, rb_rect); } @@ -534,8 +529,8 @@ void TabBar::_draw_tab(Ref<StyleBox> &p_tab_style, Color &p_font_color, int p_in // Draw and calculate rect of the close button. if (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && p_index == current)) { - Ref<StyleBox> style = get_theme_stylebox(SNAME("button_highlight")); - Ref<Texture2D> cb = get_theme_icon(SNAME("close")); + Ref<StyleBox> style = theme_cache.button_hl_style; + Ref<Texture2D> cb = theme_cache.close_icon; Rect2 cb_rect; cb_rect.size = style->get_minimum_size() + cb->get_size(); @@ -546,7 +541,7 @@ void TabBar::_draw_tab(Ref<StyleBox> &p_tab_style, Color &p_font_color, int p_in if (!tabs[p_index].disabled && cb_hover == p_index) { if (cb_pressing) { - get_theme_stylebox(SNAME("button_pressed"))->draw(ci, cb_rect); + theme_cache.button_pressed_style->draw(ci, cb_rect); } else { style->draw(ci, cb_rect); } @@ -849,14 +844,8 @@ void TabBar::_update_cache() { return; } - Ref<StyleBox> tab_disabled = get_theme_stylebox(SNAME("tab_disabled")); - Ref<StyleBox> tab_unselected = get_theme_stylebox(SNAME("tab_unselected")); - Ref<StyleBox> tab_selected = get_theme_stylebox(SNAME("tab_selected")); - Ref<Texture2D> incr = get_theme_icon(SNAME("increment")); - Ref<Texture2D> decr = get_theme_icon(SNAME("decrement")); - int limit = get_size().width; - int limit_minus_buttons = limit - incr->get_width() - decr->get_width(); + int limit_minus_buttons = limit - theme_cache.increment_icon->get_width() - theme_cache.decrement_icon->get_width(); int w = 0; @@ -1258,52 +1247,47 @@ void TabBar::move_tab(int p_from, int p_to) { int TabBar::get_tab_width(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, tabs.size(), 0); - Ref<StyleBox> tab_unselected = get_theme_stylebox(SNAME("tab_unselected")); - Ref<StyleBox> tab_selected = get_theme_stylebox(SNAME("tab_selected")); - Ref<StyleBox> tab_disabled = get_theme_stylebox(SNAME("tab_disabled")); - int hseparation = get_theme_constant(SNAME("h_separation")); - Ref<StyleBox> style; if (tabs[p_idx].disabled) { - style = tab_disabled; + style = theme_cache.tab_disabled_style; } else if (current == p_idx) { - style = tab_selected; + style = theme_cache.tab_selected_style; } else { - style = tab_unselected; + style = theme_cache.tab_unselected_style; } int x = style->get_minimum_size().width; Ref<Texture2D> tex = tabs[p_idx].icon; if (tex.is_valid()) { - x += tex->get_width() + hseparation; + x += tex->get_width() + theme_cache.h_separation; } if (!tabs[p_idx].text.is_empty()) { - x += tabs[p_idx].size_text + hseparation; + x += tabs[p_idx].size_text + theme_cache.h_separation; } bool close_visible = cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && p_idx == current); if (tabs[p_idx].right_button.is_valid()) { - Ref<StyleBox> btn_style = get_theme_stylebox(SNAME("button_highlight")); + Ref<StyleBox> btn_style = theme_cache.button_hl_style; Ref<Texture2D> rb = tabs[p_idx].right_button; if (close_visible) { x += btn_style->get_minimum_size().width + rb->get_width(); } else { - x += btn_style->get_margin(SIDE_LEFT) + rb->get_width() + hseparation; + x += btn_style->get_margin(SIDE_LEFT) + rb->get_width() + theme_cache.h_separation; } } if (close_visible) { - Ref<StyleBox> btn_style = get_theme_stylebox(SNAME("button_highlight")); - Ref<Texture2D> cb = get_theme_icon(SNAME("close")); - x += btn_style->get_margin(SIDE_LEFT) + cb->get_width() + hseparation; + Ref<StyleBox> btn_style = theme_cache.button_hl_style; + Ref<Texture2D> cb = theme_cache.close_icon; + x += btn_style->get_margin(SIDE_LEFT) + cb->get_width() + theme_cache.h_separation; } if (x > style->get_minimum_size().width) { - x -= hseparation; + x -= theme_cache.h_separation; } return x; @@ -1314,9 +1298,7 @@ void TabBar::_ensure_no_over_offset() { return; } - Ref<Texture2D> incr = get_theme_icon(SNAME("increment")); - Ref<Texture2D> decr = get_theme_icon(SNAME("decrement")); - int limit_minus_buttons = get_size().width - incr->get_width() - decr->get_width(); + int limit_minus_buttons = get_size().width - theme_cache.increment_icon->get_width() - theme_cache.decrement_icon->get_width(); int prev_offset = offset; @@ -1359,9 +1341,7 @@ void TabBar::ensure_tab_visible(int p_idx) { return; } - Ref<Texture2D> incr = get_theme_icon(SNAME("increment")); - Ref<Texture2D> decr = get_theme_icon(SNAME("decrement")); - int limit_minus_buttons = get_size().width - incr->get_width() - decr->get_width(); + int limit_minus_buttons = get_size().width - theme_cache.increment_icon->get_width() - theme_cache.decrement_icon->get_width(); int total_w = tabs[max_drawn_tab].ofs_cache - tabs[offset].ofs_cache; for (int i = max_drawn_tab; i <= p_idx; i++) { diff --git a/scene/gui/tab_bar.h b/scene/gui/tab_bar.h index d123385e47..ac4a6a195e 100644 --- a/scene/gui/tab_bar.h +++ b/scene/gui/tab_bar.h @@ -104,6 +104,34 @@ private: bool scroll_to_selected = true; int tabs_rearrange_group = -1; + struct ThemeCache { + int h_separation = 0; + + Ref<StyleBox> tab_unselected_style; + Ref<StyleBox> tab_selected_style; + Ref<StyleBox> tab_disabled_style; + + Ref<Texture2D> increment_icon; + Ref<Texture2D> increment_hl_icon; + Ref<Texture2D> decrement_icon; + Ref<Texture2D> decrement_hl_icon; + Ref<Texture2D> drop_mark_icon; + Color drop_mark_color; + + Ref<Font> font; + int font_size; + int outline_size = 0; + + Color font_selected_color; + Color font_unselected_color; + Color font_disabled_color; + Color font_outline_color; + + Ref<Texture2D> close_icon; + Ref<StyleBox> button_pressed_style; + Ref<StyleBox> button_hl_style; + } theme_cache; + int get_tab_width(int p_idx) const; void _ensure_no_over_offset(); @@ -117,6 +145,7 @@ private: protected: virtual void gui_input(const Ref<InputEvent> &p_event) override; + virtual void _update_theme_item_cache() override; bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp index 3e04ebee6a..f45d132a66 100644 --- a/scene/gui/tab_container.cpp +++ b/scene/gui/tab_container.cpp @@ -60,26 +60,24 @@ void TabContainer::gui_input(const Ref<InputEvent> &p_event) { } // Handle menu button. - Ref<Texture2D> menu = get_theme_icon(SNAME("menu")); - if (is_layout_rtl()) { - if (popup && pos.x < menu->get_width()) { + if (popup && pos.x < theme_cache.menu_icon->get_width()) { emit_signal(SNAME("pre_popup_pressed")); Vector2 popup_pos = get_screen_position(); - popup_pos.y += menu->get_height(); + popup_pos.y += theme_cache.menu_icon->get_height(); popup->set_position(popup_pos); popup->popup(); return; } } else { - if (popup && pos.x > size.width - menu->get_width()) { + if (popup && pos.x > size.width - theme_cache.menu_icon->get_width()) { emit_signal(SNAME("pre_popup_pressed")); Vector2 popup_pos = get_screen_position(); popup_pos.x += size.width - popup->get_size().width; - popup_pos.y += menu->get_height(); + popup_pos.y += theme_cache.menu_icon->get_height(); popup->set_position(popup_pos); popup->popup(); @@ -103,10 +101,9 @@ void TabContainer::gui_input(const Ref<InputEvent> &p_event) { return; } - Ref<Texture2D> menu = get_theme_icon(SNAME("menu")); if (popup) { if (is_layout_rtl()) { - if (pos.x <= menu->get_width()) { + if (pos.x <= theme_cache.menu_icon->get_width()) { if (!menu_hovered) { menu_hovered = true; queue_redraw(); @@ -117,7 +114,7 @@ void TabContainer::gui_input(const Ref<InputEvent> &p_event) { queue_redraw(); } } else { - if (pos.x >= size.width - menu->get_width()) { + if (pos.x >= size.width - theme_cache.menu_icon->get_width()) { if (!menu_hovered) { menu_hovered = true; queue_redraw(); @@ -136,6 +133,41 @@ void TabContainer::gui_input(const Ref<InputEvent> &p_event) { } } +void TabContainer::_update_theme_item_cache() { + Container::_update_theme_item_cache(); + + theme_cache.side_margin = get_theme_constant(SNAME("side_margin")); + + theme_cache.panel_style = get_theme_stylebox(SNAME("panel")); + theme_cache.tabbar_style = get_theme_stylebox(SNAME("tabbar_background")); + + theme_cache.menu_icon = get_theme_icon(SNAME("menu")); + theme_cache.menu_hl_icon = get_theme_icon(SNAME("menu_highlight")); + + // TabBar overrides. + theme_cache.icon_separation = get_theme_constant(SNAME("icon_separation")); + theme_cache.outline_size = get_theme_constant(SNAME("outline_size")); + + theme_cache.tab_unselected_style = get_theme_stylebox(SNAME("tab_unselected")); + theme_cache.tab_selected_style = get_theme_stylebox(SNAME("tab_selected")); + theme_cache.tab_disabled_style = get_theme_stylebox(SNAME("tab_disabled")); + + theme_cache.increment_icon = get_theme_icon(SNAME("increment")); + theme_cache.increment_hl_icon = get_theme_icon(SNAME("increment_highlight")); + theme_cache.decrement_icon = get_theme_icon(SNAME("decrement")); + theme_cache.decrement_hl_icon = get_theme_icon(SNAME("decrement_highlight")); + theme_cache.drop_mark_icon = get_theme_icon(SNAME("drop_mark")); + theme_cache.drop_mark_color = get_theme_color(SNAME("drop_mark_color")); + + theme_cache.font_selected_color = get_theme_color(SNAME("font_selected_color")); + theme_cache.font_unselected_color = get_theme_color(SNAME("font_unselected_color")); + theme_cache.font_disabled_color = get_theme_color(SNAME("font_disabled_color")); + theme_cache.font_outline_color = get_theme_color(SNAME("font_outline_color")); + + theme_cache.tab_font = get_theme_font(SNAME("font")); + theme_cache.tab_font_size = get_theme_font_size(SNAME("font_size")); +} + void TabContainer::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { @@ -155,31 +187,26 @@ void TabContainer::_notification(int p_what) { Size2 size = get_size(); // Draw only the tab area if the header is hidden. - Ref<StyleBox> panel = get_theme_stylebox(SNAME("panel")); if (!tabs_visible) { - panel->draw(canvas, Rect2(0, 0, size.width, size.height)); + theme_cache.panel_style->draw(canvas, Rect2(0, 0, size.width, size.height)); return; } int header_height = _get_top_margin(); // Draw background for the tabbar. - Ref<StyleBox> tabbar_background = get_theme_stylebox(SNAME("tabbar_background")); - tabbar_background->draw(canvas, Rect2(0, 0, size.width, header_height)); + theme_cache.tabbar_style->draw(canvas, Rect2(0, 0, size.width, header_height)); // Draw the background for the tab's content. - panel->draw(canvas, Rect2(0, header_height, size.width, size.height - header_height)); + theme_cache.panel_style->draw(canvas, Rect2(0, header_height, size.width, size.height - header_height)); // Draw the popup menu. if (get_popup()) { - Ref<Texture2D> menu = get_theme_icon(SNAME("menu")); - Ref<Texture2D> menu_hl = get_theme_icon(SNAME("menu_highlight")); - - int x = is_layout_rtl() ? 0 : get_size().width - menu->get_width(); + int x = is_layout_rtl() ? 0 : get_size().width - theme_cache.menu_icon->get_width(); if (menu_hovered) { - menu_hl->draw(get_canvas_item(), Point2(x, (header_height - menu_hl->get_height()) / 2)); + theme_cache.menu_hl_icon->draw(get_canvas_item(), Point2(x, (header_height - theme_cache.menu_hl_icon->get_height()) / 2)); } else { - menu->draw(get_canvas_item(), Point2(x, (header_height - menu->get_height()) / 2)); + theme_cache.menu_icon->draw(get_canvas_item(), Point2(x, (header_height - theme_cache.menu_icon->get_height()) / 2)); } } } break; @@ -198,23 +225,27 @@ void TabContainer::_on_theme_changed() { return; } - tab_bar->add_theme_style_override(SNAME("tab_unselected"), get_theme_stylebox(SNAME("tab_unselected"))); - tab_bar->add_theme_style_override(SNAME("tab_selected"), get_theme_stylebox(SNAME("tab_selected"))); - tab_bar->add_theme_style_override(SNAME("tab_disabled"), get_theme_stylebox(SNAME("tab_disabled"))); - tab_bar->add_theme_icon_override(SNAME("increment"), get_theme_icon(SNAME("increment"))); - tab_bar->add_theme_icon_override(SNAME("increment_highlight"), get_theme_icon(SNAME("increment_highlight"))); - tab_bar->add_theme_icon_override(SNAME("decrement"), get_theme_icon(SNAME("decrement"))); - tab_bar->add_theme_icon_override(SNAME("decrement_highlight"), get_theme_icon(SNAME("decrement_highlight"))); - tab_bar->add_theme_icon_override(SNAME("drop_mark"), get_theme_icon(SNAME("drop_mark"))); - tab_bar->add_theme_color_override(SNAME("drop_mark_color"), get_theme_color(SNAME("drop_mark_color"))); - tab_bar->add_theme_color_override(SNAME("font_selected_color"), get_theme_color(SNAME("font_selected_color"))); - tab_bar->add_theme_color_override(SNAME("font_unselected_color"), get_theme_color(SNAME("font_unselected_color"))); - tab_bar->add_theme_color_override(SNAME("font_disabled_color"), get_theme_color(SNAME("font_disabled_color"))); - tab_bar->add_theme_color_override(SNAME("font_outline_color"), get_theme_color(SNAME("font_outline_color"))); - tab_bar->add_theme_font_override(SNAME("font"), get_theme_font(SNAME("font"))); - tab_bar->add_theme_font_size_override(SNAME("font_size"), get_theme_font_size(SNAME("font_size"))); - tab_bar->add_theme_constant_override(SNAME("h_separation"), get_theme_constant(SNAME("icon_separation"))); - tab_bar->add_theme_constant_override(SNAME("outline_size"), get_theme_constant(SNAME("outline_size"))); + tab_bar->add_theme_style_override(SNAME("tab_unselected"), theme_cache.tab_unselected_style); + tab_bar->add_theme_style_override(SNAME("tab_selected"), theme_cache.tab_selected_style); + tab_bar->add_theme_style_override(SNAME("tab_disabled"), theme_cache.tab_disabled_style); + + tab_bar->add_theme_icon_override(SNAME("increment"), theme_cache.increment_icon); + tab_bar->add_theme_icon_override(SNAME("increment_highlight"), theme_cache.increment_hl_icon); + tab_bar->add_theme_icon_override(SNAME("decrement"), theme_cache.decrement_icon); + tab_bar->add_theme_icon_override(SNAME("decrement_highlight"), theme_cache.decrement_hl_icon); + tab_bar->add_theme_icon_override(SNAME("drop_mark"), theme_cache.drop_mark_icon); + tab_bar->add_theme_color_override(SNAME("drop_mark_color"), theme_cache.drop_mark_color); + + tab_bar->add_theme_color_override(SNAME("font_selected_color"), theme_cache.font_selected_color); + tab_bar->add_theme_color_override(SNAME("font_unselected_color"), theme_cache.font_unselected_color); + tab_bar->add_theme_color_override(SNAME("font_disabled_color"), theme_cache.font_disabled_color); + tab_bar->add_theme_color_override(SNAME("font_outline_color"), theme_cache.font_outline_color); + + tab_bar->add_theme_font_override(SNAME("font"), theme_cache.tab_font); + tab_bar->add_theme_font_size_override(SNAME("font_size"), theme_cache.tab_font_size); + + tab_bar->add_theme_constant_override(SNAME("h_separation"), theme_cache.icon_separation); + tab_bar->add_theme_constant_override(SNAME("outline_size"), theme_cache.outline_size); _update_margins(); if (get_tab_count() > 0) { @@ -228,7 +259,6 @@ void TabContainer::_on_theme_changed() { } void TabContainer::_repaint() { - Ref<StyleBox> sb = get_theme_stylebox(SNAME("panel")); Vector<Control *> controls = _get_tab_controls(); int current = get_current_tab(); @@ -243,10 +273,10 @@ void TabContainer::_repaint() { c->set_offset(SIDE_TOP, _get_top_margin()); } - c->set_offset(SIDE_TOP, c->get_offset(SIDE_TOP) + sb->get_margin(SIDE_TOP)); - c->set_offset(SIDE_LEFT, c->get_offset(SIDE_LEFT) + sb->get_margin(SIDE_LEFT)); - c->set_offset(SIDE_RIGHT, c->get_offset(SIDE_RIGHT) - sb->get_margin(SIDE_RIGHT)); - c->set_offset(SIDE_BOTTOM, c->get_offset(SIDE_BOTTOM) - sb->get_margin(SIDE_BOTTOM)); + c->set_offset(SIDE_TOP, c->get_offset(SIDE_TOP) + theme_cache.panel_style->get_margin(SIDE_TOP)); + c->set_offset(SIDE_LEFT, c->get_offset(SIDE_LEFT) + theme_cache.panel_style->get_margin(SIDE_LEFT)); + c->set_offset(SIDE_RIGHT, c->get_offset(SIDE_RIGHT) - theme_cache.panel_style->get_margin(SIDE_RIGHT)); + c->set_offset(SIDE_BOTTOM, c->get_offset(SIDE_BOTTOM) - theme_cache.panel_style->get_margin(SIDE_BOTTOM)); } else { c->hide(); } @@ -256,8 +286,7 @@ void TabContainer::_repaint() { } void TabContainer::_update_margins() { - int menu_width = get_theme_icon(SNAME("menu"))->get_width(); - int side_margin = get_theme_constant(SNAME("side_margin")); + int menu_width = theme_cache.menu_icon->get_width(); // Directly check for validity, to avoid errors when quitting. bool has_popup = popup_obj_id.is_valid(); @@ -271,7 +300,7 @@ void TabContainer::_update_margins() { switch (get_tab_alignment()) { case TabBar::ALIGNMENT_LEFT: { - tab_bar->set_offset(SIDE_LEFT, side_margin); + tab_bar->set_offset(SIDE_LEFT, theme_cache.side_margin); tab_bar->set_offset(SIDE_RIGHT, has_popup ? -menu_width : 0); } break; @@ -293,10 +322,10 @@ void TabContainer::_update_margins() { int total_tabs_width = last_tab_rect.position.x - first_tab_pos + last_tab_rect.size.width; // Calculate if all the tabs would still fit if the margin was present. - if (get_clip_tabs() && (tab_bar->get_offset_buttons_visible() || (get_tab_count() > 1 && (total_tabs_width + side_margin) > get_size().width))) { + if (get_clip_tabs() && (tab_bar->get_offset_buttons_visible() || (get_tab_count() > 1 && (total_tabs_width + theme_cache.side_margin) > get_size().width))) { tab_bar->set_offset(SIDE_RIGHT, has_popup ? -menu_width : 0); } else { - tab_bar->set_offset(SIDE_RIGHT, -side_margin); + tab_bar->set_offset(SIDE_RIGHT, -theme_cache.side_margin); } } break; @@ -798,13 +827,12 @@ Size2 TabContainer::get_minimum_size() const { if (!get_clip_tabs()) { if (get_popup()) { - ms.x += get_theme_icon(SNAME("menu"))->get_width(); + ms.x += theme_cache.menu_icon->get_width(); } - int side_margin = get_theme_constant(SNAME("side_margin")); - if (side_margin > 0 && get_tab_alignment() != TabBar::ALIGNMENT_CENTER && + if (theme_cache.side_margin > 0 && get_tab_alignment() != TabBar::ALIGNMENT_CENTER && (get_tab_alignment() != TabBar::ALIGNMENT_RIGHT || !get_popup())) { - ms.x += side_margin; + ms.x += theme_cache.side_margin; } } } @@ -824,7 +852,7 @@ Size2 TabContainer::get_minimum_size() const { } ms.y += max_control_height; - Size2 panel_ms = get_theme_stylebox(SNAME("panel"))->get_minimum_size(); + Size2 panel_ms = theme_cache.panel_style->get_minimum_size(); ms.x = MAX(ms.x, panel_ms.x); ms.y += panel_ms.y; diff --git a/scene/gui/tab_container.h b/scene/gui/tab_container.h index 60c8130939..b552aa459b 100644 --- a/scene/gui/tab_container.h +++ b/scene/gui/tab_container.h @@ -48,6 +48,39 @@ class TabContainer : public Container { bool theme_changing = false; Node *child_removing = nullptr; + struct ThemeCache { + int side_margin = 0; + + Ref<StyleBox> panel_style; + Ref<StyleBox> tabbar_style; + + Ref<Texture2D> menu_icon; + Ref<Texture2D> menu_hl_icon; + + // TabBar overrides. + int icon_separation = 0; + int outline_size = 0; + + Ref<StyleBox> tab_unselected_style; + Ref<StyleBox> tab_selected_style; + Ref<StyleBox> tab_disabled_style; + + Ref<Texture2D> increment_icon; + Ref<Texture2D> increment_hl_icon; + Ref<Texture2D> decrement_icon; + Ref<Texture2D> decrement_hl_icon; + Ref<Texture2D> drop_mark_icon; + Color drop_mark_color; + + Color font_selected_color; + Color font_unselected_color; + Color font_disabled_color; + Color font_outline_color; + + Ref<Font> tab_font; + int tab_font_size; + } theme_cache; + int _get_top_margin() const; Vector<Control *> _get_tab_controls() const; void _on_theme_changed(); @@ -65,6 +98,8 @@ class TabContainer : public Container { protected: virtual void gui_input(const Ref<InputEvent> &p_event) override; + virtual void _update_theme_item_cache() override; + void _notification(int p_what); virtual void add_child_notify(Node *p_child) override; virtual void move_child_notify(Node *p_child) override; diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 95338c7b8c..f93591d8c4 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -4786,6 +4786,9 @@ void TextEdit::add_gutter(int p_at) { } text.add_gutter(p_at); + + _update_gutter_width(); + emit_signal(SNAME("gutter_added")); queue_redraw(); } @@ -4796,6 +4799,9 @@ void TextEdit::remove_gutter(int p_gutter) { gutters.remove_at(p_gutter); text.remove_gutter(p_gutter); + + _update_gutter_width(); + emit_signal(SNAME("gutter_removed")); queue_redraw(); } diff --git a/scene/gui/texture_button.cpp b/scene/gui/texture_button.cpp index e2fd903e0e..2efb6593d3 100644 --- a/scene/gui/texture_button.cpp +++ b/scene/gui/texture_button.cpp @@ -112,7 +112,7 @@ bool TextureButton::has_point(const Point2 &p_point) const { } Point2i p = point; - return click_mask->get_bit(p); + return click_mask->get_bitv(p); } return Control::has_point(p_point); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 3c6be008f2..e8164b5728 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -1286,14 +1286,14 @@ Size2 TreeItem::get_minimum_size(int p_column) { // Icon. if (cell.mode == CELL_MODE_CHECK) { - size.width += tree->cache.checked->get_width() + tree->cache.hseparation; + size.width += tree->theme_cache.checked->get_width() + tree->theme_cache.hseparation; } if (cell.icon.is_valid()) { Size2i icon_size = cell.get_icon_size(); if (cell.icon_max_w > 0 && icon_size.width > cell.icon_max_w) { icon_size.width = cell.icon_max_w; } - size.width += icon_size.width + tree->cache.hseparation; + size.width += icon_size.width + tree->theme_cache.hseparation; size.height = MAX(size.height, icon_size.height); } @@ -1301,13 +1301,13 @@ Size2 TreeItem::get_minimum_size(int p_column) { for (int i = 0; i < cell.buttons.size(); i++) { Ref<Texture2D> texture = cell.buttons[i].texture; if (texture.is_valid()) { - Size2 button_size = texture->get_size() + tree->cache.button_pressed->get_minimum_size(); + Size2 button_size = texture->get_size() + tree->theme_cache.button_pressed->get_minimum_size(); size.width += button_size.width; size.height = MAX(size.height, button_size.height); } } if (cell.buttons.size() >= 2) { - size.width += (cell.buttons.size() - 1) * tree->cache.button_margin; + size.width += (cell.buttons.size() - 1) * tree->theme_cache.button_margin; } cells.write[p_column].cached_minimum_size = size; @@ -1535,68 +1535,66 @@ TreeItem::~TreeItem() { /**********************************************/ /**********************************************/ -void Tree::update_cache() { - cache.font = get_theme_font(SNAME("font")); - cache.font_size = get_theme_font_size(SNAME("font_size")); - cache.tb_font = get_theme_font(SNAME("title_button_font")); - cache.tb_font_size = get_theme_font_size(SNAME("title_button_font_size")); - cache.bg = get_theme_stylebox(SNAME("bg")); - cache.selected = get_theme_stylebox(SNAME("selected")); - cache.selected_focus = get_theme_stylebox(SNAME("selected_focus")); - cache.cursor = get_theme_stylebox(SNAME("cursor")); - cache.cursor_unfocus = get_theme_stylebox(SNAME("cursor_unfocused")); - cache.button_pressed = get_theme_stylebox(SNAME("button_pressed")); - - cache.checked = get_theme_icon(SNAME("checked")); - cache.unchecked = get_theme_icon(SNAME("unchecked")); - cache.indeterminate = get_theme_icon(SNAME("indeterminate")); - if (is_layout_rtl()) { - cache.arrow_collapsed = get_theme_icon(SNAME("arrow_collapsed_mirrored")); - } else { - cache.arrow_collapsed = get_theme_icon(SNAME("arrow_collapsed")); - } - cache.arrow = get_theme_icon(SNAME("arrow")); - cache.select_arrow = get_theme_icon(SNAME("select_arrow")); - cache.updown = get_theme_icon(SNAME("updown")); - - cache.custom_button = get_theme_stylebox(SNAME("custom_button")); - cache.custom_button_hover = get_theme_stylebox(SNAME("custom_button_hover")); - cache.custom_button_pressed = get_theme_stylebox(SNAME("custom_button_pressed")); - cache.custom_button_font_highlight = get_theme_color(SNAME("custom_button_font_highlight")); - - cache.font_color = get_theme_color(SNAME("font_color")); - cache.font_selected_color = get_theme_color(SNAME("font_selected_color")); - cache.drop_position_color = get_theme_color(SNAME("drop_position_color")); - cache.hseparation = get_theme_constant(SNAME("h_separation")); - cache.vseparation = get_theme_constant(SNAME("v_separation")); - cache.item_margin = get_theme_constant(SNAME("item_margin")); - cache.button_margin = get_theme_constant(SNAME("button_margin")); - - cache.font_outline_color = get_theme_color(SNAME("font_outline_color")); - cache.font_outline_size = get_theme_constant(SNAME("outline_size")); - - cache.draw_guides = get_theme_constant(SNAME("draw_guides")); - cache.guide_color = get_theme_color(SNAME("guide_color")); - cache.draw_relationship_lines = get_theme_constant(SNAME("draw_relationship_lines")); - cache.relationship_line_width = get_theme_constant(SNAME("relationship_line_width")); - cache.parent_hl_line_width = get_theme_constant(SNAME("parent_hl_line_width")); - cache.children_hl_line_width = get_theme_constant(SNAME("children_hl_line_width")); - cache.parent_hl_line_margin = get_theme_constant(SNAME("parent_hl_line_margin")); - cache.relationship_line_color = get_theme_color(SNAME("relationship_line_color")); - cache.parent_hl_line_color = get_theme_color(SNAME("parent_hl_line_color")); - cache.children_hl_line_color = get_theme_color(SNAME("children_hl_line_color")); - - cache.scroll_border = get_theme_constant(SNAME("scroll_border")); - cache.scroll_speed = get_theme_constant(SNAME("scroll_speed")); - - cache.title_button = get_theme_stylebox(SNAME("title_button_normal")); - cache.title_button_pressed = get_theme_stylebox(SNAME("title_button_pressed")); - cache.title_button_hover = get_theme_stylebox(SNAME("title_button_hover")); - cache.title_button_color = get_theme_color(SNAME("title_button_color")); - - cache.base_scale = get_theme_default_base_scale(); - - v_scroll->set_custom_step(cache.font->get_height(cache.font_size)); +void Tree::_update_theme_item_cache() { + Control::_update_theme_item_cache(); + + theme_cache.font = get_theme_font(SNAME("font")); + theme_cache.font_size = get_theme_font_size(SNAME("font_size")); + theme_cache.tb_font = get_theme_font(SNAME("title_button_font")); + theme_cache.tb_font_size = get_theme_font_size(SNAME("title_button_font_size")); + theme_cache.bg = get_theme_stylebox(SNAME("bg")); + theme_cache.bg_focus = get_theme_stylebox(SNAME("bg_focus")); + theme_cache.selected = get_theme_stylebox(SNAME("selected")); + theme_cache.selected_focus = get_theme_stylebox(SNAME("selected_focus")); + theme_cache.cursor = get_theme_stylebox(SNAME("cursor")); + theme_cache.cursor_unfocus = get_theme_stylebox(SNAME("cursor_unfocused")); + theme_cache.button_pressed = get_theme_stylebox(SNAME("button_pressed")); + + theme_cache.checked = get_theme_icon(SNAME("checked")); + theme_cache.unchecked = get_theme_icon(SNAME("unchecked")); + theme_cache.indeterminate = get_theme_icon(SNAME("indeterminate")); + theme_cache.arrow = get_theme_icon(SNAME("arrow")); + theme_cache.arrow_collapsed = get_theme_icon(SNAME("arrow_collapsed")); + theme_cache.arrow_collapsed_mirrored = get_theme_icon(SNAME("arrow_collapsed_mirrored")); + theme_cache.select_arrow = get_theme_icon(SNAME("select_arrow")); + theme_cache.updown = get_theme_icon(SNAME("updown")); + + theme_cache.custom_button = get_theme_stylebox(SNAME("custom_button")); + theme_cache.custom_button_hover = get_theme_stylebox(SNAME("custom_button_hover")); + theme_cache.custom_button_pressed = get_theme_stylebox(SNAME("custom_button_pressed")); + theme_cache.custom_button_font_highlight = get_theme_color(SNAME("custom_button_font_highlight")); + + theme_cache.font_color = get_theme_color(SNAME("font_color")); + theme_cache.font_selected_color = get_theme_color(SNAME("font_selected_color")); + theme_cache.drop_position_color = get_theme_color(SNAME("drop_position_color")); + theme_cache.hseparation = get_theme_constant(SNAME("h_separation")); + theme_cache.vseparation = get_theme_constant(SNAME("v_separation")); + theme_cache.item_margin = get_theme_constant(SNAME("item_margin")); + theme_cache.button_margin = get_theme_constant(SNAME("button_margin")); + + theme_cache.font_outline_color = get_theme_color(SNAME("font_outline_color")); + theme_cache.font_outline_size = get_theme_constant(SNAME("outline_size")); + + theme_cache.draw_guides = get_theme_constant(SNAME("draw_guides")); + theme_cache.guide_color = get_theme_color(SNAME("guide_color")); + theme_cache.draw_relationship_lines = get_theme_constant(SNAME("draw_relationship_lines")); + theme_cache.relationship_line_width = get_theme_constant(SNAME("relationship_line_width")); + theme_cache.parent_hl_line_width = get_theme_constant(SNAME("parent_hl_line_width")); + theme_cache.children_hl_line_width = get_theme_constant(SNAME("children_hl_line_width")); + theme_cache.parent_hl_line_margin = get_theme_constant(SNAME("parent_hl_line_margin")); + theme_cache.relationship_line_color = get_theme_color(SNAME("relationship_line_color")); + theme_cache.parent_hl_line_color = get_theme_color(SNAME("parent_hl_line_color")); + theme_cache.children_hl_line_color = get_theme_color(SNAME("children_hl_line_color")); + + theme_cache.scroll_border = get_theme_constant(SNAME("scroll_border")); + theme_cache.scroll_speed = get_theme_constant(SNAME("scroll_speed")); + + 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")); + theme_cache.title_button_color = get_theme_color(SNAME("title_button_color")); + + theme_cache.base_scale = get_theme_default_base_scale(); } int Tree::compute_item_height(TreeItem *p_item) const { @@ -1604,7 +1602,7 @@ int Tree::compute_item_height(TreeItem *p_item) const { return 0; } - ERR_FAIL_COND_V(cache.font.is_null(), 0); + ERR_FAIL_COND_V(theme_cache.font.is_null(), 0); int height = 0; for (int i = 0; i < columns.size(); i++) { @@ -1622,7 +1620,7 @@ int Tree::compute_item_height(TreeItem *p_item) const { switch (p_item->cells[i].mode) { case TreeItem::CELL_MODE_CHECK: { - int check_icon_h = cache.checked->get_height(); + int check_icon_h = theme_cache.checked->get_height(); if (height < check_icon_h) { height = check_icon_h; } @@ -1642,7 +1640,7 @@ int Tree::compute_item_height(TreeItem *p_item) const { } } if (p_item->cells[i].mode == TreeItem::CELL_MODE_CUSTOM && p_item->cells[i].custom_button) { - height += cache.custom_button->get_minimum_size().height; + height += theme_cache.custom_button->get_minimum_size().height; } } break; @@ -1655,7 +1653,7 @@ int Tree::compute_item_height(TreeItem *p_item) const { height = item_min_height; } - height += cache.vseparation; + height += theme_cache.vseparation; return height; } @@ -1665,7 +1663,7 @@ int Tree::get_item_height(TreeItem *p_item) const { return 0; } int height = compute_item_height(p_item); - height += cache.vseparation; + height += theme_cache.vseparation; if (!p_item->collapsed) { /* if not collapsed, check the children */ @@ -1682,7 +1680,7 @@ int Tree::get_item_height(TreeItem *p_item) const { } void Tree::draw_item_rect(TreeItem::Cell &p_cell, const Rect2i &p_rect, const Color &p_color, const Color &p_icon_color, int p_ol_size, const Color &p_ol_color) { - ERR_FAIL_COND(cache.font.is_null()); + ERR_FAIL_COND(theme_cache.font.is_null()); Rect2i rect = p_rect; Size2 ts = p_cell.text_buf->get_size(); @@ -1694,7 +1692,7 @@ void Tree::draw_item_rect(TreeItem::Cell &p_cell, const Rect2i &p_rect, const Co if (p_cell.icon_max_w > 0 && bmsize.width > p_cell.icon_max_w) { bmsize.width = p_cell.icon_max_w; } - w += bmsize.width + cache.hseparation; + w += bmsize.width + theme_cache.hseparation; if (rect.size.width > 0 && (w + ts.width) > rect.size.width) { ts.width = rect.size.width - w; } @@ -1728,8 +1726,8 @@ void Tree::draw_item_rect(TreeItem::Cell &p_cell, const Rect2i &p_rect, const Co p_cell.text_buf->draw_outline(ci, draw_pos, p_ol_size, p_ol_color); } p_cell.text_buf->draw(ci, draw_pos, p_color); - rect.position.x += ts.width + cache.hseparation; - rect.size.x -= ts.width + cache.hseparation; + rect.position.x += ts.width + theme_cache.hseparation; + rect.size.x -= ts.width + theme_cache.hseparation; } if (!p_cell.icon.is_null()) { @@ -1741,8 +1739,8 @@ void Tree::draw_item_rect(TreeItem::Cell &p_cell, const Rect2i &p_rect, const Co } p_cell.draw_icon(ci, rect.position + Size2i(0, Math::floor((real_t)(rect.size.y - bmsize.y) / 2)), bmsize, p_icon_color); - rect.position.x += bmsize.x + cache.hseparation; - rect.size.x -= bmsize.x + cache.hseparation; + rect.position.x += bmsize.x + theme_cache.hseparation; + rect.size.x -= bmsize.x + theme_cache.hseparation; } if (!rtl) { @@ -1764,7 +1762,7 @@ void Tree::update_column(int p_col) { columns.write[p_col].text_buf->set_direction((TextServer::Direction)columns[p_col].text_direction); } - columns.write[p_col].text_buf->add_string(columns[p_col].title, cache.font, cache.font_size, columns[p_col].language); + columns.write[p_col].text_buf->add_string(columns[p_col].title, theme_cache.font, theme_cache.font_size, columns[p_col].language); } void Tree::update_item_cell(TreeItem *p_item, int p_col) { @@ -1813,14 +1811,14 @@ void Tree::update_item_cell(TreeItem *p_item, int p_col) { if (p_item->cells[p_col].custom_font.is_valid()) { font = p_item->cells[p_col].custom_font; } else { - font = cache.font; + font = theme_cache.font; } int font_size; if (p_item->cells[p_col].custom_font_size > 0) { font_size = p_item->cells[p_col].custom_font_size; } else { - font_size = cache.font_size; + font_size = theme_cache.font_size; } p_item->cells.write[p_col].text_buf->add_string(valtext, font, font_size, p_item->cells[p_col].language); TS->shaped_text_set_bidi_override(p_item->cells[p_col].text_buf->get_rid(), structured_text_parser(p_item->cells[p_col].st_parser, p_item->cells[p_col].st_args, valtext)); @@ -1840,7 +1838,7 @@ void Tree::update_item_cache(TreeItem *p_item) { } int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 &p_draw_size, TreeItem *p_item) { - if (p_pos.y - cache.offset.y > (p_draw_size.height)) { + if (p_pos.y - theme_cache.offset.y > (p_draw_size.height)) { return -1; //draw no more! } @@ -1856,18 +1854,18 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 bool rtl = cache.rtl; /* Calculate height of the label part */ - label_h += cache.vseparation; + label_h += theme_cache.vseparation; /* Draw label, if height fits */ bool skip = (p_item == root && hide_root); - if (!skip && (p_pos.y + label_h - cache.offset.y) > 0) { + if (!skip && (p_pos.y + label_h - theme_cache.offset.y) > 0) { // Draw separation. - ERR_FAIL_COND_V(cache.font.is_null(), -1); + ERR_FAIL_COND_V(theme_cache.font.is_null(), -1); - int ofs = p_pos.x + ((p_item->disable_folding || hide_folding) ? cache.hseparation : cache.item_margin); + int ofs = p_pos.x + ((p_item->disable_folding || hide_folding) ? theme_cache.hseparation : theme_cache.item_margin); int skip2 = 0; for (int i = 0; i < columns.size(); i++) { if (skip2) { @@ -1885,8 +1883,8 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 continue; } } else { - ofs += cache.hseparation; - w -= cache.hseparation; + ofs += theme_cache.hseparation; + w -= theme_cache.hseparation; } if (p_item->cells[i].expand_right) { @@ -1902,10 +1900,10 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 int button_w = 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 + cache.button_pressed->get_minimum_size().width + cache.button_margin; + button_w += b->get_size().width + theme_cache.button_pressed->get_minimum_size().width + theme_cache.button_margin; } - int total_ofs = ofs - cache.offset.x; + 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); @@ -1915,9 +1913,9 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 int bw = 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() + cache.button_pressed->get_minimum_size(); + Size2 s = b->get_size() + theme_cache.button_pressed->get_minimum_size(); - Point2i o = Point2i(ofs + w - s.width, p_pos.y) - cache.offset + p_draw_ofs; + Point2i o = Point2i(ofs + w - s.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. @@ -1925,48 +1923,48 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 if (rtl) { od.x = get_size().width - od.x - s.x; } - cache.button_pressed->draw(get_canvas_item(), Rect2(od.x, od.y, s.width, MAX(s.height, label_h))); + 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 += cache.button_pressed->get_offset(); + 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 + cache.button_margin; - bw += s.width + cache.button_margin; + w -= s.width + theme_cache.button_margin; + bw += s.width + theme_cache.button_margin; } - Rect2i item_rect = Rect2i(Point2i(ofs, p_pos.y) - 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(w, label_h)); Rect2i cell_rect = item_rect; if (i != 0) { - cell_rect.position.x -= cache.hseparation; - cell_rect.size.x += cache.hseparation; + cell_rect.position.x -= theme_cache.hseparation; + cell_rect.size.x += theme_cache.hseparation; } - if (cache.draw_guides) { + if (theme_cache.draw_guides) { Rect2 r = cell_rect; if (rtl) { r.position.x = get_size().width - r.position.x - r.size.x; } - RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(r.position.x, r.position.y + r.size.height), r.position + r.size, cache.guide_color, 1); + RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(r.position.x, r.position.y + r.size.height), r.position + r.size, theme_cache.guide_color, 1); } if (i == 0) { if (p_item->cells[0].selected && select_mode == SELECT_ROW) { - Rect2i row_rect = Rect2i(Point2i(cache.bg->get_margin(SIDE_LEFT), item_rect.position.y), Size2i(get_size().width - cache.bg->get_minimum_size().width, item_rect.size.y)); + Rect2i row_rect = Rect2i(Point2i(theme_cache.bg->get_margin(SIDE_LEFT), item_rect.position.y), Size2i(get_size().width - theme_cache.bg->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)); if (rtl) { row_rect.position.x = get_size().width - row_rect.position.x - row_rect.size.x; } if (has_focus()) { - cache.selected_focus->draw(ci, row_rect); + theme_cache.selected_focus->draw(ci, row_rect); } else { - cache.selected->draw(ci, row_rect); + theme_cache.selected->draw(ci, row_rect); } } } @@ -1982,9 +1980,9 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 } if (p_item->cells[i].selected) { if (has_focus()) { - cache.selected_focus->draw(ci, r); + theme_cache.selected_focus->draw(ci, r); } else { - cache.selected->draw(ci, r); + theme_cache.selected->draw(ci, r); } } } @@ -1996,8 +1994,8 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 r.position.x = p_draw_ofs.x; r.size.x = w + ofs; } else { - r.position.x -= cache.hseparation; - r.size.x += cache.hseparation; + r.position.x -= theme_cache.hseparation; + r.size.x += theme_cache.hseparation; } if (rtl) { r.position.x = get_size().width - r.position.x - r.size.x; @@ -2020,28 +2018,34 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 if (drop_mode_over == p_item) { if (drop_mode_section == 0 || drop_mode_section == -1) { // Line above. - RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x, r.position.y, r.size.x, 1), cache.drop_position_color); + RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x, r.position.y, r.size.x, 1), theme_cache.drop_position_color); } if (drop_mode_section == 0) { // Side lines. - RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x, r.position.y, 1, r.size.y), cache.drop_position_color); - RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x + r.size.x - 1, r.position.y, 1, r.size.y), cache.drop_position_color); + RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x, r.position.y, 1, r.size.y), theme_cache.drop_position_color); + RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x + r.size.x - 1, r.position.y, 1, r.size.y), theme_cache.drop_position_color); } if (drop_mode_section == 0 || (drop_mode_section == 1 && (!p_item->get_first_child() || p_item->is_collapsed()))) { // Line below. - RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x, r.position.y + r.size.y, r.size.x, 1), cache.drop_position_color); + RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x, r.position.y + r.size.y, r.size.x, 1), theme_cache.drop_position_color); } } else if (drop_mode_over == p_item->get_parent()) { if (drop_mode_section == 1 && !p_item->get_prev() /* && !drop_mode_over->is_collapsed() */) { // The drop_mode_over shouldn't ever be collapsed in here, otherwise we would be drawing a child of a collapsed item. // Line above. - RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x, r.position.y, r.size.x, 1), cache.drop_position_color); + RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x, r.position.y, r.size.x, 1), theme_cache.drop_position_color); } } } - Color col = p_item->cells[i].custom_color ? p_item->cells[i].color : get_theme_color(p_item->cells[i].selected ? "font_selected_color" : "font_color"); - Color font_outline_color = cache.font_outline_color; - int outline_size = cache.font_outline_size; + Color col; + if (p_item->cells[i].custom_color) { + col = p_item->cells[i].color; + } else { + col = p_item->cells[i].selected ? theme_cache.font_selected_color : theme_cache.font_color; + } + + Color font_outline_color = theme_cache.font_outline_color; + int outline_size = theme_cache.font_outline_size; Color icon_col = p_item->cells[i].icon_color; if (p_item->cells[i].dirty) { @@ -2061,9 +2065,9 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 draw_item_rect(p_item->cells.write[i], item_rect, col, icon_col, outline_size, font_outline_color); } break; case TreeItem::CELL_MODE_CHECK: { - Ref<Texture2D> checked = cache.checked; - Ref<Texture2D> unchecked = cache.unchecked; - Ref<Texture2D> indeterminate = cache.indeterminate; + Ref<Texture2D> checked = theme_cache.checked; + Ref<Texture2D> unchecked = theme_cache.unchecked; + Ref<Texture2D> indeterminate = theme_cache.indeterminate; Point2i check_ofs = item_rect.position; check_ofs.y += Math::floor((real_t)(item_rect.size.y - checked->get_height()) / 2); @@ -2075,7 +2079,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 unchecked->draw(ci, check_ofs); } - int check_w = checked->get_width() + cache.hseparation; + int check_w = checked->get_width() + theme_cache.hseparation; text_pos.x += check_w; @@ -2091,7 +2095,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 break; } - Ref<Texture2D> downarrow = cache.select_arrow; + Ref<Texture2D> downarrow = theme_cache.select_arrow; int cell_width = item_rect.size.x - downarrow->get_width(); p_item->cells.write[i].text_buf->set_width(cell_width); @@ -2113,7 +2117,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 downarrow->draw(ci, arrow_pos); } else { - Ref<Texture2D> updown = cache.updown; + Ref<Texture2D> updown = theme_cache.updown; int cell_width = item_rect.size.x - updown->get_width(); @@ -2170,7 +2174,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 break; } - Ref<Texture2D> downarrow = cache.select_arrow; + Ref<Texture2D> downarrow = theme_cache.select_arrow; Rect2i ir = item_rect; @@ -2182,16 +2186,16 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 if (p_item->cells[i].custom_button) { if (cache.hover_item == p_item && cache.hover_cell == i) { if (Input::get_singleton()->is_mouse_button_pressed(MouseButton::LEFT)) { - draw_style_box(cache.custom_button_pressed, ir); + draw_style_box(theme_cache.custom_button_pressed, ir); } else { - draw_style_box(cache.custom_button_hover, ir); - col = cache.custom_button_font_highlight; + draw_style_box(theme_cache.custom_button_hover, ir); + col = theme_cache.custom_button_font_highlight; } } else { - draw_style_box(cache.custom_button, ir); + draw_style_box(theme_cache.custom_button, ir); } - ir.size -= cache.custom_button->get_minimum_size(); - ir.position += cache.custom_button->get_offset(); + ir.size -= theme_cache.custom_button->get_minimum_size(); + 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); @@ -2212,9 +2216,9 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 cell_rect.position.x = get_size().width - cell_rect.position.x - cell_rect.size.x; } if (has_focus()) { - cache.cursor->draw(ci, cell_rect); + theme_cache.cursor->draw(ci, cell_rect); } else { - cache.cursor_unfocus->draw(ci, cell_rect); + theme_cache.cursor_unfocus->draw(ci, cell_rect); } } } @@ -2224,13 +2228,17 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 Ref<Texture2D> arrow; if (p_item->collapsed) { - arrow = cache.arrow_collapsed; + if (is_layout_rtl()) { + arrow = theme_cache.arrow_collapsed_mirrored; + } else { + arrow = theme_cache.arrow_collapsed; + } } else { - arrow = cache.arrow; + arrow = theme_cache.arrow; } - Point2 apos = p_pos + Point2i(0, (label_h - arrow->get_height()) / 2) - cache.offset + p_draw_ofs; - apos.x += cache.item_margin - arrow->get_width(); + Point2 apos = p_pos + Point2i(0, (label_h - arrow->get_height()) / 2) - theme_cache.offset + p_draw_ofs; + apos.x += theme_cache.item_margin - arrow->get_width(); if (rtl) { apos.x = get_size().width - apos.x - arrow->get_width(); @@ -2243,7 +2251,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 Point2 children_pos = p_pos; if (!skip) { - children_pos.x += cache.item_margin; + children_pos.x += theme_cache.item_margin; htotal += label_h; children_pos.y += htotal; } @@ -2251,7 +2259,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 if (!p_item->collapsed) { /* if not collapsed, check the children */ TreeItem *c = p_item->first_child; - int base_ofs = children_pos.y - cache.offset.y + p_draw_ofs.y; + int base_ofs = children_pos.y - theme_cache.offset.y + p_draw_ofs.y; int prev_ofs = base_ofs; int prev_hl_ofs = base_ofs; @@ -2262,20 +2270,20 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 } // Draw relationship lines. - if (cache.draw_relationship_lines > 0 && (!hide_root || c->parent != root) && c->is_visible()) { - int root_ofs = children_pos.x + ((p_item->disable_folding || hide_folding) ? cache.hseparation : cache.item_margin); - int parent_ofs = p_pos.x + cache.item_margin; - Point2i root_pos = Point2i(root_ofs, children_pos.y + label_h / 2) - cache.offset + p_draw_ofs; + if (theme_cache.draw_relationship_lines > 0 && (!hide_root || c->parent != root) && c->is_visible()) { + int root_ofs = children_pos.x + ((p_item->disable_folding || hide_folding) ? theme_cache.hseparation : theme_cache.item_margin); + int parent_ofs = p_pos.x + theme_cache.item_margin; + Point2i root_pos = Point2i(root_ofs, children_pos.y + label_h / 2) - theme_cache.offset + p_draw_ofs; if (c->get_visible_child_count() > 0) { - root_pos -= Point2i(cache.arrow->get_width(), 0); + root_pos -= Point2i(theme_cache.arrow->get_width(), 0); } - float line_width = cache.relationship_line_width * Math::round(cache.base_scale); - float parent_line_width = cache.parent_hl_line_width * Math::round(cache.base_scale); - float children_line_width = cache.children_hl_line_width * Math::round(cache.base_scale); + float line_width = theme_cache.relationship_line_width * Math::round(theme_cache.base_scale); + float parent_line_width = theme_cache.parent_hl_line_width * Math::round(theme_cache.base_scale); + float children_line_width = theme_cache.children_hl_line_width * Math::round(theme_cache.base_scale); - Point2i parent_pos = Point2i(parent_ofs - cache.arrow->get_width() / 2, p_pos.y + label_h / 2 + cache.arrow->get_height() / 2) - cache.offset + p_draw_ofs; + Point2i parent_pos = Point2i(parent_ofs - theme_cache.arrow->get_width() / 2, p_pos.y + label_h / 2 + theme_cache.arrow->get_height() / 2) - theme_cache.offset + p_draw_ofs; int more_prev_ofs = 0; @@ -2289,43 +2297,43 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 if (_is_branch_selected(c)) { // If this item or one of its children is selected, we draw the line using parent highlight style. if (htotal >= 0) { - RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + Math::floor(parent_line_width / 2), root_pos.y), cache.parent_hl_line_color, parent_line_width); + RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + Math::floor(parent_line_width / 2), root_pos.y), theme_cache.parent_hl_line_color, parent_line_width); } - RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(parent_line_width / 2)), Point2i(parent_pos.x, prev_hl_ofs), cache.parent_hl_line_color, parent_line_width); + RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(parent_line_width / 2)), Point2i(parent_pos.x, prev_hl_ofs), theme_cache.parent_hl_line_color, parent_line_width); - more_prev_ofs = cache.parent_hl_line_margin; + more_prev_ofs = theme_cache.parent_hl_line_margin; prev_hl_ofs = root_pos.y + Math::floor(parent_line_width / 2); } else if (p_item->is_selected(0)) { // If parent item is selected (but this item is not), we draw the line using children highlight style. // Siblings of the selected branch can be drawn with a slight offset and their vertical line must appear as highlighted. if (_is_sibling_branch_selected(c)) { if (htotal >= 0) { - RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + Math::floor(parent_line_width / 2), root_pos.y), cache.children_hl_line_color, children_line_width); + RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + Math::floor(parent_line_width / 2), root_pos.y), theme_cache.children_hl_line_color, children_line_width); } - RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(parent_line_width / 2)), Point2i(parent_pos.x, prev_hl_ofs), cache.parent_hl_line_color, parent_line_width); + RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(parent_line_width / 2)), Point2i(parent_pos.x, prev_hl_ofs), theme_cache.parent_hl_line_color, parent_line_width); prev_hl_ofs = root_pos.y + Math::floor(parent_line_width / 2); } else { if (htotal >= 0) { - RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + Math::floor(children_line_width / 2), root_pos.y), cache.children_hl_line_color, children_line_width); + RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + Math::floor(children_line_width / 2), root_pos.y), theme_cache.children_hl_line_color, children_line_width); } - RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(children_line_width / 2)), Point2i(parent_pos.x, prev_ofs + Math::floor(children_line_width / 2)), cache.children_hl_line_color, children_line_width); + RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(children_line_width / 2)), Point2i(parent_pos.x, prev_ofs + Math::floor(children_line_width / 2)), theme_cache.children_hl_line_color, children_line_width); } } else { // If nothing of the above is true, we draw the line using normal style. // Siblings of the selected branch can be drawn with a slight offset and their vertical line must appear as highlighted. if (_is_sibling_branch_selected(c)) { if (htotal >= 0) { - RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + cache.parent_hl_line_margin, root_pos.y), cache.relationship_line_color, line_width); + RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + theme_cache.parent_hl_line_margin, root_pos.y), theme_cache.relationship_line_color, line_width); } - RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(parent_line_width / 2)), Point2i(parent_pos.x, prev_hl_ofs), cache.parent_hl_line_color, parent_line_width); + RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(parent_line_width / 2)), Point2i(parent_pos.x, prev_hl_ofs), theme_cache.parent_hl_line_color, parent_line_width); prev_hl_ofs = root_pos.y + Math::floor(parent_line_width / 2); } else { if (htotal >= 0) { - RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + Math::floor(line_width / 2), root_pos.y), cache.relationship_line_color, line_width); + RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + Math::floor(line_width / 2), root_pos.y), theme_cache.relationship_line_color, line_width); } - RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(line_width / 2)), Point2i(parent_pos.x, prev_ofs + Math::floor(line_width / 2)), cache.relationship_line_color, line_width); + RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(line_width / 2)), Point2i(parent_pos.x, prev_ofs + Math::floor(line_width / 2)), theme_cache.relationship_line_color, line_width); } } } @@ -2338,12 +2346,12 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 break; // Last loop done, stop. } - if (cache.draw_relationship_lines == 0) { + if (theme_cache.draw_relationship_lines == 0) { return -1; // No need to draw anymore, full stop. } htotal = -1; - children_pos.y = cache.offset.y + p_draw_size.height; + children_pos.y = theme_cache.offset.y + p_draw_size.height; } else { htotal += child_h; children_pos.y += child_h; @@ -2494,7 +2502,7 @@ Rect2 Tree::search_item_rect(TreeItem *p_from, TreeItem *p_item) { void Tree::_range_click_timeout() { if (range_item_last && !range_drag_enabled && Input::get_singleton()->is_mouse_button_pressed(MouseButton::LEFT)) { - Point2 pos = get_local_mouse_position() - cache.bg->get_offset(); + Point2 pos = get_local_mouse_position() - theme_cache.bg->get_offset(); if (show_column_titles) { pos.y -= _get_title_button_height(); @@ -2512,7 +2520,7 @@ void Tree::_range_click_timeout() { Ref<InputEventMouseButton> mb; mb.instantiate(); - int x_limit = get_size().width - cache.bg->get_minimum_size().width; + int x_limit = get_size().width - theme_cache.bg->get_minimum_size().width; if (h_scroll->is_visible()) { x_limit -= h_scroll->get_minimum_size().width; } @@ -2521,7 +2529,7 @@ void Tree::_range_click_timeout() { propagate_mouse_activated = false; // done from outside, so signal handler can't clear the tree in the middle of emit (which is a common case) blocked++; - propagate_mouse_event(pos + cache.offset, 0, 0, x_limit + cache.offset.width, false, root, MouseButton::LEFT, mb); + propagate_mouse_event(pos + theme_cache.offset, 0, 0, x_limit + theme_cache.offset.width, false, root, MouseButton::LEFT, mb); blocked--; if (range_click_timer->is_one_shot()) { @@ -2550,7 +2558,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int return 0; } - int item_h = compute_item_height(p_item) + cache.vseparation; + int item_h = compute_item_height(p_item) + theme_cache.vseparation; bool skip = (p_item == root && hide_root); @@ -2561,7 +2569,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int return -1; } - if (!p_item->disable_folding && !hide_folding && p_item->first_child && (p_pos.x >= x_ofs && p_pos.x < (x_ofs + cache.item_margin))) { + if (!p_item->disable_folding && !hide_folding && p_item->first_child && (p_pos.x >= x_ofs && p_pos.x < (x_ofs + theme_cache.item_margin))) { p_item->set_collapsed(!p_item->is_collapsed()); return -1; } @@ -2580,7 +2588,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int 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()) { - col_width += cache.hseparation; + col_width += theme_cache.hseparation; col_width += get_column_width(i + plus); plus++; } @@ -2600,16 +2608,16 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int if (col == -1) { return -1; } else if (col == 0) { - int margin = x_ofs + cache.item_margin; //-cache.hseparation; - //int lm = cache.bg->get_margin(SIDE_LEFT); + int margin = x_ofs + theme_cache.item_margin; //-theme_cache.hseparation; + //int lm = theme_cache.bg->get_margin(SIDE_LEFT); col_width -= margin; limit_w -= margin; col_ofs += margin; x -= margin; } else { - col_width -= cache.hseparation; - limit_w -= cache.hseparation; - x -= cache.hseparation; + col_width -= theme_cache.hseparation; + limit_w -= theme_cache.hseparation; + x -= theme_cache.hseparation; } if (!p_item->disable_folding && !hide_folding && !p_item->cells[col].editable && !p_item->cells[col].selectable && p_item->get_first_child()) { @@ -2626,7 +2634,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int int button_w = 0; for (int j = p_item->cells[col].buttons.size() - 1; j >= 0; j--) { Ref<Texture2D> b = p_item->cells[col].buttons[j].texture; - button_w += b->get_size().width + cache.button_pressed->get_minimum_size().width + cache.button_margin; + button_w += b->get_size().width + theme_cache.button_pressed->get_minimum_size().width + theme_cache.button_margin; } col_width = MAX(button_w, MIN(limit_w, col_width)); @@ -2634,7 +2642,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int for (int j = c.buttons.size() - 1; j >= 0; j--) { Ref<Texture2D> b = c.buttons[j].texture; - int w = b->get_size().width + cache.button_pressed->get_minimum_size().width; + int w = b->get_size().width + theme_cache.button_pressed->get_minimum_size().width; if (x > col_width - w) { if (c.buttons[j].disabled) { @@ -2662,7 +2670,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int return -1; } - col_width -= w + cache.button_margin; + col_width -= w + theme_cache.button_margin; } if (p_button == MouseButton::LEFT || (p_button == MouseButton::RIGHT && allow_rmb_select)) { @@ -2742,7 +2750,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int case TreeItem::CELL_MODE_CHECK: { bring_up_editor = false; //checkboxes are not edited with editor if (force_edit_checkbox_only_on_checkbox) { - if (x < cache.checked->get_width()) { + if (x < theme_cache.checked->get_width()) { p_item->set_checked(col, !c.checked); item_edited(col, p_item, p_button); } @@ -2764,7 +2772,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int } popup_menu->set_size(Size2(col_width, 0)); - popup_menu->set_position(get_screen_position() + Point2i(col_ofs, _get_title_button_height() + y_ofs + item_h) - cache.offset); + popup_menu->set_position(get_screen_position() + Point2i(col_ofs, _get_title_button_height() + y_ofs + item_h) - theme_cache.offset); popup_menu->popup(); popup_edited_item = p_item; popup_edited_item_col = col; @@ -2822,9 +2830,9 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int case TreeItem::CELL_MODE_CUSTOM: { edited_item = p_item; edited_col = col; - bool on_arrow = x > col_width - cache.select_arrow->get_width(); + bool on_arrow = x > col_width - theme_cache.select_arrow->get_width(); - custom_popup_rect = Rect2i(get_global_position() + Point2i(col_ofs, _get_title_button_height() + y_ofs + item_h - cache.offset.y), Size2(get_column_width(col), item_h)); + custom_popup_rect = Rect2i(get_global_position() + Point2i(col_ofs, _get_title_button_height() + y_ofs + item_h - theme_cache.offset.y), Size2(get_column_width(col), item_h)); if (on_arrow || !p_item->cells[col].custom_button) { emit_signal(SNAME("custom_popup_edited"), ((bool)(x >= (col_width - item_h / 2)))); @@ -2846,7 +2854,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int popup_pressing_edited_item = p_item; popup_pressing_edited_item_column = col; - pressing_item_rect = Rect2(get_global_position() + Point2i(col_ofs, _get_title_button_height() + y_ofs) - cache.offset, Size2(col_width, item_h)); + pressing_item_rect = Rect2(get_global_position() + Point2i(col_ofs, _get_title_button_height() + y_ofs) - theme_cache.offset, Size2(col_width, item_h)); pressing_for_editor_text = editor_text; pressing_for_editor = true; @@ -2855,8 +2863,8 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int Point2i new_pos = p_pos; if (!skip) { - x_ofs += cache.item_margin; - //new_pos.x-=cache.item_margin; + x_ofs += theme_cache.item_margin; + //new_pos.x-=theme_cache.item_margin; y_ofs += item_h; new_pos.y -= item_h; } @@ -3300,18 +3308,14 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseMotion> mm = p_event; if (mm.is_valid()) { - if (cache.font.is_null()) { // avoid a strange case that may corrupt stuff - update_cache(); - } - - Ref<StyleBox> bg = cache.bg; + Ref<StyleBox> bg = theme_cache.bg; bool rtl = is_layout_rtl(); Point2 pos = mm->get_position(); if (rtl) { pos.x = get_size().width - pos.x; } - pos -= cache.bg->get_offset(); + pos -= theme_cache.bg->get_offset(); Cache::ClickType old_hover = cache.hover_type; int old_index = cache.hover_index; @@ -3321,7 +3325,7 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) { if (show_column_titles) { pos.y -= _get_title_button_height(); if (pos.y < 0) { - pos.x += cache.offset.x; + pos.x += theme_cache.offset.x; int len = 0; for (int i = 0; i < columns.size(); i++) { len += get_column_width(i); @@ -3339,7 +3343,7 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) { if (rtl) { mpos.x = get_size().width - mpos.x; } - mpos -= cache.bg->get_offset(); + mpos -= theme_cache.bg->get_offset(); mpos.y -= _get_title_button_height(); if (mpos.y >= 0) { if (h_scroll->is_visible_in_tree()) { @@ -3430,10 +3434,6 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid()) { - if (cache.font.is_null()) { // avoid a strange case that may corrupt stuff - update_cache(); - } - bool rtl = is_layout_rtl(); if (!mb->is_pressed()) { @@ -3443,12 +3443,12 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) { if (rtl) { pos.x = get_size().width - pos.x; } - pos -= cache.bg->get_offset(); + pos -= theme_cache.bg->get_offset(); if (show_column_titles) { pos.y -= _get_title_button_height(); if (pos.y < 0) { - pos.x += cache.offset.x; + pos.x += theme_cache.offset.x; int len = 0; for (int i = 0; i < columns.size(); i++) { len += get_column_width(i); @@ -3537,7 +3537,7 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) { switch (mb->get_button_index()) { case MouseButton::RIGHT: case MouseButton::LEFT: { - Ref<StyleBox> bg = cache.bg; + Ref<StyleBox> bg = theme_cache.bg; Point2 pos = mb->get_position(); if (rtl) { @@ -3549,7 +3549,7 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) { pos.y -= _get_title_button_height(); if (pos.y < 0) { - pos.x += cache.offset.x; + pos.x += theme_cache.offset.x; int len = 0; for (int i = 0; i < columns.size(); i++) { len += get_column_width(i); @@ -3572,14 +3572,14 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) { pressing_for_editor = false; propagate_mouse_activated = false; - int x_limit = get_size().width - cache.bg->get_minimum_size().width; + int x_limit = get_size().width - theme_cache.bg->get_minimum_size().width; if (h_scroll->is_visible()) { x_limit -= h_scroll->get_minimum_size().width; } cache.rtl = is_layout_rtl(); blocked++; - propagate_mouse_event(pos + cache.offset, 0, 0, x_limit + cache.offset.width, mb->is_double_click(), root, mb->get_button_index(), mb); + propagate_mouse_event(pos + theme_cache.offset, 0, 0, x_limit + theme_cache.offset.width, mb->is_double_click(), root, mb->get_button_index(), mb); blocked--; if (pressing_for_editor) { @@ -3766,7 +3766,7 @@ bool Tree::is_editing() { } Size2 Tree::get_internal_min_size() const { - Size2i size = cache.bg->get_offset(); + Size2i size = theme_cache.bg->get_offset(); if (root) { size.height += get_item_height(root); } @@ -3789,23 +3789,23 @@ void Tree::update_scrollbars() { Size2 hmin = h_scroll->get_combined_minimum_size(); Size2 vmin = v_scroll->get_combined_minimum_size(); - v_scroll->set_begin(Point2(size.width - vmin.width, cache.bg->get_margin(SIDE_TOP))); - v_scroll->set_end(Point2(size.width, size.height - cache.bg->get_margin(SIDE_TOP) - cache.bg->get_margin(SIDE_BOTTOM))); + v_scroll->set_begin(Point2(size.width - vmin.width, theme_cache.bg->get_margin(SIDE_TOP))); + v_scroll->set_end(Point2(size.width, size.height - theme_cache.bg->get_margin(SIDE_TOP) - theme_cache.bg->get_margin(SIDE_BOTTOM))); h_scroll->set_begin(Point2(0, size.height - hmin.height)); h_scroll->set_end(Point2(size.width - vmin.width, size.height)); Size2 internal_min_size = get_internal_min_size(); - bool display_vscroll = internal_min_size.height + cache.bg->get_margin(SIDE_TOP) > size.height; - bool display_hscroll = internal_min_size.width + cache.bg->get_margin(SIDE_LEFT) > size.width; + bool display_vscroll = internal_min_size.height + theme_cache.bg->get_margin(SIDE_TOP) > size.height; + bool display_hscroll = internal_min_size.width + theme_cache.bg->get_margin(SIDE_LEFT) > size.width; for (int i = 0; i < 2; i++) { // Check twice, as both values are dependent on each other. if (display_hscroll) { - display_vscroll = internal_min_size.height + cache.bg->get_margin(SIDE_TOP) + hmin.height > size.height; + display_vscroll = internal_min_size.height + theme_cache.bg->get_margin(SIDE_TOP) + hmin.height > size.height; } if (display_vscroll) { - display_hscroll = internal_min_size.width + cache.bg->get_margin(SIDE_LEFT) + vmin.width > size.width; + display_hscroll = internal_min_size.width + theme_cache.bg->get_margin(SIDE_LEFT) + vmin.width > size.width; } } @@ -3813,29 +3813,29 @@ void Tree::update_scrollbars() { v_scroll->show(); v_scroll->set_max(internal_min_size.height); v_scroll->set_page(size.height - hmin.height - tbh); - cache.offset.y = v_scroll->get_value(); + theme_cache.offset.y = v_scroll->get_value(); } else { v_scroll->hide(); - cache.offset.y = 0; + theme_cache.offset.y = 0; } if (display_hscroll) { h_scroll->show(); h_scroll->set_max(internal_min_size.width); h_scroll->set_page(size.width - vmin.width); - cache.offset.x = h_scroll->get_value(); + theme_cache.offset.x = h_scroll->get_value(); } else { h_scroll->hide(); - cache.offset.x = 0; + theme_cache.offset.x = 0; } } int Tree::_get_title_button_height() const { - ERR_FAIL_COND_V(cache.font.is_null() || cache.title_button.is_null(), 0); + ERR_FAIL_COND_V(theme_cache.font.is_null() || theme_cache.title_button.is_null(), 0); int h = 0; if (show_column_titles) { for (int i = 0; i < columns.size(); i++) { - h = MAX(h, columns[i].text_buf->get_size().y + cache.title_button->get_minimum_size().height); + h = MAX(h, columns[i].text_buf->get_size().y + theme_cache.title_button->get_minimum_size().height); } } return h; @@ -3860,10 +3860,6 @@ void Tree::_notification(int p_what) { drag_touching = false; } break; - case NOTIFICATION_ENTER_TREE: { - update_cache(); - } break; - case NOTIFICATION_DRAG_END: { drop_mode_flags = 0; scrolling = false; @@ -3873,7 +3869,7 @@ void Tree::_notification(int p_what) { case NOTIFICATION_DRAG_BEGIN: { single_select_defer = nullptr; - if (cache.scroll_speed > 0) { + if (theme_cache.scroll_speed > 0) { scrolling = true; set_physics_process_internal(true); } @@ -3917,22 +3913,22 @@ void Tree::_notification(int p_what) { } Point2 mouse_position = get_viewport()->get_mouse_position() - get_global_position(); - if (scrolling && get_rect().grow(cache.scroll_border).has_point(mouse_position)) { + if (scrolling && get_rect().grow(theme_cache.scroll_border).has_point(mouse_position)) { Point2 point; - if ((ABS(mouse_position.x) < ABS(mouse_position.x - get_size().width)) && (ABS(mouse_position.x) < cache.scroll_border)) { - point.x = mouse_position.x - cache.scroll_border; - } else if (ABS(mouse_position.x - get_size().width) < cache.scroll_border) { - point.x = mouse_position.x - (get_size().width - cache.scroll_border); + if ((ABS(mouse_position.x) < ABS(mouse_position.x - get_size().width)) && (ABS(mouse_position.x) < theme_cache.scroll_border)) { + point.x = mouse_position.x - theme_cache.scroll_border; + } else if (ABS(mouse_position.x - get_size().width) < theme_cache.scroll_border) { + point.x = mouse_position.x - (get_size().width - theme_cache.scroll_border); } - if ((ABS(mouse_position.y) < ABS(mouse_position.y - get_size().height)) && (ABS(mouse_position.y) < cache.scroll_border)) { - point.y = mouse_position.y - cache.scroll_border; - } else if (ABS(mouse_position.y - get_size().height) < cache.scroll_border) { - point.y = mouse_position.y - (get_size().height - cache.scroll_border); + if ((ABS(mouse_position.y) < ABS(mouse_position.y - get_size().height)) && (ABS(mouse_position.y) < theme_cache.scroll_border)) { + point.y = mouse_position.y - theme_cache.scroll_border; + } else if (ABS(mouse_position.y - get_size().height) < theme_cache.scroll_border) { + point.y = mouse_position.y - (get_size().height - theme_cache.scroll_border); } - point *= cache.scroll_speed * get_physics_process_delta_time(); + point *= theme_cache.scroll_speed * get_physics_process_delta_time(); point += get_scroll(); h_scroll->set_value(point.x); v_scroll->set_value(point.y); @@ -3940,13 +3936,12 @@ void Tree::_notification(int p_what) { } break; case NOTIFICATION_DRAW: { - update_cache(); + v_scroll->set_custom_step(theme_cache.font->get_height(theme_cache.font_size)); + update_scrollbars(); RID ci = get_canvas_item(); - Ref<StyleBox> bg = cache.bg; - Color font_outline_color = get_theme_color(SNAME("font_outline_color")); - int outline_size = get_theme_constant(SNAME("outline_size")); + Ref<StyleBox> bg = theme_cache.bg; Point2 draw_ofs; draw_ofs += bg->get_offset(); @@ -3970,11 +3965,11 @@ void Tree::_notification(int p_what) { if (show_column_titles) { //title buttons - int ofs2 = cache.bg->get_margin(SIDE_LEFT); + int ofs2 = theme_cache.bg->get_margin(SIDE_LEFT); for (int i = 0; i < columns.size(); i++) { - Ref<StyleBox> sb = (cache.click_type == Cache::CLICK_TITLE && cache.click_index == i) ? cache.title_button_pressed : ((cache.hover_type == Cache::CLICK_TITLE && cache.hover_index == i) ? cache.title_button_hover : cache.title_button); - Ref<Font> f = cache.tb_font; - Rect2 tbrect = Rect2(ofs2 - cache.offset.x, bg->get_margin(SIDE_TOP), get_column_width(i), tbh); + Ref<StyleBox> sb = (cache.click_type == Cache::CLICK_TITLE && cache.click_index == i) ? theme_cache.title_button_pressed : ((cache.hover_type == Cache::CLICK_TITLE && cache.hover_index == i) ? theme_cache.title_button_hover : theme_cache.title_button); + Ref<Font> f = theme_cache.tb_font; + Rect2 tbrect = Rect2(ofs2 - theme_cache.offset.x, bg->get_margin(SIDE_TOP), get_column_width(i), tbh); if (cache.rtl) { tbrect.position.x = get_size().width - tbrect.size.x - tbrect.position.x; } @@ -3985,10 +3980,10 @@ void Tree::_notification(int p_what) { columns.write[i].text_buf->set_width(clip_w); Vector2 text_pos = tbrect.position + Point2i(sb->get_offset().x + (tbrect.size.width - columns[i].text_buf->get_size().x) / 2, (tbrect.size.height - columns[i].text_buf->get_size().y) / 2); - if (outline_size > 0 && font_outline_color.a > 0) { - columns[i].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color); + if (theme_cache.font_outline_size > 0 && theme_cache.font_outline_color.a > 0) { + columns[i].text_buf->draw_outline(ci, text_pos, theme_cache.font_outline_size, theme_cache.font_outline_color); } - columns[i].text_buf->draw(ci, text_pos, cache.title_button_color); + columns[i].text_buf->draw(ci, text_pos, theme_cache.title_button_color); } } @@ -3996,8 +3991,7 @@ void Tree::_notification(int p_what) { // Otherwise, section heading backgrounds can appear to be in front of the focus outline when scrolling. if (has_focus()) { RenderingServer::get_singleton()->canvas_item_add_clip_ignore(ci, true); - const Ref<StyleBox> bg_focus = get_theme_stylebox(SNAME("bg_focus")); - bg_focus->draw(ci, Rect2(Point2(), get_size())); + theme_cache.bg_focus->draw(ci, Rect2(Point2(), get_size())); RenderingServer::get_singleton()->canvas_item_add_clip_ignore(ci, false); } } break; @@ -4005,7 +3999,6 @@ void Tree::_notification(int p_what) { case NOTIFICATION_THEME_CHANGED: case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: case NOTIFICATION_TRANSLATION_CHANGED: { - update_cache(); _update_all(); } break; @@ -4040,7 +4033,7 @@ Size2 Tree::get_minimum_size() const { return Size2(); } else { Vector2 min_size = get_internal_min_size(); - Ref<StyleBox> bg = cache.bg; + Ref<StyleBox> bg = theme_cache.bg; if (bg.is_valid()) { min_size.x += bg->get_margin(SIDE_LEFT) + bg->get_margin(SIDE_RIGHT); min_size.y += bg->get_margin(SIDE_TOP) + bg->get_margin(SIDE_BOTTOM); @@ -4336,7 +4329,7 @@ int Tree::get_column_minimum_width(int p_column) const { // Check if the visible title of the column is wider. if (show_column_titles) { - min_width = MAX(cache.font->get_string_size(columns[p_column].title, HORIZONTAL_ALIGNMENT_LEFT, -1, cache.font_size).width + cache.bg->get_margin(SIDE_LEFT) + cache.bg->get_margin(SIDE_RIGHT), min_width); + min_width = MAX(theme_cache.font->get_string_size(columns[p_column].title, HORIZONTAL_ALIGNMENT_LEFT, -1, theme_cache.font_size).width + theme_cache.bg->get_margin(SIDE_LEFT) + theme_cache.bg->get_margin(SIDE_RIGHT), min_width); } if (!columns[p_column].clip_content) { @@ -4360,9 +4353,9 @@ int Tree::get_column_minimum_width(int p_column) const { // Get the item minimum size. Size2 item_size = item->get_minimum_size(p_column); if (p_column == 0) { - item_size.width += cache.item_margin * depth; + item_size.width += theme_cache.item_margin * depth; } else { - item_size.width += cache.hseparation; + item_size.width += theme_cache.hseparation; } // Check if the item is wider. @@ -4381,7 +4374,7 @@ int Tree::get_column_width(int p_column) const { if (columns[p_column].expand) { int expand_area = get_size().width; - Ref<StyleBox> bg = cache.bg; + Ref<StyleBox> bg = theme_cache.bg; if (bg.is_valid()) { expand_area -= bg->get_margin(SIDE_LEFT) + bg->get_margin(SIDE_RIGHT); @@ -4458,7 +4451,7 @@ int Tree::get_item_offset(TreeItem *p_item) const { ofs += compute_item_height(it); if (it != root || !hide_root) { - ofs += cache.vseparation; + ofs += theme_cache.vseparation; } if (it->first_child && !it->collapsed) { @@ -4489,14 +4482,14 @@ void Tree::ensure_cursor_is_visible() { return; // Nothing under cursor. } - const Size2 area_size = get_size() - cache.bg->get_minimum_size(); + const Size2 area_size = get_size() - theme_cache.bg->get_minimum_size(); int y_offset = get_item_offset(selected_item); if (y_offset != -1) { const int tbh = _get_title_button_height(); y_offset -= tbh; - const int cell_h = compute_item_height(selected_item) + cache.vseparation; + const int cell_h = compute_item_height(selected_item) + theme_cache.vseparation; const int screen_h = area_size.height - h_scroll->get_combined_minimum_size().height - tbh; if (cell_h > screen_h) { // Screen size is too small, maybe it was not resized yet. @@ -4563,7 +4556,7 @@ Rect2 Tree::get_item_rect(TreeItem *p_item, int p_column, int p_button) const { Vector2 ofst = Vector2(r.position.x + r.size.x, r.position.y); for (int j = c.buttons.size() - 1; j >= 0; j--) { Ref<Texture2D> b = c.buttons[j].texture; - Size2 size = b->get_size() + cache.button_pressed->get_minimum_size(); + Size2 size = b->get_size() + theme_cache.button_pressed->get_minimum_size(); ofst.x -= size.x; if (j == p_button) { @@ -4596,9 +4589,6 @@ void Tree::set_column_title(int p_column, const String &p_title) { return; } - if (cache.font.is_null()) { // avoid a strange case that may corrupt stuff - update_cache(); - } columns.write[p_column].title = p_title; update_column(p_column); queue_redraw(); @@ -4660,7 +4650,7 @@ void Tree::scroll_to_item(TreeItem *p_item, bool p_center_on_item) { const real_t tree_height = get_size().y; const Rect2 item_rect = get_item_rect(p_item); const real_t item_y = item_rect.position.y; - const real_t item_height = item_rect.size.y + cache.vseparation; + const real_t item_height = item_rect.size.y + theme_cache.vseparation; if (p_center_on_item) { v_scroll->set_value(item_y - (tree_height - item_height) / 2.0f); @@ -4784,7 +4774,7 @@ TreeItem *Tree::_find_item_at_pos(TreeItem *p_item, const Point2 &p_pos, int &r_ Point2 pos = p_pos; if ((root != p_item || !hide_root) && p_item->is_visible()) { - h = compute_item_height(p_item) + cache.vseparation; + h = compute_item_height(p_item) + theme_cache.vseparation; if (pos.y < h) { if (drop_mode_flags == DROP_MODE_ON_ITEM) { section = 0; @@ -4841,7 +4831,7 @@ int Tree::get_column_at_position(const Point2 &p_pos) const { if (is_layout_rtl()) { pos.x = get_size().width - pos.x; } - pos -= cache.bg->get_offset(); + pos -= theme_cache.bg->get_offset(); pos.y -= _get_title_button_height(); if (pos.y < 0) { return -1; @@ -4871,7 +4861,7 @@ int Tree::get_drop_section_at_position(const Point2 &p_pos) const { if (is_layout_rtl()) { pos.x = get_size().width - pos.x; } - pos -= cache.bg->get_offset(); + pos -= theme_cache.bg->get_offset(); pos.y -= _get_title_button_height(); if (pos.y < 0) { return -100; @@ -4901,7 +4891,7 @@ TreeItem *Tree::get_item_at_position(const Point2 &p_pos) const { if (is_layout_rtl()) { pos.x = get_size().width - pos.x; } - pos -= cache.bg->get_offset(); + pos -= theme_cache.bg->get_offset(); pos.y -= _get_title_button_height(); if (pos.y < 0) { return nullptr; @@ -4928,7 +4918,7 @@ TreeItem *Tree::get_item_at_position(const Point2 &p_pos) const { int Tree::get_button_id_at_position(const Point2 &p_pos) const { if (root) { Point2 pos = p_pos; - pos -= cache.bg->get_offset(); + pos -= theme_cache.bg->get_offset(); pos.y -= _get_title_button_height(); if (pos.y < 0) { return -1; @@ -4954,7 +4944,7 @@ int Tree::get_button_id_at_position(const Point2 &p_pos) const { for (int j = c.buttons.size() - 1; j >= 0; j--) { Ref<Texture2D> b = c.buttons[j].texture; - Size2 size = b->get_size() + cache.button_pressed->get_minimum_size(); + Size2 size = b->get_size() + theme_cache.button_pressed->get_minimum_size(); if (pos.x > col_width - size.width) { return c.buttons[j].id; } @@ -4969,7 +4959,7 @@ int Tree::get_button_id_at_position(const Point2 &p_pos) const { String Tree::get_tooltip(const Point2 &p_pos) const { if (root) { Point2 pos = p_pos; - pos -= cache.bg->get_offset(); + pos -= theme_cache.bg->get_offset(); pos.y -= _get_title_button_height(); if (pos.y < 0) { return Control::get_tooltip(p_pos); @@ -4995,7 +4985,7 @@ String Tree::get_tooltip(const Point2 &p_pos) const { for (int j = c.buttons.size() - 1; j >= 0; j--) { Ref<Texture2D> b = c.buttons[j].texture; - Size2 size = b->get_size() + cache.button_pressed->get_minimum_size(); + Size2 size = b->get_size() + theme_cache.button_pressed->get_minimum_size(); if (pos.x > col_width - size.width) { String tooltip = c.buttons[j].tooltip; if (!tooltip.is_empty()) { @@ -5231,8 +5221,6 @@ Tree::Tree() { set_mouse_filter(MOUSE_FILTER_STOP); set_clip_contents(true); - - update_cache(); } Tree::~Tree() { diff --git a/scene/gui/tree.h b/scene/gui/tree.h index 8eabdd60a1..b4ee686bab 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -482,12 +482,13 @@ private: void propagate_set_columns(TreeItem *p_item); - struct Cache { + struct ThemeCache { Ref<Font> font; Ref<Font> tb_font; int font_size = 0; int tb_font_size = 0; Ref<StyleBox> bg; + Ref<StyleBox> bg_focus; Ref<StyleBox> selected; Ref<StyleBox> selected_focus; Ref<StyleBox> cursor; @@ -505,8 +506,9 @@ private: Ref<Texture2D> checked; Ref<Texture2D> unchecked; Ref<Texture2D> indeterminate; - Ref<Texture2D> arrow_collapsed; Ref<Texture2D> arrow; + Ref<Texture2D> arrow_collapsed; + Ref<Texture2D> arrow_collapsed_mirrored; Ref<Texture2D> select_arrow; Ref<Texture2D> updown; @@ -536,7 +538,9 @@ private: int scroll_border = 0; int scroll_speed = 0; int font_outline_size = 0; + } theme_cache; + struct Cache { enum ClickType { CLICK_NONE, CLICK_TITLE, @@ -559,7 +563,6 @@ private: Point2i text_editor_position; bool rtl = false; - } cache; int _get_title_button_height() const; @@ -572,7 +575,6 @@ private: bool v_scroll_enabled = true; Size2 get_internal_min_size() const; - void update_cache(); void update_scrollbars(); Rect2 search_item_rect(TreeItem *p_from, TreeItem *p_item); @@ -620,6 +622,8 @@ private: bool _scroll(bool p_horizontal, float p_pages); protected: + virtual void _update_theme_item_cache() override; + static void _bind_methods(); public: diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index 61a7600664..65e7ba3e67 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -338,6 +338,7 @@ void CanvasItem::_notification(int p_what) { } if (window) { window->disconnect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &CanvasItem::_window_visibility_changed)); + window = nullptr; } global_invalid = true; parent_visible_in_tree = false; diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp index 4890db995a..214efe432b 100644 --- a/scene/main/canvas_layer.cpp +++ b/scene/main/canvas_layer.cpp @@ -329,14 +329,14 @@ void CanvasLayer::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible"); ADD_GROUP("Transform", ""); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset", PROPERTY_HINT_NONE, "suffix:px"), "set_offset", "get_offset"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation", PROPERTY_HINT_RANGE, "-1080,1080,0.1,or_lesser,or_greater,radians"), "set_rotation", "get_rotation"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation", PROPERTY_HINT_RANGE, "-1080,1080,0.1,or_less,or_greater,radians"), "set_rotation", "get_rotation"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scale", PROPERTY_HINT_LINK), "set_scale", "get_scale"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "transform", PROPERTY_HINT_NONE, "suffix:px"), "set_transform", "get_transform"); ADD_GROUP("", ""); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_viewport", PROPERTY_HINT_RESOURCE_TYPE, "Viewport", PROPERTY_USAGE_NONE), "set_custom_viewport", "get_custom_viewport"); ADD_GROUP("Follow Viewport", "follow_viewport"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "follow_viewport_enabled"), "set_follow_viewport", "is_following_viewport"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "follow_viewport_scale", PROPERTY_HINT_RANGE, "0.001,1000,0.001,or_greater,or_lesser"), "set_follow_viewport_scale", "get_follow_viewport_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "follow_viewport_scale", PROPERTY_HINT_RANGE, "0.001,1000,0.001,or_greater,or_less"), "set_follow_viewport_scale", "get_follow_viewport_scale"); ADD_SIGNAL(MethodInfo("visibility_changed")); } diff --git a/scene/main/multiplayer_peer.cpp b/scene/main/multiplayer_peer.cpp index aad5baccab..9b63118f7c 100644 --- a/scene/main/multiplayer_peer.cpp +++ b/scene/main/multiplayer_peer.cpp @@ -120,19 +120,10 @@ void MultiplayerPeer::_bind_methods() { /*************/ -int MultiplayerPeerExtension::get_available_packet_count() const { - int count; - if (GDVIRTUAL_CALL(_get_available_packet_count, count)) { - return count; - } - WARN_PRINT_ONCE("MultiplayerPeerExtension::_get_available_packet_count is unimplemented!"); - return -1; -} - Error MultiplayerPeerExtension::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { - int err; + Error err; if (GDVIRTUAL_CALL(_get_packet, r_buffer, &r_buffer_size, err)) { - return (Error)err; + return err; } if (GDVIRTUAL_IS_OVERRIDDEN(_get_packet_script)) { if (!GDVIRTUAL_CALL(_get_packet_script, script_buffer)) { @@ -153,9 +144,9 @@ Error MultiplayerPeerExtension::get_packet(const uint8_t **r_buffer, int &r_buff } Error MultiplayerPeerExtension::put_packet(const uint8_t *p_buffer, int p_buffer_size) { - int err; + Error err; if (GDVIRTUAL_CALL(_put_packet, p_buffer, p_buffer_size, err)) { - return (Error)err; + return err; } if (GDVIRTUAL_IS_OVERRIDDEN(_put_packet_script)) { PackedByteArray a; @@ -171,87 +162,6 @@ Error MultiplayerPeerExtension::put_packet(const uint8_t *p_buffer, int p_buffer return FAILED; } -int MultiplayerPeerExtension::get_max_packet_size() const { - int size; - if (GDVIRTUAL_CALL(_get_max_packet_size, size)) { - return size; - } - WARN_PRINT_ONCE("MultiplayerPeerExtension::_get_max_packet_size is unimplemented!"); - return 0; -} - -void MultiplayerPeerExtension::set_transfer_channel(int p_channel) { - if (GDVIRTUAL_CALL(_set_transfer_channel, p_channel)) { - return; - } - MultiplayerPeer::set_transfer_channel(p_channel); -} - -int MultiplayerPeerExtension::get_transfer_channel() const { - int channel; - if (GDVIRTUAL_CALL(_get_transfer_channel, channel)) { - return channel; - } - return MultiplayerPeer::get_transfer_channel(); -} - -void MultiplayerPeerExtension::set_transfer_mode(TransferMode p_mode) { - if (GDVIRTUAL_CALL(_set_transfer_mode, p_mode)) { - return; - } - MultiplayerPeer::set_transfer_mode(p_mode); -} - -MultiplayerPeer::TransferMode MultiplayerPeerExtension::get_transfer_mode() const { - int mode; - if (GDVIRTUAL_CALL(_get_transfer_mode, mode)) { - return (MultiplayerPeer::TransferMode)mode; - } - return MultiplayerPeer::get_transfer_mode(); -} - -void MultiplayerPeerExtension::set_target_peer(int p_peer_id) { - if (GDVIRTUAL_CALL(_set_target_peer, p_peer_id)) { - return; - } - WARN_PRINT_ONCE("MultiplayerPeerExtension::_set_target_peer is unimplemented!"); -} - -int MultiplayerPeerExtension::get_packet_peer() const { - int peer; - if (GDVIRTUAL_CALL(_get_packet_peer, peer)) { - return peer; - } - WARN_PRINT_ONCE("MultiplayerPeerExtension::_get_packet_peer is unimplemented!"); - return 0; -} - -bool MultiplayerPeerExtension::is_server() const { - bool server; - if (GDVIRTUAL_CALL(_is_server, server)) { - return server; - } - WARN_PRINT_ONCE("MultiplayerPeerExtension::_is_server is unimplemented!"); - return false; -} - -void MultiplayerPeerExtension::poll() { - int err; - if (GDVIRTUAL_CALL(_poll, err)) { - return; - } - WARN_PRINT_ONCE("MultiplayerPeerExtension::_poll is unimplemented!"); -} - -int MultiplayerPeerExtension::get_unique_id() const { - int id; - if (GDVIRTUAL_CALL(_get_unique_id, id)) { - return id; - } - WARN_PRINT_ONCE("MultiplayerPeerExtension::_get_unique_id is unimplemented!"); - return 0; -} - void MultiplayerPeerExtension::set_refuse_new_connections(bool p_enable) { if (GDVIRTUAL_CALL(_set_refuse_new_connections, p_enable)) { return; @@ -267,15 +177,6 @@ bool MultiplayerPeerExtension::is_refusing_new_connections() const { return MultiplayerPeer::is_refusing_new_connections(); } -MultiplayerPeer::ConnectionStatus MultiplayerPeerExtension::get_connection_status() const { - int status; - if (GDVIRTUAL_CALL(_get_connection_status, status)) { - return (ConnectionStatus)status; - } - WARN_PRINT_ONCE("MultiplayerPeerExtension::_get_connection_status is unimplemented!"); - return CONNECTION_DISCONNECTED; -} - void MultiplayerPeerExtension::_bind_methods() { GDVIRTUAL_BIND(_get_packet, "r_buffer", "r_buffer_size"); GDVIRTUAL_BIND(_put_packet, "p_buffer", "p_buffer_size"); @@ -300,4 +201,7 @@ void MultiplayerPeerExtension::_bind_methods() { GDVIRTUAL_BIND(_set_refuse_new_connections, "p_enable"); GDVIRTUAL_BIND(_is_refusing_new_connections); GDVIRTUAL_BIND(_get_connection_status); + + ADD_PROPERTY_DEFAULT("transfer_mode", TRANSFER_MODE_RELIABLE); + ADD_PROPERTY_DEFAULT("transfer_channel", 0); } diff --git a/scene/main/multiplayer_peer.h b/scene/main/multiplayer_peer.h index 8a012d7520..ab7483ece5 100644 --- a/scene/main/multiplayer_peer.h +++ b/scene/main/multiplayer_peer.h @@ -33,6 +33,7 @@ #include "core/io/packet_peer.h" +#include "core/extension/ext_wrappers.gen.inc" #include "core/object/gdvirtual.gen.inc" #include "core/object/script_language.h" #include "core/variant/native_ptr.h" @@ -103,55 +104,35 @@ protected: PackedByteArray script_buffer; public: - /* PacketPeer */ - virtual int get_available_packet_count() const override; + /* PacketPeer extension */ virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size) override; ///< buffer is GONE after next get_packet - virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size) override; - virtual int get_max_packet_size() const override; - - /* MultiplayerPeer */ - virtual void set_transfer_channel(int p_channel) override; - virtual int get_transfer_channel() const override; - virtual void set_transfer_mode(TransferMode p_mode) override; - virtual TransferMode get_transfer_mode() const override; - virtual void set_target_peer(int p_peer_id) override; - - virtual int get_packet_peer() const override; - - virtual bool is_server() const override; + GDVIRTUAL2R(Error, _get_packet, GDNativeConstPtr<const uint8_t *>, GDNativePtr<int>); + GDVIRTUAL0R(PackedByteArray, _get_packet_script); // For GDScript. - virtual void poll() override; + virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size) override; + GDVIRTUAL2R(Error, _put_packet, GDNativeConstPtr<const uint8_t>, int); + GDVIRTUAL1R(Error, _put_packet_script, PackedByteArray); // For GDScript. - virtual int get_unique_id() const override; + EXBIND0RC(int, get_available_packet_count); + EXBIND0RC(int, get_max_packet_size); + /* MultiplayerPeer extension */ virtual void set_refuse_new_connections(bool p_enable) override; - virtual bool is_refusing_new_connections() const override; + GDVIRTUAL1(_set_refuse_new_connections, bool); // Optional. - virtual ConnectionStatus get_connection_status() const override; - - /* PacketPeer GDExtension */ - GDVIRTUAL0RC(int, _get_available_packet_count); - GDVIRTUAL2R(int, _get_packet, GDNativeConstPtr<const uint8_t *>, GDNativePtr<int>); - GDVIRTUAL2R(int, _put_packet, GDNativeConstPtr<const uint8_t>, int); - GDVIRTUAL0RC(int, _get_max_packet_size); - - /* PacketPeer GDScript */ - GDVIRTUAL0R(PackedByteArray, _get_packet_script); - GDVIRTUAL1R(int, _put_packet_script, PackedByteArray); - - /* MultiplayerPeer GDExtension */ - GDVIRTUAL1(_set_transfer_channel, int); - GDVIRTUAL0RC(int, _get_transfer_channel); - GDVIRTUAL1(_set_transfer_mode, int); - GDVIRTUAL0RC(int, _get_transfer_mode); - GDVIRTUAL1(_set_target_peer, int); - GDVIRTUAL0RC(int, _get_packet_peer); - GDVIRTUAL0RC(bool, _is_server); - GDVIRTUAL0R(int, _poll); - GDVIRTUAL0RC(int, _get_unique_id); - GDVIRTUAL1(_set_refuse_new_connections, bool); - GDVIRTUAL0RC(bool, _is_refusing_new_connections); - GDVIRTUAL0RC(int, _get_connection_status); + virtual bool is_refusing_new_connections() const override; + GDVIRTUAL0RC(bool, _is_refusing_new_connections); // Optional. + + EXBIND1(set_transfer_channel, int); + EXBIND0RC(int, get_transfer_channel); + EXBIND1(set_transfer_mode, TransferMode); + EXBIND0RC(TransferMode, get_transfer_mode); + EXBIND1(set_target_peer, int); + EXBIND0RC(int, get_packet_peer); + EXBIND0RC(bool, is_server); + EXBIND0(poll); + EXBIND0RC(int, get_unique_id); + EXBIND0RC(ConnectionStatus, get_connection_status); }; #endif // MULTIPLAYER_PEER_H diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 268b381029..25c9b33ff9 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -88,6 +88,14 @@ bool SceneTreeTimer::is_process_always() { return process_always; } +void SceneTreeTimer::set_process_in_physics(bool p_process_in_physics) { + process_in_physics = p_process_in_physics; +} + +bool SceneTreeTimer::is_process_in_physics() { + return process_in_physics; +} + void SceneTreeTimer::set_ignore_time_scale(bool p_ignore) { ignore_time_scale = p_ignore; } @@ -420,6 +428,8 @@ bool SceneTree::physics_process(double p_time) { _flush_ugc(); MessageQueue::get_singleton()->flush(); //small little hack + process_timers(p_time, true); //go through timers + process_tweens(p_time, true); flush_transform_notifications(); @@ -462,37 +472,7 @@ bool SceneTree::process(double p_time) { _flush_delete_queue(); - //go through timers - - List<Ref<SceneTreeTimer>>::Element *L = timers.back(); //last element - - for (List<Ref<SceneTreeTimer>>::Element *E = timers.front(); E;) { - List<Ref<SceneTreeTimer>>::Element *N = E->next(); - if (paused && !E->get()->is_process_always()) { - if (E == L) { - break; //break on last, so if new timers were added during list traversal, ignore them. - } - E = N; - continue; - } - - double time_left = E->get()->get_time_left(); - if (E->get()->is_ignore_time_scale()) { - time_left -= Engine::get_singleton()->get_process_step(); - } else { - time_left -= p_time; - } - E->get()->set_time_left(time_left); - - if (time_left <= 0) { - E->get()->emit_signal(SNAME("timeout")); - timers.erase(E); - } - if (E == L) { - break; //break on last, so if new timers were added during list traversal, ignore them. - } - E = N; - } + process_timers(p_time, false); //go through timers process_tweens(p_time, false); @@ -530,6 +510,38 @@ bool SceneTree::process(double p_time) { return _quit; } +void SceneTree::process_timers(float p_delta, bool p_physics_frame) { + List<Ref<SceneTreeTimer>>::Element *L = timers.back(); //last element + + for (List<Ref<SceneTreeTimer>>::Element *E = timers.front(); E;) { + List<Ref<SceneTreeTimer>>::Element *N = E->next(); + if ((paused && !E->get()->is_process_always()) || (E->get()->is_process_in_physics() != p_physics_frame)) { + if (E == L) { + break; //break on last, so if new timers were added during list traversal, ignore them. + } + E = N; + continue; + } + + double time_left = E->get()->get_time_left(); + if (E->get()->is_ignore_time_scale()) { + time_left -= Engine::get_singleton()->get_process_step(); + } else { + time_left -= p_delta; + } + E->get()->set_time_left(time_left); + + if (time_left <= 0) { + E->get()->emit_signal(SNAME("timeout")); + timers.erase(E); + } + if (E == L) { + break; //break on last, so if new timers were added during list traversal, ignore them. + } + E = N; + } +} + void SceneTree::process_tweens(float p_delta, bool p_physics) { // This methods works similarly to how SceneTreeTimers are handled. List<Ref<Tween>>::Element *L = tweens.back(); @@ -1157,11 +1169,13 @@ void SceneTree::add_current_scene(Node *p_current) { root->add_child(p_current); } -Ref<SceneTreeTimer> SceneTree::create_timer(double p_delay_sec, bool p_process_always) { +Ref<SceneTreeTimer> SceneTree::create_timer(double p_delay_sec, bool p_process_always, bool p_process_in_physics, bool p_ignore_time_scale) { Ref<SceneTreeTimer> stt; stt.instantiate(); stt->set_process_always(p_process_always); stt->set_time_left(p_delay_sec); + stt->set_process_in_physics(p_process_in_physics); + stt->set_ignore_time_scale(p_ignore_time_scale); timers.push_back(stt); return stt; } @@ -1259,7 +1273,7 @@ void SceneTree::_bind_methods() { ClassDB::bind_method(D_METHOD("set_pause", "enable"), &SceneTree::set_pause); ClassDB::bind_method(D_METHOD("is_paused"), &SceneTree::is_paused); - ClassDB::bind_method(D_METHOD("create_timer", "time_sec", "process_always"), &SceneTree::create_timer, DEFVAL(true)); + ClassDB::bind_method(D_METHOD("create_timer", "time_sec", "process_always", "process_in_physics", "ignore_time_scale"), &SceneTree::create_timer, DEFVAL(true), DEFVAL(false), DEFVAL(false)); ClassDB::bind_method(D_METHOD("create_tween"), &SceneTree::create_tween); ClassDB::bind_method(D_METHOD("get_processed_tweens"), &SceneTree::get_processed_tweens); diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h index e66363ab33..45653001ca 100644 --- a/scene/main/scene_tree.h +++ b/scene/main/scene_tree.h @@ -53,6 +53,7 @@ class SceneTreeTimer : public RefCounted { double time_left = 0.0; bool process_always = true; + bool process_in_physics = false; bool ignore_time_scale = false; protected: @@ -65,6 +66,9 @@ public: void set_process_always(bool p_process_always); bool is_process_always(); + void set_process_in_physics(bool p_process_in_physics); + bool is_process_in_physics(); + void set_ignore_time_scale(bool p_ignore); bool is_ignore_time_scale(); @@ -176,6 +180,7 @@ private: void node_added(Node *p_node); void node_removed(Node *p_node); void node_renamed(Node *p_node); + void process_timers(float p_delta, bool p_physics_frame); void process_tweens(float p_delta, bool p_physics_frame); Group *add_to_group(const StringName &p_group, Node *p_node); @@ -365,7 +370,7 @@ public: Error change_scene_to(const Ref<PackedScene> &p_scene); Error reload_current_scene(); - Ref<SceneTreeTimer> create_timer(double p_delay_sec, bool p_process_always = true); + Ref<SceneTreeTimer> create_timer(double p_delay_sec, bool p_process_always = true, bool p_process_in_physics = false, bool p_ignore_time_scale = false); Ref<Tween> create_tween(); TypedArray<Tween> get_processed_tweens(); diff --git a/scene/main/shader_globals_override.cpp b/scene/main/shader_globals_override.cpp index a621aea9c8..13034c5447 100644 --- a/scene/main/shader_globals_override.cpp +++ b/scene/main/shader_globals_override.cpp @@ -64,9 +64,9 @@ bool ShaderGlobalsOverride::_set(const StringName &p_name, const Variant &p_valu if (active) { if (o->override.get_type() == Variant::OBJECT) { RID tex_rid = p_value; - RS::get_singleton()->global_shader_uniform_set_override(*r, tex_rid); + RS::get_singleton()->global_shader_parameter_set_override(*r, tex_rid); } else { - RS::get_singleton()->global_shader_uniform_set_override(*r, p_value); + RS::get_singleton()->global_shader_parameter_set_override(*r, p_value); } } o->in_use = p_value.get_type() != Variant::NIL; @@ -93,13 +93,13 @@ bool ShaderGlobalsOverride::_get(const StringName &p_name, Variant &r_ret) const void ShaderGlobalsOverride::_get_property_list(List<PropertyInfo> *p_list) const { Vector<StringName> variables; - variables = RS::get_singleton()->global_shader_uniform_get_list(); + variables = RS::get_singleton()->global_shader_parameter_get_list(); for (int i = 0; i < variables.size(); i++) { PropertyInfo pinfo; pinfo.name = "params/" + variables[i]; pinfo.usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; - switch (RS::get_singleton()->global_shader_uniform_get_type(variables[i])) { + switch (RS::get_singleton()->global_shader_parameter_get_type(variables[i])) { case RS::GLOBAL_VAR_TYPE_BOOL: { pinfo.type = Variant::BOOL; } break; @@ -234,9 +234,9 @@ void ShaderGlobalsOverride::_activate() { if (o->in_use && o->override.get_type() != Variant::NIL) { if (o->override.get_type() == Variant::OBJECT) { RID tex_rid = o->override; - RS::get_singleton()->global_shader_uniform_set_override(E.key, tex_rid); + RS::get_singleton()->global_shader_parameter_set_override(E.key, tex_rid); } else { - RS::get_singleton()->global_shader_uniform_set_override(E.key, o->override); + RS::get_singleton()->global_shader_parameter_set_override(E.key, o->override); } } @@ -258,7 +258,7 @@ void ShaderGlobalsOverride::_notification(int p_what) { for (const KeyValue<StringName, Override> &E : overrides) { const Override *o = &E.value; if (o->in_use) { - RS::get_singleton()->global_shader_uniform_set_override(E.key, Variant()); + RS::get_singleton()->global_shader_parameter_set_override(E.key, Variant()); } } } diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 1bb1faacdd..e901f76c0a 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -805,6 +805,10 @@ void Viewport::_set_size(const Size2i &p_size, const Size2i &p_size_2d_override, update_canvas_items(); + for (ViewportTexture *E : viewport_textures) { + E->emit_changed(); + } + emit_signal(SNAME("size_changed")); } diff --git a/scene/main/window.cpp b/scene/main/window.cpp index 1e52b644a3..04f56bb874 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -38,6 +38,7 @@ #include "scene/gui/control.h" #include "scene/scene_string_names.h" #include "scene/theme/theme_db.h" +#include "scene/theme/theme_owner.h" void Window::set_title(const String &p_title) { title = p_title; @@ -799,6 +800,19 @@ Viewport *Window::_get_embedder() const { void Window::_notification(int p_what) { switch (p_what) { + case NOTIFICATION_POSTINITIALIZE: { + _invalidate_theme_cache(); + _update_theme_item_cache(); + } break; + + case NOTIFICATION_PARENTED: { + theme_owner->assign_theme_on_parented(this); + } break; + + case NOTIFICATION_UNPARENTED: { + theme_owner->clear_theme_on_unparented(this); + } break; + case NOTIFICATION_ENTER_TREE: { bool embedded = false; { @@ -851,13 +865,13 @@ void Window::_notification(int p_what) { RS::get_singleton()->viewport_set_active(get_viewport_rid(), true); } - // Need to defer here, because theme owner information might be set in - // add_child_notify, which doesn't get called until right after this. - call_deferred(SNAME("notification"), NOTIFICATION_THEME_CHANGED); + notification(NOTIFICATION_THEME_CHANGED); } break; case NOTIFICATION_THEME_CHANGED: { emit_signal(SceneStringNames::get_singleton()->theme_changed); + _invalidate_theme_cache(); + _update_theme_item_cache(); } break; case NOTIFICATION_READY: { @@ -867,6 +881,9 @@ void Window::_notification(int p_what) { } break; case NOTIFICATION_TRANSLATION_CHANGED: { + _invalidate_theme_cache(); + _update_theme_item_cache(); + if (embedder) { embedder->_sub_window_update(this); } else if (window_id != DisplayServer::INVALID_WINDOW_ID) { @@ -1279,28 +1296,29 @@ Rect2i Window::get_usable_parent_rect() const { } void Window::add_child_notify(Node *p_child) { - // We propagate when this node uses a custom theme, so it can pass it on to its children. - if (theme_owner || theme_owner_window) { - // `p_notify` is false here as `NOTIFICATION_THEME_CHANGED` will be handled by `NOTIFICATION_ENTER_TREE`. - Control::_propagate_theme_changed(this, theme_owner, theme_owner_window, false, true); - } - if (is_inside_tree() && wrap_controls) { child_controls_changed(); } } void Window::remove_child_notify(Node *p_child) { - // If the removed child isn't inheriting any theme items through this node, then there's no need to propagate. - if (theme_owner || theme_owner_window) { - Control::_propagate_theme_changed(this, nullptr, nullptr, false, true); - } - if (is_inside_tree() && wrap_controls) { child_controls_changed(); } } +void Window::set_theme_owner_node(Node *p_node) { + theme_owner->set_owner_node(p_node); +} + +Node *Window::get_theme_owner_node() const { + return theme_owner->get_owner_node(); +} + +bool Window::has_theme_owner_node() const { + return theme_owner->has_owner_node(); +} + void Window::set_theme(const Ref<Theme> &p_theme) { if (theme == p_theme) { return; @@ -1312,24 +1330,24 @@ void Window::set_theme(const Ref<Theme> &p_theme) { theme = p_theme; if (theme.is_valid()) { - Control::_propagate_theme_changed(this, nullptr, this, is_inside_tree(), true); + theme_owner->propagate_theme_changed(this, this, is_inside_tree(), true); theme->connect("changed", callable_mp(this, &Window::_theme_changed), CONNECT_DEFERRED); return; } Control *parent_c = Object::cast_to<Control>(get_parent()); - if (parent_c && (parent_c->data.theme_owner || parent_c->data.theme_owner_window)) { - Control::_propagate_theme_changed(this, parent_c->data.theme_owner, parent_c->data.theme_owner_window, is_inside_tree(), true); + if (parent_c && parent_c->has_theme_owner_node()) { + theme_owner->propagate_theme_changed(this, parent_c->get_theme_owner_node(), is_inside_tree(), true); return; } Window *parent_w = cast_to<Window>(get_parent()); - if (parent_w && (parent_w->theme_owner || parent_w->theme_owner_window)) { - Control::_propagate_theme_changed(this, parent_w->theme_owner, parent_w->theme_owner_window, is_inside_tree(), true); + if (parent_w && parent_w->has_theme_owner_node()) { + theme_owner->propagate_theme_changed(this, parent_w->get_theme_owner_node(), is_inside_tree(), true); return; } - Control::_propagate_theme_changed(this, nullptr, nullptr, is_inside_tree(), true); + theme_owner->propagate_theme_changed(this, nullptr, is_inside_tree(), true); } Ref<Theme> Window::get_theme() const { @@ -1338,10 +1356,22 @@ Ref<Theme> Window::get_theme() const { void Window::_theme_changed() { if (is_inside_tree()) { - Control::_propagate_theme_changed(this, nullptr, this, true, false); + theme_owner->propagate_theme_changed(this, this, true, false); } } +void Window::_invalidate_theme_cache() { + theme_icon_cache.clear(); + theme_style_cache.clear(); + theme_font_cache.clear(); + theme_font_size_cache.clear(); + theme_color_cache.clear(); + theme_constant_cache.clear(); +} + +void Window::_update_theme_item_cache() { +} + void Window::set_theme_type_variation(const StringName &p_theme_type) { theme_type_variation = p_theme_type; if (is_inside_tree()) { @@ -1353,100 +1383,124 @@ StringName Window::get_theme_type_variation() const { return theme_type_variation; } -void Window::_get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == theme_type_variation) { - if (ThemeDB::get_singleton()->get_project_theme().is_valid() && ThemeDB::get_singleton()->get_project_theme()->get_type_variation_base(theme_type_variation) != StringName()) { - ThemeDB::get_singleton()->get_project_theme()->get_type_dependencies(get_class_name(), theme_type_variation, p_list); - } else { - ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(get_class_name(), theme_type_variation, p_list); - } - } else { - ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(p_theme_type, StringName(), p_list); +Ref<Texture2D> Window::get_theme_icon(const StringName &p_name, const StringName &p_theme_type) const { + if (theme_icon_cache.has(p_theme_type) && theme_icon_cache[p_theme_type].has(p_name)) { + return theme_icon_cache[p_theme_type][p_name]; } -} -Ref<Texture2D> Window::get_theme_icon(const StringName &p_name, const StringName &p_theme_type) const { List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return Control::get_theme_item_in_types<Ref<Texture2D>>(theme_owner, theme_owner_window, Theme::DATA_TYPE_ICON, p_name, theme_types); + theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Ref<Texture2D> icon = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_ICON, p_name, theme_types); + theme_icon_cache[p_theme_type][p_name] = icon; + return icon; } Ref<StyleBox> Window::get_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const { + if (theme_style_cache.has(p_theme_type) && theme_style_cache[p_theme_type].has(p_name)) { + return theme_style_cache[p_theme_type][p_name]; + } + List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return Control::get_theme_item_in_types<Ref<StyleBox>>(theme_owner, theme_owner_window, Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); + theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Ref<StyleBox> style = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); + theme_style_cache[p_theme_type][p_name] = style; + return style; } Ref<Font> Window::get_theme_font(const StringName &p_name, const StringName &p_theme_type) const { + if (theme_font_cache.has(p_theme_type) && theme_font_cache[p_theme_type].has(p_name)) { + return theme_font_cache[p_theme_type][p_name]; + } + List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return Control::get_theme_item_in_types<Ref<Font>>(theme_owner, theme_owner_window, Theme::DATA_TYPE_FONT, p_name, theme_types); + theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Ref<Font> font = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_FONT, p_name, theme_types); + theme_font_cache[p_theme_type][p_name] = font; + return font; } int Window::get_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const { + if (theme_font_size_cache.has(p_theme_type) && theme_font_size_cache[p_theme_type].has(p_name)) { + return theme_font_size_cache[p_theme_type][p_name]; + } + List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return Control::get_theme_item_in_types<int>(theme_owner, theme_owner_window, Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); + theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + int font_size = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); + theme_font_size_cache[p_theme_type][p_name] = font_size; + return font_size; } Color Window::get_theme_color(const StringName &p_name, const StringName &p_theme_type) const { + if (theme_color_cache.has(p_theme_type) && theme_color_cache[p_theme_type].has(p_name)) { + return theme_color_cache[p_theme_type][p_name]; + } + List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return Control::get_theme_item_in_types<Color>(theme_owner, theme_owner_window, Theme::DATA_TYPE_COLOR, p_name, theme_types); + theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Color color = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_COLOR, p_name, theme_types); + theme_color_cache[p_theme_type][p_name] = color; + return color; } int Window::get_theme_constant(const StringName &p_name, const StringName &p_theme_type) const { + if (theme_constant_cache.has(p_theme_type) && theme_constant_cache[p_theme_type].has(p_name)) { + return theme_constant_cache[p_theme_type][p_name]; + } + List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return Control::get_theme_item_in_types<int>(theme_owner, theme_owner_window, Theme::DATA_TYPE_CONSTANT, p_name, theme_types); + theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + int constant = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_CONSTANT, p_name, theme_types); + theme_constant_cache[p_theme_type][p_name] = constant; + return constant; } bool Window::has_theme_icon(const StringName &p_name, const StringName &p_theme_type) const { List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return Control::has_theme_item_in_types(theme_owner, theme_owner_window, Theme::DATA_TYPE_ICON, p_name, theme_types); + theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_ICON, p_name, theme_types); } bool Window::has_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const { List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return Control::has_theme_item_in_types(theme_owner, theme_owner_window, Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); + theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); } bool Window::has_theme_font(const StringName &p_name, const StringName &p_theme_type) const { List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return Control::has_theme_item_in_types(theme_owner, theme_owner_window, Theme::DATA_TYPE_FONT, p_name, theme_types); + theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_FONT, p_name, theme_types); } bool Window::has_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const { List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return Control::has_theme_item_in_types(theme_owner, theme_owner_window, Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); + theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); } bool Window::has_theme_color(const StringName &p_name, const StringName &p_theme_type) const { List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return Control::has_theme_item_in_types(theme_owner, theme_owner_window, Theme::DATA_TYPE_COLOR, p_name, theme_types); + theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_COLOR, p_name, theme_types); } bool Window::has_theme_constant(const StringName &p_name, const StringName &p_theme_type) const { List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return Control::has_theme_item_in_types(theme_owner, theme_owner_window, Theme::DATA_TYPE_CONSTANT, p_name, theme_types); + theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_CONSTANT, p_name, theme_types); } float Window::get_theme_default_base_scale() const { - return Control::fetch_theme_default_base_scale(theme_owner, theme_owner_window); + return theme_owner->get_theme_default_base_scale(); } Ref<Font> Window::get_theme_default_font() const { - return Control::fetch_theme_default_font(theme_owner, theme_owner_window); + return theme_owner->get_theme_default_font(); } int Window::get_theme_default_font_size() const { - return Control::fetch_theme_default_font_size(theme_owner, theme_owner_window); + return theme_owner->get_theme_default_font_size(); } Rect2i Window::get_parent_rect() const { @@ -1776,8 +1830,10 @@ void Window::_bind_methods() { } Window::Window() { + theme_owner = memnew(ThemeOwner); RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_DISABLED); } Window::~Window() { + memdelete(theme_owner); } diff --git a/scene/main/window.h b/scene/main/window.h index 238be484c0..8113117103 100644 --- a/scene/main/window.h +++ b/scene/main/window.h @@ -32,12 +32,13 @@ #define WINDOW_H #include "scene/main/viewport.h" +#include "scene/resources/theme.h" class Control; class Font; class Shortcut; class StyleBox; -class Theme; +class ThemeOwner; class Window : public Viewport { GDCLASS(Window, Viewport) @@ -135,12 +136,20 @@ private: Window *exclusive_child = nullptr; HashSet<Window *> transient_children; - friend class Control; + ThemeOwner *theme_owner = nullptr; Ref<Theme> theme; - Control *theme_owner = nullptr; - Window *theme_owner_window = nullptr; StringName theme_type_variation; + mutable HashMap<StringName, Theme::ThemeIconMap> theme_icon_cache; + mutable HashMap<StringName, Theme::ThemeStyleMap> theme_style_cache; + mutable HashMap<StringName, Theme::ThemeFontMap> theme_font_cache; + mutable HashMap<StringName, Theme::ThemeFontSizeMap> theme_font_size_cache; + mutable HashMap<StringName, Theme::ThemeColorMap> theme_color_cache; + mutable HashMap<StringName, Theme::ThemeConstantMap> theme_constant_cache; + + void _theme_changed(); + void _invalidate_theme_cache(); + Viewport *embedder = nullptr; friend class Viewport; //friend back, can call the methods below @@ -158,6 +167,8 @@ protected: Viewport *_get_embedder() const; virtual Rect2i _popup_adjust_rect() const { return Rect2i(); } + virtual void _update_theme_item_cache(); + virtual void _post_popup() {} virtual Size2 _get_contents_minimum_size() const; static void _bind_methods(); @@ -257,13 +268,15 @@ public: void popup_centered(const Size2i &p_minsize = Size2i()); void popup_centered_clamped(const Size2i &p_size = Size2i(), float p_fallback_ratio = 0.75); + void set_theme_owner_node(Node *p_node); + Node *get_theme_owner_node() const; + bool has_theme_owner_node() const; + void set_theme(const Ref<Theme> &p_theme); Ref<Theme> get_theme() const; - void _theme_changed(); void set_theme_type_variation(const StringName &p_theme_type); StringName get_theme_type_variation() const; - _FORCE_INLINE_ void _get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const; Size2 get_contents_minimum_size() const; diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index cc40d36fa3..a9470596b2 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -54,6 +54,7 @@ #include "scene/2d/mesh_instance_2d.h" #include "scene/2d/multimesh_instance_2d.h" #include "scene/2d/navigation_agent_2d.h" +#include "scene/2d/navigation_link_2d.h" #include "scene/2d/navigation_obstacle_2d.h" #include "scene/2d/parallax_background.h" #include "scene/2d/parallax_layer.h" @@ -240,6 +241,7 @@ #include "scene/3d/mesh_instance_3d.h" #include "scene/3d/multimesh_instance_3d.h" #include "scene/3d/navigation_agent_3d.h" +#include "scene/3d/navigation_link_3d.h" #include "scene/3d/navigation_obstacle_3d.h" #include "scene/3d/navigation_region_3d.h" #include "scene/3d/node_3d.h" @@ -378,14 +380,14 @@ void register_scene_types() { GDREGISTER_CLASS(VSeparator); GDREGISTER_CLASS(TextureButton); GDREGISTER_CLASS(Container); - GDREGISTER_ABSTRACT_CLASS(BoxContainer); + GDREGISTER_CLASS(BoxContainer); GDREGISTER_CLASS(HBoxContainer); GDREGISTER_CLASS(VBoxContainer); GDREGISTER_CLASS(GridContainer); GDREGISTER_CLASS(CenterContainer); GDREGISTER_CLASS(ScrollContainer); GDREGISTER_CLASS(PanelContainer); - GDREGISTER_ABSTRACT_CLASS(FlowContainer); + GDREGISTER_CLASS(FlowContainer); GDREGISTER_CLASS(HFlowContainer); GDREGISTER_CLASS(VFlowContainer); @@ -422,7 +424,7 @@ void register_scene_types() { GDREGISTER_CLASS(MarginContainer); GDREGISTER_CLASS(SubViewportContainer); - GDREGISTER_ABSTRACT_CLASS(SplitContainer); + GDREGISTER_CLASS(SplitContainer); GDREGISTER_CLASS(HSplitContainer); GDREGISTER_CLASS(VSplitContainer); @@ -577,6 +579,7 @@ void register_scene_types() { GDREGISTER_CLASS(NavigationRegion3D); GDREGISTER_CLASS(NavigationAgent3D); GDREGISTER_CLASS(NavigationObstacle3D); + GDREGISTER_CLASS(NavigationLink3D); OS::get_singleton()->yield(); // may take time to init #endif // _3D_DISABLED @@ -639,21 +642,22 @@ void register_scene_types() { GDREGISTER_CLASS(VisualShaderNodeTexture2DArray); GDREGISTER_CLASS(VisualShaderNodeTexture3D); GDREGISTER_CLASS(VisualShaderNodeCubemap); - GDREGISTER_ABSTRACT_CLASS(VisualShaderNodeUniform); - GDREGISTER_CLASS(VisualShaderNodeUniformRef); - GDREGISTER_CLASS(VisualShaderNodeFloatUniform); - GDREGISTER_CLASS(VisualShaderNodeIntUniform); - GDREGISTER_CLASS(VisualShaderNodeBooleanUniform); - GDREGISTER_CLASS(VisualShaderNodeColorUniform); - GDREGISTER_CLASS(VisualShaderNodeVec2Uniform); - GDREGISTER_CLASS(VisualShaderNodeVec3Uniform); - GDREGISTER_CLASS(VisualShaderNodeVec4Uniform); - GDREGISTER_CLASS(VisualShaderNodeTransformUniform); - GDREGISTER_CLASS(VisualShaderNodeTextureUniform); - GDREGISTER_CLASS(VisualShaderNodeTextureUniformTriplanar); - GDREGISTER_CLASS(VisualShaderNodeTexture2DArrayUniform); - GDREGISTER_CLASS(VisualShaderNodeTexture3DUniform); - GDREGISTER_CLASS(VisualShaderNodeCubemapUniform); + GDREGISTER_ABSTRACT_CLASS(VisualShaderNodeParameter); + GDREGISTER_CLASS(VisualShaderNodeParameterRef); + GDREGISTER_CLASS(VisualShaderNodeFloatParameter); + GDREGISTER_CLASS(VisualShaderNodeIntParameter); + GDREGISTER_CLASS(VisualShaderNodeBooleanParameter); + GDREGISTER_CLASS(VisualShaderNodeColorParameter); + GDREGISTER_CLASS(VisualShaderNodeVec2Parameter); + GDREGISTER_CLASS(VisualShaderNodeVec3Parameter); + GDREGISTER_CLASS(VisualShaderNodeVec4Parameter); + GDREGISTER_CLASS(VisualShaderNodeTransformParameter); + GDREGISTER_ABSTRACT_CLASS(VisualShaderNodeTextureParameter); + GDREGISTER_CLASS(VisualShaderNodeTexture2DParameter); + GDREGISTER_CLASS(VisualShaderNodeTextureParameterTriplanar); + GDREGISTER_CLASS(VisualShaderNodeTexture2DArrayParameter); + GDREGISTER_CLASS(VisualShaderNodeTexture3DParameter); + GDREGISTER_CLASS(VisualShaderNodeCubemapParameter); GDREGISTER_CLASS(VisualShaderNodeLinearSceneDepth); GDREGISTER_CLASS(VisualShaderNodeIf); GDREGISTER_CLASS(VisualShaderNodeSwitch); @@ -934,6 +938,7 @@ void register_scene_types() { GDREGISTER_CLASS(NavigationRegion2D); GDREGISTER_CLASS(NavigationAgent2D); GDREGISTER_CLASS(NavigationObstacle2D); + GDREGISTER_CLASS(NavigationLink2D); OS::get_singleton()->yield(); // may take time to init @@ -1084,10 +1089,12 @@ void register_scene_types() { ClassDB::add_compatibility_class("VisibilityNotifier2D", "VisibleOnScreenNotifier2D"); ClassDB::add_compatibility_class("VisibilityNotifier3D", "VisibleOnScreenNotifier3D"); ClassDB::add_compatibility_class("VisualServer", "RenderingServer"); + ClassDB::add_compatibility_class("World", "World3D"); + + // VisualShader classes. ClassDB::add_compatibility_class("VisualShaderNodeScalarConstant", "VisualShaderNodeFloatConstant"); ClassDB::add_compatibility_class("VisualShaderNodeScalarFunc", "VisualShaderNodeFloatFunc"); ClassDB::add_compatibility_class("VisualShaderNodeScalarOp", "VisualShaderNodeFloatOp"); - ClassDB::add_compatibility_class("VisualShaderNodeScalarUniform", "VisualShaderNodeFloatUniform"); ClassDB::add_compatibility_class("VisualShaderNodeScalarClamp", "VisualShaderNodeClamp"); ClassDB::add_compatibility_class("VisualShaderNodeVectorClamp", "VisualShaderNodeClamp"); ClassDB::add_compatibility_class("VisualShaderNodeScalarInterp", "VisualShaderNodeMix"); @@ -1101,7 +1108,17 @@ void register_scene_types() { ClassDB::add_compatibility_class("VisualShaderNodeScalarTransformMult", "VisualShaderNodeTransformOp"); ClassDB::add_compatibility_class("VisualShaderNodeScalarDerivativeFunc", "VisualShaderNodeDerivativeFunc"); ClassDB::add_compatibility_class("VisualShaderNodeVectorDerivativeFunc", "VisualShaderNodeDerivativeFunc"); - ClassDB::add_compatibility_class("World", "World3D"); + + ClassDB::add_compatibility_class("VisualShaderNodeBooleanUniform", "VisualShaderNodeBooleanParameter"); + ClassDB::add_compatibility_class("VisualShaderNodeColorUniform", "VisualShaderNodeColorParameter"); + ClassDB::add_compatibility_class("VisualShaderNodeScalarUniform", "VisualShaderNodeFloatParameter"); + ClassDB::add_compatibility_class("VisualShaderNodeCubeMapUniform", "VisualShaderNodeCubeMapParameter"); + ClassDB::add_compatibility_class("VisualShaderNodeTextureUniform", "VisualShaderNodeTexture2DParameter"); + ClassDB::add_compatibility_class("VisualShaderNodeTextureUniformTriplanar", "VisualShaderNodeTextureParameterTriplanar"); + ClassDB::add_compatibility_class("VisualShaderNodeTransformUniform", "VisualShaderNodeTransformParameter"); + ClassDB::add_compatibility_class("VisualShaderNodeVec3Uniform", "VisualShaderNodeVec3Parameter"); + ClassDB::add_compatibility_class("VisualShaderNodeUniform", "VisualShaderNodeParameter"); + ClassDB::add_compatibility_class("VisualShaderNodeUniformRef", "VisualShaderNodeParameterRef"); // Renamed during 4.0 alpha, added to ease transition between alphas. ClassDB::add_compatibility_class("AudioStreamOGGVorbis", "AudioStreamOggVorbis"); diff --git a/scene/resources/bit_map.cpp b/scene/resources/bit_map.cpp index 9b1adde00a..0505f6b559 100644 --- a/scene/resources/bit_map.cpp +++ b/scene/resources/bit_map.cpp @@ -33,13 +33,18 @@ #include "core/io/image_loader.h" #include "core/variant/typed_array.h" -void BitMap::create(const Size2 &p_size) { +void BitMap::create(const Size2i &p_size) { ERR_FAIL_COND(p_size.width < 1); ERR_FAIL_COND(p_size.height < 1); + ERR_FAIL_COND(static_cast<int64_t>(p_size.width) * static_cast<int64_t>(p_size.height) > INT32_MAX); + + Error err = bitmask.resize((((p_size.width * p_size.height) - 1) / 8) + 1); + ERR_FAIL_COND(err != OK); + width = p_size.width; height = p_size.height; - bitmask.resize((((width * height) - 1) / 8) + 1); + memset(bitmask.ptrw(), 0, bitmask.size()); } @@ -49,7 +54,7 @@ void BitMap::create_from_image_alpha(const Ref<Image> &p_image, float p_threshol img->convert(Image::FORMAT_LA8); ERR_FAIL_COND(img->get_format() != Image::FORMAT_LA8); - create(img->get_size()); + create(Size2i(img->get_width(), img->get_height())); const uint8_t *r = img->get_data().ptr(); uint8_t *w = bitmask.ptrw(); @@ -63,7 +68,7 @@ void BitMap::create_from_image_alpha(const Ref<Image> &p_image, float p_threshol } } -void BitMap::set_bit_rect(const Rect2 &p_rect, bool p_value) { +void BitMap::set_bit_rect(const Rect2i &p_rect, bool p_value) { Rect2i current = Rect2i(0, 0, width, height).intersection(p_rect); uint8_t *data = bitmask.ptrw(); @@ -91,7 +96,7 @@ int BitMap::get_true_bit_count() const { const uint8_t *d = bitmask.ptr(); int c = 0; - //fast, almost branchless version + // Fast, almost branchless version. for (int i = 0; i < ds; i++) { c += (d[i] & (1 << 7)) >> 7; @@ -107,14 +112,15 @@ int BitMap::get_true_bit_count() const { return c; } -void BitMap::set_bit(const Point2 &p_pos, bool p_value) { - int x = p_pos.x; - int y = p_pos.y; +void BitMap::set_bitv(const Point2i &p_pos, bool p_value) { + set_bit(p_pos.x, p_pos.y, p_value); +} - ERR_FAIL_INDEX(x, width); - ERR_FAIL_INDEX(y, height); +void BitMap::set_bit(int p_x, int p_y, bool p_value) { + ERR_FAIL_INDEX(p_x, width); + ERR_FAIL_INDEX(p_y, height); - int ofs = width * y + x; + int ofs = width * p_y + p_x; int bbyte = ofs / 8; int bbit = ofs % 8; @@ -129,21 +135,23 @@ void BitMap::set_bit(const Point2 &p_pos, bool p_value) { bitmask.write[bbyte] = b; } -bool BitMap::get_bit(const Point2 &p_pos) const { - int x = Math::fast_ftoi(p_pos.x); - int y = Math::fast_ftoi(p_pos.y); - ERR_FAIL_INDEX_V(x, width, false); - ERR_FAIL_INDEX_V(y, height, false); +bool BitMap::get_bitv(const Point2i &p_pos) const { + return get_bit(p_pos.x, p_pos.y); +} + +bool BitMap::get_bit(int p_x, int p_y) const { + ERR_FAIL_INDEX_V(p_x, width, false); + ERR_FAIL_INDEX_V(p_y, height, false); - int ofs = width * y + x; + int ofs = width * p_y + p_x; int bbyte = ofs / 8; int bbit = ofs % 8; return (bitmask[bbyte] & (1 << bbit)) != 0; } -Size2 BitMap::get_size() const { - return Size2(width, height); +Size2i BitMap::get_size() const { + return Size2i(width, height); } void BitMap::_set_data(const Dictionary &p_d) { @@ -161,13 +169,13 @@ Dictionary BitMap::_get_data() const { return d; } -Vector<Vector2> BitMap::_march_square(const Rect2i &rect, const Point2i &start) const { +Vector<Vector2> BitMap::_march_square(const Rect2i &p_rect, const Point2i &p_start) const { int stepx = 0; int stepy = 0; int prevx = 0; int prevy = 0; - int startx = start.x; - int starty = start.y; + int startx = p_start.x; + int starty = p_start.y; int curx = startx; int cury = starty; unsigned int count = 0; @@ -176,7 +184,7 @@ Vector<Vector2> BitMap::_march_square(const Rect2i &rect, const Point2i &start) Vector<Vector2> _points; do { int sv = 0; - { //square value + { // Square value /* checking the 2x2 pixel grid, assigning these values to each pixel, if not transparent @@ -187,13 +195,13 @@ Vector<Vector2> BitMap::_march_square(const Rect2i &rect, const Point2i &start) +---+---+ */ Point2i tl = Point2i(curx - 1, cury - 1); - sv += (rect.has_point(tl) && get_bit(tl)) ? 1 : 0; + sv += (p_rect.has_point(tl) && get_bitv(tl)) ? 1 : 0; Point2i tr = Point2i(curx, cury - 1); - sv += (rect.has_point(tr) && get_bit(tr)) ? 2 : 0; + sv += (p_rect.has_point(tr) && get_bitv(tr)) ? 2 : 0; Point2i bl = Point2i(curx - 1, cury); - sv += (rect.has_point(bl) && get_bit(bl)) ? 4 : 0; + sv += (p_rect.has_point(bl) && get_bitv(bl)) ? 4 : 0; Point2i br = Point2i(curx, cury); - sv += (rect.has_point(br) && get_bit(br)) ? 8 : 0; + sv += (p_rect.has_point(br) && get_bitv(br)) ? 8 : 0; ERR_FAIL_COND_V(sv == 0 || sv == 15, Vector<Vector2>()); } @@ -303,16 +311,16 @@ Vector<Vector2> BitMap::_march_square(const Rect2i &rect, const Point2i &start) default: ERR_PRINT("this shouldn't happen."); } - //little optimization - // if previous direction is same as current direction, - // then we should modify the last vec to current + // Small optimization: + // If the previous direction is same as the current direction, + // then we should modify the last vector to current. curx += stepx; cury += stepy; if (stepx == prevx && stepy == prevy) { - _points.write[_points.size() - 1].x = (float)(curx - rect.position.x); - _points.write[_points.size() - 1].y = (float)(cury + rect.position.y); + _points.write[_points.size() - 1].x = (float)(curx - p_rect.position.x); + _points.write[_points.size() - 1].y = (float)(cury + p_rect.position.y); } else { - _points.push_back(Vector2((float)(curx - rect.position.x), (float)(cury + rect.position.y))); + _points.push_back(Vector2((float)(curx - p_rect.position.x), (float)(cury + p_rect.position.y))); } count++; @@ -348,7 +356,7 @@ static Vector<Vector2> rdp(const Vector<Vector2> &v, float optimization) { int index = -1; float dist = 0.0; - //not looping first and last point + // Not looping first and last point. for (size_t i = 1, size = v.size(); i < size - 1; ++i) { float cdist = perpendicular_distance(v[i], v[0], v[v.size() - 1]); if (cdist > dist) { @@ -385,9 +393,9 @@ static Vector<Vector2> rdp(const Vector<Vector2> &v, float optimization) { static Vector<Vector2> reduce(const Vector<Vector2> &points, const Rect2i &rect, float epsilon) { int size = points.size(); - // if there are less than 3 points, then we have nothing + // If there are less than 3 points, then we have nothing. ERR_FAIL_COND_V(size < 3, Vector<Vector2>()); - // if there are less than 9 points (but more than 3), then we don't need to reduce it + // If there are less than 9 points (but more than 3), then we don't need to reduce it. if (size < 9) { return points; } @@ -412,9 +420,9 @@ struct FillBitsStackEntry { }; static void fill_bits(const BitMap *p_src, Ref<BitMap> &p_map, const Point2i &p_pos, const Rect2i &rect) { - // Using a custom stack to work iteratively to avoid stack overflow on big bitmaps + // Using a custom stack to work iteratively to avoid stack overflow on big bitmaps. Vector<FillBitsStackEntry> stack; - // Tracking size since we won't be shrinking the stack vector + // Tracking size since we won't be shrinking the stack vector. int stack_size = 0; Point2i pos = p_pos; @@ -433,10 +441,10 @@ static void fill_bits(const BitMap *p_src, Ref<BitMap> &p_map, const Point2i &p_ for (int i = next_i; i <= pos.x + 1; i++) { for (int j = next_j; j <= pos.y + 1; j++) { if (popped) { - // The next loop over j must start normally + // The next loop over j must start normally. next_j = pos.y; popped = false; - // Skip because an iteration was already executed with current counter values + // Skip because an iteration was already executed with current counter values. continue; } @@ -447,11 +455,11 @@ static void fill_bits(const BitMap *p_src, Ref<BitMap> &p_map, const Point2i &p_ continue; } - if (p_map->get_bit(Vector2(i, j))) { + if (p_map->get_bit(i, j)) { continue; - } else if (p_src->get_bit(Vector2(i, j))) { - p_map->set_bit(Vector2(i, j), true); + } else if (p_src->get_bit(i, j)) { + p_map->set_bit(i, j, true); FillBitsStackEntry se = { pos, i, j }; stack.resize(MAX(stack_size + 1, stack.size())); @@ -482,7 +490,7 @@ static void fill_bits(const BitMap *p_src, Ref<BitMap> &p_map, const Point2i &p_ print_verbose("BitMap: Max stack size: " + itos(stack.size())); } -Vector<Vector<Vector2>> BitMap::clip_opaque_to_polygons(const Rect2 &p_rect, float p_epsilon) const { +Vector<Vector<Vector2>> BitMap::clip_opaque_to_polygons(const Rect2i &p_rect, float p_epsilon) const { Rect2i r = Rect2i(0, 0, width, height).intersection(p_rect); print_verbose("BitMap: Rect: " + r); @@ -494,7 +502,7 @@ Vector<Vector<Vector2>> BitMap::clip_opaque_to_polygons(const Rect2 &p_rect, flo Vector<Vector<Vector2>> polygons; for (int i = r.position.y; i < r.position.y + r.size.height; i++) { for (int j = r.position.x; j < r.position.x + r.size.width; j++) { - if (!fill->get_bit(Point2(j, i)) && get_bit(Point2(j, i))) { + if (!fill->get_bit(j, i) && get_bit(j, i)) { fill_bits(this, fill, Point2i(j, i), r); Vector<Vector2> polygon = _march_square(r, Point2i(j, i)); @@ -515,7 +523,7 @@ Vector<Vector<Vector2>> BitMap::clip_opaque_to_polygons(const Rect2 &p_rect, flo return polygons; } -void BitMap::grow_mask(int p_pixels, const Rect2 &p_rect) { +void BitMap::grow_mask(int p_pixels, const Rect2i &p_rect) { if (p_pixels == 0) { return; } @@ -532,7 +540,7 @@ void BitMap::grow_mask(int p_pixels, const Rect2 &p_rect) { for (int i = r.position.y; i < r.position.y + r.size.height; i++) { for (int j = r.position.x; j < r.position.x + r.size.width; j++) { - if (bit_value == get_bit(Point2(j, i))) { + if (bit_value == get_bit(j, i)) { continue; } @@ -543,7 +551,7 @@ void BitMap::grow_mask(int p_pixels, const Rect2 &p_rect) { bool outside = false; if ((x < p_rect.position.x) || (x >= p_rect.position.x + p_rect.size.x) || (y < p_rect.position.y) || (y >= p_rect.position.y + p_rect.size.y)) { - // outside of rectangle counts as bit not set + // Outside of rectangle counts as bit not set. if (!bit_value) { outside = true; } else { @@ -556,7 +564,7 @@ void BitMap::grow_mask(int p_pixels, const Rect2 &p_rect) { continue; } - if (outside || (bit_value == copy->get_bit(Point2(x, y)))) { + if (outside || (bit_value == copy->get_bit(x, y))) { found = true; break; } @@ -567,20 +575,20 @@ void BitMap::grow_mask(int p_pixels, const Rect2 &p_rect) { } if (found) { - set_bit(Point2(j, i), bit_value); + set_bit(j, i, bit_value); } } } } -void BitMap::shrink_mask(int p_pixels, const Rect2 &p_rect) { +void BitMap::shrink_mask(int p_pixels, const Rect2i &p_rect) { grow_mask(-p_pixels, p_rect); } -TypedArray<PackedVector2Array> BitMap::_opaque_to_polygons_bind(const Rect2 &p_rect, float p_epsilon) const { +TypedArray<PackedVector2Array> BitMap::_opaque_to_polygons_bind(const Rect2i &p_rect, float p_epsilon) const { Vector<Vector<Vector2>> result = clip_opaque_to_polygons(p_rect, p_epsilon); - // Convert result to bindable types + // Convert result to bindable types. TypedArray<PackedVector2Array> result_array; result_array.resize(result.size()); @@ -603,15 +611,25 @@ TypedArray<PackedVector2Array> BitMap::_opaque_to_polygons_bind(const Rect2 &p_r return result_array; } -void BitMap::resize(const Size2 &p_new_size) { +void BitMap::resize(const Size2i &p_new_size) { + ERR_FAIL_COND(p_new_size.width < 0 || p_new_size.height < 0); + if (p_new_size == get_size()) { + return; + } + Ref<BitMap> new_bitmap; new_bitmap.instantiate(); new_bitmap->create(p_new_size); - int lw = MIN(width, p_new_size.width); - int lh = MIN(height, p_new_size.height); + // also allow for upscaling + int lw = (width == 0) ? 0 : p_new_size.width; + int lh = (height == 0) ? 0 : p_new_size.height; + + float scale_x = ((float)width / p_new_size.width); + float scale_y = ((float)height / p_new_size.height); for (int x = 0; x < lw; x++) { for (int y = 0; y < lh; y++) { - new_bitmap->set_bit(Vector2(x, y), get_bit(Vector2(x, y))); + bool new_bit = get_bit(x * scale_x, y * scale_y); + new_bitmap->set_bit(x, y, new_bit); } } @@ -627,14 +645,16 @@ Ref<Image> BitMap::convert_to_image() const { for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { - image->set_pixel(i, j, get_bit(Point2(i, j)) ? Color(1, 1, 1) : Color(0, 0, 0)); + image->set_pixel(i, j, get_bit(i, j) ? Color(1, 1, 1) : Color(0, 0, 0)); } } return image; } -void BitMap::blit(const Vector2 &p_pos, const Ref<BitMap> &p_bitmap) { +void BitMap::blit(const Vector2i &p_pos, const Ref<BitMap> &p_bitmap) { + ERR_FAIL_COND_MSG(p_bitmap.is_null(), "It's not a reference to a valid BitMap object."); + int x = p_pos.x; int y = p_pos.y; int w = p_bitmap->get_size().width; @@ -650,8 +670,8 @@ void BitMap::blit(const Vector2 &p_pos, const Ref<BitMap> &p_bitmap) { if (py < 0 || py >= height) { continue; } - if (p_bitmap->get_bit(Vector2(i, j))) { - set_bit(Vector2(x, y), true); + if (p_bitmap->get_bit(i, j)) { + set_bit(px, py, true); } } } @@ -661,8 +681,10 @@ void BitMap::_bind_methods() { ClassDB::bind_method(D_METHOD("create", "size"), &BitMap::create); ClassDB::bind_method(D_METHOD("create_from_image_alpha", "image", "threshold"), &BitMap::create_from_image_alpha, DEFVAL(0.1)); - ClassDB::bind_method(D_METHOD("set_bit", "position", "bit"), &BitMap::set_bit); - ClassDB::bind_method(D_METHOD("get_bit", "position"), &BitMap::get_bit); + ClassDB::bind_method(D_METHOD("set_bitv", "position", "bit"), &BitMap::set_bitv); + ClassDB::bind_method(D_METHOD("set_bit", "x", "y", "bit"), &BitMap::set_bit); + ClassDB::bind_method(D_METHOD("get_bitv", "position"), &BitMap::get_bitv); + ClassDB::bind_method(D_METHOD("get_bit", "x", "y"), &BitMap::get_bit); ClassDB::bind_method(D_METHOD("set_bit_rect", "rect", "bit"), &BitMap::set_bit_rect); ClassDB::bind_method(D_METHOD("get_true_bit_count"), &BitMap::get_true_bit_count); @@ -681,5 +703,3 @@ void BitMap::_bind_methods() { } BitMap::BitMap() {} - -////////////////////////////////////// diff --git a/scene/resources/bit_map.h b/scene/resources/bit_map.h index d8507dfa8b..291ed8c4d0 100644 --- a/scene/resources/bit_map.h +++ b/scene/resources/bit_map.h @@ -46,9 +46,9 @@ class BitMap : public Resource { int width = 0; int height = 0; - Vector<Vector2> _march_square(const Rect2i &rect, const Point2i &start) const; + Vector<Vector2> _march_square(const Rect2i &p_rect, const Point2i &p_start) const; - TypedArray<PackedVector2Array> _opaque_to_polygons_bind(const Rect2 &p_rect, float p_epsilon) const; + TypedArray<PackedVector2Array> _opaque_to_polygons_bind(const Rect2i &p_rect, float p_epsilon) const; protected: void _set_data(const Dictionary &p_d); @@ -57,24 +57,27 @@ protected: static void _bind_methods(); public: - void create(const Size2 &p_size); + void create(const Size2i &p_size); void create_from_image_alpha(const Ref<Image> &p_image, float p_threshold = 0.1); - void set_bit(const Point2 &p_pos, bool p_value); - bool get_bit(const Point2 &p_pos) const; - void set_bit_rect(const Rect2 &p_rect, bool p_value); + void set_bitv(const Point2i &p_pos, bool p_value); + void set_bit(int p_x, int p_y, bool p_value); + void set_bit_rect(const Rect2i &p_rect, bool p_value); + bool get_bitv(const Point2i &p_pos) const; + bool get_bit(int p_x, int p_y) const; + int get_true_bit_count() const; - Size2 get_size() const; - void resize(const Size2 &p_new_size); + Size2i get_size() const; + void resize(const Size2i &p_new_size); - void grow_mask(int p_pixels, const Rect2 &p_rect); - void shrink_mask(int p_pixels, const Rect2 &p_rect); + void grow_mask(int p_pixels, const Rect2i &p_rect); + void shrink_mask(int p_pixels, const Rect2i &p_rect); - void blit(const Vector2 &p_pos, const Ref<BitMap> &p_bitmap); + void blit(const Vector2i &p_pos, const Ref<BitMap> &p_bitmap); Ref<Image> convert_to_image() const; - Vector<Vector<Vector2>> clip_opaque_to_polygons(const Rect2 &p_rect, float p_epsilon = 2.0) const; + Vector<Vector<Vector2>> clip_opaque_to_polygons(const Rect2i &p_rect, float p_epsilon = 2.0) const; BitMap(); }; diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 73ad1ceff7..208e28f17a 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -609,11 +609,9 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const // Dialogs - theme->set_constant("margin", "Dialogs", 8 * scale); - theme->set_constant("button_margin", "Dialogs", 32 * scale); - - // AcceptDialog - + // AcceptDialog is currently the base dialog, so this defines styles for all extending nodes. + theme->set_constant("margin", "AcceptDialog", 8 * scale); + theme->set_constant("button_margin", "AcceptDialog", 32 * scale); theme->set_stylebox("panel", "AcceptDialog", make_flat_stylebox(style_popup_color, 0, 0, 0, 0)); // File Dialog @@ -998,9 +996,12 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const // Containers + theme->set_icon("h_grabber", "SplitContainer", icons["hsplitter"]); + theme->set_icon("v_grabber", "SplitContainer", icons["vsplitter"]); theme->set_icon("grabber", "VSplitContainer", icons["vsplitter"]); theme->set_icon("grabber", "HSplitContainer", icons["hsplitter"]); + 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); @@ -1009,10 +1010,14 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("margin_bottom", "MarginContainer", 0 * scale); theme->set_constant("h_separation", "GridContainer", 4 * scale); theme->set_constant("v_separation", "GridContainer", 4 * scale); + theme->set_constant("separation", "SplitContainer", 12 * scale); theme->set_constant("separation", "HSplitContainer", 12 * scale); theme->set_constant("separation", "VSplitContainer", 12 * scale); + theme->set_constant("autohide", "SplitContainer", 1 * scale); theme->set_constant("autohide", "HSplitContainer", 1 * scale); theme->set_constant("autohide", "VSplitContainer", 1 * scale); + theme->set_constant("h_separation", "FlowContainer", 4 * scale); + theme->set_constant("v_separation", "FlowContainer", 4 * scale); theme->set_constant("h_separation", "HFlowContainer", 4 * scale); theme->set_constant("v_separation", "HFlowContainer", 4 * scale); theme->set_constant("h_separation", "VFlowContainer", 4 * scale); diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index 8c23471e73..ebdaaaa95f 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -818,6 +818,15 @@ float Environment::get_fog_aerial_perspective() const { return fog_aerial_perspective; } +void Environment::set_fog_sky_affect(float p_sky_affect) { + fog_sky_affect = p_sky_affect; + _update_fog(); +} + +float Environment::get_fog_sky_affect() const { + return fog_sky_affect; +} + void Environment::_update_fog() { RS::get_singleton()->environment_set_fog( environment, @@ -828,13 +837,28 @@ void Environment::_update_fog() { fog_density, fog_height, fog_height_density, - fog_aerial_perspective); + fog_aerial_perspective, + fog_sky_affect); } // Volumetric Fog void Environment::_update_volumetric_fog() { - RS::get_singleton()->environment_set_volumetric_fog(environment, volumetric_fog_enabled, volumetric_fog_density, volumetric_fog_albedo, volumetric_fog_emission, volumetric_fog_emission_energy, volumetric_fog_anisotropy, volumetric_fog_length, volumetric_fog_detail_spread, volumetric_fog_gi_inject, volumetric_fog_temporal_reproject, volumetric_fog_temporal_reproject_amount, volumetric_fog_ambient_inject); + RS::get_singleton()->environment_set_volumetric_fog( + environment, + volumetric_fog_enabled, + volumetric_fog_density, + volumetric_fog_albedo, + volumetric_fog_emission, + volumetric_fog_emission_energy, + volumetric_fog_anisotropy, + volumetric_fog_length, + volumetric_fog_detail_spread, + volumetric_fog_gi_inject, + volumetric_fog_temporal_reproject, + volumetric_fog_temporal_reproject_amount, + volumetric_fog_ambient_inject, + volumetric_fog_sky_affect); } void Environment::set_volumetric_fog_enabled(bool p_enable) { @@ -912,6 +936,15 @@ float Environment::get_volumetric_fog_ambient_inject() const { return volumetric_fog_ambient_inject; } +void Environment::set_volumetric_fog_sky_affect(float p_sky_affect) { + volumetric_fog_sky_affect = p_sky_affect; + _update_volumetric_fog(); +} + +float Environment::get_volumetric_fog_sky_affect() const { + return volumetric_fog_sky_affect; +} + void Environment::set_volumetric_fog_temporal_reprojection_enabled(bool p_enable) { volumetric_fog_temporal_reproject = p_enable; _update_volumetric_fog(); @@ -1151,7 +1184,7 @@ void Environment::_bind_methods() { ADD_GROUP("Sky", "sky_"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "sky", PROPERTY_HINT_RESOURCE_TYPE, "Sky"), "set_sky", "get_sky"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sky_custom_fov", PROPERTY_HINT_RANGE, "0,180,0.1,degrees"), "set_sky_custom_fov", "get_sky_custom_fov"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "sky_rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians"), "set_sky_rotation", "get_sky_rotation"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "sky_rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_less,or_greater,radians"), "set_sky_rotation", "get_sky_rotation"); // Ambient light @@ -1375,6 +1408,9 @@ void Environment::_bind_methods() { ClassDB::bind_method(D_METHOD("set_fog_aerial_perspective", "aerial_perspective"), &Environment::set_fog_aerial_perspective); ClassDB::bind_method(D_METHOD("get_fog_aerial_perspective"), &Environment::get_fog_aerial_perspective); + ClassDB::bind_method(D_METHOD("set_fog_sky_affect", "sky_affect"), &Environment::set_fog_sky_affect); + ClassDB::bind_method(D_METHOD("get_fog_sky_affect"), &Environment::get_fog_sky_affect); + ADD_GROUP("Fog", "fog_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_enabled"), "set_fog_enabled", "is_fog_enabled"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "fog_light_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_fog_light_color", "get_fog_light_color"); @@ -1383,8 +1419,9 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_density", PROPERTY_HINT_RANGE, "0,1,0.0001,or_greater"), "set_fog_density", "get_fog_density"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_aerial_perspective", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_fog_aerial_perspective", "get_fog_aerial_perspective"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height", PROPERTY_HINT_RANGE, "-1024,1024,0.01,or_lesser,or_greater,suffix:m"), "set_fog_height", "get_fog_height"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height_density", PROPERTY_HINT_RANGE, "-16,16,0.0001,or_lesser,or_greater"), "set_fog_height_density", "get_fog_height_density"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_sky_affect", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_fog_sky_affect", "get_fog_sky_affect"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height", PROPERTY_HINT_RANGE, "-1024,1024,0.01,or_less,or_greater,suffix:m"), "set_fog_height", "get_fog_height"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height_density", PROPERTY_HINT_RANGE, "-16,16,0.0001,or_less,or_greater"), "set_fog_height_density", "get_fog_height_density"); ClassDB::bind_method(D_METHOD("set_volumetric_fog_enabled", "enabled"), &Environment::set_volumetric_fog_enabled); ClassDB::bind_method(D_METHOD("is_volumetric_fog_enabled"), &Environment::is_volumetric_fog_enabled); @@ -1406,6 +1443,8 @@ void Environment::_bind_methods() { ClassDB::bind_method(D_METHOD("get_volumetric_fog_gi_inject"), &Environment::get_volumetric_fog_gi_inject); ClassDB::bind_method(D_METHOD("set_volumetric_fog_ambient_inject", "enabled"), &Environment::set_volumetric_fog_ambient_inject); ClassDB::bind_method(D_METHOD("get_volumetric_fog_ambient_inject"), &Environment::get_volumetric_fog_ambient_inject); + ClassDB::bind_method(D_METHOD("set_volumetric_fog_sky_affect", "sky_affect"), &Environment::set_volumetric_fog_sky_affect); + ClassDB::bind_method(D_METHOD("get_volumetric_fog_sky_affect"), &Environment::get_volumetric_fog_sky_affect); ClassDB::bind_method(D_METHOD("set_volumetric_fog_temporal_reprojection_enabled", "enabled"), &Environment::set_volumetric_fog_temporal_reprojection_enabled); ClassDB::bind_method(D_METHOD("is_volumetric_fog_temporal_reprojection_enabled"), &Environment::is_volumetric_fog_temporal_reprojection_enabled); ClassDB::bind_method(D_METHOD("set_volumetric_fog_temporal_reprojection_amount", "temporal_reprojection_amount"), &Environment::set_volumetric_fog_temporal_reprojection_amount); @@ -1422,6 +1461,7 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_length", PROPERTY_HINT_RANGE, "0,1024,0.01,or_greater"), "set_volumetric_fog_length", "get_volumetric_fog_length"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_detail_spread", PROPERTY_HINT_EXP_EASING, "positive_only"), "set_volumetric_fog_detail_spread", "get_volumetric_fog_detail_spread"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_ambient_inject", PROPERTY_HINT_RANGE, "0.0,16,0.01,exp"), "set_volumetric_fog_ambient_inject", "get_volumetric_fog_ambient_inject"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_sky_affect", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_volumetric_fog_sky_affect", "get_volumetric_fog_sky_affect"); ADD_SUBGROUP("Temporal Reprojection", "volumetric_fog_temporal_reprojection_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "volumetric_fog_temporal_reprojection_enabled"), "set_volumetric_fog_temporal_reprojection_enabled", "is_volumetric_fog_temporal_reprojection_enabled"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_temporal_reprojection_amount", PROPERTY_HINT_RANGE, "0.5,0.99,0.001"), "set_volumetric_fog_temporal_reprojection_amount", "get_volumetric_fog_temporal_reprojection_amount"); diff --git a/scene/resources/environment.h b/scene/resources/environment.h index 6d8330f74b..507a0cee39 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -179,6 +179,7 @@ private: float fog_height = 0.0; float fog_height_density = 0.0; //can be negative to invert effect float fog_aerial_perspective = 0.0; + float fog_sky_affect = 1.0; void _update_fog(); @@ -193,6 +194,7 @@ private: float volumetric_fog_detail_spread = 2.0; float volumetric_fog_gi_inject = 1.0; float volumetric_fog_ambient_inject = 0.0; + float volumetric_fog_sky_affect = 1.0; bool volumetric_fog_temporal_reproject = true; float volumetric_fog_temporal_reproject_amount = 0.9; void _update_volumetric_fog(); @@ -374,6 +376,8 @@ public: float get_fog_height_density() const; void set_fog_aerial_perspective(float p_aerial_perspective); float get_fog_aerial_perspective() const; + void set_fog_sky_affect(float p_sky_affect); + float get_fog_sky_affect() const; // Volumetric Fog void set_volumetric_fog_enabled(bool p_enable); @@ -396,6 +400,8 @@ public: float get_volumetric_fog_gi_inject() const; void set_volumetric_fog_ambient_inject(float p_ambient_inject); float get_volumetric_fog_ambient_inject() const; + void set_volumetric_fog_sky_affect(float p_sky_affect); + float get_volumetric_fog_sky_affect() const; void set_volumetric_fog_temporal_reprojection_enabled(bool p_enable); bool is_volumetric_fog_temporal_reprojection_enabled() const; void set_volumetric_fog_temporal_reprojection_amount(float p_amount); diff --git a/scene/resources/fog_material.cpp b/scene/resources/fog_material.cpp index 39ade85af6..0395ed0346 100644 --- a/scene/resources/fog_material.cpp +++ b/scene/resources/fog_material.cpp @@ -122,7 +122,7 @@ void FogMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_density_texture", "density_texture"), &FogMaterial::set_density_texture); ClassDB::bind_method(D_METHOD("get_density_texture"), &FogMaterial::get_density_texture); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "density", PROPERTY_HINT_RANGE, "0.0,16.0,0.0001,or_greater,or_lesser"), "set_density", "get_density"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "density", PROPERTY_HINT_RANGE, "0.0,16.0,0.0001,or_greater,or_less"), "set_density", "get_density"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "albedo", PROPERTY_HINT_COLOR_NO_ALPHA), "set_albedo", "get_albedo"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "emission", PROPERTY_HINT_COLOR_NO_ALPHA), "set_emission", "get_emission"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height_falloff", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_height_falloff", "get_height_falloff"); diff --git a/scene/resources/importer_mesh.cpp b/scene/resources/importer_mesh.cpp index 3638d1862c..0afca95de0 100644 --- a/scene/resources/importer_mesh.cpp +++ b/scene/resources/importer_mesh.cpp @@ -154,7 +154,7 @@ Mesh::BlendShapeMode ImporterMesh::get_blend_shape_mode() const { return blend_shape_mode; } -void ImporterMesh::add_surface(Mesh::PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, const Dictionary &p_lods, const Ref<Material> &p_material, const String &p_name, const uint32_t p_flags) { +void ImporterMesh::add_surface(Mesh::PrimitiveType p_primitive, const Array &p_arrays, const TypedArray<Array> &p_blend_shapes, const Dictionary &p_lods, const Ref<Material> &p_material, const String &p_name, const uint32_t p_flags) { ERR_FAIL_COND(p_blend_shapes.size() != blend_shapes.size()); ERR_FAIL_COND(p_arrays.size() != Mesh::ARRAY_MAX); Surface s; @@ -1230,7 +1230,7 @@ void ImporterMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_blend_shape_mode", "mode"), &ImporterMesh::set_blend_shape_mode); ClassDB::bind_method(D_METHOD("get_blend_shape_mode"), &ImporterMesh::get_blend_shape_mode); - ClassDB::bind_method(D_METHOD("add_surface", "primitive", "arrays", "blend_shapes", "lods", "material", "name", "flags"), &ImporterMesh::add_surface, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(Ref<Material>()), DEFVAL(String()), DEFVAL(0)); + ClassDB::bind_method(D_METHOD("add_surface", "primitive", "arrays", "blend_shapes", "lods", "material", "name", "flags"), &ImporterMesh::add_surface, DEFVAL(TypedArray<Array>()), DEFVAL(Dictionary()), DEFVAL(Ref<Material>()), DEFVAL(String()), DEFVAL(0)); ClassDB::bind_method(D_METHOD("get_surface_count"), &ImporterMesh::get_surface_count); ClassDB::bind_method(D_METHOD("get_surface_primitive_type", "surface_idx"), &ImporterMesh::get_surface_primitive_type); diff --git a/scene/resources/importer_mesh.h b/scene/resources/importer_mesh.h index bf1d0301d1..dce2638c19 100644 --- a/scene/resources/importer_mesh.h +++ b/scene/resources/importer_mesh.h @@ -93,7 +93,7 @@ public: int get_blend_shape_count() const; String get_blend_shape_name(int p_blend_shape) const; - void add_surface(Mesh::PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), const Ref<Material> &p_material = Ref<Material>(), const String &p_name = String(), const uint32_t p_flags = 0); + void add_surface(Mesh::PrimitiveType p_primitive, const Array &p_arrays, const TypedArray<Array> &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), const Ref<Material> &p_material = Ref<Material>(), const String &p_name = String(), const uint32_t p_flags = 0); int get_surface_count() const; void set_blend_shape_mode(Mesh::BlendShapeMode p_blend_shape_mode); diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 9a1b784ec4..448ff74a53 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -159,15 +159,16 @@ bool ShaderMaterial::_set(const StringName &p_name, const Variant &p_value) { StringName pr = shader->remap_uniform(p_name); if (!pr) { String n = p_name; - if (n.find("param/") == 0) { //backwards compatibility - pr = n.substr(6, n.length()); - } - if (n.find("shader_uniform/") == 0) { //backwards compatibility + if (n.find("shader_parameter/") == 0) { //backwards compatibility + pr = n.replace_first("shader_parameter/", ""); + } else if (n.find("shader_uniform/") == 0) { //backwards compatibility pr = n.replace_first("shader_uniform/", ""); + } else if (n.find("param/") == 0) { //backwards compatibility + pr = n.substr(6, n.length()); } } if (pr) { - set_shader_uniform(pr, p_value); + set_shader_parameter(pr, p_value); return true; } } @@ -180,11 +181,12 @@ bool ShaderMaterial::_get(const StringName &p_name, Variant &r_ret) const { StringName pr = shader->remap_uniform(p_name); if (!pr) { String n = p_name; - if (n.find("param/") == 0) { //backwards compatibility - pr = n.substr(6, n.length()); - } - if (n.find("shader_uniform/") == 0) { //backwards compatibility + if (n.find("shader_parameter/") == 0) { //backwards compatibility + pr = n.replace_first("shader_parameter/", ""); + } else if (n.find("shader_uniform/") == 0) { //backwards compatibility pr = n.replace_first("shader_uniform/", ""); + } else if (n.find("param/") == 0) { //backwards compatibility + pr = n.substr(6, n.length()); } } @@ -303,7 +305,7 @@ bool ShaderMaterial::_property_can_revert(const StringName &p_name) const { if (shader.is_valid()) { StringName pr = shader->remap_uniform(p_name); if (pr) { - Variant default_value = RenderingServer::get_singleton()->shader_get_param_default(shader->get_rid(), pr); + Variant default_value = RenderingServer::get_singleton()->shader_get_parameter_default(shader->get_rid(), pr); Variant current_value; _get(p_name, current_value); return default_value.get_type() != Variant::NIL && default_value != current_value; @@ -316,7 +318,7 @@ bool ShaderMaterial::_property_get_revert(const StringName &p_name, Variant &r_p if (shader.is_valid()) { StringName pr = shader->remap_uniform(p_name); if (pr) { - r_property = RenderingServer::get_singleton()->shader_get_param_default(shader->get_rid(), pr); + r_property = RenderingServer::get_singleton()->shader_get_parameter_default(shader->get_rid(), pr); return true; } } @@ -351,7 +353,7 @@ Ref<Shader> ShaderMaterial::get_shader() const { return shader; } -void ShaderMaterial::set_shader_uniform(const StringName &p_param, const Variant &p_value) { +void ShaderMaterial::set_shader_parameter(const StringName &p_param, const Variant &p_value) { if (p_value.get_type() == Variant::NIL) { param_cache.erase(p_param); RS::get_singleton()->material_set_param(_get_material(), p_param, Variant()); @@ -371,7 +373,7 @@ void ShaderMaterial::set_shader_uniform(const StringName &p_param, const Variant } } -Variant ShaderMaterial::get_shader_uniform(const StringName &p_param) const { +Variant ShaderMaterial::get_shader_parameter(const StringName &p_param) const { if (param_cache.has(p_param)) { return param_cache[p_param]; } else { @@ -386,20 +388,20 @@ void ShaderMaterial::_shader_changed() { void ShaderMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_shader", "shader"), &ShaderMaterial::set_shader); ClassDB::bind_method(D_METHOD("get_shader"), &ShaderMaterial::get_shader); - ClassDB::bind_method(D_METHOD("set_shader_uniform", "param", "value"), &ShaderMaterial::set_shader_uniform); - ClassDB::bind_method(D_METHOD("get_shader_uniform", "param"), &ShaderMaterial::get_shader_uniform); + ClassDB::bind_method(D_METHOD("set_shader_parameter", "param", "value"), &ShaderMaterial::set_shader_parameter); + ClassDB::bind_method(D_METHOD("get_shader_parameter", "param"), &ShaderMaterial::get_shader_parameter); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shader", PROPERTY_HINT_RESOURCE_TYPE, "Shader"), "set_shader", "get_shader"); } void ShaderMaterial::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { String f = p_function.operator String(); - if ((f == "get_shader_uniform" || f == "set_shader_uniform") && p_idx == 0) { + if ((f == "get_shader_parameter" || f == "set_shader_parameter") && p_idx == 0) { if (shader.is_valid()) { List<PropertyInfo> pl; shader->get_shader_uniform_list(&pl); for (const PropertyInfo &E : pl) { - r_options->push_back(E.name.replace_first("shader_uniform/", "").quote()); + r_options->push_back(E.name.replace_first("shader_parameter/", "").quote()); } } } diff --git a/scene/resources/material.h b/scene/resources/material.h index 9458e859f0..6c81293ee3 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -115,8 +115,8 @@ public: void set_shader(const Ref<Shader> &p_shader); Ref<Shader> get_shader() const; - void set_shader_uniform(const StringName &p_param, const Variant &p_value); - Variant get_shader_uniform(const StringName &p_param) const; + void set_shader_parameter(const StringName &p_param, const Variant &p_value); + Variant get_shader_parameter(const StringName &p_param) const; virtual Shader::Mode get_shader_mode() const override; diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 7f318af899..b42e65c8df 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -1614,7 +1614,7 @@ void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const emit_changed(); } -void ArrayMesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, const Dictionary &p_lods, uint32_t p_flags) { +void ArrayMesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const TypedArray<Array> &p_blend_shapes, const Dictionary &p_lods, uint32_t p_flags) { ERR_FAIL_COND(p_arrays.size() != ARRAY_MAX); RS::SurfaceData surface; diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index fd3c2c4fa4..5ed4164117 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -265,7 +265,7 @@ protected: static void _bind_methods(); public: - void add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), uint32_t p_flags = 0); + void add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const TypedArray<Array> &p_blend_shapes = TypedArray<Array>(), const Dictionary &p_lods = Dictionary(), uint32_t p_flags = 0); void add_surface(uint32_t p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, const Vector<uint8_t> &p_attribute_array, const Vector<uint8_t> &p_skin_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<uint8_t> &p_blend_shape_data = Vector<uint8_t>(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>(), const Vector<RS::SurfaceData::LOD> &p_lods = Vector<RS::SurfaceData::LOD>()); diff --git a/scene/resources/particle_process_material.cpp b/scene/resources/particle_process_material.cpp index ed19101de4..e51c786786 100644 --- a/scene/resources/particle_process_material.cpp +++ b/scene/resources/particle_process_material.cpp @@ -1684,35 +1684,35 @@ void ParticleProcessMaterial::_bind_methods() { ADD_GROUP("Gravity", ""); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "gravity"), "set_gravity", "get_gravity"); ADD_GROUP("Initial Velocity", "initial_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_min", PROPERTY_HINT_RANGE, "0,1000,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_INITIAL_LINEAR_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_max", PROPERTY_HINT_RANGE, "0,1000,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_INITIAL_LINEAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_min", PROPERTY_HINT_RANGE, "0,1000,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_INITIAL_LINEAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_max", PROPERTY_HINT_RANGE, "0,1000,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_INITIAL_LINEAR_VELOCITY); ADD_GROUP("Angular Velocity", "angular_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_min", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_ANGULAR_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_max", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_ANGULAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_min", PROPERTY_HINT_RANGE, "-720,720,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_ANGULAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_max", PROPERTY_HINT_RANGE, "-720,720,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_ANGULAR_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angular_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANGULAR_VELOCITY); ADD_GROUP("Orbit Velocity", "orbit_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_min", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_ORBIT_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_max", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_ORBIT_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_min", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_ORBIT_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_max", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_ORBIT_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "orbit_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ORBIT_VELOCITY); ADD_GROUP("Linear Accel", "linear_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_LINEAR_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_LINEAR_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_LINEAR_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_LINEAR_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "linear_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_LINEAR_ACCEL); ADD_GROUP("Radial Accel", "radial_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_RADIAL_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_RADIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_RADIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_RADIAL_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "radial_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_RADIAL_ACCEL); ADD_GROUP("Tangential Accel", "tangential_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_TANGENTIAL_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_TANGENTIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_TANGENTIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_TANGENTIAL_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "tangential_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_TANGENTIAL_ACCEL); ADD_GROUP("Damping", ""); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_min", PROPERTY_HINT_RANGE, "0,100,0.01,or_greater"), "set_param_min", "get_param_min", PARAM_DAMPING); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_max", PROPERTY_HINT_RANGE, "0,100,0.01,or_greater"), "set_param_max", "get_param_max", PARAM_DAMPING); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "damping_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_DAMPING); ADD_GROUP("Angle", ""); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_min", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater,degrees"), "set_param_min", "get_param_min", PARAM_ANGLE); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_max", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater,degrees"), "set_param_max", "get_param_max", PARAM_ANGLE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_min", PROPERTY_HINT_RANGE, "-720,720,0.1,or_less,or_greater,degrees"), "set_param_min", "get_param_min", PARAM_ANGLE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_max", PROPERTY_HINT_RANGE, "-720,720,0.1,or_less,or_greater,degrees"), "set_param_max", "get_param_max", PARAM_ANGLE); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angle_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANGLE); ADD_GROUP("Scale", ""); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "scale_min", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param_min", "get_param_min", PARAM_SCALE); @@ -1741,11 +1741,11 @@ void ParticleProcessMaterial::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "turbulence_influence_over_life", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_TURB_INFLUENCE_OVER_LIFE); ADD_GROUP("Animation", "anim_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_min", PROPERTY_HINT_RANGE, "0,16,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_ANIM_SPEED); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_max", PROPERTY_HINT_RANGE, "0,16,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_ANIM_SPEED); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_min", PROPERTY_HINT_RANGE, "0,16,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_ANIM_SPEED); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_max", PROPERTY_HINT_RANGE, "0,16,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_ANIM_SPEED); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_speed_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANIM_SPEED); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_min", PROPERTY_HINT_RANGE, "0,16,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_ANIM_OFFSET); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_max", PROPERTY_HINT_RANGE, "0,16,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_ANIM_OFFSET); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_min", PROPERTY_HINT_RANGE, "0,16,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_ANIM_OFFSET); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_max", PROPERTY_HINT_RANGE, "0,16,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_ANIM_OFFSET); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_offset_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANIM_OFFSET); ADD_GROUP("Sub Emitter", "sub_emitter_"); diff --git a/scene/resources/rectangle_shape_2d.cpp b/scene/resources/rectangle_shape_2d.cpp index a64b262cb4..6ebf96db8e 100644 --- a/scene/resources/rectangle_shape_2d.cpp +++ b/scene/resources/rectangle_shape_2d.cpp @@ -41,7 +41,7 @@ void RectangleShape2D::_update_shape() { bool RectangleShape2D::_set(const StringName &p_name, const Variant &p_value) { if (p_name == "extents") { // Compatibility with Godot 3.x. // Convert to `size`, twice as big. - set_size((Vector2)p_value * 2); + set_size((Size2)p_value * 2); return true; } return false; @@ -57,13 +57,13 @@ bool RectangleShape2D::_get(const StringName &p_name, Variant &r_property) const } #endif // DISABLE_DEPRECATED -void RectangleShape2D::set_size(const Vector2 &p_size) { +void RectangleShape2D::set_size(const Size2 &p_size) { ERR_FAIL_COND_MSG(p_size.x < 0 || p_size.y < 0, "RectangleShape2D size cannot be negative."); size = p_size; _update_shape(); } -Vector2 RectangleShape2D::get_size() const { +Size2 RectangleShape2D::get_size() const { return size; } @@ -106,6 +106,6 @@ void RectangleShape2D::_bind_methods() { RectangleShape2D::RectangleShape2D() : Shape2D(PhysicsServer2D::get_singleton()->rectangle_shape_create()) { - size = Vector2(20, 20); + size = Size2(20, 20); _update_shape(); } diff --git a/scene/resources/rectangle_shape_2d.h b/scene/resources/rectangle_shape_2d.h index fa85aef428..9cc7b999be 100644 --- a/scene/resources/rectangle_shape_2d.h +++ b/scene/resources/rectangle_shape_2d.h @@ -36,7 +36,7 @@ class RectangleShape2D : public Shape2D { GDCLASS(RectangleShape2D, Shape2D); - Vector2 size; + Size2 size; void _update_shape(); protected: @@ -47,8 +47,8 @@ protected: #endif // DISABLE_DEPRECATED public: - void set_size(const Vector2 &p_size); - Vector2 get_size() const; + void set_size(const Size2 &p_size); + Size2 get_size() const; virtual void draw(const RID &p_to_rid, const Color &p_color) override; virtual Rect2 get_rect() const override; diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index 48d06934e3..4d566178a5 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -107,7 +107,7 @@ void Shader::get_shader_uniform_list(List<PropertyInfo> *p_params, bool p_get_gr _update_shader(); List<PropertyInfo> local; - RenderingServer::get_singleton()->shader_get_shader_uniform_list(shader, &local); + RenderingServer::get_singleton()->get_shader_parameter_list(shader, &local); params_cache.clear(); params_cache_dirty = false; @@ -138,35 +138,35 @@ RID Shader::get_rid() const { return shader; } -void Shader::set_default_texture_param(const StringName &p_param, const Ref<Texture2D> &p_texture, int p_index) { +void Shader::set_default_texture_parameter(const StringName &p_name, const Ref<Texture2D> &p_texture, int p_index) { if (p_texture.is_valid()) { - if (!default_textures.has(p_param)) { - default_textures[p_param] = HashMap<int, Ref<Texture2D>>(); + if (!default_textures.has(p_name)) { + default_textures[p_name] = HashMap<int, Ref<Texture2D>>(); } - default_textures[p_param][p_index] = p_texture; - RS::get_singleton()->shader_set_default_texture_param(shader, p_param, p_texture->get_rid(), p_index); + default_textures[p_name][p_index] = p_texture; + RS::get_singleton()->shader_set_default_texture_parameter(shader, p_name, p_texture->get_rid(), p_index); } else { - if (default_textures.has(p_param) && default_textures[p_param].has(p_index)) { - default_textures[p_param].erase(p_index); + if (default_textures.has(p_name) && default_textures[p_name].has(p_index)) { + default_textures[p_name].erase(p_index); - if (default_textures[p_param].is_empty()) { - default_textures.erase(p_param); + if (default_textures[p_name].is_empty()) { + default_textures.erase(p_name); } } - RS::get_singleton()->shader_set_default_texture_param(shader, p_param, RID(), p_index); + RS::get_singleton()->shader_set_default_texture_parameter(shader, p_name, RID(), p_index); } emit_changed(); } -Ref<Texture2D> Shader::get_default_texture_param(const StringName &p_param, int p_index) const { - if (default_textures.has(p_param) && default_textures[p_param].has(p_index)) { - return default_textures[p_param][p_index]; +Ref<Texture2D> Shader::get_default_texture_parameter(const StringName &p_name, int p_index) const { + if (default_textures.has(p_name) && default_textures[p_name].has(p_index)) { + return default_textures[p_name][p_index]; } return Ref<Texture2D>(); } -void Shader::get_default_texture_param_list(List<StringName> *r_textures) const { +void Shader::get_default_texture_parameter_list(List<StringName> *r_textures) const { for (const KeyValue<StringName, HashMap<int, Ref<Texture2D>>> &E : default_textures) { r_textures->push_back(E.key); } @@ -176,8 +176,8 @@ bool Shader::is_text_shader() const { return true; } -bool Shader::has_uniform(const StringName &p_param) const { - return params_cache.has("shader_uniform/" + p_param); +bool Shader::has_parameter(const StringName &p_name) const { + return params_cache.has("shader_parameter/" + p_name); } void Shader::_update_shader() const { @@ -189,10 +189,10 @@ void Shader::_bind_methods() { ClassDB::bind_method(D_METHOD("set_code", "code"), &Shader::set_code); ClassDB::bind_method(D_METHOD("get_code"), &Shader::get_code); - ClassDB::bind_method(D_METHOD("set_default_texture_param", "param", "texture", "index"), &Shader::set_default_texture_param, DEFVAL(0)); - ClassDB::bind_method(D_METHOD("get_default_texture_param", "param", "index"), &Shader::get_default_texture_param, DEFVAL(0)); + ClassDB::bind_method(D_METHOD("set_default_texture_parameter", "name", "texture", "index"), &Shader::set_default_texture_parameter, DEFVAL(0)); + ClassDB::bind_method(D_METHOD("get_default_texture_parameter", "name", "index"), &Shader::get_default_texture_parameter, DEFVAL(0)); - ClassDB::bind_method(D_METHOD("has_uniform", "name"), &Shader::has_uniform); + ClassDB::bind_method(D_METHOD("has_parameter", "name"), &Shader::has_parameter); ADD_PROPERTY(PropertyInfo(Variant::STRING, "code", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_code", "get_code"); diff --git a/scene/resources/shader.h b/scene/resources/shader.h index abc953de5f..d267e6520e 100644 --- a/scene/resources/shader.h +++ b/scene/resources/shader.h @@ -79,11 +79,11 @@ public: String get_code() const; void get_shader_uniform_list(List<PropertyInfo> *p_params, bool p_get_groups = false) const; - bool has_uniform(const StringName &p_param) const; + bool has_parameter(const StringName &p_name) const; - void set_default_texture_param(const StringName &p_uniform, const Ref<Texture2D> &p_texture, int p_index = 0); - Ref<Texture2D> get_default_texture_param(const StringName &p_uniform, int p_index = 0) const; - void get_default_texture_param_list(List<StringName> *r_textures) const; + void set_default_texture_parameter(const StringName &p_name, const Ref<Texture2D> &p_texture, int p_index = 0); + Ref<Texture2D> get_default_texture_parameter(const StringName &p_name, int p_index = 0) const; + void get_default_texture_parameter_list(List<StringName> *r_textures) const; virtual bool is_text_shader() const; diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp index ff5210f1b3..4b151eed12 100644 --- a/scene/resources/style_box.cpp +++ b/scene/resources/style_box.cpp @@ -687,7 +687,7 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const { const bool rounded_corners = (corner_radius[0] > 0) || (corner_radius[1] > 0) || (corner_radius[2] > 0) || (corner_radius[3] > 0); // Only enable antialiasing if it is actually needed. This improve performances // and maximizes sharpness for non-skewed StyleBoxes with sharp corners. - const bool aa_on = (rounded_corners || !skew.is_equal_approx(Vector2())) && anti_aliased; + const bool aa_on = (rounded_corners || !skew.is_zero_approx()) && anti_aliased; const bool blend_on = blend_border && draw_border; diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index f8f6900976..a269416d8b 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -294,7 +294,7 @@ bool ImageTexture::is_pixel_opaque(int p_x, int p_y) const { x = CLAMP(x, 0, aw); y = CLAMP(y, 0, ah); - return alpha_cache->get_bit(Point2(x, y)); + return alpha_cache->get_bit(x, y); } return true; @@ -561,7 +561,7 @@ bool PortableCompressedTexture2D::is_pixel_opaque(int p_x, int p_y) const { x = CLAMP(x, 0, aw); y = CLAMP(y, 0, ah); - return alpha_cache->get_bit(Point2(x, y)); + return alpha_cache->get_bit(x, y); } return true; @@ -1017,7 +1017,7 @@ bool CompressedTexture2D::is_pixel_opaque(int p_x, int p_y) const { x = CLAMP(x, 0, aw); y = CLAMP(y, 0, ah); - return alpha_cache->get_bit(Point2(x, y)); + return alpha_cache->get_bit(x, y); } return true; @@ -2955,7 +2955,7 @@ ImageTextureLayered::LayeredType ImageTextureLayered::get_layered_type() const { return layered_type; } -Error ImageTextureLayered::_create_from_images(const Array &p_images) { +Error ImageTextureLayered::_create_from_images(const TypedArray<Image> &p_images) { Vector<Ref<Image>> images; for (int i = 0; i < p_images.size(); i++) { Ref<Image> img = p_images[i]; @@ -2966,8 +2966,8 @@ Error ImageTextureLayered::_create_from_images(const Array &p_images) { return create_from_images(images); } -Array ImageTextureLayered::_get_images() const { - Array images; +TypedArray<Image> ImageTextureLayered::_get_images() const { + TypedArray<Image> images; for (int i = 0; i < layers; i++) { images.push_back(get_layer_data(i)); } @@ -3054,7 +3054,7 @@ void ImageTextureLayered::_bind_methods() { ClassDB::bind_method(D_METHOD("_get_images"), &ImageTextureLayered::_get_images); - ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_images", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_INTERNAL), "create_from_images", "_get_images"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_images", PROPERTY_HINT_ARRAY_TYPE, "Image", PROPERTY_USAGE_INTERNAL), "create_from_images", "_get_images"); } ImageTextureLayered::ImageTextureLayered(LayeredType p_layered_type) { diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 133b312d27..430c73dbc6 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -422,9 +422,9 @@ class ImageTextureLayered : public TextureLayered { int layers = 0; bool mipmaps = false; - Error _create_from_images(const Array &p_images); + Error _create_from_images(const TypedArray<Image> &p_images); - Array _get_images() const; + TypedArray<Image> _get_images() const; protected: static void _bind_methods(); diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index 376b53b75c..9138a82ba8 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -118,7 +118,7 @@ void TileMapPattern::remove_cell(const Vector2i &p_coords, bool p_update_size) { pattern.erase(p_coords); if (p_update_size) { - size = Vector2i(); + size = Size2i(); for (const KeyValue<Vector2i, TileMapCell> &E : pattern) { size = size.max(E.key + Vector2i(1, 1)); } @@ -157,11 +157,11 @@ TypedArray<Vector2i> TileMapPattern::get_used_cells() const { return a; } -Vector2i TileMapPattern::get_size() const { +Size2i TileMapPattern::get_size() const { return size; } -void TileMapPattern::set_size(const Vector2i &p_size) { +void TileMapPattern::set_size(const Size2i &p_size) { for (const KeyValue<Vector2i, TileMapCell> &E : pattern) { Vector2i coords = E.key; if (p_size.x <= coords.x || p_size.y <= coords.y) { @@ -178,7 +178,7 @@ bool TileMapPattern::is_empty() const { }; void TileMapPattern::clear() { - size = Vector2i(); + size = Size2i(); pattern.clear(); emit_changed(); }; diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h index 4c0823cdf2..e156679711 100644 --- a/scene/resources/tile_set.h +++ b/scene/resources/tile_set.h @@ -117,7 +117,7 @@ union TileMapCell { class TileMapPattern : public Resource { GDCLASS(TileMapPattern, Resource); - Vector2i size; + Size2i size; HashMap<Vector2i, TileMapCell> pattern; void _set_tile_data(const Vector<int> &p_data); @@ -140,8 +140,8 @@ public: TypedArray<Vector2i> get_used_cells() const; - Vector2i get_size() const; - void set_size(const Vector2i &p_size); + Size2i get_size() const; + void set_size(const Size2i &p_size); bool is_empty() const; void clear(); diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index 90f1a1bff1..70a73186bc 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -723,10 +723,10 @@ void VisualShader::add_node(Type p_type, const Ref<VisualShaderNode> &p_node, co n.node = p_node; n.position = p_position; - Ref<VisualShaderNodeUniform> uniform = n.node; - if (uniform.is_valid()) { - String valid_name = validate_uniform_name(uniform->get_uniform_name(), uniform); - uniform->set_uniform_name(valid_name); + Ref<VisualShaderNodeParameter> parameter = n.node; + if (parameter.is_valid()) { + String valid_name = validate_parameter_name(parameter->get_parameter_name(), parameter); + parameter->set_parameter_name(valid_name); } Ref<VisualShaderNodeInput> input = n.node; @@ -1279,7 +1279,7 @@ String VisualShader::validate_port_name(const String &p_port_name, VisualShaderN return name; } -String VisualShader::validate_uniform_name(const String &p_name, const Ref<VisualShaderNodeUniform> &p_uniform) const { +String VisualShader::validate_parameter_name(const String &p_name, const Ref<VisualShaderNodeParameter> &p_parameter) const { String name = p_name; //validate name first while (name.length() && !is_ascii_char(name[0])) { name = name.substr(1, name.length() - 1); @@ -1299,7 +1299,7 @@ String VisualShader::validate_uniform_name(const String &p_name, const Ref<Visua } if (name.is_empty()) { - name = p_uniform->get_caption(); + name = p_parameter->get_caption(); } int attempt = 1; @@ -1308,11 +1308,11 @@ String VisualShader::validate_uniform_name(const String &p_name, const Ref<Visua bool exists = false; for (int i = 0; i < TYPE_MAX; i++) { for (const KeyValue<int, Node> &E : graph[i].nodes) { - Ref<VisualShaderNodeUniform> node = E.value.node; - if (node == p_uniform) { //do not test on self + Ref<VisualShaderNodeParameter> node = E.value.node; + if (node == p_parameter) { //do not test on self continue; } - if (node.is_valid() && node->get_uniform_name() == name) { + if (node.is_valid() && node->get_parameter_name() == name) { exists = true; break; } @@ -1620,8 +1620,8 @@ Error VisualShader::_write_node(Type type, StringBuilder *global_code, StringBui bool skip_global = input.is_valid() && for_preview; if (!skip_global) { - Ref<VisualShaderNodeUniform> uniform = vsnode; - if (!uniform.is_valid() || !uniform->is_global_code_generated()) { + Ref<VisualShaderNodeParameter> parameter = vsnode; + if (!parameter.is_valid() || !parameter->is_global_code_generated()) { if (global_code) { *global_code += vsnode->generate_global(get_mode(), type, node); } @@ -1680,8 +1680,8 @@ Error VisualShader::_write_node(Type type, StringBuilder *global_code, StringBui VisualShaderNode *ptr = const_cast<VisualShaderNode *>(graph[type].nodes[from_node].node.ptr()); if (ptr->has_method("get_input_real_name")) { inputs[i] = ptr->call("get_input_real_name"); - } else if (ptr->has_method("get_uniform_name")) { - inputs[i] = ptr->call("get_uniform_name"); + } else if (ptr->has_method("get_parameter_name")) { + inputs[i] = ptr->call("get_parameter_name"); } else { inputs[i] = ""; } @@ -2150,8 +2150,8 @@ void VisualShader::_update_shader() const { static const char *func_name[TYPE_MAX] = { "vertex", "fragment", "light", "start", "process", "collide", "start_custom", "process_custom", "sky", "fog" }; String global_expressions; - HashSet<String> used_uniform_names; - List<VisualShaderNodeUniform *> uniforms; + HashSet<String> used_parameter_names; + List<VisualShaderNodeParameter *> parameters; HashMap<int, List<int>> emitters; HashMap<int, List<int>> varying_setters; @@ -2170,13 +2170,13 @@ void VisualShader::_update_shader() const { expr += "\n"; global_expressions += expr; } - Ref<VisualShaderNodeUniformRef> uniform_ref = E.value.node; - if (uniform_ref.is_valid()) { - used_uniform_names.insert(uniform_ref->get_uniform_name()); + Ref<VisualShaderNodeParameterRef> parameter_ref = E.value.node; + if (parameter_ref.is_valid()) { + used_parameter_names.insert(parameter_ref->get_parameter_name()); } - Ref<VisualShaderNodeUniform> uniform = E.value.node; - if (uniform.is_valid()) { - uniforms.push_back(uniform.ptr()); + Ref<VisualShaderNodeParameter> parameter = E.value.node; + if (parameter.is_valid()) { + parameters.push_back(parameter.ptr()); } Ref<VisualShaderNodeVaryingSetter> varying_setter = E.value.node; if (varying_setter.is_valid() && varying_setter->is_input_port_connected(0)) { @@ -2195,13 +2195,13 @@ void VisualShader::_update_shader() const { } } - for (int i = 0; i < uniforms.size(); i++) { - VisualShaderNodeUniform *uniform = uniforms[i]; - if (used_uniform_names.has(uniform->get_uniform_name())) { - global_code += uniform->generate_global(get_mode(), Type(i), -1); - const_cast<VisualShaderNodeUniform *>(uniform)->set_global_code_generated(true); + for (int i = 0; i < parameters.size(); i++) { + VisualShaderNodeParameter *parameter = parameters[i]; + if (used_parameter_names.has(parameter->get_parameter_name())) { + global_code += parameter->generate_global(get_mode(), Type(i), -1); + const_cast<VisualShaderNodeParameter *>(parameter)->set_global_code_generated(true); } else { - const_cast<VisualShaderNodeUniform *>(uniform)->set_global_code_generated(false); + const_cast<VisualShaderNodeParameter *>(parameter)->set_global_code_generated(false); } } @@ -2520,7 +2520,7 @@ void VisualShader::_update_shader() const { const_cast<VisualShader *>(this)->set_code(final_code); for (int i = 0; i < default_tex_params.size(); i++) { for (int j = 0; j < default_tex_params[i].params.size(); j++) { - const_cast<VisualShader *>(this)->set_default_texture_param(default_tex_params[i].name, default_tex_params[i].params[j], j); + const_cast<VisualShader *>(this)->set_default_texture_parameter(default_tex_params[i].name, default_tex_params[i].params[j], j); } } if (previous_code != final_code) { @@ -3215,20 +3215,20 @@ void VisualShaderNodeInput::_bind_methods() { VisualShaderNodeInput::VisualShaderNodeInput() { } -////////////// UniformRef +////////////// ParameterRef -RBMap<RID, List<VisualShaderNodeUniformRef::Uniform>> uniforms; +RBMap<RID, List<VisualShaderNodeParameterRef::Parameter>> parameters; -void VisualShaderNodeUniformRef::add_uniform(RID p_shader_rid, const String &p_name, UniformType p_type) { - uniforms[p_shader_rid].push_back({ p_name, p_type }); +void VisualShaderNodeParameterRef::add_parameter(RID p_shader_rid, const String &p_name, ParameterType p_type) { + parameters[p_shader_rid].push_back({ p_name, p_type }); } -void VisualShaderNodeUniformRef::clear_uniforms(RID p_shader_rid) { - uniforms[p_shader_rid].clear(); +void VisualShaderNodeParameterRef::clear_parameters(RID p_shader_rid) { + parameters[p_shader_rid].clear(); } -bool VisualShaderNodeUniformRef::has_uniform(RID p_shader_rid, const String &p_name) { - for (const VisualShaderNodeUniformRef::Uniform &E : uniforms[p_shader_rid]) { +bool VisualShaderNodeParameterRef::has_parameter(RID p_shader_rid, const String &p_name) { + for (const VisualShaderNodeParameterRef::Parameter &E : parameters[p_shader_rid]) { if (E.name == p_name) { return true; } @@ -3236,41 +3236,41 @@ bool VisualShaderNodeUniformRef::has_uniform(RID p_shader_rid, const String &p_n return false; } -String VisualShaderNodeUniformRef::get_caption() const { - return "UniformRef"; +String VisualShaderNodeParameterRef::get_caption() const { + return "ParameterRef"; } -int VisualShaderNodeUniformRef::get_input_port_count() const { +int VisualShaderNodeParameterRef::get_input_port_count() const { return 0; } -VisualShaderNodeUniformRef::PortType VisualShaderNodeUniformRef::get_input_port_type(int p_port) const { +VisualShaderNodeParameterRef::PortType VisualShaderNodeParameterRef::get_input_port_type(int p_port) const { return PortType::PORT_TYPE_SCALAR; } -String VisualShaderNodeUniformRef::get_input_port_name(int p_port) const { +String VisualShaderNodeParameterRef::get_input_port_name(int p_port) const { return ""; } -int VisualShaderNodeUniformRef::get_output_port_count() const { - switch (uniform_type) { - case UniformType::UNIFORM_TYPE_FLOAT: +int VisualShaderNodeParameterRef::get_output_port_count() const { + switch (param_type) { + case PARAMETER_TYPE_FLOAT: return 1; - case UniformType::UNIFORM_TYPE_INT: + case PARAMETER_TYPE_INT: return 1; - case UniformType::UNIFORM_TYPE_BOOLEAN: + case PARAMETER_TYPE_BOOLEAN: return 1; - case UniformType::UNIFORM_TYPE_VECTOR2: + case PARAMETER_TYPE_VECTOR2: return 1; - case UniformType::UNIFORM_TYPE_VECTOR3: + case PARAMETER_TYPE_VECTOR3: return 1; - case UniformType::UNIFORM_TYPE_VECTOR4: + case PARAMETER_TYPE_VECTOR4: return 1; - case UniformType::UNIFORM_TYPE_TRANSFORM: + case PARAMETER_TYPE_TRANSFORM: return 1; - case UniformType::UNIFORM_TYPE_COLOR: + case PARAMETER_TYPE_COLOR: return 2; - case UniformType::UNIFORM_TYPE_SAMPLER: + case UNIFORM_TYPE_SAMPLER: return 1; default: break; @@ -3278,30 +3278,30 @@ int VisualShaderNodeUniformRef::get_output_port_count() const { return 1; } -VisualShaderNodeUniformRef::PortType VisualShaderNodeUniformRef::get_output_port_type(int p_port) const { - switch (uniform_type) { - case UniformType::UNIFORM_TYPE_FLOAT: +VisualShaderNodeParameterRef::PortType VisualShaderNodeParameterRef::get_output_port_type(int p_port) const { + switch (param_type) { + case PARAMETER_TYPE_FLOAT: return PortType::PORT_TYPE_SCALAR; - case UniformType::UNIFORM_TYPE_INT: + case PARAMETER_TYPE_INT: return PortType::PORT_TYPE_SCALAR_INT; - case UniformType::UNIFORM_TYPE_BOOLEAN: + case PARAMETER_TYPE_BOOLEAN: return PortType::PORT_TYPE_BOOLEAN; - case UniformType::UNIFORM_TYPE_VECTOR2: + case PARAMETER_TYPE_VECTOR2: return PortType::PORT_TYPE_VECTOR_2D; - case UniformType::UNIFORM_TYPE_VECTOR3: + case PARAMETER_TYPE_VECTOR3: return PortType::PORT_TYPE_VECTOR_3D; - case UniformType::UNIFORM_TYPE_VECTOR4: + case PARAMETER_TYPE_VECTOR4: return PortType::PORT_TYPE_VECTOR_4D; - case UniformType::UNIFORM_TYPE_TRANSFORM: + case PARAMETER_TYPE_TRANSFORM: return PortType::PORT_TYPE_TRANSFORM; - case UniformType::UNIFORM_TYPE_COLOR: + case PARAMETER_TYPE_COLOR: if (p_port == 0) { return PortType::PORT_TYPE_VECTOR_3D; } else if (p_port == 1) { return PORT_TYPE_SCALAR; } break; - case UniformType::UNIFORM_TYPE_SAMPLER: + case UNIFORM_TYPE_SAMPLER: return PortType::PORT_TYPE_SAMPLER; default: break; @@ -3309,30 +3309,30 @@ VisualShaderNodeUniformRef::PortType VisualShaderNodeUniformRef::get_output_port return PORT_TYPE_SCALAR; } -String VisualShaderNodeUniformRef::get_output_port_name(int p_port) const { - switch (uniform_type) { - case UniformType::UNIFORM_TYPE_FLOAT: +String VisualShaderNodeParameterRef::get_output_port_name(int p_port) const { + switch (param_type) { + case PARAMETER_TYPE_FLOAT: return ""; - case UniformType::UNIFORM_TYPE_INT: + case PARAMETER_TYPE_INT: return ""; - case UniformType::UNIFORM_TYPE_BOOLEAN: + case PARAMETER_TYPE_BOOLEAN: return ""; - case UniformType::UNIFORM_TYPE_VECTOR2: + case PARAMETER_TYPE_VECTOR2: return ""; - case UniformType::UNIFORM_TYPE_VECTOR3: + case PARAMETER_TYPE_VECTOR3: return ""; - case UniformType::UNIFORM_TYPE_VECTOR4: + case PARAMETER_TYPE_VECTOR4: return ""; - case UniformType::UNIFORM_TYPE_TRANSFORM: + case PARAMETER_TYPE_TRANSFORM: return ""; - case UniformType::UNIFORM_TYPE_COLOR: + case PARAMETER_TYPE_COLOR: if (p_port == 0) { return "rgb"; } else if (p_port == 1) { return "alpha"; } break; - case UniformType::UNIFORM_TYPE_SAMPLER: + case UNIFORM_TYPE_SAMPLER: return ""; break; default: @@ -3341,85 +3341,85 @@ String VisualShaderNodeUniformRef::get_output_port_name(int p_port) const { return ""; } -void VisualShaderNodeUniformRef::set_shader_rid(const RID &p_shader_rid) { +void VisualShaderNodeParameterRef::set_shader_rid(const RID &p_shader_rid) { shader_rid = p_shader_rid; } -void VisualShaderNodeUniformRef::set_uniform_name(const String &p_name) { - uniform_name = p_name; +void VisualShaderNodeParameterRef::set_parameter_name(const String &p_name) { + parameter_name = p_name; if (shader_rid.is_valid()) { - update_uniform_type(); + update_parameter_type(); } emit_changed(); } -void VisualShaderNodeUniformRef::update_uniform_type() { - if (uniform_name != "[None]") { - uniform_type = get_uniform_type_by_name(uniform_name); +void VisualShaderNodeParameterRef::update_parameter_type() { + if (parameter_name != "[None]") { + param_type = get_parameter_type_by_name(parameter_name); } else { - uniform_type = UniformType::UNIFORM_TYPE_FLOAT; + param_type = PARAMETER_TYPE_FLOAT; } } -String VisualShaderNodeUniformRef::get_uniform_name() const { - return uniform_name; +String VisualShaderNodeParameterRef::get_parameter_name() const { + return parameter_name; } -int VisualShaderNodeUniformRef::get_uniforms_count() const { +int VisualShaderNodeParameterRef::get_parameters_count() const { ERR_FAIL_COND_V(!shader_rid.is_valid(), 0); - return uniforms[shader_rid].size(); + return parameters[shader_rid].size(); } -String VisualShaderNodeUniformRef::get_uniform_name_by_index(int p_idx) const { +String VisualShaderNodeParameterRef::get_parameter_name_by_index(int p_idx) const { ERR_FAIL_COND_V(!shader_rid.is_valid(), String()); - if (p_idx >= 0 && p_idx < uniforms[shader_rid].size()) { - return uniforms[shader_rid][p_idx].name; + if (p_idx >= 0 && p_idx < parameters[shader_rid].size()) { + return parameters[shader_rid][p_idx].name; } return ""; } -VisualShaderNodeUniformRef::UniformType VisualShaderNodeUniformRef::get_uniform_type_by_name(const String &p_name) const { - ERR_FAIL_COND_V(!shader_rid.is_valid(), UNIFORM_TYPE_FLOAT); +VisualShaderNodeParameterRef::ParameterType VisualShaderNodeParameterRef::get_parameter_type_by_name(const String &p_name) const { + ERR_FAIL_COND_V(!shader_rid.is_valid(), PARAMETER_TYPE_FLOAT); - for (int i = 0; i < uniforms[shader_rid].size(); i++) { - if (uniforms[shader_rid][i].name == p_name) { - return uniforms[shader_rid][i].type; + for (int i = 0; i < parameters[shader_rid].size(); i++) { + if (parameters[shader_rid][i].name == p_name) { + return parameters[shader_rid][i].type; } } - return UniformType::UNIFORM_TYPE_FLOAT; + return PARAMETER_TYPE_FLOAT; } -VisualShaderNodeUniformRef::UniformType VisualShaderNodeUniformRef::get_uniform_type_by_index(int p_idx) const { - ERR_FAIL_COND_V(!shader_rid.is_valid(), UNIFORM_TYPE_FLOAT); +VisualShaderNodeParameterRef::ParameterType VisualShaderNodeParameterRef::get_parameter_type_by_index(int p_idx) const { + ERR_FAIL_COND_V(!shader_rid.is_valid(), PARAMETER_TYPE_FLOAT); - if (p_idx >= 0 && p_idx < uniforms[shader_rid].size()) { - return uniforms[shader_rid][p_idx].type; + if (p_idx >= 0 && p_idx < parameters[shader_rid].size()) { + return parameters[shader_rid][p_idx].type; } - return UniformType::UNIFORM_TYPE_FLOAT; + return PARAMETER_TYPE_FLOAT; } -VisualShaderNodeUniformRef::PortType VisualShaderNodeUniformRef::get_port_type_by_index(int p_idx) const { +VisualShaderNodeParameterRef::PortType VisualShaderNodeParameterRef::get_port_type_by_index(int p_idx) const { ERR_FAIL_COND_V(!shader_rid.is_valid(), PORT_TYPE_SCALAR); - if (p_idx >= 0 && p_idx < uniforms[shader_rid].size()) { - switch (uniforms[shader_rid][p_idx].type) { - case UniformType::UNIFORM_TYPE_FLOAT: + if (p_idx >= 0 && p_idx < parameters[shader_rid].size()) { + switch (parameters[shader_rid][p_idx].type) { + case PARAMETER_TYPE_FLOAT: return PORT_TYPE_SCALAR; - case UniformType::UNIFORM_TYPE_INT: + case PARAMETER_TYPE_INT: return PORT_TYPE_SCALAR_INT; - case UniformType::UNIFORM_TYPE_SAMPLER: + case UNIFORM_TYPE_SAMPLER: return PORT_TYPE_SAMPLER; - case UniformType::UNIFORM_TYPE_VECTOR2: + case PARAMETER_TYPE_VECTOR2: return PORT_TYPE_VECTOR_2D; - case UniformType::UNIFORM_TYPE_VECTOR3: + case PARAMETER_TYPE_VECTOR3: return PORT_TYPE_VECTOR_3D; - case UniformType::UNIFORM_TYPE_VECTOR4: + case PARAMETER_TYPE_VECTOR4: return PORT_TYPE_VECTOR_4D; - case UniformType::UNIFORM_TYPE_TRANSFORM: + case PARAMETER_TYPE_TRANSFORM: return PORT_TYPE_TRANSFORM; - case UniformType::UNIFORM_TYPE_COLOR: + case PARAMETER_TYPE_COLOR: return PORT_TYPE_VECTOR_3D; default: break; @@ -3428,54 +3428,54 @@ VisualShaderNodeUniformRef::PortType VisualShaderNodeUniformRef::get_port_type_b return PORT_TYPE_SCALAR; } -String VisualShaderNodeUniformRef::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - switch (uniform_type) { - case UniformType::UNIFORM_TYPE_FLOAT: - if (uniform_name == "[None]") { +String VisualShaderNodeParameterRef::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + switch (param_type) { + case PARAMETER_TYPE_FLOAT: + if (parameter_name == "[None]") { return " " + p_output_vars[0] + " = 0.0;\n"; } break; - case UniformType::UNIFORM_TYPE_COLOR: { - String code = " " + p_output_vars[0] + " = " + get_uniform_name() + ".rgb;\n"; - code += " " + p_output_vars[1] + " = " + get_uniform_name() + ".a;\n"; + case PARAMETER_TYPE_COLOR: { + String code = " " + p_output_vars[0] + " = " + get_parameter_name() + ".rgb;\n"; + code += " " + p_output_vars[1] + " = " + get_parameter_name() + ".a;\n"; return code; } break; - case UniformType::UNIFORM_TYPE_SAMPLER: + case UNIFORM_TYPE_SAMPLER: return String(); default: break; } - return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; + return " " + p_output_vars[0] + " = " + get_parameter_name() + ";\n"; } -void VisualShaderNodeUniformRef::_set_uniform_type(int p_uniform_type) { - uniform_type = (UniformType)p_uniform_type; +void VisualShaderNodeParameterRef::_set_parameter_type(int p_type) { + param_type = (ParameterType)p_type; } -int VisualShaderNodeUniformRef::_get_uniform_type() const { - return (int)uniform_type; +int VisualShaderNodeParameterRef::_get_parameter_type() const { + return (int)param_type; } -void VisualShaderNodeUniformRef::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_uniform_name", "name"), &VisualShaderNodeUniformRef::set_uniform_name); - ClassDB::bind_method(D_METHOD("get_uniform_name"), &VisualShaderNodeUniformRef::get_uniform_name); +void VisualShaderNodeParameterRef::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_parameter_name", "name"), &VisualShaderNodeParameterRef::set_parameter_name); + ClassDB::bind_method(D_METHOD("get_parameter_name"), &VisualShaderNodeParameterRef::get_parameter_name); - ClassDB::bind_method(D_METHOD("_set_uniform_type", "type"), &VisualShaderNodeUniformRef::_set_uniform_type); - ClassDB::bind_method(D_METHOD("_get_uniform_type"), &VisualShaderNodeUniformRef::_get_uniform_type); + ClassDB::bind_method(D_METHOD("_set_parameter_type", "type"), &VisualShaderNodeParameterRef::_set_parameter_type); + ClassDB::bind_method(D_METHOD("_get_parameter_type"), &VisualShaderNodeParameterRef::_get_parameter_type); - ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "uniform_name", PROPERTY_HINT_ENUM, ""), "set_uniform_name", "get_uniform_name"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "uniform_type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_uniform_type", "_get_uniform_type"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "parameter_name", PROPERTY_HINT_ENUM, ""), "set_parameter_name", "get_parameter_name"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "param_type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_parameter_type", "_get_parameter_type"); } -Vector<StringName> VisualShaderNodeUniformRef::get_editable_properties() const { +Vector<StringName> VisualShaderNodeParameterRef::get_editable_properties() const { Vector<StringName> props; - props.push_back("uniform_name"); - props.push_back("uniform_type"); + props.push_back("parameter_name"); + props.push_back("param_type"); return props; } -VisualShaderNodeUniformRef::VisualShaderNodeUniformRef() { +VisualShaderNodeParameterRef::VisualShaderNodeParameterRef() { } //////////////////////////////////////////// @@ -3687,17 +3687,17 @@ VisualShaderNodeOutput::VisualShaderNodeOutput() { /////////////////////////// -void VisualShaderNodeUniform::set_uniform_name(const String &p_name) { - uniform_name = p_name; +void VisualShaderNodeParameter::set_parameter_name(const String &p_name) { + parameter_name = p_name; emit_signal(SNAME("name_changed")); emit_changed(); } -String VisualShaderNodeUniform::get_uniform_name() const { - return uniform_name; +String VisualShaderNodeParameter::get_parameter_name() const { + return parameter_name; } -void VisualShaderNodeUniform::set_qualifier(VisualShaderNodeUniform::Qualifier p_qual) { +void VisualShaderNodeParameter::set_qualifier(VisualShaderNodeParameter::Qualifier p_qual) { ERR_FAIL_INDEX(int(p_qual), int(QUAL_MAX)); if (qualifier == p_qual) { return; @@ -3706,26 +3706,26 @@ void VisualShaderNodeUniform::set_qualifier(VisualShaderNodeUniform::Qualifier p emit_changed(); } -VisualShaderNodeUniform::Qualifier VisualShaderNodeUniform::get_qualifier() const { +VisualShaderNodeParameter::Qualifier VisualShaderNodeParameter::get_qualifier() const { return qualifier; } -void VisualShaderNodeUniform::set_global_code_generated(bool p_enabled) { +void VisualShaderNodeParameter::set_global_code_generated(bool p_enabled) { global_code_generated = p_enabled; } -bool VisualShaderNodeUniform::is_global_code_generated() const { +bool VisualShaderNodeParameter::is_global_code_generated() const { return global_code_generated; } -void VisualShaderNodeUniform::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_uniform_name", "name"), &VisualShaderNodeUniform::set_uniform_name); - ClassDB::bind_method(D_METHOD("get_uniform_name"), &VisualShaderNodeUniform::get_uniform_name); +void VisualShaderNodeParameter::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_parameter_name", "name"), &VisualShaderNodeParameter::set_parameter_name); + ClassDB::bind_method(D_METHOD("get_parameter_name"), &VisualShaderNodeParameter::get_parameter_name); - ClassDB::bind_method(D_METHOD("set_qualifier", "qualifier"), &VisualShaderNodeUniform::set_qualifier); - ClassDB::bind_method(D_METHOD("get_qualifier"), &VisualShaderNodeUniform::get_qualifier); + ClassDB::bind_method(D_METHOD("set_qualifier", "qualifier"), &VisualShaderNodeParameter::set_qualifier); + ClassDB::bind_method(D_METHOD("get_qualifier"), &VisualShaderNodeParameter::get_qualifier); - ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "uniform_name"), "set_uniform_name", "get_uniform_name"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "parameter_name"), "set_parameter_name", "get_parameter_name"); ADD_PROPERTY(PropertyInfo(Variant::INT, "qualifier", PROPERTY_HINT_ENUM, "None,Global,Instance"), "set_qualifier", "get_qualifier"); BIND_ENUM_CONSTANT(QUAL_NONE); @@ -3734,7 +3734,7 @@ void VisualShaderNodeUniform::_bind_methods() { BIND_ENUM_CONSTANT(QUAL_MAX); } -String VisualShaderNodeUniform::_get_qual_str() const { +String VisualShaderNodeParameter::_get_qual_str() const { if (is_qualifier_supported(qualifier)) { switch (qualifier) { case QUAL_NONE: @@ -3750,11 +3750,11 @@ String VisualShaderNodeUniform::_get_qual_str() const { return String(); } -String VisualShaderNodeUniform::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const { +String VisualShaderNodeParameter::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const { List<String> keyword_list; ShaderLanguage::get_keyword_list(&keyword_list); - if (keyword_list.find(uniform_name)) { - return RTR("Shader keywords cannot be used as uniform names.\nChoose another name."); + if (keyword_list.find(parameter_name)) { + return RTR("Shader keywords cannot be used as parameter names.\nChoose another name."); } if (!is_qualifier_supported(qualifier)) { String qualifier_str; @@ -3770,66 +3770,66 @@ String VisualShaderNodeUniform::get_warning(Shader::Mode p_mode, VisualShader::T default: break; } - return vformat(RTR("This uniform type does not support the '%s' qualifier."), qualifier_str); + return vformat(RTR("This parameter type does not support the '%s' qualifier."), qualifier_str); } else if (qualifier == Qualifier::QUAL_GLOBAL) { - RS::GlobalShaderUniformType gvt = RS::get_singleton()->global_shader_uniform_get_type(uniform_name); + RS::GlobalShaderParameterType gvt = RS::get_singleton()->global_shader_parameter_get_type(parameter_name); if (gvt == RS::GLOBAL_VAR_TYPE_MAX) { - return vformat(RTR("Global uniform '%s' does not exist.\nCreate it in the Project Settings."), uniform_name); + return vformat(RTR("Global parameter '%s' does not exist.\nCreate it in the Project Settings."), parameter_name); } bool incompatible_type = false; switch (gvt) { case RS::GLOBAL_VAR_TYPE_FLOAT: { - if (!Object::cast_to<VisualShaderNodeFloatUniform>(this)) { + if (!Object::cast_to<VisualShaderNodeFloatParameter>(this)) { incompatible_type = true; } } break; case RS::GLOBAL_VAR_TYPE_INT: { - if (!Object::cast_to<VisualShaderNodeIntUniform>(this)) { + if (!Object::cast_to<VisualShaderNodeIntParameter>(this)) { incompatible_type = true; } } break; case RS::GLOBAL_VAR_TYPE_BOOL: { - if (!Object::cast_to<VisualShaderNodeBooleanUniform>(this)) { + if (!Object::cast_to<VisualShaderNodeBooleanParameter>(this)) { incompatible_type = true; } } break; case RS::GLOBAL_VAR_TYPE_COLOR: { - if (!Object::cast_to<VisualShaderNodeColorUniform>(this)) { + if (!Object::cast_to<VisualShaderNodeColorParameter>(this)) { incompatible_type = true; } } break; case RS::GLOBAL_VAR_TYPE_VEC3: { - if (!Object::cast_to<VisualShaderNodeVec3Uniform>(this)) { + if (!Object::cast_to<VisualShaderNodeVec3Parameter>(this)) { incompatible_type = true; } } break; case RS::GLOBAL_VAR_TYPE_VEC4: { - if (!Object::cast_to<VisualShaderNodeVec4Uniform>(this)) { + if (!Object::cast_to<VisualShaderNodeVec4Parameter>(this)) { incompatible_type = true; } } break; case RS::GLOBAL_VAR_TYPE_TRANSFORM: { - if (!Object::cast_to<VisualShaderNodeTransformUniform>(this)) { + if (!Object::cast_to<VisualShaderNodeTransformParameter>(this)) { incompatible_type = true; } } break; case RS::GLOBAL_VAR_TYPE_SAMPLER2D: { - if (!Object::cast_to<VisualShaderNodeTextureUniform>(this)) { + if (!Object::cast_to<VisualShaderNodeTextureParameter>(this)) { incompatible_type = true; } } break; case RS::GLOBAL_VAR_TYPE_SAMPLER3D: { - if (!Object::cast_to<VisualShaderNodeTexture3DUniform>(this)) { + if (!Object::cast_to<VisualShaderNodeTexture3DParameter>(this)) { incompatible_type = true; } } break; case RS::GLOBAL_VAR_TYPE_SAMPLER2DARRAY: { - if (!Object::cast_to<VisualShaderNodeTexture2DArrayUniform>(this)) { + if (!Object::cast_to<VisualShaderNodeTexture2DArrayParameter>(this)) { incompatible_type = true; } } break; case RS::GLOBAL_VAR_TYPE_SAMPLERCUBE: { - if (!Object::cast_to<VisualShaderNodeCubemapUniform>(this)) { + if (!Object::cast_to<VisualShaderNodeCubemapParameter>(this)) { incompatible_type = true; } } break; @@ -3837,29 +3837,29 @@ String VisualShaderNodeUniform::get_warning(Shader::Mode p_mode, VisualShader::T break; } if (incompatible_type) { - return vformat(RTR("Global uniform '%s' has an incompatible type for this kind of node.\nChange it in the Project Settings."), uniform_name); + return vformat(RTR("Global parameter '%s' has an incompatible type for this kind of node.\nChange it in the Project Settings."), parameter_name); } } return String(); } -Vector<StringName> VisualShaderNodeUniform::get_editable_properties() const { +Vector<StringName> VisualShaderNodeParameter::get_editable_properties() const { Vector<StringName> props; props.push_back("qualifier"); return props; } -VisualShaderNodeUniform::VisualShaderNodeUniform() { +VisualShaderNodeParameter::VisualShaderNodeParameter() { } ////////////// ResizeableBase -void VisualShaderNodeResizableBase::set_size(const Vector2 &p_size) { +void VisualShaderNodeResizableBase::set_size(const Size2 &p_size) { size = p_size; } -Vector2 VisualShaderNodeResizableBase::get_size() const { +Size2 VisualShaderNodeResizableBase::get_size() const { return size; } diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index 09a3917a16..88e92f15cf 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -36,7 +36,7 @@ #include "scene/gui/control.h" #include "scene/resources/shader.h" -class VisualShaderNodeUniform; +class VisualShaderNodeParameter; class VisualShaderNode; class VisualShader : public Shader { @@ -229,7 +229,7 @@ public: // internal methods String generate_preview_shader(Type p_type, int p_node, int p_port, Vector<DefaultTextureParam> &r_default_tex_params) const; String validate_port_name(const String &p_port_name, VisualShaderNode *p_node, int p_port_id, bool p_output) const; - String validate_uniform_name(const String &p_name, const Ref<VisualShaderNodeUniform> &p_uniform) const; + String validate_parameter_name(const String &p_name, const Ref<VisualShaderNodeParameter> &p_parameter) const; VisualShader(); }; @@ -499,8 +499,8 @@ public: VisualShaderNodeOutput(); }; -class VisualShaderNodeUniform : public VisualShaderNode { - GDCLASS(VisualShaderNodeUniform, VisualShaderNode); +class VisualShaderNodeParameter : public VisualShaderNode { + GDCLASS(VisualShaderNodeParameter, VisualShaderNode); public: enum Qualifier { @@ -511,7 +511,7 @@ public: }; private: - String uniform_name = ""; + String parameter_name = ""; Qualifier qualifier = QUAL_NONE; bool global_code_generated = false; @@ -520,8 +520,8 @@ protected: String _get_qual_str() const; public: - void set_uniform_name(const String &p_name); - String get_uniform_name() const; + void set_parameter_name(const String &p_name); + String get_parameter_name() const; void set_qualifier(Qualifier p_qual); Qualifier get_qualifier() const; @@ -535,44 +535,44 @@ public: virtual Vector<StringName> get_editable_properties() const override; virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const override; - VisualShaderNodeUniform(); + VisualShaderNodeParameter(); }; -VARIANT_ENUM_CAST(VisualShaderNodeUniform::Qualifier) +VARIANT_ENUM_CAST(VisualShaderNodeParameter::Qualifier) -class VisualShaderNodeUniformRef : public VisualShaderNode { - GDCLASS(VisualShaderNodeUniformRef, VisualShaderNode); +class VisualShaderNodeParameterRef : public VisualShaderNode { + GDCLASS(VisualShaderNodeParameterRef, VisualShaderNode); public: - enum UniformType { - UNIFORM_TYPE_FLOAT, - UNIFORM_TYPE_INT, - UNIFORM_TYPE_BOOLEAN, - UNIFORM_TYPE_VECTOR2, - UNIFORM_TYPE_VECTOR3, - UNIFORM_TYPE_VECTOR4, - UNIFORM_TYPE_TRANSFORM, - UNIFORM_TYPE_COLOR, + enum ParameterType { + PARAMETER_TYPE_FLOAT, + PARAMETER_TYPE_INT, + PARAMETER_TYPE_BOOLEAN, + PARAMETER_TYPE_VECTOR2, + PARAMETER_TYPE_VECTOR3, + PARAMETER_TYPE_VECTOR4, + PARAMETER_TYPE_TRANSFORM, + PARAMETER_TYPE_COLOR, UNIFORM_TYPE_SAMPLER, }; - struct Uniform { + struct Parameter { String name; - UniformType type; + ParameterType type; }; private: RID shader_rid; - String uniform_name = "[None]"; - UniformType uniform_type = UniformType::UNIFORM_TYPE_FLOAT; + String parameter_name = "[None]"; + ParameterType param_type = ParameterType::PARAMETER_TYPE_FLOAT; protected: static void _bind_methods(); public: - static void add_uniform(RID p_shader_rid, const String &p_name, UniformType p_type); - static void clear_uniforms(RID p_shader_rid); - static bool has_uniform(RID p_shader_rid, const String &p_name); + static void add_parameter(RID p_shader_rid, const String &p_name, ParameterType p_type); + static void clear_parameters(RID p_shader_rid); + static bool has_parameter(RID p_shader_rid, const String &p_name); public: virtual String get_caption() const override; @@ -587,40 +587,40 @@ public: void set_shader_rid(const RID &p_shader); - void set_uniform_name(const String &p_name); - String get_uniform_name() const; + void set_parameter_name(const String &p_name); + String get_parameter_name() const; - void update_uniform_type(); + void update_parameter_type(); - void _set_uniform_type(int p_uniform_type); - int _get_uniform_type() const; + void _set_parameter_type(int p_parameter_type); + int _get_parameter_type() const; - int get_uniforms_count() const; - String get_uniform_name_by_index(int p_idx) const; - UniformType get_uniform_type_by_name(const String &p_name) const; - UniformType get_uniform_type_by_index(int p_idx) const; + int get_parameters_count() const; + String get_parameter_name_by_index(int p_idx) const; + ParameterType get_parameter_type_by_name(const String &p_name) const; + ParameterType get_parameter_type_by_index(int p_idx) const; PortType get_port_type_by_index(int p_idx) const; virtual Vector<StringName> get_editable_properties() const override; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; - VisualShaderNodeUniformRef(); + VisualShaderNodeParameterRef(); }; class VisualShaderNodeResizableBase : public VisualShaderNode { GDCLASS(VisualShaderNodeResizableBase, VisualShaderNode); protected: - Vector2 size = Size2(0, 0); + Size2 size = Size2(0, 0); bool allow_v_resize = true; protected: static void _bind_methods(); public: - void set_size(const Vector2 &p_size); - Vector2 get_size() const; + void set_size(const Size2 &p_size); + Size2 get_size() const; bool is_allow_v_resize() const; void set_allow_v_resize(bool p_enabled); diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index a968aebdaa..72e55ac47d 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -4712,44 +4712,44 @@ VisualShaderNodeTransformDecompose::VisualShaderNodeTransformDecompose() { set_input_port_default_value(0, Transform3D()); } -////////////// Float Uniform +////////////// Float Parameter -String VisualShaderNodeFloatUniform::get_caption() const { - return "FloatUniform"; +String VisualShaderNodeFloatParameter::get_caption() const { + return "FloatParameter"; } -int VisualShaderNodeFloatUniform::get_input_port_count() const { +int VisualShaderNodeFloatParameter::get_input_port_count() const { return 0; } -VisualShaderNodeFloatUniform::PortType VisualShaderNodeFloatUniform::get_input_port_type(int p_port) const { +VisualShaderNodeFloatParameter::PortType VisualShaderNodeFloatParameter::get_input_port_type(int p_port) const { return PORT_TYPE_SCALAR; } -String VisualShaderNodeFloatUniform::get_input_port_name(int p_port) const { +String VisualShaderNodeFloatParameter::get_input_port_name(int p_port) const { return String(); } -int VisualShaderNodeFloatUniform::get_output_port_count() const { +int VisualShaderNodeFloatParameter::get_output_port_count() const { return 1; } -VisualShaderNodeFloatUniform::PortType VisualShaderNodeFloatUniform::get_output_port_type(int p_port) const { +VisualShaderNodeFloatParameter::PortType VisualShaderNodeFloatParameter::get_output_port_type(int p_port) const { return PORT_TYPE_SCALAR; } -String VisualShaderNodeFloatUniform::get_output_port_name(int p_port) const { +String VisualShaderNodeFloatParameter::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } -String VisualShaderNodeFloatUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { +String VisualShaderNodeFloatParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { String code = ""; if (hint == HINT_RANGE) { - code += _get_qual_str() + "uniform float " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ")"; + code += _get_qual_str() + "uniform float " + get_parameter_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ")"; } else if (hint == HINT_RANGE_STEP) { - code += _get_qual_str() + "uniform float " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ", " + rtos(hint_range_step) + ")"; + code += _get_qual_str() + "uniform float " + get_parameter_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ", " + rtos(hint_range_step) + ")"; } else { - code += _get_qual_str() + "uniform float " + get_uniform_name(); + code += _get_qual_str() + "uniform float " + get_parameter_name(); } if (default_value_enabled) { code += " = " + rtos(default_value); @@ -4758,19 +4758,19 @@ String VisualShaderNodeFloatUniform::generate_global(Shader::Mode p_mode, Visual return code; } -String VisualShaderNodeFloatUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; +String VisualShaderNodeFloatParameter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return " " + p_output_vars[0] + " = " + get_parameter_name() + ";\n"; } -bool VisualShaderNodeFloatUniform::is_show_prop_names() const { +bool VisualShaderNodeFloatParameter::is_show_prop_names() const { return true; } -bool VisualShaderNodeFloatUniform::is_use_prop_slots() const { +bool VisualShaderNodeFloatParameter::is_use_prop_slots() const { return true; } -void VisualShaderNodeFloatUniform::set_hint(Hint p_hint) { +void VisualShaderNodeFloatParameter::set_hint(Hint p_hint) { ERR_FAIL_INDEX(int(p_hint), int(HINT_MAX)); if (hint == p_hint) { return; @@ -4779,11 +4779,11 @@ void VisualShaderNodeFloatUniform::set_hint(Hint p_hint) { emit_changed(); } -VisualShaderNodeFloatUniform::Hint VisualShaderNodeFloatUniform::get_hint() const { +VisualShaderNodeFloatParameter::Hint VisualShaderNodeFloatParameter::get_hint() const { return hint; } -void VisualShaderNodeFloatUniform::set_min(float p_value) { +void VisualShaderNodeFloatParameter::set_min(float p_value) { if (Math::is_equal_approx(hint_range_min, p_value)) { return; } @@ -4791,11 +4791,11 @@ void VisualShaderNodeFloatUniform::set_min(float p_value) { emit_changed(); } -float VisualShaderNodeFloatUniform::get_min() const { +float VisualShaderNodeFloatParameter::get_min() const { return hint_range_min; } -void VisualShaderNodeFloatUniform::set_max(float p_value) { +void VisualShaderNodeFloatParameter::set_max(float p_value) { if (Math::is_equal_approx(hint_range_max, p_value)) { return; } @@ -4803,11 +4803,11 @@ void VisualShaderNodeFloatUniform::set_max(float p_value) { emit_changed(); } -float VisualShaderNodeFloatUniform::get_max() const { +float VisualShaderNodeFloatParameter::get_max() const { return hint_range_max; } -void VisualShaderNodeFloatUniform::set_step(float p_value) { +void VisualShaderNodeFloatParameter::set_step(float p_value) { if (Math::is_equal_approx(hint_range_step, p_value)) { return; } @@ -4815,11 +4815,11 @@ void VisualShaderNodeFloatUniform::set_step(float p_value) { emit_changed(); } -float VisualShaderNodeFloatUniform::get_step() const { +float VisualShaderNodeFloatParameter::get_step() const { return hint_range_step; } -void VisualShaderNodeFloatUniform::set_default_value_enabled(bool p_enabled) { +void VisualShaderNodeFloatParameter::set_default_value_enabled(bool p_enabled) { if (default_value_enabled == p_enabled) { return; } @@ -4827,11 +4827,11 @@ void VisualShaderNodeFloatUniform::set_default_value_enabled(bool p_enabled) { emit_changed(); } -bool VisualShaderNodeFloatUniform::is_default_value_enabled() const { +bool VisualShaderNodeFloatParameter::is_default_value_enabled() const { return default_value_enabled; } -void VisualShaderNodeFloatUniform::set_default_value(float p_value) { +void VisualShaderNodeFloatParameter::set_default_value(float p_value) { if (Math::is_equal_approx(default_value, p_value)) { return; } @@ -4839,28 +4839,28 @@ void VisualShaderNodeFloatUniform::set_default_value(float p_value) { emit_changed(); } -float VisualShaderNodeFloatUniform::get_default_value() const { +float VisualShaderNodeFloatParameter::get_default_value() const { return default_value; } -void VisualShaderNodeFloatUniform::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_hint", "hint"), &VisualShaderNodeFloatUniform::set_hint); - ClassDB::bind_method(D_METHOD("get_hint"), &VisualShaderNodeFloatUniform::get_hint); +void VisualShaderNodeFloatParameter::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_hint", "hint"), &VisualShaderNodeFloatParameter::set_hint); + ClassDB::bind_method(D_METHOD("get_hint"), &VisualShaderNodeFloatParameter::get_hint); - ClassDB::bind_method(D_METHOD("set_min", "value"), &VisualShaderNodeFloatUniform::set_min); - ClassDB::bind_method(D_METHOD("get_min"), &VisualShaderNodeFloatUniform::get_min); + ClassDB::bind_method(D_METHOD("set_min", "value"), &VisualShaderNodeFloatParameter::set_min); + ClassDB::bind_method(D_METHOD("get_min"), &VisualShaderNodeFloatParameter::get_min); - ClassDB::bind_method(D_METHOD("set_max", "value"), &VisualShaderNodeFloatUniform::set_max); - ClassDB::bind_method(D_METHOD("get_max"), &VisualShaderNodeFloatUniform::get_max); + ClassDB::bind_method(D_METHOD("set_max", "value"), &VisualShaderNodeFloatParameter::set_max); + ClassDB::bind_method(D_METHOD("get_max"), &VisualShaderNodeFloatParameter::get_max); - ClassDB::bind_method(D_METHOD("set_step", "value"), &VisualShaderNodeFloatUniform::set_step); - ClassDB::bind_method(D_METHOD("get_step"), &VisualShaderNodeFloatUniform::get_step); + ClassDB::bind_method(D_METHOD("set_step", "value"), &VisualShaderNodeFloatParameter::set_step); + ClassDB::bind_method(D_METHOD("get_step"), &VisualShaderNodeFloatParameter::get_step); - ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeFloatUniform::set_default_value_enabled); - ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeFloatUniform::is_default_value_enabled); + ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeFloatParameter::set_default_value_enabled); + ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeFloatParameter::is_default_value_enabled); - ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeFloatUniform::set_default_value); - ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeFloatUniform::get_default_value); + ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeFloatParameter::set_default_value); + ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeFloatParameter::get_default_value); ADD_PROPERTY(PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_ENUM, "None,Range,Range+Step"), "set_hint", "get_hint"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "min"), "set_min", "get_min"); @@ -4875,16 +4875,16 @@ void VisualShaderNodeFloatUniform::_bind_methods() { BIND_ENUM_CONSTANT(HINT_MAX); } -bool VisualShaderNodeFloatUniform::is_qualifier_supported(Qualifier p_qual) const { +bool VisualShaderNodeFloatParameter::is_qualifier_supported(Qualifier p_qual) const { return true; // all qualifiers are supported } -bool VisualShaderNodeFloatUniform::is_convertible_to_constant() const { +bool VisualShaderNodeFloatParameter::is_convertible_to_constant() const { return true; // conversion is allowed } -Vector<StringName> VisualShaderNodeFloatUniform::get_editable_properties() const { - Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); +Vector<StringName> VisualShaderNodeFloatParameter::get_editable_properties() const { + Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties(); props.push_back("hint"); if (hint == HINT_RANGE || hint == HINT_RANGE_STEP) { props.push_back("min"); @@ -4900,47 +4900,47 @@ Vector<StringName> VisualShaderNodeFloatUniform::get_editable_properties() const return props; } -VisualShaderNodeFloatUniform::VisualShaderNodeFloatUniform() { +VisualShaderNodeFloatParameter::VisualShaderNodeFloatParameter() { } -////////////// Integer Uniform +////////////// Integer Parametet -String VisualShaderNodeIntUniform::get_caption() const { - return "IntUniform"; +String VisualShaderNodeIntParameter::get_caption() const { + return "IntParameter"; } -int VisualShaderNodeIntUniform::get_input_port_count() const { +int VisualShaderNodeIntParameter::get_input_port_count() const { return 0; } -VisualShaderNodeIntUniform::PortType VisualShaderNodeIntUniform::get_input_port_type(int p_port) const { +VisualShaderNodeIntParameter::PortType VisualShaderNodeIntParameter::get_input_port_type(int p_port) const { return PORT_TYPE_SCALAR_INT; } -String VisualShaderNodeIntUniform::get_input_port_name(int p_port) const { +String VisualShaderNodeIntParameter::get_input_port_name(int p_port) const { return String(); } -int VisualShaderNodeIntUniform::get_output_port_count() const { +int VisualShaderNodeIntParameter::get_output_port_count() const { return 1; } -VisualShaderNodeIntUniform::PortType VisualShaderNodeIntUniform::get_output_port_type(int p_port) const { +VisualShaderNodeIntParameter::PortType VisualShaderNodeIntParameter::get_output_port_type(int p_port) const { return PORT_TYPE_SCALAR_INT; } -String VisualShaderNodeIntUniform::get_output_port_name(int p_port) const { +String VisualShaderNodeIntParameter::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } -String VisualShaderNodeIntUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { +String VisualShaderNodeIntParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { String code = ""; if (hint == HINT_RANGE) { - code += _get_qual_str() + "uniform int " + get_uniform_name() + " : hint_range(" + itos(hint_range_min) + ", " + itos(hint_range_max) + ")"; + code += _get_qual_str() + "uniform int " + get_parameter_name() + " : hint_range(" + itos(hint_range_min) + ", " + itos(hint_range_max) + ")"; } else if (hint == HINT_RANGE_STEP) { - code += _get_qual_str() + "uniform int " + get_uniform_name() + " : hint_range(" + itos(hint_range_min) + ", " + itos(hint_range_max) + ", " + itos(hint_range_step) + ")"; + code += _get_qual_str() + "uniform int " + get_parameter_name() + " : hint_range(" + itos(hint_range_min) + ", " + itos(hint_range_max) + ", " + itos(hint_range_step) + ")"; } else { - code += _get_qual_str() + "uniform int " + get_uniform_name(); + code += _get_qual_str() + "uniform int " + get_parameter_name(); } if (default_value_enabled) { code += " = " + itos(default_value); @@ -4949,19 +4949,19 @@ String VisualShaderNodeIntUniform::generate_global(Shader::Mode p_mode, VisualSh return code; } -String VisualShaderNodeIntUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; +String VisualShaderNodeIntParameter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return " " + p_output_vars[0] + " = " + get_parameter_name() + ";\n"; } -bool VisualShaderNodeIntUniform::is_show_prop_names() const { +bool VisualShaderNodeIntParameter::is_show_prop_names() const { return true; } -bool VisualShaderNodeIntUniform::is_use_prop_slots() const { +bool VisualShaderNodeIntParameter::is_use_prop_slots() const { return true; } -void VisualShaderNodeIntUniform::set_hint(Hint p_hint) { +void VisualShaderNodeIntParameter::set_hint(Hint p_hint) { ERR_FAIL_INDEX(int(p_hint), int(HINT_MAX)); if (hint == p_hint) { return; @@ -4970,11 +4970,11 @@ void VisualShaderNodeIntUniform::set_hint(Hint p_hint) { emit_changed(); } -VisualShaderNodeIntUniform::Hint VisualShaderNodeIntUniform::get_hint() const { +VisualShaderNodeIntParameter::Hint VisualShaderNodeIntParameter::get_hint() const { return hint; } -void VisualShaderNodeIntUniform::set_min(int p_value) { +void VisualShaderNodeIntParameter::set_min(int p_value) { if (hint_range_min == p_value) { return; } @@ -4982,11 +4982,11 @@ void VisualShaderNodeIntUniform::set_min(int p_value) { emit_changed(); } -int VisualShaderNodeIntUniform::get_min() const { +int VisualShaderNodeIntParameter::get_min() const { return hint_range_min; } -void VisualShaderNodeIntUniform::set_max(int p_value) { +void VisualShaderNodeIntParameter::set_max(int p_value) { if (hint_range_max == p_value) { return; } @@ -4994,11 +4994,11 @@ void VisualShaderNodeIntUniform::set_max(int p_value) { emit_changed(); } -int VisualShaderNodeIntUniform::get_max() const { +int VisualShaderNodeIntParameter::get_max() const { return hint_range_max; } -void VisualShaderNodeIntUniform::set_step(int p_value) { +void VisualShaderNodeIntParameter::set_step(int p_value) { if (hint_range_step == p_value) { return; } @@ -5006,11 +5006,11 @@ void VisualShaderNodeIntUniform::set_step(int p_value) { emit_changed(); } -int VisualShaderNodeIntUniform::get_step() const { +int VisualShaderNodeIntParameter::get_step() const { return hint_range_step; } -void VisualShaderNodeIntUniform::set_default_value_enabled(bool p_default_value_enabled) { +void VisualShaderNodeIntParameter::set_default_value_enabled(bool p_default_value_enabled) { if (default_value_enabled == p_default_value_enabled) { return; } @@ -5018,11 +5018,11 @@ void VisualShaderNodeIntUniform::set_default_value_enabled(bool p_default_value_ emit_changed(); } -bool VisualShaderNodeIntUniform::is_default_value_enabled() const { +bool VisualShaderNodeIntParameter::is_default_value_enabled() const { return default_value_enabled; } -void VisualShaderNodeIntUniform::set_default_value(int p_default_value) { +void VisualShaderNodeIntParameter::set_default_value(int p_default_value) { if (default_value == p_default_value) { return; } @@ -5030,28 +5030,28 @@ void VisualShaderNodeIntUniform::set_default_value(int p_default_value) { emit_changed(); } -int VisualShaderNodeIntUniform::get_default_value() const { +int VisualShaderNodeIntParameter::get_default_value() const { return default_value; } -void VisualShaderNodeIntUniform::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_hint", "hint"), &VisualShaderNodeIntUniform::set_hint); - ClassDB::bind_method(D_METHOD("get_hint"), &VisualShaderNodeIntUniform::get_hint); +void VisualShaderNodeIntParameter::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_hint", "hint"), &VisualShaderNodeIntParameter::set_hint); + ClassDB::bind_method(D_METHOD("get_hint"), &VisualShaderNodeIntParameter::get_hint); - ClassDB::bind_method(D_METHOD("set_min", "value"), &VisualShaderNodeIntUniform::set_min); - ClassDB::bind_method(D_METHOD("get_min"), &VisualShaderNodeIntUniform::get_min); + ClassDB::bind_method(D_METHOD("set_min", "value"), &VisualShaderNodeIntParameter::set_min); + ClassDB::bind_method(D_METHOD("get_min"), &VisualShaderNodeIntParameter::get_min); - ClassDB::bind_method(D_METHOD("set_max", "value"), &VisualShaderNodeIntUniform::set_max); - ClassDB::bind_method(D_METHOD("get_max"), &VisualShaderNodeIntUniform::get_max); + ClassDB::bind_method(D_METHOD("set_max", "value"), &VisualShaderNodeIntParameter::set_max); + ClassDB::bind_method(D_METHOD("get_max"), &VisualShaderNodeIntParameter::get_max); - ClassDB::bind_method(D_METHOD("set_step", "value"), &VisualShaderNodeIntUniform::set_step); - ClassDB::bind_method(D_METHOD("get_step"), &VisualShaderNodeIntUniform::get_step); + ClassDB::bind_method(D_METHOD("set_step", "value"), &VisualShaderNodeIntParameter::set_step); + ClassDB::bind_method(D_METHOD("get_step"), &VisualShaderNodeIntParameter::get_step); - ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeIntUniform::set_default_value_enabled); - ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeIntUniform::is_default_value_enabled); + ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeIntParameter::set_default_value_enabled); + ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeIntParameter::is_default_value_enabled); - ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeIntUniform::set_default_value); - ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeIntUniform::get_default_value); + ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeIntParameter::set_default_value); + ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeIntParameter::get_default_value); ADD_PROPERTY(PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_ENUM, "None,Range,Range + Step"), "set_hint", "get_hint"); ADD_PROPERTY(PropertyInfo(Variant::INT, "min"), "set_min", "get_min"); @@ -5066,16 +5066,16 @@ void VisualShaderNodeIntUniform::_bind_methods() { BIND_ENUM_CONSTANT(HINT_MAX); } -bool VisualShaderNodeIntUniform::is_qualifier_supported(Qualifier p_qual) const { +bool VisualShaderNodeIntParameter::is_qualifier_supported(Qualifier p_qual) const { return true; // all qualifiers are supported } -bool VisualShaderNodeIntUniform::is_convertible_to_constant() const { +bool VisualShaderNodeIntParameter::is_convertible_to_constant() const { return true; // conversion is allowed } -Vector<StringName> VisualShaderNodeIntUniform::get_editable_properties() const { - Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); +Vector<StringName> VisualShaderNodeIntParameter::get_editable_properties() const { + Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties(); props.push_back("hint"); if (hint == HINT_RANGE || hint == HINT_RANGE_STEP) { props.push_back("min"); @@ -5091,40 +5091,40 @@ Vector<StringName> VisualShaderNodeIntUniform::get_editable_properties() const { return props; } -VisualShaderNodeIntUniform::VisualShaderNodeIntUniform() { +VisualShaderNodeIntParameter::VisualShaderNodeIntParameter() { } -////////////// Boolean Uniform +////////////// Boolean Parameter -String VisualShaderNodeBooleanUniform::get_caption() const { - return "BooleanUniform"; +String VisualShaderNodeBooleanParameter::get_caption() const { + return "BooleanParameter"; } -int VisualShaderNodeBooleanUniform::get_input_port_count() const { +int VisualShaderNodeBooleanParameter::get_input_port_count() const { return 0; } -VisualShaderNodeBooleanUniform::PortType VisualShaderNodeBooleanUniform::get_input_port_type(int p_port) const { +VisualShaderNodeBooleanParameter::PortType VisualShaderNodeBooleanParameter::get_input_port_type(int p_port) const { return PORT_TYPE_BOOLEAN; } -String VisualShaderNodeBooleanUniform::get_input_port_name(int p_port) const { +String VisualShaderNodeBooleanParameter::get_input_port_name(int p_port) const { return String(); } -int VisualShaderNodeBooleanUniform::get_output_port_count() const { +int VisualShaderNodeBooleanParameter::get_output_port_count() const { return 1; } -VisualShaderNodeBooleanUniform::PortType VisualShaderNodeBooleanUniform::get_output_port_type(int p_port) const { +VisualShaderNodeBooleanParameter::PortType VisualShaderNodeBooleanParameter::get_output_port_type(int p_port) const { return PORT_TYPE_BOOLEAN; } -String VisualShaderNodeBooleanUniform::get_output_port_name(int p_port) const { +String VisualShaderNodeBooleanParameter::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } -void VisualShaderNodeBooleanUniform::set_default_value_enabled(bool p_default_value_enabled) { +void VisualShaderNodeBooleanParameter::set_default_value_enabled(bool p_default_value_enabled) { if (default_value_enabled == p_default_value_enabled) { return; } @@ -5132,11 +5132,11 @@ void VisualShaderNodeBooleanUniform::set_default_value_enabled(bool p_default_va emit_changed(); } -bool VisualShaderNodeBooleanUniform::is_default_value_enabled() const { +bool VisualShaderNodeBooleanParameter::is_default_value_enabled() const { return default_value_enabled; } -void VisualShaderNodeBooleanUniform::set_default_value(bool p_default_value) { +void VisualShaderNodeBooleanParameter::set_default_value(bool p_default_value) { if (default_value == p_default_value) { return; } @@ -5144,12 +5144,12 @@ void VisualShaderNodeBooleanUniform::set_default_value(bool p_default_value) { emit_changed(); } -bool VisualShaderNodeBooleanUniform::get_default_value() const { +bool VisualShaderNodeBooleanParameter::get_default_value() const { return default_value; } -String VisualShaderNodeBooleanUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { - String code = _get_qual_str() + "uniform bool " + get_uniform_name(); +String VisualShaderNodeBooleanParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = _get_qual_str() + "uniform bool " + get_parameter_name(); if (default_value_enabled) { if (default_value) { code += " = true"; @@ -5161,39 +5161,39 @@ String VisualShaderNodeBooleanUniform::generate_global(Shader::Mode p_mode, Visu return code; } -String VisualShaderNodeBooleanUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; +String VisualShaderNodeBooleanParameter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return " " + p_output_vars[0] + " = " + get_parameter_name() + ";\n"; } -bool VisualShaderNodeBooleanUniform::is_show_prop_names() const { +bool VisualShaderNodeBooleanParameter::is_show_prop_names() const { return true; } -bool VisualShaderNodeBooleanUniform::is_use_prop_slots() const { +bool VisualShaderNodeBooleanParameter::is_use_prop_slots() const { return true; } -void VisualShaderNodeBooleanUniform::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeBooleanUniform::set_default_value_enabled); - ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeBooleanUniform::is_default_value_enabled); +void VisualShaderNodeBooleanParameter::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeBooleanParameter::set_default_value_enabled); + ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeBooleanParameter::is_default_value_enabled); - ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeBooleanUniform::set_default_value); - ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeBooleanUniform::get_default_value); + ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeBooleanParameter::set_default_value); + ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeBooleanParameter::get_default_value); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value"), "set_default_value", "get_default_value"); } -bool VisualShaderNodeBooleanUniform::is_qualifier_supported(Qualifier p_qual) const { +bool VisualShaderNodeBooleanParameter::is_qualifier_supported(Qualifier p_qual) const { return true; // all qualifiers are supported } -bool VisualShaderNodeBooleanUniform::is_convertible_to_constant() const { +bool VisualShaderNodeBooleanParameter::is_convertible_to_constant() const { return true; // conversion is allowed } -Vector<StringName> VisualShaderNodeBooleanUniform::get_editable_properties() const { - Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); +Vector<StringName> VisualShaderNodeBooleanParameter::get_editable_properties() const { + Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties(); props.push_back("default_value_enabled"); if (default_value_enabled) { props.push_back("default_value"); @@ -5201,47 +5201,47 @@ Vector<StringName> VisualShaderNodeBooleanUniform::get_editable_properties() con return props; } -VisualShaderNodeBooleanUniform::VisualShaderNodeBooleanUniform() { +VisualShaderNodeBooleanParameter::VisualShaderNodeBooleanParameter() { } -////////////// Color Uniform +////////////// Color Parameter -String VisualShaderNodeColorUniform::get_caption() const { - return "ColorUniform"; +String VisualShaderNodeColorParameter::get_caption() const { + return "ColorParameter"; } -int VisualShaderNodeColorUniform::get_input_port_count() const { +int VisualShaderNodeColorParameter::get_input_port_count() const { return 0; } -VisualShaderNodeColorUniform::PortType VisualShaderNodeColorUniform::get_input_port_type(int p_port) const { +VisualShaderNodeColorParameter::PortType VisualShaderNodeColorParameter::get_input_port_type(int p_port) const { return PORT_TYPE_SCALAR; } -String VisualShaderNodeColorUniform::get_input_port_name(int p_port) const { +String VisualShaderNodeColorParameter::get_input_port_name(int p_port) const { return String(); } -int VisualShaderNodeColorUniform::get_output_port_count() const { +int VisualShaderNodeColorParameter::get_output_port_count() const { return 1; } -VisualShaderNodeColorUniform::PortType VisualShaderNodeColorUniform::get_output_port_type(int p_port) const { +VisualShaderNodeColorParameter::PortType VisualShaderNodeColorParameter::get_output_port_type(int p_port) const { return p_port == 0 ? PORT_TYPE_VECTOR_4D : PORT_TYPE_SCALAR; } -String VisualShaderNodeColorUniform::get_output_port_name(int p_port) const { +String VisualShaderNodeColorParameter::get_output_port_name(int p_port) const { return "color"; } -bool VisualShaderNodeColorUniform::is_output_port_expandable(int p_port) const { +bool VisualShaderNodeColorParameter::is_output_port_expandable(int p_port) const { if (p_port == 0) { return true; } return false; } -void VisualShaderNodeColorUniform::set_default_value_enabled(bool p_enabled) { +void VisualShaderNodeColorParameter::set_default_value_enabled(bool p_enabled) { if (default_value_enabled == p_enabled) { return; } @@ -5249,11 +5249,11 @@ void VisualShaderNodeColorUniform::set_default_value_enabled(bool p_enabled) { emit_changed(); } -bool VisualShaderNodeColorUniform::is_default_value_enabled() const { +bool VisualShaderNodeColorParameter::is_default_value_enabled() const { return default_value_enabled; } -void VisualShaderNodeColorUniform::set_default_value(const Color &p_value) { +void VisualShaderNodeColorParameter::set_default_value(const Color &p_value) { if (default_value.is_equal_approx(p_value)) { return; } @@ -5261,12 +5261,12 @@ void VisualShaderNodeColorUniform::set_default_value(const Color &p_value) { emit_changed(); } -Color VisualShaderNodeColorUniform::get_default_value() const { +Color VisualShaderNodeColorParameter::get_default_value() const { return default_value; } -String VisualShaderNodeColorUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { - String code = _get_qual_str() + "uniform vec4 " + get_uniform_name() + " : source_color"; +String VisualShaderNodeColorParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = _get_qual_str() + "uniform vec4 " + get_parameter_name() + " : source_color"; if (default_value_enabled) { code += vformat(" = vec4(%.6f, %.6f, %.6f, %.6f)", default_value.r, default_value.g, default_value.b, default_value.a); } @@ -5274,35 +5274,35 @@ String VisualShaderNodeColorUniform::generate_global(Shader::Mode p_mode, Visual return code; } -String VisualShaderNodeColorUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; +String VisualShaderNodeColorParameter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return " " + p_output_vars[0] + " = " + get_parameter_name() + ";\n"; } -bool VisualShaderNodeColorUniform::is_show_prop_names() const { +bool VisualShaderNodeColorParameter::is_show_prop_names() const { return true; } -void VisualShaderNodeColorUniform::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeColorUniform::set_default_value_enabled); - ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeColorUniform::is_default_value_enabled); +void VisualShaderNodeColorParameter::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeColorParameter::set_default_value_enabled); + ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeColorParameter::is_default_value_enabled); - ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeColorUniform::set_default_value); - ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeColorUniform::get_default_value); + ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeColorParameter::set_default_value); + ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeColorParameter::get_default_value); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "default_value"), "set_default_value", "get_default_value"); } -bool VisualShaderNodeColorUniform::is_qualifier_supported(Qualifier p_qual) const { +bool VisualShaderNodeColorParameter::is_qualifier_supported(Qualifier p_qual) const { return true; // all qualifiers are supported } -bool VisualShaderNodeColorUniform::is_convertible_to_constant() const { +bool VisualShaderNodeColorParameter::is_convertible_to_constant() const { return true; // conversion is allowed } -Vector<StringName> VisualShaderNodeColorUniform::get_editable_properties() const { - Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); +Vector<StringName> VisualShaderNodeColorParameter::get_editable_properties() const { + Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties(); props.push_back("default_value_enabled"); if (default_value_enabled) { props.push_back("default_value"); @@ -5310,59 +5310,59 @@ Vector<StringName> VisualShaderNodeColorUniform::get_editable_properties() const return props; } -VisualShaderNodeColorUniform::VisualShaderNodeColorUniform() { +VisualShaderNodeColorParameter::VisualShaderNodeColorParameter() { } -////////////// Vector2 Uniform +////////////// Vector2 Parameter -String VisualShaderNodeVec2Uniform::get_caption() const { - return "Vector2Uniform"; +String VisualShaderNodeVec2Parameter::get_caption() const { + return "Vector2Parameter"; } -int VisualShaderNodeVec2Uniform::get_input_port_count() const { +int VisualShaderNodeVec2Parameter::get_input_port_count() const { return 0; } -VisualShaderNodeVec2Uniform::PortType VisualShaderNodeVec2Uniform::get_input_port_type(int p_port) const { +VisualShaderNodeVec2Parameter::PortType VisualShaderNodeVec2Parameter::get_input_port_type(int p_port) const { return PORT_TYPE_VECTOR_2D; } -String VisualShaderNodeVec2Uniform::get_input_port_name(int p_port) const { +String VisualShaderNodeVec2Parameter::get_input_port_name(int p_port) const { return String(); } -int VisualShaderNodeVec2Uniform::get_output_port_count() const { +int VisualShaderNodeVec2Parameter::get_output_port_count() const { return 1; } -VisualShaderNodeVec2Uniform::PortType VisualShaderNodeVec2Uniform::get_output_port_type(int p_port) const { +VisualShaderNodeVec2Parameter::PortType VisualShaderNodeVec2Parameter::get_output_port_type(int p_port) const { return PORT_TYPE_VECTOR_2D; } -String VisualShaderNodeVec2Uniform::get_output_port_name(int p_port) const { +String VisualShaderNodeVec2Parameter::get_output_port_name(int p_port) const { return String(); } -void VisualShaderNodeVec2Uniform::set_default_value_enabled(bool p_enabled) { +void VisualShaderNodeVec2Parameter::set_default_value_enabled(bool p_enabled) { default_value_enabled = p_enabled; emit_changed(); } -bool VisualShaderNodeVec2Uniform::is_default_value_enabled() const { +bool VisualShaderNodeVec2Parameter::is_default_value_enabled() const { return default_value_enabled; } -void VisualShaderNodeVec2Uniform::set_default_value(const Vector2 &p_value) { +void VisualShaderNodeVec2Parameter::set_default_value(const Vector2 &p_value) { default_value = p_value; emit_changed(); } -Vector2 VisualShaderNodeVec2Uniform::get_default_value() const { +Vector2 VisualShaderNodeVec2Parameter::get_default_value() const { return default_value; } -String VisualShaderNodeVec2Uniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { - String code = _get_qual_str() + "uniform vec2 " + get_uniform_name(); +String VisualShaderNodeVec2Parameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = _get_qual_str() + "uniform vec2 " + get_parameter_name(); if (default_value_enabled) { code += vformat(" = vec2(%.6f, %.6f)", default_value.x, default_value.y); } @@ -5370,39 +5370,39 @@ String VisualShaderNodeVec2Uniform::generate_global(Shader::Mode p_mode, VisualS return code; } -String VisualShaderNodeVec2Uniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; +String VisualShaderNodeVec2Parameter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return " " + p_output_vars[0] + " = " + get_parameter_name() + ";\n"; } -void VisualShaderNodeVec2Uniform::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeVec2Uniform::set_default_value_enabled); - ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeVec2Uniform::is_default_value_enabled); +void VisualShaderNodeVec2Parameter::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeVec2Parameter::set_default_value_enabled); + ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeVec2Parameter::is_default_value_enabled); - ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeVec2Uniform::set_default_value); - ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeVec2Uniform::get_default_value); + ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeVec2Parameter::set_default_value); + ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeVec2Parameter::get_default_value); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "default_value"), "set_default_value", "get_default_value"); } -bool VisualShaderNodeVec2Uniform::is_show_prop_names() const { +bool VisualShaderNodeVec2Parameter::is_show_prop_names() const { return true; } -bool VisualShaderNodeVec2Uniform::is_use_prop_slots() const { +bool VisualShaderNodeVec2Parameter::is_use_prop_slots() const { return true; } -bool VisualShaderNodeVec2Uniform::is_qualifier_supported(Qualifier p_qual) const { +bool VisualShaderNodeVec2Parameter::is_qualifier_supported(Qualifier p_qual) const { return true; // all qualifiers are supported } -bool VisualShaderNodeVec2Uniform::is_convertible_to_constant() const { +bool VisualShaderNodeVec2Parameter::is_convertible_to_constant() const { return true; // conversion is allowed } -Vector<StringName> VisualShaderNodeVec2Uniform::get_editable_properties() const { - Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); +Vector<StringName> VisualShaderNodeVec2Parameter::get_editable_properties() const { + Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties(); props.push_back("default_value_enabled"); if (default_value_enabled) { props.push_back("default_value"); @@ -5410,59 +5410,59 @@ Vector<StringName> VisualShaderNodeVec2Uniform::get_editable_properties() const return props; } -VisualShaderNodeVec2Uniform::VisualShaderNodeVec2Uniform() { +VisualShaderNodeVec2Parameter::VisualShaderNodeVec2Parameter() { } -////////////// Vector3 Uniform +////////////// Vector3 Parameter -String VisualShaderNodeVec3Uniform::get_caption() const { - return "Vector3Uniform"; +String VisualShaderNodeVec3Parameter::get_caption() const { + return "Vector3Parameter"; } -int VisualShaderNodeVec3Uniform::get_input_port_count() const { +int VisualShaderNodeVec3Parameter::get_input_port_count() const { return 0; } -VisualShaderNodeVec3Uniform::PortType VisualShaderNodeVec3Uniform::get_input_port_type(int p_port) const { +VisualShaderNodeVec3Parameter::PortType VisualShaderNodeVec3Parameter::get_input_port_type(int p_port) const { return PORT_TYPE_VECTOR_3D; } -String VisualShaderNodeVec3Uniform::get_input_port_name(int p_port) const { +String VisualShaderNodeVec3Parameter::get_input_port_name(int p_port) const { return String(); } -int VisualShaderNodeVec3Uniform::get_output_port_count() const { +int VisualShaderNodeVec3Parameter::get_output_port_count() const { return 1; } -VisualShaderNodeVec3Uniform::PortType VisualShaderNodeVec3Uniform::get_output_port_type(int p_port) const { +VisualShaderNodeVec3Parameter::PortType VisualShaderNodeVec3Parameter::get_output_port_type(int p_port) const { return PORT_TYPE_VECTOR_3D; } -String VisualShaderNodeVec3Uniform::get_output_port_name(int p_port) const { +String VisualShaderNodeVec3Parameter::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } -void VisualShaderNodeVec3Uniform::set_default_value_enabled(bool p_enabled) { +void VisualShaderNodeVec3Parameter::set_default_value_enabled(bool p_enabled) { default_value_enabled = p_enabled; emit_changed(); } -bool VisualShaderNodeVec3Uniform::is_default_value_enabled() const { +bool VisualShaderNodeVec3Parameter::is_default_value_enabled() const { return default_value_enabled; } -void VisualShaderNodeVec3Uniform::set_default_value(const Vector3 &p_value) { +void VisualShaderNodeVec3Parameter::set_default_value(const Vector3 &p_value) { default_value = p_value; emit_changed(); } -Vector3 VisualShaderNodeVec3Uniform::get_default_value() const { +Vector3 VisualShaderNodeVec3Parameter::get_default_value() const { return default_value; } -String VisualShaderNodeVec3Uniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { - String code = _get_qual_str() + "uniform vec3 " + get_uniform_name(); +String VisualShaderNodeVec3Parameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = _get_qual_str() + "uniform vec3 " + get_parameter_name(); if (default_value_enabled) { code += vformat(" = vec3(%.6f, %.6f, %.6f)", default_value.x, default_value.y, default_value.z); } @@ -5470,39 +5470,39 @@ String VisualShaderNodeVec3Uniform::generate_global(Shader::Mode p_mode, VisualS return code; } -String VisualShaderNodeVec3Uniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; +String VisualShaderNodeVec3Parameter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return " " + p_output_vars[0] + " = " + get_parameter_name() + ";\n"; } -void VisualShaderNodeVec3Uniform::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeVec3Uniform::set_default_value_enabled); - ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeVec3Uniform::is_default_value_enabled); +void VisualShaderNodeVec3Parameter::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeVec3Parameter::set_default_value_enabled); + ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeVec3Parameter::is_default_value_enabled); - ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeVec3Uniform::set_default_value); - ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeVec3Uniform::get_default_value); + ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeVec3Parameter::set_default_value); + ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeVec3Parameter::get_default_value); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "default_value"), "set_default_value", "get_default_value"); } -bool VisualShaderNodeVec3Uniform::is_show_prop_names() const { +bool VisualShaderNodeVec3Parameter::is_show_prop_names() const { return true; } -bool VisualShaderNodeVec3Uniform::is_use_prop_slots() const { +bool VisualShaderNodeVec3Parameter::is_use_prop_slots() const { return true; } -bool VisualShaderNodeVec3Uniform::is_qualifier_supported(Qualifier p_qual) const { +bool VisualShaderNodeVec3Parameter::is_qualifier_supported(Qualifier p_qual) const { return true; // all qualifiers are supported } -bool VisualShaderNodeVec3Uniform::is_convertible_to_constant() const { +bool VisualShaderNodeVec3Parameter::is_convertible_to_constant() const { return true; // conversion is allowed } -Vector<StringName> VisualShaderNodeVec3Uniform::get_editable_properties() const { - Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); +Vector<StringName> VisualShaderNodeVec3Parameter::get_editable_properties() const { + Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties(); props.push_back("default_value_enabled"); if (default_value_enabled) { props.push_back("default_value"); @@ -5510,59 +5510,59 @@ Vector<StringName> VisualShaderNodeVec3Uniform::get_editable_properties() const return props; } -VisualShaderNodeVec3Uniform::VisualShaderNodeVec3Uniform() { +VisualShaderNodeVec3Parameter::VisualShaderNodeVec3Parameter() { } -////////////// Vector4 Uniform +////////////// Vector4 Parameter -String VisualShaderNodeVec4Uniform::get_caption() const { - return "Vector4Uniform"; +String VisualShaderNodeVec4Parameter::get_caption() const { + return "Vector4Parameter"; } -int VisualShaderNodeVec4Uniform::get_input_port_count() const { +int VisualShaderNodeVec4Parameter::get_input_port_count() const { return 0; } -VisualShaderNodeVec4Uniform::PortType VisualShaderNodeVec4Uniform::get_input_port_type(int p_port) const { +VisualShaderNodeVec4Parameter::PortType VisualShaderNodeVec4Parameter::get_input_port_type(int p_port) const { return PORT_TYPE_VECTOR_4D; } -String VisualShaderNodeVec4Uniform::get_input_port_name(int p_port) const { +String VisualShaderNodeVec4Parameter::get_input_port_name(int p_port) const { return String(); } -int VisualShaderNodeVec4Uniform::get_output_port_count() const { +int VisualShaderNodeVec4Parameter::get_output_port_count() const { return 1; } -VisualShaderNodeVec4Uniform::PortType VisualShaderNodeVec4Uniform::get_output_port_type(int p_port) const { +VisualShaderNodeVec4Parameter::PortType VisualShaderNodeVec4Parameter::get_output_port_type(int p_port) const { return PORT_TYPE_VECTOR_4D; } -String VisualShaderNodeVec4Uniform::get_output_port_name(int p_port) const { +String VisualShaderNodeVec4Parameter::get_output_port_name(int p_port) const { return ""; // No output port means the editor will be used as port. } -void VisualShaderNodeVec4Uniform::set_default_value_enabled(bool p_enabled) { +void VisualShaderNodeVec4Parameter::set_default_value_enabled(bool p_enabled) { default_value_enabled = p_enabled; emit_changed(); } -bool VisualShaderNodeVec4Uniform::is_default_value_enabled() const { +bool VisualShaderNodeVec4Parameter::is_default_value_enabled() const { return default_value_enabled; } -void VisualShaderNodeVec4Uniform::set_default_value(const Quaternion &p_value) { +void VisualShaderNodeVec4Parameter::set_default_value(const Vector4 &p_value) { default_value = p_value; emit_changed(); } -Quaternion VisualShaderNodeVec4Uniform::get_default_value() const { +Vector4 VisualShaderNodeVec4Parameter::get_default_value() const { return default_value; } -String VisualShaderNodeVec4Uniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { - String code = _get_qual_str() + "uniform vec4 " + get_uniform_name(); +String VisualShaderNodeVec4Parameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = _get_qual_str() + "uniform vec4 " + get_parameter_name(); if (default_value_enabled) { code += vformat(" = vec4(%.6f, %.6f, %.6f, %.6f)", default_value.x, default_value.y, default_value.z, default_value.w); } @@ -5570,39 +5570,39 @@ String VisualShaderNodeVec4Uniform::generate_global(Shader::Mode p_mode, VisualS return code; } -String VisualShaderNodeVec4Uniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; +String VisualShaderNodeVec4Parameter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return " " + p_output_vars[0] + " = " + get_parameter_name() + ";\n"; } -void VisualShaderNodeVec4Uniform::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeVec4Uniform::set_default_value_enabled); - ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeVec4Uniform::is_default_value_enabled); +void VisualShaderNodeVec4Parameter::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeVec4Parameter::set_default_value_enabled); + ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeVec4Parameter::is_default_value_enabled); - ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeVec4Uniform::set_default_value); - ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeVec4Uniform::get_default_value); + ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeVec4Parameter::set_default_value); + ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeVec4Parameter::get_default_value); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::QUATERNION, "default_value"), "set_default_value", "get_default_value"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR4, "default_value"), "set_default_value", "get_default_value"); } -bool VisualShaderNodeVec4Uniform::is_show_prop_names() const { +bool VisualShaderNodeVec4Parameter::is_show_prop_names() const { return true; } -bool VisualShaderNodeVec4Uniform::is_use_prop_slots() const { +bool VisualShaderNodeVec4Parameter::is_use_prop_slots() const { return true; } -bool VisualShaderNodeVec4Uniform::is_qualifier_supported(Qualifier p_qual) const { +bool VisualShaderNodeVec4Parameter::is_qualifier_supported(Qualifier p_qual) const { return true; // All qualifiers are supported. } -bool VisualShaderNodeVec4Uniform::is_convertible_to_constant() const { +bool VisualShaderNodeVec4Parameter::is_convertible_to_constant() const { return true; // Conversion is allowed. } -Vector<StringName> VisualShaderNodeVec4Uniform::get_editable_properties() const { - Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); +Vector<StringName> VisualShaderNodeVec4Parameter::get_editable_properties() const { + Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties(); props.push_back("default_value_enabled"); if (default_value_enabled) { props.push_back("default_value"); @@ -5610,59 +5610,59 @@ Vector<StringName> VisualShaderNodeVec4Uniform::get_editable_properties() const return props; } -VisualShaderNodeVec4Uniform::VisualShaderNodeVec4Uniform() { +VisualShaderNodeVec4Parameter::VisualShaderNodeVec4Parameter() { } -////////////// Transform Uniform +////////////// Transform Parameter -String VisualShaderNodeTransformUniform::get_caption() const { - return "TransformUniform"; +String VisualShaderNodeTransformParameter::get_caption() const { + return "TransformParameter"; } -int VisualShaderNodeTransformUniform::get_input_port_count() const { +int VisualShaderNodeTransformParameter::get_input_port_count() const { return 0; } -VisualShaderNodeTransformUniform::PortType VisualShaderNodeTransformUniform::get_input_port_type(int p_port) const { +VisualShaderNodeTransformParameter::PortType VisualShaderNodeTransformParameter::get_input_port_type(int p_port) const { return PORT_TYPE_VECTOR_3D; } -String VisualShaderNodeTransformUniform::get_input_port_name(int p_port) const { +String VisualShaderNodeTransformParameter::get_input_port_name(int p_port) const { return String(); } -int VisualShaderNodeTransformUniform::get_output_port_count() const { +int VisualShaderNodeTransformParameter::get_output_port_count() const { return 1; } -VisualShaderNodeTransformUniform::PortType VisualShaderNodeTransformUniform::get_output_port_type(int p_port) const { +VisualShaderNodeTransformParameter::PortType VisualShaderNodeTransformParameter::get_output_port_type(int p_port) const { return PORT_TYPE_TRANSFORM; } -String VisualShaderNodeTransformUniform::get_output_port_name(int p_port) const { +String VisualShaderNodeTransformParameter::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } -void VisualShaderNodeTransformUniform::set_default_value_enabled(bool p_enabled) { +void VisualShaderNodeTransformParameter::set_default_value_enabled(bool p_enabled) { default_value_enabled = p_enabled; emit_changed(); } -bool VisualShaderNodeTransformUniform::is_default_value_enabled() const { +bool VisualShaderNodeTransformParameter::is_default_value_enabled() const { return default_value_enabled; } -void VisualShaderNodeTransformUniform::set_default_value(const Transform3D &p_value) { +void VisualShaderNodeTransformParameter::set_default_value(const Transform3D &p_value) { default_value = p_value; emit_changed(); } -Transform3D VisualShaderNodeTransformUniform::get_default_value() const { +Transform3D VisualShaderNodeTransformParameter::get_default_value() const { return default_value; } -String VisualShaderNodeTransformUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { - String code = _get_qual_str() + "uniform mat4 " + get_uniform_name(); +String VisualShaderNodeTransformParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = _get_qual_str() + "uniform mat4 " + get_parameter_name(); if (default_value_enabled) { Vector3 row0 = default_value.basis.rows[0]; Vector3 row1 = default_value.basis.rows[1]; @@ -5674,42 +5674,42 @@ String VisualShaderNodeTransformUniform::generate_global(Shader::Mode p_mode, Vi return code; } -String VisualShaderNodeTransformUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; +String VisualShaderNodeTransformParameter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return " " + p_output_vars[0] + " = " + get_parameter_name() + ";\n"; } -void VisualShaderNodeTransformUniform::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeTransformUniform::set_default_value_enabled); - ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeTransformUniform::is_default_value_enabled); +void VisualShaderNodeTransformParameter::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeTransformParameter::set_default_value_enabled); + ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeTransformParameter::is_default_value_enabled); - ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeTransformUniform::set_default_value); - ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeTransformUniform::get_default_value); + ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeTransformParameter::set_default_value); + ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeTransformParameter::get_default_value); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "default_value"), "set_default_value", "get_default_value"); } -bool VisualShaderNodeTransformUniform::is_show_prop_names() const { +bool VisualShaderNodeTransformParameter::is_show_prop_names() const { return true; } -bool VisualShaderNodeTransformUniform::is_use_prop_slots() const { +bool VisualShaderNodeTransformParameter::is_use_prop_slots() const { return true; } -bool VisualShaderNodeTransformUniform::is_qualifier_supported(Qualifier p_qual) const { +bool VisualShaderNodeTransformParameter::is_qualifier_supported(Qualifier p_qual) const { if (p_qual == Qualifier::QUAL_INSTANCE) { return false; } return true; } -bool VisualShaderNodeTransformUniform::is_convertible_to_constant() const { +bool VisualShaderNodeTransformParameter::is_convertible_to_constant() const { return true; // conversion is allowed } -Vector<StringName> VisualShaderNodeTransformUniform::get_editable_properties() const { - Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); +Vector<StringName> VisualShaderNodeTransformParameter::get_editable_properties() const { + Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties(); props.push_back("default_value_enabled"); if (default_value_enabled) { props.push_back("default_value"); @@ -5717,12 +5717,12 @@ Vector<StringName> VisualShaderNodeTransformUniform::get_editable_properties() c return props; } -VisualShaderNodeTransformUniform::VisualShaderNodeTransformUniform() { +VisualShaderNodeTransformParameter::VisualShaderNodeTransformParameter() { } ////////////// -String get_sampler_hint(VisualShaderNodeTextureUniform::TextureType p_texture_type, VisualShaderNodeTextureUniform::ColorDefault p_color_default, VisualShaderNodeTextureUniform::TextureFilter p_texture_filter, VisualShaderNodeTextureUniform::TextureRepeat p_texture_repeat) { +String get_sampler_hint(VisualShaderNodeTextureParameter::TextureType p_texture_type, VisualShaderNodeTextureParameter::ColorDefault p_color_default, VisualShaderNodeTextureParameter::TextureFilter p_texture_filter, VisualShaderNodeTextureParameter::TextureRepeat p_texture_repeat) { String code; bool has_colon = false; @@ -5731,25 +5731,25 @@ String get_sampler_hint(VisualShaderNodeTextureUniform::TextureType p_texture_ty String type_code; switch (p_texture_type) { - case VisualShaderNodeTextureUniform::TYPE_DATA: - if (p_color_default == VisualShaderNodeTextureUniform::COLOR_DEFAULT_BLACK) { + case VisualShaderNodeTextureParameter::TYPE_DATA: + if (p_color_default == VisualShaderNodeTextureParameter::COLOR_DEFAULT_BLACK) { type_code = "hint_default_black"; - } else if (p_color_default == VisualShaderNodeTextureUniform::COLOR_DEFAULT_TRANSPARENT) { + } else if (p_color_default == VisualShaderNodeTextureParameter::COLOR_DEFAULT_TRANSPARENT) { type_code = "hint_default_transparent"; } break; - case VisualShaderNodeTextureUniform::TYPE_COLOR: + case VisualShaderNodeTextureParameter::TYPE_COLOR: type_code = "source_color"; - if (p_color_default == VisualShaderNodeTextureUniform::COLOR_DEFAULT_BLACK) { + if (p_color_default == VisualShaderNodeTextureParameter::COLOR_DEFAULT_BLACK) { type_code += ", hint_default_black"; - } else if (p_color_default == VisualShaderNodeTextureUniform::COLOR_DEFAULT_TRANSPARENT) { + } else if (p_color_default == VisualShaderNodeTextureParameter::COLOR_DEFAULT_TRANSPARENT) { type_code += ", hint_default_transparent"; } break; - case VisualShaderNodeTextureUniform::TYPE_NORMAL_MAP: + case VisualShaderNodeTextureParameter::TYPE_NORMAL_MAP: type_code = "hint_normal"; break; - case VisualShaderNodeTextureUniform::TYPE_ANISOTROPY: + case VisualShaderNodeTextureParameter::TYPE_ANISOTROPY: type_code = "hint_anisotropy"; break; default: @@ -5767,22 +5767,22 @@ String get_sampler_hint(VisualShaderNodeTextureUniform::TextureType p_texture_ty String filter_code; switch (p_texture_filter) { - case VisualShaderNodeTextureUniform::FILTER_NEAREST: + case VisualShaderNodeTextureParameter::FILTER_NEAREST: filter_code = "filter_nearest"; break; - case VisualShaderNodeTextureUniform::FILTER_LINEAR: + case VisualShaderNodeTextureParameter::FILTER_LINEAR: filter_code = "filter_linear"; break; - case VisualShaderNodeTextureUniform::FILTER_NEAREST_MIPMAP: + case VisualShaderNodeTextureParameter::FILTER_NEAREST_MIPMAP: filter_code = "filter_nearest_mipmap"; break; - case VisualShaderNodeTextureUniform::FILTER_LINEAR_MIPMAP: + case VisualShaderNodeTextureParameter::FILTER_LINEAR_MIPMAP: filter_code = "filter_linear_mipmap"; break; - case VisualShaderNodeTextureUniform::FILTER_NEAREST_MIPMAP_ANISOTROPIC: + case VisualShaderNodeTextureParameter::FILTER_NEAREST_MIPMAP_ANISOTROPIC: filter_code = "filter_nearest_mipmap_anisotropic"; break; - case VisualShaderNodeTextureUniform::FILTER_LINEAR_MIPMAP_ANISOTROPIC: + case VisualShaderNodeTextureParameter::FILTER_LINEAR_MIPMAP_ANISOTROPIC: filter_code = "filter_linear_mipmap_anisotropic"; break; default: @@ -5805,10 +5805,10 @@ String get_sampler_hint(VisualShaderNodeTextureUniform::TextureType p_texture_ty String repeat_code; switch (p_texture_repeat) { - case VisualShaderNodeTextureUniform::REPEAT_ENABLED: + case VisualShaderNodeTextureParameter::REPEAT_ENABLED: repeat_code = "repeat_enable"; break; - case VisualShaderNodeTextureUniform::REPEAT_DISABLED: + case VisualShaderNodeTextureParameter::REPEAT_DISABLED: repeat_code = "repeat_disable"; break; default: @@ -5828,29 +5828,25 @@ String get_sampler_hint(VisualShaderNodeTextureUniform::TextureType p_texture_ty return code; } -////////////// Texture Uniform +////////////// Texture Parameter -String VisualShaderNodeTextureUniform::get_caption() const { - return "TextureUniform"; -} - -int VisualShaderNodeTextureUniform::get_input_port_count() const { +int VisualShaderNodeTextureParameter::get_input_port_count() const { return 0; } -VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniform::get_input_port_type(int p_port) const { +VisualShaderNodeTextureParameter::PortType VisualShaderNodeTextureParameter::get_input_port_type(int p_port) const { return PORT_TYPE_SCALAR; } -String VisualShaderNodeTextureUniform::get_input_port_name(int p_port) const { +String VisualShaderNodeTextureParameter::get_input_port_name(int p_port) const { return ""; } -int VisualShaderNodeTextureUniform::get_output_port_count() const { +int VisualShaderNodeTextureParameter::get_output_port_count() const { return 1; } -VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniform::get_output_port_type(int p_port) const { +VisualShaderNodeTextureParameter::PortType VisualShaderNodeTextureParameter::get_output_port_type(int p_port) const { switch (p_port) { case 0: return PORT_TYPE_SAMPLER; @@ -5859,27 +5855,11 @@ VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniform::get_out } } -String VisualShaderNodeTextureUniform::get_output_port_name(int p_port) const { - switch (p_port) { - case 0: - return "sampler2D"; - default: - return ""; - } -} - -String VisualShaderNodeTextureUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { - String code = _get_qual_str() + "uniform sampler2D " + get_uniform_name(); - code += get_sampler_hint(texture_type, color_default, texture_filter, texture_repeat); - code += ";\n"; - return code; -} - -String VisualShaderNodeTextureUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { +String VisualShaderNodeTextureParameter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { return ""; } -void VisualShaderNodeTextureUniform::set_texture_type(TextureType p_texture_type) { +void VisualShaderNodeTextureParameter::set_texture_type(TextureType p_texture_type) { ERR_FAIL_INDEX(int(p_texture_type), int(TYPE_MAX)); if (texture_type == p_texture_type) { return; @@ -5888,11 +5868,11 @@ void VisualShaderNodeTextureUniform::set_texture_type(TextureType p_texture_type emit_changed(); } -VisualShaderNodeTextureUniform::TextureType VisualShaderNodeTextureUniform::get_texture_type() const { +VisualShaderNodeTextureParameter::TextureType VisualShaderNodeTextureParameter::get_texture_type() const { return texture_type; } -void VisualShaderNodeTextureUniform::set_color_default(ColorDefault p_color_default) { +void VisualShaderNodeTextureParameter::set_color_default(ColorDefault p_color_default) { ERR_FAIL_INDEX(int(p_color_default), int(COLOR_DEFAULT_MAX)); if (color_default == p_color_default) { return; @@ -5901,11 +5881,11 @@ void VisualShaderNodeTextureUniform::set_color_default(ColorDefault p_color_defa emit_changed(); } -VisualShaderNodeTextureUniform::ColorDefault VisualShaderNodeTextureUniform::get_color_default() const { +VisualShaderNodeTextureParameter::ColorDefault VisualShaderNodeTextureParameter::get_color_default() const { return color_default; } -void VisualShaderNodeTextureUniform::set_texture_filter(TextureFilter p_filter) { +void VisualShaderNodeTextureParameter::set_texture_filter(TextureFilter p_filter) { ERR_FAIL_INDEX(int(p_filter), int(FILTER_MAX)); if (texture_filter == p_filter) { return; @@ -5914,11 +5894,11 @@ void VisualShaderNodeTextureUniform::set_texture_filter(TextureFilter p_filter) emit_changed(); } -VisualShaderNodeTextureUniform::TextureFilter VisualShaderNodeTextureUniform::get_texture_filter() const { +VisualShaderNodeTextureParameter::TextureFilter VisualShaderNodeTextureParameter::get_texture_filter() const { return texture_filter; } -void VisualShaderNodeTextureUniform::set_texture_repeat(TextureRepeat p_repeat) { +void VisualShaderNodeTextureParameter::set_texture_repeat(TextureRepeat p_repeat) { ERR_FAIL_INDEX(int(p_repeat), int(REPEAT_MAX)); if (texture_repeat == p_repeat) { return; @@ -5927,12 +5907,12 @@ void VisualShaderNodeTextureUniform::set_texture_repeat(TextureRepeat p_repeat) emit_changed(); } -VisualShaderNodeTextureUniform::TextureRepeat VisualShaderNodeTextureUniform::get_texture_repeat() const { +VisualShaderNodeTextureParameter::TextureRepeat VisualShaderNodeTextureParameter::get_texture_repeat() const { return texture_repeat; } -Vector<StringName> VisualShaderNodeTextureUniform::get_editable_properties() const { - Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); +Vector<StringName> VisualShaderNodeTextureParameter::get_editable_properties() const { + Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties(); props.push_back("texture_type"); if (texture_type == TYPE_DATA || texture_type == TYPE_COLOR) { props.push_back("color_default"); @@ -5942,11 +5922,11 @@ Vector<StringName> VisualShaderNodeTextureUniform::get_editable_properties() con return props; } -bool VisualShaderNodeTextureUniform::is_show_prop_names() const { +bool VisualShaderNodeTextureParameter::is_show_prop_names() const { return true; } -HashMap<StringName, String> VisualShaderNodeTextureUniform::get_editable_properties_names() const { +HashMap<StringName, String> VisualShaderNodeTextureParameter::get_editable_properties_names() const { HashMap<StringName, String> names; names.insert("texture_type", RTR("Type")); names.insert("color_default", RTR("Default Color")); @@ -5955,18 +5935,18 @@ HashMap<StringName, String> VisualShaderNodeTextureUniform::get_editable_propert return names; } -void VisualShaderNodeTextureUniform::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_texture_type", "type"), &VisualShaderNodeTextureUniform::set_texture_type); - ClassDB::bind_method(D_METHOD("get_texture_type"), &VisualShaderNodeTextureUniform::get_texture_type); +void VisualShaderNodeTextureParameter::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_texture_type", "type"), &VisualShaderNodeTextureParameter::set_texture_type); + ClassDB::bind_method(D_METHOD("get_texture_type"), &VisualShaderNodeTextureParameter::get_texture_type); - ClassDB::bind_method(D_METHOD("set_color_default", "type"), &VisualShaderNodeTextureUniform::set_color_default); - ClassDB::bind_method(D_METHOD("get_color_default"), &VisualShaderNodeTextureUniform::get_color_default); + ClassDB::bind_method(D_METHOD("set_color_default", "type"), &VisualShaderNodeTextureParameter::set_color_default); + ClassDB::bind_method(D_METHOD("get_color_default"), &VisualShaderNodeTextureParameter::get_color_default); - ClassDB::bind_method(D_METHOD("set_texture_filter", "filter"), &VisualShaderNodeTextureUniform::set_texture_filter); - ClassDB::bind_method(D_METHOD("get_texture_filter"), &VisualShaderNodeTextureUniform::get_texture_filter); + ClassDB::bind_method(D_METHOD("set_texture_filter", "filter"), &VisualShaderNodeTextureParameter::set_texture_filter); + ClassDB::bind_method(D_METHOD("get_texture_filter"), &VisualShaderNodeTextureParameter::get_texture_filter); - ClassDB::bind_method(D_METHOD("set_texture_repeat", "type"), &VisualShaderNodeTextureUniform::set_texture_repeat); - ClassDB::bind_method(D_METHOD("get_texture_repeat"), &VisualShaderNodeTextureUniform::get_texture_repeat); + ClassDB::bind_method(D_METHOD("set_texture_repeat", "type"), &VisualShaderNodeTextureParameter::set_texture_repeat); + ClassDB::bind_method(D_METHOD("get_texture_repeat"), &VisualShaderNodeTextureParameter::get_texture_repeat); ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normal Map,Anisotropic"), "set_texture_type", "get_texture_type"); ADD_PROPERTY(PropertyInfo(Variant::INT, "color_default", PROPERTY_HINT_ENUM, "White,Black,Transparent"), "set_color_default", "get_color_default"); @@ -5999,7 +5979,7 @@ void VisualShaderNodeTextureUniform::_bind_methods() { BIND_ENUM_CONSTANT(REPEAT_MAX); } -bool VisualShaderNodeTextureUniform::is_qualifier_supported(Qualifier p_qual) const { +bool VisualShaderNodeTextureParameter::is_qualifier_supported(Qualifier p_qual) const { switch (p_qual) { case Qualifier::QUAL_NONE: return true; @@ -6013,31 +5993,56 @@ bool VisualShaderNodeTextureUniform::is_qualifier_supported(Qualifier p_qual) co return false; } -bool VisualShaderNodeTextureUniform::is_convertible_to_constant() const { +bool VisualShaderNodeTextureParameter::is_convertible_to_constant() const { return false; // conversion is not allowed } -VisualShaderNodeTextureUniform::VisualShaderNodeTextureUniform() { +VisualShaderNodeTextureParameter::VisualShaderNodeTextureParameter() { +} + +////////////// Texture2D Parameter + +String VisualShaderNodeTexture2DParameter::get_caption() const { + return "Texture2DParameter"; +} + +String VisualShaderNodeTexture2DParameter::get_output_port_name(int p_port) const { + switch (p_port) { + case 0: + return "sampler2D"; + default: + return ""; + } +} + +String VisualShaderNodeTexture2DParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = _get_qual_str() + "uniform sampler2D " + get_parameter_name(); + code += get_sampler_hint(texture_type, color_default, texture_filter, texture_repeat); + code += ";\n"; + return code; } -////////////// Texture Uniform (Triplanar) +VisualShaderNodeTexture2DParameter::VisualShaderNodeTexture2DParameter() { +} -String VisualShaderNodeTextureUniformTriplanar::get_caption() const { +////////////// Texture Parameter (Triplanar) + +String VisualShaderNodeTextureParameterTriplanar::get_caption() const { return "TextureUniformTriplanar"; } -int VisualShaderNodeTextureUniformTriplanar::get_input_port_count() const { +int VisualShaderNodeTextureParameterTriplanar::get_input_port_count() const { return 2; } -VisualShaderNodeTextureUniformTriplanar::PortType VisualShaderNodeTextureUniformTriplanar::get_input_port_type(int p_port) const { +VisualShaderNodeTextureParameterTriplanar::PortType VisualShaderNodeTextureParameterTriplanar::get_input_port_type(int p_port) const { if (p_port == 0 || p_port == 1) { return PORT_TYPE_VECTOR_3D; } return PORT_TYPE_SCALAR; } -String VisualShaderNodeTextureUniformTriplanar::get_input_port_name(int p_port) const { +String VisualShaderNodeTextureParameterTriplanar::get_input_port_name(int p_port) const { if (p_port == 0) { return "weights"; } else if (p_port == 1) { @@ -6046,11 +6051,11 @@ String VisualShaderNodeTextureUniformTriplanar::get_input_port_name(int p_port) return ""; } -int VisualShaderNodeTextureUniformTriplanar::get_output_port_count() const { +int VisualShaderNodeTextureParameterTriplanar::get_output_port_count() const { return 2; } -VisualShaderNodeTextureUniformTriplanar::PortType VisualShaderNodeTextureUniformTriplanar::get_output_port_type(int p_port) const { +VisualShaderNodeTextureParameterTriplanar::PortType VisualShaderNodeTextureParameterTriplanar::get_output_port_type(int p_port) const { switch (p_port) { case 0: return PORT_TYPE_VECTOR_4D; @@ -6061,7 +6066,7 @@ VisualShaderNodeTextureUniformTriplanar::PortType VisualShaderNodeTextureUniform } } -String VisualShaderNodeTextureUniformTriplanar::get_output_port_name(int p_port) const { +String VisualShaderNodeTextureParameterTriplanar::get_output_port_name(int p_port) const { switch (p_port) { case 0: return "color"; @@ -6072,7 +6077,7 @@ String VisualShaderNodeTextureUniformTriplanar::get_output_port_name(int p_port) } } -String VisualShaderNodeTextureUniformTriplanar::generate_global_per_node(Shader::Mode p_mode, int p_id) const { +String VisualShaderNodeTextureParameterTriplanar::generate_global_per_node(Shader::Mode p_mode, int p_id) const { String code; code += "// " + get_caption() + "\n"; @@ -6094,7 +6099,7 @@ String VisualShaderNodeTextureUniformTriplanar::generate_global_per_node(Shader: return code; } -String VisualShaderNodeTextureUniformTriplanar::generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { +String VisualShaderNodeTextureParameterTriplanar::generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { String code; if (p_type == VisualShader::TYPE_VERTEX) { @@ -6110,8 +6115,8 @@ String VisualShaderNodeTextureUniformTriplanar::generate_global_per_func(Shader: return code; } -String VisualShaderNodeTextureUniformTriplanar::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - String id = get_uniform_name(); +String VisualShaderNodeTextureParameterTriplanar::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String id = get_parameter_name(); String code; if (p_input_vars[0].is_empty() && p_input_vars[1].is_empty()) { @@ -6127,7 +6132,7 @@ String VisualShaderNodeTextureUniformTriplanar::generate_code(Shader::Mode p_mod return code; } -bool VisualShaderNodeTextureUniformTriplanar::is_input_port_default(int p_port, Shader::Mode p_mode) const { +bool VisualShaderNodeTextureParameterTriplanar::is_input_port_default(int p_port, Shader::Mode p_mode) const { if (p_port == 0) { return true; } else if (p_port == 1) { @@ -6136,79 +6141,67 @@ bool VisualShaderNodeTextureUniformTriplanar::is_input_port_default(int p_port, return false; } -VisualShaderNodeTextureUniformTriplanar::VisualShaderNodeTextureUniformTriplanar() { +VisualShaderNodeTextureParameterTriplanar::VisualShaderNodeTextureParameterTriplanar() { } -////////////// Texture2DArray Uniform +////////////// Texture2DArray Parameter -String VisualShaderNodeTexture2DArrayUniform::get_caption() const { - return "Texture2DArrayUniform"; +String VisualShaderNodeTexture2DArrayParameter::get_caption() const { + return "Texture2DArrayParameter"; } -String VisualShaderNodeTexture2DArrayUniform::get_output_port_name(int p_port) const { +String VisualShaderNodeTexture2DArrayParameter::get_output_port_name(int p_port) const { return "sampler2DArray"; } -String VisualShaderNodeTexture2DArrayUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { - String code = _get_qual_str() + "uniform sampler2DArray " + get_uniform_name(); +String VisualShaderNodeTexture2DArrayParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = _get_qual_str() + "uniform sampler2DArray " + get_parameter_name(); code += get_sampler_hint(texture_type, color_default, texture_filter, texture_repeat); code += ";\n"; return code; } -String VisualShaderNodeTexture2DArrayUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return String(); +VisualShaderNodeTexture2DArrayParameter::VisualShaderNodeTexture2DArrayParameter() { } -VisualShaderNodeTexture2DArrayUniform::VisualShaderNodeTexture2DArrayUniform() { -} +////////////// Texture3D Parameter -////////////// Texture3D Uniform - -String VisualShaderNodeTexture3DUniform::get_caption() const { - return "Texture3DUniform"; +String VisualShaderNodeTexture3DParameter::get_caption() const { + return "Texture3DParameter"; } -String VisualShaderNodeTexture3DUniform::get_output_port_name(int p_port) const { +String VisualShaderNodeTexture3DParameter::get_output_port_name(int p_port) const { return "sampler3D"; } -String VisualShaderNodeTexture3DUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { - String code = _get_qual_str() + "uniform sampler3D " + get_uniform_name(); +String VisualShaderNodeTexture3DParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = _get_qual_str() + "uniform sampler3D " + get_parameter_name(); code += get_sampler_hint(texture_type, color_default, texture_filter, texture_repeat); code += ";\n"; return code; } -String VisualShaderNodeTexture3DUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return String(); -} - -VisualShaderNodeTexture3DUniform::VisualShaderNodeTexture3DUniform() { +VisualShaderNodeTexture3DParameter::VisualShaderNodeTexture3DParameter() { } -////////////// Cubemap Uniform +////////////// Cubemap Parameter -String VisualShaderNodeCubemapUniform::get_caption() const { - return "CubemapUniform"; +String VisualShaderNodeCubemapParameter::get_caption() const { + return "CubemapParameter"; } -String VisualShaderNodeCubemapUniform::get_output_port_name(int p_port) const { +String VisualShaderNodeCubemapParameter::get_output_port_name(int p_port) const { return "samplerCube"; } -String VisualShaderNodeCubemapUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { - String code = _get_qual_str() + "uniform samplerCube " + get_uniform_name(); +String VisualShaderNodeCubemapParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = _get_qual_str() + "uniform samplerCube " + get_parameter_name(); code += get_sampler_hint(texture_type, color_default, texture_filter, texture_repeat); code += ";\n"; return code; } -String VisualShaderNodeCubemapUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return String(); -} - -VisualShaderNodeCubemapUniform::VisualShaderNodeCubemapUniform() { +VisualShaderNodeCubemapParameter::VisualShaderNodeCubemapParameter() { } ////////////// If diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index c603a10eae..ecba412fcb 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -1762,11 +1762,11 @@ public: }; /////////////////////////////////////// -/// UNIFORMS +/// PARAMETERS /////////////////////////////////////// -class VisualShaderNodeFloatUniform : public VisualShaderNodeUniform { - GDCLASS(VisualShaderNodeFloatUniform, VisualShaderNodeUniform); +class VisualShaderNodeFloatParameter : public VisualShaderNodeParameter { + GDCLASS(VisualShaderNodeFloatParameter, VisualShaderNodeParameter); public: enum Hint { @@ -1827,13 +1827,13 @@ public: virtual Vector<StringName> get_editable_properties() const override; - VisualShaderNodeFloatUniform(); + VisualShaderNodeFloatParameter(); }; -VARIANT_ENUM_CAST(VisualShaderNodeFloatUniform::Hint) +VARIANT_ENUM_CAST(VisualShaderNodeFloatParameter::Hint) -class VisualShaderNodeIntUniform : public VisualShaderNodeUniform { - GDCLASS(VisualShaderNodeIntUniform, VisualShaderNodeUniform); +class VisualShaderNodeIntParameter : public VisualShaderNodeParameter { + GDCLASS(VisualShaderNodeIntParameter, VisualShaderNodeParameter); public: enum Hint { @@ -1894,15 +1894,15 @@ public: virtual Vector<StringName> get_editable_properties() const override; - VisualShaderNodeIntUniform(); + VisualShaderNodeIntParameter(); }; -VARIANT_ENUM_CAST(VisualShaderNodeIntUniform::Hint) +VARIANT_ENUM_CAST(VisualShaderNodeIntParameter::Hint) /////////////////////////////////////// -class VisualShaderNodeBooleanUniform : public VisualShaderNodeUniform { - GDCLASS(VisualShaderNodeBooleanUniform, VisualShaderNodeUniform); +class VisualShaderNodeBooleanParameter : public VisualShaderNodeParameter { + GDCLASS(VisualShaderNodeBooleanParameter, VisualShaderNodeParameter); private: bool default_value_enabled = false; @@ -1939,13 +1939,13 @@ public: virtual Vector<StringName> get_editable_properties() const override; - VisualShaderNodeBooleanUniform(); + VisualShaderNodeBooleanParameter(); }; /////////////////////////////////////// -class VisualShaderNodeColorUniform : public VisualShaderNodeUniform { - GDCLASS(VisualShaderNodeColorUniform, VisualShaderNodeUniform); +class VisualShaderNodeColorParameter : public VisualShaderNodeParameter { + GDCLASS(VisualShaderNodeColorParameter, VisualShaderNodeParameter); private: bool default_value_enabled = false; @@ -1983,13 +1983,13 @@ public: virtual Vector<StringName> get_editable_properties() const override; - VisualShaderNodeColorUniform(); + VisualShaderNodeColorParameter(); }; /////////////////////////////////////// -class VisualShaderNodeVec2Uniform : public VisualShaderNodeUniform { - GDCLASS(VisualShaderNodeVec2Uniform, VisualShaderNodeUniform); +class VisualShaderNodeVec2Parameter : public VisualShaderNodeParameter { + GDCLASS(VisualShaderNodeVec2Parameter, VisualShaderNodeParameter); private: bool default_value_enabled = false; @@ -2026,13 +2026,13 @@ public: virtual Vector<StringName> get_editable_properties() const override; - VisualShaderNodeVec2Uniform(); + VisualShaderNodeVec2Parameter(); }; /////////////////////////////////////// -class VisualShaderNodeVec3Uniform : public VisualShaderNodeUniform { - GDCLASS(VisualShaderNodeVec3Uniform, VisualShaderNodeUniform); +class VisualShaderNodeVec3Parameter : public VisualShaderNodeParameter { + GDCLASS(VisualShaderNodeVec3Parameter, VisualShaderNodeParameter); private: bool default_value_enabled = false; @@ -2069,17 +2069,17 @@ public: virtual Vector<StringName> get_editable_properties() const override; - VisualShaderNodeVec3Uniform(); + VisualShaderNodeVec3Parameter(); }; /////////////////////////////////////// -class VisualShaderNodeVec4Uniform : public VisualShaderNodeUniform { - GDCLASS(VisualShaderNodeVec4Uniform, VisualShaderNodeUniform); +class VisualShaderNodeVec4Parameter : public VisualShaderNodeParameter { + GDCLASS(VisualShaderNodeVec4Parameter, VisualShaderNodeParameter); private: bool default_value_enabled = false; - Quaternion default_value; + Vector4 default_value; protected: static void _bind_methods(); @@ -2104,21 +2104,21 @@ public: void set_default_value_enabled(bool p_enabled); bool is_default_value_enabled() const; - void set_default_value(const Quaternion &p_value); - Quaternion get_default_value() const; + void set_default_value(const Vector4 &p_value); + Vector4 get_default_value() const; bool is_qualifier_supported(Qualifier p_qual) const override; bool is_convertible_to_constant() const override; virtual Vector<StringName> get_editable_properties() const override; - VisualShaderNodeVec4Uniform(); + VisualShaderNodeVec4Parameter(); }; /////////////////////////////////////// -class VisualShaderNodeTransformUniform : public VisualShaderNodeUniform { - GDCLASS(VisualShaderNodeTransformUniform, VisualShaderNodeUniform); +class VisualShaderNodeTransformParameter : public VisualShaderNodeParameter { + GDCLASS(VisualShaderNodeTransformParameter, VisualShaderNodeParameter); private: bool default_value_enabled = false; @@ -2155,13 +2155,13 @@ public: virtual Vector<StringName> get_editable_properties() const override; - VisualShaderNodeTransformUniform(); + VisualShaderNodeTransformParameter(); }; /////////////////////////////////////// -class VisualShaderNodeTextureUniform : public VisualShaderNodeUniform { - GDCLASS(VisualShaderNodeTextureUniform, VisualShaderNodeUniform); +class VisualShaderNodeTextureParameter : public VisualShaderNodeParameter { + GDCLASS(VisualShaderNodeTextureParameter, VisualShaderNodeParameter); public: enum TextureType { @@ -2207,17 +2207,13 @@ protected: static void _bind_methods(); public: - virtual String get_caption() const override; - virtual int get_input_port_count() const override; virtual PortType get_input_port_type(int p_port) const override; virtual String get_input_port_name(int p_port) const override; virtual int get_output_port_count() const override; virtual PortType get_output_port_type(int p_port) const override; - virtual String get_output_port_name(int p_port) const override; - virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; virtual HashMap<StringName, String> get_editable_properties_names() const override; @@ -2240,18 +2236,32 @@ public: bool is_qualifier_supported(Qualifier p_qual) const override; bool is_convertible_to_constant() const override; - VisualShaderNodeTextureUniform(); + VisualShaderNodeTextureParameter(); }; -VARIANT_ENUM_CAST(VisualShaderNodeTextureUniform::TextureType) -VARIANT_ENUM_CAST(VisualShaderNodeTextureUniform::ColorDefault) -VARIANT_ENUM_CAST(VisualShaderNodeTextureUniform::TextureFilter) -VARIANT_ENUM_CAST(VisualShaderNodeTextureUniform::TextureRepeat) +VARIANT_ENUM_CAST(VisualShaderNodeTextureParameter::TextureType) +VARIANT_ENUM_CAST(VisualShaderNodeTextureParameter::ColorDefault) +VARIANT_ENUM_CAST(VisualShaderNodeTextureParameter::TextureFilter) +VARIANT_ENUM_CAST(VisualShaderNodeTextureParameter::TextureRepeat) + +/////////////////////////////////////// + +class VisualShaderNodeTexture2DParameter : public VisualShaderNodeTextureParameter { + GDCLASS(VisualShaderNodeTexture2DParameter, VisualShaderNodeTextureParameter); + +public: + virtual String get_caption() const override; + virtual String get_output_port_name(int p_port) const override; + + virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; + + VisualShaderNodeTexture2DParameter(); +}; /////////////////////////////////////// -class VisualShaderNodeTextureUniformTriplanar : public VisualShaderNodeTextureUniform { - GDCLASS(VisualShaderNodeTextureUniformTriplanar, VisualShaderNodeTextureUniform); +class VisualShaderNodeTextureParameterTriplanar : public VisualShaderNodeTextureParameter { + GDCLASS(VisualShaderNodeTextureParameterTriplanar, VisualShaderNodeTextureParameter); public: virtual String get_caption() const override; @@ -2270,52 +2280,49 @@ public: virtual String generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; - VisualShaderNodeTextureUniformTriplanar(); + VisualShaderNodeTextureParameterTriplanar(); }; /////////////////////////////////////// -class VisualShaderNodeTexture2DArrayUniform : public VisualShaderNodeTextureUniform { - GDCLASS(VisualShaderNodeTexture2DArrayUniform, VisualShaderNodeTextureUniform); +class VisualShaderNodeTexture2DArrayParameter : public VisualShaderNodeTextureParameter { + GDCLASS(VisualShaderNodeTexture2DArrayParameter, VisualShaderNodeTextureParameter); public: virtual String get_caption() const override; virtual String get_output_port_name(int p_port) const override; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; - VisualShaderNodeTexture2DArrayUniform(); + VisualShaderNodeTexture2DArrayParameter(); }; /////////////////////////////////////// -class VisualShaderNodeTexture3DUniform : public VisualShaderNodeTextureUniform { - GDCLASS(VisualShaderNodeTexture3DUniform, VisualShaderNodeTextureUniform); +class VisualShaderNodeTexture3DParameter : public VisualShaderNodeTextureParameter { + GDCLASS(VisualShaderNodeTexture3DParameter, VisualShaderNodeTextureParameter); public: virtual String get_caption() const override; virtual String get_output_port_name(int p_port) const override; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; - VisualShaderNodeTexture3DUniform(); + VisualShaderNodeTexture3DParameter(); }; /////////////////////////////////////// -class VisualShaderNodeCubemapUniform : public VisualShaderNodeTextureUniform { - GDCLASS(VisualShaderNodeCubemapUniform, VisualShaderNodeTextureUniform); +class VisualShaderNodeCubemapParameter : public VisualShaderNodeTextureParameter { + GDCLASS(VisualShaderNodeCubemapParameter, VisualShaderNodeTextureParameter); public: virtual String get_caption() const override; virtual String get_output_port_name(int p_port) const override; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; - VisualShaderNodeCubemapUniform(); + VisualShaderNodeCubemapParameter(); }; /////////////////////////////////////// diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp index 4dfbe5f079..75deb1e60b 100644 --- a/scene/resources/world_2d.cpp +++ b/scene/resources/world_2d.cpp @@ -85,6 +85,7 @@ World2D::World2D() { NavigationServer2D::get_singleton()->map_set_active(navigation_map, true); NavigationServer2D::get_singleton()->map_set_cell_size(navigation_map, GLOBAL_DEF("navigation/2d/default_cell_size", 1)); NavigationServer2D::get_singleton()->map_set_edge_connection_margin(navigation_map, GLOBAL_DEF("navigation/2d/default_edge_connection_margin", 1)); + NavigationServer2D::get_singleton()->map_set_link_connection_radius(navigation_map, GLOBAL_DEF("navigation/2d/default_link_connection_radius", 4)); } World2D::~World2D() { diff --git a/scene/resources/world_3d.cpp b/scene/resources/world_3d.cpp index 945b6af614..ae8c9a182f 100644 --- a/scene/resources/world_3d.cpp +++ b/scene/resources/world_3d.cpp @@ -153,6 +153,7 @@ World3D::World3D() { NavigationServer3D::get_singleton()->map_set_active(navigation_map, true); NavigationServer3D::get_singleton()->map_set_cell_size(navigation_map, GLOBAL_DEF("navigation/3d/default_cell_size", 0.25)); NavigationServer3D::get_singleton()->map_set_edge_connection_margin(navigation_map, GLOBAL_DEF("navigation/3d/default_edge_connection_margin", 0.25)); + NavigationServer3D::get_singleton()->map_set_link_connection_radius(navigation_map, GLOBAL_DEF("navigation/3d/default_link_connection_radius", 1.0)); } World3D::~World3D() { diff --git a/scene/theme/theme_owner.cpp b/scene/theme/theme_owner.cpp new file mode 100644 index 0000000000..e89aa1b28d --- /dev/null +++ b/scene/theme/theme_owner.cpp @@ -0,0 +1,410 @@ +/*************************************************************************/ +/* theme_owner.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "theme_owner.h" + +#include "scene/gui/control.h" +#include "scene/main/window.h" +#include "scene/theme/theme_db.h" + +// Theme owner node. + +void ThemeOwner::set_owner_node(Node *p_node) { + owner_control = nullptr; + owner_window = nullptr; + + Control *c = Object::cast_to<Control>(p_node); + if (c) { + owner_control = c; + return; + } + + Window *w = Object::cast_to<Window>(p_node); + if (w) { + owner_window = w; + return; + } +} + +Node *ThemeOwner::get_owner_node() const { + if (owner_control) { + return owner_control; + } else if (owner_window) { + return owner_window; + } + return nullptr; +} + +bool ThemeOwner::has_owner_node() const { + return bool(owner_control || owner_window); +} + +// Theme propagation. + +void ThemeOwner::assign_theme_on_parented(Node *p_for_node) { + // We check if there are any themes affecting the parent. If that's the case + // its children also need to be affected. + // We don't notify here because `NOTIFICATION_THEME_CHANGED` will be handled + // a bit later by `NOTIFICATION_ENTER_TREE`. + + Node *parent = p_for_node->get_parent(); + + Control *parent_c = Object::cast_to<Control>(parent); + if (parent_c && parent_c->has_theme_owner_node()) { + propagate_theme_changed(p_for_node, parent_c->get_theme_owner_node(), false, true); + } else { + Window *parent_w = Object::cast_to<Window>(parent); + if (parent_w && parent_w->has_theme_owner_node()) { + propagate_theme_changed(p_for_node, parent_w->get_theme_owner_node(), false, true); + } + } +} + +void ThemeOwner::clear_theme_on_unparented(Node *p_for_node) { + // We check if there were any themes affecting the parent. If that's the case + // its children need were also affected and need to be updated. + // We don't notify because we're exiting the tree, and it's not important. + + Node *parent = p_for_node->get_parent(); + + Control *parent_c = Object::cast_to<Control>(parent); + if (parent_c && parent_c->has_theme_owner_node()) { + propagate_theme_changed(p_for_node, nullptr, false, true); + } else { + Window *parent_w = Object::cast_to<Window>(parent); + if (parent_w && parent_w->has_theme_owner_node()) { + propagate_theme_changed(p_for_node, nullptr, false, true); + } + } +} + +void ThemeOwner::propagate_theme_changed(Node *p_to_node, Node *p_owner_node, bool p_notify, bool p_assign) { + Control *c = Object::cast_to<Control>(p_to_node); + Window *w = c == nullptr ? Object::cast_to<Window>(p_to_node) : nullptr; + + if (!c && !w) { + // Theme inheritance chains are broken by nodes that aren't Control or Window. + return; + } + + bool assign = p_assign; + if (c) { + if (c != p_owner_node && c->get_theme().is_valid()) { + // Has a theme, so we don't want to change the theme owner, + // but we still want to propagate in case this child has theme items + // it inherits from the theme this node uses. + // See https://github.com/godotengine/godot/issues/62844. + assign = false; + } + + if (assign) { + c->set_theme_owner_node(p_owner_node); + } + + if (p_notify) { + c->notification(Control::NOTIFICATION_THEME_CHANGED); + } + } else if (w) { + if (w != p_owner_node && w->get_theme().is_valid()) { + // Same as above. + assign = false; + } + + if (assign) { + w->set_theme_owner_node(p_owner_node); + } + + if (p_notify) { + w->notification(Window::NOTIFICATION_THEME_CHANGED); + } + } + + for (int i = 0; i < p_to_node->get_child_count(); i++) { + propagate_theme_changed(p_to_node->get_child(i), p_owner_node, p_notify, assign); + } +} + +// Theme lookup. + +void ThemeOwner::get_theme_type_dependencies(const Node *p_for_node, const StringName &p_theme_type, List<StringName> *r_list) const { + const Control *for_c = Object::cast_to<Control>(p_for_node); + const Window *for_w = Object::cast_to<Window>(p_for_node); + ERR_FAIL_COND_MSG(!for_c && !for_w, "Only Control and Window nodes and derivatives can be polled for theming."); + + Ref<Theme> default_theme = ThemeDB::get_singleton()->get_default_theme(); + Ref<Theme> project_theme = ThemeDB::get_singleton()->get_project_theme(); + + StringName type_variation; + if (for_c) { + type_variation = for_c->get_theme_type_variation(); + } else if (for_w) { + type_variation = for_w->get_theme_type_variation(); + } + + if (p_theme_type == StringName() || p_theme_type == p_for_node->get_class_name() || p_theme_type == type_variation) { + if (project_theme.is_valid() && project_theme->get_type_variation_base(type_variation) != StringName()) { + project_theme->get_type_dependencies(p_for_node->get_class_name(), type_variation, r_list); + } else { + default_theme->get_type_dependencies(p_for_node->get_class_name(), type_variation, r_list); + } + } else { + default_theme->get_type_dependencies(p_theme_type, StringName(), r_list); + } +} + +Node *ThemeOwner::_get_next_owner_node(Node *p_from_node) const { + Node *parent = p_from_node->get_parent(); + + Control *parent_c = Object::cast_to<Control>(parent); + if (parent_c) { + return parent_c->get_theme_owner_node(); + } else { + Window *parent_w = Object::cast_to<Window>(parent); + if (parent_w) { + return parent_w->get_theme_owner_node(); + } + } + + return nullptr; +} + +Variant ThemeOwner::get_theme_item_in_types(Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types) { + ERR_FAIL_COND_V_MSG(p_theme_types.size() == 0, Variant(), "At least one theme type must be specified."); + + // First, look through each control or window node in the branch, until no valid parent can be found. + // Only nodes with a theme resource attached are considered. + Node *owner_node = get_owner_node(); + + while (owner_node) { + // For each theme resource check the theme types provided and see if p_name exists with any of them. + for (const StringName &E : p_theme_types) { + Ref<Theme> owner_theme; + + Control *owner_c = Object::cast_to<Control>(owner_node); + if (owner_c) { + owner_theme = owner_c->get_theme(); + } + Window *owner_w = Object::cast_to<Window>(owner_node); + if (owner_w) { + owner_theme = owner_w->get_theme(); + } + + if (owner_theme.is_valid() && owner_theme->has_theme_item(p_data_type, p_name, E)) { + return owner_theme->get_theme_item(p_data_type, p_name, E); + } + } + + owner_node = _get_next_owner_node(owner_node); + } + + // Secondly, check the project-defined Theme resource. + if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { + for (const StringName &E : p_theme_types) { + if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(p_data_type, p_name, E)) { + return ThemeDB::get_singleton()->get_project_theme()->get_theme_item(p_data_type, p_name, E); + } + } + } + + // Lastly, fall back on the items defined in the default Theme, if they exist. + for (const StringName &E : p_theme_types) { + if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(p_data_type, p_name, E)) { + return ThemeDB::get_singleton()->get_default_theme()->get_theme_item(p_data_type, p_name, E); + } + } + + // If they don't exist, use any type to return the default/empty value. + return ThemeDB::get_singleton()->get_default_theme()->get_theme_item(p_data_type, p_name, p_theme_types[0]); +} + +bool ThemeOwner::has_theme_item_in_types(Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types) { + ERR_FAIL_COND_V_MSG(p_theme_types.size() == 0, false, "At least one theme type must be specified."); + + // First, look through each control or window node in the branch, until no valid parent can be found. + // Only nodes with a theme resource attached are considered. + Node *owner_node = get_owner_node(); + + while (owner_node) { + // For each theme resource check the theme types provided and see if p_name exists with any of them. + for (const StringName &E : p_theme_types) { + Ref<Theme> owner_theme; + + Control *owner_c = Object::cast_to<Control>(owner_node); + if (owner_c) { + owner_theme = owner_c->get_theme(); + } + Window *owner_w = Object::cast_to<Window>(owner_node); + if (owner_w) { + owner_theme = owner_w->get_theme(); + } + + if (owner_theme.is_valid() && owner_theme->has_theme_item(p_data_type, p_name, E)) { + return true; + } + } + + owner_node = _get_next_owner_node(owner_node); + } + + // Secondly, check the project-defined Theme resource. + if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { + for (const StringName &E : p_theme_types) { + if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(p_data_type, p_name, E)) { + return true; + } + } + } + + // Lastly, fall back on the items defined in the default Theme, if they exist. + for (const StringName &E : p_theme_types) { + if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(p_data_type, p_name, E)) { + return true; + } + } + + return false; +} + +float ThemeOwner::get_theme_default_base_scale() { + // First, look through each control or window node in the branch, until no valid parent can be found. + // Only nodes with a theme resource attached are considered. + // For each theme resource see if their assigned theme has the default value defined and valid. + Node *owner_node = get_owner_node(); + + while (owner_node) { + Ref<Theme> owner_theme; + + Control *owner_c = Object::cast_to<Control>(owner_node); + if (owner_c) { + owner_theme = owner_c->get_theme(); + } + Window *owner_w = Object::cast_to<Window>(owner_node); + if (owner_w) { + owner_theme = owner_w->get_theme(); + } + + if (owner_theme.is_valid() && owner_theme->has_default_base_scale()) { + return owner_theme->get_default_base_scale(); + } + + owner_node = _get_next_owner_node(owner_node); + } + + // Secondly, check the project-defined Theme resource. + if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { + if (ThemeDB::get_singleton()->get_project_theme()->has_default_base_scale()) { + return ThemeDB::get_singleton()->get_project_theme()->get_default_base_scale(); + } + } + + // Lastly, fall back on the default Theme. + if (ThemeDB::get_singleton()->get_default_theme()->has_default_base_scale()) { + return ThemeDB::get_singleton()->get_default_theme()->get_default_base_scale(); + } + return ThemeDB::get_singleton()->get_fallback_base_scale(); +} + +Ref<Font> ThemeOwner::get_theme_default_font() { + // First, look through each control or window node in the branch, until no valid parent can be found. + // Only nodes with a theme resource attached are considered. + // For each theme resource see if their assigned theme has the default value defined and valid. + Node *owner_node = get_owner_node(); + + while (owner_node) { + Ref<Theme> owner_theme; + + Control *owner_c = Object::cast_to<Control>(owner_node); + if (owner_c) { + owner_theme = owner_c->get_theme(); + } + Window *owner_w = Object::cast_to<Window>(owner_node); + if (owner_w) { + owner_theme = owner_w->get_theme(); + } + + if (owner_theme.is_valid() && owner_theme->has_default_font()) { + return owner_theme->get_default_font(); + } + + owner_node = _get_next_owner_node(owner_node); + } + + // Secondly, check the project-defined Theme resource. + if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { + if (ThemeDB::get_singleton()->get_project_theme()->has_default_font()) { + return ThemeDB::get_singleton()->get_project_theme()->get_default_font(); + } + } + + // Lastly, fall back on the default Theme. + if (ThemeDB::get_singleton()->get_default_theme()->has_default_font()) { + return ThemeDB::get_singleton()->get_default_theme()->get_default_font(); + } + return ThemeDB::get_singleton()->get_fallback_font(); +} + +int ThemeOwner::get_theme_default_font_size() { + // First, look through each control or window node in the branch, until no valid parent can be found. + // Only nodes with a theme resource attached are considered. + // For each theme resource see if their assigned theme has the default value defined and valid. + Node *owner_node = get_owner_node(); + + while (owner_node) { + Ref<Theme> owner_theme; + + Control *owner_c = Object::cast_to<Control>(owner_node); + if (owner_c) { + owner_theme = owner_c->get_theme(); + } + Window *owner_w = Object::cast_to<Window>(owner_node); + if (owner_w) { + owner_theme = owner_w->get_theme(); + } + + if (owner_theme.is_valid() && owner_theme->has_default_font_size()) { + return owner_theme->get_default_font_size(); + } + + owner_node = _get_next_owner_node(owner_node); + } + + // Secondly, check the project-defined Theme resource. + if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { + if (ThemeDB::get_singleton()->get_project_theme()->has_default_font_size()) { + return ThemeDB::get_singleton()->get_project_theme()->get_default_font_size(); + } + } + + // Lastly, fall back on the default Theme. + if (ThemeDB::get_singleton()->get_default_theme()->has_default_font_size()) { + return ThemeDB::get_singleton()->get_default_theme()->get_default_font_size(); + } + return ThemeDB::get_singleton()->get_fallback_font_size(); +} diff --git a/scene/theme/theme_owner.h b/scene/theme/theme_owner.h new file mode 100644 index 0000000000..59b72c1627 --- /dev/null +++ b/scene/theme/theme_owner.h @@ -0,0 +1,75 @@ +/*************************************************************************/ +/* theme_owner.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef THEME_OWNER_H +#define THEME_OWNER_H + +#include "core/object/object.h" +#include "scene/resources/theme.h" + +class Control; +class Node; +class Window; + +class ThemeOwner : public Object { + Control *owner_control = nullptr; + Window *owner_window = nullptr; + + Node *_get_next_owner_node(Node *p_from_node) const; + +public: + // Theme owner node. + + void set_owner_node(Node *p_node); + Node *get_owner_node() const; + bool has_owner_node() const; + + // Theme propagation. + + void assign_theme_on_parented(Node *p_for_node); + void clear_theme_on_unparented(Node *p_for_node); + void propagate_theme_changed(Node *p_to_node, Node *p_owner_node, bool p_notify, bool p_assign); + + // Theme lookup. + + void get_theme_type_dependencies(const Node *p_for_node, const StringName &p_theme_type, List<StringName> *r_list) const; + + Variant get_theme_item_in_types(Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types); + bool has_theme_item_in_types(Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types); + + float get_theme_default_base_scale(); + Ref<Font> get_theme_default_font(); + int get_theme_default_font_size(); + + ThemeOwner() {} + ~ThemeOwner() {} +}; + +#endif // THEME_OWNER_H diff --git a/servers/camera_server.cpp b/servers/camera_server.cpp index b83b41a571..b87cdd6d9f 100644 --- a/servers/camera_server.cpp +++ b/servers/camera_server.cpp @@ -105,10 +105,7 @@ void CameraServer::add_feed(const Ref<CameraFeed> &p_feed) { // add our feed feeds.push_back(p_feed); -// record for debugging -#ifdef DEBUG_ENABLED - print_line("Registered camera " + p_feed->get_name() + " with id " + itos(p_feed->get_id()) + " position " + itos(p_feed->get_position()) + " at index " + itos(feeds.size() - 1)); -#endif + print_verbose("CameraServer: Registered camera " + p_feed->get_name() + " with ID " + itos(p_feed->get_id()) + " and position " + itos(p_feed->get_position()) + " at index " + itos(feeds.size() - 1)); // let whomever is interested know emit_signal(SNAME("camera_feed_added"), p_feed->get_id()); @@ -119,10 +116,7 @@ void CameraServer::remove_feed(const Ref<CameraFeed> &p_feed) { if (feeds[i] == p_feed) { int feed_id = p_feed->get_id(); -// record for debugging -#ifdef DEBUG_ENABLED - print_line("Removed camera " + p_feed->get_name() + " with id " + itos(feed_id) + " position " + itos(p_feed->get_position())); -#endif + print_verbose("CameraServer: Removed camera " + p_feed->get_name() + " with ID " + itos(feed_id) + " and position " + itos(p_feed->get_position())); // remove it from our array, if this results in our feed being unreferenced it will be destroyed feeds.remove_at(i); diff --git a/servers/display_server.cpp b/servers/display_server.cpp index 22f42ca343..dda8e29b6a 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -44,37 +44,37 @@ DisplayServer::DisplayServerCreate DisplayServer::server_create_functions[Displa int DisplayServer::server_create_count = 1; -int DisplayServer::global_menu_add_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +int DisplayServer::global_menu_add_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Callable &p_key_callback, const Variant &p_tag, Key p_accel, int p_index) { WARN_PRINT("Global menus not supported by this display server."); return -1; } -int DisplayServer::global_menu_add_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +int DisplayServer::global_menu_add_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Callable &p_key_callback, const Variant &p_tag, Key p_accel, int p_index) { WARN_PRINT("Global menus not supported by this display server."); return -1; } -int DisplayServer::global_menu_add_icon_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +int DisplayServer::global_menu_add_icon_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Callable &p_key_callback, const Variant &p_tag, Key p_accel, int p_index) { WARN_PRINT("Global menus not supported by this display server."); return -1; } -int DisplayServer::global_menu_add_icon_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +int DisplayServer::global_menu_add_icon_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Callable &p_key_callback, const Variant &p_tag, Key p_accel, int p_index) { WARN_PRINT("Global menus not supported by this display server."); return -1; } -int DisplayServer::global_menu_add_radio_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +int DisplayServer::global_menu_add_radio_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Callable &p_key_callback, const Variant &p_tag, Key p_accel, int p_index) { WARN_PRINT("Global menus not supported by this display server."); return -1; } -int DisplayServer::global_menu_add_icon_radio_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +int DisplayServer::global_menu_add_icon_radio_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Callable &p_key_callback, const Variant &p_tag, Key p_accel, int p_index) { WARN_PRINT("Global menus not supported by this display server."); return -1; } -int DisplayServer::global_menu_add_multistate_item(const String &p_menu_root, const String &p_label, int p_max_states, int p_default_state, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +int DisplayServer::global_menu_add_multistate_item(const String &p_menu_root, const String &p_label, int p_max_states, int p_default_state, const Callable &p_callback, const Callable &p_key_callback, const Variant &p_tag, Key p_accel, int p_index) { WARN_PRINT("Global menus not supported by this display server."); return -1; } @@ -103,6 +103,10 @@ void DisplayServer::global_menu_set_item_callback(const String &p_menu_root, int WARN_PRINT("Global menus not supported by this display server."); } +void DisplayServer::global_menu_set_item_key_callback(const String &p_menu_root, int p_idx, const Callable &p_key_callback) { + WARN_PRINT("Global menus not supported by this display server."); +} + bool DisplayServer::global_menu_is_item_checked(const String &p_menu_root, int p_idx) const { WARN_PRINT("Global menus not supported by this display server."); return false; @@ -123,6 +127,11 @@ Callable DisplayServer::global_menu_get_item_callback(const String &p_menu_root, return Callable(); } +Callable DisplayServer::global_menu_get_item_key_callback(const String &p_menu_root, int p_idx) const { + WARN_PRINT("Global menus not supported by this display server."); + return Callable(); +} + Variant DisplayServer::global_menu_get_item_tag(const String &p_menu_root, int p_idx) const { WARN_PRINT("Global menus not supported by this display server."); return Variant(); @@ -527,14 +536,14 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("has_feature", "feature"), &DisplayServer::has_feature); ClassDB::bind_method(D_METHOD("get_name"), &DisplayServer::get_name); - ClassDB::bind_method(D_METHOD("global_menu_add_item", "menu_root", "label", "callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_item, DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); - ClassDB::bind_method(D_METHOD("global_menu_add_check_item", "menu_root", "label", "callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_check_item, DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); - ClassDB::bind_method(D_METHOD("global_menu_add_icon_item", "menu_root", "icon", "label", "callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_icon_item, DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); - ClassDB::bind_method(D_METHOD("global_menu_add_icon_check_item", "menu_root", "icon", "label", "callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_icon_check_item, DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); - ClassDB::bind_method(D_METHOD("global_menu_add_radio_check_item", "menu_root", "label", "callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_radio_check_item, DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); - ClassDB::bind_method(D_METHOD("global_menu_add_icon_radio_check_item", "menu_root", "icon", "label", "callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_icon_radio_check_item, DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); - ClassDB::bind_method(D_METHOD("global_menu_add_multistate_item", "menu_root", "labe", "max_states", "default_state", "callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_multistate_item, DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); ClassDB::bind_method(D_METHOD("global_menu_add_submenu_item", "menu_root", "label", "submenu", "index"), &DisplayServer::global_menu_add_submenu_item, DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("global_menu_add_item", "menu_root", "label", "callback", "key_callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_item, DEFVAL(Callable()), DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("global_menu_add_check_item", "menu_root", "label", "callback", "key_callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_check_item, DEFVAL(Callable()), DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("global_menu_add_icon_item", "menu_root", "icon", "label", "callback", "key_callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_icon_item, DEFVAL(Callable()), DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("global_menu_add_icon_check_item", "menu_root", "icon", "label", "callback", "key_callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_icon_check_item, DEFVAL(Callable()), DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("global_menu_add_radio_check_item", "menu_root", "label", "callback", "key_callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_radio_check_item, DEFVAL(Callable()), DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("global_menu_add_icon_radio_check_item", "menu_root", "icon", "label", "callback", "key_callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_icon_radio_check_item, DEFVAL(Callable()), DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("global_menu_add_multistate_item", "menu_root", "labe", "max_states", "default_state", "callback", "key_callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_multistate_item, DEFVAL(Callable()), DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); ClassDB::bind_method(D_METHOD("global_menu_add_separator", "menu_root", "index"), &DisplayServer::global_menu_add_separator, DEFVAL(-1)); ClassDB::bind_method(D_METHOD("global_menu_get_item_index_from_text", "menu_root", "text"), &DisplayServer::global_menu_get_item_index_from_text); @@ -544,6 +553,7 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("global_menu_is_item_checkable", "menu_root", "idx"), &DisplayServer::global_menu_is_item_checkable); ClassDB::bind_method(D_METHOD("global_menu_is_item_radio_checkable", "menu_root", "idx"), &DisplayServer::global_menu_is_item_radio_checkable); ClassDB::bind_method(D_METHOD("global_menu_get_item_callback", "menu_root", "idx"), &DisplayServer::global_menu_get_item_callback); + ClassDB::bind_method(D_METHOD("global_menu_get_item_key_callback", "menu_root", "idx"), &DisplayServer::global_menu_get_item_key_callback); ClassDB::bind_method(D_METHOD("global_menu_get_item_tag", "menu_root", "idx"), &DisplayServer::global_menu_get_item_tag); ClassDB::bind_method(D_METHOD("global_menu_get_item_text", "menu_root", "idx"), &DisplayServer::global_menu_get_item_text); ClassDB::bind_method(D_METHOD("global_menu_get_item_submenu", "menu_root", "idx"), &DisplayServer::global_menu_get_item_submenu); @@ -559,6 +569,7 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("global_menu_set_item_checkable", "menu_root", "idx", "checkable"), &DisplayServer::global_menu_set_item_checkable); ClassDB::bind_method(D_METHOD("global_menu_set_item_radio_checkable", "menu_root", "idx", "checkable"), &DisplayServer::global_menu_set_item_radio_checkable); ClassDB::bind_method(D_METHOD("global_menu_set_item_callback", "menu_root", "idx", "callback"), &DisplayServer::global_menu_set_item_callback); + ClassDB::bind_method(D_METHOD("global_menu_set_item_key_callback", "menu_root", "idx", "key_callback"), &DisplayServer::global_menu_set_item_key_callback); ClassDB::bind_method(D_METHOD("global_menu_set_item_tag", "menu_root", "idx", "tag"), &DisplayServer::global_menu_set_item_tag); ClassDB::bind_method(D_METHOD("global_menu_set_item_text", "menu_root", "idx", "text"), &DisplayServer::global_menu_set_item_text); ClassDB::bind_method(D_METHOD("global_menu_set_item_submenu", "menu_root", "idx", "submenu"), &DisplayServer::global_menu_set_item_submenu); @@ -586,6 +597,10 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("tts_set_utterance_callback", "event", "callable"), &DisplayServer::tts_set_utterance_callback); ClassDB::bind_method(D_METHOD("_tts_post_utterance_event", "event", "id", "char_pos"), &DisplayServer::tts_post_utterance_event); + ClassDB::bind_method(D_METHOD("is_dark_mode_supported"), &DisplayServer::is_dark_mode_supported); + ClassDB::bind_method(D_METHOD("is_dark_mode"), &DisplayServer::is_dark_mode); + ClassDB::bind_method(D_METHOD("get_accent_color"), &DisplayServer::get_accent_color); + ClassDB::bind_method(D_METHOD("mouse_set_mode", "mouse_mode"), &DisplayServer::mouse_set_mode); ClassDB::bind_method(D_METHOD("mouse_get_mode"), &DisplayServer::mouse_get_mode); diff --git a/servers/display_server.h b/servers/display_server.h index 0b162fe491..ab4f9fc499 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -128,14 +128,14 @@ public: virtual bool has_feature(Feature p_feature) const = 0; virtual String get_name() const = 0; - virtual int global_menu_add_item(const String &p_menu_root, const String &p_label, const Callable &p_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1); - virtual int global_menu_add_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1); - virtual int global_menu_add_icon_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1); - virtual int global_menu_add_icon_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1); - virtual int global_menu_add_radio_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1); - virtual int global_menu_add_icon_radio_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1); - virtual int global_menu_add_multistate_item(const String &p_menu_root, const String &p_label, int p_max_states, int p_default_state, const Callable &p_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1); virtual int global_menu_add_submenu_item(const String &p_menu_root, const String &p_label, const String &p_submenu, int p_index = -1); + virtual int global_menu_add_item(const String &p_menu_root, const String &p_label, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1); + virtual int global_menu_add_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1); + virtual int global_menu_add_icon_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1); + virtual int global_menu_add_icon_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1); + virtual int global_menu_add_radio_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1); + virtual int global_menu_add_icon_radio_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1); + virtual int global_menu_add_multistate_item(const String &p_menu_root, const String &p_label, int p_max_states, int p_default_state, const Callable &p_callback = Callable(), const Callable &p_key_callback = Callable(), const Variant &p_tag = Variant(), Key p_accel = Key::NONE, int p_index = -1); virtual int global_menu_add_separator(const String &p_menu_root, int p_index = -1); virtual int global_menu_get_item_index_from_text(const String &p_menu_root, const String &p_text) const; @@ -145,6 +145,7 @@ public: virtual bool global_menu_is_item_checkable(const String &p_menu_root, int p_idx) const; virtual bool global_menu_is_item_radio_checkable(const String &p_menu_root, int p_idx) const; virtual Callable global_menu_get_item_callback(const String &p_menu_root, int p_idx) const; + virtual Callable global_menu_get_item_key_callback(const String &p_menu_root, int p_idx) const; virtual Variant global_menu_get_item_tag(const String &p_menu_root, int p_idx) const; virtual String global_menu_get_item_text(const String &p_menu_root, int p_idx) const; virtual String global_menu_get_item_submenu(const String &p_menu_root, int p_idx) const; @@ -160,6 +161,7 @@ public: virtual void global_menu_set_item_checkable(const String &p_menu_root, int p_idx, bool p_checkable); virtual void global_menu_set_item_radio_checkable(const String &p_menu_root, int p_idx, bool p_checkable); virtual void global_menu_set_item_callback(const String &p_menu_root, int p_idx, const Callable &p_callback); + virtual void global_menu_set_item_key_callback(const String &p_menu_root, int p_idx, const Callable &p_key_callback); virtual void global_menu_set_item_tag(const String &p_menu_root, int p_idx, const Variant &p_tag); virtual void global_menu_set_item_text(const String &p_menu_root, int p_idx, const String &p_text); virtual void global_menu_set_item_submenu(const String &p_menu_root, int p_idx, const String &p_submenu); @@ -210,6 +212,10 @@ public: virtual void tts_set_utterance_callback(TTSUtteranceEvent p_event, const Callable &p_callable); virtual void tts_post_utterance_event(TTSUtteranceEvent p_event, int p_id, int p_pos = 0); + virtual bool is_dark_mode_supported() const { return false; }; + virtual bool is_dark_mode() const { return false; }; + virtual Color get_accent_color() const { return Color(0, 0, 0, 0); }; + enum MouseMode { MOUSE_MODE_VISIBLE, MOUSE_MODE_HIDDEN, diff --git a/servers/navigation_server_2d.cpp b/servers/navigation_server_2d.cpp index 0f73df8894..cec8b95225 100644 --- a/servers/navigation_server_2d.cpp +++ b/servers/navigation_server_2d.cpp @@ -53,6 +53,12 @@ NavigationServer2D *NavigationServer2D::singleton = nullptr; return NavigationServer3D::get_singleton()->FUNC_NAME(CONV_0(D_0)); \ } +#define FORWARD_1_R_C(CONV_R, FUNC_NAME, T_0, D_0, CONV_0) \ + NavigationServer2D::FUNC_NAME(T_0 D_0) \ + const { \ + return CONV_R(NavigationServer3D::get_singleton()->FUNC_NAME(CONV_0(D_0))); \ + } + #define FORWARD_2_C(FUNC_NAME, T_0, D_0, T_1, D_1, CONV_0, CONV_1) \ NavigationServer2D::FUNC_NAME(T_0 D_0, T_1 D_1) \ const { \ @@ -190,6 +196,22 @@ Color NavigationServer2D::get_debug_navigation_geometry_face_disabled_color() co return NavigationServer3D::get_singleton()->get_debug_navigation_geometry_face_disabled_color(); } +void NavigationServer2D::set_debug_navigation_link_connection_color(const Color &p_color) { + NavigationServer3D::get_singleton_mut()->set_debug_navigation_link_connection_color(p_color); +} + +Color NavigationServer2D::get_debug_navigation_link_connection_color() const { + return NavigationServer3D::get_singleton()->get_debug_navigation_link_connection_color(); +} + +void NavigationServer2D::set_debug_navigation_link_connection_disabled_color(const Color &p_color) { + NavigationServer3D::get_singleton_mut()->set_debug_navigation_link_connection_disabled_color(p_color); +} + +Color NavigationServer2D::get_debug_navigation_link_connection_disabled_color() const { + return NavigationServer3D::get_singleton()->get_debug_navigation_link_connection_disabled_color(); +} + void NavigationServer2D::set_debug_navigation_enable_edge_connections(const bool p_value) { NavigationServer3D::get_singleton_mut()->set_debug_navigation_enable_edge_connections(p_value); } @@ -209,10 +231,13 @@ void NavigationServer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("map_get_cell_size", "map"), &NavigationServer2D::map_get_cell_size); ClassDB::bind_method(D_METHOD("map_set_edge_connection_margin", "map", "margin"), &NavigationServer2D::map_set_edge_connection_margin); ClassDB::bind_method(D_METHOD("map_get_edge_connection_margin", "map"), &NavigationServer2D::map_get_edge_connection_margin); + ClassDB::bind_method(D_METHOD("map_set_link_connection_radius", "map", "radius"), &NavigationServer2D::map_set_link_connection_radius); + ClassDB::bind_method(D_METHOD("map_get_link_connection_radius", "map"), &NavigationServer2D::map_get_link_connection_radius); ClassDB::bind_method(D_METHOD("map_get_path", "map", "origin", "destination", "optimize", "navigation_layers"), &NavigationServer2D::map_get_path, DEFVAL(1)); ClassDB::bind_method(D_METHOD("map_get_closest_point", "map", "to_point"), &NavigationServer2D::map_get_closest_point); ClassDB::bind_method(D_METHOD("map_get_closest_point_owner", "map", "to_point"), &NavigationServer2D::map_get_closest_point_owner); + ClassDB::bind_method(D_METHOD("map_get_links", "map"), &NavigationServer2D::map_get_links); ClassDB::bind_method(D_METHOD("map_get_regions", "map"), &NavigationServer2D::map_get_regions); ClassDB::bind_method(D_METHOD("map_get_agents", "map"), &NavigationServer2D::map_get_agents); @@ -234,6 +259,22 @@ void NavigationServer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("region_get_connection_pathway_start", "region", "connection"), &NavigationServer2D::region_get_connection_pathway_start); ClassDB::bind_method(D_METHOD("region_get_connection_pathway_end", "region", "connection"), &NavigationServer2D::region_get_connection_pathway_end); + ClassDB::bind_method(D_METHOD("link_create"), &NavigationServer2D::link_create); + ClassDB::bind_method(D_METHOD("link_set_map", "link", "map"), &NavigationServer2D::link_set_map); + ClassDB::bind_method(D_METHOD("link_get_map", "link"), &NavigationServer2D::link_get_map); + ClassDB::bind_method(D_METHOD("link_set_bidirectional", "link", "bidirectional"), &NavigationServer2D::link_set_bidirectional); + ClassDB::bind_method(D_METHOD("link_is_bidirectional", "link"), &NavigationServer2D::link_is_bidirectional); + ClassDB::bind_method(D_METHOD("link_set_navigation_layers", "link", "navigation_layers"), &NavigationServer2D::link_set_navigation_layers); + ClassDB::bind_method(D_METHOD("link_get_navigation_layers", "link"), &NavigationServer2D::link_get_navigation_layers); + ClassDB::bind_method(D_METHOD("link_set_start_location", "link", "location"), &NavigationServer2D::link_set_start_location); + ClassDB::bind_method(D_METHOD("link_get_start_location", "link"), &NavigationServer2D::link_get_start_location); + ClassDB::bind_method(D_METHOD("link_set_end_location", "link", "location"), &NavigationServer2D::link_set_end_location); + ClassDB::bind_method(D_METHOD("link_get_end_location", "link"), &NavigationServer2D::link_get_end_location); + ClassDB::bind_method(D_METHOD("link_set_enter_cost", "link", "enter_cost"), &NavigationServer2D::link_set_enter_cost); + ClassDB::bind_method(D_METHOD("link_get_enter_cost", "link"), &NavigationServer2D::link_get_enter_cost); + ClassDB::bind_method(D_METHOD("link_set_travel_cost", "link", "travel_cost"), &NavigationServer2D::link_set_travel_cost); + ClassDB::bind_method(D_METHOD("link_get_travel_cost", "link"), &NavigationServer2D::link_get_travel_cost); + ClassDB::bind_method(D_METHOD("agent_create"), &NavigationServer2D::agent_create); ClassDB::bind_method(D_METHOD("agent_set_map", "agent", "map"), &NavigationServer2D::agent_set_map); ClassDB::bind_method(D_METHOD("agent_get_map", "agent"), &NavigationServer2D::agent_get_map); @@ -265,6 +306,8 @@ NavigationServer2D::~NavigationServer2D() { TypedArray<RID> FORWARD_0_C(get_maps); +TypedArray<RID> FORWARD_1_C(map_get_links, RID, p_map, rid_to_rid); + TypedArray<RID> FORWARD_1_C(map_get_regions, RID, p_map, rid_to_rid); TypedArray<RID> FORWARD_1_C(map_get_agents, RID, p_map, rid_to_rid); @@ -289,6 +332,9 @@ real_t FORWARD_1_C(map_get_cell_size, RID, p_map, rid_to_rid); void FORWARD_2_C(map_set_edge_connection_margin, RID, p_map, real_t, p_connection_margin, rid_to_rid, real_to_real); real_t FORWARD_1_C(map_get_edge_connection_margin, RID, p_map, rid_to_rid); +void FORWARD_2_C(map_set_link_connection_radius, RID, p_map, real_t, p_connection_radius, rid_to_rid, real_to_real); +real_t FORWARD_1_C(map_get_link_connection_radius, RID, p_map, rid_to_rid); + Vector<Vector2> FORWARD_5_R_C(vector_v3_to_v2, map_get_path, RID, p_map, Vector2, p_origin, Vector2, p_destination, bool, p_optimize, uint32_t, p_layers, rid_to_rid, v2_to_v3, v2_to_v3, bool_to_bool, uint32_to_uint32); Vector2 FORWARD_2_R_C(v3_to_v2, map_get_closest_point, RID, p_map, const Vector2 &, p_point, rid_to_rid, v2_to_v3); @@ -315,6 +361,23 @@ int FORWARD_1_C(region_get_connections_count, RID, p_region, rid_to_rid); Vector2 FORWARD_2_R_C(v3_to_v2, region_get_connection_pathway_start, RID, p_region, int, p_connection_id, rid_to_rid, int_to_int); Vector2 FORWARD_2_R_C(v3_to_v2, region_get_connection_pathway_end, RID, p_region, int, p_connection_id, rid_to_rid, int_to_int); +RID FORWARD_0_C(link_create); + +void FORWARD_2_C(link_set_map, RID, p_link, RID, p_map, rid_to_rid, rid_to_rid); +RID FORWARD_1_C(link_get_map, RID, p_link, rid_to_rid); +void FORWARD_2_C(link_set_bidirectional, RID, p_link, bool, p_bidirectional, rid_to_rid, bool_to_bool); +bool FORWARD_1_C(link_is_bidirectional, RID, p_link, rid_to_rid); +void FORWARD_2_C(link_set_navigation_layers, RID, p_link, uint32_t, p_navigation_layers, rid_to_rid, uint32_to_uint32); +uint32_t FORWARD_1_C(link_get_navigation_layers, RID, p_link, rid_to_rid); +void FORWARD_2_C(link_set_start_location, RID, p_link, Vector2, p_location, rid_to_rid, v2_to_v3); +Vector2 FORWARD_1_R_C(v3_to_v2, link_get_start_location, RID, p_link, rid_to_rid); +void FORWARD_2_C(link_set_end_location, RID, p_link, Vector2, p_location, rid_to_rid, v2_to_v3); +Vector2 FORWARD_1_R_C(v3_to_v2, link_get_end_location, RID, p_link, rid_to_rid); +void FORWARD_2_C(link_set_enter_cost, RID, p_link, real_t, p_enter_cost, rid_to_rid, real_to_real); +real_t FORWARD_1_C(link_get_enter_cost, RID, p_link, rid_to_rid); +void FORWARD_2_C(link_set_travel_cost, RID, p_link, real_t, p_travel_cost, rid_to_rid, real_to_real); +real_t FORWARD_1_C(link_get_travel_cost, RID, p_link, rid_to_rid); + RID NavigationServer2D::agent_create() const { RID agent = NavigationServer3D::get_singleton()->agent_create(); NavigationServer3D::get_singleton()->agent_set_ignore_y(agent, true); diff --git a/servers/navigation_server_2d.h b/servers/navigation_server_2d.h index 5e96466d66..b2ea4c28a0 100644 --- a/servers/navigation_server_2d.h +++ b/servers/navigation_server_2d.h @@ -76,12 +76,19 @@ public: /// Returns the edge connection margin of this map. virtual real_t map_get_edge_connection_margin(RID p_map) const; + /// Set the map link connection radius used to attach links to the nav mesh. + virtual void map_set_link_connection_radius(RID p_map, real_t p_connection_radius) const; + + /// Returns the link connection radius of this map. + virtual real_t map_get_link_connection_radius(RID p_map) const; + /// Returns the navigation path to reach the destination from the origin. virtual Vector<Vector2> map_get_path(RID p_map, Vector2 p_origin, Vector2 p_destination, bool p_optimize, uint32_t p_navigation_layers = 1) const; virtual Vector2 map_get_closest_point(RID p_map, const Vector2 &p_point) const; virtual RID map_get_closest_point_owner(RID p_map, const Vector2 &p_point) const; + virtual TypedArray<RID> map_get_links(RID p_map) const; virtual TypedArray<RID> map_get_regions(RID p_map) const; virtual TypedArray<RID> map_get_agents(RID p_map) const; @@ -119,6 +126,37 @@ public: virtual Vector2 region_get_connection_pathway_start(RID p_region, int p_connection_id) const; virtual Vector2 region_get_connection_pathway_end(RID p_region, int p_connection_id) const; + /// Creates a new link between locations in the nav map. + virtual RID link_create() const; + + /// Set the map of this link. + virtual void link_set_map(RID p_link, RID p_map) const; + virtual RID link_get_map(RID p_link) const; + + /// Set whether this link travels in both directions. + virtual void link_set_bidirectional(RID p_link, bool p_bidirectional) const; + virtual bool link_is_bidirectional(RID p_link) const; + + /// Set the link's layers. + virtual void link_set_navigation_layers(RID p_link, uint32_t p_navigation_layers) const; + virtual uint32_t link_get_navigation_layers(RID p_link) const; + + /// Set the start location of the link. + virtual void link_set_start_location(RID p_link, Vector2 p_location) const; + virtual Vector2 link_get_start_location(RID p_link) const; + + /// Set the end location of the link. + virtual void link_set_end_location(RID p_link, Vector2 p_location) const; + virtual Vector2 link_get_end_location(RID p_link) const; + + /// Set the enter cost of the link. + virtual void link_set_enter_cost(RID p_link, real_t p_enter_cost) const; + virtual real_t link_get_enter_cost(RID p_link) const; + + /// Set the travel cost of the link. + virtual void link_set_travel_cost(RID p_link, real_t p_travel_cost) const; + virtual real_t link_get_travel_cost(RID p_link) const; + /// Creates the agent. virtual RID agent_create() const; @@ -198,6 +236,12 @@ public: void set_debug_navigation_geometry_face_disabled_color(const Color &p_color); Color get_debug_navigation_geometry_face_disabled_color() const; + void set_debug_navigation_link_connection_color(const Color &p_color); + Color get_debug_navigation_link_connection_color() const; + + void set_debug_navigation_link_connection_disabled_color(const Color &p_color); + Color get_debug_navigation_link_connection_disabled_color() const; + void set_debug_navigation_enable_edge_connections(const bool p_value); bool get_debug_navigation_enable_edge_connections() const; #endif // DEBUG_ENABLED diff --git a/servers/navigation_server_3d.cpp b/servers/navigation_server_3d.cpp index 466b74bc64..bc0602e1df 100644 --- a/servers/navigation_server_3d.cpp +++ b/servers/navigation_server_3d.cpp @@ -48,12 +48,15 @@ void NavigationServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("map_get_cell_size", "map"), &NavigationServer3D::map_get_cell_size); ClassDB::bind_method(D_METHOD("map_set_edge_connection_margin", "map", "margin"), &NavigationServer3D::map_set_edge_connection_margin); ClassDB::bind_method(D_METHOD("map_get_edge_connection_margin", "map"), &NavigationServer3D::map_get_edge_connection_margin); + ClassDB::bind_method(D_METHOD("map_set_link_connection_radius", "map", "radius"), &NavigationServer3D::map_set_link_connection_radius); + ClassDB::bind_method(D_METHOD("map_get_link_connection_radius", "map"), &NavigationServer3D::map_get_link_connection_radius); ClassDB::bind_method(D_METHOD("map_get_path", "map", "origin", "destination", "optimize", "navigation_layers"), &NavigationServer3D::map_get_path, DEFVAL(1)); ClassDB::bind_method(D_METHOD("map_get_closest_point_to_segment", "map", "start", "end", "use_collision"), &NavigationServer3D::map_get_closest_point_to_segment, DEFVAL(false)); ClassDB::bind_method(D_METHOD("map_get_closest_point", "map", "to_point"), &NavigationServer3D::map_get_closest_point); ClassDB::bind_method(D_METHOD("map_get_closest_point_normal", "map", "to_point"), &NavigationServer3D::map_get_closest_point_normal); ClassDB::bind_method(D_METHOD("map_get_closest_point_owner", "map", "to_point"), &NavigationServer3D::map_get_closest_point_owner); + ClassDB::bind_method(D_METHOD("map_get_links", "map"), &NavigationServer3D::map_get_links); ClassDB::bind_method(D_METHOD("map_get_regions", "map"), &NavigationServer3D::map_get_regions); ClassDB::bind_method(D_METHOD("map_get_agents", "map"), &NavigationServer3D::map_get_agents); @@ -76,6 +79,22 @@ void NavigationServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("region_get_connection_pathway_start", "region", "connection"), &NavigationServer3D::region_get_connection_pathway_start); ClassDB::bind_method(D_METHOD("region_get_connection_pathway_end", "region", "connection"), &NavigationServer3D::region_get_connection_pathway_end); + ClassDB::bind_method(D_METHOD("link_create"), &NavigationServer3D::link_create); + ClassDB::bind_method(D_METHOD("link_set_map", "link", "map"), &NavigationServer3D::link_set_map); + ClassDB::bind_method(D_METHOD("link_get_map", "link"), &NavigationServer3D::link_get_map); + ClassDB::bind_method(D_METHOD("link_set_bidirectional", "link", "bidirectional"), &NavigationServer3D::link_set_bidirectional); + ClassDB::bind_method(D_METHOD("link_is_bidirectional", "link"), &NavigationServer3D::link_is_bidirectional); + ClassDB::bind_method(D_METHOD("link_set_navigation_layers", "link", "navigation_layers"), &NavigationServer3D::link_set_navigation_layers); + ClassDB::bind_method(D_METHOD("link_get_navigation_layers", "link"), &NavigationServer3D::link_get_navigation_layers); + ClassDB::bind_method(D_METHOD("link_set_start_location", "link", "location"), &NavigationServer3D::link_set_start_location); + ClassDB::bind_method(D_METHOD("link_get_start_location", "link"), &NavigationServer3D::link_get_start_location); + ClassDB::bind_method(D_METHOD("link_set_end_location", "link", "location"), &NavigationServer3D::link_set_end_location); + ClassDB::bind_method(D_METHOD("link_get_end_location", "link"), &NavigationServer3D::link_get_end_location); + ClassDB::bind_method(D_METHOD("link_set_enter_cost", "link", "enter_cost"), &NavigationServer3D::link_set_enter_cost); + ClassDB::bind_method(D_METHOD("link_get_enter_cost", "link"), &NavigationServer3D::link_get_enter_cost); + ClassDB::bind_method(D_METHOD("link_set_travel_cost", "link", "travel_cost"), &NavigationServer3D::link_set_travel_cost); + ClassDB::bind_method(D_METHOD("link_get_travel_cost", "link"), &NavigationServer3D::link_get_travel_cost); + ClassDB::bind_method(D_METHOD("agent_create"), &NavigationServer3D::agent_create); ClassDB::bind_method(D_METHOD("agent_set_map", "agent", "map"), &NavigationServer3D::agent_set_map); ClassDB::bind_method(D_METHOD("agent_get_map", "agent"), &NavigationServer3D::agent_get_map); @@ -118,11 +137,16 @@ NavigationServer3D::NavigationServer3D() { debug_navigation_geometry_face_color = GLOBAL_DEF("debug/shapes/navigation/geometry_face_color", Color(0.5, 1.0, 1.0, 0.4)); debug_navigation_geometry_edge_disabled_color = GLOBAL_DEF("debug/shapes/navigation/geometry_edge_disabled_color", Color(0.5, 0.5, 0.5, 1.0)); debug_navigation_geometry_face_disabled_color = GLOBAL_DEF("debug/shapes/navigation/geometry_face_disabled_color", Color(0.5, 0.5, 0.5, 0.4)); + debug_navigation_link_connection_color = GLOBAL_DEF("debug/shapes/navigation/link_connection_color", Color(1.0, 0.5, 1.0, 1.0)); + debug_navigation_link_connection_disabled_color = GLOBAL_DEF("debug/shapes/navigation/link_connection_disabled_color", Color(0.5, 0.5, 0.5, 1.0)); + debug_navigation_enable_edge_connections = GLOBAL_DEF("debug/shapes/navigation/enable_edge_connections", true); debug_navigation_enable_edge_connections_xray = GLOBAL_DEF("debug/shapes/navigation/enable_edge_connections_xray", true); debug_navigation_enable_edge_lines = GLOBAL_DEF("debug/shapes/navigation/enable_edge_lines", true); debug_navigation_enable_edge_lines_xray = GLOBAL_DEF("debug/shapes/navigation/enable_edge_lines_xray", true); debug_navigation_enable_geometry_face_random_color = GLOBAL_DEF("debug/shapes/navigation/enable_geometry_face_random_color", true); + debug_navigation_enable_link_connections = GLOBAL_DEF("debug/shapes/navigation/enable_link_connections", true); + debug_navigation_enable_link_connections_xray = GLOBAL_DEF("debug/shapes/navigation/enable_link_connections_xray", true); if (Engine::get_singleton()->is_editor_hint()) { // enable NavigationServer3D when in Editor or else navmesh edge connections are invisible @@ -261,6 +285,40 @@ Ref<StandardMaterial3D> NavigationServer3D::get_debug_navigation_edge_connection return debug_navigation_edge_connections_material; } +Ref<StandardMaterial3D> NavigationServer3D::get_debug_navigation_link_connections_material() { + if (debug_navigation_link_connections_material.is_valid()) { + return debug_navigation_link_connections_material; + } + + Ref<StandardMaterial3D> material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); + material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + material->set_albedo(debug_navigation_link_connection_color); + if (debug_navigation_enable_link_connections_xray) { + material->set_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST, true); + } + material->set_render_priority(StandardMaterial3D::RENDER_PRIORITY_MAX - 2); + + debug_navigation_link_connections_material = material; + return debug_navigation_link_connections_material; +} + +Ref<StandardMaterial3D> NavigationServer3D::get_debug_navigation_link_connections_disabled_material() { + if (debug_navigation_link_connections_disabled_material.is_valid()) { + return debug_navigation_link_connections_disabled_material; + } + + Ref<StandardMaterial3D> material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); + material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + material->set_albedo(debug_navigation_link_connection_disabled_color); + if (debug_navigation_enable_link_connections_xray) { + material->set_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST, true); + } + material->set_render_priority(StandardMaterial3D::RENDER_PRIORITY_MAX - 2); + + debug_navigation_link_connections_disabled_material = material; + return debug_navigation_link_connections_disabled_material; +} + void NavigationServer3D::set_debug_navigation_edge_connection_color(const Color &p_color) { debug_navigation_edge_connection_color = p_color; if (debug_navigation_edge_connections_material.is_valid()) { @@ -316,6 +374,28 @@ Color NavigationServer3D::get_debug_navigation_geometry_face_disabled_color() co return debug_navigation_geometry_face_disabled_color; } +void NavigationServer3D::set_debug_navigation_link_connection_color(const Color &p_color) { + debug_navigation_link_connection_color = p_color; + if (debug_navigation_link_connections_material.is_valid()) { + debug_navigation_link_connections_material->set_albedo(debug_navigation_link_connection_color); + } +} + +Color NavigationServer3D::get_debug_navigation_link_connection_color() const { + return debug_navigation_link_connection_color; +} + +void NavigationServer3D::set_debug_navigation_link_connection_disabled_color(const Color &p_color) { + debug_navigation_link_connection_disabled_color = p_color; + if (debug_navigation_link_connections_disabled_material.is_valid()) { + debug_navigation_link_connections_disabled_material->set_albedo(debug_navigation_link_connection_disabled_color); + } +} + +Color NavigationServer3D::get_debug_navigation_link_connection_disabled_color() const { + return debug_navigation_link_connection_disabled_color; +} + void NavigationServer3D::set_debug_navigation_enable_edge_connections(const bool p_value) { debug_navigation_enable_edge_connections = p_value; debug_dirty = true; @@ -368,6 +448,27 @@ bool NavigationServer3D::get_debug_navigation_enable_geometry_face_random_color( return debug_navigation_enable_geometry_face_random_color; } +void NavigationServer3D::set_debug_navigation_enable_link_connections(const bool p_value) { + debug_navigation_enable_link_connections = p_value; + debug_dirty = true; + call_deferred("_emit_navigation_debug_changed_signal"); +} + +bool NavigationServer3D::get_debug_navigation_enable_link_connections() const { + return debug_navigation_enable_link_connections; +} + +void NavigationServer3D::set_debug_navigation_enable_link_connections_xray(const bool p_value) { + debug_navigation_enable_link_connections_xray = p_value; + if (debug_navigation_link_connections_material.is_valid()) { + debug_navigation_link_connections_material->set_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST, debug_navigation_enable_link_connections_xray); + } +} + +bool NavigationServer3D::get_debug_navigation_enable_link_connections_xray() const { + return debug_navigation_enable_link_connections_xray; +} + void NavigationServer3D::set_debug_enabled(bool p_enabled) { if (debug_enabled != p_enabled) { debug_dirty = true; diff --git a/servers/navigation_server_3d.h b/servers/navigation_server_3d.h index 3213da3d84..02770794c6 100644 --- a/servers/navigation_server_3d.h +++ b/servers/navigation_server_3d.h @@ -85,6 +85,12 @@ public: /// Returns the edge connection margin of this map. virtual real_t map_get_edge_connection_margin(RID p_map) const = 0; + /// Set the map link connection radius used to attach links to the nav mesh. + virtual void map_set_link_connection_radius(RID p_map, real_t p_connection_radius) const = 0; + + /// Returns the link connection radius of this map. + virtual real_t map_get_link_connection_radius(RID p_map) const = 0; + /// Returns the navigation path to reach the destination from the origin. virtual Vector<Vector3> map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_navigation_layers = 1) const = 0; @@ -93,6 +99,7 @@ public: virtual Vector3 map_get_closest_point_normal(RID p_map, const Vector3 &p_point) const = 0; virtual RID map_get_closest_point_owner(RID p_map, const Vector3 &p_point) const = 0; + virtual TypedArray<RID> map_get_links(RID p_map) const = 0; virtual TypedArray<RID> map_get_regions(RID p_map) const = 0; virtual TypedArray<RID> map_get_agents(RID p_map) const = 0; @@ -133,6 +140,37 @@ public: virtual Vector3 region_get_connection_pathway_start(RID p_region, int p_connection_id) const = 0; virtual Vector3 region_get_connection_pathway_end(RID p_region, int p_connection_id) const = 0; + /// Creates a new link between locations in the nav map. + virtual RID link_create() const = 0; + + /// Set the map of this link. + virtual void link_set_map(RID p_link, RID p_map) const = 0; + virtual RID link_get_map(RID p_link) const = 0; + + /// Set whether this link travels in both directions. + virtual void link_set_bidirectional(RID p_link, bool p_bidirectional) const = 0; + virtual bool link_is_bidirectional(RID p_link) const = 0; + + /// Set the link's layers. + virtual void link_set_navigation_layers(RID p_link, uint32_t p_navigation_layers) const = 0; + virtual uint32_t link_get_navigation_layers(RID p_link) const = 0; + + /// Set the start location of the link. + virtual void link_set_start_location(RID p_link, Vector3 p_location) const = 0; + virtual Vector3 link_get_start_location(RID p_link) const = 0; + + /// Set the end location of the link. + virtual void link_set_end_location(RID p_link, Vector3 p_location) const = 0; + virtual Vector3 link_get_end_location(RID p_link) const = 0; + + /// Set the enter cost of the link. + virtual void link_set_enter_cost(RID p_link, real_t p_enter_cost) const = 0; + virtual real_t link_get_enter_cost(RID p_link) const = 0; + + /// Set the travel cost of the link. + virtual void link_set_travel_cost(RID p_link, real_t p_travel_cost) const = 0; + virtual real_t link_get_travel_cost(RID p_link) const = 0; + /// Creates the agent. virtual RID agent_create() const = 0; @@ -209,29 +247,38 @@ public: virtual ~NavigationServer3D(); #ifdef DEBUG_ENABLED +private: bool debug_enabled = false; bool debug_dirty = true; void _emit_navigation_debug_changed_signal(); - void set_debug_enabled(bool p_enabled); - bool get_debug_enabled() const; - Color debug_navigation_edge_connection_color = Color(1.0, 0.0, 1.0, 1.0); Color debug_navigation_geometry_edge_color = Color(0.5, 1.0, 1.0, 1.0); Color debug_navigation_geometry_face_color = Color(0.5, 1.0, 1.0, 0.4); Color debug_navigation_geometry_edge_disabled_color = Color(0.5, 0.5, 0.5, 1.0); Color debug_navigation_geometry_face_disabled_color = Color(0.5, 0.5, 0.5, 0.4); + Color debug_navigation_link_connection_color = Color(1.0, 0.5, 1.0, 1.0); + Color debug_navigation_link_connection_disabled_color = Color(0.5, 0.5, 0.5, 1.0); + bool debug_navigation_enable_edge_connections = true; bool debug_navigation_enable_edge_connections_xray = true; bool debug_navigation_enable_edge_lines = true; bool debug_navigation_enable_edge_lines_xray = true; bool debug_navigation_enable_geometry_face_random_color = true; + bool debug_navigation_enable_link_connections = true; + bool debug_navigation_enable_link_connections_xray = true; Ref<StandardMaterial3D> debug_navigation_geometry_edge_material; Ref<StandardMaterial3D> debug_navigation_geometry_face_material; Ref<StandardMaterial3D> debug_navigation_geometry_edge_disabled_material; Ref<StandardMaterial3D> debug_navigation_geometry_face_disabled_material; Ref<StandardMaterial3D> debug_navigation_edge_connections_material; + Ref<StandardMaterial3D> debug_navigation_link_connections_material; + Ref<StandardMaterial3D> debug_navigation_link_connections_disabled_material; + +public: + void set_debug_enabled(bool p_enabled); + bool get_debug_enabled() const; void set_debug_navigation_edge_connection_color(const Color &p_color); Color get_debug_navigation_edge_connection_color() const; @@ -248,6 +295,12 @@ public: void set_debug_navigation_geometry_face_disabled_color(const Color &p_color); Color get_debug_navigation_geometry_face_disabled_color() const; + void set_debug_navigation_link_connection_color(const Color &p_color); + Color get_debug_navigation_link_connection_color() const; + + void set_debug_navigation_link_connection_disabled_color(const Color &p_color); + Color get_debug_navigation_link_connection_disabled_color() const; + void set_debug_navigation_enable_edge_connections(const bool p_value); bool get_debug_navigation_enable_edge_connections() const; @@ -263,11 +316,19 @@ public: void set_debug_navigation_enable_geometry_face_random_color(const bool p_value); bool get_debug_navigation_enable_geometry_face_random_color() const; + void set_debug_navigation_enable_link_connections(const bool p_value); + bool get_debug_navigation_enable_link_connections() const; + + void set_debug_navigation_enable_link_connections_xray(const bool p_value); + bool get_debug_navigation_enable_link_connections_xray() const; + Ref<StandardMaterial3D> get_debug_navigation_geometry_face_material(); Ref<StandardMaterial3D> get_debug_navigation_geometry_edge_material(); Ref<StandardMaterial3D> get_debug_navigation_geometry_face_disabled_material(); Ref<StandardMaterial3D> get_debug_navigation_geometry_edge_disabled_material(); Ref<StandardMaterial3D> get_debug_navigation_edge_connections_material(); + Ref<StandardMaterial3D> get_debug_navigation_link_connections_material(); + Ref<StandardMaterial3D> get_debug_navigation_link_connections_disabled_material(); #endif // DEBUG_ENABLED }; diff --git a/servers/physics_2d/godot_body_direct_state_2d.cpp b/servers/physics_2d/godot_body_direct_state_2d.cpp index cde6e8c991..d413e03be6 100644 --- a/servers/physics_2d/godot_body_direct_state_2d.cpp +++ b/servers/physics_2d/godot_body_direct_state_2d.cpp @@ -138,7 +138,7 @@ void GodotPhysicsDirectBodyState2D::add_constant_torque(real_t p_torque) { } void GodotPhysicsDirectBodyState2D::set_constant_force(const Vector2 &p_force) { - if (!p_force.is_equal_approx(Vector2())) { + if (!p_force.is_zero_approx()) { body->wakeup(); } body->set_constant_force(p_force); diff --git a/servers/physics_2d/godot_physics_server_2d.cpp b/servers/physics_2d/godot_physics_server_2d.cpp index c728dccd4f..cec31bdc31 100644 --- a/servers/physics_2d/godot_physics_server_2d.cpp +++ b/servers/physics_2d/godot_physics_server_2d.cpp @@ -848,7 +848,7 @@ void GodotPhysicsServer2D::body_set_constant_force(RID p_body, const Vector2 &p_ ERR_FAIL_COND(!body); body->set_constant_force(p_force); - if (!p_force.is_equal_approx(Vector2())) { + if (!p_force.is_zero_approx()) { body->wakeup(); } } diff --git a/servers/physics_3d/godot_body_direct_state_3d.cpp b/servers/physics_3d/godot_body_direct_state_3d.cpp index a8c6086e1c..25088d33f3 100644 --- a/servers/physics_3d/godot_body_direct_state_3d.cpp +++ b/servers/physics_3d/godot_body_direct_state_3d.cpp @@ -145,7 +145,7 @@ void GodotPhysicsDirectBodyState3D::add_constant_torque(const Vector3 &p_torque) } void GodotPhysicsDirectBodyState3D::set_constant_force(const Vector3 &p_force) { - if (!p_force.is_equal_approx(Vector3())) { + if (!p_force.is_zero_approx()) { body->wakeup(); } body->set_constant_force(p_force); @@ -156,7 +156,7 @@ Vector3 GodotPhysicsDirectBodyState3D::get_constant_force() const { } void GodotPhysicsDirectBodyState3D::set_constant_torque(const Vector3 &p_torque) { - if (!p_torque.is_equal_approx(Vector3())) { + if (!p_torque.is_zero_approx()) { body->wakeup(); } body->set_constant_torque(p_torque); diff --git a/servers/physics_3d/godot_collision_solver_3d_sat.cpp b/servers/physics_3d/godot_collision_solver_3d_sat.cpp index 20e9300778..56e644b57b 100644 --- a/servers/physics_3d/godot_collision_solver_3d_sat.cpp +++ b/servers/physics_3d/godot_collision_solver_3d_sat.cpp @@ -629,7 +629,7 @@ public: _FORCE_INLINE_ bool test_axis(const Vector3 &p_axis) { Vector3 axis = p_axis; - if (axis.is_equal_approx(Vector3())) { + if (axis.is_zero_approx()) { // strange case, try an upwards separator axis = Vector3(0.0, 1.0, 0.0); } diff --git a/servers/physics_3d/godot_physics_server_3d.cpp b/servers/physics_3d/godot_physics_server_3d.cpp index 9c1535f561..b028c00a31 100644 --- a/servers/physics_3d/godot_physics_server_3d.cpp +++ b/servers/physics_3d/godot_physics_server_3d.cpp @@ -760,7 +760,7 @@ void GodotPhysicsServer3D::body_set_constant_force(RID p_body, const Vector3 &p_ ERR_FAIL_COND(!body); body->set_constant_force(p_force); - if (!p_force.is_equal_approx(Vector3())) { + if (!p_force.is_zero_approx()) { body->wakeup(); } } @@ -776,7 +776,7 @@ void GodotPhysicsServer3D::body_set_constant_torque(RID p_body, const Vector3 &p ERR_FAIL_COND(!body); body->set_constant_torque(p_torque); - if (!p_torque.is_equal_approx(Vector3())) { + if (!p_torque.is_zero_approx()) { body->wakeup(); } } diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp index ca9c9c8fc4..6424915b58 100644 --- a/servers/physics_server_2d.cpp +++ b/servers/physics_server_2d.cpp @@ -148,7 +148,7 @@ PhysicsDirectBodyState2D::PhysicsDirectBodyState2D() {} /////////////////////////////////////////////////////// -Ref<PhysicsRayQueryParameters2D> PhysicsRayQueryParameters2D::create(Vector2 p_from, Vector2 p_to, uint32_t p_mask, const Vector<RID> &p_exclude) { +Ref<PhysicsRayQueryParameters2D> PhysicsRayQueryParameters2D::create(Vector2 p_from, Vector2 p_to, uint32_t p_mask, const TypedArray<RID> &p_exclude) { Ref<PhysicsRayQueryParameters2D> params; params.instantiate(); params->set_from(p_from); @@ -158,25 +158,25 @@ Ref<PhysicsRayQueryParameters2D> PhysicsRayQueryParameters2D::create(Vector2 p_f return params; } -void PhysicsRayQueryParameters2D::set_exclude(const Vector<RID> &p_exclude) { +void PhysicsRayQueryParameters2D::set_exclude(const TypedArray<RID> &p_exclude) { parameters.exclude.clear(); for (int i = 0; i < p_exclude.size(); i++) { parameters.exclude.insert(p_exclude[i]); } } -Vector<RID> PhysicsRayQueryParameters2D::get_exclude() const { - Vector<RID> ret; +TypedArray<RID> PhysicsRayQueryParameters2D::get_exclude() const { + TypedArray<RID> ret; ret.resize(parameters.exclude.size()); int idx = 0; for (const RID &E : parameters.exclude) { - ret.write[idx++] = E; + ret[idx++] = E; } return ret; } void PhysicsRayQueryParameters2D::_bind_methods() { - ClassDB::bind_static_method("PhysicsRayQueryParameters2D", D_METHOD("create", "from", "to", "collision_mask", "exclude"), &PhysicsRayQueryParameters2D::create, DEFVAL(UINT32_MAX), DEFVAL(Vector<RID>())); + ClassDB::bind_static_method("PhysicsRayQueryParameters2D", D_METHOD("create", "from", "to", "collision_mask", "exclude"), &PhysicsRayQueryParameters2D::create, DEFVAL(UINT32_MAX), DEFVAL(TypedArray<RID>())); ClassDB::bind_method(D_METHOD("set_from", "from"), &PhysicsRayQueryParameters2D::set_from); ClassDB::bind_method(D_METHOD("get_from"), &PhysicsRayQueryParameters2D::get_from); @@ -210,19 +210,19 @@ void PhysicsRayQueryParameters2D::_bind_methods() { /////////////////////////////////////////////////////// -void PhysicsPointQueryParameters2D::set_exclude(const Vector<RID> &p_exclude) { +void PhysicsPointQueryParameters2D::set_exclude(const TypedArray<RID> &p_exclude) { parameters.exclude.clear(); for (int i = 0; i < p_exclude.size(); i++) { parameters.exclude.insert(p_exclude[i]); } } -Vector<RID> PhysicsPointQueryParameters2D::get_exclude() const { - Vector<RID> ret; +TypedArray<RID> PhysicsPointQueryParameters2D::get_exclude() const { + TypedArray<RID> ret; ret.resize(parameters.exclude.size()); int idx = 0; for (const RID &E : parameters.exclude) { - ret.write[idx++] = E; + ret[idx++] = E; } return ret; } @@ -269,19 +269,19 @@ void PhysicsShapeQueryParameters2D::set_shape_rid(const RID &p_shape) { } } -void PhysicsShapeQueryParameters2D::set_exclude(const Vector<RID> &p_exclude) { +void PhysicsShapeQueryParameters2D::set_exclude(const TypedArray<RID> &p_exclude) { parameters.exclude.clear(); for (int i = 0; i < p_exclude.size(); i++) { parameters.exclude.insert(p_exclude[i]); } } -Vector<RID> PhysicsShapeQueryParameters2D::get_exclude() const { - Vector<RID> ret; +TypedArray<RID> PhysicsShapeQueryParameters2D::get_exclude() const { + TypedArray<RID> ret; ret.resize(parameters.exclude.size()); int idx = 0; for (const RID &E : parameters.exclude) { - ret.write[idx++] = E; + ret[idx++] = E; } return ret; } @@ -461,21 +461,21 @@ void PhysicsDirectSpaceState2D::_bind_methods() { /////////////////////////////// -Vector<RID> PhysicsTestMotionParameters2D::get_exclude_bodies() const { - Vector<RID> exclude; +TypedArray<RID> PhysicsTestMotionParameters2D::get_exclude_bodies() const { + TypedArray<RID> exclude; exclude.resize(parameters.exclude_bodies.size()); int body_index = 0; for (RID body : parameters.exclude_bodies) { - exclude.write[body_index++] = body; + exclude[body_index++] = body; } return exclude; } -void PhysicsTestMotionParameters2D::set_exclude_bodies(const Vector<RID> &p_exclude) { - for (RID body : p_exclude) { - parameters.exclude_bodies.insert(body); +void PhysicsTestMotionParameters2D::set_exclude_bodies(const TypedArray<RID> &p_exclude) { + for (int i = 0; i < p_exclude.size(); i++) { + parameters.exclude_bodies.insert(p_exclude[i]); } } diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h index 071ff5ffe9..f7c44533bf 100644 --- a/servers/physics_server_2d.h +++ b/servers/physics_server_2d.h @@ -610,7 +610,7 @@ protected: static void _bind_methods(); public: - static Ref<PhysicsRayQueryParameters2D> create(Vector2 p_from, Vector2 p_to, uint32_t p_mask, const Vector<RID> &p_exclude); + static Ref<PhysicsRayQueryParameters2D> create(Vector2 p_from, Vector2 p_to, uint32_t p_mask, const TypedArray<RID> &p_exclude); const PhysicsDirectSpaceState2D::RayParameters &get_parameters() const { return parameters; } void set_from(const Vector2 &p_from) { parameters.from = p_from; } @@ -631,8 +631,8 @@ public: void set_hit_from_inside(bool p_enable) { parameters.hit_from_inside = p_enable; } bool is_hit_from_inside_enabled() const { return parameters.hit_from_inside; } - void set_exclude(const Vector<RID> &p_exclude); - Vector<RID> get_exclude() const; + void set_exclude(const TypedArray<RID> &p_exclude); + TypedArray<RID> get_exclude() const; }; class PhysicsPointQueryParameters2D : public RefCounted { @@ -661,8 +661,8 @@ public: void set_collide_with_areas(bool p_enable) { parameters.collide_with_areas = p_enable; } bool is_collide_with_areas_enabled() const { return parameters.collide_with_areas; } - void set_exclude(const Vector<RID> &p_exclude); - Vector<RID> get_exclude() const; + void set_exclude(const TypedArray<RID> &p_exclude); + TypedArray<RID> get_exclude() const; }; class PhysicsShapeQueryParameters2D : public RefCounted { @@ -702,8 +702,8 @@ public: void set_collide_with_areas(bool p_enable) { parameters.collide_with_areas = p_enable; } bool is_collide_with_areas_enabled() const { return parameters.collide_with_areas; } - void set_exclude(const Vector<RID> &p_exclude); - Vector<RID> get_exclude() const; + void set_exclude(const TypedArray<RID> &p_exclude); + TypedArray<RID> get_exclude() const; }; class PhysicsTestMotionParameters2D : public RefCounted { @@ -729,8 +729,8 @@ public: bool is_collide_separation_ray_enabled() const { return parameters.collide_separation_ray; } void set_collide_separation_ray_enabled(bool p_enabled) { parameters.collide_separation_ray = p_enabled; } - Vector<RID> get_exclude_bodies() const; - void set_exclude_bodies(const Vector<RID> &p_exclude); + TypedArray<RID> get_exclude_bodies() const; + void set_exclude_bodies(const TypedArray<RID> &p_exclude); Array get_exclude_objects() const; void set_exclude_objects(const Array &p_exclude); diff --git a/servers/rendering/dummy/rasterizer_scene_dummy.h b/servers/rendering/dummy/rasterizer_scene_dummy.h index 7dac1f5966..4a2a947b94 100644 --- a/servers/rendering/dummy/rasterizer_scene_dummy.h +++ b/servers/rendering/dummy/rasterizer_scene_dummy.h @@ -197,7 +197,7 @@ public: void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) override {} void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) override {} - TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) override { return TypedArray<Image>(); } + TypedArray<Image> bake_render_uv2(RID p_base, const TypedArray<RID> &p_material_overrides, const Size2i &p_image_size) override { return TypedArray<Image>(); } bool free(RID p_rid) override { if (is_environment(p_rid)) { diff --git a/servers/rendering/dummy/storage/material_storage.h b/servers/rendering/dummy/storage/material_storage.h index e25a2ac3a9..ed8fefc558 100644 --- a/servers/rendering/dummy/storage/material_storage.h +++ b/servers/rendering/dummy/storage/material_storage.h @@ -40,21 +40,21 @@ class MaterialStorage : public RendererMaterialStorage { public: /* GLOBAL SHADER UNIFORM API */ - virtual void global_shader_uniform_add(const StringName &p_name, RS::GlobalShaderUniformType p_type, const Variant &p_value) override {} - virtual void global_shader_uniform_remove(const StringName &p_name) override {} - virtual Vector<StringName> global_shader_uniform_get_list() const override { return Vector<StringName>(); } + virtual void global_shader_parameter_add(const StringName &p_name, RS::GlobalShaderParameterType p_type, const Variant &p_value) override {} + virtual void global_shader_parameter_remove(const StringName &p_name) override {} + virtual Vector<StringName> global_shader_parameter_get_list() const override { return Vector<StringName>(); } - virtual void global_shader_uniform_set(const StringName &p_name, const Variant &p_value) override {} - virtual void global_shader_uniform_set_override(const StringName &p_name, const Variant &p_value) override {} - virtual Variant global_shader_uniform_get(const StringName &p_name) const override { return Variant(); } - virtual RS::GlobalShaderUniformType global_shader_uniform_get_type(const StringName &p_name) const override { return RS::GLOBAL_VAR_TYPE_MAX; } + virtual void global_shader_parameter_set(const StringName &p_name, const Variant &p_value) override {} + virtual void global_shader_parameter_set_override(const StringName &p_name, const Variant &p_value) override {} + virtual Variant global_shader_parameter_get(const StringName &p_name) const override { return Variant(); } + virtual RS::GlobalShaderParameterType global_shader_parameter_get_type(const StringName &p_name) const override { return RS::GLOBAL_VAR_TYPE_MAX; } - virtual void global_shader_uniforms_load_settings(bool p_load_textures = true) override {} - virtual void global_shader_uniforms_clear() override {} + virtual void global_shader_parameters_load_settings(bool p_load_textures = true) override {} + virtual void global_shader_parameters_clear() override {} - virtual int32_t global_shader_uniforms_instance_allocate(RID p_instance) override { return 0; } - virtual void global_shader_uniforms_instance_free(RID p_instance) override {} - virtual void global_shader_uniforms_instance_update(RID p_instance, int p_index, const Variant &p_value) override {} + virtual int32_t global_shader_parameters_instance_allocate(RID p_instance) override { return 0; } + virtual void global_shader_parameters_instance_free(RID p_instance) override {} + virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value) override {} /* SHADER API */ @@ -66,11 +66,11 @@ public: virtual void shader_set_path_hint(RID p_shader, const String &p_code) override {} virtual String shader_get_code(RID p_shader) const override { return ""; } - virtual void shader_get_shader_uniform_list(RID p_shader, List<PropertyInfo> *p_param_list) const override {} + virtual void get_shader_parameter_list(RID p_shader, List<PropertyInfo> *p_param_list) const override {} - virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) override {} - virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const override { return RID(); } - virtual Variant shader_get_param_default(RID p_material, const StringName &p_param) const override { return Variant(); } + virtual void shader_set_default_texture_parameter(RID p_shader, const StringName &p_name, RID p_texture, int p_index) override {} + virtual RID shader_get_default_texture_parameter(RID p_shader, const StringName &p_name, int p_index) const override { return RID(); } + virtual Variant shader_get_parameter_default(RID p_material, const StringName &p_param) const override { return Variant(); } virtual RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const override { return RS::ShaderNativeSourceCode(); }; @@ -89,7 +89,7 @@ public: virtual bool material_is_animated(RID p_material) override { return false; } virtual bool material_casts_shadows(RID p_material) override { return false; } - virtual void material_get_instance_shader_uniforms(RID p_material, List<InstanceShaderParam> *r_parameters) override {} + virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override {} virtual void material_update_dependency(RID p_material, DependencyTracker *p_instance) override {} }; diff --git a/servers/rendering/renderer_rd/environment/fog.cpp b/servers/rendering/renderer_rd/environment/fog.cpp index 91ffa053c9..a41552cd5c 100644 --- a/servers/rendering/renderer_rd/environment/fog.cpp +++ b/servers/rendering/renderer_rd/environment/fog.cpp @@ -361,7 +361,7 @@ void Fog::FogShaderData::set_code(const String &p_code) { valid = true; } -void Fog::FogShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) { +void Fog::FogShaderData::set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) { if (!p_texture.is_valid()) { if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { default_texture_params[p_name].erase(p_index); @@ -430,7 +430,7 @@ void Fog::FogShaderData::get_instance_param_list(List<RendererMaterialStorage::I } } -bool Fog::FogShaderData::is_param_texture(const StringName &p_param) const { +bool Fog::FogShaderData::is_parameter_texture(const StringName &p_param) const { if (!uniforms.has(p_param)) { return false; } diff --git a/servers/rendering/renderer_rd/environment/fog.h b/servers/rendering/renderer_rd/environment/fog.h index 30c8a3f382..9ecd5699dc 100644 --- a/servers/rendering/renderer_rd/environment/fog.h +++ b/servers/rendering/renderer_rd/environment/fog.h @@ -202,10 +202,10 @@ private: virtual void set_path_hint(const String &p_hint); virtual void set_code(const String &p_Code); - virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); + virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index); virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; - virtual bool is_param_texture(const StringName &p_param) const; + virtual bool is_parameter_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; virtual Variant get_default_parameter(const StringName &p_parameter) const; diff --git a/servers/rendering/renderer_rd/environment/sky.cpp b/servers/rendering/renderer_rd/environment/sky.cpp index 3fbe1086a1..65d1d9e705 100644 --- a/servers/rendering/renderer_rd/environment/sky.cpp +++ b/servers/rendering/renderer_rd/environment/sky.cpp @@ -152,7 +152,7 @@ void SkyRD::SkyShaderData::set_code(const String &p_code) { valid = true; } -void SkyRD::SkyShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) { +void SkyRD::SkyShaderData::set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) { if (!p_texture.is_valid()) { if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { default_texture_params[p_name].erase(p_index); @@ -220,7 +220,7 @@ void SkyRD::SkyShaderData::get_instance_param_list(List<RendererMaterialStorage: } } -bool SkyRD::SkyShaderData::is_param_texture(const StringName &p_param) const { +bool SkyRD::SkyShaderData::is_parameter_texture(const StringName &p_param) const { if (!uniforms.has(p_param)) { return false; } @@ -1328,6 +1328,9 @@ void SkyRD::setup(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, const P sky_scene_state.ubo.fog_light_color[2] = fog_color.b * fog_energy; sky_scene_state.ubo.fog_sun_scatter = RendererSceneRenderRD::get_singleton()->environment_get_fog_sun_scatter(p_env); + sky_scene_state.ubo.fog_sky_affect = RendererSceneRenderRD::get_singleton()->environment_get_fog_sky_affect(p_env); + sky_scene_state.ubo.volumetric_fog_sky_affect = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_sky_affect(p_env); + RD::get_singleton()->buffer_update(sky_scene_state.uniform_buffer, 0, sizeof(SkySceneState::UBO), &sky_scene_state.ubo); } diff --git a/servers/rendering/renderer_rd/environment/sky.h b/servers/rendering/renderer_rd/environment/sky.h index 406479d4d3..45c4f9bda7 100644 --- a/servers/rendering/renderer_rd/environment/sky.h +++ b/servers/rendering/renderer_rd/environment/sky.h @@ -130,10 +130,10 @@ private: virtual void set_code(const String &p_Code); virtual void set_path_hint(const String &p_hint); - virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); + virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index); virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; - virtual bool is_param_texture(const StringName &p_param) const; + virtual bool is_parameter_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; virtual Variant get_default_parameter(const StringName &p_parameter) const; @@ -148,20 +148,23 @@ private: public: struct SkySceneState { struct UBO { - uint32_t volumetric_fog_enabled; - float volumetric_fog_inv_length; - float volumetric_fog_detail_spread; - - float fog_aerial_perspective; - - float fog_light_color[3]; - float fog_sun_scatter; - - uint32_t fog_enabled; - float fog_density; - - float z_far; - uint32_t directional_light_count; + uint32_t volumetric_fog_enabled; // 4 - 4 + float volumetric_fog_inv_length; // 4 - 8 + float volumetric_fog_detail_spread; // 4 - 12 + float volumetric_fog_sky_affect; // 4 - 16 + + uint32_t fog_enabled; // 4 - 20 + float fog_sky_affect; // 4 - 24 + float fog_density; // 4 - 28 + float fog_sun_scatter; // 4 - 32 + + float fog_light_color[3]; // 12 - 44 + float fog_aerial_perspective; // 4 - 48 + + float z_far; // 4 - 52 + uint32_t directional_light_count; // 4 - 56 + uint32_t pad1; // 4 - 60 + uint32_t pad2; // 4 - 64 }; UBO ubo; diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp index 0911ee595f..75ccf1add5 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp @@ -375,7 +375,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { valid = true; } -void SceneShaderForwardClustered::ShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) { +void SceneShaderForwardClustered::ShaderData::set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) { if (!p_texture.is_valid()) { if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { default_texture_params[p_name].erase(p_index); @@ -448,7 +448,7 @@ void SceneShaderForwardClustered::ShaderData::get_instance_param_list(List<Rende } } -bool SceneShaderForwardClustered::ShaderData::is_param_texture(const StringName &p_param) const { +bool SceneShaderForwardClustered::ShaderData::is_parameter_texture(const StringName &p_param) const { if (!uniforms.has(p_param)) { return false; } diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h index d6b526fa4a..c2f56eb164 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h @@ -182,11 +182,11 @@ public: virtual void set_code(const String &p_Code); virtual void set_path_hint(const String &p_path); - virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); + virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index); virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; - virtual bool is_param_texture(const StringName &p_param) const; + virtual bool is_parameter_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; virtual Variant get_default_parameter(const StringName &p_parameter) const; diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp index 85c9e1db2a..383ed9247d 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp @@ -331,7 +331,7 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) { valid = true; } -void SceneShaderForwardMobile::ShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) { +void SceneShaderForwardMobile::ShaderData::set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) { if (!p_texture.is_valid()) { if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { default_texture_params[p_name].erase(p_index); @@ -403,7 +403,7 @@ void SceneShaderForwardMobile::ShaderData::get_instance_param_list(List<Renderer } } -bool SceneShaderForwardMobile::ShaderData::is_param_texture(const StringName &p_param) const { +bool SceneShaderForwardMobile::ShaderData::is_parameter_texture(const StringName &p_param) const { if (!uniforms.has(p_param)) { return false; } diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h index e208334547..21270d7c62 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h @@ -141,11 +141,11 @@ public: virtual void set_code(const String &p_Code); virtual void set_path_hint(const String &p_path); - virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); + virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index); virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; - virtual bool is_param_texture(const StringName &p_param) const; + virtual bool is_parameter_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; virtual Variant get_default_parameter(const StringName &p_parameter) const; diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 7102f1f0ff..ab3e3ebe51 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -2192,7 +2192,7 @@ void RendererCanvasRenderRD::CanvasShaderData::set_code(const String &p_code) { valid = true; } -void RendererCanvasRenderRD::CanvasShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) { +void RendererCanvasRenderRD::CanvasShaderData::set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) { if (!p_texture.is_valid()) { if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { default_texture_params[p_name].erase(p_index); @@ -2264,7 +2264,7 @@ void RendererCanvasRenderRD::CanvasShaderData::get_instance_param_list(List<Rend } } -bool RendererCanvasRenderRD::CanvasShaderData::is_param_texture(const StringName &p_param) const { +bool RendererCanvasRenderRD::CanvasShaderData::is_parameter_texture(const StringName &p_param) const { if (!uniforms.has(p_param)) { return false; } diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h index 54077a5b9a..67db56d913 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h @@ -182,11 +182,11 @@ class RendererCanvasRenderRD : public RendererCanvasRender { virtual void set_code(const String &p_Code); virtual void set_path_hint(const String &p_path); - virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); + virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index); virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; - virtual bool is_param_texture(const StringName &p_param) const; + virtual bool is_parameter_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; virtual Variant get_default_parameter(const StringName &p_parameter) const; diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index cb7c643dfb..78c83d1fb4 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -3570,7 +3570,7 @@ float RendererSceneRenderRD::screen_space_roughness_limiter_get_limit() const { return screen_space_roughness_limiter_limit; } -TypedArray<Image> RendererSceneRenderRD::bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) { +TypedArray<Image> RendererSceneRenderRD::bake_render_uv2(RID p_base, const TypedArray<RID> &p_material_overrides, const Size2i &p_image_size) { RD::TextureFormat tf; tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; tf.width = p_image_size.width; // Always 64x64 diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index 396faf8108..76d2bc68fe 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -1046,7 +1046,7 @@ public: int get_roughness_layers() const; bool is_using_radiance_cubemap_array() const; - virtual TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) override; + virtual TypedArray<Image> bake_render_uv2(RID p_base, const TypedArray<RID> &p_material_overrides, const Size2i &p_image_size) override; virtual bool free(RID p_rid) override; diff --git a/servers/rendering/renderer_rd/shaders/environment/sky.glsl b/servers/rendering/renderer_rd/shaders/environment/sky.glsl index 7a0b2af3ce..0eb0f5f8fd 100644 --- a/servers/rendering/renderer_rd/shaders/environment/sky.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/sky.glsl @@ -83,20 +83,23 @@ layout(set = 0, binding = 1, std430) restrict readonly buffer GlobalShaderUnifor global_shader_uniforms; layout(set = 0, binding = 2, std140) uniform SceneData { - bool volumetric_fog_enabled; - float volumetric_fog_inv_length; - float volumetric_fog_detail_spread; - - float fog_aerial_perspective; - - vec3 fog_light_color; - float fog_sun_scatter; - - bool fog_enabled; - float fog_density; - - float z_far; - uint directional_light_count; + bool volumetric_fog_enabled; // 4 - 4 + float volumetric_fog_inv_length; // 4 - 8 + float volumetric_fog_detail_spread; // 4 - 12 + float volumetric_fog_sky_affect; // 4 - 16 + + bool fog_enabled; // 4 - 20 + float fog_sky_affect; // 4 - 24 + float fog_density; // 4 - 28 + float fog_sun_scatter; // 4 - 32 + + vec3 fog_light_color; // 12 - 44 + float fog_aerial_perspective; // 4 - 48 + + float z_far; // 4 - 52 + uint directional_light_count; // 4 - 56 + uint pad1; // 4 - 60 + uint pad2; // 4 - 64 } scene_data; @@ -169,9 +172,7 @@ vec4 fog_process(vec3 view, vec3 sky_color) { } } - float fog_amount = clamp(1.0 - exp(-scene_data.z_far * scene_data.fog_density), 0.0, 1.0); - - return vec4(fog_color, fog_amount); + return vec4(fog_color, 1.0); } void main() { @@ -228,12 +229,12 @@ void main() { // Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky. if (scene_data.fog_enabled) { vec4 fog = fog_process(cube_normal, frag_color.rgb); - frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a); + frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a * scene_data.fog_sky_affect); } if (scene_data.volumetric_fog_enabled) { vec4 fog = volumetric_fog_process(uv); - frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a); + frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a * scene_data.volumetric_fog_sky_affect); } if (custom_fog.a > 0.0) { diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp index fa8406e7a1..b36a028f04 100644 --- a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp @@ -954,7 +954,7 @@ void MaterialStorage::MaterialData::update_uniform_buffer(const HashMap<StringNa if (gv) { index = gv->buffer_index; } else { - WARN_PRINT("Shader uses global uniform '" + E.key + "', but it was removed at some point. Material will not display correctly."); + WARN_PRINT("Shader uses global parameter '" + E.key + "', but it was removed at some point. Material will not display correctly."); } uint32_t offset = p_uniform_offsets[E.value.order]; @@ -1070,7 +1070,7 @@ void MaterialStorage::MaterialData::update_textures(const HashMap<StringName, Va GlobalShaderUniforms::Variable *v = material_storage->global_shader_uniforms.variables.getptr(uniform_name); if (v) { if (v->buffer_index >= 0) { - WARN_PRINT("Shader uses global uniform texture '" + String(uniform_name) + "', but it changed type and is no longer a texture!."); + WARN_PRINT("Shader uses global parameter texture '" + String(uniform_name) + "', but it changed type and is no longer a texture!."); } else { HashMap<StringName, uint64_t>::Iterator E = used_global_textures.find(uniform_name); @@ -1085,7 +1085,7 @@ void MaterialStorage::MaterialData::update_textures(const HashMap<StringName, Va } } else { - WARN_PRINT("Shader uses global uniform texture '" + String(uniform_name) + "', but it was removed at some point. Material will not display correctly."); + WARN_PRINT("Shader uses global parameter texture '" + String(uniform_name) + "', but it was removed at some point. Material will not display correctly."); } } else { HashMap<StringName, Variant>::ConstIterator V = p_parameters.find(uniform_name); @@ -1652,7 +1652,7 @@ int32_t MaterialStorage::_global_shader_uniform_allocate(uint32_t p_elements) { return -1; } -void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS::GlobalShaderUniformType p_type, const Variant &p_value) { +void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS::GlobalShaderParameterType p_type, const Variant &p_value) { switch (p_type) { case RS::GLOBAL_VAR_TYPE_BOOL: { GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; @@ -1945,7 +1945,7 @@ void MaterialStorage::_global_shader_uniform_mark_buffer_dirty(int32_t p_index, } } -void MaterialStorage::global_shader_uniform_add(const StringName &p_name, RS::GlobalShaderUniformType p_type, const Variant &p_value) { +void MaterialStorage::global_shader_parameter_add(const StringName &p_name, RS::GlobalShaderParameterType p_type, const Variant &p_value) { ERR_FAIL_COND(global_shader_uniforms.variables.has(p_name)); GlobalShaderUniforms::Variable gv; gv.type = p_type; @@ -1983,7 +1983,7 @@ void MaterialStorage::global_shader_uniform_add(const StringName &p_name, RS::Gl global_shader_uniforms.variables[p_name] = gv; } -void MaterialStorage::global_shader_uniform_remove(const StringName &p_name) { +void MaterialStorage::global_shader_parameter_remove(const StringName &p_name) { if (!global_shader_uniforms.variables.has(p_name)) { return; } @@ -1999,7 +1999,7 @@ void MaterialStorage::global_shader_uniform_remove(const StringName &p_name) { global_shader_uniforms.variables.erase(p_name); } -Vector<StringName> MaterialStorage::global_shader_uniform_get_list() const { +Vector<StringName> MaterialStorage::global_shader_parameter_get_list() const { if (!Engine::get_singleton()->is_editor_hint()) { ERR_FAIL_V_MSG(Vector<StringName>(), "This function should never be used outside the editor, it can severely damage performance."); } @@ -2012,7 +2012,7 @@ Vector<StringName> MaterialStorage::global_shader_uniform_get_list() const { return names; } -void MaterialStorage::global_shader_uniform_set(const StringName &p_name, const Variant &p_value) { +void MaterialStorage::global_shader_parameter_set(const StringName &p_name, const Variant &p_value) { ERR_FAIL_COND(!global_shader_uniforms.variables.has(p_name)); GlobalShaderUniforms::Variable &gv = global_shader_uniforms.variables[p_name]; gv.value = p_value; @@ -2033,7 +2033,7 @@ void MaterialStorage::global_shader_uniform_set(const StringName &p_name, const } } -void MaterialStorage::global_shader_uniform_set_override(const StringName &p_name, const Variant &p_value) { +void MaterialStorage::global_shader_parameter_set_override(const StringName &p_name, const Variant &p_value) { if (!global_shader_uniforms.variables.has(p_name)) { return; //variable may not exist } @@ -2064,7 +2064,7 @@ void MaterialStorage::global_shader_uniform_set_override(const StringName &p_nam } } -Variant MaterialStorage::global_shader_uniform_get(const StringName &p_name) const { +Variant MaterialStorage::global_shader_parameter_get(const StringName &p_name) const { if (!Engine::get_singleton()->is_editor_hint()) { ERR_FAIL_V_MSG(Variant(), "This function should never be used outside the editor, it can severely damage performance."); } @@ -2076,7 +2076,7 @@ Variant MaterialStorage::global_shader_uniform_get(const StringName &p_name) con return global_shader_uniforms.variables[p_name].value; } -RS::GlobalShaderUniformType MaterialStorage::global_shader_uniform_get_type_internal(const StringName &p_name) const { +RS::GlobalShaderParameterType MaterialStorage::global_shader_parameter_get_type_internal(const StringName &p_name) const { if (!global_shader_uniforms.variables.has(p_name)) { return RS::GLOBAL_VAR_TYPE_MAX; } @@ -2084,15 +2084,15 @@ RS::GlobalShaderUniformType MaterialStorage::global_shader_uniform_get_type_inte return global_shader_uniforms.variables[p_name].type; } -RS::GlobalShaderUniformType MaterialStorage::global_shader_uniform_get_type(const StringName &p_name) const { +RS::GlobalShaderParameterType MaterialStorage::global_shader_parameter_get_type(const StringName &p_name) const { if (!Engine::get_singleton()->is_editor_hint()) { ERR_FAIL_V_MSG(RS::GLOBAL_VAR_TYPE_MAX, "This function should never be used outside the editor, it can severely damage performance."); } - return global_shader_uniform_get_type_internal(p_name); + return global_shader_parameter_get_type_internal(p_name); } -void MaterialStorage::global_shader_uniforms_load_settings(bool p_load_textures) { +void MaterialStorage::global_shader_parameters_load_settings(bool p_load_textures) { List<PropertyInfo> settings; ProjectSettings::get_singleton()->get_property_list(&settings); @@ -2137,11 +2137,11 @@ void MaterialStorage::global_shader_uniforms_load_settings(bool p_load_textures) "samplerCube", }; - RS::GlobalShaderUniformType gvtype = RS::GLOBAL_VAR_TYPE_MAX; + RS::GlobalShaderParameterType gvtype = RS::GLOBAL_VAR_TYPE_MAX; for (int i = 0; i < RS::GLOBAL_VAR_TYPE_MAX; i++) { if (global_var_type_names[i] == type) { - gvtype = RS::GlobalShaderUniformType(i); + gvtype = RS::GlobalShaderParameterType(i); break; } } @@ -2165,15 +2165,15 @@ void MaterialStorage::global_shader_uniforms_load_settings(bool p_load_textures) if (global_shader_uniforms.variables.has(name)) { //has it, update it - global_shader_uniform_set(name, value); + global_shader_parameter_set(name, value); } else { - global_shader_uniform_add(name, gvtype, value); + global_shader_parameter_add(name, gvtype, value); } } } } -void MaterialStorage::global_shader_uniforms_clear() { +void MaterialStorage::global_shader_parameters_clear() { global_shader_uniforms.variables.clear(); //not right but for now enough } @@ -2181,7 +2181,7 @@ RID MaterialStorage::global_shader_uniforms_get_storage_buffer() const { return global_shader_uniforms.buffer; } -int32_t MaterialStorage::global_shader_uniforms_instance_allocate(RID p_instance) { +int32_t MaterialStorage::global_shader_parameters_instance_allocate(RID p_instance) { ERR_FAIL_COND_V(global_shader_uniforms.instance_buffer_pos.has(p_instance), -1); int32_t pos = _global_shader_uniform_allocate(ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES); global_shader_uniforms.instance_buffer_pos[p_instance] = pos; //save anyway @@ -2190,7 +2190,7 @@ int32_t MaterialStorage::global_shader_uniforms_instance_allocate(RID p_instance return pos; } -void MaterialStorage::global_shader_uniforms_instance_free(RID p_instance) { +void MaterialStorage::global_shader_parameters_instance_free(RID p_instance) { ERR_FAIL_COND(!global_shader_uniforms.instance_buffer_pos.has(p_instance)); int32_t pos = global_shader_uniforms.instance_buffer_pos[p_instance]; if (pos >= 0) { @@ -2199,7 +2199,7 @@ void MaterialStorage::global_shader_uniforms_instance_free(RID p_instance) { global_shader_uniforms.instance_buffer_pos.erase(p_instance); } -void MaterialStorage::global_shader_uniforms_instance_update(RID p_instance, int p_index, const Variant &p_value) { +void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value) { if (!global_shader_uniforms.instance_buffer_pos.has(p_instance)) { return; //just not allocated, ignore } @@ -2384,7 +2384,7 @@ void MaterialStorage::shader_set_code(RID p_shader, const String &p_code) { if (shader->data) { for (const KeyValue<StringName, HashMap<int, RID>> &E : shader->default_texture_parameter) { for (const KeyValue<int, RID> &E2 : E.value) { - shader->data->set_default_texture_param(E.key, E2.value, E2.key); + shader->data->set_default_texture_parameter(E.key, E2.value, E2.key); } } } @@ -2418,7 +2418,7 @@ String MaterialStorage::shader_get_code(RID p_shader) const { return shader->code; } -void MaterialStorage::shader_get_shader_uniform_list(RID p_shader, List<PropertyInfo> *p_param_list) const { +void MaterialStorage::get_shader_parameter_list(RID p_shader, List<PropertyInfo> *p_param_list) const { Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND(!shader); if (shader->data) { @@ -2426,7 +2426,7 @@ void MaterialStorage::shader_get_shader_uniform_list(RID p_shader, List<Property } } -void MaterialStorage::shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) { +void MaterialStorage::shader_set_default_texture_parameter(RID p_shader, const StringName &p_name, RID p_texture, int p_index) { Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND(!shader); @@ -2445,7 +2445,7 @@ void MaterialStorage::shader_set_default_texture_param(RID p_shader, const Strin } } if (shader->data) { - shader->data->set_default_texture_param(p_name, p_texture, p_index); + shader->data->set_default_texture_parameter(p_name, p_texture, p_index); } for (Material *E : shader->owners) { Material *material = E; @@ -2453,7 +2453,7 @@ void MaterialStorage::shader_set_default_texture_param(RID p_shader, const Strin } } -RID MaterialStorage::shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const { +RID MaterialStorage::shader_get_default_texture_parameter(RID p_shader, const StringName &p_name, int p_index) const { Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND_V(!shader, RID()); if (shader->default_texture_parameter.has(p_name) && shader->default_texture_parameter[p_name].has(p_index)) { @@ -2463,7 +2463,7 @@ RID MaterialStorage::shader_get_default_texture_param(RID p_shader, const String return RID(); } -Variant MaterialStorage::shader_get_param_default(RID p_shader, const StringName &p_param) const { +Variant MaterialStorage::shader_get_parameter_default(RID p_shader, const StringName &p_param) const { Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND_V(!shader, Variant()); if (shader->data) { @@ -2616,7 +2616,7 @@ void MaterialStorage::material_set_param(RID p_material, const StringName &p_par } if (material->shader && material->shader->data) { //shader is valid - bool is_texture = material->shader->data->is_param_texture(p_param); + bool is_texture = material->shader->data->is_parameter_texture(p_param); _material_queue_update(material, !is_texture, is_texture); } else { _material_queue_update(material, true, true); @@ -2684,14 +2684,14 @@ bool MaterialStorage::material_casts_shadows(RID p_material) { return true; //by default everything casts shadows } -void MaterialStorage::material_get_instance_shader_uniforms(RID p_material, List<InstanceShaderParam> *r_parameters) { +void MaterialStorage::material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) { Material *material = material_owner.get_or_null(p_material); ERR_FAIL_COND(!material); if (material->shader && material->shader->data) { material->shader->data->get_instance_param_list(r_parameters); if (material->next_pass.is_valid()) { - material_get_instance_shader_uniforms(material->next_pass, r_parameters); + material_get_instance_shader_parameters(material->next_pass, r_parameters); } } } diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.h b/servers/rendering/renderer_rd/storage_rd/material_storage.h index dbf7a92e23..db2e4cfa2a 100644 --- a/servers/rendering/renderer_rd/storage_rd/material_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/material_storage.h @@ -56,11 +56,11 @@ public: struct ShaderData { virtual void set_code(const String &p_Code) = 0; virtual void set_path_hint(const String &p_hint) = 0; - virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) = 0; + virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) = 0; virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const = 0; virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const = 0; - virtual bool is_param_texture(const StringName &p_param) const = 0; + virtual bool is_parameter_texture(const StringName &p_param) const = 0; virtual bool is_animated() const = 0; virtual bool casts_shadows() const = 0; virtual Variant get_default_parameter(const StringName &p_parameter) const = 0; @@ -119,7 +119,7 @@ private: struct Variable { HashSet<RID> texture_materials; // materials using this - RS::GlobalShaderUniformType type; + RS::GlobalShaderParameterType type; Variant value; Variant override; int32_t buffer_index; //for vectors @@ -171,7 +171,7 @@ private: } global_shader_uniforms; int32_t _global_shader_uniform_allocate(uint32_t p_elements); - void _global_shader_uniform_store_in_buffer(int32_t p_index, RS::GlobalShaderUniformType p_type, const Variant &p_value); + void _global_shader_uniform_store_in_buffer(int32_t p_index, RS::GlobalShaderParameterType p_type, const Variant &p_value); void _global_shader_uniform_mark_buffer_dirty(int32_t p_index, int32_t p_elements); /* SHADER API */ @@ -332,22 +332,22 @@ public: void _update_global_shader_uniforms(); - virtual void global_shader_uniform_add(const StringName &p_name, RS::GlobalShaderUniformType p_type, const Variant &p_value) override; - virtual void global_shader_uniform_remove(const StringName &p_name) override; - virtual Vector<StringName> global_shader_uniform_get_list() const override; + virtual void global_shader_parameter_add(const StringName &p_name, RS::GlobalShaderParameterType p_type, const Variant &p_value) override; + virtual void global_shader_parameter_remove(const StringName &p_name) override; + virtual Vector<StringName> global_shader_parameter_get_list() const override; - virtual void global_shader_uniform_set(const StringName &p_name, const Variant &p_value) override; - virtual void global_shader_uniform_set_override(const StringName &p_name, const Variant &p_value) override; - virtual Variant global_shader_uniform_get(const StringName &p_name) const override; - virtual RS::GlobalShaderUniformType global_shader_uniform_get_type(const StringName &p_name) const override; - RS::GlobalShaderUniformType global_shader_uniform_get_type_internal(const StringName &p_name) const; + virtual void global_shader_parameter_set(const StringName &p_name, const Variant &p_value) override; + virtual void global_shader_parameter_set_override(const StringName &p_name, const Variant &p_value) override; + virtual Variant global_shader_parameter_get(const StringName &p_name) const override; + virtual RS::GlobalShaderParameterType global_shader_parameter_get_type(const StringName &p_name) const override; + RS::GlobalShaderParameterType global_shader_parameter_get_type_internal(const StringName &p_name) const; - virtual void global_shader_uniforms_load_settings(bool p_load_textures = true) override; - virtual void global_shader_uniforms_clear() override; + virtual void global_shader_parameters_load_settings(bool p_load_textures = true) override; + virtual void global_shader_parameters_clear() override; - virtual int32_t global_shader_uniforms_instance_allocate(RID p_instance) override; - virtual void global_shader_uniforms_instance_free(RID p_instance) override; - virtual void global_shader_uniforms_instance_update(RID p_instance, int p_index, const Variant &p_value) override; + virtual int32_t global_shader_parameters_instance_allocate(RID p_instance) override; + virtual void global_shader_parameters_instance_free(RID p_instance) override; + virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value) override; RID global_shader_uniforms_get_storage_buffer() const; @@ -362,11 +362,11 @@ public: virtual void shader_set_code(RID p_shader, const String &p_code) override; virtual void shader_set_path_hint(RID p_shader, const String &p_path) override; virtual String shader_get_code(RID p_shader) const override; - virtual void shader_get_shader_uniform_list(RID p_shader, List<PropertyInfo> *p_param_list) const override; + virtual void get_shader_parameter_list(RID p_shader, List<PropertyInfo> *p_param_list) const override; - virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) override; - virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const override; - virtual Variant shader_get_param_default(RID p_shader, const StringName &p_param) const override; + virtual void shader_set_default_texture_parameter(RID p_shader, const StringName &p_name, RID p_texture, int p_index) override; + virtual RID shader_get_default_texture_parameter(RID p_shader, const StringName &p_name, int p_index) const override; + virtual Variant shader_get_parameter_default(RID p_shader, const StringName &p_param) const override; void shader_set_data_request_function(ShaderType p_shader_type, ShaderDataRequestFunction p_function); virtual RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const override; @@ -394,7 +394,7 @@ public: virtual bool material_is_animated(RID p_material) override; virtual bool material_casts_shadows(RID p_material) override; - virtual void material_get_instance_shader_uniforms(RID p_material, List<InstanceShaderParam> *r_parameters) override; + virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override; virtual void material_update_dependency(RID p_material, DependencyTracker *p_instance) override; diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp index 022b027644..424d2d3c7a 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp @@ -1586,7 +1586,7 @@ void ParticlesStorage::ParticlesShaderData::set_code(const String &p_code) { valid = true; } -void ParticlesStorage::ParticlesShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) { +void ParticlesStorage::ParticlesShaderData::set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) { if (!p_texture.is_valid()) { if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { default_texture_params[p_name].erase(p_index); @@ -1655,7 +1655,7 @@ void ParticlesStorage::ParticlesShaderData::get_instance_param_list(List<Rendere } } -bool ParticlesStorage::ParticlesShaderData::is_param_texture(const StringName &p_param) const { +bool ParticlesStorage::ParticlesShaderData::is_parameter_texture(const StringName &p_param) const { if (!uniforms.has(p_param)) { return false; } diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.h b/servers/rendering/renderer_rd/storage_rd/particles_storage.h index 299fdc6ec8..af29f5022b 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.h @@ -336,10 +336,10 @@ private: virtual void set_code(const String &p_Code); virtual void set_path_hint(const String &p_hint); - virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); + virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index); virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; - virtual bool is_param_texture(const StringName &p_param) const; + virtual bool is_parameter_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; virtual Variant get_default_parameter(const StringName &p_parameter) const; diff --git a/servers/rendering/renderer_scene.h b/servers/rendering/renderer_scene.h index 807fc09498..29c65fcffb 100644 --- a/servers/rendering/renderer_scene.h +++ b/servers/rendering/renderer_scene.h @@ -101,10 +101,10 @@ public: virtual void instance_geometry_set_visibility_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin, RS::VisibilityRangeFadeMode p_fade_mode) = 0; virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index) = 0; virtual void instance_geometry_set_lod_bias(RID p_instance, float p_lod_bias) = 0; - virtual void instance_geometry_set_shader_uniform(RID p_instance, const StringName &p_parameter, const Variant &p_value) = 0; - virtual void instance_geometry_get_shader_uniform_list(RID p_instance, List<PropertyInfo> *p_parameters) const = 0; - virtual Variant instance_geometry_get_shader_uniform(RID p_instance, const StringName &p_parameter) const = 0; - virtual Variant instance_geometry_get_shader_uniform_default_value(RID p_instance, const StringName &p_parameter) const = 0; + virtual void instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value) = 0; + virtual void instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const = 0; + virtual Variant instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const = 0; + virtual Variant instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const = 0; virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = true) = 0; @@ -155,7 +155,7 @@ public: virtual float environment_get_white(RID p_env) const = 0; // Fog - virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) = 0; + virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective, float p_sky_affect) = 0; virtual bool environment_get_fog_enabled(RID p_env) const = 0; virtual Color environment_get_fog_light_color(RID p_env) const = 0; @@ -165,9 +165,10 @@ public: virtual float environment_get_fog_height(RID p_env) const = 0; virtual float environment_get_fog_height_density(RID p_env) const = 0; virtual float environment_get_fog_aerial_perspective(RID p_env) const = 0; + virtual float environment_get_fog_sky_affect(RID p_env) const = 0; // Volumetric Fog - virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject) = 0; + virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject, float p_sky_affect) = 0; virtual bool environment_get_volumetric_fog_enabled(RID p_env) const = 0; virtual float environment_get_volumetric_fog_density(RID p_env) const = 0; @@ -178,6 +179,7 @@ public: virtual float environment_get_volumetric_fog_length(RID p_env) const = 0; virtual float environment_get_volumetric_fog_detail_spread(RID p_env) const = 0; virtual float environment_get_volumetric_fog_gi_inject(RID p_env) const = 0; + virtual float environment_get_volumetric_fog_sky_affect(RID p_env) const = 0; virtual bool environment_get_volumetric_fog_temporal_reprojection(RID p_env) const = 0; virtual float environment_get_volumetric_fog_temporal_reprojection_amount(RID p_env) const = 0; virtual float environment_get_volumetric_fog_ambient_inject(RID p_env) const = 0; @@ -294,7 +296,7 @@ public: virtual void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) = 0; - virtual TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) = 0; + virtual TypedArray<Image> bake_render_uv2(RID p_base, const TypedArray<RID> &p_material_overrides, const Size2i &p_image_size) = 0; virtual void voxel_gi_set_quality(RS::VoxelGIQuality) = 0; virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) = 0; diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index c7df8ebadb..ffd1b421db 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -1436,7 +1436,7 @@ void RendererSceneCull::instance_geometry_set_lod_bias(RID p_instance, float p_l } } -void RendererSceneCull::instance_geometry_set_shader_uniform(RID p_instance, const StringName &p_parameter, const Variant &p_value) { +void RendererSceneCull::instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value) { Instance *instance = instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!instance); @@ -1454,12 +1454,12 @@ void RendererSceneCull::instance_geometry_set_shader_uniform(RID p_instance, con E->value.value = p_value; if (E->value.index >= 0 && instance->instance_allocated_shader_uniforms) { //update directly - RSG::material_storage->global_shader_uniforms_instance_update(p_instance, E->value.index, p_value); + RSG::material_storage->global_shader_parameters_instance_update(p_instance, E->value.index, p_value); } } } -Variant RendererSceneCull::instance_geometry_get_shader_uniform(RID p_instance, const StringName &p_parameter) const { +Variant RendererSceneCull::instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const { const Instance *instance = const_cast<RendererSceneCull *>(this)->instance_owner.get_or_null(p_instance); ERR_FAIL_COND_V(!instance, Variant()); @@ -1469,7 +1469,7 @@ Variant RendererSceneCull::instance_geometry_get_shader_uniform(RID p_instance, return Variant(); } -Variant RendererSceneCull::instance_geometry_get_shader_uniform_default_value(RID p_instance, const StringName &p_parameter) const { +Variant RendererSceneCull::instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const { const Instance *instance = const_cast<RendererSceneCull *>(this)->instance_owner.get_or_null(p_instance); ERR_FAIL_COND_V(!instance, Variant()); @@ -1479,7 +1479,7 @@ Variant RendererSceneCull::instance_geometry_get_shader_uniform_default_value(RI return Variant(); } -void RendererSceneCull::instance_geometry_get_shader_uniform_list(RID p_instance, List<PropertyInfo> *p_parameters) const { +void RendererSceneCull::instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const { const Instance *instance = const_cast<RendererSceneCull *>(this)->instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!instance); @@ -3676,7 +3676,7 @@ void RendererSceneCull::render_particle_colliders() { void RendererSceneCull::_update_instance_shader_uniforms_from_material(HashMap<StringName, Instance::InstanceShaderParameter> &isparams, const HashMap<StringName, Instance::InstanceShaderParameter> &existing_isparams, RID p_material) { List<RendererMaterialStorage::InstanceShaderParam> plist; - RSG::material_storage->material_get_instance_shader_uniforms(p_material, &plist); + RSG::material_storage->material_get_instance_shader_parameters(p_material, &plist); for (const RendererMaterialStorage::InstanceShaderParam &E : plist) { StringName name = E.info.name; if (isparams.has(name)) { @@ -3882,17 +3882,17 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { if (p_instance->instance_allocated_shader_uniforms != (p_instance->instance_shader_uniforms.size() > 0)) { p_instance->instance_allocated_shader_uniforms = (p_instance->instance_shader_uniforms.size() > 0); if (p_instance->instance_allocated_shader_uniforms) { - p_instance->instance_allocated_shader_uniforms_offset = RSG::material_storage->global_shader_uniforms_instance_allocate(p_instance->self); + p_instance->instance_allocated_shader_uniforms_offset = RSG::material_storage->global_shader_parameters_instance_allocate(p_instance->self); ERR_FAIL_NULL(geom->geometry_instance); geom->geometry_instance->set_instance_shader_uniforms_offset(p_instance->instance_allocated_shader_uniforms_offset); for (const KeyValue<StringName, Instance::InstanceShaderParameter> &E : p_instance->instance_shader_uniforms) { if (E.value.value.get_type() != Variant::NIL) { - RSG::material_storage->global_shader_uniforms_instance_update(p_instance->self, E.value.index, E.value.value); + RSG::material_storage->global_shader_parameters_instance_update(p_instance->self, E.value.index, E.value.value); } } } else { - RSG::material_storage->global_shader_uniforms_instance_free(p_instance->self); + RSG::material_storage->global_shader_parameters_instance_free(p_instance->self); p_instance->instance_allocated_shader_uniforms_offset = -1; ERR_FAIL_NULL(geom->geometry_instance); geom->geometry_instance->set_instance_shader_uniforms_offset(-1); @@ -3990,7 +3990,7 @@ bool RendererSceneCull::free(RID p_rid) { if (instance->instance_allocated_shader_uniforms) { //free the used shader parameters - RSG::material_storage->global_shader_uniforms_instance_free(instance->self); + RSG::material_storage->global_shader_parameters_instance_free(instance->self); } update_dirty_instances(); //in case something changed this @@ -4002,7 +4002,7 @@ bool RendererSceneCull::free(RID p_rid) { return true; } -TypedArray<Image> RendererSceneCull::bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) { +TypedArray<Image> RendererSceneCull::bake_render_uv2(RID p_base, const TypedArray<RID> &p_material_overrides, const Size2i &p_image_size) { return scene_render->bake_render_uv2(p_base, p_material_overrides, p_image_size); } diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h index 871b7a68d2..c799553f87 100644 --- a/servers/rendering/renderer_scene_cull.h +++ b/servers/rendering/renderer_scene_cull.h @@ -970,10 +970,10 @@ public: void _update_instance_shader_uniforms_from_material(HashMap<StringName, Instance::InstanceShaderParameter> &isparams, const HashMap<StringName, Instance::InstanceShaderParameter> &existing_isparams, RID p_material); - virtual void instance_geometry_set_shader_uniform(RID p_instance, const StringName &p_parameter, const Variant &p_value); - virtual void instance_geometry_get_shader_uniform_list(RID p_instance, List<PropertyInfo> *p_parameters) const; - virtual Variant instance_geometry_get_shader_uniform(RID p_instance, const StringName &p_parameter) const; - virtual Variant instance_geometry_get_shader_uniform_default_value(RID p_instance, const StringName &p_parameter) const; + virtual void instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value); + virtual void instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const; + virtual Variant instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const; + virtual Variant instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const; _FORCE_INLINE_ void _update_instance(Instance *p_instance); _FORCE_INLINE_ void _update_instance_aabb(Instance *p_instance); @@ -1064,7 +1064,7 @@ public: void render_particle_colliders(); virtual void render_probes(); - TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size); + TypedArray<Image> bake_render_uv2(RID p_base, const TypedArray<RID> &p_material_overrides, const Size2i &p_image_size); //pass to scene render @@ -1125,13 +1125,14 @@ public: PASS1RC(float, environment_get_white, RID) // Fog - PASS9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float) + PASS10(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float, float) PASS1RC(bool, environment_get_fog_enabled, RID) PASS1RC(Color, environment_get_fog_light_color, RID) PASS1RC(float, environment_get_fog_light_energy, RID) PASS1RC(float, environment_get_fog_sun_scatter, RID) PASS1RC(float, environment_get_fog_density, RID) + PASS1RC(float, environment_get_fog_sky_affect, RID) PASS1RC(float, environment_get_fog_height, RID) PASS1RC(float, environment_get_fog_height_density, RID) PASS1RC(float, environment_get_fog_aerial_perspective, RID) @@ -1140,7 +1141,7 @@ public: PASS1(environment_set_volumetric_fog_filter_active, bool) // Volumentric Fog - PASS13(environment_set_volumetric_fog, RID, bool, float, const Color &, const Color &, float, float, float, float, float, bool, float, float) + PASS14(environment_set_volumetric_fog, RID, bool, float, const Color &, const Color &, float, float, float, float, float, bool, float, float, float) PASS1RC(bool, environment_get_volumetric_fog_enabled, RID) PASS1RC(float, environment_get_volumetric_fog_density, RID) @@ -1151,6 +1152,7 @@ public: PASS1RC(float, environment_get_volumetric_fog_length, RID) PASS1RC(float, environment_get_volumetric_fog_detail_spread, RID) PASS1RC(float, environment_get_volumetric_fog_gi_inject, RID) + PASS1RC(float, environment_get_volumetric_fog_sky_affect, RID) PASS1RC(bool, environment_get_volumetric_fog_temporal_reprojection, RID) PASS1RC(float, environment_get_volumetric_fog_temporal_reprojection_amount, RID) PASS1RC(float, environment_get_volumetric_fog_ambient_inject, RID) diff --git a/servers/rendering/renderer_scene_render.cpp b/servers/rendering/renderer_scene_render.cpp index 29a0002a32..f085168df3 100644 --- a/servers/rendering/renderer_scene_render.cpp +++ b/servers/rendering/renderer_scene_render.cpp @@ -308,8 +308,8 @@ float RendererSceneRender::environment_get_white(RID p_env) const { // Fog -void RendererSceneRender::environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) { - environment_storage.environment_set_fog(p_env, p_enable, p_light_color, p_light_energy, p_sun_scatter, p_density, p_height, p_height_density, p_aerial_perspective); +void RendererSceneRender::environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective, float p_sky_affect) { + environment_storage.environment_set_fog(p_env, p_enable, p_light_color, p_light_energy, p_sun_scatter, p_density, p_height, p_height_density, p_aerial_perspective, p_sky_affect); } bool RendererSceneRender::environment_get_fog_enabled(RID p_env) const { @@ -332,6 +332,10 @@ float RendererSceneRender::environment_get_fog_density(RID p_env) const { return environment_storage.environment_get_fog_density(p_env); } +float RendererSceneRender::environment_get_fog_sky_affect(RID p_env) const { + return environment_storage.environment_get_fog_sky_affect(p_env); +} + float RendererSceneRender::environment_get_fog_height(RID p_env) const { return environment_storage.environment_get_fog_height(p_env); } @@ -346,8 +350,8 @@ float RendererSceneRender::environment_get_fog_aerial_perspective(RID p_env) con // Volumetric Fog -void RendererSceneRender::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject) { - environment_storage.environment_set_volumetric_fog(p_env, p_enable, p_density, p_albedo, p_emission, p_emission_energy, p_anisotropy, p_length, p_detail_spread, p_gi_inject, p_temporal_reprojection, p_temporal_reprojection_amount, p_ambient_inject); +void RendererSceneRender::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject, float p_sky_affect) { + environment_storage.environment_set_volumetric_fog(p_env, p_enable, p_density, p_albedo, p_emission, p_emission_energy, p_anisotropy, p_length, p_detail_spread, p_gi_inject, p_temporal_reprojection, p_temporal_reprojection_amount, p_ambient_inject, p_sky_affect); } bool RendererSceneRender::environment_get_volumetric_fog_enabled(RID p_env) const { @@ -386,6 +390,10 @@ float RendererSceneRender::environment_get_volumetric_fog_gi_inject(RID p_env) c return environment_storage.environment_get_volumetric_fog_gi_inject(p_env); } +float RendererSceneRender::environment_get_volumetric_fog_sky_affect(RID p_env) const { + return environment_storage.environment_get_volumetric_fog_sky_affect(p_env); +} + bool RendererSceneRender::environment_get_volumetric_fog_temporal_reprojection(RID p_env) const { return environment_storage.environment_get_volumetric_fog_temporal_reprojection(p_env); } diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h index 535348a29b..9aa4108412 100644 --- a/servers/rendering/renderer_scene_render.h +++ b/servers/rendering/renderer_scene_render.h @@ -127,18 +127,19 @@ public: float environment_get_white(RID p_env) const; // Fog - void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective); + void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective, float p_sky_affect); bool environment_get_fog_enabled(RID p_env) const; Color environment_get_fog_light_color(RID p_env) const; float environment_get_fog_light_energy(RID p_env) const; float environment_get_fog_sun_scatter(RID p_env) const; float environment_get_fog_density(RID p_env) const; + float environment_get_fog_sky_affect(RID p_env) const; float environment_get_fog_height(RID p_env) const; float environment_get_fog_height_density(RID p_env) const; float environment_get_fog_aerial_perspective(RID p_env) const; // Volumetric Fog - void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject); + void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject, float p_sky_affect); bool environment_get_volumetric_fog_enabled(RID p_env) const; float environment_get_volumetric_fog_density(RID p_env) const; Color environment_get_volumetric_fog_scattering(RID p_env) const; @@ -148,6 +149,7 @@ public: float environment_get_volumetric_fog_length(RID p_env) const; float environment_get_volumetric_fog_detail_spread(RID p_env) const; float environment_get_volumetric_fog_gi_inject(RID p_env) const; + float environment_get_volumetric_fog_sky_affect(RID p_env) const; bool environment_get_volumetric_fog_temporal_reprojection(RID p_env) const; float environment_get_volumetric_fog_temporal_reprojection_amount(RID p_env) const; float environment_get_volumetric_fog_ambient_inject(RID p_env) const; @@ -336,7 +338,7 @@ public: virtual void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) = 0; virtual void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) = 0; - virtual TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) = 0; + virtual TypedArray<Image> bake_render_uv2(RID p_base, const TypedArray<RID> &p_material_overrides, const Size2i &p_image_size) = 0; virtual bool free(RID p_rid) = 0; diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index 2fefdbff52..dd190437a3 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -235,7 +235,7 @@ RID RenderingDevice::_shader_create_from_spirv(const Ref<RDShaderSPIRV> &p_spirv return shader_create_from_spirv(stage_data); } -RID RenderingDevice::_uniform_set_create(const Array &p_uniforms, RID p_shader, uint32_t p_shader_set) { +RID RenderingDevice::_uniform_set_create(const TypedArray<RDUniform> &p_uniforms, RID p_shader, uint32_t p_shader_set) { Vector<Uniform> uniforms; uniforms.resize(p_uniforms.size()); for (int i = 0; i < p_uniforms.size(); i++) { diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index ed88f57a94..29e5c9cd77 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -42,7 +42,7 @@ class RDSamplerState; class RDVertexAttribute; class RDShaderSource; class RDShaderSPIRV; -class RDUniforms; +class RDUniform; class RDPipelineRasterizationState; class RDPipelineMultisampleState; class RDPipelineDepthStencilState; @@ -1314,7 +1314,7 @@ protected: Vector<uint8_t> _shader_compile_binary_from_spirv(const Ref<RDShaderSPIRV> &p_bytecode, const String &p_shader_name = ""); RID _shader_create_from_spirv(const Ref<RDShaderSPIRV> &p_spirv, const String &p_shader_name = ""); - RID _uniform_set_create(const Array &p_uniforms, RID p_shader, uint32_t p_shader_set); + RID _uniform_set_create(const TypedArray<RDUniform> &p_uniforms, RID p_shader, uint32_t p_shader_set); Error _buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL); diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index 40912805dc..dfe16431bd 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -227,11 +227,11 @@ public: FUNC2(shader_set_path_hint, RID, const String &) FUNC1RC(String, shader_get_code, RID) - FUNC2SC(shader_get_shader_uniform_list, RID, List<PropertyInfo> *) + FUNC2SC(get_shader_parameter_list, RID, List<PropertyInfo> *) - FUNC4(shader_set_default_texture_param, RID, const StringName &, RID, int) - FUNC3RC(RID, shader_get_default_texture_param, RID, const StringName &, int) - FUNC2RC(Variant, shader_get_param_default, RID, const StringName &) + FUNC4(shader_set_default_texture_parameter, RID, const StringName &, RID, int) + FUNC3RC(RID, shader_get_default_texture_parameter, RID, const StringName &, int) + FUNC2RC(Variant, shader_get_parameter_default, RID, const StringName &) FUNC1RC(ShaderNativeSourceCode, shader_get_native_source_code, RID) @@ -695,8 +695,8 @@ public: FUNC7(environment_set_adjustment, RID, bool, float, float, float, bool, RID) - FUNC9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float) - FUNC13(environment_set_volumetric_fog, RID, bool, float, const Color &, const Color &, float, float, float, float, float, bool, float, float) + FUNC10(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float, float) + FUNC14(environment_set_volumetric_fog, RID, bool, float, const Color &, const Color &, float, float, float, float, float, bool, float, float, float) FUNC2(environment_set_volumetric_fog_volume_size, int, int) FUNC1(environment_set_volumetric_fog_filter_active, bool) @@ -783,12 +783,12 @@ public: FUNC4(instance_geometry_set_lightmap, RID, RID, const Rect2 &, int) FUNC2(instance_geometry_set_lod_bias, RID, float) FUNC2(instance_geometry_set_transparency, RID, float) - FUNC3(instance_geometry_set_shader_uniform, RID, const StringName &, const Variant &) - FUNC2RC(Variant, instance_geometry_get_shader_uniform, RID, const StringName &) - FUNC2RC(Variant, instance_geometry_get_shader_uniform_default_value, RID, const StringName &) - FUNC2C(instance_geometry_get_shader_uniform_list, RID, List<PropertyInfo> *) + FUNC3(instance_geometry_set_shader_parameter, RID, const StringName &, const Variant &) + FUNC2RC(Variant, instance_geometry_get_shader_parameter, RID, const StringName &) + FUNC2RC(Variant, instance_geometry_get_shader_parameter_default_value, RID, const StringName &) + FUNC2C(instance_geometry_get_shader_parameter_list, RID, List<PropertyInfo> *) - FUNC3R(TypedArray<Image>, bake_render_uv2, RID, const Vector<RID> &, const Size2i &) + FUNC3R(TypedArray<Image>, bake_render_uv2, RID, const TypedArray<RID> &, const Size2i &) FUNC1(gi_set_use_half_resolution, bool) @@ -919,16 +919,16 @@ public: #define ServerName RendererMaterialStorage #define server_name RSG::material_storage - FUNC3(global_shader_uniform_add, const StringName &, GlobalShaderUniformType, const Variant &) - FUNC1(global_shader_uniform_remove, const StringName &) - FUNC0RC(Vector<StringName>, global_shader_uniform_get_list) - FUNC2(global_shader_uniform_set, const StringName &, const Variant &) - FUNC2(global_shader_uniform_set_override, const StringName &, const Variant &) - FUNC1RC(GlobalShaderUniformType, global_shader_uniform_get_type, const StringName &) - FUNC1RC(Variant, global_shader_uniform_get, const StringName &) + FUNC3(global_shader_parameter_add, const StringName &, GlobalShaderParameterType, const Variant &) + FUNC1(global_shader_parameter_remove, const StringName &) + FUNC0RC(Vector<StringName>, global_shader_parameter_get_list) + FUNC2(global_shader_parameter_set, const StringName &, const Variant &) + FUNC2(global_shader_parameter_set_override, const StringName &, const Variant &) + FUNC1RC(GlobalShaderParameterType, global_shader_parameter_get_type, const StringName &) + FUNC1RC(Variant, global_shader_parameter_get, const StringName &) - FUNC1(global_shader_uniforms_load_settings, bool) - FUNC0(global_shader_uniforms_clear) + FUNC1(global_shader_parameters_load_settings, bool) + FUNC0(global_shader_parameters_clear) #undef server_name #undef ServerName diff --git a/servers/rendering/shader_compiler.cpp b/servers/rendering/shader_compiler.cpp index 7b33a13ec3..ab5b8af794 100644 --- a/servers/rendering/shader_compiler.cpp +++ b/servers/rendering/shader_compiler.cpp @@ -1349,7 +1349,7 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene } ShaderLanguage::DataType ShaderCompiler::_get_variable_type(const StringName &p_type) { - RS::GlobalShaderUniformType gvt = RS::get_singleton()->global_shader_uniform_get_type(p_type); + RS::GlobalShaderParameterType gvt = RS::get_singleton()->global_shader_parameter_get_type(p_type); return (ShaderLanguage::DataType)RS::global_shader_uniform_type_get_shader_datatype(gvt); } diff --git a/servers/rendering/storage/environment_storage.cpp b/servers/rendering/storage/environment_storage.cpp index 19cb067025..9b1842f1d9 100644 --- a/servers/rendering/storage/environment_storage.cpp +++ b/servers/rendering/storage/environment_storage.cpp @@ -205,7 +205,7 @@ float RendererEnvironmentStorage::environment_get_white(RID p_env) const { // Fog -void RendererEnvironmentStorage::environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_fog_aerial_perspective) { +void RendererEnvironmentStorage::environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_fog_aerial_perspective, float p_sky_affect) { Environment *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->fog_enabled = p_enable; @@ -216,6 +216,7 @@ void RendererEnvironmentStorage::environment_set_fog(RID p_env, bool p_enable, c env->fog_height = p_height; env->fog_height_density = p_height_density; env->fog_aerial_perspective = p_fog_aerial_perspective; + env->fog_sky_affect = p_sky_affect; } bool RendererEnvironmentStorage::environment_get_fog_enabled(RID p_env) const { @@ -266,9 +267,15 @@ float RendererEnvironmentStorage::environment_get_fog_aerial_perspective(RID p_e return env->fog_aerial_perspective; } +float RendererEnvironmentStorage::environment_get_fog_sky_affect(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.0); + return env->fog_sky_affect; +} + // Volumetric Fog -void RendererEnvironmentStorage::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject) { +void RendererEnvironmentStorage::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject, float p_sky_affect) { Environment *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->volumetric_fog_enabled = p_enable; @@ -283,6 +290,7 @@ void RendererEnvironmentStorage::environment_set_volumetric_fog(RID p_env, bool env->volumetric_fog_temporal_reprojection = p_temporal_reprojection; env->volumetric_fog_temporal_reprojection_amount = p_temporal_reprojection_amount; env->volumetric_fog_ambient_inject = p_ambient_inject; + env->volumetric_fog_sky_affect = p_sky_affect; } bool RendererEnvironmentStorage::environment_get_volumetric_fog_enabled(RID p_env) const { @@ -339,6 +347,12 @@ float RendererEnvironmentStorage::environment_get_volumetric_fog_gi_inject(RID p return env->volumetric_fog_gi_inject; } +float RendererEnvironmentStorage::environment_get_volumetric_fog_sky_affect(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.0); + return env->volumetric_fog_sky_affect; +} + bool RendererEnvironmentStorage::environment_get_volumetric_fog_temporal_reprojection(RID p_env) const { Environment *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, true); diff --git a/servers/rendering/storage/environment_storage.h b/servers/rendering/storage/environment_storage.h index 2821d299a8..17bde94902 100644 --- a/servers/rendering/storage/environment_storage.h +++ b/servers/rendering/storage/environment_storage.h @@ -66,6 +66,7 @@ private: float fog_light_energy = 1.0; float fog_sun_scatter = 0.0; float fog_density = 0.01; + float fog_sky_affect = 1.0; float fog_height = 0.0; float fog_height_density = 0.0; //can be negative to invert effect float fog_aerial_perspective = 0.0; @@ -81,6 +82,7 @@ private: float volumetric_fog_detail_spread = 2.0; float volumetric_fog_gi_inject = 1.0; float volumetric_fog_ambient_inject = 0.0; + float volumetric_fog_sky_affect = 1.0; bool volumetric_fog_temporal_reprojection = true; float volumetric_fog_temporal_reprojection_amount = 0.9; @@ -190,18 +192,19 @@ public: float environment_get_white(RID p_env) const; // Fog - void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective); + void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective, float p_sky_affect); bool environment_get_fog_enabled(RID p_env) const; Color environment_get_fog_light_color(RID p_env) const; float environment_get_fog_light_energy(RID p_env) const; float environment_get_fog_sun_scatter(RID p_env) const; float environment_get_fog_density(RID p_env) const; + float environment_get_fog_sky_affect(RID p_env) const; float environment_get_fog_height(RID p_env) const; float environment_get_fog_height_density(RID p_env) const; float environment_get_fog_aerial_perspective(RID p_env) const; // Volumetric Fog - void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject); + void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject, float p_sky_affect); bool environment_get_volumetric_fog_enabled(RID p_env) const; float environment_get_volumetric_fog_density(RID p_env) const; Color environment_get_volumetric_fog_scattering(RID p_env) const; @@ -211,6 +214,7 @@ public: float environment_get_volumetric_fog_length(RID p_env) const; float environment_get_volumetric_fog_detail_spread(RID p_env) const; float environment_get_volumetric_fog_gi_inject(RID p_env) const; + float environment_get_volumetric_fog_sky_affect(RID p_env) const; bool environment_get_volumetric_fog_temporal_reprojection(RID p_env) const; float environment_get_volumetric_fog_temporal_reprojection_amount(RID p_env) const; float environment_get_volumetric_fog_ambient_inject(RID p_env) const; diff --git a/servers/rendering/storage/material_storage.h b/servers/rendering/storage/material_storage.h index ad8e3e79bf..396668c9ed 100644 --- a/servers/rendering/storage/material_storage.h +++ b/servers/rendering/storage/material_storage.h @@ -39,21 +39,21 @@ public: virtual ~RendererMaterialStorage(){}; /* GLOBAL SHADER UNIFORM API */ - virtual void global_shader_uniform_add(const StringName &p_name, RS::GlobalShaderUniformType p_type, const Variant &p_value) = 0; - virtual void global_shader_uniform_remove(const StringName &p_name) = 0; - virtual Vector<StringName> global_shader_uniform_get_list() const = 0; + virtual void global_shader_parameter_add(const StringName &p_name, RS::GlobalShaderParameterType p_type, const Variant &p_value) = 0; + virtual void global_shader_parameter_remove(const StringName &p_name) = 0; + virtual Vector<StringName> global_shader_parameter_get_list() const = 0; - virtual void global_shader_uniform_set(const StringName &p_name, const Variant &p_value) = 0; - virtual void global_shader_uniform_set_override(const StringName &p_name, const Variant &p_value) = 0; - virtual Variant global_shader_uniform_get(const StringName &p_name) const = 0; - virtual RS::GlobalShaderUniformType global_shader_uniform_get_type(const StringName &p_name) const = 0; + virtual void global_shader_parameter_set(const StringName &p_name, const Variant &p_value) = 0; + virtual void global_shader_parameter_set_override(const StringName &p_name, const Variant &p_value) = 0; + virtual Variant global_shader_parameter_get(const StringName &p_name) const = 0; + virtual RS::GlobalShaderParameterType global_shader_parameter_get_type(const StringName &p_name) const = 0; - virtual void global_shader_uniforms_load_settings(bool p_load_textures = true) = 0; - virtual void global_shader_uniforms_clear() = 0; + virtual void global_shader_parameters_load_settings(bool p_load_textures = true) = 0; + virtual void global_shader_parameters_clear() = 0; - virtual int32_t global_shader_uniforms_instance_allocate(RID p_instance) = 0; - virtual void global_shader_uniforms_instance_free(RID p_instance) = 0; - virtual void global_shader_uniforms_instance_update(RID p_instance, int p_index, const Variant &p_value) = 0; + virtual int32_t global_shader_parameters_instance_allocate(RID p_instance) = 0; + virtual void global_shader_parameters_instance_free(RID p_instance) = 0; + virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value) = 0; /* SHADER API */ virtual RID shader_allocate() = 0; @@ -63,11 +63,11 @@ public: virtual void shader_set_code(RID p_shader, const String &p_code) = 0; virtual void shader_set_path_hint(RID p_shader, const String &p_path) = 0; virtual String shader_get_code(RID p_shader) const = 0; - virtual void shader_get_shader_uniform_list(RID p_shader, List<PropertyInfo> *p_param_list) const = 0; + virtual void get_shader_parameter_list(RID p_shader, List<PropertyInfo> *p_param_list) const = 0; - virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) = 0; - virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const = 0; - virtual Variant shader_get_param_default(RID p_material, const StringName &p_param) const = 0; + virtual void shader_set_default_texture_parameter(RID p_shader, const StringName &p_name, RID p_texture, int p_index) = 0; + virtual RID shader_get_default_texture_parameter(RID p_shader, const StringName &p_name, int p_index) const = 0; + virtual Variant shader_get_parameter_default(RID p_material, const StringName &p_param) const = 0; virtual RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const = 0; @@ -94,7 +94,7 @@ public: Variant default_value; }; - virtual void material_get_instance_shader_uniforms(RID p_material, List<InstanceShaderParam> *r_parameters) = 0; + virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) = 0; virtual void material_update_dependency(RID p_material, DependencyTracker *p_instance) = 0; }; diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index a840375393..aa3351c815 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -95,7 +95,7 @@ PackedInt64Array RenderingServer::_instances_cull_ray_bind(const Vector3 &p_from return to_int_array(ids); } -PackedInt64Array RenderingServer::_instances_cull_convex_bind(const Array &p_convex, RID p_scenario) const { +PackedInt64Array RenderingServer::_instances_cull_convex_bind(const TypedArray<Plane> &p_convex, RID p_scenario) const { if (RSG::threaded) { WARN_PRINT_ONCE("Using this function with a threaded renderer hurts performance, as it causes a server stall."); } @@ -1400,7 +1400,7 @@ Array RenderingServer::_mesh_surface_get_skeleton_aabb_bind(RID p_mesh, int p_su } #endif -int RenderingServer::global_shader_uniform_type_get_shader_datatype(GlobalShaderUniformType p_type) { +int RenderingServer::global_shader_uniform_type_get_shader_datatype(GlobalShaderParameterType p_type) { switch (p_type) { case RS::GLOBAL_VAR_TYPE_BOOL: return ShaderLanguage::TYPE_BOOL; @@ -1501,9 +1501,9 @@ TypedArray<Image> RenderingServer::_texture_3d_get(RID p_texture) const { return ret; } -TypedArray<Dictionary> RenderingServer::_shader_get_shader_uniform_list(RID p_shader) const { +TypedArray<Dictionary> RenderingServer::_shader_get_shader_parameter_list(RID p_shader) const { List<PropertyInfo> l; - shader_get_shader_uniform_list(p_shader, &l); + get_shader_parameter_list(p_shader, &l); return convert_property_list(&l); } @@ -1626,14 +1626,14 @@ Dictionary RenderingServer::_mesh_get_surface(RID p_mesh, int p_idx) { return d; } -TypedArray<Dictionary> RenderingServer::_instance_geometry_get_shader_uniform_list(RID p_instance) const { +TypedArray<Dictionary> RenderingServer::_instance_geometry_get_shader_parameter_list(RID p_instance) const { List<PropertyInfo> params; - instance_geometry_get_shader_uniform_list(p_instance, ¶ms); + instance_geometry_get_shader_parameter_list(p_instance, ¶ms); return convert_property_list(¶ms); } TypedArray<Image> RenderingServer::_bake_render_uv2(RID p_base, const TypedArray<RID> &p_material_overrides, const Size2i &p_image_size) { - Vector<RID> mat_overrides; + TypedArray<RID> mat_overrides; for (int i = 0; i < p_material_overrides.size(); i++) { mat_overrides.push_back(p_material_overrides[i]); } @@ -1702,11 +1702,11 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("shader_set_code", "shader", "code"), &RenderingServer::shader_set_code); ClassDB::bind_method(D_METHOD("shader_set_path_hint", "shader", "path"), &RenderingServer::shader_set_path_hint); ClassDB::bind_method(D_METHOD("shader_get_code", "shader"), &RenderingServer::shader_get_code); - ClassDB::bind_method(D_METHOD("shader_get_shader_uniform_list", "shader"), &RenderingServer::_shader_get_shader_uniform_list); - ClassDB::bind_method(D_METHOD("shader_get_param_default", "shader", "param"), &RenderingServer::shader_get_param_default); + ClassDB::bind_method(D_METHOD("get_shader_parameter_list", "shader"), &RenderingServer::_shader_get_shader_parameter_list); + ClassDB::bind_method(D_METHOD("shader_get_parameter_default", "shader", "name"), &RenderingServer::shader_get_parameter_default); - ClassDB::bind_method(D_METHOD("shader_set_default_texture_param", "shader", "param", "texture", "index"), &RenderingServer::shader_set_default_texture_param, DEFVAL(0)); - ClassDB::bind_method(D_METHOD("shader_get_default_texture_param", "shader", "param", "index"), &RenderingServer::shader_get_default_texture_param, DEFVAL(0)); + ClassDB::bind_method(D_METHOD("shader_set_default_texture_parameter", "shader", "name", "texture", "index"), &RenderingServer::shader_set_default_texture_parameter, DEFVAL(0)); + ClassDB::bind_method(D_METHOD("shader_get_default_texture_parameter", "shader", "name", "index"), &RenderingServer::shader_get_default_texture_parameter, DEFVAL(0)); BIND_ENUM_CONSTANT(SHADER_SPATIAL); BIND_ENUM_CONSTANT(SHADER_CANVAS_ITEM); @@ -2335,9 +2335,9 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("environment_set_adjustment", "env", "enable", "brightness", "contrast", "saturation", "use_1d_color_correction", "color_correction"), &RenderingServer::environment_set_adjustment); ClassDB::bind_method(D_METHOD("environment_set_ssr", "env", "enable", "max_steps", "fade_in", "fade_out", "depth_tolerance"), &RenderingServer::environment_set_ssr); ClassDB::bind_method(D_METHOD("environment_set_ssao", "env", "enable", "radius", "intensity", "power", "detail", "horizon", "sharpness", "light_affect", "ao_channel_affect"), &RenderingServer::environment_set_ssao); - ClassDB::bind_method(D_METHOD("environment_set_fog", "env", "enable", "light_color", "light_energy", "sun_scatter", "density", "height", "height_density", "aerial_perspective"), &RenderingServer::environment_set_fog); + ClassDB::bind_method(D_METHOD("environment_set_fog", "env", "enable", "light_color", "light_energy", "sun_scatter", "density", "height", "height_density", "aerial_perspective", "sky_affect"), &RenderingServer::environment_set_fog); ClassDB::bind_method(D_METHOD("environment_set_sdfgi", "env", "enable", "cascades", "min_cell_size", "y_scale", "use_occlusion", "bounce_feedback", "read_sky", "energy", "normal_bias", "probe_bias"), &RenderingServer::environment_set_sdfgi); - ClassDB::bind_method(D_METHOD("environment_set_volumetric_fog", "env", "enable", "density", "albedo", "emission", "emission_energy", "anisotropy", "length", "p_detail_spread", "gi_inject", "temporal_reprojection", "temporal_reprojection_amount", "ambient_inject"), &RenderingServer::environment_set_volumetric_fog); + ClassDB::bind_method(D_METHOD("environment_set_volumetric_fog", "env", "enable", "density", "albedo", "emission", "emission_energy", "anisotropy", "length", "p_detail_spread", "gi_inject", "temporal_reprojection", "temporal_reprojection_amount", "ambient_inject", "sky_affect"), &RenderingServer::environment_set_volumetric_fog); ClassDB::bind_method(D_METHOD("environment_glow_set_use_bicubic_upscale", "enable"), &RenderingServer::environment_glow_set_use_bicubic_upscale); ClassDB::bind_method(D_METHOD("environment_glow_set_use_high_quality", "enable"), &RenderingServer::environment_glow_set_use_high_quality); @@ -2490,10 +2490,10 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("instance_geometry_set_lightmap", "instance", "lightmap", "lightmap_uv_scale", "lightmap_slice"), &RenderingServer::instance_geometry_set_lightmap); ClassDB::bind_method(D_METHOD("instance_geometry_set_lod_bias", "instance", "lod_bias"), &RenderingServer::instance_geometry_set_lod_bias); - ClassDB::bind_method(D_METHOD("instance_geometry_set_shader_uniform", "instance", "parameter", "value"), &RenderingServer::instance_geometry_set_shader_uniform); - ClassDB::bind_method(D_METHOD("instance_geometry_get_shader_uniform", "instance", "parameter"), &RenderingServer::instance_geometry_get_shader_uniform); - ClassDB::bind_method(D_METHOD("instance_geometry_get_shader_uniform_default_value", "instance", "parameter"), &RenderingServer::instance_geometry_get_shader_uniform_default_value); - ClassDB::bind_method(D_METHOD("instance_geometry_get_shader_uniform_list", "instance"), &RenderingServer::_instance_geometry_get_shader_uniform_list); + ClassDB::bind_method(D_METHOD("instance_geometry_set_shader_parameter", "instance", "parameter", "value"), &RenderingServer::instance_geometry_set_shader_parameter); + ClassDB::bind_method(D_METHOD("instance_geometry_get_shader_parameter", "instance", "parameter"), &RenderingServer::instance_geometry_get_shader_parameter); + ClassDB::bind_method(D_METHOD("instance_geometry_get_shader_parameter_default_value", "instance", "parameter"), &RenderingServer::instance_geometry_get_shader_parameter_default_value); + ClassDB::bind_method(D_METHOD("instance_geometry_get_shader_parameter_list", "instance"), &RenderingServer::_instance_geometry_get_shader_parameter_list); ClassDB::bind_method(D_METHOD("instances_cull_aabb", "aabb", "scenario"), &RenderingServer::_instances_cull_aabb_bind, DEFVAL(RID())); ClassDB::bind_method(D_METHOD("instances_cull_ray", "from", "to", "scenario"), &RenderingServer::_instances_cull_ray_bind, DEFVAL(RID())); @@ -2690,13 +2690,13 @@ void RenderingServer::_bind_methods() { /* GLOBAL SHADER UNIFORMS */ - ClassDB::bind_method(D_METHOD("global_shader_uniform_add", "name", "type", "default_value"), &RenderingServer::global_shader_uniform_add); - ClassDB::bind_method(D_METHOD("global_shader_uniform_remove", "name"), &RenderingServer::global_shader_uniform_remove); - ClassDB::bind_method(D_METHOD("global_shader_uniform_get_list"), &RenderingServer::global_shader_uniform_get_list); - ClassDB::bind_method(D_METHOD("global_shader_uniform_set", "name", "value"), &RenderingServer::global_shader_uniform_set); - ClassDB::bind_method(D_METHOD("global_shader_uniform_set_override", "name", "value"), &RenderingServer::global_shader_uniform_set_override); - ClassDB::bind_method(D_METHOD("global_shader_uniform_get", "name"), &RenderingServer::global_shader_uniform_get); - ClassDB::bind_method(D_METHOD("global_shader_uniform_get_type", "name"), &RenderingServer::global_shader_uniform_get_type); + ClassDB::bind_method(D_METHOD("global_shader_parameter_add", "name", "type", "default_value"), &RenderingServer::global_shader_parameter_add); + ClassDB::bind_method(D_METHOD("global_shader_parameter_remove", "name"), &RenderingServer::global_shader_parameter_remove); + ClassDB::bind_method(D_METHOD("global_shader_parameter_get_list"), &RenderingServer::global_shader_parameter_get_list); + ClassDB::bind_method(D_METHOD("global_shader_parameter_set", "name", "value"), &RenderingServer::global_shader_parameter_set); + ClassDB::bind_method(D_METHOD("global_shader_parameter_set_override", "name", "value"), &RenderingServer::global_shader_parameter_set_override); + ClassDB::bind_method(D_METHOD("global_shader_parameter_get", "name"), &RenderingServer::global_shader_parameter_get); + ClassDB::bind_method(D_METHOD("global_shader_parameter_get_type", "name"), &RenderingServer::global_shader_parameter_get_type); BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_BOOL); BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_BVEC2); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 8cefad7cb5..67ba407775 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -173,11 +173,11 @@ public: virtual void shader_set_code(RID p_shader, const String &p_code) = 0; virtual void shader_set_path_hint(RID p_shader, const String &p_path) = 0; virtual String shader_get_code(RID p_shader) const = 0; - virtual void shader_get_shader_uniform_list(RID p_shader, List<PropertyInfo> *p_param_list) const = 0; - virtual Variant shader_get_param_default(RID p_shader, const StringName &p_param) const = 0; + virtual void get_shader_parameter_list(RID p_shader, List<PropertyInfo> *p_param_list) const = 0; + virtual Variant shader_get_parameter_default(RID p_shader, const StringName &p_param) const = 0; - virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index = 0) = 0; - virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index = 0) const = 0; + virtual void shader_set_default_texture_parameter(RID p_shader, const StringName &p_name, RID p_texture, int p_index = 0) = 0; + virtual RID shader_get_default_texture_parameter(RID p_shader, const StringName &p_name, int p_index = 0) const = 0; struct ShaderNativeSourceCode { struct Version { @@ -1120,9 +1120,9 @@ public: virtual void environment_set_sdfgi_frames_to_update_light(EnvironmentSDFGIFramesToUpdateLight p_update) = 0; - virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) = 0; + virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective, float p_sky_affect) = 0; - virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject) = 0; + virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject, float p_sky_affect) = 0; virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0; virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0; @@ -1223,7 +1223,7 @@ public: PackedInt64Array _instances_cull_aabb_bind(const AABB &p_aabb, RID p_scenario = RID()) const; PackedInt64Array _instances_cull_ray_bind(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario = RID()) const; - PackedInt64Array _instances_cull_convex_bind(const Array &p_convex, RID p_scenario = RID()) const; + PackedInt64Array _instances_cull_convex_bind(const TypedArray<Plane> &p_convex, RID p_scenario = RID()) const; enum InstanceFlags { INSTANCE_FLAG_USE_BAKED_LIGHT, @@ -1255,10 +1255,10 @@ public: virtual void instance_geometry_set_lod_bias(RID p_instance, float p_lod_bias) = 0; virtual void instance_geometry_set_transparency(RID p_instance, float p_transparency) = 0; - virtual void instance_geometry_set_shader_uniform(RID p_instance, const StringName &, const Variant &p_value) = 0; - virtual Variant instance_geometry_get_shader_uniform(RID p_instance, const StringName &) const = 0; - virtual Variant instance_geometry_get_shader_uniform_default_value(RID p_instance, const StringName &) const = 0; - virtual void instance_geometry_get_shader_uniform_list(RID p_instance, List<PropertyInfo> *p_parameters) const = 0; + virtual void instance_geometry_set_shader_parameter(RID p_instance, const StringName &, const Variant &p_value) = 0; + virtual Variant instance_geometry_get_shader_parameter(RID p_instance, const StringName &) const = 0; + virtual Variant instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &) const = 0; + virtual void instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const = 0; /* Bake 3D objects */ @@ -1269,7 +1269,7 @@ public: BAKE_CHANNEL_EMISSION }; - virtual TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) = 0; + virtual TypedArray<Image> bake_render_uv2(RID p_base, const TypedArray<RID> &p_material_overrides, const Size2i &p_image_size) = 0; /* CANVAS (2D) */ @@ -1441,7 +1441,7 @@ public: /* GLOBAL SHADER UNIFORMS */ - enum GlobalShaderUniformType { + enum GlobalShaderParameterType { GLOBAL_VAR_TYPE_BOOL, GLOBAL_VAR_TYPE_BVEC2, GLOBAL_VAR_TYPE_BVEC3, @@ -1473,20 +1473,20 @@ public: GLOBAL_VAR_TYPE_MAX }; - virtual void global_shader_uniform_add(const StringName &p_name, GlobalShaderUniformType p_type, const Variant &p_value) = 0; - virtual void global_shader_uniform_remove(const StringName &p_name) = 0; - virtual Vector<StringName> global_shader_uniform_get_list() const = 0; + virtual void global_shader_parameter_add(const StringName &p_name, GlobalShaderParameterType p_type, const Variant &p_value) = 0; + virtual void global_shader_parameter_remove(const StringName &p_name) = 0; + virtual Vector<StringName> global_shader_parameter_get_list() const = 0; - virtual void global_shader_uniform_set(const StringName &p_name, const Variant &p_value) = 0; - virtual void global_shader_uniform_set_override(const StringName &p_name, const Variant &p_value) = 0; + virtual void global_shader_parameter_set(const StringName &p_name, const Variant &p_value) = 0; + virtual void global_shader_parameter_set_override(const StringName &p_name, const Variant &p_value) = 0; - virtual Variant global_shader_uniform_get(const StringName &p_name) const = 0; - virtual GlobalShaderUniformType global_shader_uniform_get_type(const StringName &p_name) const = 0; + virtual Variant global_shader_parameter_get(const StringName &p_name) const = 0; + virtual GlobalShaderParameterType global_shader_parameter_get_type(const StringName &p_name) const = 0; - virtual void global_shader_uniforms_load_settings(bool p_load_textures) = 0; - virtual void global_shader_uniforms_clear() = 0; + virtual void global_shader_parameters_load_settings(bool p_load_textures) = 0; + virtual void global_shader_parameters_clear() = 0; - static int global_shader_uniform_type_get_shader_datatype(GlobalShaderUniformType p_type); + static int global_shader_uniform_type_get_shader_datatype(GlobalShaderParameterType p_type); /* FREE */ @@ -1583,11 +1583,11 @@ private: RID _texture_3d_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const TypedArray<Image> &p_data); void _texture_3d_update(RID p_texture, const TypedArray<Image> &p_data); TypedArray<Image> _texture_3d_get(RID p_texture) const; - TypedArray<Dictionary> _shader_get_shader_uniform_list(RID p_shader) const; + TypedArray<Dictionary> _shader_get_shader_parameter_list(RID p_shader) const; RID _mesh_create_from_surfaces(const TypedArray<Dictionary> &p_surfaces, int p_blend_shape_count); void _mesh_add_surface(RID p_mesh, const Dictionary &p_surface); Dictionary _mesh_get_surface(RID p_mesh, int p_idx); - TypedArray<Dictionary> _instance_geometry_get_shader_uniform_list(RID p_instance) const; + TypedArray<Dictionary> _instance_geometry_get_shader_parameter_list(RID p_instance) const; TypedArray<Image> _bake_render_uv2(RID p_base, const TypedArray<RID> &p_material_overrides, const Size2i &p_image_size); void _particles_set_trail_bind_poses(RID p_particles, const TypedArray<Transform3D> &p_bind_poses); }; @@ -1662,7 +1662,7 @@ VARIANT_ENUM_CAST(RenderingServer::CanvasLightMode); VARIANT_ENUM_CAST(RenderingServer::CanvasLightBlendMode); VARIANT_ENUM_CAST(RenderingServer::CanvasLightShadowFilter); VARIANT_ENUM_CAST(RenderingServer::CanvasOccluderPolygonCullMode); -VARIANT_ENUM_CAST(RenderingServer::GlobalShaderUniformType); +VARIANT_ENUM_CAST(RenderingServer::GlobalShaderParameterType); VARIANT_ENUM_CAST(RenderingServer::RenderingInfo); VARIANT_ENUM_CAST(RenderingServer::Features); VARIANT_ENUM_CAST(RenderingServer::CanvasTextureChannel); diff --git a/servers/text/text_server_extension.cpp b/servers/text/text_server_extension.cpp index 74ae2bfff0..ebd35b0f75 100644 --- a/servers/text/text_server_extension.cpp +++ b/servers/text/text_server_extension.cpp @@ -1136,7 +1136,7 @@ int64_t TextServerExtension::shaped_text_get_spacing(const RID &p_shaped, TextSe return 0; } -bool TextServerExtension::shaped_text_add_string(const RID &p_shaped, const String &p_text, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features, const String &p_language, const Variant &p_meta) { +bool TextServerExtension::shaped_text_add_string(const RID &p_shaped, const String &p_text, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features, const String &p_language, const Variant &p_meta) { bool ret; if (GDVIRTUAL_CALL(shaped_text_add_string, p_shaped, p_text, p_fonts, p_size, p_opentype_features, p_language, p_meta, ret)) { return ret; @@ -1176,7 +1176,7 @@ Variant TextServerExtension::shaped_get_span_meta(const RID &p_shaped, int64_t p return false; } -void TextServerExtension::shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features) { +void TextServerExtension::shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features) { GDVIRTUAL_CALL(shaped_set_span_update_font, p_shaped, p_index, p_fonts, p_size, p_opentype_features); } diff --git a/servers/text/text_server_extension.h b/servers/text/text_server_extension.h index 6a2c199898..700d08f7d7 100644 --- a/servers/text/text_server_extension.h +++ b/servers/text/text_server_extension.h @@ -378,19 +378,19 @@ public: GDVIRTUAL3(shaped_text_set_spacing, RID, SpacingType, int64_t); GDVIRTUAL2RC(int64_t, shaped_text_get_spacing, RID, SpacingType); - virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) override; + virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) override; virtual bool shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int64_t p_length = 1) override; virtual bool shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) override; - GDVIRTUAL7R(bool, shaped_text_add_string, RID, const String &, const Array &, int64_t, const Dictionary &, const String &, const Variant &); + GDVIRTUAL7R(bool, shaped_text_add_string, RID, const String &, const TypedArray<RID> &, int64_t, const Dictionary &, const String &, const Variant &); GDVIRTUAL5R(bool, shaped_text_add_object, RID, const Variant &, const Size2 &, InlineAlignment, int64_t); GDVIRTUAL4R(bool, shaped_text_resize_object, RID, const Variant &, const Size2 &, InlineAlignment); virtual int64_t shaped_get_span_count(const RID &p_shaped) const override; virtual Variant shaped_get_span_meta(const RID &p_shaped, int64_t p_index) const override; - virtual void shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary()) override; + virtual void shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary()) override; GDVIRTUAL1RC(int64_t, shaped_get_span_count, RID); GDVIRTUAL2RC(Variant, shaped_get_span_meta, RID, int64_t); - GDVIRTUAL5(shaped_set_span_update_font, RID, int64_t, const Array &, int64_t, const Dictionary &); + GDVIRTUAL5(shaped_set_span_update_font, RID, int64_t, const TypedArray<RID> &, int64_t, const Dictionary &); virtual RID shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const override; virtual RID shaped_text_get_parent(const RID &p_shaped) const override; diff --git a/servers/text_server.cpp b/servers/text_server.cpp index 9df74b1b20..660247839c 100644 --- a/servers/text_server.cpp +++ b/servers/text_server.cpp @@ -683,7 +683,9 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(const RID &p_shaped int line_start = MAX(p_start, range.x); int prev_safe_break = 0; int last_safe_break = -1; + int word_count = 0; int chunk = 0; + bool trim_next = false; int l_size = shaped_text_get_glyph_count(p_shaped); const Glyph *l_gl = const_cast<TextServer *>(this)->shaped_text_sort_logical(p_shaped); @@ -698,8 +700,7 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(const RID &p_shaped if (p_break_flags.has_flag(BREAK_TRIM_EDGE_SPACES)) { int start_pos = prev_safe_break; int end_pos = last_safe_break; - - while ((start_pos < end_pos) && ((l_gl[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { + while (trim_next && (start_pos < end_pos) && ((l_gl[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { start_pos += l_gl[start_pos].count; } while ((start_pos < end_pos) && ((l_gl[end_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { @@ -707,6 +708,7 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(const RID &p_shaped } lines.push_back(l_gl[start_pos].start); lines.push_back(l_gl[end_pos].end); + trim_next = true; } else { lines.push_back(line_start); lines.push_back(l_gl[last_safe_break].end); @@ -716,6 +718,7 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(const RID &p_shaped i = last_safe_break; last_safe_break = -1; width = 0; + word_count = 0; chunk++; if (chunk >= p_width.size()) { chunk = 0; @@ -730,8 +733,7 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(const RID &p_shaped if (p_break_flags.has_flag(BREAK_TRIM_EDGE_SPACES)) { int start_pos = prev_safe_break; int end_pos = i; - - while ((start_pos < end_pos) && ((l_gl[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { + while (trim_next && (start_pos < end_pos) && ((l_gl[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { start_pos += l_gl[start_pos].count; } while ((start_pos < end_pos) && ((l_gl[end_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { @@ -739,6 +741,7 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(const RID &p_shaped } lines.push_back(l_gl[start_pos].start); lines.push_back(l_gl[end_pos].end); + trim_next = false; } else { lines.push_back(line_start); lines.push_back(l_gl[i].end); @@ -757,9 +760,10 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(const RID &p_shaped if (p_break_flags.has_flag(BREAK_WORD_BOUND)) { if ((l_gl[i].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT) { last_safe_break = i; + word_count++; } } - if (p_break_flags.has_flag(BREAK_GRAPHEME_BOUND)) { + if (p_break_flags.has_flag(BREAK_GRAPHEME_BOUND) && word_count == 0) { last_safe_break = i; } } @@ -771,19 +775,14 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(const RID &p_shaped if (p_break_flags.has_flag(BREAK_TRIM_EDGE_SPACES)) { int start_pos = (prev_safe_break < l_size) ? prev_safe_break : l_size - 1; int end_pos = l_size - 1; - - while ((start_pos < end_pos) && ((l_gl[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { + while (trim_next && (start_pos < end_pos) && ((l_gl[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { start_pos += l_gl[start_pos].count; } - while ((start_pos < end_pos) && ((l_gl[end_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { - end_pos -= l_gl[end_pos].count; - } lines.push_back(l_gl[start_pos].start); - lines.push_back(l_gl[end_pos].end); } else { lines.push_back(line_start); - lines.push_back(range.y); } + lines.push_back(range.y); } } else { lines.push_back(0); @@ -804,6 +803,7 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, do int prev_safe_break = 0; int last_safe_break = -1; int word_count = 0; + bool trim_next = false; int l_size = shaped_text_get_glyph_count(p_shaped); const Glyph *l_gl = const_cast<TextServer *>(this)->shaped_text_sort_logical(p_shaped); @@ -818,16 +818,15 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, do if (p_break_flags.has_flag(BREAK_TRIM_EDGE_SPACES)) { int start_pos = prev_safe_break; int end_pos = last_safe_break; - - while ((start_pos < end_pos) && ((l_gl[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { + while (trim_next && (start_pos < end_pos) && ((l_gl[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { start_pos += l_gl[start_pos].count; } while ((start_pos < end_pos) && ((l_gl[end_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { end_pos -= l_gl[end_pos].count; } - //printf("%s", vformat("BRK TRIM(W): %d..%d -> %d..%d\n", line_start, l_gl[last_safe_break].end, l_gl[start_pos].start, l_gl[end_pos].end).utf8().get_data()); lines.push_back(l_gl[start_pos].start); lines.push_back(l_gl[end_pos].end); + trim_next = true; } else { lines.push_back(line_start); lines.push_back(l_gl[last_safe_break].end); @@ -845,16 +844,15 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, do if (p_break_flags.has_flag(BREAK_TRIM_EDGE_SPACES)) { int start_pos = prev_safe_break; int end_pos = i; - - while ((start_pos < end_pos) && ((l_gl[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { + while (trim_next && (start_pos < end_pos) && ((l_gl[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { start_pos += l_gl[start_pos].count; } while ((start_pos < end_pos) && ((l_gl[end_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { end_pos -= l_gl[end_pos].count; } + trim_next = false; lines.push_back(l_gl[start_pos].start); lines.push_back(l_gl[end_pos].end); - //printf("%s", vformat("BRK TRIM(M): %d..%d -> %d..%d\n", line_start, l_gl[i].end, l_gl[start_pos].start, l_gl[end_pos].end).utf8().get_data()); } else { lines.push_back(line_start); lines.push_back(l_gl[i].end); @@ -887,19 +885,14 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, do if (p_break_flags.has_flag(BREAK_TRIM_EDGE_SPACES)) { int start_pos = (prev_safe_break < l_size) ? prev_safe_break : l_size - 1; int end_pos = l_size - 1; - - while ((start_pos < end_pos) && ((l_gl[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { + while (trim_next && (start_pos < end_pos) && ((l_gl[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { start_pos += l_gl[start_pos].count; } - while ((start_pos < end_pos) && ((l_gl[end_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { - end_pos -= l_gl[end_pos].count; - } lines.push_back(l_gl[start_pos].start); - lines.push_back(l_gl[end_pos].end); } else { lines.push_back(line_start); - lines.push_back(range.y); } + lines.push_back(range.y); } } else { lines.push_back(0); diff --git a/servers/text_server.h b/servers/text_server.h index e8945dd807..b62d418fc8 100644 --- a/servers/text_server.h +++ b/servers/text_server.h @@ -409,13 +409,13 @@ public: virtual void shaped_text_set_spacing(const RID &p_shaped, SpacingType p_spacing, int64_t p_value) = 0; virtual int64_t shaped_text_get_spacing(const RID &p_shaped, SpacingType p_spacing) const = 0; - virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) = 0; + virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) = 0; virtual bool shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int64_t p_length = 1) = 0; virtual bool shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) = 0; virtual int64_t shaped_get_span_count(const RID &p_shaped) const = 0; virtual Variant shaped_get_span_meta(const RID &p_shaped, int64_t p_index) const = 0; - virtual void shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary()) = 0; + virtual void shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary()) = 0; virtual RID shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const = 0; // Copy shaped substring (e.g. line break) without reshaping, but correctly reordered, preservers range. virtual RID shaped_text_get_parent(const RID &p_shaped) const = 0; diff --git a/tests/core/math/test_geometry_3d.h b/tests/core/math/test_geometry_3d.h index 99a4ef2d46..23bbf1e183 100644 --- a/tests/core/math/test_geometry_3d.h +++ b/tests/core/math/test_geometry_3d.h @@ -63,7 +63,7 @@ TEST_CASE("[Geometry3D] Closest Distance Between Segments") { p_1(p_p_1), p_2(p_p_2), p_3(p_p_3), p_4(p_p_4), want(p_want){}; }; Vector<Case> tt; - tt.push_back(Case(Vector3(1, -2, 0), Vector3(1, 2, 0), Vector3(-1, 2, 0), Vector3(-1, -2, 0), 0.0f)); + tt.push_back(Case(Vector3(1, -2, 0), Vector3(1, 2, 0), Vector3(-1, 2, 0), Vector3(-1, -2, 0), 2.0f)); for (int i = 0; i < tt.size(); ++i) { Case current_case = tt[i]; float out = Geometry3D::get_closest_distance_between_segments(current_case.p_1, current_case.p_2, current_case.p_3, current_case.p_4); diff --git a/tests/core/variant/test_dictionary.h b/tests/core/variant/test_dictionary.h index 729035919d..c98434d42c 100644 --- a/tests/core/variant/test_dictionary.h +++ b/tests/core/variant/test_dictionary.h @@ -500,6 +500,24 @@ TEST_CASE("[Dictionary] Recursive self comparison") { d2.clear(); } +TEST_CASE("[Dictionary] Order and find") { + Dictionary d; + d[4] = "four"; + d[8] = "eight"; + d[12] = "twelve"; + d["4"] = "four"; + + Array keys; + keys.append(4); + keys.append(8); + keys.append(12); + keys.append("4"); + + CHECK_EQ(d.keys(), keys); + CHECK_EQ(d.find_key("four"), Variant(4)); + CHECK_EQ(d.find_key("does not exist"), Variant()); +} + } // namespace TestDictionary #endif // TEST_DICTIONARY_H diff --git a/tests/scene/test_bit_map.h b/tests/scene/test_bit_map.h new file mode 100644 index 0000000000..53afdc38f7 --- /dev/null +++ b/tests/scene/test_bit_map.h @@ -0,0 +1,445 @@ +/*************************************************************************/ +/* test_bit_map.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_BIT_MAP_H +#define TEST_BIT_MAP_H + +#include "core/os/memory.h" +#include "scene/resources/bit_map.h" +#include "tests/test_macros.h" + +namespace TestBitmap { + +void reset_bit_map(BitMap &p_bm) { + Size2i size = p_bm.get_size(); + p_bm.set_bit_rect(Rect2i(0, 0, size.width, size.height), false); +} + +TEST_CASE("[BitMap] Create bit map") { + Size2i dim{ 256, 512 }; + BitMap bit_map{}; + bit_map.create(dim); + CHECK(bit_map.get_size() == Size2i(256, 512)); + CHECK_MESSAGE(bit_map.get_true_bit_count() == 0, "This will go through the entire bitmask inside of bitmap, thus hopefully checking if the bitmask was correctly set up."); + + dim = Size2i(0, 256); + bit_map.create(dim); + CHECK_MESSAGE(bit_map.get_size() == Size2i(256, 512), "We should still have the same dimensions as before, because the new dimension is invalid."); + + dim = Size2i(512, 0); + bit_map.create(dim); + CHECK_MESSAGE(bit_map.get_size() == Size2i(256, 512), "We should still have the same dimensions as before, because the new dimension is invalid."); + + dim = Size2i(46341, 46341); + bit_map.create(dim); + CHECK_MESSAGE(bit_map.get_size() == Size2i(256, 512), "We should still have the same dimensions as before, because the new dimension is too large (46341*46341=2147488281)."); +} + +TEST_CASE("[BitMap] Create bit map from image alpha") { + const Size2i dim{ 256, 256 }; + BitMap bit_map{}; + bit_map.create(dim); + + const Ref<Image> null_img = nullptr; + bit_map.create_from_image_alpha(null_img); + CHECK_MESSAGE(bit_map.get_size() == Size2i(256, 256), "Bitmap should have its old values because bitmap creation from a nullptr should fail."); + + Ref<Image> empty_img; + empty_img.instantiate(); + bit_map.create_from_image_alpha(empty_img); + CHECK_MESSAGE(bit_map.get_size() == Size2i(256, 256), "Bitmap should have its old values because bitmap creation from an empty image should fail."); + + Ref<Image> wrong_format_img; + wrong_format_img.instantiate(); + wrong_format_img->create(3, 3, false, Image::Format::FORMAT_DXT1); + bit_map.create_from_image_alpha(wrong_format_img); + CHECK_MESSAGE(bit_map.get_size() == Size2i(256, 256), "Bitmap should have its old values because converting from a compressed image should fail."); + + Ref<Image> img; + img.instantiate(); + img->create(3, 3, false, Image::Format::FORMAT_RGBA8); + img->set_pixel(0, 0, Color(0, 0, 0, 0)); + img->set_pixel(0, 1, Color(0, 0, 0, 0.09f)); + img->set_pixel(0, 2, Color(0, 0, 0, 0.25f)); + img->set_pixel(1, 0, Color(0, 0, 0, 0.5f)); + img->set_pixel(1, 1, Color(0, 0, 0, 0.75f)); + img->set_pixel(1, 2, Color(0, 0, 0, 0.99f)); + img->set_pixel(2, 0, Color(0, 0, 0, 1.f)); + + // Check different threshold values. + bit_map.create_from_image_alpha(img); + CHECK_MESSAGE(bit_map.get_true_bit_count() == 5, "There are 5 values in the image that are smaller than the default threshold of 0.1."); + + bit_map.create_from_image_alpha(img, 0.08f); + CHECK_MESSAGE(bit_map.get_true_bit_count() == 6, "There are 6 values in the image that are smaller than the threshold of 0.08."); + + bit_map.create_from_image_alpha(img, 1); + CHECK_MESSAGE(bit_map.get_true_bit_count() == 0, "There are no values in the image that are smaller than the threshold of 1, there is one value equal to 1, but we check for inequality only."); +} + +TEST_CASE("[BitMap] Set bit") { + Size2i dim{ 256, 256 }; + BitMap bit_map{}; + + // Setting a point before a bit map is created should not crash, because there are checks to see if we are out of bounds. + bit_map.set_bitv(Point2i(128, 128), true); + + bit_map.create(dim); + CHECK_MESSAGE(bit_map.get_true_bit_count() == 0, "All values should be initialized to false."); + bit_map.set_bitv(Point2i(128, 128), true); + CHECK_MESSAGE(bit_map.get_true_bit_count() == 1, "One bit should be set to true."); + CHECK_MESSAGE(bit_map.get_bitv(Point2i(128, 128)) == true, "The bit at (128,128) should be set to true"); + + bit_map.set_bitv(Point2i(128, 128), false); + CHECK_MESSAGE(bit_map.get_true_bit_count() == 0, "The bit should now be set to false again"); + CHECK_MESSAGE(bit_map.get_bitv(Point2i(128, 128)) == false, "The bit at (128,128) should now be set to false again"); + + bit_map.create(dim); + bit_map.set_bitv(Point2i(512, 512), true); + CHECK_MESSAGE(bit_map.get_true_bit_count() == 0, "Nothing should change as we were trying to edit a bit outside of the correct range."); +} + +TEST_CASE("[BitMap] Get bit") { + const Size2i dim{ 256, 256 }; + BitMap bit_map{}; + + CHECK_MESSAGE(bit_map.get_bitv(Point2i(128, 128)) == false, "Trying to access a bit outside of the BitMap's range should always return false"); + + bit_map.create(dim); + CHECK(bit_map.get_bitv(Point2i(128, 128)) == false); + + bit_map.set_bit_rect(Rect2i(-1, -1, 257, 257), true); + + // Checking that range is [0, 256). + CHECK(bit_map.get_bitv(Point2i(-1, 0)) == false); + CHECK(bit_map.get_bitv(Point2i(0, 0)) == true); + CHECK(bit_map.get_bitv(Point2i(128, 128)) == true); + CHECK(bit_map.get_bitv(Point2i(255, 255)) == true); + CHECK(bit_map.get_bitv(Point2i(256, 256)) == false); + CHECK(bit_map.get_bitv(Point2i(257, 257)) == false); +} + +TEST_CASE("[BitMap] Set bit rect") { + const Size2i dim{ 256, 256 }; + BitMap bit_map{}; + + // Although we have not setup the BitMap yet, this should not crash because we get an empty intersection inside of the method. + bit_map.set_bit_rect(Rect2i{ 0, 0, 128, 128 }, true); + + bit_map.create(dim); + CHECK(bit_map.get_true_bit_count() == 0); + + bit_map.set_bit_rect(Rect2i{ 0, 0, 256, 256 }, true); + CHECK(bit_map.get_true_bit_count() == 65536); + + reset_bit_map(bit_map); + + // Checking out of bounds handling. + bit_map.set_bit_rect(Rect2i{ 128, 128, 256, 256 }, true); + CHECK(bit_map.get_true_bit_count() == 16384); + + reset_bit_map(bit_map); + + bit_map.set_bit_rect(Rect2i{ -128, -128, 256, 256 }, true); + CHECK(bit_map.get_true_bit_count() == 16384); + + reset_bit_map(bit_map); + + bit_map.set_bit_rect(Rect2i{ -128, -128, 512, 512 }, true); + CHECK(bit_map.get_true_bit_count() == 65536); +} + +TEST_CASE("[BitMap] Get true bit count") { + const Size2i dim{ 256, 256 }; + BitMap bit_map{}; + + CHECK(bit_map.get_true_bit_count() == 0); + + bit_map.create(dim); + CHECK_MESSAGE(bit_map.get_true_bit_count() == 0, "Unitialized bit map should have no true bits"); + bit_map.set_bit_rect(Rect2i{ 0, 0, 256, 256 }, true); + CHECK(bit_map.get_true_bit_count() == 65536); + bit_map.set_bitv(Point2i{ 0, 0 }, false); + CHECK(bit_map.get_true_bit_count() == 65535); + bit_map.set_bit_rect(Rect2i{ 0, 0, 256, 256 }, false); + CHECK(bit_map.get_true_bit_count() == 0); +} + +TEST_CASE("[BitMap] Get size") { + const Size2i dim{ 256, 256 }; + BitMap bit_map{}; + + CHECK_MESSAGE(bit_map.get_size() == Size2i(0, 0), "Unitialized bit map should have a size of 0x0"); + + bit_map.create(dim); + CHECK(bit_map.get_size() == Size2i(256, 256)); + + bit_map.create(Size2i(-1, 0)); + CHECK_MESSAGE(bit_map.get_size() == Size2i(256, 256), "Invalid size should not be accepted by create"); + + bit_map.create(Size2i(256, 128)); + CHECK_MESSAGE(bit_map.get_size() == Size2i(256, 128), "Bitmap should have updated size"); +} + +TEST_CASE("[BitMap] Resize") { + const Size2i dim{ 128, 128 }; + BitMap bit_map{}; + + bit_map.resize(dim); + CHECK(bit_map.get_size() == dim); + + bit_map.create(dim); + bit_map.set_bit_rect(Rect2i(0, 0, 10, 10), true); + bit_map.set_bit_rect(Rect2i(118, 118, 10, 10), true); + CHECK_MESSAGE(bit_map.get_true_bit_count() == 200, "There should be 100 bits in the top left corner, and 100 bits in the bottom right corner"); + bit_map.resize(Size2i(64, 64)); + CHECK_MESSAGE(bit_map.get_true_bit_count() == 50, "There should be 25 bits in the top left corner, and 25 bits in the bottom right corner"); + + bit_map.create(dim); + bit_map.resize(Size2i(-1, 128)); + CHECK_MESSAGE(bit_map.get_size() == Size2i(128, 128), "When an invalid size is given the bit map will keep its size"); + + bit_map.create(dim); + bit_map.set_bit_rect(Rect2i(0, 0, 10, 10), true); + bit_map.set_bit_rect(Rect2i(118, 118, 10, 10), true); + CHECK_MESSAGE(bit_map.get_true_bit_count() == 200, "There should be 100 bits in the top left corner, and 100 bits in the bottom right corner"); + bit_map.resize(Size2i(256, 256)); + CHECK_MESSAGE(bit_map.get_true_bit_count() == 800, "There should still be 100 bits in the bottom right corner, and all new bits should be initialized to false"); + CHECK_MESSAGE(bit_map.get_size() == Size2i(256, 256), "The bitmap should now be 256x256"); +} + +TEST_CASE("[BitMap] Grow and shrink mask") { + const Size2i dim{ 256, 256 }; + BitMap bit_map{}; + bit_map.grow_mask(100, Rect2i(0, 0, 128, 128)); // Check if method does not crash when working with an uninitialised bit map. + CHECK_MESSAGE(bit_map.get_size() == Size2i(0, 0), "Size should still be equal to 0x0"); + + bit_map.create(dim); + + bit_map.set_bit_rect(Rect2i(96, 96, 64, 64), true); + + CHECK_MESSAGE(bit_map.get_true_bit_count() == 4096, "Creating a square of 64x64 should be 4096 bits"); + bit_map.grow_mask(0, Rect2i(0, 0, 256, 256)); + CHECK_MESSAGE(bit_map.get_true_bit_count() == 4096, "Growing with size of 0 should not change any bits"); + + reset_bit_map(bit_map); + + bit_map.set_bit_rect(Rect2i(96, 96, 64, 64), true); + + CHECK_MESSAGE(bit_map.get_bitv(Point2i(95, 128)) == false, "Bits just outside of the square should not be set"); + CHECK_MESSAGE(bit_map.get_bitv(Point2i(160, 128)) == false, "Bits just outside of the square should not be set"); + CHECK_MESSAGE(bit_map.get_bitv(Point2i(128, 95)) == false, "Bits just outside of the square should not be set"); + CHECK_MESSAGE(bit_map.get_bitv(Point2i(128, 160)) == false, "Bits just outside of the square should not be set"); + bit_map.grow_mask(1, Rect2i(0, 0, 256, 256)); + CHECK_MESSAGE(bit_map.get_true_bit_count() == 4352, "We should have 4*64 (perimeter of square) more bits set to true"); + CHECK_MESSAGE(bit_map.get_bitv(Point2i(95, 128)) == true, "Bits that were just outside of the square should now be set to true"); + CHECK_MESSAGE(bit_map.get_bitv(Point2i(160, 128)) == true, "Bits that were just outside of the square should now be set to true"); + CHECK_MESSAGE(bit_map.get_bitv(Point2i(128, 95)) == true, "Bits that were just outside of the square should now be set to true"); + CHECK_MESSAGE(bit_map.get_bitv(Point2i(128, 160)) == true, "Bits that were just outside of the square should now be set to true"); + + reset_bit_map(bit_map); + + bit_map.set_bit_rect(Rect2i(127, 127, 1, 1), true); + + CHECK(bit_map.get_true_bit_count() == 1); + bit_map.grow_mask(32, Rect2i(0, 0, 256, 256)); + CHECK_MESSAGE(bit_map.get_true_bit_count() == 3209, "Creates a circle around the initial bit with a radius of 32 bits. Any bit that has a distance within this radius will be set to true"); + + reset_bit_map(bit_map); + + bit_map.set_bit_rect(Rect2i(127, 127, 1, 1), true); + for (int i = 0; i < 32; i++) { + bit_map.grow_mask(1, Rect2i(0, 0, 256, 256)); + } + CHECK_MESSAGE(bit_map.get_true_bit_count() == 2113, "Creates a diamond around the initial bit with diagonals that are 65 bits long."); + + reset_bit_map(bit_map); + + bit_map.set_bit_rect(Rect2i(123, 123, 10, 10), true); + + CHECK(bit_map.get_true_bit_count() == 100); + bit_map.grow_mask(-11, Rect2i(0, 0, 256, 256)); + CHECK_MESSAGE(bit_map.get_true_bit_count() == 0, "Shrinking by more than the width of the square should totally remove it."); + + reset_bit_map(bit_map); + bit_map.set_bit_rect(Rect2i(96, 96, 64, 64), true); + + CHECK_MESSAGE(bit_map.get_bitv(Point2i(96, 129)) == true, "Bits on the edge of the square should be true"); + CHECK_MESSAGE(bit_map.get_bitv(Point2i(159, 129)) == true, "Bits on the edge of the square should be true"); + CHECK_MESSAGE(bit_map.get_bitv(Point2i(129, 96)) == true, "Bits on the edge of the square should be true"); + CHECK_MESSAGE(bit_map.get_bitv(Point2i(129, 159)) == true, "Bits on the edge of the square should be true"); + bit_map.grow_mask(-1, Rect2i(0, 0, 256, 256)); + CHECK_MESSAGE(bit_map.get_true_bit_count() == 3844, "Shrinking by 1 should set 4*63=252 bits to false"); + CHECK_MESSAGE(bit_map.get_bitv(Point2i(96, 129)) == false, "Bits that were on the edge of the square should now be set to false"); + CHECK_MESSAGE(bit_map.get_bitv(Point2i(159, 129)) == false, "Bits that were on the edge of the square should now be set to false"); + CHECK_MESSAGE(bit_map.get_bitv(Point2i(129, 96)) == false, "Bits that were on the edge of the square should now be set to false"); + CHECK_MESSAGE(bit_map.get_bitv(Point2i(129, 159)) == false, "Bits that were on the edge of the square should now be set to false"); + + reset_bit_map(bit_map); + + bit_map.set_bit_rect(Rect2i(125, 125, 1, 6), true); + bit_map.set_bit_rect(Rect2i(130, 125, 1, 6), true); + bit_map.set_bit_rect(Rect2i(125, 130, 6, 1), true); + + CHECK(bit_map.get_true_bit_count() == 16); + CHECK_MESSAGE(bit_map.get_bitv(Point2i(125, 131)) == false, "Bits that are on the edge of the shape should be set to false"); + CHECK_MESSAGE(bit_map.get_bitv(Point2i(131, 131)) == false, "Bits that are on the edge of the shape should be set to false"); + CHECK_MESSAGE(bit_map.get_bitv(Point2i(125, 124)) == false, "Bits that are on the edge of the shape should be set to false"); + CHECK_MESSAGE(bit_map.get_bitv(Point2i(130, 124)) == false, "Bits that are on the edge of the shape should be set to false"); + bit_map.grow_mask(1, Rect2i(0, 0, 256, 256)); + CHECK(bit_map.get_true_bit_count() == 48); + CHECK_MESSAGE(bit_map.get_bitv(Point2i(125, 131)) == true, "Bits that were on the edge of the shape should now be set to true"); + CHECK_MESSAGE(bit_map.get_bitv(Point2i(131, 130)) == true, "Bits that were on the edge of the shape should now be set to true"); + CHECK_MESSAGE(bit_map.get_bitv(Point2i(125, 124)) == true, "Bits that were on the edge of the shape should now be set to true"); + CHECK_MESSAGE(bit_map.get_bitv(Point2i(130, 124)) == true, "Bits that were on the edge of the shape should now be set to true"); + + CHECK_MESSAGE(bit_map.get_bitv(Point2i(124, 124)) == false, "Bits that are on the edge of the shape should be set to false"); + CHECK_MESSAGE(bit_map.get_bitv(Point2i(126, 124)) == false, "Bits that are on the edge of the shape should be set to false"); + CHECK_MESSAGE(bit_map.get_bitv(Point2i(124, 131)) == false, "Bits that are on the edge of the shape should be set to false"); + CHECK_MESSAGE(bit_map.get_bitv(Point2i(131, 131)) == false, "Bits that are on the edge of the shape should be set to false"); +} + +TEST_CASE("[BitMap] Blit") { + Point2i blit_pos{ 128, 128 }; + Point2i bit_map_size{ 256, 256 }; + Point2i blit_size{ 32, 32 }; + + BitMap bit_map{}; + Ref<BitMap> blit_bit_map{}; + + // Testing null reference to blit bit map. + bit_map.blit(blit_pos, blit_bit_map); + + blit_bit_map.instantiate(); + + // Testing if uninitialised blit bit map and uninitialised bit map does not crash + bit_map.blit(blit_pos, blit_bit_map); + + // Testing if uninitialised bit map does not crash + blit_bit_map->create(blit_size); + bit_map.blit(blit_pos, blit_bit_map); + + // Testing if uninitialised bit map does not crash + blit_bit_map.unref(); + blit_bit_map.instantiate(); + CHECK_MESSAGE(blit_bit_map->get_size() == Point2i(0, 0), "Size should be cleared by unref and instance calls."); + bit_map.create(bit_map_size); + bit_map.blit(Point2i(128, 128), blit_bit_map); + + // Testing if both initialised does not crash. + blit_bit_map->create(blit_size); + bit_map.blit(blit_pos, blit_bit_map); + + bit_map.set_bit_rect(Rect2i{ 127, 127, 3, 3 }, true); + CHECK(bit_map.get_true_bit_count() == 9); + bit_map.blit(Point2i(112, 112), blit_bit_map); + CHECK_MESSAGE(bit_map.get_true_bit_count() == 9, "No bits should have been changed, as the blit bit map only contains falses"); + + bit_map.create(bit_map_size); + blit_bit_map->create(blit_size); + blit_bit_map->set_bit_rect(Rect2i(15, 15, 3, 3), true); + CHECK(blit_bit_map->get_true_bit_count() == 9); + + CHECK(bit_map.get_true_bit_count() == 0); + bit_map.blit(Point2i(112, 112), blit_bit_map); + CHECK_MESSAGE(bit_map.get_true_bit_count() == 9, "All true bits should have been moved to the bit map"); + for (int x = 127; x < 129; ++x) { + for (int y = 127; y < 129; ++y) { + CHECK_MESSAGE(bit_map.get_bitv(Point2i(x, y)) == true, "All true bits should have been moved to the bit map"); + } + } +} + +TEST_CASE("[BitMap] Convert to image") { + const Size2i dim{ 256, 256 }; + BitMap bit_map{}; + Ref<Image> img; + + img = bit_map.convert_to_image(); + CHECK_MESSAGE(img.is_valid(), "We should receive a valid Image Object even if BitMap is not created yet"); + CHECK_MESSAGE(img->get_format() == Image::FORMAT_L8, "We should receive a valid Image Object even if BitMap is not created yet"); + CHECK_MESSAGE(img->get_size() == (Size2i(0, 0)), "Image should have no width or height, because BitMap has not yet been created"); + + bit_map.create(dim); + img = bit_map.convert_to_image(); + CHECK_MESSAGE(img->get_size() == dim, "Image should have the same dimensions as the BitMap"); + CHECK_MESSAGE(img->get_pixel(0, 0).is_equal_approx(Color(0, 0, 0)), "BitMap is intialized to all 0's, so Image should be all black"); + + reset_bit_map(bit_map); + bit_map.set_bit_rect(Rect2i(0, 0, 128, 128), true); + img = bit_map.convert_to_image(); + CHECK_MESSAGE(img->get_pixel(0, 0).is_equal_approx(Color(1, 1, 1)), "BitMap's top-left quadrant is all 1's, so Image should be white"); + CHECK_MESSAGE(img->get_pixel(256, 256).is_equal_approx(Color(0, 0, 0)), "All other quadrants were 0's, so these should be black"); +} + +TEST_CASE("[BitMap] Clip to polygon") { + const Size2i dim{ 256, 256 }; + BitMap bit_map{}; + Vector<Vector<Vector2>> polygons; + + polygons = bit_map.clip_opaque_to_polygons(Rect2i(0, 0, 128, 128)); + CHECK_MESSAGE(polygons.size() == 0, "We should have no polygons, because the BitMap was not initialized"); + + bit_map.create(dim); + polygons = bit_map.clip_opaque_to_polygons(Rect2i(0, 0, 128, 128)); + CHECK_MESSAGE(polygons.size() == 0, "We should have no polygons, because the BitMap was all 0's"); + + reset_bit_map(bit_map); + bit_map.set_bit_rect(Rect2i(0, 0, 64, 64), true); + polygons = bit_map.clip_opaque_to_polygons(Rect2i(0, 0, 128, 128)); + CHECK_MESSAGE(polygons.size() == 1, "We should have exactly 1 polygon"); + CHECK_MESSAGE(polygons[0].size() == 4, "The polygon should have exactly 4 points"); + + reset_bit_map(bit_map); + bit_map.set_bit_rect(Rect2i(0, 0, 32, 32), true); + bit_map.set_bit_rect(Rect2i(64, 64, 32, 32), true); + polygons = bit_map.clip_opaque_to_polygons(Rect2i(0, 0, 128, 128)); + CHECK_MESSAGE(polygons.size() == 2, "We should have exactly 2 polygons"); + CHECK_MESSAGE(polygons[0].size() == 4, "The polygon should have exactly 4 points"); + CHECK_MESSAGE(polygons[1].size() == 4, "The polygon should have exactly 4 points"); + + reset_bit_map(bit_map); + bit_map.set_bit_rect(Rect2i(124, 112, 8, 32), true); + bit_map.set_bit_rect(Rect2i(112, 124, 32, 8), true); + polygons = bit_map.clip_opaque_to_polygons(Rect2i(0, 0, 256, 256)); + CHECK_MESSAGE(polygons.size() == 1, "We should have exactly 1 polygon"); + CHECK_MESSAGE(polygons[0].size() == 12, "The polygon should have exactly 12 points"); + + reset_bit_map(bit_map); + bit_map.set_bit_rect(Rect2i(124, 112, 8, 32), true); + bit_map.set_bit_rect(Rect2i(112, 124, 32, 8), true); + polygons = bit_map.clip_opaque_to_polygons(Rect2i(0, 0, 128, 128)); + CHECK_MESSAGE(polygons.size() == 1, "We should have exactly 1 polygon"); + CHECK_MESSAGE(polygons[0].size() == 6, "The polygon should have exactly 6 points"); +} + +} // namespace TestBitmap + +#endif // TEST_BIT_MAP_H diff --git a/tests/scene/test_code_edit.h b/tests/scene/test_code_edit.h index 4fc88f398f..3940bdb37a 100644 --- a/tests/scene/test_code_edit.h +++ b/tests/scene/test_code_edit.h @@ -3245,7 +3245,7 @@ TEST_CASE("[SceneTree][CodeEdit] symbol lookup") { code_edit->set_text("this is some text"); Point2 caret_pos = code_edit->get_caret_draw_pos(); - caret_pos.x += 58; + caret_pos.x += 60; SEND_GUI_MOUSE_BUTTON_EVENT(code_edit, caret_pos, MouseButton::NONE, MouseButton::NONE, Key::NONE); CHECK(code_edit->get_text_for_symbol_lookup() == "this is s" + String::chr(0xFFFF) + "ome text"); diff --git a/tests/scene/test_text_edit.h b/tests/scene/test_text_edit.h index 0fce359c5a..7550c12a0f 100644 --- a/tests/scene/test_text_edit.h +++ b/tests/scene/test_text_edit.h @@ -3388,6 +3388,8 @@ TEST_CASE("[SceneTree][TextEdit] gutters") { SUBCASE("[TextEdit] gutter add and remove") { text_edit->add_gutter(); CHECK(text_edit->get_gutter_count() == 1); + CHECK(text_edit->get_gutter_width(0) == 24); + CHECK(text_edit->get_total_gutter_width() == 24 + 2); SIGNAL_CHECK("gutter_added", empty_signal_args); text_edit->set_gutter_name(0, "test_gutter"); @@ -3395,39 +3397,43 @@ TEST_CASE("[SceneTree][TextEdit] gutters") { text_edit->set_gutter_width(0, 10); CHECK(text_edit->get_gutter_width(0) == 10); - CHECK(text_edit->get_total_gutter_width() > 10); - CHECK(text_edit->get_total_gutter_width() < 20); + CHECK(text_edit->get_total_gutter_width() == 10 + 2); text_edit->add_gutter(-100); text_edit->set_gutter_width(1, 10); - CHECK(text_edit->get_total_gutter_width() > 20); - CHECK(text_edit->get_total_gutter_width() < 30); + CHECK(text_edit->get_gutter_width(1) == 10); + CHECK(text_edit->get_total_gutter_width() == 20 + 2); CHECK(text_edit->get_gutter_count() == 2); CHECK(text_edit->get_gutter_name(0) == "test_gutter"); SIGNAL_CHECK("gutter_added", empty_signal_args); text_edit->set_gutter_draw(1, false); - CHECK(text_edit->get_total_gutter_width() > 10); - CHECK(text_edit->get_total_gutter_width() < 20); + CHECK(text_edit->get_total_gutter_width() == 10 + 2); text_edit->add_gutter(100); CHECK(text_edit->get_gutter_count() == 3); + CHECK(text_edit->get_gutter_width(2) == 24); + CHECK(text_edit->get_total_gutter_width() == 34 + 2); CHECK(text_edit->get_gutter_name(0) == "test_gutter"); SIGNAL_CHECK("gutter_added", empty_signal_args); text_edit->add_gutter(0); CHECK(text_edit->get_gutter_count() == 4); + CHECK(text_edit->get_gutter_width(0) == 24); + CHECK(text_edit->get_total_gutter_width() == 58 + 2); CHECK(text_edit->get_gutter_name(1) == "test_gutter"); SIGNAL_CHECK("gutter_added", empty_signal_args); text_edit->remove_gutter(2); CHECK(text_edit->get_gutter_name(1) == "test_gutter"); CHECK(text_edit->get_gutter_count() == 3); + CHECK(text_edit->get_total_gutter_width() == 58 + 2); SIGNAL_CHECK("gutter_removed", empty_signal_args); text_edit->remove_gutter(0); CHECK(text_edit->get_gutter_name(0) == "test_gutter"); CHECK(text_edit->get_gutter_count() == 2); + CHECK(text_edit->get_total_gutter_width() == 34 + 2); SIGNAL_CHECK("gutter_removed", empty_signal_args); ERR_PRINT_OFF; diff --git a/tests/test_main.cpp b/tests/test_main.cpp index a30d11342a..7712189e45 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -85,6 +85,7 @@ #include "tests/core/variant/test_variant.h" #include "tests/scene/test_animation.h" #include "tests/scene/test_audio_stream_wav.h" +#include "tests/scene/test_bit_map.h" #include "tests/scene/test_code_edit.h" #include "tests/scene/test_curve.h" #include "tests/scene/test_gradient.h" @@ -282,7 +283,7 @@ struct GodotTestCaseListener : public doctest::IReporter { if (RenderingServer::get_singleton()) { RenderingServer::get_singleton()->sync(); - RenderingServer::get_singleton()->global_shader_uniforms_clear(); + RenderingServer::get_singleton()->global_shader_parameters_clear(); RenderingServer::get_singleton()->finish(); memdelete(RenderingServer::get_singleton()); } |