diff options
Diffstat (limited to 'scene')
485 files changed, 5632 insertions, 3782 deletions
diff --git a/scene/2d/animated_sprite_2d.cpp b/scene/2d/animated_sprite_2d.cpp index fad4784d51..4916eb573c 100644 --- a/scene/2d/animated_sprite_2d.cpp +++ b/scene/2d/animated_sprite_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -122,13 +122,13 @@ void AnimatedSprite2D::_validate_property(PropertyInfo &property) const { } property.hint_string += String(E->get()); - if (animation == E) { + if (animation == E->get()) { current_found = true; } } if (!current_found) { - if (property.hint_string == String()) { + if (property.hint_string.is_empty()) { property.hint_string = String(animation); } else { property.hint_string = String(animation) + "," + property.hint_string; @@ -366,7 +366,7 @@ void AnimatedSprite2D::_res_changed() { update(); } -void AnimatedSprite2D::_set_playing(bool p_playing) { +void AnimatedSprite2D::set_playing(bool p_playing) { if (playing == p_playing) { return; } @@ -375,7 +375,7 @@ void AnimatedSprite2D::_set_playing(bool p_playing) { set_process_internal(playing); } -bool AnimatedSprite2D::_is_playing() const { +bool AnimatedSprite2D::is_playing() const { return playing; } @@ -389,15 +389,11 @@ void AnimatedSprite2D::play(const StringName &p_animation, const bool p_backward } } - _set_playing(true); + set_playing(true); } void AnimatedSprite2D::stop() { - _set_playing(false); -} - -bool AnimatedSprite2D::is_playing() const { - return playing; + set_playing(false); } double AnimatedSprite2D::_get_frame_duration() { @@ -455,12 +451,11 @@ void AnimatedSprite2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_animation", "animation"), &AnimatedSprite2D::set_animation); ClassDB::bind_method(D_METHOD("get_animation"), &AnimatedSprite2D::get_animation); - ClassDB::bind_method(D_METHOD("_set_playing", "playing"), &AnimatedSprite2D::_set_playing); - ClassDB::bind_method(D_METHOD("_is_playing"), &AnimatedSprite2D::_is_playing); + ClassDB::bind_method(D_METHOD("set_playing", "playing"), &AnimatedSprite2D::set_playing); + ClassDB::bind_method(D_METHOD("is_playing"), &AnimatedSprite2D::is_playing); ClassDB::bind_method(D_METHOD("play", "anim", "backwards"), &AnimatedSprite2D::play, DEFVAL(StringName()), DEFVAL(false)); ClassDB::bind_method(D_METHOD("stop"), &AnimatedSprite2D::stop); - ClassDB::bind_method(D_METHOD("is_playing"), &AnimatedSprite2D::is_playing); ClassDB::bind_method(D_METHOD("set_centered", "centered"), &AnimatedSprite2D::set_centered); ClassDB::bind_method(D_METHOD("is_centered"), &AnimatedSprite2D::is_centered); @@ -488,7 +483,7 @@ void AnimatedSprite2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "animation"), "set_animation", "get_animation"); ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "speed_scale"), "set_speed_scale", "get_speed_scale"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing"), "_set_playing", "_is_playing"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing"), "set_playing", "is_playing"); ADD_GROUP("Offset", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "centered"), "set_centered", "is_centered"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset"); diff --git a/scene/2d/animated_sprite_2d.h b/scene/2d/animated_sprite_2d.h index ac4b20a6d9..b3af931ea2 100644 --- a/scene/2d/animated_sprite_2d.h +++ b/scene/2d/animated_sprite_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -57,8 +57,6 @@ class AnimatedSprite2D : public Node2D { double _get_frame_duration(); void _reset_timeout(); - void _set_playing(bool p_playing); - bool _is_playing() const; Rect2 _get_rect() const; protected: @@ -85,6 +83,8 @@ public: void play(const StringName &p_animation = StringName(), const bool p_backwards = false); void stop(); + + void set_playing(bool p_playing); bool is_playing() const; void set_animation(const StringName &p_animation); diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index 8db1491953..70b9b769cd 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h index 98ba270a61..68047ccebf 100644 --- a/scene/2d/area_2d.h +++ b/scene/2d/area_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/audio_listener_2d.cpp b/scene/2d/audio_listener_2d.cpp index f16e359a1d..8fae339756 100644 --- a/scene/2d/audio_listener_2d.cpp +++ b/scene/2d/audio_listener_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/audio_listener_2d.h b/scene/2d/audio_listener_2d.h index 454053bc4a..172d388efc 100644 --- a/scene/2d/audio_listener_2d.h +++ b/scene/2d/audio_listener_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp index 8bf95e6965..a761d0d1ec 100644 --- a/scene/2d/audio_stream_player_2d.cpp +++ b/scene/2d/audio_stream_player_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/audio_stream_player_2d.h b/scene/2d/audio_stream_player_2d.h index 5360fd4934..73b09e432f 100644 --- a/scene/2d/audio_stream_player_2d.h +++ b/scene/2d/audio_stream_player_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/back_buffer_copy.cpp b/scene/2d/back_buffer_copy.cpp index 539a66b881..c411aaf411 100644 --- a/scene/2d/back_buffer_copy.cpp +++ b/scene/2d/back_buffer_copy.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/back_buffer_copy.h b/scene/2d/back_buffer_copy.h index 6bdb3aaab2..4e7cac1f3e 100644 --- a/scene/2d/back_buffer_copy.h +++ b/scene/2d/back_buffer_copy.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index b6902686fe..f4c0665f36 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h index d697515547..662bee3612 100644 --- a/scene/2d/camera_2d.h +++ b/scene/2d/camera_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/canvas_group.cpp b/scene/2d/canvas_group.cpp index ee025b6dfc..37a858330c 100644 --- a/scene/2d/canvas_group.cpp +++ b/scene/2d/canvas_group.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/canvas_group.h b/scene/2d/canvas_group.h index b487d7a098..9bc1772ee2 100644 --- a/scene/2d/canvas_group.h +++ b/scene/2d/canvas_group.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/canvas_modulate.cpp b/scene/2d/canvas_modulate.cpp index 4de99959a3..d0abed4a0c 100644 --- a/scene/2d/canvas_modulate.cpp +++ b/scene/2d/canvas_modulate.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/canvas_modulate.h b/scene/2d/canvas_modulate.h index 3d85a92a11..ec37449f8f 100644 --- a/scene/2d/canvas_modulate.h +++ b/scene/2d/canvas_modulate.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp index bd13d96b01..0f4e3c8bed 100644 --- a/scene/2d/collision_object_2d.cpp +++ b/scene/2d/collision_object_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/collision_object_2d.h b/scene/2d/collision_object_2d.h index 19abacb201..9463b2c429 100644 --- a/scene/2d/collision_object_2d.h +++ b/scene/2d/collision_object_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index 00bfa62449..2923b287be 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -164,15 +164,15 @@ void CollisionPolygon2D::_notification(int p_what) { dcol.a = 1.0; Vector2 line_to(0, 20); draw_line(Vector2(), line_to, dcol, 3); - Vector<Vector2> pts; real_t tsize = 8; - pts.push_back(line_to + (Vector2(0, tsize))); - pts.push_back(line_to + (Vector2(Math_SQRT12 * tsize, 0))); - pts.push_back(line_to + (Vector2(-Math_SQRT12 * tsize, 0))); - Vector<Color> cols; - for (int i = 0; i < 3; i++) { - cols.push_back(dcol); - } + + Vector<Vector2> pts = { + line_to + Vector2(0, tsize), + line_to + Vector2(Math_SQRT12 * tsize, 0), + line_to + Vector2(-Math_SQRT12 * tsize, 0) + }; + + Vector<Color> cols{ dcol, dcol, dcol }; draw_primitive(pts, cols, Vector<Vector2>()); //small arrow } diff --git a/scene/2d/collision_polygon_2d.h b/scene/2d/collision_polygon_2d.h index 6b32923010..e18022ab7e 100644 --- a/scene/2d/collision_polygon_2d.h +++ b/scene/2d/collision_polygon_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp index c7742c7ba5..a0520ca28f 100644 --- a/scene/2d/collision_shape_2d.cpp +++ b/scene/2d/collision_shape_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -121,15 +121,15 @@ void CollisionShape2D::_notification(int p_what) { } Vector2 line_to(0, 20); draw_line(Vector2(), line_to, draw_col, 2); - Vector<Vector2> pts; real_t tsize = 8; - pts.push_back(line_to + (Vector2(0, tsize))); - pts.push_back(line_to + (Vector2(Math_SQRT12 * tsize, 0))); - pts.push_back(line_to + (Vector2(-Math_SQRT12 * tsize, 0))); - Vector<Color> cols; - for (int i = 0; i < 3; i++) { - cols.push_back(draw_col); - } + + Vector<Vector2> pts{ + line_to + Vector2(0, tsize), + line_to + Vector2(Math_SQRT12 * tsize, 0), + line_to + Vector2(-Math_SQRT12 * tsize, 0) + }; + + Vector<Color> cols{ draw_col, draw_col, draw_col }; draw_primitive(pts, cols, Vector<Vector2>()); } diff --git a/scene/2d/collision_shape_2d.h b/scene/2d/collision_shape_2d.h index eaf72627c8..dbc81e8424 100644 --- a/scene/2d/collision_shape_2d.h +++ b/scene/2d/collision_shape_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index 8d997bb1f5..4673a99082 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -152,11 +152,14 @@ void CPUParticles2D::_update_mesh_texture() { } else { tex_size = Size2(1, 1); } - Vector<Vector2> vertices; - vertices.push_back(-tex_size * 0.5); - vertices.push_back(-tex_size * 0.5 + Vector2(tex_size.x, 0)); - vertices.push_back(-tex_size * 0.5 + tex_size); - vertices.push_back(-tex_size * 0.5 + Vector2(0, tex_size.y)); + + Vector<Vector2> vertices = { + -tex_size * 0.5, + -tex_size * 0.5 + Vector2(tex_size.x, 0), + -tex_size * 0.5 + tex_size, + -tex_size * 0.5 + Vector2(0, tex_size.y) + }; + Vector<Vector2> uvs; AtlasTexture *atlas_texure = Object::cast_to<AtlasTexture>(*texture); if (atlas_texure && atlas_texure->get_atlas().is_valid()) { @@ -172,18 +175,15 @@ void CPUParticles2D::_update_mesh_texture() { uvs.push_back(Vector2(1, 1)); uvs.push_back(Vector2(0, 1)); } - Vector<Color> colors; - colors.push_back(Color(1, 1, 1, 1)); - colors.push_back(Color(1, 1, 1, 1)); - colors.push_back(Color(1, 1, 1, 1)); - colors.push_back(Color(1, 1, 1, 1)); - Vector<int> indices; - indices.push_back(0); - indices.push_back(1); - indices.push_back(2); - indices.push_back(2); - indices.push_back(3); - indices.push_back(0); + + Vector<Color> colors = { + Color(1, 1, 1, 1), + Color(1, 1, 1, 1), + Color(1, 1, 1, 1), + Color(1, 1, 1, 1) + }; + + Vector<int> indices = { 0, 1, 2, 2, 3, 0 }; Array arr; arr.resize(RS::ARRAY_MAX); @@ -398,6 +398,14 @@ Ref<Gradient> CPUParticles2D::get_color_ramp() const { return color_ramp; } +void CPUParticles2D::set_color_initial_ramp(const Ref<Gradient> &p_ramp) { + color_initial_ramp = p_ramp; +} + +Ref<Gradient> CPUParticles2D::get_color_initial_ramp() const { + return color_initial_ramp; +} + void CPUParticles2D::set_particle_flag(ParticleFlags p_particle_flag, bool p_enable) { ERR_FAIL_INDEX(p_particle_flag, PARTICLE_FLAG_MAX); particle_flags[p_particle_flag] = p_enable; @@ -727,9 +735,15 @@ void CPUParticles2D::_particles_process(double p_delta) { p.hue_rot_rand = Math::randf(); p.anim_offset_rand = Math::randf(); + if (color_initial_ramp.is_valid()) { + p.start_color_rand = color_initial_ramp->get_color_at_offset(Math::randf()); + } else { + p.start_color_rand = Color(1, 1, 1, 1); + } + real_t angle1_rad = direction.angle() + Math::deg2rad((Math::randf() * 2.0 - 1.0) * spread); Vector2 rot = Vector2(Math::cos(angle1_rad), Math::sin(angle1_rad)); - p.velocity = rot * Math::lerp(parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], Math::randf()); + p.velocity = rot * Math::lerp(parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], (real_t)Math::randf()); real_t base_angle = tex_angle * Math::lerp(parameters_min[PARAM_ANGLE], parameters_max[PARAM_ANGLE], p.angle_rand); p.rotation = Math::deg2rad(base_angle); @@ -946,7 +960,7 @@ void CPUParticles2D::_particles_process(double p_delta) { p.color.g = color_rgb.y; p.color.b = color_rgb.z; - p.color *= p.base_color; + p.color *= p.base_color * p.start_color_rand; if (particle_flags[PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY]) { if (p.velocity.length() > 0.0) { @@ -1173,6 +1187,11 @@ void CPUParticles2D::convert_from_particles(Node *p_particles) { set_color_ramp(gt->get_gradient()); } + Ref<GradientTexture1D> gti = material->get_color_initial_ramp(); + if (gti.is_valid()) { + set_color_initial_ramp(gti->get_gradient()); + } + set_particle_flag(PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY, material->get_particle_flag(ParticlesMaterial::PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY)); set_emission_shape(EmissionShape(material->get_emission_shape())); @@ -1295,6 +1314,9 @@ void CPUParticles2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_color_ramp", "ramp"), &CPUParticles2D::set_color_ramp); ClassDB::bind_method(D_METHOD("get_color_ramp"), &CPUParticles2D::get_color_ramp); + ClassDB::bind_method(D_METHOD("set_color_initial_ramp", "ramp"), &CPUParticles2D::set_color_initial_ramp); + ClassDB::bind_method(D_METHOD("get_color_initial_ramp"), &CPUParticles2D::get_color_initial_ramp); + ClassDB::bind_method(D_METHOD("set_particle_flag", "particle_flag", "enable"), &CPUParticles2D::set_particle_flag); ClassDB::bind_method(D_METHOD("get_particle_flag", "particle_flag"), &CPUParticles2D::get_particle_flag); @@ -1386,6 +1408,7 @@ void CPUParticles2D::_bind_methods() { ADD_GROUP("Color", ""); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_color_ramp", "get_color_ramp"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_initial_ramp", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_color_initial_ramp", "get_color_initial_ramp"); ADD_GROUP("Hue Variation", "hue_"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation_min", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param_min", "get_param_min", PARAM_HUE_VARIATION); diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h index 391f51224e..8c8f161d74 100644 --- a/scene/2d/cpu_particles_2d.h +++ b/scene/2d/cpu_particles_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -89,6 +89,7 @@ private: real_t scale_rand = 0.0; real_t hue_rot_rand = 0.0; real_t anim_offset_rand = 0.0; + Color start_color_rand; double time = 0.0; double lifetime = 0.0; Color base_color; @@ -156,6 +157,7 @@ private: Ref<Curve> curve_parameters[PARAM_MAX]; Color color; Ref<Gradient> color_ramp; + Ref<Gradient> color_initial_ramp; bool particle_flags[PARTICLE_FLAG_MAX]; @@ -250,6 +252,9 @@ public: void set_color_ramp(const Ref<Gradient> &p_ramp); Ref<Gradient> get_color_ramp() const; + void set_color_initial_ramp(const Ref<Gradient> &p_ramp); + Ref<Gradient> get_color_initial_ramp() const; + void set_particle_flag(ParticleFlags p_particle_flag, bool p_enable); bool get_particle_flag(ParticleFlags p_particle_flag) const; diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp index 4384ec8141..b6d1e5c934 100644 --- a/scene/2d/gpu_particles_2d.cpp +++ b/scene/2d/gpu_particles_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -427,26 +427,23 @@ void GPUParticles2D::_notification(int p_what) { } else { RS::get_singleton()->mesh_clear(mesh); - Vector<Vector2> points; - points.resize(4); - points.write[0] = Vector2(-size.x / 2.0, -size.y / 2.0); - points.write[1] = Vector2(size.x / 2.0, -size.y / 2.0); - points.write[2] = Vector2(size.x / 2.0, size.y / 2.0); - points.write[3] = Vector2(-size.x / 2.0, size.y / 2.0); - Vector<Vector2> uvs; - uvs.resize(4); - uvs.write[0] = Vector2(0, 0); - uvs.write[1] = Vector2(1, 0); - uvs.write[2] = Vector2(1, 1); - uvs.write[3] = Vector2(0, 1); - Vector<int> indices; - indices.resize(6); - indices.write[0] = 0; - indices.write[1] = 1; - indices.write[2] = 2; - indices.write[3] = 0; - indices.write[4] = 2; - indices.write[5] = 3; + + Vector<Vector2> points = { + Vector2(-size.x / 2.0, -size.y / 2.0), + Vector2(size.x / 2.0, -size.y / 2.0), + Vector2(size.x / 2.0, size.y / 2.0), + Vector2(-size.x / 2.0, size.y / 2.0) + }; + + Vector<Vector2> uvs = { + Vector2(0, 0), + Vector2(1, 0), + Vector2(1, 1), + Vector2(0, 1) + }; + + Vector<int> indices = { 0, 1, 2, 0, 2, 3 }; + Array arr; arr.resize(RS::ARRAY_MAX); arr[RS::ARRAY_VERTEX] = points; diff --git a/scene/2d/gpu_particles_2d.h b/scene/2d/gpu_particles_2d.h index a9e66b3051..aa9a8da129 100644 --- a/scene/2d/gpu_particles_2d.h +++ b/scene/2d/gpu_particles_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/joint_2d.cpp b/scene/2d/joint_2d.cpp index 8a528151cf..62a77fb969 100644 --- a/scene/2d/joint_2d.cpp +++ b/scene/2d/joint_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/joint_2d.h b/scene/2d/joint_2d.h index 0c3956e463..e3cd600cbd 100644 --- a/scene/2d/joint_2d.h +++ b/scene/2d/joint_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index 66c0f979ae..f496e1aac2 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h index d9ecd81f1c..f7b1f420e3 100644 --- a/scene/2d/light_2d.h +++ b/scene/2d/light_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp index fdc28f81c2..0a7e4c8841 100644 --- a/scene/2d/light_occluder_2d.cpp +++ b/scene/2d/light_occluder_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/light_occluder_2d.h b/scene/2d/light_occluder_2d.h index b4a48d1062..4f8c6d20df 100644 --- a/scene/2d/light_occluder_2d.h +++ b/scene/2d/light_occluder_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp index 00767ec22c..1a6aaecaa8 100644 --- a/scene/2d/line_2d.cpp +++ b/scene/2d/line_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/line_2d.h b/scene/2d/line_2d.h index 5e7eb4bac9..5322c5a5fe 100644 --- a/scene/2d/line_2d.h +++ b/scene/2d/line_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/line_builder.cpp b/scene/2d/line_builder.cpp index 05d77f8224..25eb9b9851 100644 --- a/scene/2d/line_builder.cpp +++ b/scene/2d/line_builder.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/line_builder.h b/scene/2d/line_builder.h index 16c88d00e9..e50acc9ce4 100644 --- a/scene/2d/line_builder.h +++ b/scene/2d/line_builder.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/mesh_instance_2d.cpp b/scene/2d/mesh_instance_2d.cpp index 58bff97da9..5f8a46ad2e 100644 --- a/scene/2d/mesh_instance_2d.cpp +++ b/scene/2d/mesh_instance_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/mesh_instance_2d.h b/scene/2d/mesh_instance_2d.h index f94d53da7d..0647d1ddd9 100644 --- a/scene/2d/mesh_instance_2d.h +++ b/scene/2d/mesh_instance_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/multimesh_instance_2d.cpp b/scene/2d/multimesh_instance_2d.cpp index 1bff2f337d..e1af99d931 100644 --- a/scene/2d/multimesh_instance_2d.cpp +++ b/scene/2d/multimesh_instance_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/multimesh_instance_2d.h b/scene/2d/multimesh_instance_2d.h index 213cbd19b0..37d0d24f8f 100644 --- a/scene/2d/multimesh_instance_2d.h +++ b/scene/2d/multimesh_instance_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp index 7faa964407..9331f2dccb 100644 --- a/scene/2d/navigation_agent_2d.cpp +++ b/scene/2d/navigation_agent_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -241,7 +241,7 @@ TypedArray<String> NavigationAgent2D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (!Object::cast_to<Node2D>(get_parent())) { - warnings.push_back(TTR("The NavigationAgent2D can be used only under a Node2D node")); + warnings.push_back(TTR("The NavigationAgent2D can be used only under a Node2D node.")); } return warnings; diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation_agent_2d.h index 052cd78a56..dcedc6506a 100644 --- a/scene/2d/navigation_agent_2d.h +++ b/scene/2d/navigation_agent_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/navigation_obstacle_2d.cpp b/scene/2d/navigation_obstacle_2d.cpp index 8802a1098a..e5df089771 100644 --- a/scene/2d/navigation_obstacle_2d.cpp +++ b/scene/2d/navigation_obstacle_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/navigation_obstacle_2d.h b/scene/2d/navigation_obstacle_2d.h index a5603f059f..2a0ef14e73 100644 --- a/scene/2d/navigation_obstacle_2d.h +++ b/scene/2d/navigation_obstacle_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp index ecd79c23a7..34f5830d8d 100644 --- a/scene/2d/navigation_region_2d.cpp +++ b/scene/2d/navigation_region_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -363,10 +363,10 @@ void NavigationRegion2D::set_enabled(bool p_enabled) { if (!enabled) { NavigationServer2D::get_singleton()->region_set_map(region, RID()); - NavigationServer2D::get_singleton()->disconnect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed)); + NavigationServer2D::get_singleton_mut()->disconnect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed)); } else { NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map()); - NavigationServer2D::get_singleton()->connect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed)); + NavigationServer2D::get_singleton_mut()->connect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed)); } if (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()) { @@ -402,7 +402,7 @@ void NavigationRegion2D::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: { if (enabled) { NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map()); - NavigationServer2D::get_singleton()->connect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed)); + NavigationServer2D::get_singleton_mut()->connect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed)); } } break; case NOTIFICATION_TRANSFORM_CHANGED: { @@ -411,7 +411,7 @@ void NavigationRegion2D::_notification(int p_what) { case NOTIFICATION_EXIT_TREE: { NavigationServer2D::get_singleton()->region_set_map(region, RID()); if (enabled) { - NavigationServer2D::get_singleton()->disconnect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed)); + NavigationServer2D::get_singleton_mut()->disconnect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed)); } } break; case NOTIFICATION_DRAW: { diff --git a/scene/2d/navigation_region_2d.h b/scene/2d/navigation_region_2d.h index 2db8d70791..012debb584 100644 --- a/scene/2d/navigation_region_2d.h +++ b/scene/2d/navigation_region_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index 6a8788ee6e..9331340e1b 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -42,9 +42,9 @@ Dictionary Node2D::_edit_get_state() const { } void Node2D::_edit_set_state(const Dictionary &p_state) { - pos = p_state["position"]; - angle = p_state["rotation"]; - _scale = p_state["scale"]; + position = p_state["position"]; + rotation = p_state["rotation"]; + scale = p_state["scale"]; skew = p_state["skew"]; _update_transform(); @@ -55,7 +55,7 @@ void Node2D::_edit_set_position(const Point2 &p_position) { } Point2 Node2D::_edit_get_position() const { - return pos; + return position; } void Node2D::_edit_set_scale(const Size2 &p_scale) { @@ -63,16 +63,16 @@ void Node2D::_edit_set_scale(const Size2 &p_scale) { } Size2 Node2D::_edit_get_scale() const { - return _scale; + return scale; } void Node2D::_edit_set_rotation(real_t p_rotation) { - angle = p_rotation; + rotation = p_rotation; _update_transform(); } real_t Node2D::_edit_get_rotation() const { - return angle; + return rotation; } bool Node2D::_edit_use_rotation() const { @@ -85,48 +85,44 @@ void Node2D::_edit_set_rect(const Rect2 &p_edit_rect) { Rect2 r = _edit_get_rect(); Vector2 zero_offset; - if (r.size.x != 0) { - zero_offset.x = -r.position.x / r.size.x; - } - if (r.size.y != 0) { - zero_offset.y = -r.position.y / r.size.y; - } - Size2 new_scale(1, 1); if (r.size.x != 0) { + zero_offset.x = -r.position.x / r.size.x; new_scale.x = p_edit_rect.size.x / r.size.x; } + if (r.size.y != 0) { + zero_offset.y = -r.position.y / r.size.y; new_scale.y = p_edit_rect.size.y / r.size.y; } Point2 new_pos = p_edit_rect.position + p_edit_rect.size * zero_offset; Transform2D postxf; - postxf.set_rotation_scale_and_skew(angle, _scale, skew); + postxf.set_rotation_scale_and_skew(rotation, scale, skew); new_pos = postxf.xform(new_pos); - pos += new_pos; - _scale *= new_scale; + position += new_pos; + scale *= new_scale; _update_transform(); } #endif void Node2D::_update_xform_values() { - pos = _mat.elements[2]; - angle = _mat.get_rotation(); - _scale = _mat.get_scale(); - skew = _mat.get_skew(); + position = transform.elements[2]; + rotation = transform.get_rotation(); + scale = transform.get_scale(); + skew = transform.get_skew(); _xform_dirty = false; } void Node2D::_update_transform() { - _mat.set_rotation_scale_and_skew(angle, _scale, skew); - _mat.elements[2] = pos; + transform.set_rotation_scale_and_skew(rotation, scale, skew); + transform.elements[2] = position; - RenderingServer::get_singleton()->canvas_item_set_transform(get_canvas_item(), _mat); + RenderingServer::get_singleton()->canvas_item_set_transform(get_canvas_item(), transform); if (!is_inside_tree()) { return; @@ -139,7 +135,7 @@ void Node2D::set_position(const Point2 &p_pos) { if (_xform_dirty) { ((Node2D *)this)->_update_xform_values(); } - pos = p_pos; + position = p_pos; _update_transform(); } @@ -147,7 +143,7 @@ void Node2D::set_rotation(real_t p_radians) { if (_xform_dirty) { ((Node2D *)this)->_update_xform_values(); } - angle = p_radians; + rotation = p_radians; _update_transform(); } @@ -163,13 +159,13 @@ void Node2D::set_scale(const Size2 &p_scale) { if (_xform_dirty) { ((Node2D *)this)->_update_xform_values(); } - _scale = p_scale; + scale = p_scale; // Avoid having 0 scale values, can lead to errors in physics and rendering. - if (Math::is_zero_approx(_scale.x)) { - _scale.x = CMP_EPSILON; + if (Math::is_zero_approx(scale.x)) { + scale.x = CMP_EPSILON; } - if (Math::is_zero_approx(_scale.y)) { - _scale.y = CMP_EPSILON; + if (Math::is_zero_approx(scale.y)) { + scale.y = CMP_EPSILON; } _update_transform(); } @@ -178,7 +174,7 @@ Point2 Node2D::get_position() const { if (_xform_dirty) { ((Node2D *)this)->_update_xform_values(); } - return pos; + return position; } real_t Node2D::get_rotation() const { @@ -186,7 +182,7 @@ real_t Node2D::get_rotation() const { ((Node2D *)this)->_update_xform_values(); } - return angle; + return rotation; } real_t Node2D::get_skew() const { @@ -202,11 +198,11 @@ Size2 Node2D::get_scale() const { ((Node2D *)this)->_update_xform_values(); } - return _scale; + return scale; } Transform2D Node2D::get_transform() const { - return _mat; + return transform; } void Node2D::rotate(real_t p_radians) { @@ -287,10 +283,10 @@ void Node2D::set_global_scale(const Size2 &p_scale) { } void Node2D::set_transform(const Transform2D &p_transform) { - _mat = p_transform; + transform = p_transform; _xform_dirty = true; - RenderingServer::get_singleton()->canvas_item_set_transform(get_canvas_item(), _mat); + RenderingServer::get_singleton()->canvas_item_set_transform(get_canvas_item(), transform); if (!is_inside_tree()) { return; diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h index 3e66541e32..69d14f82ad 100644 --- a/scene/2d/node_2d.h +++ b/scene/2d/node_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -36,15 +36,15 @@ class Node2D : public CanvasItem { GDCLASS(Node2D, CanvasItem); - Point2 pos; - real_t angle = 0.0; - Size2 _scale = Vector2(1, 1); + Point2 position; + real_t rotation = 0.0; + Size2 scale = Vector2(1, 1); real_t skew = 0.0; int z_index = 0; bool z_relative = true; bool y_sort_enabled = false; - Transform2D _mat; + Transform2D transform; bool _xform_dirty = false; diff --git a/scene/2d/parallax_background.cpp b/scene/2d/parallax_background.cpp index 4870ae614b..f75baaab0f 100644 --- a/scene/2d/parallax_background.cpp +++ b/scene/2d/parallax_background.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/parallax_background.h b/scene/2d/parallax_background.h index 3745c5b587..1a3cb43999 100644 --- a/scene/2d/parallax_background.h +++ b/scene/2d/parallax_background.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/parallax_layer.cpp b/scene/2d/parallax_layer.cpp index 797e2e59cb..ff572c9b9a 100644 --- a/scene/2d/parallax_layer.cpp +++ b/scene/2d/parallax_layer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/parallax_layer.h b/scene/2d/parallax_layer.h index cc2d2e096e..b4dcf0ea61 100644 --- a/scene/2d/parallax_layer.h +++ b/scene/2d/parallax_layer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index 40211f2a9b..742756113f 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -93,6 +93,10 @@ void Path2D::_notification(int p_what) { return; } + if (curve->get_point_count() < 2) { + return; + } + #ifdef TOOLS_ENABLED const real_t line_width = 2 * EDSCALE; #else diff --git a/scene/2d/path_2d.h b/scene/2d/path_2d.h index 7e8478283f..bc55f84831 100644 --- a/scene/2d/path_2d.h +++ b/scene/2d/path_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/physical_bone_2d.cpp b/scene/2d/physical_bone_2d.cpp index c1b0bc35dd..1fc4b651d8 100644 --- a/scene/2d/physical_bone_2d.cpp +++ b/scene/2d/physical_bone_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/physical_bone_2d.h b/scene/2d/physical_bone_2d.h index 8b41f75c3e..9f31c22031 100644 --- a/scene/2d/physical_bone_2d.h +++ b/scene/2d/physical_bone_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index f0e51097db..b2cc8164b6 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -809,32 +809,44 @@ void RigidDynamicBody2D::apply_torque_impulse(real_t p_torque) { PhysicsServer2D::get_singleton()->body_apply_torque_impulse(get_rid(), p_torque); } -void RigidDynamicBody2D::set_applied_force(const Vector2 &p_force) { - PhysicsServer2D::get_singleton()->body_set_applied_force(get_rid(), p_force); -}; +void RigidDynamicBody2D::apply_central_force(const Vector2 &p_force) { + PhysicsServer2D::get_singleton()->body_apply_central_force(get_rid(), p_force); +} -Vector2 RigidDynamicBody2D::get_applied_force() const { - return PhysicsServer2D::get_singleton()->body_get_applied_force(get_rid()); -}; +void RigidDynamicBody2D::apply_force(const Vector2 &p_force, const Vector2 &p_position) { + PhysicsServer2D::get_singleton()->body_apply_force(get_rid(), p_force, p_position); +} -void RigidDynamicBody2D::set_applied_torque(const real_t p_torque) { - PhysicsServer2D::get_singleton()->body_set_applied_torque(get_rid(), p_torque); -}; +void RigidDynamicBody2D::apply_torque(real_t p_torque) { + PhysicsServer2D::get_singleton()->body_apply_torque(get_rid(), p_torque); +} -real_t RigidDynamicBody2D::get_applied_torque() const { - return PhysicsServer2D::get_singleton()->body_get_applied_torque(get_rid()); -}; +void RigidDynamicBody2D::add_constant_central_force(const Vector2 &p_force) { + PhysicsServer2D::get_singleton()->body_add_constant_central_force(get_rid(), p_force); +} -void RigidDynamicBody2D::add_central_force(const Vector2 &p_force) { - PhysicsServer2D::get_singleton()->body_add_central_force(get_rid(), p_force); +void RigidDynamicBody2D::add_constant_force(const Vector2 &p_force, const Vector2 &p_position) { + PhysicsServer2D::get_singleton()->body_add_constant_force(get_rid(), p_force, p_position); } -void RigidDynamicBody2D::add_force(const Vector2 &p_force, const Vector2 &p_position) { - PhysicsServer2D::get_singleton()->body_add_force(get_rid(), p_force, p_position); +void RigidDynamicBody2D::add_constant_torque(const real_t p_torque) { + PhysicsServer2D::get_singleton()->body_add_constant_torque(get_rid(), p_torque); } -void RigidDynamicBody2D::add_torque(const real_t p_torque) { - PhysicsServer2D::get_singleton()->body_add_torque(get_rid(), p_torque); +void RigidDynamicBody2D::set_constant_force(const Vector2 &p_force) { + PhysicsServer2D::get_singleton()->body_set_constant_force(get_rid(), p_force); +} + +Vector2 RigidDynamicBody2D::get_constant_force() const { + return PhysicsServer2D::get_singleton()->body_get_constant_force(get_rid()); +} + +void RigidDynamicBody2D::set_constant_torque(real_t p_torque) { + PhysicsServer2D::get_singleton()->body_set_constant_torque(get_rid(), p_torque); +} + +real_t RigidDynamicBody2D::get_constant_torque() const { + return PhysicsServer2D::get_singleton()->body_get_constant_torque(get_rid()); } void RigidDynamicBody2D::set_continuous_collision_detection_mode(CCDMode p_mode) { @@ -979,15 +991,19 @@ void RigidDynamicBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("apply_impulse", "impulse", "position"), &RigidDynamicBody2D::apply_impulse, Vector2()); ClassDB::bind_method(D_METHOD("apply_torque_impulse", "torque"), &RigidDynamicBody2D::apply_torque_impulse); - ClassDB::bind_method(D_METHOD("set_applied_force", "force"), &RigidDynamicBody2D::set_applied_force); - ClassDB::bind_method(D_METHOD("get_applied_force"), &RigidDynamicBody2D::get_applied_force); + ClassDB::bind_method(D_METHOD("apply_central_force", "force"), &RigidDynamicBody2D::apply_central_force); + ClassDB::bind_method(D_METHOD("apply_force", "force", "position"), &RigidDynamicBody2D::apply_force, Vector2()); + ClassDB::bind_method(D_METHOD("apply_torque", "torque"), &RigidDynamicBody2D::apply_torque); + + ClassDB::bind_method(D_METHOD("add_constant_central_force", "force"), &RigidDynamicBody2D::add_constant_central_force); + ClassDB::bind_method(D_METHOD("add_constant_force", "force", "position"), &RigidDynamicBody2D::add_constant_force, Vector2()); + ClassDB::bind_method(D_METHOD("add_constant_torque", "torque"), &RigidDynamicBody2D::add_constant_torque); - ClassDB::bind_method(D_METHOD("set_applied_torque", "torque"), &RigidDynamicBody2D::set_applied_torque); - ClassDB::bind_method(D_METHOD("get_applied_torque"), &RigidDynamicBody2D::get_applied_torque); + ClassDB::bind_method(D_METHOD("set_constant_force", "force"), &RigidDynamicBody2D::set_constant_force); + ClassDB::bind_method(D_METHOD("get_constant_force"), &RigidDynamicBody2D::get_constant_force); - ClassDB::bind_method(D_METHOD("add_central_force", "force"), &RigidDynamicBody2D::add_central_force); - ClassDB::bind_method(D_METHOD("add_force", "force", "position"), &RigidDynamicBody2D::add_force, Vector2()); - ClassDB::bind_method(D_METHOD("add_torque", "torque"), &RigidDynamicBody2D::add_torque); + ClassDB::bind_method(D_METHOD("set_constant_torque", "torque"), &RigidDynamicBody2D::set_constant_torque); + ClassDB::bind_method(D_METHOD("get_constant_torque"), &RigidDynamicBody2D::get_constant_torque); ClassDB::bind_method(D_METHOD("set_sleeping", "sleeping"), &RigidDynamicBody2D::set_sleeping); ClassDB::bind_method(D_METHOD("is_sleeping"), &RigidDynamicBody2D::is_sleeping); @@ -1032,9 +1048,9 @@ void RigidDynamicBody2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_velocity"), "set_angular_velocity", "get_angular_velocity"); ADD_PROPERTY(PropertyInfo(Variant::INT, "angular_damp_mode", PROPERTY_HINT_ENUM, "Combine,Replace"), "set_angular_damp_mode", "get_angular_damp_mode"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); - ADD_GROUP("Applied Forces", "applied_"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "applied_force"), "set_applied_force", "get_applied_force"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "applied_torque"), "set_applied_torque", "get_applied_torque"); + ADD_GROUP("Constant Forces", "constant_"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "constant_force"), "set_constant_force", "get_constant_force"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "constant_torque"), "set_constant_torque", "get_constant_torque"); ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape_index"), PropertyInfo(Variant::INT, "local_shape_index"))); ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape_index"), PropertyInfo(Variant::INT, "local_shape_index"))); diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index 2abce4b0a5..649d67d759 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -292,15 +292,19 @@ public: void apply_impulse(const Vector2 &p_impulse, const Vector2 &p_position = Vector2()); void apply_torque_impulse(real_t p_torque); - void set_applied_force(const Vector2 &p_force); - Vector2 get_applied_force() const; + void apply_central_force(const Vector2 &p_force); + void apply_force(const Vector2 &p_force, const Vector2 &p_position = Vector2()); + void apply_torque(real_t p_torque); - void set_applied_torque(const real_t p_torque); - real_t get_applied_torque() const; + void add_constant_central_force(const Vector2 &p_force); + void add_constant_force(const Vector2 &p_force, const Vector2 &p_position = Vector2()); + void add_constant_torque(real_t p_torque); - void add_central_force(const Vector2 &p_force); - void add_force(const Vector2 &p_force, const Vector2 &p_position = Vector2()); - void add_torque(real_t p_torque); + void set_constant_force(const Vector2 &p_force); + Vector2 get_constant_force() const; + + void set_constant_torque(real_t p_torque); + real_t get_constant_torque() const; TypedArray<Node2D> get_colliding_bodies() const; //function for script diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp index 7a237bf557..1f4dec6864 100644 --- a/scene/2d/polygon_2d.cpp +++ b/scene/2d/polygon_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -662,7 +662,7 @@ void Polygon2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "uv"), "set_uv", "get_uv"); ADD_PROPERTY(PropertyInfo(Variant::PACKED_COLOR_ARRAY, "vertex_colors"), "set_vertex_colors", "get_vertex_colors"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "polygons"), "set_polygons", "get_polygons"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bones", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "_set_bones", "_get_bones"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "bones", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "_set_bones", "_get_bones"); ADD_PROPERTY(PropertyInfo(Variant::INT, "internal_vertex_count", PROPERTY_HINT_RANGE, "0,1000"), "set_internal_vertex_count", "get_internal_vertex_count"); } diff --git a/scene/2d/polygon_2d.h b/scene/2d/polygon_2d.h index bf386b9ace..d6a1be0f6d 100644 --- a/scene/2d/polygon_2d.h +++ b/scene/2d/polygon_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/position_2d.cpp b/scene/2d/position_2d.cpp index 4f053ff8b0..67aff9c520 100644 --- a/scene/2d/position_2d.cpp +++ b/scene/2d/position_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -36,37 +36,41 @@ void Position2D::_draw_cross() { const real_t extents = get_gizmo_extents(); // Add more points to create a "hard stop" in the color gradient. - PackedVector2Array points_x; - points_x.push_back(Point2(+extents, 0)); - points_x.push_back(Point2()); - points_x.push_back(Point2()); - points_x.push_back(Point2(-extents, 0)); - - PackedVector2Array points_y; - points_y.push_back(Point2(0, +extents)); - points_y.push_back(Point2()); - points_y.push_back(Point2()); - points_y.push_back(Point2(0, -extents)); + PackedVector2Array points_x = { + Point2(+extents, 0), + Point2(), + Point2(), + Point2(-extents, 0) + }; + + PackedVector2Array points_y = { + Point2(0, +extents), + Point2(), + Point2(), + Point2(0, -extents) + }; // Use the axis color which is brighter for the positive axis. // Use a darkened axis color for the negative axis. // This makes it possible to see in which direction the Position3D node is rotated // (which can be important depending on how it's used). // Axis colors are taken from `axis_x_color` and `axis_y_color` (defined in `editor/editor_themes.cpp`). - PackedColorArray colors_x; const Color color_x = Color(0.96, 0.20, 0.32); - colors_x.push_back(color_x); - colors_x.push_back(color_x); - colors_x.push_back(color_x.lerp(Color(0, 0, 0), 0.5)); - colors_x.push_back(color_x.lerp(Color(0, 0, 0), 0.5)); + PackedColorArray colors_x = { + color_x, + color_x, + color_x.lerp(Color(0, 0, 0), 0.5), + color_x.lerp(Color(0, 0, 0), 0.5) + }; draw_multiline_colors(points_x, colors_x); - PackedColorArray colors_y; const Color color_y = Color(0.53, 0.84, 0.01); - colors_y.push_back(color_y); - colors_y.push_back(color_y); - colors_y.push_back(color_y.lerp(Color(0, 0, 0), 0.5)); - colors_y.push_back(color_y.lerp(Color(0, 0, 0), 0.5)); + PackedColorArray colors_y = { + color_y, + color_y, + color_y.lerp(Color(0, 0, 0), 0.5), + color_y.lerp(Color(0, 0, 0), 0.5) + }; draw_multiline_colors(points_y, colors_y); } diff --git a/scene/2d/position_2d.h b/scene/2d/position_2d.h index 9ed622c8f6..4ef07eb05c 100644 --- a/scene/2d/position_2d.h +++ b/scene/2d/position_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp index f9830a8743..1fdd8b05a6 100644 --- a/scene/2d/ray_cast_2d.cpp +++ b/scene/2d/ray_cast_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -244,15 +244,13 @@ void RayCast2D::_draw_debug_shape() { xf.rotate(target_position.angle()); xf.translate(Vector2(no_line ? 0 : target_position.length() - arrow_size, 0)); - Vector<Vector2> pts; - pts.push_back(xf.xform(Vector2(arrow_size, 0))); - pts.push_back(xf.xform(Vector2(0, 0.5 * arrow_size))); - pts.push_back(xf.xform(Vector2(0, -0.5 * arrow_size))); + Vector<Vector2> pts = { + xf.xform(Vector2(arrow_size, 0)), + xf.xform(Vector2(0, 0.5 * arrow_size)), + xf.xform(Vector2(0, -0.5 * arrow_size)) + }; - Vector<Color> cols; - for (int i = 0; i < 3; i++) { - cols.push_back(draw_col); - } + Vector<Color> cols = { draw_col, draw_col, draw_col }; draw_primitive(pts, cols, Vector<Vector2>()); } diff --git a/scene/2d/ray_cast_2d.h b/scene/2d/ray_cast_2d.h index 3ee09fad32..a1015c6ce0 100644 --- a/scene/2d/ray_cast_2d.h +++ b/scene/2d/ray_cast_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/remote_transform_2d.cpp b/scene/2d/remote_transform_2d.cpp index fe3e867424..e9431efde3 100644 --- a/scene/2d/remote_transform_2d.cpp +++ b/scene/2d/remote_transform_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/remote_transform_2d.h b/scene/2d/remote_transform_2d.h index 36fddb58c7..bd352e1054 100644 --- a/scene/2d/remote_transform_2d.h +++ b/scene/2d/remote_transform_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/shape_cast_2d.cpp b/scene/2d/shape_cast_2d.cpp index 50b44eb4ef..10194861b4 100644 --- a/scene/2d/shape_cast_2d.cpp +++ b/scene/2d/shape_cast_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -223,7 +223,7 @@ void ShapeCast2D::_notification(int p_what) { draw_col.g = g; draw_col.b = g; } - // Draw continuos chain of shapes along the cast. + // Draw continuous chain of shapes along the cast. const int steps = MAX(2, target_position.length() / shape->get_rect().get_size().length() * 4); for (int i = 0; i <= steps; ++i) { Vector2 t = (real_t(i) / steps) * target_position; @@ -239,14 +239,16 @@ void ShapeCast2D::_notification(int p_what) { xf.translate(Vector2(target_position.length(), 0)); draw_line(Vector2(), target_position, draw_col, 2); - Vector<Vector2> pts; + float tsize = 8; - pts.push_back(xf.xform(Vector2(tsize, 0))); - pts.push_back(xf.xform(Vector2(0, Math_SQRT12 * tsize))); - pts.push_back(xf.xform(Vector2(0, -Math_SQRT12 * tsize))); - Vector<Color> cols; - for (int i = 0; i < 3; i++) - cols.push_back(draw_col); + + Vector<Vector2> pts = { + xf.xform(Vector2(tsize, 0)), + xf.xform(Vector2(0, Math_SQRT12 * tsize)), + xf.xform(Vector2(0, -Math_SQRT12 * tsize)) + }; + + Vector<Color> cols = { draw_col, draw_col, draw_col }; draw_primitive(pts, cols, Vector<Vector2>()); } diff --git a/scene/2d/shape_cast_2d.h b/scene/2d/shape_cast_2d.h index fca6b46155..7e1ebeb315 100644 --- a/scene/2d/shape_cast_2d.h +++ b/scene/2d/shape_cast_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp index b558f0aa21..2270926ea7 100644 --- a/scene/2d/skeleton_2d.cpp +++ b/scene/2d/skeleton_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/skeleton_2d.h b/scene/2d/skeleton_2d.h index 56fd0e8504..98fb867d99 100644 --- a/scene/2d/skeleton_2d.h +++ b/scene/2d/skeleton_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/sprite_2d.cpp b/scene/2d/sprite_2d.cpp index b2302d09db..389fa0388f 100644 --- a/scene/2d/sprite_2d.cpp +++ b/scene/2d/sprite_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/sprite_2d.h b/scene/2d/sprite_2d.h index 49df78c59d..6893e92d4a 100644 --- a/scene/2d/sprite_2d.h +++ b/scene/2d/sprite_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 084a5a520d..62dc4d1c15 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -866,7 +866,7 @@ void TileMap::_recreate_layer_internals(int p_layer) { return; } - // Upadate the layer internals. + // Update the layer internals. _rendering_update_layer(p_layer); // Recreate the quadrants. @@ -1375,7 +1375,7 @@ void TileMap::_physics_notification(int p_what) { in_editor = Engine::get_singleton()->is_editor_hint(); #endif if (is_inside_tree() && collision_animatable && !in_editor) { - // Update tranform on the physics tick when in animatable mode. + // Update transform on the physics tick when in animatable mode. last_valid_transform = new_transform; set_notify_local_transform(false); set_global_transform(new_transform); @@ -2104,6 +2104,7 @@ Ref<TileMapPattern> TileMap::get_pattern(int p_layer, TypedArray<Vector2i> p_coo } Vector2i TileMap::map_pattern(Vector2i p_position_in_tilemap, Vector2i p_coords_in_pattern, Ref<TileMapPattern> p_pattern) { + ERR_FAIL_COND_V(p_pattern.is_null(), Vector2i()); ERR_FAIL_COND_V(!p_pattern->has_cell(p_coords_in_pattern), Vector2i()); Vector2i output = p_position_in_tilemap + p_coords_in_pattern; @@ -2295,7 +2296,7 @@ Map<Vector2i, TileSet::TerrainsPattern> TileMap::terrain_wave_function_collapse( // Randomly a cell to fill out of the most constrained. Vector2i selected_cell_to_replace = to_choose_from[Math::random(0, to_choose_from.size() - 1)]; - // Get the list of acceptable pattens for the given cell. + // Get the list of acceptable patterns for the given cell. Set<TileSet::TerrainsPattern> valid_tiles = per_cell_acceptable_tiles[selected_cell_to_replace]; if (valid_tiles.is_empty()) { break; // No possibilities :/ diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index f260422290..0da04bfeae 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp index 8bd7b696f2..ff186b01f2 100644 --- a/scene/2d/touch_screen_button.cpp +++ b/scene/2d/touch_screen_button.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -32,13 +32,13 @@ #include "scene/main/window.h" -void TouchScreenButton::set_texture(const Ref<Texture2D> &p_texture) { - texture = p_texture; +void TouchScreenButton::set_texture_normal(const Ref<Texture2D> &p_texture) { + texture_normal = p_texture; update(); } -Ref<Texture2D> TouchScreenButton::get_texture() const { - return texture; +Ref<Texture2D> TouchScreenButton::get_texture_normal() const { + return texture_normal; } void TouchScreenButton::set_texture_pressed(const Ref<Texture2D> &p_texture_pressed) { @@ -107,13 +107,13 @@ void TouchScreenButton::_notification(int p_what) { if (finger_pressed != -1) { if (texture_pressed.is_valid()) { draw_texture(texture_pressed, Point2()); - } else if (texture.is_valid()) { - draw_texture(texture, Point2()); + } else if (texture_normal.is_valid()) { + draw_texture(texture_normal, Point2()); } } else { - if (texture.is_valid()) { - draw_texture(texture, Point2()); + if (texture_normal.is_valid()) { + draw_texture(texture_normal, Point2()); } } @@ -127,8 +127,8 @@ void TouchScreenButton::_notification(int p_what) { Color draw_col = get_tree()->get_debug_collisions_color(); Vector2 pos; - if (shape_centered && texture.is_valid()) { - pos = texture->get_size() * 0.5; + if (shape_centered && texture_normal.is_valid()) { + pos = texture_normal->get_size() * 0.5; } draw_set_transform_matrix(get_canvas_transform().translated(pos)); @@ -254,8 +254,8 @@ bool TouchScreenButton::_is_point_inside(const Point2 &p_point) { check_rect = false; Vector2 pos; - if (shape_centered && texture.is_valid()) { - pos = texture->get_size() * 0.5; + if (shape_centered && texture_normal.is_valid()) { + pos = texture_normal->get_size() * 0.5; } touched = shape->collide(Transform2D().translated(pos), unit_rect, Transform2D(0, coord + Vector2(0.5, 0.5))); @@ -271,8 +271,8 @@ bool TouchScreenButton::_is_point_inside(const Point2 &p_point) { } if (!touched && check_rect) { - if (texture.is_valid()) { - touched = Rect2(Size2(), texture->get_size()).has_point(coord); + if (texture_normal.is_valid()) { + touched = Rect2(Size2(), texture_normal->get_size()).has_point(coord); } } @@ -317,24 +317,24 @@ void TouchScreenButton::_release(bool p_exiting_tree) { #ifdef TOOLS_ENABLED Rect2 TouchScreenButton::_edit_get_rect() const { - if (texture.is_null()) { + if (texture_normal.is_null()) { return CanvasItem::_edit_get_rect(); } - return Rect2(Size2(), texture->get_size()); + return Rect2(Size2(), texture_normal->get_size()); } bool TouchScreenButton::_edit_use_rect() const { - return !texture.is_null(); + return !texture_normal.is_null(); } #endif Rect2 TouchScreenButton::get_anchorable_rect() const { - if (texture.is_null()) { + if (texture_normal.is_null()) { return CanvasItem::get_anchorable_rect(); } - return Rect2(Size2(), texture->get_size()); + return Rect2(Size2(), texture_normal->get_size()); } void TouchScreenButton::set_visibility_mode(VisibilityMode p_mode) { @@ -355,10 +355,10 @@ bool TouchScreenButton::is_passby_press_enabled() const { } void TouchScreenButton::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_texture", "texture"), &TouchScreenButton::set_texture); - ClassDB::bind_method(D_METHOD("get_texture"), &TouchScreenButton::get_texture); + ClassDB::bind_method(D_METHOD("set_texture_normal", "texture"), &TouchScreenButton::set_texture_normal); + ClassDB::bind_method(D_METHOD("get_texture_normal"), &TouchScreenButton::get_texture_normal); - ClassDB::bind_method(D_METHOD("set_texture_pressed", "texture_pressed"), &TouchScreenButton::set_texture_pressed); + ClassDB::bind_method(D_METHOD("set_texture_pressed", "texture"), &TouchScreenButton::set_texture_pressed); ClassDB::bind_method(D_METHOD("get_texture_pressed"), &TouchScreenButton::get_texture_pressed); ClassDB::bind_method(D_METHOD("set_bitmask", "bitmask"), &TouchScreenButton::set_bitmask); @@ -384,8 +384,8 @@ void TouchScreenButton::_bind_methods() { ClassDB::bind_method(D_METHOD("is_pressed"), &TouchScreenButton::is_pressed); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "pressed", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture_pressed", "get_texture_pressed"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture_normal", "get_texture_normal"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_pressed", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture_pressed", "get_texture_pressed"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "bitmask", PROPERTY_HINT_RESOURCE_TYPE, "BitMap"), "set_bitmask", "get_bitmask"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D"), "set_shape", "get_shape"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shape_centered"), "set_shape_centered", "is_shape_centered"); diff --git a/scene/2d/touch_screen_button.h b/scene/2d/touch_screen_button.h index 1c515149d4..e7f6da9f50 100644 --- a/scene/2d/touch_screen_button.h +++ b/scene/2d/touch_screen_button.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -46,7 +46,7 @@ public: }; private: - Ref<Texture2D> texture; + Ref<Texture2D> texture_normal; Ref<Texture2D> texture_pressed; Ref<BitMap> bitmask; Ref<Shape2D> shape; @@ -78,8 +78,8 @@ public: virtual bool _edit_use_rect() const override; #endif - void set_texture(const Ref<Texture2D> &p_texture); - Ref<Texture2D> get_texture() const; + void set_texture_normal(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_texture_normal() const; void set_texture_pressed(const Ref<Texture2D> &p_texture_pressed); Ref<Texture2D> get_texture_pressed() const; diff --git a/scene/2d/visible_on_screen_notifier_2d.cpp b/scene/2d/visible_on_screen_notifier_2d.cpp index eb4bedb6a3..a7c2ae5bb1 100644 --- a/scene/2d/visible_on_screen_notifier_2d.cpp +++ b/scene/2d/visible_on_screen_notifier_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/2d/visible_on_screen_notifier_2d.h b/scene/2d/visible_on_screen_notifier_2d.h index 9c236a138f..e0d580f174 100644 --- a/scene/2d/visible_on_screen_notifier_2d.h +++ b/scene/2d/visible_on_screen_notifier_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp index 073543638f..5123a6eb6c 100644 --- a/scene/3d/area_3d.cpp +++ b/scene/3d/area_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/area_3d.h b/scene/3d/area_3d.h index 7f31be2e17..c2399985ff 100644 --- a/scene/3d/area_3d.h +++ b/scene/3d/area_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/audio_listener_3d.cpp b/scene/3d/audio_listener_3d.cpp index b2319e40d7..0eb7588958 100644 --- a/scene/3d/audio_listener_3d.cpp +++ b/scene/3d/audio_listener_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/audio_listener_3d.h b/scene/3d/audio_listener_3d.h index 31de3b4fb1..ebc37673ed 100644 --- a/scene/3d/audio_listener_3d.h +++ b/scene/3d/audio_listener_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index efe23c6102..3b52974b8e 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -391,7 +391,13 @@ Vector<AudioFrame> AudioStreamPlayer3D::_update_panning() { PhysicsDirectSpaceState3D *space_state = PhysicsServer3D::get_singleton()->space_get_direct_state(world_3d->get_space()); for (Camera3D *camera : cameras) { + if (!camera) { + continue; + } Viewport *vp = camera->get_viewport(); + if (!vp) { + continue; + } if (!vp->is_audio_listener_3d()) { continue; } diff --git a/scene/3d/audio_stream_player_3d.h b/scene/3d/audio_stream_player_3d.h index 697bbe2381..53cdd2e630 100644 --- a/scene/3d/audio_stream_player_3d.h +++ b/scene/3d/audio_stream_player_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/bone_attachment_3d.cpp b/scene/3d/bone_attachment_3d.cpp index 5dc7382197..73a4dcd1f7 100644 --- a/scene/3d/bone_attachment_3d.cpp +++ b/scene/3d/bone_attachment_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/bone_attachment_3d.h b/scene/3d/bone_attachment_3d.h index 57b9854e0e..395dfde1d7 100644 --- a/scene/3d/bone_attachment_3d.h +++ b/scene/3d/bone_attachment_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp index cc5b7078e3..2c95010eb4 100644 --- a/scene/3d/camera_3d.cpp +++ b/scene/3d/camera_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -331,11 +331,13 @@ Vector<Vector3> Camera3D::get_near_plane_points() const { Vector3 endpoints[8]; cm.get_endpoints(Transform3D(), endpoints); - Vector<Vector3> points; - points.push_back(Vector3()); - for (int i = 0; i < 4; i++) { - points.push_back(endpoints[i + 4]); - } + Vector<Vector3> points = { + Vector3(), + endpoints[4], + endpoints[5], + endpoints[6], + endpoints[7] + }; return points; } diff --git a/scene/3d/camera_3d.h b/scene/3d/camera_3d.h index 73126611d5..b5665814c7 100644 --- a/scene/3d/camera_3d.h +++ b/scene/3d/camera_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp index 085f1ade66..df7c044f9e 100644 --- a/scene/3d/collision_object_3d.cpp +++ b/scene/3d/collision_object_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/collision_object_3d.h b/scene/3d/collision_object_3d.h index 1c7e205888..f560753543 100644 --- a/scene/3d/collision_object_3d.h +++ b/scene/3d/collision_object_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/collision_polygon_3d.cpp b/scene/3d/collision_polygon_3d.cpp index 6328d9c67d..7926175459 100644 --- a/scene/3d/collision_polygon_3d.cpp +++ b/scene/3d/collision_polygon_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/collision_polygon_3d.h b/scene/3d/collision_polygon_3d.h index 73b8a8e0e3..a24d485af2 100644 --- a/scene/3d/collision_polygon_3d.h +++ b/scene/3d/collision_polygon_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/collision_shape_3d.cpp b/scene/3d/collision_shape_3d.cpp index 4e496fba47..773095b377 100644 --- a/scene/3d/collision_shape_3d.cpp +++ b/scene/3d/collision_shape_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/collision_shape_3d.h b/scene/3d/collision_shape_3d.h index cb7fe21eae..bd5595f974 100644 --- a/scene/3d/collision_shape_3d.h +++ b/scene/3d/collision_shape_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp index b081142fbf..e3d551d782 100644 --- a/scene/3d/cpu_particles_3d.cpp +++ b/scene/3d/cpu_particles_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -368,6 +368,14 @@ Ref<Gradient> CPUParticles3D::get_color_ramp() const { return color_ramp; } +void CPUParticles3D::set_color_initial_ramp(const Ref<Gradient> &p_ramp) { + color_initial_ramp = p_ramp; +} + +Ref<Gradient> CPUParticles3D::get_color_initial_ramp() const { + return color_initial_ramp; +} + void CPUParticles3D::set_particle_flag(ParticleFlags p_particle_flag, bool p_enable) { ERR_FAIL_INDEX(p_particle_flag, PARTICLE_FLAG_MAX); particle_flags[p_particle_flag] = p_enable; @@ -748,10 +756,16 @@ void CPUParticles3D::_particles_process(double p_delta) { p.hue_rot_rand = Math::randf(); p.anim_offset_rand = Math::randf(); + if (color_initial_ramp.is_valid()) { + p.start_color_rand = color_initial_ramp->get_color_at_offset(Math::randf()); + } else { + p.start_color_rand = Color(1, 1, 1, 1); + } + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { real_t angle1_rad = Math::atan2(direction.y, direction.x) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * spread); Vector3 rot = Vector3(Math::cos(angle1_rad), Math::sin(angle1_rad), 0.0); - p.velocity = rot * Math::lerp(parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], parameters_max[PARAM_INITIAL_LINEAR_VELOCITY], Math::randf()); + p.velocity = rot * Math::lerp(parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], parameters_max[PARAM_INITIAL_LINEAR_VELOCITY], (real_t)Math::randf()); } else { //initiate velocity spread in 3D real_t angle1_rad = Math::deg2rad((Math::randf() * (real_t)2.0 - (real_t)1.0) * spread); @@ -775,7 +789,7 @@ void CPUParticles3D::_particles_process(double p_delta) { binormal.normalize(); Vector3 normal = binormal.cross(direction_nrm); spread_direction = binormal * spread_direction.x + normal * spread_direction.y + direction_nrm * spread_direction.z; - p.velocity = spread_direction * Math::lerp(parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], parameters_max[PARAM_INITIAL_LINEAR_VELOCITY], float(Math::randf())); + p.velocity = spread_direction * Math::lerp(parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], parameters_max[PARAM_INITIAL_LINEAR_VELOCITY], (real_t)Math::randf()); } real_t base_angle = tex_angle * Math::lerp(parameters_min[PARAM_ANGLE], parameters_max[PARAM_ANGLE], p.angle_rand); @@ -1046,7 +1060,7 @@ void CPUParticles3D::_particles_process(double p_delta) { p.color.g = color_rgb.y; p.color.b = color_rgb.z; - p.color *= p.base_color; + p.color *= p.base_color * p.start_color_rand; if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { if (particle_flags[PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY]) { @@ -1333,6 +1347,11 @@ void CPUParticles3D::convert_from_particles(Node *p_particles) { set_color_ramp(gt->get_gradient()); } + Ref<GradientTexture1D> gti = material->get_color_initial_ramp(); + if (gti.is_valid()) { + set_color_initial_ramp(gti->get_gradient()); + } + set_particle_flag(PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY, material->get_particle_flag(ParticlesMaterial::PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY)); set_particle_flag(PARTICLE_FLAG_ROTATE_Y, material->get_particle_flag(ParticlesMaterial::PARTICLE_FLAG_ROTATE_Y)); set_particle_flag(PARTICLE_FLAG_DISABLE_Z, material->get_particle_flag(ParticlesMaterial::PARTICLE_FLAG_DISABLE_Z)); @@ -1459,6 +1478,9 @@ void CPUParticles3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_color_ramp", "ramp"), &CPUParticles3D::set_color_ramp); ClassDB::bind_method(D_METHOD("get_color_ramp"), &CPUParticles3D::get_color_ramp); + ClassDB::bind_method(D_METHOD("set_color_initial_ramp", "ramp"), &CPUParticles3D::set_color_initial_ramp); + ClassDB::bind_method(D_METHOD("get_color_initial_ramp"), &CPUParticles3D::get_color_initial_ramp); + ClassDB::bind_method(D_METHOD("set_particle_flag", "particle_flag", "enable"), &CPUParticles3D::set_particle_flag); ClassDB::bind_method(D_METHOD("get_particle_flag", "particle_flag"), &CPUParticles3D::get_particle_flag); @@ -1572,6 +1594,7 @@ void CPUParticles3D::_bind_methods() { ADD_GROUP("Color", ""); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_color_ramp", "get_color_ramp"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_initial_ramp", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_color_initial_ramp", "get_color_initial_ramp"); ADD_GROUP("Hue Variation", "hue_"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation_min", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param_min", "get_param_min", PARAM_HUE_VARIATION); diff --git a/scene/3d/cpu_particles_3d.h b/scene/3d/cpu_particles_3d.h index aca7328a27..bd736bdf24 100644 --- a/scene/3d/cpu_particles_3d.h +++ b/scene/3d/cpu_particles_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -91,6 +91,7 @@ private: real_t scale_rand = 0.0; real_t hue_rot_rand = 0.0; real_t anim_offset_rand = 0.0; + Color start_color_rand; double time = 0.0; double lifetime = 0.0; Color base_color; @@ -160,6 +161,7 @@ private: Ref<Curve> curve_parameters[PARAM_MAX]; Color color = Color(1, 1, 1, 1); Ref<Gradient> color_ramp; + Ref<Gradient> color_initial_ramp; bool particle_flags[PARTICLE_FLAG_MAX] = {}; @@ -261,6 +263,9 @@ public: void set_color_ramp(const Ref<Gradient> &p_ramp); Ref<Gradient> get_color_ramp() const; + void set_color_initial_ramp(const Ref<Gradient> &p_ramp); + Ref<Gradient> get_color_initial_ramp() const; + void set_particle_flag(ParticleFlags p_particle_flag, bool p_enable); bool get_particle_flag(ParticleFlags p_particle_flag) const; diff --git a/scene/3d/decal.cpp b/scene/3d/decal.cpp index 500bf4d8f5..dfac9055f5 100644 --- a/scene/3d/decal.cpp +++ b/scene/3d/decal.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/decal.h b/scene/3d/decal.h index e9bda3276d..740dd2c407 100644 --- a/scene/3d/decal.h +++ b/scene/3d/decal.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/fog_volume.cpp b/scene/3d/fog_volume.cpp index 694defd7dc..8d05254a25 100644 --- a/scene/3d/fog_volume.cpp +++ b/scene/3d/fog_volume.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/fog_volume.h b/scene/3d/fog_volume.h index 0807fb22e6..68d5c58169 100644 --- a/scene/3d/fog_volume.h +++ b/scene/3d/fog_volume.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp index b35a45576f..aaaa728838 100644 --- a/scene/3d/gpu_particles_3d.cpp +++ b/scene/3d/gpu_particles_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/gpu_particles_3d.h b/scene/3d/gpu_particles_3d.h index 5e96f660da..54ae84628a 100644 --- a/scene/3d/gpu_particles_3d.h +++ b/scene/3d/gpu_particles_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/gpu_particles_collision_3d.cpp b/scene/3d/gpu_particles_collision_3d.cpp index 2235de1599..54fbc720ce 100644 --- a/scene/3d/gpu_particles_collision_3d.cpp +++ b/scene/3d/gpu_particles_collision_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -62,68 +62,68 @@ GPUParticlesCollision3D::~GPUParticlesCollision3D() { ///////////////////////////////// -void GPUParticlesCollisionSphere::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_radius", "radius"), &GPUParticlesCollisionSphere::set_radius); - ClassDB::bind_method(D_METHOD("get_radius"), &GPUParticlesCollisionSphere::get_radius); +void GPUParticlesCollisionSphere3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_radius", "radius"), &GPUParticlesCollisionSphere3D::set_radius); + ClassDB::bind_method(D_METHOD("get_radius"), &GPUParticlesCollisionSphere3D::get_radius); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater"), "set_radius", "get_radius"); } -void GPUParticlesCollisionSphere::set_radius(real_t p_radius) { +void GPUParticlesCollisionSphere3D::set_radius(real_t p_radius) { radius = p_radius; RS::get_singleton()->particles_collision_set_sphere_radius(_get_collision(), radius); update_gizmos(); } -real_t GPUParticlesCollisionSphere::get_radius() const { +real_t GPUParticlesCollisionSphere3D::get_radius() const { return radius; } -AABB GPUParticlesCollisionSphere::get_aabb() const { +AABB GPUParticlesCollisionSphere3D::get_aabb() const { return AABB(Vector3(-radius, -radius, -radius), Vector3(radius * 2, radius * 2, radius * 2)); } -GPUParticlesCollisionSphere::GPUParticlesCollisionSphere() : +GPUParticlesCollisionSphere3D::GPUParticlesCollisionSphere3D() : GPUParticlesCollision3D(RS::PARTICLES_COLLISION_TYPE_SPHERE_COLLIDE) { } -GPUParticlesCollisionSphere::~GPUParticlesCollisionSphere() { +GPUParticlesCollisionSphere3D::~GPUParticlesCollisionSphere3D() { } /////////////////////////// -void GPUParticlesCollisionBox::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesCollisionBox::set_extents); - ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesCollisionBox::get_extents); +void GPUParticlesCollisionBox3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesCollisionBox3D::set_extents); + ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesCollisionBox3D::get_extents); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater"), "set_extents", "get_extents"); } -void GPUParticlesCollisionBox::set_extents(const Vector3 &p_extents) { +void GPUParticlesCollisionBox3D::set_extents(const Vector3 &p_extents) { extents = p_extents; RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents); update_gizmos(); } -Vector3 GPUParticlesCollisionBox::get_extents() const { +Vector3 GPUParticlesCollisionBox3D::get_extents() const { return extents; } -AABB GPUParticlesCollisionBox::get_aabb() const { +AABB GPUParticlesCollisionBox3D::get_aabb() const { return AABB(-extents, extents * 2); } -GPUParticlesCollisionBox::GPUParticlesCollisionBox() : +GPUParticlesCollisionBox3D::GPUParticlesCollisionBox3D() : GPUParticlesCollision3D(RS::PARTICLES_COLLISION_TYPE_BOX_COLLIDE) { } -GPUParticlesCollisionBox::~GPUParticlesCollisionBox() { +GPUParticlesCollisionBox3D::~GPUParticlesCollisionBox3D() { } /////////////////////////////// /////////////////////////// -void GPUParticlesCollisionSDF::_find_meshes(const AABB &p_aabb, Node *p_at_node, List<PlotMesh> &plot_meshes) { +void GPUParticlesCollisionSDF3D::_find_meshes(const AABB &p_aabb, Node *p_at_node, List<PlotMesh> &plot_meshes) { MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_at_node); if (mi && mi->is_visible_in_tree()) { Ref<Mesh> mesh = mi->get_mesh(); @@ -172,7 +172,7 @@ void GPUParticlesCollisionSDF::_find_meshes(const AABB &p_aabb, Node *p_at_node, } } -uint32_t GPUParticlesCollisionSDF::_create_bvh(LocalVector<BVH> &bvh_tree, FacePos *p_faces, uint32_t p_face_count, const Face3 *p_triangles, float p_thickness) { +uint32_t GPUParticlesCollisionSDF3D::_create_bvh(LocalVector<BVH> &bvh_tree, FacePos *p_faces, uint32_t p_face_count, const Face3 *p_triangles, float p_thickness) { if (p_face_count == 1) { return BVH::LEAF_BIT | p_faces[0].index; } @@ -220,7 +220,7 @@ static _FORCE_INLINE_ real_t Vector3_dot2(const Vector3 &p_vec3) { return p_vec3.dot(p_vec3); } -void GPUParticlesCollisionSDF::_find_closest_distance(const Vector3 &p_pos, const BVH *bvh, uint32_t p_bvh_cell, const Face3 *triangles, float thickness, float &closest_distance) { +void GPUParticlesCollisionSDF3D::_find_closest_distance(const Vector3 &p_pos, const BVH *bvh, uint32_t p_bvh_cell, const Face3 *triangles, float thickness, float &closest_distance) { if (p_bvh_cell & BVH::LEAF_BIT) { p_bvh_cell &= BVH::LEAF_MASK; //remove bit @@ -321,7 +321,7 @@ void GPUParticlesCollisionSDF::_find_closest_distance(const Vector3 &p_pos, cons } } -void GPUParticlesCollisionSDF::_compute_sdf_z(uint32_t p_z, ComputeSDFParams *params) { +void GPUParticlesCollisionSDF3D::_compute_sdf_z(uint32_t p_z, ComputeSDFParams *params) { int32_t z_ofs = p_z * params->size.y * params->size.x; for (int32_t y = 0; y < params->size.y; y++) { int32_t y_ofs = z_ofs + y * params->size.x; @@ -338,10 +338,10 @@ void GPUParticlesCollisionSDF::_compute_sdf_z(uint32_t p_z, ComputeSDFParams *pa } } -void GPUParticlesCollisionSDF::_compute_sdf(ComputeSDFParams *params) { +void GPUParticlesCollisionSDF3D::_compute_sdf(ComputeSDFParams *params) { ThreadWorkPool work_pool; work_pool.init(); - work_pool.begin_work(params->size.z, this, &GPUParticlesCollisionSDF::_compute_sdf_z, params); + work_pool.begin_work(params->size.z, this, &GPUParticlesCollisionSDF3D::_compute_sdf_z, params); while (!work_pool.is_done_dispatching()) { OS::get_singleton()->delay_usec(10000); bake_step_function(work_pool.get_work_index() * 100 / params->size.z, "Baking SDF"); @@ -350,7 +350,7 @@ void GPUParticlesCollisionSDF::_compute_sdf(ComputeSDFParams *params) { work_pool.finish(); } -Vector3i GPUParticlesCollisionSDF::get_estimated_cell_size() const { +Vector3i GPUParticlesCollisionSDF3D::get_estimated_cell_size() const { static const int subdivs[RESOLUTION_MAX] = { 16, 32, 64, 128, 256, 512 }; int subdiv = subdivs[get_resolution()]; @@ -365,7 +365,7 @@ Vector3i GPUParticlesCollisionSDF::get_estimated_cell_size() const { return sdf_size; } -Ref<Image> GPUParticlesCollisionSDF::bake() { +Ref<Image> GPUParticlesCollisionSDF3D::bake() { static const int subdivs[RESOLUTION_MAX] = { 16, 32, 64, 128, 256, 512 }; int subdiv = subdivs[get_resolution()]; @@ -501,18 +501,18 @@ Ref<Image> GPUParticlesCollisionSDF::bake() { return ret; } -void GPUParticlesCollisionSDF::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesCollisionSDF::set_extents); - ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesCollisionSDF::get_extents); +void GPUParticlesCollisionSDF3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesCollisionSDF3D::set_extents); + ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesCollisionSDF3D::get_extents); - ClassDB::bind_method(D_METHOD("set_resolution", "resolution"), &GPUParticlesCollisionSDF::set_resolution); - ClassDB::bind_method(D_METHOD("get_resolution"), &GPUParticlesCollisionSDF::get_resolution); + ClassDB::bind_method(D_METHOD("set_resolution", "resolution"), &GPUParticlesCollisionSDF3D::set_resolution); + ClassDB::bind_method(D_METHOD("get_resolution"), &GPUParticlesCollisionSDF3D::get_resolution); - ClassDB::bind_method(D_METHOD("set_texture", "texture"), &GPUParticlesCollisionSDF::set_texture); - ClassDB::bind_method(D_METHOD("get_texture"), &GPUParticlesCollisionSDF::get_texture); + ClassDB::bind_method(D_METHOD("set_texture", "texture"), &GPUParticlesCollisionSDF3D::set_texture); + ClassDB::bind_method(D_METHOD("get_texture"), &GPUParticlesCollisionSDF3D::get_texture); - ClassDB::bind_method(D_METHOD("set_thickness", "thickness"), &GPUParticlesCollisionSDF::set_thickness); - ClassDB::bind_method(D_METHOD("get_thickness"), &GPUParticlesCollisionSDF::get_thickness); + ClassDB::bind_method(D_METHOD("set_thickness", "thickness"), &GPUParticlesCollisionSDF3D::set_thickness); + ClassDB::bind_method(D_METHOD("get_thickness"), &GPUParticlesCollisionSDF3D::get_thickness); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater"), "set_extents", "get_extents"); ADD_PROPERTY(PropertyInfo(Variant::INT, "resolution", PROPERTY_HINT_ENUM, "16,32,64,128,256,512"), "set_resolution", "get_resolution"); @@ -528,62 +528,62 @@ void GPUParticlesCollisionSDF::_bind_methods() { BIND_ENUM_CONSTANT(RESOLUTION_MAX); } -void GPUParticlesCollisionSDF::set_thickness(float p_thickness) { +void GPUParticlesCollisionSDF3D::set_thickness(float p_thickness) { thickness = p_thickness; } -float GPUParticlesCollisionSDF::get_thickness() const { +float GPUParticlesCollisionSDF3D::get_thickness() const { return thickness; } -void GPUParticlesCollisionSDF::set_extents(const Vector3 &p_extents) { +void GPUParticlesCollisionSDF3D::set_extents(const Vector3 &p_extents) { extents = p_extents; RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents); update_gizmos(); } -Vector3 GPUParticlesCollisionSDF::get_extents() const { +Vector3 GPUParticlesCollisionSDF3D::get_extents() const { return extents; } -void GPUParticlesCollisionSDF::set_resolution(Resolution p_resolution) { +void GPUParticlesCollisionSDF3D::set_resolution(Resolution p_resolution) { resolution = p_resolution; update_gizmos(); } -GPUParticlesCollisionSDF::Resolution GPUParticlesCollisionSDF::get_resolution() const { +GPUParticlesCollisionSDF3D::Resolution GPUParticlesCollisionSDF3D::get_resolution() const { return resolution; } -void GPUParticlesCollisionSDF::set_texture(const Ref<Texture3D> &p_texture) { +void GPUParticlesCollisionSDF3D::set_texture(const Ref<Texture3D> &p_texture) { texture = p_texture; RID tex = texture.is_valid() ? texture->get_rid() : RID(); RS::get_singleton()->particles_collision_set_field_texture(_get_collision(), tex); } -Ref<Texture3D> GPUParticlesCollisionSDF::get_texture() const { +Ref<Texture3D> GPUParticlesCollisionSDF3D::get_texture() const { return texture; } -AABB GPUParticlesCollisionSDF::get_aabb() const { +AABB GPUParticlesCollisionSDF3D::get_aabb() const { return AABB(-extents, extents * 2); } -GPUParticlesCollisionSDF::BakeBeginFunc GPUParticlesCollisionSDF::bake_begin_function = nullptr; -GPUParticlesCollisionSDF::BakeStepFunc GPUParticlesCollisionSDF::bake_step_function = nullptr; -GPUParticlesCollisionSDF::BakeEndFunc GPUParticlesCollisionSDF::bake_end_function = nullptr; +GPUParticlesCollisionSDF3D::BakeBeginFunc GPUParticlesCollisionSDF3D::bake_begin_function = nullptr; +GPUParticlesCollisionSDF3D::BakeStepFunc GPUParticlesCollisionSDF3D::bake_step_function = nullptr; +GPUParticlesCollisionSDF3D::BakeEndFunc GPUParticlesCollisionSDF3D::bake_end_function = nullptr; -GPUParticlesCollisionSDF::GPUParticlesCollisionSDF() : +GPUParticlesCollisionSDF3D::GPUParticlesCollisionSDF3D() : GPUParticlesCollision3D(RS::PARTICLES_COLLISION_TYPE_SDF_COLLIDE) { } -GPUParticlesCollisionSDF::~GPUParticlesCollisionSDF() { +GPUParticlesCollisionSDF3D::~GPUParticlesCollisionSDF3D() { } //////////////////////////// //////////////////////////// -void GPUParticlesCollisionHeightField::_notification(int p_what) { +void GPUParticlesCollisionHeightField3D::_notification(int p_what) { if (p_what == NOTIFICATION_INTERNAL_PROCESS) { if (update_mode == UPDATE_MODE_ALWAYS) { RS::get_singleton()->particles_collision_height_field_update(_get_collision()); @@ -628,21 +628,21 @@ void GPUParticlesCollisionHeightField::_notification(int p_what) { } } -void GPUParticlesCollisionHeightField::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesCollisionHeightField::set_extents); - ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesCollisionHeightField::get_extents); +void GPUParticlesCollisionHeightField3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesCollisionHeightField3D::set_extents); + ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesCollisionHeightField3D::get_extents); - ClassDB::bind_method(D_METHOD("set_resolution", "resolution"), &GPUParticlesCollisionHeightField::set_resolution); - ClassDB::bind_method(D_METHOD("get_resolution"), &GPUParticlesCollisionHeightField::get_resolution); + ClassDB::bind_method(D_METHOD("set_resolution", "resolution"), &GPUParticlesCollisionHeightField3D::set_resolution); + ClassDB::bind_method(D_METHOD("get_resolution"), &GPUParticlesCollisionHeightField3D::get_resolution); - ClassDB::bind_method(D_METHOD("set_update_mode", "update_mode"), &GPUParticlesCollisionHeightField::set_update_mode); - ClassDB::bind_method(D_METHOD("get_update_mode"), &GPUParticlesCollisionHeightField::get_update_mode); + ClassDB::bind_method(D_METHOD("set_update_mode", "update_mode"), &GPUParticlesCollisionHeightField3D::set_update_mode); + ClassDB::bind_method(D_METHOD("get_update_mode"), &GPUParticlesCollisionHeightField3D::get_update_mode); - ClassDB::bind_method(D_METHOD("set_follow_camera_mode", "enabled"), &GPUParticlesCollisionHeightField::set_follow_camera_mode); - ClassDB::bind_method(D_METHOD("is_follow_camera_mode_enabled"), &GPUParticlesCollisionHeightField::is_follow_camera_mode_enabled); + ClassDB::bind_method(D_METHOD("set_follow_camera_mode", "enabled"), &GPUParticlesCollisionHeightField3D::set_follow_camera_mode); + ClassDB::bind_method(D_METHOD("is_follow_camera_mode_enabled"), &GPUParticlesCollisionHeightField3D::is_follow_camera_mode_enabled); - ClassDB::bind_method(D_METHOD("set_follow_camera_push_ratio", "ratio"), &GPUParticlesCollisionHeightField::set_follow_camera_push_ratio); - ClassDB::bind_method(D_METHOD("get_follow_camera_push_ratio"), &GPUParticlesCollisionHeightField::get_follow_camera_push_ratio); + ClassDB::bind_method(D_METHOD("set_follow_camera_push_ratio", "ratio"), &GPUParticlesCollisionHeightField3D::set_follow_camera_push_ratio); + ClassDB::bind_method(D_METHOD("get_follow_camera_push_ratio"), &GPUParticlesCollisionHeightField3D::get_follow_camera_push_ratio); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater"), "set_extents", "get_extents"); ADD_PROPERTY(PropertyInfo(Variant::INT, "resolution", PROPERTY_HINT_ENUM, "256,512,1024,2048,4096,8192"), "set_resolution", "get_resolution"); @@ -663,63 +663,63 @@ void GPUParticlesCollisionHeightField::_bind_methods() { BIND_ENUM_CONSTANT(UPDATE_MODE_ALWAYS); } -void GPUParticlesCollisionHeightField::set_follow_camera_push_ratio(float p_follow_camera_push_ratio) { +void GPUParticlesCollisionHeightField3D::set_follow_camera_push_ratio(float p_follow_camera_push_ratio) { follow_camera_push_ratio = p_follow_camera_push_ratio; } -float GPUParticlesCollisionHeightField::get_follow_camera_push_ratio() const { +float GPUParticlesCollisionHeightField3D::get_follow_camera_push_ratio() const { return follow_camera_push_ratio; } -void GPUParticlesCollisionHeightField::set_extents(const Vector3 &p_extents) { +void GPUParticlesCollisionHeightField3D::set_extents(const Vector3 &p_extents) { extents = p_extents; RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents); update_gizmos(); RS::get_singleton()->particles_collision_height_field_update(_get_collision()); } -Vector3 GPUParticlesCollisionHeightField::get_extents() const { +Vector3 GPUParticlesCollisionHeightField3D::get_extents() const { return extents; } -void GPUParticlesCollisionHeightField::set_resolution(Resolution p_resolution) { +void GPUParticlesCollisionHeightField3D::set_resolution(Resolution p_resolution) { resolution = p_resolution; RS::get_singleton()->particles_collision_set_height_field_resolution(_get_collision(), RS::ParticlesCollisionHeightfieldResolution(resolution)); update_gizmos(); RS::get_singleton()->particles_collision_height_field_update(_get_collision()); } -GPUParticlesCollisionHeightField::Resolution GPUParticlesCollisionHeightField::get_resolution() const { +GPUParticlesCollisionHeightField3D::Resolution GPUParticlesCollisionHeightField3D::get_resolution() const { return resolution; } -void GPUParticlesCollisionHeightField::set_update_mode(UpdateMode p_update_mode) { +void GPUParticlesCollisionHeightField3D::set_update_mode(UpdateMode p_update_mode) { update_mode = p_update_mode; set_process_internal(follow_camera_mode || update_mode == UPDATE_MODE_ALWAYS); } -GPUParticlesCollisionHeightField::UpdateMode GPUParticlesCollisionHeightField::get_update_mode() const { +GPUParticlesCollisionHeightField3D::UpdateMode GPUParticlesCollisionHeightField3D::get_update_mode() const { return update_mode; } -void GPUParticlesCollisionHeightField::set_follow_camera_mode(bool p_enabled) { +void GPUParticlesCollisionHeightField3D::set_follow_camera_mode(bool p_enabled) { follow_camera_mode = p_enabled; set_process_internal(follow_camera_mode || update_mode == UPDATE_MODE_ALWAYS); } -bool GPUParticlesCollisionHeightField::is_follow_camera_mode_enabled() const { +bool GPUParticlesCollisionHeightField3D::is_follow_camera_mode_enabled() const { return follow_camera_mode; } -AABB GPUParticlesCollisionHeightField::get_aabb() const { +AABB GPUParticlesCollisionHeightField3D::get_aabb() const { return AABB(-extents, extents * 2); } -GPUParticlesCollisionHeightField::GPUParticlesCollisionHeightField() : +GPUParticlesCollisionHeightField3D::GPUParticlesCollisionHeightField3D() : GPUParticlesCollision3D(RS::PARTICLES_COLLISION_TYPE_HEIGHTFIELD_COLLIDE) { } -GPUParticlesCollisionHeightField::~GPUParticlesCollisionHeightField() { +GPUParticlesCollisionHeightField3D::~GPUParticlesCollisionHeightField3D() { } //////////////////////////// @@ -792,104 +792,104 @@ GPUParticlesAttractor3D::~GPUParticlesAttractor3D() { ///////////////////////////////// -void GPUParticlesAttractorSphere::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_radius", "radius"), &GPUParticlesAttractorSphere::set_radius); - ClassDB::bind_method(D_METHOD("get_radius"), &GPUParticlesAttractorSphere::get_radius); +void GPUParticlesAttractorSphere3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_radius", "radius"), &GPUParticlesAttractorSphere3D::set_radius); + ClassDB::bind_method(D_METHOD("get_radius"), &GPUParticlesAttractorSphere3D::get_radius); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater"), "set_radius", "get_radius"); } -void GPUParticlesAttractorSphere::set_radius(real_t p_radius) { +void GPUParticlesAttractorSphere3D::set_radius(real_t p_radius) { radius = p_radius; RS::get_singleton()->particles_collision_set_sphere_radius(_get_collision(), radius); update_gizmos(); } -real_t GPUParticlesAttractorSphere::get_radius() const { +real_t GPUParticlesAttractorSphere3D::get_radius() const { return radius; } -AABB GPUParticlesAttractorSphere::get_aabb() const { +AABB GPUParticlesAttractorSphere3D::get_aabb() const { return AABB(Vector3(-radius, -radius, -radius), Vector3(radius * 2, radius * 2, radius * 2)); } -GPUParticlesAttractorSphere::GPUParticlesAttractorSphere() : +GPUParticlesAttractorSphere3D::GPUParticlesAttractorSphere3D() : GPUParticlesAttractor3D(RS::PARTICLES_COLLISION_TYPE_SPHERE_ATTRACT) { } -GPUParticlesAttractorSphere::~GPUParticlesAttractorSphere() { +GPUParticlesAttractorSphere3D::~GPUParticlesAttractorSphere3D() { } /////////////////////////// -void GPUParticlesAttractorBox::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesAttractorBox::set_extents); - ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesAttractorBox::get_extents); +void GPUParticlesAttractorBox3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesAttractorBox3D::set_extents); + ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesAttractorBox3D::get_extents); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater"), "set_extents", "get_extents"); } -void GPUParticlesAttractorBox::set_extents(const Vector3 &p_extents) { +void GPUParticlesAttractorBox3D::set_extents(const Vector3 &p_extents) { extents = p_extents; RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents); update_gizmos(); } -Vector3 GPUParticlesAttractorBox::get_extents() const { +Vector3 GPUParticlesAttractorBox3D::get_extents() const { return extents; } -AABB GPUParticlesAttractorBox::get_aabb() const { +AABB GPUParticlesAttractorBox3D::get_aabb() const { return AABB(-extents, extents * 2); } -GPUParticlesAttractorBox::GPUParticlesAttractorBox() : +GPUParticlesAttractorBox3D::GPUParticlesAttractorBox3D() : GPUParticlesAttractor3D(RS::PARTICLES_COLLISION_TYPE_BOX_ATTRACT) { } -GPUParticlesAttractorBox::~GPUParticlesAttractorBox() { +GPUParticlesAttractorBox3D::~GPUParticlesAttractorBox3D() { } /////////////////////////// -void GPUParticlesAttractorVectorField::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesAttractorVectorField::set_extents); - ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesAttractorVectorField::get_extents); +void GPUParticlesAttractorVectorField3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesAttractorVectorField3D::set_extents); + ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesAttractorVectorField3D::get_extents); - ClassDB::bind_method(D_METHOD("set_texture", "texture"), &GPUParticlesAttractorVectorField::set_texture); - ClassDB::bind_method(D_METHOD("get_texture"), &GPUParticlesAttractorVectorField::get_texture); + ClassDB::bind_method(D_METHOD("set_texture", "texture"), &GPUParticlesAttractorVectorField3D::set_texture); + ClassDB::bind_method(D_METHOD("get_texture"), &GPUParticlesAttractorVectorField3D::get_texture); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater"), "set_extents", "get_extents"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture3D"), "set_texture", "get_texture"); } -void GPUParticlesAttractorVectorField::set_extents(const Vector3 &p_extents) { +void GPUParticlesAttractorVectorField3D::set_extents(const Vector3 &p_extents) { extents = p_extents; RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents); update_gizmos(); } -Vector3 GPUParticlesAttractorVectorField::get_extents() const { +Vector3 GPUParticlesAttractorVectorField3D::get_extents() const { return extents; } -void GPUParticlesAttractorVectorField::set_texture(const Ref<Texture3D> &p_texture) { +void GPUParticlesAttractorVectorField3D::set_texture(const Ref<Texture3D> &p_texture) { texture = p_texture; RID tex = texture.is_valid() ? texture->get_rid() : RID(); RS::get_singleton()->particles_collision_set_field_texture(_get_collision(), tex); } -Ref<Texture3D> GPUParticlesAttractorVectorField::get_texture() const { +Ref<Texture3D> GPUParticlesAttractorVectorField3D::get_texture() const { return texture; } -AABB GPUParticlesAttractorVectorField::get_aabb() const { +AABB GPUParticlesAttractorVectorField3D::get_aabb() const { return AABB(-extents, extents * 2); } -GPUParticlesAttractorVectorField::GPUParticlesAttractorVectorField() : +GPUParticlesAttractorVectorField3D::GPUParticlesAttractorVectorField3D() : GPUParticlesAttractor3D(RS::PARTICLES_COLLISION_TYPE_VECTOR_FIELD_ATTRACT) { } -GPUParticlesAttractorVectorField::~GPUParticlesAttractorVectorField() { +GPUParticlesAttractorVectorField3D::~GPUParticlesAttractorVectorField3D() { } diff --git a/scene/3d/gpu_particles_collision_3d.h b/scene/3d/gpu_particles_collision_3d.h index fbf68ed6df..b6de1d83fc 100644 --- a/scene/3d/gpu_particles_collision_3d.h +++ b/scene/3d/gpu_particles_collision_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -55,8 +55,8 @@ public: ~GPUParticlesCollision3D(); }; -class GPUParticlesCollisionSphere : public GPUParticlesCollision3D { - GDCLASS(GPUParticlesCollisionSphere, GPUParticlesCollision3D); +class GPUParticlesCollisionSphere3D : public GPUParticlesCollision3D { + GDCLASS(GPUParticlesCollisionSphere3D, GPUParticlesCollision3D); real_t radius = 1.0; @@ -69,12 +69,12 @@ public: virtual AABB get_aabb() const override; - GPUParticlesCollisionSphere(); - ~GPUParticlesCollisionSphere(); + GPUParticlesCollisionSphere3D(); + ~GPUParticlesCollisionSphere3D(); }; -class GPUParticlesCollisionBox : public GPUParticlesCollision3D { - GDCLASS(GPUParticlesCollisionBox, GPUParticlesCollision3D); +class GPUParticlesCollisionBox3D : public GPUParticlesCollision3D { + GDCLASS(GPUParticlesCollisionBox3D, GPUParticlesCollision3D); Vector3 extents = Vector3(1, 1, 1); @@ -87,12 +87,12 @@ public: virtual AABB get_aabb() const override; - GPUParticlesCollisionBox(); - ~GPUParticlesCollisionBox(); + GPUParticlesCollisionBox3D(); + ~GPUParticlesCollisionBox3D(); }; -class GPUParticlesCollisionSDF : public GPUParticlesCollision3D { - GDCLASS(GPUParticlesCollisionSDF, GPUParticlesCollision3D); +class GPUParticlesCollisionSDF3D : public GPUParticlesCollision3D { + GDCLASS(GPUParticlesCollisionSDF3D, GPUParticlesCollision3D); public: enum Resolution { @@ -184,14 +184,14 @@ public: static BakeStepFunc bake_step_function; static BakeEndFunc bake_end_function; - GPUParticlesCollisionSDF(); - ~GPUParticlesCollisionSDF(); + GPUParticlesCollisionSDF3D(); + ~GPUParticlesCollisionSDF3D(); }; -VARIANT_ENUM_CAST(GPUParticlesCollisionSDF::Resolution) +VARIANT_ENUM_CAST(GPUParticlesCollisionSDF3D::Resolution) -class GPUParticlesCollisionHeightField : public GPUParticlesCollision3D { - GDCLASS(GPUParticlesCollisionHeightField, GPUParticlesCollision3D); +class GPUParticlesCollisionHeightField3D : public GPUParticlesCollision3D { + GDCLASS(GPUParticlesCollisionHeightField3D, GPUParticlesCollision3D); public: enum Resolution { @@ -239,12 +239,12 @@ public: virtual AABB get_aabb() const override; - GPUParticlesCollisionHeightField(); - ~GPUParticlesCollisionHeightField(); + GPUParticlesCollisionHeightField3D(); + ~GPUParticlesCollisionHeightField3D(); }; -VARIANT_ENUM_CAST(GPUParticlesCollisionHeightField::Resolution) -VARIANT_ENUM_CAST(GPUParticlesCollisionHeightField::UpdateMode) +VARIANT_ENUM_CAST(GPUParticlesCollisionHeightField3D::Resolution) +VARIANT_ENUM_CAST(GPUParticlesCollisionHeightField3D::UpdateMode) class GPUParticlesAttractor3D : public VisualInstance3D { GDCLASS(GPUParticlesAttractor3D, VisualInstance3D); @@ -279,8 +279,8 @@ public: ~GPUParticlesAttractor3D(); }; -class GPUParticlesAttractorSphere : public GPUParticlesAttractor3D { - GDCLASS(GPUParticlesAttractorSphere, GPUParticlesAttractor3D); +class GPUParticlesAttractorSphere3D : public GPUParticlesAttractor3D { + GDCLASS(GPUParticlesAttractorSphere3D, GPUParticlesAttractor3D); real_t radius = 1.0; @@ -293,12 +293,12 @@ public: virtual AABB get_aabb() const override; - GPUParticlesAttractorSphere(); - ~GPUParticlesAttractorSphere(); + GPUParticlesAttractorSphere3D(); + ~GPUParticlesAttractorSphere3D(); }; -class GPUParticlesAttractorBox : public GPUParticlesAttractor3D { - GDCLASS(GPUParticlesAttractorBox, GPUParticlesAttractor3D); +class GPUParticlesAttractorBox3D : public GPUParticlesAttractor3D { + GDCLASS(GPUParticlesAttractorBox3D, GPUParticlesAttractor3D); Vector3 extents = Vector3(1, 1, 1); @@ -311,12 +311,12 @@ public: virtual AABB get_aabb() const override; - GPUParticlesAttractorBox(); - ~GPUParticlesAttractorBox(); + GPUParticlesAttractorBox3D(); + ~GPUParticlesAttractorBox3D(); }; -class GPUParticlesAttractorVectorField : public GPUParticlesAttractor3D { - GDCLASS(GPUParticlesAttractorVectorField, GPUParticlesAttractor3D); +class GPUParticlesAttractorVectorField3D : public GPUParticlesAttractor3D { + GDCLASS(GPUParticlesAttractorVectorField3D, GPUParticlesAttractor3D); Vector3 extents = Vector3(1, 1, 1); Ref<Texture3D> texture; @@ -333,8 +333,8 @@ public: virtual AABB get_aabb() const override; - GPUParticlesAttractorVectorField(); - ~GPUParticlesAttractorVectorField(); + GPUParticlesAttractorVectorField3D(); + ~GPUParticlesAttractorVectorField3D(); }; #endif // GPU_PARTICLES_COLLISION_3D_H diff --git a/scene/3d/importer_mesh_instance_3d.cpp b/scene/3d/importer_mesh_instance_3d.cpp index 748a2e5092..7cd6a81532 100644 --- a/scene/3d/importer_mesh_instance_3d.cpp +++ b/scene/3d/importer_mesh_instance_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/importer_mesh_instance_3d.h b/scene/3d/importer_mesh_instance_3d.h index 0cf7dbe86b..3daf06771d 100644 --- a/scene/3d/importer_mesh_instance_3d.h +++ b/scene/3d/importer_mesh_instance_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/joint_3d.cpp b/scene/3d/joint_3d.cpp index aa5ca85bdf..bd47ab3462 100644 --- a/scene/3d/joint_3d.cpp +++ b/scene/3d/joint_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/joint_3d.h b/scene/3d/joint_3d.h index 211cf8e071..ea356ef3b7 100644 --- a/scene/3d/joint_3d.h +++ b/scene/3d/joint_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp index 5d9ae019c2..0a0507207a 100644 --- a/scene/3d/light_3d.cpp +++ b/scene/3d/light_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/light_3d.h b/scene/3d/light_3d.h index a9f5ce27b4..93dc8155bb 100644 --- a/scene/3d/light_3d.h +++ b/scene/3d/light_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/lightmap_gi.cpp b/scene/3d/lightmap_gi.cpp index 1b5d4ad243..715c421632 100644 --- a/scene/3d/lightmap_gi.cpp +++ b/scene/3d/lightmap_gi.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -614,7 +614,7 @@ void LightmapGI::_gen_new_positions_from_octree(const GenProbesOctree *p_cell, f } LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_path, Lightmapper::BakeStepFunc p_bake_step, void *p_bake_userdata) { - if (p_image_data_path == "") { + if (p_image_data_path.is_empty()) { if (get_light_data().is_null()) { return BAKE_ERROR_NO_SAVE_PATH; } @@ -884,15 +884,16 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa Light3D *light = lights_found[i].light; Transform3D xf = lights_found[i].xform; + Color linear_color = light->get_color().to_linear(); if (Object::cast_to<DirectionalLight3D>(light)) { DirectionalLight3D *l = Object::cast_to<DirectionalLight3D>(light); - lightmapper->add_directional_light(light->get_bake_mode() == Light3D::BAKE_STATIC, -xf.basis.get_axis(Vector3::AXIS_Z).normalized(), l->get_color(), l->get_param(Light3D::PARAM_ENERGY), l->get_param(Light3D::PARAM_SIZE)); + lightmapper->add_directional_light(light->get_bake_mode() == Light3D::BAKE_STATIC, -xf.basis.get_axis(Vector3::AXIS_Z).normalized(), linear_color, l->get_param(Light3D::PARAM_ENERGY), l->get_param(Light3D::PARAM_SIZE)); } else if (Object::cast_to<OmniLight3D>(light)) { OmniLight3D *l = Object::cast_to<OmniLight3D>(light); - lightmapper->add_omni_light(light->get_bake_mode() == Light3D::BAKE_STATIC, xf.origin, l->get_color(), l->get_param(Light3D::PARAM_ENERGY), l->get_param(Light3D::PARAM_RANGE), l->get_param(Light3D::PARAM_ATTENUATION), l->get_param(Light3D::PARAM_SIZE)); + lightmapper->add_omni_light(light->get_bake_mode() == Light3D::BAKE_STATIC, xf.origin, linear_color, l->get_param(Light3D::PARAM_ENERGY), l->get_param(Light3D::PARAM_RANGE), l->get_param(Light3D::PARAM_ATTENUATION), l->get_param(Light3D::PARAM_SIZE)); } else if (Object::cast_to<SpotLight3D>(light)) { SpotLight3D *l = Object::cast_to<SpotLight3D>(light); - lightmapper->add_spot_light(light->get_bake_mode() == Light3D::BAKE_STATIC, xf.origin, -xf.basis.get_axis(Vector3::AXIS_Z).normalized(), l->get_color(), l->get_param(Light3D::PARAM_ENERGY), l->get_param(Light3D::PARAM_RANGE), l->get_param(Light3D::PARAM_ATTENUATION), l->get_param(Light3D::PARAM_SPOT_ANGLE), l->get_param(Light3D::PARAM_SPOT_ATTENUATION), l->get_param(Light3D::PARAM_SIZE)); + lightmapper->add_spot_light(light->get_bake_mode() == Light3D::BAKE_STATIC, xf.origin, -xf.basis.get_axis(Vector3::AXIS_Z).normalized(), linear_color, l->get_param(Light3D::PARAM_ENERGY), l->get_param(Light3D::PARAM_RANGE), l->get_param(Light3D::PARAM_ATTENUATION), l->get_param(Light3D::PARAM_SPOT_ANGLE), l->get_param(Light3D::PARAM_SPOT_ATTENUATION), l->get_param(Light3D::PARAM_SIZE)); } } for (int i = 0; i < probes_found.size(); i++) { @@ -941,11 +942,7 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa c.r *= environment_custom_energy; c.g *= environment_custom_energy; c.b *= environment_custom_energy; - for (int i = 0; i < 128; i++) { - for (int j = 0; j < 64; j++) { - environment_image->set_pixel(i, j, c); - } - } + environment_image->fill(c); } break; } diff --git a/scene/3d/lightmap_gi.h b/scene/3d/lightmap_gi.h index e73350fd64..66acf4f487 100644 --- a/scene/3d/lightmap_gi.h +++ b/scene/3d/lightmap_gi.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/lightmap_probe.cpp b/scene/3d/lightmap_probe.cpp index 830b97ffab..641b0a4c48 100644 --- a/scene/3d/lightmap_probe.cpp +++ b/scene/3d/lightmap_probe.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/lightmap_probe.h b/scene/3d/lightmap_probe.h index df87ed49dd..11b35451a1 100644 --- a/scene/3d/lightmap_probe.h +++ b/scene/3d/lightmap_probe.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/lightmapper.cpp b/scene/3d/lightmapper.cpp index 9e5078ba95..8ab710d98f 100644 --- a/scene/3d/lightmapper.cpp +++ b/scene/3d/lightmapper.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/lightmapper.h b/scene/3d/lightmapper.h index d028628901..f641c99ec1 100644 --- a/scene/3d/lightmapper.h +++ b/scene/3d/lightmapper.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp index ae686143e4..58ff512130 100644 --- a/scene/3d/mesh_instance_3d.cpp +++ b/scene/3d/mesh_instance_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/mesh_instance_3d.h b/scene/3d/mesh_instance_3d.h index 8f21726601..03ee3cd608 100644 --- a/scene/3d/mesh_instance_3d.h +++ b/scene/3d/mesh_instance_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/multimesh_instance_3d.cpp b/scene/3d/multimesh_instance_3d.cpp index 2adef115cf..34b1e86435 100644 --- a/scene/3d/multimesh_instance_3d.cpp +++ b/scene/3d/multimesh_instance_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/multimesh_instance_3d.h b/scene/3d/multimesh_instance_3d.h index 63735fd3a6..d03b24eb4e 100644 --- a/scene/3d/multimesh_instance_3d.h +++ b/scene/3d/multimesh_instance_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp index 1bc7d20c19..e90971845e 100644 --- a/scene/3d/navigation_agent_3d.cpp +++ b/scene/3d/navigation_agent_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/navigation_agent_3d.h b/scene/3d/navigation_agent_3d.h index bebfdc5f7e..aebd5be7e4 100644 --- a/scene/3d/navigation_agent_3d.h +++ b/scene/3d/navigation_agent_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/navigation_obstacle_3d.cpp b/scene/3d/navigation_obstacle_3d.cpp index f9fff802e0..b1f6f0cf91 100644 --- a/scene/3d/navigation_obstacle_3d.cpp +++ b/scene/3d/navigation_obstacle_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/navigation_obstacle_3d.h b/scene/3d/navigation_obstacle_3d.h index 12c813ab08..542d603a0a 100644 --- a/scene/3d/navigation_obstacle_3d.h +++ b/scene/3d/navigation_obstacle_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation_region_3d.cpp index 473368cf69..1e298e0137 100644 --- a/scene/3d/navigation_region_3d.cpp +++ b/scene/3d/navigation_region_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/navigation_region_3d.h b/scene/3d/navigation_region_3d.h index ec7761ef93..1a50bb5f64 100644 --- a/scene/3d/navigation_region_3d.h +++ b/scene/3d/navigation_region_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index ddd9d2da8a..a992d2aaf2 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -33,6 +33,7 @@ #include "core/object/message_queue.h" #include "scene/3d/visual_instance_3d.h" #include "scene/main/viewport.h" +#include "scene/property_utils.h" #include "scene/scene_string_names.h" /* @@ -84,6 +85,9 @@ void Node3D::_notify_dirty() { } void Node3D::_update_local_transform() const { + if (this->get_rotation_edit_mode() != ROTATION_EDIT_MODE_BASIS) { + data.local_transform = data.local_transform.orthogonalized(); + } data.local_transform.basis.set_euler_scale(data.rotation, data.scale); data.dirty &= ~DIRTY_LOCAL; @@ -172,6 +176,7 @@ void Node3D::_notification(int p_what) { if (get_script_instance()) { get_script_instance()->call(SceneStringNames::get_singleton()->_enter_world); } + #ifdef TOOLS_ENABLED if (Engine::get_singleton()->is_editor_hint() && get_tree()->is_node_being_edited(this)) { get_tree()->call_group_flags(0, SceneStringNames::get_singleton()->_spatial_editor_group, SceneStringNames::get_singleton()->_request_gizmo, this); @@ -186,7 +191,6 @@ void Node3D::_notification(int p_what) { } } #endif - } break; case NOTIFICATION_EXIT_WORLD: { #ifdef TOOLS_ENABLED @@ -321,6 +325,14 @@ void Node3D::set_rotation_edit_mode(RotationEditMode p_mode) { return; } data.rotation_edit_mode = p_mode; + + // Shearing is not allowed except in ROTATION_EDIT_MODE_BASIS. + data.dirty |= DIRTY_LOCAL; + _propagate_transform_changed(this); + if (data.notify_local_transform) { + notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED); + } + notify_property_list_changed(); } @@ -456,7 +468,6 @@ void Node3D::clear_subgizmo_selection() { void Node3D::add_gizmo(Ref<Node3DGizmo> p_gizmo) { #ifdef TOOLS_ENABLED - if (data.gizmos_disabled || p_gizmo.is_null()) { return; } @@ -474,7 +485,6 @@ void Node3D::add_gizmo(Ref<Node3DGizmo> p_gizmo) { void Node3D::remove_gizmo(Ref<Node3DGizmo> p_gizmo) { #ifdef TOOLS_ENABLED - int idx = data.gizmos.find(p_gizmo); if (idx != -1) { p_gizmo->free(); @@ -506,10 +516,8 @@ Array Node3D::get_gizmos_bind() const { Vector<Ref<Node3DGizmo>> Node3D::get_gizmos() const { #ifdef TOOLS_ENABLED - return data.gizmos; #else - return Vector<Ref<Node3DGizmo>>(); #endif } @@ -561,7 +569,6 @@ void Node3D::set_as_top_level(bool p_enabled) { data.top_level = p_enabled; data.top_level_active = p_enabled; - } else { data.top_level = p_enabled; } @@ -581,6 +588,7 @@ Ref<World3D> Node3D::get_world_3d() const { void Node3D::_propagate_visibility_changed() { notification(NOTIFICATION_VISIBILITY_CHANGED); emit_signal(SceneStringNames::get_singleton()->visibility_changed); + #ifdef TOOLS_ENABLED if (!data.gizmos.is_empty()) { data.gizmos_dirty = true; @@ -597,33 +605,30 @@ void Node3D::_propagate_visibility_changed() { } void Node3D::show() { - if (data.visible) { - return; - } - - data.visible = true; - - if (!is_inside_tree()) { - return; - } - - _propagate_visibility_changed(); + set_visible(true); } void Node3D::hide() { - if (!data.visible) { + set_visible(false); +} + +void Node3D::set_visible(bool p_visible) { + if (data.visible == p_visible) { return; } - data.visible = false; + data.visible = p_visible; if (!is_inside_tree()) { return; } - _propagate_visibility_changed(); } +bool Node3D::is_visible() const { + return data.visible; +} + bool Node3D::is_visible_in_tree() const { const Node3D *s = this; @@ -637,18 +642,6 @@ bool Node3D::is_visible_in_tree() const { return true; } -void Node3D::set_visible(bool p_visible) { - if (p_visible) { - show(); - } else { - hide(); - } -} - -bool Node3D::is_visible() const { - return data.visible; -} - void Node3D::rotate_object_local(const Vector3 &p_axis, real_t p_angle) { Transform3D t = get_transform(); t.basis.rotate_local(p_axis, p_angle); @@ -757,16 +750,16 @@ Vector3 Node3D::to_global(Vector3 p_local) const { return get_global_transform().xform(p_local); } -void Node3D::set_notify_transform(bool p_enable) { - data.notify_transform = p_enable; +void Node3D::set_notify_transform(bool p_enabled) { + data.notify_transform = p_enabled; } bool Node3D::is_transform_notification_enabled() const { return data.notify_transform; } -void Node3D::set_notify_local_transform(bool p_enable) { - data.notify_local_transform = p_enable; +void Node3D::set_notify_local_transform(bool p_enabled) { + data.notify_local_transform = p_enabled; } bool Node3D::is_local_transform_notification_enabled() const { @@ -845,6 +838,64 @@ void Node3D::_validate_property(PropertyInfo &property) const { } } +bool Node3D::property_can_revert(const String &p_name) { + if (p_name == "basis") { + return true; + } else if (p_name == "scale") { + return true; + } else if (p_name == "quaternion") { + return true; + } else if (p_name == "rotation") { + return true; + } else if (p_name == "position") { + return true; + } + return false; +} + +Variant Node3D::property_get_revert(const String &p_name) { + Variant r_ret; + bool valid = false; + + if (p_name == "basis") { + Variant variant = PropertyUtils::get_property_default_value(this, "transform", &valid); + if (valid && variant.get_type() == Variant::Type::TRANSFORM3D) { + r_ret = Transform3D(variant).get_basis(); + } else { + r_ret = Basis(); + } + } else if (p_name == "scale") { + Variant variant = PropertyUtils::get_property_default_value(this, "transform", &valid); + if (valid && variant.get_type() == Variant::Type::TRANSFORM3D) { + r_ret = Transform3D(variant).get_basis().get_scale(); + } else { + return Vector3(1.0, 1.0, 1.0); + } + } else if (p_name == "quaternion") { + Variant variant = PropertyUtils::get_property_default_value(this, "transform", &valid); + if (valid && variant.get_type() == Variant::Type::TRANSFORM3D) { + r_ret = Quaternion(Transform3D(variant).get_basis()); + } else { + return Quaternion(); + } + } else if (p_name == "rotation") { + Variant variant = PropertyUtils::get_property_default_value(this, "transform", &valid); + if (valid && variant.get_type() == Variant::Type::TRANSFORM3D) { + r_ret = Transform3D(variant).get_basis().get_euler_normalized(data.rotation_order); + } else { + return Vector3(); + } + } else if (p_name == "position") { + Variant variant = PropertyUtils::get_property_default_value(this, "transform", &valid); + if (valid) { + r_ret = Transform3D(variant).get_origin(); + } else { + return Vector3(); + } + } + return r_ret; +} + void Node3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_transform", "local"), &Node3D::set_transform); ClassDB::bind_method(D_METHOD("get_transform"), &Node3D::get_transform); @@ -916,6 +967,9 @@ void Node3D::_bind_methods() { ClassDB::bind_method(D_METHOD("to_local", "global_point"), &Node3D::to_local); ClassDB::bind_method(D_METHOD("to_global", "local_point"), &Node3D::to_global); + ClassDB::bind_method(D_METHOD("property_can_revert", "name"), &Node3D::property_can_revert); + ClassDB::bind_method(D_METHOD("property_get_revert", "name"), &Node3D::property_get_revert); + BIND_CONSTANT(NOTIFICATION_TRANSFORM_CHANGED); BIND_CONSTANT(NOTIFICATION_ENTER_WORLD); BIND_CONSTANT(NOTIFICATION_EXIT_WORLD); @@ -934,6 +988,7 @@ void Node3D::_bind_methods() { //ADD_PROPERTY( PropertyInfo(Variant::TRANSFORM3D,"transform/global",PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR ), "set_global_transform", "get_global_transform") ; ADD_GROUP("Transform", ""); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_transform", "get_transform"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "global_transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_global_transform", "get_global_transform"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "position", PROPERTY_HINT_RANGE, "-99999,99999,0,or_greater,or_lesser,noslider,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"); @@ -943,7 +998,6 @@ void Node3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "rotation_edit_mode", PROPERTY_HINT_ENUM, "Euler,Quaternion,Basis"), "set_rotation_edit_mode", "get_rotation_edit_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "rotation_order", PROPERTY_HINT_ENUM, "XYZ,XZY,YXZ,YZX,ZXY,ZYX"), "set_rotation_order", "get_rotation_order"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "top_level"), "set_as_top_level", "is_set_as_top_level"); - ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_transform", "get_transform"); ADD_GROUP("Visibility", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible"); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "visibility_parent", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "GeometryInstance3D"), "set_visibility_parent", "get_visibility_parent"); diff --git a/scene/3d/node_3d.h b/scene/3d/node_3d.h index 3e21eb12be..4abda66187 100644 --- a/scene/3d/node_3d.h +++ b/scene/3d/node_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -137,6 +137,9 @@ protected: virtual void _validate_property(PropertyInfo &property) const override; + bool property_can_revert(const String &p_name); + Variant property_get_revert(const String &p_name); + public: enum { NOTIFICATION_TRANSFORM_CHANGED = SceneTree::NOTIFICATION_TRANSFORM_CHANGED, @@ -182,12 +185,6 @@ public: virtual bool is_transform_gizmo_visible() const { return data.transform_gizmo_visible; }; #endif - void set_as_top_level(bool p_enabled); - bool is_set_as_top_level() const; - - void set_disable_scale(bool p_enabled); - bool is_scale_disabled() const; - void set_disable_gizmos(bool p_enabled); void update_gizmos(); void set_subgizmo_selection(Ref<Node3DGizmo> p_gizmo, int p_id, Transform3D p_transform = Transform3D()); @@ -198,6 +195,12 @@ public: void remove_gizmo(Ref<Node3DGizmo> p_gizmo); void clear_gizmos(); + void set_as_top_level(bool p_enabled); + bool is_set_as_top_level() const; + + void set_disable_scale(bool p_enabled); + bool is_scale_disabled() const; + _FORCE_INLINE_ bool is_inside_world() const { return data.inside_world; } Transform3D get_relative_transform(const Node *p_parent) const; @@ -223,19 +226,19 @@ public: Vector3 to_local(Vector3 p_global) const; Vector3 to_global(Vector3 p_local) const; - void set_notify_transform(bool p_enable); + void set_notify_transform(bool p_enabled); bool is_transform_notification_enabled() const; - void set_notify_local_transform(bool p_enable); + void set_notify_local_transform(bool p_enabled); bool is_local_transform_notification_enabled() const; void orthonormalize(); void set_identity(); void set_visible(bool p_visible); - bool is_visible() const; void show(); void hide(); + bool is_visible() const; bool is_visible_in_tree() const; void force_update_transform(); diff --git a/scene/3d/occluder_instance_3d.cpp b/scene/3d/occluder_instance_3d.cpp index aeac430cd9..e0e2eae4a5 100644 --- a/scene/3d/occluder_instance_3d.cpp +++ b/scene/3d/occluder_instance_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -291,7 +291,7 @@ void OccluderInstance3D::_bake_node(Node *p_node, PackedVector3Array &r_vertices } OccluderInstance3D::BakeError OccluderInstance3D::bake(Node *p_from_node, String p_occluder_path) { - if (p_occluder_path == "") { + if (p_occluder_path.is_empty()) { if (get_occluder().is_null()) { return BAKE_ERROR_NO_SAVE_PATH; } diff --git a/scene/3d/occluder_instance_3d.h b/scene/3d/occluder_instance_3d.h index 173614b80c..8a8d4c9af4 100644 --- a/scene/3d/occluder_instance_3d.h +++ b/scene/3d/occluder_instance_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp index a0eac76e39..6e1c9ef781 100644 --- a/scene/3d/path_3d.cpp +++ b/scene/3d/path_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/path_3d.h b/scene/3d/path_3d.h index 1ffe291100..32ca5a1beb 100644 --- a/scene/3d/path_3d.h +++ b/scene/3d/path_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index 393e29e398..b3192a5bb5 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -875,30 +875,59 @@ int RigidDynamicBody3D::get_max_contacts_reported() const { return max_contacts_reported; } -void RigidDynamicBody3D::add_central_force(const Vector3 &p_force) { - PhysicsServer3D::get_singleton()->body_add_central_force(get_rid(), p_force); +void RigidDynamicBody3D::apply_central_impulse(const Vector3 &p_impulse) { + PhysicsServer3D::get_singleton()->body_apply_central_impulse(get_rid(), p_impulse); } -void RigidDynamicBody3D::add_force(const Vector3 &p_force, const Vector3 &p_position) { +void RigidDynamicBody3D::apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position) { PhysicsServer3D *singleton = PhysicsServer3D::get_singleton(); - singleton->body_add_force(get_rid(), p_force, p_position); + singleton->body_apply_impulse(get_rid(), p_impulse, p_position); } -void RigidDynamicBody3D::add_torque(const Vector3 &p_torque) { - PhysicsServer3D::get_singleton()->body_add_torque(get_rid(), p_torque); +void RigidDynamicBody3D::apply_torque_impulse(const Vector3 &p_impulse) { + PhysicsServer3D::get_singleton()->body_apply_torque_impulse(get_rid(), p_impulse); } -void RigidDynamicBody3D::apply_central_impulse(const Vector3 &p_impulse) { - PhysicsServer3D::get_singleton()->body_apply_central_impulse(get_rid(), p_impulse); +void RigidDynamicBody3D::apply_central_force(const Vector3 &p_force) { + PhysicsServer3D::get_singleton()->body_apply_central_force(get_rid(), p_force); } -void RigidDynamicBody3D::apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position) { +void RigidDynamicBody3D::apply_force(const Vector3 &p_force, const Vector3 &p_position) { PhysicsServer3D *singleton = PhysicsServer3D::get_singleton(); - singleton->body_apply_impulse(get_rid(), p_impulse, p_position); + singleton->body_apply_force(get_rid(), p_force, p_position); } -void RigidDynamicBody3D::apply_torque_impulse(const Vector3 &p_impulse) { - PhysicsServer3D::get_singleton()->body_apply_torque_impulse(get_rid(), p_impulse); +void RigidDynamicBody3D::apply_torque(const Vector3 &p_torque) { + PhysicsServer3D::get_singleton()->body_apply_torque(get_rid(), p_torque); +} + +void RigidDynamicBody3D::add_constant_central_force(const Vector3 &p_force) { + PhysicsServer3D::get_singleton()->body_add_constant_central_force(get_rid(), p_force); +} + +void RigidDynamicBody3D::add_constant_force(const Vector3 &p_force, const Vector3 &p_position) { + PhysicsServer3D *singleton = PhysicsServer3D::get_singleton(); + singleton->body_add_constant_force(get_rid(), p_force, p_position); +} + +void RigidDynamicBody3D::add_constant_torque(const Vector3 &p_torque) { + PhysicsServer3D::get_singleton()->body_add_constant_torque(get_rid(), p_torque); +} + +void RigidDynamicBody3D::set_constant_force(const Vector3 &p_force) { + PhysicsServer3D::get_singleton()->body_set_constant_force(get_rid(), p_force); +} + +Vector3 RigidDynamicBody3D::get_constant_force() const { + return PhysicsServer3D::get_singleton()->body_get_constant_force(get_rid()); +} + +void RigidDynamicBody3D::set_constant_torque(const Vector3 &p_torque) { + PhysicsServer3D::get_singleton()->body_set_constant_torque(get_rid(), p_torque); +} + +Vector3 RigidDynamicBody3D::get_constant_torque() const { + return PhysicsServer3D::get_singleton()->body_get_constant_torque(get_rid()); } void RigidDynamicBody3D::set_use_continuous_collision_detection(bool p_enable) { @@ -1024,14 +1053,24 @@ void RigidDynamicBody3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_axis_velocity", "axis_velocity"), &RigidDynamicBody3D::set_axis_velocity); - ClassDB::bind_method(D_METHOD("add_central_force", "force"), &RigidDynamicBody3D::add_central_force); - ClassDB::bind_method(D_METHOD("add_force", "force", "position"), &RigidDynamicBody3D::add_force, Vector3()); - ClassDB::bind_method(D_METHOD("add_torque", "torque"), &RigidDynamicBody3D::add_torque); - ClassDB::bind_method(D_METHOD("apply_central_impulse", "impulse"), &RigidDynamicBody3D::apply_central_impulse); ClassDB::bind_method(D_METHOD("apply_impulse", "impulse", "position"), &RigidDynamicBody3D::apply_impulse, Vector3()); ClassDB::bind_method(D_METHOD("apply_torque_impulse", "impulse"), &RigidDynamicBody3D::apply_torque_impulse); + ClassDB::bind_method(D_METHOD("apply_central_force", "force"), &RigidDynamicBody3D::apply_central_force); + ClassDB::bind_method(D_METHOD("apply_force", "force", "position"), &RigidDynamicBody3D::apply_force, Vector3()); + ClassDB::bind_method(D_METHOD("apply_torque", "torque"), &RigidDynamicBody3D::apply_torque); + + ClassDB::bind_method(D_METHOD("add_constant_central_force", "force"), &RigidDynamicBody3D::add_constant_central_force); + ClassDB::bind_method(D_METHOD("add_constant_force", "force", "position"), &RigidDynamicBody3D::add_constant_force, Vector3()); + ClassDB::bind_method(D_METHOD("add_constant_torque", "torque"), &RigidDynamicBody3D::add_constant_torque); + + ClassDB::bind_method(D_METHOD("set_constant_force", "force"), &RigidDynamicBody3D::set_constant_force); + ClassDB::bind_method(D_METHOD("get_constant_force"), &RigidDynamicBody3D::get_constant_force); + + ClassDB::bind_method(D_METHOD("set_constant_torque", "torque"), &RigidDynamicBody3D::set_constant_torque); + ClassDB::bind_method(D_METHOD("get_constant_torque"), &RigidDynamicBody3D::get_constant_torque); + ClassDB::bind_method(D_METHOD("set_sleeping", "sleeping"), &RigidDynamicBody3D::set_sleeping); ClassDB::bind_method(D_METHOD("is_sleeping"), &RigidDynamicBody3D::is_sleeping); @@ -1075,6 +1114,9 @@ void RigidDynamicBody3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "angular_velocity"), "set_angular_velocity", "get_angular_velocity"); ADD_PROPERTY(PropertyInfo(Variant::INT, "angular_damp_mode", PROPERTY_HINT_ENUM, "Combine,Replace"), "set_angular_damp_mode", "get_angular_damp_mode"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); + ADD_GROUP("Constant Forces", "constant_"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "constant_force"), "set_constant_force", "get_constant_force"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "constant_torque"), "set_constant_torque", "get_constant_torque"); ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape_index"), PropertyInfo(Variant::INT, "local_shape_index"))); ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape_index"), PropertyInfo(Variant::INT, "local_shape_index"))); diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h index 2ea796d335..e37b841117 100644 --- a/scene/3d/physics_body_3d.h +++ b/scene/3d/physics_body_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -306,14 +306,24 @@ public: Array get_colliding_bodies() const; - void add_central_force(const Vector3 &p_force); - void add_force(const Vector3 &p_force, const Vector3 &p_position = Vector3()); - void add_torque(const Vector3 &p_torque); - void apply_central_impulse(const Vector3 &p_impulse); void apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position = Vector3()); void apply_torque_impulse(const Vector3 &p_impulse); + void apply_central_force(const Vector3 &p_force); + void apply_force(const Vector3 &p_force, const Vector3 &p_position = Vector3()); + void apply_torque(const Vector3 &p_torque); + + void add_constant_central_force(const Vector3 &p_force); + void add_constant_force(const Vector3 &p_force, const Vector3 &p_position = Vector3()); + void add_constant_torque(const Vector3 &p_torque); + + void set_constant_force(const Vector3 &p_force); + Vector3 get_constant_force() const; + + void set_constant_torque(const Vector3 &p_torque); + Vector3 get_constant_torque() const; + virtual TypedArray<String> get_configuration_warnings() const override; RigidDynamicBody3D(); diff --git a/scene/3d/position_3d.cpp b/scene/3d/position_3d.cpp index 9747465103..7dc1b1ace0 100644 --- a/scene/3d/position_3d.cpp +++ b/scene/3d/position_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/position_3d.h b/scene/3d/position_3d.h index 065b14c3bd..5514399e6e 100644 --- a/scene/3d/position_3d.h +++ b/scene/3d/position_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/proximity_group_3d.cpp b/scene/3d/proximity_group_3d.cpp deleted file mode 100644 index 23df00c1f6..0000000000 --- a/scene/3d/proximity_group_3d.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/*************************************************************************/ -/* proximity_group_3d.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 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 "proximity_group_3d.h" - -#include "core/math/math_funcs.h" - -void ProximityGroup3D::_clear_groups() { - Map<StringName, uint32_t>::Element *E; - const int size = 16; - - do { - StringName remove_list[size]; - E = groups.front(); - int num = 0; - while (E && num < size) { - if (E->get() != group_version) { - remove_list[num++] = E->key(); - } - - E = E->next(); - } - for (int i = 0; i < num; i++) { - groups.erase(remove_list[i]); - } - } while (E); -} - -void ProximityGroup3D::_update_groups() { - if (grid_radius == Vector3(0, 0, 0)) { - return; - } - - ++group_version; - - Vector3 pos = get_global_transform().get_origin(); - Vector3 vcell = pos / cell_size; - int cell[3] = { Math::fast_ftoi(vcell.x), Math::fast_ftoi(vcell.y), Math::fast_ftoi(vcell.z) }; - - _add_groups(cell, group_name, 0); - - _clear_groups(); -} - -void ProximityGroup3D::_add_groups(int *p_cell, String p_base, int p_depth) { - p_base = p_base + "|"; - if (grid_radius[p_depth] == 0) { - if (p_depth == 2) { - _new_group(p_base); - } else { - _add_groups(p_cell, p_base, p_depth + 1); - } - } - - int start = p_cell[p_depth] - grid_radius[p_depth]; - int end = p_cell[p_depth] + grid_radius[p_depth]; - - for (int i = start; i <= end; i++) { - String gname = p_base + itos(i); - if (p_depth == 2) { - _new_group(gname); - } else { - _add_groups(p_cell, gname, p_depth + 1); - } - } -} - -void ProximityGroup3D::_new_group(StringName p_name) { - const Map<StringName, uint32_t>::Element *E = groups.find(p_name); - if (!E) { - add_to_group(p_name); - } - - groups[p_name] = group_version; -} - -void ProximityGroup3D::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_EXIT_TREE: - ++group_version; - _clear_groups(); - break; - case NOTIFICATION_TRANSFORM_CHANGED: - _update_groups(); - break; - } -} - -void ProximityGroup3D::broadcast(String p_method, Variant p_parameters) { - Map<StringName, uint32_t>::Element *E; - E = groups.front(); - while (E) { - get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFAULT, E->key(), "_proximity_group_broadcast", p_method, p_parameters); - E = E->next(); - } -} - -void ProximityGroup3D::_proximity_group_broadcast(String p_method, Variant p_parameters) { - if (dispatch_mode == MODE_PROXY) { - ERR_FAIL_COND(!is_inside_tree()); - get_parent()->call(p_method, p_parameters); - } else { - emit_signal(SNAME("broadcast"), p_method, p_parameters); - } -} - -void ProximityGroup3D::set_group_name(const String &p_group_name) { - group_name = p_group_name; -} - -String ProximityGroup3D::get_group_name() const { - return group_name; -} - -void ProximityGroup3D::set_dispatch_mode(DispatchMode p_mode) { - dispatch_mode = p_mode; -} - -ProximityGroup3D::DispatchMode ProximityGroup3D::get_dispatch_mode() const { - return dispatch_mode; -} - -void ProximityGroup3D::set_grid_radius(const Vector3 &p_radius) { - grid_radius = p_radius; -} - -Vector3 ProximityGroup3D::get_grid_radius() const { - return grid_radius; -} - -void ProximityGroup3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_group_name", "name"), &ProximityGroup3D::set_group_name); - ClassDB::bind_method(D_METHOD("get_group_name"), &ProximityGroup3D::get_group_name); - ClassDB::bind_method(D_METHOD("set_dispatch_mode", "mode"), &ProximityGroup3D::set_dispatch_mode); - ClassDB::bind_method(D_METHOD("get_dispatch_mode"), &ProximityGroup3D::get_dispatch_mode); - ClassDB::bind_method(D_METHOD("set_grid_radius", "radius"), &ProximityGroup3D::set_grid_radius); - ClassDB::bind_method(D_METHOD("get_grid_radius"), &ProximityGroup3D::get_grid_radius); - - ClassDB::bind_method(D_METHOD("broadcast", "method", "parameters"), &ProximityGroup3D::broadcast); - - ClassDB::bind_method(D_METHOD("_proximity_group_broadcast", "method", "parameters"), &ProximityGroup3D::_proximity_group_broadcast); - - ADD_PROPERTY(PropertyInfo(Variant::STRING, "group_name"), "set_group_name", "get_group_name"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "dispatch_mode", PROPERTY_HINT_ENUM, "Proxy,Signal"), "set_dispatch_mode", "get_dispatch_mode"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "grid_radius"), "set_grid_radius", "get_grid_radius"); - - ADD_SIGNAL(MethodInfo("broadcast", PropertyInfo(Variant::STRING, "method"), PropertyInfo(Variant::ARRAY, "parameters"))); - - BIND_ENUM_CONSTANT(MODE_PROXY); - BIND_ENUM_CONSTANT(MODE_SIGNAL); -} - -ProximityGroup3D::ProximityGroup3D() { - set_notify_transform(true); -} diff --git a/scene/3d/ray_cast_3d.cpp b/scene/3d/ray_cast_3d.cpp index bfa397a1f5..3bb65d07a0 100644 --- a/scene/3d/ray_cast_3d.cpp +++ b/scene/3d/ray_cast_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -355,7 +355,7 @@ void RayCast3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "debug_shape_thickness", PROPERTY_HINT_RANGE, "1,5"), "set_debug_shape_thickness", "get_debug_shape_thickness"); } -float RayCast3D::get_debug_shape_thickness() const { +int RayCast3D::get_debug_shape_thickness() const { return debug_shape_thickness; } @@ -384,7 +384,7 @@ void RayCast3D::_update_debug_shape_vertices() { } } -void RayCast3D::set_debug_shape_thickness(const float p_debug_shape_thickness) { +void RayCast3D::set_debug_shape_thickness(const int p_debug_shape_thickness) { debug_shape_thickness = p_debug_shape_thickness; update_gizmos(); diff --git a/scene/3d/ray_cast_3d.h b/scene/3d/ray_cast_3d.h index 5c2a61c35b..a53e2c83fc 100644 --- a/scene/3d/ray_cast_3d.h +++ b/scene/3d/ray_cast_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -105,8 +105,8 @@ public: Ref<StandardMaterial3D> get_debug_material(); - float get_debug_shape_thickness() const; - void set_debug_shape_thickness(const float p_debug_thickness); + int get_debug_shape_thickness() const; + void set_debug_shape_thickness(const int p_debug_thickness); void force_raycast_update(); bool is_colliding() const; diff --git a/scene/3d/reflection_probe.cpp b/scene/3d/reflection_probe.cpp index f7f19596a7..be655e71db 100644 --- a/scene/3d/reflection_probe.cpp +++ b/scene/3d/reflection_probe.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -76,13 +76,13 @@ float ReflectionProbe::get_max_distance() const { return max_distance; } -void ReflectionProbe::set_lod_threshold(float p_pixels) { - lod_threshold = p_pixels; - RS::get_singleton()->reflection_probe_set_lod_threshold(probe, p_pixels); +void ReflectionProbe::set_mesh_lod_threshold(float p_pixels) { + mesh_lod_threshold = p_pixels; + RS::get_singleton()->reflection_probe_set_mesh_lod_threshold(probe, p_pixels); } -float ReflectionProbe::get_lod_threshold() const { - return lod_threshold; +float ReflectionProbe::get_mesh_lod_threshold() const { + return mesh_lod_threshold; } void ReflectionProbe::set_extents(const Vector3 &p_extents) { @@ -207,8 +207,8 @@ void ReflectionProbe::_bind_methods() { ClassDB::bind_method(D_METHOD("set_max_distance", "max_distance"), &ReflectionProbe::set_max_distance); ClassDB::bind_method(D_METHOD("get_max_distance"), &ReflectionProbe::get_max_distance); - ClassDB::bind_method(D_METHOD("set_lod_threshold", "ratio"), &ReflectionProbe::set_lod_threshold); - ClassDB::bind_method(D_METHOD("get_lod_threshold"), &ReflectionProbe::get_lod_threshold); + ClassDB::bind_method(D_METHOD("set_mesh_lod_threshold", "ratio"), &ReflectionProbe::set_mesh_lod_threshold); + ClassDB::bind_method(D_METHOD("get_mesh_lod_threshold"), &ReflectionProbe::get_mesh_lod_threshold); ClassDB::bind_method(D_METHOD("set_extents", "extents"), &ReflectionProbe::set_extents); ClassDB::bind_method(D_METHOD("get_extents"), &ReflectionProbe::get_extents); @@ -240,7 +240,7 @@ void ReflectionProbe::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interior"), "set_as_interior", "is_set_as_interior"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enable_shadows"), "set_enable_shadows", "are_shadows_enabled"); ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_cull_mask", "get_cull_mask"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lod_threshold", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_lod_threshold", "get_lod_threshold"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mesh_lod_threshold", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_mesh_lod_threshold", "get_mesh_lod_threshold"); ADD_GROUP("Ambient", "ambient_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "ambient_mode", PROPERTY_HINT_ENUM, "Disabled,Environment,Constant Color"), "set_ambient_mode", "get_ambient_mode"); diff --git a/scene/3d/reflection_probe.h b/scene/3d/reflection_probe.h index d1b9b12f65..d0643496a4 100644 --- a/scene/3d/reflection_probe.h +++ b/scene/3d/reflection_probe.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -60,7 +60,7 @@ private: AmbientMode ambient_mode = AMBIENT_ENVIRONMENT; Color ambient_color = Color(0, 0, 0); float ambient_color_energy = 1.0; - float lod_threshold = 1.0; + float mesh_lod_threshold = 1.0; uint32_t cull_mask = (1 << 20) - 1; UpdateMode update_mode = UPDATE_ONCE; @@ -88,8 +88,8 @@ public: void set_max_distance(float p_distance); float get_max_distance() const; - void set_lod_threshold(float p_pixels); - float get_lod_threshold() const; + void set_mesh_lod_threshold(float p_pixels); + float get_mesh_lod_threshold() const; void set_extents(const Vector3 &p_extents); Vector3 get_extents() const; diff --git a/scene/3d/remote_transform_3d.cpp b/scene/3d/remote_transform_3d.cpp index d890609e23..2770b6f40c 100644 --- a/scene/3d/remote_transform_3d.cpp +++ b/scene/3d/remote_transform_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/remote_transform_3d.h b/scene/3d/remote_transform_3d.h index 321bd3b51e..03bb253578 100644 --- a/scene/3d/remote_transform_3d.h +++ b/scene/3d/remote_transform_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 04b5b88ef8..3957a1653f 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -506,7 +506,7 @@ int Skeleton3D::get_bone_axis_forward_enum(int p_bone) { // Skeleton creation api void Skeleton3D::add_bone(const String &p_name) { - ERR_FAIL_COND(p_name == "" || p_name.find(":") != -1 || p_name.find("/") != -1); + ERR_FAIL_COND(p_name.is_empty() || p_name.find(":") != -1 || p_name.find("/") != -1); for (int i = 0; i < bones.size(); i++) { ERR_FAIL_COND(bones[i].name == p_name); diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h index f7bc3df94e..80ff2a1f79 100644 --- a/scene/3d/skeleton_3d.h +++ b/scene/3d/skeleton_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/skeleton_ik_3d.cpp b/scene/3d/skeleton_ik_3d.cpp index 1498955ec0..c645009c72 100644 --- a/scene/3d/skeleton_ik_3d.cpp +++ b/scene/3d/skeleton_ik_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -28,10 +28,6 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -/** - * @author AndreaCatania - */ - #include "skeleton_ik_3d.h" #ifndef _3D_DISABLED diff --git a/scene/3d/skeleton_ik_3d.h b/scene/3d/skeleton_ik_3d.h index ccb25bcd4c..3ced5c49d3 100644 --- a/scene/3d/skeleton_ik_3d.h +++ b/scene/3d/skeleton_ik_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/soft_dynamic_body_3d.cpp b/scene/3d/soft_dynamic_body_3d.cpp index d9907430fc..8ee777bcbf 100644 --- a/scene/3d/soft_dynamic_body_3d.cpp +++ b/scene/3d/soft_dynamic_body_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/soft_dynamic_body_3d.h b/scene/3d/soft_dynamic_body_3d.h index daef9acac0..c30ec701c7 100644 --- a/scene/3d/soft_dynamic_body_3d.h +++ b/scene/3d/soft_dynamic_body_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/spring_arm_3d.cpp b/scene/3d/spring_arm_3d.cpp index 0b5af8823b..e0cd44e05b 100644 --- a/scene/3d/spring_arm_3d.cpp +++ b/scene/3d/spring_arm_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/spring_arm_3d.h b/scene/3d/spring_arm_3d.h index 63505ab9d3..b247ea1707 100644 --- a/scene/3d/spring_arm_3d.h +++ b/scene/3d/spring_arm_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index 197a5c0f27..a37fce9469 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -141,15 +141,6 @@ real_t SpriteBase3D::get_pixel_size() const { return pixel_size; } -void SpriteBase3D::set_opacity(float p_amount) { - opacity = p_amount; - _queue_update(); -} - -float SpriteBase3D::get_opacity() const { - return opacity; -} - void SpriteBase3D::set_axis(Vector3::Axis p_axis) { ERR_FAIL_INDEX(p_axis, 3); axis = p_axis; @@ -295,9 +286,6 @@ void SpriteBase3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_modulate", "modulate"), &SpriteBase3D::set_modulate); ClassDB::bind_method(D_METHOD("get_modulate"), &SpriteBase3D::get_modulate); - ClassDB::bind_method(D_METHOD("set_opacity", "opacity"), &SpriteBase3D::set_opacity); - ClassDB::bind_method(D_METHOD("get_opacity"), &SpriteBase3D::get_opacity); - ClassDB::bind_method(D_METHOD("set_pixel_size", "pixel_size"), &SpriteBase3D::set_pixel_size); ClassDB::bind_method(D_METHOD("get_pixel_size"), &SpriteBase3D::get_pixel_size); @@ -324,7 +312,6 @@ void SpriteBase3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_h"), "set_flip_h", "is_flipped_h"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_v"), "set_flip_v", "is_flipped_v"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "modulate"), "set_modulate", "get_modulate"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "opacity", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_opacity", "get_opacity"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pixel_size", PROPERTY_HINT_RANGE, "0.0001,128,0.0001"), "set_pixel_size", "get_pixel_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "axis", PROPERTY_HINT_ENUM, "X-Axis,Y-Axis,Z-Axis"), "set_axis", "get_axis"); ADD_GROUP("Flags", ""); @@ -468,7 +455,6 @@ void Sprite3D::_draw() { } Color color = _get_color_accum(); - color.a *= get_opacity(); real_t pixel_size = get_pixel_size(); @@ -837,7 +823,6 @@ void AnimatedSprite3D::_draw() { } Color color = _get_color_accum(); - color.a *= get_opacity(); real_t pixel_size = get_pixel_size(); @@ -998,13 +983,13 @@ void AnimatedSprite3D::_validate_property(PropertyInfo &property) const { } property.hint_string += String(E->get()); - if (animation == E) { + if (animation == E->get()) { current_found = true; } } if (!current_found) { - if (property.hint_string == String()) { + if (property.hint_string.is_empty()) { property.hint_string = String(animation); } else { property.hint_string = String(animation) + "," + property.hint_string; diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h index 61448c0e32..985103e190 100644 --- a/scene/3d/sprite_3d.h +++ b/scene/3d/sprite_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -69,7 +69,6 @@ private: bool vflip = false; Color modulate = Color(1, 1, 1, 1); - float opacity = 1.0; Vector3::Axis axis = Vector3::AXIS_Z; real_t pixel_size = 0.01; @@ -121,9 +120,6 @@ public: void set_modulate(const Color &p_color); Color get_modulate() const; - void set_opacity(float p_amount); - float get_opacity() const; - void set_pixel_size(real_t p_amount); real_t get_pixel_size() const; diff --git a/scene/3d/vehicle_body_3d.cpp b/scene/3d/vehicle_body_3d.cpp index 90db093137..a5fd3a7dd0 100644 --- a/scene/3d/vehicle_body_3d.cpp +++ b/scene/3d/vehicle_body_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -225,6 +225,10 @@ bool VehicleWheel3D::is_in_contact() const { return m_raycastInfo.m_isInContact; } +Node3D *VehicleWheel3D::get_contact_body() const { + return m_raycastInfo.m_groundObject; +} + void VehicleWheel3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_radius", "length"), &VehicleWheel3D::set_radius); ClassDB::bind_method(D_METHOD("get_radius"), &VehicleWheel3D::get_radius); @@ -257,6 +261,7 @@ void VehicleWheel3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_friction_slip"), &VehicleWheel3D::get_friction_slip); ClassDB::bind_method(D_METHOD("is_in_contact"), &VehicleWheel3D::is_in_contact); + ClassDB::bind_method(D_METHOD("get_contact_body"), &VehicleWheel3D::get_contact_body); ClassDB::bind_method(D_METHOD("set_roll_influence", "roll_influence"), &VehicleWheel3D::set_roll_influence); ClassDB::bind_method(D_METHOD("get_roll_influence"), &VehicleWheel3D::get_roll_influence); @@ -413,9 +418,8 @@ real_t VehicleBody3D::_ray_cast(int p_idx, PhysicsDirectBodyState3D *s) { ray_params.exclude = exclude; ray_params.collision_mask = get_collision_mask(); - bool col = ss->intersect_ray(ray_params, rr); - wheel.m_raycastInfo.m_groundObject = nullptr; + bool col = ss->intersect_ray(ray_params, rr); if (col) { param = source.distance_to(rr.position) / source.distance_to(target); diff --git a/scene/3d/vehicle_body_3d.h b/scene/3d/vehicle_body_3d.h index a798c76c1f..d2371d819b 100644 --- a/scene/3d/vehicle_body_3d.h +++ b/scene/3d/vehicle_body_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -129,6 +129,8 @@ public: bool is_in_contact() const; + Node3D *get_contact_body() const; + void set_roll_influence(real_t p_value); real_t get_roll_influence() const; diff --git a/scene/3d/velocity_tracker_3d.cpp b/scene/3d/velocity_tracker_3d.cpp index 200664a41b..5bfe519440 100644 --- a/scene/3d/velocity_tracker_3d.cpp +++ b/scene/3d/velocity_tracker_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/velocity_tracker_3d.h b/scene/3d/velocity_tracker_3d.h index 827c3f5bd8..7fdcacc9c1 100644 --- a/scene/3d/velocity_tracker_3d.h +++ b/scene/3d/velocity_tracker_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/visible_on_screen_notifier_3d.cpp b/scene/3d/visible_on_screen_notifier_3d.cpp index 3d0bc3df9c..44d2a3e03f 100644 --- a/scene/3d/visible_on_screen_notifier_3d.cpp +++ b/scene/3d/visible_on_screen_notifier_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/visible_on_screen_notifier_3d.h b/scene/3d/visible_on_screen_notifier_3d.h index fb7137c4f0..852c7e2ed3 100644 --- a/scene/3d/visible_on_screen_notifier_3d.h +++ b/scene/3d/visible_on_screen_notifier_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp index d407592376..0db2fe9fc6 100644 --- a/scene/3d/visual_instance_3d.cpp +++ b/scene/3d/visual_instance_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -152,6 +152,15 @@ Ref<Material> GeometryInstance3D::get_material_override() const { return material_override; } +void GeometryInstance3D::set_material_overlay(const Ref<Material> &p_material) { + material_overlay = p_material; + RS::get_singleton()->instance_geometry_set_material_overlay(get_instance(), p_material.is_valid() ? p_material->get_rid() : RID()); +} + +Ref<Material> GeometryInstance3D::get_material_overlay() const { + return material_overlay; +} + void GeometryInstance3D::set_transparecy(float p_transparency) { transparency = CLAMP(p_transparency, 0.0f, 1.0f); RS::get_singleton()->instance_geometry_set_transparency(get_instance(), transparency); @@ -184,6 +193,7 @@ float GeometryInstance3D::get_visibility_range_end() const { void GeometryInstance3D::set_visibility_range_begin_margin(float p_dist) { visibility_range_begin_margin = p_dist; RS::get_singleton()->instance_geometry_set_visibility_range(get_instance(), visibility_range_begin, visibility_range_end, visibility_range_begin_margin, visibility_range_end_margin, (RS::VisibilityRangeFadeMode)visibility_range_fade_mode); + update_configuration_warnings(); } float GeometryInstance3D::get_visibility_range_begin_margin() const { @@ -193,6 +203,7 @@ float GeometryInstance3D::get_visibility_range_begin_margin() const { void GeometryInstance3D::set_visibility_range_end_margin(float p_dist) { visibility_range_end_margin = p_dist; RS::get_singleton()->instance_geometry_set_visibility_range(get_instance(), visibility_range_begin, visibility_range_end, visibility_range_begin_margin, visibility_range_end_margin, (RS::VisibilityRangeFadeMode)visibility_range_fade_mode); + update_configuration_warnings(); } float GeometryInstance3D::get_visibility_range_end_margin() const { @@ -202,6 +213,7 @@ float GeometryInstance3D::get_visibility_range_end_margin() const { void GeometryInstance3D::set_visibility_range_fade_mode(VisibilityRangeFadeMode p_mode) { visibility_range_fade_mode = p_mode; RS::get_singleton()->instance_geometry_set_visibility_range(get_instance(), visibility_range_begin, visibility_range_end, visibility_range_begin_margin, visibility_range_end_margin, (RS::VisibilityRangeFadeMode)visibility_range_fade_mode); + update_configuration_warnings(); } GeometryInstance3D::VisibilityRangeFadeMode GeometryInstance3D::get_visibility_range_fade_mode() const { @@ -380,6 +392,14 @@ TypedArray<String> GeometryInstance3D::get_configuration_warnings() const { warnings.push_back(TTR("The GeometryInstance3D visibility range's End distance is set to a non-zero value, but is lower than the Begin distance.\nThis means the GeometryInstance3D will never be visible.\nTo resolve this, set the End distance to 0 or to a value greater than the Begin distance.")); } + if ((visibility_range_fade_mode == VISIBILITY_RANGE_FADE_SELF || visibility_range_fade_mode == VISIBILITY_RANGE_FADE_DEPENDENCIES) && !Math::is_zero_approx(visibility_range_begin) && Math::is_zero_approx(visibility_range_begin_margin)) { + warnings.push_back(TTR("The GeometryInstance3D is configured to fade in smoothly over distance, but the fade transition distance is set to 0.\nTo resolve this, increase Visibility Range Begin Margin above 0.")); + } + + if ((visibility_range_fade_mode == VISIBILITY_RANGE_FADE_SELF || visibility_range_fade_mode == VISIBILITY_RANGE_FADE_DEPENDENCIES) && !Math::is_zero_approx(visibility_range_end) && Math::is_zero_approx(visibility_range_end_margin)) { + warnings.push_back(TTR("The GeometryInstance3D is configured to fade out smoothly over distance, but the fade transition distance is set to 0.\nTo resolve this, increase Visibility Range End Margin above 0.")); + } + return warnings; } @@ -387,6 +407,9 @@ void GeometryInstance3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_material_override", "material"), &GeometryInstance3D::set_material_override); ClassDB::bind_method(D_METHOD("get_material_override"), &GeometryInstance3D::get_material_override); + ClassDB::bind_method(D_METHOD("set_material_overlay", "material"), &GeometryInstance3D::set_material_overlay); + ClassDB::bind_method(D_METHOD("get_material_overlay"), &GeometryInstance3D::get_material_overlay); + ClassDB::bind_method(D_METHOD("set_cast_shadows_setting", "shadow_casting_setting"), &GeometryInstance3D::set_cast_shadows_setting); ClassDB::bind_method(D_METHOD("get_cast_shadows_setting"), &GeometryInstance3D::get_cast_shadows_setting); @@ -432,6 +455,7 @@ void GeometryInstance3D::_bind_methods() { ADD_GROUP("Geometry", ""); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material_override", PROPERTY_HINT_RESOURCE_TYPE, "BaseMaterial3D,ShaderMaterial", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE), "set_material_override", "get_material_override"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material_overlay", PROPERTY_HINT_RESOURCE_TYPE, "BaseMaterial3D,ShaderMaterial", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE), "set_material_overlay", "get_material_overlay"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "transparency", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_transparency", "get_transparency"); ADD_PROPERTY(PropertyInfo(Variant::INT, "cast_shadow", PROPERTY_HINT_ENUM, "Off,On,Double-Sided,Shadows Only"), "set_cast_shadows_setting", "get_cast_shadows_setting"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "extra_cull_margin", PROPERTY_HINT_RANGE, "0,16384,0.01"), "set_extra_cull_margin", "get_extra_cull_margin"); diff --git a/scene/3d/visual_instance_3d.h b/scene/3d/visual_instance_3d.h index acdbc4666a..dd0eb25001 100644 --- a/scene/3d/visual_instance_3d.h +++ b/scene/3d/visual_instance_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -110,6 +110,7 @@ public: private: ShadowCastingSetting shadow_casting_setting = SHADOW_CASTING_SETTING_ON; Ref<Material> material_override; + Ref<Material> material_overlay; float visibility_range_begin = 0.0; float visibility_range_end = 0.0; @@ -164,6 +165,9 @@ public: void set_material_override(const Ref<Material> &p_material); Ref<Material> get_material_override() const; + void set_material_overlay(const Ref<Material> &p_material); + Ref<Material> get_material_overlay() const; + void set_extra_cull_margin(float p_margin); float get_extra_cull_margin() const; diff --git a/scene/3d/voxel_gi.cpp b/scene/3d/voxel_gi.cpp index c7108cbae0..35ac1792e9 100644 --- a/scene/3d/voxel_gi.cpp +++ b/scene/3d/voxel_gi.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -227,7 +227,7 @@ void VoxelGIData::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "dynamic_range", PROPERTY_HINT_RANGE, "0,8,0.01"), "set_dynamic_range", "get_dynamic_range"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dynamic_range", PROPERTY_HINT_RANGE, "1,8,0.01"), "set_dynamic_range", "get_dynamic_range"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_energy", "get_energy"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bias", PROPERTY_HINT_RANGE, "0,8,0.01"), "set_bias", "get_bias"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "normal_bias", PROPERTY_HINT_RANGE, "0,8,0.01"), "set_normal_bias", "get_normal_bias"); diff --git a/scene/3d/voxel_gi.h b/scene/3d/voxel_gi.h index 5d0dda1ba3..3678bd4f3b 100644 --- a/scene/3d/voxel_gi.h +++ b/scene/3d/voxel_gi.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -45,7 +45,7 @@ class VoxelGIData : public Resource { AABB bounds; Vector3 octree_size; - float dynamic_range = 4.0; + float dynamic_range = 2.0; float energy = 1.0; float bias = 1.5; float normal_bias = 0.0; diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp index aa1236521d..f56e3caa4b 100644 --- a/scene/3d/voxelizer.cpp +++ b/scene/3d/voxelizer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/voxelizer.h b/scene/3d/voxelizer.h index 09c126bc4e..dc7569d17c 100644 --- a/scene/3d/voxelizer.h +++ b/scene/3d/voxelizer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/world_environment.cpp b/scene/3d/world_environment.cpp index 4eeb987dde..98f28a8cff 100644 --- a/scene/3d/world_environment.cpp +++ b/scene/3d/world_environment.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/world_environment.h b/scene/3d/world_environment.h index 310d1e96a5..8dbb57364c 100644 --- a/scene/3d/world_environment.h +++ b/scene/3d/world_environment.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/xr_nodes.cpp b/scene/3d/xr_nodes.cpp index a16820cbdc..a054f35d2e 100644 --- a/scene/3d/xr_nodes.cpp +++ b/scene/3d/xr_nodes.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/3d/xr_nodes.h b/scene/3d/xr_nodes.h index 5e7d06093d..5675cbd944 100644 --- a/scene/3d/xr_nodes.h +++ b/scene/3d/xr_nodes.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -34,13 +34,10 @@ #include "scene/3d/camera_3d.h" #include "servers/xr/xr_positional_tracker.h" -/** - @author Bastiaan Olij <mux213@gmail.com> -**/ - /* XRCamera is a subclass of camera which will register itself with its parent XROrigin and as a result is automatically positioned */ + class XRCamera3D : public Camera3D { GDCLASS(XRCamera3D, Camera3D); @@ -181,6 +178,7 @@ public: Our camera and controllers will always be child nodes and thus place relative to this origin point. This node will automatically locate any camera child nodes and update its position while our XRController3D node will handle tracked controllers. */ + class XROrigin3D : public Node3D { GDCLASS(XROrigin3D, Node3D); @@ -204,4 +202,4 @@ public: ~XROrigin3D() {} }; -#endif /* XR_NODES_H */ +#endif // XR_NODES_H diff --git a/scene/animation/animation_blend_space_1d.cpp b/scene/animation/animation_blend_space_1d.cpp index 9a71e7bf55..33939d4cd6 100644 --- a/scene/animation/animation_blend_space_1d.cpp +++ b/scene/animation/animation_blend_space_1d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/animation/animation_blend_space_1d.h b/scene/animation/animation_blend_space_1d.h index 6730c09fd4..7038cece06 100644 --- a/scene/animation/animation_blend_space_1d.h +++ b/scene/animation/animation_blend_space_1d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/animation/animation_blend_space_2d.cpp b/scene/animation/animation_blend_space_2d.cpp index 8b5203961f..f169e79751 100644 --- a/scene/animation/animation_blend_space_2d.cpp +++ b/scene/animation/animation_blend_space_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/animation/animation_blend_space_2d.h b/scene/animation/animation_blend_space_2d.h index a919fff1d2..1356656bf8 100644 --- a/scene/animation/animation_blend_space_2d.h +++ b/scene/animation/animation_blend_space_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp index d6c5d0b51c..2740103a4a 100644 --- a/scene/animation/animation_blend_tree.cpp +++ b/scene/animation/animation_blend_tree.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -57,7 +57,7 @@ void AnimationNodeAnimation::_validate_property(PropertyInfo &property) const { } anims += String(names[i]); } - if (anims != String()) { + if (!anims.is_empty()) { property.hint = PROPERTY_HINT_ENUM; property.hint_string = anims; } diff --git a/scene/animation/animation_blend_tree.h b/scene/animation/animation_blend_tree.h index e55dfb58ed..2acacd7396 100644 --- a/scene/animation/animation_blend_tree.h +++ b/scene/animation/animation_blend_tree.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index c8fa8bf395..a23e1b689c 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -52,7 +52,7 @@ void AnimationNodeStateMachineTransition::set_advance_condition(const StringName String cs = p_condition; ERR_FAIL_COND(cs.find("/") != -1 || cs.find(":") != -1); advance_condition = p_condition; - if (cs != String()) { + if (!cs.is_empty()) { advance_condition_name = "conditions/" + cs; } else { advance_condition_name = StringName(); diff --git a/scene/animation/animation_node_state_machine.h b/scene/animation/animation_node_state_machine.h index 6f0e3107fd..b980556875 100644 --- a/scene/animation/animation_node_state_machine.h +++ b/scene/animation/animation_node_state_machine.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 93339711bd..128c6cae8b 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -625,7 +625,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double pa->object->set_indexed(pa->subpath, value, &valid); //you are not speshul #ifdef DEBUG_ENABLED if (!valid) { - ERR_PRINT("Failed setting track value '" + String(pa->owner->path) + "'. Check if property exists or the type of key is valid. Animation '" + a->get_name() + "' at node '" + get_path() + "'."); + ERR_PRINT("Failed setting track value '" + String(pa->owner->path) + "'. Check if the property exists or the type of key is valid. Animation '" + a->get_name() + "' at node '" + get_path() + "'."); } #endif @@ -736,7 +736,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double ba->bezier_accum = bezier; ba->accum_pass = accum_pass; } else { - ba->bezier_accum = Math::lerp(ba->bezier_accum, bezier, p_interp); + ba->bezier_accum = Math::lerp(ba->bezier_accum, (float)bezier, p_interp); } } break; @@ -1070,8 +1070,24 @@ void AnimationPlayer::_animation_update_transforms() { bool valid; pa->object->set_indexed(pa->subpath, pa->value_accum, &valid); //you are not speshul #ifdef DEBUG_ENABLED + if (!valid) { - ERR_PRINT("Failed setting key at time " + rtos(playback.current.pos) + " in Animation '" + get_current_animation() + "' at Node '" + get_path() + "', Track '" + String(pa->owner->path) + "'. Check if property exists or the type of key is right for the property"); + // Get subpath as string for printing the error + // Cannot use `String::join(Vector<String>)` because this is a vector of StringName + String key_debug; + if (pa->subpath.size() > 0) { + key_debug = pa->subpath[0]; + for (int subpath_index = 1; subpath_index < pa->subpath.size(); ++subpath_index) { + key_debug += "."; + key_debug += pa->subpath[subpath_index]; + } + } + ERR_PRINT("Failed setting key '" + key_debug + + "' at time " + rtos(playback.current.pos) + + " in Animation '" + get_current_animation() + + "' at Node '" + get_path() + + "', Track '" + String(pa->owner->path) + + "'. Check if the property exists or the type of key is right for the property."); } #endif @@ -1416,7 +1432,7 @@ bool AnimationPlayer::is_playing() const { } void AnimationPlayer::set_current_animation(const String &p_anim) { - if (p_anim == "[stop]" || p_anim == "") { + if (p_anim == "[stop]" || p_anim.is_empty()) { stop(); } else if (!is_playing() || playback.assigned != p_anim) { play(p_anim); @@ -1754,7 +1770,7 @@ Ref<AnimatedValuesBackup> AnimationPlayer::backup_animated_values(Node *p_root_o Ref<AnimatedValuesBackup> AnimationPlayer::apply_reset(bool p_user_initiated) { ERR_FAIL_COND_V(!can_apply_reset(), Ref<AnimatedValuesBackup>()); - Ref<Animation> reset_anim = animation_set["RESET"].animation; + Ref<Animation> reset_anim = animation_set[SceneStringNames::get_singleton()->RESET].animation; ERR_FAIL_COND_V(reset_anim.is_null(), Ref<AnimatedValuesBackup>()); Node *root_node = get_node_or_null(root); @@ -1762,8 +1778,8 @@ Ref<AnimatedValuesBackup> AnimationPlayer::apply_reset(bool p_user_initiated) { AnimationPlayer *aux_player = memnew(AnimationPlayer); EditorNode::get_singleton()->add_child(aux_player); - aux_player->add_animation("RESET", reset_anim); - aux_player->set_assigned_animation("RESET"); + aux_player->add_animation(SceneStringNames::get_singleton()->RESET, reset_anim); + aux_player->set_assigned_animation(SceneStringNames::get_singleton()->RESET); // Forcing the use of the original root because the scene where original player belongs may be not the active one Node *root = get_node(get_root()); Ref<AnimatedValuesBackup> old_values = aux_player->backup_animated_values(root); @@ -1785,7 +1801,7 @@ Ref<AnimatedValuesBackup> AnimationPlayer::apply_reset(bool p_user_initiated) { } bool AnimationPlayer::can_apply_reset() const { - return has_animation("RESET") && playback.assigned != StringName("RESET"); + return has_animation(SceneStringNames::get_singleton()->RESET) && playback.assigned != SceneStringNames::get_singleton()->RESET; } #endif diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h index 1b07c086c0..c4fc69f370 100644 --- a/scene/animation/animation_player.h +++ b/scene/animation/animation_player.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index 57c615a6ab..a551417778 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -138,7 +138,7 @@ real_t AnimationNode::_pre_process(const StringName &p_base_path, AnimationNode void AnimationNode::make_invalid(const String &p_reason) { ERR_FAIL_COND(!state); state->valid = false; - if (state->invalid_reasons != String()) { + if (!state->invalid_reasons.is_empty()) { state->invalid_reasons += "\n"; } state->invalid_reasons += String::utf8("• ") + p_reason; @@ -1239,8 +1239,7 @@ void AnimationTree::_process_graph(real_t p_delta) { continue; } - t->value = Math::lerp(t->value, value, blend); - + t->value = Math::lerp(t->value, value, (float)blend); #endif // _3D_DISABLED } break; case Animation::TYPE_VALUE: { diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h index 6fc051fa41..11c9bcd4ef 100644 --- a/scene/animation/animation_tree.h +++ b/scene/animation/animation_tree.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/animation/easing_equations.h b/scene/animation/easing_equations.h index c38d083b7f..6d246c7a93 100644 --- a/scene/animation/easing_equations.h +++ b/scene/animation/easing_equations.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/animation/root_motion_view.cpp b/scene/animation/root_motion_view.cpp index 770996820d..0d44687588 100644 --- a/scene/animation/root_motion_view.cpp +++ b/scene/animation/root_motion_view.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/animation/root_motion_view.h b/scene/animation/root_motion_view.h index d64c8bc675..e8b141c1fd 100644 --- a/scene/animation/root_motion_view.h +++ b/scene/animation/root_motion_view.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index da933ae02d..a37c6f5355 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -260,10 +260,8 @@ bool Tween::step(float p_delta) { } if (is_bound) { - Object *bound_instance = ObjectDB::get_instance(bound_node); - if (bound_instance) { - Node *bound_node = Object::cast_to<Node>(bound_instance); - // This can't by anything else than Node, so we can omit checking if casting succeeded. + Node *bound_node = get_bound_node(); + if (bound_node) { if (!bound_node->is_inside_tree()) { return true; } @@ -320,16 +318,23 @@ bool Tween::step(float p_delta) { return true; } -bool Tween::should_pause() { +bool Tween::can_process(bool p_tree_paused) const { if (is_bound && pause_mode == TWEEN_PAUSE_BOUND) { - Object *bound_instance = ObjectDB::get_instance(bound_node); - if (bound_instance) { - Node *bound_node = Object::cast_to<Node>(bound_instance); - return !bound_node->can_process(); + Node *bound_node = get_bound_node(); + if (bound_node) { + return bound_node->can_process(); } } - return pause_mode != TWEEN_PAUSE_PROCESS; + return !p_tree_paused || pause_mode == TWEEN_PAUSE_PROCESS; +} + +Node *Tween::get_bound_node() const { + if (is_bound) { + return Object::cast_to<Node>(ObjectDB::get_instance(bound_node)); + } else { + return nullptr; + } } real_t Tween::run_equation(TransitionType p_trans_type, EaseType p_ease_type, real_t p_time, real_t p_initial, real_t p_delta, real_t p_duration) { diff --git a/scene/animation/tween.h b/scene/animation/tween.h index 6a48d332b8..5b0745b2b3 100644 --- a/scene/animation/tween.h +++ b/scene/animation/tween.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -97,7 +97,7 @@ public: private: TweenProcessMode process_mode = TweenProcessMode::TWEEN_PROCESS_IDLE; - TweenPauseMode pause_mode = TweenPauseMode::TWEEN_PAUSE_STOP; + TweenPauseMode pause_mode = TweenPauseMode::TWEEN_PAUSE_BOUND; TransitionType default_transition = TransitionType::TRANS_LINEAR; EaseType default_ease = EaseType::EASE_IN_OUT; ObjectID bound_node; @@ -164,7 +164,8 @@ public: Variant calculate_delta_value(Variant p_intial_val, Variant p_final_val); bool step(float p_delta); - bool should_pause(); + bool can_process(bool p_tree_paused) const; + Node *get_bound_node() const; Tween() {} }; diff --git a/scene/audio/audio_stream_player.cpp b/scene/audio/audio_stream_player.cpp index 3da4f23a08..5f9d8a0d47 100644 --- a/scene/audio/audio_stream_player.cpp +++ b/scene/audio/audio_stream_player.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/audio/audio_stream_player.h b/scene/audio/audio_stream_player.h index 7205fce204..67e616312a 100644 --- a/scene/audio/audio_stream_player.h +++ b/scene/audio/audio_stream_player.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/debugger/scene_debugger.cpp b/scene/debugger/scene_debugger.cpp index 56c04b32e3..41340f281b 100644 --- a/scene/debugger/scene_debugger.cpp +++ b/scene/debugger/scene_debugger.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -226,7 +226,7 @@ void SceneDebugger::add_to_cache(const String &p_filename, Node *p_node) { return; } - if (EngineDebugger::get_script_debugger() && p_filename != String()) { + if (EngineDebugger::get_script_debugger() && !p_filename.is_empty()) { debugger->live_scene_edit_cache[p_filename].insert(p_node); } } diff --git a/scene/debugger/scene_debugger.h b/scene/debugger/scene_debugger.h index 9d54556187..432317a423 100644 --- a/scene/debugger/scene_debugger.h +++ b/scene/debugger/scene_debugger.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/aspect_ratio_container.cpp b/scene/gui/aspect_ratio_container.cpp index fb6fa9dec9..181d1bf33b 100644 --- a/scene/gui/aspect_ratio_container.cpp +++ b/scene/gui/aspect_ratio_container.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -60,12 +60,12 @@ void AspectRatioContainer::set_stretch_mode(StretchMode p_mode) { queue_sort(); } -void AspectRatioContainer::set_alignment_horizontal(AlignMode p_alignment_horizontal) { +void AspectRatioContainer::set_alignment_horizontal(AlignmentMode p_alignment_horizontal) { alignment_horizontal = p_alignment_horizontal; queue_sort(); } -void AspectRatioContainer::set_alignment_vertical(AlignMode p_alignment_vertical) { +void AspectRatioContainer::set_alignment_vertical(AlignmentMode p_alignment_vertical) { alignment_vertical = p_alignment_vertical; queue_sort(); } @@ -107,25 +107,25 @@ void AspectRatioContainer::_notification(int p_what) { float align_x = 0.5; switch (alignment_horizontal) { - case ALIGN_BEGIN: { + case ALIGNMENT_BEGIN: { align_x = 0.0; } break; - case ALIGN_CENTER: { + case ALIGNMENT_CENTER: { align_x = 0.5; } break; - case ALIGN_END: { + case ALIGNMENT_END: { align_x = 1.0; } break; } float align_y = 0.5; switch (alignment_vertical) { - case ALIGN_BEGIN: { + case ALIGNMENT_BEGIN: { align_y = 0.0; } break; - case ALIGN_CENTER: { + case ALIGNMENT_CENTER: { align_y = 0.5; } break; - case ALIGN_END: { + case ALIGNMENT_END: { align_y = 1.0; } break; } @@ -166,7 +166,7 @@ void AspectRatioContainer::_bind_methods() { BIND_ENUM_CONSTANT(STRETCH_FIT); BIND_ENUM_CONSTANT(STRETCH_COVER); - BIND_ENUM_CONSTANT(ALIGN_BEGIN); - BIND_ENUM_CONSTANT(ALIGN_CENTER); - BIND_ENUM_CONSTANT(ALIGN_END); + BIND_ENUM_CONSTANT(ALIGNMENT_BEGIN); + BIND_ENUM_CONSTANT(ALIGNMENT_CENTER); + BIND_ENUM_CONSTANT(ALIGNMENT_END); } diff --git a/scene/gui/aspect_ratio_container.h b/scene/gui/aspect_ratio_container.h index c95c6a7274..4a168bad14 100644 --- a/scene/gui/aspect_ratio_container.h +++ b/scene/gui/aspect_ratio_container.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -48,17 +48,17 @@ public: STRETCH_FIT, STRETCH_COVER, }; - enum AlignMode { - ALIGN_BEGIN, - ALIGN_CENTER, - ALIGN_END, + enum AlignmentMode { + ALIGNMENT_BEGIN, + ALIGNMENT_CENTER, + ALIGNMENT_END, }; private: float ratio = 1.0; StretchMode stretch_mode = STRETCH_FIT; - AlignMode alignment_horizontal = ALIGN_CENTER; - AlignMode alignment_vertical = ALIGN_CENTER; + AlignmentMode alignment_horizontal = ALIGNMENT_CENTER; + AlignmentMode alignment_vertical = ALIGNMENT_CENTER; public: void set_ratio(float p_ratio); @@ -67,14 +67,14 @@ public: void set_stretch_mode(StretchMode p_mode); StretchMode get_stretch_mode() const { return stretch_mode; } - void set_alignment_horizontal(AlignMode p_alignment_horizontal); - AlignMode get_alignment_horizontal() const { return alignment_horizontal; } + void set_alignment_horizontal(AlignmentMode p_alignment_horizontal); + AlignmentMode get_alignment_horizontal() const { return alignment_horizontal; } - void set_alignment_vertical(AlignMode p_alignment_vertical); - AlignMode get_alignment_vertical() const { return alignment_vertical; } + void set_alignment_vertical(AlignmentMode p_alignment_vertical); + AlignmentMode get_alignment_vertical() const { return alignment_vertical; } }; VARIANT_ENUM_CAST(AspectRatioContainer::StretchMode); -VARIANT_ENUM_CAST(AspectRatioContainer::AlignMode); +VARIANT_ENUM_CAST(AspectRatioContainer::AlignmentMode); #endif // ASPECT_RATIO_CONTAINER_H diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp index 9f712ed478..eee7663b09 100644 --- a/scene/gui/base_button.cpp +++ b/scene/gui/base_button.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -355,8 +355,8 @@ String BaseButton::get_tooltip(const Point2 &p_pos) const { String tooltip = Control::get_tooltip(p_pos); if (shortcut_in_tooltip && shortcut.is_valid() && shortcut->has_valid_event()) { String text = shortcut->get_name() + " (" + shortcut->get_as_text() + ")"; - if (tooltip != String() && shortcut->get_name().nocasecmp_to(tooltip) != 0) { - text += "\n" + tooltip; + if (!tooltip.is_empty() && shortcut->get_name().nocasecmp_to(tooltip) != 0) { + text += "\n" + atr(tooltip); } tooltip = text; } diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h index 3ea59c3ff9..0bcad4fc0e 100644 --- a/scene/gui/base_button.h +++ b/scene/gui/base_button.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/box_container.cpp b/scene/gui/box_container.cpp index cb9f13e970..9827bd0cef 100644 --- a/scene/gui/box_container.cpp +++ b/scene/gui/box_container.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -154,29 +154,29 @@ void BoxContainer::_resort() { int ofs = 0; if (!has_stretched) { if (!vertical) { - switch (align) { - case ALIGN_BEGIN: + switch (alignment) { + case ALIGNMENT_BEGIN: if (rtl) { ofs = stretch_diff; } break; - case ALIGN_CENTER: + case ALIGNMENT_CENTER: ofs = stretch_diff / 2; break; - case ALIGN_END: + case ALIGNMENT_END: if (!rtl) { ofs = stretch_diff; } break; } } else { - switch (align) { - case ALIGN_BEGIN: + switch (alignment) { + case ALIGNMENT_BEGIN: break; - case ALIGN_CENTER: + case ALIGNMENT_CENTER: ofs = stretch_diff / 2; break; - case ALIGN_END: + case ALIGNMENT_END: ofs = stretch_diff; break; } @@ -295,7 +295,7 @@ void BoxContainer::_notification(int p_what) { _resort(); } break; case NOTIFICATION_THEME_CHANGED: { - minimum_size_changed(); + update_minimum_size(); } break; case NOTIFICATION_TRANSLATION_CHANGED: case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: { @@ -304,13 +304,13 @@ void BoxContainer::_notification(int p_what) { } } -void BoxContainer::set_alignment(AlignMode p_align) { - align = p_align; +void BoxContainer::set_alignment(AlignmentMode p_alignment) { + alignment = p_alignment; _resort(); } -BoxContainer::AlignMode BoxContainer::get_alignment() const { - return align; +BoxContainer::AlignmentMode BoxContainer::get_alignment() const { + return alignment; } Control *BoxContainer::add_spacer(bool p_begin) { @@ -340,9 +340,9 @@ void BoxContainer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_alignment"), &BoxContainer::get_alignment); ClassDB::bind_method(D_METHOD("set_alignment", "alignment"), &BoxContainer::set_alignment); - BIND_ENUM_CONSTANT(ALIGN_BEGIN); - BIND_ENUM_CONSTANT(ALIGN_CENTER); - BIND_ENUM_CONSTANT(ALIGN_END); + 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"); } @@ -351,11 +351,11 @@ MarginContainer *VBoxContainer::add_margin_child(const String &p_label, Control Label *l = memnew(Label); l->set_theme_type_variation("HeaderSmall"); l->set_text(p_label); - add_child(l, false, INTERNAL_MODE_FRONT); + add_child(l); MarginContainer *mc = memnew(MarginContainer); mc->add_theme_constant_override("margin_left", 0); mc->add_child(p_control, true); - add_child(mc, false, INTERNAL_MODE_FRONT); + add_child(mc); if (p_expand) { mc->set_v_size_flags(SIZE_EXPAND_FILL); } diff --git a/scene/gui/box_container.h b/scene/gui/box_container.h index 23feea565c..68d55e1aaf 100644 --- a/scene/gui/box_container.h +++ b/scene/gui/box_container.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -37,15 +37,15 @@ class BoxContainer : public Container { GDCLASS(BoxContainer, Container); public: - enum AlignMode { - ALIGN_BEGIN, - ALIGN_CENTER, - ALIGN_END + enum AlignmentMode { + ALIGNMENT_BEGIN, + ALIGNMENT_CENTER, + ALIGNMENT_END }; private: bool vertical = false; - AlignMode align = ALIGN_BEGIN; + AlignmentMode alignment = ALIGNMENT_BEGIN; void _resort(); @@ -57,8 +57,8 @@ protected: public: Control *add_spacer(bool p_begin = false); - void set_alignment(AlignMode p_align); - AlignMode get_alignment() const; + void set_alignment(AlignmentMode p_alignment); + AlignmentMode get_alignment() const; virtual Size2 get_minimum_size() const override; @@ -84,6 +84,6 @@ public: BoxContainer(true) {} }; -VARIANT_ENUM_CAST(BoxContainer::AlignMode); +VARIANT_ENUM_CAST(BoxContainer::AlignmentMode); #endif // BOX_CONTAINER_H diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index 9818c8f0cc..046b9c18c7 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -50,9 +50,9 @@ Size2 Button::get_minimum_size() const { if (!_icon.is_null()) { minsize.height = MAX(minsize.height, _icon->get_height()); - if (icon_align != ALIGN_CENTER) { + if (icon_alignment != HORIZONTAL_ALIGNMENT_CENTER) { minsize.width += _icon->get_width(); - if (xl_text != "") { + if (!xl_text.is_empty()) { minsize.width += get_theme_constant(SNAME("hseparation")); } } else { @@ -82,13 +82,13 @@ void Button::_notification(int p_what) { xl_text = atr(text); _shape(); - minimum_size_changed(); + update_minimum_size(); update(); } break; case NOTIFICATION_THEME_CHANGED: { _shape(); - minimum_size_changed(); + update_minimum_size(); update(); } break; case NOTIFICATION_DRAW: { @@ -126,7 +126,8 @@ void Button::_notification(int p_what) { } } break; case DRAW_HOVER_PRESSED: { - if (has_theme_stylebox(SNAME("hover_pressed")) && has_theme_stylebox_override("hover_pressed")) { + // 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")); } else { @@ -138,8 +139,6 @@ void Button::_notification(int p_what) { } if (has_theme_color(SNAME("font_hover_pressed_color"))) { color = get_theme_color(SNAME("font_hover_pressed_color")); - } else { - color = get_theme_color(SNAME("font_color")); } if (has_theme_color(SNAME("icon_hover_pressed_color"))) { color_icon = get_theme_color(SNAME("icon_hover_pressed_color")); @@ -216,19 +215,19 @@ void Button::_notification(int p_what) { } Rect2 icon_region = Rect2(); - TextAlign icon_align_rtl_checked = icon_align; - TextAlign align_rtl_checked = align; + HorizontalAlignment icon_align_rtl_checked = icon_alignment; + HorizontalAlignment align_rtl_checked = alignment; // Swap icon and text alignment sides if right-to-left layout is set. if (rtl) { - if (icon_align == ALIGN_RIGHT) { - icon_align_rtl_checked = ALIGN_LEFT; - } else if (icon_align == ALIGN_LEFT) { - icon_align_rtl_checked = ALIGN_RIGHT; + if (icon_alignment == HORIZONTAL_ALIGNMENT_RIGHT) { + icon_align_rtl_checked = HORIZONTAL_ALIGNMENT_LEFT; + } else if (icon_alignment == HORIZONTAL_ALIGNMENT_LEFT) { + icon_align_rtl_checked = HORIZONTAL_ALIGNMENT_RIGHT; } - if (align == ALIGN_RIGHT) { - align_rtl_checked = ALIGN_LEFT; - } else if (align == ALIGN_LEFT) { - align_rtl_checked = ALIGN_RIGHT; + if (alignment == HORIZONTAL_ALIGNMENT_RIGHT) { + align_rtl_checked = HORIZONTAL_ALIGNMENT_LEFT; + } else if (alignment == HORIZONTAL_ALIGNMENT_LEFT) { + align_rtl_checked = HORIZONTAL_ALIGNMENT_RIGHT; } } if (!_icon.is_null()) { @@ -240,14 +239,14 @@ void Button::_notification(int p_what) { float icon_ofs_region = 0.0; Point2 style_offset; Size2 icon_size = _icon->get_size(); - if (icon_align_rtl_checked == ALIGN_LEFT) { + 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("hseparation")); } - } else if (icon_align_rtl_checked == ALIGN_CENTER) { + } else if (icon_align_rtl_checked == HORIZONTAL_ALIGNMENT_CENTER) { style_offset.x = 0.0; - } else if (icon_align_rtl_checked == ALIGN_RIGHT) { + } 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("hseparation")); @@ -258,7 +257,7 @@ void Button::_notification(int p_what) { if (expand_icon) { Size2 _size = get_size() - style->get_offset() * 2; _size.width -= get_theme_constant(SNAME("hseparation")) + icon_ofs_region; - if (!clip_text && icon_align_rtl_checked != ALIGN_CENTER) { + if (!clip_text && icon_align_rtl_checked != HORIZONTAL_ALIGNMENT_CENTER) { _size.width -= text_buf->get_size().width; } float icon_width = _icon->get_width() * _size.height / _icon->get_height(); @@ -272,9 +271,9 @@ void Button::_notification(int p_what) { icon_size = Size2(icon_width, icon_height); } - if (icon_align_rtl_checked == ALIGN_LEFT) { + if (icon_align_rtl_checked == HORIZONTAL_ALIGNMENT_LEFT) { icon_region = Rect2(style_offset + Point2(icon_ofs_region, Math::floor((valign - icon_size.y) * 0.5)), icon_size); - } else if (icon_align_rtl_checked == ALIGN_CENTER) { + } else if (icon_align_rtl_checked == HORIZONTAL_ALIGNMENT_CENTER) { icon_region = Rect2(style_offset + Point2(icon_ofs_region + Math::floor((size.x - icon_size.x) * 0.5), Math::floor((valign - icon_size.y) * 0.5)), icon_size); } else { icon_region = Rect2(style_offset + Point2(icon_ofs_region + size.x - icon_size.x, Math::floor((valign - icon_size.y) * 0.5)), icon_size); @@ -286,7 +285,7 @@ void Button::_notification(int p_what) { } Point2 icon_ofs = !_icon.is_null() ? Point2(icon_region.size.width + get_theme_constant(SNAME("hseparation")), 0) : Point2(); - if (align_rtl_checked == ALIGN_CENTER && icon_align_rtl_checked == ALIGN_CENTER) { + if (align_rtl_checked == HORIZONTAL_ALIGNMENT_CENTER && icon_align_rtl_checked == HORIZONTAL_ALIGNMENT_CENTER) { icon_ofs.x = 0.0; } int text_clip = size.width - style->get_minimum_size().width - icon_ofs.width; @@ -303,9 +302,12 @@ void Button::_notification(int p_what) { 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; + text_buf->set_alignment(align_rtl_checked); + text_buf->set_width(text_width); switch (align_rtl_checked) { - case ALIGN_LEFT: { - if (icon_align_rtl_checked != ALIGN_LEFT) { + case HORIZONTAL_ALIGNMENT_FILL: + case HORIZONTAL_ALIGNMENT_LEFT: { + if (icon_align_rtl_checked != HORIZONTAL_ALIGNMENT_LEFT) { icon_ofs.x = 0.0; } if (_internal_margin[SIDE_LEFT] > 0) { @@ -315,23 +317,23 @@ void Button::_notification(int p_what) { } text_ofs.y += style->get_offset().y; } break; - case ALIGN_CENTER: { + case HORIZONTAL_ALIGNMENT_CENTER: { if (text_ofs.x < 0) { text_ofs.x = 0; } - if (icon_align_rtl_checked == ALIGN_LEFT) { + if (icon_align_rtl_checked == HORIZONTAL_ALIGNMENT_LEFT) { text_ofs += icon_ofs; } text_ofs += style->get_offset(); } break; - case ALIGN_RIGHT: { + 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("hseparation")); } else { text_ofs.x = size.x - style->get_margin(SIDE_RIGHT) - text_width; } text_ofs.y += style->get_offset().y; - if (icon_align_rtl_checked == ALIGN_RIGHT) { + if (icon_align_rtl_checked == HORIZONTAL_ALIGNMENT_RIGHT) { text_ofs.x -= icon_ofs.x; } } break; @@ -358,7 +360,7 @@ void Button::_shape() { } else { text_buf->set_direction((TextServer::Direction)text_direction); } - text_buf->add_string(xl_text, font, font_size, opentype_features, (language != "") ? language : TranslationServer::get_singleton()->get_tool_locale()); + text_buf->add_string(xl_text, font, font_size, opentype_features, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale()); } void Button::set_text(const String &p_text) { @@ -368,7 +370,7 @@ void Button::set_text(const String &p_text) { _shape(); update(); - minimum_size_changed(); + update_minimum_size(); } } @@ -428,7 +430,7 @@ void Button::set_icon(const Ref<Texture2D> &p_icon) { if (icon != p_icon) { icon = p_icon; update(); - minimum_size_changed(); + update_minimum_size(); } } @@ -440,7 +442,7 @@ void Button::set_expand_icon(bool p_enabled) { if (expand_icon != p_enabled) { expand_icon = p_enabled; update(); - minimum_size_changed(); + update_minimum_size(); } } @@ -463,7 +465,7 @@ void Button::set_clip_text(bool p_enabled) { if (clip_text != p_enabled) { clip_text = p_enabled; update(); - minimum_size_changed(); + update_minimum_size(); } } @@ -471,25 +473,25 @@ bool Button::get_clip_text() const { return clip_text; } -void Button::set_text_align(TextAlign p_align) { - if (align != p_align) { - align = p_align; +void Button::set_text_alignment(HorizontalAlignment p_alignment) { + if (alignment != p_alignment) { + alignment = p_alignment; update(); } } -Button::TextAlign Button::get_text_align() const { - return align; +HorizontalAlignment Button::get_text_alignment() const { + return alignment; } -void Button::set_icon_align(TextAlign p_align) { - icon_align = p_align; - minimum_size_changed(); +void Button::set_icon_alignment(HorizontalAlignment p_alignment) { + icon_alignment = p_alignment; + update_minimum_size(); update(); } -Button::TextAlign Button::get_icon_align() const { - return icon_align; +HorizontalAlignment Button::get_icon_alignment() const { + return icon_alignment; } bool Button::_set(const StringName &p_name, const Variant &p_value) { @@ -497,7 +499,7 @@ bool Button::_set(const StringName &p_name, const Variant &p_value) { if (str.begins_with("opentype_features/")) { String name = str.get_slicec('/', 1); int32_t tag = TS->name_to_tag(name); - double value = p_value; + int value = p_value; if (value == -1) { if (opentype_features.has(tag)) { opentype_features.erase(tag); @@ -505,7 +507,7 @@ bool Button::_set(const StringName &p_name, const Variant &p_value) { update(); } } else { - if ((double)opentype_features[tag] != value) { + if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) { opentype_features[tag] = value; _shape(); update(); @@ -537,7 +539,7 @@ bool Button::_get(const StringName &p_name, Variant &r_ret) const { void Button::_get_property_list(List<PropertyInfo> *p_list) const { for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) { String name = TS->tag_to_name(*ftr); - p_list->push_back(PropertyInfo(Variant::FLOAT, "opentype_features/" + name)); + p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name)); } p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR)); } @@ -558,25 +560,21 @@ void Button::_bind_methods() { ClassDB::bind_method(D_METHOD("is_flat"), &Button::is_flat); ClassDB::bind_method(D_METHOD("set_clip_text", "enabled"), &Button::set_clip_text); ClassDB::bind_method(D_METHOD("get_clip_text"), &Button::get_clip_text); - ClassDB::bind_method(D_METHOD("set_text_align", "align"), &Button::set_text_align); - ClassDB::bind_method(D_METHOD("get_text_align"), &Button::get_text_align); - ClassDB::bind_method(D_METHOD("set_icon_align", "icon_align"), &Button::set_icon_align); - ClassDB::bind_method(D_METHOD("get_icon_align"), &Button::get_icon_align); + ClassDB::bind_method(D_METHOD("set_text_alignment", "alignment"), &Button::set_text_alignment); + ClassDB::bind_method(D_METHOD("get_text_alignment"), &Button::get_text_alignment); + ClassDB::bind_method(D_METHOD("set_icon_alignment", "icon_alignment"), &Button::set_icon_alignment); + ClassDB::bind_method(D_METHOD("get_icon_alignment"), &Button::get_icon_alignment); ClassDB::bind_method(D_METHOD("set_expand_icon", "enabled"), &Button::set_expand_icon); ClassDB::bind_method(D_METHOD("is_expand_icon"), &Button::is_expand_icon); - BIND_ENUM_CONSTANT(ALIGN_LEFT); - BIND_ENUM_CONSTANT(ALIGN_CENTER); - BIND_ENUM_CONSTANT(ALIGN_RIGHT); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text"); ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "language"), "set_language", "get_language"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_button_icon", "get_button_icon"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flat"), "set_flat", "is_flat"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_text"), "set_clip_text", "get_clip_text"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_text_align", "get_text_align"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "icon_align", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_icon_align", "get_icon_align"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "alignment", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_text_alignment", "get_text_alignment"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "icon_alignment", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_icon_alignment", "get_icon_alignment"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "expand_icon"), "set_expand_icon", "is_expand_icon"); } diff --git a/scene/gui/button.h b/scene/gui/button.h index fd36cb77af..1abf86c986 100644 --- a/scene/gui/button.h +++ b/scene/gui/button.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -37,13 +37,6 @@ class Button : public BaseButton { GDCLASS(Button, BaseButton); -public: - enum TextAlign { - ALIGN_LEFT, - ALIGN_CENTER, - ALIGN_RIGHT - }; - private: bool flat = false; String text; @@ -57,8 +50,8 @@ private: Ref<Texture2D> icon; bool expand_icon = false; bool clip_text = false; - TextAlign align = ALIGN_CENTER; - TextAlign icon_align = ALIGN_LEFT; + HorizontalAlignment alignment = HORIZONTAL_ALIGNMENT_CENTER; + HorizontalAlignment icon_alignment = HORIZONTAL_ALIGNMENT_LEFT; float _internal_margin[4] = {}; void _shape(); @@ -100,16 +93,14 @@ public: void set_clip_text(bool p_enabled); bool get_clip_text() const; - void set_text_align(TextAlign p_align); - TextAlign get_text_align() const; + void set_text_alignment(HorizontalAlignment p_alignment); + HorizontalAlignment get_text_alignment() const; - void set_icon_align(TextAlign p_align); - TextAlign get_icon_align() const; + void set_icon_alignment(HorizontalAlignment p_alignment); + HorizontalAlignment get_icon_alignment() const; Button(const String &p_text = String()); ~Button(); }; -VARIANT_ENUM_CAST(Button::TextAlign); - #endif diff --git a/scene/gui/center_container.cpp b/scene/gui/center_container.cpp index 909516e7ef..f3306783f3 100644 --- a/scene/gui/center_container.cpp +++ b/scene/gui/center_container.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -61,7 +61,7 @@ void CenterContainer::set_use_top_left(bool p_enable) { use_top_left = p_enable; - minimum_size_changed(); + update_minimum_size(); queue_sort(); } diff --git a/scene/gui/center_container.h b/scene/gui/center_container.h index 0944f200fc..16a10c8070 100644 --- a/scene/gui/center_container.h +++ b/scene/gui/center_container.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/check_box.cpp b/scene/gui/check_box.cpp index 411fb2e1f0..da2d4369d1 100644 --- a/scene/gui/check_box.cpp +++ b/scene/gui/check_box.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -123,7 +123,7 @@ CheckBox::CheckBox(const String &p_text) : Button(p_text) { set_toggle_mode(true); - set_text_align(ALIGN_LEFT); + set_text_alignment(HORIZONTAL_ALIGNMENT_LEFT); if (is_layout_rtl()) { _set_internal_margin(SIDE_RIGHT, get_icon_size().width); diff --git a/scene/gui/check_box.h b/scene/gui/check_box.h index 9fb0aea218..fcdb2ce08c 100644 --- a/scene/gui/check_box.h +++ b/scene/gui/check_box.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -32,9 +32,7 @@ #define CHECK_BOX_H #include "scene/gui/button.h" -/** -@author Mariano Suligoy <marianognu.esyrpg@gmail.com> -*/ + class CheckBox : public Button { GDCLASS(CheckBox, Button); @@ -50,4 +48,4 @@ public: ~CheckBox(); }; -#endif +#endif // CHECK_BOX_H diff --git a/scene/gui/check_button.cpp b/scene/gui/check_button.cpp index 162a256d23..afb23a540b 100644 --- a/scene/gui/check_button.cpp +++ b/scene/gui/check_button.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -107,7 +107,7 @@ void CheckButton::_notification(int p_what) { CheckButton::CheckButton() { set_toggle_mode(true); - set_text_align(ALIGN_LEFT); + set_text_alignment(HORIZONTAL_ALIGNMENT_LEFT); if (is_layout_rtl()) { _set_internal_margin(SIDE_LEFT, get_icon_size().width); } else { diff --git a/scene/gui/check_button.h b/scene/gui/check_button.h index 29c557ce89..9a72d04db2 100644 --- a/scene/gui/check_button.h +++ b/scene/gui/check_button.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -32,9 +32,7 @@ #define CHECK_BUTTON_H #include "scene/gui/button.h" -/** -@author Juan Linietsky <reduzio@gmail.com> -*/ + class CheckButton : public Button { GDCLASS(CheckButton, Button); @@ -48,4 +46,4 @@ public: ~CheckButton(); }; -#endif +#endif // CHECK_BUTTON_H diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp index a8c5966569..040075150b 100644 --- a/scene/gui/code_edit.cpp +++ b/scene/gui/code_edit.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -92,7 +92,7 @@ void CodeEdit::_notification(int p_what) { if (line_length_guideline_columns.size() > 0) { const int xmargin_beg = style_normal->get_margin(SIDE_LEFT) + get_total_gutter_width(); const int xmargin_end = size.width - style_normal->get_margin(SIDE_RIGHT) - (is_drawing_minimap() ? get_minimap_width() : 0); - const int char_size = (int)font->get_char_size('0', 0, font_size).width; + const int char_size = Math::round(font->get_char_size('0', 0, font_size).width); for (int i = 0; i < line_length_guideline_columns.size(); i++) { const int xoffset = xmargin_beg + char_size * (int)line_length_guideline_columns[i] - get_h_scroll(); @@ -143,7 +143,6 @@ void CodeEdit::_notification(int p_what) { code_completion_line_ofs = CLAMP(code_completion_current_selected - lines / 2, 0, code_completion_options_count - lines); RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(code_completion_rect.position.x, code_completion_rect.position.y + (code_completion_current_selected - code_completion_line_ofs) * row_height), Size2(code_completion_rect.size.width, row_height)), code_completion_selected_color); - draw_rect(Rect2(code_completion_rect.position + Vector2(icon_area_size.x + icon_hsep, 0), Size2(MIN(code_completion_base_width, code_completion_rect.size.width - (icon_area_size.x + icon_hsep)), code_completion_rect.size.height)), code_completion_existing_color); for (int i = 0; i < lines; i++) { int l = code_completion_line_ofs + i; @@ -170,13 +169,24 @@ void CodeEdit::_notification(int p_what) { if (code_completion_options[l].default_value.get_type() == Variant::COLOR) { draw_rect(Rect2(Point2(code_completion_rect.position.x, icon_area.position.y), icon_area_size), (Color)code_completion_options[l].default_value); } - tl->set_align(HALIGN_RIGHT); + tl->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT); } else { if (code_completion_options[l].default_value.get_type() == Variant::COLOR) { draw_rect(Rect2(Point2(code_completion_rect.position.x + code_completion_rect.size.width - icon_area_size.x, icon_area.position.y), icon_area_size), (Color)code_completion_options[l].default_value); } - tl->set_align(HALIGN_LEFT); + tl->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_LEFT); } + + Point2 match_pos = Point2(code_completion_rect.position.x + icon_area_size.x + icon_hsep, code_completion_rect.position.y + i * row_height); + + for (int j = 0; j < code_completion_options[l].matches.size(); j++) { + Pair<int, int> match = code_completion_options[l].matches[j]; + int match_offset = font->get_string_size(code_completion_options[l].display.substr(0, match.first), font_size).width; + int match_len = font->get_string_size(code_completion_options[l].display.substr(match.first, match.second), font_size).width; + + draw_rect(Rect2(match_pos + Point2(match_offset, 0), Size2(match_len, row_height)), code_completion_existing_color); + } + tl->draw(ci, title_pos, code_completion_options[l].font_color); } @@ -189,7 +199,7 @@ void CodeEdit::_notification(int p_what) { } /* Code hint */ - if (caret_visible && code_hint != "" && (!code_completion_active || (code_completion_below != code_hint_draw_below))) { + if (caret_visible && !code_hint.is_empty() && (!code_completion_active || (code_completion_below != code_hint_draw_below))) { const int font_height = font->get_height(font_size); Ref<StyleBox> sb = get_theme_stylebox(SNAME("panel"), SNAME("TooltipPanel")); Color font_color = get_theme_color(SNAME("font_color"), SNAME("TooltipLabel")); @@ -229,7 +239,7 @@ void CodeEdit::_notification(int p_what) { Point2 round_ofs = hint_ofs + sb->get_offset() + Vector2(0, font->get_ascent(font_size) + font_height * i + yofs); round_ofs = round_ofs.round(); - draw_string(font, round_ofs, line.replace(String::chr(0xFFFF), ""), HALIGN_LEFT, -1, font_size, font_color); + draw_string(font, round_ofs, line.replace(String::chr(0xFFFF), ""), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color); if (end > 0) { // Draw an underline for the currently edited function parameter. const Vector2 b = hint_ofs + sb->get_offset() + Vector2(begin, font_height + font_height * i + yofs); @@ -315,7 +325,7 @@ void CodeEdit::gui_input(const Ref<InputEvent> &p_gui_input) { } } else { if (mb->get_button_index() == MouseButton::LEFT) { - if (mb->is_command_pressed() && symbol_lookup_word != String()) { + if (mb->is_command_pressed() && !symbol_lookup_word.is_empty()) { Vector2i mpos = mb->get_position(); if (is_layout_rtl()) { mpos.x = get_size().x - mpos.x; @@ -530,7 +540,7 @@ void CodeEdit::gui_input(const Ref<InputEvent> &p_gui_input) { /* General overrides */ Control::CursorShape CodeEdit::get_cursor_shape(const Point2 &p_pos) const { - if (symbol_lookup_word != String()) { + if (!symbol_lookup_word.is_empty()) { return CURSOR_POINTING_HAND; } @@ -2597,7 +2607,7 @@ void CodeEdit::_add_delimiter(const String &p_start_key, const String &p_end_key delimiter.type = p_type; delimiter.start_key = p_start_key; delimiter.end_key = p_end_key; - delimiter.line_only = p_line_only || p_end_key == ""; + delimiter.line_only = p_line_only || p_end_key.is_empty(); delimiters.insert(at, delimiter); if (!setting_delimiters) { delimiter_cache.clear(); @@ -2647,7 +2657,7 @@ void CodeEdit::_set_delimiters(const TypedArray<String> &p_delimiters, Delimiter const String start_key = key.get_slice(" ", 0); const String end_key = key.get_slice_count(" ") > 1 ? key.get_slice(" ", 1) : String(); - _add_delimiter(start_key, end_key, end_key == "", p_type); + _add_delimiter(start_key, end_key, end_key.is_empty(), p_type); } setting_delimiters = false; _update_delimiter_cache(); @@ -2808,6 +2818,8 @@ void CodeEdit::_filter_code_completion_candidates_impl() { code_completion_base = string_to_complete; Vector<ScriptCodeCompletionOption> completion_options_casei; + Vector<ScriptCodeCompletionOption> completion_options_substr; + Vector<ScriptCodeCompletionOption> completion_options_substr_casei; Vector<ScriptCodeCompletionOption> completion_options_subseq; Vector<ScriptCodeCompletionOption> completion_options_subseq_casei; @@ -2862,35 +2874,100 @@ void CodeEdit::_filter_code_completion_candidates_impl() { const char32_t *tgt = &option.display[0]; const char32_t *tgt_lower = &display_lower[0]; - const char32_t *ssq_last_tgt = nullptr; - const char32_t *ssq_lower_last_tgt = nullptr; + const char32_t *sst = &string_to_complete[0]; + const char32_t *sst_lower = &display_lower[0]; + + Vector<Pair<int, int>> ssq_matches; + int ssq_match_start = 0; + int ssq_match_len = 0; + + Vector<Pair<int, int>> ssq_lower_matches; + int ssq_lower_match_start = 0; + int ssq_lower_match_len = 0; + + int sst_start = -1; + int sst_lower_start = -1; + + for (int i = 0; *tgt; tgt++, tgt_lower++, i++) { + // Check substring. + if (*sst == *tgt) { + sst++; + if (sst_start == -1) { + sst_start = i; + } + } else if (sst_start != -1 && *sst) { + sst = &string_to_complete[0]; + sst_start = -1; + } - for (; *tgt; tgt++, tgt_lower++) { + // Check subsequence. if (*ssq == *tgt) { ssq++; - ssq_last_tgt = tgt; + if (ssq_match_len == 0) { + ssq_match_start = i; + } + ssq_match_len++; + } else if (ssq_match_len > 0) { + ssq_matches.push_back(Pair<int, int>(ssq_match_start, ssq_match_len)); + ssq_match_len = 0; } + + // Check lower substring. + if (*sst_lower == *tgt) { + sst_lower++; + if (sst_lower_start == -1) { + sst_lower_start = i; + } + } else if (sst_lower_start != -1 && *sst_lower) { + sst_lower = &string_to_complete[0]; + sst_lower_start = -1; + } + + // Check lower subsequence. if (*ssq_lower == *tgt_lower) { ssq_lower++; - ssq_lower_last_tgt = tgt; + if (ssq_lower_match_len == 0) { + ssq_lower_match_start = i; + } + ssq_lower_match_len++; + } else if (ssq_lower_match_len > 0) { + ssq_lower_matches.push_back(Pair<int, int>(ssq_lower_match_start, ssq_lower_match_len)); + ssq_lower_match_len = 0; } } /* Matched the whole subsequence in s. */ - if (!*ssq) { - /* Finished matching in the first s.length() characters. */ - if (ssq_last_tgt == &option.display[string_to_complete.length() - 1]) { + if (!*ssq) { // Matched the whole subsequence in s. + option.matches.clear(); + + if (sst_start == 0) { // Matched substring in beginning of s. + option.matches.push_back(Pair<int, int>(sst_start, string_to_complete.length())); code_completion_options.push_back(option); + } else if (sst_start > 0) { // Matched substring in s. + option.matches.push_back(Pair<int, int>(sst_start, string_to_complete.length())); + completion_options_substr.push_back(option); } else { + if (ssq_match_len > 0) { + ssq_matches.push_back(Pair<int, int>(ssq_match_start, ssq_match_len)); + } + option.matches.append_array(ssq_matches); completion_options_subseq.push_back(option); } max_width = MAX(max_width, font->get_string_size(option.display, font_size).width + offset); - /* Matched the whole subsequence in s_lower. */ - } else if (!*ssq_lower) { - /* Finished matching in the first s.length() characters. */ - if (ssq_lower_last_tgt == &option.display[string_to_complete.length() - 1]) { + } else if (!*ssq_lower) { // Matched the whole subsequence in s_lower. + option.matches.clear(); + + if (sst_lower_start == 0) { // Matched substring in beginning of s_lower. + option.matches.push_back(Pair<int, int>(sst_lower_start, string_to_complete.length())); completion_options_casei.push_back(option); + } else if (sst_lower_start > 0) { // Matched substring in s_lower. + option.matches.push_back(Pair<int, int>(sst_lower_start, string_to_complete.length())); + completion_options_substr_casei.push_back(option); } else { + if (ssq_lower_match_len > 0) { + ssq_lower_matches.push_back(Pair<int, int>(ssq_lower_match_start, ssq_lower_match_len)); + } + option.matches.append_array(ssq_lower_matches); completion_options_subseq_casei.push_back(option); } max_width = MAX(max_width, font->get_string_size(option.display, font_size).width + offset); @@ -2990,7 +3067,7 @@ CodeEdit::CodeEdit() { add_auto_brace_completion_pair("\"", "\""); add_auto_brace_completion_pair("\'", "\'"); - /* Delimiter traking */ + /* Delimiter tracking */ add_string_delimiter("\"", "\"", false); add_string_delimiter("\'", "\'", false); diff --git a/scene/gui/code_edit.h b/scene/gui/code_edit.h index f0d971dd35..cb1309ced3 100644 --- a/scene/gui/code_edit.h +++ b/scene/gui/code_edit.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 5a378554c9..36ea843d1e 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -1274,7 +1274,7 @@ ColorPicker::ColorPicker() : preset_container->set_columns(preset_column_count); add_child(preset_container, false, INTERNAL_MODE_FRONT); - btn_add_preset->set_icon_align(Button::ALIGN_CENTER); + btn_add_preset->set_icon_alignment(HORIZONTAL_ALIGNMENT_CENTER); btn_add_preset->set_tooltip(RTR("Add current color as a preset.")); btn_add_preset->connect("pressed", callable_mp(this, &ColorPicker::_add_preset_pressed)); preset_container->add_child(btn_add_preset); diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h index ad4f5ad5b1..d6067b1cf4 100644 --- a/scene/gui/color_picker.h +++ b/scene/gui/color_picker.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/color_rect.cpp b/scene/gui/color_rect.cpp index e35d37d520..dbac1fc78a 100644 --- a/scene/gui/color_rect.cpp +++ b/scene/gui/color_rect.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/color_rect.h b/scene/gui/color_rect.h index 5c650f9f01..35c8ebcaf8 100644 --- a/scene/gui/color_rect.h +++ b/scene/gui/color_rect.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/container.cpp b/scene/gui/container.cpp index a1bd82f6f7..7b213ec314 100644 --- a/scene/gui/container.cpp +++ b/scene/gui/container.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -35,7 +35,7 @@ void Container::_child_minsize_changed() { //Size2 ms = get_combined_minimum_size(); //if (ms.width > get_size().width || ms.height > get_size().height) { - minimum_size_changed(); + update_minimum_size(); queue_sort(); } @@ -51,7 +51,7 @@ void Container::add_child_notify(Node *p_child) { control->connect(SNAME("minimum_size_changed"), callable_mp(this, &Container::_child_minsize_changed)); control->connect(SNAME("visibility_changed"), callable_mp(this, &Container::_child_minsize_changed)); - minimum_size_changed(); + update_minimum_size(); queue_sort(); } @@ -62,7 +62,7 @@ void Container::move_child_notify(Node *p_child) { return; } - minimum_size_changed(); + update_minimum_size(); queue_sort(); } @@ -78,7 +78,7 @@ void Container::remove_child_notify(Node *p_child) { control->disconnect("minimum_size_changed", callable_mp(this, &Container::_child_minsize_changed)); control->disconnect("visibility_changed", callable_mp(this, &Container::_child_minsize_changed)); - minimum_size_changed(); + update_minimum_size(); queue_sort(); } diff --git a/scene/gui/container.h b/scene/gui/container.h index f3ae948556..0e986f46ef 100644 --- a/scene/gui/container.h +++ b/scene/gui/container.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 9f715be155..69e6d74292 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -192,7 +192,7 @@ void Control::set_custom_minimum_size(const Size2 &p_custom) { return; } data.custom_minimum_size = p_custom; - minimum_size_changed(); + update_minimum_size(); } Size2 Control::get_custom_minimum_size() const { @@ -213,7 +213,7 @@ void Control::_update_minimum_size_cache() { data.minimum_size_valid = true; if (size_changed) { - minimum_size_changed(); + update_minimum_size(); } } @@ -589,6 +589,7 @@ void Control::_notification(int p_notification) { _size_changed(); } break; case NOTIFICATION_EXIT_TREE: { + release_focus(); get_viewport()->_gui_remove_control(this); } break; case NOTIFICATION_READY: { @@ -713,7 +714,7 @@ void Control::_notification(int p_notification) { update(); } break; case NOTIFICATION_THEME_CHANGED: { - minimum_size_changed(); + update_minimum_size(); update(); } break; case NOTIFICATION_VISIBILITY_CHANGED: { @@ -1148,12 +1149,12 @@ float Control::fetch_theme_default_base_scale(Control *p_theme_owner, Window *p_ Window *theme_owner_window = p_theme_owner_window; while (theme_owner || theme_owner_window) { - if (theme_owner && theme_owner->data.theme->has_default_theme_base_scale()) { - return theme_owner->data.theme->get_default_theme_base_scale(); + 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_theme_base_scale()) { - return theme_owner_window->theme->get_default_theme_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(); @@ -1175,13 +1176,16 @@ float Control::fetch_theme_default_base_scale(Control *p_theme_owner, Window *p_ // Secondly, check the project-defined Theme resource. if (Theme::get_project_default().is_valid()) { - if (Theme::get_project_default()->has_default_theme_base_scale()) { - return Theme::get_project_default()->get_default_theme_base_scale(); + if (Theme::get_project_default()->has_default_base_scale()) { + return Theme::get_project_default()->get_default_base_scale(); } } // Lastly, fall back on the default Theme. - return Theme::get_default()->get_default_theme_base_scale(); + if (Theme::get_default()->has_default_base_scale()) { + return Theme::get_default()->get_default_base_scale(); + } + return Theme::get_fallback_base_scale(); } float Control::get_theme_default_base_scale() const { @@ -1196,12 +1200,12 @@ Ref<Font> Control::fetch_theme_default_font(Control *p_theme_owner, Window *p_th Window *theme_owner_window = p_theme_owner_window; while (theme_owner || theme_owner_window) { - if (theme_owner && theme_owner->data.theme->has_default_theme_font()) { - return theme_owner->data.theme->get_default_theme_font(); + 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_theme_font()) { - return theme_owner_window->theme->get_default_theme_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(); @@ -1223,13 +1227,16 @@ Ref<Font> Control::fetch_theme_default_font(Control *p_theme_owner, Window *p_th // Secondly, check the project-defined Theme resource. if (Theme::get_project_default().is_valid()) { - if (Theme::get_project_default()->has_default_theme_font()) { - return Theme::get_project_default()->get_default_theme_font(); + if (Theme::get_project_default()->has_default_font()) { + return Theme::get_project_default()->get_default_font(); } } // Lastly, fall back on the default Theme. - return Theme::get_default()->get_default_theme_font(); + if (Theme::get_default()->has_default_font()) { + return Theme::get_default()->get_default_font(); + } + return Theme::get_fallback_font(); } Ref<Font> Control::get_theme_default_font() const { @@ -1244,12 +1251,12 @@ int Control::fetch_theme_default_font_size(Control *p_theme_owner, Window *p_the Window *theme_owner_window = p_theme_owner_window; while (theme_owner || theme_owner_window) { - if (theme_owner && theme_owner->data.theme->has_default_theme_font_size()) { - return theme_owner->data.theme->get_default_theme_font_size(); + 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_theme_font_size()) { - return theme_owner_window->theme->get_default_theme_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(); @@ -1271,13 +1278,16 @@ int Control::fetch_theme_default_font_size(Control *p_theme_owner, Window *p_the // Secondly, check the project-defined Theme resource. if (Theme::get_project_default().is_valid()) { - if (Theme::get_project_default()->has_default_theme_font_size()) { - return Theme::get_project_default()->get_default_theme_font_size(); + if (Theme::get_project_default()->has_default_font_size()) { + return Theme::get_project_default()->get_default_font_size(); } } // Lastly, fall back on the default Theme. - return Theme::get_default()->get_default_theme_font_size(); + if (Theme::get_default()->has_default_font_size()) { + return Theme::get_default()->get_default_font_size(); + } + return Theme::get_fallback_font_size(); } int Control::get_theme_default_font_size() const { @@ -2534,7 +2544,7 @@ void Control::grab_click_focus() { get_viewport()->_gui_grab_click_focus(this); } -void Control::minimum_size_changed() { +void Control::update_minimum_size() { if (!is_inside_tree() || data.block_minimum_size_adjust) { return; } @@ -2597,7 +2607,7 @@ bool Control::is_text_field() const { return false; } -Array Control::structured_text_parser(StructuredTextParser p_theme_type, const Array &p_args, const String p_text) const { +Array Control::structured_text_parser(StructuredTextParser p_theme_type, const Array &p_args, const String &p_text) const { Array ret; switch (p_theme_type) { case STRUCTURED_TEXT_URI: { @@ -2696,7 +2706,7 @@ real_t Control::get_rotation() const { void Control::_override_changed() { notification(NOTIFICATION_THEME_CHANGED); emit_signal(SceneStringNames::get_singleton()->theme_changed); - minimum_size_changed(); // overrides are likely to affect minimum size + update_minimum_size(); // Overrides are likely to affect minimum size. } void Control::set_pivot_offset(const Vector2 &p_pivot) { @@ -2791,7 +2801,7 @@ void Control::get_argument_options(const StringName &p_function, int p_idx, List TypedArray<String> Control::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); - if (data.mouse_filter == MOUSE_FILTER_IGNORE && data.tooltip != "") { + if (data.mouse_filter == MOUSE_FILTER_IGNORE && !data.tooltip.is_empty()) { warnings.push_back(TTR("The Hint Tooltip won't be displayed as the control's Mouse Filter is set to \"Ignore\". To solve this, set the Mouse Filter to \"Stop\" or \"Pass\".")); } @@ -2977,7 +2987,7 @@ void Control::_bind_methods() { ClassDB::bind_method(D_METHOD("warp_mouse", "to_position"), &Control::warp_mouse); - ClassDB::bind_method(D_METHOD("minimum_size_changed"), &Control::minimum_size_changed); + ClassDB::bind_method(D_METHOD("update_minimum_size"), &Control::update_minimum_size); ClassDB::bind_method(D_METHOD("set_layout_direction", "direction"), &Control::set_layout_direction); ClassDB::bind_method(D_METHOD("get_layout_direction"), &Control::get_layout_direction); diff --git a/scene/gui/control.h b/scene/gui/control.h index 1a94cc68a6..bf79f790e7 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -279,7 +279,7 @@ protected: //virtual void _window_gui_input(InputEvent p_event); - virtual Array structured_text_parser(StructuredTextParser p_theme_type, const Array &p_args, const String p_text) const; + virtual Array structured_text_parser(StructuredTextParser p_theme_type, const Array &p_args, const String &p_text) const; bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; @@ -441,7 +441,7 @@ public: void set_stretch_ratio(real_t p_ratio); real_t get_stretch_ratio() const; - void minimum_size_changed(); + void update_minimum_size(); /* FOCUS */ diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp index f66d3f6835..1cbe3adb3c 100644 --- a/scene/gui/dialogs.cpp +++ b/scene/gui/dialogs.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -242,7 +242,7 @@ Button *AcceptDialog::add_button(const String &p_text, bool p_right, const Strin hbc->add_spacer(true); } - if (p_action != "") { + if (!p_action.is_empty()) { button->connect("pressed", callable_mp(this, &AcceptDialog::_custom_action), varray(p_action)); } @@ -251,7 +251,7 @@ Button *AcceptDialog::add_button(const String &p_text, bool p_right, const Strin Button *AcceptDialog::add_cancel_button(const String &p_cancel) { String c = p_cancel; - if (p_cancel == "") { + if (p_cancel.is_empty()) { c = TTRC("Cancel"); } Button *b = swap_cancel_ok ? add_button(c, true) : add_button(c); diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h index 8e803a2a7c..1365b1df24 100644 --- a/scene/gui/dialogs.h +++ b/scene/gui/dialogs.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index e3754c4d38..44ef641cb8 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -42,6 +42,17 @@ FileDialog::RegisterFunc FileDialog::unregister_func = nullptr; void FileDialog::popup_file_dialog() { popup_centered_clamped(Size2i(700, 500), 0.8f); + _focus_file_text(); +} + +void FileDialog::_focus_file_text() { + int lp = file->get_text().rfind("."); + if (lp != -1) { + file->select(0, lp); + if (file->is_inside_tree() && !get_tree()->is_node_being_edited(file)) { + file->grab_focus(); + } + } } VBoxContainer *FileDialog::get_vbox() { @@ -649,6 +660,7 @@ void FileDialog::clear_filters() { } void FileDialog::add_filter(const String &p_filter) { + ERR_FAIL_COND_MSG(p_filter.begins_with("."), "Filter must be \"filename.extension\", can't start with dot."); filters.push_back(p_filter); update_filters(); invalidate(); @@ -687,13 +699,7 @@ void FileDialog::set_current_file(const String &p_file) { file->set_text(p_file); update_dir(); invalidate(); - int lp = p_file.rfind("."); - if (lp != -1) { - file->select(0, lp); - if (file->is_inside_tree() && !get_tree()->is_node_being_edited(file)) { - file->grab_focus(); - } - } + _focus_file_text(); } void FileDialog::set_current_path(const String &p_path) { @@ -1000,8 +1006,8 @@ FileDialog::FileDialog() { message = memnew(Label); message->hide(); message->set_anchors_and_offsets_preset(Control::PRESET_WIDE); - message->set_align(Label::ALIGN_CENTER); - message->set_valign(Label::VALIGN_CENTER); + message->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); + message->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER); tree->add_child(message); file_box = memnew(HBoxContainer); diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h index b5190bdab1..9f8bc02b2a 100644 --- a/scene/gui/file_dialog.h +++ b/scene/gui/file_dialog.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -113,6 +113,8 @@ private: void update_file_list(); void update_filters(); + void _focus_file_text(); + void _tree_multi_selected(Object *p_object, int p_cell, bool p_selected); void _tree_selected(); diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp index 1210be15ce..bec3d58384 100644 --- a/scene/gui/gradient_edit.cpp +++ b/scene/gui/gradient_edit.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -432,6 +432,10 @@ Gradient::InterpolationMode GradientEdit::get_interpolation_mode() { return interpolation_mode; } +ColorPicker *GradientEdit::get_picker() { + return picker; +} + void GradientEdit::_bind_methods() { ADD_SIGNAL(MethodInfo("ramp_changed")); } diff --git a/scene/gui/gradient_edit.h b/scene/gui/gradient_edit.h index 66b60d87c7..407f61f7c1 100644 --- a/scene/gui/gradient_edit.h +++ b/scene/gui/gradient_edit.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -75,6 +75,7 @@ public: Vector<Gradient::Point> &get_points(); void set_interpolation_mode(Gradient::InterpolationMode p_interp_mode); Gradient::InterpolationMode get_interpolation_mode(); + ColorPicker *get_picker(); virtual Size2 get_minimum_size() const override; diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index e7d98a686f..79b73f7cc3 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -35,6 +35,7 @@ #include "core/os/keyboard.h" #include "scene/gui/box_container.h" #include "scene/gui/button.h" +#include "scene/gui/view_panner.h" constexpr int MINIMAP_OFFSET = 12; constexpr int MINIMAP_PADDING = 5; @@ -549,15 +550,13 @@ bool GraphEdit::_filter_input(const Point2 &p_point) { } for (int j = 0; j < gn->get_connection_output_count(); j++) { - Vector2 pos = gn->get_connection_output_position(j) + gn->get_position(); - if (is_in_hot_zone(pos / zoom, p_point / zoom, port_size, false)) { + if (is_in_output_hotzone(gn, j, p_point / zoom, port_size)) { return true; } } for (int j = 0; j < gn->get_connection_input_count(); j++) { - Vector2 pos = gn->get_connection_input_position(j) + gn->get_position(); - if (is_in_hot_zone(pos / zoom, p_point / zoom, port_size, true)) { + if (is_in_input_hotzone(gn, j, p_point / zoom, port_size)) { return true; } } @@ -582,7 +581,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { for (int j = 0; j < gn->get_connection_output_count(); j++) { Vector2 pos = gn->get_connection_output_position(j) + gn->get_position(); - if (is_in_hot_zone(pos / zoom, click_pos, port_size, false)) { + if (is_in_output_hotzone(gn, j, click_pos, port_size)) { if (valid_left_disconnect_types.has(gn->get_connection_output_type(j))) { //check disconnect for (const Connection &E : connections) { @@ -602,6 +601,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { to = get_node(String(connecting_from)); //maybe it was erased if (Object::cast_to<GraphNode>(to)) { connecting = true; + emit_signal(SNAME("connection_drag_started"), connecting_from, connecting_index, false); } return; } @@ -618,13 +618,14 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { connecting_target = false; connecting_to = pos; just_disconnected = false; + emit_signal(SNAME("connection_drag_started"), connecting_from, connecting_index, true); return; } } for (int j = 0; j < gn->get_connection_input_count(); j++) { Vector2 pos = gn->get_connection_input_position(j) + gn->get_position(); - if (is_in_hot_zone(pos / zoom, click_pos, port_size, true)) { + if (is_in_input_hotzone(gn, j, click_pos, port_size)) { if (right_disconnects || valid_right_disconnect_types.has(gn->get_connection_input_type(j))) { //check disconnect for (const Connection &E : connections) { @@ -644,6 +645,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { fr = get_node(String(connecting_from)); //maybe it was erased if (Object::cast_to<GraphNode>(fr)) { connecting = true; + emit_signal(SNAME("connection_drag_started"), connecting_from, connecting_index, true); } return; } @@ -660,7 +662,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { connecting_target = false; connecting_to = pos; just_disconnected = false; - + emit_signal(SNAME("connection_drag_started"), connecting_from, connecting_index, false); return; } } @@ -690,7 +692,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { for (int j = 0; j < gn->get_connection_output_count(); j++) { Vector2 pos = gn->get_connection_output_position(j) + gn->get_position(); int type = gn->get_connection_output_type(j); - if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos / zoom, mpos, port_size, false)) { + if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_output_hotzone(gn, j, mpos, port_size)) { connecting_target = true; connecting_to = pos; connecting_target_to = gn->get_name(); @@ -702,7 +704,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { for (int j = 0; j < gn->get_connection_input_count(); j++) { Vector2 pos = gn->get_connection_input_position(j) + gn->get_position(); int type = gn->get_connection_input_type(j); - if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos / zoom, mpos, port_size, true)) { + if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_input_hotzone(gn, j, mpos, port_size)) { connecting_target = true; connecting_to = pos; connecting_target_to = gn->get_name(); @@ -742,11 +744,9 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { } } - connecting = false; - top_layer->update(); - minimap->update(); - update(); - connections_layer->update(); + if (connecting) { + force_connection_drag_end(); + } } } @@ -773,25 +773,29 @@ bool GraphEdit::_check_clickable_control(Control *p_control, const Vector2 &pos) } } -bool GraphEdit::is_in_hot_zone(const Vector2 &pos, const Vector2 &p_mouse_pos, const Vector2i &p_port_size, bool p_left) { - if (p_left) { - if (!Rect2( - pos.x - p_port_size.x / 2 - port_grab_distance_horizontal, - pos.y - p_port_size.y / 2 - port_grab_distance_vertical / 2, - p_port_size.x + port_grab_distance_horizontal, - p_port_size.y + port_grab_distance_vertical) - .has_point(p_mouse_pos)) { - return false; - } +bool GraphEdit::is_in_input_hotzone(GraphNode *p_graph_node, int p_slot_index, const Vector2 &p_mouse_pos, const Vector2i &p_port_size) { + bool success; + if (GDVIRTUAL_CALL(_is_in_input_hotzone, p_graph_node, p_slot_index, p_mouse_pos, success)) { + return success; } else { - if (!Rect2( - pos.x - p_port_size.x / 2, - pos.y - p_port_size.y / 2 - port_grab_distance_vertical / 2, - p_port_size.x + port_grab_distance_horizontal, - p_port_size.y + port_grab_distance_vertical) - .has_point(p_mouse_pos)) { - return false; - } + Vector2 pos = p_graph_node->get_connection_input_position(p_slot_index) + p_graph_node->get_position(); + return is_in_port_hotzone(pos / zoom, p_mouse_pos, p_port_size, true); + } +} + +bool GraphEdit::is_in_output_hotzone(GraphNode *p_graph_node, int p_slot_index, const Vector2 &p_mouse_pos, const Vector2i &p_port_size) { + bool success; + if (GDVIRTUAL_CALL(_is_in_output_hotzone, p_graph_node, p_slot_index, p_mouse_pos, success)) { + return success; + } else { + Vector2 pos = p_graph_node->get_connection_output_position(p_slot_index) + p_graph_node->get_position(); + return is_in_port_hotzone(pos / zoom, p_mouse_pos, p_port_size, false); + } +} + +bool GraphEdit::is_in_port_hotzone(const Vector2 &pos, const Vector2 &p_mouse_pos, const Vector2i &p_port_size, bool p_left) { + if (!Rect2(pos.x - port_grab_distance_horizontal, pos.y - port_grab_distance_vertical, port_grab_distance_horizontal * 2, port_grab_distance_vertical * 2).has_point(p_mouse_pos)) { + return false; } for (int i = 0; i < get_child_count(); i++) { @@ -1066,13 +1070,9 @@ void GraphEdit::set_selected(Node *p_child) { void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) { ERR_FAIL_COND(p_ev.is_null()); + panner->gui_input(p_ev); Ref<InputEventMouseMotion> mm = p_ev; - if (mm.is_valid() && ((mm->get_button_mask() & MouseButton::MASK_MIDDLE) != MouseButton::NONE || ((mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE && Input::get_singleton()->is_key_pressed(Key::SPACE)))) { - Vector2i relative = Input::get_singleton()->warp_mouse_motion(mm, get_global_rect()); - h_scroll->set_value(h_scroll->get_value() - relative.x); - v_scroll->set_value(v_scroll->get_value() - relative.y); - } if (mm.is_valid() && dragging) { if (!moving_selection) { @@ -1162,11 +1162,9 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) { minimap->update(); } else { if (connecting) { - connecting = false; - top_layer->update(); - minimap->update(); + force_connection_drag_end(); } else { - emit_signal(SNAME("popup_request"), b->get_global_position()); + emit_signal(SNAME("popup_request"), get_screen_position() + b->get_position()); } } } @@ -1326,22 +1324,6 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) { top_layer->update(); minimap->update(); } - - int scroll_direction = (b->get_button_index() == MouseButton::WHEEL_DOWN) - (b->get_button_index() == MouseButton::WHEEL_UP); - if (scroll_direction != 0) { - if (b->is_ctrl_pressed()) { - if (b->is_shift_pressed()) { - // Horizontal scrolling. - h_scroll->set_value(h_scroll->get_value() + (h_scroll->get_page() * b->get_factor() / 8) * scroll_direction); - } else { - // Vertical scrolling. - v_scroll->set_value(v_scroll->get_value() + (v_scroll->get_page() * b->get_factor() / 8) * scroll_direction); - } - } else { - // Zooming. - set_zoom_custom(scroll_direction < 0 ? zoom * zoom_step : zoom / zoom_step, b->get_position()); - } - } } if (p_ev->is_pressed()) { @@ -1372,6 +1354,23 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) { } } +void GraphEdit::_scroll_callback(Vector2 p_scroll_vec) { + if (p_scroll_vec.x != 0) { + h_scroll->set_value(h_scroll->get_value() + (h_scroll->get_page() * Math::abs(p_scroll_vec.x) / 8) * SIGN(p_scroll_vec.x)); + } else { + v_scroll->set_value(v_scroll->get_value() + (v_scroll->get_page() * Math::abs(p_scroll_vec.y) / 8) * SIGN(p_scroll_vec.y)); + } +} + +void GraphEdit::_pan_callback(Vector2 p_scroll_vec) { + h_scroll->set_value(h_scroll->get_value() - p_scroll_vec.x); + v_scroll->set_value(v_scroll->get_value() - p_scroll_vec.y); +} + +void GraphEdit::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin) { + set_zoom_custom(p_scroll_vec.y < 0 ? zoom * zoom_step : zoom / zoom_step, p_origin); +} + void GraphEdit::set_connection_activity(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port, float p_activity) { for (Connection &E : connections) { if (E.from == p_from && E.from_port == p_from_port && E.to == p_to && E.to_port == p_to_port) { @@ -1394,6 +1393,26 @@ void GraphEdit::clear_connections() { connections_layer->update(); } +void GraphEdit::force_connection_drag_end() { + ERR_FAIL_COND_MSG(!connecting, "Drag end requested without active drag!"); + connecting = false; + connecting_valid = false; + top_layer->update(); + minimap->update(); + update(); + connections_layer->update(); + emit_signal(SNAME("connection_drag_ended")); +} + +void GraphEdit::set_panning_scheme(PanningScheme p_scheme) { + panning_scheme = p_scheme; + panner->set_control_scheme((ViewPanner::ControlScheme)p_scheme); +} + +GraphEdit::PanningScheme GraphEdit::get_panning_scheme() const { + return panning_scheme; +} + void GraphEdit::set_zoom(float p_zoom) { set_zoom_custom(p_zoom, get_size() / 2); } @@ -1692,7 +1711,7 @@ int GraphEdit::_set_operations(SET_OPERATIONS p_operation, Set<StringName> &r_u, r_u.insert(E->get()); } } - return r_v.size(); + return r_u.size(); } break; default: break; @@ -1787,8 +1806,8 @@ void GraphEdit::_horizontal_alignment(Dictionary &r_root, Dictionary &r_align, c } } - int start = up.size() / 2; - int end = up.size() % 2 ? start : start + 1; + int start = (up.size() - 1) / 2; + int end = (up.size() - 1) % 2 ? start + 1 : start; for (int p = start; p <= end; p++) { StringName Align = r_align[current_node]; if (Align == current_node && r < up[p].first) { @@ -2107,7 +2126,7 @@ void GraphEdit::arrange_nodes() { } while (u != E->get()); } - //Compute horizontal co-ordinates individually for layers to get uniform gap + // Compute horizontal coordinates individually for layers to get uniform gap. float start_from = origin.x; float largest_node_size = 0.0f; @@ -2165,6 +2184,7 @@ void GraphEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("set_connection_activity", "from", "from_port", "to", "to_port", "amount"), &GraphEdit::set_connection_activity); ClassDB::bind_method(D_METHOD("get_connection_list"), &GraphEdit::_get_connection_list); ClassDB::bind_method(D_METHOD("clear_connections"), &GraphEdit::clear_connections); + ClassDB::bind_method(D_METHOD("force_connection_drag_end"), &GraphEdit::force_connection_drag_end); ClassDB::bind_method(D_METHOD("get_scroll_ofs"), &GraphEdit::get_scroll_ofs); ClassDB::bind_method(D_METHOD("set_scroll_ofs", "ofs"), &GraphEdit::set_scroll_ofs); @@ -2177,6 +2197,9 @@ void GraphEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("is_valid_connection_type", "from_type", "to_type"), &GraphEdit::is_valid_connection_type); ClassDB::bind_method(D_METHOD("get_connection_line", "from", "to"), &GraphEdit::get_connection_line); + ClassDB::bind_method(D_METHOD("set_panning_scheme", "scheme"), &GraphEdit::set_panning_scheme); + ClassDB::bind_method(D_METHOD("get_panning_scheme"), &GraphEdit::get_panning_scheme); + ClassDB::bind_method(D_METHOD("set_zoom", "zoom"), &GraphEdit::set_zoom); ClassDB::bind_method(D_METHOD("get_zoom"), &GraphEdit::get_zoom); @@ -2216,6 +2239,8 @@ void GraphEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("is_right_disconnects_enabled"), &GraphEdit::is_right_disconnects_enabled); ClassDB::bind_method(D_METHOD("_update_scroll_offset"), &GraphEdit::_update_scroll_offset); + GDVIRTUAL_BIND(_is_in_input_hotzone, "graph_node", "slot_index", "mouse_position"); + GDVIRTUAL_BIND(_is_in_output_hotzone, "graph_node", "slot_index", "mouse_position"); ClassDB::bind_method(D_METHOD("get_zoom_hbox"), &GraphEdit::get_zoom_hbox); @@ -2229,6 +2254,7 @@ void GraphEdit::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scroll_offset"), "set_scroll_ofs", "get_scroll_ofs"); ADD_PROPERTY(PropertyInfo(Variant::INT, "snap_distance"), "set_snap", "get_snap"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_snap"), "set_use_snap", "is_using_snap"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "panning_scheme", PROPERTY_HINT_ENUM, "Scroll Zooms,Scroll Pans"), "set_panning_scheme", "get_panning_scheme"); ADD_GROUP("Connection Lines", "connection_lines"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "connection_lines_thickness"), "set_connection_lines_thickness", "get_connection_lines_thickness"); @@ -2260,6 +2286,11 @@ void GraphEdit::_bind_methods() { ADD_SIGNAL(MethodInfo("begin_node_move")); ADD_SIGNAL(MethodInfo("end_node_move")); ADD_SIGNAL(MethodInfo("scroll_offset_changed", PropertyInfo(Variant::VECTOR2, "ofs"))); + ADD_SIGNAL(MethodInfo("connection_drag_started", PropertyInfo(Variant::STRING, "from"), PropertyInfo(Variant::STRING, "slot"), PropertyInfo(Variant::BOOL, "is_output"))); + ADD_SIGNAL(MethodInfo("connection_drag_ended")); + + BIND_ENUM_CONSTANT(SCROLL_ZOOMS); + BIND_ENUM_CONSTANT(SCROLL_PANS); } GraphEdit::GraphEdit() { @@ -2272,6 +2303,10 @@ GraphEdit::GraphEdit() { // Allow zooming 4 times from the default zoom level. zoom_max = (1 * Math::pow(zoom_step, 4)); + panner.instantiate(); + panner->set_callbacks(callable_mp(this, &GraphEdit::_scroll_callback), callable_mp(this, &GraphEdit::_pan_callback), callable_mp(this, &GraphEdit::_zoom_callback)); + panner->set_disable_rmb(true); + top_layer = memnew(GraphEditFilter(this)); add_child(top_layer, false, INTERNAL_MODE_BACK); top_layer->set_mouse_filter(MOUSE_FILTER_PASS); @@ -2312,7 +2347,7 @@ GraphEdit::GraphEdit() { zoom_hb->add_child(zoom_label); zoom_label->set_visible(false); zoom_label->set_v_size_flags(Control::SIZE_SHRINK_CENTER); - zoom_label->set_align(Label::ALIGN_CENTER); + zoom_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); zoom_label->set_custom_minimum_size(Size2(48, 0)); _update_zoom_label(); diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index 6c11f9df6a..4e998d30a7 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -41,6 +41,7 @@ #include "scene/gui/texture_rect.h" class GraphEdit; +class ViewPanner; class GraphEditFilter : public Control { GDCLASS(GraphEditFilter, Control); @@ -103,6 +104,12 @@ public: float activity = 0.0; }; + // Should be in sync with ControlScheme in ViewPanner. + enum PanningScheme { + SCROLL_ZOOMS, + SCROLL_PANS, + }; + private: Label *zoom_label; Button *zoom_minus; @@ -122,6 +129,11 @@ private: float port_grab_distance_horizontal = 0.0; float port_grab_distance_vertical; + Ref<ViewPanner> panner; + void _scroll_callback(Vector2 p_scroll_vec); + void _pan_callback(Vector2 p_scroll_vec); + void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin); + bool connecting = false; String connecting_from; bool connecting_out = false; @@ -136,6 +148,7 @@ private: bool connecting_valid = false; Vector2 click_pos; + PanningScheme panning_scheme = SCROLL_ZOOMS; bool dragging = false; bool just_selected = false; bool moving_selection = false; @@ -183,7 +196,9 @@ private: GraphEditMinimap *minimap; void _top_layer_input(const Ref<InputEvent> &p_ev); - bool is_in_hot_zone(const Vector2 &pos, const Vector2 &p_mouse_pos, const Vector2i &p_port_size, bool p_left); + bool is_in_input_hotzone(GraphNode *p_graph_node, int p_slot_index, const Vector2 &p_mouse_pos, const Vector2i &p_port_size); + bool is_in_output_hotzone(GraphNode *p_graph_node, int p_slot_index, const Vector2 &p_mouse_pos, const Vector2i &p_port_size); + bool is_in_port_hotzone(const Vector2 &pos, const Vector2 &p_mouse_pos, const Vector2i &p_port_size, bool p_left); void _top_layer_draw(); void _connections_layer_draw(); @@ -259,12 +274,15 @@ protected: void _notification(int p_what); GDVIRTUAL2RC(Vector<Vector2>, _get_connection_line, Vector2, Vector2) + GDVIRTUAL3R(bool, _is_in_input_hotzone, Object *, int, Vector2) + GDVIRTUAL3R(bool, _is_in_output_hotzone, Object *, int, Vector2) public: Error connect_node(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port); bool is_node_connected(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port); void disconnect_node(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port); void clear_connections(); + void force_connection_drag_end(); void set_connection_activity(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port, float p_activity); @@ -272,6 +290,9 @@ public: void remove_valid_connection_type(int p_type, int p_with_type); bool is_valid_connection_type(int p_type, int p_with_type) const; + void set_panning_scheme(PanningScheme p_scheme); + PanningScheme get_panning_scheme() const; + void set_zoom(float p_zoom); void set_zoom_custom(float p_zoom, const Vector2 &p_center); float get_zoom() const; @@ -333,4 +354,6 @@ public: GraphEdit(); }; +VARIANT_ENUM_CAST(GraphEdit::PanningScheme); + #endif // GRAPHEdit_H diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index e7094c89b1..d6569e3de4 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -46,7 +46,7 @@ bool GraphNode::_set(const StringName &p_name, const Variant &p_value) { if (str.begins_with("opentype_features/")) { String name = str.get_slicec('/', 1); int32_t tag = TS->name_to_tag(name); - double value = p_value; + int value = p_value; if (value == -1) { if (opentype_features.has(tag)) { opentype_features.erase(tag); @@ -54,7 +54,7 @@ bool GraphNode::_set(const StringName &p_name, const Variant &p_value) { update(); } } else { - if ((double)opentype_features[tag] != value) { + if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) { opentype_features[tag] = value; _shape(); update(); @@ -153,7 +153,7 @@ bool GraphNode::_get(const StringName &p_name, Variant &r_ret) const { void GraphNode::_get_property_list(List<PropertyInfo> *p_list) const { for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) { String name = TS->tag_to_name(*ftr); - p_list->push_back(PropertyInfo(Variant::FLOAT, "opentype_features/" + name)); + p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name)); } p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR)); @@ -442,7 +442,7 @@ void GraphNode::_notification(int p_what) { case NOTIFICATION_THEME_CHANGED: { _shape(); - minimum_size_changed(); + update_minimum_size(); update(); } break; } @@ -458,7 +458,7 @@ void GraphNode::_shape() { } else { title_buf->set_direction((TextServer::Direction)text_direction); } - title_buf->add_string(title, font, font_size, opentype_features, (language != "") ? language : TranslationServer::get_singleton()->get_tool_locale()); + title_buf->add_string(title, font, font_size, opentype_features, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale()); } #ifdef TOOLS_ENABLED @@ -666,7 +666,7 @@ void GraphNode::set_title(const String &p_title) { _shape(); update(); - minimum_size_changed(); + update_minimum_size(); } String GraphNode::get_title() const { diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h index 2238cfdb56..b41fc7f5d4 100644 --- a/scene/gui/graph_node.h +++ b/scene/gui/graph_node.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp index 2beb2624d2..465c9dac78 100644 --- a/scene/gui/grid_container.cpp +++ b/scene/gui/grid_container.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -182,7 +182,7 @@ void GridContainer::_notification(int p_what) { } break; case NOTIFICATION_THEME_CHANGED: { - minimum_size_changed(); + update_minimum_size(); } break; case NOTIFICATION_TRANSLATION_CHANGED: case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: { @@ -195,7 +195,7 @@ void GridContainer::set_columns(int p_columns) { ERR_FAIL_COND(p_columns < 1); columns = p_columns; queue_sort(); - minimum_size_changed(); + update_minimum_size(); } int GridContainer::get_columns() const { diff --git a/scene/gui/grid_container.h b/scene/gui/grid_container.h index 9b43a5bc7e..9d77f90ab3 100644 --- a/scene/gui/grid_container.h +++ b/scene/gui/grid_container.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index 408ef53e89..0cb3249c1d 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -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.opentype_features, (item.language != "") ? item.language : TranslationServer::get_singleton()->get_tool_locale()); + item.text_buf->add_string(item.text, get_theme_font(SNAME("font")), get_theme_font_size(SNAME("font_size")), item.opentype_features, (!item.language.is_empty()) ? item.language : TranslationServer::get_singleton()->get_tool_locale()); if (icon_mode == ICON_MODE_TOP && max_text_lines > 0) { item.text_buf->set_flags(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::BREAK_GRAPHEME_BOUND); } else { @@ -653,7 +653,7 @@ void ItemList::gui_input(const Ref<InputEvent> &p_event) { if (p_event->is_pressed() && items.size() > 0) { if (p_event->is_action("ui_up")) { - if (search_string != "") { + if (!search_string.is_empty()) { uint64_t now = OS::get_singleton()->get_ticks_msec(); uint64_t diff = now - search_time_msec; @@ -683,7 +683,7 @@ void ItemList::gui_input(const Ref<InputEvent> &p_event) { accept_event(); } } else if (p_event->is_action("ui_down")) { - if (search_string != "") { + if (!search_string.is_empty()) { uint64_t now = OS::get_singleton()->get_ticks_msec(); uint64_t diff = now - search_time_msec; @@ -920,7 +920,7 @@ void ItemList::_notification(int p_what) { minsize = items[i].get_icon_size() * icon_scale; } - if (items[i].text != "") { + if (!items[i].text.is_empty()) { if (icon_mode == ICON_MODE_TOP) { minsize.y += icon_margin; } else { @@ -929,7 +929,7 @@ void ItemList::_notification(int p_what) { } } - if (items[i].text != "") { + if (!items[i].text.is_empty()) { int max_width = -1; if (fixed_column_width) { max_width = fixed_column_width; @@ -1037,7 +1037,7 @@ void ItemList::_notification(int p_what) { } } - minimum_size_changed(); + update_minimum_size(); shape_changed = false; } @@ -1188,7 +1188,7 @@ void ItemList::_notification(int p_what) { draw_texture(items[i].tag_icon, draw_pos + base_ofs); } - if (items[i].text != "") { + if (!items[i].text.is_empty()) { int max_len = -1; Vector2 size2 = items[i].text_buf->get_size(); @@ -1213,7 +1213,7 @@ void ItemList::_notification(int p_what) { text_ofs.x = size.width - text_ofs.x - max_len; } - items.write[i].text_buf->set_align(HALIGN_CENTER); + 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); @@ -1241,9 +1241,9 @@ void ItemList::_notification(int p_what) { items.write[i].text_buf->set_width(max_len); if (rtl) { - items.write[i].text_buf->set_align(HALIGN_RIGHT); + items.write[i].text_buf->set_alignment(HORIZONTAL_ALIGNMENT_RIGHT); } else { - items.write[i].text_buf->set_align(HALIGN_LEFT); + items.write[i].text_buf->set_alignment(HORIZONTAL_ALIGNMENT_LEFT); } if (outline_size > 0 && font_outline_color.a > 0) { @@ -1360,10 +1360,10 @@ String ItemList::get_tooltip(const Point2 &p_pos) const { if (!items[closest].tooltip_enabled) { return ""; } - if (items[closest].tooltip != "") { + if (!items[closest].tooltip.is_empty()) { return items[closest].tooltip; } - if (items[closest].text != "") { + if (!items[closest].text.is_empty()) { return items[closest].text; } } @@ -1492,6 +1492,9 @@ bool ItemList::_set(const StringName &p_name, const Variant &p_value) { } else if (components[1] == "disabled") { set_item_disabled(item_index, p_value); return true; + } else if (components[1] == "selectable") { + set_item_selectable(item_index, p_value); + return true; } } #ifndef DISABLE_DEPRECATED @@ -1528,6 +1531,9 @@ bool ItemList::_get(const StringName &p_name, Variant &r_ret) const { } else if (components[1] == "disabled") { r_ret = is_item_disabled(item_index); return true; + } else if (components[1] == "selectable") { + r_ret = is_item_selectable(item_index); + return true; } } return false; @@ -1541,6 +1547,10 @@ void ItemList::_get_property_list(List<PropertyInfo> *p_list) const { pi.usage &= ~(get_item_icon(i).is_null() ? PROPERTY_USAGE_STORAGE : 0); p_list->push_back(pi); + pi = PropertyInfo(Variant::BOOL, vformat("item_%d/selectable", i)); + pi.usage &= ~(is_item_selectable(i) ? PROPERTY_USAGE_STORAGE : 0); + p_list->push_back(pi); + pi = PropertyInfo(Variant::BOOL, vformat("item_%d/disabled", i)); pi.usage &= ~(!is_item_disabled(i) ? PROPERTY_USAGE_STORAGE : 0); p_list->push_back(pi); @@ -1652,7 +1662,7 @@ void ItemList::_bind_methods() { ClassDB::bind_method(D_METHOD("ensure_current_is_visible"), &ItemList::ensure_current_is_visible); - ClassDB::bind_method(D_METHOD("get_v_scroll"), &ItemList::get_v_scroll); + ClassDB::bind_method(D_METHOD("get_v_scroll_bar"), &ItemList::get_v_scroll_bar); ClassDB::bind_method(D_METHOD("set_text_overrun_behavior", "overrun_behavior"), &ItemList::set_text_overrun_behavior); ClassDB::bind_method(D_METHOD("get_text_overrun_behavior"), &ItemList::get_text_overrun_behavior); @@ -1663,7 +1673,7 @@ void ItemList::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "max_text_lines", PROPERTY_HINT_RANGE, "1,10,1,or_greater"), "set_max_text_lines", "get_max_text_lines"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_height"), "set_auto_height", "has_auto_height"); ADD_PROPERTY(PropertyInfo(Variant::INT, "text_overrun_behavior", PROPERTY_HINT_ENUM, "Trim Nothing,Trim Characters,Trim Words,Ellipsis,Word Ellipsis"), "set_text_overrun_behavior", "get_text_overrun_behavior"); - ADD_ARRAY_COUNT("Items", "items_count", "set_item_count", "get_item_count", "item_"); + ADD_ARRAY_COUNT("Items", "item_count", "set_item_count", "get_item_count", "item_"); ADD_GROUP("Columns", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "max_columns", PROPERTY_HINT_RANGE, "0,10,1,or_greater"), "set_max_columns", "get_max_columns"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "same_column_width"), "set_same_column_width", "is_same_column_width"); diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h index e780179e7b..77e910870f 100644 --- a/scene/gui/item_list.h +++ b/scene/gui/item_list.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -62,7 +62,7 @@ private: String language; TextDirection text_direction = TEXT_DIRECTION_AUTO; - bool selectable = false; + bool selectable = true; bool selected = false; bool disabled = false; bool tooltip_enabled = true; @@ -255,7 +255,7 @@ public: void set_autoscroll_to_bottom(const bool p_enable); - VScrollBar *get_v_scroll() { return scroll_bar; } + VScrollBar *get_v_scroll_bar() { return scroll_bar; } ItemList(); ~ItemList(); diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index 50908f6a77..a3878fe7ed 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -44,7 +44,7 @@ void Label::set_autowrap_mode(Label::AutowrapMode p_mode) { update(); if (clip || overrun_behavior != OVERRUN_NO_TRIMMING) { - minimum_size_changed(); + update_minimum_size(); } } @@ -83,6 +83,7 @@ void Label::_shape() { int width = (get_size().width - style->get_minimum_size().width); if (dirty) { + String lang = (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale(); TS->shaped_text_clear(text_rid); if (text_direction == Control::TEXT_DIRECTION_INHERITED) { TS->shaped_text_set_direction(text_rid, is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR); @@ -92,11 +93,11 @@ void Label::_shape() { const Ref<Font> &font = get_theme_font(SNAME("font")); int font_size = get_theme_font_size(SNAME("font_size")); ERR_FAIL_COND(font.is_null()); - String text = (uppercase) ? xl_text.to_upper() : xl_text; - if (visible_chars >= 0) { + String text = (uppercase) ? TS->string_to_upper(xl_text, lang) : xl_text; + if (visible_chars >= 0 && visible_chars_behavior == VC_CHARS_BEFORE_SHAPING) { text = text.substr(0, visible_chars); } - TS->shaped_text_add_string(text_rid, text, font->get_rids(), font_size, opentype_features, (language != "") ? language : TranslationServer::get_singleton()->get_tool_locale()); + TS->shaped_text_add_string(text_rid, text, font->get_rids(), font_size, opentype_features, lang); TS->shaped_text_set_bidi_override(text_rid, structured_text_parser(st_parser, st_args, text)); dirty = false; lines_dirty = true; @@ -175,7 +176,7 @@ void Label::_shape() { if (lines_hidden) { overrun_flags |= TextServer::OVERRUN_ENFORCE_ELLIPSIS; } - if (align == ALIGN_FILL) { + if (horizontal_alignment == HORIZONTAL_ALIGNMENT_FILL) { for (int i = 0; i < lines_rid.size(); i++) { if (i < visible_lines - 1 || lines_rid.size() == 1) { TS->shaped_text_fit_to_width(lines_rid[i], width); @@ -183,15 +184,13 @@ void Label::_shape() { TS->shaped_text_overrun_trim_to_width(lines_rid[visible_lines - 1], width, overrun_flags); } } - } else if (lines_hidden) { TS->shaped_text_overrun_trim_to_width(lines_rid[visible_lines - 1], width, overrun_flags); } - } else { // Autowrap disabled. for (int i = 0; i < lines_rid.size(); i++) { - if (align == ALIGN_FILL) { + if (horizontal_alignment == HORIZONTAL_ALIGNMENT_FILL) { TS->shaped_text_fit_to_width(lines_rid[i], width); overrun_flags |= TextServer::OVERRUN_JUSTIFICATION_AWARE; TS->shaped_text_overrun_trim_to_width(lines_rid[i], width, overrun_flags); @@ -207,7 +206,7 @@ void Label::_shape() { _update_visible(); if (autowrap_mode == AUTOWRAP_OFF || !clip || overrun_behavior == OVERRUN_NO_TRIMMING) { - minimum_size_changed(); + update_minimum_size(); } } @@ -294,7 +293,7 @@ void Label::_notification(int p_what) { Color font_outline_color = get_theme_color(SNAME("font_outline_color")); int outline_size = get_theme_constant(SNAME("outline_size")); int shadow_outline_size = get_theme_constant(SNAME("shadow_outline_size")); - bool rtl = TS->shaped_text_get_direction(text_rid); + bool rtl = (TS->shaped_text_get_inferred_direction(text_rid) == TextServer::DIRECTION_RTL); bool rtl_layout = is_layout_rtl(); style->draw(ci, Rect2(Point2(0, 0), get_size())); @@ -316,31 +315,38 @@ void Label::_notification(int p_what) { } int last_line = MIN(lines_rid.size(), lines_visible + lines_skipped); + bool trim_chars = (visible_chars >= 0) && (visible_chars_behavior == VC_CHARS_AFTER_SHAPING); + bool trim_glyphs_ltr = (visible_chars >= 0) && ((visible_chars_behavior == VC_GLYPHS_LTR) || ((visible_chars_behavior == VC_GLYPHS_AUTO) && !rtl_layout)); + bool trim_glyphs_rtl = (visible_chars >= 0) && ((visible_chars_behavior == VC_GLYPHS_RTL) || ((visible_chars_behavior == VC_GLYPHS_AUTO) && rtl_layout)); // Get real total height. + int total_glyphs = 0; total_h = 0; for (int64_t i = lines_skipped; i < last_line; i++) { total_h += TS->shaped_text_get_size(lines_rid[i]).y + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM) + line_spacing; + total_glyphs += TS->shaped_text_get_glyph_count(lines_rid[i]) + TS->shaped_text_get_ellipsis_glyph_count(lines_rid[i]); } + int visible_glyphs = total_glyphs * percent_visible; + int processed_glyphs = 0; total_h += style->get_margin(SIDE_TOP) + style->get_margin(SIDE_BOTTOM); int vbegin = 0, vsep = 0; if (lines_visible > 0) { - switch (valign) { - case VALIGN_TOP: { + switch (vertical_alignment) { + case VERTICAL_ALIGNMENT_TOP: { // Nothing. } break; - case VALIGN_CENTER: { + case VERTICAL_ALIGNMENT_CENTER: { vbegin = (size.y - (total_h - line_spacing)) / 2; vsep = 0; } break; - case VALIGN_BOTTOM: { + case VERTICAL_ALIGNMENT_BOTTOM: { vbegin = size.y - (total_h - line_spacing); vsep = 0; } break; - case VALIGN_FILL: { + case VERTICAL_ALIGNMENT_FILL: { vbegin = 0; if (lines_visible > 1) { vsep = (size.y - (total_h - line_spacing)) / (lines_visible - 1); @@ -358,25 +364,25 @@ void Label::_notification(int p_what) { Size2 line_size = TS->shaped_text_get_size(lines_rid[i]); ofs.x = 0; ofs.y += TS->shaped_text_get_ascent(lines_rid[i]) + font->get_spacing(TextServer::SPACING_TOP); - switch (align) { - case ALIGN_FILL: + switch (horizontal_alignment) { + case HORIZONTAL_ALIGNMENT_FILL: if (rtl && autowrap_mode != AUTOWRAP_OFF) { ofs.x = int(size.width - style->get_margin(SIDE_RIGHT) - line_size.width); } else { ofs.x = style->get_offset().x; } break; - case ALIGN_LEFT: { + case HORIZONTAL_ALIGNMENT_LEFT: { if (rtl_layout) { ofs.x = int(size.width - style->get_margin(SIDE_RIGHT) - line_size.width); } else { ofs.x = style->get_offset().x; } } break; - case ALIGN_CENTER: { + case HORIZONTAL_ALIGNMENT_CENTER: { ofs.x = int(size.width - line_size.width) / 2; } break; - case ALIGN_RIGHT: { + case HORIZONTAL_ALIGNMENT_RIGHT: { if (rtl_layout) { ofs.x = style->get_offset().x; } else { @@ -395,14 +401,19 @@ void Label::_notification(int p_what) { int ellipsis_gl_size = TS->shaped_text_get_ellipsis_glyph_count(lines_rid[i]); // Draw outline. Note: Do not merge this into the single loop with the main text, to prevent overlaps. + int processed_glyphs_ol = processed_glyphs; if ((outline_size > 0 && font_outline_color.a != 0) || (font_shadow_color.a != 0)) { Vector2 offset = ofs; // Draw RTL ellipsis string when necessary. if (rtl && ellipsis_pos >= 0) { for (int gl_idx = ellipsis_gl_size - 1; gl_idx >= 0; gl_idx--) { for (int j = 0; j < ellipsis_glyphs[gl_idx].repeat; j++) { + bool skip = (trim_chars && ellipsis_glyphs[gl_idx].end > visible_chars) || (trim_glyphs_ltr && (processed_glyphs_ol >= visible_glyphs)) || (trim_glyphs_rtl && (processed_glyphs_ol < total_glyphs - visible_glyphs)); //Draw glyph outlines and shadow. - draw_glyph_outline(ellipsis_glyphs[gl_idx], ci, font_color, font_shadow_color, font_outline_color, shadow_outline_size, outline_size, offset, shadow_ofs); + if (!skip) { + draw_glyph_outline(ellipsis_glyphs[gl_idx], ci, font_color, font_shadow_color, font_outline_color, shadow_outline_size, outline_size, offset, shadow_ofs); + } + processed_glyphs_ol++; offset.x += ellipsis_glyphs[gl_idx].advance; } } @@ -410,22 +421,26 @@ void Label::_notification(int p_what) { // Draw main text. for (int j = 0; j < gl_size; j++) { - for (int k = 0; k < glyphs[j].repeat; k++) { - // Trim when necessary. - if (trim_pos >= 0) { - if (rtl) { - if (j < trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { - continue; - } - } else { - if (j >= trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { - break; - } + // Trim when necessary. + if (trim_pos >= 0) { + if (rtl) { + if (j < trim_pos) { + continue; + } + } else { + if (j >= trim_pos) { + break; } } + } + for (int k = 0; k < glyphs[j].repeat; k++) { + bool skip = (trim_chars && glyphs[j].end > visible_chars) || (trim_glyphs_ltr && (processed_glyphs_ol >= visible_glyphs)) || (trim_glyphs_rtl && (processed_glyphs_ol < total_glyphs - visible_glyphs)); // Draw glyph outlines and shadow. - draw_glyph_outline(glyphs[j], ci, font_color, font_shadow_color, font_outline_color, shadow_outline_size, outline_size, offset, shadow_ofs); + if (!skip) { + draw_glyph_outline(glyphs[j], ci, font_color, font_shadow_color, font_outline_color, shadow_outline_size, outline_size, offset, shadow_ofs); + } + processed_glyphs_ol++; offset.x += glyphs[j].advance; } } @@ -433,8 +448,12 @@ void Label::_notification(int p_what) { if (!rtl && ellipsis_pos >= 0) { for (int gl_idx = 0; gl_idx < ellipsis_gl_size; gl_idx++) { for (int j = 0; j < ellipsis_glyphs[gl_idx].repeat; j++) { + bool skip = (trim_chars && ellipsis_glyphs[gl_idx].end > visible_chars) || (trim_glyphs_ltr && (processed_glyphs_ol >= visible_glyphs)) || (trim_glyphs_rtl && (processed_glyphs_ol < total_glyphs - visible_glyphs)); //Draw glyph outlines and shadow. - draw_glyph_outline(ellipsis_glyphs[gl_idx], ci, font_color, font_shadow_color, font_outline_color, shadow_outline_size, outline_size, offset, shadow_ofs); + if (!skip) { + draw_glyph_outline(ellipsis_glyphs[gl_idx], ci, font_color, font_shadow_color, font_outline_color, shadow_outline_size, outline_size, offset, shadow_ofs); + } + processed_glyphs_ol++; offset.x += ellipsis_glyphs[gl_idx].advance; } } @@ -447,8 +466,12 @@ void Label::_notification(int p_what) { if (rtl && ellipsis_pos >= 0) { for (int gl_idx = ellipsis_gl_size - 1; gl_idx >= 0; gl_idx--) { for (int j = 0; j < ellipsis_glyphs[gl_idx].repeat; j++) { + bool skip = (trim_chars && ellipsis_glyphs[gl_idx].end > visible_chars) || (trim_glyphs_ltr && (processed_glyphs >= visible_glyphs)) || (trim_glyphs_rtl && (processed_glyphs < total_glyphs - visible_glyphs)); //Draw glyph outlines and shadow. - draw_glyph(ellipsis_glyphs[gl_idx], ci, font_color, ofs); + if (!skip) { + draw_glyph(ellipsis_glyphs[gl_idx], ci, font_color, ofs); + } + processed_glyphs++; ofs.x += ellipsis_glyphs[gl_idx].advance; } } @@ -456,22 +479,26 @@ void Label::_notification(int p_what) { // Draw main text. for (int j = 0; j < gl_size; j++) { - for (int k = 0; k < glyphs[j].repeat; k++) { - // Trim when necessary. - if (trim_pos >= 0) { - if (rtl) { - if (j < trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { - continue; - } - } else { - if (j >= trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { - break; - } + // Trim when necessary. + if (trim_pos >= 0) { + if (rtl) { + if (j < trim_pos) { + continue; + } + } else { + if (j >= trim_pos) { + break; } } + } + for (int k = 0; k < glyphs[j].repeat; k++) { + bool skip = (trim_chars && glyphs[j].end > visible_chars) || (trim_glyphs_ltr && (processed_glyphs >= visible_glyphs)) || (trim_glyphs_rtl && (processed_glyphs < total_glyphs - visible_glyphs)); // Draw glyph outlines and shadow. - draw_glyph(glyphs[j], ci, font_color, ofs); + if (!skip) { + draw_glyph(glyphs[j], ci, font_color, ofs); + } + processed_glyphs++; ofs.x += glyphs[j].advance; } } @@ -479,8 +506,12 @@ void Label::_notification(int p_what) { if (!rtl && ellipsis_pos >= 0) { for (int gl_idx = 0; gl_idx < ellipsis_gl_size; gl_idx++) { for (int j = 0; j < ellipsis_glyphs[gl_idx].repeat; j++) { + bool skip = (trim_chars && ellipsis_glyphs[gl_idx].end > visible_chars) || (trim_glyphs_ltr && (processed_glyphs >= visible_glyphs)) || (trim_glyphs_rtl && (processed_glyphs < total_glyphs - visible_glyphs)); //Draw glyph outlines and shadow. - draw_glyph(ellipsis_glyphs[gl_idx], ci, font_color, ofs); + if (!skip) { + draw_glyph(ellipsis_glyphs[gl_idx], ci, font_color, ofs); + } + processed_glyphs++; ofs.x += ellipsis_glyphs[gl_idx].advance; } } @@ -556,29 +587,29 @@ int Label::get_visible_line_count() const { return lines_visible; } -void Label::set_align(Align p_align) { - ERR_FAIL_INDEX((int)p_align, 4); - if (align != p_align) { - if (align == ALIGN_FILL || p_align == ALIGN_FILL) { +void Label::set_horizontal_alignment(HorizontalAlignment p_alignment) { + ERR_FAIL_INDEX((int)p_alignment, 4); + if (horizontal_alignment != p_alignment) { + if (horizontal_alignment == HORIZONTAL_ALIGNMENT_FILL || p_alignment == HORIZONTAL_ALIGNMENT_FILL) { lines_dirty = true; // Reshape lines. } - align = p_align; + horizontal_alignment = p_alignment; } update(); } -Label::Align Label::get_align() const { - return align; +HorizontalAlignment Label::get_horizontal_alignment() const { + return horizontal_alignment; } -void Label::set_valign(VAlign p_align) { - ERR_FAIL_INDEX((int)p_align, 4); - valign = p_align; +void Label::set_vertical_alignment(VerticalAlignment p_alignment) { + ERR_FAIL_INDEX((int)p_alignment, 4); + vertical_alignment = p_alignment; update(); } -Label::VAlign Label::get_valign() const { - return valign; +VerticalAlignment Label::get_vertical_alignment() const { + return vertical_alignment; } void Label::set_text(const String &p_string) { @@ -592,7 +623,7 @@ void Label::set_text(const String &p_string) { visible_chars = get_total_character_count() * percent_visible; } update(); - minimum_size_changed(); + update_minimum_size(); } void Label::set_text_direction(Control::TextDirection p_text_direction) { @@ -668,7 +699,7 @@ String Label::get_language() const { void Label::set_clip_text(bool p_clip) { clip = p_clip; update(); - minimum_size_changed(); + update_minimum_size(); } bool Label::is_clipping_text() const { @@ -682,7 +713,7 @@ void Label::set_text_overrun_behavior(Label::OverrunBehavior p_behavior) { } update(); if (clip || overrun_behavior != OVERRUN_NO_TRIMMING) { - minimum_size_changed(); + update_minimum_size(); } } @@ -702,7 +733,9 @@ void Label::set_visible_characters(int p_amount) { } else { percent_visible = 1.0; } - dirty = true; + if (visible_chars_behavior == VC_CHARS_BEFORE_SHAPING) { + dirty = true; + } update(); } } @@ -720,7 +753,9 @@ void Label::set_percent_visible(float p_percent) { visible_chars = get_total_character_count() * p_percent; percent_visible = p_percent; } - dirty = true; + if (visible_chars_behavior == VC_CHARS_BEFORE_SHAPING) { + dirty = true; + } update(); } } @@ -729,6 +764,18 @@ float Label::get_percent_visible() const { return percent_visible; } +Label::VisibleCharactersBehavior Label::get_visible_characters_behavior() const { + return visible_chars_behavior; +} + +void Label::set_visible_characters_behavior(Label::VisibleCharactersBehavior p_behavior) { + if (visible_chars_behavior != p_behavior) { + visible_chars_behavior = p_behavior; + dirty = true; + update(); + } +} + void Label::set_lines_skipped(int p_lines) { ERR_FAIL_COND(p_lines < 0); lines_skipped = p_lines; @@ -763,7 +810,7 @@ bool Label::_set(const StringName &p_name, const Variant &p_value) { if (str.begins_with("opentype_features/")) { String name = str.get_slicec('/', 1); int32_t tag = TS->name_to_tag(name); - double value = p_value; + int value = p_value; if (value == -1) { if (opentype_features.has(tag)) { opentype_features.erase(tag); @@ -771,7 +818,7 @@ bool Label::_set(const StringName &p_name, const Variant &p_value) { update(); } } else { - if ((double)opentype_features[tag] != value) { + if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) { opentype_features[tag] = value; dirty = true; update(); @@ -803,16 +850,16 @@ bool Label::_get(const StringName &p_name, Variant &r_ret) const { void Label::_get_property_list(List<PropertyInfo> *p_list) const { for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) { String name = TS->tag_to_name(*ftr); - p_list->push_back(PropertyInfo(Variant::FLOAT, "opentype_features/" + name)); + p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name)); } p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR)); } void Label::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_align", "align"), &Label::set_align); - ClassDB::bind_method(D_METHOD("get_align"), &Label::get_align); - ClassDB::bind_method(D_METHOD("set_valign", "valign"), &Label::set_valign); - ClassDB::bind_method(D_METHOD("get_valign"), &Label::get_valign); + ClassDB::bind_method(D_METHOD("set_horizontal_alignment", "alignment"), &Label::set_horizontal_alignment); + ClassDB::bind_method(D_METHOD("get_horizontal_alignment"), &Label::get_horizontal_alignment); + ClassDB::bind_method(D_METHOD("set_vertical_alignment", "alignment"), &Label::set_vertical_alignment); + ClassDB::bind_method(D_METHOD("get_vertical_alignment"), &Label::get_vertical_alignment); ClassDB::bind_method(D_METHOD("set_text", "text"), &Label::set_text); ClassDB::bind_method(D_METHOD("get_text"), &Label::get_text); ClassDB::bind_method(D_METHOD("set_text_direction", "direction"), &Label::set_text_direction); @@ -836,6 +883,8 @@ void Label::_bind_methods() { ClassDB::bind_method(D_METHOD("get_total_character_count"), &Label::get_total_character_count); ClassDB::bind_method(D_METHOD("set_visible_characters", "amount"), &Label::set_visible_characters); ClassDB::bind_method(D_METHOD("get_visible_characters"), &Label::get_visible_characters); + ClassDB::bind_method(D_METHOD("get_visible_characters_behavior"), &Label::get_visible_characters_behavior); + ClassDB::bind_method(D_METHOD("set_visible_characters_behavior", "behavior"), &Label::set_visible_characters_behavior); ClassDB::bind_method(D_METHOD("set_percent_visible", "percent_visible"), &Label::set_percent_visible); ClassDB::bind_method(D_METHOD("get_percent_visible"), &Label::get_percent_visible); ClassDB::bind_method(D_METHOD("set_lines_skipped", "lines_skipped"), &Label::set_lines_skipped); @@ -847,16 +896,6 @@ void Label::_bind_methods() { ClassDB::bind_method(D_METHOD("set_structured_text_bidi_override_options", "args"), &Label::set_structured_text_bidi_override_options); ClassDB::bind_method(D_METHOD("get_structured_text_bidi_override_options"), &Label::get_structured_text_bidi_override_options); - BIND_ENUM_CONSTANT(ALIGN_LEFT); - BIND_ENUM_CONSTANT(ALIGN_CENTER); - BIND_ENUM_CONSTANT(ALIGN_RIGHT); - BIND_ENUM_CONSTANT(ALIGN_FILL); - - BIND_ENUM_CONSTANT(VALIGN_TOP); - BIND_ENUM_CONSTANT(VALIGN_CENTER); - BIND_ENUM_CONSTANT(VALIGN_BOTTOM); - BIND_ENUM_CONSTANT(VALIGN_FILL); - BIND_ENUM_CONSTANT(AUTOWRAP_OFF); BIND_ENUM_CONSTANT(AUTOWRAP_ARBITRARY); BIND_ENUM_CONSTANT(AUTOWRAP_WORD); @@ -868,16 +907,24 @@ void Label::_bind_methods() { BIND_ENUM_CONSTANT(OVERRUN_TRIM_ELLIPSIS); BIND_ENUM_CONSTANT(OVERRUN_TRIM_WORD_ELLIPSIS); + BIND_ENUM_CONSTANT(VC_CHARS_BEFORE_SHAPING); + BIND_ENUM_CONSTANT(VC_CHARS_AFTER_SHAPING); + BIND_ENUM_CONSTANT(VC_GLYPHS_AUTO); + BIND_ENUM_CONSTANT(VC_GLYPHS_LTR); + BIND_ENUM_CONSTANT(VC_GLYPHS_RTL); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text"); + ADD_GROUP("Locale", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "language"), "set_language", "get_language"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_align", "get_align"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "valign", PROPERTY_HINT_ENUM, "Top,Center,Bottom,Fill"), "set_valign", "get_valign"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "horizontal_alignment", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_horizontal_alignment", "get_horizontal_alignment"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "vertical_alignment", PROPERTY_HINT_ENUM, "Top,Center,Bottom,Fill"), "set_vertical_alignment", "get_vertical_alignment"); ADD_PROPERTY(PropertyInfo(Variant::INT, "autowrap_mode", PROPERTY_HINT_ENUM, "Off,Arbitrary,Word,Word (Smart)"), "set_autowrap_mode", "get_autowrap_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_text"), "set_clip_text", "is_clipping_text"); ADD_PROPERTY(PropertyInfo(Variant::INT, "text_overrun_behavior", PROPERTY_HINT_ENUM, "Trim Nothing,Trim Characters,Trim Words,Ellipsis,Word Ellipsis"), "set_text_overrun_behavior", "get_text_overrun_behavior"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "uppercase"), "set_uppercase", "is_uppercase"); ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_characters", PROPERTY_HINT_RANGE, "-1,128000,1"), "set_visible_characters", "get_visible_characters"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_characters_behavior", PROPERTY_HINT_ENUM, "Characters Before Shaping,Characters After Shaping,Glyphs (Layout Direction),Glyphs (Left-to-Right),Glyphs (Right-to-Left)"), "set_visible_characters_behavior", "get_visible_characters_behavior"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "percent_visible", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_percent_visible", "get_percent_visible"); ADD_PROPERTY(PropertyInfo(Variant::INT, "lines_skipped", PROPERTY_HINT_RANGE, "0,999,1"), "set_lines_skipped", "get_lines_skipped"); ADD_PROPERTY(PropertyInfo(Variant::INT, "max_lines_visible", PROPERTY_HINT_RANGE, "-1,999,1"), "set_max_lines_visible", "get_max_lines_visible"); diff --git a/scene/gui/label.h b/scene/gui/label.h index 8b48eb9670..354e9c664d 100644 --- a/scene/gui/label.h +++ b/scene/gui/label.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -37,20 +37,6 @@ class Label : public Control { GDCLASS(Label, Control); public: - enum Align { - ALIGN_LEFT, - ALIGN_CENTER, - ALIGN_RIGHT, - ALIGN_FILL - }; - - enum VAlign { - VALIGN_TOP, - VALIGN_CENTER, - VALIGN_BOTTOM, - VALIGN_FILL - }; - enum AutowrapMode { AUTOWRAP_OFF, AUTOWRAP_ARBITRARY, @@ -66,9 +52,17 @@ public: OVERRUN_TRIM_WORD_ELLIPSIS, }; + enum VisibleCharactersBehavior { + VC_CHARS_BEFORE_SHAPING, + VC_CHARS_AFTER_SHAPING, + VC_GLYPHS_AUTO, + VC_GLYPHS_LTR, + VC_GLYPHS_RTL, + }; + private: - Align align = ALIGN_LEFT; - VAlign valign = VALIGN_TOP; + HorizontalAlignment horizontal_alignment = HORIZONTAL_ALIGNMENT_LEFT; + VerticalAlignment vertical_alignment = VERTICAL_ALIGNMENT_TOP; String text; String xl_text; AutowrapMode autowrap_mode = AUTOWRAP_OFF; @@ -90,6 +84,7 @@ private: float percent_visible = 1.0; + VisibleCharactersBehavior visible_chars_behavior = VC_CHARS_BEFORE_SHAPING; int visible_chars = -1; int lines_skipped = 0; int max_lines_visible = -1; @@ -109,11 +104,11 @@ protected: public: virtual Size2 get_minimum_size() const override; - void set_align(Align p_align); - Align get_align() const; + void set_horizontal_alignment(HorizontalAlignment p_alignment); + HorizontalAlignment get_horizontal_alignment() const; - void set_valign(VAlign p_align); - VAlign get_valign() const; + void set_vertical_alignment(VerticalAlignment p_alignment); + VerticalAlignment get_vertical_alignment() const; void set_text(const String &p_string); String get_text() const; @@ -140,6 +135,9 @@ public: void set_uppercase(bool p_uppercase); bool is_uppercase() const; + VisibleCharactersBehavior get_visible_characters_behavior() const; + void set_visible_characters_behavior(VisibleCharactersBehavior p_behavior); + void set_visible_characters(int p_amount); int get_visible_characters() const; int get_total_character_count() const; @@ -167,9 +165,8 @@ public: ~Label(); }; -VARIANT_ENUM_CAST(Label::Align); -VARIANT_ENUM_CAST(Label::VAlign); VARIANT_ENUM_CAST(Label::AutowrapMode); VARIANT_ENUM_CAST(Label::OverrunBehavior); +VARIANT_ENUM_CAST(Label::VisibleCharactersBehavior); #endif diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 30a6f0fc9a..f7d6850a88 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -227,7 +227,7 @@ void LineEdit::gui_input(const Ref<InputEvent> &p_event) { } if (b->is_pressed() && b->get_button_index() == MouseButton::RIGHT && context_menu_enabled) { _ensure_menu(); - menu->set_position(get_screen_transform().xform(get_local_mouse_position())); + menu->set_position(get_screen_position() + get_local_mouse_position()); menu->reset_size(); menu->popup(); grab_focus(); @@ -392,7 +392,7 @@ void LineEdit::gui_input(const Ref<InputEvent> &p_event) { 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); - menu->set_position(get_global_transform().xform(pos)); + menu->set_position(get_screen_position() + pos); menu->reset_size(); menu->popup(); menu->grab_focus(); @@ -548,17 +548,17 @@ void LineEdit::gui_input(const Ref<InputEvent> &p_event) { } } -void LineEdit::set_align(Align p_align) { - ERR_FAIL_INDEX((int)p_align, 4); - if (align != p_align) { - align = p_align; +void LineEdit::set_horizontal_alignment(HorizontalAlignment p_alignment) { + ERR_FAIL_INDEX((int)p_alignment, 4); + if (alignment != p_alignment) { + alignment = p_alignment; _shape(); } update(); } -LineEdit::Align LineEdit::get_align() const { - return align; +HorizontalAlignment LineEdit::get_horizontal_alignment() const { + return alignment; } Variant LineEdit::get_drag_data(const Point2 &p_point) { @@ -715,23 +715,23 @@ void LineEdit::_notification(int p_what) { float text_width = TS->shaped_text_get_size(text_rid).x; float text_height = TS->shaped_text_get_size(text_rid).y + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM); - switch (align) { - case ALIGN_FILL: - case ALIGN_LEFT: { + switch (alignment) { + case HORIZONTAL_ALIGNMENT_FILL: + case HORIZONTAL_ALIGNMENT_LEFT: { if (rtl) { x_ofs = MAX(style->get_margin(SIDE_LEFT), int(size.width - style->get_margin(SIDE_RIGHT) - (text_width))); } else { x_ofs = style->get_offset().x; } } break; - case ALIGN_CENTER: { + case HORIZONTAL_ALIGNMENT_CENTER: { if (scroll_offset != 0) { x_ofs = style->get_offset().x; } else { x_ofs = MAX(style->get_margin(SIDE_LEFT), int(size.width - (text_width)) / 2); } } break; - case ALIGN_RIGHT: { + case HORIZONTAL_ALIGNMENT_RIGHT: { if (rtl) { x_ofs = style->get_offset().x; } else { @@ -769,7 +769,7 @@ void LineEdit::_notification(int p_what) { r_icon->draw(ci, Point2(width - r_icon->get_width() - style->get_margin(SIDE_RIGHT), height / 2 - r_icon->get_height() / 2), color_icon); - if (align == ALIGN_CENTER) { + if (alignment == HORIZONTAL_ALIGNMENT_CENTER) { if (scroll_offset == 0) { x_ofs = MAX(style->get_margin(SIDE_LEFT), int(size.width - text_width - r_icon->get_width() - style->get_margin(SIDE_RIGHT) * 2) / 2); } @@ -780,8 +780,6 @@ void LineEdit::_notification(int p_what) { ofs_max -= r_icon->get_width(); } - int caret_width = Math::round(1 * get_theme_default_base_scale()); - // Draw selections rects. Vector2 ofs = Point2(x_ofs + scroll_offset, y_ofs); if (selection.enabled) { @@ -843,6 +841,8 @@ void LineEdit::_notification(int p_what) { // Draw carets. ofs.x = x_ofs + scroll_offset; if (draw_caret || drag_caret_force_displayed) { + const int caret_width = get_theme_constant(SNAME("caret_width")) * get_theme_default_base_scale(); + if (ime_text.length() == 0) { // Normal caret. CaretInfo caret = TS->shaped_text_get_carets(text_rid, caret_column); @@ -1017,7 +1017,7 @@ void LineEdit::paste_text() { // Strip escape characters like \n and \t as they can't be displayed on LineEdit. String paste_buffer = DisplayServer::get_singleton()->clipboard_get().strip_escapes(); - if (paste_buffer != "") { + if (!paste_buffer.is_empty()) { int prev_len = text.length(); if (selection.enabled) { selection_delete(); @@ -1115,23 +1115,23 @@ void LineEdit::set_caret_at_pixel_pos(int p_x) { int x_ofs = 0; float text_width = TS->shaped_text_get_size(text_rid).x; - switch (align) { - case ALIGN_FILL: - case ALIGN_LEFT: { + switch (alignment) { + case HORIZONTAL_ALIGNMENT_FILL: + case HORIZONTAL_ALIGNMENT_LEFT: { if (rtl) { x_ofs = MAX(style->get_margin(SIDE_LEFT), int(get_size().width - style->get_margin(SIDE_RIGHT) - (text_width))); } else { x_ofs = style->get_offset().x; } } break; - case ALIGN_CENTER: { + case HORIZONTAL_ALIGNMENT_CENTER: { if (scroll_offset != 0) { x_ofs = style->get_offset().x; } else { x_ofs = MAX(style->get_margin(SIDE_LEFT), int(get_size().width - (text_width)) / 2); } } break; - case ALIGN_RIGHT: { + case HORIZONTAL_ALIGNMENT_RIGHT: { if (rtl) { x_ofs = style->get_offset().x; } else { @@ -1144,7 +1144,7 @@ void LineEdit::set_caret_at_pixel_pos(int p_x) { 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; - if (align == ALIGN_CENTER) { + if (alignment == HORIZONTAL_ALIGNMENT_CENTER) { if (scroll_offset == 0) { 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); } @@ -1163,23 +1163,23 @@ Vector2i LineEdit::get_caret_pixel_pos() { int x_ofs = 0; float text_width = TS->shaped_text_get_size(text_rid).x; - switch (align) { - case ALIGN_FILL: - case ALIGN_LEFT: { + switch (alignment) { + case HORIZONTAL_ALIGNMENT_FILL: + case HORIZONTAL_ALIGNMENT_LEFT: { if (rtl) { x_ofs = MAX(style->get_margin(SIDE_LEFT), int(get_size().width - style->get_margin(SIDE_RIGHT) - (text_width))); } else { x_ofs = style->get_offset().x; } } break; - case ALIGN_CENTER: { + case HORIZONTAL_ALIGNMENT_CENTER: { if (scroll_offset != 0) { x_ofs = style->get_offset().x; } else { x_ofs = MAX(style->get_margin(SIDE_LEFT), int(get_size().width - (text_width)) / 2); } } break; - case ALIGN_RIGHT: { + case HORIZONTAL_ALIGNMENT_RIGHT: { if (rtl) { x_ofs = style->get_offset().x; } else { @@ -1192,7 +1192,7 @@ Vector2i LineEdit::get_caret_pixel_pos() { 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; - if (align == ALIGN_CENTER) { + if (alignment == HORIZONTAL_ALIGNMENT_CENTER) { if (scroll_offset == 0) { 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); } @@ -1508,23 +1508,23 @@ void LineEdit::set_caret_column(int p_column) { int x_ofs = 0; float text_width = TS->shaped_text_get_size(text_rid).x; - switch (align) { - case ALIGN_FILL: - case ALIGN_LEFT: { + switch (alignment) { + case HORIZONTAL_ALIGNMENT_FILL: + case HORIZONTAL_ALIGNMENT_LEFT: { if (rtl) { x_ofs = MAX(style->get_margin(SIDE_LEFT), int(get_size().width - style->get_margin(SIDE_RIGHT) - (text_width))); } else { x_ofs = style->get_offset().x; } } break; - case ALIGN_CENTER: { + case HORIZONTAL_ALIGNMENT_CENTER: { if (scroll_offset != 0) { x_ofs = style->get_offset().x; } else { x_ofs = MAX(style->get_margin(SIDE_LEFT), int(get_size().width - (text_width)) / 2); } } break; - case ALIGN_RIGHT: { + case HORIZONTAL_ALIGNMENT_RIGHT: { if (rtl) { x_ofs = style->get_offset().x; } else { @@ -1538,7 +1538,7 @@ void LineEdit::set_caret_column(int p_column) { 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; - if (align == ALIGN_CENTER) { + if (alignment == HORIZONTAL_ALIGNMENT_CENTER) { if (scroll_offset == 0) { 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); } @@ -1718,7 +1718,7 @@ void LineEdit::set_editable(bool p_editable) { editable = p_editable; - minimum_size_changed(); + update_minimum_size(); update(); } @@ -1948,7 +1948,7 @@ void LineEdit::_editor_settings_changed() { void LineEdit::set_expand_to_text_length_enabled(bool p_enabled) { expand_to_text_length = p_enabled; - minimum_size_changed(); + update_minimum_size(); set_caret_column(caret_column); } @@ -1962,7 +1962,7 @@ void LineEdit::set_clear_button_enabled(bool p_enabled) { } clear_button_enabled = p_enabled; _fit_to_width(); - minimum_size_changed(); + update_minimum_size(); update(); } @@ -2023,7 +2023,7 @@ void LineEdit::set_right_icon(const Ref<Texture2D> &p_icon) { } right_icon = p_icon; _fit_to_width(); - minimum_size_changed(); + update_minimum_size(); update(); } @@ -2078,7 +2078,7 @@ void LineEdit::_shape() { const Ref<Font> &font = get_theme_font(SNAME("font")); int font_size = get_theme_font_size(SNAME("font_size")); ERR_FAIL_COND(font.is_null()); - TS->shaped_text_add_string(text_rid, t, font->get_rids(), font_size, opentype_features, (language != "") ? language : TranslationServer::get_singleton()->get_tool_locale()); + TS->shaped_text_add_string(text_rid, t, font->get_rids(), font_size, opentype_features, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale()); TS->shaped_text_set_bidi_override(text_rid, structured_text_parser(st_parser, st_args, t)); full_width = TS->shaped_text_get_size(text_rid).x; @@ -2087,12 +2087,12 @@ void LineEdit::_shape() { Size2 size = TS->shaped_text_get_size(text_rid); if ((expand_to_text_length && old_size.x != size.x) || (old_size.y != size.y)) { - minimum_size_changed(); + update_minimum_size(); } } void LineEdit::_fit_to_width() { - if (align == ALIGN_FILL) { + if (alignment == HORIZONTAL_ALIGNMENT_FILL) { Ref<StyleBox> style = get_theme_stylebox(SNAME("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(); @@ -2164,7 +2164,7 @@ bool LineEdit::_set(const StringName &p_name, const Variant &p_value) { if (str.begins_with("opentype_features/")) { String name = str.get_slicec('/', 1); int32_t tag = TS->name_to_tag(name); - double value = p_value; + int value = p_value; if (value == -1) { if (opentype_features.has(tag)) { opentype_features.erase(tag); @@ -2172,7 +2172,7 @@ bool LineEdit::_set(const StringName &p_name, const Variant &p_value) { update(); } } else { - if ((double)opentype_features[tag] != value) { + if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) { opentype_features[tag] = value; _shape(); update(); @@ -2204,7 +2204,7 @@ bool LineEdit::_get(const StringName &p_name, Variant &r_ret) const { void LineEdit::_get_property_list(List<PropertyInfo> *p_list) const { for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) { String name = TS->tag_to_name(*ftr); - p_list->push_back(PropertyInfo(Variant::FLOAT, "opentype_features/" + name)); + p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name)); } p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR)); } @@ -2218,8 +2218,8 @@ void LineEdit::_validate_property(PropertyInfo &property) const { void LineEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("_text_changed"), &LineEdit::_text_changed); - ClassDB::bind_method(D_METHOD("set_align", "align"), &LineEdit::set_align); - ClassDB::bind_method(D_METHOD("get_align"), &LineEdit::get_align); + ClassDB::bind_method(D_METHOD("set_horizontal_alignment", "alignment"), &LineEdit::set_horizontal_alignment); + ClassDB::bind_method(D_METHOD("get_horizontal_alignment"), &LineEdit::get_horizontal_alignment); ClassDB::bind_method(D_METHOD("clear"), &LineEdit::clear); ClassDB::bind_method(D_METHOD("select", "from", "to"), &LineEdit::select, DEFVAL(0), DEFVAL(-1)); @@ -2297,11 +2297,6 @@ void LineEdit::_bind_methods() { ADD_SIGNAL(MethodInfo("text_change_rejected", PropertyInfo(Variant::STRING, "rejected_substring"))); ADD_SIGNAL(MethodInfo("text_submitted", PropertyInfo(Variant::STRING, "new_text"))); - BIND_ENUM_CONSTANT(ALIGN_LEFT); - BIND_ENUM_CONSTANT(ALIGN_CENTER); - BIND_ENUM_CONSTANT(ALIGN_RIGHT); - BIND_ENUM_CONSTANT(ALIGN_FILL); - BIND_ENUM_CONSTANT(MENU_CUT); BIND_ENUM_CONSTANT(MENU_COPY); BIND_ENUM_CONSTANT(MENU_PASTE); @@ -2333,7 +2328,7 @@ void LineEdit::_bind_methods() { BIND_ENUM_CONSTANT(MENU_MAX); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text"), "set_text", "get_text"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_align", "get_align"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "alignment", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_horizontal_alignment", "get_horizontal_alignment"); ADD_PROPERTY(PropertyInfo(Variant::INT, "max_length", PROPERTY_HINT_RANGE, "0,1000,1,or_greater"), "set_max_length", "get_max_length"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editable"), "set_editable", "is_editable"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "secret"), "set_secret", "is_secret"); diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h index 221dd9eb2e..0c313f71c2 100644 --- a/scene/gui/line_edit.h +++ b/scene/gui/line_edit.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -38,13 +38,6 @@ class LineEdit : public Control { GDCLASS(LineEdit, Control); public: - enum Align { - ALIGN_LEFT, - ALIGN_CENTER, - ALIGN_RIGHT, - ALIGN_FILL - }; - enum MenuItems { MENU_CUT, MENU_COPY, @@ -78,7 +71,7 @@ public: }; private: - Align align = ALIGN_LEFT; + HorizontalAlignment alignment = HORIZONTAL_ALIGNMENT_LEFT; bool editable = false; bool pass = false; @@ -104,7 +97,7 @@ private: PopupMenu *menu_dir = nullptr; PopupMenu *menu_ctl = nullptr; - bool caret_mid_grapheme_enabled = false; + bool caret_mid_grapheme_enabled = true; int caret_column = 0; int scroll_offset = 0; @@ -218,8 +211,8 @@ protected: void _validate_property(PropertyInfo &property) const override; public: - void set_align(Align p_align); - Align get_align() const; + void set_horizontal_alignment(HorizontalAlignment p_alignment); + HorizontalAlignment get_horizontal_alignment() const; virtual Variant get_drag_data(const Point2 &p_point) override; virtual bool can_drop_data(const Point2 &p_point, const Variant &p_data) const override; @@ -347,7 +340,6 @@ public: ~LineEdit(); }; -VARIANT_ENUM_CAST(LineEdit::Align); VARIANT_ENUM_CAST(LineEdit::MenuItems); #endif diff --git a/scene/gui/link_button.cpp b/scene/gui/link_button.cpp index c3201186ea..67ffa2c7ed 100644 --- a/scene/gui/link_button.cpp +++ b/scene/gui/link_button.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -42,7 +42,7 @@ void LinkButton::_shape() { text_buf->set_direction((TextServer::Direction)text_direction); } TS->shaped_text_set_bidi_override(text_buf->get_rid(), structured_text_parser(st_parser, st_args, xl_text)); - text_buf->add_string(xl_text, font, font_size, opentype_features, (language != "") ? language : TranslationServer::get_singleton()->get_tool_locale()); + text_buf->add_string(xl_text, font, font_size, opentype_features, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale()); } void LinkButton::set_text(const String &p_text) { @@ -52,7 +52,7 @@ void LinkButton::set_text(const String &p_text) { text = p_text; xl_text = atr(text); _shape(); - minimum_size_changed(); + update_minimum_size(); update(); } @@ -149,7 +149,7 @@ void LinkButton::_notification(int p_what) { xl_text = atr(text); _shape(); - minimum_size_changed(); + update_minimum_size(); update(); } break; case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: { @@ -157,7 +157,7 @@ void LinkButton::_notification(int p_what) { } break; case NOTIFICATION_THEME_CHANGED: { _shape(); - minimum_size_changed(); + update_minimum_size(); update(); } break; case NOTIFICATION_DRAW: { @@ -240,7 +240,7 @@ bool LinkButton::_set(const StringName &p_name, const Variant &p_value) { if (str.begins_with("opentype_features/")) { String name = str.get_slicec('/', 1); int32_t tag = TS->name_to_tag(name); - double value = p_value; + int value = p_value; if (value == -1) { if (opentype_features.has(tag)) { opentype_features.erase(tag); @@ -248,7 +248,7 @@ bool LinkButton::_set(const StringName &p_name, const Variant &p_value) { update(); } } else { - if ((double)opentype_features[tag] != value) { + if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) { opentype_features[tag] = value; _shape(); update(); @@ -280,7 +280,7 @@ bool LinkButton::_get(const StringName &p_name, Variant &r_ret) const { void LinkButton::_get_property_list(List<PropertyInfo> *p_list) const { for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) { String name = TS->tag_to_name(*ftr); - p_list->push_back(PropertyInfo(Variant::FLOAT, "opentype_features/" + name)); + p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name)); } p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR)); } diff --git a/scene/gui/link_button.h b/scene/gui/link_button.h index 231543c63c..7d302e967d 100644 --- a/scene/gui/link_button.h +++ b/scene/gui/link_button.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/margin_container.cpp b/scene/gui/margin_container.cpp index 50b4d192a9..7b696ddb84 100644 --- a/scene/gui/margin_container.cpp +++ b/scene/gui/margin_container.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -90,7 +90,7 @@ void MarginContainer::_notification(int p_what) { } } break; case NOTIFICATION_THEME_CHANGED: { - minimum_size_changed(); + update_minimum_size(); } break; } } diff --git a/scene/gui/margin_container.h b/scene/gui/margin_container.h index b782976ada..3a2f0fa8b3 100644 --- a/scene/gui/margin_container.h +++ b/scene/gui/margin_container.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index 39c7b04955..f7805136f9 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -184,7 +184,7 @@ void MenuButton::_get_property_list(List<PropertyInfo> *p_list) const { pi.usage &= ~(!popup->is_item_checked(i) ? PROPERTY_USAGE_STORAGE : 0); p_list->push_back(pi); - pi = PropertyInfo(Variant::INT, vformat("popup/item_%d/id", i), PROPERTY_HINT_RANGE, "1,10,1,or_greater"); + pi = PropertyInfo(Variant::INT, vformat("popup/item_%d/id", i), PROPERTY_HINT_RANGE, "0,10,1,or_greater"); p_list->push_back(pi); pi = PropertyInfo(Variant::BOOL, vformat("popup/item_%d/disabled", i)); @@ -207,7 +207,7 @@ void MenuButton::_bind_methods() { ClassDB::bind_method(D_METHOD("get_item_count"), &MenuButton::get_item_count); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "switch_on_hover"), "set_switch_on_hover", "is_switch_on_hover"); - ADD_ARRAY_COUNT("Items", "items_count", "set_item_count", "get_item_count", "popup/item_"); + ADD_ARRAY_COUNT("Items", "item_count", "set_item_count", "get_item_count", "popup/item_"); ADD_SIGNAL(MethodInfo("about_to_popup")); } diff --git a/scene/gui/menu_button.h b/scene/gui/menu_button.h index 455b7dc870..3647a69d33 100644 --- a/scene/gui/menu_button.h +++ b/scene/gui/menu_button.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/nine_patch_rect.cpp b/scene/gui/nine_patch_rect.cpp index 8bf25ac915..779d1307f5 100644 --- a/scene/gui/nine_patch_rect.cpp +++ b/scene/gui/nine_patch_rect.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -97,7 +97,7 @@ void NinePatchRect::set_texture(const Ref<Texture2D> &p_tex) { if (texture.is_valid()) texture->set_flags(texture->get_flags()&(~Texture::FLAG_REPEAT)); //remove repeat from texture, it looks bad in sprites */ - minimum_size_changed(); + update_minimum_size(); emit_signal(SceneStringNames::get_singleton()->texture_changed); } @@ -109,7 +109,7 @@ void NinePatchRect::set_patch_margin(Side p_side, int p_size) { ERR_FAIL_INDEX((int)p_side, 4); margin[p_side] = p_size; update(); - minimum_size_changed(); + update_minimum_size(); } int NinePatchRect::get_patch_margin(Side p_side) const { diff --git a/scene/gui/nine_patch_rect.h b/scene/gui/nine_patch_rect.h index f9a3f31fe5..23aebbb782 100644 --- a/scene/gui/nine_patch_rect.h +++ b/scene/gui/nine_patch_rect.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index dcf3cfeb09..90bb316448 100644 --- a/scene/gui/option_button.cpp +++ b/scene/gui/option_button.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -110,6 +110,63 @@ void OptionButton::_notification(int p_what) { } } +bool OptionButton::_set(const StringName &p_name, const Variant &p_value) { + Vector<String> components = String(p_name).split("/", true, 2); + if (components.size() >= 2 && components[0] == "popup") { + bool valid; + popup->set(String(p_name).trim_prefix("popup/"), p_value, &valid); + + int idx = components[1].get_slice("_", 1).to_int(); + if (idx == current) { + // Force refreshing currently displayed item. + current = -1; + _select(idx, false); + } + + return valid; + } + return false; +} + +bool OptionButton::_get(const StringName &p_name, Variant &r_ret) const { + Vector<String> components = String(p_name).split("/", true, 2); + if (components.size() >= 2 && components[0] == "popup") { + bool valid; + r_ret = popup->get(String(p_name).trim_prefix("popup/"), &valid); + return valid; + } + return false; +} + +void OptionButton::_get_property_list(List<PropertyInfo> *p_list) const { + for (int i = 0; i < popup->get_item_count(); i++) { + p_list->push_back(PropertyInfo(Variant::STRING, vformat("popup/item_%d/text", i))); + + PropertyInfo pi = PropertyInfo(Variant::OBJECT, vformat("popup/item_%d/icon", i), PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"); + pi.usage &= ~(popup->get_item_icon(i).is_null() ? PROPERTY_USAGE_STORAGE : 0); + p_list->push_back(pi); + + pi = PropertyInfo(Variant::INT, vformat("popup/item_%d/checkable", i), PROPERTY_HINT_ENUM, "No,As checkbox,As radio button"); + pi.usage &= ~(!popup->is_item_checkable(i) ? PROPERTY_USAGE_STORAGE : 0); + p_list->push_back(pi); + + pi = PropertyInfo(Variant::BOOL, vformat("popup/item_%d/checked", i)); + pi.usage &= ~(!popup->is_item_checked(i) ? PROPERTY_USAGE_STORAGE : 0); + p_list->push_back(pi); + + pi = PropertyInfo(Variant::INT, vformat("popup/item_%d/id", i), PROPERTY_HINT_RANGE, "1,10,1,or_greater"); + p_list->push_back(pi); + + pi = PropertyInfo(Variant::BOOL, vformat("popup/item_%d/disabled", i)); + pi.usage &= ~(!popup->is_item_disabled(i) ? PROPERTY_USAGE_STORAGE : 0); + p_list->push_back(pi); + + pi = PropertyInfo(Variant::BOOL, vformat("popup/item_%d/separator", i)); + pi.usage &= ~(!popup->is_item_separator(i) ? PROPERTY_USAGE_STORAGE : 0); + p_list->push_back(pi); + } +} + void OptionButton::_focused(int p_which) { emit_signal(SNAME("item_focused"), p_which); } @@ -122,6 +179,7 @@ void OptionButton::pressed() { Size2 size = get_size() * get_viewport()->get_canvas_transform().get_scale(); popup->set_position(get_screen_position() + Size2(0, size.height * get_global_transform().get_scale().y)); popup->set_size(Size2(size.width, 0)); + popup->set_current_index(current); popup->popup(); } @@ -191,6 +249,12 @@ bool OptionButton::is_item_disabled(int p_idx) const { return popup->is_item_disabled(p_idx); } +void OptionButton::set_item_count(int p_count) { + ERR_FAIL_COND(p_count < 0); + popup->set_item_count(p_count); + notify_property_list_changed(); +} + int OptionButton::get_item_count() const { return popup->get_item_count(); } @@ -267,38 +331,6 @@ PopupMenu *OptionButton::get_popup() const { return popup; } -Array OptionButton::_get_items() const { - Array items; - for (int i = 0; i < get_item_count(); i++) { - items.push_back(get_item_text(i)); - items.push_back(get_item_icon(i)); - items.push_back(is_item_disabled(i)); - items.push_back(get_item_id(i)); - items.push_back(get_item_metadata(i)); - } - - return items; -} - -void OptionButton::_set_items(const Array &p_items) { - ERR_FAIL_COND(p_items.size() % 5); - clear(); - - for (int i = 0; i < p_items.size(); i += 5) { - String text = p_items[i + 0]; - Ref<Texture2D> icon = p_items[i + 1]; - bool disabled = p_items[i + 2]; - int id = p_items[i + 3]; - Variant meta = p_items[i + 4]; - - int idx = get_item_count(); - add_item(text, id); - set_item_icon(idx, icon); - set_item_disabled(idx, disabled); - set_item_metadata(idx, meta); - } -} - void OptionButton::get_translatable_strings(List<String> *p_strings) const { popup->get_translatable_strings(p_strings); } @@ -317,7 +349,6 @@ void OptionButton::_bind_methods() { ClassDB::bind_method(D_METHOD("get_item_index", "id"), &OptionButton::get_item_index); ClassDB::bind_method(D_METHOD("get_item_metadata", "idx"), &OptionButton::get_item_metadata); ClassDB::bind_method(D_METHOD("is_item_disabled", "idx"), &OptionButton::is_item_disabled); - ClassDB::bind_method(D_METHOD("get_item_count"), &OptionButton::get_item_count); ClassDB::bind_method(D_METHOD("add_separator"), &OptionButton::add_separator); ClassDB::bind_method(D_METHOD("clear"), &OptionButton::clear); ClassDB::bind_method(D_METHOD("select", "idx"), &OptionButton::select); @@ -329,11 +360,11 @@ void OptionButton::_bind_methods() { ClassDB::bind_method(D_METHOD("get_popup"), &OptionButton::get_popup); - ClassDB::bind_method(D_METHOD("_set_items"), &OptionButton::_set_items); - ClassDB::bind_method(D_METHOD("_get_items"), &OptionButton::_get_items); + ClassDB::bind_method(D_METHOD("set_item_count", "count"), &OptionButton::set_item_count); + ClassDB::bind_method(D_METHOD("get_item_count"), &OptionButton::get_item_count); - ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "items", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_items", "_get_items"); - // "selected" property must come after "items", otherwise GH-10213 occurs. + // "selected" property must come after "item_count", otherwise GH-10213 occurs. + ADD_ARRAY_COUNT("Items", "item_count", "set_item_count", "get_item_count", "popup/item_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "selected"), "_select_int", "get_selected"); ADD_SIGNAL(MethodInfo("item_selected", PropertyInfo(Variant::INT, "index"))); ADD_SIGNAL(MethodInfo("item_focused", PropertyInfo(Variant::INT, "index"))); @@ -341,7 +372,7 @@ void OptionButton::_bind_methods() { OptionButton::OptionButton() { set_toggle_mode(true); - set_text_align(ALIGN_LEFT); + 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()); diff --git a/scene/gui/option_button.h b/scene/gui/option_button.h index 953337ecce..adf2bb90ef 100644 --- a/scene/gui/option_button.h +++ b/scene/gui/option_button.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -45,14 +45,14 @@ class OptionButton : public Button { void _select(int p_which, bool p_emit = false); void _select_int(int p_which); - Array _get_items() const; - void _set_items(const Array &p_items); - virtual void pressed() override; protected: Size2 get_minimum_size() const 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; + void _get_property_list(List<PropertyInfo> *p_list) const; static void _bind_methods(); public: @@ -76,6 +76,7 @@ public: Variant get_item_metadata(int p_idx) const; bool is_item_disabled(int p_idx) const; + void set_item_count(int p_count); int get_item_count() const; void add_separator(); diff --git a/scene/gui/panel.cpp b/scene/gui/panel.cpp index e8e7e3d997..86858fdc78 100644 --- a/scene/gui/panel.cpp +++ b/scene/gui/panel.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/panel.h b/scene/gui/panel.h index 84fd6aaead..37f14c250c 100644 --- a/scene/gui/panel.h +++ b/scene/gui/panel.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/panel_container.cpp b/scene/gui/panel_container.cpp index d910e1e882..463ad3c513 100644 --- a/scene/gui/panel_container.cpp +++ b/scene/gui/panel_container.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/panel_container.h b/scene/gui/panel_container.h index f27ca7fad7..a5ff74cebb 100644 --- a/scene/gui/panel_container.h +++ b/scene/gui/panel_container.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp index a48ad0f770..7c03fcbb37 100644 --- a/scene/gui/popup.cpp +++ b/scene/gui/popup.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/popup.h b/scene/gui/popup.h index 8458a75eef..5678043b23 100644 --- a/scene/gui/popup.h +++ b/scene/gui/popup.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 2e854abb76..d7139d0140 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -50,7 +50,7 @@ Size2 PopupMenu::_get_contents_minimum_size() const { int hseparation = get_theme_constant(SNAME("hseparation")); Size2 minsize = get_theme_stylebox(SNAME("panel"))->get_minimum_size(); // Accounts for margin in the margin container - minsize.x += scroll_container->get_v_scrollbar()->get_size().width * 2; // Adds a buffer so that the scrollbar does not render over the top of content + 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; @@ -80,7 +80,7 @@ Size2 PopupMenu::_get_contents_minimum_size() const { accel_max_w = MAX(accel_w, accel_max_w); } - if (items[i].submenu != "") { + if (!items[i].submenu.is_empty()) { size.width += get_theme_icon(SNAME("submenu"))->get_width(); } @@ -216,7 +216,7 @@ void PopupMenu::_activate_submenu(int p_over) { submenu_pos.x = this_pos.x + submenu_size.width; } - if (submenu_pos.x + submenu_size.width > get_parent_rect().size.width) { + if (submenu_pos.x + submenu_size.width > get_parent_rect().position.x + get_parent_rect().size.width) { submenu_pos.x = this_pos.x - submenu_size.width; } @@ -326,13 +326,13 @@ void PopupMenu::gui_input(const Ref<InputEvent> &p_event) { set_input_as_handled(); } } else if (p_event->is_action("ui_right") && p_event->is_pressed()) { - if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator && items[mouse_over].submenu != "" && submenu_over != mouse_over) { + if (mouse_over >= 0 && mouse_over < items.size() && !!items[mouse_over].separator && items[mouse_over].submenu.is_empty() && submenu_over != mouse_over) { _activate_submenu(mouse_over); set_input_as_handled(); } } else if (p_event->is_action("ui_accept") && p_event->is_pressed()) { if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator) { - if (items[mouse_over].submenu != "" && submenu_over != mouse_over) { + if (!items[mouse_over].submenu.is_empty() && submenu_over != mouse_over) { _activate_submenu(mouse_over); } else { activate_item(mouse_over); @@ -343,11 +343,11 @@ void PopupMenu::gui_input(const Ref<InputEvent> &p_event) { // Make an area which does not include v scrollbar, so that items are not activated when dragging scrollbar. Rect2 item_clickable_area = scroll_container->get_rect(); - if (scroll_container->get_v_scrollbar()->is_visible_in_tree()) { + if (scroll_container->get_v_scroll_bar()->is_visible_in_tree()) { if (is_layout_rtl()) { - item_clickable_area.position.x += scroll_container->get_v_scrollbar()->get_size().width; + item_clickable_area.position.x += scroll_container->get_v_scroll_bar()->get_size().width; } else { - item_clickable_area.size.width -= scroll_container->get_v_scrollbar()->get_size().width; + item_clickable_area.size.width -= scroll_container->get_v_scroll_bar()->get_size().width; } } @@ -371,7 +371,7 @@ void PopupMenu::gui_input(const Ref<InputEvent> &p_event) { // Disable clicks under a time threshold to avoid selection right when opening the popup. uint64_t now = OS::get_singleton()->get_ticks_msec(); uint64_t diff = now - popup_time_msec; - if (diff < 100) { + if (diff < 150) { return; } @@ -387,7 +387,7 @@ void PopupMenu::gui_input(const Ref<InputEvent> &p_event) { return; } - if (items[over].submenu != "") { + if (!items[over].submenu.is_empty()) { _activate_submenu(over); return; } @@ -419,7 +419,7 @@ void PopupMenu::gui_input(const Ref<InputEvent> &p_event) { return; } - if (items[over].submenu != "" && submenu_over != over) { + if (!items[over].submenu.is_empty() && submenu_over != over) { submenu_over = over; submenu_timer->start(); } @@ -508,7 +508,7 @@ void PopupMenu::_draw_items() { 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_scrollbar()->is_visible_in_tree() ? scroll_container->get_v_scrollbar()->get_size().width : 0; + 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; // Find the widest icon and whether any items have a checkbox, and store the offsets for each. @@ -558,7 +558,7 @@ void PopupMenu::_draw_items() { if (items[i].separator) { int sep_h = separator->get_center_size().height + separator->get_minimum_size().height; int sep_ofs = Math::floor((h - sep_h) / 2.0); - if (text != String()) { + if (!text.is_empty()) { int text_size = items[i].text_buf->get_size().width; int text_center = display_width / 2; int text_left = text_center - text_size / 2; @@ -599,7 +599,7 @@ void PopupMenu::_draw_items() { } // Submenu arrow on right hand side - if (items[i].submenu != "") { + 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); } else { @@ -611,7 +611,7 @@ void PopupMenu::_draw_items() { Color font_outline_color = get_theme_color(SNAME("font_outline_color")); int outline_size = get_theme_constant(SNAME("outline_size")); if (items[i].separator) { - if (text != String()) { + if (!text.is_empty()) { int center = (display_width - items[i].text_buf->get_size().width) / 2; Vector2 text_pos = Point2(center, item_ofs.y + Math::floor((h - items[i].text_buf->get_size().y) / 2.0)); if (outline_size > 0 && font_outline_color.a > 0) { @@ -701,7 +701,7 @@ void PopupMenu::_shape_item(int p_item) { } else { items.write[p_item].text_buf->set_direction((TextServer::Direction)items[p_item].text_direction); } - items.write[p_item].text_buf->add_string(items.write[p_item].xl_text, font, font_size, items[p_item].opentype_features, (items[p_item].language != "") ? items[p_item].language : TranslationServer::get_singleton()->get_tool_locale()); + items.write[p_item].text_buf->add_string(items.write[p_item].xl_text, font, font_size, items[p_item].opentype_features, !items[p_item].language.is_empty() ? items[p_item].language : TranslationServer::get_singleton()->get_tool_locale()); items.write[p_item].accel_text_buf->clear(); items.write[p_item].accel_text_buf->set_direction(is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR); @@ -736,7 +736,7 @@ void PopupMenu::_notification(int p_what) { grab_focus(); } break; case NOTIFICATION_WM_MOUSE_EXIT: { - if (mouse_over >= 0 && (items[mouse_over].submenu == "" || submenu_over != -1)) { + if (mouse_over >= 0 && (items[mouse_over].submenu.is_empty() || submenu_over != -1)) { mouse_over = -1; control->update(); } @@ -769,7 +769,7 @@ void PopupMenu::_notification(int p_what) { } for (int i = 0; i < items.size(); i++) { - if (items[i].submenu == "") { + if (items[i].submenu.is_empty()) { continue; } @@ -1269,13 +1269,28 @@ bool PopupMenu::is_item_shortcut_disabled(int p_idx) const { return items[p_idx].shortcut_is_disabled; } +void PopupMenu::set_current_index(int p_idx) { + ERR_FAIL_INDEX(p_idx, items.size()); + mouse_over = p_idx; + _scroll_to_item(mouse_over); + control->update(); +} + int PopupMenu::get_current_index() const { return mouse_over; } void PopupMenu::set_item_count(int p_count) { ERR_FAIL_COND(p_count < 0); + int prev_size = items.size(); items.resize(p_count); + + if (prev_size < p_count) { + for (int i = prev_size; i < p_count; i++) { + items.write[i].id = i; + } + } + control->update(); child_controls_changed(); notify_property_list_changed(); @@ -1323,7 +1338,7 @@ bool PopupMenu::activate_item_by_event(const Ref<InputEvent> &p_event, bool p_fo return true; } - if (items[i].submenu != "") { + if (!items[i].submenu.is_empty()) { Node *n = get_node(items[i].submenu); if (!n) { continue; @@ -1412,7 +1427,7 @@ void PopupMenu::add_separator(const String &p_text, int p_id) { Item sep; sep.separator = true; sep.id = p_id; - if (p_text != String()) { + if (!p_text.is_empty()) { sep.text = p_text; sep.xl_text = atr(p_text); } @@ -1510,7 +1525,7 @@ void PopupMenu::set_parent_rect(const Rect2 &p_rect) { void PopupMenu::get_translatable_strings(List<String> *p_strings) const { for (int i = 0; i < items.size(); i++) { - if (items[i].xl_text != "") { + if (!items[i].xl_text.is_empty()) { p_strings->push_back(items[i].xl_text); } } @@ -1658,7 +1673,7 @@ void PopupMenu::_get_property_list(List<PropertyInfo> *p_list) const { pi.usage &= ~(!is_item_checked(i) ? PROPERTY_USAGE_STORAGE : 0); p_list->push_back(pi); - pi = PropertyInfo(Variant::INT, vformat("item_%d/id", i), PROPERTY_HINT_RANGE, "1,10,1,or_greater"); + pi = PropertyInfo(Variant::INT, vformat("item_%d/id", i), PROPERTY_HINT_RANGE, "0,10,1,or_greater"); p_list->push_back(pi); pi = PropertyInfo(Variant::BOOL, vformat("item_%d/disabled", i)); @@ -1690,53 +1705,53 @@ void PopupMenu::_bind_methods() { ClassDB::bind_method(D_METHOD("add_submenu_item", "label", "submenu", "id"), &PopupMenu::add_submenu_item, DEFVAL(-1)); - ClassDB::bind_method(D_METHOD("set_item_text", "idx", "text"), &PopupMenu::set_item_text); - ClassDB::bind_method(D_METHOD("set_item_text_direction", "idx", "direction"), &PopupMenu::set_item_text_direction); - ClassDB::bind_method(D_METHOD("set_item_opentype_feature", "idx", "tag", "value"), &PopupMenu::set_item_opentype_feature); - ClassDB::bind_method(D_METHOD("set_item_language", "idx", "language"), &PopupMenu::set_item_language); - ClassDB::bind_method(D_METHOD("set_item_icon", "idx", "icon"), &PopupMenu::set_item_icon); - ClassDB::bind_method(D_METHOD("set_item_checked", "idx", "checked"), &PopupMenu::set_item_checked); - ClassDB::bind_method(D_METHOD("set_item_id", "idx", "id"), &PopupMenu::set_item_id); - ClassDB::bind_method(D_METHOD("set_item_accelerator", "idx", "accel"), &PopupMenu::set_item_accelerator); - ClassDB::bind_method(D_METHOD("set_item_metadata", "idx", "metadata"), &PopupMenu::set_item_metadata); - ClassDB::bind_method(D_METHOD("set_item_disabled", "idx", "disabled"), &PopupMenu::set_item_disabled); - ClassDB::bind_method(D_METHOD("set_item_submenu", "idx", "submenu"), &PopupMenu::set_item_submenu); - ClassDB::bind_method(D_METHOD("set_item_as_separator", "idx", "enable"), &PopupMenu::set_item_as_separator); - ClassDB::bind_method(D_METHOD("set_item_as_checkable", "idx", "enable"), &PopupMenu::set_item_as_checkable); - ClassDB::bind_method(D_METHOD("set_item_as_radio_checkable", "idx", "enable"), &PopupMenu::set_item_as_radio_checkable); - ClassDB::bind_method(D_METHOD("set_item_tooltip", "idx", "tooltip"), &PopupMenu::set_item_tooltip); - ClassDB::bind_method(D_METHOD("set_item_shortcut", "idx", "shortcut", "global"), &PopupMenu::set_item_shortcut, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("set_item_multistate", "idx", "state"), &PopupMenu::set_item_multistate); - ClassDB::bind_method(D_METHOD("set_item_shortcut_disabled", "idx", "disabled"), &PopupMenu::set_item_shortcut_disabled); - - ClassDB::bind_method(D_METHOD("toggle_item_checked", "idx"), &PopupMenu::toggle_item_checked); - ClassDB::bind_method(D_METHOD("toggle_item_multistate", "idx"), &PopupMenu::toggle_item_multistate); - - ClassDB::bind_method(D_METHOD("get_item_text", "idx"), &PopupMenu::get_item_text); - ClassDB::bind_method(D_METHOD("get_item_text_direction", "idx"), &PopupMenu::get_item_text_direction); - ClassDB::bind_method(D_METHOD("get_item_opentype_feature", "idx", "tag"), &PopupMenu::get_item_opentype_feature); - ClassDB::bind_method(D_METHOD("clear_item_opentype_features", "idx"), &PopupMenu::clear_item_opentype_features); - ClassDB::bind_method(D_METHOD("get_item_language", "idx"), &PopupMenu::get_item_language); - ClassDB::bind_method(D_METHOD("get_item_icon", "idx"), &PopupMenu::get_item_icon); - ClassDB::bind_method(D_METHOD("is_item_checked", "idx"), &PopupMenu::is_item_checked); - ClassDB::bind_method(D_METHOD("get_item_id", "idx"), &PopupMenu::get_item_id); + ClassDB::bind_method(D_METHOD("set_item_text", "index", "text"), &PopupMenu::set_item_text); + ClassDB::bind_method(D_METHOD("set_item_text_direction", "index", "direction"), &PopupMenu::set_item_text_direction); + ClassDB::bind_method(D_METHOD("set_item_opentype_feature", "index", "tag", "value"), &PopupMenu::set_item_opentype_feature); + ClassDB::bind_method(D_METHOD("set_item_language", "index", "language"), &PopupMenu::set_item_language); + ClassDB::bind_method(D_METHOD("set_item_icon", "index", "icon"), &PopupMenu::set_item_icon); + ClassDB::bind_method(D_METHOD("set_item_checked", "index", "checked"), &PopupMenu::set_item_checked); + ClassDB::bind_method(D_METHOD("set_item_id", "index", "id"), &PopupMenu::set_item_id); + ClassDB::bind_method(D_METHOD("set_item_accelerator", "index", "accel"), &PopupMenu::set_item_accelerator); + ClassDB::bind_method(D_METHOD("set_item_metadata", "index", "metadata"), &PopupMenu::set_item_metadata); + ClassDB::bind_method(D_METHOD("set_item_disabled", "index", "disabled"), &PopupMenu::set_item_disabled); + ClassDB::bind_method(D_METHOD("set_item_submenu", "index", "submenu"), &PopupMenu::set_item_submenu); + ClassDB::bind_method(D_METHOD("set_item_as_separator", "index", "enable"), &PopupMenu::set_item_as_separator); + ClassDB::bind_method(D_METHOD("set_item_as_checkable", "index", "enable"), &PopupMenu::set_item_as_checkable); + ClassDB::bind_method(D_METHOD("set_item_as_radio_checkable", "index", "enable"), &PopupMenu::set_item_as_radio_checkable); + ClassDB::bind_method(D_METHOD("set_item_tooltip", "index", "tooltip"), &PopupMenu::set_item_tooltip); + ClassDB::bind_method(D_METHOD("set_item_shortcut", "index", "shortcut", "global"), &PopupMenu::set_item_shortcut, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("set_item_multistate", "index", "state"), &PopupMenu::set_item_multistate); + ClassDB::bind_method(D_METHOD("set_item_shortcut_disabled", "index", "disabled"), &PopupMenu::set_item_shortcut_disabled); + + ClassDB::bind_method(D_METHOD("toggle_item_checked", "index"), &PopupMenu::toggle_item_checked); + ClassDB::bind_method(D_METHOD("toggle_item_multistate", "index"), &PopupMenu::toggle_item_multistate); + + ClassDB::bind_method(D_METHOD("get_item_text", "index"), &PopupMenu::get_item_text); + ClassDB::bind_method(D_METHOD("get_item_text_direction", "index"), &PopupMenu::get_item_text_direction); + ClassDB::bind_method(D_METHOD("get_item_opentype_feature", "index", "tag"), &PopupMenu::get_item_opentype_feature); + ClassDB::bind_method(D_METHOD("clear_item_opentype_features", "index"), &PopupMenu::clear_item_opentype_features); + ClassDB::bind_method(D_METHOD("get_item_language", "index"), &PopupMenu::get_item_language); + ClassDB::bind_method(D_METHOD("get_item_icon", "index"), &PopupMenu::get_item_icon); + ClassDB::bind_method(D_METHOD("is_item_checked", "index"), &PopupMenu::is_item_checked); + ClassDB::bind_method(D_METHOD("get_item_id", "index"), &PopupMenu::get_item_id); ClassDB::bind_method(D_METHOD("get_item_index", "id"), &PopupMenu::get_item_index); - ClassDB::bind_method(D_METHOD("get_item_accelerator", "idx"), &PopupMenu::get_item_accelerator); - ClassDB::bind_method(D_METHOD("get_item_metadata", "idx"), &PopupMenu::get_item_metadata); - ClassDB::bind_method(D_METHOD("is_item_disabled", "idx"), &PopupMenu::is_item_disabled); - ClassDB::bind_method(D_METHOD("get_item_submenu", "idx"), &PopupMenu::get_item_submenu); - ClassDB::bind_method(D_METHOD("is_item_separator", "idx"), &PopupMenu::is_item_separator); - ClassDB::bind_method(D_METHOD("is_item_checkable", "idx"), &PopupMenu::is_item_checkable); - ClassDB::bind_method(D_METHOD("is_item_radio_checkable", "idx"), &PopupMenu::is_item_radio_checkable); - ClassDB::bind_method(D_METHOD("is_item_shortcut_disabled", "idx"), &PopupMenu::is_item_shortcut_disabled); - ClassDB::bind_method(D_METHOD("get_item_tooltip", "idx"), &PopupMenu::get_item_tooltip); - ClassDB::bind_method(D_METHOD("get_item_shortcut", "idx"), &PopupMenu::get_item_shortcut); + ClassDB::bind_method(D_METHOD("get_item_accelerator", "index"), &PopupMenu::get_item_accelerator); + ClassDB::bind_method(D_METHOD("get_item_metadata", "index"), &PopupMenu::get_item_metadata); + ClassDB::bind_method(D_METHOD("is_item_disabled", "index"), &PopupMenu::is_item_disabled); + ClassDB::bind_method(D_METHOD("get_item_submenu", "index"), &PopupMenu::get_item_submenu); + ClassDB::bind_method(D_METHOD("is_item_separator", "index"), &PopupMenu::is_item_separator); + ClassDB::bind_method(D_METHOD("is_item_checkable", "index"), &PopupMenu::is_item_checkable); + ClassDB::bind_method(D_METHOD("is_item_radio_checkable", "index"), &PopupMenu::is_item_radio_checkable); + ClassDB::bind_method(D_METHOD("is_item_shortcut_disabled", "index"), &PopupMenu::is_item_shortcut_disabled); + ClassDB::bind_method(D_METHOD("get_item_tooltip", "index"), &PopupMenu::get_item_tooltip); + ClassDB::bind_method(D_METHOD("get_item_shortcut", "index"), &PopupMenu::get_item_shortcut); ClassDB::bind_method(D_METHOD("get_current_index"), &PopupMenu::get_current_index); ClassDB::bind_method(D_METHOD("set_item_count", "count"), &PopupMenu::set_item_count); ClassDB::bind_method(D_METHOD("get_item_count"), &PopupMenu::get_item_count); - ClassDB::bind_method(D_METHOD("remove_item", "idx"), &PopupMenu::remove_item); + ClassDB::bind_method(D_METHOD("remove_item", "index"), &PopupMenu::remove_item); ClassDB::bind_method(D_METHOD("add_separator", "label", "id"), &PopupMenu::add_separator, DEFVAL(String()), DEFVAL(-1)); ClassDB::bind_method(D_METHOD("clear"), &PopupMenu::clear); @@ -1762,7 +1777,7 @@ void PopupMenu::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "submenu_popup_delay"), "set_submenu_popup_delay", "get_submenu_popup_delay"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_search"), "set_allow_search", "get_allow_search"); - ADD_ARRAY_COUNT("Items", "items_count", "set_item_count", "get_item_count", "item_"); + ADD_ARRAY_COUNT("Items", "item_count", "set_item_count", "get_item_count", "item_"); ADD_SIGNAL(MethodInfo("id_pressed", PropertyInfo(Variant::INT, "id"))); ADD_SIGNAL(MethodInfo("id_focused", PropertyInfo(Variant::INT, "id"))); diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h index 22912fb59c..7c2212d82d 100644 --- a/scene/gui/popup_menu.h +++ b/scene/gui/popup_menu.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -212,6 +212,7 @@ public: Ref<Shortcut> get_item_shortcut(int p_idx) const; int get_item_state(int p_idx) const; + void set_current_index(int p_idx); int get_current_index() const; void set_item_count(int p_count); diff --git a/scene/gui/progress_bar.cpp b/scene/gui/progress_bar.cpp index 2cfaaa2fde..c20fb0d7a8 100644 --- a/scene/gui/progress_bar.cpp +++ b/scene/gui/progress_bar.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/progress_bar.h b/scene/gui/progress_bar.h index fb6060d932..2d89163f78 100644 --- a/scene/gui/progress_bar.h +++ b/scene/gui/progress_bar.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/range.cpp b/scene/gui/range.cpp index c4f05a7975..879f25c8d8 100644 --- a/scene/gui/range.cpp +++ b/scene/gui/range.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/range.h b/scene/gui/range.h index 0dc702b19c..c27eeee13c 100644 --- a/scene/gui/range.h +++ b/scene/gui/range.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/reference_rect.cpp b/scene/gui/reference_rect.cpp index 6d7f2cfd57..e2a0d568a1 100644 --- a/scene/gui/reference_rect.cpp +++ b/scene/gui/reference_rect.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/reference_rect.h b/scene/gui/reference_rect.h index 7097e83a15..4a2d328162 100644 --- a/scene/gui/reference_rect.h +++ b/scene/gui/reference_rect.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/rich_text_effect.cpp b/scene/gui/rich_text_effect.cpp index 076fa132c0..c9516ed6b9 100644 --- a/scene/gui/rich_text_effect.cpp +++ b/scene/gui/rich_text_effect.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/rich_text_effect.h b/scene/gui/rich_text_effect.h index 5681f9b193..4532a812ee 100644 --- a/scene/gui/rich_text_effect.h +++ b/scene/gui/rich_text_effect.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index fd19fad667..863555120d 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -383,7 +383,7 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> // Add indent. l.offset.x = _find_margin(l.from, p_base_font, p_base_font_size); l.text_buf->set_width(p_width - l.offset.x); - l.text_buf->set_align((HAlign)_find_align(l.from)); + l.text_buf->set_alignment(_find_alignment(l.from)); l.text_buf->set_direction(_find_direction(l.from)); if (tab_size > 0) { // Align inline tabs. @@ -397,7 +397,7 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> Item *it_to = (p_line + 1 < p_frame->lines.size()) ? p_frame->lines[p_line + 1].from : nullptr; int remaining_characters = visible_characters - l.char_offset; for (Item *it = l.from; it && it != it_to; it = _get_next_item(it)) { - if (visible_characters >= 0 && remaining_characters <= 0) { + if (visible_chars_behavior == VC_CHARS_BEFORE_SHAPING && visible_characters >= 0 && remaining_characters <= 0) { break; } switch (it->type) { @@ -440,7 +440,7 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> Dictionary font_ftr = _find_font_features(it); String lang = _find_language(it); String tx = t->text; - if (visible_characters >= 0 && remaining_characters >= 0) { + if (visible_chars_behavior == VC_CHARS_BEFORE_SHAPING && visible_characters >= 0 && remaining_characters >= 0) { tx = tx.substr(0, remaining_characters); } remaining_characters -= tx.length(); @@ -621,7 +621,7 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> } } -int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Color &p_base_color, int p_outline_size, const Color &p_outline_color, const Color &p_font_shadow_color, int p_shadow_outline_size, const Point2 &p_shadow_ofs) { +int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Color &p_base_color, int p_outline_size, const Color &p_outline_color, const Color &p_font_shadow_color, int p_shadow_outline_size, const Point2 &p_shadow_ofs, int &r_processed_glyphs) { Vector2 off; ERR_FAIL_COND_V(p_frame == nullptr, 0); @@ -641,6 +641,12 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o bool rtl = (l.text_buf->get_direction() == TextServer::DIRECTION_RTL); bool lrtl = is_layout_rtl(); + bool trim_chars = (visible_characters >= 0) && (visible_chars_behavior == VC_CHARS_AFTER_SHAPING); + bool trim_glyphs_ltr = (visible_characters >= 0) && ((visible_chars_behavior == VC_GLYPHS_LTR) || ((visible_chars_behavior == VC_GLYPHS_AUTO) && !lrtl)); + bool trim_glyphs_rtl = (visible_characters >= 0) && ((visible_chars_behavior == VC_GLYPHS_RTL) || ((visible_chars_behavior == VC_GLYPHS_AUTO) && lrtl)); + int total_glyphs = (trim_glyphs_ltr || trim_glyphs_rtl) ? get_total_glyph_count() : 0; + int visible_glyphs = total_glyphs * percent_visible; + Vector<int> list_index; Vector<ItemList *> list_items; _find_list(l.from, list_index, list_items); @@ -670,7 +676,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o prefix = segment + prefix; } } - if (prefix != "") { + if (!prefix.is_empty()) { Ref<Font> font = _find_font(l.from); if (font.is_null()) { font = get_theme_font(SNAME("normal_font")); @@ -684,13 +690,13 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o if (!lrtl && p_frame == main) { // Skip Scrollbar. offx -= scroll_w; } - font->draw_string(ci, p_ofs + Vector2(p_width - l.offset.x + offx, l.text_buf->get_line_ascent(0)), " " + prefix, HALIGN_LEFT, l.offset.x, font_size, _find_color(l.from, p_base_color)); + font->draw_string(ci, p_ofs + Vector2(p_width - l.offset.x + offx, l.text_buf->get_line_ascent(0)), " " + prefix, HORIZONTAL_ALIGNMENT_LEFT, l.offset.x, font_size, _find_color(l.from, p_base_color)); } else { float offx = 0.0f; if (lrtl && p_frame == main) { // Skip Scrollbar. offx += scroll_w; } - font->draw_string(ci, p_ofs + Vector2(offx, l.text_buf->get_line_ascent(0)), prefix + " ", HALIGN_RIGHT, l.offset.x, font_size, _find_color(l.from, p_base_color)); + font->draw_string(ci, p_ofs + Vector2(offx, l.text_buf->get_line_ascent(0)), prefix + " ", HORIZONTAL_ALIGNMENT_RIGHT, l.offset.x, font_size, _find_color(l.from, p_base_color)); } } @@ -734,17 +740,17 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o } // Draw text. - switch (l.text_buf->get_align()) { - case HALIGN_FILL: - case HALIGN_LEFT: { + switch (l.text_buf->get_alignment()) { + case HORIZONTAL_ALIGNMENT_FILL: + case HORIZONTAL_ALIGNMENT_LEFT: { if (rtl) { off.x += width - length; } } break; - case HALIGN_CENTER: { + case HORIZONTAL_ALIGNMENT_CENTER: { off.x += Math::floor((width - length) / 2.0); } break; - case HALIGN_RIGHT: { + case HORIZONTAL_ALIGNMENT_RIGHT: { if (!rtl) { off.x += width - length; } @@ -804,7 +810,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o } for (int j = 0; j < frame->lines.size(); j++) { - _draw_line(frame, j, p_ofs + rect.position + off + Vector2(0, frame->lines[j].offset.y), rect.size.x, p_base_color, p_outline_size, p_outline_color, p_font_shadow_color, p_shadow_outline_size, p_shadow_ofs); + _draw_line(frame, j, p_ofs + rect.position + off + Vector2(0, frame->lines[j].offset.y), rect.size.x, p_base_color, p_outline_size, p_outline_color, p_font_shadow_color, p_shadow_outline_size, p_shadow_ofs, r_processed_glyphs); } idx++; } @@ -820,6 +826,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o Vector2 gloff = off; // Draw oulines and shadow. + int processed_glyphs_ol = r_processed_glyphs; for (int i = 0; i < gl_size; i++) { Item *it = _get_item_at_pos(it_from, it_to, glyphs[i].start); int size = _find_outline_size(it, p_outline_size); @@ -947,7 +954,8 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o // Draw glyph outlines. for (int j = 0; j < glyphs[i].repeat; j++) { if (visible) { - if (frid != RID()) { + bool skip = (trim_chars && l.char_offset + glyphs[i].end > visible_characters) || (trim_glyphs_ltr && (processed_glyphs_ol >= visible_glyphs)) || (trim_glyphs_rtl && (processed_glyphs_ol < total_glyphs - visible_glyphs)); + if (!skip && frid != RID()) { if (font_shadow_color.a > 0) { TS->font_draw_glyph(frid, ci, glyphs[i].font_size, p_ofs + fx_offset + gloff + p_shadow_ofs, gl, font_shadow_color); } @@ -958,6 +966,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, size, p_ofs + fx_offset + gloff, gl, font_color); } } + processed_glyphs_ol++; } gloff.x += glyphs[i].advance; } @@ -996,7 +1005,8 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o 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(); draw_line(p_ofs + Vector2(off.x, off.y + y_off), p_ofs + Vector2(off.x + glyphs[i].advance * glyphs[i].repeat, off.y + y_off), uc, underline_width); - } else if (_find_strikethrough(it)) { + } + if (_find_strikethrough(it)) { Color uc = font_color; uc.a *= 0.5; float y_off = -TS->shaped_text_get_ascent(rid) + TS->shaped_text_get_size(rid).y / 2; @@ -1124,11 +1134,15 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o // Draw glyphs. for (int j = 0; j < glyphs[i].repeat; j++) { if (visible) { - if (frid != RID()) { - TS->font_draw_glyph(frid, ci, glyphs[i].font_size, p_ofs + fx_offset + off, gl, selected ? selection_fg : font_color); - } else if ((glyphs[i].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { - TS->draw_hex_code_box(ci, glyphs[i].font_size, p_ofs + fx_offset + off, gl, selected ? selection_fg : font_color); + bool skip = (trim_chars && l.char_offset + glyphs[i].end > visible_characters) || (trim_glyphs_ltr && (r_processed_glyphs >= visible_glyphs)) || (trim_glyphs_rtl && (r_processed_glyphs < total_glyphs - visible_glyphs)); + if (!skip) { + if (frid != RID()) { + TS->font_draw_glyph(frid, ci, glyphs[i].font_size, p_ofs + fx_offset + off, gl, selected ? selection_fg : font_color); + } else if ((glyphs[i].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { + TS->draw_hex_code_box(ci, glyphs[i].font_size, p_ofs + fx_offset + off, gl, selected ? selection_fg : font_color); + } } + r_processed_glyphs++; } off.x += glyphs[i].advance; } @@ -1214,17 +1228,17 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V } } - switch (l.text_buf->get_align()) { - case HALIGN_FILL: - case HALIGN_LEFT: { + switch (l.text_buf->get_alignment()) { + case HORIZONTAL_ALIGNMENT_FILL: + case HORIZONTAL_ALIGNMENT_LEFT: { if (rtl) { off.x += width - length; } } break; - case HALIGN_CENTER: { + case HORIZONTAL_ALIGNMENT_CENTER: { off.x += Math::floor((width - length) / 2.0); } break; - case HALIGN_RIGHT: { + case HORIZONTAL_ALIGNMENT_RIGHT: { if (!rtl) { off.x += width - length; } @@ -1423,7 +1437,7 @@ void RichTextLabel::_notification(int p_what) { } break; case NOTIFICATION_THEME_CHANGED: case NOTIFICATION_ENTER_TREE: { - if (text != "") { + if (!text.is_empty()) { set_text(text); } @@ -1481,9 +1495,10 @@ void RichTextLabel::_notification(int p_what) { // New cache draw. Point2 ofs = text_rect.get_position() + Vector2(0, main->lines[from_line].offset.y - vofs); + int processed_glyphs = 0; while (ofs.y < size.height && from_line < main->lines.size()) { 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); + 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 + get_theme_constant(SNAME("line_separation")); from_line++; } @@ -1950,19 +1965,19 @@ int RichTextLabel::_find_margin(Item *p_item, const Ref<Font> &p_base_font, int return margin; } -RichTextLabel::Align RichTextLabel::_find_align(Item *p_item) { +HorizontalAlignment RichTextLabel::_find_alignment(Item *p_item) { Item *item = p_item; while (item) { if (item->type == ITEM_PARAGRAPH) { ItemParagraph *p = static_cast<ItemParagraph *>(item); - return p->align; + return p->alignment; } item = item->parent; } - return default_align; + return default_alignment; } TextServer::Direction RichTextLabel::_find_direction(Item *p_item) { @@ -2190,7 +2205,7 @@ void RichTextLabel::_validate_line_caches(ItemFrame *p_frame) { updating_scroll = false; if (fit_content_height) { - minimum_size_changed(); + update_minimum_size(); } return; } @@ -2227,7 +2242,7 @@ void RichTextLabel::_validate_line_caches(ItemFrame *p_frame) { updating_scroll = false; if (fit_content_height) { - minimum_size_changed(); + update_minimum_size(); } } @@ -2324,7 +2339,7 @@ void RichTextLabel::_add_item(Item *p_item, bool p_enter, bool p_ensure_newline) _invalidate_current_line(current_frame); if (fixed_width != -1) { - minimum_size_changed(); + update_minimum_size(); } } @@ -2349,9 +2364,10 @@ void RichTextLabel::_remove_item(Item *p_item, const int p_line, const int p_sub // Then remove the provided item itself. p_item->parent->subitems.erase(p_item); } + memdelete(p_item); } -void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width, const int p_height, const Color &p_color, InlineAlign p_align) { +void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width, const int p_height, const Color &p_color, InlineAlignment p_alignment) { if (current->type == ITEM_TABLE) { return; } @@ -2363,7 +2379,7 @@ void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width, item->image = p_image; item->color = p_color; - item->inline_align = p_align; + item->inline_align = p_alignment; if (p_width > 0) { // custom width @@ -2555,11 +2571,11 @@ void RichTextLabel::push_strikethrough() { _add_item(item, true); } -void RichTextLabel::push_paragraph(Align p_align, Control::TextDirection p_direction, const String &p_language, Control::StructuredTextParser p_st_parser) { +void RichTextLabel::push_paragraph(HorizontalAlignment p_alignment, Control::TextDirection p_direction, const String &p_language, Control::StructuredTextParser p_st_parser) { ERR_FAIL_COND(current->type == ITEM_TABLE); ItemParagraph *item = memnew(ItemParagraph); - item->align = p_align; + item->alignment = p_alignment; item->direction = p_direction; item->language = p_language; item->st_parser = p_st_parser; @@ -2595,13 +2611,13 @@ void RichTextLabel::push_meta(const Variant &p_meta) { _add_item(item, true); } -void RichTextLabel::push_table(int p_columns, InlineAlign p_align) { +void RichTextLabel::push_table(int p_columns, InlineAlignment p_alignment) { ERR_FAIL_COND(p_columns < 1); ItemTable *item = memnew(ItemTable); item->columns.resize(p_columns); item->total_width = 0; - item->inline_align = p_align; + item->inline_align = p_alignment; for (int i = 0; i < item->columns.size(); i++) { item->columns.write[i].expand = false; item->columns.write[i].expand_ratio = 1; @@ -2755,7 +2771,7 @@ void RichTextLabel::clear() { } if (fixed_width != -1) { - minimum_size_changed(); + update_minimum_size(); } } @@ -2772,7 +2788,7 @@ int RichTextLabel::get_tab_size() const { void RichTextLabel::set_fit_content_height(bool p_enabled) { if (p_enabled != fit_content_height) { fit_content_height = p_enabled; - minimum_size_changed(); + update_minimum_size(); } } @@ -2958,35 +2974,35 @@ void RichTextLabel::append_text(const String &p_bbcode) { columns = 1; } - int align = INLINE_ALIGN_TOP; + int alignment = INLINE_ALIGNMENT_TOP; if (subtag.size() > 2) { if (subtag[1] == "top" || subtag[1] == "t") { - align = INLINE_ALIGN_TOP_TO; + alignment = INLINE_ALIGNMENT_TOP_TO; } else if (subtag[1] == "center" || subtag[1] == "c") { - align = INLINE_ALIGN_CENTER_TO; + alignment = INLINE_ALIGNMENT_CENTER_TO; } else if (subtag[1] == "bottom" || subtag[1] == "b") { - align = INLINE_ALIGN_BOTTOM_TO; + alignment = INLINE_ALIGNMENT_BOTTOM_TO; } if (subtag[2] == "top" || subtag[2] == "t") { - align |= INLINE_ALIGN_TO_TOP; + alignment |= INLINE_ALIGNMENT_TO_TOP; } else if (subtag[2] == "center" || subtag[2] == "c") { - align |= INLINE_ALIGN_TO_CENTER; + alignment |= INLINE_ALIGNMENT_TO_CENTER; } else if (subtag[2] == "baseline" || subtag[2] == "l") { - align |= INLINE_ALIGN_TO_BASELINE; + alignment |= INLINE_ALIGNMENT_TO_BASELINE; } else if (subtag[2] == "bottom" || subtag[2] == "b") { - align |= INLINE_ALIGN_TO_BOTTOM; + alignment |= INLINE_ALIGNMENT_TO_BOTTOM; } } else if (subtag.size() > 1) { if (subtag[1] == "top" || subtag[1] == "t") { - align = INLINE_ALIGN_TOP; + alignment = INLINE_ALIGNMENT_TOP; } else if (subtag[1] == "center" || subtag[1] == "c") { - align = INLINE_ALIGN_CENTER; + alignment = INLINE_ALIGNMENT_CENTER; } else if (subtag[1] == "bottom" || subtag[1] == "b") { - align = INLINE_ALIGN_BOTTOM; + alignment = INLINE_ALIGNMENT_BOTTOM; } } - push_table(columns, (InlineAlign)align); + push_table(columns, (InlineAlignment)alignment); pos = brk_end + 1; tag_stack.push_front("table"); } else if (tag == "cell") { @@ -3050,6 +3066,12 @@ void RichTextLabel::append_text(const String &p_bbcode) { push_strikethrough(); pos = brk_end + 1; tag_stack.push_front(tag); + } else if (tag == "lb") { + add_text("["); + pos = brk_end + 1; + } else if (tag == "rb") { + add_text("]"); + pos = brk_end + 1; } else if (tag == "lrm") { add_text(String::chr(0x200E)); pos = brk_end + 1; @@ -3099,15 +3121,15 @@ void RichTextLabel::append_text(const String &p_bbcode) { add_text(String::chr(0x00AD)); pos = brk_end + 1; } else if (tag == "center") { - push_paragraph(ALIGN_CENTER); + push_paragraph(HORIZONTAL_ALIGNMENT_CENTER); pos = brk_end + 1; tag_stack.push_front(tag); } else if (tag == "fill") { - push_paragraph(ALIGN_FILL); + push_paragraph(HORIZONTAL_ALIGNMENT_FILL); pos = brk_end + 1; tag_stack.push_front(tag); } else if (tag == "right") { - push_paragraph(ALIGN_RIGHT); + push_paragraph(HORIZONTAL_ALIGNMENT_RIGHT); pos = brk_end + 1; tag_stack.push_front(tag); } else if (tag == "ul") { @@ -3146,12 +3168,12 @@ void RichTextLabel::append_text(const String &p_bbcode) { pos = brk_end + 1; tag_stack.push_front(tag); } else if (tag == "p") { - push_paragraph(ALIGN_LEFT); + push_paragraph(HORIZONTAL_ALIGNMENT_LEFT); pos = brk_end + 1; tag_stack.push_front("p"); } else if (tag.begins_with("p ")) { Vector<String> subtag = tag.substr(2, tag.length()).split(" "); - Align align = ALIGN_LEFT; + HorizontalAlignment alignment = HORIZONTAL_ALIGNMENT_LEFT; Control::TextDirection dir = Control::TEXT_DIRECTION_INHERITED; String lang; Control::StructuredTextParser st_parser = STRUCTURED_TEXT_DEFAULT; @@ -3160,13 +3182,13 @@ void RichTextLabel::append_text(const String &p_bbcode) { if (subtag_a.size() == 2) { if (subtag_a[0] == "align") { if (subtag_a[1] == "l" || subtag_a[1] == "left") { - align = ALIGN_LEFT; + alignment = HORIZONTAL_ALIGNMENT_LEFT; } else if (subtag_a[1] == "c" || subtag_a[1] == "center") { - align = ALIGN_CENTER; + alignment = HORIZONTAL_ALIGNMENT_CENTER; } else if (subtag_a[1] == "r" || subtag_a[1] == "right") { - align = ALIGN_RIGHT; + alignment = HORIZONTAL_ALIGNMENT_RIGHT; } else if (subtag_a[1] == "f" || subtag_a[1] == "fill") { - align = ALIGN_FILL; + alignment = HORIZONTAL_ALIGNMENT_FILL; } } else if (subtag_a[0] == "dir" || subtag_a[0] == "direction") { if (subtag_a[1] == "a" || subtag_a[1] == "auto") { @@ -3197,7 +3219,7 @@ void RichTextLabel::append_text(const String &p_bbcode) { } } } - push_paragraph(align, dir, lang, st_parser); + push_paragraph(alignment, dir, lang, st_parser); pos = brk_end + 1; tag_stack.push_front("p"); } else if (tag == "url") { @@ -3265,33 +3287,33 @@ void RichTextLabel::append_text(const String &p_bbcode) { pos = end; tag_stack.push_front(bbcode_name); } else if (tag.begins_with("img")) { - int align = INLINE_ALIGN_CENTER; + int alignment = INLINE_ALIGNMENT_CENTER; if (tag.begins_with("img=")) { Vector<String> subtag = tag.substr(4, tag.length()).split(","); if (subtag.size() > 1) { if (subtag[0] == "top" || subtag[0] == "t") { - align = INLINE_ALIGN_TOP_TO; + alignment = INLINE_ALIGNMENT_TOP_TO; } else if (subtag[0] == "center" || subtag[0] == "c") { - align = INLINE_ALIGN_CENTER_TO; + alignment = INLINE_ALIGNMENT_CENTER_TO; } else if (subtag[0] == "bottom" || subtag[0] == "b") { - align = INLINE_ALIGN_BOTTOM_TO; + alignment = INLINE_ALIGNMENT_BOTTOM_TO; } if (subtag[1] == "top" || subtag[1] == "t") { - align |= INLINE_ALIGN_TO_TOP; + alignment |= INLINE_ALIGNMENT_TO_TOP; } else if (subtag[1] == "center" || subtag[1] == "c") { - align |= INLINE_ALIGN_TO_CENTER; + alignment |= INLINE_ALIGNMENT_TO_CENTER; } else if (subtag[1] == "baseline" || subtag[1] == "l") { - align |= INLINE_ALIGN_TO_BASELINE; + alignment |= INLINE_ALIGNMENT_TO_BASELINE; } else if (subtag[1] == "bottom" || subtag[1] == "b") { - align |= INLINE_ALIGN_TO_BOTTOM; + alignment |= INLINE_ALIGNMENT_TO_BOTTOM; } } else if (subtag.size() > 0) { if (subtag[0] == "top" || subtag[0] == "t") { - align = INLINE_ALIGN_TOP; + alignment = INLINE_ALIGNMENT_TOP; } else if (subtag[0] == "center" || subtag[0] == "c") { - align = INLINE_ALIGN_CENTER; + alignment = INLINE_ALIGNMENT_CENTER; } else if (subtag[0] == "bottom" || subtag[0] == "b") { - align = INLINE_ALIGN_BOTTOM; + alignment = INLINE_ALIGNMENT_BOTTOM; } } } @@ -3333,7 +3355,7 @@ void RichTextLabel::append_text(const String &p_bbcode) { } } - add_image(texture, width, height, color, (InlineAlign)align); + add_image(texture, width, height, color, (InlineAlignment)alignment); } pos = end; @@ -3853,7 +3875,7 @@ String RichTextLabel::get_selected_text() const { void RichTextLabel::selection_copy() { String text = get_selected_text(); - if (text != "") { + if (!text.is_empty()) { DisplayServer::get_singleton()->clipboard_set(text); } } @@ -3993,8 +4015,10 @@ void RichTextLabel::set_percent_visible(float p_percent) { visible_characters = get_total_character_count() * p_percent; percent_visible = p_percent; } - main->first_invalid_line = 0; //invalidate ALL - _validate_line_caches(main); + if (visible_chars_behavior == VC_CHARS_BEFORE_SHAPING) { + main->first_invalid_line = 0; //invalidate ALL + _validate_line_caches(main); + } update(); } } @@ -4005,7 +4029,7 @@ float RichTextLabel::get_percent_visible() const { void RichTextLabel::set_effects(Array p_effects) { custom_effects = p_effects; - if ((text != "") && use_bbcode) { + if ((!text.is_empty()) && use_bbcode) { parse_bbcode(text); } } @@ -4020,7 +4044,7 @@ void RichTextLabel::install_effect(const Variant effect) { if (rteffect.is_valid()) { custom_effects.push_back(effect); - if ((text != "") && use_bbcode) { + if ((!text.is_empty()) && use_bbcode) { parse_bbcode(text); } } @@ -4036,7 +4060,7 @@ int RichTextLabel::get_content_height() const { #ifndef DISABLE_DEPRECATED // People will be very angry, if their texts get erased, because of #39148. (3.x -> 4.0) -// Altough some people may not used bbcode_text, so we only overwrite, if bbcode_text is not empty +// Although some people may not used bbcode_text, so we only overwrite, if bbcode_text is not empty. bool RichTextLabel::_set(const StringName &p_name, const Variant &p_value) { if (p_name == "bbcode_text" && !((String)p_value).is_empty()) { set_text(p_value); @@ -4050,7 +4074,7 @@ void RichTextLabel::_bind_methods() { ClassDB::bind_method(D_METHOD("get_parsed_text"), &RichTextLabel::get_parsed_text); ClassDB::bind_method(D_METHOD("add_text", "text"), &RichTextLabel::add_text); ClassDB::bind_method(D_METHOD("set_text", "text"), &RichTextLabel::set_text); - ClassDB::bind_method(D_METHOD("add_image", "image", "width", "height", "color", "inline_align"), &RichTextLabel::add_image, DEFVAL(0), DEFVAL(0), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(INLINE_ALIGN_CENTER)); + ClassDB::bind_method(D_METHOD("add_image", "image", "width", "height", "color", "inline_align"), &RichTextLabel::add_image, DEFVAL(0), DEFVAL(0), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(INLINE_ALIGNMENT_CENTER)); ClassDB::bind_method(D_METHOD("newline"), &RichTextLabel::add_newline); ClassDB::bind_method(D_METHOD("remove_line", "line"), &RichTextLabel::remove_line); ClassDB::bind_method(D_METHOD("push_font", "font"), &RichTextLabel::push_font); @@ -4064,13 +4088,13 @@ void RichTextLabel::_bind_methods() { ClassDB::bind_method(D_METHOD("push_color", "color"), &RichTextLabel::push_color); ClassDB::bind_method(D_METHOD("push_outline_size", "outline_size"), &RichTextLabel::push_outline_size); ClassDB::bind_method(D_METHOD("push_outline_color", "color"), &RichTextLabel::push_outline_color); - ClassDB::bind_method(D_METHOD("push_paragraph", "align", "base_direction", "language", "st_parser"), &RichTextLabel::push_paragraph, DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(""), DEFVAL(STRUCTURED_TEXT_DEFAULT)); + ClassDB::bind_method(D_METHOD("push_paragraph", "alignment", "base_direction", "language", "st_parser"), &RichTextLabel::push_paragraph, DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(""), DEFVAL(STRUCTURED_TEXT_DEFAULT)); ClassDB::bind_method(D_METHOD("push_indent", "level"), &RichTextLabel::push_indent); ClassDB::bind_method(D_METHOD("push_list", "level", "type", "capitalize"), &RichTextLabel::push_list); ClassDB::bind_method(D_METHOD("push_meta", "data"), &RichTextLabel::push_meta); ClassDB::bind_method(D_METHOD("push_underline"), &RichTextLabel::push_underline); ClassDB::bind_method(D_METHOD("push_strikethrough"), &RichTextLabel::push_strikethrough); - ClassDB::bind_method(D_METHOD("push_table", "columns", "inline_align"), &RichTextLabel::push_table, DEFVAL(INLINE_ALIGN_TOP)); + ClassDB::bind_method(D_METHOD("push_table", "columns", "inline_align"), &RichTextLabel::push_table, DEFVAL(INLINE_ALIGNMENT_TOP)); ClassDB::bind_method(D_METHOD("push_dropcap", "string", "font", "size", "dropcap_margins", "color", "outline_size", "outline_color"), &RichTextLabel::push_dropcap, DEFVAL(Rect2()), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(0, 0, 0, 0))); ClassDB::bind_method(D_METHOD("set_table_column_expand", "column", "expand", "ratio"), &RichTextLabel::set_table_column_expand); ClassDB::bind_method(D_METHOD("set_cell_row_background_color", "odd_row_bg", "even_row_bg"), &RichTextLabel::set_cell_row_background_color); @@ -4105,7 +4129,7 @@ void RichTextLabel::_bind_methods() { ClassDB::bind_method(D_METHOD("set_scroll_follow", "follow"), &RichTextLabel::set_scroll_follow); ClassDB::bind_method(D_METHOD("is_scroll_following"), &RichTextLabel::is_scroll_following); - ClassDB::bind_method(D_METHOD("get_v_scroll"), &RichTextLabel::get_v_scroll); + ClassDB::bind_method(D_METHOD("get_v_scroll_bar"), &RichTextLabel::get_v_scroll_bar); ClassDB::bind_method(D_METHOD("scroll_to_line", "line"), &RichTextLabel::scroll_to_line); ClassDB::bind_method(D_METHOD("scroll_to_paragraph", "paragraph"), &RichTextLabel::scroll_to_paragraph); @@ -4135,6 +4159,9 @@ void RichTextLabel::_bind_methods() { ClassDB::bind_method(D_METHOD("set_visible_characters", "amount"), &RichTextLabel::set_visible_characters); ClassDB::bind_method(D_METHOD("get_visible_characters"), &RichTextLabel::get_visible_characters); + ClassDB::bind_method(D_METHOD("get_visible_characters_behavior"), &RichTextLabel::get_visible_characters_behavior); + ClassDB::bind_method(D_METHOD("set_visible_characters_behavior", "behavior"), &RichTextLabel::set_visible_characters_behavior); + ClassDB::bind_method(D_METHOD("set_percent_visible", "percent_visible"), &RichTextLabel::set_percent_visible); ClassDB::bind_method(D_METHOD("get_percent_visible"), &RichTextLabel::get_percent_visible); @@ -4160,6 +4187,8 @@ void RichTextLabel::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_characters", PROPERTY_HINT_RANGE, "-1,128000,1"), "set_visible_characters", "get_visible_characters"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "percent_visible", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_percent_visible", "get_percent_visible"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_characters_behavior", PROPERTY_HINT_ENUM, "Characters Before Shaping,Characters After Shaping,Glyphs (Layout Direction),Glyphs (Left-to-Right),Glyphs (Right-to-Left)"), "set_visible_characters_behavior", "get_visible_characters_behavior"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "meta_underlined"), "set_meta_underline", "is_meta_underlined"); ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_size", PROPERTY_HINT_RANGE, "0,24,1"), "set_tab_size", "get_tab_size"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT), "set_text", "get_text"); @@ -4188,11 +4217,6 @@ void RichTextLabel::_bind_methods() { ADD_SIGNAL(MethodInfo("meta_hover_started", PropertyInfo(Variant::NIL, "meta", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT))); ADD_SIGNAL(MethodInfo("meta_hover_ended", PropertyInfo(Variant::NIL, "meta", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT))); - BIND_ENUM_CONSTANT(ALIGN_LEFT); - BIND_ENUM_CONSTANT(ALIGN_CENTER); - BIND_ENUM_CONSTANT(ALIGN_RIGHT); - BIND_ENUM_CONSTANT(ALIGN_FILL); - BIND_ENUM_CONSTANT(LIST_NUMBERS); BIND_ENUM_CONSTANT(LIST_LETTERS); BIND_ENUM_CONSTANT(LIST_ROMAN); @@ -4224,6 +4248,25 @@ void RichTextLabel::_bind_methods() { BIND_ENUM_CONSTANT(ITEM_META); BIND_ENUM_CONSTANT(ITEM_DROPCAP); BIND_ENUM_CONSTANT(ITEM_CUSTOMFX); + + BIND_ENUM_CONSTANT(VC_CHARS_BEFORE_SHAPING); + BIND_ENUM_CONSTANT(VC_CHARS_AFTER_SHAPING); + BIND_ENUM_CONSTANT(VC_GLYPHS_AUTO); + BIND_ENUM_CONSTANT(VC_GLYPHS_LTR); + BIND_ENUM_CONSTANT(VC_GLYPHS_RTL); +} + +RichTextLabel::VisibleCharactersBehavior RichTextLabel::get_visible_characters_behavior() const { + return visible_chars_behavior; +} + +void RichTextLabel::set_visible_characters_behavior(RichTextLabel::VisibleCharactersBehavior p_behavior) { + if (visible_chars_behavior != p_behavior) { + visible_chars_behavior = p_behavior; + main->first_invalid_line = 0; //invalidate ALL + _validate_line_caches(main); + update(); + } } void RichTextLabel::set_visible_characters(int p_visible) { @@ -4237,8 +4280,10 @@ void RichTextLabel::set_visible_characters(int p_visible) { percent_visible = (float)p_visible / (float)total_char_count; } } - main->first_invalid_line = 0; //invalidate ALL - _validate_line_caches(main); + if (visible_chars_behavior == VC_CHARS_BEFORE_SHAPING) { + main->first_invalid_line = 0; //invalidate ALL + _validate_line_caches(main); + } update(); } } @@ -4266,9 +4311,25 @@ int RichTextLabel::get_total_character_count() const { return tc; } +int RichTextLabel::get_total_glyph_count() const { + int tg = 0; + Item *it = main; + while (it) { + if (it->type == ITEM_FRAME) { + ItemFrame *f = static_cast<ItemFrame *>(it); + for (int i = 0; i < f->lines.size(); i++) { + tg += TS->shaped_text_get_glyph_count(f->lines[i].text_buf->get_rid()); + } + } + it = _get_next_item(it, true); + } + + return tg; +} + void RichTextLabel::set_fixed_size_to_width(int p_width) { fixed_width = p_width; - minimum_size_changed(); + update_minimum_size(); } Size2 RichTextLabel::get_minimum_size() const { diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index 5b58f14d96..70467e7e7c 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -39,13 +39,6 @@ class RichTextLabel : public Control { GDCLASS(RichTextLabel, Control); public: - enum Align { - ALIGN_LEFT, - ALIGN_CENTER, - ALIGN_RIGHT, - ALIGN_FILL - }; - enum ListType { LIST_NUMBERS, LIST_LETTERS, @@ -82,6 +75,14 @@ public: ITEM_CUSTOMFX }; + enum VisibleCharactersBehavior { + VC_CHARS_BEFORE_SHAPING, + VC_CHARS_AFTER_SHAPING, + VC_GLYPHS_AUTO, + VC_GLYPHS_LTR, + VC_GLYPHS_RTL, + }; + protected: void _notification(int p_what); static void _bind_methods(); @@ -160,7 +161,7 @@ private: struct ItemImage : public Item { Ref<Texture2D> image; - InlineAlign inline_align = INLINE_ALIGN_CENTER; + InlineAlignment inline_align = INLINE_ALIGNMENT_CENTER; Size2 size; Color color; ItemImage() { type = ITEM_IMAGE; } @@ -210,7 +211,7 @@ private: }; struct ItemParagraph : public Item { - Align align = ALIGN_LEFT; + HorizontalAlignment alignment = HORIZONTAL_ALIGNMENT_LEFT; String language; Control::TextDirection direction = Control::TEXT_DIRECTION_AUTO; Control::StructuredTextParser st_parser = STRUCTURED_TEXT_DEFAULT; @@ -247,7 +248,7 @@ private: int total_width = 0; int total_height = 0; - InlineAlign inline_align = INLINE_ALIGN_TOP; + InlineAlignment inline_align = INLINE_ALIGNMENT_TOP; ItemTable() { type = ITEM_TABLE; } }; @@ -360,7 +361,7 @@ private: bool underline_meta = true; bool override_selected_font_color = false; - Align default_align = ALIGN_LEFT; + HorizontalAlignment default_alignment = HORIZONTAL_ALIGNMENT_LEFT; ItemMeta *meta_hovering = nullptr; Variant current_meta; @@ -403,6 +404,7 @@ private: int visible_characters = -1; float percent_visible = 1.0; + VisibleCharactersBehavior visible_chars_behavior = VC_CHARS_BEFORE_SHAPING; void _find_click(ItemFrame *p_frame, const Point2i &p_click, ItemFrame **r_click_frame = nullptr, int *r_click_line = nullptr, Item **r_click_item = nullptr, int *r_click_char = nullptr, bool *r_outside = nullptr); @@ -412,7 +414,7 @@ private: void _shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size, int p_width, int *r_char_offset); void _resize_line(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size, int p_width); - int _draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Color &p_base_color, int p_outline_size, const Color &p_outline_color, const Color &p_font_shadow_color, int p_shadow_outline_size, const Point2 &p_shadow_ofs); + int _draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Color &p_base_color, int p_outline_size, const Color &p_outline_color, const Color &p_font_shadow_color, int p_shadow_outline_size, const Point2 &p_shadow_ofs, int &r_processed_glyphs); float _find_click_in_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Point2i &p_click, ItemFrame **r_click_frame = nullptr, int *r_click_line = nullptr, Item **r_click_item = nullptr, int *r_click_char = nullptr); String _roman(int p_num, bool p_capitalize) const; @@ -428,7 +430,7 @@ private: ItemDropcap *_find_dc_item(Item *p_item); int _find_list(Item *p_item, Vector<int> &r_index, Vector<ItemList *> &r_list); int _find_margin(Item *p_item, const Ref<Font> &p_base_font, int p_base_font_size); - Align _find_align(Item *p_item); + HorizontalAlignment _find_alignment(Item *p_item); TextServer::Direction _find_direction(Item *p_item); Control::StructuredTextParser _find_stt(Item *p_item); String _find_language(Item *p_item); @@ -469,7 +471,7 @@ private: public: String get_parsed_text() const; void add_text(const String &p_text); - void add_image(const Ref<Texture2D> &p_image, const int p_width = 0, const int p_height = 0, const Color &p_color = Color(1.0, 1.0, 1.0), InlineAlign p_align = INLINE_ALIGN_CENTER); + void add_image(const Ref<Texture2D> &p_image, const int p_width = 0, const int p_height = 0, const Color &p_color = Color(1.0, 1.0, 1.0), InlineAlignment p_alignment = INLINE_ALIGNMENT_CENTER); void add_newline(); bool remove_line(const int p_line); void push_dropcap(const String &p_string, const Ref<Font> &p_font, int p_size, const Rect2 &p_dropcap_margins = Rect2(), const Color &p_color = Color(1, 1, 1), int p_ol_size = 0, const Color &p_ol_color = Color(0, 0, 0, 0)); @@ -486,11 +488,11 @@ public: void push_outline_color(const Color &p_color); void push_underline(); void push_strikethrough(); - void push_paragraph(Align p_align, Control::TextDirection p_direction = Control::TEXT_DIRECTION_INHERITED, const String &p_language = "", Control::StructuredTextParser p_st_parser = STRUCTURED_TEXT_DEFAULT); + void push_paragraph(HorizontalAlignment p_alignment, Control::TextDirection p_direction = Control::TEXT_DIRECTION_INHERITED, const String &p_language = "", Control::StructuredTextParser p_st_parser = STRUCTURED_TEXT_DEFAULT); void push_indent(int p_level); void push_list(int p_level, ListType p_list, bool p_capitalize); void push_meta(const Variant &p_meta); - void push_table(int p_columns, InlineAlign p_align = INLINE_ALIGN_TOP); + void push_table(int p_columns, InlineAlignment p_alignment = INLINE_ALIGNMENT_TOP); void push_fade(int p_start_index, int p_length); void push_shake(int p_strength, float p_rate); void push_wave(float p_frequency, float p_amplitude); @@ -542,7 +544,7 @@ public: int get_content_height() const; - VScrollBar *get_v_scroll() { return vscroll; } + VScrollBar *get_v_scroll_bar() { return vscroll; } virtual CursorShape get_cursor_shape(const Point2 &p_pos) const override; @@ -579,10 +581,14 @@ public: void set_visible_characters(int p_visible); int get_visible_characters() const; int get_total_character_count() const; + int get_total_glyph_count() const; void set_percent_visible(float p_percent); float get_percent_visible() const; + VisibleCharactersBehavior get_visible_characters_behavior() const; + void set_visible_characters_behavior(VisibleCharactersBehavior p_behavior); + void set_effects(Array p_effects); Array get_effects(); @@ -595,8 +601,8 @@ public: ~RichTextLabel(); }; -VARIANT_ENUM_CAST(RichTextLabel::Align); VARIANT_ENUM_CAST(RichTextLabel::ListType); VARIANT_ENUM_CAST(RichTextLabel::ItemType); +VARIANT_ENUM_CAST(RichTextLabel::VisibleCharactersBehavior); #endif // RICH_TEXT_LABEL_H diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp index 8c292e663e..343056957c 100644 --- a/scene/gui/scroll_bar.cpp +++ b/scene/gui/scroll_bar.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/scroll_bar.h b/scene/gui/scroll_bar.h index 574d17ee20..651edd1a74 100644 --- a/scene/gui/scroll_bar.h +++ b/scene/gui/scroll_bar.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp index 7b2ea46e17..5e128d594c 100644 --- a/scene/gui/scroll_container.cpp +++ b/scene/gui/scroll_container.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -49,10 +49,10 @@ Size2 ScrollContainer::get_minimum_size() const { } Size2 minsize = c->get_combined_minimum_size(); - if (!scroll_h) { + if (horizontal_scroll_mode == SCROLL_MODE_DISABLED) { min_size.x = MAX(min_size.x, minsize.x); } - if (!scroll_v) { + if (vertical_scroll_mode == SCROLL_MODE_DISABLED) { min_size.y = MAX(min_size.y, minsize.y); } } @@ -170,7 +170,7 @@ void ScrollContainer::gui_input(const Ref<InputEvent> &p_gui_input) { Vector2 motion = mm->get_relative(); drag_accum -= motion; - if (beyond_deadzone || (scroll_h && Math::abs(drag_accum.x) > deadzone) || (scroll_v && Math::abs(drag_accum.y) > deadzone)) { + if (beyond_deadzone || (horizontal_scroll_mode != SCROLL_MODE_DISABLED && Math::abs(drag_accum.x) > deadzone) || (vertical_scroll_mode != SCROLL_MODE_DISABLED && Math::abs(drag_accum.y) > deadzone)) { if (!beyond_deadzone) { propagate_notification(NOTIFICATION_SCROLL_BEGIN); emit_signal(SNAME("scroll_started")); @@ -180,12 +180,12 @@ void ScrollContainer::gui_input(const Ref<InputEvent> &p_gui_input) { drag_accum = -motion; } Vector2 diff = drag_from + drag_accum; - if (scroll_h) { + if (horizontal_scroll_mode != SCROLL_MODE_DISABLED) { h_scroll->set_value(diff.x); } else { drag_accum.x = 0; } - if (scroll_v) { + if (vertical_scroll_mode != SCROLL_MODE_DISABLED) { v_scroll->set_value(diff.y); } else { drag_accum.y = 0; @@ -286,7 +286,7 @@ void ScrollContainer::_update_dimensions() { child_max_size.y = MAX(child_max_size.y, minsize.y); Rect2 r = Rect2(-Size2(get_h_scroll(), get_v_scroll()), minsize); - if (!scroll_h || (!h_scroll->is_visible_in_tree() && c->get_h_size_flags() & SIZE_EXPAND)) { + if (horizontal_scroll_mode == SCROLL_MODE_DISABLED || (!h_scroll->is_visible_in_tree() && c->get_h_size_flags() & SIZE_EXPAND)) { r.position.x = 0; if (c->get_h_size_flags() & SIZE_EXPAND) { r.size.width = MAX(size.width, minsize.width); @@ -294,7 +294,7 @@ void ScrollContainer::_update_dimensions() { r.size.width = minsize.width; } } - if (!scroll_v || (!v_scroll->is_visible_in_tree() && c->get_v_size_flags() & SIZE_EXPAND)) { + if (vertical_scroll_mode == SCROLL_MODE_DISABLED || (!v_scroll->is_visible_in_tree() && c->get_v_size_flags() & SIZE_EXPAND)) { r.position.y = 0; if (c->get_v_size_flags() & SIZE_EXPAND) { r.size.height = MAX(size.height, minsize.height); @@ -364,10 +364,10 @@ void ScrollContainer::_notification(int p_what) { turnoff_v = true; } - if (scroll_h) { + if (horizontal_scroll_mode != SCROLL_MODE_DISABLED) { h_scroll->set_value(pos.x); } - if (scroll_v) { + if (vertical_scroll_mode != SCROLL_MODE_DISABLED) { v_scroll->set_value(pos.y); } @@ -413,17 +413,17 @@ void ScrollContainer::update_scrollbars() { Size2 hmin; Size2 vmin; - if (scroll_h) { + if (horizontal_scroll_mode != SCROLL_MODE_DISABLED) { hmin = h_scroll->get_combined_minimum_size(); } - if (scroll_v) { + if (vertical_scroll_mode != SCROLL_MODE_DISABLED) { vmin = v_scroll->get_combined_minimum_size(); } Size2 min = child_max_size; - bool hide_scroll_h = !scroll_h || min.width <= size.width || !h_scroll_visible; - bool hide_scroll_v = !scroll_v || min.height <= size.height || !v_scroll_visible; + bool hide_scroll_h = horizontal_scroll_mode != SCROLL_MODE_SHOW_ALWAYS && (horizontal_scroll_mode == SCROLL_MODE_DISABLED || horizontal_scroll_mode == SCROLL_MODE_SHOW_NEVER || (horizontal_scroll_mode == SCROLL_MODE_AUTO && min.width <= size.width)); + bool hide_scroll_v = vertical_scroll_mode != SCROLL_MODE_SHOW_ALWAYS && (vertical_scroll_mode == SCROLL_MODE_DISABLED || vertical_scroll_mode == SCROLL_MODE_SHOW_NEVER || (vertical_scroll_mode == SCROLL_MODE_AUTO && min.height <= size.height)); h_scroll->set_max(min.width); h_scroll->set_page(size.width - (hide_scroll_v ? 0 : vmin.width)); @@ -461,58 +461,32 @@ int ScrollContainer::get_v_scroll() const { return v_scroll->get_value(); } -void ScrollContainer::set_enable_h_scroll(bool p_enable) { - if (scroll_h == p_enable) { +void ScrollContainer::set_horizontal_scroll_mode(ScrollMode p_mode) { + if (horizontal_scroll_mode == p_mode) { return; } - scroll_h = p_enable; - minimum_size_changed(); + horizontal_scroll_mode = p_mode; + update_minimum_size(); queue_sort(); } -bool ScrollContainer::is_h_scroll_enabled() const { - return scroll_h; +ScrollContainer::ScrollMode ScrollContainer::get_horizontal_scroll_mode() const { + return horizontal_scroll_mode; } -void ScrollContainer::set_enable_v_scroll(bool p_enable) { - if (scroll_v == p_enable) { +void ScrollContainer::set_vertical_scroll_mode(ScrollMode p_mode) { + if (vertical_scroll_mode == p_mode) { return; } - scroll_v = p_enable; - minimum_size_changed(); + vertical_scroll_mode = p_mode; + update_minimum_size(); queue_sort(); } -bool ScrollContainer::is_v_scroll_enabled() const { - return scroll_v; -} - -void ScrollContainer::set_h_scroll_visible(bool p_visible) { - if (h_scroll_visible == p_visible) { - return; - } - - h_scroll_visible = p_visible; - update_scrollbars(); -} - -bool ScrollContainer::is_h_scroll_visible() const { - return h_scroll_visible; -} - -void ScrollContainer::set_v_scroll_visible(bool p_visible) { - if (v_scroll_visible == p_visible) { - return; - } - - v_scroll_visible = p_visible; - update_scrollbars(); -} - -bool ScrollContainer::is_v_scroll_visible() const { - return v_scroll_visible; +ScrollContainer::ScrollMode ScrollContainer::get_vertical_scroll_mode() const { + return vertical_scroll_mode; } int ScrollContainer::get_deadzone() const { @@ -558,11 +532,11 @@ TypedArray<String> ScrollContainer::get_configuration_warnings() const { return warnings; } -HScrollBar *ScrollContainer::get_h_scrollbar() { +HScrollBar *ScrollContainer::get_h_scroll_bar() { return h_scroll; } -VScrollBar *ScrollContainer::get_v_scrollbar() { +VScrollBar *ScrollContainer::get_v_scroll_bar() { return v_scroll; } @@ -575,17 +549,11 @@ void ScrollContainer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_v_scroll", "value"), &ScrollContainer::set_v_scroll); ClassDB::bind_method(D_METHOD("get_v_scroll"), &ScrollContainer::get_v_scroll); - ClassDB::bind_method(D_METHOD("set_enable_h_scroll", "enable"), &ScrollContainer::set_enable_h_scroll); - ClassDB::bind_method(D_METHOD("is_h_scroll_enabled"), &ScrollContainer::is_h_scroll_enabled); - - ClassDB::bind_method(D_METHOD("set_enable_v_scroll", "enable"), &ScrollContainer::set_enable_v_scroll); - ClassDB::bind_method(D_METHOD("is_v_scroll_enabled"), &ScrollContainer::is_v_scroll_enabled); + ClassDB::bind_method(D_METHOD("set_horizontal_scroll_mode", "enable"), &ScrollContainer::set_horizontal_scroll_mode); + ClassDB::bind_method(D_METHOD("get_horizontal_scroll_mode"), &ScrollContainer::get_horizontal_scroll_mode); - ClassDB::bind_method(D_METHOD("set_h_scroll_visible", "visible"), &ScrollContainer::set_h_scroll_visible); - ClassDB::bind_method(D_METHOD("is_h_scroll_visible"), &ScrollContainer::is_h_scroll_visible); - - ClassDB::bind_method(D_METHOD("set_v_scroll_visible", "visible"), &ScrollContainer::set_v_scroll_visible); - ClassDB::bind_method(D_METHOD("is_v_scroll_visible"), &ScrollContainer::is_v_scroll_visible); + ClassDB::bind_method(D_METHOD("set_vertical_scroll_mode", "enable"), &ScrollContainer::set_vertical_scroll_mode); + ClassDB::bind_method(D_METHOD("get_vertical_scroll_mode"), &ScrollContainer::get_vertical_scroll_mode); ClassDB::bind_method(D_METHOD("set_deadzone", "deadzone"), &ScrollContainer::set_deadzone); ClassDB::bind_method(D_METHOD("get_deadzone"), &ScrollContainer::get_deadzone); @@ -593,8 +561,8 @@ void ScrollContainer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_follow_focus", "enabled"), &ScrollContainer::set_follow_focus); ClassDB::bind_method(D_METHOD("is_following_focus"), &ScrollContainer::is_following_focus); - ClassDB::bind_method(D_METHOD("get_h_scrollbar"), &ScrollContainer::get_h_scrollbar); - ClassDB::bind_method(D_METHOD("get_v_scrollbar"), &ScrollContainer::get_v_scrollbar); + ClassDB::bind_method(D_METHOD("get_h_scroll_bar"), &ScrollContainer::get_h_scroll_bar); + ClassDB::bind_method(D_METHOD("get_v_scroll_bar"), &ScrollContainer::get_v_scroll_bar); ClassDB::bind_method(D_METHOD("ensure_control_visible", "control"), &ScrollContainer::ensure_control_visible); ADD_SIGNAL(MethodInfo("scroll_started")); @@ -605,12 +573,15 @@ void ScrollContainer::_bind_methods() { ADD_GROUP("Scroll", "scroll_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "scroll_horizontal"), "set_h_scroll", "get_h_scroll"); ADD_PROPERTY(PropertyInfo(Variant::INT, "scroll_vertical"), "set_v_scroll", "get_v_scroll"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_horizontal_enabled"), "set_enable_h_scroll", "is_h_scroll_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_vertical_enabled"), "set_enable_v_scroll", "is_v_scroll_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_horizontal_visible"), "set_h_scroll_visible", "is_h_scroll_visible"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_vertical_visible"), "set_v_scroll_visible", "is_v_scroll_visible"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "horizontal_scroll_mode", PROPERTY_HINT_ENUM, "Disabled,Auto,Always Show,Never Show"), "set_horizontal_scroll_mode", "get_horizontal_scroll_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "vertical_scroll_mode", PROPERTY_HINT_ENUM, "Disabled,Auto,Always Show,Never Show"), "set_vertical_scroll_mode", "get_vertical_scroll_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "scroll_deadzone"), "set_deadzone", "get_deadzone"); + BIND_ENUM_CONSTANT(SCROLL_MODE_DISABLED); + BIND_ENUM_CONSTANT(SCROLL_MODE_AUTO); + BIND_ENUM_CONSTANT(SCROLL_MODE_SHOW_ALWAYS); + BIND_ENUM_CONSTANT(SCROLL_MODE_SHOW_NEVER); + GLOBAL_DEF("gui/common/default_scroll_deadzone", 0); }; diff --git a/scene/gui/scroll_container.h b/scene/gui/scroll_container.h index 9c87d07f66..c00df87b18 100644 --- a/scene/gui/scroll_container.h +++ b/scene/gui/scroll_container.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -38,6 +38,15 @@ class ScrollContainer : public Container { GDCLASS(ScrollContainer, Container); +public: + enum ScrollMode { + SCROLL_MODE_DISABLED = 0, + SCROLL_MODE_AUTO, + SCROLL_MODE_SHOW_ALWAYS, + SCROLL_MODE_SHOW_NEVER, + }; + +private: HScrollBar *h_scroll; VScrollBar *v_scroll; @@ -54,11 +63,8 @@ class ScrollContainer : public Container { bool drag_touching_deaccel = false; bool beyond_deadzone = false; - bool scroll_h = true; - bool scroll_v = true; - - bool h_scroll_visible = true; - bool v_scroll_visible = true; + ScrollMode horizontal_scroll_mode = SCROLL_MODE_AUTO; + ScrollMode vertical_scroll_mode = SCROLL_MODE_AUTO; int deadzone = 0; bool follow_focus = false; @@ -87,17 +93,11 @@ public: void set_v_scroll(int p_pos); int get_v_scroll() const; - void set_enable_h_scroll(bool p_enable); - bool is_h_scroll_enabled() const; - - void set_enable_v_scroll(bool p_enable); - bool is_v_scroll_enabled() const; + void set_horizontal_scroll_mode(ScrollMode p_mode); + ScrollMode get_horizontal_scroll_mode() const; - void set_h_scroll_visible(bool p_visible); - bool is_h_scroll_visible() const; - - void set_v_scroll_visible(bool p_visible); - bool is_v_scroll_visible() const; + void set_vertical_scroll_mode(ScrollMode p_mode); + ScrollMode get_vertical_scroll_mode() const; int get_deadzone() const; void set_deadzone(int p_deadzone); @@ -105,8 +105,8 @@ public: bool is_following_focus() const; void set_follow_focus(bool p_follow); - HScrollBar *get_h_scrollbar(); - VScrollBar *get_v_scrollbar(); + HScrollBar *get_h_scroll_bar(); + VScrollBar *get_v_scroll_bar(); void ensure_control_visible(Control *p_control); TypedArray<String> get_configuration_warnings() const override; @@ -114,4 +114,6 @@ public: ScrollContainer(); }; +VARIANT_ENUM_CAST(ScrollContainer::ScrollMode); + #endif diff --git a/scene/gui/separator.cpp b/scene/gui/separator.cpp index 1f3cb7aa24..9c19eb54dc 100644 --- a/scene/gui/separator.cpp +++ b/scene/gui/separator.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/separator.h b/scene/gui/separator.h index 77162c68fa..1621bb3351 100644 --- a/scene/gui/separator.h +++ b/scene/gui/separator.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp index 4cc425aad3..1d459d589f 100644 --- a/scene/gui/slider.cpp +++ b/scene/gui/slider.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -70,8 +70,13 @@ void Slider::gui_input(const Ref<InputEvent> &p_event) { } grab.active = true; grab.uvalue = get_as_ratio(); + + emit_signal(SNAME("drag_started")); } else { grab.active = false; + + const bool value_changed = !Math::is_equal_approx((double)grab.uvalue, get_as_ratio()); + emit_signal(SNAME("drag_ended"), value_changed); } } else if (scrollable) { if (mb->is_pressed() && mb->get_button_index() == MouseButton::WHEEL_UP) { @@ -142,7 +147,7 @@ void Slider::gui_input(const Ref<InputEvent> &p_event) { void Slider::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: { - minimum_size_changed(); + update_minimum_size(); update(); } break; case NOTIFICATION_MOUSE_ENTER: { @@ -264,6 +269,9 @@ void Slider::_bind_methods() { ClassDB::bind_method(D_METHOD("set_scrollable", "scrollable"), &Slider::set_scrollable); ClassDB::bind_method(D_METHOD("is_scrollable"), &Slider::is_scrollable); + ADD_SIGNAL(MethodInfo("drag_started")); + ADD_SIGNAL(MethodInfo("drag_ended", PropertyInfo(Variant::BOOL, "value_changed"))); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editable"), "set_editable", "is_editable"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scrollable"), "set_scrollable", "is_scrollable"); ADD_PROPERTY(PropertyInfo(Variant::INT, "tick_count", PROPERTY_HINT_RANGE, "0,4096,1"), "set_ticks", "get_ticks"); diff --git a/scene/gui/slider.h b/scene/gui/slider.h index 46fa08bbf0..5fbfee2aec 100644 --- a/scene/gui/slider.h +++ b/scene/gui/slider.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp index f30206c943..19d47ea492 100644 --- a/scene/gui/spin_box.cpp +++ b/scene/gui/spin_box.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -41,10 +41,10 @@ Size2 SpinBox::get_minimum_size() const { void SpinBox::_value_changed(double) { String value = TS->format_number(String::num(get_value(), Math::range_step_decimals(get_step()))); - if (prefix != "") { + if (!prefix.is_empty()) { value = prefix + " " + value; } - if (suffix != "") { + if (!suffix.is_empty()) { value += " " + suffix; } line_edit->set_text(value); @@ -220,19 +220,19 @@ void SpinBox::_notification(int p_what) { } else if (p_what == NOTIFICATION_TRANSLATION_CHANGED) { _value_changed(0); } else if (p_what == NOTIFICATION_THEME_CHANGED) { - call_deferred(SNAME("minimum_size_changed")); - get_line_edit()->call_deferred(SNAME("minimum_size_changed")); + call_deferred(SNAME("update_minimum_size")); + get_line_edit()->call_deferred(SNAME("update_minimum_size")); } else if (p_what == NOTIFICATION_LAYOUT_DIRECTION_CHANGED || p_what == NOTIFICATION_TRANSLATION_CHANGED) { update(); } } -void SpinBox::set_align(LineEdit::Align p_align) { - line_edit->set_align(p_align); +void SpinBox::set_horizontal_alignment(HorizontalAlignment p_alignment) { + line_edit->set_horizontal_alignment(p_alignment); } -LineEdit::Align SpinBox::get_align() const { - return line_edit->get_align(); +HorizontalAlignment SpinBox::get_horizontal_alignment() const { + return line_edit->get_horizontal_alignment(); } void SpinBox::set_suffix(const String &p_suffix) { @@ -284,8 +284,8 @@ void SpinBox::apply() { } void SpinBox::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_align", "align"), &SpinBox::set_align); - ClassDB::bind_method(D_METHOD("get_align"), &SpinBox::get_align); + ClassDB::bind_method(D_METHOD("set_horizontal_alignment", "alignment"), &SpinBox::set_horizontal_alignment); + ClassDB::bind_method(D_METHOD("get_horizontal_alignment"), &SpinBox::get_horizontal_alignment); ClassDB::bind_method(D_METHOD("set_suffix", "suffix"), &SpinBox::set_suffix); ClassDB::bind_method(D_METHOD("get_suffix"), &SpinBox::get_suffix); ClassDB::bind_method(D_METHOD("set_prefix", "prefix"), &SpinBox::set_prefix); @@ -297,7 +297,7 @@ void SpinBox::_bind_methods() { ClassDB::bind_method(D_METHOD("apply"), &SpinBox::apply); ClassDB::bind_method(D_METHOD("get_line_edit"), &SpinBox::get_line_edit); - ADD_PROPERTY(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_align", "get_align"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "alignment", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_horizontal_alignment", "get_horizontal_alignment"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editable"), "set_editable", "is_editable"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "update_on_text_changed"), "set_update_on_text_changed", "get_update_on_text_changed"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "prefix"), "set_prefix", "get_prefix"); @@ -310,7 +310,7 @@ SpinBox::SpinBox() { line_edit->set_anchors_and_offsets_preset(Control::PRESET_WIDE); line_edit->set_mouse_filter(MOUSE_FILTER_PASS); - line_edit->set_align(LineEdit::ALIGN_LEFT); + line_edit->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_LEFT); line_edit->connect("text_submitted", callable_mp(this, &SpinBox::_text_submitted), Vector<Variant>(), CONNECT_DEFERRED); line_edit->connect("focus_exited", callable_mp(this, &SpinBox::_line_edit_focus_exit), Vector<Variant>(), CONNECT_DEFERRED); diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h index f2299ce1c2..0691a4b48d 100644 --- a/scene/gui/spin_box.h +++ b/scene/gui/spin_box.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -79,8 +79,8 @@ public: virtual Size2 get_minimum_size() const override; - void set_align(LineEdit::Align p_align); - LineEdit::Align get_align() const; + void set_horizontal_alignment(HorizontalAlignment p_alignment); + HorizontalAlignment get_horizontal_alignment() const; void set_editable(bool p_enabled); bool is_editable() const; diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp index 6b53c0220e..874e5868b6 100644 --- a/scene/gui/split_container.cpp +++ b/scene/gui/split_container.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -201,7 +201,7 @@ void SplitContainer::_notification(int p_what) { } } break; case NOTIFICATION_THEME_CHANGED: { - minimum_size_changed(); + update_minimum_size(); } break; } } diff --git a/scene/gui/split_container.h b/scene/gui/split_container.h index 47fd30a122..ba6fff6f55 100644 --- a/scene/gui/split_container.h +++ b/scene/gui/split_container.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/subviewport_container.cpp b/scene/gui/subviewport_container.cpp index 53ea32e1b7..760144591e 100644 --- a/scene/gui/subviewport_container.cpp +++ b/scene/gui/subviewport_container.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -54,6 +54,7 @@ Size2 SubViewportContainer::get_minimum_size() const { void SubViewportContainer::set_stretch(bool p_enable) { stretch = p_enable; + update_minimum_size(); queue_sort(); update(); } diff --git a/scene/gui/subviewport_container.h b/scene/gui/subviewport_container.h index 7853f1590e..e7520763fb 100644 --- a/scene/gui/subviewport_container.h +++ b/scene/gui/subviewport_container.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/tab_bar.cpp b/scene/gui/tab_bar.cpp index c7d5a600a1..9da030f0a2 100644 --- a/scene/gui/tab_bar.cpp +++ b/scene/gui/tab_bar.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -50,7 +50,7 @@ Size2 TabBar::get_minimum_size() const { Ref<Texture2D> tex = tabs[i].icon; if (tex.is_valid()) { ms.height = MAX(ms.height, tex->get_size().height); - if (tabs[i].text != "") { + if (!tabs[i].text.is_empty()) { ms.width += get_theme_constant(SNAME("hseparation")); } } @@ -147,6 +147,7 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) { if (scrolling_enabled && buttons_visible) { if (offset > 0) { offset--; + _update_cache(); update(); } } @@ -154,9 +155,9 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) { if (mb->is_pressed() && mb->get_button_index() == MouseButton::WHEEL_DOWN && !mb->is_command_pressed()) { if (scrolling_enabled && buttons_visible) { - if (missing_right) { + if (missing_right && offset < tabs.size()) { offset++; - _ensure_no_over_offset(); // Avoid overreaching when scrolling fast. + _update_cache(); update(); } } @@ -194,12 +195,14 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) { if (pos.x < decr->get_width()) { if (missing_right) { offset++; + _update_cache(); update(); } return; } else if (pos.x < incr->get_width() + decr->get_width()) { if (offset > 0) { offset--; + _update_cache(); update(); } return; @@ -209,12 +212,14 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) { if (pos.x > limit + decr->get_width()) { if (missing_right) { offset++; + _update_cache(); update(); } return; } else if (pos.x > limit) { if (offset > 0) { offset--; + _update_cache(); update(); } return; @@ -270,7 +275,7 @@ 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.write[p_tab].xl_text, font, font_size, tabs[p_tab].opentype_features, (tabs[p_tab].language != "") ? tabs[p_tab].language : TranslationServer::get_singleton()->get_tool_locale()); + tabs.write[p_tab].text_buf->add_string(tabs.write[p_tab].xl_text, font, font_size, tabs[p_tab].opentype_features, !tabs[p_tab].language.is_empty() ? tabs[p_tab].language : TranslationServer::get_singleton()->get_tool_locale()); } void TabBar::_notification(int p_what) { @@ -285,7 +290,7 @@ void TabBar::_notification(int p_what) { _shape(i); } _update_cache(); - minimum_size_changed(); + update_minimum_size(); update(); } break; case NOTIFICATION_RESIZED: { @@ -294,8 +299,9 @@ void TabBar::_notification(int p_what) { ensure_tab_visible(current); } break; case NOTIFICATION_DRAW: { - _update_cache(); - RID ci = get_canvas_item(); + if (tabs.is_empty()) { + return; + } Ref<StyleBox> tab_unselected = get_theme_stylebox(SNAME("tab_unselected")); Ref<StyleBox> tab_selected = get_theme_stylebox(SNAME("tab_selected")); @@ -303,174 +309,46 @@ void TabBar::_notification(int p_what) { 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> close = get_theme_icon(SNAME("close")); - Color font_outline_color = get_theme_color(SNAME("font_outline_color")); - int outline_size = get_theme_constant(SNAME("outline_size")); - - Vector2 size = get_size(); - bool rtl = is_layout_rtl(); - - int h = get_size().height; - int w = 0; - int mw = 0; - - for (int i = 0; i < tabs.size(); i++) { - tabs.write[i].ofs_cache = mw; - mw += get_tab_width(i); - } - - if (tab_align == ALIGN_CENTER) { - w = (get_size().width - mw) / 2; - } else if (tab_align == ALIGN_RIGHT) { - w = get_size().width - mw; - } - - if (w < 0) { - w = 0; - } - Ref<Texture2D> incr = get_theme_icon(SNAME("increment")); Ref<Texture2D> decr = get_theme_icon(SNAME("decrement")); Ref<Texture2D> incr_hl = get_theme_icon(SNAME("increment_highlight")); Ref<Texture2D> decr_hl = get_theme_icon(SNAME("decrement_highlight")); - int limit = get_size().width; - int limit_minus_buttons = get_size().width - incr->get_width() - decr->get_width(); - - missing_right = false; - - for (int i = offset; i < tabs.size(); i++) { - tabs.write[i].ofs_cache = w; - - int lsize = tabs[i].size_cache; - - Ref<StyleBox> sb; - Color col; - - if (tabs[i].disabled) { - sb = tab_disabled; - col = font_disabled_color; - } else if (i == current) { - sb = tab_selected; - col = font_selected_color; - } else { - sb = tab_unselected; - col = font_unselected_color; - } - - int new_width = w + lsize; - if (new_width > limit || (i < tabs.size() - 1 && new_width > limit_minus_buttons)) { // For the last tab, we accept if the tab covers the buttons. - max_drawn_tab = i - 1; - missing_right = true; - break; - } else { - max_drawn_tab = i; - } - - Rect2 sb_rect; - if (rtl) { - sb_rect = Rect2(size.width - w - tabs[i].size_cache, 0, tabs[i].size_cache, h); - } else { - sb_rect = Rect2(w, 0, tabs[i].size_cache, h); - } - sb->draw(ci, sb_rect); - - w += sb->get_margin(SIDE_LEFT); - - Size2i sb_ms = sb->get_minimum_size(); - Ref<Texture2D> icon = tabs[i].icon; - if (icon.is_valid()) { - if (rtl) { - icon->draw(ci, Point2i(size.width - w - icon->get_width(), sb->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - icon->get_height()) / 2)); - } else { - icon->draw(ci, Point2i(w, sb->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - icon->get_height()) / 2)); - } - if (tabs[i].text != "") { - w += icon->get_width() + get_theme_constant(SNAME("hseparation")); - } - } - - if (rtl) { - Vector2 text_pos = Point2i(size.width - w - tabs[i].text_buf->get_size().x, sb->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - tabs[i].text_buf->get_size().y) / 2); - if (outline_size > 0 && font_outline_color.a > 0) { - tabs[i].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color); - } - tabs[i].text_buf->draw(ci, text_pos, col); - } else { - Vector2 text_pos = Point2i(w, sb->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - tabs[i].text_buf->get_size().y) / 2); - if (outline_size > 0 && font_outline_color.a > 0) { - tabs[i].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color); - } - tabs[i].text_buf->draw(ci, text_pos, col); - } - - w += tabs[i].size_text; - - if (tabs[i].right_button.is_valid()) { - Ref<StyleBox> style = get_theme_stylebox(SNAME("close_bg_highlight")); - Ref<Texture2D> rb = tabs[i].right_button; + bool rtl = is_layout_rtl(); + Vector2 size = get_size(); + int limit_minus_buttons = size.width - incr->get_width() - decr->get_width(); - w += get_theme_constant(SNAME("hseparation")); + int ofs = tabs[offset].ofs_cache; - Rect2 rb_rect; - rb_rect.size = style->get_minimum_size() + rb->get_size(); - if (rtl) { - rb_rect.position.x = size.width - w - rb_rect.size.x; + // Draw unselected tabs in the back. + for (int i = offset; i <= max_drawn_tab; i++) { + if (i != current) { + Ref<StyleBox> sb; + Color col; + + if (tabs[i].disabled) { + sb = tab_disabled; + col = font_disabled_color; + } else if (i == current) { + sb = tab_selected; + col = font_selected_color; } else { - rb_rect.position.x = w; + sb = tab_unselected; + col = font_unselected_color; } - rb_rect.position.y = sb->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - (rb_rect.size.y)) / 2; - if (rb_hover == i) { - if (rb_pressing) { - get_theme_stylebox(SNAME("button_pressed"))->draw(ci, rb_rect); - } else { - style->draw(ci, rb_rect); - } - } - - if (rtl) { - rb->draw(ci, Point2i(size.width - w - rb_rect.size.x + style->get_margin(SIDE_LEFT), rb_rect.position.y + style->get_margin(SIDE_TOP))); - } else { - rb->draw(ci, Point2i(w + style->get_margin(SIDE_LEFT), rb_rect.position.y + style->get_margin(SIDE_TOP))); - } - w += rb->get_width(); - tabs.write[i].rb_rect = rb_rect; + _draw_tab(sb, col, i, rtl ? size.width - ofs - tabs[i].size_cache : ofs); } - if (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && i == current)) { - Ref<StyleBox> style = get_theme_stylebox(SNAME("close_bg_highlight")); - Ref<Texture2D> cb = close; - - w += get_theme_constant(SNAME("hseparation")); - - Rect2 cb_rect; - cb_rect.size = style->get_minimum_size() + cb->get_size(); - if (rtl) { - cb_rect.position.x = size.width - w - cb_rect.size.x; - } else { - cb_rect.position.x = w; - } - cb_rect.position.y = sb->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - (cb_rect.size.y)) / 2; - - if (!tabs[i].disabled && cb_hover == i) { - if (cb_pressing) { - get_theme_stylebox(SNAME("close_bg_pressed"))->draw(ci, cb_rect); - } else { - style->draw(ci, cb_rect); - } - } + ofs += tabs[i].size_cache; + } - if (rtl) { - cb->draw(ci, Point2i(size.width - w - cb_rect.size.x + style->get_margin(SIDE_LEFT), cb_rect.position.y + style->get_margin(SIDE_TOP))); - } else { - cb->draw(ci, Point2i(w + style->get_margin(SIDE_LEFT), cb_rect.position.y + style->get_margin(SIDE_TOP))); - } - w += cb->get_width(); - tabs.write[i].cb_rect = cb_rect; - } + // Draw selected tab in the front, but only if it's visible. + if (current >= offset && current <= max_drawn_tab) { + Ref<StyleBox> sb = tabs[current].disabled ? tab_disabled : tab_selected; + float x = rtl ? size.width - tabs[current].ofs_cache - tabs[current].size_cache : tabs[current].ofs_cache; - w += sb->get_margin(SIDE_RIGHT); + _draw_tab(sb, font_selected_color, current, x); } if (offset > 0 || missing_right) { @@ -501,13 +379,98 @@ void TabBar::_notification(int p_what) { draw_texture(incr, Point2(limit_minus_buttons + decr->get_size().width, vofs), Color(1, 1, 1, 0.5)); } } + } + } break; + } +} + +void TabBar::_draw_tab(Ref<StyleBox> &p_tab_style, Color &p_font_color, int p_index, float p_x) { + RID ci = get_canvas_item(); + + Color font_outline_color = get_theme_color(SNAME("font_outline_color")); + int outline_size = get_theme_constant(SNAME("outline_size")); + + Tab tab = tabs[p_index]; - buttons_visible = true; + Rect2 sb_rect = Rect2(p_x, 0, tab.size_cache, get_size().height); + p_tab_style->draw(ci, sb_rect); + + p_x += p_tab_style->get_margin(SIDE_LEFT); + + Size2i sb_ms = p_tab_style->get_minimum_size(); + + Ref<Texture2D> icon = tab.icon; + if (icon.is_valid()) { + icon->draw(ci, Point2i(p_x, p_tab_style->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - icon->get_height()) / 2)); + + if (!tab.text.is_empty()) { + p_x += icon->get_width() + get_theme_constant(SNAME("hseparation")); + } + } + + Vector2 text_pos = Point2i(p_x, p_tab_style->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - tab.text_buf->get_size().y) / 2); + if (outline_size > 0 && font_outline_color.a > 0) { + tab.text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color); + } + tab.text_buf->draw(ci, text_pos, p_font_color); + + p_x += tab.size_text; + + if (tab.right_button.is_valid()) { + Ref<StyleBox> style = get_theme_stylebox(SNAME("close_bg_highlight")); + Ref<Texture2D> rb = tab.right_button; + + p_x += get_theme_constant(SNAME("hseparation")); + + Rect2 rb_rect; + rb_rect.size = style->get_minimum_size() + rb->get_size(); + rb_rect.position.x = p_x; + rb_rect.position.y = p_tab_style->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - (rb_rect.size.y)) / 2; + + if (rb_hover == p_index) { + if (rb_pressing) { + get_theme_stylebox(SNAME("button_pressed"))->draw(ci, rb_rect); } else { - buttons_visible = false; + style->draw(ci, rb_rect); } - } break; + } + + rb->draw(ci, Point2i(p_x + style->get_margin(SIDE_LEFT), rb_rect.position.y + style->get_margin(SIDE_TOP))); + p_x += rb->get_width(); + tabs.write[p_index].rb_rect = rb_rect; } + + if (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && p_index == current)) { + Ref<StyleBox> style = get_theme_stylebox(SNAME("close_bg_highlight")); + Ref<Texture2D> cb = get_theme_icon(SNAME("close")); + + p_x += get_theme_constant(SNAME("hseparation")); + + Rect2 cb_rect; + cb_rect.size = style->get_minimum_size() + cb->get_size(); + cb_rect.position.x = p_x; + cb_rect.position.y = p_tab_style->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - (cb_rect.size.y)) / 2; + + if (!tab.disabled && cb_hover == p_index) { + if (cb_pressing) { + get_theme_stylebox(SNAME("close_bg_pressed"))->draw(ci, cb_rect); + } else { + style->draw(ci, cb_rect); + } + } + + cb->draw(ci, Point2i(p_x + style->get_margin(SIDE_LEFT), cb_rect.position.y + style->get_margin(SIDE_TOP))); + p_x += cb->get_width(); + tabs.write[p_index].cb_rect = cb_rect; + } +} + +void TabBar::set_tab_count(int p_count) { + ERR_FAIL_COND(p_count < 0); + tabs.resize(p_count); + _update_cache(); + update(); + notify_property_list_changed(); } int TabBar::get_tab_count() const { @@ -553,8 +516,9 @@ void TabBar::set_tab_title(int p_tab, const String &p_title) { ERR_FAIL_INDEX(p_tab, tabs.size()); tabs.write[p_tab].text = p_title; _shape(p_tab); + _update_cache(); update(); - minimum_size_changed(); + update_minimum_size(); } String TabBar::get_tab_title(int p_tab) const { @@ -581,6 +545,7 @@ void TabBar::clear_tab_opentype_features(int p_tab) { ERR_FAIL_INDEX(p_tab, tabs.size()); tabs.write[p_tab].opentype_features.clear(); _shape(p_tab); + _update_cache(); update(); } @@ -590,6 +555,7 @@ void TabBar::set_tab_opentype_feature(int p_tab, const String &p_name, int p_val if (!tabs[p_tab].opentype_features.has(tag) || (int)tabs[p_tab].opentype_features[tag] != p_value) { tabs.write[p_tab].opentype_features[tag] = p_value; _shape(p_tab); + _update_cache(); update(); } } @@ -620,8 +586,9 @@ String TabBar::get_tab_language(int p_tab) const { void TabBar::set_tab_icon(int p_tab, const Ref<Texture2D> &p_icon) { ERR_FAIL_INDEX(p_tab, tabs.size()); tabs.write[p_tab].icon = p_icon; + _update_cache(); update(); - minimum_size_changed(); + update_minimum_size(); } Ref<Texture2D> TabBar::get_tab_icon(int p_tab) const { @@ -635,7 +602,7 @@ void TabBar::set_tab_disabled(int p_tab, bool p_disabled) { update(); } -bool TabBar::get_tab_disabled(int p_tab) const { +bool TabBar::is_tab_disabled(int p_tab) const { ERR_FAIL_INDEX_V(p_tab, tabs.size(), false); return tabs[p_tab].disabled; } @@ -645,7 +612,7 @@ void TabBar::set_tab_right_button(int p_tab, const Ref<Texture2D> &p_right_butto tabs.write[p_tab].right_button = p_right_button; _update_cache(); update(); - minimum_size_changed(); + update_minimum_size(); } Ref<Texture2D> TabBar::get_tab_right_button(int p_tab) const { @@ -691,33 +658,43 @@ void TabBar::_update_hover() { } void TabBar::_update_cache() { + if (tabs.is_empty()) { + 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_minus_buttons = get_size().width - incr->get_width() - decr->get_width(); + + int limit = get_size().width; + int limit_minus_buttons = limit - incr->get_width() - decr->get_width(); int w = 0; int mw = 0; int size_fixed = 0; int count_resize = 0; + for (int i = 0; i < tabs.size(); i++) { - tabs.write[i].ofs_cache = mw; + tabs.write[i].ofs_cache = 0; tabs.write[i].size_cache = get_tab_width(i); tabs.write[i].size_text = Math::ceil(tabs[i].text_buf->get_size().x); tabs.write[i].text_buf->set_width(-1); mw += tabs[i].size_cache; + if (tabs[i].size_cache <= min_width || i == current) { size_fixed += tabs[i].size_cache; } else { count_resize++; } } + int m_width = min_width; if (count_resize > 0) { m_width = MAX((limit_minus_buttons - size_fixed) / count_resize, min_width); } + for (int i = offset; i < tabs.size(); i++) { Ref<StyleBox> sb; if (tabs[i].disabled) { @@ -727,11 +704,13 @@ void TabBar::_update_cache() { } else { sb = tab_unselected; } + int lsize = tabs[i].size_cache; int slen = tabs[i].size_text; if (min_width > 0 && mw > limit_minus_buttons && i != current) { if (lsize > m_width) { slen = m_width - (sb->get_margin(SIDE_LEFT) + sb->get_margin(SIDE_RIGHT)); + if (tabs[i].icon.is_valid()) { slen -= tabs[i].icon->get_width(); slen -= get_theme_constant(SNAME("hseparation")); @@ -741,15 +720,52 @@ void TabBar::_update_cache() { slen -= cb->get_width(); slen -= get_theme_constant(SNAME("hseparation")); } + slen = MAX(slen, 1); lsize = m_width; } } + tabs.write[i].ofs_cache = w; tabs.write[i].size_cache = lsize; tabs.write[i].size_text = slen; tabs.write[i].text_buf->set_width(slen); + w += lsize; + max_drawn_tab = i; + + // Check if all tabs would fit inside the area. + if (i > offset && (w > limit || (offset > 0 && w > limit_minus_buttons))) { + w -= get_tab_width(i); + max_drawn_tab -= 1; + + while (w > limit_minus_buttons && max_drawn_tab > offset) { + w -= get_tab_width(max_drawn_tab); + max_drawn_tab -= 1; + } + + break; + } + } + + missing_right = max_drawn_tab < tabs.size() - 1; + buttons_visible = offset > 0 || missing_right; + + if (tab_alignment == ALIGNMENT_LEFT) { + return; + } else if (tab_alignment == ALIGNMENT_CENTER) { + w = ((buttons_visible ? limit_minus_buttons : limit) - w) / 2; + } else if (tab_alignment == ALIGNMENT_RIGHT) { + w = (buttons_visible ? limit_minus_buttons : limit) - w; + } + + if (w < 0) { + w = 0; + } + + for (int i = offset; i <= max_drawn_tab; i++) { + tabs.write[i].ofs_cache = w; + w += tabs.write[i].size_cache; } } @@ -765,19 +781,15 @@ void TabBar::add_tab(const String &p_str, const Ref<Texture2D> &p_icon) { Tab t; t.text = p_str; t.xl_text = atr(p_str); - t.text_buf.instantiate(); t.text_buf->set_direction(is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR); t.text_buf->add_string(t.xl_text, get_theme_font(SNAME("font")), get_theme_font_size(SNAME("font_size")), Dictionary(), TranslationServer::get_singleton()->get_tool_locale()); t.icon = p_icon; - t.disabled = false; - t.ofs_cache = 0; - t.size_cache = 0; tabs.push_back(t); _update_cache(); call_deferred(SNAME("_update_hover")); update(); - minimum_size_changed(); + update_minimum_size(); } void TabBar::clear_tabs() { @@ -786,6 +798,7 @@ void TabBar::clear_tabs() { previous = 0; call_deferred(SNAME("_update_hover")); update(); + notify_property_list_changed(); } void TabBar::remove_tab(int p_idx) { @@ -797,7 +810,7 @@ void TabBar::remove_tab(int p_idx) { _update_cache(); call_deferred(SNAME("_update_hover")); update(); - minimum_size_changed(); + update_minimum_size(); if (current < 0) { current = 0; @@ -808,6 +821,7 @@ void TabBar::remove_tab(int p_idx) { } _ensure_no_over_offset(); + notify_property_list_changed(); } Variant TabBar::get_drag_data(const Point2 &p_point) { @@ -911,10 +925,10 @@ void TabBar::drop_data(const Point2 &p_point, const Variant &p_data) { set_current_tab(hover_now); emit_signal(SNAME("tab_changed"), hover_now); _update_cache(); + update(); } } } - update(); } int TabBar::get_tab_idx_at_point(const Point2 &p_point) const { @@ -929,14 +943,15 @@ int TabBar::get_tab_idx_at_point(const Point2 &p_point) const { return hover_now; } -void TabBar::set_tab_align(TabAlign p_align) { - ERR_FAIL_INDEX(p_align, ALIGN_MAX); - tab_align = p_align; +void TabBar::set_tab_alignment(AlignmentMode p_alignment) { + ERR_FAIL_INDEX(p_alignment, ALIGNMENT_MAX); + tab_alignment = p_alignment; + _update_cache(); update(); } -TabBar::TabAlign TabBar::get_tab_align() const { - return tab_align; +TabBar::AlignmentMode TabBar::get_tab_alignment() const { + return tab_alignment; } void TabBar::set_clip_tabs(bool p_clip_tabs) { @@ -944,8 +959,9 @@ void TabBar::set_clip_tabs(bool p_clip_tabs) { return; } clip_tabs = p_clip_tabs; + _update_cache(); update(); - minimum_size_changed(); + update_minimum_size(); } bool TabBar::get_clip_tabs() const { @@ -966,6 +982,7 @@ void TabBar::move_tab(int from, int to) { _update_cache(); update(); + notify_property_list_changed(); } int TabBar::get_tab_width(int p_idx) const { @@ -980,7 +997,7 @@ int TabBar::get_tab_width(int p_idx) const { Ref<Texture2D> tex = tabs[p_idx].icon; if (tex.is_valid()) { x += tex->get_width(); - if (tabs[p_idx].text != "") { + if (!tabs[p_idx].text.is_empty()) { x += get_theme_constant(SNAME("hseparation")); } } @@ -1011,64 +1028,73 @@ int TabBar::get_tab_width(int p_idx) const { } void TabBar::_ensure_no_over_offset() { - if (!is_inside_tree()) { + if (!is_inside_tree() || !buttons_visible) { return; } 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 = get_size().width - incr->get_width() - decr->get_width(); + int prev_offset = offset; + + int total_w = tabs[max_drawn_tab].ofs_cache + tabs[max_drawn_tab].size_cache - tabs[offset].ofs_cache; while (offset > 0) { - int total_w = 0; - for (int i = offset - 1; i < tabs.size(); i++) { - total_w += tabs[i].size_cache; - } + total_w += tabs[offset - 1].size_cache; - if ((buttons_visible && total_w < limit_minus_buttons) || total_w < limit) { // For the last tab, we accept if the tab covers the buttons. + if (total_w < limit_minus_buttons) { offset--; - update(); } else { break; } } -} -void TabBar::ensure_tab_visible(int p_idx) { - if (!is_inside_tree()) { - return; + if (prev_offset != offset) { + _update_cache(); + update(); } +} - if (tabs.size() == 0) { +void TabBar::ensure_tab_visible(int p_idx) { + if (!is_inside_tree() || !buttons_visible) { return; } ERR_FAIL_INDEX(p_idx, tabs.size()); - if (p_idx == offset) { + if (p_idx >= offset && p_idx <= max_drawn_tab) { return; } + if (p_idx < offset) { offset = p_idx; + _update_cache(); update(); + return; } - int prev_offset = offset; 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 = get_size().width - incr->get_width() - decr->get_width(); - for (int i = offset; i <= p_idx; i++) { - int total_w = tabs[i].ofs_cache + tabs[i].size_cache; - if (total_w > limit || (buttons_visible && total_w > limit_minus_buttons)) { + int total_w = tabs[max_drawn_tab].ofs_cache - tabs[offset].ofs_cache; + for (int i = max_drawn_tab; i <= p_idx; i++) { + total_w += tabs[i].size_cache; + } + + int prev_offset = offset; + + for (int i = offset; i < p_idx; i++) { + if (total_w > limit_minus_buttons) { + total_w -= tabs[i].size_cache; offset++; + } else { + break; } } if (prev_offset != offset) { + _update_cache(); update(); } } @@ -1085,6 +1111,7 @@ Rect2 TabBar::get_tab_rect(int p_tab) const { void TabBar::set_tab_close_display_policy(CloseButtonDisplayPolicy p_policy) { ERR_FAIL_INDEX(p_policy, CLOSE_BUTTON_MAX); cb_displaypolicy = p_policy; + _update_cache(); update(); } @@ -1128,8 +1155,61 @@ bool TabBar::get_select_with_rmb() const { return select_with_rmb; } +bool TabBar::_set(const StringName &p_name, const Variant &p_value) { + Vector<String> components = String(p_name).split("/", true, 2); + if (components.size() >= 2 && components[0].begins_with("tab_") && components[0].trim_prefix("tab_").is_valid_int()) { + int tab_index = components[0].trim_prefix("tab_").to_int(); + String property = components[1]; + if (property == "title") { + set_tab_title(tab_index, p_value); + return true; + } else if (property == "icon") { + set_tab_icon(tab_index, p_value); + return true; + } else if (components[1] == "disabled") { + set_tab_disabled(tab_index, p_value); + return true; + } + } + return false; +} + +bool TabBar::_get(const StringName &p_name, Variant &r_ret) const { + Vector<String> components = String(p_name).split("/", true, 2); + if (components.size() >= 2 && components[0].begins_with("tab_") && components[0].trim_prefix("tab_").is_valid_int()) { + int tab_index = components[0].trim_prefix("tab_").to_int(); + String property = components[1]; + if (property == "title") { + r_ret = get_tab_title(tab_index); + return true; + } else if (property == "icon") { + r_ret = get_tab_icon(tab_index); + return true; + } else if (components[1] == "disabled") { + r_ret = is_tab_disabled(tab_index); + return true; + } + } + return false; +} + +void TabBar::_get_property_list(List<PropertyInfo> *p_list) const { + for (int i = 0; i < tabs.size(); i++) { + p_list->push_back(PropertyInfo(Variant::STRING, vformat("tab_%d/title", i))); + + PropertyInfo pi = PropertyInfo(Variant::OBJECT, vformat("tab_%d/icon", i), PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"); + pi.usage &= ~(get_tab_icon(i).is_null() ? PROPERTY_USAGE_STORAGE : 0); + p_list->push_back(pi); + + pi = PropertyInfo(Variant::BOOL, vformat("tab_%d/disabled", i)); + pi.usage &= ~(!is_tab_disabled(i) ? PROPERTY_USAGE_STORAGE : 0); + p_list->push_back(pi); + } +} + void TabBar::_bind_methods() { ClassDB::bind_method(D_METHOD("_update_hover"), &TabBar::_update_hover); + ClassDB::bind_method(D_METHOD("set_tab_count", "count"), &TabBar::set_tab_count); ClassDB::bind_method(D_METHOD("get_tab_count"), &TabBar::get_tab_count); ClassDB::bind_method(D_METHOD("set_current_tab", "tab_idx"), &TabBar::set_current_tab); ClassDB::bind_method(D_METHOD("get_current_tab"), &TabBar::get_current_tab); @@ -1146,11 +1226,11 @@ void TabBar::_bind_methods() { ClassDB::bind_method(D_METHOD("set_tab_icon", "tab_idx", "icon"), &TabBar::set_tab_icon); ClassDB::bind_method(D_METHOD("get_tab_icon", "tab_idx"), &TabBar::get_tab_icon); ClassDB::bind_method(D_METHOD("set_tab_disabled", "tab_idx", "disabled"), &TabBar::set_tab_disabled); - ClassDB::bind_method(D_METHOD("get_tab_disabled", "tab_idx"), &TabBar::get_tab_disabled); + ClassDB::bind_method(D_METHOD("is_tab_disabled", "tab_idx"), &TabBar::is_tab_disabled); ClassDB::bind_method(D_METHOD("remove_tab", "tab_idx"), &TabBar::remove_tab); ClassDB::bind_method(D_METHOD("add_tab", "title", "icon"), &TabBar::add_tab, DEFVAL(""), DEFVAL(Ref<Texture2D>())); - ClassDB::bind_method(D_METHOD("set_tab_align", "align"), &TabBar::set_tab_align); - ClassDB::bind_method(D_METHOD("get_tab_align"), &TabBar::get_tab_align); + ClassDB::bind_method(D_METHOD("set_tab_alignment", "alignment"), &TabBar::set_tab_alignment); + ClassDB::bind_method(D_METHOD("get_tab_alignment"), &TabBar::get_tab_alignment); ClassDB::bind_method(D_METHOD("set_clip_tabs", "clip_tabs"), &TabBar::set_clip_tabs); ClassDB::bind_method(D_METHOD("get_clip_tabs"), &TabBar::get_clip_tabs); ClassDB::bind_method(D_METHOD("get_tab_offset"), &TabBar::get_tab_offset); @@ -1178,16 +1258,18 @@ void TabBar::_bind_methods() { ADD_SIGNAL(MethodInfo("tab_clicked", PropertyInfo(Variant::INT, "tab"))); ADD_PROPERTY(PropertyInfo(Variant::INT, "current_tab", PROPERTY_HINT_RANGE, "-1,4096,1", PROPERTY_USAGE_EDITOR), "set_current_tab", "get_current_tab"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_align", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_tab_align", "get_tab_align"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_alignment", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_tab_alignment", "get_tab_alignment"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_tabs"), "set_clip_tabs", "get_clip_tabs"); ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_close_display_policy", PROPERTY_HINT_ENUM, "Show Never,Show Active Only,Show Always"), "set_tab_close_display_policy", "get_tab_close_display_policy"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scrolling_enabled"), "set_scrolling_enabled", "get_scrolling_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "drag_to_rearrange_enabled"), "set_drag_to_rearrange_enabled", "get_drag_to_rearrange_enabled"); - BIND_ENUM_CONSTANT(ALIGN_LEFT); - BIND_ENUM_CONSTANT(ALIGN_CENTER); - BIND_ENUM_CONSTANT(ALIGN_RIGHT); - BIND_ENUM_CONSTANT(ALIGN_MAX); + ADD_ARRAY_COUNT("Tabs", "tab_count", "set_tab_count", "get_tab_count", "tab_"); + + BIND_ENUM_CONSTANT(ALIGNMENT_LEFT); + BIND_ENUM_CONSTANT(ALIGNMENT_CENTER); + BIND_ENUM_CONSTANT(ALIGNMENT_RIGHT); + BIND_ENUM_CONSTANT(ALIGNMENT_MAX); BIND_ENUM_CONSTANT(CLOSE_BUTTON_SHOW_NEVER); BIND_ENUM_CONSTANT(CLOSE_BUTTON_SHOW_ACTIVE_ONLY); diff --git a/scene/gui/tab_bar.h b/scene/gui/tab_bar.h index 411a62b1d9..d0055ae4d2 100644 --- a/scene/gui/tab_bar.h +++ b/scene/gui/tab_bar.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -38,11 +38,11 @@ class TabBar : public Control { GDCLASS(TabBar, Control); public: - enum TabAlign { - ALIGN_LEFT, - ALIGN_CENTER, - ALIGN_RIGHT, - ALIGN_MAX + enum AlignmentMode { + ALIGNMENT_LEFT, + ALIGNMENT_CENTER, + ALIGNMENT_RIGHT, + ALIGNMENT_MAX, }; enum CloseButtonDisplayPolicy { @@ -73,6 +73,10 @@ private: Ref<Texture2D> right_button; Rect2 rb_rect; Rect2 cb_rect; + + Tab() { + text_buf.instantiate(); + } }; int offset = 0; @@ -83,7 +87,7 @@ private: Vector<Tab> tabs; int current = 0; int previous = 0; - TabAlign tab_align = ALIGN_CENTER; + AlignmentMode tab_alignment = ALIGNMENT_CENTER; bool clip_tabs = true; int rb_hover = -1; bool rb_pressing = false; @@ -109,9 +113,13 @@ private: void _on_mouse_exited(); void _shape(int p_tab); + void _draw_tab(Ref<StyleBox> &p_tab_style, Color &p_font_color, int p_index, float p_x); protected: virtual void gui_input(const Ref<InputEvent> &p_event) 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; void _notification(int p_what); static void _bind_methods(); @@ -140,13 +148,13 @@ public: Ref<Texture2D> get_tab_icon(int p_tab) const; void set_tab_disabled(int p_tab, bool p_disabled); - bool get_tab_disabled(int p_tab) const; + bool is_tab_disabled(int p_tab) const; void set_tab_right_button(int p_tab, const Ref<Texture2D> &p_right_button); Ref<Texture2D> get_tab_right_button(int p_tab) const; - void set_tab_align(TabAlign p_align); - TabAlign get_tab_align() const; + void set_tab_alignment(AlignmentMode p_alignment); + AlignmentMode get_tab_alignment() const; void set_clip_tabs(bool p_clip_tabs); bool get_clip_tabs() const; @@ -156,7 +164,9 @@ public: void set_tab_close_display_policy(CloseButtonDisplayPolicy p_policy); CloseButtonDisplayPolicy get_tab_close_display_policy() const; + void set_tab_count(int p_count); int get_tab_count() const; + void set_current_tab(int p_current); int get_current_tab() const; int get_previous_tab() const; @@ -189,7 +199,7 @@ public: TabBar(); }; -VARIANT_ENUM_CAST(TabBar::TabAlign); +VARIANT_ENUM_CAST(TabBar::AlignmentMode); VARIANT_ENUM_CAST(TabBar::CloseButtonDisplayPolicy); #endif // TAB_BAR_H diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp index ff53d91ea3..c3fc08731e 100644 --- a/scene/gui/tab_container.cpp +++ b/scene/gui/tab_container.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -406,14 +406,14 @@ void TabContainer::_notification(int p_what) { } // Find the offset at which to draw tabs, according to the alignment. - switch (align) { - case ALIGN_LEFT: + switch (alignment) { + case ALIGNMENT_LEFT: tabs_ofs_cache = header_x; break; - case ALIGN_CENTER: + case ALIGNMENT_CENTER: tabs_ofs_cache = header_x + (header_width / 2) - (all_tabs_width / 2); break; - case ALIGN_RIGHT: + case ALIGNMENT_RIGHT: tabs_ofs_cache = header_x + header_width - all_tabs_width; break; } @@ -561,7 +561,7 @@ void TabContainer::_draw_tab(Ref<StyleBox> &p_tab_style, Color &p_font_color, in if (icon.is_valid()) { int y = y_center - (icon->get_height() / 2); icon->draw(canvas, Point2i(x_content, y)); - if (text != "") { + if (!text.is_empty()) { x_content += icon->get_width() + icon_text_distance; } } @@ -600,7 +600,7 @@ void TabContainer::_on_theme_changed() { _refresh_texts(); - minimum_size_changed(); + update_minimum_size(); if (get_tab_count() > 0) { _repaint(); update(); @@ -656,7 +656,7 @@ int TabContainer::_get_tab_width(int p_index) const { Ref<Texture2D> icon = control->get_meta("_tab_icon"); if (icon.is_valid()) { width += icon->get_width(); - if (text != "") { + if (!text.is_empty()) { width += get_theme_constant(SNAME("icon_separation")); } } @@ -703,30 +703,16 @@ void TabContainer::add_child_notify(Node *p_child) { return; } - Vector<Control *> tabs = _get_tabs(); _refresh_texts(); + call_deferred("_repaint"); + update(); - bool first = false; - - if (tabs.size() != 1) { - c->hide(); - } else { - c->show(); - //call_deferred(SNAME("set_current_tab"),0); - first = true; + bool first = (_get_tabs().size() == 1); + if (first) { current = 0; previous = 0; } - c->set_anchors_and_offsets_preset(Control::PRESET_WIDE); - if (tabs_visible) { - c->set_offset(SIDE_TOP, _get_top_margin()); - } - Ref<StyleBox> sb = get_theme_stylebox(SNAME("panel")); - 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)); - update(); + p_child->connect("renamed", callable_mp(this, &TabContainer::_child_renamed_callback)); if (first && is_inside_tree()) { emit_signal(SNAME("tab_changed"), current); @@ -967,14 +953,14 @@ int TabContainer::get_tab_idx_at_point(const Point2 &p_point) const { return -1; } -void TabContainer::set_tab_align(TabAlign p_align) { - ERR_FAIL_INDEX(p_align, 3); - align = p_align; +void TabContainer::set_tab_alignment(AlignmentMode p_alignment) { + ERR_FAIL_INDEX(p_alignment, 3); + alignment = p_alignment; update(); } -TabContainer::TabAlign TabContainer::get_tab_align() const { - return align; +TabContainer::AlignmentMode TabContainer::get_tab_alignment() const { + return alignment; } void TabContainer::set_tabs_visible(bool p_visible) { @@ -995,7 +981,7 @@ void TabContainer::set_tabs_visible(bool p_visible) { } update(); - minimum_size_changed(); + update_minimum_size(); } bool TabContainer::are_tabs_visible() const { @@ -1108,7 +1094,7 @@ void TabContainer::get_translatable_strings(List<String> *p_strings) const { String name = c->get_meta("_tab_name"); - if (name != "") { + if (!name.is_empty()) { p_strings->push_back(name); } } @@ -1198,8 +1184,8 @@ void TabContainer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_previous_tab"), &TabContainer::get_previous_tab); ClassDB::bind_method(D_METHOD("get_current_tab_control"), &TabContainer::get_current_tab_control); ClassDB::bind_method(D_METHOD("get_tab_control", "tab_idx"), &TabContainer::get_tab_control); - ClassDB::bind_method(D_METHOD("set_tab_align", "align"), &TabContainer::set_tab_align); - ClassDB::bind_method(D_METHOD("get_tab_align"), &TabContainer::get_tab_align); + ClassDB::bind_method(D_METHOD("set_tab_alignment", "alignment"), &TabContainer::set_tab_alignment); + ClassDB::bind_method(D_METHOD("get_tab_alignment"), &TabContainer::get_tab_alignment); ClassDB::bind_method(D_METHOD("set_tabs_visible", "visible"), &TabContainer::set_tabs_visible); ClassDB::bind_method(D_METHOD("are_tabs_visible"), &TabContainer::are_tabs_visible); ClassDB::bind_method(D_METHOD("set_all_tabs_in_front", "is_front"), &TabContainer::set_all_tabs_in_front); @@ -1223,6 +1209,7 @@ void TabContainer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_use_hidden_tabs_for_min_size", "enabled"), &TabContainer::set_use_hidden_tabs_for_min_size); ClassDB::bind_method(D_METHOD("get_use_hidden_tabs_for_min_size"), &TabContainer::get_use_hidden_tabs_for_min_size); + ClassDB::bind_method(D_METHOD("_repaint"), &TabContainer::_repaint); ClassDB::bind_method(D_METHOD("_on_theme_changed"), &TabContainer::_on_theme_changed); ClassDB::bind_method(D_METHOD("_update_current_tab"), &TabContainer::_update_current_tab); @@ -1230,16 +1217,16 @@ void TabContainer::_bind_methods() { ADD_SIGNAL(MethodInfo("tab_selected", PropertyInfo(Variant::INT, "tab"))); ADD_SIGNAL(MethodInfo("pre_popup_pressed")); - ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_align", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_tab_align", "get_tab_align"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_alignment", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_tab_alignment", "get_tab_alignment"); ADD_PROPERTY(PropertyInfo(Variant::INT, "current_tab", PROPERTY_HINT_RANGE, "-1,4096,1", PROPERTY_USAGE_EDITOR), "set_current_tab", "get_current_tab"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "tabs_visible"), "set_tabs_visible", "are_tabs_visible"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "all_tabs_in_front"), "set_all_tabs_in_front", "is_all_tabs_in_front"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "drag_to_rearrange_enabled"), "set_drag_to_rearrange_enabled", "get_drag_to_rearrange_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_hidden_tabs_for_min_size"), "set_use_hidden_tabs_for_min_size", "get_use_hidden_tabs_for_min_size"); - BIND_ENUM_CONSTANT(ALIGN_LEFT); - BIND_ENUM_CONSTANT(ALIGN_CENTER); - BIND_ENUM_CONSTANT(ALIGN_RIGHT); + BIND_ENUM_CONSTANT(ALIGNMENT_LEFT); + BIND_ENUM_CONSTANT(ALIGNMENT_CENTER); + BIND_ENUM_CONSTANT(ALIGNMENT_RIGHT); } TabContainer::TabContainer() { diff --git a/scene/gui/tab_container.h b/scene/gui/tab_container.h index fe96df25e8..01e71e9fa8 100644 --- a/scene/gui/tab_container.h +++ b/scene/gui/tab_container.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -39,10 +39,10 @@ class TabContainer : public Container { GDCLASS(TabContainer, Container); public: - enum TabAlign { - ALIGN_LEFT, - ALIGN_CENTER, - ALIGN_RIGHT + enum AlignmentMode { + ALIGNMENT_LEFT, + ALIGNMENT_CENTER, + ALIGNMENT_RIGHT, }; private: @@ -56,7 +56,7 @@ private: bool buttons_visible_cache = false; bool menu_hovered = false; int highlight_arrow = -1; - TabAlign align = ALIGN_CENTER; + AlignmentMode alignment = ALIGNMENT_CENTER; int _get_top_margin() const; mutable ObjectID popup_obj_id; bool drag_to_rearrange_enabled = false; @@ -90,8 +90,8 @@ protected: static void _bind_methods(); public: - void set_tab_align(TabAlign p_align); - TabAlign get_tab_align() const; + void set_tab_alignment(AlignmentMode p_alignment); + AlignmentMode get_tab_alignment() const; void set_tabs_visible(bool p_visible); bool are_tabs_visible() const; @@ -136,6 +136,6 @@ public: TabContainer(); }; -VARIANT_ENUM_CAST(TabContainer::TabAlign); +VARIANT_ENUM_CAST(TabContainer::AlignmentMode); #endif // TAB_CONTAINER_H diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index bc30bf4447..2b10ead8f6 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -155,30 +155,30 @@ _FORCE_INLINE_ const String &TextEdit::Text::operator[](int p_line) const { void TextEdit::Text::_calculate_line_height() { int height = 0; - for (int i = 0; i < text.size(); i++) { + for (const Line &l : text) { // Found another line with the same height...nothing to update. - if (text[i].height == line_height) { + if (l.height == line_height) { height = line_height; break; } - height = MAX(height, text[i].height); + height = MAX(height, l.height); } line_height = height; } void TextEdit::Text::_calculate_max_line_width() { int width = 0; - for (int i = 0; i < text.size(); i++) { - if (is_hidden(i)) { + for (const Line &l : text) { + if (l.hidden) { continue; } // Found another line with the same width...nothing to update. - if (text[i].width == max_width) { + if (l.width == max_width) { width = max_width; break; } - width = MAX(width, text[i].width); + width = MAX(width, l.width); } max_width = width; } @@ -216,7 +216,7 @@ void TextEdit::Text::invalidate_cache(int p_line, int p_column, const String &p_ // Update height. const int old_height = text.write[p_line].height; const int wrap_amount = get_line_wrap_amount(p_line); - int height = font->get_height(font_size); + int height = font_height; for (int i = 0; i <= wrap_amount; i++) { height = MAX(height, text[p_line].data_buf->get_line_size(i).y); } @@ -267,6 +267,13 @@ void TextEdit::Text::invalidate_all() { return; } + max_width = -1; + line_height = -1; + + if (!font.is_null() && font_size > 0) { + font_height = font->get_height(font_size); + } + for (int i = 0; i < text.size(); i++) { invalidate_cache(i); } @@ -275,7 +282,15 @@ void TextEdit::Text::invalidate_all() { void TextEdit::Text::clear() { text.clear(); - insert(0, "", Array()); + + max_width = -1; + line_height = -1; + + Line line; + line.gutters.resize(gutter_count); + line.data = ""; + text.insert(0, line); + invalidate_cache(0); } int TextEdit::Text::get_max_width() const { @@ -290,30 +305,64 @@ void TextEdit::Text::set(int p_line, const String &p_text, const Array &p_bidi_o invalidate_cache(p_line); } -void TextEdit::Text::insert(int p_at, const String &p_text, const Array &p_bidi_override) { - Line line; - line.gutters.resize(gutter_count); - line.hidden = false; - line.data = p_text; - line.bidi_override = p_bidi_override; - text.insert(p_at, line); +void TextEdit::Text::insert(int p_at, const Vector<String> &p_text, const Vector<Array> &p_bidi_override) { + int new_line_count = p_text.size() - 1; + if (new_line_count > 0) { + text.resize(text.size() + new_line_count); + for (int i = (text.size() - 1); i > p_at; i--) { + if ((i - new_line_count) <= 0) { + break; + } + text.write[i] = text[i - new_line_count]; + } + } - invalidate_cache(p_at); + for (int i = 0; i < p_text.size(); i++) { + if (i == 0) { + set(p_at + i, p_text[i], p_bidi_override[i]); + continue; + } + Line line; + line.gutters.resize(gutter_count); + line.data = p_text[i]; + line.bidi_override = p_bidi_override[i]; + text.write[p_at + i] = line; + invalidate_cache(p_at + i); + } } -void TextEdit::Text::remove_at(int p_index) { - int height = text[p_index].height; - int width = text[p_index].width; +void TextEdit::Text::remove_range(int p_from_line, int p_to_line) { + if (p_from_line == p_to_line) { + return; + } + + bool dirty_height = false; + bool dirty_width = false; + for (int i = p_from_line; i < p_to_line; i++) { + if (!dirty_height && text[i].height == line_height) { + dirty_height = true; + } - text.remove_at(p_index); + if (!dirty_width && text[i].width == max_width) { + dirty_width = true; + } - // If this is the tallest line, we need to get the next tallest. - if (height == line_height) { + if (dirty_height && dirty_width) { + break; + } + } + + int diff = (p_to_line - p_from_line); + for (int i = p_to_line; i < text.size() - 1; i++) { + text.write[(i - diff) + 1] = text[i + 1]; + } + text.resize(text.size() - diff); + + if (dirty_height) { _calculate_line_height(); } - // If this is the longest line, we need to get the next longest. - if (width == max_width) { + if (dirty_width) { _calculate_max_line_width(); } } @@ -601,7 +650,7 @@ void TextEdit::_notification(int p_what) { String highlighted_text = get_selected_text(); // Check if highlighted words contain only whitespaces (tabs or spaces). - bool only_whitespaces_highlighted = highlighted_text.strip_edges() == String(); + bool only_whitespaces_highlighted = highlighted_text.strip_edges().is_empty(); const int caret_wrap_index = get_caret_wrap_index(); @@ -916,7 +965,7 @@ void TextEdit::_notification(int p_what) { switch (gutter.type) { case GUTTER_TYPE_STRING: { const String &text = get_line_gutter_text(line, g); - if (text == "") { + if (text.is_empty()) { break; } @@ -1086,7 +1135,7 @@ void TextEdit::_notification(int p_what) { int first_visible_char = TS->shaped_text_get_range(rid).y; int last_visible_char = TS->shaped_text_get_range(rid).x; - int char_ofs = 0; + float char_ofs = 0; if (outline_size > 0 && outline_color.a > 0) { for (int j = 0; j < gl_size; j++) { for (int k = 0; k < glyphs[j].repeat; k++) { @@ -1121,7 +1170,7 @@ void TextEdit::_notification(int p_what) { } } - int char_pos = char_ofs + char_margin + ofs_x; + float char_pos = char_ofs + char_margin + ofs_x; if (char_pos >= xmargin_beg) { if (highlight_matching_braces_enabled) { if ((brace_open_match_line == line && brace_open_match_column == glyphs[j].start) || @@ -1195,7 +1244,7 @@ void TextEdit::_notification(int p_what) { } // Carets. - int caret_width = Math::round(1 * get_theme_default_base_scale()); + const int caret_width = get_theme_constant(SNAME("caret_width")) * get_theme_default_base_scale(); if (!clipped && caret.line == line && line_wrap_index == caret_wrap_index) { caret.draw_pos.y = ofs_y + ldata->get_line_descent(line_wrap_index); @@ -1624,7 +1673,7 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) { } _generate_context_menu(); - menu->set_position(get_screen_transform().xform(mpos)); + menu->set_position(get_screen_position() + mpos); menu->reset_size(); menu->popup(); grab_focus(); @@ -1871,7 +1920,7 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) { if (context_menu_enabled) { _generate_context_menu(); adjust_viewport_to_caret(); - menu->set_position(get_screen_transform().xform(get_caret_draw_pos())); + menu->set_position(get_screen_position() + get_caret_draw_pos()); menu->reset_size(); menu->popup(); menu->grab_focus(); @@ -2428,7 +2477,7 @@ void TextEdit::_update_caches() { } else { dir = (TextServer::Direction)text_direction; } - text.set_direction_and_language(dir, (language != "") ? language : TranslationServer::get_singleton()->get_tool_locale()); + text.set_direction_and_language(dir, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale()); text.set_font_features(opentype_features); text.set_draw_control_chars(draw_control_chars); text.set_font(font); @@ -2611,7 +2660,7 @@ void TextEdit::set_text_direction(Control::TextDirection p_text_direction) { } else { dir = (TextServer::Direction)text_direction; } - text.set_direction_and_language(dir, (language != "") ? language : TranslationServer::get_singleton()->get_tool_locale()); + text.set_direction_and_language(dir, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale()); text.invalidate_all(); if (menu_dir) { @@ -2662,7 +2711,7 @@ void TextEdit::set_language(const String &p_language) { } else { dir = (TextServer::Direction)text_direction; } - text.set_direction_and_language(dir, (language != "") ? language : TranslationServer::get_singleton()->get_tool_locale()); + text.set_direction_and_language(dir, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale()); text.invalidate_all(); update(); } @@ -2763,6 +2812,17 @@ void TextEdit::clear() { } void TextEdit::_clear() { + if (editable && undo_enabled) { + _move_caret_document_start(false); + begin_complex_operation(); + + _remove_text(0, 0, MAX(0, get_line_count() - 1), MAX(get_line(MAX(get_line_count() - 1, 0)).size() - 1, 0)); + insert_text_at_caret(""); + text.clear(); + + end_complex_operation(); + return; + } clear_undo_history(); text.clear(); caret.column = 0; @@ -4226,7 +4286,10 @@ double TextEdit::get_scroll_pos_for_line(int p_line, int p_wrap_index) const { return p_line; } - double new_line_scroll_pos = get_visible_line_count_in_range(0, CLAMP(p_line, 0, text.size() - 1)); + double new_line_scroll_pos = 0.0; + if (p_line > 0) { + new_line_scroll_pos = get_visible_line_count_in_range(0, MIN(p_line - 1, text.size() - 1)); + } new_line_scroll_pos += p_wrap_index; return new_line_scroll_pos; } @@ -4290,7 +4353,7 @@ int TextEdit::get_visible_line_count_in_range(int p_from_line, int p_to_line) co /* Returns the total number of (lines + wrapped - hidden). */ if (!_is_hiding_enabled() && get_line_wrapping_mode() == LineWrappingMode::LINE_WRAPPING_NONE) { - return p_to_line - p_from_line; + return (p_to_line - p_from_line) + 1; } int total_rows = 0; @@ -4996,7 +5059,7 @@ void TextEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("get_line_wrapped_text", "line"), &TextEdit::get_line_wrapped_text); /* Viewport. */ - // Scolling. + // Scrolling. ClassDB::bind_method(D_METHOD("set_smooth_scroll_enable", "enable"), &TextEdit::set_smooth_scroll_enabled); ClassDB::bind_method(D_METHOD("is_smooth_scroll_enabled"), &TextEdit::is_smooth_scroll_enabled); @@ -5176,7 +5239,7 @@ bool TextEdit::_set(const StringName &p_name, const Variant &p_value) { if (str.begins_with("opentype_features/")) { String name = str.get_slicec('/', 1); int32_t tag = TS->name_to_tag(name); - double value = p_value; + int value = p_value; if (value == -1) { if (opentype_features.has(tag)) { opentype_features.erase(tag); @@ -5185,7 +5248,7 @@ bool TextEdit::_set(const StringName &p_name, const Variant &p_value) { update(); } } else { - if ((double)opentype_features[tag] != value) { + if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) { opentype_features[tag] = value; text.set_font_features(opentype_features); text.invalidate_all(); @@ -5218,7 +5281,7 @@ bool TextEdit::_get(const StringName &p_name, Variant &r_ret) const { void TextEdit::_get_property_list(List<PropertyInfo> *p_list) const { for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) { String name = TS->tag_to_name(*ftr); - p_list->push_back(PropertyInfo(Variant::FLOAT, "opentype_features/" + name)); + p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name)); } p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR)); } @@ -5358,7 +5421,7 @@ void TextEdit::_cut_internal() { set_caret_line(get_caret_line() + 1); } - // Correct the visualy perceived caret column taking care of identation level of the lines. + // Correct the visually perceived caret column taking care of indentation level of the lines. int diff_indent = indent_level - get_indent_level(get_caret_line()); cc += diff_indent; if (diff_indent != 0) { @@ -5897,6 +5960,7 @@ void TextEdit::_update_scrollbars() { caret.line_ofs = 0; caret.wrap_ofs = 0; v_scroll->set_value(0); + v_scroll->set_max(0); v_scroll->hide(); } @@ -5914,6 +5978,7 @@ void TextEdit::_update_scrollbars() { } else { caret.x_ofs = 0; h_scroll->set_value(0); + h_scroll->set_max(0); h_scroll->hide(); } @@ -6289,11 +6354,11 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i ERR_FAIL_COND(p_char < 0); /* STEP 1: Remove \r from source text and separate in substrings. */ - - Vector<String> substrings = p_text.replace("\r", "").split("\n"); + const String text_to_insert = p_text.replace("\r", ""); + Vector<String> substrings = text_to_insert.split("\n"); // Is this just a new empty line? - bool shift_first_line = p_char == 0 && p_text.replace("\r", "") == "\n"; + bool shift_first_line = p_char == 0 && substrings.size() == 2 && text_to_insert == "\n"; /* STEP 2: Add spaces if the char is greater than the end of the line. */ while (p_char > text[p_line].length()) { @@ -6301,24 +6366,19 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i } /* STEP 3: Separate dest string in pre and post text. */ - - String preinsert_text = text[p_line].substr(0, p_char); String postinsert_text = text[p_line].substr(p_char, text[p_line].size()); - for (int j = 0; j < substrings.size(); j++) { - // Insert the substrings. - - if (j == 0) { - text.set(p_line, preinsert_text + substrings[j], structured_text_parser(st_parser, st_args, preinsert_text + substrings[j])); - } else { - text.insert(p_line + j, substrings[j], structured_text_parser(st_parser, st_args, substrings[j])); - } + substrings.write[0] = text[p_line].substr(0, p_char) + substrings[0]; + substrings.write[substrings.size() - 1] += postinsert_text; - if (j == substrings.size() - 1) { - text.set(p_line + j, text[p_line + j] + postinsert_text, structured_text_parser(st_parser, st_args, text[p_line + j] + postinsert_text)); - } + Vector<Array> bidi_override; + bidi_override.resize(substrings.size()); + for (int i = 0; i < substrings.size(); i++) { + bidi_override.write[i] = structured_text_parser(st_parser, st_args, substrings[i]); } + text.insert(p_line, substrings, bidi_override); + if (shift_first_line) { text.move_gutters(p_line, p_line + 1); text.set_hidden(p_line + 1, text.is_hidden(p_line)); @@ -6351,7 +6411,7 @@ String TextEdit::_base_get_text(int p_from_line, int p_from_column, int p_to_lin ERR_FAIL_COND_V(p_to_line < p_from_line, String()); // 'from > to'. ERR_FAIL_COND_V(p_to_line == p_from_line && p_to_column < p_from_column, String()); // 'from > to'. - String ret; + StringBuilder ret; for (int i = p_from_line; i <= p_to_line; i++) { int begin = (i == p_from_line) ? p_from_column : 0; @@ -6363,7 +6423,7 @@ String TextEdit::_base_get_text(int p_from_line, int p_from_column, int p_to_lin ret += text[i].substr(begin, end - begin); } - return ret; + return ret.as_string(); } void TextEdit::_base_remove_text(int p_from_line, int p_from_column, int p_to_line, int p_to_column) { @@ -6377,9 +6437,7 @@ void TextEdit::_base_remove_text(int p_from_line, int p_from_column, int p_to_li String pre_text = text[p_from_line].substr(0, p_from_column); String post_text = text[p_to_line].substr(p_to_column, text[p_to_line].length()); - for (int i = p_from_line; i < p_to_line; i++) { - text.remove_at(p_from_line + 1); - } + text.remove_range(p_from_line, p_to_line); text.set(p_from_line, pre_text + post_text, structured_text_parser(st_parser, st_args, pre_text + post_text)); if (!text_changed_dirty && !setting_text) { diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index a1b2ed59f5..57b48b5f52 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -70,7 +70,7 @@ public: GUTTER_TYPE_CUSTOM }; - /* Contex Menu. */ + /* Context Menu. */ enum MenuItems { MENU_CUT, MENU_COPY, @@ -159,6 +159,7 @@ private: mutable Vector<Line> text; Ref<Font> font; int font_size = -1; + int font_height = 0; Dictionary opentype_features; String language; @@ -204,8 +205,8 @@ private: } } bool is_hidden(int p_line) const { return text[p_line].hidden; } - void insert(int p_at, const String &p_text, const Array &p_bidi_override); - void remove_at(int p_index); + void insert(int p_at, const Vector<String> &p_text, const Vector<Array> &p_bidi_override); + void remove_range(int p_from_line, int p_to_line); int size() const { return text.size(); } void clear(); @@ -373,7 +374,7 @@ private: bool move_caret_on_right_click = true; - bool caret_mid_grapheme_enabled = false; + bool caret_mid_grapheme_enabled = true; bool drag_action = false; bool drag_caret_force_displayed = false; diff --git a/scene/gui/texture_button.cpp b/scene/gui/texture_button.cpp index 8659ea06a2..da202c1c8f 100644 --- a/scene/gui/texture_button.cpp +++ b/scene/gui/texture_button.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -170,6 +170,12 @@ void TextureButton::_notification(int p_what) { Point2 ofs; Size2 size; + bool draw_focus = (has_focus() && focused.is_valid()); + + // If no other texture is valid, try using focused texture. + if (!texdraw.is_valid() && draw_focus) { + texdraw = focused; + } if (texdraw.is_valid()) { size = texdraw->get_size(); @@ -226,7 +232,9 @@ void TextureButton::_notification(int p_what) { size.width *= hflip ? -1.0f : 1.0f; size.height *= vflip ? -1.0f : 1.0f; - if (_tile) { + if (texdraw == focused) { + // Do nothing, we only needed to calculate the rectangle. + } else if (_tile) { draw_texture_rect(texdraw, Rect2(ofs, size), _tile); } else { draw_texture_rect_region(texdraw, Rect2(ofs, size), _texture_region); @@ -235,7 +243,7 @@ void TextureButton::_notification(int p_what) { _position_rect = Rect2(); } - if (has_focus() && focused.is_valid()) { + if (draw_focus) { draw_texture_rect(focused, Rect2(ofs, size), false); }; } break; @@ -289,19 +297,19 @@ void TextureButton::_bind_methods() { void TextureButton::set_normal_texture(const Ref<Texture2D> &p_normal) { normal = p_normal; update(); - minimum_size_changed(); + update_minimum_size(); } void TextureButton::set_pressed_texture(const Ref<Texture2D> &p_pressed) { pressed = p_pressed; update(); - minimum_size_changed(); + update_minimum_size(); } void TextureButton::set_hover_texture(const Ref<Texture2D> &p_hover) { hover = p_hover; update(); - minimum_size_changed(); + update_minimum_size(); } void TextureButton::set_disabled_texture(const Ref<Texture2D> &p_disabled) { @@ -312,7 +320,7 @@ void TextureButton::set_disabled_texture(const Ref<Texture2D> &p_disabled) { void TextureButton::set_click_mask(const Ref<BitMap> &p_click_mask) { click_mask = p_click_mask; update(); - minimum_size_changed(); + update_minimum_size(); } Ref<Texture2D> TextureButton::get_normal_texture() const { @@ -349,7 +357,7 @@ bool TextureButton::get_expand() const { void TextureButton::set_expand(bool p_expand) { expand = p_expand; - minimum_size_changed(); + update_minimum_size(); update(); } diff --git a/scene/gui/texture_button.h b/scene/gui/texture_button.h index 8361f3c341..1428a79a1d 100644 --- a/scene/gui/texture_button.h +++ b/scene/gui/texture_button.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/texture_progress_bar.cpp b/scene/gui/texture_progress_bar.cpp index 3c10c6bd66..043c0f464c 100644 --- a/scene/gui/texture_progress_bar.cpp +++ b/scene/gui/texture_progress_bar.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -35,7 +35,7 @@ void TextureProgressBar::set_under_texture(const Ref<Texture2D> &p_texture) { under = p_texture; update(); - minimum_size_changed(); + update_minimum_size(); } Ref<Texture2D> TextureProgressBar::get_under_texture() const { @@ -46,7 +46,7 @@ void TextureProgressBar::set_over_texture(const Ref<Texture2D> &p_texture) { over = p_texture; update(); if (under.is_null()) { - minimum_size_changed(); + update_minimum_size(); } } @@ -58,7 +58,7 @@ void TextureProgressBar::set_stretch_margin(Side p_side, int p_size) { ERR_FAIL_INDEX((int)p_side, 4); stretch_margin[p_side] = p_size; update(); - minimum_size_changed(); + update_minimum_size(); } int TextureProgressBar::get_stretch_margin(Side p_side) const { @@ -69,7 +69,7 @@ int TextureProgressBar::get_stretch_margin(Side p_side) const { void TextureProgressBar::set_nine_patch_stretch(bool p_stretch) { nine_patch_stretch = p_stretch; update(); - minimum_size_changed(); + update_minimum_size(); } bool TextureProgressBar::get_nine_patch_stretch() const { @@ -93,7 +93,7 @@ Size2 TextureProgressBar::get_minimum_size() const { void TextureProgressBar::set_progress_texture(const Ref<Texture2D> &p_texture) { progress = p_texture; update(); - minimum_size_changed(); + update_minimum_size(); } Ref<Texture2D> TextureProgressBar::get_progress_texture() const { diff --git a/scene/gui/texture_progress_bar.h b/scene/gui/texture_progress_bar.h index c508f41387..4d3e38e006 100644 --- a/scene/gui/texture_progress_bar.h +++ b/scene/gui/texture_progress_bar.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/gui/texture_rect.cpp b/scene/gui/texture_rect.cpp index 1cba88e06f..a8cdeb44f5 100644 --- a/scene/gui/texture_rect.cpp +++ b/scene/gui/texture_rect.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -44,9 +44,6 @@ void TextureRect::_notification(int p_what) { bool tile = false; switch (stretch_mode) { - case STRETCH_SCALE_ON_EXPAND: { - size = expand ? get_size() : texture->get_size(); - } break; case STRETCH_SCALE: { size = get_size(); } break; @@ -114,7 +111,7 @@ void TextureRect::_notification(int p_what) { } Size2 TextureRect::get_minimum_size() const { - if (!expand && !texture.is_null()) { + if (!ignore_texture_size && !texture.is_null()) { return texture->get_size(); } else { return Size2(); @@ -124,8 +121,8 @@ Size2 TextureRect::get_minimum_size() const { void TextureRect::_bind_methods() { ClassDB::bind_method(D_METHOD("set_texture", "texture"), &TextureRect::set_texture); ClassDB::bind_method(D_METHOD("get_texture"), &TextureRect::get_texture); - ClassDB::bind_method(D_METHOD("set_expand", "enable"), &TextureRect::set_expand); - ClassDB::bind_method(D_METHOD("has_expand"), &TextureRect::has_expand); + ClassDB::bind_method(D_METHOD("set_ignore_texture_size", "ignore"), &TextureRect::set_ignore_texture_size); + ClassDB::bind_method(D_METHOD("get_ignore_texture_size"), &TextureRect::get_ignore_texture_size); ClassDB::bind_method(D_METHOD("set_flip_h", "enable"), &TextureRect::set_flip_h); ClassDB::bind_method(D_METHOD("is_flipped_h"), &TextureRect::is_flipped_h); ClassDB::bind_method(D_METHOD("set_flip_v", "enable"), &TextureRect::set_flip_v); @@ -134,12 +131,11 @@ void TextureRect::_bind_methods() { ClassDB::bind_method(D_METHOD("get_stretch_mode"), &TextureRect::get_stretch_mode); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "expand"), "set_expand", "has_expand"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "stretch_mode", PROPERTY_HINT_ENUM, "Scale On Expand (Compat),Scale,Tile,Keep,Keep Centered,Keep Aspect,Keep Aspect Centered,Keep Aspect Covered"), "set_stretch_mode", "get_stretch_mode"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ignore_texture_size"), "set_ignore_texture_size", "get_ignore_texture_size"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "stretch_mode", PROPERTY_HINT_ENUM, "Scale,Tile,Keep,Keep Centered,Keep Aspect,Keep Aspect Centered,Keep Aspect Covered"), "set_stretch_mode", "get_stretch_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_h"), "set_flip_h", "is_flipped_h"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_v"), "set_flip_v", "is_flipped_v"); - BIND_ENUM_CONSTANT(STRETCH_SCALE_ON_EXPAND); BIND_ENUM_CONSTANT(STRETCH_SCALE); BIND_ENUM_CONSTANT(STRETCH_TILE); BIND_ENUM_CONSTANT(STRETCH_KEEP); @@ -152,7 +148,7 @@ void TextureRect::_bind_methods() { void TextureRect::_texture_changed() { if (texture.is_valid()) { update(); - minimum_size_changed(); + update_minimum_size(); } } @@ -172,21 +168,21 @@ void TextureRect::set_texture(const Ref<Texture2D> &p_tex) { } update(); - minimum_size_changed(); + update_minimum_size(); } Ref<Texture2D> TextureRect::get_texture() const { return texture; } -void TextureRect::set_expand(bool p_expand) { - expand = p_expand; +void TextureRect::set_ignore_texture_size(bool p_ignore) { + ignore_texture_size = p_ignore; update(); - minimum_size_changed(); + update_minimum_size(); } -bool TextureRect::has_expand() const { - return expand; +bool TextureRect::get_ignore_texture_size() const { + return ignore_texture_size; } void TextureRect::set_stretch_mode(StretchMode p_mode) { diff --git a/scene/gui/texture_rect.h b/scene/gui/texture_rect.h index 0f93d5732f..7d667b25a8 100644 --- a/scene/gui/texture_rect.h +++ b/scene/gui/texture_rect.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -38,7 +38,6 @@ class TextureRect : public Control { public: enum StretchMode { - STRETCH_SCALE_ON_EXPAND, //default, for backwards compatibility STRETCH_SCALE, STRETCH_TILE, STRETCH_KEEP, @@ -49,11 +48,11 @@ public: }; private: - bool expand = false; + bool ignore_texture_size = false; bool hflip = false; bool vflip = false; Ref<Texture2D> texture; - StretchMode stretch_mode = STRETCH_SCALE_ON_EXPAND; + StretchMode stretch_mode = STRETCH_SCALE; void _texture_changed(); @@ -66,8 +65,8 @@ public: void set_texture(const Ref<Texture2D> &p_tex); Ref<Texture2D> get_texture() const; - void set_expand(bool p_expand); - bool has_expand() const; + void set_ignore_texture_size(bool p_ignore); + bool get_ignore_texture_size() const; void set_stretch_mode(StretchMode p_mode); StretchMode get_stretch_mode() const; diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 89caaaafd0..e46de43f1e 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -1002,18 +1002,18 @@ bool TreeItem::is_custom_set_as_button(int p_column) const { return cells[p_column].custom_button; } -void TreeItem::set_text_align(int p_column, TextAlign p_align) { +void TreeItem::set_text_alignment(int p_column, HorizontalAlignment p_alignment) { ERR_FAIL_INDEX(p_column, cells.size()); - cells.write[p_column].text_align = p_align; + cells.write[p_column].text_alignment = p_alignment; cells.write[p_column].cached_minimum_size_dirty = true; _changed_notify(p_column); } -TreeItem::TextAlign TreeItem::get_text_align(int p_column) const { - ERR_FAIL_INDEX_V(p_column, cells.size(), ALIGN_LEFT); - return cells[p_column].text_align; +HorizontalAlignment TreeItem::get_text_alignment(int p_column) const { + ERR_FAIL_INDEX_V(p_column, cells.size(), HORIZONTAL_ALIGNMENT_LEFT); + return cells[p_column].text_alignment; } void TreeItem::set_expand_right(int p_column, bool p_enable) { @@ -1231,8 +1231,8 @@ void TreeItem::_bind_methods() { ClassDB::bind_method(D_METHOD("set_tooltip", "column", "tooltip"), &TreeItem::set_tooltip); ClassDB::bind_method(D_METHOD("get_tooltip", "column"), &TreeItem::get_tooltip); - ClassDB::bind_method(D_METHOD("set_text_align", "column", "text_align"), &TreeItem::set_text_align); - ClassDB::bind_method(D_METHOD("get_text_align", "column"), &TreeItem::get_text_align); + ClassDB::bind_method(D_METHOD("set_text_alignment", "column", "text_alignment"), &TreeItem::set_text_alignment); + ClassDB::bind_method(D_METHOD("get_text_alignment", "column"), &TreeItem::get_text_alignment); ClassDB::bind_method(D_METHOD("set_expand_right", "column", "enable"), &TreeItem::set_expand_right); ClassDB::bind_method(D_METHOD("get_expand_right", "column"), &TreeItem::get_expand_right); @@ -1278,10 +1278,6 @@ void TreeItem::_bind_methods() { BIND_ENUM_CONSTANT(CELL_MODE_RANGE); BIND_ENUM_CONSTANT(CELL_MODE_ICON); BIND_ENUM_CONSTANT(CELL_MODE_CUSTOM); - - BIND_ENUM_CONSTANT(ALIGN_LEFT); - BIND_ENUM_CONSTANT(ALIGN_CENTER); - BIND_ENUM_CONSTANT(ALIGN_RIGHT); } void TreeItem::clear_children() { @@ -1477,16 +1473,17 @@ void Tree::draw_item_rect(TreeItem::Cell &p_cell, const Rect2i &p_rect, const Co } w += ts.width; - switch (p_cell.text_align) { - case TreeItem::ALIGN_LEFT: + switch (p_cell.text_alignment) { + case HORIZONTAL_ALIGNMENT_FILL: + case HORIZONTAL_ALIGNMENT_LEFT: { if (rtl) { rect.position.x += MAX(0, (rect.size.width - w)); } - break; - case TreeItem::ALIGN_CENTER: + } break; + case HORIZONTAL_ALIGNMENT_CENTER: rect.position.x += MAX(0, (rect.size.width - w) / 2); break; - case TreeItem::ALIGN_RIGHT: + case HORIZONTAL_ALIGNMENT_RIGHT: if (!rtl) { rect.position.x += MAX(0, (rect.size.width - w)); } @@ -1539,7 +1536,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].opentype_features, (columns[p_col].language != "") ? columns[p_col].language : TranslationServer::get_singleton()->get_tool_locale()); + columns.write[p_col].text_buf->add_string(columns[p_col].title, cache.font, cache.font_size, columns[p_col].opentype_features, !columns[p_col].language.is_empty() ? columns[p_col].language : TranslationServer::get_singleton()->get_tool_locale()); } void Tree::update_item_cell(TreeItem *p_item, int p_col) { @@ -1547,7 +1544,7 @@ void Tree::update_item_cell(TreeItem *p_item, int p_col) { p_item->cells.write[p_col].text_buf->clear(); if (p_item->cells[p_col].mode == TreeItem::CELL_MODE_RANGE) { - if (p_item->cells[p_col].text != "") { + if (!p_item->cells[p_col].text.is_empty()) { if (!p_item->cells[p_col].editable) { return; } @@ -1574,7 +1571,7 @@ void Tree::update_item_cell(TreeItem *p_item, int p_col) { valtext = p_item->cells[p_col].text; } - if (p_item->cells[p_col].suffix != String()) { + if (!p_item->cells[p_col].suffix.is_empty()) { valtext += " " + p_item->cells[p_col].suffix; } @@ -1597,7 +1594,7 @@ void Tree::update_item_cell(TreeItem *p_item, int p_col) { } else { font_size = cache.font_size; } - p_item->cells.write[p_col].text_buf->add_string(valtext, font, font_size, p_item->cells[p_col].opentype_features, (p_item->cells[p_col].language != "") ? p_item->cells[p_col].language : TranslationServer::get_singleton()->get_tool_locale()); + p_item->cells.write[p_col].text_buf->add_string(valtext, font, font_size, p_item->cells[p_col].opentype_features, !p_item->cells[p_col].language.is_empty() ? p_item->cells[p_col].language : TranslationServer::get_singleton()->get_tool_locale()); 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)); p_item->cells.write[p_col].dirty = false; } @@ -1663,7 +1660,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 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 == "" && p_item->cells[i + plus].icon.is_null()) { + while (i + plus < columns.size() && !p_item->cells[i + plus].editable && p_item->cells[i + plus].mode == TreeItem::CELL_MODE_STRING && p_item->cells[i + plus].text.is_empty() && p_item->cells[i + plus].icon.is_null()) { w += get_column_width(i + plus); plus++; skip2++; @@ -1860,7 +1857,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 } break; case TreeItem::CELL_MODE_RANGE: { - if (p_item->cells[i].text != "") { + if (!p_item->cells[i].text.is_empty()) { if (!p_item->cells[i].editable) { break; } @@ -2198,8 +2195,10 @@ void Tree::select_single_item(TreeItem *p_selected, TreeItem *p_current, int p_c */ } else if (c.selected) { - c.selected = false; - //p_current->deselected_signal.call(p_col); + if (p_selected != p_current) { + // Deselect other rows. + c.selected = false; + } } } else if (select_mode == SELECT_SINGLE || select_mode == SELECT_MULTI) { if (!r_in_range && &selected_cell == &c) { @@ -2319,12 +2318,9 @@ 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_pos.x >= x_ofs && p_pos.x < (x_ofs + cache.item_margin))) { - if (p_item->first_child) { - p_item->set_collapsed(!p_item->is_collapsed()); - } - - return -1; //handled! + if (!p_item->disable_folding && !hide_folding && p_item->first_child && (p_pos.x >= x_ofs && p_pos.x < (x_ofs + cache.item_margin))) { + p_item->set_collapsed(!p_item->is_collapsed()); + return -1; } int x = p_pos.x; @@ -2340,7 +2336,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 == "" && p_item->cells[i + plus].icon.is_null()) { + 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 += get_column_width(i + plus); plus++; @@ -2523,7 +2519,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int } break; case TreeItem::CELL_MODE_RANGE: { - if (c.text != "") { + if (!c.text.is_empty()) { //if (x >= (get_column_width(col)-item_h/2)) { popup_menu->clear(); for (int i = 0; i < c.text.get_slice_count(","); i++) { @@ -2532,7 +2528,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_global_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) - cache.offset); popup_menu->popup(); popup_edited_item = p_item; popup_edited_item_col = col; @@ -3175,7 +3171,7 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) { if (drag_touching && !drag_touching_deaccel) { drag_accum -= mm->get_relative().y; v_scroll->set_value(drag_from + drag_accum); - drag_speed = -mm->get_speed().y; + drag_speed = -mm->get_velocity().y; } } @@ -3433,7 +3429,7 @@ bool Tree::edit_selected() { item_edited(col, s); return true; - } else if (c.mode == TreeItem::CELL_MODE_RANGE && c.text != "") { + } else if (c.mode == TreeItem::CELL_MODE_RANGE && !c.text.is_empty()) { popup_menu->clear(); for (int i = 0; i < c.text.get_slice_count(","); i++) { String s2 = c.text.get_slicec(',', i); @@ -3441,7 +3437,7 @@ bool Tree::edit_selected() { } popup_menu->set_size(Size2(rect.size.width, 0)); - popup_menu->set_position(get_global_position() + rect.position + Point2i(0, rect.size.height)); + popup_menu->set_position(get_screen_position() + rect.position + Point2i(0, rect.size.height)); popup_menu->popup(); popup_edited_item = s; popup_edited_item_col = col; @@ -4370,7 +4366,7 @@ void Tree::scroll_to_item(TreeItem *p_item) { void Tree::set_h_scroll_enabled(bool p_enable) { h_scroll_enabled = p_enable; - minimum_size_changed(); + update_minimum_size(); } bool Tree::is_h_scroll_enabled() const { @@ -4379,7 +4375,7 @@ bool Tree::is_h_scroll_enabled() const { void Tree::set_v_scroll_enabled(bool p_enable) { v_scroll_enabled = p_enable; - minimum_size_changed(); + update_minimum_size(); } bool Tree::is_v_scroll_enabled() const { @@ -4682,7 +4678,7 @@ String Tree::get_tooltip(const Point2 &p_pos) const { Size2 size = b->get_size() + cache.button_pressed->get_minimum_size(); if (pos.x > col_width - size.width) { String tooltip = c.buttons[j].tooltip; - if (tooltip != "") { + if (!tooltip.is_empty()) { return tooltip; } } @@ -4830,6 +4826,7 @@ void Tree::_bind_methods() { ClassDB::bind_method(D_METHOD("get_allow_reselect"), &Tree::get_allow_reselect); ADD_PROPERTY(PropertyInfo(Variant::INT, "columns"), "set_columns", "get_columns"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "column_titles_visible"), "set_column_titles_visible", "are_column_titles_visible"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_reselect"), "set_allow_reselect", "get_allow_reselect"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_rmb_select"), "set_allow_rmb_select", "get_allow_rmb_select"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_folding"), "set_hide_folding", "is_folding_hidden"); diff --git a/scene/gui/tree.h b/scene/gui/tree.h index d4caec614a..c60c87564e 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -52,12 +52,6 @@ public: CELL_MODE_CUSTOM, ///< Contains a custom value, show a string, and an edit button }; - enum TextAlign { - ALIGN_LEFT, - ALIGN_CENTER, - ALIGN_RIGHT - }; - private: friend class Tree; @@ -98,7 +92,7 @@ private: Size2i cached_minimum_size; bool cached_minimum_size_dirty = true; - TextAlign text_align = ALIGN_LEFT; + HorizontalAlignment text_alignment = HORIZONTAL_ALIGNMENT_LEFT; Variant meta; String tooltip; @@ -316,8 +310,8 @@ public: void set_tooltip(int p_column, const String &p_tooltip); String get_tooltip(int p_column) const; - void set_text_align(int p_column, TextAlign p_align); - TextAlign get_text_align(int p_column) const; + void set_text_alignment(int p_column, HorizontalAlignment p_alignment); + HorizontalAlignment get_text_alignment(int p_column) const; void set_expand_right(int p_column, bool p_enable); bool get_expand_right(int p_column) const; @@ -359,7 +353,6 @@ public: }; VARIANT_ENUM_CAST(TreeItem::TreeCellMode); -VARIANT_ENUM_CAST(TreeItem::TextAlign); class VBoxContainer; diff --git a/scene/gui/video_player.cpp b/scene/gui/video_stream_player.cpp index 989aabc549..1f2a8c8aa1 100644 --- a/scene/gui/video_player.cpp +++ b/scene/gui/video_stream_player.cpp @@ -1,12 +1,12 @@ /*************************************************************************/ -/* video_player.cpp */ +/* video_stream_player.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -28,13 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "video_player.h" +#include "video_stream_player.h" #include "core/os/os.h" #include "scene/scene_string_names.h" #include "servers/audio_server.h" -int VideoPlayer::sp_get_channel_count() const { +int VideoStreamPlayer::sp_get_channel_count() const { if (playback.is_null()) { return 0; } @@ -42,7 +42,7 @@ int VideoPlayer::sp_get_channel_count() const { return playback->get_channels(); } -bool VideoPlayer::mix(AudioFrame *p_buffer, int p_frames) { +bool VideoStreamPlayer::mix(AudioFrame *p_buffer, int p_frames) { // Check the amount resampler can really handle. // If it cannot, wait "wait_resampler_phase_limit" times. // This mechanism contributes to smoother pause/unpause operation. @@ -56,11 +56,11 @@ bool VideoPlayer::mix(AudioFrame *p_buffer, int p_frames) { } // Called from main thread (e.g. VideoStreamPlaybackTheora::update). -int VideoPlayer::_audio_mix_callback(void *p_udata, const float *p_data, int p_frames) { +int VideoStreamPlayer::_audio_mix_callback(void *p_udata, const float *p_data, int p_frames) { ERR_FAIL_NULL_V(p_udata, 0); ERR_FAIL_NULL_V(p_data, 0); - VideoPlayer *vp = (VideoPlayer *)p_udata; + VideoStreamPlayer *vp = (VideoStreamPlayer *)p_udata; int todo = MIN(vp->resampler.get_writer_space(), p_frames); @@ -75,13 +75,13 @@ int VideoPlayer::_audio_mix_callback(void *p_udata, const float *p_data, int p_f return todo; } -void VideoPlayer::_mix_audios(void *p_self) { +void VideoStreamPlayer::_mix_audios(void *p_self) { ERR_FAIL_NULL(p_self); - reinterpret_cast<VideoPlayer *>(p_self)->_mix_audio(); + reinterpret_cast<VideoStreamPlayer *>(p_self)->_mix_audio(); } // Called from audio thread -void VideoPlayer::_mix_audio() { +void VideoStreamPlayer::_mix_audio() { if (!stream.is_valid()) { return; } @@ -126,7 +126,7 @@ void VideoPlayer::_mix_audio() { } } -void VideoPlayer::_notification(int p_notification) { +void VideoStreamPlayer::_notification(int p_notification) { switch (p_notification) { case NOTIFICATION_ENTER_TREE: { AudioServer::get_singleton()->add_mix_callback(_mix_audios, this); @@ -180,7 +180,7 @@ void VideoPlayer::_notification(int p_notification) { }; }; -Size2 VideoPlayer::get_minimum_size() const { +Size2 VideoStreamPlayer::get_minimum_size() const { if (!expand && !texture.is_null()) { return texture->get_size(); } else { @@ -188,17 +188,17 @@ Size2 VideoPlayer::get_minimum_size() const { } } -void VideoPlayer::set_expand(bool p_expand) { +void VideoStreamPlayer::set_expand(bool p_expand) { expand = p_expand; update(); - minimum_size_changed(); + update_minimum_size(); } -bool VideoPlayer::has_expand() const { +bool VideoStreamPlayer::has_expand() const { return expand; } -void VideoPlayer::set_stream(const Ref<VideoStream> &p_stream) { +void VideoStreamPlayer::set_stream(const Ref<VideoStream> &p_stream) { stop(); AudioServer::get_singleton()->lock(); @@ -241,15 +241,15 @@ void VideoPlayer::set_stream(const Ref<VideoStream> &p_stream) { update(); if (!expand) { - minimum_size_changed(); + update_minimum_size(); } }; -Ref<VideoStream> VideoPlayer::get_stream() const { +Ref<VideoStream> VideoStreamPlayer::get_stream() const { return stream; }; -void VideoPlayer::play() { +void VideoStreamPlayer::play() { ERR_FAIL_COND(!is_inside_tree()); if (playback.is_null()) { return; @@ -262,7 +262,7 @@ void VideoPlayer::play() { last_audio_time = 0; }; -void VideoPlayer::stop() { +void VideoStreamPlayer::stop() { if (!is_inside_tree()) { return; } @@ -277,7 +277,7 @@ void VideoPlayer::stop() { last_audio_time = 0; }; -bool VideoPlayer::is_playing() const { +bool VideoStreamPlayer::is_playing() const { if (playback.is_null()) { return false; } @@ -285,7 +285,7 @@ bool VideoPlayer::is_playing() const { return playback->is_playing(); }; -void VideoPlayer::set_paused(bool p_paused) { +void VideoStreamPlayer::set_paused(bool p_paused) { paused = p_paused; if (playback.is_valid()) { playback->set_paused(p_paused); @@ -294,35 +294,35 @@ void VideoPlayer::set_paused(bool p_paused) { last_audio_time = 0; }; -bool VideoPlayer::is_paused() const { +bool VideoStreamPlayer::is_paused() const { return paused; } -void VideoPlayer::set_buffering_msec(int p_msec) { +void VideoStreamPlayer::set_buffering_msec(int p_msec) { buffering_ms = p_msec; } -int VideoPlayer::get_buffering_msec() const { +int VideoStreamPlayer::get_buffering_msec() const { return buffering_ms; } -void VideoPlayer::set_audio_track(int p_track) { +void VideoStreamPlayer::set_audio_track(int p_track) { audio_track = p_track; } -int VideoPlayer::get_audio_track() const { +int VideoStreamPlayer::get_audio_track() const { return audio_track; } -void VideoPlayer::set_volume(float p_vol) { +void VideoStreamPlayer::set_volume(float p_vol) { volume = p_vol; }; -float VideoPlayer::get_volume() const { +float VideoStreamPlayer::get_volume() const { return volume; }; -void VideoPlayer::set_volume_db(float p_db) { +void VideoStreamPlayer::set_volume_db(float p_db) { if (p_db < -79) { set_volume(0); } else { @@ -330,7 +330,7 @@ void VideoPlayer::set_volume_db(float p_db) { } }; -float VideoPlayer::get_volume_db() const { +float VideoStreamPlayer::get_volume_db() const { if (volume == 0) { return -80; } else { @@ -338,27 +338,27 @@ float VideoPlayer::get_volume_db() const { } }; -String VideoPlayer::get_stream_name() const { +String VideoStreamPlayer::get_stream_name() const { if (stream.is_null()) { return "<No Stream>"; } return stream->get_name(); }; -float VideoPlayer::get_stream_position() const { +float VideoStreamPlayer::get_stream_position() const { if (playback.is_null()) { return 0; } return playback->get_playback_position(); }; -void VideoPlayer::set_stream_position(float p_position) { +void VideoStreamPlayer::set_stream_position(float p_position) { if (playback.is_valid()) { playback->seek(p_position); } } -Ref<Texture2D> VideoPlayer::get_video_texture() const { +Ref<Texture2D> VideoStreamPlayer::get_video_texture() const { if (playback.is_valid()) { return playback->get_texture(); } @@ -366,22 +366,22 @@ Ref<Texture2D> VideoPlayer::get_video_texture() const { return Ref<Texture2D>(); } -void VideoPlayer::set_autoplay(bool p_enable) { +void VideoStreamPlayer::set_autoplay(bool p_enable) { autoplay = p_enable; }; -bool VideoPlayer::has_autoplay() const { +bool VideoStreamPlayer::has_autoplay() const { return autoplay; }; -void VideoPlayer::set_bus(const StringName &p_bus) { +void VideoStreamPlayer::set_bus(const StringName &p_bus) { //if audio is active, must lock this AudioServer::get_singleton()->lock(); bus = p_bus; AudioServer::get_singleton()->unlock(); } -StringName VideoPlayer::get_bus() const { +StringName VideoStreamPlayer::get_bus() const { for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) { if (AudioServer::get_singleton()->get_bus_name(i) == bus) { return bus; @@ -390,7 +390,7 @@ StringName VideoPlayer::get_bus() const { return "Master"; } -void VideoPlayer::_validate_property(PropertyInfo &p_property) const { +void VideoStreamPlayer::_validate_property(PropertyInfo &p_property) const { if (p_property.name == "bus") { String options; for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) { @@ -405,45 +405,45 @@ void VideoPlayer::_validate_property(PropertyInfo &p_property) const { } } -void VideoPlayer::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_stream", "stream"), &VideoPlayer::set_stream); - ClassDB::bind_method(D_METHOD("get_stream"), &VideoPlayer::get_stream); +void VideoStreamPlayer::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_stream", "stream"), &VideoStreamPlayer::set_stream); + ClassDB::bind_method(D_METHOD("get_stream"), &VideoStreamPlayer::get_stream); - ClassDB::bind_method(D_METHOD("play"), &VideoPlayer::play); - ClassDB::bind_method(D_METHOD("stop"), &VideoPlayer::stop); + ClassDB::bind_method(D_METHOD("play"), &VideoStreamPlayer::play); + ClassDB::bind_method(D_METHOD("stop"), &VideoStreamPlayer::stop); - ClassDB::bind_method(D_METHOD("is_playing"), &VideoPlayer::is_playing); + ClassDB::bind_method(D_METHOD("is_playing"), &VideoStreamPlayer::is_playing); - ClassDB::bind_method(D_METHOD("set_paused", "paused"), &VideoPlayer::set_paused); - ClassDB::bind_method(D_METHOD("is_paused"), &VideoPlayer::is_paused); + ClassDB::bind_method(D_METHOD("set_paused", "paused"), &VideoStreamPlayer::set_paused); + ClassDB::bind_method(D_METHOD("is_paused"), &VideoStreamPlayer::is_paused); - ClassDB::bind_method(D_METHOD("set_volume", "volume"), &VideoPlayer::set_volume); - ClassDB::bind_method(D_METHOD("get_volume"), &VideoPlayer::get_volume); + ClassDB::bind_method(D_METHOD("set_volume", "volume"), &VideoStreamPlayer::set_volume); + ClassDB::bind_method(D_METHOD("get_volume"), &VideoStreamPlayer::get_volume); - ClassDB::bind_method(D_METHOD("set_volume_db", "db"), &VideoPlayer::set_volume_db); - ClassDB::bind_method(D_METHOD("get_volume_db"), &VideoPlayer::get_volume_db); + ClassDB::bind_method(D_METHOD("set_volume_db", "db"), &VideoStreamPlayer::set_volume_db); + ClassDB::bind_method(D_METHOD("get_volume_db"), &VideoStreamPlayer::get_volume_db); - ClassDB::bind_method(D_METHOD("set_audio_track", "track"), &VideoPlayer::set_audio_track); - ClassDB::bind_method(D_METHOD("get_audio_track"), &VideoPlayer::get_audio_track); + ClassDB::bind_method(D_METHOD("set_audio_track", "track"), &VideoStreamPlayer::set_audio_track); + ClassDB::bind_method(D_METHOD("get_audio_track"), &VideoStreamPlayer::get_audio_track); - ClassDB::bind_method(D_METHOD("get_stream_name"), &VideoPlayer::get_stream_name); + ClassDB::bind_method(D_METHOD("get_stream_name"), &VideoStreamPlayer::get_stream_name); - ClassDB::bind_method(D_METHOD("set_stream_position", "position"), &VideoPlayer::set_stream_position); - ClassDB::bind_method(D_METHOD("get_stream_position"), &VideoPlayer::get_stream_position); + ClassDB::bind_method(D_METHOD("set_stream_position", "position"), &VideoStreamPlayer::set_stream_position); + ClassDB::bind_method(D_METHOD("get_stream_position"), &VideoStreamPlayer::get_stream_position); - ClassDB::bind_method(D_METHOD("set_autoplay", "enabled"), &VideoPlayer::set_autoplay); - ClassDB::bind_method(D_METHOD("has_autoplay"), &VideoPlayer::has_autoplay); + ClassDB::bind_method(D_METHOD("set_autoplay", "enabled"), &VideoStreamPlayer::set_autoplay); + ClassDB::bind_method(D_METHOD("has_autoplay"), &VideoStreamPlayer::has_autoplay); - ClassDB::bind_method(D_METHOD("set_expand", "enable"), &VideoPlayer::set_expand); - ClassDB::bind_method(D_METHOD("has_expand"), &VideoPlayer::has_expand); + ClassDB::bind_method(D_METHOD("set_expand", "enable"), &VideoStreamPlayer::set_expand); + ClassDB::bind_method(D_METHOD("has_expand"), &VideoStreamPlayer::has_expand); - ClassDB::bind_method(D_METHOD("set_buffering_msec", "msec"), &VideoPlayer::set_buffering_msec); - ClassDB::bind_method(D_METHOD("get_buffering_msec"), &VideoPlayer::get_buffering_msec); + ClassDB::bind_method(D_METHOD("set_buffering_msec", "msec"), &VideoStreamPlayer::set_buffering_msec); + ClassDB::bind_method(D_METHOD("get_buffering_msec"), &VideoStreamPlayer::get_buffering_msec); - ClassDB::bind_method(D_METHOD("set_bus", "bus"), &VideoPlayer::set_bus); - ClassDB::bind_method(D_METHOD("get_bus"), &VideoPlayer::get_bus); + ClassDB::bind_method(D_METHOD("set_bus", "bus"), &VideoStreamPlayer::set_bus); + ClassDB::bind_method(D_METHOD("get_bus"), &VideoStreamPlayer::get_bus); - ClassDB::bind_method(D_METHOD("get_video_texture"), &VideoPlayer::get_video_texture); + ClassDB::bind_method(D_METHOD("get_video_texture"), &VideoStreamPlayer::get_video_texture); ADD_SIGNAL(MethodInfo("finished")); @@ -461,9 +461,9 @@ void VideoPlayer::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus"); } -VideoPlayer::VideoPlayer() {} +VideoStreamPlayer::VideoStreamPlayer() {} -VideoPlayer::~VideoPlayer() { +VideoStreamPlayer::~VideoStreamPlayer() { // if (stream_rid.is_valid()) // AudioServer::get_singleton()->free(stream_rid); resampler.clear(); //Not necessary here, but make in consistent with other "stream_player" classes diff --git a/scene/gui/video_player.h b/scene/gui/video_stream_player.h index 0edad296a1..130b2901f1 100644 --- a/scene/gui/video_player.h +++ b/scene/gui/video_stream_player.h @@ -1,12 +1,12 @@ /*************************************************************************/ -/* video_player.h */ +/* video_stream_player.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -28,16 +28,16 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef VIDEO_PLAYER_H -#define VIDEO_PLAYER_H +#ifndef VIDEO_STREAM_PLAYER_H +#define VIDEO_STREAM_PLAYER_H #include "scene/gui/control.h" #include "scene/resources/video_stream.h" #include "servers/audio/audio_rb_resampler.h" #include "servers/audio_server.h" -class VideoPlayer : public Control { - GDCLASS(VideoPlayer, Control); +class VideoStreamPlayer : public Control { + GDCLASS(VideoStreamPlayer, Control); struct Output { AudioFrame vol; @@ -119,8 +119,8 @@ public: void set_bus(const StringName &p_bus); StringName get_bus() const; - VideoPlayer(); - ~VideoPlayer(); + VideoStreamPlayer(); + ~VideoStreamPlayer(); }; -#endif // VIDEO_PLAYER_H +#endif // VIDEO_STREAM_PLAYER_H diff --git a/scene/gui/view_panner.cpp b/scene/gui/view_panner.cpp new file mode 100644 index 0000000000..ba5e8d4a17 --- /dev/null +++ b/scene/gui/view_panner.cpp @@ -0,0 +1,142 @@ +/*************************************************************************/ +/* view_panner.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 "view_panner.h" + +#include "core/input/input.h" +#include "core/os/keyboard.h" + +bool ViewPanner::gui_input(const Ref<InputEvent> &p_event, Rect2 p_canvas_rect) { + Ref<InputEventMouseButton> mb = p_event; + if (mb.is_valid()) { + // Alt modifier is unused, so ignore such events. + if (mb->is_alt_pressed()) { + return false; + } + + Vector2i scroll_vec = Vector2((mb->get_button_index() == MouseButton::WHEEL_RIGHT) - (mb->get_button_index() == MouseButton::WHEEL_LEFT), (mb->get_button_index() == MouseButton::WHEEL_DOWN) - (mb->get_button_index() == MouseButton::WHEEL_UP)); + if (scroll_vec != Vector2()) { + if (control_scheme == SCROLL_PANS) { + if (mb->is_ctrl_pressed()) { + scroll_vec.y *= mb->get_factor(); + callback_helper(zoom_callback, scroll_vec, mb->get_position()); + return true; + } else { + Vector2 panning; + if (mb->is_shift_pressed()) { + panning.x += mb->get_factor() * scroll_vec.y; + panning.y += mb->get_factor() * scroll_vec.x; + } else { + panning.y += mb->get_factor() * scroll_vec.y; + panning.x += mb->get_factor() * scroll_vec.x; + } + callback_helper(scroll_callback, panning); + return true; + } + } else { + if (mb->is_ctrl_pressed()) { + Vector2 panning; + if (mb->is_shift_pressed()) { + panning.x += mb->get_factor() * scroll_vec.y; + panning.y += mb->get_factor() * scroll_vec.x; + } else { + panning.y += mb->get_factor() * scroll_vec.y; + panning.x += mb->get_factor() * scroll_vec.x; + } + callback_helper(scroll_callback, panning); + return true; + } else if (!mb->is_shift_pressed()) { + scroll_vec.y *= mb->get_factor(); + callback_helper(zoom_callback, scroll_vec, mb->get_position()); + return true; + } + } + } + + if (mb->get_button_index() == MouseButton::MIDDLE || (mb->get_button_index() == MouseButton::RIGHT && !disable_rmb) || (mb->get_button_index() == MouseButton::LEFT && (Input::get_singleton()->is_key_pressed(Key::SPACE) || (is_dragging && !mb->is_pressed())))) { + if (mb->is_pressed()) { + is_dragging = true; + } else { + is_dragging = false; + } + return true; + } + } + + Ref<InputEventMouseMotion> mm = p_event; + if (mm.is_valid()) { + if (is_dragging) { + if (p_canvas_rect != Rect2()) { + callback_helper(pan_callback, Input::get_singleton()->warp_mouse_motion(mm, p_canvas_rect)); + } else { + callback_helper(pan_callback, mm->get_relative()); + } + return true; + } + } + + return false; +} + +void ViewPanner::callback_helper(Callable p_callback, Vector2 p_arg1, Vector2 p_arg2) { + if (p_callback == zoom_callback) { + const Variant **argptr = (const Variant **)alloca(sizeof(Variant *) * 2); + Variant var1 = p_arg1; + argptr[0] = &var1; + Variant var2 = p_arg2; + argptr[1] = &var2; + + Variant result; + Callable::CallError ce; + p_callback.call(argptr, 2, result, ce); + } else { + const Variant **argptr = (const Variant **)alloca(sizeof(Variant *)); + Variant var = p_arg1; + argptr[0] = &var; + + Variant result; + Callable::CallError ce; + p_callback.call(argptr, 1, result, ce); + } +} + +void ViewPanner::set_callbacks(Callable p_scroll_callback, Callable p_pan_callback, Callable p_zoom_callback) { + scroll_callback = p_scroll_callback; + pan_callback = p_pan_callback; + zoom_callback = p_zoom_callback; +} + +void ViewPanner::set_control_scheme(ControlScheme p_scheme) { + control_scheme = p_scheme; +} + +void ViewPanner::set_disable_rmb(bool p_disable) { + disable_rmb = p_disable; +} diff --git a/scene/3d/proximity_group_3d.h b/scene/gui/view_panner.h index e45adc3040..0a92cb3dfd 100644 --- a/scene/3d/proximity_group_3d.h +++ b/scene/gui/view_panner.h @@ -1,12 +1,12 @@ /*************************************************************************/ -/* proximity_group_3d.h */ +/* view_panner.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -28,58 +28,41 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef PROXIMITY_GROUP_H -#define PROXIMITY_GROUP_H +#ifndef VIEW_PANNER_H +#define VIEW_PANNER_H -#include "node_3d.h" +#include "core/object/ref_counted.h" -class ProximityGroup3D : public Node3D { - GDCLASS(ProximityGroup3D, Node3D); +class InputEvent; + +class ViewPanner : public RefCounted { + GDCLASS(ViewPanner, RefCounted); public: - enum DispatchMode { - MODE_PROXY, - MODE_SIGNAL, + enum ControlScheme { + SCROLL_ZOOMS, + SCROLL_PANS, }; private: - Map<StringName, uint32_t> groups; - - String group_name; - DispatchMode dispatch_mode = MODE_PROXY; - Vector3 grid_radius = Vector3(1, 1, 1); - - real_t cell_size = 1.0; - uint32_t group_version = 0; - - void _clear_groups(); - void _update_groups(); - void _add_groups(int *p_cell, String p_base, int p_depth); - void _new_group(StringName p_name); + bool is_dragging = false; + bool disable_rmb = false; - void _proximity_group_broadcast(String p_method, Variant p_parameters); + Callable scroll_callback; + Callable pan_callback; + Callable zoom_callback; -protected: - void _notification(int p_what); - - static void _bind_methods(); + void callback_helper(Callable p_callback, Vector2 p_arg1, Vector2 p_arg2 = Vector2()); + ControlScheme control_scheme = SCROLL_ZOOMS; public: - void set_group_name(const String &p_group_name); - String get_group_name() const; - - void set_dispatch_mode(DispatchMode p_mode); - DispatchMode get_dispatch_mode() const; + void set_callbacks(Callable p_scroll_callback, Callable p_pan_callback, Callable p_zoom_callback); + void set_control_scheme(ControlScheme p_scheme); + void set_disable_rmb(bool p_disable); - void set_grid_radius(const Vector3 &p_radius); - Vector3 get_grid_radius() const; + bool is_panning() const { return is_dragging; } - void broadcast(String p_method, Variant p_parameters); - - ProximityGroup3D(); - ~ProximityGroup3D() {} + bool gui_input(const Ref<InputEvent> &p_ev, Rect2 p_canvas_rect = Rect2()); }; -VARIANT_ENUM_CAST(ProximityGroup3D::DispatchMode); - -#endif // PROXIMITY_GROUP_H +#endif // VIEW_PANNER_H diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index 22e3c3bf24..59d933fa1d 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -99,34 +99,31 @@ void CanvasItem::_propagate_visibility_changed(bool p_visible) { _unblock(); } -void CanvasItem::show() { - if (visible) { +void CanvasItem::set_visible(bool p_visible) { + if (visible == p_visible) { return; } - visible = true; - RenderingServer::get_singleton()->canvas_item_set_visible(canvas_item, true); + visible = p_visible; + RenderingServer::get_singleton()->canvas_item_set_visible(canvas_item, p_visible); if (!is_inside_tree()) { return; } - _propagate_visibility_changed(true); + _propagate_visibility_changed(p_visible); } -void CanvasItem::hide() { - if (!visible) { - return; - } - - visible = false; - RenderingServer::get_singleton()->canvas_item_set_visible(canvas_item, false); +void CanvasItem::show() { + set_visible(true); +} - if (!is_inside_tree()) { - return; - } +void CanvasItem::hide() { + set_visible(false); +} - _propagate_visibility_changed(false); +bool CanvasItem::is_visible() const { + return visible; } CanvasItem *CanvasItem::current_item_drawn = nullptr; @@ -275,9 +272,6 @@ void CanvasItem::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { ERR_FAIL_COND(!is_inside_tree()); - _update_texture_filter_changed(false); - _update_texture_repeat_changed(false); - first_draw = true; Node *parent = get_parent(); if (parent) { @@ -306,6 +300,10 @@ void CanvasItem::_notification(int p_what) { } } _enter_canvas(); + + _update_texture_filter_changed(false); + _update_texture_repeat_changed(false); + if (!block_transform_notify && !xform_change.in_list()) { get_tree()->xform_change_list.add(&xform_change); } @@ -347,24 +345,12 @@ void CanvasItem::_notification(int p_what) { } } -void CanvasItem::set_visible(bool p_visible) { - if (p_visible) { - show(); - } else { - hide(); - } -} - void CanvasItem::_window_visibility_changed() { if (visible) { _propagate_visibility_changed(window->is_visible()); } } -bool CanvasItem::is_visible() const { - return visible; -} - void CanvasItem::update() { if (!is_inside_tree()) { return; @@ -648,16 +634,16 @@ void CanvasItem::draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Tex RenderingServer::get_singleton()->canvas_item_add_multimesh(canvas_item, p_multimesh->get_rid(), texture_rid); } -void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align, real_t p_width, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const { +void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, real_t p_width, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const { ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); ERR_FAIL_COND(p_font.is_null()); - p_font->draw_string(canvas_item, p_pos, p_text, p_align, p_width, p_size, p_modulate, p_outline_size, p_outline_modulate, p_flags); + p_font->draw_string(canvas_item, p_pos, p_text, p_alignment, p_width, p_size, p_modulate, p_outline_size, p_outline_modulate, p_flags); } -void CanvasItem::draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align, real_t p_width, int p_max_lines, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const { +void CanvasItem::draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, real_t p_width, int p_max_lines, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const { ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); ERR_FAIL_COND(p_font.is_null()); - p_font->draw_multiline_string(canvas_item, p_pos, p_text, p_align, p_width, p_max_lines, p_size, p_modulate, p_outline_size, p_outline_modulate, p_flags); + p_font->draw_multiline_string(canvas_item, p_pos, p_text, p_alignment, p_width, p_max_lines, p_size, p_modulate, p_outline_size, p_outline_modulate, p_flags); } real_t CanvasItem::draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, const String &p_next, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate) const { @@ -893,8 +879,8 @@ void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("draw_primitive", "points", "colors", "uvs", "texture", "width"), &CanvasItem::draw_primitive, DEFVAL(Ref<Texture2D>()), DEFVAL(1.0)); ClassDB::bind_method(D_METHOD("draw_polygon", "points", "colors", "uvs", "texture"), &CanvasItem::draw_polygon, DEFVAL(PackedVector2Array()), DEFVAL(Ref<Texture2D>())); ClassDB::bind_method(D_METHOD("draw_colored_polygon", "points", "color", "uvs", "texture"), &CanvasItem::draw_colored_polygon, DEFVAL(PackedVector2Array()), DEFVAL(Ref<Texture2D>())); - ClassDB::bind_method(D_METHOD("draw_string", "font", "pos", "text", "align", "width", "size", "modulate", "outline_size", "outline_modulate", "flags"), &CanvasItem::draw_string, DEFVAL(HALIGN_LEFT), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND)); - ClassDB::bind_method(D_METHOD("draw_multiline_string", "font", "pos", "text", "align", "width", "max_lines", "size", "modulate", "outline_size", "outline_modulate", "flags"), &CanvasItem::draw_multiline_string, DEFVAL(HALIGN_LEFT), DEFVAL(-1), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND)); + ClassDB::bind_method(D_METHOD("draw_string", "font", "pos", "text", "alignment", "width", "size", "modulate", "outline_size", "outline_modulate", "flags"), &CanvasItem::draw_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND)); + ClassDB::bind_method(D_METHOD("draw_multiline_string", "font", "pos", "text", "alignment", "width", "max_lines", "size", "modulate", "outline_size", "outline_modulate", "flags"), &CanvasItem::draw_multiline_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND)); ClassDB::bind_method(D_METHOD("draw_char", "font", "pos", "char", "next", "size", "modulate", "outline_size", "outline_modulate"), &CanvasItem::draw_char, DEFVAL(""), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0))); ClassDB::bind_method(D_METHOD("draw_mesh", "mesh", "texture", "transform", "modulate"), &CanvasItem::draw_mesh, DEFVAL(Transform2D()), DEFVAL(Color(1, 1, 1, 1))); ClassDB::bind_method(D_METHOD("draw_multimesh", "multimesh", "texture"), &CanvasItem::draw_multimesh); diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h index 04376ad809..3d49d89746 100644 --- a/scene/main/canvas_item.h +++ b/scene/main/canvas_item.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -235,8 +235,8 @@ public: void draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture2D> &p_texture, const Transform2D &p_transform = Transform2D(), const Color &p_modulate = Color(1, 1, 1)); void draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture2D> &p_texture); - void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const; - void draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_max_lines = -1, int p_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const; + void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, real_t p_width = -1, int p_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const; + void draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, real_t p_width = -1, int p_max_lines = -1, int p_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const; real_t draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, const String &p_next = "", int p_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0)) const; void draw_set_transform(const Point2 &p_offset, real_t p_rot = 0.0, const Size2 &p_scale = Size2(1.0, 1.0)); diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp index cd7534f73c..282ab6b497 100644 --- a/scene/main/canvas_layer.cpp +++ b/scene/main/canvas_layer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/main/canvas_layer.h b/scene/main/canvas_layer.h index 9d8e0c203d..93a0152787 100644 --- a/scene/main/canvas_layer.h +++ b/scene/main/canvas_layer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp index a4fcc04e20..34cc4aceb8 100644 --- a/scene/main/http_request.cpp +++ b/scene/main/http_request.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -243,7 +243,7 @@ bool HTTPRequest::_handle_response(bool *ret_value) { } } - if (new_request != "") { + if (!new_request.is_empty()) { // Process redirect client->close(); int new_redirs = redirections + 1; // Because _request() will clear it @@ -363,7 +363,7 @@ bool HTTPRequest::_update_connection() { return true; } - if (download_to_file != String()) { + if (!download_to_file.is_empty()) { file = FileAccess::open(download_to_file, FileAccess::WRITE); if (!file) { call_deferred(SNAME("_request_done"), RESULT_DOWNLOAD_FILE_CANT_OPEN, response_code, response_headers, PackedByteArray()); @@ -554,6 +554,14 @@ int HTTPRequest::get_body_size() const { return body_len; } +void HTTPRequest::set_http_proxy(const String &p_host, int p_port) { + client->set_http_proxy(p_host, p_port); +} + +void HTTPRequest::set_https_proxy(const String &p_host, int p_port) { + client->set_https_proxy(p_host, p_port); +} + void HTTPRequest::set_timeout(int p_timeout) { ERR_FAIL_COND(p_timeout < 0); timeout = p_timeout; @@ -602,6 +610,9 @@ void HTTPRequest::_bind_methods() { ClassDB::bind_method(D_METHOD("set_download_chunk_size", "chunk_size"), &HTTPRequest::set_download_chunk_size); ClassDB::bind_method(D_METHOD("get_download_chunk_size"), &HTTPRequest::get_download_chunk_size); + ClassDB::bind_method(D_METHOD("set_http_proxy", "host", "port"), &HTTPRequest::set_http_proxy); + ClassDB::bind_method(D_METHOD("set_https_proxy", "host", "port"), &HTTPRequest::set_https_proxy); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "download_file", PROPERTY_HINT_FILE), "set_download_file", "get_download_file"); ADD_PROPERTY(PropertyInfo(Variant::INT, "download_chunk_size", PROPERTY_HINT_RANGE, "256,16777216"), "set_download_chunk_size", "get_download_chunk_size"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_threads"), "set_use_threads", "is_using_threads"); diff --git a/scene/main/http_request.h b/scene/main/http_request.h index 673cf3a740..62880fa282 100644 --- a/scene/main/http_request.h +++ b/scene/main/http_request.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -154,6 +154,9 @@ public: int get_downloaded_bytes() const; int get_body_size() const; + void set_http_proxy(const String &p_host, int p_port); + void set_https_proxy(const String &p_host, int p_port); + HTTPRequest(); ~HTTPRequest(); }; diff --git a/scene/main/instance_placeholder.cpp b/scene/main/instance_placeholder.cpp index b5ba1899ec..6dd83e4636 100644 --- a/scene/main/instance_placeholder.cpp +++ b/scene/main/instance_placeholder.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/main/instance_placeholder.h b/scene/main/instance_placeholder.h index fe20fc4760..8f2eb01773 100644 --- a/scene/main/instance_placeholder.h +++ b/scene/main/instance_placeholder.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 0d646ff2a9..9d96c71113 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -152,12 +152,6 @@ void Node::_notification(int p_notification) { data.in_constructor = false; } break; case NOTIFICATION_PREDELETE: { - set_owner(nullptr); - - while (data.owned.size()) { - data.owned.front()->get()->set_owner(nullptr); - } - if (data.parent) { data.parent->remove_child(this); } @@ -165,10 +159,8 @@ void Node::_notification(int p_notification) { // kill children as cleanly as possible while (data.children.size()) { Node *child = data.children[data.children.size() - 1]; //begin from the end because its faster and more consistent with creation - remove_child(child); memdelete(child); } - } break; } } @@ -237,11 +229,32 @@ void Node::_propagate_enter_tree() { } void Node::_propagate_after_exit_tree() { + // Clear owner if it was not part of the pruned branch + if (data.owner) { + bool found = false; + Node *parent = data.parent; + + while (parent) { + if (parent == data.owner) { + found = true; + break; + } + + parent = parent->data.parent; + } + + if (!found) { + data.owner->data.owned.erase(data.OW); + data.owner = nullptr; + } + } + data.blocked++; - for (int i = 0; i < data.children.size(); i++) { + for (int i = data.children.size() - 1; i >= 0; i--) { data.children[i]->_propagate_after_exit_tree(); } data.blocked--; + emit_signal(SceneStringNames::get_singleton()->tree_exited); } @@ -892,11 +905,11 @@ void Node::_set_name_nocheck(const StringName &p_name) { void Node::set_name(const String &p_name) { String name = p_name.validate_node_name(); - ERR_FAIL_COND(name == ""); + ERR_FAIL_COND(name.is_empty()); data.name = name; if (data.parent) { - data.parent->_validate_child_name(this); + data.parent->_validate_child_name(this, true); } propagate_notification(NOTIFICATION_PATH_RENAMED); @@ -1144,31 +1157,6 @@ void Node::add_sibling(Node *p_sibling, bool p_legible_unique_name) { data.parent->_move_child(p_sibling, get_index() + 1); } -void Node::_propagate_validate_owner() { - if (data.owner) { - bool found = false; - Node *parent = data.parent; - - while (parent) { - if (parent == data.owner) { - found = true; - break; - } - - parent = parent->data.parent; - } - - if (!found) { - data.owner->data.owned.erase(data.OW); - data.owner = nullptr; - } - } - - for (int i = 0; i < data.children.size(); i++) { - data.children[i]->_propagate_validate_owner(); - } -} - void Node::remove_child(Node *p_child) { ERR_FAIL_NULL(p_child); ERR_FAIL_COND_MSG(data.blocked > 0, "Parent node is busy setting up children, remove_node() failed. Consider using call_deferred(\"remove_child\", child) instead."); @@ -1222,9 +1210,6 @@ void Node::remove_child(Node *p_child) { p_child->data.parent = nullptr; p_child->data.pos = -1; - // validate owner - p_child->_propagate_validate_owner(); - if (data.inside_tree) { p_child->_propagate_after_exit_tree(); } @@ -1990,7 +1975,7 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const nip->set_instance_path(ip->get_instance_path()); node = nip; - } else if ((p_flags & DUPLICATE_USE_INSTANCING) && get_scene_file_path() != String()) { + } else if ((p_flags & DUPLICATE_USE_INSTANCING) && !get_scene_file_path().is_empty()) { Ref<PackedScene> res = ResourceLoader::load(get_scene_file_path()); ERR_FAIL_COND_V(res.is_null(), nullptr); PackedScene::GenEditState ges = PackedScene::GEN_EDIT_STATE_DISABLED; @@ -2001,6 +1986,7 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const #endif node = res->instantiate(ges); ERR_FAIL_COND_V(!node, nullptr); + node->set_scene_instance_load_placeholder(get_scene_instance_load_placeholder()); instantiated = true; @@ -2014,7 +2000,7 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const ERR_FAIL_COND_V(!node, nullptr); } - if (get_scene_file_path() != "") { //an instance + if (!get_scene_file_path().is_empty()) { //an instance node->set_scene_file_path(get_scene_file_path()); node->data.editable_instance = data.editable_instance; } @@ -2046,7 +2032,7 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const node_tree.push_back(descendant); - if (descendant->get_scene_file_path() != "" && instance_roots.has(descendant->get_owner())) { + if (!descendant->get_scene_file_path().is_empty() && instance_roots.has(descendant->get_owner())) { instance_roots.push_back(descendant); } } diff --git a/scene/main/node.h b/scene/main/node.h index dc74a33580..a1fc672a15 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -172,7 +172,6 @@ private: void _propagate_ready(); void _propagate_exit_tree(); void _propagate_after_exit_tree(); - void _propagate_validate_owner(); void _print_stray_nodes(); void _propagate_process_owner(Node *p_owner, int p_pause_notification, int p_enabled_notification); Array _get_node_and_resource(const NodePath &p_path); diff --git a/scene/main/resource_preloader.cpp b/scene/main/resource_preloader.cpp index c44b55284d..49010095ff 100644 --- a/scene/main/resource_preloader.cpp +++ b/scene/main/resource_preloader.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/main/resource_preloader.h b/scene/main/resource_preloader.h index 1b7ea3fb9f..aabb109d56 100644 --- a/scene/main/resource_preloader.h +++ b/scene/main/resource_preloader.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index a122241cd0..cafa4a43fd 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -510,7 +510,7 @@ bool SceneTree::process(double p_time) { cpath = fallback->get_path(); } if (cpath != env_path) { - if (env_path != String()) { + if (!env_path.is_empty()) { fallback = ResourceLoader::load(env_path); if (fallback.is_null()) { //could not load fallback, set as empty @@ -535,7 +535,7 @@ void SceneTree::process_tweens(float p_delta, bool p_physics) { for (List<Ref<Tween>>::Element *E = tweens.front(); E;) { List<Ref<Tween>>::Element *N = E->next(); // Don't process if paused or process mode doesn't match. - if ((paused && E->get()->should_pause()) || (p_physics == (E->get()->get_process_mode() == Tween::TWEEN_PROCESS_IDLE))) { + if (!E->get()->can_process(paused) || (p_physics == (E->get()->get_process_mode() == Tween::TWEEN_PROCESS_IDLE))) { if (E == L) { break; } @@ -1290,7 +1290,7 @@ void SceneTree::get_argument_options(const StringName &p_function, int p_idx, Li dir_access->list_dir_begin(); String filename = dir_access->get_next(); - while (filename != "") { + while (!filename.is_empty()) { if (filename == "." || filename == "..") { filename = dir_access->get_next(); continue; @@ -1355,9 +1355,9 @@ SceneTree::SceneTree() { const bool use_occlusion_culling = GLOBAL_DEF("rendering/occlusion_culling/use_occlusion_culling", false); root->set_use_occlusion_culling(use_occlusion_culling); - float lod_threshold = GLOBAL_DEF("rendering/mesh_lod/lod_change/threshold_pixels", 1.0); + float mesh_lod_threshold = GLOBAL_DEF("rendering/mesh_lod/lod_change/threshold_pixels", 1.0); ProjectSettings::get_singleton()->set_custom_property_info("rendering/mesh_lod/lod_change/threshold_pixels", PropertyInfo(Variant::FLOAT, "rendering/mesh_lod/lod_change/threshold_pixels", PROPERTY_HINT_RANGE, "0,1024,0.1")); - root->set_lod_threshold(lod_threshold); + root->set_mesh_lod_threshold(mesh_lod_threshold); bool snap_2d_transforms = GLOBAL_DEF("rendering/2d/snap/snap_2d_transforms_to_pixel", false); root->set_snap_2d_transforms_to_pixel(snap_2d_transforms); @@ -1400,7 +1400,7 @@ SceneTree::SceneTree() { ResourceLoader::get_recognized_extensions_for_type("Environment", &exts); String ext_hint; for (const String &E : exts) { - if (ext_hint != String()) { + if (!ext_hint.is_empty()) { ext_hint += ","; } ext_hint += "*." + E; @@ -1410,7 +1410,7 @@ SceneTree::SceneTree() { // Setup property. ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/defaults/default_environment", PropertyInfo(Variant::STRING, "rendering/viewport/default_environment", PROPERTY_HINT_FILE, ext_hint)); env_path = env_path.strip_edges(); - if (env_path != String()) { + if (!env_path.is_empty()) { Ref<Environment> env = ResourceLoader::load(env_path); if (env.is_valid()) { root->get_world_3d()->set_fallback_environment(env); diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h index 7a4f9f9c52..1dff1dab4f 100644 --- a/scene/main/scene_tree.h +++ b/scene/main/scene_tree.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/main/shader_globals_override.cpp b/scene/main/shader_globals_override.cpp index 9477e300d1..240e662efb 100644 --- a/scene/main/shader_globals_override.cpp +++ b/scene/main/shader_globals_override.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/main/shader_globals_override.h b/scene/main/shader_globals_override.h index ab4b9de727..af99bf9aa7 100644 --- a/scene/main/shader_globals_override.h +++ b/scene/main/shader_globals_override.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/main/timer.cpp b/scene/main/timer.cpp index 154e4cf683..babe62f453 100644 --- a/scene/main/timer.cpp +++ b/scene/main/timer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/main/timer.h b/scene/main/timer.h index e2f34042dd..8785d31a8a 100644 --- a/scene/main/timer.h +++ b/scene/main/timer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 007e5d1173..4ad250ff54 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -48,6 +48,7 @@ #include "scene/gui/label.h" #include "scene/gui/popup.h" #include "scene/gui/popup_menu.h" +#include "scene/gui/subviewport_container.h" #include "scene/main/canvas_layer.h" #include "scene/main/window.h" #include "scene/resources/mesh.h" @@ -371,8 +372,6 @@ void Viewport::_sub_window_remove(Window *p_window) { void Viewport::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { - gui.embedding_subwindows = gui.embed_subwindows_hint; - if (get_parent()) { parent = get_parent()->get_viewport(); RenderingServer::get_singleton()->viewport_set_parent_viewport(viewport, parent->get_viewport_rid()); @@ -462,6 +461,10 @@ void Viewport::_notification(int p_what) { RenderingServer::get_singleton()->viewport_set_parent_viewport(viewport, RID()); } break; case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { + if (!get_tree()) { + return; + } + if (get_tree()->is_debugging_collisions_hint() && contact_2d_debug.is_valid()) { RenderingServer::get_singleton()->canvas_item_clear(contact_2d_debug); RenderingServer::get_singleton()->canvas_item_set_draw_index(contact_2d_debug, 0xFFFFF); //very high index @@ -1696,13 +1699,13 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { if (over) { Transform2D localizer = over->get_global_transform_with_canvas().affine_inverse(); Size2 pos = localizer.xform(mpos); - Vector2 speed = localizer.basis_xform(mm->get_speed()); + Vector2 velocity = localizer.basis_xform(mm->get_velocity()); Vector2 rel = localizer.basis_xform(mm->get_relative()); mm = mm->xformed_by(Transform2D()); // Make a copy. mm->set_global_position(mpos); - mm->set_speed(speed); + mm->set_velocity(velocity); mm->set_relative(rel); if (mm->get_button_mask() == MouseButton::NONE) { @@ -1952,12 +1955,12 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { if (over->can_process()) { Transform2D localizer = over->get_global_transform_with_canvas().affine_inverse(); Size2 pos = localizer.xform(drag_event->get_position()); - Vector2 speed = localizer.basis_xform(drag_event->get_speed()); + Vector2 velocity = localizer.basis_xform(drag_event->get_velocity()); Vector2 rel = localizer.basis_xform(drag_event->get_relative()); drag_event = drag_event->xformed_by(Transform2D()); // Make a copy. - drag_event->set_speed(speed); + drag_event->set_velocity(velocity); drag_event->set_relative(rel); drag_event->set_position(pos); @@ -2541,7 +2544,7 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) { if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) { bool click_on_window = false; for (int i = gui.sub_windows.size() - 1; i >= 0; i--) { - SubWindow &sw = gui.sub_windows.write[i]; + SubWindow sw = gui.sub_windows.write[i]; // Clicked inside window? @@ -2829,13 +2832,13 @@ bool Viewport::is_using_debanding() const { return use_debanding; } -void Viewport::set_lod_threshold(float p_pixels) { - lod_threshold = p_pixels; - RS::get_singleton()->viewport_set_lod_threshold(viewport, lod_threshold); +void Viewport::set_mesh_lod_threshold(float p_pixels) { + mesh_lod_threshold = p_pixels; + RS::get_singleton()->viewport_set_mesh_lod_threshold(viewport, mesh_lod_threshold); } -float Viewport::get_lod_threshold() const { - return lod_threshold; +float Viewport::get_mesh_lod_threshold() const { + return mesh_lod_threshold; } void Viewport::set_use_occlusion_culling(bool p_use_occlusion_culling) { @@ -3630,8 +3633,8 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_sdf_scale", "scale"), &Viewport::set_sdf_scale); ClassDB::bind_method(D_METHOD("get_sdf_scale"), &Viewport::get_sdf_scale); - ClassDB::bind_method(D_METHOD("set_lod_threshold", "pixels"), &Viewport::set_lod_threshold); - ClassDB::bind_method(D_METHOD("get_lod_threshold"), &Viewport::get_lod_threshold); + ClassDB::bind_method(D_METHOD("set_mesh_lod_threshold", "pixels"), &Viewport::set_mesh_lod_threshold); + ClassDB::bind_method(D_METHOD("get_mesh_lod_threshold"), &Viewport::get_mesh_lod_threshold); ClassDB::bind_method(D_METHOD("_process_picking"), &Viewport::_process_picking); @@ -3681,7 +3684,7 @@ void Viewport::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "screen_space_aa", PROPERTY_HINT_ENUM, "Disabled (Fastest),FXAA (Fast)"), "set_screen_space_aa", "get_screen_space_aa"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_debanding"), "set_use_debanding", "is_using_debanding"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_occlusion_culling"), "set_use_occlusion_culling", "is_using_occlusion_culling"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lod_threshold", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_lod_threshold", "get_lod_threshold"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mesh_lod_threshold", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_mesh_lod_threshold", "get_mesh_lod_threshold"); ADD_PROPERTY(PropertyInfo(Variant::INT, "debug_draw", PROPERTY_HINT_ENUM, "Disabled,Unshaded,Overdraw,Wireframe"), "set_debug_draw", "get_debug_draw"); #ifndef _3D_DISABLED ADD_GROUP("Scaling 3D", ""); @@ -3762,6 +3765,7 @@ void Viewport::_bind_methods() { BIND_ENUM_CONSTANT(DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS); BIND_ENUM_CONSTANT(DEBUG_DRAW_SCENE_LUMINANCE); BIND_ENUM_CONSTANT(DEBUG_DRAW_SSAO); + BIND_ENUM_CONSTANT(DEBUG_DRAW_SSIL); BIND_ENUM_CONSTANT(DEBUG_DRAW_PSSM_SPLITS); BIND_ENUM_CONSTANT(DEBUG_DRAW_DECAL_ATLAS); BIND_ENUM_CONSTANT(DEBUG_DRAW_SDFGI); @@ -3820,7 +3824,7 @@ Viewport::Viewport() { set_shadow_atlas_quadrant_subdiv(2, SHADOW_ATLAS_QUADRANT_SUBDIV_16); set_shadow_atlas_quadrant_subdiv(3, SHADOW_ATLAS_QUADRANT_SUBDIV_64); - set_lod_threshold(lod_threshold); + set_mesh_lod_threshold(mesh_lod_threshold); String id = itos(get_instance_id()); input_group = "_vp_input" + id; @@ -3860,6 +3864,11 @@ Viewport::~Viewport() { void SubViewport::set_size(const Size2i &p_size) { _set_size(p_size, _get_size_2d_override(), Rect2i(), _stretch_transform(), true); + + SubViewportContainer *c = Object::cast_to<SubViewportContainer>(get_parent()); + if (c) { + c->update_minimum_size(); + } } Size2i SubViewport::get_size() const { @@ -3945,8 +3954,8 @@ void SubViewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_clear_mode", "mode"), &SubViewport::set_clear_mode); ClassDB::bind_method(D_METHOD("get_clear_mode"), &SubViewport::get_clear_mode); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size_2d_override"), "set_size_2d_override", "get_size_2d_override"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "size"), "set_size", "get_size"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "size_2d_override"), "set_size_2d_override", "get_size_2d_override"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "size_2d_override_stretch"), "set_size_2d_override_stretch", "is_size_2d_override_stretch_enabled"); ADD_GROUP("Render Target", "render_target_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "render_target_clear_mode", PROPERTY_HINT_ENUM, "Always,Never,Next Frame"), "set_clear_mode", "get_clear_mode"); diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 38d43e1e59..a3127811f5 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -148,6 +148,7 @@ public: DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS, DEBUG_DRAW_SCENE_LUMINANCE, DEBUG_DRAW_SSAO, + DEBUG_DRAW_SSIL, DEBUG_DRAW_PSSM_SPLITS, DEBUG_DRAW_DECAL_ATLAS, DEBUG_DRAW_SDFGI, @@ -296,7 +297,7 @@ private: float fsr_sharpness = 0.2f; float fsr_mipmap_bias = 0.0f; bool use_debanding = false; - float lod_threshold = 1.0; + float mesh_lod_threshold = 1.0; bool use_occlusion_culling = false; Ref<ViewportTexture> default_texture; @@ -361,7 +362,6 @@ private: bool dragging = false; bool drag_successful = false; bool embed_subwindows_hint = false; - bool embedding_subwindows = false; Window *subwindow_focused = nullptr; SubWindowDrag subwindow_drag = SUB_WINDOW_DRAG_DISABLED; @@ -372,7 +372,7 @@ private: SubWindowResize subwindow_resize_mode; Rect2i subwindow_resize_from_rect; - Vector<SubWindow> sub_windows; + Vector<SubWindow> sub_windows; // Don't obtain references or pointers to the elements, as their location can change. } gui; DefaultCanvasItemTextureFilter default_canvas_item_texture_filter = DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR; @@ -530,8 +530,8 @@ public: void set_use_debanding(bool p_use_debanding); bool is_using_debanding() const; - void set_lod_threshold(float p_pixels); - float get_lod_threshold() const; + void set_mesh_lod_threshold(float p_pixels); + float get_mesh_lod_threshold() const; void set_use_occlusion_culling(bool p_us_occlusion_culling); bool is_using_occlusion_culling() const; diff --git a/scene/main/window.cpp b/scene/main/window.cpp index 20f8b30dc6..43de4187d4 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -560,9 +560,12 @@ void Window::_update_viewport_size() { float font_oversampling = 1.0; if (content_scale_mode == CONTENT_SCALE_MODE_DISABLED || content_scale_size.x == 0 || content_scale_size.y == 0) { - stretch_transform = Transform2D(); + font_oversampling = content_scale_factor; final_size = size; + final_size_override = Size2(size) / content_scale_factor; + stretch_transform = Transform2D(); + stretch_transform.scale(Size2(content_scale_factor, content_scale_factor)); } else { //actual screen video mode Size2 video_mode = size; @@ -634,9 +637,9 @@ void Window::_update_viewport_size() { } break; case CONTENT_SCALE_MODE_CANVAS_ITEMS: { final_size = screen_size; - final_size_override = viewport_size; + final_size_override = viewport_size / content_scale_factor; attach_to_screen_rect = Rect2(margin, screen_size); - font_oversampling = screen_size.x / viewport_size.x; + font_oversampling = (screen_size.x / viewport_size.x) * content_scale_factor; Size2 scale = Vector2(screen_size) / Vector2(final_size_override); stretch_transform.scale(scale); @@ -825,6 +828,16 @@ Window::ContentScaleAspect Window::get_content_scale_aspect() const { return content_scale_aspect; } +void Window::set_content_scale_factor(real_t p_factor) { + ERR_FAIL_COND(p_factor <= 0); + content_scale_factor = p_factor; + _update_viewport_size(); +} + +real_t Window::get_content_scale_factor() const { + return content_scale_factor; +} + void Window::set_use_font_oversampling(bool p_oversampling) { if (is_inside_tree() && window_id != DisplayServer::MAIN_WINDOW_ID) { ERR_FAIL_MSG("Only the root window can set and use font oversampling."); @@ -1468,6 +1481,9 @@ void Window::_bind_methods() { ClassDB::bind_method(D_METHOD("set_content_scale_aspect", "aspect"), &Window::set_content_scale_aspect); ClassDB::bind_method(D_METHOD("get_content_scale_aspect"), &Window::get_content_scale_aspect); + ClassDB::bind_method(D_METHOD("set_content_scale_factor", "factor"), &Window::set_content_scale_factor); + ClassDB::bind_method(D_METHOD("get_content_scale_factor"), &Window::get_content_scale_factor); + ClassDB::bind_method(D_METHOD("set_use_font_oversampling", "enable"), &Window::set_use_font_oversampling); ClassDB::bind_method(D_METHOD("is_using_font_oversampling"), &Window::is_using_font_oversampling); @@ -1539,6 +1555,7 @@ void Window::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "content_scale_size"), "set_content_scale_size", "get_content_scale_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_mode", PROPERTY_HINT_ENUM, "Disabled,Canvas Items,Viewport"), "set_content_scale_mode", "get_content_scale_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_aspect", PROPERTY_HINT_ENUM, "Ignore,Keep,Keep Width,Keep Height,Expand"), "set_content_scale_aspect", "get_content_scale_aspect"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "content_scale_factor"), "set_content_scale_factor", "get_content_scale_factor"); ADD_GROUP("Theme", "theme_"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "Theme"), "set_theme", "get_theme"); diff --git a/scene/main/window.h b/scene/main/window.h index 0b1075ff76..2dd1dd6601 100644 --- a/scene/main/window.h +++ b/scene/main/window.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -112,6 +112,7 @@ private: Size2i content_scale_size; ContentScaleMode content_scale_mode = CONTENT_SCALE_MODE_DISABLED; ContentScaleAspect content_scale_aspect = CONTENT_SCALE_ASPECT_IGNORE; + real_t content_scale_factor = 1.0; void _make_window(); void _clear_window(); @@ -230,6 +231,9 @@ public: void set_content_scale_aspect(ContentScaleAspect p_aspect); ContentScaleAspect get_content_scale_aspect() const; + void set_content_scale_factor(real_t p_factor); + real_t get_content_scale_factor() const; + void set_use_font_oversampling(bool p_oversampling); bool is_using_font_oversampling() const; diff --git a/scene/property_utils.cpp b/scene/property_utils.cpp index 7df601492b..2540a633a9 100644 --- a/scene/property_utils.cpp +++ b/scene/property_utils.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -50,7 +50,7 @@ bool PropertyUtils::is_property_value_different(const Variant &p_a, const Varian } } -Variant PropertyUtils::get_property_default_value(const Object *p_object, const StringName &p_property, const Vector<SceneState::PackState> *p_states_stack_cache, bool p_update_exports, const Node *p_owner, bool *r_is_class_default) { +Variant PropertyUtils::get_property_default_value(const Object *p_object, const StringName &p_property, bool *r_is_valid, const Vector<SceneState::PackState> *p_states_stack_cache, bool p_update_exports, const Node *p_owner, bool *r_is_class_default) { // This function obeys the way property values are set when an object is instantiated, // which is the following (the latter wins): // 1. Default value from builtin class @@ -60,6 +60,9 @@ Variant PropertyUtils::get_property_default_value(const Object *p_object, const if (r_is_class_default) { *r_is_class_default = false; } + if (r_is_valid) { + *r_is_valid = false; + } Ref<Script> topmost_script; @@ -71,6 +74,9 @@ Variant PropertyUtils::get_property_default_value(const Object *p_object, const bool found = false; Variant value_in_ancestor = ia.state->get_property_value(ia.node, p_property, found); if (found) { + if (r_is_valid) { + *r_is_valid = true; + } return value_in_ancestor; } // Save script for later @@ -97,15 +103,45 @@ Variant PropertyUtils::get_property_default_value(const Object *p_object, const } Variant default_value; if (topmost_script->get_property_default_value(p_property, default_value)) { + if (r_is_valid) { + *r_is_valid = true; + } return default_value; } } // Fall back to the default from the native class - if (r_is_class_default) { - *r_is_class_default = true; + { + if (r_is_class_default) { + *r_is_class_default = true; + } + bool valid = false; + Variant value = ClassDB::class_get_default_property_value(p_object->get_class_name(), p_property, &valid); + if (valid) { + if (r_is_valid) { + *r_is_valid = true; + } + return value; + } else { + // Heuristically check if this is a synthetic property (whatever/0, whatever/1, etc.) + // because they are not in the class DB yet must have a default (null). + String prop_str = String(p_property); + int p = prop_str.rfind("/"); + if (p != -1 && p < prop_str.length() - 1) { + bool all_digits = true; + for (int i = p + 1; i < prop_str.length(); i++) { + if (prop_str[i] < '0' || prop_str[i] > '9') { + all_digits = false; + break; + } + } + if (r_is_valid) { + *r_is_valid = all_digits; + } + } + return Variant(); + } } - return ClassDB::class_get_default_property_value(p_object->get_class_name(), p_property); } // Like SceneState::PackState, but using a raw pointer to avoid the cost of @@ -164,7 +200,7 @@ Vector<SceneState::PackState> PropertyUtils::get_node_states_stack(const Node *p } } break; - } else if (n->get_scene_file_path() != String()) { + } else if (!n->get_scene_file_path().is_empty()) { const Ref<SceneState> &state = n->get_scene_instance_state(); _collect_inheritance_chain(state, n->get_path_to(p_node), states_stack); } diff --git a/scene/property_utils.h b/scene/property_utils.h index fde9163548..5ada35fdd7 100644 --- a/scene/property_utils.h +++ b/scene/property_utils.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -38,7 +38,7 @@ class PropertyUtils { public: static bool is_property_value_different(const Variant &p_a, const Variant &p_b); // Gets the most pure default value, the one that would be set when the node has just been instantiated - static Variant get_property_default_value(const Object *p_object, const StringName &p_property, const Vector<SceneState::PackState> *p_states_stack_cache = nullptr, bool p_update_exports = false, const Node *p_owner = nullptr, bool *r_is_class_default = nullptr); + static Variant get_property_default_value(const Object *p_object, const StringName &p_property, bool *r_is_valid = nullptr, const Vector<SceneState::PackState> *p_states_stack_cache = nullptr, bool p_update_exports = false, const Node *p_owner = nullptr, bool *r_is_class_default = nullptr); // Gets the instance/inheritance states of this node, in order of precedence, // that is, from the topmost (the most able to override values) to the lowermost diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index b1178b9263..e6b73b7780 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -123,7 +123,7 @@ #include "scene/gui/texture_progress_bar.h" #include "scene/gui/texture_rect.h" #include "scene/gui/tree.h" -#include "scene/gui/video_player.h" +#include "scene/gui/video_stream_player.h" #include "scene/main/canvas_item.h" #include "scene/main/canvas_layer.h" #include "scene/main/http_request.h" @@ -232,7 +232,6 @@ #include "scene/3d/path_3d.h" #include "scene/3d/physics_body_3d.h" #include "scene/3d/position_3d.h" -#include "scene/3d/proximity_group_3d.h" #include "scene/3d/ray_cast_3d.h" #include "scene/3d/reflection_probe.h" #include "scene/3d/remote_transform_3d.h" @@ -361,7 +360,7 @@ void register_scene_types() { GDREGISTER_CLASS(ItemList); GDREGISTER_CLASS(LineEdit); - GDREGISTER_CLASS(VideoPlayer); + GDREGISTER_CLASS(VideoStreamPlayer); #ifndef ADVANCED_GUI_DISABLED GDREGISTER_CLASS(FileDialog); @@ -477,14 +476,14 @@ void register_scene_types() { GDREGISTER_VIRTUAL_CLASS(Lightmapper); GDREGISTER_CLASS(GPUParticles3D); GDREGISTER_VIRTUAL_CLASS(GPUParticlesCollision3D); - GDREGISTER_CLASS(GPUParticlesCollisionBox); - GDREGISTER_CLASS(GPUParticlesCollisionSphere); - GDREGISTER_CLASS(GPUParticlesCollisionSDF); - GDREGISTER_CLASS(GPUParticlesCollisionHeightField); + GDREGISTER_CLASS(GPUParticlesCollisionBox3D); + GDREGISTER_CLASS(GPUParticlesCollisionSphere3D); + GDREGISTER_CLASS(GPUParticlesCollisionSDF3D); + GDREGISTER_CLASS(GPUParticlesCollisionHeightField3D); GDREGISTER_VIRTUAL_CLASS(GPUParticlesAttractor3D); - GDREGISTER_CLASS(GPUParticlesAttractorBox); - GDREGISTER_CLASS(GPUParticlesAttractorSphere); - GDREGISTER_CLASS(GPUParticlesAttractorVectorField); + GDREGISTER_CLASS(GPUParticlesAttractorBox3D); + GDREGISTER_CLASS(GPUParticlesAttractorSphere3D); + GDREGISTER_CLASS(GPUParticlesAttractorVectorField3D); GDREGISTER_CLASS(CPUParticles3D); GDREGISTER_CLASS(Position3D); @@ -511,7 +510,6 @@ void register_scene_types() { GDREGISTER_CLASS(VehicleBody3D); GDREGISTER_CLASS(VehicleWheel3D); GDREGISTER_CLASS(Area3D); - GDREGISTER_CLASS(ProximityGroup3D); GDREGISTER_CLASS(CollisionShape3D); GDREGISTER_CLASS(CollisionPolygon3D); GDREGISTER_CLASS(RayCast3D); @@ -884,6 +882,14 @@ void register_scene_types() { ClassDB::add_compatibility_class("GIProbeData", "VoxelGIData"); ClassDB::add_compatibility_class("BakedLightmap", "LightmapGI"); ClassDB::add_compatibility_class("BakedLightmapData", "LightmapGIData"); + // Portal and room occlusion was replaced by raster occlusion (OccluderInstance3D node). + ClassDB::add_compatibility_class("Portal", "Node3D"); + ClassDB::add_compatibility_class("Room", "Node3D"); + ClassDB::add_compatibility_class("RoomManager", "Node3D"); + ClassDB::add_compatibility_class("RoomGroup", "Node3D"); + ClassDB::add_compatibility_class("Occluder", "Node3D"); + // The OccluderShapeSphere resource (used in the old Occluder node) is not present anymore. + ClassDB::add_compatibility_class("OccluderShapeSphere", "Resource"); // Renamed in 4.0. // Keep alphabetical ordering to easily locate classes and avoid duplicates. @@ -933,6 +939,7 @@ void register_scene_types() { ClassDB::add_compatibility_class("KinematicBody2D", "CharacterBody2D"); ClassDB::add_compatibility_class("KinematicCollision", "KinematicCollision3D"); ClassDB::add_compatibility_class("Light", "Light3D"); + ClassDB::add_compatibility_class("Light2D", "PointLight2D"); ClassDB::add_compatibility_class("LineShape2D", "WorldBoundaryShape2D"); ClassDB::add_compatibility_class("Listener", "AudioListener3D"); ClassDB::add_compatibility_class("MeshInstance", "MeshInstance3D"); @@ -964,7 +971,6 @@ void register_scene_types() { ClassDB::add_compatibility_class("PinJoint", "PinJoint3D"); ClassDB::add_compatibility_class("PlaneShape", "WorldBoundaryShape3D"); ClassDB::add_compatibility_class("ProceduralSky", "Sky"); - ClassDB::add_compatibility_class("ProximityGroup", "ProximityGroup3D"); ClassDB::add_compatibility_class("RayCast", "RayCast3D"); ClassDB::add_compatibility_class("RayShape", "SeparationRayShape3D"); ClassDB::add_compatibility_class("RayShape2D", "SeparationRayShape2D"); @@ -986,13 +992,17 @@ void register_scene_types() { ClassDB::add_compatibility_class("SpringArm", "SpringArm3D"); ClassDB::add_compatibility_class("Sprite", "Sprite2D"); ClassDB::add_compatibility_class("StaticBody", "StaticBody3D"); + ClassDB::add_compatibility_class("StreamTexture", "StreamTexture2D"); ClassDB::add_compatibility_class("TextureProgress", "TextureProgressBar"); ClassDB::add_compatibility_class("VehicleBody", "VehicleBody3D"); ClassDB::add_compatibility_class("VehicleWheel", "VehicleWheel3D"); + ClassDB::add_compatibility_class("VideoPlayer", "VideoStreamPlayer"); ClassDB::add_compatibility_class("ViewportContainer", "SubViewportContainer"); ClassDB::add_compatibility_class("Viewport", "SubViewport"); ClassDB::add_compatibility_class("VisibilityEnabler", "VisibleOnScreenEnabler3D"); ClassDB::add_compatibility_class("VisibilityNotifier", "VisibleOnScreenNotifier3D"); + ClassDB::add_compatibility_class("VisibilityNotifier2D", "VisibleOnScreenNotifier2D"); + ClassDB::add_compatibility_class("VisibilityNotifier3D", "VisibleOnScreenNotifier3D"); ClassDB::add_compatibility_class("VisualServer", "RenderingServer"); ClassDB::add_compatibility_class("VisualShaderNodeScalarConstant", "VisualShaderNodeFloatConstant"); ClassDB::add_compatibility_class("VisualShaderNodeScalarFunc", "VisualShaderNodeFloatFunc"); @@ -1010,11 +1020,6 @@ void register_scene_types() { ClassDB::add_compatibility_class("VisualShaderNodeScalarSwitch", "VisualShaderNodeSwitch"); ClassDB::add_compatibility_class("VisualShaderNodeScalarTransformMult", "VisualShaderNodeTransformOp"); ClassDB::add_compatibility_class("World", "World3D"); - ClassDB::add_compatibility_class("StreamTexture", "StreamTexture2D"); - ClassDB::add_compatibility_class("Light2D", "PointLight2D"); - ClassDB::add_compatibility_class("VisibilityNotifier2D", "VisibleOnScreenNotifier2D"); - ClassDB::add_compatibility_class("VisibilityNotifier3D", "VisibleOnScreenNotifier3D"); - #endif /* DISABLE_DEPRECATED */ OS::get_singleton()->yield(); // may take time to init @@ -1049,7 +1054,7 @@ void initialize_theme() { ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/custom_font", PropertyInfo(Variant::STRING, "gui/theme/custom_font", PROPERTY_HINT_FILE, "*.tres,*.res,*.font", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)); Ref<Font> font; - if (font_path != String()) { + if (!font_path.is_empty()) { font = ResourceLoader::load(font_path); if (!font.is_valid()) { ERR_PRINT("Error loading custom font '" + font_path + "'"); @@ -1061,12 +1066,12 @@ void initialize_theme() { make_default_theme(default_theme_hidpi, font); } - if (theme_path != String()) { + if (!theme_path.is_empty()) { Ref<Theme> theme = ResourceLoader::load(theme_path); if (theme.is_valid()) { Theme::set_project_default(theme); if (font.is_valid()) { - Theme::set_default_font(font); + Theme::set_fallback_font(font); } } else { ERR_PRINT("Error loading custom theme '" + theme_path + "'"); diff --git a/scene/register_scene_types.h b/scene/register_scene_types.h index 32ab165fb3..f0a14387c1 100644 --- a/scene/register_scene_types.h +++ b/scene/register_scene_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index e3cf9183a0..44d3e4af19 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -2715,6 +2715,7 @@ void Animation::value_track_set_update_mode(int p_track, UpdateMode p_mode) { ValueTrack *vt = static_cast<ValueTrack *>(t); vt->update_mode = p_mode; + emit_changed(); } Animation::UpdateMode Animation::value_track_get_update_mode(int p_track) const { @@ -3998,13 +3999,12 @@ bool Animation::_blend_shape_track_optimize_key(const TKey<float> &t0, const TKe float v1 = t1.value; float v2 = t2.value; - if (Math::is_equal_approx(v1, v2, p_allowed_unit_error)) { + if (Math::is_equal_approx(v1, v2, (float)p_allowed_unit_error)) { //0 and 2 are close, let's see if 1 is close - if (!Math::is_equal_approx(v0, v1, p_allowed_unit_error)) { + if (!Math::is_equal_approx(v0, v1, (float)p_allowed_unit_error)) { //not close, not optimizable return false; } - } else { /* TODO eventually discuss a way to optimize these better. @@ -4198,7 +4198,7 @@ struct AnimationCompressionDataState { }; uint32_t components = 3; - LocalVector<uint8_t> data; //commited packets + LocalVector<uint8_t> data; // Committed packets. struct PacketData { int32_t data[3] = { 0, 0, 0 }; uint32_t frame = 0; @@ -4577,7 +4577,7 @@ void Animation::compress(uint32_t p_page_size, uint32_t p_fps, float p_split_tol } } for (int j = 0; j < 3; j++) { - //cant have zero + // Can't have zero. if (aabb.size[j] < CMP_EPSILON) { aabb.size[j] = CMP_EPSILON; } @@ -4597,7 +4597,7 @@ void Animation::compress(uint32_t p_page_size, uint32_t p_fps, float p_split_tol } } for (int j = 0; j < 3; j++) { - //cant have zero + // Can't have zero. if (aabb.size[j] < CMP_EPSILON) { aabb.size[j] = CMP_EPSILON; } diff --git a/scene/resources/animation.h b/scene/resources/animation.h index 8e4287e4fb..f9a33da428 100644 --- a/scene/resources/animation.h +++ b/scene/resources/animation.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/audio_stream_sample.cpp b/scene/resources/audio_stream_sample.cpp index d3fab802c5..56786ac4b1 100644 --- a/scene/resources/audio_stream_sample.cpp +++ b/scene/resources/audio_stream_sample.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/audio_stream_sample.h b/scene/resources/audio_stream_sample.h index 0eb34be9bf..043a62ff70 100644 --- a/scene/resources/audio_stream_sample.h +++ b/scene/resources/audio_stream_sample.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/bit_map.cpp b/scene/resources/bit_map.cpp index 16f1507c34..25f169b6a2 100644 --- a/scene/resources/bit_map.cpp +++ b/scene/resources/bit_map.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/bit_map.h b/scene/resources/bit_map.h index 68fd0b999a..0d0d779c32 100644 --- a/scene/resources/bit_map.h +++ b/scene/resources/bit_map.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/box_shape_3d.cpp b/scene/resources/box_shape_3d.cpp index 008914c5ee..b97d378e02 100644 --- a/scene/resources/box_shape_3d.cpp +++ b/scene/resources/box_shape_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/box_shape_3d.h b/scene/resources/box_shape_3d.h index 91978a0e6a..4e6db893af 100644 --- a/scene/resources/box_shape_3d.h +++ b/scene/resources/box_shape_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/camera_effects.cpp b/scene/resources/camera_effects.cpp index 0df372ea1b..ebe2aa4dba 100644 --- a/scene/resources/camera_effects.cpp +++ b/scene/resources/camera_effects.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/camera_effects.h b/scene/resources/camera_effects.h index b9338f4806..85ae64cdf5 100644 --- a/scene/resources/camera_effects.h +++ b/scene/resources/camera_effects.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/canvas_item_material.cpp b/scene/resources/canvas_item_material.cpp index b291724c4c..2d668cdf7f 100644 --- a/scene/resources/canvas_item_material.cpp +++ b/scene/resources/canvas_item_material.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/canvas_item_material.h b/scene/resources/canvas_item_material.h index 37cd4de136..e40e4392cb 100644 --- a/scene/resources/canvas_item_material.h +++ b/scene/resources/canvas_item_material.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/capsule_shape_2d.cpp b/scene/resources/capsule_shape_2d.cpp index 0818e4fd99..cb8a189116 100644 --- a/scene/resources/capsule_shape_2d.cpp +++ b/scene/resources/capsule_shape_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/capsule_shape_2d.h b/scene/resources/capsule_shape_2d.h index 37b6c52c0e..ec8b540947 100644 --- a/scene/resources/capsule_shape_2d.h +++ b/scene/resources/capsule_shape_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/capsule_shape_3d.cpp b/scene/resources/capsule_shape_3d.cpp index afec7b1877..c16ddad984 100644 --- a/scene/resources/capsule_shape_3d.cpp +++ b/scene/resources/capsule_shape_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/capsule_shape_3d.h b/scene/resources/capsule_shape_3d.h index f09b4fb77d..967a413da4 100644 --- a/scene/resources/capsule_shape_3d.h +++ b/scene/resources/capsule_shape_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/circle_shape_2d.cpp b/scene/resources/circle_shape_2d.cpp index f06bc4248d..68ee1be9f9 100644 --- a/scene/resources/circle_shape_2d.cpp +++ b/scene/resources/circle_shape_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/circle_shape_2d.h b/scene/resources/circle_shape_2d.h index 333f299236..62a907387f 100644 --- a/scene/resources/circle_shape_2d.h +++ b/scene/resources/circle_shape_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/concave_polygon_shape_2d.cpp b/scene/resources/concave_polygon_shape_2d.cpp index 0c767c8a52..b188a6164d 100644 --- a/scene/resources/concave_polygon_shape_2d.cpp +++ b/scene/resources/concave_polygon_shape_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/concave_polygon_shape_2d.h b/scene/resources/concave_polygon_shape_2d.h index 98ae341e97..0f49a0d80f 100644 --- a/scene/resources/concave_polygon_shape_2d.h +++ b/scene/resources/concave_polygon_shape_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/concave_polygon_shape_3d.cpp b/scene/resources/concave_polygon_shape_3d.cpp index 03854683bd..3e178108c4 100644 --- a/scene/resources/concave_polygon_shape_3d.cpp +++ b/scene/resources/concave_polygon_shape_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/concave_polygon_shape_3d.h b/scene/resources/concave_polygon_shape_3d.h index bb28359dcc..5337deb5fb 100644 --- a/scene/resources/concave_polygon_shape_3d.h +++ b/scene/resources/concave_polygon_shape_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/convex_polygon_shape_2d.cpp b/scene/resources/convex_polygon_shape_2d.cpp index ac31315858..667399ee75 100644 --- a/scene/resources/convex_polygon_shape_2d.cpp +++ b/scene/resources/convex_polygon_shape_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/convex_polygon_shape_2d.h b/scene/resources/convex_polygon_shape_2d.h index 1813b608bd..4896d3ec66 100644 --- a/scene/resources/convex_polygon_shape_2d.h +++ b/scene/resources/convex_polygon_shape_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/convex_polygon_shape_3d.cpp b/scene/resources/convex_polygon_shape_3d.cpp index 6b895da606..e7960f1ba4 100644 --- a/scene/resources/convex_polygon_shape_3d.cpp +++ b/scene/resources/convex_polygon_shape_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/convex_polygon_shape_3d.h b/scene/resources/convex_polygon_shape_3d.h index edd127c8f4..930edb015d 100644 --- a/scene/resources/convex_polygon_shape_3d.h +++ b/scene/resources/convex_polygon_shape_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp index bf3efd7599..d2cd76b796 100644 --- a/scene/resources/curve.cpp +++ b/scene/resources/curve.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/curve.h b/scene/resources/curve.h index 16facda85a..767900b843 100644 --- a/scene/resources/curve.h +++ b/scene/resources/curve.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/cylinder_shape_3d.cpp b/scene/resources/cylinder_shape_3d.cpp index 63bdc8d26d..5eeb62d17b 100644 --- a/scene/resources/cylinder_shape_3d.cpp +++ b/scene/resources/cylinder_shape_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/cylinder_shape_3d.h b/scene/resources/cylinder_shape_3d.h index d1b8364672..0211f2b08f 100644 --- a/scene/resources/cylinder_shape_3d.h +++ b/scene/resources/cylinder_shape_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index a1d76ef352..61cd834867 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -407,6 +407,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("minimum_character_width", "LineEdit", 4); theme->set_constant("outline_size", "LineEdit", 0); + theme->set_constant("caret_width", "LineEdit", 1); theme->set_icon("clear", "LineEdit", make_icon(line_edit_clear_png)); @@ -451,6 +452,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("line_spacing", "TextEdit", 4 * scale); theme->set_constant("outline_size", "TextEdit", 0); + theme->set_constant("caret_width", "TextEdit", 1); // CodeEdit @@ -770,8 +772,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const tc_sb->set_default_margin(SIDE_TOP, 8 * scale); theme->set_stylebox("tab_selected", "TabContainer", sb_expand(make_stylebox(tab_current_png, 4, 4, 4, 1, 16, 4, 16, 4), 2, 2, 2, 2)); - theme->set_stylebox("tab_unselected", "TabContainer", sb_expand(make_stylebox(tab_behind_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 3)); - theme->set_stylebox("tab_disabled", "TabContainer", sb_expand(make_stylebox(tab_disabled_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 3)); + theme->set_stylebox("tab_unselected", "TabContainer", sb_expand(make_stylebox(tab_behind_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 0)); + theme->set_stylebox("tab_disabled", "TabContainer", sb_expand(make_stylebox(tab_disabled_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 0)); theme->set_stylebox("panel", "TabContainer", tc_sb); theme->set_icon("increment", "TabContainer", make_icon(scroll_button_right_png)); @@ -795,9 +797,9 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const // TabBar - theme->set_stylebox("tab_selected", "TabBar", sb_expand(make_stylebox(tab_current_png, 4, 3, 4, 1, 16, 3, 16, 2), 2, 2, 2, 2)); - theme->set_stylebox("tab_unselected", "TabBar", sb_expand(make_stylebox(tab_behind_png, 5, 4, 5, 1, 16, 5, 16, 2), 3, 3, 3, 3)); - theme->set_stylebox("tab_disabled", "TabBar", sb_expand(make_stylebox(tab_disabled_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 3)); + theme->set_stylebox("tab_selected", "TabBar", sb_expand(make_stylebox(tab_current_png, 4, 4, 4, 1, 16, 4, 16, 4), 2, 2, 2, 2)); + theme->set_stylebox("tab_unselected", "TabBar", sb_expand(make_stylebox(tab_behind_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 0)); + theme->set_stylebox("tab_disabled", "TabBar", sb_expand(make_stylebox(tab_disabled_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 0)); theme->set_stylebox("close_bg_pressed", "TabBar", make_stylebox(button_pressed_png, 4, 4, 4, 4)); theme->set_stylebox("close_bg_highlight", "TabBar", make_stylebox(button_normal_png, 4, 4, 4, 4)); @@ -994,7 +996,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const // Visual Node Ports theme->set_constant("port_grab_distance_horizontal", "GraphEdit", 24 * scale); - theme->set_constant("port_grab_distance_vertical", "GraphEdit", 6 * scale); + theme->set_constant("port_grab_distance_vertical", "GraphEdit", 26 * scale); theme->set_stylebox("bg", "GraphEditMinimap", make_flat_stylebox(Color(0.24, 0.24, 0.24), 0, 0, 0, 0)); Ref<StyleBoxFlat> style_minimap_camera = make_flat_stylebox(Color(0.65, 0.65, 0.65, 0.2), 0, 0, 0, 0); @@ -1053,17 +1055,17 @@ void make_default_theme(bool p_hidpi, Ref<Font> p_font) { fill_default_theme(t, default_font, large_font, default_icon, default_style, default_scale); Theme::set_default(t); - Theme::set_default_base_scale(default_scale); - Theme::set_default_icon(default_icon); - Theme::set_default_style(default_style); - Theme::set_default_font(default_font); - Theme::set_default_font_size(default_font_size); + Theme::set_fallback_base_scale(default_scale); + Theme::set_fallback_icon(default_icon); + Theme::set_fallback_style(default_style); + Theme::set_fallback_font(default_font); + Theme::set_fallback_font_size(default_font_size); } void clear_default_theme() { Theme::set_project_default(nullptr); Theme::set_default(nullptr); - Theme::set_default_icon(nullptr); - Theme::set_default_style(nullptr); - Theme::set_default_font(nullptr); + Theme::set_fallback_icon(nullptr); + Theme::set_fallback_style(nullptr); + Theme::set_fallback_font(nullptr); } diff --git a/scene/resources/default_theme/default_theme.h b/scene/resources/default_theme/default_theme.h index 4cd781e814..e6d7b31b3e 100644 --- a/scene/resources/default_theme/default_theme.h +++ b/scene/resources/default_theme/default_theme.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/default_theme/tab_current.png b/scene/resources/default_theme/tab_current.png Binary files differindex d5641e917a..ce2b9b0925 100644 --- a/scene/resources/default_theme/tab_current.png +++ b/scene/resources/default_theme/tab_current.png diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h index 57ff9a5325..1cec50eab4 100644 --- a/scene/resources/default_theme/theme_data.h +++ b/scene/resources/default_theme/theme_data.h @@ -395,7 +395,7 @@ static const unsigned char tab_container_bg_png[] = { }; static const unsigned char tab_current_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x99, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x3d, 0x48, 0x5b, 0x58, 0x66, 0x5b, 0x57, 0x65, 0x57, 0x54, 0x62, 0x55, 0x53, 0x62, 0x4a, 0x46, 0x52, 0x46, 0x41, 0x4e, 0x45, 0x41, 0x4d, 0x55, 0x52, 0x60, 0x44, 0x41, 0x4c, 0x53, 0x50, 0x5e, 0x43, 0x40, 0x4b, 0x52, 0x4e, 0x5d, 0x41, 0x3e, 0x4a, 0x4f, 0x4d, 0x5a, 0x3f, 0x3d, 0x48, 0x4e, 0x4b, 0x59, 0x3e, 0x3c, 0x47, 0x4d, 0x4a, 0x58, 0x3d, 0x3b, 0x46, 0x4b, 0x49, 0x54, 0x3c, 0x3a, 0x44, 0x4b, 0x47, 0x54, 0x3b, 0x39, 0x43, 0x3b, 0x39, 0x42, 0x3b, 0x38, 0x43, 0x3b, 0x38, 0x42, 0x3a, 0x37, 0x41, 0x39, 0x37, 0x41, 0x3a, 0x38, 0x41, 0x39, 0x36, 0x3f, 0x38, 0x36, 0x3f, 0x39, 0x36, 0x40, 0x38, 0x36, 0x40, 0x37, 0x35, 0x3e, 0x37, 0x34, 0x3e, 0x36, 0x35, 0x3d, 0xd7, 0x41, 0xa4, 0x19, 0x0, 0x0, 0x0, 0x11, 0x74, 0x52, 0x4e, 0x53, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x77, 0xef, 0xef, 0xa3, 0x31, 0x6b, 0xc2, 0x0, 0x0, 0x0, 0x5f, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x55, 0xca, 0x85, 0xd, 0xc0, 0x40, 0x14, 0xc3, 0x50, 0x27, 0xf7, 0xd5, 0xfd, 0xd7, 0x2d, 0xa6, 0x4c, 0x16, 0x3f, 0x59, 0xe8, 0x8, 0xc8, 0x91, 0xd4, 0x5d, 0x92, 0xa3, 0xa1, 0x76, 0xb1, 0xd8, 0xcb, 0x92, 0x41, 0x1b, 0xb8, 0xe9, 0x2, 0xcf, 0xd2, 0x7e, 0xc4, 0x9c, 0x2d, 0xed, 0x3c, 0xc4, 0x95, 0xa3, 0x3f, 0xb0, 0x3, 0x7f, 0xa0, 0xe0, 0xb, 0x50, 0xe4, 0xb, 0xa1, 0xf2, 0x87, 0x38, 0x31, 0x4f, 0x4e, 0xa, 0x30, 0x22, 0x58, 0x33, 0x81, 0x1d, 0x4a, 0x44, 0x5a, 0xec, 0x8c, 0x27, 0x34, 0x10, 0x58, 0xf1, 0xf8, 0x39, 0xe0, 0x60, 0x56, 0x63, 0x63, 0x30, 0x69, 0xf8, 0x3c, 0xb4, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 + 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x1, 0x71, 0x69, 0x43, 0x43, 0x50, 0x69, 0x63, 0x63, 0x0, 0x0, 0x28, 0x91, 0x75, 0x91, 0x3d, 0x4b, 0xc3, 0x50, 0x14, 0x86, 0xdf, 0xb6, 0x8a, 0xa2, 0x91, 0xe, 0x15, 0x11, 0x71, 0xc8, 0x50, 0xc5, 0xa1, 0x85, 0xa2, 0x20, 0x8e, 0x5a, 0x87, 0x2e, 0x45, 0x4a, 0xad, 0x60, 0xd5, 0x25, 0xb9, 0x4d, 0x5a, 0x21, 0x49, 0xc3, 0x4d, 0x8a, 0x14, 0x57, 0xc1, 0xc5, 0xa1, 0xe0, 0x20, 0xba, 0xf8, 0x35, 0xf8, 0xf, 0x74, 0x15, 0x5c, 0x15, 0x4, 0x41, 0x11, 0x44, 0x9c, 0xfc, 0x1, 0x7e, 0x2d, 0x52, 0xe2, 0xb9, 0x4d, 0xa1, 0x45, 0xda, 0x13, 0x6e, 0xce, 0xc3, 0x7b, 0xcf, 0x7b, 0xb8, 0xf7, 0x5c, 0x20, 0x98, 0x36, 0x98, 0xe9, 0xf4, 0x24, 0x0, 0xd3, 0x72, 0x79, 0x36, 0x95, 0x94, 0x57, 0xf3, 0x6b, 0x72, 0xdf, 0x3b, 0x2, 0x90, 0x30, 0x82, 0x8, 0x24, 0x85, 0x39, 0xf6, 0x42, 0x26, 0x93, 0x46, 0xd7, 0xf8, 0x79, 0xa4, 0x6a, 0x8a, 0x87, 0xb8, 0xe8, 0xd5, 0xbd, 0xae, 0x63, 0xc, 0x16, 0x34, 0x87, 0x1, 0x81, 0x7e, 0xe2, 0x59, 0x66, 0x73, 0x97, 0x78, 0x9e, 0x38, 0xbd, 0xe5, 0xda, 0x82, 0xf7, 0x88, 0x87, 0x59, 0x49, 0x29, 0x10, 0x9f, 0x10, 0xc7, 0x38, 0x1d, 0x90, 0xf8, 0x56, 0xe8, 0xaa, 0xcf, 0x6f, 0x82, 0x8b, 0x3e, 0x7f, 0x9, 0xe6, 0xb9, 0xec, 0x22, 0x10, 0x14, 0x3d, 0xe5, 0x62, 0x1b, 0xab, 0x6d, 0xcc, 0x4a, 0xdc, 0x24, 0x9e, 0x22, 0x8e, 0x9a, 0x46, 0x85, 0x35, 0xcf, 0x23, 0x6e, 0x22, 0x69, 0xd6, 0xca, 0x32, 0xe5, 0x31, 0x5a, 0xe3, 0x70, 0x90, 0x45, 0xa, 0x49, 0xc8, 0x50, 0x51, 0xc1, 0x26, 0xc, 0xb8, 0x88, 0x53, 0xb6, 0x68, 0x66, 0x9d, 0x7d, 0x89, 0x86, 0x6f, 0x9, 0x65, 0xf2, 0x30, 0xfa, 0xdb, 0xa8, 0x82, 0x93, 0xa3, 0x88, 0x12, 0x79, 0x63, 0xa4, 0x56, 0xa8, 0xab, 0x46, 0x59, 0x27, 0x5d, 0xa3, 0xcf, 0x40, 0x55, 0xcc, 0xfd, 0xff, 0x3c, 0x1d, 0x7d, 0x66, 0xda, 0xef, 0x2e, 0x25, 0x81, 0xde, 0x57, 0xcf, 0xfb, 0x9c, 0x0, 0xfa, 0xf6, 0x81, 0x7a, 0xcd, 0xf3, 0x7e, 0x4f, 0x3d, 0xaf, 0x7e, 0x6, 0x84, 0x5e, 0x80, 0x6b, 0xab, 0xe5, 0x2f, 0xd3, 0x9c, 0xe6, 0xbe, 0x49, 0xaf, 0xb5, 0xb4, 0xe8, 0x31, 0x10, 0xde, 0x1, 0x2e, 0x6f, 0x5a, 0x9a, 0x7a, 0x0, 0x5c, 0xed, 0x2, 0xa3, 0xcf, 0xb6, 0xc2, 0x95, 0x86, 0x14, 0xa2, 0x15, 0xd4, 0x75, 0xe0, 0xe3, 0x2, 0x18, 0xca, 0x3, 0x91, 0x7b, 0x60, 0x60, 0xdd, 0x9f, 0x55, 0x73, 0x1f, 0xe7, 0x4f, 0x40, 0x6e, 0x9b, 0x9e, 0xe8, 0xe, 0x38, 0x3c, 0x2, 0x26, 0xa9, 0x3e, 0xbc, 0xf1, 0x7, 0x9c, 0x2f, 0x67, 0xdc, 0x46, 0x9a, 0x3c, 0x4e, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x12, 0x0, 0x0, 0xb, 0x12, 0x1, 0xd2, 0xdd, 0x7e, 0xfc, 0x0, 0x0, 0x1, 0x27, 0x49, 0x44, 0x41, 0x54, 0x38, 0xcb, 0x9d, 0x93, 0x41, 0x4e, 0xc3, 0x30, 0x10, 0x45, 0xc7, 0xee, 0xd0, 0x82, 0x58, 0xd4, 0x6b, 0x28, 0xdc, 0x4, 0xc1, 0x92, 0x35, 0xa7, 0xe9, 0x11, 0x38, 0xd, 0x6b, 0x36, 0x2c, 0x10, 0x3b, 0xee, 0xc0, 0x6, 0x95, 0x1d, 0x6a, 0x83, 0x54, 0x4, 0xad, 0x1d, 0xf, 0x7f, 0xf0, 0x4, 0xb5, 0x52, 0x11, 0xe, 0x3f, 0x7a, 0x91, 0x93, 0x7c, 0xff, 0x78, 0x9c, 0x89, 0x23, 0x22, 0x6, 0x43, 0x30, 0x2, 0xfb, 0x36, 0x1e, 0x0, 0x4f, 0xdb, 0xca, 0xa0, 0x5, 0x6b, 0xf0, 0x9, 0x56, 0x3a, 0xee, 0x26, 0x1f, 0x82, 0x0, 0xc6, 0x36, 0xd6, 0x30, 0x67, 0xa8, 0xc4, 0xd0, 0x49, 0xef, 0xe0, 0xd, 0x34, 0x64, 0x6f, 0x57, 0x73, 0x38, 0x3f, 0xbb, 0xbc, 0x9a, 0x1c, 0x9f, 0x4e, 0x53, 0x4a, 0x21, 0xb, 0xed, 0x94, 0x47, 0x1c, 0x33, 0x37, 0xb3, 0x97, 0xe7, 0xeb, 0xfb, 0x87, 0xdb, 0x1b, 0xdc, 0x4a, 0x6c, 0xcb, 0x1e, 0x4f, 0x8e, 0x4e, 0xa6, 0x8b, 0xf9, 0x6b, 0x48, 0x31, 0xe1, 0x55, 0xbb, 0x13, 0x1c, 0xe, 0xde, 0xe3, 0xa0, 0x5e, 0x5c, 0xde, 0x81, 0xe5, 0x4f, 0x9, 0xeb, 0x18, 0x43, 0x8c, 0xf1, 0xd7, 0xc9, 0xa5, 0xe, 0x21, 0xf5, 0xa8, 0xd7, 0x4a, 0x1d, 0xb2, 0x6d, 0xd8, 0x28, 0xe7, 0x4c, 0x59, 0x32, 0xfd, 0x25, 0xd, 0x51, 0xaf, 0x95, 0x3e, 0x60, 0xdb, 0x6d, 0x27, 0x59, 0x1f, 0x8, 0xd5, 0x48, 0x8a, 0x4f, 0x37, 0xd8, 0x73, 0x57, 0x5e, 0x2b, 0x6d, 0xd5, 0xa, 0x54, 0xea, 0xed, 0xbe, 0x10, 0x6f, 0xa6, 0x8a, 0xf4, 0x5a, 0x1, 0x6d, 0x6, 0x88, 0x4e, 0xae, 0xe, 0x28, 0xbe, 0xef, 0x93, 0xb7, 0xe, 0x43, 0x68, 0xa2, 0x5a, 0x99, 0x57, 0x3, 0xb2, 0xb7, 0xf6, 0x5c, 0x51, 0xa6, 0x7a, 0x15, 0xaf, 0x76, 0x65, 0xcb, 0x5b, 0x8d, 0xe2, 0x1c, 0xf5, 0x15, 0xdb, 0x8f, 0xd1, 0xfc, 0x23, 0xe0, 0xa0, 0x6b, 0x24, 0xfd, 0xbb, 0x96, 0xa5, 0xd7, 0x7b, 0x5, 0xcc, 0xc1, 0x87, 0xee, 0xc1, 0x2, 0x3c, 0x81, 0xb, 0xa1, 0xba, 0x43, 0xbd, 0xe0, 0x11, 0xcc, 0xbe, 0x0, 0xbe, 0xe0, 0x95, 0x8, 0xaf, 0xb2, 0x52, 0x33, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; static const unsigned char tab_disabled_png[] = { diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index 4c25ed589b..7e71ad8986 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -426,6 +426,64 @@ void Environment::_update_ssao() { ssao_ao_channel_affect); } +// SSIL + +void Environment::set_ssil_enabled(bool p_enabled) { + ssil_enabled = p_enabled; + _update_ssil(); + notify_property_list_changed(); +} + +bool Environment::is_ssil_enabled() const { + return ssil_enabled; +} + +void Environment::set_ssil_radius(float p_radius) { + ssil_radius = p_radius; + _update_ssil(); +} + +float Environment::get_ssil_radius() const { + return ssil_radius; +} + +void Environment::set_ssil_intensity(float p_intensity) { + ssil_intensity = p_intensity; + _update_ssil(); +} + +float Environment::get_ssil_intensity() const { + return ssil_intensity; +} + +void Environment::set_ssil_sharpness(float p_sharpness) { + ssil_sharpness = p_sharpness; + _update_ssil(); +} + +float Environment::get_ssil_sharpness() const { + return ssil_sharpness; +} + +void Environment::set_ssil_normal_rejection(float p_normal_rejection) { + ssil_normal_rejection = p_normal_rejection; + _update_ssil(); +} + +float Environment::get_ssil_normal_rejection() const { + return ssil_normal_rejection; +} + +void Environment::_update_ssil() { + RS::get_singleton()->environment_set_ssil( + environment, + ssil_enabled, + ssil_radius, + ssil_intensity, + ssil_sharpness, + ssil_normal_rejection); +} + // SDFGI void Environment::set_sdfgi_enabled(bool p_enabled) { @@ -1164,7 +1222,6 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ss_reflections_depth_tolerance", PROPERTY_HINT_RANGE, "0.01,128,0.1"), "set_ssr_depth_tolerance", "get_ssr_depth_tolerance"); // SSAO - ClassDB::bind_method(D_METHOD("set_ssao_enabled", "enabled"), &Environment::set_ssao_enabled); ClassDB::bind_method(D_METHOD("is_ssao_enabled"), &Environment::is_ssao_enabled); ClassDB::bind_method(D_METHOD("set_ssao_radius", "radius"), &Environment::set_ssao_radius); @@ -1195,6 +1252,25 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_light_affect", PROPERTY_HINT_RANGE, "0.00,1,0.01"), "set_ssao_direct_light_affect", "get_ssao_direct_light_affect"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_ao_channel_affect", PROPERTY_HINT_RANGE, "0.00,1,0.01"), "set_ssao_ao_channel_affect", "get_ssao_ao_channel_affect"); + // SSIL + ClassDB::bind_method(D_METHOD("set_ssil_enabled", "enabled"), &Environment::set_ssil_enabled); + ClassDB::bind_method(D_METHOD("is_ssil_enabled"), &Environment::is_ssil_enabled); + ClassDB::bind_method(D_METHOD("set_ssil_radius", "radius"), &Environment::set_ssil_radius); + ClassDB::bind_method(D_METHOD("get_ssil_radius"), &Environment::get_ssil_radius); + ClassDB::bind_method(D_METHOD("set_ssil_intensity", "intensity"), &Environment::set_ssil_intensity); + ClassDB::bind_method(D_METHOD("get_ssil_intensity"), &Environment::get_ssil_intensity); + ClassDB::bind_method(D_METHOD("set_ssil_sharpness", "sharpness"), &Environment::set_ssil_sharpness); + ClassDB::bind_method(D_METHOD("get_ssil_sharpness"), &Environment::get_ssil_sharpness); + ClassDB::bind_method(D_METHOD("set_ssil_normal_rejection", "normal_rejection"), &Environment::set_ssil_normal_rejection); + ClassDB::bind_method(D_METHOD("get_ssil_normal_rejection"), &Environment::get_ssil_normal_rejection); + + ADD_GROUP("SSIL", "ssil_"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ssil_enabled"), "set_ssil_enabled", "is_ssil_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssil_radius", PROPERTY_HINT_RANGE, "0.01,16,0.01,or_greater"), "set_ssil_radius", "get_ssil_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssil_intensity", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_ssil_intensity", "get_ssil_intensity"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssil_sharpness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_ssil_sharpness", "get_ssil_sharpness"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssil_normal_rejection", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_ssil_normal_rejection", "get_ssil_normal_rejection"); + // SDFGI ClassDB::bind_method(D_METHOD("set_sdfgi_enabled", "enabled"), &Environment::set_sdfgi_enabled); @@ -1431,6 +1507,7 @@ Environment::Environment() { _update_tonemap(); _update_ssr(); _update_ssao(); + _update_ssil(); _update_sdfgi(); _update_glow(); _update_fog(); diff --git a/scene/resources/environment.h b/scene/resources/environment.h index 024bef34de..98e755c336 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -142,6 +142,15 @@ private: float ssao_ao_channel_affect = 0.0; void _update_ssao(); + // SSIL + bool ssil_enabled = false; + float ssil_radius = 5.0; + float ssil_intensity = 1.0; + float ssil_sharpness = 0.98; + float ssil_normal_rejection = 1.0; + + void _update_ssil(); + // SDFGI bool sdfgi_enabled = false; SDFGICascades sdfgi_cascades = SDFGI_CASCADES_6; @@ -296,6 +305,18 @@ public: void set_ssao_ao_channel_affect(float p_ao_channel_affect); float get_ssao_ao_channel_affect() const; + // SSIL + void set_ssil_enabled(bool p_enabled); + bool is_ssil_enabled() const; + void set_ssil_radius(float p_radius); + float get_ssil_radius() const; + void set_ssil_intensity(float p_intensity); + float get_ssil_intensity() const; + void set_ssil_sharpness(float p_sharpness); + float get_ssil_sharpness() const; + void set_ssil_normal_rejection(float p_normal_rejection); + float get_ssil_normal_rejection() const; + // SDFGI void set_sdfgi_enabled(bool p_enabled); bool is_sdfgi_enabled() const; diff --git a/scene/resources/fog_material.cpp b/scene/resources/fog_material.cpp index 978aaca33d..a05ef0c779 100644 --- a/scene/resources/fog_material.cpp +++ b/scene/resources/fog_material.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/fog_material.h b/scene/resources/fog_material.h index e256bd4719..1f7cd7bfe6 100644 --- a/scene/resources/fog_material.h +++ b/scene/resources/fog_material.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index d88a2c557b..f040041aa5 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -30,6 +30,7 @@ #include "font.h" +#include "core/io/image_loader.h" #include "core/io/resource_loader.h" #include "core/string/translation.h" #include "core/templates/hashfuncs.h" @@ -64,6 +65,9 @@ _FORCE_INLINE_ void FontData::_ensure_rid(int p_cache_index) const { } void FontData::_bind_methods() { + ClassDB::bind_method(D_METHOD("load_bitmap_font", "path"), &FontData::load_bitmap_font); + ClassDB::bind_method(D_METHOD("load_dynamic_font", "path"), &FontData::load_dynamic_font); + ClassDB::bind_method(D_METHOD("set_data", "data"), &FontData::set_data); ClassDB::bind_method(D_METHOD("get_data"), &FontData::get_data); @@ -184,6 +188,9 @@ void FontData::_bind_methods() { ClassDB::bind_method(D_METHOD("remove_script_support_override", "script"), &FontData::remove_script_support_override); ClassDB::bind_method(D_METHOD("get_script_support_overrides"), &FontData::get_script_support_overrides); + ClassDB::bind_method(D_METHOD("set_opentype_feature_overrides", "overrides"), &FontData::set_opentype_feature_overrides); + ClassDB::bind_method(D_METHOD("get_opentype_feature_overrides"), &FontData::get_opentype_feature_overrides); + ClassDB::bind_method(D_METHOD("has_char", "char"), &FontData::has_char); ClassDB::bind_method(D_METHOD("get_supported_chars"), &FontData::get_supported_chars); @@ -191,49 +198,25 @@ void FontData::_bind_methods() { ClassDB::bind_method(D_METHOD("get_supported_feature_list"), &FontData::get_supported_feature_list); ClassDB::bind_method(D_METHOD("get_supported_variation_list"), &FontData::get_supported_variation_list); + + ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_data", "get_data"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "antialiased", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_antialiased", "is_antialiased"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "font_name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_font_name", "get_font_name"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "style_name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_font_style_name", "get_font_style_name"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "font_style", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_font_style", "get_font_style"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "multichannel_signed_distance_field", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_multichannel_signed_distance_field", "is_multichannel_signed_distance_field"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "msdf_pixel_range", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_msdf_pixel_range", "get_msdf_pixel_range"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "msdf_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_msdf_size", "get_msdf_size"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "force_autohinter", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_force_autohinter", "is_force_autohinter"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal", PROPERTY_USAGE_STORAGE), "set_hinting", "get_hinting"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_oversampling", "get_oversampling"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_fixed_size", "get_fixed_size"); + ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "opentype_feature_overrides", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_opentype_feature_overrides", "get_opentype_feature_overrides"); } bool FontData::_set(const StringName &p_name, const Variant &p_value) { Vector<String> tokens = p_name.operator String().split("/"); - if (tokens.size() == 1) { - if (tokens[0] == "data") { - set_data(p_value); - return true; - } else if (tokens[0] == "antialiased") { - set_antialiased(p_value); - return true; - } else if (tokens[0] == "font_name") { - set_font_name(p_value); - return true; - } else if (tokens[0] == "style_name") { - set_font_style_name(p_value); - return true; - } else if (tokens[0] == "font_style") { - set_font_style(p_value); - return true; - } else if (tokens[0] == "multichannel_signed_distance_field") { - set_multichannel_signed_distance_field(p_value); - return true; - } else if (tokens[0] == "msdf_pixel_range") { - set_msdf_pixel_range(p_value); - return true; - } else if (tokens[0] == "msdf_size") { - set_msdf_size(p_value); - return true; - } else if (tokens[0] == "fixed_size") { - set_fixed_size(p_value); - return true; - } else if (tokens[0] == "hinting") { - set_hinting((TextServer::Hinting)p_value.operator int()); - return true; - } else if (tokens[0] == "force_autohinter") { - set_force_autohinter(p_value); - return true; - } else if (tokens[0] == "oversampling") { - set_oversampling(p_value); - return true; - } - } else if (tokens.size() == 2 && tokens[0] == "language_support_override") { + if (tokens.size() == 2 && tokens[0] == "language_support_override") { String lang = tokens[1]; set_language_support_override(lang, p_value); return true; @@ -309,45 +292,7 @@ bool FontData::_set(const StringName &p_name, const Variant &p_value) { bool FontData::_get(const StringName &p_name, Variant &r_ret) const { Vector<String> tokens = p_name.operator String().split("/"); - if (tokens.size() == 1) { - if (tokens[0] == "data") { - r_ret = get_data(); - return true; - } else if (tokens[0] == "antialiased") { - r_ret = is_antialiased(); - return true; - } else if (tokens[0] == "font_name") { - r_ret = get_font_name(); - return true; - } else if (tokens[0] == "style_name") { - r_ret = get_font_style_name(); - return true; - } else if (tokens[0] == "font_style") { - r_ret = get_font_style(); - return true; - } else if (tokens[0] == "multichannel_signed_distance_field") { - r_ret = is_multichannel_signed_distance_field(); - return true; - } else if (tokens[0] == "msdf_pixel_range") { - r_ret = get_msdf_pixel_range(); - return true; - } else if (tokens[0] == "msdf_size") { - r_ret = get_msdf_size(); - return true; - } else if (tokens[0] == "fixed_size") { - r_ret = get_fixed_size(); - return true; - } else if (tokens[0] == "hinting") { - r_ret = get_hinting(); - return true; - } else if (tokens[0] == "force_autohinter") { - r_ret = is_force_autohinter(); - return true; - } else if (tokens[0] == "oversampling") { - r_ret = get_oversampling(); - return true; - } - } else if (tokens.size() == 2 && tokens[0] == "language_support_override") { + if (tokens.size() == 2 && tokens[0] == "language_support_override") { String lang = tokens[1]; r_ret = get_language_support_override(lang); return true; @@ -422,20 +367,6 @@ bool FontData::_get(const StringName &p_name, Variant &r_ret) const { } void FontData::_get_property_list(List<PropertyInfo> *p_list) const { - p_list->push_back(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE)); - - p_list->push_back(PropertyInfo(Variant::STRING, "font_name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE)); - p_list->push_back(PropertyInfo(Variant::STRING, "style_name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE)); - p_list->push_back(PropertyInfo(Variant::INT, "font_style", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE)); - p_list->push_back(PropertyInfo(Variant::BOOL, "antialiased", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE)); - p_list->push_back(PropertyInfo(Variant::BOOL, "multichannel_signed_distance_field", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE)); - p_list->push_back(PropertyInfo(Variant::INT, "msdf_pixel_range", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE)); - p_list->push_back(PropertyInfo(Variant::INT, "msdf_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE)); - p_list->push_back(PropertyInfo(Variant::INT, "fixed_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE)); - p_list->push_back(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal", PROPERTY_USAGE_STORAGE)); - p_list->push_back(PropertyInfo(Variant::BOOL, "force_autohinter", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE)); - p_list->push_back(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE)); - Vector<String> lang_over = get_language_support_overrides(); for (int i = 0; i < lang_over.size(); i++) { p_list->push_back(PropertyInfo(Variant::BOOL, "language_support_override/" + lang_over[i], PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE)); @@ -501,11 +432,766 @@ void FontData::reset_state() { hinting = TextServer::HINTING_LIGHT; msdf_pixel_range = 14; msdf_size = 128; + fixed_size = 0; oversampling = 0.f; } +void FontData::_convert_packed_8bit(Ref<Image> &p_source, int p_page, int p_sz) { + int w = p_source->get_width(); + int h = p_source->get_height(); + + PackedByteArray imgdata = p_source->get_data(); + const uint8_t *r = imgdata.ptr(); + + PackedByteArray imgdata_r; + imgdata_r.resize(w * h * 2); + uint8_t *wr = imgdata_r.ptrw(); + + PackedByteArray imgdata_g; + imgdata_g.resize(w * h * 2); + uint8_t *wg = imgdata_g.ptrw(); + + PackedByteArray imgdata_b; + imgdata_b.resize(w * h * 2); + uint8_t *wb = imgdata_b.ptrw(); + + PackedByteArray imgdata_a; + imgdata_a.resize(w * h * 2); + uint8_t *wa = imgdata_a.ptrw(); + + for (int i = 0; i < h; i++) { + for (int j = 0; j < w; j++) { + int ofs_src = (i * w + j) * 4; + int ofs_dst = (i * w + j) * 2; + wr[ofs_dst + 0] = 255; + wr[ofs_dst + 1] = r[ofs_src + 0]; + wg[ofs_dst + 0] = 255; + wg[ofs_dst + 1] = r[ofs_src + 1]; + wb[ofs_dst + 0] = 255; + wb[ofs_dst + 1] = r[ofs_src + 2]; + wa[ofs_dst + 0] = 255; + wa[ofs_dst + 1] = r[ofs_src + 3]; + } + } + Ref<Image> img_r = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_r)); + set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 0, img_r); + Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_g)); + set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 1, img_g); + Ref<Image> img_b = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_b)); + set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 2, img_b); + Ref<Image> img_a = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_a)); + set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 3, img_a); +} + +void FontData::_convert_packed_4bit(Ref<Image> &p_source, int p_page, int p_sz) { + int w = p_source->get_width(); + int h = p_source->get_height(); + + PackedByteArray imgdata = p_source->get_data(); + const uint8_t *r = imgdata.ptr(); + + PackedByteArray imgdata_r; + imgdata_r.resize(w * h * 2); + uint8_t *wr = imgdata_r.ptrw(); + + PackedByteArray imgdata_g; + imgdata_g.resize(w * h * 2); + uint8_t *wg = imgdata_g.ptrw(); + + PackedByteArray imgdata_b; + imgdata_b.resize(w * h * 2); + uint8_t *wb = imgdata_b.ptrw(); + + PackedByteArray imgdata_a; + imgdata_a.resize(w * h * 2); + uint8_t *wa = imgdata_a.ptrw(); + + PackedByteArray imgdata_ro; + imgdata_ro.resize(w * h * 2); + uint8_t *wro = imgdata_ro.ptrw(); + + PackedByteArray imgdata_go; + imgdata_go.resize(w * h * 2); + uint8_t *wgo = imgdata_go.ptrw(); + + PackedByteArray imgdata_bo; + imgdata_bo.resize(w * h * 2); + uint8_t *wbo = imgdata_bo.ptrw(); + + PackedByteArray imgdata_ao; + imgdata_ao.resize(w * h * 2); + uint8_t *wao = imgdata_ao.ptrw(); + + for (int i = 0; i < h; i++) { + for (int j = 0; j < w; j++) { + int ofs_src = (i * w + j) * 4; + int ofs_dst = (i * w + j) * 2; + wr[ofs_dst + 0] = 255; + wro[ofs_dst + 0] = 255; + if (r[ofs_src + 0] > 0x0F) { + wr[ofs_dst + 1] = (r[ofs_src + 0] - 0x0F) * 2; + wro[ofs_dst + 1] = 0; + } else { + wr[ofs_dst + 1] = 0; + wro[ofs_dst + 1] = r[ofs_src + 0] * 2; + } + wg[ofs_dst + 0] = 255; + wgo[ofs_dst + 0] = 255; + if (r[ofs_src + 1] > 0x0F) { + wg[ofs_dst + 1] = (r[ofs_src + 1] - 0x0F) * 2; + wgo[ofs_dst + 1] = 0; + } else { + wg[ofs_dst + 1] = 0; + wgo[ofs_dst + 1] = r[ofs_src + 1] * 2; + } + wb[ofs_dst + 0] = 255; + wbo[ofs_dst + 0] = 255; + if (r[ofs_src + 2] > 0x0F) { + wb[ofs_dst + 1] = (r[ofs_src + 2] - 0x0F) * 2; + wbo[ofs_dst + 1] = 0; + } else { + wb[ofs_dst + 1] = 0; + wbo[ofs_dst + 1] = r[ofs_src + 2] * 2; + } + wa[ofs_dst + 0] = 255; + wao[ofs_dst + 0] = 255; + if (r[ofs_src + 3] > 0x0F) { + wa[ofs_dst + 1] = (r[ofs_src + 3] - 0x0F) * 2; + wao[ofs_dst + 1] = 0; + } else { + wa[ofs_dst + 1] = 0; + wao[ofs_dst + 1] = r[ofs_src + 3] * 2; + } + } + } + Ref<Image> img_r = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_r)); + set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 0, img_r); + Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_g)); + set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 1, img_g); + Ref<Image> img_b = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_b)); + set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 2, img_b); + Ref<Image> img_a = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_a)); + set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 3, img_a); + + Ref<Image> img_ro = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_ro)); + set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 0, img_ro); + Ref<Image> img_go = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_go)); + set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 1, img_go); + Ref<Image> img_bo = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_bo)); + set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 2, img_bo); + Ref<Image> img_ao = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_ao)); + set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 3, img_ao); +} + +void FontData::_convert_rgba_4bit(Ref<Image> &p_source, int p_page, int p_sz) { + int w = p_source->get_width(); + int h = p_source->get_height(); + + PackedByteArray imgdata = p_source->get_data(); + const uint8_t *r = imgdata.ptr(); + + PackedByteArray imgdata_g; + imgdata_g.resize(w * h * 4); + uint8_t *wg = imgdata_g.ptrw(); + + PackedByteArray imgdata_o; + imgdata_o.resize(w * h * 4); + uint8_t *wo = imgdata_o.ptrw(); + + for (int i = 0; i < h; i++) { + for (int j = 0; j < w; j++) { + int ofs = (i * w + j) * 4; + + if (r[ofs + 0] > 0x7F) { + wg[ofs + 0] = r[ofs + 0]; + wo[ofs + 0] = 0; + } else { + wg[ofs + 0] = 0; + wo[ofs + 0] = r[ofs + 0] * 2; + } + if (r[ofs + 1] > 0x7F) { + wg[ofs + 1] = r[ofs + 1]; + wo[ofs + 1] = 0; + } else { + wg[ofs + 1] = 0; + wo[ofs + 1] = r[ofs + 1] * 2; + } + if (r[ofs + 2] > 0x7F) { + wg[ofs + 2] = r[ofs + 2]; + wo[ofs + 2] = 0; + } else { + wg[ofs + 2] = 0; + wo[ofs + 2] = r[ofs + 2] * 2; + } + if (r[ofs + 3] > 0x7F) { + wg[ofs + 3] = r[ofs + 3]; + wo[ofs + 3] = 0; + } else { + wg[ofs + 3] = 0; + wo[ofs + 3] = r[ofs + 3] * 2; + } + } + } + Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_RGBA8, imgdata_g)); + set_texture_image(0, Vector2i(p_sz, 0), p_page, img_g); + + Ref<Image> img_o = memnew(Image(w, h, 0, Image::FORMAT_RGBA8, imgdata_o)); + set_texture_image(0, Vector2i(p_sz, 1), p_page, img_o); +} + +void FontData::_convert_mono_8bit(Ref<Image> &p_source, int p_page, int p_ch, int p_sz, int p_ol) { + int w = p_source->get_width(); + int h = p_source->get_height(); + + PackedByteArray imgdata = p_source->get_data(); + const uint8_t *r = imgdata.ptr(); + + int size = 4; + if (p_source->get_format() == Image::FORMAT_L8) { + size = 1; + p_ch = 0; + } + + PackedByteArray imgdata_g; + imgdata_g.resize(w * h * 2); + uint8_t *wg = imgdata_g.ptrw(); + + for (int i = 0; i < h; i++) { + for (int j = 0; j < w; j++) { + int ofs_src = (i * w + j) * size; + int ofs_dst = (i * w + j) * 2; + wg[ofs_dst + 0] = 255; + wg[ofs_dst + 1] = r[ofs_src + p_ch]; + } + } + Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_g)); + set_texture_image(0, Vector2i(p_sz, p_ol), p_page, img_g); +} + +void FontData::_convert_mono_4bit(Ref<Image> &p_source, int p_page, int p_ch, int p_sz, int p_ol) { + int w = p_source->get_width(); + int h = p_source->get_height(); + + PackedByteArray imgdata = p_source->get_data(); + const uint8_t *r = imgdata.ptr(); + + int size = 4; + if (p_source->get_format() == Image::FORMAT_L8) { + size = 1; + p_ch = 0; + } + + PackedByteArray imgdata_g; + imgdata_g.resize(w * h * 2); + uint8_t *wg = imgdata_g.ptrw(); + + PackedByteArray imgdata_o; + imgdata_o.resize(w * h * 2); + uint8_t *wo = imgdata_o.ptrw(); + + for (int i = 0; i < h; i++) { + for (int j = 0; j < w; j++) { + int ofs_src = (i * w + j) * size; + int ofs_dst = (i * w + j) * 2; + wg[ofs_dst + 0] = 255; + wo[ofs_dst + 0] = 255; + if (r[ofs_src + p_ch] > 0x7F) { + wg[ofs_dst + 1] = r[ofs_src + p_ch]; + wo[ofs_dst + 1] = 0; + } else { + wg[ofs_dst + 1] = 0; + wo[ofs_dst + 1] = r[ofs_src + p_ch] * 2; + } + } + } + Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_g)); + set_texture_image(0, Vector2i(p_sz, 0), p_page, img_g); + + Ref<Image> img_o = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_o)); + set_texture_image(0, Vector2i(p_sz, p_ol), p_page, img_o); +} + /*************************************************************************/ +Error FontData::load_bitmap_font(const String &p_path) { + reset_state(); + + antialiased = false; + msdf = false; + force_autohinter = false; + hinting = TextServer::HINTING_NONE; + oversampling = 1.0f; + + FileAccessRef f = FileAccess::open(p_path, FileAccess::READ); + if (f == nullptr) { + ERR_FAIL_V_MSG(ERR_CANT_CREATE, TTR("Cannot open font from file ") + "\"" + p_path + "\"."); + } + + int base_size = 16; + int height = 0; + int ascent = 0; + int outline = 0; + uint32_t st_flags = 0; + String font_name; + + bool packed = false; + uint8_t ch[4] = { 0, 0, 0, 0 }; // RGBA + int first_gl_ch = -1; + int first_ol_ch = -1; + int first_cm_ch = -1; + + unsigned char magic[4]; + f->get_buffer((unsigned char *)&magic, 4); + if (magic[0] == 'B' && magic[1] == 'M' && magic[2] == 'F') { + // Binary BMFont file. + ERR_FAIL_COND_V_MSG(magic[3] != 3, ERR_CANT_CREATE, vformat(TTR("Version %d of BMFont is not supported."), (int)magic[3])); + + uint8_t block_type = f->get_8(); + uint32_t block_size = f->get_32(); + while (!f->eof_reached()) { + uint64_t off = f->get_position(); + switch (block_type) { + case 1: /* info */ { + ERR_FAIL_COND_V_MSG(block_size < 15, ERR_CANT_CREATE, TTR("Invalid BMFont info block size.")); + base_size = f->get_16(); + uint8_t flags = f->get_8(); + ERR_FAIL_COND_V_MSG(flags & 0x02, ERR_CANT_CREATE, TTR("Non-unicode version of BMFont is not supported.")); + if (flags & (1 << 3)) { + st_flags |= TextServer::FONT_BOLD; + } + if (flags & (1 << 2)) { + st_flags |= TextServer::FONT_ITALIC; + } + f->get_8(); // non-unicode charset, skip + f->get_16(); // stretch_h, skip + f->get_8(); // aa, skip + f->get_32(); // padding, skip + f->get_16(); // spacing, skip + outline = f->get_8(); + // font name + PackedByteArray name_data; + name_data.resize(block_size - 14); + f->get_buffer(name_data.ptrw(), block_size - 14); + font_name = String::utf8((const char *)name_data.ptr(), block_size - 14); + set_fixed_size(base_size); + } break; + case 2: /* common */ { + ERR_FAIL_COND_V_MSG(block_size != 15, ERR_CANT_CREATE, TTR("Invalid BMFont common block size.")); + height = f->get_16(); + ascent = f->get_16(); + f->get_32(); // scale, skip + f->get_16(); // pages, skip + uint8_t flags = f->get_8(); + packed = (flags & 0x01); + ch[3] = f->get_8(); + ch[0] = f->get_8(); + ch[1] = f->get_8(); + ch[2] = f->get_8(); + for (int i = 0; i < 4; i++) { + if (ch[i] == 0 && first_gl_ch == -1) { + first_gl_ch = i; + } + if (ch[i] == 1 && first_ol_ch == -1) { + first_ol_ch = i; + } + if (ch[i] == 2 && first_cm_ch == -1) { + first_cm_ch = i; + } + } + } break; + case 3: /* pages */ { + int page = 0; + CharString cs; + char32_t c = f->get_8(); + while (!f->eof_reached() && f->get_position() <= off + block_size) { + if (c == '\0') { + String base_dir = p_path.get_base_dir(); + String file = base_dir.plus_file(String::utf8(cs.ptr(), cs.length())); + if (RenderingServer::get_singleton() != nullptr) { + Ref<Image> img; + img.instantiate(); + Error err = ImageLoader::load_image(file, img); + ERR_FAIL_COND_V_MSG(err != OK, ERR_FILE_CANT_READ, TTR("Can't load font texture: ") + "\"" + file + "\"."); + + if (packed) { + if (ch[3] == 0) { // 4 x 8 bit monochrome, no outline + outline = 0; + ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format.")); + _convert_packed_8bit(img, page, base_size); + } else if ((ch[3] == 2) && (outline > 0)) { // 4 x 4 bit monochrome, gl + outline + ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format.")); + _convert_packed_4bit(img, page, base_size); + } else { + ERR_FAIL_V_MSG(ERR_CANT_CREATE, TTR("Unsupported BMFont texture format.")); + } + } else { + if ((ch[0] == 0) && (ch[1] == 0) && (ch[2] == 0) && (ch[3] == 0)) { // RGBA8 color, no outline + outline = 0; + ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format.")); + set_texture_image(0, Vector2i(base_size, 0), page, img); + } else if ((ch[0] == 2) && (ch[1] == 2) && (ch[2] == 2) && (ch[3] == 2) && (outline > 0)) { // RGBA4 color, gl + outline + ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format.")); + _convert_rgba_4bit(img, page, base_size); + } else if ((first_gl_ch >= 0) && (first_ol_ch >= 0) && (outline > 0)) { // 1 x 8 bit monochrome, gl + outline + ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format.")); + _convert_mono_8bit(img, page, first_gl_ch, base_size, 0); + _convert_mono_8bit(img, page, first_ol_ch, base_size, 1); + } else if ((first_cm_ch >= 0) && (outline > 0)) { // 1 x 4 bit monochrome, gl + outline + ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format.")); + _convert_mono_4bit(img, page, first_cm_ch, base_size, 1); + } else if (first_gl_ch >= 0) { // 1 x 8 bit monochrome, no outline + outline = 0; + ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format.")); + _convert_mono_8bit(img, page, first_gl_ch, base_size, 0); + } else { + ERR_FAIL_V_MSG(ERR_CANT_CREATE, TTR("Unsupported BMFont texture format.")); + } + } + } + page++; + cs = ""; + } else { + cs += c; + } + c = f->get_8(); + } + } break; + case 4: /* chars */ { + int char_count = block_size / 20; + for (int i = 0; i < char_count; i++) { + Vector2 advance; + Vector2 size; + Vector2 offset; + Rect2 uv_rect; + + char32_t idx = f->get_32(); + uv_rect.position.x = (int16_t)f->get_16(); + uv_rect.position.y = (int16_t)f->get_16(); + uv_rect.size.width = (int16_t)f->get_16(); + size.width = uv_rect.size.width; + uv_rect.size.height = (int16_t)f->get_16(); + size.height = uv_rect.size.height; + offset.x = (int16_t)f->get_16(); + offset.y = (int16_t)f->get_16() - ascent; + advance.x = (int16_t)f->get_16(); + if (advance.x < 0) { + advance.x = size.width + 1; + } + + int texture_idx = f->get_8(); + uint8_t channel = f->get_8(); + + ERR_FAIL_COND_V_MSG(!packed && channel != 15, ERR_CANT_CREATE, TTR("Invalid glyph channel.")); + int ch_off = 0; + switch (channel) { + case 1: + ch_off = 2; + break; // B + case 2: + ch_off = 1; + break; // G + case 4: + ch_off = 0; + break; // R + case 8: + ch_off = 3; + break; // A + default: + ch_off = 0; + break; + } + set_glyph_advance(0, base_size, idx, advance); + set_glyph_offset(0, Vector2i(base_size, 0), idx, offset); + set_glyph_size(0, Vector2i(base_size, 0), idx, size); + set_glyph_uv_rect(0, Vector2i(base_size, 0), idx, uv_rect); + set_glyph_texture_idx(0, Vector2i(base_size, 0), idx, texture_idx * (packed ? 4 : 1) + ch_off); + if (outline > 0) { + set_glyph_offset(0, Vector2i(base_size, 1), idx, offset); + set_glyph_size(0, Vector2i(base_size, 1), idx, size); + set_glyph_uv_rect(0, Vector2i(base_size, 1), idx, uv_rect); + set_glyph_texture_idx(0, Vector2i(base_size, 1), idx, texture_idx * (packed ? 4 : 1) + ch_off); + } + } + } break; + case 5: /* kerning */ { + int pair_count = block_size / 10; + for (int i = 0; i < pair_count; i++) { + Vector2i kpk; + kpk.x = f->get_32(); + kpk.y = f->get_32(); + set_kerning(0, base_size, kpk, Vector2((int16_t)f->get_16(), 0)); + } + } break; + default: { + ERR_FAIL_V_MSG(ERR_CANT_CREATE, TTR("Invalid BMFont block type.")); + } break; + } + f->seek(off + block_size); + block_type = f->get_8(); + block_size = f->get_32(); + } + + } else { + // Text BMFont file. + f->seek(0); + while (true) { + String line = f->get_line(); + + int delimiter = line.find(" "); + String type = line.substr(0, delimiter); + int pos = delimiter + 1; + Map<String, String> keys; + + while (pos < line.size() && line[pos] == ' ') { + pos++; + } + + while (pos < line.size()) { + int eq = line.find("=", pos); + if (eq == -1) { + break; + } + String key = line.substr(pos, eq - pos); + int end = -1; + String value; + if (line[eq + 1] == '"') { + end = line.find("\"", eq + 2); + if (end == -1) { + break; + } + value = line.substr(eq + 2, end - 1 - eq - 1); + pos = end + 1; + } else { + end = line.find(" ", eq + 1); + if (end == -1) { + end = line.size(); + } + value = line.substr(eq + 1, end - eq); + pos = end; + } + + while (pos < line.size() && line[pos] == ' ') { + pos++; + } + + keys[key] = value; + } + + if (type == "info") { + if (keys.has("size")) { + base_size = keys["size"].to_int(); + set_fixed_size(base_size); + } + if (keys.has("outline")) { + outline = keys["outline"].to_int(); + } + if (keys.has("bold")) { + if (keys["bold"].to_int()) { + st_flags |= TextServer::FONT_BOLD; + } + } + if (keys.has("italic")) { + if (keys["italic"].to_int()) { + st_flags |= TextServer::FONT_ITALIC; + } + } + if (keys.has("face")) { + font_name = keys["face"]; + } + ERR_FAIL_COND_V_MSG((!keys.has("unicode") || keys["unicode"].to_int() != 1), ERR_CANT_CREATE, TTR("Non-unicode version of BMFont is not supported.")); + } else if (type == "common") { + if (keys.has("lineHeight")) { + height = keys["lineHeight"].to_int(); + } + if (keys.has("base")) { + ascent = keys["base"].to_int(); + } + if (keys.has("packed")) { + packed = (keys["packed"].to_int() == 1); + } + if (keys.has("alphaChnl")) { + ch[3] = keys["alphaChnl"].to_int(); + } + if (keys.has("redChnl")) { + ch[0] = keys["redChnl"].to_int(); + } + if (keys.has("greenChnl")) { + ch[1] = keys["greenChnl"].to_int(); + } + if (keys.has("blueChnl")) { + ch[2] = keys["blueChnl"].to_int(); + } + for (int i = 0; i < 4; i++) { + if (ch[i] == 0 && first_gl_ch == -1) { + first_gl_ch = i; + } + if (ch[i] == 1 && first_ol_ch == -1) { + first_ol_ch = i; + } + if (ch[i] == 2 && first_cm_ch == -1) { + first_cm_ch = i; + } + } + } else if (type == "page") { + int page = 0; + if (keys.has("id")) { + page = keys["id"].to_int(); + } + if (keys.has("file")) { + String base_dir = p_path.get_base_dir(); + String file = base_dir.plus_file(keys["file"]); + if (RenderingServer::get_singleton() != nullptr) { + Ref<Image> img; + img.instantiate(); + Error err = ImageLoader::load_image(file, img); + ERR_FAIL_COND_V_MSG(err != OK, ERR_FILE_CANT_READ, TTR("Can't load font texture: ") + "\"" + file + "\"."); + if (packed) { + if (ch[3] == 0) { // 4 x 8 bit monochrome, no outline + outline = 0; + ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format.")); + _convert_packed_8bit(img, page, base_size); + } else if ((ch[3] == 2) && (outline > 0)) { // 4 x 4 bit monochrome, gl + outline + ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format.")); + _convert_packed_4bit(img, page, base_size); + } else { + ERR_FAIL_V_MSG(ERR_CANT_CREATE, TTR("Unsupported BMFont texture format.")); + } + } else { + if ((ch[0] == 0) && (ch[1] == 0) && (ch[2] == 0) && (ch[3] == 0)) { // RGBA8 color, no outline + outline = 0; + ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format.")); + set_texture_image(0, Vector2i(base_size, 0), page, img); + } else if ((ch[0] == 2) && (ch[1] == 2) && (ch[2] == 2) && (ch[3] == 2) && (outline > 0)) { // RGBA4 color, gl + outline + ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format.")); + _convert_rgba_4bit(img, page, base_size); + } else if ((first_gl_ch >= 0) && (first_ol_ch >= 0) && (outline > 0)) { // 1 x 8 bit monochrome, gl + outline + ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format.")); + _convert_mono_8bit(img, page, first_gl_ch, base_size, 0); + _convert_mono_8bit(img, page, first_ol_ch, base_size, 1); + } else if ((first_cm_ch >= 0) && (outline > 0)) { // 1 x 4 bit monochrome, gl + outline + ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format.")); + _convert_mono_4bit(img, page, first_cm_ch, base_size, 1); + } else if (first_gl_ch >= 0) { // 1 x 8 bit monochrome, no outline + outline = 0; + ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format.")); + _convert_mono_8bit(img, page, first_gl_ch, base_size, 0); + } else { + ERR_FAIL_V_MSG(ERR_CANT_CREATE, TTR("Unsupported BMFont texture format.")); + } + } + } + } + } else if (type == "char") { + char32_t idx = 0; + Vector2 advance; + Vector2 size; + Vector2 offset; + Rect2 uv_rect; + int texture_idx = -1; + uint8_t channel = 15; + + if (keys.has("id")) { + idx = keys["id"].to_int(); + } + if (keys.has("x")) { + uv_rect.position.x = keys["x"].to_int(); + } + if (keys.has("y")) { + uv_rect.position.y = keys["y"].to_int(); + } + if (keys.has("width")) { + uv_rect.size.width = keys["width"].to_int(); + size.width = keys["width"].to_int(); + } + if (keys.has("height")) { + uv_rect.size.height = keys["height"].to_int(); + size.height = keys["height"].to_int(); + } + if (keys.has("xoffset")) { + offset.x = keys["xoffset"].to_int(); + } + if (keys.has("yoffset")) { + offset.y = keys["yoffset"].to_int() - ascent; + } + if (keys.has("page")) { + texture_idx = keys["page"].to_int(); + } + if (keys.has("xadvance")) { + advance.x = keys["xadvance"].to_int(); + } + if (advance.x < 0) { + advance.x = size.width + 1; + } + if (keys.has("chnl")) { + channel = keys["chnl"].to_int(); + } + + ERR_FAIL_COND_V_MSG(!packed && channel != 15, ERR_CANT_CREATE, TTR("Invalid glyph channel.")); + int ch_off = 0; + switch (channel) { + case 1: + ch_off = 2; + break; // B + case 2: + ch_off = 1; + break; // G + case 4: + ch_off = 0; + break; // R + case 8: + ch_off = 3; + break; // A + default: + ch_off = 0; + break; + } + set_glyph_advance(0, base_size, idx, advance); + set_glyph_offset(0, Vector2i(base_size, 0), idx, offset); + set_glyph_size(0, Vector2i(base_size, 0), idx, size); + set_glyph_uv_rect(0, Vector2i(base_size, 0), idx, uv_rect); + set_glyph_texture_idx(0, Vector2i(base_size, 0), idx, texture_idx * (packed ? 4 : 1) + ch_off); + if (outline > 0) { + set_glyph_offset(0, Vector2i(base_size, 1), idx, offset); + set_glyph_size(0, Vector2i(base_size, 1), idx, size); + set_glyph_uv_rect(0, Vector2i(base_size, 1), idx, uv_rect); + set_glyph_texture_idx(0, Vector2i(base_size, 1), idx, texture_idx * (packed ? 4 : 1) + ch_off); + } + } else if (type == "kerning") { + Vector2i kpk; + if (keys.has("first")) { + kpk.x = keys["first"].to_int(); + } + if (keys.has("second")) { + kpk.y = keys["second"].to_int(); + } + if (keys.has("amount")) { + set_kerning(0, base_size, kpk, Vector2(keys["amount"].to_int(), 0)); + } + } + + if (f->eof_reached()) { + break; + } + } + } + + set_font_name(font_name); + set_font_style(st_flags); + set_ascent(0, base_size, ascent); + set_descent(0, base_size, height - ascent); + + return OK; +} + +Error FontData::load_dynamic_font(const String &p_path) { + reset_state(); + + Vector<uint8_t> data = FileAccess::get_file_as_array(p_path); + set_data(data); + + return OK; +} + void FontData::set_data_ptr(const uint8_t *p_data, size_t p_size) { data.clear(); data_ptr = p_data; @@ -1077,6 +1763,16 @@ Vector<String> FontData::get_script_support_overrides() const { return TS->font_get_script_support_overrides(cache[0]); } +void FontData::set_opentype_feature_overrides(const Dictionary &p_overrides) { + _ensure_rid(0); + TS->font_set_opentype_feature_overrides(cache[0], p_overrides); +} + +Dictionary FontData::get_opentype_feature_overrides() const { + _ensure_rid(0); + return TS->font_get_opentype_feature_overrides(cache[0]); +} + bool FontData::has_char(char32_t p_char) const { _ensure_rid(0); return TS->font_has_char(cache[0], p_char); @@ -1152,11 +1848,11 @@ void Font::_bind_methods() { ClassDB::bind_method(D_METHOD("get_underline_position", "size"), &Font::get_underline_position, DEFVAL(DEFAULT_FONT_SIZE)); ClassDB::bind_method(D_METHOD("get_underline_thickness", "size"), &Font::get_underline_thickness, DEFVAL(DEFAULT_FONT_SIZE)); - ClassDB::bind_method(D_METHOD("get_string_size", "text", "size", "align", "width", "flags"), &Font::get_string_size, DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(HALIGN_LEFT), DEFVAL(-1), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND)); + ClassDB::bind_method(D_METHOD("get_string_size", "text", "size", "alignment", "width", "flags"), &Font::get_string_size, DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND)); ClassDB::bind_method(D_METHOD("get_multiline_string_size", "text", "width", "size", "flags"), &Font::get_multiline_string_size, DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND)); - ClassDB::bind_method(D_METHOD("draw_string", "canvas_item", "pos", "text", "align", "width", "size", "modulate", "outline_size", "outline_modulate", "flags"), &Font::draw_string, DEFVAL(HALIGN_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND)); - ClassDB::bind_method(D_METHOD("draw_multiline_string", "canvas_item", "pos", "text", "align", "width", "max_lines", "size", "modulate", "outline_size", "outline_modulate", "flags"), &Font::draw_multiline_string, DEFVAL(HALIGN_LEFT), DEFVAL(-1), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND)); + ClassDB::bind_method(D_METHOD("draw_string", "canvas_item", "pos", "text", "alignment", "width", "size", "modulate", "outline_size", "outline_modulate", "flags"), &Font::draw_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND)); + ClassDB::bind_method(D_METHOD("draw_multiline_string", "canvas_item", "pos", "text", "alignment", "width", "max_lines", "size", "modulate", "outline_size", "outline_modulate", "flags"), &Font::draw_multiline_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND)); ClassDB::bind_method(D_METHOD("get_char_size", "char", "next", "size"), &Font::get_char_size, DEFVAL(0), DEFVAL(DEFAULT_FONT_SIZE)); ClassDB::bind_method(D_METHOD("draw_char", "canvas_item", "pos", "char", "next", "size", "modulate", "outline_size", "outline_modulate"), &Font::draw_char, DEFVAL(0), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0))); @@ -1449,7 +2145,7 @@ real_t Font::get_underline_thickness(int p_size) const { return ret; } -Size2 Font::get_string_size(const String &p_text, int p_size, HAlign p_align, real_t p_width, uint16_t p_flags) const { +Size2 Font::get_string_size(const String &p_text, int p_size, HorizontalAlignment p_alignment, float p_width, uint16_t p_flags) const { ERR_FAIL_COND_V(data.is_empty(), Size2()); for (int i = 0; i < data.size(); i++) { @@ -1457,7 +2153,7 @@ Size2 Font::get_string_size(const String &p_text, int p_size, HAlign p_align, re } uint64_t hash = p_text.hash64(); - if (p_align == HALIGN_FILL) { + if (p_alignment == HORIZONTAL_ALIGNMENT_FILL) { hash = hash_djb2_one_64(hash_djb2_one_float(p_width), hash); hash = hash_djb2_one_64(p_flags, hash); } @@ -1474,7 +2170,7 @@ Size2 Font::get_string_size(const String &p_text, int p_size, HAlign p_align, re return buffer->get_size(); } -Size2 Font::get_multiline_string_size(const String &p_text, real_t p_width, int p_size, uint16_t p_flags) const { +Size2 Font::get_multiline_string_size(const String &p_text, float p_width, int p_size, uint16_t p_flags) const { ERR_FAIL_COND_V(data.is_empty(), Size2()); for (int i = 0; i < data.size(); i++) { @@ -1511,7 +2207,7 @@ Size2 Font::get_multiline_string_size(const String &p_text, real_t p_width, int return ret; } -void Font::draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HAlign p_align, real_t p_width, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const { +void Font::draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const { ERR_FAIL_COND(data.is_empty()); for (int i = 0; i < data.size(); i++) { @@ -1519,7 +2215,7 @@ void Font::draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_t } uint64_t hash = p_text.hash64(); - if (p_align == HALIGN_FILL) { + if (p_alignment == HORIZONTAL_ALIGNMENT_FILL) { hash = hash_djb2_one_64(hash_djb2_one_float(p_width), hash); hash = hash_djb2_one_64(p_flags, hash); } @@ -1542,7 +2238,7 @@ void Font::draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_t } buffer->set_width(p_width); - buffer->set_align(p_align); + buffer->set_horizontal_alignment(p_alignment); buffer->set_flags(p_flags); if (p_outline_size > 0 && p_outline_modulate.a != 0.0f) { @@ -1551,7 +2247,7 @@ void Font::draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_t buffer->draw(p_canvas_item, ofs, p_modulate); } -void Font::draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HAlign p_align, float p_width, int p_max_lines, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const { +void Font::draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_max_lines, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const { ERR_FAIL_COND(data.is_empty()); for (int i = 0; i < data.size(); i++) { @@ -1574,7 +2270,7 @@ void Font::draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const S cache_wrap.insert(wrp_hash, lines_buffer); } - lines_buffer->set_align(p_align); + lines_buffer->set_alignment(p_alignment); Vector2 lofs = p_pos; for (int i = 0; i < lines_buffer->get_line_count(); i++) { @@ -1588,7 +2284,7 @@ void Font::draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const S } } if (p_width > 0) { - lines_buffer->set_align(p_align); + lines_buffer->set_alignment(p_alignment); } if (p_outline_size > 0 && p_outline_modulate.a != 0.0f) { diff --git a/scene/resources/font.h b/scene/resources/font.h index 4d9ee72c84..93351a3493 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -63,6 +63,12 @@ class FontData : public Resource { _FORCE_INLINE_ void _clear_cache(); _FORCE_INLINE_ void _ensure_rid(int p_cache_index) const; + void _convert_packed_8bit(Ref<Image> &p_source, int p_page, int p_sz); + void _convert_packed_4bit(Ref<Image> &p_source, int p_page, int p_sz); + void _convert_rgba_4bit(Ref<Image> &p_source, int p_page, int p_sz); + void _convert_mono_8bit(Ref<Image> &p_source, int p_page, int p_ch, int p_sz, int p_ol); + void _convert_mono_4bit(Ref<Image> &p_source, int p_page, int p_ch, int p_sz, int p_ol); + protected: static void _bind_methods(); @@ -73,6 +79,9 @@ protected: virtual void reset_state() override; public: + Error load_bitmap_font(const String &p_path); + Error load_dynamic_font(const String &p_path); + // Font source data. virtual void set_data_ptr(const uint8_t *p_data, size_t p_size); virtual void set_data(const PackedByteArray &p_data); @@ -198,6 +207,9 @@ public: virtual void remove_script_support_override(const String &p_script); virtual Vector<String> get_script_support_overrides() const; + virtual void set_opentype_feature_overrides(const Dictionary &p_overrides); + virtual Dictionary get_opentype_feature_overrides() const; + // Base font properties. virtual bool has_char(char32_t p_char) const; virtual String get_supported_chars() const; @@ -273,11 +285,11 @@ public: virtual real_t get_underline_thickness(int p_size = DEFAULT_FONT_SIZE) const; // Drawing string. - virtual Size2 get_string_size(const String &p_text, int p_size = DEFAULT_FONT_SIZE, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const; - virtual Size2 get_multiline_string_size(const String &p_text, real_t p_width = -1, int p_size = DEFAULT_FONT_SIZE, uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND) const; + virtual Size2 get_string_size(const String &p_text, int p_size = DEFAULT_FONT_SIZE, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const; + virtual Size2 get_multiline_string_size(const String &p_text, float p_width = -1, int p_size = DEFAULT_FONT_SIZE, uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND) const; - virtual void draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_size = DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const; - virtual void draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_max_lines = -1, int p_size = DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const; + virtual void draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_size = DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const; + virtual void draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_max_lines = -1, int p_size = DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const; // Helper functions. virtual bool has_char(char32_t p_char) const; diff --git a/scene/resources/gradient.cpp b/scene/resources/gradient.cpp index 95ec141df6..79ac1b57c3 100644 --- a/scene/resources/gradient.cpp +++ b/scene/resources/gradient.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/gradient.h b/scene/resources/gradient.h index eb438d0bba..c2085b3a13 100644 --- a/scene/resources/gradient.h +++ b/scene/resources/gradient.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/height_map_shape_3d.cpp b/scene/resources/height_map_shape_3d.cpp index d1a958ad38..121930d86f 100644 --- a/scene/resources/height_map_shape_3d.cpp +++ b/scene/resources/height_map_shape_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/height_map_shape_3d.h b/scene/resources/height_map_shape_3d.h index 1273aee040..79d1b15674 100644 --- a/scene/resources/height_map_shape_3d.h +++ b/scene/resources/height_map_shape_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/immediate_mesh.cpp b/scene/resources/immediate_mesh.cpp index 4f9a055bfb..b9469803a0 100644 --- a/scene/resources/immediate_mesh.cpp +++ b/scene/resources/immediate_mesh.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/immediate_mesh.h b/scene/resources/immediate_mesh.h index 92bf91441d..e5f627ae8e 100644 --- a/scene/resources/immediate_mesh.h +++ b/scene/resources/immediate_mesh.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/importer_mesh.cpp b/scene/resources/importer_mesh.cpp index 7afa4c91f0..92ab091b86 100644 --- a/scene/resources/importer_mesh.cpp +++ b/scene/resources/importer_mesh.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -485,7 +485,7 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_spli raycaster->intersect(rays); LocalVector<Vector3> ray_normals; - LocalVector<float> ray_normal_weights; + LocalVector<real_t> ray_normal_weights; ray_normals.resize(new_index_count); ray_normal_weights.resize(new_index_count); @@ -517,10 +517,10 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_spli Vector3 normal = n0 * w + n1 * u + n2 * v; Vector2 orig_uv = ray_uvs[j]; - float orig_bary[3] = { 1.0f - orig_uv.x - orig_uv.y, orig_uv.x, orig_uv.y }; + real_t orig_bary[3] = { 1.0f - orig_uv.x - orig_uv.y, orig_uv.x, orig_uv.y }; for (int k = 0; k < 3; k++) { int idx = orig_tri_id * 3 + k; - float weight = orig_bary[k]; + real_t weight = orig_bary[k]; ray_normals[idx] += normal * weight; ray_normal_weights[idx] += weight; } @@ -653,7 +653,7 @@ Ref<ArrayMesh> ImporterMesh::get_mesh(const Ref<ArrayMesh> &p_base) { if (surfaces[i].material.is_valid()) { mesh->surface_set_material(mesh->get_surface_count() - 1, surfaces[i].material); } - if (surfaces[i].name != String()) { + if (!surfaces[i].name.is_empty()) { mesh->surface_set_name(mesh->get_surface_count() - 1, surfaces[i].name); } } @@ -839,7 +839,7 @@ Dictionary ImporterMesh::_get_data() const { d["material"] = surfaces[i].material; } - if (surfaces[i].name != String()) { + if (!surfaces[i].name.is_empty()) { d["name"] = surfaces[i].name; } diff --git a/scene/resources/importer_mesh.h b/scene/resources/importer_mesh.h index 8576312a8a..8f77597a58 100644 --- a/scene/resources/importer_mesh.h +++ b/scene/resources/importer_mesh.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 00c109f1a6..f3e5ece1f9 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -449,10 +449,10 @@ void BaseMaterial3D::_update_shader() { texfilter_str = "filter_linear_mipmap"; break; case TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC: - texfilter_str = "filter_nearest_mipmap_aniso"; + texfilter_str = "filter_nearest_mipmap_anisotropic"; break; case TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC: - texfilter_str = "filter_linear_mipmap_aniso"; + texfilter_str = "filter_linear_mipmap_anisotropic"; break; case TEXTURE_FILTER_MAX: break; // Internal value, skip. @@ -695,7 +695,7 @@ void BaseMaterial3D::_update_shader() { } if (features[FEATURE_ANISOTROPY]) { code += "uniform float anisotropy_ratio : hint_range(0,256);\n"; - code += "uniform sampler2D texture_flowmap : hint_aniso," + texfilter_str + ";\n"; + code += "uniform sampler2D texture_flowmap : hint_anisotropy," + texfilter_str + ";\n"; } if (features[FEATURE_AMBIENT_OCCLUSION]) { code += "uniform sampler2D texture_ambient_occlusion : hint_white, " + texfilter_str + ";\n"; @@ -1659,18 +1659,6 @@ bool BaseMaterial3D::get_feature(Feature p_feature) const { void BaseMaterial3D::set_texture(TextureParam p_param, const Ref<Texture2D> &p_texture) { ERR_FAIL_INDEX(p_param, TEXTURE_MAX); - if (get_texture(TEXTURE_ROUGHNESS).is_null() && p_texture.is_valid() && p_param == TEXTURE_ROUGHNESS) { - // If no roughness texture is currently set, automatically set the recommended value - // for roughness when using a roughness map. - set_roughness(1.0); - } - - if (get_texture(TEXTURE_METALLIC).is_null() && p_texture.is_valid() && p_param == TEXTURE_METALLIC) { - // If no metallic texture is currently set, automatically set the recommended value - // for metallic when using a metallic map. - set_metallic(1.0); - } - textures[p_param] = p_texture; RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); RS::get_singleton()->material_set_param(_get_material(), shader_names->texture_names[p_param], rid); @@ -2569,7 +2557,7 @@ void BaseMaterial3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "uv2_world_triplanar"), "set_flag", "get_flag", FLAG_UV2_USE_WORLD_TRIPLANAR); ADD_GROUP("Sampling", "texture_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,Nearest Mipmap,Linear Mipmap,Nearest Mipmap Aniso.,Linear Mipmap Aniso."), "set_texture_filter", "get_texture_filter"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,Nearest Mipmap,Linear Mipmap,Nearest Mipmap Anisotropic,Linear Mipmap Anisotropic"), "set_texture_filter", "get_texture_filter"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "texture_repeat"), "set_flag", "get_flag", FLAG_USE_TEXTURE_REPEAT); ADD_GROUP("Shadows", ""); @@ -2899,7 +2887,7 @@ bool StandardMaterial3D::_set(const StringName &p_name, const Variant &p_value) idx++; } - print_line("remapped parameter not found: " + String(p_name)); + WARN_PRINT("Godot 3.x SpatialMaterial remapped parameter not found: " + String(p_name)); return true; } diff --git a/scene/resources/material.h b/scene/resources/material.h index 798f7568df..57591bee2f 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -35,7 +35,6 @@ #include "core/templates/self_list.h" #include "scene/resources/shader.h" #include "scene/resources/texture.h" -#include "servers/rendering/shader_language.h" #include "servers/rendering_server.h" class Material : public Resource { diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 51b4e1fbd8..d2d96b1f06 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -596,7 +596,7 @@ enum OldArrayFormat { OLD_ARRAY_FLAG_USE_2D_VERTICES = OLD_ARRAY_COMPRESS_INDEX << 1, OLD_ARRAY_FLAG_USE_16_BIT_BONES = OLD_ARRAY_COMPRESS_INDEX << 2, OLD_ARRAY_FLAG_USE_DYNAMIC_UPDATE = OLD_ARRAY_COMPRESS_INDEX << 3, - + OLD_ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION = OLD_ARRAY_COMPRESS_INDEX << 4, }; #ifndef DISABLE_DEPRECATED @@ -626,6 +626,27 @@ static Mesh::PrimitiveType _old_primitives[7] = { }; #endif // DISABLE_DEPRECATED +// Convert Octahedron-mapped normalized vector back to Cartesian +// Assumes normalized format (elements of v within range [-1, 1]) +Vector3 _oct_to_norm(const Vector2 v) { + Vector3 res(v.x, v.y, 1 - (Math::absf(v.x) + Math::absf(v.y))); + float t = MAX(-res.z, 0.0f); + res.x += t * -SIGN(res.x); + res.y += t * -SIGN(res.y); + return res.normalized(); +} + +// Convert Octahedron-mapped normalized tangent vector back to Cartesian +// out_sign provides the direction for the original cartesian tangent +// Assumes normalized format (elements of v within range [-1, 1]) +Vector3 _oct_to_tangent(const Vector2 v, float *out_sign) { + Vector2 v_decompressed = v; + v_decompressed.y = Math::absf(v_decompressed.y) * 2 - 1; + Vector3 res = _oct_to_norm(v_decompressed); + *out_sign = SIGN(v[1]); + return res; +} + void _fix_array_compatibility(const Vector<uint8_t> &p_src, uint32_t p_old_format, uint32_t p_new_format, uint32_t p_elements, Vector<uint8_t> &vertex_data, Vector<uint8_t> &attribute_data, Vector<uint8_t> &skin_data) { uint32_t dst_vertex_stride; uint32_t dst_attribute_stride; @@ -692,66 +713,133 @@ void _fix_array_compatibility(const Vector<uint8_t> &p_src, uint32_t p_old_forma } } break; case OLD_ARRAY_NORMAL: { - if (p_old_format & OLD_ARRAY_COMPRESS_NORMAL) { - const float multiplier = 1.f / 127.f * 1023.0f; + if (p_old_format & OLD_ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION) { + if ((p_old_format & OLD_ARRAY_COMPRESS_NORMAL) && (p_old_format & OLD_ARRAY_FORMAT_TANGENT) && (p_old_format & OLD_ARRAY_COMPRESS_TANGENT)) { + for (uint32_t i = 0; i < p_elements; i++) { + const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; + uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; + const Vector2 src_vec(src[0] / 127.0f, src[1] / 127.0f); + + const Vector3 res = _oct_to_norm(src_vec) * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5); + *dst = 0; + *dst |= CLAMP(int(res.x * 1023.0f), 0, 1023); + *dst |= CLAMP(int(res.y * 1023.0f), 0, 1023) << 10; + *dst |= CLAMP(int(res.z * 1023.0f), 0, 1023) << 20; + } + src_offset += sizeof(int8_t) * 2; + } else { + for (uint32_t i = 0; i < p_elements; i++) { + const int16_t *src = (const int16_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; + uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; + const Vector2 src_vec(src[0] / 32767.0f, src[1] / 32767.0f); + + const Vector3 res = _oct_to_norm(src_vec) * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5); + *dst = 0; + *dst |= CLAMP(int(res.x * 1023.0f), 0, 1023); + *dst |= CLAMP(int(res.y * 1023.0f), 0, 1023) << 10; + *dst |= CLAMP(int(res.z * 1023.0f), 0, 1023) << 20; + } + src_offset += sizeof(int16_t) * 2; + } + } else { // No Octahedral compression + if (p_old_format & OLD_ARRAY_COMPRESS_NORMAL) { + const float multiplier = 1.f / 127.f * 1023.0f; - for (uint32_t i = 0; i < p_elements; i++) { - const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; - uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; + for (uint32_t i = 0; i < p_elements; i++) { + const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; + uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; - *dst = 0; - *dst |= CLAMP(int(src[0] * multiplier), 0, 1023); - *dst |= CLAMP(int(src[1] * multiplier), 0, 1023) << 10; - *dst |= CLAMP(int(src[2] * multiplier), 0, 1023) << 20; - } - src_offset += sizeof(uint32_t); - } else { - for (uint32_t i = 0; i < p_elements; i++) { - const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; - uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; + *dst = 0; + *dst |= CLAMP(int(src[0] * multiplier), 0, 1023); + *dst |= CLAMP(int(src[1] * multiplier), 0, 1023) << 10; + *dst |= CLAMP(int(src[2] * multiplier), 0, 1023) << 20; + } + src_offset += sizeof(uint32_t); + } else { + for (uint32_t i = 0; i < p_elements; i++) { + const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; + uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; - *dst = 0; - *dst |= CLAMP(int(src[0] * 1023.0), 0, 1023); - *dst |= CLAMP(int(src[1] * 1023.0), 0, 1023) << 10; - *dst |= CLAMP(int(src[2] * 1023.0), 0, 1023) << 20; + *dst = 0; + *dst |= CLAMP(int(src[0] * 1023.0), 0, 1023); + *dst |= CLAMP(int(src[1] * 1023.0), 0, 1023) << 10; + *dst |= CLAMP(int(src[2] * 1023.0), 0, 1023) << 20; + } + src_offset += sizeof(float) * 3; } - src_offset += sizeof(float) * 3; } } break; case OLD_ARRAY_TANGENT: { - if (p_old_format & OLD_ARRAY_COMPRESS_TANGENT) { - const float multiplier = 1.f / 127.f * 1023.0f; - - for (uint32_t i = 0; i < p_elements; i++) { - const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; - uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]]; - - *dst = 0; - *dst |= CLAMP(int(src[0] * multiplier), 0, 1023); - *dst |= CLAMP(int(src[1] * multiplier), 0, 1023) << 10; - *dst |= CLAMP(int(src[2] * multiplier), 0, 1023) << 20; - if (src[3] > 0) { - *dst |= 3 << 30; + if (p_old_format & OLD_ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION) { + if (p_old_format & OLD_ARRAY_COMPRESS_TANGENT) { // int8 + for (uint32_t i = 0; i < p_elements; i++) { + const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; + uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]]; + const Vector2 src_vec(src[0] / 127.0f, src[1] / 127.0f); + float out_sign; + const Vector3 res = _oct_to_tangent(src_vec, &out_sign) * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5); + + *dst = 0; + *dst |= CLAMP(int(res.x * 1023.0), 0, 1023); + *dst |= CLAMP(int(res.y * 1023.0), 0, 1023) << 10; + *dst |= CLAMP(int(res.z * 1023.0), 0, 1023) << 20; + if (out_sign > 0) { + *dst |= 3 << 30; + } } + src_offset += sizeof(int8_t) * 2; + } else { // int16 + for (uint32_t i = 0; i < p_elements; i++) { + const int16_t *src = (const int16_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; + uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]]; + const Vector2 src_vec(src[0] / 32767.0f, src[1] / 32767.0f); + float out_sign; + Vector3 res = _oct_to_tangent(src_vec, &out_sign) * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5); + + *dst = 0; + *dst |= CLAMP(int(res.x * 1023.0), 0, 1023); + *dst |= CLAMP(int(res.y * 1023.0), 0, 1023) << 10; + *dst |= CLAMP(int(res.z * 1023.0), 0, 1023) << 20; + if (out_sign > 0) { + *dst |= 3 << 30; + } + } + src_offset += sizeof(int16_t) * 2; } - src_offset += sizeof(uint32_t); - } else { - for (uint32_t i = 0; i < p_elements; i++) { - const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; - uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]]; - - *dst = 0; - *dst |= CLAMP(int(src[0] * 1023.0), 0, 1023); - *dst |= CLAMP(int(src[1] * 1023.0), 0, 1023) << 10; - *dst |= CLAMP(int(src[2] * 1023.0), 0, 1023) << 20; - if (src[3] > 0) { - *dst |= 3 << 30; + } else { // No Octahedral compression + if (p_old_format & OLD_ARRAY_COMPRESS_TANGENT) { + const float multiplier = 1.f / 127.f * 1023.0f; + + for (uint32_t i = 0; i < p_elements; i++) { + const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; + uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]]; + + *dst = 0; + *dst |= CLAMP(int(src[0] * multiplier), 0, 1023); + *dst |= CLAMP(int(src[1] * multiplier), 0, 1023) << 10; + *dst |= CLAMP(int(src[2] * multiplier), 0, 1023) << 20; + if (src[3] > 0) { + *dst |= 3 << 30; + } + } + src_offset += sizeof(uint32_t); + } else { + for (uint32_t i = 0; i < p_elements; i++) { + const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; + uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]]; + + *dst = 0; + *dst |= CLAMP(int(src[0] * 1023.0), 0, 1023); + *dst |= CLAMP(int(src[1] * 1023.0), 0, 1023) << 10; + *dst |= CLAMP(int(src[2] * 1023.0), 0, 1023) << 20; + if (src[3] > 0) { + *dst |= 3 << 30; + } } + src_offset += sizeof(float) * 4; } - src_offset += sizeof(float) * 4; } - } break; case OLD_ARRAY_COLOR: { if (p_old_format & OLD_ARRAY_COMPRESS_COLOR) { @@ -898,7 +986,9 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) { return false; } - WARN_DEPRECATED_MSG("Mesh uses old surface format, which is deprecated (and loads slower). Consider re-importing or re-saving the scene."); + WARN_DEPRECATED_MSG(vformat( + "Mesh uses old surface format, which is deprecated (and loads slower). Consider re-importing or re-saving the scene. Path: \"%s\"", + get_path())); int idx = sname.get_slicec('/', 1).to_int(); String what = sname.get_slicec('/', 2); @@ -994,9 +1084,9 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) { } //clear unused flags - print_line("format pre: " + itos(old_format)); + print_verbose("Mesh format pre-conversion: " + itos(old_format)); - print_line("format post: " + itos(new_format)); + print_verbose("Mesh format post-conversion: " + itos(new_format)); ERR_FAIL_COND_V(!d.has("aabb"), false); AABB aabb = d["aabb"]; @@ -1104,7 +1194,7 @@ Array ArrayMesh::_get_surfaces() const { data["material"] = surfaces[i].material; } - if (surfaces[i].name != String()) { + if (!surfaces[i].name.is_empty()) { data["name"] = surfaces[i].name; } diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index a95b4d4a5e..08d834bdb9 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/mesh_data_tool.cpp b/scene/resources/mesh_data_tool.cpp index 9ecd8ec2f3..594f723a1d 100644 --- a/scene/resources/mesh_data_tool.cpp +++ b/scene/resources/mesh_data_tool.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/mesh_data_tool.h b/scene/resources/mesh_data_tool.h index b0ebfba7ee..ff27d78c29 100644 --- a/scene/resources/mesh_data_tool.h +++ b/scene/resources/mesh_data_tool.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/mesh_library.cpp b/scene/resources/mesh_library.cpp index 309670e0b1..3db839a1d0 100644 --- a/scene/resources/mesh_library.cpp +++ b/scene/resources/mesh_library.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/mesh_library.h b/scene/resources/mesh_library.h index c25df757e9..e0f2ab2114 100644 --- a/scene/resources/mesh_library.h +++ b/scene/resources/mesh_library.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/multimesh.cpp b/scene/resources/multimesh.cpp index 8894f0bb11..c30e748f66 100644 --- a/scene/resources/multimesh.cpp +++ b/scene/resources/multimesh.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/multimesh.h b/scene/resources/multimesh.h index 2fe0927e6f..30ada5365f 100644 --- a/scene/resources/multimesh.h +++ b/scene/resources/multimesh.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/navigation_mesh.cpp b/scene/resources/navigation_mesh.cpp index db091ec37b..47a87bdea5 100644 --- a/scene/resources/navigation_mesh.cpp +++ b/scene/resources/navigation_mesh.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/navigation_mesh.h b/scene/resources/navigation_mesh.h index 009239838f..e43e8627e4 100644 --- a/scene/resources/navigation_mesh.h +++ b/scene/resources/navigation_mesh.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index c39f59d535..402e67a0f1 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -353,15 +353,23 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const { continue; } - Vector<Variant> binds; - if (c.binds.size()) { - binds.resize(c.binds.size()); - for (int j = 0; j < c.binds.size(); j++) { - binds.write[j] = props[c.binds[j]]; + Callable callable(cto, snames[c.method]); + if (c.unbinds > 0) { + callable = callable.unbind(c.unbinds); + } else if (!c.binds.is_empty()) { + Vector<Variant> binds; + if (c.binds.size()) { + binds.resize(c.binds.size()); + for (int j = 0; j < c.binds.size(); j++) { + binds.write[j] = props[c.binds[j]]; + } } + + const Variant *args = binds.ptr(); + callable = callable.bind(&args, binds.size()); } - cfrom->connect(snames[c.signal], Callable(cto, snames[c.method]), binds, CONNECT_PERSIST | c.flags); + cfrom->connect(snames[c.signal], callable, varray(), CONNECT_PERSIST | c.flags); } //Node *s = ret_nodes[0]; @@ -417,7 +425,7 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map // save the child instantiated scenes that are chosen as editable, so they can be restored // upon load back - if (p_node != p_owner && p_node->get_scene_file_path() != String() && p_owner->is_editable_instance(p_node)) { + if (p_node != p_owner && !p_node->get_scene_file_path().is_empty() && p_owner->is_editable_instance(p_node)) { editable_instances.push_back(p_owner->get_path_to(p_node)); // Node is the root of an editable instance. is_editable_instance = true; @@ -451,7 +459,7 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map bool instantiated_by_owner = false; Vector<SceneState::PackState> states_stack = PropertyUtils::get_node_states_stack(p_node, p_owner, &instantiated_by_owner); - if (p_node->get_scene_file_path() != String() && p_node->get_owner() == p_owner && instantiated_by_owner) { + if (!p_node->get_scene_file_path().is_empty() && p_node->get_owner() == p_owner && instantiated_by_owner) { if (p_node->get_scene_instance_load_placeholder()) { //it's a placeholder, use the placeholder path nd.instance = _vm_get_variant(p_node->get_scene_file_path(), variant_map); @@ -501,8 +509,9 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map Variant value = forced_value.get_type() == Variant::NIL ? p_node->get(name) : forced_value; if (!pinned_props.has(name) && forced_value.get_type() == Variant::NIL) { - Variant default_value = PropertyUtils::get_property_default_value(p_node, name, &states_stack, true); - if (!PropertyUtils::is_property_value_different(value, default_value)) { + bool is_valid_default = false; + Variant default_value = PropertyUtils::get_property_default_value(p_node, name, &is_valid_default, &states_stack, true); + if (is_valid_default && !PropertyUtils::is_property_value_different(value, default_value)) { continue; } } @@ -651,12 +660,32 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName continue; } + Vector<Variant> binds; + int unbinds = 0; + Callable base_callable; + + if (c.callable.is_custom()) { + CallableCustomBind *ccb = dynamic_cast<CallableCustomBind *>(c.callable.get_custom()); + if (ccb) { + binds = ccb->get_binds(); + base_callable = ccb->get_callable(); + } + + CallableCustomUnbind *ccu = dynamic_cast<CallableCustomUnbind *>(c.callable.get_custom()); + if (ccu) { + unbinds = ccu->get_unbinds(); + base_callable = ccu->get_callable(); + } + } else { + base_callable = c.callable; + } + //find if this connection already exists Node *common_parent = target->find_common_parent_with(p_node); ERR_CONTINUE(!common_parent); - if (common_parent != p_owner && common_parent->get_scene_file_path() == String()) { + if (common_parent != p_owner && common_parent->get_scene_file_path().is_empty()) { common_parent = common_parent->get_owner(); } @@ -676,7 +705,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName NodePath signal_from = common_parent->get_path_to(p_node); NodePath signal_to = common_parent->get_path_to(target); - if (ps->has_connection(signal_from, c.signal.get_name(), signal_to, c.callable.get_method())) { + if (ps->has_connection(signal_from, c.signal.get_name(), signal_to, base_callable.get_method())) { exists = true; break; } @@ -707,7 +736,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName if (from_node >= 0 && to_node >= 0) { //this one has state for this node, save - if (state->is_connection(from_node, c.signal.get_name(), to_node, c.callable.get_method())) { + if (state->is_connection(from_node, c.signal.get_name(), to_node, base_callable.get_method())) { exists2 = true; break; } @@ -716,7 +745,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName nl = nullptr; } else { - if (nl->get_scene_file_path() != String()) { + if (!nl->get_scene_file_path().is_empty()) { //is an instance Ref<SceneState> state = nl->get_scene_instance_state(); if (state.is_valid()) { @@ -725,7 +754,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName if (from_node >= 0 && to_node >= 0) { //this one has state for this node, save - if (state->is_connection(from_node, c.signal.get_name(), to_node, c.callable.get_method())) { + if (state->is_connection(from_node, c.signal.get_name(), to_node, base_callable.get_method())) { exists2 = true; break; } @@ -772,12 +801,16 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName ConnectionData cd; cd.from = src_id; cd.to = target_id; - cd.method = _nm_get_string(c.callable.get_method(), name_map); + cd.method = _nm_get_string(base_callable.get_method(), name_map); cd.signal = _nm_get_string(c.signal.get_name(), name_map); cd.flags = c.flags; - for (int i = 0; i < c.binds.size(); i++) { + cd.unbinds = unbinds; + for (int i = 0; i < c.binds.size(); i++) { // TODO: This could be removed now. cd.binds.push_back(_vm_get_variant(c.binds[i], variant_map)); } + for (int i = 0; i < binds.size(); i++) { + cd.binds.push_back(_vm_get_variant(binds[i], variant_map)); + } connections.push_back(cd); } } @@ -1389,6 +1422,11 @@ int SceneState::get_connection_flags(int p_idx) const { return connections[p_idx].flags; } +int SceneState::get_connection_unbinds(int p_idx) const { + ERR_FAIL_INDEX_V(p_idx, connections.size(), -1); + return connections[p_idx].unbinds; +} + Array SceneState::get_connection_binds(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, connections.size(), Array()); Array binds; @@ -1493,7 +1531,7 @@ void SceneState::set_base_scene(int p_idx) { base_scene_idx = p_idx; } -void SceneState::add_connection(int p_from, int p_to, int p_signal, int p_method, int p_flags, const Vector<int> &p_binds) { +void SceneState::add_connection(int p_from, int p_to, int p_signal, int p_method, int p_flags, int p_unbinds, const Vector<int> &p_binds) { ERR_FAIL_INDEX(p_signal, names.size()); ERR_FAIL_INDEX(p_method, names.size()); @@ -1506,6 +1544,7 @@ void SceneState::add_connection(int p_from, int p_to, int p_signal, int p_method c.signal = p_signal; c.method = p_method; c.flags = p_flags; + c.unbinds = p_unbinds; c.binds = p_binds; connections.push_back(c); } @@ -1548,6 +1587,7 @@ void SceneState::_bind_methods() { ClassDB::bind_method(D_METHOD("get_connection_method", "idx"), &SceneState::get_connection_method); ClassDB::bind_method(D_METHOD("get_connection_flags", "idx"), &SceneState::get_connection_flags); ClassDB::bind_method(D_METHOD("get_connection_binds", "idx"), &SceneState::get_connection_binds); + ClassDB::bind_method(D_METHOD("get_connection_unbinds", "idx"), &SceneState::get_connection_unbinds); BIND_ENUM_CONSTANT(GEN_EDIT_STATE_DISABLED); BIND_ENUM_CONSTANT(GEN_EDIT_STATE_INSTANCE); diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h index a03da558e4..81b38840d9 100644 --- a/scene/resources/packed_scene.h +++ b/scene/resources/packed_scene.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -77,6 +77,7 @@ class SceneState : public RefCounted { int signal = 0; int method = 0; int flags = 0; + int unbinds = 0; Vector<int> binds; }; @@ -163,6 +164,7 @@ public: NodePath get_connection_target(int p_idx) const; StringName get_connection_method(int p_idx) const; int get_connection_flags(int p_idx) const; + int get_connection_unbinds(int p_idx) const; Array get_connection_binds(int p_idx) const; bool has_connection(const NodePath &p_node_from, const StringName &p_signal, const NodePath &p_node_to, const StringName &p_method); @@ -178,7 +180,7 @@ public: void add_node_property(int p_node, int p_name, int p_value); void add_node_group(int p_node, int p_group); void set_base_scene(int p_idx); - void add_connection(int p_from, int p_to, int p_signal, int p_method, int p_flags, const Vector<int> &p_binds); + void add_connection(int p_from, int p_to, int p_signal, int p_method, int p_flags, int p_unbinds, const Vector<int> &p_binds); void add_editable_instance(const NodePath &p_path); virtual void set_last_modified_time(uint64_t p_time) { last_modified_time = p_time; } diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp index 5ceb90d511..1ef2b3496f 100644 --- a/scene/resources/particles_material.cpp +++ b/scene/resources/particles_material.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -85,6 +85,7 @@ void ParticlesMaterial::init_shaders() { shader_names->color = "color_value"; shader_names->color_ramp = "color_ramp"; + shader_names->color_initial_ramp = "color_initial_ramp"; shader_names->emission_sphere_radius = "emission_sphere_radius"; shader_names->emission_box_extents = "emission_box_extents"; @@ -232,6 +233,10 @@ void ParticlesMaterial::_update_shader() { code += "uniform sampler2D color_ramp;\n"; } + if (color_initial_ramp.is_valid()) { + code += "uniform sampler2D color_initial_ramp;\n"; + } + if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) { code += "uniform sampler2D linear_velocity_texture;\n"; } @@ -311,6 +316,9 @@ void ParticlesMaterial::_update_shader() { code += " float scale_rand = rand_from_seed(alt_seed);\n"; code += " float hue_rot_rand = rand_from_seed(alt_seed);\n"; code += " float anim_offset_rand = rand_from_seed(alt_seed);\n"; + if (color_initial_ramp.is_valid()) { + code += " float color_initial_rand = rand_from_seed(alt_seed);\n"; + } code += " float pi = 3.14159;\n"; code += " float degree_to_rad = pi / 180.0;\n"; code += "\n"; @@ -462,6 +470,10 @@ void ParticlesMaterial::_update_shader() { code += " float scale_rand = rand_from_seed(alt_seed);\n"; code += " float hue_rot_rand = rand_from_seed(alt_seed);\n"; code += " float anim_offset_rand = rand_from_seed(alt_seed);\n"; + if (color_initial_ramp.is_valid()) { + code += " float color_initial_rand = rand_from_seed(alt_seed);\n"; + } + code += " float pi = 3.14159;\n"; code += " float degree_to_rad = pi / 180.0;\n"; code += "\n"; @@ -620,6 +632,12 @@ void ParticlesMaterial::_update_shader() { } else { code += " COLOR = hue_rot_mat * color_value;\n"; } + + if (color_initial_ramp.is_valid()) { + code += " vec4 start_color = textureLod(color_initial_ramp, vec2(color_initial_rand, 0.0), 0.0);\n"; + code += " COLOR *= start_color;\n"; + } + if (emission_color_texture.is_valid() && (emission_shape == EMISSION_SHAPE_POINTS || emission_shape == EMISSION_SHAPE_DIRECTED_POINTS)) { code += " COLOR *= texelFetch(emission_texture_color, emission_tex_ofs, 0);\n"; } @@ -988,6 +1006,18 @@ Ref<Texture2D> ParticlesMaterial::get_color_ramp() const { return color_ramp; } +void ParticlesMaterial::set_color_initial_ramp(const Ref<Texture2D> &p_texture) { + color_initial_ramp = p_texture; + RID tex_rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); + RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->color_initial_ramp, tex_rid); + _queue_shader_change(); + notify_property_list_changed(); +} + +Ref<Texture2D> ParticlesMaterial::get_color_initial_ramp() const { + return color_initial_ramp; +} + void ParticlesMaterial::set_particle_flag(ParticleFlags p_particle_flag, bool p_enable) { ERR_FAIL_INDEX(p_particle_flag, PARTICLE_FLAG_MAX); particle_flags[p_particle_flag] = p_enable; @@ -1282,6 +1312,9 @@ void ParticlesMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_color_ramp", "ramp"), &ParticlesMaterial::set_color_ramp); ClassDB::bind_method(D_METHOD("get_color_ramp"), &ParticlesMaterial::get_color_ramp); + ClassDB::bind_method(D_METHOD("set_color_initial_ramp", "ramp"), &ParticlesMaterial::set_color_initial_ramp); + ClassDB::bind_method(D_METHOD("get_color_initial_ramp"), &ParticlesMaterial::get_color_initial_ramp); + ClassDB::bind_method(D_METHOD("set_particle_flag", "particle_flag", "enable"), &ParticlesMaterial::set_particle_flag); ClassDB::bind_method(D_METHOD("get_particle_flag", "particle_flag"), &ParticlesMaterial::get_particle_flag); @@ -1414,6 +1447,7 @@ void ParticlesMaterial::_bind_methods() { ADD_GROUP("Color", ""); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "GradientTexture1D"), "set_color_ramp", "get_color_ramp"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_initial_ramp", PROPERTY_HINT_RESOURCE_TYPE, "GradientTexture1D"), "set_color_initial_ramp", "get_color_initial_ramp"); ADD_GROUP("Hue Variation", "hue_"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation_min", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param_min", "get_param_min", PARAM_HUE_VARIATION); diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h index 36bc456978..fd00c58468 100644 --- a/scene/resources/particles_material.h +++ b/scene/resources/particles_material.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -194,6 +194,7 @@ private: StringName color; StringName color_ramp; + StringName color_initial_ramp; StringName emission_sphere_radius; StringName emission_box_extents; @@ -237,6 +238,7 @@ private: Ref<Texture2D> tex_parameters[PARAM_MAX]; Color color; Ref<Texture2D> color_ramp; + Ref<Texture2D> color_initial_ramp; bool particle_flags[PARTICLE_FLAG_MAX]; @@ -299,6 +301,9 @@ public: void set_color_ramp(const Ref<Texture2D> &p_texture); Ref<Texture2D> get_color_ramp() const; + void set_color_initial_ramp(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_color_initial_ramp() const; + void set_particle_flag(ParticleFlags p_particle_flag, bool p_enable); bool get_particle_flag(ParticleFlags p_particle_flag) const; diff --git a/scene/resources/physics_material.cpp b/scene/resources/physics_material.cpp index 31df35aa51..c1b868cb97 100644 --- a/scene/resources/physics_material.cpp +++ b/scene/resources/physics_material.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/physics_material.h b/scene/resources/physics_material.h index d302800823..f352e66189 100644 --- a/scene/resources/physics_material.h +++ b/scene/resources/physics_material.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/polygon_path_finder.cpp b/scene/resources/polygon_path_finder.cpp index ec2022ed2f..882afdb43d 100644 --- a/scene/resources/polygon_path_finder.cpp +++ b/scene/resources/polygon_path_finder.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/polygon_path_finder.h b/scene/resources/polygon_path_finder.h index 2f3cb634fb..db96192917 100644 --- a/scene/resources/polygon_path_finder.h +++ b/scene/resources/polygon_path_finder.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index f8be00f5fb..38acd0af0a 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h index d447dad97a..aa9682bd80 100644 --- a/scene/resources/primitive_meshes.h +++ b/scene/resources/primitive_meshes.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -36,11 +36,10 @@ ///@TODO probably should change a few integers to unsigned integers... /** - @author Bastiaan Olij <mux213@gmail.com> - Base class for all the classes in this file, handles a number of code functions that are shared among all meshes. This class is set apart that it assumes a single surface is always generated for our mesh. */ + class PrimitiveMesh : public Mesh { GDCLASS(PrimitiveMesh, Mesh); diff --git a/scene/resources/rectangle_shape_2d.cpp b/scene/resources/rectangle_shape_2d.cpp index 17ce0b34ac..27659f724e 100644 --- a/scene/resources/rectangle_shape_2d.cpp +++ b/scene/resources/rectangle_shape_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/rectangle_shape_2d.h b/scene/resources/rectangle_shape_2d.h index f1e8be4c5b..fa85aef428 100644 --- a/scene/resources/rectangle_shape_2d.h +++ b/scene/resources/rectangle_shape_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index cead42b4e2..1b81455d4c 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -274,12 +274,12 @@ Ref<PackedScene> ResourceLoaderText::_parse_node_tag(VariantParser::ResourcePars } } - if (assign != String()) { + if (!assign.is_empty()) { int nameidx = packed_scene->get_state()->add_name(assign); int valueidx = packed_scene->get_state()->add_value(value); packed_scene->get_state()->add_node_property(node_id, nameidx, valueidx); //it's assignment - } else if (next_tag.name != String()) { + } else if (!next_tag.name.is_empty()) { break; } } @@ -313,6 +313,7 @@ Ref<PackedScene> ResourceLoaderText::_parse_node_tag(VariantParser::ResourcePars StringName method = next_tag.fields["method"]; StringName signal = next_tag.fields["signal"]; int flags = Object::CONNECT_PERSIST; + int unbinds = 0; Array binds; if (next_tag.fields.has("flags")) { @@ -323,6 +324,10 @@ Ref<PackedScene> ResourceLoaderText::_parse_node_tag(VariantParser::ResourcePars binds = next_tag.fields["binds"]; } + if (next_tag.fields.has("unbinds")) { + unbinds = next_tag.fields["unbinds"]; + } + Vector<int> bind_ints; for (int i = 0; i < binds.size(); i++) { bind_ints.push_back(packed_scene->get_state()->add_value(binds[i])); @@ -334,6 +339,7 @@ Ref<PackedScene> ResourceLoaderText::_parse_node_tag(VariantParser::ResourcePars packed_scene->get_state()->add_name(signal), packed_scene->get_state()->add_name(method), flags, + unbinds, bind_ints); error = VariantParser::parse_tag(&stream, lines, error_text, next_tag, &parser); @@ -575,12 +581,12 @@ Error ResourceLoaderText::load() { return error; } - if (assign != String()) { + if (!assign.is_empty()) { if (do_assign) { res->set(assign, value); } //it's assignment - } else if (next_tag.name != String()) { + } else if (!next_tag.name.is_empty()) { error = OK; break; } else { @@ -659,10 +665,10 @@ Error ResourceLoaderText::load() { return error; } - if (assign != String()) { + if (!assign.is_empty()) { resource->set(assign, value); //it's assignment - } else if (next_tag.name != String()) { + } else if (!next_tag.name.is_empty()) { error = ERR_FILE_CORRUPT; error_text = "Extra tag found when parsing main resource file"; _printerr(); @@ -1166,13 +1172,13 @@ Error ResourceLoaderText::save_as_binary(FileAccess *p_f, const String &p_path) return error; } - if (assign != String()) { + if (!assign.is_empty()) { Map<StringName, int> empty_string_map; //unused bs_save_unicode_string(wf2, assign, true); ResourceFormatSaverBinaryInstance::write_variant(wf2, value, dummy_read.resource_index_map, dummy_read.external_resources, empty_string_map); prop_count++; - } else if (next_tag.name != String()) { + } else if (!next_tag.name.is_empty()) { error = OK; break; } else { @@ -1350,7 +1356,7 @@ RES ResourceFormatLoaderText::load(const String &p_path, const String &p_origina ERR_FAIL_COND_V_MSG(err != OK, RES(), "Cannot open file '" + p_path + "'."); ResourceLoaderText loader; - String path = p_original_path != "" ? p_original_path : p_path; + String path = !p_original_path.is_empty() ? p_original_path : p_path; loader.cache_mode = p_cache_mode; loader.use_sub_threads = p_use_sub_threads; loader.local_path = ProjectSettings::get_singleton()->localize_path(path); @@ -1369,7 +1375,7 @@ RES ResourceFormatLoaderText::load(const String &p_path, const String &p_origina } void ResourceFormatLoaderText::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const { - if (p_type == "") { + if (p_type.is_empty()) { get_recognized_extensions(p_extensions); return; } @@ -1655,7 +1661,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r Set<String> cached_ids_found; for (KeyValue<RES, String> &E : external_resources) { String cached_id = E.key->get_id_for_path(local_path); - if (cached_id == "" || cached_ids_found.has(cached_id)) { + if (cached_id.is_empty() || cached_ids_found.has(cached_id)) { int sep_pos = E.value.find("_"); if (sep_pos != -1) { E.value = E.value.substr(0, sep_pos + 1); // Keep the order found, for improved thread loading performance. @@ -1729,7 +1735,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r for (List<RES>::Element *E = saved_resources.front(); E; E = E->next()) { RES res = E->get(); if (E->next() && res->is_built_in()) { - if (res->get_scene_unique_id() != "") { + if (!res->get_scene_unique_id().is_empty()) { if (used_unique_ids.has(res->get_scene_unique_id())) { res->set_scene_unique_id(""); // Repeated. } else { @@ -1752,7 +1758,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r f->store_line("[resource]"); } else { String line = "[sub_resource "; - if (res->get_scene_unique_id() == "") { + if (res->get_scene_unique_id().is_empty()) { String new_id; while (true) { new_id = res->get_class() + "_" + Resource::generate_scene_unique_id(); @@ -1866,7 +1872,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r f->store_string(header); - if (instance_placeholder != String()) { + if (!instance_placeholder.is_empty()) { String vars; f->store_string(" instance_placeholder="); VariantWriter::write_to_string(instance_placeholder, vars, _write_resources, this); @@ -1909,6 +1915,11 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r connstr += " flags=" + itos(flags); } + int unbinds = state->get_connection_unbinds(i); + if (unbinds > 0) { + connstr += " unbinds=" + itos(unbinds); + } + Array binds = state->get_connection_binds(i); f->store_string(connstr); if (binds.size()) { diff --git a/scene/resources/resource_format_text.h b/scene/resources/resource_format_text.h index 373e71b2c4..9585b9040f 100644 --- a/scene/resources/resource_format_text.h +++ b/scene/resources/resource_format_text.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/segment_shape_2d.cpp b/scene/resources/segment_shape_2d.cpp index 35439634f8..cea8ca1b29 100644 --- a/scene/resources/segment_shape_2d.cpp +++ b/scene/resources/segment_shape_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/segment_shape_2d.h b/scene/resources/segment_shape_2d.h index f218955061..6ade0618e3 100644 --- a/scene/resources/segment_shape_2d.h +++ b/scene/resources/segment_shape_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/separation_ray_shape_2d.cpp b/scene/resources/separation_ray_shape_2d.cpp index 0acd6d268d..0406c91b70 100644 --- a/scene/resources/separation_ray_shape_2d.cpp +++ b/scene/resources/separation_ray_shape_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -59,15 +59,13 @@ void SeparationRayShape2D::draw(const RID &p_to_rid, const Color &p_color) { xf.rotate(target_position.angle()); xf.translate(Vector2(no_line ? 0 : target_position.length() - arrow_size, 0)); - Vector<Vector2> pts; - pts.push_back(xf.xform(Vector2(arrow_size, 0))); - pts.push_back(xf.xform(Vector2(0, 0.5 * arrow_size))); - pts.push_back(xf.xform(Vector2(0, -0.5 * arrow_size))); + Vector<Vector2> pts = { + xf.xform(Vector2(arrow_size, 0)), + xf.xform(Vector2(0, 0.5 * arrow_size)), + xf.xform(Vector2(0, -0.5 * arrow_size)) + }; - Vector<Color> cols; - for (int i = 0; i < 3; i++) { - cols.push_back(p_color); - } + Vector<Color> cols = { p_color, p_color, p_color }; RS::get_singleton()->canvas_item_add_primitive(p_to_rid, pts, cols, Vector<Point2>(), RID()); } diff --git a/scene/resources/separation_ray_shape_2d.h b/scene/resources/separation_ray_shape_2d.h index 5b74e6c727..7c35d53133 100644 --- a/scene/resources/separation_ray_shape_2d.h +++ b/scene/resources/separation_ray_shape_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/separation_ray_shape_3d.cpp b/scene/resources/separation_ray_shape_3d.cpp index 376e04c844..5aa7616589 100644 --- a/scene/resources/separation_ray_shape_3d.cpp +++ b/scene/resources/separation_ray_shape_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -33,9 +33,10 @@ #include "servers/physics_server_3d.h" Vector<Vector3> SeparationRayShape3D::get_debug_mesh_lines() const { - Vector<Vector3> points; - points.push_back(Vector3()); - points.push_back(Vector3(0, 0, get_length())); + Vector<Vector3> points = { + Vector3(), + Vector3(0, 0, get_length()) + }; return points; } diff --git a/scene/resources/separation_ray_shape_3d.h b/scene/resources/separation_ray_shape_3d.h index 54058b6095..0e750a48e6 100644 --- a/scene/resources/separation_ray_shape_3d.h +++ b/scene/resources/separation_ray_shape_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index 84fa07e4f4..ce7fcb199d 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/shader.h b/scene/resources/shader.h index c688dc1bab..d05ec06819 100644 --- a/scene/resources/shader.h +++ b/scene/resources/shader.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/shape_2d.cpp b/scene/resources/shape_2d.cpp index 013b1ef1a9..16ef45829f 100644 --- a/scene/resources/shape_2d.cpp +++ b/scene/resources/shape_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/shape_2d.h b/scene/resources/shape_2d.h index 7c5d1344e8..e9dc10eeae 100644 --- a/scene/resources/shape_2d.h +++ b/scene/resources/shape_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/shape_3d.cpp b/scene/resources/shape_3d.cpp index a02a0e5488..ffb2b27644 100644 --- a/scene/resources/shape_3d.cpp +++ b/scene/resources/shape_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -48,6 +48,15 @@ void Shape3D::add_vertices_to_array(Vector<Vector3> &array, const Transform3D &p } } +void Shape3D::set_custom_solver_bias(real_t p_bias) { + custom_bias = p_bias; + PhysicsServer3D::get_singleton()->shape_set_custom_solver_bias(shape, custom_bias); +} + +real_t Shape3D::get_custom_solver_bias() const { + return custom_bias; +} + real_t Shape3D::get_margin() const { return margin; } @@ -99,11 +108,15 @@ void Shape3D::_update_shape() { } void Shape3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_custom_solver_bias", "bias"), &Shape3D::set_custom_solver_bias); + ClassDB::bind_method(D_METHOD("get_custom_solver_bias"), &Shape3D::get_custom_solver_bias); + ClassDB::bind_method(D_METHOD("set_margin", "margin"), &Shape3D::set_margin); ClassDB::bind_method(D_METHOD("get_margin"), &Shape3D::get_margin); ClassDB::bind_method(D_METHOD("get_debug_mesh"), &Shape3D::get_debug_mesh); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "custom_solver_bias", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_custom_solver_bias", "get_custom_solver_bias"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin", PROPERTY_HINT_RANGE, "0.001,10,0.001"), "set_margin", "get_margin"); } diff --git a/scene/resources/shape_3d.h b/scene/resources/shape_3d.h index b8e529cd3c..77e79a269d 100644 --- a/scene/resources/shape_3d.h +++ b/scene/resources/shape_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -40,6 +40,7 @@ class Shape3D : public Resource { OBJ_SAVE_TYPE(Shape3D); RES_BASE_EXTENSION("shape"); RID shape; + real_t custom_bias = 0.0; real_t margin = 0.04; Ref<ArrayMesh> debug_mesh_cache; @@ -62,6 +63,9 @@ public: void add_vertices_to_array(Vector<Vector3> &array, const Transform3D &p_xform); + void set_custom_solver_bias(real_t p_bias); + real_t get_custom_solver_bias() const; + real_t get_margin() const; void set_margin(real_t p_margin); diff --git a/scene/resources/skeleton_modification_2d.cpp b/scene/resources/skeleton_modification_2d.cpp index 7ac40b497d..885cf0f1b8 100644 --- a/scene/resources/skeleton_modification_2d.cpp +++ b/scene/resources/skeleton_modification_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_2d.h b/scene/resources/skeleton_modification_2d.h index aaddb9136e..d49f9e7f51 100644 --- a/scene/resources/skeleton_modification_2d.h +++ b/scene/resources/skeleton_modification_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_2d_ccdik.cpp b/scene/resources/skeleton_modification_2d_ccdik.cpp index bea42109cb..7adaf1452c 100644 --- a/scene/resources/skeleton_modification_2d_ccdik.cpp +++ b/scene/resources/skeleton_modification_2d_ccdik.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_2d_ccdik.h b/scene/resources/skeleton_modification_2d_ccdik.h index dc48291f62..31485fa31f 100644 --- a/scene/resources/skeleton_modification_2d_ccdik.h +++ b/scene/resources/skeleton_modification_2d_ccdik.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_2d_fabrik.cpp b/scene/resources/skeleton_modification_2d_fabrik.cpp index 3b5c555f89..393d404e9b 100644 --- a/scene/resources/skeleton_modification_2d_fabrik.cpp +++ b/scene/resources/skeleton_modification_2d_fabrik.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_2d_fabrik.h b/scene/resources/skeleton_modification_2d_fabrik.h index 79e0106e26..d5077084ef 100644 --- a/scene/resources/skeleton_modification_2d_fabrik.h +++ b/scene/resources/skeleton_modification_2d_fabrik.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_2d_jiggle.cpp b/scene/resources/skeleton_modification_2d_jiggle.cpp index 31045455a3..eee6067dae 100644 --- a/scene/resources/skeleton_modification_2d_jiggle.cpp +++ b/scene/resources/skeleton_modification_2d_jiggle.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_2d_jiggle.h b/scene/resources/skeleton_modification_2d_jiggle.h index e24038a1db..a1abca6564 100644 --- a/scene/resources/skeleton_modification_2d_jiggle.h +++ b/scene/resources/skeleton_modification_2d_jiggle.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_2d_lookat.cpp b/scene/resources/skeleton_modification_2d_lookat.cpp index 740937fc44..23e1c579dc 100644 --- a/scene/resources/skeleton_modification_2d_lookat.cpp +++ b/scene/resources/skeleton_modification_2d_lookat.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_2d_lookat.h b/scene/resources/skeleton_modification_2d_lookat.h index 6aff30b826..ff91b92e7d 100644 --- a/scene/resources/skeleton_modification_2d_lookat.h +++ b/scene/resources/skeleton_modification_2d_lookat.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_2d_physicalbones.cpp b/scene/resources/skeleton_modification_2d_physicalbones.cpp index 9dedb93f36..ddfd1d06b3 100644 --- a/scene/resources/skeleton_modification_2d_physicalbones.cpp +++ b/scene/resources/skeleton_modification_2d_physicalbones.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_2d_physicalbones.h b/scene/resources/skeleton_modification_2d_physicalbones.h index cdf6a5f570..d53102fa5e 100644 --- a/scene/resources/skeleton_modification_2d_physicalbones.h +++ b/scene/resources/skeleton_modification_2d_physicalbones.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_2d_stackholder.cpp b/scene/resources/skeleton_modification_2d_stackholder.cpp index 9436092cd9..9ec3434704 100644 --- a/scene/resources/skeleton_modification_2d_stackholder.cpp +++ b/scene/resources/skeleton_modification_2d_stackholder.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_2d_stackholder.h b/scene/resources/skeleton_modification_2d_stackholder.h index 9cc38e3942..99d9f6f381 100644 --- a/scene/resources/skeleton_modification_2d_stackholder.h +++ b/scene/resources/skeleton_modification_2d_stackholder.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_2d_twoboneik.cpp b/scene/resources/skeleton_modification_2d_twoboneik.cpp index 4f752896a9..b08fd82381 100644 --- a/scene/resources/skeleton_modification_2d_twoboneik.cpp +++ b/scene/resources/skeleton_modification_2d_twoboneik.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_2d_twoboneik.h b/scene/resources/skeleton_modification_2d_twoboneik.h index c7e545a488..fc14d35f70 100644 --- a/scene/resources/skeleton_modification_2d_twoboneik.h +++ b/scene/resources/skeleton_modification_2d_twoboneik.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_3d.cpp b/scene/resources/skeleton_modification_3d.cpp index b476952d86..b5b3fd5e9f 100644 --- a/scene/resources/skeleton_modification_3d.cpp +++ b/scene/resources/skeleton_modification_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_3d.h b/scene/resources/skeleton_modification_3d.h index fb1f3d33d1..a81c0c38bd 100644 --- a/scene/resources/skeleton_modification_3d.h +++ b/scene/resources/skeleton_modification_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_3d_ccdik.cpp b/scene/resources/skeleton_modification_3d_ccdik.cpp index 6409022563..f19be47db2 100644 --- a/scene/resources/skeleton_modification_3d_ccdik.cpp +++ b/scene/resources/skeleton_modification_3d_ccdik.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_3d_ccdik.h b/scene/resources/skeleton_modification_3d_ccdik.h index e7537cc5b0..873ab8aa5a 100644 --- a/scene/resources/skeleton_modification_3d_ccdik.h +++ b/scene/resources/skeleton_modification_3d_ccdik.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_3d_fabrik.cpp b/scene/resources/skeleton_modification_3d_fabrik.cpp index dedea3e282..b62dda3f4f 100644 --- a/scene/resources/skeleton_modification_3d_fabrik.cpp +++ b/scene/resources/skeleton_modification_3d_fabrik.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_3d_fabrik.h b/scene/resources/skeleton_modification_3d_fabrik.h index 6c58b8a07a..cc4d3a5e20 100644 --- a/scene/resources/skeleton_modification_3d_fabrik.h +++ b/scene/resources/skeleton_modification_3d_fabrik.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_3d_jiggle.cpp b/scene/resources/skeleton_modification_3d_jiggle.cpp index 2535f2b987..3e36c241f7 100644 --- a/scene/resources/skeleton_modification_3d_jiggle.cpp +++ b/scene/resources/skeleton_modification_3d_jiggle.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -168,7 +168,7 @@ void SkeletonModification3DJiggle::_execute_jiggle_joint(int p_joint_idx, Node3D } if (_print_execution_error( jiggle_data_chain[p_joint_idx].bone_idx < 0 || jiggle_data_chain[p_joint_idx].bone_idx > stack->skeleton->get_bone_count(), - "Jiggle joint " + itos(p_joint_idx) + " bone index is invald. Cannot execute modification!")) { + "Jiggle joint " + itos(p_joint_idx) + " bone index is invalid. Cannot execute modification!")) { return; } diff --git a/scene/resources/skeleton_modification_3d_jiggle.h b/scene/resources/skeleton_modification_3d_jiggle.h index c210c8fa73..7ec5ed4f11 100644 --- a/scene/resources/skeleton_modification_3d_jiggle.h +++ b/scene/resources/skeleton_modification_3d_jiggle.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_3d_lookat.cpp b/scene/resources/skeleton_modification_3d_lookat.cpp index f3b0f41d60..3e8c1e3a77 100644 --- a/scene/resources/skeleton_modification_3d_lookat.cpp +++ b/scene/resources/skeleton_modification_3d_lookat.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_3d_lookat.h b/scene/resources/skeleton_modification_3d_lookat.h index 5971e3f647..9f5120a0fd 100644 --- a/scene/resources/skeleton_modification_3d_lookat.h +++ b/scene/resources/skeleton_modification_3d_lookat.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_3d_stackholder.cpp b/scene/resources/skeleton_modification_3d_stackholder.cpp index 56035a4def..fb2e80d217 100644 --- a/scene/resources/skeleton_modification_3d_stackholder.cpp +++ b/scene/resources/skeleton_modification_3d_stackholder.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_3d_stackholder.h b/scene/resources/skeleton_modification_3d_stackholder.h index c765cd8de3..5780d7d43f 100644 --- a/scene/resources/skeleton_modification_3d_stackholder.h +++ b/scene/resources/skeleton_modification_3d_stackholder.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_3d_twoboneik.cpp b/scene/resources/skeleton_modification_3d_twoboneik.cpp index 93ec155a88..acc5ff716c 100644 --- a/scene/resources/skeleton_modification_3d_twoboneik.cpp +++ b/scene/resources/skeleton_modification_3d_twoboneik.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_3d_twoboneik.h b/scene/resources/skeleton_modification_3d_twoboneik.h index e62d6cc497..a4ddc6cee7 100644 --- a/scene/resources/skeleton_modification_3d_twoboneik.h +++ b/scene/resources/skeleton_modification_3d_twoboneik.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_stack_2d.cpp b/scene/resources/skeleton_modification_stack_2d.cpp index e596390f78..b944c244b6 100644 --- a/scene/resources/skeleton_modification_stack_2d.cpp +++ b/scene/resources/skeleton_modification_stack_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_stack_2d.h b/scene/resources/skeleton_modification_stack_2d.h index 58855701a1..7b5f8e0322 100644 --- a/scene/resources/skeleton_modification_stack_2d.h +++ b/scene/resources/skeleton_modification_stack_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_stack_3d.cpp b/scene/resources/skeleton_modification_stack_3d.cpp index e5b7771251..7ccba1228c 100644 --- a/scene/resources/skeleton_modification_stack_3d.cpp +++ b/scene/resources/skeleton_modification_stack_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skeleton_modification_stack_3d.h b/scene/resources/skeleton_modification_stack_3d.h index cbc8d4e0b9..2c17fba2c5 100644 --- a/scene/resources/skeleton_modification_stack_3d.h +++ b/scene/resources/skeleton_modification_stack_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/skin.cpp b/scene/resources/skin.cpp index 15cdb86bab..54ed71999c 100644 --- a/scene/resources/skin.cpp +++ b/scene/resources/skin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -143,6 +143,7 @@ void Skin::_bind_methods() { ClassDB::bind_method(D_METHOD("get_bind_count"), &Skin::get_bind_count); ClassDB::bind_method(D_METHOD("add_bind", "bone", "pose"), &Skin::add_bind); + ClassDB::bind_method(D_METHOD("add_named_bind", "name", "pose"), &Skin::add_named_bind); ClassDB::bind_method(D_METHOD("set_bind_pose", "bind_index", "pose"), &Skin::set_bind_pose); ClassDB::bind_method(D_METHOD("get_bind_pose", "bind_index"), &Skin::get_bind_pose); diff --git a/scene/resources/skin.h b/scene/resources/skin.h index 6857bf743a..6ade9dbed1 100644 --- a/scene/resources/skin.h +++ b/scene/resources/skin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -67,23 +67,17 @@ public: void set_bind_name(int p_index, const StringName &p_name); inline int get_bind_bone(int p_index) const { -#ifdef DEBUG_ENABLED ERR_FAIL_INDEX_V(p_index, bind_count, -1); -#endif return binds_ptr[p_index].bone; } inline StringName get_bind_name(int p_index) const { -#ifdef DEBUG_ENABLED ERR_FAIL_INDEX_V(p_index, bind_count, StringName()); -#endif return binds_ptr[p_index].name; } inline Transform3D get_bind_pose(int p_index) const { -#ifdef DEBUG_ENABLED ERR_FAIL_INDEX_V(p_index, bind_count, Transform3D()); -#endif return binds_ptr[p_index].pose; } diff --git a/scene/resources/sky.cpp b/scene/resources/sky.cpp index 71424ba8ac..9cb6a16f5c 100644 --- a/scene/resources/sky.cpp +++ b/scene/resources/sky.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/sky.h b/scene/resources/sky.h index f0226d321d..5e52239032 100644 --- a/scene/resources/sky.h +++ b/scene/resources/sky.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/sky_material.cpp b/scene/resources/sky_material.cpp index ff388e288c..6ec16f12df 100644 --- a/scene/resources/sky_material.cpp +++ b/scene/resources/sky_material.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -308,14 +308,30 @@ Ref<Texture2D> PanoramaSkyMaterial::get_panorama() const { return panorama; } +void PanoramaSkyMaterial::set_filtering_enabled(bool p_enabled) { + filter = p_enabled; + notify_property_list_changed(); + _update_shader(); + // Only set if shader already compiled + if (shader_set) { + RS::get_singleton()->material_set_shader(_get_material(), shader_cache[int(filter)]); + } +} + +bool PanoramaSkyMaterial::is_filtering_enabled() const { + return filter; +} + Shader::Mode PanoramaSkyMaterial::get_shader_mode() const { return Shader::MODE_SKY; } RID PanoramaSkyMaterial::get_rid() const { _update_shader(); + // Don't compile shaders until first use, then compile both if (!shader_set) { - RS::get_singleton()->material_set_shader(_get_material(), shader); + RS::get_singleton()->material_set_shader(_get_material(), shader_cache[1 - int(filter)]); + RS::get_singleton()->material_set_shader(_get_material(), shader_cache[int(filter)]); shader_set = true; } return _get_material(); @@ -323,42 +339,47 @@ RID PanoramaSkyMaterial::get_rid() const { RID PanoramaSkyMaterial::get_shader_rid() const { _update_shader(); - return shader; + return shader_cache[int(filter)]; } void PanoramaSkyMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_panorama", "texture"), &PanoramaSkyMaterial::set_panorama); ClassDB::bind_method(D_METHOD("get_panorama"), &PanoramaSkyMaterial::get_panorama); + ClassDB::bind_method(D_METHOD("set_filtering_enabled", "enabled"), &PanoramaSkyMaterial::set_filtering_enabled); + ClassDB::bind_method(D_METHOD("is_filtering_enabled"), &PanoramaSkyMaterial::is_filtering_enabled); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "panorama", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_panorama", "get_panorama"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter"), "set_filtering_enabled", "is_filtering_enabled"); } Mutex PanoramaSkyMaterial::shader_mutex; -RID PanoramaSkyMaterial::shader; +RID PanoramaSkyMaterial::shader_cache[2]; void PanoramaSkyMaterial::cleanup_shader() { - if (shader.is_valid()) { - RS::get_singleton()->free(shader); + if (shader_cache[0].is_valid()) { + RS::get_singleton()->free(shader_cache[0]); + RS::get_singleton()->free(shader_cache[1]); } } void PanoramaSkyMaterial::_update_shader() { shader_mutex.lock(); - if (shader.is_null()) { - shader = RS::get_singleton()->shader_create(); + if (shader_cache[0].is_null()) { + for (int i = 0; i < 2; i++) { + shader_cache[i] = RS::get_singleton()->shader_create(); - // Add a comment to describe the shader origin (useful when converting to ShaderMaterial). - RS::get_singleton()->shader_set_code(shader, R"( + // Add a comment to describe the shader origin (useful when converting to ShaderMaterial). + RS::get_singleton()->shader_set_code(shader_cache[i], vformat(R"( // NOTE: Shader automatically converted from )" VERSION_NAME " " VERSION_FULL_CONFIG R"('s PanoramaSkyMaterial. - shader_type sky; - -uniform sampler2D source_panorama : filter_linear, hint_albedo; - +uniform sampler2D source_panorama : %s, hint_albedo; void sky() { COLOR = texture(source_panorama, SKY_COORDS).rgb; } -)"); +)", + i ? "filter_linear" : "filter_nearest")); + } } shader_mutex.unlock(); diff --git a/scene/resources/sky_material.h b/scene/resources/sky_material.h index daeda212d4..7f421beb8d 100644 --- a/scene/resources/sky_material.h +++ b/scene/resources/sky_material.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -110,10 +110,12 @@ private: Ref<Texture2D> panorama; static Mutex shader_mutex; - static RID shader; + static RID shader_cache[2]; static void _update_shader(); mutable bool shader_set = false; + bool filter = true; + protected: static void _bind_methods(); @@ -121,6 +123,9 @@ public: void set_panorama(const Ref<Texture2D> &p_panorama); Ref<Texture2D> get_panorama() const; + void set_filtering_enabled(bool p_enabled); + bool is_filtering_enabled() const; + virtual Shader::Mode get_shader_mode() const override; virtual RID get_shader_rid() const override; virtual RID get_rid() const override; diff --git a/scene/resources/sphere_shape_3d.cpp b/scene/resources/sphere_shape_3d.cpp index e4b4398063..ee789362c9 100644 --- a/scene/resources/sphere_shape_3d.cpp +++ b/scene/resources/sphere_shape_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/sphere_shape_3d.h b/scene/resources/sphere_shape_3d.h index eddd2a2132..ff6d883940 100644 --- a/scene/resources/sphere_shape_3d.h +++ b/scene/resources/sphere_shape_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/sprite_frames.cpp b/scene/resources/sprite_frames.cpp index 71ed96cf15..ece126791e 100644 --- a/scene/resources/sprite_frames.cpp +++ b/scene/resources/sprite_frames.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/sprite_frames.h b/scene/resources/sprite_frames.h index fdfd6af5ab..12b69afde1 100644 --- a/scene/resources/sprite_frames.h +++ b/scene/resources/sprite_frames.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp index b960944d99..5afd424e03 100644 --- a/scene/resources/style_box.cpp +++ b/scene/resources/style_box.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -521,21 +521,22 @@ inline void draw_ring(Vector<Vector2> &verts, Vector<int> &indices, Vector<Color set_inner_corner_radius(style_rect, ring_rect, corner_radius, ring_corner_radius); // Corner radius center points. - Vector<Point2> outer_points; - outer_points.push_back(ring_rect.position + Vector2(ring_corner_radius[0], ring_corner_radius[0])); //tl - outer_points.push_back(Point2(ring_rect.position.x + ring_rect.size.x - ring_corner_radius[1], ring_rect.position.y + ring_corner_radius[1])); //tr - outer_points.push_back(ring_rect.position + ring_rect.size - Vector2(ring_corner_radius[2], ring_corner_radius[2])); //br - outer_points.push_back(Point2(ring_rect.position.x + ring_corner_radius[3], ring_rect.position.y + ring_rect.size.y - ring_corner_radius[3])); //bl + Vector<Point2> outer_points = { + ring_rect.position + Vector2(ring_corner_radius[0], ring_corner_radius[0]), //tl + Point2(ring_rect.position.x + ring_rect.size.x - ring_corner_radius[1], ring_rect.position.y + ring_corner_radius[1]), //tr + ring_rect.position + ring_rect.size - Vector2(ring_corner_radius[2], ring_corner_radius[2]), //br + Point2(ring_rect.position.x + ring_corner_radius[3], ring_rect.position.y + ring_rect.size.y - ring_corner_radius[3]) //bl + }; real_t inner_corner_radius[4]; set_inner_corner_radius(style_rect, inner_rect, corner_radius, inner_corner_radius); - Vector<Point2> inner_points; - inner_points.push_back(inner_rect.position + Vector2(inner_corner_radius[0], inner_corner_radius[0])); //tl - inner_points.push_back(Point2(inner_rect.position.x + inner_rect.size.x - inner_corner_radius[1], inner_rect.position.y + inner_corner_radius[1])); //tr - inner_points.push_back(inner_rect.position + inner_rect.size - Vector2(inner_corner_radius[2], inner_corner_radius[2])); //br - inner_points.push_back(Point2(inner_rect.position.x + inner_corner_radius[3], inner_rect.position.y + inner_rect.size.y - inner_corner_radius[3])); //bl - + Vector<Point2> inner_points = { + inner_rect.position + Vector2(inner_corner_radius[0], inner_corner_radius[0]), //tl + Point2(inner_rect.position.x + inner_rect.size.x - inner_corner_radius[1], inner_rect.position.y + inner_corner_radius[1]), //tr + inner_rect.position + inner_rect.size - Vector2(inner_corner_radius[2], inner_corner_radius[2]), //br + Point2(inner_rect.position.x + inner_corner_radius[3], inner_rect.position.y + inner_rect.size.y - inner_corner_radius[3]) //bl + }; // Calculate the vertices. for (int corner_index = 0; corner_index < 4; corner_index++) { for (int detail = 0; detail <= adapted_corner_detail; detail++) { diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h index a6cd5b7fb7..4c41f42293 100644 --- a/scene/resources/style_box.h +++ b/scene/resources/style_box.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index 455af8a40c..cc7322476f 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h index bde6702759..9cb83e0e68 100644 --- a/scene/resources/surface_tool.h +++ b/scene/resources/surface_tool.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/syntax_highlighter.cpp b/scene/resources/syntax_highlighter.cpp index cfb5ac2ca6..e0aa21ac37 100644 --- a/scene/resources/syntax_highlighter.cpp +++ b/scene/resources/syntax_highlighter.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -171,12 +171,15 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting_impl(int p_line) { /* color regions */ if (is_a_symbol || in_region != -1) { int from = j; - for (; from < line_length; from++) { - if (str[from] == '\\') { - from++; - continue; + + if (in_region == -1) { + for (; from < line_length; from++) { + if (str[from] == '\\') { + from++; + continue; + } + break; } - break; } if (from != line_length) { @@ -208,6 +211,12 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting_impl(int p_line) { /* check if it's the whole line */ if (end_key_length == 0 || color_regions[c].line_only || from + end_key_length > line_length) { + if (from + end_key_length > line_length && (color_regions[in_region].start_key == "\"" || color_regions[in_region].start_key == "\'")) { + // If it's key length and there is a '\', dont skip to highlight esc chars. + if (str.find("\\", from) >= 0) { + break; + } + } prev_color = color_regions[in_region].color; highlighter_info["color"] = color_regions[c].color; color_map[j] = highlighter_info; @@ -227,13 +236,23 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting_impl(int p_line) { /* if we are in one find the end key */ if (in_region != -1) { + bool is_string = (color_regions[in_region].start_key == "\"" || color_regions[in_region].start_key == "\'"); + + Color region_color = color_regions[in_region].color; + prev_color = region_color; + highlighter_info["color"] = region_color; + color_map[j] = highlighter_info; + /* search the line */ int region_end_index = -1; int end_key_length = color_regions[in_region].end_key.length(); const char32_t *end_key = color_regions[in_region].end_key.get_data(); for (; from < line_length; from++) { if (line_length - from < end_key_length) { - break; + // Don't break if '\' to highlight esc chars. + if (!is_string || str.find("\\", from) < 0) { + break; + } } if (!is_symbol(str[from])) { @@ -241,7 +260,20 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting_impl(int p_line) { } if (str[from] == '\\') { + if (is_string) { + Dictionary escape_char_highlighter_info; + escape_char_highlighter_info["color"] = symbol_color; + color_map[from] = escape_char_highlighter_info; + } + from++; + + if (is_string) { + Dictionary region_continue_highlighter_info; + prev_color = region_color; + region_continue_highlighter_info["color"] = region_color; + color_map[from + 1] = region_continue_highlighter_info; + } continue; } @@ -258,10 +290,6 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting_impl(int p_line) { } } - prev_color = color_regions[in_region].color; - highlighter_info["color"] = color_regions[in_region].color; - color_map[j] = highlighter_info; - j = from + (end_key_length - 1); if (region_end_index == -1) { color_region_cache[p_line] = in_region; @@ -493,7 +521,7 @@ void CodeHighlighter::add_color_region(const String &p_start_key, const String & color_region.color = p_color; color_region.start_key = p_start_key; color_region.end_key = p_end_key; - color_region.line_only = p_line_only || p_end_key == ""; + color_region.line_only = p_line_only || p_end_key.is_empty(); color_regions.insert(at, color_region); clear_highlighting_cache(); } @@ -529,7 +557,7 @@ void CodeHighlighter::set_color_regions(const Dictionary &p_color_regions) { String start_key = key.get_slice(" ", 0); String end_key = key.get_slice_count(" ") > 1 ? key.get_slice(" ", 1) : String(); - add_color_region(start_key, end_key, p_color_regions[key], end_key == ""); + add_color_region(start_key, end_key, p_color_regions[key], end_key.is_empty()); } clear_highlighting_cache(); } diff --git a/scene/resources/syntax_highlighter.h b/scene/resources/syntax_highlighter.h index 0fe39ccff6..143f1679c6 100644 --- a/scene/resources/syntax_highlighter.h +++ b/scene/resources/syntax_highlighter.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/text_file.cpp b/scene/resources/text_file.cpp index 33bb0a83e9..cbfee754e2 100644 --- a/scene/resources/text_file.cpp +++ b/scene/resources/text_file.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -33,7 +33,7 @@ #include "core/io/file_access.h" bool TextFile::has_text() const { - return text != ""; + return !text.is_empty(); } String TextFile::get_text() const { diff --git a/scene/resources/text_file.h b/scene/resources/text_file.h index 005075a218..0c8cf855f0 100644 --- a/scene/resources/text_file.h +++ b/scene/resources/text_file.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/text_line.cpp b/scene/resources/text_line.cpp index 0094518967..f3752053c0 100644 --- a/scene/resources/text_line.cpp +++ b/scene/resources/text_line.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -56,18 +56,18 @@ void TextLine::_bind_methods() { ClassDB::bind_method(D_METHOD("set_bidi_override", "override"), &TextLine::set_bidi_override); ClassDB::bind_method(D_METHOD("add_string", "text", "fonts", "size", "opentype_features", "language"), &TextLine::add_string, DEFVAL(Dictionary()), DEFVAL("")); - ClassDB::bind_method(D_METHOD("add_object", "key", "size", "inline_align", "length"), &TextLine::add_object, DEFVAL(INLINE_ALIGN_CENTER), DEFVAL(1)); - ClassDB::bind_method(D_METHOD("resize_object", "key", "size", "inline_align"), &TextLine::resize_object, DEFVAL(INLINE_ALIGN_CENTER)); + ClassDB::bind_method(D_METHOD("add_object", "key", "size", "inline_align", "length"), &TextLine::add_object, DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(1)); + ClassDB::bind_method(D_METHOD("resize_object", "key", "size", "inline_align"), &TextLine::resize_object, DEFVAL(INLINE_ALIGNMENT_CENTER)); ClassDB::bind_method(D_METHOD("set_width", "width"), &TextLine::set_width); ClassDB::bind_method(D_METHOD("get_width"), &TextLine::get_width); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "width"), "set_width", "get_width"); - ClassDB::bind_method(D_METHOD("set_align", "align"), &TextLine::set_align); - ClassDB::bind_method(D_METHOD("get_align"), &TextLine::get_align); + ClassDB::bind_method(D_METHOD("set_horizontal_alignment", "alignment"), &TextLine::set_horizontal_alignment); + ClassDB::bind_method(D_METHOD("get_horizontal_alignment"), &TextLine::get_horizontal_alignment); - ADD_PROPERTY(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_align", "get_align"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "alignment", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_horizontal_alignment", "get_horizontal_alignment"); ClassDB::bind_method(D_METHOD("tab_align", "tab_stops"), &TextLine::tab_align); @@ -135,14 +135,14 @@ void TextLine::_shape() { break; } - if (align == HALIGN_FILL) { + if (alignment == HORIZONTAL_ALIGNMENT_FILL) { TS->shaped_text_fit_to_width(rid, width, flags); overrun_flags |= TextServer::OVERRUN_JUSTIFICATION_AWARE; TS->shaped_text_overrun_trim_to_width(rid, width, overrun_flags); } else { TS->shaped_text_overrun_trim_to_width(rid, width, overrun_flags); } - } else if (align == HALIGN_FILL) { + } else if (alignment == HORIZONTAL_ALIGNMENT_FILL) { TS->shaped_text_fit_to_width(rid, width, flags); } dirty = false; @@ -209,13 +209,13 @@ bool TextLine::add_string(const String &p_text, const Ref<Font> &p_fonts, int p_ return res; } -bool TextLine::add_object(Variant p_key, const Size2 &p_size, InlineAlign p_inline_align, int p_length) { +bool TextLine::add_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align, int p_length) { bool res = TS->shaped_text_add_object(rid, p_key, p_size, p_inline_align, p_length); dirty = true; return res; } -bool TextLine::resize_object(Variant p_key, const Size2 &p_size, InlineAlign p_inline_align) { +bool TextLine::resize_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align) { const_cast<TextLine *>(this)->_shape(); return TS->shaped_text_resize_object(rid, p_key, p_size, p_inline_align); } @@ -228,19 +228,19 @@ Rect2 TextLine::get_object_rect(Variant p_key) const { return TS->shaped_text_get_object_rect(rid, p_key); } -void TextLine::set_align(HAlign p_align) { - if (align != p_align) { - if (align == HALIGN_FILL || p_align == HALIGN_FILL) { - align = p_align; +void TextLine::set_horizontal_alignment(HorizontalAlignment p_alignment) { + if (alignment != p_alignment) { + if (alignment == HORIZONTAL_ALIGNMENT_FILL || p_alignment == HORIZONTAL_ALIGNMENT_FILL) { + alignment = p_alignment; dirty = true; } else { - align = p_align; + alignment = p_alignment; } } } -HAlign TextLine::get_align() const { - return align; +HorizontalAlignment TextLine::get_horizontal_alignment() const { + return alignment; } void TextLine::tab_align(const Vector<float> &p_tab_stops) { @@ -272,7 +272,7 @@ TextLine::OverrunBehavior TextLine::get_text_overrun_behavior() const { void TextLine::set_width(float p_width) { width = p_width; - if (align == HALIGN_FILL || overrun_behavior != OVERRUN_NO_TRIMMING) { + if (alignment == HORIZONTAL_ALIGNMENT_FILL || overrun_behavior != OVERRUN_NO_TRIMMING) { dirty = true; } } @@ -322,18 +322,18 @@ void TextLine::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_color) co float length = TS->shaped_text_get_width(rid); if (width > 0) { - switch (align) { - case HALIGN_FILL: - case HALIGN_LEFT: + switch (alignment) { + case HORIZONTAL_ALIGNMENT_FILL: + case HORIZONTAL_ALIGNMENT_LEFT: break; - case HALIGN_CENTER: { + case HORIZONTAL_ALIGNMENT_CENTER: { if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) { ofs.x += Math::floor((width - length) / 2.0); } else { ofs.y += Math::floor((width - length) / 2.0); } } break; - case HALIGN_RIGHT: { + case HORIZONTAL_ALIGNMENT_RIGHT: { if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) { ofs.x += width - length; } else { @@ -361,18 +361,18 @@ void TextLine::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outline_si float length = TS->shaped_text_get_width(rid); if (width > 0) { - switch (align) { - case HALIGN_FILL: - case HALIGN_LEFT: + switch (alignment) { + case HORIZONTAL_ALIGNMENT_FILL: + case HORIZONTAL_ALIGNMENT_LEFT: break; - case HALIGN_CENTER: { + case HORIZONTAL_ALIGNMENT_CENTER: { if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) { ofs.x += Math::floor((width - length) / 2.0); } else { ofs.y += Math::floor((width - length) / 2.0); } } break; - case HALIGN_RIGHT: { + case HORIZONTAL_ALIGNMENT_RIGHT: { if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) { ofs.x += width - length; } else { diff --git a/scene/resources/text_line.h b/scene/resources/text_line.h index 43739f27ec..e68049ee45 100644 --- a/scene/resources/text_line.h +++ b/scene/resources/text_line.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -57,7 +57,7 @@ private: float width = -1.0; uint16_t flags = TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA; - HAlign align = HALIGN_LEFT; + HorizontalAlignment alignment = HORIZONTAL_ALIGNMENT_LEFT; OverrunBehavior overrun_behavior = OVERRUN_TRIM_ELLIPSIS; Vector<float> tab_stops; @@ -87,11 +87,11 @@ public: bool get_preserve_control() const; bool add_string(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = ""); - bool add_object(Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER, int p_length = 1); - bool resize_object(Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER); + bool add_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1); + bool resize_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER); - void set_align(HAlign p_align); - HAlign get_align() const; + void set_horizontal_alignment(HorizontalAlignment p_alignment); + HorizontalAlignment get_horizontal_alignment() const; void tab_align(const Vector<float> &p_tab_stops); diff --git a/scene/resources/text_paragraph.cpp b/scene/resources/text_paragraph.cpp index 1b7fc64267..c3bdef7b01 100644 --- a/scene/resources/text_paragraph.cpp +++ b/scene/resources/text_paragraph.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -64,13 +64,13 @@ void TextParagraph::_bind_methods() { ClassDB::bind_method(D_METHOD("clear_dropcap"), &TextParagraph::clear_dropcap); ClassDB::bind_method(D_METHOD("add_string", "text", "fonts", "size", "opentype_features", "language"), &TextParagraph::add_string, DEFVAL(Dictionary()), DEFVAL("")); - ClassDB::bind_method(D_METHOD("add_object", "key", "size", "inline_align", "length"), &TextParagraph::add_object, DEFVAL(INLINE_ALIGN_CENTER), DEFVAL(1)); - ClassDB::bind_method(D_METHOD("resize_object", "key", "size", "inline_align"), &TextParagraph::resize_object, DEFVAL(INLINE_ALIGN_CENTER)); + ClassDB::bind_method(D_METHOD("add_object", "key", "size", "inline_align", "length"), &TextParagraph::add_object, DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(1)); + ClassDB::bind_method(D_METHOD("resize_object", "key", "size", "inline_align"), &TextParagraph::resize_object, DEFVAL(INLINE_ALIGNMENT_CENTER)); - ClassDB::bind_method(D_METHOD("set_align", "align"), &TextParagraph::set_align); - ClassDB::bind_method(D_METHOD("get_align"), &TextParagraph::get_align); + ClassDB::bind_method(D_METHOD("set_alignment", "alignment"), &TextParagraph::set_alignment); + ClassDB::bind_method(D_METHOD("get_alignment"), &TextParagraph::get_alignment); - ADD_PROPERTY(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_align", "get_align"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "alignment", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_alignment", "get_alignment"); ClassDB::bind_method(D_METHOD("tab_align", "tab_stops"), &TextParagraph::tab_align); @@ -223,7 +223,7 @@ void TextParagraph::_shape_lines() { if (lines_hidden) { overrun_flags |= TextServer::OVERRUN_ENFORCE_ELLIPSIS; } - if (align == HALIGN_FILL) { + if (alignment == HORIZONTAL_ALIGNMENT_FILL) { for (int i = 0; i < lines_rid.size(); i++) { if (i < visible_lines - 1 || lines_rid.size() == 1) { TS->shaped_text_fit_to_width(lines_rid[i], width, flags); @@ -239,7 +239,7 @@ void TextParagraph::_shape_lines() { } else { // Autowrap disabled. for (int i = 0; i < lines_rid.size(); i++) { - if (align == HALIGN_FILL) { + if (alignment == HORIZONTAL_ALIGNMENT_FILL) { TS->shaped_text_fit_to_width(lines_rid[i], width, flags); overrun_flags |= TextServer::OVERRUN_JUSTIFICATION_AWARE; TS->shaped_text_overrun_trim_to_width(lines_rid[i], width, overrun_flags); @@ -366,31 +366,31 @@ void TextParagraph::set_bidi_override(const Array &p_override) { lines_dirty = true; } -bool TextParagraph::add_object(Variant p_key, const Size2 &p_size, InlineAlign p_inline_align, int p_length) { +bool TextParagraph::add_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align, int p_length) { bool res = TS->shaped_text_add_object(rid, p_key, p_size, p_inline_align, p_length); lines_dirty = true; return res; } -bool TextParagraph::resize_object(Variant p_key, const Size2 &p_size, InlineAlign p_inline_align) { +bool TextParagraph::resize_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align) { bool res = TS->shaped_text_resize_object(rid, p_key, p_size, p_inline_align); lines_dirty = true; return res; } -void TextParagraph::set_align(HAlign p_align) { - if (align != p_align) { - if (align == HALIGN_FILL || p_align == HALIGN_FILL) { - align = p_align; +void TextParagraph::set_alignment(HorizontalAlignment p_alignment) { + if (alignment != p_alignment) { + if (alignment == HORIZONTAL_ALIGNMENT_FILL || p_alignment == HORIZONTAL_ALIGNMENT_FILL) { + alignment = p_alignment; lines_dirty = true; } else { - align = p_align; + alignment = p_alignment; } } } -HAlign TextParagraph::get_align() const { - return align; +HorizontalAlignment TextParagraph::get_alignment() const { + return alignment; } void TextParagraph::tab_align(const Vector<float> &p_tab_stops) { @@ -561,7 +561,7 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo if (h_offset > 0) { // Draw dropcap. Vector2 dc_off = ofs; - if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_RTL) { + if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_RTL) { if (TS->shaped_text_get_orientation(dropcap_rid) == TextServer::ORIENTATION_HORIZONTAL) { dc_off.x += width - h_offset; } else { @@ -579,7 +579,7 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo ofs.x = p_pos.x; ofs.y += TS->shaped_text_get_ascent(lines_rid[i]) + spacing_top; if (i <= dropcap_lines) { - if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_LTR) { + if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_LTR) { ofs.x -= h_offset; } l_width -= h_offset; @@ -588,7 +588,7 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo ofs.y = p_pos.y; ofs.x += TS->shaped_text_get_ascent(lines_rid[i]) + spacing_top; if (i <= dropcap_lines) { - if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_LTR) { + if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_LTR) { ofs.x -= h_offset; } l_width -= h_offset; @@ -596,9 +596,9 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo } float line_width = TS->shaped_text_get_width(lines_rid[i]); if (width > 0) { - switch (align) { - case HALIGN_FILL: - if (TS->shaped_text_get_direction(lines_rid[i]) == TextServer::DIRECTION_RTL) { + switch (alignment) { + case HORIZONTAL_ALIGNMENT_FILL: + if (TS->shaped_text_get_inferred_direction(lines_rid[i]) == TextServer::DIRECTION_RTL) { if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) { ofs.x += l_width - line_width; } else { @@ -606,16 +606,16 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo } } break; - case HALIGN_LEFT: + case HORIZONTAL_ALIGNMENT_LEFT: break; - case HALIGN_CENTER: { + case HORIZONTAL_ALIGNMENT_CENTER: { if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) { ofs.x += Math::floor((l_width - line_width) / 2.0); } else { ofs.y += Math::floor((l_width - line_width) / 2.0); } } break; - case HALIGN_RIGHT: { + case HORIZONTAL_ALIGNMENT_RIGHT: { if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) { ofs.x += l_width - line_width; } else { @@ -655,7 +655,7 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli if (h_offset > 0) { // Draw dropcap. Vector2 dc_off = ofs; - if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_RTL) { + if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_RTL) { if (TS->shaped_text_get_orientation(dropcap_rid) == TextServer::ORIENTATION_HORIZONTAL) { dc_off.x += width - h_offset; } else { @@ -671,7 +671,7 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli ofs.x = p_pos.x; ofs.y += TS->shaped_text_get_ascent(lines_rid[i]) + spacing_top; if (i <= dropcap_lines) { - if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_LTR) { + if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_LTR) { ofs.x -= h_offset; } l_width -= h_offset; @@ -680,7 +680,7 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli ofs.y = p_pos.y; ofs.x += TS->shaped_text_get_ascent(lines_rid[i]) + spacing_top; if (i <= dropcap_lines) { - if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_LTR) { + if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_LTR) { ofs.x -= h_offset; } l_width -= h_offset; @@ -688,9 +688,9 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli } float length = TS->shaped_text_get_width(lines_rid[i]); if (width > 0) { - switch (align) { - case HALIGN_FILL: - if (TS->shaped_text_get_direction(lines_rid[i]) == TextServer::DIRECTION_RTL) { + switch (alignment) { + case HORIZONTAL_ALIGNMENT_FILL: + if (TS->shaped_text_get_inferred_direction(lines_rid[i]) == TextServer::DIRECTION_RTL) { if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) { ofs.x += l_width - length; } else { @@ -698,16 +698,16 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli } } break; - case HALIGN_LEFT: + case HORIZONTAL_ALIGNMENT_LEFT: break; - case HALIGN_CENTER: { + case HORIZONTAL_ALIGNMENT_CENTER: { if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) { ofs.x += Math::floor((l_width - length) / 2.0); } else { ofs.y += Math::floor((l_width - length) / 2.0); } } break; - case HALIGN_RIGHT: { + case HORIZONTAL_ALIGNMENT_RIGHT: { if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) { ofs.x += l_width - length; } else { @@ -772,7 +772,7 @@ void TextParagraph::draw_dropcap(RID p_canvas, const Vector2 &p_pos, const Color if (h_offset > 0) { // Draw dropcap. - if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_RTL) { + if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_RTL) { if (TS->shaped_text_get_orientation(dropcap_rid) == TextServer::ORIENTATION_HORIZONTAL) { ofs.x += width - h_offset; } else { @@ -794,7 +794,7 @@ void TextParagraph::draw_dropcap_outline(RID p_canvas, const Vector2 &p_pos, int if (h_offset > 0) { // Draw dropcap. - if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_RTL) { + if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_RTL) { if (TS->shaped_text_get_orientation(dropcap_rid) == TextServer::ORIENTATION_HORIZONTAL) { ofs.x += width - h_offset; } else { diff --git a/scene/resources/text_paragraph.h b/scene/resources/text_paragraph.h index 4c4af43d14..773cc1a858 100644 --- a/scene/resources/text_paragraph.h +++ b/scene/resources/text_paragraph.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -66,7 +66,7 @@ private: uint16_t flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA; OverrunBehavior overrun_behavior = OVERRUN_NO_TRIMMING; - HAlign align = HALIGN_LEFT; + HorizontalAlignment alignment = HORIZONTAL_ALIGNMENT_LEFT; Vector<float> tab_stops; @@ -103,11 +103,11 @@ public: void clear_dropcap(); bool add_string(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = ""); - bool add_object(Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER, int p_length = 1); - bool resize_object(Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER); + bool add_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1); + bool resize_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER); - void set_align(HAlign p_align); - HAlign get_align() const; + void set_alignment(HorizontalAlignment p_alignment); + HorizontalAlignment get_alignment() const; void tab_align(const Vector<float> &p_tab_stops); diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 311bd9524b..331674d248 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -553,7 +553,7 @@ Error StreamTexture2D::load(const String &p_path) { path_to_file = p_path; format = image->get_format(); - if (get_path() == String()) { + if (get_path().is_empty()) { //temporarily set path if no path set for resource, helps find errors RenderingServer::get_singleton()->texture_set_path(texture, p_path); } @@ -927,7 +927,7 @@ Error StreamTexture3D::load(const String &p_path) { path_to_file = p_path; - if (get_path() == String()) { + if (get_path().is_empty()) { //temporarily set path if no path set for resource, helps find errors RenderingServer::get_singleton()->texture_set_path(texture, p_path); } @@ -1156,7 +1156,7 @@ void AtlasTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_m rc.size.height = atlas->get_height(); } - RS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(p_pos + margin.position, rc.size), atlas->get_rid(), rc, p_modulate, p_transpose, filter_clip); + atlas->draw_rect_region(p_canvas_item, Rect2(p_pos + margin.position, rc.size), rc, p_modulate, p_transpose, filter_clip); } void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const { @@ -1177,7 +1177,7 @@ void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile Vector2 scale = p_rect.size / (region.size + margin.size); Rect2 dr(p_rect.position + margin.position * scale, rc.size * scale); - RS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), rc, p_modulate, p_transpose, filter_clip); + atlas->draw_rect_region(p_canvas_item, dr, rc, p_modulate, p_transpose, filter_clip); } void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, bool p_clip_uv) const { @@ -1190,7 +1190,7 @@ void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons Rect2 src_c; get_rect_region(p_rect, p_src_rect, dr, src_c); - RS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), src_c, p_modulate, p_transpose, filter_clip); + atlas->draw_rect_region(p_canvas_item, dr, src_c, p_modulate, p_transpose, filter_clip); } bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const { @@ -2680,7 +2680,7 @@ Error StreamTextureLayered::load(const String &p_path) { path_to_file = p_path; - if (get_path() == String()) { + if (get_path().is_empty()) { //temporarily set path if no path set for resource, helps find errors RenderingServer::get_singleton()->texture_set_path(texture, p_path); } diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 5b69711de6..c3f29ad417 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index 99977a20f2..8da287042e 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -36,11 +36,11 @@ Ref<Theme> Theme::default_theme; Ref<Theme> Theme::project_default_theme; // Universal default values, final fallback for every theme. -float Theme::default_base_scale = 1.0; -Ref<Texture2D> Theme::default_icon; -Ref<StyleBox> Theme::default_style; -Ref<Font> Theme::default_font; -int Theme::default_font_size = 16; +float Theme::fallback_base_scale = 1.0; +Ref<Texture2D> Theme::fallback_icon; +Ref<StyleBox> Theme::fallback_style; +Ref<Font> Theme::fallback_font; +int Theme::fallback_font_size = 16; // Dynamic properties. bool Theme::_set(const StringName &p_name, const Variant &p_value) { @@ -220,87 +220,107 @@ void Theme::set_project_default(const Ref<Theme> &p_project_default) { } // Universal fallback values for theme item types. -void Theme::set_default_base_scale(float p_base_scale) { - default_base_scale = p_base_scale; +void Theme::set_fallback_base_scale(float p_base_scale) { + fallback_base_scale = p_base_scale; } -void Theme::set_default_icon(const Ref<Texture2D> &p_icon) { - default_icon = p_icon; +void Theme::set_fallback_icon(const Ref<Texture2D> &p_icon) { + fallback_icon = p_icon; } -void Theme::set_default_style(const Ref<StyleBox> &p_style) { - default_style = p_style; +void Theme::set_fallback_style(const Ref<StyleBox> &p_style) { + fallback_style = p_style; } -void Theme::set_default_font(const Ref<Font> &p_font) { - default_font = p_font; +void Theme::set_fallback_font(const Ref<Font> &p_font) { + fallback_font = p_font; } -void Theme::set_default_font_size(int p_font_size) { - default_font_size = p_font_size; +void Theme::set_fallback_font_size(int p_font_size) { + fallback_font_size = p_font_size; +} + +float Theme::get_fallback_base_scale() { + return fallback_base_scale; +} + +Ref<Texture2D> Theme::get_fallback_icon() { + return fallback_icon; +} + +Ref<StyleBox> Theme::get_fallback_style() { + return fallback_style; +} + +Ref<Font> Theme::get_fallback_font() { + return fallback_font; +} + +int Theme::get_fallback_font_size() { + return fallback_font_size; } // Fallback values for theme item types, configurable per theme. -void Theme::set_default_theme_base_scale(float p_base_scale) { - if (default_theme_base_scale == p_base_scale) { +void Theme::set_default_base_scale(float p_base_scale) { + if (default_base_scale == p_base_scale) { return; } - default_theme_base_scale = p_base_scale; + default_base_scale = p_base_scale; _emit_theme_changed(); } -float Theme::get_default_theme_base_scale() const { - return default_theme_base_scale; +float Theme::get_default_base_scale() const { + return default_base_scale; } -bool Theme::has_default_theme_base_scale() const { - return default_theme_base_scale > 0.0; +bool Theme::has_default_base_scale() const { + return default_base_scale > 0.0; } -void Theme::set_default_theme_font(const Ref<Font> &p_default_font) { - if (default_theme_font == p_default_font) { +void Theme::set_default_font(const Ref<Font> &p_default_font) { + if (default_font == p_default_font) { return; } - if (default_theme_font.is_valid()) { - default_theme_font->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); + if (default_font.is_valid()) { + default_font->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); } - default_theme_font = p_default_font; + default_font = p_default_font; - if (default_theme_font.is_valid()) { - default_theme_font->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(false), CONNECT_REFERENCE_COUNTED); + if (default_font.is_valid()) { + default_font->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(false), CONNECT_REFERENCE_COUNTED); } _emit_theme_changed(); } -Ref<Font> Theme::get_default_theme_font() const { - return default_theme_font; +Ref<Font> Theme::get_default_font() const { + return default_font; } -bool Theme::has_default_theme_font() const { - return default_theme_font.is_valid(); +bool Theme::has_default_font() const { + return default_font.is_valid(); } -void Theme::set_default_theme_font_size(int p_font_size) { - if (default_theme_font_size == p_font_size) { +void Theme::set_default_font_size(int p_font_size) { + if (default_font_size == p_font_size) { return; } - default_theme_font_size = p_font_size; + default_font_size = p_font_size; _emit_theme_changed(); } -int Theme::get_default_theme_font_size() const { - return default_theme_font_size; +int Theme::get_default_font_size() const { + return default_font_size; } -bool Theme::has_default_theme_font_size() const { - return default_theme_font_size > 0; +bool Theme::has_default_font_size() const { + return default_font_size > 0; } // Icons. @@ -324,7 +344,7 @@ Ref<Texture2D> Theme::get_icon(const StringName &p_name, const StringName &p_the if (icon_map.has(p_theme_type) && icon_map[p_theme_type].has(p_name) && icon_map[p_theme_type][p_name].is_valid()) { return icon_map[p_theme_type][p_name]; } else { - return default_icon; + return fallback_icon; } } @@ -411,7 +431,7 @@ Ref<StyleBox> Theme::get_stylebox(const StringName &p_name, const StringName &p_ if (style_map.has(p_theme_type) && style_map[p_theme_type].has(p_name) && style_map[p_theme_type][p_name].is_valid()) { return style_map[p_theme_type][p_name]; } else { - return default_style; + return fallback_style; } } @@ -497,15 +517,15 @@ void Theme::set_font(const StringName &p_name, const StringName &p_theme_type, c Ref<Font> Theme::get_font(const StringName &p_name, const StringName &p_theme_type) const { if (font_map.has(p_theme_type) && font_map[p_theme_type].has(p_name) && font_map[p_theme_type][p_name].is_valid()) { return font_map[p_theme_type][p_name]; - } else if (has_default_theme_font()) { - return default_theme_font; - } else { + } else if (has_default_font()) { return default_font; + } else { + return fallback_font; } } bool Theme::has_font(const StringName &p_name, const StringName &p_theme_type) const { - return ((font_map.has(p_theme_type) && font_map[p_theme_type].has(p_name) && font_map[p_theme_type][p_name].is_valid()) || has_default_theme_font()); + return ((font_map.has(p_theme_type) && font_map[p_theme_type].has(p_name) && font_map[p_theme_type][p_name].is_valid()) || has_default_font()); } bool Theme::has_font_nocheck(const StringName &p_name, const StringName &p_theme_type) const { @@ -577,15 +597,15 @@ void Theme::set_font_size(const StringName &p_name, const StringName &p_theme_ty int Theme::get_font_size(const StringName &p_name, const StringName &p_theme_type) const { if (font_size_map.has(p_theme_type) && font_size_map[p_theme_type].has(p_name) && (font_size_map[p_theme_type][p_name] > 0)) { return font_size_map[p_theme_type][p_name]; - } else if (has_default_theme_font_size()) { - return default_theme_font_size; - } else { + } else if (has_default_font_size()) { return default_font_size; + } else { + return fallback_font_size; } } bool Theme::has_font_size(const StringName &p_name, const StringName &p_theme_type) const { - return ((font_size_map.has(p_theme_type) && font_size_map[p_theme_type].has(p_name) && (font_size_map[p_theme_type][p_name] > 0)) || has_default_theme_font_size()); + return ((font_size_map.has(p_theme_type) && font_size_map[p_theme_type].has(p_name) && (font_size_map[p_theme_type][p_name] > 0)) || has_default_font_size()); } bool Theme::has_font_size_nocheck(const StringName &p_name, const StringName &p_theme_type) const { @@ -1622,17 +1642,17 @@ void Theme::_bind_methods() { ClassDB::bind_method(D_METHOD("get_constant_list", "theme_type"), &Theme::_get_constant_list); ClassDB::bind_method(D_METHOD("get_constant_type_list"), &Theme::_get_constant_type_list); - ClassDB::bind_method(D_METHOD("set_default_base_scale", "font_size"), &Theme::set_default_theme_base_scale); - ClassDB::bind_method(D_METHOD("get_default_base_scale"), &Theme::get_default_theme_base_scale); - ClassDB::bind_method(D_METHOD("has_default_base_scale"), &Theme::has_default_theme_base_scale); + ClassDB::bind_method(D_METHOD("set_default_base_scale", "base_scale"), &Theme::set_default_base_scale); + ClassDB::bind_method(D_METHOD("get_default_base_scale"), &Theme::get_default_base_scale); + ClassDB::bind_method(D_METHOD("has_default_base_scale"), &Theme::has_default_base_scale); - ClassDB::bind_method(D_METHOD("set_default_font", "font"), &Theme::set_default_theme_font); - ClassDB::bind_method(D_METHOD("get_default_font"), &Theme::get_default_theme_font); - ClassDB::bind_method(D_METHOD("has_default_font"), &Theme::has_default_theme_font); + ClassDB::bind_method(D_METHOD("set_default_font", "font"), &Theme::set_default_font); + ClassDB::bind_method(D_METHOD("get_default_font"), &Theme::get_default_font); + ClassDB::bind_method(D_METHOD("has_default_font"), &Theme::has_default_font); - ClassDB::bind_method(D_METHOD("set_default_font_size", "font_size"), &Theme::set_default_theme_font_size); - ClassDB::bind_method(D_METHOD("get_default_font_size"), &Theme::get_default_theme_font_size); - ClassDB::bind_method(D_METHOD("has_default_font_size"), &Theme::has_default_theme_font_size); + ClassDB::bind_method(D_METHOD("set_default_font_size", "font_size"), &Theme::set_default_font_size); + ClassDB::bind_method(D_METHOD("get_default_font_size"), &Theme::get_default_font_size); + ClassDB::bind_method(D_METHOD("has_default_font_size"), &Theme::has_default_font_size); ClassDB::bind_method(D_METHOD("set_theme_item", "data_type", "name", "theme_type", "value"), &Theme::set_theme_item); ClassDB::bind_method(D_METHOD("get_theme_item", "data_type", "name", "theme_type"), &Theme::get_theme_item); diff --git a/scene/resources/theme.h b/scene/resources/theme.h index d170d53ae3..822743a1fe 100644 --- a/scene/resources/theme.h +++ b/scene/resources/theme.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -101,16 +101,16 @@ protected: static Ref<Theme> project_default_theme; // Universal default values, final fallback for every theme. - static float default_base_scale; - static Ref<Texture2D> default_icon; - static Ref<StyleBox> default_style; - static Ref<Font> default_font; - static int default_font_size; + static float fallback_base_scale; + static Ref<Texture2D> fallback_icon; + static Ref<StyleBox> fallback_style; + static Ref<Font> fallback_font; + static int fallback_font_size; // Default values configurable for each individual theme. - float default_theme_base_scale = 0.0; - Ref<Font> default_theme_font; - int default_theme_font_size = -1; + float default_base_scale = 0.0; + Ref<Font> default_font; + int default_font_size = -1; static void _bind_methods(); @@ -126,23 +126,29 @@ public: static Ref<Theme> get_project_default(); static void set_project_default(const Ref<Theme> &p_project_default); - static void set_default_base_scale(float p_base_scale); - static void set_default_icon(const Ref<Texture2D> &p_icon); - static void set_default_style(const Ref<StyleBox> &p_style); - static void set_default_font(const Ref<Font> &p_font); - static void set_default_font_size(int p_font_size); - - void set_default_theme_base_scale(float p_base_scale); - float get_default_theme_base_scale() const; - bool has_default_theme_base_scale() const; - - void set_default_theme_font(const Ref<Font> &p_default_font); - Ref<Font> get_default_theme_font() const; - bool has_default_theme_font() const; - - void set_default_theme_font_size(int p_font_size); - int get_default_theme_font_size() const; - bool has_default_theme_font_size() const; + static void set_fallback_base_scale(float p_base_scale); + static void set_fallback_icon(const Ref<Texture2D> &p_icon); + static void set_fallback_style(const Ref<StyleBox> &p_style); + static void set_fallback_font(const Ref<Font> &p_font); + static void set_fallback_font_size(int p_font_size); + + static float get_fallback_base_scale(); + static Ref<Texture2D> get_fallback_icon(); + static Ref<StyleBox> get_fallback_style(); + static Ref<Font> get_fallback_font(); + static int get_fallback_font_size(); + + void set_default_base_scale(float p_base_scale); + float get_default_base_scale() const; + bool has_default_base_scale() const; + + void set_default_font(const Ref<Font> &p_default_font); + Ref<Font> get_default_font() const; + bool has_default_font() const; + + void set_default_font_size(int p_font_size); + int get_default_font_size() const; + bool has_default_font_size() const; void set_icon(const StringName &p_name, const StringName &p_theme_type, const Ref<Texture2D> &p_icon); Ref<Texture2D> get_icon(const StringName &p_name, const StringName &p_theme_type) const; diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index 34fe7c0b87..ddb9cc7440 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -1765,11 +1765,14 @@ Vector<Point2> TileSet::_get_square_corner_or_side_terrain_bit_polygon(Vector2i break; } bit_rect.position *= Vector2(p_size) / 6.0; - Vector<Vector2> polygon; - polygon.push_back(bit_rect.position); - polygon.push_back(Vector2(bit_rect.get_end().x, bit_rect.position.y)); - polygon.push_back(bit_rect.get_end()); - polygon.push_back(Vector2(bit_rect.position.x, bit_rect.get_end().y)); + + Vector<Vector2> polygon = { + bit_rect.position, + Vector2(bit_rect.get_end().x, bit_rect.position.y), + bit_rect.get_end(), + Vector2(bit_rect.position.x, bit_rect.get_end().y) + }; + return polygon; } @@ -1984,25 +1987,26 @@ Vector<Point2> TileSet::_get_isometric_side_terrain_bit_polygon(Vector2i p_size, } Vector<Point2> TileSet::_get_half_offset_corner_or_side_terrain_bit_polygon(Vector2i p_size, TileSet::CellNeighbor p_bit, float p_overlap, TileSet::TileOffsetAxis p_offset_axis) { - Vector<Vector2> point_list; - point_list.push_back(Vector2(3, (3.0 * (1.0 - p_overlap * 2.0)) / 2.0)); - point_list.push_back(Vector2(3, 3.0 * (1.0 - p_overlap * 2.0))); - point_list.push_back(Vector2(2, 3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0))); - point_list.push_back(Vector2(1, 3.0 - p_overlap * 2.0)); - point_list.push_back(Vector2(0, 3)); - point_list.push_back(Vector2(-1, 3.0 - p_overlap * 2.0)); - point_list.push_back(Vector2(-2, 3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0))); - point_list.push_back(Vector2(-3, 3.0 * (1.0 - p_overlap * 2.0))); - point_list.push_back(Vector2(-3, (3.0 * (1.0 - p_overlap * 2.0)) / 2.0)); - point_list.push_back(Vector2(-3, -(3.0 * (1.0 - p_overlap * 2.0)) / 2.0)); - point_list.push_back(Vector2(-3, -3.0 * (1.0 - p_overlap * 2.0))); - point_list.push_back(Vector2(-2, -3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0))); - point_list.push_back(Vector2(-1, -(3.0 - p_overlap * 2.0))); - point_list.push_back(Vector2(0, -3)); - point_list.push_back(Vector2(1, -(3.0 - p_overlap * 2.0))); - point_list.push_back(Vector2(2, -3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0))); - point_list.push_back(Vector2(3, -3.0 * (1.0 - p_overlap * 2.0))); - point_list.push_back(Vector2(3, -(3.0 * (1.0 - p_overlap * 2.0)) / 2.0)); + Vector<Vector2> point_list = { + Vector2(3, (3.0 * (1.0 - p_overlap * 2.0)) / 2.0), + Vector2(3, 3.0 * (1.0 - p_overlap * 2.0)), + Vector2(2, 3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0)), + Vector2(1, 3.0 - p_overlap * 2.0), + Vector2(0, 3), + Vector2(-1, 3.0 - p_overlap * 2.0), + Vector2(-2, 3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0)), + Vector2(-3, 3.0 * (1.0 - p_overlap * 2.0)), + Vector2(-3, (3.0 * (1.0 - p_overlap * 2.0)) / 2.0), + Vector2(-3, -(3.0 * (1.0 - p_overlap * 2.0)) / 2.0), + Vector2(-3, -3.0 * (1.0 - p_overlap * 2.0)), + Vector2(-2, -3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0)), + Vector2(-1, -(3.0 - p_overlap * 2.0)), + Vector2(0, -3), + Vector2(1, -(3.0 - p_overlap * 2.0)), + Vector2(2, -3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0)), + Vector2(3, -3.0 * (1.0 - p_overlap * 2.0)), + Vector2(3, -(3.0 * (1.0 - p_overlap * 2.0)) / 2.0) + }; Vector2 unit = Vector2(p_size) / 6.0; for (int i = 0; i < point_list.size(); i++) { @@ -2144,19 +2148,20 @@ Vector<Point2> TileSet::_get_half_offset_corner_or_side_terrain_bit_polygon(Vect } Vector<Point2> TileSet::_get_half_offset_corner_terrain_bit_polygon(Vector2i p_size, TileSet::CellNeighbor p_bit, float p_overlap, TileSet::TileOffsetAxis p_offset_axis) { - Vector<Vector2> point_list; - point_list.push_back(Vector2(3, 0)); - point_list.push_back(Vector2(3, 3.0 * (1.0 - p_overlap * 2.0))); - point_list.push_back(Vector2(1.5, (3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0)); - point_list.push_back(Vector2(0, 3)); - point_list.push_back(Vector2(-1.5, (3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0)); - point_list.push_back(Vector2(-3, 3.0 * (1.0 - p_overlap * 2.0))); - point_list.push_back(Vector2(-3, 0)); - point_list.push_back(Vector2(-3, -3.0 * (1.0 - p_overlap * 2.0))); - point_list.push_back(Vector2(-1.5, -(3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0)); - point_list.push_back(Vector2(0, -3)); - point_list.push_back(Vector2(1.5, -(3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0)); - point_list.push_back(Vector2(3, -3.0 * (1.0 - p_overlap * 2.0))); + Vector<Vector2> point_list = { + Vector2(3, 0), + Vector2(3, 3.0 * (1.0 - p_overlap * 2.0)), + Vector2(1.5, (3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0), + Vector2(0, 3), + Vector2(-1.5, (3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0), + Vector2(-3, 3.0 * (1.0 - p_overlap * 2.0)), + Vector2(-3, 0), + Vector2(-3, -3.0 * (1.0 - p_overlap * 2.0)), + Vector2(-1.5, -(3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0), + Vector2(0, -3), + Vector2(1.5, -(3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0), + Vector2(3, -3.0 * (1.0 - p_overlap * 2.0)) + }; Vector2 unit = Vector2(p_size) / 6.0; for (int i = 0; i < point_list.size(); i++) { @@ -2250,13 +2255,14 @@ Vector<Point2> TileSet::_get_half_offset_corner_terrain_bit_polygon(Vector2i p_s } Vector<Point2> TileSet::_get_half_offset_side_terrain_bit_polygon(Vector2i p_size, TileSet::CellNeighbor p_bit, float p_overlap, TileSet::TileOffsetAxis p_offset_axis) { - Vector<Vector2> point_list; - point_list.push_back(Vector2(3, 3.0 * (1.0 - p_overlap * 2.0))); - point_list.push_back(Vector2(0, 3)); - point_list.push_back(Vector2(-3, 3.0 * (1.0 - p_overlap * 2.0))); - point_list.push_back(Vector2(-3, -3.0 * (1.0 - p_overlap * 2.0))); - point_list.push_back(Vector2(0, -3)); - point_list.push_back(Vector2(3, -3.0 * (1.0 - p_overlap * 2.0))); + Vector<Vector2> point_list = { + Vector2(3, 3.0 * (1.0 - p_overlap * 2.0)), + Vector2(0, 3), + Vector2(-3, 3.0 * (1.0 - p_overlap * 2.0)), + Vector2(-3, -3.0 * (1.0 - p_overlap * 2.0)), + Vector2(0, -3), + Vector2(3, -3.0 * (1.0 - p_overlap * 2.0)) + }; Vector2 unit = Vector2(p_size) / 6.0; for (int i = 0; i < point_list.size(); i++) { diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h index d2238c26d2..2673ca1cb6 100644 --- a/scene/resources/tile_set.h +++ b/scene/resources/tile_set.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/video_stream.h b/scene/resources/video_stream.h index f960f85521..3e154d539b 100644 --- a/scene/resources/video_stream.h +++ b/scene/resources/video_stream.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index 41e78e0bc8..ece1ba1972 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -349,11 +349,11 @@ String VisualShaderNodeCustom::get_output_port_name(int p_port) const { String VisualShaderNodeCustom::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 { ERR_FAIL_COND_V(!GDVIRTUAL_IS_OVERRIDDEN(_get_code), ""); - Vector<String> input_vars; + TypedArray<String> input_vars; for (int i = 0; i < get_input_port_count(); i++) { input_vars.push_back(p_input_vars[i]); } - Array output_vars; + TypedArray<String> output_vars; for (int i = 0; i < get_output_port_count(); i++) { output_vars.push_back(p_output_vars[i]); } @@ -979,7 +979,7 @@ String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port String VisualShader::validate_port_name(const String &p_port_name, VisualShaderNode *p_node, int p_port_id, bool p_output) const { String name = p_port_name; - if (name == String()) { + if (name.is_empty()) { return String(); } @@ -987,7 +987,7 @@ String VisualShader::validate_port_name(const String &p_port_name, VisualShaderN name = name.substr(1, name.length() - 1); } - if (name != String()) { + if (!name.is_empty()) { String valid_name; for (int i = 0; i < name.length(); i++) { @@ -1031,7 +1031,7 @@ String VisualShader::validate_uniform_name(const String &p_name, const Ref<Visua while (name.length() && !IS_INITIAL_CHAR(name[0])) { name = name.substr(1, name.length() - 1); } - if (name != String()) { + if (!name.is_empty()) { String valid_name; for (int i = 0; i < name.length(); i++) { @@ -1045,7 +1045,7 @@ String VisualShader::validate_uniform_name(const String &p_name, const Ref<Visua name = valid_name; } - if (name == String()) { + if (name.is_empty()) { name = p_uniform->get_caption(); } @@ -1075,7 +1075,7 @@ String VisualShader::validate_uniform_name(const String &p_name, const Ref<Visua while (name.length() && name[name.length() - 1] >= '0' && name[name.length() - 1] <= '9') { name = name.substr(0, name.length() - 1); } - ERR_FAIL_COND_V(name == String(), String()); + ERR_FAIL_COND_V(name.is_empty(), String()); name += itos(attempt); } else { break; @@ -1085,16 +1085,6 @@ String VisualShader::validate_uniform_name(const String &p_name, const Ref<Visua return name; } -VisualShader::RenderModeEnums VisualShader::render_mode_enums[] = { - { Shader::MODE_SPATIAL, "blend" }, - { Shader::MODE_SPATIAL, "depth_draw" }, - { Shader::MODE_SPATIAL, "cull" }, - { Shader::MODE_SPATIAL, "diffuse" }, - { Shader::MODE_SPATIAL, "specular" }, - { Shader::MODE_CANVAS_ITEM, "blend" }, - { Shader::MODE_CANVAS_ITEM, nullptr } -}; - static const char *type_string[VisualShader::TYPE_MAX] = { "vertex", "fragment", @@ -1261,27 +1251,25 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const { Map<String, String> blend_mode_enums; Set<String> toggles; - for (int i = 0; i < ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader_mode)).size(); i++) { - String mode = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader_mode))[i]; - int idx = 0; - bool in_enum = false; - while (render_mode_enums[idx].string) { - if (mode.begins_with(render_mode_enums[idx].string)) { - String begin = render_mode_enums[idx].string; - String option = mode.replace_first(begin + "_", ""); + const Vector<ShaderLanguage::ModeInfo> &rmodes = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader_mode)); + + for (int i = 0; i < rmodes.size(); i++) { + const ShaderLanguage::ModeInfo &info = rmodes[i]; + + if (!info.options.is_empty()) { + const String begin = String(info.name); + + for (int j = 0; j < info.options.size(); j++) { + const String option = String(info.options[j]); + if (!blend_mode_enums.has(begin)) { blend_mode_enums[begin] = option; } else { blend_mode_enums[begin] += "," + option; } - in_enum = true; - break; } - idx++; - } - - if (!in_enum) { - toggles.insert(mode); + } else { + toggles.insert(String(info.name)); } } @@ -1568,7 +1556,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui } node_code += vsnode->generate_code(get_mode(), type, node, inputs, outputs, for_preview); - if (node_code != String()) { + if (!node_code.is_empty()) { code += node_name; code += node_code; code += "\n"; @@ -1653,44 +1641,36 @@ void VisualShader::_update_shader() const { String render_mode; { - //fill render mode enums - int idx = 0; - while (render_mode_enums[idx].string) { - if (shader_mode == render_mode_enums[idx].mode) { - if (modes.has(render_mode_enums[idx].string)) { - int which = modes[render_mode_enums[idx].string]; - int count = 0; - for (int i = 0; i < ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader_mode)).size(); i++) { - String mode = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader_mode))[i]; - if (mode.begins_with(render_mode_enums[idx].string)) { - if (count == which) { - if (render_mode != String()) { - render_mode += ", "; - } - render_mode += mode; - break; - } - count++; - } + const Vector<ShaderLanguage::ModeInfo> &rmodes = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader_mode)); + Vector<String> flag_names; + + // Add enum modes first. + for (int i = 0; i < rmodes.size(); i++) { + const ShaderLanguage::ModeInfo &info = rmodes[i]; + const String temp = String(info.name); + + if (!info.options.is_empty()) { + if (modes.has(temp) && modes[temp] < info.options.size()) { + if (!render_mode.is_empty()) { + render_mode += ", "; } + render_mode += temp + "_" + info.options[modes[temp]]; } + } else if (flags.has(temp)) { + flag_names.push_back(temp); } - idx++; } - //fill render mode flags - for (int i = 0; i < ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader_mode)).size(); i++) { - String mode = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader_mode))[i]; - if (flags.has(mode)) { - if (render_mode != String()) { - render_mode += ", "; - } - render_mode += mode; + // Add flags afterward. + for (int i = 0; i < flag_names.size(); i++) { + if (!render_mode.is_empty()) { + render_mode += ", "; } + render_mode += flag_names[i]; } } - if (render_mode != String()) { + if (!render_mode.is_empty()) { global_code += "render_mode " + render_mode + ";\n\n"; } @@ -2035,7 +2015,7 @@ void VisualShader::_bind_methods() { ClassDB::bind_method(D_METHOD("_update_shader"), &VisualShader::_update_shader); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "graph_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_graph_offset", "get_graph_offset"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "engine_version", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_engine_version", "get_engine_version"); + ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "engine_version", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_engine_version", "get_engine_version"); ADD_PROPERTY_DEFAULT("code", ""); // Inherited from Shader, prevents showing default code as override in docs. @@ -2468,7 +2448,7 @@ String VisualShaderNodeInput::generate_code(Shader::Mode p_mode, VisualShader::T idx++; } - if (code == String()) { + if (code.is_empty()) { switch (get_output_port_type(0)) { case PORT_TYPE_SCALAR: { code = " " + p_output_vars[0] + " = 0.0;\n"; @@ -2502,7 +2482,7 @@ String VisualShaderNodeInput::generate_code(Shader::Mode p_mode, VisualShader::T idx++; } - if (code == String()) { + if (code.is_empty()) { code = " " + p_output_vars[0] + " = 0.0;\n"; //default (none found) is scalar } @@ -2605,7 +2585,7 @@ void VisualShaderNodeInput::_validate_property(PropertyInfo &property) const { while (ports[idx].mode != Shader::MODE_MAX) { if (ports[idx].mode == shader_mode && ports[idx].shader_type == shader_type) { - if (port_list != String()) { + if (!port_list.is_empty()) { port_list += ","; } port_list += ports[idx].name; @@ -2613,7 +2593,7 @@ void VisualShaderNodeInput::_validate_property(PropertyInfo &property) const { idx++; } - if (port_list == "") { + if (port_list.is_empty()) { port_list = TTR("None"); } property.hint_string = port_list; @@ -3063,7 +3043,7 @@ String VisualShaderNodeOutput::generate_code(Shader::Mode p_mode, VisualShader:: String code; while (ports[idx].mode != Shader::MODE_MAX) { if (ports[idx].mode == shader_mode && ports[idx].shader_type == shader_type) { - if (p_input_vars[count] != String()) { + if (!p_input_vars[count].is_empty()) { String s = ports[idx].string; if (s.find(":") != -1) { code += " " + s.get_slicec(':', 0) + " = " + p_input_vars[count] + "." + s.get_slicec(':', 1) + ";\n"; diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index 5bb9d45f39..066c18e3bc 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -102,8 +102,6 @@ private: HashMap<String, int> modes; Set<StringName> flags; - static RenderModeEnums render_mode_enums[]; - mutable SafeFlag dirty; void _queue_update(); @@ -328,7 +326,7 @@ protected: GDVIRTUAL0RC(int, _get_output_port_count) GDVIRTUAL1RC(int, _get_output_port_type, int) GDVIRTUAL1RC(String, _get_output_port_name, int) - GDVIRTUAL4RC(String, _get_code, Vector<String>, TypedArray<String>, Shader::Mode, VisualShader::Type) + GDVIRTUAL4RC(String, _get_code, TypedArray<String>, TypedArray<String>, Shader::Mode, VisualShader::Type) GDVIRTUAL1RC(String, _get_global_code, Shader::Mode) GDVIRTUAL0RC(bool, _is_highend) diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index e6870971d4..b61e3f5d14 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -535,15 +535,15 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (source == SOURCE_TEXTURE) { String id = make_unique_id(p_type, p_id, "tex"); String code; - if (p_input_vars[0] == String()) { // Use UV by default. + if (p_input_vars[0].is_empty()) { // Use UV by default. - if (p_input_vars[1] == String()) { + if (p_input_vars[1].is_empty()) { code += " vec4 " + id + "_read = texture(" + id + ", " + default_uv + ");\n"; } else { code += " vec4 " + id + "_read = textureLod(" + id + ", " + default_uv + ", " + p_input_vars[1] + ");\n"; } - } else if (p_input_vars[1] == String()) { + } else if (p_input_vars[1].is_empty()) { //no lod code += " vec4 " + id + "_read = texture(" + id + ", " + p_input_vars[0] + ".xy);\n"; } else { @@ -560,18 +560,18 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: String code; code += " {\n"; - if (id == String()) { + if (id.is_empty()) { code += " vec4 " + id + "_tex_read = vec4(0.0);\n"; } else { - if (p_input_vars[0] == String()) { // Use UV by default. + if (p_input_vars[0].is_empty()) { // Use UV by default. - if (p_input_vars[1] == String()) { + if (p_input_vars[1].is_empty()) { code += " vec4 " + id + "_tex_read = texture(" + id + ", " + default_uv + ");\n"; } else { code += " vec4 " + id + "_tex_read = textureLod(" + id + ", " + default_uv + ", " + p_input_vars[1] + ");\n"; } - } else if (p_input_vars[1] == String()) { + } else if (p_input_vars[1].is_empty()) { //no lod code += " vec4 " + id + "_tex_read = texture(" + id + ", " + p_input_vars[0] + ".xy);\n"; } else { @@ -587,15 +587,15 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (source == SOURCE_SCREEN && (p_mode == Shader::MODE_SPATIAL || p_mode == Shader::MODE_CANVAS_ITEM) && p_type == VisualShader::TYPE_FRAGMENT) { String code = " {\n"; - if (p_input_vars[0] == String() || p_for_preview) { // Use UV by default. + if (p_input_vars[0].is_empty() || p_for_preview) { // Use UV by default. - if (p_input_vars[1] == String()) { + if (p_input_vars[1].is_empty()) { code += " vec4 _tex_read = textureLod(SCREEN_TEXTURE, " + default_uv + ", 0.0 );\n"; } else { code += " vec4 _tex_read = textureLod(SCREEN_TEXTURE, " + default_uv + ", " + p_input_vars[1] + ");\n"; } - } else if (p_input_vars[1] == String()) { + } else if (p_input_vars[1].is_empty()) { //no lod code += " vec4 _tex_read = textureLod(SCREEN_TEXTURE, " + p_input_vars[0] + ".xy, 0.0);\n"; } else { @@ -610,15 +610,15 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (source == SOURCE_2D_TEXTURE && p_mode == Shader::MODE_CANVAS_ITEM && p_type == VisualShader::TYPE_FRAGMENT) { String code = " {\n"; - if (p_input_vars[0] == String()) { // Use UV by default. + if (p_input_vars[0].is_empty()) { // Use UV by default. - if (p_input_vars[1] == String()) { + if (p_input_vars[1].is_empty()) { code += " vec4 _tex_read = texture(TEXTURE, " + default_uv + ");\n"; } else { code += " vec4 _tex_read = textureLod(TEXTURE, " + default_uv + ", " + p_input_vars[1] + ");\n"; } - } else if (p_input_vars[1] == String()) { + } else if (p_input_vars[1].is_empty()) { //no lod code += " vec4 _tex_read = texture(TEXTURE, " + p_input_vars[0] + ".xy);\n"; } else { @@ -633,15 +633,15 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (source == SOURCE_2D_NORMAL && p_mode == Shader::MODE_CANVAS_ITEM && p_type == VisualShader::TYPE_FRAGMENT) { String code = " {\n"; - if (p_input_vars[0] == String()) { // Use UV by default. + if (p_input_vars[0].is_empty()) { // Use UV by default. - if (p_input_vars[1] == String()) { + if (p_input_vars[1].is_empty()) { code += " vec4 _tex_read = texture(NORMAL_TEXTURE, " + default_uv + ");\n"; } else { code += " vec4 _tex_read = textureLod(NORMAL_TEXTURE, " + default_uv + ", " + p_input_vars[1] + ");\n"; } - } else if (p_input_vars[1] == String()) { + } else if (p_input_vars[1].is_empty()) { //no lod code += " vec4 _tex_read = texture(NORMAL_TEXTURE, " + p_input_vars[0] + ".xy);\n"; } else { @@ -666,15 +666,15 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (source == SOURCE_DEPTH && p_mode == Shader::MODE_SPATIAL && p_type == VisualShader::TYPE_FRAGMENT) { String code = " {\n"; - if (p_input_vars[0] == String()) { // Use UV by default. + if (p_input_vars[0].is_empty()) { // Use UV by default. - if (p_input_vars[1] == String()) { + if (p_input_vars[1].is_empty()) { code += " float _depth = texture(DEPTH_TEXTURE, " + default_uv + ").r;\n"; } else { code += " float _depth = textureLod(DEPTH_TEXTURE, " + default_uv + ", " + p_input_vars[1] + ").r;\n"; } - } else if (p_input_vars[1] == String()) { + } else if (p_input_vars[1].is_empty()) { //no lod code += " float _depth = texture(DEPTH_TEXTURE, " + p_input_vars[0] + ".xy).r;\n"; } else { @@ -883,7 +883,7 @@ String VisualShaderNodeCurveTexture::generate_global(Shader::Mode p_mode, Visual } String VisualShaderNodeCurveTexture::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 { - if (p_input_vars[0] == String()) { + if (p_input_vars[0].is_empty()) { return " " + p_output_vars[0] + " = 0.0;\n"; } String id = make_unique_id(p_type, p_id, "curve"); @@ -968,7 +968,7 @@ String VisualShaderNodeCurveXYZTexture::generate_global(Shader::Mode p_mode, Vis } String VisualShaderNodeCurveXYZTexture::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 { - if (p_input_vars[0] == String()) { + if (p_input_vars[0].is_empty()) { return " " + p_output_vars[0] + " = vec3(0.0);\n"; } String id = make_unique_id(p_type, p_id, "curve3d"); @@ -1076,14 +1076,14 @@ String VisualShaderNodeSample3D::generate_code(Shader::Mode p_mode, VisualShader } else { id = p_input_vars[2]; } - if (id != String()) { - if (p_input_vars[0] == String()) { // Use UV by default. - if (p_input_vars[1] == String()) { + if (!id.is_empty()) { + if (p_input_vars[0].is_empty()) { // Use UV by default. + if (p_input_vars[1].is_empty()) { code += " vec4 " + id + "_tex_read = texture(" + id + ", " + default_uv + ");\n"; } else { code += " vec4 " + id + "_tex_read = textureLod(" + id + ", " + default_uv + ", " + p_input_vars[1] + ");\n"; } - } else if (p_input_vars[1] == String()) { + } else if (p_input_vars[1].is_empty()) { //no lod code += " vec4 " + id + "_tex_read = texture(" + id + ", " + p_input_vars[0] + ");\n"; } else { @@ -1364,7 +1364,7 @@ String VisualShaderNodeCubemap::generate_code(Shader::Mode p_mode, VisualShader: code += " {\n"; - if (id == String()) { + if (id.is_empty()) { code += " vec4 " + id + "_read = vec4(0.0);\n"; code += " " + p_output_vars[0] + " = " + id + "_read.rgb;\n"; code += " " + p_output_vars[1] + " = " + id + "_read.a;\n"; @@ -1372,15 +1372,15 @@ String VisualShaderNodeCubemap::generate_code(Shader::Mode p_mode, VisualShader: return code; } - if (p_input_vars[0] == String()) { // Use UV by default. + if (p_input_vars[0].is_empty()) { // Use UV by default. - if (p_input_vars[1] == String()) { + if (p_input_vars[1].is_empty()) { code += " vec4 " + id + "_read = texture(" + id + ", " + default_uv + ");\n"; } else { code += " vec4 " + id + "_read = textureLod(" + id + ", " + default_uv + ", " + p_input_vars[1] + " );\n"; } - } else if (p_input_vars[1] == String()) { + } else if (p_input_vars[1].is_empty()) { //no lod code += " vec4 " + id + "_read = texture(" + id + ", " + p_input_vars[0] + ");\n"; } else { @@ -4857,34 +4857,106 @@ String VisualShaderNodeTextureUniform::get_output_port_name(int p_port) const { } String VisualShaderNodeTextureUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + bool has_colon = false; String code = _get_qual_str() + "uniform sampler2D " + get_uniform_name(); - switch (texture_type) { - case TYPE_DATA: - if (color_default == COLOR_DEFAULT_BLACK) { - code += " : hint_black;\n"; + // type + { + String type_code; + + switch (texture_type) { + case TYPE_DATA: + if (color_default == COLOR_DEFAULT_BLACK) { + type_code = "hint_black"; + } + break; + case TYPE_COLOR: + if (color_default == COLOR_DEFAULT_BLACK) { + type_code = "hint_black_albedo"; + } else { + type_code = "hint_albedo"; + } + break; + case TYPE_NORMAL_MAP: + type_code = "hint_normal"; + break; + case TYPE_ANISOTROPY: + type_code = "hint_anisotropy"; + break; + default: + break; + } + + if (!type_code.is_empty()) { + code += " : " + type_code; + has_colon = true; + } + } + + // filter + { + String filter_code; + + switch (texture_filter) { + case FILTER_NEAREST: + filter_code = "filter_nearest"; + break; + case FILTER_LINEAR: + filter_code = "filter_linear"; + break; + case FILTER_NEAREST_MIPMAP: + filter_code = "filter_nearest_mipmap"; + break; + case FILTER_LINEAR_MIPMAP: + filter_code = "filter_linear_mipmap"; + break; + case FILTER_NEAREST_MIPMAP_ANISOTROPIC: + filter_code = "filter_nearest_mipmap_anisotropic"; + break; + case FILTER_LINEAR_MIPMAP_ANISOTROPIC: + filter_code = "filter_linear_mipmap_anisotropic"; + break; + default: + break; + } + + if (!filter_code.is_empty()) { + if (!has_colon) { + code += " : "; + has_colon = true; } else { - code += ";\n"; + code += ", "; } - break; - case TYPE_COLOR: - if (color_default == COLOR_DEFAULT_BLACK) { - code += " : hint_black_albedo;\n"; + code += filter_code; + } + } + + // repeat + { + String repeat_code; + + switch (texture_repeat) { + case REPEAT_ENABLED: + repeat_code = "repeat_enable"; + break; + case REPEAT_DISABLED: + repeat_code = "repeat_disable"; + break; + default: + break; + } + + if (!repeat_code.is_empty()) { + if (!has_colon) { + code += " : "; } else { - code += " : hint_albedo;\n"; + code += ", "; } - break; - case TYPE_NORMAL_MAP: - code += " : hint_normal;\n"; - break; - case TYPE_ANISO: - code += " : hint_aniso;\n"; - break; - default: - code += ";\n"; - break; + code += repeat_code; + } } + code += ";\n"; return code; } @@ -4902,13 +4974,13 @@ String VisualShaderNodeTextureUniform::generate_code(Shader::Mode p_mode, Visual String id = get_uniform_name(); String code = " {\n"; - if (p_input_vars[0] == String()) { // Use UV by default. - if (p_input_vars[1] == String()) { + if (p_input_vars[0].is_empty()) { // Use UV by default. + if (p_input_vars[1].is_empty()) { code += " vec4 n_tex_read = texture(" + id + ", " + default_uv + ");\n"; } else { code += " vec4 n_tex_read = textureLod(" + id + ", " + default_uv + ", " + p_input_vars[1] + ");\n"; } - } else if (p_input_vars[1] == String()) { + } else if (p_input_vars[1].is_empty()) { //no lod code += " vec4 n_tex_read = texture(" + id + ", " + p_input_vars[0] + ".xy);\n"; } else { @@ -4947,13 +5019,56 @@ VisualShaderNodeTextureUniform::ColorDefault VisualShaderNodeTextureUniform::get return color_default; } +void VisualShaderNodeTextureUniform::set_texture_filter(TextureFilter p_filter) { + ERR_FAIL_INDEX(int(p_filter), int(FILTER_MAX)); + if (texture_filter == p_filter) { + return; + } + texture_filter = p_filter; + emit_changed(); +} + +VisualShaderNodeTextureUniform::TextureFilter VisualShaderNodeTextureUniform::get_texture_filter() const { + return texture_filter; +} + +void VisualShaderNodeTextureUniform::set_texture_repeat(TextureRepeat p_repeat) { + ERR_FAIL_INDEX(int(p_repeat), int(REPEAT_MAX)); + if (texture_repeat == p_repeat) { + return; + } + texture_repeat = p_repeat; + emit_changed(); +} + +VisualShaderNodeTextureUniform::TextureRepeat VisualShaderNodeTextureUniform::get_texture_repeat() const { + return texture_repeat; +} + Vector<StringName> VisualShaderNodeTextureUniform::get_editable_properties() const { Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); props.push_back("texture_type"); - props.push_back("color_default"); + if (texture_type == TYPE_DATA || texture_type == TYPE_COLOR) { + props.push_back("color_default"); + } + props.push_back("texture_filter"); + props.push_back("texture_repeat"); return props; } +bool VisualShaderNodeTextureUniform::is_show_prop_names() const { + return true; +} + +Map<StringName, String> VisualShaderNodeTextureUniform::get_editable_properties_names() const { + Map<StringName, String> names; + names.insert("texture_type", TTR("Type")); + names.insert("color_default", TTR("Default Color")); + names.insert("texture_filter", TTR("Filter")); + names.insert("texture_repeat", TTR("Repeat")); + 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); @@ -4961,18 +5076,40 @@ void VisualShaderNodeTextureUniform::_bind_methods() { 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_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_repeat", "type"), &VisualShaderNodeTextureUniform::set_texture_repeat); + ClassDB::bind_method(D_METHOD("get_texture_repeat"), &VisualShaderNodeTextureUniform::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 Default,Black Default"), "set_color_default", "get_color_default"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "color_default", PROPERTY_HINT_ENUM, "White,Black"), "set_color_default", "get_color_default"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "Default,Nearest,Linear,Nearest Mipmap,Linear Mipmap,Nearest Mipmap Anisotropic,Linear Mipmap Anisotropic"), "set_texture_filter", "get_texture_filter"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_repeat", PROPERTY_HINT_ENUM, "Default,Enabled,Disabled"), "set_texture_repeat", "get_texture_repeat"); BIND_ENUM_CONSTANT(TYPE_DATA); BIND_ENUM_CONSTANT(TYPE_COLOR); BIND_ENUM_CONSTANT(TYPE_NORMAL_MAP); - BIND_ENUM_CONSTANT(TYPE_ANISO); + BIND_ENUM_CONSTANT(TYPE_ANISOTROPY); BIND_ENUM_CONSTANT(TYPE_MAX); BIND_ENUM_CONSTANT(COLOR_DEFAULT_WHITE); BIND_ENUM_CONSTANT(COLOR_DEFAULT_BLACK); BIND_ENUM_CONSTANT(COLOR_DEFAULT_MAX); + + BIND_ENUM_CONSTANT(FILTER_DEFAULT); + BIND_ENUM_CONSTANT(FILTER_NEAREST); + BIND_ENUM_CONSTANT(FILTER_LINEAR); + BIND_ENUM_CONSTANT(FILTER_NEAREST_MIPMAP); + BIND_ENUM_CONSTANT(FILTER_LINEAR_MIPMAP); + BIND_ENUM_CONSTANT(FILTER_NEAREST_MIPMAP_ANISOTROPIC); + BIND_ENUM_CONSTANT(FILTER_LINEAR_MIPMAP_ANISOTROPIC); + BIND_ENUM_CONSTANT(FILTER_MAX); + + BIND_ENUM_CONSTANT(REPEAT_DEFAULT); + BIND_ENUM_CONSTANT(REPEAT_ENABLED); + BIND_ENUM_CONSTANT(REPEAT_DISABLED); + BIND_ENUM_CONSTANT(REPEAT_MAX); } String VisualShaderNodeTextureUniform::get_input_port_default_hint(int p_port) const { @@ -5070,11 +5207,11 @@ String VisualShaderNodeTextureUniformTriplanar::generate_code(Shader::Mode p_mod String id = get_uniform_name(); String code = " {\n"; - if (p_input_vars[0] == String() && p_input_vars[1] == String()) { + if (p_input_vars[0].is_empty() && p_input_vars[1].is_empty()) { code += " vec4 n_tex_read = triplanar_texture(" + id + ", triplanar_power_normal, triplanar_pos);\n"; - } else if (p_input_vars[0] != String() && p_input_vars[1] == String()) { + } else if (!p_input_vars[0].is_empty() && p_input_vars[1].is_empty()) { code += " vec4 n_tex_read = triplanar_texture(" + id + ", " + p_input_vars[0] + ", triplanar_pos);\n"; - } else if (p_input_vars[0] == String() && p_input_vars[1] != String()) { + } else if (p_input_vars[0].is_empty() && !p_input_vars[1].is_empty()) { code += " vec4 n_tex_read = triplanar_texture(" + id + ", triplanar_power_normal, " + p_input_vars[1] + ");\n"; } else { code += " vec4 n_tex_read = triplanar_texture(" + id + ", " + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; @@ -5154,8 +5291,8 @@ String VisualShaderNodeTexture2DArrayUniform::generate_global(Shader::Mode p_mod case TYPE_NORMAL_MAP: code += " : hint_normal;\n"; break; - case TYPE_ANISO: - code += " : hint_aniso;\n"; + case TYPE_ANISOTROPY: + code += " : hint_anisotropy;\n"; break; default: code += ";\n"; @@ -5227,8 +5364,8 @@ String VisualShaderNodeTexture3DUniform::generate_global(Shader::Mode p_mode, Vi case TYPE_NORMAL_MAP: code += " : hint_normal;\n"; break; - case TYPE_ANISO: - code += " : hint_aniso;\n"; + case TYPE_ANISOTROPY: + code += " : hint_anisotropy;\n"; break; default: code += ";\n"; @@ -5300,8 +5437,8 @@ String VisualShaderNodeCubemapUniform::generate_global(Shader::Mode p_mode, Visu case TYPE_NORMAL_MAP: code += " : hint_normal;\n"; break; - case TYPE_ANISO: - code += " : hint_aniso;\n"; + case TYPE_ANISOTROPY: + code += " : hint_anisotropy;\n"; break; default: code += ";\n"; @@ -5600,12 +5737,12 @@ bool VisualShaderNodeFresnel::is_generate_input_var(int p_port) const { String VisualShaderNodeFresnel::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 normal; String view; - if (p_input_vars[0] == String()) { + if (p_input_vars[0].is_empty()) { normal = "NORMAL"; } else { normal = p_input_vars[0]; } - if (p_input_vars[1] == String()) { + if (p_input_vars[1].is_empty()) { view = "VIEW"; } else { view = p_input_vars[1]; diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index 2f3400404c..f1dda634f1 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -1943,7 +1943,7 @@ public: TYPE_DATA, TYPE_COLOR, TYPE_NORMAL_MAP, - TYPE_ANISO, + TYPE_ANISOTROPY, TYPE_MAX, }; @@ -1953,9 +1953,29 @@ public: COLOR_DEFAULT_MAX, }; + enum TextureFilter { + FILTER_DEFAULT, + FILTER_NEAREST, + FILTER_LINEAR, + FILTER_NEAREST_MIPMAP, + FILTER_LINEAR_MIPMAP, + FILTER_NEAREST_MIPMAP_ANISOTROPIC, + FILTER_LINEAR_MIPMAP_ANISOTROPIC, + FILTER_MAX, + }; + + enum TextureRepeat { + REPEAT_DEFAULT, + REPEAT_ENABLED, + REPEAT_DISABLED, + REPEAT_MAX, + }; + protected: TextureType texture_type = TYPE_DATA; ColorDefault color_default = COLOR_DEFAULT_WHITE; + TextureFilter texture_filter = FILTER_DEFAULT; + TextureRepeat texture_repeat = REPEAT_DEFAULT; protected: static void _bind_methods(); @@ -1975,6 +1995,8 @@ public: 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 Map<StringName, String> get_editable_properties_names() const override; + virtual bool is_show_prop_names() const override; virtual bool is_code_generated() const override; Vector<StringName> get_editable_properties() const override; @@ -1985,6 +2007,12 @@ public: void set_color_default(ColorDefault p_default); ColorDefault get_color_default() const; + void set_texture_filter(TextureFilter p_filter); + TextureFilter get_texture_filter() const; + + void set_texture_repeat(TextureRepeat p_repeat); + TextureRepeat get_texture_repeat() const; + bool is_qualifier_supported(Qualifier p_qual) const override; bool is_convertible_to_constant() const override; @@ -1993,6 +2021,8 @@ public: VARIANT_ENUM_CAST(VisualShaderNodeTextureUniform::TextureType) VARIANT_ENUM_CAST(VisualShaderNodeTextureUniform::ColorDefault) +VARIANT_ENUM_CAST(VisualShaderNodeTextureUniform::TextureFilter) +VARIANT_ENUM_CAST(VisualShaderNodeTextureUniform::TextureRepeat) /////////////////////////////////////// diff --git a/scene/resources/visual_shader_particle_nodes.cpp b/scene/resources/visual_shader_particle_nodes.cpp index a7c20b2cb9..c970b9c08b 100644 --- a/scene/resources/visual_shader_particle_nodes.cpp +++ b/scene/resources/visual_shader_particle_nodes.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/visual_shader_particle_nodes.h b/scene/resources/visual_shader_particle_nodes.h index ae7ea69225..add6928841 100644 --- a/scene/resources/visual_shader_particle_nodes.h +++ b/scene/resources/visual_shader_particle_nodes.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/visual_shader_sdf_nodes.cpp b/scene/resources/visual_shader_sdf_nodes.cpp index 14c655b129..1b43fda4c5 100644 --- a/scene/resources/visual_shader_sdf_nodes.cpp +++ b/scene/resources/visual_shader_sdf_nodes.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -61,7 +61,7 @@ String VisualShaderNodeSDFToScreenUV::get_output_port_name(int p_port) const { } String VisualShaderNodeSDFToScreenUV::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] + " = vec3(sdf_to_screen_uv(" + (p_input_vars[0] == String() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + "), 0.0f);\n"; + return " " + p_output_vars[0] + " = vec3(sdf_to_screen_uv(" + (p_input_vars[0].is_empty() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + "), 0.0f);\n"; } VisualShaderNodeSDFToScreenUV::VisualShaderNodeSDFToScreenUV() { @@ -105,7 +105,7 @@ String VisualShaderNodeScreenUVToSDF::get_input_port_default_hint(int p_port) co } String VisualShaderNodeScreenUVToSDF::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] + " = vec3(screen_uv_to_sdf(" + (p_input_vars[0] == String() ? "SCREEN_UV" : p_input_vars[0] + ".xy") + "), 0.0f);\n"; + return " " + p_output_vars[0] + " = vec3(screen_uv_to_sdf(" + (p_input_vars[0].is_empty() ? "SCREEN_UV" : p_input_vars[0] + ".xy") + "), 0.0f);\n"; } VisualShaderNodeScreenUVToSDF::VisualShaderNodeScreenUVToSDF() { @@ -142,7 +142,7 @@ String VisualShaderNodeTextureSDF::get_output_port_name(int p_port) const { } String VisualShaderNodeTextureSDF::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] + " = texture_sdf(" + (p_input_vars[0] == String() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + ");\n"; + return " " + p_output_vars[0] + " = texture_sdf(" + (p_input_vars[0].is_empty() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + ");\n"; } VisualShaderNodeTextureSDF::VisualShaderNodeTextureSDF() { @@ -179,7 +179,7 @@ String VisualShaderNodeTextureSDFNormal::get_output_port_name(int p_port) const } String VisualShaderNodeTextureSDFNormal::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] + " = vec3(texture_sdf_normal(" + (p_input_vars[0] == String() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + "), 0.0f);\n"; + return " " + p_output_vars[0] + " = vec3(texture_sdf_normal(" + (p_input_vars[0].is_empty() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + "), 0.0f);\n"; } VisualShaderNodeTextureSDFNormal::VisualShaderNodeTextureSDFNormal() { @@ -242,13 +242,13 @@ String VisualShaderNodeSDFRaymarch::generate_code(Shader::Mode p_mode, VisualSha code += " {\n"; - if (p_input_vars[0] == String()) { + if (p_input_vars[0].is_empty()) { code += " vec2 __from_pos = vec2(0.0f);\n"; } else { code += " vec2 __from_pos = " + p_input_vars[0] + ".xy;\n"; } - if (p_input_vars[1] == String()) { + if (p_input_vars[1].is_empty()) { code += " vec2 __to_pos = vec2(0.0f);\n"; } else { code += " vec2 __to_pos = " + p_input_vars[1] + ".xy;\n"; diff --git a/scene/resources/visual_shader_sdf_nodes.h b/scene/resources/visual_shader_sdf_nodes.h index 0fcf5ec0b5..d2d1dde4ea 100644 --- a/scene/resources/visual_shader_sdf_nodes.h +++ b/scene/resources/visual_shader_sdf_nodes.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp index eceb42ee14..c937d988d2 100644 --- a/scene/resources/world_2d.cpp +++ b/scene/resources/world_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/world_2d.h b/scene/resources/world_2d.h index 65f89c8f64..91f9a026d3 100644 --- a/scene/resources/world_2d.h +++ b/scene/resources/world_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/world_3d.cpp b/scene/resources/world_3d.cpp index 0e1b343eac..c012ab6177 100644 --- a/scene/resources/world_3d.cpp +++ b/scene/resources/world_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/world_3d.h b/scene/resources/world_3d.h index 2c5be35609..b34b7a2bfb 100644 --- a/scene/resources/world_3d.h +++ b/scene/resources/world_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/world_boundary_shape_2d.cpp b/scene/resources/world_boundary_shape_2d.cpp index 39af92793f..9789388c6a 100644 --- a/scene/resources/world_boundary_shape_2d.cpp +++ b/scene/resources/world_boundary_shape_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/world_boundary_shape_2d.h b/scene/resources/world_boundary_shape_2d.h index 4cc60f5985..3275e8c916 100644 --- a/scene/resources/world_boundary_shape_2d.h +++ b/scene/resources/world_boundary_shape_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/resources/world_boundary_shape_3d.cpp b/scene/resources/world_boundary_shape_3d.cpp index 8cde537164..09d41e8291 100644 --- a/scene/resources/world_boundary_shape_3d.cpp +++ b/scene/resources/world_boundary_shape_3d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -34,7 +34,6 @@ Vector<Vector3> WorldBoundaryShape3D::get_debug_mesh_lines() const { Plane p = get_plane(); - Vector<Vector3> points; Vector3 n1 = p.get_any_perpendicular_normal(); Vector3 n2 = p.normal.cross(n1).normalized(); @@ -46,16 +45,18 @@ Vector<Vector3> WorldBoundaryShape3D::get_debug_mesh_lines() const { p.normal * p.d + n1 * -10.0 + n2 * 10.0, }; - points.push_back(pface[0]); - points.push_back(pface[1]); - points.push_back(pface[1]); - points.push_back(pface[2]); - points.push_back(pface[2]); - points.push_back(pface[3]); - points.push_back(pface[3]); - points.push_back(pface[0]); - points.push_back(p.normal * p.d); - points.push_back(p.normal * p.d + p.normal * 3); + Vector<Vector3> points = { + pface[0], + pface[1], + pface[1], + pface[2], + pface[2], + pface[3], + pface[3], + pface[0], + p.normal * p.d, + p.normal * p.d + p.normal * 3 + }; return points; } diff --git a/scene/resources/world_boundary_shape_3d.h b/scene/resources/world_boundary_shape_3d.h index 853f555ebc..5378bc52c7 100644 --- a/scene/resources/world_boundary_shape_3d.h +++ b/scene/resources/world_boundary_shape_3d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp index 186764e69e..a15c03d675 100644 --- a/scene/scene_string_names.cpp +++ b/scene/scene_string_names.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -61,6 +61,7 @@ SceneStringNames::SceneStringNames() { animation_finished = StaticCString::create("animation_finished"); animation_changed = StaticCString::create("animation_changed"); animation_started = StaticCString::create("animation_started"); + RESET = StaticCString::create("RESET"); pose_updated = StaticCString::create("pose_updated"); bone_pose_changed = StaticCString::create("bone_pose_changed"); diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h index 67007c85e0..5589ab327f 100644 --- a/scene/scene_string_names.h +++ b/scene/scene_string_names.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* 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 */ @@ -97,6 +97,7 @@ public: StringName animation_finished; StringName animation_changed; StringName animation_started; + StringName RESET; StringName pose_updated; StringName bone_pose_changed; |