From 9c28c320d680d69b16d4895fda1bdcab9ad5b18d Mon Sep 17 00:00:00 2001 From: "xun.zhang" Date: Tue, 25 Feb 2025 15:26:10 +0800 Subject: [PATCH] ENH: new wiping dialog 1.Enhance performance and ui display jira: None Signed-off-by: xun.zhang Change-Id: If1cde4d1a17437ee5485dd51adff4c3444774ffd --- resources/web/flush/WipingDialog.html | 645 +++++++++++++++++ src/slic3r/GUI/FilamentGroupPopup.cpp | 4 +- src/slic3r/GUI/Plater.cpp | 19 +- src/slic3r/GUI/WipeTowerDialog.cpp | 966 ++++++-------------------- src/slic3r/GUI/WipeTowerDialog.hpp | 124 +--- 5 files changed, 881 insertions(+), 877 deletions(-) create mode 100644 resources/web/flush/WipingDialog.html diff --git a/resources/web/flush/WipingDialog.html b/resources/web/flush/WipingDialog.html new file mode 100644 index 000000000..ce4b2da4e --- /dev/null +++ b/resources/web/flush/WipingDialog.html @@ -0,0 +1,645 @@ + + + + + + + + +
+
+ Studio would re-calculate your flushing volumes every time the filament + color changed or filaments changed. You could disable the auto-calculate + in Bambu Studio > Preferences. +
+ +
+ + +
+ +
+ + + + + + + +
+
+ +
+
+ Flushing volume (mm³) for each filament pair. +
+
+ Suggestion: Flushing Volume in range [50, 999] +
+
+ + +
+
+ The multiplier should be in range [0.50, 3.00]. +
+
+
+ + +
+
+ + + + diff --git a/src/slic3r/GUI/FilamentGroupPopup.cpp b/src/slic3r/GUI/FilamentGroupPopup.cpp index ac3d72895..43a11365c 100644 --- a/src/slic3r/GUI/FilamentGroupPopup.cpp +++ b/src/slic3r/GUI/FilamentGroupPopup.cpp @@ -73,9 +73,9 @@ bool open_filament_group_wiki() bool is_zh = wxGetApp().app_config->get("language") == "zh_CN"; fs::path wiki_path; if (is_zh) - wiki_path = fs::path(resources_dir()) / "/wiki/filament_group_wiki_zh.html"; + wiki_path = fs::path(resources_dir()) / "wiki/filament_group_wiki_zh.html"; else - wiki_path = fs::path(resources_dir()) / "/wiki/filament_group_wiki_en.html"; + wiki_path = fs::path(resources_dir()) / "wiki/filament_group_wiki_en.html"; wxString wiki_path_str = wxString::FromUTF8(wiki_path.string()); if (wxFileExists(wiki_path_str)) { diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 570080107..6c05bc959 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1787,22 +1787,13 @@ Sidebar::Sidebar(Plater *parent) extra_flush_volumes[nozzle_id] = get_min_flush_volumes(full_config, nozzle_id); } - std::vector flush_multiplier; - ConfigOptionFloats *flush_multi_opt = project_config.option("flush_multiplier"); - if (flush_multi_opt) - flush_multiplier = cast(flush_multi_opt->values); - - flush_multiplier.resize(nozzle_nums, 1.0f); - - WipingDialog dlg(parent, cast(init_matrix), cast(init_extruders), extruder_colours, extra_flush_volumes, flush_multiplier, nozzle_nums); - if (dlg.ShowModal() == wxID_OK) { - std::vector matrix = dlg.get_matrix(); - std::vector extruders = dlg.get_extruders(); - std::vector flush_multipliers = dlg.get_flush_multiplier_vector(); + WipingDialog dlg(static_cast(wxGetApp().mainframe),extra_flush_volumes); + dlg.ShowModal(); + if (dlg.GetSubmitFlag()) { + auto matrix = dlg.GetFlattenMatrix(); + auto flush_multipliers = dlg.GetMultipliers(); (project_config.option("flush_volumes_matrix"))->values = std::vector(matrix.begin(), matrix.end()); - (project_config.option("flush_volumes_vector"))->values = std::vector(extruders.begin(), extruders.end()); (project_config.option("flush_multiplier"))->values = std::vector(flush_multipliers.begin(), flush_multipliers.end()); - wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config); wxGetApp().plater()->update_project_dirty_from_presets(); diff --git a/src/slic3r/GUI/WipeTowerDialog.cpp b/src/slic3r/GUI/WipeTowerDialog.cpp index ac4b9c0d1..53507c8e7 100644 --- a/src/slic3r/GUI/WipeTowerDialog.cpp +++ b/src/slic3r/GUI/WipeTowerDialog.cpp @@ -1,667 +1,224 @@ #include -#include +#include #include "libslic3r/FlushVolCalc.hpp" #include "WipeTowerDialog.hpp" -#include "BitmapCache.hpp" #include "GUI.hpp" #include "I18N.hpp" #include "GUI_App.hpp" -#include "MsgDialog.hpp" -#include "Widgets/Button.hpp" -#include "slic3r/Utils/ColorSpaceConvert.hpp" -#include "MainFrame.hpp" #include "libslic3r/Config.hpp" -#include using namespace Slic3r; using namespace Slic3r::GUI; -int scale(const int val) { return val * Slic3r::GUI::wxGetApp().em_unit() / 10; } -int ITEM_WIDTH() { return scale(30); } -static const wxColour g_text_color = wxColour(107, 107, 107, 255); - -#define WIPE_TOWER_ICON_SIZE wxSize(FromDIP(16), FromDIP(16)) -#define TABLE_BORDER FromDIP(28) -#define HEADER_VERT_PADDING FromDIP(12) -#define HEADER_BEG_PADDING FromDIP(30) -#define ICON_GAP FromDIP(44) -#define HEADER_END_PADDING FromDIP(24) -#define ROW_VERT_PADDING FromDIP(6) -#define ROW_BEG_PADDING FromDIP(20) -#define EDIT_BOXES_GAP FromDIP(30) -#define ROW_END_PADDING FromDIP(21) -#define BTN_SIZE wxSize(FromDIP(58), FromDIP(24)) -#define BTN_GAP FromDIP(20) -#define TEXT_BEG_PADDING FromDIP(30) -#define MAX_FLUSH_VALUE 999 -#define MIN_WIPING_DIALOG_WIDTH FromDIP(300) -#define TIP_MESSAGES_PADDING FromDIP(8) - - -static void update_ui(wxWindow* window) -{ - Slic3r::GUI::wxGetApp().UpdateDarkUI(window); -} - -#ifdef _WIN32 -#define style wxSP_ARROW_KEYS | wxBORDER_SIMPLE -#else -#define style wxSP_ARROW_KEYS -#endif - static const float g_min_flush_multiplier = 0.f; static const float g_max_flush_multiplier = 3.f; -wxBoxSizer* WipingDialog::create_btn_sizer(long flags) -{ - auto btn_sizer = new wxBoxSizer(wxHORIZONTAL); - btn_sizer->AddStretchSpacer(); - - StateColor ok_btn_bg( - std::pair(wxColour(27, 136, 68), StateColor::Pressed), - std::pair(wxColour(61, 203, 115), StateColor::Hovered), - std::pair(wxColour(0, 174, 66), StateColor::Normal) - ); - - StateColor ok_btn_bd( - std::pair(wxColour(0, 174, 66), StateColor::Normal) - ); - - StateColor ok_btn_text( - std::pair(wxColour(255, 255, 254), StateColor::Normal) - ); - - StateColor cancel_btn_bg( - std::pair(wxColour(206, 206, 206), StateColor::Pressed), - std::pair(wxColour(238, 238, 238), StateColor::Hovered), - std::pair(wxColour(255, 255, 255), StateColor::Normal) - ); - - StateColor cancel_btn_bd_( - std::pair(wxColour(38, 46, 48), StateColor::Normal) - ); - - StateColor cancel_btn_text( - std::pair(wxColour(38, 46, 48), StateColor::Normal) - ); - - - StateColor calc_btn_bg( - std::pair(wxColour(27, 136, 68), StateColor::Pressed), - std::pair(wxColour(61, 203, 115), StateColor::Hovered), - std::pair(wxColour(0, 174, 66), StateColor::Normal) - ); - - StateColor calc_btn_bd( - std::pair(wxColour(0, 174, 66), StateColor::Normal) - ); - - StateColor calc_btn_text( - std::pair(wxColour(255, 255, 254), StateColor::Normal) - ); - - if (flags & wxRESET) { - Button *calc_btn = new Button(this, _L("Auto-Calc")); - calc_btn->SetMinSize(wxSize(FromDIP(75), FromDIP(24))); - calc_btn->SetCornerRadius(FromDIP(12)); - calc_btn->SetBackgroundColor(calc_btn_bg); - calc_btn->SetBorderColor(calc_btn_bd); - calc_btn->SetTextColor(calc_btn_text); - calc_btn->SetFocus(); - calc_btn->SetId(wxID_RESET); - btn_sizer->Add(calc_btn, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, BTN_GAP); - m_button_list[wxRESET] = calc_btn; +static std::vector MatrixFlatten(const WipingDialog::VolumeMatrix& matrix) { + std::vector vec; + for (auto row_elems : matrix) { + for (auto elem : row_elems) + vec.emplace_back(elem); } - if (flags & wxOK) { - Button* ok_btn = new Button(this, _L("OK")); - ok_btn->SetMinSize(BTN_SIZE); - ok_btn->SetCornerRadius(FromDIP(12)); - ok_btn->SetBackgroundColor(ok_btn_bg); - ok_btn->SetBorderColor(ok_btn_bd); - ok_btn->SetTextColor(ok_btn_text); - ok_btn->SetFocus(); - ok_btn->SetId(wxID_OK); - btn_sizer->Add(ok_btn, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, BTN_GAP); - m_button_list[wxOK] = ok_btn; - } - if (flags & wxCANCEL) { - Button* cancel_btn = new Button(this, _L("Cancel")); - cancel_btn->SetMinSize(BTN_SIZE); - cancel_btn->SetCornerRadius(FromDIP(12)); - cancel_btn->SetBackgroundColor(cancel_btn_bg); - cancel_btn->SetBorderColor(cancel_btn_bd_); - cancel_btn->SetTextColor(cancel_btn_text); - cancel_btn->SetId(wxID_CANCEL); - btn_sizer->Add(cancel_btn, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, BTN_GAP); - m_button_list[wxCANCEL] = cancel_btn; - } - - return btn_sizer; - + return vec; } -wxBoxSizer* WipingPanel::create_calc_btn_sizer(wxWindow* parent) { - auto btn_sizer = new wxBoxSizer(wxHORIZONTAL); - StateColor calc_btn_bg( - std::pair(wxColour(27, 136, 68), StateColor::Pressed), - std::pair(wxColour(61, 203, 115), StateColor::Hovered), - std::pair(wxColour(0, 174, 66), StateColor::Normal) - ); - - StateColor calc_btn_bd( - std::pair(wxColour(0, 174, 66), StateColor::Normal) - ); - - StateColor calc_btn_text( - std::pair(wxColour(255, 255, 254), StateColor::Normal) - ); - - Button* calc_btn = new Button(parent, _L("Re-calculate")); - calc_btn->SetFont(Label::Body_13); - calc_btn->SetMinSize(wxSize(FromDIP(75), FromDIP(24))); - calc_btn->SetCornerRadius(FromDIP(12)); - calc_btn->SetBackgroundColor(calc_btn_bg); - calc_btn->SetBorderColor(calc_btn_bd); - calc_btn->SetTextColor(calc_btn_text); - calc_btn->SetFocus(); - btn_sizer->Add(calc_btn, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, BTN_GAP); - calc_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { calc_flushing_volumes(); }); - - if (m_nozzle_nums == 2) { - ComboBox *extruder_combo = new ComboBox(parent, wxID_ANY, "", wxDefaultPosition, wxSize(FromDIP(130), FromDIP(24)), 0, nullptr, wxCB_READONLY); - extruder_combo->AppendString(_L("Left extruder")); - extruder_combo->AppendString(_L("Right extruder")); - extruder_combo->SetSelection(0); - extruder_combo->Bind(wxEVT_COMBOBOX, &WipingPanel::on_select_extruder, this); - btn_sizer->Add(extruder_combo); - } - - return btn_sizer; -} -void WipingDialog::on_dpi_changed(const wxRect &suggested_rect) +wxString WipingDialog::BuildTableObjStr() { - for (auto button_item : m_button_list) - { - if (button_item.first == wxRESET) - { - button_item.second->SetMinSize(wxSize(FromDIP(75), FromDIP(24))); - button_item.second->SetCornerRadius(FromDIP(12)); - } - if (button_item.first == wxOK) { - button_item.second->SetMinSize(BTN_SIZE); - button_item.second->SetCornerRadius(FromDIP(12)); - } - if (button_item.first == wxCANCEL) { - button_item.second->SetMinSize(BTN_SIZE); - button_item.second->SetCornerRadius(FromDIP(12)); - } + auto full_config = wxGetApp().preset_bundle->full_config(); + auto filament_colors = full_config.option("filament_colour")->values; + auto flush_multiplier = full_config.option("flush_multiplier")->values; + int nozzle_num = full_config.option("nozzle_diameter")->values.size(); + auto raw_matrix_data = full_config.option("flush_volumes_matrix")->values; + std::vector> flush_matrixs; + for (int idx = 0; idx < nozzle_num; ++idx) { + flush_matrixs.emplace_back(get_flush_volumes_matrix(raw_matrix_data, idx, nozzle_num)); } - m_panel_wiping->msw_rescale(); - this->Refresh(); -}; + flush_multiplier.resize(nozzle_num, 1); -// Parent dialog for purging volume adjustments - it fathers WipingPanel widget (that contains all controls) and a button to toggle simple/advanced mode: -WipingDialog::WipingDialog(wxWindow* parent, const std::vector& matrix, const std::vector& extruders, const std::vector& extruder_colours, - const std::vector>&extra_flush_volume, const std::vector& flush_multiplier, size_t nozzle_nums) - : DPIDialog(parent ? parent : static_cast(wxGetApp().mainframe), - wxID_ANY, - _(L("Flushing volumes for filament change")), - wxDefaultPosition, - wxDefaultSize, - wxDEFAULT_DIALOG_STYLE /* | wxRESIZE_BORDER*/) + m_raw_matrixs = flush_matrixs; + m_flush_multipliers = flush_multiplier; + + json obj; + obj["flush_multiplier"] = flush_multiplier; + obj["extruder_num"] = nozzle_num; + obj["filament_colors"] = filament_colors; + obj["flush_volume_matrixs"] = json::array(); + obj["min_flush_volumes"] = json::array(); + obj["max_flush_volumes"] = json::array(); + obj["min_flush_multiplier"] = g_min_flush_multiplier; + obj["max_flush_multiplier"] = g_max_flush_multiplier; + obj["is_dark_mode"] = wxGetApp().dark_mode(); + + for (const auto& vec : flush_matrixs) { + obj["flush_volume_matrixs"].push_back(vec); + } + + for (int idx = 0; idx < nozzle_num; ++idx) { + obj["min_flush_volumes"].push_back(*min_element(m_extra_flush_volume[idx].begin(), m_extra_flush_volume[idx].end())); + obj["max_flush_volumes"].push_back(m_max_flush_volume); + } + + auto obj_str = obj.dump(); + return obj_str; +} + +wxString WipingDialog::BuildTextObjStr() +{ + wxString auto_flush_tip = _L("Studio would re-calculate your flushing volumes everytime the filaments color changed or filaments changed. You could disable the auto-calculate in Bambu Studio > Preferences"); + wxString volume_desp_panel = _L("Flushing volume (mm³) for each filament pair."); + wxString volume_range_panel = wxString::Format(_L("Suggestion: Flushing Volume in range [%d, %d]"), 0, 700); + wxString multiplier_range_panel = wxString::Format(_L("The multiplier should be in range [%.2f, %.2f]."), 0, 3); + wxString calc_btn_panel = _L("Re-calculate"); + wxString extruder_label_0 = _L("Left extruder"); + wxString extruder_label_1 = _L("Right extruder"); + wxString multiplier_label = _L("Multiplier"); + wxString ok_btn_label = _L("OK"); + wxString cancel_btn_label = _L("Cancel"); + + wxString text_obj = "{"; + text_obj += wxString::Format("\"volume_desp_panel\":\"%s\",", volume_desp_panel); + text_obj += wxString::Format("\"volume_range_panel\":\"%s\",", volume_range_panel); + text_obj += wxString::Format("\"multiplier_range_panel\":\"%s\",", multiplier_range_panel); + text_obj += wxString::Format("\"calc_btn_panel\":\"%s\",", calc_btn_panel); + text_obj += wxString::Format("\"extruder_label_0\":\"%s\",", extruder_label_0); + text_obj += wxString::Format("\"extruder_label_1\":\"%s\",", extruder_label_1); + text_obj += wxString::Format("\"multiplier_label\":\"%s\",", multiplier_label); + text_obj += wxString::Format("\"ok_btn_label\":\"%s\",", ok_btn_label); + text_obj += wxString::Format("\"cancel_btn_label\":\"%s\",", cancel_btn_label); + text_obj += wxString::Format("\"auto_flush_tip\":\"%s\"", auto_flush_tip); + text_obj += "}"; + return text_obj; +} + +WipingDialog::WipingDialog(wxWindow* parent, const std::vector>& extra_flush_volume,const int max_flush_volume) : + wxDialog(parent, wxID_ANY, _(L("Flushing volumes for filament change")), + wxDefaultPosition, wxDefaultSize, + wxDEFAULT_DIALOG_STYLE ), + m_extra_flush_volume(extra_flush_volume), + m_max_flush_volume(max_flush_volume) { std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % Slic3r::resources_dir()).str(); SetIcon(wxIcon(Slic3r::encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO)); + wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); + this->SetSizer(main_sizer); - auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1)); - m_line_top->SetBackgroundColour(wxColour(166, 169, 170)); + auto filament_count= wxGetApp().preset_bundle->project_config.option("filament_colour")->values.size(); + wxSize extra_size = { FromDIP(100),FromDIP(235) }; + if (filament_count <= 2) + extra_size.y += FromDIP(16) * 3 + FromDIP(32); + else if (filament_count == 3) + extra_size.y += FromDIP(16) * 3; + else if (4 <= filament_count && filament_count <= 8) + extra_size.y += FromDIP(16) * 2; + else + extra_size.y += FromDIP(16); - this->SetBackgroundColour(*wxWHITE); - this->SetMinSize(wxSize(MIN_WIPING_DIALOG_WIDTH, -1)); + wxSize max_scroll_size = { FromDIP(1000),FromDIP(500) }; + wxSize estimate_size = { (int)(filament_count + 1) * FromDIP(60),(int)(filament_count + 1) * FromDIP(30)+FromDIP(2)}; + wxSize scroll_size ={ std::min(max_scroll_size.x,estimate_size.x),std::min(max_scroll_size.y,estimate_size.y) }; + wxSize appied_size = scroll_size + extra_size; + m_webview = wxWebView::New(this, wxID_ANY, + wxEmptyString, + wxDefaultPosition, + appied_size, + wxWebViewBackendDefault, + wxNO_BORDER); - m_panel_wiping = new WipingPanel(this, matrix, extruders, 0, extruder_colours, nullptr, extra_flush_volume, flush_multiplier, nozzle_nums); + m_webview->AddScriptMessageHandler("wipingDialog"); + main_sizer->Add(m_webview, 1); - auto main_sizer = new wxBoxSizer(wxVERTICAL); - main_sizer->Add(m_line_top, 0, wxEXPAND, 0); + fs::path filepath = fs::path(resources_dir()) / "web/flush/WipingDialog.html"; + wxString filepath_str = wxString::FromUTF8(filepath.string()); + wxFileName fn(filepath_str); + if(fn.FileExists()) { + wxString url = "file:///" + fn.GetFullPath(); + m_webview->LoadURL(url); + } else { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< "WipingDialog.html not exist"; + } - // set min sizer width according to extruders count - auto sizer_width = (int)((sqrt(matrix.size()) + 2.8)*ITEM_WIDTH()); - sizer_width = sizer_width > MIN_WIPING_DIALOG_WIDTH ? sizer_width : MIN_WIPING_DIALOG_WIDTH; - main_sizer->SetMinSize(wxSize(sizer_width, -1)); - main_sizer->Add(m_panel_wiping, 1, wxEXPAND | wxALL, 0); - - auto btn_sizer = create_btn_sizer(wxOK | wxCANCEL); - main_sizer->Add(btn_sizer, 0, wxBOTTOM | wxRIGHT | wxEXPAND, BTN_GAP); - SetSizer(main_sizer); main_sizer->SetSizeHints(this); - - if (this->FindWindowById(wxID_OK, this)) { - this->FindWindowById(wxID_OK, this)->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { // if OK button is clicked.. - m_output_matrix = m_panel_wiping->read_matrix_values(); // ..query wiping panel and save returned values - m_output_extruders = m_panel_wiping->read_extruders_values(); // so they can be recovered later by calling get_...() - EndModal(wxID_OK); - }, wxID_OK); - } - if (this->FindWindowById(wxID_CANCEL, this)) { - update_ui(static_cast(this->FindWindowById(wxID_CANCEL, this))); - this->FindWindowById(wxID_CANCEL, this)->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { EndModal(wxCANCEL); }); - - } - - /* - if (this->FindWindowById(wxID_RESET, this)) { - this->FindWindowById(wxID_RESET, this)->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { m_panel_wiping->calc_flushing_volumes(); }); - } - */ - - this->Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent& e) { EndModal(wxCANCEL); }); - this->Bind(wxEVT_CHAR_HOOK, [this](wxKeyEvent& e) { - if (e.GetKeyCode() == WXK_ESCAPE) { - if (this->IsModal()) - this->EndModal(wxID_CANCEL); - else - this->Close(); - } - else - e.Skip(); - }); - + main_sizer->Fit(this); CenterOnParent(); - wxGetApp().UpdateDlgDarkUI(this); -} -void WipingPanel::create_panels(wxWindow* parent, const int num) { - for (size_t i = 0; i < num; i++) - { - wxPanel* panel = new wxPanel(parent); - panel->SetBackgroundColour(i % 2 == 0 ? *wxWHITE : wxColour(238, 238, 238)); - auto sizer = new wxBoxSizer(wxHORIZONTAL); - panel->SetSizer(sizer); + //m_webview->Bind(wxEVT_WEBVIEW_NAVIGATED, [this](auto& evt) { + // auto table_obj_str = BuildTableObjStr(); + // auto text_obj_str = BuildTextObjStr(); + // CallAfter([table_obj_str, text_obj_str, this] { + // wxString script = wxString::Format("buildTable(%s);buildText(%s)", table_obj_str, text_obj_str); + // m_webview->RunScript(script); + // }); + // }); - wxButton* icon = new wxButton(panel, wxID_ANY, {}, wxDefaultPosition, WIPE_TOWER_ICON_SIZE, wxBORDER_NONE | wxBU_AUTODRAW); - icon->SetBitmap(*get_extruder_color_icon(m_colours[i].GetAsString(wxC2S_HTML_SYNTAX).ToStdString(), std::to_string(i + 1), FromDIP(16), FromDIP(16))); - icon->SetCanFocus(false); - icon_list2.push_back(icon); - - sizer->AddSpacer(ROW_BEG_PADDING); - sizer->Add(icon, 0, wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM, ROW_VERT_PADDING); - - for (unsigned int j = 0; j < (unsigned int)num; ++j) { - edit_boxes[j][i]->Reparent(panel); - edit_boxes[j][i]->SetBackgroundColour(panel->GetBackgroundColour()); - edit_boxes[j][i]->SetFont(::Label::Body_13); - sizer->AddSpacer(EDIT_BOXES_GAP); - sizer->Add(edit_boxes[j][i], 0, wxALIGN_CENTER_VERTICAL, 0); - } - sizer->AddSpacer(ROW_END_PADDING); - - m_sizer_advanced->Add(panel, 0, wxRIGHT | wxLEFT | wxEXPAND, TABLE_BORDER); - panel->Layout(); - } -} - -// This panel contains all control widgets for both simple and advanced mode (these reside in separate sizers) -WipingPanel::WipingPanel(wxWindow* parent, const std::vector& matrix, const std::vector& extruders, - size_t cur_extruder_id, - const std::vector& extruder_colours, Button* calc_button, - const std::vector>& extra_flush_volume, const std::vector& flush_multiplier, size_t nozzle_nums) - : wxPanel(parent,wxID_ANY, wxDefaultPosition, wxDefaultSize/*,wxBORDER_RAISED*/) - , m_flush_multiplier(flush_multiplier) - , m_matrix(matrix) - , m_cur_extruder_id(cur_extruder_id) - , m_min_flush_volume(extra_flush_volume) - , m_max_flush_volume(Slic3r::g_max_flush_volume) - , m_nozzle_nums(nozzle_nums) -{ - m_number_of_extruders = (unsigned int)extruder_colours.size(); - - generate_display_matrix(); - - for (const std::string& color : extruder_colours) { - //unsigned char rgb[3]; - //Slic3r::GUI::BitmapCache::parse_color(color, rgb); - m_colours.push_back(wxColor(color)); - } - auto sizer_width = (int)((sqrt(m_display_matrix.size())) * ITEM_WIDTH() + (sqrt(m_display_matrix.size()) + 1) * HEADER_BEG_PADDING); - sizer_width = sizer_width > MIN_WIPING_DIALOG_WIDTH ? sizer_width : MIN_WIPING_DIALOG_WIDTH; - // Create two switched panels with their own sizers - m_sizer_simple = new wxBoxSizer(wxVERTICAL); - m_sizer_advanced = new wxBoxSizer(wxVERTICAL); - m_page_simple = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); - m_page_advanced = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); - m_page_simple->SetSizer(m_sizer_simple); - m_page_advanced->SetSizer(m_sizer_advanced); - m_page_advanced->SetBackgroundColour(*wxWHITE); - - update_ui(m_page_simple); - update_ui(m_page_advanced); - - auto gridsizer_simple = new wxGridSizer(3, 5, 10); - m_gridsizer_advanced = new wxGridSizer(m_number_of_extruders + 1, 5, 1); - - // First create controls for advanced mode and assign them to m_page_advanced: - for (unsigned int i = 0; i < m_number_of_extruders; ++i) { - edit_boxes.push_back(std::vector(0)); - - for (unsigned int j = 0; j < m_number_of_extruders; ++j) { -#ifdef _WIN32 - wxTextCtrl* text = new wxTextCtrl(m_page_advanced, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(ITEM_WIDTH(), -1), wxTE_CENTER | wxBORDER_NONE | wxTE_PROCESS_ENTER); - update_ui(text); - edit_boxes.back().push_back(text); -#else - edit_boxes.back().push_back(new wxTextCtrl(m_page_advanced, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(ITEM_WIDTH(), -1))); -#endif - if (i == j) { - edit_boxes[i][j]->SetValue(wxString("0")); - edit_boxes[i][j]->SetEditable(false); - edit_boxes[i][j]->Bind(wxEVT_KILL_FOCUS, [this](wxFocusEvent&) {}); - edit_boxes[i][j]->Bind(wxEVT_SET_FOCUS, [this](wxFocusEvent&) {}); - } - else { - edit_boxes[i][j]->SetValue(wxString("") << int(m_display_matrix[m_number_of_extruders * j + i] * m_flush_multiplier[m_cur_extruder_id])); - - edit_boxes[i][j]->Bind(wxEVT_TEXT, [this, i, j](wxCommandEvent& e) { - wxString str = edit_boxes[i][j]->GetValue(); - int value = wxAtoi(str); - if (value > MAX_FLUSH_VALUE) { - str = wxString::Format(("%d"), MAX_FLUSH_VALUE); - edit_boxes[i][j]->SetValue(str); - } - else if (value < 0) { - edit_boxes[i][j]->SetValue(wxString("0")); - } + m_webview->Bind(wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, [this](wxWebViewEvent& evt) { + std::string message = evt.GetString().ToStdString(); + try { + json j = json::parse(message); + if (j["msg"].get() == "init") { + auto table_obj_str = BuildTableObjStr(); + auto text_obj_str = BuildTextObjStr(); + CallAfter([table_obj_str, text_obj_str, this] { + wxString script = wxString::Format("buildTable(%s);buildText(%s)", table_obj_str, text_obj_str); + m_webview->RunScript(script); }); - - auto on_apply_text_modify = [this, i, j](wxEvent &e) { - wxString str = edit_boxes[i][j]->GetValue(); - int value = wxAtoi(str); - m_display_matrix[m_number_of_extruders * j + i] = value / get_flush_multiplier(); - this->update_warning_texts(); - e.Skip(); - }; - - edit_boxes[i][j]->Bind(wxEVT_TEXT_ENTER, on_apply_text_modify); - edit_boxes[i][j]->Bind(wxEVT_KILL_FOCUS, on_apply_text_modify); + } + else if (j["msg"].get() == "updateMatrix") { + int extruder_id = j["extruder_id"].get(); + auto new_matrix = CalcFlushingVolumes(extruder_id); + json obj; + obj["flush_volume_matrix"] = MatrixFlatten(new_matrix); + obj["extruder_id"] = extruder_id; + CallAfter([obj, this] { + std::string flush_volume_matrix_str = obj["flush_volume_matrix"].dump(); + std::string extruder_id_str = std::to_string(obj["extruder_id"].get()); + wxString script = wxString::Format("updateTable(%s,%s)", flush_volume_matrix_str, extruder_id_str); + m_webview->RunScript(script); + }); + } + else if (j["msg"].get() == "storeData") { + int extruder_num = j["number_of_extruders"].get(); + std::vector> store_matrixs; + for (auto iter = j["raw_matrix"].begin(); iter != j["raw_matrix"].end(); ++iter) { + store_matrixs.emplace_back((*iter).get>()); + } + std::vectorstore_multipliers = j["flush_multiplier"].get>(); + this->StoreFlushData(extruder_num, store_matrixs, store_multipliers); + m_submit_flag = true; + this->Close(); + } + else if (j["msg"].get() == "quit") { + this->Close(); } } - } + catch (...) { - // BBS - m_sizer_advanced->AddSpacer(FromDIP(10)); - auto tip_message_panel = new wxPanel(m_page_advanced, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); - tip_message_panel->SetBackgroundColour(wxColour(238, 238, 238)); - auto message_sizer = new wxBoxSizer(wxVERTICAL); - tip_message_panel->SetSizer(message_sizer); - { - wxString message = _L("Studio would re-calculate your flushing volumes everytime the filaments color changed or filaments changed. You could disable the auto-calculate in Bambu Studio > Preferences"); - m_tip_message_label = new Label(tip_message_panel, wxEmptyString); - wxClientDC dc(tip_message_panel); - wxString multiline_message; - m_tip_message_label->split_lines(dc, sizer_width, message, multiline_message); - m_tip_message_label->SetLabel(multiline_message); - m_tip_message_label->SetFont(Label::Body_13); - message_sizer->Add(m_tip_message_label, 0, wxEXPAND | wxALL, TIP_MESSAGES_PADDING); - } - m_sizer_advanced->Add(tip_message_panel, 0, wxEXPAND | wxRIGHT | wxLEFT, TABLE_BORDER); - bool is_show = wxGetApp().app_config->get("auto_calculate_flush") != "disabled"; - tip_message_panel->Show(is_show); - m_sizer_advanced->AddSpacer(FromDIP(10)); - auto calc_btn_sizer = create_calc_btn_sizer(m_page_advanced); - m_sizer_advanced->Add(calc_btn_sizer, 0, wxEXPAND | wxLEFT, FromDIP(30)); - - //m_sizer_advanced->AddSpacer(FromDIP(10)); - m_sizer_advanced->AddSpacer(FromDIP(5)); - header_line_panel = new wxPanel(m_page_advanced, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); - header_line_panel->SetBackgroundColour(wxColour(238, 238, 238)); - auto header_line_sizer = new wxBoxSizer(wxHORIZONTAL); - header_line_panel->SetSizer(header_line_sizer); - - header_line_sizer->AddSpacer(HEADER_BEG_PADDING); - for (unsigned int i = 0; i < m_number_of_extruders; ++i) { - wxButton* icon = new wxButton(header_line_panel, wxID_ANY, {}, wxDefaultPosition, WIPE_TOWER_ICON_SIZE, wxBORDER_NONE | wxBU_AUTODRAW); - icon->SetBitmap(*get_extruder_color_icon(m_colours[i].GetAsString(wxC2S_HTML_SYNTAX).ToStdString(), std::to_string(i + 1), FromDIP(16), FromDIP(16))); - icon->SetCanFocus(false); - icon_list1.push_back(icon); - - header_line_sizer->AddSpacer(ICON_GAP); - header_line_sizer->Add(icon, 0, wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM, HEADER_VERT_PADDING); - } - header_line_sizer->AddSpacer(HEADER_END_PADDING); - - m_sizer_advanced->Add(header_line_panel, 0, wxEXPAND | wxRIGHT | wxLEFT, TABLE_BORDER); - - create_panels(m_page_advanced, m_number_of_extruders); - - //m_sizer_advanced->AddSpacer(BTN_SIZE.y); - - // BBS: for tunning flush volumes - { - auto multi_desc_label = new wxStaticText(m_page_advanced, wxID_ANY, _(L("Flushing volume (mm³) for each filament pair.")), wxDefaultPosition, wxDefaultSize, 0); - multi_desc_label->SetForegroundColour(g_text_color); - m_sizer_advanced->Add(multi_desc_label, 0, wxEXPAND | wxLEFT, TEXT_BEG_PADDING); - - wxString min_flush_str = wxString::Format(_L("Suggestion: Flushing Volume in range [%d, %d]"),*std::min_element(m_min_flush_volume[m_cur_extruder_id].begin(), m_min_flush_volume[m_cur_extruder_id].end()), m_max_flush_volume); - m_min_flush_label = new wxStaticText(m_page_advanced, wxID_ANY, min_flush_str, wxDefaultPosition, wxDefaultSize, 0); - m_min_flush_label->SetForegroundColour(g_text_color); - m_sizer_advanced->Add(m_min_flush_label, 0, wxEXPAND | wxLEFT, TEXT_BEG_PADDING); - - auto on_apply_text_modify = [this](wxEvent& e) { - wxString str = m_flush_multiplier_ebox->GetValue(); - float multiplier = wxAtof(str); - if (multiplier < g_min_flush_multiplier || multiplier > g_max_flush_multiplier) { - str = wxString::Format(("%.2f"), multiplier < g_min_flush_multiplier ? g_min_flush_multiplier : g_max_flush_multiplier); - m_flush_multiplier_ebox->SetValue(str); - m_flush_multiplier[m_cur_extruder_id] = wxAtof(m_flush_multiplier_ebox->GetValue()); - MessageDialog dlg(nullptr, - wxString::Format(_L("The multiplier should be in range [%.2f, %.2f]."), g_min_flush_multiplier, g_max_flush_multiplier), - _L("Warning"), wxICON_WARNING | wxOK); - dlg.ShowModal(); - } - else { - m_flush_multiplier[m_cur_extruder_id] = multiplier; - } - for (unsigned int i = 0; i < m_number_of_extruders; ++i) { - for (unsigned int j = 0; j < m_number_of_extruders; ++j) { - edit_boxes[i][j]->SetValue(to_string(int(m_display_matrix[m_number_of_extruders * j + i] * multiplier))); - } - } - - this->update_warning_texts(); - e.Skip(); - }; - - m_sizer_advanced->AddSpacer(10); - - wxBoxSizer* param_sizer = new wxBoxSizer(wxHORIZONTAL); - wxStaticText* flush_multiplier_title = new wxStaticText(m_page_advanced, wxID_ANY, _L("Multiplier")); - param_sizer->Add(flush_multiplier_title, 0, wxALIGN_CENTER | wxALL, 0); - param_sizer->AddSpacer(FromDIP(5)); - m_flush_multiplier_ebox = new wxTextCtrl(m_page_advanced, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(50), -1), wxTE_PROCESS_ENTER); - m_flush_multiplier_ebox->SetValue(wxString::Format(("%.2f"), m_flush_multiplier[m_cur_extruder_id])); - m_flush_multiplier_ebox->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); - param_sizer->Add(m_flush_multiplier_ebox, 0, wxALIGN_CENTER | wxALL, 0); - param_sizer->AddStretchSpacer(1); - m_sizer_advanced->Add(param_sizer, 0, wxEXPAND | wxLEFT, TEXT_BEG_PADDING); - - wxStaticText* suggest = new wxStaticText(m_page_advanced, wxID_ANY, wxString::Format(_L("The multiplier should be in range [%.2f, %.2f]."), g_min_flush_multiplier, g_max_flush_multiplier)); - suggest->SetForegroundColour(g_text_color); - m_sizer_advanced->Add(suggest, 0, wxEXPAND | wxLEFT, TEXT_BEG_PADDING); - m_sizer_advanced->AddSpacer(5); - - m_flush_multiplier_ebox->Bind(wxEVT_TEXT_ENTER, on_apply_text_modify); - m_flush_multiplier_ebox->Bind(wxEVT_KILL_FOCUS, on_apply_text_modify); - m_flush_multiplier_ebox->Bind(wxEVT_COMMAND_TEXT_UPDATED, [this](wxCommandEvent&) { - wxString str = m_flush_multiplier_ebox->GetValue(); - float multiplier = wxAtof(str); - if (multiplier < g_min_flush_multiplier || multiplier > g_max_flush_multiplier) { - str = wxString::Format(("%.2f"), multiplier < g_min_flush_multiplier ? g_min_flush_multiplier : g_max_flush_multiplier); - m_flush_multiplier_ebox->SetValue(str); - m_flush_multiplier[m_cur_extruder_id] = wxAtof(m_flush_multiplier_ebox->GetValue()); - } - else { - m_flush_multiplier[m_cur_extruder_id] = multiplier; - } - m_flush_multiplier_ebox->SetInsertionPointEnd(); + } }); - } - this->update_warning_texts(); - - m_page_advanced->Hide(); - - // Now the same for simple mode: - gridsizer_simple->Add(new wxStaticText(m_page_simple, wxID_ANY, wxString("")), 0, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL); - gridsizer_simple->Add(new wxStaticText(m_page_simple, wxID_ANY, wxString(_(L("unloaded")))), 0, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL); - gridsizer_simple->Add(new wxStaticText(m_page_simple,wxID_ANY,wxString(_(L("loaded")))), 0, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL); - - auto add_spin_ctrl = [this](std::vector& vec, float initial) - { - wxSpinCtrl* spin_ctrl = new wxSpinCtrl(m_page_simple, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(ITEM_WIDTH(), -1), style | wxALIGN_RIGHT, 0, 300, (int)initial); - update_ui(spin_ctrl); - vec.push_back(spin_ctrl); - -#ifdef __WXOSX__ - // On OSX / Cocoa, wxSpinCtrl::GetValue() doesn't return the new value - // when it was changed from the text control, so the on_change callback - // gets the old one, and on_kill_focus resets the control to the old value. - // As a workaround, we get the new value from $event->GetString and store - // here temporarily so that we can return it from get_value() - spin_ctrl->Bind(wxEVT_TEXT, ([spin_ctrl](wxCommandEvent e) - { - long value; - const bool parsed = e.GetString().ToLong(&value); - int tmp_value = parsed && value >= INT_MIN && value <= INT_MAX ? (int)value : INT_MIN; - - // Forcibly set the input value for SpinControl, since the value - // inserted from the keyboard or clipboard is not updated under OSX - if (tmp_value != INT_MIN) { - spin_ctrl->SetValue(tmp_value); - - // But in SetValue() is executed m_text_ctrl->SelectAll(), so - // discard this selection and set insertion point to the end of string - spin_ctrl->GetText()->SetInsertionPointEnd(); - } - }), spin_ctrl->GetId()); -#endif - }; - - for (unsigned int i=0;iSetCanFocus(false); - w->SetBackgroundColour(m_colours[i]); - hsizer->Add(w, wxALIGN_CENTER_VERTICAL); - hsizer->AddSpacer(10); - hsizer->Add(new wxStaticText(m_page_simple, wxID_ANY, wxString(_(L("Filament #"))) << i + 1 << ": "), 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); - - gridsizer_simple->Add(hsizer, 1, wxEXPAND | wxALIGN_CENTER_VERTICAL); - gridsizer_simple->Add(m_old.back(),0); - gridsizer_simple->Add(m_new.back(),0); - } - - m_sizer = new wxBoxSizer(wxVERTICAL); - m_sizer->Add(m_page_simple, 0, wxEXPAND, 0); - m_sizer->Add(m_page_advanced, 0, wxEXPAND, 0); - - m_sizer->SetSizeHints(this); - SetSizer(m_sizer); - this->Layout(); - - toggle_advanced(); // to show/hide what is appropriate - - header_line_panel->Bind(wxEVT_PAINT, [this](wxPaintEvent&) { - wxPaintDC dc(header_line_panel); - wxString from_text = _L("From"); - wxString to_text = _L("To"); - wxSize from_text_size = dc.GetTextExtent(from_text); - wxSize to_text_size = dc.GetTextExtent(to_text); - - int base_y = (header_line_panel->GetSize().y - from_text_size.y - to_text_size.y) / 2; - int vol_width = ROW_BEG_PADDING + EDIT_BOXES_GAP / 2 + WIPE_TOWER_ICON_SIZE.x; - int base_x = (vol_width - from_text_size.x - to_text_size.x) / 2; - - // draw from text - int x = base_x; - int y = base_y + to_text_size.y; - dc.DrawText(from_text, x, y); - - // draw to text - x = base_x + from_text_size.x; - y = base_y; - dc.DrawText(to_text, x, y); - - // draw a line - int p1_x = base_x + from_text_size.x - to_text_size.y; - int p1_y = base_y; - int p2_x = base_x + from_text_size.x + from_text_size.y; - int p2_y = base_y + from_text_size.y + to_text_size.y; - dc.SetPen(wxPen(wxColour(172, 172, 172, 1))); - dc.DrawLine(p1_x, p1_y, p2_x, p2_y); - }); } -int WipingPanel::calc_flushing_volume(const wxColour& from_, const wxColour& to_ ,int min_flush_volume) -{ - Slic3r::FlushVolCalculator calculator(min_flush_volume, m_max_flush_volume); - return calculator.calc_flush_vol(from_.Alpha(), from_.Red(), from_.Green(), from_.Blue(), to_.Alpha(), to_.Red(), to_.Green(), to_.Blue()); +int WipingDialog::CalcFlushingVolume(const wxColour& from, const wxColour& to, int min_flush_volume) +{ + Slic3r::FlushVolCalculator calculator(min_flush_volume, Slic3r::g_max_flush_volume); + return calculator.calc_flush_vol(from.Alpha(), from.Red(), from.Green(), from.Blue(), to.Alpha(), to.Red(), to.Green(), to.Blue()); } -void WipingPanel::update_warning_texts() +WipingDialog::VolumeMatrix WipingDialog::CalcFlushingVolumes(int extruder_id) { - static const wxColour g_warning_color = *wxRED; - static const wxColour g_normal_color = *wxBLACK; + auto& preset_bundle = wxGetApp().preset_bundle; + auto full_config = preset_bundle->full_config(); + auto& ams_multi_color_filament = preset_bundle->ams_multi_color_filment; - wxString multi_str = m_flush_multiplier_ebox->GetValue(); - float multiplier = wxAtof(multi_str); - - bool has_exception_flush = false; - for (int i = 0; i < edit_boxes.size(); i++) { - auto& box_vec = edit_boxes[i]; - for (int j = 0; j < box_vec.size(); j++) { - if (i == j) - continue; - - auto text_box = box_vec[j]; - wxString str = text_box->GetValue(); - int actual_volume = wxAtoi(str); - if (actual_volume < m_min_flush_volume[m_cur_extruder_id][i] || actual_volume > m_max_flush_volume) { - if (text_box->GetForegroundColour() != g_warning_color) { - text_box->SetForegroundColour(g_warning_color); - text_box->Refresh(); - } - has_exception_flush = true; - } - else { - if (text_box->GetForegroundColour() != g_normal_color) { - text_box->SetForegroundColour(StateColor::darkModeColorFor(g_normal_color)); - text_box->Refresh(); - } - } - } - } - - if (has_exception_flush && m_min_flush_label->GetForegroundColour() != g_warning_color) { - m_min_flush_label->SetForegroundColour(g_warning_color); - m_min_flush_label->Refresh(); - } - else if (!has_exception_flush && m_min_flush_label->GetForegroundColour() != g_text_color) { - m_min_flush_label->SetForegroundColour(g_text_color); - m_min_flush_label->Refresh(); - } -} - -void WipingPanel::calc_flushing_volumes() -{ - auto& ams_multi_color_filament = wxGetApp().preset_bundle->ams_multi_color_filment; + std::vector filament_color_strs = full_config.option("filament_colour")->values; std::vector> multi_colors; + std::vector filament_colors; + for (auto color_str : filament_color_strs) + filament_colors.emplace_back(color_str); // Support for multi-color filament - for (int i = 0; i < m_colours.size(); ++i) { + for (int i = 0; i < filament_colors.size(); ++i) { std::vector single_filament; if (i < ams_multi_color_filament.size()) { if (!ams_multi_color_filament[i].empty()) { @@ -673,169 +230,64 @@ void WipingPanel::calc_flushing_volumes() continue; } } - single_filament.push_back(wxColour(m_colours[i])); + single_filament.push_back(wxColour(filament_colors[i])); multi_colors.push_back(single_filament); } + VolumeMatrix matrix; + for (int from_idx = 0; from_idx < multi_colors.size(); ++from_idx) { bool is_from_support = is_support_filament(from_idx); + matrix.emplace_back(); for (int to_idx = 0; to_idx < multi_colors.size(); ++to_idx) { - bool is_to_support = is_support_filament(to_idx); if (from_idx == to_idx) { - edit_boxes[to_idx][from_idx]->SetValue(std::to_string(0)); + matrix.back().emplace_back(0); + continue; + } + + bool is_to_support = is_support_filament(to_idx); + + int flushing_volume = 0; + if (is_to_support) { + flushing_volume = Slic3r::g_flush_volume_to_support; } else { - int flushing_volume = 0; - if (is_to_support) { - flushing_volume = Slic3r::g_flush_volume_to_support; - } - else { - for (int i = 0; i < multi_colors[from_idx].size(); ++i) { - const wxColour& from = multi_colors[from_idx][i]; - for (int j = 0; j < multi_colors[to_idx].size(); ++j) { - const wxColour& to = multi_colors[to_idx][j]; - int volume = calc_flushing_volume(from, to, m_min_flush_volume[m_cur_extruder_id][from_idx]); - flushing_volume = std::max(flushing_volume, volume); - } - } - - if (is_from_support) { - flushing_volume = std::max(Slic3r::g_min_flush_volume_from_support, flushing_volume); + for (int i = 0; i < multi_colors[from_idx].size(); ++i) { + const wxColour& from = multi_colors[from_idx][i]; + for (int j = 0; j < multi_colors[to_idx].size(); ++j) { + const wxColour& to = multi_colors[to_idx][j]; + int volume = CalcFlushingVolume(from, to, m_extra_flush_volume[extruder_id][from_idx]); + flushing_volume = std::max(flushing_volume, volume); } } - m_display_matrix[m_number_of_extruders * from_idx + to_idx] = flushing_volume; - flushing_volume = int(flushing_volume * get_flush_multiplier()); - edit_boxes[to_idx][from_idx]->SetValue(std::to_string(flushing_volume)); + if (is_from_support) { + flushing_volume = std::max(Slic3r::g_min_flush_volume_from_support, flushing_volume); + } } + matrix.back().emplace_back(flushing_volume); } } - - this->update_warning_texts(); + return matrix; } -void WipingPanel::msw_rescale() +void WipingDialog::StoreFlushData(int extruder_num, const std::vector>& flush_volume_vecs, const std::vector&flush_multipliers) { - for (unsigned int i = 0; i < icon_list1.size(); ++i) { - auto bitmap = *get_extruder_color_icon(m_colours[i].GetAsString(wxC2S_HTML_SYNTAX).ToStdString(), std::to_string(i + 1), FromDIP(16), FromDIP(16)); - icon_list1[i]->SetBitmap(bitmap); - icon_list2[i]->SetBitmap(bitmap); - } + m_flush_multipliers = flush_multipliers; + m_raw_matrixs = flush_volume_vecs; } -// Reads values from the (advanced) wiping matrix: -std::vector WipingPanel::read_matrix_values() { - if (!m_advanced) - fill_in_matrix(); - std::vector output; - for (unsigned int i=0;iGetValue().ToDouble(&val); - output.push_back((float) val / get_flush_multiplier()); - } - } - } - m_display_matrix = output; - back_matrix(); - return m_matrix; -} - -// Reads values from simple mode to save them for next time: -std::vector WipingPanel::read_extruders_values() { - std::vector output; - for (unsigned int i=0;iGetValue()); - output.push_back(m_new[i]->GetValue()); - } - return output; -} - -// This updates the "advanced" matrix based on values from "simple" mode -void WipingPanel::fill_in_matrix() { - for (unsigned i=0;iSetValue(wxString("")<< (m_old[i]->GetValue() + m_new[j]->GetValue())); - } - } -} - -void WipingPanel::generate_display_matrix() +std::vector WipingDialog::GetFlattenMatrix()const { - m_display_matrix = get_flush_volumes_matrix(m_matrix, m_cur_extruder_id, m_nozzle_nums); + std::vector ret; + for (auto& matrix : m_raw_matrixs) { + ret.insert(ret.end(), matrix.begin(), matrix.end()); + } + return ret; } -void WipingPanel::back_matrix() + +std::vector WipingDialog::GetMultipliers()const { - set_flush_volumes_matrix(m_matrix, m_display_matrix, m_cur_extruder_id, m_nozzle_nums); -} - -void WipingPanel::update_table() -{ - for (unsigned int i = 0; i < m_number_of_extruders; ++i) { - for (unsigned int j = 0; j < m_number_of_extruders; ++j) { - if (i == j) { - edit_boxes[i][j]->SetValue(wxString("0")); - edit_boxes[i][j]->SetEditable(false); - } else { - edit_boxes[i][j]->SetValue(wxString("") << int(m_display_matrix[m_number_of_extruders * j + i] * m_flush_multiplier[m_cur_extruder_id])); - } - } - } - wxString str = wxString::Format(("%.2f"), m_flush_multiplier[m_cur_extruder_id]); - m_flush_multiplier_ebox->SetValue(str); - update_warning_texts(); -} - -void WipingPanel::on_select_extruder(wxCommandEvent &evt) -{ - ComboBox *comboBox = dynamic_cast(evt.GetEventObject()); - if (comboBox) { - int selection = comboBox->GetSelection(); - if (m_cur_extruder_id != selection) { - read_matrix_values(); - m_cur_extruder_id = selection; - generate_display_matrix(); - update_table(); - } - } -} - -// Function to check if simple and advanced settings are matching -bool WipingPanel::advanced_matches_simple() { - for (unsigned i=0;iGetValue() != (wxString("")<< (m_old[i]->GetValue() + m_new[j]->GetValue()))) - return false; - } - } - return true; -} - - -// Switches the dialog from simple to advanced mode and vice versa -void WipingPanel::toggle_advanced(bool user_action) { - if (user_action) - m_advanced = !m_advanced; // user demands a change -> toggle - else { - // BBS: show advanced mode by default - //m_advanced = !advanced_matches_simple(); // if called from constructor, show what is appropriate - m_advanced = true; - } - - (m_advanced ? m_page_advanced : m_page_simple)->Show(); - (!m_advanced ? m_page_advanced : m_page_simple)->Hide(); - - if (m_advanced) - if (user_action) fill_in_matrix(); // otherwise keep values loaded from config - - m_sizer->Layout(); - Refresh(); -} + return m_flush_multipliers; +} \ No newline at end of file diff --git a/src/slic3r/GUI/WipeTowerDialog.hpp b/src/slic3r/GUI/WipeTowerDialog.hpp index 45ac8d008..a4bf53e31 100644 --- a/src/slic3r/GUI/WipeTowerDialog.hpp +++ b/src/slic3r/GUI/WipeTowerDialog.hpp @@ -1,117 +1,33 @@ #ifndef _WIPE_TOWER_DIALOG_H_ #define _WIPE_TOWER_DIALOG_H_ -#include "GUI_Utils.hpp" - -#include -#include -#include -#include -#include -#include -class Button; -class Label; - -class WipingPanel : public wxPanel { -public: - // BBS - WipingPanel(wxWindow* parent, const std::vector& matrix, const std::vector& extruders, size_t cur_extruder_id, - const std::vector& extruder_colours, Button* calc_button, - const std::vector>& extra_flush_volume, const std::vector& flush_multiplier, size_t nozzle_nums); - std::vector read_matrix_values(); - std::vector read_extruders_values(); - void toggle_advanced(bool user_action = false); - void create_panels(wxWindow* parent, const int num); - void calc_flushing_volumes(); - void msw_rescale(); - wxBoxSizer* create_calc_btn_sizer(wxWindow* parent); - - float get_flush_multiplier() - { - if (m_flush_multiplier_ebox == nullptr) - return 1.f; - - return wxAtof(m_flush_multiplier_ebox->GetValue()); - } - - std::vector get_flush_multiplier_vector() { return m_flush_multiplier; } - -private: - void on_select_extruder(wxCommandEvent &evt); - void generate_display_matrix(); // generate display_matrix frem matrix - void back_matrix(); - void update_table(); // if matrix is modified update the table - void fill_in_matrix(); - bool advanced_matches_simple(); - int calc_flushing_volume(const wxColour& from, const wxColour& to,int min_flush_volume); - void update_warning_texts(); - - std::vector m_old; - std::vector m_new; - std::vector> edit_boxes; - std::vector m_colours; - unsigned int m_number_of_extruders = 0; - bool m_advanced = false; - wxPanel* m_page_simple = nullptr; - wxPanel* m_page_advanced = nullptr; - wxPanel* header_line_panel = nullptr; - wxBoxSizer* m_sizer = nullptr; - wxBoxSizer* m_sizer_simple = nullptr; - wxBoxSizer* m_sizer_advanced = nullptr; - wxGridSizer* m_gridsizer_advanced = nullptr; - wxButton* m_widget_button = nullptr; - Label* m_tip_message_label = nullptr; - - std::vector icon_list1; - std::vector icon_list2; - - const std::vector> m_min_flush_volume; - const int m_max_flush_volume; - - wxTextCtrl* m_flush_multiplier_ebox = nullptr; - wxStaticText* m_min_flush_label = nullptr; - - std::vector m_flush_multiplier; - std::vector m_matrix; - std::vector m_display_matrix; - size_t m_cur_extruder_id; - size_t m_nozzle_nums; -}; +#include - - - -class WipingDialog : public Slic3r::GUI::DPIDialog +class WipingDialog : public wxDialog { public: - WipingDialog(wxWindow* parent, const std::vector& matrix, const std::vector& extruders, const std::vector& extruder_colours, - const std::vector>&extra_flush_volume, const std::vector& flush_multiplier, size_t nozzle_nums); - std::vector get_matrix() const { return m_output_matrix; } - std::vector get_extruders() const { return m_output_extruders; } - wxBoxSizer* create_btn_sizer(long flags); + using VolumeMatrix = std::vector>; - float get_flush_multiplier() - { - if (m_panel_wiping == nullptr) - return 1.f; - - return m_panel_wiping->get_flush_multiplier(); - } - - std::vector get_flush_multiplier_vector() const { - if (m_panel_wiping == nullptr) - return {1.f, 1.f}; - return m_panel_wiping->get_flush_multiplier_vector(); - } - - void on_dpi_changed(const wxRect &suggested_rect) override; + WipingDialog(wxWindow* parent,const std::vector>& extra_flush_volume, const int max_flush_volume = Slic3r::g_max_flush_volume); + VolumeMatrix CalcFlushingVolumes(int extruder_id); + std::vector GetFlattenMatrix()const; + std::vector GetMultipliers()const; + bool GetSubmitFlag() const { return m_submit_flag; } private: - WipingPanel* m_panel_wiping = nullptr; - std::vector m_output_matrix; - std::vector m_output_extruders; - std::unordered_map m_button_list; + int CalcFlushingVolume(const wxColour& from_, const wxColour& to_, int min_flush_volume); + wxString BuildTableObjStr(); + wxString BuildTextObjStr(); + void StoreFlushData(int extruder_num, const std::vector>& flush_volume_vecs, const std::vector& flush_multipliers); + + wxWebView* m_webview; + std::vector> m_extra_flush_volume; + int m_max_flush_volume; + + VolumeMatrix m_raw_matrixs; + std::vector m_flush_multipliers; + bool m_submit_flag{ false }; }; #endif // _WIPE_TOWER_DIALOG_H_ \ No newline at end of file