From 1c4b9d43d174f1072152d82708b4091542759bbf Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 22 Dec 2023 14:56:37 +0100 Subject: [PATCH] Search improvements: * Set max size. * Close search dialog, when both of search dialog and search input lose a focus * Update dialog position in respect to the position and size of search input --- src/slic3r/GUI/GUI_App.cpp | 4 ++ src/slic3r/GUI/Search.cpp | 77 ++++++++++++++++++++++++++++++-------- src/slic3r/GUI/Search.hpp | 5 ++- src/slic3r/GUI/TopBar.cpp | 7 +++- 4 files changed, 73 insertions(+), 20 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index dbc158fa9d..663ebf3ea7 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -1113,6 +1113,10 @@ void GUI_App::jump_to_option(const std::string& composite_key) void GUI_App::show_search_dialog() { + // To avoid endless loop caused by mutual lose focuses from serch_input and search_dialog + // invoke killFocus for serch_input by set focus to tab_panel + GUI::wxGetApp().tab_panel()->SetFocus(); + check_and_update_searcher(get_mode()); m_searcher->show_dialog(); } diff --git a/src/slic3r/GUI/Search.cpp b/src/slic3r/GUI/Search.cpp index 5792316a42..1b0b854e58 100644 --- a/src/slic3r/GUI/Search.cpp +++ b/src/slic3r/GUI/Search.cpp @@ -16,6 +16,8 @@ #include "libslic3r/PrintConfig.hpp" #include "libslic3r/PresetBundle.hpp" #include "GUI_App.hpp" +#include "I18N.hpp" +#include "format.hpp" #include "MainFrame.hpp" #include "Tab.hpp" @@ -422,24 +424,60 @@ Option OptionsSearcher::get_option(const std::string& opt_key, const wxString& l return create_option(opt_key, label, type, gc); } -void OptionsSearcher::show_dialog() +static bool has_focus(wxWindow* win) { - if (!search_dialog) - search_dialog = new SearchDialog(this); + if (win->HasFocus()) + return true; - wxSize srch_sz = search_input->GetSize(); - if (search_dialog->GetPosition().x != search_input->GetPosition().x) - search_dialog->SetPosition(search_input->GetScreenPosition() + wxPoint(0, srch_sz.y)); + auto children = win->GetChildren(); + for (auto child : children) { + if (has_focus(child)) + return true; + } - wxSize dlg_sz = search_dialog->GetSize(); - if (dlg_sz.x < srch_sz.x) - search_dialog->SetSize(wxSize(srch_sz.x, dlg_sz.y)); + return false; +} + +void OptionsSearcher::update_dialog_position() +{ + if (search_dialog) { + search_dialog->CenterOnParent(wxHORIZONTAL); + search_dialog->SetPosition({ search_dialog->GetPosition().x, search_input->GetScreenPosition().y + search_input->GetSize().y }); + } +} + +void OptionsSearcher::show_dialog(bool show /*= true*/) +{ + if (search_dialog && !show) { + search_dialog->EndModal(wxID_CLOSE); + return; + } + + if (!search_dialog) { + search_dialog = new SearchDialog(this, search_input); + update_dialog_position(); + + search_dialog->Bind(wxEVT_KILL_FOCUS, [this](wxFocusEvent& e) + { + if (search_dialog->IsShown() && !search_input->HasFocus()) + show_dialog(false); + e.Skip(); + }); + + search_input->Bind(wxEVT_KILL_FOCUS, [this](wxFocusEvent& e) + { + e.Skip(); + if (search_dialog->IsShown() && !has_focus(search_dialog)) + show_dialog(false); + }); + } search_string(); search_input->SetSelection(-1,-1); search_dialog->Popup(); - search_input->SetFocus(); + if (!search_input->HasFocus()) + search_input->SetFocus(); } void OptionsSearcher::dlg_sys_color_changed() @@ -460,12 +498,13 @@ void OptionsSearcher::set_search_input(TextInput* input_ctrl) search_input->Bind(wxEVT_TEXT, [this](wxEvent& e) { - if (search_dialog && search_dialog->IsShown()) + if (search_dialog) { search_dialog->input_text(search_input->GetValue()); - else { - GUI::wxGetApp().check_and_update_searcher(GUI::wxGetApp().get_mode()); - show_dialog(); + if (!search_dialog->IsShown()) + search_dialog->Popup(); } + else + GUI::wxGetApp().show_search_dialog(); }); wxTextCtrl* ctrl = search_input->GetTextCtrl(); @@ -488,6 +527,12 @@ void OptionsSearcher::set_search_input(TextInput* input_ctrl) search_input->SetValue(""); event.Skip(); }); + + search_input->Bind(wxEVT_MOVE, [this](wxMoveEvent& event) + { + event.Skip(); + update_dialog_position(); + }); } void OptionsSearcher::add_key(const std::string& opt_key, Preset::Type type, const wxString& group, const wxString& category) @@ -509,8 +554,8 @@ static const std::map icon_idxs = { {ImGui::PreferencesButton , 5}, }; -SearchDialog::SearchDialog(OptionsSearcher* searcher) - : GUI::DPIDialog(GUI::wxGetApp().tab_panel(), wxID_ANY, _L("Search"), wxDefaultPosition, wxDefaultSize, wxSTAY_ON_TOP | wxRESIZE_BORDER), +SearchDialog::SearchDialog(OptionsSearcher* searcher, wxWindow* parent) + : GUI::DPIDialog(parent ? parent : GUI::wxGetApp().tab_panel(), wxID_ANY, _L("Search"), wxDefaultPosition, wxDefaultSize, wxSTAY_ON_TOP | wxRESIZE_BORDER), searcher(searcher) { SetFont(GUI::wxGetApp().normal_font()); diff --git a/src/slic3r/GUI/Search.hpp b/src/slic3r/GUI/Search.hpp index cc018ab2e5..87187247f3 100644 --- a/src/slic3r/GUI/Search.hpp +++ b/src/slic3r/GUI/Search.hpp @@ -147,7 +147,8 @@ public: } void sort_options_by_label() { sort_options(); } - void show_dialog(); + void update_dialog_position(); + void show_dialog(bool show = true); void dlg_sys_color_changed(); void dlg_msw_rescale(); @@ -184,7 +185,7 @@ class SearchDialog : public GUI::DPIDialog void update_list(); public: - SearchDialog(OptionsSearcher* searcher); + SearchDialog(OptionsSearcher* searcher, wxWindow* parent); ~SearchDialog(); void Popup(wxPoint position = wxDefaultPosition); diff --git a/src/slic3r/GUI/TopBar.cpp b/src/slic3r/GUI/TopBar.cpp index a5f6f6d3c0..920c38e1bd 100644 --- a/src/slic3r/GUI/TopBar.cpp +++ b/src/slic3r/GUI/TopBar.cpp @@ -185,6 +185,7 @@ void TopBarItemsCtrl::UpdateAuthMenu() void TopBarItemsCtrl::CreateSearch() { m_search = new ::TextInput(this, wxGetApp().searcher().default_string, "", "search", wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER); + m_search->SetMaxSize(wxSize(42*em_unit(this), -1)); wxGetApp().UpdateDarkUI(m_search); wxGetApp().searcher().set_search_input(m_search); } @@ -223,11 +224,13 @@ TopBarItemsCtrl::TopBarItemsCtrl(wxWindow *parent) : #endif m_buttons_sizer = new wxFlexGridSizer(1, m_btn_margin, m_btn_margin); - left_sizer->Add(m_buttons_sizer, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 2 * m_btn_margin); + left_sizer->Add(m_buttons_sizer, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 2 * m_btn_margin); CreateSearch(); - left_sizer->Add(m_search, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, 3 * m_btn_margin); + wxBoxSizer* search_sizer = new wxBoxSizer(wxVERTICAL); + search_sizer->Add(m_search, 0, wxEXPAND | wxALIGN_RIGHT); + left_sizer->Add(search_sizer, 1, wxALIGN_CENTER_VERTICAL); m_sizer->Add(left_sizer, 1, wxEXPAND);