diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index dc4bb87956..53c0c653e9 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -25,7 +25,7 @@ namespace GUI wxDEFINE_EVENT(EVT_OBJ_LIST_OBJECT_SELECT, SimpleEvent); // pt_FFF -FreqSettingsBundle FREQ_SETTINGS_BUNDLE_FFF = +SettingsBundle FREQ_SETTINGS_BUNDLE_FFF = { { L("Layers and Perimeters"), { "layer_height" , "perimeters", "top_solid_layers", "bottom_solid_layers" } }, { L("Infill") , { "fill_density", "fill_pattern" } }, @@ -36,7 +36,7 @@ FreqSettingsBundle FREQ_SETTINGS_BUNDLE_FFF = }; // pt_SLA -FreqSettingsBundle FREQ_SETTINGS_BUNDLE_SLA = +SettingsBundle FREQ_SETTINGS_BUNDLE_SLA = { { L("Pad and Support") , { "supports_enable", "pad_enable" } } }; @@ -676,10 +676,7 @@ void ObjectList::paste_volumes_into_list(int obj_idx, const ModelVolumePtrs& vol const wxDataViewItem& vol_item = m_objects_model->AddVolumeChild(object_item, wxString::FromUTF8(volume->name.c_str()), volume->type(), volume->get_mesh_errors_count()>0 , volume->config.has("extruder") ? volume->config.option("extruder")->value : 0); - auto opt_keys = volume->config.keys(); - if (!opt_keys.empty() && !((opt_keys.size() == 1) && (opt_keys[0] == "extruder"))) - select_item(m_objects_model->AddSettingsChild(vol_item)); - + add_settings_item(vol_item, &volume->config); items.Add(vol_item); } @@ -991,7 +988,7 @@ std::vector ObjectList::get_options(const bool is_part) const std::vector& ObjectList::get_options_for_bundle(const wxString& bundle_name) { - const FreqSettingsBundle& bundle = printer_technology() == ptSLA ? + const SettingsBundle& bundle = printer_technology() == ptSLA ? FREQ_SETTINGS_BUNDLE_SLA : FREQ_SETTINGS_BUNDLE_FFF; for (auto& it : bundle) @@ -1001,7 +998,7 @@ const std::vector& ObjectList::get_options_for_bundle(const wxStrin } #if 0 // if "Quick menu" is selected - FreqSettingsBundle& bundle_quick = printer_technology() == ptSLA ? + SettingsBundle& bundle_quick = printer_technology() == ptSLA ? m_freq_settings_sla: m_freq_settings_fff; for (auto& it : bundle_quick) @@ -1077,7 +1074,7 @@ void ObjectList::get_settings_choice(const wxString& category_name) if (selection_cnt > 0) { // Add selected items to the "Quick menu" - FreqSettingsBundle& freq_settings = printer_technology() == ptSLA ? + SettingsBundle& freq_settings = printer_technology() == ptSLA ? m_freq_settings_sla : m_freq_settings_fff; bool changed_existing = false; @@ -1149,8 +1146,8 @@ void ObjectList::get_settings_choice(const wxString& category_name) } - // Add settings item for object - update_settings_item(); + // Add settings item for object/sub-object and show them + show_settings(add_settings_item(GetSelection(), m_config)); } void ObjectList::get_freq_settings_choice(const wxString& bundle_name) @@ -1186,13 +1183,21 @@ void ObjectList::get_freq_settings_choice(const wxString& bundle_name) } } - // Add settings item for object - update_settings_item(); + // Add settings item for object/sub-object and show them + show_settings(add_settings_item(GetSelection(), m_config)); } -void ObjectList::update_settings_item() +void ObjectList::show_settings(const wxDataViewItem settings_item) { - auto item = GetSelection(); + if (!settings_item) + return; + + select_item(settings_item); + + // update object selection on Plater + if (!m_prevent_canvas_selection_update) + update_selections_on_canvas(); +/* auto item = GetSelection(); if (item) { if (m_objects_model->GetItemType(item) == itInstance) item = m_objects_model->GetTopParent(item); @@ -1204,12 +1209,14 @@ void ObjectList::update_settings_item() if (!m_prevent_canvas_selection_update) update_selections_on_canvas(); } - else { + else { + //# ys_FIXME ??? use case ??? auto panel = wxGetApp().sidebar().scrolled_panel(); panel->Freeze(); wxGetApp().obj_settings()->UpdateAndShow(true); panel->Thaw(); } + */ } wxMenu* ObjectList::append_submenu_add_generic(wxMenu* menu, const ModelVolumeType type) { @@ -1520,7 +1527,7 @@ wxMenu* ObjectList::create_settings_popupmenu(wxMenu *parent_menu) void ObjectList::create_freq_settings_popupmenu(wxMenu *menu) { // Add default settings bundles - const FreqSettingsBundle& bundle = printer_technology() == ptFFF ? + const SettingsBundle& bundle = printer_technology() == ptFFF ? FREQ_SETTINGS_BUNDLE_FFF : FREQ_SETTINGS_BUNDLE_SLA; const int extruders_cnt = extruders_count(); @@ -1535,7 +1542,7 @@ void ObjectList::create_freq_settings_popupmenu(wxMenu *menu) } #if 0 // Add "Quick" settings bundles - const FreqSettingsBundle& bundle_quick = printer_technology() == ptFFF ? + const SettingsBundle& bundle_quick = printer_technology() == ptFFF ? m_freq_settings_fff : m_freq_settings_sla; for (auto& it : bundle_quick) { @@ -1898,11 +1905,7 @@ void ObjectList::split() volume->config.option("extruder")->value : 0, false); // add settings to the part, if it has those - auto opt_keys = volume->config.keys(); - if ( !(opt_keys.size() == 1 && opt_keys[0] == "extruder") ) { - select_item(m_objects_model->AddSettingsChild(vol_item)); - Expand(vol_item); - } + add_settings_item(vol_item, &volume->config); } if (parent == item) @@ -2148,6 +2151,77 @@ void ObjectList::part_selection_changed() panel.Thaw(); } +SettingsBundle ObjectList::get_item_settings_bundle(const DynamicPrintConfig* config, const bool is_layers_range_settings) +{ + auto opt_keys = config->keys(); + if (opt_keys.empty()) + return SettingsBundle(); + + update_opt_keys(opt_keys); // update options list according to print technology + + if (opt_keys.size() == 1 && opt_keys[0] == "extruder" || + is_layers_range_settings && opt_keys.size() == 2) + return SettingsBundle(); + + const int extruders_cnt = wxGetApp().extruders_edited_cnt(); + + SettingsBundle bundle; + for (auto& opt_key : opt_keys) + { + auto category = config->def()->get(opt_key)->category; + if (category.empty() || (category == "Extruders" && extruders_cnt == 1)) + continue; + + std::vector< std::string > new_category; + + auto& cat_opt = bundle.find(category) == bundle.end() ? new_category : bundle.at(category); + cat_opt.push_back(opt_key); + if (cat_opt.size() == 1) + bundle[category] = cat_opt; + } + + return bundle; +} + +wxDataViewItem ObjectList::add_settings_item(wxDataViewItem parent_item, const DynamicPrintConfig* config) +{ + wxDataViewItem ret = wxDataViewItem(0); + + if (!parent_item) + return ret; + + const bool is_layers_range_settings = m_objects_model->GetItemType(parent_item) == itLayer; + SettingsBundle cat_options = get_item_settings_bundle(config, is_layers_range_settings); + if (cat_options.empty()) + return ret; + + std::vector categories; + categories.reserve(cat_options.size()); + for (auto& cat : cat_options) + { + if (cat.second.size() == 1 && + (cat.second[0] == "extruder" || is_layers_range_settings && cat.second[0] == "layer_height")) + continue; + + categories.push_back(cat.first); + } + + if (categories.empty()) + return ret; + + if (m_objects_model->GetItemType(parent_item) & itInstance) + parent_item = m_objects_model->GetTopParent(parent_item); + + ret = m_objects_model->IsSettingsItem(parent_item) ? parent_item : m_objects_model->GetSettingsItem(parent_item); + + if (!ret) ret = m_objects_model->AddSettingsChild(parent_item); + + m_objects_model->UpdateSettingsDigest(ret, categories); + Expand(parent_item); + + return ret; +} + void ObjectList::add_object_to_list(size_t obj_idx, bool call_selection_changed) { auto model_object = (*m_objects)[obj_idx]; @@ -2167,13 +2241,7 @@ void ObjectList::add_object_to_list(size_t obj_idx, bool call_selection_changed) !volume->config.has("extruder") ? 0 : volume->config.option("extruder")->value, false); - auto opt_keys = volume->config.keys(); - if (!opt_keys.empty() && !(opt_keys.size() == 1 && opt_keys[0] == "extruder")) { - const wxDataViewItem &settings_item = m_objects_model->AddSettingsChild(vol_item); - if (call_selection_changed) - select_item(settings_item); - Expand(vol_item); - } + add_settings_item(vol_item, &volume->config); } Expand(item); } @@ -2183,13 +2251,7 @@ void ObjectList::add_object_to_list(size_t obj_idx, bool call_selection_changed) increase_object_instances(obj_idx, model_object->instances.size()); // add settings to the object, if it has those - auto opt_keys = model_object->config.keys(); - if (!opt_keys.empty() && !(opt_keys.size() == 1 && opt_keys[0] == "extruder")) { - const wxDataViewItem &settings_item = m_objects_model->AddSettingsChild(item); - if (call_selection_changed) - select_item(settings_item); - Expand(item); - } + add_settings_item(item, &model_object->config); // Add layers if it has add_layer_root_item(item); @@ -2491,11 +2553,7 @@ void ObjectList::add_layer_item(const t_layer_height_range& range, range, config.opt_int("extruder"), layer_idx); - - if (config.keys().size() > 2) { - m_objects_model->AddSettingsChild(layer_item); - Expand(layer_item); - } + add_settings_item(layer_item, &config); } bool ObjectList::edit_layer_range(const t_layer_height_range& range, coordf_t layer_height) @@ -3010,7 +3068,7 @@ void ObjectList::change_part_type() } else if (!settings_item && (new_type == ModelVolumeType::MODEL_PART || new_type == ModelVolumeType::PARAMETER_MODIFIER)) { - select_item(m_objects_model->AddSettingsChild(item)); + add_settings_item(item, &volume->config); } } diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 34efa90252..72bddeec81 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -26,7 +26,7 @@ enum class ModelVolumeType : int; // FIXME: broken build on mac os because of this is missing: typedef std::vector t_config_option_keys; -typedef std::map> FreqSettingsBundle; +typedef std::map> SettingsBundle; // category -> vector ( option ; label ) typedef std::map< std::string, std::vector< std::pair > > settings_menu_hierarchy; @@ -152,8 +152,8 @@ class ObjectList : public wxDataViewCtrl wxDataViewItem m_last_selected_item {nullptr}; #if 0 - FreqSettingsBundle m_freq_settings_fff; - FreqSettingsBundle m_freq_settings_sla; + SettingsBundle m_freq_settings_fff; + SettingsBundle m_freq_settings_sla; #endif public: @@ -209,7 +209,7 @@ public: void get_settings_choice(const wxString& category_name); void get_freq_settings_choice(const wxString& bundle_name); - void update_settings_item(); + void show_settings(const wxDataViewItem settings_item); wxMenu* append_submenu_add_generic(wxMenu* menu, const ModelVolumeType type); void append_menu_items_add_volume(wxMenu* menu); @@ -247,6 +247,7 @@ public: void layers_editing(); wxDataViewItem add_layer_root_item(const wxDataViewItem obj_item); + wxDataViewItem add_settings_item(wxDataViewItem parent_item, const DynamicPrintConfig* config); DynamicPrintConfig get_default_layer_config(const int obj_idx); bool get_volume_by_item(const wxDataViewItem& item, ModelVolume*& volume); @@ -258,6 +259,7 @@ public: wxBoxSizer* get_sizer() {return m_sizer;} int get_selected_obj_idx() const; DynamicPrintConfig& get_item_config(const wxDataViewItem& item) const; + SettingsBundle get_item_settings_bundle(const DynamicPrintConfig* config, const bool is_layers_range_settings); void changed_object(const int obj_idx = -1) const; void part_selection_changed(); diff --git a/src/slic3r/GUI/GUI_ObjectSettings.cpp b/src/slic3r/GUI/GUI_ObjectSettings.cpp index ab2614895c..16c64360a2 100644 --- a/src/slic3r/GUI/GUI_ObjectSettings.cpp +++ b/src/slic3r/GUI/GUI_ObjectSettings.cpp @@ -63,20 +63,28 @@ ObjectSettings::ObjectSettings(wxWindow* parent) : m_bmp_delete = ScalableBitmap(parent, "cross"); } -void ObjectSettings::update_settings_list() +bool ObjectSettings::update_settings_list() { m_settings_list_sizer->Clear(true); + m_og_settings.resize(0); auto objects_ctrl = wxGetApp().obj_list(); auto objects_model = wxGetApp().obj_list()->GetModel(); auto config = wxGetApp().obj_list()->config(); const auto item = objects_ctrl->GetSelection(); - const bool is_layers_range_settings = objects_model->GetItemType(objects_model->GetParent(item)) == itLayer; + + if (!item || !objects_model->IsSettingsItem(item) || !config || objects_ctrl->multiple_selection()) + return false; + + const bool is_layers_range_settings = objects_model->GetItemType(objects_model->GetParent(item)) == itLayer; + SettingsBundle cat_options = objects_ctrl->get_item_settings_bundle(config, is_layers_range_settings); + + if (!cat_options.empty()) + { + std::vector categories; + categories.reserve(cat_options.size()); - if (item && !objects_ctrl->multiple_selection() && - config && objects_model->IsSettingsItem(item)) - { auto extra_column = [config, this](wxWindow* parent, const Line& line) { auto opt_key = (line.get_options())[0].opt_id; //we assume that we have one option per line @@ -96,86 +104,61 @@ void ObjectSettings::update_settings_list() return btn; }; - std::map> cat_options; - auto opt_keys = config->keys(); - objects_ctrl->update_opt_keys(opt_keys); // update options list according to print technology - - m_og_settings.resize(0); - std::vector categories; - if (!(opt_keys.size() == 1 && opt_keys[0] == "extruder"))// return; + for (auto& cat : cat_options) { - const int extruders_cnt = wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA ? 1 : - wxGetApp().preset_bundle->printers.get_edited_preset().config.option("nozzle_diameter")->values.size(); + if (cat.second.size() == 1 && + (cat.second[0] == "extruder" || is_layers_range_settings && cat.second[0] == "layer_height")) + continue; - for (auto& opt_key : opt_keys) { - auto category = config->def()->get(opt_key)->category; - if (category.empty() || - (category == "Extruders" && extruders_cnt == 1)) continue; + categories.push_back(cat.first); - std::vector< std::string > new_category; + auto optgroup = std::make_shared(m_og->ctrl_parent(), _(cat.first), config, false, extra_column); + optgroup->label_width = 15; + optgroup->sidetext_width = 5.5; - auto& cat_opt = cat_options.find(category) == cat_options.end() ? new_category : cat_options.at(category); - cat_opt.push_back(opt_key); - if (cat_opt.size() == 1) - cat_options[category] = cat_opt; - } + optgroup->m_on_change = [](const t_config_option_key& opt_id, const boost::any& value) { + wxGetApp().obj_list()->changed_object(); }; - for (auto& cat : cat_options) { - if (cat.second.size() == 1 && - (cat.second[0] == "extruder" || is_layers_range_settings && cat.second[0] == "layer_height")) + // call back for rescaling of the extracolumn control + optgroup->rescale_extra_column_item = [this](wxWindow* win) { + auto *ctrl = dynamic_cast(win); + if (ctrl == nullptr) + return; + ctrl->SetBitmap_(m_bmp_delete); + }; + + const bool is_extruders_cat = cat.first == "Extruders"; + for (auto& opt : cat.second) + { + if (opt == "extruder" || is_layers_range_settings && opt == "layer_height") continue; - - auto optgroup = std::make_shared(m_og->ctrl_parent(), _(cat.first), config, false, extra_column); - optgroup->label_width = 15; - optgroup->sidetext_width = 5.5; - - optgroup->m_on_change = [](const t_config_option_key& opt_id, const boost::any& value) { - wxGetApp().obj_list()->changed_object(); }; - - const bool is_extruders_cat = cat.first == "Extruders"; - for (auto& opt : cat.second) - { - if (opt == "extruder" || is_layers_range_settings && opt == "layer_height") - continue; - Option option = optgroup->get_option(opt); - option.opt.width = 12; - if (is_extruders_cat) - option.opt.max = wxGetApp().extruders_cnt(); - optgroup->append_single_option_line(option); - } - optgroup->reload_config(); - m_settings_list_sizer->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 0); - - // call back for rescaling of the extracolumn control - optgroup->rescale_extra_column_item = [this](wxWindow* win) { - auto *ctrl = dynamic_cast(win); - if (ctrl == nullptr) - return; - ctrl->SetBitmap_(m_bmp_delete); - }; - - m_og_settings.push_back(optgroup); - - categories.push_back(cat.first); + Option option = optgroup->get_option(opt); + option.opt.width = 12; + if (is_extruders_cat) + option.opt.max = wxGetApp().extruders_edited_cnt(); + optgroup->append_single_option_line(option); } + optgroup->reload_config(); + + m_settings_list_sizer->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 0); + m_og_settings.push_back(optgroup); } - if (m_og_settings.empty()) { - objects_ctrl->select_item(objects_model->Delete(item)); - } - else { - if (!categories.empty()) - objects_model->UpdateSettingsDigest(item, categories); - } - } + if (!categories.empty()) + objects_model->UpdateSettingsDigest(item, categories); + } + else + { + objects_ctrl->select_item(objects_model->Delete(item)); + return false; + } + + return true; } void ObjectSettings::UpdateAndShow(const bool show) { - if (show) - update_settings_list(); - - OG_Settings::UpdateAndShow(show); + OG_Settings::UpdateAndShow(show ? update_settings_list() : false); } void ObjectSettings::msw_rescale() diff --git a/src/slic3r/GUI/GUI_ObjectSettings.hpp b/src/slic3r/GUI/GUI_ObjectSettings.hpp index 3d49f13b7f..01daa5622a 100644 --- a/src/slic3r/GUI/GUI_ObjectSettings.hpp +++ b/src/slic3r/GUI/GUI_ObjectSettings.hpp @@ -44,7 +44,7 @@ public: ObjectSettings(wxWindow* parent); ~ObjectSettings() {} - void update_settings_list(); + bool update_settings_list(); void UpdateAndShow(const bool show) override; void msw_rescale(); };