Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements to the shader editor #61459

Merged
merged 1 commit into from
Jun 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion editor/editor_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7047,7 +7047,6 @@ EditorNode::EditorNode() {
add_editor_plugin(VersionControlEditorPlugin::get_singleton());
add_editor_plugin(memnew(ShaderEditorPlugin));
add_editor_plugin(memnew(ShaderFileEditorPlugin));
add_editor_plugin(memnew(VisualShaderEditorPlugin));

add_editor_plugin(memnew(Camera3DEditorPlugin));
add_editor_plugin(memnew(ThemeEditorPlugin));
Expand Down
2 changes: 1 addition & 1 deletion editor/plugins/script_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3547,7 +3547,7 @@ void ScriptEditor::_on_find_in_files_result_selected(String fpath, int line_numb
ShaderEditorPlugin *shader_editor = Object::cast_to<ShaderEditorPlugin>(EditorNode::get_singleton()->get_editor_data().get_editor("Shader"));
shader_editor->edit(res.ptr());
shader_editor->make_visible(true);
shader_editor->get_shader_editor()->goto_line_selection(line_number - 1, begin, end);
shader_editor->get_shader_editor(res)->goto_line_selection(line_number - 1, begin, end);
return;
} else if (fpath.get_extension() == "tscn") {
EditorNode::get_singleton()->load_scene(fpath);
Expand Down
210 changes: 190 additions & 20 deletions editor/plugins/shader_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,12 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
#include "editor/filesystem_dock.h"
#include "editor/plugins/visual_shader_editor_plugin.h"
#include "editor/project_settings_editor.h"
#include "editor/property_editor.h"
#include "editor/shader_create_dialog.h"
#include "scene/gui/split_container.h"
#include "servers/display_server.h"
#include "servers/rendering/shader_types.h"

Expand Down Expand Up @@ -836,50 +840,216 @@ ShaderEditor::ShaderEditor() {
_editor_settings_changed();
}

void ShaderEditorPlugin::_update_shader_list() {
shader_list->clear();
for (uint32_t i = 0; i < edited_shaders.size(); i++) {
reduz marked this conversation as resolved.
Show resolved Hide resolved
String text;
String path = edited_shaders[i].shader->get_path();
String _class = edited_shaders[i].shader->get_class();

if (path.is_resource_file()) {
text = path.get_file();
} else if (edited_shaders[i].shader->get_name() != "") {
reduz marked this conversation as resolved.
Show resolved Hide resolved
text = edited_shaders[i].shader->get_name();
} else {
text = _class + ":" + itos(edited_shaders[i].shader->get_instance_id());
}

if (!shader_list->has_theme_icon(_class, SNAME("EditorIcons"))) {
_class = "Resource";
}
Ref<Texture2D> icon = shader_list->get_theme_icon(_class, SNAME("EditorIcons"));

shader_list->add_item(text, icon);
shader_list->set_item_tooltip(shader_list->get_item_count() - 1, path);
reduz marked this conversation as resolved.
Show resolved Hide resolved
}

if (shader_tabs->get_tab_count()) {
shader_list->select(shader_tabs->get_current_tab());
}

for (int i = 1; i < FILE_MAX; i++) {
file_menu->get_popup()->set_item_disabled(file_menu->get_popup()->get_item_index(i), edited_shaders.size() == 0);
reduz marked this conversation as resolved.
Show resolved Hide resolved
}
}

void ShaderEditorPlugin::edit(Object *p_object) {
Shader *s = Object::cast_to<Shader>(p_object);
shader_editor->edit(s);
for (uint32_t i = 0; i < edited_shaders.size(); i++) {
if (edited_shaders[i].shader.ptr() == s) {
// Exists, select.
shader_tabs->set_current_tab(i);
shader_list->select(i);
return;
}
}
// Add.
EditedShader es;
es.shader = Ref<Shader>(s);
Ref<VisualShader> vs = es.shader;
if (vs.is_valid()) {
es.visual_shader_editor = memnew(VisualShaderEditor);
es.visual_shader_editor->edit(vs.ptr());
shader_tabs->add_child(es.visual_shader_editor);
} else {
es.shader_editor = memnew(ShaderEditor);
es.shader_editor->edit(s);
shader_tabs->add_child(es.shader_editor);
}
shader_tabs->set_current_tab(shader_tabs->get_tab_count() - 1);
edited_shaders.push_back(es);
_update_shader_list();
}

bool ShaderEditorPlugin::handles(Object *p_object) const {
Shader *shader = Object::cast_to<Shader>(p_object);
return shader != nullptr && shader->is_text_shader();
return Object::cast_to<Shader>(p_object) != nullptr;
}

void ShaderEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
button->show();
EditorNode::get_singleton()->make_bottom_panel_item_visible(shader_editor);

} else {
button->hide();
if (shader_editor->is_visible_in_tree()) {
EditorNode::get_singleton()->hide_bottom_panel();
}
shader_editor->apply_shaders();
EditorNode::get_singleton()->make_bottom_panel_item_visible(main_split);
}
}

