summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/io/resource.cpp96
-rw-r--r--core/io/resource.h4
-rw-r--r--core/io/resource_format_binary.cpp10
-rw-r--r--core/io/resource_loader.cpp51
-rw-r--r--core/object/object.h2
-rw-r--r--doc/classes/@GlobalScope.xml2
-rw-r--r--doc/classes/NavigationAgent2D.xml3
-rw-r--r--doc/classes/NavigationAgent3D.xml3
-rw-r--r--doc/classes/TextEdit.xml3
-rw-r--r--editor/code_editor.cpp1
-rw-r--r--editor/dependency_editor.cpp2
-rw-r--r--editor/editor_file_system.cpp9
-rw-r--r--editor/editor_folding.cpp5
-rw-r--r--editor/editor_node.cpp10
-rw-r--r--editor/editor_properties.cpp2
-rw-r--r--editor/editor_settings.cpp1
-rw-r--r--editor/icons/BaseButton.svg1
-rw-r--r--editor/icons/GeometryInstance3D.svg1
-rw-r--r--editor/icons/ImporterMeshInstance3D.svg1
-rw-r--r--editor/icons/MultiplayerSpawner.svg1
-rw-r--r--editor/icons/MultiplayerSynchronizer.svg1
-rw-r--r--editor/icons/Range.svg1
-rw-r--r--editor/icons/VisualInstance3D.svg1
-rw-r--r--editor/import/resource_importer_scene.cpp4
-rw-r--r--editor/import/resource_importer_texture_atlas.cpp6
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp2
-rw-r--r--editor/quick_open.cpp2
-rw-r--r--modules/gdscript/gdscript_editor.cpp2
-rw-r--r--modules/visual_script/visual_script_flow_control.cpp2
-rw-r--r--modules/visual_script/visual_script_func_nodes.cpp12
-rw-r--r--platform/android/android_input_handler.cpp10
-rw-r--r--platform/android/android_input_handler.h2
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotLib.java5
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java9
-rw-r--r--platform/android/java_godot_lib_jni.cpp9
-rw-r--r--platform/android/java_godot_lib_jni.h1
-rw-r--r--scene/2d/node_2d.cpp2
-rw-r--r--scene/3d/lightmap_gi.cpp2
-rw-r--r--scene/3d/node_3d.cpp2
-rw-r--r--scene/debugger/scene_debugger.cpp4
-rw-r--r--scene/gui/dialogs.cpp4
-rw-r--r--scene/gui/file_dialog.cpp46
-rw-r--r--scene/gui/progress_bar.cpp4
-rw-r--r--scene/gui/tab_container.cpp1
-rw-r--r--scene/gui/text_edit.cpp14
-rw-r--r--scene/gui/text_edit.h4
-rw-r--r--scene/resources/primitive_meshes.cpp7
-rw-r--r--scene/resources/resource_format_text.cpp22
-rw-r--r--servers/rendering/renderer_rd/effects/copy_effects.cpp4
49 files changed, 193 insertions, 200 deletions
diff --git a/core/io/resource.cpp b/core/io/resource.cpp
index ed7228d0b9..fec5ca5c7b 100644
--- a/core/io/resource.cpp
+++ b/core/io/resource.cpp
@@ -52,41 +52,36 @@ void Resource::set_path(const String &p_path, bool p_take_over) {
return;
}
+ if (p_path.is_empty()) {
+ p_take_over = false; // Can't take over an empty path
+ }
+
+ ResourceCache::lock.lock();
+
if (!path_cache.is_empty()) {
- ResourceCache::lock.write_lock();
ResourceCache::resources.erase(path_cache);
- ResourceCache::lock.write_unlock();
}
path_cache = "";
- ResourceCache::lock.read_lock();
- bool has_path = ResourceCache::resources.has(p_path);
- ResourceCache::lock.read_unlock();
+ Ref<Resource> existing = ResourceCache::get_ref(p_path);
- if (has_path) {
+ if (existing.is_valid()) {
if (p_take_over) {
- ResourceCache::lock.write_lock();
- Resource **res = ResourceCache::resources.getptr(p_path);
- if (res) {
- (*res)->set_name("");
- }
- ResourceCache::lock.write_unlock();
+ existing->path_cache = String();
+ ResourceCache::resources.erase(p_path);
} else {
- ResourceCache::lock.read_lock();
- bool exists = ResourceCache::resources.has(p_path);
- ResourceCache::lock.read_unlock();
-
- ERR_FAIL_COND_MSG(exists, "Another resource is loaded from path '" + p_path + "' (possible cyclic resource inclusion).");
+ ResourceCache::lock.unlock();
+ ERR_FAIL_MSG("Another resource is loaded from path '" + p_path + "' (possible cyclic resource inclusion).");
}
}
+
path_cache = p_path;
if (!path_cache.is_empty()) {
- ResourceCache::lock.write_lock();
ResourceCache::resources[path_cache] = this;
- ResourceCache::lock.write_unlock();
}
+ ResourceCache::lock.unlock();
_resource_path_changed();
}
@@ -380,7 +375,7 @@ void Resource::set_as_translation_remapped(bool p_remapped) {
return;
}
- ResourceCache::lock.write_lock();
+ ResourceCache::lock.lock();
if (p_remapped) {
ResourceLoader::remapped_list.add(&remapped_list);
@@ -388,7 +383,7 @@ void Resource::set_as_translation_remapped(bool p_remapped) {
ResourceLoader::remapped_list.remove(&remapped_list);
}
- ResourceCache::lock.write_unlock();
+ ResourceCache::lock.unlock();
}
bool Resource::is_translation_remapped() const {
@@ -455,9 +450,9 @@ Resource::Resource() :
Resource::~Resource() {
if (!path_cache.is_empty()) {
- ResourceCache::lock.write_lock();
+ ResourceCache::lock.lock();
ResourceCache::resources.erase(path_cache);
- ResourceCache::lock.write_unlock();
+ ResourceCache::lock.unlock();
}
if (owners.size()) {
WARN_PRINT("Resource is still owned.");
@@ -469,7 +464,7 @@ HashMap<String, Resource *> ResourceCache::resources;
HashMap<String, HashMap<String, String>> ResourceCache::resource_path_cache;
#endif
-RWLock ResourceCache::lock;
+Mutex ResourceCache::lock;
#ifdef TOOLS_ENABLED
RWLock ResourceCache::path_cache_lock;
#endif
@@ -491,46 +486,67 @@ void ResourceCache::reload_externals() {
}
bool ResourceCache::has(const String &p_path) {
- lock.read_lock();
- bool b = resources.has(p_path);
- lock.read_unlock();
+ lock.lock();
+
+ Resource **res = resources.getptr(p_path);
- return b;
+ if (res && (*res)->reference_get_count() == 0) {
+ // This resource is in the process of being deleted, ignore its existence.
+ (*res)->path_cache = String();
+ resources.erase(p_path);
+ res = nullptr;
+ }
+
+ lock.unlock();
+
+ if (!res) {
+ return false;
+ }
+
+ return true;
}
-Resource *ResourceCache::get(const String &p_path) {
- lock.read_lock();
+Ref<Resource> ResourceCache::get_ref(const String &p_path) {
+ Ref<Resource> ref;
+ lock.lock();
Resource **res = resources.getptr(p_path);
- lock.read_unlock();
+ if (res) {
+ ref = Ref<Resource>(*res);
+ }
- if (!res) {
- return nullptr;
+ if (res && !ref.is_valid()) {
+ // This resource is in the process of being deleted, ignore its existence
+ (*res)->path_cache = String();
+ resources.erase(p_path);
+ res = nullptr;
}
- return *res;
+ lock.unlock();
+
+ return ref;
}
void ResourceCache::get_cached_resources(List<Ref<Resource>> *p_resources) {
- lock.read_lock();
+ lock.lock();
for (KeyValue<String, Resource *> &E : resources) {
p_resources->push_back(Ref<Resource>(E.value));
}
- lock.read_unlock();
+ lock.unlock();
}
int ResourceCache::get_cached_resource_count() {
- lock.read_lock();
+ lock.lock();
int rc = resources.size();
- lock.read_unlock();
+ lock.unlock();
return rc;
}
void ResourceCache::dump(const char *p_file, bool p_short) {
#ifdef DEBUG_ENABLED
- lock.read_lock();
+ lock.lock();
HashMap<String, int> type_count;
@@ -562,7 +578,7 @@ void ResourceCache::dump(const char *p_file, bool p_short) {
}
}
- lock.read_unlock();
+ lock.unlock();
#else
WARN_PRINT("ResourceCache::dump only with in debug builds.");
#endif
diff --git a/core/io/resource.h b/core/io/resource.h
index a45bc6e1e4..a2cde87990 100644
--- a/core/io/resource.h
+++ b/core/io/resource.h
@@ -153,7 +153,7 @@ public:
class ResourceCache {
friend class Resource;
friend class ResourceLoader; //need the lock
- static RWLock lock;
+ static Mutex lock;
static HashMap<String, Resource *> resources;
#ifdef TOOLS_ENABLED
static HashMap<String, HashMap<String, String>> resource_path_cache; // Each tscn has a set of resource paths and IDs.
@@ -166,7 +166,7 @@ class ResourceCache {
public:
static void reload_externals();
static bool has(const String &p_path);
- static Resource *get(const String &p_path);
+ static Ref<Resource> get_ref(const String &p_path);
static void dump(const char *p_file = nullptr, bool p_short = false);
static void get_cached_resources(List<Ref<Resource>> *p_resources);
static int get_cached_resource_count();
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index 2469e1a4be..b1c50e829c 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -693,7 +693,7 @@ Error ResourceLoaderBinary::load() {
}
if (cache_mode == ResourceFormatLoader::CACHE_MODE_REUSE && ResourceCache::has(path)) {
- Ref<Resource> cached = ResourceCache::get(path);
+ Ref<Resource> cached = ResourceCache::get_ref(path);
if (cached.is_valid()) {
//already loaded, don't do anything
error = OK;
@@ -717,10 +717,10 @@ Error ResourceLoaderBinary::load() {
if (cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE && ResourceCache::has(path)) {
//use the existing one
- Resource *r = ResourceCache::get(path);
- if (r->get_class() == t) {
- r->reset_state();
- res = Ref<Resource>(r);
+ Ref<Resource> cached = ResourceCache::get_ref(path);
+ if (cached->get_class() == t) {
+ cached->reset_state();
+ res = cached;
}
}
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index fb21db1a19..2cd455475c 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -335,23 +335,15 @@ Error ResourceLoader::load_threaded_request(const String &p_path, const String &
thread_load_mutex->unlock();
ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Attempted to load a resource already being loaded from this thread, cyclic reference?");
}
- //lock first if possible
- ResourceCache::lock.read_lock();
-
- //get ptr
- Resource **rptr = ResourceCache::resources.getptr(local_path);
-
- if (rptr) {
- Ref<Resource> res(*rptr);
- //it is possible this resource was just freed in a thread. If so, this referencing will not work and resource is considered not cached
- if (res.is_valid()) {
- //referencing is fine
- load_task.resource = res;
- load_task.status = THREAD_LOAD_LOADED;
- load_task.progress = 1.0;
- }
+
+ Ref<Resource> existing = ResourceCache::get_ref(local_path);
+
+ if (existing.is_valid()) {
+ //referencing is fine
+ load_task.resource = existing;
+ load_task.status = THREAD_LOAD_LOADED;
+ load_task.progress = 1.0;
}
- ResourceCache::lock.read_unlock();
}
if (!p_source_resource.is_empty()) {
@@ -530,27 +522,18 @@ Ref<Resource> ResourceLoader::load(const String &p_path, const String &p_type_hi
}
//Is it cached?
- ResourceCache::lock.read_lock();
-
- Resource **rptr = ResourceCache::resources.getptr(local_path);
- if (rptr) {
- Ref<Resource> res(*rptr);
+ Ref<Resource> existing = ResourceCache::get_ref(local_path);
- //it is possible this resource was just freed in a thread. If so, this referencing will not work and resource is considered not cached
- if (res.is_valid()) {
- ResourceCache::lock.read_unlock();
- thread_load_mutex->unlock();
-
- if (r_error) {
- *r_error = OK;
- }
+ if (existing.is_valid()) {
+ thread_load_mutex->unlock();
- return res; //use cached
+ if (r_error) {
+ *r_error = OK;
}
- }
- ResourceCache::lock.read_unlock();
+ return existing; //use cached
+ }
//load using task (but this thread)
ThreadLoadTask load_task;
@@ -867,7 +850,7 @@ String ResourceLoader::path_remap(const String &p_path) {
}
void ResourceLoader::reload_translation_remaps() {
- ResourceCache::lock.read_lock();
+ ResourceCache::lock.lock();
List<Resource *> to_reload;
SelfList<Resource> *E = remapped_list.first();
@@ -877,7 +860,7 @@ void ResourceLoader::reload_translation_remaps() {
E = E->next();
}
- ResourceCache::lock.read_unlock();
+ ResourceCache::lock.unlock();
//now just make sure to not delete any of these resources while changing locale..
while (to_reload.front()) {
diff --git a/core/object/object.h b/core/object/object.h
index fe9231cfd8..2a9f2ebf93 100644
--- a/core/object/object.h
+++ b/core/object/object.h
@@ -47,7 +47,7 @@
enum PropertyHint {
PROPERTY_HINT_NONE, ///< no hint provided.
- PROPERTY_HINT_RANGE, ///< hint_text = "min,max[,step][,or_greater][,or_lesser][,noslider][,radians][,degrees][,exp][,suffix:<keyword>] range.
+ PROPERTY_HINT_RANGE, ///< hint_text = "min,max[,step][,or_greater][,or_lesser][,no_slider][,radians][,degrees][,exp][,suffix:<keyword>] range.
PROPERTY_HINT_ENUM, ///< hint_text= "val1,val2,val3,etc"
PROPERTY_HINT_ENUM_SUGGESTION, ///< hint_text= "val1,val2,val3,etc"
PROPERTY_HINT_EXP_EASING, /// exponential easing function (Math::ease) use "attenuation" hint string to revert (flip h), "full" to also include in/out. (ie: "attenuation,inout")
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml
index 4048b483e8..475d166925 100644
--- a/doc/classes/@GlobalScope.xml
+++ b/doc/classes/@GlobalScope.xml
@@ -2460,7 +2460,7 @@
</constant>
<constant name="PROPERTY_HINT_RANGE" value="1" enum="PropertyHint">
Hints that an integer or float property should be within a range specified via the hint string [code]"min,max"[/code] or [code]"min,max,step"[/code]. The hint string can optionally include [code]"or_greater"[/code] and/or [code]"or_lesser"[/code] to allow manual input going respectively above the max or below the min values. Example: [code]"-360,360,1,or_greater,or_lesser"[/code].
- Additionally, other keywords can be included: "exp" for exponential range editing, "radians" for editing radian angles in degrees, "degrees" to hint at an angle and "noslider" to hide the slider.
+ Additionally, other keywords can be included: "exp" for exponential range editing, "radians" for editing radian angles in degrees, "degrees" to hint at an angle and "no_slider" to hide the slider.
</constant>
<constant name="PROPERTY_HINT_ENUM" value="2" enum="PropertyHint">
Hints that an integer, float or string property is an enumerated value to pick in a list specified via a hint string.
diff --git a/doc/classes/NavigationAgent2D.xml b/doc/classes/NavigationAgent2D.xml
index 757b635252..058f1032cb 100644
--- a/doc/classes/NavigationAgent2D.xml
+++ b/doc/classes/NavigationAgent2D.xml
@@ -136,7 +136,8 @@
The maximum distance the agent is allowed away from the ideal path to the final location. This can happen due to trying to avoid collisions. When the maximum distance is exceeded, it recalculates the ideal path.
</member>
<member name="radius" type="float" setter="set_radius" getter="get_radius" default="10.0">
- The radius of the agent.
+ The radius of the avoidance agent. This is the "body" of the avoidance agent and not the avoidance maneuver starting radius (which is controlled by [member neighbor_dist]).
+ Does not affect normal pathfinding. To change an actor's pathfinding radius bake [NavigationMesh] resources with a different [member NavigationMesh.agent_radius] property and use different navigation maps for each actor size.
</member>
<member name="target_desired_distance" type="float" setter="set_target_desired_distance" getter="get_target_desired_distance" default="1.0">
The distance threshold before the final target point is considered to be reached. This will allow an agent to not have to hit the point of the final target exactly, but only the area. If this value is set to low the NavigationAgent will be stuck in a repath loop cause it will constantly overshoot or undershoot the distance to the final target point on each physics frame update.
diff --git a/doc/classes/NavigationAgent3D.xml b/doc/classes/NavigationAgent3D.xml
index 5e1004165d..c689ddc345 100644
--- a/doc/classes/NavigationAgent3D.xml
+++ b/doc/classes/NavigationAgent3D.xml
@@ -142,7 +142,8 @@
The maximum distance the agent is allowed away from the ideal path to the final location. This can happen due to trying to avoid collisions. When the maximum distance is exceeded, it recalculates the ideal path.
</member>
<member name="radius" type="float" setter="set_radius" getter="get_radius" default="1.0">
- The radius of the agent.
+ The radius of the avoidance agent. This is the "body" of the avoidance agent and not the avoidance maneuver starting radius (which is controlled by [member neighbor_dist]).
+ Does not affect normal pathfinding. To change an actor's pathfinding radius bake [NavigationMesh] resources with a different [member NavigationMesh.agent_radius] property and use different navigation maps for each actor size.
</member>
<member name="target_desired_distance" type="float" setter="set_target_desired_distance" getter="get_target_desired_distance" default="1.0">
The distance threshold before the final target point is considered to be reached. This will allow an agent to not have to hit the point of the final target exactly, but only the area. If this value is set to low the NavigationAgent will be stuck in a repath loop cause it will constantly overshoot or undershoot the distance to the final target point on each physics frame update.
diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml
index 58fdd2d058..2de185903d 100644
--- a/doc/classes/TextEdit.xml
+++ b/doc/classes/TextEdit.xml
@@ -956,6 +956,9 @@
<member name="deselect_on_focus_loss_enabled" type="bool" setter="set_deselect_on_focus_loss_enabled" getter="is_deselect_on_focus_loss_enabled" default="true">
If [code]true[/code], the selected text will be deselected when focus is lost.
</member>
+ <member name="drag_and_drop_selection_enabled" type="bool" setter="set_drag_and_drop_selection_enabled" getter="is_drag_and_drop_selection_enabled" default="true">
+ If [code]true[/code], allow drag and drop of selected text.
+ </member>
<member name="draw_control_chars" type="bool" setter="set_draw_control_chars" getter="get_draw_control_chars" default="false">
If [code]true[/code], control characters are displayed.
</member>
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index 7c00cf351c..272de725c8 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -1024,6 +1024,7 @@ void CodeTextEditor::update_editor_settings() {
text_editor->set_scroll_past_end_of_file_enabled(EditorSettings::get_singleton()->get("text_editor/behavior/navigation/scroll_past_end_of_file"));
text_editor->set_smooth_scroll_enabled(EditorSettings::get_singleton()->get("text_editor/behavior/navigation/smooth_scrolling"));
text_editor->set_v_scroll_speed(EditorSettings::get_singleton()->get("text_editor/behavior/navigation/v_scroll_speed"));
+ text_editor->set_drag_and_drop_selection_enabled(EditorSettings::get_singleton()->get("text_editor/behavior/navigation/drag_and_drop_selection"));
// Behavior: indent
text_editor->set_indent_using_spaces(EditorSettings::get_singleton()->get("text_editor/behavior/indent/type"));
diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp
index 97699d0349..9a1b2b5ff5 100644
--- a/editor/dependency_editor.cpp
+++ b/editor/dependency_editor.cpp
@@ -487,7 +487,7 @@ void DependencyRemoveDialog::show(const Vector<String> &p_folders, const Vector<
void DependencyRemoveDialog::ok_pressed() {
for (int i = 0; i < files_to_delete.size(); ++i) {
if (ResourceCache::has(files_to_delete[i])) {
- Resource *res = ResourceCache::get(files_to_delete[i]);
+ Ref<Resource> res = ResourceCache::get_ref(files_to_delete[i]);
res->set_path("");
}
diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp
index f9a4c14c48..adbba98897 100644
--- a/editor/editor_file_system.cpp
+++ b/editor/editor_file_system.cpp
@@ -1792,9 +1792,9 @@ Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector
//if file is currently up, maybe the source it was loaded from changed, so import math must be updated for it
//to reload properly
- if (ResourceCache::has(file)) {
- Resource *r = ResourceCache::get(file);
+ Ref<Resource> r = ResourceCache::get_ref(file);
+ if (r.is_valid()) {
if (!r->get_import_path().is_empty()) {
String dst_path = ResourceFormatImporter::get_singleton()->get_internal_resource_path(file);
r->set_import_path(dst_path);
@@ -2034,9 +2034,8 @@ void EditorFileSystem::_reimport_file(const String &p_file, const HashMap<String
//if file is currently up, maybe the source it was loaded from changed, so import math must be updated for it
//to reload properly
- if (ResourceCache::has(p_file)) {
- Resource *r = ResourceCache::get(p_file);
-
+ Ref<Resource> r = ResourceCache::get_ref(p_file);
+ if (r.is_valid()) {
if (!r->get_import_path().is_empty()) {
String dst_path = ResourceFormatImporter::get_singleton()->get_internal_resource_path(p_file);
r->set_import_path(dst_path);
diff --git a/editor/editor_folding.cpp b/editor/editor_folding.cpp
index 9e1b361f64..8c508494c0 100644
--- a/editor/editor_folding.cpp
+++ b/editor/editor_folding.cpp
@@ -193,10 +193,7 @@ void EditorFolding::load_scene_folding(Node *p_scene, const String &p_path) {
for (int i = 0; i < res_unfolds.size(); i += 2) {
String path2 = res_unfolds[i];
- Ref<Resource> res;
- if (ResourceCache::has(path2)) {
- res = Ref<Resource>(ResourceCache::get(path2));
- }
+ Ref<Resource> res = ResourceCache::get_ref(path2);
if (res.is_null()) {
continue;
}
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 93caf7944c..9b0ac305d1 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -881,7 +881,7 @@ void EditorNode::_resources_changed(const Vector<String> &p_resources) {
int rc = p_resources.size();
for (int i = 0; i < rc; i++) {
- Ref<Resource> res(ResourceCache::get(p_resources.get(i)));
+ Ref<Resource> res = ResourceCache::get_ref(p_resources.get(i));
if (res.is_null()) {
continue;
}
@@ -1011,8 +1011,8 @@ void EditorNode::_resources_reimported(const Vector<String> &p_resources) {
continue;
}
// Reload normally.
- Resource *resource = ResourceCache::get(p_resources[i]);
- if (resource) {
+ Ref<Resource> resource = ResourceCache::get_ref(p_resources[i]);
+ if (resource.is_valid()) {
resource->reload_from_file();
}
}
@@ -1725,7 +1725,7 @@ void EditorNode::_save_scene(String p_file, int idx) {
// We must update it, but also let the previous scene state go, as
// old version still work for referencing changes in instantiated or inherited scenes.
- sdata = Ref<PackedScene>(Object::cast_to<PackedScene>(ResourceCache::get(p_file)));
+ sdata = ResourceCache::get_ref(p_file);
if (sdata.is_valid()) {
sdata->recreate_state();
} else {
@@ -3717,7 +3717,7 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b
if (ResourceCache::has(lpath)) {
// Used from somewhere else? No problem! Update state and replace sdata.
- Ref<PackedScene> ps = Ref<PackedScene>(Object::cast_to<PackedScene>(ResourceCache::get(lpath)));
+ Ref<PackedScene> ps = ResourceCache::get_ref(lpath);
if (ps.is_valid()) {
ps->replace_state(sdata->get_state());
ps->set_last_modified_time(sdata->get_last_modified_time());
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index 61b434a240..2562c740aa 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -3601,7 +3601,7 @@ static EditorPropertyRangeHint _parse_range_hint(PropertyHint p_hint, const Stri
hint.greater = true;
} else if (slice == "or_lesser") {
hint.lesser = true;
- } else if (slice == "noslider") {
+ } else if (slice == "no_slider") {
hint.hide_slider = true;
} else if (slice == "exp") {
hint.exp_range = true;
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index db9193db06..ad9c547693 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -542,6 +542,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("text_editor/behavior/navigation/scroll_past_end_of_file", false);
_initial_set("text_editor/behavior/navigation/smooth_scrolling", true);
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "text_editor/behavior/navigation/v_scroll_speed", 80, "1,10000,1")
+ _initial_set("text_editor/behavior/navigation/drag_and_drop_selection", true);
// Behavior: Indent
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "text_editor/behavior/indent/type", 0, "Tabs,Spaces")
diff --git a/editor/icons/BaseButton.svg b/editor/icons/BaseButton.svg
new file mode 100644
index 0000000000..9aa0ae1c07
--- /dev/null
+++ b/editor/icons/BaseButton.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5.5 9c-.831 0-1.5.669-1.5 1.5v1.5h-2v2h12v-2h-2v-1.5c0-.831-.669-1.5-1.5-1.5z" fill="#8eef97"/></svg>
diff --git a/editor/icons/GeometryInstance3D.svg b/editor/icons/GeometryInstance3D.svg
new file mode 100644
index 0000000000..759d5fe413
--- /dev/null
+++ b/editor/icons/GeometryInstance3D.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7304688v6.5410152a2 2 0 0 0 -1 1.728516 2 2 0 0 0 2 2 2 2 0 0 0 1.7304688-1h6.5410152a2 2 0 0 0 1.728516 1 2 2 0 0 0 2-2 2 2 0 0 0 -1.03125-1.75h.03125v-6.5214844a2 2 0 0 0 1-1.7285156 2 2 0 0 0 -2-2 2 2 0 0 0 -1.730469 1h-6.5410154a2 2 0 0 0 -1.7285156-1zm1 3h1.4140625 3.5859375 2.271484a2 2 0 0 0 .728516.7304688v1.2695312 4.585938 1.414062h-1.414062-4.585938-1.2714844a2 2 0 0 0 -.7285156-.730469v-3.269531-2.5859375z" fill="#fc7f7f"/></svg>
diff --git a/editor/icons/ImporterMeshInstance3D.svg b/editor/icons/ImporterMeshInstance3D.svg
new file mode 100644
index 0000000000..7e7598ac2b
--- /dev/null
+++ b/editor/icons/ImporterMeshInstance3D.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fc7f7f"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7304688v6.5410152a2 2 0 0 0 -1 1.728516 2 2 0 0 0 2 2 2 2 0 0 0 1.7304688-1h6.5410152a2 2 0 0 0 1.728516 1 2 2 0 0 0 2-2 2 2 0 0 0 -1.03125-1.75h.03125v-6.5214844a2 2 0 0 0 1-1.7285156 2 2 0 0 0 -2-2 2 2 0 0 0 -1.730469 1h-6.5410154a2 2 0 0 0 -1.7285156-1zm1 3h1.4140625 3.5859375 2.271484a2 2 0 0 0 .728516.7304688v1.2695312 4.585938 1.414062h-1.414062-4.585938-1.2714844a2 2 0 0 0 -.7285156-.730469v-3.269531-2.5859375z"/><path d="m7 7h2v4h-2z"/><path d="m7 5h2v1h-2z"/></g></svg>
diff --git a/editor/icons/MultiplayerSpawner.svg b/editor/icons/MultiplayerSpawner.svg
new file mode 100644
index 0000000000..68ffd3aab4
--- /dev/null
+++ b/editor/icons/MultiplayerSpawner.svg
@@ -0,0 +1 @@
+<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><path style="fill:none;fill-opacity:.996078;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:16.5;stroke-opacity:1;paint-order:stroke markers fill" d="M4.936 7.429A4 4 0 0 1 8 6a4 4 0 0 1 3.064 1.429M1.872 4.858A8 8 0 0 1 8 2a8 8 0 0 1 6.128 2.858"/><path d="M7 9v2H5v2h2v2h2v-2h2v-2H9V9Z" fill="#5fff97"/></svg>
diff --git a/editor/icons/MultiplayerSynchronizer.svg b/editor/icons/MultiplayerSynchronizer.svg
new file mode 100644
index 0000000000..1547ec5a2b
--- /dev/null
+++ b/editor/icons/MultiplayerSynchronizer.svg
@@ -0,0 +1 @@
+<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><path style="fill:#5fff97;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" d="M5 10h3l-2 4-2-4Z"/><path style="fill:#ff5f5f;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" d="M9 14h3l-2-4-2 4Z"/><path style="fill:none;fill-opacity:.996078;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:16.5;stroke-opacity:1;paint-order:stroke markers fill" d="M4.936 7.429A4 4 0 0 1 8 6a4 4 0 0 1 3.064 1.429M1.872 4.858A8 8 0 0 1 8 2a8 8 0 0 1 6.128 2.858"/></svg>
diff --git a/editor/icons/Range.svg b/editor/icons/Range.svg
new file mode 100644
index 0000000000..49311546b0
--- /dev/null
+++ b/editor/icons/Range.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.8027344 2.7714844c-1.0905892.2029663-1.089037 1.7659969.00195 1.9667968l2.8808595.5761719.576172 2.8808594c.231158 1.3504655 2.264924.9453327 1.960937-.390625l-.7070279-3.5371094c-.039663-.1968491-.137665-.3771998-.28125-.5175781-.138135-.1351849-.312483-.2274468-.501953-.265625l-3.5371095-.7070312c-.1291868-.0278728-.262617-.0298643-.3925781-.0058594zm-3.9941406 4.2167968c-.6571498-.0349349-1.1683412.5633914-1.03125 1.2070313l.7070312 3.5371095c.079467.394998.3882047.703736.7832031.783203l3.5371094.707031c1.3359577.303987 1.7410905-1.729779.390625-1.960937l-2.8808594-.576172-.5761719-2.8808595c-.0369237-.1982539-.1329195-.3807141-.2753906-.5234375-.1744016-.1751556-.407488-.2795227-.6542968-.2929688z" fill="#8eef97"/></svg>
diff --git a/editor/icons/VisualInstance3D.svg b/editor/icons/VisualInstance3D.svg
new file mode 100644
index 0000000000..e5e43b59dd
--- /dev/null
+++ b/editor/icons/VisualInstance3D.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fc7f7f"><circle cx="3" cy="3" r="2"/><circle cx="13" cy="3" r="2"/><circle cx="13" cy="13" r="2"/><circle cx="3" cy="13" r="2"/></g></svg>
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index f2975b1d7a..171ef5bf4c 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -1115,7 +1115,7 @@ Ref<Animation> ResourceImporterScene::_save_animation_to_file(Ref<Animation> ani
}
if (ResourceCache::has(p_save_to_path)) {
- Ref<Animation> old_anim = Ref<Resource>(ResourceCache::get(p_save_to_path));
+ Ref<Animation> old_anim = ResourceCache::get_ref(p_save_to_path);
if (old_anim.is_valid()) {
old_anim->copy_from(anim);
anim = old_anim;
@@ -1711,7 +1711,7 @@ void ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_m
}
if (!save_to_file.is_empty()) {
- Ref<Mesh> existing = Ref<Resource>(ResourceCache::get(save_to_file));
+ Ref<Mesh> existing = ResourceCache::get_ref(save_to_file);
if (existing.is_valid()) {
//if somehow an existing one is useful, create
existing->reset_state();
diff --git a/editor/import/resource_importer_texture_atlas.cpp b/editor/import/resource_importer_texture_atlas.cpp
index aa338a6c0d..e5fe99890e 100644
--- a/editor/import/resource_importer_texture_atlas.cpp
+++ b/editor/import/resource_importer_texture_atlas.cpp
@@ -306,10 +306,8 @@ Error ResourceImporterTextureAtlas::import_group_file(const String &p_group_file
//update cache if existing, else create
Ref<Texture2D> cache;
- if (ResourceCache::has(p_group_file)) {
- Resource *resptr = ResourceCache::get(p_group_file);
- cache.reference_ptr(resptr);
- } else {
+ cache = ResourceCache::get_ref(p_group_file);
+ if (!cache.is_valid()) {
Ref<ImageTexture> res_cache;
res_cache.instantiate();
res_cache->create_from_image(new_atlas);
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 1ea0299d4e..dea4aaded7 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -5455,7 +5455,7 @@ void CanvasItemEditorViewport::_create_nodes(Node *parent, Node *child, String &
}
child->set_name(name);
- Ref<Texture2D> texture = Ref<Texture2D>(Object::cast_to<Texture2D>(ResourceCache::get(path)));
+ Ref<Texture2D> texture = ResourceCache::get_ref(path);
if (parent) {
editor_data->get_undo_redo().add_do_method(parent, "add_child", child, true);
diff --git a/editor/quick_open.cpp b/editor/quick_open.cpp
index 53da945868..4938699fc4 100644
--- a/editor/quick_open.cpp
+++ b/editor/quick_open.cpp
@@ -146,8 +146,8 @@ void EditorQuickOpen::_confirmed() {
return;
}
_cleanup();
- emit_signal(SNAME("quick_open"));
hide();
+ emit_signal(SNAME("quick_open"));
}
void EditorQuickOpen::cancel_pressed() {
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index 5345143271..474c8094f2 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -746,7 +746,7 @@ static void _find_annotation_arguments(const GDScriptParser::AnnotationNode *p_a
ScriptLanguage::CodeCompletionOption slider2("or_lesser", ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
slider2.insert_text = slider2.display.quote(p_quote_style);
r_result.insert(slider2.display, slider2);
- ScriptLanguage::CodeCompletionOption slider3("noslider", ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
+ ScriptLanguage::CodeCompletionOption slider3("no_slider", ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
slider3.insert_text = slider3.display.quote(p_quote_style);
r_result.insert(slider3.display, slider3);
}
diff --git a/modules/visual_script/visual_script_flow_control.cpp b/modules/visual_script/visual_script_flow_control.cpp
index bbbb995635..19bbd834cc 100644
--- a/modules/visual_script/visual_script_flow_control.cpp
+++ b/modules/visual_script/visual_script_flow_control.cpp
@@ -803,7 +803,7 @@ public:
//if the script is not in use by anyone, we can safely assume whatever we got is not casting to it.
return 1;
}
- Ref<Script> cast_script = Ref<Resource>(ResourceCache::get(script));
+ Ref<Script> cast_script = ResourceCache::get_ref(script);
if (!cast_script.is_valid()) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = "Script path is not a script: " + script;
diff --git a/modules/visual_script/visual_script_func_nodes.cpp b/modules/visual_script/visual_script_func_nodes.cpp
index 483fc8b6c3..b16358ae38 100644
--- a/modules/visual_script/visual_script_func_nodes.cpp
+++ b/modules/visual_script/visual_script_func_nodes.cpp
@@ -377,7 +377,7 @@ void VisualScriptFunctionCall::_update_method_cache() {
}
if (ResourceCache::has(base_script)) {
- script = Ref<Resource>(ResourceCache::get(base_script));
+ script = ResourceCache::get_ref(base_script);
} else {
return;
}
@@ -587,7 +587,7 @@ void VisualScriptFunctionCall::_validate_property(PropertyInfo &property) const
}
if (ResourceCache::has(base_script)) {
- Ref<Script> script = Ref<Resource>(ResourceCache::get(base_script));
+ Ref<Script> script = ResourceCache::get_ref(base_script);
if (script.is_valid()) {
property.hint = PROPERTY_HINT_METHOD_OF_SCRIPT;
property.hint_string = itos(script->get_instance_id());
@@ -1178,7 +1178,7 @@ void VisualScriptPropertySet::_update_cache() {
}
if (ResourceCache::has(base_script)) {
- script = Ref<Resource>(ResourceCache::get(base_script));
+ script = ResourceCache::get_ref(base_script);
} else {
return;
}
@@ -1338,7 +1338,7 @@ void VisualScriptPropertySet::_validate_property(PropertyInfo &property) const {
}
if (ResourceCache::has(base_script)) {
- Ref<Script> script = Ref<Resource>(ResourceCache::get(base_script));
+ Ref<Script> script = ResourceCache::get_ref(base_script);
if (script.is_valid()) {
property.hint = PROPERTY_HINT_PROPERTY_OF_SCRIPT;
property.hint_string = itos(script->get_instance_id());
@@ -1864,7 +1864,7 @@ void VisualScriptPropertyGet::_update_cache() {
}
if (ResourceCache::has(base_script)) {
- script = Ref<Resource>(ResourceCache::get(base_script));
+ script = ResourceCache::get_ref(base_script);
} else {
return;
}
@@ -2044,7 +2044,7 @@ void VisualScriptPropertyGet::_validate_property(PropertyInfo &property) const {
}
if (ResourceCache::has(base_script)) {
- Ref<Script> script = Ref<Resource>(ResourceCache::get(base_script));
+ Ref<Script> script = ResourceCache::get_ref(base_script);
if (script.is_valid()) {
property.hint = PROPERTY_HINT_PROPERTY_OF_SCRIPT;
property.hint_string = itos(script->get_instance_id());
diff --git a/platform/android/android_input_handler.cpp b/platform/android/android_input_handler.cpp
index 10f23b320b..81802298d9 100644
--- a/platform/android/android_input_handler.cpp
+++ b/platform/android/android_input_handler.cpp
@@ -381,13 +381,3 @@ MouseButton AndroidInputHandler::_android_button_mask_to_godot_button_mask(int a
return godot_button_mask;
}
-
-void AndroidInputHandler::process_scroll(Point2 p_pos) {
- Ref<InputEventPanGesture> ev;
- ev.instantiate();
- _set_key_modifier_state(ev);
- ev->set_position(p_pos);
- ev->set_delta(p_pos - scroll_prev_pos);
- Input::get_singleton()->parse_input_event(ev);
- scroll_prev_pos = p_pos;
-}
diff --git a/platform/android/android_input_handler.h b/platform/android/android_input_handler.h
index e9c0ec1475..1397ca59e4 100644
--- a/platform/android/android_input_handler.h
+++ b/platform/android/android_input_handler.h
@@ -69,7 +69,6 @@ private:
Vector<TouchPos> touch;
Point2 hover_prev_pos; // needed to calculate the relative position on hover events
- Point2 scroll_prev_pos; // needed to calculate the relative position on scroll events
void _set_key_modifier_state(Ref<InputEventWithModifiers> ev);
@@ -83,7 +82,6 @@ public:
void process_hover(int p_type, Point2 p_pos);
void process_mouse_event(int input_device, int event_action, int event_android_buttons_mask, Point2 event_pos, float event_vertical_factor = 0, float event_horizontal_factor = 0);
void process_double_tap(int event_android_button_mask, Point2 p_pos);
- void process_scroll(Point2 p_pos);
void process_joy_event(JoypadEvent p_event);
void process_key_event(int p_keycode, int p_scancode, int p_unicode_char, bool p_pressed);
};
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
index 1f8f8c82a6..3182ab0666 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
@@ -114,11 +114,6 @@ public class GodotLib {
public static native void doubleTap(int buttonMask, int x, int y);
/**
- * Forward scroll events from the main thread to the GL thread.
- */
- public static native void scroll(int x, int y);
-
- /**
* Forward accelerometer sensor events from the main thread to the GL thread.
* @see android.hardware.SensorEventListener#onSensorChanged(SensorEvent)
*/
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java
index ac13cad23e..778efa914a 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java
@@ -80,15 +80,6 @@ public class GodotGestureHandler extends GestureDetector.SimpleOnGestureListener
}
@Override
- public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
- //Log.i("GodotGesture", "onScroll");
- final int x = Math.round(distanceX);
- final int y = Math.round(distanceY);
- GodotLib.scroll(x, y);
- return true;
- }
-
- @Override
public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) {
//Log.i("GodotGesture", "onFling");
return true;
diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp
index de666f1b11..eaffe14b13 100644
--- a/platform/android/java_godot_lib_jni.cpp
+++ b/platform/android/java_godot_lib_jni.cpp
@@ -306,15 +306,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_doubleTap(JNIEnv *env
}
// Called on the UI thread
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_scroll(JNIEnv *env, jclass clazz, jint p_x, jint p_y) {
- if (step.get() <= 0) {
- return;
- }
-
- input_handler->process_scroll(Point2(p_x, p_y));
-}
-
-// Called on the UI thread
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env, jclass clazz, jint p_device, jint p_button, jboolean p_pressed) {
if (step.get() <= 0) {
return;
diff --git a/platform/android/java_godot_lib_jni.h b/platform/android/java_godot_lib_jni.h
index e1d30eea77..aa8d67cf46 100644
--- a/platform/android/java_godot_lib_jni.h
+++ b/platform/android/java_godot_lib_jni.h
@@ -51,7 +51,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch__IIII_3FI(JNIEn
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch__IIII_3FIFF(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray positions, jint buttons_mask, jfloat vertical_factor, jfloat horizontal_factor);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_hover(JNIEnv *env, jclass clazz, jint p_type, jfloat p_x, jfloat p_y);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_doubleTap(JNIEnv *env, jclass clazz, jint p_button_mask, jint p_x, jint p_y);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_scroll(JNIEnv *env, jclass clazz, jint p_x, jint p_y);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jclass clazz, jint p_keycode, jint p_scancode, jint p_unicode_char, jboolean p_pressed);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env, jclass clazz, jint p_device, jint p_button, jboolean p_pressed);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, jclass clazz, jint p_device, jint p_axis, jfloat p_value);
diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp
index b2b848d380..4599785ce4 100644
--- a/scene/2d/node_2d.cpp
+++ b/scene/2d/node_2d.cpp
@@ -437,7 +437,7 @@ void Node2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_relative_transform_to_parent", "parent"), &Node2D::get_relative_transform_to_parent);
ADD_GROUP("Transform", "");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position", PROPERTY_HINT_RANGE, "-99999,99999,0.001,or_lesser,or_greater,noslider,suffix:px"), "set_position", "get_position");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position", PROPERTY_HINT_RANGE, "-99999,99999,0.001,or_lesser,or_greater,no_slider,suffix:px"), "set_position", "get_position");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians"), "set_rotation", "get_rotation");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scale", PROPERTY_HINT_LINK), "set_scale", "get_scale");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "skew", PROPERTY_HINT_RANGE, "-89.9,89.9,0.1,radians"), "set_skew", "get_skew");
diff --git a/scene/3d/lightmap_gi.cpp b/scene/3d/lightmap_gi.cpp
index 74ac96c6cc..abe942b97a 100644
--- a/scene/3d/lightmap_gi.cpp
+++ b/scene/3d/lightmap_gi.cpp
@@ -116,7 +116,7 @@ void LightmapGIData::_set_light_textures_data(const Array &p_data) {
Array LightmapGIData::_get_light_textures_data() const {
Array ret;
- if (light_texture.is_null()) {
+ if (light_texture.is_null() || light_texture->get_layers() == 0) {
return ret;
}
diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp
index 6e36815f2b..60858b00b1 100644
--- a/scene/3d/node_3d.cpp
+++ b/scene/3d/node_3d.cpp
@@ -980,7 +980,7 @@ void Node3D::_bind_methods() {
ADD_GROUP("Transform", "");
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "transform", PROPERTY_HINT_NONE, "suffix:m", PROPERTY_USAGE_NO_EDITOR), "set_transform", "get_transform");
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "global_transform", PROPERTY_HINT_NONE, "suffix:m", PROPERTY_USAGE_NONE), "set_global_transform", "get_global_transform");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "position", PROPERTY_HINT_RANGE, "-99999,99999,0.001,or_greater,or_lesser,noslider,suffix:m", PROPERTY_USAGE_EDITOR), "set_position", "get_position");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "position", PROPERTY_HINT_RANGE, "-99999,99999,0.001,or_greater,or_lesser,no_slider,suffix:m", PROPERTY_USAGE_EDITOR), "set_position", "get_position");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians", PROPERTY_USAGE_EDITOR), "set_rotation", "get_rotation");
ADD_PROPERTY(PropertyInfo(Variant::QUATERNION, "quaternion", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_quaternion", "get_quaternion");
ADD_PROPERTY(PropertyInfo(Variant::BASIS, "basis", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_basis", "get_basis");
diff --git a/scene/debugger/scene_debugger.cpp b/scene/debugger/scene_debugger.cpp
index a54e728c1b..e9c33b1839 100644
--- a/scene/debugger/scene_debugger.cpp
+++ b/scene/debugger/scene_debugger.cpp
@@ -701,7 +701,7 @@ void LiveEditor::_res_set_func(int p_id, const StringName &p_prop, const Variant
return;
}
- Ref<Resource> r = ResourceCache::get(resp);
+ Ref<Resource> r = ResourceCache::get_ref(resp);
if (!r.is_valid()) {
return;
}
@@ -728,7 +728,7 @@ void LiveEditor::_res_call_func(int p_id, const StringName &p_method, const Vari
return;
}
- Ref<Resource> r = ResourceCache::get(resp);
+ Ref<Resource> r = ResourceCache::get_ref(resp);
if (!r.is_valid()) {
return;
}
diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp
index 192d214262..a2b05ee50d 100644
--- a/scene/gui/dialogs.cpp
+++ b/scene/gui/dialogs.cpp
@@ -262,7 +262,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.is_empty()) {
- c = TTRC("Cancel");
+ c = RTR("Cancel");
}
Button *b = swap_cancel_ok ? add_button(c, true) : add_button(c);
b->connect("pressed", callable_mp(this, &AcceptDialog::_cancel_pressed));
@@ -349,7 +349,7 @@ AcceptDialog::AcceptDialog() {
hbc->add_spacer();
ok = memnew(Button);
- ok->set_text(TTRC("OK"));
+ ok->set_text(RTR("OK"));
hbc->add_child(ok);
hbc->add_spacer();
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 1725816c31..0e0f8bde83 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -337,7 +337,7 @@ void FileDialog::_action_pressed() {
}
if (dir_access->file_exists(f)) {
- confirm_save->set_text(TTRC("File exists, overwrite?"));
+ confirm_save->set_text(RTR("File exists, overwrite?"));
confirm_save->popup_centered(Size2(200, 80));
} else {
emit_signal(SNAME("file_selected"), f);
@@ -423,10 +423,10 @@ void FileDialog::deselect_all() {
switch (mode) {
case FILE_MODE_OPEN_FILE:
case FILE_MODE_OPEN_FILES:
- get_ok_button()->set_text(TTRC("Open"));
+ get_ok_button()->set_text(RTR("Open"));
break;
case FILE_MODE_OPEN_DIR:
- get_ok_button()->set_text(TTRC("Select Current Folder"));
+ get_ok_button()->set_text(RTR("Select Current Folder"));
break;
case FILE_MODE_OPEN_ANY:
case FILE_MODE_SAVE_FILE:
@@ -450,7 +450,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(TTRC("Select This Folder"));
+ get_ok_button()->set_text(RTR("Select This Folder"));
}
get_ok_button()->set_disabled(_is_open_should_be_disabled());
@@ -502,7 +502,7 @@ void FileDialog::update_file_list() {
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->set_text(RTR("You don't have permission to access contents of this folder."));
message->show();
}
@@ -746,35 +746,35 @@ void FileDialog::set_file_mode(FileMode p_mode) {
mode = p_mode;
switch (mode) {
case FILE_MODE_OPEN_FILE:
- get_ok_button()->set_text(TTRC("Open"));
+ get_ok_button()->set_text(RTR("Open"));
if (mode_overrides_title) {
set_title(TTRC("Open a File"));
}
makedir->hide();
break;
case FILE_MODE_OPEN_FILES:
- get_ok_button()->set_text(TTRC("Open"));
+ get_ok_button()->set_text(RTR("Open"));
if (mode_overrides_title) {
set_title(TTRC("Open File(s)"));
}
makedir->hide();
break;
case FILE_MODE_OPEN_DIR:
- get_ok_button()->set_text(TTRC("Select Current Folder"));
+ get_ok_button()->set_text(RTR("Select Current Folder"));
if (mode_overrides_title) {
set_title(TTRC("Open a Directory"));
}
makedir->show();
break;
case FILE_MODE_OPEN_ANY:
- get_ok_button()->set_text(TTRC("Open"));
+ get_ok_button()->set_text(RTR("Open"));
if (mode_overrides_title) {
set_title(TTRC("Open a File or Directory"));
}
makedir->show();
break;
case FILE_MODE_SAVE_FILE:
- get_ok_button()->set_text(TTRC("Save"));
+ get_ok_button()->set_text(RTR("Save"));
if (mode_overrides_title) {
set_title(TTRC("Save a File"));
}
@@ -964,13 +964,13 @@ FileDialog::FileDialog() {
dir_prev = memnew(Button);
dir_prev->set_flat(true);
- dir_prev->set_tooltip(TTRC("Go to previous folder."));
+ dir_prev->set_tooltip(RTR("Go to previous folder."));
dir_next = memnew(Button);
dir_next->set_flat(true);
- dir_next->set_tooltip(TTRC("Go to next folder."));
+ dir_next->set_tooltip(RTR("Go to next folder."));
dir_up = memnew(Button);
dir_up->set_flat(true);
- dir_up->set_tooltip(TTRC("Go to parent folder."));
+ dir_up->set_tooltip(RTR("Go to parent folder."));
hbc->add_child(dir_prev);
hbc->add_child(dir_next);
hbc->add_child(dir_up);
@@ -978,7 +978,7 @@ FileDialog::FileDialog() {
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(TTRC("Path:"))));
+ hbc->add_child(memnew(Label(RTR("Path:"))));
drives_container = memnew(HBoxContainer);
hbc->add_child(drives_container);
@@ -994,7 +994,7 @@ FileDialog::FileDialog() {
refresh = memnew(Button);
refresh->set_flat(true);
- refresh->set_tooltip(TTRC("Refresh files."));
+ refresh->set_tooltip(RTR("Refresh files."));
refresh->connect("pressed", callable_mp(this, &FileDialog::update_file_list));
hbc->add_child(refresh);
@@ -1002,7 +1002,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(TTRC("Toggle the visibility of hidden files."));
+ show_hidden->set_tooltip(RTR("Toggle the visibility of hidden files."));
show_hidden->connect("toggled", callable_mp(this, &FileDialog::set_show_hidden_files));
hbc->add_child(show_hidden);
@@ -1010,14 +1010,14 @@ FileDialog::FileDialog() {
hbc->add_child(shortcuts_container);
makedir = memnew(Button);
- makedir->set_text(TTRC("Create Folder"));
+ makedir->set_text(RTR("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(TTRC("Directories & Files:"), tree, true);
+ vbox->add_margin_child(RTR("Directories & Files:"), tree, true);
message = memnew(Label);
message->hide();
@@ -1027,7 +1027,7 @@ FileDialog::FileDialog() {
tree->add_child(message);
file_box = memnew(HBoxContainer);
- file_box->add_child(memnew(Label(TTRC("File:"))));
+ file_box->add_child(memnew(Label(RTR("File:"))));
file = memnew(LineEdit);
file->set_structured_text_bidi_override(TextServer::STRUCTURED_TEXT_FILE);
file->set_stretch_ratio(4);
@@ -1058,22 +1058,22 @@ FileDialog::FileDialog() {
confirm_save->connect("confirmed", callable_mp(this, &FileDialog::_save_confirm_pressed));
makedialog = memnew(ConfirmationDialog);
- makedialog->set_title(TTRC("Create Folder"));
+ makedialog->set_title(RTR("Create Folder"));
VBoxContainer *makevb = memnew(VBoxContainer);
makedialog->add_child(makevb);
makedirname = memnew(LineEdit);
makedirname->set_structured_text_bidi_override(TextServer::STRUCTURED_TEXT_FILE);
- makevb->add_margin_child(TTRC("Name:"), makedirname);
+ makevb->add_margin_child(RTR("Name:"), makedirname);
add_child(makedialog, false, INTERNAL_MODE_FRONT);
makedialog->register_text_enter(makedirname);
makedialog->connect("confirmed", callable_mp(this, &FileDialog::_make_dir_confirm));
mkdirerr = memnew(AcceptDialog);
- mkdirerr->set_text(TTRC("Could not create folder."));
+ mkdirerr->set_text(RTR("Could not create folder."));
add_child(mkdirerr, false, INTERNAL_MODE_FRONT);
exterr = memnew(AcceptDialog);
- exterr->set_text(TTRC("Must use a valid extension."));
+ exterr->set_text(RTR("Must use a valid extension."));
add_child(exterr, false, INTERNAL_MODE_FRONT);
update_filters();
diff --git a/scene/gui/progress_bar.cpp b/scene/gui/progress_bar.cpp
index f36682942f..80859e8eb9 100644
--- a/scene/gui/progress_bar.cpp
+++ b/scene/gui/progress_bar.cpp
@@ -126,7 +126,11 @@ int ProgressBar::get_fill_mode() {
}
void ProgressBar::set_percent_visible(bool p_visible) {
+ if (percent_visible == p_visible) {
+ return;
+ }
percent_visible = p_visible;
+ update_minimum_size();
update();
}
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index 8299d73b68..fa929344d4 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -727,6 +727,7 @@ void TabContainer::set_tab_hidden(int p_tab, bool p_hidden) {
if (!get_clip_tabs()) {
update_minimum_size();
}
+ call_deferred(SNAME("_repaint"));
}
bool TabContainer::is_tab_hidden(int p_tab) const {
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index d9a91590f7..5506616b7a 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -1723,7 +1723,7 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
update();
}
- } else if (is_mouse_over_selection()) {
+ } else if (drag_and_drop_selection_enabled && is_mouse_over_selection()) {
selection.selecting_mode = SelectionMode::SELECTION_MODE_NONE;
selection.drag_attempt = true;
} else {
@@ -4163,6 +4163,14 @@ bool TextEdit::is_deselect_on_focus_loss_enabled() const {
return deselect_on_focus_loss_enabled;
}
+void TextEdit::set_drag_and_drop_selection_enabled(const bool p_enabled) {
+ drag_and_drop_selection_enabled = p_enabled;
+}
+
+bool TextEdit::is_drag_and_drop_selection_enabled() const {
+ return drag_and_drop_selection_enabled;
+}
+
void TextEdit::set_override_selected_font_color(bool p_override_selected_font_color) {
override_selected_font_color = p_override_selected_font_color;
}
@@ -5243,6 +5251,9 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_deselect_on_focus_loss_enabled", "enable"), &TextEdit::set_deselect_on_focus_loss_enabled);
ClassDB::bind_method(D_METHOD("is_deselect_on_focus_loss_enabled"), &TextEdit::is_deselect_on_focus_loss_enabled);
+ ClassDB::bind_method(D_METHOD("set_drag_and_drop_selection_enabled", "enable"), &TextEdit::set_drag_and_drop_selection_enabled);
+ ClassDB::bind_method(D_METHOD("is_drag_and_drop_selection_enabled"), &TextEdit::is_drag_and_drop_selection_enabled);
+
ClassDB::bind_method(D_METHOD("set_override_selected_font_color", "override"), &TextEdit::set_override_selected_font_color);
ClassDB::bind_method(D_METHOD("is_overriding_selected_font_color"), &TextEdit::is_overriding_selected_font_color);
@@ -5405,6 +5416,7 @@ void TextEdit::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shortcut_keys_enabled"), "set_shortcut_keys_enabled", "is_shortcut_keys_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selecting_enabled"), "set_selecting_enabled", "is_selecting_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "deselect_on_focus_loss_enabled"), "set_deselect_on_focus_loss_enabled", "is_deselect_on_focus_loss_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "drag_and_drop_selection_enabled"), "set_drag_and_drop_selection_enabled", "is_drag_and_drop_selection_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "virtual_keyboard_enabled"), "set_virtual_keyboard_enabled", "is_virtual_keyboard_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "middle_mouse_paste_enabled"), "set_middle_mouse_paste_enabled", "is_middle_mouse_paste_enabled");
ADD_PROPERTY(PropertyInfo(Variant::INT, "wrap_mode", PROPERTY_HINT_ENUM, "None,Boundary"), "set_line_wrapping_mode", "get_line_wrapping_mode");
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index 993203bee6..9de2982d0a 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -422,6 +422,7 @@ private:
bool selecting_enabled = true;
bool deselect_on_focus_loss_enabled = true;
+ bool drag_and_drop_selection_enabled = true;
Color font_selected_color = Color(1, 1, 1);
Color selection_color = Color(1, 1, 1);
@@ -795,6 +796,9 @@ public:
void set_deselect_on_focus_loss_enabled(const bool p_enabled);
bool is_deselect_on_focus_loss_enabled() const;
+ void set_drag_and_drop_selection_enabled(const bool p_enabled);
+ bool is_drag_and_drop_selection_enabled() const;
+
void set_override_selected_font_color(bool p_override_selected_font_color);
bool is_overriding_selected_font_color() const;
diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp
index b2fd8eb895..f4fd81b25f 100644
--- a/scene/resources/primitive_meshes.cpp
+++ b/scene/resources/primitive_meshes.cpp
@@ -439,12 +439,15 @@ void CapsuleMesh::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater,suffix:m"), "set_height", "get_height");
ADD_PROPERTY(PropertyInfo(Variant::INT, "radial_segments", PROPERTY_HINT_RANGE, "1,100,1,or_greater"), "set_radial_segments", "get_radial_segments");
ADD_PROPERTY(PropertyInfo(Variant::INT, "rings", PROPERTY_HINT_RANGE, "1,100,1,or_greater"), "set_rings", "get_rings");
+
+ ADD_LINKED_PROPERTY("radius", "height");
+ ADD_LINKED_PROPERTY("height", "radius");
}
void CapsuleMesh::set_radius(const float p_radius) {
radius = p_radius;
if (radius > height * 0.5) {
- radius = height * 0.5;
+ height = radius * 2.0;
}
_request_update();
}
@@ -456,7 +459,7 @@ float CapsuleMesh::get_radius() const {
void CapsuleMesh::set_height(const float p_height) {
height = p_height;
if (radius > height * 0.5) {
- height = radius * 2;
+ radius = height * 0.5;
}
_request_update();
}
diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp
index dba53338eb..3cda2f05b2 100644
--- a/scene/resources/resource_format_text.cpp
+++ b/scene/resources/resource_format_text.cpp
@@ -526,9 +526,9 @@ Error ResourceLoaderText::load() {
if (cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE && ResourceCache::has(path)) {
//reuse existing
- Resource *r = ResourceCache::get(path);
- if (r && r->get_class() == type) {
- res = Ref<Resource>(r);
+ Ref<Resource> cache = ResourceCache::get_ref(path);
+ if (cache.is_valid() && cache->get_class() == type) {
+ res = cache;
res->reset_state();
do_assign = true;
}
@@ -537,10 +537,10 @@ Error ResourceLoaderText::load() {
MissingResource *missing_resource = nullptr;
if (res.is_null()) { //not reuse
- if (cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE && ResourceCache::has(path)) { //only if it doesn't exist
+ Ref<Resource> cache = ResourceCache::get_ref(path);
+ if (cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE && cache.is_valid()) { //only if it doesn't exist
//cached, do not assign
- Resource *r = ResourceCache::get(path);
- res = Ref<Resource>(r);
+ res = cache;
} else {
//create
@@ -650,12 +650,10 @@ Error ResourceLoaderText::load() {
return error;
}
- if (cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE && ResourceCache::has(local_path)) {
- Resource *r = ResourceCache::get(local_path);
- if (r->get_class() == res_type) {
- r->reset_state();
- resource = Ref<Resource>(r);
- }
+ Ref<Resource> cache = ResourceCache::get_ref(local_path);
+ if (cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE && cache.is_valid() && cache->get_class() == res_type) {
+ cache->reset_state();
+ resource = cache;
}
MissingResource *missing_resource = nullptr;
diff --git a/servers/rendering/renderer_rd/effects/copy_effects.cpp b/servers/rendering/renderer_rd/effects/copy_effects.cpp
index aa42643699..c30e8ed58f 100644
--- a/servers/rendering/renderer_rd/effects/copy_effects.cpp
+++ b/servers/rendering/renderer_rd/effects/copy_effects.cpp
@@ -1029,7 +1029,7 @@ void CopyEffects::cubemap_roughness(RID p_source_rd_texture, RID p_dest_texture,
RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_mipmap_sampler, p_source_rd_texture }));
RD::Uniform u_dest_texture(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_dest_texture }));
- RID shader = roughness.compute_shader.version_get_shader(filter.shader_version, 0);
+ RID shader = roughness.compute_shader.version_get_shader(roughness.shader_version, 0);
ERR_FAIL_COND(shader.is_null());
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
@@ -1070,7 +1070,7 @@ void CopyEffects::cubemap_roughness_raster(RID p_source_rd_texture, RID p_dest_f
RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));
- RID shader = roughness.raster_shader.version_get_shader(filter.shader_version, 0);
+ RID shader = roughness.raster_shader.version_get_shader(roughness.shader_version, 0);
ERR_FAIL_COND(shader.is_null());
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);