From 5f989c81d131972a1d4d1ec239e3c90c2f5d1e65 Mon Sep 17 00:00:00 2001 From: Noisyfox Date: Mon, 19 May 2025 23:37:10 +0800 Subject: [PATCH] Port BBS `AMSHumidity` --- src/slic3r/GUI/Widgets/AMSControl.cpp | 1 - src/slic3r/GUI/Widgets/AMSItem.cpp | 351 +++++++++++++++++--------- src/slic3r/GUI/Widgets/AMSItem.hpp | 99 +++++++- 3 files changed, 317 insertions(+), 134 deletions(-) diff --git a/src/slic3r/GUI/Widgets/AMSControl.cpp b/src/slic3r/GUI/Widgets/AMSControl.cpp index 6fa1f41257..87e81bde30 100644 --- a/src/slic3r/GUI/Widgets/AMSControl.cpp +++ b/src/slic3r/GUI/Widgets/AMSControl.cpp @@ -782,7 +782,6 @@ void AMSControl::msw_rescale() m_button_guide->SetMinSize(wxSize(-1, FromDIP(24))); m_button_retry->SetMinSize(wxSize(-1, FromDIP(24))); m_vams_lib->msw_rescale(); - m_vams_road->msw_rescale(); for (auto i = 0; i < m_ams_cans_list.GetCount(); i++) { AmsCansWindow *cans = m_ams_cans_list[i]; diff --git a/src/slic3r/GUI/Widgets/AMSItem.cpp b/src/slic3r/GUI/Widgets/AMSItem.cpp index 7da276db6b..2e77a8dc91 100644 --- a/src/slic3r/GUI/Widgets/AMSItem.cpp +++ b/src/slic3r/GUI/Widgets/AMSItem.cpp @@ -1406,12 +1406,6 @@ AMSRoad::AMSRoad(wxWindow *parent, wxWindowID id, Caninfo info, int canindex, in m_rode_mode = AMSRoadMode::AMS_ROAD_MODE_NONE_ANY_ROAD; } - for (int i = 1; i <= 5; i++) { ams_humidity_imgs.push_back(ScalableBitmap(this, "hum_level" + std::to_string(i) + "_light", 32));} - for (int i = 1; i <= 5; i++) { ams_humidity_dark_imgs.push_back(ScalableBitmap(this, "hum_level" + std::to_string(i) + "_dark", 32));} - for (int i = 1; i <= 5; i++) { ams_humidity_no_num_imgs.push_back(ScalableBitmap(this, "hum_level" + std::to_string(i) + "_no_num_light", 16)); } - for (int i = 1; i <= 5; i++) { ams_humidity_no_num_dark_imgs.push_back(ScalableBitmap(this, "hum_level" + std::to_string(i) + "_no_num_dark", 16)); } - ams_sun_img = ScalableBitmap(this, "ams_drying", 16); - ams_drying_img = ScalableBitmap(this, "ams_is_drying", 16); if (m_rode_mode != AMSRoadMode::AMS_ROAD_MODE_VIRTUAL_TRAY) { create(parent, id, pos, size); } @@ -1423,25 +1417,6 @@ AMSRoad::AMSRoad(wxWindow *parent, wxWindowID id, Caninfo info, int canindex, in Bind(wxEVT_PAINT, &AMSRoad::paintEvent, this); wxWindow::SetBackgroundColour(AMS_CONTROL_DEF_BLOCK_BK_COLOUR); - - Bind(wxEVT_LEFT_UP, [this](wxMouseEvent& e) { - if (m_canindex == 3 && m_show_humidity) { - auto mouse_pos = ClientToScreen(e.GetPosition()); - auto rect = ClientToScreen(wxPoint(0, 0)); - - if (mouse_pos.x > rect.x + GetSize().x - FromDIP(40) && - mouse_pos.y > rect.y + GetSize().y - FromDIP(40)) { - wxCommandEvent show_event(EVT_AMS_SHOW_HUMIDITY_TIPS); - wxPostEvent(GetParent()->GetParent(), show_event); - -#ifdef __WXMSW__ - wxCommandEvent close_event(EVT_CLEAR_SPEED_CONTROL); - wxPostEvent(GetParent()->GetParent(), close_event); -#endif // __WXMSW__ - - } - } - }); } void AMSRoad::create(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size) { wxWindow::Create(parent, id, pos, size); } @@ -1585,85 +1560,6 @@ void AMSRoad::doRender(wxDC &dc) dc.SetBrush(wxBrush(m_road_def_color)); dc.DrawRoundedRectangle(size.x * 0.37 / 2, size.y * 0.6 - size.y / 6, size.x * 0.63, size.y / 3, m_radius); } - - if (m_canindex == 3) { - - if (m_amsinfo.ams_humidity >= 1 && m_amsinfo.ams_humidity <= 5) {m_show_humidity = true;} - else {m_show_humidity = false;} - - if (m_show_humidity) { - wxPoint pot; - if (m_amsinfo.humidity_raw != -1) /*image with no number + percentage*/ - { - // hum image - ScalableBitmap hum_img; - if (!wxGetApp().dark_mode()) { - hum_img = ams_humidity_no_num_imgs[m_amsinfo.ams_humidity - 1]; - } else { - hum_img = ams_humidity_no_num_dark_imgs[m_amsinfo.ams_humidity - 1]; - } - - pot = wxPoint(FromDIP(5), size.y - hum_img.GetBmpSize().y - FromDIP(8)); - dc.DrawBitmap(hum_img.bmp(), pot); - - // percentage - wxString hum_percentage(std::to_string(m_amsinfo.humidity_raw)); - auto tsize = dc.GetMultiLineTextExtent(hum_percentage); - dc.SetPen(wxPen(*wxTRANSPARENT_PEN)); - dc.SetFont(Label::Body_14); - dc.SetTextForeground(StateColor::darkModeColorFor(AMS_CONTROL_BLACK_COLOUR)); - // pot = wxPoint(FromDIP(size.x * 0.3), FromDIP((size.y - tsize.y) / 2)); - pot.x = pot.x + hum_img.GetBmpSize().x + FromDIP(3); - dc.DrawText(hum_percentage, pot); - - pot.x += (tsize.x + FromDIP(5)); - dc.SetFont(Label::Body_12); - tsize = dc.GetMultiLineTextExtent(_L("%")); - pot.y += (tsize.y / 2 - FromDIP(4)); - dc.DrawText(_L("%"), pot); - - pot.x = pot.x + tsize.x + FromDIP(2); - } - else /*image with number*/ - { - // hum image - ScalableBitmap hum_img; - if (!wxGetApp().dark_mode()) { - hum_img = ams_humidity_imgs[m_amsinfo.ams_humidity - 1]; - } else { - hum_img = ams_humidity_dark_imgs[m_amsinfo.ams_humidity - 1]; - } - - pot = wxPoint(size.x - FromDIP(33), size.y - FromDIP(33)); - dc.DrawBitmap(hum_img.bmp(), pot); - pot.x = pot.x + hum_img.GetBmpSize().x + FromDIP(3); - } - - if (m_amsinfo.support_drying()) - { - pot.x += FromDIP(2);// spacing - - // vertical line - dc.SetPen(wxPen(wxColour(194, 194, 194))); - dc.SetBrush(wxBrush(wxColour(194, 194, 194))); - dc.DrawLine(pot.x, GetSize().y / 2 - FromDIP(10), pot.x, GetSize().y / 2 + FromDIP(10)); - - // sun image - dc.SetPen(wxPen(*wxTRANSPARENT_PEN)); - pot.x += ((size.GetWidth() - pot.x) - ams_drying_img.GetBmpWidth()) / 2;// spacing - if (m_amsinfo.left_dray_time > 0) { - pot.y = (size.y - ams_drying_img.GetBmpHeight()) / 2; - dc.DrawBitmap(ams_drying_img.bmp(), pot); - } else { - pot.y = (size.y - ams_sun_img.GetBmpHeight()) / 2; - dc.DrawBitmap(ams_sun_img.bmp(), pot); - } - } - } - else { - //to do ... - } - } } void AMSRoad::UpdatePassRoad(int tag_index, AMSPassRoadType type, AMSPassRoadSTEP step) {} @@ -1719,16 +1615,6 @@ void AMSRoad::OnPassRoad(std::vector prord_list) } } -void AMSRoad::msw_rescale() -{ - for (auto& img : ams_humidity_imgs) { img.msw_rescale();} - for (auto& img : ams_humidity_dark_imgs) { img.msw_rescale(); } - for (auto &img : ams_humidity_no_num_imgs) { img.msw_rescale(); } - for (auto &img : ams_humidity_no_num_dark_imgs) { img.msw_rescale(); } - ams_sun_img.msw_rescale(); - ams_drying_img.msw_rescale(); -} - /************************************************* Description:AmsCan @@ -1754,13 +1640,17 @@ void AmsCans::create(wxWindow *parent) Freeze(); SetBackgroundColour(AMS_CONTROL_DEF_BLOCK_BK_COLOUR); - if (m_ams_model == AMSModel::GENERIC_AMS) { + if (m_ams_model == AMSModel::GENERIC_AMS || m_ams_model == AMSModel::N3F_AMS || m_ams_model == AMSModel::N3S_AMS) { sizer_can = new wxBoxSizer(wxHORIZONTAL); + sizer_item = new wxBoxSizer(wxVERTICAL); for (auto it = m_info.cans.begin(); it != m_info.cans.end(); it++) { AddCan(*it, m_can_count, m_info.cans.size(), sizer_can); m_can_count++; } - SetSizer(sizer_can); + m_humidity = new AMSHumidity(this, wxID_ANY, m_info); + sizer_item->Add(m_humidity, 0, wxALIGN_CENTER_HORIZONTAL, 0); + sizer_item->Add(sizer_can, 0, wxALIGN_CENTER_HORIZONTAL, 0); + SetSizer(sizer_item); } else if(m_ams_model == AMSModel::AMS_LITE) { sizer_can = new wxBoxSizer(wxVERTICAL); @@ -1843,7 +1733,7 @@ void AmsCans::AddCan(Caninfo caninfo, int canindex, int maxcan, wxBoxSizer* size auto m_panel_road = new AMSRoad(amscan, wxID_ANY, caninfo, canindex, maxcan, wxDefaultPosition, AMS_CAN_ROAD_SIZE); if (m_ams_model == AMSModel::GENERIC_AMS) { - m_sizer_ams->Add(0, 0, 0, wxEXPAND | wxTOP, FromDIP(14)); + m_sizer_ams->Add(0, 0, 0, wxEXPAND | wxTOP, FromDIP(2)); m_sizer_ams->Add(m_panel_refresh, 0, wxALIGN_CENTER_HORIZONTAL, 0); m_sizer_ams->Add(0, 0, 0, wxEXPAND | wxTOP, FromDIP(2)); m_sizer_ams->Add(m_panel_lib, 1, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, FromDIP(3)); @@ -1903,6 +1793,11 @@ void AmsCans::Update(AMSinfo info) m_info = info; m_can_count = info.cans.size(); + if (m_humidity) + { + m_humidity->Update(m_info); + } + for (auto i = 0; i < m_can_refresh_list.GetCount(); i++) { Canrefreshs *refresh = m_can_refresh_list[i]; if (i < m_can_count) { @@ -2262,11 +2157,7 @@ void AmsCans::msw_rescale() CanLibs* lib = m_can_lib_list[i]; lib->canLib->msw_rescale(); } - - for (auto i = 0; i < m_can_road_list.GetCount(); i++) { - CanRoads* road = m_can_road_list[i]; - road->canRoad->msw_rescale(); - } + if (m_humidity != nullptr) m_humidity->msw_rescale(); } void AmsCans::show_sn_value(bool show) @@ -2277,6 +2168,222 @@ void AmsCans::show_sn_value(bool show) } } +/************************************************* +Description:AMSHumidity +**************************************************/ + +AMSHumidity::AMSHumidity() {} +AMSHumidity::AMSHumidity(wxWindow* parent, wxWindowID id, AMSinfo info, const wxPoint& pos, const wxSize& size) + : AMSHumidity() +{ + create(parent, id, pos, wxDefaultSize); + + for (int i = 1; i <= 5; i++) { ams_humidity_imgs.push_back(ScalableBitmap(this, "hum_level" + std::to_string(i) + "_light", 16));} + for (int i = 1; i <= 5; i++) { ams_humidity_dark_imgs.push_back(ScalableBitmap(this, "hum_level" + std::to_string(i) + "_dark", 16));} + for (int i = 1; i <= 5; i++) { ams_humidity_no_num_imgs.push_back(ScalableBitmap(this, "hum_level" + std::to_string(i) + "_no_num_light", 16)); } + for (int i = 1; i <= 5; i++) { ams_humidity_no_num_dark_imgs.push_back(ScalableBitmap(this, "hum_level" + std::to_string(i) + "_no_num_dark", 16)); } + + ams_sun_img = ScalableBitmap(this, "ams_drying", 16); + ams_drying_img = ScalableBitmap(this, "ams_is_drying", 16); + + Bind(wxEVT_PAINT, &AMSHumidity::paintEvent, this); + //wxWindow::SetBackgroundColour(AMS_CONTROL_DEF_HUMIDITY_BK_COLOUR); + + Bind(wxEVT_LEFT_UP, [this](wxMouseEvent& e) { + if (m_show_humidity) { + auto mouse_pos = ClientToScreen(e.GetPosition()); + auto rect = ClientToScreen(wxPoint(0, 0)); + + if (mouse_pos.x > rect.x && + mouse_pos.y > rect.y) { + wxCommandEvent show_event(EVT_AMS_SHOW_HUMIDITY_TIPS); + + //uiAmsHumidityInfo *info = new uiAmsHumidityInfo; + //info->ams_id = m_amsinfo.ams_id; + //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__ + wxCommandEvent close_event(EVT_CLEAR_SPEED_CONTROL); + wxPostEvent(GetParent()->GetParent(), close_event); +#endif // __WXMSW__ + + } + } + }); + + Update(info); +} + +void AMSHumidity::create(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size) { + wxWindow::Create(parent, id, pos, size); + SetBackgroundColour(StateColor::darkModeColorFor(AMS_CONTROL_DEF_LIB_BK_COLOUR)); +} + + +void AMSHumidity::Update(AMSinfo amsinfo) +{ + if (m_amsinfo != amsinfo) + { + m_amsinfo = amsinfo; + update_size(); + Refresh(); + } +} + +void AMSHumidity::update_size() +{ + wxSize size; + if (m_amsinfo.humidity_raw != -1) { + size = AMS_HUMIDITY_SIZE; + } else { + size = AMS_HUMIDITY_NO_PERCENT_SIZE; + } + + if (!m_amsinfo.support_drying()) { size.x -= AMS_HUMIDITY_DRY_WIDTH; } + + SetMaxSize(size); + SetMinSize(size); + SetSize(size); +} + + +void AMSHumidity::paintEvent(wxPaintEvent& evt) +{ + wxPaintDC dc(this); + render(dc); +} + +void AMSHumidity::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 AMSHumidity::doRender(wxDC& dc) +{ + wxSize size = GetSize(); + + dc.SetPen(wxPen(*wxTRANSPARENT_PEN)); + dc.SetBrush(wxBrush(StateColor::darkModeColorFor(AMS_CONTROL_DEF_BLOCK_BK_COLOUR))); + // left mode + if (m_amsinfo.ams_humidity >= 1 && m_amsinfo.ams_humidity <= 5) { m_show_humidity = true; } + else { m_show_humidity = false; } + + if (m_show_humidity) { + //background + dc.SetPen(wxPen(*wxTRANSPARENT_PEN)); + dc.SetBrush(wxBrush(StateColor::darkModeColorFor(AMS_CONTROL_DEF_BLOCK_BK_COLOUR))); + dc.DrawRoundedRectangle(0, 0, (size.x), (size.y), (size.y / 2)); + + wxPoint pot; + if (m_amsinfo.humidity_raw != -1) /*image with no number + percentage*/ + { + // hum image + ScalableBitmap hum_img; + if (!wxGetApp().dark_mode()) { + hum_img = ams_humidity_no_num_imgs[m_amsinfo.ams_humidity - 1]; + } else { + hum_img = ams_humidity_no_num_dark_imgs[m_amsinfo.ams_humidity - 1]; + } + + pot = wxPoint(FromDIP(5), ((size.y - hum_img.GetBmpSize().y) / 2)); + dc.DrawBitmap(hum_img.bmp(), pot); + pot.x += hum_img.GetBmpSize().x + FromDIP(3); + + // percentage + wxString hum_percentage(std::to_string(m_amsinfo.humidity_raw)); + dc.SetPen(wxPen(*wxTRANSPARENT_PEN)); + dc.SetFont(Label::Body_14); + dc.SetTextForeground(StateColor::darkModeColorFor(AMS_CONTROL_BLACK_COLOUR)); + + //WxFontUtils::get_suitable_font_size(0.7 * size.GetHeight(), dc); + auto tsize1 = dc.GetMultiLineTextExtent(hum_percentage); + pot.y = (size.y - tsize1.y) / 2; + dc.DrawText(hum_percentage, pot); + pot.x += (tsize1.x + FromDIP(3)); + + // percentage sign + dc.SetFont(Label::Body_12); + //WxFontUtils::get_suitable_font_size(0.5 * size.GetHeight(), dc); + auto tsize2 = dc.GetMultiLineTextExtent(_L("%")); + pot.y = pot.y + ((tsize1.y - tsize2.y) / 2) + FromDIP(2); + dc.DrawText(_L("%"), pot); + + pot.x += tsize2.x; + } + else /*image with number*/ + { + // hum image + ScalableBitmap hum_img; + if (!wxGetApp().dark_mode()) { + hum_img = ams_humidity_imgs[m_amsinfo.ams_humidity - 1]; + } else { + hum_img = ams_humidity_dark_imgs[m_amsinfo.ams_humidity - 1]; + } + + pot = wxPoint(FromDIP(5), ((size.y - hum_img.GetBmpSize().y) / 2)); + dc.DrawBitmap(hum_img.bmp(), pot); + pot.x = pot.x + hum_img.GetBmpSize().x; + } + + if (m_amsinfo.support_drying()) + { + pot.x += FromDIP(2);// spacing + + // vertical line + dc.SetPen(wxPen(wxColour(194, 194, 194))); + dc.SetBrush(wxBrush(wxColour(194, 194, 194))); + dc.DrawLine(pot.x, GetSize().y / 2 - FromDIP(10), pot.x, GetSize().y / 2 + FromDIP(10)); + + // sun image + dc.SetPen(wxPen(*wxTRANSPARENT_PEN)); + pot.x += ((size.GetWidth() - pot.x) - ams_drying_img.GetBmpWidth()) / 2;// spacing + if (m_amsinfo.left_dray_time > 0) { + pot.y = (size.y - ams_drying_img.GetBmpHeight()) / 2; + dc.DrawBitmap(ams_drying_img.bmp(), pot); + } else { + pot.y = (size.y - ams_sun_img.GetBmpHeight()) / 2; + dc.DrawBitmap(ams_sun_img.bmp(), pot); + } + } + } + else { + //to do ... + } +} + +void AMSHumidity::msw_rescale() { + for (auto& img : ams_humidity_imgs) { img.msw_rescale();} + for (auto& img : ams_humidity_dark_imgs) { img.msw_rescale(); } + for (auto &img : ams_humidity_no_num_imgs) { img.msw_rescale(); } + for (auto &img : ams_humidity_no_num_dark_imgs) { img.msw_rescale(); } + ams_sun_img.msw_rescale(); + ams_drying_img.msw_rescale(); + + Layout(); + Refresh(); +} + /************************************************* Description:AMSItem **************************************************/ diff --git a/src/slic3r/GUI/Widgets/AMSItem.hpp b/src/slic3r/GUI/Widgets/AMSItem.hpp index 3b8960be24..37edad7de7 100644 --- a/src/slic3r/GUI/Widgets/AMSItem.hpp +++ b/src/slic3r/GUI/Widgets/AMSItem.hpp @@ -137,6 +137,8 @@ enum FilamentStepType { #define AMS_EXTRUDER_SIZE wxSize(FromDIP(86), FromDIP(72)) #define AMS_EXTRUDER_BITMAP_SIZE wxSize(FromDIP(36), FromDIP(55)) +#define AMS_HUMIDITY_SIZE wxSize(FromDIP(93), FromDIP(26)) +#define AMS_HUMIDITY_NO_PERCENT_SIZE wxSize(FromDIP(60), FromDIP(26)) #define AMS_HUMIDITY_DRY_WIDTH FromDIP(35) @@ -151,6 +153,25 @@ struct Caninfo float k = 0.0f; float n = 0.0f; std::vector material_cols; + +public: + bool operator==(const Caninfo& other) const + { + if (can_id == other.can_id && + material_name == other.material_name && + material_colour == other.material_colour && + material_state == other.material_state && + ctype == other.ctype && + material_remain == other.material_remain && + k == other.k && + n == other.n && + material_cols == other.material_cols) + { + return true; + } + + return false; + }; }; struct AMSinfo @@ -167,6 +188,35 @@ public: int left_dray_time = 0; AMSModel ams_type = AMSModel::GENERIC_AMS; +public: + bool operator== (const AMSinfo& other) const + { + if (ams_id == other.ams_id && + cans == other.cans && + current_can_id == other.current_can_id && + current_step == other.current_step && + current_action == other.current_action && + curreent_filamentstep == other.curreent_filamentstep && + ams_humidity == other.ams_humidity && + left_dray_time == other.left_dray_time && + ams_type == other.ams_type) + { + return true; + } + + return false; + }; + + bool operator!=(const AMSinfo &other) const + { + if (operator==(other)) + { + return false; + } + + return true; + }; + bool parse_ams_info(MachineObject* obj, Ams *ams, bool remain_flag = false, bool humidity_flag = false); bool support_drying() const { return (ams_type == AMSModel::N3S_AMS) || (ams_type == AMSModel::N3F_AMS); }; @@ -399,17 +449,6 @@ public: wxColour m_road_color; void Update(AMSinfo amsinfo, Caninfo info, int canindex, int maxcan); - std::vector ams_humidity_imgs; - std::vector ams_humidity_dark_imgs; - - std::vector ams_humidity_no_num_imgs; - std::vector ams_humidity_no_num_dark_imgs; - - ScalableBitmap ams_sun_img; - ScalableBitmap ams_drying_img; - - int m_humidity = { 0 }; - bool m_show_humidity = { false }; bool m_vams_loading{false}; AMSModel m_ams_model; @@ -422,7 +461,42 @@ public: void paintEvent(wxPaintEvent &evt); void render(wxDC &dc); void doRender(wxDC& dc); +}; + +/************************************************* +Description:AMSHumidity +**************************************************/ +class AMSHumidity : public wxWindow +{ +public: + AMSHumidity(); + AMSHumidity(wxWindow* parent, wxWindowID id, AMSinfo info, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize); + void create(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize); + +public: + AMSinfo m_amsinfo; + void Update(AMSinfo amsinfo); + + std::vector ams_humidity_imgs; + std::vector ams_humidity_dark_imgs; + + std::vector ams_humidity_no_num_imgs; + std::vector ams_humidity_no_num_dark_imgs; + + ScalableBitmap ams_sun_img; + ScalableBitmap ams_drying_img; + + + int m_humidity = { 0 }; + bool m_show_humidity = { false }; + + void paintEvent(wxPaintEvent& evt); + void render(wxDC& dc); + void doRender(wxDC& dc); void msw_rescale(); + +private: + void update_size(); }; /************************************************* @@ -530,8 +604,11 @@ public: CanLibsHash m_can_lib_list; CansRoadsHash m_can_road_list; CanrefreshsHash m_can_refresh_list; + AMSHumidity* m_humidity = { nullptr }; + AMSinfo m_info; wxBoxSizer * sizer_can = {nullptr}; + wxBoxSizer * sizer_item = { nullptr }; wxBoxSizer * sizer_can_middle = {nullptr}; wxBoxSizer * sizer_can_left = {nullptr}; wxBoxSizer * sizer_can_right = {nullptr};