Files
OrcaSlicer/src/slic3r/GUI/Search.hpp
T
Kris AustinandRodrigo Faselli cbd1bf2c37 build: clear 295 more -Woverloaded-virtual warnings in GUI widgets (#15394)
build: clear 295 -Woverloaded-virtual warnings in GUI widgets

Turns three hidden base virtuals into real overrides, clearing 295 of
the 553 -Woverloaded-virtual warnings and taking a full clang-cl build
from 1,264 to 969. Part of #15374.

Search.hpp: SearchDialog::Popup and SearchObjectDialog::Popup took a
wxPoint that neither body ever read, hiding the virtual
wxPopupTransientWindow::Popup(wxWindow*). Both bodies clear the input,
call the base, set focus and refill the list, and SearchObjectDialog
also guards re-entry, so hiding meant none of that ran when the window
was popped through a base pointer. They now override and forward focus.

LabeledStaticBox::SetFont and ScrolledWindow::SetBackgroundColour hid
their base virtuals the same way, so the label metrics recompute and
the child colour propagation only ran for callers holding the concrete
type. Both now override.

Marking a member override makes clang flag every other unmarked
override in the same class, so seven sibling declarations needed the
keyword too. Left unmarked they were worth 481 warnings, which would
have made this a net loss.

MSWDismissUnfocusedPopup is declared only inside #ifdef __WXMSW__ in
wx/popupwin.h, so off Windows there is no base virtual to override and
the keyword would not compile. Both the declarations and the definitions
are guarded, which is how wxWidgets itself declares MSWWindowProc in
wx/nativewin.h and how this repo already handles it in BBLTopbar,
MainFrame, Button, ComboBox and TabCtrl.

ScrolledWindow's constructor left m_userPanel and m_scroll_win
uninitialised unless the style requested a vertical scrollbar, while
SetBackgroundColour dereferences both. No caller hits that today since
every instantiation passes wxVSCROLL, but the override widens who can
reach them, so they are now initialised alongside their siblings.

Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
2026-08-27 08:06:50 -03:00

308 lines
9.1 KiB
C++

#ifndef slic3r_SearchComboBox_hpp_
#define slic3r_SearchComboBox_hpp_
#include <vector>
#include <map>
#include <boost/nowide/convert.hpp>
#include <wx/panel.h>
#include <wx/sizer.h>
#include <wx/listctrl.h>
#include <wx/combo.h>
#include <wx/checkbox.h>
#include <wx/dialog.h>
#include <wx/srchctrl.h>
#include "wxExtensions.hpp"
#include "GUI_Utils.hpp"
#include "libslic3r/Preset.hpp"
#include "Widgets/ScrolledWindow.hpp"
#include "Widgets/TextInput.hpp"
#include "Widgets/PopupWindow.hpp"
#include "GUI_ObjectList.hpp"
namespace Slic3r {
wxDECLARE_EVENT(wxCUSTOMEVT_JUMP_TO_OPTION, wxCommandEvent);
wxDECLARE_EVENT(wxCUSTOMEVT_EXIT_SEARCH, wxCommandEvent);
wxDECLARE_EVENT(wxCUSTOMEVT_JUMP_TO_OBJECT, wxCommandEvent);
namespace Search {
class SearchDialog;
struct InputInfo
{
DynamicPrintConfig *config{nullptr};
Preset::Type type{Preset::TYPE_INVALID};
ConfigOptionMode mode{comSimple};
};
struct GroupAndCategory
{
wxString group;
wxString category;
};
struct Option
{
// bool operator<(const Option& other) const { return other.label > this->label; }
bool operator<(const Option &other) const { return other.key > this->key; }
// Fuzzy matching works at a character level. Thus matching with wide characters is a safer bet than with short characters,
// though for some languages (Chinese?) it may not work correctly.
std::wstring key;
Preset::Type type{Preset::TYPE_INVALID};
std::wstring label;
std::wstring label_local;
std::wstring group;
std::wstring group_local;
std::wstring category;
std::wstring category_local;
bool multi_category { false };
std::string opt_key() const;
};
struct FoundOption
{
// UTF8 encoding, to be consumed by ImGUI by reference.
std::string label;
std::string marked_label;
std::string tooltip;
size_t option_idx{0};
int outScore{0};
// Returning pointers to contents of std::string members, to be used by ImGUI for rendering.
void get_marked_label_and_tooltip(const char **label, const char **tooltip) const;
};
struct OptionViewParameters
{
bool category{false};
bool english{false};
int hovered_id{0};
};
class OptionsSearcher
{
std::string search_line;
Preset::Type search_type = Preset::TYPE_INVALID;
std::map<std::string, GroupAndCategory> groups_and_categories;
PrinterTechnology printer_technology;
std::vector<Option> options{};
std::vector<FoundOption> found{};
void append_options(DynamicPrintConfig *config, Preset::Type type, ConfigOptionMode mode);
void sort_options();
void sort_found()
{
std::sort(found.begin(), found.end(),
[](const FoundOption &f1, const FoundOption &f2) { return f1.outScore > f2.outScore || (f1.outScore == f2.outScore && f1.label < f2.label); });
};
size_t options_size() const { return options.size(); }
size_t found_size() const { return found.size(); }
public:
OptionViewParameters view_params;
SearchDialog *search_dialog{nullptr};
OptionsSearcher();
~OptionsSearcher();
void init(std::vector<InputInfo> input_values);
void apply(DynamicPrintConfig *config, Preset::Type type, ConfigOptionMode mode);
bool search();
bool search(const std::string &search, bool force = false, Preset::Type type = Preset::TYPE_INVALID);
void add_key(const std::string &opt_key, Preset::Type type, const wxString &group, const wxString &category);
size_t size() const { return found_size(); }
const FoundOption &operator[](const size_t pos) const noexcept { return found[pos]; }
const Option & get_option(size_t pos_in_filter) const;
const Option & get_option(const std::string &opt_key, Preset::Type type, int &variant_index) const;
Option get_option(const std::string &opt_key, const wxString &label, Preset::Type type) const;
const std::vector<FoundOption> &found_options() { return found; }
const GroupAndCategory & get_group_and_category(const std::string &opt_key) { return groups_and_categories[opt_key]; }
std::string & search_string() { return search_line; }
void set_printer_technology(PrinterTechnology pt) { printer_technology = pt; }
void sort_options_by_key()
{
std::sort(options.begin(), options.end(), [](const Option &o1, const Option &o2) { return o1.key < o2.key; });
}
void sort_options_by_label() { sort_options(); }
void show_dialog(Preset::Type type, wxWindow *parent, TextInput *input, wxWindow *ssearch_btn);
void dlg_sys_color_changed();
void dlg_msw_rescale();
};
//------------------------------------------
// SearchDialog
//------------------------------------------
class SearchDialog;
class SearchObjectDialog;
class SearchItem : public wxWindow
{
public:
wxString m_text;
int m_index;
SearchDialog* m_sdialog{ nullptr };
SearchObjectDialog* m_search_object_dialog{ nullptr };
GUI::ObjectDataViewModelNode* m_item{ nullptr };
SearchItem(wxWindow *parent, wxString text, int index, SearchDialog *sdialog = nullptr, SearchObjectDialog* search_dialog = nullptr, wxString tooltip = "");
~SearchItem(){};
wxSize DrawTextString(wxDC &dc, const wxString &text, const wxPoint &pt, bool bold);
void OnPaint(wxPaintEvent &event);
void on_mouse_enter(wxMouseEvent &evt);
void on_mouse_leave(wxMouseEvent &evt);
void on_mouse_left_down(wxMouseEvent &evt);
void on_mouse_left_up(wxMouseEvent &evt);
};
//------------------------------------------
// SearchDialog
//------------------------------------------
class SearchListModel;
class SearchDialog : public PopupWindow
{
public:
wxColour m_bg_colour;
wxColour m_thumb_color;
wxBoxSizer *m_sizer_body{nullptr};
wxBoxSizer *m_sizer_main{nullptr};
wxBoxSizer *m_sizer_border{nullptr};
wxWindow *m_border_panel{nullptr};
wxWindow *m_client_panel{nullptr};
wxWindow *m_event_tag{nullptr};
wxWindow *m_search_item_tag{nullptr};
int em;
const int POPUP_WIDTH = 38;
const int POPUP_HEIGHT = 40;
TextInput * search_line{nullptr};
wxTextCtrl * search_line2{nullptr};
Preset::Type search_type = Preset::TYPE_INVALID;
ScrolledWindow * m_scrolledWindow{nullptr};
OptionsSearcher *searcher{nullptr};
void OnInputText(wxCommandEvent &event);
void OnLeftUpInTextCtrl(wxEvent &event);
void update_list();
public:
SearchDialog(OptionsSearcher *searcher, Preset::Type type, wxWindow *parent, TextInput *input, wxWindow *search_btn);
~SearchDialog();
#ifdef __WXMSW__
void MSWDismissUnfocusedPopup() override;
#endif // __WXMSW__
void Popup(wxWindow *focus = nullptr) override;
void OnDismiss() override;
void Dismiss() override;
void Die();
void msw_rescale();
};
// ----------------------------------------------------------------------------
// SearchListModel
// ----------------------------------------------------------------------------
class SearchListModel : public wxDataViewVirtualListModel
{
std::vector<std::pair<wxString, int>> m_values;
ScalableBitmap m_icon[5];
public:
enum { colIcon, colMarkedText, colMax };
SearchListModel(wxWindow *parent);
// helper methods to change the model
void Clear();
void Prepend(const std::string &text);
void msw_rescale();
// implementation of base class virtuals to define model
unsigned int GetColumnCount() const override { return colMax; }
wxString GetColumnType(unsigned int col) const override;
void GetValueByRow(wxVariant &variant, unsigned int row, unsigned int col) const override;
bool GetAttrByRow(unsigned int row, unsigned int col, wxDataViewItemAttr &attr) const override { return true; }
bool SetValueByRow(const wxVariant &variant, unsigned int row, unsigned int col) override { return false; }
};
class SearchObjectDialog : public PopupWindow
{
public:
SearchObjectDialog(GUI::ObjectList* object_list, wxWindow* parent, TextInput* input);
~SearchObjectDialog();
#ifdef __WXMSW__
void MSWDismissUnfocusedPopup() override;
#endif // __WXMSW__
void Popup(wxWindow *focus = nullptr) override;
void OnDismiss() override;
void Dismiss() override;
void Die();
void OnInputText(wxCommandEvent& event);
void OnLeftUpInTextCtrl(wxEvent& event);
void update_list();
public:
GUI::ObjectList* m_object_list{ nullptr };
int em;
const int POPUP_WIDTH = 41;
const int POPUP_HEIGHT = 45;
TextInput* search_line{nullptr};
wxTextCtrl* search_line2{nullptr};
ScrolledWindow* m_scrolledWindow{ nullptr };
wxColour m_bg_color;
wxColour m_thumb_color;
wxBoxSizer* m_sizer_body{ nullptr };
wxBoxSizer* m_sizer_main{ nullptr };
wxBoxSizer* m_sizer_border{ nullptr };
wxWindow* m_border_panel{ nullptr };
wxWindow* m_client_panel{ nullptr };
private:
bool m_is_dismissing{ false };
};
} // namespace Search
} // namespace Slic3r
#endif // slic3r_SearchComboBox_hpp_