ENH: [STUDIO-1608] select support filament by combobox

Change-Id: I26543530202a53ef5753c38404617458a6d4a1ef
This commit is contained in:
chunmao.guo 2022-12-06 18:53:26 +08:00 committed by Lane.Wei
parent 278eab5ae2
commit 41b1ad6f2f
5 changed files with 132 additions and 14 deletions

View file

@ -2465,7 +2465,8 @@ void PrintConfigDef::init_fff_params()
def->set_default_value(new ConfigOptionInt(0)); def->set_default_value(new ConfigOptionInt(0));
def = this->add("support_filament", coInt); def = this->add("support_filament", coInt);
def->label = L("Support"); def->gui_type = ConfigOptionDef::GUIType::i_enum_open;
def->label = L("Support");
def->category = L("Support"); def->category = L("Support");
def->tooltip = L("Filament to print support and skirt. 0 means no specific filament for support and current filament is used"); def->tooltip = L("Filament to print support and skirt. 0 means no specific filament for support and current filament is used");
def->min = 0; def->min = 0;
@ -2489,11 +2490,12 @@ void PrintConfigDef::init_fff_params()
def->set_default_value(new ConfigOptionBool(false)); def->set_default_value(new ConfigOptionBool(false));
def = this->add("support_interface_filament", coInt); def = this->add("support_interface_filament", coInt);
def->label = L("Support interface"); def->gui_type = ConfigOptionDef::GUIType::i_enum_open;
def->label = L("Support interface");
def->category = L("Support"); def->category = L("Support");
def->tooltip = L("Filament to print support interface. 0 means no specific filament for support interface and current filament is used"); def->tooltip = L("Filament to print support interface. 0 means no specific filament for support interface and current filament is used");
def->min = 0; def->min = 0;
//BBS // BBS
def->mode = comSimple; def->mode = comSimple;
def->set_default_value(new ConfigOptionInt(1)); def->set_default_value(new ConfigOptionInt(1));

View file

