void AnimationNodeBlendTreeEditor::_node_selected(Object *p_node) { GraphNode *gn = Object::cast_to<GraphNode>(p_node); ERR_FAIL_COND(!gn); String name = gn->get_name(); Ref<AnimationNode> anode = blend_tree->get_node(name); ERR_FAIL_COND(!anode.is_valid()); EditorNode::get_singleton()->push_item(anode.ptr(), "", true); }
void VisualShaderEditor::_node_selected(Object *p_node) { VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); GraphNode *gn = Object::cast_to<GraphNode>(p_node); ERR_FAIL_COND(!gn); int id = String(gn->get_name()).to_int(); Ref<VisualShaderNode> vsnode = visual_shader->get_node(type, id); ERR_FAIL_COND(!vsnode.is_valid()); //do not rely on this, makes editor more complex //EditorNode::get_singleton()->push_item(vsnode.ptr(), "", true); }
void VisualShaderEditor::_duplicate_nodes() { VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); List<int> nodes; Set<int> excluded; for (int i = 0; i < graph->get_child_count(); i++) { GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i)); if (gn) { int id = String(gn->get_name()).to_int(); Ref<VisualShaderNode> node = visual_shader->get_node(type, id); Ref<VisualShaderNodeOutput> output = node; if (output.is_valid()) { // can't duplicate output excluded.insert(id); continue; } if (node.is_valid() && gn->is_selected()) { nodes.push_back(id); } excluded.insert(id); } } if (nodes.empty()) return; undo_redo->create_action(TTR("Duplicate Nodes")); int base_id = visual_shader->get_valid_node_id(type); int id_from = base_id; Map<int, int> connection_remap; for (List<int>::Element *E = nodes.front(); E; E = E->next()) { connection_remap[E->get()] = id_from; Ref<VisualShaderNode> node = visual_shader->get_node(type, E->get()); Ref<VisualShaderNode> dupli = node->duplicate(); undo_redo->add_do_method(visual_shader.ptr(), "add_node", type, dupli, visual_shader->get_node_position(type, E->get()) + Vector2(10, 10) * EDSCALE, id_from); undo_redo->add_undo_method(visual_shader.ptr(), "remove_node", type, id_from); id_from++; } List<VisualShader::Connection> conns; visual_shader->get_node_connections(type, &conns); for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) { if (connection_remap.has(E->get().from_node) && connection_remap.has(E->get().to_node)) { undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, connection_remap[E->get().from_node], E->get().from_port, connection_remap[E->get().to_node], E->get().to_port); } } undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); undo_redo->commit_action(); // reselect duplicated nodes by excluding the other ones for (int i = 0; i < graph->get_child_count(); i++) { GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i)); if (gn) { int id = String(gn->get_name()).to_int(); if (!excluded.has(id)) { gn->set_selected(true); } else { gn->set_selected(false); } } } }
void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { Ref<InputEventMouseButton> mb = p_ev; if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) { Ref<Texture> port = get_icon("port", "GraphNode"); Vector2 mpos(mb->get_position().x, mb->get_position().y); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); if (!gn) continue; for (int j = 0; j < gn->get_connection_output_count(); j++) { Vector2 pos = gn->get_connection_output_position(j) + gn->get_position(); if (is_in_hot_zone(pos, mpos)) { if (valid_left_disconnect_types.has(gn->get_connection_output_type(j))) { //check disconnect for (List<Connection>::Element *E = connections.front(); E; E = E->next()) { if (E->get().from == gn->get_name() && E->get().from_port == j) { Node *to = get_node(String(E->get().to)); if (Object::cast_to<GraphNode>(to)) { connecting_from = E->get().to; connecting_index = E->get().to_port; connecting_out = false; connecting_type = Object::cast_to<GraphNode>(to)->get_connection_input_type(E->get().to_port); connecting_color = Object::cast_to<GraphNode>(to)->get_connection_input_color(E->get().to_port); connecting_target = false; connecting_to = pos; just_disconnected = true; emit_signal("disconnection_request", E->get().from, E->get().from_port, E->get().to, E->get().to_port); to = get_node(String(connecting_from)); //maybe it was erased if (Object::cast_to<GraphNode>(to)) { connecting = true; } return; } } } } connecting = true; connecting_from = gn->get_name(); connecting_index = j; connecting_out = true; connecting_type = gn->get_connection_output_type(j); connecting_color = gn->get_connection_output_color(j); connecting_target = false; connecting_to = pos; just_disconnected = false; return; } } for (int j = 0; j < gn->get_connection_input_count(); j++) { Vector2 pos = gn->get_connection_input_position(j) + gn->get_position(); if (is_in_hot_zone(pos, mpos)) { if (right_disconnects || valid_right_disconnect_types.has(gn->get_connection_input_type(j))) { //check disconnect for (List<Connection>::Element *E = connections.front(); E; E = E->next()) { if (E->get().to == gn->get_name() && E->get().to_port == j) { Node *fr = get_node(String(E->get().from)); if (Object::cast_to<GraphNode>(fr)) { connecting_from = E->get().from; connecting_index = E->get().from_port; connecting_out = true; connecting_type = Object::cast_to<GraphNode>(fr)->get_connection_output_type(E->get().from_port); connecting_color = Object::cast_to<GraphNode>(fr)->get_connection_output_color(E->get().from_port); connecting_target = false; connecting_to = pos; just_disconnected = true; emit_signal("disconnection_request", E->get().from, E->get().from_port, E->get().to, E->get().to_port); fr = get_node(String(connecting_from)); //maybe it was erased if (Object::cast_to<GraphNode>(fr)) { connecting = true; } return; } } } } connecting = true; connecting_from = gn->get_name(); connecting_index = j; connecting_out = false; connecting_type = gn->get_connection_input_type(j); connecting_color = gn->get_connection_input_color(j); connecting_target = false; connecting_to = pos; just_disconnected = true; return; } } } } Ref<InputEventMouseMotion> mm = p_ev; if (mm.is_valid() && connecting) { connecting_to = mm->get_position(); connecting_target = false; top_layer->update(); Ref<Texture> port = get_icon("port", "GraphNode"); Vector2 mpos = mm->get_position(); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); if (!gn) continue; if (!connecting_out) { for (int j = 0; j < gn->get_connection_output_count(); j++) { Vector2 pos = gn->get_connection_output_position(j) + gn->get_position(); int type = gn->get_connection_output_type(j); if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos, mpos)) { connecting_target = true; connecting_to = pos; connecting_target_to = gn->get_name(); connecting_target_index = j; return; } } } else { for (int j = 0; j < gn->get_connection_input_count(); j++) { Vector2 pos = gn->get_connection_input_position(j) + gn->get_position(); int type = gn->get_connection_input_type(j); if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos, mpos)) { connecting_target = true; connecting_to = pos; connecting_target_to = gn->get_name(); connecting_target_index = j; return; } } } } } if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && !mb->is_pressed()) { if (connecting && connecting_target) { String from = connecting_from; int from_slot = connecting_index; String to = connecting_target_to; int to_slot = connecting_target_index; if (!connecting_out) { SWAP(from, to); SWAP(from_slot, to_slot); } emit_signal("connection_request", from, from_slot, to, to_slot); } else if (!just_disconnected) { String from = connecting_from; int from_slot = connecting_index; Vector2 ofs = Vector2(mb->get_position().x, mb->get_position().y); emit_signal("connection_to_empty", from, from_slot, ofs); } connecting = false; top_layer->update(); update(); connections_layer->update(); } }
void GraphEdit::_top_layer_input(const InputEvent &p_ev) { float grab_r_extend = 2.0; if (p_ev.type == InputEvent::MOUSE_BUTTON && p_ev.mouse_button.button_index == BUTTON_LEFT && p_ev.mouse_button.pressed) { Ref<Texture> port = get_icon("port", "GraphNode"); Vector2 mpos(p_ev.mouse_button.x, p_ev.mouse_button.y); float grab_r = port->get_width() * 0.5 * grab_r_extend; for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = get_child(i)->cast_to<GraphNode>(); if (!gn) continue; for (int j = 0; j < gn->get_connection_output_count(); j++) { Vector2 pos = gn->get_connection_output_pos(j) + gn->get_pos(); if (pos.distance_to(mpos) < grab_r) { if (valid_left_disconnect_types.has(gn->get_connection_output_type(j))) { //check disconnect for (List<Connection>::Element *E = connections.front(); E; E = E->next()) { if (E->get().from == gn->get_name() && E->get().from_port == j) { Node *to = get_node(String(E->get().to)); if (to && to->cast_to<GraphNode>()) { connecting_from = E->get().to; connecting_index = E->get().to_port; connecting_out = false; connecting_type = to->cast_to<GraphNode>()->get_connection_input_type(E->get().to_port); connecting_color = to->cast_to<GraphNode>()->get_connection_input_color(E->get().to_port); connecting_target = false; connecting_to = pos; just_disconected = true; emit_signal("disconnection_request", E->get().from, E->get().from_port, E->get().to, E->get().to_port); to = get_node(String(connecting_from)); //maybe it was erased if (to && to->cast_to<GraphNode>()) { connecting = true; } return; } } } } connecting = true; connecting_from = gn->get_name(); connecting_index = j; connecting_out = true; connecting_type = gn->get_connection_output_type(j); connecting_color = gn->get_connection_output_color(j); connecting_target = false; connecting_to = pos; just_disconected = false; return; } } for (int j = 0; j < gn->get_connection_input_count(); j++) { Vector2 pos = gn->get_connection_input_pos(j) + gn->get_pos(); if (pos.distance_to(mpos) < grab_r) { if (right_disconnects || valid_right_disconnect_types.has(gn->get_connection_input_type(j))) { //check disconnect for (List<Connection>::Element *E = connections.front(); E; E = E->next()) { if (E->get().to == gn->get_name() && E->get().to_port == j) { Node *fr = get_node(String(E->get().from)); if (fr && fr->cast_to<GraphNode>()) { connecting_from = E->get().from; connecting_index = E->get().from_port; connecting_out = true; connecting_type = fr->cast_to<GraphNode>()->get_connection_output_type(E->get().from_port); connecting_color = fr->cast_to<GraphNode>()->get_connection_output_color(E->get().from_port); connecting_target = false; connecting_to = pos; just_disconected = true; emit_signal("disconnection_request", E->get().from, E->get().from_port, E->get().to, E->get().to_port); fr = get_node(String(connecting_from)); //maybe it was erased if (fr && fr->cast_to<GraphNode>()) { connecting = true; } return; } } } } connecting = true; connecting_from = gn->get_name(); connecting_index = j; connecting_out = false; connecting_type = gn->get_connection_input_type(j); connecting_color = gn->get_connection_input_color(j); connecting_target = false; connecting_to = pos; just_disconected = true; return; } } } } if (p_ev.type == InputEvent::MOUSE_MOTION && connecting) { connecting_to = Vector2(p_ev.mouse_motion.x, p_ev.mouse_motion.y); connecting_target = false; top_layer->update(); Ref<Texture> port = get_icon("port", "GraphNode"); Vector2 mpos(p_ev.mouse_button.x, p_ev.mouse_button.y); float grab_r = port->get_width() * 0.5 * grab_r_extend; for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = get_child(i)->cast_to<GraphNode>(); if (!gn) continue; if (!connecting_out) { for (int j = 0; j < gn->get_connection_output_count(); j++) { Vector2 pos = gn->get_connection_output_pos(j) + gn->get_pos(); int type = gn->get_connection_output_type(j); if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && pos.distance_to(mpos) < grab_r) { connecting_target = true; connecting_to = pos; connecting_target_to = gn->get_name(); connecting_target_index = j; return; } } } else { for (int j = 0; j < gn->get_connection_input_count(); j++) { Vector2 pos = gn->get_connection_input_pos(j) + gn->get_pos(); int type = gn->get_connection_input_type(j); if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && pos.distance_to(mpos) < grab_r) { connecting_target = true; connecting_to = pos; connecting_target_to = gn->get_name(); connecting_target_index = j; return; } } } } } if (p_ev.type == InputEvent::MOUSE_BUTTON && p_ev.mouse_button.button_index == BUTTON_LEFT && !p_ev.mouse_button.pressed) { if (connecting && connecting_target) { String from = connecting_from; int from_slot = connecting_index; String to = connecting_target_to; int to_slot = connecting_target_index; if (!connecting_out) { SWAP(from, to); SWAP(from_slot, to_slot); } emit_signal("connection_request", from, from_slot, to, to_slot); } else if (!just_disconected) { String from = connecting_from; int from_slot = connecting_index; Vector2 ofs = Vector2(p_ev.mouse_button.x, p_ev.mouse_button.y); emit_signal("connection_to_empty", from, from_slot, ofs); } connecting = false; top_layer->update(); update(); connections_layer->update(); } }