void ShaderEditorPlugin::selected_notify() {
shader_editor->ensure_select_current();
}

ShaderEditor *ShaderEditorPlugin::get_shader_editor(const Ref<Shader> &p_for_shader) {
for (uint32_t i = 0; i < edited_shaders.size(); i++) {
if (edited_shaders[i].shader == p_for_shader) {
return edited_shaders[i].shader_editor;
}
}
return nullptr;
}

void ShaderEditorPlugin::save_external_data() {
shader_editor->save_external_data();
for (uint32_t i = 0; i < edited_shaders.size(); i++) {
if (edited_shaders[i].shader_editor) {
edited_shaders[i].shader_editor->save_external_data();
}
}
}

void ShaderEditorPlugin::apply_changes() {
shader_editor->apply_shaders();
for (uint32_t i = 0; i < edited_shaders.size(); i++) {
if (edited_shaders[i].shader_editor) {
edited_shaders[i].shader_editor->apply_shaders();
}
}
}

void ShaderEditorPlugin::_shader_selected(int p_index) {
shader_tabs->set_current_tab(p_index);
}

void ShaderEditorPlugin::_close_shader(int p_index) {
int index = shader_tabs->get_current_tab();
ERR_FAIL_INDEX(index, shader_tabs->get_tab_count());
Control *c = shader_tabs->get_tab_control(index);
memdelete(c);
edited_shaders.remove_at(index);
_update_shader_list();
}

void ShaderEditorPlugin::_resource_saved(Object *obj) {
// May have been renamed on save.
for (uint32_t i = 0; i < edited_shaders.size(); i++) {
if (edited_shaders[i].shader.ptr() == obj) {
_update_shader_list();
return;
}
}
}

void ShaderEditorPlugin::_menu_item_pressed(int p_index) {
switch (p_index) {
case FILE_NEW: {
String base_path = FileSystemDock::get_singleton()->get_current_path();
shader_create_dialog->config(base_path.plus_file("new_shader"), false, false, 0);
shader_create_dialog->popup_centered();
} break;
case FILE_OPEN: {
InspectorDock::get_singleton()->open_resource("Shader");
} break;
case FILE_SAVE: {
int index = shader_tabs->get_current_tab();
ERR_FAIL_INDEX(index, shader_tabs->get_tab_count());
EditorNode::get_singleton()->save_resource(edited_shaders[index].shader);
} break;
case FILE_SAVE_AS: {
int index = shader_tabs->get_current_tab();
ERR_FAIL_INDEX(index, shader_tabs->get_tab_count());
String path = edited_shaders[index].shader->get_path();
if (!path.is_resource_file()) {
path = "";
}
EditorNode::get_singleton()->save_resource_as(edited_shaders[index].shader, path);
} break;
case FILE_INSPECT: {
int index = shader_tabs->get_current_tab();
ERR_FAIL_INDEX(index, shader_tabs->get_tab_count());
EditorNode::get_singleton()->push_item(edited_shaders[index].shader.ptr());
} break;
case FILE_CLOSE: {
_close_shader(shader_tabs->get_current_tab());
} break;
}
}

void ShaderEditorPlugin::_shader_created(Ref<Shader> p_shader) {
EditorNode::get_singleton()->push_item(p_shader.ptr());
}

ShaderEditorPlugin::ShaderEditorPlugin() {
shader_editor = memnew(ShaderEditor);
main_split = memnew(HSplitContainer);

VBoxContainer *vb = memnew(VBoxContainer);

HBoxContainer *file_hb = memnew(HBoxContainer);
reduz marked this conversation as resolved.
Show resolved Hide resolved
vb->add_child(file_hb);
file_menu = memnew(MenuButton);
file_menu->set_text(TTR("File"));
file_menu->get_popup()->add_item(TTR("New Shader"), FILE_NEW);
file_menu->get_popup()->add_separator();
file_menu->get_popup()->add_item(TTR("Load Shader"), FILE_OPEN);
file_menu->get_popup()->add_item(TTR("Save Shader"), FILE_SAVE);
file_menu->get_popup()->add_item(TTR("Save Shader As"), FILE_SAVE_AS);
file_menu->get_popup()->add_separator();
file_menu->get_popup()->add_item(TTR("Open Shader in Inspector"), FILE_INSPECT);
file_menu->get_popup()->add_separator();
file_menu->get_popup()->add_item(TTR("Close Shader"), FILE_CLOSE);
file_menu->get_popup()->connect("id_pressed", callable_mp(this, &ShaderEditorPlugin::_menu_item_pressed));
file_hb->add_child(file_menu);

for (int i = 1; i < FILE_MAX; i++) {
file_menu->get_popup()->set_item_disabled(file_menu->get_popup()->get_item_index(i), true);
}

shader_list = memnew(ItemList);
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));

