#include "mm_graph_node.h" #include "../nodes/bases/curve_base.h" #include "../nodes/bases/gradient_base.h" #include "../nodes/bases/polygon_base.h" #include "../nodes/mm_material.h" #include "../nodes/mm_node.h" #include "../nodes/mm_node_universal_property.h" #include "mat_maker_gd_editor.h" #include "scene/resources/packed_scene.h" #include "scene/gui/check_box.h" #include "scene/gui/color_picker.h" #include "scene/gui/label.h" #include "scene/gui/line_edit.h" #include "scene/gui/option_button.h" #include "scene/gui/spin_box.h" #include "scene/gui/texture_rect.h" #include "widgets/curve_edit/curve_edit.h" #include "widgets/gradient_editor/gradient_editor.h" #include "widgets/image_picker_button/image_picker_button.h" #include "widgets/polygon_edit/polygon_edit.h" Ref MMGraphNode::get_gradient_editor_scene() { return gradient_editor_scene; } void MMGraphNode::set_gradient_editor_scene(const Ref &val) { gradient_editor_scene = val; } Ref MMGraphNode::get_polygon_edit_scene() { return polygon_edit_scene; } void MMGraphNode::set_polygon_edit_scene(const Ref &val) { polygon_edit_scene = val; } Ref MMGraphNode::get_curve_edit_scene() { return curve_edit_scene; } void MMGraphNode::set_curve_edit_scene(const Ref &val) { curve_edit_scene = val; } Ref MMGraphNode::get_mm_material() { return _material; } void MMGraphNode::set_mm_material(const Ref &val) { _material = val; } Ref MMGraphNode::get_material_node() { return _node; } Ref MMGraphNode::get_mm_node() { return *_node; } void MMGraphNode::set_mm_node(const Ref &val) { _node = val; } MatMakerGDEditor *MMGraphNode::get_editor_node() { return _editor_node; } void MMGraphNode::set_editor_node(MatMakerGDEditor *val) { _editor_node = val; _undo_redo = _editor_node->get_undo_redo(); } UndoRedo *MMGraphNode::get_undo_redo() { return _undo_redo; } void MMGraphNode::set_undo_redo(UndoRedo *val) { _undo_redo = val; } bool MMGraphNode::get_ignore_change_event() const { return _ignore_change_event; } void MMGraphNode::set_ignore_change_event(const bool val) { _ignore_change_event = val; } void MMGraphNode::ignore_changes(const bool val) { _ignore_change_event = val; _editor_node->ignore_changes(val); } int MMGraphNode::add_slot_texture(const String &getter, const String &setter) { TextureRect *t = memnew(TextureRect); t->set_custom_minimum_size(Vector2(128, 128)); t->set_expand(true); t->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED); int slot_idx = add_slot(MMNodeUniversalProperty::SLOT_TYPE_NONE, MMNodeUniversalProperty::SLOT_TYPE_NONE, getter, setter, t); t->set_texture(_node->call(getter, _material, slot_idx)); properties.write[slot_idx].texture = t->get_texture(); return slot_idx; } int MMGraphNode::add_slot_texture_universal(const Ref &p_property) { Ref property = p_property; TextureRect *t = memnew(TextureRect); t->set_custom_minimum_size(Vector2(128, 128)); t->set_expand(true); t->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED); int slot_idx = add_slot(property->get_input_slot_type(), property->get_output_slot_type(), "", "", t); Ref img = property->get_active_image(); Ref tex; tex.instance(); if (img.is_valid()) { tex->create_from_image(img, 0); } t->set_texture(tex); properties.write[slot_idx].universal_property = property; Vector bindings; bindings.push_back(slot_idx); property->connect("changed", this, "on_universal_texture_changed", bindings); return slot_idx; } int MMGraphNode::add_slot_image_path_universal(const Ref &property, const String &getter, const String &setter) { ImagePickerButton *t = memnew(ImagePickerButton); int slot_idx = add_slot(property->get_input_slot_type(), property->get_output_slot_type(), "", "", t); properties.write[slot_idx].universal_property = property; properties.write[slot_idx].alt_getter = getter; properties.write[slot_idx].alt_setter = setter; Vector bindings; bindings.push_back(slot_idx); Ref prop = property; prop->connect("changed", this, "on_universal_texture_changed_image_picker", bindings); t->connect("on_file_selected", this, "on_universal_image_path_changed", bindings); t->call_deferred("do_set_image_path", _node->call(getter)); return slot_idx; } int MMGraphNode::add_slot_gradient() { ERR_FAIL_COND_V(!_node->is_class("GradientBase"), 0); MMGradientEditor *ge = memnew(MMGradientEditor); ge->set_graph_node(this); ge->set_undo_redo(_undo_redo); int slot_idx = add_slot(MMNodeUniversalProperty::SLOT_TYPE_NONE, MMNodeUniversalProperty::SLOT_TYPE_NONE, "", "", ge); ge->set_value(_node); //ge.texture = _node.call(getter, _material, slot_idx); //properties[slot_idx].append(ge.texture); return slot_idx; } int MMGraphNode::add_slot_polygon() { ERR_FAIL_COND_V(!_node->is_class("PolygonBase"), 0); PolygonEdit *pe = memnew(PolygonEdit); int slot_idx = add_slot(MMNodeUniversalProperty::SLOT_TYPE_NONE, MMNodeUniversalProperty::SLOT_TYPE_NONE, "", "", pe); pe->set_value(_node); //ge.texture = _node.call(getter, _material, slot_idx); //properties[slot_idx].append(ge.texture); return slot_idx; } int MMGraphNode::add_slot_curve() { ERR_FAIL_COND_V(!_node->is_class("CurveBase"), 0); CurveEdit *ce = memnew(CurveEdit); int slot_idx = add_slot(MMNodeUniversalProperty::SLOT_TYPE_NONE, MMNodeUniversalProperty::SLOT_TYPE_NONE, "", "", ce); ce->set_value(_node); //ge.texture = _node.call(getter, _material, slot_idx); //properties[slot_idx].append(ge.texture); return slot_idx; } int MMGraphNode::add_slot_color(const String &getter, const String &setter) { ColorPickerButton *cp = memnew(ColorPickerButton); int slot_idx = add_slot(MMNodeUniversalProperty::SLOT_TYPE_NONE, MMNodeUniversalProperty::SLOT_TYPE_NONE, getter, setter, cp); cp->set_pick_color(_node->call(getter)); Vector bindings; bindings.push_back(slot_idx); cp->connect("popup_closed", this, "on_color_picker_popup_closed", bindings); return slot_idx; } int MMGraphNode::add_slot_color_universal(const Ref &property) { ColorPickerButton *cp = memnew(ColorPickerButton); int slot_idx = add_slot(property->get_input_slot_type(), property->get_output_slot_type(), "", "", cp); cp->set_pick_color(property->get_default_value_const()); properties.write[slot_idx].universal_property = property; Vector bindings; bindings.push_back(slot_idx); cp->connect("color_changed", this, "on_universal_color_changed", bindings); return slot_idx; } int MMGraphNode::add_slot_label(const String &getter, const String &setter, const String &slot_name) { Label *l = memnew(Label); l->set_text(slot_name); return add_slot(MMNodeUniversalProperty::SLOT_TYPE_NONE, MMNodeUniversalProperty::SLOT_TYPE_NONE, getter, setter, l); } int MMGraphNode::add_slot_line_edit(const String &getter, const String &setter, const String &slot_name, const String &placeholder) { VBoxContainer *bc = memnew(VBoxContainer); Label *l = memnew(Label); l->set_text(slot_name); bc->add_child(l); LineEdit *le = memnew(LineEdit); le->set_placeholder(placeholder); bc->add_child(le); int slot_idx = add_slot(MMNodeUniversalProperty::SLOT_TYPE_NONE, MMNodeUniversalProperty::SLOT_TYPE_NONE, getter, setter, bc); le->set_text(_node->call(getter)); Vector bindings; bindings.push_back(slot_idx); le->connect("text_entered", this, "on_slot_line_edit_text_entered", bindings); return slot_idx; } int MMGraphNode::add_slot_enum(const String &getter, const String &setter, const String &slot_name, const Array &values) { VBoxContainer *bc = memnew(VBoxContainer); if (slot_name != "") { Label *l = memnew(Label); l->set_text(slot_name); bc->add_child(l); } OptionButton *mb = memnew(OptionButton); for (int i = 0; i < values.size(); ++i) { String v = values[i]; mb->add_item(v); } bc->add_child(mb); int slot_idx = add_slot(MMNodeUniversalProperty::SLOT_TYPE_NONE, MMNodeUniversalProperty::SLOT_TYPE_NONE, getter, setter, bc); mb->select(_node->call(getter)); Vector bindings; bindings.push_back(slot_idx); mb->connect("item_selected", this, "on_slot_enum_item_selected", bindings); return slot_idx; } int MMGraphNode::add_slot_int(const String &getter, const String &setter, const String &slot_name, const Vector2 &prange) { VBoxContainer *bc = memnew(VBoxContainer); Label *l = memnew(Label); l->set_text(slot_name); bc->add_child(l); SpinBox *sb = memnew(SpinBox); sb->set_use_rounded_values(true); sb->set_min(prange.x); sb->set_max(prange.y); bc->add_child(sb); int slot_idx = add_slot(MMNodeUniversalProperty::SLOT_TYPE_NONE, MMNodeUniversalProperty::SLOT_TYPE_NONE, getter, setter, bc); sb->set_value(_node->call(getter)); Vector bindings; bindings.push_back(slot_idx); sb->connect("value_changed", this, "on_int_spinbox_value_changed", bindings); return slot_idx; } int MMGraphNode::add_slot_bool(const String &getter, const String &setter, const String &slot_name) { CheckBox *cb = memnew(CheckBox); cb->set_text(slot_name); int slot_idx = add_slot(MMNodeUniversalProperty::SLOT_TYPE_NONE, MMNodeUniversalProperty::SLOT_TYPE_NONE, getter, setter, cb); cb->set_pressed(_node->call(getter)); cb->connect("toggled", *_node, setter); return slot_idx; } int MMGraphNode::add_slot_label_universal(const Ref &property) { Label *l = memnew(Label); l->set_text(property->get_slot_name()); int slot_idx = add_slot(property->get_input_slot_type(), property->get_output_slot_type(), "", "", l); properties.write[slot_idx].universal_property = property; return slot_idx; } int MMGraphNode::add_slot_int_universal(const Ref &property) { VBoxContainer *bc = memnew(VBoxContainer); Label *l = memnew(Label); l->set_text(property->get_slot_name()); bc->add_child(l); SpinBox *sb = memnew(SpinBox); sb->set_use_rounded_values(true); sb->set_min(property->get_value_range().x); sb->set_max(property->get_value_range().y); bc->add_child(sb); int slot_idx = add_slot(property->get_input_slot_type(), property->get_output_slot_type(), "", "", bc); sb->set_value(property->get_default_value_const()); Vector bindings; bindings.push_back(slot_idx); sb->connect("value_changed", this, "on_int_universal_spinbox_value_changed", bindings); properties.write[slot_idx].universal_property = property; return slot_idx; } int MMGraphNode::add_slot_float(const String &getter, const String &setter, const String &slot_name, const float step, const Vector2 &prange) { VBoxContainer *bc = memnew(VBoxContainer); Label *l = memnew(Label); l->set_text(slot_name); bc->add_child(l); SpinBox *sb = memnew(SpinBox); bc->add_child(sb); int slot_idx = add_slot(MMNodeUniversalProperty::SLOT_TYPE_NONE, MMNodeUniversalProperty::SLOT_TYPE_NONE, getter, setter, bc); sb->set_use_rounded_values(false); sb->set_step(step); sb->set_min(prange.x); sb->set_max(prange.y); sb->set_value(_node->call(getter)); Vector bindings; bindings.push_back(slot_idx); sb->connect("value_changed", this, "on_float_spinbox_value_changed", bindings); return slot_idx; } int MMGraphNode::add_slot_float_universal(const Ref &property) { VBoxContainer *bc = memnew(VBoxContainer); Label *l = memnew(Label); l->set_text(property->get_slot_name()); bc->add_child(l); SpinBox *sb = memnew(SpinBox); bc->add_child(sb); int slot_idx = add_slot(property->get_input_slot_type(), property->get_output_slot_type(), "", "", bc); sb->set_use_rounded_values(false); sb->set_step(property->get_value_step()); sb->set_min(property->get_value_range().x); sb->set_max(property->get_value_range().y); sb->set_value(property->get_default_value_const()); properties.write[slot_idx].universal_property = property; Vector bindings; bindings.push_back(slot_idx); sb->connect("value_changed", this, "on_float_universal_spinbox_value_changed", bindings); return slot_idx; } int MMGraphNode::add_slot_vector2(const String &getter, const String &setter, const String &slot_name, const float step, const Vector2 &prange) { VBoxContainer *bc = memnew(VBoxContainer); Label *l = memnew(Label); l->set_text(slot_name); bc->add_child(l); SpinBox *sbx = memnew(SpinBox); bc->add_child(sbx); SpinBox *sby = memnew(SpinBox); bc->add_child(sby); int slot_idx = add_slot(MMNodeUniversalProperty::SLOT_TYPE_NONE, MMNodeUniversalProperty::SLOT_TYPE_NONE, getter, setter, bc); sbx->set_use_rounded_values(false); sby->set_use_rounded_values(false); sbx->set_step(step); sby->set_step(step); sbx->set_min(prange.x); sbx->set_max(prange.y); sby->set_min(prange.x); sby->set_max(prange.y); Vector2 val = _node->call(getter); sbx->set_value(val.x); sby->set_value(val.y); Vector bindings; bindings.push_back(slot_idx); bindings.push_back(sbx); bindings.push_back(sby); sbx->connect("value_changed", this, "on_vector2_spinbox_value_changed", bindings); sby->connect("value_changed", this, "on_vector2_spinbox_value_changed", bindings); return slot_idx; } int MMGraphNode::add_slot_vector3(const String &getter, const String &setter, const String &slot_name, const float step, const Vector2 &prange) { VBoxContainer *bc = memnew(VBoxContainer); Label *l = memnew(Label); l->set_text(slot_name); bc->add_child(l); SpinBox *sbx = memnew(SpinBox); bc->add_child(sbx); SpinBox *sby = memnew(SpinBox); bc->add_child(sby); SpinBox *sbz = memnew(SpinBox); bc->add_child(sbz); int slot_idx = add_slot(MMNodeUniversalProperty::SLOT_TYPE_NONE, MMNodeUniversalProperty::SLOT_TYPE_NONE, getter, setter, bc); sbx->set_use_rounded_values(false); sby->set_use_rounded_values(false); sbz->set_use_rounded_values(false); sbx->set_step(step); sby->set_step(step); sbz->set_step(step); sbx->set_min(prange.x); sbx->set_max(prange.y); sby->set_min(prange.x); sby->set_max(prange.y); sbz->set_min(prange.x); sbz->set_max(prange.y); Vector3 val = _node->call(getter); sbx->set_value(val.x); sby->set_value(val.y); sbz->set_value(val.z); Vector bindings; bindings.push_back(slot_idx); bindings.push_back(sbx); bindings.push_back(sby); bindings.push_back(sbz); sbx->connect("value_changed", this, "on_vector3_spinbox_value_changed", bindings); sby->connect("value_changed", this, "on_vector3_spinbox_value_changed", bindings); sbz->connect("value_changed", this, "on_vector3_spinbox_value_changed", bindings); return slot_idx; } int MMGraphNode::add_slot_vector2_universal(const Ref &property) { VBoxContainer *bc = memnew(VBoxContainer); Label *l = memnew(Label); l->set_text(property->get_slot_name()); bc->add_child(l); SpinBox *sbx = memnew(SpinBox); bc->add_child(sbx); SpinBox *sby = memnew(SpinBox); bc->add_child(sby); int slot_idx = add_slot(property->get_input_slot_type(), property->get_output_slot_type(), "", "", bc); sbx->set_use_rounded_values(false); sby->set_use_rounded_values(false); sbx->set_step(property->get_value_step()); sby->set_step(property->get_value_step()); sbx->set_min(property->get_value_range().x); sbx->set_max(property->get_value_range().y); sby->set_min(property->get_value_range().x); sby->set_max(property->get_value_range().y); Vector2 val = property->get_default_value_const(); sbx->set_value(val.x); sby->set_value(val.y); properties.write[slot_idx].universal_property = property; Vector bindings; bindings.push_back(slot_idx); bindings.push_back(sbx); bindings.push_back(sby); sbx->connect("value_changed", this, "on_vector2_universal_spinbox_value_changed", bindings); sby->connect("value_changed", this, "on_vector2_universal_spinbox_value_changed", bindings); return slot_idx; } int MMGraphNode::add_slot(const int input_type, const int output_type, const String &getter, const String &setter, Control *control) { add_child(control); int slot_idx = get_child_count() - 1; MMGraphNodeEntry e; e.slot_idx = slot_idx; e.input_type = input_type; e.output_type = output_type; e.getter = getter; e.setter = setter; e.control = control; properties.push_back(e); /* Array arr; arr.append(slot_idx); arr.append(input_type); arr.append(output_type); arr.append(getter); arr.append(setter); arr.append(control); properties.append(arr); */ set_slot_enabled_left(slot_idx, input_type != -1); set_slot_enabled_right(slot_idx, output_type != -1); if (input_type != -1) { set_slot_type_left(slot_idx, input_type); set_slot_color_left(slot_idx, get_slot_color(input_type)); } if (output_type != -1) { set_slot_type_left(slot_idx, output_type); set_slot_color_right(slot_idx, get_slot_color(output_type)); } return slot_idx; } bool MMGraphNode::connect_slot(const int slot_idx, Node *p_to_node, const int to_slot_idx) { MMGraphNode *to_node = Object::cast_to(p_to_node); ERR_FAIL_COND_V(!to_node, false); int from_property_index = -1; int to_property_index = -1; for (int i = 0; i < properties.size(); ++i) { //i in range(properties.size()) if (properties[i].output_type != -1) { from_property_index += 1; if (from_property_index == slot_idx) { from_property_index = i; break; } } } for (int i = 0; i < to_node->properties.size(); ++i) { //i in range(to_node.properties.size()) if (to_node->properties[i].input_type != -1) { to_property_index += 1; if (to_property_index == to_slot_idx) { to_property_index = i; break; } //to_node.properties[to_property_index][6].set_input_property(properties[from_property_index][6]); } } _undo_redo->create_action("MMGD: connect_slot"); _undo_redo->add_do_method(*(to_node->properties.write[to_property_index].universal_property), "set_input_property", *(properties.write[from_property_index].universal_property)); _undo_redo->add_undo_method(*(to_node->properties.write[to_property_index].universal_property), "set_input_property", *(to_node->properties.write[to_property_index].universal_property->get_input_property())); _undo_redo->commit_action(); return true; } bool MMGraphNode::disconnect_slot(const int slot_idx, Node *p_to_node, const int to_slot_idx) { MMGraphNode *to_node = Object::cast_to(p_to_node); ERR_FAIL_COND_V(!to_node, false); int from_property_index = -1; int to_property_index = -1; for (int i = 0; i < properties.size(); ++i) { //i in range(properties.size()) if (properties[i].output_type != -1) { from_property_index += 1; if (from_property_index == slot_idx) { from_property_index = i; break; } } } for (int i = 0; i < to_node->properties.size(); ++i) { //i in range(to_node.properties.size()) if (to_node->properties[i].input_type != -1) { to_property_index += 1; if (to_property_index == to_slot_idx) { to_property_index = i; break; } //to_node.properties[to_property_index][6].set_input_property(null); } } _undo_redo->create_action("MMGD: disconnect_slot"); _undo_redo->add_do_method(*(to_node->properties.write[to_property_index].universal_property), "unset_input_property"); _undo_redo->add_undo_method(*(to_node->properties.write[to_property_index].universal_property), "set_input_property", *(to_node->properties.write[to_property_index].universal_property->get_input_property())); _undo_redo->commit_action(); return true; } int MMGraphNode::get_input_property_graph_node_slot_index(const Variant &property) { int property_index = -1; for (int i = 0; i < properties.size(); ++i) { //i in range(properties.size()) if (properties[i].input_type != -1) { property_index += 1; if (properties[i].universal_property == property) { break; } } } return property_index; } int MMGraphNode::get_output_property_graph_node_slot_index(const Variant &property) { int property_index = -1; for (int i = 0; i < properties.size(); ++i) { //i in range(properties.size()) if (properties[i].output_type != -1) { property_index += 1; if (properties[i].universal_property == property) { break; } } } return property_index; } Control *MMGraphNode::get_property_control(const int slot_idx) { return properties[slot_idx].control; } void MMGraphNode::set_node(const Ref &material, const Ref &node) { _node = node; _material = material; if (!_node.is_valid()) { return; } set_title(_node->get_class()); Ref