diff --git a/resources/config.json b/resources/config.json index 2eea04ed9..56482f373 100644 --- a/resources/config.json +++ b/resources/config.json @@ -18,6 +18,7 @@ "FUNC_ALTER_RESOLUTION": false, "FUNC_AUTO_SWITCH_FILAMENT": false, "FUNC_CHAMBER_FAN" : false, + "FUNC_EXTRUSION_CALI": true, "FUNC_SEND_TO_SDCARD": false }, "camera_resolution":["720p"], @@ -29,6 +30,7 @@ { "display_name": "Bambu Lab X1", "func": { + "FUNC_EXTRUSION_CALI": false, "FUNC_LOCAL_TUNNEL": false }, "camera_resolution":["720p","1080p"], @@ -39,6 +41,7 @@ { "display_name": "Bambu Lab X1 Carbon", "func": { + "FUNC_EXTRUSION_CALI": false, "FUNC_LOCAL_TUNNEL": false }, "model_id": "BL-P001", diff --git a/resources/images/extrusion_calibrati_open_button.svg b/resources/images/extrusion_calibrati_open_button.svg new file mode 100644 index 000000000..d6190e25c --- /dev/null +++ b/resources/images/extrusion_calibrati_open_button.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/resources/images/extrusion_calibration_tips.png b/resources/images/extrusion_calibration_tips.png new file mode 100644 index 000000000..b76ab1c66 Binary files /dev/null and b/resources/images/extrusion_calibration_tips.png differ diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 8ea21fb58..feca4025c 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -153,6 +153,8 @@ set(SLIC3R_GUI_SOURCES GUI/AMSSetting.hpp GUI/AMSMaterialsSetting.cpp GUI/AMSMaterialsSetting.hpp + GUI/ExtrusionCalibration.cpp + GUI/ExtrusionCalibration.hpp GUI/PresetHints.cpp GUI/PresetHints.hpp GUI/GUI.cpp diff --git a/src/slic3r/GUI/AMSMaterialsSetting.cpp b/src/slic3r/GUI/AMSMaterialsSetting.cpp index d5ef155c3..d6820a0ed 100644 --- a/src/slic3r/GUI/AMSMaterialsSetting.cpp +++ b/src/slic3r/GUI/AMSMaterialsSetting.cpp @@ -1,4 +1,6 @@ #include "AMSMaterialsSetting.hpp" +#include "ExtrusionCalibration.hpp" +#include "MsgDialog.hpp" #include "GUI_App.hpp" #include "libslic3r/Preset.hpp" #include "I18N.hpp" @@ -6,11 +8,6 @@ namespace Slic3r { namespace GUI { static bool show_flag; -#ifdef __APPLE__ -#define COMBOBOX_FILAMENT (m_comboBox_filament_mac) -#else -#define COMBOBOX_FILAMENT (m_comboBox_filament) -#endif AMSMaterialsSetting::AMSMaterialsSetting(wxWindow *parent, wxWindowID id) : DPIDialog(parent, id, _L("AMS Materials Setting"), wxDefaultPosition, wxDefaultSize, wxBORDER_NONE) { @@ -23,173 +20,10 @@ void AMSMaterialsSetting::create() SetBackgroundColour(*wxWHITE); wxBoxSizer *m_sizer_main = new wxBoxSizer(wxVERTICAL); - wxBoxSizer *m_sizer_filament = new wxBoxSizer(wxHORIZONTAL); - - m_title_filament = new wxStaticText(this, wxID_ANY, _L("Filament"), wxDefaultPosition, wxSize(AMS_MATERIALS_SETTING_LABEL_WIDTH, -1), 0); - m_title_filament->SetFont(::Label::Body_13); - m_title_filament->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800); - m_title_filament->Wrap(-1); - m_sizer_filament->Add(m_title_filament, 0, wxALIGN_CENTER, 0); - - m_sizer_filament->Add(0, 0, 0, wxEXPAND, 0); - -#ifdef __APPLE__ - m_comboBox_filament_mac = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, AMS_MATERIALS_SETTING_COMBOX_WIDTH, 0, nullptr, wxCB_READONLY); -#else - m_comboBox_filament = new ::ComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, AMS_MATERIALS_SETTING_COMBOX_WIDTH, 0, nullptr, wxCB_READONLY); -#endif - - m_sizer_filament->Add(COMBOBOX_FILAMENT, 1, wxALIGN_CENTER, 0); - - m_readonly_filament = new TextInput(this, wxEmptyString, "", "", wxDefaultPosition, AMS_MATERIALS_SETTING_COMBOX_WIDTH, wxTE_READONLY); - m_readonly_filament->SetBorderColor(StateColor(std::make_pair(0xDBDBDB, (int)StateColor::Focused), std::make_pair(0x00AE42, (int)StateColor::Hovered), - std::make_pair(0xDBDBDB, (int)StateColor::Normal))); - m_readonly_filament->GetTextCtrl()->Bind(wxEVT_SET_FOCUS, [](auto& e) { - ; - }); - m_sizer_filament->Add(m_readonly_filament, 1, wxALIGN_CENTER, 0); - m_readonly_filament->Hide(); - - wxBoxSizer *m_sizer_colour = new wxBoxSizer(wxHORIZONTAL); - - m_title_colour = new wxStaticText(this, wxID_ANY, _L("Colour"), wxDefaultPosition, wxSize(AMS_MATERIALS_SETTING_LABEL_WIDTH, -1), 0); - m_title_colour->SetFont(::Label::Body_13); - m_title_colour->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800); - m_title_colour->Wrap(-1); - m_sizer_colour->Add(m_title_colour, 0, wxALIGN_CENTER, 0); - - m_sizer_colour->Add(0, 0, 0, wxEXPAND, 0); - - m_clrData = new wxColourData(); - m_clrData->SetChooseFull(true); - m_clrData->SetChooseAlpha(false); - - m_clr_picker = new Button(this, wxEmptyString, wxEmptyString, wxBU_AUTODRAW); - m_clr_picker->SetCanFocus(false); - m_clr_picker->SetSize(FromDIP(50), FromDIP(25)); - m_clr_picker->SetMinSize(wxSize(FromDIP(50), FromDIP(25))); - m_clr_picker->SetCornerRadius(FromDIP(6)); - m_clr_picker->SetBorderColor(wxColour(172, 172, 172)); - m_clr_picker->Bind(wxEVT_BUTTON, &AMSMaterialsSetting::on_clr_picker, this); - m_sizer_colour->Add(m_clr_picker, 0, 0, 0); - - wxBoxSizer *m_sizer_temperature = new wxBoxSizer(wxHORIZONTAL); - m_title_temperature = new wxStaticText(this, wxID_ANY, _L("Nozzle\nTemperature"), wxDefaultPosition, wxSize(AMS_MATERIALS_SETTING_LABEL_WIDTH, -1), 0); - m_title_temperature->SetFont(::Label::Body_13); - m_title_temperature->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800); - m_title_temperature->Wrap(-1); - m_sizer_temperature->Add(m_title_temperature, 0, wxALIGN_CENTER, 0); - - m_sizer_temperature->Add(0, 0, 0, wxEXPAND, 0); - - wxBoxSizer *sizer_other = new wxBoxSizer(wxVERTICAL); - wxBoxSizer *sizer_tempinput = new wxBoxSizer(wxHORIZONTAL); - - m_input_nozzle_max = new ::TextInput(this, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, AMS_MATERIALS_SETTING_INPUT_SIZE, wxTE_CENTRE | wxTE_PROCESS_ENTER); - m_input_nozzle_min = new ::TextInput(this, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, AMS_MATERIALS_SETTING_INPUT_SIZE, wxTE_CENTRE | wxTE_PROCESS_ENTER); - m_input_nozzle_max->Enable(false); - m_input_nozzle_min->Enable(false); - - m_input_nozzle_max->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); - m_input_nozzle_max->GetTextCtrl()->SetSize(wxSize(-1, FromDIP(20))); - m_input_nozzle_min->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); - m_input_nozzle_min->GetTextCtrl()->SetSize(wxSize(-1, FromDIP(20))); - - auto bitmap_max_degree = new wxStaticBitmap(this, -1, create_scaled_bitmap("degree", nullptr, 16), wxDefaultPosition, wxDefaultSize); - auto bitmap_min_degree = new wxStaticBitmap(this, -1, create_scaled_bitmap("degree", nullptr, 16), wxDefaultPosition, wxDefaultSize); - - sizer_tempinput->Add(m_input_nozzle_max, 1, wxALIGN_CENTER, 0); - sizer_tempinput->Add(bitmap_min_degree, 0, wxALIGN_CENTER, 0); - sizer_tempinput->Add(FromDIP(10), 0, 0, 0); - sizer_tempinput->Add(m_input_nozzle_min, 1, wxALIGN_CENTER, 0); - sizer_tempinput->Add(bitmap_max_degree, 0, wxALIGN_CENTER, 0); - - wxBoxSizer *sizer_temp_txt = new wxBoxSizer(wxHORIZONTAL); - auto m_title_max = new wxStaticText(this, wxID_ANY, _L("max"), wxDefaultPosition, AMS_MATERIALS_SETTING_INPUT_SIZE); - m_title_max->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800); - m_title_max->SetFont(::Label::Body_13); - auto m_title_min = new wxStaticText(this, wxID_ANY, _L("min"), wxDefaultPosition, AMS_MATERIALS_SETTING_INPUT_SIZE); - m_title_min->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800); - m_title_min->SetFont(::Label::Body_13); - sizer_temp_txt->Add(m_title_max, 1, wxALIGN_CENTER, 0); - sizer_temp_txt->Add(FromDIP(10), 0, 0, 0); - sizer_temp_txt->Add(m_title_min, 1, wxALIGN_CENTER | wxRIGHT, FromDIP(16)); - - - sizer_other->Add(sizer_temp_txt, 0, wxALIGN_CENTER, 0); - sizer_other->Add(sizer_tempinput, 0, wxALIGN_CENTER, 0); - - m_sizer_temperature->Add(sizer_other, 0, wxALL | wxALIGN_CENTER, 0); - m_sizer_temperature->AddStretchSpacer(); - - wxString warning_string = wxString::FromUTF8( - (boost::format(_u8L("The input value should be greater than %1% and less than %2%")) % FILAMENT_MIN_TEMP % FILAMENT_MAX_TEMP).str()); - warning_text = new wxStaticText(this, wxID_ANY, warning_string, wxDefaultPosition, wxDefaultSize, 0); - warning_text->SetFont(::Label::Body_13); - warning_text->SetForegroundColour(wxColour(255, 111, 0)); - - warning_text->Wrap(AMS_MATERIALS_SETTING_BODY_WIDTH); - warning_text->SetMinSize(wxSize(AMS_MATERIALS_SETTING_BODY_WIDTH, -1)); - warning_text->Hide(); - - m_input_nozzle_min->GetTextCtrl()->Bind(wxEVT_SET_FOCUS, [this](wxFocusEvent &e) { - warning_text->Hide(); - Layout(); - Fit(); - e.Skip(); - }); - m_input_nozzle_min->GetTextCtrl()->Bind(wxEVT_TEXT_ENTER, [this](wxCommandEvent &e) { - input_min_finish(); - e.Skip(); - }); - m_input_nozzle_min->GetTextCtrl()->Bind(wxEVT_KILL_FOCUS, [this](wxFocusEvent &e) { - input_min_finish(); - e.Skip(); - }); - - m_input_nozzle_max->GetTextCtrl()->Bind(wxEVT_SET_FOCUS, [this](wxFocusEvent &e) { - warning_text->Hide(); - Layout(); - Fit(); - e.Skip(); - }); - m_input_nozzle_max->GetTextCtrl()->Bind(wxEVT_TEXT_ENTER, [this](wxCommandEvent &e) { - input_max_finish(); - e.Skip(); - }); - m_input_nozzle_max->GetTextCtrl()->Bind(wxEVT_KILL_FOCUS, [this](wxFocusEvent &e) { - input_max_finish(); - e.Skip(); - }); - - m_panel_SN = new wxPanel(this, wxID_ANY); - wxBoxSizer *m_sizer_SN = new wxBoxSizer(wxVERTICAL); - m_sizer_SN->AddSpacer(FromDIP(16)); - - wxBoxSizer *m_sizer_SN_inside = new wxBoxSizer(wxHORIZONTAL); - - auto m_title_SN = new wxStaticText(m_panel_SN, wxID_ANY, _L("SN"), wxDefaultPosition, wxSize(AMS_MATERIALS_SETTING_LABEL_WIDTH, -1), 0); - m_title_SN->SetFont(::Label::Body_13); - m_title_SN->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800); - m_title_SN->Wrap(-1); - m_sizer_SN_inside->Add(m_title_SN, 0, wxALIGN_CENTER, 0); - - m_sizer_SN_inside->Add(0, 0, 0, wxEXPAND, 0); - - m_sn_number = new wxStaticText(m_panel_SN, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize); - m_sn_number->SetForegroundColour(*wxBLACK); - m_sizer_SN_inside->Add(m_sn_number, 0, wxALIGN_CENTER, 0); - m_sizer_SN->Add(m_sizer_SN_inside); - - m_panel_SN->SetSizer(m_sizer_SN); - m_panel_SN->Layout(); - m_panel_SN->Fit(); - - wxBoxSizer* m_tip_sizer = new wxBoxSizer(wxHORIZONTAL); - m_tip_readonly = new wxStaticText(this, wxID_ANY, _L("Setting AMS slot information while printing is not supported"), wxDefaultPosition, wxSize(-1, AMS_MATERIALS_SETTING_INPUT_SIZE.y)); - m_tip_readonly->SetForegroundColour(*wxBLACK); - m_tip_readonly->Hide(); - m_tip_sizer->Add(m_tip_readonly, 0, wxALIGN_CENTER | wxRIGHT, FromDIP(20)); + m_panel_normal = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + create_panel_normal(m_panel_normal); + m_panel_kn = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + create_panel_kn(m_panel_kn); wxBoxSizer *m_sizer_button = new wxBoxSizer(wxHORIZONTAL); @@ -219,17 +53,11 @@ void AMSMaterialsSetting::create() m_sizer_button->Add(m_button_confirm, 0, wxALIGN_CENTER | wxRIGHT, FromDIP(20)); m_sizer_button->Add(m_button_close, 0, wxALIGN_CENTER, 0); - m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(16)); - m_sizer_main->Add(m_sizer_filament, 0, wxLEFT | wxRIGHT, FromDIP(20)); - m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(16)); - m_sizer_main->Add(m_sizer_colour, 0, wxLEFT | wxRIGHT, FromDIP(20)); - m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(16)); - m_sizer_main->Add(m_sizer_temperature, 0, wxLEFT | wxRIGHT, FromDIP(20)); - m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(5)); - m_sizer_main->Add(warning_text, 0, wxLEFT | wxRIGHT, FromDIP(20)); - m_sizer_main->Add(m_panel_SN, 0, wxLEFT, FromDIP(20)); + m_sizer_main->Add(m_panel_normal, 0, wxALL, FromDIP(2)); + + m_sizer_main->Add(m_panel_kn, 0, wxALL, FromDIP(2)); + m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(24)); - m_sizer_main->Add(m_tip_sizer, 0, wxLEFT, FromDIP(20)); m_sizer_main->Add(m_sizer_button, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(20)); m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(16)); @@ -237,8 +65,240 @@ void AMSMaterialsSetting::create() Layout(); Fit(); - Bind(wxEVT_PAINT, &AMSMaterialsSetting::paintEvent, this); - COMBOBOX_FILAMENT->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(AMSMaterialsSetting::on_select_filament), NULL, this); + m_input_nozzle_min->GetTextCtrl()->Bind(wxEVT_SET_FOCUS, [this](wxFocusEvent& e) { + warning_text->Hide(); + Layout(); + Fit(); + e.Skip(); + }); + m_input_nozzle_min->GetTextCtrl()->Bind(wxEVT_TEXT_ENTER, [this](wxCommandEvent& e) { + input_min_finish(); + e.Skip(); + }); + m_input_nozzle_min->GetTextCtrl()->Bind(wxEVT_KILL_FOCUS, [this](wxFocusEvent& e) { + input_min_finish(); + e.Skip(); + }); + + m_input_nozzle_max->GetTextCtrl()->Bind(wxEVT_SET_FOCUS, [this](wxFocusEvent& e) { + warning_text->Hide(); + Layout(); + Fit(); + e.Skip(); + }); + m_input_nozzle_max->GetTextCtrl()->Bind(wxEVT_TEXT_ENTER, [this](wxCommandEvent& e) { + input_max_finish(); + e.Skip(); + }); + m_input_nozzle_max->GetTextCtrl()->Bind(wxEVT_KILL_FOCUS, [this](wxFocusEvent& e) { + input_max_finish(); + e.Skip(); + }); + + Bind(wxEVT_PAINT, &AMSMaterialsSetting::paintEvent, this); + m_comboBox_filament->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(AMSMaterialsSetting::on_select_filament), NULL, this); +} + +void AMSMaterialsSetting::create_panel_normal(wxWindow* parent) +{ + auto sizer = new wxBoxSizer(wxVERTICAL); + + wxBoxSizer* m_sizer_filament = new wxBoxSizer(wxHORIZONTAL); + + m_title_filament = new wxStaticText(parent, wxID_ANY, _L("Filament"), wxDefaultPosition, wxSize(AMS_MATERIALS_SETTING_LABEL_WIDTH, -1), 0); + m_title_filament->SetFont(::Label::Body_13); + m_title_filament->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800); + m_title_filament->Wrap(-1); + m_sizer_filament->Add(m_title_filament, 0, wxALIGN_CENTER, 0); + + m_sizer_filament->Add(0, 0, 0, wxEXPAND, 0); + +#ifdef __APPLE__ + m_comboBox_filament = new wxComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, AMS_MATERIALS_SETTING_COMBOX_WIDTH, 0, nullptr, wxCB_READONLY); +#else + m_comboBox_filament = new ::ComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, AMS_MATERIALS_SETTING_COMBOX_WIDTH, 0, nullptr, wxCB_READONLY); +#endif + + m_sizer_filament->Add(m_comboBox_filament, 1, wxALIGN_CENTER, 0); + + m_readonly_filament = new TextInput(parent, wxEmptyString, "", "", wxDefaultPosition, AMS_MATERIALS_SETTING_COMBOX_WIDTH, wxTE_READONLY); + m_readonly_filament->SetBorderColor(StateColor(std::make_pair(0xDBDBDB, (int)StateColor::Focused), std::make_pair(0x00AE42, (int)StateColor::Hovered), + std::make_pair(0xDBDBDB, (int)StateColor::Normal))); + m_readonly_filament->GetTextCtrl()->Bind(wxEVT_SET_FOCUS, [](auto& e) { + ; + }); + m_sizer_filament->Add(m_readonly_filament, 1, wxALIGN_CENTER, 0); + m_readonly_filament->Hide(); + + wxBoxSizer* m_sizer_colour = new wxBoxSizer(wxHORIZONTAL); + + m_title_colour = new wxStaticText(parent, wxID_ANY, _L("Colour"), wxDefaultPosition, wxSize(AMS_MATERIALS_SETTING_LABEL_WIDTH, -1), 0); + m_title_colour->SetFont(::Label::Body_13); + m_title_colour->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800); + m_title_colour->Wrap(-1); + m_sizer_colour->Add(m_title_colour, 0, wxALIGN_CENTER, 0); + + m_sizer_colour->Add(0, 0, 0, wxEXPAND, 0); + + m_clrData = new wxColourData(); + m_clrData->SetChooseFull(true); + m_clrData->SetChooseAlpha(false); + + m_clr_picker = new Button(parent, wxEmptyString, wxEmptyString, wxBU_AUTODRAW); + m_clr_picker->SetCanFocus(false); + m_clr_picker->SetSize(FromDIP(50), FromDIP(25)); + m_clr_picker->SetMinSize(wxSize(FromDIP(50), FromDIP(25))); + m_clr_picker->SetCornerRadius(FromDIP(6)); + m_clr_picker->SetBorderColor(wxColour(172, 172, 172)); + m_clr_picker->Bind(wxEVT_BUTTON, &AMSMaterialsSetting::on_clr_picker, this); + m_sizer_colour->Add(m_clr_picker, 0, 0, 0); + + wxBoxSizer* m_sizer_temperature = new wxBoxSizer(wxHORIZONTAL); + m_title_temperature = new wxStaticText(parent, wxID_ANY, _L("Nozzle\nTemperature"), wxDefaultPosition, wxSize(AMS_MATERIALS_SETTING_LABEL_WIDTH, -1), 0); + m_title_temperature->SetFont(::Label::Body_13); + m_title_temperature->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800); + m_title_temperature->Wrap(-1); + m_sizer_temperature->Add(m_title_temperature, 0, wxALIGN_CENTER, 0); + + m_sizer_temperature->Add(0, 0, 0, wxEXPAND, 0); + + wxBoxSizer* sizer_other = new wxBoxSizer(wxVERTICAL); + wxBoxSizer* sizer_tempinput = new wxBoxSizer(wxHORIZONTAL); + + m_input_nozzle_max = new ::TextInput(parent, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, AMS_MATERIALS_SETTING_INPUT_SIZE, wxTE_CENTRE | wxTE_PROCESS_ENTER); + m_input_nozzle_min = new ::TextInput(parent, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, AMS_MATERIALS_SETTING_INPUT_SIZE, wxTE_CENTRE | wxTE_PROCESS_ENTER); + m_input_nozzle_max->Enable(false); + m_input_nozzle_min->Enable(false); + + m_input_nozzle_max->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); + m_input_nozzle_max->GetTextCtrl()->SetSize(wxSize(-1, FromDIP(20))); + m_input_nozzle_min->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); + m_input_nozzle_min->GetTextCtrl()->SetSize(wxSize(-1, FromDIP(20))); + + auto bitmap_max_degree = new wxStaticBitmap(parent, -1, create_scaled_bitmap("degree", nullptr, 16), wxDefaultPosition, wxDefaultSize); + auto bitmap_min_degree = new wxStaticBitmap(parent, -1, create_scaled_bitmap("degree", nullptr, 16), wxDefaultPosition, wxDefaultSize); + + sizer_tempinput->Add(m_input_nozzle_max, 1, wxALIGN_CENTER, 0); + sizer_tempinput->Add(bitmap_min_degree, 0, wxALIGN_CENTER, 0); + sizer_tempinput->Add(FromDIP(10), 0, 0, 0); + sizer_tempinput->Add(m_input_nozzle_min, 1, wxALIGN_CENTER, 0); + sizer_tempinput->Add(bitmap_max_degree, 0, wxALIGN_CENTER, 0); + + wxBoxSizer* sizer_temp_txt = new wxBoxSizer(wxHORIZONTAL); + auto m_title_max = new wxStaticText(parent, wxID_ANY, _L("max"), wxDefaultPosition, AMS_MATERIALS_SETTING_INPUT_SIZE); + m_title_max->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800); + m_title_max->SetFont(::Label::Body_13); + auto m_title_min = new wxStaticText(parent, wxID_ANY, _L("min"), wxDefaultPosition, AMS_MATERIALS_SETTING_INPUT_SIZE); + m_title_min->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800); + m_title_min->SetFont(::Label::Body_13); + sizer_temp_txt->Add(m_title_max, 1, wxALIGN_CENTER, 0); + sizer_temp_txt->Add(FromDIP(10), 0, 0, 0); + sizer_temp_txt->Add(m_title_min, 1, wxALIGN_CENTER | wxRIGHT, FromDIP(16)); + + + sizer_other->Add(sizer_temp_txt, 0, wxALIGN_CENTER, 0); + sizer_other->Add(sizer_tempinput, 0, wxALIGN_CENTER, 0); + + m_sizer_temperature->Add(sizer_other, 0, wxALL | wxALIGN_CENTER, 0); + m_sizer_temperature->AddStretchSpacer(); + + wxString warning_string = wxString::FromUTF8( + (boost::format(_u8L("The input value should be greater than %1% and less than %2%")) % FILAMENT_MIN_TEMP % FILAMENT_MAX_TEMP).str()); + warning_text = new wxStaticText(parent, wxID_ANY, warning_string, wxDefaultPosition, wxDefaultSize, 0); + warning_text->SetFont(::Label::Body_13); + warning_text->SetForegroundColour(wxColour(255, 111, 0)); + + warning_text->Wrap(AMS_MATERIALS_SETTING_BODY_WIDTH); + warning_text->SetMinSize(wxSize(AMS_MATERIALS_SETTING_BODY_WIDTH, -1)); + warning_text->Hide(); + + m_panel_SN = new wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + wxBoxSizer* m_sizer_SN = new wxBoxSizer(wxVERTICAL); + m_sizer_SN->AddSpacer(FromDIP(16)); + + wxBoxSizer* m_sizer_SN_inside = new wxBoxSizer(wxHORIZONTAL); + + auto m_title_SN = new wxStaticText(m_panel_SN, wxID_ANY, _L("SN"), wxDefaultPosition, wxSize(AMS_MATERIALS_SETTING_LABEL_WIDTH, -1), 0); + m_title_SN->SetFont(::Label::Body_13); + m_title_SN->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800); + m_title_SN->Wrap(-1); + m_sizer_SN_inside->Add(m_title_SN, 0, wxALIGN_CENTER, 0); + + m_sizer_SN_inside->Add(0, 0, 0, wxEXPAND, 0); + + m_sn_number = new wxStaticText(m_panel_SN, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize); + m_sn_number->SetForegroundColour(*wxBLACK); + m_sizer_SN_inside->Add(m_sn_number, 0, wxALIGN_CENTER, 0); + m_sizer_SN->Add(m_sizer_SN_inside); + + m_panel_SN->SetSizer(m_sizer_SN); + m_panel_SN->Layout(); + m_panel_SN->Fit(); + + wxBoxSizer* m_tip_sizer = new wxBoxSizer(wxHORIZONTAL); + m_tip_readonly = new wxStaticText(parent, wxID_ANY, _L("Setting AMS slot information while printing is not supported"), wxDefaultPosition, wxSize(-1, AMS_MATERIALS_SETTING_INPUT_SIZE.y)); + m_tip_readonly->SetForegroundColour(*wxBLACK); + m_tip_readonly->Hide(); + m_tip_sizer->Add(m_tip_readonly, 0, wxALIGN_CENTER | wxRIGHT, FromDIP(20)); + + sizer->Add(0, 0, 0, wxTOP, FromDIP(16)); + sizer->Add(m_sizer_filament, 0, wxLEFT | wxRIGHT, FromDIP(20)); + sizer->Add(0, 0, 0, wxTOP, FromDIP(16)); + sizer->Add(m_sizer_colour, 0, wxLEFT | wxRIGHT, FromDIP(20)); + sizer->Add(0, 0, 0, wxTOP, FromDIP(16)); + sizer->Add(m_sizer_temperature, 0, wxLEFT | wxRIGHT, FromDIP(20)); + sizer->Add(0, 0, 0, wxTOP, FromDIP(5)); + sizer->Add(warning_text, 0, wxLEFT | wxRIGHT, FromDIP(20)); + sizer->Add(m_panel_SN, 0, wxLEFT, FromDIP(20)); + sizer->Add(0, 0, 0, wxTOP, FromDIP(24)); + sizer->Add(m_tip_sizer, 0, wxLEFT, FromDIP(20)); + parent->SetSizer(sizer); +} + +void AMSMaterialsSetting::create_panel_kn(wxWindow* parent) +{ + auto sizer = new wxBoxSizer(wxVERTICAL); + // title + auto ratio_text = new wxStaticText(parent, wxID_ANY, _L("Factors of dynamic flow cali")); + ratio_text->SetFont(Label::Head_14); + + auto kn_val_sizer = new wxFlexGridSizer(0, 2, 0, 0); + kn_val_sizer->SetFlexibleDirection(wxBOTH); + kn_val_sizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); + kn_val_sizer->AddGrowableCol(1); + + // k params input + m_k_param = new wxStaticText(parent, wxID_ANY, _L("Factor K"), wxDefaultPosition, wxDefaultSize, 0); + m_k_param->SetFont(::Label::Body_13); + m_k_param->SetForegroundColour(wxColour(50, 58, 61)); + m_k_param->Wrap(-1); + kn_val_sizer->Add(m_k_param, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5)); + + m_input_k_val = new TextInput(parent, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_CENTRE | wxTE_PROCESS_ENTER); + m_input_k_val->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); + kn_val_sizer->Add(m_input_k_val, 0, wxALL | wxEXPAND | wxALIGN_CENTER_VERTICAL, FromDIP(5)); + + // n params input + wxBoxSizer* n_sizer = new wxBoxSizer(wxHORIZONTAL); + m_n_param = new wxStaticText(parent, wxID_ANY, _L("Factor N"), wxDefaultPosition, wxDefaultSize, 0); + m_n_param->SetFont(::Label::Body_13); + m_n_param->SetForegroundColour(wxColour(50, 58, 61)); + m_n_param->Wrap(-1); + kn_val_sizer->Add(m_n_param, 1, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5)); + m_input_n_val = new TextInput(parent, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_CENTRE | wxTE_PROCESS_ENTER); + m_input_n_val->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); + kn_val_sizer->Add(m_input_n_val, 0, wxALL | wxEXPAND | wxALIGN_CENTER_VERTICAL, FromDIP(5)); + + // hide n + m_n_param->Hide(); + m_input_n_val->Hide(); + + sizer->Add(0, 0, 0, wxTOP, FromDIP(10)); + sizer->Add(ratio_text, 0, wxLEFT | wxRIGHT | wxEXPAND, FromDIP(20)); + sizer->Add(0, 0, 0, wxTOP, FromDIP(10)); + sizer->Add(kn_val_sizer, 0, wxLEFT | wxRIGHT | wxEXPAND, FromDIP(20)); + sizer->Add(0, 0, 0, wxTOP, FromDIP(10)); + parent->SetSizer(sizer); } void AMSMaterialsSetting::paintEvent(wxPaintEvent &evt) @@ -252,7 +312,7 @@ void AMSMaterialsSetting::paintEvent(wxPaintEvent &evt) AMSMaterialsSetting::~AMSMaterialsSetting() { - COMBOBOX_FILAMENT->Disconnect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(AMSMaterialsSetting::on_select_filament), NULL, this); + m_comboBox_filament->Disconnect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(AMSMaterialsSetting::on_select_filament), NULL, this); } void AMSMaterialsSetting::input_min_finish() @@ -289,6 +349,7 @@ void AMSMaterialsSetting::input_max_finish() void AMSMaterialsSetting::update() { if (obj) { + update_widgets(); if (obj->is_in_printing() || obj->can_resume()) { enable_confirm_button(false); } else { @@ -304,7 +365,7 @@ void AMSMaterialsSetting::enable_confirm_button(bool en) } else { m_button_confirm->Show(en); - COMBOBOX_FILAMENT->Show(en); + m_comboBox_filament->Show(en); m_readonly_filament->Show(!en); m_tip_readonly->Show(!en); } @@ -312,37 +373,135 @@ void AMSMaterialsSetting::enable_confirm_button(bool en) void AMSMaterialsSetting::on_select_ok(wxCommandEvent &event) { - if (!m_is_third) { + wxString k_text = m_input_k_val->GetTextCtrl()->GetValue(); + wxString n_text = m_input_n_val->GetTextCtrl()->GetValue(); + + if (is_virtual_tray()) { + if (!ExtrusionCalibration::check_k_n_validation(k_text, n_text)) { + wxString kn_tips = _L("Plase input valid value, k is in range 0 ~ 0.5, n is in range 0.6 ~ 2.0"); + MessageDialog msg_dlg(nullptr, kn_tips, wxEmptyString, wxICON_WARNING | wxOK); + msg_dlg.ShowModal(); + return; + } + double k = 0.0; + try { + k_text.ToDouble(&k); + } + catch (...) { + ; + } + double n = 0.0; + try { + n_text.ToDouble(&n); + } + catch (...) { + ; + } + obj->command_extrusion_cali_set(VIRTUAL_TRAY_ID, "", "", k, n); Close(); - return; - } - wxString nozzle_temp_min = m_input_nozzle_min->GetTextCtrl()->GetValue(); - auto filament = COMBOBOX_FILAMENT->GetValue(); + } else { + if (!m_is_third) { + // check and set k n + if (obj->is_function_supported(PrinterFunction::FUNC_EXTRUSION_CALI)) { + if (!ExtrusionCalibration::check_k_n_validation(k_text, n_text)) { + wxString kn_tips = _L("Plase input valid value, K is in range 0 ~ 0.5, N is in range 0.6 ~ 2.0"); + MessageDialog msg_dlg(nullptr, kn_tips, wxEmptyString, wxICON_WARNING | wxOK); + msg_dlg.ShowModal(); + return; + } + } - wxString nozzle_temp_max = m_input_nozzle_max->GetTextCtrl()->GetValue(); - long nozzle_temp_min_int, nozzle_temp_max_int; - nozzle_temp_min.ToLong(&nozzle_temp_min_int); - nozzle_temp_max.ToLong(&nozzle_temp_max_int); - wxColour color = m_clrData->GetColour(); - char col_buf[10]; - sprintf(col_buf, "%02X%02X%02XFF", (int) color.Red(), (int) color.Green(), (int) color.Blue()); - ams_filament_id = ""; + // set k / n value + if (obj->is_function_supported(PrinterFunction::FUNC_EXTRUSION_CALI)) { + // set extrusion cali ratio + int cali_tray_id = ams_id * 4 + tray_id; - PresetBundle *preset_bundle = wxGetApp().preset_bundle; - if (preset_bundle) { - for (auto it = preset_bundle->filaments.begin(); it != preset_bundle->filaments.end(); it++) { - if (it->alias.compare(COMBOBOX_FILAMENT->GetValue().ToStdString()) == 0) { - ams_filament_id = it->filament_id; + double k = 0.0; + try { + k_text.ToDouble(&k); + } + catch (...) { + ; + } + + double n = 0.0; + try { + n_text.ToDouble(&n); + } + catch (...) { + ; + } + obj->command_extrusion_cali_set(cali_tray_id, "", "", k, n); + } + Close(); + return; + } + wxString nozzle_temp_min = m_input_nozzle_min->GetTextCtrl()->GetValue(); + auto filament = m_comboBox_filament->GetValue(); + + wxString nozzle_temp_max = m_input_nozzle_max->GetTextCtrl()->GetValue(); + + long nozzle_temp_min_int, nozzle_temp_max_int; + nozzle_temp_min.ToLong(&nozzle_temp_min_int); + nozzle_temp_max.ToLong(&nozzle_temp_max_int); + wxColour color = m_clrData->GetColour(); + char col_buf[10]; + sprintf(col_buf, "%02X%02X%02XFF", (int) color.Red(), (int) color.Green(), (int) color.Blue()); + ams_filament_id = ""; + ams_setting_id = ""; + + PresetBundle *preset_bundle = wxGetApp().preset_bundle; + if (preset_bundle) { + for (auto it = preset_bundle->filaments.begin(); it != preset_bundle->filaments.end(); it++) { + if (it->alias.compare(m_comboBox_filament->GetValue().ToStdString()) == 0) { + ams_filament_id = it->filament_id; + ams_setting_id = it->setting_id; + } } } - } - if (ams_filament_id.empty() || nozzle_temp_min.empty() || nozzle_temp_max.empty() || m_filament_type.empty()) { - BOOST_LOG_TRIVIAL(trace) << "Invalid Setting id"; - } else { - if (obj) { - obj->command_ams_filament_settings(ams_id, tray_id, ams_filament_id, std::string(col_buf), m_filament_type, nozzle_temp_min_int, nozzle_temp_max_int); + if (ams_filament_id.empty() || nozzle_temp_min.empty() || nozzle_temp_max.empty() || m_filament_type.empty()) { + BOOST_LOG_TRIVIAL(trace) << "Invalid Setting id"; + } else { + if (obj) { + if (obj->is_function_supported(PrinterFunction::FUNC_EXTRUSION_CALI)) { + if (!ExtrusionCalibration::check_k_n_validation(k_text, n_text)) { + wxString kn_tips = _L("Plase input valid value, k is in range 0 ~ 0.5, n is in range 0.6 ~ 2.0"); + MessageDialog msg_dlg(nullptr, kn_tips, wxEmptyString, wxICON_WARNING | wxOK); + msg_dlg.ShowModal(); + return; + } + } + + // set filament + if (!is_virtual_tray()) { + obj->command_ams_filament_settings(ams_id, tray_id, ams_filament_id, ams_setting_id, std::string(col_buf), m_filament_type, nozzle_temp_min_int, nozzle_temp_max_int); + } + + // set k / n value + if (obj->is_function_supported(PrinterFunction::FUNC_EXTRUSION_CALI)) { + // set extrusion cali ratio + int cali_tray_id = ams_id * 4 + tray_id; + + double k = 0.0; + try { + k_text.ToDouble(&k); + } + catch (...) { + ; + } + + double n = 0.0; + try { + n_text.ToDouble(&n); + } + catch (...) { + ; + } + obj->command_extrusion_cali_set(cali_tray_id, "", "", k, n); + } + } } } Close(); @@ -375,6 +534,29 @@ void AMSMaterialsSetting::on_clr_picker(wxCommandEvent & event) } } +bool AMSMaterialsSetting::is_virtual_tray() +{ + if (tray_id == VIRTUAL_TRAY_ID) + return true; + return false; +} + +void AMSMaterialsSetting::update_widgets() +{ + // virtual tray + if (is_virtual_tray()) { + m_panel_normal->Hide(); + m_panel_kn->Show(); + } else if (obj && obj->is_function_supported(PrinterFunction::FUNC_EXTRUSION_CALI)) { + m_panel_normal->Show(); + m_panel_kn->Show(); + } else { + m_panel_normal->Show(); + m_panel_kn->Hide(); + } + Layout(); +} + bool AMSMaterialsSetting::Show(bool show) { if (show) { @@ -386,102 +568,126 @@ bool AMSMaterialsSetting::Show(bool show) return DPIDialog::Show(show); } -void AMSMaterialsSetting::Popup(wxString filament, wxString sn, wxString temp_min, wxString temp_max) +void AMSMaterialsSetting::Popup(wxString filament, wxString sn, wxString temp_min, wxString temp_max, wxString k, wxString n) { - m_clr_picker->SetBackgroundColor(wxColour( - m_clrData->GetColour().Red(), - m_clrData->GetColour().Green(), - m_clrData->GetColour().Blue(), - 254 - )); + update_widgets(); + // set default value + if (k.IsEmpty()) + k = "0.00"; + if (n.IsEmpty()) + n = "0.00"; - if (!m_is_third) { - m_button_confirm->Hide(); - m_sn_number->SetLabel(sn); - m_panel_SN->Show(); - COMBOBOX_FILAMENT->Hide(); - m_readonly_filament->Show(); - m_readonly_filament->GetTextCtrl()->SetLabel("Bambu " + filament); - m_input_nozzle_min->GetTextCtrl()->SetValue(temp_min); - m_input_nozzle_max->GetTextCtrl()->SetValue(temp_max); + m_input_k_val->GetTextCtrl()->SetValue(k); + m_input_n_val->GetTextCtrl()->SetValue(n); + if (is_virtual_tray()) { + m_button_confirm->Show(); update(); Layout(); Fit(); ShowModal(); return; - } + } else { + m_clr_picker->SetBackgroundColor(wxColour( + m_clrData->GetColour().Red(), + m_clrData->GetColour().Green(), + m_clrData->GetColour().Blue(), + 254 + )); - m_button_confirm->Show(); - m_panel_SN->Hide(); - COMBOBOX_FILAMENT->Show(); - m_readonly_filament->Hide(); + if (!m_is_third) { + if (obj && obj->is_function_supported(PrinterFunction::FUNC_EXTRUSION_CALI)) { + m_button_confirm->Show(); + } else { + m_button_confirm->Hide(); + } + + m_sn_number->SetLabel(sn); + m_panel_SN->Show(); + m_comboBox_filament->Hide(); + m_readonly_filament->Show(); + m_readonly_filament->GetTextCtrl()->SetLabel("Bambu " + filament); + m_input_nozzle_min->GetTextCtrl()->SetValue(temp_min); + m_input_nozzle_max->GetTextCtrl()->SetValue(temp_max); + + update(); + Layout(); + Fit(); + ShowModal(); + return; + } + + m_button_confirm->Show(); + m_panel_SN->Hide(); + m_comboBox_filament->Show(); + m_readonly_filament->Hide(); - int selection_idx = -1, idx = 0; - wxArrayString filament_items; - std::set filament_id_set; + int selection_idx = -1, idx = 0; + wxArrayString filament_items; + std::set filament_id_set; - PresetBundle* preset_bundle = wxGetApp().preset_bundle; - if (preset_bundle) { - BOOST_LOG_TRIVIAL(trace) << "system_preset_bundle filament number=" << preset_bundle->filaments.size(); - for (auto filament_it = preset_bundle->filaments.begin(); filament_it != preset_bundle->filaments.end(); filament_it++) { - // filter by system preset - if (!filament_it->is_system) continue; - - for (auto printer_it = preset_bundle->printers.begin(); printer_it != preset_bundle->printers.end(); printer_it++) { + PresetBundle* preset_bundle = wxGetApp().preset_bundle; + if (preset_bundle) { + BOOST_LOG_TRIVIAL(trace) << "system_preset_bundle filament number=" << preset_bundle->filaments.size(); + for (auto filament_it = preset_bundle->filaments.begin(); filament_it != preset_bundle->filaments.end(); filament_it++) { // filter by system preset - if (!printer_it->is_system) continue; - // get printer_model - ConfigOption* printer_model_opt = printer_it->config.option("printer_model"); - ConfigOptionString* printer_model_str = dynamic_cast(printer_model_opt); - if (!printer_model_str || !obj) - continue; + if (!filament_it->is_system) continue; - // use printer_model as printer type - if (printer_model_str->value != MachineObject::get_preset_printer_model_name(obj->printer_type)) - continue; - ConfigOption* printer_opt = filament_it->config.option("compatible_printers"); - ConfigOptionStrings* printer_strs = dynamic_cast(printer_opt); - for (auto printer_str : printer_strs->values) { - if (printer_it->name == printer_str) { - if (filament_id_set.find(filament_it->filament_id) != filament_id_set.end()) { - continue; - } - else { - filament_id_set.insert(filament_it->filament_id); - // name matched - filament_items.push_back(filament_it->alias); - if (filament_it->filament_id == ams_filament_id) { - selection_idx = idx; + for (auto printer_it = preset_bundle->printers.begin(); printer_it != preset_bundle->printers.end(); printer_it++) { + // filter by system preset + if (!printer_it->is_system) continue; + // get printer_model + ConfigOption* printer_model_opt = printer_it->config.option("printer_model"); + ConfigOptionString* printer_model_str = dynamic_cast(printer_model_opt); + if (!printer_model_str || !obj) + continue; - // update if nozzle_temperature_range is found - ConfigOption* opt_min = filament_it->config.option("nozzle_temperature_range_low"); - if (opt_min) { - ConfigOptionInts* opt_min_ints = dynamic_cast(opt_min); - if (opt_min_ints) { - wxString text_nozzle_temp_min = wxString::Format("%d", opt_min_ints->get_at(0)); - m_input_nozzle_min->GetTextCtrl()->SetValue(text_nozzle_temp_min); - } - } - ConfigOption* opt_max = filament_it->config.option("nozzle_temperature_range_high"); - if (opt_max) { - ConfigOptionInts* opt_max_ints = dynamic_cast(opt_max); - if (opt_max_ints) { - wxString text_nozzle_temp_max = wxString::Format("%d", opt_max_ints->get_at(0)); - m_input_nozzle_max->GetTextCtrl()->SetValue(text_nozzle_temp_max); - } - } + // use printer_model as printer type + if (printer_model_str->value != MachineObject::get_preset_printer_model_name(obj->printer_type)) + continue; + ConfigOption* printer_opt = filament_it->config.option("compatible_printers"); + ConfigOptionStrings* printer_strs = dynamic_cast(printer_opt); + for (auto printer_str : printer_strs->values) { + if (printer_it->name == printer_str) { + if (filament_id_set.find(filament_it->filament_id) != filament_id_set.end()) { + continue; + } + else { + filament_id_set.insert(filament_it->filament_id); + // name matched + filament_items.push_back(filament_it->alias); + if (filament_it->filament_id == ams_filament_id) { + selection_idx = idx; + + // update if nozzle_temperature_range is found + ConfigOption* opt_min = filament_it->config.option("nozzle_temperature_range_low"); + if (opt_min) { + ConfigOptionInts* opt_min_ints = dynamic_cast(opt_min); + if (opt_min_ints) { + wxString text_nozzle_temp_min = wxString::Format("%d", opt_min_ints->get_at(0)); + m_input_nozzle_min->GetTextCtrl()->SetValue(text_nozzle_temp_min); + } + } + ConfigOption* opt_max = filament_it->config.option("nozzle_temperature_range_high"); + if (opt_max) { + ConfigOptionInts* opt_max_ints = dynamic_cast(opt_max); + if (opt_max_ints) { + wxString text_nozzle_temp_max = wxString::Format("%d", opt_max_ints->get_at(0)); + m_input_nozzle_max->GetTextCtrl()->SetValue(text_nozzle_temp_max); + } + } + } + idx++; } - idx++; } } } } + m_comboBox_filament->Set(filament_items); + m_comboBox_filament->SetSelection(selection_idx); + post_select_event(); } - COMBOBOX_FILAMENT->Set(filament_items); - COMBOBOX_FILAMENT->SetSelection(selection_idx); - post_select_event(); } update(); @@ -492,8 +698,8 @@ void AMSMaterialsSetting::Popup(wxString filament, wxString sn, wxString temp_mi void AMSMaterialsSetting::post_select_event() { wxCommandEvent event(wxEVT_COMBOBOX); - event.SetEventObject(COMBOBOX_FILAMENT); - wxPostEvent(COMBOBOX_FILAMENT, event); + event.SetEventObject(m_comboBox_filament); + wxPostEvent(m_comboBox_filament, event); } void AMSMaterialsSetting::on_select_filament(wxCommandEvent &evt) @@ -502,8 +708,7 @@ void AMSMaterialsSetting::on_select_filament(wxCommandEvent &evt) PresetBundle* preset_bundle = wxGetApp().preset_bundle; if (preset_bundle) { for (auto it = preset_bundle->filaments.begin(); it != preset_bundle->filaments.end(); it++) { - auto a = it->alias; - if (it->alias.compare(COMBOBOX_FILAMENT->GetValue().ToStdString()) == 0) { + if (it->alias.compare(m_comboBox_filament->GetValue().ToStdString()) == 0) { // ) if nozzle_temperature_range is found ConfigOption* opt_min = it->config.option("nozzle_temperature_range_low"); if (opt_min) { diff --git a/src/slic3r/GUI/AMSMaterialsSetting.hpp b/src/slic3r/GUI/AMSMaterialsSetting.hpp index 4a4b635be..46c0ea145 100644 --- a/src/slic3r/GUI/AMSMaterialsSetting.hpp +++ b/src/slic3r/GUI/AMSMaterialsSetting.hpp @@ -41,9 +41,11 @@ public: void update(); void enable_confirm_button(bool en); bool Show(bool show) override; - void Popup(wxString filament = wxEmptyString, wxString sn = wxEmptyString, wxString temp_min = wxEmptyString, wxString temp_max = wxEmptyString); + void Popup(wxString filament = wxEmptyString, wxString sn = wxEmptyString, + wxString temp_min = wxEmptyString, wxString temp_max = wxEmptyString, + wxString k = wxEmptyString, wxString n = wxEmptyString); - void post_select_event(); + void post_select_event(); void set_color(wxColour color); @@ -52,6 +54,7 @@ public: int tray_id { 0 }; /* 0 ~ 3 */ std::string ams_filament_id; + std::string ams_setting_id; bool m_is_third; wxString m_brand_filament; @@ -61,15 +64,20 @@ public: std::string m_filament_type; protected: + void create_panel_normal(wxWindow* parent); + void create_panel_kn(wxWindow* parent); void on_dpi_changed(const wxRect &suggested_rect) override; void on_select_filament(wxCommandEvent& evt); void on_select_ok(wxCommandEvent &event); void on_select_close(wxCommandEvent &event); void on_clr_picker(wxCommandEvent &event); + bool is_virtual_tray(); + void update_widgets(); protected: StateColor m_btn_bg_green; StateColor m_btn_bg_gray; + wxPanel * m_panel_normal; wxPanel * m_panel_SN; wxStaticText * m_sn_number; wxStaticText * warning_text; @@ -77,7 +85,6 @@ protected: wxStaticText * m_title_filament; wxStaticText * m_title_colour; wxStaticText * m_title_temperature; - wxStaticText * m_label_other; TextInput * m_input_nozzle_min; TextInput* m_input_nozzle_max; Button * m_button_confirm; @@ -85,8 +92,15 @@ protected: Button * m_button_close; Button * m_clr_picker; wxColourData * m_clrData; + + wxPanel * m_panel_kn; + wxStaticText* m_k_param; + TextInput* m_input_k_val; + wxStaticText* m_n_param; + TextInput* m_input_n_val; + #ifdef __APPLE__ - wxComboBox *m_comboBox_filament_mac; + wxComboBox *m_comboBox_filament; #else ComboBox *m_comboBox_filament; #endif diff --git a/src/slic3r/GUI/AmsMappingPopup.cpp b/src/slic3r/GUI/AmsMappingPopup.cpp index bba961b07..4ad6a6f22 100644 --- a/src/slic3r/GUI/AmsMappingPopup.cpp +++ b/src/slic3r/GUI/AmsMappingPopup.cpp @@ -920,4 +920,89 @@ bool AmsTutorialPopup::ProcessLeftDown(wxMouseEvent& event) { } +AmsIntroducePopup::AmsIntroducePopup(wxWindow* parent) +:wxPopupTransientWindow(parent, wxBORDER_NONE) +{ + Bind(wxEVT_PAINT, &AmsIntroducePopup::paintEvent, this); + SetBackgroundColour(*wxWHITE); + + SetMinSize(wxSize(FromDIP(200), FromDIP(200))); + SetMaxSize(wxSize(FromDIP(200), FromDIP(200))); + + wxBoxSizer* bSizer4 = new wxBoxSizer(wxVERTICAL); + + m_staticText_top = new Label(this, _L("Do not Enable AMS")); + m_staticText_top->SetFont(::Label::Head_13); + m_staticText_top->SetForegroundColour(wxColour(0x323A3D)); + m_staticText_top->Wrap(-1); + bSizer4->Add(m_staticText_top, 0, wxALL, 5); + + m_staticText_bottom = new Label(this, _L("Print using materials mounted on the back of the case")); + m_staticText_bottom->Wrap(-1); + m_staticText_bottom->SetFont(::Label::Body_13); + m_staticText_bottom->SetForegroundColour(wxColour(0x6B6B6B)); + bSizer4->Add(m_staticText_bottom, 0, wxALL, 5); + + wxBoxSizer* bSizer5; + bSizer5 = new wxBoxSizer(wxHORIZONTAL); + + m_img_enable_ams = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap("monitor_upgrade_ams", this, FromDIP(140)), wxDefaultPosition, wxDefaultSize, 0); + m_img_disable_ams = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap("disable_ams_demo_icon", this, FromDIP(110)), wxDefaultPosition, wxDefaultSize, 0); + + m_img_enable_ams->SetMinSize(wxSize(FromDIP(96), FromDIP(110))); + m_img_disable_ams->SetMinSize(wxSize(FromDIP(96), FromDIP(110))); + + bSizer5->Add(m_img_enable_ams, 0, wxALIGN_CENTER, 0); + bSizer5->Add(m_img_disable_ams, 0, wxALIGN_CENTER, 0); + + m_img_disable_ams->Hide(); + m_img_disable_ams->Hide(); + + + bSizer4->Add(bSizer5, 0, wxALIGN_CENTER | wxBOTTOM, FromDIP(1)); + + + SetSizer(bSizer4); + Layout(); + Fit(); + + wxGetApp().UpdateDarkUIWin(this); +} + +void AmsIntroducePopup::set_mode(bool enable_ams) +{ + if (enable_ams) { + m_staticText_top->SetLabelText(_L("Enable AMS")); + m_staticText_bottom->SetLabelText(_L("Print with filaments in ams")); + m_img_enable_ams->Show(); + m_img_disable_ams->Hide(); + } + else { + m_staticText_top->SetLabelText(_L("Do not Enable AMS")); + m_staticText_bottom->SetLabelText(_L("Print with filaments mounted on the back of the chassis")); + m_staticText_bottom->SetMinSize(wxSize(FromDIP(180), -1)); + m_staticText_bottom->Wrap(FromDIP(180)); + m_img_enable_ams->Hide(); + m_img_disable_ams->Show(); + } + Layout(); + Fit(); +} + +void AmsIntroducePopup::paintEvent(wxPaintEvent& evt) +{ + wxPaintDC dc(this); + dc.SetPen(wxColour(0xAC, 0xAC, 0xAC)); + dc.SetBrush(*wxTRANSPARENT_BRUSH); + dc.DrawRoundedRectangle(0, 0, GetSize().x, GetSize().y, 0); +} + + +void AmsIntroducePopup::OnDismiss() {} + +bool AmsIntroducePopup::ProcessLeftDown(wxMouseEvent& event) { + return wxPopupTransientWindow::ProcessLeftDown(event); +} + + }} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/AmsMappingPopup.hpp b/src/slic3r/GUI/AmsMappingPopup.hpp index 3cbdc9e1d..c4abe83cc 100644 --- a/src/slic3r/GUI/AmsMappingPopup.hpp +++ b/src/slic3r/GUI/AmsMappingPopup.hpp @@ -203,6 +203,25 @@ public: }; +class AmsIntroducePopup : public wxPopupTransientWindow +{ +public: + bool is_enable_ams = {false}; + Label* m_staticText_top; + Label* m_staticText_bottom; + wxStaticBitmap* m_img_enable_ams; + wxStaticBitmap* m_img_disable_ams; + + AmsIntroducePopup(wxWindow* parent); + ~AmsIntroducePopup() {}; + + void set_mode(bool enable_ams); + void paintEvent(wxPaintEvent& evt); + virtual void OnDismiss() wxOVERRIDE; + virtual bool ProcessLeftDown(wxMouseEvent& event) wxOVERRIDE; +}; + + wxDECLARE_EVENT(EVT_SET_FINISH_MAPPING, wxCommandEvent); }} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/DeviceManager.cpp b/src/slic3r/GUI/DeviceManager.cpp index 2cbe0c3e5..40a7993a0 100644 --- a/src/slic3r/GUI/DeviceManager.cpp +++ b/src/slic3r/GUI/DeviceManager.cpp @@ -325,7 +325,8 @@ MachineObject::MachineObject(NetworkAgent* agent, std::string name, std::string dev_ip(ip), subtask_(nullptr), slice_info(nullptr), - m_is_online(false) + m_is_online(false), + vt_tray(std::to_string(VIRTUAL_TRAY_ID)) { m_agent = agent; @@ -426,6 +427,27 @@ void MachineObject::_parse_print_option_ack(int option) xcam_auto_recovery_step_loss = ((option >> (int)PRINT_OP_AUTO_RECOVERY) & 0x01) != 0; } +bool MachineObject::is_in_extrusion_cali() +{ + if (is_in_printing_status(print_status) + && print_type == "system" + && boost::contains(m_gcode_file, "extrusion_cali") + ) + { + return true; + } + return false; +} + +bool MachineObject::is_extrusion_cali_finished() +{ + if (boost::contains(m_gcode_file, "extrusion_cali") + && this->mc_print_percent == 100) + return true; + else + return false; +} + void MachineObject::_parse_tray_now(std::string tray_now) { m_tray_now = tray_now; @@ -1551,21 +1573,22 @@ int MachineObject::command_ams_calibrate(int ams_id) return this->publish_gcode(gcode_cmd); } -int MachineObject::command_ams_filament_settings(int ams_id, int tray_id, std::string setting_id, std::string tray_color, std::string tray_type, int nozzle_temp_min, int nozzle_temp_max) +int MachineObject::command_ams_filament_settings(int ams_id, int tray_id, std::string filament_id, std::string setting_id, std::string tray_color, std::string tray_type, int nozzle_temp_min, int nozzle_temp_max) { BOOST_LOG_TRIVIAL(info) << "command_ams_filament_settings, ams_id = " << ams_id << ", tray_id = " << tray_id << ", tray_color = " << tray_color - << ", tray_type = " << tray_type; + << ", tray_type = " << tray_type << ", setting_id = " << setting_id; json j; - j["print"]["command"] = "ams_filament_setting"; - j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++); - j["print"]["ams_id"] = ams_id; - j["print"]["tray_id"] = tray_id; - j["print"]["tray_info_idx"] = setting_id; + j["print"]["command"] = "ams_filament_setting"; + j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++); + j["print"]["ams_id"] = ams_id; + j["print"]["tray_id"] = tray_id; + j["print"]["tray_info_idx"] = filament_id; + j["print"]["setting_id"] = setting_id; // format "FFFFFFFF" RGBA - j["print"]["tray_color"] = tray_color; + j["print"]["tray_color"] = tray_color; j["print"]["nozzle_temp_min"] = nozzle_temp_min; - j["print"]["nozzle_temp_max"] = nozzle_temp_max; - j["print"]["tray_type"] = tray_type; + j["print"]["nozzle_temp_max"] = nozzle_temp_max; + j["print"]["tray_type"] = tray_type; return this->publish_json(j.dump()); } @@ -1628,6 +1651,54 @@ int MachineObject::command_set_work_light(LIGHT_EFFECT effect, int on_time, int return this->publish_json(j.dump()); } +int MachineObject::command_start_extrusion_cali(int tray_index, int nozzle_temp, int bed_temp, float max_volumetric_speed, std::string setting_id) +{ + BOOST_LOG_TRIVIAL(info) << "extrusion_cali: tray_id = " << tray_index << ", nozzle_temp = " << nozzle_temp << ", bed_temp = " << bed_temp + << ", max_volumetric_speed = " << max_volumetric_speed; + + json j; + j["print"]["command"] = "extrusion_cali"; + j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++); + j["print"]["tray_id"] = tray_index; + //j["print"]["setting_id"] = setting_id; + //j["print"]["name"] = ""; + j["print"]["nozzle_temp"] = nozzle_temp; + j["print"]["bed_temp"] = bed_temp; + j["print"]["max_volumetric_speed"] = max_volumetric_speed; + return this->publish_json(j.dump()); +} + +int MachineObject::command_stop_extrusion_cali() +{ + BOOST_LOG_TRIVIAL(info) << "extrusion_cali: stop"; + if (is_in_extrusion_cali()) { + return command_task_abort(); + } + return 0; +} + +int MachineObject::command_extrusion_cali_set(int tray_index, std::string setting_id, std::string name, float k, float n, int bed_temp, int nozzle_temp, float max_volumetric_speed) +{ + BOOST_LOG_TRIVIAL(info) << "extrusion_cali: tray_id = " << tray_index << ", setting_id = " << setting_id << ", k = " << k + << ", n = " << n; + json j; + j["print"]["command"] = "extrusion_cali_set"; + j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++); + j["print"]["tray_id"] = tray_index; + //j["print"]["setting_id"] = setting_id; + //j["print"]["name"] = name; + j["print"]["k_value"] = k; + j["print"]["n_coef"] = 1.4f; // fixed n + //j["print"]["n_coef"] = n; + if (bed_temp >= 0 && nozzle_temp >= 0 && max_volumetric_speed >= 0) { + j["print"]["bed_temp"] = bed_temp; + j["print"]["nozzle_temp"] = nozzle_temp; + j["print"]["max_volumetric_speed"] = max_volumetric_speed; + } + return this->publish_json(j.dump()); +} + + int MachineObject::command_set_printing_speed(PrintingSpeedLevel lvl) { json j; @@ -2086,6 +2157,11 @@ bool MachineObject::is_function_supported(PrinterFunction func) case FUNC_CHAMBER_FAN: func_name = "FUNC_CHAMBER_FAN"; break; + case FUNC_EXTRUSION_CALI: + if (!ams_support_virtual_tray) + return false; + func_name = "FUNC_EXTRUSION_CALI"; + break; default: return true; } @@ -2938,6 +3014,15 @@ int MachineObject::parse_json(std::string payload) } catch (...) { } + if (tray_it->contains("setting_id")) { + curr_tray->filament_setting_id = (*tray_it)["setting_id"].get(); + } + if (tray_it->contains("k")) { + curr_tray->k = (*tray_it)["k"].get(); + } + if (tray_it->contains("n")) { + curr_tray->n = (*tray_it)["n"].get(); + } } // remove not in trayList for (auto tray_it = tray_id_set.begin(); tray_it != tray_id_set.end(); tray_it++) { @@ -2961,6 +3046,21 @@ int MachineObject::parse_json(std::string payload) } } } + + /* vitrual tray*/ + try { + if (jj.contains("vt_tray")) { + if (jj["vt_tray"].contains("id")) + vt_tray.id = jj["vt_tray"]["id"].get(); + if (jj["vt_tray"].contains("k")) + vt_tray.k = jj["vt_tray"]["k"].get(); + if (jj["vt_tray"].contains("n")) + vt_tray.n = jj["vt_tray"]["n"].get(); + } + } + catch (...) { + ; + } #pragma endregion } else if (jj["command"].get() == "gcode_line") { @@ -3041,7 +3141,7 @@ int MachineObject::parse_json(std::string payload) } } } - }else if(jj["command"].get() == "print_option") { + } else if(jj["command"].get() == "print_option") { try { if (jj.contains("option")) { if (jj["option"].is_number()) { @@ -3055,6 +3155,46 @@ int MachineObject::parse_json(std::string payload) } catch(...) { } + } else if (jj["command"].get() == "extrusion_cali") { + if (jj.contains("result") && jj["result"].get() == "success") { + // enter extrusion cali + } + } else if (jj["command"].get() == "extrusion_cali_set") { + int ams_id = -1; + int tray_id = -1; + if (jj.contains("tray_id")) { + try { + int curr_tray_id = jj["tray_id"].get(); + if (curr_tray_id == VIRTUAL_TRAY_ID) + tray_id = curr_tray_id; + else if (curr_tray_id >= 0 && curr_tray_id < 16){ + ams_id = curr_tray_id / 4; + tray_id = curr_tray_id % 4; + } else { + BOOST_LOG_TRIVIAL(trace) << "extrusion_cali_set: unsupported tray_id = " << curr_tray_id; + } + } + catch(...) { + ; + } + } + if (tray_id == VIRTUAL_TRAY_ID) { + if (jj.contains("k_value")) + vt_tray.k = jj["k_value"].get(); + if (jj.contains("n_coef")) + vt_tray.n = jj["n_coef"].get(); + } else { + auto ams_item = this->amsList.find(std::to_string(ams_id)); + if (ams_item != this->amsList.end()) { + auto tray_item = ams_item->second->trayList.find(std::to_string(tray_id)); + if (tray_item != ams_item->second->trayList.end()) { + if (jj.contains("k_value")) + tray_item->second->k = jj["k_value"].get(); + if (jj.contains("n_coef")) + tray_item->second->n = jj["n_coef"].get(); + } + } + } } } } diff --git a/src/slic3r/GUI/DeviceManager.hpp b/src/slic3r/GUI/DeviceManager.hpp index ecd26aeac..383cb4169 100644 --- a/src/slic3r/GUI/DeviceManager.hpp +++ b/src/slic3r/GUI/DeviceManager.hpp @@ -30,6 +30,7 @@ #define HOLD_COUNT_CAMERA 6 #define GET_VERSION_RETRYS 10 #define RETRY_INTERNAL 2000 +#define VIRTUAL_TRAY_ID 254 inline int correct_filament_temperature(int filament_temp) { @@ -85,6 +86,7 @@ enum PrinterFunction { FUNC_SEND_TO_SDCARD, FUNC_AUTO_SWITCH_FILAMENT, FUNC_CHAMBER_FAN, + FUNC_EXTRUSION_CALI, FUNC_MAX }; @@ -178,8 +180,9 @@ public: } std::string id; - std::string tag_uid; // tag_uid - std::string setting_id; // tray_info_idx + std::string tag_uid; // tag_uid + std::string setting_id; // tray_info_idx + std::string filament_setting_id; // setting_id std::string type; std::string sub_brands; std::string color; @@ -193,6 +196,8 @@ public: std::string nozzle_temp_min; std::string xcam_info; std::string uuid; + float k = 0.0f; // k range: 0 ~ 0.5 + float n = 0.0f; // k range: 0.6 ~ 2.0 wxColour wx_color; bool is_bbl; @@ -364,6 +369,15 @@ public: SDCARD_STATE_NUM = 3 }; + class ExtrusionRatioInfo + { + public: + std::string name; + std::string setting_id; + float k = 0.0; + float n = 0.0; + }; + /* static members and functions */ static inline int m_sequence_id = 20000; static std::string parse_printer_type(std::string type_str); @@ -416,6 +430,7 @@ public: /* ams properties */ std::map amsList; // key: ams[id], start with 0 + AmsTray vt_tray; // virtual tray long ams_exist_bits = 0; long tray_exist_bits = 0; long tray_is_bbl_bits = 0; @@ -429,6 +444,7 @@ public: bool ams_auto_switch_filament_flag { false }; bool ams_support_use_ams { false }; bool ams_support_remain { true }; + bool ams_support_virtual_tray { true }; int ams_humidity; int ams_user_setting_hold_count = 0; AmsStatusMain ams_status_main; @@ -438,6 +454,9 @@ public: std::string m_tray_id; // local tray id : "0" ~ "3" std::string m_tray_now; // tray_now : "0" ~ "15" or "255" std::string m_tray_tar; // tray_tar : "0" ~ "15" or "255" + + bool is_in_extrusion_cali(); + bool is_extrusion_cali_finished(); void _parse_tray_now(std::string tray_now); bool is_filament_move() { return atoi(m_tray_now.c_str()) == 255 ? false : true; }; bool is_ams_need_update; @@ -509,6 +528,7 @@ public: int get_version_retry = 0; std::map module_vers; std::map new_ver_list; + std::map extrusion_ratio_map; bool m_new_ver_list_exist = false; int upgrade_err_code = 0; std::vector firmware_list; @@ -525,10 +545,9 @@ public: /* printing */ std::string print_type; - float nozzle { 0.0f }; + float nozzle { 0.0f }; // default is 0.0f as initial value bool is_220V_voltage { false }; - int mc_print_stage; int mc_print_sub_stage; int mc_print_error_code; @@ -665,12 +684,15 @@ public: int command_ams_user_settings(int ams_id, AmsOptionType op, bool value); int command_ams_switch_filament(bool switch_filament); int command_ams_calibrate(int ams_id); - int command_ams_filament_settings(int ams_id, int tray_id, std::string setting_id, std::string tray_color, std::string tray_type, int nozzle_temp_min, int nozzle_temp_max); + int command_ams_filament_settings(int ams_id, int tray_id, std::string filament_id, std::string setting_id, std::string tray_color, std::string tray_type, int nozzle_temp_min, int nozzle_temp_max); int command_ams_select_tray(std::string tray_id); int command_ams_refresh_rfid(std::string tray_id); int command_ams_control(std::string action); int command_set_chamber_light(LIGHT_EFFECT effect, int on_time = 500, int off_time = 500, int loops = 1, int interval = 1000); int command_set_work_light(LIGHT_EFFECT effect, int on_time = 500, int off_time = 500, int loops = 1, int interval = 1000); + int command_start_extrusion_cali(int tray_index, int nozzle_temp, int bed_temp, float max_volumetric_speed, std::string setting_id = ""); + int command_stop_extrusion_cali(); + int command_extrusion_cali_set(int tray_index, std::string setting_id, std::string name, float k, float n, int bed_temp = -1, int nozzle_temp = -1, float max_volumetric_speed = -1); // set printing speed int command_set_printing_speed(PrintingSpeedLevel lvl); diff --git a/src/slic3r/GUI/ExtrusionCalibration.cpp b/src/slic3r/GUI/ExtrusionCalibration.cpp new file mode 100644 index 000000000..976a7a4a0 --- /dev/null +++ b/src/slic3r/GUI/ExtrusionCalibration.cpp @@ -0,0 +1,758 @@ +#include "ExtrusionCalibration.hpp" +#include "GUI_App.hpp" +#include "MsgDialog.hpp" +#include "libslic3r/Preset.hpp" +#include "I18N.hpp" + +namespace Slic3r { namespace GUI { + + +ExtrusionCalibration::ExtrusionCalibration(wxWindow *parent, wxWindowID id) + : DPIDialog(parent, id, _L("Dynamic flow calibration"), wxDefaultPosition, wxDefaultSize, (wxSYSTEM_MENU | + wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxCLOSE_BOX | wxCAPTION |wxCLIP_CHILDREN)) +{ + create(); + wxGetApp().UpdateDlgDarkUI(this); +} + +void ExtrusionCalibration::create() +{ + SetBackgroundColour(*wxWHITE); + wxBoxSizer* sizer_main = new wxBoxSizer(wxVERTICAL); + m_step_1_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + m_step_1_panel->SetBackgroundColour(*wxWHITE); + wxBoxSizer* step_1_sizer = new wxBoxSizer(wxVERTICAL); + + m_step_1_panel->SetSizer(step_1_sizer); + + step_1_sizer->Add(0, EXTRUSION_CALIBRATION_WIDGET_GAP, 0, 0); + + // filament title + wxString intro_text = _L("The nozzle temp and max volumetric speed will affect the calibration results. Please fill in the same values as the actual printing. They can be auto-filled by selecting a filament preset."); + m_filament_preset_title = new Label(m_step_1_panel, intro_text); + m_filament_preset_title->SetFont(Label::Body_12); + m_filament_preset_title->SetForegroundColour(EXTRUSION_CALIBRATION_GREY800); + m_filament_preset_title->Wrap(this->GetSize().x); + step_1_sizer->Add(m_filament_preset_title, 0, wxEXPAND); + + step_1_sizer->AddSpacer(FromDIP(12)); + + auto select_sizer = new wxBoxSizer(wxVERTICAL); + + auto nozzle_dia_sel_text = new wxStaticText(m_step_1_panel, wxID_ANY, _L("Nozzle Diameter"), wxDefaultPosition, wxDefaultSize, 0); + select_sizer->Add(nozzle_dia_sel_text, 0, wxALIGN_LEFT); + select_sizer->AddSpacer(FromDIP(4)); + + +#ifdef __APPLE__ + m_comboBox_nozzle_dia = new wxComboBox(m_step_1_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, EXTRUSION_CALIBRATION_BED_COMBOX, 0, nullptr, wxCB_READONLY); +#else + m_comboBox_nozzle_dia = new ComboBox(m_step_1_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, EXTRUSION_CALIBRATION_BED_COMBOX, 0, nullptr, wxCB_READONLY); +#endif + m_comboBox_nozzle_dia->AppendString("0.2"); + m_comboBox_nozzle_dia->AppendString("0.4"); + m_comboBox_nozzle_dia->AppendString("0.6"); + m_comboBox_nozzle_dia->AppendString("0.8"); + + select_sizer->Add(m_comboBox_nozzle_dia, 0, wxEXPAND); + select_sizer->Add(0, EXTRUSION_CALIBRATION_WIDGET_GAP, 0, 0); + + auto filament_sel_text = new wxStaticText(m_step_1_panel, wxID_ANY, _L("Filament"), wxDefaultPosition, wxDefaultSize, 0); + select_sizer->Add(filament_sel_text, 0, wxALIGN_LEFT); + select_sizer->AddSpacer(FromDIP(4)); +#ifdef __APPLE__ + m_comboBox_filament = new wxComboBox(m_step_1_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, EXTRUSION_CALIBRATION_BED_COMBOX, 0, nullptr, wxCB_READONLY); +#else + m_comboBox_filament = new ComboBox(m_step_1_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, EXTRUSION_CALIBRATION_BED_COMBOX, 0, nullptr, wxCB_READONLY); +#endif + select_sizer->Add(m_comboBox_filament, 0, wxEXPAND); + select_sizer->Add(0, EXTRUSION_CALIBRATION_WIDGET_GAP, 0, 0); + + auto bed_type_sel_text = new wxStaticText(m_step_1_panel, wxID_ANY, _L("Bed Type"), wxDefaultPosition, wxDefaultSize, 0); + select_sizer->Add(bed_type_sel_text, 0, wxALIGN_LEFT); + select_sizer->AddSpacer(FromDIP(4)); + +#ifdef __APPLE__ + m_comboBox_bed_type = new wxComboBox(m_step_1_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, EXTRUSION_CALIBRATION_BED_COMBOX, 0, nullptr, wxCB_READONLY); +#else + m_comboBox_bed_type = new ComboBox(m_step_1_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, EXTRUSION_CALIBRATION_BED_COMBOX, 0, nullptr, wxCB_READONLY); +#endif + select_sizer->Add(m_comboBox_bed_type, 0, wxEXPAND); + + // get bed type + const ConfigOptionDef* bed_type_def = print_config_def.get("curr_bed_type"); + if (bed_type_def && bed_type_def->enum_keys_map) { + for (auto item : *bed_type_def->enum_keys_map) { + if (item.first == "Default Plate") + continue; + m_comboBox_bed_type->AppendString(_L(item.first)); + } + } + + step_1_sizer->Add(select_sizer, 0, wxEXPAND); + + // static line + step_1_sizer->Add(0, EXTRUSION_CALIBRATION_WIDGET_GAP, 0, 0); + wxPanel* static_line = new wxPanel(m_step_1_panel, wxID_ANY, wxDefaultPosition, { -1, FromDIP(1) }); + static_line->SetBackgroundColour(EXTRUSION_CALIBRATION_GREY300); + step_1_sizer->Add(static_line, 0, wxEXPAND); + step_1_sizer->Add(0, EXTRUSION_CALIBRATION_WIDGET_GAP, 0, 0); + + // filament info + auto info_sizer = new wxFlexGridSizer(0, 3, 0, FromDIP(16)); + info_sizer->SetFlexibleDirection(wxBOTH); + info_sizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); + + auto nozzle_temp_sizer = new wxBoxSizer(wxVERTICAL); + auto nozzle_temp_text = new wxStaticText(m_step_1_panel, wxID_ANY, _L("Nozzle temperature")); + auto max_input_width = std::max(std::max(std::max(wxWindow::GetTextExtent(_L("Nozzle temperature")).x, + wxWindow::GetTextExtent(_L("Bed Temperature")).x), + wxWindow::GetTextExtent(_L("Max Flow")).x), + EXTRUSION_CALIBRATION_INPUT_SIZE.x); + m_nozzle_temp = new TextInput(m_step_1_panel, wxEmptyString, _L("\u2103"), "", wxDefaultPosition, { max_input_width, EXTRUSION_CALIBRATION_INPUT_SIZE.y }, wxTE_READONLY); + nozzle_temp_sizer->Add(nozzle_temp_text, 0, wxALIGN_LEFT); + nozzle_temp_sizer->AddSpacer(FromDIP(4)); + nozzle_temp_sizer->Add(m_nozzle_temp, 0, wxEXPAND); + + auto bed_temp_sizer = new wxBoxSizer(wxVERTICAL); + auto bed_temp_text = new wxStaticText(m_step_1_panel, wxID_ANY, _L("Bed temperature")); + m_bed_temp = new TextInput(m_step_1_panel, wxEmptyString, _L("\u2103"), "", wxDefaultPosition, { max_input_width, EXTRUSION_CALIBRATION_INPUT_SIZE.y }, wxTE_READONLY); + bed_temp_sizer->Add(bed_temp_text, 0, wxALIGN_LEFT); + bed_temp_sizer->AddSpacer(FromDIP(4)); + bed_temp_sizer->Add(m_bed_temp, 0, wxEXPAND); + + auto max_flow_sizer = new wxBoxSizer(wxVERTICAL); + auto max_flow_text = new wxStaticText(m_step_1_panel, wxID_ANY, _L("Max volumetric speed")); + m_max_flow_ratio = new TextInput(m_step_1_panel, wxEmptyString, _L("mm\u00B3"), "", wxDefaultPosition, { max_input_width, EXTRUSION_CALIBRATION_INPUT_SIZE.y }, wxTE_READONLY); + max_flow_sizer->Add(max_flow_text, 0, wxALIGN_LEFT); + max_flow_sizer->AddSpacer(FromDIP(4)); + max_flow_sizer->Add(m_max_flow_ratio, 0, wxEXPAND); + + info_sizer->Add(nozzle_temp_sizer); + info_sizer->Add(bed_temp_sizer); + info_sizer->Add(max_flow_sizer); + + step_1_sizer->Add(info_sizer, 0, wxEXPAND); + + // static line + step_1_sizer->Add(0, EXTRUSION_CALIBRATION_WIDGET_GAP, 0, 0); + wxPanel* static_line2 = new wxPanel(m_step_1_panel, wxID_ANY, wxDefaultPosition, { -1, FromDIP(1) }); + static_line2->SetBackgroundColour(EXTRUSION_CALIBRATION_GREY300); + step_1_sizer->Add(static_line2, 0, wxEXPAND); + step_1_sizer->Add(0, EXTRUSION_CALIBRATION_WIDGET_GAP, 0, 0); + + auto cali_sizer = new wxBoxSizer(wxHORIZONTAL); + + m_info_text = new wxStaticText(m_step_1_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END); + m_info_text->SetFont(Label::Body_12); + m_info_text->Hide(); + + m_error_text = new wxStaticText(m_step_1_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END); + m_error_text->SetFont(Label::Body_12); + m_error_text->SetForegroundColour(wxColour(208, 27, 27)); + m_error_text->Hide(); + + m_button_cali = new Button(m_step_1_panel, _L("Start")); + m_btn_bg_green = StateColor(std::pair(wxColour(238, 238, 238), StateColor::Disabled), std::pair(wxColour(27, 136, 68), StateColor::Pressed), std::pair(wxColour(61, 203, 115), StateColor::Hovered), + std::pair(wxColour(0, 174, 66), StateColor::Normal)); + m_button_cali->SetBackgroundColor(m_btn_bg_green); + m_button_cali->SetFont(Label::Body_13); + m_button_cali->SetBorderColor({ std::pair(wxColour(238, 238, 238), StateColor::Disabled), std::pair(wxColour(0, 174, 66), StateColor::Enabled) }); + m_button_cali->SetTextColor({ std::pair(wxColour(172, 172, 172), StateColor::Disabled), std::pair(EXTRUSION_CALIBRATION_GREY200, StateColor::Enabled) }); + m_button_cali->SetCornerRadius(FromDIP(12)); + m_button_cali->SetMinSize(wxSize(-1, FromDIP(24))); + m_button_cali->Bind(wxEVT_BUTTON, &ExtrusionCalibration::on_click_cali, this); + + m_cali_cancel = new Button(m_step_1_panel, _L("Cancel")); + m_btn_bg_green = StateColor(std::pair(wxColour(27, 136, 68), StateColor::Pressed), std::pair(wxColour(61, 203, 115), StateColor::Hovered), + std::pair(wxColour(0, 174, 66), StateColor::Normal)); + m_cali_cancel->SetBackgroundColor(m_btn_bg_green); + m_cali_cancel->SetBorderColor(wxColour(0, 174, 66)); + m_cali_cancel->SetTextColor(EXTRUSION_CALIBRATION_GREY200); + m_cali_cancel->SetMinSize(EXTRUSION_CALIBRATION_BUTTON_SIZE); + m_cali_cancel->SetCornerRadius(FromDIP(12)); + m_cali_cancel->Hide(); + m_cali_cancel->Bind(wxEVT_BUTTON, &ExtrusionCalibration::on_click_cancel, this); + + m_button_next_step = new Button(m_step_1_panel, _L("Next")); + m_btn_bg_gray = StateColor(std::pair(wxColour(206, 206, 206), StateColor::Pressed), std::pair(*wxWHITE, StateColor::Focused), + std::pair(wxColour(238, 238, 238), StateColor::Hovered), + std::pair(*wxWHITE, StateColor::Normal)); + m_button_next_step->SetBackgroundColor(m_btn_bg_gray); + m_button_next_step->SetFont(Label::Body_13); + m_button_next_step->SetBorderColor(EXTRUSION_CALIBRATION_GREY900); + m_button_next_step->SetTextColor(EXTRUSION_CALIBRATION_GREY900); + m_button_next_step->SetMinSize(EXTRUSION_CALIBRATION_BUTTON_SIZE); + m_button_next_step->SetCornerRadius(FromDIP(12)); + m_button_next_step->Bind(wxEVT_BUTTON, &ExtrusionCalibration::on_click_next, this); + m_button_next_step->Hide(); + + cali_sizer->Add(m_info_text, 10, wxALIGN_LEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL, FromDIP(10)); + cali_sizer->Add(m_error_text, 10, wxALIGN_LEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL, FromDIP(10)); + cali_sizer->AddStretchSpacer(); + cali_sizer->Add(m_button_cali, 0, wxRIGHT | wxALIGN_CENTRE_VERTICAL, FromDIP(10)); + cali_sizer->Add(m_cali_cancel, 0, wxRIGHT | wxALIGN_CENTRE_VERTICAL, FromDIP(10)); + cali_sizer->Add(m_button_next_step, 0, wxRIGHT | wxALIGN_CENTRE_VERTICAL, FromDIP(10)); + + step_1_sizer->Add(cali_sizer, 0, wxEXPAND); + step_1_sizer->Add(0, EXTRUSION_CALIBRATION_WIDGET_GAP, 0, 0); + + + m_step_2_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + m_step_2_panel->SetBackgroundColour(*wxWHITE); + wxBoxSizer* step_2_sizer = new wxBoxSizer(wxVERTICAL); + m_step_2_panel->SetSizer(step_2_sizer); + + step_2_sizer->Add(0, EXTRUSION_CALIBRATION_WIDGET_GAP, 0, 0); + + // save result title and tips + wxBoxSizer* save_result_sizer = new wxBoxSizer(wxHORIZONTAL); + wxString fill_intro_text = _L("Calibration completed. Please select the factors according to the left figure and fill them in the input boxes."); + m_save_cali_result_title = new Label(m_step_2_panel, fill_intro_text); + m_save_cali_result_title->SetFont(::Label::Body_12); + m_save_cali_result_title->SetForegroundColour(EXTRUSION_CALIBRATION_GREY800); + m_save_cali_result_title->Wrap(this->GetSize().x); + save_result_sizer->Add(m_save_cali_result_title, 0, wxEXPAND); + step_2_sizer->Add(save_result_sizer, 0, wxEXPAND); + step_2_sizer->Add(0, EXTRUSION_CALIBRATION_WIDGET_GAP, 0, 0); + + auto content_sizer = new wxBoxSizer(wxHORIZONTAL); + m_calibration_tips_static_bmp = new wxStaticBitmap(m_step_2_panel, wxID_ANY, wxNullBitmap, wxDefaultPosition, EXTRUSION_CALIBRATION_BMP_SIZE, 0); + content_sizer->Add(m_calibration_tips_static_bmp, 1, wxEXPAND | wxSHAPED); + m_calibration_tips_bmp = create_scaled_bitmap("extrusion_calibration_tips", nullptr, 256); + m_calibration_tips_open_btn_bmp = create_scaled_bitmap("extrusion_calibrati_open_button", nullptr, 32); + content_sizer->Add(EXTRUSION_CALIBRATION_WIDGET_GAP, 0, 0, 0); + // k/n input value + auto kn_sizer = new wxBoxSizer(wxVERTICAL); + auto k_val_text = new wxStaticText(m_step_2_panel, wxID_ANY, _L("Factor K"), wxDefaultPosition, wxDefaultSize, 0); + m_k_val = new TextInput(m_step_2_panel, wxEmptyString, "", "", wxDefaultPosition, wxDefaultSize); + auto n_val_text = new wxStaticText(m_step_2_panel, wxID_ANY, _L("Factor N"), wxDefaultPosition, wxDefaultSize, 0); + m_n_val = new TextInput(m_step_2_panel, wxEmptyString, "", "", wxDefaultPosition, wxDefaultSize); + + // hide n + n_val_text->Hide(); + m_n_val->Hide(); + kn_sizer->Add(k_val_text, 0, wxALIGN_CENTER_VERTICAL); + kn_sizer->Add(m_k_val, 0, wxEXPAND); + kn_sizer->Add(0, EXTRUSION_CALIBRATION_WIDGET_GAP, 0, 0); + kn_sizer->Add(n_val_text, 0, wxALIGN_CENTER_VERTICAL); + kn_sizer->Add(m_n_val, 0, wxEXPAND); + + // save button + m_button_save_result = new Button(m_step_2_panel, _L("Save")); + m_btn_bg_green = StateColor(std::pair(wxColour(27, 136, 68), StateColor::Pressed), std::pair(wxColour(61, 203, 115), StateColor::Hovered), + std::pair(wxColour(0, 174, 66), StateColor::Normal)); + m_button_save_result->SetBackgroundColor(m_btn_bg_green); + m_button_save_result->SetFont(Label::Body_13); + m_button_save_result->SetBorderColor(wxColour(0, 174, 66)); + m_button_save_result->SetTextColor(EXTRUSION_CALIBRATION_GREY200); + m_button_save_result->SetMinSize(EXTRUSION_CALIBRATION_BUTTON_SIZE); + m_button_save_result->SetCornerRadius(FromDIP(12)); + m_button_save_result->Bind(wxEVT_BUTTON, &ExtrusionCalibration::on_click_save, this); + + m_button_last_step = new Button(m_step_2_panel, _L("Last Step")); // Back for english + m_button_last_step->SetBackgroundColor(m_btn_bg_gray); + m_button_last_step->SetFont(Label::Body_13); + m_button_last_step->SetBorderColor(EXTRUSION_CALIBRATION_GREY900); + m_button_last_step->SetTextColor(EXTRUSION_CALIBRATION_GREY900); + m_button_last_step->SetMinSize(EXTRUSION_CALIBRATION_BUTTON_SIZE); + m_button_last_step->SetCornerRadius(FromDIP(12)); + m_button_last_step->Bind(wxEVT_BUTTON, &ExtrusionCalibration::on_click_last, this); + + + kn_sizer->AddStretchSpacer(); + kn_sizer->Add(m_button_last_step, 0); + kn_sizer->AddSpacer(FromDIP(10)); + kn_sizer->Add(m_button_save_result, 0); + + content_sizer->Add(kn_sizer, 0, wxEXPAND); + + step_2_sizer->Add(content_sizer, 0, wxEXPAND); + step_2_sizer->Add(0, EXTRUSION_CALIBRATION_WIDGET_GAP, 0, 0); + + sizer_main->Add(m_step_1_panel, 1, wxEXPAND); + sizer_main->Add(m_step_2_panel, 1, wxEXPAND); + + wxBoxSizer* top_sizer = new wxBoxSizer(wxHORIZONTAL); + top_sizer->Add(FromDIP(24), 0); + top_sizer->Add(sizer_main, 1, wxEXPAND); + top_sizer->Add(FromDIP(24), 0); + SetSizer(top_sizer); + + // set default nozzle + m_comboBox_nozzle_dia->SetSelection(1); + // set a default bed type + m_comboBox_bed_type->SetSelection(0); + // set to step 1 + set_step(1); + + Layout(); + Fit(); + + m_k_val->GetTextCtrl()->Bind(wxEVT_TEXT_ENTER, [this](wxCommandEvent& e) { + input_value_finish(); + e.Skip(); + }); + + m_n_val->GetTextCtrl()->Bind(wxEVT_TEXT_ENTER, [this](wxCommandEvent& e) { + input_value_finish(); + e.Skip(); + }); + + + m_calibration_tips_static_bmp->Bind(wxEVT_PAINT, &ExtrusionCalibration::paint, this); + + m_calibration_tips_static_bmp->Bind(wxEVT_LEFT_UP, &ExtrusionCalibration::open_bitmap, this); + + m_comboBox_filament->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(ExtrusionCalibration::on_select_filament), NULL, this); + m_comboBox_bed_type->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(ExtrusionCalibration::on_select_bed_type), NULL, this); + m_comboBox_nozzle_dia->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(ExtrusionCalibration::on_select_nozzle_dia), NULL, this); +} + +ExtrusionCalibration::~ExtrusionCalibration() +{ + m_comboBox_filament->Disconnect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(ExtrusionCalibration::on_select_filament), NULL, this); + m_comboBox_bed_type->Disconnect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(ExtrusionCalibration::on_select_bed_type), NULL, this); + m_comboBox_nozzle_dia->Disconnect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(ExtrusionCalibration::on_select_nozzle_dia), NULL, this); +} + +void ExtrusionCalibration::paint(wxPaintEvent&) { + auto size = m_calibration_tips_static_bmp->GetSize(); + wxPaintDC dc(m_calibration_tips_static_bmp); + dc.DrawBitmap(m_calibration_tips_bmp, wxPoint(0, 0)); + dc.DrawBitmap(m_calibration_tips_open_btn_bmp, wxPoint(0, size.y - EXTRUSION_CALIBRATION_BMP_BTN_SIZE.y)); + return; +} + +void ExtrusionCalibration::open_bitmap(wxMouseEvent& event) { + auto pos = event.GetPosition(); + auto size = m_calibration_tips_static_bmp->GetSize(); + if (pos.x > 0 && pos.y > size.y - EXTRUSION_CALIBRATION_BMP_BTN_SIZE.y && + pos.x < EXTRUSION_CALIBRATION_BMP_BTN_SIZE.x && pos.y < size.y) { + auto* popup = new wxDialog(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize); + auto bmp_sizer = new wxBoxSizer(wxVERTICAL); + wxStaticBitmap* zoomed_bitmap = new wxStaticBitmap(popup, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0); + zoomed_bitmap->SetBitmap(create_scaled_bitmap("extrusion_calibration_tips", nullptr, 720)); + bmp_sizer->Add(zoomed_bitmap, 1, wxEXPAND); + popup->SetSizer(bmp_sizer); + popup->Layout(); + popup->Fit(); + popup->CenterOnParent(); + popup->ShowModal(); + } + return; +} + +void ExtrusionCalibration::input_value_finish() +{ + ; +} + +void ExtrusionCalibration::show_info(bool show, bool is_error, wxString text) +{ + if (show && !is_error) { + m_info_text->Show(); + m_info_text->SetLabelText(text); + m_error_text->Hide(); + } else if (show && is_error) { + m_error_text->Show(); + m_error_text->SetLabelText(text); + m_info_text->Hide(); + } else { + if (is_error) { + m_error_text->Hide(); + } else { + m_info_text->Hide(); + } + } +} + +void ExtrusionCalibration::update() +{ + if (obj) { + if (obj->is_in_extrusion_cali()) { + m_cali_cancel->Show(); + m_cali_cancel->Enable(); + show_info(true, false, wxString::Format(_L("Calibrating... %d%%"), obj->mc_print_percent)); + m_button_next_step->Hide(); + m_button_cali->Hide(); + } else if (obj->is_extrusion_cali_finished()) { + show_info(true, false, _L("Calibration completed")); + m_cali_cancel->Hide(); + m_button_next_step->Show(); + } else { + show_info(false, false, wxEmptyString); + m_cali_cancel->Hide(); + m_button_cali->Show(); + m_button_next_step->Hide(); + } + Layout(); + } +} + +void ExtrusionCalibration::on_click_cali(wxCommandEvent& event) +{ + if (obj) { + int nozzle_temp = -1; + int bed_temp = -1; + float max_volumetric_speed = -1; + + PresetBundle* preset_bundle = wxGetApp().preset_bundle; + if (preset_bundle) { + for (auto it = preset_bundle->filaments.begin(); it != preset_bundle->filaments.end(); it++) { + wxString filament_name = wxString::FromUTF8(it->name); + if (filament_name.compare(m_comboBox_filament->GetValue()) == 0) { + try { + bed_temp = get_bed_temp(&it->config); + const ConfigOptionInts* nozzle_temp_opt = it->config.option("nozzle_temperature"); + const ConfigOptionFloats* speed_opt = it->config.option("filament_max_volumetric_speed"); + if (nozzle_temp_opt && speed_opt) { + nozzle_temp = nozzle_temp_opt->get_at(0); + max_volumetric_speed = speed_opt->get_at(0); + if (bed_temp >= 0 && nozzle_temp >= 0 && max_volumetric_speed >= 0) { + int curr_tray_id = ams_id * 4 + tray_id; + if (tray_id == VIRTUAL_TRAY_ID) + curr_tray_id = tray_id; + obj->command_start_extrusion_cali(curr_tray_id, nozzle_temp, bed_temp, max_volumetric_speed, it->setting_id); + return; + } + } else { + BOOST_LOG_TRIVIAL(error) << "cali parameters is invalid"; + } + } catch(...) { + ; + } + } + } + } else { + BOOST_LOG_TRIVIAL(error) << "extrusion_cali: preset_bundle is nullptr"; + } + } else { + BOOST_LOG_TRIVIAL(error) << "cali obj parameters is invalid"; + } +} + +void ExtrusionCalibration::on_click_cancel(wxCommandEvent& event) +{ + if (obj) { + BOOST_LOG_TRIVIAL(info) << "extrusion_cali: stop"; + obj->command_stop_extrusion_cali(); + } +} + +bool ExtrusionCalibration::check_k_n_validation(wxString k_text, wxString n_text) +{ + if (k_text.IsEmpty() || n_text.IsEmpty()) + return false; + double k = 0.0; + try { + k_text.ToDouble(&k); + } + catch (...) { + ; + } + + double n = 0.0; + try { + n_text.ToDouble(&n); + } + catch (...) { + ; + } + if (k < 0 || k > 0.5) + return false; + if (n < 0.6 || n > 2.0) + return false; + return true; +} + +void ExtrusionCalibration::on_click_save(wxCommandEvent &event) +{ + wxString k_text = m_k_val->GetTextCtrl()->GetValue(); + wxString n_text = m_n_val->GetTextCtrl()->GetValue(); + if (!ExtrusionCalibration::check_k_n_validation(k_text, n_text)) { + wxString kn_tips = _L("Please input a valid value (K in 0~0.5, N in 0.6~2.0)"); + MessageDialog msg_dlg(nullptr, kn_tips, wxEmptyString, wxICON_WARNING | wxOK); + msg_dlg.ShowModal(); + return; + } + + double k = 0.0; + try { + k_text.ToDouble(&k); + } + catch (...) { + ; + } + + double n = 0.0; + try { + n_text.ToDouble(&n); + } + catch (...) { + ; + } + + // set values + int nozzle_temp = -1; + int bed_temp = -1; + float max_volumetric_speed = -1; + std::string setting_id; + std::string name; + PresetBundle* preset_bundle = wxGetApp().preset_bundle; + if (preset_bundle) { + for (auto it = preset_bundle->filaments.begin(); it != preset_bundle->filaments.end(); it++) { + wxString filament_name = wxString::FromUTF8(it->name); + if (filament_name.compare(m_comboBox_filament->GetValue()) == 0) { + if (obj) { + bed_temp = get_bed_temp(&it->config); + const ConfigOptionInts* nozzle_temp_opt = it->config.option("nozzle_temperature"); + const ConfigOptionFloats* speed_opt = it->config.option("filament_max_volumetric_speed"); + if (nozzle_temp_opt && speed_opt) { + nozzle_temp = nozzle_temp_opt->get_at(0); + max_volumetric_speed = speed_opt->get_at(0); + } + setting_id = it->setting_id; + name = it->name; + } + } + } + } + + // send command + int curr_tray_id = ams_id * 4 + tray_id; + if (tray_id == VIRTUAL_TRAY_ID) + curr_tray_id = tray_id; + obj->command_extrusion_cali_set(curr_tray_id, setting_id, name, k, n, bed_temp, nozzle_temp, max_volumetric_speed); + Close(); +} + +void ExtrusionCalibration::on_click_last(wxCommandEvent &event) +{ + set_step(1); +} + +void ExtrusionCalibration::on_click_next(wxCommandEvent& event) +{ + set_step(2); +} + +bool ExtrusionCalibration::Show(bool show) +{ + if (show) { + m_k_val->GetTextCtrl()->SetSize(wxSize(-1, FromDIP(20))); + m_n_val->GetTextCtrl()->SetSize(wxSize(-1, FromDIP(20))); + } + return DPIDialog::Show(show); +} + +void ExtrusionCalibration::update_combobox_filaments() +{ + m_comboBox_filament->SetValue(wxEmptyString); + user_filaments.clear(); + int selection_idx = -1; + wxArrayString filament_items; + PresetBundle* preset_bundle = wxGetApp().preset_bundle; + if (preset_bundle && obj) { + BOOST_LOG_TRIVIAL(trace) << "system_preset_bundle filament number=" << preset_bundle->filaments.size(); + std::string printer_type = obj->printer_type; + std::set printer_preset_list; + for (auto printer_it = preset_bundle->printers.begin(); printer_it != preset_bundle->printers.end(); printer_it++) { + // only use system printer preset + if (!printer_it->is_system) continue; + + std::string model_id = printer_it->get_current_printer_type(preset_bundle); + ConfigOption* printer_nozzle_opt = printer_it->config.option("nozzle_diameter"); + ConfigOptionFloats* printer_nozzle_vals = nullptr; + if (printer_nozzle_opt) + printer_nozzle_vals = dynamic_cast(printer_nozzle_opt); + double nozzle_value = 0.4; + wxString nozzle_value_str = m_comboBox_nozzle_dia->GetValue(); + try { + nozzle_value_str.ToDouble(&nozzle_value); + } catch(...) { + ; + } + if (!model_id.empty() && model_id.compare(obj->printer_type) == 0 + && printer_nozzle_vals + && abs(printer_nozzle_vals->get_at(0) - nozzle_value) < 1e-3) { + printer_preset_list.insert(printer_it->name); + BOOST_LOG_TRIVIAL(trace) << "extrusion_cali: printer_model = " << model_id; + } else { + BOOST_LOG_TRIVIAL(error) << "extrusion_cali: printer_model = " << model_id; + } + } + + for (auto filament_it = preset_bundle->filaments.begin(); filament_it != preset_bundle->filaments.end(); filament_it++) { + if (filament_it->setting_id.empty()) continue; + + ConfigOption* printer_opt = filament_it->config.option("compatible_printers"); + ConfigOptionStrings* printer_strs = dynamic_cast(printer_opt); + for (auto printer_str : printer_strs->values) { + if (printer_preset_list.find(printer_str) != printer_preset_list.end()) { + user_filaments.push_back(&(*filament_it)); + wxString filament_name = wxString::FromUTF8(filament_it->name); + filament_items.Add(filament_name); + break; + } + } + } + m_comboBox_filament->Set(filament_items); + m_comboBox_filament->SetSelection(selection_idx); + post_select_event(); + } + + if (m_comboBox_filament->GetValue().IsEmpty()) + m_button_cali->Disable(); + else + m_button_cali->Enable(); +} + +void ExtrusionCalibration::show_bed_type_incompatible(bool incompatible) +{ + if (incompatible) { + show_info(false, true, wxEmptyString); + m_button_cali->Enable(); + } else { + std::string filament_alias = ""; + PresetBundle* preset_bundle = wxGetApp().preset_bundle; + if (preset_bundle) { + for (auto filament_it = preset_bundle->filaments.begin(); filament_it != preset_bundle->filaments.end(); filament_it++) { + wxString filament_name = wxString::FromUTF8(filament_it->name); + if (filament_name.compare(m_comboBox_filament->GetValue()) == 0) { + filament_alias = filament_it->alias; + } + } + } + wxString tips = wxString::Format("%s does not support %s", m_comboBox_bed_type->GetValue(), filament_alias); + show_info(true, true, tips); + m_button_cali->Disable(); + } +} + +void ExtrusionCalibration::Popup() +{ + this->SetSize(EXTRUSION_CALIBRATION_DIALOG_SIZE); + + update_combobox_filaments(); + + set_step(1); + + update(); + Layout(); + Fit(); + ShowModal(); +} +void ExtrusionCalibration::post_select_event() { + wxCommandEvent event(wxEVT_COMBOBOX); + event.SetEventObject(m_comboBox_filament); + wxPostEvent(m_comboBox_filament, event); +} + +void ExtrusionCalibration::set_step(int step_index) +{ + if (step_index == 2) { + wxString title_text = wxString::Format("%s - %s 2/2", _L("Dynamic flow Calibration"), _L("Step")); + SetTitle(title_text); + m_step_1_panel->Hide(); + m_step_2_panel->Show(); + } else { + wxString title_text = wxString::Format("%s - %s 1/2", _L("Dynamic flow Calibration"), _L("Step")); + SetTitle(title_text); + m_step_1_panel->Show(); + m_step_2_panel->Hide(); + } + this->SetMinSize(EXTRUSION_CALIBRATION_DIALOG_SIZE); + Layout(); + Fit(); +} + +void ExtrusionCalibration::on_select_filament(wxCommandEvent &evt) +{ + m_filament_type = ""; + update_filament_info(); + + // set a default value for input values + if (m_k_val->GetTextCtrl()->GetValue().IsEmpty()) { + m_k_val->GetTextCtrl()->SetValue("0"); + } + if (m_n_val->GetTextCtrl()->GetValue().IsEmpty()) { + m_n_val->GetTextCtrl()->SetValue("0"); + } +} + +void ExtrusionCalibration::update_filament_info() +{ + if (m_comboBox_filament->GetValue().IsEmpty()) { + m_nozzle_temp->GetTextCtrl()->SetValue(wxEmptyString); + m_bed_temp->GetTextCtrl()->SetValue(wxEmptyString); + m_max_flow_ratio->GetTextCtrl()->SetValue(wxEmptyString); + return; + } + + PresetBundle* preset_bundle = wxGetApp().preset_bundle; + int bed_temp_int = -1; + if (preset_bundle) { + for (auto filament_it = preset_bundle->filaments.begin(); filament_it != preset_bundle->filaments.end(); filament_it++) { + wxString filament_name = wxString::FromUTF8(filament_it->name); + if (filament_name.compare(m_comboBox_filament->GetValue()) == 0) { + m_filament_type = filament_it->name; + + // update nozzle temperature + ConfigOption* opt_nozzle_temp = filament_it->config.option("nozzle_temperature"); + if (opt_nozzle_temp) { + ConfigOptionInts* opt_min_ints = dynamic_cast(opt_nozzle_temp); + if (opt_min_ints) { + wxString text_nozzle_temp = wxString::Format("%d", opt_min_ints->get_at(0)); + m_nozzle_temp->GetTextCtrl()->SetValue(text_nozzle_temp); + } + } + // update bed temperature + bed_temp_int = get_bed_temp(&filament_it->config); + wxString bed_temp_text = wxString::Format("%d", bed_temp_int); + m_bed_temp->GetTextCtrl()->SetValue(bed_temp_text); + + // update max flow speed + ConfigOption* opt_flow_speed = filament_it->config.option("filament_max_volumetric_speed"); + if (opt_flow_speed) { + ConfigOptionFloats* opt_flow_floats = dynamic_cast(opt_flow_speed); + if (opt_flow_floats) { + wxString flow_val_text = wxString::Format("%0.2f", opt_flow_floats->get_at(0)); + m_max_flow_ratio->GetTextCtrl()->SetValue(flow_val_text); + } + } + } + } + } + + // incompatible bed type and filament + if (bed_temp_int == 0) { + show_bed_type_incompatible(false); + } else { + show_bed_type_incompatible(true); + } +} + +int ExtrusionCalibration::get_bed_temp(DynamicPrintConfig* config) +{ + BedType curr_bed_type = BedType(m_comboBox_bed_type->GetSelection() + btDefault + 1); + const ConfigOptionInts* opt_bed_temp_ints = config->option(get_bed_temp_key(curr_bed_type)); + if (opt_bed_temp_ints) { + return opt_bed_temp_ints->get_at(0); + } + return -1; +} + +void ExtrusionCalibration::on_select_bed_type(wxCommandEvent &evt) +{ + update_filament_info(); +} + +void ExtrusionCalibration::on_select_nozzle_dia(wxCommandEvent &evt) +{ + update_combobox_filaments(); +} + +void ExtrusionCalibration::on_dpi_changed(const wxRect &suggested_rect) { this->Refresh(); } + +}} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/ExtrusionCalibration.hpp b/src/slic3r/GUI/ExtrusionCalibration.hpp new file mode 100644 index 000000000..7265d9ab5 --- /dev/null +++ b/src/slic3r/GUI/ExtrusionCalibration.hpp @@ -0,0 +1,142 @@ +#ifndef slic3r_ExtrusionCalibration_hpp_ +#define slic3r_ExtrusionCalibration_hpp_ + +#include "libslic3r/Preset.hpp" +#include "wxExtensions.hpp" +#include "GUI_Utils.hpp" +#include "DeviceManager.hpp" +#include "wx/clrpicker.h" +#include "Widgets/RadioBox.hpp" +#include "Widgets/Button.hpp" +#include "Widgets/RoundedRectangle.hpp" +#include "Widgets/Label.hpp" +#include "Widgets/CheckBox.hpp" +#include "Widgets/ComboBox.hpp" +#include "Widgets/TextInput.hpp" +#include "ParamsDialog.hpp" +#include "GUI_App.hpp" +#include "wx/hyperlink.h" + +#define EXTRUSION_CALIBRATION_DEF_COLOUR wxColour(255, 255, 255) +#define EXTRUSION_CALIBRATION_GREY900 wxColour(38, 46, 48) +#define EXTRUSION_CALIBRATION_GREY800 wxColour(50, 58, 61) +#define EXTRUSION_CALIBRATION_GREY700 wxColour(107, 107, 107) +#define EXTRUSION_CALIBRATION_GREY300 wxColour(238, 238, 238) +#define EXTRUSION_CALIBRATION_GREY200 wxColour(248, 248, 248) +#define EXTRUSION_CALIBRATION_BODY_WIDTH FromDIP(380) +#define EXTRUSION_CALIBRATION_LABEL_WIDTH FromDIP(80) +#define EXTRUSION_CALIBRATION_WIDGET_GAP FromDIP(18) +#define EXTRUSION_CALIBRATION_DIALOG_SIZE wxSize(FromDIP(400), -1) +//#define EXTRUSION_CALIBRATION_DIALOG_SIZE wxSize(FromDIP(520), -1) +#define EXTRUSION_CALIBRATION_BED_COMBOX wxSize(FromDIP(200), FromDIP(24)) +#define EXTRUSION_CALIBRATION_BUTTON_SIZE wxSize(FromDIP(72), FromDIP(24)) +#define EXTRUSION_CALIBRATION_INPUT_SIZE wxSize(FromDIP(100), FromDIP(24)) +#define EXTRUSION_CALIBRATION_BMP_SIZE wxSize(FromDIP(256), FromDIP(256)) +#define EXTRUSION_CALIBRATION_BMP_BTN_SIZE wxSize(FromDIP(32), FromDIP(32)) + + + +namespace Slic3r { namespace GUI { + +class ExtrusionCalibration : public DPIDialog +{ +public: + ExtrusionCalibration(wxWindow *parent, wxWindowID id); + ~ExtrusionCalibration(); + void create(); + + void input_value_finish(); + void update(); + bool Show(bool show) override; + void Popup(); + + void post_select_event(); + void update_machine_obj(MachineObject* obj_) { obj = obj_; }; + + // input is 1 or 2 + void set_step(int step_index); + + static bool check_k_n_validation(wxString k, wxString n); + + MachineObject *obj { nullptr }; + int ams_id { 0 }; /* 0 ~ 3 */ + int tray_id { 0 }; /* 0 ~ 3 | 254 for virtual tray id*/ + + std::string m_filament_type; + + std::vector user_filaments; + +protected: + void on_dpi_changed(const wxRect &suggested_rect) override; + void paint(wxPaintEvent&); + void open_bitmap(wxMouseEvent& event); + void on_select_filament(wxCommandEvent& evt); + void on_select_bed_type(wxCommandEvent& evt); + void on_select_nozzle_dia(wxCommandEvent& evt); + void on_click_cali(wxCommandEvent& evt); + void on_click_cancel(wxCommandEvent& evt); + void on_click_save(wxCommandEvent& evt); + void on_click_last(wxCommandEvent& evt); + void on_click_next(wxCommandEvent& evt); + + void update_filament_info(); + void update_combobox_filaments(); + void show_bed_type_incompatible(bool incompatible); + void show_info(bool show, bool is_error, wxString text); + + int get_bed_temp(DynamicPrintConfig* config); + +protected: + StateColor m_btn_bg_green; + StateColor m_btn_bg_gray; + + wxPanel* m_step_1_panel; + wxPanel* m_step_2_panel; + + // title of select filament preset + Label* m_filament_preset_title; + // select a filament preset +#ifdef __APPLE__ + wxComboBox* m_comboBox_filament; +#else + ComboBox* m_comboBox_filament; +#endif + +#ifdef __APPLE__ + wxComboBox* m_comboBox_bed_type; +#else + ComboBox* m_comboBox_bed_type; +#endif + +#ifdef __APPLE__ + wxComboBox* m_comboBox_nozzle_dia; +#else + ComboBox* m_comboBox_nozzle_dia; +#endif + + TextInput* m_nozzle_temp; + TextInput* m_bed_temp; + TextInput* m_max_flow_ratio; + Button* m_cali_cancel; + Button* m_button_cali; + Button* m_button_next_step; + Label* m_save_cali_result_title; + wxStaticText* m_fill_cali_params_tips; + wxStaticText* m_info_text; + wxStaticText* m_error_text; + + wxBitmap m_calibration_tips_open_btn_bmp; + wxBitmap m_calibration_tips_bmp; + wxStaticBitmap* m_calibration_tips_static_bmp; + // save n and k result + wxStaticText* m_k_param; + TextInput* m_k_val; + wxStaticText* m_n_param; + TextInput* m_n_val; + Button* m_button_last_step; + Button* m_button_save_result; +}; + +}} // namespace Slic3r::GUI + +#endif diff --git a/src/slic3r/GUI/StatusPanel.cpp b/src/slic3r/GUI/StatusPanel.cpp index 55076c65d..d59f07f5c 100644 --- a/src/slic3r/GUI/StatusPanel.cpp +++ b/src/slic3r/GUI/StatusPanel.cpp @@ -646,27 +646,31 @@ wxBoxSizer *StatusBasePanel::create_temp_axis_group(wxWindow *parent) box->SetBorderColor(box_border_colour); box->SetCornerRadius(5); - box->SetMinSize(wxSize(FromDIP(530), -1)); - box->SetMaxSize(wxSize(FromDIP(530), -1)); + box->SetMinSize(wxSize(FromDIP(578), -1)); + box->SetMaxSize(wxSize(FromDIP(578), -1)); wxBoxSizer *content_sizer = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer *m_temp_ctrl = create_temp_control(box); - content_sizer->Add(m_temp_ctrl, 0, wxEXPAND | wxALL, FromDIP(5)); + m_temp_extruder_line = new StaticLine(box, true); m_temp_extruder_line->SetLineColour(STATIC_BOX_LINE_COL); - content_sizer->Add(m_temp_extruder_line, 0, wxEXPAND, 1); - content_sizer->Add(FromDIP(9), 0, 0, wxEXPAND, 1); + auto m_axis_sizer = create_axis_control(box); - content_sizer->Add(m_axis_sizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0); + wxBoxSizer *bed_sizer = create_bed_control(box); - content_sizer->Add(bed_sizer, 0, wxEXPAND | wxLEFT | wxTOP| wxBOTTOM, FromDIP(12)); - - content_sizer->Add(0, 0, 0, wxLEFT, FromDIP(12)); - wxBoxSizer *extruder_sizer = create_extruder_control(box); + + content_sizer->Add(m_temp_ctrl, 0, wxEXPAND | wxALL, FromDIP(5)); + content_sizer->Add(m_temp_extruder_line, 0, wxEXPAND, 1); + content_sizer->Add(FromDIP(9), 0, 0, wxEXPAND, 1); + content_sizer->Add(0, 0, 0, wxLEFT, FromDIP(18)); + content_sizer->Add(m_axis_sizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0); + content_sizer->Add(0, 0, 0, wxLEFT, FromDIP(18)); + content_sizer->Add(bed_sizer, 0, wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, FromDIP(12)); + content_sizer->Add(0, 0, 0, wxLEFT, FromDIP(18)); content_sizer->Add(extruder_sizer, 0, wxEXPAND | wxTOP | wxBOTTOM, FromDIP(12)); box->SetSizer(content_sizer); @@ -1032,7 +1036,6 @@ wxBoxSizer *StatusBasePanel::create_extruder_control(wxWindow *parent) bSizer_e_ctrl->Add(0, 0, 1, wxEXPAND, 0); bSizer_e_ctrl->Add(m_button_unload, 0, wxALIGN_CENTER_HORIZONTAL| wxTOP|wxBOTTOM, FromDIP(5)); - bSizer_e_ctrl->Add(0, FromDIP(9), 0, wxEXPAND, 0); m_staticText_e = new wxStaticText(panel, wxID_ANY, _L("Extruder"), wxDefaultPosition, wxDefaultSize, 0); @@ -1062,7 +1065,7 @@ wxBoxSizer *StatusBasePanel::create_ams_group(wxWindow *parent) m_ams_control_box->SetBorderColor(box_border_colour); m_ams_control_box->SetCornerRadius(5); - m_ams_control_box->SetMinSize(wxSize(FromDIP(530), -1)); + m_ams_control_box->SetMinSize(wxSize(FromDIP(578), -1)); m_ams_control_box->SetBackgroundColour(*wxWHITE); #if !BBL_RELEASE_TO_PUBLIC m_ams_debug = new wxStaticText(m_ams_control_box, wxID_ANY, _L("Debug Info"), wxDefaultPosition, wxDefaultSize, 0); @@ -1083,13 +1086,12 @@ wxBoxSizer *StatusBasePanel::create_ams_group(wxWindow *parent) return sizer; } -void StatusBasePanel::show_ams_group(bool show) +void StatusBasePanel::show_ams_group(bool show, bool support_virtual_tray) { - if (m_show_ams_group != show) { - m_ams_control->Show(show); - m_ams_control_box->Show(show); - Fit(); - } + m_ams_control->Show(true); + m_ams_control_box->Show(true); + m_ams_control->show_noams_mode(show, support_virtual_tray); + Fit(); m_show_ams_group = show; } @@ -1248,12 +1250,14 @@ StatusPanel::StatusPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, co m_bpButton_e_10->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_axis_ctrl_e_up_10), NULL, this); m_bpButton_e_down_10->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_axis_ctrl_e_down_10), NULL, this); m_button_unload->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_start_unload), NULL, this); + Bind(EVT_AMS_EXTRUSION_CALI, &StatusPanel::on_filament_extrusion_cali, this); Bind(EVT_AMS_LOAD, &StatusPanel::on_ams_load, this); Bind(EVT_AMS_UNLOAD, &StatusPanel::on_ams_unload, this); Bind(EVT_AMS_SETTINGS, &StatusPanel::on_ams_setting_click, this); Bind(EVT_AMS_REFRESH_RFID, &StatusPanel::on_ams_refresh_rfid, this); Bind(EVT_AMS_ON_SELECTED, &StatusPanel::on_ams_selected, this); Bind(EVT_AMS_ON_FILAMENT_EDIT, &StatusPanel::on_filament_edit, this); + Bind(EVT_VAMS_ON_FILAMENT_EDIT, &StatusPanel::on_ext_spool_edit, this); Bind(EVT_AMS_GUIDE_WIKI, &StatusPanel::on_ams_guide, this); Bind(EVT_AMS_RETRY, &StatusPanel::on_ams_retry, this); Bind(EVT_FAN_CHANGED, &StatusPanel::on_fan_changed, this); @@ -1317,7 +1321,7 @@ void StatusPanel::init_scaled_buttons() //m_button_abort->SetMinSize(wxSize(FromDIP(48), FromDIP(24))); //m_button_abort->SetCornerRadius(FromDIP(12)); m_button_clean->SetMinSize(wxSize(FromDIP(48), FromDIP(24))); - m_button_clean->SetCornerRadius(FromDIP(12)); + m_button_clean->SetCornerRadius(FromDIP(12)); m_button_unload->SetMinSize(wxSize(-1, FromDIP(24))); m_button_unload->SetCornerRadius(FromDIP(12)); m_bpButton_z_10->SetMinSize(Z_BUTTON_SIZE); @@ -1490,6 +1494,15 @@ void StatusPanel::update(MachineObject *obj) update_cali(obj); if (obj) { + // update extrusion calibration + if (obj->is_function_supported(PrinterFunction::FUNC_EXTRUSION_CALI)) { + if (m_extrusion_cali_dlg) { + m_extrusion_cali_dlg->update_machine_obj(obj); + m_extrusion_cali_dlg->update(); + } + } + + // update calibration status if (calibration_dlg == nullptr) { calibration_dlg = new CalibrationDialog(); calibration_dlg->update_machine_obj(obj); @@ -1870,19 +1883,30 @@ void StatusPanel::update_ams(MachineObject *obj) last_read_done_bits = -1; last_reading_bits = -1; last_ams_version = -1; + m_ams_control->show_vams(false); m_ams_control->EnterNoneAMSMode(); - show_ams_group(false); + show_ams_group(false, obj->is_function_supported(PrinterFunction::FUNC_EXTRUSION_CALI)); BOOST_LOG_TRIVIAL(trace) << "machine object" << obj->dev_name << " was disconnected, set show_ams_group is false"; return; } + bool is_support_extrusion_cali = obj->is_function_supported(PrinterFunction::FUNC_EXTRUSION_CALI); + if (is_support_extrusion_cali) { + m_ams_control->show_vams(true); + m_ams_control->update_vams_kn_value(obj->vt_tray); + } + else { + m_ams_control->show_vams(false); + } + if (obj->amsList.empty() || obj->ams_exist_bits == 0) { m_ams_control->EnterNoneAMSMode(); - show_ams_group(false); + show_ams_group(false, obj->is_function_supported(PrinterFunction::FUNC_EXTRUSION_CALI)); + update_ams_control_state("", is_support_extrusion_cali); BOOST_LOG_TRIVIAL(trace) << "machine object" << obj->dev_name << " ams nonexistent, set show_ams_group is false"; return; } else { - show_ams_group(true); + show_ams_group(true, obj->is_function_supported(PrinterFunction::FUNC_EXTRUSION_CALI)); if (m_filament_setting_dlg) m_filament_setting_dlg->update(); std::vector ams_info; @@ -1904,10 +1928,9 @@ void StatusPanel::update_ams(MachineObject *obj) // last_ams_version = obj->ams_version; //} - // select current ams - // if (!obj->m_ams_id.empty()) m_ams_control->SwitchAms(obj->m_ams_id); + // must select a current can + m_ams_control->UpdateAms(ams_info, false, is_support_extrusion_cali); - m_ams_control->UpdateAms(ams_info, false); last_tray_exist_bits = obj->tray_exist_bits; last_ams_exist_bits = obj->ams_exist_bits; last_tray_is_bbl_bits = obj->tray_is_bbl_bits; @@ -1916,12 +1939,6 @@ void StatusPanel::update_ams(MachineObject *obj) last_ams_version = obj->ams_version; } - if (!obj->is_ams_unload()) { - ; // TODO set filament step to load - } else { - ; // TODO set filament step to unload - } - std::string curr_ams_id = m_ams_control->GetCurentAms(); std::string curr_can_id = m_ams_control->GetCurrentCan(curr_ams_id); @@ -2022,20 +2039,36 @@ void StatusPanel::update_ams(MachineObject *obj) } } catch (...) {} } - // update rfid button style + update_ams_control_state(curr_ams_id, is_support_extrusion_cali); +} + +void StatusPanel::update_ams_control_state(std::string ams_id, bool is_support_virtual_tray) +{ // update load/unload enable state - if (obj->is_in_printing() && !obj->can_resume()) { - m_ams_control->SetActionState(AMSAction::AMS_ACTION_PRINTING); - } else { + if (ams_id.compare(std::to_string(VIRTUAL_TRAY_ID)) == 0) { + m_ams_control->SetActionState(AMSAction::AMS_ACTION_VIRTUAL, is_support_virtual_tray); + } + else if (obj->is_in_extrusion_cali()) { + m_ams_control->SetActionState(AMSAction::AMS_ACTION_CALI, is_support_virtual_tray); + } + else if (!obj->has_ams()) { + m_ams_control->SetActionState(AMSAction::AMS_ACTION_NOAMS, is_support_virtual_tray); + } + else if (obj->is_in_printing() && !obj->can_resume()) { + m_ams_control->SetActionState(AMSAction::AMS_ACTION_PRINTING, is_support_virtual_tray); + } + else { if (obj->ams_status_main != AMS_STATUS_MAIN_FILAMENT_CHANGE) { if (obj->m_tray_now == "255") { - m_ams_control->SetActionState(AMSAction::AMS_ACTION_LOAD); - } else { - m_ams_control->SetActionState(AMSAction::AMS_ACTION_NORMAL); + m_ams_control->SetActionState(AMSAction::AMS_ACTION_LOAD, is_support_virtual_tray); } - } else { - m_ams_control->SetActionState(AMSAction::AMS_ACTION_PRINTING); + else { + m_ams_control->SetActionState(AMSAction::AMS_ACTION_NORMAL, is_support_virtual_tray); + } + } + else { + m_ams_control->SetActionState(AMSAction::AMS_ACTION_PRINTING, is_support_virtual_tray); } } } @@ -2500,6 +2533,42 @@ void StatusPanel::on_ams_setting_click(SimpleEvent &event) } } +void StatusPanel::on_filament_extrusion_cali(wxCommandEvent &event) +{ + if (!m_extrusion_cali_dlg) + m_extrusion_cali_dlg = new ExtrusionCalibration((wxWindow*)this, wxID_ANY); + + if (obj) { + m_extrusion_cali_dlg->obj = obj; + std::string ams_id = m_ams_control->GetCurentAms(); + std::string tray_id = m_ams_control->GetCurrentCan(ams_id); + if (tray_id.empty() && ams_id.compare(std::to_string(VIRTUAL_TRAY_ID)) != 0) { + wxString txt = _L("Please select an AMS slot before calibration"); + MessageDialog msg_dlg(nullptr, txt, wxEmptyString, wxICON_WARNING | wxOK); + msg_dlg.ShowModal(); + return; + } + + int ams_id_int = 0; + int tray_id_int = 0; + if (ams_id.compare(std::to_string(VIRTUAL_TRAY_ID)) == 0) { + tray_id_int = VIRTUAL_TRAY_ID; + } else { + ams_id_int = atoi(ams_id.c_str()); + tray_id_int = atoi(tray_id.c_str()); + } + + try { + m_extrusion_cali_dlg->ams_id = ams_id_int; + m_extrusion_cali_dlg->tray_id = tray_id_int; + m_extrusion_cali_dlg->SetPosition(m_ams_control->GetScreenPosition()); + m_extrusion_cali_dlg->Popup(); + } catch(...) { + ; + } + } +} + void StatusPanel::on_filament_edit(wxCommandEvent &event) { // update params @@ -2507,36 +2576,77 @@ void StatusPanel::on_filament_edit(wxCommandEvent &event) if (obj) { m_filament_setting_dlg->obj = obj; std::string ams_id = m_ams_control->GetCurentAms(); - std::string tray_id = event.GetString().ToStdString(); // m_ams_control->GetCurrentCan(ams_id); - try { - int ams_id_int = atoi(ams_id.c_str()); - int tray_id_int = atoi(tray_id.c_str()); - m_filament_setting_dlg->ams_id = ams_id_int; + int ams_id_int = 0; + int tray_id_int = 0; + if (ams_id.compare(std::to_string(VIRTUAL_TRAY_ID)) == 0) { + tray_id_int = VIRTUAL_TRAY_ID; + m_filament_setting_dlg->ams_id = ams_id_int; m_filament_setting_dlg->tray_id = tray_id_int; + m_filament_setting_dlg->SetPosition(m_ams_control->GetScreenPosition()); + wxString k_val; + wxString n_val; + k_val = wxString::Format("%.2f", obj->vt_tray.k); + n_val = wxString::Format("%.2f", obj->vt_tray.n); + m_filament_setting_dlg->SetPosition(m_ams_control->GetScreenPosition()); + m_filament_setting_dlg->Popup(wxEmptyString, wxEmptyString, wxEmptyString, wxEmptyString, k_val, n_val); + } else { + std::string tray_id = event.GetString().ToStdString(); // m_ams_control->GetCurrentCan(ams_id); + try { + ams_id_int = atoi(ams_id.c_str()); + tray_id_int = atoi(tray_id.c_str()); + m_filament_setting_dlg->ams_id = ams_id_int; + m_filament_setting_dlg->tray_id = tray_id_int; - std::string sn_number; - std::string filament; - std::string temp_max; - std::string temp_min; - auto it = obj->amsList.find(ams_id); - if (it != obj->amsList.end()) { - auto tray_it = it->second->trayList.find(tray_id); - if (tray_it != it->second->trayList.end()) { - wxColor color = AmsTray::decode_color(tray_it->second->color); - m_filament_setting_dlg->set_color(color); - m_filament_setting_dlg->ams_filament_id = tray_it->second->setting_id; - m_filament_setting_dlg->m_is_third = !MachineObject::is_bbl_filament(tray_it->second->tag_uid); - if (!m_filament_setting_dlg->m_is_third) { - sn_number = tray_it->second->uuid; - filament = tray_it->second->sub_brands; - temp_max = tray_it->second->nozzle_temp_max; - temp_min = tray_it->second->nozzle_temp_min; + std::string sn_number; + std::string filament; + std::string temp_max; + std::string temp_min; + wxString k_val; + wxString n_val; + auto it = obj->amsList.find(ams_id); + if (it != obj->amsList.end()) { + auto tray_it = it->second->trayList.find(tray_id); + if (tray_it != it->second->trayList.end()) { + k_val = wxString::Format("%.2f", tray_it->second->k); + n_val = wxString::Format("%.2f", tray_it->second->n); + wxColor color = AmsTray::decode_color(tray_it->second->color); + m_filament_setting_dlg->set_color(color); + m_filament_setting_dlg->ams_filament_id = tray_it->second->setting_id; + m_filament_setting_dlg->m_is_third = !MachineObject::is_bbl_filament(tray_it->second->tag_uid); + if (!m_filament_setting_dlg->m_is_third) { + sn_number = tray_it->second->uuid; + filament = tray_it->second->sub_brands; + temp_max = tray_it->second->nozzle_temp_max; + temp_min = tray_it->second->nozzle_temp_min; + } } } + m_filament_setting_dlg->SetPosition(m_ams_control->GetScreenPosition()); + m_filament_setting_dlg->Popup(filament, sn_number, temp_min, temp_max, k_val, n_val); } + catch (...) { + ; + } + } + } +} + +void StatusPanel::on_ext_spool_edit(wxCommandEvent &event) +{ + // update params + if (!m_filament_setting_dlg) m_filament_setting_dlg = new AMSMaterialsSetting((wxWindow*)this, wxID_ANY); + if (obj) { + m_filament_setting_dlg->obj = obj; + try { + m_filament_setting_dlg->tray_id = VIRTUAL_TRAY_ID; + wxString k_val; + wxString n_val; + k_val = wxString::Format("%.2f", obj->vt_tray.k); + n_val = wxString::Format("%.2f", obj->vt_tray.n); m_filament_setting_dlg->SetPosition(m_ams_control->GetScreenPosition()); - m_filament_setting_dlg->Popup(filament, sn_number, temp_min, temp_max); - } catch (...) { + m_filament_setting_dlg->Popup(wxEmptyString, wxEmptyString, wxEmptyString, wxEmptyString, k_val, n_val); + } + catch (...) { ; } } @@ -2557,6 +2667,10 @@ void StatusPanel::on_ams_refresh_rfid(wxCommandEvent &event) } std::string curr_ams_id = m_ams_control->GetCurentAms(); + // do not support refresh rfid for VIRTUAL_TRAY_ID + if (curr_ams_id.compare(std::to_string(VIRTUAL_TRAY_ID)) == 0) { + return; + } std::string curr_can_id = event.GetString().ToStdString(); std::map::iterator it = obj->amsList.find(curr_ams_id); @@ -2583,27 +2697,31 @@ void StatusPanel::on_ams_selected(wxCommandEvent &event) { if (obj) { std::string curr_ams_id = m_ams_control->GetCurentAms(); - std::string curr_can_id = event.GetString().ToStdString(); - - std::map::iterator it = obj->amsList.find(curr_ams_id); - if (it == obj->amsList.end()) { - BOOST_LOG_TRIVIAL(trace) << "ams: find " << curr_ams_id << " failed"; + if (curr_ams_id.compare(std::to_string(VIRTUAL_TRAY_ID)) == 0) { + update_ams_control_state(curr_ams_id, true); return; + } else { + std::string curr_can_id = event.GetString().ToStdString(); + std::map::iterator it = obj->amsList.find(curr_ams_id); + if (it == obj->amsList.end()) { + BOOST_LOG_TRIVIAL(trace) << "ams: find " << curr_ams_id << " failed"; + return; + } + auto tray_it = it->second->trayList.find(curr_can_id); + if (tray_it == it->second->trayList.end()) { + BOOST_LOG_TRIVIAL(trace) << "ams: find " << curr_can_id << " failed"; + return; + } + try { + int tray_index = atoi(curr_ams_id.c_str()) * 4 + atoi(tray_it->second->id.c_str()); + obj->command_ams_select_tray(std::to_string(tray_index)); + } catch (...) { + ; + } + update_ams_control_state(curr_ams_id, obj->is_function_supported(PrinterFunction::FUNC_EXTRUSION_CALI)); } - auto tray_it = it->second->trayList.find(curr_can_id); - if (tray_it == it->second->trayList.end()) { - BOOST_LOG_TRIVIAL(trace) << "ams: find " << curr_can_id << " failed"; - return; - } - - - try { - int tray_index = atoi(curr_ams_id.c_str()) * 4 + atoi(tray_it->second->id.c_str()); - obj->command_ams_select_tray(std::to_string(tray_index)); - } catch (...) { - ; - } } + } void StatusPanel::on_ams_guide(wxCommandEvent& event) diff --git a/src/slic3r/GUI/StatusPanel.hpp b/src/slic3r/GUI/StatusPanel.hpp index be25269a7..311659530 100644 --- a/src/slic3r/GUI/StatusPanel.hpp +++ b/src/slic3r/GUI/StatusPanel.hpp @@ -19,6 +19,7 @@ #include "Calibration.hpp" #include "PrintOptionsDialog.hpp" #include "AMSMaterialsSetting.hpp" +#include "ExtrusionCalibration.hpp" #include "ReleaseNote.hpp" #include "Widgets/SwitchButton.hpp" #include "Widgets/AxisCtrlButton.hpp" @@ -251,7 +252,7 @@ public: wxBoxSizer *create_ams_group(wxWindow *parent); wxBoxSizer *create_settings_group(wxWindow *parent); - void show_ams_group(bool show = true); + void show_ams_group(bool show = true, bool support_virtual_tray = true); }; @@ -269,12 +270,15 @@ protected: PrintOptionsDialog* print_options_dlg { nullptr }; CalibrationDialog* calibration_dlg {nullptr}; AMSMaterialsSetting *m_filament_setting_dlg{nullptr}; + SecondaryCheckDialog* m_print_error_dlg = nullptr; SecondaryCheckDialog* abort_dlg = nullptr; SecondaryCheckDialog* ctrl_e_hint_dlg = nullptr; SecondaryCheckDialog* sdcard_hint_dlg = nullptr; FanControlPopup* m_fan_control_popup{nullptr}; + ExtrusionCalibration *m_extrusion_cali_dlg{nullptr}; + wxString m_request_url; bool m_start_loading_thumbnail = false; bool m_load_sdcard_thumbnail = false; @@ -335,6 +339,8 @@ protected: void on_ams_unload(SimpleEvent &event); void on_ams_setting_click(SimpleEvent &event); void on_filament_edit(wxCommandEvent &event); + void on_ext_spool_edit(wxCommandEvent &event); + void on_filament_extrusion_cali(wxCommandEvent &event); void on_ams_refresh_rfid(wxCommandEvent &event); void on_ams_selected(wxCommandEvent &event); void on_ams_guide(wxCommandEvent &event); @@ -373,6 +379,7 @@ protected: void update_misc_ctrl(MachineObject *obj); void update_ams(MachineObject* obj); void update_extruder_status(MachineObject* obj); + void update_ams_control_state(std::string ams_id, bool is_support_virtual_tray); void update_cali(MachineObject* obj); void reset_printing_values(); diff --git a/src/slic3r/GUI/Widgets/AMSControl.cpp b/src/slic3r/GUI/Widgets/AMSControl.cpp index 59700a173..545bd9bc0 100644 --- a/src/slic3r/GUI/Widgets/AMSControl.cpp +++ b/src/slic3r/GUI/Widgets/AMSControl.cpp @@ -24,17 +24,20 @@ static wxString FILAMENT_LOAD_STEP_STRING[LOAD_STEP_COUNT] = { static wxString FILAMENT_UNLOAD_STEP_STRING[UNLOAD_STEP_COUNT] = {_L("Heat the nozzle"), _L("Cut filament"), _L("Pull back current filament")}; +wxDEFINE_EVENT(EVT_AMS_EXTRUSION_CALI, wxCommandEvent); wxDEFINE_EVENT(EVT_AMS_LOAD, SimpleEvent); wxDEFINE_EVENT(EVT_AMS_UNLOAD, SimpleEvent); wxDEFINE_EVENT(EVT_AMS_SETTINGS, SimpleEvent); wxDEFINE_EVENT(EVT_AMS_REFRESH_RFID, wxCommandEvent); wxDEFINE_EVENT(EVT_AMS_ON_SELECTED, wxCommandEvent); wxDEFINE_EVENT(EVT_AMS_ON_FILAMENT_EDIT, wxCommandEvent); +wxDEFINE_EVENT(EVT_VAMS_ON_FILAMENT_EDIT, wxCommandEvent); wxDEFINE_EVENT(EVT_AMS_CLIBRATION_AGAIN, wxCommandEvent); wxDEFINE_EVENT(EVT_AMS_CLIBRATION_CANCEL, wxCommandEvent); wxDEFINE_EVENT(EVT_AMS_GUIDE_WIKI, wxCommandEvent); wxDEFINE_EVENT(EVT_AMS_RETRY, wxCommandEvent); wxDEFINE_EVENT(EVT_AMS_SHOW_HUMIDITY_TIPS, wxCommandEvent); +wxDEFINE_EVENT(EVT_AMS_UNSELETED_VAMS, wxCommandEvent); bool AMSinfo::parse_ams_info(Ams *ams, bool remain_flag, bool humidity_flag) { @@ -86,6 +89,10 @@ bool AMSinfo::parse_ams_info(Ams *ams, bool remain_flag, bool humidity_flag) info.material_state = AMSCanType::AMS_CAN_TYPE_THIRDBRAND; wxColour(255, 255, 255); } + + info.k = it->second->k; + info.n = it->second->n; + } else { info.can_id = i; info.material_state = AMSCanType::AMS_CAN_TYPE_EMPTY; @@ -478,14 +485,24 @@ void AMSLib::on_left_down(wxMouseEvent &evt) if (m_info.material_state != AMSCanType::AMS_CAN_TYPE_EMPTY && m_info.material_state != AMSCanType::AMS_CAN_TYPE_NONE) { auto size = GetSize(); auto pos = evt.GetPosition(); - if (m_info.material_state == AMSCanType::AMS_CAN_TYPE_THIRDBRAND || m_info.material_state == AMSCanType::AMS_CAN_TYPE_BRAND) { + if (m_info.material_state == AMSCanType::AMS_CAN_TYPE_THIRDBRAND || m_info.material_state == AMSCanType::AMS_CAN_TYPE_BRAND || + m_info.material_state == AMSCanType::AMS_CAN_TYPE_VIRTUAL) { auto left = FromDIP(20); auto top = (size.y - FromDIP(10) - m_bitmap_editable_light.GetBmpSize().y); auto right = size.x - FromDIP(20); auto bottom = size.y - FromDIP(10); if (pos.x >= left && pos.x <= right && pos.y >= top && top <= bottom) { - post_event(wxCommandEvent(EVT_AMS_ON_FILAMENT_EDIT)); + if (m_selected) { + if (m_info.material_state == AMSCanType::AMS_CAN_TYPE_VIRTUAL) { + post_event(wxCommandEvent(EVT_VAMS_ON_FILAMENT_EDIT)); + } + else { + post_event(wxCommandEvent(EVT_AMS_ON_FILAMENT_EDIT)); + } + } else { + BOOST_LOG_TRIVIAL(trace) << "current amslib is not selected"; + } } } } @@ -540,10 +557,17 @@ void AMSLib::render(wxDC &dc) dc.SetTextForeground(temp_text_colour); auto libsize = GetSize(); - if (m_info.material_state == AMSCanType::AMS_CAN_TYPE_THIRDBRAND || m_info.material_state == AMSCanType::AMS_CAN_TYPE_BRAND) { + if (m_info.material_state == AMSCanType::AMS_CAN_TYPE_THIRDBRAND + || m_info.material_state == AMSCanType::AMS_CAN_TYPE_BRAND + || m_info.material_state == AMSCanType::AMS_CAN_TYPE_VIRTUAL) { if (m_info.material_name.empty()) { auto tsize = dc.GetMultiLineTextExtent("?"); - auto pot = wxPoint((libsize.x - tsize.x) / 2, (libsize.y - tsize.y) / 2 + FromDIP(3)); + auto pot = wxPoint(0, 0); + if (m_show_kn) { + pot = wxPoint((libsize.x - tsize.x) / 2, (libsize.y - tsize.y) / 2 - FromDIP(9)); + } else { + pot = wxPoint((libsize.x - tsize.x) / 2, (libsize.y - tsize.y) / 2 + FromDIP(3)); + } dc.DrawText(L("?"), pot); } else { auto tsize = dc.GetMultiLineTextExtent(m_info.material_name); @@ -564,10 +588,28 @@ void AMSLib::render(wxDC &dc) dc.DrawText(line_bottom, pot_bottom); } else { - auto pot = wxPoint((libsize.x - tsize.x) / 2, (libsize.y - tsize.y) / 2 + FromDIP(3)); + auto pot = wxPoint(0, 0); + if (m_show_kn) { + pot = wxPoint((libsize.x - tsize.x) / 2, (libsize.y - tsize.y) / 2 - FromDIP(9)); + } else { + pot = wxPoint((libsize.x - tsize.x) / 2, (libsize.y - tsize.y) / 2 + FromDIP(3)); + } dc.DrawText(m_info.material_name, pot); } } + + //draw k&n + if (m_show_kn) { + wxString str_k = wxString::Format("k %1.2f", m_info.k); + wxString str_n = wxString::Format("n %1.2f", m_info.n); + dc.SetFont(::Label::Body_11); + auto tsize = dc.GetMultiLineTextExtent(str_k); + auto pot_k = wxPoint((libsize.x - tsize.x) / 2, (libsize.y - tsize.y) / 2 - FromDIP(9) + tsize.y); + dc.DrawText(str_k, pot_k); + + //auto pot_n = wxPoint((libsize.x - tsize.x) / 2, (libsize.y - tsize.y) / 2 - FromDIP(18) + tsize.y * 2); + //dc.DrawText(str_n, pot_n); + } } if (m_info.material_state == AMSCanType::AMS_CAN_TYPE_EMPTY) { @@ -712,7 +754,7 @@ void AMSLib::doRender(wxDC &dc) // edit icon if (m_info.material_state != AMSCanType::AMS_CAN_TYPE_EMPTY && m_info.material_state != AMSCanType::AMS_CAN_TYPE_NONE) { - if (m_info.material_state == AMSCanType::AMS_CAN_TYPE_THIRDBRAND) + if (m_info.material_state == AMSCanType::AMS_CAN_TYPE_THIRDBRAND || m_info.material_state == AMSCanType::AMS_CAN_TYPE_VIRTUAL) dc.DrawBitmap(temp_bitmap_third.bmp(), (size.x - temp_bitmap_third.GetBmpSize().x) / 2, (size.y - FromDIP(10) - temp_bitmap_third.GetBmpSize().y)); if (m_info.material_state == AMSCanType::AMS_CAN_TYPE_BRAND) dc.DrawBitmap(temp_bitmap_brand.bmp(), (size.x - temp_bitmap_brand.GetBmpSize().x) / 2, (size.y - FromDIP(10) - temp_bitmap_brand.GetBmpSize().y)); @@ -774,6 +816,9 @@ AMSRoad::AMSRoad(wxWindow *parent, wxWindowID id, Caninfo info, int canindex, in } else if (m_canindex == (maxcan - 1)) { m_rode_mode = AMSRoadMode::AMS_ROAD_MODE_LEFT; } + else { + m_rode_mode = AMSRoadMode::AMS_ROAD_MODE_NONE_ANY_ROAD; + } ams_humidity_0 = ScalableBitmap(this, "ams_humidity_0", 18); ams_humidity_1 = ScalableBitmap(this, "ams_humidity_1", 18); @@ -1255,6 +1300,9 @@ void AmsCans::AddCan(Caninfo caninfo, int canindex, int maxcan) for (auto i = 0; i < m_can_lib_list.GetCount(); i++) { CanLibs *lib = m_can_lib_list[i]; if (lib->canLib->m_can_index == m_canlib_selection) { + wxCommandEvent evt(EVT_AMS_UNSELETED_VAMS); + evt.SetString(m_info.ams_id); + wxPostEvent(GetParent()->GetParent(), evt); lib->canLib->OnSelected(); } else { lib->canLib->UnSelected(); @@ -1302,6 +1350,9 @@ void AmsCans::SelectCan(std::string canid) for (auto i = 0; i < m_can_lib_list.GetCount(); i++) { CanLibs *lib = m_can_lib_list[i]; if (lib->canLib->m_info.can_id == m_canlib_id) { + wxCommandEvent evt(EVT_AMS_UNSELETED_VAMS); + evt.SetString(m_info.ams_id); + wxPostEvent(GetParent()->GetParent(), evt); lib->canLib->OnSelected(); } else { lib->canLib->UnSelected(); @@ -1415,6 +1466,14 @@ void AmsCans::msw_rescale() } } +void AmsCans::show_sn_value(bool show) +{ + for (auto i = 0; i < m_can_lib_list.GetCount(); i++) { + CanLibs* lib = m_can_lib_list[i]; + lib->canLib->show_kn_value(show); + } +} + //wxColour AmsCans::GetCanColour(wxString canid) //{ // wxColour col = *wxWHITE; @@ -1432,6 +1491,7 @@ Description:AMSControl AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size) : wxSimplebook(parent, wxID_ANY, pos, size) , m_Humidity_tip_popup(AmsHumidityTipPopup(this)) + , m_ams_introduce_popup(AmsIntroducePopup(this)) { SetBackgroundColour(*wxWHITE); // normal mode @@ -1467,6 +1527,27 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons wxBoxSizer *m_sizer_bottom = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer *m_sizer_left = new wxBoxSizer(wxVERTICAL); + m_sizer_ams_tips = new wxBoxSizer(wxHORIZONTAL); + auto m_ams_tip = new wxStaticText(m_amswin, wxID_ANY, _L("AMS")); + m_ams_tip->SetFont(::Label::Body_12); + m_ams_tip->SetForegroundColour(wxColour(0x323A3D)); + auto img_amsmapping_tip = new wxStaticBitmap(m_amswin, wxID_ANY, create_scaled_bitmap("enable_ams", this, 16), wxDefaultPosition, wxSize(FromDIP(16), FromDIP(16)), 0); + m_sizer_ams_tips->Add(m_ams_tip, 0, wxALIGN_CENTER, 0); + m_sizer_ams_tips->Add(img_amsmapping_tip, 0, wxALL, FromDIP(2)); + + img_amsmapping_tip->Bind(wxEVT_ENTER_WINDOW, [this, img_amsmapping_tip](auto& e) { + wxPoint img_pos = img_amsmapping_tip->ClientToScreen(wxPoint(0, 0)); + wxPoint popup_pos(img_pos.x, img_pos.y + img_amsmapping_tip->GetRect().height); + m_ams_introduce_popup.set_mode(true); + m_ams_introduce_popup.Position(popup_pos, wxSize(0, 0)); + m_ams_introduce_popup.Popup(); + }); + + img_amsmapping_tip->Bind(wxEVT_LEAVE_WINDOW, [this](wxMouseEvent& e) { + m_ams_introduce_popup.Dismiss(); + }); + + m_panel_can = new StaticBox(m_amswin, wxID_ANY, wxDefaultPosition, AMS_CANS_SIZE, wxBORDER_NONE); m_panel_can->SetMinSize(AMS_CANS_SIZE); m_panel_can->SetCornerRadius(FromDIP(10)); @@ -1485,11 +1566,25 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons // none ams mode m_none_ams_panel = new wxPanel(m_simplebook_ams, wxID_ANY, wxDefaultPosition, AMS_CANS_WINDOW_SIZE, 0); m_none_ams_panel->SetBackgroundColour(AMS_CONTROL_DEF_BLOCK_BK_COLOUR); - m_none_ams_panel->SetDoubleBuffered(true); + //m_none_ams_panel->SetDoubleBuffered(true); - wxBoxSizer *sizer_ams_panel = new wxBoxSizer(wxHORIZONTAL); - AMSinfo none_ams = AMSinfo{"0", std::vector{Caninfo{"0", wxEmptyString, *wxWHITE, AMSCanType::AMS_CAN_TYPE_EMPTY}}}; - auto amscans = new AmsCans(m_none_ams_panel, wxID_ANY, none_ams); + auto m_tip_none_ams = new wxStaticText(m_none_ams_panel, wxID_ANY, _L("NO AMS"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER_HORIZONTAL); + m_tip_none_ams->SetMinSize(wxSize(AMS_CANS_SIZE.x - FromDIP(20), -1)); + m_tip_none_ams->SetFont(::Label::Head_16); + m_tip_none_ams->SetForegroundColour(AMS_CONTROL_DISABLE_COLOUR); + + wxBoxSizer *sizer_ams_panel_v = new wxBoxSizer(wxVERTICAL); + wxBoxSizer *sizer_ams_panel_h = new wxBoxSizer(wxHORIZONTAL); + + sizer_ams_panel_v->Add(m_tip_none_ams, 0, wxALIGN_CENTER, 0); + sizer_ams_panel_h->Add(sizer_ams_panel_v, 0, wxALIGN_CENTER, 0); + + m_none_ams_panel->SetSizer(sizer_ams_panel_h); + m_none_ams_panel->Layout(); + + /*wxBoxSizer *sizer_ams_panel = new wxBoxSizer(wxHORIZONTAL); + AMSinfo none_ams = AMSinfo{ "0", std::vector{Caninfo{"0", wxEmptyString, *wxWHITE, AMSCanType::AMS_CAN_TYPE_EMPTY}} }; + auto amscans = new AmsCans(m_none_ams_panel, wxID_ANY, none_ams); sizer_ams_panel->Add(amscans, 0, wxALL, 0); sizer_ams_panel->Add(0, 0, 0, wxLEFT, 20); auto m_tip_none_ams = new wxStaticText(m_none_ams_panel, wxID_ANY, _L("Click the pencil icon to edit the filament."), wxDefaultPosition, wxDefaultSize, 0); @@ -1499,7 +1594,7 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons m_tip_none_ams->SetMinSize({150, -1}); sizer_ams_panel->Add(m_tip_none_ams, 0, wxALIGN_CENTER, 0); m_none_ams_panel->SetSizer(sizer_ams_panel); - m_none_ams_panel->Layout(); + m_none_ams_panel->Layout();*/ m_simplebook_ams->AddPage(m_simplebook_cans, wxEmptyString, true); m_simplebook_ams->AddPage(m_none_ams_panel, wxEmptyString, false); @@ -1508,6 +1603,7 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons m_panel_can->Layout(); m_sizer_cans->Fit(m_panel_can); + m_sizer_left->Add(m_sizer_ams_tips, 0, wxALIGN_CENTER, 0); m_sizer_left->Add(m_panel_can, 1, wxEXPAND, 0); wxBoxSizer *m_sizer_left_bottom = new wxBoxSizer(wxHORIZONTAL); @@ -1524,7 +1620,6 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons m_sizer_left_bottom->Add(extruder_pane, 0, wxLEFT, FromDIP(10)); m_sizer_left_bottom->Add(0, 0, 0, wxEXPAND, 0); - m_sizer_left_bottom->Add(0, 0, 0, wxALL | wxLEFT, FromDIP(26)); StateColor btn_bg_green(std::pair(AMS_CONTROL_DISABLE_COLOUR, StateColor::Disabled),std::pair(wxColour(27, 136, 68), StateColor::Pressed), std::pair(wxColour(61, 203, 115), StateColor::Hovered), std::pair(AMS_CONTROL_BRAND_COLOUR, StateColor::Normal)); @@ -1537,24 +1632,118 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons StateColor btn_bd_white(std::pair(AMS_CONTROL_WHITE_COLOUR, StateColor::Disabled), std::pair(wxColour(38, 46, 48), StateColor::Enabled)); StateColor btn_text_green(std::pair(*wxBLACK, StateColor::Disabled), std::pair(AMS_CONTROL_WHITE_COLOUR, StateColor::Enabled)); m_sizer_left_bottom->AddStretchSpacer(); + + m_button_extrusion_cali = new Button(m_amswin, _L("Cali")); + m_button_extrusion_cali->SetToolTip(_L("Calibration of extrusion")); + m_button_extrusion_cali->SetBackgroundColor(btn_bg_green); + m_button_extrusion_cali->SetBorderColor(btn_bd_green); + m_button_extrusion_cali->SetTextColor(btn_text_green); + m_button_extrusion_cali->SetFont(Label::Body_13); + m_button_extruder_feed = new Button(m_amswin, _L("Load Filament")); m_button_extruder_feed->SetBackgroundColor(btn_bg_green); m_button_extruder_feed->SetBorderColor(btn_bd_green); m_button_extruder_feed->SetTextColor(wxColour("#FFFFFE")); m_button_extruder_feed->SetFont(Label::Body_13); - + m_button_extruder_back = new Button(m_amswin, _L("Unload Filament")); m_button_extruder_back->SetBackgroundColor(btn_bg_white); m_button_extruder_back->SetBorderColor(btn_bd_white); m_button_extruder_back->SetFont(Label::Body_13); - m_sizer_left_bottom->Add(m_button_extruder_feed, 0, wxTOP, FromDIP(20)); - m_sizer_left_bottom->Add(0, 0, 0, wxALL | wxLEFT, FromDIP(10)); + m_sizer_left_bottom->Add(m_button_extrusion_cali, 0, wxTOP, FromDIP(20)); + m_sizer_left_bottom->Add(0, 0, 0, wxALL | wxLEFT, FromDIP(5)); m_sizer_left_bottom->Add(m_button_extruder_back, 0, wxTOP, FromDIP(20)); + m_sizer_left_bottom->Add(0, 0, 0, wxALL | wxLEFT, FromDIP(5)); + m_sizer_left_bottom->Add(m_button_extruder_feed, 0, wxTOP, FromDIP(20)); m_sizer_left->Add(m_sizer_left_bottom, 0, wxEXPAND, 0); + + + //virtual ams + m_panel_virtual = new StaticBox(m_amswin, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); + m_panel_virtual->SetBackgroundColor(StateColor(std::pair(AMS_CONTROL_DEF_BLOCK_BK_COLOUR, StateColor::Normal))); + m_panel_virtual->SetMinSize(wxSize(AMS_CAN_LIB_SIZE.x + FromDIP(16), AMS_CANS_SIZE.y)); + m_panel_virtual->SetMaxSize(wxSize(AMS_CAN_LIB_SIZE.x + FromDIP(16), AMS_CANS_SIZE.y)); + + m_vams_info.material_state = AMSCanType::AMS_CAN_TYPE_VIRTUAL; + m_vams_info.can_id = wxString::Format("%d", VIRTUAL_TRAY_ID).ToStdString(); + auto vams_panel = new wxWindow(m_panel_virtual, wxID_ANY); + m_vams_refresh = new AMSrefresh(vams_panel, wxID_ANY, 0, m_vams_info); + m_vams_lib = new AMSLib(vams_panel, wxID_ANY, m_vams_info); + m_vams_road = new AMSRoad(vams_panel, wxID_ANY, m_vams_info, -1, -1, wxDefaultPosition, AMS_CAN_ROAD_SIZE); + + m_vams_lib->Bind(wxEVT_LEFT_DOWN, [this](auto& e) { + //clear all selected + m_current_ams = m_vams_info.can_id; + m_vams_lib->OnSelected(); + + SwitchAms(m_current_ams); + for (auto i = 0; i < m_ams_cans_list.GetCount(); i++) { + AmsCansWindow* cans = m_ams_cans_list[i]; + cans->amsCans->SelectCan(m_current_ams); + } + + e.Skip(); + }); + + Bind(EVT_AMS_UNSELETED_VAMS, [this](wxCommandEvent& e) { + m_current_ams = e.GetString().ToStdString(); + m_vams_lib->UnSelected(); + e.Skip(); + }); + + wxBoxSizer* m_sizer_vams = new wxBoxSizer(wxVERTICAL); + m_sizer_vams->Add(0, 0, 0, wxEXPAND | wxTOP, FromDIP(14)); + m_sizer_vams->Add(m_vams_refresh, 0, wxALIGN_CENTER_HORIZONTAL, 0); + m_sizer_vams->Add(0, 0, 0, wxEXPAND | wxTOP, FromDIP(2)); + m_sizer_vams->Add(m_vams_lib, 1, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, FromDIP(4)); + m_sizer_vams->Add(m_vams_road, 0, wxALL, 0); + + vams_panel->SetSizer(m_sizer_vams); + vams_panel->Layout(); + vams_panel->Fit(); + + wxBoxSizer* m_sizer_vams_panel = new wxBoxSizer(wxVERTICAL); + + m_sizer_vams_panel->Add(vams_panel, 0, wxALIGN_CENTER_HORIZONTAL, 0); + m_panel_virtual->SetSizer(m_sizer_vams_panel); + m_panel_virtual->Layout(); + m_panel_virtual->Fit(); + //virtual ams + + m_vams_sizer = new wxBoxSizer(wxVERTICAL); + + m_sizer_vams_tips = new wxBoxSizer(wxHORIZONTAL); + auto m_vams_tip = new wxStaticText(m_amswin, wxID_ANY, _L("Ext Spool")); + m_vams_tip->SetFont(::Label::Body_12); + m_vams_tip->SetForegroundColour(wxColour(0x323A3D)); + auto img_vams_tip = new wxStaticBitmap(m_amswin, wxID_ANY, create_scaled_bitmap("enable_ams", this, 16), wxDefaultPosition, wxSize(FromDIP(16), FromDIP(16)), 0); + + img_vams_tip->Bind(wxEVT_ENTER_WINDOW, [this, img_vams_tip](auto& e) { + wxPoint img_pos = img_vams_tip->ClientToScreen(wxPoint(0, 0)); + wxPoint popup_pos(img_pos.x, img_pos.y + img_vams_tip->GetRect().height); + m_ams_introduce_popup.set_mode(false); + m_ams_introduce_popup.Position(popup_pos, wxSize(0, 0)); + m_ams_introduce_popup.Popup(); + }); + + img_vams_tip->Bind(wxEVT_LEAVE_WINDOW, [this](wxMouseEvent& e) { + m_ams_introduce_popup.Dismiss(); + }); + + + + m_sizer_vams_tips->Add(m_vams_tip, 0, wxALIGN_CENTER, 0); + m_sizer_vams_tips->Add(img_vams_tip, 0, wxALL, FromDIP(2)); + + m_vams_sizer->Add(m_sizer_vams_tips, 0, wxALIGN_CENTER, 0); + m_vams_sizer->Add(m_panel_virtual, 0, wxALIGN_CENTER, 0); + + m_sizer_bottom->Add(m_vams_sizer, 0, wxEXPAND, 0); + m_sizer_bottom->Add(0, 0, 0, wxEXPAND | wxLEFT, FromDIP(10)); m_sizer_bottom->Add(m_sizer_left, 0, wxEXPAND, 0); - m_sizer_bottom->Add(0, 0, 0, wxEXPAND | wxLEFT, FromDIP(43)); + m_sizer_bottom->Add(0, 0, 0, wxEXPAND | wxLEFT, FromDIP(23)); wxBoxSizer *m_sizer_right = new wxBoxSizer(wxVERTICAL); m_simplebook_right = new wxSimplebook(m_amswin, wxID_ANY); @@ -1623,7 +1812,7 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons m_sizer_body->Add(m_simplebook_amsitems, 0, wxEXPAND, 0); m_sizer_body->Add(0, 0, 1, wxEXPAND | wxTOP, FromDIP(18)); - m_sizer_body->Add(m_sizer_bottom, 0, wxEXPAND | wxLEFT, FromDIP(11)); + m_sizer_body->Add(m_sizer_bottom, 0, wxEXPAND | wxLEFT, FromDIP(6)); init_scaled_buttons(); m_amswin->SetSizer(m_sizer_body); @@ -1706,9 +1895,9 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons UpdateStepCtrl(); + m_button_extrusion_cali->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AMSControl::on_extrusion_cali), NULL, this); m_button_extruder_feed->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AMSControl::on_filament_load), NULL, this); m_button_extruder_back->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AMSControl::on_filament_unload), NULL, this); - m_button_ams_setting->Bind(wxEVT_LEFT_DOWN, &AMSControl::on_ams_setting_click, this); m_button_ams_setting->Bind(wxEVT_ENTER_WINDOW, [this](wxMouseEvent& e) { m_button_ams_setting->SetBitmap(m_button_ams_setting_hover.bmp()); e.Skip(); @@ -1744,6 +1933,8 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons void AMSControl::init_scaled_buttons() { + m_button_extrusion_cali->SetMinSize(wxSize(-1, FromDIP(24))); + m_button_extrusion_cali->SetCornerRadius(FromDIP(12)); m_button_extruder_feed->SetMinSize(wxSize(-1, FromDIP(24))); m_button_extruder_feed->SetCornerRadius(FromDIP(12)); m_button_extruder_back->SetMinSize(wxSize(-1, FromDIP(24))); @@ -1787,26 +1978,56 @@ wxColour AMSControl::GetCanColour(std::string amsid, std::string canid) return col; } -void AMSControl::SetActionState(AMSAction action) +void AMSControl::SetActionState(AMSAction action, bool support_virtual_tray) { + if (action == Slic3r::GUI::AMSAction::AMS_ACTION_NOAMS && !support_virtual_tray) + { + m_button_extrusion_cali->Hide(); + m_button_extruder_feed->Hide(); + m_button_extruder_back->Hide(); + } else { + m_button_extrusion_cali->Show(); + m_button_extruder_feed->Show(); + m_button_extruder_back->Show(); + } + switch (action) { case Slic3r::GUI::AMSAction::AMS_ACTION_NONE: break; + case Slic3r::GUI::AMSAction::AMS_ACTION_VIRTUAL: + m_button_extrusion_cali->Enable(); + m_button_extruder_feed->Disable(); + m_button_extruder_back->Disable(); + break; case Slic3r::GUI::AMSAction::AMS_ACTION_LOAD: + m_button_extrusion_cali->Enable(); m_button_extruder_feed->Enable(); m_button_extruder_back->Disable(); break; case Slic3r::GUI::AMSAction::AMS_ACTION_UNLOAD: + m_button_extrusion_cali->Enable(); m_button_extruder_feed->Disable(); m_button_extruder_back->Enable(); break; case Slic3r::GUI::AMSAction::AMS_ACTION_PRINTING: + m_button_extrusion_cali->Disable(); m_button_extruder_feed->Disable(); m_button_extruder_back->Disable(); break; case Slic3r::GUI::AMSAction::AMS_ACTION_NORMAL: + m_button_extrusion_cali->Enable(); m_button_extruder_feed->Enable(); m_button_extruder_back->Enable(); break; + case Slic3r::GUI::AMSAction::AMS_ACTION_CALI: + m_button_extrusion_cali->Enable(); + m_button_extruder_feed->Disable(); + m_button_extruder_back->Disable(); + break; + case Slic3r::GUI::AMSAction::AMS_ACTION_NOAMS: + m_button_extrusion_cali->Disable(); + m_button_extruder_feed->Disable(); + m_button_extruder_back->Disable(); + break; default: break; } } @@ -1815,7 +2036,10 @@ void AMSControl::EnterNoneAMSMode() { m_simplebook_amsitems->SetSelection(1); m_simplebook_ams->SetSelection(1); - m_button_extruder_feed->Hide(); + m_extruder->Hide(); + m_button_ams_setting->Hide(); + m_button_guide->Hide(); + m_button_retry->Hide(); ShowFilamentTip(false); } @@ -1823,7 +2047,10 @@ void AMSControl::ExitNoneAMSMode() { m_simplebook_ams->SetSelection(0); m_simplebook_amsitems->SetSelection(0); - m_button_extruder_feed->Show(); + m_extruder->Show(); + m_button_ams_setting->Show(); + m_button_guide->Show(); + m_button_retry->Show(); ShowFilamentTip(true); } @@ -1880,8 +2107,9 @@ void AMSControl::msw_rescale() m_button_ams_setting->SetBitmap(m_button_ams_setting_normal.bmp()); m_extruder->msw_rescale(); - m_button_extruder_back->SetMinSize(wxSize(-1, FromDIP(24))); + m_button_extrusion_cali->SetMinSize(wxSize(-1, FromDIP(24))); m_button_extruder_feed->SetMinSize(wxSize(-1, FromDIP(24))); + m_button_extruder_back->SetMinSize(wxSize(-1, FromDIP(24))); m_button_ams_setting->SetMinSize(wxSize(FromDIP(25), FromDIP(24))); m_button_guide->SetMinSize(wxSize(-1, FromDIP(24))); m_button_retry->SetMinSize(wxSize(-1, FromDIP(24))); @@ -1939,13 +2167,46 @@ void AMSControl::Reset() m_current_senect = ""; } +void AMSControl::show_noams_mode(bool show, bool support_virtual_tray) +{ + m_sizer_ams_tips->Show(support_virtual_tray); + show?ExitNoneAMSMode() : EnterNoneAMSMode(); +} -void AMSControl::UpdateAms(std::vector info, bool keep_selection) +void AMSControl::show_vams(bool show) +{ + m_panel_virtual->Show(show); + m_vams_sizer->Show(show); + show_vams_kn_value(show); + Layout(); +} + +void AMSControl::show_vams_kn_value(bool show) +{ + m_vams_lib->show_kn_value(show); +} + +void AMSControl::update_vams_kn_value(AmsTray tray) +{ + m_vams_info.k = tray.k; + m_vams_info.n = tray.n; + m_vams_lib->m_info.k = tray.k; + m_vams_lib->m_info.n = tray.n; + m_vams_lib->Refresh(); +} + +void AMSControl::UpdateAms(std::vector info, bool keep_selection, bool has_extrusion_cali) { std::string curr_ams_id = GetCurentAms(); std::string curr_can_id = GetCurrentCan(curr_ams_id); if (info.size() > 0) ExitNoneAMSMode(); + // update extrusion cali + if (has_extrusion_cali) + m_button_extrusion_cali->Show(); + else + m_button_extrusion_cali->Hide(); + // update item m_ams_info = info; @@ -1979,6 +2240,7 @@ void AMSControl::UpdateAms(std::vector info, bool keep_selection) if (i < info.size()) { cans->amsCans->m_info = m_ams_info[i]; cans->amsCans->Update(m_ams_info[i]); + cans->amsCans->show_sn_value(has_extrusion_cali); } } @@ -2130,8 +2392,9 @@ bool AMSControl::Enable(bool enable) AmsCansWindow *cans = m_ams_cans_list[i]; cans->amsCans->Enable(enable); } - m_button_extruder_back->Enable(enable); + m_button_extrusion_cali->Enable(enable); m_button_extruder_feed->Enable(enable); + m_button_extruder_back->Enable(enable); m_button_ams_setting->Enable(enable); m_filament_load_step->Enable(enable); @@ -2185,7 +2448,7 @@ void AMSControl::SetAmsStep(std::string ams_id, std::string canid, AMSPassRoadTy } if (type == AMSPassRoadType::AMS_ROAD_TYPE_LOAD) { - SetActionState(AMSAction::AMS_ACTION_LOAD); + SetActionState(AMSAction::AMS_ACTION_LOAD); } if (type == AMSPassRoadType::AMS_ROAD_TYPE_UNLOAD) { @@ -2202,6 +2465,14 @@ void AMSControl::on_filament_load(wxCommandEvent &event) post_event(SimpleEvent(EVT_AMS_LOAD)); } +void AMSControl::on_extrusion_cali(wxCommandEvent &event) +{ + for (auto i = 0; i < m_ams_info.size(); i++) { + if (m_ams_info[i].ams_id == m_current_ams) { m_ams_info[i].current_action = AMSAction::AMS_ACTION_CALI; } + } + post_event(SimpleEvent(EVT_AMS_EXTRUSION_CALI)); +} + void AMSControl::on_filament_unload(wxCommandEvent &event) { m_button_extruder_feed->Disable(); @@ -2213,6 +2484,9 @@ void AMSControl::on_filament_unload(wxCommandEvent &event) void AMSControl::on_ams_setting_click(wxMouseEvent &event) { + for (auto i = 0; i < m_ams_info.size(); i++) { + if (m_ams_info[i].ams_id == m_current_ams) { m_ams_info[i].current_action = AMSAction::AMS_ACTION_CALI; } + } post_event(SimpleEvent(EVT_AMS_SETTINGS)); } diff --git a/src/slic3r/GUI/Widgets/AMSControl.hpp b/src/slic3r/GUI/Widgets/AMSControl.hpp index fc10d419d..d5360a7da 100644 --- a/src/slic3r/GUI/Widgets/AMSControl.hpp +++ b/src/slic3r/GUI/Widgets/AMSControl.hpp @@ -41,6 +41,7 @@ enum class AMSRoadMode : int { AMS_ROAD_MODE_END, AMS_ROAD_MODE_END_ONLY, AMS_ROAD_MODE_NONE, + AMS_ROAD_MODE_NONE_ANY_ROAD, }; enum class AMSPassRoadMode : int { @@ -56,8 +57,11 @@ enum class AMSAction : int { AMS_ACTION_NONE, AMS_ACTION_LOAD, AMS_ACTION_UNLOAD, + AMS_ACTION_CALI, AMS_ACTION_PRINTING, AMS_ACTION_NORMAL, + AMS_ACTION_VIRTUAL, + AMS_ACTION_NOAMS, }; enum class AMSPassRoadSTEP : int { @@ -82,6 +86,7 @@ enum class AMSCanType : int { AMS_CAN_TYPE_BRAND, AMS_CAN_TYPE_THIRDBRAND, AMS_CAN_TYPE_EMPTY, + AMS_CAN_TYPE_VIRTUAL, }; enum FilamentStep { @@ -114,6 +119,8 @@ struct Caninfo wxColour material_colour = {*wxWHITE}; AMSCanType material_state; int material_remain = 100; + float k = 0.0f; + float n = 0.0f; }; struct AMSinfo @@ -237,6 +244,7 @@ public: virtual bool Enable(bool enable = true); void post_event(wxCommandEvent &&event); Caninfo m_info; + void show_kn_value(bool show) { m_show_kn = show; }; protected: wxStaticBitmap *m_edit_bitmp = {nullptr}; @@ -249,6 +257,7 @@ protected: bool m_enable = {false}; bool m_selected = {false}; bool m_hover = {false}; + bool m_show_kn = {false}; double m_radius = {4}; wxColour m_border_color; @@ -390,6 +399,7 @@ public: void PlayRridLoading(wxString canid); void StopRridLoading(wxString canid); void msw_rescale(); + void show_sn_value(bool show); std::string GetCurrentCan(); @@ -453,6 +463,8 @@ protected: AMSextruder *m_extruder = {nullptr}; + AmsIntroducePopup m_ams_introduce_popup; + wxSimplebook *m_simplebook_right = {nullptr}; wxSimplebook *m_simplebook_calibration = {nullptr}; wxSimplebook *m_simplebook_amsitems = {nullptr}; @@ -466,11 +478,20 @@ protected: wxWindow * m_none_ams_panel = {nullptr}; wxWindow * m_panel_top = {nullptr}; wxWindow * m_amswin = {nullptr}; + wxBoxSizer* m_vams_sizer = {nullptr}; + wxBoxSizer* m_sizer_vams_tips = {nullptr}; + + Caninfo m_vams_info; + StaticBox* m_panel_virtual = {nullptr}; + AMSrefresh* m_vams_refresh = {nullptr}; + AMSLib* m_vams_lib = {nullptr}; + AMSRoad* m_vams_road = {nullptr}; StaticBox * m_panel_can = {nullptr}; wxBoxSizer *m_sizer_top = {nullptr}; wxBoxSizer *m_sizer_cans = {nullptr}; wxBoxSizer *m_sizer_right_tip = {nullptr}; + wxBoxSizer* m_sizer_ams_tips = {nullptr}; ::StepIndicator *m_filament_load_step = {nullptr}; ::StepIndicator *m_filament_unload_step = {nullptr}; @@ -481,6 +502,7 @@ protected: ScalableBitmap m_button_ams_setting_normal; ScalableBitmap m_button_ams_setting_hover; ScalableBitmap m_button_ams_setting_press; + Button *m_button_extrusion_cali= {nullptr}; Button *m_button_guide = {nullptr}; Button *m_button_retry = {nullptr}; @@ -491,7 +513,7 @@ public: std::string GetCurrentCan(std::string amsid); wxColour GetCanColour(std::string amsid, std::string canid); - void SetActionState(AMSAction action); + void SetActionState(AMSAction action, bool support_virtual_tray = true); void EnterNoneAMSMode(); void ExitNoneAMSMode(); @@ -510,7 +532,7 @@ public: void SetHumidity(std::string amsid, int humidity); void UpdateStepCtrl(); void CreateAms(); - void UpdateAms(std::vector info, bool keep_selection = true); + void UpdateAms(std::vector info, bool keep_selection = true, bool has_extrusion_cali = true); void AddAms(AMSinfo info, bool refresh = true); void SetAmsStep(std::string ams_id, std::string canid, AMSPassRoadType type, AMSPassRoadSTEP step); void SwitchAms(std::string ams_id); @@ -519,10 +541,17 @@ public: void on_filament_load(wxCommandEvent &event); void on_filament_unload(wxCommandEvent &event); void on_ams_setting_click(wxMouseEvent &event); + void on_extrusion_cali(wxCommandEvent &event); + void on_ams_setting_click(wxCommandEvent &event); void on_clibration_again_click(wxMouseEvent &event); void on_clibration_cancel_click(wxMouseEvent &event); void Reset(); + void show_noams_mode(bool show, bool support_virtual_tray); + void show_vams(bool show); + void show_vams_kn_value(bool show); + void update_vams_kn_value(AmsTray tray); + void post_event(wxEvent &&event); virtual bool Enable(bool enable = true); @@ -531,17 +560,20 @@ public: std::string m_current_senect; }; +wxDECLARE_EVENT(EVT_AMS_EXTRUSION_CALI, wxCommandEvent); wxDECLARE_EVENT(EVT_AMS_LOAD, SimpleEvent); wxDECLARE_EVENT(EVT_AMS_UNLOAD, SimpleEvent); wxDECLARE_EVENT(EVT_AMS_SETTINGS, SimpleEvent); wxDECLARE_EVENT(EVT_AMS_REFRESH_RFID, wxCommandEvent); wxDECLARE_EVENT(EVT_AMS_ON_SELECTED, wxCommandEvent); wxDECLARE_EVENT(EVT_AMS_ON_FILAMENT_EDIT, wxCommandEvent); +wxDECLARE_EVENT(EVT_VAMS_ON_FILAMENT_EDIT, wxCommandEvent); wxDECLARE_EVENT(EVT_AMS_CLIBRATION_AGAIN, wxCommandEvent); wxDECLARE_EVENT(EVT_AMS_CLIBRATION_CANCEL, wxCommandEvent); wxDECLARE_EVENT(EVT_AMS_GUIDE_WIKI, wxCommandEvent); wxDECLARE_EVENT(EVT_AMS_RETRY, wxCommandEvent); wxDECLARE_EVENT(EVT_AMS_SHOW_HUMIDITY_TIPS, wxCommandEvent); +wxDECLARE_EVENT(EVT_AMS_UNSELETED_VAMS, wxCommandEvent); }} // namespace Slic3r::GUI