diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 29d23eee58..8efb4ff307 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -29,7 +29,8 @@ namespace Slic3r { namespace GUI { } } - void Field::PostInitialize(){ + void Field::PostInitialize() + { auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); m_Undo_btn = new MyButton(m_parent, wxID_ANY, "", wxDefaultPosition,wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); m_Undo_to_sys_btn = new MyButton(m_parent, wxID_ANY, "", wxDefaultPosition,wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); @@ -65,7 +66,8 @@ namespace Slic3r { namespace GUI { BUILD(); } - void Field::on_kill_focus(wxEvent& event) { + void Field::on_kill_focus(wxEvent& event) + { // Without this, there will be nasty focus bugs on Windows. // Also, docs for wxEvent::Skip() say "In general, it is recommended to skip all // non-command events to allow the default handling to take place." @@ -81,12 +83,14 @@ namespace Slic3r { namespace GUI { m_on_change(m_opt_id, get_value()); } - void Field::on_back_to_initial_value(){ + void Field::on_back_to_initial_value() + { if (m_back_to_initial_value != nullptr && m_is_modified_value) m_back_to_initial_value(m_opt_id); } - void Field::on_back_to_sys_value(){ + void Field::on_back_to_sys_value() + { if (m_back_to_sys_value != nullptr && m_is_nonsys_value) m_back_to_sys_value(m_opt_id); } diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 2ebdf7e408..b74edcd8ab 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1091,7 +1091,7 @@ void ObjectList::add_object_to_list(size_t obj_idx) auto stats = model_object->volumes[0]->mesh.stl.stats; int errors = stats.degenerate_facets + stats.edges_fixed + stats.facets_removed + stats.facets_added + stats.facets_reversed + stats.backwards_edges; - if (errors > 0) { + if (errors > 0) { wxVariant variant; variant << PrusaDataViewBitmapText(item_name, m_bmp_manifold_warning); m_objects_model->SetValue(variant, item, 0); @@ -1241,7 +1241,7 @@ void ObjectList::update_selections_on_canvas() auto add_to_selection = [this](const wxDataViewItem& item, GLCanvas3D::Selection& selection, bool as_single_selection) { - if (m_objects_model->GetParent(item) == wxDataViewItem(0)){ + if (m_objects_model->GetParent(item) == wxDataViewItem(0)) { selection.add_object(m_objects_model->GetIdByItem(item), as_single_selection); return; } diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index ca35871187..344fb38ad9 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -268,7 +268,7 @@ void ObjectManipulation::update_settings_value(const GLCanvas3D::Selection& sele { if (selection.is_single_full_object()) { - if (wxGetApp().mainframe->m_plater->model().objects[selection.get_object_idx()]->instances.size() == 1) + if (!wxGetApp().model_objects()->empty() && (*wxGetApp().model_objects())[selection.get_object_idx()]->instances.size() == 1) { // all volumes in the selection belongs to the same instance, any of them contains the needed data, so we take the first const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); diff --git a/src/slic3r/GUI/LambdaObjectDialog.hpp b/src/slic3r/GUI/LambdaObjectDialog.hpp index 9ee7824fcb..3a4d0cf054 100644 --- a/src/slic3r/GUI/LambdaObjectDialog.hpp +++ b/src/slic3r/GUI/LambdaObjectDialog.hpp @@ -44,7 +44,7 @@ public: ~LambdaObjectDialog(){} bool CanClose() { return true; } // ??? - OBJECT_PARAMETERS& ObjectParameters(){ return object_parameters; } + OBJECT_PARAMETERS& ObjectParameters() { return object_parameters; } ConfigOptionsGroupShp init_modificator_options_page(const wxString& title); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index d538a0f536..e9deed020d 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -132,18 +132,27 @@ ObjectInfo::ObjectInfo(wxWindow *parent) : Add(grid_sizer, 0, wxEXPAND); } +enum SlisedInfoIdx +{ + siFilament_m, + siFilament_mm3, + siFilament_g, + siCost, + siTimeNormal, + siTimeSilent, + siWTNumbetOfToolchanges, + + siCount +}; + class SlicedInfo : public wxStaticBoxSizer { public: SlicedInfo(wxWindow *parent); + void SetTextAndShow(SlisedInfoIdx idx, const wxString& text); private: - wxStaticText *info_filament_m; - wxStaticText *info_filament_mm3; - wxStaticText *info_filament_g; - wxStaticText *info_cost; - wxStaticText *info_time_normal; - wxStaticText *info_time_silent; + std::vector> info_vec; }; SlicedInfo::SlicedInfo(wxWindow *parent) : @@ -155,23 +164,37 @@ SlicedInfo::SlicedInfo(wxWindow *parent) : grid_sizer->SetFlexibleDirection(wxHORIZONTAL); grid_sizer->AddGrowableCol(1, 1); - auto init_info_label = [parent, grid_sizer](wxStaticText *&info_label, wxString text_label) { + info_vec.reserve(siCount); + + auto init_info_label = [this, parent, grid_sizer](wxString text_label) { auto *text = new wxStaticText(parent, wxID_ANY, text_label); text->SetFont(wxGetApp().small_font()); - info_label = new wxStaticText(parent, wxID_ANY, "N/A"); + auto info_label = new wxStaticText(parent, wxID_ANY, "N/A"); info_label->SetFont(wxGetApp().small_font()); grid_sizer->Add(text, 0); grid_sizer->Add(info_label, 0); + info_vec.push_back(std::pair(text, info_label)); }; - init_info_label(info_filament_m, _(L("Used Filament (m)"))); - init_info_label(info_filament_mm3, _(L("Used Filament (mm³)"))); - init_info_label(info_filament_g, _(L("Used Filament (g)"))); - init_info_label(info_cost, _(L("Cost"))); - init_info_label(info_time_normal, _(L("Estimated printing time (normal mode)"))); - init_info_label(info_time_silent, _(L("Estimated printing time (silent mode)"))); + init_info_label(_(L("Used Filament (m)"))); + init_info_label(_(L("Used Filament (mm³)"))); + init_info_label(_(L("Used Filament (g)"))); + init_info_label(_(L("Cost"))); + init_info_label(_(L("Estimated printing time (normal mode)"))); + init_info_label(_(L("Estimated printing time (silent mode)"))); + init_info_label(_(L("Number of tool changes"))); Add(grid_sizer, 0, wxEXPAND); + this->Show(false); +} + +void SlicedInfo::SetTextAndShow(SlisedInfoIdx idx, const wxString& text) +{ + const bool show = text != "N/A"; + if (show) + info_vec[idx].second->SetLabelText(text); + info_vec[idx].first->Show(show); + info_vec[idx].second->Show(show); } PresetComboBox::PresetComboBox(wxWindow *parent, Preset::Type preset_type) : @@ -633,7 +656,43 @@ void Sidebar::show_info_sizers(const bool show) { p->object_info->Show(show); p->object_info->manifold_warning_icon->Show(show && p->show_manifold_warning_icon); // where is g_show_manifold_warning_icon updating? #ys_FIXME - p->sliced_info->Show(show && p->show_print_info); // where is g_show_print_info updating? #ys_FIXME +// p->sliced_info->Show(show && p->show_print_info); +} + +void Sidebar::show_sliced_info_sizer(const bool show) +{ + p->plater->Freeze(); +// p->show_print_info = show; + p->sliced_info->Show(show); + if (show) { + const PrintStatistics& ps = p->plater->print().print_statistics(); + const bool is_wipe_tower = ps.total_wipe_tower_filament > 0; + + wxString info_text = is_wipe_tower ? + wxString::Format("%.2f (%.2f %s + %.2f %s)", ps.total_used_filament / 1000, + (ps.total_used_filament - ps.total_wipe_tower_filament) / 1000, _(L("objects")), + ps.total_wipe_tower_filament / 1000, _(L("wipe tower"))) : + wxString::Format("%.2f", ps.total_used_filament / 1000); + p->sliced_info->SetTextAndShow(siFilament_m, info_text); + p->sliced_info->SetTextAndShow(siFilament_mm3, wxString::Format("%.2f", ps.total_extruded_volume)); + p->sliced_info->SetTextAndShow(siFilament_g, wxString::Format("%.2f", ps.total_weight)); + + info_text = is_wipe_tower ? + wxString::Format("%.2f (%.2f %s + %.2f %s)", ps.total_cost, + (ps.total_cost - ps.total_wipe_tower_cost), _(L("objects")), + ps.total_wipe_tower_cost, _(L("wipe tower"))) : + wxString::Format("%.2f", ps.total_cost); + p->sliced_info->SetTextAndShow(siCost, info_text); + p->sliced_info->SetTextAndShow(siTimeNormal, ps.estimated_normal_print_time); + p->sliced_info->SetTextAndShow(siTimeSilent, ps.estimated_silent_print_time); + + // if there is a wipe tower, insert number of toolchanges info into the array: + p->sliced_info->SetTextAndShow(siWTNumbetOfToolchanges, is_wipe_tower ? wxString::Format("%.d", p->plater->print().wipe_tower_data().number_of_toolchanges) : "N/A"); + } + + p->scrolled->Layout(); + p->plater->Layout(); + p->plater->Thaw(); } void Sidebar::show_buttons(const bool show) @@ -1678,7 +1737,7 @@ void Plater::priv::async_apply_config() if (invalidated == Print::APPLY_STATUS_INVALIDATED) { // Some previously calculated data on the Print was invalidated. // Hide the slicing results, as the current slicing status is no more valid. - this->sidebar->show_info_sizers(false); + this->sidebar->show_sliced_info_sizer(false); // Reset preview canvases. If the print has been invalidated, the preview canvases will be cleared. // Otherwise they will be just refreshed. this->gcode_preview_data.reset(); @@ -1858,7 +1917,7 @@ void Plater::priv::on_process_completed(wxCommandEvent &evt) if (canceled) this->statusbar()->set_status_text(L("Cancelled")); - this->sidebar->show_info_sizers(success); + this->sidebar->show_sliced_info_sizer(success); // this updates buttons status //$self->object_list_changed; diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 4c6d0ff302..0a69e68bda 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -78,6 +78,7 @@ public: wxButton* get_wiping_dialog_button(); void update_objects_list_extruder_column(int extruders_count); void show_info_sizers(const bool show); + void show_sliced_info_sizer(const bool show); void show_buttons(const bool show); void show_button(ButtonAction but_action, bool show); void enable_buttons(bool enable);