diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index bdf566e991c1..509104a14cdc 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -135,6 +135,7 @@ void ShaderTextEditor::set_edited_code(const String &p_code) { get_text_editor()->clear_undo_history(); get_text_editor()->call_deferred(SNAME("set_h_scroll"), 0); get_text_editor()->call_deferred(SNAME("set_v_scroll"), 0); + get_text_editor()->tag_saved_version(); _validate_script(); _line_col_changed(); @@ -844,6 +845,7 @@ void ShaderEditor::save_external_data(const String &p_str) { if (shader_inc.is_valid() && shader_inc != edited_shader_inc) { ResourceSaver::save(shader_inc->get_path(), shader_inc); } + shader_editor->get_text_editor()->tag_saved_version(); disk_changed->hide(); } @@ -852,6 +854,10 @@ void ShaderEditor::validate_script() { shader_editor->_validate_script(); } +bool ShaderEditor::is_unsaved() const { + return shader_editor->get_text_editor()->get_saved_version() != shader_editor->get_text_editor()->get_version(); +} + void ShaderEditor::apply_shaders() { String editor_code = shader_editor->get_text_editor()->get_text(); if (shader.is_valid()) { @@ -1128,36 +1134,34 @@ ShaderEditor::ShaderEditor() { void ShaderEditorPlugin::_update_shader_list() { shader_list->clear(); for (uint32_t i = 0; i < edited_shaders.size(); i++) { - String text; - String path; - String _class; - String shader_name; - if (edited_shaders[i].shader.is_valid()) { - Ref shader = edited_shaders[i].shader; - - path = shader->get_path(); - _class = shader->get_class(); - shader_name = shader->get_name(); - } else { - Ref shader_inc = edited_shaders[i].shader_inc; - - path = shader_inc->get_path(); - _class = shader_inc->get_class(); - shader_name = shader_inc->get_name(); + Ref shader = edited_shaders[i].shader; + if (shader.is_null()) { + shader = edited_shaders[i].shader_inc; } - if (path.is_resource_file()) { - text = path.get_file(); - } else if (shader_name != "") { - text = shader_name; - } else { - if (edited_shaders[i].shader.is_valid()) { - text = _class + ":" + itos(edited_shaders[i].shader->get_instance_id()); - } else { - text = _class + ":" + itos(edited_shaders[i].shader_inc->get_instance_id()); + String path = shader->get_path(); + String text = path.get_file(); + if (text.is_empty()) { + // This appears for newly created built-in shaders before saving the scene. + text = TTR("[unsaved]"); + } else if (shader->is_built_in()) { + const String &shader_name = shader->get_name(); + if (!shader_name.is_empty()) { + text = vformat("%s (%s)", shader_name, text.get_slice("::", 0)); } } + bool unsaved = false; + if (edited_shaders[i].shader_editor) { + unsaved = edited_shaders[i].shader_editor->is_unsaved(); + } + // TODO: Handle visual shaders too. + + if (unsaved) { + text += "(*)"; + } + + String _class = shader->get_class(); if (!shader_list->has_theme_icon(_class, SNAME("EditorIcons"))) { _class = "TextFile"; } @@ -1207,7 +1211,7 @@ void ShaderEditorPlugin::edit(Object *p_object) { es.shader_editor = memnew(ShaderEditor); es.shader_editor->edit(si); shader_tabs->add_child(es.shader_editor); - es.shader_editor->connect("validation_changed", callable_mp(this, &ShaderEditorPlugin::_update_shader_list_status)); + es.shader_editor->connect("validation_changed", callable_mp(this, &ShaderEditorPlugin::_update_shader_list)); } else { Shader *s = Object::cast_to(p_object); for (uint32_t i = 0; i < edited_shaders.size(); i++) { @@ -1227,7 +1231,7 @@ void ShaderEditorPlugin::edit(Object *p_object) { es.shader_editor = memnew(ShaderEditor); shader_tabs->add_child(es.shader_editor); es.shader_editor->edit(s); - es.shader_editor->connect("validation_changed", callable_mp(this, &ShaderEditorPlugin::_update_shader_list_status)); + es.shader_editor->connect("validation_changed", callable_mp(this, &ShaderEditorPlugin::_update_shader_list)); } } @@ -1273,6 +1277,7 @@ void ShaderEditorPlugin::save_external_data() { edited_shaders[i].shader_editor->save_external_data(); } } + _update_shader_list(); } void ShaderEditorPlugin::apply_changes() { @@ -1290,6 +1295,12 @@ void ShaderEditorPlugin::_shader_selected(int p_index) { shader_tabs->set_current_tab(p_index); } +void ShaderEditorPlugin::_shader_list_clicked(int p_item, Vector2 p_local_mouse_pos, MouseButton p_mouse_button_index) { + if (p_mouse_button_index == MouseButton::MIDDLE) { + _close_shader(p_item); + } +} + void ShaderEditorPlugin::_close_shader(int p_index) { int index = shader_tabs->get_current_tab(); ERR_FAIL_INDEX(index, shader_tabs->get_tab_count()); @@ -1409,6 +1420,7 @@ ShaderEditorPlugin::ShaderEditorPlugin() { shader_list->set_v_size_flags(Control::SIZE_EXPAND_FILL); vb->add_child(shader_list); shader_list->connect("item_selected", callable_mp(this, &ShaderEditorPlugin::_shader_selected)); + shader_list->connect("item_clicked", callable_mp(this, &ShaderEditorPlugin::_shader_list_clicked)); main_split->add_child(vb); vb->set_custom_minimum_size(Size2(200, 300) * EDSCALE); diff --git a/editor/plugins/shader_editor_plugin.h b/editor/plugins/shader_editor_plugin.h index 907de6ea87da..9a59e8619220 100644 --- a/editor/plugins/shader_editor_plugin.h +++ b/editor/plugins/shader_editor_plugin.h @@ -185,6 +185,7 @@ class ShaderEditor : public PanelContainer { void goto_line_selection(int p_line, int p_begin, int p_end); void save_external_data(const String &p_str = ""); void validate_script(); + bool is_unsaved() const; virtual Size2 get_minimum_size() const override { return Size2(0, 200); } @@ -226,6 +227,7 @@ class ShaderEditorPlugin : public EditorPlugin { void _update_shader_list(); void _shader_selected(int p_index); + void _shader_list_clicked(int p_item, Vector2 p_local_mouse_pos, MouseButton p_mouse_button_index); void _menu_item_pressed(int p_index); void _resource_saved(Object *obj); void _close_shader(int p_index); @@ -235,8 +237,6 @@ class ShaderEditorPlugin : public EditorPlugin { void _update_shader_list_status(); public: - virtual String get_name() const override { return "Shader"; } - bool has_main_screen() const override { return false; } virtual void edit(Object *p_object) override; virtual bool handles(Object *p_object) const override; virtual void make_visible(bool p_visible) override;