@ -986,13 +986,46 @@ using choice_ctrl = ::ComboBox; // BBS
using choice_ctrl = ::ComboBox; // BBS using choice_ctrl = ::ComboBox; // BBS
#endif // __WXOSX__ #endif // __WXOSX__
void Choice::BUILD() { static std::map<std::string, DynamicList*> dynamic_lists;
void Choice::register_dynamic_list(std::string const &optname, DynamicList *list) { dynamic_lists.emplace(optname, list); }
void DynamicList::update()
{
for (auto c : m_choices) apply_on(c);
}
void DynamicList::add_choice(Choice *choice)
{
auto iter = std::find(m_choices.begin(), m_choices.end(), choice);
if (iter != m_choices.end()) return;
apply_on(choice);
m_choices.push_back(choice);
}
void DynamicList::remove_choice(Choice *choice)
{
auto iter = std::find(m_choices.begin(), m_choices.end(), choice);
if (iter != m_choices.end()) m_choices.erase(iter);
}
Choice::~Choice()
{
if (m_list) { m_list->remove_choice(this); }
}
void Choice::BUILD()
{
wxSize size(def_width_wider() * m_em_unit, wxDefaultCoord); wxSize size(def_width_wider() * m_em_unit, wxDefaultCoord);
if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit); if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit);
if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit); if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit);
choice_ctrl* temp; choice_ctrl* temp;
if (m_opt.gui_type != ConfigOptionDef::GUIType::undefined && m_opt.gui_type != ConfigOptionDef::GUIType::select_open) { auto dynamic_list = dynamic_lists.find(m_opt.opt_key);
if (dynamic_list != dynamic_lists.end())
m_list = dynamic_list->second;
if (m_opt.gui_type != ConfigOptionDef::GUIType::undefined && m_opt.gui_type != ConfigOptionDef::GUIType::select_open
&& m_list == nullptr) {
m_is_editable = true; m_is_editable = true;
temp = new choice_ctrl(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxTE_PROCESS_ENTER); temp = new choice_ctrl(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxTE_PROCESS_ENTER);
} }
@ -1051,7 +1084,10 @@ void Choice::BUILD() {
} }
} }
set_selection(); set_selection();
} } else if (m_list) {
m_list->add_choice(this);
set_selection();
}
temp->Bind(wxEVT_MOUSEWHEEL, [this](wxMouseEvent& e) { temp->Bind(wxEVT_MOUSEWHEEL, [this](wxMouseEvent& e) {
if (m_suppress_scroll && !m_is_dropped) if (m_suppress_scroll && !m_is_dropped)
@ -1224,7 +1260,9 @@ void Choice::set_value(const boost::any& value, bool change_event)
break; break;
++idx; ++idx;
} }
if (idx == enums.size()) { if (m_list)
field->SetSelection(m_list->index_of(text_value));
else if (idx == enums.size()) {
// For editable Combobox under OSX is needed to set selection to -1 explicitly, // For editable Combobox under OSX is needed to set selection to -1 explicitly,
// otherwise selection doesn't be changed // otherwise selection doesn't be changed
field->SetSelection(-1); field->SetSelection(-1);
@ -1344,7 +1382,10 @@ boost::any& Choice::get_value()
} }
else if (m_opt.gui_type == ConfigOptionDef::GUIType::f_enum_open || m_opt.gui_type == ConfigOptionDef::GUIType::i_enum_open) { else if (m_opt.gui_type == ConfigOptionDef::GUIType::f_enum_open || m_opt.gui_type == ConfigOptionDef::GUIType::i_enum_open) {
const int ret_enum = field->GetSelection(); const int ret_enum = field->GetSelection();
if (ret_enum < 0 || m_opt.enum_values.empty() || m_opt.type == coStrings || if (m_list) {
ret_str = m_list->get_value(ret_enum);
get_value_by_opt_type(ret_str);
} else if (ret_enum < 0 || m_opt.enum_values.empty() || m_opt.type == coStrings ||
(ret_str != m_opt.enum_values[ret_enum] && ret_str != _(m_opt.enum_labels[ret_enum]))) (ret_str != m_opt.enum_values[ret_enum] && ret_str != _(m_opt.enum_labels[ret_enum])))
// modifies ret_string! // modifies ret_string!
get_value_by_opt_type(ret_str); get_value_by_opt_type(ret_str);
@ -1802,5 +1843,4 @@ boost::any& SliderCtrl::get_value()
} }
} // GUI }} // Slic3r
} // Slic3r

View file

@ -335,13 +335,36 @@ public:
wxWindow* getWindow() override { return window; } wxWindow* getWindow() override { return window; }
}; };
class Choice;
class DynamicList
{
public:
virtual ~DynamicList() {}
virtual void apply_on(Choice * choice) = 0;
virtual wxString get_value(int index) = 0;
virtual int index_of(wxString value) = 0;
protected:
void update();
std::vector<Choice*> m_choices;
private:
friend class Choice;
void add_choice(Choice *choice);
void remove_choice(Choice *choice);
};
class Choice : public Field { class Choice : public Field {
using Field::Field; using Field::Field;
DynamicList * m_list = nullptr;
public: public:
Choice(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {} Choice(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {}
Choice(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {} Choice(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {}
~Choice() {} ~Choice();
static void register_dynamic_list(std::string const &optname, DynamicList *list);
wxWindow* window{ nullptr }; wxWindow* window{ nullptr };
void BUILD() override; void BUILD() override;

View file

@ -931,7 +931,6 @@ void MainFrame::init_tabpanel()
select_tab(MainFrame::tpHome); select_tab(MainFrame::tpHome);
m_webview->load_url(url); m_webview->load_url(url);
}); });
m_tabpanel->AddPage(m_webview, "", "tab_home_active", "tab_home_active"); m_tabpanel->AddPage(m_webview, "", "tab_home_active", "tab_home_active");
m_param_panel = new ParamsPanel(m_tabpanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL); m_param_panel = new ParamsPanel(m_tabpanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL);
} }

View file

