From 75da1db2f926125a0cb3595a8cae9f4d7588c6a8 Mon Sep 17 00:00:00 2001 From: "xin.zhang" Date: Fri, 21 Feb 2025 15:57:10 +0800 Subject: [PATCH] FIX: The humidity popup with humidity_percent/temperature/dry_time jira: [STUDIO-9268] Change-Id: Ic6e923ae7cff56fa3e053d48e5dea6e393cd41eb --- bbl/i18n/list.txt | 4 + src/slic3r/GUI/DeviceManager.cpp | 14 ++ src/slic3r/GUI/DeviceManager.hpp | 2 + src/slic3r/GUI/DeviceTab/CMakeLists.txt | 2 + .../GUI/DeviceTab/uiAmsHumidityPopup.cpp | 238 ++++++++++++++++++ src/slic3r/GUI/DeviceTab/uiAmsHumidityPopup.h | 70 ++++++ src/slic3r/GUI/Widgets/AMSControl.cpp | 37 ++- src/slic3r/GUI/Widgets/AMSControl.hpp | 4 + src/slic3r/GUI/Widgets/AMSItem.cpp | 11 +- src/slic3r/GUI/Widgets/AMSItem.hpp | 2 + 10 files changed, 376 insertions(+), 8 deletions(-) create mode 100644 src/slic3r/GUI/DeviceTab/uiAmsHumidityPopup.cpp create mode 100644 src/slic3r/GUI/DeviceTab/uiAmsHumidityPopup.h diff --git a/bbl/i18n/list.txt b/bbl/i18n/list.txt index 1044beb49..f7067dd62 100644 --- a/bbl/i18n/list.txt +++ b/bbl/i18n/list.txt @@ -1,3 +1,7 @@ +src/slic3r/GUI/DeviceTab/uiAmsHumidityPopup.h +src/slic3r/GUI/DeviceTab/uiAmsHumidityPopup.cpp +src/slic3r/GUI/DeviceTab/uiDeviceUpdateVersion.h +src/slic3r/GUI/DeviceTab/uiDeviceUpdateVersion.cpp src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp diff --git a/src/slic3r/GUI/DeviceManager.cpp b/src/slic3r/GUI/DeviceManager.cpp index 0230efafe..8fe89f440 100644 --- a/src/slic3r/GUI/DeviceManager.cpp +++ b/src/slic3r/GUI/DeviceManager.cpp @@ -4472,6 +4472,20 @@ int MachineObject::parse_json(std::string payload, bool key_field_only) } } + + if (it->contains("temp")) + { + std::string temp = (*it)["temp"].get(); + try + { + curr_ams->current_temperature = string_to_float(temp); + } + catch (...) + { + curr_ams->current_temperature = INVALID_AMS_TEMPERATURE; + } + } + if (it->contains("tray")) { std::set tray_id_set; for (auto it = curr_ams->trayList.begin(); it != curr_ams->trayList.end(); it++) { diff --git a/src/slic3r/GUI/DeviceManager.hpp b/src/slic3r/GUI/DeviceManager.hpp index 91c14222d..94c6277cf 100644 --- a/src/slic3r/GUI/DeviceManager.hpp +++ b/src/slic3r/GUI/DeviceManager.hpp @@ -353,6 +353,7 @@ public: std::string get_filament_type(); }; +#define INVALID_AMS_TEMPERATURE std::numeric_limits::min() class Ams { public: @@ -365,6 +366,7 @@ public: int left_dry_time = 0; int humidity = 5; int humidity_raw = -1;// the percentage, -1 means invalid. eg. 100 means 100% + float current_temperature = INVALID_AMS_TEMPERATURE; // the temperature bool startup_read_opt{true}; bool tray_read_opt{false}; bool is_exists{false}; diff --git a/src/slic3r/GUI/DeviceTab/CMakeLists.txt b/src/slic3r/GUI/DeviceTab/CMakeLists.txt index 455f92ff6..2d62d59a0 100644 --- a/src/slic3r/GUI/DeviceTab/CMakeLists.txt +++ b/src/slic3r/GUI/DeviceTab/CMakeLists.txt @@ -4,6 +4,8 @@ # status -- Building list(APPEND SLIC3R_GUI_SOURCES + GUI/DeviceTab/uiAmsHumidityPopup.h + GUI/DeviceTab/uiAmsHumidityPopup.cpp GUI/DeviceTab/uiDeviceUpdateVersion.h GUI/DeviceTab/uiDeviceUpdateVersion.cpp ) diff --git a/src/slic3r/GUI/DeviceTab/uiAmsHumidityPopup.cpp b/src/slic3r/GUI/DeviceTab/uiAmsHumidityPopup.cpp new file mode 100644 index 000000000..f9c14ba01 --- /dev/null +++ b/src/slic3r/GUI/DeviceTab/uiAmsHumidityPopup.cpp @@ -0,0 +1,238 @@ +//**********************************************************/ +/* File: uiAmsHumidityPopup.cpp +* Description: The popup with Ams Humidity +* +* \n class uiAmsHumidityPopup +//**********************************************************/ + +#include "uiAmsHumidityPopup.h" + +#include "slic3r/Utils/WxFontUtils.hpp" + +#include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/GUI/I18N.hpp" +#include "slic3r/GUI/Widgets/StateColor.hpp" + + +#include + +namespace Slic3r { namespace GUI { + +uiAmsPercentHumidityDryPopup::uiAmsPercentHumidityDryPopup(wxWindow *parent) + : PopupWindow(parent, wxBORDER_NONE) +{ + SetSize(wxSize(FromDIP(400), FromDIP(270))); + SetMinSize(wxSize(FromDIP(400), FromDIP(270))); + SetMaxSize(wxSize(FromDIP(400), FromDIP(270))); + + idle_img = ScalableBitmap(this, "ams_drying", 16); + drying_img = ScalableBitmap(this, "ams_is_drying", 16); + close_img = ScalableBitmap(this, "hum_popup_close", 24); + + Bind(wxEVT_PAINT, &uiAmsPercentHumidityDryPopup::paintEvent, this); + Bind(wxEVT_LEFT_UP, [this](auto &e) { + auto rect = ClientToScreen(wxPoint(0, 0)); + + auto close_left = rect.x + GetSize().x - close_img.GetBmpWidth() - FromDIP(38); + auto close_right = close_left + close_img.GetBmpWidth(); + auto close_top = rect.y + FromDIP(24); + auto close_bottom = close_top + close_img.GetBmpHeight(); + + auto mouse_pos = ClientToScreen(e.GetPosition()); + if (mouse_pos.x > close_left && mouse_pos.y > close_top && mouse_pos.x < close_right && mouse_pos.y < close_bottom) { Dismiss(); } + }); +} + +void uiAmsPercentHumidityDryPopup::Update(int humidiy_level, int humidity_percent, int left_dry_time, float current_temperature) +{ + if (m_humidity_level != humidiy_level || m_humidity_percent != humidity_percent || + m_left_dry_time != left_dry_time || m_current_temperature != current_temperature) + { + m_humidity_level = humidiy_level; + m_humidity_percent = humidity_percent; + m_left_dry_time = left_dry_time; + m_current_temperature = current_temperature; + + Refresh(); + } +} + +void uiAmsPercentHumidityDryPopup::paintEvent(wxPaintEvent &evt) +{ + wxPaintDC dc(this); + render(dc); +} + +void uiAmsPercentHumidityDryPopup::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 uiAmsPercentHumidityDryPopup::doRender(wxDC &dc) +{ + // background + { + dc.SetPen(StateColor::darkModeColorFor(*wxWHITE)); + dc.SetBrush(*wxTRANSPARENT_BRUSH); + dc.DrawRoundedRectangle(0, 0, GetSize().x, GetSize().y, 0); + } + + wxPoint p; + + // Header + { + dc.SetFont(::Label::Head_24); + dc.SetTextForeground(StateColor::darkModeColorFor(*wxBLACK)); + WxFontUtils::get_suitable_font_size(FromDIP(24), dc); + + auto extent = dc.GetTextExtent(_L("Current AMS humidity")); + dc.DrawText(_L("Current AMS humidity"), (GetSize().GetWidth() - extent.GetWidth()) / 2, FromDIP(24)); + } + + // close icon + p.y += FromDIP(24); + dc.DrawBitmap(close_img.bmp(), GetSize().x - close_img.GetBmpWidth() - FromDIP(38), p.y); + + // humitidy image + if (0 < m_humidity_level && m_humidity_level < 6) + { + ScalableBitmap humitidy_image; + if (wxGetApp().dark_mode()) + { + humitidy_image = ScalableBitmap(this, "hum_level" + std::to_string(m_humidity_level) + "_no_num_light", 64); + } + else + { + humitidy_image = ScalableBitmap(this, "hum_level" + std::to_string(m_humidity_level) + "_no_num_light", 64); + } + + p.y += 2 * FromDIP(24); + dc.DrawBitmap(humitidy_image.bmp(), (GetSize().GetWidth() - humitidy_image.GetBmpWidth()) / 2, p.y); + p.y += humitidy_image.GetBmpHeight(); + } + + // dry state + int spacing = FromDIP(5); + { + p.y += spacing; + if (m_left_dry_time > 0) + { + dc.DrawBitmap(drying_img.bmp(), GetSize().GetWidth() / 2 - drying_img.GetBmpWidth() - spacing, p.y); + } + else + { + dc.DrawBitmap(idle_img.bmp(), GetSize().GetWidth() / 2 - idle_img.GetBmpWidth() - spacing, p.y); + } + + dc.SetFont(::Label::Body_14); + WxFontUtils::get_suitable_font_size(idle_img.GetBmpHeight(), dc); + + const wxString &dry_state = (m_left_dry_time > 0) ? _L("Drying") : _L("Idle"); + auto dry_state_extent = dc.GetTextExtent(dry_state); + + p.y += (idle_img.GetBmpHeight() - dry_state_extent.GetHeight());//align bottom + dc.DrawText(dry_state, GetSize().GetWidth() / 2 + spacing, p.y); + p.y += dry_state_extent.GetHeight(); + } + + // Grid area + { + p.y += 2 * spacing; + DrawGridArea(dc, p); + } +} + + +static vector grid_header{ L("Humidity"), L("Temperature"), L("Left Time")}; +void uiAmsPercentHumidityDryPopup::DrawGridArea(wxDC &dc, wxPoint start_p) +{ + const wxColour& gray_clr = StateColor::darkModeColorFor(wxColour(194, 194, 194)); + const wxColour& black_clr = StateColor::darkModeColorFor(*wxBLACK); + + // Horizontal line + dc.SetPen(gray_clr); + int h_margin = FromDIP(20); + dc.DrawLine(h_margin, start_p.y, GetSize().GetWidth() - h_margin, start_p.y); + start_p.x = h_margin; + start_p.y += h_margin; + + // Draw grid area + int toltal_col; + if (m_left_dry_time > 0) + { + toltal_col = 3; + } + else + { + toltal_col = 2; + } + + int row_height = FromDIP(30); + int text_height = FromDIP(20); + int distance = (GetSize().GetWidth() - 2 * h_margin)/ toltal_col; + for (int col = 0; col < toltal_col; ++col) + { + const wxString& header = _L(grid_header[col]); + dc.SetFont(::Label::Body_14); + WxFontUtils::get_suitable_font_size(text_height, dc); + const auto &header_extent = dc.GetTextExtent(header); + + int left = start_p.x + (distance - header_extent.GetWidth()) / 2; + dc.SetPen(gray_clr); + dc.DrawText(header, left, start_p.y); + + // row content + dc.SetPen(black_clr); + if (header == _L("Humidity")) + { + const wxString &humidity_str = wxString::Format("%d%%", m_humidity_percent); + dc.DrawText(humidity_str, left, start_p.y + row_height); + } + else if (header == _L("Temperature")) + { + const wxString &temp_str = wxString::Format(_L("%.1f \u2103"), m_current_temperature); + dc.DrawText(temp_str, left, start_p.y + row_height); + } + else if (header == _L("Left Time")) + { + const wxString &time_str = wxString::Format(_L("%d Hours"), m_left_dry_time); + dc.DrawText(time_str, left, start_p.y + row_height); + } + + start_p.x += distance; + if (col < toltal_col - 1) /*draw splitter*/ + { + dc.SetPen(gray_clr); + dc.DrawLine(start_p.x, start_p.y, start_p.x, start_p.y + 2 * row_height); + } + } +} + +void uiAmsPercentHumidityDryPopup::msw_rescale() +{ + idle_img.msw_rescale(); + drying_img.msw_rescale(); + close_img.msw_rescale(); + + Refresh(); +} + +} // namespace GUI + +} // namespace Slic3r \ No newline at end of file diff --git a/src/slic3r/GUI/DeviceTab/uiAmsHumidityPopup.h b/src/slic3r/GUI/DeviceTab/uiAmsHumidityPopup.h new file mode 100644 index 000000000..e3a092e9c --- /dev/null +++ b/src/slic3r/GUI/DeviceTab/uiAmsHumidityPopup.h @@ -0,0 +1,70 @@ +//**********************************************************/ +/* File: uiAmsHumidityPopup.h +* Description: The popup with Ams Humidity +* +* \n class uiAmsHumidityPopup +//**********************************************************/ + +#pragma once +#include "slic3r/GUI/Widgets/Label.hpp" +#include "slic3r/GUI/Widgets/PopupWindow.hpp" + +#include "slic3r/GUI/wxExtensions.hpp" + +//Previous defintions +class wxGrid; + +namespace Slic3r { namespace GUI { + +struct uiAmsHumidityInfo +{ + int humidity_level = -1; + int humidity_percent = -1; + float current_temperature; + int left_dry_time = -1; +}; + +/// +/// Note: The popup of Ams Humidity with percentage and dry time +/// Author: xin.zhang +/// +class uiAmsPercentHumidityDryPopup : public PopupWindow +{ +public: + uiAmsPercentHumidityDryPopup(wxWindow *parent); + ~uiAmsPercentHumidityDryPopup() = default; + +public: + void Update(uiAmsHumidityInfo *info) { Update(info->humidity_level, info->humidity_percent, info->left_dry_time, info->current_temperature); }; + + virtual void OnDismiss() wxOVERRIDE {}; + virtual bool ProcessLeftDown(wxMouseEvent &event) wxOVERRIDE { return true;}; + + void msw_rescale(); + +private: + void Update(int humidiy_level, int humidity_percent, int left_dry_time, float current_temperature); + + void paintEvent(wxPaintEvent &evt); + void render(wxDC &dc); + void doRender(wxDC &dc); + + void DrawGridArea(wxDC &dc, wxPoint start_p); + +private: + int m_humidity_level = 0; + int m_humidity_percent = 0; + int m_left_dry_time = 0; + float m_current_temperature = 0; + + // Bitmap + ScalableBitmap close_img; + ScalableBitmap drying_img; + ScalableBitmap idle_img; + + // Widgets + wxStaticBitmap* m_humidity_img; + wxGrid* m_grid_area; +}; + +}} // namespace Slic3r::GUI \ No newline at end of file diff --git a/src/slic3r/GUI/Widgets/AMSControl.cpp b/src/slic3r/GUI/Widgets/AMSControl.cpp index 7fa0607c2..1f28cc17f 100644 --- a/src/slic3r/GUI/Widgets/AMSControl.cpp +++ b/src/slic3r/GUI/Widgets/AMSControl.cpp @@ -4,6 +4,8 @@ #include "../I18N.hpp" #include "../GUI_App.hpp" +#include "slic3r/GUI/DeviceTab/uiAmsHumidityPopup.h" + #include #include @@ -2418,6 +2420,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_percent_humidity_dry_popup(new uiAmsPercentHumidityDryPopup(this)) , m_ams_introduce_popup(AmsIntroducePopup(this)) { Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager(); @@ -2667,15 +2670,31 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons }); Bind(EVT_AMS_SHOW_HUMIDITY_TIPS, [this](wxCommandEvent& evt) { + uiAmsHumidityInfo *info = (uiAmsHumidityInfo *) evt.GetClientData(); + if (info) + { + if (info->humidity_percent >= 0) + { + m_percent_humidity_dry_popup->Update(info); - wxPoint img_pos = ClientToScreen(wxPoint(0, 0)); - wxPoint popup_pos(img_pos.x - m_Humidity_tip_popup.GetSize().GetWidth() + FromDIP(150), img_pos.y - FromDIP(80)); - m_Humidity_tip_popup.Position(popup_pos, wxSize(0, 0)); - int humidity_value = evt.GetInt(); - if (humidity_value > 0 && humidity_value <= 5) { - m_Humidity_tip_popup.set_humidity_level(humidity_value); + wxPoint img_pos = ClientToScreen(wxPoint(0, 0)); + wxPoint popup_pos(img_pos.x - m_percent_humidity_dry_popup->GetSize().GetWidth() + FromDIP(150), img_pos.y - FromDIP(80)); + m_percent_humidity_dry_popup->Position(popup_pos, wxSize(0, 0)); + m_percent_humidity_dry_popup->Popup(); + } + else + { + wxPoint img_pos = ClientToScreen(wxPoint(0, 0)); + wxPoint popup_pos(img_pos.x - m_Humidity_tip_popup.GetSize().GetWidth() + FromDIP(150), img_pos.y - FromDIP(80)); + m_Humidity_tip_popup.Position(popup_pos, wxSize(0, 0)); + + int humidity_value = info->humidity_level; + if (humidity_value > 0 && humidity_value <= 5) { m_Humidity_tip_popup.set_humidity_level(humidity_value); } + m_Humidity_tip_popup.Popup(); + } } - m_Humidity_tip_popup.Popup(); + + delete info; }); Bind(EVT_AMS_ON_SELECTED, &AMSControl::AmsSelectedSwitch, this); } @@ -2893,6 +2912,10 @@ void AMSControl::msw_rescale() m_down_road->msw_rescale(); } + if (m_percent_humidity_dry_popup){ + m_percent_humidity_dry_popup->msw_rescale(); + } + Layout(); Refresh(); } diff --git a/src/slic3r/GUI/Widgets/AMSControl.hpp b/src/slic3r/GUI/Widgets/AMSControl.hpp index ff7b88585..20d867333 100644 --- a/src/slic3r/GUI/Widgets/AMSControl.hpp +++ b/src/slic3r/GUI/Widgets/AMSControl.hpp @@ -17,6 +17,9 @@ namespace Slic3r { namespace GUI { +//Previous definitions +class uiAmsPercentHumidityDryPopup; + class AMSControl : public wxSimplebook { public: @@ -112,6 +115,7 @@ protected: ScalableBitmap m_button_ams_setting_press; AmsHumidityTipPopup m_Humidity_tip_popup; + uiAmsPercentHumidityDryPopup* m_percent_humidity_dry_popup; std::string m_last_ams_id = ""; std::string m_last_tray_id = ""; diff --git a/src/slic3r/GUI/Widgets/AMSItem.cpp b/src/slic3r/GUI/Widgets/AMSItem.cpp index b8fd455c0..bf3c9d67e 100644 --- a/src/slic3r/GUI/Widgets/AMSItem.cpp +++ b/src/slic3r/GUI/Widgets/AMSItem.cpp @@ -5,6 +5,8 @@ #include "../GUI_App.hpp" #include "../Utils/WxFontUtils.hpp" +#include "slic3r/GUI/DeviceTab/uiAmsHumidityPopup.h" + #include #include @@ -55,6 +57,7 @@ bool AMSinfo::parse_ams_info(MachineObject *obj, Ams *ams, bool remain_flag, boo this->humidity_raw = ams->humidity_raw; this->left_dray_time = ams->left_dry_time; + this->current_temperature = ams->current_temperature; this->ams_type = AMSModel(ams->type); nozzle_id = ams->nozzle; @@ -2784,7 +2787,13 @@ AMSHumidity::AMSHumidity(wxWindow* parent, wxWindowID id, AMSinfo info, const wx if (mouse_pos.x > rect.x && mouse_pos.y > rect.y) { wxCommandEvent show_event(EVT_AMS_SHOW_HUMIDITY_TIPS); - show_event.SetInt(m_amsinfo.ams_humidity); + + uiAmsHumidityInfo *info = new uiAmsHumidityInfo; + info->humidity_level = m_amsinfo.ams_humidity; + info->humidity_percent = m_amsinfo.humidity_raw; + info->left_dry_time = m_amsinfo.left_dray_time; + info->current_temperature = m_amsinfo.current_temperature; + show_event.SetClientData(info); wxPostEvent(GetParent()->GetParent(), show_event); #ifdef __WXMSW__ diff --git a/src/slic3r/GUI/Widgets/AMSItem.hpp b/src/slic3r/GUI/Widgets/AMSItem.hpp index 60135e42b..dfdd6c52d 100644 --- a/src/slic3r/GUI/Widgets/AMSItem.hpp +++ b/src/slic3r/GUI/Widgets/AMSItem.hpp @@ -219,6 +219,7 @@ public: int ams_humidity = 0; int humidity_raw = -1; int left_dray_time = 0; + float current_temperature = INVALID_AMS_TEMPERATURE; AMSModel ams_type = AMSModel::GENERIC_AMS; AMSModelOriginType ext_type = AMSModelOriginType::GENERIC_EXT; @@ -234,6 +235,7 @@ public: curreent_filamentstep == other.curreent_filamentstep && ams_humidity == other.ams_humidity && left_dray_time == other.left_dray_time && + current_temperature == other.current_temperature && ams_type == other.ams_type && ext_type == other.ext_type) {