Completed a search list cleaning (deleted unused options).

+ Implemented BlinkingBitmap
+ Options, that doesn't have related controls, are highlighted near the widgets.
This commit is contained in:
YuSanka 2020-04-16 09:59:12 +02:00
parent 45147d887b
commit b69dfd63ca
9 changed files with 219 additions and 68 deletions

View File

@ -57,8 +57,7 @@ void Field::PostInitialize()
m_Undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_initial_value(); })); m_Undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_initial_value(); }));
m_Undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_sys_value(); })); m_Undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_sys_value(); }));
m_attention_bmp = ScalableBitmap(m_parent, "attention"); m_blinking_bmp = new BlinkingBitmap(m_parent);
m_find_image = new wxStaticBitmap(m_parent, wxID_ANY, wxNullBitmap, wxDefaultPosition, m_attention_bmp.bmp().GetSize());
switch (m_opt.type) switch (m_opt.type)
{ {

View File

@ -191,20 +191,6 @@ public:
return false; return false;
} }
void invalidate_attention_bmp() const {
m_find_image->SetBitmap(wxNullBitmap);
m_find_image->Show();
}
void activate_attention_bmp() const {
m_find_image->SetBitmap(m_attention_bmp.bmp());
}
void blink_attention_bmp() const {
bool is_shown = m_find_image->IsShown();
m_find_image->Show(!is_shown);
}
bool set_label_colour_force(const wxColour *clr) { bool set_label_colour_force(const wxColour *clr) {
if (m_Label == nullptr) return false; if (m_Label == nullptr) return false;
m_Label->SetForegroundColour(*clr); m_Label->SetForegroundColour(*clr);
@ -244,6 +230,8 @@ public:
static int def_width_wider() ; static int def_width_wider() ;
static int def_width_thinner() ; static int def_width_thinner() ;
BlinkingBitmap* blinking_bitmap() const { return m_blinking_bmp;}
protected: protected:
RevertButton* m_Undo_btn = nullptr; RevertButton* m_Undo_btn = nullptr;
// Bitmap and Tooltip text for m_Undo_btn. The wxButton will be updated only if the new wxBitmap pointer differs from the currently rendered one. // Bitmap and Tooltip text for m_Undo_btn. The wxButton will be updated only if the new wxBitmap pointer differs from the currently rendered one.
@ -254,8 +242,7 @@ protected:
const ScalableBitmap* m_undo_to_sys_bitmap = nullptr; const ScalableBitmap* m_undo_to_sys_bitmap = nullptr;
const wxString* m_undo_to_sys_tooltip = nullptr; const wxString* m_undo_to_sys_tooltip = nullptr;
ScalableBitmap m_attention_bmp; BlinkingBitmap* m_blinking_bmp{ nullptr };
wxStaticBitmap* m_find_image{ nullptr };
wxStaticText* m_Label = nullptr; wxStaticText* m_Label = nullptr;
// Color for Label. The wxColour will be updated only if the new wxColour pointer differs from the currently rendered one. // Color for Label. The wxColour will be updated only if the new wxColour pointer differs from the currently rendered one.

View File

@ -108,9 +108,9 @@ void OptionsGroup::add_undo_buttuns_to_sizer(wxSizer* sizer, const t_field& fiel
return; return;
} }
sizer->Add(field->m_blinking_bmp, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 2);
sizer->Add(field->m_Undo_to_sys_btn, 0, wxALIGN_CENTER_VERTICAL); sizer->Add(field->m_Undo_to_sys_btn, 0, wxALIGN_CENTER_VERTICAL);
sizer->Add(field->m_Undo_btn, 0, wxALIGN_CENTER_VERTICAL); sizer->Add(field->m_Undo_btn, 0, wxALIGN_CENTER_VERTICAL);
sizer->Add(field->m_find_image, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 2);
} }
void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = nullptr*/) { void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = nullptr*/) {

View File

@ -92,16 +92,35 @@ void FoundOption::get_marked_label(const char** out_text) const
} }
template<class T> template<class T>
void change_opt_key(std::string& opt_key, DynamicPrintConfig* config) //void change_opt_key(std::string& opt_key, DynamicPrintConfig* config)
void change_opt_key(std::string& opt_key, DynamicPrintConfig* config, int& cnt)
{ {
T* opt_cur = static_cast<T*>(config->option(opt_key)); T* opt_cur = static_cast<T*>(config->option(opt_key));
cnt = opt_cur->values.size();
return;
if (opt_cur->values.size() > 0) if (opt_cur->values.size() > 0)
opt_key += "#" + std::to_string(0); opt_key += "#" + std::to_string(0);
} }
void OptionsSearcher::append_options(DynamicPrintConfig* config, Preset::Type type, ConfigOptionMode mode) void OptionsSearcher::append_options(DynamicPrintConfig* config, Preset::Type type, ConfigOptionMode mode)
{ {
std::vector<std::string> non_added_options {"printer_technology", "thumbnails" }; auto emplace = [this, type](const std::string opt_key, const wxString& label)
{
const GroupAndCategory& gc = groups_and_categories[opt_key];
if (gc.group.IsEmpty() || gc.category.IsEmpty())
return;
wxString suffix;
if (gc.category == "Machine limits")
suffix = opt_key.back()=='1' ? L("Stealth") : L("Normal");
if (!label.IsEmpty())
options.emplace_back(Option{ opt_key, type,
label+ " " + suffix, _(label)+ " " + _(suffix),
gc.group, _(gc.group),
gc.category, _(gc.category) });
};
for (std::string opt_key : config->keys()) for (std::string opt_key : config->keys())
{ {
@ -109,27 +128,37 @@ void OptionsSearcher::append_options(DynamicPrintConfig* config, Preset::Type ty
if (opt.mode > mode) if (opt.mode > mode)
continue; continue;
if (type == Preset::TYPE_SLA_MATERIAL || type == Preset::TYPE_PRINTER) int cnt = 0;
if ( (type == Preset::TYPE_SLA_MATERIAL || type == Preset::TYPE_PRINTER) && opt_key != "bed_shape")
switch (config->option(opt_key)->type()) switch (config->option(opt_key)->type())
{ {
case coInts: change_opt_key<ConfigOptionInts >(opt_key, config); break; case coInts: change_opt_key<ConfigOptionInts >(opt_key, config, cnt); break;
case coBools: change_opt_key<ConfigOptionBools >(opt_key, config); break; case coBools: change_opt_key<ConfigOptionBools >(opt_key, config, cnt); break;
case coFloats: change_opt_key<ConfigOptionFloats >(opt_key, config); break; case coFloats: change_opt_key<ConfigOptionFloats >(opt_key, config, cnt); break;
case coStrings: change_opt_key<ConfigOptionStrings >(opt_key, config); break; case coStrings: change_opt_key<ConfigOptionStrings >(opt_key, config, cnt); break;
case coPercents:change_opt_key<ConfigOptionPercents >(opt_key, config); break; case coPercents:change_opt_key<ConfigOptionPercents >(opt_key, config, cnt); break;
case coPoints: change_opt_key<ConfigOptionPoints >(opt_key, config); break; case coPoints: change_opt_key<ConfigOptionPoints >(opt_key, config, cnt); break;
default: break; default: break;
} }
wxString label = opt.full_label.empty() ? opt.label : opt.full_label; wxString label = opt.full_label.empty() ? opt.label : opt.full_label;
const GroupAndCategory& gc = groups_and_categories[opt_key]; if (cnt == 0)
emplace(opt_key, label);
else
for (int i = 0; i < cnt; ++i)
emplace(opt_key + "#" + std::to_string(i), label);
/*const GroupAndCategory& gc = groups_and_categories[opt_key];
if (gc.group.IsEmpty() || gc.category.IsEmpty())
continue;
if (!label.IsEmpty()) if (!label.IsEmpty())
options.emplace_back(Option{opt_key, type, options.emplace_back(Option{opt_key, type,
label, _(label), label, _(label),
gc.group, _(gc.group), gc.group, _(gc.group),
gc.category, _(gc.category) }); gc.category, _(gc.category) });*/
} }
} }
@ -243,6 +272,22 @@ void OptionsSearcher::init(std::vector<InputInfo> input_values)
search(search_line, true); search(search_line, true);
} }
void OptionsSearcher::apply(DynamicPrintConfig* config, Preset::Type type, ConfigOptionMode mode)
{
if (options.empty())
return;
options.erase(std::remove_if(options.begin(), options.end(), [type](Option opt) {
return opt.type == type;
}), options.end());
append_options(config, type, mode);
sort_options();
search(search_line, true);
}
const Option& OptionsSearcher::get_option(size_t pos_in_filter) const const Option& OptionsSearcher::get_option(size_t pos_in_filter) const
{ {
assert(pos_in_filter != size_t(-1) && found[pos_in_filter].option_idx != size_t(-1)); assert(pos_in_filter != size_t(-1) && found[pos_in_filter].option_idx != size_t(-1));
@ -353,12 +398,7 @@ SearchCtrl::SearchCtrl(wxWindow* parent) :
this->Bind(wxEVT_TEXT, &SearchCtrl::OnInputText, this); this->Bind(wxEVT_TEXT, &SearchCtrl::OnInputText, this);
this->Bind(wxEVT_TEXT_ENTER, &SearchCtrl::PopupList, this); this->Bind(wxEVT_TEXT_ENTER, &SearchCtrl::PopupList, this);
this->Bind(wxEVT_COMBOBOX_DROPDOWN, &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); this->GetTextCtrl()->Bind(wxEVT_LEFT_UP, &SearchCtrl::OnLeftUpInTextCtrl, this);
popupListBox->Bind(wxEVT_LISTBOX, &SearchCtrl::OnSelect, this); popupListBox->Bind(wxEVT_LISTBOX, &SearchCtrl::OnSelect, this);
} }
@ -421,7 +461,7 @@ void SearchCtrl::OnSelect(wxCommandEvent& event)
void SearchCtrl::update_list(const std::vector<FoundOption>& filters) void SearchCtrl::update_list(const std::vector<FoundOption>& filters)
{ {
if (popupListBox->GetCount() == filters.size() && if (!filters.empty() && popupListBox->GetCount() == filters.size() &&
popupListBox->GetString(0) == filters[0].label && popupListBox->GetString(0) == filters[0].label &&
popupListBox->GetString(popupListBox->GetCount()-1) == filters[filters.size()-1].label) popupListBox->GetString(popupListBox->GetCount()-1) == filters[filters.size()-1].label)
return; return;

View File

@ -76,11 +76,11 @@ struct FoundOption {
class OptionsSearcher class OptionsSearcher
{ {
std::string search_line; std::string search_line;
std::map<std::string, GroupAndCategory> groups_and_categories; std::map<std::string, GroupAndCategory> groups_and_categories;
std::vector<Option> options {}; std::vector<Option> options {};
std::vector<FoundOption> found {}; std::vector<FoundOption> found {};
void append_options(DynamicPrintConfig* config, Preset::Type type, ConfigOptionMode mode); void append_options(DynamicPrintConfig* config, Preset::Type type, ConfigOptionMode mode);
@ -101,6 +101,9 @@ public:
bool group{ true }; bool group{ true };
void init(std::vector<InputInfo> input_values); void init(std::vector<InputInfo> input_values);
void apply(DynamicPrintConfig *config,
Preset::Type type,
ConfigOptionMode mode);
bool search(const std::string& search, bool force = false); bool search(const std::string& search, bool force = false);
void add_key(const std::string& opt_key, const wxString& group, const wxString& category); void add_key(const std::string& opt_key, const wxString& group, const wxString& category);
@ -111,6 +114,7 @@ public:
const Option& get_option(size_t pos_in_filter) const; const Option& get_option(size_t pos_in_filter) const;
const std::vector<FoundOption>& found_options() { return found; } 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]; }
}; };

View File

@ -39,26 +39,41 @@ namespace GUI {
wxDEFINE_EVENT(EVT_TAB_VALUE_CHANGED, wxCommandEvent); wxDEFINE_EVENT(EVT_TAB_VALUE_CHANGED, wxCommandEvent);
wxDEFINE_EVENT(EVT_TAB_PRESETS_CHANGED, SimpleEvent); wxDEFINE_EVENT(EVT_TAB_PRESETS_CHANGED, SimpleEvent);
void Tab::Highlighter::init(Field* f) void Tab::Highlighter::set_timer_owner(wxEvtHandler* owner, int timerid/* = wxID_ANY*/)
{ {
field = f; timer.SetOwner(owner, timerid);
field->activate_attention_bmp(); }
void Tab::Highlighter::init(BlinkingBitmap* bmp)
{
if (timer.IsRunning())
invalidate();
if (!bmp)
return;
timer.Start(100, false);
bbmp = bmp;
bbmp->activate();
} }
void Tab::Highlighter::invalidate() void Tab::Highlighter::invalidate()
{ {
field->invalidate_attention_bmp(); timer.Stop();
field = nullptr;
bbmp->invalidate();
bbmp = nullptr;
blink_counter = 0; blink_counter = 0;
} }
bool Tab::Highlighter::blink() void Tab::Highlighter::blink()
{ {
field->blink_attention_bmp(); if (!bbmp)
return;
bbmp->blink();
if ((++blink_counter) == 29) if ((++blink_counter) == 29)
invalidate(); invalidate();
return blink_counter != 0;
} }
Tab::Tab(wxNotebook* parent, const wxString& title, Preset::Type type) : Tab::Tab(wxNotebook* parent, const wxString& title, Preset::Type type) :
@ -92,11 +107,10 @@ Tab::Tab(wxNotebook* parent, const wxString& title, Preset::Type type) :
evt.Skip(); evt.Skip();
})); }));
this->m_highlighting_timer.SetOwner(this, 0); m_highlighter.set_timer_owner(this, 0);
this->Bind(wxEVT_TIMER, [this](wxTimerEvent&) this->Bind(wxEVT_TIMER, [this](wxTimerEvent&)
{ {
if (!m_highlighter.blink()) m_highlighter.blink();
m_highlighting_timer.Stop();
}); });
} }
@ -1021,19 +1035,28 @@ void Tab::activate_option(const std::string& opt_key, const wxString& category)
// focused selected field // focused selected field
if (field) { if (field) {
field->getWindow()->SetFocus(); field->getWindow()->SetFocus();
if (m_highlighting_timer.IsRunning()) { m_highlighter.init(field->blinking_bitmap());
m_highlighting_timer.Stop(); }
m_highlighter.invalidate(); else if (category == "Single extruder MM setup")
{
// When we show and hide "Single extruder MM setup" page,
// related options are still in the search list
// So, let's hightlighte a "single_extruder_multi_material" option,
// as a "way" to show hidden page again
field = get_field("single_extruder_multi_material");
if (field) {
field->getWindow()->SetFocus();
m_highlighter.init(field->blinking_bitmap());
} }
m_highlighting_timer.Start(100, false);
m_highlighter.init(field);
} }
else else
{ m_highlighter.init(m_blinking_ikons[opt_key]);
// "bed_shape", "bed_custom_texture", "bed_custom_model"
}
} void Tab::apply_searcher()
{
wxGetApp().sidebar().get_searcher().apply(m_config, m_type, m_mode);
} }
@ -2533,6 +2556,9 @@ void TabPrinter::build_unregular_pages()
// Reload preset pages with current configuration values // Reload preset pages with current configuration values
reload_config(); reload_config();
// apply searcher with current configuration
apply_searcher();
} }
// this gets executed after preset is loaded and before GUI fields are updated // this gets executed after preset is loaded and before GUI fields are updated
@ -3321,7 +3347,10 @@ wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &dep
add_scaled_button(parent, &deps.btn, "printer_white", from_u8((boost::format(" %s %s") % _utf8(L("Set")) % std::string(dots.ToUTF8())).str()), wxBU_LEFT | wxBU_EXACTFIT); add_scaled_button(parent, &deps.btn, "printer_white", from_u8((boost::format(" %s %s") % _utf8(L("Set")) % std::string(dots.ToUTF8())).str()), wxBU_LEFT | wxBU_EXACTFIT);
deps.btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); deps.btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
BlinkingBitmap* bbmp = new BlinkingBitmap(parent);
auto sizer = new wxBoxSizer(wxHORIZONTAL); auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(bbmp, 0, wxALIGN_CENTER_VERTICAL);
sizer->Add((deps.checkbox), 0, wxALIGN_CENTER_VERTICAL); sizer->Add((deps.checkbox), 0, wxALIGN_CENTER_VERTICAL);
sizer->Add((deps.btn), 0, wxALIGN_CENTER_VERTICAL); sizer->Add((deps.btn), 0, wxALIGN_CENTER_VERTICAL);
@ -3381,6 +3410,12 @@ wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &dep
this->update_changed_ui(); this->update_changed_ui();
} }
})); }));
// fill m_blinking_ikons map with options
{
m_blinking_ikons[deps.key_list] = bbmp;
}
return sizer; return sizer;
} }
@ -3391,8 +3426,11 @@ wxSizer* TabPrinter::create_bed_shape_widget(wxWindow* parent)
add_scaled_button(parent, &btn, "printer_white", " " + _(L("Set")) + " " + dots, wxBU_LEFT | wxBU_EXACTFIT); add_scaled_button(parent, &btn, "printer_white", " " + _(L("Set")) + " " + dots, wxBU_LEFT | wxBU_EXACTFIT);
btn->SetFont(wxGetApp().normal_font()); btn->SetFont(wxGetApp().normal_font());
BlinkingBitmap* bbmp = new BlinkingBitmap(parent);
auto sizer = new wxBoxSizer(wxHORIZONTAL); auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(btn); sizer->Add(bbmp, 0, wxALIGN_CENTER_VERTICAL);
sizer->Add(btn, 0, wxALIGN_CENTER_VERTICAL);
btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e)
{ {
@ -3414,6 +3452,21 @@ wxSizer* TabPrinter::create_bed_shape_widget(wxWindow* parent)
} }
})); }));
// may be it is not a best place, but
// add information about Category/Grope for "bed_custom_texture" and "bed_custom_model" as a copy from "bed_shape" option
{
Search::OptionsSearcher& searcher = wxGetApp().sidebar().get_searcher();
const Search::GroupAndCategory& gc = searcher.get_group_and_category("bed_shape");
searcher.add_key("bed_custom_texture", gc.group, gc.category);
searcher.add_key("bed_custom_model", gc.group, gc.category);
}
// fill m_blinking_ikons map with options
{
for (const std::string opt : {"bed_shape", "bed_custom_texture", "bed_custom_model"})
m_blinking_ikons[opt] = bbmp;
}
return sizer; return sizer;
} }

