diff options
Diffstat (limited to 'editor')
75 files changed, 740 insertions, 726 deletions
diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp index 3678642521..da376c588e 100644 --- a/editor/animation_bezier_editor.cpp +++ b/editor/animation_bezier_editor.cpp @@ -218,7 +218,7 @@ void AnimationBezierTrackEdit::_draw_line_clipped(const Vector2 &p_from, const V void AnimationBezierTrackEdit::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE || p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { - panner->set_control_scheme((ViewPanner::ControlScheme)EDITOR_GET("interface/editors/animation_editors_panning_scheme").operator int()); + panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/animation_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning"))); } if (p_what == NOTIFICATION_THEME_CHANGED || p_what == NOTIFICATION_ENTER_TREE) { close_button->set_icon(get_theme_icon(SNAME("Close"), SNAME("EditorIcons"))); @@ -632,27 +632,6 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { } Ref<InputEventMouseButton> mb = p_event; - if (mb.is_valid() && mb->is_pressed() && mb->is_alt_pressed()) { - // Alternate zoom (doesn't affect timeline). - if (mb->get_button_index() == MouseButton::WHEEL_DOWN) { - const float v_zoom_orig = v_zoom; - if (v_zoom < 100000) { - v_zoom *= 1.2; - } - v_scroll = v_scroll + (mb->get_position().y - get_size().y / 2) * (v_zoom - v_zoom_orig); - update(); - } - - if (mb->get_button_index() == MouseButton::WHEEL_UP) { - const float v_zoom_orig = v_zoom; - if (v_zoom > 0.000001) { - v_zoom /= 1.2; - } - v_scroll = v_scroll + (mb->get_position().y - get_size().y / 2) * (v_zoom - v_zoom_orig); - update(); - } - } - if (mb.is_valid() && mb->get_button_index() == MouseButton::RIGHT && mb->is_pressed()) { menu_insert_key = mb->get_position(); if (menu_insert_key.x >= timeline->get_name_limit() && menu_insert_key.x <= get_size().width - timeline->get_buttons_width()) { @@ -1015,7 +994,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { } } -void AnimationBezierTrackEdit::_scroll_callback(Vector2 p_scroll_vec) { +void AnimationBezierTrackEdit::_scroll_callback(Vector2 p_scroll_vec, bool p_alt) { _pan_callback(-p_scroll_vec * 32); } @@ -1026,12 +1005,21 @@ void AnimationBezierTrackEdit::_pan_callback(Vector2 p_scroll_vec) { update(); } -void AnimationBezierTrackEdit::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin) { +void AnimationBezierTrackEdit::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin, bool p_alt) { const float v_zoom_orig = v_zoom; - if (p_scroll_vec.y > 0) { - timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() / 1.05); + if (p_alt) { + // Alternate zoom (doesn't affect timeline). + if (p_scroll_vec.y > 0) { + v_zoom = MIN(v_zoom * 1.2, 100000); + } else { + v_zoom = MAX(v_zoom / 1.2, 0.000001); + } } else { - timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() * 1.05); + if (p_scroll_vec.y > 0) { + timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() / 1.05); + } else { + timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() * 1.05); + } } v_scroll = v_scroll + (p_origin.y - get_size().y / 2) * (v_zoom - v_zoom_orig); update(); @@ -1172,8 +1160,6 @@ void AnimationBezierTrackEdit::_bind_methods() { AnimationBezierTrackEdit::AnimationBezierTrackEdit() { panner.instantiate(); panner->set_callbacks(callable_mp(this, &AnimationBezierTrackEdit::_scroll_callback), callable_mp(this, &AnimationBezierTrackEdit::_pan_callback), callable_mp(this, &AnimationBezierTrackEdit::_zoom_callback)); - panner->set_disable_rmb(true); - panner->set_control_scheme(ViewPanner::SCROLL_PANS); play_position = memnew(Control); play_position->set_mouse_filter(MOUSE_FILTER_PASS); diff --git a/editor/animation_bezier_editor.h b/editor/animation_bezier_editor.h index 6a5b97a7da..cf719a0355 100644 --- a/editor/animation_bezier_editor.h +++ b/editor/animation_bezier_editor.h @@ -126,9 +126,9 @@ class AnimationBezierTrackEdit : public Control { Set<int> selection; Ref<ViewPanner> panner; - void _scroll_callback(Vector2 p_scroll_vec); + void _scroll_callback(Vector2 p_scroll_vec, bool p_alt); void _pan_callback(Vector2 p_scroll_vec); - void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin); + void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin, bool p_alt); void _draw_line_clipped(const Vector2 &p_from, const Vector2 &p_to, const Color &p_color, int p_clip_left, int p_clip_right); void _draw_track(int p_track, const Color &p_color); diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 13e9d58744..dbbdd85706 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -1459,7 +1459,7 @@ int AnimationTimelineEdit::get_name_limit() const { void AnimationTimelineEdit::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE || p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { - panner->set_control_scheme((ViewPanner::ControlScheme)EDITOR_GET("interface/editors/animation_editors_panning_scheme").operator int()); + panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/animation_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning"))); } if (p_what == NOTIFICATION_ENTER_TREE) { @@ -1799,7 +1799,7 @@ void AnimationTimelineEdit::gui_input(const Ref<InputEvent> &p_event) { int x = mb->get_position().x - get_name_limit(); float ofs = x / get_zoom_scale() + get_value(); - emit_signal(SNAME("timeline_changed"), ofs, false, Input::get_singleton()->is_key_pressed(Key::ALT)); + emit_signal(SNAME("timeline_changed"), ofs, false, mb->is_alt_pressed()); dragging_timeline = true; } } @@ -1833,7 +1833,7 @@ void AnimationTimelineEdit::gui_input(const Ref<InputEvent> &p_event) { } } -void AnimationTimelineEdit::_scroll_callback(Vector2 p_scroll_vec) { +void AnimationTimelineEdit::_scroll_callback(Vector2 p_scroll_vec, bool p_alt) { // Timeline has no vertical scroll, so we change it to horizontal. p_scroll_vec.x += p_scroll_vec.y; _pan_callback(-p_scroll_vec * 32); @@ -1843,7 +1843,7 @@ void AnimationTimelineEdit::_pan_callback(Vector2 p_scroll_vec) { set_value(get_value() - p_scroll_vec.x / get_zoom_scale()); } -void AnimationTimelineEdit::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin) { +void AnimationTimelineEdit::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin, bool p_alt) { if (p_scroll_vec.y < 0) { get_zoom()->set_value(get_zoom()->get_value() * 1.05); } else { @@ -1872,7 +1872,7 @@ void AnimationTimelineEdit::_track_added(int p_track) { void AnimationTimelineEdit::_bind_methods() { ADD_SIGNAL(MethodInfo("zoom_changed")); ADD_SIGNAL(MethodInfo("name_limit_changed")); - ADD_SIGNAL(MethodInfo("timeline_changed", PropertyInfo(Variant::FLOAT, "position"), PropertyInfo(Variant::BOOL, "drag"))); + ADD_SIGNAL(MethodInfo("timeline_changed", PropertyInfo(Variant::FLOAT, "position"), PropertyInfo(Variant::BOOL, "drag"), PropertyInfo(Variant::BOOL, "timeline_only"))); ADD_SIGNAL(MethodInfo("track_added", PropertyInfo(Variant::INT, "track"))); ADD_SIGNAL(MethodInfo("length_changed", PropertyInfo(Variant::FLOAT, "size"))); } @@ -1932,8 +1932,6 @@ AnimationTimelineEdit::AnimationTimelineEdit() { panner.instantiate(); panner->set_callbacks(callable_mp(this, &AnimationTimelineEdit::_scroll_callback), callable_mp(this, &AnimationTimelineEdit::_pan_callback), callable_mp(this, &AnimationTimelineEdit::_zoom_callback)); - panner->set_disable_rmb(true); - panner->set_control_scheme(ViewPanner::SCROLL_PANS); set_layout_direction(Control::LAYOUT_DIRECTION_LTR); } @@ -3123,7 +3121,7 @@ void AnimationTrackEdit::append_to_selection(const Rect2 &p_box, bool p_deselect } void AnimationTrackEdit::_bind_methods() { - ADD_SIGNAL(MethodInfo("timeline_changed", PropertyInfo(Variant::FLOAT, "position"), PropertyInfo(Variant::BOOL, "drag"))); + ADD_SIGNAL(MethodInfo("timeline_changed", PropertyInfo(Variant::FLOAT, "position"), PropertyInfo(Variant::BOOL, "drag"), PropertyInfo(Variant::BOOL, "timeline_only"))); ADD_SIGNAL(MethodInfo("remove_request", PropertyInfo(Variant::INT, "track"))); ADD_SIGNAL(MethodInfo("dropped", PropertyInfo(Variant::INT, "from_track"), PropertyInfo(Variant::INT, "to_track"))); ADD_SIGNAL(MethodInfo("insert_key", PropertyInfo(Variant::FLOAT, "ofs"))); @@ -3375,7 +3373,13 @@ Node *AnimationTrackEditor::get_root() const { } void AnimationTrackEditor::update_keying() { - bool keying_enabled = is_visible_in_tree() && animation.is_valid(); + bool keying_enabled = false; + + EditorHistory *editor_history = EditorNode::get_singleton()->get_editor_history(); + if (is_visible_in_tree() && animation.is_valid() && editor_history->get_path_size() > 0) { + Object *obj = ObjectDB::get_instance(editor_history->get_path_object(0)); + keying_enabled = Object::cast_to<Node>(obj) != nullptr; + } if (keying_enabled == keying) { return; @@ -3644,7 +3648,7 @@ void AnimationTrackEditor::_insert_track(bool p_create_reset, bool p_create_bezi pos = animation->get_length(); } set_anim_pos(pos); - emit_signal(SNAME("timeline_changed"), pos, true); + emit_signal(SNAME("timeline_changed"), pos, true, false); } } @@ -4506,7 +4510,7 @@ MenuButton *AnimationTrackEditor::get_edit_menu() { void AnimationTrackEditor::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE || p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { - panner->set_control_scheme((ViewPanner::ControlScheme)EDITOR_GET("interface/editors/animation_editors_panning_scheme").operator int()); + panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/animation_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning"))); } if (p_what == NOTIFICATION_THEME_CHANGED || p_what == NOTIFICATION_ENTER_TREE) { @@ -4525,8 +4529,6 @@ void AnimationTrackEditor::_notification(int p_what) { if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { update_keying(); - EditorNode::get_singleton()->update_keying(); - emit_signal(SNAME("keying_changed")); } } @@ -5008,7 +5010,7 @@ struct _AnimMoveRestore { void AnimationTrackEditor::_clear_key_edit() { if (key_edit) { // If key edit is the object being inspected, remove it first. - if (EditorNode::get_singleton()->get_inspector()->get_edited_object() == key_edit) { + if (InspectorDock::get_inspector_singleton()->get_edited_object() == key_edit) { EditorNode::get_singleton()->push_item(nullptr); } @@ -5018,7 +5020,7 @@ void AnimationTrackEditor::_clear_key_edit() { } if (multi_key_edit) { - if (EditorNode::get_singleton()->get_inspector()->get_edited_object() == multi_key_edit) { + if (InspectorDock::get_inspector_singleton()->get_edited_object() == multi_key_edit) { EditorNode::get_singleton()->push_item(nullptr); } @@ -5228,16 +5230,6 @@ void AnimationTrackEditor::_scroll_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; - if (mb.is_valid() && mb->is_pressed() && mb->is_alt_pressed() && mb->get_button_index() == MouseButton::WHEEL_UP) { - goto_prev_step(true); - scroll->accept_event(); - } - - if (mb.is_valid() && mb->is_pressed() && mb->is_alt_pressed() && mb->get_button_index() == MouseButton::WHEEL_DOWN) { - goto_next_step(true); - scroll->accept_event(); - } - if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT) { if (mb->is_pressed()) { box_selecting = true; @@ -5302,8 +5294,16 @@ void AnimationTrackEditor::_scroll_input(const Ref<InputEvent> &p_event) { } } -void AnimationTrackEditor::_scroll_callback(Vector2 p_scroll_vec) { - _pan_callback(-p_scroll_vec * 32); +void AnimationTrackEditor::_scroll_callback(Vector2 p_scroll_vec, bool p_alt) { + if (p_alt) { + if (p_scroll_vec.x < 0 || p_scroll_vec.y < 0) { + goto_prev_step(true); + } else { + goto_next_step(true); + } + } else { + _pan_callback(-p_scroll_vec * 32); + } } void AnimationTrackEditor::_pan_callback(Vector2 p_scroll_vec) { @@ -5311,7 +5311,7 @@ void AnimationTrackEditor::_pan_callback(Vector2 p_scroll_vec) { scroll->set_v_scroll(scroll->get_v_scroll() - p_scroll_vec.y); } -void AnimationTrackEditor::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin) { +void AnimationTrackEditor::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin, bool p_alt) { if (p_scroll_vec.y < 0) { timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() * 1.05); } else { @@ -5445,7 +5445,7 @@ void AnimationTrackEditor::goto_prev_step(bool p_from_mouse_event) { pos = 0; } set_anim_pos(pos); - emit_signal(SNAME("timeline_changed"), pos, true); + emit_signal(SNAME("timeline_changed"), pos, true, false); } void AnimationTrackEditor::goto_next_step(bool p_from_mouse_event) { @@ -5472,7 +5472,7 @@ void AnimationTrackEditor::goto_next_step(bool p_from_mouse_event) { } set_anim_pos(pos); - emit_signal(SNAME("timeline_changed"), pos, true); + emit_signal(SNAME("timeline_changed"), pos, true, false); } void AnimationTrackEditor::_edit_menu_pressed(int p_option) { @@ -5696,16 +5696,16 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { to_restore.push_back(amr); } -#define _NEW_POS(m_ofs) (((s > 0) ? m_ofs : from_t + (len - (m_ofs - from_t))) - pivot) * ABS(s) + from_t +#define NEW_POS(m_ofs) (((s > 0) ? m_ofs : from_t + (len - (m_ofs - from_t))) - pivot) * ABS(s) + from_t // 3 - Move the keys (re insert them). for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) { - float newpos = _NEW_POS(E->get().pos); + float newpos = NEW_POS(E->get().pos); undo_redo->add_do_method(animation.ptr(), "track_insert_key", E->key().track, newpos, animation->track_get_key_value(E->key().track, E->key().key), animation->track_get_key_transition(E->key().track, E->key().key)); } // 4 - (Undo) Remove inserted keys. for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) { - float newpos = _NEW_POS(E->get().pos); + float newpos = NEW_POS(E->get().pos); undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_time", E->key().track, newpos); } @@ -5725,13 +5725,13 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { // 7-reselect. for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) { float oldpos = E->get().pos; - float newpos = _NEW_POS(oldpos); + float newpos = NEW_POS(oldpos); if (newpos >= 0) { undo_redo->add_do_method(this, "_select_at_anim", animation, E->key().track, newpos); } undo_redo->add_undo_method(this, "_select_at_anim", animation, E->key().track, oldpos); } -#undef _NEW_POS +#undef NEW_POS undo_redo->commit_action(); } break; case EDIT_DUPLICATE_SELECTION: { @@ -5996,7 +5996,7 @@ void AnimationTrackEditor::_bind_methods() { ClassDB::bind_method("_key_deselected", &AnimationTrackEditor::_key_deselected); // Still used by some connect_compat. ClassDB::bind_method("_clear_selection", &AnimationTrackEditor::_clear_selection); // Still used by some connect_compat. - ADD_SIGNAL(MethodInfo("timeline_changed", PropertyInfo(Variant::FLOAT, "position"), PropertyInfo(Variant::BOOL, "drag"))); + ADD_SIGNAL(MethodInfo("timeline_changed", PropertyInfo(Variant::FLOAT, "position"), PropertyInfo(Variant::BOOL, "drag"), PropertyInfo(Variant::BOOL, "timeline_only"))); ADD_SIGNAL(MethodInfo("keying_changed")); ADD_SIGNAL(MethodInfo("animation_len_changed", PropertyInfo(Variant::FLOAT, "len"))); ADD_SIGNAL(MethodInfo("animation_step_changed", PropertyInfo(Variant::FLOAT, "step"))); @@ -6107,8 +6107,6 @@ AnimationTrackEditor::AnimationTrackEditor() { panner.instantiate(); panner->set_callbacks(callable_mp(this, &AnimationTrackEditor::_scroll_callback), callable_mp(this, &AnimationTrackEditor::_pan_callback), callable_mp(this, &AnimationTrackEditor::_zoom_callback)); - panner->set_disable_rmb(true); - panner->set_control_scheme(ViewPanner::SCROLL_PANS); scroll = memnew(ScrollContainer); timeline_vbox->add_child(scroll); @@ -6116,7 +6114,9 @@ AnimationTrackEditor::AnimationTrackEditor() { VScrollBar *sb = scroll->get_v_scroll_bar(); scroll->remove_child(sb); timeline_scroll->add_child(sb); // Move here so timeline and tracks are always aligned. + scroll->set_focus_mode(FOCUS_CLICK); scroll->connect("gui_input", callable_mp(this, &AnimationTrackEditor::_scroll_input)); + scroll->connect("focus_exited", callable_mp(panner.ptr(), &ViewPanner::release_pan_key)); bezier_edit = memnew(AnimationBezierTrackEdit); timeline_vbox->add_child(bezier_edit); diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h index 2a2b20ada9..50c5c692c0 100644 --- a/editor/animation_track_editor.h +++ b/editor/animation_track_editor.h @@ -82,9 +82,9 @@ class AnimationTimelineEdit : public Range { bool use_fps; Ref<ViewPanner> panner; - void _scroll_callback(Vector2 p_scroll_vec); + void _scroll_callback(Vector2 p_scroll_vec, bool p_alt); void _pan_callback(Vector2 p_scroll_vec); - void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin); + void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin, bool p_alt); bool dragging_timeline; bool dragging_hsize; @@ -316,7 +316,7 @@ class AnimationTrackEditor : public VBoxContainer { void _update_tracks(); void _name_limit_changed(); - void _timeline_changed(float p_new_pos, bool p_drag, bool p_timeline_only = false); + void _timeline_changed(float p_new_pos, bool p_drag, bool p_timeline_only); void _track_remove_request(int p_track); void _track_grab_focus(int p_track); @@ -377,9 +377,9 @@ class AnimationTrackEditor : public VBoxContainer { PropertyInfo _find_hint_for_track(int p_idx, NodePath &r_base_path, Variant *r_current_val = nullptr); Ref<ViewPanner> panner; - void _scroll_callback(Vector2 p_scroll_vec); + void _scroll_callback(Vector2 p_scroll_vec, bool p_alt); void _pan_callback(Vector2 p_scroll_vec); - void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin); + void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin, bool p_alt); void _timeline_value_changed(double); diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index 4669e56e20..fb36bfc5e5 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -1909,7 +1909,7 @@ CodeTextEditor::CodeTextEditor() { text_editor->connect("gui_input", callable_mp(this, &CodeTextEditor::_text_editor_gui_input)); text_editor->connect("caret_changed", callable_mp(this, &CodeTextEditor::_line_col_changed)); text_editor->connect("text_changed", callable_mp(this, &CodeTextEditor::_text_changed)); - text_editor->connect("request_code_completion", callable_mp(this, &CodeTextEditor::_complete_request)); + text_editor->connect("code_completion_requested", callable_mp(this, &CodeTextEditor::_complete_request)); TypedArray<String> cs; cs.push_back("."); cs.push_back(","); diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index c23fd6a943..bda558bb72 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -649,8 +649,8 @@ void ConnectionsDock::_connect(ConnectDialog::ConnectionData p_cd) { undo_redo->add_undo_method(source, "disconnect", p_cd.signal, callable); undo_redo->add_do_method(this, "update_tree"); undo_redo->add_undo_method(this, "update_tree"); - undo_redo->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); // To force redraw of scene tree. - undo_redo->add_undo_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); + undo_redo->add_do_method(SceneTreeDock::get_singleton()->get_tree_editor(), "update_tree"); // To force redraw of scene tree. + undo_redo->add_undo_method(SceneTreeDock::get_singleton()->get_tree_editor(), "update_tree"); undo_redo->commit_action(); } @@ -671,8 +671,8 @@ void ConnectionsDock::_disconnect(TreeItem &p_item) { undo_redo->add_undo_method(selected_node, "connect", cd.signal, callable, cd.binds, cd.flags); undo_redo->add_do_method(this, "update_tree"); undo_redo->add_undo_method(this, "update_tree"); - undo_redo->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); // To force redraw of scene tree. - undo_redo->add_undo_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); + undo_redo->add_do_method(SceneTreeDock::get_singleton()->get_tree_editor(), "update_tree"); // To force redraw of scene tree. + undo_redo->add_undo_method(SceneTreeDock::get_singleton()->get_tree_editor(), "update_tree"); undo_redo->commit_action(); } @@ -702,8 +702,8 @@ void ConnectionsDock::_disconnect_all() { undo_redo->add_do_method(this, "update_tree"); undo_redo->add_undo_method(this, "update_tree"); - undo_redo->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); - undo_redo->add_undo_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); + undo_redo->add_do_method(SceneTreeDock::get_singleton()->get_tree_editor(), "update_tree"); + undo_redo->add_undo_method(SceneTreeDock::get_singleton()->get_tree_editor(), "update_tree"); undo_redo->commit_action(); } diff --git a/editor/debugger/editor_debugger_node.cpp b/editor/debugger/editor_debugger_node.cpp index e9d275895f..79853b6809 100644 --- a/editor/debugger/editor_debugger_node.cpp +++ b/editor/debugger/editor_debugger_node.cpp @@ -75,8 +75,8 @@ EditorDebuggerNode::EditorDebuggerNode() { remote_scene_tree = memnew(EditorDebuggerTree); remote_scene_tree->connect("object_selected", callable_mp(this, &EditorDebuggerNode::_remote_object_requested)); remote_scene_tree->connect("save_node", callable_mp(this, &EditorDebuggerNode::_save_node_requested)); - EditorNode::get_singleton()->get_scene_tree_dock()->add_remote_tree_editor(remote_scene_tree); - EditorNode::get_singleton()->get_scene_tree_dock()->connect("remote_tree_selected", callable_mp(this, &EditorDebuggerNode::request_remote_tree)); + SceneTreeDock::get_singleton()->add_remote_tree_editor(remote_scene_tree); + SceneTreeDock::get_singleton()->connect("remote_tree_selected", callable_mp(this, &EditorDebuggerNode::request_remote_tree)); remote_scene_tree_timeout = EDITOR_DEF("debugger/remote_scene_tree_refresh_interval", 1.0); inspect_edited_object_timeout = EDITOR_DEF("debugger/remote_inspect_refresh_interval", 0.2); @@ -332,10 +332,10 @@ void EditorDebuggerNode::_notification(int p_what) { // Switch to remote tree view if so desired. auto_switch_remote_scene_tree = (bool)EditorSettings::get_singleton()->get("debugger/auto_switch_to_remote_scene_tree"); if (auto_switch_remote_scene_tree) { - EditorNode::get_singleton()->get_scene_tree_dock()->show_remote_tree(); + SceneTreeDock::get_singleton()->show_remote_tree(); } // Good to go. - EditorNode::get_singleton()->get_scene_tree_dock()->show_tab_buttons(); + SceneTreeDock::get_singleton()->show_tab_buttons(); debugger->set_editor_remote_tree(remote_scene_tree); debugger->start(server->take_connection()); // Send breakpoints. @@ -361,8 +361,8 @@ void EditorDebuggerNode::_debugger_stopped(int p_id) { if (!found) { EditorNode::get_singleton()->get_pause_button()->set_pressed(false); EditorNode::get_singleton()->get_pause_button()->set_disabled(true); - EditorNode::get_singleton()->get_scene_tree_dock()->hide_remote_tree(); - EditorNode::get_singleton()->get_scene_tree_dock()->hide_tab_buttons(); + SceneTreeDock::get_singleton()->hide_remote_tree(); + SceneTreeDock::get_singleton()->hide_tab_buttons(); EditorNode::get_singleton()->notify_all_debug_sessions_exited(); } } @@ -576,7 +576,7 @@ void EditorDebuggerNode::_remote_object_property_updated(ObjectID p_id, const St if (obj->remote_object_id != p_id) { return; } - EditorNode::get_singleton()->get_inspector()->update_property(p_property); + InspectorDock::get_inspector_singleton()->update_property(p_property); } } diff --git a/editor/debugger/editor_debugger_tree.cpp b/editor/debugger/editor_debugger_tree.cpp index 70d64615ae..29d0014b8a 100644 --- a/editor/debugger/editor_debugger_tree.cpp +++ b/editor/debugger/editor_debugger_tree.cpp @@ -128,7 +128,7 @@ void EditorDebuggerTree::_scene_tree_rmb_selected(const Vector2 &p_position) { void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int p_debugger) { updating_scene_tree = true; const String last_path = get_selected_path(); - const String filter = EditorNode::get_singleton()->get_scene_tree_dock()->get_filter(); + const String filter = SceneTreeDock::get_singleton()->get_filter(); bool filter_changed = filter != last_filter; TreeItem *scroll_item = nullptr; diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp index 4349ffc75b..ee844fff64 100644 --- a/editor/debugger/script_editor_debugger.cpp +++ b/editor/debugger/script_editor_debugger.cpp @@ -1121,7 +1121,7 @@ void ScriptEditorDebugger::_property_changed(Object *p_base, const StringName &p NodePath path = editor->get_edited_scene()->get_path_to(node); int pathid = _get_node_path_cache(path); - if (p_value.is_ref()) { + if (p_value.is_ref_counted()) { Ref<Resource> res = p_value; if (res.is_valid() && !res->get_path().is_empty()) { Array msg; @@ -1147,7 +1147,7 @@ void ScriptEditorDebugger::_property_changed(Object *p_base, const StringName &p String respath = res->get_path(); int pathid = _get_res_path_cache(respath); - if (p_value.is_ref()) { + if (p_value.is_ref_counted()) { Ref<Resource> res2 = p_value; if (res2.is_valid() && !res2->get_path().is_empty()) { Array msg; diff --git a/editor/editor_asset_installer.cpp b/editor/editor_asset_installer.cpp index 5d4c746785..76c0811166 100644 --- a/editor/editor_asset_installer.cpp +++ b/editor/editor_asset_installer.cpp @@ -36,45 +36,6 @@ #include "editor_node.h" #include "progress_dialog.h" -void EditorAssetInstaller::_update_subitems(TreeItem *p_item, bool p_check, bool p_first) { - if (p_check) { - if (p_item->get_custom_color(0) == Color()) { - p_item->set_checked(0, true); - } - } else { - p_item->set_checked(0, false); - } - - if (p_item->get_first_child()) { - _update_subitems(p_item->get_first_child(), p_check); - } - - if (!p_first && p_item->get_next()) { - _update_subitems(p_item->get_next(), p_check); - } -} - -void EditorAssetInstaller::_uncheck_parent(TreeItem *p_item) { - if (!p_item) { - return; - } - - bool any_checked = false; - TreeItem *item = p_item->get_first_child(); - while (item) { - if (item->is_checked(0)) { - any_checked = true; - break; - } - item = item->get_next(); - } - - if (!any_checked) { - p_item->set_checked(0, false); - _uncheck_parent(p_item->get_parent()); - } -} - void EditorAssetInstaller::_item_edited() { if (updating) { return; @@ -85,22 +46,17 @@ void EditorAssetInstaller::_item_edited() { return; } - String path = item->get_metadata(0); - updating = true; - if (path.is_empty() || item == tree->get_root()) { //a dir or root - _update_subitems(item, item->is_checked(0), true); - } + item->propagate_check(0); + updating = false; +} - if (item->is_checked(0)) { - while (item) { - item->set_checked(0, true); - item = item->get_parent(); - } - } else { - _uncheck_parent(item->get_parent()); +void EditorAssetInstaller::_check_propagated_to_item(Object *p_obj, int column) { + TreeItem *affected_item = Object::cast_to<TreeItem>(p_obj); + if (affected_item && affected_item->get_custom_color(0) != Color()) { + affected_item->set_checked(0, false); + affected_item->propagate_check(0, false); } - updating = false; } void EditorAssetInstaller::open(const String &p_path, int p_depth) { @@ -259,6 +215,7 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) { ti->set_custom_color(0, tree->get_theme_color(SNAME("error_color"), SNAME("Editor"))); ti->set_tooltip(0, vformat(TTR("%s (already exists)"), res_path)); ti->set_checked(0, false); + ti->propagate_check(0); } else { ti->set_tooltip(0, res_path); } @@ -275,7 +232,7 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) { asset_contents->set_text(vformat(TTR("Contents of asset \"%s\" - No files conflict with your project:"), asset_name)); } - popup_centered_ratio(); + popup_centered_ratio(0.5); updating = false; } @@ -304,7 +261,7 @@ void EditorAssetInstaller::ok_pressed() { String name = String::utf8(fname); - if (status_map.has(name) && status_map[name]->is_checked(0)) { + if (status_map.has(name) && (status_map[name]->is_checked(0) || status_map[name]->is_indeterminate(0))) { String path = status_map[name]->get_metadata(0); if (path.is_empty()) { // a dir @@ -392,6 +349,7 @@ EditorAssetInstaller::EditorAssetInstaller() { tree = memnew(Tree); tree->set_v_size_flags(Control::SIZE_EXPAND_FILL); tree->connect("item_edited", callable_mp(this, &EditorAssetInstaller::_item_edited)); + tree->connect("check_propagated_to_item", callable_mp(this, &EditorAssetInstaller::_check_propagated_to_item)); vb->add_child(tree); error = memnew(AcceptDialog); diff --git a/editor/editor_asset_installer.h b/editor/editor_asset_installer.h index 2f59250933..f5993f73e7 100644 --- a/editor/editor_asset_installer.h +++ b/editor/editor_asset_installer.h @@ -43,9 +43,8 @@ class EditorAssetInstaller : public ConfirmationDialog { AcceptDialog *error; Map<String, TreeItem *> status_map; bool updating; - void _update_subitems(TreeItem *p_item, bool p_check, bool p_first = false); - void _uncheck_parent(TreeItem *p_item); void _item_edited(); + void _check_propagated_to_item(Object *p_obj, int column); virtual void ok_pressed() override; protected: diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index 8e4bbbb99b..5e4e375db4 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -1163,7 +1163,7 @@ void EditorAudioBuses::_server_save() { } void EditorAudioBuses::_select_layout() { - EditorNode::get_singleton()->get_filesystem_dock()->select_file(edited_path); + FileSystemDock::get_singleton()->select_file(edited_path); } void EditorAudioBuses::_save_as_layout() { diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp index d556255a8f..0c9a7b2972 100644 --- a/editor/editor_fonts.cpp +++ b/editor/editor_fonts.cpp @@ -269,7 +269,10 @@ void editor_register_fonts(Ref<Theme> p_theme) { /* Hack */ - Ref<FontData> dfmono = load_cached_internal_font(_font_Hack_Regular, _font_Hack_Regular_size, font_hinting, font_antialiased, true); + Ref<FontData> dfmono = load_cached_internal_font(_font_JetBrainsMono_Regular, _font_JetBrainsMono_Regular_size, font_hinting, font_antialiased, true); + Dictionary opentype_features; + opentype_features["calt"] = 0; + dfmono->set_opentype_feature_overrides(opentype_features); // Disable contextual alternates (coding ligatures). // Default font MAKE_DEFAULT_FONT(df, String()); diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index 28cf2ee75f..6d5e56184a 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -169,12 +169,15 @@ void EditorHelp::_class_desc_resized() { Ref<Font> doc_code_font = get_theme_font(SNAME("doc_source"), SNAME("EditorFonts")); int font_size = get_theme_font_size(SNAME("doc_source_size"), SNAME("EditorFonts")); real_t char_width = doc_code_font->get_char_size('x', 0, font_size).width; - const int display_margin = MAX(30 * EDSCALE, get_parent_anchorable_rect().size.width - char_width * 120 * EDSCALE) * 0.5; - - Ref<StyleBox> class_desc_stylebox = EditorNode::get_singleton()->get_theme_base()->get_theme_stylebox(SNAME("normal"), SNAME("RichTextLabel"))->duplicate(); - class_desc_stylebox->set_default_margin(SIDE_LEFT, display_margin); - class_desc_stylebox->set_default_margin(SIDE_RIGHT, display_margin); - class_desc->add_theme_style_override("normal", class_desc_stylebox); + const int new_display_margin = MAX(30 * EDSCALE, get_parent_anchorable_rect().size.width - char_width * 120 * EDSCALE) * 0.5; + if (display_margin != new_display_margin) { + display_margin = new_display_margin; + + Ref<StyleBox> class_desc_stylebox = EditorNode::get_singleton()->get_theme_base()->get_theme_stylebox(SNAME("normal"), SNAME("RichTextLabel"))->duplicate(); + class_desc_stylebox->set_default_margin(SIDE_LEFT, display_margin); + class_desc_stylebox->set_default_margin(SIDE_RIGHT, display_margin); + class_desc->add_theme_style_override("normal", class_desc_stylebox); + } } void EditorHelp::_add_type(const String &p_type, const String &p_enum) { @@ -1599,24 +1602,28 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) { pos = brk_pos + 1; } else if (tag.begins_with("method ") || tag.begins_with("member ") || tag.begins_with("signal ") || tag.begins_with("enum ") || tag.begins_with("constant ") || tag.begins_with("theme_item ")) { - int tag_end = tag.find(" "); - - String link_tag = tag.substr(0, tag_end); - String link_target = tag.substr(tag_end + 1, tag.length()).lstrip(" "); + const int tag_end = tag.find(" "); + const String link_tag = tag.substr(0, tag_end); + const String link_target = tag.substr(tag_end + 1, tag.length()).lstrip(" "); + p_rt->push_font(doc_code_font); p_rt->push_color(link_color); p_rt->push_meta("@" + link_tag + " " + link_target); p_rt->add_text(link_target + (tag.begins_with("method ") ? "()" : "")); p_rt->pop(); p_rt->pop(); + p_rt->pop(); pos = brk_end + 1; } else if (doc->class_list.has(tag)) { + // Class reference tag such as [Node2D] or [SceneTree]. + p_rt->push_font(doc_code_font); p_rt->push_color(link_color); p_rt->push_meta("#" + tag); p_rt->add_text(tag); p_rt->pop(); p_rt->pop(); + p_rt->pop(); pos = brk_end + 1; } else if (tag == "b") { diff --git a/editor/editor_help.h b/editor/editor_help.h index 377ae05a08..237cf4f347 100644 --- a/editor/editor_help.h +++ b/editor/editor_help.h @@ -156,6 +156,7 @@ class EditorHelp : public VBoxContainer { void _class_desc_select(const String &p_select); void _class_desc_input(const Ref<InputEvent> &p_input); void _class_desc_resized(); + int display_margin = 0; Error _goto_desc(const String &p_class, int p_vscr = -1); //void _update_history_buttons(); diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 75e518e050..a3538d3381 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -623,14 +623,17 @@ void EditorProperty::gui_input(const Ref<InputEvent> &p_event) { if (property == "frame_coords" && (object->is_class("Sprite2D") || object->is_class("Sprite3D"))) { Vector2i new_coords = object->get(property); new_coords.x++; - if (new_coords.x >= object->get("hframes").operator int64_t()) { + if (new_coords.x >= int64_t(object->get("hframes"))) { new_coords.x = 0; new_coords.y++; } - - call_deferred(SNAME("emit_changed"), property, new_coords, "", false); + if (new_coords.x < int64_t(object->get("hframes")) && new_coords.y < int64_t(object->get("vframes"))) { + call_deferred(SNAME("emit_changed"), property, new_coords, "", false); + } } else { - call_deferred(SNAME("emit_changed"), property, object->get(property).operator int64_t() + 1, "", false); + if (int64_t(object->get(property)) + 1 < (int64_t(object->get("hframes")) * int64_t(object->get("vframes")))) { + call_deferred(SNAME("emit_changed"), property, object->get(property).operator int64_t() + 1, "", false); + } } call_deferred(SNAME("update_property")); @@ -861,10 +864,10 @@ String EditorProperty::get_tooltip_text() const { void EditorProperty::menu_option(int p_option) { switch (p_option) { case MENU_COPY_PROPERTY: { - EditorNode::get_singleton()->get_inspector()->set_property_clipboard(object->get(property)); + InspectorDock::get_inspector_singleton()->set_property_clipboard(object->get(property)); } break; case MENU_PASTE_PROPERTY: { - emit_changed(property, EditorNode::get_singleton()->get_inspector()->get_property_clipboard()); + emit_changed(property, InspectorDock::get_inspector_singleton()->get_property_clipboard()); } break; case MENU_COPY_PROPERTY_PATH: { DisplayServer::get_singleton()->clipboard_set(property); @@ -2905,6 +2908,7 @@ void EditorInspector::edit(Object *p_object) { object->connect("property_list_changed", callable_mp(this, &EditorInspector::_changed_callback)); update_tree(); } + emit_signal("edited_object_changed"); } void EditorInspector::set_keying(bool p_active) { @@ -3543,6 +3547,7 @@ void EditorInspector::_bind_methods() { ADD_SIGNAL(MethodInfo("object_id_selected", PropertyInfo(Variant::INT, "id"))); ADD_SIGNAL(MethodInfo("property_edited", PropertyInfo(Variant::STRING, "property"))); ADD_SIGNAL(MethodInfo("property_toggled", PropertyInfo(Variant::STRING, "property"), PropertyInfo(Variant::BOOL, "checked"))); + ADD_SIGNAL(MethodInfo("edited_object_changed")); ADD_SIGNAL(MethodInfo("restart_requested")); } diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index cc92d391d9..a1f259c864 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -429,7 +429,7 @@ void EditorNode::unhandled_input(const Ref<InputEvent> &p_event) { _scene_tab_changed(next_tab); } if (ED_IS_SHORTCUT("editor/filter_files", p_event)) { - filesystem_dock->focus_on_filter(); + FileSystemDock::get_singleton()->focus_on_filter(); } if (ED_IS_SHORTCUT("editor/editor_2d", p_event)) { @@ -1100,8 +1100,8 @@ void EditorNode::_version_button_pressed() { } void EditorNode::_node_renamed() { - if (get_inspector()) { - get_inspector()->update_tree(); + if (InspectorDock::get_inspector_singleton()) { + InspectorDock::get_inspector_singleton()->update_tree(); } } @@ -1162,7 +1162,7 @@ Error EditorNode::load_resource(const String &p_resource, bool p_ignore_broken_d return ERR_FILE_MISSING_DEPENDENCIES; } - inspector_dock->edit_resource(res); + InspectorDock::get_singleton()->edit_resource(res); return OK; } @@ -2070,10 +2070,10 @@ void EditorNode::edit_item(Object *p_object) { void EditorNode::push_item(Object *p_object, const String &p_property, bool p_inspector_only) { if (!p_object) { - get_inspector()->edit(nullptr); - node_dock->set_node(nullptr); - scene_tree_dock->set_selected(nullptr); - inspector_dock->update(nullptr); + InspectorDock::get_inspector_singleton()->edit(nullptr); + NodeDock::get_singleton()->set_node(nullptr); + SceneTreeDock::get_singleton()->set_selected(nullptr); + InspectorDock::get_singleton()->update(nullptr); _display_top_editors(false); return; } @@ -2146,17 +2146,17 @@ void EditorNode::_edit_current(bool p_skip_foreign) { this->current = current_obj; if (!current_obj) { - scene_tree_dock->set_selected(nullptr); - get_inspector()->edit(nullptr); - node_dock->set_node(nullptr); - inspector_dock->update(nullptr); + SceneTreeDock::get_singleton()->set_selected(nullptr); + InspectorDock::get_inspector_singleton()->edit(nullptr); + NodeDock::get_singleton()->set_node(nullptr); + InspectorDock::get_singleton()->update(nullptr); _display_top_editors(false); return; } - Object *prev_inspected_object = get_inspector()->get_edited_object(); + Object *prev_inspected_object = InspectorDock::get_inspector_singleton()->get_edited_object(); bool disable_folding = bool(EDITOR_GET("interface/inspector/disable_folding")); bool is_resource = current_obj->is_class("Resource"); @@ -2167,11 +2167,11 @@ void EditorNode::_edit_current(bool p_skip_foreign) { if (is_resource) { Resource *current_res = Object::cast_to<Resource>(current_obj); ERR_FAIL_COND(!current_res); - get_inspector()->edit(current_res); - scene_tree_dock->set_selected(nullptr); - node_dock->set_node(nullptr); - inspector_dock->update(nullptr); - EditorNode::get_singleton()->get_import_dock()->set_edit_path(current_res->get_path()); + InspectorDock::get_inspector_singleton()->edit(current_res); + SceneTreeDock::get_singleton()->set_selected(nullptr); + NodeDock::get_singleton()->set_node(nullptr); + InspectorDock::get_singleton()->update(nullptr); + ImportDock::get_singleton()->set_edit_path(current_res->get_path()); int subr_idx = current_res->get_path().find("::"); if (subr_idx != -1) { @@ -2192,15 +2192,15 @@ void EditorNode::_edit_current(bool p_skip_foreign) { Node *current_node = Object::cast_to<Node>(current_obj); ERR_FAIL_COND(!current_node); - get_inspector()->edit(current_node); + InspectorDock::get_inspector_singleton()->edit(current_node); if (current_node->is_inside_tree()) { - node_dock->set_node(current_node); - scene_tree_dock->set_selected(current_node); - inspector_dock->update(current_node); + NodeDock::get_singleton()->set_node(current_node); + SceneTreeDock::get_singleton()->set_selected(current_node); + InspectorDock::get_singleton()->update(current_node); } else { - node_dock->set_node(nullptr); - scene_tree_dock->set_selected(nullptr); - inspector_dock->update(nullptr); + NodeDock::get_singleton()->set_node(nullptr); + SceneTreeDock::get_singleton()->set_selected(nullptr); + InspectorDock::get_singleton()->update(nullptr); } if (get_edited_scene() && !get_edited_scene()->get_scene_file_path().is_empty()) { @@ -2238,21 +2238,21 @@ void EditorNode::_edit_current(bool p_skip_foreign) { } } - get_inspector()->edit(current_obj); - node_dock->set_node(nullptr); - scene_tree_dock->set_selected(selected_node); - inspector_dock->update(nullptr); + InspectorDock::get_inspector_singleton()->edit(current_obj); + NodeDock::get_singleton()->set_node(nullptr); + SceneTreeDock::get_singleton()->set_selected(selected_node); + InspectorDock::get_singleton()->update(nullptr); } if (current_obj == prev_inspected_object) { // Make sure inspected properties are restored. - get_inspector()->update_tree(); + InspectorDock::get_inspector_singleton()->update_tree(); } - inspector_dock->set_warning(editable_warning); + InspectorDock::get_singleton()->set_warning(editable_warning); - if (get_inspector()->is_using_folding() == disable_folding) { - get_inspector()->set_use_folding(!disable_folding); + if (InspectorDock::get_inspector_singleton()->is_using_folding() == disable_folding) { + InspectorDock::get_inspector_singleton()->set_use_folding(!disable_folding); } /* Take care of PLUGIN EDITOR */ @@ -2306,8 +2306,7 @@ void EditorNode::_edit_current(bool p_skip_foreign) { } } - inspector_dock->update(current_obj); - inspector_dock->update_keying(); + InspectorDock::get_singleton()->update(current_obj); } void EditorNode::_run(bool p_current, const String &p_custom) { @@ -2765,7 +2764,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { case FILE_SHOW_IN_FILESYSTEM: { String path = editor_data.get_scene_path(editor_data.get_edited_scene()); if (!path.is_empty()) { - filesystem_dock->navigate_to_path(path); + FileSystemDock::get_singleton()->navigate_to_path(path); } } break; @@ -3362,7 +3361,7 @@ void EditorNode::set_edited_scene(Node *p_scene) { if (Object::cast_to<Popup>(p_scene)) { Object::cast_to<Popup>(p_scene)->show(); // show popups } - scene_tree_dock->set_edited_scene(p_scene); + SceneTreeDock::get_singleton()->set_edited_scene(p_scene); if (get_tree()) { get_tree()->set_edited_scene_root(p_scene); } @@ -3387,10 +3386,10 @@ int EditorNode::_get_current_main_editor() { Dictionary EditorNode::_get_main_scene_state() { Dictionary state; state["main_tab"] = _get_current_main_editor(); - state["scene_tree_offset"] = scene_tree_dock->get_tree_editor()->get_scene_tree()->get_vscroll_bar()->get_value(); - state["property_edit_offset"] = get_inspector()->get_scroll_offset(); + state["scene_tree_offset"] = SceneTreeDock::get_singleton()->get_tree_editor()->get_scene_tree()->get_vscroll_bar()->get_value(); + state["property_edit_offset"] = InspectorDock::get_inspector_singleton()->get_scroll_offset(); state["saved_version"] = saved_version; - state["node_filter"] = scene_tree_dock->get_filter(); + state["node_filter"] = SceneTreeDock::get_singleton()->get_filter(); return state; } @@ -3432,14 +3431,14 @@ void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) { } if (p_state.has("scene_tree_offset")) { - scene_tree_dock->get_tree_editor()->get_scene_tree()->get_vscroll_bar()->set_value(p_state["scene_tree_offset"]); + SceneTreeDock::get_singleton()->get_tree_editor()->get_scene_tree()->get_vscroll_bar()->set_value(p_state["scene_tree_offset"]); } if (p_state.has("property_edit_offset")) { - get_inspector()->set_scroll_offset(p_state["property_edit_offset"]); + InspectorDock::get_inspector_singleton()->set_scroll_offset(p_state["property_edit_offset"]); } if (p_state.has("node_filter")) { - scene_tree_dock->set_filter(p_state["node_filter"]); + SceneTreeDock::get_singleton()->set_filter(p_state["node_filter"]); } // this should only happen at the very end @@ -3494,7 +3493,7 @@ void EditorNode::set_current_scene(int p_idx) { Object::cast_to<Popup>(new_scene)->show(); // show popups } - scene_tree_dock->set_edited_scene(new_scene); + SceneTreeDock::get_singleton()->set_edited_scene(new_scene); if (get_tree()) { get_tree()->set_edited_scene_root(new_scene); } @@ -3674,7 +3673,7 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b prev_scene->set_disabled(previous_scenes.size() == 0); opening_prev = false; - scene_tree_dock->set_selected(new_scene); + SceneTreeDock::get_singleton()->set_selected(new_scene); EditorDebuggerNode::get_singleton()->update_live_edit_root(); @@ -3699,27 +3698,11 @@ void EditorNode::open_request(const String &p_path) { } void EditorNode::request_instance_scene(const String &p_path) { - scene_tree_dock->instantiate(p_path); + SceneTreeDock::get_singleton()->instantiate(p_path); } void EditorNode::request_instantiate_scenes(const Vector<String> &p_files) { - scene_tree_dock->instantiate_scenes(p_files); -} - -ImportDock *EditorNode::get_import_dock() { - return import_dock; -} - -FileSystemDock *EditorNode::get_filesystem_dock() { - return filesystem_dock; -} - -SceneTreeDock *EditorNode::get_scene_tree_dock() { - return scene_tree_dock; -} - -InspectorDock *EditorNode::get_inspector_dock() { - return inspector_dock; + SceneTreeDock::get_singleton()->instantiate_scenes(p_files); } void EditorNode::_inherit_request(String p_file) { @@ -4515,10 +4498,10 @@ void EditorNode::_save_docks_to_config(Ref<ConfigFile> p_layout, const String &p } } - p_layout->set_value(p_section, "dock_filesystem_split", filesystem_dock->get_split_offset()); - p_layout->set_value(p_section, "dock_filesystem_display_mode", filesystem_dock->get_display_mode()); - p_layout->set_value(p_section, "dock_filesystem_file_sort", filesystem_dock->get_file_sort()); - p_layout->set_value(p_section, "dock_filesystem_file_list_display_mode", filesystem_dock->get_file_list_display_mode()); + p_layout->set_value(p_section, "dock_filesystem_split", FileSystemDock::get_singleton()->get_split_offset()); + p_layout->set_value(p_section, "dock_filesystem_display_mode", FileSystemDock::get_singleton()->get_display_mode()); + p_layout->set_value(p_section, "dock_filesystem_file_sort", FileSystemDock::get_singleton()->get_file_sort()); + p_layout->set_value(p_section, "dock_filesystem_file_list_display_mode", FileSystemDock::get_singleton()->get_file_list_display_mode()); for (int i = 0; i < vsplits.size(); i++) { if (vsplits[i]->is_visible_in_tree()) { @@ -4704,22 +4687,22 @@ void EditorNode::_load_docks_from_config(Ref<ConfigFile> p_layout, const String if (p_layout->has_section_key(p_section, "dock_filesystem_split")) { int fs_split_ofs = p_layout->get_value(p_section, "dock_filesystem_split"); - filesystem_dock->set_split_offset(fs_split_ofs); + FileSystemDock::get_singleton()->set_split_offset(fs_split_ofs); } if (p_layout->has_section_key(p_section, "dock_filesystem_display_mode")) { FileSystemDock::DisplayMode dock_filesystem_display_mode = FileSystemDock::DisplayMode(int(p_layout->get_value(p_section, "dock_filesystem_display_mode"))); - filesystem_dock->set_display_mode(dock_filesystem_display_mode); + FileSystemDock::get_singleton()->set_display_mode(dock_filesystem_display_mode); } if (p_layout->has_section_key(p_section, "dock_filesystem_file_sort")) { FileSystemDock::FileSortOption dock_filesystem_file_sort = FileSystemDock::FileSortOption(int(p_layout->get_value(p_section, "dock_filesystem_file_sort"))); - filesystem_dock->set_file_sort(dock_filesystem_file_sort); + FileSystemDock::get_singleton()->set_file_sort(dock_filesystem_file_sort); } if (p_layout->has_section_key(p_section, "dock_filesystem_file_list_display_mode")) { FileSystemDock::FileListDisplayMode dock_filesystem_file_list_display_mode = FileSystemDock::FileListDisplayMode(int(p_layout->get_value(p_section, "dock_filesystem_file_list_display_mode"))); - filesystem_dock->set_file_list_display_mode(dock_filesystem_file_list_display_mode); + FileSystemDock::get_singleton()->set_file_list_display_mode(dock_filesystem_file_list_display_mode); } for (int i = 0; i < vsplits.size(); i++) { @@ -4973,7 +4956,7 @@ void EditorNode::_layout_menu_option(int p_id) { void EditorNode::_scene_tab_script_edited(int p_tab) { Ref<Script> script = editor_data.get_scene_root_script(p_tab); if (script.is_valid()) { - inspector_dock->edit_resource(script); + InspectorDock::get_singleton()->edit_resource(script); } } @@ -5438,7 +5421,7 @@ void EditorNode::_global_menu_new_window(const Variant &p_tag) { } void EditorNode::_dropped_files(const Vector<String> &p_files, int p_screen) { - String to_path = ProjectSettings::get_singleton()->globalize_path(get_filesystem_dock()->get_selected_path()); + String to_path = ProjectSettings::get_singleton()->globalize_path(FileSystemDock::get_singleton()->get_selected_path()); _add_dropped_files_recursive(p_files, to_path); @@ -5644,15 +5627,15 @@ void EditorNode::_resource_loaded(RES p_resource, const String &p_path) { void EditorNode::_feature_profile_changed() { Ref<EditorFeatureProfile> profile = feature_profile_manager->get_current_profile(); - TabContainer *import_tabs = cast_to<TabContainer>(import_dock->get_parent()); - TabContainer *node_tabs = cast_to<TabContainer>(node_dock->get_parent()); - TabContainer *fs_tabs = cast_to<TabContainer>(filesystem_dock->get_parent()); + TabContainer *import_tabs = cast_to<TabContainer>(ImportDock::get_singleton()->get_parent()); + TabContainer *node_tabs = cast_to<TabContainer>(NodeDock::get_singleton()->get_parent()); + TabContainer *fs_tabs = cast_to<TabContainer>(FileSystemDock::get_singleton()->get_parent()); if (profile.is_valid()) { - node_tabs->set_tab_hidden(node_dock->get_index(), profile->is_feature_disabled(EditorFeatureProfile::FEATURE_NODE_DOCK)); + node_tabs->set_tab_hidden(NodeDock::get_singleton()->get_index(), profile->is_feature_disabled(EditorFeatureProfile::FEATURE_NODE_DOCK)); // The Import dock is useless without the FileSystem dock. Ensure the configuration is valid. bool fs_dock_disabled = profile->is_feature_disabled(EditorFeatureProfile::FEATURE_FILESYSTEM_DOCK); - fs_tabs->set_tab_hidden(filesystem_dock->get_index(), fs_dock_disabled); - import_tabs->set_tab_hidden(import_dock->get_index(), fs_dock_disabled || profile->is_feature_disabled(EditorFeatureProfile::FEATURE_IMPORT_DOCK)); + fs_tabs->set_tab_hidden(FileSystemDock::get_singleton()->get_index(), fs_dock_disabled); + import_tabs->set_tab_hidden(ImportDock::get_singleton()->get_index(), fs_dock_disabled || profile->is_feature_disabled(EditorFeatureProfile::FEATURE_IMPORT_DOCK)); main_editor_buttons[EDITOR_3D]->set_visible(!profile->is_feature_disabled(EditorFeatureProfile::FEATURE_3D)); main_editor_buttons[EDITOR_SCRIPT]->set_visible(!profile->is_feature_disabled(EditorFeatureProfile::FEATURE_SCRIPT)); @@ -5665,12 +5648,12 @@ void EditorNode::_feature_profile_changed() { _editor_select(EDITOR_2D); } } else { - import_tabs->set_tab_hidden(import_dock->get_index(), false); - node_tabs->set_tab_hidden(node_dock->get_index(), false); - fs_tabs->set_tab_hidden(filesystem_dock->get_index(), false); - import_dock->set_visible(true); - node_dock->set_visible(true); - filesystem_dock->set_visible(true); + import_tabs->set_tab_hidden(ImportDock::get_singleton()->get_index(), false); + node_tabs->set_tab_hidden(NodeDock::get_singleton()->get_index(), false); + fs_tabs->set_tab_hidden(FileSystemDock::get_singleton()->get_index(), false); + ImportDock::get_singleton()->set_visible(true); + NodeDock::get_singleton()->set_visible(true); + FileSystemDock::get_singleton()->set_visible(true); main_editor_buttons[EDITOR_3D]->set_visible(true); main_editor_buttons[EDITOR_SCRIPT]->set_visible(true); if (StreamPeerSSL::is_available()) { @@ -5698,8 +5681,6 @@ void EditorNode::_bind_methods() { ClassDB::bind_method("stop_child_process", &EditorNode::stop_child_process); - ClassDB::bind_method("get_script_create_dialog", &EditorNode::get_script_create_dialog); - ClassDB::bind_method("set_current_scene", &EditorNode::set_current_scene); ClassDB::bind_method("set_current_version", &EditorNode::set_current_version); ClassDB::bind_method("_thumbnail_done", &EditorNode::_thumbnail_done); @@ -6044,11 +6025,8 @@ EditorNode::EditorNode() { EDITOR_DEF("interface/inspector/default_color_picker_shape", (int32_t)ColorPicker::SHAPE_VHS_CIRCLE); EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/inspector/default_color_picker_shape", PROPERTY_HINT_ENUM, "HSV Rectangle,HSV Rectangle Wheel,VHS Circle", PROPERTY_USAGE_DEFAULT)); EDITOR_DEF("run/auto_save/save_before_running", true); - EDITOR_DEF("interface/editors/sub_editor_panning_scheme", 0); - EDITOR_DEF("interface/editors/animation_editors_panning_scheme", 1); - // Should be in sync with ControlScheme in ViewPanner. - EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/editors/sub_editor_panning_scheme", PROPERTY_HINT_ENUM, "Scroll Zooms,Scroll Pans", PROPERTY_USAGE_DEFAULT)); - EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/editors/animation_editors_panning_scheme", PROPERTY_HINT_ENUM, "Scroll Zooms,Scroll Pans", PROPERTY_USAGE_DEFAULT)); + + ED_SHORTCUT("canvas_item_editor/pan_view", TTR("Pan View"), Key::SPACE); const Vector<String> textfile_ext = ((String)(EditorSettings::get_singleton()->get("docks/filesystem/textfile_extensions"))).split(",", false); for (const String &E : textfile_ext) { @@ -6702,35 +6680,35 @@ EditorNode::EditorNode() { // Instantiate and place editor docks - scene_tree_dock = memnew(SceneTreeDock(this, scene_root, editor_selection, editor_data)); - inspector_dock = memnew(InspectorDock(this, editor_data)); - import_dock = memnew(ImportDock); - node_dock = memnew(NodeDock); + memnew(SceneTreeDock(this, scene_root, editor_selection, editor_data)); + memnew(InspectorDock(this, editor_data)); + memnew(ImportDock); + memnew(NodeDock); - filesystem_dock = memnew(FileSystemDock(this)); + FileSystemDock *filesystem_dock = memnew(FileSystemDock(this)); filesystem_dock->connect("inherit", callable_mp(this, &EditorNode::_inherit_request)); filesystem_dock->connect("instance", callable_mp(this, &EditorNode::_instantiate_request)); filesystem_dock->connect("display_mode_changed", callable_mp(this, &EditorNode::_save_docks)); // Scene: Top left - dock_slot[DOCK_SLOT_LEFT_UR]->add_child(scene_tree_dock); - dock_slot[DOCK_SLOT_LEFT_UR]->set_tab_title(scene_tree_dock->get_index(), TTR("Scene")); + dock_slot[DOCK_SLOT_LEFT_UR]->add_child(SceneTreeDock::get_singleton()); + dock_slot[DOCK_SLOT_LEFT_UR]->set_tab_title(SceneTreeDock::get_singleton()->get_index(), TTR("Scene")); // Import: Top left, behind Scene - dock_slot[DOCK_SLOT_LEFT_UR]->add_child(import_dock); - dock_slot[DOCK_SLOT_LEFT_UR]->set_tab_title(import_dock->get_index(), TTR("Import")); + dock_slot[DOCK_SLOT_LEFT_UR]->add_child(ImportDock::get_singleton()); + dock_slot[DOCK_SLOT_LEFT_UR]->set_tab_title(ImportDock::get_singleton()->get_index(), TTR("Import")); // FileSystem: Bottom left - dock_slot[DOCK_SLOT_LEFT_BR]->add_child(filesystem_dock); - dock_slot[DOCK_SLOT_LEFT_BR]->set_tab_title(filesystem_dock->get_index(), TTR("FileSystem")); + dock_slot[DOCK_SLOT_LEFT_BR]->add_child(FileSystemDock::get_singleton()); + dock_slot[DOCK_SLOT_LEFT_BR]->set_tab_title(FileSystemDock::get_singleton()->get_index(), TTR("FileSystem")); // Inspector: Full height right - dock_slot[DOCK_SLOT_RIGHT_UL]->add_child(inspector_dock); - dock_slot[DOCK_SLOT_RIGHT_UL]->set_tab_title(inspector_dock->get_index(), TTR("Inspector")); + dock_slot[DOCK_SLOT_RIGHT_UL]->add_child(InspectorDock::get_singleton()); + dock_slot[DOCK_SLOT_RIGHT_UL]->set_tab_title(InspectorDock::get_singleton()->get_index(), TTR("Inspector")); // Node: Full height right, behind Inspector - dock_slot[DOCK_SLOT_RIGHT_UL]->add_child(node_dock); - dock_slot[DOCK_SLOT_RIGHT_UL]->set_tab_title(node_dock->get_index(), TTR("Node")); + dock_slot[DOCK_SLOT_RIGHT_UL]->add_child(NodeDock::get_singleton()); + dock_slot[DOCK_SLOT_RIGHT_UL]->set_tab_title(NodeDock::get_singleton()->get_index(), TTR("Node")); // Hide unused dock slots and vsplits dock_slot[DOCK_SLOT_LEFT_UL]->hide(); @@ -7174,7 +7152,7 @@ EditorNode::EditorNode() { editor_data.set_edited_scene(0); _update_scene_tabs(); - import_dock->initialize_import_options(); + ImportDock::get_singleton()->initialize_import_options(); FileAccess::set_file_close_fail_notify_callback(_file_access_close_error_notify); diff --git a/editor/editor_node.h b/editor/editor_node.h index ff56040297..f8489777bd 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -302,11 +302,6 @@ private: Ref<Theme> theme; PopupMenu *recent_scenes; - SceneTreeDock *scene_tree_dock; - InspectorDock *inspector_dock; - NodeDock *node_dock; - ImportDock *import_dock; - FileSystemDock *filesystem_dock; EditorRunNative *run_native; ConfirmationDialog *confirmation; @@ -717,9 +712,6 @@ public: EditorPluginList *get_editor_plugins_over() { return editor_plugins_over; } EditorPluginList *get_editor_plugins_force_over() { return editor_plugins_force_over; } EditorPluginList *get_editor_plugins_force_input_forwarding() { return editor_plugins_force_input_forwarding; } - EditorInspector *get_inspector() { return inspector_dock->get_inspector(); } - Container *get_inspector_dock_addon_area() { return inspector_dock->get_addon_area(); } - ScriptCreateDialog *get_script_create_dialog() { return scene_tree_dock->get_script_create_dialog(); } ProjectSettingsEditor *get_project_settings() { return project_settings; } @@ -743,8 +735,7 @@ public: bool is_addon_plugin_enabled(const String &p_addon) const; void edit_node(Node *p_node); - void edit_resource(const Ref<Resource> &p_resource) { inspector_dock->edit_resource(p_resource); }; - void open_resource(const String &p_type) { inspector_dock->open_resource(p_type); }; + void edit_resource(const Ref<Resource> &p_resource) { InspectorDock::get_singleton()->edit_resource(p_resource); }; void save_resource_in_path(const Ref<Resource> &p_resource, const String &p_path); void save_resource(const Ref<Resource> &p_resource); @@ -795,10 +786,6 @@ public: void request_instance_scene(const String &p_path); void request_instantiate_scenes(const Vector<String> &p_files); - FileSystemDock *get_filesystem_dock(); - ImportDock *get_import_dock(); - SceneTreeDock *get_scene_tree_dock(); - InspectorDock *get_inspector_dock(); static UndoRedo *get_undo_redo() { return &singleton->editor_data.get_undo_redo(); } EditorSelection *get_editor_selection() { return editor_selection; } @@ -884,7 +871,6 @@ public: void edit_current() { _edit_current(); }; - void update_keying() const { inspector_dock->update_keying(); }; bool has_scenes_in_session(); int execute_and_show_output(const String &p_title, const String &p_path, const List<String> &p_arguments, bool p_close_on_ok = true, bool p_close_on_errors = false); diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index 6579b1eb31..29f6079fcf 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -233,15 +233,15 @@ ScriptEditor *EditorInterface::get_script_editor() { } void EditorInterface::select_file(const String &p_file) { - EditorNode::get_singleton()->get_filesystem_dock()->select_file(p_file); + FileSystemDock::get_singleton()->select_file(p_file); } String EditorInterface::get_selected_path() const { - return EditorNode::get_singleton()->get_filesystem_dock()->get_selected_path(); + return FileSystemDock::get_singleton()->get_selected_path(); } String EditorInterface::get_current_path() const { - return EditorNode::get_singleton()->get_filesystem_dock()->get_current_path(); + return FileSystemDock::get_singleton()->get_current_path(); } void EditorInterface::inspect_object(Object *p_obj, const String &p_for_property, bool p_inspector_only) { @@ -253,7 +253,7 @@ EditorFileSystem *EditorInterface::get_resource_file_system() { } FileSystemDock *EditorInterface::get_file_system_dock() { - return EditorNode::get_singleton()->get_filesystem_dock(); + return FileSystemDock::get_singleton(); } EditorSelection *EditorInterface::get_selection() { @@ -288,7 +288,7 @@ bool EditorInterface::is_plugin_enabled(const String &p_plugin) const { } EditorInspector *EditorInterface::get_inspector() const { - return EditorNode::get_singleton()->get_inspector(); + return InspectorDock::get_inspector_singleton(); } Error EditorInterface::save_scene() { @@ -445,7 +445,7 @@ void EditorPlugin::add_control_to_container(CustomControlContainer p_location, C } break; case CONTAINER_PROPERTY_EDITOR_BOTTOM: { - EditorNode::get_singleton()->get_inspector_dock_addon_area()->add_child(p_control); + InspectorDock::get_singleton()->get_addon_area()->add_child(p_control); } break; case CONTAINER_PROJECT_SETTING_TAB_LEFT: { @@ -498,7 +498,7 @@ void EditorPlugin::remove_control_from_container(CustomControlContainer p_locati } break; case CONTAINER_PROPERTY_EDITOR_BOTTOM: { - EditorNode::get_singleton()->get_inspector_dock_addon_area()->remove_child(p_control); + InspectorDock::get_singleton()->get_addon_area()->remove_child(p_control); } break; case CONTAINER_PROJECT_SETTING_TAB_LEFT: @@ -833,7 +833,7 @@ EditorInterface *EditorPlugin::get_editor_interface() { } ScriptCreateDialog *EditorPlugin::get_script_create_dialog() { - return EditorNode::get_singleton()->get_script_create_dialog(); + return SceneTreeDock::get_singleton()->get_script_create_dialog(); } void EditorPlugin::add_debugger_plugin(const Ref<Script> &p_script) { diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp index 36203bca36..71a855b22c 100644 --- a/editor/editor_properties_array_dict.cpp +++ b/editor/editor_properties_array_dict.cpp @@ -627,7 +627,7 @@ void EditorPropertyArray::_reorder_button_gui_input(const Ref<InputEvent> &p_eve } vbox->move_child(reorder_selected_element_hbox, reorder_to_index % page_length + 2); // Ensure the moving element is visible. - EditorNode::get_singleton()->get_inspector()->ensure_control_visible(reorder_selected_element_hbox); + InspectorDock::get_inspector_singleton()->ensure_control_visible(reorder_selected_element_hbox); } } } diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp index 6002bcfadc..716643f812 100644 --- a/editor/editor_resource_picker.cpp +++ b/editor/editor_resource_picker.cpp @@ -328,7 +328,7 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { } break; case OBJ_MENU_SHOW_IN_FILE_SYSTEM: { - FileSystemDock *file_system_dock = EditorNode::get_singleton()->get_filesystem_dock(); + FileSystemDock *file_system_dock = FileSystemDock::get_singleton(); file_system_dock->navigate_to_path(edited_resource->get_path()); // Ensure that the FileSystem dock is visible. @@ -862,6 +862,7 @@ void EditorResourcePicker::_ensure_resource_menu() { edit_menu->connect("id_pressed", callable_mp(this, &EditorResourcePicker::_edit_menu_cbk)); edit_menu->connect("popup_hide", callable_mp((BaseButton *)edit_button, &BaseButton::set_pressed), varray(false)); } + EditorResourcePicker::EditorResourcePicker() { assign_button = memnew(Button); assign_button->set_flat(true); @@ -906,14 +907,14 @@ bool EditorScriptPicker::handle_menu_selected(int p_which) { switch (p_which) { case OBJ_MENU_NEW_SCRIPT: { if (script_owner) { - EditorNode::get_singleton()->get_scene_tree_dock()->open_script_dialog(script_owner, false); + SceneTreeDock::get_singleton()->open_script_dialog(script_owner, false); } return true; } case OBJ_MENU_EXTEND_SCRIPT: { if (script_owner) { - EditorNode::get_singleton()->get_scene_tree_dock()->open_script_dialog(script_owner, true); + SceneTreeDock::get_singleton()->open_script_dialog(script_owner, true); } return true; } @@ -958,7 +959,7 @@ bool EditorShaderPicker::handle_menu_selected(int p_which) { switch (p_which) { case OBJ_MENU_NEW_SHADER: { if (material.is_valid()) { - EditorNode::get_singleton()->get_scene_tree_dock()->open_shader_dialog(material, preferred_mode); + SceneTreeDock::get_singleton()->open_shader_dialog(material, preferred_mode); return true; } } break; diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index b9291bcd0f..8146f48f91 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -377,7 +377,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { lang_hint += locale; int score = TranslationServer::get_singleton()->compare_locales(host_lang, locale); - if (score >= best_score) { + if (score > 0 && score >= best_score) { best = locale; best_score = score; if (score == 10) { @@ -643,10 +643,15 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { _initial_set("editors/2d/bone_outline_size", 2); _initial_set("editors/2d/viewport_border_color", Color(0.4, 0.4, 1.0, 0.4)); _initial_set("editors/2d/constrain_editor_view", true); - _initial_set("editors/2d/warped_mouse_panning", true); - _initial_set("editors/2d/simple_panning", false); - _initial_set("editors/2d/scroll_to_pan", false); - _initial_set("editors/2d/pan_speed", 20); + + // Panning + // Enum should be in sync with ControlScheme in ViewPanner. + EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "editors/panning/2d_editor_panning_scheme", 0, "Scroll Zooms,Scroll Pans"); + EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "editors/panning/sub_editors_panning_scheme", 0, "Scroll Zooms,Scroll Pans"); + EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "editors/panning/animation_editors_panning_scheme", 1, "Scroll Zooms,Scroll Pans"); + _initial_set("editors/panning/simple_panning", false); + _initial_set("editors/panning/warped_mouse_panning", true); + _initial_set("editors/panning/2d_editor_pan_speed", 20); // Tiles editor _initial_set("editors/tiles_editor/display_grid", true); diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 8e87ddee80..db4161fc3d 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -112,6 +112,7 @@ static Ref<Texture2D> flip_icon(Ref<Texture2D> p_texture, bool p_flip_y = false, } #ifdef MODULE_SVG_ENABLED +// See also `generate_icon()` in `scene/resources/default_theme.cpp`. static Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color, float p_scale = EDSCALE, float p_saturation = 1.0, Dictionary p_convert_colors = Dictionary()) { Ref<ImageTexture> icon = memnew(ImageTexture); Ref<Image> img = memnew(Image); diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index d71861e72d..cd29a3e617 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -48,6 +48,8 @@ #include "servers/display_server.h" #include "shader_create_dialog.h" +FileSystemDock *FileSystemDock::singleton = nullptr; + Ref<Texture2D> FileSystemDock::_get_tree_item_icon(bool p_is_valid, String p_file_type) { Ref<Texture2D> file_icon; if (!p_is_valid) { @@ -2335,7 +2337,7 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, String to_dir; bool favorite; _get_drag_target_folder(to_dir, favorite, p_point, p_from); - EditorNode::get_singleton()->get_scene_tree_dock()->save_branch_to_file(to_dir); + SceneTreeDock::get_singleton()->save_branch_to_file(to_dir); } } @@ -2506,6 +2508,7 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str String fpath = p_paths[0]; String item_text = fpath.ends_with("/") ? TTR("Open in File Manager") : TTR("Show in File Manager"); p_popup->add_icon_item(get_theme_icon(SNAME("Filesystem"), SNAME("EditorIcons")), item_text, FILE_SHOW_IN_EXPLORER); + path = fpath; } } @@ -2542,6 +2545,9 @@ void FileSystemDock::_tree_rmb_empty(const Vector2 &p_pos) { tree_popup->add_icon_item(get_theme_icon(SNAME("Script"), SNAME("EditorIcons")), TTR("New Script..."), FILE_NEW_SCRIPT); tree_popup->add_icon_item(get_theme_icon(SNAME("Object"), SNAME("EditorIcons")), TTR("New Resource..."), FILE_NEW_RESOURCE); tree_popup->add_icon_item(get_theme_icon(SNAME("TextFile"), SNAME("EditorIcons")), TTR("New TextFile..."), FILE_NEW_TEXTFILE); + tree_popup->add_separator(); + tree_popup->add_icon_item(get_theme_icon(SNAME("Filesystem"), SNAME("EditorIcons")), TTR("Open in File Manager"), FILE_SHOW_IN_EXPLORER); + tree_popup->set_position(tree->get_screen_position() + p_pos); tree_popup->reset_size(); tree_popup->popup(); @@ -2581,6 +2587,8 @@ void FileSystemDock::_file_list_rmb_pressed(const Vector2 &p_pos) { return; } + path = current_path->get_text(); + file_list_popup->clear(); file_list_popup->reset_size(); @@ -2737,11 +2745,11 @@ void FileSystemDock::_update_import_dock() { } if (imports.size() == 0) { - EditorNode::get_singleton()->get_import_dock()->clear(); + ImportDock::get_singleton()->clear(); } else if (imports.size() == 1) { - EditorNode::get_singleton()->get_import_dock()->set_edit_path(imports[0]); + ImportDock::get_singleton()->set_edit_path(imports[0]); } else { - EditorNode::get_singleton()->get_import_dock()->set_edit_multiple_paths(imports); + ImportDock::get_singleton()->set_edit_multiple_paths(imports); } import_dock_needs_update = false; @@ -2810,6 +2818,7 @@ void FileSystemDock::_bind_methods() { } FileSystemDock::FileSystemDock(EditorNode *p_editor) { + singleton = this; set_name("FileSystem"); editor = p_editor; path = "res://"; @@ -3045,4 +3054,5 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { } FileSystemDock::~FileSystemDock() { + singleton = nullptr; } diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index 8d50f05da9..1dc986dcb2 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -304,6 +304,12 @@ private: void _feature_profile_changed(); Vector<String> _remove_self_included_paths(Vector<String> selected_strings); +private: + static FileSystemDock *singleton; + +public: + static FileSystemDock *get_singleton() { return singleton; } + protected: void _notification(int p_what); static void _bind_methods(); diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp index ff24339f9f..15455b759b 100644 --- a/editor/groups_editor.cpp +++ b/editor/groups_editor.cpp @@ -144,8 +144,8 @@ void GroupDialog::_add_pressed() { undo_redo->add_undo_method(this, "emit_signal", "group_edited"); // To force redraw of scene tree. - undo_redo->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); - undo_redo->add_undo_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); + undo_redo->add_do_method(SceneTreeDock::get_singleton()->get_tree_editor(), "update_tree"); + undo_redo->add_undo_method(SceneTreeDock::get_singleton()->get_tree_editor(), "update_tree"); undo_redo->commit_action(); } @@ -173,8 +173,8 @@ void GroupDialog::_removed_pressed() { undo_redo->add_undo_method(this, "emit_signal", "group_edited"); // To force redraw of scene tree. - undo_redo->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); - undo_redo->add_undo_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); + undo_redo->add_do_method(SceneTreeDock::get_singleton()->get_tree_editor(), "update_tree"); + undo_redo->add_undo_method(SceneTreeDock::get_singleton()->get_tree_editor(), "update_tree"); undo_redo->commit_action(); } @@ -211,6 +211,10 @@ void GroupDialog::_add_group(String p_name) { groups->ensure_cursor_is_visible(); } +void GroupDialog::_add_group_text_changed(const String &p_new_text) { + add_group_button->set_disabled(p_new_text.strip_edges().is_empty()); +} + void GroupDialog::_group_renamed() { TreeItem *renamed_group = groups->get_edited(); if (!renamed_group) { @@ -333,8 +337,8 @@ void GroupDialog::_modify_group_pressed(Object *p_item, int p_column, int p_id) undo_redo->add_undo_method(this, "emit_signal", "group_edited"); // To force redraw of scene tree. - undo_redo->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); - undo_redo->add_undo_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); + undo_redo->add_do_method(SceneTreeDock::get_singleton()->get_tree_editor(), "update_tree"); + undo_redo->add_undo_method(SceneTreeDock::get_singleton()->get_tree_editor(), "update_tree"); undo_redo->commit_action(); } break; @@ -457,8 +461,9 @@ GroupDialog::GroupDialog() { chbc->add_child(add_group_text); add_group_text->set_h_size_flags(Control::SIZE_EXPAND_FILL); add_group_text->connect("text_submitted", callable_mp(this, &GroupDialog::_add_group_pressed)); + add_group_text->connect("text_changed", callable_mp(this, &GroupDialog::_add_group_text_changed)); - Button *add_group_button = memnew(Button); + add_group_button = memnew(Button); add_group_button->set_text(TTR("Add")); chbc->add_child(add_group_button); add_group_button->connect("pressed", callable_mp(this, &GroupDialog::_add_group_pressed), varray(String())); @@ -557,6 +562,8 @@ GroupDialog::GroupDialog() { error = memnew(ConfirmationDialog); add_child(error); error->get_ok_button()->set_text(TTR("Close")); + + _add_group_text_changed(""); } //////////////////////////////////////////////////////////////////////////////// @@ -571,6 +578,7 @@ void GroupsEditor::_add_group(const String &p_group) { return; } + group_name->clear(); if (node->is_in_group(name)) { return; } @@ -583,12 +591,10 @@ void GroupsEditor::_add_group(const String &p_group) { undo_redo->add_undo_method(this, "update_tree"); // To force redraw of scene tree. - undo_redo->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); - undo_redo->add_undo_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); + undo_redo->add_do_method(SceneTreeDock::get_singleton()->get_tree_editor(), "update_tree"); + undo_redo->add_undo_method(SceneTreeDock::get_singleton()->get_tree_editor(), "update_tree"); undo_redo->commit_action(); - - group_name->clear(); } void GroupsEditor::_modify_group(Object *p_item, int p_column, int p_id) { @@ -611,8 +617,8 @@ void GroupsEditor::_modify_group(Object *p_item, int p_column, int p_id) { undo_redo->add_undo_method(this, "update_tree"); // To force redraw of scene tree. - undo_redo->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); - undo_redo->add_undo_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); + undo_redo->add_do_method(SceneTreeDock::get_singleton()->get_tree_editor(), "update_tree"); + undo_redo->add_undo_method(SceneTreeDock::get_singleton()->get_tree_editor(), "update_tree"); undo_redo->commit_action(); } break; @@ -622,6 +628,10 @@ void GroupsEditor::_modify_group(Object *p_item, int p_column, int p_id) { } } +void GroupsEditor::_group_name_changed(const String &p_new_text) { + add->set_disabled(p_new_text.strip_edges().is_empty()); +} + struct _GroupInfoComparator { bool operator()(const Node::GroupInfo &p_a, const Node::GroupInfo &p_b) const { return p_a.name.operator String() < p_b.name.operator String(); @@ -711,6 +721,7 @@ GroupsEditor::GroupsEditor() { group_name->set_h_size_flags(Control::SIZE_EXPAND_FILL); hbc->add_child(group_name); group_name->connect("text_submitted", callable_mp(this, &GroupsEditor::_add_group)); + group_name->connect("text_changed", callable_mp(this, &GroupsEditor::_group_name_changed)); add = memnew(Button); add->set_text(TTR("Add")); @@ -724,6 +735,8 @@ GroupsEditor::GroupsEditor() { tree->connect("button_pressed", callable_mp(this, &GroupsEditor::_modify_group)); tree->add_theme_constant_override("draw_guides", 1); add_theme_constant_override("separation", 3 * EDSCALE); + + _group_name_changed(""); } GroupsEditor::~GroupsEditor() { diff --git a/editor/groups_editor.h b/editor/groups_editor.h index 677ef14a1f..aa70ac5bc4 100644 --- a/editor/groups_editor.h +++ b/editor/groups_editor.h @@ -49,6 +49,7 @@ class GroupDialog : public AcceptDialog { TreeItem *groups_root; LineEdit *add_group_text; + Button *add_group_button; Tree *groups; @@ -77,6 +78,7 @@ class GroupDialog : public AcceptDialog { void _add_pressed(); void _removed_pressed(); void _add_group_pressed(const String &p_name); + void _add_group_text_changed(const String &p_new_text); void _group_renamed(); void _rename_group_item(const String &p_old_name, const String &p_new_name); @@ -122,6 +124,7 @@ class GroupsEditor : public VBoxContainer { void update_tree(); void _add_group(const String &p_group = ""); void _modify_group(Object *p_item, int p_column, int p_id); + void _group_name_changed(const String &p_new_text); void _show_group_dialog(); diff --git a/editor/icons/GizmoGIProbe.svg b/editor/icons/GizmoVoxelGI.svg index ff3cafa1f5..ff3cafa1f5 100644 --- a/editor/icons/GizmoGIProbe.svg +++ b/editor/icons/GizmoVoxelGI.svg diff --git a/editor/icons/editor_icons_builders.py b/editor/icons/editor_icons_builders.py index d7145abe50..fb9a57c429 100644 --- a/editor/icons/editor_icons_builders.py +++ b/editor/icons/editor_icons_builders.py @@ -8,7 +8,7 @@ import os from io import StringIO from platform_methods import subprocess_main - +# See also `scene/resources/default_theme/default_theme_icons_builders.py`. def make_editor_icons_action(target, source, env): dst = target[0] diff --git a/editor/import/dynamicfont_import_settings.cpp b/editor/import/dynamicfont_import_settings.cpp index f4b1468314..81b98c1d45 100644 --- a/editor/import/dynamicfont_import_settings.cpp +++ b/editor/import/dynamicfont_import_settings.cpp @@ -427,6 +427,7 @@ void DynamicFontImportSettings::_add_glyph_range_item(int32_t p_start, int32_t p for (int i = 0; i < pages; i++) { TreeItem *item = glyph_tree->create_item(glyph_root); ERR_FAIL_NULL(item); + item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); item->set_text(0, _pad_zeros(String::num_int64(start, 16)) + " - " + _pad_zeros(String::num_int64(start + page_size, 16))); item->set_text(1, p_name); item->set_metadata(0, Vector2i(start, start + page_size)); @@ -435,6 +436,7 @@ void DynamicFontImportSettings::_add_glyph_range_item(int32_t p_start, int32_t p if (remain > 0) { TreeItem *item = glyph_tree->create_item(glyph_root); ERR_FAIL_NULL(item); + item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); item->set_text(0, _pad_zeros(String::num_int64(start, 16)) + " - " + _pad_zeros(String::num_int64(p_end, 16))); item->set_text(1, p_name); item->set_metadata(0, Vector2i(start, p_end)); @@ -656,6 +658,30 @@ void DynamicFontImportSettings::_glyph_selected() { } } label_glyphs->set_text(TTR("Preloaded glyphs: ") + itos(selected_glyphs.size())); + + item = glyph_tree->get_selected(); + ERR_FAIL_NULL(item); + Vector2i range = item->get_metadata(0); + + int total_chars = range.y - range.x; + int selected_count = 0; + for (int i = range.x; i < range.y; i++) { + if (!font_main->has_char(i)) { + total_chars--; + } + + if (selected_chars.has(i)) { + selected_count++; + } + } + + if (selected_count == total_chars) { + item->set_checked(0, true); + } else if (selected_count > 0) { + item->set_indeterminate(0, true); + } else { + item->set_checked(0, false); + } } void DynamicFontImportSettings::_range_edited() { @@ -760,6 +786,10 @@ void DynamicFontImportSettings::_range_update(int32_t p_start, int32_t p_end) { } } _edit_range(p_start, p_end); + + TreeItem *item = glyph_tree->get_selected(); + ERR_FAIL_NULL(item); + item->set_checked(0, !all_selected); } /*************************************************************************/ diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index b6624a8cfa..0fefa0f3c4 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -282,7 +282,8 @@ bool ResourceImporterScene::get_option_visibility(const String &p_path, const St } } - if (p_option == "meshes/lightmap_texel_size" && int(p_options["meshes/light_baking"]) < 3) { + if (p_option == "meshes/lightmap_texel_size" && int(p_options["meshes/light_baking"]) != 2) { + // Only display the lightmap texel size import option when using the Static Lightmaps light baking mode. return false; } @@ -1476,7 +1477,7 @@ void ResourceImporterScene::get_import_options(const String &p_path, List<Import r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/ensure_tangents"), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/generate_lods"), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/create_shadow_meshes"), true)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "meshes/light_baking", PROPERTY_HINT_ENUM, "Disabled,Dynamic,Static,Static Lightmaps", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 2)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "meshes/light_baking", PROPERTY_HINT_ENUM, "Disabled,Static (VoxelGI/SDFGI),Static Lightmaps (VoxelGI/SDFGI/LightmapGI),Dynamic (VoxelGI only)", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 1)); r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "meshes/lightmap_texel_size", PROPERTY_HINT_RANGE, "0.001,100,0.001"), 0.1)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "skins/use_named_skins"), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/import"), true)); @@ -1660,7 +1661,7 @@ void ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_m } break; case LIGHT_BAKE_STATIC: case LIGHT_BAKE_STATIC_LIGHTMAPS: { - mesh_node->set_gi_mode(GeometryInstance3D::GI_MODE_BAKED); + mesh_node->set_gi_mode(GeometryInstance3D::GI_MODE_STATIC); } break; } @@ -1776,7 +1777,8 @@ void ResourceImporterScene::_optimize_track_usage(AnimationPlayer *p_player, Ani if (bone_idx == -1) { continue; } - skel->get_bone_pose(bone_idx); + // Note that this is using get_bone_pose to update the bone pose cache. + _ALLOW_DISCARD_ skel->get_bone_pose(bone_idx); loc = skel->get_bone_pose_position(bone_idx); rot = skel->get_bone_pose_rotation(bone_idx); scale = skel->get_bone_pose_scale(bone_idx); diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index 066e8b603b..13b55b5754 100644 --- a/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h @@ -159,9 +159,9 @@ class ResourceImporterScene : public ResourceImporter { enum LightBakeMode { LIGHT_BAKE_DISABLED, - LIGHT_BAKE_DYNAMIC, LIGHT_BAKE_STATIC, - LIGHT_BAKE_STATIC_LIGHTMAPS + LIGHT_BAKE_STATIC_LIGHTMAPS, + LIGHT_BAKE_DYNAMIC, }; enum MeshPhysicsMode { diff --git a/editor/import_dock.cpp b/editor/import_dock.cpp index 10654cfe43..419688fd9f 100644 --- a/editor/import_dock.cpp +++ b/editor/import_dock.cpp @@ -91,6 +91,8 @@ public: } }; +ImportDock *ImportDock::singleton = nullptr; + void ImportDock::set_edit_path(const String &p_path) { Ref<ConfigFile> config; config.instantiate(); @@ -606,6 +608,7 @@ void ImportDock::initialize_import_options() const { } ImportDock::ImportDock() { + singleton = this; set_name("Import"); content = memnew(VBoxContainer); @@ -687,5 +690,6 @@ ImportDock::ImportDock() { } ImportDock::~ImportDock() { + singleton = nullptr; memdelete(params); } diff --git a/editor/import_dock.h b/editor/import_dock.h index 33fc23f1b4..c5cdc4ac40 100644 --- a/editor/import_dock.h +++ b/editor/import_dock.h @@ -85,6 +85,12 @@ class ImportDock : public VBoxContainer { ITEM_CLEAR_DEFAULT, }; +private: + static ImportDock *singleton; + +public: + static ImportDock *get_singleton() { return singleton; } + protected: static void _bind_methods(); void _notification(int p_what); diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp index f56e868286..e36c86fb10 100644 --- a/editor/inspector_dock.cpp +++ b/editor/inspector_dock.cpp @@ -33,6 +33,8 @@ #include "editor/editor_scale.h" #include "editor/plugins/animation_player_editor_plugin.h" +InspectorDock *InspectorDock::singleton = nullptr; + void InspectorDock::_menu_option(int p_option) { _menu_option_confirm(p_option, false); } @@ -108,7 +110,7 @@ void InspectorDock::_menu_option_confirm(int p_option, bool p_confirmed) { Variant v = current->get(E->get().name); REF ref = v; RES res = ref; - if (v.is_ref() && ref.is_valid() && res.is_valid()) { + if (v.is_ref_counted() && ref.is_valid() && res.is_valid()) { // Valid resource which would be duplicated if action is confirmed. resource_propnames.append(E->get().name); } @@ -145,7 +147,7 @@ void InspectorDock::_menu_option_confirm(int p_option, bool p_confirmed) { } Variant v = current->get(prop_info.name); - if (v.is_ref()) { + if (v.is_ref_counted()) { REF ref = v; if (ref.is_valid()) { RES res = ref; @@ -156,7 +158,7 @@ void InspectorDock::_menu_option_confirm(int p_option, bool p_confirmed) { res = duplicates[res]; current->set(prop_info.name, res); - editor->get_inspector()->update_property(prop_info.name); + get_inspector_singleton()->update_property(prop_info.name); } } } @@ -382,20 +384,6 @@ void InspectorDock::_menu_expandall() { inspector->expand_all_folding(); } -void InspectorDock::_property_keyed(const String &p_keyed, const Variant &p_value, bool p_advance) { - AnimationPlayerEditor::get_singleton()->get_track_editor()->insert_value_key(p_keyed, p_value, p_advance); -} - -void InspectorDock::_transform_keyed(Object *sp, const String &p_sub, const Transform3D &p_key) { - Node3D *s = Object::cast_to<Node3D>(sp); - if (!s) { - return; - } - AnimationPlayerEditor::get_singleton()->get_track_editor()->insert_transform_key(s, p_sub, Animation::TYPE_POSITION_3D, p_key.origin); - AnimationPlayerEditor::get_singleton()->get_track_editor()->insert_transform_key(s, p_sub, Animation::TYPE_ROTATION_3D, p_key.basis.get_rotation_quaternion()); - AnimationPlayerEditor::get_singleton()->get_track_editor()->insert_transform_key(s, p_sub, Animation::TYPE_SCALE_3D, p_key.basis.get_scale()); -} - void InspectorDock::_warning_pressed() { warning_dialog->popup_centered(); } @@ -440,9 +428,6 @@ void InspectorDock::_notification(int p_what) { } void InspectorDock::_bind_methods() { - ClassDB::bind_method("update_keying", &InspectorDock::update_keying); - ClassDB::bind_method("_transform_keyed", &InspectorDock::_transform_keyed); // Still used by some connect_compat. - ClassDB::bind_method("_unref_resource", &InspectorDock::_unref_resource); ClassDB::bind_method("_paste_resource", &InspectorDock::_paste_resource); ClassDB::bind_method("_copy_resource", &InspectorDock::_copy_resource); @@ -547,23 +532,8 @@ void InspectorDock::go_back() { _edit_back(); } -void InspectorDock::update_keying() { - bool valid = false; - - if (AnimationPlayerEditor::get_singleton()->get_track_editor()->has_keying()) { - EditorHistory *editor_history = EditorNode::get_singleton()->get_editor_history(); - if (editor_history->get_path_size() >= 1) { - Object *obj = ObjectDB::get_instance(editor_history->get_path_object(0)); - if (Object::cast_to<Node>(obj)) { - valid = true; - } - } - } - - inspector->set_keying(valid); -} - InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) { + singleton = this; set_name("Inspector"); editor = p_editor; @@ -716,8 +686,8 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) { inspector->set_use_filter(true); // TODO: check me inspector->connect("resource_selected", callable_mp(this, &InspectorDock::_resource_selected)); - inspector->connect("property_keyed", callable_mp(this, &InspectorDock::_property_keyed)); } InspectorDock::~InspectorDock() { + singleton = nullptr; } diff --git a/editor/inspector_dock.h b/editor/inspector_dock.h index 94e4f67348..9dd3fa2070 100644 --- a/editor/inspector_dock.h +++ b/editor/inspector_dock.h @@ -117,8 +117,12 @@ class InspectorDock : public VBoxContainer { void _select_history(int p_idx); void _prepare_history(); - void _property_keyed(const String &p_keyed, const Variant &p_value, bool p_advance); - void _transform_keyed(Object *sp, const String &p_sub, const Transform3D &p_key); +private: + static InspectorDock *singleton; + +public: + static InspectorDock *get_singleton() { return singleton; } + static EditorInspector *get_inspector_singleton() { return singleton->inspector; } protected: static void _bind_methods(); @@ -126,7 +130,6 @@ protected: public: void go_back(); - void update_keying(); void edit_resource(const Ref<Resource> &p_resource); void open_resource(const String &p_type); void clear(); diff --git a/editor/multi_node_edit.cpp b/editor/multi_node_edit.cpp index 59fc473d73..c61380684a 100644 --- a/editor/multi_node_edit.cpp +++ b/editor/multi_node_edit.cpp @@ -87,8 +87,8 @@ bool MultiNodeEdit::_set_impl(const StringName &p_name, const Variant &p_value, ur->add_undo_property(n, name, n->get(name)); } - ur->add_do_method(EditorNode::get_singleton()->get_inspector(), "refresh"); - ur->add_undo_method(EditorNode::get_singleton()->get_inspector(), "refresh"); + ur->add_do_method(InspectorDock::get_inspector_singleton(), "refresh"); + ur->add_undo_method(InspectorDock::get_inspector_singleton(), "refresh"); ur->commit_action(); return true; diff --git a/editor/node_dock.cpp b/editor/node_dock.cpp index d8f16b367a..1246ebe0dd 100644 --- a/editor/node_dock.cpp +++ b/editor/node_dock.cpp @@ -134,3 +134,7 @@ NodeDock::NodeDock() { select_a_node->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART); add_child(select_a_node); } + +NodeDock::~NodeDock() { + singleton = nullptr; +} diff --git a/editor/node_dock.h b/editor/node_dock.h index b35be8de8a..4c814ab65f 100644 --- a/editor/node_dock.h +++ b/editor/node_dock.h @@ -48,13 +48,17 @@ class NodeDock : public VBoxContainer { Label *select_a_node; +private: + static NodeDock *singleton; + +public: + static NodeDock *get_singleton() { return singleton; } + protected: static void _bind_methods(); void _notification(int p_what); public: - static NodeDock *singleton; - void set_node(Node *p_node); void show_groups(); @@ -63,6 +67,7 @@ public: void update_lists(); NodeDock(); + ~NodeDock(); }; #endif // NODE_DOCK_H diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp index 71db40a829..e46c81b77e 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.cpp +++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp @@ -40,6 +40,7 @@ #include "scene/gui/menu_button.h" #include "scene/gui/panel.h" #include "scene/gui/progress_bar.h" +#include "scene/gui/view_panner.h" #include "scene/main/window.h" void AnimationNodeBlendTreeEditor::add_custom_type(const String &p_name, const Ref<Script> &p_script) { @@ -733,7 +734,8 @@ void AnimationNodeBlendTreeEditor::_removed_from_graph() { void AnimationNodeBlendTreeEditor::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE || p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { - graph->set_panning_scheme((GraphEdit::PanningScheme)EDITOR_GET("interface/editors/sub_editor_panning_scheme").operator int()); + graph->get_panner()->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/sub_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning"))); + graph->set_warped_panning(bool(EditorSettings::get_singleton()->get("editors/panning/warped_mouse_panning"))); } if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { @@ -896,6 +898,9 @@ void AnimationNodeBlendTreeEditor::_node_renamed(const String &p_text, Ref<Anima } void AnimationNodeBlendTreeEditor::_node_renamed_focus_out(Node *le, Ref<AnimationNode> p_node) { + if (le == nullptr) { + return; // The text_submitted signal triggered the graph update and freed the LineEdit. + } _node_renamed(le->call("get_text"), p_node); } diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index d7c0ba7540..83c2b53241 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -301,7 +301,6 @@ void AnimationPlayerEditor::_animation_selected(int p_which) { autoplay->set_pressed(current == player->get_autoplay()); AnimationPlayerEditor::get_singleton()->get_track_editor()->update_keying(); - EditorNode::get_singleton()->update_keying(); _animation_key_editor_seek(timeline_position, false); } @@ -829,7 +828,6 @@ void AnimationPlayerEditor::_update_player() { if (!player) { AnimationPlayerEditor::get_singleton()->get_track_editor()->update_keying(); - EditorNode::get_singleton()->update_keying(); return; } @@ -1507,7 +1505,7 @@ void AnimationPlayerEditor::_stop_onion_skinning() { } void AnimationPlayerEditor::_pin_pressed() { - EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor()->update_tree(); + SceneTreeDock::get_singleton()->get_tree_editor()->update_tree(); } void AnimationPlayerEditor::_bind_methods() { @@ -1795,11 +1793,39 @@ AnimationPlayerEditor::~AnimationPlayerEditor() { void AnimationPlayerEditorPlugin::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { + Node3DEditor::get_singleton()->connect("transform_key_request", callable_mp(this, &AnimationPlayerEditorPlugin::_transform_key_request)); + InspectorDock::get_inspector_singleton()->connect("property_keyed", callable_mp(this, &AnimationPlayerEditorPlugin::_property_keyed)); + anim_editor->get_track_editor()->connect("keying_changed", callable_mp(this, &AnimationPlayerEditorPlugin::_update_keying)); + InspectorDock::get_inspector_singleton()->connect("edited_object_changed", callable_mp(anim_editor->get_track_editor(), &AnimationTrackEditor::update_keying)); set_force_draw_over_forwarding_enabled(); } break; } } +void AnimationPlayerEditorPlugin::_property_keyed(const String &p_keyed, const Variant &p_value, bool p_advance) { + if (!anim_editor->get_track_editor()->has_keying()) { + return; + } + anim_editor->get_track_editor()->insert_value_key(p_keyed, p_value, p_advance); +} + +void AnimationPlayerEditorPlugin::_transform_key_request(Object *sp, const String &p_sub, const Transform3D &p_key) { + if (!anim_editor->get_track_editor()->has_keying()) { + return; + } + Node3D *s = Object::cast_to<Node3D>(sp); + if (!s) { + return; + } + anim_editor->get_track_editor()->insert_transform_key(s, p_sub, Animation::TYPE_POSITION_3D, p_key.origin); + anim_editor->get_track_editor()->insert_transform_key(s, p_sub, Animation::TYPE_ROTATION_3D, p_key.basis.get_rotation_quaternion()); + anim_editor->get_track_editor()->insert_transform_key(s, p_sub, Animation::TYPE_SCALE_3D, p_key.basis.get_scale()); +} + +void AnimationPlayerEditorPlugin::_update_keying() { + InspectorDock::get_inspector_singleton()->set_keying(anim_editor->get_track_editor()->has_keying()); +} + void AnimationPlayerEditorPlugin::edit(Object *p_object) { anim_editor->set_undo_redo(&get_undo_redo()); if (!p_object) { diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h index 626d31f439..06dca11aff 100644 --- a/editor/plugins/animation_player_editor_plugin.h +++ b/editor/plugins/animation_player_editor_plugin.h @@ -255,6 +255,10 @@ class AnimationPlayerEditorPlugin : public EditorPlugin { protected: void _notification(int p_what); + void _property_keyed(const String &p_keyed, const Variant &p_value, bool p_advance); + void _transform_key_request(Object *sp, const String &p_sub, const Transform3D &p_key); + void _update_keying(); + public: virtual Dictionary get_state() const override { return anim_editor->get_state(); } virtual void set_state(const Dictionary &p_state) override { anim_editor->set_state(p_state); } diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp index 5fb3040b75..7199f69f0b 100644 --- a/editor/plugins/asset_library_editor_plugin.cpp +++ b/editor/plugins/asset_library_editor_plugin.cpp @@ -374,7 +374,7 @@ void EditorAssetLibraryItemDownload::_http_download_completed(int p_status, int } install_button->set_disabled(false); - status->set_text(TTR("Success!")); + status->set_text(TTR("Ready to install!")); // Make the progress bar invisible but don't reflow other Controls around it. progress->set_modulate(Color(0, 0, 0, 0)); @@ -462,6 +462,10 @@ void EditorAssetLibraryItemDownload::_close() { queue_delete(); } +bool EditorAssetLibraryItemDownload::can_install() const { + return !install_button->is_disabled(); +} + void EditorAssetLibraryItemDownload::install() { String file = download->get_download_file(); @@ -608,6 +612,7 @@ void EditorAssetLibrary::_notification(int p_what) { } break; case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { _update_repository_options(); + setup_http_request(request); } break; } } @@ -1265,9 +1270,16 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const EditorAssetLibraryItemDownload *download_item = _get_asset_in_progress(description->get_asset_id()); if (download_item) { - description->get_ok_button()->set_text(TTR("Install")); + if (download_item->can_install()) { + description->get_ok_button()->set_text(TTR("Install")); + description->get_ok_button()->set_disabled(false); + } else { + description->get_ok_button()->set_text(TTR("Downloading...")); + description->get_ok_button()->set_disabled(true); + } } else { description->get_ok_button()->set_text(TTR("Download")); + description->get_ok_button()->set_disabled(false); } if (r.has("icon_url") && !r["icon_url"].operator String().is_empty()) { diff --git a/editor/plugins/asset_library_editor_plugin.h b/editor/plugins/asset_library_editor_plugin.h index 058aafc221..29d26411f3 100644 --- a/editor/plugins/asset_library_editor_plugin.h +++ b/editor/plugins/asset_library_editor_plugin.h @@ -164,7 +164,10 @@ public: void set_external_install(bool p_enable) { external_install = p_enable; } int get_asset_id() { return asset_id; } void configure(const String &p_title, int p_asset_id, const Ref<Texture2D> &p_preview, const String &p_download_url, const String &p_sha256_hash); + + bool can_install() const; void install(); + EditorAssetLibraryItemDownload(); }; diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 14f488f096..1aae82f66f 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -51,6 +51,7 @@ #include "scene/gui/grid_container.h" #include "scene/gui/nine_patch_rect.h" #include "scene/gui/subviewport_container.h" +#include "scene/gui/view_panner.h" #include "scene/main/canvas_layer.h" #include "scene/main/window.h" #include "scene/resources/packed_scene.h" @@ -882,9 +883,9 @@ void CanvasItemEditor::_selection_menu_hide() { void CanvasItemEditor::_add_node_pressed(int p_result) { if (p_result == AddNodeOption::ADD_NODE) { - editor->get_scene_tree_dock()->open_add_child_dialog(); + SceneTreeDock::get_singleton()->open_add_child_dialog(); } else if (p_result == AddNodeOption::ADD_INSTANCE) { - editor->get_scene_tree_dock()->open_instance_child_dialog(); + SceneTreeDock::get_singleton()->open_instance_child_dialog(); } } @@ -1116,77 +1117,15 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve } bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event, bool p_already_accepted) { - Ref<InputEventMouseButton> b = p_event; - if (b.is_valid() && !p_already_accepted) { - const bool pan_on_scroll = bool(EditorSettings::get_singleton()->get("editors/2d/scroll_to_pan")) && !b->is_ctrl_pressed(); - - if (pan_on_scroll) { - // Perform horizontal scrolling first so we can check for Shift being held. - if (b->is_pressed() && - (b->get_button_index() == MouseButton::WHEEL_LEFT || (b->is_shift_pressed() && b->get_button_index() == MouseButton::WHEEL_UP))) { - // Pan left - view_offset.x -= int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor(); - update_viewport(); - return true; - } - - if (b->is_pressed() && - (b->get_button_index() == MouseButton::WHEEL_RIGHT || (b->is_shift_pressed() && b->get_button_index() == MouseButton::WHEEL_DOWN))) { - // Pan right - view_offset.x += int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor(); - update_viewport(); - return true; - } - } - - if (b->is_pressed() && b->get_button_index() == MouseButton::WHEEL_DOWN) { - // Scroll or pan down - if (pan_on_scroll) { - view_offset.y += int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor(); - update_viewport(); - } else { - zoom_widget->set_zoom_by_increments(-1, Input::get_singleton()->is_key_pressed(Key::ALT)); - if (!Math::is_equal_approx(b->get_factor(), 1.0f)) { - // Handle high-precision (analog) scrolling. - zoom_widget->set_zoom(zoom * ((zoom_widget->get_zoom() / zoom - 1.f) * b->get_factor() + 1.f)); - } - _zoom_on_position(zoom_widget->get_zoom(), b->get_position()); - } - return true; - } - - if (b->is_pressed() && b->get_button_index() == MouseButton::WHEEL_UP) { - // Scroll or pan up - if (pan_on_scroll) { - view_offset.y -= int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor(); - update_viewport(); - } else { - zoom_widget->set_zoom_by_increments(1, Input::get_singleton()->is_key_pressed(Key::ALT)); - if (!Math::is_equal_approx(b->get_factor(), 1.0f)) { - // Handle high-precision (analog) scrolling. - zoom_widget->set_zoom(zoom * ((zoom_widget->get_zoom() / zoom - 1.f) * b->get_factor() + 1.f)); - } - _zoom_on_position(zoom_widget->get_zoom(), b->get_position()); - } - return true; - } - - if (!panning) { - if (b->is_pressed() && - (b->get_button_index() == MouseButton::MIDDLE || - (b->get_button_index() == MouseButton::LEFT && tool == TOOL_PAN) || - (b->get_button_index() == MouseButton::LEFT && !EditorSettings::get_singleton()->get("editors/2d/simple_panning") && pan_pressed))) { - // Pan the viewport - panning = true; - } - } + panner->set_force_drag(tool == TOOL_PAN); + bool panner_active = panner->gui_input(p_event, warped_panning ? viewport->get_global_rect() : Rect2()); + if (panner->is_panning() != pan_pressed) { + pan_pressed = panner->is_panning(); + _update_cursor(); + } - if (panning) { - if (!b->is_pressed() && (pan_on_scroll || (b->get_button_index() != MouseButton::WHEEL_DOWN && b->get_button_index() != MouseButton::WHEEL_UP))) { - // Stop panning the viewport (for any mouse button press except zooming) - panning = false; - } - } + if (panner_active) { + return true; } Ref<InputEventKey> k = p_event; @@ -1214,44 +1153,6 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event, bo _update_zoom(16.0 * MAX(1, EDSCALE)); } } - - bool is_pan_key = pan_view_shortcut.is_valid() && pan_view_shortcut->matches_event(p_event); - - if (is_pan_key && (EditorSettings::get_singleton()->get("editors/2d/simple_panning") || drag_type != DRAG_NONE)) { - if (!panning) { - if (k->is_pressed() && !k->is_echo()) { - //Pan the viewport - panning = true; - } - } else { - if (!k->is_pressed()) { - // Stop panning the viewport (for any mouse button press) - panning = false; - } - } - } - - if (is_pan_key && pan_pressed != k->is_pressed()) { - pan_pressed = k->is_pressed(); - _update_cursor(); - } - } - - Ref<InputEventMouseMotion> m = p_event; - if (m.is_valid()) { - if (panning) { - // Pan the viewport - Point2i relative; - if (bool(EditorSettings::get_singleton()->get("editors/2d/warped_mouse_panning"))) { - relative = Input::get_singleton()->warp_mouse_motion(m, viewport->get_global_rect()); - } else { - relative = m->get_relative(); - } - view_offset.x -= relative.x / zoom; - view_offset.y -= relative.y / zoom; - update_viewport(); - return true; - } } Ref<InputEventMagnifyGesture> magnify_gesture = p_event; @@ -1277,7 +1178,7 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event, bo } // Pan gesture - const Vector2 delta = (int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom) * pan_gesture->get_delta(); + const Vector2 delta = (pan_speed / zoom) * pan_gesture->get_delta(); view_offset.x += delta.x; view_offset.y += delta.y; update_viewport(); @@ -1287,6 +1188,25 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event, bo return false; } +void CanvasItemEditor::_scroll_callback(Vector2 p_scroll_vec, bool p_alt) { + _pan_callback(-p_scroll_vec * pan_speed); +} + +void CanvasItemEditor::_pan_callback(Vector2 p_scroll_vec) { + view_offset.x -= p_scroll_vec.x / zoom; + view_offset.y -= p_scroll_vec.y / zoom; + update_viewport(); +} + +void CanvasItemEditor::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin, bool p_alt) { + zoom_widget->set_zoom_by_increments(-1, p_alt); + if (!Math::is_equal_approx(p_scroll_vec.y, (real_t)1.0)) { + // Handle high-precision (analog) scrolling. + zoom_widget->set_zoom(zoom * ((zoom_widget->get_zoom() / zoom - 1.f) * p_scroll_vec.y + 1.f)); + } + _zoom_on_position(zoom_widget->get_zoom(), p_origin); +} + bool CanvasItemEditor::_gui_input_pivot(const Ref<InputEvent> &p_event) { Ref<InputEventMouseMotion> m = p_event; Ref<InputEventMouseButton> b = p_event; @@ -2281,7 +2201,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { return true; } - if (b.is_valid() && b->get_button_index() == MouseButton::LEFT && b->is_pressed() && tool == TOOL_SELECT) { + if (b.is_valid() && b->get_button_index() == MouseButton::LEFT && b->is_pressed() && tool == TOOL_SELECT && !panner->is_panning()) { // Single item selection Point2 click = transform.affine_inverse().xform(b->get_position()); @@ -2498,31 +2418,34 @@ bool CanvasItemEditor::_gui_input_hover(const Ref<InputEvent> &p_event) { void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) { bool accepted = false; - if (EditorSettings::get_singleton()->get("editors/2d/simple_panning") || !pan_pressed) { + Ref<InputEventMouseButton> mb = p_event; + bool release_lmb = (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT); // Required to properly release some stuff (e.g. selection box) while panning. + + if (EditorSettings::get_singleton()->get("editors/panning/simple_panning") || !pan_pressed || release_lmb) { if ((accepted = _gui_input_rulers_and_guides(p_event))) { - //printf("Rulers and guides\n"); + // print_line("Rulers and guides"); } else if ((accepted = editor->get_editor_plugins_over()->forward_gui_input(p_event))) { - //printf("Plugin\n"); + // print_line("Plugin"); } else if ((accepted = _gui_input_open_scene_on_double_click(p_event))) { - //printf("Open scene on double click\n"); + // print_line("Open scene on double click"); } else if ((accepted = _gui_input_scale(p_event))) { - //printf("Set scale\n"); + // print_line("Set scale"); } else if ((accepted = _gui_input_pivot(p_event))) { - //printf("Set pivot\n"); + // print_line("Set pivot"); } else if ((accepted = _gui_input_resize(p_event))) { - //printf("Resize\n"); + // print_line("Resize"); } else if ((accepted = _gui_input_rotate(p_event))) { - //printf("Rotate\n"); + // print_line("Rotate"); } else if ((accepted = _gui_input_move(p_event))) { - //printf("Move\n"); + // print_line("Move"); } else if ((accepted = _gui_input_anchors(p_event))) { - //printf("Anchors\n"); + // print_line("Anchors"); } else if ((accepted = _gui_input_select(p_event))) { - //printf("Selection\n"); + // print_line("Selection"); } else if ((accepted = _gui_input_ruler_tool(p_event))) { - //printf("Measure\n"); + // print_line("Measure"); } else { - //printf("Not accepted\n"); + // print_line("Not accepted"); } } @@ -3935,6 +3858,10 @@ void CanvasItemEditor::_notification(int p_what) { anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignWide"), SNAME("EditorIcons")), TTR("Full Rect"), ANCHORS_PRESET_WIDE); anchor_mode_button->set_icon(get_theme_icon(SNAME("Anchor"), SNAME("EditorIcons"))); + + panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/2d_editor_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning"))); + pan_speed = int(EditorSettings::get_singleton()->get("editors/panning/2d_editor_pan_speed")); + warped_panning = bool(EditorSettings::get_singleton()->get("editors/panning/warped_mouse_panning")); } if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { @@ -5205,7 +5132,6 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { dragged_guide_index = -1; is_hovering_h_guide = false; is_hovering_v_guide = false; - panning = false; pan_pressed = false; ruler_tool_active = false; @@ -5221,8 +5147,8 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { editor_selection->connect("selection_changed", callable_mp((CanvasItem *)this, &CanvasItem::update)); editor_selection->connect("selection_changed", callable_mp(this, &CanvasItemEditor::_selection_changed)); - editor->get_scene_tree_dock()->connect("node_created", callable_mp(this, &CanvasItemEditor::_node_created)); - editor->get_scene_tree_dock()->connect("add_node_used", callable_mp(this, &CanvasItemEditor::_reset_create_position)); + SceneTreeDock::get_singleton()->connect("node_created", callable_mp(this, &CanvasItemEditor::_node_created)); + SceneTreeDock::get_singleton()->connect("add_node_used", callable_mp(this, &CanvasItemEditor::_reset_create_position)); editor->call_deferred(SNAME("connect"), "play_pressed", Callable(this, "_update_override_camera_button"), make_binds(true)); editor->call_deferred(SNAME("connect"), "stop_pressed", Callable(this, "_update_override_camera_button"), make_binds(false)); @@ -5260,6 +5186,9 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { controls_vb = memnew(VBoxContainer); controls_vb->set_begin(Point2(5, 5)); + panner.instantiate(); + panner->set_callbacks(callable_mp(this, &CanvasItemEditor::_scroll_callback), callable_mp(this, &CanvasItemEditor::_pan_callback), callable_mp(this, &CanvasItemEditor::_zoom_callback)); + viewport = memnew(CanvasItemEditorViewport(p_editor, this)); viewport_scrollable->add_child(viewport); viewport->set_mouse_filter(MOUSE_FILTER_PASS); @@ -5268,6 +5197,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { viewport->set_focus_mode(FOCUS_ALL); viewport->connect("draw", callable_mp(this, &CanvasItemEditor::_draw_viewport)); viewport->connect("gui_input", callable_mp(this, &CanvasItemEditor::_gui_input_viewport)); + viewport->connect("focus_exited", callable_mp(panner.ptr(), &ViewPanner::release_pan_key)); h_scroll = memnew(HScrollBar); viewport->add_child(h_scroll); @@ -5618,13 +5548,12 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { add_node_menu = memnew(PopupMenu); add_child(add_node_menu); - add_node_menu->add_icon_item(editor->get_scene_tree_dock()->get_theme_icon(SNAME("Add"), SNAME("EditorIcons")), TTR("Add Node Here")); - add_node_menu->add_icon_item(editor->get_scene_tree_dock()->get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")), TTR("Instance Scene Here")); + add_node_menu->add_icon_item(SceneTreeDock::get_singleton()->get_theme_icon(SNAME("Add"), SNAME("EditorIcons")), TTR("Add Node Here")); + add_node_menu->add_icon_item(SceneTreeDock::get_singleton()->get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")), TTR("Instance Scene Here")); add_node_menu->connect("id_pressed", callable_mp(this, &CanvasItemEditor::_add_node_pressed)); multiply_grid_step_shortcut = ED_SHORTCUT("canvas_item_editor/multiply_grid_step", TTR("Multiply grid step by 2"), Key::KP_MULTIPLY); divide_grid_step_shortcut = ED_SHORTCUT("canvas_item_editor/divide_grid_step", TTR("Divide grid step by 2"), Key::KP_DIVIDE); - pan_view_shortcut = ED_SHORTCUT("canvas_item_editor/pan_view", TTR("Pan View"), Key::SPACE); skeleton_menu->get_popup()->set_item_checked(skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES), true); singleton = this; @@ -6130,7 +6059,7 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte target_node = nullptr; editor = p_node; - editor_data = editor->get_scene_tree_dock()->get_editor_data(); + editor_data = SceneTreeDock::get_singleton()->get_editor_data(); canvas_item_editor = p_canvas_item_editor; preview_node = memnew(Control); diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index d58fb17356..1e8fc0670d 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -42,6 +42,7 @@ #include "scene/main/canvas_item.h" class CanvasItemEditorViewport; +class ViewPanner; class CanvasItemEditorSelectedItem : public Object { GDCLASS(CanvasItemEditorSelectedItem, Object); @@ -276,7 +277,6 @@ private: bool key_pos; bool key_rot; bool key_scale; - bool panning; bool pan_pressed; bool ruler_tool_active; @@ -402,7 +402,13 @@ private: Ref<Shortcut> set_pivot_shortcut; Ref<Shortcut> multiply_grid_step_shortcut; Ref<Shortcut> divide_grid_step_shortcut; - Ref<Shortcut> pan_view_shortcut; + + Ref<ViewPanner> panner; + bool warped_panning = true; + int pan_speed = 20; + void _scroll_callback(Vector2 p_scroll_vec, bool p_alt); + void _pan_callback(Vector2 p_scroll_vec); + void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin, bool p_alt); bool _is_node_locked(const Node *p_node); bool _is_node_movable(const Node *p_node, bool p_popup_warning = false); diff --git a/editor/plugins/gpu_particles_2d_editor_plugin.cpp b/editor/plugins/gpu_particles_2d_editor_plugin.cpp index 6b93a1872d..06be9d678f 100644 --- a/editor/plugins/gpu_particles_2d_editor_plugin.cpp +++ b/editor/plugins/gpu_particles_2d_editor_plugin.cpp @@ -110,9 +110,9 @@ void GPUParticles2DEditorPlugin::_menu_callback(int p_idx) { UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); ur->create_action(TTR("Convert to CPUParticles2D")); - ur->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock(), "replace_node", particles, cpu_particles, true, false); + ur->add_do_method(SceneTreeDock::get_singleton(), "replace_node", particles, cpu_particles, true, false); ur->add_do_reference(cpu_particles); - ur->add_undo_method(EditorNode::get_singleton()->get_scene_tree_dock(), "replace_node", cpu_particles, particles, false, false); + ur->add_undo_method(SceneTreeDock::get_singleton(), "replace_node", cpu_particles, particles, false, false); ur->add_undo_reference(particles); ur->commit_action(); diff --git a/editor/plugins/gpu_particles_3d_editor_plugin.cpp b/editor/plugins/gpu_particles_3d_editor_plugin.cpp index 0057566603..087b0a26b7 100644 --- a/editor/plugins/gpu_particles_3d_editor_plugin.cpp +++ b/editor/plugins/gpu_particles_3d_editor_plugin.cpp @@ -269,9 +269,9 @@ void GPUParticles3DEditor::_menu_option(int p_option) { UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); ur->create_action(TTR("Convert to CPUParticles3D")); - ur->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock(), "replace_node", node, cpu_particles, true, false); + ur->add_do_method(SceneTreeDock::get_singleton(), "replace_node", node, cpu_particles, true, false); ur->add_do_reference(cpu_particles); - ur->add_undo_method(EditorNode::get_singleton()->get_scene_tree_dock(), "replace_node", cpu_particles, node, false, false); + ur->add_undo_method(SceneTreeDock::get_singleton(), "replace_node", cpu_particles, node, false, false); ur->add_undo_reference(node); ur->commit_action(); diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp index d82d0c6ffc..e47381b8a0 100644 --- a/editor/plugins/mesh_library_editor_plugin.cpp +++ b/editor/plugins/mesh_library_editor_plugin.cpp @@ -136,9 +136,11 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library, continue; } - //Transform3D shape_transform = sb->shape_owner_get_transform(E); - - //shape_transform.set_origin(shape_transform.get_origin() - phys_offset); + Transform3D shape_transform; + if (p_apply_xforms) { + shape_transform = mi->get_transform(); + } + shape_transform *= sb->get_transform() * sb->shape_owner_get_transform(E); for (int k = 0; k < sb->shape_owner_get_shape_count(E); k++) { Ref<Shape3D> collision = sb->shape_owner_get_shape(E, k); @@ -147,7 +149,7 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library, } MeshLibrary::ShapeData shape_data; shape_data.shape = collision; - shape_data.local_transform = sb->get_transform() * sb->shape_owner_get_transform(E); + shape_data.local_transform = shape_transform; collisions.push_back(shape_data); } } @@ -226,7 +228,7 @@ void MeshLibraryEditor::_menu_cbk(int p_option) { mesh_library->create_item(mesh_library->get_last_unused_item_id()); } break; case MENU_OPTION_REMOVE_ITEM: { - String p = editor->get_inspector()->get_selected_path(); + String p = InspectorDock::get_inspector_singleton()->get_selected_path(); if (p.begins_with("/MeshLibrary/item") && p.get_slice_count("/") >= 3) { to_erase = p.get_slice("/", 3).to_int(); cd_remove->set_text(vformat(TTR("Remove item %d?"), to_erase)); diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 20f86c6a81..9165223948 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -2733,7 +2733,7 @@ void Node3DEditorViewport::_notification(int p_what) { _update_freelook(delta); - Node *scene_root = editor->get_scene_tree_dock()->get_editor_data()->get_edited_scene_root(); + Node *scene_root = SceneTreeDock::get_singleton()->get_editor_data()->get_edited_scene_root(); if (previewing_cinema && scene_root != nullptr) { Camera3D *cam = scene_root->get_viewport()->get_camera_3d(); if (cam != nullptr && cam != previewing) { @@ -4284,7 +4284,7 @@ void Node3DEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p_ target_node = root_node; } else { // Create a root node so we can add child nodes to it. - EditorNode::get_singleton()->get_scene_tree_dock()->add_root_node(memnew(Node3D)); + SceneTreeDock::get_singleton()->add_root_node(memnew(Node3D)); target_node = get_tree()->get_edited_scene_root(); } } else { @@ -4311,7 +4311,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito index = p_index; editor = p_editor; - editor_data = editor->get_scene_tree_dock()->get_editor_data(); + editor_data = SceneTreeDock::get_singleton()->get_editor_data(); editor_selection = editor->get_editor_selection(); undo_redo = editor->get_undo_redo(); @@ -6704,7 +6704,7 @@ void Node3DEditor::_add_sun_to_scene(bool p_already_added_environment) { Node *base = get_tree()->get_edited_scene_root(); if (!base) { // Create a root node so we can add child nodes to it. - EditorNode::get_singleton()->get_scene_tree_dock()->add_root_node(memnew(Node3D)); + SceneTreeDock::get_singleton()->add_root_node(memnew(Node3D)); base = get_tree()->get_edited_scene_root(); } ERR_FAIL_COND(!base); @@ -6732,7 +6732,7 @@ void Node3DEditor::_add_environment_to_scene(bool p_already_added_sun) { Node *base = get_tree()->get_edited_scene_root(); if (!base) { // Create a root node so we can add child nodes to it. - EditorNode::get_singleton()->get_scene_tree_dock()->add_root_node(memnew(Node3D)); + SceneTreeDock::get_singleton()->add_root_node(memnew(Node3D)); base = get_tree()->get_edited_scene_root(); } ERR_FAIL_COND(!base); @@ -6790,7 +6790,7 @@ void Node3DEditor::_notification(int p_what) { get_tree()->connect("node_removed", callable_mp(this, &Node3DEditor::_node_removed)); get_tree()->connect("node_added", callable_mp(this, &Node3DEditor::_node_added)); - EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor()->connect("node_changed", callable_mp(this, &Node3DEditor::_refresh_menu_icons)); + SceneTreeDock::get_singleton()->get_tree_editor()->connect("node_changed", callable_mp(this, &Node3DEditor::_refresh_menu_icons)); editor_selection->connect("selection_changed", callable_mp(this, &Node3DEditor::_selection_changed)); editor->connect("stop_pressed", callable_mp(this, &Node3DEditor::_update_camera_override_button), make_binds(false)); @@ -8043,7 +8043,6 @@ Node3DEditorPlugin::Node3DEditorPlugin(EditorNode *p_node) { editor->get_main_control()->add_child(spatial_editor); spatial_editor->hide(); - spatial_editor->connect("transform_key_request", Callable(editor->get_inspector_dock(), "_transform_keyed")); } Node3DEditorPlugin::~Node3DEditorPlugin() { diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp index c6d1d99c08..7a96e6eced 100644 --- a/editor/plugins/polygon_2d_editor_plugin.cpp +++ b/editor/plugins/polygon_2d_editor_plugin.cpp @@ -66,7 +66,7 @@ void Polygon2DEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - uv_panner->set_control_scheme((ViewPanner::ControlScheme)EDITOR_GET("interface/editors/sub_editor_panning_scheme").operator int()); + uv_panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/sub_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning"))); } break; case NOTIFICATION_READY: { button_uv->set_icon(get_theme_icon(SNAME("Uv"), SNAME("EditorIcons"))); @@ -926,7 +926,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { } } -void Polygon2DEditor::_uv_scroll_callback(Vector2 p_scroll_vec) { +void Polygon2DEditor::_uv_scroll_callback(Vector2 p_scroll_vec, bool p_alt) { _uv_pan_callback(-p_scroll_vec * 32); } @@ -935,7 +935,7 @@ void Polygon2DEditor::_uv_pan_callback(Vector2 p_scroll_vec) { uv_vscroll->set_value(uv_vscroll->get_value() - p_scroll_vec.y); } -void Polygon2DEditor::_uv_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin) { +void Polygon2DEditor::_uv_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin, bool p_alt) { if (p_scroll_vec.y < 0) { uv_zoom->set_value(uv_zoom->get_value() / (1 - (0.1 * Math::abs(p_scroll_vec.y)))); } else { @@ -1280,10 +1280,6 @@ Polygon2DEditor::Polygon2DEditor(EditorNode *p_editor) : uv_edit_mode[2]->connect("pressed", callable_mp(this, &Polygon2DEditor::_uv_edit_mode_select), varray(2)); uv_edit_mode[3]->connect("pressed", callable_mp(this, &Polygon2DEditor::_uv_edit_mode_select), varray(3)); - uv_panner.instantiate(); - uv_panner->set_callbacks(callable_mp(this, &Polygon2DEditor::_uv_scroll_callback), callable_mp(this, &Polygon2DEditor::_uv_pan_callback), callable_mp(this, &Polygon2DEditor::_uv_zoom_callback)); - uv_panner->set_disable_rmb(true); - uv_mode_hb->add_child(memnew(VSeparator)); uv_main_vb->add_child(uv_mode_hb); @@ -1470,8 +1466,13 @@ Polygon2DEditor::Polygon2DEditor(EditorNode *p_editor) : bone_scroll_vb = memnew(VBoxContainer); bone_scroll->add_child(bone_scroll_vb); + uv_panner.instantiate(); + uv_panner->set_callbacks(callable_mp(this, &Polygon2DEditor::_uv_scroll_callback), callable_mp(this, &Polygon2DEditor::_uv_pan_callback), callable_mp(this, &Polygon2DEditor::_uv_zoom_callback)); + uv_edit_draw->connect("draw", callable_mp(this, &Polygon2DEditor::_uv_draw)); uv_edit_draw->connect("gui_input", callable_mp(this, &Polygon2DEditor::_uv_input)); + uv_edit_draw->connect("focus_exited", callable_mp(uv_panner.ptr(), &ViewPanner::release_pan_key)); + uv_edit_draw->set_focus_mode(FOCUS_CLICK); uv_draw_zoom = 1.0; point_drag_index = -1; uv_drag = false; diff --git a/editor/plugins/polygon_2d_editor_plugin.h b/editor/plugins/polygon_2d_editor_plugin.h index 959c230d7b..0f10b6b645 100644 --- a/editor/plugins/polygon_2d_editor_plugin.h +++ b/editor/plugins/polygon_2d_editor_plugin.h @@ -81,9 +81,9 @@ class Polygon2DEditor : public AbstractPolygon2DEditor { TextureRect *uv_icon_zoom; Ref<ViewPanner> uv_panner; - void _uv_scroll_callback(Vector2 p_scroll_vec); + void _uv_scroll_callback(Vector2 p_scroll_vec, bool p_alt); void _uv_pan_callback(Vector2 p_scroll_vec); - void _uv_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin); + void _uv_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin, bool p_alt); VBoxContainer *bone_scroll_main_vb; ScrollContainer *bone_scroll; diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index f1e5e7612b..2fc4cda861 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -677,6 +677,7 @@ void ScriptEditor::_update_recent_scripts() { recent_scripts->add_separator(); recent_scripts->add_shortcut(ED_SHORTCUT("script_editor/clear_recent", TTR("Clear Recent Files"))); + recent_scripts->set_item_disabled(recent_scripts->get_item_id(recent_scripts->get_item_count() - 1), rc.is_empty()); recent_scripts->set_as_minsize(); } @@ -1421,7 +1422,7 @@ void ScriptEditor::_menu_option(int p_option) { path = path.get_slice("::", 0); // Show the scene instead. } - FileSystemDock *file_system_dock = EditorNode::get_singleton()->get_filesystem_dock(); + FileSystemDock *file_system_dock = FileSystemDock::get_singleton(); file_system_dock->navigate_to_path(path); // Ensure that the FileSystem dock is visible. TabContainer *tab_container = (TabContainer *)file_system_dock->get_parent_control(); @@ -1540,6 +1541,51 @@ void ScriptEditor::_show_save_theme_as_dialog() { file_dialog->set_title(TTR("Save Theme As...")); } +bool ScriptEditor::_has_docs_tab() const { + const int child_count = tab_container->get_child_count(); + for (int i = 0; i < child_count; i++) { + if (Object::cast_to<EditorHelp>(tab_container->get_child(i))) { + return true; + } + } + return false; +} + +bool ScriptEditor::_has_script_tab() const { + const int child_count = tab_container->get_child_count(); + for (int i = 0; i < child_count; i++) { + if (Object::cast_to<ScriptEditorBase>(tab_container->get_child(i))) { + return true; + } + } + return false; +} + +void ScriptEditor::_prepare_file_menu() { + PopupMenu *menu = file_menu->get_popup(); + const bool current_is_doc = _get_current_editor() == nullptr; + + menu->set_item_disabled(menu->get_item_index(FILE_REOPEN_CLOSED), previous_scripts.is_empty()); + + menu->set_item_disabled(menu->get_item_index(FILE_SAVE), current_is_doc); + menu->set_item_disabled(menu->get_item_index(FILE_SAVE_AS), current_is_doc); + menu->set_item_disabled(menu->get_item_index(FILE_SAVE_ALL), !_has_script_tab()); + + menu->set_item_disabled(menu->get_item_index(FILE_TOOL_RELOAD_SOFT), current_is_doc); + menu->set_item_disabled(menu->get_item_index(FILE_COPY_PATH), current_is_doc); + menu->set_item_disabled(menu->get_item_index(SHOW_IN_FILE_SYSTEM), current_is_doc); + + menu->set_item_disabled(menu->get_item_index(WINDOW_PREV), history_pos <= 0); + menu->set_item_disabled(menu->get_item_index(WINDOW_NEXT), history_pos >= history.size() - 1); + + menu->set_item_disabled(menu->get_item_index(FILE_CLOSE), tab_container->get_child_count() < 1); + menu->set_item_disabled(menu->get_item_index(CLOSE_ALL), tab_container->get_child_count() < 1); + menu->set_item_disabled(menu->get_item_index(CLOSE_OTHER_TABS), tab_container->get_child_count() <= 1); + menu->set_item_disabled(menu->get_item_index(CLOSE_DOCS), !_has_docs_tab()); + + menu->set_item_disabled(menu->get_item_index(FILE_RUN), current_is_doc); +} + void ScriptEditor::_tab_changed(int p_which) { ensure_select_current(); } @@ -1551,8 +1597,8 @@ void ScriptEditor::_notification(int p_what) { editor->connect("script_add_function_request", callable_mp(this, &ScriptEditor::_add_callback)); editor->connect("resource_saved", callable_mp(this, &ScriptEditor::_res_saved_callback)); editor->connect("scene_saved", callable_mp(this, &ScriptEditor::_scene_saved_callback)); - editor->get_filesystem_dock()->connect("files_moved", callable_mp(this, &ScriptEditor::_files_moved)); - editor->get_filesystem_dock()->connect("file_removed", callable_mp(this, &ScriptEditor::_file_removed)); + FileSystemDock::get_singleton()->connect("files_moved", callable_mp(this, &ScriptEditor::_files_moved)); + FileSystemDock::get_singleton()->connect("file_removed", callable_mp(this, &ScriptEditor::_file_removed)); script_list->connect("item_selected", callable_mp(this, &ScriptEditor::_script_selected)); members_overview->connect("item_selected", callable_mp(this, &ScriptEditor::_members_overview_selected)); @@ -1595,7 +1641,7 @@ void ScriptEditor::_notification(int p_what) { case NOTIFICATION_READY: { get_tree()->connect("tree_changed", callable_mp(this, &ScriptEditor::_tree_changed)); - editor->get_inspector_dock()->connect("request_help", callable_mp(this, &ScriptEditor::_help_class_open)); + InspectorDock::get_singleton()->connect("request_help", callable_mp(this, &ScriptEditor::_help_class_open)); editor->connect("request_help_search", callable_mp(this, &ScriptEditor::_help_search)); } break; @@ -2122,8 +2168,6 @@ void ScriptEditor::_update_script_names() { _update_members_overview_visibility(); _update_help_overview_visibility(); _update_script_colors(); - - file_menu->get_popup()->set_item_disabled(file_menu->get_popup()->get_item_index(FILE_REOPEN_CLOSED), previous_scripts.is_empty()); } void ScriptEditor::_update_script_connections() { @@ -2347,7 +2391,7 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra // If we delete a script within the filesystem, the original resource path // is lost, so keep it as metadata to figure out the exact tab to delete. se->set_meta("_edit_res_path", p_resource->get_path()); - se->set_tooltip_request_func("_get_debug_tooltip", this); + se->set_tooltip_request_func(callable_mp(this, &ScriptEditor::_get_debug_tooltip)); if (se->get_edit_menu()) { se->get_edit_menu()->hide(); menu_hb->add_child(se->get_edit_menu()); @@ -2794,6 +2838,7 @@ Variant ScriptEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) { if (!preview_icon.is_null()) { TextureRect *tf = memnew(TextureRect); tf->set_texture(preview_icon); + tf->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED); drag_preview->add_child(tf); } Label *label = memnew(Label(preview_name)); @@ -3067,6 +3112,12 @@ void ScriptEditor::_make_script_list_context_menu() { context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/window_sort"), WINDOW_SORT); context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/toggle_scripts_panel"), TOGGLE_SCRIPTS_PANEL); + context_menu->set_item_disabled(context_menu->get_item_index(CLOSE_ALL), tab_container->get_child_count() <= 0); + context_menu->set_item_disabled(context_menu->get_item_index(CLOSE_OTHER_TABS), tab_container->get_child_count() <= 1); + context_menu->set_item_disabled(context_menu->get_item_index(WINDOW_MOVE_UP), tab_container->get_current_tab() <= 0); + context_menu->set_item_disabled(context_menu->get_item_index(WINDOW_MOVE_DOWN), tab_container->get_current_tab() >= tab_container->get_child_count() - 1); + context_menu->set_item_disabled(context_menu->get_item_index(WINDOW_SORT), tab_container->get_child_count() <= 1); + context_menu->set_position(get_screen_position() + get_local_mouse_position()); context_menu->reset_size(); context_menu->popup(); @@ -3455,7 +3506,7 @@ void ScriptEditor::register_create_script_editor_function(CreateScriptEditorFunc } void ScriptEditor::_script_changed() { - NodeDock::singleton->update_lists(); + NodeDock::get_singleton()->update_lists(); } void ScriptEditor::_on_find_in_files_requested(String text) { @@ -3547,7 +3598,6 @@ void ScriptEditor::_bind_methods() { ClassDB::bind_method("_goto_script_line2", &ScriptEditor::_goto_script_line2); ClassDB::bind_method("_copy_script_path", &ScriptEditor::_copy_script_path); - ClassDB::bind_method("_get_debug_tooltip", &ScriptEditor::_get_debug_tooltip); ClassDB::bind_method("_update_script_connections", &ScriptEditor::_update_script_connections); ClassDB::bind_method("_help_class_open", &ScriptEditor::_help_class_open); ClassDB::bind_method("_live_auto_reload_running_scripts", &ScriptEditor::_live_auto_reload_running_scripts); @@ -3690,7 +3740,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { ED_SHORTCUT("script_editor/next_script", TTR("Next Script"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::PERIOD); ED_SHORTCUT("script_editor/prev_script", TTR("Previous Script"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::COMMA); set_process_input(true); - set_process_unhandled_input(true); + set_process_unhandled_key_input(true); file_menu = memnew(MenuButton); file_menu->set_text(TTR("File")); @@ -3698,8 +3748,8 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { file_menu->set_shortcut_context(this); menu_hb->add_child(file_menu); - file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/new", TTR("New Script...")), FILE_NEW); - file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/new_textfile", TTR("New Text File...")), FILE_NEW_TEXTFILE); + file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/new", TTR("New Script..."), KeyModifierMask::CMD | Key::N), FILE_NEW); + file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/new_textfile", TTR("New Text File..."), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::N), FILE_NEW_TEXTFILE); file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/open", TTR("Open...")), FILE_OPEN); file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/reopen_closed_script", TTR("Reopen Closed Script"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::T), FILE_REOPEN_CLOSED); file_menu->get_popup()->add_submenu_item(TTR("Open Recent"), "RecentScripts", FILE_OPEN_RECENT); @@ -3749,6 +3799,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { file_menu->get_popup()->add_separator(); file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/toggle_scripts_panel", TTR("Toggle Scripts Panel"), KeyModifierMask::CMD | Key::BACKSLASH), TOGGLE_SCRIPTS_PANEL); file_menu->get_popup()->connect("id_pressed", callable_mp(this, &ScriptEditor::_menu_option)); + file_menu->get_popup()->connect("about_to_popup", callable_mp(this, &ScriptEditor::_prepare_file_menu)); script_search_menu = memnew(MenuButton); script_search_menu->set_text(TTR("Search")); diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h index ca409e15ca..67a6a9da02 100644 --- a/editor/plugins/script_editor_plugin.h +++ b/editor/plugins/script_editor_plugin.h @@ -165,7 +165,7 @@ public: virtual bool show_members_overview() = 0; - virtual void set_tooltip_request_func(String p_method, Object *p_obj) = 0; + virtual void set_tooltip_request_func(const Callable &p_toolip_callback) = 0; virtual Control *get_edit_menu() = 0; virtual void clear_edit_menu() = 0; virtual void set_find_replace_bar(FindReplaceBar *p_bar) = 0; @@ -315,6 +315,9 @@ class ScriptEditor : public PanelContainer { void _menu_option(int p_option); void _theme_option(int p_option); void _show_save_theme_as_dialog(); + bool _has_docs_tab() const; + bool _has_script_tab() const; + void _prepare_file_menu(); Tree *disk_changed_list; ConfirmationDialog *disk_changed; diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index ab094f4dc6..b765091d2b 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -1375,8 +1375,10 @@ void ScriptTextEditor::clear_breakpoints() { code_editor->get_text_editor()->clear_breakpointed_lines(); } -void ScriptTextEditor::set_tooltip_request_func(String p_method, Object *p_obj) { - code_editor->get_text_editor()->set_tooltip_request_func(p_obj, p_method, this); +void ScriptTextEditor::set_tooltip_request_func(const Callable &p_toolip_callback) { + Variant args[1] = { this }; + const Variant *argp[] = { &args[0] }; + code_editor->get_text_editor()->set_tooltip_request_func(p_toolip_callback.bind(argp, 1)); } void ScriptTextEditor::set_debugger_active(bool p_active) { diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h index 6e67444489..bc674ce964 100644 --- a/editor/plugins/script_text_editor.h +++ b/editor/plugins/script_text_editor.h @@ -233,7 +233,7 @@ public: virtual bool show_members_overview() override; - virtual void set_tooltip_request_func(String p_method, Object *p_obj) override; + virtual void set_tooltip_request_func(const Callable &p_toolip_callback) override; virtual void set_debugger_active(bool p_active) override; diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp index e1b27cb045..169ce29438 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.cpp +++ b/editor/plugins/skeleton_3d_editor_plugin.cpp @@ -149,6 +149,9 @@ void BoneTransformEditor::set_target(const String &p_prop) { void BoneTransformEditor::_property_keyed(const String &p_path, bool p_advance) { AnimationTrackEditor *te = AnimationPlayerEditor::get_singleton()->get_track_editor(); + if (!te->has_keying()) { + return; + } PackedStringArray split = p_path.split("/"); if (split.size() == 3 && split[0] == "bones") { int bone_idx = split[1].to_int(); diff --git a/editor/plugins/sprite_2d_editor_plugin.cpp b/editor/plugins/sprite_2d_editor_plugin.cpp index 1eac651ed6..85ff20dd23 100644 --- a/editor/plugins/sprite_2d_editor_plugin.cpp +++ b/editor/plugins/sprite_2d_editor_plugin.cpp @@ -337,9 +337,9 @@ void Sprite2DEditor::_convert_to_mesh_2d_node() { UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); ur->create_action(TTR("Convert to Mesh2D")); - ur->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock(), "replace_node", node, mesh_instance, true, false); + ur->add_do_method(SceneTreeDock::get_singleton(), "replace_node", node, mesh_instance, true, false); ur->add_do_reference(mesh_instance); - ur->add_undo_method(EditorNode::get_singleton()->get_scene_tree_dock(), "replace_node", mesh_instance, node, false, false); + ur->add_undo_method(SceneTreeDock::get_singleton(), "replace_node", mesh_instance, node, false, false); ur->add_undo_reference(node); ur->commit_action(); } @@ -395,9 +395,9 @@ void Sprite2DEditor::_convert_to_polygon_2d_node() { UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); ur->create_action(TTR("Convert to Polygon2D")); - ur->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock(), "replace_node", node, polygon_2d_instance, true, false); + ur->add_do_method(SceneTreeDock::get_singleton(), "replace_node", node, polygon_2d_instance, true, false); ur->add_do_reference(polygon_2d_instance); - ur->add_undo_method(EditorNode::get_singleton()->get_scene_tree_dock(), "replace_node", polygon_2d_instance, node, false, false); + ur->add_undo_method(SceneTreeDock::get_singleton(), "replace_node", polygon_2d_instance, node, false, false); ur->add_undo_reference(node); ur->commit_action(); } diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index 3350cec912..014fa0e7a5 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -821,19 +821,30 @@ void SpriteFramesEditor::_update_library(bool p_skip_selector) { for (int i = 0; i < frames->get_frame_count(edited_anim); i++) { String name; - Ref<Texture2D> icon; + Ref<Texture2D> frame = frames->get_frame(edited_anim, i); - if (frames->get_frame(edited_anim, i).is_null()) { + if (frame.is_null()) { name = itos(i) + ": " + TTR("(empty)"); - } else { - name = itos(i) + ": " + frames->get_frame(edited_anim, i)->get_name(); - icon = frames->get_frame(edited_anim, i); + name = itos(i) + ": " + frame->get_name(); } - tree->add_item(name, icon); - if (frames->get_frame(edited_anim, i).is_valid()) { - tree->set_item_tooltip(tree->get_item_count() - 1, frames->get_frame(edited_anim, i)->get_path()); + tree->add_item(name, frame); + if (frame.is_valid()) { + String tooltip = frame->get_path(); + + // Frame is often saved as an AtlasTexture subresource within a scene/resource file, + // thus its path might be not what the user is looking for. So we're also showing + // subsequent source texture paths. + String prefix = String::utf8("┖╴"); + Ref<AtlasTexture> at = frame; + while (at.is_valid() && at->get_atlas().is_valid()) { + tooltip += "\n" + prefix + at->get_atlas()->get_path(); + prefix = " " + prefix; + at = at->get_atlas(); + } + + tree->set_item_tooltip(tree->get_item_count() - 1, tooltip); } if (sel == i) { tree->select(tree->get_item_count() - 1); diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp index 12d13571f8..940f269803 100644 --- a/editor/plugins/text_editor.cpp +++ b/editor/plugins/text_editor.cpp @@ -272,8 +272,10 @@ void TextEditor::update_settings() { code_editor->update_editor_settings(); } -void TextEditor::set_tooltip_request_func(String p_method, Object *p_obj) { - code_editor->get_text_editor()->set_tooltip_request_func(p_obj, p_method, this); +void TextEditor::set_tooltip_request_func(const Callable &p_toolip_callback) { + Variant args[1] = { this }; + const Variant *argp[] = { &args[0] }; + code_editor->get_text_editor()->set_tooltip_request_func(p_toolip_callback.bind(argp, 1)); } Control *TextEditor::get_edit_menu() { diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h index d3fb0c0a16..d03385d79e 100644 --- a/editor/plugins/text_editor.h +++ b/editor/plugins/text_editor.h @@ -135,7 +135,7 @@ public: virtual bool show_members_overview() override; virtual bool can_lose_focus_on_node_selection() override { return true; } virtual void set_debugger_active(bool p_active) override; - virtual void set_tooltip_request_func(String p_method, Object *p_obj) override; + virtual void set_tooltip_request_func(const Callable &p_toolip_callback) override; virtual void add_callback(const String &p_function, PackedStringArray p_args) override; void update_toggle_scripts_button() override; diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp index 900bf4ef57..662c0126ec 100644 --- a/editor/plugins/texture_region_editor_plugin.cpp +++ b/editor/plugins/texture_region_editor_plugin.cpp @@ -35,6 +35,7 @@ #include "core/os/keyboard.h" #include "editor/editor_scale.h" #include "scene/gui/check_box.h" +#include "scene/gui/view_panner.h" void draw_margin_line(Control *edit_draw, Vector2 from, Vector2 to) { Vector2 line = (to - from).normalized() * 10; @@ -259,6 +260,10 @@ void TextureRegionEditor::_region_draw() { } void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { + if (panner->gui_input(p_input)) { + return; + } + Transform2D mtx; mtx.elements[2] = -draw_ofs * draw_zoom; mtx.scale_basis(Vector2(draw_zoom, draw_zoom)); @@ -281,7 +286,7 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { Ref<InputEventMouseButton> mb = p_input; if (mb.is_valid()) { if (mb->get_button_index() == MouseButton::LEFT) { - if (mb->is_pressed()) { + if (mb->is_pressed() && !panner->is_panning()) { if (node_ninepatch || obj_styleBox.is_valid()) { edited_margin = -1; float margins[4] = { 0 }; @@ -400,7 +405,7 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { } } - } else if (drag) { + } else if (!mb->is_pressed() && drag) { if (edited_margin >= 0) { undo_redo->create_action(TTR("Set Margin")); static Side side[4] = { SIDE_TOP, SIDE_BOTTOM, SIDE_LEFT, SIDE_RIGHT }; @@ -461,21 +466,13 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { drag_index = -1; } } - } else if (mb->get_button_index() == MouseButton::WHEEL_UP && mb->is_pressed()) { - _zoom_on_position(draw_zoom * ((0.95 + (0.05 * mb->get_factor())) / 0.95), mb->get_position()); - } else if (mb->get_button_index() == MouseButton::WHEEL_DOWN && mb->is_pressed()) { - _zoom_on_position(draw_zoom * (1 - (0.05 * mb->get_factor())), mb->get_position()); } } Ref<InputEventMouseMotion> mm = p_input; if (mm.is_valid()) { - if ((mm->get_button_mask() & MouseButton::MASK_MIDDLE) != MouseButton::NONE || Input::get_singleton()->is_key_pressed(Key::SPACE)) { - Vector2 dragged(mm->get_relative().x / draw_zoom, mm->get_relative().y / draw_zoom); - hscroll->set_value(hscroll->get_value() - dragged.x); - vscroll->set_value(vscroll->get_value() - dragged.y); - } else if (drag) { + if (drag) { if (edited_margin >= 0) { float new_margin = 0; @@ -605,6 +602,24 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { } } +void TextureRegionEditor::_scroll_callback(Vector2 p_scroll_vec, bool p_alt) { + _pan_callback(-p_scroll_vec * 32); +} + +void TextureRegionEditor::_pan_callback(Vector2 p_scroll_vec) { + p_scroll_vec /= draw_zoom; + hscroll->set_value(hscroll->get_value() - p_scroll_vec.x); + vscroll->set_value(vscroll->get_value() - p_scroll_vec.y); +} + +void TextureRegionEditor::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin, bool p_alt) { + if (p_scroll_vec.y < 0) { + _zoom_on_position(draw_zoom * ((0.95 + (0.05 * Math::abs(p_scroll_vec.y))) / 0.95), p_origin); + } else { + _zoom_on_position(draw_zoom * (1 - (0.05 * Math::abs(p_scroll_vec.y))), p_origin); + } +} + void TextureRegionEditor::_scroll_changed(float) { if (updating_scroll) { return; @@ -802,6 +817,10 @@ void TextureRegionEditor::_notification(int p_what) { vscroll->set_anchors_and_offsets_preset(PRESET_RIGHT_WIDE); hscroll->set_anchors_and_offsets_preset(PRESET_BOTTOM_WIDE); + [[fallthrough]]; + } + case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { + panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/sub_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning"))); } break; case NOTIFICATION_VISIBILITY_CHANGED: { if (snap_mode == SNAP_AUTOSLICE && is_visible() && autoslice_is_dirty) { @@ -1058,11 +1077,16 @@ TextureRegionEditor::TextureRegionEditor(EditorNode *p_editor) { hb_grid->hide(); + panner.instantiate(); + panner->set_callbacks(callable_mp(this, &TextureRegionEditor::_scroll_callback), callable_mp(this, &TextureRegionEditor::_pan_callback), callable_mp(this, &TextureRegionEditor::_zoom_callback)); + edit_draw = memnew(Panel); add_child(edit_draw); edit_draw->set_v_size_flags(SIZE_EXPAND_FILL); edit_draw->connect("draw", callable_mp(this, &TextureRegionEditor::_region_draw)); edit_draw->connect("gui_input", callable_mp(this, &TextureRegionEditor::_region_input)); + edit_draw->connect("focus_exited", callable_mp(panner.ptr(), &ViewPanner::release_pan_key)); + edit_draw->set_focus_mode(FOCUS_CLICK); draw_zoom = 1.0; edit_draw->set_clip_contents(true); diff --git a/editor/plugins/texture_region_editor_plugin.h b/editor/plugins/texture_region_editor_plugin.h index bffc6fd9bf..d78ad3891c 100644 --- a/editor/plugins/texture_region_editor_plugin.h +++ b/editor/plugins/texture_region_editor_plugin.h @@ -40,6 +40,8 @@ #include "scene/resources/style_box.h" #include "scene/resources/texture.h" +class ViewPanner; + class TextureRegionEditor : public VBoxContainer { GDCLASS(TextureRegionEditor, VBoxContainer); @@ -98,6 +100,11 @@ class TextureRegionEditor : public VBoxContainer { Vector2 drag_from; int drag_index; + Ref<ViewPanner> panner; + void _scroll_callback(Vector2 p_scroll_vec, bool p_alt); + void _pan_callback(Vector2 p_scroll_vec); + void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin, bool p_alt); + void _set_snap_mode(int p_mode); void _set_snap_off_x(float p_val); void _set_snap_off_y(float p_val); diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index 91c17399c2..f95b2b40b5 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -81,8 +81,6 @@ void ThemeItemImportTree::_update_items_tree() { bool is_matching_filter = (filter_text.is_empty() || type_name.findn(filter_text) > -1); bool has_filtered_items = false; - bool any_checked = false; - bool any_checked_with_data = false; for (int i = 0; i < Theme::DATA_TYPE_MAX; i++) { Theme::DataType dt = (Theme::DataType)i; @@ -178,9 +176,6 @@ void ThemeItemImportTree::_update_items_tree() { break; // Can't happen, but silences warning. } - bool data_type_any_checked = false; - bool data_type_any_checked_with_data = false; - filtered_names.sort_custom<StringName::AlphCompare>(); for (const StringName &F : filtered_names) { TreeItem *item_node = import_items_tree->create_item(data_type_node); @@ -194,20 +189,11 @@ void ThemeItemImportTree::_update_items_tree() { item_node->set_editable(IMPORT_ITEM_DATA, true); _restore_selected_item(item_node); - if (item_node->is_checked(IMPORT_ITEM)) { - data_type_any_checked = true; - any_checked = true; - } - if (item_node->is_checked(IMPORT_ITEM_DATA)) { - data_type_any_checked_with_data = true; - any_checked_with_data = true; - } + item_node->propagate_check(IMPORT_ITEM, false); + item_node->propagate_check(IMPORT_ITEM_DATA, false); item_list->push_back(item_node); } - - data_type_node->set_checked(IMPORT_ITEM, data_type_any_checked); - data_type_node->set_checked(IMPORT_ITEM_DATA, data_type_any_checked && data_type_any_checked_with_data); } // Remove the item if it doesn't match the filter in any way. @@ -221,9 +207,6 @@ void ThemeItemImportTree::_update_items_tree() { if (!filter_text.is_empty() && has_filtered_items) { type_node->set_collapsed(false); } - - type_node->set_checked(IMPORT_ITEM, any_checked); - type_node->set_checked(IMPORT_ITEM_DATA, any_checked && any_checked_with_data); } if (color_amount > 0) { @@ -471,23 +454,26 @@ void ThemeItemImportTree::_tree_item_edited() { if (is_checked) { if (edited_column == IMPORT_ITEM_DATA) { edited_item->set_checked(IMPORT_ITEM, true); + edited_item->propagate_check(IMPORT_ITEM); } - - _select_all_subitems(edited_item, (edited_column == IMPORT_ITEM_DATA)); } else { if (edited_column == IMPORT_ITEM) { edited_item->set_checked(IMPORT_ITEM_DATA, false); + edited_item->propagate_check(IMPORT_ITEM_DATA); } - - _deselect_all_subitems(edited_item, (edited_column == IMPORT_ITEM)); } - - _update_parent_items(edited_item); - _store_selected_item(edited_item); - + edited_item->propagate_check(edited_column); updating_tree = false; } +void ThemeItemImportTree::_check_propagated_to_tree_item(Object *p_obj, int p_column) { + TreeItem *item = Object::cast_to<TreeItem>(p_obj); + // Skip "category" tree items by checking for children. + if (item && !item->get_first_child()) { + _store_selected_item(item); + } +} + void ThemeItemImportTree::_select_all_subitems(TreeItem *p_root_item, bool p_select_with_data) { TreeItem *child_item = p_root_item->get_first_child(); while (child_item) { @@ -516,32 +502,6 @@ void ThemeItemImportTree::_deselect_all_subitems(TreeItem *p_root_item, bool p_d } } -void ThemeItemImportTree::_update_parent_items(TreeItem *p_root_item) { - TreeItem *parent_item = p_root_item->get_parent(); - if (!parent_item) { - return; - } - - bool any_checked = false; - bool any_checked_with_data = false; - - TreeItem *child_item = parent_item->get_first_child(); - while (child_item) { - if (child_item->is_checked(IMPORT_ITEM)) { - any_checked = true; - } - if (child_item->is_checked(IMPORT_ITEM_DATA)) { - any_checked_with_data = true; - } - - child_item = child_item->get_next(); - } - - parent_item->set_checked(IMPORT_ITEM, any_checked); - parent_item->set_checked(IMPORT_ITEM_DATA, any_checked && any_checked_with_data); - _update_parent_items(parent_item); -} - void ThemeItemImportTree::_select_all_items_pressed() { if (updating_tree) { return; @@ -629,7 +589,7 @@ void ThemeItemImportTree::_select_all_data_type_pressed(int p_data_type) { } child_item->set_checked(IMPORT_ITEM, true); - _update_parent_items(child_item); + child_item->propagate_check(IMPORT_ITEM, false); _store_selected_item(child_item); } @@ -685,7 +645,8 @@ void ThemeItemImportTree::_select_full_data_type_pressed(int p_data_type) { child_item->set_checked(IMPORT_ITEM, true); child_item->set_checked(IMPORT_ITEM_DATA, true); - _update_parent_items(child_item); + child_item->propagate_check(IMPORT_ITEM, false); + child_item->propagate_check(IMPORT_ITEM_DATA, false); _store_selected_item(child_item); } @@ -741,7 +702,8 @@ void ThemeItemImportTree::_deselect_all_data_type_pressed(int p_data_type) { child_item->set_checked(IMPORT_ITEM, false); child_item->set_checked(IMPORT_ITEM_DATA, false); - _update_parent_items(child_item); + child_item->propagate_check(IMPORT_ITEM, false); + child_item->propagate_check(IMPORT_ITEM_DATA, false); _store_selected_item(child_item); } @@ -937,6 +899,7 @@ ThemeItemImportTree::ThemeItemImportTree() { import_items_tree->set_h_size_flags(Control::SIZE_EXPAND_FILL); import_main_hb->add_child(import_items_tree); import_items_tree->connect("item_edited", callable_mp(this, &ThemeItemImportTree::_tree_item_edited)); + import_items_tree->connect("check_propagated_to_item", callable_mp(this, &ThemeItemImportTree::_check_propagated_to_tree_item)); import_items_tree->set_columns(3); import_items_tree->set_column_titles_visible(true); diff --git a/editor/plugins/theme_editor_plugin.h b/editor/plugins/theme_editor_plugin.h index 4c6b16a68c..c00ce3ae65 100644 --- a/editor/plugins/theme_editor_plugin.h +++ b/editor/plugins/theme_editor_plugin.h @@ -149,9 +149,9 @@ class ThemeItemImportTree : public VBoxContainer { void _update_total_selected(Theme::DataType p_data_type); void _tree_item_edited(); + void _check_propagated_to_tree_item(Object *p_obj, int p_column); void _select_all_subitems(TreeItem *p_root_item, bool p_select_with_data); void _deselect_all_subitems(TreeItem *p_root_item, bool p_deselect_completely); - void _update_parent_items(TreeItem *p_root_item); void _select_all_items_pressed(); void _select_full_items_pressed(); diff --git a/editor/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp index 24ede3b85e..3b9bde6b0d 100644 --- a/editor/plugins/tiles/tile_atlas_view.cpp +++ b/editor/plugins/tiles/tile_atlas_view.cpp @@ -48,7 +48,7 @@ void TileAtlasView::gui_input(const Ref<InputEvent> &p_event) { } } -void TileAtlasView::_scroll_callback(Vector2 p_scroll_vec) { +void TileAtlasView::_scroll_callback(Vector2 p_scroll_vec, bool p_alt) { _pan_callback(-p_scroll_vec * 32); } @@ -58,7 +58,7 @@ void TileAtlasView::_pan_callback(Vector2 p_scroll_vec) { _update_zoom_and_panning(true); } -void TileAtlasView::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin) { +void TileAtlasView::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin, bool p_alt) { zoom_widget->set_zoom_by_increments(-p_scroll_vec.y * 2); emit_signal(SNAME("transform_changed"), zoom_widget->get_zoom(), panning); _update_zoom_and_panning(true); @@ -524,7 +524,7 @@ void TileAtlasView::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: - panner->set_control_scheme((ViewPanner::ControlScheme)EDITOR_GET("interface/editors/sub_editor_panning_scheme").operator int()); + panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/sub_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning"))); break; case NOTIFICATION_READY: @@ -540,9 +540,6 @@ void TileAtlasView::_bind_methods() { TileAtlasView::TileAtlasView() { set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST); - panner.instantiate(); - panner->set_callbacks(callable_mp(this, &TileAtlasView::_scroll_callback), callable_mp(this, &TileAtlasView::_pan_callback), callable_mp(this, &TileAtlasView::_zoom_callback)); - Panel *panel = memnew(Panel); panel->set_clip_contents(true); panel->set_mouse_filter(Control::MOUSE_FILTER_IGNORE); @@ -566,10 +563,16 @@ TileAtlasView::TileAtlasView() { button_center_view->set_tooltip(TTR("Center View")); add_child(button_center_view); + panner.instantiate(); + panner->set_callbacks(callable_mp(this, &TileAtlasView::_scroll_callback), callable_mp(this, &TileAtlasView::_pan_callback), callable_mp(this, &TileAtlasView::_zoom_callback)); + panner->set_enable_rmb(true); + center_container = memnew(CenterContainer); center_container->set_mouse_filter(Control::MOUSE_FILTER_IGNORE); center_container->set_anchors_preset(Control::PRESET_CENTER); center_container->connect("gui_input", callable_mp(this, &TileAtlasView::gui_input)); + center_container->connect("focus_exited", callable_mp(panner.ptr(), &ViewPanner::release_pan_key)); + center_container->set_focus_mode(FOCUS_CLICK); panel->add_child(center_container); missing_source_label = memnew(Label); diff --git a/editor/plugins/tiles/tile_atlas_view.h b/editor/plugins/tiles/tile_atlas_view.h index 6a0e0ae820..37ef7d6a2a 100644 --- a/editor/plugins/tiles/tile_atlas_view.h +++ b/editor/plugins/tiles/tile_atlas_view.h @@ -67,9 +67,9 @@ private: virtual void gui_input(const Ref<InputEvent> &p_event) override; Ref<ViewPanner> panner; - void _scroll_callback(Vector2 p_scroll_vec); + void _scroll_callback(Vector2 p_scroll_vec, bool p_alt); void _pan_callback(Vector2 p_scroll_vec); - void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin); + void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin, bool p_alt); Map<Vector2, Map<int, Rect2i>> alternative_tiles_rect_cache; void _update_alternative_tiles_rect_cache(); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index f05ff72e5d..2d0ca11b6a 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -42,6 +42,7 @@ #include "scene/animation/animation_player.h" #include "scene/gui/menu_button.h" #include "scene/gui/panel.h" +#include "scene/gui/view_panner.h" #include "scene/main/window.h" #include "scene/resources/visual_shader_nodes.h" #include "scene/resources/visual_shader_particle_nodes.h" @@ -351,6 +352,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { if (!graph_plugin) { return; } + Shader::Mode mode = visual_shader->get_mode(); Control *offset; @@ -707,9 +709,9 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { label->add_theme_style_override("normal", label_style); //more compact hb->add_child(label); - if (vsnode->get_input_port_default_hint(i) != "" && !port_left_used) { + if (vsnode->is_input_port_default(i, mode) && !port_left_used) { Label *hint_label = memnew(Label); - hint_label->set_text("[" + vsnode->get_input_port_default_hint(i) + "]"); + hint_label->set_text(TTR("[default]")); hint_label->add_theme_color_override("font_color", editor->get_theme_color(SNAME("font_readonly_color"), SNAME("TextEdit"))); hint_label->add_theme_style_override("normal", label_style); hb->add_child(hint_label); @@ -840,7 +842,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { offset->set_custom_minimum_size(Size2(0, 4 * EDSCALE)); node->add_child(offset); - String error = vsnode->get_warning(visual_shader->get_mode(), p_type); + String error = vsnode->get_warning(mode, p_type); if (!error.is_empty()) { Label *error_label = memnew(Label); error_label->add_theme_color_override("font_color", editor->get_theme_color(SNAME("error_color"), SNAME("Editor"))); @@ -3222,7 +3224,8 @@ void VisualShaderEditor::_notification(int p_what) { } if (p_what == NOTIFICATION_ENTER_TREE || p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { - graph->set_panning_scheme((GraphEdit::PanningScheme)EDITOR_GET("interface/editors/sub_editor_panning_scheme").operator int()); + graph->get_panner()->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/sub_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning"))); + graph->set_warped_panning(bool(EditorSettings::get_singleton()->get("editors/panning/warped_mouse_panning"))); } if (p_what == NOTIFICATION_DRAG_BEGIN) { @@ -4495,7 +4498,6 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("ObjectPosition", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "object_position"), "object_position", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FOG, Shader::MODE_FOG)); add_options.push_back(AddOption("UVW", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "uvw"), "uvw", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FOG, Shader::MODE_FOG)); add_options.push_back(AddOption("Extents", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "extents"), "extents", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FOG, Shader::MODE_FOG)); - add_options.push_back(AddOption("Transform", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "transform"), "transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_FOG, Shader::MODE_FOG)); add_options.push_back(AddOption("SDF", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "sdf"), "sdf", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FOG, Shader::MODE_FOG)); add_options.push_back(AddOption("Time", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FOG, Shader::MODE_FOG)); @@ -4967,7 +4969,7 @@ public: } void _open_inspector(RES p_resource) { - EditorNode::get_singleton()->get_inspector()->edit(p_resource.ptr()); + InspectorDock::get_inspector_singleton()->edit(p_resource.ptr()); } bool updating; diff --git a/editor/project_export.cpp b/editor/project_export.cpp index 9bd8c1e227..f39a494df8 100644 --- a/editor/project_export.cpp +++ b/editor/project_export.cpp @@ -752,12 +752,10 @@ bool ProjectExportDialog::_fill_tree(EditorFileSystemDirectory *p_dir, TreeItem p_item->set_metadata(0, p_dir->get_path()); bool used = false; - bool checked = true; for (int i = 0; i < p_dir->get_subdir_count(); i++) { TreeItem *subdir = include_files->create_item(p_item); if (_fill_tree(p_dir->get_subdir(i), subdir, current, p_only_scenes)) { used = true; - checked = checked && subdir->is_checked(0); } else { memdelete(subdir); } @@ -782,12 +780,10 @@ bool ProjectExportDialog::_fill_tree(EditorFileSystemDirectory *p_dir, TreeItem file->set_editable(0, true); file->set_checked(0, current->has_export_file(path)); file->set_metadata(0, path); - checked = checked && file->is_checked(0); + file->propagate_check(0); used = true; } - - p_item->set_checked(0, checked); return used; } @@ -806,54 +802,24 @@ void ProjectExportDialog::_tree_changed() { return; } - String path = item->get_metadata(0); - bool added = item->is_checked(0); + item->propagate_check(0); +} - if (path.ends_with("/")) { - _check_dir_recursive(item, added); - } else { +void ProjectExportDialog::_check_propagated_to_item(Object *p_obj, int column) { + Ref<EditorExportPreset> current = get_current_preset(); + if (current.is_null()) { + return; + } + TreeItem *item = Object::cast_to<TreeItem>(p_obj); + String path = item->get_metadata(0); + if (item && !path.ends_with("/")) { + bool added = item->is_checked(0); if (added) { current->add_export_file(path); } else { current->remove_export_file(path); } } - _refresh_parent_checks(item); // Makes parent folder checked if all files/folders are checked. -} - -void ProjectExportDialog::_check_dir_recursive(TreeItem *p_dir, bool p_checked) { - for (TreeItem *child = p_dir->get_first_child(); child; child = child->get_next()) { - String path = child->get_metadata(0); - - child->set_checked(0, p_checked); - if (path.ends_with("/")) { - _check_dir_recursive(child, p_checked); - } else { - if (p_checked) { - get_current_preset()->add_export_file(path); - } else { - get_current_preset()->remove_export_file(path); - } - } - } -} - -void ProjectExportDialog::_refresh_parent_checks(TreeItem *p_item) { - TreeItem *parent = p_item->get_parent(); - if (!parent) { - return; - } - - bool checked = true; - for (TreeItem *child = parent->get_first_child(); child; child = child->get_next()) { - checked = checked && child->is_checked(0); - if (!checked) { - break; - } - } - parent->set_checked(0, checked); - - _refresh_parent_checks(parent); } void ProjectExportDialog::_export_pck_zip() { @@ -1126,6 +1092,7 @@ ProjectExportDialog::ProjectExportDialog() { include_files = memnew(Tree); include_margin->add_child(include_files); include_files->connect("item_edited", callable_mp(this, &ProjectExportDialog::_tree_changed)); + include_files->connect("check_propagated_to_item", callable_mp(this, &ProjectExportDialog::_check_propagated_to_item)); include_filters = memnew(LineEdit); resources_vb->add_margin_child( diff --git a/editor/project_export.h b/editor/project_export.h index af7ec083c4..3d90a0d3ff 100644 --- a/editor/project_export.h +++ b/editor/project_export.h @@ -124,8 +124,7 @@ private: void _fill_resource_tree(); bool _fill_tree(EditorFileSystemDirectory *p_dir, TreeItem *p_item, Ref<EditorExportPreset> ¤t, bool p_only_scenes); void _tree_changed(); - void _check_dir_recursive(TreeItem *p_dir, bool p_checked); - void _refresh_parent_checks(TreeItem *p_item); + void _check_propagated_to_item(Object *p_obj, int column); Variant get_drag_data_fw(const Point2 &p_point, Control *p_from); bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp index c971bb6473..9d894afa6f 100644 --- a/editor/property_editor.cpp +++ b/editor/property_editor.cpp @@ -208,19 +208,19 @@ void CustomPropertyEditor::_menu_option(int p_which) { } break; case OBJ_MENU_NEW_SCRIPT: { if (Object::cast_to<Node>(owner)) { - EditorNode::get_singleton()->get_scene_tree_dock()->open_script_dialog(Object::cast_to<Node>(owner), false); + SceneTreeDock::get_singleton()->open_script_dialog(Object::cast_to<Node>(owner), false); } } break; case OBJ_MENU_EXTEND_SCRIPT: { if (Object::cast_to<Node>(owner)) { - EditorNode::get_singleton()->get_scene_tree_dock()->open_script_dialog(Object::cast_to<Node>(owner), true); + SceneTreeDock::get_singleton()->open_script_dialog(Object::cast_to<Node>(owner), true); } } break; case OBJ_MENU_SHOW_IN_FILE_SYSTEM: { RES r = v; - FileSystemDock *file_system_dock = EditorNode::get_singleton()->get_filesystem_dock(); + FileSystemDock *file_system_dock = FileSystemDock::get_singleton(); file_system_dock->navigate_to_path(r->get_path()); // Ensure that the FileSystem dock is visible. TabContainer *tab_container = (TabContainer *)file_system_dock->get_parent_control(); @@ -1256,7 +1256,7 @@ void CustomPropertyEditor::_action_pressed(int p_which) { if (owner->is_class("Node") && (v.get_type() == Variant::NODE_PATH) && Object::cast_to<Node>(owner)->has_node(v)) { Node *target_node = Object::cast_to<Node>(owner)->get_node(v); EditorNode::get_singleton()->get_editor_selection()->clear(); - EditorNode::get_singleton()->get_scene_tree_dock()->set_selected(target_node); + SceneTreeDock::get_singleton()->set_selected(target_node); } hide(); diff --git a/editor/rename_dialog.cpp b/editor/rename_dialog.cpp index 20845b0e9d..72686e9eb3 100644 --- a/editor/rename_dialog.cpp +++ b/editor/rename_dialog.cpp @@ -284,6 +284,7 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und vbc->add_child(lbl_preview_title); lbl_preview = memnew(Label); + lbl_preview->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART); vbc->add_child(lbl_preview); // ---- Dialog related diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index c9acb7b668..125fcc02dc 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -1043,7 +1043,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { if (node) { node->set_scene_inherited_state(Ref<SceneState>()); scene_tree->update_tree(); - EditorNode::get_singleton()->get_inspector()->update_tree(); + InspectorDock::get_inspector_singleton()->update_tree(); } } } break; @@ -2067,7 +2067,7 @@ void SceneTreeDock::_delete_confirm(bool p_cut) { // Fixes the EditorHistory from still offering deleted notes EditorHistory *editor_history = EditorNode::get_singleton()->get_editor_history(); editor_history->cleanup_history(); - EditorNode::get_singleton()->get_inspector_dock()->call("_prepare_history"); + InspectorDock::get_singleton()->call("_prepare_history"); } void SceneTreeDock::_update_script_button() { @@ -2809,15 +2809,9 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { menu->popup(); } -void SceneTreeDock::_open_tree_menu() { - menu->clear(); - - menu->add_check_item(TTR("Auto Expand to Selected"), TOOL_AUTO_EXPAND); - menu->set_item_checked(menu->get_item_idx_from_text(TTR("Auto Expand to Selected")), EditorSettings::get_singleton()->get("docks/scene_tree/auto_expand_to_selected")); - - menu->reset_size(); - menu->set_position(get_screen_position() + get_local_mouse_position()); - menu->popup(); +void SceneTreeDock::_update_tree_menu() { + PopupMenu *tree_menu = button_tree_menu->get_popup(); + tree_menu->set_item_checked(tree_menu->get_item_idx_from_text(TTR("Auto Expand to Selected")), EditorSettings::get_singleton()->get("docks/scene_tree/auto_expand_to_selected")); } void SceneTreeDock::_filter_changed(const String &p_filter) { @@ -3220,7 +3214,7 @@ void SceneTreeDock::_create_remap_for_node(Node *p_node, Map<RES, RES> &r_remap) } Variant v = p_node->get(E.name); - if (v.is_ref()) { + if (v.is_ref_counted()) { RES res = v; if (res.is_valid()) { if (!states_stack_ready) { @@ -3258,7 +3252,7 @@ void SceneTreeDock::_create_remap_for_resource(RES p_resource, Map<RES, RES> &r_ } Variant v = p_resource->get(E.name); - if (v.is_ref()) { + if (v.is_ref_counted()) { RES res = v; if (res.is_valid()) { if (res->is_built_in() && !r_remap.has(res)) { @@ -3370,11 +3364,15 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel filter_hbc->add_child(button_detach_script); button_detach_script->hide(); - button_tree_menu = memnew(Button); + button_tree_menu = memnew(MenuButton); button_tree_menu->set_flat(true); - button_tree_menu->connect("pressed", callable_mp(this, &SceneTreeDock::_open_tree_menu)); + button_tree_menu->connect("about_to_popup", callable_mp(this, &SceneTreeDock::_update_tree_menu)); filter_hbc->add_child(button_tree_menu); + PopupMenu *tree_menu = button_tree_menu->get_popup(); + tree_menu->add_check_item(TTR("Auto Expand to Selected"), TOOL_AUTO_EXPAND); + tree_menu->connect("id_pressed", callable_mp(this, &SceneTreeDock::_tool_selected), make_binds(false)); + button_hb = memnew(HBoxContainer); vbc->add_child(button_hb); diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h index f442d3fc6b..d73038ef36 100644 --- a/editor/scene_tree_dock.h +++ b/editor/scene_tree_dock.h @@ -117,7 +117,7 @@ class SceneTreeDock : public VBoxContainer { Button *button_instance; Button *button_create_script; Button *button_detach_script; - Button *button_tree_menu; + MenuButton *button_tree_menu; Button *button_2d; Button *button_3d; @@ -242,7 +242,7 @@ class SceneTreeDock : public VBoxContainer { void _quick_open(); void _tree_rmb(const Vector2 &p_menu_pos); - void _open_tree_menu(); + void _update_tree_menu(); void _filter_changed(const String &p_filter); @@ -264,12 +264,17 @@ class SceneTreeDock : public VBoxContainer { bool profile_allow_editing; bool profile_allow_script_editing; - static SceneTreeDock *singleton; static void _update_configuration_warning(); bool _update_node_path(Node *p_root_node, NodePath &r_node_path, Map<Node *, NodePath> *p_renames) const; bool _check_node_path_recursive(Node *p_root_node, Variant &r_variant, Map<Node *, NodePath> *p_renames) const; +private: + static SceneTreeDock *singleton; + +public: + static SceneTreeDock *get_singleton() { return singleton; } + protected: void _notification(int p_what); static void _bind_methods(); diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index dc95b73569..4a36462d65 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -133,8 +133,8 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i set_selected(n); - NodeDock::singleton->get_parent()->call("set_current_tab", NodeDock::singleton->get_index()); - NodeDock::singleton->show_connections(); + NodeDock::get_singleton()->get_parent()->call("set_current_tab", NodeDock::get_singleton()->get_index()); + NodeDock::get_singleton()->show_connections(); } else if (p_id == BUTTON_GROUPS) { editor_selection->clear(); @@ -142,8 +142,8 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i set_selected(n); - NodeDock::singleton->get_parent()->call("set_current_tab", NodeDock::singleton->get_index()); - NodeDock::singleton->show_groups(); + NodeDock::get_singleton()->get_parent()->call("set_current_tab", NodeDock::get_singleton()->get_index()); + NodeDock::get_singleton()->show_groups(); } } |