mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-07-28 21:32:11 +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
|
list(APPEND SLIC3R_GUI_SOURCES
|
||||||
GUI/DeviceTab/uiAmsHumidityPopup.h
|
GUI/DeviceTab/uiAmsHumidityPopup.h
|
||||||
GUI/DeviceTab/uiAmsHumidityPopup.cpp
|
GUI/DeviceTab/uiAmsHumidityPopup.cpp
|
||||||
|
GUI/DeviceTab/uiAMSBestPositionPopup.hpp
|
||||||
|
GUI/DeviceTab/uiAMSBestPositionPopup.cpp
|
||||||
GUI/DeviceTab/uiDeviceUpdateVersion.h
|
GUI/DeviceTab/uiDeviceUpdateVersion.h
|
||||||
GUI/DeviceTab/uiDeviceUpdateVersion.cpp
|
GUI/DeviceTab/uiDeviceUpdateVersion.cpp
|
||||||
GUI/DeviceTab/wgtDeviceNozzleRackNozzleItem.h
|
|
||||||
GUI/DeviceTab/wgtDeviceNozzleRackNozzleItem.cpp
|
|
||||||
GUI/DeviceTab/wgtDeviceNozzleRack.h
|
GUI/DeviceTab/wgtDeviceNozzleRack.h
|
||||||
GUI/DeviceTab/wgtDeviceNozzleRack.cpp
|
GUI/DeviceTab/wgtDeviceNozzleRack.cpp
|
||||||
GUI/DeviceTab/wgtDeviceNozzleRackUpdate.h
|
GUI/DeviceTab/wgtDeviceNozzleRackUpdate.h
|
||||||
@@ -14,5 +14,7 @@ list(APPEND SLIC3R_GUI_SOURCES
|
|||||||
GUI/DeviceTab/wgtDeviceNozzleSelect.cpp
|
GUI/DeviceTab/wgtDeviceNozzleSelect.cpp
|
||||||
GUI/DeviceTab/wgtMsgBox.h
|
GUI/DeviceTab/wgtMsgBox.h
|
||||||
GUI/DeviceTab/wgtMsgBox.cpp
|
GUI/DeviceTab/wgtMsgBox.cpp
|
||||||
|
GUI/DeviceTab/wgtMsgPanel.h
|
||||||
|
GUI/DeviceTab/wgtMsgPanel.cpp
|
||||||
)
|
)
|
||||||
set(SLIC3R_GUI_SOURCES ${SLIC3R_GUI_SOURCES} PARENT_SCOPE)
|
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,14 +23,14 @@ uiAmsPercentHumidityDryPopup::uiAmsPercentHumidityDryPopup(wxWindow *parent)
|
|||||||
: wxDialog(parent, wxID_ANY, "")
|
: wxDialog(parent, wxID_ANY, "")
|
||||||
{
|
{
|
||||||
Create();
|
Create();
|
||||||
wxGetApp().UpdateDlgDarkUI(this);
|
wxGetApp().UpdateDlgDarkUI(this); // Orca: apply dark-mode theming to the popup
|
||||||
}
|
}
|
||||||
|
|
||||||
void uiAmsPercentHumidityDryPopup::Create()
|
void uiAmsPercentHumidityDryPopup::Create()
|
||||||
{
|
{
|
||||||
// create images
|
// create images
|
||||||
idle_img = ScalableBitmap(this, "ams_drying", 16);
|
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);
|
SetBackgroundColour(*wxWHITE);
|
||||||
@@ -147,7 +147,8 @@ void uiAmsPercentHumidityDryPopup::UpdateContents()
|
|||||||
// table grid
|
// table grid
|
||||||
const wxString& humidity_str = wxString::Format("%d%%", m_humidity_percent);
|
const wxString& humidity_str = wxString::Format("%d%%", m_humidity_percent);
|
||||||
m_humidity_label->SetLabel(humidity_str);
|
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);
|
m_temperature_label->SetLabel(temp_str);
|
||||||
|
|
||||||
if (m_left_dry_time > 0)
|
if (m_left_dry_time > 0)
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace Slic3r { namespace GUI {
|
|||||||
struct uiAmsHumidityInfo
|
struct uiAmsHumidityInfo
|
||||||
{
|
{
|
||||||
std::string ams_id;
|
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_display_idx = -1;
|
||||||
int humidity_percent = -1;
|
int humidity_percent = -1;
|
||||||
float current_temperature;
|
float current_temperature;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
#include "slic3r/GUI/I18N.hpp"
|
#include "slic3r/GUI/I18N.hpp"
|
||||||
#include "slic3r/GUI/wxExtensions.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>
|
#include <wx/stattext.h>
|
||||||
|
|
||||||
@@ -81,7 +81,6 @@ void uiDeviceUpdateVersion::CreateWidgets()
|
|||||||
serial_text->SetFont(font);
|
serial_text->SetFont(font);
|
||||||
version_text->SetFont(font);
|
version_text->SetFont(font);
|
||||||
model_text->SetFont(font);
|
model_text->SetFont(font);
|
||||||
|
|
||||||
// The grid sizer
|
// The grid sizer
|
||||||
wxFlexGridSizer* grid_sizer = new wxFlexGridSizer(0, 2, 0, 0);
|
wxFlexGridSizer* grid_sizer = new wxFlexGridSizer(0, 2, 0, 0);
|
||||||
//grid_sizer->AddGrowableCol(1);
|
//grid_sizer->AddGrowableCol(1);
|
||||||
@@ -106,7 +105,7 @@ void uiDeviceUpdateVersion::CreateWidgets()
|
|||||||
|
|
||||||
// Updating
|
// Updating
|
||||||
wxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);
|
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));
|
main_sizer->Add(grid_sizer, 0, wxALIGN_LEFT, FromDIP(5));
|
||||||
|
|
||||||
SetSizer(main_sizer);
|
SetSizer(main_sizer);
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
//**********************************************************/
|
//**********************************************************/
|
||||||
/* File: wgtDeviceNozzleRack.cpp
|
/* 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 wgtDeviceNozzleRackArea;
|
||||||
|
* \n class wgtDeviceNozzleRackNozzleItem;
|
||||||
|
* \n class wgtDeviceNozzleRackToolHead;
|
||||||
* \n class wgtDeviceNozzleRackPos;
|
* \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"
|
#include "wgtDeviceNozzleRack.h"
|
||||||
@@ -17,29 +14,41 @@
|
|||||||
#include "slic3r/GUI/DeviceCore/DevNozzleSystem.h"
|
#include "slic3r/GUI/DeviceCore/DevNozzleSystem.h"
|
||||||
|
|
||||||
#include "slic3r/GUI/I18N.hpp"
|
#include "slic3r/GUI/I18N.hpp"
|
||||||
#include "slic3r/GUI/GUI_App.hpp"
|
|
||||||
#include "slic3r/GUI/MainFrame.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/wxExtensions.hpp"
|
||||||
|
|
||||||
#include "slic3r/GUI/Widgets/Button.hpp"
|
#include "slic3r/GUI/Widgets/Button.hpp"
|
||||||
#include "slic3r/GUI/Widgets/Label.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 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_A_STR _L("Row A")
|
||||||
#define L_RAW_B_STR _L("Row B")
|
#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.
|
// Orca: StateColor lacks these grey constants, so mirror the values here.
|
||||||
static const wxColour WGT_GREY200 = wxColour(248, 248, 248);
|
static const wxColour WGT_GREY200 = wxColour(248, 248, 248);
|
||||||
static const wxColour WGT_GREY300 = wxColour(238, 238, 238);
|
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
|
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) {
|
static wxBitmap SetNozzleBmpColor(const wxBitmap& bmp, const std::string& color_str) {
|
||||||
if(color_str.empty()) return bmp;
|
if(color_str.empty()) return bmp;
|
||||||
|
|
||||||
@@ -353,6 +362,36 @@ StaticBox* wgtDeviceNozzleRackArea::CreateNozzleBox(const std::vector<int> nozzl
|
|||||||
return nozzle_box;
|
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,
|
void wgtDeviceNozzleRackArea::UpdateNozzleItems(const std::unordered_map<int, wgtDeviceNozzleRackNozzleItem*>& nozzle_items,
|
||||||
std::shared_ptr<DevNozzleRack> nozzle_rack)
|
std::shared_ptr<DevNozzleRack> nozzle_rack)
|
||||||
{
|
{
|
||||||
@@ -409,6 +448,7 @@ void wgtDeviceNozzleRackArea::UpdateRackInfo(std::weak_ptr<DevNozzleRack> rack)
|
|||||||
const auto& nozzle_rack = rack.lock();
|
const auto& nozzle_rack = rack.lock();
|
||||||
if (nozzle_rack)
|
if (nozzle_rack)
|
||||||
{
|
{
|
||||||
|
// s_update_title(nozzle_rack, m_title_nozzle_rack);
|
||||||
UpdateNozzleItems(m_nozzle_items, nozzle_rack);
|
UpdateNozzleItems(m_nozzle_items, nozzle_rack);
|
||||||
m_rack_pos_panel->UpdateRackPos(nozzle_rack);
|
m_rack_pos_panel->UpdateRackPos(nozzle_rack);
|
||||||
m_btn_read_all->Enable(nozzle_rack->CtrlCanReadAll());
|
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,
|
void wgtDeviceNozzleRackPos::UpdateRackPos(DevNozzleRack::RackPos new_pos,
|
||||||
DevNozzleRack::RackStatus new_status, bool is_reading)
|
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)
|
if (is_reading)
|
||||||
{
|
{
|
||||||
s_show_label(m_label_rowup, L_RAW_A_STR, *wxBLACK);
|
s_show_label(m_label_rowup, L_RAW_A_STR, *wxBLACK);
|
||||||
@@ -697,4 +737,298 @@ void wgtDeviceNozzleRackPos::Rescale()
|
|||||||
m_btn_homing->msw_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
|
/* 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 wgtDeviceNozzleRackArea;
|
||||||
|
* \n class wgtDeviceNozzleRackNozzleItem;
|
||||||
|
* \n class wgtDeviceNozzleRackToolHead;
|
||||||
* \n class wgtDeviceNozzleRackPos;
|
* \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
|
#pragma once
|
||||||
#include "slic3r/GUI/DeviceCore/DevNozzleRack.h"
|
#include "slic3r/GUI/DeviceCore/DevNozzleRack.h"
|
||||||
|
|
||||||
#include "wgtDeviceNozzleRackNozzleItem.h"
|
|
||||||
|
|
||||||
#include "slic3r/GUI/Widgets/StaticBox.hpp"
|
#include "slic3r/GUI/Widgets/StaticBox.hpp"
|
||||||
#include "slic3r/GUI/Widgets/AnimaController.hpp"
|
#include "slic3r/GUI/Widgets/AnimaController.hpp"
|
||||||
|
|
||||||
#include <wx/panel.h>
|
#include <wx/panel.h>
|
||||||
#include <wx/simplebook.h>
|
#include <wx/simplebook.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <unordered_map>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
// Previous definitions
|
// Previous definitions
|
||||||
class Button;
|
class Button;
|
||||||
@@ -47,6 +38,9 @@ namespace GUI
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Events
|
||||||
|
wxDECLARE_EVENT(EVT_NOZZLE_RACK_NOZZLE_ITEM_SELECTED, wxCommandEvent);
|
||||||
|
|
||||||
namespace Slic3r::GUI
|
namespace Slic3r::GUI
|
||||||
{
|
{
|
||||||
class wgtDeviceNozzleRack : public wxPanel
|
class wgtDeviceNozzleRack : public wxPanel
|
||||||
@@ -148,8 +142,6 @@ private:
|
|||||||
Label* m_progress_refresh{ nullptr };
|
Label* m_progress_refresh{ nullptr };
|
||||||
AnimaIcon* m_refresh_icon{ 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;
|
wgtDeviceNozzleRackUpgradeDlg* m_rack_upgrade_dlg = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -193,4 +185,71 @@ private:
|
|||||||
ScalableButton* m_btn_homing{ nullptr };
|
ScalableButton* m_btn_homing{ nullptr };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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
|
};// 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
|
/* File: wgtDeviceNozzleRackNozzleItem.h
|
||||||
* Description: One nozzle cell of the H2C hotend rack view.
|
* Description: Compatibility header for the single-nozzle-cell widget.
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
//**********************************************************/
|
//**********************************************************/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "slic3r/GUI/DeviceCore/DevNozzleRack.h"
|
|
||||||
|
|
||||||
#include "slic3r/GUI/Widgets/StaticBox.hpp"
|
// Orca: transitional shim (removed in resync cluster 8)
|
||||||
#include "slic3r/GUI/Widgets/Label.hpp" // complete type required by the inline SetDisplayIdText below
|
// 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
|
||||||
#include <wx/panel.h>
|
// kept only so the not-yet-resynced GUI/Widgets/MultiNozzleSync includer keeps resolving; it is
|
||||||
#include <memory>
|
// deleted once that consumer is resynced to include wgtDeviceNozzleRack.h directly.
|
||||||
|
#include "wgtDeviceNozzleRack.h"
|
||||||
// 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
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//**********************************************************/
|
//**********************************************************/
|
||||||
/* File: wgtDeviceNozzleRackUpdate.cpp
|
/* File: wgtDeviceNozzleRackUpdate.cpp
|
||||||
* Description: The dialog for reading/upgrading the H2C induction-hotend-rack firmware.
|
* Description: The panel with rack updating
|
||||||
*
|
*
|
||||||
* \n class wgtDeviceNozzleRackUpdate
|
* \n class wgtDeviceNozzleRackUpdate
|
||||||
//**********************************************************/
|
//**********************************************************/
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "wgtDeviceNozzleRackUpdate.h"
|
#include "wgtDeviceNozzleRackUpdate.h"
|
||||||
|
|
||||||
#include "slic3r/GUI/DeviceCore/DevNozzleSystem.h"
|
#include "slic3r/GUI/DeviceCore/DevNozzleSystem.h"
|
||||||
|
#include "slic3r/GUI/DeviceCore/DevUpgrade.h"
|
||||||
|
|
||||||
#include "slic3r/GUI/MainFrame.hpp"
|
#include "slic3r/GUI/MainFrame.hpp"
|
||||||
#include "slic3r/GUI/GUI_App.hpp"
|
#include "slic3r/GUI/GUI_App.hpp"
|
||||||
@@ -103,7 +104,7 @@ void wgtDeviceNozzleRackUprade::CreateGui()
|
|||||||
wxPanel* separator = new wxPanel(this);
|
wxPanel* separator = new wxPanel(this);
|
||||||
separator->SetMaxSize(wxSize(-1, FromDIP(1)));
|
separator->SetMaxSize(wxSize(-1, FromDIP(1)));
|
||||||
separator->SetMinSize(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));
|
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->SetMinSize(WX_DIP_SIZE(16, 16));
|
||||||
m_colour_box->SetCornerRadius(FromDIP(2));
|
m_colour_box->SetCornerRadius(FromDIP(2));
|
||||||
m_colour_box->SetSize(wxSize(FromDIP(16), FromDIP(16)));
|
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->Add(m_colour_box, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
|
||||||
type_sizer_row_1->AddStretchSpacer(1);
|
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->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 = new Label(type_panel);
|
||||||
m_diameter_label->SetFont(Label::Body_12);
|
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_used_time->SetBackgroundColour(WGT_DEVICE_NOZZLE_RACK_HOTEND_UPDATE_DEFAULT_BG);
|
||||||
|
|
||||||
m_refresh_icon = new ScalableBitmap(this, "refresh_printer", 12);
|
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_error_icon = new ScalableBitmap(this, "error", 14);
|
||||||
m_status_bitmap = new wxStaticBitmap(this, wxID_ANY, m_refresh_icon->bmp());
|
m_status_bitmap = new wxStaticBitmap(this, wxID_ANY, m_refresh_icon->bmp());
|
||||||
m_status_bitmap->Bind(wxEVT_LEFT_UP, &wgtDeviceNozzleRackHotendUpdate::OnStatusIconClick, this);
|
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"};
|
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
|
// Orca: AnimaIcon has no per-instance size argument (it fixes the size internally), so none is passed.
|
||||||
// passed here.
|
|
||||||
m_refreshing_icon = new AnimaIcon(this, wxID_ANY, list, "refresh_nozzle", 100);
|
m_refreshing_icon = new AnimaIcon(this, wxID_ANY, list, "refresh_nozzle", 100);
|
||||||
m_refreshing_icon->Show(false);
|
m_refreshing_icon->Show(false);
|
||||||
|
|
||||||
|
|
||||||
m_status_label = new Label(this);
|
m_status_label = new Label(this);
|
||||||
m_status_label->SetFont(Label::Body_12);
|
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(info_panel, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(20));
|
||||||
content_sizer->Add(m_used_time, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(20));
|
content_sizer->Add(m_used_time, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(20));
|
||||||
@@ -312,6 +317,7 @@ void wgtDeviceNozzleRackHotendUpdate::OnStatusIconClick(wxMouseEvent& event)
|
|||||||
m_status_label->SetForegroundColour(wxColour("#A3A3A3"));
|
m_status_label->SetForegroundColour(wxColour("#A3A3A3"));
|
||||||
m_status_label->SetLabel(_L("Refreshing"));
|
m_status_label->SetLabel(_L("Refreshing"));
|
||||||
m_status_bitmap->Show(false);
|
m_status_bitmap->Show(false);
|
||||||
|
// m_status_bitmap->Refresh();
|
||||||
if(!m_refreshing_icon->IsPlaying())
|
if(!m_refreshing_icon->IsPlaying())
|
||||||
{
|
{
|
||||||
m_refreshing_icon->Play();
|
m_refreshing_icon->Play();
|
||||||
@@ -612,7 +618,7 @@ void wgtDeviceNozzleRackHotendUpdate::UpdateInfo(const DevNozzle& nozzle)
|
|||||||
m_used_time->Show(true);
|
m_used_time->Show(true);
|
||||||
m_status_label->Show(true);
|
m_status_label->Show(true);
|
||||||
m_status_bitmap->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_label->SetLabel(_L("Refresh"));
|
||||||
m_status_bitmap->SetBitmap(m_refresh_icon->bmp());
|
m_status_bitmap->SetBitmap(m_refresh_icon->bmp());
|
||||||
m_status_bitmap->Refresh();
|
m_status_bitmap->Refresh();
|
||||||
|
|||||||
@@ -1,16 +1,8 @@
|
|||||||
//**********************************************************/
|
//**********************************************************/
|
||||||
/* File: wgtDeviceNozzleRackUpdate.h
|
/* 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 wgtDeviceNozzleRackUpdate
|
||||||
* \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.
|
|
||||||
//**********************************************************/
|
//**********************************************************/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
@@ -22,8 +14,6 @@
|
|||||||
|
|
||||||
#include <wx/panel.h>
|
#include <wx/panel.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <unordered_map>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
// Previous definitions
|
// Previous definitions
|
||||||
class Button;
|
class Button;
|
||||||
@@ -49,7 +39,7 @@ public:
|
|||||||
wgtDeviceNozzleRackUpgradeDlg(wxWindow* parent, const std::shared_ptr<DevNozzleRack> rack);
|
wgtDeviceNozzleRackUpgradeDlg(wxWindow* parent, const std::shared_ptr<DevNozzleRack> rack);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void UpdateRackInfo(const std::shared_ptr<DevNozzleRack> rack);
|
void UpdateRackInfo(const std::shared_ptr<DevNozzleRack> rack);;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void on_dpi_changed(const wxRect& suggested_rect) override;
|
void on_dpi_changed(const wxRect& suggested_rect) override;
|
||||||
@@ -146,6 +136,7 @@ private:
|
|||||||
ScalableBitmap* m_scaled_nozzle_image = nullptr;
|
ScalableBitmap* m_scaled_nozzle_image = nullptr;
|
||||||
ScalableBitmap* m_scaled_nozzle_empty_image = nullptr;
|
ScalableBitmap* m_scaled_nozzle_empty_image = nullptr;
|
||||||
ScalableBitmap* m_refresh_icon = nullptr;
|
ScalableBitmap* m_refresh_icon = nullptr;
|
||||||
|
// ScalableBitmap* m_in_refreh_icon = nullptr;
|
||||||
AnimaIcon* m_refreshing_icon = nullptr;
|
AnimaIcon* m_refreshing_icon = nullptr;
|
||||||
ScalableBitmap* m_error_icon = nullptr;
|
ScalableBitmap* m_error_icon = nullptr;
|
||||||
|
|
||||||
|
|||||||
@@ -6,14 +6,14 @@
|
|||||||
//**********************************************************/
|
//**********************************************************/
|
||||||
|
|
||||||
#include "wgtDeviceNozzleSelect.h"
|
#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/I18N.hpp"
|
||||||
#include "slic3r/GUI/DeviceTab/wgtMsgBox.h"
|
#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_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 wxColour s_red_clr("#D01B1B");
|
||||||
|
|
||||||
static std::vector<int> a_nozzle_seq = {16, 18, 20, 17, 19, 21};
|
static std::vector<int> a_nozzle_seq = {16, 18, 20, 17, 19, 21};
|
||||||
|
|||||||
@@ -7,14 +7,11 @@
|
|||||||
|
|
||||||
#pragma once
|
#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 <wx/panel.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
// Previous definitions
|
// Previous definitions
|
||||||
class Label;
|
class Label;
|
||||||
|
|||||||
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