mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-07-18 00:12:09 +00:00
Resync the device tab widgets and add the AMS best-position popup
This commit is contained in:
@@ -2,10 +2,10 @@
|
||||
list(APPEND SLIC3R_GUI_SOURCES
|
||||
GUI/DeviceTab/uiAmsHumidityPopup.h
|
||||
GUI/DeviceTab/uiAmsHumidityPopup.cpp
|
||||
GUI/DeviceTab/uiAMSBestPositionPopup.hpp
|
||||
GUI/DeviceTab/uiAMSBestPositionPopup.cpp
|
||||
GUI/DeviceTab/uiDeviceUpdateVersion.h
|
||||
GUI/DeviceTab/uiDeviceUpdateVersion.cpp
|
||||
GUI/DeviceTab/wgtDeviceNozzleRackNozzleItem.h
|
||||
GUI/DeviceTab/wgtDeviceNozzleRackNozzleItem.cpp
|
||||
GUI/DeviceTab/wgtDeviceNozzleRack.h
|
||||
GUI/DeviceTab/wgtDeviceNozzleRack.cpp
|
||||
GUI/DeviceTab/wgtDeviceNozzleRackUpdate.h
|
||||
@@ -14,5 +14,7 @@ list(APPEND SLIC3R_GUI_SOURCES
|
||||
GUI/DeviceTab/wgtDeviceNozzleSelect.cpp
|
||||
GUI/DeviceTab/wgtMsgBox.h
|
||||
GUI/DeviceTab/wgtMsgBox.cpp
|
||||
GUI/DeviceTab/wgtMsgPanel.h
|
||||
GUI/DeviceTab/wgtMsgPanel.cpp
|
||||
)
|
||||
set(SLIC3R_GUI_SOURCES ${SLIC3R_GUI_SOURCES} PARENT_SCOPE)
|
||||
1046
src/slic3r/GUI/DeviceTab/uiAMSBestPositionPopup.cpp
Normal file
1046
src/slic3r/GUI/DeviceTab/uiAMSBestPositionPopup.cpp
Normal file
File diff suppressed because it is too large
Load Diff
224
src/slic3r/GUI/DeviceTab/uiAMSBestPositionPopup.hpp
Normal file
224
src/slic3r/GUI/DeviceTab/uiAMSBestPositionPopup.hpp
Normal file
@@ -0,0 +1,224 @@
|
||||
//**********************************************************/
|
||||
/* File: uiAMSBestPositionPopup.hpp
|
||||
* Description: The popup with suggest best ams position
|
||||
*
|
||||
//**********************************************************/
|
||||
|
||||
#pragma once
|
||||
#include "slic3r/GUI/Widgets/AMSItem.hpp"
|
||||
#include "slic3r/GUI/Widgets/Label.hpp"
|
||||
#include "slic3r/GUI/Widgets/PopupWindow.hpp"
|
||||
#include "slic3r/GUI/wxExtensions.hpp"
|
||||
#include "slic3r/GUI/Widgets/Button.hpp"
|
||||
#include "slic3r/GUI/DeviceCore/DevFilaSystem.h"
|
||||
#include "slic3r/GUI/DeviceCore/DevFilaSwitch.h"
|
||||
#include <algorithm>
|
||||
|
||||
#include <tuple>
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
|
||||
class UiStyledAMSPanel : public wxPanel
|
||||
{
|
||||
public:
|
||||
UiStyledAMSPanel(wxWindow* parent,
|
||||
wxWindowID id = wxID_ANY,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
const wxColour& borderColor = wxColour(200, 200, 200),
|
||||
const wxColour& bgColor = wxColour(255, 255, 255),
|
||||
bool borderDashed = true,
|
||||
wxString name = "",
|
||||
bool isTop = false);
|
||||
|
||||
protected:
|
||||
void OnPaint(wxPaintEvent& event);
|
||||
|
||||
private:
|
||||
|
||||
bool m_borderDashed;
|
||||
int m_borderWidth;
|
||||
int m_radius;
|
||||
wxColour m_borderColor;
|
||||
wxColour m_bgColor;
|
||||
wxString m_name;
|
||||
bool m_isTop;
|
||||
};
|
||||
|
||||
class UiStyledSwitchPanel : public wxPanel
|
||||
{
|
||||
public:
|
||||
UiStyledSwitchPanel(wxWindow* parent,
|
||||
wxWindowID id,
|
||||
const wxPoint& pos,
|
||||
const wxSize& size,
|
||||
const wxColour& borderColor,
|
||||
const wxColour& bgColor,
|
||||
bool borderDashed,
|
||||
int borderWidth,
|
||||
int radius,
|
||||
bool isTop);
|
||||
|
||||
|
||||
void AddToLeft(wxWindow* window, int proportion = 0, int flag = wxEXPAND, int border = 0);
|
||||
void AddToRight(wxWindow* window, int proportion = 0, int flag = wxEXPAND, int border = 0);
|
||||
void Clear(bool deleteWindows);
|
||||
|
||||
wxSizer* GetLeftSizer() { return m_leftSizer; }
|
||||
wxSizer* GetRightSizer() { return m_rightSizer; }
|
||||
void LayoutAndFit()
|
||||
{
|
||||
m_leftSizer->Layout();
|
||||
// m_leftSizer->Fit();
|
||||
m_rightSizer->Layout();
|
||||
// m_rightSizer->Fit();
|
||||
m_splitSizer->Layout();
|
||||
// m_splitSizer->Fit();
|
||||
m_contentSizer->Layout();
|
||||
// m_contentSizer->Fit();
|
||||
m_mainSizer->Layout();
|
||||
// m_mainSizer->Fit();
|
||||
Fit();
|
||||
}
|
||||
protected:
|
||||
void OnPaint(wxPaintEvent& event);
|
||||
private:
|
||||
|
||||
bool m_borderDashed;
|
||||
int m_borderWidth;
|
||||
int m_radius;
|
||||
wxColour m_borderColor;
|
||||
wxColour m_bgColor;
|
||||
bool m_isTop;
|
||||
|
||||
wxBoxSizer* m_mainSizer{nullptr};
|
||||
wxBoxSizer* m_contentSizer{nullptr};
|
||||
wxBoxSizer* m_splitSizer{nullptr};
|
||||
wxSizer* m_leftSizer{nullptr};
|
||||
wxSizer* m_rightSizer{nullptr};
|
||||
|
||||
static constexpr int labelHeight = 30;
|
||||
|
||||
};
|
||||
|
||||
|
||||
enum DataStatusType {
|
||||
ADJUST,
|
||||
OK,
|
||||
UNMATCHED
|
||||
};
|
||||
|
||||
class UiAMSSlot : public wxPanel
|
||||
{
|
||||
public:
|
||||
UiAMSSlot(wxWindow* parent,
|
||||
const std::vector<wxColour>& bgColours,
|
||||
const wxString& text,
|
||||
DataStatusType status,
|
||||
wxWindowID id = wxID_ANY,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
double colourFactor = 1.0,
|
||||
double scaleFactor = 1.0);
|
||||
|
||||
|
||||
private:
|
||||
void OnPaint(wxPaintEvent&);
|
||||
void DrawRectangle(wxPaintDC& dc, const wxSize& cli);
|
||||
void DrawLine(wxPaintDC& dc, const wxSize& cli);
|
||||
wxColour LightenColour(const wxColour& original);
|
||||
bool IsDark(const wxColour& c)
|
||||
{
|
||||
int brightness = (c.Red() * 299 + c.Green() * 587 + c.Blue() * 114) / 1000;
|
||||
return brightness < 128; // 0-255 range,128 mid
|
||||
}
|
||||
private:
|
||||
const std::vector<wxColour>& m_bgColours;
|
||||
wxString m_text;
|
||||
DataStatusType m_status;
|
||||
wxSize m_size;
|
||||
ScalableBitmap *m_ams_slot_readonly{nullptr};
|
||||
int m_rectangleW = 44;
|
||||
int m_rectangleH = 62;
|
||||
int rectangleW = 44;
|
||||
int rectangleH = 62;
|
||||
double m_colourFactor = 1.0f;
|
||||
double m_scaleFactor = 1.0f;
|
||||
// wxDECLARE_EVENT_TABLE();
|
||||
};
|
||||
|
||||
struct DataAmsSlotInfo
|
||||
{
|
||||
wxString amsName;
|
||||
wxString name;
|
||||
std::vector<wxColour> colours;
|
||||
double colourFactor;
|
||||
double scaleFactor;
|
||||
DataStatusType status;
|
||||
};
|
||||
|
||||
class UiAMS : public UiStyledAMSPanel
|
||||
{
|
||||
public:
|
||||
UiAMS(wxWindow* parent,
|
||||
const std::vector<DataAmsSlotInfo>& amsInfo,
|
||||
wxWindowID id,
|
||||
const wxPoint& pos,
|
||||
const wxSize& minSize);
|
||||
private:
|
||||
void init();
|
||||
std::vector<DataAmsSlotInfo> m_amsInfo;
|
||||
wxString m_amsTitle;
|
||||
wxSize m_minSize;
|
||||
};
|
||||
|
||||
|
||||
struct DataStatusParam {
|
||||
// int count = 0;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
std::vector<DataAmsSlotInfo> slots;
|
||||
};
|
||||
|
||||
class ReselectMachineDialog : public wxDialog
|
||||
{
|
||||
public:
|
||||
ReselectMachineDialog(wxWindow* parent);
|
||||
~ReselectMachineDialog();
|
||||
void Update(MachineObject* obj,
|
||||
const std::map<int, int>& best_pos_map,
|
||||
const std::vector<FilamentInfo>& ams_mapping,
|
||||
wxString save_time);
|
||||
|
||||
private:
|
||||
int CaculateSwitcherDistribution(MachineObject* obj, const std::map<int, int>& best_pos_map, const std::vector<FilamentInfo>& ams_mapping);
|
||||
wxString getTrayID(MachineObject* obj, const std::string& amsID, const std::string& slotID);
|
||||
void OnRefreshButton(wxCommandEvent& event);
|
||||
|
||||
private:
|
||||
int saveTimes{0};
|
||||
wxBoxSizer* mainSizer{nullptr};
|
||||
wxPanel* textPanel{nullptr};
|
||||
wxBoxSizer* textSizer{nullptr};
|
||||
Label* suggestText{nullptr};
|
||||
// wxHyperlinkCtrl* linkwiki{nullptr};
|
||||
Label* linkwiki{nullptr};
|
||||
Label* summaryText{nullptr};
|
||||
UiStyledSwitchPanel* filamentSwitch{nullptr};
|
||||
wxStaticText* filamentTips{nullptr};
|
||||
std::vector<std::vector<DataAmsSlotInfo>> inAAMS{};
|
||||
std::vector<std::vector<DataAmsSlotInfo>> inBAMS{};
|
||||
wxPanel* statusBar{nullptr};
|
||||
wxBoxSizer* btnSizer{nullptr};
|
||||
Button* m_buttonClose{nullptr };
|
||||
Button* m_buttonRefresh{ nullptr };
|
||||
std::vector<wxColour>colourAdjust{wxColour("#675AFF")};
|
||||
std::vector<wxColour>colourOK{wxColour("#FF8181")};
|
||||
std::vector<wxColour>colourUnused{wxColour("#FF818140")};
|
||||
// wxStaticBitmap* m_bitmapSelectMachine{nullptr};
|
||||
};
|
||||
|
||||
wxDECLARE_EVENT(wxEVT_REFRESH_DATA, wxCommandEvent);
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
@@ -23,16 +23,16 @@ uiAmsPercentHumidityDryPopup::uiAmsPercentHumidityDryPopup(wxWindow *parent)
|
||||
: wxDialog(parent, wxID_ANY, "")
|
||||
{
|
||||
Create();
|
||||
wxGetApp().UpdateDlgDarkUI(this);
|
||||
wxGetApp().UpdateDlgDarkUI(this); // Orca: apply dark-mode theming to the popup
|
||||
}
|
||||
|
||||
void uiAmsPercentHumidityDryPopup::Create()
|
||||
{
|
||||
// create images
|
||||
idle_img = ScalableBitmap(this, "ams_drying", 16);
|
||||
drying_img = ScalableBitmap(this, "ams_is_drying", 16);
|
||||
drying_img = ScalableBitmap(this, "ams_is_drying", 16); // Orca: use the drying-state icon
|
||||
|
||||
// background
|
||||
// background
|
||||
SetBackgroundColour(*wxWHITE);
|
||||
|
||||
// create title sizer
|
||||
@@ -147,7 +147,8 @@ void uiAmsPercentHumidityDryPopup::UpdateContents()
|
||||
// table grid
|
||||
const wxString& humidity_str = wxString::Format("%d%%", m_humidity_percent);
|
||||
m_humidity_label->SetLabel(humidity_str);
|
||||
const wxString& temp_str = wxString::Format(wxString::FromUTF8(u8"%d\u2103" /* °C */), (int)std::round(m_current_temperature));
|
||||
// Orca: format the temperature with an explicit UTF-8 \u2103 (no translation of a units-only format)
|
||||
const wxString& temp_str = wxString::Format(wxString::FromUTF8(u8"%d\u2103" /* \u00b0C */), (int)std::round(m_current_temperature));
|
||||
m_temperature_label->SetLabel(temp_str);
|
||||
|
||||
if (m_left_dry_time > 0)
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Slic3r { namespace GUI {
|
||||
struct uiAmsHumidityInfo
|
||||
{
|
||||
std::string ams_id;
|
||||
AMSModel ams_type;
|
||||
AMSModel ams_type; // Orca: GUI-layer AMS enum; consumer (AMSItem.cpp) assigns an AMSModel
|
||||
int humidity_display_idx = -1;
|
||||
int humidity_percent = -1;
|
||||
float current_temperature;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#include "slic3r/GUI/I18N.hpp"
|
||||
#include "slic3r/GUI/wxExtensions.hpp"
|
||||
#include "slic3r/GUI/Widgets/Label.hpp"
|
||||
#include "slic3r/GUI/Widgets/Label.hpp" // Orca: explicit Label include
|
||||
|
||||
#include <wx/stattext.h>
|
||||
|
||||
@@ -81,7 +81,6 @@ void uiDeviceUpdateVersion::CreateWidgets()
|
||||
serial_text->SetFont(font);
|
||||
version_text->SetFont(font);
|
||||
model_text->SetFont(font);
|
||||
|
||||
// The grid sizer
|
||||
wxFlexGridSizer* grid_sizer = new wxFlexGridSizer(0, 2, 0, 0);
|
||||
//grid_sizer->AddGrowableCol(1);
|
||||
@@ -103,10 +102,10 @@ void uiDeviceUpdateVersion::CreateWidgets()
|
||||
|
||||
grid_sizer->Add(version_hsizer, 0, wxEXPAND, 0);
|
||||
grid_sizer->Add(m_dev_version, 0, wxEXPAND | wxALL, FromDIP(5));
|
||||
|
||||
|
||||
// Updating
|
||||
wxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
main_sizer->AddSpacer(FromDIP(40));
|
||||
main_sizer->AddSpacer(FromDIP(40)); // Orca: top spacing above the firmware-info grid
|
||||
main_sizer->Add(grid_sizer, 0, wxALIGN_LEFT, FromDIP(5));
|
||||
|
||||
SetSizer(main_sizer);
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
//**********************************************************/
|
||||
/* File: wgtDeviceNozzleRack.cpp
|
||||
* Description: The Device-tab panel with the toolhead nozzle and the H2C induction hotend rack.
|
||||
* Description: The panel with rack info
|
||||
*
|
||||
* \n class wgtDeviceNozzleRack;
|
||||
* \n class wgtDeviceNozzleRackToolHead;
|
||||
* \n class wgtDeviceNozzleRackArea;
|
||||
* \n class wgtDeviceNozzleRackNozzleItem;
|
||||
* \n class wgtDeviceNozzleRackToolHead;
|
||||
* \n class wgtDeviceNozzleRackPos;
|
||||
*
|
||||
* The wgtDeviceNozzleRackNozzleItem tile and the EVT_NOZZLE_RACK_NOZZLE_ITEM_SELECTED event live in
|
||||
* wgtDeviceNozzleRackNozzleItem.{h,cpp}, so they are not redefined here.
|
||||
//**********************************************************/
|
||||
|
||||
#include "wgtDeviceNozzleRack.h"
|
||||
@@ -17,29 +14,41 @@
|
||||
#include "slic3r/GUI/DeviceCore/DevNozzleSystem.h"
|
||||
|
||||
#include "slic3r/GUI/I18N.hpp"
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/MainFrame.hpp"
|
||||
#include "slic3r/GUI/MsgDialog.hpp"
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/wxExtensions.hpp"
|
||||
|
||||
#include "slic3r/GUI/Widgets/Button.hpp"
|
||||
#include "slic3r/GUI/Widgets/Label.hpp"
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
#define WX_DIP_SIZE_18 wxSize(FromDIP(18), FromDIP(18))
|
||||
#define WX_DIP_SIZE_46 wxSize(FromDIP(46), FromDIP(46))
|
||||
#define WX_DIP_SIZE(x, y) wxSize(FromDIP(x), FromDIP(y))
|
||||
|
||||
#define WGT_RACK_NOZZLE_SIZE WX_DIP_SIZE(88, 100)
|
||||
|
||||
#define L_RAW_A_STR _L("Row A")
|
||||
#define L_RAW_B_STR _L("Row B")
|
||||
|
||||
static wxColour s_gray_clr("#B0B0B0");
|
||||
static wxColour s_hgreen_clr("#009688"); // Orca: accent green
|
||||
static wxColour s_red_clr("#D01B1B");
|
||||
|
||||
// Orca: StateColor lacks these grey constants, so mirror the values here.
|
||||
static const wxColour WGT_GREY200 = wxColour(248, 248, 248);
|
||||
static const wxColour WGT_GREY300 = wxColour(238, 238, 238);
|
||||
|
||||
static wxColour s_hgreen_clr("#009688");
|
||||
static std::vector<int> a_nozzle_seq = { 0, 2, 4, 1, 3, 5 };
|
||||
static std::vector<int> b_nozzle_seq = { 1, 3, 5, 0, 2, 4 };
|
||||
|
||||
wxDEFINE_EVENT(EVT_NOZZLE_RACK_NOZZLE_ITEM_SELECTED, wxCommandEvent);
|
||||
|
||||
namespace Slic3r::GUI
|
||||
{
|
||||
|
||||
// Tints the "yellow" template pixels of a nozzle bitmap with the loaded filament colour.
|
||||
// Duplicates the file-local helper of the same purpose in wgtDeviceNozzleRackNozzleItem.cpp.
|
||||
static wxBitmap SetNozzleBmpColor(const wxBitmap& bmp, const std::string& color_str) {
|
||||
if(color_str.empty()) return bmp;
|
||||
|
||||
@@ -353,6 +362,36 @@ StaticBox* wgtDeviceNozzleRackArea::CreateNozzleBox(const std::vector<int> nozzl
|
||||
return nozzle_box;
|
||||
}
|
||||
|
||||
static void s_update_title(const std::shared_ptr<DevNozzleRack> rack, wgtDeviceNozzleRackTitle* title_label)
|
||||
{
|
||||
wxString title = _L("Induction Hotend Rack");
|
||||
if (rack && (rack->GetReadingCount() > 0))
|
||||
{
|
||||
wxString pending = ": " + _L("Reading") + wxString::Format(" %d/%d", rack->GetReadingIdx(), rack->GetReadingCount());
|
||||
title += pending;
|
||||
}
|
||||
|
||||
title_label->SetLabel(title);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void s_update_readall_btn(const std::shared_ptr<DevNozzleRack> rack, Button* btn)
|
||||
{
|
||||
wxString label = _L("Read All");
|
||||
if (rack && rack->HasUnreliableNozzles())
|
||||
{
|
||||
label += "*";
|
||||
}
|
||||
|
||||
if (btn->GetLabel() != label)
|
||||
{
|
||||
btn->SetLabel(label);
|
||||
}
|
||||
|
||||
btn->Enable(rack->CtrlCanReadAll());
|
||||
};
|
||||
#endif
|
||||
|
||||
void wgtDeviceNozzleRackArea::UpdateNozzleItems(const std::unordered_map<int, wgtDeviceNozzleRackNozzleItem*>& nozzle_items,
|
||||
std::shared_ptr<DevNozzleRack> nozzle_rack)
|
||||
{
|
||||
@@ -409,6 +448,7 @@ void wgtDeviceNozzleRackArea::UpdateRackInfo(std::weak_ptr<DevNozzleRack> rack)
|
||||
const auto& nozzle_rack = rack.lock();
|
||||
if (nozzle_rack)
|
||||
{
|
||||
// s_update_title(nozzle_rack, m_title_nozzle_rack);
|
||||
UpdateNozzleItems(m_nozzle_items, nozzle_rack);
|
||||
m_rack_pos_panel->UpdateRackPos(nozzle_rack);
|
||||
m_btn_read_all->Enable(nozzle_rack->CtrlCanReadAll());
|
||||
@@ -571,7 +611,7 @@ static void s_show_label(Label* label, const wxString& text, const wxColour& tex
|
||||
void wgtDeviceNozzleRackPos::UpdateRackPos(DevNozzleRack::RackPos new_pos,
|
||||
DevNozzleRack::RackStatus new_status, bool is_reading)
|
||||
{
|
||||
// While reading, both rows show a "Running..." status and the move buttons are hidden.
|
||||
/* di*/
|
||||
if (is_reading)
|
||||
{
|
||||
s_show_label(m_label_rowup, L_RAW_A_STR, *wxBLACK);
|
||||
@@ -697,4 +737,298 @@ void wgtDeviceNozzleRackPos::Rescale()
|
||||
m_btn_homing->msw_rescale();
|
||||
}
|
||||
|
||||
};// end of namespace Slic3r::GUI
|
||||
wgtDeviceNozzleRackNozzleItem::wgtDeviceNozzleRackNozzleItem(wxWindow* parent, int nozzle_id)
|
||||
: StaticBox(parent, wxID_ANY), m_nozzle_id(nozzle_id)
|
||||
{
|
||||
CreateGui();
|
||||
}
|
||||
|
||||
void wgtDeviceNozzleRackNozzleItem::CreateGui()
|
||||
{
|
||||
// Background
|
||||
SetCornerRadius(FromDIP(5));
|
||||
SetBackgroundColor(*wxWHITE);
|
||||
|
||||
// Top H
|
||||
wxSizer *top_h_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
m_nozzle_label_id = new Label(this);
|
||||
m_nozzle_label_id->SetFont(Label::Body_12);
|
||||
m_nozzle_label_id->SetBackgroundColour(*wxWHITE);
|
||||
m_nozzle_label_id->SetLabel(wxString::Format("%d", m_nozzle_id + 1));
|
||||
|
||||
m_status = NOZZLE_STATUS::NOZZLE_EMPTY;
|
||||
m_nozzle_empty_image = new ScalableBitmap(this, "dev_rack_nozzle_empty", 46);
|
||||
m_nozzle_icon = new wxStaticBitmap(this, wxID_ANY, m_nozzle_empty_image->bmp(), wxDefaultPosition, WX_DIP_SIZE_46);
|
||||
m_nozzle_icon->SetBackgroundColour(*wxWHITE);
|
||||
|
||||
m_nozzle_selected_bitmap = new wxStaticBitmap(this, wxID_ANY, wxNullBitmap, wxDefaultPosition, WX_DIP_SIZE(20, 20));
|
||||
m_nozzle_selected_bitmap->SetBackgroundColour(*wxWHITE);
|
||||
|
||||
top_h_sizer->Add(m_nozzle_label_id, 0, wxTOP | wxLEFT, FromDIP(6));
|
||||
top_h_sizer->AddStretchSpacer(1);
|
||||
top_h_sizer->Add(m_nozzle_icon, 0, wxTOP, FromDIP(10));
|
||||
top_h_sizer->AddStretchSpacer(1);
|
||||
top_h_sizer->Add(m_nozzle_selected_bitmap, 0, wxTOP | wxRIGHT, FromDIP(2));
|
||||
|
||||
// Bottom V
|
||||
wxBoxSizer* bottom_v = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
wxSizer* label_h_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_nozzle_label_1 = new Label(this);
|
||||
m_nozzle_label_1->SetFont(Label::Body_12);
|
||||
m_nozzle_label_1->SetBackgroundColour(*wxWHITE);
|
||||
m_nozzle_label_1->SetLabel(_L("Empty"));
|
||||
|
||||
label_h_sizer->Add(m_nozzle_label_1, 0, wxALIGN_LEFT);
|
||||
|
||||
auto status_icon = create_scaled_bitmap("dev_rack_nozzle_error_icon", this, 14);
|
||||
m_nozzle_status_icon = new wxStaticBitmap(this, wxID_ANY, status_icon, wxDefaultPosition, WX_DIP_SIZE(14, 14));
|
||||
m_nozzle_status_icon->Bind(wxEVT_LEFT_DOWN, &wgtDeviceNozzleRackNozzleItem::OnBtnNozzleStatus, this);
|
||||
m_nozzle_status_icon->Bind(wxEVT_ENTER_WINDOW, [this](auto&) { SetCursor(wxCURSOR_HAND); });
|
||||
m_nozzle_status_icon->Bind(wxEVT_LEAVE_WINDOW, [this](auto&) { SetCursor(wxCURSOR_ARROW); });
|
||||
m_nozzle_status_icon->SetBackgroundColour(*wxWHITE);
|
||||
m_nozzle_status_icon->Show(false);
|
||||
|
||||
label_h_sizer->Add(m_nozzle_status_icon, 0, wxALIGN_CENTER | wxLEFT, FromDIP(2));
|
||||
bottom_v->Add(label_h_sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxTOP, FromDIP(2));
|
||||
|
||||
m_nozzle_label_2 = new Label(this);
|
||||
m_nozzle_label_2->SetFont(Label::Body_12);
|
||||
m_nozzle_label_2->SetBackgroundColour(*wxWHITE);
|
||||
bottom_v->Add(m_nozzle_label_2, 0, wxALIGN_CENTER_HORIZONTAL);
|
||||
|
||||
// Main sizer
|
||||
wxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
main_sizer->Add(top_h_sizer, 0, wxEXPAND);
|
||||
main_sizer->Add(bottom_v, 0, wxALIGN_CENTER_HORIZONTAL);
|
||||
SetSizer(main_sizer);
|
||||
|
||||
SetMinSize(WGT_RACK_NOZZLE_SIZE);
|
||||
SetMaxSize(WGT_RACK_NOZZLE_SIZE);
|
||||
SetSize(WGT_RACK_NOZZLE_SIZE);
|
||||
Layout();
|
||||
};
|
||||
|
||||
void wgtDeviceNozzleRackNozzleItem::SetSelected(bool selected)
|
||||
{
|
||||
if (!m_enable_select){
|
||||
assert(false && "not support select");
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_is_selected != selected) {
|
||||
m_is_selected = selected;
|
||||
if (selected) {
|
||||
if (!m_nozzle_selected_image) {
|
||||
m_nozzle_selected_image = new ScalableBitmap(this, "dev_rack_nozzle_selected", 20);
|
||||
}
|
||||
|
||||
m_nozzle_selected_bitmap->SetBitmap(m_nozzle_selected_image->bmp());
|
||||
SetBorderColor(StateColor::darkModeColorFor(s_hgreen_clr));
|
||||
} else {
|
||||
m_nozzle_selected_bitmap->SetBitmap(wxNullBitmap);
|
||||
SetBorderColor(StateColor::darkModeColorFor(s_gray_clr));
|
||||
}
|
||||
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
void wgtDeviceNozzleRackNozzleItem::Update(const std::shared_ptr<DevNozzleRack> rack, bool on_rack /*= true*/)
|
||||
{
|
||||
m_rack = rack;
|
||||
|
||||
if (rack) {
|
||||
const auto &nozzle_info = on_rack ? rack->GetNozzle(m_nozzle_id) : rack->GetNozzleSystem()->GetExtNozzle(m_nozzle_id);
|
||||
const wxString &diameter_str = nozzle_info.GetNozzleDiameterStr();
|
||||
const wxString &flowtype_str = nozzle_info.GetNozzleFlowTypeStr();
|
||||
const std::string &color = nozzle_info.GetFilamentColor();
|
||||
|
||||
/*check empty first*/
|
||||
if (nozzle_info.IsEmpty()) {
|
||||
SetNozzleStatus(NOZZLE_STATUS::NOZZLE_EMPTY, _L("Empty"), wxEmptyString, color);
|
||||
} else if (nozzle_info.IsNormal()) {
|
||||
SetNozzleStatus(NOZZLE_STATUS::NOZZLE_NORMAL, diameter_str, flowtype_str, color);
|
||||
} else if (nozzle_info.IsAbnormal()) {
|
||||
SetNozzleStatus(NOZZLE_STATUS::NOZZLE_ERROR, _L("Error"), wxEmptyString, color);
|
||||
} else if (nozzle_info.IsUnknown()) {
|
||||
SetNozzleStatus(NOZZLE_STATUS::NOZZLE_UNKNOWN, _L("Unknown"), wxEmptyString, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void wgtDeviceNozzleRackNozzleItem::SetNozzleStatus(NOZZLE_STATUS status, const wxString& str1, const wxString& str2, const std::string& color)
|
||||
{
|
||||
if (m_status != status || m_filament_color != color)
|
||||
{
|
||||
m_status = status;
|
||||
m_filament_color = color;
|
||||
switch (status)
|
||||
{
|
||||
case Slic3r::GUI::wgtDeviceNozzleRackNozzleItem::NOZZLE_EMPTY:
|
||||
{
|
||||
if (!m_nozzle_empty_image) { m_nozzle_empty_image = new ScalableBitmap(this, "dev_rack_nozzle_empty", 46);}
|
||||
m_nozzle_icon->SetBitmap(m_nozzle_empty_image->bmp());
|
||||
break;
|
||||
}
|
||||
case Slic3r::GUI::wgtDeviceNozzleRackNozzleItem::NOZZLE_NORMAL:
|
||||
{
|
||||
if (!m_nozzle_normal_image) { m_nozzle_normal_image = new ScalableBitmap(this, "dev_rack_nozzle_normal", 46);}
|
||||
m_nozzle_icon->SetBitmap(SetNozzleBmpColor(m_nozzle_normal_image->bmp(), m_filament_color));
|
||||
break;
|
||||
}
|
||||
case Slic3r::GUI::wgtDeviceNozzleRackNozzleItem::NOZZLE_UNKNOWN:
|
||||
{
|
||||
if (!m_nozzle_unknown_image) { m_nozzle_unknown_image = new ScalableBitmap(this, "dev_rack_nozzle_unknown", 46);}
|
||||
m_nozzle_icon->SetBitmap(m_nozzle_unknown_image->bmp());
|
||||
break;
|
||||
}
|
||||
case Slic3r::GUI::wgtDeviceNozzleRackNozzleItem::NOZZLE_ERROR:
|
||||
{
|
||||
if (!m_nozzle_error_image) { m_nozzle_error_image = new ScalableBitmap(this, "dev_rack_nozzle_error", 46);}
|
||||
m_nozzle_icon->SetBitmap(m_nozzle_error_image->bmp());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (status == wgtDeviceNozzleRackNozzleItem::NOZZLE_ERROR)
|
||||
{
|
||||
m_nozzle_label_1->SetForegroundColour(StateColor::darkModeColorFor(s_red_clr));
|
||||
m_nozzle_status_icon->Show(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_nozzle_label_1->SetForegroundColour(StateColor::darkModeColorFor(*wxBLACK));
|
||||
m_nozzle_status_icon->Show(false);
|
||||
}
|
||||
}
|
||||
|
||||
bool update_layout = (m_nozzle_label_1->GetLabel() != str1 || m_nozzle_label_2->GetLabel() != str2);
|
||||
m_nozzle_label_1->SetLabel(str1);
|
||||
m_nozzle_label_2->SetLabel(str2);
|
||||
|
||||
if (update_layout) {
|
||||
Layout();
|
||||
}
|
||||
}
|
||||
|
||||
void wgtDeviceNozzleRackNozzleItem::OnBtnNozzleStatus(wxMouseEvent& evt)
|
||||
{
|
||||
if (m_is_disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto rack = m_rack.lock();
|
||||
if (rack && m_status == wgtDeviceNozzleRackNozzleItem::NOZZLE_ERROR)
|
||||
{
|
||||
MessageDialog dlg(nullptr, _L("The hotend is in an abnormal state and currently unavailable. "
|
||||
"Please go to 'Device -> Upgrade' to upgrade firmware."), _L("Abnormal Hotend"), wxICON_WARNING);
|
||||
dlg.AddButton(wxID_CANCEL, _L("Cancel"), false);
|
||||
dlg.AddButton(wxID_OK,_L("Jump to the upgrade page"), true);
|
||||
|
||||
if (dlg.ShowModal() == wxID_OK) {
|
||||
wxGetApp().mainframe->m_monitor->jump_to_Upgrade();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
void wgtDeviceNozzleRackNozzleItem::Rescale()
|
||||
{
|
||||
if (m_nozzle_normal_image) { m_nozzle_normal_image->msw_rescale(); }
|
||||
if (m_nozzle_empty_image) { m_nozzle_empty_image->msw_rescale(); }
|
||||
if (m_nozzle_unknown_image) { m_nozzle_unknown_image->msw_rescale(); }
|
||||
if (m_nozzle_error_image) { m_nozzle_error_image->msw_rescale(); }
|
||||
|
||||
auto status_icon = create_scaled_bitmap("dev_rack_nozzle_error_icon", this, 14);
|
||||
m_nozzle_status_icon->SetBitmap(status_icon);
|
||||
m_nozzle_status_icon->Refresh();
|
||||
|
||||
if (m_nozzle_selected_image) {
|
||||
m_nozzle_selected_image->msw_rescale();
|
||||
if (m_is_selected) {
|
||||
m_nozzle_selected_bitmap->SetBitmap(m_nozzle_selected_image->bmp());
|
||||
}
|
||||
};
|
||||
|
||||
switch (m_status)
|
||||
{
|
||||
case Slic3r::GUI::wgtDeviceNozzleRackNozzleItem::NOZZLE_EMPTY:
|
||||
{
|
||||
m_nozzle_icon->SetBitmap(m_nozzle_empty_image->bmp());
|
||||
break;
|
||||
}
|
||||
case Slic3r::GUI::wgtDeviceNozzleRackNozzleItem::NOZZLE_NORMAL:
|
||||
{
|
||||
m_nozzle_icon->SetBitmap(SetNozzleBmpColor(m_nozzle_normal_image->bmp(), m_filament_color));
|
||||
break;
|
||||
}
|
||||
case Slic3r::GUI::wgtDeviceNozzleRackNozzleItem::NOZZLE_UNKNOWN:
|
||||
{
|
||||
m_nozzle_icon->SetBitmap(m_nozzle_unknown_image->bmp());
|
||||
break;
|
||||
}
|
||||
case Slic3r::GUI::wgtDeviceNozzleRackNozzleItem::NOZZLE_ERROR:
|
||||
{
|
||||
m_nozzle_icon->SetBitmap(m_nozzle_error_image->bmp());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void wgtDeviceNozzleRackNozzleItem::EnableSelect()
|
||||
{
|
||||
if (m_enable_select == true) {
|
||||
return;
|
||||
};
|
||||
|
||||
m_enable_select = true;
|
||||
m_nozzle_icon->Bind(wxEVT_LEFT_DOWN, [this](auto& evt) { OnItemSelected(evt); });
|
||||
m_nozzle_label_id->Bind(wxEVT_LEFT_DOWN, [this](auto& evt) { OnItemSelected(evt); });
|
||||
m_nozzle_label_1->Bind(wxEVT_LEFT_DOWN, [this](auto& evt) { OnItemSelected(evt); });
|
||||
m_nozzle_label_2->Bind(wxEVT_LEFT_DOWN, [this](auto& evt) { OnItemSelected(evt); });
|
||||
Bind(wxEVT_LEFT_DOWN, [this](auto& evt) { OnItemSelected(evt); });
|
||||
}
|
||||
|
||||
void wgtDeviceNozzleRackNozzleItem::OnItemSelected(wxMouseEvent& evt)
|
||||
{
|
||||
if (m_enable_select && !m_is_disabled){
|
||||
SetSelected(true);
|
||||
wxCommandEvent command_evt(EVT_NOZZLE_RACK_NOZZLE_ITEM_SELECTED, GetId());
|
||||
command_evt.SetEventObject(this);
|
||||
ProcessEvent(command_evt);
|
||||
}
|
||||
|
||||
evt.Skip();
|
||||
}
|
||||
|
||||
|
||||
void wgtDeviceNozzleRackNozzleItem::SetDisable(bool disabled)
|
||||
{
|
||||
if (m_is_disabled == disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_is_disabled = disabled;
|
||||
|
||||
auto bg_clr = disabled ? StateColor::darkModeColorFor("#E5E7EB") : StateColor::darkModeColorFor(*wxWHITE);
|
||||
m_nozzle_icon->SetBackgroundColour(bg_clr);
|
||||
m_nozzle_label_id->SetBackgroundColour(bg_clr);
|
||||
m_nozzle_label_1->SetBackgroundColour(bg_clr);
|
||||
m_nozzle_status_icon->SetBackgroundColour(bg_clr);
|
||||
m_nozzle_label_2->SetBackgroundColour(bg_clr);
|
||||
m_nozzle_selected_bitmap->SetBackgroundColour(bg_clr);
|
||||
|
||||
SetBackgroundColor(bg_clr);
|
||||
Refresh();
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -1,31 +1,22 @@
|
||||
//**********************************************************/
|
||||
/* File: wgtDeviceNozzleRack.h
|
||||
* Description: The Device-tab panel with the toolhead nozzle and the H2C induction hotend rack.
|
||||
* Description: The panel with rack and nozzles
|
||||
*
|
||||
* \n class wgtDeviceNozzleRack; // toolhead panel + rack area, side by side
|
||||
* \n class wgtDeviceNozzleRackToolHead;
|
||||
* \n class wgtDeviceNozzleRackArea;
|
||||
* \n class wgtDeviceNozzleRackNozzleItem;
|
||||
* \n class wgtDeviceNozzleRackToolHead;
|
||||
* \n class wgtDeviceNozzleRackPos;
|
||||
*
|
||||
* The single-nozzle tile class wgtDeviceNozzleRackNozzleItem lives in its own translation unit
|
||||
* (wgtDeviceNozzleRackNozzleItem.{h,cpp}), so it is included here rather than redeclared.
|
||||
* The Hotends-Info upgrade dialog (wgtDeviceNozzleRackUpgradeDlg) is intentionally not wired yet
|
||||
* (see the TODO markers in the .cpp).
|
||||
//**********************************************************/
|
||||
|
||||
#pragma once
|
||||
#include "slic3r/GUI/DeviceCore/DevNozzleRack.h"
|
||||
|
||||
#include "wgtDeviceNozzleRackNozzleItem.h"
|
||||
|
||||
#include "slic3r/GUI/Widgets/StaticBox.hpp"
|
||||
#include "slic3r/GUI/Widgets/AnimaController.hpp"
|
||||
|
||||
#include <wx/panel.h>
|
||||
#include <wx/simplebook.h>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
// Previous definitions
|
||||
class Button;
|
||||
@@ -47,6 +38,9 @@ namespace GUI
|
||||
}
|
||||
};
|
||||
|
||||
// Events
|
||||
wxDECLARE_EVENT(EVT_NOZZLE_RACK_NOZZLE_ITEM_SELECTED, wxCommandEvent);
|
||||
|
||||
namespace Slic3r::GUI
|
||||
{
|
||||
class wgtDeviceNozzleRack : public wxPanel
|
||||
@@ -148,8 +142,6 @@ private:
|
||||
Label* m_progress_refresh{ nullptr };
|
||||
AnimaIcon* m_refresh_icon{ nullptr };
|
||||
|
||||
// "Hotends Info" upgrade dialog. Owned for its ShowModal lifetime by
|
||||
// OnBtnHotendsInfos; UpdateRackInfo forwards live device pushes to it while it is shown.
|
||||
wgtDeviceNozzleRackUpgradeDlg* m_rack_upgrade_dlg = nullptr;
|
||||
};
|
||||
|
||||
@@ -193,4 +185,71 @@ private:
|
||||
ScalableButton* m_btn_homing{ nullptr };
|
||||
};
|
||||
|
||||
};// end of namespace Slic3r::GUI
|
||||
class wgtDeviceNozzleRackNozzleItem : public StaticBox
|
||||
{
|
||||
public:
|
||||
enum NOZZLE_STATUS
|
||||
{
|
||||
NOZZLE_EMPTY,
|
||||
NOZZLE_NORMAL,
|
||||
NOZZLE_UNKNOWN,
|
||||
NOZZLE_ERROR
|
||||
};
|
||||
|
||||
public:
|
||||
wgtDeviceNozzleRackNozzleItem(wxWindow* parent, int nozzle_id);
|
||||
|
||||
public:
|
||||
void Update(const std::shared_ptr<DevNozzleRack> rack, bool on_rack = true); // on_rack is false means extruder nozzle
|
||||
|
||||
int GetNozzleId() const { return m_nozzle_id; }
|
||||
void SetDisplayIdText(const wxString& text) { m_nozzle_label_id->SetLabel(text);};
|
||||
|
||||
void EnableSelect();;
|
||||
void SetSelected(bool selected);
|
||||
bool IsSelected() const { return m_is_selected; }
|
||||
|
||||
bool IsDisabled() const { return m_is_disabled; }
|
||||
void SetDisable(bool disabled);
|
||||
|
||||
void Rescale();
|
||||
|
||||
private:
|
||||
void CreateGui();
|
||||
|
||||
void SetNozzleStatus(NOZZLE_STATUS status, const wxString& str1, const wxString& str2, const std::string& color);
|
||||
|
||||
void OnBtnNozzleStatus(wxMouseEvent& evt);
|
||||
void OnItemSelected(wxMouseEvent& evt);
|
||||
|
||||
private:
|
||||
std::weak_ptr<DevNozzleRack> m_rack;
|
||||
|
||||
int m_nozzle_id; // internal id, from 0 to 5
|
||||
std::string m_filament_color;
|
||||
NOZZLE_STATUS m_status = NOZZLE_STATUS::NOZZLE_EMPTY;
|
||||
|
||||
// select
|
||||
bool m_is_selected = false;
|
||||
bool m_enable_select = false;
|
||||
ScalableBitmap* m_nozzle_selected_image{ nullptr };
|
||||
wxStaticBitmap* m_nozzle_selected_bitmap{ nullptr };
|
||||
|
||||
// enable or disable
|
||||
bool m_is_disabled = false;
|
||||
|
||||
// Images
|
||||
ScalableBitmap* m_nozzle_normal_image{ nullptr };
|
||||
ScalableBitmap* m_nozzle_empty_image{ nullptr };
|
||||
ScalableBitmap* m_nozzle_unknown_image{ nullptr };
|
||||
ScalableBitmap* m_nozzle_error_image{ nullptr };
|
||||
|
||||
// GUI
|
||||
wxStaticBitmap* m_nozzle_icon{ nullptr };
|
||||
Label* m_nozzle_label_id { nullptr };
|
||||
Label* m_nozzle_label_1{ nullptr };
|
||||
wxStaticBitmap* m_nozzle_status_icon = nullptr;
|
||||
Label* m_nozzle_label_2{ nullptr };
|
||||
};
|
||||
|
||||
};// end of namespace Slic3r::GUI
|
||||
@@ -1,347 +0,0 @@
|
||||
//**********************************************************/
|
||||
/* File: wgtDeviceNozzleRackNozzleItem.cpp
|
||||
* Description: One nozzle cell of the H2C hotend rack view. Holds the
|
||||
* wgtDeviceNozzleRackNozzleItem widget, the SetNozzleBmpColor helper and the layout
|
||||
* constants it needs.
|
||||
//**********************************************************/
|
||||
|
||||
#include "wgtDeviceNozzleRackNozzleItem.h"
|
||||
|
||||
#include "slic3r/GUI/DeviceCore/DevNozzleSystem.h"
|
||||
|
||||
#include "slic3r/GUI/I18N.hpp"
|
||||
#include "slic3r/GUI/MsgDialog.hpp"
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/wxExtensions.hpp"
|
||||
|
||||
#include "slic3r/GUI/Widgets/Label.hpp"
|
||||
|
||||
#define WX_DIP_SIZE_46 wxSize(FromDIP(46), FromDIP(46))
|
||||
#define WX_DIP_SIZE(x, y) wxSize(FromDIP(x), FromDIP(y))
|
||||
|
||||
#define WGT_RACK_NOZZLE_SIZE WX_DIP_SIZE(88, 100)
|
||||
|
||||
static wxColour s_gray_clr("#B0B0B0");
|
||||
static wxColour s_hgreen_clr("#009688");
|
||||
static wxColour s_red_clr("#D01B1B");
|
||||
|
||||
wxDEFINE_EVENT(EVT_NOZZLE_RACK_NOZZLE_ITEM_SELECTED, wxCommandEvent);
|
||||
|
||||
namespace Slic3r::GUI
|
||||
{
|
||||
|
||||
static wxBitmap SetNozzleBmpColor(const wxBitmap& bmp, const std::string& color_str) {
|
||||
if(color_str.empty()) return bmp;
|
||||
|
||||
wxImage img = bmp.ConvertToImage();
|
||||
wxColour color("#" + color_str);
|
||||
|
||||
for (int y = 0; y < img.GetHeight(); ++y) {
|
||||
for (int x = 0; x < img.GetWidth(); ++x) {
|
||||
unsigned char r = img.GetRed(x, y);
|
||||
unsigned char g = img.GetGreen(x, y);
|
||||
unsigned char b = img.GetBlue(x, y);
|
||||
|
||||
/*replace yellow with color*/
|
||||
if ( r >= 180 && g >= 180 && b <= 150) {
|
||||
img.SetRGB(x, y, color.Red(), color.Green(), color.Blue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return wxBitmap(img, -1, bmp.GetScaleFactor());
|
||||
}
|
||||
|
||||
wgtDeviceNozzleRackNozzleItem::wgtDeviceNozzleRackNozzleItem(wxWindow* parent, int nozzle_id)
|
||||
: StaticBox(parent, wxID_ANY), m_nozzle_id(nozzle_id)
|
||||
{
|
||||
CreateGui();
|
||||
}
|
||||
|
||||
void wgtDeviceNozzleRackNozzleItem::CreateGui()
|
||||
{
|
||||
// Background
|
||||
SetCornerRadius(FromDIP(5));
|
||||
SetBackgroundColor(*wxWHITE);
|
||||
|
||||
// Top H
|
||||
wxSizer *top_h_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
m_nozzle_label_id = new Label(this);
|
||||
m_nozzle_label_id->SetFont(Label::Body_12);
|
||||
m_nozzle_label_id->SetBackgroundColour(*wxWHITE);
|
||||
m_nozzle_label_id->SetLabel(wxString::Format("%d", m_nozzle_id + 1));
|
||||
|
||||
m_status = NOZZLE_STATUS::NOZZLE_EMPTY;
|
||||
m_nozzle_empty_image = new ScalableBitmap(this, "dev_rack_nozzle_empty", 46);
|
||||
m_nozzle_icon = new wxStaticBitmap(this, wxID_ANY, m_nozzle_empty_image->bmp(), wxDefaultPosition, WX_DIP_SIZE_46);
|
||||
m_nozzle_icon->SetBackgroundColour(*wxWHITE);
|
||||
|
||||
m_nozzle_selected_bitmap = new wxStaticBitmap(this, wxID_ANY, wxNullBitmap, wxDefaultPosition, WX_DIP_SIZE(20, 20));
|
||||
m_nozzle_selected_bitmap->SetBackgroundColour(*wxWHITE);
|
||||
|
||||
top_h_sizer->Add(m_nozzle_label_id, 0, wxTOP | wxLEFT, FromDIP(6));
|
||||
top_h_sizer->AddStretchSpacer(1);
|
||||
top_h_sizer->Add(m_nozzle_icon, 0, wxTOP, FromDIP(10));
|
||||
top_h_sizer->AddStretchSpacer(1);
|
||||
top_h_sizer->Add(m_nozzle_selected_bitmap, 0, wxTOP | wxRIGHT, FromDIP(2));
|
||||
|
||||
// Bottom V
|
||||
wxBoxSizer* bottom_v = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
wxSizer* label_h_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_nozzle_label_1 = new Label(this);
|
||||
m_nozzle_label_1->SetFont(Label::Body_12);
|
||||
m_nozzle_label_1->SetBackgroundColour(*wxWHITE);
|
||||
m_nozzle_label_1->SetLabel(_L("Empty"));
|
||||
|
||||
label_h_sizer->Add(m_nozzle_label_1, 0, wxALIGN_LEFT);
|
||||
|
||||
auto status_icon = create_scaled_bitmap("dev_rack_nozzle_error_icon", this, 14);
|
||||
m_nozzle_status_icon = new wxStaticBitmap(this, wxID_ANY, status_icon, wxDefaultPosition, WX_DIP_SIZE(14, 14));
|
||||
m_nozzle_status_icon->Bind(wxEVT_LEFT_DOWN, &wgtDeviceNozzleRackNozzleItem::OnBtnNozzleStatus, this);
|
||||
m_nozzle_status_icon->Bind(wxEVT_ENTER_WINDOW, [this](auto&) { SetCursor(wxCURSOR_HAND); });
|
||||
m_nozzle_status_icon->Bind(wxEVT_LEAVE_WINDOW, [this](auto&) { SetCursor(wxCURSOR_ARROW); });
|
||||
m_nozzle_status_icon->SetBackgroundColour(*wxWHITE);
|
||||
m_nozzle_status_icon->Show(false);
|
||||
|
||||
label_h_sizer->Add(m_nozzle_status_icon, 0, wxALIGN_CENTER | wxLEFT, FromDIP(2));
|
||||
bottom_v->Add(label_h_sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxTOP, FromDIP(2));
|
||||
|
||||
m_nozzle_label_2 = new Label(this);
|
||||
m_nozzle_label_2->SetFont(Label::Body_12);
|
||||
m_nozzle_label_2->SetBackgroundColour(*wxWHITE);
|
||||
bottom_v->Add(m_nozzle_label_2, 0, wxALIGN_CENTER_HORIZONTAL);
|
||||
|
||||
// Main sizer
|
||||
wxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
main_sizer->Add(top_h_sizer, 0, wxEXPAND);
|
||||
main_sizer->Add(bottom_v, 0, wxALIGN_CENTER_HORIZONTAL);
|
||||
SetSizer(main_sizer);
|
||||
|
||||
SetMinSize(WGT_RACK_NOZZLE_SIZE);
|
||||
SetMaxSize(WGT_RACK_NOZZLE_SIZE);
|
||||
SetSize(WGT_RACK_NOZZLE_SIZE);
|
||||
Layout();
|
||||
};
|
||||
|
||||
void wgtDeviceNozzleRackNozzleItem::SetSelected(bool selected)
|
||||
{
|
||||
if (!m_enable_select){
|
||||
assert(false && "not support select");
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_is_selected != selected) {
|
||||
m_is_selected = selected;
|
||||
if (selected) {
|
||||
if (!m_nozzle_selected_image) {
|
||||
m_nozzle_selected_image = new ScalableBitmap(this, "dev_rack_nozzle_selected", 20);
|
||||
}
|
||||
|
||||
m_nozzle_selected_bitmap->SetBitmap(m_nozzle_selected_image->bmp());
|
||||
SetBorderColor(StateColor::darkModeColorFor(s_hgreen_clr));
|
||||
} else {
|
||||
m_nozzle_selected_bitmap->SetBitmap(wxNullBitmap);
|
||||
SetBorderColor(StateColor::darkModeColorFor(s_gray_clr));
|
||||
}
|
||||
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
void wgtDeviceNozzleRackNozzleItem::Update(const std::shared_ptr<DevNozzleRack> rack, bool on_rack /*= true*/)
|
||||
{
|
||||
m_rack = rack;
|
||||
|
||||
if (rack) {
|
||||
const auto &nozzle_info = on_rack ? rack->GetNozzle(m_nozzle_id) : rack->GetNozzleSystem()->GetExtNozzle(m_nozzle_id);
|
||||
const wxString &diameter_str = nozzle_info.GetNozzleDiameterStr();
|
||||
const wxString &flowtype_str = nozzle_info.GetNozzleFlowTypeStr();
|
||||
const std::string &color = nozzle_info.GetFilamentColor();
|
||||
|
||||
/*check empty first*/
|
||||
if (nozzle_info.IsEmpty()) {
|
||||
SetNozzleStatus(NOZZLE_STATUS::NOZZLE_EMPTY, _L("Empty"), wxEmptyString, color);
|
||||
} else if (nozzle_info.IsNormal()) {
|
||||
SetNozzleStatus(NOZZLE_STATUS::NOZZLE_NORMAL, diameter_str, flowtype_str, color);
|
||||
} else if (nozzle_info.IsAbnormal()) {
|
||||
SetNozzleStatus(NOZZLE_STATUS::NOZZLE_ERROR, _L("Error"), wxEmptyString, color);
|
||||
} else if (nozzle_info.IsUnknown()) {
|
||||
SetNozzleStatus(NOZZLE_STATUS::NOZZLE_UNKNOWN, _L("Unknown"), wxEmptyString, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void wgtDeviceNozzleRackNozzleItem::SetNozzleStatus(NOZZLE_STATUS status, const wxString& str1, const wxString& str2, const std::string& color)
|
||||
{
|
||||
if (m_status != status || m_filament_color != color)
|
||||
{
|
||||
m_status = status;
|
||||
m_filament_color = color;
|
||||
switch (status)
|
||||
{
|
||||
case Slic3r::GUI::wgtDeviceNozzleRackNozzleItem::NOZZLE_EMPTY:
|
||||
{
|
||||
if (!m_nozzle_empty_image) { m_nozzle_empty_image = new ScalableBitmap(this, "dev_rack_nozzle_empty", 46);}
|
||||
m_nozzle_icon->SetBitmap(m_nozzle_empty_image->bmp());
|
||||
break;
|
||||
}
|
||||
case Slic3r::GUI::wgtDeviceNozzleRackNozzleItem::NOZZLE_NORMAL:
|
||||
{
|
||||
if (!m_nozzle_normal_image) { m_nozzle_normal_image = new ScalableBitmap(this, "dev_rack_nozzle_normal", 46);}
|
||||
m_nozzle_icon->SetBitmap(SetNozzleBmpColor(m_nozzle_normal_image->bmp(), m_filament_color));
|
||||
break;
|
||||
}
|
||||
case Slic3r::GUI::wgtDeviceNozzleRackNozzleItem::NOZZLE_UNKNOWN:
|
||||
{
|
||||
if (!m_nozzle_unknown_image) { m_nozzle_unknown_image = new ScalableBitmap(this, "dev_rack_nozzle_unknown", 46);}
|
||||
m_nozzle_icon->SetBitmap(m_nozzle_unknown_image->bmp());
|
||||
break;
|
||||
}
|
||||
case Slic3r::GUI::wgtDeviceNozzleRackNozzleItem::NOZZLE_ERROR:
|
||||
{
|
||||
if (!m_nozzle_error_image) { m_nozzle_error_image = new ScalableBitmap(this, "dev_rack_nozzle_error", 46);}
|
||||
m_nozzle_icon->SetBitmap(m_nozzle_error_image->bmp());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (status == wgtDeviceNozzleRackNozzleItem::NOZZLE_ERROR)
|
||||
{
|
||||
m_nozzle_label_1->SetForegroundColour(StateColor::darkModeColorFor(s_red_clr));
|
||||
m_nozzle_status_icon->Show(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_nozzle_label_1->SetForegroundColour(StateColor::darkModeColorFor(*wxBLACK));
|
||||
m_nozzle_status_icon->Show(false);
|
||||
}
|
||||
}
|
||||
|
||||
bool update_layout = (m_nozzle_label_1->GetLabel() != str1 || m_nozzle_label_2->GetLabel() != str2);
|
||||
m_nozzle_label_1->SetLabel(str1);
|
||||
m_nozzle_label_2->SetLabel(str2);
|
||||
|
||||
if (update_layout) {
|
||||
Layout();
|
||||
}
|
||||
}
|
||||
|
||||
void wgtDeviceNozzleRackNozzleItem::OnBtnNozzleStatus(wxMouseEvent& evt)
|
||||
{
|
||||
if (m_is_disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto rack = m_rack.lock();
|
||||
if (rack && m_status == wgtDeviceNozzleRackNozzleItem::NOZZLE_ERROR)
|
||||
{
|
||||
// Orca: show the abnormal-hotend warning as an informational dialog only, with no
|
||||
// "Jump to the upgrade page" button, since Orca's MessageDialog and device Upgrade UI
|
||||
// have no such entry point. Fires when tapping an error-state rack nozzle's status icon.
|
||||
MessageDialog dlg(nullptr, _L("The hotend is in an abnormal state and currently unavailable. "
|
||||
"Please go to 'Device -> Upgrade' to upgrade firmware."), _L("Abnormal Hotend"), wxICON_WARNING | wxOK);
|
||||
dlg.ShowModal();
|
||||
}
|
||||
}
|
||||
|
||||
void wgtDeviceNozzleRackNozzleItem::Rescale()
|
||||
{
|
||||
if (m_nozzle_normal_image) { m_nozzle_normal_image->msw_rescale(); }
|
||||
if (m_nozzle_empty_image) { m_nozzle_empty_image->msw_rescale(); }
|
||||
if (m_nozzle_unknown_image) { m_nozzle_unknown_image->msw_rescale(); }
|
||||
if (m_nozzle_error_image) { m_nozzle_error_image->msw_rescale(); }
|
||||
|
||||
auto status_icon = create_scaled_bitmap("dev_rack_nozzle_error_icon", this, 14);
|
||||
m_nozzle_status_icon->SetBitmap(status_icon);
|
||||
m_nozzle_status_icon->Refresh();
|
||||
|
||||
if (m_nozzle_selected_image) {
|
||||
m_nozzle_selected_image->msw_rescale();
|
||||
if (m_is_selected) {
|
||||
m_nozzle_selected_bitmap->SetBitmap(m_nozzle_selected_image->bmp());
|
||||
}
|
||||
};
|
||||
|
||||
switch (m_status)
|
||||
{
|
||||
case Slic3r::GUI::wgtDeviceNozzleRackNozzleItem::NOZZLE_EMPTY:
|
||||
{
|
||||
m_nozzle_icon->SetBitmap(m_nozzle_empty_image->bmp());
|
||||
break;
|
||||
}
|
||||
case Slic3r::GUI::wgtDeviceNozzleRackNozzleItem::NOZZLE_NORMAL:
|
||||
{
|
||||
m_nozzle_icon->SetBitmap(SetNozzleBmpColor(m_nozzle_normal_image->bmp(), m_filament_color));
|
||||
break;
|
||||
}
|
||||
case Slic3r::GUI::wgtDeviceNozzleRackNozzleItem::NOZZLE_UNKNOWN:
|
||||
{
|
||||
m_nozzle_icon->SetBitmap(m_nozzle_unknown_image->bmp());
|
||||
break;
|
||||
}
|
||||
case Slic3r::GUI::wgtDeviceNozzleRackNozzleItem::NOZZLE_ERROR:
|
||||
{
|
||||
m_nozzle_icon->SetBitmap(m_nozzle_error_image->bmp());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void wgtDeviceNozzleRackNozzleItem::EnableSelect()
|
||||
{
|
||||
if (m_enable_select == true) {
|
||||
return;
|
||||
};
|
||||
|
||||
m_enable_select = true;
|
||||
m_nozzle_icon->Bind(wxEVT_LEFT_DOWN, [this](auto& evt) { OnItemSelected(evt); });
|
||||
m_nozzle_label_id->Bind(wxEVT_LEFT_DOWN, [this](auto& evt) { OnItemSelected(evt); });
|
||||
m_nozzle_label_1->Bind(wxEVT_LEFT_DOWN, [this](auto& evt) { OnItemSelected(evt); });
|
||||
m_nozzle_label_2->Bind(wxEVT_LEFT_DOWN, [this](auto& evt) { OnItemSelected(evt); });
|
||||
Bind(wxEVT_LEFT_DOWN, [this](auto& evt) { OnItemSelected(evt); });
|
||||
}
|
||||
|
||||
void wgtDeviceNozzleRackNozzleItem::OnItemSelected(wxMouseEvent& evt)
|
||||
{
|
||||
if (m_enable_select && !m_is_disabled){
|
||||
SetSelected(true);
|
||||
wxCommandEvent command_evt(EVT_NOZZLE_RACK_NOZZLE_ITEM_SELECTED, GetId());
|
||||
command_evt.SetEventObject(this);
|
||||
ProcessEvent(command_evt);
|
||||
}
|
||||
|
||||
evt.Skip();
|
||||
}
|
||||
|
||||
|
||||
void wgtDeviceNozzleRackNozzleItem::SetDisable(bool disabled)
|
||||
{
|
||||
if (m_is_disabled == disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_is_disabled = disabled;
|
||||
|
||||
auto bg_clr = disabled ? StateColor::darkModeColorFor("#E5E7EB") : StateColor::darkModeColorFor(*wxWHITE);
|
||||
m_nozzle_icon->SetBackgroundColour(bg_clr);
|
||||
m_nozzle_label_id->SetBackgroundColour(bg_clr);
|
||||
m_nozzle_label_1->SetBackgroundColour(bg_clr);
|
||||
m_nozzle_status_icon->SetBackgroundColour(bg_clr);
|
||||
m_nozzle_label_2->SetBackgroundColour(bg_clr);
|
||||
m_nozzle_selected_bitmap->SetBackgroundColour(bg_clr);
|
||||
|
||||
SetBackgroundColor(bg_clr);
|
||||
Refresh();
|
||||
};
|
||||
|
||||
};// end of namespace Slic3r::GUI
|
||||
@@ -1,99 +1,13 @@
|
||||
//**********************************************************/
|
||||
/* File: wgtDeviceNozzleRackNozzleItem.h
|
||||
* Description: One nozzle cell of the H2C hotend rack view.
|
||||
*
|
||||
* This header defines only the single-nozzle-cell widget (and the selection event it emits), which
|
||||
* is the one dependency MultiNozzleSync's HotEndTable needs. The rest of the Device-tab rack panel
|
||||
* (wgtDeviceNozzleRack / ...Area / ...ToolHead / ...Pos) is not provided here.
|
||||
* Description: Compatibility header for the single-nozzle-cell widget.
|
||||
//**********************************************************/
|
||||
|
||||
#pragma once
|
||||
#include "slic3r/GUI/DeviceCore/DevNozzleRack.h"
|
||||
|
||||
#include "slic3r/GUI/Widgets/StaticBox.hpp"
|
||||
#include "slic3r/GUI/Widgets/Label.hpp" // complete type required by the inline SetDisplayIdText below
|
||||
|
||||
#include <wx/panel.h>
|
||||
#include <memory>
|
||||
|
||||
// Previous definitions
|
||||
class ScalableBitmap;
|
||||
namespace Slic3r
|
||||
{
|
||||
struct DevNozzle;
|
||||
class DevNozzleRack;
|
||||
};
|
||||
|
||||
// Events
|
||||
wxDECLARE_EVENT(EVT_NOZZLE_RACK_NOZZLE_ITEM_SELECTED, wxCommandEvent);
|
||||
|
||||
namespace Slic3r::GUI
|
||||
{
|
||||
class wgtDeviceNozzleRackNozzleItem : public StaticBox
|
||||
{
|
||||
public:
|
||||
enum NOZZLE_STATUS
|
||||
{
|
||||
NOZZLE_EMPTY,
|
||||
NOZZLE_NORMAL,
|
||||
NOZZLE_UNKNOWN,
|
||||
NOZZLE_ERROR
|
||||
};
|
||||
|
||||
public:
|
||||
wgtDeviceNozzleRackNozzleItem(wxWindow* parent, int nozzle_id);
|
||||
|
||||
public:
|
||||
void Update(const std::shared_ptr<DevNozzleRack> rack, bool on_rack = true); // on_rack is false means extruder nozzle
|
||||
|
||||
int GetNozzleId() const { return m_nozzle_id; }
|
||||
void SetDisplayIdText(const wxString& text) { m_nozzle_label_id->SetLabel(text);};
|
||||
|
||||
void EnableSelect();;
|
||||
void SetSelected(bool selected);
|
||||
bool IsSelected() const { return m_is_selected; }
|
||||
|
||||
bool IsDisabled() const { return m_is_disabled; }
|
||||
void SetDisable(bool disabled);
|
||||
|
||||
void Rescale();
|
||||
|
||||
private:
|
||||
void CreateGui();
|
||||
|
||||
void SetNozzleStatus(NOZZLE_STATUS status, const wxString& str1, const wxString& str2, const std::string& color);
|
||||
|
||||
void OnBtnNozzleStatus(wxMouseEvent& evt);
|
||||
void OnItemSelected(wxMouseEvent& evt);
|
||||
|
||||
private:
|
||||
std::weak_ptr<DevNozzleRack> m_rack;
|
||||
|
||||
int m_nozzle_id; // internal id, from 0 to 5
|
||||
std::string m_filament_color;
|
||||
NOZZLE_STATUS m_status = NOZZLE_STATUS::NOZZLE_EMPTY;
|
||||
|
||||
// select
|
||||
bool m_is_selected = false;
|
||||
bool m_enable_select = false;
|
||||
ScalableBitmap* m_nozzle_selected_image{ nullptr };
|
||||
wxStaticBitmap* m_nozzle_selected_bitmap{ nullptr };
|
||||
|
||||
// enable or disable
|
||||
bool m_is_disabled = false;
|
||||
|
||||
// Images
|
||||
ScalableBitmap* m_nozzle_normal_image{ nullptr };
|
||||
ScalableBitmap* m_nozzle_empty_image{ nullptr };
|
||||
ScalableBitmap* m_nozzle_unknown_image{ nullptr };
|
||||
ScalableBitmap* m_nozzle_error_image{ nullptr };
|
||||
|
||||
// GUI
|
||||
wxStaticBitmap* m_nozzle_icon{ nullptr };
|
||||
Label* m_nozzle_label_id { nullptr };
|
||||
Label* m_nozzle_label_1{ nullptr };
|
||||
wxStaticBitmap* m_nozzle_status_icon = nullptr;
|
||||
Label* m_nozzle_label_2{ nullptr };
|
||||
};
|
||||
|
||||
};// end of namespace Slic3r::GUI
|
||||
// Orca: transitional shim (removed in resync cluster 8)
|
||||
// The wgtDeviceNozzleRackNozzleItem class and its EVT_NOZZLE_RACK_NOZZLE_ITEM_SELECTED event now
|
||||
// live inline in wgtDeviceNozzleRack.{h,cpp} (folded back to the reference shape). This header is
|
||||
// kept only so the not-yet-resynced GUI/Widgets/MultiNozzleSync includer keeps resolving; it is
|
||||
// deleted once that consumer is resynced to include wgtDeviceNozzleRack.h directly.
|
||||
#include "wgtDeviceNozzleRack.h"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//**********************************************************/
|
||||
/* File: wgtDeviceNozzleRackUpdate.cpp
|
||||
* Description: The dialog for reading/upgrading the H2C induction-hotend-rack firmware.
|
||||
* Description: The panel with rack updating
|
||||
*
|
||||
* \n class wgtDeviceNozzleRackUpdate
|
||||
//**********************************************************/
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "wgtDeviceNozzleRackUpdate.h"
|
||||
|
||||
#include "slic3r/GUI/DeviceCore/DevNozzleSystem.h"
|
||||
#include "slic3r/GUI/DeviceCore/DevUpgrade.h"
|
||||
|
||||
#include "slic3r/GUI/MainFrame.hpp"
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
@@ -103,7 +104,7 @@ void wgtDeviceNozzleRackUprade::CreateGui()
|
||||
wxPanel* separator = new wxPanel(this);
|
||||
separator->SetMaxSize(wxSize(-1, FromDIP(1)));
|
||||
separator->SetMinSize(wxSize(-1, FromDIP(1)));
|
||||
separator->SetBackgroundColour(wxColour(238, 238, 238));// Orca: grey300 spelled out as a literal RGB, since Orca has no equivalent grey-300 colour macro
|
||||
separator->SetBackgroundColour(wxColour(238, 238, 238)); // Orca: grey300 as a literal, no equivalent colour macro in Orca
|
||||
main_sizer->Add(separator, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(12));
|
||||
}
|
||||
}
|
||||
@@ -215,10 +216,13 @@ void wgtDeviceNozzleRackHotendUpdate::CreateGui()
|
||||
m_colour_box->SetMinSize(WX_DIP_SIZE(16, 16));
|
||||
m_colour_box->SetCornerRadius(FromDIP(2));
|
||||
m_colour_box->SetSize(wxSize(FromDIP(16), FromDIP(16)));
|
||||
// m_colour_box->SetBackgroundColour(*wxRED);
|
||||
|
||||
// type_sizer_row_1->AddStretchSpacer();
|
||||
type_sizer_row_1->Add(m_colour_box, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
|
||||
type_sizer_row_1->AddStretchSpacer(1);
|
||||
type_sizer_row_1->Add(m_material_label, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(2));
|
||||
// type_sizer_row_1->AddStretchSpacer();
|
||||
|
||||
m_diameter_label = new Label(type_panel);
|
||||
m_diameter_label->SetFont(Label::Body_12);
|
||||
@@ -277,19 +281,20 @@ void wgtDeviceNozzleRackHotendUpdate::CreateGui()
|
||||
m_used_time->SetBackgroundColour(WGT_DEVICE_NOZZLE_RACK_HOTEND_UPDATE_DEFAULT_BG);
|
||||
|
||||
m_refresh_icon = new ScalableBitmap(this, "refresh_printer", 12);
|
||||
// m_in_refreh_icon = new ScalableBitmap(this, "refresh_nozzle", 12);
|
||||
m_error_icon = new ScalableBitmap(this, "error", 14);
|
||||
m_status_bitmap = new wxStaticBitmap(this, wxID_ANY, m_refresh_icon->bmp());
|
||||
m_status_bitmap->Bind(wxEVT_LEFT_UP, &wgtDeviceNozzleRackHotendUpdate::OnStatusIconClick, this);
|
||||
|
||||
std::vector<std::string> list{"refresh_nozzle_1", "refresh_nozzle_2", "refresh_nozzle_3", "refresh_nozzle_4"};
|
||||
// Orca: AnimaIcon has no per-instance size argument (it fixes 25px internally), so no size is
|
||||
// passed here.
|
||||
// Orca: AnimaIcon has no per-instance size argument (it fixes the size internally), so none is passed.
|
||||
m_refreshing_icon = new AnimaIcon(this, wxID_ANY, list, "refresh_nozzle", 100);
|
||||
m_refreshing_icon->Show(false);
|
||||
|
||||
|
||||
m_status_label = new Label(this);
|
||||
m_status_label->SetFont(Label::Body_12);
|
||||
// m_status_label->SetForegroundColour(wxColour("#00AE42"));
|
||||
|
||||
content_sizer->Add(info_panel, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(20));
|
||||
content_sizer->Add(m_used_time, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(20));
|
||||
@@ -312,7 +317,8 @@ void wgtDeviceNozzleRackHotendUpdate::OnStatusIconClick(wxMouseEvent& event)
|
||||
m_status_label->SetForegroundColour(wxColour("#A3A3A3"));
|
||||
m_status_label->SetLabel(_L("Refreshing"));
|
||||
m_status_bitmap->Show(false);
|
||||
if(!m_refreshing_icon->IsPlaying())
|
||||
// m_status_bitmap->Refresh();
|
||||
if(!m_refreshing_icon->IsPlaying())
|
||||
{
|
||||
m_refreshing_icon->Play();
|
||||
m_refreshing_icon->Show();
|
||||
@@ -333,17 +339,17 @@ void wgtDeviceNozzleRackHotendUpdate::OnStatusIconClick(wxMouseEvent& event)
|
||||
dlg.AddButton(wxID_CANCEL, _L("Cancel"), false);
|
||||
dlg.AddButton(wxID_OK,_L("Jump to the upgrade page"), true);
|
||||
|
||||
if (dlg.ShowModal() == wxID_OK)
|
||||
if (dlg.ShowModal() == wxID_OK)
|
||||
{
|
||||
wxGetApp().mainframe->m_monitor->jump_to_Upgrade();
|
||||
|
||||
wxCommandEvent evt(wxEVT_NOZZLE_JUMP_UPGRADE, GetId());
|
||||
evt.SetEventObject(this);
|
||||
wxWindow* target = GetParent();
|
||||
if (target)
|
||||
if (target)
|
||||
{
|
||||
target = target->GetParent();
|
||||
if (target)
|
||||
if (target)
|
||||
{
|
||||
wxPostEvent(target, evt);
|
||||
}
|
||||
@@ -370,8 +376,8 @@ void wgtDeviceNozzleRackHotendUpdate::OnBitmapHoverEnter(wxMouseEvent& event)
|
||||
scaledBmp = m_scaled_nozzle_image;
|
||||
}
|
||||
|
||||
m_hoverFrame = new wxFrame(nullptr, wxID_ANY, "",
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
m_hoverFrame = new wxFrame(nullptr, wxID_ANY, "",
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
wxFRAME_NO_TASKBAR | wxBORDER_NONE | wxTRANSPARENT_WINDOW);
|
||||
m_hoverFrame->SetBackgroundColour(WGT_DEVICE_NOZZLE_RACK_HOTEND_UPDATE_DEFAULT_BG);
|
||||
m_hoverFrame->SetSize(scaledW, scaledH);
|
||||
@@ -506,11 +512,11 @@ void wgtDeviceNozzleRackHotendUpdate::UpdateInfo(const DevNozzle& nozzle)
|
||||
}
|
||||
|
||||
wxString filamentDisplayName{};
|
||||
for (auto iter = GUI::wxGetApp().preset_bundle->filaments.begin(); iter != GUI::wxGetApp().preset_bundle->filaments.end(); ++iter)
|
||||
for (auto iter = GUI::wxGetApp().preset_bundle->filaments.begin(); iter != GUI::wxGetApp().preset_bundle->filaments.end(); ++iter)
|
||||
{
|
||||
const Preset& filament_preset = *iter;
|
||||
// const auto& config = filament_preset.config;
|
||||
if (filament_preset.filament_id == nozzle.GetFilamentId())
|
||||
if (filament_preset.filament_id == nozzle.GetFilamentId())
|
||||
{
|
||||
filamentDisplayName = wxString(filament_preset.alias);
|
||||
}
|
||||
@@ -612,7 +618,7 @@ void wgtDeviceNozzleRackHotendUpdate::UpdateInfo(const DevNozzle& nozzle)
|
||||
m_used_time->Show(true);
|
||||
m_status_label->Show(true);
|
||||
m_status_bitmap->Show(true);
|
||||
m_status_label->SetForegroundColour(wxColour("#009688"));
|
||||
m_status_label->SetForegroundColour(wxColour("#009688")); // Orca: accent green
|
||||
m_status_label->SetLabel(_L("Refresh"));
|
||||
m_status_bitmap->SetBitmap(m_refresh_icon->bmp());
|
||||
m_status_bitmap->Refresh();
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
//**********************************************************/
|
||||
/* File: wgtDeviceNozzleRackUpdate.h
|
||||
* Description: The dialog for reading/upgrading the H2C induction-hotend-rack firmware.
|
||||
* Description: The panel for updating hotends
|
||||
*
|
||||
* \n class wgtDeviceNozzleRackUpgradeDlg; // modal "Hotends Info" dialog
|
||||
* \n class wgtDeviceNozzleRackUprade; // the dialog's content panel (per-nozzle rows)
|
||||
* \n class wgtDeviceNozzleRackHotendUpdate; // one hotend row (toolhead "R" + rack 1..6)
|
||||
*
|
||||
* Opened from the Device-tab rack panel's "Hotends Info" button (wgtDeviceNozzleRack.cpp) and
|
||||
* reused by the Device->Upgrade page "Hotends on Rack" section
|
||||
* (UpgradePanel::createNozzleRackWidgets). All device data + MQTT commands live in
|
||||
* DevNozzleRack / DevNozzleSystem, so this is additive GUI gated behind
|
||||
* DevNozzleRack::IsSupported() — dormant for every non-rack printer.
|
||||
* \n class wgtDeviceNozzleRackUpdate
|
||||
//**********************************************************/
|
||||
|
||||
#pragma once
|
||||
@@ -22,8 +14,6 @@
|
||||
|
||||
#include <wx/panel.h>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
// Previous definitions
|
||||
class Button;
|
||||
@@ -49,7 +39,7 @@ public:
|
||||
wgtDeviceNozzleRackUpgradeDlg(wxWindow* parent, const std::shared_ptr<DevNozzleRack> rack);
|
||||
|
||||
public:
|
||||
void UpdateRackInfo(const std::shared_ptr<DevNozzleRack> rack);
|
||||
void UpdateRackInfo(const std::shared_ptr<DevNozzleRack> rack);;
|
||||
|
||||
public:
|
||||
void on_dpi_changed(const wxRect& suggested_rect) override;
|
||||
@@ -146,6 +136,7 @@ private:
|
||||
ScalableBitmap* m_scaled_nozzle_image = nullptr;
|
||||
ScalableBitmap* m_scaled_nozzle_empty_image = nullptr;
|
||||
ScalableBitmap* m_refresh_icon = nullptr;
|
||||
// ScalableBitmap* m_in_refreh_icon = nullptr;
|
||||
AnimaIcon* m_refreshing_icon = nullptr;
|
||||
ScalableBitmap* m_error_icon = nullptr;
|
||||
|
||||
@@ -159,7 +150,7 @@ private:
|
||||
|
||||
Label* m_status_label{ nullptr };
|
||||
Label* m_used_time{ nullptr };
|
||||
|
||||
|
||||
Label* m_diameter_label;
|
||||
Label* m_flowtype_label;
|
||||
Label* m_type_label;
|
||||
@@ -172,4 +163,4 @@ private:
|
||||
|
||||
wxDECLARE_EVENT(wxEVT_NOZZLE_JUMP_UPGRADE, wxCommandEvent);
|
||||
|
||||
};// end of namespace Slic3r::GUI
|
||||
};// end of namespace Slic3r::GUI
|
||||
@@ -6,14 +6,14 @@
|
||||
//**********************************************************/
|
||||
|
||||
#include "wgtDeviceNozzleSelect.h"
|
||||
#include "wgtDeviceNozzleRackNozzleItem.h" // the nozzle-item widget lives in its own header
|
||||
#include "wgtDeviceNozzleRack.h"
|
||||
|
||||
#include "slic3r/GUI/I18N.hpp"
|
||||
#include "slic3r/GUI/DeviceTab/wgtMsgBox.h"
|
||||
#include "slic3r/GUI/Widgets/Label.hpp"
|
||||
#include "slic3r/GUI/Widgets/Label.hpp" // Orca: explicit Label include
|
||||
|
||||
static wxColour s_gray_clr("#B0B0B0");
|
||||
static wxColour s_hgreen_clr("#009688");
|
||||
static wxColour s_hgreen_clr("#009688"); // Orca: accent green
|
||||
static wxColour s_red_clr("#D01B1B");
|
||||
|
||||
static std::vector<int> a_nozzle_seq = {16, 18, 20, 17, 19, 21};
|
||||
@@ -132,7 +132,7 @@ void wgtDeviceNozzleRackSelect::UpdateNozzleInfos(std::shared_ptr<DevNozzleRack>
|
||||
}
|
||||
}
|
||||
|
||||
static void s_enable_item_if_match(wgtDeviceNozzleRackNozzleItem* item,
|
||||
static void s_enable_item_if_match(wgtDeviceNozzleRackNozzleItem* item,
|
||||
const DevNozzle& nozzle_info,
|
||||
const DevNozzle& selected_nozzle)
|
||||
{
|
||||
@@ -214,7 +214,7 @@ void wgtDeviceNozzleRackSelect::UpdatSelectedNozzles(std::shared_ptr<DevNozzleRa
|
||||
}
|
||||
}
|
||||
|
||||
void wgtDeviceNozzleRackSelect::ClearSelection()
|
||||
void wgtDeviceNozzleRackSelect::ClearSelection()
|
||||
{
|
||||
m_selected_nozzle = DevNozzle();
|
||||
m_toolhead_nozzle_l->SetSelected(false);
|
||||
|
||||
@@ -7,14 +7,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "slic3r/GUI/DeviceCore/DevNozzleSystem.h" // DevNozzle (value member) + DevDefs.h (PrintFromType, MAIN/DEPUTY_EXTRUDER_ID)
|
||||
#include "slic3r/GUI/DeviceCore/DevNozzleSystem.h"
|
||||
|
||||
#include <wx/panel.h>
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
// Previous definitions
|
||||
class Label;
|
||||
@@ -71,4 +68,4 @@ private:
|
||||
std::unordered_map<int, wgtDeviceNozzleRackNozzleItem *> m_nozzle_items; // from 16 to 21
|
||||
};
|
||||
|
||||
};// end of namespace Slic3r::GUI
|
||||
};// end of namespace Slic3r::GUI
|
||||
@@ -28,4 +28,4 @@ private:
|
||||
};
|
||||
}
|
||||
|
||||
#endif // WGTMSGBOX_H
|
||||
#endif // WGTMSGBOX_H
|
||||
163
src/slic3r/GUI/DeviceTab/wgtMsgPanel.cpp
Normal file
163
src/slic3r/GUI/DeviceTab/wgtMsgPanel.cpp
Normal file
@@ -0,0 +1,163 @@
|
||||
#include "wgtMsgPanel.h"
|
||||
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/Widgets/Label.hpp"
|
||||
#include "slic3r/GUI/Widgets/StateColor.hpp"
|
||||
#include "slic3r/GUI/wxExtensions.hpp"
|
||||
|
||||
#include <wx/sizer.h>
|
||||
|
||||
namespace Slic3r::GUI
|
||||
{
|
||||
|
||||
// ===== wgtMsgPanelItem ======================================================
|
||||
|
||||
wgtMsgPanelItem::wgtMsgPanelItem(wxWindow* parent,
|
||||
const wxColour& colour,
|
||||
const wxString& text,
|
||||
int max_width,
|
||||
const wxString& wiki_url)
|
||||
: wxPanel(parent, wxID_ANY)
|
||||
, m_max_width(max_width)
|
||||
, m_colour(colour)
|
||||
, m_text(text)
|
||||
, m_wiki_url(wiki_url)
|
||||
{
|
||||
CreateGui();
|
||||
}
|
||||
|
||||
void wgtMsgPanelItem::CreateGui()
|
||||
{
|
||||
SetBackgroundColour(StateColor::darkModeColorFor(wxColour(*wxWHITE)));
|
||||
|
||||
wxBoxSizer* main_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
// Color bar on the left
|
||||
//wxPanel* color_bar = new wxPanel(this, wxID_ANY);
|
||||
//color_bar->SetMinSize(wxSize(FromDIP(4), -1));
|
||||
//color_bar->SetBackgroundColour(m_colour);
|
||||
//main_sizer->Add(color_bar, 0, wxEXPAND | wxRIGHT, FromDIP(4));
|
||||
|
||||
// Text and optional wiki link
|
||||
wxBoxSizer* text_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
m_text_label = new ::Label(this, m_text);
|
||||
m_text_label->SetFont(::Label::Body_13);
|
||||
m_text_label->SetBackgroundColour(StateColor::darkModeColorFor(wxColour(*wxWHITE)));
|
||||
m_text_label->SetForegroundColour(m_colour);
|
||||
if (!m_wiki_url.IsEmpty()) {
|
||||
m_text_label->Wrap(m_max_width - FromDIP(20)); // Wrap text to fit within a reasonable width
|
||||
} else {
|
||||
m_text_label->Wrap(m_max_width - FromDIP(10)); // Wrap text to fit within a reasonable width
|
||||
}
|
||||
|
||||
text_sizer->Add(m_text_label, 0, wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
if (!m_wiki_url.IsEmpty()) {
|
||||
m_wiki_link = new wxHyperlinkCtrl(this, wxID_ANY, "Wiki->", m_wiki_url);
|
||||
m_wiki_link->SetNormalColour(m_colour);
|
||||
m_wiki_link->SetHoverColour(wxColour(0, 0, 200));
|
||||
m_wiki_link->SetVisitedColour(*wxBLUE);
|
||||
Bind(wxEVT_HYPERLINK, &wgtMsgPanelItem::OnClickWiki, this, m_wiki_link->GetId());
|
||||
text_sizer->AddSpacer(FromDIP(4));
|
||||
text_sizer->Add(m_wiki_link, 0, wxALIGN_CENTER_VERTICAL | wxEXPAND);
|
||||
}
|
||||
|
||||
main_sizer->Add(text_sizer, 0, wxALIGN_LEFT | wxEXPAND);
|
||||
|
||||
SetSizer(main_sizer);
|
||||
Layout();
|
||||
Fit();
|
||||
}
|
||||
|
||||
void wgtMsgPanelItem::SetColour(const wxColour& colour)
|
||||
{
|
||||
m_colour = colour;
|
||||
// Simple handling: refresh the whole control to redraw the color bar
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void wgtMsgPanelItem::SetText(const wxString& text)
|
||||
{
|
||||
m_text = text;
|
||||
if (m_text_label) {
|
||||
m_text_label->SetLabel(m_text);
|
||||
}
|
||||
}
|
||||
|
||||
void wgtMsgPanelItem::SetWiki(const wxString& wiki_url)
|
||||
{
|
||||
m_wiki_url = wiki_url;
|
||||
if (m_wiki_link) {
|
||||
m_wiki_link->SetURL(m_wiki_url);
|
||||
}
|
||||
}
|
||||
|
||||
void wgtMsgPanelItem::OnClickWiki(wxHyperlinkEvent& evt)
|
||||
{
|
||||
if (!m_wiki_url.IsEmpty()) {
|
||||
wxLaunchDefaultBrowser(m_wiki_url);
|
||||
}
|
||||
}
|
||||
|
||||
// ===== wgtMsgPanel ==========================================================
|
||||
|
||||
wgtMsgPanel::wgtMsgPanel(wxWindow* parent)
|
||||
: wxPanel(parent, wxID_ANY)
|
||||
{
|
||||
CreateGui();
|
||||
}
|
||||
|
||||
void wgtMsgPanel::CreateGui()
|
||||
{
|
||||
SetBackgroundColour(StateColor::darkModeColorFor(wxColour(*wxWHITE)));
|
||||
|
||||
wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_label_title = new Label(this, _L("Note:"));
|
||||
m_label_title->SetFont(::Label::Body_14);
|
||||
main_sizer->Add(m_label_title, 0, wxEXPAND | wxALL, FromDIP(4));
|
||||
|
||||
m_list_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
main_sizer->Add(m_list_sizer, 1, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(4));
|
||||
|
||||
SetSizer(main_sizer);
|
||||
Layout();
|
||||
}
|
||||
|
||||
void wgtMsgPanel::AddMessage(const wxString& text,
|
||||
const wxColour& colour,
|
||||
const wxString& wiki_url)
|
||||
{
|
||||
if (!m_list_sizer) return;
|
||||
|
||||
auto* label = new ::Label(this, wxString::Format("%d. ", GetMessageCount() + 1));
|
||||
label->SetFont(::Label::Body_14);
|
||||
label->SetBackgroundColour(StateColor::darkModeColorFor(wxColour(*wxWHITE)));
|
||||
label->SetForegroundColour(colour);
|
||||
|
||||
auto* item = new wgtMsgPanelItem(this, colour, text, GetSize().GetWidth(), wiki_url);
|
||||
auto h_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
h_sizer->Add(label, 0, wxEXPAND);
|
||||
h_sizer->Add(item, 0, wxEXPAND);
|
||||
m_list_sizer->Add(h_sizer, 0, wxEXPAND | wxTOP | wxBOTTOM, FromDIP(2));
|
||||
Layout();
|
||||
}
|
||||
|
||||
void wgtMsgPanel::Clear()
|
||||
{
|
||||
if (!m_list_sizer) return;
|
||||
|
||||
Freeze();
|
||||
wxSizerItemList children = m_list_sizer->GetChildren();
|
||||
for (auto it = children.begin(); it != children.end(); ++it) {
|
||||
if (wxWindow* win = (*it)->GetWindow()) {
|
||||
win->Destroy();
|
||||
}
|
||||
}
|
||||
m_list_sizer->Clear(true);
|
||||
Thaw();
|
||||
Layout();
|
||||
}
|
||||
|
||||
} // namespace Slic3r::GUI
|
||||
69
src/slic3r/GUI/DeviceTab/wgtMsgPanel.h
Normal file
69
src/slic3r/GUI/DeviceTab/wgtMsgPanel.h
Normal file
@@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
|
||||
#include <wx/panel.h>
|
||||
#include <wx/hyperlink.h>
|
||||
#include <wx/sizer.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
class Label;
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
namespace GUI
|
||||
{
|
||||
|
||||
// Single message item, including color, text and optional wiki link
|
||||
class wgtMsgPanelItem : public wxPanel
|
||||
{
|
||||
public:
|
||||
wgtMsgPanelItem(wxWindow* parent,
|
||||
const wxColour& colour,
|
||||
const wxString& text,
|
||||
int max_width,
|
||||
const wxString& wiki_url = wxEmptyString);
|
||||
|
||||
void SetColour(const wxColour& colour);
|
||||
void SetText(const wxString& text);
|
||||
void SetWiki(const wxString& wiki_url);
|
||||
|
||||
private:
|
||||
void CreateGui();
|
||||
void OnClickWiki(wxHyperlinkEvent& evt);
|
||||
|
||||
private:
|
||||
int m_max_width;
|
||||
wxColour m_colour;
|
||||
wxString m_text;
|
||||
wxString m_wiki_url;
|
||||
|
||||
Label* m_text_label{ nullptr };
|
||||
wxHyperlinkCtrl* m_wiki_link{ nullptr };
|
||||
};
|
||||
|
||||
// Message panel based on wxWidget, shows wgtMsgPanelItem in a list
|
||||
class wgtMsgPanel : public wxPanel
|
||||
{
|
||||
public:
|
||||
explicit wgtMsgPanel(wxWindow* parent);
|
||||
~wgtMsgPanel() override = default;
|
||||
|
||||
// Add a message (preferred API)
|
||||
void AddMessage(const wxString& text,
|
||||
const wxColour& colour,
|
||||
const wxString& wiki_url = wxEmptyString);
|
||||
void Clear();
|
||||
|
||||
// Const API
|
||||
int GetMessageCount() const { return m_list_sizer ? m_list_sizer->GetItemCount() : 0; }
|
||||
|
||||
private:
|
||||
void CreateGui();
|
||||
|
||||
private:
|
||||
Label* m_label_title{ nullptr };
|
||||
wxBoxSizer* m_list_sizer{ nullptr };
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace Slic3r::GUI
|
||||
Reference in New Issue
Block a user