main_split->add_child(vb);
vb->set_custom_minimum_size(Size2(200, 300) * EDSCALE);

shader_tabs = memnew(TabContainer);
shader_tabs->set_tabs_visible(false);
shader_tabs->set_h_size_flags(Control::SIZE_EXPAND_FILL);
main_split->add_child(shader_tabs);
Ref<StyleBoxEmpty> empty;
empty.instantiate();
shader_tabs->add_theme_style_override("panel", empty);

button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("Shader Editor"), main_split);

shader_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE);
button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("Shader"), shader_editor);
button->hide();
// Defer connect because Editor class is not in the binding system yet.
EditorNode::get_singleton()->call_deferred("connect", "resource_saved", callable_mp(this, &ShaderEditorPlugin::_resource_saved), varray(), CONNECT_DEFERRED);

_2d = false;
shader_create_dialog = memnew(ShaderCreateDialog);
vb->add_child(shader_create_dialog);
shader_create_dialog->connect("shader_created", callable_mp(this, &ShaderEditorPlugin::_shader_created));
}

ShaderEditorPlugin::~ShaderEditorPlugin() {
Expand Down
42 changes: 39 additions & 3 deletions editor/plugins/shader_editor_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@
#include "scene/resources/shader.h"
#include "servers/rendering/shader_warnings.h"

class ItemList;
class VisualShaderEditor;
class HSplitContainer;
class ShaderCreateDialog;

class ShaderTextEditor : public CodeTextEditor {
GDCLASS(ShaderTextEditor, CodeTextEditor);

Expand Down Expand Up @@ -160,9 +165,40 @@ class ShaderEditor : public PanelContainer {
class ShaderEditorPlugin : public EditorPlugin {
GDCLASS(ShaderEditorPlugin, EditorPlugin);

bool _2d;
ShaderEditor *shader_editor = nullptr;
struct EditedShader {
Ref<Shader> shader;
ShaderEditor *shader_editor = nullptr;
VisualShaderEditor *visual_shader_editor = nullptr;
};

LocalVector<EditedShader> edited_shaders;

enum {
FILE_NEW,
FILE_OPEN,
FILE_SAVE,
FILE_SAVE_AS,
FILE_INSPECT,
FILE_CLOSE,
FILE_MAX
};

HSplitContainer *main_split = nullptr;
ItemList *shader_list = nullptr;
TabContainer *shader_tabs = nullptr;

Button *button = nullptr;
MenuButton *file_menu = nullptr;

ShaderCreateDialog *shader_create_dialog = nullptr;

void _update_shader_list();
void _shader_selected(int p_index);
void _menu_item_pressed(int p_index);
void _resource_saved(Object *obj);
void _close_shader(int p_index);

void _shader_created(Ref<Shader> p_shader);

public:
virtual String get_name() const override { return "Shader"; }
Expand All @@ -172,7 +208,7 @@ class ShaderEditorPlugin : public EditorPlugin {
virtual void make_visible(bool p_visible) override;
virtual void selected_notify() override;

ShaderEditor *get_shader_editor() const { return shader_editor; }
ShaderEditor *get_shader_editor(const Ref<Shader> &p_for_shader);
reduz marked this conversation as resolved.
Show resolved Hide resolved

virtual void save_external_data() override;
virtual void apply_changes() override;
Expand Down
42 changes: 0 additions & 42 deletions editor/plugins/visual_shader_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5659,48 +5659,6 @@ VisualShaderEditor::VisualShaderEditor() {
property_editor->connect("variant_changed", callable_mp(this, &VisualShaderEditor::_port_edited));
}

/////////////////

void VisualShaderEditorPlugin::edit(Object *p_object) {
visual_shader_editor->edit(Object::cast_to<VisualShader>(p_object));
}

bool VisualShaderEditorPlugin::handles(Object *p_object) const {
return p_object->is_class("VisualShader");
}

void VisualShaderEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
//editor->hide_animation_player_editors();
//editor->animation_panel_make_visible(true);
button->show();
EditorNode::get_singleton()->make_bottom_panel_item_visible(visual_shader_editor);
visual_shader_editor->update_nodes();
visual_shader_editor->set_process_input(true);
//visual_shader_editor->set_process(true);
} else {
if (visual_shader_editor->is_visible_in_tree()) {
EditorNode::get_singleton()->hide_bottom_panel();
}
button->hide();
visual_shader_editor->set_process_input(false);
//visual_shader_editor->set_process(false);
}
}

VisualShaderEditorPlugin::VisualShaderEditorPlugin() {
visual_shader_editor = memnew(VisualShaderEditor);
visual_shader_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE);

button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("VisualShader"), visual_shader_editor);
button->hide();
}

VisualShaderEditorPlugin::~VisualShaderEditorPlugin() {
}

////////////////

class VisualShaderNodePluginInputEditor : public OptionButton {
GDCLASS(VisualShaderNodePluginInputEditor, OptionButton);

Expand Down
Loading