diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 33362c5114..f9fecb6905 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -3387,13 +3387,13 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { } break; case SCENE_QUICK_OPEN: { - quick_open_dialog->popup_dialog({ "Resource" }, callable_mp(this, &EditorNode::_quick_opened)); + quick_open_dialog->popup_dialog({ "Resource" }, callable_mp(this, &EditorNode::_quick_opened), true); } break; case SCENE_QUICK_OPEN_SCENE: { - quick_open_dialog->popup_dialog({ "PackedScene" }, callable_mp(this, &EditorNode::_quick_opened)); + quick_open_dialog->popup_dialog({ "PackedScene" }, callable_mp(this, &EditorNode::_quick_opened), true); } break; case SCENE_QUICK_OPEN_SCRIPT: { - quick_open_dialog->popup_dialog({ "Script" }, callable_mp(this, &EditorNode::_quick_opened)); + quick_open_dialog->popup_dialog({ "Script" }, callable_mp(this, &EditorNode::_quick_opened), true); } break; case SCENE_OPEN_PREV: { if (!prev_closed_scenes.is_empty()) { diff --git a/editor/gui/editor_quick_open_dialog.cpp b/editor/gui/editor_quick_open_dialog.cpp index 4c7745fd11..1974b05189 100644 --- a/editor/gui/editor_quick_open_dialog.cpp +++ b/editor/gui/editor_quick_open_dialog.cpp @@ -151,14 +151,16 @@ String EditorQuickOpenDialog::get_dialog_title(const Vector &p_base_ return vformat(TTR("Select %s"), p_base_types[0]); } -void EditorQuickOpenDialog::popup_dialog(const Vector &p_base_types, const Callable &p_item_selected_callback) { +void EditorQuickOpenDialog::popup_dialog(const Vector &p_base_types, const Callable &p_item_selected_callback, bool p_allow_type_switching) { ERR_FAIL_COND(p_base_types.is_empty()); ERR_FAIL_COND(!p_item_selected_callback.is_valid()); property_object = nullptr; property_path = ""; item_selected_callback = p_item_selected_callback; + allow_type_switching = p_allow_type_switching; + is_cycling_items = false; container->init(p_base_types); container->set_instant_preview_toggle_visible(false); _finish_dialog_setup(p_base_types); @@ -173,6 +175,7 @@ void EditorQuickOpenDialog::popup_dialog_for_property(const Vector & property_path = p_path; item_selected_callback = p_item_selected_callback; initial_property_value = property_object->get(property_path); + allow_type_switching = false; // Reset this, so that the property isn't updated immediately upon opening // the window. @@ -184,6 +187,7 @@ void EditorQuickOpenDialog::popup_dialog_for_property(const Vector & } void EditorQuickOpenDialog::_finish_dialog_setup(const Vector &p_base_types) { + set_process_shortcut_input(allow_type_switching); get_ok_button()->set_disabled(container->has_nothing_selected()); set_title(get_dialog_title(p_base_types)); popup_centered_clamped(Size2(780, 650) * EDSCALE, 0.8f); @@ -294,6 +298,55 @@ void EditorQuickOpenDialog::cancel_pressed() { search_box->clear(); } +void EditorQuickOpenDialog::shortcut_input(const Ref &p_event) { + // If the user is cycling through items (with up/down arrows), confirm selection when releasing the keys. + Ref iewm = p_event; + if (is_cycling_items && iewm.is_valid() && p_event->is_released() && iewm->get_modifiers_mask().is_empty()) { + ok_pressed(); + return; + } + + if (p_event.is_null() || !p_event->is_pressed() || p_event->is_echo()) { + return; + } + + Vector new_base_types; + if (EditorSettings *settings = EditorSettings::get_singleton()) { + if (settings->is_shortcut("editor/quick_open", p_event)) { + new_base_types.push_back("Resource"); + } else if (settings->is_shortcut("editor/quick_open_scene", p_event)) { + new_base_types.push_back("PackedScene"); + } else if (settings->is_shortcut("editor/quick_open_script", p_event)) { + new_base_types.push_back("Script"); + } + } + + if (new_base_types.size() != 1) { + return; + } + + // Check if we're already showing this dialog type. + const Vector ¤t_base_types = container->get_base_types(); + if (current_base_types.size() == 1 && current_base_types[0] == new_base_types[0]) { + // Already showing the requested dialog type, move next. + Ref down_event = memnew(InputEventKey); + down_event->set_keycode(Key::DOWN); + down_event->set_pressed(true); + container->handle_search_box_input(down_event); + is_cycling_items = true; + } else { + // Switch to the new dialog type. + container->init(new_base_types); + container->set_instant_preview_toggle_visible(false); + is_cycling_items = false; + set_title(get_dialog_title(new_base_types)); + search_box->clear(); + search_box->grab_focus(); + } + + set_input_as_handled(); +} + void EditorQuickOpenDialog::_search_box_text_changed(const String &p_query) { container->set_query_and_update(p_query); get_ok_button()->set_disabled(container->has_nothing_selected()); @@ -1029,6 +1082,10 @@ String QuickOpenResultContainer::get_selected_path() const { return path; } +const Vector &QuickOpenResultContainer::get_base_types() const { + return base_types; +} + QuickOpenDisplayMode QuickOpenResultContainer::get_adaptive_display_mode(const Vector &p_base_types) { static const Vector grid_preferred_types = { StringName("Font", true), diff --git a/editor/gui/editor_quick_open_dialog.h b/editor/gui/editor_quick_open_dialog.h index e3fc4f2ef0..ea5f7ff944 100644 --- a/editor/gui/editor_quick_open_dialog.h +++ b/editor/gui/editor_quick_open_dialog.h @@ -100,6 +100,7 @@ public: bool has_nothing_selected() const; ResourceUID::ID get_selected() const; String get_selected_path() const; + const Vector &get_base_types() const; bool is_instant_preview_enabled() const; void set_instant_preview_toggle_visible(bool p_visible); @@ -260,13 +261,14 @@ class EditorQuickOpenDialog : public AcceptDialog { GDCLASS(EditorQuickOpenDialog, AcceptDialog); public: - void popup_dialog(const Vector &p_base_types, const Callable &p_item_selected_callback); + void popup_dialog(const Vector &p_base_types, const Callable &p_item_selected_callback, bool p_allow_type_switching = false); void popup_dialog_for_property(const Vector &p_base_types, Object *p_obj, const StringName &p_path, const Callable &p_item_selected_callback); EditorQuickOpenDialog(); protected: virtual void cancel_pressed() override; virtual void ok_pressed() override; + virtual void shortcut_input(const Ref &p_event) override; void item_pressed(bool p_double_click); void selection_changed(); @@ -282,6 +284,8 @@ private: StringName property_path; Variant initial_property_value; bool initial_selection_performed = false; + bool allow_type_switching = false; + bool is_cycling_items = false; bool _is_instant_preview_active() const; void _search_box_text_changed(const String &p_query); void _finish_dialog_setup(const Vector &p_base_types);