summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/classes/FileSystemDock.xml5
-rw-r--r--editor/dependency_editor.cpp12
-rw-r--r--editor/filesystem_dock.cpp6
-rw-r--r--editor/filesystem_dock.h1
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp187
-rw-r--r--editor/plugins/visual_shader_editor_plugin.h11
6 files changed, 176 insertions, 46 deletions
diff --git a/doc/classes/FileSystemDock.xml b/doc/classes/FileSystemDock.xml
index 00f5c7ddff..f76bc2c279 100644
--- a/doc/classes/FileSystemDock.xml
+++ b/doc/classes/FileSystemDock.xml
@@ -51,5 +51,10 @@
<description>
</description>
</signal>
+ <signal name="resource_removed">
+ <param index="0" name="resource" type="Resource" />
+ <description>
+ </description>
+ </signal>
</signals>
</class>
diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp
index a925e2d1d3..c98ec7b2d5 100644
--- a/editor/dependency_editor.cpp
+++ b/editor/dependency_editor.cpp
@@ -536,12 +536,17 @@ 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])) {
- Ref<Resource> res = ResourceCache::get_ref(files_to_delete[i]);
+ for (const KeyValue<String, String> &E : all_remove_files) {
+ String file = E.key;
+
+ if (ResourceCache::has(file)) {
+ Ref<Resource> res = ResourceCache::get_ref(file);
+ emit_signal(SNAME("resource_removed"), res);
res->set_path("");
}
+ }
+ for (int i = 0; i < files_to_delete.size(); ++i) {
// If the file we are deleting for e.g. the main scene, default environment,
// or audio bus layout, we must clear its definition in Project Settings.
if (files_to_delete[i] == String(GLOBAL_GET("application/config/icon"))) {
@@ -621,6 +626,7 @@ void DependencyRemoveDialog::ok_pressed() {
}
void DependencyRemoveDialog::_bind_methods() {
+ ADD_SIGNAL(MethodInfo("resource_removed", PropertyInfo(Variant::OBJECT, "obj")));
ADD_SIGNAL(MethodInfo("file_removed", PropertyInfo(Variant::STRING, "file")));
ADD_SIGNAL(MethodInfo("folder_removed", PropertyInfo(Variant::STRING, "folder")));
}
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index f41792af7f..70a6ded690 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -1531,6 +1531,10 @@ void FileSystemDock::_make_scene_confirm() {
EditorNode::get_singleton()->save_scene_list({ scene_path });
}
+void FileSystemDock::_resource_removed(const Ref<Resource> &p_resource) {
+ emit_signal(SNAME("resource_removed"), p_resource);
+}
+
void FileSystemDock::_file_removed(String p_file) {
emit_signal(SNAME("file_removed"), p_file);
@@ -3077,6 +3081,7 @@ void FileSystemDock::_bind_methods() {
ADD_SIGNAL(MethodInfo("inherit", PropertyInfo(Variant::STRING, "file")));
ADD_SIGNAL(MethodInfo("instantiate", PropertyInfo(Variant::PACKED_STRING_ARRAY, "files")));
+ ADD_SIGNAL(MethodInfo("resource_removed", PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource")));
ADD_SIGNAL(MethodInfo("file_removed", PropertyInfo(Variant::STRING, "file")));
ADD_SIGNAL(MethodInfo("folder_removed", PropertyInfo(Variant::STRING, "folder")));
ADD_SIGNAL(MethodInfo("files_moved", PropertyInfo(Variant::STRING, "old_file"), PropertyInfo(Variant::STRING, "new_file")));
@@ -3235,6 +3240,7 @@ FileSystemDock::FileSystemDock() {
add_child(owners_editor);
remove_dialog = memnew(DependencyRemoveDialog);
+ remove_dialog->connect("resource_removed", callable_mp(this, &FileSystemDock::_resource_removed));
remove_dialog->connect("file_removed", callable_mp(this, &FileSystemDock::_file_removed));
remove_dialog->connect("folder_removed", callable_mp(this, &FileSystemDock::_folder_removed));
add_child(remove_dialog);
diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h
index 3f12b73043..08fb63dfe4 100644
--- a/editor/filesystem_dock.h
+++ b/editor/filesystem_dock.h
@@ -227,6 +227,7 @@ private:
void _update_favorites_list_after_move(const HashMap<String, String> &p_files_renames, const HashMap<String, String> &p_folders_renames) const;
void _update_project_settings_after_move(const HashMap<String, String> &p_renames) const;
+ void _resource_removed(const Ref<Resource> &p_resource);
void _file_removed(String p_file);
void _folder_removed(String p_folder);
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 96b1ad7ee0..dc19870f70 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -40,6 +40,7 @@
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
+#include "editor/filesystem_dock.h"
#include "editor/inspector_dock.h"
#include "editor/plugins/curve_editor_plugin.h"
#include "editor/plugins/shader_editor_plugin.h"
@@ -1271,18 +1272,55 @@ Dictionary VisualShaderEditor::get_custom_node_data(Ref<VisualShaderNodeCustom>
return dict;
}
-void VisualShaderEditor::update_custom_type(const Ref<Resource> &p_resource) {
- Ref<Script> scr = Ref<Script>(p_resource.ptr());
- if (scr.is_null() || scr->get_instance_base_type() != "VisualShaderNodeCustom") {
+void VisualShaderEditor::_get_current_mode_limits(int &r_begin_type, int &r_end_type) const {
+ switch (visual_shader->get_mode()) {
+ case Shader::MODE_CANVAS_ITEM:
+ case Shader::MODE_SPATIAL: {
+ r_begin_type = 0;
+ r_end_type = 3;
+ } break;
+ case Shader::MODE_PARTICLES: {
+ r_begin_type = 3;
+ r_end_type = 5 + r_begin_type;
+ } break;
+ case Shader::MODE_SKY: {
+ r_begin_type = 8;
+ r_end_type = 1 + r_begin_type;
+ } break;
+ case Shader::MODE_FOG: {
+ r_begin_type = 9;
+ r_end_type = 1 + r_begin_type;
+ } break;
+ default: {
+ } break;
+ }
+}
+
+void VisualShaderEditor::_script_created(const Ref<Script> &p_script) {
+ if (p_script.is_null() || p_script->get_instance_base_type() != "VisualShaderNodeCustom") {
+ return;
+ }
+ Ref<VisualShaderNodeCustom> ref;
+ ref.instantiate();
+ ref->set_script(p_script);
+
+ Dictionary dict = get_custom_node_data(ref);
+ add_custom_type(dict["name"], dict["script"], dict["description"], dict["return_icon_type"], dict["category"], dict["highend"]);
+
+ _update_options_menu();
+}
+
+void VisualShaderEditor::_update_custom_script(const Ref<Script> &p_script) {
+ if (p_script.is_null() || p_script->get_instance_base_type() != "VisualShaderNodeCustom") {
return;
}
Ref<VisualShaderNodeCustom> ref;
ref.instantiate();
- ref->set_script(scr);
+ ref->set_script(p_script);
if (!ref->is_available(visual_shader->get_mode(), visual_shader->get_shader_type())) {
for (int i = 0; i < add_options.size(); i++) {
- if (add_options[i].is_custom && add_options[i].script == scr) {
+ if (add_options[i].is_custom && add_options[i].script == p_script) {
add_options.remove_at(i);
_update_options_menu();
// TODO: Make indication for the existed custom nodes with that script on graph to be disabled.
@@ -1296,8 +1334,8 @@ void VisualShaderEditor::update_custom_type(const Ref<Resource> &p_resource) {
bool found_type = false;
bool need_rebuild = false;
- for (int i = 0; i < add_options.size(); i++) {
- if (add_options[i].is_custom && add_options[i].script == scr) {
+ for (int i = custom_node_option_idx; i < add_options.size(); i++) {
+ if (add_options[i].script == p_script) {
found_type = true;
add_options.write[i].name = dict["name"];
@@ -1306,31 +1344,11 @@ void VisualShaderEditor::update_custom_type(const Ref<Resource> &p_resource) {
add_options.write[i].category = dict["category"];
add_options.write[i].highend = dict["highend"];
- int max_type = 0;
- int type_offset = 0;
- switch (visual_shader->get_mode()) {
- case Shader::MODE_CANVAS_ITEM:
- case Shader::MODE_SPATIAL: {
- max_type = 3;
- } break;
- case Shader::MODE_PARTICLES: {
- max_type = 5;
- type_offset = 3;
- } break;
- case Shader::MODE_SKY: {
- max_type = 1;
- type_offset = 8;
- } break;
- case Shader::MODE_FOG: {
- max_type = 1;
- type_offset = 9;
- } break;
- default: {
- } break;
- }
- max_type = type_offset + max_type;
+ int begin_type = 0;
+ int end_type = 0;
+ _get_current_mode_limits(begin_type, end_type);
- for (int t = type_offset; t < max_type; t++) {
+ for (int t = begin_type; t < end_type; t++) {
VisualShader::Type type = (VisualShader::Type)t;
Vector<int> nodes = visual_shader->get_node_list(type);
@@ -1339,28 +1357,27 @@ void VisualShaderEditor::update_custom_type(const Ref<Resource> &p_resource) {
List<VisualShader::Connection> custom_node_input_connections;
List<VisualShader::Connection> custom_node_output_connections;
+
for (const VisualShader::Connection &E : node_connections) {
int from = E.from_node;
- int from_idx = E.from_port;
+ int from_port = E.from_port;
int to = E.to_node;
- int to_idx = E.to_port;
+ int to_port = E.to_port;
- if (graph_plugin->get_node_script(from) == scr) {
- custom_node_output_connections.push_back({ from, from_idx, to, to_idx });
- } else if (graph_plugin->get_node_script(to) == scr) {
- custom_node_input_connections.push_back({ from, from_idx, to, to_idx });
+ if (graph_plugin->get_node_script(from) == p_script) {
+ custom_node_output_connections.push_back({ from, from_port, to, to_port });
+ } else if (graph_plugin->get_node_script(to) == p_script) {
+ custom_node_input_connections.push_back({ from, from_port, to, to_port });
}
}
- for (int j = 0; j < nodes.size(); j++) {
- int node_id = nodes[j];
-
+ for (int node_id : nodes) {
Ref<VisualShaderNode> vsnode = visual_shader->get_node(type, node_id);
if (vsnode.is_null()) {
continue;
}
Ref<VisualShaderNodeCustom> custom_node = Ref<VisualShaderNodeCustom>(vsnode.ptr());
- if (custom_node.is_null() || custom_node->get_script() != scr) {
+ if (custom_node.is_null() || custom_node->get_script() != p_script) {
continue;
}
need_rebuild = true;
@@ -1429,6 +1446,89 @@ void VisualShaderEditor::update_custom_type(const Ref<Resource> &p_resource) {
}
}
+void VisualShaderEditor::_resource_saved(const Ref<Resource> &p_resource) {
+ _update_custom_script(Ref<Script>(p_resource.ptr()));
+}
+
+void VisualShaderEditor::_resources_removed() {
+ bool has_any_instance = false;
+
+ for (const Ref<Script> &scr : custom_scripts_to_delete) {
+ for (int i = custom_node_option_idx; i < add_options.size(); i++) {
+ if (add_options[i].script == scr) {
+ add_options.remove_at(i);
+
+ // Removes all node instances using that script from the graph.
+ {
+ int begin_type = 0;
+ int end_type = 0;
+ _get_current_mode_limits(begin_type, end_type);
+
+ for (int t = begin_type; t < end_type; t++) {
+ VisualShader::Type type = (VisualShader::Type)t;
+
+ List<VisualShader::Connection> node_connections;
+ visual_shader->get_node_connections(type, &node_connections);
+
+ for (const VisualShader::Connection &E : node_connections) {
+ int from = E.from_node;
+ int from_port = E.from_port;
+ int to = E.to_node;
+ int to_port = E.to_port;
+
+ if (graph_plugin->get_node_script(from) == scr || graph_plugin->get_node_script(to) == scr) {
+ visual_shader->disconnect_nodes(type, from, from_port, to, to_port);
+ graph_plugin->disconnect_nodes(type, from, from_port, to, to_port);
+ }
+ }
+
+ Vector<int> nodes = visual_shader->get_node_list(type);
+ for (int node_id : nodes) {
+ Ref<VisualShaderNode> vsnode = visual_shader->get_node(type, node_id);
+ if (vsnode.is_null()) {
+ continue;
+ }
+ Ref<VisualShaderNodeCustom> custom_node = Ref<VisualShaderNodeCustom>(vsnode.ptr());
+ if (custom_node.is_null() || custom_node->get_script() != scr) {
+ continue;
+ }
+ visual_shader->remove_node(type, node_id);
+ graph_plugin->remove_node(type, node_id, false);
+
+ has_any_instance = true;
+ }
+ }
+ }
+
+ break;
+ }
+ }
+ }
+ if (has_any_instance) {
+ EditorUndoRedoManager::get_singleton()->clear_history(); // Need to clear undo history, otherwise it may lead to hard-detected errors and crashes (since the script was removed).
+ ResourceSaver::save(visual_shader, visual_shader->get_path());
+ }
+ _update_options_menu();
+
+ custom_scripts_to_delete.clear();
+ pending_custom_scripts_to_delete = false;
+}
+
+void VisualShaderEditor::_resource_removed(const Ref<Resource> &p_resource) {
+ Ref<Script> scr = Ref<Script>(p_resource.ptr());
+ if (scr.is_null() || scr->get_instance_base_type() != "VisualShaderNodeCustom") {
+ return;
+ }
+
+ custom_scripts_to_delete.push_back(scr);
+
+ if (!pending_custom_scripts_to_delete) {
+ pending_custom_scripts_to_delete = true;
+
+ call_deferred("_resources_removed");
+ }
+}
+
void VisualShaderEditor::_update_options_menu_deferred() {
_update_options_menu();
@@ -4901,13 +5001,16 @@ void VisualShaderEditor::_bind_methods() {
ClassDB::bind_method("_expand_output_port", &VisualShaderEditor::_expand_output_port);
ClassDB::bind_method("_update_options_menu_deferred", &VisualShaderEditor::_update_options_menu_deferred);
ClassDB::bind_method("_rebuild_shader_deferred", &VisualShaderEditor::_rebuild_shader_deferred);
+ ClassDB::bind_method("_resources_removed", &VisualShaderEditor::_resources_removed);
ClassDB::bind_method("_is_available", &VisualShaderEditor::_is_available);
}
VisualShaderEditor::VisualShaderEditor() {
ShaderLanguage::get_keyword_list(&keyword_list);
- EditorNode::get_singleton()->connect("resource_saved", callable_mp(this, &VisualShaderEditor::update_custom_type));
+ EditorNode::get_singleton()->connect("resource_saved", callable_mp(this, &VisualShaderEditor::_resource_saved));
+ FileSystemDock::get_singleton()->get_script_create_dialog()->connect("script_created", callable_mp(this, &VisualShaderEditor::_script_created));
+ FileSystemDock::get_singleton()->connect("resource_removed", callable_mp(this, &VisualShaderEditor::_resource_removed));
graph = memnew(GraphEdit);
graph->get_zoom_hbox()->set_h_size_flags(SIZE_EXPAND_FILL);
diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h
index c4f6b4952c..519a390ccc 100644
--- a/editor/plugins/visual_shader_editor_plugin.h
+++ b/editor/plugins/visual_shader_editor_plugin.h
@@ -188,6 +188,9 @@ class VisualShaderEditor : public VBoxContainer {
PanelContainer *error_panel = nullptr;
Label *error_label = nullptr;
+ bool pending_custom_scripts_to_delete = false;
+ List<Ref<Script>> custom_scripts_to_delete;
+
bool _block_update_options_menu = false;
bool _block_rebuild_shader = false;
@@ -503,6 +506,13 @@ class VisualShaderEditor : public VBoxContainer {
void _visibility_changed();
+ void _get_current_mode_limits(int &r_begin_type, int &r_end_type) const;
+ void _update_custom_script(const Ref<Script> &p_script);
+ void _script_created(const Ref<Script> &p_script);
+ void _resource_saved(const Ref<Resource> &p_resource);
+ void _resource_removed(const Ref<Resource> &p_resource);
+ void _resources_removed();
+
protected:
void _notification(int p_what);
static void _bind_methods();
@@ -517,7 +527,6 @@ public:
void add_custom_type(const String &p_name, const Ref<Script> &p_script, const String &p_description, int p_return_icon_type, const String &p_category, bool p_highend);
Dictionary get_custom_node_data(Ref<VisualShaderNodeCustom> &p_custom_node);
- void update_custom_type(const Ref<Resource> &p_resource);
virtual Size2 get_minimum_size() const override;
void edit(VisualShader *p_visual_shader);