View File

@ -223,16 +223,20 @@ protected:
bool m_completed { false }; bool m_completed { false };
ConfigOptionMode m_mode = comExpert; // to correct first Tab update_visibility() set mode to Expert ConfigOptionMode m_mode = comExpert; // to correct first Tab update_visibility() set mode to Expert
wxTimer m_highlighting_timer;
struct Highlighter struct Highlighter
{ {
void init(Field* f); void set_timer_owner(wxEvtHandler* owner, int timerid = wxID_ANY);
void invalidate(); void init(BlinkingBitmap* bmp);
bool blink(); void blink();
private: private:
Field* field {nullptr}; void invalidate();
int blink_counter {0};
} m_highlighter; BlinkingBitmap* bbmp {nullptr};
int blink_counter {0};
wxTimer timer;
}
m_highlighter;
public: public:
PresetBundle* m_preset_bundle; PresetBundle* m_preset_bundle;
@ -246,6 +250,10 @@ public:
// Used for options which don't have corresponded field // Used for options which don't have corresponded field
std::map<std::string, wxStaticText*> m_colored_Labels; std::map<std::string, wxStaticText*> m_colored_Labels;
// map of option name -> BlinkingBitmap (blinking ikon, associated with option)
// Used for options which don't have corresponded field
std::map<std::string, BlinkingBitmap*> m_blinking_ikons;
// Counter for the updating (because of an update() function can have a recursive behavior): // Counter for the updating (because of an update() function can have a recursive behavior):
// 1. increase value from the very beginning of an update() function // 1. increase value from the very beginning of an update() function
// 2. decrease value at the end of an update() function // 2. decrease value at the end of an update() function
@ -328,6 +336,7 @@ public:
void update_wiping_button_visibility(); void update_wiping_button_visibility();
void activate_option(const std::string& opt_key, const wxString& category); void activate_option(const std::string& opt_key, const wxString& category);
void apply_searcher();
protected: protected:
void create_line_with_widget(ConfigOptionsGroup* optgroup, const std::string& opt_key, widget_t widget); void create_line_with_widget(ConfigOptionsGroup* optgroup, const std::string& opt_key, widget_t widget);

