void VisualShaderEditor::_update_graph() { if (updating) return; if (visual_shader.is_null()) return; graph->set_scroll_ofs(visual_shader->get_graph_offset() * EDSCALE); VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); graph->clear_connections(); //erase all nodes for (int i = 0; i < graph->get_child_count(); i++) { if (Object::cast_to<GraphNode>(graph->get_child(i))) { memdelete(graph->get_child(i)); i--; } } static const Color type_color[3] = { Color::html("#61daf4"), Color::html("#d67dee"), Color::html("#f6a86e") }; List<VisualShader::Connection> connections; visual_shader->get_node_connections(type, &connections); Ref<StyleBoxEmpty> label_style = make_empty_stylebox(2, 1, 2, 1); Vector<int> nodes = visual_shader->get_node_list(type); 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]); GraphNode *node = memnew(GraphNode); graph->add_child(node); /*if (!vsnode->is_connected("changed", this, "_node_changed")) { vsnode->connect("changed", this, "_node_changed", varray(vsnode->get_instance_id()), CONNECT_DEFERRED); }*/ node->set_offset(position); node->set_title(vsnode->get_caption()); node->set_name(itos(nodes[n_i])); if (nodes[n_i] >= 2) { node->set_show_close_button(true); node->connect("close_request", this, "_delete_request", varray(nodes[n_i]), CONNECT_DEFERRED); } node->connect("dragged", this, "_node_dragged", varray(nodes[n_i])); Control *custom_editor = NULL; int port_offset = 0; Ref<VisualShaderNodeUniform> uniform = vsnode; if (uniform.is_valid()) { LineEdit *uniform_name = memnew(LineEdit); uniform_name->set_text(uniform->get_uniform_name()); node->add_child(uniform_name); uniform_name->connect("text_entered", this, "_line_edit_changed", varray(uniform_name, nodes[n_i])); uniform_name->connect("focus_exited", this, "_line_edit_focus_out", varray(uniform_name, nodes[n_i])); if (vsnode->get_input_port_count() == 0 && vsnode->get_output_port_count() == 1 && vsnode->get_output_port_name(0) == "") { //shortcut VisualShaderNode::PortType port_right = vsnode->get_output_port_type(0); node->set_slot(0, false, VisualShaderNode::PORT_TYPE_SCALAR, Color(), true, port_right, type_color[port_right]); continue; } port_offset++; } for (int i = 0; i < plugins.size(); i++) { custom_editor = plugins.write[i]->create_editor(vsnode); if (custom_editor) { break; } } if (custom_editor && vsnode->get_output_port_count() > 0 && vsnode->get_output_port_name(0) == "" && (vsnode->get_input_port_count() == 0 || vsnode->get_input_port_name(0) == "")) { //will be embedded in first port } else if (custom_editor) { port_offset++; node->add_child(custom_editor); custom_editor = NULL; } for (int i = 0; i < MAX(vsnode->get_input_port_count(), vsnode->get_output_port_count()); i++) { if (vsnode->is_port_separator(i)) { node->add_child(memnew(HSeparator)); port_offset++; } bool valid_left = i < vsnode->get_input_port_count(); VisualShaderNode::PortType port_left = VisualShaderNode::PORT_TYPE_SCALAR; bool port_left_used = false; String name_left; if (valid_left) { name_left = vsnode->get_input_port_name(i); port_left = vsnode->get_input_port_type(i); for (List<VisualShader::Connection>::Element *E = connections.front(); E; E = E->next()) { if (E->get().to_node == nodes[n_i] && E->get().to_port == i) { port_left_used = true; } } } bool valid_right = i < vsnode->get_output_port_count(); VisualShaderNode::PortType port_right = VisualShaderNode::PORT_TYPE_SCALAR; String name_right; if (valid_right) { name_right = vsnode->get_output_port_name(i); port_right = vsnode->get_output_port_type(i); } HBoxContainer *hb = memnew(HBoxContainer); Variant default_value; if (valid_left && !port_left_used) { default_value = vsnode->get_input_port_default_value(i); } if (default_value.get_type() != Variant::NIL) { // only a label Button *button = memnew(Button); hb->add_child(button); button->connect("pressed", this, "_edit_port_default_input", varray(button, nodes[n_i], i)); switch (default_value.get_type()) { case Variant::COLOR: { button->set_custom_minimum_size(Size2(30, 0) * EDSCALE); button->connect("draw", this, "_draw_color_over_button", varray(button, default_value)); } break; case Variant::INT: case Variant::REAL: { button->set_text(String::num(default_value, 4)); } break; case Variant::VECTOR3: { Vector3 v = default_value; button->set_text(String::num(v.x, 3) + "," + String::num(v.y, 3) + "," + String::num(v.z, 3)); } break; default: {} } } if (i == 0 && custom_editor) { hb->add_child(custom_editor); custom_editor->set_h_size_flags(SIZE_EXPAND_FILL); } else { if (valid_left) { Label *label = memnew(Label); label->set_text(name_left); label->add_style_override("normal", label_style); //more compact hb->add_child(label); } hb->add_spacer(); if (valid_right) { Label *label = memnew(Label); label->set_text(name_right); label->set_align(Label::ALIGN_RIGHT); label->add_style_override("normal", label_style); //more compact hb->add_child(label); } } if (valid_right && edit_type->get_selected() == VisualShader::TYPE_FRAGMENT) { TextureButton *preview = memnew(TextureButton); preview->set_toggle_mode(true); preview->set_normal_texture(get_icon("GuiVisibilityHidden", "EditorIcons")); preview->set_pressed_texture(get_icon("GuiVisibilityVisible", "EditorIcons")); preview->set_v_size_flags(SIZE_SHRINK_CENTER); if (vsnode->get_output_port_for_preview() == i) { preview->set_pressed(true); } preview->connect("pressed", this, "_preview_select_port", varray(nodes[n_i], i), CONNECT_DEFERRED); hb->add_child(preview); } node->add_child(hb); node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], valid_right, port_right, type_color[port_right]); if (EditorSettings::get_singleton()->get("interface/theme/use_graph_node_headers")) { Ref<StyleBoxFlat> sb = node->get_stylebox("frame", "GraphNode"); Color c = sb->get_border_color(MARGIN_TOP); Color mono_color = ((c.r + c.g + c.b) / 3) < 0.7 ? Color(1.0, 1.0, 1.0) : Color(0.0, 0.0, 0.0); mono_color.a = 0.85; c = mono_color; node->add_color_override("title_color", c); c.a = 0.7; node->add_color_override("close_color", c); } } if (vsnode->get_output_port_for_preview() >= 0) { 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); } String error = vsnode->get_warning(visual_shader->get_mode(), type); if (error != String()) { Label *error_label = memnew(Label); error_label->add_color_override("font_color", get_color("error_color", "Editor")); error_label->set_text(error); node->add_child(error_label); } } 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; int to = E->get().to_node; int to_idx = E->get().to_port; graph->connect_node(itos(from), from_idx, itos(to), to_idx); } }
void AnimationNodeBlendTreeEditor::_update_graph() { if (updating) return; graph->set_scroll_ofs(blend_tree->get_graph_offset() * EDSCALE); if (blend_tree->get_parent().is_valid()) { goto_parent->show(); } else { goto_parent->hide(); } graph->clear_connections(); //erase all nodes for (int i = 0; i < graph->get_child_count(); i++) { if (Object::cast_to<GraphNode>(graph->get_child(i))) { memdelete(graph->get_child(i)); i--; } } animations.clear(); List<StringName> nodes; blend_tree->get_node_list(&nodes); for (List<StringName>::Element *E = nodes.front(); E; E = E->next()) { GraphNode *node = memnew(GraphNode); graph->add_child(node); Ref<AnimationNode> agnode = blend_tree->get_node(E->get()); if (!agnode->is_connected("changed", this, "_node_changed")) { agnode->connect("changed", this, "_node_changed", varray(agnode->get_instance_id()), CONNECT_DEFERRED); } node->set_offset(agnode->get_position() * EDSCALE); node->set_title(agnode->get_caption()); node->set_name(E->get()); int base = 0; if (String(E->get()) != "output") { LineEdit *name = memnew(LineEdit); name->set_text(E->get()); name->set_expand_to_text_length(true); node->add_child(name); node->set_slot(0, false, 0, Color(), true, 0, get_color("font_color", "Label")); name->connect("text_entered", this, "_node_renamed", varray(agnode)); name->connect("focus_exited", this, "_node_renamed_focus_out", varray(name, agnode)); base = 1; node->set_show_close_button(true); node->connect("close_request", this, "_delete_request", varray(E->get()), CONNECT_DEFERRED); } for (int i = 0; i < agnode->get_input_count(); i++) { Label *in_name = memnew(Label); node->add_child(in_name); in_name->set_text(agnode->get_input_name(i)); node->set_slot(base + i, true, 0, get_color("font_color", "Label"), false, 0, Color()); } node->connect("dragged", this, "_node_dragged", varray(agnode)); if (EditorNode::get_singleton()->item_has_editor(agnode.ptr())) { node->add_child(memnew(HSeparator)); Button *open_in_editor = memnew(Button); open_in_editor->set_text(TTR("Open Editor")); open_in_editor->set_icon(get_icon("Edit", "EditorIcons")); node->add_child(open_in_editor); open_in_editor->connect("pressed", this, "_open_in_editor", varray(E->get()), CONNECT_DEFERRED); open_in_editor->set_h_size_flags(SIZE_SHRINK_CENTER); } if (agnode->has_filter()) { node->add_child(memnew(HSeparator)); Button *edit_filters = memnew(Button); edit_filters->set_text(TTR("Edit Filters")); edit_filters->set_icon(get_icon("AnimationFilter", "EditorIcons")); node->add_child(edit_filters); edit_filters->connect("pressed", this, "_edit_filters", varray(E->get()), CONNECT_DEFERRED); edit_filters->set_h_size_flags(SIZE_SHRINK_CENTER); } Ref<AnimationNodeAnimation> anim = agnode; if (anim.is_valid()) { MenuButton *mb = memnew(MenuButton); mb->set_text(anim->get_animation()); mb->set_icon(get_icon("Animation", "EditorIcons")); Array options; node->add_child(memnew(HSeparator)); node->add_child(mb); ProgressBar *pb = memnew(ProgressBar); AnimationTree *player = anim->get_tree(); if (player->has_node(player->get_animation_player())) { AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(player->get_node(player->get_animation_player())); if (ap) { List<StringName> anims; ap->get_animation_list(&anims); for (List<StringName>::Element *F = anims.front(); F; F = F->next()) { mb->get_popup()->add_item(F->get()); options.push_back(F->get()); } if (ap->has_animation(anim->get_animation())) { pb->set_max(ap->get_animation(anim->get_animation())->get_length()); } } } pb->set_percent_visible(false); animations[E->get()] = pb; node->add_child(pb); mb->get_popup()->connect("index_pressed", this, "_anim_selected", varray(options, E->get()), CONNECT_DEFERRED); } Ref<AnimationNodeOneShot> oneshot = agnode; if (oneshot.is_valid()) { HBoxContainer *play_stop = memnew(HBoxContainer); play_stop->add_spacer(); Button *play = memnew(Button); play->set_icon(get_icon("Play", "EditorIcons")); play->connect("pressed", this, "_oneshot_start", varray(E->get()), CONNECT_DEFERRED); play_stop->add_child(play); Button *stop = memnew(Button); stop->set_icon(get_icon("Stop", "EditorIcons")); stop->connect("pressed", this, "_oneshot_stop", varray(E->get()), CONNECT_DEFERRED); play_stop->add_child(stop); play_stop->add_spacer(); node->add_child(play_stop); } } List<AnimationNodeBlendTree::NodeConnection> connections; blend_tree->get_node_connections(&connections); for (List<AnimationNodeBlendTree::NodeConnection>::Element *E = connections.front(); E; E = E->next()) { StringName from = E->get().output_node; StringName to = E->get().input_node; int to_idx = E->get().input_index; graph->connect_node(from, 0, to, to_idx); } }
void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { Ref<InputEventMouseMotion> mm = p_ev; if (mm.is_valid() && (mm->get_button_mask() & BUTTON_MASK_MIDDLE || (mm->get_button_mask() & BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE)))) { h_scroll->set_value(h_scroll->get_value() - mm->get_relative().x); v_scroll->set_value(v_scroll->get_value() - mm->get_relative().y); } if (mm.is_valid() && dragging) { just_selected = true; // TODO: Remove local mouse pos hack if/when InputEventMouseMotion is fixed to support floats //drag_accum+=Vector2(mm->get_relative().x,mm->get_relative().y); drag_accum = get_local_mouse_position() - drag_origin; for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); if (gn && gn->is_selected()) { Vector2 pos = (gn->get_drag_from() * zoom + drag_accum) / zoom; if (is_using_snap()) { int snap = get_snap(); pos = pos.snapped(Vector2(snap, snap)); } gn->set_offset(pos); } } } if (mm.is_valid() && box_selecting) { box_selecting_to = get_local_mouse_position(); box_selecting_rect = Rect2(MIN(box_selecting_from.x, box_selecting_to.x), MIN(box_selecting_from.y, box_selecting_to.y), ABS(box_selecting_from.x - box_selecting_to.x), ABS(box_selecting_from.y - box_selecting_to.y)); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); if (!gn) continue; Rect2 r = gn->get_rect(); r.size *= zoom; bool in_box = r.intersects(box_selecting_rect); if (in_box) gn->set_selected(box_selection_mode_aditive); else gn->set_selected(previus_selected.find(gn) != NULL); } top_layer->update(); } Ref<InputEventMouseButton> b = p_ev; if (b.is_valid()) { if (b->get_button_index() == BUTTON_RIGHT && b->is_pressed()) { if (box_selecting) { box_selecting = false; for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); if (!gn) continue; gn->set_selected(previus_selected.find(gn) != NULL); } top_layer->update(); } else { if (connecting) { connecting = false; top_layer->update(); } else { emit_signal("popup_request", b->get_global_position()); } } } if (b->get_button_index() == BUTTON_LEFT && !b->is_pressed() && dragging) { if (!just_selected && drag_accum == Vector2() && Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { //deselect current node for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); if (gn) { Rect2 r = gn->get_rect(); r.size *= zoom; if (r.has_point(get_local_mouse_position())) gn->set_selected(false); } } } if (drag_accum != Vector2()) { emit_signal("_begin_node_move"); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); if (gn && gn->is_selected()) gn->set_drag(false); } emit_signal("_end_node_move"); } dragging = false; top_layer->update(); update(); connections_layer->update(); } if (b->get_button_index() == BUTTON_LEFT && b->is_pressed()) { GraphNode *gn = NULL; for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn_selected = Object::cast_to<GraphNode>(get_child(i)); if (gn_selected) { if (gn_selected->is_resizing()) continue; if (gn_selected->has_point(gn_selected->get_local_mouse_position())) { gn = gn_selected; break; } } } if (gn) { if (_filter_input(b->get_position())) return; dragging = true; drag_accum = Vector2(); drag_origin = get_local_mouse_position(); just_selected = !gn->is_selected(); if (!gn->is_selected() && !Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { for (int i = 0; i < get_child_count(); i++) { GraphNode *o_gn = Object::cast_to<GraphNode>(get_child(i)); if (o_gn) o_gn->set_selected(o_gn == gn); } } gn->set_selected(true); for (int i = 0; i < get_child_count(); i++) { GraphNode *o_gn = Object::cast_to<GraphNode>(get_child(i)); if (!o_gn) continue; if (o_gn->is_selected()) o_gn->set_drag(true); } } else { if (_filter_input(b->get_position())) return; if (Input::get_singleton()->is_key_pressed(KEY_SPACE)) return; box_selecting = true; box_selecting_from = get_local_mouse_position(); if (b->get_control()) { box_selection_mode_aditive = true; previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i)); if (!gn2 || !gn2->is_selected()) continue; previus_selected.push_back(gn2); } } else if (b->get_shift()) { box_selection_mode_aditive = false; previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i)); if (!gn2 || !gn2->is_selected()) continue; previus_selected.push_back(gn2); } } else { box_selection_mode_aditive = true; previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i)); if (!gn2) continue; gn2->set_selected(false); } } } } if (b->get_button_index() == BUTTON_LEFT && !b->is_pressed() && box_selecting) { box_selecting = false; previus_selected.clear(); top_layer->update(); } if (b->get_button_index() == BUTTON_WHEEL_UP && b->is_pressed()) { //too difficult to get right //set_zoom(zoom*ZOOM_SCALE); } if (b->get_button_index() == BUTTON_WHEEL_DOWN && b->is_pressed()) { //too difficult to get right //set_zoom(zoom/ZOOM_SCALE); } if (b->get_button_index() == BUTTON_WHEEL_UP && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() * b->get_factor() / 8); } if (b->get_button_index() == BUTTON_WHEEL_DOWN && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * b->get_factor() / 8); } if (b->get_button_index() == BUTTON_WHEEL_RIGHT || (b->get_button_index() == BUTTON_WHEEL_DOWN && Input::get_singleton()->is_key_pressed(KEY_SHIFT))) { h_scroll->set_value(h_scroll->get_value() + h_scroll->get_page() * b->get_factor() / 8); } if (b->get_button_index() == BUTTON_WHEEL_LEFT || (b->get_button_index() == BUTTON_WHEEL_UP && Input::get_singleton()->is_key_pressed(KEY_SHIFT))) { h_scroll->set_value(h_scroll->get_value() - h_scroll->get_page() * b->get_factor() / 8); } } Ref<InputEventKey> k = p_ev; if (k.is_valid() && k->get_scancode() == KEY_D && k->is_pressed() && k->get_command()) { emit_signal("duplicate_nodes_request"); accept_event(); } if (k.is_valid() && k->get_scancode() == KEY_DELETE && k->is_pressed()) { emit_signal("delete_nodes_request"); accept_event(); } Ref<InputEventMagnifyGesture> magnify_gesture = p_ev; if (magnify_gesture.is_valid()) { set_zoom_custom(zoom * magnify_gesture->get_factor(), magnify_gesture->get_position()); } Ref<InputEventPanGesture> pan_gesture = p_ev; if (pan_gesture.is_valid()) { h_scroll->set_value(h_scroll->get_value() + h_scroll->get_page() * pan_gesture->get_delta().x / 8); v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * pan_gesture->get_delta().y / 8); } }
void GraphEdit::_gui_input(const InputEvent &p_ev) { if (p_ev.type == InputEvent::MOUSE_MOTION && (p_ev.mouse_motion.button_mask & BUTTON_MASK_MIDDLE || (p_ev.mouse_motion.button_mask & BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE)))) { h_scroll->set_value(h_scroll->get_value() - p_ev.mouse_motion.relative_x); v_scroll->set_value(v_scroll->get_value() - p_ev.mouse_motion.relative_y); } if (p_ev.type == InputEvent::MOUSE_MOTION && dragging) { just_selected = true; // TODO: Remove local mouse pos hack if/when InputEventMouseMotion is fixed to support floats //drag_accum+=Vector2(p_ev.mouse_motion.relative_x,p_ev.mouse_motion.relative_y); drag_accum = get_local_mouse_pos() - drag_origin; for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = get_child(i)->cast_to<GraphNode>(); if (gn && gn->is_selected()) { Vector2 pos = (gn->get_drag_from() * zoom + drag_accum) / zoom; if (is_using_snap()) { int snap = get_snap(); pos = pos.snapped(Vector2(snap, snap)); } gn->set_offset(pos); } } } if (p_ev.type == InputEvent::MOUSE_MOTION && box_selecting) { box_selecting_to = get_local_mouse_pos(); box_selecting_rect = Rect2(MIN(box_selecting_from.x, box_selecting_to.x), MIN(box_selecting_from.y, box_selecting_to.y), ABS(box_selecting_from.x - box_selecting_to.x), ABS(box_selecting_from.y - box_selecting_to.y)); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = get_child(i)->cast_to<GraphNode>(); if (!gn) continue; Rect2 r = gn->get_rect(); r.size *= zoom; bool in_box = r.intersects(box_selecting_rect); if (in_box) gn->set_selected(box_selection_mode_aditive); else gn->set_selected(previus_selected.find(gn) != NULL); } top_layer->update(); } if (p_ev.type == InputEvent::MOUSE_BUTTON) { const InputEventMouseButton &b = p_ev.mouse_button; if (b.button_index == BUTTON_RIGHT && b.pressed) { if (box_selecting) { box_selecting = false; for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = get_child(i)->cast_to<GraphNode>(); if (!gn) continue; gn->set_selected(previus_selected.find(gn) != NULL); } top_layer->update(); } else { if (connecting) { connecting = false; top_layer->update(); } else { emit_signal("popup_request", Vector2(b.global_x, b.global_y)); } } } if (b.button_index == BUTTON_LEFT && !b.pressed && dragging) { if (!just_selected && drag_accum == Vector2() && Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { //deselect current node for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = get_child(i)->cast_to<GraphNode>(); if (gn) { Rect2 r = gn->get_rect(); r.size *= zoom; if (r.has_point(get_local_mouse_pos())) gn->set_selected(false); } } } if (drag_accum != Vector2()) { emit_signal("_begin_node_move"); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = get_child(i)->cast_to<GraphNode>(); if (gn && gn->is_selected()) gn->set_drag(false); } emit_signal("_end_node_move"); } dragging = false; top_layer->update(); update(); connections_layer->update(); } if (b.button_index == BUTTON_LEFT && b.pressed) { GraphNode *gn = NULL; GraphNode *gn_selected = NULL; for (int i = get_child_count() - 1; i >= 0; i--) { gn_selected = get_child(i)->cast_to<GraphNode>(); if (gn_selected) { if (gn_selected->is_resizing()) continue; Rect2 r = gn_selected->get_rect(); r.size *= zoom; if (r.has_point(get_local_mouse_pos())) gn = gn_selected; break; } } if (gn) { if (_filter_input(Vector2(b.x, b.y))) return; dragging = true; drag_accum = Vector2(); drag_origin = get_local_mouse_pos(); just_selected = !gn->is_selected(); if (!gn->is_selected() && !Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { for (int i = 0; i < get_child_count(); i++) { GraphNode *o_gn = get_child(i)->cast_to<GraphNode>(); if (o_gn) o_gn->set_selected(o_gn == gn); } } gn->set_selected(true); for (int i = 0; i < get_child_count(); i++) { GraphNode *o_gn = get_child(i)->cast_to<GraphNode>(); if (!o_gn) continue; if (o_gn->is_selected()) o_gn->set_drag(true); } } else { if (_filter_input(Vector2(b.x, b.y))) return; if (Input::get_singleton()->is_key_pressed(KEY_SPACE)) return; box_selecting = true; box_selecting_from = get_local_mouse_pos(); if (b.mod.control) { box_selection_mode_aditive = true; previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = get_child(i)->cast_to<GraphNode>(); if (!gn || !gn->is_selected()) continue; previus_selected.push_back(gn); } } else if (b.mod.shift) { box_selection_mode_aditive = false; previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = get_child(i)->cast_to<GraphNode>(); if (!gn || !gn->is_selected()) continue; previus_selected.push_back(gn); } } else { box_selection_mode_aditive = true; previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = get_child(i)->cast_to<GraphNode>(); if (!gn) continue; gn->set_selected(false); } } } } if (b.button_index == BUTTON_LEFT && !b.pressed && box_selecting) { box_selecting = false; previus_selected.clear(); top_layer->update(); } if (b.button_index == BUTTON_WHEEL_UP && b.pressed) { //too difficult to get right //set_zoom(zoom*ZOOM_SCALE); } if (b.button_index == BUTTON_WHEEL_DOWN && b.pressed) { //too difficult to get right //set_zoom(zoom/ZOOM_SCALE); } } if (p_ev.type == InputEvent::KEY && p_ev.key.scancode == KEY_D && p_ev.key.pressed && p_ev.key.mod.command) { emit_signal("duplicate_nodes_request"); accept_event(); } if (p_ev.type == InputEvent::KEY && p_ev.key.scancode == KEY_DELETE && p_ev.key.pressed) { emit_signal("delete_nodes_request"); accept_event(); } }