@ -420,11 +420,61 @@ void Sidebar::priv::hide_rich_tip(wxButton* btn)
// Sidebar / public // Sidebar / public
static struct DynamicFilamentList : DynamicList
{
std::vector<std::pair<wxString, wxBitmap *>> items;
void apply_on(Choice *c) override
{
if (items.empty())
update(true);
auto cb = dynamic_cast<ComboBox *>(c->window);
auto n = cb->GetSelection();
cb->Clear();
cb->Append(_L("Default"));
for (auto i : items) {
cb->Append(i.first, *i.second);
}
if (n < cb->GetCount())
cb->SetSelection(n);
}
wxString get_value(int index) override
{
wxString str;
str << index;
return str;
}
int index_of(wxString value) override
{
long n = 0;
return value.ToLong(&n) ? int(n) : -1;
}
void update(bool force = false)
{
items.clear();
if (!force && m_choices.empty())
return;
auto icons = get_extruder_color_icons(true);
auto presets = wxGetApp().preset_bundle->filament_presets;
for (int i = 0; i < presets.size(); ++i) {
wxString str;
std::string type;
wxGetApp().preset_bundle->filaments.find_preset(presets[i])->get_filament_type(type);
str << (i + 1) << " - " << type;
items.push_back({str, icons[i]});
}
DynamicList::update();
}
} dynamic_filament_list;
Sidebar::Sidebar(Plater *parent) Sidebar::Sidebar(Plater *parent)
: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(42 * wxGetApp().em_unit(), -1)), p(new priv(parent)) : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(42 * wxGetApp().em_unit(), -1)), p(new priv(parent))
{ {
Choice::register_dynamic_list("support_filament", &dynamic_filament_list);
Choice::register_dynamic_list("support_interface_filament", &dynamic_filament_list);
p->scrolled = new wxPanel(this); p->scrolled = new wxPanel(this);
// p->scrolled->SetScrollbars(0, 100, 1, 2); // ys_DELETE_after_testing. pixelsPerUnitY = 100 // p->scrolled->SetScrollbars(0, 100, 1, 2); // ys_DELETE_after_testing. pixelsPerUnitY = 100
// but this cause the bad layout of the sidebar, when all infoboxes appear. // but this cause the bad layout of the sidebar, when all infoboxes appear.
// As a result we can see the empty block at the bottom of the sidebar // As a result we can see the empty block at the bottom of the sidebar
// But if we set this value to 5, layout will be better // But if we set this value to 5, layout will be better
@ -1021,6 +1071,7 @@ void Sidebar::update_presets(Preset::Type preset_type)
for (size_t i = 0; i < filament_cnt; i++) for (size_t i = 0; i < filament_cnt; i++)
p->combos_filament[i]->update(); p->combos_filament[i]->update();
dynamic_filament_list.update();
break; break;
} }
@ -1290,6 +1341,7 @@ void Sidebar::on_filaments_change(size_t num_filaments)
p->m_panel_filament_title->Layout(); p->m_panel_filament_title->Layout();
p->m_panel_filament_title->Refresh(); p->m_panel_filament_title->Refresh();
update_ui_from_settings(); update_ui_from_settings();
dynamic_filament_list.update();
} }
void Sidebar::on_bed_type_change(BedType bed_type) void Sidebar::on_bed_type_change(BedType bed_type)
@ -1354,6 +1406,7 @@ void Sidebar::sync_ams_list()
c->update(); c->update();
wxGetApp().get_tab(Preset::TYPE_PRINT)->update(); wxGetApp().get_tab(Preset::TYPE_PRINT)->update();
wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config); wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config);
dynamic_filament_list.update();
} }
ObjectList* Sidebar::obj_list() ObjectList* Sidebar::obj_list()
@ -5391,6 +5444,7 @@ void Plater::priv::on_select_preset(wxCommandEvent &evt)
wxGetApp().preset_bundle->set_filament_preset(idx, preset_name); wxGetApp().preset_bundle->set_filament_preset(idx, preset_name);
wxGetApp().plater()->update_project_dirty_from_presets(); wxGetApp().plater()->update_project_dirty_from_presets();
wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config); wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config);
dynamic_filament_list.update();
} }
bool select_preset = !combo->selection_is_changed_according_to_physical_printers(); bool select_preset = !combo->selection_is_changed_according_to_physical_printers();