View File

@ -942,5 +942,40 @@ void ScalableButton::msw_rescale()
} }
// ----------------------------------------------------------------------------
// BlinkingBitmap
// ----------------------------------------------------------------------------
BlinkingBitmap::BlinkingBitmap(wxWindow* parent, const std::string& icon_name) :
wxStaticBitmap(parent, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize(int(1.6 * Slic3r::GUI::wxGetApp().em_unit()), -1))
{
bmp = ScalableBitmap(parent, icon_name);
}
void BlinkingBitmap::msw_rescale()
{
bmp.msw_rescale();
this->SetSize(bmp.GetBmpSize());
this->SetMinSize(bmp.GetBmpSize());
}
void BlinkingBitmap::invalidate()
{
this->SetBitmap(wxNullBitmap);
}
void BlinkingBitmap::activate()
{
this->SetBitmap(bmp.bmp());
show = true;
}
void BlinkingBitmap::blink()
{
show = !show;
this->SetBitmap(show ? bmp.bmp() : wxNullBitmap);
}

View File

@ -8,6 +8,7 @@
#include <wx/sizer.h> #include <wx/sizer.h>
#include <wx/menu.h> #include <wx/menu.h>
#include <wx/bmpcbox.h> #include <wx/bmpcbox.h>
#include <wx/statbmp.h>
#include <vector> #include <vector>
#include <functional> #include <functional>
@ -355,5 +356,28 @@ private:
}; };
// ----------------------------------------------------------------------------
// BlinkingBitmap
// ----------------------------------------------------------------------------
class BlinkingBitmap : public wxStaticBitmap
{
public:
BlinkingBitmap() {};
BlinkingBitmap(wxWindow* parent, const std::string& icon_name = "redo_toolbar");
~BlinkingBitmap() {}
void msw_rescale();
void invalidate();
void activate();
void blink();
private:
ScalableBitmap bmp;
bool show {false};
};
#endif // slic3r_GUI_wxExtensions_hpp_ #endif // slic3r_GUI_wxExtensions_hpp_