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();