diff --git a/src/slic3r/GUI/BitmapCache.cpp b/src/slic3r/GUI/BitmapCache.cpp index bb4145107..551882410 100644 --- a/src/slic3r/GUI/BitmapCache.cpp +++ b/src/slic3r/GUI/BitmapCache.cpp @@ -259,9 +259,6 @@ wxBitmap* BitmapCache::load_svg(const std::string &bitmap_name, unsigned target_ wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency) { - width = width * 0.1f * Slic3r::GUI::wxGetApp().em_unit() + 0.5f; - height = height * 0.1f * Slic3r::GUI::wxGetApp().em_unit() + 0.5f; - wxImage image(width, height); image.InitAlpha(); unsigned char* imgdata = image.GetData(); diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index f8ad8b7bb..fe8b13fb7 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -463,8 +463,7 @@ void ObjectList::paste_volumes_into_list(int obj_idx, const ModelVolumePtrs& vol items.Add(vol_item); } - m_parts_changed = true; - parts_changed(obj_idx); + changed_object(obj_idx); if (items.size() > 1) { @@ -490,9 +489,7 @@ void ObjectList::paste_objects_into_list(const std::vector& object_idxs) items.Add(m_objects_model->GetItemById(object)); } - m_parts_changed = true; wxGetApp().plater()->changed_objects(object_idxs); - m_parts_changed = false; select_items(items); #ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME @@ -703,8 +700,7 @@ void ObjectList::OnDrop(wxDataViewEvent &event) select_item(m_objects_model->ReorganizeChildren(from_volume_id, to_volume_id, m_objects_model->GetParent(item))); - m_parts_changed = true; - parts_changed(m_dragged_data.obj_idx()); + changed_object(m_dragged_data.obj_idx()); m_dragged_data.clear(); } @@ -1290,7 +1286,7 @@ void ObjectList::load_subobject(ModelVolumeType type) wxArrayString part_names; load_part((*m_objects)[obj_idx], part_names, type); - parts_changed(obj_idx); + changed_object(obj_idx); for (int i = 0; i < part_names.size(); ++i) { const wxDataViewItem sel_item = m_objects_model->AddVolumeChild(item, part_names.Item(i), type); @@ -1306,7 +1302,6 @@ void ObjectList::load_part( ModelObject* model_object, { wxWindow* parent = wxGetApp().tab_panel()->GetPage(0); - m_parts_changed = false; wxArrayString input_files; wxGetApp().import_model(parent, input_files); for (int i = 0; i < input_files.size(); ++i) { @@ -1342,8 +1337,6 @@ void ObjectList::load_part( ModelObject* model_object, // set a default extruder value, since user can't add it manually new_volume->config.set_key_value("extruder", new ConfigOptionInt(0)); - - m_parts_changed = true; } } } @@ -1493,8 +1486,7 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode // set a default extruder value, since user can't add it manually new_volume->config.set_key_value("extruder", new ConfigOptionInt(0)); - m_parts_changed = true; - parts_changed(obj_idx); + changed_object(obj_idx); const auto object_item = m_objects_model->GetTopParent(GetSelection()); select_item(m_objects_model->AddVolumeChild(object_item, name, type)); @@ -1558,8 +1550,7 @@ void ObjectList::del_instances_from_object(const int obj_idx) (*m_objects)[obj_idx]->invalidate_bounding_box(); // ? #ys_FIXME - m_parts_changed = true; - parts_changed(obj_idx); + changed_object(obj_idx); } bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, const int type) @@ -1604,8 +1595,7 @@ bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, con else return false; - m_parts_changed = true; - parts_changed(obj_idx); + changed_object(obj_idx); return true; } @@ -1655,8 +1645,7 @@ void ObjectList::split() if (parent == item) Expand(parent); - m_parts_changed = true; - parts_changed(obj_idx); + changed_object(obj_idx); } bool ObjectList::get_volume_by_item(const wxDataViewItem& item, ModelVolume*& volume) @@ -1713,17 +1702,10 @@ bool ObjectList::can_split_instances() return selection.is_multiple_full_instance() || selection.is_single_full_instance(); } -void ObjectList::part_settings_changed() +// NO_PARAMETERS function call means that changed object index will be determine from Selection() +void ObjectList::changed_object(const int obj_idx/* = -1*/) const { - m_part_settings_changed = true; - wxGetApp().plater()->changed_object(get_selected_obj_idx()); - m_part_settings_changed = false; -} - -void ObjectList::parts_changed(int obj_idx) -{ - wxGetApp().plater()->changed_object(obj_idx); - m_parts_changed = false; + wxGetApp().plater()->changed_object(obj_idx < 0 ? get_selected_obj_idx() : obj_idx); } void ObjectList::part_selection_changed() @@ -2446,8 +2428,7 @@ void ObjectList::change_part_type() volume->set_type(new_type); m_objects_model->SetVolumeType(item, new_type); - m_parts_changed = true; - parts_changed(get_selected_obj_idx()); + changed_object(get_selected_obj_idx()); // Update settings showing, if we have it //(we show additional settings for Part and Modifier and hide it for Support Blocker/Enforcer) diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index a0343100a..7b3b2c744 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -139,8 +139,8 @@ class ObjectList : public wxDataViewCtrl // update_settings_items - updating canvas selection is undesirable, // because it would turn off the gizmos (mainly a problem for the SLA gizmo) - bool m_parts_changed = false; - bool m_part_settings_changed = false; +// bool m_parts_changed = false; +// bool m_part_settings_changed = false; int m_selected_row = 0; wxDataViewItem m_last_selected_item {nullptr}; @@ -225,11 +225,8 @@ public: wxBoxSizer* get_sizer() {return m_sizer;} int get_selected_obj_idx() const; DynamicPrintConfig& get_item_config(const wxDataViewItem& item) const; - bool is_parts_changed() const { return m_parts_changed; } - bool is_part_settings_changed() const { return m_part_settings_changed; } - void part_settings_changed(); - void parts_changed(int obj_idx); + void changed_object(const int obj_idx = -1) const; void part_selection_changed(); // Add object to the list diff --git a/src/slic3r/GUI/GUI_ObjectSettings.cpp b/src/slic3r/GUI/GUI_ObjectSettings.cpp index 72eeb76de..1c5ca5a32 100644 --- a/src/slic3r/GUI/GUI_ObjectSettings.cpp +++ b/src/slic3r/GUI/GUI_ObjectSettings.cpp @@ -84,7 +84,7 @@ void ObjectSettings::update_settings_list() #endif // __WXMSW__ btn->Bind(wxEVT_BUTTON, [opt_key, config, this](wxEvent &event) { config->erase(opt_key); - wxGetApp().obj_list()->part_settings_changed(); + wxGetApp().obj_list()->changed_object(); wxTheApp->CallAfter([this]() { wxWindowUpdateLocker noUpdates(m_parent); update_settings_list(); @@ -127,7 +127,7 @@ void ObjectSettings::update_settings_list() optgroup->sidetext_width = 5.5 * wxGetApp().em_unit(); optgroup->m_on_change = [](const t_config_option_key& opt_id, const boost::any& value) { - wxGetApp().obj_list()->part_settings_changed(); }; + wxGetApp().obj_list()->changed_object(); }; for (auto& opt : cat.second) { diff --git a/src/slic3r/GUI/GUI_Utils.hpp b/src/slic3r/GUI/GUI_Utils.hpp index e12153625..5418ea430 100644 --- a/src/slic3r/GUI/GUI_Utils.hpp +++ b/src/slic3r/GUI/GUI_Utils.hpp @@ -16,6 +16,7 @@ #include #include #include +#include class wxCheckBox; class wxTopLevelWindow; diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index a5d3a1f6d..a8b2be2bc 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -4,6 +4,7 @@ #include "libslic3r/PrintConfig.hpp" #include +#include #include #include diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 8eb68fc39..5bba6ce72 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -274,7 +274,7 @@ wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(15 * cfg.set_key_value("extruder_colour", colors); wxGetApp().get_tab(Preset::TYPE_PRINTER)->load_config(cfg); - wxGetApp().preset_bundle->update_platter_filament_ui(extruder_idx, this); + wxGetApp().preset_bundle->update_platter_filament_ui(extruder_idx, this, wxGetApp().em_unit()); wxGetApp().plater()->on_config_change(cfg); } dialog->Destroy(); @@ -800,7 +800,7 @@ void Sidebar::update_presets(Preset::Type preset_type) } for (size_t i = 0; i < filament_cnt; i++) { - preset_bundle.update_platter_filament_ui(i, p->combos_filament[i]); + preset_bundle.update_platter_filament_ui(i, p->combos_filament[i], wxGetApp().em_unit()); } break; @@ -835,7 +835,7 @@ void Sidebar::update_presets(Preset::Type preset_type) // update the dirty flags. if (print_tech == ptFFF) { for (size_t i = 0; i < p->combos_filament.size(); ++ i) - preset_bundle.update_platter_filament_ui(i, p->combos_filament[i]); + preset_bundle.update_platter_filament_ui(i, p->combos_filament[i], wxGetApp().em_unit()); } p->show_preset_comboboxes(); break; @@ -2599,7 +2599,7 @@ void Plater::priv::on_select_preset(wxCommandEvent &evt) // TODO: ? if (preset_type == Preset::TYPE_FILAMENT && sidebar->is_multifilament()) { // Only update the platter UI for the 2nd and other filaments. - wxGetApp().preset_bundle->update_platter_filament_ui(idx, combo); + wxGetApp().preset_bundle->update_platter_filament_ui(idx, combo, wxGetApp().em_unit()); } else { wxWindowUpdateLocker noUpdates(sidebar->presets_panel()); @@ -3580,7 +3580,7 @@ void Plater::on_extruders_change(int num_extruders) choices.push_back(choice); // initialize selection - wxGetApp().preset_bundle->update_platter_filament_ui(i, choice); + wxGetApp().preset_bundle->update_platter_filament_ui(i, choice, wxGetApp().em_unit()); ++i; } @@ -3709,22 +3709,16 @@ void Plater::changed_object(int obj_idx) { if (obj_idx < 0) return; - auto list = wxGetApp().obj_list(); - wxASSERT(list != nullptr); - if (list == nullptr) - return; - - if (list->is_parts_changed()) { - // recenter and re - align to Z = 0 - auto model_object = p->model.objects[obj_idx]; - model_object->ensure_on_bed(); - if (this->p->printer_technology == ptSLA) { - // Update the SLAPrint from the current Model, so that the reload_scene() - // pulls the correct data, update the 3D scene. - this->p->update_restart_background_process(true, false); - } else - p->view3D->reload_scene(false); + // recenter and re - align to Z = 0 + auto model_object = p->model.objects[obj_idx]; + model_object->ensure_on_bed(); + if (this->p->printer_technology == ptSLA) { + // Update the SLAPrint from the current Model, so that the reload_scene() + // pulls the correct data, update the 3D scene. + this->p->update_restart_background_process(true, false); } + else + p->view3D->reload_scene(false); // update print this->p->schedule_background_process(); @@ -3735,26 +3729,19 @@ void Plater::changed_objects(const std::vector& object_idxs) if (object_idxs.empty()) return; - auto list = wxGetApp().obj_list(); - wxASSERT(list != nullptr); - if (list == nullptr) - return; - - if (list->is_parts_changed()) { - for (int obj_idx : object_idxs) - { - if (obj_idx < p->model.objects.size()) - // recenter and re - align to Z = 0 - p->model.objects[obj_idx]->ensure_on_bed(); - } - if (this->p->printer_technology == ptSLA) { - // Update the SLAPrint from the current Model, so that the reload_scene() - // pulls the correct data, update the 3D scene. - this->p->update_restart_background_process(true, false); - } - else - p->view3D->reload_scene(false); + for (int obj_idx : object_idxs) + { + if (obj_idx < p->model.objects.size()) + // recenter and re - align to Z = 0 + p->model.objects[obj_idx]->ensure_on_bed(); } + if (this->p->printer_technology == ptSLA) { + // Update the SLAPrint from the current Model, so that the reload_scene() + // pulls the correct data, update the 3D scene. + this->p->update_restart_background_process(true, false); + } + else + p->view3D->reload_scene(false); // update print this->p->schedule_background_process(); diff --git a/src/slic3r/GUI/PresetBundle.cpp b/src/slic3r/GUI/PresetBundle.cpp index bcf76d958..5fdd38936 100644 --- a/src/slic3r/GUI/PresetBundle.cpp +++ b/src/slic3r/GUI/PresetBundle.cpp @@ -1443,7 +1443,7 @@ void PresetBundle::load_default_preset_bitmaps(wxWindow *window) this->load_compatible_bitmaps(window); } -void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, GUI::PresetComboBox *ui) +void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, GUI::PresetComboBox *ui, const int em/* = 10*/) { if (ui == nullptr || this->printers.get_edited_preset().printer_technology() == ptSLA || this->filament_presets.size() <= idx_extruder ) @@ -1468,6 +1468,18 @@ void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, GUI::Pr wxString selected_str = ""; if (!this->filaments().front().is_visible) ui->set_label_marker(ui->Append(PresetCollection::separator(L("System presets")), wxNullBitmap)); + + /* It's supposed that standard size of an icon is 16px*16px for 100% scaled display. + * So set sizes for solid_colored icons used for filament preset + * and scale then in respect to em_unit value + */ + const float scale_f = em * 0.1f; + const int icon_height = 16 * scale_f + 0.5f; + const int normal_icon_width = 16 * scale_f + 0.5f; + const int space_icon_width = 2 * scale_f + 0.5f; + const int wide_icon_width = 24 * scale_f + 0.5f; + const int thin_icon_width = 8 * scale_f + 0.5f; + for (int i = this->filaments().front().is_visible ? 0 : 1; i < int(this->filaments().size()); ++i) { const Preset &preset = this->filaments.preset(i); bool selected = this->filament_presets[idx_extruder] == preset.name; @@ -1491,17 +1503,17 @@ void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, GUI::Pr std::vector bmps; if (wide_icons) // Paint a red flag for incompatible presets. - bmps.emplace_back(preset.is_compatible ? m_bitmapCache->mkclear(16, 16) : *m_bitmapIncompatible); + bmps.emplace_back(preset.is_compatible ? m_bitmapCache->mkclear(normal_icon_width, icon_height) : *m_bitmapIncompatible); // Paint the color bars. parse_color(filament_rgb, rgb); - bmps.emplace_back(m_bitmapCache->mksolid(single_bar ? 24 : 16, 16, rgb)); + bmps.emplace_back(m_bitmapCache->mksolid(single_bar ? wide_icon_width : normal_icon_width, icon_height, rgb)); if (! single_bar) { parse_color(extruder_rgb, rgb); - bmps.emplace_back(m_bitmapCache->mksolid(8, 16, rgb)); + bmps.emplace_back(m_bitmapCache->mksolid(thin_icon_width, icon_height, rgb)); } // Paint a lock at the system presets. - bmps.emplace_back(m_bitmapCache->mkclear(2, 16)); - bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmapLock : m_bitmapCache->mkclear(16, 16)); + bmps.emplace_back(m_bitmapCache->mkclear(space_icon_width, icon_height)); + bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmapLock : m_bitmapCache->mkclear(normal_icon_width, icon_height)); // (preset.is_dirty ? *m_bitmapLockOpen : *m_bitmapLock) : m_bitmapCache->mkclear(16, 16)); bitmap = m_bitmapCache->insert(bitmap_key, bmps); } diff --git a/src/slic3r/GUI/PresetBundle.hpp b/src/slic3r/GUI/PresetBundle.hpp index 069ebd784..2309ceecd 100644 --- a/src/slic3r/GUI/PresetBundle.hpp +++ b/src/slic3r/GUI/PresetBundle.hpp @@ -107,7 +107,7 @@ public: void export_configbundle(const std::string &path, bool export_system_settings = false); // Update a filament selection combo box on the platter for an idx_extruder. - void update_platter_filament_ui(unsigned int idx_extruder, GUI::PresetComboBox *ui); + void update_platter_filament_ui(unsigned int idx_extruder, GUI::PresetComboBox *ui, const int em = 10); // Enable / disable the "- default -" preset. void set_default_suppressed(bool default_suppressed); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index a697c7a71..d1347d9e5 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1755,6 +1755,8 @@ void TabPrinter::build_fff() auto *nozzle_diameter = dynamic_cast(m_config->option("nozzle_diameter")); m_initial_extruders_count = m_extruders_count = nozzle_diameter->values.size(); + wxGetApp().sidebar().update_objects_list_extruder_column(m_initial_extruders_count); + const Preset* parent_preset = m_presets->get_selected_preset_parent(); m_sys_extruders_count = parent_preset == nullptr ? 0 : static_cast(parent_preset->config.option("nozzle_diameter"))->values.size(); @@ -1881,7 +1883,7 @@ void TabPrinter::build_fff() m_use_silent_mode = val; } } - build_extruder_pages(); + build_unregular_pages(); update_dirty(); on_value_change(opt_key, value); }); @@ -1948,7 +1950,7 @@ void TabPrinter::build_fff() }; optgroup->append_line(line); - build_extruder_pages(); + build_unregular_pages(); #if 0 if (!m_no_controller) @@ -2051,13 +2053,24 @@ void TabPrinter::update_serial_ports() void TabPrinter::extruders_count_changed(size_t extruders_count) { - m_extruders_count = extruders_count; - m_preset_bundle->printers.get_edited_preset().set_num_extruders(extruders_count); - m_preset_bundle->update_multi_material_filament_presets(); - build_extruder_pages(); - reload_config(); - on_value_change("extruders_count", extruders_count); - wxGetApp().sidebar().update_objects_list_extruder_column(extruders_count); + bool is_count_changed = false; + if (m_extruders_count != extruders_count) { + m_extruders_count = extruders_count; + m_preset_bundle->printers.get_edited_preset().set_num_extruders(extruders_count); + m_preset_bundle->update_multi_material_filament_presets(); + is_count_changed = true; + } + + /* This function should be call in any case because of correct updating/rebuilding + * of unregular pages of a Printer Settings + */ + build_unregular_pages(); +// reload_config(); // #ys_FIXME_delete_after_testing : This function is called from build_extruder_pages() now + + if (is_count_changed) { + on_value_change("extruders_count", extruders_count); + wxGetApp().sidebar().update_objects_list_extruder_column(extruders_count); + } } void TabPrinter::append_option_line(ConfigOptionsGroupShp optgroup, const std::string opt_key) @@ -2125,12 +2138,23 @@ PageShp TabPrinter::build_kinematics_page() return page; } - -void TabPrinter::build_extruder_pages() +/* Previous name build_extruder_pages(). + * + * This function was renamed because of now it implements not just an extruder pages building, + * but "Machine limits" and "Single extruder MM setup" too + * (These pages can changes according to the another values of a current preset) + * */ +void TabPrinter::build_unregular_pages() { size_t n_before_extruders = 2; // Count of pages before Extruder pages bool is_marlin_flavor = m_config->option>("gcode_flavor")->value == gcfMarlin; + /* ! Freeze/Thaw in this function is needed to avoid call OnPaint() for erased pages + * and be cause of application crash, when try to change Preset in moment, + * when one of unregular pages is selected. + * */ + Freeze(); + // Add/delete Kinematics page according to is_marlin_flavor size_t existed_page = 0; for (int i = n_before_extruders; i < m_pages.size(); ++i) // first make sure it's not there already @@ -2175,12 +2199,11 @@ void TabPrinter::build_extruder_pages() m_has_single_extruder_MM_page = true; } - + // Build missed extruder pages for (auto extruder_idx = m_extruders_count_old; extruder_idx < m_extruders_count; ++extruder_idx) { //# build page - char buf[512]; - sprintf(buf, _CHB(L("Extruder %d")), extruder_idx + 1); - auto page = add_options_page(from_u8(buf), "funnel", true); + const wxString& page_name = wxString::Format(_(L("Extruder %d")), int(extruder_idx + 1)); + auto page = add_options_page(page_name, "funnel", true); m_pages.insert(m_pages.begin() + n_before_extruders + extruder_idx, page); auto optgroup = page->new_optgroup(_(L("Size"))); @@ -2223,8 +2246,13 @@ void TabPrinter::build_extruder_pages() m_pages.erase( m_pages.begin() + n_before_extruders + m_extruders_count, m_pages.begin() + n_before_extruders + m_extruders_count_old); + Thaw(); + m_extruders_count_old = m_extruders_count; rebuild_page_tree(); + + // Reload preset pages with current configuration values + reload_config(); } // this gets executed after preset is loaded and before GUI fields are updated @@ -2492,7 +2520,6 @@ void Tab::rebuild_page_tree() m_treectrl->SelectItem(item); } } -// Thaw(); } void Tab::update_page_tree_visibility() @@ -2728,7 +2755,8 @@ bool Tab::may_switch_to_SLA_preset() void Tab::OnTreeSelChange(wxTreeEvent& event) { - if (m_disable_tree_sel_changed_event) return; + if (m_disable_tree_sel_changed_event) + return; // There is a bug related to Ubuntu overlay scrollbars, see https://github.com/prusa3d/Slic3r/issues/898 and https://github.com/prusa3d/Slic3r/issues/952. // The issue apparently manifests when Show()ing a window with overlay scrollbars while the UI is frozen. For this reason, diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 58950990c..69cf76043 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -368,7 +368,7 @@ public: void update_serial_ports(); void extruders_count_changed(size_t extruders_count); PageShp build_kinematics_page(); - void build_extruder_pages(); + void build_unregular_pages(); void on_preset_loaded() override; void init_options_list() override; bool supports_printer_technology(const PrinterTechnology /* tech */) override { return true; }