summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/animated_sprite_2d.cpp209
-rw-r--r--scene/2d/animated_sprite_2d.h67
-rw-r--r--scene/2d/camera_2d.cpp35
-rw-r--r--scene/2d/camera_2d.h28
-rw-r--r--scene/2d/canvas_group.cpp8
-rw-r--r--scene/2d/canvas_group.h12
-rw-r--r--scene/2d/cpu_particles_2d.cpp110
-rw-r--r--scene/2d/cpu_particles_2d.h54
-rw-r--r--scene/2d/light_2d.cpp27
-rw-r--r--scene/2d/light_2d.h31
-rw-r--r--scene/2d/line_builder.cpp8
-rw-r--r--scene/2d/navigation_2d.cpp92
-rw-r--r--scene/2d/navigation_2d.h71
-rw-r--r--scene/2d/navigation_agent_2d.cpp45
-rw-r--r--scene/2d/navigation_agent_2d.h15
-rw-r--r--scene/2d/navigation_obstacle_2d.cpp113
-rw-r--r--scene/2d/navigation_obstacle_2d.h14
-rw-r--r--scene/2d/navigation_region_2d.cpp117
-rw-r--r--scene/2d/navigation_region_2d.h7
-rw-r--r--scene/2d/node_2d.cpp38
-rw-r--r--scene/2d/node_2d.h40
-rw-r--r--scene/2d/parallax_background.cpp4
-rw-r--r--scene/2d/parallax_background.h6
-rw-r--r--scene/2d/parallax_layer.cpp6
-rw-r--r--scene/2d/parallax_layer.h2
-rw-r--r--scene/2d/path_2d.cpp32
-rw-r--r--scene/2d/path_2d.h20
-rw-r--r--scene/2d/physics_body_2d.cpp4
-rw-r--r--scene/2d/polygon_2d.cpp20
-rw-r--r--scene/2d/polygon_2d.h21
-rw-r--r--scene/2d/position_2d.cpp10
-rw-r--r--scene/2d/position_2d.h4
-rw-r--r--scene/2d/ray_cast_2d.cpp43
-rw-r--r--scene/2d/skeleton_2d.cpp6
-rw-r--r--scene/2d/skeleton_2d.h6
-rw-r--r--scene/2d/sprite_2d.cpp50
-rw-r--r--scene/2d/sprite_2d.h14
-rw-r--r--scene/2d/tile_map.cpp73
-rw-r--r--scene/2d/tile_map.h6
-rw-r--r--scene/3d/area_3d.cpp4
-rw-r--r--scene/3d/baked_lightmap.cpp10
-rw-r--r--scene/3d/camera_3d.cpp4
-rw-r--r--scene/3d/collision_object_3d.cpp3
-rw-r--r--scene/3d/decal.cpp2
-rw-r--r--scene/3d/decal.h5
-rw-r--r--scene/3d/gpu_particles_3d.cpp2
-rw-r--r--scene/3d/light_3d.cpp2
-rw-r--r--scene/3d/navigation_3d.cpp117
-rw-r--r--scene/3d/navigation_agent_3d.cpp45
-rw-r--r--scene/3d/navigation_agent_3d.h10
-rw-r--r--scene/3d/navigation_obstacle_3d.cpp130
-rw-r--r--scene/3d/navigation_obstacle_3d.h14
-rw-r--r--scene/3d/navigation_region_3d.cpp49
-rw-r--r--scene/3d/navigation_region_3d.h6
-rw-r--r--scene/3d/node_3d.cpp2
-rw-r--r--scene/3d/physics_body_3d.cpp4
-rw-r--r--scene/3d/ray_cast_3d.cpp4
-rw-r--r--scene/3d/skeleton_ik_3d.cpp32
-rw-r--r--scene/3d/skeleton_ik_3d.h3
-rw-r--r--scene/3d/soft_body_3d.cpp72
-rw-r--r--scene/3d/soft_body_3d.h20
-rw-r--r--scene/3d/sprite_3d.cpp30
-rw-r--r--scene/3d/sprite_3d.h12
-rw-r--r--scene/3d/vehicle_body_3d.cpp4
-rw-r--r--scene/3d/voxelizer.cpp8
-rw-r--r--scene/animation/animation_player.cpp8
-rw-r--r--scene/animation/animation_tree.cpp7
-rw-r--r--scene/animation/tween.cpp2
-rw-r--r--scene/audio/audio_stream_player.cpp2
-rw-r--r--scene/debugger/scene_debugger.cpp2
-rw-r--r--scene/gui/base_button.h2
-rw-r--r--scene/gui/box_container.cpp4
-rw-r--r--scene/gui/box_container.h2
-rw-r--r--scene/gui/check_box.cpp6
-rw-r--r--scene/gui/color_picker.cpp106
-rw-r--r--scene/gui/color_picker.h1
-rw-r--r--scene/gui/control.cpp73
-rw-r--r--scene/gui/control.h42
-rw-r--r--scene/gui/dialogs.cpp8
-rw-r--r--scene/gui/file_dialog.cpp148
-rw-r--r--scene/gui/file_dialog.h10
-rw-r--r--scene/gui/graph_edit.cpp64
-rw-r--r--scene/gui/graph_edit.h2
-rw-r--r--scene/gui/graph_node.cpp136
-rw-r--r--scene/gui/item_list.cpp20
-rw-r--r--scene/gui/label.cpp5
-rw-r--r--scene/gui/line_edit.cpp24
-rw-r--r--scene/gui/line_edit.h6
-rw-r--r--scene/gui/popup_menu.cpp5
-rw-r--r--scene/gui/rich_text_label.cpp60
-rw-r--r--scene/gui/rich_text_label.h5
-rw-r--r--scene/gui/scroll_bar.cpp6
-rw-r--r--scene/gui/scroll_container.cpp10
-rw-r--r--scene/gui/slider.cpp6
-rw-r--r--scene/gui/spin_box.cpp31
-rw-r--r--scene/gui/spin_box.h1
-rw-r--r--scene/gui/split_container.cpp2
-rw-r--r--scene/gui/tab_container.cpp5
-rw-r--r--scene/gui/tabs.cpp69
-rw-r--r--scene/gui/tabs.h4
-rw-r--r--scene/gui/text_edit.cpp59
-rw-r--r--scene/gui/tree.cpp68
-rw-r--r--scene/gui/tree.h2
-rw-r--r--scene/main/canvas_item.cpp43
-rw-r--r--scene/main/canvas_item.h38
-rw-r--r--scene/main/canvas_layer.cpp2
-rw-r--r--scene/main/canvas_layer.h5
-rw-r--r--scene/main/http_request.cpp2
-rw-r--r--scene/main/node.cpp35
-rw-r--r--scene/main/node.h6
-rw-r--r--scene/main/scene_tree.cpp1
-rw-r--r--scene/main/viewport.cpp38
-rw-r--r--scene/main/viewport.h2
-rw-r--r--scene/main/window.cpp9
-rw-r--r--scene/register_scene_types.cpp13
-rw-r--r--scene/resources/animation.cpp4
-rw-r--r--scene/resources/bit_map.cpp2
-rw-r--r--scene/resources/camera_effects.cpp2
-rw-r--r--scene/resources/camera_effects.h5
-rw-r--r--scene/resources/concave_polygon_shape_3d.cpp37
-rw-r--r--scene/resources/concave_polygon_shape_3d.h6
-rw-r--r--scene/resources/default_theme/bar_arrow.pngbin0 -> 208 bytes
-rw-r--r--scene/resources/default_theme/checked_disabled.pngbin0 -> 421 bytes
-rw-r--r--scene/resources/default_theme/default_theme.cpp11
-rw-r--r--scene/resources/default_theme/radio_checked_disabled.pngbin0 -> 235 bytes
-rw-r--r--scene/resources/default_theme/radio_unchecked_disabled.pngbin0 -> 183 bytes
-rw-r--r--scene/resources/default_theme/theme_data.h20
-rw-r--r--scene/resources/default_theme/unchecked_disabled.pngbin0 -> 246 bytes
-rw-r--r--scene/resources/material.cpp4
-rw-r--r--scene/resources/particles_material.cpp19
-rw-r--r--scene/resources/polygon_path_finder.cpp4
-rw-r--r--scene/resources/ray_shape_2d.cpp28
-rw-r--r--scene/resources/resource_format_text.cpp2
-rw-r--r--scene/resources/sprite_frames.cpp241
-rw-r--r--scene/resources/sprite_frames.h (renamed from scene/3d/navigation_3d.h)88
-rw-r--r--scene/resources/style_box.cpp7
-rw-r--r--scene/resources/style_box.h1
-rw-r--r--scene/resources/surface_tool.cpp9
-rw-r--r--scene/resources/surface_tool.h3
-rw-r--r--scene/resources/text_paragraph.cpp11
-rw-r--r--scene/resources/text_paragraph.h3
-rw-r--r--scene/resources/texture.cpp22
-rw-r--r--scene/resources/texture.h12
-rw-r--r--scene/resources/theme.cpp432
-rw-r--r--scene/resources/theme.h40
-rw-r--r--scene/resources/world_2d.cpp23
-rw-r--r--scene/resources/world_2d.h6
-rw-r--r--scene/resources/world_3d.cpp13
-rw-r--r--scene/resources/world_3d.h2
149 files changed, 2373 insertions, 1953 deletions
diff --git a/scene/2d/animated_sprite_2d.cpp b/scene/2d/animated_sprite_2d.cpp
index f39850441b..dfc08583f2 100644
--- a/scene/2d/animated_sprite_2d.cpp
+++ b/scene/2d/animated_sprite_2d.cpp
@@ -105,214 +105,6 @@ Rect2 AnimatedSprite2D::_get_rect() const {
return Rect2(ofs, s);
}
-void SpriteFrames::add_frame(const StringName &p_anim, const Ref<Texture2D> &p_frame, int p_at_pos) {
- Map<StringName, Anim>::Element *E = animations.find(p_anim);
- ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist.");
-
- if (p_at_pos >= 0 && p_at_pos < E->get().frames.size()) {
- E->get().frames.insert(p_at_pos, p_frame);
- } else {
- E->get().frames.push_back(p_frame);
- }
-
- emit_changed();
-}
-
-int SpriteFrames::get_frame_count(const StringName &p_anim) const {
- const Map<StringName, Anim>::Element *E = animations.find(p_anim);
- ERR_FAIL_COND_V_MSG(!E, 0, "Animation '" + String(p_anim) + "' doesn't exist.");
-
- return E->get().frames.size();
-}
-
-void SpriteFrames::remove_frame(const StringName &p_anim, int p_idx) {
- Map<StringName, Anim>::Element *E = animations.find(p_anim);
- ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist.");
-
- E->get().frames.remove(p_idx);
- emit_changed();
-}
-
-void SpriteFrames::clear(const StringName &p_anim) {
- Map<StringName, Anim>::Element *E = animations.find(p_anim);
- ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist.");
-
- E->get().frames.clear();
- emit_changed();
-}
-
-void SpriteFrames::clear_all() {
- animations.clear();
- add_animation("default");
-}
-
-void SpriteFrames::add_animation(const StringName &p_anim) {
- ERR_FAIL_COND_MSG(animations.has(p_anim), "SpriteFrames already has animation '" + p_anim + "'.");
-
- animations[p_anim] = Anim();
-}
-
-bool SpriteFrames::has_animation(const StringName &p_anim) const {
- return animations.has(p_anim);
-}
-
-void SpriteFrames::remove_animation(const StringName &p_anim) {
- animations.erase(p_anim);
-}
-
-void SpriteFrames::rename_animation(const StringName &p_prev, const StringName &p_next) {
- ERR_FAIL_COND_MSG(!animations.has(p_prev), "SpriteFrames doesn't have animation '" + String(p_prev) + "'.");
- ERR_FAIL_COND_MSG(animations.has(p_next), "Animation '" + String(p_next) + "' already exists.");
-
- Anim anim = animations[p_prev];
- animations.erase(p_prev);
- animations[p_next] = anim;
-}
-
-Vector<String> SpriteFrames::_get_animation_list() const {
- Vector<String> ret;
- List<StringName> al;
- get_animation_list(&al);
- for (List<StringName>::Element *E = al.front(); E; E = E->next()) {
- ret.push_back(E->get());
- }
-
- return ret;
-}
-
-void SpriteFrames::get_animation_list(List<StringName> *r_animations) const {
- for (const Map<StringName, Anim>::Element *E = animations.front(); E; E = E->next()) {
- r_animations->push_back(E->key());
- }
-}
-
-Vector<String> SpriteFrames::get_animation_names() const {
- Vector<String> names;
- for (const Map<StringName, Anim>::Element *E = animations.front(); E; E = E->next()) {
- names.push_back(E->key());
- }
- names.sort();
- return names;
-}
-
-void SpriteFrames::set_animation_speed(const StringName &p_anim, float p_fps) {
- ERR_FAIL_COND_MSG(p_fps < 0, "Animation speed cannot be negative (" + itos(p_fps) + ").");
- Map<StringName, Anim>::Element *E = animations.find(p_anim);
- ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist.");
- E->get().speed = p_fps;
-}
-
-float SpriteFrames::get_animation_speed(const StringName &p_anim) const {
- const Map<StringName, Anim>::Element *E = animations.find(p_anim);
- ERR_FAIL_COND_V_MSG(!E, 0, "Animation '" + String(p_anim) + "' doesn't exist.");
- return E->get().speed;
-}
-
-void SpriteFrames::set_animation_loop(const StringName &p_anim, bool p_loop) {
- Map<StringName, Anim>::Element *E = animations.find(p_anim);
- ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist.");
- E->get().loop = p_loop;
-}
-
-bool SpriteFrames::get_animation_loop(const StringName &p_anim) const {
- const Map<StringName, Anim>::Element *E = animations.find(p_anim);
- ERR_FAIL_COND_V_MSG(!E, false, "Animation '" + String(p_anim) + "' doesn't exist.");
- return E->get().loop;
-}
-
-void SpriteFrames::_set_frames(const Array &p_frames) {
- clear_all();
- Map<StringName, Anim>::Element *E = animations.find(SceneStringNames::get_singleton()->_default);
- ERR_FAIL_COND(!E);
-
- E->get().frames.resize(p_frames.size());
- for (int i = 0; i < E->get().frames.size(); i++) {
- E->get().frames.write[i] = p_frames[i];
- }
-}
-
-Array SpriteFrames::_get_frames() const {
- return Array();
-}
-
-Array SpriteFrames::_get_animations() const {
- Array anims;
- for (Map<StringName, Anim>::Element *E = animations.front(); E; E = E->next()) {
- Dictionary d;
- d["name"] = E->key();
- d["speed"] = E->get().speed;
- d["loop"] = E->get().loop;
- Array frames;
- for (int i = 0; i < E->get().frames.size(); i++) {
- frames.push_back(E->get().frames[i]);
- }
- d["frames"] = frames;
- anims.push_back(d);
- }
-
- return anims;
-}
-
-void SpriteFrames::_set_animations(const Array &p_animations) {
- animations.clear();
- for (int i = 0; i < p_animations.size(); i++) {
- Dictionary d = p_animations[i];
-
- ERR_CONTINUE(!d.has("name"));
- ERR_CONTINUE(!d.has("speed"));
- ERR_CONTINUE(!d.has("loop"));
- ERR_CONTINUE(!d.has("frames"));
-
- Anim anim;
- anim.speed = d["speed"];
- anim.loop = d["loop"];
- Array frames = d["frames"];
- for (int j = 0; j < frames.size(); j++) {
- RES res = frames[j];
- anim.frames.push_back(res);
- }
-
- animations[d["name"]] = anim;
- }
-}
-
-void SpriteFrames::_bind_methods() {
- ClassDB::bind_method(D_METHOD("add_animation", "anim"), &SpriteFrames::add_animation);
- ClassDB::bind_method(D_METHOD("has_animation", "anim"), &SpriteFrames::has_animation);
- ClassDB::bind_method(D_METHOD("remove_animation", "anim"), &SpriteFrames::remove_animation);
- ClassDB::bind_method(D_METHOD("rename_animation", "anim", "newname"), &SpriteFrames::rename_animation);
-
- ClassDB::bind_method(D_METHOD("get_animation_names"), &SpriteFrames::get_animation_names);
-
- ClassDB::bind_method(D_METHOD("set_animation_speed", "anim", "speed"), &SpriteFrames::set_animation_speed);
- ClassDB::bind_method(D_METHOD("get_animation_speed", "anim"), &SpriteFrames::get_animation_speed);
-
- ClassDB::bind_method(D_METHOD("set_animation_loop", "anim", "loop"), &SpriteFrames::set_animation_loop);
- ClassDB::bind_method(D_METHOD("get_animation_loop", "anim"), &SpriteFrames::get_animation_loop);
-
- ClassDB::bind_method(D_METHOD("add_frame", "anim", "frame", "at_position"), &SpriteFrames::add_frame, DEFVAL(-1));
- ClassDB::bind_method(D_METHOD("get_frame_count", "anim"), &SpriteFrames::get_frame_count);
- ClassDB::bind_method(D_METHOD("get_frame", "anim", "idx"), &SpriteFrames::get_frame);
- ClassDB::bind_method(D_METHOD("set_frame", "anim", "idx", "txt"), &SpriteFrames::set_frame);
- ClassDB::bind_method(D_METHOD("remove_frame", "anim", "idx"), &SpriteFrames::remove_frame);
- ClassDB::bind_method(D_METHOD("clear", "anim"), &SpriteFrames::clear);
- ClassDB::bind_method(D_METHOD("clear_all"), &SpriteFrames::clear_all);
-
- ClassDB::bind_method(D_METHOD("_set_frames"), &SpriteFrames::_set_frames);
- ClassDB::bind_method(D_METHOD("_get_frames"), &SpriteFrames::_get_frames);
-
- ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "frames", PROPERTY_HINT_NONE, "", 0), "_set_frames", "_get_frames"); //compatibility
-
- ClassDB::bind_method(D_METHOD("_set_animations"), &SpriteFrames::_set_animations);
- ClassDB::bind_method(D_METHOD("_get_animations"), &SpriteFrames::_get_animations);
-
- ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "animations", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_animations", "_get_animations"); //compatibility
-}
-
-SpriteFrames::SpriteFrames() {
- add_animation(SceneStringNames::get_singleton()->_default);
-}
-
void AnimatedSprite2D::_validate_property(PropertyInfo &property) const {
if (!frames.is_valid()) {
return;
@@ -590,6 +382,7 @@ bool AnimatedSprite2D::_is_playing() const {
}
void AnimatedSprite2D::play(const StringName &p_animation, const bool p_backwards) {
+ ERR_FAIL_NULL_MSG(frames, "Can't play AnimatedSprite2D without a valid SpriteFrames resource.");
backwards = p_backwards;
if (p_animation) {
diff --git a/scene/2d/animated_sprite_2d.h b/scene/2d/animated_sprite_2d.h
index 5e53a401e2..14ecb18866 100644
--- a/scene/2d/animated_sprite_2d.h
+++ b/scene/2d/animated_sprite_2d.h
@@ -32,74 +32,9 @@
#define ANIMATED_SPRITE_2D_H
#include "scene/2d/node_2d.h"
+#include "scene/resources/sprite_frames.h"
#include "scene/resources/texture.h"
-class SpriteFrames : public Resource {
- GDCLASS(SpriteFrames, Resource);
-
- struct Anim {
- float speed = 5.0;
- bool loop = true;
- Vector<Ref<Texture2D>> frames;
- };
-
- Map<StringName, Anim> animations;
-
- Array _get_frames() const;
- void _set_frames(const Array &p_frames);
-
- Array _get_animations() const;
- void _set_animations(const Array &p_animations);
-
- Vector<String> _get_animation_list() const;
-
-protected:
- static void _bind_methods();
-
-public:
- void add_animation(const StringName &p_anim);
- bool has_animation(const StringName &p_anim) const;
- void remove_animation(const StringName &p_anim);
- void rename_animation(const StringName &p_prev, const StringName &p_next);
-
- void get_animation_list(List<StringName> *r_animations) const;
- Vector<String> get_animation_names() const;
-
- void set_animation_speed(const StringName &p_anim, float p_fps);
- float get_animation_speed(const StringName &p_anim) const;
-
- void set_animation_loop(const StringName &p_anim, bool p_loop);
- bool get_animation_loop(const StringName &p_anim) const;
-
- void add_frame(const StringName &p_anim, const Ref<Texture2D> &p_frame, int p_at_pos = -1);
- int get_frame_count(const StringName &p_anim) const;
- _FORCE_INLINE_ Ref<Texture2D> get_frame(const StringName &p_anim, int p_idx) const {
- const Map<StringName, Anim>::Element *E = animations.find(p_anim);
- ERR_FAIL_COND_V_MSG(!E, Ref<Texture2D>(), "Animation '" + String(p_anim) + "' doesn't exist.");
- ERR_FAIL_COND_V(p_idx < 0, Ref<Texture2D>());
- if (p_idx >= E->get().frames.size()) {
- return Ref<Texture2D>();
- }
-
- return E->get().frames[p_idx];
- }
-
- void set_frame(const StringName &p_anim, int p_idx, const Ref<Texture2D> &p_frame) {
- Map<StringName, Anim>::Element *E = animations.find(p_anim);
- ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist.");
- ERR_FAIL_COND(p_idx < 0);
- if (p_idx >= E->get().frames.size()) {
- return;
- }
- E->get().frames.write[p_idx] = p_frame;
- }
- void remove_frame(const StringName &p_anim, int p_idx);
- void clear(const StringName &p_anim);
- void clear_all();
-
- SpriteFrames();
-};
-
class AnimatedSprite2D : public Node2D {
GDCLASS(AnimatedSprite2D, Node2D);
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp
index c5ac4e1a05..01045502d5 100644
--- a/scene/2d/camera_2d.cpp
+++ b/scene/2d/camera_2d.cpp
@@ -157,7 +157,7 @@ Transform2D Camera2D::get_camera_transform() {
}
if (smoothing_enabled && !Engine::get_singleton()->is_editor_hint()) {
- float c = smoothing * (process_callback == CAMERA2D_PROCESS_PHYSICS ? get_physics_process_delta_time() : get_process_delta_time());
+ real_t c = smoothing * (process_callback == CAMERA2D_PROCESS_PHYSICS ? get_physics_process_delta_time() : get_process_delta_time());
smoothed_camera_pos = ((camera_pos - smoothed_camera_pos) * c) + smoothed_camera_pos;
ret_camera_pos = smoothed_camera_pos;
//camera_pos=camera_pos*(1.0-smoothing)+new_camera_pos*smoothing;
@@ -172,7 +172,7 @@ Transform2D Camera2D::get_camera_transform() {
Point2 screen_offset = (anchor_mode == ANCHOR_MODE_DRAG_CENTER ? (screen_size * 0.5 * zoom) : Point2());
- float angle = get_global_transform().get_rotation();
+ real_t angle = get_global_transform().get_rotation();
if (rotating) {
screen_offset = screen_offset.rotated(angle);
}
@@ -271,7 +271,7 @@ void Camera2D::_notification(int p_what) {
if (screen_drawing_enabled) {
Color area_axis_color(0.5, 0.42, 0.87, 0.63);
- float area_axis_width = 1;
+ real_t area_axis_width = 1;
if (is_current()) {
area_axis_width = 3;
area_axis_color.a = 0.83;
@@ -296,7 +296,7 @@ void Camera2D::_notification(int p_what) {
if (limit_drawing_enabled) {
Color limit_drawing_color(1, 1, 0, 0.63);
- float limit_drawing_width = 1;
+ real_t limit_drawing_width = 1;
if (is_current()) {
limit_drawing_color.a = 0.83;
limit_drawing_width = 3;
@@ -318,7 +318,7 @@ void Camera2D::_notification(int p_what) {
if (margin_drawing_enabled) {
Color margin_drawing_color(0, 1, 1, 0.63);
- float margin_drawing_width = 1;
+ real_t margin_drawing_width = 1;
if (is_current()) {
margin_drawing_width = 3;
margin_drawing_color.a = 0.83;
@@ -446,13 +446,13 @@ bool Camera2D::is_limit_smoothing_enabled() const {
return limit_smoothing_enabled;
}
-void Camera2D::set_drag_margin(Side p_side, float p_drag_margin) {
+void Camera2D::set_drag_margin(Side p_side, real_t p_drag_margin) {
ERR_FAIL_INDEX((int)p_side, 4);
drag_margin[p_side] = p_drag_margin;
update();
}
-float Camera2D::get_drag_margin(Side p_side) const {
+real_t Camera2D::get_drag_margin(Side p_side) const {
ERR_FAIL_INDEX_V((int)p_side, 4, 0);
return drag_margin[p_side];
}
@@ -494,7 +494,7 @@ void Camera2D::align() {
_update_scroll();
}
-void Camera2D::set_follow_smoothing(float p_speed) {
+void Camera2D::set_follow_smoothing(real_t p_speed) {
smoothing = p_speed;
if (smoothing > 0 && !(is_inside_tree() && Engine::get_singleton()->is_editor_hint())) {
set_process_internal(true);
@@ -503,7 +503,7 @@ void Camera2D::set_follow_smoothing(float p_speed) {
}
}
-float Camera2D::get_follow_smoothing() const {
+real_t Camera2D::get_follow_smoothing() const {
return smoothing;
}
@@ -535,7 +535,7 @@ bool Camera2D::is_drag_vertical_enabled() const {
return drag_vertical_enabled;
}
-void Camera2D::set_drag_vertical_offset(float p_offset) {
+void Camera2D::set_drag_vertical_offset(real_t p_offset) {
drag_vertical_offset = p_offset;
drag_vertical_offset_changed = true;
Point2 old_smoothed_camera_pos = smoothed_camera_pos;
@@ -543,11 +543,11 @@ void Camera2D::set_drag_vertical_offset(float p_offset) {
smoothed_camera_pos = old_smoothed_camera_pos;
}
-float Camera2D::get_drag_vertical_offset() const {
+real_t Camera2D::get_drag_vertical_offset() const {
return drag_vertical_offset;
}
-void Camera2D::set_drag_horizontal_offset(float p_offset) {
+void Camera2D::set_drag_horizontal_offset(real_t p_offset) {
drag_horizontal_offset = p_offset;
drag_horizontal_offset_changed = true;
Point2 old_smoothed_camera_pos = smoothed_camera_pos;
@@ -555,11 +555,11 @@ void Camera2D::set_drag_horizontal_offset(float p_offset) {
smoothed_camera_pos = old_smoothed_camera_pos;
}
-float Camera2D::get_drag_horizontal_offset() const {
+real_t Camera2D::get_drag_horizontal_offset() const {
return drag_horizontal_offset;
}
-void Camera2D::_set_old_smoothing(float p_enable) {
+void Camera2D::_set_old_smoothing(real_t p_enable) {
//compatibility
if (p_enable > 0) {
smoothing_enabled = true;
@@ -569,6 +569,7 @@ void Camera2D::_set_old_smoothing(float p_enable) {
void Camera2D::set_enable_follow_smoothing(bool p_enabled) {
smoothing_enabled = p_enabled;
+ notify_property_list_changed();
}
bool Camera2D::is_follow_smoothing_enabled() const {
@@ -642,6 +643,12 @@ bool Camera2D::is_margin_drawing_enabled() const {
return margin_drawing_enabled;
}
+void Camera2D::_validate_property(PropertyInfo &property) const {
+ if (!smoothing_enabled && property.name == "smoothing_speed") {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
+ }
+}
+
void Camera2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_offset", "offset"), &Camera2D::set_offset);
ClassDB::bind_method(D_METHOD("get_offset"), &Camera2D::get_offset);
diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h
index 252d2686fc..7494e526cc 100644
--- a/scene/2d/camera_2d.h
+++ b/scene/2d/camera_2d.h
@@ -65,16 +65,16 @@ protected:
AnchorMode anchor_mode = ANCHOR_MODE_DRAG_CENTER;
bool rotating = false;
bool current = false;
- float smoothing = 5.0;
+ real_t smoothing = 5.0;
bool smoothing_enabled = false;
int limit[4];
bool limit_smoothing_enabled = false;
- float drag_margin[4];
+ real_t drag_margin[4];
bool drag_horizontal_enabled = false;
bool drag_vertical_enabled = false;
- float drag_horizontal_offset = 0.0;
- float drag_vertical_offset = 0.0;
+ real_t drag_horizontal_offset = 0.0;
+ real_t drag_vertical_offset = 0.0;
bool drag_horizontal_offset_changed = false;
bool drag_vertical_offset_changed = false;
@@ -85,7 +85,7 @@ protected:
void _make_current(Object *p_which);
void _set_current(bool p_current);
- void _set_old_smoothing(float p_enable);
+ void _set_old_smoothing(real_t p_enable);
bool screen_drawing_enabled = true;
bool limit_drawing_enabled = false;
@@ -97,8 +97,10 @@ protected:
protected:
virtual Transform2D get_camera_transform();
+
void _notification(int p_what);
static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const override;
public:
void set_offset(const Vector2 &p_offset);
@@ -122,20 +124,20 @@ public:
void set_drag_vertical_enabled(bool p_enabled);
bool is_drag_vertical_enabled() const;
- void set_drag_margin(Side p_side, float p_drag_margin);
- float get_drag_margin(Side p_side) const;
+ void set_drag_margin(Side p_side, real_t p_drag_margin);
+ real_t get_drag_margin(Side p_side) const;
- void set_drag_horizontal_offset(float p_offset);
- float get_drag_horizontal_offset() const;
+ void set_drag_horizontal_offset(real_t p_offset);
+ real_t get_drag_horizontal_offset() const;
- void set_drag_vertical_offset(float p_offset);
- float get_drag_vertical_offset() const;
+ void set_drag_vertical_offset(real_t p_offset);
+ real_t get_drag_vertical_offset() const;
void set_enable_follow_smoothing(bool p_enabled);
bool is_follow_smoothing_enabled() const;
- void set_follow_smoothing(float p_speed);
- float get_follow_smoothing() const;
+ void set_follow_smoothing(real_t p_speed);
+ real_t get_follow_smoothing() const;
void set_process_callback(Camera2DProcessCallback p_mode);
Camera2DProcessCallback get_process_callback() const;
diff --git a/scene/2d/canvas_group.cpp b/scene/2d/canvas_group.cpp
index 0f0e583ea7..ee025b6dfc 100644
--- a/scene/2d/canvas_group.cpp
+++ b/scene/2d/canvas_group.cpp
@@ -30,7 +30,7 @@
#include "canvas_group.h"
-void CanvasGroup::set_fit_margin(float p_fit_margin) {
+void CanvasGroup::set_fit_margin(real_t p_fit_margin) {
ERR_FAIL_COND(p_fit_margin < 0.0);
fit_margin = p_fit_margin;
@@ -39,11 +39,11 @@ void CanvasGroup::set_fit_margin(float p_fit_margin) {
update();
}
-float CanvasGroup::get_fit_margin() const {
+real_t CanvasGroup::get_fit_margin() const {
return fit_margin;
}
-void CanvasGroup::set_clear_margin(float p_clear_margin) {
+void CanvasGroup::set_clear_margin(real_t p_clear_margin) {
ERR_FAIL_COND(p_clear_margin < 0.0);
clear_margin = p_clear_margin;
@@ -52,7 +52,7 @@ void CanvasGroup::set_clear_margin(float p_clear_margin) {
update();
}
-float CanvasGroup::get_clear_margin() const {
+real_t CanvasGroup::get_clear_margin() const {
return clear_margin;
}
diff --git a/scene/2d/canvas_group.h b/scene/2d/canvas_group.h
index cecf7c24f4..b487d7a098 100644
--- a/scene/2d/canvas_group.h
+++ b/scene/2d/canvas_group.h
@@ -35,19 +35,19 @@
class CanvasGroup : public Node2D {
GDCLASS(CanvasGroup, Node2D)
- float fit_margin = 10.0;
- float clear_margin = 10.0;
+ real_t fit_margin = 10.0;
+ real_t clear_margin = 10.0;
bool use_mipmaps = false;
protected:
static void _bind_methods();
public:
- void set_fit_margin(float p_fit_margin);
- float get_fit_margin() const;
+ void set_fit_margin(real_t p_fit_margin);
+ real_t get_fit_margin() const;
- void set_clear_margin(float p_clear_margin);
- float get_clear_margin() const;
+ void set_clear_margin(real_t p_clear_margin);
+ real_t get_clear_margin() const;
void set_use_mipmaps(bool p_use_mipmaps);
bool is_using_mipmaps() const;
diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp
index 48acee1bc4..6a69a4c618 100644
--- a/scene/2d/cpu_particles_2d.cpp
+++ b/scene/2d/cpu_particles_2d.cpp
@@ -78,11 +78,11 @@ void CPUParticles2D::set_pre_process_time(float p_time) {
pre_process_time = p_time;
}
-void CPUParticles2D::set_explosiveness_ratio(float p_ratio) {
+void CPUParticles2D::set_explosiveness_ratio(real_t p_ratio) {
explosiveness_ratio = p_ratio;
}
-void CPUParticles2D::set_randomness_ratio(float p_ratio) {
+void CPUParticles2D::set_randomness_ratio(real_t p_ratio) {
randomness_ratio = p_ratio;
}
@@ -95,7 +95,7 @@ void CPUParticles2D::set_use_local_coordinates(bool p_enable) {
set_notify_transform(!p_enable);
}
-void CPUParticles2D::set_speed_scale(float p_scale) {
+void CPUParticles2D::set_speed_scale(real_t p_scale) {
speed_scale = p_scale;
}
@@ -119,11 +119,11 @@ float CPUParticles2D::get_pre_process_time() const {
return pre_process_time;
}
-float CPUParticles2D::get_explosiveness_ratio() const {
+real_t CPUParticles2D::get_explosiveness_ratio() const {
return explosiveness_ratio;
}
-float CPUParticles2D::get_randomness_ratio() const {
+real_t CPUParticles2D::get_randomness_ratio() const {
return randomness_ratio;
}
@@ -135,7 +135,7 @@ bool CPUParticles2D::get_use_local_coordinates() const {
return local_coords;
}
-float CPUParticles2D::get_speed_scale() const {
+real_t CPUParticles2D::get_speed_scale() const {
return speed_scale;
}
@@ -289,39 +289,39 @@ Vector2 CPUParticles2D::get_direction() const {
return direction;
}
-void CPUParticles2D::set_spread(float p_spread) {
+void CPUParticles2D::set_spread(real_t p_spread) {
spread = p_spread;
}
-float CPUParticles2D::get_spread() const {
+real_t CPUParticles2D::get_spread() const {
return spread;
}
-void CPUParticles2D::set_param(Parameter p_param, float p_value) {
+void CPUParticles2D::set_param(Parameter p_param, real_t p_value) {
ERR_FAIL_INDEX(p_param, PARAM_MAX);
parameters[p_param] = p_value;
}
-float CPUParticles2D::get_param(Parameter p_param) const {
+real_t CPUParticles2D::get_param(Parameter p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return parameters[p_param];
}
-void CPUParticles2D::set_param_randomness(Parameter p_param, float p_value) {
+void CPUParticles2D::set_param_randomness(Parameter p_param, real_t p_value) {
ERR_FAIL_INDEX(p_param, PARAM_MAX);
randomness[p_param] = p_value;
}
-float CPUParticles2D::get_param_randomness(Parameter p_param) const {
+real_t CPUParticles2D::get_param_randomness(Parameter p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return randomness[p_param];
}
-static void _adjust_curve_range(const Ref<Curve> &p_curve, float p_min, float p_max) {
+static void _adjust_curve_range(const Ref<Curve> &p_curve, real_t p_min, real_t p_max) {
Ref<Curve> curve = p_curve;
if (!curve.is_valid()) {
return;
@@ -413,7 +413,7 @@ void CPUParticles2D::set_emission_shape(EmissionShape p_shape) {
notify_property_list_changed();
}
-void CPUParticles2D::set_emission_sphere_radius(float p_radius) {
+void CPUParticles2D::set_emission_sphere_radius(real_t p_radius) {
emission_sphere_radius = p_radius;
}
@@ -433,7 +433,7 @@ void CPUParticles2D::set_emission_colors(const Vector<Color> &p_colors) {
emission_colors = p_colors;
}
-float CPUParticles2D::get_emission_sphere_radius() const {
+real_t CPUParticles2D::get_emission_sphere_radius() const {
return emission_sphere_radius;
}
@@ -502,7 +502,7 @@ static uint32_t idhash(uint32_t x) {
return x;
}
-static float rand_from_seed(uint32_t &seed) {
+static real_t rand_from_seed(uint32_t &seed) {
int k;
int s = int(seed);
if (s == 0) {
@@ -514,7 +514,7 @@ static float rand_from_seed(uint32_t &seed) {
s += 2147483647;
}
seed = uint32_t(s);
- return float(seed % uint32_t(65536)) / 65535.0;
+ return (seed % uint32_t(65536)) / 65535.0;
}
void CPUParticles2D::_update_internal() {
@@ -625,7 +625,7 @@ void CPUParticles2D::_particles_process(float p_delta) {
// The phase is a ratio between 0 (birth) and 1 (end of life) for each particle.
// While we use time in tests later on, for randomness we use the phase as done in the
// original shader code, and we later multiply by lifetime to get the time.
- float restart_phase = float(i) / float(pcount);
+ real_t restart_phase = real_t(i) / real_t(pcount);
if (randomness_ratio > 0.0) {
uint32_t seed = cycle;
@@ -634,8 +634,8 @@ void CPUParticles2D::_particles_process(float p_delta) {
}
seed *= uint32_t(pcount);
seed += uint32_t(i);
- float random = float(idhash(seed) % uint32_t(65536)) / 65536.0;
- restart_phase += randomness_ratio * random * 1.0 / float(pcount);
+ real_t random = (idhash(seed) % uint32_t(65536)) / 65536.0;
+ restart_phase += randomness_ratio * random * 1.0 / pcount;
}
restart_phase *= (1.0 - explosiveness_ratio);
@@ -680,17 +680,17 @@ void CPUParticles2D::_particles_process(float p_delta) {
}
p.active = true;
- /*float tex_linear_velocity = 0;
+ /*real_t tex_linear_velocity = 0;
if (curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(0);
}*/
- float tex_angle = 0.0;
+ real_t tex_angle = 0.0;
if (curve_parameters[PARAM_ANGLE].is_valid()) {
tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv);
}
- float tex_anim_offset = 0.0;
+ real_t tex_anim_offset = 0.0;
if (curve_parameters[PARAM_ANGLE].is_valid()) {
tex_anim_offset = curve_parameters[PARAM_ANGLE]->interpolate(tv);
}
@@ -702,16 +702,16 @@ void CPUParticles2D::_particles_process(float p_delta) {
p.hue_rot_rand = Math::randf();
p.anim_offset_rand = Math::randf();
- float angle1_rad = Math::atan2(direction.y, direction.x) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * spread);
+ real_t angle1_rad = Math::atan2(direction.y, direction.x) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * spread);
Vector2 rot = Vector2(Math::cos(angle1_rad), Math::sin(angle1_rad));
- p.velocity = rot * parameters[PARAM_INITIAL_LINEAR_VELOCITY] * Math::lerp(1.0f, float(Math::randf()), randomness[PARAM_INITIAL_LINEAR_VELOCITY]);
+ p.velocity = rot * parameters[PARAM_INITIAL_LINEAR_VELOCITY] * Math::lerp((real_t)1.0, real_t(Math::randf()), randomness[PARAM_INITIAL_LINEAR_VELOCITY]);
- float base_angle = (parameters[PARAM_ANGLE] + tex_angle) * Math::lerp(1.0f, p.angle_rand, randomness[PARAM_ANGLE]);
+ real_t base_angle = (parameters[PARAM_ANGLE] + tex_angle) * Math::lerp((real_t)1.0, p.angle_rand, randomness[PARAM_ANGLE]);
p.rotation = Math::deg2rad(base_angle);
p.custom[0] = 0.0; // unused
p.custom[1] = 0.0; // phase [0..1]
- p.custom[2] = (parameters[PARAM_ANIM_OFFSET] + tex_anim_offset) * Math::lerp(1.0f, p.anim_offset_rand, randomness[PARAM_ANIM_OFFSET]); //animation phase [0..1]
+ p.custom[2] = (parameters[PARAM_ANIM_OFFSET] + tex_anim_offset) * Math::lerp((real_t)1.0, p.anim_offset_rand, randomness[PARAM_ANIM_OFFSET]); //animation phase [0..1]
p.custom[3] = 0.0;
p.transform = Transform2D();
p.time = 0;
@@ -723,8 +723,8 @@ void CPUParticles2D::_particles_process(float p_delta) {
//do none
} break;
case EMISSION_SHAPE_SPHERE: {
- float s = Math::randf(), t = Math_TAU * Math::randf();
- float radius = emission_sphere_radius * Math::sqrt(1.0 - s * s);
+ real_t s = Math::randf(), t = Math_TAU * Math::randf();
+ real_t radius = emission_sphere_radius * Math::sqrt(1.0 - s * s);
p.transform[2] = Vector2(Math::cos(t), Math::sin(t)) * radius;
} break;
case EMISSION_SHAPE_RECTANGLE: {
@@ -775,51 +775,51 @@ void CPUParticles2D::_particles_process(float p_delta) {
p.custom[1] = p.time / lifetime;
tv = p.time / p.lifetime;
- float tex_linear_velocity = 0.0;
+ real_t tex_linear_velocity = 0.0;
if (curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(tv);
}
- float tex_orbit_velocity = 0.0;
+ real_t tex_orbit_velocity = 0.0;
if (curve_parameters[PARAM_ORBIT_VELOCITY].is_valid()) {
tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(tv);
}
- float tex_angular_velocity = 0.0;
+ real_t tex_angular_velocity = 0.0;
if (curve_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) {
tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(tv);
}
- float tex_linear_accel = 0.0;
+ real_t tex_linear_accel = 0.0;
if (curve_parameters[PARAM_LINEAR_ACCEL].is_valid()) {
tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(tv);
}
- float tex_tangential_accel = 0.0;
+ real_t tex_tangential_accel = 0.0;
if (curve_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) {
tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(tv);
}
- float tex_radial_accel = 0.0;
+ real_t tex_radial_accel = 0.0;
if (curve_parameters[PARAM_RADIAL_ACCEL].is_valid()) {
tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(tv);
}
- float tex_damping = 0.0;
+ real_t tex_damping = 0.0;
if (curve_parameters[PARAM_DAMPING].is_valid()) {
tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(tv);
}
- float tex_angle = 0.0;
+ real_t tex_angle = 0.0;
if (curve_parameters[PARAM_ANGLE].is_valid()) {
tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv);
}
- float tex_anim_speed = 0.0;
+ real_t tex_anim_speed = 0.0;
if (curve_parameters[PARAM_ANIM_SPEED].is_valid()) {
tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(tv);
}
- float tex_anim_offset = 0.0;
+ real_t tex_anim_offset = 0.0;
if (curve_parameters[PARAM_ANIM_OFFSET].is_valid()) {
tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(tv);
}
@@ -828,20 +828,20 @@ void CPUParticles2D::_particles_process(float p_delta) {
Vector2 pos = p.transform[2];
//apply linear acceleration
- force += p.velocity.length() > 0.0 ? p.velocity.normalized() * (parameters[PARAM_LINEAR_ACCEL] + tex_linear_accel) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_LINEAR_ACCEL]) : Vector2();
+ force += p.velocity.length() > 0.0 ? p.velocity.normalized() * (parameters[PARAM_LINEAR_ACCEL] + tex_linear_accel) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed), randomness[PARAM_LINEAR_ACCEL]) : Vector2();
//apply radial acceleration
Vector2 org = emission_xform[2];
Vector2 diff = pos - org;
- force += diff.length() > 0.0 ? diff.normalized() * (parameters[PARAM_RADIAL_ACCEL] + tex_radial_accel) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_RADIAL_ACCEL]) : Vector2();
+ force += diff.length() > 0.0 ? diff.normalized() * (parameters[PARAM_RADIAL_ACCEL] + tex_radial_accel) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed), randomness[PARAM_RADIAL_ACCEL]) : Vector2();
//apply tangential acceleration;
Vector2 yx = Vector2(diff.y, diff.x);
- force += yx.length() > 0.0 ? (yx * Vector2(-1.0, 1.0)).normalized() * ((parameters[PARAM_TANGENTIAL_ACCEL] + tex_tangential_accel) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_TANGENTIAL_ACCEL])) : Vector2();
+ force += yx.length() > 0.0 ? (yx * Vector2(-1.0, 1.0)).normalized() * ((parameters[PARAM_TANGENTIAL_ACCEL] + tex_tangential_accel) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed), randomness[PARAM_TANGENTIAL_ACCEL])) : Vector2();
//apply attractor forces
p.velocity += force * local_delta;
//orbit velocity
- float orbit_amount = (parameters[PARAM_ORBIT_VELOCITY] + tex_orbit_velocity) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_ORBIT_VELOCITY]);
+ real_t orbit_amount = (parameters[PARAM_ORBIT_VELOCITY] + tex_orbit_velocity) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed), randomness[PARAM_ORBIT_VELOCITY]);
if (orbit_amount != 0.0) {
- float ang = orbit_amount * local_delta * Math_TAU;
+ real_t ang = orbit_amount * local_delta * Math_TAU;
// Not sure why the ParticlesMaterial code uses a clockwise rotation matrix,
// but we use -ang here to reproduce its behavior.
Transform2D rot = Transform2D(-ang, Vector2());
@@ -853,8 +853,8 @@ void CPUParticles2D::_particles_process(float p_delta) {
}
if (parameters[PARAM_DAMPING] + tex_damping > 0.0) {
- float v = p.velocity.length();
- float damp = (parameters[PARAM_DAMPING] + tex_damping) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_DAMPING]);
+ real_t v = p.velocity.length();
+ real_t damp = (parameters[PARAM_DAMPING] + tex_damping) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed), randomness[PARAM_DAMPING]);
v -= damp * local_delta;
if (v < 0.0) {
p.velocity = Vector2();
@@ -862,28 +862,28 @@ void CPUParticles2D::_particles_process(float p_delta) {
p.velocity = p.velocity.normalized() * v;
}
}
- float base_angle = (parameters[PARAM_ANGLE] + tex_angle) * Math::lerp(1.0f, p.angle_rand, randomness[PARAM_ANGLE]);
- base_angle += p.custom[1] * lifetime * (parameters[PARAM_ANGULAR_VELOCITY] + tex_angular_velocity) * Math::lerp(1.0f, rand_from_seed(alt_seed) * 2.0f - 1.0f, randomness[PARAM_ANGULAR_VELOCITY]);
+ real_t base_angle = (parameters[PARAM_ANGLE] + tex_angle) * Math::lerp((real_t)1.0, p.angle_rand, randomness[PARAM_ANGLE]);
+ base_angle += p.custom[1] * lifetime * (parameters[PARAM_ANGULAR_VELOCITY] + tex_angular_velocity) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed) * 2.0f - 1.0f, randomness[PARAM_ANGULAR_VELOCITY]);
p.rotation = Math::deg2rad(base_angle); //angle
- float animation_phase = (parameters[PARAM_ANIM_OFFSET] + tex_anim_offset) * Math::lerp(1.0f, p.anim_offset_rand, randomness[PARAM_ANIM_OFFSET]) + p.custom[1] * (parameters[PARAM_ANIM_SPEED] + tex_anim_speed) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_ANIM_SPEED]);
+ real_t animation_phase = (parameters[PARAM_ANIM_OFFSET] + tex_anim_offset) * Math::lerp((real_t)1.0, p.anim_offset_rand, randomness[PARAM_ANIM_OFFSET]) + p.custom[1] * (parameters[PARAM_ANIM_SPEED] + tex_anim_speed) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed), randomness[PARAM_ANIM_SPEED]);
p.custom[2] = animation_phase;
}
//apply color
//apply hue rotation
- float tex_scale = 1.0;
+ real_t tex_scale = 1.0;
if (curve_parameters[PARAM_SCALE].is_valid()) {
tex_scale = curve_parameters[PARAM_SCALE]->interpolate(tv);
}
- float tex_hue_variation = 0.0;
+ real_t tex_hue_variation = 0.0;
if (curve_parameters[PARAM_HUE_VARIATION].is_valid()) {
tex_hue_variation = curve_parameters[PARAM_HUE_VARIATION]->interpolate(tv);
}
- float hue_rot_angle = (parameters[PARAM_HUE_VARIATION] + tex_hue_variation) * Math_TAU * Math::lerp(1.0f, p.hue_rot_rand * 2.0f - 1.0f, randomness[PARAM_HUE_VARIATION]);
- float hue_rot_c = Math::cos(hue_rot_angle);
- float hue_rot_s = Math::sin(hue_rot_angle);
+ real_t hue_rot_angle = (parameters[PARAM_HUE_VARIATION] + tex_hue_variation) * Math_TAU * Math::lerp(1.0f, p.hue_rot_rand * 2.0f - 1.0f, randomness[PARAM_HUE_VARIATION]);
+ real_t hue_rot_c = Math::cos(hue_rot_angle);
+ real_t hue_rot_s = Math::sin(hue_rot_angle);
Basis hue_rot_mat;
{
@@ -921,7 +921,7 @@ void CPUParticles2D::_particles_process(float p_delta) {
}
//scale by scale
- float base_scale = tex_scale * Math::lerp(parameters[PARAM_SCALE], 1.0f, p.scale_rand * randomness[PARAM_SCALE]);
+ real_t base_scale = tex_scale * Math::lerp(parameters[PARAM_SCALE], (real_t)1.0, p.scale_rand * randomness[PARAM_SCALE]);
if (base_scale < 0.000001) {
base_scale = 0.000001;
}
diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h
index 7ee165b3e1..ab04ee4a57 100644
--- a/scene/2d/cpu_particles_2d.h
+++ b/scene/2d/cpu_particles_2d.h
@@ -84,13 +84,13 @@ private:
Transform2D transform;
Color color;
float custom[4] = {};
- float rotation = 0.0;
+ real_t rotation = 0.0;
Vector2 velocity;
bool active = false;
- float angle_rand = 0.0;
- float scale_rand = 0.0;
- float hue_rot_rand = 0.0;
- float anim_offset_rand = 0.0;
+ real_t angle_rand = 0.0;
+ real_t scale_rand = 0.0;
+ real_t hue_rot_rand = 0.0;
+ real_t anim_offset_rand = 0.0;
float time = 0.0;
float lifetime = 0.0;
Color base_color;
@@ -133,10 +133,10 @@ private:
float lifetime = 1.0;
float pre_process_time = 0.0;
- float explosiveness_ratio = 0.0;
- float randomness_ratio = 0.0;
- float lifetime_randomness = 0.0;
- float speed_scale = 1.0;
+ real_t explosiveness_ratio = 0.0;
+ real_t randomness_ratio = 0.0;
+ real_t lifetime_randomness = 0.0;
+ real_t speed_scale = 1.0;
bool local_coords;
int fixed_fps = 0;
bool fractional_delta = true;
@@ -150,10 +150,10 @@ private:
////////
Vector2 direction = Vector2(1, 0);
- float spread = 45.0;
+ real_t spread = 45.0;
- float parameters[PARAM_MAX];
- float randomness[PARAM_MAX];
+ real_t parameters[PARAM_MAX];
+ real_t randomness[PARAM_MAX];
Ref<Curve> curve_parameters[PARAM_MAX];
Color color;
@@ -162,7 +162,7 @@ private:
bool particle_flags[PARTICLE_FLAG_MAX];
EmissionShape emission_shape = EMISSION_SHAPE_POINT;
- float emission_sphere_radius = 1.0;
+ real_t emission_sphere_radius = 1.0;
Vector2 emission_rect_extents = Vector2(1, 1);
Vector<Vector2> emission_points;
Vector<Vector2> emission_normals;
@@ -196,24 +196,24 @@ public:
void set_lifetime(float p_lifetime);
void set_one_shot(bool p_one_shot);
void set_pre_process_time(float p_time);
- void set_explosiveness_ratio(float p_ratio);
- void set_randomness_ratio(float p_ratio);
+ void set_explosiveness_ratio(real_t p_ratio);
+ void set_randomness_ratio(real_t p_ratio);
void set_lifetime_randomness(float p_random);
void set_visibility_aabb(const Rect2 &p_aabb);
void set_use_local_coordinates(bool p_enable);
- void set_speed_scale(float p_scale);
+ void set_speed_scale(real_t p_scale);
bool is_emitting() const;
int get_amount() const;
float get_lifetime() const;
bool get_one_shot() const;
float get_pre_process_time() const;
- float get_explosiveness_ratio() const;
- float get_randomness_ratio() const;
+ real_t get_explosiveness_ratio() const;
+ real_t get_randomness_ratio() const;
float get_lifetime_randomness() const;
Rect2 get_visibility_aabb() const;
bool get_use_local_coordinates() const;
- float get_speed_scale() const;
+ real_t get_speed_scale() const;
void set_fixed_fps(int p_count);
int get_fixed_fps() const;
@@ -235,14 +235,14 @@ public:
void set_direction(Vector2 p_direction);
Vector2 get_direction() const;
- void set_spread(float p_spread);
- float get_spread() const;
+ void set_spread(real_t p_spread);
+ real_t get_spread() const;
- void set_param(Parameter p_param, float p_value);
- float get_param(Parameter p_param) const;
+ void set_param(Parameter p_param, real_t p_value);
+ real_t get_param(Parameter p_param) const;
- void set_param_randomness(Parameter p_param, float p_value);
- float get_param_randomness(Parameter p_param) const;
+ void set_param_randomness(Parameter p_param, real_t p_value);
+ real_t get_param_randomness(Parameter p_param) const;
void set_param_curve(Parameter p_param, const Ref<Curve> &p_curve);
Ref<Curve> get_param_curve(Parameter p_param) const;
@@ -257,7 +257,7 @@ public:
bool get_particle_flag(ParticleFlags p_particle_flag) const;
void set_emission_shape(EmissionShape p_shape);
- void set_emission_sphere_radius(float p_radius);
+ void set_emission_sphere_radius(real_t p_radius);
void set_emission_rect_extents(Vector2 p_extents);
void set_emission_points(const Vector<Vector2> &p_points);
void set_emission_normals(const Vector<Vector2> &p_normals);
@@ -265,7 +265,7 @@ public:
void set_emission_point_count(int p_count);
EmissionShape get_emission_shape() const;
- float get_emission_sphere_radius() const;
+ real_t get_emission_sphere_radius() const;
Vector2 get_emission_rect_extents() const;
Vector<Vector2> get_emission_points() const;
Vector<Vector2> get_emission_normals() const;
diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp
index 15fcb08422..99e35cad1d 100644
--- a/scene/2d/light_2d.cpp
+++ b/scene/2d/light_2d.cpp
@@ -84,21 +84,21 @@ Color Light2D::get_color() const {
return color;
}
-void Light2D::set_height(float p_height) {
+void Light2D::set_height(real_t p_height) {
height = p_height;
RS::get_singleton()->canvas_light_set_height(canvas_light, height);
}
-float Light2D::get_height() const {
+real_t Light2D::get_height() const {
return height;
}
-void Light2D::set_energy(float p_energy) {
+void Light2D::set_energy(real_t p_energy) {
energy = p_energy;
RS::get_singleton()->canvas_light_set_energy(canvas_light, energy);
}
-float Light2D::get_energy() const {
+real_t Light2D::get_energy() const {
return energy;
}
@@ -159,6 +159,7 @@ int Light2D::get_item_shadow_cull_mask() const {
void Light2D::set_shadow_enabled(bool p_enabled) {
shadow = p_enabled;
RS::get_singleton()->canvas_light_set_shadow_enabled(canvas_light, shadow);
+ notify_property_list_changed();
}
bool Light2D::is_shadow_enabled() const {
@@ -212,15 +213,21 @@ void Light2D::_notification(int p_what) {
}
}
-void Light2D::set_shadow_smooth(float p_amount) {
+void Light2D::set_shadow_smooth(real_t p_amount) {
shadow_smooth = p_amount;
RS::get_singleton()->canvas_light_set_shadow_smooth(canvas_light, shadow_smooth);
}
-float Light2D::get_shadow_smooth() const {
+real_t Light2D::get_shadow_smooth() const {
return shadow_smooth;
}
+void Light2D::_validate_property(PropertyInfo &property) const {
+ if (!shadow && (property.name == "shadow_color" || property.name == "shadow_filter" || property.name == "shadow_filter_smooth" || property.name == "shadow_item_cull_mask")) {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
+ }
+}
+
void Light2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &Light2D::set_enabled);
ClassDB::bind_method(D_METHOD("is_enabled"), &Light2D::is_enabled);
@@ -396,7 +403,7 @@ String PointLight2D::get_configuration_warning() const {
return warning;
}
-void PointLight2D::set_texture_scale(float p_scale) {
+void PointLight2D::set_texture_scale(real_t p_scale) {
_scale = p_scale;
// Avoid having 0 scale values, can lead to errors in physics and rendering.
if (_scale == 0) {
@@ -406,7 +413,7 @@ void PointLight2D::set_texture_scale(float p_scale) {
item_rect_changed();
}
-float PointLight2D::get_texture_scale() const {
+real_t PointLight2D::get_texture_scale() const {
return _scale;
}
@@ -432,12 +439,12 @@ PointLight2D::PointLight2D() {
//////////
-void DirectionalLight2D::set_max_distance(float p_distance) {
+void DirectionalLight2D::set_max_distance(real_t p_distance) {
max_distance = p_distance;
RS::get_singleton()->canvas_light_set_directional_distance(_get_light(), max_distance);
}
-float DirectionalLight2D::get_max_distance() const {
+real_t DirectionalLight2D::get_max_distance() const {
return max_distance;
}
diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h
index 4279baf15b..ae6cf6d0a0 100644
--- a/scene/2d/light_2d.h
+++ b/scene/2d/light_2d.h
@@ -57,15 +57,15 @@ private:
bool shadow = false;
Color color = Color(1, 1, 1);
Color shadow_color = Color(0, 0, 0, 0);
- float height = 0.0;
- float energy = 1.0;
+ real_t height = 0.0;
+ real_t energy = 1.0;
int z_min = -1024;
int z_max = 1024;
int layer_min = 0;
int layer_max = 0;
int item_mask = 1;
int item_shadow_mask = 1;
- float shadow_smooth = 0.0;
+ real_t shadow_smooth = 0.0;
Ref<Texture2D> texture;
Vector2 texture_offset;
ShadowFilter shadow_filter = SHADOW_FILTER_NONE;
@@ -77,6 +77,7 @@ protected:
_FORCE_INLINE_ RID _get_light() const { return canvas_light; }
void _notification(int p_what);
static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const override;
public:
void set_enabled(bool p_enabled);
@@ -88,11 +89,11 @@ public:
void set_color(const Color &p_color);
Color get_color() const;
- void set_height(float p_height);
- float get_height() const;
+ void set_height(real_t p_height);
+ real_t get_height() const;
- void set_energy(float p_energy);
- float get_energy() const;
+ void set_energy(real_t p_energy);
+ real_t get_energy() const;
void set_z_range_min(int p_min_z);
int get_z_range_min() const;
@@ -121,8 +122,8 @@ public:
void set_shadow_color(const Color &p_shadow_color);
Color get_shadow_color() const;
- void set_shadow_smooth(float p_amount);
- float get_shadow_smooth() const;
+ void set_shadow_smooth(real_t p_amount);
+ real_t get_shadow_smooth() const;
void set_blend_mode(BlendMode p_mode);
BlendMode get_blend_mode() const;
@@ -138,7 +139,7 @@ class PointLight2D : public Light2D {
GDCLASS(PointLight2D, Light2D);
private:
- float _scale = 1.0;
+ real_t _scale = 1.0;
Ref<Texture2D> texture;
Vector2 texture_offset;
@@ -165,8 +166,8 @@ public:
void set_texture_offset(const Vector2 &p_offset);
Vector2 get_texture_offset() const;
- void set_texture_scale(float p_scale);
- float get_texture_scale() const;
+ void set_texture_scale(real_t p_scale);
+ real_t get_texture_scale() const;
String get_configuration_warning() const override;
@@ -176,14 +177,14 @@ public:
class DirectionalLight2D : public Light2D {
GDCLASS(DirectionalLight2D, Light2D);
- float max_distance = 10000.0;
+ real_t max_distance = 10000.0;
protected:
static void _bind_methods();
public:
- void set_max_distance(float p_distance);
- float get_max_distance() const;
+ void set_max_distance(real_t p_distance);
+ real_t get_max_distance() const;
DirectionalLight2D();
};
diff --git a/scene/2d/line_builder.cpp b/scene/2d/line_builder.cpp
index 892ccadfda..c478f03356 100644
--- a/scene/2d/line_builder.cpp
+++ b/scene/2d/line_builder.cpp
@@ -375,7 +375,7 @@ void LineBuilder::build() {
}
if (intersection_result != SEGMENT_INTERSECT) {
- // In this case the joint is too corrputed to be re-used,
+ // In this case the joint is too corrupted to be re-used,
// start again the strip with fallback points
strip_begin(pos_up0, pos_down0, color1, uvx1);
}
@@ -485,7 +485,7 @@ void LineBuilder::strip_add_tri(Vector2 up, Orientation orientation) {
if (texture_mode != Line2D::LINE_TEXTURE_NONE) {
// UVs are just one slice of the texture all along
- // (otherwise we can't share the bottom vertice)
+ // (otherwise we can't share the bottom vertex)
uvs.push_back(uvs[_last_index[opposite_orientation]]);
}
@@ -520,7 +520,7 @@ void LineBuilder::strip_add_arc(Vector2 center, float angle_delta, Orientation o
strip_add_tri(rpos, orientation);
}
- // Last arc vertice
+ // Last arc vertex
rpos = center + Vector2(Math::cos(end_angle), Math::sin(end_angle)) * radius;
strip_add_tri(rpos, orientation);
}
@@ -569,7 +569,7 @@ void LineBuilder::new_arc(Vector2 center, Vector2 vbegin, float angle_delta, Col
}
}
- // Last arc vertice
+ // Last arc vertex
Vector2 sc = Vector2(Math::cos(end_angle), Math::sin(end_angle));
rpos = center + sc * radius;
vertices.push_back(rpos);
diff --git a/scene/2d/navigation_2d.cpp b/scene/2d/navigation_2d.cpp
deleted file mode 100644
index bec5ee7984..0000000000
--- a/scene/2d/navigation_2d.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/*************************************************************************/
-/* navigation_2d.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 "navigation_2d.h"
-#include "servers/navigation_server_2d.h"
-
-void Navigation2D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("get_rid"), &Navigation2D::get_rid);
-
- ClassDB::bind_method(D_METHOD("get_simple_path", "start", "end", "optimize"), &Navigation2D::get_simple_path, DEFVAL(true));
- ClassDB::bind_method(D_METHOD("get_closest_point", "to_point"), &Navigation2D::get_closest_point);
- ClassDB::bind_method(D_METHOD("get_closest_point_owner", "to_point"), &Navigation2D::get_closest_point_owner);
-
- ClassDB::bind_method(D_METHOD("set_cell_size", "cell_size"), &Navigation2D::set_cell_size);
- ClassDB::bind_method(D_METHOD("get_cell_size"), &Navigation2D::get_cell_size);
-
- ClassDB::bind_method(D_METHOD("set_edge_connection_margin", "margin"), &Navigation2D::set_edge_connection_margin);
- ClassDB::bind_method(D_METHOD("get_edge_connection_margin"), &Navigation2D::get_edge_connection_margin);
-
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cell_size"), "set_cell_size", "get_cell_size");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "edge_connection_margin"), "set_edge_connection_margin", "get_edge_connection_margin");
-}
-
-void Navigation2D::_notification(int p_what) {
- switch (p_what) {
- case NOTIFICATION_READY: {
- NavigationServer2D::get_singleton()->map_set_active(map, true);
- } break;
- case NOTIFICATION_EXIT_TREE: {
- NavigationServer2D::get_singleton()->map_set_active(map, false);
- } break;
- }
-}
-
-void Navigation2D::set_cell_size(float p_cell_size) {
- cell_size = p_cell_size;
- NavigationServer2D::get_singleton()->map_set_cell_size(map, cell_size);
-}
-
-void Navigation2D::set_edge_connection_margin(float p_edge_connection_margin) {
- edge_connection_margin = p_edge_connection_margin;
- NavigationServer2D::get_singleton()->map_set_edge_connection_margin(map, edge_connection_margin);
-}
-
-Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vector2 &p_end, bool p_optimize) const {
- return NavigationServer2D::get_singleton()->map_get_path(map, p_start, p_end, p_optimize);
-}
-
-Vector2 Navigation2D::get_closest_point(const Vector2 &p_point) const {
- return NavigationServer2D::get_singleton()->map_get_closest_point(map, p_point);
-}
-
-RID Navigation2D::get_closest_point_owner(const Vector2 &p_point) const {
- return NavigationServer2D::get_singleton()->map_get_closest_point_owner(map, p_point);
-}
-
-Navigation2D::Navigation2D() {
- map = NavigationServer2D::get_singleton()->map_create();
- set_cell_size(10); // Ten pixels
- set_edge_connection_margin(100);
-}
-
-Navigation2D::~Navigation2D() {
- NavigationServer2D::get_singleton()->free(map);
-}
diff --git a/scene/2d/navigation_2d.h b/scene/2d/navigation_2d.h
deleted file mode 100644
index 12847e52ac..0000000000
--- a/scene/2d/navigation_2d.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*************************************************************************/
-/* navigation_2d.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). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef NAVIGATION_2D_H
-#define NAVIGATION_2D_H
-
-#include "scene/2d/navigation_region_2d.h"
-#include "scene/2d/node_2d.h"
-
-class Navigation2D : public Node2D {
- GDCLASS(Navigation2D, Node2D);
-
- RID map;
- real_t cell_size;
- real_t edge_connection_margin;
-
-protected:
- static void _bind_methods();
- void _notification(int p_what);
-
-public:
- RID get_rid() const {
- return map;
- }
-
- void set_cell_size(float p_cell_size);
- float get_cell_size() const {
- return cell_size;
- }
-
- void set_edge_connection_margin(float p_edge_connection_margin);
- float get_edge_connection_margin() const {
- return edge_connection_margin;
- }
-
- Vector<Vector2> get_simple_path(const Vector2 &p_start, const Vector2 &p_end, bool p_optimize = true) const;
- Vector2 get_closest_point(const Vector2 &p_point) const;
- RID get_closest_point_owner(const Vector2 &p_point) const;
-
- Navigation2D();
- ~Navigation2D();
-};
-
-#endif // NAVIGATION_2D_H
diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp
index 534e31b1f2..064fcc91a4 100644
--- a/scene/2d/navigation_agent_2d.cpp
+++ b/scene/2d/navigation_agent_2d.cpp
@@ -32,7 +32,6 @@
#include "core/config/engine.h"
#include "core/math/geometry_2d.h"
-#include "scene/2d/navigation_2d.h"
#include "servers/navigation_server_2d.h"
void NavigationAgent2D::_bind_methods() {
@@ -42,9 +41,6 @@ void NavigationAgent2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_radius", "radius"), &NavigationAgent2D::set_radius);
ClassDB::bind_method(D_METHOD("get_radius"), &NavigationAgent2D::get_radius);
- ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationAgent2D::set_navigation_node);
- ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationAgent2D::get_navigation_node);
-
ClassDB::bind_method(D_METHOD("set_neighbor_dist", "neighbor_dist"), &NavigationAgent2D::set_neighbor_dist);
ClassDB::bind_method(D_METHOD("get_neighbor_dist"), &NavigationAgent2D::get_neighbor_dist);
@@ -95,27 +91,10 @@ void NavigationAgent2D::_notification(int p_what) {
NavigationServer2D::get_singleton()->agent_set_callback(agent, this, "_avoidance_done");
- // Search the navigation node and set it
- {
- Navigation2D *nav = nullptr;
- Node *p = get_parent();
- while (p != nullptr) {
- nav = Object::cast_to<Navigation2D>(p);
- if (nav != nullptr) {
- p = nullptr;
- } else {
- p = p->get_parent();
- }
- }
-
- set_navigation(nav);
- }
-
set_physics_process_internal(true);
} break;
case NOTIFICATION_EXIT_TREE: {
agent_parent = nullptr;
- set_navigation(nullptr);
set_physics_process_internal(false);
} break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
@@ -146,23 +125,13 @@ NavigationAgent2D::~NavigationAgent2D() {
agent = RID(); // Pointless
}
-void NavigationAgent2D::set_navigation(Navigation2D *p_nav) {
- if (navigation == p_nav) {
- return; // Pointless
- }
-
- navigation = p_nav;
- NavigationServer2D::get_singleton()->agent_set_map(agent, navigation == nullptr ? RID() : navigation->get_rid());
-}
-
-void NavigationAgent2D::set_navigation_node(Node *p_nav) {
- Navigation2D *nav = Object::cast_to<Navigation2D>(p_nav);
- ERR_FAIL_COND(nav == nullptr);
- set_navigation(nav);
+void NavigationAgent2D::set_navigable_layers(uint32_t p_layers) {
+ navigable_layers = p_layers;
+ update_navigation();
}
-Node *NavigationAgent2D::get_navigation_node() const {
- return Object::cast_to<Node>(navigation);
+uint32_t NavigationAgent2D::get_navigable_layers() const {
+ return navigable_layers;
}
void NavigationAgent2D::set_target_desired_distance(real_t p_dd) {
@@ -287,7 +256,7 @@ void NavigationAgent2D::update_navigation() {
if (agent_parent == nullptr) {
return;
}
- if (navigation == nullptr) {
+ if (!agent_parent->is_inside_tree()) {
return;
}
if (update_frame_id == Engine::get_singleton()->get_physics_frames()) {
@@ -319,7 +288,7 @@ void NavigationAgent2D::update_navigation() {
}
if (reload_path) {
- navigation_path = NavigationServer2D::get_singleton()->map_get_path(navigation->get_rid(), o, target_location, true);
+ navigation_path = NavigationServer2D::get_singleton()->map_get_path(agent_parent->get_world_2d()->get_navigation_map(), o, target_location, true, navigable_layers);
navigation_finished = false;
nav_path_index = 0;
emit_signal("path_changed");
diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation_agent_2d.h
index 6b7da4a5f2..153ede8cec 100644
--- a/scene/2d/navigation_agent_2d.h
+++ b/scene/2d/navigation_agent_2d.h
@@ -35,16 +35,16 @@
#include "scene/main/node.h"
class Node2D;
-class Navigation2D;
class NavigationAgent2D : public Node {
GDCLASS(NavigationAgent2D, Node);
Node2D *agent_parent = nullptr;
- Navigation2D *navigation = nullptr;
RID agent;
+ uint32_t navigable_layers = 1;
+
real_t target_desired_distance = 1.0;
real_t radius;
real_t neighbor_dist;
@@ -74,18 +74,13 @@ public:
NavigationAgent2D();
virtual ~NavigationAgent2D();
- void set_navigation(Navigation2D *p_nav);
- const Navigation2D *get_navigation() const {
- return navigation;
- }
-
- void set_navigation_node(Node *p_nav);
- Node *get_navigation_node() const;
-
RID get_rid() const {
return agent;
}
+ void set_navigable_layers(uint32_t p_layers);
+ uint32_t get_navigable_layers() const;
+
void set_target_desired_distance(real_t p_dd);
real_t get_target_desired_distance() const {
return target_desired_distance;
diff --git a/scene/2d/navigation_obstacle_2d.cpp b/scene/2d/navigation_obstacle_2d.cpp
index 7e1aefe5e2..965e2b6dc1 100644
--- a/scene/2d/navigation_obstacle_2d.cpp
+++ b/scene/2d/navigation_obstacle_2d.cpp
@@ -31,48 +31,31 @@
#include "navigation_obstacle_2d.h"
#include "scene/2d/collision_shape_2d.h"
-#include "scene/2d/navigation_2d.h"
#include "scene/2d/physics_body_2d.h"
#include "servers/navigation_server_2d.h"
void NavigationObstacle2D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationObstacle2D::set_navigation_node);
- ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationObstacle2D::get_navigation_node);
}
void NavigationObstacle2D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_READY: {
- update_agent_shape();
-
- // Search the navigation node and set it
- {
- Navigation2D *nav = nullptr;
- Node *p = get_parent();
- while (p != nullptr) {
- nav = Object::cast_to<Navigation2D>(p);
- if (nav != nullptr) {
- p = nullptr;
- } else {
- p = p->get_parent();
- }
- }
-
- set_navigation(nav);
- }
-
set_physics_process_internal(true);
} break;
case NOTIFICATION_EXIT_TREE: {
- set_navigation(nullptr);
set_physics_process_internal(false);
} break;
+ case NOTIFICATION_PARENTED: {
+ parent_node2d = Object::cast_to<Node2D>(get_parent());
+ update_agent_shape();
+ } break;
+ case NOTIFICATION_UNPARENTED: {
+ parent_node2d = nullptr;
+ } break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
- Node2D *node = Object::cast_to<Node2D>(get_parent());
- if (node) {
- NavigationServer2D::get_singleton()->agent_set_position(agent, node->get_global_transform().get_origin());
+ if (parent_node2d) {
+ NavigationServer2D::get_singleton()->agent_set_position(agent, parent_node2d->get_global_transform().get_origin());
}
-
} break;
}
}
@@ -86,25 +69,6 @@ NavigationObstacle2D::~NavigationObstacle2D() {
agent = RID(); // Pointless
}
-void NavigationObstacle2D::set_navigation(Navigation2D *p_nav) {
- if (navigation == p_nav) {
- return; // Pointless
- }
-
- navigation = p_nav;
- NavigationServer2D::get_singleton()->agent_set_map(agent, navigation == nullptr ? RID() : navigation->get_rid());
-}
-
-void NavigationObstacle2D::set_navigation_node(Node *p_nav) {
- Navigation2D *nav = Object::cast_to<Navigation2D>(p_nav);
- ERR_FAIL_COND(nav == nullptr);
- set_navigation(nav);
-}
-
-Node *NavigationObstacle2D::get_navigation_node() const {
- return Object::cast_to<Node>(navigation);
-}
-
String NavigationObstacle2D::get_configuration_warning() const {
String warning = Node::get_configuration_warning();
@@ -119,40 +83,37 @@ String NavigationObstacle2D::get_configuration_warning() const {
}
void NavigationObstacle2D::update_agent_shape() {
- Node *node = get_parent();
-
- // Estimate the radius of this physics body
- real_t radius = 0.0;
- for (int i(0); i < node->get_child_count(); i++) {
- // For each collision shape
- CollisionShape2D *cs = Object::cast_to<CollisionShape2D>(node->get_child(i));
- if (cs) {
- // Take the distance between the Body center to the shape center
- real_t r = cs->get_transform().get_origin().length();
- if (cs->get_shape().is_valid()) {
- // and add the enclosing shape radius
- r += cs->get_shape()->get_enclosing_radius();
+ if (parent_node2d) {
+ // Estimate the radius of this physics body
+ real_t radius = 0.0;
+ for (int i(0); i < parent_node2d->get_child_count(); i++) {
+ // For each collision shape
+ CollisionShape2D *cs = Object::cast_to<CollisionShape2D>(parent_node2d->get_child(i));
+ if (cs) {
+ // Take the distance between the Body center to the shape center
+ real_t r = cs->get_transform().get_origin().length();
+ if (cs->get_shape().is_valid()) {
+ // and add the enclosing shape radius
+ r += cs->get_shape()->get_enclosing_radius();
+ }
+ Size2 s = cs->get_global_transform().get_scale();
+ r *= MAX(s.x, s.y);
+ // Takes the biggest radius
+ radius = MAX(radius, r);
}
- Size2 s = cs->get_global_transform().get_scale();
- r *= MAX(s.x, s.y);
- // Takes the biggest radius
- radius = MAX(radius, r);
}
- }
- Node2D *node_2d = Object::cast_to<Node2D>(node);
- if (node_2d) {
- Vector2 s = node_2d->get_global_transform().get_scale();
+ Vector2 s = parent_node2d->get_global_transform().get_scale();
radius *= MAX(s.x, s.y);
- }
- if (radius == 0.0) {
- radius = 1.0; // Never a 0 radius
- }
+ if (radius == 0.0) {
+ radius = 1.0; // Never a 0 radius
+ }
- // Initialize the Agent as an object
- NavigationServer2D::get_singleton()->agent_set_neighbor_dist(agent, 0.0);
- NavigationServer2D::get_singleton()->agent_set_max_neighbors(agent, 0);
- NavigationServer2D::get_singleton()->agent_set_time_horizon(agent, 0.0);
- NavigationServer2D::get_singleton()->agent_set_radius(agent, radius);
- NavigationServer2D::get_singleton()->agent_set_max_speed(agent, 0.0);
+ // Initialize the Agent as an object
+ NavigationServer2D::get_singleton()->agent_set_neighbor_dist(agent, 0.0);
+ NavigationServer2D::get_singleton()->agent_set_max_neighbors(agent, 0);
+ NavigationServer2D::get_singleton()->agent_set_time_horizon(agent, 0.0);
+ NavigationServer2D::get_singleton()->agent_set_radius(agent, radius);
+ NavigationServer2D::get_singleton()->agent_set_max_speed(agent, 0.0);
+ }
}
diff --git a/scene/2d/navigation_obstacle_2d.h b/scene/2d/navigation_obstacle_2d.h
index 421f8ca7cd..135ca4651e 100644
--- a/scene/2d/navigation_obstacle_2d.h
+++ b/scene/2d/navigation_obstacle_2d.h
@@ -31,15 +31,13 @@
#ifndef NAVIGATION_OBSTACLE_2D_H
#define NAVIGATION_OBSTACLE_2D_H
+#include "scene/2d/node_2d.h"
#include "scene/main/node.h"
-class Navigation2D;
-
class NavigationObstacle2D : public Node {
GDCLASS(NavigationObstacle2D, Node);
- Navigation2D *navigation = nullptr;
-
+ Node2D *parent_node2d = nullptr;
RID agent;
protected:
@@ -50,14 +48,6 @@ public:
NavigationObstacle2D();
virtual ~NavigationObstacle2D();
- void set_navigation(Navigation2D *p_nav);
- const Navigation2D *get_navigation() const {
- return navigation;
- }
-
- void set_navigation_node(Node *p_nav);
- Node *get_navigation_node() const;
-
RID get_rid() const {
return agent;
}
diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp
index b02cdf12ad..8be8c8db4a 100644
--- a/scene/2d/navigation_region_2d.cpp
+++ b/scene/2d/navigation_region_2d.cpp
@@ -34,7 +34,6 @@
#include "core/core_string_names.h"
#include "core/math/geometry_2d.h"
#include "core/os/mutex.h"
-#include "navigation_2d.h"
#include "servers/navigation_server_2d.h"
#include "thirdparty/misc/polypartition.h"
@@ -365,10 +364,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));
} else {
- if (navigation) {
- NavigationServer2D::get_singleton()->region_set_map(region, navigation->get_rid());
- }
+ 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));
}
if (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()) {
@@ -380,6 +379,14 @@ bool NavigationRegion2D::is_enabled() const {
return enabled;
}
+void NavigationRegion2D::set_layers(uint32_t p_layers) {
+ NavigationServer2D::get_singleton()->region_set_layers(region, p_layers);
+}
+
+uint32_t NavigationRegion2D::get_layers() const {
+ return NavigationServer2D::get_singleton()->region_get_layers(region);
+}
+
/////////////////////////////
#ifdef TOOLS_ENABLED
Rect2 NavigationRegion2D::_edit_get_rect() const {
@@ -394,35 +401,24 @@ bool NavigationRegion2D::_edit_is_selected_on_click(const Point2 &p_point, doubl
void NavigationRegion2D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
- Node2D *c = this;
- while (c) {
- navigation = Object::cast_to<Navigation2D>(c);
- if (navigation) {
- if (enabled) {
- NavigationServer2D::get_singleton()->region_set_map(region, navigation->get_rid());
- }
- break;
- }
-
- c = Object::cast_to<Node2D>(c->get_parent());
+ 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));
}
-
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
NavigationServer2D::get_singleton()->region_set_transform(region, get_global_transform());
-
} break;
case NOTIFICATION_EXIT_TREE: {
- if (navigation) {
- NavigationServer2D::get_singleton()->region_set_map(region, RID());
+ NavigationServer2D::get_singleton()->region_set_map(region, RID());
+ if (enabled) {
+ NavigationServer2D::get_singleton()->disconnect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
}
- navigation = nullptr;
} break;
case NOTIFICATION_DRAW: {
if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()) && navpoly.is_valid()) {
Vector<Vector2> verts = navpoly->get_vertices();
- int vsize = verts.size();
- if (vsize < 3) {
+ if (verts.size() < 3) {
return;
}
@@ -432,33 +428,47 @@ void NavigationRegion2D::_notification(int p_what) {
} else {
color = get_tree()->get_debug_navigation_disabled_color();
}
- Vector<Color> colors;
- Vector<Vector2> vertices;
- vertices.resize(vsize);
- colors.resize(vsize);
- {
- const Vector2 *vr = verts.ptr();
- for (int i = 0; i < vsize; i++) {
- vertices.write[i] = vr[i];
- colors.write[i] = color;
- }
- }
+ Color doors_color = color.lightened(0.2);
- Vector<int> indices;
+ RandomPCG rand;
for (int i = 0; i < navpoly->get_polygon_count(); i++) {
+ // An array of vertices for this polygon.
Vector<int> polygon = navpoly->get_polygon(i);
-
- for (int j = 2; j < polygon.size(); j++) {
- int kofs[3] = { 0, j - 1, j };
- for (int k = 0; k < 3; k++) {
- int idx = polygon[kofs[k]];
- ERR_FAIL_INDEX(idx, vsize);
- indices.push_back(idx);
- }
+ Vector<Vector2> vertices;
+ vertices.resize(polygon.size());
+ for (int j = 0; j < polygon.size(); j++) {
+ ERR_FAIL_INDEX(polygon[j], verts.size());
+ vertices.write[j] = verts[polygon[j]];
}
+
+ // Generate the polygon color, slightly randomly modified from the settings one.
+ Color random_variation_color;
+ random_variation_color.set_hsv(color.get_h() + rand.random(-1.0, 1.0) * 0.05, color.get_s(), color.get_v() + rand.random(-1.0, 1.0) * 0.1);
+ random_variation_color.a = color.a;
+ Vector<Color> colors;
+ colors.push_back(random_variation_color);
+
+ RS::get_singleton()->canvas_item_add_polygon(get_canvas_item(), vertices, colors);
+ }
+
+ // Draw the region
+ Transform2D xform = get_global_transform();
+ const NavigationServer2D *ns = NavigationServer2D::get_singleton();
+ float radius = ns->map_get_edge_connection_margin(get_world_2d()->get_navigation_map()) / 2.0;
+ for (int i = 0; i < ns->region_get_connections_count(region); i++) {
+ // Two main points
+ Vector2 a = ns->region_get_connection_pathway_start(region, i);
+ a = xform.affine_inverse().xform(a);
+ Vector2 b = ns->region_get_connection_pathway_end(region, i);
+ b = xform.affine_inverse().xform(b);
+ draw_line(a, b, doors_color);
+
+ // Draw a circle to illustrate the margins.
+ float angle = (b - a).angle();
+ draw_arc(a, radius, angle + Math_PI / 2.0, angle - Math_PI / 2.0 + Math_TAU, 10, doors_color);
+ draw_arc(b, radius, angle - Math_PI / 2.0, angle + Math_PI / 2.0, 10, doors_color);
}
- RS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, vertices, colors);
}
} break;
}
@@ -493,6 +503,11 @@ void NavigationRegion2D::_navpoly_changed() {
update();
}
}
+void NavigationRegion2D::_map_changed(RID p_map) {
+ if (enabled && get_world_2d()->get_navigation_map() == p_map) {
+ update();
+ }
+}
String NavigationRegion2D::get_configuration_warning() const {
if (!is_visible_in_tree() || !is_inside_tree()) {
@@ -507,18 +522,8 @@ String NavigationRegion2D::get_configuration_warning() const {
}
warning += TTR("A NavigationPolygon resource must be set or created for this node to work. Please set a property or draw a polygon.");
}
- const Node2D *c = this;
- while (c) {
- if (Object::cast_to<Navigation2D>(c)) {
- return warning;
- }
- c = Object::cast_to<Node2D>(c->get_parent());
- }
- if (!warning.is_empty()) {
- warning += "\n\n";
- }
- return warning + TTR("NavigationRegion2D must be a child or grandchild to a Navigation2D node. It only provides navigation data.");
+ return warning;
}
void NavigationRegion2D::_bind_methods() {
@@ -528,10 +533,14 @@ void NavigationRegion2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationRegion2D::set_enabled);
ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationRegion2D::is_enabled);
+ ClassDB::bind_method(D_METHOD("set_layers", "layers"), &NavigationRegion2D::set_layers);
+ ClassDB::bind_method(D_METHOD("get_layers"), &NavigationRegion2D::get_layers);
+
ClassDB::bind_method(D_METHOD("_navpoly_changed"), &NavigationRegion2D::_navpoly_changed);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "navpoly", PROPERTY_HINT_RESOURCE_TYPE, "NavigationPolygon"), "set_navigation_polygon", "get_navigation_polygon");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "layers", PROPERTY_HINT_LAYERS_2D_NAVIGATION), "set_layers", "get_layers");
}
NavigationRegion2D::NavigationRegion2D() {
diff --git a/scene/2d/navigation_region_2d.h b/scene/2d/navigation_region_2d.h
index 0b9a258a25..58f04599be 100644
--- a/scene/2d/navigation_region_2d.h
+++ b/scene/2d/navigation_region_2d.h
@@ -91,17 +91,15 @@ public:
~NavigationPolygon() {}
};
-class Navigation2D;
-
class NavigationRegion2D : public Node2D {
GDCLASS(NavigationRegion2D, Node2D);
bool enabled = true;
RID region;
- Navigation2D *navigation = nullptr;
Ref<NavigationPolygon> navpoly;
void _navpoly_changed();
+ void _map_changed(RID p_RID);
protected:
void _notification(int p_what);
@@ -116,6 +114,9 @@ public:
void set_enabled(bool p_enabled);
bool is_enabled() const;
+ void set_layers(uint32_t p_layers);
+ uint32_t get_layers() const;
+
void set_navigation_polygon(const Ref<NavigationPolygon> &p_navpoly);
Ref<NavigationPolygon> get_navigation_polygon() const;
diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp
index bf311632c8..8afc43ddc9 100644
--- a/scene/2d/node_2d.cpp
+++ b/scene/2d/node_2d.cpp
@@ -71,12 +71,12 @@ Size2 Node2D::_edit_get_scale() const {
return _scale;
}
-void Node2D::_edit_set_rotation(float p_rotation) {
+void Node2D::_edit_set_rotation(real_t p_rotation) {
angle = p_rotation;
_update_transform();
}
-float Node2D::_edit_get_rotation() const {
+real_t Node2D::_edit_get_rotation() const {
return angle;
}
@@ -148,7 +148,7 @@ void Node2D::set_position(const Point2 &p_pos) {
_update_transform();
}
-void Node2D::set_rotation(float p_radians) {
+void Node2D::set_rotation(real_t p_radians) {
if (_xform_dirty) {
((Node2D *)this)->_update_xform_values();
}
@@ -156,7 +156,7 @@ void Node2D::set_rotation(float p_radians) {
_update_transform();
}
-void Node2D::set_skew(float p_radians) {
+void Node2D::set_skew(real_t p_radians) {
if (_xform_dirty) {
((Node2D *)this)->_update_xform_values();
}
@@ -164,11 +164,11 @@ void Node2D::set_skew(float p_radians) {
_update_transform();
}
-void Node2D::set_rotation_degrees(float p_degrees) {
+void Node2D::set_rotation_degrees(real_t p_degrees) {
set_rotation(Math::deg2rad(p_degrees));
}
-void Node2D::set_skew_degrees(float p_degrees) {
+void Node2D::set_skew_degrees(real_t p_degrees) {
set_skew(Math::deg2rad(p_degrees));
}
@@ -194,7 +194,7 @@ Point2 Node2D::get_position() const {
return pos;
}
-float Node2D::get_rotation() const {
+real_t Node2D::get_rotation() const {
if (_xform_dirty) {
((Node2D *)this)->_update_xform_values();
}
@@ -202,7 +202,7 @@ float Node2D::get_rotation() const {
return angle;
}
-float Node2D::get_skew() const {
+real_t Node2D::get_skew() const {
if (_xform_dirty) {
((Node2D *)this)->_update_xform_values();
}
@@ -210,11 +210,11 @@ float Node2D::get_skew() const {
return skew;
}
-float Node2D::get_rotation_degrees() const {
+real_t Node2D::get_rotation_degrees() const {
return Math::rad2deg(get_rotation());
}
-float Node2D::get_skew_degrees() const {
+real_t Node2D::get_skew_degrees() const {
return Math::rad2deg(get_skew());
}
@@ -230,7 +230,7 @@ Transform2D Node2D::get_transform() const {
return _mat;
}
-void Node2D::rotate(float p_radians) {
+void Node2D::rotate(real_t p_radians) {
set_rotation(get_rotation() + p_radians);
}
@@ -246,7 +246,7 @@ void Node2D::apply_scale(const Size2 &p_amount) {
set_scale(get_scale() * p_amount);
}
-void Node2D::move_x(float p_delta, bool p_scaled) {
+void Node2D::move_x(real_t p_delta, bool p_scaled) {
Transform2D t = get_transform();
Vector2 m = t[0];
if (!p_scaled) {
@@ -255,7 +255,7 @@ void Node2D::move_x(float p_delta, bool p_scaled) {
set_position(t[2] + m * p_delta);
}
-void Node2D::move_y(float p_delta, bool p_scaled) {
+void Node2D::move_y(real_t p_delta, bool p_scaled) {
Transform2D t = get_transform();
Vector2 m = t[1];
if (!p_scaled) {
@@ -279,25 +279,25 @@ void Node2D::set_global_position(const Point2 &p_pos) {
}
}
-float Node2D::get_global_rotation() const {
+real_t Node2D::get_global_rotation() const {
return get_global_transform().get_rotation();
}
-void Node2D::set_global_rotation(float p_radians) {
+void Node2D::set_global_rotation(real_t p_radians) {
CanvasItem *pi = get_parent_item();
if (pi) {
- const float parent_global_rot = pi->get_global_transform().get_rotation();
+ const real_t parent_global_rot = pi->get_global_transform().get_rotation();
set_rotation(p_radians - parent_global_rot);
} else {
set_rotation(p_radians);
}
}
-float Node2D::get_global_rotation_degrees() const {
+real_t Node2D::get_global_rotation_degrees() const {
return Math::rad2deg(get_global_rotation());
}
-void Node2D::set_global_rotation_degrees(float p_degrees) {
+void Node2D::set_global_rotation_degrees(real_t p_degrees) {
set_global_rotation(Math::deg2rad(p_degrees));
}
@@ -379,7 +379,7 @@ void Node2D::look_at(const Vector2 &p_pos) {
rotate(get_angle_to(p_pos));
}
-float Node2D::get_angle_to(const Vector2 &p_pos) const {
+real_t Node2D::get_angle_to(const Vector2 &p_pos) const {
return (to_local(p_pos) * get_scale()).angle();
}
diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h
index c27d740b8a..358b7e6520 100644
--- a/scene/2d/node_2d.h
+++ b/scene/2d/node_2d.h
@@ -37,9 +37,9 @@ class Node2D : public CanvasItem {
GDCLASS(Node2D, CanvasItem);
Point2 pos;
- float angle = 0.0;
+ real_t angle = 0.0;
Size2 _scale = Vector2(1, 1);
- float skew = 0.0;
+ real_t skew = 0.0;
int z_index = 0;
bool z_relative = true;
@@ -65,51 +65,51 @@ public:
virtual void _edit_set_scale(const Size2 &p_scale) override;
virtual Size2 _edit_get_scale() const override;
- virtual void _edit_set_rotation(float p_rotation) override;
- virtual float _edit_get_rotation() const override;
+ virtual void _edit_set_rotation(real_t p_rotation) override;
+ virtual real_t _edit_get_rotation() const override;
virtual bool _edit_use_rotation() const override;
virtual void _edit_set_rect(const Rect2 &p_edit_rect) override;
#endif
void set_position(const Point2 &p_pos);
- void set_rotation(float p_radians);
- void set_rotation_degrees(float p_degrees);
- void set_skew(float p_radians);
- void set_skew_degrees(float p_radians);
+ void set_rotation(real_t p_radians);
+ void set_rotation_degrees(real_t p_degrees);
+ void set_skew(real_t p_radians);
+ void set_skew_degrees(real_t p_radians);
void set_scale(const Size2 &p_scale);
- void rotate(float p_radians);
- void move_x(float p_delta, bool p_scaled = false);
- void move_y(float p_delta, bool p_scaled = false);
+ void rotate(real_t p_radians);
+ void move_x(real_t p_delta, bool p_scaled = false);
+ void move_y(real_t p_delta, bool p_scaled = false);
void translate(const Vector2 &p_amount);
void global_translate(const Vector2 &p_amount);
void apply_scale(const Size2 &p_amount);
Point2 get_position() const;
- float get_rotation() const;
- float get_skew() const;
- float get_rotation_degrees() const;
- float get_skew_degrees() const;
+ real_t get_rotation() const;
+ real_t get_skew() const;
+ real_t get_rotation_degrees() const;
+ real_t get_skew_degrees() const;
Size2 get_scale() const;
Point2 get_global_position() const;
- float get_global_rotation() const;
- float get_global_rotation_degrees() const;
+ real_t get_global_rotation() const;
+ real_t get_global_rotation_degrees() const;
Size2 get_global_scale() const;
void set_transform(const Transform2D &p_transform);
void set_global_transform(const Transform2D &p_transform);
void set_global_position(const Point2 &p_pos);
- void set_global_rotation(float p_radians);
- void set_global_rotation_degrees(float p_degrees);
+ void set_global_rotation(real_t p_radians);
+ void set_global_rotation_degrees(real_t p_degrees);
void set_global_scale(const Size2 &p_scale);
void set_z_index(int p_z);
int get_z_index() const;
void look_at(const Vector2 &p_pos);
- float get_angle_to(const Vector2 &p_pos) const;
+ real_t get_angle_to(const Vector2 &p_pos) const;
Point2 to_local(Point2 p_global) const;
Point2 to_global(Point2 p_local) const;
diff --git a/scene/2d/parallax_background.cpp b/scene/2d/parallax_background.cpp
index c93915d1bc..4870ae614b 100644
--- a/scene/2d/parallax_background.cpp
+++ b/scene/2d/parallax_background.cpp
@@ -51,11 +51,11 @@ void ParallaxBackground::_camera_moved(const Transform2D &p_transform, const Poi
set_scroll_offset(p_transform.get_origin());
}
-void ParallaxBackground::set_scroll_scale(float p_scale) {
+void ParallaxBackground::set_scroll_scale(real_t p_scale) {
scale = p_scale;
}
-float ParallaxBackground::get_scroll_scale() const {
+real_t ParallaxBackground::get_scroll_scale() const {
return scale;
}
diff --git a/scene/2d/parallax_background.h b/scene/2d/parallax_background.h
index c9991efc9d..27134dab29 100644
--- a/scene/2d/parallax_background.h
+++ b/scene/2d/parallax_background.h
@@ -39,7 +39,7 @@ class ParallaxBackground : public CanvasLayer {
GDCLASS(ParallaxBackground, CanvasLayer);
Point2 offset;
- float scale = 1.0;
+ real_t scale = 1.0;
Point2 base_offset;
Point2 base_scale = Vector2(1, 1);
Point2 screen_offset;
@@ -61,8 +61,8 @@ public:
void set_scroll_offset(const Point2 &p_ofs);
Point2 get_scroll_offset() const;
- void set_scroll_scale(float p_scale);
- float get_scroll_scale() const;
+ void set_scroll_scale(real_t p_scale);
+ real_t get_scroll_scale() const;
void set_scroll_base_offset(const Point2 &p_ofs);
Point2 get_scroll_base_offset() const;
diff --git a/scene/2d/parallax_layer.cpp b/scene/2d/parallax_layer.cpp
index a38338e1e3..725e858a43 100644
--- a/scene/2d/parallax_layer.cpp
+++ b/scene/2d/parallax_layer.cpp
@@ -39,7 +39,7 @@ void ParallaxLayer::set_motion_scale(const Size2 &p_scale) {
ParallaxBackground *pb = Object::cast_to<ParallaxBackground>(get_parent());
if (pb && is_inside_tree()) {
Vector2 ofs = pb->get_final_offset();
- float scale = pb->get_scroll_scale();
+ real_t scale = pb->get_scroll_scale();
set_base_offset_and_scale(ofs, scale, screen_offset);
}
}
@@ -54,7 +54,7 @@ void ParallaxLayer::set_motion_offset(const Size2 &p_offset) {
ParallaxBackground *pb = Object::cast_to<ParallaxBackground>(get_parent());
if (pb && is_inside_tree()) {
Vector2 ofs = pb->get_final_offset();
- float scale = pb->get_scroll_scale();
+ real_t scale = pb->get_scroll_scale();
set_base_offset_and_scale(ofs, scale, screen_offset);
}
}
@@ -107,7 +107,7 @@ void ParallaxLayer::_notification(int p_what) {
}
}
-void ParallaxLayer::set_base_offset_and_scale(const Point2 &p_offset, float p_scale, const Point2 &p_screen_offset) {
+void ParallaxLayer::set_base_offset_and_scale(const Point2 &p_offset, real_t p_scale, const Point2 &p_screen_offset) {
screen_offset = p_screen_offset;
if (!is_inside_tree()) {
diff --git a/scene/2d/parallax_layer.h b/scene/2d/parallax_layer.h
index 86694c7724..e826e6da9c 100644
--- a/scene/2d/parallax_layer.h
+++ b/scene/2d/parallax_layer.h
@@ -59,7 +59,7 @@ public:
void set_mirroring(const Size2 &p_mirroring);
Size2 get_mirroring() const;
- void set_base_offset_and_scale(const Point2 &p_offset, float p_scale, const Point2 &p_screen_offset);
+ void set_base_offset_and_scale(const Point2 &p_offset, real_t p_scale, const Point2 &p_screen_offset);
virtual String get_configuration_warning() const override;
ParallaxLayer();
diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp
index 724998641f..be160ee1dd 100644
--- a/scene/2d/path_2d.cpp
+++ b/scene/2d/path_2d.cpp
@@ -96,9 +96,9 @@ void Path2D::_notification(int p_what) {
}
#ifdef TOOLS_ENABLED
- const float line_width = 2 * EDSCALE;
+ const real_t line_width = 2 * EDSCALE;
#else
- const float line_width = 2;
+ const real_t line_width = 2;
#endif
const Color color = Color(0.5, 0.6, 1.0, 0.7);
@@ -164,14 +164,14 @@ void PathFollow2D::_update_transform() {
return;
}
- float path_length = c->get_baked_length();
+ real_t path_length = c->get_baked_length();
if (path_length == 0) {
return;
}
Vector2 pos = c->interpolate_baked(offset, cubic);
if (rotates) {
- float ahead = offset + lookahead;
+ real_t ahead = offset + lookahead;
if (loop && ahead >= path_length) {
// If our lookahead will loop, we need to check if the path is closed.
@@ -240,7 +240,7 @@ bool PathFollow2D::get_cubic_interpolation() const {
void PathFollow2D::_validate_property(PropertyInfo &property) const {
if (property.name == "offset") {
- float max = 10000.0;
+ real_t max = 10000.0;
if (path && path->get_curve().is_valid()) {
max = path->get_curve()->get_baked_length();
}
@@ -301,11 +301,11 @@ void PathFollow2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lookahead", PROPERTY_HINT_RANGE, "0.001,1024.0,0.001"), "set_lookahead", "get_lookahead");
}
-void PathFollow2D::set_offset(float p_offset) {
+void PathFollow2D::set_offset(real_t p_offset) {
offset = p_offset;
if (path) {
if (path->get_curve().is_valid()) {
- float path_length = path->get_curve()->get_baked_length();
+ real_t path_length = path->get_curve()->get_baked_length();
if (loop) {
offset = Math::fposmod(offset, path_length);
@@ -321,39 +321,39 @@ void PathFollow2D::set_offset(float p_offset) {
}
}
-void PathFollow2D::set_h_offset(float p_h_offset) {
+void PathFollow2D::set_h_offset(real_t p_h_offset) {
h_offset = p_h_offset;
if (path) {
_update_transform();
}
}
-float PathFollow2D::get_h_offset() const {
+real_t PathFollow2D::get_h_offset() const {
return h_offset;
}
-void PathFollow2D::set_v_offset(float p_v_offset) {
+void PathFollow2D::set_v_offset(real_t p_v_offset) {
v_offset = p_v_offset;
if (path) {
_update_transform();
}
}
-float PathFollow2D::get_v_offset() const {
+real_t PathFollow2D::get_v_offset() const {
return v_offset;
}
-float PathFollow2D::get_offset() const {
+real_t PathFollow2D::get_offset() const {
return offset;
}
-void PathFollow2D::set_unit_offset(float p_unit_offset) {
+void PathFollow2D::set_unit_offset(real_t p_unit_offset) {
if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length()) {
set_offset(p_unit_offset * path->get_curve()->get_baked_length());
}
}
-float PathFollow2D::get_unit_offset() const {
+real_t PathFollow2D::get_unit_offset() const {
if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length()) {
return get_offset() / path->get_curve()->get_baked_length();
} else {
@@ -361,11 +361,11 @@ float PathFollow2D::get_unit_offset() const {
}
}
-void PathFollow2D::set_lookahead(float p_lookahead) {
+void PathFollow2D::set_lookahead(real_t p_lookahead) {
lookahead = p_lookahead;
}
-float PathFollow2D::get_lookahead() const {
+real_t PathFollow2D::get_lookahead() const {
return lookahead;
}
diff --git a/scene/2d/path_2d.h b/scene/2d/path_2d.h
index a748817555..671ab493c3 100644
--- a/scene/2d/path_2d.h
+++ b/scene/2d/path_2d.h
@@ -81,20 +81,20 @@ protected:
static void _bind_methods();
public:
- void set_offset(float p_offset);
- float get_offset() const;
+ void set_offset(real_t p_offset);
+ real_t get_offset() const;
- void set_h_offset(float p_h_offset);
- float get_h_offset() const;
+ void set_h_offset(real_t p_h_offset);
+ real_t get_h_offset() const;
- void set_v_offset(float p_v_offset);
- float get_v_offset() const;
+ void set_v_offset(real_t p_v_offset);
+ real_t get_v_offset() const;
- void set_unit_offset(float p_unit_offset);
- float get_unit_offset() const;
+ void set_unit_offset(real_t p_unit_offset);
+ real_t get_unit_offset() const;
- void set_lookahead(float p_lookahead);
- float get_lookahead() const;
+ void set_lookahead(real_t p_lookahead);
+ real_t get_lookahead() const;
void set_loop(bool p_loop);
bool has_loop() const;
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 96d8fb609b..a615d96687 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -411,13 +411,13 @@ void RigidBody2D::_direct_state_changed(Object *p_state) {
}
}
- //process remotions
+ //process removals
for (int i = 0; i < toremove_count; i++) {
_body_inout(0, toremove[i].body_id, toremove[i].pair.body_shape, toremove[i].pair.local_shape);
}
- //process aditions
+ //process additions
for (int i = 0; i < toadd_count; i++) {
_body_inout(1, toadd[i].id, toadd[i].shape, toadd[i].local_shape);
diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp
index a60a32f1d2..1a7038bb80 100644
--- a/scene/2d/polygon_2d.cpp
+++ b/scene/2d/polygon_2d.cpp
@@ -88,13 +88,13 @@ bool Polygon2D::_edit_is_selected_on_click(const Point2 &p_point, double p_toler
}
return Geometry2D::is_point_in_polygon(p_point - get_offset(), polygon2d);
}
+#endif
void Polygon2D::_validate_property(PropertyInfo &property) const {
if (!invert && property.name == "invert_border") {
property.usage = PROPERTY_USAGE_NOEDITOR;
}
}
-#endif
void Polygon2D::_skeleton_bone_setup_changed() {
update();
@@ -160,8 +160,8 @@ void Polygon2D::_notification(int p_what) {
if (invert) {
Rect2 bounds;
int highest_idx = -1;
- float highest_y = -1e20;
- float sum = 0.0;
+ real_t highest_y = -1e20;
+ real_t sum = 0.0;
for (int i = 0; i < len; i++) {
if (i == 0) {
@@ -279,7 +279,7 @@ void Polygon2D::_notification(int p_what) {
//normalize the weights
for (int i = 0; i < vc; i++) {
- float tw = 0.0;
+ real_t tw = 0.0;
for (int j = 0; j < 4; j++) {
tw += weightsw[i * 4 + j];
}
@@ -432,20 +432,20 @@ Vector2 Polygon2D::get_texture_offset() const {
return tex_ofs;
}
-void Polygon2D::set_texture_rotation(float p_rot) {
+void Polygon2D::set_texture_rotation(real_t p_rot) {
tex_rot = p_rot;
update();
}
-float Polygon2D::get_texture_rotation() const {
+real_t Polygon2D::get_texture_rotation() const {
return tex_rot;
}
-void Polygon2D::set_texture_rotation_degrees(float p_rot) {
+void Polygon2D::set_texture_rotation_degrees(real_t p_rot) {
set_texture_rotation(Math::deg2rad(p_rot));
}
-float Polygon2D::get_texture_rotation_degrees() const {
+real_t Polygon2D::get_texture_rotation_degrees() const {
return Math::rad2deg(get_texture_rotation());
}
@@ -477,12 +477,12 @@ bool Polygon2D::get_antialiased() const {
return antialiased;
}
-void Polygon2D::set_invert_border(float p_invert_border) {
+void Polygon2D::set_invert_border(real_t p_invert_border) {
invert_border = p_invert_border;
update();
}
-float Polygon2D::get_invert_border() const {
+real_t Polygon2D::get_invert_border() const {
return invert_border;
}
diff --git a/scene/2d/polygon_2d.h b/scene/2d/polygon_2d.h
index 43a66aad13..c207024a53 100644
--- a/scene/2d/polygon_2d.h
+++ b/scene/2d/polygon_2d.h
@@ -55,9 +55,9 @@ class Polygon2D : public Node2D {
Size2 tex_scale = Vector2(1, 1);
Vector2 tex_ofs;
bool tex_tile = true;
- float tex_rot = 0.0;
+ real_t tex_rot = 0.0;
bool invert = false;
- float invert_border = 100.0;
+ real_t invert_border = 100.0;
bool antialiased = false;
Vector2 offset;
@@ -72,13 +72,10 @@ class Polygon2D : public Node2D {
void _skeleton_bone_setup_changed();
-#ifdef TOOLS_ENABLED
- void _validate_property(PropertyInfo &property) const override;
-#endif
-
protected:
void _notification(int p_what);
static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const override;
public:
#ifdef TOOLS_ENABLED
@@ -118,11 +115,11 @@ public:
void set_texture_offset(const Vector2 &p_offset);
Vector2 get_texture_offset() const;
- void set_texture_rotation(float p_rot);
- float get_texture_rotation() const;
+ void set_texture_rotation(real_t p_rot);
+ real_t get_texture_rotation() const;
- void set_texture_rotation_degrees(float p_rot);
- float get_texture_rotation_degrees() const;
+ void set_texture_rotation_degrees(real_t p_rot);
+ real_t get_texture_rotation_degrees() const;
void set_texture_scale(const Size2 &p_scale);
Size2 get_texture_scale() const;
@@ -133,8 +130,8 @@ public:
void set_antialiased(bool p_antialiased);
bool get_antialiased() const;
- void set_invert_border(float p_invert_border);
- float get_invert_border() const;
+ void set_invert_border(real_t p_invert_border);
+ real_t get_invert_border() const;
void set_offset(const Vector2 &p_offset);
Vector2 get_offset() const;
diff --git a/scene/2d/position_2d.cpp b/scene/2d/position_2d.cpp
index ff7a0dbac3..5c7d65e3e0 100644
--- a/scene/2d/position_2d.cpp
+++ b/scene/2d/position_2d.cpp
@@ -33,10 +33,10 @@
#include "core/config/engine.h"
#include "scene/resources/texture.h"
-const float DEFAULT_GIZMO_EXTENTS = 10.0;
+const real_t DEFAULT_GIZMO_EXTENTS = 10.0;
void Position2D::_draw_cross() {
- float extents = get_gizmo_extents();
+ real_t extents = get_gizmo_extents();
// Colors taken from `axis_x_color` and `axis_y_color` (defined in `editor/editor_themes.cpp`)
draw_line(Point2(-extents, 0), Point2(+extents, 0), Color(0.96, 0.20, 0.32));
draw_line(Point2(0, -extents), Point2(0, +extents), Color(0.53, 0.84, 0.01));
@@ -44,7 +44,7 @@ void Position2D::_draw_cross() {
#ifdef TOOLS_ENABLED
Rect2 Position2D::_edit_get_rect() const {
- float extents = get_gizmo_extents();
+ real_t extents = get_gizmo_extents();
return Rect2(Point2(-extents, -extents), Size2(extents * 2, extents * 2));
}
@@ -70,7 +70,7 @@ void Position2D::_notification(int p_what) {
}
}
-void Position2D::set_gizmo_extents(float p_extents) {
+void Position2D::set_gizmo_extents(real_t p_extents) {
if (p_extents == DEFAULT_GIZMO_EXTENTS) {
set_meta("_gizmo_extents_", Variant());
} else {
@@ -80,7 +80,7 @@ void Position2D::set_gizmo_extents(float p_extents) {
update();
}
-float Position2D::get_gizmo_extents() const {
+real_t Position2D::get_gizmo_extents() const {
if (has_meta("_gizmo_extents_")) {
return get_meta("_gizmo_extents_");
} else {
diff --git a/scene/2d/position_2d.h b/scene/2d/position_2d.h
index fcaef0e6a3..9ed622c8f6 100644
--- a/scene/2d/position_2d.h
+++ b/scene/2d/position_2d.h
@@ -48,8 +48,8 @@ public:
virtual bool _edit_use_rect() const override;
#endif
- void set_gizmo_extents(float p_extents);
- float get_gizmo_extents() const;
+ void set_gizmo_extents(real_t p_extents);
+ real_t get_gizmo_extents() const;
Position2D();
};
diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp
index e7b5cb5a51..50625a0f39 100644
--- a/scene/2d/ray_cast_2d.cpp
+++ b/scene/2d/ray_cast_2d.cpp
@@ -208,8 +208,6 @@ void RayCast2D::_update_raycast_state() {
}
void RayCast2D::_draw_debug_shape() {
- float tsize = 6.0;
- bool draw_arrow = target_position.length() >= tsize;
Color draw_col = collided ? Color(1.0, 0.01, 0) : get_tree()->get_debug_collisions_color();
if (!enabled) {
float g = draw_col.get_v();
@@ -218,26 +216,33 @@ void RayCast2D::_draw_debug_shape() {
draw_col.b = g;
}
- draw_line(Vector2(), target_position - Vector2(0, tsize * draw_arrow), draw_col, 1.4);
-
// Draw an arrow indicating where the RayCast is pointing to
- if (draw_arrow) {
- Transform2D xf;
- xf.rotate(target_position.angle());
- xf.translate(Vector2(target_position.length() - tsize, 0));
-
- Vector<Vector2> pts;
- pts.push_back(xf.xform(Vector2(tsize, 0)));
- pts.push_back(xf.xform(Vector2(0, 0.5 * tsize)));
- pts.push_back(xf.xform(Vector2(0, -0.5 * tsize)));
-
- Vector<Color> cols;
- for (int i = 0; i < 3; i++) {
- cols.push_back(draw_col);
- }
+ const float max_arrow_size = 6;
+ const float line_width = 1.4;
+ bool no_line = target_position.length() < line_width;
+ float arrow_size = CLAMP(target_position.length() * 2 / 3, line_width, max_arrow_size);
+
+ if (no_line) {
+ arrow_size = target_position.length();
+ } else {
+ draw_line(Vector2(), target_position - target_position.normalized() * arrow_size, draw_col, line_width);
+ }
+
+ Transform2D xf;
+ xf.rotate(target_position.angle());
+ xf.translate(Vector2(no_line ? 0 : target_position.length() - arrow_size, 0));
- draw_primitive(pts, cols, Vector<Vector2>());
+ 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<Color> cols;
+ for (int i = 0; i < 3; i++) {
+ cols.push_back(draw_col);
}
+
+ draw_primitive(pts, cols, Vector<Vector2>());
}
void RayCast2D::force_raycast_update() {
diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp
index 5728230a8c..2d19d254b1 100644
--- a/scene/2d/skeleton_2d.cpp
+++ b/scene/2d/skeleton_2d.cpp
@@ -119,11 +119,11 @@ void Bone2D::apply_rest() {
set_transform(rest);
}
-void Bone2D::set_default_length(float p_length) {
+void Bone2D::set_default_length(real_t p_length) {
default_length = p_length;
}
-float Bone2D::get_default_length() const {
+real_t Bone2D::get_default_length() const {
return default_length;
}
@@ -184,7 +184,7 @@ void Skeleton2D::_update_bone_setup() {
bone_setup_dirty = false;
RS::get_singleton()->skeleton_allocate_data(skeleton, bones.size(), true);
- bones.sort(); //sorty so they are always in the same order/index
+ bones.sort(); //sorting so that they are always in the same order/index
for (int i = 0; i < bones.size(); i++) {
bones.write[i].rest_inverse = bones[i].bone->get_skeleton_rest().affine_inverse(); //bind pose
diff --git a/scene/2d/skeleton_2d.h b/scene/2d/skeleton_2d.h
index 80ca8c80ac..1f43ea742b 100644
--- a/scene/2d/skeleton_2d.h
+++ b/scene/2d/skeleton_2d.h
@@ -46,7 +46,7 @@ class Bone2D : public Node2D {
Bone2D *parent_bone = nullptr;
Skeleton2D *skeleton = nullptr;
Transform2D rest;
- float default_length = 16.0;
+ real_t default_length = 16.0;
int skeleton_index = -1;
@@ -62,8 +62,8 @@ public:
String get_configuration_warning() const override;
- void set_default_length(float p_length);
- float get_default_length() const;
+ void set_default_length(real_t p_length);
+ real_t get_default_length() const;
int get_index_in_skeleton() const;
diff --git a/scene/2d/sprite_2d.cpp b/scene/2d/sprite_2d.cpp
index 31040020dd..7c93edbff9 100644
--- a/scene/2d/sprite_2d.cpp
+++ b/scene/2d/sprite_2d.cpp
@@ -77,14 +77,14 @@ Rect2 Sprite2D::get_anchorable_rect() const {
return get_rect();
}
-void Sprite2D::_get_rects(Rect2 &r_src_rect, Rect2 &r_dst_rect, bool &r_filter_clip) const {
+void Sprite2D::_get_rects(Rect2 &r_src_rect, Rect2 &r_dst_rect, bool &r_filter_clip_enabled) const {
Rect2 base_rect;
- if (region) {
- r_filter_clip = region_filter_clip;
+ if (region_enabled) {
+ r_filter_clip_enabled = region_filter_clip_enabled;
base_rect = region_rect;
} else {
- r_filter_clip = false;
+ r_filter_clip_enabled = false;
base_rect = Rect2(0, 0, texture->get_width(), texture->get_height());
}
@@ -129,10 +129,10 @@ void Sprite2D::_notification(int p_what) {
*/
Rect2 src_rect, dst_rect;
- bool filter_clip;
- _get_rects(src_rect, dst_rect, filter_clip);
+ bool filter_clip_enabled;
+ _get_rects(src_rect, dst_rect, filter_clip_enabled);
- texture->draw_rect_region(ci, dst_rect, src_rect, Color(1, 1, 1), false, filter_clip);
+ texture->draw_rect_region(ci, dst_rect, src_rect, Color(1, 1, 1), false, filter_clip_enabled);
} break;
}
}
@@ -199,18 +199,18 @@ bool Sprite2D::is_flipped_v() const {
return vflip;
}
-void Sprite2D::set_region(bool p_region) {
- if (p_region == region) {
+void Sprite2D::set_region_enabled(bool p_region_enabled) {
+ if (p_region_enabled == region_enabled) {
return;
}
- region = p_region;
+ region_enabled = p_region_enabled;
update();
notify_property_list_changed();
}
-bool Sprite2D::is_region() const {
- return region;
+bool Sprite2D::is_region_enabled() const {
+ return region_enabled;
}
void Sprite2D::set_region_rect(const Rect2 &p_region_rect) {
@@ -220,7 +220,7 @@ void Sprite2D::set_region_rect(const Rect2 &p_region_rect) {
region_rect = p_region_rect;
- if (region) {
+ if (region_enabled) {
item_rect_changed();
}
}
@@ -229,13 +229,13 @@ Rect2 Sprite2D::get_region_rect() const {
return region_rect;
}
-void Sprite2D::set_region_filter_clip(bool p_enable) {
- region_filter_clip = p_enable;
+void Sprite2D::set_region_filter_clip_enabled(bool p_region_filter_clip_enabled) {
+ region_filter_clip_enabled = p_region_filter_clip_enabled;
update();
}
bool Sprite2D::is_region_filter_clip_enabled() const {
- return region_filter_clip;
+ return region_filter_clip_enabled;
}
void Sprite2D::set_frame(int p_frame) {
@@ -299,8 +299,8 @@ bool Sprite2D::is_pixel_opaque(const Point2 &p_point) const {
}
Rect2 src_rect, dst_rect;
- bool filter_clip;
- _get_rects(src_rect, dst_rect, filter_clip);
+ bool filter_clip_enabled;
+ _get_rects(src_rect, dst_rect, filter_clip_enabled);
dst_rect.size = dst_rect.size.abs();
if (!dst_rect.has_point(p_point)) {
@@ -350,7 +350,7 @@ Rect2 Sprite2D::get_rect() const {
Size2i s;
- if (region) {
+ if (region_enabled) {
s = region_rect.size;
} else {
s = texture->get_size();
@@ -385,7 +385,7 @@ void Sprite2D::_validate_property(PropertyInfo &property) const {
property.usage |= PROPERTY_USAGE_KEYING_INCREMENTS;
}
- if (!region && (property.name == "region_rect" || property.name == "region_filter_clip")) {
+ if (!region_enabled && (property.name == "region_rect" || property.name == "region_filter_clip")) {
property.usage = PROPERTY_USAGE_NOEDITOR;
}
}
@@ -414,15 +414,15 @@ void Sprite2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_flip_v", "flip_v"), &Sprite2D::set_flip_v);
ClassDB::bind_method(D_METHOD("is_flipped_v"), &Sprite2D::is_flipped_v);
- ClassDB::bind_method(D_METHOD("set_region", "enabled"), &Sprite2D::set_region);
- ClassDB::bind_method(D_METHOD("is_region"), &Sprite2D::is_region);
+ ClassDB::bind_method(D_METHOD("set_region_enabled", "enabled"), &Sprite2D::set_region_enabled);
+ ClassDB::bind_method(D_METHOD("is_region_enabled"), &Sprite2D::is_region_enabled);
ClassDB::bind_method(D_METHOD("is_pixel_opaque", "pos"), &Sprite2D::is_pixel_opaque);
ClassDB::bind_method(D_METHOD("set_region_rect", "rect"), &Sprite2D::set_region_rect);
ClassDB::bind_method(D_METHOD("get_region_rect"), &Sprite2D::get_region_rect);
- ClassDB::bind_method(D_METHOD("set_region_filter_clip", "enabled"), &Sprite2D::set_region_filter_clip);
+ ClassDB::bind_method(D_METHOD("set_region_filter_clip_enabled", "enabled"), &Sprite2D::set_region_filter_clip_enabled);
ClassDB::bind_method(D_METHOD("is_region_filter_clip_enabled"), &Sprite2D::is_region_filter_clip_enabled);
ClassDB::bind_method(D_METHOD("set_frame", "frame"), &Sprite2D::set_frame);
@@ -455,9 +455,9 @@ void Sprite2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "frame_coords", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_frame_coords", "get_frame_coords");
ADD_GROUP("Region", "region_");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "region_enabled"), "set_region", "is_region");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "region_enabled"), "set_region_enabled", "is_region_enabled");
ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "region_filter_clip"), "set_region_filter_clip", "is_region_filter_clip_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "region_filter_clip_enabled"), "set_region_filter_clip_enabled", "is_region_filter_clip_enabled");
}
Sprite2D::Sprite2D() {
diff --git a/scene/2d/sprite_2d.h b/scene/2d/sprite_2d.h
index fa765f457d..9db74cfe26 100644
--- a/scene/2d/sprite_2d.h
+++ b/scene/2d/sprite_2d.h
@@ -39,23 +39,23 @@ class Sprite2D : public Node2D {
Ref<Texture2D> texture;
Color specular_color;
- float shininess = 0.0;
+ real_t shininess = 0.0;
bool centered = true;
Point2 offset;
bool hflip = false;
bool vflip = false;
- bool region = false;
+ bool region_enabled = false;
Rect2 region_rect;
- bool region_filter_clip = false;
+ bool region_filter_clip_enabled = false;
int frame = 0;
int vframes = 1;
int hframes = 1;
- void _get_rects(Rect2 &r_src_rect, Rect2 &r_dst_rect, bool &r_filter_clip) const;
+ void _get_rects(Rect2 &r_src_rect, Rect2 &r_dst_rect, bool &r_filter_clip_enabled) const;
void _texture_changed();
@@ -97,10 +97,10 @@ public:
void set_flip_v(bool p_flip);
bool is_flipped_v() const;
- void set_region(bool p_region);
- bool is_region() const;
+ void set_region_enabled(bool p_enabled);
+ bool is_region_enabled() const;
- void set_region_filter_clip(bool p_enable);
+ void set_region_filter_clip_enabled(bool p_enabled);
bool is_region_filter_clip_enabled() const;
void set_region_rect(const Rect2 &p_region_rect);
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index d868ebae25..81a5b0b28c 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -48,16 +48,6 @@ int TileMap::_get_quadrant_size() const {
void TileMap::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
- Node2D *c = this;
- while (c) {
- navigation = Object::cast_to<Navigation2D>(c);
- if (navigation) {
- break;
- }
-
- c = Object::cast_to<Node2D>(c->get_parent());
- }
-
if (use_parent) {
_clear_quadrants();
collision_parent = Object::cast_to<CollisionObject2D>(get_parent());
@@ -77,12 +67,10 @@ void TileMap::_notification(int p_what) {
_update_quadrant_space(RID());
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
Quadrant &q = E->get();
- if (navigation) {
- for (Map<PosKey, Quadrant::NavPoly>::Element *F = q.navpoly_ids.front(); F; F = F->next()) {
- NavigationServer2D::get_singleton()->region_set_map(F->get().region, RID());
- }
- q.navpoly_ids.clear();
+ for (Map<PosKey, Quadrant::NavPoly>::Element *F = q.navpoly_ids.front(); F; F = F->next()) {
+ NavigationServer2D::get_singleton()->region_set_map(F->get().region, RID());
}
+ q.navpoly_ids.clear();
if (collision_parent) {
collision_parent->remove_shape_owner(q.shape_owner_id);
@@ -96,8 +84,6 @@ void TileMap::_notification(int p_what) {
}
collision_parent = nullptr;
- navigation = nullptr;
-
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
@@ -135,11 +121,6 @@ void TileMap::_update_quadrant_transform() {
local_transform = get_transform();
}
- Transform2D nav_rel;
- if (navigation) {
- nav_rel = get_relative_transform_to_parent(navigation);
- }
-
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
Quadrant &q = E->get();
Transform2D xform;
@@ -150,9 +131,9 @@ void TileMap::_update_quadrant_transform() {
PhysicsServer2D::get_singleton()->body_set_state(q.body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform);
}
- if (navigation) {
+ if (bake_navigation) {
for (Map<PosKey, Quadrant::NavPoly>::Element *F = q.navpoly_ids.front(); F; F = F->next()) {
- NavigationServer2D::get_singleton()->region_set_transform(F->get().region, nav_rel * F->get().xform);
+ NavigationServer2D::get_singleton()->region_set_transform(F->get().region, F->get().xform);
}
}
@@ -315,11 +296,6 @@ void TileMap::update_dirty_quadrants() {
RenderingServer *vs = RenderingServer::get_singleton();
PhysicsServer2D *ps = PhysicsServer2D::get_singleton();
Vector2 tofs = get_cell_draw_offset();
- Transform2D nav_rel;
- if (navigation) {
- nav_rel = get_relative_transform_to_parent(navigation);
- }
-
Vector2 qofs;
SceneTree *st = SceneTree::get_singleton();
@@ -352,12 +328,10 @@ void TileMap::update_dirty_quadrants() {
}
int shape_idx = 0;
- if (navigation) {
- for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) {
- NavigationServer2D::get_singleton()->region_set_map(E->get().region, RID());
- }
- q.navpoly_ids.clear();
+ for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) {
+ NavigationServer2D::get_singleton()->region_set_map(E->get().region, RID());
}
+ q.navpoly_ids.clear();
for (Map<PosKey, Quadrant::Occluder>::Element *E = q.occluder_instances.front(); E; E = E->next()) {
RS::get_singleton()->free(E->get().id);
@@ -579,7 +553,7 @@ void TileMap::update_dirty_quadrants() {
vs->canvas_item_add_set_transform(debug_canvas_item, Transform2D());
}
- if (navigation) {
+ if (bake_navigation) {
Ref<NavigationPolygon> navpoly;
Vector2 npoly_ofs;
if (tile_set->tile_get_tile_mode(c.id) == TileSet::AUTO_TILE || tile_set->tile_get_tile_mode(c.id) == TileSet::ATLAS_TILE) {
@@ -596,8 +570,8 @@ void TileMap::update_dirty_quadrants() {
_fix_cell_transform(xform, c, npoly_ofs, s);
RID region = NavigationServer2D::get_singleton()->region_create();
- NavigationServer2D::get_singleton()->region_set_map(region, navigation->get_rid());
- NavigationServer2D::get_singleton()->region_set_transform(region, nav_rel * xform);
+ NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map());
+ NavigationServer2D::get_singleton()->region_set_transform(region, xform);
NavigationServer2D::get_singleton()->region_set_navpoly(region, navpoly);
Quadrant::NavPoly np;
@@ -787,12 +761,10 @@ void TileMap::_erase_quadrant(Map<PosKey, Quadrant>::Element *Q) {
dirty_quadrant_list.remove(&q.dirty_list);
}
- if (navigation) {
- for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) {
- NavigationServer2D::get_singleton()->region_set_map(E->get().region, RID());
- }
- q.navpoly_ids.clear();
+ for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) {
+ NavigationServer2D::get_singleton()->region_set_map(E->get().region, RID());
}
+ q.navpoly_ids.clear();
for (Map<PosKey, Quadrant::Occluder>::Element *E = q.occluder_instances.front(); E; E = E->next()) {
RS::get_singleton()->free(E->get().id);
@@ -1360,6 +1332,17 @@ float TileMap::get_collision_bounce() const {
return bounce;
}
+void TileMap::set_bake_navigation(bool p_bake_navigation) {
+ bake_navigation = p_bake_navigation;
+ for (Map<PosKey, Quadrant>::Element *F = quadrant_map.front(); F; F = F->next()) {
+ _make_quadrant_dirty(F);
+ }
+}
+
+bool TileMap::is_baking_navigation() {
+ return bake_navigation;
+}
+
uint32_t TileMap::get_collision_layer() const {
return collision_layer;
}
@@ -1784,6 +1767,9 @@ void TileMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_collision_bounce", "value"), &TileMap::set_collision_bounce);
ClassDB::bind_method(D_METHOD("get_collision_bounce"), &TileMap::get_collision_bounce);
+ ClassDB::bind_method(D_METHOD("set_bake_navigation", "bake_navigation"), &TileMap::set_bake_navigation);
+ ClassDB::bind_method(D_METHOD("is_baking_navigation"), &TileMap::is_baking_navigation);
+
ClassDB::bind_method(D_METHOD("set_occluder_light_mask", "mask"), &TileMap::set_occluder_light_mask);
ClassDB::bind_method(D_METHOD("get_occluder_light_mask"), &TileMap::get_occluder_light_mask);
@@ -1842,6 +1828,9 @@ void TileMap::_bind_methods() {
ADD_GROUP("Occluder", "occluder_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "occluder_light_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_occluder_light_mask", "get_occluder_light_mask");
+ ADD_GROUP("Navigation", "");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bake_navigation"), "set_bake_navigation", "is_baking_navigation");
+
ADD_PROPERTY_DEFAULT("format", FORMAT_1);
ADD_SIGNAL(MethodInfo("settings_changed"));
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index 3bf4587921..26c84a0bb9 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -33,7 +33,6 @@
#include "core/templates/self_list.h"
#include "core/templates/vset.h"
-#include "scene/2d/navigation_2d.h"
#include "scene/2d/node_2d.h"
#include "scene/resources/tile_set.h"
@@ -78,7 +77,7 @@ private:
bool use_parent = false;
CollisionObject2D *collision_parent = nullptr;
bool use_kinematic = false;
- Navigation2D *navigation = nullptr;
+ bool bake_navigation = false;
union PosKey {
struct {
@@ -295,6 +294,9 @@ public:
void set_collision_bounce(float p_bounce);
float get_collision_bounce() const;
+ void set_bake_navigation(bool p_bake_navigation);
+ bool is_baking_navigation();
+
void set_mode(Mode p_mode);
Mode get_mode() const;
diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp
index 23eda379be..749cf4ff9d 100644
--- a/scene/3d/area_3d.cpp
+++ b/scene/3d/area_3d.cpp
@@ -211,7 +211,7 @@ void Area3D::_clear_monitoring() {
Object *obj = ObjectDB::get_instance(E->key());
Node *node = Object::cast_to<Node>(obj);
- if (!node) { //node may have been deleted in previous frame or at other legiminate point
+ if (!node) { //node may have been deleted in previous frame or at other legitimate point
continue;
}
//ERR_CONTINUE(!node);
@@ -240,7 +240,7 @@ void Area3D::_clear_monitoring() {
Object *obj = ObjectDB::get_instance(E->key());
Node *node = Object::cast_to<Node>(obj);
- if (!node) { //node may have been deleted in previous frame or at other legiminate point
+ if (!node) { //node may have been deleted in previous frame or at other legitimate point
continue;
}
//ERR_CONTINUE(!node);
diff --git a/scene/3d/baked_lightmap.cpp b/scene/3d/baked_lightmap.cpp
index 402e2b8f40..95ffbe48c1 100644
--- a/scene/3d/baked_lightmap.cpp
+++ b/scene/3d/baked_lightmap.cpp
@@ -449,7 +449,7 @@ int32_t BakedLightmap::_compute_bsp_tree(const Vector<Vector3> &p_points, const
ERR_FAIL_COND_V(p_simplex_indices.size() <= 1, 0); //should not happen, this is a bug
// Failed to separate the tetrahedrons using planes
- // this means Delaunay borked at some point.
+ // this means Delaunay broke at some point.
// Luckily, because we are using tetrahedrons, we can resort to
// less precise but still working ways to generate the separating plane
// this will most likely look bad when interpolating, but at least it will not crash.
@@ -511,7 +511,7 @@ int32_t BakedLightmap::_compute_bsp_tree(const Vector<Vector3> &p_points, const
node.plane = best_plane;
if (indices_under.size() == 0) {
- //noting to do here
+ //nothing to do here
node.under = BSPNode::EMPTY_LEAF;
} else if (indices_under.size() == 1) {
node.under = -(indices_under[0] + 1);
@@ -520,7 +520,7 @@ int32_t BakedLightmap::_compute_bsp_tree(const Vector<Vector3> &p_points, const
}
if (indices_over.size() == 0) {
- //noting to do here
+ //nothing to do here
node.over = BSPNode::EMPTY_LEAF;
} else if (indices_over.size() == 1) {
node.over = -(indices_over[0] + 1);
@@ -660,7 +660,7 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, String p_image_d
}
// create mesh data for insert
- //get the base material textures, help compute altlas size and bounds
+ //get the base material textures, help compute atlas size and bounds
for (int m_i = 0; m_i < meshes_found.size(); m_i++) {
if (p_bake_step) {
float p = (float)(m_i) / meshes_found.size();
@@ -974,7 +974,7 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, String p_image_d
for (int i = 0; i < lightmapper->get_bake_texture_count(); i++) {
images.push_back(lightmapper->get_bake_texture(i));
}
- //we assume they are all the same, so lets create a large one for saving
+ //we assume they are all the same, so let's create a large one for saving
Ref<Image> large_image;
large_image.instance();
diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp
index f0623c625e..cd8d02233b 100644
--- a/scene/3d/camera_3d.cpp
+++ b/scene/3d/camera_3d.cpp
@@ -102,7 +102,7 @@ void Camera3D::_update_camera() {
void Camera3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_WORLD: {
- // Needs to track the Viewport because it's needed on NOTIFICATION_EXIT_WORLD
+ // Needs to track the Viewport because it's needed on NOTIFICATION_EXIT_WORLD
// and Spatial will handle it first, including clearing its reference to the Viewport,
// therefore making it impossible to subclasses to access it
viewport = get_viewport();
@@ -715,7 +715,7 @@ void ClippedCamera3D::_notification(int p_what) {
Vector3 ray_from = parent_plane.project(cam_pos);
- clip_offset = 0; //reset by defau;t
+ clip_offset = 0; //reset by default
{ //check if points changed
Vector<Vector3> local_points = get_near_plane_points();
diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp
index 849ef7a2bf..39880db29c 100644
--- a/scene/3d/collision_object_3d.cpp
+++ b/scene/3d/collision_object_3d.cpp
@@ -30,6 +30,7 @@
#include "collision_object_3d.h"
+#include "core/config/engine.h"
#include "mesh_instance_3d.h"
#include "scene/scene_string_names.h"
#include "servers/physics_server_3d.h"
@@ -139,7 +140,7 @@ void CollisionObject3D::_update_debug_shapes() {
}
void CollisionObject3D::_update_shape_data(uint32_t p_owner) {
- if (is_inside_tree() && get_tree()->is_debugging_collisions_hint()) {
+ if (is_inside_tree() && get_tree()->is_debugging_collisions_hint() && !Engine::get_singleton()->is_editor_hint()) {
if (debug_shapes_to_update.is_empty()) {
call_deferred("_update_debug_shapes");
}
diff --git a/scene/3d/decal.cpp b/scene/3d/decal.cpp
index b5eab35605..7d6abe458a 100644
--- a/scene/3d/decal.cpp
+++ b/scene/3d/decal.cpp
@@ -154,13 +154,11 @@ Vector<Face3> Decal::get_faces(uint32_t p_usage_flags) const {
return Vector<Face3>();
}
-#ifdef TOOLS_ENABLED
void Decal::_validate_property(PropertyInfo &property) const {
if (!distance_fade_enabled && (property.name == "distance_fade_begin" || property.name == "distance_fade_length")) {
property.usage = PROPERTY_USAGE_NOEDITOR;
}
}
-#endif
void Decal::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_extents", "extents"), &Decal::set_extents);
diff --git a/scene/3d/decal.h b/scene/3d/decal.h
index 20d86ee16c..ce19e76de1 100644
--- a/scene/3d/decal.h
+++ b/scene/3d/decal.h
@@ -62,12 +62,9 @@ private:
float distance_fade_begin = 10.0;
float distance_fade_length = 1.0;
-#ifdef TOOLS_ENABLED
- void _validate_property(PropertyInfo &property) const override;
-#endif
-
protected:
static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const override;
public:
void set_extents(const Vector3 &p_extents);
diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp
index 17a61b3e4d..e2cfc2ed87 100644
--- a/scene/3d/gpu_particles_3d.cpp
+++ b/scene/3d/gpu_particles_3d.cpp
@@ -348,7 +348,7 @@ void GPUParticles3D::_notification(int p_what) {
}
}
- // Use internal process when emitting and one_shot are on so that when
+ // Use internal process when emitting and one_shot is on so that when
// the shot ends the editor can properly update
if (p_what == NOTIFICATION_INTERNAL_PROCESS) {
if (one_shot && !is_emitting()) {
diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp
index 87f54022b3..f109640aef 100644
--- a/scene/3d/light_3d.cpp
+++ b/scene/3d/light_3d.cpp
@@ -204,7 +204,7 @@ bool Light3D::is_editor_only() const {
}
void Light3D::_validate_property(PropertyInfo &property) const {
- if (!shadow && (property.name == "shadow_color" || property.name == "shadow_color" || property.name == "shadow_bias" || property.name == "shadow_normal_bias" || property.name == "shadow_reverse_cull_face" || property.name == "shadow_transmittance_bias" || property.name == "shadow_blur")) {
+ if (!shadow && (property.name == "shadow_color" || property.name == "shadow_bias" || property.name == "shadow_normal_bias" || property.name == "shadow_reverse_cull_face" || property.name == "shadow_transmittance_bias" || property.name == "shadow_fog_fade" || property.name == "shadow_blur")) {
property.usage = PROPERTY_USAGE_NOEDITOR;
}
diff --git a/scene/3d/navigation_3d.cpp b/scene/3d/navigation_3d.cpp
deleted file mode 100644
index eaddec7601..0000000000
--- a/scene/3d/navigation_3d.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/*************************************************************************/
-/* navigation_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 "navigation_3d.h"
-
-#include "servers/navigation_server_3d.h"
-
-Vector<Vector3> Navigation3D::get_simple_path(const Vector3 &p_start, const Vector3 &p_end, bool p_optimize) const {
- return NavigationServer3D::get_singleton()->map_get_path(map, p_start, p_end, p_optimize);
-}
-
-Vector3 Navigation3D::get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, bool p_use_collision) const {
- return NavigationServer3D::get_singleton()->map_get_closest_point_to_segment(map, p_from, p_to, p_use_collision);
-}
-
-Vector3 Navigation3D::get_closest_point(const Vector3 &p_point) const {
- return NavigationServer3D::get_singleton()->map_get_closest_point(map, p_point);
-}
-
-Vector3 Navigation3D::get_closest_point_normal(const Vector3 &p_point) const {
- return NavigationServer3D::get_singleton()->map_get_closest_point_normal(map, p_point);
-}
-
-RID Navigation3D::get_closest_point_owner(const Vector3 &p_point) const {
- return NavigationServer3D::get_singleton()->map_get_closest_point_owner(map, p_point);
-}
-
-void Navigation3D::set_up_vector(const Vector3 &p_up) {
- up = p_up;
- NavigationServer3D::get_singleton()->map_set_up(map, up);
-}
-
-Vector3 Navigation3D::get_up_vector() const {
- return up;
-}
-
-void Navigation3D::set_cell_size(float p_cell_size) {
- cell_size = p_cell_size;
- NavigationServer3D::get_singleton()->map_set_cell_size(map, cell_size);
-}
-
-void Navigation3D::set_edge_connection_margin(float p_edge_connection_margin) {
- edge_connection_margin = p_edge_connection_margin;
- NavigationServer3D::get_singleton()->map_set_edge_connection_margin(map, edge_connection_margin);
-}
-
-void Navigation3D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("get_rid"), &Navigation3D::get_rid);
-
- ClassDB::bind_method(D_METHOD("get_simple_path", "start", "end", "optimize"), &Navigation3D::get_simple_path, DEFVAL(true));
- ClassDB::bind_method(D_METHOD("get_closest_point_to_segment", "start", "end", "use_collision"), &Navigation3D::get_closest_point_to_segment, DEFVAL(false));
- ClassDB::bind_method(D_METHOD("get_closest_point", "to_point"), &Navigation3D::get_closest_point);
- ClassDB::bind_method(D_METHOD("get_closest_point_normal", "to_point"), &Navigation3D::get_closest_point_normal);
- ClassDB::bind_method(D_METHOD("get_closest_point_owner", "to_point"), &Navigation3D::get_closest_point_owner);
-
- ClassDB::bind_method(D_METHOD("set_up_vector", "up"), &Navigation3D::set_up_vector);
- ClassDB::bind_method(D_METHOD("get_up_vector"), &Navigation3D::get_up_vector);
-
- ClassDB::bind_method(D_METHOD("set_cell_size", "cell_size"), &Navigation3D::set_cell_size);
- ClassDB::bind_method(D_METHOD("get_cell_size"), &Navigation3D::get_cell_size);
-
- ClassDB::bind_method(D_METHOD("set_edge_connection_margin", "margin"), &Navigation3D::set_edge_connection_margin);
- ClassDB::bind_method(D_METHOD("get_edge_connection_margin"), &Navigation3D::get_edge_connection_margin);
-
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "up_vector"), "set_up_vector", "get_up_vector");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cell_size"), "set_cell_size", "get_cell_size");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "edge_connection_margin"), "set_edge_connection_margin", "get_edge_connection_margin");
-}
-
-void Navigation3D::_notification(int p_what) {
- switch (p_what) {
- case NOTIFICATION_READY: {
- NavigationServer3D::get_singleton()->map_set_active(map, true);
- } break;
- case NOTIFICATION_EXIT_TREE: {
- NavigationServer3D::get_singleton()->map_set_active(map, false);
- } break;
- }
-}
-
-Navigation3D::Navigation3D() {
- map = NavigationServer3D::get_singleton()->map_create();
-
- set_cell_size(0.3);
- set_edge_connection_margin(5.0); // Five meters, depends a lot on the agent's radius
-}
-
-Navigation3D::~Navigation3D() {
- NavigationServer3D::get_singleton()->free(map);
-}
diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp
index 8917cc4664..21ca3d70dd 100644
--- a/scene/3d/navigation_agent_3d.cpp
+++ b/scene/3d/navigation_agent_3d.cpp
@@ -31,7 +31,6 @@
#include "navigation_agent_3d.h"
#include "core/config/engine.h"
-#include "scene/3d/navigation_3d.h"
#include "servers/navigation_server_3d.h"
void NavigationAgent3D::_bind_methods() {
@@ -47,9 +46,6 @@ void NavigationAgent3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_ignore_y", "ignore"), &NavigationAgent3D::set_ignore_y);
ClassDB::bind_method(D_METHOD("get_ignore_y"), &NavigationAgent3D::get_ignore_y);
- ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationAgent3D::set_navigation_node);
- ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationAgent3D::get_navigation_node);
-
ClassDB::bind_method(D_METHOD("set_neighbor_dist", "neighbor_dist"), &NavigationAgent3D::set_neighbor_dist);
ClassDB::bind_method(D_METHOD("get_neighbor_dist"), &NavigationAgent3D::get_neighbor_dist);
@@ -101,28 +97,10 @@ void NavigationAgent3D::_notification(int p_what) {
agent_parent = Object::cast_to<Node3D>(get_parent());
NavigationServer3D::get_singleton()->agent_set_callback(agent, this, "_avoidance_done");
-
- // Search the navigation node and set it
- {
- Navigation3D *nav = nullptr;
- Node *p = get_parent();
- while (p != nullptr) {
- nav = Object::cast_to<Navigation3D>(p);
- if (nav != nullptr) {
- p = nullptr;
- } else {
- p = p->get_parent();
- }
- }
-
- set_navigation(nav);
- }
-
set_physics_process_internal(true);
} break;
case NOTIFICATION_EXIT_TREE: {
agent_parent = nullptr;
- set_navigation(nullptr);
set_physics_process_internal(false);
} break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
@@ -154,25 +132,6 @@ NavigationAgent3D::~NavigationAgent3D() {
agent = RID(); // Pointless
}
-void NavigationAgent3D::set_navigation(Navigation3D *p_nav) {
- if (navigation == p_nav) {
- return; // Pointless
- }
-
- navigation = p_nav;
- NavigationServer3D::get_singleton()->agent_set_map(agent, navigation == nullptr ? RID() : navigation->get_rid());
-}
-
-void NavigationAgent3D::set_navigation_node(Node *p_nav) {
- Navigation3D *nav = Object::cast_to<Navigation3D>(p_nav);
- ERR_FAIL_COND(nav == nullptr);
- set_navigation(nav);
-}
-
-Node *NavigationAgent3D::get_navigation_node() const {
- return Object::cast_to<Node>(navigation);
-}
-
void NavigationAgent3D::set_target_desired_distance(real_t p_dd) {
target_desired_distance = p_dd;
}
@@ -303,7 +262,7 @@ void NavigationAgent3D::update_navigation() {
if (agent_parent == nullptr) {
return;
}
- if (navigation == nullptr) {
+ if (!agent_parent->is_inside_tree()) {
return;
}
if (update_frame_id == Engine::get_singleton()->get_physics_frames()) {
@@ -337,7 +296,7 @@ void NavigationAgent3D::update_navigation() {
}
if (reload_path) {
- navigation_path = NavigationServer3D::get_singleton()->map_get_path(navigation->get_rid(), o, target_location, true);
+ navigation_path = NavigationServer3D::get_singleton()->map_get_path(agent_parent->get_world_3d()->get_navigation_map(), o, target_location, true);
navigation_finished = false;
nav_path_index = 0;
emit_signal("path_changed");
diff --git a/scene/3d/navigation_agent_3d.h b/scene/3d/navigation_agent_3d.h
index bd890a051b..22db889618 100644
--- a/scene/3d/navigation_agent_3d.h
+++ b/scene/3d/navigation_agent_3d.h
@@ -35,13 +35,11 @@
#include "scene/main/node.h"
class Node3D;
-class Navigation3D;
class NavigationAgent3D : public Node {
GDCLASS(NavigationAgent3D, Node);
Node3D *agent_parent = nullptr;
- Navigation3D *navigation = nullptr;
RID agent;
@@ -76,14 +74,6 @@ public:
NavigationAgent3D();
virtual ~NavigationAgent3D();
- void set_navigation(Navigation3D *p_nav);
- const Navigation3D *get_navigation() const {
- return navigation;
- }
-
- void set_navigation_node(Node *p_nav);
- Node *get_navigation_node() const;
-
RID get_rid() const {
return agent;
}
diff --git a/scene/3d/navigation_obstacle_3d.cpp b/scene/3d/navigation_obstacle_3d.cpp
index 01bf7de913..df03bca4fd 100644
--- a/scene/3d/navigation_obstacle_3d.cpp
+++ b/scene/3d/navigation_obstacle_3d.cpp
@@ -31,55 +31,38 @@
#include "navigation_obstacle_3d.h"
#include "scene/3d/collision_shape_3d.h"
-#include "scene/3d/navigation_3d.h"
#include "scene/3d/physics_body_3d.h"
#include "servers/navigation_server_3d.h"
void NavigationObstacle3D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationObstacle3D::set_navigation_node);
- ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationObstacle3D::get_navigation_node);
}
void NavigationObstacle3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_READY: {
- update_agent_shape();
-
- // Search the navigation node and set it
- {
- Navigation3D *nav = nullptr;
- Node *p = get_parent();
- while (p != nullptr) {
- nav = Object::cast_to<Navigation3D>(p);
- if (nav != nullptr) {
- p = nullptr;
- } else {
- p = p->get_parent();
- }
- }
-
- set_navigation(nav);
- }
-
set_physics_process_internal(true);
} break;
case NOTIFICATION_EXIT_TREE: {
- set_navigation(nullptr);
set_physics_process_internal(false);
} break;
+ case NOTIFICATION_PARENTED: {
+ parent_node3d = Object::cast_to<Node3D>(get_parent());
+ update_agent_shape();
+ } break;
+ case NOTIFICATION_UNPARENTED: {
+ parent_node3d = nullptr;
+ } break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
- Node3D *spatial = Object::cast_to<Node3D>(get_parent());
- if (spatial) {
- NavigationServer3D::get_singleton()->agent_set_position(agent, spatial->get_global_transform().origin);
- }
-
- PhysicsBody3D *rigid = Object::cast_to<PhysicsBody3D>(get_parent());
- if (rigid) {
- Vector3 v = rigid->get_linear_velocity();
- NavigationServer3D::get_singleton()->agent_set_velocity(agent, v);
- NavigationServer3D::get_singleton()->agent_set_target_velocity(agent, v);
+ if (parent_node3d) {
+ NavigationServer3D::get_singleton()->agent_set_position(agent, parent_node3d->get_global_transform().origin);
+
+ PhysicsBody3D *rigid = Object::cast_to<PhysicsBody3D>(get_parent());
+ if (rigid) {
+ Vector3 v = rigid->get_linear_velocity();
+ NavigationServer3D::get_singleton()->agent_set_velocity(agent, v);
+ NavigationServer3D::get_singleton()->agent_set_target_velocity(agent, v);
+ }
}
-
} break;
}
}
@@ -93,29 +76,10 @@ NavigationObstacle3D::~NavigationObstacle3D() {
agent = RID(); // Pointless
}
-void NavigationObstacle3D::set_navigation(Navigation3D *p_nav) {
- if (navigation == p_nav) {
- return; // Pointless
- }
-
- navigation = p_nav;
- NavigationServer3D::get_singleton()->agent_set_map(agent, navigation == nullptr ? RID() : navigation->get_rid());
-}
-
-void NavigationObstacle3D::set_navigation_node(Node *p_nav) {
- Navigation3D *nav = Object::cast_to<Navigation3D>(p_nav);
- ERR_FAIL_COND(nav == nullptr);
- set_navigation(nav);
-}
-
-Node *NavigationObstacle3D::get_navigation_node() const {
- return Object::cast_to<Node>(navigation);
-}
-
String NavigationObstacle3D::get_configuration_warning() const {
String warning = Node::get_configuration_warning();
- if (!Object::cast_to<Node3D>(get_parent())) {
+ if (!parent_node3d) {
if (!warning.is_empty()) {
warning += "\n\n";
}
@@ -126,40 +90,38 @@ String NavigationObstacle3D::get_configuration_warning() const {
}
void NavigationObstacle3D::update_agent_shape() {
- Node *node = get_parent();
-
- // Estimate the radius of this physics body
- real_t radius = 0.0;
- for (int i(0); i < node->get_child_count(); i++) {
- // For each collision shape
- CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(node->get_child(i));
- if (cs) {
- // Take the distance between the Body center to the shape center
- real_t r = cs->get_transform().origin.length();
- if (cs->get_shape().is_valid()) {
- // and add the enclosing shape radius
- r += cs->get_shape()->get_enclosing_radius();
+ if (parent_node3d) {
+ // Estimate the radius of this physics body
+ real_t radius = 0.0;
+ for (int i(0); i < parent_node3d->get_child_count(); i++) {
+ // For each collision shape
+ CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(parent_node3d->get_child(i));
+ if (cs) {
+ // Take the distance between the Body center to the shape center
+ real_t r = cs->get_transform().origin.length();
+ if (cs->get_shape().is_valid()) {
+ // and add the enclosing shape radius
+ r += cs->get_shape()->get_enclosing_radius();
+ }
+ Vector3 s = cs->get_global_transform().basis.get_scale();
+ r *= MAX(s.x, MAX(s.y, s.z));
+ // Takes the biggest radius
+ radius = MAX(radius, r);
}
- Vector3 s = cs->get_global_transform().basis.get_scale();
- r *= MAX(s.x, MAX(s.y, s.z));
- // Takes the biggest radius
- radius = MAX(radius, r);
}
- }
- Node3D *spa = Object::cast_to<Node3D>(node);
- if (spa) {
- Vector3 s = spa->get_global_transform().basis.get_scale();
+
+ Vector3 s = parent_node3d->get_global_transform().basis.get_scale();
radius *= MAX(s.x, MAX(s.y, s.z));
- }
- if (radius == 0.0) {
- radius = 1.0; // Never a 0 radius
- }
+ if (radius == 0.0) {
+ radius = 1.0; // Never a 0 radius
+ }
- // Initialize the Agent as an object
- NavigationServer3D::get_singleton()->agent_set_neighbor_dist(agent, 0.0);
- NavigationServer3D::get_singleton()->agent_set_max_neighbors(agent, 0);
- NavigationServer3D::get_singleton()->agent_set_time_horizon(agent, 0.0);
- NavigationServer3D::get_singleton()->agent_set_radius(agent, radius);
- NavigationServer3D::get_singleton()->agent_set_max_speed(agent, 0.0);
+ // Initialize the Agent as an object
+ NavigationServer3D::get_singleton()->agent_set_neighbor_dist(agent, 0.0);
+ NavigationServer3D::get_singleton()->agent_set_max_neighbors(agent, 0);
+ NavigationServer3D::get_singleton()->agent_set_time_horizon(agent, 0.0);
+ NavigationServer3D::get_singleton()->agent_set_radius(agent, radius);
+ NavigationServer3D::get_singleton()->agent_set_max_speed(agent, 0.0);
+ }
}
diff --git a/scene/3d/navigation_obstacle_3d.h b/scene/3d/navigation_obstacle_3d.h
index b8d05b8a87..b1bb53724a 100644
--- a/scene/3d/navigation_obstacle_3d.h
+++ b/scene/3d/navigation_obstacle_3d.h
@@ -31,15 +31,13 @@
#ifndef NAVIGATION_OBSTACLE_H
#define NAVIGATION_OBSTACLE_H
+#include "scene/3d/node_3d.h"
#include "scene/main/node.h"
-class Navigation3D;
-
class NavigationObstacle3D : public Node {
GDCLASS(NavigationObstacle3D, Node);
- Navigation3D *navigation = nullptr;
-
+ Node3D *parent_node3d = nullptr;
RID agent;
protected:
@@ -50,14 +48,6 @@ public:
NavigationObstacle3D();
virtual ~NavigationObstacle3D();
- void set_navigation(Navigation3D *p_nav);
- const Navigation3D *get_navigation() const {
- return navigation;
- }
-
- void set_navigation_node(Node *p_nav);
- Node *get_navigation_node() const;
-
RID get_rid() const {
return agent;
}
diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation_region_3d.cpp
index 19bde94222..3ca704e4b8 100644
--- a/scene/3d/navigation_region_3d.cpp
+++ b/scene/3d/navigation_region_3d.cpp
@@ -32,7 +32,6 @@
#include "core/os/thread.h"
#include "mesh_instance_3d.h"
-#include "navigation_3d.h"
#include "servers/navigation_server_3d.h"
void NavigationRegion3D::set_enabled(bool p_enabled) {
@@ -48,9 +47,7 @@ void NavigationRegion3D::set_enabled(bool p_enabled) {
if (!enabled) {
NavigationServer3D::get_singleton()->region_set_map(region, RID());
} else {
- if (navigation) {
- NavigationServer3D::get_singleton()->region_set_map(region, navigation->get_rid());
- }
+ NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map());
}
if (debug_view) {
@@ -69,22 +66,21 @@ bool NavigationRegion3D::is_enabled() const {
return enabled;
}
+void NavigationRegion3D::set_layers(uint32_t p_layers) {
+ NavigationServer3D::get_singleton()->region_set_layers(region, p_layers);
+}
+
+uint32_t NavigationRegion3D::get_layers() const {
+ return NavigationServer3D::get_singleton()->region_get_layers(region);
+}
+
/////////////////////////////
void NavigationRegion3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
- Node3D *c = this;
- while (c) {
- navigation = Object::cast_to<Navigation3D>(c);
- if (navigation) {
- if (enabled) {
- NavigationServer3D::get_singleton()->region_set_map(region, navigation->get_rid());
- }
- break;
- }
-
- c = c->get_parent_spatial();
+ if (enabled) {
+ NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map());
}
if (navmesh.is_valid() && get_tree()->is_debugging_navigation_hint()) {
@@ -105,15 +101,12 @@ void NavigationRegion3D::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_TREE: {
- if (navigation) {
- NavigationServer3D::get_singleton()->region_set_map(region, RID());
- }
+ NavigationServer3D::get_singleton()->region_set_map(region, RID());
if (debug_view) {
debug_view->queue_delete();
debug_view = nullptr;
}
- navigation = nullptr;
} break;
}
}
@@ -198,19 +191,7 @@ String NavigationRegion3D::get_configuration_warning() const {
warning += TTR("A NavigationMesh resource must be set or created for this node to work.");
}
- const Node3D *c = this;
- while (c) {
- if (Object::cast_to<Navigation3D>(c)) {
- return warning;
- }
-
- c = Object::cast_to<Node3D>(c->get_parent());
- }
-
- if (!warning.is_empty()) {
- warning += "\n\n";
- }
- return warning + TTR("NavigationRegion3D must be a child or grandchild to a Navigation3D node. It only provides navigation data.");
+ return warning;
}
void NavigationRegion3D::_bind_methods() {
@@ -220,11 +201,15 @@ void NavigationRegion3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationRegion3D::set_enabled);
ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationRegion3D::is_enabled);
+ ClassDB::bind_method(D_METHOD("set_layers", "layers"), &NavigationRegion3D::set_layers);
+ ClassDB::bind_method(D_METHOD("get_layers"), &NavigationRegion3D::get_layers);
+
ClassDB::bind_method(D_METHOD("bake_navigation_mesh"), &NavigationRegion3D::bake_navigation_mesh);
ClassDB::bind_method(D_METHOD("_bake_finished", "nav_mesh"), &NavigationRegion3D::_bake_finished);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "navmesh", PROPERTY_HINT_RESOURCE_TYPE, "NavigationMesh"), "set_navigation_mesh", "get_navigation_mesh");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "layers", PROPERTY_HINT_LAYERS_3D_NAVIGATION), "set_layers", "get_layers");
ADD_SIGNAL(MethodInfo("navigation_mesh_changed"));
ADD_SIGNAL(MethodInfo("bake_finished"));
diff --git a/scene/3d/navigation_region_3d.h b/scene/3d/navigation_region_3d.h
index 6ae15c9360..52fa2d6159 100644
--- a/scene/3d/navigation_region_3d.h
+++ b/scene/3d/navigation_region_3d.h
@@ -35,8 +35,6 @@
#include "scene/resources/mesh.h"
#include "scene/resources/navigation_mesh.h"
-class Navigation3D;
-
class NavigationRegion3D : public Node3D {
GDCLASS(NavigationRegion3D, Node3D);
@@ -44,7 +42,6 @@ class NavigationRegion3D : public Node3D {
RID region;
Ref<NavigationMesh> navmesh;
- Navigation3D *navigation = nullptr;
Node *debug_view = nullptr;
Thread bake_thread;
@@ -58,6 +55,9 @@ public:
void set_enabled(bool p_enabled);
bool is_enabled() const;
+ void set_layers(uint32_t p_layers);
+ uint32_t get_layers() const;
+
void set_navigation_mesh(const Ref<NavigationMesh> &p_navmesh);
Ref<NavigationMesh> get_navigation_mesh() const;
diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp
index 4575716f7a..ba0f8cc870 100644
--- a/scene/3d/node_3d.cpp
+++ b/scene/3d/node_3d.cpp
@@ -48,7 +48,7 @@
a) If above is invalid, don't keep invalidating upwards
2) If a node sets a GLOBAL, it is converted to LOCAL (and forces validation of everything pending below)
- drawback: setting/reading globals is useful and used very very often, and using affine inverses is slow
+ drawback: setting/reading globals is useful and used very often, and using affine inverses is slow
---
diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp
index 6d135c8283..e225c1f22d 100644
--- a/scene/3d/physics_body_3d.cpp
+++ b/scene/3d/physics_body_3d.cpp
@@ -416,13 +416,13 @@ void RigidBody3D::_direct_state_changed(Object *p_state) {
}
}
- //process remotions
+ //process removals
for (int i = 0; i < toremove_count; i++) {
_body_inout(0, toremove[i].body_id, toremove[i].pair.body_shape, toremove[i].pair.local_shape);
}
- //process aditions
+ //process additions
for (int i = 0; i < toadd_count; i++) {
_body_inout(1, toadd[i].id, toadd[i].shape, toadd[i].local_shape);
diff --git a/scene/3d/ray_cast_3d.cpp b/scene/3d/ray_cast_3d.cpp
index 465de2cb47..66f3e539a2 100644
--- a/scene/3d/ray_cast_3d.cpp
+++ b/scene/3d/ray_cast_3d.cpp
@@ -428,10 +428,10 @@ void RayCast3D::_update_debug_shape_material(bool p_check_collision) {
if (p_check_collision) {
if ((color.get_h() < 0.055 || color.get_h() > 0.945) && color.get_s() > 0.5 && color.get_v() > 0.5) {
- // If base color is already quite reddish, hightlight collision with green color
+ // If base color is already quite reddish, highlight collision with green color
color = Color(0.0, 1.0, 0.0, color.a);
} else {
- // Else, hightlight collision with red color
+ // Else, highlight collision with red color
color = Color(1.0, 0, 0, color.a);
}
}
diff --git a/scene/3d/skeleton_ik_3d.cpp b/scene/3d/skeleton_ik_3d.cpp
index cb486a12ae..85da546430 100644
--- a/scene/3d/skeleton_ik_3d.cpp
+++ b/scene/3d/skeleton_ik_3d.cpp
@@ -63,7 +63,6 @@ bool FabrikInverseKinematic::build_chain(Task *p_task, bool p_force_simple_chain
chain.chain_root.bone = p_task->root_bone;
chain.chain_root.initial_transform = p_task->skeleton->get_bone_global_pose(chain.chain_root.bone);
chain.chain_root.current_pos = chain.chain_root.initial_transform.origin;
- chain.chain_root.pb = p_task->skeleton->get_physical_bone(chain.chain_root.bone);
chain.middle_chain_item = nullptr;
// Holds all IDs that are composing a single chain in reverse order
@@ -96,8 +95,6 @@ bool FabrikInverseKinematic::build_chain(Task *p_task, bool p_force_simple_chain
if (!child_ci) {
child_ci = sub_chain->add_child(chain_ids[i]);
- child_ci->pb = p_task->skeleton->get_physical_bone(child_ci->bone);
-
child_ci->initial_transform = p_task->skeleton->get_bone_global_pose(child_ci->bone);
child_ci->current_pos = child_ci->initial_transform.origin;
@@ -123,7 +120,7 @@ bool FabrikInverseKinematic::build_chain(Task *p_task, bool p_force_simple_chain
if (p_force_simple_chain) {
// NOTE:
- // This is an "hack" that force to create only one tip per chain since the solver of multi tip (end effector)
+ // This is a "hack" that force to create only one tip per chain since the solver of multi tip (end effector)
// is not yet created.
// Remove this code when this is done
break;
@@ -132,20 +129,6 @@ bool FabrikInverseKinematic::build_chain(Task *p_task, bool p_force_simple_chain
return true;
}
-void FabrikInverseKinematic::update_chain(const Skeleton3D *p_sk, ChainItem *p_chain_item) {
- if (!p_chain_item) {
- return;
- }
-
- p_chain_item->initial_transform = p_sk->get_bone_global_pose(p_chain_item->bone);
- p_chain_item->current_pos = p_chain_item->initial_transform.origin;
-
- ChainItem *items = p_chain_item->children.ptrw();
- for (int i = 0; i < p_chain_item->children.size(); i += 1) {
- update_chain(p_sk, items + i);
- }
-}
-
void FabrikInverseKinematic::solve_simple(Task *p_task, bool p_solve_magnet) {
real_t distance_to_goal(1e4);
real_t previous_distance_to_goal(0);
@@ -263,7 +246,7 @@ void FabrikInverseKinematic::make_goal(Task *p_task, const Transform &p_inverse_
p_task->end_effectors.write[0].goal_transform = p_inverse_transf * p_task->goal_global_transform;
} else {
// End effector in local transform
- const Transform end_effector_pose(p_task->skeleton->get_bone_global_pose(p_task->end_effectors.write[0].tip_bone));
+ const Transform end_effector_pose(p_task->skeleton->get_bone_global_pose(p_task->end_effectors[0].tip_bone));
// Update the end_effector (local transform) by blending with current pose
p_task->end_effectors.write[0].goal_transform = end_effector_pose.interpolate_with(p_inverse_transf * p_task->goal_global_transform, blending_delta);
@@ -285,9 +268,11 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove
p_task->skeleton->set_bone_global_pose_override(p_task->chain.tips[i].chain_item->bone, Transform(), 0.0, true);
}
- make_goal(p_task, p_task->skeleton->get_global_transform().affine_inverse().scaled(p_task->skeleton->get_global_transform().get_basis().get_scale()), blending_delta);
+ // Update the initial root transform
+ p_task->chain.chain_root.initial_transform = p_task->skeleton->get_bone_global_pose(p_task->chain.chain_root.bone);
+ p_task->chain.chain_root.current_pos = p_task->chain.chain_root.initial_transform.origin;
- update_chain(p_task->skeleton, &p_task->chain.chain_root);
+ make_goal(p_task, p_task->skeleton->get_global_transform().affine_inverse(), blending_delta);
if (p_use_magnet && p_task->chain.middle_chain_item) {
p_task->chain.magnet_position = p_task->chain.middle_chain_item->initial_transform.origin.lerp(p_magnet_position, blending_delta);
@@ -310,6 +295,7 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove
const real_t rot_angle(Math::acos(CLAMP(initial_ori.dot(ci->current_ori), -1, 1)));
new_bone_pose.basis.rotate(rot_axis, rot_angle);
}
+
} else {
// Set target orientation to tip
if (override_tip_basis) {
@@ -319,6 +305,10 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove
}
}
+ // IK should not affect scale, so undo any scaling
+ new_bone_pose.basis.orthonormalize();
+ new_bone_pose.basis.scale(p_task->skeleton->get_bone_global_pose(ci->bone).basis.get_scale());
+
p_task->skeleton->set_bone_global_pose_override(ci->bone, new_bone_pose, 1.0, true);
if (!ci->children.is_empty()) {
diff --git a/scene/3d/skeleton_ik_3d.h b/scene/3d/skeleton_ik_3d.h
index eefecf68bb..c98f55804c 100644
--- a/scene/3d/skeleton_ik_3d.h
+++ b/scene/3d/skeleton_ik_3d.h
@@ -52,7 +52,6 @@ class FabrikInverseKinematic {
// Bone info
BoneId bone = -1;
- PhysicalBone3D *pb = nullptr;
real_t length = 0.0;
/// Positions relative to root bone
@@ -107,8 +106,6 @@ private:
/// Init a chain that starts from the root to tip
static bool build_chain(Task *p_task, bool p_force_simple_chain = true);
- static void update_chain(const Skeleton3D *p_sk, ChainItem *p_chain_item);
-
static void solve_simple(Task *p_task, bool p_solve_magnet);
/// Special solvers that solve only chains with one end effector
static void solve_simple_backwards(Chain &r_chain, bool p_solve_magnet);
diff --git a/scene/3d/soft_body_3d.cpp b/scene/3d/soft_body_3d.cpp
index 2d8f22ab37..3fde4d6ef3 100644
--- a/scene/3d/soft_body_3d.cpp
+++ b/scene/3d/soft_body_3d.cpp
@@ -37,7 +37,6 @@
#include "scene/3d/collision_object_3d.h"
#include "scene/3d/physics_body_3d.h"
#include "scene/3d/skeleton_3d.h"
-#include "servers/physics_server_3d.h"
SoftBodyRenderingServerHandler::SoftBodyRenderingServerHandler() {}
@@ -48,27 +47,28 @@ void SoftBodyRenderingServerHandler::prepare(RID p_mesh, int p_surface) {
mesh = p_mesh;
surface = p_surface;
-#ifndef _MSC_VER
-#warning Softbody is not working, needs to be redone considering that these functions no longer exist
-#endif
-#if 0
- const uint32_t surface_format = RS::get_singleton()->mesh_surface_get_format(mesh, surface);
- const int surface_vertex_len = RS::get_singleton()->mesh_surface_get_array_len(mesh, p_surface);
- const int surface_index_len = RS::get_singleton()->mesh_surface_get_array_index_len(mesh, p_surface);
+
+ RS::SurfaceData surface_data = RS::get_singleton()->mesh_get_surface(mesh, surface);
+
uint32_t surface_offsets[RS::ARRAY_MAX];
+ uint32_t vertex_stride;
+ uint32_t attrib_stride;
+ uint32_t skin_stride;
+ RS::get_singleton()->mesh_surface_make_offsets_from_format(surface_data.format, surface_data.vertex_count, surface_data.index_count, surface_offsets, vertex_stride, attrib_stride, skin_stride);
- buffer = RS::get_singleton()->mesh_surface_get_array(mesh, surface);
- stride = RS::get_singleton()->mesh_surface_make_offsets_from_format(surface_format, surface_vertex_len, surface_index_len, surface_offsets);
+ buffer = surface_data.vertex_data;
+ stride = vertex_stride;
offset_vertices = surface_offsets[RS::ARRAY_VERTEX];
offset_normal = surface_offsets[RS::ARRAY_NORMAL];
-#endif
}
void SoftBodyRenderingServerHandler::clear() {
- if (mesh.is_valid()) {
- buffer.resize(0);
- }
+ buffer.resize(0);
+ stride = 0;
+ offset_vertices = 0;
+ offset_normal = 0;
+ surface = 0;
mesh = RID();
}
@@ -77,7 +77,7 @@ void SoftBodyRenderingServerHandler::open() {
}
void SoftBodyRenderingServerHandler::close() {
- //write_buffer.release();
+ write_buffer = nullptr;
}
void SoftBodyRenderingServerHandler::commit_changes() {
@@ -309,6 +309,8 @@ void SoftBody3D::_notification(int p_what) {
}
void SoftBody3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_physics_rid"), &SoftBody3D::get_physics_rid);
+
ClassDB::bind_method(D_METHOD("set_collision_mask", "collision_mask"), &SoftBody3D::set_collision_mask);
ClassDB::bind_method(D_METHOD("get_collision_mask"), &SoftBody3D::get_collision_mask);
@@ -337,18 +339,9 @@ void SoftBody3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_linear_stiffness", "linear_stiffness"), &SoftBody3D::set_linear_stiffness);
ClassDB::bind_method(D_METHOD("get_linear_stiffness"), &SoftBody3D::get_linear_stiffness);
- ClassDB::bind_method(D_METHOD("set_angular_stiffness", "angular_stiffness"), &SoftBody3D::set_angular_stiffness);
- ClassDB::bind_method(D_METHOD("get_angular_stiffness"), &SoftBody3D::get_angular_stiffness);
-
- ClassDB::bind_method(D_METHOD("set_volume_stiffness", "volume_stiffness"), &SoftBody3D::set_volume_stiffness);
- ClassDB::bind_method(D_METHOD("get_volume_stiffness"), &SoftBody3D::get_volume_stiffness);
-
ClassDB::bind_method(D_METHOD("set_pressure_coefficient", "pressure_coefficient"), &SoftBody3D::set_pressure_coefficient);
ClassDB::bind_method(D_METHOD("get_pressure_coefficient"), &SoftBody3D::get_pressure_coefficient);
- ClassDB::bind_method(D_METHOD("set_pose_matching_coefficient", "pose_matching_coefficient"), &SoftBody3D::set_pose_matching_coefficient);
- ClassDB::bind_method(D_METHOD("get_pose_matching_coefficient"), &SoftBody3D::get_pose_matching_coefficient);
-
ClassDB::bind_method(D_METHOD("set_damping_coefficient", "damping_coefficient"), &SoftBody3D::set_damping_coefficient);
ClassDB::bind_method(D_METHOD("get_damping_coefficient"), &SoftBody3D::get_damping_coefficient);
@@ -366,12 +359,9 @@ void SoftBody3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "simulation_precision", PROPERTY_HINT_RANGE, "1,100,1"), "set_simulation_precision", "get_simulation_precision");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "total_mass", PROPERTY_HINT_RANGE, "0.01,10000,1"), "set_total_mass", "get_total_mass");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_linear_stiffness", "get_linear_stiffness");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_angular_stiffness", "get_angular_stiffness");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volume_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_volume_stiffness", "get_volume_stiffness");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pressure_coefficient"), "set_pressure_coefficient", "get_pressure_coefficient");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "damping_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_damping_coefficient", "get_damping_coefficient");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "drag_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_coefficient", "get_drag_coefficient");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pose_matching_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_pose_matching_coefficient", "get_pose_matching_coefficient");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ray_pickable"), "set_ray_pickable", "is_ray_pickable");
}
@@ -612,34 +602,10 @@ real_t SoftBody3D::get_linear_stiffness() {
return PhysicsServer3D::get_singleton()->soft_body_get_linear_stiffness(physics_rid);
}
-void SoftBody3D::set_angular_stiffness(real_t p_angular_stiffness) {
- PhysicsServer3D::get_singleton()->soft_body_set_angular_stiffness(physics_rid, p_angular_stiffness);
-}
-
-real_t SoftBody3D::get_angular_stiffness() {
- return PhysicsServer3D::get_singleton()->soft_body_get_angular_stiffness(physics_rid);
-}
-
-void SoftBody3D::set_volume_stiffness(real_t p_volume_stiffness) {
- PhysicsServer3D::get_singleton()->soft_body_set_volume_stiffness(physics_rid, p_volume_stiffness);
-}
-
-real_t SoftBody3D::get_volume_stiffness() {
- return PhysicsServer3D::get_singleton()->soft_body_get_volume_stiffness(physics_rid);
-}
-
real_t SoftBody3D::get_pressure_coefficient() {
return PhysicsServer3D::get_singleton()->soft_body_get_pressure_coefficient(physics_rid);
}
-void SoftBody3D::set_pose_matching_coefficient(real_t p_pose_matching_coefficient) {
- PhysicsServer3D::get_singleton()->soft_body_set_pose_matching_coefficient(physics_rid, p_pose_matching_coefficient);
-}
-
-real_t SoftBody3D::get_pose_matching_coefficient() {
- return PhysicsServer3D::get_singleton()->soft_body_get_pose_matching_coefficient(physics_rid);
-}
-
void SoftBody3D::set_pressure_coefficient(real_t p_pressure_coefficient) {
PhysicsServer3D::get_singleton()->soft_body_set_pressure_coefficient(physics_rid, p_pressure_coefficient);
}
@@ -768,7 +734,9 @@ void SoftBody3D::_reset_points_offsets() {
PinnedPoint *w = pinned_points.ptrw();
for (int i = pinned_points.size() - 1; 0 <= i; --i) {
if (!r[i].spatial_attachment) {
- w[i].spatial_attachment = Object::cast_to<Node3D>(get_node(r[i].spatial_attachment_path));
+ if (!r[i].spatial_attachment_path.is_empty() && has_node(r[i].spatial_attachment_path)) {
+ w[i].spatial_attachment = Object::cast_to<Node3D>(get_node(r[i].spatial_attachment_path));
+ }
}
if (!r[i].spatial_attachment) {
diff --git a/scene/3d/soft_body_3d.h b/scene/3d/soft_body_3d.h
index 6e24a530bd..f98df39209 100644
--- a/scene/3d/soft_body_3d.h
+++ b/scene/3d/soft_body_3d.h
@@ -32,10 +32,11 @@
#define SOFT_PHYSICS_BODY_H
#include "scene/3d/mesh_instance_3d.h"
+#include "servers/physics_server_3d.h"
class SoftBody3D;
-class SoftBodyRenderingServerHandler {
+class SoftBodyRenderingServerHandler : public RenderingServerHandler {
friend class SoftBody3D;
RID mesh;
@@ -57,9 +58,9 @@ private:
void commit_changes();
public:
- void set_vertex(int p_vertex_id, const void *p_vector3);
- void set_normal(int p_vertex_id, const void *p_vector3);
- void set_aabb(const AABB &p_aabb);
+ void set_vertex(int p_vertex_id, const void *p_vector3) override;
+ void set_normal(int p_vertex_id, const void *p_vector3) override;
+ void set_aabb(const AABB &p_aabb) override;
};
class SoftBody3D : public MeshInstance3D {
@@ -122,6 +123,8 @@ public:
void prepare_physics_server();
void become_mesh_owner();
+ RID get_physics_rid() const { return physics_rid; }
+
void set_collision_mask(uint32_t p_mask);
uint32_t get_collision_mask() const;
@@ -149,18 +152,9 @@ public:
void set_linear_stiffness(real_t p_linear_stiffness);
real_t get_linear_stiffness();
- void set_angular_stiffness(real_t p_angular_stiffness);
- real_t get_angular_stiffness();
-
- void set_volume_stiffness(real_t p_volume_stiffness);
- real_t get_volume_stiffness();
-
void set_pressure_coefficient(real_t p_pressure_coefficient);
real_t get_pressure_coefficient();
- void set_pose_matching_coefficient(real_t p_pose_matching_coefficient);
- real_t get_pose_matching_coefficient();
-
void set_damping_coefficient(real_t p_damping_coefficient);
real_t get_damping_coefficient();
diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp
index f881181ccd..0be54e7243 100644
--- a/scene/3d/sprite_3d.cpp
+++ b/scene/3d/sprite_3d.cpp
@@ -366,7 +366,7 @@ void Sprite3D::_draw() {
}
Rect2 base_rect;
- if (region) {
+ if (region_enabled) {
base_rect = region_rect;
} else {
base_rect = Rect2(0, 0, texture->get_width(), texture->get_height());
@@ -511,24 +511,24 @@ Ref<Texture2D> Sprite3D::get_texture() const {
return texture;
}
-void Sprite3D::set_region(bool p_region) {
- if (p_region == region) {
+void Sprite3D::set_region_enabled(bool p_region_enabled) {
+ if (p_region_enabled == region_enabled) {
return;
}
- region = p_region;
+ region_enabled = p_region_enabled;
_queue_update();
notify_property_list_changed();
}
-bool Sprite3D::is_region() const {
- return region;
+bool Sprite3D::is_region_enabled() const {
+ return region_enabled;
}
void Sprite3D::set_region_rect(const Rect2 &p_region_rect) {
bool changed = region_rect != p_region_rect;
region_rect = p_region_rect;
- if (region && changed) {
+ if (region_enabled && changed) {
_queue_update();
}
}
@@ -595,7 +595,7 @@ Rect2 Sprite3D::get_item_rect() const {
Size2i s;
- if (region) {
+ if (region_enabled) {
s = region_rect.size;
} else {
s = texture->get_size();
@@ -625,19 +625,17 @@ void Sprite3D::_validate_property(PropertyInfo &property) const {
property.usage |= PROPERTY_USAGE_KEYING_INCREMENTS;
}
-#ifdef TOOLS_ENABLED
- if (!region && property.name == "region_rect") {
+ if (!region_enabled && property.name == "region_rect") {
property.usage = PROPERTY_USAGE_NOEDITOR;
}
-#endif
}
void Sprite3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_texture", "texture"), &Sprite3D::set_texture);
ClassDB::bind_method(D_METHOD("get_texture"), &Sprite3D::get_texture);
- ClassDB::bind_method(D_METHOD("set_region", "enabled"), &Sprite3D::set_region);
- ClassDB::bind_method(D_METHOD("is_region"), &Sprite3D::is_region);
+ ClassDB::bind_method(D_METHOD("set_region_enabled", "enabled"), &Sprite3D::set_region_enabled);
+ ClassDB::bind_method(D_METHOD("is_region_enabled"), &Sprite3D::is_region_enabled);
ClassDB::bind_method(D_METHOD("set_region_rect", "rect"), &Sprite3D::set_region_rect);
ClassDB::bind_method(D_METHOD("get_region_rect"), &Sprite3D::get_region_rect);
@@ -661,14 +659,14 @@ void Sprite3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "frame_coords", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_frame_coords", "get_frame_coords");
ADD_GROUP("Region", "region_");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "region_enabled"), "set_region", "is_region");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "region_enabled"), "set_region_enabled", "is_region_enabled");
ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect");
ADD_SIGNAL(MethodInfo("frame_changed"));
}
Sprite3D::Sprite3D() {
- region = false;
+ region_enabled = false;
frame = 0;
vframes = 1;
hframes = 1;
@@ -694,7 +692,7 @@ void AnimatedSprite3D::_draw() {
Ref<Texture2D> texture = frames->get_frame(animation, frame);
if (!texture.is_valid()) {
- return; //no texuture no life
+ return; //no texture no life
}
Vector2 tsize = texture->get_size();
if (tsize.x == 0 || tsize.y == 0) {
diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h
index a9ce2d8eee..b48660eb2d 100644
--- a/scene/3d/sprite_3d.h
+++ b/scene/3d/sprite_3d.h
@@ -31,8 +31,8 @@
#ifndef SPRITE_3D_H
#define SPRITE_3D_H
-#include "scene/2d/animated_sprite_2d.h"
#include "scene/3d/visual_instance_3d.h"
+#include "scene/resources/sprite_frames.h"
class SpriteBase3D : public GeometryInstance3D {
GDCLASS(SpriteBase3D, GeometryInstance3D);
@@ -107,8 +107,8 @@ public:
void set_flip_v(bool p_flip);
bool is_flipped_v() const;
- void set_region(bool p_region);
- bool is_region() const;
+ void set_region_enabled(bool p_region_enabled);
+ bool is_region_enabled() const;
void set_region_rect(const Rect2 &p_region_rect);
Rect2 get_region_rect() const;
@@ -147,7 +147,7 @@ class Sprite3D : public SpriteBase3D {
GDCLASS(Sprite3D, SpriteBase3D);
Ref<Texture2D> texture;
- bool region;
+ bool region_enabled;
Rect2 region_rect;
int frame;
@@ -167,8 +167,8 @@ public:
void set_texture(const Ref<Texture2D> &p_texture);
Ref<Texture2D> get_texture() const;
- void set_region(bool p_region);
- bool is_region() const;
+ void set_region_enabled(bool p_region_enabled);
+ bool is_region_enabled() const;
void set_region_rect(const Rect2 &p_region_rect);
Rect2 get_region_rect() const;
diff --git a/scene/3d/vehicle_body_3d.cpp b/scene/3d/vehicle_body_3d.cpp
index 0d25e2f21f..5b0b3b89d3 100644
--- a/scene/3d/vehicle_body_3d.cpp
+++ b/scene/3d/vehicle_body_3d.cpp
@@ -407,7 +407,7 @@ real_t VehicleBody3D::_ray_cast(int p_idx, PhysicsDirectBodyState3D *s) {
PhysicsDirectSpaceState3D *ss = s->get_space_state();
- bool col = ss->intersect_ray(source, target, rr, exclude);
+ bool col = ss->intersect_ray(source, target, rr, exclude, get_collision_mask());
wheel.m_raycastInfo.m_groundObject = nullptr;
@@ -563,7 +563,7 @@ void VehicleBody3D::_resolve_single_bilateral(PhysicsDirectBodyState3D *s, const
b2invmass);
// FIXME: rel_vel assignment here is overwritten by the following assignment.
- // What seems to be intended in the next next assignment is: rel_vel = normal.dot(rel_vel);
+ // What seems to be intended in the next assignment is: rel_vel = normal.dot(rel_vel);
// Investigate why.
real_t rel_vel = jac.getRelativeVelocity(
s->get_linear_velocity(),
diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp
index 17c8596e8f..1b9ce0201f 100644
--- a/scene/3d/voxelizer.cpp
+++ b/scene/3d/voxelizer.cpp
@@ -151,7 +151,7 @@ void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, co
Vector2 uv;
Vector3 lnormal;
get_uv_and_normal(intersection, p_vtx, p_uv, p_normal, uv, lnormal);
- if (lnormal == Vector3()) { //just in case normal as nor provided
+ if (lnormal == Vector3()) { //just in case normal is not provided
lnormal = normal;
}
@@ -183,7 +183,7 @@ void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, co
Vector3 lnormal;
Vector2 uv;
get_uv_and_normal(inters, p_vtx, p_uv, p_normal, uv, normal);
- if (lnormal == Vector3()) { //just in case normal as nor provided
+ if (lnormal == Vector3()) { //just in case normal is not provided
lnormal = normal;
}
@@ -344,7 +344,7 @@ Voxelizer::MaterialCache Voxelizer::_get_material_cache(Ref<Material> p_material
Ref<Image> img_albedo;
if (albedo_tex.is_valid()) {
- img_albedo = albedo_tex->get_data();
+ img_albedo = albedo_tex->get_image();
mc.albedo = _get_bake_texture(img_albedo, mat->get_albedo(), Color(0, 0, 0)); // albedo texture, color is multiplicative
} else {
mc.albedo = _get_bake_texture(img_albedo, Color(1, 1, 1), mat->get_albedo()); // no albedo texture, color is additive
@@ -358,7 +358,7 @@ Voxelizer::MaterialCache Voxelizer::_get_material_cache(Ref<Material> p_material
Ref<Image> img_emission;
if (emission_tex.is_valid()) {
- img_emission = emission_tex->get_data();
+ img_emission = emission_tex->get_image();
}
if (mat->get_emission_operator() == StandardMaterial3D::EMISSION_OP_ADD) {
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index 2c19307c52..0c1798a876 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -605,7 +605,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
}
if (p_seeked) {
- //find whathever should be playing
+ //find whatever should be playing
int idx = a->track_find_key(i, p_time);
if (idx < 0) {
continue;
@@ -634,7 +634,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
nc->audio_playing = true;
playing_caches.insert(nc);
- if (len && end_ofs > 0) { //force a end at a time
+ if (len && end_ofs > 0) { //force an end at a time
nc->audio_len = len - start_ofs - end_ofs;
} else {
nc->audio_len = 0;
@@ -665,7 +665,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
nc->audio_playing = true;
playing_caches.insert(nc);
- if (len && end_ofs > 0) { //force a end at a time
+ if (len && end_ofs > 0) { //force an end at a time
nc->audio_len = len - start_ofs - end_ofs;
} else {
nc->audio_len = 0;
@@ -1343,7 +1343,7 @@ void AnimationPlayer::_stop_playing_caches() {
}
void AnimationPlayer::_node_removed(Node *p_node) {
- clear_caches(); // nodes contained here ar being removed, clear the caches
+ clear_caches(); // nodes contained here are being removed, clear the caches
}
void AnimationPlayer::clear_caches() {
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp
index 26a13f33c9..4b4d3943c9 100644
--- a/scene/animation/animation_tree.cpp
+++ b/scene/animation/animation_tree.cpp
@@ -1009,7 +1009,7 @@ void AnimationTree::_process_graph(float p_delta) {
TrackCacheAudio *t = static_cast<TrackCacheAudio *>(track);
if (seeked) {
- //find whathever should be playing
+ //find whatever should be playing
int idx = a->track_find_key(i, time);
if (idx < 0) {
continue;
@@ -1038,7 +1038,7 @@ void AnimationTree::_process_graph(float p_delta) {
t->playing = true;
playing_caches.insert(t);
- if (len && end_ofs > 0) { //force a end at a time
+ if (len && end_ofs > 0) { //force an end at a time
t->len = len - start_ofs - end_ofs;
} else {
t->len = 0;
@@ -1069,7 +1069,7 @@ void AnimationTree::_process_graph(float p_delta) {
t->playing = true;
playing_caches.insert(t);
- if (len && end_ofs > 0) { //force a end at a time
+ if (len && end_ofs > 0) { //force an end at a time
t->len = len - start_ofs - end_ofs;
} else {
t->len = 0;
@@ -1337,6 +1337,7 @@ void AnimationTree::_tree_changed() {
}
void AnimationTree::_update_properties_for_node(const String &p_base_path, Ref<AnimationNode> node) {
+ ERR_FAIL_COND(node.is_null());
if (!property_parent_map.has(p_base_path)) {
property_parent_map[p_base_path] = HashMap<StringName, StringName>();
}
diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp
index eb35979a47..2030808724 100644
--- a/scene/animation/tween.cpp
+++ b/scene/animation/tween.cpp
@@ -1115,7 +1115,7 @@ real_t Tween::tell() const {
// For each interpolation...
for (const List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) {
- // Get the data and figure out if it's position is further along than the previous ones
+ // Get the data and figure out if its position is further along than the previous ones
const InterpolateData &data = E->get();
if (data.elapsed > pos) {
// Save it if so
diff --git a/scene/audio/audio_stream_player.cpp b/scene/audio/audio_stream_player.cpp
index 2853a8b9d9..1478cbf69e 100644
--- a/scene/audio/audio_stream_player.cpp
+++ b/scene/audio/audio_stream_player.cpp
@@ -171,7 +171,7 @@ void AudioStreamPlayer::set_stream(Ref<AudioStream> p_stream) {
if (active.is_set() && stream_playback.is_valid() && !stream_paused) {
//changing streams out of the blue is not a great idea, but at least
- //lets try to somehow avoid a click
+ //let's try to somehow avoid a click
AudioFrame *buffer = fadeout_buffer.ptrw();
int buffer_size = fadeout_buffer.size();
diff --git a/scene/debugger/scene_debugger.cpp b/scene/debugger/scene_debugger.cpp
index 4dbe3cc1c4..a1d4adcd41 100644
--- a/scene/debugger/scene_debugger.cpp
+++ b/scene/debugger/scene_debugger.cpp
@@ -487,7 +487,7 @@ void LiveEditor::_send_tree() {
}
Array arr;
- // Encoded as a flat list depth fist.
+ // Encoded as a flat list depth first.
SceneDebuggerTree tree(scene_tree->root);
tree.serialize(arr);
EngineDebugger::get_singleton()->send_message("scene:scene_tree", arr);
diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h
index d54d63cc39..6c7a8f3433 100644
--- a/scene/gui/base_button.h
+++ b/scene/gui/base_button.h
@@ -45,7 +45,7 @@ public:
};
private:
- int button_mask = BUTTON_MASK_LEFT;
+ int button_mask = MOUSE_BUTTON_MASK_LEFT;
bool toggle_mode = false;
bool shortcut_in_tooltip = true;
bool keep_pressed_outside = false;
diff --git a/scene/gui/box_container.cpp b/scene/gui/box_container.cpp
index c570438b6a..7407ad5b8f 100644
--- a/scene/gui/box_container.cpp
+++ b/scene/gui/box_container.cpp
@@ -313,7 +313,7 @@ BoxContainer::AlignMode BoxContainer::get_alignment() const {
return align;
}
-void BoxContainer::add_spacer(bool p_begin) {
+Control *BoxContainer::add_spacer(bool p_begin) {
Control *c = memnew(Control);
c->set_mouse_filter(MOUSE_FILTER_PASS); //allow spacer to pass mouse events
@@ -327,6 +327,8 @@ void BoxContainer::add_spacer(bool p_begin) {
if (p_begin) {
move_child(c, 0);
}
+
+ return c;
}
BoxContainer::BoxContainer(bool p_vertical) {
diff --git a/scene/gui/box_container.h b/scene/gui/box_container.h
index 31050d1feb..23feea565c 100644
--- a/scene/gui/box_container.h
+++ b/scene/gui/box_container.h
@@ -55,7 +55,7 @@ protected:
static void _bind_methods();
public:
- void add_spacer(bool p_begin = false);
+ Control *add_spacer(bool p_begin = false);
void set_alignment(AlignMode p_align);
AlignMode get_alignment() const;
diff --git a/scene/gui/check_box.cpp b/scene/gui/check_box.cpp
index 9df328dd11..c0650a8f3f 100644
--- a/scene/gui/check_box.cpp
+++ b/scene/gui/check_box.cpp
@@ -34,7 +34,9 @@
Size2 CheckBox::get_icon_size() const {
Ref<Texture2D> checked = Control::get_theme_icon("checked");
+ Ref<Texture2D> checked_disabled = Control::get_theme_icon("checked_disabled");
Ref<Texture2D> unchecked = Control::get_theme_icon("unchecked");
+ Ref<Texture2D> unchecked_disabled = Control::get_theme_icon("unchecked_disabled");
Ref<Texture2D> radio_checked = Control::get_theme_icon("radio_checked");
Ref<Texture2D> radio_unchecked = Control::get_theme_icon("radio_unchecked");
@@ -79,8 +81,8 @@ void CheckBox::_notification(int p_what) {
} else if (p_what == NOTIFICATION_DRAW) {
RID ci = get_canvas_item();
- Ref<Texture2D> on = Control::get_theme_icon(is_radio() ? "radio_checked" : "checked");
- Ref<Texture2D> off = Control::get_theme_icon(is_radio() ? "radio_unchecked" : "unchecked");
+ Ref<Texture2D> on = Control::get_theme_icon(vformat("%s%s", is_radio() ? "radio_checked" : "checked", is_disabled() ? "_disabled" : ""));
+ Ref<Texture2D> off = Control::get_theme_icon(vformat("%s%s", is_radio() ? "radio_unchecked" : "unchecked", is_disabled() ? "_disabled" : ""));
Ref<StyleBox> sb = get_theme_stylebox("normal");
Vector2 ofs;
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index e8586b72e9..a919ae8dd0 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -113,6 +113,24 @@ void ColorPicker::_update_controls() {
btn_hsv->set_disabled(false);
}
+ if (raw_mode_enabled) {
+ for (int i = 0; i < 3; i++) {
+ scroll[i]->add_theme_icon_override("grabber", Ref<Texture2D>());
+ scroll[i]->add_theme_icon_override("grabber_highlight", Ref<Texture2D>());
+ scroll[i]->add_theme_style_override("slider", Ref<StyleBox>());
+ scroll[i]->add_theme_style_override("grabber_area", Ref<StyleBox>());
+ scroll[i]->add_theme_style_override("grabber_area_highlight", Ref<StyleBox>());
+ }
+ } else {
+ for (int i = 0; i < 3; i++) {
+ scroll[i]->add_theme_icon_override("grabber", get_theme_icon("bar_arrow"));
+ scroll[i]->add_theme_icon_override("grabber_highlight", get_theme_icon("bar_arrow"));
+ scroll[i]->add_theme_style_override("slider", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty)));
+ scroll[i]->add_theme_style_override("grabber_area", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty)));
+ scroll[i]->add_theme_style_override("grabber_area_highlight", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty)));
+ }
+ }
+
if (edit_alpha) {
values[3]->show();
scroll[3]->show();
@@ -243,6 +261,9 @@ void ColorPicker::_update_color(bool p_update_sliders) {
sample->update();
uv_edit->update();
w_edit->update();
+ for (int i = 0; i < 4; i++) {
+ scroll[i]->update();
+ }
updating = false;
}
@@ -456,11 +477,74 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
}
}
+void ColorPicker::_slider_draw(int p_which) {
+ Vector<Vector2> pos;
+ pos.resize(4);
+ Vector<Color> col;
+ col.resize(4);
+ Size2 size = scroll[p_which]->get_size();
+ Color left_color;
+ Color right_color;
+#ifdef TOOLS_ENABLED
+ const real_t margin = 4 * EDSCALE;
+#else
+ const real_t margin = 4;
+#endif
+
+ if (p_which == 3) {
+ scroll[p_which]->draw_texture_rect(get_theme_icon("preset_bg", "ColorPicker"), Rect2(Point2(0, margin), Size2(size.x, margin)), true);
+
+ left_color = color;
+ left_color.a = 0;
+ right_color = color;
+ right_color.a = 1;
+ } else {
+ if (raw_mode_enabled) {
+ return;
+ }
+ if (hsv_mode_enabled) {
+ if (p_which == 0) {
+ Ref<Texture2D> hue = get_theme_icon("color_hue", "ColorPicker");
+ scroll[p_which]->draw_set_transform(Point2(), -Math_PI / 2, Size2(1.0, 1.0));
+ scroll[p_which]->draw_texture_rect(hue, Rect2(Vector2(margin * -2, 0), Vector2(scroll[p_which]->get_size().x, margin)), false, Color(1, 1, 1), true);
+ return;
+ }
+ Color s_col;
+ Color v_col;
+ s_col.set_hsv(h, 0, v);
+ left_color = (p_which == 1) ? s_col : Color(0, 0, 0);
+ s_col.set_hsv(h, 1, v);
+ v_col.set_hsv(h, s, 1);
+ right_color = (p_which == 1) ? s_col : v_col;
+ } else {
+ left_color = Color(
+ p_which == 0 ? 0 : color.r,
+ p_which == 1 ? 0 : color.g,
+ p_which == 2 ? 0 : color.b);
+ right_color = Color(
+ p_which == 0 ? 1 : color.r,
+ p_which == 1 ? 1 : color.g,
+ p_which == 2 ? 1 : color.b);
+ }
+ }
+
+ col.set(0, left_color);
+ col.set(1, right_color);
+ col.set(2, right_color);
+ col.set(3, left_color);
+ pos.set(0, Vector2(0, margin));
+ pos.set(1, Vector2(size.x, margin));
+ pos.set(2, Vector2(size.x, margin * 2));
+ pos.set(3, Vector2(0, margin * 2));
+
+ scroll[p_which]->draw_polygon(pos, col);
+}
+
void ColorPicker::_uv_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> bev = p_event;
if (bev.is_valid()) {
- if (bev->is_pressed() && bev->get_button_index() == BUTTON_LEFT) {
+ if (bev->is_pressed() && bev->get_button_index() == MOUSE_BUTTON_LEFT) {
changing_color = true;
float x = CLAMP((float)bev->get_position().x, 0, uv_edit->get_size().width);
float y = CLAMP((float)bev->get_position().y, 0, uv_edit->get_size().height);
@@ -473,7 +557,7 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &p_event) {
if (!deferred_mode_enabled) {
emit_signal("color_changed", color);
}
- } else if (deferred_mode_enabled && !bev->is_pressed() && bev->get_button_index() == BUTTON_LEFT) {
+ } else if (deferred_mode_enabled && !bev->is_pressed() && bev->get_button_index() == MOUSE_BUTTON_LEFT) {
emit_signal("color_changed", color);
changing_color = false;
} else {
@@ -505,7 +589,7 @@ void ColorPicker::_w_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> bev = p_event;
if (bev.is_valid()) {
- if (bev->is_pressed() && bev->get_button_index() == BUTTON_LEFT) {
+ if (bev->is_pressed() && bev->get_button_index() == MOUSE_BUTTON_LEFT) {
changing_color = true;
float y = CLAMP((float)bev->get_position().y, 0, w_edit->get_size().height);
h = y / w_edit->get_size().height;
@@ -518,7 +602,7 @@ void ColorPicker::_w_input(const Ref<InputEvent> &p_event) {
_update_color();
if (!deferred_mode_enabled) {
emit_signal("color_changed", color);
- } else if (!bev->is_pressed() && bev->get_button_index() == BUTTON_LEFT) {
+ } else if (!bev->is_pressed() && bev->get_button_index() == MOUSE_BUTTON_LEFT) {
emit_signal("color_changed", color);
}
}
@@ -546,7 +630,7 @@ void ColorPicker::_preset_input(const Ref<InputEvent> &p_event) {
if (bev.is_valid()) {
int index = 0;
- if (bev->is_pressed() && bev->get_button_index() == BUTTON_LEFT) {
+ if (bev->is_pressed() && bev->get_button_index() == MOUSE_BUTTON_LEFT) {
for (int i = 0; i < presets.size(); i++) {
int x = (i % presets_per_row) * bt_add_preset->get_size().x;
int y = (Math::floor((float)i / presets_per_row)) * bt_add_preset->get_size().y;
@@ -557,7 +641,7 @@ void ColorPicker::_preset_input(const Ref<InputEvent> &p_event) {
set_pick_color(presets[index]);
_update_color();
emit_signal("color_changed", color);
- } else if (bev->is_pressed() && bev->get_button_index() == BUTTON_RIGHT && presets_enabled) {
+ } else if (bev->is_pressed() && bev->get_button_index() == MOUSE_BUTTON_RIGHT && presets_enabled) {
index = bev->get_position().x / (preset->get_size().x / presets.size());
Color clicked_preset = presets[index];
erase_preset(clicked_preset);
@@ -586,7 +670,7 @@ void ColorPicker::_screen_input(const Ref<InputEvent> &p_event) {
}
Ref<InputEventMouseButton> bev = p_event;
- if (bev.is_valid() && bev->get_button_index() == BUTTON_LEFT && !bev->is_pressed()) {
+ if (bev.is_valid() && bev->get_button_index() == MOUSE_BUTTON_LEFT && !bev->is_pressed()) {
emit_signal("color_changed", color);
screen->hide();
}
@@ -598,7 +682,7 @@ void ColorPicker::_screen_input(const Ref<InputEvent> &p_event) {
return;
}
- Ref<Image> img = r->get_texture()->get_data();
+ Ref<Image> img = r->get_texture()->get_image();
if (img.is_valid() && !img->is_empty()) {
Vector2 ofs = mev->get_global_position() - r->get_visible_rect().get_position();
Color c = img->get_pixel(ofs.x, r->get_visible_rect().size.height - ofs.y);
@@ -799,10 +883,16 @@ ColorPicker::ColorPicker() :
scroll[i]->set_h_size_flags(SIZE_EXPAND_FILL);
scroll[i]->connect("value_changed", callable_mp(this, &ColorPicker::_value_changed));
+ scroll[i]->connect("draw", callable_mp(this, &ColorPicker::_slider_draw), make_binds(i));
vbr->add_child(hbc);
}
labels[3]->set_text("A");
+ scroll[3]->add_theme_icon_override("grabber", get_theme_icon("bar_arrow"));
+ scroll[3]->add_theme_icon_override("grabber_highlight", get_theme_icon("bar_arrow"));
+ scroll[3]->add_theme_style_override("slider", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty)));
+ scroll[3]->add_theme_style_override("grabber_area", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty)));
+ scroll[3]->add_theme_style_override("grabber_area_highlight", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty)));
HBoxContainer *hhb = memnew(HBoxContainer);
vbr->add_child(hhb);
diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h
index 7915527bc0..24e1746c41 100644
--- a/scene/gui/color_picker.h
+++ b/scene/gui/color_picker.h
@@ -91,6 +91,7 @@ private:
void _text_type_toggled();
void _sample_draw();
void _hsv_draw(int p_which, Control *c);
+ void _slider_draw(int p_which);
void _uv_input(const Ref<InputEvent> &p_event);
void _w_input(const Ref<InputEvent> &p_event);
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 76ceef2782..1e13597e94 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -73,6 +73,9 @@ Dictionary Control::_edit_get_state() const {
}
void Control::_edit_set_state(const Dictionary &p_state) {
+ ERR_FAIL_COND((p_state.size() <= 0) ||
+ !p_state.has("rotation") || !p_state.has("scale") ||
+ !p_state.has("pivot") || !p_state.has("anchors") || !p_state.has("offsets"));
Dictionary state = p_state;
set_rotation(state["rotation"]);
@@ -93,6 +96,7 @@ void Control::_edit_set_state(const Dictionary &p_state) {
void Control::_edit_set_position(const Point2 &p_position) {
#ifdef TOOLS_ENABLED
+ ERR_FAIL_COND_MSG(!Engine::get_singleton()->is_editor_hint(), "This function can only be used from editor plugins.");
set_position(p_position, CanvasItemEditor::get_singleton()->is_anchors_mode_enabled() && Object::cast_to<Control>(data.parent));
#else
// Unlikely to happen. TODO: enclose all _edit_ functions into TOOLS_ENABLED
@@ -114,6 +118,7 @@ Size2 Control::_edit_get_scale() const {
void Control::_edit_set_rect(const Rect2 &p_edit_rect) {
#ifdef TOOLS_ENABLED
+ ERR_FAIL_COND_MSG(!Engine::get_singleton()->is_editor_hint(), "This function can only be used from editor plugins.");
set_position((get_position() + get_transform().basis_xform(p_edit_rect.position)).snapped(Vector2(1, 1)), CanvasItemEditor::get_singleton()->is_anchors_mode_enabled());
set_size(p_edit_rect.size.snapped(Vector2(1, 1)), CanvasItemEditor::get_singleton()->is_anchors_mode_enabled());
#else
@@ -131,11 +136,11 @@ bool Control::_edit_use_rect() const {
return true;
}
-void Control::_edit_set_rotation(float p_rotation) {
+void Control::_edit_set_rotation(real_t p_rotation) {
set_rotation(p_rotation);
}
-float Control::_edit_get_rotation() const {
+real_t Control::_edit_get_rotation() const {
return get_rotation();
}
@@ -577,7 +582,7 @@ void Control::_notification(int p_notification) {
} break;
case NOTIFICATION_MOVED_IN_PARENT: {
- // some parents need to know the order of the childrens to draw (like TabContainer)
+ // some parents need to know the order of the children to draw (like TabContainer)
// update if necessary
if (data.parent) {
data.parent->update();
@@ -1229,10 +1234,10 @@ Size2 Control::get_parent_area_size() const {
void Control::_size_changed() {
Rect2 parent_rect = get_parent_anchorable_rect();
- float edge_pos[4];
+ real_t edge_pos[4];
for (int i = 0; i < 4; i++) {
- float area = parent_rect.size[i & 1];
+ real_t area = parent_rect.size[i & 1];
edge_pos[i] = data.offset[i] + (data.anchor[i] * area);
}
@@ -1286,13 +1291,13 @@ void Control::_size_changed() {
}
}
-void Control::set_anchor(Side p_side, float p_anchor, bool p_keep_offset, bool p_push_opposite_anchor) {
+void Control::set_anchor(Side p_side, real_t p_anchor, bool p_keep_offset, bool p_push_opposite_anchor) {
ERR_FAIL_INDEX((int)p_side, 4);
Rect2 parent_rect = get_parent_anchorable_rect();
- float parent_range = (p_side == SIDE_LEFT || p_side == SIDE_RIGHT) ? parent_rect.size.x : parent_rect.size.y;
- float previous_pos = data.offset[p_side] + data.anchor[p_side] * parent_range;
- float previous_opposite_pos = data.offset[(p_side + 2) % 4] + data.anchor[(p_side + 2) % 4] * parent_range;
+ real_t parent_range = (p_side == SIDE_LEFT || p_side == SIDE_RIGHT) ? parent_rect.size.x : parent_rect.size.y;
+ real_t previous_pos = data.offset[p_side] + data.anchor[p_side] * parent_range;
+ real_t previous_opposite_pos = data.offset[(p_side + 2) % 4] + data.anchor[(p_side + 2) % 4] * parent_range;
data.anchor[p_side] = p_anchor;
@@ -1318,11 +1323,11 @@ void Control::set_anchor(Side p_side, float p_anchor, bool p_keep_offset, bool p
update();
}
-void Control::_set_anchor(Side p_side, float p_anchor) {
+void Control::_set_anchor(Side p_side, real_t p_anchor) {
set_anchor(p_side, p_anchor);
}
-void Control::set_anchor_and_offset(Side p_side, float p_anchor, float p_pos, bool p_push_opposite_anchor) {
+void Control::set_anchor_and_offset(Side p_side, real_t p_anchor, real_t p_pos, bool p_push_opposite_anchor) {
set_anchor(p_side, p_anchor, false, p_push_opposite_anchor);
set_offset(p_side, p_pos);
}
@@ -1459,7 +1464,7 @@ void Control::set_offsets_preset(LayoutPreset p_preset, LayoutPresetMode p_resiz
Rect2 parent_rect = get_parent_anchorable_rect();
- float x = parent_rect.size.x;
+ real_t x = parent_rect.size.x;
if (is_layout_rtl()) {
x = parent_rect.size.x - x - new_size.x;
}
@@ -1583,13 +1588,13 @@ void Control::set_anchors_and_offsets_preset(LayoutPreset p_preset, LayoutPreset
set_offsets_preset(p_preset, p_resize_mode, p_margin);
}
-float Control::get_anchor(Side p_side) const {
+real_t Control::get_anchor(Side p_side) const {
ERR_FAIL_INDEX_V(int(p_side), 4, 0.0);
return data.anchor[p_side];
}
-void Control::set_offset(Side p_side, float p_value) {
+void Control::set_offset(Side p_side, real_t p_value) {
ERR_FAIL_INDEX((int)p_side, 4);
data.offset[p_side] = p_value;
@@ -1608,7 +1613,7 @@ void Control::set_end(const Size2 &p_point) {
_size_changed();
}
-float Control::get_offset(Side p_side) const {
+real_t Control::get_offset(Side p_side) const {
ERR_FAIL_INDEX_V((int)p_side, 4, 0);
return data.offset[p_side];
@@ -1651,12 +1656,12 @@ void Control::set_global_position(const Point2 &p_point, bool p_keep_offsets) {
set_position(inv.xform(p_point), p_keep_offsets);
}
-void Control::_compute_anchors(Rect2 p_rect, const float p_offsets[4], float (&r_anchors)[4]) {
+void Control::_compute_anchors(Rect2 p_rect, const real_t p_offsets[4], real_t (&r_anchors)[4]) {
Size2 parent_rect_size = get_parent_anchorable_rect().size;
ERR_FAIL_COND(parent_rect_size.x == 0.0);
ERR_FAIL_COND(parent_rect_size.y == 0.0);
- float x = p_rect.position.x;
+ real_t x = p_rect.position.x;
if (is_layout_rtl()) {
x = parent_rect_size.x - x - p_rect.size.x;
}
@@ -1666,10 +1671,10 @@ void Control::_compute_anchors(Rect2 p_rect, const float p_offsets[4], float (&r
r_anchors[3] = (p_rect.position.y + p_rect.size.y - p_offsets[3]) / parent_rect_size.y;
}
-void Control::_compute_offsets(Rect2 p_rect, const float p_anchors[4], float (&r_offsets)[4]) {
+void Control::_compute_offsets(Rect2 p_rect, const real_t p_anchors[4], real_t (&r_offsets)[4]) {
Size2 parent_rect_size = get_parent_anchorable_rect().size;
- float x = p_rect.position.x;
+ real_t x = p_rect.position.x;
if (is_layout_rtl()) {
x = parent_rect_size.x - x - p_rect.size.x;
}
@@ -1775,7 +1780,7 @@ void Control::add_theme_icon_override(const StringName &p_name, const Ref<Textur
data.icon_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed));
}
- // clear if "null" is passed instead of a icon
+ // clear if "null" is passed instead of an icon
if (p_icon.is_null()) {
data.icon_override.erase(p_name);
} else {
@@ -2248,7 +2253,7 @@ Control *Control::_get_focus_neighbor(Side p_side, int p_count) {
return c;
}
- float dist = 1e7;
+ real_t dist = 1e7;
Control *result = nullptr;
Point2 points[4];
@@ -2269,10 +2274,10 @@ Control *Control::_get_focus_neighbor(Side p_side, int p_count) {
Vector2 vdir = dir[p_side];
- float maxd = -1e7;
+ real_t maxd = -1e7;
for (int i = 0; i < 4; i++) {
- float d = vdir.dot(points[i]);
+ real_t d = vdir.dot(points[i]);
if (d > maxd) {
maxd = d;
}
@@ -2299,7 +2304,7 @@ Control *Control::_get_focus_neighbor(Side p_side, int p_count) {
return result;
}
-void Control::_window_find_focus_neighbor(const Vector2 &p_dir, Node *p_at, const Point2 *p_points, float p_min, float &r_closest_dist, Control **r_closest) {
+void Control::_window_find_focus_neighbor(const Vector2 &p_dir, Node *p_at, const Point2 *p_points, real_t p_min, real_t &r_closest_dist, Control **r_closest) {
if (Object::cast_to<Viewport>(p_at)) {
return; //bye
}
@@ -2316,10 +2321,10 @@ void Control::_window_find_focus_neighbor(const Vector2 &p_dir, Node *p_at, cons
points[2] = xform.xform(c->get_size());
points[3] = xform.xform(Point2(0, c->get_size().y));
- float min = 1e7;
+ real_t min = 1e7;
for (int i = 0; i < 4; i++) {
- float d = p_dir.dot(points[i]);
+ real_t d = p_dir.dot(points[i]);
if (d < min) {
min = d;
}
@@ -2335,8 +2340,8 @@ void Control::_window_find_focus_neighbor(const Vector2 &p_dir, Node *p_at, cons
Vector2 fb = points[(j + 1) % 4];
Vector2 pa, pb;
- float d = Geometry2D::get_closest_points_between_segments(la, lb, fa, fb, pa, pb);
- //float d = Geometry2D::get_closest_distance_between_segments(Vector3(la.x,la.y,0),Vector3(lb.x,lb.y,0),Vector3(fa.x,fa.y,0),Vector3(fb.x,fb.y,0));
+ real_t d = Geometry2D::get_closest_points_between_segments(la, lb, fa, fb, pa, pb);
+ //real_t d = Geometry2D::get_closest_distance_between_segments(Vector3(la.x,la.y,0),Vector3(lb.x,lb.y,0),Vector3(fa.x,fa.y,0),Vector3(fb.x,fb.y,0));
if (d < r_closest_dist) {
r_closest_dist = d;
*r_closest = c;
@@ -2376,7 +2381,7 @@ void Control::set_v_size_flags(int p_flags) {
emit_signal(SceneStringNames::get_singleton()->size_flags_changed);
}
-void Control::set_stretch_ratio(float p_ratio) {
+void Control::set_stretch_ratio(real_t p_ratio) {
if (data.expand == p_ratio) {
return;
}
@@ -2385,7 +2390,7 @@ void Control::set_stretch_ratio(float p_ratio) {
emit_signal(SceneStringNames::get_singleton()->size_flags_changed);
}
-float Control::get_stretch_ratio() const {
+real_t Control::get_stretch_ratio() const {
return data.expand;
}
@@ -2557,21 +2562,21 @@ Vector<Vector2i> Control::structured_text_parser(StructuredTextParser p_node_typ
return ret;
}
-void Control::set_rotation(float p_radians) {
+void Control::set_rotation(real_t p_radians) {
data.rotation = p_radians;
update();
_notify_transform();
}
-float Control::get_rotation() const {
+real_t Control::get_rotation() const {
return data.rotation;
}
-void Control::set_rotation_degrees(float p_degrees) {
+void Control::set_rotation_degrees(real_t p_degrees) {
set_rotation(Math::deg2rad(p_degrees));
}
-float Control::get_rotation_degrees() const {
+real_t Control::get_rotation_degrees() const {
return Math::rad2deg(get_rotation());
}
diff --git a/scene/gui/control.h b/scene/gui/control.h
index 8981e05872..a911d69c3f 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -171,22 +171,22 @@ private:
Size2 last_minimum_size;
bool updating_last_minimum_size = false;
- float offset[4] = { 0.0, 0.0, 0.0, 0.0 };
- float anchor[4] = { ANCHOR_BEGIN, ANCHOR_BEGIN, ANCHOR_BEGIN, ANCHOR_BEGIN };
+ real_t offset[4] = { 0.0, 0.0, 0.0, 0.0 };
+ real_t anchor[4] = { ANCHOR_BEGIN, ANCHOR_BEGIN, ANCHOR_BEGIN, ANCHOR_BEGIN };
FocusMode focus_mode = FOCUS_NONE;
GrowDirection h_grow = GROW_DIRECTION_END;
GrowDirection v_grow = GROW_DIRECTION_END;
LayoutDirection layout_dir = LAYOUT_DIRECTION_INHERITED;
- float rotation = 0.0;
+ real_t rotation = 0.0;
Vector2 scale = Vector2(1, 1);
Vector2 pivot_offset;
bool size_warning = true;
int h_size_flags = SIZE_FILL;
int v_size_flags = SIZE_FILL;
- float expand = 1.0;
+ real_t expand = 1.0;
Point2 custom_minimum_size;
MouseFilter mouse_filter = MOUSE_FILTER_STOP;
@@ -224,10 +224,10 @@ private:
// used internally
Control *_find_control_at_pos(CanvasItem *p_node, const Point2 &p_pos, const Transform2D &p_xform, Transform2D &r_inv_xform);
- void _window_find_focus_neighbor(const Vector2 &p_dir, Node *p_at, const Point2 *p_points, float p_min, float &r_closest_dist, Control **r_closest);
+ void _window_find_focus_neighbor(const Vector2 &p_dir, Node *p_at, const Point2 *p_points, real_t p_min, real_t &r_closest_dist, Control **r_closest);
Control *_get_focus_neighbor(Side p_side, int p_count = 0);
- void _set_anchor(Side p_side, float p_anchor);
+ void _set_anchor(Side p_side, real_t p_anchor);
void _set_position(const Point2 &p_point);
void _set_global_position(const Point2 &p_point);
void _set_size(const Size2 &p_size);
@@ -239,8 +239,8 @@ private:
void _clear_size_warning();
void _update_scroll();
- void _compute_offsets(Rect2 p_rect, const float p_anchors[4], float (&r_offsets)[4]);
- void _compute_anchors(Rect2 p_rect, const float p_offsets[4], float (&r_anchors)[4]);
+ void _compute_offsets(Rect2 p_rect, const real_t p_anchors[4], real_t (&r_offsets)[4]);
+ void _compute_anchors(Rect2 p_rect, const real_t p_offsets[4], real_t (&r_anchors)[4]);
void _size_changed();
String _get_tooltip() const;
@@ -325,8 +325,8 @@ public:
virtual Rect2 _edit_get_rect() const override;
virtual bool _edit_use_rect() const override;
- virtual void _edit_set_rotation(float p_rotation) override;
- virtual float _edit_get_rotation() const override;
+ virtual void _edit_set_rotation(real_t p_rotation) override;
+ virtual real_t _edit_get_rotation() const override;
virtual bool _edit_use_rotation() const override;
virtual void _edit_set_pivot(const Point2 &p_pivot) override;
@@ -364,13 +364,13 @@ public:
void set_offsets_preset(LayoutPreset p_preset, LayoutPresetMode p_resize_mode = PRESET_MODE_MINSIZE, int p_margin = 0);
void set_anchors_and_offsets_preset(LayoutPreset p_preset, LayoutPresetMode p_resize_mode = PRESET_MODE_MINSIZE, int p_margin = 0);
- void set_anchor(Side p_side, float p_anchor, bool p_keep_offset = true, bool p_push_opposite_anchor = true);
- float get_anchor(Side p_side) const;
+ void set_anchor(Side p_side, real_t p_anchor, bool p_keep_offset = true, bool p_push_opposite_anchor = true);
+ real_t get_anchor(Side p_side) const;
- void set_offset(Side p_side, float p_value);
- float get_offset(Side p_side) const;
+ void set_offset(Side p_side, real_t p_value);
+ real_t get_offset(Side p_side) const;
- void set_anchor_and_offset(Side p_side, float p_anchor, float p_pos, bool p_push_opposite_anchor = true);
+ void set_anchor_and_offset(Side p_side, real_t p_anchor, real_t p_pos, bool p_push_opposite_anchor = true);
void set_begin(const Point2 &p_point); // helper
void set_end(const Point2 &p_point); // helper
@@ -395,10 +395,10 @@ public:
void set_rect(const Rect2 &p_rect); // Reset anchors to begin and set rect, for faster container children sorting.
- void set_rotation(float p_radians);
- void set_rotation_degrees(float p_degrees);
- float get_rotation() const;
- float get_rotation_degrees() const;
+ void set_rotation(real_t p_radians);
+ void set_rotation_degrees(real_t p_degrees);
+ real_t get_rotation() const;
+ real_t get_rotation_degrees() const;
void set_h_grow_direction(GrowDirection p_direction);
GrowDirection get_h_grow_direction() const;
@@ -421,8 +421,8 @@ public:
void set_v_size_flags(int p_flags);
int get_v_size_flags() const;
- void set_stretch_ratio(float p_ratio);
- float get_stretch_ratio() const;
+ void set_stretch_ratio(real_t p_ratio);
+ real_t get_stretch_ratio() const;
void minimum_size_changed();
diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp
index fdfbf9eafc..b6884bd37d 100644
--- a/scene/gui/dialogs.cpp
+++ b/scene/gui/dialogs.cpp
@@ -256,7 +256,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 == "") {
- c = RTR("Cancel");
+ c = TTRC("Cancel");
}
Button *b = swap_cancel_ok ? add_button(c, true) : add_button(c);
b->connect("pressed", callable_mp(this, &AcceptDialog::_cancel_pressed));
@@ -317,13 +317,13 @@ AcceptDialog::AcceptDialog() {
hbc->add_spacer();
ok = memnew(Button);
- ok->set_text(RTR("OK"));
+ ok->set_text(TTRC("OK"));
hbc->add_child(ok);
hbc->add_spacer();
ok->connect("pressed", callable_mp(this, &AcceptDialog::_ok_pressed));
- set_title(RTR("Alert!"));
+ set_title(TTRC("Alert!"));
connect("window_input", callable_mp(this, &AcceptDialog::_input_from_window));
}
@@ -342,7 +342,7 @@ Button *ConfirmationDialog::get_cancel_button() {
}
ConfirmationDialog::ConfirmationDialog() {
- set_title(RTR("Please Confirm..."));
+ set_title(TTRC("Please Confirm..."));
#ifdef TOOLS_ENABLED
set_min_size(Size2(200, 70) * EDSCALE);
#endif
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 7453324505..7ac8dbccca 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -57,6 +57,14 @@ void FileDialog::_theme_changed() {
dir_up->add_theme_color_override("icon_hover_color", font_hover_color);
dir_up->add_theme_color_override("icon_pressed_color", font_pressed_color);
+ dir_prev->add_theme_color_override("icon_color_normal", font_color);
+ dir_prev->add_theme_color_override("icon_color_hover", font_hover_color);
+ dir_prev->add_theme_color_override("icon_color_pressed", font_pressed_color);
+
+ dir_next->add_theme_color_override("icon_color_normal", font_color);
+ dir_next->add_theme_color_override("icon_color_hover", font_hover_color);
+ dir_next->add_theme_color_override("icon_color_pressed", font_pressed_color);
+
refresh->add_theme_color_override("icon_normal_color", font_color);
refresh->add_theme_color_override("icon_hover_color", font_hover_color);
refresh->add_theme_color_override("icon_pressed_color", font_pressed_color);
@@ -74,6 +82,13 @@ void FileDialog::_notification(int p_what) {
}
if (p_what == NOTIFICATION_ENTER_TREE) {
dir_up->set_icon(vbox->get_theme_icon("parent_folder", "FileDialog"));
+ if (vbox->is_layout_rtl()) {
+ dir_prev->set_icon(vbox->get_theme_icon("forward_folder", "FileDialog"));
+ dir_next->set_icon(vbox->get_theme_icon("back_folder", "FileDialog"));
+ } else {
+ dir_prev->set_icon(vbox->get_theme_icon("back_folder", "FileDialog"));
+ dir_next->set_icon(vbox->get_theme_icon("forward_folder", "FileDialog"));
+ }
refresh->set_icon(vbox->get_theme_icon("reload", "FileDialog"));
show_hidden->set_icon(vbox->get_theme_icon("toggle_hidden", "FileDialog"));
_theme_changed();
@@ -144,6 +159,7 @@ void FileDialog::_dir_entered(String p_dir) {
file->set_text("");
invalidate();
update_dir();
+ _push_history();
}
void FileDialog::_file_entered(const String &p_file) {
@@ -177,6 +193,21 @@ void FileDialog::_post_popup() {
} else {
file_box->set_visible(true);
}
+
+ local_history.clear();
+ local_history_pos = -1;
+ _push_history();
+}
+
+void FileDialog::_push_history() {
+ local_history.resize(local_history_pos + 1);
+ String new_path = dir_access->get_current_dir();
+ if (local_history.size() == 0 || new_path != local_history[local_history_pos]) {
+ local_history.push_back(new_path);
+ local_history_pos++;
+ dir_prev->set_disabled(local_history_pos == 0);
+ dir_next->set_disabled(true);
+ }
}
void FileDialog::_action_pressed() {
@@ -272,7 +303,7 @@ void FileDialog::_action_pressed() {
}
if (dir_access->file_exists(f)) {
- confirm_save->set_text(RTR("File exists, overwrite?"));
+ confirm_save->set_text(TTRC("File exists, overwrite?"));
confirm_save->popup_centered(Size2(200, 80));
} else {
emit_signal("file_selected", f);
@@ -316,6 +347,35 @@ void FileDialog::_go_up() {
dir_access->change_dir("..");
update_file_list();
update_dir();
+ _push_history();
+}
+
+void FileDialog::_go_back() {
+ if (local_history_pos <= 0) {
+ return;
+ }
+
+ local_history_pos--;
+ dir_access->change_dir(local_history[local_history_pos]);
+ update_file_list();
+ update_dir();
+
+ dir_prev->set_disabled(local_history_pos == 0);
+ dir_next->set_disabled(local_history_pos == local_history.size() - 1);
+}
+
+void FileDialog::_go_forward() {
+ if (local_history_pos == local_history.size() - 1) {
+ return;
+ }
+
+ local_history_pos++;
+ dir_access->change_dir(local_history[local_history_pos]);
+ update_file_list();
+ update_dir();
+
+ dir_prev->set_disabled(local_history_pos == 0);
+ dir_next->set_disabled(local_history_pos == local_history.size() - 1);
}
void FileDialog::deselect_all() {
@@ -329,10 +389,10 @@ void FileDialog::deselect_all() {
switch (mode) {
case FILE_MODE_OPEN_FILE:
case FILE_MODE_OPEN_FILES:
- get_ok_button()->set_text(RTR("Open"));
+ get_ok_button()->set_text(TTRC("Open"));
break;
case FILE_MODE_OPEN_DIR:
- get_ok_button()->set_text(RTR("Select Current Folder"));
+ get_ok_button()->set_text(TTRC("Select Current Folder"));
break;
case FILE_MODE_OPEN_ANY:
case FILE_MODE_SAVE_FILE:
@@ -356,7 +416,7 @@ void FileDialog::_tree_selected() {
if (!d["dir"]) {
file->set_text(d["name"]);
} else if (mode == FILE_MODE_OPEN_DIR) {
- get_ok_button()->set_text(RTR("Select This Folder"));
+ get_ok_button()->set_text(TTRC("Select This Folder"));
}
get_ok_button()->set_disabled(_is_open_should_be_disabled());
@@ -377,6 +437,7 @@ void FileDialog::_tree_item_activated() {
}
call_deferred("_update_file_list");
call_deferred("_update_dir");
+ _push_history();
} else {
_action_pressed();
}
@@ -415,6 +476,13 @@ void FileDialog::update_file_list() {
bool is_hidden;
String item;
+ if (dir_access->is_readable(dir_access->get_current_dir().utf8().get_data())) {
+ message->hide();
+ } else {
+ message->set_text(TTRC("You don't have permission to access contents of this folder."));
+ message->show();
+ }
+
while ((item = dir_access->get_next()) != "") {
if (item == "." || item == "..") {
continue;
@@ -549,7 +617,7 @@ void FileDialog::update_filters() {
all_filters += ", ...";
}
- filter->add_item(RTR("All Recognized") + " (" + all_filters + ")");
+ filter->add_item(String(TTRC("All Recognized")) + " (" + all_filters + ")");
}
for (int i = 0; i < filters.size(); i++) {
String flt = filters[i].get_slice(";", 0).strip_edges();
@@ -561,7 +629,7 @@ void FileDialog::update_filters() {
}
}
- filter->add_item(RTR("All Files (*)"));
+ filter->add_item(TTRC("All Files (*)"));
}
void FileDialog::clear_filters() {
@@ -602,6 +670,7 @@ void FileDialog::set_current_dir(const String &p_dir) {
dir_access->change_dir(p_dir);
update_dir();
invalidate();
+ _push_history();
}
void FileDialog::set_current_file(const String &p_file) {
@@ -646,37 +715,37 @@ void FileDialog::set_file_mode(FileMode p_mode) {
mode = p_mode;
switch (mode) {
case FILE_MODE_OPEN_FILE:
- get_ok_button()->set_text(RTR("Open"));
+ get_ok_button()->set_text(TTRC("Open"));
if (mode_overrides_title) {
- set_title(RTR("Open a File"));
+ set_title(TTRC("Open a File"));
}
makedir->hide();
break;
case FILE_MODE_OPEN_FILES:
- get_ok_button()->set_text(RTR("Open"));
+ get_ok_button()->set_text(TTRC("Open"));
if (mode_overrides_title) {
- set_title(RTR("Open File(s)"));
+ set_title(TTRC("Open File(s)"));
}
makedir->hide();
break;
case FILE_MODE_OPEN_DIR:
- get_ok_button()->set_text(RTR("Select Current Folder"));
+ get_ok_button()->set_text(TTRC("Select Current Folder"));
if (mode_overrides_title) {
- set_title(RTR("Open a Directory"));
+ set_title(TTRC("Open a Directory"));
}
makedir->show();
break;
case FILE_MODE_OPEN_ANY:
- get_ok_button()->set_text(RTR("Open"));
+ get_ok_button()->set_text(TTRC("Open"));
if (mode_overrides_title) {
- set_title(RTR("Open a File or Directory"));
+ set_title(TTRC("Open a File or Directory"));
}
makedir->show();
break;
case FILE_MODE_SAVE_FILE:
- get_ok_button()->set_text(RTR("Save"));
+ get_ok_button()->set_text(TTRC("Save"));
if (mode_overrides_title) {
- set_title(RTR("Save a File"));
+ set_title(TTRC("Save a File"));
}
makedir->show();
break;
@@ -731,12 +800,13 @@ FileDialog::Access FileDialog::get_access() const {
}
void FileDialog::_make_dir_confirm() {
- Error err = dir_access->make_dir(makedirname->get_text());
+ Error err = dir_access->make_dir(makedirname->get_text().strip_edges());
if (err == OK) {
- dir_access->change_dir(makedirname->get_text());
+ dir_access->change_dir(makedirname->get_text().strip_edges());
invalidate();
update_filters();
update_dir();
+ _push_history();
} else {
mkdirerr->popup_centered(Size2(250, 50));
}
@@ -754,6 +824,7 @@ void FileDialog::_select_drive(int p_idx) {
file->set_text("");
invalidate();
update_dir();
+ _push_history();
}
void FileDialog::_update_drives() {
@@ -857,17 +928,27 @@ FileDialog::FileDialog() {
vbox->connect("theme_changed", callable_mp(this, &FileDialog::_theme_changed));
mode = FILE_MODE_SAVE_FILE;
- set_title(RTR("Save a File"));
+ set_title(TTRC("Save a File"));
HBoxContainer *hbc = memnew(HBoxContainer);
+ dir_prev = memnew(Button);
+ dir_prev->set_flat(true);
+ dir_prev->set_tooltip(TTRC("Go to previous folder."));
+ dir_next = memnew(Button);
+ dir_next->set_flat(true);
+ dir_next->set_tooltip(TTRC("Go to next folder."));
dir_up = memnew(Button);
dir_up->set_flat(true);
- dir_up->set_tooltip(RTR("Go to parent folder."));
+ dir_up->set_tooltip(TTRC("Go to parent folder."));
+ hbc->add_child(dir_prev);
+ hbc->add_child(dir_next);
hbc->add_child(dir_up);
+ dir_prev->connect("pressed", callable_mp(this, &FileDialog::_go_back));
+ dir_next->connect("pressed", callable_mp(this, &FileDialog::_go_forward));
dir_up->connect("pressed", callable_mp(this, &FileDialog::_go_up));
- hbc->add_child(memnew(Label(RTR("Path:"))));
+ hbc->add_child(memnew(Label(TTRC("Path:"))));
drives_container = memnew(HBoxContainer);
hbc->add_child(drives_container);
@@ -883,7 +964,7 @@ FileDialog::FileDialog() {
refresh = memnew(Button);
refresh->set_flat(true);
- refresh->set_tooltip(RTR("Refresh files."));
+ refresh->set_tooltip(TTRC("Refresh files."));
refresh->connect("pressed", callable_mp(this, &FileDialog::update_file_list));
hbc->add_child(refresh);
@@ -891,7 +972,7 @@ FileDialog::FileDialog() {
show_hidden->set_flat(true);
show_hidden->set_toggle_mode(true);
show_hidden->set_pressed(is_showing_hidden_files());
- show_hidden->set_tooltip(RTR("Toggle the visibility of hidden files."));
+ show_hidden->set_tooltip(TTRC("Toggle the visibility of hidden files."));
show_hidden->connect("toggled", callable_mp(this, &FileDialog::set_show_hidden_files));
hbc->add_child(show_hidden);
@@ -899,17 +980,24 @@ FileDialog::FileDialog() {
hbc->add_child(shortcuts_container);
makedir = memnew(Button);
- makedir->set_text(RTR("Create Folder"));
+ makedir->set_text(TTRC("Create Folder"));
makedir->connect("pressed", callable_mp(this, &FileDialog::_make_dir));
hbc->add_child(makedir);
vbox->add_child(hbc);
tree = memnew(Tree);
tree->set_hide_root(true);
- vbox->add_margin_child(RTR("Directories & Files:"), tree, true);
+ vbox->add_margin_child(TTRC("Directories & Files:"), tree, true);
+
+ 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);
+ tree->add_child(message);
file_box = memnew(HBoxContainer);
- file_box->add_child(memnew(Label(RTR("File:"))));
+ file_box->add_child(memnew(Label(TTRC("File:"))));
file = memnew(LineEdit);
file->set_structured_text_bidi_override(Control::STRUCTURED_TEXT_FILE);
file->set_stretch_ratio(4);
@@ -941,22 +1029,22 @@ FileDialog::FileDialog() {
confirm_save->connect("confirmed", callable_mp(this, &FileDialog::_save_confirm_pressed));
makedialog = memnew(ConfirmationDialog);
- makedialog->set_title(RTR("Create Folder"));
+ makedialog->set_title(TTRC("Create Folder"));
VBoxContainer *makevb = memnew(VBoxContainer);
makedialog->add_child(makevb);
makedirname = memnew(LineEdit);
makedirname->set_structured_text_bidi_override(Control::STRUCTURED_TEXT_FILE);
- makevb->add_margin_child(RTR("Name:"), makedirname);
+ makevb->add_margin_child(TTRC("Name:"), makedirname);
add_child(makedialog);
makedialog->register_text_enter(makedirname);
makedialog->connect("confirmed", callable_mp(this, &FileDialog::_make_dir_confirm));
mkdirerr = memnew(AcceptDialog);
- mkdirerr->set_text(RTR("Could not create folder."));
+ mkdirerr->set_text(TTRC("Could not create folder."));
add_child(mkdirerr);
exterr = memnew(AcceptDialog);
- exterr->set_text(RTR("Must use a valid extension."));
+ exterr->set_text(TTRC("Must use a valid extension."));
add_child(exterr);
update_filters();
diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h
index 25b742c234..4996f00cb3 100644
--- a/scene/gui/file_dialog.h
+++ b/scene/gui/file_dialog.h
@@ -86,6 +86,10 @@ private:
DirAccess *dir_access;
ConfirmationDialog *confirm_save;
+ Label *message;
+
+ Button *dir_prev;
+ Button *dir_next;
Button *dir_up;
Button *refresh;
@@ -93,6 +97,10 @@ private:
Vector<String> filters;
+ Vector<String> local_history;
+ int local_history_pos = 0;
+ void _push_history();
+
bool mode_overrides_title = true;
static bool default_show_hidden_files;
@@ -119,6 +127,8 @@ private:
void _make_dir();
void _make_dir_confirm();
void _go_up();
+ void _go_back();
+ void _go_forward();
void _update_drives();
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index 331f0380c5..b93391ee4c 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -161,7 +161,7 @@ void GraphEditMinimap::_gui_input(const Ref<InputEvent> &p_ev) {
Ref<InputEventMouseButton> mb = p_ev;
Ref<InputEventMouseMotion> mm = p_ev;
- if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT) {
+ if (mb.is_valid() && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
if (mb->is_pressed()) {
is_pressing = true;
@@ -180,7 +180,12 @@ void GraphEditMinimap::_gui_input(const Ref<InputEvent> &p_ev) {
accept_event();
} else if (mm.is_valid() && is_pressing) {
if (is_resizing) {
- ge->set_minimap_size(ge->get_minimap_size() - mm->get_relative());
+ // Prevent setting minimap wider than GraphEdit
+ Vector2 new_minimap_size;
+ new_minimap_size.x = MIN(get_size().x - mm->get_relative().x, ge->get_size().x - 2.0 * minimap_padding.x);
+ new_minimap_size.y = MIN(get_size().y - mm->get_relative().y, ge->get_size().y - 2.0 * minimap_padding.y);
+ ge->set_minimap_size(new_minimap_size);
+
update();
} else {
Vector2 click_position = _convert_to_graph_position(mm->get_position() - minimap_padding) - graph_padding;
@@ -548,7 +553,7 @@ bool GraphEdit::_filter_input(const Point2 &p_point) {
void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
Ref<InputEventMouseButton> mb = p_ev;
- if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) {
+ if (mb.is_valid() && mb->get_button_index() == MOUSE_BUTTON_LEFT && mb->is_pressed()) {
connecting_valid = false;
Ref<Texture2D> port = get_theme_icon("port", "GraphNode");
click_pos = mb->get_position() / zoom;
@@ -691,7 +696,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
}
}
- if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && !mb->is_pressed()) {
+ if (mb.is_valid() && mb->get_button_index() == MOUSE_BUTTON_LEFT && !mb->is_pressed()) {
if (connecting_valid) {
if (connecting && connecting_target) {
String from = connecting_from;
@@ -1062,7 +1067,7 @@ void GraphEdit::set_selected(Node *p_child) {
void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
Ref<InputEventMouseMotion> mm = p_ev;
- if (mm.is_valid() && (mm->get_button_mask() & BUTTON_MASK_MIDDLE || (mm->get_button_mask() & BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE)))) {
+ if (mm.is_valid() && (mm->get_button_mask() & MOUSE_BUTTON_MASK_MIDDLE || (mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE)))) {
h_scroll->set_value(h_scroll->get_value() - mm->get_relative().x);
v_scroll->set_value(v_scroll->get_value() - mm->get_relative().y);
}
@@ -1118,7 +1123,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
}
gn->set_selected(box_selection_mode_additive);
} else {
- bool select = (previus_selected.find(gn) != nullptr);
+ bool select = (previous_selected.find(gn) != nullptr);
if (gn->is_selected() && !select) {
emit_signal("node_deselected", gn);
} else if (!gn->is_selected() && select) {
@@ -1134,7 +1139,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
Ref<InputEventMouseButton> b = p_ev;
if (b.is_valid()) {
- if (b->get_button_index() == BUTTON_RIGHT && b->is_pressed()) {
+ if (b->get_button_index() == MOUSE_BUTTON_RIGHT && b->is_pressed()) {
if (box_selecting) {
box_selecting = false;
for (int i = get_child_count() - 1; i >= 0; i--) {
@@ -1143,7 +1148,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
continue;
}
- bool select = (previus_selected.find(gn) != nullptr);
+ bool select = (previous_selected.find(gn) != nullptr);
if (gn->is_selected() && !select) {
emit_signal("node_deselected", gn);
} else if (!gn->is_selected() && select) {
@@ -1164,7 +1169,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
}
}
- if (b->get_button_index() == BUTTON_LEFT && !b->is_pressed() && dragging) {
+ if (b->get_button_index() == MOUSE_BUTTON_LEFT && !b->is_pressed() && dragging) {
if (!just_selected && drag_accum == Vector2() && Input::get_singleton()->is_key_pressed(KEY_CONTROL)) {
//deselect current node
for (int i = get_child_count() - 1; i >= 0; i--) {
@@ -1203,7 +1208,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
connections_layer->update();
}
- if (b->get_button_index() == BUTTON_LEFT && b->is_pressed()) {
+ if (b->get_button_index() == MOUSE_BUTTON_LEFT && b->is_pressed()) {
GraphNode *gn = nullptr;
for (int i = get_child_count() - 1; i >= 0; i--) {
@@ -1268,29 +1273,29 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
box_selecting_from = b->get_position();
if (b->get_control()) {
box_selection_mode_additive = true;
- previus_selected.clear();
+ previous_selected.clear();
for (int i = get_child_count() - 1; i >= 0; i--) {
GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i));
if (!gn2 || !gn2->is_selected()) {
continue;
}
- previus_selected.push_back(gn2);
+ previous_selected.push_back(gn2);
}
} else if (b->get_shift()) {
box_selection_mode_additive = false;
- previus_selected.clear();
+ previous_selected.clear();
for (int i = get_child_count() - 1; i >= 0; i--) {
GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i));
if (!gn2 || !gn2->is_selected()) {
continue;
}
- previus_selected.push_back(gn2);
+ previous_selected.push_back(gn2);
}
} else {
box_selection_mode_additive = true;
- previus_selected.clear();
+ previous_selected.clear();
for (int i = get_child_count() - 1; i >= 0; i--) {
GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i));
if (!gn2) {
@@ -1305,32 +1310,25 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
}
}
- if (b->get_button_index() == BUTTON_LEFT && !b->is_pressed() && box_selecting) {
+ if (b->get_button_index() == MOUSE_BUTTON_LEFT && !b->is_pressed() && box_selecting) {
box_selecting = false;
- previus_selected.clear();
+ box_selecting_rect = Rect2();
+ previous_selected.clear();
top_layer->update();
minimap->update();
}
- if (b->get_button_index() == BUTTON_WHEEL_UP && b->is_pressed()) {
- //too difficult to get right
- //set_zoom(zoom*ZOOM_SCALE);
- }
-
- if (b->get_button_index() == BUTTON_WHEEL_DOWN && b->is_pressed()) {
- //too difficult to get right
- //set_zoom(zoom/ZOOM_SCALE);
- }
- if (b->get_button_index() == BUTTON_WHEEL_UP && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+ if (b->get_button_index() == MOUSE_BUTTON_WHEEL_UP && Input::get_singleton()->is_key_pressed(KEY_CONTROL)) {
+ set_zoom(zoom * ZOOM_SCALE);
+ } else if (b->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && Input::get_singleton()->is_key_pressed(KEY_CONTROL)) {
+ set_zoom(zoom / ZOOM_SCALE);
+ } else if (b->get_button_index() == MOUSE_BUTTON_WHEEL_UP && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() * b->get_factor() / 8);
- }
- if (b->get_button_index() == BUTTON_WHEEL_DOWN && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+ } else if (b->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * b->get_factor() / 8);
- }
- if (b->get_button_index() == BUTTON_WHEEL_RIGHT || (b->get_button_index() == BUTTON_WHEEL_DOWN && Input::get_singleton()->is_key_pressed(KEY_SHIFT))) {
+ } else if (b->get_button_index() == MOUSE_BUTTON_WHEEL_RIGHT || (b->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && Input::get_singleton()->is_key_pressed(KEY_SHIFT))) {
h_scroll->set_value(h_scroll->get_value() + h_scroll->get_page() * b->get_factor() / 8);
- }
- if (b->get_button_index() == BUTTON_WHEEL_LEFT || (b->get_button_index() == BUTTON_WHEEL_UP && Input::get_singleton()->is_key_pressed(KEY_SHIFT))) {
+ } else if (b->get_button_index() == MOUSE_BUTTON_WHEEL_LEFT || (b->get_button_index() == MOUSE_BUTTON_WHEEL_UP && Input::get_singleton()->is_key_pressed(KEY_SHIFT))) {
h_scroll->set_value(h_scroll->get_value() - h_scroll->get_page() * b->get_factor() / 8);
}
}
diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h
index 8fdf975319..fa3b113705 100644
--- a/scene/gui/graph_edit.h
+++ b/scene/gui/graph_edit.h
@@ -150,7 +150,7 @@ private:
Point2 box_selecting_from;
Point2 box_selecting_to;
Rect2 box_selecting_rect;
- List<GraphNode *> previus_selected;
+ List<GraphNode *> previous_selected;
bool setting_scroll_ofs = false;
bool right_disconnects = false;
diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp
index b615cdb266..8eba473d57 100644
--- a/scene/gui/graph_node.cpp
+++ b/scene/gui/graph_node.cpp
@@ -32,6 +32,12 @@
#include "core/string/translation.h"
+struct _MinSizeCache {
+ int min_size;
+ bool will_stretch;
+ int final_size;
+};
+
bool GraphNode::_set(const StringName &p_name, const Variant &p_value) {
String str = p_name;
if (str.begins_with("opentype_features/")) {
@@ -171,15 +177,23 @@ void GraphNode::_get_property_list(List<PropertyInfo> *p_list) const {
}
void GraphNode::_resort() {
- int sep = get_theme_constant("separation");
+ /** First pass, determine minimum size AND amount of stretchable elements */
+
+ Size2i new_size = get_size();
Ref<StyleBox> sb = get_theme_stylebox("frame");
- bool first = true;
- Size2 minsize;
+ int sep = get_theme_constant("separation");
+
+ bool first = true;
+ int children_count = 0;
+ int stretch_min = 0;
+ int stretch_avail = 0;
+ float stretch_ratio_total = 0;
+ Map<Control *, _MinSizeCache> min_size_cache;
for (int i = 0; i < get_child_count(); i++) {
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c) {
+ if (!c || !c->is_visible_in_tree()) {
continue;
}
if (c->is_set_as_top_level()) {
@@ -187,38 +201,120 @@ void GraphNode::_resort() {
}
Size2i size = c->get_combined_minimum_size();
+ _MinSizeCache msc;
- minsize.y += size.y;
- minsize.x = MAX(minsize.x, size.x);
+ stretch_min += size.height;
+ msc.min_size = size.height;
+ msc.will_stretch = c->get_v_size_flags() & SIZE_EXPAND;
- if (first) {
- first = false;
- } else {
- minsize.y += sep;
+ if (msc.will_stretch) {
+ stretch_avail += msc.min_size;
+ stretch_ratio_total += c->get_stretch_ratio();
}
+ msc.final_size = msc.min_size;
+ min_size_cache[c] = msc;
+ children_count++;
}
- int vofs = 0;
- int w = get_size().x - sb->get_minimum_size().x;
+ if (children_count == 0) {
+ return;
+ }
+
+ int stretch_max = new_size.height - (children_count - 1) * sep;
+ int stretch_diff = stretch_max - stretch_min;
+ if (stretch_diff < 0) {
+ //avoid negative stretch space
+ stretch_diff = 0;
+ }
+
+ stretch_avail += stretch_diff - sb->get_margin(SIDE_BOTTOM) - sb->get_margin(SIDE_TOP); //available stretch space.
+ /** Second, pass sucessively to discard elements that can't be stretched, this will run while stretchable
+ elements exist */
+
+ while (stretch_ratio_total > 0) { // first of all, don't even be here if no stretchable objects exist
+ bool refit_successful = true; //assume refit-test will go well
+
+ for (int i = 0; i < get_child_count(); i++) {
+ Control *c = Object::cast_to<Control>(get_child(i));
+ if (!c || !c->is_visible_in_tree()) {
+ continue;
+ }
+ if (c->is_set_as_top_level()) {
+ continue;
+ }
+ ERR_FAIL_COND(!min_size_cache.has(c));
+ _MinSizeCache &msc = min_size_cache[c];
+
+ if (msc.will_stretch) { //wants to stretch
+ //let's see if it can really stretch
+
+ int final_pixel_size = stretch_avail * c->get_stretch_ratio() / stretch_ratio_total;
+ if (final_pixel_size < msc.min_size) {
+ //if available stretching area is too small for widget,
+ //then remove it from stretching area
+ msc.will_stretch = false;
+ stretch_ratio_total -= c->get_stretch_ratio();
+ refit_successful = false;
+ stretch_avail -= msc.min_size;
+ msc.final_size = msc.min_size;
+ break;
+ } else {
+ msc.final_size = final_pixel_size;
+ }
+ }
+ }
+
+ if (refit_successful) { //uf refit went well, break
+ break;
+ }
+ }
+
+ /** Final pass, draw and stretch elements **/
+
+ int ofs = sb->get_margin(SIDE_TOP);
+
+ first = true;
+ int idx = 0;
cache_y.clear();
+ int w = new_size.width - sb->get_minimum_size().x;
+
for (int i = 0; i < get_child_count(); i++) {
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c) {
+ if (!c || !c->is_visible_in_tree()) {
continue;
}
if (c->is_set_as_top_level()) {
continue;
}
- Size2i size = c->get_combined_minimum_size();
+ _MinSizeCache &msc = min_size_cache[c];
+
+ if (first) {
+ first = false;
+ } else {
+ ofs += sep;
+ }
- Rect2 r(sb->get_margin(SIDE_LEFT), sb->get_margin(SIDE_TOP) + vofs, w, size.y);
+ int from = ofs;
+ int to = ofs + msc.final_size;
- fit_child_in_rect(c, r);
- cache_y.push_back(vofs + size.y * 0.5);
+ if (msc.will_stretch && idx == children_count - 1) {
+ //adjust so the last one always fits perfect
+ //compensating for numerical imprecision
- vofs += size.y + sep;
+ to = new_size.height - sb->get_margin(SIDE_BOTTOM);
+ }
+
+ int size = to - from;
+
+ Rect2 rect(sb->get_margin(SIDE_LEFT), from, w, size);
+
+ fit_child_in_rect(c, rect);
+ cache_y.push_back(from - sb->get_margin(SIDE_TOP) + size * 0.5);
+
+ ofs = to;
+ idx++;
}
update();
@@ -712,7 +808,7 @@ void GraphNode::_gui_input(const Ref<InputEvent> &p_ev) {
if (mb.is_valid()) {
ERR_FAIL_COND_MSG(get_parent_control() == nullptr, "GraphNode must be the child of a GraphEdit node.");
- if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
+ if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
Vector2 mpos = Vector2(mb->get_position().x, mb->get_position().y);
if (close_rect.size != Size2() && close_rect.has_point(mpos)) {
//send focus to parent
@@ -735,7 +831,7 @@ void GraphNode::_gui_input(const Ref<InputEvent> &p_ev) {
emit_signal("raise_request");
}
- if (!mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
+ if (!mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
resizing = false;
}
}
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index 7afc04c51c..482560d29d 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -540,7 +540,7 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mb = p_event;
- if (defer_select_single >= 0 && mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && !mb->is_pressed()) {
+ if (defer_select_single >= 0 && mb.is_valid() && mb->get_button_index() == MOUSE_BUTTON_LEFT && !mb->is_pressed()) {
select(defer_select_single, true);
emit_signal("multi_selected", defer_select_single, true);
@@ -548,7 +548,7 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
return;
}
- if (mb.is_valid() && (mb->get_button_index() == BUTTON_LEFT || (allow_rmb_select && mb->get_button_index() == BUTTON_RIGHT)) && mb->is_pressed()) {
+ if (mb.is_valid() && (mb->get_button_index() == MOUSE_BUTTON_LEFT || (allow_rmb_select && mb->get_button_index() == MOUSE_BUTTON_RIGHT)) && mb->is_pressed()) {
search_string = ""; //any mousepress cancels
Vector2 pos = mb->get_position();
Ref<StyleBox> bg = get_theme_stylebox("bg");
@@ -594,16 +594,16 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
}
}
- if (mb->get_button_index() == BUTTON_RIGHT) {
+ if (mb->get_button_index() == MOUSE_BUTTON_RIGHT) {
emit_signal("item_rmb_selected", i, get_local_mouse_position());
}
} else {
- if (!mb->is_doubleclick() && !mb->get_command() && select_mode == SELECT_MULTI && items[i].selectable && !items[i].disabled && items[i].selected && mb->get_button_index() == BUTTON_LEFT) {
+ if (!mb->is_doubleclick() && !mb->get_command() && select_mode == SELECT_MULTI && items[i].selectable && !items[i].disabled && items[i].selected && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
defer_select_single = i;
return;
}
- if (items[i].selected && mb->get_button_index() == BUTTON_RIGHT) {
+ if (items[i].selected && mb->get_button_index() == MOUSE_BUTTON_RIGHT) {
emit_signal("item_rmb_selected", i, get_local_mouse_position());
} else {
bool selected = items[i].selected;
@@ -618,7 +618,7 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
}
}
- if (mb->get_button_index() == BUTTON_RIGHT) {
+ if (mb->get_button_index() == MOUSE_BUTTON_RIGHT) {
emit_signal("item_rmb_selected", i, get_local_mouse_position());
} else if (/*select_mode==SELECT_SINGLE &&*/ mb->is_doubleclick()) {
emit_signal("item_activated", i);
@@ -628,7 +628,7 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
return;
}
- if (mb->get_button_index() == BUTTON_RIGHT) {
+ if (mb->get_button_index() == MOUSE_BUTTON_RIGHT) {
emit_signal("rmb_clicked", mb->get_position());
return;
@@ -637,10 +637,10 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
// Since closest is null, more likely we clicked on empty space, so send signal to interested controls. Allows, for example, implement items deselecting.
emit_signal("nothing_selected");
}
- if (mb.is_valid() && mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed()) {
+ if (mb.is_valid() && mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP && mb->is_pressed()) {
scroll_bar->set_value(scroll_bar->get_value() - scroll_bar->get_page() * mb->get_factor() / 8);
}
- if (mb.is_valid() && mb->get_button_index() == BUTTON_WHEEL_DOWN && mb->is_pressed()) {
+ if (mb.is_valid() && mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && mb->is_pressed()) {
scroll_bar->set_value(scroll_bar->get_value() + scroll_bar->get_page() * mb->get_factor() / 8);
}
@@ -768,7 +768,7 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
}
}
} else if (p_event->is_action("ui_accept")) {
- search_string = ""; //any mousepress cance
+ search_string = ""; //any mousepress cancels
if (current >= 0 && current < items.size()) {
emit_signal("item_activated", current);
diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp
index b98caf3562..be73fd8f51 100644
--- a/scene/gui/label.cpp
+++ b/scene/gui/label.cpp
@@ -260,7 +260,8 @@ void Label::_notification(int p_what) {
}
}
}
- visible_glyphs = total_glyphs * percent_visible;
+
+ visible_glyphs = MIN(total_glyphs, visible_chars);
}
Vector2 ofs;
@@ -541,6 +542,8 @@ void Label::set_visible_characters(int p_amount) {
visible_chars = p_amount;
if (get_total_character_count() > 0) {
percent_visible = (float)p_amount / (float)get_total_character_count();
+ } else {
+ percent_visible = 1.0;
}
update();
}
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 3e8ebd2429..d1cd73c803 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -222,7 +222,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
// Ignore mouse clicks in IME input mode.
return;
}
- if (b->is_pressed() && b->get_button_index() == BUTTON_RIGHT && context_menu_enabled) {
+ if (b->is_pressed() && b->get_button_index() == MOUSE_BUTTON_RIGHT && context_menu_enabled) {
menu->set_position(get_screen_transform().xform(get_local_mouse_position()));
menu->set_size(Vector2(1, 1));
_generate_context_menu();
@@ -232,7 +232,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
return;
}
- if (b->get_button_index() != BUTTON_LEFT) {
+ if (b->get_button_index() != MOUSE_BUTTON_LEFT) {
return;
}
@@ -327,7 +327,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
}
}
- if (m->get_button_mask() & BUTTON_LEFT) {
+ if (m->get_button_mask() & MOUSE_BUTTON_LEFT) {
if (selection.creating) {
set_cursor_at_pixel_pos(m->get_position().x);
selection_fill_at_cursor();
@@ -809,7 +809,7 @@ void LineEdit::_notification(int p_what) {
}
} else {
{
- // IME intermidiet text range.
+ // IME intermediate text range.
Vector<Vector2> sel = TS->shaped_text_get_selection(text_rid, cursor_pos, cursor_pos + ime_text.length());
for (int i = 0; i < sel.size(); i++) {
Rect2 rect = Rect2(sel[i].x + ofs.x, ofs.y, sel[i].y - sel[i].x, text_height);
@@ -848,7 +848,7 @@ void LineEdit::_notification(int p_what) {
}
if (has_focus()) {
- if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID) {
+ if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_IME)) {
DisplayServer::get_singleton()->window_set_ime_active(true, get_viewport()->get_window_id());
DisplayServer::get_singleton()->window_set_ime_position(get_global_position() + Point2(using_placeholder ? 0 : x_ofs, y_ofs + TS->shaped_text_get_size(text_rid).y), get_viewport()->get_window_id());
}
@@ -865,7 +865,7 @@ void LineEdit::_notification(int p_what) {
}
}
- if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID) {
+ if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_IME)) {
DisplayServer::get_singleton()->window_set_ime_active(true, get_viewport()->get_window_id());
Point2 cursor_pos = Point2(get_cursor_position(), 1) * get_minimum_size().height;
DisplayServer::get_singleton()->window_set_ime_position(get_global_position() + cursor_pos, get_viewport()->get_window_id());
@@ -878,7 +878,7 @@ void LineEdit::_notification(int p_what) {
caret_blink_timer->stop();
}
- if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID) {
+ if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_IME)) {
DisplayServer::get_singleton()->window_set_ime_position(Point2(), get_viewport()->get_window_id());
DisplayServer::get_singleton()->window_set_ime_active(false, get_viewport()->get_window_id());
}
@@ -1154,6 +1154,8 @@ void LineEdit::cursor_set_blink_enabled(const bool p_enabled) {
}
draw_caret = true;
+
+ notify_property_list_changed();
}
bool LineEdit::cursor_get_force_displayed() const {
@@ -1434,7 +1436,7 @@ void LineEdit::set_cursor_position(int p_pos) {
ofs_max -= r_icon->get_width();
}
- // Note: Use too coordinates to fit IME input range.
+ // Note: Use two coordinates to fit IME input range.
Vector2i primary_catret_offset = get_cursor_pixel_pos();
if (MIN(primary_catret_offset.x, primary_catret_offset.y) <= x_ofs) {
@@ -2075,6 +2077,12 @@ void LineEdit::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
}
+void LineEdit::_validate_property(PropertyInfo &property) const {
+ if (!caret_blink_enabled && property.name == "caret_blink_speed") {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
+ }
+}
+
void LineEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("_text_changed"), &LineEdit::_text_changed);
diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h
index f1d9de255a..ef36377f2e 100644
--- a/scene/gui/line_edit.h
+++ b/scene/gui/line_edit.h
@@ -198,15 +198,15 @@ private:
void _backspace(bool p_word = false, bool p_all_to_left = false);
void _delete(bool p_word = false, bool p_all_to_right = false);
- void _gui_input(Ref<InputEvent> p_event);
- void _notification(int p_what);
-
protected:
+ void _notification(int p_what);
static void _bind_methods();
+ void _gui_input(Ref<InputEvent> p_event);
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 _validate_property(PropertyInfo &property) const override;
public:
void set_align(Align p_align);
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index f237f79be1..bfbd46a9f0 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -222,7 +222,7 @@ void PopupMenu::_activate_submenu(int p_over) {
submenu_popup->set_close_on_parent_focus(false);
submenu_popup->set_position(submenu_pos);
- submenu_popup->set_as_minsize(); // Shrink the popup size to it's contents.
+ submenu_popup->set_as_minsize(); // Shrink the popup size to its contents.
submenu_popup->popup();
// Set autohide areas
@@ -359,7 +359,7 @@ void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) {
if (b->is_pressed() || (!b->is_pressed() && during_grabbed_click)) {
// Allow activating item by releasing the LMB or any that was down when the popup appeared.
// However, if button was not held when opening menu, do not allow release to activate item.
- if (button_idx == BUTTON_LEFT || (initial_button_mask & (1 << (button_idx - 1)))) {
+ if (button_idx == MOUSE_BUTTON_LEFT || (initial_button_mask & (1 << (button_idx - 1)))) {
bool was_during_grabbed_click = during_grabbed_click;
during_grabbed_click = false;
initial_button_mask = 0;
@@ -722,6 +722,7 @@ void PopupMenu::_notification(int p_what) {
for (int i = 0; i < items.size(); i++) {
items.write[i].xl_text = tr(items[i].text);
items.write[i].dirty = true;
+ _shape_item(i);
}
child_controls_changed();
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 682584d73f..09f6578295 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -147,7 +147,7 @@ RichTextLabel::Item *RichTextLabel::_get_item_at_pos(RichTextLabel::Item *p_item
case ITEM_TEXT: {
ItemText *t = (ItemText *)it;
offset += t->text.length();
- if (offset >= p_position) {
+ if (offset > p_position) {
return it;
}
} break;
@@ -588,7 +588,8 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
offset.x += table->columns[column].width + hseparation + frame->padding.size.x;
row_height = MAX(yofs, row_height);
- if (column == col_count - 1) {
+ // Add row height after last column of the row or last cell of the table.
+ if (column == col_count - 1 || E->next() == nullptr) {
offset.x = 0;
row_height += vseparation;
table->total_height += row_height;
@@ -759,7 +760,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
//draw_rect(Rect2(p_ofs + off, TS->shaped_text_get_size(rid)), Color(1,0,0), false, 2); //DEBUG_RECTS
- off.y += TS->shaped_text_get_ascent(rid);
+ off.y += TS->shaped_text_get_ascent(rid) + l.text_buf->get_spacing_top();
// Draw inlined objects.
Array objects = TS->shaped_text_get_objects(rid);
for (int i = 0; i < objects.size(); i++) {
@@ -1078,7 +1079,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
off.x += glyphs[i].advance;
}
}
- off.y += TS->shaped_text_get_descent(rid);
+ off.y += TS->shaped_text_get_descent(rid) + l.text_buf->get_spacing_bottom();
}
return line_count;
@@ -1117,7 +1118,8 @@ void RichTextLabel::_find_click(ItemFrame *p_frame, const Point2i &p_click, Item
Point2 ofs = text_rect.get_position() + Vector2(0, main->lines[from_line].offset.y - vofs);
while (ofs.y < size.height && from_line < main->lines.size()) {
- ofs.y += _find_click_in_line(p_frame, from_line, ofs, text_rect.size.x, p_click, r_click_frame, r_click_line, r_click_item, r_click_char);
+ _find_click_in_line(p_frame, from_line, ofs, text_rect.size.x, p_click, r_click_frame, r_click_line, r_click_item, r_click_char);
+ ofs.y += main->lines[from_line].text_buf->get_size().y;
if (((r_click_item != nullptr) && ((*r_click_item) != nullptr)) || ((r_click_frame != nullptr) && ((*r_click_frame) != nullptr))) {
if (r_outside != nullptr) {
*r_outside = false;
@@ -1172,7 +1174,7 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V
} break;
}
- off.y += TS->shaped_text_get_ascent(rid);
+ off.y += TS->shaped_text_get_ascent(rid) + l.text_buf->get_spacing_top();
Array objects = TS->shaped_text_get_objects(rid);
for (int i = 0; i < objects.size(); i++) {
@@ -1236,7 +1238,7 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V
if (rect.has_point(p_click) && !table_hit) {
char_pos = TS->shaped_text_hit_test_position(rid, p_click.x - rect.position.x);
}
- off.y += TS->shaped_text_get_descent(rid);
+ off.y += TS->shaped_text_get_descent(rid) + l.text_buf->get_spacing_bottom();
}
if (char_pos >= 0) {
@@ -1244,8 +1246,19 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V
if (r_click_item != nullptr) {
Item *it = p_frame->lines[p_line].from;
Item *it_to = (p_line + 1 < p_frame->lines.size()) ? p_frame->lines[p_line + 1].from : nullptr;
- it = _get_item_at_pos(it, it_to, char_pos);
- *r_click_item = it;
+ if (char_pos == p_frame->lines[p_line].char_count) {
+ // Selection after the end of line, select last item.
+ if (it_to != nullptr) {
+ *r_click_item = _get_prev_item(it_to);
+ } else {
+ for (Item *i = it; i && i != it_to; i = _get_next_item(i)) {
+ *r_click_item = i;
+ }
+ }
+ } else {
+ // Selection in the line.
+ *r_click_item = _get_item_at_pos(it, it_to, char_pos);
+ }
}
if (r_click_frame != nullptr) {
@@ -1466,7 +1479,7 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) {
return;
}
- if (b->get_button_index() == BUTTON_LEFT) {
+ if (b->get_button_index() == MOUSE_BUTTON_LEFT) {
if (b->is_pressed() && !b->is_doubleclick()) {
scroll_updated = false;
ItemFrame *c_frame = nullptr;
@@ -1551,12 +1564,12 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) {
}
}
- if (b->get_button_index() == BUTTON_WHEEL_UP) {
+ if (b->get_button_index() == MOUSE_BUTTON_WHEEL_UP) {
if (scroll_active) {
vscroll->set_value(vscroll->get_value() - vscroll->get_page() * b->get_factor() * 0.5 / 8);
}
}
- if (b->get_button_index() == BUTTON_WHEEL_DOWN) {
+ if (b->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN) {
if (scroll_active) {
vscroll->set_value(vscroll->get_value() + vscroll->get_page() * b->get_factor() * 0.5 / 8);
}
@@ -3634,6 +3647,7 @@ void RichTextLabel::set_use_bbcode(bool p_enable) {
}
use_bbcode = p_enable;
set_bbcode(bbcode);
+ notify_property_list_changed();
}
bool RichTextLabel::is_using_bbcode() const {
@@ -3742,7 +3756,9 @@ void RichTextLabel::set_effects(const Vector<Variant> &effects) {
custom_effects.push_back(effect);
}
- parse_bbcode(bbcode);
+ if ((bbcode != "") && use_bbcode) {
+ parse_bbcode(bbcode);
+ }
}
Vector<Variant> RichTextLabel::get_effects() {
@@ -3759,7 +3775,9 @@ void RichTextLabel::install_effect(const Variant effect) {
if (rteffect.is_valid()) {
custom_effects.push_back(effect);
- parse_bbcode(bbcode);
+ if ((bbcode != "") && use_bbcode) {
+ parse_bbcode(bbcode);
+ }
}
}
@@ -3771,6 +3789,12 @@ int RichTextLabel::get_content_height() const {
return total_height;
}
+void RichTextLabel::_validate_property(PropertyInfo &property) const {
+ if (!use_bbcode && property.name == "bbcode_text") {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
+ }
+}
+
void RichTextLabel::_bind_methods() {
ClassDB::bind_method(D_METHOD("_gui_input"), &RichTextLabel::_gui_input);
ClassDB::bind_method(D_METHOD("get_text"), &RichTextLabel::get_text);
@@ -3979,14 +4003,16 @@ void RichTextLabel::set_fixed_size_to_width(int p_width) {
}
Size2 RichTextLabel::get_minimum_size() const {
- Size2 size(0, 0);
+ Ref<StyleBox> style = get_theme_stylebox("normal");
+ Size2 size = style->get_minimum_size();
+
if (fixed_width != -1) {
- size.x = fixed_width;
+ size.x += fixed_width;
}
if (fixed_width != -1 || fit_content_height) {
const_cast<RichTextLabel *>(this)->_validate_line_caches(main);
- size.y = get_content_height();
+ size.y += get_content_height();
}
return size;
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index 2351aff0a4..e3e457d1f2 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -81,7 +81,9 @@ public:
};
protected:
+ void _notification(int p_what);
static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const override;
private:
struct Item;
@@ -441,9 +443,6 @@ private:
bool fit_content_height = false;
-protected:
- void _notification(int p_what);
-
public:
String get_text();
void add_text(const String &p_text);
diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp
index f2516e76a5..a56bf15507 100644
--- a/scene/gui/scroll_bar.cpp
+++ b/scene/gui/scroll_bar.cpp
@@ -52,17 +52,17 @@ void ScrollBar::_gui_input(Ref<InputEvent> p_event) {
if (b.is_valid()) {
accept_event();
- if (b->get_button_index() == BUTTON_WHEEL_DOWN && b->is_pressed()) {
+ if (b->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && b->is_pressed()) {
set_value(get_value() + get_page() / 4.0);
accept_event();
}
- if (b->get_button_index() == BUTTON_WHEEL_UP && b->is_pressed()) {
+ if (b->get_button_index() == MOUSE_BUTTON_WHEEL_UP && b->is_pressed()) {
set_value(get_value() - get_page() / 4.0);
accept_event();
}
- if (b->get_button_index() != BUTTON_LEFT) {
+ if (b->get_button_index() != MOUSE_BUTTON_LEFT) {
return;
}
diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp
index 411891ece8..90a528482f 100644
--- a/scene/gui/scroll_container.cpp
+++ b/scene/gui/scroll_container.cpp
@@ -94,7 +94,7 @@ void ScrollContainer::_gui_input(const Ref<InputEvent> &p_gui_input) {
Ref<InputEventMouseButton> mb = p_gui_input;
if (mb.is_valid()) {
- if (mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed()) {
+ if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP && mb->is_pressed()) {
// only horizontal is enabled, scroll horizontally
if (h_scroll->is_visible() && (!v_scroll->is_visible() || mb->get_shift())) {
h_scroll->set_value(h_scroll->get_value() - h_scroll->get_page() / 8 * mb->get_factor());
@@ -103,7 +103,7 @@ void ScrollContainer::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
}
- if (mb->get_button_index() == BUTTON_WHEEL_DOWN && mb->is_pressed()) {
+ if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && mb->is_pressed()) {
// only horizontal is enabled, scroll horizontally
if (h_scroll->is_visible() && (!v_scroll->is_visible() || mb->get_shift())) {
h_scroll->set_value(h_scroll->get_value() + h_scroll->get_page() / 8 * mb->get_factor());
@@ -112,13 +112,13 @@ void ScrollContainer::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
}
- if (mb->get_button_index() == BUTTON_WHEEL_LEFT && mb->is_pressed()) {
+ if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_LEFT && mb->is_pressed()) {
if (h_scroll->is_visible_in_tree()) {
h_scroll->set_value(h_scroll->get_value() - h_scroll->get_page() * mb->get_factor() / 8);
}
}
- if (mb->get_button_index() == BUTTON_WHEEL_RIGHT && mb->is_pressed()) {
+ if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_RIGHT && mb->is_pressed()) {
if (h_scroll->is_visible_in_tree()) {
h_scroll->set_value(h_scroll->get_value() + h_scroll->get_page() * mb->get_factor() / 8);
}
@@ -132,7 +132,7 @@ void ScrollContainer::_gui_input(const Ref<InputEvent> &p_gui_input) {
return;
}
- if (mb->get_button_index() != BUTTON_LEFT) {
+ if (mb->get_button_index() != MOUSE_BUTTON_LEFT) {
return;
}
diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp
index 2239226c78..7f1d19a87a 100644
--- a/scene/gui/slider.cpp
+++ b/scene/gui/slider.cpp
@@ -53,7 +53,7 @@ void Slider::_gui_input(Ref<InputEvent> p_event) {
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid()) {
- if (mb->get_button_index() == BUTTON_LEFT) {
+ if (mb->get_button_index() == MOUSE_BUTTON_LEFT) {
if (mb->is_pressed()) {
Ref<Texture2D> grabber = get_theme_icon(mouse_inside || has_focus() ? "grabber_highlight" : "grabber");
grab.pos = orientation == VERTICAL ? mb->get_position().y : mb->get_position().x;
@@ -72,10 +72,10 @@ void Slider::_gui_input(Ref<InputEvent> p_event) {
grab.active = false;
}
} else if (scrollable) {
- if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_UP) {
+ if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP) {
grab_focus();
set_value(get_value() + get_step());
- } else if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_DOWN) {
+ } else if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN) {
grab_focus();
set_value(get_value() - get_step());
}
diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp
index 2c9720e4b6..50b25fa7b4 100644
--- a/scene/gui/spin_box.cpp
+++ b/scene/gui/spin_box.cpp
@@ -76,7 +76,7 @@ void SpinBox::_line_edit_input(const Ref<InputEvent> &p_event) {
}
void SpinBox::_range_click_timeout() {
- if (!drag.enabled && Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) {
+ if (!drag.enabled && Input::get_singleton()->is_mouse_button_pressed(MOUSE_BUTTON_LEFT)) {
bool up = get_local_mouse_position().y < (get_size().height / 2);
set_value(get_value() + (up ? get_step() : -get_step()));
@@ -91,6 +91,14 @@ void SpinBox::_range_click_timeout() {
}
}
+void SpinBox::_release_mouse() {
+ if (drag.enabled) {
+ drag.enabled = false;
+ Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
+ warp_mouse(drag.capture_pos);
+ }
+}
+
void SpinBox::_gui_input(const Ref<InputEvent> &p_event) {
if (!is_editable()) {
return;
@@ -102,7 +110,7 @@ void SpinBox::_gui_input(const Ref<InputEvent> &p_event) {
bool up = mb->get_position().y < (get_size().height / 2);
switch (mb->get_button_index()) {
- case BUTTON_LEFT: {
+ case MOUSE_BUTTON_LEFT: {
line_edit->grab_focus();
set_value(get_value() + (up ? get_step() : -get_step()));
@@ -114,17 +122,17 @@ void SpinBox::_gui_input(const Ref<InputEvent> &p_event) {
drag.allowed = true;
drag.capture_pos = mb->get_position();
} break;
- case BUTTON_RIGHT: {
+ case MOUSE_BUTTON_RIGHT: {
line_edit->grab_focus();
set_value((up ? get_max() : get_min()));
} break;
- case BUTTON_WHEEL_UP: {
+ case MOUSE_BUTTON_WHEEL_UP: {
if (line_edit->has_focus()) {
set_value(get_value() + get_step() * mb->get_factor());
accept_event();
}
} break;
- case BUTTON_WHEEL_DOWN: {
+ case MOUSE_BUTTON_WHEEL_DOWN: {
if (line_edit->has_focus()) {
set_value(get_value() - get_step() * mb->get_factor());
accept_event();
@@ -133,21 +141,16 @@ void SpinBox::_gui_input(const Ref<InputEvent> &p_event) {
}
}
- if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
+ if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
//set_default_cursor_shape(CURSOR_ARROW);
range_click_timer->stop();
-
- if (drag.enabled) {
- drag.enabled = false;
- Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
- warp_mouse(drag.capture_pos);
- }
+ _release_mouse();
drag.allowed = false;
}
Ref<InputEventMouseMotion> mm = p_event;
- if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_LEFT) {
+ if (mm.is_valid() && mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT) {
if (drag.enabled) {
drag.diff_y += mm->get_relative().y;
float diff_y = -0.01 * Math::pow(ABS(drag.diff_y), 1.8f) * SGN(drag.diff_y);
@@ -199,6 +202,8 @@ void SpinBox::_notification(int p_what) {
} else if (p_what == NOTIFICATION_ENTER_TREE) {
_adjust_width_for_icon(get_theme_icon("updown"));
_value_changed(0);
+ } else if (p_what == NOTIFICATION_EXIT_TREE) {
+ _release_mouse();
} else if (p_what == NOTIFICATION_TRANSLATION_CHANGED) {
_value_changed(0);
} else if (p_what == NOTIFICATION_THEME_CHANGED) {
diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h
index 4c3adf30e8..e116adb64c 100644
--- a/scene/gui/spin_box.h
+++ b/scene/gui/spin_box.h
@@ -43,6 +43,7 @@ class SpinBox : public Range {
Timer *range_click_timer;
void _range_click_timeout();
+ void _release_mouse();
void _text_entered(const String &p_string);
virtual void _value_changed(double) override;
diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp
index d43e195df1..c80120f87d 100644
--- a/scene/gui/split_container.cpp
+++ b/scene/gui/split_container.cpp
@@ -214,7 +214,7 @@ void SplitContainer::_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid()) {
- if (mb->get_button_index() == BUTTON_LEFT) {
+ if (mb->get_button_index() == MOUSE_BUTTON_LEFT) {
if (mb->is_pressed()) {
int sep = get_theme_constant("separation");
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index e3e3f549de..1e31f9e206 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -76,7 +76,7 @@ void TabContainer::_gui_input(const Ref<InputEvent> &p_event) {
Popup *popup = get_popup();
- if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
+ if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
Point2 pos(mb->get_position().x, mb->get_position().y);
Size2 size = get_size();
@@ -645,7 +645,7 @@ int TabContainer::_get_tab_width(int p_index) const {
// Get the width of the text displayed on the tab.
Ref<Font> font = get_theme_font("font");
int font_size = get_theme_font_size("font_size");
- String text = control->has_meta("_tab_name") ? String(tr(String(control->get_meta("_tab_name")))) : String(control->get_name());
+ String text = control->has_meta("_tab_name") ? String(tr(String(control->get_meta("_tab_name")))) : String(tr(control->get_name()));
int width = font->get_string_size(text, font_size).width;
// Add space for a tab icon.
@@ -1023,6 +1023,7 @@ void TabContainer::set_tab_title(int p_tab, const String &p_title) {
Control *child = _get_tab(p_tab);
ERR_FAIL_COND(!child);
child->set_meta("_tab_name", p_title);
+ _refresh_texts();
update();
}
diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp
index da1a9698d0..38a5588b7e 100644
--- a/scene/gui/tabs.cpp
+++ b/scene/gui/tabs.cpp
@@ -83,7 +83,10 @@ Size2 Tabs::get_minimum_size() const {
}
}
- ms.width = 0; //TODO: should make this optional
+ if (clip_tabs) {
+ ms.width = 0;
+ }
+
return ms;
}
@@ -105,10 +108,10 @@ void Tabs::_gui_input(const Ref<InputEvent> &p_event) {
highlight_arrow = 0;
}
} else {
- int limit = get_size().width - incr->get_width() - decr->get_width();
- if (pos.x > limit + decr->get_width()) {
+ int limit_minus_buttons = get_size().width - incr->get_width() - decr->get_width();
+ if (pos.x > limit_minus_buttons + decr->get_width()) {
highlight_arrow = 1;
- } else if (pos.x > limit) {
+ } else if (pos.x > limit_minus_buttons) {
highlight_arrow = 0;
}
}
@@ -122,7 +125,7 @@ void Tabs::_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid()) {
- if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_UP && !mb->get_command()) {
+ if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP && !mb->get_command()) {
if (scrolling_enabled && buttons_visible) {
if (offset > 0) {
offset--;
@@ -131,7 +134,7 @@ void Tabs::_gui_input(const Ref<InputEvent> &p_event) {
}
}
- if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_DOWN && !mb->get_command()) {
+ if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && !mb->get_command()) {
if (scrolling_enabled && buttons_visible) {
if (missing_right) {
offset++;
@@ -140,7 +143,7 @@ void Tabs::_gui_input(const Ref<InputEvent> &p_event) {
}
}
- if (rb_pressing && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
+ if (rb_pressing && !mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
if (rb_hover != -1) {
//pressed
emit_signal("right_button_pressed", rb_hover);
@@ -150,7 +153,7 @@ void Tabs::_gui_input(const Ref<InputEvent> &p_event) {
update();
}
- if (cb_pressing && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
+ if (cb_pressing && !mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
if (cb_hover != -1) {
//pressed
emit_signal("tab_closed", cb_hover);
@@ -160,7 +163,7 @@ void Tabs::_gui_input(const Ref<InputEvent> &p_event) {
update();
}
- if (mb->is_pressed() && (mb->get_button_index() == BUTTON_LEFT || (select_with_rmb && mb->get_button_index() == BUTTON_RIGHT))) {
+ if (mb->is_pressed() && (mb->get_button_index() == MOUSE_BUTTON_LEFT || (select_with_rmb && mb->get_button_index() == MOUSE_BUTTON_RIGHT))) {
// clicks
Point2 pos(mb->get_position().x, mb->get_position().y);
@@ -305,7 +308,8 @@ void Tabs::_notification(int p_what) {
Ref<Texture2D> incr_hl = get_theme_icon("increment_highlight");
Ref<Texture2D> decr_hl = get_theme_icon("decrement_highlight");
- int limit = get_size().width - incr->get_size().width - decr->get_size().width;
+ int limit = get_size().width;
+ int limit_minus_buttons = get_size().width - incr->get_width() - decr->get_width();
missing_right = false;
@@ -328,7 +332,8 @@ void Tabs::_notification(int p_what) {
col = font_unselected_color;
}
- if (w + lsize > limit) {
+ 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;
@@ -459,15 +464,15 @@ void Tabs::_notification(int p_what) {
}
} else {
if (offset > 0) {
- draw_texture(highlight_arrow == 0 ? decr_hl : decr, Point2(limit, vofs));
+ draw_texture(highlight_arrow == 0 ? decr_hl : decr, Point2(limit_minus_buttons, vofs));
} else {
- draw_texture(decr, Point2(limit, vofs), Color(1, 1, 1, 0.5));
+ draw_texture(decr, Point2(limit_minus_buttons, vofs), Color(1, 1, 1, 0.5));
}
if (missing_right) {
- draw_texture(highlight_arrow == 1 ? incr_hl : incr, Point2(limit + decr->get_size().width, vofs));
+ draw_texture(highlight_arrow == 1 ? incr_hl : incr, Point2(limit_minus_buttons + decr->get_size().width, vofs));
} else {
- draw_texture(incr, Point2(limit + decr->get_size().width, vofs), Color(1, 1, 1, 0.5));
+ draw_texture(incr, Point2(limit_minus_buttons + decr->get_size().width, vofs), Color(1, 1, 1, 0.5));
}
}
@@ -666,7 +671,7 @@ void Tabs::_update_cache() {
Ref<StyleBox> tab_selected = get_theme_stylebox("tab_selected");
Ref<Texture2D> incr = get_theme_icon("increment");
Ref<Texture2D> decr = get_theme_icon("decrement");
- int limit = get_size().width - incr->get_width() - decr->get_width();
+ int limit_minus_buttons = get_size().width - incr->get_width() - decr->get_width();
int w = 0;
int mw = 0;
@@ -686,7 +691,7 @@ void Tabs::_update_cache() {
}
int m_width = min_width;
if (count_resize > 0) {
- m_width = MAX((limit - size_fixed) / count_resize, min_width);
+ m_width = MAX((limit_minus_buttons - size_fixed) / count_resize, min_width);
}
for (int i = offset; i < tabs.size(); i++) {
Ref<StyleBox> sb;
@@ -699,7 +704,7 @@ void Tabs::_update_cache() {
}
int lsize = tabs[i].size_cache;
int slen = tabs[i].size_text;
- if (min_width > 0 && mw > limit && i != current) {
+ 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()) {
@@ -909,6 +914,19 @@ Tabs::TabAlign Tabs::get_tab_align() const {
return tab_align;
}
+void Tabs::set_clip_tabs(bool p_clip_tabs) {
+ if (clip_tabs == p_clip_tabs) {
+ return;
+ }
+ clip_tabs = p_clip_tabs;
+ update();
+ minimum_size_changed();
+}
+
+bool Tabs::get_clip_tabs() const {
+ return clip_tabs;
+}
+
void Tabs::move_tab(int from, int to) {
if (from == to) {
return;
@@ -975,7 +993,8 @@ void Tabs::_ensure_no_over_offset() {
Ref<Texture2D> incr = get_theme_icon("increment");
Ref<Texture2D> decr = get_theme_icon("decrement");
- int limit = get_size().width - incr->get_width() - decr->get_width();
+ int limit = get_size().width;
+ int limit_minus_buttons = get_size().width - incr->get_width() - decr->get_width();
while (offset > 0) {
int total_w = 0;
@@ -983,7 +1002,7 @@ void Tabs::_ensure_no_over_offset() {
total_w += tabs[i].size_cache;
}
- if (total_w < limit) {
+ if ((buttons_visible && total_w < limit_minus_buttons) || total_w < limit) { // For the last tab, we accept if the tab covers the buttons.
offset--;
update();
} else {
@@ -1014,9 +1033,12 @@ void Tabs::ensure_tab_visible(int p_idx) {
int prev_offset = offset;
Ref<Texture2D> incr = get_theme_icon("increment");
Ref<Texture2D> decr = get_theme_icon("decrement");
- int limit = get_size().width - incr->get_width() - decr->get_width();
+ 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++) {
- if (tabs[i].ofs_cache + tabs[i].size_cache > limit) {
+ int total_w = tabs[i].ofs_cache + tabs[i].size_cache;
+ if (total_w > limit || (buttons_visible && total_w > limit_minus_buttons)) {
offset++;
}
}
@@ -1105,6 +1127,8 @@ void Tabs::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_tab", "title", "icon"), &Tabs::add_tab, DEFVAL(""), DEFVAL(Ref<Texture2D>()));
ClassDB::bind_method(D_METHOD("set_tab_align", "align"), &Tabs::set_tab_align);
ClassDB::bind_method(D_METHOD("get_tab_align"), &Tabs::get_tab_align);
+ ClassDB::bind_method(D_METHOD("set_clip_tabs", "clip_tabs"), &Tabs::set_clip_tabs);
+ ClassDB::bind_method(D_METHOD("get_clip_tabs"), &Tabs::get_clip_tabs);
ClassDB::bind_method(D_METHOD("get_tab_offset"), &Tabs::get_tab_offset);
ClassDB::bind_method(D_METHOD("get_offset_buttons_visible"), &Tabs::get_offset_buttons_visible);
ClassDB::bind_method(D_METHOD("ensure_tab_visible", "idx"), &Tabs::ensure_tab_visible);
@@ -1131,6 +1155,7 @@ void Tabs::_bind_methods() {
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::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");
diff --git a/scene/gui/tabs.h b/scene/gui/tabs.h
index 86877f4d80..61c9a5d96a 100644
--- a/scene/gui/tabs.h
+++ b/scene/gui/tabs.h
@@ -85,6 +85,7 @@ private:
int previous = 0;
int _get_top_margin() const;
TabAlign tab_align = ALIGN_CENTER;
+ bool clip_tabs = true;
int rb_hover = -1;
bool rb_pressing = false;
@@ -148,6 +149,9 @@ public:
void set_tab_align(TabAlign p_align);
TabAlign get_tab_align() const;
+ void set_clip_tabs(bool p_clip_tabs);
+ bool get_clip_tabs() const;
+
void move_tab(int from, int to);
void set_tab_close_display_policy(CloseButtonDisplayPolicy p_policy);
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 5a7901c11b..74c530f1b0 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -357,10 +357,10 @@ void TextEdit::_update_scrollbars() {
}
void TextEdit::_click_selection_held() {
- // Warning: is_mouse_button_pressed(BUTTON_LEFT) returns false for double+ clicks, so this doesn't work for MODE_WORD
+ // Warning: is_mouse_button_pressed(MOUSE_BUTTON_LEFT) returns false for double+ clicks, so this doesn't work for MODE_WORD
// and MODE_LINE. However, moving the mouse triggers _gui_input, which calls these functions too, so that's not a huge problem.
// I'm unsure if there's an actual fix that doesn't have a ton of side effects.
- if (Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT) && selection.selecting_mode != SelectionMode::SELECTION_MODE_NONE) {
+ if (Input::get_singleton()->is_mouse_button_pressed(MOUSE_BUTTON_LEFT) && selection.selecting_mode != SelectionMode::SELECTION_MODE_NONE) {
switch (selection.selecting_mode) {
case SelectionMode::SELECTION_MODE_POINTER: {
_update_selection_mode_pointer();
@@ -808,7 +808,7 @@ void TextEdit::_notification(int p_what) {
// Get the highlighted words.
String highlighted_text = get_selection_text();
- // Check if highlighted words contains only whitespaces (tabs or spaces).
+ // Check if highlighted words contain only whitespaces (tabs or spaces).
bool only_whitespaces_highlighted = highlighted_text.strip_edges() == String();
int cursor_wrap_index = get_cursor_wrap_index();
@@ -1057,7 +1057,7 @@ void TextEdit::_notification(int p_what) {
}
if (str.length() == 0) {
- // Draw line background if empty as we won't loop at at all.
+ // Draw line background if empty as we won't loop at all.
if (line == cursor.line && cursor_wrap_index == line_wrap_index && highlight_current_line) {
if (rtl) {
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - ofs_x - xmargin_end, ofs_y, xmargin_end, row_height), cache.current_line_color);
@@ -1442,7 +1442,7 @@ void TextEdit::_notification(int p_what) {
}
} else {
{
- // IME intermidiet text range.
+ // IME Intermediate text range.
Vector<Vector2> sel = TS->shaped_text_get_selection(rid, cursor.column, cursor.column + ime_text.length());
for (int j = 0; j < sel.size(); j++) {
Rect2 rect = Rect2(sel[j].x + char_margin + ofs_x, ofs_y, sel[j].y - sel[j].x, text_height);
@@ -1557,7 +1557,7 @@ void TextEdit::_notification(int p_what) {
completion_rect.position.x = rect_left_border_x;
}
- if (cursor_pos.y + row_height + total_height > get_size().height) {
+ if (cursor_pos.y + row_height + total_height > get_size().height && cursor_pos.y > total_height) {
// Completion panel above the cursor line
completion_rect.position.y = cursor_pos.y - total_height;
} else {
@@ -1702,7 +1702,7 @@ void TextEdit::_notification(int p_what) {
}
if (has_focus()) {
- if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID) {
+ if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_IME)) {
DisplayServer::get_singleton()->window_set_ime_active(true, get_viewport()->get_window_id());
DisplayServer::get_singleton()->window_set_ime_position(get_global_position() + cursor_pos, get_viewport()->get_window_id());
}
@@ -1715,7 +1715,7 @@ void TextEdit::_notification(int p_what) {
draw_caret = true;
}
- if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID) {
+ if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_IME)) {
DisplayServer::get_singleton()->window_set_ime_active(true, get_viewport()->get_window_id());
DisplayServer::get_singleton()->window_set_ime_position(get_global_position() + _get_cursor_pixel_pos(false), get_viewport()->get_window_id());
}
@@ -1744,7 +1744,7 @@ void TextEdit::_notification(int p_what) {
caret_blink_timer->stop();
}
- if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID) {
+ if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_IME)) {
DisplayServer::get_singleton()->window_set_ime_position(Point2(), get_viewport()->get_window_id());
DisplayServer::get_singleton()->window_set_ime_active(false, get_viewport()->get_window_id());
}
@@ -2009,7 +2009,7 @@ void TextEdit::indent_selected_lines_right() {
// We don't really care where selection is - we just need to know indentation level at the beginning of the line.
int left = _find_first_non_whitespace_column_of_line(line_text);
int spaces_to_add = _calculate_spaces_till_next_right_indent(left);
- // Since we will add this much spaces we want move whole selection and cursor by this much.
+ // Since we will add these many spaces, we want to move the whole selection and cursor by this much.
selection_offset = spaces_to_add;
for (int j = 0; j < spaces_to_add; j++) {
line_text = ' ' + line_text;
@@ -2034,7 +2034,7 @@ void TextEdit::indent_selected_lines_left() {
int end_line;
// Moving cursor and selection after unindenting can get tricky because
- // changing content of line can move cursor and selection on it's own (if new line ends before previous position of either),
+ // changing content of line can move cursor and selection on its own (if new line ends before previous position of either),
// therefore we just remember initial values and at the end of the operation offset them by number of removed characters.
int removed_characters = 0;
int initial_selection_end_column = selection.to_column;
@@ -2190,9 +2190,14 @@ void TextEdit::_new_line(bool p_split_current_line, bool p_above) {
// No need to move the brace below if we are not taking the text with us.
char32_t closing_char = _get_right_pair_symbol(indent_char);
- if ((closing_char != 0) && (closing_char == text[cursor.line][cursor.column]) && !p_split_current_line) {
- brace_indent = true;
- ins += "\n" + ins.substr(1, ins.length() - 2);
+ if ((closing_char != 0) && (closing_char == text[cursor.line][cursor.column])) {
+ if (p_split_current_line) {
+ brace_indent = true;
+ ins += "\n" + ins.substr(1, ins.length() - 2);
+ } else {
+ brace_indent = false;
+ ins = "\n" + ins.substr(1, ins.length() - 2);
+ }
}
}
}
@@ -2449,7 +2454,7 @@ void TextEdit::_move_cursor_to_line_start(bool p_select) {
row_start_col += rows[i].length();
}
if (cursor.column == row_start_col || wi == 0) {
- // Compute whitespace symbols seq length.
+ // Compute whitespace symbols sequence length.
int current_line_whitespace_len = 0;
while (current_line_whitespace_len < text[cursor.line].length()) {
char32_t c = text[cursor.line][current_line_whitespace_len];
@@ -2868,14 +2873,14 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
return;
}
- if (mb->get_button_index() == BUTTON_WHEEL_UP) {
+ if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP) {
if (completion_index > 0) {
completion_index--;
completion_current = completion_options[completion_index];
update();
}
}
- if (mb->get_button_index() == BUTTON_WHEEL_DOWN) {
+ if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN) {
if (completion_index < completion_options.size() - 1) {
completion_index++;
completion_current = completion_options[completion_index];
@@ -2883,7 +2888,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
}
- if (mb->get_button_index() == BUTTON_LEFT) {
+ if (mb->get_button_index() == MOUSE_BUTTON_LEFT) {
completion_index = CLAMP(completion_line_ofs + (mpos.y - completion_rect.position.y) / get_row_height(), 0, completion_options.size() - 1);
completion_current = completion_options[completion_index];
@@ -2899,27 +2904,27 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
if (mb->is_pressed()) {
- if (mb->get_button_index() == BUTTON_WHEEL_UP && !mb->get_command()) {
+ if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP && !mb->get_command()) {
if (mb->get_shift()) {
h_scroll->set_value(h_scroll->get_value() - (100 * mb->get_factor()));
} else if (v_scroll->is_visible()) {
_scroll_up(3 * mb->get_factor());
}
}
- if (mb->get_button_index() == BUTTON_WHEEL_DOWN && !mb->get_command()) {
+ if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && !mb->get_command()) {
if (mb->get_shift()) {
h_scroll->set_value(h_scroll->get_value() + (100 * mb->get_factor()));
} else if (v_scroll->is_visible()) {
_scroll_down(3 * mb->get_factor());
}
}
- if (mb->get_button_index() == BUTTON_WHEEL_LEFT) {
+ if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_LEFT) {
h_scroll->set_value(h_scroll->get_value() - (100 * mb->get_factor()));
}
- if (mb->get_button_index() == BUTTON_WHEEL_RIGHT) {
+ if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_RIGHT) {
h_scroll->set_value(h_scroll->get_value() + (100 * mb->get_factor()));
}
- if (mb->get_button_index() == BUTTON_LEFT) {
+ if (mb->get_button_index() == MOUSE_BUTTON_LEFT) {
_reset_caret_blink_timer();
int row, col;
@@ -2984,8 +2989,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
} else {
if (cursor.line < selection.selecting_line || (cursor.line == selection.selecting_line && cursor.column < selection.selecting_column)) {
if (selection.shiftclick_left) {
- SWAP(selection.from_column, selection.to_column);
- SWAP(selection.from_line, selection.to_line);
selection.shiftclick_left = !selection.shiftclick_left;
}
selection.from_column = cursor.column;
@@ -3028,7 +3031,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
update();
}
- if (mb->get_button_index() == BUTTON_RIGHT && context_menu_enabled) {
+ if (mb->get_button_index() == MOUSE_BUTTON_RIGHT && context_menu_enabled) {
_reset_caret_blink_timer();
int row, col;
@@ -3059,7 +3062,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
grab_focus();
}
} else {
- if (mb->get_button_index() == BUTTON_LEFT) {
+ if (mb->get_button_index() == MOUSE_BUTTON_LEFT) {
if (mb->get_command() && highlighted_word != String()) {
int row, col;
_get_mouse_pos(Point2i(mpos.x, mpos.y), row, col);
@@ -3115,7 +3118,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
}
- if (mm->get_button_mask() & BUTTON_MASK_LEFT && get_viewport()->gui_get_drag_data() == Variant()) { // Ignore if dragging.
+ if (mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT && get_viewport()->gui_get_drag_data() == Variant()) { // Ignore if dragging.
_reset_caret_blink_timer();
if (draw_minimap && !dragging_selection) {
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 6ac4d7fd2f..abfea241f3 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -410,6 +410,14 @@ bool TreeItem::is_collapsed() {
return collapsed;
}
+void TreeItem::uncollapse_tree() {
+ TreeItem *t = this;
+ while (t) {
+ t->set_collapsed(false);
+ t = t->parent;
+ }
+}
+
void TreeItem::set_custom_minimum_height(int p_height) {
custom_min_height = p_height;
_changed_notify();
@@ -842,6 +850,8 @@ void TreeItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_collapsed", "enable"), &TreeItem::set_collapsed);
ClassDB::bind_method(D_METHOD("is_collapsed"), &TreeItem::is_collapsed);
+ ClassDB::bind_method(D_METHOD("uncollapse_tree"), &TreeItem::uncollapse_tree);
+
ClassDB::bind_method(D_METHOD("set_custom_minimum_height", "height"), &TreeItem::set_custom_minimum_height);
ClassDB::bind_method(D_METHOD("get_custom_minimum_height"), &TreeItem::get_custom_minimum_height);
@@ -1578,7 +1588,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
if (p_item->cells[i].custom_button) {
if (cache.hover_item == p_item && cache.hover_cell == i) {
- if (Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) {
+ if (Input::get_singleton()->is_mouse_button_pressed(MOUSE_BUTTON_LEFT)) {
draw_style_box(cache.custom_button_pressed, ir);
} else {
draw_style_box(cache.custom_button_hover, ir);
@@ -1815,7 +1825,7 @@ Rect2 Tree::search_item_rect(TreeItem *p_from, TreeItem *p_item) {
}
void Tree::_range_click_timeout() {
- if (range_item_last && !range_drag_enabled && Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) {
+ if (range_item_last && !range_drag_enabled && Input::get_singleton()->is_mouse_button_pressed(MOUSE_BUTTON_LEFT)) {
Point2 pos = get_local_mouse_position() - cache.bg->get_offset();
if (show_column_titles) {
pos.y -= _get_title_button_height();
@@ -1833,7 +1843,7 @@ void Tree::_range_click_timeout() {
propagate_mouse_activated = false; // done from outside, so signal handler can't clear the tree in the middle of emit (which is a common case)
blocked++;
- propagate_mouse_event(pos + cache.offset, 0, 0, false, root, BUTTON_LEFT, mb);
+ propagate_mouse_event(pos + cache.offset, 0, 0, false, root, MOUSE_BUTTON_LEFT, mb);
blocked--;
if (range_click_timer->is_one_shot()) {
@@ -1950,7 +1960,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
col_width -= w + cache.button_margin;
}
- if (p_button == BUTTON_LEFT || (p_button == BUTTON_RIGHT && allow_rmb_select)) {
+ if (p_button == MOUSE_BUTTON_LEFT || (p_button == MOUSE_BUTTON_RIGHT && allow_rmb_select)) {
/* process selection */
if (p_doubleclick && (!c.editable || c.mode == TreeItem::CELL_MODE_CUSTOM || c.mode == TreeItem::CELL_MODE_ICON /*|| c.mode==TreeItem::CELL_MODE_CHECK*/)) { //it's confusing for check
@@ -1962,10 +1972,10 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
}
if (select_mode == SELECT_MULTI && p_mod->get_command() && c.selectable) {
- if (!c.selected || p_button == BUTTON_RIGHT) {
+ if (!c.selected || p_button == MOUSE_BUTTON_RIGHT) {
p_item->select(col);
emit_signal("multi_selected", p_item, col, true);
- if (p_button == BUTTON_RIGHT) {
+ if (p_button == MOUSE_BUTTON_RIGHT) {
emit_signal("item_rmb_selected", get_local_mouse_position());
}
@@ -1982,21 +1992,21 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
bool inrange = false;
select_single_item(p_item, root, col, selected_item, &inrange);
- if (p_button == BUTTON_RIGHT) {
+ if (p_button == MOUSE_BUTTON_RIGHT) {
emit_signal("item_rmb_selected", get_local_mouse_position());
}
} else {
int icount = _count_selected_items(root);
- if (select_mode == SELECT_MULTI && icount > 1 && p_button != BUTTON_RIGHT) {
+ if (select_mode == SELECT_MULTI && icount > 1 && p_button != MOUSE_BUTTON_RIGHT) {
single_select_defer = p_item;
single_select_defer_column = col;
} else {
- if (p_button != BUTTON_RIGHT || !c.selected) {
+ if (p_button != MOUSE_BUTTON_RIGHT || !c.selected) {
select_single_item(p_item, root, col);
}
- if (p_button == BUTTON_RIGHT) {
+ if (p_button == MOUSE_BUTTON_RIGHT) {
emit_signal("item_rmb_selected", get_local_mouse_position());
}
}
@@ -2066,7 +2076,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
/* touching the combo */
bool up = p_pos.y < (item_h / 2);
- if (p_button == BUTTON_LEFT) {
+ if (p_button == MOUSE_BUTTON_LEFT) {
if (range_click_timer->get_time_left() == 0) {
range_item_last = p_item;
range_up_last = up;
@@ -2083,13 +2093,13 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
item_edited(col, p_item);
- } else if (p_button == BUTTON_RIGHT) {
+ } else if (p_button == MOUSE_BUTTON_RIGHT) {
p_item->set_range(col, (up ? c.max : c.min));
item_edited(col, p_item);
- } else if (p_button == BUTTON_WHEEL_UP) {
+ } else if (p_button == MOUSE_BUTTON_WHEEL_UP) {
p_item->set_range(col, c.val + c.step);
item_edited(col, p_item);
- } else if (p_button == BUTTON_WHEEL_DOWN) {
+ } else if (p_button == MOUSE_BUTTON_WHEEL_DOWN) {
p_item->set_range(col, c.val - c.step);
item_edited(col, p_item);
}
@@ -2122,14 +2132,14 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
}
if (!p_item->cells[col].custom_button || !on_arrow) {
- item_edited(col, p_item, p_button == BUTTON_LEFT);
+ item_edited(col, p_item, p_button == MOUSE_BUTTON_LEFT);
}
click_handled = true;
return -1;
} break;
};
- if (!bring_up_editor || p_button != BUTTON_LEFT) {
+ if (!bring_up_editor || p_button != MOUSE_BUTTON_LEFT) {
return -1;
}
@@ -2169,7 +2179,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
item_h += child_h;
}
}
- if (p_item == root && p_button == BUTTON_RIGHT) {
+ if (p_item == root && p_button == MOUSE_BUTTON_RIGHT) {
emit_signal("empty_rmb", get_local_mouse_position());
}
}
@@ -2710,7 +2720,7 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
bool rtl = is_layout_rtl();
if (!b->is_pressed()) {
- if (b->get_button_index() == BUTTON_LEFT) {
+ if (b->get_button_index() == MOUSE_BUTTON_LEFT) {
Point2 pos = b->get_position();
if (rtl) {
pos.x = get_size().width - pos.x;
@@ -2791,8 +2801,8 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
}
switch (b->get_button_index()) {
- case BUTTON_RIGHT:
- case BUTTON_LEFT: {
+ case MOUSE_BUTTON_RIGHT:
+ case MOUSE_BUTTON_LEFT: {
Ref<StyleBox> bg = cache.bg;
Point2 pos = b->get_position();
@@ -2805,7 +2815,7 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
pos.y -= _get_title_button_height();
if (pos.y < 0) {
- if (b->get_button_index() == BUTTON_LEFT) {
+ if (b->get_button_index() == MOUSE_BUTTON_LEFT) {
pos.x += cache.offset.x;
int len = 0;
for (int i = 0; i < columns.size(); i++) {
@@ -2823,7 +2833,7 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
}
}
if (!root || (!root->get_children() && hide_root)) {
- if (b->get_button_index() == BUTTON_RIGHT && allow_rmb_select) {
+ if (b->get_button_index() == MOUSE_BUTTON_RIGHT && allow_rmb_select) {
emit_signal("empty_tree_rmb_selected", get_local_mouse_position());
}
break;
@@ -2844,7 +2854,7 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
}
}
- if (b->get_button_index() == BUTTON_RIGHT) {
+ if (b->get_button_index() == MOUSE_BUTTON_RIGHT) {
break;
}
@@ -2867,7 +2877,7 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
set_physics_process_internal(true);
}
- if (b->get_button_index() == BUTTON_LEFT) {
+ if (b->get_button_index() == MOUSE_BUTTON_LEFT) {
if (get_item_at_position(b->get_position()) == nullptr && !b->get_shift() && !b->get_control() && !b->get_command()) {
emit_signal("nothing_selected");
}
@@ -2880,7 +2890,7 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
}
} break;
- case BUTTON_WHEEL_UP: {
+ case MOUSE_BUTTON_WHEEL_UP: {
double prev_value = v_scroll->get_value();
v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() * b->get_factor() / 8);
if (v_scroll->get_value() != prev_value) {
@@ -2888,7 +2898,7 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
}
} break;
- case BUTTON_WHEEL_DOWN: {
+ case MOUSE_BUTTON_WHEEL_DOWN: {
double prev_value = v_scroll->get_value();
v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * b->get_factor() / 8);
if (v_scroll->get_value() != prev_value) {
@@ -3506,9 +3516,13 @@ int Tree::get_column_width(int p_column) const {
return columns[p_column].min_width;
}
+ int expand_area = get_size().width;
+
Ref<StyleBox> bg = cache.bg;
- int expand_area = get_size().width - (bg->get_margin(SIDE_LEFT) + bg->get_margin(SIDE_RIGHT));
+ if (bg.is_valid()) {
+ expand_area -= bg->get_margin(SIDE_LEFT) + bg->get_margin(SIDE_RIGHT);
+ }
if (v_scroll->is_visible_in_tree()) {
expand_area -= v_scroll->get_combined_minimum_size().width;
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index 1be21cb4a4..d1407e24d4 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -229,6 +229,8 @@ public:
void set_collapsed(bool p_collapsed);
bool is_collapsed();
+ void uncollapse_tree();
+
void set_custom_minimum_height(int p_height);
int get_custom_minimum_height() const;
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp
index 90bc99a941..55529517f1 100644
--- a/scene/main/canvas_item.cpp
+++ b/scene/main/canvas_item.cpp
@@ -729,13 +729,13 @@ void CanvasItem::item_rect_changed(bool p_size_changed) {
emit_signal(SceneStringNames::get_singleton()->item_rect_changed);
}
-void CanvasItem::draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width) {
+void CanvasItem::draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width) {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
RenderingServer::get_singleton()->canvas_item_add_line(canvas_item, p_from, p_to, p_color, p_width);
}
-void CanvasItem::draw_polyline(const Vector<Point2> &p_points, const Color &p_color, float p_width, bool p_antialiased) {
+void CanvasItem::draw_polyline(const Vector<Point2> &p_points, const Color &p_color, real_t p_width, bool p_antialiased) {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
Vector<Color> colors;
@@ -743,25 +743,25 @@ void CanvasItem::draw_polyline(const Vector<Point2> &p_points, const Color &p_co
RenderingServer::get_singleton()->canvas_item_add_polyline(canvas_item, p_points, colors, p_width, p_antialiased);
}
-void CanvasItem::draw_polyline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width, bool p_antialiased) {
+void CanvasItem::draw_polyline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, real_t p_width, bool p_antialiased) {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
RenderingServer::get_singleton()->canvas_item_add_polyline(canvas_item, p_points, p_colors, p_width, p_antialiased);
}
-void CanvasItem::draw_arc(const Vector2 &p_center, float p_radius, float p_start_angle, float p_end_angle, int p_point_count, const Color &p_color, float p_width, bool p_antialiased) {
+void CanvasItem::draw_arc(const Vector2 &p_center, real_t p_radius, real_t p_start_angle, real_t p_end_angle, int p_point_count, const Color &p_color, real_t p_width, bool p_antialiased) {
Vector<Point2> points;
points.resize(p_point_count);
- const float delta_angle = p_end_angle - p_start_angle;
+ const real_t delta_angle = p_end_angle - p_start_angle;
for (int i = 0; i < p_point_count; i++) {
- float theta = (i / (p_point_count - 1.0f)) * delta_angle + p_start_angle;
+ real_t theta = (i / (p_point_count - 1.0f)) * delta_angle + p_start_angle;
points.set(i, p_center + Vector2(Math::cos(theta), Math::sin(theta)) * p_radius);
}
draw_polyline(points, p_color, p_width, p_antialiased);
}
-void CanvasItem::draw_multiline(const Vector<Point2> &p_points, const Color &p_color, float p_width) {
+void CanvasItem::draw_multiline(const Vector<Point2> &p_points, const Color &p_color, real_t p_width) {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
Vector<Color> colors;
@@ -769,13 +769,13 @@ void CanvasItem::draw_multiline(const Vector<Point2> &p_points, const Color &p_c
RenderingServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, colors, p_width);
}
-void CanvasItem::draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width) {
+void CanvasItem::draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, real_t p_width) {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
RenderingServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, p_colors, p_width);
}
-void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled, float p_width) {
+void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled, real_t p_width) {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
if (p_filled) {
@@ -787,7 +787,7 @@ void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_fil
} else {
// Thick lines are offset depending on their width to avoid partial overlapping.
// Thin lines don't require an offset, so don't apply one in this case
- float offset;
+ real_t offset;
if (p_width >= 2) {
offset = p_width / 2.0;
} else {
@@ -821,7 +821,7 @@ void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_fil
}
}
-void CanvasItem::draw_circle(const Point2 &p_pos, float p_radius, const Color &p_color) {
+void CanvasItem::draw_circle(const Point2 &p_pos, real_t p_radius, const Color &p_color) {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
RenderingServer::get_singleton()->canvas_item_add_circle(canvas_item, p_pos, p_radius, p_color);
@@ -856,14 +856,14 @@ void CanvasItem::draw_style_box(const Ref<StyleBox> &p_style_box, const Rect2 &p
p_style_box->draw(canvas_item, p_rect);
}
-void CanvasItem::draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture2D> p_texture, float p_width) {
+void CanvasItem::draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture2D> p_texture, real_t p_width) {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
RenderingServer::get_singleton()->canvas_item_add_primitive(canvas_item, p_points, p_colors, p_uvs, rid, p_width);
}
-void CanvasItem::draw_set_transform(const Point2 &p_offset, float p_rot, const Size2 &p_scale) {
+void CanvasItem::draw_set_transform(const Point2 &p_offset, real_t p_rot, const Size2 &p_scale) {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
Transform2D xform(p_rot, p_offset);
@@ -907,19 +907,19 @@ 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, float p_width, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint8_t p_flags) const {
+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, uint8_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);
}
-void CanvasItem::draw_multiline_string(const Ref<Font> &p_font, 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, uint8_t p_flags) const {
+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, uint8_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);
}
-float 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 {
+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 {
ERR_FAIL_COND_V_MSG(!drawing, 0.f, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL_COND_V(p_font.is_null(), 0.f);
ERR_FAIL_COND_V(p_char.length() != 1, 0.f);
@@ -1441,6 +1441,7 @@ void CanvasTexture::set_specular_texture(const Ref<Texture2D> &p_specular) {
RID tex_rid = specular_texture.is_valid() ? specular_texture->get_rid() : RID();
RS::get_singleton()->canvas_texture_set_channel(canvas_texture, RS::CANVAS_TEXTURE_CHANNEL_SPECULAR, tex_rid);
}
+
Ref<Texture2D> CanvasTexture::get_specular_texture() const {
return specular_texture;
}
@@ -1449,15 +1450,17 @@ void CanvasTexture::set_specular_color(const Color &p_color) {
specular = p_color;
RS::get_singleton()->canvas_texture_set_shading_parameters(canvas_texture, specular, shininess);
}
+
Color CanvasTexture::get_specular_color() const {
return specular;
}
-void CanvasTexture::set_specular_shininess(float p_shininess) {
+void CanvasTexture::set_specular_shininess(real_t p_shininess) {
shininess = p_shininess;
RS::get_singleton()->canvas_texture_set_shading_parameters(canvas_texture, specular, shininess);
}
-float CanvasTexture::get_specular_shininess() const {
+
+real_t CanvasTexture::get_specular_shininess() const {
return shininess;
}
@@ -1508,9 +1511,9 @@ bool CanvasTexture::has_alpha() const {
}
}
-Ref<Image> CanvasTexture::get_data() const {
+Ref<Image> CanvasTexture::get_image() const {
if (diffuse_texture.is_valid()) {
- return diffuse_texture->get_data();
+ return diffuse_texture->get_image();
} else {
return Ref<Image>();
}
diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h
index e22f93a7ea..1c64cafab8 100644
--- a/scene/main/canvas_item.h
+++ b/scene/main/canvas_item.h
@@ -290,8 +290,8 @@ public:
// Used to rotate the node
virtual bool _edit_use_rotation() const { return false; };
- virtual void _edit_set_rotation(float p_rotation) {}
- virtual float _edit_get_rotation() const { return 0.0; };
+ virtual void _edit_set_rotation(real_t p_rotation) {}
+ virtual real_t _edit_get_rotation() const { return 0.0; };
// Used to resize/move the node
virtual bool _edit_use_rect() const { return false; }; // MAYBE REPLACE BY A _edit_get_editmode()
@@ -331,30 +331,30 @@ public:
/* DRAWING API */
- void draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = 1.0);
- void draw_polyline(const Vector<Point2> &p_points, const Color &p_color, float p_width = 1.0, bool p_antialiased = false);
- void draw_polyline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0, bool p_antialiased = false);
- void draw_arc(const Vector2 &p_center, float p_radius, float p_start_angle, float p_end_angle, int p_point_count, const Color &p_color, float p_width = 1.0, bool p_antialiased = false);
- void draw_multiline(const Vector<Point2> &p_points, const Color &p_color, float p_width = 1.0);
- void draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0);
- void draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled = true, float p_width = 1.0);
- void draw_circle(const Point2 &p_pos, float p_radius, const Color &p_color);
+ void draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width = 1.0);
+ void draw_polyline(const Vector<Point2> &p_points, const Color &p_color, real_t p_width = 1.0, bool p_antialiased = false);
+ void draw_polyline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, real_t p_width = 1.0, bool p_antialiased = false);
+ void draw_arc(const Vector2 &p_center, real_t p_radius, real_t p_start_angle, real_t p_end_angle, int p_point_count, const Color &p_color, real_t p_width = 1.0, bool p_antialiased = false);
+ void draw_multiline(const Vector<Point2> &p_points, const Color &p_color, real_t p_width = 1.0);
+ void draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, real_t p_width = 1.0);
+ void draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled = true, real_t p_width = 1.0);
+ void draw_circle(const Point2 &p_pos, real_t p_radius, const Color &p_color);
void draw_texture(const Ref<Texture2D> &p_texture, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1, 1));
void draw_texture_rect(const Ref<Texture2D> &p_texture, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false);
void draw_texture_rect_region(const Ref<Texture2D> &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, bool p_clip_uv = false);
void draw_style_box(const Ref<StyleBox> &p_style_box, const Rect2 &p_rect);
- void draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture2D> p_texture = Ref<Texture2D>(), float p_width = 1);
+ void draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture2D> p_texture = Ref<Texture2D>(), real_t p_width = 1);
void draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture2D> p_texture = Ref<Texture2D>());
void draw_colored_polygon(const Vector<Point2> &p_points, const Color &p_color, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture2D> p_texture = Ref<Texture2D>());
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, float p_width = -1, int p_size = -1, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint8_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, float p_width = -1, int p_max_lines = -1, int p_size = -1, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint8_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
- float draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, const String &p_next = "", int p_size = -1, 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_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 = -1, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint8_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 = -1, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint8_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 = -1, 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, float p_rot = 0.0, const Size2 &p_scale = Size2(1.0, 1.0));
+ void draw_set_transform(const Point2 &p_offset, real_t p_rot = 0.0, const Size2 &p_scale = Size2(1.0, 1.0));
void draw_set_transform_matrix(const Transform2D &p_matrix);
static CanvasItem *get_current_item_drawn();
@@ -437,7 +437,7 @@ class CanvasTexture : public Texture2D {
Ref<Texture2D> normal_texture;
Ref<Texture2D> specular_texture;
Color specular = Color(1, 1, 1, 1);
- float shininess = 1.0;
+ real_t shininess = 1.0;
RID canvas_texture;
@@ -460,8 +460,8 @@ public:
void set_specular_color(const Color &p_color);
Color get_specular_color() const;
- void set_specular_shininess(float p_shininess);
- float get_specular_shininess() const;
+ void set_specular_shininess(real_t p_shininess);
+ real_t get_specular_shininess() const;
void set_texture_filter(CanvasItem::TextureFilter p_filter);
CanvasItem::TextureFilter get_texture_filter() const;
@@ -475,7 +475,7 @@ public:
virtual bool is_pixel_opaque(int p_x, int p_y) const override;
virtual bool has_alpha() const override;
- virtual Ref<Image> get_data() const override;
+ virtual Ref<Image> get_image() const override;
virtual RID get_rid() const override;
diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp
index d9b29daf26..85d7edd64b 100644
--- a/scene/main/canvas_layer.cpp
+++ b/scene/main/canvas_layer.cpp
@@ -258,13 +258,11 @@ void CanvasLayer::_update_follow_viewport(bool p_force_exit) {
}
}
-#ifdef TOOLS_ENABLED
void CanvasLayer::_validate_property(PropertyInfo &property) const {
if (!follow_viewport && property.name == "follow_viewport_scale") {
property.usage = PROPERTY_USAGE_NOEDITOR;
}
}
-#endif
void CanvasLayer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_layer", "layer"), &CanvasLayer::set_layer);
diff --git a/scene/main/canvas_layer.h b/scene/main/canvas_layer.h
index b20b291367..899039340a 100644
--- a/scene/main/canvas_layer.h
+++ b/scene/main/canvas_layer.h
@@ -61,13 +61,10 @@ class CanvasLayer : public Node {
void _update_locrotscale();
void _update_follow_viewport(bool p_force_exit = false);
-#ifdef TOOLS_ENABLED
- void _validate_property(PropertyInfo &property) const override;
-#endif
-
protected:
void _notification(int p_what);
static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const override;
public:
void set_layer(int p_xform);
diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp
index 71c372aec2..e4ed5c6e6c 100644
--- a/scene/main/http_request.cpp
+++ b/scene/main/http_request.cpp
@@ -335,7 +335,7 @@ bool HTTPRequest::_update_connection() {
call_deferred("_request_done", RESULT_CHUNKED_BODY_SIZE_MISMATCH, response_code, response_headers, PackedByteArray());
return true;
- // Request migh have been done
+ // Request might have been done
} else {
// Did not request yet, do request
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 9d8c7981e6..933f67db68 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -428,7 +428,7 @@ void Node::set_process_mode(ProcessMode p_mode) {
_propagate_process_owner(data.process_owner, pause_notification);
#ifdef TOOLS_ENABLED
// This is required for the editor to update the visibility of disabled nodes
- // Its very expensive during runtime to change, so editor-only
+ // It's very expensive during runtime to change, so editor-only
if (Engine::get_singleton()->is_editor_hint()) {
get_tree()->emit_signal("tree_process_mode_changed");
}
@@ -1021,22 +1021,8 @@ void Node::_set_name_nocheck(const StringName &p_name) {
data.name = p_name;
}
-String Node::invalid_character = ". : @ / \"";
-
-bool Node::_validate_node_name(String &p_name) {
- String name = p_name;
- Vector<String> chars = Node::invalid_character.split(" ");
- for (int i = 0; i < chars.size(); i++) {
- name = name.replace(chars[i], "");
- }
- bool is_valid = name == p_name;
- p_name = name;
- return is_valid;
-}
-
void Node::set_name(const String &p_name) {
- String name = p_name;
- _validate_node_name(name);
+ String name = p_name.validate_node_name();
ERR_FAIL_COND(name == "");
data.name = name;
@@ -1144,7 +1130,7 @@ String increase_numeric_string(const String &s) {
void Node::_generate_serial_child_name(const Node *p_child, StringName &name) const {
if (name == StringName()) {
- //no name and a new nade is needed, create one.
+ //no name and a new name is needed, create one.
name = p_child->get_class();
// Adjust casing according to project setting. The current type name is expected to be in PascalCase.
@@ -1170,7 +1156,7 @@ void Node::_generate_serial_child_name(const Node *p_child, StringName &name) co
bool exists = false;
for (int i = 0; i < cc; i++) {
- if (children_ptr[i] == p_child) { //exclude self in renaming if its already a child
+ if (children_ptr[i] == p_child) { //exclude self in renaming if it's already a child
continue;
}
if (children_ptr[i]->data.name == name) {
@@ -1959,7 +1945,7 @@ void Node::set_editable_instance(Node *p_node, bool p_editable) {
if (!p_editable) {
p_node->data.editable_instance = false;
// Avoid this flag being needlessly saved;
- // also give more visual feedback if editable children is re-enabled
+ // also give more visual feedback if editable children are re-enabled
set_display_folded(false);
} else {
p_node->data.editable_instance = true;
@@ -2065,19 +2051,26 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
// Since nodes in the instanced hierarchy won't be duplicated explicitly, we need to make an inventory
// of all the nodes in the tree of the instanced scene in order to transfer the values of the properties
+ Vector<const Node *> instance_roots;
+ instance_roots.push_back(this);
+
for (List<const Node *>::Element *N = node_tree.front(); N; N = N->next()) {
for (int i = 0; i < N->get()->get_child_count(); ++i) {
Node *descendant = N->get()->get_child(i);
// Skip nodes not really belonging to the instanced hierarchy; they'll be processed normally later
// but remember non-instanced nodes that are hidden below instanced ones
- if (descendant->data.owner != this) {
- if (descendant->get_parent() && descendant->get_parent() != this && descendant->get_parent()->data.owner == this && descendant->data.owner != descendant->get_parent()) {
+ if (!instance_roots.has(descendant->get_owner())) {
+ if (descendant->get_parent() && descendant->get_parent() != this && descendant->data.owner != descendant->get_parent()) {
hidden_roots.push_back(descendant);
}
continue;
}
node_tree.push_back(descendant);
+
+ if (descendant->get_filename() != "" && instance_roots.has(descendant->get_owner())) {
+ instance_roots.push_back(descendant);
+ }
}
}
}
diff --git a/scene/main/node.h b/scene/main/node.h
index d47d271a10..b1e51d2aee 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -190,12 +190,6 @@ private:
_FORCE_INLINE_ bool _can_process(bool p_paused) const;
-#ifdef TOOLS_ENABLED
- friend class SceneTreeEditor;
-#endif
- static String invalid_character;
- static bool _validate_node_name(String &p_name);
-
protected:
void _block() { data.blocked++; }
void _unblock() { data.blocked--; }
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 9aaddfd373..66f3a2ebde 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -389,6 +389,7 @@ void SceneTree::set_group(const StringName &p_group, const String &p_name, const
}
void SceneTree::initialize() {
+ ERR_FAIL_COND(!root);
initialized = true;
root->_set_tree(this);
MainLoop::initialize();
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 40b85e6d7b..5df35d1e6a 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -131,7 +131,7 @@ bool ViewportTexture::has_alpha() const {
return false;
}
-Ref<Image> ViewportTexture::get_data() const {
+Ref<Image> ViewportTexture::get_image() const {
ERR_FAIL_COND_V_MSG(!vp, Ref<Image>(), "Viewport Texture must be set to use it.");
return RS::get_singleton()->texture_2d_get(vp->texture_rid);
}
@@ -1163,7 +1163,7 @@ void Viewport::set_world_2d(const Ref<World2D> &p_world_2d) {
if (p_world_2d.is_valid()) {
world_2d = p_world_2d;
} else {
- WARN_PRINT("Invalid world_3d");
+ WARN_PRINT("Invalid world_2d");
world_2d = Ref<World2D>(memnew(World2D));
}
@@ -1621,10 +1621,10 @@ void Viewport::_gui_call_input(Control *p_control, const Ref<InputEvent> &p_inpu
Ref<InputEventMouseButton> mb = p_input;
bool cant_stop_me_now = (mb.is_valid() &&
- (mb->get_button_index() == BUTTON_WHEEL_DOWN ||
- mb->get_button_index() == BUTTON_WHEEL_UP ||
- mb->get_button_index() == BUTTON_WHEEL_LEFT ||
- mb->get_button_index() == BUTTON_WHEEL_RIGHT));
+ (mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN ||
+ mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP ||
+ mb->get_button_index() == MOUSE_BUTTON_WHEEL_LEFT ||
+ mb->get_button_index() == MOUSE_BUTTON_WHEEL_RIGHT));
Ref<InputEventPanGesture> pn = p_input;
cant_stop_me_now = pn.is_valid() || cant_stop_me_now;
@@ -1860,7 +1860,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
gui.mouse_focus_mask = 1 << (mb->get_button_index() - 1);
- if (mb->get_button_index() == BUTTON_LEFT) {
+ if (mb->get_button_index() == MOUSE_BUTTON_LEFT) {
gui.drag_accum = Vector2();
gui.drag_attempted = false;
}
@@ -1883,7 +1883,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
}
#endif
- if (mb->get_button_index() == BUTTON_LEFT) { //assign focus
+ if (mb->get_button_index() == MOUSE_BUTTON_LEFT) { //assign focus
CanvasItem *ci = gui.mouse_focus;
while (ci) {
Control *control = Object::cast_to<Control>(ci);
@@ -1914,7 +1914,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
set_input_as_handled();
- if (gui.drag_data.get_type() != Variant::NIL && mb->get_button_index() == BUTTON_LEFT) {
+ if (gui.drag_data.get_type() != Variant::NIL && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
//alternate drop use (when using force_drag(), as proposed by #5342
if (gui.mouse_focus) {
_gui_drop(gui.mouse_focus, pos, false);
@@ -1934,7 +1934,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
_gui_cancel_tooltip();
} else {
- if (gui.drag_data.get_type() != Variant::NIL && mb->get_button_index() == BUTTON_LEFT) {
+ if (gui.drag_data.get_type() != Variant::NIL && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
if (gui.drag_mouse_over) {
_gui_drop(gui.drag_mouse_over, gui.drag_mouse_over_pos, false);
}
@@ -1978,7 +1978,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
_gui_call_input(mouse_focus, mb);
}
- /*if (gui.drag_data.get_type()!=Variant::NIL && mb->get_button_index()==BUTTON_LEFT) {
+ /*if (gui.drag_data.get_type()!=Variant::NIL && mb->get_button_index()==MOUSE_BUTTON_LEFT) {
_propagate_viewport_notification(this,NOTIFICATION_DRAG_END);
gui.drag_data=Variant(); //always clear
}*/
@@ -2022,7 +2022,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Control *over = nullptr;
// D&D
- if (!gui.drag_attempted && gui.mouse_focus && mm->get_button_mask() & BUTTON_MASK_LEFT) {
+ if (!gui.drag_attempted && gui.mouse_focus && mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT) {
gui.drag_accum += mm->get_relative();
float len = gui.drag_accum.length();
if (len > 10) {
@@ -2201,7 +2201,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
embedder = this;
viewport_pos = mpos;
} else {
- //not an embeder, but may be a subwindow of an embedder
+ //not an embedder, but may be a subwindow of an embedder
Window *w = Object::cast_to<Window>(this);
if (w) {
if (w->is_embedded()) {
@@ -2266,7 +2266,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Transform2D localizer = gui.drag_mouse_over->get_global_transform_with_canvas().affine_inverse();
gui.drag_mouse_over_pos = localizer.xform(viewport_pos);
- if (mm->get_button_mask() & BUTTON_MASK_LEFT) {
+ if (mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT) {
bool can_drop = _gui_drop(gui.drag_mouse_over, gui.drag_mouse_over_pos, true);
if (!can_drop) {
@@ -2393,7 +2393,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
//keyboard focus
//if (from && p_event->is_pressed() && !p_event->get_alt() && !p_event->get_metakey() && !p_event->key->get_command()) {
Ref<InputEventKey> k = p_event;
- //need to check for mods, otherwise any combination of alt/ctrl/shift+<up/down/left/righ/etc> is handled here when it shouldn't be.
+ //need to check for mods, otherwise any combination of alt/ctrl/shift+<up/down/left/right/etc> is handled here when it shouldn't be.
bool mods = k.is_valid() && (k->get_control() || k->get_alt() || k->get_shift() || k->get_metakey());
if (from && p_event->is_pressed()) {
@@ -2672,7 +2672,7 @@ void Viewport::_post_gui_grab_click_focus() {
Ref<InputEventMouseButton> mb;
mb.instance();
- //send unclic
+ //send unclick
mb->set_position(click);
mb->set_button_index(i + 1);
@@ -2690,7 +2690,7 @@ void Viewport::_post_gui_grab_click_focus() {
Ref<InputEventMouseButton> mb;
mb.instance();
- //send clic
+ //send click
mb->set_position(click);
mb->set_button_index(i + 1);
@@ -2783,7 +2783,7 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND_V(gui.subwindow_focused == nullptr, false);
Ref<InputEventMouseButton> mb = p_event;
- if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
+ if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
if (gui.subwindow_drag == SUB_WINDOW_DRAG_CLOSE) {
if (gui.subwindow_drag_close_rect.has_point(mb->get_position())) {
//close window
@@ -2908,7 +2908,7 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mb = p_event;
//if the event is a mouse button, we need to check whether another window was clicked
- if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
+ if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
bool click_on_window = false;
for (int i = gui.sub_windows.size() - 1; i >= 0; i--) {
SubWindow &sw = gui.sub_windows.write[i];
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 0f11e6fb19..8e79b50385 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -77,7 +77,7 @@ public:
virtual bool has_alpha() const override;
- virtual Ref<Image> get_data() const override;
+ virtual Ref<Image> get_image() const override;
ViewportTexture();
~ViewportTexture();
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index d697a1a5dd..bacb0030bb 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -232,7 +232,7 @@ void Window::_make_window() {
DisplayServer::get_singleton()->window_set_current_screen(current_screen, window_id);
DisplayServer::get_singleton()->window_set_max_size(max_size, window_id);
DisplayServer::get_singleton()->window_set_min_size(min_size, window_id);
- DisplayServer::get_singleton()->window_set_title(title, window_id);
+ DisplayServer::get_singleton()->window_set_title(tr(title), window_id);
DisplayServer::get_singleton()->window_attach_instance_id(get_instance_id(), window_id);
_update_window_size();
@@ -759,6 +759,10 @@ void Window::_notification(int p_what) {
}
}
+ if (p_what == NOTIFICATION_TRANSLATION_CHANGED) {
+ child_controls_changed();
+ }
+
if (p_what == NOTIFICATION_EXIT_TREE) {
if (transient) {
_clear_transient();
@@ -893,12 +897,13 @@ void Window::_window_input(const Ref<InputEvent> &p_ev) {
}
if (exclusive_child != nullptr) {
+ /*
Window *focus_target = exclusive_child;
focus_target->grab_focus();
while (focus_target->exclusive_child != nullptr) {
focus_target = focus_target->exclusive_child;
focus_target->grab_focus();
- }
+ }*/
if (!is_embedding_subwindows()) { //not embedding, no need for event
return;
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 51d4643883..93964db8da 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -50,7 +50,6 @@
#include "scene/2d/line_2d.h"
#include "scene/2d/mesh_instance_2d.h"
#include "scene/2d/multimesh_instance_2d.h"
-#include "scene/2d/navigation_2d.h"
#include "scene/2d/navigation_agent_2d.h"
#include "scene/2d/navigation_obstacle_2d.h"
#include "scene/2d/parallax_background.h"
@@ -206,7 +205,6 @@
#include "scene/3d/listener_3d.h"
#include "scene/3d/mesh_instance_3d.h"
#include "scene/3d/multimesh_instance_3d.h"
-#include "scene/3d/navigation_3d.h"
#include "scene/3d/navigation_agent_3d.h"
#include "scene/3d/navigation_obstacle_3d.h"
#include "scene/3d/navigation_region_3d.h"
@@ -516,7 +514,6 @@ void register_scene_types() {
ClassDB::register_class<ConeTwistJoint3D>();
ClassDB::register_class<Generic6DOFJoint3D>();
- ClassDB::register_class<Navigation3D>();
ClassDB::register_class<NavigationRegion3D>();
ClassDB::register_class<NavigationAgent3D>();
ClassDB::register_class<NavigationObstacle3D>();
@@ -793,7 +790,6 @@ void register_scene_types() {
ClassDB::register_class<PathFollow2D>();
ClassDB::register_class<NavigationMesh>();
- ClassDB::register_class<Navigation2D>();
ClassDB::register_class<NavigationPolygon>();
ClassDB::register_class<NavigationRegion2D>();
ClassDB::register_class<NavigationAgent2D>();
@@ -814,6 +810,8 @@ void register_scene_types() {
ClassDB::add_compatibility_class("DynamicFont", "Font");
ClassDB::add_compatibility_class("DynamicFontData", "FontData");
ClassDB::add_compatibility_class("ToolButton", "Button");
+ ClassDB::add_compatibility_class("Navigation3D", "Node3D");
+ ClassDB::add_compatibility_class("Navigation2D", "Node2D");
// Renamed in 4.0.
// Keep alphabetical ordering to easily locate classes and avoid duplicates.
@@ -865,7 +863,6 @@ void register_scene_types() {
ClassDB::add_compatibility_class("Listener", "Listener3D");
ClassDB::add_compatibility_class("MeshInstance", "MeshInstance3D");
ClassDB::add_compatibility_class("MultiMeshInstance", "MultiMeshInstance3D");
- ClassDB::add_compatibility_class("Navigation", "Navigation3D");
ClassDB::add_compatibility_class("NavigationAgent", "NavigationAgent3D");
ClassDB::add_compatibility_class("NavigationMeshInstance", "NavigationRegion3D");
ClassDB::add_compatibility_class("NavigationObstacle", "NavigationObstacle3D");
@@ -950,15 +947,17 @@ void register_scene_types() {
for (int i = 0; i < 20; i++) {
GLOBAL_DEF_BASIC(vformat("layer_names/2d_render/layer_%d", i), "");
GLOBAL_DEF_BASIC(vformat("layer_names/2d_physics/layer_%d", i), "");
+ GLOBAL_DEF_BASIC(vformat("layer_names/2d_navigation/layer_%d", i), "");
GLOBAL_DEF_BASIC(vformat("layer_names/3d_render/layer_%d", i), "");
GLOBAL_DEF_BASIC(vformat("layer_names/3d_physics/layer_%d", i), "");
+ GLOBAL_DEF_BASIC(vformat("layer_names/3d_navigation/layer_%d", i), "");
}
bool default_theme_hidpi = GLOBAL_DEF("gui/theme/use_hidpi", false);
ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/use_hidpi", PropertyInfo(Variant::BOOL, "gui/theme/use_hidpi", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
- String theme_path = GLOBAL_DEF("gui/theme/custom", "");
+ String theme_path = GLOBAL_DEF_RST("gui/theme/custom", "");
ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/custom", PropertyInfo(Variant::STRING, "gui/theme/custom", PROPERTY_HINT_FILE, "*.tres,*.res,*.theme", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
- String font_path = GLOBAL_DEF("gui/theme/custom_font", "");
+ String font_path = GLOBAL_DEF_RST("gui/theme/custom_font", "");
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;
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index cc1dafd0db..6f64ac6d04 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -2738,7 +2738,7 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
real_t d = Geometry3D::get_closest_point_to_segment(v1, s).distance_to(v1);
if (d > pd.length() * p_alowed_linear_err) {
- return false; //beyond allowed error for colinearity
+ return false; //beyond allowed error for collinearity
}
if (p_norm != Vector3() && Math::acos(pd.normalized().dot(p_norm)) > p_alowed_angular_err) {
@@ -2828,7 +2828,7 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
real_t d = Geometry3D::get_closest_point_to_segment(v1, s).distance_to(v1);
if (d > pd.length() * p_alowed_linear_err) {
- return false; //beyond allowed error for colinearity
+ return false; //beyond allowed error for collinearity
}
t[2] = (d1 - d0) / (d2 - d0);
diff --git a/scene/resources/bit_map.cpp b/scene/resources/bit_map.cpp
index 8ffc7b4b4c..3cc1af59ae 100644
--- a/scene/resources/bit_map.cpp
+++ b/scene/resources/bit_map.cpp
@@ -285,7 +285,7 @@ Vector<Vector2> BitMap::_march_square(const Rect2i &rect, const Point2i &start)
+---+---+
| 4 | |
+---+---+
- this normally go RIGHT, but if its coming from RIGHT, it should go LEFT
+ this normally go RIGHT, but if it's coming from RIGHT, it should go LEFT
*/
if (case6s.has(Point2i(curx, cury))) {
//found, so we go left, and delete from case6s;
diff --git a/scene/resources/camera_effects.cpp b/scene/resources/camera_effects.cpp
index 00312fc7b2..34c6bc05bc 100644
--- a/scene/resources/camera_effects.cpp
+++ b/scene/resources/camera_effects.cpp
@@ -145,7 +145,6 @@ void CameraEffects::_update_override_exposure() {
// Private methods, constructor and destructor
-#ifdef TOOLS_ENABLED
void CameraEffects::_validate_property(PropertyInfo &property) const {
if ((!dof_blur_far_enabled && (property.name == "dof_blur_far_distance" || property.name == "dof_blur_far_transition")) ||
(!dof_blur_near_enabled && (property.name == "dof_blur_near_distance" || property.name == "dof_blur_near_transition")) ||
@@ -153,7 +152,6 @@ void CameraEffects::_validate_property(PropertyInfo &property) const {
property.usage = PROPERTY_USAGE_NOEDITOR;
}
}
-#endif
void CameraEffects::_bind_methods() {
// DOF blur
diff --git a/scene/resources/camera_effects.h b/scene/resources/camera_effects.h
index 51fb2b6cf7..b9338f4806 100644
--- a/scene/resources/camera_effects.h
+++ b/scene/resources/camera_effects.h
@@ -57,12 +57,9 @@ private:
float override_exposure = 1.0;
void _update_override_exposure();
-#ifdef TOOLS_ENABLED
- void _validate_property(PropertyInfo &property) const override;
-#endif
-
protected:
static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const override;
public:
virtual RID get_rid() const override;
diff --git a/scene/resources/concave_polygon_shape_3d.cpp b/scene/resources/concave_polygon_shape_3d.cpp
index f067695d7d..3fed700383 100644
--- a/scene/resources/concave_polygon_shape_3d.cpp
+++ b/scene/resources/concave_polygon_shape_3d.cpp
@@ -35,13 +35,12 @@
Vector<Vector3> ConcavePolygonShape3D::get_debug_mesh_lines() const {
Set<DrawEdge> edges;
- Vector<Vector3> data = get_faces();
- int datalen = data.size();
- ERR_FAIL_COND_V((datalen % 3) != 0, Vector<Vector3>());
+ int index_count = faces.size();
+ ERR_FAIL_COND_V((index_count % 3) != 0, Vector<Vector3>());
- const Vector3 *r = data.ptr();
+ const Vector3 *r = faces.ptr();
- for (int i = 0; i < datalen; i += 3) {
+ for (int i = 0; i < index_count; i += 3) {
for (int j = 0; j < 3; j++) {
DrawEdge de(r[i + j], r[i + ((j + 1) % 3)]);
edges.insert(de);
@@ -71,22 +70,46 @@ real_t ConcavePolygonShape3D::get_enclosing_radius() const {
}
void ConcavePolygonShape3D::_update_shape() {
+ Dictionary d;
+ d["faces"] = faces;
+ d["backface_collision"] = backface_collision;
+ PhysicsServer3D::get_singleton()->shape_set_data(get_shape(), d);
+
Shape3D::_update_shape();
}
void ConcavePolygonShape3D::set_faces(const Vector<Vector3> &p_faces) {
- PhysicsServer3D::get_singleton()->shape_set_data(get_shape(), p_faces);
+ faces = p_faces;
+ _update_shape();
notify_change_to_owners();
}
Vector<Vector3> ConcavePolygonShape3D::get_faces() const {
- return PhysicsServer3D::get_singleton()->shape_get_data(get_shape());
+ return faces;
+}
+
+void ConcavePolygonShape3D::set_backface_collision_enabled(bool p_enabled) {
+ backface_collision = p_enabled;
+
+ if (!faces.is_empty()) {
+ _update_shape();
+ notify_change_to_owners();
+ }
+}
+
+bool ConcavePolygonShape3D::is_backface_collision_enabled() const {
+ return backface_collision;
}
void ConcavePolygonShape3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_faces", "faces"), &ConcavePolygonShape3D::set_faces);
ClassDB::bind_method(D_METHOD("get_faces"), &ConcavePolygonShape3D::get_faces);
+
+ ClassDB::bind_method(D_METHOD("set_backface_collision_enabled", "enabled"), &ConcavePolygonShape3D::set_backface_collision_enabled);
+ ClassDB::bind_method(D_METHOD("is_backface_collision_enabled"), &ConcavePolygonShape3D::is_backface_collision_enabled);
+
ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR3_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_faces", "get_faces");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "backface_collision"), "set_backface_collision_enabled", "is_backface_collision_enabled");
}
ConcavePolygonShape3D::ConcavePolygonShape3D() :
diff --git a/scene/resources/concave_polygon_shape_3d.h b/scene/resources/concave_polygon_shape_3d.h
index 391459a3d7..bb28359dcc 100644
--- a/scene/resources/concave_polygon_shape_3d.h
+++ b/scene/resources/concave_polygon_shape_3d.h
@@ -36,6 +36,9 @@
class ConcavePolygonShape3D : public Shape3D {
GDCLASS(ConcavePolygonShape3D, Shape3D);
+ Vector<Vector3> faces;
+ bool backface_collision = false;
+
struct DrawEdge {
Vector3 a;
Vector3 b;
@@ -65,6 +68,9 @@ public:
void set_faces(const Vector<Vector3> &p_faces);
Vector<Vector3> get_faces() const;
+ void set_backface_collision_enabled(bool p_enabled);
+ bool is_backface_collision_enabled() const;
+
virtual Vector<Vector3> get_debug_mesh_lines() const override;
virtual real_t get_enclosing_radius() const override;
diff --git a/scene/resources/default_theme/bar_arrow.png b/scene/resources/default_theme/bar_arrow.png
new file mode 100644
index 0000000000..7cf146b8da
--- /dev/null
+++ b/scene/resources/default_theme/bar_arrow.png
Binary files differ
diff --git a/scene/resources/default_theme/checked_disabled.png b/scene/resources/default_theme/checked_disabled.png
new file mode 100644
index 0000000000..70549e2edc
--- /dev/null
+++ b/scene/resources/default_theme/checked_disabled.png
Binary files differ
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index a94209c75f..85d097aa19 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -114,7 +114,7 @@ static Ref<Texture2D> flip_icon(Ref<Texture2D> p_texture, bool p_flip_y = false,
}
Ref<ImageTexture> texture(memnew(ImageTexture));
- Ref<Image> img = p_texture->get_data();
+ Ref<Image> img = p_texture->get_image();
img = img->duplicate();
if (p_flip_y) {
@@ -348,9 +348,13 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("focus", "CheckBox", cbx_focus);
theme->set_icon("checked", "CheckBox", make_icon(checked_png));
+ theme->set_icon("checked_disabled", "CheckBox", make_icon(checked_disabled_png));
theme->set_icon("unchecked", "CheckBox", make_icon(unchecked_png));
+ theme->set_icon("unchecked_disabled", "CheckBox", make_icon(unchecked_disabled_png));
theme->set_icon("radio_checked", "CheckBox", make_icon(radio_checked_png));
+ theme->set_icon("radio_checked_disabled", "CheckBox", make_icon(radio_checked_disabled_png));
theme->set_icon("radio_unchecked", "CheckBox", make_icon(radio_unchecked_png));
+ theme->set_icon("radio_unchecked_disabled", "CheckBox", make_icon(radio_unchecked_disabled_png));
theme->set_font("font", "CheckBox", Ref<Font>());
theme->set_font_size("font_size", "CheckBox", -1);
@@ -628,6 +632,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// File Dialog
theme->set_icon("parent_folder", "FileDialog", make_icon(icon_parent_folder_png));
+ theme->set_icon("back_folder", "FileDialog", make_icon(arrow_left_png));
+ theme->set_icon("forward_folder", "FileDialog", make_icon(arrow_right_png));
theme->set_icon("reload", "FileDialog", make_icon(icon_reload_png));
theme->set_icon("toggle_hidden", "FileDialog", make_icon(icon_visibility_png));
@@ -884,6 +890,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("color_sample", "ColorPicker", make_icon(color_picker_sample_png));
theme->set_icon("preset_bg", "ColorPicker", make_icon(mini_checkerboard_png));
theme->set_icon("overbright_indicator", "ColorPicker", make_icon(overbright_indicator_png));
+ theme->set_icon("bar_arrow", "ColorPicker", make_icon(bar_arrow_png));
theme->set_icon("bg", "ColorPickerButton", make_icon(mini_checkerboard_png));
@@ -1017,7 +1024,7 @@ void make_default_theme(bool p_hidpi, Ref<Font> p_font) {
Ref<StyleBox> default_style;
Ref<Texture2D> default_icon;
Ref<Font> default_font;
- int default_font_size = 16;
+ int default_font_size = 14;
if (p_font.is_valid()) {
default_font = p_font;
} else if (p_hidpi) {
diff --git a/scene/resources/default_theme/radio_checked_disabled.png b/scene/resources/default_theme/radio_checked_disabled.png
new file mode 100644
index 0000000000..72f08ecb96
--- /dev/null
+++ b/scene/resources/default_theme/radio_checked_disabled.png
Binary files differ
diff --git a/scene/resources/default_theme/radio_unchecked_disabled.png b/scene/resources/default_theme/radio_unchecked_disabled.png
new file mode 100644
index 0000000000..a8f4c1b555
--- /dev/null
+++ b/scene/resources/default_theme/radio_unchecked_disabled.png
Binary files differ
diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h
index b905c9db69..5d4dbd0758 100644
--- a/scene/resources/default_theme/theme_data.h
+++ b/scene/resources/default_theme/theme_data.h
@@ -14,6 +14,10 @@ static const unsigned char arrow_right_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x4, 0x0, 0x0, 0x0, 0xfc, 0x7c, 0x94, 0x6c, 0x0, 0x0, 0x0, 0x2e, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x20, 0x17, 0x3c, 0xf8, 0xf, 0x82, 0xf7, 0x13, 0x70, 0x48, 0x3c, 0xf8, 0xf2, 0x50, 0x1b, 0x43, 0x2, 0xa, 0xaf, 0xbe, 0xe0, 0xc6, 0x2e, 0xf1, 0xff, 0xe1, 0x7c, 0x12, 0x24, 0x10, 0x46, 0x11, 0xb6, 0x1c, 0xe1, 0x5c, 0xa, 0x0, 0x0, 0xe0, 0x14, 0x48, 0xb1, 0x3d, 0x1b, 0x7a, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
+static const unsigned char bar_arrow_png[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x14, 0x8, 0x4, 0x0, 0x0, 0x0, 0x2e, 0x6b, 0x75, 0xfc, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x1, 0x73, 0x52, 0x47, 0x42, 0x0, 0xae, 0xce, 0x1c, 0xe9, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xe, 0xc0, 0x0, 0x0, 0xe, 0xc0, 0x1, 0x6a, 0xd6, 0x89, 0x9, 0x0, 0x0, 0x0, 0x65, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x63, 0xfc, 0xcf, 0x80, 0x1f, 0x30, 0x8e, 0x20, 0x5, 0x8c, 0x38, 0x24, 0xff, 0x53, 0x5f, 0xc1, 0xb, 0xee, 0x9f, 0x53, 0x18, 0x18, 0xd8, 0x73, 0x24, 0xbe, 0x62, 0x55, 0x70, 0x5f, 0x83, 0x61, 0x15, 0xa3, 0x2e, 0x3, 0x3, 0xc3, 0xd, 0xe6, 0x30, 0xd9, 0xcb, 0x18, 0xa, 0x1e, 0xc6, 0xfd, 0x9f, 0xc6, 0xc0, 0xd, 0x35, 0xea, 0x3b, 0x63, 0x81, 0xfc, 0x2c, 0x14, 0x5, 0xf, 0x2a, 0x18, 0xda, 0xd1, 0x1c, 0x50, 0xa9, 0xd0, 0x1, 0x57, 0xf0, 0x10, 0x53, 0x9a, 0x81, 0x81, 0x81, 0xa1, 0x52, 0xbe, 0x83, 0x81, 0x81, 0xf1, 0x3f, 0x2e, 0x69, 0xa8, 0x12, 0x3a, 0x4, 0x14, 0x0, 0x7b, 0xda, 0x34, 0x1, 0xbb, 0xb5, 0x3e, 0x6c, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
+
static const unsigned char bookmark_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, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x4, 0x73, 0x42, 0x49, 0x54, 0x8, 0x8, 0x8, 0x8, 0x7c, 0x8, 0x64, 0x88, 0x0, 0x0, 0x0, 0x57, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xed, 0x93, 0x31, 0xa, 0xc0, 0x30, 0xc, 0x3, 0xa5, 0xd0, 0xff, 0x7f, 0x59, 0x1d, 0x8a, 0x42, 0x8, 0x9, 0x95, 0xc9, 0xd2, 0xa1, 0x9a, 0x8c, 0xf1, 0xdd, 0x62, 0x1b, 0x38, 0xc, 0x87, 0x5a, 0x5, 0xae, 0x79, 0xde, 0x2, 0x1, 0x80, 0x94, 0x39, 0x48, 0x76, 0x49, 0x17, 0xa4, 0xf0, 0x24, 0x61, 0x2b, 0x51, 0x8b, 0xfc, 0x82, 0xcf, 0xb, 0x48, 0x7a, 0xdf, 0x75, 0x81, 0xf, 0xe5, 0x29, 0xf7, 0x92, 0x6b, 0x3, 0x1a, 0x1e, 0xda, 0x7c, 0x3d, 0x77, 0x21, 0x7b, 0xa8, 0x74, 0x2e, 0xcb, 0xd, 0xc8, 0x75, 0x13, 0x28, 0x9, 0xed, 0xc2, 0xc8, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
@@ -42,6 +46,10 @@ static const unsigned char checked_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, 0x8d, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x58, 0x56, 0x63, 0xb0, 0xaf, 0xb5, 0x38, 0x37, 0x40, 0x20, 0x20, 0x24, 0xb6, 0xb6, 0xb9, 0x57, 0x57, 0x5a, 0x20, 0x20, 0x24, 0x38, 0x36, 0x40, 0x20, 0x20, 0x25, 0x1e, 0x1e, 0x22, 0x1f, 0x1f, 0x23, 0x8b, 0x8b, 0x8d, 0xff, 0xff, 0xff, 0x20, 0x20, 0x24, 0x22, 0x22, 0x27, 0x23, 0x23, 0x28, 0x42, 0x42, 0x47, 0xf8, 0xf8, 0xf8, 0xfe, 0xfe, 0xfe, 0x25, 0x25, 0x2a, 0x4e, 0x4e, 0x52, 0x26, 0x26, 0x2b, 0xc5, 0xc5, 0xc7, 0xaa, 0xaa, 0xab, 0xb8, 0xb8, 0xba, 0x5f, 0x5f, 0x63, 0x74, 0x74, 0x77, 0xed, 0xed, 0xed, 0x33, 0x33, 0x38, 0x8d, 0x8d, 0x8f, 0xb8, 0xb8, 0xb9, 0x35, 0x35, 0x39, 0x3a, 0x3a, 0x3e, 0xfb, 0xfb, 0xfb, 0xfa, 0xfa, 0xfa, 0xb2, 0xb2, 0xb4, 0x45, 0x45, 0x49, 0x61, 0x61, 0x65, 0x8f, 0x8f, 0x92, 0x63, 0x63, 0x66, 0x2a, 0x2a, 0x2f, 0x40, 0x82, 0xb, 0xf6, 0x0, 0x0, 0x0, 0xf, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x7, 0x27, 0x50, 0x66, 0x68, 0x6a, 0x81, 0xb4, 0xfa, 0xdd, 0xfb, 0xfb, 0xb4, 0xfa, 0xb8, 0xf0, 0x7f, 0x59, 0x0, 0x0, 0x0, 0x7e, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x5d, 0xca, 0x5, 0xb2, 0x2, 0x30, 0x18, 0x3, 0xe1, 0x4d, 0xed, 0xb9, 0x60, 0xf7, 0x3f, 0x20, 0xee, 0x4e, 0x99, 0xe0, 0xb0, 0x63, 0xfd, 0xbf, 0x86, 0xd7, 0x12, 0x72, 0x38, 0x69, 0x5b, 0x6b, 0x42, 0x45, 0xe5, 0xa, 0xab, 0x95, 0x41, 0x9f, 0x32, 0x20, 0x69, 0x2d, 0xbc, 0x50, 0x46, 0x3a, 0x10, 0x17, 0x5f, 0x49, 0x4, 0x7f, 0x90, 0x57, 0x89, 0xb7, 0xc5, 0x5f, 0x96, 0x17, 0x2e, 0x93, 0xcb, 0x8e, 0x3a, 0x83, 0xb, 0xc4, 0x8e, 0xd4, 0xff, 0x5c, 0x73, 0x83, 0x69, 0x9e, 0x95, 0xfc, 0x3b, 0xf4, 0x33, 0xe0, 0xf8, 0x61, 0xd3, 0xf1, 0x7d, 0x5d, 0x30, 0x7a, 0x6f, 0x89, 0xb, 0xd4, 0x5a, 0xe1, 0x40, 0xf, 0xfc, 0x34, 0x6c, 0xd2, 0x56, 0x80, 0xef, 0xfd, 0x9, 0xd2, 0x3a, 0x5e, 0x41, 0x15, 0x21, 0x77, 0x6, 0xc7, 0x6b, 0x47, 0x4e, 0x3a, 0x2f, 0x53, 0xb4, 0x10, 0xc7, 0x8c, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
+static const unsigned char checked_disabled_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, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x99, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x7a, 0x78, 0x83, 0x7a, 0x78, 0x83, 0x73, 0x72, 0x7b, 0x7a, 0x78, 0x83, 0x7a, 0x78, 0x83, 0x7a, 0x78, 0x83, 0x82, 0x80, 0x8a, 0x90, 0x90, 0x93, 0x6a, 0x69, 0x70, 0x6a, 0x68, 0x70, 0x93, 0x93, 0x95, 0x58, 0x58, 0x5c, 0x58, 0x58, 0x5b, 0x7d, 0x7d, 0x7f, 0x58, 0x58, 0x5b, 0xa4, 0xa4, 0xa4, 0x9e, 0x9e, 0xa0, 0x9e, 0x9e, 0x9e, 0x9b, 0x9b, 0x9c, 0x9b, 0x9b, 0x9b, 0x9a, 0x9a, 0x9a, 0x99, 0x99, 0x99, 0x98, 0x98, 0x98, 0x97, 0x97, 0x97, 0x96, 0x96, 0x96, 0x95, 0x95, 0x95, 0x93, 0x93, 0x94, 0x8f, 0x8f, 0x8f, 0x86, 0x86, 0x88, 0x85, 0x85, 0x86, 0x82, 0x82, 0x83, 0x81, 0x81, 0x83, 0x7f, 0x7f, 0x81, 0x7c, 0x7c, 0x7e, 0x7a, 0x7a, 0x7d, 0x78, 0x78, 0x7b, 0x71, 0x71, 0x74, 0x68, 0x68, 0x6c, 0x66, 0x66, 0x6a, 0x65, 0x65, 0x68, 0x63, 0x63, 0x66, 0x5f, 0x5f, 0x63, 0x5c, 0x5c, 0x60, 0x5c, 0x5c, 0x5f, 0x5a, 0x5a, 0x5e, 0x59, 0x59, 0x5d, 0x59, 0x59, 0x5c, 0x58, 0x58, 0x5b, 0x57, 0x57, 0x5a, 0x56, 0x56, 0x59, 0x10, 0x13, 0xbb, 0xf, 0x0, 0x0, 0x0, 0x10, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x7, 0x27, 0x27, 0x50, 0x66, 0x68, 0x6a, 0x81, 0xb4, 0xb4, 0xdd, 0xfa, 0xfa, 0xfb, 0xfb, 0x5b, 0xd1, 0xf1, 0xe6, 0x0, 0x0, 0x0, 0x96, 0x49, 0x44, 0x41, 0x54, 0x78, 0x5e, 0x5d, 0x8f, 0xc9, 0x12, 0x82, 0x30, 0x14, 0x4, 0x87, 0x18, 0x50, 0x51, 0x44, 0x25, 0x42, 0x4, 0x77, 0xc4, 0x8d, 0x97, 0x0, 0xf9, 0xff, 0x8f, 0xb3, 0x88, 0xa4, 0x4a, 0xed, 0x63, 0x5f, 0xa6, 0x7, 0xf8, 0x7, 0x1e, 0xe3, 0x7e, 0x60, 0x19, 0x4f, 0x46, 0x1e, 0x0, 0x36, 0x8d, 0x4c, 0x67, 0x59, 0x65, 0x33, 0x6, 0x80, 0x47, 0xad, 0x56, 0x3d, 0xb7, 0x3c, 0x5d, 0x70, 0x0, 0xbe, 0xd1, 0x44, 0x65, 0x4d, 0x94, 0xc8, 0xc2, 0xf8, 0x0, 0x82, 0x4e, 0x91, 0x94, 0x15, 0x5d, 0xd2, 0xec, 0xde, 0x5, 0x83, 0x38, 0xc8, 0xe3, 0x63, 0x23, 0xce, 0xca, 0x9, 0x7a, 0x6e, 0xf3, 0x93, 0x48, 0x1a, 0x27, 0x14, 0x35, 0x3b, 0xb9, 0x5e, 0x56, 0xe4, 0x84, 0x22, 0xba, 0xa, 0x51, 0xd0, 0xb7, 0xa8, 0xcb, 0xfd, 0xcb, 0x9, 0x3b, 0xfb, 0x41, 0xdb, 0x59, 0x17, 0xa6, 0x94, 0x6e, 0xe3, 0x3e, 0x8c, 0x85, 0xf1, 0x90, 0x6e, 0xe6, 0x21, 0xfb, 0x39, 0xe7, 0x73, 0xe6, 0xfd, 0x5f, 0x7, 0xde, 0xc3, 0xb5, 0x16, 0x87, 0xb0, 0x9e, 0x42, 0x46, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
+
static const unsigned char checker_bg_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x0, 0x0, 0x0, 0x0, 0xe1, 0x64, 0xe1, 0x57, 0x0, 0x0, 0x0, 0x14, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0xfc, 0xcf, 0xc0, 0xc0, 0xd0, 0x0, 0xc4, 0xf8, 0x18, 0xf5, 0x84, 0x19, 0x0, 0x9f, 0x5f, 0xa, 0x1, 0xf8, 0xef, 0x65, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
@@ -282,10 +290,18 @@ static const unsigned char radio_checked_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, 0x42, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4, 0x3, 0x4, 0x9, 0x9, 0x9, 0x6, 0x6, 0x6, 0xa, 0xa, 0xb, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x7f, 0x7f, 0x82, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, 0xd9, 0x47, 0x47, 0x48, 0xd3, 0xd3, 0xd3, 0xa2, 0xa2, 0xa2, 0x79, 0x79, 0x79, 0x73, 0x73, 0x73, 0x1c, 0x1c, 0x1c, 0x3, 0x3, 0x3, 0x0, 0x0, 0x0, 0xd1, 0xa7, 0xf5, 0xaa, 0x0, 0x0, 0x0, 0xb, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x88, 0xd1, 0xf7, 0x64, 0xf6, 0x2, 0xb3, 0xed, 0xd7, 0x0, 0x0, 0x0, 0x63, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x6d, 0x4f, 0x55, 0x2, 0x43, 0x31, 0x8, 0x4b, 0xe8, 0x6a, 0xf7, 0xbf, 0xeb, 0xc, 0x9b, 0x6b, 0x1f, 0x9f, 0xc4, 0x89, 0xbf, 0xbb, 0x3f, 0x2a, 0x49, 0x64, 0xa6, 0x3e, 0x1e, 0x1c, 0x7c, 0x3e, 0xf2, 0x14, 0xb7, 0xc7, 0xac, 0xf1, 0x10, 0xa6, 0xe8, 0x1, 0x44, 0xad, 0x42, 0xb9, 0x33, 0x22, 0x43, 0x95, 0x68, 0x55, 0xa4, 0xdc, 0x1f, 0x1e, 0xa1, 0x67, 0xa2, 0x57, 0x96, 0x22, 0x0, 0xc2, 0x3d, 0xf5, 0x44, 0x8c, 0x8a, 0x5d, 0x21, 0x80, 0x74, 0x83, 0x1e, 0x97, 0xc7, 0x22, 0x59, 0x4c, 0xd7, 0xd8, 0xb5, 0x18, 0x4a, 0x7b, 0x57, 0x57, 0xdb, 0x1a, 0xf7, 0x77, 0x17, 0x3a, 0x56, 0x4e, 0x11, 0x6f, 0x82, 0x20, 0xde, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
+static const unsigned char radio_checked_disabled_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, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x45, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x3, 0x4, 0x9, 0x9, 0x9, 0x6, 0x6, 0x6, 0xa, 0xa, 0xb, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x7f, 0x7f, 0x82, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, 0xd9, 0x47, 0x47, 0x48, 0xd3, 0xd3, 0xd3, 0xa2, 0xa2, 0xa2, 0x79, 0x79, 0x79, 0x73, 0x73, 0x73, 0x1c, 0x1c, 0x1c, 0x3, 0x3, 0x3, 0x0, 0x0, 0x0, 0x83, 0xac, 0xe9, 0xaf, 0x0, 0x0, 0x0, 0x1, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x40, 0xe6, 0xd8, 0x66, 0x0, 0x0, 0x0, 0x3f, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0x20, 0xe, 0xf0, 0x8, 0x2, 0x1, 0xf, 0x9c, 0x2b, 0x2c, 0x8, 0x5, 0xc2, 0x50, 0x1, 0xb0, 0x34, 0x58, 0x11, 0x5c, 0xbd, 0x10, 0x3f, 0x10, 0x8, 0xc1, 0x74, 0x1, 0x65, 0xf8, 0xc1, 0x0, 0xa6, 0x4, 0x28, 0x1, 0x11, 0xe0, 0xc1, 0x2d, 0x80, 0xa6, 0x5, 0xc3, 0x50, 0xc, 0x6b, 0x31, 0x1d, 0x86, 0xe1, 0x74, 0xfc, 0x0, 0x0, 0x1b, 0xc, 0x7, 0xb9, 0xa, 0x5e, 0x2e, 0x12, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
+
static const unsigned char radio_unchecked_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, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x2a, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4, 0x3, 0x4, 0x9, 0x9, 0x9, 0x6, 0x6, 0x6, 0xa, 0xa, 0xb, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x7f, 0x7f, 0x82, 0xd9, 0xd9, 0xd9, 0x47, 0x47, 0x48, 0x2b, 0x6e, 0xf2, 0xbf, 0x0, 0x0, 0x0, 0xb, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x88, 0xd1, 0xf7, 0x64, 0xf6, 0x2, 0xb3, 0xed, 0xd7, 0x0, 0x0, 0x0, 0x49, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x40, 0x2, 0x61, 0x15, 0xed, 0xa9, 0x20, 0x5a, 0x72, 0xf5, 0x99, 0x33, 0xbb, 0x26, 0x1, 0x19, 0x73, 0xcf, 0x0, 0xc1, 0x4d, 0x6, 0x6, 0xd6, 0x35, 0x20, 0xc6, 0xa9, 0x0, 0x6, 0xb6, 0x3d, 0x20, 0xc6, 0xe9, 0x4, 0x6, 0xf6, 0x33, 0x60, 0x50, 0xc0, 0xc0, 0x1, 0x61, 0x34, 0xc0, 0x19, 0x70, 0x29, 0xb8, 0x62, 0xb8, 0x76, 0x84, 0x81, 0xc, 0x96, 0x20, 0x2b, 0xa6, 0xc0, 0x2d, 0x45, 0x0, 0x0, 0x37, 0xca, 0x3d, 0x81, 0xb4, 0x84, 0xb6, 0x80, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
+static const unsigned char radio_unchecked_disabled_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, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0xf, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x54, 0x54, 0x54, 0xad, 0xad, 0xad, 0x80, 0x80, 0x81, 0x64, 0x64, 0x64, 0xf4, 0x17, 0x36, 0x28, 0x0, 0x0, 0x0, 0x2, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x1b, 0xfc, 0xf6, 0x4, 0xd4, 0x0, 0x0, 0x0, 0x40, 0x49, 0x44, 0x41, 0x54, 0x78, 0x5e, 0x7d, 0x8d, 0xb1, 0x11, 0x80, 0x40, 0xc, 0xc3, 0x94, 0xd, 0x12, 0x60, 0x1, 0xc4, 0x4, 0xb0, 0x1, 0xfb, 0x2f, 0x45, 0xe5, 0x3b, 0xaa, 0x57, 0xe5, 0xc2, 0xb6, 0x20, 0xc0, 0xcc, 0xc, 0x40, 0xed, 0x7a, 0x37, 0x70, 0xa8, 0xbe, 0x50, 0x9b, 0xea, 0xd9, 0xd4, 0xa3, 0x7a, 0x35, 0xa5, 0xaa, 0xeb, 0x90, 0x72, 0xe6, 0x39, 0xfc, 0x2b, 0x22, 0xd, 0x1f, 0xe7, 0x64, 0xa, 0x5d, 0x6c, 0xfe, 0xc1, 0x3b, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
+
static const unsigned char scroll_bg_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x3, 0x0, 0x0, 0x0, 0x61, 0xab, 0xac, 0xd5, 0x0, 0x0, 0x0, 0x45, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x40, 0x3e, 0x4a, 0x2a, 0x29, 0x2f, 0x20, 0x20, 0x24, 0x3f, 0x3e, 0x49, 0x1f, 0x1f, 0x24, 0x20, 0x20, 0x24, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x3f, 0x3e, 0x49, 0x3f, 0x3e, 0x49, 0x1e, 0x1e, 0x23, 0x20, 0x20, 0x25, 0x22, 0x22, 0x27, 0x23, 0x23, 0x27, 0x23, 0x23, 0x28, 0x25, 0x25, 0x2a, 0x14, 0xee, 0x69, 0x20, 0x0, 0x0, 0x0, 0x11, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x4, 0x19, 0x40, 0x5d, 0x66, 0x28, 0x93, 0xf0, 0xfc, 0x94, 0xfc, 0xfd, 0x67, 0x1a, 0x96, 0x95, 0x1c, 0xf0, 0x43, 0x52, 0x0, 0x0, 0x0, 0x55, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x55, 0x8e, 0x45, 0x2, 0x80, 0x50, 0x10, 0x42, 0xc1, 0xee, 0xfb, 0x5f, 0xd4, 0xd6, 0xdf, 0xfd, 0x36, 0xd3, 0x3, 0x4, 0xd, 0x90, 0x6, 0xb2, 0x25, 0x39, 0xe0, 0xd2, 0xf9, 0xcb, 0x6a, 0x60, 0x6f, 0x27, 0xb7, 0xbc, 0x58, 0xb7, 0x53, 0x4d, 0x0, 0xf2, 0x3f, 0x5e, 0x36, 0x43, 0x5f, 0xc3, 0xf0, 0xdf, 0x17, 0xd7, 0xa6, 0xae, 0x60, 0x10, 0xff, 0x57, 0x16, 0xc5, 0x5a, 0xf1, 0x60, 0xe3, 0xe7, 0x5f, 0x37, 0x46, 0x74, 0xba, 0x9a, 0x16, 0xef, 0x37, 0x1c, 0x6f, 0x61, 0x47, 0x1, 0xa5, 0xc7, 0x32, 0x47, 0x38, 0x12, 0x92, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
@@ -430,6 +446,10 @@ static const unsigned char unchecked_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, 0x33, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x38, 0x37, 0x40, 0x20, 0x20, 0x24, 0x20, 0x20, 0x24, 0x38, 0x36, 0x40, 0x20, 0x20, 0x25, 0x1e, 0x1e, 0x22, 0x1f, 0x1f, 0x23, 0x20, 0x20, 0x24, 0x22, 0x22, 0x27, 0x23, 0x23, 0x28, 0x25, 0x25, 0x2a, 0x23, 0xc3, 0x49, 0x39, 0x0, 0x0, 0x0, 0xb, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x7, 0x27, 0x50, 0x66, 0x68, 0xb4, 0xfa, 0xfb, 0xb4, 0xfa, 0xa4, 0x7f, 0xe1, 0x5a, 0x0, 0x0, 0x0, 0x4f, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xb5, 0xcf, 0x45, 0x2, 0x80, 0x40, 0x8, 0x0, 0x40, 0x97, 0x66, 0xfb, 0xff, 0x9f, 0xb5, 0xdb, 0xb3, 0x73, 0xa4, 0x19, 0xbe, 0x2, 0x20, 0xf1, 0x8a, 0x10, 0xc2, 0x1c, 0x0, 0xd1, 0x94, 0x57, 0x49, 0x5, 0xe6, 0x0, 0x6a, 0xa9, 0x6d, 0x55, 0x8b, 0xe2, 0x1c, 0xa0, 0x54, 0xfb, 0xae, 0x26, 0x9a, 0x3, 0x9c, 0xdb, 0x11, 0x68, 0x99, 0xff, 0xa, 0x7c, 0xd6, 0xde, 0xf, 0x33, 0x9c, 0x3, 0xe0, 0x76, 0x9c, 0x1e, 0x1d, 0xbe, 0xcf, 0x7d, 0x4c, 0x93, 0xe2, 0x8, 0xa4, 0x66, 0x3c, 0xec, 0xed, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
+static const unsigned char unchecked_disabled_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, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x33, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x7a, 0x78, 0x83, 0x7a, 0x78, 0x83, 0x7a, 0x78, 0x83, 0x7a, 0x78, 0x83, 0x7a, 0x78, 0x83, 0x6a, 0x69, 0x70, 0x6a, 0x68, 0x70, 0x58, 0x58, 0x5c, 0x58, 0x58, 0x5b, 0x58, 0x58, 0x5b, 0x5c, 0x5c, 0x5f, 0x5a, 0x5a, 0x5e, 0x59, 0x59, 0x5d, 0x58, 0x58, 0x5b, 0x57, 0x57, 0x5a, 0x56, 0x56, 0x59, 0x27, 0xa1, 0xa6, 0x53, 0x0, 0x0, 0x0, 0xb, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x7, 0x27, 0x50, 0x66, 0x68, 0xb4, 0xb4, 0xfa, 0xfa, 0xfb, 0xc7, 0x8b, 0xf6, 0x7e, 0x0, 0x0, 0x0, 0x52, 0x49, 0x44, 0x41, 0x54, 0x78, 0x5e, 0xb5, 0xcf, 0x31, 0x12, 0xc0, 0x20, 0x8, 0x44, 0xd1, 0x15, 0x50, 0x83, 0x11, 0xe5, 0xfe, 0xa7, 0xcd, 0xe8, 0xc4, 0x22, 0xf4, 0x79, 0xe5, 0x36, 0x7c, 0x80, 0x8, 0x89, 0x58, 0xf2, 0x26, 0x4c, 0x9, 0x0, 0x15, 0xf5, 0xb9, 0xb9, 0x16, 0x2, 0xc0, 0x3a, 0xac, 0x6f, 0x36, 0x94, 0x1, 0x88, 0xdb, 0xfd, 0x32, 0x17, 0x0, 0x79, 0xf6, 0x33, 0xf4, 0x99, 0xff, 0x1a, 0xe2, 0xd9, 0x4f, 0x58, 0x5b, 0x61, 0x54, 0xdb, 0x49, 0xbf, 0xea, 0x4a, 0x8f, 0xcf, 0x45, 0xf, 0x4, 0x40, 0x7, 0x90, 0xb0, 0x7b, 0x47, 0x4, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
+
static const unsigned char updown_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0x81, 0x83, 0xf6, 0xf6, 0x0, 0x0, 0x0, 0x57, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x8d, 0x4e, 0xb5, 0x1, 0xc0, 0x30, 0xc, 0xf3, 0x15, 0xfe, 0xff, 0x96, 0x64, 0xa, 0x6c, 0xca, 0x56, 0xd2, 0x25, 0x65, 0xe6, 0xc8, 0x8b, 0x49, 0x20, 0x79, 0x28, 0x95, 0x81, 0xa1, 0xd4, 0x7d, 0x4, 0xbb, 0xa1, 0x50, 0xea, 0x3c, 0xa6, 0x71, 0x98, 0x96, 0x69, 0x58, 0x31, 0xcc, 0xb7, 0xe5, 0x2f, 0x48, 0x63, 0x26, 0xf6, 0xa2, 0xd4, 0x18, 0xf9, 0x7, 0x2d, 0xe3, 0x46, 0x89, 0xb4, 0xd2, 0xf8, 0xa3, 0x68, 0xe3, 0xd7, 0x14, 0x20, 0xe6, 0xc3, 0x3d, 0xd8, 0xca, 0x5e, 0x94, 0x32, 0xd0, 0x3, 0x91, 0xba, 0x5f, 0x1b, 0x4a, 0x9b, 0x12, 0x62, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
diff --git a/scene/resources/default_theme/unchecked_disabled.png b/scene/resources/default_theme/unchecked_disabled.png
new file mode 100644
index 0000000000..bef9316f58
--- /dev/null
+++ b/scene/resources/default_theme/unchecked_disabled.png
Binary files differ
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 9931757cc4..0d02bde90d 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -1703,7 +1703,7 @@ void BaseMaterial3D::_validate_property(PropertyInfo &property) const {
property.usage = PROPERTY_USAGE_NOEDITOR;
}
- // you can only enable anti-aliasing (in mataerials) on alpha scissor and alpha hash
+ // you can only enable anti-aliasing (in materials) on alpha scissor and alpha hash
const bool can_select_aa = (transparency == TRANSPARENCY_ALPHA_SCISSOR || transparency == TRANSPARENCY_ALPHA_HASH);
// alpha anti aliasiasing is only enabled when you can select aa
const bool alpha_aa_enabled = (alpha_antialiasing_mode != ALPHA_ANTIALIASING_OFF) && can_select_aa;
@@ -1722,7 +1722,7 @@ void BaseMaterial3D::_validate_property(PropertyInfo &property) const {
property.usage = 0;
}
- // we cant choose an antialiasing mode if alpha isnt possible
+ // we can't choose an antialiasing mode if alpha isn't possible
if (property.name == "alpha_antialiasing_edge" && !alpha_aa_enabled) {
property.usage = 0;
}
diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp
index 167540eb77..195ce070a7 100644
--- a/scene/resources/particles_material.cpp
+++ b/scene/resources/particles_material.cpp
@@ -340,14 +340,21 @@ void ParticlesMaterial::_update_shader() {
//initiate velocity spread in 3D
code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n";
code += " float angle2_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad * (1.0 - flatness);\n";
- code += " angle1_rad += direction.z != 0.0 ? atan(direction.x, direction.z) : sign(direction.x) * (pi / 2.0);\n";
- code += " angle2_rad += direction.z != 0.0 ? atan(direction.y, abs(direction.z)) : (direction.x != 0.0 ? atan(direction.y, abs(direction.x)) : sign(direction.y) * (pi / 2.0));\n";
code += " vec3 direction_xz = vec3(sin(angle1_rad), 0.0, cos(angle1_rad));\n";
code += " vec3 direction_yz = vec3(0.0, sin(angle2_rad), cos(angle2_rad));\n";
code += " direction_yz.z = direction_yz.z / max(0.0001,sqrt(abs(direction_yz.z))); // better uniform distribution\n";
- code += " vec3 vec_direction = vec3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z);\n";
- code += " vec_direction = normalize(vec_direction);\n";
- code += " VELOCITY = vec_direction * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n";
+ code += " vec3 spread_direction = vec3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z);\n";
+ code += " vec3 direction_nrm = normalize(direction);\n";
+ code += " // rotate spread to direction\n";
+ code += " vec3 binormal = cross(vec3(0.0, 1.0, 0.0), direction_nrm);\n";
+ code += " if (length(binormal) < 0.0001) {\n";
+ code += " // direction is parallel to Y. Choose Z as the binormal.\n";
+ code += " binormal = vec3(0.0, 0.0, 1.0);\n";
+ code += " }\n";
+ code += " binormal = normalize(binormal);\n";
+ code += " vec3 normal = cross(binormal, direction_nrm);\n";
+ code += " spread_direction = binormal * spread_direction.x + normal * spread_direction.y + direction_nrm * spread_direction.z;\n";
+ code += " VELOCITY = spread_direction * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n";
}
code += " }\n";
@@ -1075,7 +1082,7 @@ ParticlesMaterial::SubEmitterMode ParticlesMaterial::get_sub_emitter_mode() cons
void ParticlesMaterial::set_sub_emitter_frequency(float p_frequency) {
sub_emitter_frequency = p_frequency;
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->sub_emitter_frequency, 1.0 / p_frequency); //pas delta instead of frequency, since its easier to compute
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->sub_emitter_frequency, 1.0 / p_frequency); //pass delta instead of frequency, since its easier to compute
}
float ParticlesMaterial::get_sub_emitter_frequency() const {
return sub_emitter_frequency;
diff --git a/scene/resources/polygon_path_finder.cpp b/scene/resources/polygon_path_finder.cpp
index f292140d6b..536318ed16 100644
--- a/scene/resources/polygon_path_finder.cpp
+++ b/scene/resources/polygon_path_finder.cpp
@@ -77,7 +77,7 @@ void PolygonPathFinder::setup(const Vector<Vector2> &p_points, const Vector<int>
outside_point.x += 20.451 + Math::randf() * 10.2039;
outside_point.y += 21.193 + Math::randf() * 12.5412;
- //insert edges (which are also connetions)
+ //insert edges (which are also connections)
for (int i = 0; i < p_connections.size(); i += 2) {
Edge e(p_connections[i], p_connections[i + 1]);
@@ -335,7 +335,7 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
//oh this was visited already, can we win the cost?
if (p.distance > distance) {
- p.prev = least_cost_point; //reasign previous
+ p.prev = least_cost_point; //reassign previous
p.distance = distance;
}
} else {
diff --git a/scene/resources/ray_shape_2d.cpp b/scene/resources/ray_shape_2d.cpp
index d2125445fa..fb8f4b9985 100644
--- a/scene/resources/ray_shape_2d.cpp
+++ b/scene/resources/ray_shape_2d.cpp
@@ -42,17 +42,33 @@ void RayShape2D::_update_shape() {
}
void RayShape2D::draw(const RID &p_to_rid, const Color &p_color) {
- Vector2 tip = Vector2(0, get_length());
- RS::get_singleton()->canvas_item_add_line(p_to_rid, Vector2(), tip, p_color, 3);
+ const Vector2 target_position = Vector2(0, get_length());
+
+ const float max_arrow_size = 6;
+ const float line_width = 1.4;
+ bool no_line = target_position.length() < line_width;
+ float arrow_size = CLAMP(target_position.length() * 2 / 3, line_width, max_arrow_size);
+
+ if (no_line) {
+ arrow_size = target_position.length();
+ } else {
+ RS::get_singleton()->canvas_item_add_line(p_to_rid, Vector2(), target_position - target_position.normalized() * arrow_size, p_color, line_width);
+ }
+
+ Transform2D xf;
+ xf.rotate(target_position.angle());
+ xf.translate(Vector2(no_line ? 0 : target_position.length() - arrow_size, 0));
+
Vector<Vector2> pts;
- float tsize = 4.0;
- pts.push_back(tip + Vector2(0, tsize));
- pts.push_back(tip + Vector2(Math_SQRT12 * tsize, 0));
- pts.push_back(tip + Vector2(-Math_SQRT12 * tsize, 0));
+ 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<Color> cols;
for (int i = 0; i < 3; i++) {
cols.push_back(p_color);
}
+
RS::get_singleton()->canvas_item_add_primitive(p_to_rid, pts, cols, Vector<Point2>(), RID());
}
diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp
index 7ca532e1d6..f2751b7604 100644
--- a/scene/resources/resource_format_text.cpp
+++ b/scene/resources/resource_format_text.cpp
@@ -1321,7 +1321,7 @@ String ResourceFormatLoaderText::get_resource_type(const String &p_path) const {
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) {
- return ""; //could not rwead
+ return ""; //could not read
}
ResourceLoaderText loader;
diff --git a/scene/resources/sprite_frames.cpp b/scene/resources/sprite_frames.cpp
new file mode 100644
index 0000000000..90c702081b
--- /dev/null
+++ b/scene/resources/sprite_frames.cpp
@@ -0,0 +1,241 @@
+/*************************************************************************/
+/* sprite_frames.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 "sprite_frames.h"
+
+#include "scene/scene_string_names.h"
+
+void SpriteFrames::add_frame(const StringName &p_anim, const Ref<Texture2D> &p_frame, int p_at_pos) {
+ Map<StringName, Anim>::Element *E = animations.find(p_anim);
+ ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist.");
+
+ if (p_at_pos >= 0 && p_at_pos < E->get().frames.size()) {
+ E->get().frames.insert(p_at_pos, p_frame);
+ } else {
+ E->get().frames.push_back(p_frame);
+ }
+
+ emit_changed();
+}
+
+int SpriteFrames::get_frame_count(const StringName &p_anim) const {
+ const Map<StringName, Anim>::Element *E = animations.find(p_anim);
+ ERR_FAIL_COND_V_MSG(!E, 0, "Animation '" + String(p_anim) + "' doesn't exist.");
+
+ return E->get().frames.size();
+}
+
+void SpriteFrames::remove_frame(const StringName &p_anim, int p_idx) {
+ Map<StringName, Anim>::Element *E = animations.find(p_anim);
+ ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist.");
+
+ E->get().frames.remove(p_idx);
+ emit_changed();
+}
+
+void SpriteFrames::clear(const StringName &p_anim) {
+ Map<StringName, Anim>::Element *E = animations.find(p_anim);
+ ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist.");
+
+ E->get().frames.clear();
+ emit_changed();
+}
+
+void SpriteFrames::clear_all() {
+ animations.clear();
+ add_animation("default");
+}
+
+void SpriteFrames::add_animation(const StringName &p_anim) {
+ ERR_FAIL_COND_MSG(animations.has(p_anim), "SpriteFrames already has animation '" + p_anim + "'.");
+
+ animations[p_anim] = Anim();
+}
+
+bool SpriteFrames::has_animation(const StringName &p_anim) const {
+ return animations.has(p_anim);
+}
+
+void SpriteFrames::remove_animation(const StringName &p_anim) {
+ animations.erase(p_anim);
+}
+
+void SpriteFrames::rename_animation(const StringName &p_prev, const StringName &p_next) {
+ ERR_FAIL_COND_MSG(!animations.has(p_prev), "SpriteFrames doesn't have animation '" + String(p_prev) + "'.");
+ ERR_FAIL_COND_MSG(animations.has(p_next), "Animation '" + String(p_next) + "' already exists.");
+
+ Anim anim = animations[p_prev];
+ animations.erase(p_prev);
+ animations[p_next] = anim;
+}
+
+Vector<String> SpriteFrames::_get_animation_list() const {
+ Vector<String> ret;
+ List<StringName> al;
+ get_animation_list(&al);
+ for (List<StringName>::Element *E = al.front(); E; E = E->next()) {
+ ret.push_back(E->get());
+ }
+
+ return ret;
+}
+
+void SpriteFrames::get_animation_list(List<StringName> *r_animations) const {
+ for (const Map<StringName, Anim>::Element *E = animations.front(); E; E = E->next()) {
+ r_animations->push_back(E->key());
+ }
+}
+
+Vector<String> SpriteFrames::get_animation_names() const {
+ Vector<String> names;
+ for (const Map<StringName, Anim>::Element *E = animations.front(); E; E = E->next()) {
+ names.push_back(E->key());
+ }
+ names.sort();
+ return names;
+}
+
+void SpriteFrames::set_animation_speed(const StringName &p_anim, float p_fps) {
+ ERR_FAIL_COND_MSG(p_fps < 0, "Animation speed cannot be negative (" + itos(p_fps) + ").");
+ Map<StringName, Anim>::Element *E = animations.find(p_anim);
+ ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist.");
+ E->get().speed = p_fps;
+}
+
+float SpriteFrames::get_animation_speed(const StringName &p_anim) const {
+ const Map<StringName, Anim>::Element *E = animations.find(p_anim);
+ ERR_FAIL_COND_V_MSG(!E, 0, "Animation '" + String(p_anim) + "' doesn't exist.");
+ return E->get().speed;
+}
+
+void SpriteFrames::set_animation_loop(const StringName &p_anim, bool p_loop) {
+ Map<StringName, Anim>::Element *E = animations.find(p_anim);
+ ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist.");
+ E->get().loop = p_loop;
+}
+
+bool SpriteFrames::get_animation_loop(const StringName &p_anim) const {
+ const Map<StringName, Anim>::Element *E = animations.find(p_anim);
+ ERR_FAIL_COND_V_MSG(!E, false, "Animation '" + String(p_anim) + "' doesn't exist.");
+ return E->get().loop;
+}
+
+void SpriteFrames::_set_frames(const Array &p_frames) {
+ clear_all();
+ Map<StringName, Anim>::Element *E = animations.find(SceneStringNames::get_singleton()->_default);
+ ERR_FAIL_COND(!E);
+
+ E->get().frames.resize(p_frames.size());
+ for (int i = 0; i < E->get().frames.size(); i++) {
+ E->get().frames.write[i] = p_frames[i];
+ }
+}
+
+Array SpriteFrames::_get_frames() const {
+ return Array();
+}
+
+Array SpriteFrames::_get_animations() const {
+ Array anims;
+ for (Map<StringName, Anim>::Element *E = animations.front(); E; E = E->next()) {
+ Dictionary d;
+ d["name"] = E->key();
+ d["speed"] = E->get().speed;
+ d["loop"] = E->get().loop;
+ Array frames;
+ for (int i = 0; i < E->get().frames.size(); i++) {
+ frames.push_back(E->get().frames[i]);
+ }
+ d["frames"] = frames;
+ anims.push_back(d);
+ }
+
+ return anims;
+}
+
+void SpriteFrames::_set_animations(const Array &p_animations) {
+ animations.clear();
+ for (int i = 0; i < p_animations.size(); i++) {
+ Dictionary d = p_animations[i];
+
+ ERR_CONTINUE(!d.has("name"));
+ ERR_CONTINUE(!d.has("speed"));
+ ERR_CONTINUE(!d.has("loop"));
+ ERR_CONTINUE(!d.has("frames"));
+
+ Anim anim;
+ anim.speed = d["speed"];
+ anim.loop = d["loop"];
+ Array frames = d["frames"];
+ for (int j = 0; j < frames.size(); j++) {
+ RES res = frames[j];
+ anim.frames.push_back(res);
+ }
+
+ animations[d["name"]] = anim;
+ }
+}
+
+void SpriteFrames::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("add_animation", "anim"), &SpriteFrames::add_animation);
+ ClassDB::bind_method(D_METHOD("has_animation", "anim"), &SpriteFrames::has_animation);
+ ClassDB::bind_method(D_METHOD("remove_animation", "anim"), &SpriteFrames::remove_animation);
+ ClassDB::bind_method(D_METHOD("rename_animation", "anim", "newname"), &SpriteFrames::rename_animation);
+
+ ClassDB::bind_method(D_METHOD("get_animation_names"), &SpriteFrames::get_animation_names);
+
+ ClassDB::bind_method(D_METHOD("set_animation_speed", "anim", "speed"), &SpriteFrames::set_animation_speed);
+ ClassDB::bind_method(D_METHOD("get_animation_speed", "anim"), &SpriteFrames::get_animation_speed);
+
+ ClassDB::bind_method(D_METHOD("set_animation_loop", "anim", "loop"), &SpriteFrames::set_animation_loop);
+ ClassDB::bind_method(D_METHOD("get_animation_loop", "anim"), &SpriteFrames::get_animation_loop);
+
+ ClassDB::bind_method(D_METHOD("add_frame", "anim", "frame", "at_position"), &SpriteFrames::add_frame, DEFVAL(-1));
+ ClassDB::bind_method(D_METHOD("get_frame_count", "anim"), &SpriteFrames::get_frame_count);
+ ClassDB::bind_method(D_METHOD("get_frame", "anim", "idx"), &SpriteFrames::get_frame);
+ ClassDB::bind_method(D_METHOD("set_frame", "anim", "idx", "txt"), &SpriteFrames::set_frame);
+ ClassDB::bind_method(D_METHOD("remove_frame", "anim", "idx"), &SpriteFrames::remove_frame);
+ ClassDB::bind_method(D_METHOD("clear", "anim"), &SpriteFrames::clear);
+ ClassDB::bind_method(D_METHOD("clear_all"), &SpriteFrames::clear_all);
+
+ ClassDB::bind_method(D_METHOD("_set_frames"), &SpriteFrames::_set_frames);
+ ClassDB::bind_method(D_METHOD("_get_frames"), &SpriteFrames::_get_frames);
+
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "frames", PROPERTY_HINT_NONE, "", 0), "_set_frames", "_get_frames"); //compatibility
+
+ ClassDB::bind_method(D_METHOD("_set_animations"), &SpriteFrames::_set_animations);
+ ClassDB::bind_method(D_METHOD("_get_animations"), &SpriteFrames::_get_animations);
+
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "animations", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_animations", "_get_animations"); //compatibility
+}
+
+SpriteFrames::SpriteFrames() {
+ add_animation(SceneStringNames::get_singleton()->_default);
+}
diff --git a/scene/3d/navigation_3d.h b/scene/resources/sprite_frames.h
index b89725a3f5..282c5f20ab 100644
--- a/scene/3d/navigation_3d.h
+++ b/scene/resources/sprite_frames.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* navigation_3d.h */
+/* sprite_frames.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,51 +28,75 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef NAVIGATION_3D_H
-#define NAVIGATION_3D_H
+#ifndef SPRITE_FRAMES_H
+#define SPRITE_FRAMES_H
-#include "scene/3d/navigation_region_3d.h"
-#include "scene/3d/node_3d.h"
+#include "scene/resources/texture.h"
-class Navigation3D : public Node3D {
- GDCLASS(Navigation3D, Node3D);
+class SpriteFrames : public Resource {
+ GDCLASS(SpriteFrames, Resource);
- RID map;
+ struct Anim {
+ float speed = 5.0;
+ bool loop = true;
+ Vector<Ref<Texture2D>> frames;
+ };
- Vector3 up = Vector3(0, 1, 0);
- real_t cell_size;
- real_t edge_connection_margin;
+ Map<StringName, Anim> animations;
+
+ Array _get_frames() const;
+ void _set_frames(const Array &p_frames);
+
+ Array _get_animations() const;
+ void _set_animations(const Array &p_animations);
+
+ Vector<String> _get_animation_list() const;
protected:
static void _bind_methods();
- void _notification(int p_what);
public:
- RID get_rid() const {
- return map;
- }
+ void add_animation(const StringName &p_anim);
+ bool has_animation(const StringName &p_anim) const;
+ void remove_animation(const StringName &p_anim);
+ void rename_animation(const StringName &p_prev, const StringName &p_next);
- void set_up_vector(const Vector3 &p_up);
- Vector3 get_up_vector() const;
+ void get_animation_list(List<StringName> *r_animations) const;
+ Vector<String> get_animation_names() const;
- void set_cell_size(float p_cell_size);
- float get_cell_size() const {
- return cell_size;
- }
+ void set_animation_speed(const StringName &p_anim, float p_fps);
+ float get_animation_speed(const StringName &p_anim) const;
+
+ void set_animation_loop(const StringName &p_anim, bool p_loop);
+ bool get_animation_loop(const StringName &p_anim) const;
- void set_edge_connection_margin(float p_edge_connection_margin);
- float get_edge_connection_margin() const {
- return edge_connection_margin;
+ void add_frame(const StringName &p_anim, const Ref<Texture2D> &p_frame, int p_at_pos = -1);
+ int get_frame_count(const StringName &p_anim) const;
+ _FORCE_INLINE_ Ref<Texture2D> get_frame(const StringName &p_anim, int p_idx) const {
+ const Map<StringName, Anim>::Element *E = animations.find(p_anim);
+ ERR_FAIL_COND_V_MSG(!E, Ref<Texture2D>(), "Animation '" + String(p_anim) + "' doesn't exist.");
+ ERR_FAIL_COND_V(p_idx < 0, Ref<Texture2D>());
+ if (p_idx >= E->get().frames.size()) {
+ return Ref<Texture2D>();
+ }
+
+ return E->get().frames[p_idx];
}
- Vector<Vector3> get_simple_path(const Vector3 &p_start, const Vector3 &p_end, bool p_optimize = true) const;
- Vector3 get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, bool p_use_collision = false) const;
- Vector3 get_closest_point(const Vector3 &p_point) const;
- Vector3 get_closest_point_normal(const Vector3 &p_point) const;
- RID get_closest_point_owner(const Vector3 &p_point) const;
+ void set_frame(const StringName &p_anim, int p_idx, const Ref<Texture2D> &p_frame) {
+ Map<StringName, Anim>::Element *E = animations.find(p_anim);
+ ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist.");
+ ERR_FAIL_COND(p_idx < 0);
+ if (p_idx >= E->get().frames.size()) {
+ return;
+ }
+ E->get().frames.write[p_idx] = p_frame;
+ }
+ void remove_frame(const StringName &p_anim, int p_idx);
+ void clear(const StringName &p_anim);
+ void clear_all();
- Navigation3D();
- ~Navigation3D();
+ SpriteFrames();
};
-#endif // NAVIGATION_H
+#endif // SPRITE_FRAMES_H
diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp
index 9b80224c3f..2159f1bc97 100644
--- a/scene/resources/style_box.cpp
+++ b/scene/resources/style_box.cpp
@@ -460,6 +460,7 @@ Point2 StyleBoxFlat::get_shadow_offset() const {
void StyleBoxFlat::set_anti_aliased(const bool &p_anti_aliased) {
anti_aliased = p_anti_aliased;
emit_changed();
+ notify_property_list_changed();
}
bool StyleBoxFlat::is_anti_aliased() const {
@@ -781,6 +782,12 @@ float StyleBoxFlat::get_style_margin(Side p_side) const {
return border_width[p_side];
}
+void StyleBoxFlat::_validate_property(PropertyInfo &property) const {
+ if (!anti_aliased && property.name == "anti_aliasing_size") {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
+ }
+}
+
void StyleBoxFlat::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_bg_color", "color"), &StyleBoxFlat::set_bg_color);
ClassDB::bind_method(D_METHOD("get_bg_color"), &StyleBoxFlat::get_bg_color);
diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h
index 8a273afbfd..dd5c873a00 100644
--- a/scene/resources/style_box.h
+++ b/scene/resources/style_box.h
@@ -159,6 +159,7 @@ class StyleBoxFlat : public StyleBox {
protected:
virtual float get_style_margin(Side p_side) const override;
static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const override;
public:
//Color
diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp
index 47933bd69a..3d3900ecc5 100644
--- a/scene/resources/surface_tool.cpp
+++ b/scene/resources/surface_tool.cpp
@@ -1059,6 +1059,10 @@ void SurfaceTool::set_material(const Ref<Material> &p_material) {
material = p_material;
}
+Ref<Material> SurfaceTool::get_material() const {
+ return material;
+}
+
void SurfaceTool::clear() {
begun = false;
primitive = Mesh::PRIMITIVE_LINES;
@@ -1088,6 +1092,10 @@ void SurfaceTool::set_custom_format(int p_index, CustomFormat p_format) {
ERR_FAIL_COND(begun);
last_custom_format[p_index] = p_format;
}
+
+Mesh::PrimitiveType SurfaceTool::get_primitive() const {
+ return primitive;
+}
SurfaceTool::CustomFormat SurfaceTool::get_custom_format(int p_index) const {
ERR_FAIL_INDEX_V(p_index, RS::ARRAY_CUSTOM_COUNT, CUSTOM_MAX);
return last_custom_format[p_index];
@@ -1174,6 +1182,7 @@ void SurfaceTool::_bind_methods() {
ClassDB::bind_method(D_METHOD("generate_lod", "nd_threshold", "target_index_count"), &SurfaceTool::generate_lod, DEFVAL(3));
ClassDB::bind_method(D_METHOD("set_material", "material"), &SurfaceTool::set_material);
+ ClassDB::bind_method(D_METHOD("get_primitive"), &SurfaceTool::get_primitive);
ClassDB::bind_method(D_METHOD("clear"), &SurfaceTool::clear);
diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h
index 17efdcba71..28addf2245 100644
--- a/scene/resources/surface_tool.h
+++ b/scene/resources/surface_tool.h
@@ -143,6 +143,8 @@ public:
void set_custom_format(int p_index, CustomFormat p_format);
CustomFormat get_custom_format(int p_index) const;
+ Mesh::PrimitiveType get_primitive() const;
+
void begin(Mesh::PrimitiveType p_primitive);
void set_color(Color p_color);
@@ -171,6 +173,7 @@ public:
Vector<int> generate_lod(float p_threshold, int p_target_index_count = 3);
void set_material(const Ref<Material> &p_material);
+ Ref<Material> get_material() const;
void clear();
diff --git a/scene/resources/text_paragraph.cpp b/scene/resources/text_paragraph.cpp
index 444a4bb22a..012d36cc35 100644
--- a/scene/resources/text_paragraph.cpp
+++ b/scene/resources/text_paragraph.cpp
@@ -98,6 +98,9 @@ void TextParagraph::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_line_underline_position", "line"), &TextParagraph::get_line_underline_position);
ClassDB::bind_method(D_METHOD("get_line_underline_thickness", "line"), &TextParagraph::get_line_underline_thickness);
+ ClassDB::bind_method(D_METHOD("get_spacing_top"), &TextParagraph::get_spacing_top);
+ ClassDB::bind_method(D_METHOD("get_spacing_bottom"), &TextParagraph::get_spacing_bottom);
+
ClassDB::bind_method(D_METHOD("get_dropcap_size"), &TextParagraph::get_dropcap_size);
ClassDB::bind_method(D_METHOD("get_dropcap_lines"), &TextParagraph::get_dropcap_lines);
@@ -266,6 +269,14 @@ bool TextParagraph::add_string(const String &p_text, const Ref<Font> &p_fonts, i
return res;
}
+int TextParagraph::get_spacing_top() const {
+ return spacing_top;
+}
+
+int TextParagraph::get_spacing_bottom() const {
+ return spacing_bottom;
+}
+
void TextParagraph::_set_bidi_override(const Array &p_override) {
Vector<Vector2i> overrides;
for (int i = 0; i < p_override.size(); i++) {
diff --git a/scene/resources/text_paragraph.h b/scene/resources/text_paragraph.h
index a16fa8c3c4..4396b07130 100644
--- a/scene/resources/text_paragraph.h
+++ b/scene/resources/text_paragraph.h
@@ -116,6 +116,9 @@ public:
float get_line_underline_position(int p_line) const;
float get_line_underline_thickness(int p_line) const;
+ int get_spacing_top() const;
+ int get_spacing_bottom() const;
+
Size2 get_dropcap_size() const;
int get_dropcap_lines() const;
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index d2bb1338d8..b6a2f24b8b 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -71,7 +71,7 @@ void Texture2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("draw", "canvas_item", "position", "modulate", "transpose"), &Texture2D::draw, DEFVAL(Color(1, 1, 1)), DEFVAL(false));
ClassDB::bind_method(D_METHOD("draw_rect", "canvas_item", "rect", "tile", "modulate", "transpose"), &Texture2D::draw_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false));
ClassDB::bind_method(D_METHOD("draw_rect_region", "canvas_item", "rect", "src_rect", "modulate", "transpose", "clip_uv"), &Texture2D::draw_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(true));
- ClassDB::bind_method(D_METHOD("get_data"), &Texture2D::get_data);
+ ClassDB::bind_method(D_METHOD("get_image"), &Texture2D::get_image);
ADD_GROUP("", "");
}
@@ -116,7 +116,7 @@ bool ImageTexture::_set(const StringName &p_name, const Variant &p_value) {
bool ImageTexture::_get(const StringName &p_name, Variant &r_ret) const {
if (p_name == "image") {
- r_ret = get_data();
+ r_ret = get_image();
} else if (p_name == "size") {
r_ret = Size2(w, h);
} else {
@@ -200,7 +200,7 @@ void ImageTexture::_resource_path_changed() {
String path = get_path();
}
-Ref<Image> ImageTexture::get_data() const {
+Ref<Image> ImageTexture::get_image() const {
if (image_stored) {
return RenderingServer::get_singleton()->texture_2d_get(texture);
} else {
@@ -251,7 +251,7 @@ void ImageTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons
bool ImageTexture::is_pixel_opaque(int p_x, int p_y) const {
if (!alpha_cache.is_valid()) {
- Ref<Image> img = get_data();
+ Ref<Image> img = get_image();
if (img.is_valid()) {
if (img->is_compressed()) { //must decompress, if compressed
Ref<Image> decom = img->duplicate();
@@ -661,7 +661,7 @@ bool StreamTexture2D::has_alpha() const {
return false;
}
-Ref<Image> StreamTexture2D::get_data() const {
+Ref<Image> StreamTexture2D::get_image() const {
if (texture.is_valid()) {
return RS::get_singleton()->texture_2d_get(texture);
} else {
@@ -671,7 +671,7 @@ Ref<Image> StreamTexture2D::get_data() const {
bool StreamTexture2D::is_pixel_opaque(int p_x, int p_y) const {
if (!alpha_cache.is_valid()) {
- Ref<Image> img = get_data();
+ Ref<Image> img = get_image();
if (img.is_valid()) {
if (img->is_compressed()) { //must decompress, if compressed
Ref<Image> decom = img->duplicate();
@@ -1495,7 +1495,7 @@ Ref<Texture2D> LargeTexture::get_piece_texture(int p_idx) const {
Ref<Image> LargeTexture::to_image() const {
Ref<Image> img = memnew(Image(this->get_width(), this->get_height(), false, Image::FORMAT_RGBA8));
for (int i = 0; i < pieces.size(); i++) {
- Ref<Image> src_img = pieces[i].texture->get_data();
+ Ref<Image> src_img = pieces[i].texture->get_image();
img->blit_rect(src_img, Rect2(0, 0, src_img->get_width(), src_img->get_height()), pieces[i].offset);
}
@@ -1782,7 +1782,7 @@ int GradientTexture::get_width() const {
return width;
}
-Ref<Image> GradientTexture::get_data() const {
+Ref<Image> GradientTexture::get_image() const {
if (!texture.is_valid()) {
return Ref<Image>();
}
@@ -2031,14 +2031,14 @@ bool AnimatedTexture::has_alpha() const {
return frames[current_frame].texture->has_alpha();
}
-Ref<Image> AnimatedTexture::get_data() const {
+Ref<Image> AnimatedTexture::get_image() const {
RWLockRead r(rw_lock);
if (!frames[current_frame].texture.is_valid()) {
return Ref<Image>();
}
- return frames[current_frame].texture->get_data();
+ return frames[current_frame].texture->get_image();
}
bool AnimatedTexture::is_pixel_opaque(int p_x, int p_y) const {
@@ -2543,7 +2543,7 @@ uint32_t CameraTexture::get_flags() const {
return 0;
}
-Ref<Image> CameraTexture::get_data() const {
+Ref<Image> CameraTexture::get_image() const {
// not (yet) supported
return Ref<Image>();
}
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index a0d917fd86..16c98f2891 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -71,7 +71,7 @@ public:
virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, bool p_clip_uv = true) const;
virtual bool get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const;
- virtual Ref<Image> get_data() const { return Ref<Image>(); }
+ virtual Ref<Image> get_image() const { return Ref<Image>(); }
Texture2D();
};
@@ -108,7 +108,7 @@ public:
Image::Format get_format() const;
void update(const Ref<Image> &p_image, bool p_immediate = false);
- Ref<Image> get_data() const override;
+ Ref<Image> get_image() const override;
int get_width() const override;
int get_height() const override;
@@ -203,7 +203,7 @@ public:
virtual bool has_alpha() const override;
bool is_pixel_opaque(int p_x, int p_y) const override;
- virtual Ref<Image> get_data() const override;
+ virtual Ref<Image> get_image() const override;
StreamTexture2D();
~StreamTexture2D();
@@ -716,7 +716,7 @@ public:
virtual int get_height() const override { return 1; }
virtual bool has_alpha() const override { return true; }
- virtual Ref<Image> get_data() const override;
+ virtual Ref<Image> get_image() const override;
GradientTexture();
virtual ~GradientTexture();
@@ -812,7 +812,7 @@ public:
virtual bool has_alpha() const override;
- virtual Ref<Image> get_data() const override;
+ virtual Ref<Image> get_image() const override;
bool is_pixel_opaque(int p_x, int p_y) const override;
@@ -839,7 +839,7 @@ public:
virtual void set_flags(uint32_t p_flags);
virtual uint32_t get_flags() const;
- virtual Ref<Image> get_data() const override;
+ virtual Ref<Image> get_image() const override;
void set_camera_feed_id(int p_new_id);
int get_camera_feed_id() const;
diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp
index 0405ea98bb..036d11574c 100644
--- a/scene/resources/theme.cpp
+++ b/scene/resources/theme.cpp
@@ -141,6 +141,21 @@ Vector<String> Theme::_get_font_size_list(const String &p_node_type) const {
return ilret;
}
+Vector<String> Theme::_get_font_size_type_list() const {
+ Vector<String> ilret;
+ List<StringName> il;
+
+ get_font_size_type_list(&il);
+ ilret.resize(il.size());
+
+ int i = 0;
+ String *w = ilret.ptrw();
+ for (List<StringName>::Element *E = il.front(); E; E = E->next(), i++) {
+ w[i] = E->get();
+ }
+ return ilret;
+}
+
Vector<String> Theme::_get_color_list(const String &p_node_type) const {
Vector<String> ilret;
List<StringName> il;
@@ -201,6 +216,48 @@ Vector<String> Theme::_get_constant_type_list() const {
return ilret;
}
+Vector<String> Theme::_get_theme_item_list(DataType p_data_type, const String &p_node_type) const {
+ switch (p_data_type) {
+ case DATA_TYPE_COLOR:
+ return _get_color_list(p_node_type);
+ case DATA_TYPE_CONSTANT:
+ return _get_constant_list(p_node_type);
+ case DATA_TYPE_FONT:
+ return _get_font_list(p_node_type);
+ case DATA_TYPE_FONT_SIZE:
+ return _get_font_size_list(p_node_type);
+ case DATA_TYPE_ICON:
+ return _get_icon_list(p_node_type);
+ case DATA_TYPE_STYLEBOX:
+ return _get_stylebox_list(p_node_type);
+ case DATA_TYPE_MAX:
+ break; // Can't happen, but silences warning.
+ }
+
+ return Vector<String>();
+}
+
+Vector<String> Theme::_get_theme_item_type_list(DataType p_data_type) const {
+ switch (p_data_type) {
+ case DATA_TYPE_COLOR:
+ return _get_color_type_list();
+ case DATA_TYPE_CONSTANT:
+ return _get_constant_type_list();
+ case DATA_TYPE_FONT:
+ return _get_font_type_list();
+ case DATA_TYPE_FONT_SIZE:
+ return _get_font_size_type_list();
+ case DATA_TYPE_ICON:
+ return _get_icon_type_list();
+ case DATA_TYPE_STYLEBOX:
+ return _get_stylebox_type_list();
+ case DATA_TYPE_MAX:
+ break; // Can't happen, but silences warning.
+ }
+
+ return Vector<String>();
+}
+
Vector<String> Theme::_get_type_list() const {
Vector<String> ilret;
List<StringName> il;
@@ -421,8 +478,6 @@ void Theme::set_default_font_size(int p_font_size) {
}
void Theme::set_icon(const StringName &p_name, const StringName &p_node_type, const Ref<Texture2D> &p_icon) {
- //ERR_FAIL_COND(p_icon.is_null());
-
bool new_value = !icon_map.has(p_node_type) || !icon_map[p_node_type].has(p_name);
if (icon_map[p_node_type].has(p_name) && icon_map[p_node_type][p_name].is_valid()) {
@@ -453,9 +508,21 @@ bool Theme::has_icon(const StringName &p_name, const StringName &p_node_type) co
return (icon_map.has(p_node_type) && icon_map[p_node_type].has(p_name) && icon_map[p_node_type][p_name].is_valid());
}
+void Theme::rename_icon(const StringName &p_old_name, const StringName &p_name, const StringName &p_node_type) {
+ ERR_FAIL_COND_MSG(!icon_map.has(p_node_type), "Cannot rename the icon '" + String(p_old_name) + "' because the node type '" + String(p_node_type) + "' does not exist.");
+ ERR_FAIL_COND_MSG(icon_map[p_node_type].has(p_name), "Cannot rename the icon '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists.");
+ ERR_FAIL_COND_MSG(!icon_map[p_node_type].has(p_old_name), "Cannot rename the icon '" + String(p_old_name) + "' because it does not exist.");
+
+ icon_map[p_node_type][p_name] = icon_map[p_node_type][p_old_name];
+ icon_map[p_node_type].erase(p_old_name);
+
+ notify_property_list_changed();
+ emit_changed();
+}
+
void Theme::clear_icon(const StringName &p_name, const StringName &p_node_type) {
- ERR_FAIL_COND(!icon_map.has(p_node_type));
- ERR_FAIL_COND(!icon_map[p_node_type].has(p_name));
+ ERR_FAIL_COND_MSG(!icon_map.has(p_node_type), "Cannot clear the icon '" + String(p_name) + "' because the node type '" + String(p_node_type) + "' does not exist.");
+ ERR_FAIL_COND_MSG(!icon_map[p_node_type].has(p_name), "Cannot clear the icon '" + String(p_name) + "' because it does not exist.");
if (icon_map[p_node_type][p_name].is_valid()) {
icon_map[p_node_type][p_name]->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed));
@@ -481,6 +548,10 @@ void Theme::get_icon_list(StringName p_node_type, List<StringName> *p_list) cons
}
}
+void Theme::add_icon_type(const StringName &p_node_type) {
+ icon_map[p_node_type] = HashMap<StringName, Ref<Texture2D>>();
+}
+
void Theme::get_icon_type_list(List<StringName> *p_list) const {
ERR_FAIL_NULL(p_list);
@@ -491,8 +562,6 @@ void Theme::get_icon_type_list(List<StringName> *p_list) const {
}
void Theme::set_stylebox(const StringName &p_name, const StringName &p_node_type, const Ref<StyleBox> &p_style) {
- //ERR_FAIL_COND(p_style.is_null());
-
bool new_value = !style_map.has(p_node_type) || !style_map[p_node_type].has(p_name);
if (style_map[p_node_type].has(p_name) && style_map[p_node_type][p_name].is_valid()) {
@@ -523,9 +592,21 @@ bool Theme::has_stylebox(const StringName &p_name, const StringName &p_node_type
return (style_map.has(p_node_type) && style_map[p_node_type].has(p_name) && style_map[p_node_type][p_name].is_valid());
}
+void Theme::rename_stylebox(const StringName &p_old_name, const StringName &p_name, const StringName &p_node_type) {
+ ERR_FAIL_COND_MSG(!style_map.has(p_node_type), "Cannot rename the stylebox '" + String(p_old_name) + "' because the node type '" + String(p_node_type) + "' does not exist.");
+ ERR_FAIL_COND_MSG(style_map[p_node_type].has(p_name), "Cannot rename the stylebox '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists.");
+ ERR_FAIL_COND_MSG(!style_map[p_node_type].has(p_old_name), "Cannot rename the stylebox '" + String(p_old_name) + "' because it does not exist.");
+
+ style_map[p_node_type][p_name] = style_map[p_node_type][p_old_name];
+ style_map[p_node_type].erase(p_old_name);
+
+ notify_property_list_changed();
+ emit_changed();
+}
+
void Theme::clear_stylebox(const StringName &p_name, const StringName &p_node_type) {
- ERR_FAIL_COND(!style_map.has(p_node_type));
- ERR_FAIL_COND(!style_map[p_node_type].has(p_name));
+ ERR_FAIL_COND_MSG(!style_map.has(p_node_type), "Cannot clear the stylebox '" + String(p_name) + "' because the node type '" + String(p_node_type) + "' does not exist.");
+ ERR_FAIL_COND_MSG(!style_map[p_node_type].has(p_name), "Cannot clear the stylebox '" + String(p_name) + "' because it does not exist.");
if (style_map[p_node_type][p_name].is_valid()) {
style_map[p_node_type][p_name]->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed));
@@ -551,6 +632,10 @@ void Theme::get_stylebox_list(StringName p_node_type, List<StringName> *p_list)
}
}
+void Theme::add_stylebox_type(const StringName &p_node_type) {
+ style_map[p_node_type] = HashMap<StringName, Ref<StyleBox>>();
+}
+
void Theme::get_stylebox_type_list(List<StringName> *p_list) const {
ERR_FAIL_NULL(p_list);
@@ -561,8 +646,6 @@ void Theme::get_stylebox_type_list(List<StringName> *p_list) const {
}
void Theme::set_font(const StringName &p_name, const StringName &p_node_type, const Ref<Font> &p_font) {
- //ERR_FAIL_COND(p_font.is_null());
-
bool new_value = !font_map.has(p_node_type) || !font_map[p_node_type].has(p_name);
if (font_map[p_node_type][p_name].is_valid()) {
@@ -595,9 +678,21 @@ bool Theme::has_font(const StringName &p_name, const StringName &p_node_type) co
return ((font_map.has(p_node_type) && font_map[p_node_type].has(p_name) && font_map[p_node_type][p_name].is_valid()) || default_theme_font.is_valid());
}
+void Theme::rename_font(const StringName &p_old_name, const StringName &p_name, const StringName &p_node_type) {
+ ERR_FAIL_COND_MSG(!font_map.has(p_node_type), "Cannot rename the font '" + String(p_old_name) + "' because the node type '" + String(p_node_type) + "' does not exist.");
+ ERR_FAIL_COND_MSG(font_map[p_node_type].has(p_name), "Cannot rename the font '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists.");
+ ERR_FAIL_COND_MSG(!font_map[p_node_type].has(p_old_name), "Cannot rename the font '" + String(p_old_name) + "' because it does not exist.");
+
+ font_map[p_node_type][p_name] = font_map[p_node_type][p_old_name];
+ font_map[p_node_type].erase(p_old_name);
+
+ notify_property_list_changed();
+ emit_changed();
+}
+
void Theme::clear_font(const StringName &p_name, const StringName &p_node_type) {
- ERR_FAIL_COND(!font_map.has(p_node_type));
- ERR_FAIL_COND(!font_map[p_node_type].has(p_name));
+ ERR_FAIL_COND_MSG(!font_map.has(p_node_type), "Cannot clear the font '" + String(p_name) + "' because the node type '" + String(p_node_type) + "' does not exist.");
+ ERR_FAIL_COND_MSG(!font_map[p_node_type].has(p_name), "Cannot clear the font '" + String(p_name) + "' because it does not exist.");
if (font_map[p_node_type][p_name].is_valid()) {
font_map[p_node_type][p_name]->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed));
@@ -622,6 +717,10 @@ void Theme::get_font_list(StringName p_node_type, List<StringName> *p_list) cons
}
}
+void Theme::add_font_type(const StringName &p_node_type) {
+ font_map[p_node_type] = HashMap<StringName, Ref<Font>>();
+}
+
void Theme::get_font_type_list(List<StringName> *p_list) const {
ERR_FAIL_NULL(p_list);
@@ -656,9 +755,21 @@ bool Theme::has_font_size(const StringName &p_name, const StringName &p_node_typ
return ((font_size_map.has(p_node_type) && font_size_map[p_node_type].has(p_name) && (font_size_map[p_node_type][p_name] > 0)) || (default_theme_font_size > 0));
}
+void Theme::rename_font_size(const StringName &p_old_name, const StringName &p_name, const StringName &p_node_type) {
+ ERR_FAIL_COND_MSG(!font_size_map.has(p_node_type), "Cannot rename the font size '" + String(p_old_name) + "' because the node type '" + String(p_node_type) + "' does not exist.");
+ ERR_FAIL_COND_MSG(font_size_map[p_node_type].has(p_name), "Cannot rename the font size '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists.");
+ ERR_FAIL_COND_MSG(!font_size_map[p_node_type].has(p_old_name), "Cannot rename the font size '" + String(p_old_name) + "' because it does not exist.");
+
+ font_size_map[p_node_type][p_name] = font_size_map[p_node_type][p_old_name];
+ font_size_map[p_node_type].erase(p_old_name);
+
+ notify_property_list_changed();
+ emit_changed();
+}
+
void Theme::clear_font_size(const StringName &p_name, const StringName &p_node_type) {
- ERR_FAIL_COND(!font_size_map.has(p_node_type));
- ERR_FAIL_COND(!font_size_map[p_node_type].has(p_name));
+ ERR_FAIL_COND_MSG(!font_size_map.has(p_node_type), "Cannot clear the font size '" + String(p_name) + "' because the node type '" + String(p_node_type) + "' does not exist.");
+ ERR_FAIL_COND_MSG(!font_size_map[p_node_type].has(p_name), "Cannot clear the font size '" + String(p_name) + "' because it does not exist.");
font_size_map[p_node_type].erase(p_name);
notify_property_list_changed();
@@ -679,6 +790,19 @@ void Theme::get_font_size_list(StringName p_node_type, List<StringName> *p_list)
}
}
+void Theme::add_font_size_type(const StringName &p_node_type) {
+ font_size_map[p_node_type] = HashMap<StringName, int>();
+}
+
+void Theme::get_font_size_type_list(List<StringName> *p_list) const {
+ ERR_FAIL_NULL(p_list);
+
+ const StringName *key = nullptr;
+ while ((key = font_size_map.next(key))) {
+ p_list->push_back(*key);
+ }
+}
+
void Theme::set_color(const StringName &p_name, const StringName &p_node_type, const Color &p_color) {
bool new_value = !color_map.has(p_node_type) || !color_map[p_node_type].has(p_name);
@@ -702,9 +826,21 @@ bool Theme::has_color(const StringName &p_name, const StringName &p_node_type) c
return (color_map.has(p_node_type) && color_map[p_node_type].has(p_name));
}
+void Theme::rename_color(const StringName &p_old_name, const StringName &p_name, const StringName &p_node_type) {
+ ERR_FAIL_COND_MSG(!color_map.has(p_node_type), "Cannot rename the color '" + String(p_old_name) + "' because the node type '" + String(p_node_type) + "' does not exist.");
+ ERR_FAIL_COND_MSG(color_map[p_node_type].has(p_name), "Cannot rename the color '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists.");
+ ERR_FAIL_COND_MSG(!color_map[p_node_type].has(p_old_name), "Cannot rename the color '" + String(p_old_name) + "' because it does not exist.");
+
+ color_map[p_node_type][p_name] = color_map[p_node_type][p_old_name];
+ color_map[p_node_type].erase(p_old_name);
+
+ notify_property_list_changed();
+ emit_changed();
+}
+
void Theme::clear_color(const StringName &p_name, const StringName &p_node_type) {
- ERR_FAIL_COND(!color_map.has(p_node_type));
- ERR_FAIL_COND(!color_map[p_node_type].has(p_name));
+ ERR_FAIL_COND_MSG(!color_map.has(p_node_type), "Cannot clear the color '" + String(p_name) + "' because the node type '" + String(p_node_type) + "' does not exist.");
+ ERR_FAIL_COND_MSG(!color_map[p_node_type].has(p_name), "Cannot clear the color '" + String(p_name) + "' because it does not exist.");
color_map[p_node_type].erase(p_name);
notify_property_list_changed();
@@ -725,6 +861,10 @@ void Theme::get_color_list(StringName p_node_type, List<StringName> *p_list) con
}
}
+void Theme::add_color_type(const StringName &p_node_type) {
+ color_map[p_node_type] = HashMap<StringName, Color>();
+}
+
void Theme::get_color_type_list(List<StringName> *p_list) const {
ERR_FAIL_NULL(p_list);
@@ -756,9 +896,21 @@ bool Theme::has_constant(const StringName &p_name, const StringName &p_node_type
return (constant_map.has(p_node_type) && constant_map[p_node_type].has(p_name));
}
+void Theme::rename_constant(const StringName &p_old_name, const StringName &p_name, const StringName &p_node_type) {
+ ERR_FAIL_COND_MSG(!constant_map.has(p_node_type), "Cannot rename the constant '" + String(p_old_name) + "' because the node type '" + String(p_node_type) + "' does not exist.");
+ ERR_FAIL_COND_MSG(constant_map[p_node_type].has(p_name), "Cannot rename the constant '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists.");
+ ERR_FAIL_COND_MSG(!constant_map[p_node_type].has(p_old_name), "Cannot rename the constant '" + String(p_old_name) + "' because it does not exist.");
+
+ constant_map[p_node_type][p_name] = constant_map[p_node_type][p_old_name];
+ constant_map[p_node_type].erase(p_old_name);
+
+ notify_property_list_changed();
+ emit_changed();
+}
+
void Theme::clear_constant(const StringName &p_name, const StringName &p_node_type) {
- ERR_FAIL_COND(!constant_map.has(p_node_type));
- ERR_FAIL_COND(!constant_map[p_node_type].has(p_name));
+ ERR_FAIL_COND_MSG(!constant_map.has(p_node_type), "Cannot clear the constant '" + String(p_name) + "' because the node type '" + String(p_node_type) + "' does not exist.");
+ ERR_FAIL_COND_MSG(!constant_map[p_node_type].has(p_name), "Cannot clear the constant '" + String(p_name) + "' because it does not exist.");
constant_map[p_node_type].erase(p_name);
notify_property_list_changed();
@@ -779,6 +931,10 @@ void Theme::get_constant_list(StringName p_node_type, List<StringName> *p_list)
}
}
+void Theme::add_constant_type(const StringName &p_node_type) {
+ constant_map[p_node_type] = HashMap<StringName, int>();
+}
+
void Theme::get_constant_type_list(List<StringName> *p_list) const {
ERR_FAIL_NULL(p_list);
@@ -788,6 +944,216 @@ void Theme::get_constant_type_list(List<StringName> *p_list) const {
}
}
+void Theme::set_theme_item(DataType p_data_type, const StringName &p_name, const StringName &p_node_type, const Variant &p_value) {
+ switch (p_data_type) {
+ case DATA_TYPE_COLOR: {
+ ERR_FAIL_COND_MSG(p_value.get_type() != Variant::COLOR, "Theme item's data type (Color) does not match Variant's type (" + Variant::get_type_name(p_value.get_type()) + ").");
+
+ Color color_value = p_value;
+ set_color(p_name, p_node_type, color_value);
+ } break;
+ case DATA_TYPE_CONSTANT: {
+ ERR_FAIL_COND_MSG(p_value.get_type() != Variant::INT, "Theme item's data type (int) does not match Variant's type (" + Variant::get_type_name(p_value.get_type()) + ").");
+
+ int constant_value = p_value;
+ set_constant(p_name, p_node_type, constant_value);
+ } break;
+ case DATA_TYPE_FONT: {
+ ERR_FAIL_COND_MSG(p_value.get_type() != Variant::OBJECT, "Theme item's data type (Object) does not match Variant's type (" + Variant::get_type_name(p_value.get_type()) + ").");
+
+ Ref<Font> font_value = Object::cast_to<Font>(p_value.get_validated_object());
+ set_font(p_name, p_node_type, font_value);
+ } break;
+ case DATA_TYPE_FONT_SIZE: {
+ ERR_FAIL_COND_MSG(p_value.get_type() != Variant::INT, "Theme item's data type (int) does not match Variant's type (" + Variant::get_type_name(p_value.get_type()) + ").");
+
+ int font_size_value = p_value;
+ set_font_size(p_name, p_node_type, font_size_value);
+ } break;
+ case DATA_TYPE_ICON: {
+ ERR_FAIL_COND_MSG(p_value.get_type() != Variant::OBJECT, "Theme item's data type (Object) does not match Variant's type (" + Variant::get_type_name(p_value.get_type()) + ").");
+
+ Ref<Texture2D> icon_value = Object::cast_to<Texture2D>(p_value.get_validated_object());
+ set_icon(p_name, p_node_type, icon_value);
+ } break;
+ case DATA_TYPE_STYLEBOX: {
+ ERR_FAIL_COND_MSG(p_value.get_type() != Variant::OBJECT, "Theme item's data type (Object) does not match Variant's type (" + Variant::get_type_name(p_value.get_type()) + ").");
+
+ Ref<StyleBox> stylebox_value = Object::cast_to<StyleBox>(p_value.get_validated_object());
+ set_stylebox(p_name, p_node_type, stylebox_value);
+ } break;
+ case DATA_TYPE_MAX:
+ break; // Can't happen, but silences warning.
+ }
+}
+
+Variant Theme::get_theme_item(DataType p_data_type, const StringName &p_name, const StringName &p_node_type) const {
+ switch (p_data_type) {
+ case DATA_TYPE_COLOR:
+ return get_color(p_name, p_node_type);
+ case DATA_TYPE_CONSTANT:
+ return get_constant(p_name, p_node_type);
+ case DATA_TYPE_FONT:
+ return get_font(p_name, p_node_type);
+ case DATA_TYPE_FONT_SIZE:
+ return get_font_size(p_name, p_node_type);
+ case DATA_TYPE_ICON:
+ return get_icon(p_name, p_node_type);
+ case DATA_TYPE_STYLEBOX:
+ return get_stylebox(p_name, p_node_type);
+ case DATA_TYPE_MAX:
+ break; // Can't happen, but silences warning.
+ }
+
+ return Variant();
+}
+
+bool Theme::has_theme_item(DataType p_data_type, const StringName &p_name, const StringName &p_node_type) const {
+ switch (p_data_type) {
+ case DATA_TYPE_COLOR:
+ return has_color(p_name, p_node_type);
+ case DATA_TYPE_CONSTANT:
+ return has_constant(p_name, p_node_type);
+ case DATA_TYPE_FONT:
+ return has_font(p_name, p_node_type);
+ case DATA_TYPE_FONT_SIZE:
+ return has_font_size(p_name, p_node_type);
+ case DATA_TYPE_ICON:
+ return has_icon(p_name, p_node_type);
+ case DATA_TYPE_STYLEBOX:
+ return has_stylebox(p_name, p_node_type);
+ case DATA_TYPE_MAX:
+ break; // Can't happen, but silences warning.
+ }
+
+ return false;
+}
+
+void Theme::rename_theme_item(DataType p_data_type, const StringName &p_old_name, const StringName &p_name, const StringName &p_node_type) {
+ switch (p_data_type) {
+ case DATA_TYPE_COLOR:
+ rename_color(p_old_name, p_name, p_node_type);
+ break;
+ case DATA_TYPE_CONSTANT:
+ rename_constant(p_old_name, p_name, p_node_type);
+ break;
+ case DATA_TYPE_FONT:
+ rename_font(p_old_name, p_name, p_node_type);
+ break;
+ case DATA_TYPE_FONT_SIZE:
+ rename_font_size(p_old_name, p_name, p_node_type);
+ break;
+ case DATA_TYPE_ICON:
+ rename_icon(p_old_name, p_name, p_node_type);
+ break;
+ case DATA_TYPE_STYLEBOX:
+ rename_stylebox(p_old_name, p_name, p_node_type);
+ break;
+ case DATA_TYPE_MAX:
+ break; // Can't happen, but silences warning.
+ }
+}
+
+void Theme::clear_theme_item(DataType p_data_type, const StringName &p_name, const StringName &p_node_type) {
+ switch (p_data_type) {
+ case DATA_TYPE_COLOR:
+ clear_color(p_name, p_node_type);
+ break;
+ case DATA_TYPE_CONSTANT:
+ clear_constant(p_name, p_node_type);
+ break;
+ case DATA_TYPE_FONT:
+ clear_font(p_name, p_node_type);
+ break;
+ case DATA_TYPE_FONT_SIZE:
+ clear_font_size(p_name, p_node_type);
+ break;
+ case DATA_TYPE_ICON:
+ clear_icon(p_name, p_node_type);
+ break;
+ case DATA_TYPE_STYLEBOX:
+ clear_stylebox(p_name, p_node_type);
+ break;
+ case DATA_TYPE_MAX:
+ break; // Can't happen, but silences warning.
+ }
+}
+
+void Theme::get_theme_item_list(DataType p_data_type, StringName p_node_type, List<StringName> *p_list) const {
+ switch (p_data_type) {
+ case DATA_TYPE_COLOR:
+ get_color_list(p_node_type, p_list);
+ break;
+ case DATA_TYPE_CONSTANT:
+ get_constant_list(p_node_type, p_list);
+ break;
+ case DATA_TYPE_FONT:
+ get_font_list(p_node_type, p_list);
+ break;
+ case DATA_TYPE_FONT_SIZE:
+ get_font_size_list(p_node_type, p_list);
+ break;
+ case DATA_TYPE_ICON:
+ get_icon_list(p_node_type, p_list);
+ break;
+ case DATA_TYPE_STYLEBOX:
+ get_stylebox_list(p_node_type, p_list);
+ break;
+ case DATA_TYPE_MAX:
+ break; // Can't happen, but silences warning.
+ }
+}
+
+void Theme::add_theme_item_type(DataType p_data_type, const StringName &p_node_type) {
+ switch (p_data_type) {
+ case DATA_TYPE_COLOR:
+ add_color_type(p_node_type);
+ break;
+ case DATA_TYPE_CONSTANT:
+ add_constant_type(p_node_type);
+ break;
+ case DATA_TYPE_FONT:
+ add_font_type(p_node_type);
+ break;
+ case DATA_TYPE_FONT_SIZE:
+ add_font_size_type(p_node_type);
+ break;
+ case DATA_TYPE_ICON:
+ add_icon_type(p_node_type);
+ break;
+ case DATA_TYPE_STYLEBOX:
+ add_stylebox_type(p_node_type);
+ break;
+ case DATA_TYPE_MAX:
+ break; // Can't happen, but silences warning.
+ }
+}
+
+void Theme::get_theme_item_type_list(DataType p_data_type, List<StringName> *p_list) const {
+ switch (p_data_type) {
+ case DATA_TYPE_COLOR:
+ get_color_type_list(p_list);
+ break;
+ case DATA_TYPE_CONSTANT:
+ get_constant_type_list(p_list);
+ break;
+ case DATA_TYPE_FONT:
+ get_font_type_list(p_list);
+ break;
+ case DATA_TYPE_FONT_SIZE:
+ get_font_size_type_list(p_list);
+ break;
+ case DATA_TYPE_ICON:
+ get_icon_type_list(p_list);
+ break;
+ case DATA_TYPE_STYLEBOX:
+ get_stylebox_type_list(p_list);
+ break;
+ case DATA_TYPE_MAX:
+ break; // Can't happen, but silences warning.
+ }
+}
+
void Theme::clear() {
//these need disconnecting
{
@@ -847,11 +1213,10 @@ void Theme::copy_default_theme() {
void Theme::copy_theme(const Ref<Theme> &p_other) {
if (p_other.is_null()) {
clear();
-
return;
}
- //these need reconnecting, so add normally
+ // These items need reconnecting, so add them normally.
{
const StringName *K = nullptr;
while ((K = p_other->icon_map.next(K))) {
@@ -882,8 +1247,8 @@ void Theme::copy_theme(const Ref<Theme> &p_other) {
}
}
- //these are ok to just copy
-
+ // These items can be simply copied.
+ font_size_map = p_other->font_size_map;
color_map = p_other->color_map;
constant_map = p_other->constant_map;
@@ -937,6 +1302,7 @@ void Theme::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_icon", "name", "node_type", "texture"), &Theme::set_icon);
ClassDB::bind_method(D_METHOD("get_icon", "name", "node_type"), &Theme::get_icon);
ClassDB::bind_method(D_METHOD("has_icon", "name", "node_type"), &Theme::has_icon);
+ ClassDB::bind_method(D_METHOD("rename_icon", "old_name", "name", "node_type"), &Theme::rename_icon);
ClassDB::bind_method(D_METHOD("clear_icon", "name", "node_type"), &Theme::clear_icon);
ClassDB::bind_method(D_METHOD("get_icon_list", "node_type"), &Theme::_get_icon_list);
ClassDB::bind_method(D_METHOD("get_icon_type_list"), &Theme::_get_icon_type_list);
@@ -944,6 +1310,7 @@ void Theme::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_stylebox", "name", "node_type", "texture"), &Theme::set_stylebox);
ClassDB::bind_method(D_METHOD("get_stylebox", "name", "node_type"), &Theme::get_stylebox);
ClassDB::bind_method(D_METHOD("has_stylebox", "name", "node_type"), &Theme::has_stylebox);
+ ClassDB::bind_method(D_METHOD("rename_stylebox", "old_name", "name", "node_type"), &Theme::rename_stylebox);
ClassDB::bind_method(D_METHOD("clear_stylebox", "name", "node_type"), &Theme::clear_stylebox);
ClassDB::bind_method(D_METHOD("get_stylebox_list", "node_type"), &Theme::_get_stylebox_list);
ClassDB::bind_method(D_METHOD("get_stylebox_type_list"), &Theme::_get_stylebox_type_list);
@@ -951,6 +1318,7 @@ void Theme::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_font", "name", "node_type", "font"), &Theme::set_font);
ClassDB::bind_method(D_METHOD("get_font", "name", "node_type"), &Theme::get_font);
ClassDB::bind_method(D_METHOD("has_font", "name", "node_type"), &Theme::has_font);
+ ClassDB::bind_method(D_METHOD("rename_font", "old_name", "name", "node_type"), &Theme::rename_font);
ClassDB::bind_method(D_METHOD("clear_font", "name", "node_type"), &Theme::clear_font);
ClassDB::bind_method(D_METHOD("get_font_list", "node_type"), &Theme::_get_font_list);
ClassDB::bind_method(D_METHOD("get_font_type_list"), &Theme::_get_font_type_list);
@@ -958,12 +1326,15 @@ void Theme::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_font_size", "name", "node_type", "font_size"), &Theme::set_font_size);
ClassDB::bind_method(D_METHOD("get_font_size", "name", "node_type"), &Theme::get_font_size);
ClassDB::bind_method(D_METHOD("has_font_size", "name", "node_type"), &Theme::has_font_size);
+ ClassDB::bind_method(D_METHOD("rename_font_size", "old_name", "name", "node_type"), &Theme::rename_font_size);
ClassDB::bind_method(D_METHOD("clear_font_size", "name", "node_type"), &Theme::clear_font_size);
ClassDB::bind_method(D_METHOD("get_font_size_list", "node_type"), &Theme::_get_font_size_list);
+ ClassDB::bind_method(D_METHOD("get_font_size_type_list"), &Theme::_get_font_size_type_list);
ClassDB::bind_method(D_METHOD("set_color", "name", "node_type", "color"), &Theme::set_color);
ClassDB::bind_method(D_METHOD("get_color", "name", "node_type"), &Theme::get_color);
ClassDB::bind_method(D_METHOD("has_color", "name", "node_type"), &Theme::has_color);
+ ClassDB::bind_method(D_METHOD("rename_color", "old_name", "name", "node_type"), &Theme::rename_color);
ClassDB::bind_method(D_METHOD("clear_color", "name", "node_type"), &Theme::clear_color);
ClassDB::bind_method(D_METHOD("get_color_list", "node_type"), &Theme::_get_color_list);
ClassDB::bind_method(D_METHOD("get_color_type_list"), &Theme::_get_color_type_list);
@@ -971,6 +1342,7 @@ void Theme::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_constant", "name", "node_type", "constant"), &Theme::set_constant);
ClassDB::bind_method(D_METHOD("get_constant", "name", "node_type"), &Theme::get_constant);
ClassDB::bind_method(D_METHOD("has_constant", "name", "node_type"), &Theme::has_constant);
+ ClassDB::bind_method(D_METHOD("rename_constant", "old_name", "name", "node_type"), &Theme::rename_constant);
ClassDB::bind_method(D_METHOD("clear_constant", "name", "node_type"), &Theme::clear_constant);
ClassDB::bind_method(D_METHOD("get_constant_list", "node_type"), &Theme::_get_constant_list);
ClassDB::bind_method(D_METHOD("get_constant_type_list"), &Theme::_get_constant_type_list);
@@ -983,6 +1355,14 @@ void Theme::_bind_methods() {
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("set_theme_item", "data_type", "name", "node_type", "value"), &Theme::set_theme_item);
+ ClassDB::bind_method(D_METHOD("get_theme_item", "data_type", "name", "node_type"), &Theme::get_theme_item);
+ ClassDB::bind_method(D_METHOD("has_theme_item", "data_type", "name", "node_type"), &Theme::has_theme_item);
+ ClassDB::bind_method(D_METHOD("rename_theme_item", "data_type", "old_name", "name", "node_type"), &Theme::rename_theme_item);
+ ClassDB::bind_method(D_METHOD("clear_theme_item", "data_type", "name", "node_type"), &Theme::clear_theme_item);
+ ClassDB::bind_method(D_METHOD("get_theme_item_list", "data_type", "node_type"), &Theme::_get_theme_item_list);
+ ClassDB::bind_method(D_METHOD("get_theme_item_type_list", "data_type"), &Theme::_get_theme_item_type_list);
+
ClassDB::bind_method(D_METHOD("get_type_list"), &Theme::_get_type_list);
ClassDB::bind_method("copy_default_theme", &Theme::copy_default_theme);
@@ -990,6 +1370,14 @@ void Theme::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "default_font", PROPERTY_HINT_RESOURCE_TYPE, "Font"), "set_default_font", "get_default_font");
ADD_PROPERTY(PropertyInfo(Variant::INT, "default_font_size"), "set_default_font_size", "get_default_font_size");
+
+ BIND_ENUM_CONSTANT(DATA_TYPE_COLOR);
+ BIND_ENUM_CONSTANT(DATA_TYPE_CONSTANT);
+ BIND_ENUM_CONSTANT(DATA_TYPE_FONT);
+ BIND_ENUM_CONSTANT(DATA_TYPE_FONT_SIZE);
+ BIND_ENUM_CONSTANT(DATA_TYPE_ICON);
+ BIND_ENUM_CONSTANT(DATA_TYPE_STYLEBOX);
+ BIND_ENUM_CONSTANT(DATA_TYPE_MAX);
}
Theme::Theme() {
diff --git a/scene/resources/theme.h b/scene/resources/theme.h
index 35481126ea..eb918fac69 100644
--- a/scene/resources/theme.h
+++ b/scene/resources/theme.h
@@ -41,6 +41,18 @@ class Theme : public Resource {
GDCLASS(Theme, Resource);
RES_BASE_EXTENSION("theme");
+public:
+ enum DataType {
+ DATA_TYPE_COLOR,
+ DATA_TYPE_CONSTANT,
+ DATA_TYPE_FONT,
+ DATA_TYPE_FONT_SIZE,
+ DATA_TYPE_ICON,
+ DATA_TYPE_STYLEBOX,
+ DATA_TYPE_MAX
+ };
+
+private:
void _emit_theme_changed();
HashMap<StringName, HashMap<StringName, Ref<Texture2D>>> icon_map;
@@ -57,10 +69,14 @@ class Theme : public Resource {
Vector<String> _get_font_list(const String &p_node_type) const;
Vector<String> _get_font_type_list() const;
Vector<String> _get_font_size_list(const String &p_node_type) const;
+ Vector<String> _get_font_size_type_list() const;
Vector<String> _get_color_list(const String &p_node_type) const;
Vector<String> _get_color_type_list() const;
Vector<String> _get_constant_list(const String &p_node_type) const;
Vector<String> _get_constant_type_list() const;
+
+ Vector<String> _get_theme_item_list(DataType p_data_type, const String &p_node_type) const;
+ Vector<String> _get_theme_item_type_list(DataType p_data_type) const;
Vector<String> _get_type_list() const;
protected:
@@ -103,44 +119,66 @@ public:
void set_icon(const StringName &p_name, const StringName &p_node_type, const Ref<Texture2D> &p_icon);
Ref<Texture2D> get_icon(const StringName &p_name, const StringName &p_node_type) const;
bool has_icon(const StringName &p_name, const StringName &p_node_type) const;
+ void rename_icon(const StringName &p_old_name, const StringName &p_name, const StringName &p_node_type);
void clear_icon(const StringName &p_name, const StringName &p_node_type);
void get_icon_list(StringName p_node_type, List<StringName> *p_list) const;
+ void add_icon_type(const StringName &p_node_type);
void get_icon_type_list(List<StringName> *p_list) const;
void set_stylebox(const StringName &p_name, const StringName &p_node_type, const Ref<StyleBox> &p_style);
Ref<StyleBox> get_stylebox(const StringName &p_name, const StringName &p_node_type) const;
bool has_stylebox(const StringName &p_name, const StringName &p_node_type) const;
+ void rename_stylebox(const StringName &p_old_name, const StringName &p_name, const StringName &p_node_type);
void clear_stylebox(const StringName &p_name, const StringName &p_node_type);
void get_stylebox_list(StringName p_node_type, List<StringName> *p_list) const;
+ void add_stylebox_type(const StringName &p_node_type);
void get_stylebox_type_list(List<StringName> *p_list) const;
void set_font(const StringName &p_name, const StringName &p_node_type, const Ref<Font> &p_font);
Ref<Font> get_font(const StringName &p_name, const StringName &p_node_type) const;
bool has_font(const StringName &p_name, const StringName &p_node_type) const;
+ void rename_font(const StringName &p_old_name, const StringName &p_name, const StringName &p_node_type);
void clear_font(const StringName &p_name, const StringName &p_node_type);
void get_font_list(StringName p_node_type, List<StringName> *p_list) const;
+ void add_font_type(const StringName &p_node_type);
void get_font_type_list(List<StringName> *p_list) const;
void set_font_size(const StringName &p_name, const StringName &p_node_type, int p_font_size);
int get_font_size(const StringName &p_name, const StringName &p_node_type) const;
bool has_font_size(const StringName &p_name, const StringName &p_node_type) const;
+ void rename_font_size(const StringName &p_old_name, const StringName &p_name, const StringName &p_node_type);
void clear_font_size(const StringName &p_name, const StringName &p_node_type);
void get_font_size_list(StringName p_node_type, List<StringName> *p_list) const;
+ void add_font_size_type(const StringName &p_node_type);
+ void get_font_size_type_list(List<StringName> *p_list) const;
void set_color(const StringName &p_name, const StringName &p_node_type, const Color &p_color);
Color get_color(const StringName &p_name, const StringName &p_node_type) const;
bool has_color(const StringName &p_name, const StringName &p_node_type) const;
+ void rename_color(const StringName &p_old_name, const StringName &p_name, const StringName &p_node_type);
void clear_color(const StringName &p_name, const StringName &p_node_type);
void get_color_list(StringName p_node_type, List<StringName> *p_list) const;
+ void add_color_type(const StringName &p_node_type);
void get_color_type_list(List<StringName> *p_list) const;
void set_constant(const StringName &p_name, const StringName &p_node_type, int p_constant);
int get_constant(const StringName &p_name, const StringName &p_node_type) const;
bool has_constant(const StringName &p_name, const StringName &p_node_type) const;
+ void rename_constant(const StringName &p_old_name, const StringName &p_name, const StringName &p_node_type);
void clear_constant(const StringName &p_name, const StringName &p_node_type);
void get_constant_list(StringName p_node_type, List<StringName> *p_list) const;
+ void add_constant_type(const StringName &p_node_type);
void get_constant_type_list(List<StringName> *p_list) const;
+ void set_theme_item(DataType p_data_type, const StringName &p_name, const StringName &p_node_type, const Variant &p_value);
+ Variant get_theme_item(DataType p_data_type, const StringName &p_name, const StringName &p_node_type) const;
+ bool has_theme_item(DataType p_data_type, const StringName &p_name, const StringName &p_node_type) const;
+ void rename_theme_item(DataType p_data_type, const StringName &p_old_name, const StringName &p_name, const StringName &p_node_type);
+ void clear_theme_item(DataType p_data_type, const StringName &p_name, const StringName &p_node_type);
+ void get_theme_item_list(DataType p_data_type, StringName p_node_type, List<StringName> *p_list) const;
+ void add_theme_item_type(DataType p_data_type, const StringName &p_node_type);
+ void get_theme_item_type_list(DataType p_data_type, List<StringName> *p_list) const;
+
void get_type_list(List<StringName> *p_list) const;
void copy_default_theme();
@@ -151,4 +189,6 @@ public:
~Theme();
};
+VARIANT_ENUM_CAST(Theme::DataType);
+
#endif
diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp
index 156c7d0576..ccdc5bebd0 100644
--- a/scene/resources/world_2d.cpp
+++ b/scene/resources/world_2d.cpp
@@ -34,6 +34,7 @@
#include "scene/2d/camera_2d.h"
#include "scene/2d/visibility_notifier_2d.h"
#include "scene/main/window.h"
+#include "servers/navigation_server_2d.h"
#include "servers/physics_server_2d.h"
#include "servers/rendering_server.h"
@@ -315,14 +316,18 @@ void World2D::_update() {
indexer->_update();
}
-RID World2D::get_canvas() {
+RID World2D::get_canvas() const {
return canvas;
}
-RID World2D::get_space() {
+RID World2D::get_space() const {
return space;
}
+RID World2D::get_navigation_map() const {
+ return navigation_map;
+}
+
void World2D::get_viewport_list(List<Viewport *> *r_viewports) {
for (Map<Viewport *, SpatialIndexer2D::ViewportData>::Element *E = indexer->viewports.front(); E; E = E->next()) {
r_viewports->push_back(E->key());
@@ -332,11 +337,13 @@ void World2D::get_viewport_list(List<Viewport *> *r_viewports) {
void World2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_canvas"), &World2D::get_canvas);
ClassDB::bind_method(D_METHOD("get_space"), &World2D::get_space);
+ ClassDB::bind_method(D_METHOD("get_navigation_map"), &World2D::get_navigation_map);
ClassDB::bind_method(D_METHOD("get_direct_space_state"), &World2D::get_direct_space_state);
ADD_PROPERTY(PropertyInfo(Variant::RID, "canvas", PROPERTY_HINT_NONE, "", 0), "", "get_canvas");
ADD_PROPERTY(PropertyInfo(Variant::RID, "space", PROPERTY_HINT_NONE, "", 0), "", "get_space");
+ ADD_PROPERTY(PropertyInfo(Variant::RID, "navigation_map", PROPERTY_HINT_NONE, "", 0), "", "get_navigation_map");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "direct_space_state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectSpaceState2D", 0), "", "get_direct_space_state");
}
@@ -346,9 +353,9 @@ PhysicsDirectSpaceState2D *World2D::get_direct_space_state() {
World2D::World2D() {
canvas = RenderingServer::get_singleton()->canvas_create();
- space = PhysicsServer2D::get_singleton()->space_create();
- //set space2D to be more friendly with pixels than meters, by adjusting some constants
+ // Create and configure space2D to be more friendly with pixels than meters
+ space = PhysicsServer2D::get_singleton()->space_create();
PhysicsServer2D::get_singleton()->space_set_active(space, true);
PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_GRAVITY, GLOBAL_DEF("physics/2d/default_gravity", 98));
PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_GRAVITY_VECTOR, GLOBAL_DEF("physics/2d/default_gravity_vector", Vector2(0, 1)));
@@ -356,11 +363,19 @@ World2D::World2D() {
ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/default_linear_damp", PropertyInfo(Variant::FLOAT, "physics/2d/default_linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"));
PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_ANGULAR_DAMP, GLOBAL_DEF("physics/2d/default_angular_damp", 1.0));
ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/default_angular_damp", PropertyInfo(Variant::FLOAT, "physics/2d/default_angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"));
+
+ // Create and configure the navigation_map to be more friendly with pixels than meters.
+ navigation_map = NavigationServer2D::get_singleton()->map_create();
+ NavigationServer2D::get_singleton()->map_set_active(navigation_map, true);
+ NavigationServer2D::get_singleton()->map_set_cell_size(navigation_map, GLOBAL_DEF("navigation/2d/default_cell_size", 10));
+ NavigationServer2D::get_singleton()->map_set_edge_connection_margin(navigation_map, GLOBAL_DEF("navigation/2d/default_edge_connection_margin", 5));
+
indexer = memnew(SpatialIndexer2D);
}
World2D::~World2D() {
RenderingServer::get_singleton()->free(canvas);
PhysicsServer2D::get_singleton()->free(space);
+ NavigationServer2D::get_singleton()->free(navigation_map);
memdelete(indexer);
}
diff --git a/scene/resources/world_2d.h b/scene/resources/world_2d.h
index ae13367421..38abf3d7ad 100644
--- a/scene/resources/world_2d.h
+++ b/scene/resources/world_2d.h
@@ -44,6 +44,7 @@ class World2D : public Resource {
RID canvas;
RID space;
+ RID navigation_map;
SpatialIndexer2D *indexer;
@@ -63,8 +64,9 @@ protected:
void _update();
public:
- RID get_canvas();
- RID get_space();
+ RID get_canvas() const;
+ RID get_space() const;
+ RID get_navigation_map() const;
PhysicsDirectSpaceState2D *get_direct_space_state();
diff --git a/scene/resources/world_3d.cpp b/scene/resources/world_3d.cpp
index 9c0317454b..0e9f7a6cf2 100644
--- a/scene/resources/world_3d.cpp
+++ b/scene/resources/world_3d.cpp
@@ -35,6 +35,7 @@
#include "scene/3d/camera_3d.h"
#include "scene/3d/visibility_notifier_3d.h"
#include "scene/scene_string_names.h"
+#include "servers/navigation_server_3d.h"
struct SpatialIndexer {
Octree<VisibilityNotifier3D> octree;
@@ -243,6 +244,10 @@ RID World3D::get_space() const {
return space;
}
+RID World3D::get_navigation_map() const {
+ return navigation_map;
+}
+
RID World3D::get_scenario() const {
return scenario;
}
@@ -310,6 +315,7 @@ void World3D::get_camera_list(List<Camera3D *> *r_cameras) {
void World3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_space"), &World3D::get_space);
+ ClassDB::bind_method(D_METHOD("get_navigation_map"), &World3D::get_navigation_map);
ClassDB::bind_method(D_METHOD("get_scenario"), &World3D::get_scenario);
ClassDB::bind_method(D_METHOD("set_environment", "env"), &World3D::set_environment);
ClassDB::bind_method(D_METHOD("get_environment"), &World3D::get_environment);
@@ -322,6 +328,7 @@ void World3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "fallback_environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_fallback_environment", "get_fallback_environment");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "camera_effects", PROPERTY_HINT_RESOURCE_TYPE, "CameraEffects"), "set_camera_effects", "get_camera_effects");
ADD_PROPERTY(PropertyInfo(Variant::RID, "space", PROPERTY_HINT_NONE, "", 0), "", "get_space");
+ ADD_PROPERTY(PropertyInfo(Variant::RID, "navigation_map", PROPERTY_HINT_NONE, "", 0), "", "get_navigation_map");
ADD_PROPERTY(PropertyInfo(Variant::RID, "scenario", PROPERTY_HINT_NONE, "", 0), "", "get_scenario");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "direct_space_state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectSpaceState3D", 0), "", "get_direct_space_state");
}
@@ -338,6 +345,11 @@ World3D::World3D() {
PhysicsServer3D::get_singleton()->area_set_param(space, PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP, GLOBAL_DEF("physics/3d/default_angular_damp", 0.1));
ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/default_angular_damp", PropertyInfo(Variant::FLOAT, "physics/3d/default_angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"));
+ navigation_map = NavigationServer3D::get_singleton()->map_create();
+ NavigationServer3D::get_singleton()->map_set_active(navigation_map, true);
+ NavigationServer3D::get_singleton()->map_set_cell_size(navigation_map, GLOBAL_DEF("navigation/3d/default_cell_size", 0.3));
+ NavigationServer3D::get_singleton()->map_set_edge_connection_margin(navigation_map, GLOBAL_DEF("navigation/3d/default_edge_connection_margin", 5.0)); // Five meters, depends a lot on the agent's radius
+
#ifdef _3D_DISABLED
indexer = nullptr;
#else
@@ -348,6 +360,7 @@ World3D::World3D() {
World3D::~World3D() {
PhysicsServer3D::get_singleton()->free(space);
RenderingServer::get_singleton()->free(scenario);
+ NavigationServer3D::get_singleton()->free(navigation_map);
#ifndef _3D_DISABLED
memdelete(indexer);
diff --git a/scene/resources/world_3d.h b/scene/resources/world_3d.h
index 3d6c33997e..4e2717a2bb 100644
--- a/scene/resources/world_3d.h
+++ b/scene/resources/world_3d.h
@@ -46,6 +46,7 @@ class World3D : public Resource {
private:
RID space;
+ RID navigation_map;
RID scenario;
SpatialIndexer *indexer;
Ref<Environment> environment;
@@ -70,6 +71,7 @@ protected:
public:
RID get_space() const;
+ RID get_navigation_map() const;
RID get_scenario() const;
void set_environment(const Ref<Environment> &p_environment);