Added port type content filter on port dragging in visual shader

This commit is contained in:
Yuri Roubinsky 2021-07-13 08:52:52 +03:00
parent 2fcf3057fd
commit f653cc13b9
2 changed files with 104 additions and 4 deletions

View file

@ -1219,8 +1219,88 @@ void VisualShaderEditor::_update_options_menu() {
Vector<AddOption> custom_options;
Vector<AddOption> embedded_options;
static Vector<String> type_filter_exceptions;
if (type_filter_exceptions.is_empty()) {
type_filter_exceptions.append("VisualShaderNodeExpression");
}
for (int i = 0; i < add_options.size(); i++) {
if (!use_filter || add_options[i].name.findn(filter) != -1) {
// port type filtering
if (members_output_port_type != VisualShaderNode::PORT_TYPE_MAX || members_input_port_type != VisualShaderNode::PORT_TYPE_MAX) {
Ref<VisualShaderNode> vsn;
int check_result = 0;
if (!add_options[i].is_custom) {
vsn = Ref<VisualShaderNode>(Object::cast_to<VisualShaderNode>(ClassDB::instantiate(add_options[i].type)));
if (!vsn.is_valid()) {
continue;
}
if (type_filter_exceptions.has(add_options[i].type)) {
check_result = 1;
}
Ref<VisualShaderNodeInput> input = Object::cast_to<VisualShaderNodeInput>(vsn.ptr());
if (input.is_valid()) {
input->set_shader_mode(visual_shader->get_mode());
input->set_shader_type(visual_shader->get_shader_type());
input->set_input_name(add_options[i].sub_func_str);
}
Ref<VisualShaderNodeExpression> expression = Object::cast_to<VisualShaderNodeExpression>(vsn.ptr());
if (expression.is_valid()) {
if (members_input_port_type == VisualShaderNode::PORT_TYPE_SAMPLER) {
check_result = -1; // expressions creates a port with required type automatically (except for sampler output)
}
}
Ref<VisualShaderNodeUniformRef> uniform_ref = Object::cast_to<VisualShaderNodeUniformRef>(vsn.ptr());
if (uniform_ref.is_valid()) {
check_result = -1;
if (members_input_port_type != VisualShaderNode::PORT_TYPE_MAX) {
for (int j = 0; j < uniform_ref->get_uniforms_count(); j++) {
if (visual_shader->is_port_types_compatible(uniform_ref->get_port_type_by_index(j), members_input_port_type)) {
check_result = 1;
break;
}
}
}
}
} else {
check_result = 1;
}
if (members_output_port_type != VisualShaderNode::PORT_TYPE_MAX) {
if (check_result == 0) {
for (int j = 0; j < vsn->get_input_port_count(); j++) {
if (visual_shader->is_port_types_compatible(vsn->get_input_port_type(j), members_output_port_type)) {
check_result = 1;
break;
}
}
}
if (check_result != 1) {
continue;
}
}
if (members_input_port_type != VisualShaderNode::PORT_TYPE_MAX) {
if (check_result == 0) {
for (int j = 0; j < vsn->get_output_port_count(); j++) {
if (visual_shader->is_port_types_compatible(vsn->get_output_port_type(j), members_input_port_type)) {
check_result = 1;
break;
}
}
}
if (check_result != 1) {
continue;
}
}
}
if ((add_options[i].func != current_func && add_options[i].func != -1) || !_is_available(add_options[i].mode)) {
continue;
}
@ -2588,13 +2668,25 @@ void VisualShaderEditor::_disconnection_request(const String &p_from, int p_from
void VisualShaderEditor::_connection_to_empty(const String &p_from, int p_from_slot, const Vector2 &p_release_position) {
from_node = p_from.to_int();
from_slot = p_from_slot;
_show_members_dialog(true);
VisualShaderNode::PortType input_port_type = VisualShaderNode::PORT_TYPE_MAX;
VisualShaderNode::PortType output_port_type = VisualShaderNode::PORT_TYPE_MAX;
Ref<VisualShaderNode> node = visual_shader->get_node(get_current_shader_type(), from_node);
if (node.is_valid()) {
output_port_type = node->get_output_port_type(from_slot);
}
_show_members_dialog(true, input_port_type, output_port_type);
}
void VisualShaderEditor::_connection_from_empty(const String &p_to, int p_to_slot, const Vector2 &p_release_position) {
to_node = p_to.to_int();
to_slot = p_to_slot;
_show_members_dialog(true);
VisualShaderNode::PortType input_port_type = VisualShaderNode::PORT_TYPE_MAX;
VisualShaderNode::PortType output_port_type = VisualShaderNode::PORT_TYPE_MAX;
Ref<VisualShaderNode> node = visual_shader->get_node(get_current_shader_type(), to_node);
if (node.is_valid()) {
input_port_type = node->get_input_port_type(to_slot);
}
_show_members_dialog(true, input_port_type, output_port_type);
}
void VisualShaderEditor::_delete_nodes(int p_type, const List<int> &p_nodes) {
@ -3036,7 +3128,13 @@ void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) {
}
}
void VisualShaderEditor::_show_members_dialog(bool at_mouse_pos) {
void VisualShaderEditor::_show_members_dialog(bool at_mouse_pos, VisualShaderNode::PortType p_input_port_type, VisualShaderNode::PortType p_output_port_type) {
if (members_input_port_type != p_input_port_type || members_output_port_type != p_output_port_type) {
members_input_port_type = p_input_port_type;
members_output_port_type = p_output_port_type;
_update_options_menu();
}
if (at_mouse_pos) {
saved_node_pos_dirty = true;
saved_node_pos = graph->get_local_mouse_position();

View file

@ -160,6 +160,8 @@ class VisualShaderEditor : public VBoxContainer {
bool saved_node_pos_dirty;
ConfirmationDialog *members_dialog;
VisualShaderNode::PortType members_input_port_type = VisualShaderNode::PORT_TYPE_MAX;
VisualShaderNode::PortType members_output_port_type = VisualShaderNode::PORT_TYPE_MAX;
PopupMenu *popup_menu;
PopupMenu *constants_submenu = nullptr;
MenuButton *tools;
@ -227,7 +229,7 @@ class VisualShaderEditor : public VBoxContainer {
Label *highend_label;
void _tools_menu_option(int p_idx);
void _show_members_dialog(bool at_mouse_pos);
void _show_members_dialog(bool at_mouse_pos, VisualShaderNode::PortType p_input_port_type = VisualShaderNode::PORT_TYPE_MAX, VisualShaderNode::PortType p_output_port_type = VisualShaderNode::PORT_TYPE_MAX);
void _update_graph();