diff options
Diffstat (limited to 'editor/plugins')
45 files changed, 1259 insertions, 432 deletions
diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp index 22e0a3dabb..ad6d8e6379 100644 --- a/editor/plugins/abstract_polygon_2d_editor.cpp +++ b/editor/plugins/abstract_polygon_2d_editor.cpp @@ -703,10 +703,8 @@ AbstractPolygon2DEditor::PosVertex AbstractPolygon2DEditor::closest_edge_point(c } AbstractPolygon2DEditor::AbstractPolygon2DEditor(bool p_wip_destructive) { - canvas_item_editor = nullptr; undo_redo = EditorNode::get_undo_redo(); - wip_active = false; edited_point = PosVertex(); wip_destructive = p_wip_destructive; @@ -736,8 +734,6 @@ AbstractPolygon2DEditor::AbstractPolygon2DEditor(bool p_wip_destructive) { create_resource = memnew(ConfirmationDialog); add_child(create_resource); create_resource->get_ok_button()->set_text(TTR("Create")); - - mode = MODE_EDIT; } void AbstractPolygon2DEditorPlugin::edit(Object *p_object) { diff --git a/editor/plugins/abstract_polygon_2d_editor.h b/editor/plugins/abstract_polygon_2d_editor.h index b0483cbb62..696fd7b637 100644 --- a/editor/plugins/abstract_polygon_2d_editor.h +++ b/editor/plugins/abstract_polygon_2d_editor.h @@ -80,10 +80,10 @@ class AbstractPolygon2DEditor : public HBoxContainer { Vector<Vector2> pre_move_edit; Vector<Vector2> wip; - bool wip_active; - bool wip_destructive; + bool wip_active = false; + bool wip_destructive = false; - bool _polygon_editing_enabled; + bool _polygon_editing_enabled = false; CanvasItemEditor *canvas_item_editor = nullptr; Panel *panel = nullptr; @@ -97,7 +97,7 @@ protected: MODE_CONT, }; - int mode; + int mode = MODE_EDIT; UndoRedo *undo_redo = nullptr; diff --git a/editor/plugins/animation_blend_space_1d_editor.cpp b/editor/plugins/animation_blend_space_1d_editor.cpp index 94882b3464..ae4482155c 100644 --- a/editor/plugins/animation_blend_space_1d_editor.cpp +++ b/editor/plugins/animation_blend_space_1d_editor.cpp @@ -594,7 +594,6 @@ AnimationNodeBlendSpace1DEditor *AnimationNodeBlendSpace1DEditor::singleton = nu AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() { singleton = this; - updating = false; HBoxContainer *top_hb = memnew(HBoxContainer); add_child(top_hb); @@ -745,9 +744,5 @@ AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() { open_file->connect("file_selected", callable_mp(this, &AnimationNodeBlendSpace1DEditor::_file_opened)); undo_redo = EditorNode::get_undo_redo(); - selected_point = -1; - dragging_selected = false; - dragging_selected_attempt = false; - set_custom_minimum_size(Size2(0, 150 * EDSCALE)); } diff --git a/editor/plugins/animation_blend_space_1d_editor.h b/editor/plugins/animation_blend_space_1d_editor.h index 816c2555ca..2f7dee65fc 100644 --- a/editor/plugins/animation_blend_space_1d_editor.h +++ b/editor/plugins/animation_blend_space_1d_editor.h @@ -65,14 +65,14 @@ class AnimationNodeBlendSpace1DEditor : public AnimationTreeNodeEditorPlugin { SpinBox *edit_value = nullptr; Button *open_editor = nullptr; - int selected_point; + int selected_point = -1; Control *blend_space_draw = nullptr; PanelContainer *error_panel = nullptr; Label *error_label = nullptr; - bool updating; + bool updating = false; UndoRedo *undo_redo = nullptr; @@ -90,11 +90,11 @@ class AnimationNodeBlendSpace1DEditor : public AnimationTreeNodeEditorPlugin { PopupMenu *menu = nullptr; PopupMenu *animations_menu = nullptr; Vector<String> animations_to_add; - float add_point_pos; + float add_point_pos = 0.0f; Vector<real_t> points; - bool dragging_selected_attempt; - bool dragging_selected; + bool dragging_selected_attempt = false; + bool dragging_selected = false; Vector2 drag_from; Vector2 drag_ofs; diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp index 8397772bf8..d3f25d7a85 100644 --- a/editor/plugins/animation_state_machine_editor.cpp +++ b/editor/plugins/animation_state_machine_editor.cpp @@ -42,6 +42,8 @@ #include "scene/animation/animation_player.h" #include "scene/gui/menu_button.h" #include "scene/gui/panel.h" +#include "scene/gui/tree.h" +#include "scene/main/viewport.h" #include "scene/main/window.h" bool AnimationNodeStateMachineEditor::can_edit(const Ref<AnimationNode> &p_node) { @@ -55,7 +57,10 @@ void AnimationNodeStateMachineEditor::edit(const Ref<AnimationNode> &p_node) { if (state_machine.is_valid()) { selected_transition_from = StringName(); selected_transition_to = StringName(); + selected_transition_index = -1; + selected_multi_transition = TransitionLine(); selected_node = StringName(); + selected_nodes.clear(); _update_mode(); _update_graph(); } @@ -69,71 +74,39 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv Ref<InputEventKey> k = p_event; if (tool_select->is_pressed() && k.is_valid() && k->is_pressed() && k->get_keycode() == Key::KEY_DELETE && !k->is_echo()) { - if (selected_node != StringName() || selected_transition_to != StringName() || selected_transition_from != StringName()) { + if (selected_node != StringName() || !selected_nodes.is_empty() || 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() == MouseButton::RIGHT) || (tool_create->is_pressed() && mb->get_button_index() == MouseButton::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 = AnimationTreeEditor::get_singleton()->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 (const StringName &E : names) { - animations_menu->add_icon_item(get_theme_icon(SNAME("Animation"), SNAME("EditorIcons")), E); - animations_to_add.push_back(E); - } - } - } + // Group selected nodes on a state machine + if (tool_select->is_pressed() && k.is_valid() && k->is_pressed() && k->is_ctrl_pressed() && !k->is_shift_pressed() && k->get_keycode() == Key::G && !k->is_echo()) { + _group_selected_nodes(); + } - for (const StringName &E : classes) { - String name = String(E).replace_first("AnimationNode", ""); - if (name == "Animation") { - continue; // nope - } - int idx = menu->get_item_count(); - menu->add_item(vformat(TTR("Add %s"), name), idx); - menu->set_item_metadata(idx, E); - } - Ref<AnimationNode> clipb = EditorSettings::get_singleton()->get_resource_clipboard(); + // Ungroup state machine + if (tool_select->is_pressed() && k.is_valid() && k->is_pressed() && k->is_ctrl_pressed() && k->is_shift_pressed() && k->get_keycode() == Key::G && !k->is_echo()) { + _ungroup_selected_nodes(); + } - 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); + Ref<InputEventMouseButton> mb = p_event; - menu->set_position(state_machine_draw->get_screen_position() + mb->get_position()); - menu->reset_size(); - menu->popup(); - add_node_pos = mb->get_position() / EDSCALE + state_machine->get_graph_offset(); + // Add new node + if (mb.is_valid() && mb->is_pressed() && !box_selecting && !connecting && ((tool_select->is_pressed() && mb->get_button_index() == MouseButton::RIGHT) || (tool_create->is_pressed() && mb->get_button_index() == MouseButton::LEFT))) { + connecting_from = StringName(); + _open_menu(mb->get_position()); } - // select node or push a field inside - if (mb.is_valid() && !mb->is_shift_pressed() && mb->is_pressed() && tool_select->is_pressed() && mb->get_button_index() == MouseButton::LEFT) { + // Select node or push a field inside + if (mb.is_valid() && !mb->is_shift_pressed() && !mb->is_ctrl_pressed() && mb->is_pressed() && tool_select->is_pressed() && mb->get_button_index() == MouseButton::LEFT) { selected_transition_from = StringName(); selected_transition_to = StringName(); + selected_transition_index = -1; + selected_multi_transition = TransitionLine(); 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 || !playback->is_playing()) { //start @@ -146,8 +119,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv return; } - if (node_rects[i].name.has_point(mb->get_position())) { //edit name - + if (node_rects[i].name.has_point(mb->get_position()) && state_machine->can_edit_node(node_rects[i].node_name)) { // edit name Ref<StyleBox> line_sb = get_theme_stylebox(SNAME("normal"), SNAME("LineEdit")); Rect2 edit_rect = node_rects[i].name; @@ -173,6 +145,12 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv if (node_rects[i].node.has_point(mb->get_position())) { //select node since nothing else was selected selected_node = node_rects[i].node_name; + if (!selected_nodes.has(selected_node)) { + selected_nodes.clear(); + } + + selected_nodes.insert(selected_node); + Ref<AnimationNode> anode = state_machine->get_node(selected_node); EditorNode::get_singleton()->push_item(anode.ptr(), "", true); state_machine_draw->update(); @@ -209,23 +187,53 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv if (closest >= 0) { selected_transition_from = transition_lines[closest].from_node; selected_transition_to = transition_lines[closest].to_node; + selected_transition_index = closest; Ref<AnimationNodeStateMachineTransition> tr = state_machine->get_transition(closest); EditorNode::get_singleton()->push_item(tr.ptr(), "", true); + + if (!transition_lines[closest].multi_transitions.is_empty()) { + selected_transition_index = -1; + selected_multi_transition = transition_lines[closest]; + + Ref<EditorAnimationMultiTransitionEdit> multi; + multi.instantiate(); + multi->add_transition(selected_transition_from, selected_transition_to, tr); + + for (int i = 0; i < transition_lines[closest].multi_transitions.size(); i++) { + int index = transition_lines[closest].multi_transitions[i].transition_index; + + Ref<AnimationNodeStateMachineTransition> transition = state_machine->get_transition(index); + StringName from = transition_lines[closest].multi_transitions[i].from_node; + StringName to = transition_lines[closest].multi_transitions[i].to_node; + + multi->add_transition(from, to, transition); + } + EditorNode::get_singleton()->push_item(multi.ptr(), "", true); + } } state_machine_draw->update(); _update_mode(); } - //end moving node + // End moving node if (mb.is_valid() && dragging_selected_attempt && mb->get_button_index() == MouseButton::LEFT && !mb->is_pressed()) { if (dragging_selected) { Ref<AnimationNode> an = state_machine->get_node(selected_node); updating = true; + undo_redo->create_action(TTR("Move Node")); - undo_redo->add_do_method(state_machine.ptr(), "set_node_position", selected_node, state_machine->get_node_position(selected_node) + drag_ofs / EDSCALE); - undo_redo->add_undo_method(state_machine.ptr(), "set_node_position", selected_node, state_machine->get_node_position(selected_node)); + + for (int i = 0; i < node_rects.size(); i++) { + if (!selected_nodes.has(node_rects[i].node_name)) { + continue; + } + + undo_redo->add_do_method(state_machine.ptr(), "set_node_position", node_rects[i].node_name, state_machine->get_node_position(node_rects[i].node_name) + drag_ofs / EDSCALE); + undo_redo->add_undo_method(state_machine.ptr(), "set_node_position", node_rects[i].node_name, state_machine->get_node_position(node_rects[i].node_name)); + } + undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); undo_redo->commit_action(); @@ -239,7 +247,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv state_machine_draw->update(); } - //connect nodes + // Connect nodes if (mb.is_valid() && ((tool_select->is_pressed() && mb->is_shift_pressed()) || tool_connect->is_pressed()) && mb->get_button_index() == MouseButton::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 @@ -252,47 +260,63 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv } } - //end connecting nodes + // End connecting nodes if (mb.is_valid() && connecting && mb->get_button_index() == MouseButton::LEFT && !mb->is_pressed()) { if (connecting_to_node != StringName()) { - if (state_machine->has_transition(connecting_from, connecting_to_node)) { - EditorNode::get_singleton()->show_warning(TTR("Transition exists!")); + Ref<AnimationNode> node = state_machine->get_node(connecting_to_node); + Ref<AnimationNodeStateMachine> anodesm = node; + Ref<AnimationNodeEndState> end_node = node; + if (state_machine->has_transition(connecting_from, connecting_to_node) && state_machine->can_edit_node(connecting_to_node) && !anodesm.is_valid()) { + EditorNode::get_singleton()->show_warning(TTR("Transition exists!")); + connecting = false; } else { - Ref<AnimationNodeStateMachineTransition> tr; - tr.instantiate(); - tr->set_switch_mode(AnimationNodeStateMachineTransition::SwitchMode(transition_mode->get_selected())); - - updating = true; - undo_redo->create_action(TTR("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(); + if (anodesm.is_valid() || end_node.is_valid()) { + _open_connect_menu(mb->get_position()); + } else { + _add_transition(); + } } + } else { + _open_menu(mb->get_position()); } connecting_to_node = StringName(); - connecting = false; state_machine_draw->update(); } + // Start box selecting + if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT && tool_select->is_pressed()) { + box_selecting = true; + box_selecting_from = box_selecting_to = state_machine_draw->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)); + + if (mb->is_ctrl_pressed() || mb->is_shift_pressed()) { + previous_selected = selected_nodes; + } else { + selected_nodes.clear(); + previous_selected.clear(); + } + } + + // End box selecting + if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && !mb->is_pressed() && box_selecting) { + box_selecting = false; + state_machine_draw->update(); + _update_mode(); + } + Ref<InputEventMouseMotion> mm = p_event; - //pan window + // Pan window if (mm.is_valid() && (mm->get_button_mask() & MouseButton::MASK_MIDDLE) != MouseButton::NONE) { 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 + // Move mouse while connecting if (mm.is_valid() && connecting) { connecting_to = mm->get_position(); connecting_to_node = StringName(); @@ -306,7 +330,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv } } - //move mouse while moving a node + // Move mouse while moving a node if (mm.is_valid() && dragging_selected_attempt) { dragging_selected = true; drag_ofs = mm->get_position() - drag_from; @@ -353,6 +377,11 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv 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 (!state_machine->can_edit_node(node_rects[i].node_name)) { + continue; // start/end node can't be edited + } + 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())) { @@ -370,6 +399,43 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv over_node_what = new_over_node_what; state_machine_draw->update(); } + + // set tooltip for transition + if (tool_select->is_pressed()) { + 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 = Geometry2D::get_closest_point_to_segment(mm->get_position(), s); + float d = cpoint.distance_to(mm->get_position()); + if (d > transition_lines[i].width) { + continue; + } + + if (d < closest_d) { + closest = i; + closest_d = d; + } + } + + if (closest >= 0) { + String from = String(transition_lines[closest].from_node); + String to = String(transition_lines[closest].to_node); + String tooltip = from + " -> " + to; + + for (int i = 0; i < transition_lines[closest].multi_transitions.size(); i++) { + from = String(transition_lines[closest].multi_transitions[i].from_node); + to = String(transition_lines[closest].multi_transitions[i].to_node); + tooltip += "\n" + from + " -> " + to; + } + state_machine_draw->set_tooltip(tooltip); + } else { + state_machine_draw->set_tooltip(""); + } + } } Ref<InputEventPanGesture> pan_gesture = p_event; @@ -396,6 +462,458 @@ Control::CursorShape AnimationNodeStateMachineEditor::get_cursor_shape(const Poi return cursor_shape; } +void AnimationNodeStateMachineEditor::_group_selected_nodes() { + if (!selected_nodes.is_empty()) { + if (selected_nodes.size() == 1 && (selected_nodes.front()->get() == state_machine->start_node || selected_nodes.front()->get() == state_machine->end_node)) + return; + + Ref<AnimationNodeStateMachine> group_sm = memnew(AnimationNodeStateMachine); + Vector2 group_position; + + Vector<NodeUR> nodes_ur; + Vector<TransitionUR> transitions_ur; + + int base = 1; + String base_name = group_sm->get_caption(); + String group_name = base_name; + + while (state_machine->has_node(group_name) && !selected_nodes.has(group_name)) { + base++; + group_name = base_name + " " + itos(base); + } + + updating = true; + undo_redo->create_action("Group"); + + // Move selected nodes to the new state machine + for (const StringName &E : selected_nodes) { + if (!state_machine->can_edit_node(E)) { + continue; + } + + Ref<AnimationNode> node = state_machine->get_node(E); + Vector2 node_position = state_machine->get_node_position(E); + group_position += node_position; + + NodeUR new_node; + new_node.name = E; + new_node.node = node; + new_node.position = node_position; + + nodes_ur.push_back(new_node); + } + + // Add the transitions to the new state machine + for (int i = 0; i < state_machine->get_transition_count(); i++) { + String from = state_machine->get_transition_from(i); + String to = state_machine->get_transition_to(i); + + String local_from = from.get_slicec('/', 0); + String local_to = to.get_slicec('/', 0); + + String old_from = from; + String old_to = to; + + bool from_selected = false; + bool to_selected = false; + + if (selected_nodes.has(local_from) && local_from != state_machine->start_node) { + from_selected = true; + } + if (selected_nodes.has(local_to) && local_to != state_machine->end_node) { + to_selected = true; + } + if (!from_selected && !to_selected) { + continue; + } + + Ref<AnimationNodeStateMachineTransition> tr = state_machine->get_transition(i); + + if (!from_selected) { + from = "../" + old_from; + } + if (!to_selected) { + to = "../" + old_to; + } + + TransitionUR new_tr; + new_tr.new_from = from; + new_tr.new_to = to; + new_tr.old_from = old_from; + new_tr.old_to = old_to; + new_tr.transition = tr; + + transitions_ur.push_back(new_tr); + } + + for (int i = 0; i < nodes_ur.size(); i++) { + undo_redo->add_do_method(state_machine.ptr(), "remove_node", nodes_ur[i].name); + undo_redo->add_undo_method(group_sm.ptr(), "remove_node", nodes_ur[i].name); + } + + undo_redo->add_do_method(state_machine.ptr(), "add_node", group_name, group_sm, group_position / nodes_ur.size()); + undo_redo->add_undo_method(state_machine.ptr(), "remove_node", group_name); + + for (int i = 0; i < nodes_ur.size(); i++) { + undo_redo->add_do_method(group_sm.ptr(), "add_node", nodes_ur[i].name, nodes_ur[i].node, nodes_ur[i].position); + undo_redo->add_undo_method(state_machine.ptr(), "add_node", nodes_ur[i].name, nodes_ur[i].node, nodes_ur[i].position); + } + + for (int i = 0; i < transitions_ur.size(); i++) { + undo_redo->add_do_method(group_sm.ptr(), "add_transition", transitions_ur[i].new_from, transitions_ur[i].new_to, transitions_ur[i].transition); + undo_redo->add_undo_method(state_machine.ptr(), "add_transition", transitions_ur[i].old_from, transitions_ur[i].old_to, transitions_ur[i].transition); + } + + undo_redo->add_do_method(this, "_update_graph"); + undo_redo->add_undo_method(this, "_update_graph"); + undo_redo->commit_action(); + updating = false; + + selected_nodes.clear(); + selected_nodes.insert(group_name); + state_machine_draw->update(); + accept_event(); + _update_mode(); + } +} + +void AnimationNodeStateMachineEditor::_ungroup_selected_nodes() { + bool find = false; + Set<StringName> new_selected_nodes; + + for (const StringName &E : selected_nodes) { + Ref<AnimationNodeStateMachine> group_sm = state_machine->get_node(E); + + if (group_sm.is_valid()) { + find = true; + + Vector2 group_position = state_machine->get_node_position(E); + StringName group_name = E; + + List<AnimationNode::ChildNode> nodes; + group_sm->get_child_nodes(&nodes); + + Vector<NodeUR> nodes_ur; + Vector<TransitionUR> transitions_ur; + + updating = true; + undo_redo->create_action("Ungroup"); + + // Move all child nodes to current state machine + for (int i = 0; i < nodes.size(); i++) { + if (!group_sm->can_edit_node(nodes[i].name)) { + continue; + } + + Vector2 node_position = group_sm->get_node_position(nodes[i].name); + + NodeUR new_node; + new_node.name = nodes[i].name; + new_node.position = node_position; + new_node.node = nodes[i].node; + + nodes_ur.push_back(new_node); + } + + for (int i = 0; i < group_sm->get_transition_count(); i++) { + String from = group_sm->get_transition_from(i); + String to = group_sm->get_transition_to(i); + Ref<AnimationNodeStateMachineTransition> tr = group_sm->get_transition(i); + + TransitionUR new_tr; + new_tr.new_from = from.replace_first("../", ""); + new_tr.new_to = to.replace_first("../", ""); + new_tr.old_from = from; + new_tr.old_to = to; + new_tr.transition = tr; + + transitions_ur.push_back(new_tr); + } + + for (int i = 0; i < nodes_ur.size(); i++) { + undo_redo->add_do_method(group_sm.ptr(), "remove_node", nodes_ur[i].name); + undo_redo->add_undo_method(state_machine.ptr(), "remove_node", nodes_ur[i].name); + } + + undo_redo->add_do_method(state_machine.ptr(), "remove_node", group_name); + undo_redo->add_undo_method(state_machine.ptr(), "add_node", group_name, group_sm, group_position); + + for (int i = 0; i < nodes_ur.size(); i++) { + new_selected_nodes.insert(nodes_ur[i].name); + undo_redo->add_do_method(state_machine.ptr(), "add_node", nodes_ur[i].name, nodes_ur[i].node, nodes_ur[i].position); + undo_redo->add_undo_method(group_sm.ptr(), "add_node", nodes_ur[i].name, nodes_ur[i].node, nodes_ur[i].position); + } + + for (int i = 0; i < transitions_ur.size(); i++) { + if (transitions_ur[i].old_from != state_machine->start_node && transitions_ur[i].old_to != state_machine->end_node) { + undo_redo->add_do_method(state_machine.ptr(), "add_transition", transitions_ur[i].new_from, transitions_ur[i].new_to, transitions_ur[i].transition); + } + + undo_redo->add_undo_method(group_sm.ptr(), "add_transition", transitions_ur[i].old_from, transitions_ur[i].old_to, transitions_ur[i].transition); + } + + for (int i = 0; i < state_machine->get_transition_count(); i++) { + String from = state_machine->get_transition_from(i); + String to = state_machine->get_transition_to(i); + Ref<AnimationNodeStateMachineTransition> tr = state_machine->get_transition(i); + + if (from == group_name || to == group_name) { + undo_redo->add_undo_method(state_machine.ptr(), "add_transition", from, to, tr); + } + } + + undo_redo->add_do_method(this, "_update_graph"); + undo_redo->add_undo_method(this, "_update_graph"); + undo_redo->commit_action(); + updating = false; + } + } + + if (find) { + selected_nodes = new_selected_nodes; + selected_node = StringName(); + state_machine_draw->update(); + accept_event(); + _update_mode(); + } +} + +void AnimationNodeStateMachineEditor::_open_menu(const Vector2 &p_position) { + 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 = AnimationTreeEditor::get_singleton()->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_theme_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" || name == "StartState" || name == "EndState") { + continue; // nope + } + int idx = menu->get_item_count(); + menu->add_item(vformat(TTR("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_position(state_machine_draw->get_screen_transform().xform(p_position)); + menu->popup(); + add_node_pos = p_position / EDSCALE + state_machine->get_graph_offset(); +} + +void AnimationNodeStateMachineEditor::_open_connect_menu(const Vector2 &p_position) { + ERR_FAIL_COND(connecting_to_node == StringName()); + + Ref<AnimationNode> node = state_machine->get_node(connecting_to_node); + Ref<AnimationNodeStateMachine> anodesm = node; + Ref<AnimationNodeEndState> end_node = node; + ERR_FAIL_COND(!anodesm.is_valid() && !end_node.is_valid()); + + connect_menu->clear(); + state_machine_menu->clear(); + end_menu->clear(); + nodes_to_connect.clear(); + + for (int i = connect_menu->get_child_count() - 1; i >= 0; i--) { + Node *child = connect_menu->get_child(i); + + if (child->is_class("PopupMenu")) { + connect_menu->remove_child(child); + } + } + + connect_menu->reset_size(); + state_machine_menu->reset_size(); + end_menu->reset_size(); + + if (anodesm.is_valid()) { + _create_submenu(connect_menu, anodesm, connecting_to_node, connecting_to_node); + } else { + Ref<AnimationNodeStateMachine> prev = state_machine; + _create_submenu(connect_menu, prev, connecting_to_node, connecting_to_node, true); + } + + connect_menu->add_submenu_item(TTR("To") + " Animation", connecting_to_node); + + if (state_machine_menu->get_item_count() > 0 || !end_node.is_valid()) { + connect_menu->add_submenu_item(TTR("To") + " StateMachine", "state_machines"); + connect_menu->add_child(state_machine_menu); + } + + if (end_node.is_valid()) { + connect_menu->add_submenu_item(TTR("To") + " End", "end_nodes"); + connect_menu->add_child(end_menu); + } else { + state_machine_menu->add_item(connecting_to_node, nodes_to_connect.size()); + } + + nodes_to_connect.push_back(connecting_to_node); + + if (nodes_to_connect.size() == 1) { + _add_transition(); + return; + } + + connect_menu->set_position(state_machine_draw->get_screen_transform().xform(p_position)); + connect_menu->popup(); +} + +bool AnimationNodeStateMachineEditor::_create_submenu(PopupMenu *p_menu, Ref<AnimationNodeStateMachine> p_nodesm, const StringName &p_name, const StringName &p_path, bool from_root, Vector<Ref<AnimationNodeStateMachine>> p_parents) { + String prev_path; + Vector<Ref<AnimationNodeStateMachine>> parents = p_parents; + + if (from_root) { + Ref<AnimationNodeStateMachine> prev = p_nodesm->get_prev_state_machine(); + + while (prev.is_valid()) { + parents.push_back(prev); + p_nodesm = prev; + prev_path += "../"; + prev = prev->get_prev_state_machine(); + } + prev_path.remove_at(prev_path.size() - 1); + } + + List<StringName> nodes; + p_nodesm->get_node_list(&nodes); + + PopupMenu *nodes_menu = memnew(PopupMenu); + nodes_menu->set_name(p_name); + nodes_menu->connect("id_pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_connect_to)); + p_menu->add_child(nodes_menu); + + bool node_added = false; + for (const StringName &E : nodes) { + if (p_nodesm->can_edit_node(E)) { + Ref<AnimationNodeStateMachine> ansm = p_nodesm->get_node(E); + + String path; + if (from_root) { + path = prev_path + "/" + E; + } else { + path = String(p_path) + "/" + E; + } + + if (ansm == state_machine) { + end_menu->add_item(E, nodes_to_connect.size()); + nodes_to_connect.push_back(state_machine->end_node); + continue; + } + + if (ansm.is_valid()) { + bool found = false; + + for (int i = 0; i < parents.size(); i++) { + if (parents[i] == ansm) { + path = path.replace_first("/../" + E, ""); + found = true; + break; + } + } + + if (!found) { + state_machine_menu->add_item(E, nodes_to_connect.size()); + nodes_to_connect.push_back(path); + } else { + end_menu->add_item(E, nodes_to_connect.size()); + nodes_to_connect.push_back(path + "/" + state_machine->end_node); + } + + if (_create_submenu(nodes_menu, ansm, E, path, false, parents)) { + nodes_menu->add_submenu_item(E, E); + node_added = true; + } + } else { + nodes_menu->add_item(E, nodes_to_connect.size()); + nodes_to_connect.push_back(path); + node_added = true; + } + } + } + + return node_added; +} + +void AnimationNodeStateMachineEditor::_stop_connecting() { + connecting = false; + state_machine_draw->update(); +} + +void AnimationNodeStateMachineEditor::_delete_selected() { + TreeItem *item = delete_tree->get_next_selected(nullptr); + while (item) { + if (!updating) { + updating = true; + selected_multi_transition = TransitionLine(); + undo_redo->create_action("Transition(s) Removed"); + } + + Vector<String> path = item->get_text(0).split(" -> "); + + selected_transition_from = path[0]; + selected_transition_to = path[1]; + _erase_selected(true); + + item = delete_tree->get_next_selected(item); + } + + if (updating) { + undo_redo->commit_action(); + updating = false; + } +} + +void AnimationNodeStateMachineEditor::_delete_all() { + Vector<TransitionLine> multi_transitions = selected_multi_transition.multi_transitions; + selected_multi_transition = TransitionLine(); + + updating = true; + undo_redo->create_action("Transition(s) Removed"); + _erase_selected(true); + for (int i = 0; i < multi_transitions.size(); i++) { + selected_transition_from = multi_transitions[i].from_node; + selected_transition_to = multi_transitions[i].to_node; + _erase_selected(true); + } + undo_redo->commit_action(); + updating = false; + + delete_window->hide(); +} + +void AnimationNodeStateMachineEditor::_delete_tree_draw() { + TreeItem *item = delete_tree->get_next_selected(nullptr); + while (item) { + delete_window->get_cancel_button()->set_disabled(false); + return; + } + delete_window->get_cancel_button()->set_disabled(true); +} + void AnimationNodeStateMachineEditor::_file_opened(const String &p_file) { file_loaded = ResourceLoader::load(p_file); if (file_loaded.is_valid()) { @@ -456,6 +974,8 @@ void AnimationNodeStateMachineEditor::_add_menu_type(int p_index) { undo_redo->add_undo_method(state_machine.ptr(), "remove_node", name); undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); + connecting_to_node = name; + _add_transition(true); undo_redo->commit_action(); updating = false; @@ -482,13 +1002,58 @@ void AnimationNodeStateMachineEditor::_add_animation_type(int p_index) { undo_redo->add_undo_method(state_machine.ptr(), "remove_node", name); undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); + connecting_to_node = name; + _add_transition(true); undo_redo->commit_action(); updating = false; state_machine_draw->update(); } -void AnimationNodeStateMachineEditor::_connection_draw(const Vector2 &p_from, const Vector2 &p_to, AnimationNodeStateMachineTransition::SwitchMode p_mode, bool p_enabled, bool p_selected, bool p_travel, bool p_auto_advance) { +void AnimationNodeStateMachineEditor::_connect_to(int p_index) { + connecting_to_node = nodes_to_connect[p_index]; + _add_transition(); +} + +void AnimationNodeStateMachineEditor::_add_transition(const bool p_nested_action) { + if (connecting_from != StringName() && connecting_to_node != StringName()) { + if (state_machine->has_transition(connecting_from, connecting_to_node)) { + EditorNode::get_singleton()->show_warning("Transition exists!"); + connecting = false; + return; + } + + Ref<AnimationNodeStateMachineTransition> tr; + tr.instantiate(); + tr->set_switch_mode(AnimationNodeStateMachineTransition::SwitchMode(transition_mode->get_selected())); + + if (!p_nested_action) { + updating = true; + } + + undo_redo->create_action(TTR("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(); + + if (!p_nested_action) { + updating = false; + } + + selected_transition_from = connecting_from; + selected_transition_to = connecting_to_node; + selected_transition_index = transition_lines.size(); + + EditorNode::get_singleton()->push_item(tr.ptr(), "", true); + _update_mode(); + } + + connecting = false; +} + +void AnimationNodeStateMachineEditor::_connection_draw(const Vector2 &p_from, const Vector2 &p_to, AnimationNodeStateMachineTransition::SwitchMode p_mode, bool p_enabled, bool p_selected, bool p_travel, bool p_auto_advance, bool p_multi_transitions) { Color linecolor = get_theme_color(SNAME("font_color"), SNAME("Label")); Color icon_color(1, 1, 1); Color accent = get_theme_color(SNAME("accent_color"), SNAME("Editor")); @@ -516,17 +1081,24 @@ void AnimationNodeStateMachineEditor::_connection_draw(const Vector2 &p_from, co linecolor = accent; linecolor.set_hsv(1.0, linecolor.get_s(), linecolor.get_v()); } + state_machine_draw->draw_line(p_from, p_to, linecolor, 2); Ref<Texture2D> icon = icons[p_mode + (p_auto_advance ? 3 : 0)]; Transform2D xf; - xf.elements[0] = (p_to - p_from).normalized(); - xf.elements[1] = xf.elements[0].orthogonal(); - xf.elements[2] = (p_from + p_to) * 0.5 - xf.elements[1] * icon->get_height() * 0.5 - xf.elements[0] * icon->get_height() * 0.5; + xf.columns[0] = (p_to - p_from).normalized(); + xf.columns[1] = xf.columns[0].orthogonal(); + xf.columns[2] = (p_from + p_to) * 0.5 - xf.columns[1] * icon->get_height() * 0.5 - xf.columns[0] * icon->get_height() * 0.5; state_machine_draw->draw_set_transform_matrix(xf); - state_machine_draw->draw_texture(icon, Vector2(), icon_color); + if (p_multi_transitions) { + state_machine_draw->draw_texture(icons[0], Vector2(-icon->get_width(), 0), icon_color); + state_machine_draw->draw_texture(icons[0], Vector2(), icon_color); + state_machine_draw->draw_texture(icons[0], Vector2(icon->get_width(), 0), icon_color); + } else { + state_machine_draw->draw_texture(icon, Vector2(), icon_color); + } state_machine_draw->draw_set_transform_matrix(Transform2D()); } @@ -557,20 +1129,27 @@ void AnimationNodeStateMachineEditor::_clip_dst_line_to_rect(const Vector2 &p_fr void AnimationNodeStateMachineEditor::_state_machine_draw() { Ref<AnimationNodeStateMachinePlayback> playback = AnimationTreeEditor::get_singleton()->get_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + "playback"); - Ref<StyleBox> style = get_theme_stylebox(SNAME("state_machine_frame"), SNAME("GraphNode")); - Ref<StyleBox> style_selected = get_theme_stylebox(SNAME("state_machine_selected_frame"), SNAME("GraphNode")); + Ref<StyleBoxFlat> style = get_theme_stylebox(SNAME("state_machine_frame"), SNAME("GraphNode")); + Ref<StyleBoxFlat> style_selected = get_theme_stylebox(SNAME("state_machine_selected_frame"), SNAME("GraphNode")); Ref<Font> font = get_theme_font(SNAME("title_font"), SNAME("GraphNode")); int font_size = get_theme_font_size(SNAME("title_font_size"), SNAME("GraphNode")); Color font_color = get_theme_color(SNAME("title_color"), SNAME("GraphNode")); Ref<Texture2D> play = get_theme_icon(SNAME("Play"), SNAME("EditorIcons")); - Ref<Texture2D> auto_play = get_theme_icon(SNAME("AutoPlay"), SNAME("EditorIcons")); Ref<Texture2D> edit = get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")); Color accent = get_theme_color(SNAME("accent_color"), SNAME("Editor")); Color linecolor = get_theme_color(SNAME("font_color"), SNAME("Label")); linecolor.a *= 0.3; Ref<StyleBox> playing_overlay = get_theme_stylebox(SNAME("position"), SNAME("GraphNode")); + Ref<StyleBoxFlat> start_overlay = style->duplicate(); + start_overlay->set_border_width_all(1 * EDSCALE); + start_overlay->set_border_color(Color::html("#80f6cf")); + + Ref<StyleBoxFlat> end_overlay = style->duplicate(); + end_overlay->set_border_width_all(1 * EDSCALE); + end_overlay->set_border_color(Color::html("#f26661")); + bool playing = false; StringName current; StringName blend_from; @@ -612,22 +1191,25 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { Ref<AnimationNode> anode = state_machine->get_node(E); String name = E; bool needs_editor = EditorNode::get_singleton()->item_has_editor(anode.ptr()); - Ref<StyleBox> sb = E == selected_node ? style_selected : style; + Ref<StyleBox> sb = selected_nodes.has(E) ? style_selected : style; Size2 s = sb->get_minimum_size(); int strsize = font->get_string_size(name, font_size).width; s.width += strsize; s.height += MAX(font->get_height(font_size), play->get_height()); s.width += sep + play->get_width(); + if (needs_editor) { s.width += sep + edit->get_width(); } Vector2 offset; offset += state_machine->get_node_position(E) * EDSCALE; - if (selected_node == E && dragging_selected) { + + if (selected_nodes.has(E) && dragging_selected) { offset += drag_ofs; } + offset -= s / 2; offset = offset.floor(); @@ -666,7 +1248,7 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { } } - _connection_draw(from, to, AnimationNodeStateMachineTransition::SwitchMode(transition_mode->get_selected()), true, false, false, false); + _connection_draw(from, to, AnimationNodeStateMachineTransition::SwitchMode(transition_mode->get_selected()), true, false, false, false, false); } Ref<Texture2D> tr_reference_icon = get_theme_icon(SNAME("TransitionImmediateBig"), SNAME("EditorIcons")); @@ -675,13 +1257,18 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { //draw transition lines for (int i = 0; i < state_machine->get_transition_count(); i++) { TransitionLine tl; + tl.transition_index = i; tl.from_node = state_machine->get_transition_from(i); - Vector2 ofs_from = (dragging_selected && tl.from_node == selected_node) ? drag_ofs : Vector2(); - tl.from = (state_machine->get_node_position(tl.from_node) * EDSCALE) + ofs_from - state_machine->get_graph_offset() * EDSCALE; + StringName local_from = String(tl.from_node).get_slicec('/', 0); + local_from = local_from == ".." ? state_machine->start_node : local_from; + Vector2 ofs_from = (dragging_selected && selected_nodes.has(local_from)) ? drag_ofs : Vector2(); + tl.from = (state_machine->get_node_position(local_from) * EDSCALE) + ofs_from - state_machine->get_graph_offset() * EDSCALE; tl.to_node = state_machine->get_transition_to(i); - Vector2 ofs_to = (dragging_selected && tl.to_node == selected_node) ? drag_ofs : Vector2(); - tl.to = (state_machine->get_node_position(tl.to_node) * EDSCALE) + ofs_to - state_machine->get_graph_offset() * EDSCALE; + StringName local_to = String(tl.to_node).get_slicec('/', 0); + local_to = local_to == ".." ? state_machine->end_node : local_to; + Vector2 ofs_to = (dragging_selected && selected_nodes.has(local_to)) ? drag_ofs : Vector2(); + tl.to = (state_machine->get_node_position(local_to) * EDSCALE) + ofs_to - state_machine->get_graph_offset() * EDSCALE; Ref<AnimationNodeStateMachineTransition> tr = state_machine->get_transition(i); tl.disabled = tr->is_disabled(); @@ -690,62 +1277,79 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { tl.advance_condition_state = false; tl.mode = tr->get_switch_mode(); tl.width = tr_bidi_offset; + tl.travel = false; + tl.hidden = false; - if (state_machine->has_transition(tl.to_node, tl.from_node)) { //offset if same exists + if (state_machine->has_local_transition(local_to, local_from)) { //offset if same exists Vector2 offset = -(tl.from - tl.to).normalized().orthogonal() * tr_bidi_offset; tl.from += offset; tl.to += offset; } for (int j = 0; j < node_rects.size(); j++) { - if (node_rects[j].node_name == tl.from_node) { + if (node_rects[j].node_name == local_from) { _clip_src_line_to_rect(tl.from, tl.to, node_rects[j].node); } - if (node_rects[j].node_name == tl.to_node) { + if (node_rects[j].node_name == local_to) { _clip_dst_line_to_rect(tl.from, tl.to, node_rects[j].node); } } - bool selected = selected_transition_from == tl.from_node && selected_transition_to == tl.to_node; - - bool travel = false; + tl.selected = selected_transition_from == tl.from_node && selected_transition_to == tl.to_node; - if (blend_from == tl.from_node && current == tl.to_node) { - travel = true; + if (blend_from == local_from && current == local_to) { + tl.travel = true; } if (travel_path.size()) { - if (current == tl.from_node && travel_path[0] == tl.to_node) { - travel = true; + if (current == local_from && travel_path[0] == local_to) { + tl.travel = true; } else { for (int j = 0; j < travel_path.size() - 1; j++) { - if (travel_path[j] == tl.from_node && travel_path[j + 1] == tl.to_node) { - travel = true; + if (travel_path[j] == local_from && travel_path[j + 1] == local_to) { + tl.travel = true; break; } } } } - bool auto_advance = tl.auto_advance; StringName fullpath = AnimationTreeEditor::get_singleton()->get_base_path() + String(tl.advance_condition_name); if (tl.advance_condition_name != StringName() && bool(AnimationTreeEditor::get_singleton()->get_tree()->get(fullpath))) { tl.advance_condition_state = true; - auto_advance = true; + tl.auto_advance = true; } - _connection_draw(tl.from, tl.to, tl.mode, !tl.disabled, selected, travel, auto_advance); + // check if already have this local transition + for (int j = 0; j < transition_lines.size(); j++) { + StringName from = String(transition_lines[j].from_node).get_slicec('/', 0); + StringName to = String(transition_lines[j].to_node).get_slicec('/', 0); + from = from == ".." ? state_machine->start_node : from; + to = to == ".." ? state_machine->end_node : to; + + if (from == local_from && to == local_to) { + tl.hidden = true; + transition_lines.write[j].disabled = transition_lines[j].disabled && tl.disabled; + transition_lines.write[j].multi_transitions.push_back(tl); + } + } transition_lines.push_back(tl); } + for (int i = 0; i < transition_lines.size(); i++) { + TransitionLine tl = transition_lines[i]; + if (!tl.hidden) { + _connection_draw(tl.from, tl.to, tl.mode, !tl.disabled, tl.selected, tl.travel, tl.auto_advance, !tl.multi_transitions.is_empty()); + } + } + //draw actual nodes for (int i = 0; i < node_rects.size(); i++) { String name = node_rects[i].node_name; Ref<AnimationNode> anode = state_machine->get_node(name); bool needs_editor = AnimationTreeEditor::get_singleton()->can_edit(anode); - Ref<StyleBox> sb = name == selected_node ? style_selected : style; + Ref<StyleBox> sb = selected_nodes.has(name) ? style_selected : style; int strsize = font->get_string_size(name, font_size).width; - NodeRect &nr = node_rects.write[i]; Vector2 offset = nr.node.position; @@ -756,18 +1360,16 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { //now scroll it to draw state_machine_draw->draw_style_box(sb, nr.node); - if (playing && (blend_from == name || current == name || travel_path.has(name))) { - state_machine_draw->draw_style_box(playing_overlay, nr.node); + if (state_machine->start_node == name) { + state_machine_draw->draw_style_box(sb == style_selected ? style_selected : start_overlay, nr.node); } - bool onstart = state_machine->get_start_node() == name; - if (onstart) { - state_machine_draw->draw_string(font, offset + Vector2(0, -font->get_height(font_size) - 3 * EDSCALE + font->get_ascent(font_size)), TTR("Start"), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color); + if (state_machine->end_node == name) { + state_machine_draw->draw_style_box(sb == style_selected ? style_selected : end_overlay, nr.node); } - if (state_machine->get_end_node() == name) { - int endofs = nr.node.size.x - font->get_string_size(TTR("End"), font_size).x; - state_machine_draw->draw_string(font, offset + Vector2(endofs, -font->get_height(font_size) - 3 * EDSCALE + font->get_ascent(font_size)), TTR("End"), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color); + if (playing && (blend_from == name || current == name || travel_path.has(name))) { + state_machine_draw->draw_style_box(playing_overlay, nr.node); } offset.x += sb->get_offset().x; @@ -775,13 +1377,14 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { nr.play.position = offset + Vector2(0, (h - play->get_height()) / 2).floor(); nr.play.size = play->get_size(); - Ref<Texture2D> play_tex = onstart ? auto_play : play; + Ref<Texture2D> play_tex = play; if (over_node == name && over_node_what == 0) { state_machine_draw->draw_texture(play_tex, nr.play.position, accent); } else { state_machine_draw->draw_texture(play_tex, nr.play.position); } + offset.x += sep + play->get_width(); nr.name.position = offset + Vector2(0, (h - font->get_height(font_size)) / 2).floor(); @@ -803,6 +1406,11 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { } } + //draw box select + if (box_selecting) { + state_machine_draw->draw_rect(box_selecting_rect, Color(0.7, 0.7, 1.0, 0.3)); + } + scroll_range.position -= state_machine_draw->get_size(); scroll_range.size += state_machine_draw->get_size() * 2.0; @@ -829,6 +1437,10 @@ void AnimationNodeStateMachineEditor::_state_machine_pos_draw() { return; } + if (playback->get_current_node() == state_machine->start_node || playback->get_current_node() == state_machine->end_node) { + return; + } + int idx = -1; for (int i = 0; i < node_rects.size(); i++) { if (node_rects[i].node_name == playback->get_current_node()) { @@ -902,8 +1514,8 @@ void AnimationNodeStateMachineEditor::_notification(int p_what) { transition_mode->add_icon_item(get_theme_icon(SNAME("TransitionEnd"), SNAME("EditorIcons")), TTR("At End")); tool_erase->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); - tool_autoplay->set_icon(get_theme_icon(SNAME("AutoPlay"), SNAME("EditorIcons"))); - tool_end->set_icon(get_theme_icon(SNAME("AutoEnd"), SNAME("EditorIcons"))); + tool_group->set_icon(get_theme_icon(SNAME("Group"), SNAME("EditorIcons"))); + tool_ungroup->set_icon(get_theme_icon(SNAME("Ungroup"), SNAME("EditorIcons"))); play_mode->clear(); play_mode->add_icon_item(get_theme_icon(SNAME("PlayTravel"), SNAME("EditorIcons")), TTR("Travel")); @@ -1109,94 +1721,121 @@ void AnimationNodeStateMachineEditor::_scroll_changed(double) { state_machine_draw->update(); } -void AnimationNodeStateMachineEditor::_erase_selected() { - if (selected_node != StringName() && state_machine->has_node(selected_node)) { - updating = true; +void AnimationNodeStateMachineEditor::_erase_selected(const bool p_nested_action) { + if (!selected_nodes.is_empty()) { + if (!p_nested_action) { + updating = true; + } undo_redo->create_action(TTR("Node Removed")); - undo_redo->add_do_method(state_machine.ptr(), "remove_node", selected_node); - undo_redo->add_undo_method(state_machine.ptr(), "add_node", selected_node, state_machine->get_node(selected_node), state_machine->get_node_position(selected_node)); - for (int i = 0; i < state_machine->get_transition_count(); i++) { - String from = state_machine->get_transition_from(i); - String to = state_machine->get_transition_to(i); - if (from == selected_node || to == selected_node) { - undo_redo->add_undo_method(state_machine.ptr(), "add_transition", from, to, state_machine->get_transition(i)); + + for (int i = 0; i < node_rects.size(); i++) { + if (node_rects[i].node_name == state_machine->start_node || node_rects[i].node_name == state_machine->end_node) { + continue; + } + + if (!selected_nodes.has(node_rects[i].node_name)) { + continue; + } + + undo_redo->add_do_method(state_machine.ptr(), "remove_node", node_rects[i].node_name); + undo_redo->add_undo_method(state_machine.ptr(), "add_node", node_rects[i].node_name, + state_machine->get_node(node_rects[i].node_name), + state_machine->get_node_position(node_rects[i].node_name)); + + for (int j = 0; j < state_machine->get_transition_count(); j++) { + String from = state_machine->get_transition_from(j); + String to = state_machine->get_transition_to(j); + String local_from = from.get_slicec('/', 0); + String local_to = to.get_slicec('/', 0); + + if (local_from == node_rects[i].node_name || local_to == node_rects[i].node_name) { + undo_redo->add_undo_method(state_machine.ptr(), "add_transition", from, to, state_machine->get_transition(j)); + } } } - if (String(state_machine->get_start_node()) == selected_node) { - undo_redo->add_undo_method(state_machine.ptr(), "set_start_node", selected_node); - } + undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); undo_redo->commit_action(); - updating = false; - selected_node = StringName(); + + if (!p_nested_action) { + updating = false; + } + + selected_nodes.clear(); + } + + if (!selected_multi_transition.multi_transitions.is_empty()) { + delete_tree->clear(); + + TreeItem *root = delete_tree->create_item(); + + TreeItem *item = delete_tree->create_item(root); + item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); + item->set_text(0, String(selected_transition_from) + " -> " + selected_transition_to); + item->set_editable(0, true); + + for (int i = 0; i < selected_multi_transition.multi_transitions.size(); i++) { + String from = selected_multi_transition.multi_transitions[i].from_node; + String to = selected_multi_transition.multi_transitions[i].to_node; + + item = delete_tree->create_item(root); + item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); + item->set_text(0, from + " -> " + to); + item->set_editable(0, true); + } + + delete_window->popup_centered(Vector2(400, 200)); + return; } if (selected_transition_to != StringName() && selected_transition_from != StringName() && state_machine->has_transition(selected_transition_from, selected_transition_to)) { Ref<AnimationNodeStateMachineTransition> tr = state_machine->get_transition(state_machine->find_transition(selected_transition_from, selected_transition_to)); - updating = true; + if (!p_nested_action) { + updating = true; + } undo_redo->create_action(TTR("Transition Removed")); undo_redo->add_do_method(state_machine.ptr(), "remove_transition", selected_transition_from, selected_transition_to); undo_redo->add_undo_method(state_machine.ptr(), "add_transition", selected_transition_from, selected_transition_to, tr); undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); undo_redo->commit_action(); - updating = false; + if (!p_nested_action) { + updating = false; + } selected_transition_from = StringName(); selected_transition_to = StringName(); + selected_transition_index = -1; + selected_multi_transition = TransitionLine(); } state_machine_draw->update(); } -void AnimationNodeStateMachineEditor::_autoplay_selected() { - if (selected_node != StringName() && state_machine->has_node(selected_node)) { - StringName new_start_node; - if (state_machine->get_start_node() == selected_node) { //toggle it - new_start_node = StringName(); - } else { - new_start_node = selected_node; - } - - updating = true; - undo_redo->create_action(TTR("Set Start Node (Autoplay)")); - undo_redo->add_do_method(state_machine.ptr(), "set_start_node", new_start_node); - undo_redo->add_undo_method(state_machine.ptr(), "set_start_node", state_machine->get_start_node()); - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - undo_redo->commit_action(); - updating = false; - state_machine_draw->update(); - } -} - -void AnimationNodeStateMachineEditor::_end_selected() { - if (selected_node != StringName() && state_machine->has_node(selected_node)) { - StringName new_end_node; - if (state_machine->get_end_node() == selected_node) { //toggle it - new_end_node = StringName(); - } else { - new_end_node = selected_node; - } - - updating = true; - undo_redo->create_action(TTR("Set Start Node (Autoplay)")); - undo_redo->add_do_method(state_machine.ptr(), "set_end_node", new_end_node); - undo_redo->add_undo_method(state_machine.ptr(), "set_end_node", state_machine->get_end_node()); - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - undo_redo->commit_action(); - updating = false; - state_machine_draw->update(); - } -} - void AnimationNodeStateMachineEditor::_update_mode() { if (tool_select->is_pressed()) { tool_erase_hb->show(); - tool_erase->set_disabled(selected_node == StringName() && selected_transition_from == StringName() && selected_transition_to == StringName()); - tool_autoplay->set_disabled(selected_node == StringName()); - tool_end->set_disabled(selected_node == StringName()); + bool nothing_selected = selected_nodes.is_empty() && selected_transition_from == StringName() && selected_transition_to == StringName(); + bool start_end_selected = selected_nodes.size() == 1 && (selected_nodes.front()->get() == state_machine->start_node || selected_nodes.front()->get() == state_machine->end_node); + tool_erase->set_disabled(nothing_selected || start_end_selected); + + if (selected_nodes.is_empty() || start_end_selected) { + tool_group->set_disabled(true); + tool_group->set_visible(true); + tool_ungroup->set_visible(false); + } else { + Ref<AnimationNodeStateMachine> ansm = state_machine->get_node(selected_nodes.front()->get()); + + if (selected_nodes.size() == 1 && ansm.is_valid()) { + tool_group->set_disabled(true); + tool_group->set_visible(false); + tool_ungroup->set_visible(true); + } else { + tool_group->set_disabled(false); + tool_group->set_visible(true); + tool_ungroup->set_visible(false); + } + } } else { tool_erase_hb->hide(); } @@ -1204,17 +1843,19 @@ void AnimationNodeStateMachineEditor::_update_mode() { void AnimationNodeStateMachineEditor::_bind_methods() { ClassDB::bind_method("_update_graph", &AnimationNodeStateMachineEditor::_update_graph); - ClassDB::bind_method("_removed_from_graph", &AnimationNodeStateMachineEditor::_removed_from_graph); - ClassDB::bind_method("_open_editor", &AnimationNodeStateMachineEditor::_open_editor); + ClassDB::bind_method("_connect_to", &AnimationNodeStateMachineEditor::_connect_to); + ClassDB::bind_method("_stop_connecting", &AnimationNodeStateMachineEditor::_stop_connecting); + ClassDB::bind_method("_delete_selected", &AnimationNodeStateMachineEditor::_delete_selected); + ClassDB::bind_method("_delete_all", &AnimationNodeStateMachineEditor::_delete_all); + ClassDB::bind_method("_delete_tree_draw", &AnimationNodeStateMachineEditor::_delete_tree_draw); } AnimationNodeStateMachineEditor *AnimationNodeStateMachineEditor::singleton = nullptr; AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() { singleton = this; - updating = false; HBoxContainer *top_hb = memnew(HBoxContainer); add_child(top_hb); @@ -1228,7 +1869,7 @@ AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() { tool_select->set_toggle_mode(true); tool_select->set_button_group(bg); tool_select->set_pressed(true); - tool_select->set_tooltip(TTR("Select and move nodes.\nRMB to add new nodes.\nShift+LMB to create connections.")); + tool_select->set_tooltip(TTR("Select and move nodes.\nRMB: Add node at position clicked.\nShift+LMB+Drag: Connects the selected node with another node or creates a new node if you select an area without nodes.")); tool_select->connect("pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_update_mode), varray(), CONNECT_DEFERRED); tool_create = memnew(Button); @@ -1250,28 +1891,27 @@ AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() { tool_erase_hb = memnew(HBoxContainer); top_hb->add_child(tool_erase_hb); tool_erase_hb->add_child(memnew(VSeparator)); + + tool_group = memnew(Button); + tool_group->set_flat(true); + tool_group->set_tooltip(TTR("Group Selected Node(s)") + " (Ctrl+G)"); + tool_group->connect("pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_group_selected_nodes)); + tool_group->set_disabled(true); + tool_erase_hb->add_child(tool_group); + + tool_ungroup = memnew(Button); + tool_ungroup->set_flat(true); + tool_ungroup->set_tooltip(TTR("Ungroup Selected Node") + " (Ctrl+Shift+G)"); + tool_ungroup->connect("pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_ungroup_selected_nodes)); + tool_ungroup->set_visible(false); + tool_erase_hb->add_child(tool_ungroup); + tool_erase = memnew(Button); tool_erase->set_flat(true); tool_erase->set_tooltip(TTR("Remove selected node or transition.")); - tool_erase_hb->add_child(tool_erase); - tool_erase->connect("pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_erase_selected)); + tool_erase->connect("pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_erase_selected), varray(false)); tool_erase->set_disabled(true); - - tool_erase_hb->add_child(memnew(VSeparator)); - - tool_autoplay = memnew(Button); - tool_autoplay->set_flat(true); - tool_autoplay->set_tooltip(TTR("Toggle autoplay this animation on start, restart or seek to zero.")); - tool_erase_hb->add_child(tool_autoplay); - tool_autoplay->connect("pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_autoplay_selected)); - tool_autoplay->set_disabled(true); - - tool_end = memnew(Button); - tool_end->set_flat(true); - tool_end->set_tooltip(TTR("Set the end animation. This is useful for sub-transitions.")); - tool_erase_hb->add_child(tool_end); - tool_end->connect("pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_end_selected)); - tool_end->set_disabled(true); + tool_erase_hb->add_child(tool_erase); top_hb->add_child(memnew(VSeparator)); top_hb->add_child(memnew(Label(TTR("Transition: ")))); @@ -1327,12 +1967,28 @@ AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() { menu = memnew(PopupMenu); add_child(menu); menu->connect("id_pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_add_menu_type)); + menu->connect("popup_hide", callable_mp(this, &AnimationNodeStateMachineEditor::_stop_connecting)); animations_menu = memnew(PopupMenu); menu->add_child(animations_menu); animations_menu->set_name("animations"); animations_menu->connect("index_pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_add_animation_type)); + connect_menu = memnew(PopupMenu); + add_child(connect_menu); + connect_menu->connect("id_pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_connect_to)); + connect_menu->connect("popup_hide", callable_mp(this, &AnimationNodeStateMachineEditor::_stop_connecting)); + + state_machine_menu = memnew(PopupMenu); + state_machine_menu->set_name("state_machines"); + state_machine_menu->connect("id_pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_connect_to)); + connect_menu->add_child(state_machine_menu); + + end_menu = memnew(PopupMenu); + end_menu->set_name("end_nodes"); + end_menu->connect("id_pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_connect_to)); + connect_menu->add_child(end_menu); + name_edit_popup = memnew(Popup); add_child(name_edit_popup); name_edit = memnew(LineEdit); @@ -1348,11 +2004,94 @@ AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() { open_file->connect("file_selected", callable_mp(this, &AnimationNodeStateMachineEditor::_file_opened)); undo_redo = EditorNode::get_undo_redo(); + delete_window = memnew(ConfirmationDialog); + delete_window->set_flag(Window::FLAG_RESIZE_DISABLED, true); + add_child(delete_window); + + delete_tree = memnew(Tree); + delete_tree->set_hide_root(true); + delete_tree->connect("draw", callable_mp(this, &AnimationNodeStateMachineEditor::_delete_tree_draw)); + delete_window->add_child(delete_tree); + + Button *ok = delete_window->get_cancel_button(); + ok->set_text(TTR("Delete Selected")); + ok->connect("pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_delete_selected)); + + Button *delete_all = delete_window->add_button(TTR("Delete All"), true); + delete_all->connect("pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_delete_all)); + over_node_what = -1; dragging_selected_attempt = false; connecting = false; + selected_transition_index = -1; last_active = false; error_time = 0; } + +void EditorAnimationMultiTransitionEdit::add_transition(const StringName &p_from, const StringName &p_to, Ref<AnimationNodeStateMachineTransition> p_transition) { + Transition tr; + tr.from = p_from; + tr.to = p_to; + tr.transition = p_transition; + transitions.push_back(tr); +} + +bool EditorAnimationMultiTransitionEdit::_set(const StringName &p_name, const Variant &p_property) { + int index = String(p_name).get_slicec('/', 0).to_int(); + StringName prop = String(p_name).get_slicec('/', 1); + + bool found; + transitions.write[index].transition->set(prop, p_property, &found); + if (found) { + return true; + } + + return false; +} + +bool EditorAnimationMultiTransitionEdit::_get(const StringName &p_name, Variant &r_property) const { + int index = String(p_name).get_slicec('/', 0).to_int(); + StringName prop = String(p_name).get_slicec('/', 1); + + if (prop == "transition_path") { + r_property = String(transitions[index].from) + " -> " + transitions[index].to; + return true; + } + + bool found; + r_property = transitions[index].transition->get(prop, &found); + if (found) { + return true; + } + + return false; +} + +void EditorAnimationMultiTransitionEdit::_get_property_list(List<PropertyInfo> *p_list) const { + for (int i = 0; i < transitions.size(); i++) { + List<PropertyInfo> plist; + transitions[i].transition->get_property_list(&plist, true); + + PropertyInfo prop_transition_path; + prop_transition_path.type = Variant::STRING; + prop_transition_path.name = itos(i) + "/" + "transition_path"; + p_list->push_back(prop_transition_path); + + for (List<PropertyInfo>::Element *F = plist.front(); F; F = F->next()) { + if (F->get().name == "script" || F->get().name == "resource_name" || F->get().name == "resource_path" || F->get().name == "resource_local_to_scene") { + continue; + } + + if (F->get().usage != PROPERTY_USAGE_DEFAULT) { + continue; + } + + PropertyInfo prop = F->get(); + prop.name = itos(i) + "/" + prop.name; + + p_list->push_back(prop); + } + } +} diff --git a/editor/plugins/animation_state_machine_editor.h b/editor/plugins/animation_state_machine_editor.h index fe3f6f370c..1247d99389 100644 --- a/editor/plugins/animation_state_machine_editor.h +++ b/editor/plugins/animation_state_machine_editor.h @@ -50,13 +50,13 @@ class AnimationNodeStateMachineEditor : public AnimationTreeNodeEditorPlugin { Button *tool_select = nullptr; Button *tool_create = nullptr; Button *tool_connect = nullptr; + Button *tool_group = nullptr; + Button *tool_ungroup = nullptr; Popup *name_edit_popup = nullptr; LineEdit *name_edit = nullptr; HBoxContainer *tool_erase_hb = nullptr; Button *tool_erase = nullptr; - Button *tool_autoplay = nullptr; - Button *tool_end = nullptr; OptionButton *transition_mode = nullptr; OptionButton *play_mode = nullptr; @@ -64,6 +64,7 @@ class AnimationNodeStateMachineEditor : public AnimationTreeNodeEditorPlugin { PanelContainer *panel = nullptr; StringName selected_node; + Set<StringName> selected_nodes; HScrollBar *h_scroll = nullptr; VScrollBar *v_scroll = nullptr; @@ -74,39 +75,53 @@ class AnimationNodeStateMachineEditor : public AnimationTreeNodeEditorPlugin { PanelContainer *error_panel = nullptr; Label *error_label = nullptr; - bool updating; + bool updating = false; UndoRedo *undo_redo = nullptr; static AnimationNodeStateMachineEditor *singleton; void _state_machine_gui_input(const Ref<InputEvent> &p_event); - void _connection_draw(const Vector2 &p_from, const Vector2 &p_to, AnimationNodeStateMachineTransition::SwitchMode p_mode, bool p_enabled, bool p_selected, bool p_travel, bool p_auto_advance); + void _connection_draw(const Vector2 &p_from, const Vector2 &p_to, AnimationNodeStateMachineTransition::SwitchMode p_mode, bool p_enabled, bool p_selected, bool p_travel, bool p_auto_advance, bool p_multi_transitions); void _state_machine_draw(); void _state_machine_pos_draw(); void _update_graph(); PopupMenu *menu = nullptr; + PopupMenu *connect_menu = nullptr; + PopupMenu *state_machine_menu = nullptr; + PopupMenu *end_menu = nullptr; PopupMenu *animations_menu = nullptr; Vector<String> animations_to_add; + Vector<String> nodes_to_connect; Vector2 add_node_pos; - bool dragging_selected_attempt; - bool dragging_selected; + ConfirmationDialog *delete_window; + Tree *delete_tree; + + bool box_selecting = false; + Point2 box_selecting_from; + Point2 box_selecting_to; + Rect2 box_selecting_rect; + Set<StringName> previous_selected; + + bool dragging_selected_attempt = false; + bool dragging_selected = false; Vector2 drag_from; Vector2 drag_ofs; StringName snap_x; StringName snap_y; - bool connecting; + bool connecting = false; StringName connecting_from; Vector2 connecting_to; StringName connecting_to_node; void _add_menu_type(int p_index); void _add_animation_type(int p_index); + void _connect_to(int p_index); void _removed_from_graph(); @@ -131,15 +146,37 @@ class AnimationNodeStateMachineEditor : public AnimationTreeNodeEditorPlugin { bool disabled = false; bool auto_advance = false; float width = 0; + bool selected; + bool travel; + bool hidden; + int transition_index; + Vector<TransitionLine> multi_transitions; }; Vector<TransitionLine> transition_lines; + struct NodeUR { + StringName name; + Ref<AnimationNode> node; + Vector2 position; + }; + + struct TransitionUR { + StringName new_from; + StringName new_to; + StringName old_from; + StringName old_to; + Ref<AnimationNodeStateMachineTransition> transition; + }; + StringName selected_transition_from; StringName selected_transition_to; + int selected_transition_index; + TransitionLine selected_multi_transition; + void _add_transition(const bool p_nested_action = false); StringName over_node; - int over_node_what; + int over_node_what = -1; String prev_name; void _name_edited(const String &p_text); @@ -150,20 +187,29 @@ class AnimationNodeStateMachineEditor : public AnimationTreeNodeEditorPlugin { void _clip_src_line_to_rect(Vector2 &r_from, const Vector2 &p_to, const Rect2 &p_rect); void _clip_dst_line_to_rect(const Vector2 &p_from, Vector2 &r_to, const Rect2 &p_rect); - void _erase_selected(); + void _erase_selected(const bool p_nested_action = false); void _update_mode(); - void _autoplay_selected(); - void _end_selected(); + void _open_menu(const Vector2 &p_position); + void _open_connect_menu(const Vector2 &p_position); + bool _create_submenu(PopupMenu *p_menu, Ref<AnimationNodeStateMachine> p_nodesm, const StringName &p_name, const StringName &p_path, bool from_root = false, Vector<Ref<AnimationNodeStateMachine>> p_parents = Vector<Ref<AnimationNodeStateMachine>>()); + void _stop_connecting(); + + void _group_selected_nodes(); + void _ungroup_selected_nodes(); - bool last_active; + void _delete_selected(); + void _delete_all(); + void _delete_tree_draw(); + + bool last_active = false; StringName last_blend_from_node; StringName last_current_node; Vector<StringName> last_travel_path; - float last_play_pos; - float play_pos; - float current_length; + float last_play_pos = 0.0f; + float play_pos = 0.0f; + float current_length = 0.0f; - float error_time; + float error_time = 0.0f; String error_text; EditorFileDialog *open_file = nullptr; @@ -188,4 +234,26 @@ public: AnimationNodeStateMachineEditor(); }; +class EditorAnimationMultiTransitionEdit : public RefCounted { + GDCLASS(EditorAnimationMultiTransitionEdit, RefCounted); + + struct Transition { + StringName from; + StringName to; + Ref<AnimationNodeStateMachineTransition> transition; + }; + + Vector<Transition> transitions; + +protected: + bool _set(const StringName &p_name, const Variant &p_property); + bool _get(const StringName &p_name, Variant &r_property) const; + void _get_property_list(List<PropertyInfo> *p_list) const; + +public: + void add_transition(const StringName &p_from, const StringName &p_to, Ref<AnimationNodeStateMachineTransition> p_transition); + + EditorAnimationMultiTransitionEdit(){}; +}; + #endif // ANIMATION_STATE_MACHINE_EDITOR_H diff --git a/editor/plugins/asset_library_editor_plugin.h b/editor/plugins/asset_library_editor_plugin.h index 96830c31fd..65c8398558 100644 --- a/editor/plugins/asset_library_editor_plugin.h +++ b/editor/plugins/asset_library_editor_plugin.h @@ -60,9 +60,9 @@ class EditorAssetLibraryItem : public PanelContainer { TextureRect *stars[5]; Label *price = nullptr; - int asset_id; - int category_id; - int author_id; + int asset_id = 0; + int category_id = 0; + int author_id = 0; void _asset_clicked(); void _category_clicked(); @@ -102,7 +102,7 @@ class EditorAssetLibraryItemDescription : public ConfirmationDialog { void set_image(int p_type, int p_index, const Ref<Texture2D> &p_image); - int asset_id; + int asset_id = 0; String download_url; String title; String sha256; @@ -146,7 +146,7 @@ class EditorAssetLibraryItemDownload : public MarginContainer { int prev_status; - int asset_id; + int asset_id = 0; bool external_install; diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index c840ce22ce..d237697597 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -3675,7 +3675,7 @@ void CanvasItemEditor::_draw_viewport() { // Update the transform transform = Transform2D(); transform.scale_basis(Size2(zoom, zoom)); - transform.elements[2] = -view_offset * zoom; + transform.columns[2] = -view_offset * zoom; EditorNode::get_singleton()->get_scene_root()->set_global_canvas_transform(transform); // hide/show buttons depending on the selection @@ -4888,14 +4888,6 @@ CanvasItemEditor::CanvasItemEditor() { view_offset = Point2(-150 - RULER_WIDTH, -95 - RULER_WIDTH); previous_update_view_offset = view_offset; // Moves the view a little bit to the left so that (0,0) is visible. The values a relative to a 16/10 screen - grid_offset = Point2(); - grid_step = Point2(8, 8); // A power-of-two value works better as a default - primary_grid_steps = 8; // A power-of-two value works better as a default - grid_step_multiplier = 0; - - snap_rotation_offset = 0; - snap_rotation_step = Math::deg2rad(15.0); - snap_scale_step = 0.1f; snap_target[0] = SNAP_TARGET_NONE; snap_target[1] = SNAP_TARGET_NONE; @@ -5401,7 +5393,7 @@ void CanvasItemEditorViewport::_create_preview(const Vector<String> &files) cons bool add_preview = false; for (int i = 0; i < files.size(); i++) { String path = files[i]; - RES res = ResourceLoader::load(path); + Ref<Resource> res = ResourceLoader::load(path); ERR_FAIL_COND(res.is_null()); Ref<Texture2D> texture = Ref<Texture2D>(Object::cast_to<Texture2D>(*res)); Ref<PackedScene> scene = Ref<PackedScene>(Object::cast_to<PackedScene>(*res)); @@ -5596,7 +5588,7 @@ void CanvasItemEditorViewport::_perform_drop_data() { for (int i = 0; i < selected_files.size(); i++) { String path = selected_files[i]; - RES res = ResourceLoader::load(path); + Ref<Resource> res = ResourceLoader::load(path); if (res.is_null()) { continue; } @@ -5651,7 +5643,7 @@ bool CanvasItemEditorViewport::can_drop_data(const Point2 &p_point, const Varian for (int i = 0; i < files.size(); i++) { // Check if dragged files with texture or scene extension can be created at least once. if (texture_extensions.find(files[i].get_extension()) || scene_extensions.find(files[i].get_extension())) { - RES res = ResourceLoader::load(files[i]); + Ref<Resource> res = ResourceLoader::load(files[i]); if (res.is_null()) { continue; } diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index 26852ea8ed..7a49041131 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -180,7 +180,7 @@ private: GRID_VISIBILITY_HIDE, }; - bool selection_menu_additive_selection; + bool selection_menu_additive_selection = false; Tool tool = TOOL_SELECT; Control *viewport = nullptr; @@ -204,20 +204,20 @@ private: bool show_edit_locks = true; bool show_transformation_gizmos = true; - real_t zoom; + real_t zoom = 1.0; Point2 view_offset; Point2 previous_update_view_offset; bool selected_from_canvas = false; Point2 grid_offset; - Point2 grid_step; - int primary_grid_steps; - int grid_step_multiplier; + Point2 grid_step = Point2(8, 8); // A power-of-two value works better as a default. + int primary_grid_steps = 8; + int grid_step_multiplier = 0; - real_t snap_rotation_step; - real_t snap_rotation_offset; - real_t snap_scale_step; + real_t snap_rotation_step = 0.0; + real_t snap_rotation_offset = Math::deg2rad(15.0); + real_t snap_scale_step = 0.1f; bool smart_snap_active = false; bool grid_snap_active = false; @@ -241,7 +241,7 @@ private: bool pan_pressed = false; bool ruler_tool_active = false; - Point2 ruler_tool_origin = Point2(); + Point2 ruler_tool_origin; Point2 node_create_position; MenuOption last_option; @@ -346,7 +346,7 @@ private: bool is_hovering_h_guide = false; bool is_hovering_v_guide = false; - bool updating_value_dialog; + bool updating_value_dialog = false; Point2 box_selecting_to; diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index a160ca463b..80fc1c64d0 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -79,7 +79,7 @@ bool EditorTexturePreviewPlugin::generate_small_preview_automatically() const { return true; } -Ref<Texture2D> EditorTexturePreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { +Ref<Texture2D> EditorTexturePreviewPlugin::generate(const Ref<Resource> &p_from, const Size2 &p_size) const { Ref<Image> img; Ref<AtlasTexture> atex = p_from; if (atex.is_valid()) { @@ -145,7 +145,7 @@ bool EditorImagePreviewPlugin::handles(const String &p_type) const { return p_type == "Image"; } -Ref<Texture2D> EditorImagePreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { +Ref<Texture2D> EditorImagePreviewPlugin::generate(const Ref<Resource> &p_from, const Size2 &p_size) const { Ref<Image> img = p_from; if (img.is_null() || img->is_empty()) { @@ -194,7 +194,7 @@ bool EditorBitmapPreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "BitMap"); } -Ref<Texture2D> EditorBitmapPreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { +Ref<Texture2D> EditorBitmapPreviewPlugin::generate(const Ref<Resource> &p_from, const Size2 &p_size) const { Ref<BitMap> bm = p_from; if (bm->get_size() == Size2()) { @@ -261,7 +261,7 @@ bool EditorPackedScenePreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "PackedScene"); } -Ref<Texture2D> EditorPackedScenePreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { +Ref<Texture2D> EditorPackedScenePreviewPlugin::generate(const Ref<Resource> &p_from, const Size2 &p_size) const { return generate_from_path(p_from->get_path(), p_size); } @@ -316,7 +316,7 @@ bool EditorMaterialPreviewPlugin::generate_small_preview_automatically() const { return true; } -Ref<Texture2D> EditorMaterialPreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { +Ref<Texture2D> EditorMaterialPreviewPlugin::generate(const Ref<Resource> &p_from, const Size2 &p_size) const { Ref<Material> material = p_from; ERR_FAIL_COND_V(material.is_null(), Ref<Texture2D>()); @@ -467,7 +467,7 @@ bool EditorScriptPreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "Script"); } -Ref<Texture2D> EditorScriptPreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { +Ref<Texture2D> EditorScriptPreviewPlugin::generate(const Ref<Resource> &p_from, const Size2 &p_size) const { Ref<Script> scr = p_from; if (scr.is_null()) { return Ref<Texture2D>(); @@ -609,7 +609,7 @@ bool EditorAudioStreamPreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "AudioStream"); } -Ref<Texture2D> EditorAudioStreamPreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { +Ref<Texture2D> EditorAudioStreamPreviewPlugin::generate(const Ref<Resource> &p_from, const Size2 &p_size) const { Ref<AudioStream> stream = p_from; ERR_FAIL_COND_V(stream.is_null(), Ref<Texture2D>()); @@ -703,7 +703,7 @@ bool EditorMeshPreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "Mesh"); // Any mesh. } -Ref<Texture2D> EditorMeshPreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { +Ref<Texture2D> EditorMeshPreviewPlugin::generate(const Ref<Resource> &p_from, const Size2 &p_size) const { Ref<Mesh> mesh = p_from; ERR_FAIL_COND_V(mesh.is_null(), Ref<Texture2D>()); @@ -816,7 +816,7 @@ bool EditorFontPreviewPlugin::handles(const String &p_type) const { } Ref<Texture2D> EditorFontPreviewPlugin::generate_from_path(const String &p_path, const Size2 &p_size) const { - RES res = ResourceLoader::load(p_path); + Ref<Resource> res = ResourceLoader::load(p_path); ERR_FAIL_COND_V(res.is_null(), Ref<Texture2D>()); Ref<Font> sampled_font; if (res->is_class("Font")) { @@ -877,7 +877,7 @@ Ref<Texture2D> EditorFontPreviewPlugin::generate_from_path(const String &p_path, return ptex; } -Ref<Texture2D> EditorFontPreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { +Ref<Texture2D> EditorFontPreviewPlugin::generate(const Ref<Resource> &p_from, const Size2 &p_size) const { String path = p_from->get_path(); if (!FileAccess::exists(path)) { return Ref<Texture2D>(); @@ -917,7 +917,7 @@ bool EditorGradientPreviewPlugin::generate_small_preview_automatically() const { return true; } -Ref<Texture2D> EditorGradientPreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { +Ref<Texture2D> EditorGradientPreviewPlugin::generate(const Ref<Resource> &p_from, const Size2 &p_size) const { Ref<Gradient> gradient = p_from; if (gradient.is_valid()) { Ref<GradientTexture1D> ptex; diff --git a/editor/plugins/editor_preview_plugins.h b/editor/plugins/editor_preview_plugins.h index 73eb90dd86..f548683b70 100644 --- a/editor/plugins/editor_preview_plugins.h +++ b/editor/plugins/editor_preview_plugins.h @@ -42,7 +42,7 @@ class EditorTexturePreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const override; virtual bool generate_small_preview_automatically() const override; - virtual Ref<Texture2D> generate(const RES &p_from, const Size2 &p_size) const override; + virtual Ref<Texture2D> generate(const Ref<Resource> &p_from, const Size2 &p_size) const override; EditorTexturePreviewPlugin(); }; @@ -53,7 +53,7 @@ class EditorImagePreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const override; virtual bool generate_small_preview_automatically() const override; - virtual Ref<Texture2D> generate(const RES &p_from, const Size2 &p_size) const override; + virtual Ref<Texture2D> generate(const Ref<Resource> &p_from, const Size2 &p_size) const override; EditorImagePreviewPlugin(); }; @@ -64,7 +64,7 @@ class EditorBitmapPreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const override; virtual bool generate_small_preview_automatically() const override; - virtual Ref<Texture2D> generate(const RES &p_from, const Size2 &p_size) const override; + virtual Ref<Texture2D> generate(const Ref<Resource> &p_from, const Size2 &p_size) const override; EditorBitmapPreviewPlugin(); }; @@ -72,7 +72,7 @@ public: class EditorPackedScenePreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const; - virtual Ref<Texture2D> generate(const RES &p_from, const Size2 &p_size) const; + virtual Ref<Texture2D> generate(const Ref<Resource> &p_from, const Size2 &p_size) const; virtual Ref<Texture2D> generate_from_path(const String &p_path, const Size2 &p_size) const; EditorPackedScenePreviewPlugin(); @@ -99,7 +99,7 @@ class EditorMaterialPreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const override; virtual bool generate_small_preview_automatically() const override; - virtual Ref<Texture2D> generate(const RES &p_from, const Size2 &p_size) const override; + virtual Ref<Texture2D> generate(const Ref<Resource> &p_from, const Size2 &p_size) const override; EditorMaterialPreviewPlugin(); ~EditorMaterialPreviewPlugin(); @@ -108,7 +108,7 @@ public: class EditorScriptPreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const; - virtual Ref<Texture2D> generate(const RES &p_from, const Size2 &p_size) const; + virtual Ref<Texture2D> generate(const Ref<Resource> &p_from, const Size2 &p_size) const; EditorScriptPreviewPlugin(); }; @@ -116,7 +116,7 @@ public: class EditorAudioStreamPreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const; - virtual Ref<Texture2D> generate(const RES &p_from, const Size2 &p_size) const; + virtual Ref<Texture2D> generate(const Ref<Resource> &p_from, const Size2 &p_size) const; EditorAudioStreamPreviewPlugin(); }; @@ -140,7 +140,7 @@ class EditorMeshPreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const override; - virtual Ref<Texture2D> generate(const RES &p_from, const Size2 &p_size) const override; + virtual Ref<Texture2D> generate(const Ref<Resource> &p_from, const Size2 &p_size) const override; EditorMeshPreviewPlugin(); ~EditorMeshPreviewPlugin(); @@ -160,7 +160,7 @@ class EditorFontPreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const override; - virtual Ref<Texture2D> generate(const RES &p_from, const Size2 &p_size) const override; + virtual Ref<Texture2D> generate(const Ref<Resource> &p_from, const Size2 &p_size) const override; virtual Ref<Texture2D> generate_from_path(const String &p_path, const Size2 &p_size) const override; EditorFontPreviewPlugin(); @@ -177,7 +177,7 @@ class EditorTileMapPatternPreviewPlugin : public EditorResourcePreviewGenerator public: virtual bool handles(const String &p_type) const override; - virtual Ref<Texture2D> generate(const RES &p_from, const Size2 &p_size) const override; + virtual Ref<Texture2D> generate(const Ref<Resource> &p_from, const Size2 &p_size) const override; EditorTileMapPatternPreviewPlugin(); ~EditorTileMapPatternPreviewPlugin(); @@ -189,7 +189,7 @@ class EditorGradientPreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const override; virtual bool generate_small_preview_automatically() const override; - virtual Ref<Texture2D> generate(const RES &p_from, const Size2 &p_size) const override; + virtual Ref<Texture2D> generate(const Ref<Resource> &p_from, const Size2 &p_size) const override; EditorGradientPreviewPlugin(); }; diff --git a/editor/plugins/light_occluder_2d_editor_plugin.cpp b/editor/plugins/light_occluder_2d_editor_plugin.cpp index 4fbc8188b9..e7ef65c32b 100644 --- a/editor/plugins/light_occluder_2d_editor_plugin.cpp +++ b/editor/plugins/light_occluder_2d_editor_plugin.cpp @@ -96,7 +96,7 @@ void LightOccluder2DEditor::_create_resource() { undo_redo->create_action(TTR("Create Occluder Polygon")); undo_redo->add_do_method(node, "set_occluder_polygon", Ref<OccluderPolygon2D>(memnew(OccluderPolygon2D))); - undo_redo->add_undo_method(node, "set_occluder_polygon", Variant(REF())); + undo_redo->add_undo_method(node, "set_occluder_polygon", Variant(Ref<RefCounted>())); undo_redo->commit_action(); _menu_option(MODE_CREATE); diff --git a/editor/plugins/mesh_library_editor_plugin.h b/editor/plugins/mesh_library_editor_plugin.h index 85ead35534..f4b4288a5f 100644 --- a/editor/plugins/mesh_library_editor_plugin.h +++ b/editor/plugins/mesh_library_editor_plugin.h @@ -47,8 +47,8 @@ class MeshLibraryEditor : public Control { ConfirmationDialog *cd_remove = nullptr; ConfirmationDialog *cd_update = nullptr; EditorFileDialog *file = nullptr; - bool apply_xforms; - int to_erase; + bool apply_xforms = false; + int to_erase = 0; enum { MENU_OPTION_ADD_ITEM, @@ -58,7 +58,7 @@ class MeshLibraryEditor : public Control { MENU_OPTION_IMPORT_FROM_SCENE_APPLY_XFORMS }; - int option; + int option = 0; void _import_scene_cbk(const String &p_str); void _menu_cbk(int p_option); void _menu_remove_confirm(); diff --git a/editor/plugins/multimesh_editor_plugin.h b/editor/plugins/multimesh_editor_plugin.h index 9f5e85216c..5773989d0d 100644 --- a/editor/plugins/multimesh_editor_plugin.h +++ b/editor/plugins/multimesh_editor_plugin.h @@ -46,7 +46,7 @@ class MultiMeshEditor : public Control { AcceptDialog *err_dialog = nullptr; MenuButton *options = nullptr; MultiMeshInstance3D *_last_pp_node = nullptr; - bool browsing_source; + bool browsing_source = false; Panel *panel = nullptr; MultiMeshInstance3D *node = nullptr; diff --git a/editor/plugins/navigation_polygon_editor_plugin.cpp b/editor/plugins/navigation_polygon_editor_plugin.cpp index 17eaf45bb5..8f3553b8cf 100644 --- a/editor/plugins/navigation_polygon_editor_plugin.cpp +++ b/editor/plugins/navigation_polygon_editor_plugin.cpp @@ -106,7 +106,7 @@ void NavigationPolygonEditor::_create_resource() { undo_redo->create_action(TTR("Create Navigation Polygon")); undo_redo->add_do_method(node, "set_navigation_polygon", Ref<NavigationPolygon>(memnew(NavigationPolygon))); - undo_redo->add_undo_method(node, "set_navigation_polygon", Variant(REF())); + undo_redo->add_undo_method(node, "set_navigation_polygon", Variant(Ref<RefCounted>())); undo_redo->commit_action(); _menu_option(MODE_CREATE); diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp index 179f78325c..47c8c66c57 100644 --- a/editor/plugins/node_3d_editor_gizmos.cpp +++ b/editor/plugins/node_3d_editor_gizmos.cpp @@ -476,7 +476,7 @@ void EditorNode3DGizmo::add_handles(const Vector<Vector3> &p_handles, const Ref< } } -void EditorNode3DGizmo::add_solid_box(Ref<Material> &p_material, Vector3 p_size, Vector3 p_position, const Transform3D &p_xform) { +void EditorNode3DGizmo::add_solid_box(const Ref<Material> &p_material, Vector3 p_size, Vector3 p_position, const Transform3D &p_xform) { ERR_FAIL_COND(!spatial_node); BoxMesh box_mesh; diff --git a/editor/plugins/node_3d_editor_gizmos.h b/editor/plugins/node_3d_editor_gizmos.h index 8adb753a51..f859ceda3b 100644 --- a/editor/plugins/node_3d_editor_gizmos.h +++ b/editor/plugins/node_3d_editor_gizmos.h @@ -99,7 +99,7 @@ public: void add_collision_triangles(const Ref<TriangleMesh> &p_tmesh); void add_unscaled_billboard(const Ref<Material> &p_material, real_t p_scale = 1, const Color &p_modulate = Color(1, 1, 1)); void add_handles(const Vector<Vector3> &p_handles, const Ref<Material> &p_material, const Vector<int> &p_ids = Vector<int>(), bool p_billboard = false, bool p_secondary = false); - void add_solid_box(Ref<Material> &p_material, Vector3 p_size, Vector3 p_position = Vector3(), const Transform3D &p_xform = Transform3D()); + void add_solid_box(const Ref<Material> &p_material, Vector3 p_size, Vector3 p_position = Vector3(), const Transform3D &p_xform = Transform3D()); virtual bool is_handle_highlighted(int p_id, bool p_secondary) const; virtual String get_handle_name(int p_id, bool p_secondary) const; diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 7e01593bda..344efb4f13 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -2990,7 +2990,7 @@ void Node3DEditorViewport::_menu_option(int p_option) { bool current = view_menu->get_popup()->is_item_checked(idx); current = !current; if (current) { - camera->set_environment(RES()); + camera->set_environment(Ref<Resource>()); } else { camera->set_environment(Node3DEditor::get_singleton()->get_viewport_environment()); } @@ -3767,7 +3767,7 @@ Node *Node3DEditorViewport::_sanitize_preview_node(Node *p_node) const { void Node3DEditorViewport::_create_preview(const Vector<String> &files) const { for (int i = 0; i < files.size(); i++) { String path = files[i]; - RES res = ResourceLoader::load(path); + Ref<Resource> res = ResourceLoader::load(path); ERR_CONTINUE(res.is_null()); Ref<PackedScene> scene = Ref<PackedScene>(Object::cast_to<PackedScene>(*res)); Ref<Mesh> mesh = Ref<Mesh>(Object::cast_to<Mesh>(*res)); @@ -3818,7 +3818,7 @@ bool Node3DEditorViewport::_cyclical_dependency_exists(const String &p_target_sc } bool Node3DEditorViewport::_create_instance(Node *parent, String &path, const Point2 &p_point) { - RES res = ResourceLoader::load(path); + Ref<Resource> res = ResourceLoader::load(path); ERR_FAIL_COND_V(res.is_null(), false); Ref<PackedScene> scene = Ref<PackedScene>(Object::cast_to<PackedScene>(*res)); @@ -3908,7 +3908,7 @@ void Node3DEditorViewport::_perform_drop_data() { for (int i = 0; i < selected_files.size(); i++) { String path = selected_files[i]; - RES res = ResourceLoader::load(path); + Ref<Resource> res = ResourceLoader::load(path); if (res.is_null()) { continue; } @@ -3951,7 +3951,7 @@ bool Node3DEditorViewport::can_drop_data_fw(const Point2 &p_point, const Variant for (int i = 0; i < files.size(); i++) { // Check if dragged files with mesh or scene extension can be created at least once. if (mesh_extensions.find(files[i].get_extension()) || scene_extensions.find(files[i].get_extension())) { - RES res = ResourceLoader::load(files[i]); + Ref<Resource> res = ResourceLoader::load(files[i]); if (res.is_null()) { continue; } diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index d5d50c743c..43efdeec72 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -211,7 +211,7 @@ private: Control *surface = nullptr; SubViewport *viewport = nullptr; Camera3D *camera = nullptr; - bool transforming; + bool transforming = false; bool orthogonal; bool auto_orthogonal; bool lock_rotation; @@ -271,7 +271,7 @@ private: ObjectID clicked; Vector<_RayResult> selection_results; - bool clicked_wants_append; + bool clicked_wants_append = false; bool selection_in_progress = false; PopupMenu *selection_menu = nullptr; @@ -551,12 +551,12 @@ private: RID origin; RID origin_instance; - bool origin_enabled; + bool origin_enabled = false; RID grid[3]; RID grid_instance[3]; bool grid_visible[3]; //currently visible bool grid_enable[3]; //should be always visible if true - bool grid_enabled; + bool grid_enabled = false; bool grid_init_draw = false; Camera3D::Projection grid_camera_last_update_perspective = Camera3D::PROJECTION_PERSPECTIVE; Vector3 grid_camera_last_update_position = Vector3(); diff --git a/editor/plugins/packed_scene_translation_parser_plugin.cpp b/editor/plugins/packed_scene_translation_parser_plugin.cpp index 9a8584f4a2..8d083d28b2 100644 --- a/editor/plugins/packed_scene_translation_parser_plugin.cpp +++ b/editor/plugins/packed_scene_translation_parser_plugin.cpp @@ -43,7 +43,7 @@ Error PackedSceneEditorTranslationParserPlugin::parse_file(const String &p_path, // These properties are translated with the tr() function in the C++ code when being set or updated. Error err; - RES loaded_res = ResourceLoader::load(p_path, "PackedScene", ResourceFormatLoader::CACHE_MODE_REUSE, &err); + Ref<Resource> loaded_res = ResourceLoader::load(p_path, "PackedScene", ResourceFormatLoader::CACHE_MODE_REUSE, &err); if (err) { ERR_PRINT("Failed to load " + p_path); return err; diff --git a/editor/plugins/path_2d_editor_plugin.h b/editor/plugins/path_2d_editor_plugin.h index ff74aeedf7..720f5c090f 100644 --- a/editor/plugins/path_2d_editor_plugin.h +++ b/editor/plugins/path_2d_editor_plugin.h @@ -82,11 +82,11 @@ class Path2DEditor : public HBoxContainer { }; Action action; - int action_point; + int action_point = 0; Point2 moving_from; Point2 moving_screen_from; - float orig_in_length; - float orig_out_length; + float orig_in_length = 0.0f; + float orig_out_length = 0.0f; Vector2 edge_point; void _mode_selected(int p_mode); diff --git a/editor/plugins/path_3d_editor_plugin.h b/editor/plugins/path_3d_editor_plugin.h index 72c24732c0..ee31fcf43d 100644 --- a/editor/plugins/path_3d_editor_plugin.h +++ b/editor/plugins/path_3d_editor_plugin.h @@ -84,7 +84,7 @@ class Path3DEditorPlugin : public EditorPlugin { void _mode_changed(int p_idx); void _close_curve(); void _handle_option_pressed(int p_option); - bool handle_clicked; + bool handle_clicked = false; bool mirror_handle_angle; bool mirror_handle_length; diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp index 8566e92b22..a682bb455c 100644 --- a/editor/plugins/polygon_2d_editor_plugin.cpp +++ b/editor/plugins/polygon_2d_editor_plugin.cpp @@ -455,7 +455,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { } Transform2D mtx; - mtx.elements[2] = -uv_draw_ofs; + mtx.columns[2] = -uv_draw_ofs; mtx.scale_basis(Vector2(uv_draw_zoom, uv_draw_zoom)); Ref<InputEventMouseButton> mb = p_input; @@ -970,7 +970,7 @@ void Polygon2DEditor::_uv_draw() { String warning; Transform2D mtx; - mtx.elements[2] = -uv_draw_ofs; + mtx.columns[2] = -uv_draw_ofs; mtx.scale_basis(Vector2(uv_draw_zoom, uv_draw_zoom)); RS::get_singleton()->canvas_item_add_set_transform(uv_edit_draw->get_canvas_item(), mtx); diff --git a/editor/plugins/polygon_2d_editor_plugin.h b/editor/plugins/polygon_2d_editor_plugin.h index 4403d1e9c7..d878d3f9af 100644 --- a/editor/plugins/polygon_2d_editor_plugin.h +++ b/editor/plugins/polygon_2d_editor_plugin.h @@ -96,7 +96,7 @@ class Polygon2DEditor : public AbstractPolygon2DEditor { SpinBox *bone_paint_radius = nullptr; Label *bone_paint_radius_label = nullptr; bool bone_painting; - int bone_painting_bone; + int bone_painting_bone = 0; Vector<float> prev_weights; Vector2 bone_paint_pos; AcceptDialog *grid_settings = nullptr; @@ -110,7 +110,7 @@ class Polygon2DEditor : public AbstractPolygon2DEditor { Vector<Vector2> uv_create_uv_prev; Vector<Vector2> uv_create_poly_prev; Vector<Color> uv_create_colors_prev; - int uv_create_prev_internal_vertices; + int uv_create_prev_internal_vertices = 0; Array uv_create_bones_prev; Array polygons_prev; diff --git a/editor/plugins/polygon_3d_editor_plugin.h b/editor/plugins/polygon_3d_editor_plugin.h index 3ad7a4df58..e1e1261250 100644 --- a/editor/plugins/polygon_3d_editor_plugin.h +++ b/editor/plugins/polygon_3d_editor_plugin.h @@ -66,14 +66,14 @@ class Polygon3DEditor : public HBoxContainer { MenuButton *options = nullptr; - int edited_point; + int edited_point = 0; Vector2 edited_point_pos; PackedVector2Array pre_move_edit; PackedVector2Array wip; bool wip_active; bool snap_ignore; - float prev_depth; + float prev_depth = 0.0f; void _wip_close(); void _polygon_draw(); diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp index eafc53c72b..71d31aa1d7 100644 --- a/editor/plugins/resource_preloader_editor_plugin.cpp +++ b/editor/plugins/resource_preloader_editor_plugin.cpp @@ -50,7 +50,7 @@ void ResourcePreloaderEditor::_files_load_request(const Vector<String> &p_paths) for (int i = 0; i < p_paths.size(); i++) { String path = p_paths[i]; - RES resource; + Ref<Resource> resource; resource = ResourceLoader::load(path); if (resource.is_null()) { @@ -113,7 +113,7 @@ void ResourcePreloaderEditor::_item_edited() { return; } - RES samp = preloader->get_resource(old_name); + Ref<Resource> samp = preloader->get_resource(old_name); undo_redo->create_action(TTR("Rename Resource")); undo_redo->add_do_method(preloader, "remove_resource", old_name); undo_redo->add_do_method(preloader, "add_resource", new_name, samp); @@ -135,7 +135,7 @@ void ResourcePreloaderEditor::_remove_resource(const String &p_to_remove) { } void ResourcePreloaderEditor::_paste_pressed() { - RES r = EditorSettings::get_singleton()->get_resource_clipboard(); + Ref<Resource> r = EditorSettings::get_singleton()->get_resource_clipboard(); if (!r.is_valid()) { dialog->set_text(TTR("Resource clipboard is empty!")); dialog->set_title(TTR("Error!")); @@ -190,7 +190,7 @@ void ResourcePreloaderEditor::_update_library() { ti->set_text(0, E); ti->set_metadata(0, E); - RES r = preloader->get_resource(E); + Ref<Resource> r = preloader->get_resource(E); ERR_CONTINUE(r.is_null()); @@ -222,7 +222,7 @@ void ResourcePreloaderEditor::_cell_button_pressed(Object *p_item, int p_column, EditorInterface::get_singleton()->open_scene_from_path(rpath); } else if (p_id == BUTTON_EDIT_RESOURCE) { - RES r = preloader->get_resource(item->get_text(0)); + Ref<Resource> r = preloader->get_resource(item->get_text(0)); EditorInterface::get_singleton()->edit_resource(r); } else if (p_id == BUTTON_REMOVE) { @@ -249,7 +249,7 @@ Variant ResourcePreloaderEditor::get_drag_data_fw(const Point2 &p_point, Control String name = ti->get_metadata(0); - RES res = preloader->get_resource(name); + Ref<Resource> res = preloader->get_resource(name); if (!res.is_valid()) { return Variant(); } @@ -269,7 +269,7 @@ bool ResourcePreloaderEditor::can_drop_data_fw(const Point2 &p_point, const Vari } if (String(d["type"]) == "resource" && d.has("resource")) { - RES r = d["resource"]; + Ref<Resource> r = d["resource"]; return r.is_valid(); } @@ -294,7 +294,7 @@ void ResourcePreloaderEditor::drop_data_fw(const Point2 &p_point, const Variant } if (String(d["type"]) == "resource" && d.has("resource")) { - RES r = d["resource"]; + Ref<Resource> r = d["resource"]; if (r.is_valid()) { String basename; diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index a4bf28625d..0d33a7bdc6 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -232,7 +232,7 @@ void ScriptEditorBase::_bind_methods() { class EditorScriptCodeCompletionCache : public ScriptCodeCompletionCache { struct Cache { uint64_t time_loaded = 0; - RES cache; + Ref<Resource> cache; }; Map<String, Cache> cached; @@ -258,7 +258,7 @@ public: } } - virtual RES get_cached_resource(const String &p_path) { + virtual Ref<Resource> get_cached_resource(const String &p_path) { Map<String, Cache>::Element *E = cached.find(p_path); if (!E) { Cache c; @@ -428,7 +428,7 @@ void ScriptEditor::_goto_script_line2(int p_line) { } } -void ScriptEditor::_goto_script_line(REF p_script, int p_line) { +void ScriptEditor::_goto_script_line(Ref<RefCounted> p_script, int p_line) { Ref<Script> script = Object::cast_to<Script>(*p_script); if (script.is_valid() && (script->has_source_code() || script->get_path().is_resource_file())) { if (edit(p_script, p_line, 0)) { @@ -444,7 +444,7 @@ void ScriptEditor::_goto_script_line(REF p_script, int p_line) { } } -void ScriptEditor::_set_execution(REF p_script, int p_line) { +void ScriptEditor::_set_execution(Ref<RefCounted> p_script, int p_line) { Ref<Script> script = Object::cast_to<Script>(*p_script); if (script.is_valid() && (script->has_source_code() || script->get_path().is_resource_file())) { for (int i = 0; i < tab_container->get_tab_count(); i++) { @@ -460,7 +460,7 @@ void ScriptEditor::_set_execution(REF p_script, int p_line) { } } -void ScriptEditor::_clear_execution(REF p_script) { +void ScriptEditor::_clear_execution(Ref<RefCounted> p_script) { Ref<Script> script = Object::cast_to<Script>(*p_script); if (script.is_valid() && (script->has_source_code() || script->get_path().is_resource_file())) { for (int i = 0; i < tab_container->get_tab_count(); i++) { @@ -476,7 +476,7 @@ void ScriptEditor::_clear_execution(REF p_script) { } } -void ScriptEditor::_set_breakpoint(REF p_script, int p_line, bool p_enabled) { +void ScriptEditor::_set_breakpoint(Ref<RefCounted> p_script, int p_line, bool p_enabled) { Ref<Script> script = Object::cast_to<Script>(*p_script); if (script.is_valid() && (script->has_source_code() || script->get_path().is_resource_file())) { // Update if open. @@ -758,7 +758,7 @@ void ScriptEditor::_close_tab(int p_idx, bool p_save, bool p_history_back) { ScriptEditorBase *current = Object::cast_to<ScriptEditorBase>(tselected); if (current) { - RES file = current->get_edited_resource(); + Ref<Resource> file = current->get_edited_resource(); if (p_save && file.is_valid()) { // Do not try to save internal scripts, but prompt to save in-memory // scripts which are not saved to disk yet (have empty path). @@ -849,7 +849,7 @@ void ScriptEditor::_close_docs_tab() { void ScriptEditor::_copy_script_path() { ScriptEditorBase *se = _get_current_editor(); if (se) { - RES script = se->get_edited_resource(); + Ref<Resource> script = se->get_edited_resource(); DisplayServer::get_singleton()->clipboard_set(script->get_path()); } } @@ -906,7 +906,7 @@ void ScriptEditor::_resave_scripts(const String &p_str) { continue; } - RES script = se->get_edited_resource(); + Ref<Resource> script = se->get_edited_resource(); if (script->is_built_in()) { continue; //internal script, who cares @@ -947,7 +947,7 @@ void ScriptEditor::_reload_scripts() { continue; } - RES edited_res = se->get_edited_resource(); + Ref<Resource> edited_res = se->get_edited_resource(); if (edited_res->is_built_in()) { continue; //internal script, who cares @@ -991,7 +991,7 @@ void ScriptEditor::_res_saved_callback(const Ref<Resource> &p_res) { continue; } - RES script = se->get_edited_resource(); + Ref<Resource> script = se->get_edited_resource(); if (script == p_res) { se->tag_saved_version(); @@ -1010,7 +1010,7 @@ void ScriptEditor::_scene_saved_callback(const String &p_path) { continue; } - RES edited_res = se->get_edited_resource(); + Ref<Resource> edited_res = se->get_edited_resource(); if (!edited_res->is_built_in()) { continue; // External script, who cares. @@ -1039,7 +1039,7 @@ void ScriptEditor::_live_auto_reload_running_scripts() { EditorDebuggerNode::get_singleton()->reload_scripts(); } -bool ScriptEditor::_test_script_times_on_disk(RES p_for_script) { +bool ScriptEditor::_test_script_times_on_disk(Ref<Resource> p_for_script) { disk_changed_list->clear(); TreeItem *r = disk_changed_list->create_item(); disk_changed_list->set_hide_root(true); @@ -1051,7 +1051,7 @@ bool ScriptEditor::_test_script_times_on_disk(RES p_for_script) { for (int i = 0; i < tab_container->get_tab_count(); i++) { ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i)); if (se) { - RES edited_res = se->get_edited_resource(); + Ref<Resource> edited_res = se->get_edited_resource(); if (p_for_script.is_valid() && edited_res.is_valid() && p_for_script != edited_res) { continue; } @@ -1117,7 +1117,7 @@ void ScriptEditor::_file_dialog_action(String p_file) { case FILE_SAVE_AS: { ScriptEditorBase *current = _get_current_editor(); if (current) { - RES resource = current->get_edited_resource(); + Ref<Resource> resource = current->get_edited_resource(); String path = ProjectSettings::get_singleton()->localize_path(p_file); Error err = _save_text_file(resource, path); @@ -1323,7 +1323,7 @@ void ScriptEditor::_menu_option(int p_option) { } } - RES resource = current->get_edited_resource(); + Ref<Resource> resource = current->get_edited_resource(); Ref<TextFile> text_file = resource; Ref<Script> script = resource; @@ -1413,7 +1413,7 @@ void ScriptEditor::_menu_option(int p_option) { _copy_script_path(); } break; case SHOW_IN_FILE_SYSTEM: { - const RES script = current->get_edited_resource(); + const Ref<Resource> script = current->get_edited_resource(); String path = script->get_path(); if (!path.is_empty()) { if (script->is_built_in()) { @@ -2188,7 +2188,7 @@ Ref<TextFile> ScriptEditor::_load_text_file(const String &p_path, Error *r_error Ref<TextFile> text_res(text_file); Error err = text_file->load_text(path); - ERR_FAIL_COND_V_MSG(err != OK, RES(), "Cannot load text file '" + path + "'."); + ERR_FAIL_COND_V_MSG(err != OK, Ref<Resource>(), "Cannot load text file '" + path + "'."); text_file->set_file_path(local_path); text_file->set_path(local_path, true); @@ -2230,7 +2230,7 @@ Error ScriptEditor::_save_text_file(Ref<TextFile> p_text_file, const String &p_p return OK; } -bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_grab_focus) { +bool ScriptEditor::edit(const Ref<Resource> &p_resource, int p_line, int p_col, bool p_grab_focus) { if (p_resource.is_null()) { return false; } @@ -2447,7 +2447,7 @@ void ScriptEditor::save_current_script() { } } - RES resource = current->get_edited_resource(); + Ref<Resource> resource = current->get_edited_resource(); Ref<TextFile> text_file = resource; Ref<Script> script = resource; @@ -2516,7 +2516,7 @@ void ScriptEditor::save_all_scripts() { continue; } - RES edited_res = se->get_edited_resource(); + Ref<Resource> edited_res = se->get_edited_resource(); if (edited_res.is_valid()) { se->apply_code(); } @@ -2589,14 +2589,14 @@ void ScriptEditor::open_text_file_create_dialog(const String &p_base_path, const open_textfile_after_create = false; } -RES ScriptEditor::open_file(const String &p_file) { +Ref<Resource> ScriptEditor::open_file(const String &p_file) { List<String> extensions; ResourceLoader::get_recognized_extensions_for_type("Script", &extensions); if (extensions.find(p_file.get_extension())) { Ref<Script> scr = ResourceLoader::load(p_file); if (!scr.is_valid()) { EditorNode::get_singleton()->show_warning(TTR("Could not load file at:") + "\n\n" + p_file, TTR("Error!")); - return RES(); + return Ref<Resource>(); } edit(scr); @@ -2607,14 +2607,14 @@ RES ScriptEditor::open_file(const String &p_file) { Ref<TextFile> text_file = _load_text_file(p_file, &error); if (error != OK) { EditorNode::get_singleton()->show_warning(TTR("Could not load file at:") + "\n\n" + p_file, TTR("Error!")); - return RES(); + return Ref<Resource>(); } if (text_file.is_valid()) { edit(text_file); return text_file; } - return RES(); + return Ref<Resource>(); } void ScriptEditor::_editor_stop() { @@ -2980,7 +2980,7 @@ void ScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Co continue; } - RES res = open_file(file); + Ref<Resource> res = open_file(file); if (res.is_valid()) { if (tab_container->get_tab_count() > num_tabs_before) { tab_container->move_child(tab_container->get_tab_control(tab_container->get_tab_count() - 1), new_index); @@ -3533,7 +3533,7 @@ void ScriptEditor::_on_replace_in_files_requested(String text) { void ScriptEditor::_on_find_in_files_result_selected(String fpath, int line_number, int begin, int end) { if (ResourceLoader::exists(fpath)) { - RES res = ResourceLoader::load(fpath); + Ref<Resource> res = ResourceLoader::load(fpath); if (fpath.get_extension() == "gdshader") { ShaderEditorPlugin *shader_editor = Object::cast_to<ShaderEditorPlugin>(EditorNode::get_singleton()->get_editor_data().get_editor("Shader")); diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h index 7885ffe2c5..41b311f745 100644 --- a/editor/plugins/script_editor_plugin.h +++ b/editor/plugins/script_editor_plugin.h @@ -53,7 +53,7 @@ class EditorSyntaxHighlighter : public SyntaxHighlighter { GDCLASS(EditorSyntaxHighlighter, SyntaxHighlighter) private: - REF edited_resourse; + Ref<RefCounted> edited_resourse; protected: static void _bind_methods(); @@ -65,8 +65,8 @@ public: virtual String _get_name() const; virtual Array _get_supported_languages() const; - void _set_edited_resource(const RES &p_res) { edited_resourse = p_res; } - REF _get_edited_resource() { return edited_resourse; } + void _set_edited_resource(const Ref<Resource> &p_res) { edited_resourse = p_res; } + Ref<RefCounted> _get_edited_resource() { return edited_resourse; } virtual Ref<EditorSyntaxHighlighter> _create() const; }; @@ -136,9 +136,9 @@ public: virtual void set_syntax_highlighter(Ref<EditorSyntaxHighlighter> p_highlighter) = 0; virtual void apply_code() = 0; - virtual RES get_edited_resource() const = 0; + virtual Ref<Resource> get_edited_resource() const = 0; virtual Vector<String> get_functions() = 0; - virtual void set_edited_resource(const RES &p_res) = 0; + virtual void set_edited_resource(const Ref<Resource> &p_res) = 0; virtual void enable_editor() = 0; virtual void reload_text() = 0; virtual String get_name() = 0; @@ -179,7 +179,7 @@ public: ScriptEditorBase() {} }; -typedef ScriptEditorBase *(*CreateScriptEditorFunc)(const RES &p_resource); +typedef ScriptEditorBase *(*CreateScriptEditorFunc)(const Ref<Resource> &p_resource); class EditorScriptCodeCompletionCache; class FindInFilesDialog; @@ -249,7 +249,7 @@ class ScriptEditor : public PanelContainer { MenuButton *debug_menu = nullptr; PopupMenu *context_menu = nullptr; Timer *autosave_timer = nullptr; - uint64_t idle; + uint64_t idle = 0; PopupMenu *recent_scripts = nullptr; PopupMenu *theme_submenu = nullptr; @@ -330,7 +330,7 @@ class ScriptEditor : public PanelContainer { void _resave_scripts(const String &p_str); void _reload_scripts(); - bool _test_script_times_on_disk(RES p_for_script = Ref<Resource>()); + bool _test_script_times_on_disk(Ref<Resource> p_for_script = Ref<Resource>()); void _add_recent_script(String p_path); void _update_recent_scripts(); @@ -377,12 +377,12 @@ class ScriptEditor : public PanelContainer { bool convert_indent_on_save; void _goto_script_line2(int p_line); - void _goto_script_line(REF p_script, int p_line); - void _set_execution(REF p_script, int p_line); - void _clear_execution(REF p_script); + void _goto_script_line(Ref<RefCounted> p_script, int p_line); + void _set_execution(Ref<RefCounted> p_script, int p_line); + void _clear_execution(Ref<RefCounted> p_script); void _breaked(bool p_breaked, bool p_can_debug); void _script_created(Ref<Script> p_script); - void _set_breakpoint(REF p_scrpt, int p_line, bool p_enabled); + void _set_breakpoint(Ref<RefCounted> p_scrpt, int p_line, bool p_enabled); void _clear_breakpoints(); Array _get_cached_breakpoints_for_script(const String &p_path) const; @@ -481,12 +481,12 @@ public: void apply_scripts() const; void open_script_create_dialog(const String &p_base_name, const String &p_base_path); void open_text_file_create_dialog(const String &p_base_path, const String &p_base_name = ""); - RES open_file(const String &p_file); + Ref<Resource> open_file(const String &p_file); void ensure_select_current(); - _FORCE_INLINE_ bool edit(const RES &p_resource, bool p_grab_focus = true) { return edit(p_resource, -1, 0, p_grab_focus); } - bool edit(const RES &p_resource, int p_line, int p_col, bool p_grab_focus = true); + _FORCE_INLINE_ bool edit(const Ref<Resource> &p_resource, bool p_grab_focus = true) { return edit(p_resource, -1, 0, p_grab_focus); } + bool edit(const Ref<Resource> &p_resource, int p_line, int p_col, bool p_grab_focus = true); void get_breakpoints(List<String> *p_breakpoints); diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 4626f10b8d..981881fb9b 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -133,11 +133,11 @@ void ScriptTextEditor::apply_code() { code_editor->get_text_editor()->get_syntax_highlighter()->update_cache(); } -RES ScriptTextEditor::get_edited_resource() const { +Ref<Resource> ScriptTextEditor::get_edited_resource() const { return script; } -void ScriptTextEditor::set_edited_resource(const RES &p_res) { +void ScriptTextEditor::set_edited_resource(const Ref<Resource> &p_res) { ERR_FAIL_COND(script.is_valid()); ERR_FAIL_COND(p_res.is_null()); @@ -239,6 +239,29 @@ void ScriptTextEditor::_show_warnings_panel(bool p_show) { void ScriptTextEditor::_warning_clicked(Variant p_line) { if (p_line.get_type() == Variant::INT) { goto_line_centered(p_line.operator int64_t()); + } else if (p_line.get_type() == Variant::DICTIONARY) { + Dictionary meta = p_line.operator Dictionary(); + const int line = meta["line"].operator int64_t() - 1; + + CodeEdit *text_editor = code_editor->get_text_editor(); + String prev_line = line > 0 ? text_editor->get_line(line - 1) : ""; + if (prev_line.contains("@warning_ignore")) { + const int closing_bracket_idx = prev_line.find(")"); + const String text_to_insert = ", " + meta["code"].operator String(); + prev_line = prev_line.insert(closing_bracket_idx, text_to_insert); + text_editor->set_line(line - 1, prev_line); + } else { + const int indent = text_editor->get_indent_level(line) / text_editor->get_indent_size(); + String annotation_indent; + if (!text_editor->is_indent_using_spaces()) { + annotation_indent = String("\t").repeat(indent); + } else { + annotation_indent = String(" ").repeat(text_editor->get_indent_size() * indent); + } + text_editor->insert_line_at(line, annotation_indent + "@warning_ignore(" + meta["code"].operator String() + ")"); + } + + _validate_script(); } } @@ -482,8 +505,20 @@ void ScriptTextEditor::_update_warnings() { } // Add script warnings. - warnings_panel->push_table(2); + warnings_panel->push_table(3); for (const ScriptLanguage::Warning &w : warnings) { + Dictionary ignore_meta; + ignore_meta["line"] = w.start_line; + ignore_meta["code"] = w.string_code.to_lower(); + warnings_panel->push_cell(); + warnings_panel->push_meta(ignore_meta); + warnings_panel->push_color( + warnings_panel->get_theme_color(SNAME("accent_color"), SNAME("Editor")).lerp(warnings_panel->get_theme_color(SNAME("mono_color"), SNAME("Editor")), 0.5f)); + warnings_panel->add_text(TTR("[Ignore]")); + warnings_panel->pop(); // Color. + warnings_panel->pop(); // Meta ignore. + warnings_panel->pop(); // Cell. + warnings_panel->push_cell(); warnings_panel->push_meta(w.start_line - 1); warnings_panel->push_color(warnings_panel->get_theme_color(SNAME("warning_color"), SNAME("Editor"))); @@ -1963,7 +1998,7 @@ ScriptTextEditor::~ScriptTextEditor() { } } -static ScriptEditorBase *create_editor(const RES &p_resource) { +static ScriptEditorBase *create_editor(const Ref<Resource> &p_resource) { if (Object::cast_to<Script>(*p_resource)) { return memnew(ScriptTextEditor); } diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h index c1c4b0af54..b3e0c28bb1 100644 --- a/editor/plugins/script_text_editor.h +++ b/editor/plugins/script_text_editor.h @@ -205,8 +205,8 @@ public: void update_toggle_scripts_button() override; virtual void apply_code() override; - virtual RES get_edited_resource() const override; - virtual void set_edited_resource(const RES &p_res) override; + virtual Ref<Resource> get_edited_resource() const override; + virtual void set_edited_resource(const Ref<Resource> &p_res) override; virtual void enable_editor() override; virtual Vector<String> get_functions() override; virtual void reload_text() override; diff --git a/editor/plugins/shader_editor_plugin.h b/editor/plugins/shader_editor_plugin.h index 067711c75c..bd0c2db824 100644 --- a/editor/plugins/shader_editor_plugin.h +++ b/editor/plugins/shader_editor_plugin.h @@ -114,7 +114,7 @@ class ShaderEditor : public PanelContainer { MenuButton *help_menu = nullptr; PopupMenu *context_menu = nullptr; RichTextLabel *warnings_panel = nullptr; - uint64_t idle; + uint64_t idle = 0; GotoLineDialog *goto_line_dialog = nullptr; ConfirmationDialog *erase_tab_confirm = nullptr; diff --git a/editor/plugins/skeleton_3d_editor_plugin.h b/editor/plugins/skeleton_3d_editor_plugin.h index 911e39a34f..f4a82225f2 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.h +++ b/editor/plugins/skeleton_3d_editor_plugin.h @@ -131,7 +131,7 @@ class Skeleton3DEditor : public VBoxContainer { EditorFileDialog *file_dialog = nullptr; - bool keyable; + bool keyable = false; static Skeleton3DEditor *singleton; diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index 29beb8be84..7b6aeb3679 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -1012,7 +1012,7 @@ Variant SpriteFramesEditor::get_drag_data_fw(const Point2 &p_point, Control *p_f return Variant(); } - RES frame = frames->get_frame(edited_anim, idx); + Ref<Resource> frame = frames->get_frame(edited_anim, idx); if (frame.is_null()) { return Variant(); @@ -1036,7 +1036,7 @@ bool SpriteFramesEditor::can_drop_data_fw(const Point2 &p_point, const Variant & } if (String(d["type"]) == "resource" && d.has("resource")) { - RES r = d["resource"]; + Ref<Resource> r = d["resource"]; Ref<Texture2D> texture = r; @@ -1080,7 +1080,7 @@ void SpriteFramesEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da int at_pos = tree->get_item_at_position(p_point, true); if (String(d["type"]) == "resource" && d.has("resource")) { - RES r = d["resource"]; + Ref<Resource> r = d["resource"]; Ref<Texture2D> texture = r; diff --git a/editor/plugins/sprite_frames_editor_plugin.h b/editor/plugins/sprite_frames_editor_plugin.h index d31ce84d09..3230228fdd 100644 --- a/editor/plugins/sprite_frames_editor_plugin.h +++ b/editor/plugins/sprite_frames_editor_plugin.h @@ -105,7 +105,7 @@ class SpriteFramesEditor : public HSplitContainer { EditorFileDialog *file_split_sheet = nullptr; Set<int> frames_selected; Set<int> frames_toggled_by_mouse_hover; - int last_frame_selected; + int last_frame_selected = 0; float scale_ratio; int thumbnail_default_size; diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp index 34f3ec73c0..97ecc234e6 100644 --- a/editor/plugins/text_editor.cpp +++ b/editor/plugins/text_editor.cpp @@ -89,11 +89,11 @@ Ref<Texture2D> TextEditor::get_theme_icon() { return EditorNode::get_singleton()->get_object_icon(text_file.ptr(), ""); } -RES TextEditor::get_edited_resource() const { +Ref<Resource> TextEditor::get_edited_resource() const { return text_file; } -void TextEditor::set_edited_resource(const RES &p_res) { +void TextEditor::set_edited_resource(const Ref<Resource> &p_res) { ERR_FAIL_COND(text_file.is_valid()); ERR_FAIL_COND(p_res.is_null()); @@ -412,7 +412,7 @@ void TextEditor::_convert_case(CodeTextEditor::CaseStyle p_case) { code_editor->convert_case(p_case); } -static ScriptEditorBase *create_editor(const RES &p_resource) { +static ScriptEditorBase *create_editor(const Ref<Resource> &p_resource) { if (Object::cast_to<TextFile>(*p_resource)) { return memnew(TextEditor); } diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h index d03385d79e..9b6d568382 100644 --- a/editor/plugins/text_editor.h +++ b/editor/plugins/text_editor.h @@ -109,8 +109,8 @@ public: virtual String get_name() override; virtual Ref<Texture2D> get_theme_icon() override; - virtual RES get_edited_resource() const override; - virtual void set_edited_resource(const RES &p_res) override; + virtual Ref<Resource> get_edited_resource() const override; + virtual void set_edited_resource(const Ref<Resource> &p_res) override; virtual void enable_editor() override; virtual void reload_text() override; virtual void apply_code() override; diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp index 3fa12233a8..455592aa26 100644 --- a/editor/plugins/texture_region_editor_plugin.cpp +++ b/editor/plugins/texture_region_editor_plugin.cpp @@ -78,7 +78,7 @@ void TextureRegionEditor::_region_draw() { } Transform2D mtx; - mtx.elements[2] = -draw_ofs * draw_zoom; + mtx.columns[2] = -draw_ofs * draw_zoom; mtx.scale_basis(Vector2(draw_zoom, draw_zoom)); RS::get_singleton()->canvas_item_add_set_transform(edit_draw->get_canvas_item(), mtx); @@ -267,7 +267,7 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { } Transform2D mtx; - mtx.elements[2] = -draw_ofs * draw_zoom; + mtx.columns[2] = -draw_ofs * draw_zoom; mtx.scale_basis(Vector2(draw_zoom, draw_zoom)); const real_t handle_radius = 8 * EDSCALE; diff --git a/editor/plugins/texture_region_editor_plugin.h b/editor/plugins/texture_region_editor_plugin.h index 1e1cc2b7b2..2493446303 100644 --- a/editor/plugins/texture_region_editor_plugin.h +++ b/editor/plugins/texture_region_editor_plugin.h @@ -87,14 +87,14 @@ class TextureRegionEditor : public VBoxContainer { Rect2 rect; Rect2 rect_prev; - float prev_margin; + float prev_margin = 0.0f; int edited_margin; Map<RID, List<Rect2>> cache_map; List<Rect2> autoslice_cache; bool autoslice_is_dirty; bool drag; - bool creating; + bool creating = false; Vector2 drag_from; int drag_index; diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index e17bea0f2a..87f8c4b165 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -2537,7 +2537,7 @@ void ThemeTypeEditor::_update_type_items() { if (edited_theme->has_font(E.key(), edited_type)) { item_editor->set_edited_resource(edited_theme->get_font(E.key(), edited_type)); } else { - item_editor->set_edited_resource(RES()); + item_editor->set_edited_resource(Ref<Resource>()); } item_editor->connect("resource_selected", callable_mp(this, &ThemeTypeEditor::_edit_resource_item)); item_editor->connect("resource_changed", callable_mp(this, &ThemeTypeEditor::_font_item_changed), varray(E.key())); @@ -2545,7 +2545,7 @@ void ThemeTypeEditor::_update_type_items() { if (Theme::get_default()->has_font(E.key(), edited_type)) { item_editor->set_edited_resource(Theme::get_default()->get_font(E.key(), edited_type)); } else { - item_editor->set_edited_resource(RES()); + item_editor->set_edited_resource(Ref<Resource>()); } item_editor->set_editable(false); } @@ -2608,7 +2608,7 @@ void ThemeTypeEditor::_update_type_items() { if (edited_theme->has_icon(E.key(), edited_type)) { item_editor->set_edited_resource(edited_theme->get_icon(E.key(), edited_type)); } else { - item_editor->set_edited_resource(RES()); + item_editor->set_edited_resource(Ref<Resource>()); } item_editor->connect("resource_selected", callable_mp(this, &ThemeTypeEditor::_edit_resource_item)); item_editor->connect("resource_changed", callable_mp(this, &ThemeTypeEditor::_icon_item_changed), varray(E.key())); @@ -2616,7 +2616,7 @@ void ThemeTypeEditor::_update_type_items() { if (Theme::get_default()->has_icon(E.key(), edited_type)) { item_editor->set_edited_resource(Theme::get_default()->get_icon(E.key(), edited_type)); } else { - item_editor->set_edited_resource(RES()); + item_editor->set_edited_resource(Ref<Resource>()); } item_editor->set_editable(false); } @@ -2655,7 +2655,7 @@ void ThemeTypeEditor::_update_type_items() { if (edited_theme->has_stylebox(leading_stylebox.item_name, edited_type)) { item_editor->set_edited_resource(leading_stylebox.stylebox); } else { - item_editor->set_edited_resource(RES()); + item_editor->set_edited_resource(Ref<Resource>()); } item_editor->connect("resource_selected", callable_mp(this, &ThemeTypeEditor::_edit_resource_item)); item_editor->connect("resource_changed", callable_mp(this, &ThemeTypeEditor::_stylebox_item_changed), varray(leading_stylebox.item_name)); @@ -2680,7 +2680,7 @@ void ThemeTypeEditor::_update_type_items() { if (edited_theme->has_stylebox(E.key(), edited_type)) { item_editor->set_edited_resource(edited_theme->get_stylebox(E.key(), edited_type)); } else { - item_editor->set_edited_resource(RES()); + item_editor->set_edited_resource(Ref<Resource>()); } item_editor->connect("resource_selected", callable_mp(this, &ThemeTypeEditor::_edit_resource_item)); item_editor->connect("resource_changed", callable_mp(this, &ThemeTypeEditor::_stylebox_item_changed), varray(E.key())); @@ -2696,7 +2696,7 @@ void ThemeTypeEditor::_update_type_items() { if (Theme::get_default()->has_stylebox(E.key(), edited_type)) { item_editor->set_edited_resource(Theme::get_default()->get_stylebox(E.key(), edited_type)); } else { - item_editor->set_edited_resource(RES()); + item_editor->set_edited_resource(Ref<Resource>()); } item_editor->set_editable(false); } @@ -3065,7 +3065,7 @@ void ThemeTypeEditor::_font_size_item_changed(float p_value, String p_item_name) ur->commit_action(); } -void ThemeTypeEditor::_edit_resource_item(RES p_resource, bool p_edit) { +void ThemeTypeEditor::_edit_resource_item(Ref<Resource> p_resource, bool p_edit) { EditorNode::get_singleton()->edit_resource(p_resource); } @@ -3131,7 +3131,7 @@ void ThemeTypeEditor::_change_pinned_stylebox() { Ref<StyleBox> new_stylebox = edited_theme->get_stylebox(leading_stylebox.item_name, edited_type); leading_stylebox.stylebox = new_stylebox; - leading_stylebox.ref_stylebox = (new_stylebox.is_valid() ? new_stylebox->duplicate() : RES()); + leading_stylebox.ref_stylebox = (new_stylebox.is_valid() ? new_stylebox->duplicate() : Ref<Resource>()); if (leading_stylebox.stylebox.is_valid()) { new_stylebox->connect("changed", callable_mp(this, &ThemeTypeEditor::_update_stylebox_from_leading)); @@ -3169,7 +3169,7 @@ void ThemeTypeEditor::_pin_leading_stylebox(String p_item_name, Ref<StyleBox> p_ leader.pinned = true; leader.item_name = p_item_name; leader.stylebox = p_stylebox; - leader.ref_stylebox = (p_stylebox.is_valid() ? p_stylebox->duplicate() : RES()); + leader.ref_stylebox = (p_stylebox.is_valid() ? p_stylebox->duplicate() : Ref<Resource>()); leading_stylebox = leader; if (p_stylebox.is_valid()) { diff --git a/editor/plugins/theme_editor_plugin.h b/editor/plugins/theme_editor_plugin.h index 4b49fbb186..3894ca31e5 100644 --- a/editor/plugins/theme_editor_plugin.h +++ b/editor/plugins/theme_editor_plugin.h @@ -384,7 +384,7 @@ class ThemeTypeEditor : public MarginContainer { void _color_item_changed(Color p_value, String p_item_name); void _constant_item_changed(float p_value, String p_item_name); void _font_size_item_changed(float p_value, String p_item_name); - void _edit_resource_item(RES p_resource, bool p_edit); + void _edit_resource_item(Ref<Resource> p_resource, bool p_edit); void _font_item_changed(Ref<Font> p_value, String p_item_name); void _icon_item_changed(Ref<Texture2D> p_value, String p_item_name); void _stylebox_item_changed(Ref<StyleBox> p_value, String p_item_name); diff --git a/editor/plugins/tiles/tile_data_editors.h b/editor/plugins/tiles/tile_data_editors.h index 3ac9eacb05..2c849637f0 100644 --- a/editor/plugins/tiles/tile_data_editors.h +++ b/editor/plugins/tiles/tile_data_editors.h @@ -108,8 +108,8 @@ private: DRAG_TYPE_PAN, }; DragType drag_type = DRAG_TYPE_NONE; - int drag_polygon_index; - int drag_point_index; + int drag_polygon_index = 0; + int drag_point_index = 0; Vector2 drag_last_pos; PackedVector2Array drag_old_polygon; @@ -132,9 +132,9 @@ private: Ref<Texture2D> background_texture; Rect2 background_region; Vector2 background_offset; - bool background_h_flip; - bool background_v_flip; - bool background_transpose; + bool background_h_flip = false; + bool background_v_flip = false; + bool background_transpose = false; Color background_modulate; Color polygon_color = Color(1.0, 0.0, 0.0); diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp index c1a95c11f6..ba87eba9e0 100644 --- a/editor/plugins/tiles/tile_map_editor.cpp +++ b/editor/plugins/tiles/tile_map_editor.cpp @@ -76,7 +76,7 @@ void TileMapEditorTilesPlugin::_update_toolbar() { picker_button->show(); erase_button->show(); tools_settings_vsep_2->show(); - random_tile_checkbox->show(); + random_tile_toggle->show(); scatter_label->show(); scatter_spinbox->show(); } else if (tool_buttons_group->get_pressed_button() == line_tool_button) { @@ -84,7 +84,7 @@ void TileMapEditorTilesPlugin::_update_toolbar() { picker_button->show(); erase_button->show(); tools_settings_vsep_2->show(); - random_tile_checkbox->show(); + random_tile_toggle->show(); scatter_label->show(); scatter_spinbox->show(); } else if (tool_buttons_group->get_pressed_button() == rect_tool_button) { @@ -92,7 +92,7 @@ void TileMapEditorTilesPlugin::_update_toolbar() { picker_button->show(); erase_button->show(); tools_settings_vsep_2->show(); - random_tile_checkbox->show(); + random_tile_toggle->show(); scatter_label->show(); scatter_spinbox->show(); } else if (tool_buttons_group->get_pressed_button() == bucket_tool_button) { @@ -101,7 +101,7 @@ void TileMapEditorTilesPlugin::_update_toolbar() { erase_button->show(); tools_settings_vsep_2->show(); bucket_contiguous_checkbox->show(); - random_tile_checkbox->show(); + random_tile_toggle->show(); scatter_label->show(); scatter_spinbox->show(); } @@ -461,6 +461,7 @@ void TileMapEditorTilesPlugin::_update_theme() { picker_button->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("ColorPick"), SNAME("EditorIcons"))); erase_button->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("Eraser"), SNAME("EditorIcons"))); + random_tile_toggle->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("RandomNumberGenerator"), SNAME("EditorIcons"))); missing_atlas_texture_icon = tiles_bottom_panel->get_theme_icon(SNAME("TileSet"), SNAME("EditorIcons")); } @@ -870,7 +871,7 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over Transform2D tile_xform; tile_xform.set_origin(tile_map->map_to_world(E.key)); tile_xform.set_scale(tile_set->get_tile_size()); - if (!(drag_erasing || erase_button->is_pressed()) && random_tile_checkbox->is_pressed()) { + if (!(drag_erasing || erase_button->is_pressed()) && random_tile_toggle->is_pressed()) { tile_set->draw_tile_shape(p_overlay, xform * tile_xform, Color(1.0, 1.0, 1.0, 0.5), true); } else { if (tile_set->has_source(E.value.source_id)) { @@ -1001,7 +1002,7 @@ Map<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_line(Vector2 p_start_ Map<Vector2i, TileMapCell> output; if (!pattern->is_empty()) { // Paint the tiles on the tile map. - if (!p_erase && random_tile_checkbox->is_pressed()) { + if (!p_erase && random_tile_toggle->is_pressed()) { // Paint a random tile. Vector<Vector2i> line = TileMapEditor::get_line(tile_map, tile_map->world_to_map(p_from_mouse_pos), tile_map->world_to_map(p_to_mouse_pos)); for (int i = 0; i < line.size(); i++) { @@ -1061,7 +1062,7 @@ Map<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_rect(Vector2i p_start Map<Vector2i, TileMapCell> output; if (!pattern->is_empty()) { - if (!p_erase && random_tile_checkbox->is_pressed()) { + if (!p_erase && random_tile_toggle->is_pressed()) { // Paint a random tile. for (int x = 0; x < rect.size.x; x++) { for (int y = 0; y < rect.size.y; y++) { @@ -1134,7 +1135,7 @@ Map<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_bucket_fill(Vector2i source_cell.get_atlas_coords() == tile_map->get_cell_atlas_coords(tile_map_layer, coords) && source_cell.alternative_tile == tile_map->get_cell_alternative_tile(tile_map_layer, coords) && (source_cell.source_id != TileSet::INVALID_SOURCE || boundaries.has_point(coords))) { - if (!p_erase && random_tile_checkbox->is_pressed()) { + if (!p_erase && random_tile_toggle->is_pressed()) { // Paint a random tile. output.insert(coords, _pick_random_tile(pattern)); } else { @@ -1180,7 +1181,7 @@ Map<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_bucket_fill(Vector2i source_cell.get_atlas_coords() == tile_map->get_cell_atlas_coords(tile_map_layer, coords) && source_cell.alternative_tile == tile_map->get_cell_alternative_tile(tile_map_layer, coords) && (source_cell.source_id != TileSet::INVALID_SOURCE || boundaries.has_point(coords))) { - if (!p_erase && random_tile_checkbox->is_pressed()) { + if (!p_erase && random_tile_toggle->is_pressed()) { // Paint a random tile. output.insert(coords, _pick_random_tile(pattern)); } else { @@ -2103,11 +2104,12 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() { tools_settings->add_child(bucket_contiguous_checkbox); // Random tile checkbox. - random_tile_checkbox = memnew(CheckBox); - random_tile_checkbox->set_flat(true); - random_tile_checkbox->set_text(TTR("Place Random Tile")); - random_tile_checkbox->connect("toggled", callable_mp(this, &TileMapEditorTilesPlugin::_on_random_tile_checkbox_toggled)); - tools_settings->add_child(random_tile_checkbox); + random_tile_toggle = memnew(Button); + random_tile_toggle->set_flat(true); + random_tile_toggle->set_toggle_mode(true); + random_tile_toggle->set_tooltip(TTR("Place Random Tile")); + random_tile_toggle->connect("toggled", callable_mp(this, &TileMapEditorTilesPlugin::_on_random_tile_checkbox_toggled)); + tools_settings->add_child(random_tile_toggle); // Random tile scattering. scatter_label = memnew(Label); diff --git a/editor/plugins/tiles/tile_map_editor.h b/editor/plugins/tiles/tile_map_editor.h index 3a0293f48f..ec32c83d10 100644 --- a/editor/plugins/tiles/tile_map_editor.h +++ b/editor/plugins/tiles/tile_map_editor.h @@ -92,7 +92,7 @@ private: VSeparator *tools_settings_vsep_2 = nullptr; CheckBox *bucket_contiguous_checkbox = nullptr; - CheckBox *random_tile_checkbox = nullptr; + Button *random_tile_toggle = nullptr; float scattering = 0.0; Label *scatter_label = nullptr; SpinBox *scatter_spinbox = nullptr; diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index dc07ac7c39..f184049d41 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -5864,7 +5864,7 @@ public: class VisualShaderNodePluginDefaultEditor : public VBoxContainer { GDCLASS(VisualShaderNodePluginDefaultEditor, VBoxContainer); Ref<Resource> parent_resource; - int node_id; + int node_id = 0; VisualShader::Type shader_type; public: @@ -5881,18 +5881,18 @@ public: undo_redo->add_undo_property(node.ptr(), p_property, node->get(p_property)); if (p_value.get_type() == Variant::OBJECT) { - RES prev_res = node->get(p_property); - RES curr_res = p_value; + Ref<Resource> prev_res = node->get(p_property); + Ref<Resource> curr_res = p_value; if (curr_res.is_null()) { - undo_redo->add_do_method(this, "_open_inspector", (RES)parent_resource.ptr()); + undo_redo->add_do_method(this, "_open_inspector", (Ref<Resource>)parent_resource.ptr()); } else { - undo_redo->add_do_method(this, "_open_inspector", (RES)curr_res.ptr()); + undo_redo->add_do_method(this, "_open_inspector", (Ref<Resource>)curr_res.ptr()); } if (!prev_res.is_null()) { - undo_redo->add_undo_method(this, "_open_inspector", (RES)prev_res.ptr()); + undo_redo->add_undo_method(this, "_open_inspector", (Ref<Resource>)prev_res.ptr()); } else { - undo_redo->add_undo_method(this, "_open_inspector", (RES)parent_resource.ptr()); + undo_redo->add_undo_method(this, "_open_inspector", (Ref<Resource>)parent_resource.ptr()); } } if (p_property != "constant") { @@ -5919,15 +5919,15 @@ public: } } - void _resource_selected(const String &p_path, RES p_resource) { + void _resource_selected(const String &p_path, Ref<Resource> p_resource) { _open_inspector(p_resource); } - void _open_inspector(RES p_resource) { + void _open_inspector(Ref<Resource> p_resource) { InspectorDock::get_inspector_singleton()->edit(p_resource.ptr()); } - bool updating; + bool updating = false; Ref<VisualShaderNode> node; Vector<EditorProperty *> properties; Vector<Label *> prop_names; diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index 8db2cf07f9..540cb709b3 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -48,7 +48,7 @@ class VisualShaderNodePlugin : public RefCounted { protected: static void _bind_methods(); - GDVIRTUAL2RC(Object *, _create_editor, RES, Ref<VisualShaderNode>) + GDVIRTUAL2RC(Object *, _create_editor, Ref<Resource>, Ref<VisualShaderNode>) public: virtual Control *create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node); |