summaryrefslogtreecommitdiffstats
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/tile_map.cpp2
-rw-r--r--scene/3d/lightmap_gi.cpp6
-rw-r--r--scene/3d/lightmap_gi.h2
-rw-r--r--scene/3d/visual_instance_3d.cpp48
-rw-r--r--scene/3d/visual_instance_3d.h11
-rw-r--r--scene/animation/animation_blend_tree.cpp24
-rw-r--r--scene/animation/animation_blend_tree.h5
-rw-r--r--scene/animation/animation_mixer.cpp37
-rw-r--r--scene/animation/animation_mixer.h1
-rw-r--r--scene/animation/animation_player.cpp14
-rw-r--r--scene/animation/animation_player.h4
-rw-r--r--scene/animation/animation_tree.cpp4
-rw-r--r--scene/animation/animation_tree.h2
-rw-r--r--scene/gui/file_dialog.cpp33
-rw-r--r--scene/gui/file_dialog.h1
-rw-r--r--scene/gui/line_edit.cpp14
-rw-r--r--scene/gui/text_edit.cpp6
-rw-r--r--scene/main/viewport.cpp2
-rw-r--r--scene/main/window.cpp5
-rw-r--r--scene/main/window.h1
20 files changed, 175 insertions, 47 deletions
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 9e0973b239..c5174f5ec9 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -77,7 +77,7 @@ void TileMap::_set_tile_map_data_using_compatibility_format(int p_layer, TileMap
for (int i = 0; i < c; i += offset) {
const uint8_t *ptr = (const uint8_t *)&r[i];
uint8_t local[12];
- const int buffer_size = (format == TILE_MAP_DATA_FORMAT_2) ? 12 : 8;
+ const int buffer_size = (p_format >= TILE_MAP_DATA_FORMAT_2) ? 12 : 8;
for (int j = 0; j < buffer_size; j++) {
local[j] = ptr[j];
}
diff --git a/scene/3d/lightmap_gi.cpp b/scene/3d/lightmap_gi.cpp
index 8456da3280..8cd6f0f547 100644
--- a/scene/3d/lightmap_gi.cpp
+++ b/scene/3d/lightmap_gi.cpp
@@ -335,9 +335,7 @@ void LightmapGI::_find_meshes_and_lights(Node *p_at_node, Vector<MeshesFound> &m
mf.node_path = get_path_to(mi);
mf.subindex = -1;
mf.mesh = mesh;
-
- static const int lightmap_scale[GeometryInstance3D::LIGHTMAP_SCALE_MAX] = { 1, 2, 4, 8 };
- mf.lightmap_scale = lightmap_scale[mi->get_lightmap_scale()];
+ mf.lightmap_scale = mi->get_lightmap_texel_scale();
Ref<Material> all_override = mi->get_material_override();
for (int i = 0; i < mesh->get_surface_count(); i++) {
@@ -371,7 +369,7 @@ void LightmapGI::_find_meshes_and_lights(Node *p_at_node, Vector<MeshesFound> &m
mf.xform = xf * mesh_xf;
mf.node_path = get_path_to(s);
mf.subindex = i / 2;
- mf.lightmap_scale = 1;
+ mf.lightmap_scale = 1.0;
mf.mesh = mesh;
meshes.push_back(mf);
diff --git a/scene/3d/lightmap_gi.h b/scene/3d/lightmap_gi.h
index 39fca0e415..6efdcf497f 100644
--- a/scene/3d/lightmap_gi.h
+++ b/scene/3d/lightmap_gi.h
@@ -196,7 +196,7 @@ private:
NodePath node_path;
int32_t subindex = 0;
Ref<Mesh> mesh;
- int32_t lightmap_scale = 0;
+ float lightmap_scale = 0.0;
Vector<Ref<Material>> overrides;
};
diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp
index 0959c61f3a..68d412dbe2 100644
--- a/scene/3d/visual_instance_3d.cpp
+++ b/scene/3d/visual_instance_3d.cpp
@@ -456,14 +456,48 @@ AABB GeometryInstance3D::get_custom_aabb() const {
return custom_aabb;
}
+void GeometryInstance3D::set_lightmap_texel_scale(float p_scale) {
+ lightmap_texel_scale = p_scale;
+}
+
+float GeometryInstance3D::get_lightmap_texel_scale() const {
+ return lightmap_texel_scale;
+}
+
+#ifndef DISABLE_DEPRECATED
void GeometryInstance3D::set_lightmap_scale(LightmapScale p_scale) {
ERR_FAIL_INDEX(p_scale, LIGHTMAP_SCALE_MAX);
- lightmap_scale = p_scale;
+ switch (p_scale) {
+ case GeometryInstance3D::LIGHTMAP_SCALE_1X:
+ lightmap_texel_scale = 1.0f;
+ break;
+ case GeometryInstance3D::LIGHTMAP_SCALE_2X:
+ lightmap_texel_scale = 2.0f;
+ break;
+ case GeometryInstance3D::LIGHTMAP_SCALE_4X:
+ lightmap_texel_scale = 4.0f;
+ break;
+ case GeometryInstance3D::LIGHTMAP_SCALE_8X:
+ lightmap_texel_scale = 8.0f;
+ break;
+ case GeometryInstance3D::LIGHTMAP_SCALE_MAX:
+ break; // Can't happen, but silences warning.
+ }
}
GeometryInstance3D::LightmapScale GeometryInstance3D::get_lightmap_scale() const {
- return lightmap_scale;
+ // Return closest approximation.
+ if (lightmap_texel_scale < 1.5f) {
+ return GeometryInstance3D::LIGHTMAP_SCALE_1X;
+ } else if (lightmap_texel_scale < 3.0f) {
+ return GeometryInstance3D::LIGHTMAP_SCALE_2X;
+ } else if (lightmap_texel_scale < 6.0f) {
+ return GeometryInstance3D::LIGHTMAP_SCALE_4X;
+ }
+
+ return GeometryInstance3D::LIGHTMAP_SCALE_8X;
}
+#endif // DISABLE_DEPRECATED
void GeometryInstance3D::set_gi_mode(GIMode p_mode) {
switch (p_mode) {
@@ -567,8 +601,13 @@ void GeometryInstance3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_extra_cull_margin", "margin"), &GeometryInstance3D::set_extra_cull_margin);
ClassDB::bind_method(D_METHOD("get_extra_cull_margin"), &GeometryInstance3D::get_extra_cull_margin);
+ ClassDB::bind_method(D_METHOD("set_lightmap_texel_scale", "scale"), &GeometryInstance3D::set_lightmap_texel_scale);
+ ClassDB::bind_method(D_METHOD("get_lightmap_texel_scale"), &GeometryInstance3D::get_lightmap_texel_scale);
+
+#ifndef DISABLE_DEPRECATED
ClassDB::bind_method(D_METHOD("set_lightmap_scale", "scale"), &GeometryInstance3D::set_lightmap_scale);
ClassDB::bind_method(D_METHOD("get_lightmap_scale"), &GeometryInstance3D::get_lightmap_scale);
+#endif // DISABLE_DEPRECATED
ClassDB::bind_method(D_METHOD("set_gi_mode", "mode"), &GeometryInstance3D::set_gi_mode);
ClassDB::bind_method(D_METHOD("get_gi_mode"), &GeometryInstance3D::get_gi_mode);
@@ -593,7 +632,10 @@ void GeometryInstance3D::_bind_methods() {
ADD_GROUP("Global Illumination", "gi_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "gi_mode", PROPERTY_HINT_ENUM, "Disabled,Static,Dynamic"), "set_gi_mode", "get_gi_mode");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "gi_lightmap_scale", PROPERTY_HINT_ENUM, String::utf8("1×,2×,4×,8×")), "set_lightmap_scale", "get_lightmap_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gi_lightmap_texel_scale", PROPERTY_HINT_RANGE, "0.01,10,0.0001,or_greater"), "set_lightmap_texel_scale", "get_lightmap_texel_scale");
+#ifndef DISABLE_DEPRECATED
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "gi_lightmap_scale", PROPERTY_HINT_ENUM, String::utf8("1×,2×,4×,8×"), PROPERTY_USAGE_NONE), "set_lightmap_scale", "get_lightmap_scale");
+#endif // DISABLE_DEPRECATED
ADD_GROUP("Visibility Range", "visibility_range_");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_begin", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,or_greater,suffix:m"), "set_visibility_range_begin", "get_visibility_range_begin");
diff --git a/scene/3d/visual_instance_3d.h b/scene/3d/visual_instance_3d.h
index 4c4e5de2e8..48237823a4 100644
--- a/scene/3d/visual_instance_3d.h
+++ b/scene/3d/visual_instance_3d.h
@@ -136,7 +136,7 @@ private:
float extra_cull_margin = 0.0;
AABB custom_aabb;
- LightmapScale lightmap_scale = LIGHTMAP_SCALE_1X;
+ float lightmap_texel_scale = 1.0f;
GIMode gi_mode = GI_MODE_STATIC;
bool ignore_occlusion_culling = false;
@@ -187,8 +187,13 @@ public:
void set_gi_mode(GIMode p_mode);
GIMode get_gi_mode() const;
- void set_lightmap_scale(LightmapScale p_scale);
+ void set_lightmap_texel_scale(float p_scale);
+ float get_lightmap_texel_scale() const;
+
+#ifndef DISABLE_DEPRECATED
+ void set_lightmap_scale(GeometryInstance3D::LightmapScale p_scale);
LightmapScale get_lightmap_scale() const;
+#endif // DISABLE_DEPRECATED
void set_instance_shader_parameter(const StringName &p_name, const Variant &p_value);
Variant get_instance_shader_parameter(const StringName &p_name) const;
@@ -205,8 +210,8 @@ public:
};
VARIANT_ENUM_CAST(GeometryInstance3D::ShadowCastingSetting);
-VARIANT_ENUM_CAST(GeometryInstance3D::LightmapScale);
VARIANT_ENUM_CAST(GeometryInstance3D::GIMode);
+VARIANT_ENUM_CAST(GeometryInstance3D::LightmapScale);
VARIANT_ENUM_CAST(GeometryInstance3D::VisibilityRangeFadeMode);
#endif // VISUAL_INSTANCE_3D_H
diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp
index ec6b9f263d..35e974c92e 100644
--- a/scene/animation/animation_blend_tree.cpp
+++ b/scene/animation/animation_blend_tree.cpp
@@ -95,7 +95,9 @@ AnimationNode::NodeTimeInfo AnimationNodeAnimation::process(const AnimationMixer
AnimationMixer::PlaybackInfo pi = p_playback_info;
if (p_playback_info.seeked) {
- pi.delta = get_node_time_info().position - p_playback_info.time;
+ if (p_playback_info.is_external_seeking) {
+ pi.delta = get_node_time_info().position - p_playback_info.time;
+ }
} else {
pi.time = get_node_time_info().position + (backward ? -p_playback_info.delta : p_playback_info.delta);
}
@@ -142,6 +144,12 @@ AnimationNode::NodeTimeInfo AnimationNodeAnimation::_process(const AnimationMixe
// 1. Progress for AnimationNode.
bool will_end = Animation::is_greater_or_equal_approx(cur_time + cur_delta, cur_len);
+ bool is_started = p_seek && !p_is_external_seeking && Math::is_zero_approx(cur_time);
+
+ // 1. Progress for AnimationNode.
+ if (is_started && advance_on_start) {
+ cur_time = cur_delta;
+ }
if (cur_loop_mode != Animation::LOOP_NONE) {
if (cur_loop_mode == Animation::LOOP_LINEAR) {
if (!Math::is_zero_approx(cur_len)) {
@@ -234,7 +242,7 @@ AnimationNode::NodeTimeInfo AnimationNodeAnimation::_process(const AnimationMixe
// We should use call_deferred since the track keys are still being processed.
if (process_state->tree && !p_test_only) {
// AnimationTree uses seek to 0 "internally" to process the first key of the animation, which is used as the start detection.
- if (p_seek && !p_is_external_seeking && Math::is_zero_approx(cur_playback_time)) {
+ if (is_started) {
process_state->tree->call_deferred(SNAME("emit_signal"), SceneStringName(animation_started), animation);
}
// Finished.
@@ -284,6 +292,14 @@ bool AnimationNodeAnimation::is_backward() const {
return backward;
}
+void AnimationNodeAnimation::set_advance_on_start(bool p_advance_on_start) {
+ advance_on_start = p_advance_on_start;
+}
+
+bool AnimationNodeAnimation::is_advance_on_start() const {
+ return advance_on_start;
+}
+
void AnimationNodeAnimation::set_use_custom_timeline(bool p_use_custom_timeline) {
use_custom_timeline = p_use_custom_timeline;
notify_property_list_changed();
@@ -333,6 +349,9 @@ void AnimationNodeAnimation::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_play_mode", "mode"), &AnimationNodeAnimation::set_play_mode);
ClassDB::bind_method(D_METHOD("get_play_mode"), &AnimationNodeAnimation::get_play_mode);
+ ClassDB::bind_method(D_METHOD("set_advance_on_start", "advance_on_start"), &AnimationNodeAnimation::set_advance_on_start);
+ ClassDB::bind_method(D_METHOD("is_advance_on_start"), &AnimationNodeAnimation::is_advance_on_start);
+
ClassDB::bind_method(D_METHOD("set_use_custom_timeline", "use_custom_timeline"), &AnimationNodeAnimation::set_use_custom_timeline);
ClassDB::bind_method(D_METHOD("is_using_custom_timeline"), &AnimationNodeAnimation::is_using_custom_timeline);
@@ -350,6 +369,7 @@ void AnimationNodeAnimation::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "animation"), "set_animation", "get_animation");
ADD_PROPERTY(PropertyInfo(Variant::INT, "play_mode", PROPERTY_HINT_ENUM, "Forward,Backward"), "set_play_mode", "get_play_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "advance_on_start"), "set_advance_on_start", "is_advance_on_start");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_custom_timeline"), "set_use_custom_timeline", "is_using_custom_timeline");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "timeline_length", PROPERTY_HINT_RANGE, "0.001,60,0.001,or_greater,or_less,hide_slider,suffix:s"), "set_timeline_length", "get_timeline_length");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stretch_time_scale"), "set_stretch_time_scale", "is_stretching_time_scale");
diff --git a/scene/animation/animation_blend_tree.h b/scene/animation/animation_blend_tree.h
index 9967a6f449..6cb208d710 100644
--- a/scene/animation/animation_blend_tree.h
+++ b/scene/animation/animation_blend_tree.h
@@ -40,6 +40,8 @@ class AnimationNodeAnimation : public AnimationRootNode {
StringName animation;
+ bool advance_on_start = false;
+
bool use_custom_timeline = false;
double timeline_length = 1.0;
Animation::LoopMode loop_mode = Animation::LOOP_NONE;
@@ -74,6 +76,9 @@ public:
void set_backward(bool p_backward);
bool is_backward() const;
+ void set_advance_on_start(bool p_advance_on_start);
+ bool is_advance_on_start() const;
+
void set_use_custom_timeline(bool p_use_custom_timeline);
bool is_using_custom_timeline() const;
diff --git a/scene/animation/animation_mixer.cpp b/scene/animation/animation_mixer.cpp
index 00160f21a4..4566f34674 100644
--- a/scene/animation/animation_mixer.cpp
+++ b/scene/animation/animation_mixer.cpp
@@ -602,6 +602,22 @@ void AnimationMixer::_init_root_motion_cache() {
root_motion_scale_accumulator = Vector3(1, 1, 1);
}
+void AnimationMixer::_create_track_num_to_track_cashe_for_animation(Ref<Animation> &p_animation) {
+ ERR_FAIL_COND(animation_track_num_to_track_cashe.has(p_animation));
+ LocalVector<TrackCache *> &track_num_to_track_cashe = animation_track_num_to_track_cashe.insert_new(p_animation, LocalVector<TrackCache *>())->value;
+ const Vector<Animation::Track *> &tracks = p_animation->get_tracks();
+
+ track_num_to_track_cashe.resize(tracks.size());
+ for (int i = 0; i < tracks.size(); i++) {
+ TrackCache **track_ptr = track_cache.getptr(tracks[i]->thash);
+ if (track_ptr == nullptr) {
+ track_num_to_track_cashe[i] = nullptr;
+ } else {
+ track_num_to_track_cashe[i] = *track_ptr;
+ }
+ }
+}
+
bool AnimationMixer::_update_caches() {
setup_pass++;
@@ -930,20 +946,9 @@ bool AnimationMixer::_update_caches() {
}
animation_track_num_to_track_cashe.clear();
- LocalVector<TrackCache *> track_num_to_track_cashe;
for (const StringName &E : sname_list) {
Ref<Animation> anim = get_animation(E);
- const Vector<Animation::Track *> tracks = anim->get_tracks();
- track_num_to_track_cashe.resize(tracks.size());
- for (int i = 0; i < tracks.size(); i++) {
- TrackCache **track_ptr = track_cache.getptr(tracks[i]->thash);
- if (track_ptr == nullptr) {
- track_num_to_track_cashe[i] = nullptr;
- } else {
- track_num_to_track_cashe[i] = *track_ptr;
- }
- }
- animation_track_num_to_track_cashe.insert(anim, track_num_to_track_cashe);
+ _create_track_num_to_track_cashe_for_animation(anim);
}
track_count = idx;
@@ -1076,6 +1081,9 @@ void AnimationMixer::blend_capture(double p_delta) {
capture_cache.remain -= p_delta * capture_cache.step;
if (Animation::is_less_or_equal_approx(capture_cache.remain, 0)) {
+ if (capture_cache.animation.is_valid()) {
+ animation_track_num_to_track_cashe.erase(capture_cache.animation);
+ }
capture_cache.clear();
return;
}
@@ -2207,6 +2215,9 @@ void AnimationMixer::capture(const StringName &p_name, double p_duration, Tween:
capture_cache.step = 1.0 / p_duration;
capture_cache.trans_type = p_trans_type;
capture_cache.ease_type = p_ease_type;
+ if (capture_cache.animation.is_valid()) {
+ animation_track_num_to_track_cashe.erase(capture_cache.animation);
+ }
capture_cache.animation.instantiate();
bool is_valid = false;
@@ -2230,6 +2241,8 @@ void AnimationMixer::capture(const StringName &p_name, double p_duration, Tween:
}
if (!is_valid) {
capture_cache.clear();
+ } else {
+ _create_track_num_to_track_cashe_for_animation(capture_cache.animation);
}
}
diff --git a/scene/animation/animation_mixer.h b/scene/animation/animation_mixer.h
index b2468b3299..757ccb8ff6 100644
--- a/scene/animation/animation_mixer.h
+++ b/scene/animation/animation_mixer.h
@@ -323,6 +323,7 @@ protected:
void _clear_playing_caches();
void _init_root_motion_cache();
bool _update_caches();
+ void _create_track_num_to_track_cashe_for_animation(Ref<Animation> &p_animation);
/* ---- Audio ---- */
AudioServer::PlaybackType playback_type;
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index fc37a67c48..0b720d6710 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -878,6 +878,20 @@ Tween::EaseType AnimationPlayer::get_auto_capture_ease_type() const {
return auto_capture_ease_type;
}
+#ifdef TOOLS_ENABLED
+void AnimationPlayer::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
+ const String pf = p_function;
+ if (p_idx == 0 && (pf == "play" || pf == "play_backwards" || pf == "has_animation" || pf == "queue")) {
+ List<StringName> al;
+ get_animation_list(&al);
+ for (const StringName &name : al) {
+ r_options->push_back(String(name).quote());
+ }
+ }
+ AnimationMixer::get_argument_options(p_function, p_idx, r_options);
+}
+#endif
+
void AnimationPlayer::_animation_removed(const StringName &p_name, const StringName &p_library) {
AnimationMixer::_animation_removed(p_name, p_library);
diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h
index db753f6bee..dd8ffd3286 100644
--- a/scene/animation/animation_player.h
+++ b/scene/animation/animation_player.h
@@ -180,6 +180,10 @@ public:
void set_auto_capture_ease_type(Tween::EaseType p_auto_capture_ease_type);
Tween::EaseType get_auto_capture_ease_type() const;
+#ifdef TOOLS_ENABLED
+ void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override;
+#endif
+
void play(const StringName &p_name = StringName(), double p_custom_blend = -1, float p_custom_scale = 1.0, bool p_from_end = false);
void play_section_with_markers(const StringName &p_name = StringName(), const StringName &p_start_marker = StringName(), const StringName &p_end_marker = StringName(), double p_custom_blend = -1, float p_custom_scale = 1.0, bool p_from_end = false);
void play_section(const StringName &p_name = StringName(), double p_start_time = -1, double p_end_time = -1, double p_custom_blend = -1, float p_custom_scale = 1.0, bool p_from_end = false);
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp
index 7c49aac2b2..a63cf78f1c 100644
--- a/scene/animation/animation_tree.cpp
+++ b/scene/animation/animation_tree.cpp
@@ -373,7 +373,9 @@ AnimationNode::NodeTimeInfo AnimationNode::process(const AnimationMixer::Playbac
AnimationMixer::PlaybackInfo pi = p_playback_info;
if (p_playback_info.seeked) {
- pi.delta = get_node_time_info().position - p_playback_info.time;
+ if (p_playback_info.is_external_seeking) {
+ pi.delta = get_node_time_info().position - p_playback_info.time;
+ }
} else {
pi.time = get_node_time_info().position + p_playback_info.delta;
}
diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h
index 88532ab722..d50c88010c 100644
--- a/scene/animation/animation_tree.h
+++ b/scene/animation/animation_tree.h
@@ -93,7 +93,7 @@ public:
if (Math::is_zero_approx(remain)) {
return 0;
}
- return length - position;
+ return remain;
}
};
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index c8378f2b1d..b885565cdc 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -70,9 +70,9 @@ void FileDialog::_native_popup() {
root = OS::get_singleton()->get_user_data_dir();
}
if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_NATIVE_DIALOG_FILE_EXTRA)) {
- DisplayServer::get_singleton()->file_dialog_with_options_show(get_title(), ProjectSettings::get_singleton()->globalize_path(dir->get_text()), root, file->get_text().get_file(), show_hidden_files, DisplayServer::FileDialogMode(mode), filters, _get_options(), callable_mp(this, &FileDialog::_native_dialog_cb_with_options));
+ DisplayServer::get_singleton()->file_dialog_with_options_show(get_translated_title(), ProjectSettings::get_singleton()->globalize_path(dir->get_text()), root, file->get_text().get_file(), show_hidden_files, DisplayServer::FileDialogMode(mode), processed_filters, _get_options(), callable_mp(this, &FileDialog::_native_dialog_cb_with_options));
} else {
- DisplayServer::get_singleton()->file_dialog_show(get_title(), ProjectSettings::get_singleton()->globalize_path(dir->get_text()), file->get_text().get_file(), show_hidden_files, DisplayServer::FileDialogMode(mode), filters, callable_mp(this, &FileDialog::_native_dialog_cb));
+ DisplayServer::get_singleton()->file_dialog_show(get_translated_title(), ProjectSettings::get_singleton()->globalize_path(dir->get_text()), file->get_text().get_file(), show_hidden_files, DisplayServer::FileDialogMode(mode), processed_filters, callable_mp(this, &FileDialog::_native_dialog_cb));
}
}
@@ -853,37 +853,54 @@ void FileDialog::_filename_filter_selected() {
void FileDialog::update_filters() {
filter->clear();
+ processed_filters.clear();
if (filters.size() > 1) {
String all_filters;
+ String all_filters_full;
const int max_filters = 5;
for (int i = 0; i < MIN(max_filters, filters.size()); i++) {
- String flt = filters[i].get_slice(";", 0).strip_edges();
+ String flt = filters[i].get_slicec(';', 0).strip_edges();
if (i > 0) {
all_filters += ", ";
}
all_filters += flt;
}
+ for (int i = 0; i < filters.size(); i++) {
+ String flt = filters[i].get_slicec(';', 0).strip_edges();
+ if (i > 0) {
+ all_filters_full += ",";
+ }
+ all_filters_full += flt;
+ }
if (max_filters < filters.size()) {
all_filters += ", ...";
}
- filter->add_item(atr(ETR("All Recognized")) + " (" + all_filters + ")");
+ String f = atr(ETR("All Recognized")) + " (" + all_filters + ")";
+ filter->add_item(f);
+ processed_filters.push_back(all_filters_full + ";" + f);
}
for (int i = 0; i < filters.size(); i++) {
- String flt = filters[i].get_slice(";", 0).strip_edges();
+ String flt = filters[i].get_slicec(';', 0).strip_edges();
String desc = filters[i].get_slice(";", 1).strip_edges();
if (desc.length()) {
- filter->add_item(String(tr(desc)) + " (" + flt + ")");
+ String f = atr(desc) + " (" + flt + ")";
+ filter->add_item(f);
+ processed_filters.push_back(flt + ";" + f);
} else {
- filter->add_item("(" + flt + ")");
+ String f = "(" + flt + ")";
+ filter->add_item(f);
+ processed_filters.push_back(flt + ";" + f);
}
}
- filter->add_item(atr(ETR("All Files")) + " (*)");
+ String f = atr(ETR("All Files")) + " (*)";
+ filter->add_item(f);
+ processed_filters.push_back("*.*;" + f);
}
void FileDialog::clear_filename_filter() {
diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h
index 84a3334503..5eeed5b220 100644
--- a/scene/gui/file_dialog.h
+++ b/scene/gui/file_dialog.h
@@ -103,6 +103,7 @@ private:
Button *show_filename_filter_button = nullptr;
Vector<String> filters;
+ Vector<String> processed_filters;
String file_name_filter;
bool show_filename_filter = false;
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 6dcd944004..819d467da7 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -1454,13 +1454,12 @@ void LineEdit::undo() {
return;
}
+ if (!has_undo()) {
+ return;
+ }
+
if (undo_stack_pos == nullptr) {
- if (undo_stack.size() <= 1) {
- return;
- }
undo_stack_pos = undo_stack.back();
- } else if (undo_stack_pos == undo_stack.front()) {
- return;
}
deselect();
@@ -1481,10 +1480,7 @@ void LineEdit::redo() {
return;
}
- if (undo_stack_pos == nullptr) {
- return;
- }
- if (undo_stack_pos == undo_stack.back()) {
+ if (!has_redo()) {
return;
}
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 526c2a9b36..d885b07d14 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -4177,7 +4177,7 @@ void TextEdit::redo() {
}
_push_current_op();
- if (undo_stack_pos == nullptr) {
+ if (!has_redo()) {
return; // Nothing to do.
}
@@ -7312,6 +7312,10 @@ void TextEdit::_paste_internal(int p_caret) {
}
String clipboard = DisplayServer::get_singleton()->clipboard_get();
+ if (clipboard.is_empty()) {
+ // Nothing to paste.
+ return;
+ }
// Paste a full line. Ignore '\r' characters that may have been added to the clipboard by the OS.
if (get_caret_count() == 1 && !has_selection(0) && !cut_copy_line.is_empty() && cut_copy_line == clipboard.replace("\r", "")) {
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 4a808c4081..8a48b99040 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -332,7 +332,7 @@ void Viewport::_sub_window_update(Window *p_window) {
int close_h_ofs = p_window->theme_cache.close_h_offset;
int close_v_ofs = p_window->theme_cache.close_v_offset;
- TextLine title_text = TextLine(p_window->atr(p_window->get_title()), title_font, font_size);
+ TextLine title_text = TextLine(p_window->get_translated_title(), title_font, font_size);
title_text.set_width(r.size.width - panel->get_minimum_size().x - close_h_ofs);
title_text.set_direction(p_window->is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR);
int x = (r.size.width - title_text.get_size().x) / 2;
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index ab9c56d56c..3a2245c555 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -305,6 +305,11 @@ String Window::get_title() const {
return title;
}
+String Window::get_translated_title() const {
+ ERR_READ_THREAD_GUARD_V(String());
+ return tr_title;
+}
+
void Window::_settings_changed() {
if (visible && initial_position != WINDOW_INITIAL_POSITION_ABSOLUTE && is_in_edited_scene_root()) {
Size2 screen_size = Size2(GLOBAL_GET("display/window/size/viewport_width"), GLOBAL_GET("display/window/size/viewport_height"));
diff --git a/scene/main/window.h b/scene/main/window.h
index d0f9cd11b9..00345e7b82 100644
--- a/scene/main/window.h
+++ b/scene/main/window.h
@@ -276,6 +276,7 @@ public:
void set_title(const String &p_title);
String get_title() const;
+ String get_translated_title() const;
void set_initial_position(WindowInitialPosition p_initial_position);
WindowInitialPosition get_initial_position() const;