diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 9fa1d8066..611944fa3 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -4480,28 +4480,39 @@ bool GLCanvas3D::_render_search_list(float pos_x) const size_t selected = size_t(-1); bool edited = false; + bool check_changed = false; float em = static_cast(wxGetApp().em_unit()); #if ENABLE_RETINA_GL em *= m_retina_helper->get_scale_factor(); #endif - std::string& search_line = wxGetApp().sidebar().get_search_line(); + Sidebar& sidebar = wxGetApp().sidebar(); + + std::string& search_line = sidebar.get_search_line(); char *s = new char[255]; strcpy(s, search_line.empty() ? _u8L("Type here to search").c_str() : search_line.c_str()); - imgui->search_list(ImVec2(45 * em, 30 * em), &search_string_getter, s, selected, edited); + imgui->search_list(ImVec2(45 * em, 30 * em), &search_string_getter, s, + sidebar.get_searcher().category, sidebar.get_searcher().group, + selected, edited, check_changed); search_line = s; delete [] s; if (edited) - wxGetApp().sidebar().search_and_apply_tab_search_lines(); + sidebar.search_and_apply_tab_search_lines(); + + if (check_changed) { + if (search_line == _u8L("Type here to search")) + search_line.clear(); + sidebar.search_and_apply_tab_search_lines(true); + } if (selected != size_t(-1)) { // selected == 9999 means that Esc kye was pressed if (selected != 9999) - wxGetApp().sidebar().jump_to_option(selected); + sidebar.jump_to_option(selected); action_taken = true; } diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 2faf14952..a9b51874a 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -24,6 +24,7 @@ #include "libslic3r/Utils.hpp" #include "3DScene.hpp" #include "GUI.hpp" +#include "I18N.hpp" namespace Slic3r { namespace GUI { @@ -538,7 +539,8 @@ static bool selectable(const char* label, bool selected, ImGuiSelectableFlags fl return pressed; } -void ImGuiWrapper::search_list(const ImVec2& size_, bool (*items_getter)(int, const char**), char* search_str, size_t& selected, bool& edited) +void ImGuiWrapper::search_list(const ImVec2& size_, bool (*items_getter)(int, const char**), char* search_str, + bool& category, bool& group, size_t& selected, bool& edited, bool& check_changed) { // ImGui::ListBoxHeader("", size); { @@ -604,6 +606,23 @@ void ImGuiWrapper::search_list(const ImVec2& size_, bool (*items_getter)(int, co } ImGui::ListBoxFooter(); + + // add checkboxes for show/hide Categories and Groups + text(_L("Use for search")+":"); + ImGui::SameLine(); + bool cat = category; + checkbox(_L("Category"), cat); + if (ImGui::IsItemClicked()) { + category = !category; + check_changed = true; + } + ImGui::SameLine(); + bool gr = group; + checkbox(_L("Group"), gr); + if (ImGui::IsItemClicked()) { + group = !group; + check_changed = true; + } } void ImGuiWrapper::disabled_begin(bool disabled) diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp index 9001f6b5a..781d2a25f 100644 --- a/src/slic3r/GUI/ImGuiWrapper.hpp +++ b/src/slic3r/GUI/ImGuiWrapper.hpp @@ -74,7 +74,8 @@ public: bool slider_float(const wxString& label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f); bool combo(const wxString& label, const std::vector& options, int& selection); // Use -1 to not mark any option as selected bool undo_redo_list(const ImVec2& size, const bool is_undo, bool (*items_getter)(const bool, int, const char**), int& hovered, int& selected); - void search_list(const ImVec2& size, bool (*items_getter)(int, const char**), char* search_str, size_t& selected, bool& edited); + void search_list(const ImVec2& size, bool (*items_getter)(int, const char**), char* search_str, + bool& category, bool& group, size_t& selected, bool& edited, bool& check_changed); void disabled_begin(bool disabled); void disabled_end(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 0dbd11827..6cea1a7ef 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1091,9 +1091,9 @@ void Sidebar::msw_rescale() p->scrolled->Layout(); } -void Sidebar::search_and_apply_tab_search_lines() +void Sidebar::search_and_apply_tab_search_lines(bool force/* = false*/) { - if (p->searcher.search(p->search_line)) + if (p->searcher.search(p->search_line, force)) apply_search_line_on_tabs(); } diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 52a24ef36..ae7b241d9 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -105,7 +105,7 @@ public: void update_mode_sizer() const; void update_reslice_btn_tooltip() const; void msw_rescale(); - void search_and_apply_tab_search_lines(); + void search_and_apply_tab_search_lines(bool force = false); void jump_to_option(size_t selected); ObjectManipulation* obj_manipul(); diff --git a/src/slic3r/GUI/Search.cpp b/src/slic3r/GUI/Search.cpp index 49f74b340..b55f4fbab 100644 --- a/src/slic3r/GUI/Search.cpp +++ b/src/slic3r/GUI/Search.cpp @@ -186,11 +186,22 @@ bool OptionsSearcher::search(const std::string& search, bool force/* = false*/) bool full_list = search.empty(); + auto get_label = [this](const Option& opt) + { + wxString label; + if (category) + label += opt.category_local + " > "; + if (group) + label += opt.group_local + " > "; + label += opt.label_local; + return label; + }; + for (size_t i=0; i < options.size(); i++) { const Option &opt = options[i]; if (full_list) { - wxString label = opt.category_local + " > " + opt.group_local + " > " + opt.label_local; + wxString label = get_label(opt); found.emplace_back(FoundOption{ label, label, i, 0 }); continue; } @@ -200,7 +211,8 @@ bool OptionsSearcher::search(const std::string& search, bool force/* = false*/) FMFlag fuzzy_match_flag = opt.fuzzy_match(search, score); if (fuzzy_match_flag != fmUndef) { - wxString label = opt.category_local + " > " + opt.group_local + " > " + opt.label_local; + wxString label = get_label(opt); //opt.category_local + " > " + opt.group_local + " > " + opt.label_local; + if ( fuzzy_match_flag == fmLabel ) label += "(" + opt.label + ")"; else if (fuzzy_match_flag == fmGroup ) label += "(" + opt.group + ")"; else if (fuzzy_match_flag == fmCategory) label += "(" + opt.category + ")"; @@ -243,6 +255,81 @@ void OptionsSearcher::add_key(const std::string& opt_key, const wxString& group, } +//------------------------------------------ +// SearchComboPopup +//------------------------------------------ + + +void SearchComboPopup::Init() +{ + this->Bind(wxEVT_MOTION, &SearchComboPopup::OnMouseMove, this); + this->Bind(wxEVT_LEFT_UP, &SearchComboPopup::OnMouseClick, this); + this->Bind(wxEVT_KEY_DOWN, &SearchComboPopup::OnKeyDown, this); +} + +bool SearchComboPopup::Create(wxWindow* parent) +{ + return wxListBox::Create(parent, 1, wxPoint(0, 0), wxDefaultSize); +} + +void SearchComboPopup::SetStringValue(const wxString& s) +{ + int n = wxListBox::FindString(s); + if (n >= 0 && n < wxListBox::GetCount()) + wxListBox::Select(n); + + // save a combo control's string + m_input_string = s; +} + +void SearchComboPopup::ProcessSelection(int selection) +{ + wxCommandEvent event(wxEVT_LISTBOX, GetId()); + event.SetInt(selection); + event.SetEventObject(this); + ProcessEvent(event); + + Dismiss(); +} + +void SearchComboPopup::OnMouseMove(wxMouseEvent& event) +{ + wxPoint pt = wxGetMousePosition() - this->GetScreenPosition(); + int selection = this->HitTest(pt); + wxListBox::Select(selection); +} + +void SearchComboPopup::OnMouseClick(wxMouseEvent&) +{ + int selection = wxListBox::GetSelection(); + SetSelection(wxNOT_FOUND); + ProcessSelection(selection); +} + +void SearchComboPopup::OnKeyDown(wxKeyEvent& event) +{ + int key = event.GetKeyCode(); + + // change selected item in the list + if (key == WXK_UP || key == WXK_DOWN) + { + int selection = wxListBox::GetSelection(); + + if (key == WXK_UP && selection > 0) + selection--; + int last_item_id = int(wxListBox::GetCount() - 1); + if (key == WXK_DOWN && selection < int(wxListBox::GetCount() - 1)) + selection++; + + wxListBox::Select(selection); + } + // send wxEVT_LISTBOX event if "Enter" was pushed + else if (key == WXK_NUMPAD_ENTER || key == WXK_RETURN) + ProcessSelection(wxListBox::GetSelection()); + else + event.Skip(); // !Needed to have EVT_CHAR generated as well +} + //------------------------------------------ // SearchCtrl //------------------------------------------ @@ -266,7 +353,12 @@ SearchCtrl::SearchCtrl(wxWindow* parent) : this->Bind(wxEVT_TEXT, &SearchCtrl::OnInputText, this); this->Bind(wxEVT_TEXT_ENTER, &SearchCtrl::PopupList, this); this->Bind(wxEVT_COMBOBOX_DROPDOWN, &SearchCtrl::PopupList, this); - +/* + this->Bind(wxEVT_KEY_DOWN, [this](wxKeyEvent&e) + { + + }); +*/ this->GetTextCtrl()->Bind(wxEVT_LEFT_UP, &SearchCtrl::OnLeftUpInTextCtrl, this); popupListBox->Bind(wxEVT_LISTBOX, &SearchCtrl::OnSelect, this); } diff --git a/src/slic3r/GUI/Search.hpp b/src/slic3r/GUI/Search.hpp index 8488781a3..83df4136c 100644 --- a/src/slic3r/GUI/Search.hpp +++ b/src/slic3r/GUI/Search.hpp @@ -97,6 +97,9 @@ class OptionsSearcher size_t found_size() const { return found.size(); } public: + bool category{ false }; + bool group{ true }; + void init(std::vector input_values); bool search(const std::string& search, bool force = false); @@ -115,54 +118,30 @@ class SearchComboPopup : public wxListBox, public wxComboPopup { public: // Initialize member variables - virtual void Init() - { - this->Bind(wxEVT_MOTION, &SearchComboPopup::OnMouseMove, this); - this->Bind(wxEVT_LEFT_UP, &SearchComboPopup::OnMouseClick, this); - } + void Init(); // Create popup control - virtual bool Create(wxWindow* parent) - { - return wxListBox::Create(parent, 1, wxPoint(0, 0), wxDefaultSize); - } + virtual bool Create(wxWindow* parent); // Return pointer to the created control virtual wxWindow* GetControl() { return this; } - // Translate string into a list selection - virtual void SetStringValue(const wxString& s) - { - int n = wxListBox::FindString(s); - if (n >= 0 && n < wxListBox::GetCount()) - wxListBox::Select(n); - // save a combo control's string - m_input_string = s; - } + // Translate string into a list selection + virtual void SetStringValue(const wxString& s); // Get list selection as a string - virtual wxString GetStringValue() const - { + virtual wxString GetStringValue() const { // we shouldn't change a combo control's string return m_input_string; } - // Do mouse hot-tracking (which is typical in list popups) - void OnMouseMove(wxMouseEvent& event) - { - wxPoint pt = wxGetMousePosition() - this->GetScreenPosition(); - int selection = this->HitTest(pt); - wxListBox::Select(selection); - } - // On mouse left up, set the value and close the popup - void OnMouseClick(wxMouseEvent& WXUNUSED(event)) - { - int selection = wxListBox::GetSelection(); - SetSelection(wxNOT_FOUND); - wxCommandEvent event(wxEVT_LISTBOX, GetId()); - event.SetInt(selection); - event.SetEventObject(this); - ProcessEvent(event); - Dismiss(); - } + void ProcessSelection(int selection); + + // Do mouse hot-tracking (which is typical in list popups) + void OnMouseMove(wxMouseEvent& event); + // On mouse left up, set the value and close the popup + void OnMouseClick(wxMouseEvent& WXUNUSED(event)); + // process Up/Down arrows and Enter press + void OnKeyDown(wxKeyEvent& event); + protected: wxString m_input_string; };