1 #ifndef slic3r_SearchComboBox_hpp_ 2 #define slic3r_SearchComboBox_hpp_ 3 4 #include <vector> 5 #include <map> 6 7 #include <wx/panel.h> 8 #include <wx/sizer.h> 9 #include <wx/listctrl.h> 10 11 #include <wx/combo.h> 12 13 #include <wx/checkbox.h> 14 #include <wx/dialog.h> 15 16 #include "GUI_Utils.hpp" 17 #include "wxExtensions.hpp" 18 #include "libslic3r/Preset.hpp" 19 20 21 namespace Slic3r { 22 23 namespace Search{ 24 25 class SearchDialog; 26 27 struct InputInfo 28 { 29 DynamicPrintConfig* config {nullptr}; 30 Preset::Type type {Preset::TYPE_INVALID}; 31 ConfigOptionMode mode {comSimple}; 32 }; 33 34 struct GroupAndCategory { 35 wxString group; 36 wxString category; 37 }; 38 39 struct Option { 40 // bool operator<(const Option& other) const { return other.label > this->label; } operator <Slic3r::Search::Option41 bool operator<(const Option& other) const { return other.opt_key > this->opt_key; } 42 43 // Fuzzy matching works at a character level. Thus matching with wide characters is a safer bet than with short characters, 44 // though for some languages (Chinese?) it may not work correctly. 45 std::wstring opt_key; 46 Preset::Type type {Preset::TYPE_INVALID}; 47 std::wstring label; 48 std::wstring label_local; 49 std::wstring group; 50 std::wstring group_local; 51 std::wstring category; 52 std::wstring category_local; 53 }; 54 55 struct FoundOption { 56 // UTF8 encoding, to be consumed by ImGUI by reference. 57 std::string label; 58 std::string marked_label; 59 std::string tooltip; 60 size_t option_idx {0}; 61 int outScore {0}; 62 63 // Returning pointers to contents of std::string members, to be used by ImGUI for rendering. 64 void get_marked_label_and_tooltip(const char** label, const char** tooltip) const; 65 }; 66 67 struct OptionViewParameters 68 { 69 bool category {false}; 70 bool english {false}; 71 72 int hovered_id {0}; 73 }; 74 75 class OptionsSearcher 76 { 77 std::string search_line; 78 std::map<std::string, GroupAndCategory> groups_and_categories; 79 PrinterTechnology printer_technology; 80 81 std::vector<Option> options {}; 82 std::vector<FoundOption> found {}; 83 84 void append_options(DynamicPrintConfig* config, Preset::Type type, ConfigOptionMode mode); 85 sort_options()86 void sort_options() { 87 std::sort(options.begin(), options.end(), [](const Option& o1, const Option& o2) { 88 return o1.label < o2.label; }); 89 } sort_found()90 void sort_found() { 91 std::sort(found.begin(), found.end(), [](const FoundOption& f1, const FoundOption& f2) { 92 return f1.outScore > f2.outScore || (f1.outScore == f2.outScore && f1.label < f2.label); }); 93 }; 94 options_size() const95 size_t options_size() const { return options.size(); } found_size() const96 size_t found_size() const { return found.size(); } 97 98 public: 99 OptionViewParameters view_params; 100 101 SearchDialog* search_dialog { nullptr }; 102 103 OptionsSearcher(); 104 ~OptionsSearcher(); 105 106 void init(std::vector<InputInfo> input_values); 107 void apply(DynamicPrintConfig *config, 108 Preset::Type type, 109 ConfigOptionMode mode); 110 bool search(); 111 bool search(const std::string& search, bool force = false); 112 113 void add_key(const std::string& opt_key, const wxString& group, const wxString& category); 114 size() const115 size_t size() const { return found_size(); } 116 operator [](const size_t pos) const117 const FoundOption& operator[](const size_t pos) const noexcept { return found[pos]; } 118 const Option& get_option(size_t pos_in_filter) const; 119 const Option& get_option(const std::string& opt_key) const; 120 found_options()121 const std::vector<FoundOption>& found_options() { return found; } get_group_and_category(const std::string & opt_key)122 const GroupAndCategory& get_group_and_category (const std::string& opt_key) { return groups_and_categories[opt_key]; } search_string()123 std::string& search_string() { return search_line; } 124 set_printer_technology(PrinterTechnology pt)125 void set_printer_technology(PrinterTechnology pt) { printer_technology = pt; } 126 sort_options_by_opt_key()127 void sort_options_by_opt_key() { 128 std::sort(options.begin(), options.end(), [](const Option& o1, const Option& o2) { 129 return o1.opt_key < o2.opt_key; }); 130 } 131 }; 132 133 134 //------------------------------------------ 135 // SearchDialog 136 //------------------------------------------ 137 class SearchListModel; 138 class SearchDialog : public GUI::DPIDialog 139 { 140 wxString search_str; 141 wxString default_string; 142 143 bool prevent_list_events {false}; 144 145 wxTextCtrl* search_line { nullptr }; 146 wxDataViewCtrl* search_list { nullptr }; 147 SearchListModel* search_list_model { nullptr }; 148 wxCheckBox* check_category { nullptr }; 149 wxCheckBox* check_english { nullptr }; 150 151 OptionsSearcher* searcher { nullptr }; 152 153 void OnInputText(wxCommandEvent& event); 154 void OnLeftUpInTextCtrl(wxEvent& event); 155 void OnKeyDown(wxKeyEvent& event); 156 157 void OnActivate(wxDataViewEvent& event); 158 void OnSelect(wxDataViewEvent& event); 159 160 void OnCheck(wxCommandEvent& event); 161 void OnMotion(wxMouseEvent& event); 162 void OnLeftDown(wxMouseEvent& event); 163 164 void update_list(); 165 166 public: 167 SearchDialog(OptionsSearcher* searcher); ~SearchDialog()168 ~SearchDialog() {} 169 170 void Popup(wxPoint position = wxDefaultPosition); 171 void ProcessSelection(wxDataViewItem selection); 172 173 protected: 174 void on_dpi_changed(const wxRect& suggested_rect) override; 175 void on_sys_color_changed() override; 176 }; 177 178 179 // ---------------------------------------------------------------------------- 180 // SearchListModel 181 // ---------------------------------------------------------------------------- 182 183 class SearchListModel : public wxDataViewVirtualListModel 184 { 185 std::vector<std::pair<wxString, int>> m_values; 186 ScalableBitmap m_icon[5]; 187 188 public: 189 enum { 190 colIcon, 191 colMarkedText, 192 colMax 193 }; 194 195 SearchListModel(wxWindow* parent); 196 197 // helper methods to change the model 198 199 void Clear(); 200 void Prepend(const std::string& text); 201 void msw_rescale(); 202 203 // implementation of base class virtuals to define model 204 GetColumnCount() const205 unsigned int GetColumnCount() const override { return colMax; } 206 wxString GetColumnType(unsigned int col) const override; 207 void GetValueByRow(wxVariant& variant, unsigned int row, unsigned int col) const override; GetAttrByRow(unsigned int row,unsigned int col,wxDataViewItemAttr & attr) const208 bool GetAttrByRow(unsigned int row, unsigned int col, wxDataViewItemAttr& attr) const override { return true; } SetValueByRow(const wxVariant & variant,unsigned int row,unsigned int col)209 bool SetValueByRow(const wxVariant& variant, unsigned int row, unsigned int col) override { return false; } 210 }; 211 212 213 214 215 } // Search namespace 216 } 217 218 #endif //slic3r_SearchComboBox_hpp_ 219