From 5ca6b9f8d06843fd0deb6d9ab813c386dfb25183 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 3 Apr 2020 10:01:23 +0200 Subject: [PATCH] Implemented SearchCtrl class instead of SearchComboBox Search string are synchronized between Plater and Tabs. List with options and filtered list are in Sidebar. All options list on tabs and Plater use this data from Sidebar Note: SearchComboBox.cpp(hpp) was renamed to Search.cpp(hpp) --- resources/icons/search.svg | 5 +- src/slic3r/CMakeLists.txt | 4 +- src/slic3r/GUI/GLCanvas3D.cpp | 2 +- src/slic3r/GUI/Plater.cpp | 17 +- src/slic3r/GUI/Plater.hpp | 3 +- .../GUI/{SearchComboBox.cpp => Search.cpp} | 204 ++++++++++++++++-- .../GUI/{SearchComboBox.hpp => Search.hpp} | 70 +++++- src/slic3r/GUI/Tab.cpp | 17 +- src/slic3r/GUI/Tab.hpp | 9 +- 9 files changed, 283 insertions(+), 48 deletions(-) rename src/slic3r/GUI/{SearchComboBox.cpp => Search.cpp} (65%) rename src/slic3r/GUI/{SearchComboBox.hpp => Search.hpp} (67%) diff --git a/resources/icons/search.svg b/resources/icons/search.svg index bf97904e8..6421c7e05 100644 --- a/resources/icons/search.svg +++ b/resources/icons/search.svg @@ -1 +1,4 @@ - \ No newline at end of file + + + + \ No newline at end of file diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 7aaa1e622..bf30eb15e 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -151,8 +151,8 @@ set(SLIC3R_GUI_SOURCES GUI/DoubleSlider.hpp GUI/ObjectDataViewModel.cpp GUI/ObjectDataViewModel.hpp - GUI/SearchComboBox.cpp - GUI/SearchComboBox.hpp + GUI/Search.cpp + GUI/Search.hpp Utils/Http.cpp Utils/Http.hpp Utils/FixModelByWin10.cpp diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 470aafe23..0f9d49281 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -4477,7 +4477,7 @@ bool GLCanvas3D::_render_search_list(float pos_x) const std::string& search_line = wxGetApp().sidebar().get_search_line(); char *s = new char[255]; - strcpy(s, search_line.empty() ? _utf8(L("Type here to search")).c_str() : search_line.c_str()); + strcpy(s, search_line.empty() ? _u8L("Type here to search").c_str() : search_line.c_str()); imgui->search_list(ImVec2(22 * em, 30 * em), &search_string_getter, s, selected, edited); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index d270b6e0d..acf762bfb 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -80,7 +80,6 @@ #include "../Utils/FixModelByWin10.hpp" #include "../Utils/UndoRedo.hpp" #include "RemovableDriveManager.hpp" -#include "SearchComboBox.hpp" #if ENABLE_NON_STATIC_CANVAS_MANAGER #ifdef __APPLE__ @@ -1095,6 +1094,7 @@ void Sidebar::msw_rescale() void Sidebar::apply_search_filter() { p->search_list.apply_filters(p->search_line); + apply_search_line_on_tabs(); } void Sidebar::jump_to_option(size_t selected) @@ -1373,16 +1373,21 @@ static std::vector get_search_inputs(ConfigOptionMode mode) return ret; } -void Sidebar::update_search_list() +void Sidebar::apply_search_line_on_tabs() { - p->search_list.init(get_search_inputs(m_mode)); - auto& tabs_list = wxGetApp().tabs_list; auto print_tech = wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology(); for (auto tab : tabs_list) if (tab->supports_printer_technology(print_tech)) - tab->get_search_cb()->init(p->search_list); + //tab->get_search_cb()->update_combobox(); + tab->set_search_line(p->search_line); +} + +void Sidebar::update_search_list() +{ + p->search_list.init(get_search_inputs(m_mode)); + apply_search_line_on_tabs(); } void Sidebar::update_mode() @@ -5345,7 +5350,7 @@ bool Plater::search_string_getter(int idx, const char** out_text) const SearchOptions& search_list = p->sidebar->get_search_list(); if (0 <= idx && (size_t)idx < search_list.size()) { - search_list[idx].get_label(out_text); + search_list[idx].get_marked_label(out_text); return true; } diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 1fb0eab30..6544d4554 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -12,7 +12,7 @@ #include "libslic3r/BoundingBox.hpp" #include "wxExtensions.hpp" -#include "SearchComboBox.hpp" +#include "Search.hpp" class wxButton; class ScalableButton; @@ -132,6 +132,7 @@ public: void update_mode(); bool is_collapsed(); void collapse(bool collapse); + void apply_search_line_on_tabs(); void update_search_list(); std::vector& combos_filament(); diff --git a/src/slic3r/GUI/SearchComboBox.cpp b/src/slic3r/GUI/Search.cpp similarity index 65% rename from src/slic3r/GUI/SearchComboBox.cpp rename to src/slic3r/GUI/Search.cpp index 1e1ab738f..f3a0386b5 100644 --- a/src/slic3r/GUI/SearchComboBox.cpp +++ b/src/slic3r/GUI/Search.cpp @@ -1,4 +1,4 @@ -#include "SearchComboBox.hpp" +#include "Search.hpp" #include #include @@ -13,8 +13,7 @@ #include #include -#include -#include +//#include #include "libslic3r/PrintConfig.hpp" #include "GUI_App.hpp" #include "Tab.hpp" @@ -77,6 +76,11 @@ void SearchOptions::Filter::get_label(const char** out_text) const *out_text = label.utf8_str(); } +void SearchOptions::Filter::get_marked_label(const char** out_text) const +{ + *out_text = marked_label.utf8_str(); +} + template void change_opt_key(std::string& opt_key, DynamicPrintConfig* config) { @@ -169,18 +173,18 @@ void SearchOptions::apply_filters(const std::string& search) for (size_t i=0; i < options.size(); i++) { if (full_list) { - filters.emplace_back(Filter{ options[i].label, i, 0 }); + filters.emplace_back(Filter{ options[i].label, options[i].label, i, 0 }); continue; } int score = 0; if (options[i].fuzzy_match_simple(search)/*fuzzy_match(search, score)*/) { - wxString label = options[i].label; - mark_string(label, from_u8(search)); - clear_marked_string(label); + wxString marked_label = options[i].label; + mark_string(marked_label, from_u8(search)); + clear_marked_string(marked_label); - filters.emplace_back(Filter{ label, i, score }); + filters.emplace_back(Filter{ options[i].label, marked_label, i, score }); } } @@ -203,23 +207,24 @@ const SearchOptions::Option& SearchOptions::get_option(size_t pos_in_filter) con assert(pos_in_filter != size_t(-1) && filters[pos_in_filter].option_idx != size_t(-1)); return options[filters[pos_in_filter].option_idx]; } - -SearchComboBox::SearchComboBox(wxWindow *parent) : +/* +SearchComboBox::SearchComboBox(wxWindow *parent, SearchOptions& search_list) : wxBitmapComboBox(parent, wxID_ANY, _(L("Type here to search")) + dots, wxDefaultPosition, wxSize(25 * wxGetApp().em_unit(), -1)), - em_unit(wxGetApp().em_unit()) + em_unit(wxGetApp().em_unit()), + search_list(search_list) { SetFont(wxGetApp().normal_font()); default_search_line = search_line = _(L("Type here to search")) + dots; bmp = ScalableBitmap(this, "search"); -#ifdef _WIN32 - // Workaround for ignoring CBN_EDITCHANGE events, which are processed after the content of the combo box changes, so that - // the index of the item inside CBN_EDITCHANGE may no more be valid. -// EnableTextChangedEvents(false); -#endif /* _WIN32 */ - Bind(wxEVT_COMBOBOX, [this](wxCommandEvent &evt) { auto selected_item = this->GetSelection(); + if (selected_item < 0) + return; + + wxGetApp().sidebar().jump_to_option(selected_item); + + return; SearchOptions::Option* opt = reinterpret_cast(this->GetClientData(selected_item)); wxGetApp().get_tab(opt->type)->activate_option(opt->opt_key, opt->category); @@ -230,7 +235,7 @@ wxBitmapComboBox(parent, wxID_ANY, _(L("Type here to search")) + dots, wxDefault }); Bind(wxEVT_TEXT, [this](wxCommandEvent &e) { - if (prevent_update) +/* if (prevent_update) return; if (this->IsTextEmpty()) @@ -238,7 +243,10 @@ wxBitmapComboBox(parent, wxID_ANY, _(L("Type here to search")) + dots, wxDefault return; } - if (search_line != this->GetValue()) { + * / if (search_line != this->GetValue()) { + std::string& search_str = wxGetApp().sidebar().get_search_line(); + search_str = into_u8(this->GetValue()); + wxGetApp().sidebar().apply_search_filter(); update_combobox(); search_line = this->GetValue(); } @@ -293,6 +301,14 @@ void SearchComboBox::init(const SearchOptions& new_search_list) void SearchComboBox::update_combobox() { + this->Clear(); + for (const SearchOptions::Filter& item : search_list.filters) + append(item.label); + +// SuppressUpdate su(this); +// this->SetValue(default_search_line); + + return; wxString search_str = this->GetValue(); if (search_str.IsEmpty() || search_str == default_search_line) // add whole options list to the controll @@ -322,7 +338,7 @@ void SearchComboBox::append_items(const wxString& search) if (it != search_list.options.end()) append(it->label, (void*)(&(*it))); } -*/ +* / for (const SearchOptions::Option& option : search_list.options) if (option.fuzzy_match_simple(search)) @@ -332,5 +348,153 @@ void SearchComboBox::append_items(const wxString& search) this->SetValue(search); this->SetInsertionPointEnd(); } +*/ + +//------------------------------------------ +// PopupSearchList +//------------------------------------------ + +PopupSearchList::PopupSearchList(wxWindow* parent) : + wxPopupTransientWindow(parent) +{ + panel = new wxPanel(this, wxID_ANY); + + int em_unit = wxGetApp().em_unit(); + + search_ctrl = new wxListCtrl(panel, wxID_ANY, wxDefaultPosition, wxSize(25 * em_unit, 35 * em_unit), wxLC_NO_HEADER | wxLC_REPORT); + search_ctrl->AppendColumn(""); + search_ctrl->SetColumnWidth(0, 23 * em_unit); + search_ctrl->Bind(wxEVT_LIST_ITEM_SELECTED, &PopupSearchList::OnSelect, this); + + wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL); + + topSizer->Add(search_ctrl, 0, wxEXPAND | wxALL, 2); + + panel->SetSizer(topSizer); + + topSizer->Fit(panel); + SetClientSize(panel->GetSize()); +} + +void PopupSearchList::Popup(wxWindow* WXUNUSED(focus)) +{ + wxPopupTransientWindow::Popup(); +} + +void PopupSearchList::OnDismiss() +{ + wxPopupTransientWindow::OnDismiss(); +} + +bool PopupSearchList::ProcessLeftDown(wxMouseEvent& event) +{ + return wxPopupTransientWindow::ProcessLeftDown(event); +} +bool PopupSearchList::Show(bool show) +{ + return wxPopupTransientWindow::Show(show); +} + +void PopupSearchList::OnSize(wxSizeEvent& event) +{ + event.Skip(); +} + +void PopupSearchList::OnSetFocus(wxFocusEvent& event) +{ + event.Skip(); +} + +void PopupSearchList::OnKillFocus(wxFocusEvent& event) +{ + event.Skip(); +} + +void PopupSearchList::OnSelect(wxListEvent& event) +{ + int selection = event.GetIndex(); + if (selection>=0) + wxGetApp().sidebar().jump_to_option(selection); + + OnDismiss(); +} + +void PopupSearchList::update_list(std::vector& filters) +{ + search_ctrl->DeleteAllItems(); + for (const SearchOptions::Filter& item : filters) + search_ctrl->InsertItem(search_ctrl->GetItemCount(), item.label); +} + + +//------------------------------------------ +// SearchCtrl +//------------------------------------------ + +SearchCtrl::SearchCtrl(wxWindow* parent): + parent(parent) +{ + popup_win = new PopupSearchList(parent); + box_sizer = new wxBoxSizer(wxHORIZONTAL); + + search_line = new wxTextCtrl(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(25 * wxGetApp().em_unit(), -1), wxTE_PROCESS_ENTER); + search_line->Bind(wxEVT_TEXT, &SearchCtrl::OnInputText, this); + search_line->Bind(wxEVT_TEXT_ENTER, &SearchCtrl::PopupList, this); + + search_btn = new ScalableButton(parent, wxID_ANY, "search"); + search_btn->Bind(wxEVT_BUTTON, &SearchCtrl::PopupList, this); + + box_sizer->Add(search_line, 0, wxALIGN_CENTER_VERTICAL); + box_sizer->AddSpacer(5); + box_sizer->Add(search_btn, 0, wxALIGN_CENTER_VERTICAL); +} + +SearchCtrl::~SearchCtrl() +{ + if (search_btn) + search_btn->Destroy(); + if (popup_win) + popup_win->Destroy(); +} + +void SearchCtrl::OnInputText(wxCommandEvent& ) +{ + if (prevent_update) + return; + std::string& search_str = wxGetApp().sidebar().get_search_line(); + search_str = into_u8(search_line->GetValue()); + wxGetApp().sidebar().apply_search_filter(); + + popup_win->update_list(wxGetApp().sidebar().get_search_list().filters); +} + +void SearchCtrl::PopupList(wxCommandEvent& ) +{ + popup_win->update_list(wxGetApp().sidebar().get_search_list().filters); + + wxPoint pos = search_line->ClientToScreen(wxPoint(0, 0)); + wxSize sz = search_line->GetSize(); + pos.x -= sz.GetWidth(); + popup_win->Position(pos, sz); + + popup_win->Popup(); +} + +void SearchCtrl::set_search_line(const std::string& line) +{ + prevent_update = true; + search_line->SetValue(line.empty() ? _L("Type here to search") : from_u8(line)); + prevent_update = false; +} + +void SearchCtrl::msw_rescale() +{ + wxSize size = wxSize(25 * wxGetApp().em_unit(), -1); + // Set rescaled min height to correct layout + search_line->SetMinSize(size); + // Set rescaled size + search_btn->msw_rescale(); +} + }} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/SearchComboBox.hpp b/src/slic3r/GUI/Search.hpp similarity index 67% rename from src/slic3r/GUI/SearchComboBox.hpp rename to src/slic3r/GUI/Search.hpp index 294395b72..6718f3af1 100644 --- a/src/slic3r/GUI/SearchComboBox.hpp +++ b/src/slic3r/GUI/Search.hpp @@ -1,11 +1,13 @@ #ifndef slic3r_SearchComboBox_hpp_ #define slic3r_SearchComboBox_hpp_ -#include #include -#include -#include +#include +#include +//#include +#include +#include #include "Preset.hpp" #include "wxExtensions.hpp" @@ -46,15 +48,20 @@ public: struct Filter { wxString label; + wxString marked_label; size_t option_idx {0}; int outScore {0}; void get_label(const char** out_text) const; + void get_marked_label(const char** out_text) const; }; std::vector filters {}; void clear_options() { options.clear(); } void clear_filters() { filters.clear(); } + + void init(std::vector input_values); + void append_options(DynamicPrintConfig* config, Preset::Type type, ConfigOptionMode mode); void apply_filters(const std::string& search); @@ -67,16 +74,14 @@ public: return f1.outScore > f2.outScore; }); }; - void init(std::vector input_values); size_t options_size() const { return options.size(); } size_t filters_size() const { return filters.size(); } - size_t size() const { return filters_size(); } const Filter& operator[](const size_t pos) const noexcept { return filters[pos]; } const Option& get_option(size_t pos_in_filter) const; }; - +/* class SearchComboBox : public wxBitmapComboBox { class SuppressUpdate @@ -89,9 +94,10 @@ class SearchComboBox : public wxBitmapComboBox }; public: - SearchComboBox(wxWindow *parent); + SearchComboBox(wxWindow *parent, SearchOptions& search_list); ~SearchComboBox(); + int append(const wxString& item) { return Append(item, bmp.bmp()); } int append(const wxString& item, void* clientData) { return Append(item, bmp.bmp(), clientData); } int append(const wxString& item, wxClientData* clientData) { return Append(item, bmp.bmp(), clientData); } @@ -105,8 +111,9 @@ public: void init(const SearchOptions& new_search_list); void update_combobox(); + private: - SearchOptions search_list; + SearchOptions& search_list; wxString default_search_line; wxString search_line; @@ -115,6 +122,53 @@ private: ScalableBitmap bmp; }; +*/ +class PopupSearchList : public wxPopupTransientWindow +{ +public: + PopupSearchList(wxWindow* parent); + ~PopupSearchList() {} + + // wxPopupTransientWindow virtual methods are all overridden to log them + void Popup(wxWindow* focus = NULL) wxOVERRIDE; + void OnDismiss() wxOVERRIDE; + bool ProcessLeftDown(wxMouseEvent& event) wxOVERRIDE; + bool Show(bool show = true) wxOVERRIDE; + + void update_list(std::vector& filters); + +private: + wxWindow* panel; + wxListCtrl* search_ctrl{ nullptr }; + + void OnSize(wxSizeEvent& event); + void OnSetFocus(wxFocusEvent& event); + void OnKillFocus(wxFocusEvent& event); + void OnSelect(wxListEvent& event); +}; + +class SearchCtrl +{ + wxWindow* parent {nullptr}; + wxBoxSizer* box_sizer {nullptr}; + wxTextCtrl* search_line {nullptr}; + ScalableButton* search_btn {nullptr}; + PopupSearchList* popup_win {nullptr}; + + bool prevent_update{ false }; + + void PopupList(wxCommandEvent& event); + void OnInputText(wxCommandEvent& event); + +public: + SearchCtrl(wxWindow* parent); + ~SearchCtrl(); + + wxBoxSizer* sizer() const { return box_sizer; } + + void set_search_line(const std::string& search_line); + void msw_rescale(); +}; }} diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 16ee6a789..17bb68d02 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -116,7 +116,8 @@ void Tab::create_preset_tab() m_presets_choice = new PresetBitmapComboBox(panel, wxSize(35 * m_em_unit, -1)); // search combox - m_search_cb = new SearchComboBox(panel); +// m_search_cb = new SearchComboBox(panel, wxGetApp().sidebar().get_search_list()); + m_search = new SearchCtrl(panel); auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); @@ -198,7 +199,8 @@ void Tab::create_preset_tab() m_hsizer->Add(m_undo_to_sys_btn, 0, wxALIGN_CENTER_VERTICAL); m_hsizer->Add(m_undo_btn, 0, wxALIGN_CENTER_VERTICAL); m_hsizer->AddSpacer(int(/*32*/16 * scale_factor)); - m_hsizer->Add(m_search_cb, 0, wxALIGN_CENTER_VERTICAL); +// m_hsizer->Add(m_search_cb, 0, wxALIGN_CENTER_VERTICAL); + m_hsizer->Add(m_search->sizer(), 0, wxALIGN_CENTER_VERTICAL); m_hsizer->AddSpacer(int(16 * scale_factor)); // m_hsizer->AddSpacer(int(32 * scale_factor)); // m_hsizer->Add(m_question_btn, 0, wxALIGN_CENTER_VERTICAL); @@ -767,9 +769,6 @@ void Tab::update_mode() update_visibility(); update_changed_tree_ui(); - - // update list of options for search -// m_search_cb->init(m_config, type(), m_mode); } void Tab::update_visibility() @@ -796,7 +795,8 @@ void Tab::msw_rescale() m_em_unit = wxGetApp().em_unit(); m_mode_sizer->msw_rescale(); - m_search_cb->msw_rescale(); +// m_search_cb->msw_rescale(); + m_search->msw_rescale(); m_presets_choice->SetSize(35 * m_em_unit, -1); m_treectrl->SetMinSize(wxSize(20 * m_em_unit, -1)); @@ -899,6 +899,11 @@ static wxString pad_combo_value_for_config(const DynamicPrintConfig &config) return config.opt_bool("pad_enable") ? (config.opt_bool("pad_around_object") ? _("Around object") : _("Below object")) : _("None"); } +void Tab::set_search_line(const std::string& search_line) +{ + m_search->set_search_line(search_line); +} + void Tab::on_value_change(const std::string& opt_key, const boost::any& value) { if (wxGetApp().plater() == nullptr) { diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 705a806a3..fe683b49f 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -33,7 +33,7 @@ #include "Event.hpp" #include "wxExtensions.hpp" #include "ConfigManipulation.hpp" -#include "SearchComboBox.hpp" +#include "Search.hpp" namespace Slic3r { namespace GUI { @@ -122,7 +122,8 @@ protected: std::string m_name; const wxString m_title; PresetBitmapComboBox* m_presets_choice; - SearchComboBox* m_search_cb; +// SearchComboBox* m_search_cb; + SearchCtrl* m_search; ScalableButton* m_btn_save_preset; ScalableButton* m_btn_delete_preset; ScalableButton* m_btn_hide_incompatible_presets; @@ -308,9 +309,11 @@ public: DynamicPrintConfig* get_config() { return m_config; } PresetCollection* get_presets() { return m_presets; } - SearchComboBox* get_search_cb() { return m_search_cb; } +// SearchComboBox* get_search_cb() { return m_search_cb; } size_t get_selected_preset_item() { return m_selected_preset_item; } + void set_search_line(const std::string& search_line); + void on_value_change(const std::string& opt_key, const boost::any& value); void update_wiping_button_visibility();