bool GraphEdit::_filter_input(const Point2 &p_point) { Ref<Texture> port = get_icon("port", "GraphNode"); float grab_r_extend = 2.0; 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(p_point) < grab_r) return true; } 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(p_point) < grab_r) { return true; } } } return false; }
void GraphEdit::_top_layer_draw() { _update_scroll(); if (connecting) { Node *fromn = get_node(connecting_from); ERR_FAIL_COND(!fromn); GraphNode *from = fromn->cast_to<GraphNode>(); ERR_FAIL_COND(!from); Vector2 pos; if (connecting_out) pos = from->get_connection_output_pos(connecting_index); else pos = from->get_connection_input_pos(connecting_index); pos += from->get_pos(); Vector2 topos; topos = connecting_to; Color col = connecting_color; if (connecting_target) { col.r += 0.4; col.g += 0.4; col.b += 0.4; } if (!connecting_out) { SWAP(pos, topos); } _draw_cos_line(top_layer, pos, topos, col, col); } if (box_selecting) top_layer->draw_rect(box_selecting_rect, Color(0.7, 0.7, 1.0, 0.3)); }
void GraphEdit::_top_layer_draw() { _update_scroll(); if (connecting) { Node *fromn = get_node(connecting_from); ERR_FAIL_COND(!fromn); GraphNode *from = fromn->cast_to<GraphNode>(); ERR_FAIL_COND(!from); Vector2 pos; if (connecting_out) pos=from->get_connection_output_pos(connecting_index); else pos=from->get_connection_input_pos(connecting_index); pos+=from->get_pos(); Vector2 topos; topos=connecting_to; Color col=connecting_color; if (connecting_target) { col.r+=0.4; col.g+=0.4; col.b+=0.4; } _draw_cos_line(pos,topos,col); } List<List<Connection>::Element* > to_erase; for(List<Connection>::Element *E=connections.front();E;E=E->next()) { NodePath fromnp(E->get().from); Node * from = get_node(fromnp); if (!from) { to_erase.push_back(E); continue; } GraphNode *gfrom = from->cast_to<GraphNode>(); if (!gfrom) { to_erase.push_back(E); continue; } NodePath tonp(E->get().to); Node * to = get_node(tonp); if (!to) { to_erase.push_back(E); continue; } GraphNode *gto = to->cast_to<GraphNode>(); if (!gto) { to_erase.push_back(E); continue; } Vector2 frompos=gfrom->get_connection_output_pos(E->get().from_port)+gfrom->get_pos(); Color color = gfrom->get_connection_output_color(E->get().from_port); Vector2 topos=gto->get_connection_input_pos(E->get().to_port)+gto->get_pos(); _draw_cos_line(frompos,topos,color); } while(to_erase.size()) { connections.erase(to_erase.front()->get()); to_erase.pop_front(); } if (box_selecting) top_layer->draw_rect(box_selecting_rect,Color(0.7,0.7,1.0,0.3)); }
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(); } }