diff options
Diffstat (limited to 'editor')
-rw-r--r-- | editor/plugins/visual_shader_editor_plugin.cpp | 114 | ||||
-rw-r--r-- | editor/plugins/visual_shader_editor_plugin.h | 43 |
2 files changed, 139 insertions, 18 deletions
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 9810fbee2c..3753b364d2 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -60,6 +60,88 @@ void VisualShaderNodePlugin::_bind_methods() { /////////////////// +VisualShaderGraphPlugin::VisualShaderGraphPlugin() { +} + +void VisualShaderGraphPlugin::_bind_methods() { + ClassDB::bind_method("show_port_preview", &VisualShaderGraphPlugin::show_port_preview); +} + +void VisualShaderGraphPlugin::register_shader(VisualShader *p_shader) { + visual_shader = Ref<VisualShader>(p_shader); +} + +void VisualShaderGraphPlugin::show_port_preview(int p_port_id, int p_node_id) { + if (links.has(p_node_id) && links[p_node_id].type == visual_shader->get_shader_type()) { + for (Map<int, Port>::Element *E = links[p_node_id].output_ports.front(); E; E = E->next()) { + E->value().preview_button->set_pressed(false); + } + + if (links[p_node_id].preview_visible && !is_dirty()) { + links[p_node_id].graph_node->remove_child(links[p_node_id].preview_box); + links[p_node_id].graph_node->set_size(Vector2(-1, -1)); + links[p_node_id].preview_visible = false; + } + + if (p_port_id != -1) { + if (is_dirty()) { + links[p_node_id].preview_pos = links[p_node_id].graph_node->get_child_count(); + } + + VBoxContainer *vbox = memnew(VBoxContainer); + links[p_node_id].graph_node->add_child(vbox); + if (links[p_node_id].preview_pos != -1) { + links[p_node_id].graph_node->move_child(vbox, links[p_node_id].preview_pos); + } + + Control *offset = memnew(Control); + offset->set_custom_minimum_size(Size2(0, 5 * EDSCALE)); + vbox->add_child(offset); + + VisualShaderNodePortPreview *port_preview = memnew(VisualShaderNodePortPreview); + port_preview->setup(visual_shader, visual_shader->get_shader_type(), p_node_id, p_port_id); + port_preview->set_h_size_flags(Control::SIZE_SHRINK_CENTER); + vbox->add_child(port_preview); + links[p_node_id].preview_visible = true; + links[p_node_id].preview_box = vbox; + links[p_node_id].output_ports[p_port_id].preview_button->set_pressed(true); + } + } +} + +bool VisualShaderGraphPlugin::is_preview_visible(int p_id) const { + return links[p_id].preview_visible; +} + +void VisualShaderGraphPlugin::clear_links() { + links.clear(); +} + +bool VisualShaderGraphPlugin::is_dirty() const { + return dirty; +} + +void VisualShaderGraphPlugin::make_dirty(bool p_enabled) { + dirty = p_enabled; +} + +void VisualShaderGraphPlugin::register_link(VisualShader::Type p_type, int p_id, VisualShaderNode *p_visual_node, GraphNode *p_graph_node) { + links.insert(p_id, { p_type, p_visual_node, p_graph_node, p_visual_node->get_output_port_for_preview() != -1, -1 }); + + if (!p_visual_node->is_connected("show_port_preview", callable_mp(this, &VisualShaderGraphPlugin::show_port_preview))) { + p_visual_node->connect("show_port_preview", callable_mp(this, &VisualShaderGraphPlugin::show_port_preview), varray(p_id), CONNECT_DEFERRED); + } +} + +void VisualShaderGraphPlugin::register_output_port(int p_node_id, int p_port, TextureButton *p_button) { + links[p_node_id].output_ports.insert(p_port, { p_button }); +} + +VisualShaderGraphPlugin::~VisualShaderGraphPlugin() { +} + +///////////////// + void VisualShaderEditor::edit(VisualShader *p_visual_shader) { bool changed = false; if (p_visual_shader) { @@ -71,6 +153,7 @@ void VisualShaderEditor::edit(VisualShader *p_visual_shader) { } } visual_shader = Ref<VisualShader>(p_visual_shader); + graph_plugin->register_shader(visual_shader.ptr()); if (!visual_shader->is_connected("changed", callable_mp(this, &VisualShaderEditor::_update_preview))) { visual_shader->connect("changed", callable_mp(this, &VisualShaderEditor::_update_preview)); } @@ -528,6 +611,9 @@ void VisualShaderEditor::_update_graph() { Control *offset; + graph_plugin->clear_links(); + graph_plugin->make_dirty(true); + for (int n_i = 0; n_i < nodes.size(); n_i++) { Vector2 position = visual_shader->get_node_position(type, nodes[n_i]); Ref<VisualShaderNode> vsnode = visual_shader->get_node(type, nodes[n_i]); @@ -542,6 +628,7 @@ void VisualShaderEditor::_update_graph() { GraphNode *node = memnew(GraphNode); visual_shader->set_graph_node(type, nodes[n_i], node); + graph_plugin->register_link(type, nodes[n_i], vsnode.ptr(), node); if (is_group) { size = group_node->get_size(); @@ -813,9 +900,7 @@ void VisualShaderEditor::_update_graph() { preview->set_pressed_texture(get_theme_icon("GuiVisibilityVisible", "EditorIcons")); preview->set_v_size_flags(SIZE_SHRINK_CENTER); - if (vsnode->get_output_port_for_preview() == i) { - preview->set_pressed(true); - } + graph_plugin->register_output_port(nodes[n_i], i, preview); preview->connect("pressed", callable_mp(this, &VisualShaderEditor::_preview_select_port), varray(nodes[n_i], i), CONNECT_DEFERRED); hb->add_child(preview); @@ -834,18 +919,7 @@ void VisualShaderEditor::_update_graph() { } if (vsnode->get_output_port_for_preview() >= 0) { - int port_type = vsnode->get_output_port_type(vsnode->get_output_port_for_preview()); - - if (port_type != VisualShaderNode::PORT_TYPE_TRANSFORM && port_type != VisualShaderNode::PORT_TYPE_SAMPLER) { - offset = memnew(Control); - offset->set_custom_minimum_size(Size2(0, 5 * EDSCALE)); - node->add_child(offset); - - VisualShaderNodePortPreview *port_preview = memnew(VisualShaderNodePortPreview); - port_preview->setup(visual_shader, type, nodes[n_i], vsnode->get_output_port_for_preview()); - port_preview->set_h_size_flags(SIZE_SHRINK_CENTER); - node->add_child(port_preview); - } + graph_plugin->show_port_preview(vsnode->get_output_port_for_preview(), nodes[n_i]); } offset = memnew(Control); @@ -908,6 +982,8 @@ void VisualShaderEditor::_update_graph() { } } + graph_plugin->make_dirty(false); + for (List<VisualShader::Connection>::Element *E = connections.front(); E; E = E->next()) { int from = E->get().from_node; int from_idx = E->get().from_port; @@ -1208,11 +1284,9 @@ void VisualShaderEditor::_preview_select_port(int p_node, int p_port) { if (node->get_output_port_for_preview() == p_port) { p_port = -1; //toggle it } - undo_redo->create_action(TTR("Set Uniform Name")); + undo_redo->create_action(p_port == -1 ? TTR("Hide Port Preview") : TTR("Show Port Preview")); undo_redo->add_do_method(node.ptr(), "set_output_port_for_preview", p_port); undo_redo->add_undo_method(node.ptr(), "set_output_port_for_preview", node->get_output_port_for_preview()); - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); undo_redo->commit_action(); } @@ -3030,12 +3104,16 @@ VisualShaderEditor::VisualShaderEditor() { default_plugin.instance(); add_plugin(default_plugin); + graph_plugin.instance(); + property_editor = memnew(CustomPropertyEditor); add_child(property_editor); 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)); } diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index 6284c9a530..59d4765ec9 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -50,8 +50,50 @@ public: virtual Control *create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node); }; +class VisualShaderGraphPlugin : public Reference { + GDCLASS(VisualShaderGraphPlugin, Reference); + +private: + struct Port { + TextureButton *preview_button; + }; + + struct Link { + VisualShader::Type type; + VisualShaderNode *visual_node; + GraphNode *graph_node; + bool preview_visible; + int preview_pos; + Map<int, Port> output_ports; + VBoxContainer *preview_box; + }; + + Ref<VisualShader> visual_shader; + Map<int, Link> links; + bool dirty = false; + +protected: + static void _bind_methods(); + +public: + void register_shader(VisualShader *p_visual_shader); + void register_link(VisualShader::Type p_type, int p_id, VisualShaderNode *p_visual_node, GraphNode *p_graph_node); + void register_output_port(int p_id, int p_port, TextureButton *p_button); + void clear_links(); + void set_shader_type(VisualShader::Type p_type); + bool is_preview_visible(int p_id) const; + bool is_dirty() const; + void make_dirty(bool p_enabled); + + void show_port_preview(int p_node_id, int p_port_id); + + VisualShaderGraphPlugin(); + ~VisualShaderGraphPlugin(); +}; + class VisualShaderEditor : public VBoxContainer { GDCLASS(VisualShaderEditor, VBoxContainer); + friend class VisualShaderGraphPlugin; CustomPropertyEditor *property_editor; int editing_node; @@ -242,6 +284,7 @@ class VisualShaderEditor : public VBoxContainer { void _paste_nodes(bool p_use_custom_position = false, const Vector2 &p_custom_position = Vector2()); Vector<Ref<VisualShaderNodePlugin>> plugins; + Ref<VisualShaderGraphPlugin> graph_plugin; void _mode_selected(int p_id); void _rebuild(); |