FIX: The humidity popup with humidity_percent/temperature/dry_time

jira: [STUDIO-9268]
Change-Id: Ic6e923ae7cff56fa3e053d48e5dea6e393cd41eb
This commit is contained in:
xin.zhang 2025-02-21 15:57:10 +08:00 committed by lane.wei
parent adb3fbcfcf
commit 75da1db2f9
10 changed files with 376 additions and 8 deletions

View File

@ -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

View File

@ -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<std::string>();
try
{
curr_ams->current_temperature = string_to_float(temp);
}
catch (...)
{
curr_ams->current_temperature = INVALID_AMS_TEMPERATURE;
}
}
if (it->contains("tray")) {
std::set<std::string> tray_id_set;
for (auto it = curr_ams->trayList.begin(); it != curr_ams->trayList.end(); it++) {

View File

@ -353,6 +353,7 @@ public:
std::string get_filament_type();
};
#define INVALID_AMS_TEMPERATURE std::numeric_limits<float>::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};

View File

@ -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
)

View File

@ -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 <wx/dcgraph.h>
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<wxString> 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

View File

@ -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;
};
/// </summary>
/// Note: The popup of Ams Humidity with percentage and dry time
/// Author: xin.zhang
/// </summary>
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

View File

@ -4,6 +4,8 @@
#include "../I18N.hpp"
#include "../GUI_App.hpp"
#include "slic3r/GUI/DeviceTab/uiAmsHumidityPopup.h"
#include <wx/simplebook.h>
#include <wx/dcgraph.h>
@ -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_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 = evt.GetInt();
if (humidity_value > 0 && humidity_value <= 5) {
m_Humidity_tip_popup.set_humidity_level(humidity_value);
}
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();
}
}
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();
}

View File

@ -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 = "";

View File

@ -5,6 +5,8 @@
#include "../GUI_App.hpp"
#include "../Utils/WxFontUtils.hpp"
#include "slic3r/GUI/DeviceTab/uiAmsHumidityPopup.h"
#include <wx/simplebook.h>
#include <wx/dcgraph.h>
@ -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__

View File

@ -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)
{