#include "FanControl.hpp" #include "Label.hpp" #include "../BitmapCache.hpp" #include "../I18N.hpp" #include "../GUI_App.hpp" #include "../MsgDialog.hpp" #include #include namespace Slic3r { namespace GUI { wxDEFINE_EVENT(EVT_FAN_SWITCH_ON, wxCommandEvent); wxDEFINE_EVENT(EVT_FAN_SWITCH_OFF, wxCommandEvent); wxDEFINE_EVENT(EVT_FAN_ADD, wxCommandEvent); wxDEFINE_EVENT(EVT_FAN_DEC, wxCommandEvent); wxDEFINE_EVENT(EVT_FAN_CHANGED, wxCommandEvent); constexpr int time_out = 10; /************************************************* Description:Fan **************************************************/ Fan::Fan(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size) { create(parent, id, pos, size); } void Fan::create(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size) { m_current_speeds = 0; wxWindow::Create(parent, id, pos, size, wxBORDER_NONE); SetBackgroundColour(*wxWHITE); m_rotate_offsets.push_back(RotateOffSet{ 2.5, wxPoint(-FromDIP(16), FromDIP(11)) }); m_rotate_offsets.push_back(RotateOffSet{ 2.2, wxPoint(-FromDIP(20), FromDIP(11)) }); m_rotate_offsets.push_back(RotateOffSet{ 1.7, wxPoint(-FromDIP(24), FromDIP(12)) }); m_rotate_offsets.push_back(RotateOffSet{ 1.2, wxPoint(-FromDIP(22), FromDIP(4)) }); m_rotate_offsets.push_back(RotateOffSet{ 0.7, wxPoint(-FromDIP(17), -FromDIP(6)) }); m_rotate_offsets.push_back(RotateOffSet{ 0.3, wxPoint(-FromDIP(8), -FromDIP(11)) }); m_rotate_offsets.push_back(RotateOffSet{ 6.1, wxPoint(-FromDIP(0), -FromDIP(9)) }); m_rotate_offsets.push_back(RotateOffSet{ 5.5, wxPoint(-FromDIP(4), -FromDIP(2)) }); m_rotate_offsets.push_back(RotateOffSet{ 5.1, wxPoint(-FromDIP(3), FromDIP(5)) }); m_rotate_offsets.push_back(RotateOffSet{ 4.6, wxPoint(-FromDIP(3), FromDIP(14)) }); m_rotate_offsets.push_back(RotateOffSet{ 4.0, wxPoint(-FromDIP(2), FromDIP(11)) }); //auto m_bitmap_pointer = ScalableBitmap(this, "fan_pointer", FromDIP(25)); //m_img_pointer = m_bitmap_pointer.bmp().ConvertToImage(); m_bitmap_bk = ScalableBitmap(this, "fan_dash_bk", 80); for (auto i = 0; i <= 10; i++) { #ifdef __APPLE__ auto m_bitmap_scale = ScalableBitmap(this, wxString::Format("fan_scale_%d", i).ToStdString(), 60); m_bitmap_scales.push_back(m_bitmap_scale); #else auto m_bitmap_scale = ScalableBitmap(this, wxString::Format("fan_scale_%d", i).ToStdString(), 46); m_bitmap_scales.push_back(m_bitmap_scale); #endif } //#ifdef __APPLE__ // SetMinSize(wxSize(FromDIP(100), FromDIP(100) + FromDIP(6))); // SetMaxSize(wxSize(FromDIP(100), FromDIP(100) + FromDIP(6))); //#else SetMinSize(wxSize(m_bitmap_bk.GetBmpSize().x, m_bitmap_bk.GetBmpSize().y + FromDIP(6))); SetMaxSize(wxSize(m_bitmap_bk.GetBmpSize().x, m_bitmap_bk.GetBmpSize().y + FromDIP(6))); //#endif // __APPLE__ Bind(wxEVT_PAINT, &Fan::paintEvent, this); } void Fan::set_fan_speeds(int g) { m_current_speeds = g; Refresh(); } void Fan::post_event(wxCommandEvent &&event) { /*event.SetString(m_info.can_id); event.SetEventObject(m_parent); wxPostEvent(m_parent, event); event.Skip();*/ } void Fan::paintEvent(wxPaintEvent& evt) { wxPaintDC dc(this); render(dc); } void Fan::render(wxDC& dc) { #ifdef __WXMSW__ wxSize size = GetSize(); wxMemoryDC memdc; wxBitmap bmp(size.x, size.y); memdc.SelectObject(bmp); memdc.Blit({ 0, 0 }, size, &dc, { 0, 0 }); { wxGCDC dc2(memdc); doRender(dc2); } memdc.SelectObject(wxNullBitmap); dc.DrawBitmap(bmp, 0, 0); #else doRender(dc); #endif } void Fan::doRender(wxDC& dc) { auto rpm = wxT("rpm"); wxSize size = GetSize(); dc.DrawBitmap(m_bitmap_bk.bmp(), wxPoint(0,0)); //fan scale /*auto central_point = wxPoint(size.x / 2, size.y / 2 + FromDIP(15)); dc.DrawBitmap(m_bitmap_scale_0.bmp(), central_point.x - FromDIP(38), central_point.y); dc.DrawBitmap(m_bitmap_scale_1.bmp(), central_point.x - FromDIP(40), central_point.y - FromDIP(17)); dc.DrawBitmap(m_bitmap_scale_2.bmp(), central_point.x - FromDIP(40), central_point.y - FromDIP(36)); dc.DrawBitmap(m_bitmap_scale_3.bmp(), central_point.x - FromDIP(32), central_point.y - FromDIP(48)); dc.DrawBitmap(m_bitmap_scale_4.bmp(), central_point.x - FromDIP(18), central_point.y - FromDIP(53)); dc.DrawBitmap(m_bitmap_scale_5.bmp(), central_point.x - FromDIP(0), central_point.y - FromDIP(53)); dc.DrawBitmap(m_bitmap_scale_6.bmp(), central_point.x + FromDIP(18), central_point.y - FromDIP(48)); dc.DrawBitmap(m_bitmap_scale_7.bmp(), central_point.x + FromDIP(31), central_point.y - FromDIP(36)); dc.DrawBitmap(m_bitmap_scale_8.bmp(), central_point.x + FromDIP(36), central_point.y - FromDIP(17)); dc.DrawBitmap(m_bitmap_scale_9.bmp(), central_point.x + FromDIP(28), central_point.y);*/ //fan pointer //auto pointer_central_point = wxPoint((size.x - m_img_pointer.GetSize().x) / 2, (size.y - m_img_pointer.GetSize().y) / 2); //auto bmp = m_img_pointer.Rotate(m_rotate_offsets[m_current_speeds].rotate, wxPoint(size.x / 2,size.y / 2)); auto central_point = wxPoint((size.x - m_bitmap_scales[m_current_speeds].GetBmpSize().x) / 2, (size.y - m_bitmap_scales[m_current_speeds].GetBmpSize().y) / 2 - FromDIP(4)); dc.DrawBitmap(m_bitmap_scales[m_current_speeds].bmp(), central_point.x, central_point.y); //fan val dc.SetTextForeground(DRAW_TEXT_COLOUR); dc.SetFont(::Label::Head_13); auto speeds = wxString::Format("%d%%", m_current_speeds * 10); dc.DrawText(speeds, (size.x - dc.GetTextExtent(speeds).x) / 2 + FromDIP(2), size.y - dc.GetTextExtent(speeds).y - FromDIP(5)); //rpm //dc.SetFont(::Label::Body_13); //dc.DrawText(rpm, (size.x - dc.GetTextExtent(rpm).x) / 2, size.y - dc.GetTextExtent(rpm).y); } void Fan::msw_rescale() { m_bitmap_bk.msw_rescale(); } void Fan::DoSetSize(int x, int y, int width, int height, int sizeFlags) { wxWindow::DoSetSize(x, y, width, height, sizeFlags); } /************************************************* Description:FanOperate **************************************************/ FanOperate::FanOperate(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size) { m_current_speeds = 0; m_min_speeds = 1; m_max_speeds = 10; create(parent, id, pos, size); wxGetApp().UpdateDarkUIWin(this); } void FanOperate::create(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size) { wxWindow::Create(parent, id, pos, size, wxBORDER_NONE); SetBackgroundColour(*wxWHITE); m_bitmap_add = ScalableBitmap(this, "fan_control_add", 24); m_bitmap_decrease = ScalableBitmap(this, "fan_control_decrease", 24); SetMinSize(wxSize(FromDIP(SIZE_OF_FAN_OPERATE.x), FromDIP(SIZE_OF_FAN_OPERATE.y))); Bind(wxEVT_PAINT, &FanOperate::paintEvent, this); Bind(wxEVT_ENTER_WINDOW, [this](auto& e) { SetCursor(wxCURSOR_HAND);}); Bind(wxEVT_LEAVE_WINDOW, [this](auto& e) { SetCursor(wxCURSOR_ARROW);}); Bind(wxEVT_LEFT_DOWN, &FanOperate::on_left_down, this); } void FanOperate::on_left_down(wxMouseEvent& event) { auto mouse_pos = wxPoint(0,0); #ifdef __APPLE__ mouse_pos= GetParent()->GetParent()->ClientToScreen(event.GetPosition()); #else mouse_pos = ClientToScreen(event.GetPosition()); #endif // __APPLE__ auto win_pos = ClientToScreen(wxPoint(0, 0)); auto decrease_fir = FromDIP(24); auto add_fir = GetSize().x - FromDIP(24); if (mouse_pos.x > win_pos.x && mouse_pos.x < (decrease_fir + win_pos.x) && mouse_pos.y > win_pos.y && mouse_pos.y < (win_pos.y + GetSize().y)) { decrease_fan_speeds(); return; } if (mouse_pos.x > (add_fir + win_pos.x) && mouse_pos.x < (win_pos.x + GetSize().x) && mouse_pos.y > win_pos.y && mouse_pos.y < (win_pos.y + GetSize().y)) { add_fan_speeds(); return; } } void FanOperate::set_machine_obj(MachineObject *obj) { m_obj = obj; } void FanOperate::set_fan_speeds(int g) { m_current_speeds = g; Refresh(); } void FanOperate::add_fan_speeds() { if (m_obj && m_obj->is_in_printing()) { MessageDialog msg_wingow(nullptr, _L("Changed fan speed during pringing may affect print quality, please choose carefully."), "", wxICON_WARNING | wxCANCEL | wxOK); if (msg_wingow.ShowModal() == wxID_CANCEL) { return; } } if (m_current_speeds + 1 > m_max_speeds) return; set_fan_speeds(++m_current_speeds); post_event(wxCommandEvent(EVT_FAN_ADD)); post_event(wxCommandEvent(EVT_FAN_SWITCH_ON)); } void FanOperate::decrease_fan_speeds() { if (m_obj && m_obj->is_in_printing()) { MessageDialog msg_wingow(nullptr, _L("Changed fan speed during pringing may affect print quality, please choose carefully."), "", wxICON_WARNING | wxCANCEL | wxOK); if (msg_wingow.ShowModal() == wxID_CANCEL) { return; } } //turn off if (m_current_speeds - 1 < m_min_speeds) { m_current_speeds = 0; set_fan_speeds(m_current_speeds); post_event(wxCommandEvent(EVT_FAN_SWITCH_OFF)); } else { set_fan_speeds(--m_current_speeds); } post_event(wxCommandEvent(EVT_FAN_DEC)); } void FanOperate::post_event(wxCommandEvent &&event) { event.SetInt(m_current_speeds); event.SetEventObject(this); wxPostEvent(this, event); event.Skip(); } void FanOperate::paintEvent(wxPaintEvent& evt) { wxPaintDC dc(this); render(dc); } void FanOperate::render(wxDC& dc) { #ifdef __WXMSW__ wxSize size = GetSize(); wxMemoryDC memdc; wxBitmap bmp(size.x, size.y); memdc.SelectObject(bmp); memdc.Blit({ 0, 0 }, size, &dc, { 0, 0 }); { wxGCDC dc2(memdc); doRender(dc2); } memdc.SelectObject(wxNullBitmap); dc.DrawBitmap(bmp, 0, 0); #else doRender(dc); #endif } void FanOperate::doRender(wxDC& dc) { wxSize size = GetSize(); dc.SetPen(wxPen(DRAW_OPERATE_LINE_COLOUR)); dc.SetBrush(*wxTRANSPARENT_BRUSH); dc.DrawRoundedRectangle(0,0,size.x,size.y,5); //splt auto left_fir = size.x / 3; dc.DrawBitmap(m_bitmap_decrease.bmp(), 0, (size.y - m_bitmap_decrease.GetBmpHeight()) / 2); dc.DrawBitmap(m_bitmap_add.bmp(), size.x - m_bitmap_add.GetBmpWidth(), (size.y - m_bitmap_add.GetBmpSize().y) / 2); wxPoint pot(m_bitmap_decrease.GetBmpWidth(), (size.y - m_bitmap_decrease.GetBmpHeight()) / 2); dc.DrawLine(pot.x, 0, pot.x, size.y); dc.DrawLine(size.x - m_bitmap_add.GetBmpWidth(), 0, size.x - m_bitmap_add.GetBmpWidth(), size.y); //txt dc.SetFont(::Label::Body_12); dc.SetTextForeground(StateColor::darkModeColorFor(wxColour(0x898989))); wxString text = wxString::Format("%d%%", m_current_speeds * 10); wxSize text_size = dc.GetTextExtent(text); auto text_width = size.x - m_bitmap_decrease.GetBmpWidth() * 2; dc.DrawText(text, wxPoint(pot.x + (text_width - text_size.x) / 2, (size.y - text_size.y) / 2)); } void FanOperate::msw_rescale() { } static void nop_deleter_fan_control(FanControlNew* ){} /************************************************* Description:FanControlNew **************************************************/ FanControlNew::FanControlNew(wxWindow *parent, const AirDuctData &fan_data, int mode_id, int part_id, wxWindowID id, const wxPoint &pos, const wxSize &size) : wxWindow(parent, id, pos, size) , m_fan_data(fan_data) , m_mode_id(mode_id) , m_part_id(part_id) { SetMaxSize(wxSize(FromDIP(180), FromDIP(80))); SetMinSize(wxSize(FromDIP(180), FromDIP(80))); auto m_bitmap_fan = new ScalableBitmap(this, "fan_icon", 20); m_bitmap_toggle_off = new ScalableBitmap(this, "toggle_off", 16); m_bitmap_toggle_on = new ScalableBitmap(this, "toggle_on", 16); SetBackgroundColour(wxColour(248, 248, 248)); wxBoxSizer* m_sizer_main = new wxBoxSizer(wxHORIZONTAL); //m_sizer_main->Add(0, 0, 0, wxLEFT, FromDIP(18)); wxBoxSizer* sizer_control = new wxBoxSizer(wxVERTICAL); wxBoxSizer* sizer_control_top = new wxBoxSizer(wxHORIZONTAL); m_sizer_control_bottom = new wxBoxSizer(wxVERTICAL); auto m_static_bitmap_fan = new wxStaticBitmap(this, wxID_ANY, m_bitmap_fan->bmp(), wxDefaultPosition, wxDefaultSize); m_static_name = new wxStaticText(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END | wxALIGN_CENTER_HORIZONTAL); m_static_name->SetBackgroundColour(wxColour(248, 248, 248)); m_static_name->SetFont(Label::Head_18); m_static_name->SetMinSize(wxSize(FromDIP(100), -1)); m_static_name->SetMaxSize(wxSize(FromDIP(100), -1)); m_switch_button = new wxStaticBitmap(this, wxID_ANY, m_bitmap_toggle_off->bmp(), wxDefaultPosition, wxDefaultSize, 0); m_switch_button->Bind(wxEVT_ENTER_WINDOW, [this](auto& e) { SetCursor(wxCURSOR_HAND); }); m_switch_button->Bind(wxEVT_LEAVE_WINDOW, [this](auto& e) { SetCursor(wxCURSOR_RIGHT_ARROW); }); m_switch_button->Bind(wxEVT_LEFT_DOWN, &FanControlNew::on_swith_fan, this); sizer_control_top->Add(m_static_bitmap_fan, 0, wxLEFT | wxTOP, FromDIP(8)); sizer_control_top->Add(m_static_name, 0, wxLEFT | wxTOP, FromDIP(5)); sizer_control_top->Add(0, 0, 1, wxEXPAND, 0); sizer_control_top->Add(m_switch_button, 0, wxALIGN_RIGHT | wxRIGHT | wxTOP, FromDIP(10)); sizer_control->Add(sizer_control_top, 0, wxEXPAND, 0); m_static_status_name = new wxStaticText(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END | wxALIGN_CENTER_HORIZONTAL); m_static_status_name->SetForegroundColour(wxColour(0x00AE42)); m_static_status_name->SetBackgroundColour(wxColour(248, 248, 248)); m_static_status_name->SetFont(Label::Head_18); m_static_status_name->SetMinSize(wxSize(FromDIP(100), -1)); m_static_status_name->SetMaxSize(wxSize(FromDIP(100), -1)); m_fan_operate = new FanOperate(this, wxID_ANY, wxDefaultPosition, wxDefaultSize); m_fan_operate->Bind(EVT_FAN_SWITCH_ON, [this](const wxCommandEvent &e) { m_current_speed = e.GetInt(); m_switch_button->SetBitmap(m_bitmap_toggle_on->bmp()); m_switch_fan = true; }); m_fan_operate->Bind(EVT_FAN_SWITCH_OFF, [this](const wxCommandEvent &e) { m_current_speed = e.GetInt(); m_switch_button->SetBitmap(m_bitmap_toggle_off->bmp()); m_switch_fan = false; }); m_fan_operate->Bind(EVT_FAN_ADD, [this](const wxCommandEvent &e) { m_current_speed = e.GetInt(); command_control_fan(); }); m_fan_operate->Bind(EVT_FAN_DEC, [this](const wxCommandEvent& e) { m_current_speed = e.GetInt(); command_control_fan(); }); m_sizer_control_bottom->Add(m_static_status_name, 0, wxALL, FromDIP(10)); m_sizer_control_bottom->Add(m_fan_operate, 0, wxALL, FromDIP(10)); sizer_control->Add(m_sizer_control_bottom, 0, wxALL, 0); m_sizer_main->Add(sizer_control, 0, wxALIGN_CENTER, 0); update_mode(); #if __APPLE__ Bind(wxEVT_LEFT_DOWN, &FanControlNew::on_left_down, this); #endif this->SetSizer(m_sizer_main); this->Layout(); m_sizer_main->Fit(this); wxGetApp().UpdateDarkUIWin(this); } void FanControlNew::on_left_down(wxMouseEvent& evt) { //auto mouse_pos = GetParent()->ClientToScreen(evt.GetPosition()); //auto tag_pos = m_fan_operate->ScreenToClient(mouse_pos); //evt.SetPosition(tag_pos); m_fan_operate->on_left_down(evt); } void FanControlNew::command_control_fan() { if (m_current_speed < 0 || m_current_speed > 10) { return; } BOOST_LOG_TRIVIAL(info) << "Functions Need to be supplemented! :FanControlNew::command_control_fan. the speed may change"; if (m_obj) { if (!m_obj->is_enable_np){ int speed = floor(m_current_speed * float(25.5)); m_obj->command_control_fan(m_part_id, speed); } else { m_obj->command_control_fan_new(m_part_id, m_current_speed * 10, nullptr); } post_event(); } } void FanControlNew::on_swith_fan(wxMouseEvent& evt) { if (m_obj && m_obj->is_in_printing()) { MessageDialog msg_wingow(nullptr, _L("Changed fan speed during pringing may affect print quality, please choose carefully."), "", wxICON_WARNING | wxCANCEL | wxOK); if (msg_wingow.ShowModal() == wxID_CANCEL) { return; } } int speed = 0; if (m_switch_fan) { m_switch_button->SetBitmap(m_bitmap_toggle_off->bmp()); m_switch_fan = false; } else { speed = 255; m_switch_button->SetBitmap(m_bitmap_toggle_on->bmp()); m_switch_fan = true; } set_fan_speed(speed); command_control_fan(); } void FanControlNew::on_swith_fan(bool on) { m_switch_fan = on; if (m_switch_fan) { m_switch_button->SetBitmap(m_bitmap_toggle_on->bmp()); } else { m_switch_button->SetBitmap(m_bitmap_toggle_off->bmp()); } } void FanControlNew::update_mode() { int cur_mode = m_mode_id; if (cur_mode < 0) { m_static_status_name->Hide(); m_fan_operate->Show(); } else { auto mode = m_fan_data.modes[cur_mode]; auto it = std::find(mode.off.begin(), mode.off.end(), m_part_id); if (it != mode.off.end()) { m_show_mode = 2; m_static_status_name->SetLabelText(_L("Off")); } else { auto it_ctrl = std::find(mode.ctrl.begin(), mode.ctrl.end(), m_part_id); if (it_ctrl == mode.ctrl.end()) { m_show_mode = 1; m_static_status_name->SetLabelText(_L("Auto")); } else { m_show_mode = 0; } } if (m_show_mode == 0) { m_static_status_name->Hide(); m_switch_button->Show(); m_fan_operate->Show(); } else { m_static_status_name->Show(); m_switch_button->Hide(); m_fan_operate->Hide(); } } } void FanControlNew::set_machine_obj(MachineObject* obj) { m_update_already = true; m_obj = obj; if (m_fan_operate) m_fan_operate->set_machine_obj(obj); } void FanControlNew::set_name(wxString name) { m_static_name->SetLabelText(name); } void FanControlNew::set_fan_speed(int g) { if (g < 0 || g > 255) return; int speed = round(float(g) / float(25.5)); if (m_current_speed != speed) { m_current_speed = speed; m_fan_operate->set_fan_speeds(m_current_speed); if (m_current_speed <= 0) { on_swith_fan(false); } else { on_swith_fan(true); } } } void FanControlNew::set_fan_speed_percent(int speed) { if (m_current_speed != speed) { m_current_speed = speed; m_fan_operate->set_fan_speeds(m_current_speed); if (m_current_speed <= 0) { on_swith_fan(false); } else { on_swith_fan(true); } } } void FanControlNew::set_fan_switch(bool s) { } void FanControlNew::post_event() { auto event = wxCommandEvent(EVT_FAN_CHANGED); event.SetString(wxString::Format("%d", m_current_speed)); event.SetEventObject(GetParent()); wxPostEvent(GetParent(), event); event.Skip(); } /************************************************* Description:FanControlPopupNew **************************************************/ static void nop_deleter_fan_control_popup(FanControlPopupNew *) {} FanControlPopupNew::FanControlPopupNew(wxWindow* parent, MachineObject* obj, const AirDuctData& data) : PopupWindow(parent, wxBORDER_NONE) { SetBackgroundColour(*wxWHITE); init_names(); m_data = data; m_obj = obj; m_sizer_main = new wxBoxSizer(wxVERTICAL); int part_size = data.parts.size(); int grid_column = part_size > 1 ? 2 : 1; m_radio_btn_sizer = new wxGridSizer(0, 2, FromDIP(3), FromDIP(3)); m_sizer_fanControl = new wxGridSizer(0, grid_column, FromDIP(3), FromDIP(10)); m_mode_sizer = new wxBoxSizer(wxHORIZONTAL); m_button_refresh = new Button(this, wxString(""), "fan_poppingup_refresh", 0, 24); m_button_refresh->SetBackgroundColor(*wxWHITE); m_button_refresh->SetBorderColor(*wxWHITE); m_button_refresh->SetMinSize(wxSize(FromDIP(26), FromDIP(26))); m_button_refresh->SetMaxSize(wxSize(FromDIP(26), FromDIP(26))); m_button_refresh->Bind(wxEVT_ENTER_WINDOW, [this](const auto &e) { SetCursor(wxCURSOR_HAND); }); m_button_refresh->Bind(wxEVT_LEAVE_WINDOW, [this](const auto &e) { SetCursor(wxCURSOR_ARROW); }); m_button_refresh->Bind(wxEVT_LEFT_DOWN, [this](const auto &e) { CreateDuct(); Layout(); Fit(); }); m_mode_sizer->Add(m_radio_btn_sizer, 0, wxALIGN_CENTRE_VERTICAL, 0); m_mode_sizer->Add(m_button_refresh, 0, wxALIGN_CENTRE_VERTICAL, 0); m_button_refresh->Hide(); m_cooling_text = new wxStaticText(this, wxID_ANY, wxT("")); m_cooling_text->SetBackgroundColour(*wxWHITE); //Control the show or hide of controls based on id m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(23)); m_sizer_main->Add(m_mode_sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT, FromDIP(30)); m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(10)); m_sizer_main->Add(m_cooling_text, 0, wxLEFT | wxRIGHT, FromDIP(30)); m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(10)); m_sizer_main->Add(m_sizer_fanControl, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT, 0); m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(16)); CreateDuct(); SetSizer(m_sizer_main); Layout(); Fit(); this->Centre(wxBOTH); Bind(wxEVT_PAINT, &FanControlPopupNew::paintEvent, this); #if __APPLE__ Bind(wxEVT_LEFT_DOWN, &FanControlPopupNew::on_left_down, this); #endif #ifdef __WXOSX__ Bind(wxEVT_IDLE, [](wxIdleEvent& evt) {}); #endif Bind(wxEVT_SHOW, &FanControlPopupNew::on_show, this); Bind(EVT_FAN_CHANGED, &FanControlPopupNew::on_fan_changed, this); } void FanControlPopupNew::CreateDuct() { m_radio_btn_sizer->Clear(true); m_mode_switch_btn_list.clear(); //tips UpdateTips(m_data.curren_mode); //fan or door UpdateParts(m_data.curren_mode); if (m_data.modes.empty()) { //m_button_refresh->Hide(); return; } size_t mode_size = m_data.modes.size(); for (auto i = 0; i < mode_size; i++) { wxString text = wxString::Format("%s", radio_btn_name[AIR_DUCT(m_data.modes[i].id)]); SendModeSwitchButton *radio_btn = new SendModeSwitchButton(this, text, m_data.curren_mode == m_data.modes[i].id); radio_btn->Bind(wxEVT_LEFT_DOWN, &FanControlPopupNew::on_mode_changed, this); m_mode_switch_btn_list.emplace_back(radio_btn); m_radio_btn_sizer->Add(radio_btn, wxALL, FromDIP(5)); } } void FanControlPopupNew::UpdateParts(int mode_id) { m_sizer_fanControl->Clear(true); for (const auto& part : m_data.parts) { auto part_id = part.id; auto part_func = part.func; auto part_name = fan_func_name[AIR_FUN(part_id)]; auto part_state = part.state; auto fan_control = new FanControlNew(this, m_data, mode_id, part_id, wxID_ANY, wxDefaultPosition, wxDefaultSize); fan_control->set_machine_obj(m_obj); fan_control->set_name(part_name); m_fan_control_list[part_id] = fan_control; m_sizer_fanControl->Add(fan_control, 0, wxALL, FromDIP(5)); } m_sizer_fanControl->Layout(); } void FanControlPopupNew::UpdateTips(int model) { auto text = label_text[AIR_DUCT(model)]; m_cooling_text->SetLabelText(text); m_cooling_text->Wrap(FromDIP(400)); Layout(); } void FanControlPopupNew::update_fan_data(MachineObject *obj) { if (!obj) return; if (obj->is_enable_np) { if (m_fan_set_time_out > 0) { m_fan_set_time_out--; return; } update_fan_data(obj->m_air_duct_data); } else { if (m_fan_set_time_out > 0) { m_fan_set_time_out--; return; } int cooling_fan_speed = round(obj->cooling_fan_speed / float(25.5)); int big_fan1_speed = round(obj->big_fan1_speed / float(25.5)); int big_fan2_speed = round(obj->big_fan2_speed / float(25.5)); update_fan_data(AIR_FUN::FAN_COOLING_0_AIRDOOR, cooling_fan_speed); update_fan_data(AIR_FUN::FAN_REMOTE_COOLING_0_IDX, big_fan1_speed); update_fan_data(AIR_FUN::FAN_CHAMBER_0_IDX, big_fan2_speed); } } void FanControlPopupNew::update_fan_data(const AirDuctData &data) { m_data = data; for (const auto& part : m_data.parts) { auto part_id = part.id; auto part_func = part.func; auto part_name = fan_func_name[AIR_FUN(part_id)]; auto part_state = part.state; auto it = m_fan_control_list.find(part_id); if (it != m_fan_control_list.end()) { auto fan_control = m_fan_control_list[part_id]; fan_control->set_fan_speed_percent(part_state / 10); } } } void FanControlPopupNew::update_fan_data(AIR_FUN id, int speed) { for (auto& part : m_data.parts) { auto part_id = part.id; auto part_func = part.func; auto part_name = fan_func_name[AIR_FUN(part_id)]; if (id == part_id) { part.state = speed; auto it = m_fan_control_list.find(part_id); if (it != m_fan_control_list.end()) { auto fan_control = m_fan_control_list[part_id]; fan_control->update_mode(); fan_control->set_fan_speed_percent(speed); } } } } // device change void FanControlPopupNew::update_device(AirDuctData data, MachineObject* obj) { //for (int i = 0; i < data.airducts.size(); i++){ // auto duct = data.airducts[i]; // if (m_fan_control_list.find(duct.airduct_id) == m_fan_control_list.end()) // CreateDuct(duct); // else{ // auto fan_list = m_fan_control_list[duct.airduct_id]; // for (auto fan : duct.fans_list){ // if (fan_list.find(fan.id) == fan_list.end()) // CreateFanAndDoor(duct.airduct_id, fan); // else{ // auto fan_control = fan_list[fan.id]; // fan_control->update_fan_data(fan); // } // } // } // m_duct_ctrl[duct.airduct_id] = duct.fans_ctrl[i]; //} //m_data = data; //for (auto fan_list_of_duct : m_fan_control_list){ // for (auto fan : fan_list_of_duct.second){ // if (fan.second != nullptr) // fan.second->set_machine_obj(obj); // } //} ////auto text = wxString::Format("%s", radio_btn_name[AIR_DUCT_mode_e(m_data.curren_duct)]); //auto text = wxT("The fan controls the temperature during printing to improve print quality.The system automatically adjusts the fan's switch and speed according to dif"); //m_cooling_text->SetLabelText(text); //m_cooling_text->Wrap(FromDIP(360)); //ChangeCoolingTips(m_data.airducts.size()); //if (data.airducts.size() <= 1) // m_radio_btn_sizer->Show(false); //else // m_radio_btn_sizer->Show(true); //this->Layout(); //Bind(EVT_FAN_CHANGED, [this](wxCommandEvent& e) { // post_event(e.GetInt(), e.GetString()); // }); } void FanControlPopupNew::on_left_down(wxMouseEvent& evt) { auto mouse_pos = ClientToScreen(evt.GetPosition()); for (SendModeSwitchButton* sw_it : m_mode_switch_btn_list) { auto win_pos = sw_it->ClientToScreen(wxPoint(0, 0)); auto size = sw_it->GetSize(); if (mouse_pos.x > win_pos.x && mouse_pos.x < (win_pos.x + sw_it->GetSize().x) && mouse_pos.y > win_pos.y && mouse_pos.y < (win_pos.y + sw_it->GetSize().y)) { evt.SetId(sw_it->GetId()); on_mode_changed(evt); } } for (auto fan_it : m_fan_control_list){ auto fan = fan_it.second; auto win_pos = fan->m_switch_button->ClientToScreen(wxPoint(0, 0)); auto size = fan->m_switch_button->GetSize(); if (mouse_pos.x > win_pos.x && mouse_pos.x < (win_pos.x + fan->m_switch_button->GetSize().x) && mouse_pos.y > win_pos.y && mouse_pos.y < (win_pos.y + fan->m_switch_button->GetSize().y)) { fan->on_swith_fan(evt); } fan->on_left_down(evt); } evt.Skip(); } void FanControlPopupNew::OnDismiss() { } void FanControlPopupNew::post_event(int fan_type, wxString speed) { // id, speed wxCommandEvent event(EVT_FAN_CHANGED); event.SetInt(fan_type); event.SetString(speed); event.SetEventObject(GetParent()); wxPostEvent(GetParent(), event); event.Skip(); } bool FanControlPopupNew::ProcessLeftDown(wxMouseEvent& event) { return PopupWindow::ProcessLeftDown(event); } void FanControlPopupNew::on_show(wxShowEvent& evt) { wxGetApp().UpdateDarkUIWin(this); } void FanControlPopupNew::command_control_air_duct(int mode_id) { m_air_duct_time_out = time_out; token.reset(this, nop_deleter_fan_control_popup); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", control air duct, id = " << mode_id; if (m_obj) { m_obj->command_control_air_duct(mode_id, [this, w = std::weak_ptr(token), mode_id](const json& reply) { if (w.expired()) return; m_air_duct_time_out = 0; if (reply.contains("errno")) { int result = reply["errno"].get(); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", control air duct, errno = " << result; if (result == 0) { int update_id = mode_id; if (reply.contains("modeId")) { update_id = reply["modeId"].get(); this->UpdateParts(update_id); this->UpdateTips(update_id); } } this->Layout(); this->Refresh(); } }); } } void FanControlPopupNew::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 FanControlPopupNew::on_mode_changed(const wxMouseEvent &event) { if (m_obj && m_obj->is_in_printing()) { MessageDialog msg_wingow(nullptr, _L("The selected material only supports the current fan mode, and it can't be changed during printing."), "", wxICON_WARNING | wxOK); msg_wingow.ShowModal(); return; } size_t btn_list_size = m_mode_switch_btn_list.size(); for (size_t i = 0; i < btn_list_size; ++i) { if (m_mode_switch_btn_list[i]->GetId() == event.GetId()) { if (m_mode_switch_btn_list[i]->isSelected()) return; m_mode_switch_btn_list[i]->setSelected(true); command_control_air_duct(i); } else { m_mode_switch_btn_list[i]->setSelected(false); } } } void FanControlPopupNew::on_fan_changed(const wxCommandEvent &event) { m_fan_set_time_out = time_out; } void FanControlPopupNew::init_names() { //Iint fan/door/func/duct name lists radio_btn_name[AIR_DUCT::AIR_DUCT_COOLING_FILT] = _L("Cooling"); radio_btn_name[AIR_DUCT::AIR_DUCT_HEATING_INTERNAL_FILT] = _L("Heating"); radio_btn_name[AIR_DUCT::AIR_DUCT_EXHAUST] = _L("Exhaust"); radio_btn_name[AIR_DUCT::AIR_DUCT_FULL_COOLING] = _L("Full Cooling"); radio_btn_name[AIR_DUCT::AIR_DUCT_NUM] = L("Num?"); radio_btn_name[AIR_DUCT::AIR_DUCT_INIT] = L("Init"); fan_func_name[AIR_FUN::FAN_HEAT_BREAK_0_IDX] = _L("Hotend"); fan_func_name[AIR_FUN::FAN_COOLING_0_AIRDOOR] = _L("Part"); fan_func_name[AIR_FUN::FAN_REMOTE_COOLING_0_IDX] = _L("Aux"); fan_func_name[AIR_FUN::FAN_CHAMBER_0_IDX] = _L("Exhaust"); fan_func_name[AIR_FUN::FAN_HEAT_BREAK_1_IDX] = _L("Nozzle1"); fan_func_name[AIR_FUN::FAN_MC_BOARD_0_IDX] = _L("MC Board"); fan_func_name[AIR_FUN::FAN_INNNER_LOOP_FAN_0_IDX] = _L("Heat"); air_door_func_name[AIR_DOOR::AIR_DOOR_FUNC_CHAMBER] = _L("Chamber"); air_door_func_name[AIR_DOOR::AIR_DOOR_FUNC_INNERLOOP] = _L("Innerloop"); air_door_func_name[AIR_DOOR::AIR_DOOR_FUNC_TOP] = L("Top");/*UNUSED*/ label_text[AIR_DUCT::AIR_DUCT_NONE] = _L("The fan controls the temperature during printing to improve print quality." "The system automatically adjusts the fan's switch and speed " "according to different printing materials."); label_text[AIR_DUCT::AIR_DUCT_COOLING_FILT] = _L("Cooling mode is suitable for printing PLA/PETG/TPU materials and filters the chamber air."); label_text[AIR_DUCT::AIR_DUCT_HEATING_INTERNAL_FILT] = _L("Heating mode is suitable for printeing ABS/ASA/PC/PA materials and circulates filters the chamber air."); label_text[AIR_DUCT::AIR_DUCT_EXHAUST] = _L("Exhaust"); label_text[AIR_DUCT::AIR_DUCT_FULL_COOLING] = _L("Strong cooling mode is suitable for printing PLA/TPU materials. In this mode, the printouts will be fully cooled."); label_text[AIR_DUCT::AIR_DUCT_NUM] = _L("Num"); label_text[AIR_DUCT::AIR_DUCT_INIT] = _L("Init"); /*label_text[AIR_DUCT_mode_e::AIR_DUCT_NONE] = "..."; label_text[AIR_DUCT_mode_e::AIR_DUCT_COOLING_FILT] = "..."; label_text[AIR_DUCT_mode_e::AIR_DUCT_HEATING_INTERNAL_FILT] = "..."; label_text[AIR_DUCT_mode_e::AIR_DUCT_EXHAUST] = "Exhaust"; label_text[AIR_DUCT_mode_e::AIR_DUCT_FULL_COOLING] = "..."; label_text[AIR_DUCT_mode_e::AIR_DUCT_NUM] = "Num"; label_text[AIR_DUCT_mode_e::AIR_DUCT_INIT] = "Init";*/ } }} // namespace Slic3r::GUI