void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventKey> k = p_event; if (tool_select->is_pressed() && k.is_valid() && k->is_pressed() && k->get_scancode() == KEY_DELETE && !k->is_echo()) { if (selected_node != StringName() || selected_transition_to != StringName() || selected_transition_from != StringName()) { _erase_selected(); accept_event(); } } Ref<InputEventMouseButton> mb = p_event; //Add new node if (mb.is_valid() && mb->is_pressed() && ((tool_select->is_pressed() && mb->get_button_index() == BUTTON_RIGHT) || (tool_create->is_pressed() && mb->get_button_index() == BUTTON_LEFT))) { menu->clear(); animations_menu->clear(); animations_to_add.clear(); List<StringName> classes; classes.sort_custom<StringName::AlphCompare>(); ClassDB::get_inheriters_from_class("AnimationRootNode", &classes); menu->add_submenu_item(TTR("Add Animation"), "animations"); AnimationTree *gp = state_machine->get_tree(); ERR_FAIL_COND(!gp); if (gp && gp->has_node(gp->get_animation_player())) { AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(gp->get_node(gp->get_animation_player())); if (ap) { List<StringName> names; ap->get_animation_list(&names); for (List<StringName>::Element *E = names.front(); E; E = E->next()) { animations_menu->add_icon_item(get_icon("Animation", "EditorIcons"), E->get()); animations_to_add.push_back(E->get()); } } } for (List<StringName>::Element *E = classes.front(); E; E = E->next()) { String name = String(E->get()).replace_first("AnimationNode", ""); if (name == "Animation") continue; // nope int idx = menu->get_item_count(); menu->add_item(vformat("Add %s", name)); menu->set_item_metadata(idx, E->get()); } menu->set_global_position(state_machine_draw->get_global_transform().xform(mb->get_position())); menu->popup(); add_node_pos = mb->get_position() / EDSCALE + state_machine->get_graph_offset(); } // select node or push a field inside if (mb.is_valid() && !mb->get_shift() && mb->is_pressed() && tool_select->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { selected_transition_from = StringName(); selected_transition_to = StringName(); selected_node = StringName(); for (int i = node_rects.size() - 1; i >= 0; i--) { //inverse to draw order if (node_rects[i].play.has_point(mb->get_position())) { //edit name if (play_mode->get_selected() == 1 || !state_machine->is_playing()) { //start state_machine->start(node_rects[i].node_name); } else { //travel if (!state_machine->travel(node_rects[i].node_name)) { state_machine->start(node_rects[i].node_name); //removing this due to usability.. //error_time = 5; //error_text = vformat(TTR("No path found from '%s' to '%s'."), state_machine->get_current_node(), node_rects[i].node_name); } } state_machine_draw->update(); return; } if (node_rects[i].name.has_point(mb->get_position())) { //edit name Ref<StyleBox> line_sb = get_stylebox("normal", "LineEdit"); Rect2 edit_rect = node_rects[i].name; edit_rect.position -= line_sb->get_offset(); edit_rect.size += line_sb->get_minimum_size(); name_edit->set_global_position(state_machine_draw->get_global_transform().xform(edit_rect.position)); name_edit->set_size(edit_rect.size); name_edit->set_text(node_rects[i].node_name); name_edit->show_modal(); name_edit->grab_focus(); name_edit->select_all(); prev_name = node_rects[i].node_name; return; } if (node_rects[i].edit.has_point(mb->get_position())) { //edit name call_deferred("_open_editor", node_rects[i].node_name); return; } if (node_rects[i].node.has_point(mb->get_position())) { //select node since nothing else was selected selected_node = node_rects[i].node_name; Ref<AnimationNode> anode = state_machine->get_node(selected_node); EditorNode::get_singleton()->push_item(anode.ptr(), "", true); state_machine_draw->update(); dragging_selected_attempt = true; dragging_selected = false; drag_from = mb->get_position(); snap_x = StringName(); snap_y = StringName(); _update_mode(); return; } } //test the lines now int closest = -1; float closest_d = 1e20; for (int i = 0; i < transition_lines.size(); i++) { Vector2 s[2] = { transition_lines[i].from, transition_lines[i].to }; Vector2 cpoint = Geometry::get_closest_point_to_segment_2d(mb->get_position(), s); float d = cpoint.distance_to(mb->get_position()); if (d > transition_lines[i].width) { continue; } if (d < closest_d) { closest = i; closest_d = d; } } if (closest >= 0) { selected_transition_from = transition_lines[closest].from_node; selected_transition_to = transition_lines[closest].to_node; Ref<AnimationNodeStateMachineTransition> tr = state_machine->get_transition(closest); EditorNode::get_singleton()->push_item(tr.ptr(), "", true); } state_machine_draw->update(); _update_mode(); } //end moving node if (mb.is_valid() && dragging_selected_attempt && mb->get_button_index() == BUTTON_LEFT && !mb->is_pressed()) { if (dragging_selected) { Ref<AnimationNode> an = state_machine->get_node(selected_node); updating = true; undo_redo->create_action("Move Node"); undo_redo->add_do_method(an.ptr(), "set_position", an->get_position() + drag_ofs / EDSCALE); undo_redo->add_undo_method(an.ptr(), "set_position", an->get_position()); undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); undo_redo->commit_action(); updating = false; } snap_x = StringName(); snap_y = StringName(); dragging_selected_attempt = false; dragging_selected = false; state_machine_draw->update(); } //connect nodes if (mb.is_valid() && ((tool_select->is_pressed() && mb->get_shift()) || tool_connect->is_pressed()) && mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) { for (int i = node_rects.size() - 1; i >= 0; i--) { //inverse to draw order if (node_rects[i].node.has_point(mb->get_position())) { //select node since nothing else was selected connecting = true; connecting_from = node_rects[i].node_name; connecting_to = mb->get_position(); connecting_to_node = StringName(); return; } } } //end connecting nodes if (mb.is_valid() && connecting && mb->get_button_index() == BUTTON_LEFT && !mb->is_pressed()) { if (connecting_to_node != StringName()) { if (state_machine->has_transition(connecting_from, connecting_to_node)) { EditorNode::get_singleton()->show_warning("Transition exists!"); } else { Ref<AnimationNodeStateMachineTransition> tr; tr.instance(); tr->set_switch_mode(AnimationNodeStateMachineTransition::SwitchMode(transition_mode->get_selected())); updating = true; undo_redo->create_action("Add Transition"); undo_redo->add_do_method(state_machine.ptr(), "add_transition", connecting_from, connecting_to_node, tr); undo_redo->add_undo_method(state_machine.ptr(), "remove_transition", connecting_from, connecting_to_node); undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); undo_redo->commit_action(); updating = false; selected_transition_from = connecting_from; selected_transition_to = connecting_to_node; EditorNode::get_singleton()->push_item(tr.ptr(), "", true); _update_mode(); } } connecting_to_node = StringName(); connecting = false; state_machine_draw->update(); } Ref<InputEventMouseMotion> mm = p_event; //pan window if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_MIDDLE) { h_scroll->set_value(h_scroll->get_value() - mm->get_relative().x); v_scroll->set_value(v_scroll->get_value() - mm->get_relative().y); } //move mouse while connecting if (mm.is_valid() && connecting) { connecting_to = mm->get_position(); connecting_to_node = StringName(); state_machine_draw->update(); for (int i = node_rects.size() - 1; i >= 0; i--) { //inverse to draw order if (node_rects[i].node_name != connecting_from && node_rects[i].node.has_point(connecting_to)) { //select node since nothing else was selected connecting_to_node = node_rects[i].node_name; return; } } } //move mouse while moving a node if (mm.is_valid() && dragging_selected_attempt) { dragging_selected = true; drag_ofs = mm->get_position() - drag_from; snap_x = StringName(); snap_y = StringName(); { //snap Vector2 cpos = state_machine->get_node(selected_node)->get_position() + drag_ofs / EDSCALE; List<StringName> nodes; state_machine->get_node_list(&nodes); float best_d_x = 1e20; float best_d_y = 1e20; for (List<StringName>::Element *E = nodes.front(); E; E = E->next()) { if (E->get() == selected_node) continue; Vector2 npos = state_machine->get_node(E->get())->get_position(); float d_x = ABS(npos.x - cpos.x); if (d_x < MIN(5, best_d_x)) { drag_ofs.x -= cpos.x - npos.x; best_d_x = d_x; snap_x = E->get(); } float d_y = ABS(npos.y - cpos.y); if (d_y < MIN(5, best_d_y)) { drag_ofs.y -= cpos.y - npos.y; best_d_y = d_y; snap_y = E->get(); } } } state_machine_draw->update(); } //put ibeam (text cursor) over names to make it clearer that they are editable if (mm.is_valid()) { state_machine_draw->grab_focus(); bool over_text_now = false; String new_over_node = StringName(); int new_over_node_what = -1; if (tool_select->is_pressed()) { for (int i = node_rects.size() - 1; i >= 0; i--) { //inverse to draw order if (node_rects[i].name.has_point(mm->get_position())) { over_text_now = true; break; } if (node_rects[i].node.has_point(mm->get_position())) { new_over_node = node_rects[i].node_name; if (node_rects[i].play.has_point(mm->get_position())) { new_over_node_what = 0; } if (node_rects[i].edit.has_point(mm->get_position())) { new_over_node_what = 1; } } } } if (new_over_node != over_node || new_over_node_what != over_node_what) { over_node = new_over_node; over_node_what = new_over_node_what; state_machine_draw->update(); } if (over_text != over_text_now) { if (over_text_now) { state_machine_draw->set_default_cursor_shape(CURSOR_IBEAM); } else { state_machine_draw->set_default_cursor_shape(CURSOR_ARROW); } over_text = over_text_now; } } }
void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventKey> k = p_event; if (tool_select->is_pressed() && k.is_valid() && k->is_pressed() && k->get_scancode() == KEY_DELETE && !k->is_echo()) { if (selected_point != -1) { _erase_selected(); accept_event(); } } Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid() && mb->is_pressed() && ((tool_select->is_pressed() && mb->get_button_index() == BUTTON_RIGHT) || (mb->get_button_index() == BUTTON_LEFT && tool_create->is_pressed()))) { menu->clear(); animations_menu->clear(); animations_to_add.clear(); List<StringName> classes; ClassDB::get_inheriters_from_class("AnimationRootNode", &classes); classes.sort_custom<StringName::AlphCompare>(); menu->add_submenu_item(TTR("Add Animation"), "animations"); AnimationTree *gp = AnimationTreeEditor::get_singleton()->get_tree(); ERR_FAIL_COND(!gp); if (gp->has_node(gp->get_animation_player())) { AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(gp->get_node(gp->get_animation_player())); if (ap) { List<StringName> names; ap->get_animation_list(&names); for (List<StringName>::Element *E = names.front(); E; E = E->next()) { animations_menu->add_icon_item(get_icon("Animation", "EditorIcons"), E->get()); animations_to_add.push_back(E->get()); } } } for (List<StringName>::Element *E = classes.front(); E; E = E->next()) { String name = String(E->get()).replace_first("AnimationNode", ""); if (name == "Animation") continue; int idx = menu->get_item_count(); menu->add_item(vformat("Add %s", name), idx); menu->set_item_metadata(idx, E->get()); } Ref<AnimationNode> clipb = EditorSettings::get_singleton()->get_resource_clipboard(); if (clipb.is_valid()) { menu->add_separator(); menu->add_item(TTR("Paste"), MENU_PASTE); } menu->add_separator(); menu->add_item(TTR("Load.."), MENU_LOAD_FILE); menu->set_global_position(blend_space_draw->get_global_transform().xform(mb->get_position())); menu->popup(); add_point_pos = (mb->get_position() / blend_space_draw->get_size()).x; add_point_pos *= (blend_space->get_max_space() - blend_space->get_min_space()); add_point_pos += blend_space->get_min_space(); if (snap->is_pressed()) { add_point_pos = Math::stepify(add_point_pos, blend_space->get_snap()); } } if (mb.is_valid() && mb->is_pressed() && tool_select->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { blend_space_draw->update(); // why not // try to see if a point can be selected selected_point = -1; _update_tool_erase(); for (int i = 0; i < points.size(); i++) { if (Math::abs(float(points[i] - mb->get_position().x)) < 10 * EDSCALE) { selected_point = i; Ref<AnimationNode> node = blend_space->get_blend_point_node(i); EditorNode::get_singleton()->push_item(node.ptr(), "", true); dragging_selected_attempt = true; drag_from = mb->get_position(); _update_tool_erase(); _update_edited_point_pos(); return; } } } if (mb.is_valid() && !mb->is_pressed() && dragging_selected_attempt && mb->get_button_index() == BUTTON_LEFT) { if (dragging_selected) { // move float point = blend_space->get_blend_point_position(selected_point); point += drag_ofs.x; if (snap->is_pressed()) { point = Math::stepify(point, blend_space->get_snap()); } updating = true; undo_redo->create_action("Move Node Point"); undo_redo->add_do_method(blend_space.ptr(), "set_blend_point_position", selected_point, point); undo_redo->add_undo_method(blend_space.ptr(), "set_blend_point_position", selected_point, blend_space->get_blend_point_position(selected_point)); undo_redo->add_do_method(this, "_update_space"); undo_redo->add_undo_method(this, "_update_space"); undo_redo->add_do_method(this, "_update_edited_point_pos"); undo_redo->add_undo_method(this, "_update_edited_point_pos"); undo_redo->commit_action(); updating = false; _update_edited_point_pos(); } dragging_selected_attempt = false; dragging_selected = false; blend_space_draw->update(); } // *set* the blend if (mb.is_valid() && !mb->is_pressed() && tool_blend->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { float blend_pos = mb->get_position().x / blend_space_draw->get_size().x; blend_pos *= blend_space->get_max_space() - blend_space->get_min_space(); blend_pos += blend_space->get_min_space(); AnimationTreeEditor::get_singleton()->get_tree()->set(get_blend_position_path(), blend_pos); blend_space_draw->update(); } Ref<InputEventMouseMotion> mm = p_event; if (mm.is_valid() && !blend_space_draw->has_focus()) { blend_space_draw->grab_focus(); blend_space_draw->update(); } if (mm.is_valid() && dragging_selected_attempt) { dragging_selected = true; drag_ofs = ((mm->get_position() - drag_from) / blend_space_draw->get_size()) * ((blend_space->get_max_space() - blend_space->get_min_space()) * Vector2(1, 0)); blend_space_draw->update(); _update_edited_point_pos(); } if (mm.is_valid() && tool_blend->is_pressed() && mm->get_button_mask() & BUTTON_MASK_LEFT) { float blend_pos = mm->get_position().x / blend_space_draw->get_size().x; blend_pos *= blend_space->get_max_space() - blend_space->get_min_space(); blend_pos += blend_space->get_min_space(); AnimationTreeEditor::get_singleton()->get_tree()->set(get_blend_position_path(), blend_pos); blend_space_draw->update(); } }