Files
OrcaSlicer/src/slic3r/GUI/CalibrationPanel.cpp
liz.li e2934516ed NEW: support restore calibration status of printer
1.store each printer's calibration status to appconfig.
2.add retraction calibration
3.add choose fine calibration directly at flowrate calibration
4.add start pages for every calibration
5.add history window for pa calibration

Change-Id: I117fd46e689e0573e70e8579f5a52ba62d99f3d6
2023-07-07 17:29:08 +08:00

601 lines
19 KiB
C++

#include <wx/dcgraph.h>
#include "GUI.hpp"
#include "GUI_App.hpp"
#include "MainFrame.hpp"
#include "CalibrationPanel.hpp"
#include "I18N.hpp"
namespace Slic3r { namespace GUI {
#define REFRESH_INTERVAL 1000
#define INITIAL_NUMBER_OF_MACHINES 0
#define LIST_REFRESH_INTERVAL 200
#define MACHINE_LIST_REFRESH_INTERVAL 2000
wxDEFINE_EVENT(EVT_FINISHED_UPDATE_MLIST, wxCommandEvent);
wxDEFINE_EVENT(EVT_UPDATE_USER_MLIST, wxCommandEvent);
MObjectPanel::MObjectPanel(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name)
{
wxPanel::Create(parent, id, pos, SELECT_MACHINE_ITEM_SIZE, style, name);
Bind(wxEVT_PAINT, &MObjectPanel::OnPaint, this);
SetBackgroundColour(StateColor::darkModeColorFor(*wxWHITE));
m_printer_status_offline = ScalableBitmap(this, "printer_status_offline", 12);
m_printer_status_busy = ScalableBitmap(this, "printer_status_busy", 12);
m_printer_status_idle = ScalableBitmap(this, "printer_status_idle", 12);
m_printer_status_lock = ScalableBitmap(this, "printer_status_lock", 16);
m_printer_in_lan = ScalableBitmap(this, "printer_in_lan", 16);
Bind(wxEVT_ENTER_WINDOW, &MObjectPanel::on_mouse_enter, this);
Bind(wxEVT_LEAVE_WINDOW, &MObjectPanel::on_mouse_leave, this);
Bind(wxEVT_LEFT_UP, &MObjectPanel::on_mouse_left_up, this);
}
MObjectPanel::~MObjectPanel() {}
void MObjectPanel::set_printer_state(PrinterState state)
{
m_state = state;
Refresh();
}
void MObjectPanel::OnPaint(wxPaintEvent & event)
{
wxPaintDC dc(this);
doRender(dc);
}
void MObjectPanel::render(wxDC& dc)
{
#ifdef __WXMSW__
wxSize size = GetSize();
wxMemoryDC memdc;
wxBitmap bmp(size.x, size.y);
memdc.SelectObject(bmp);
memdc.Blit({ 0, 0 }, size, &dc, { 0, 0 });
{
wxGCDC dc2(memdc);
doRender(dc2);
}
memdc.SelectObject(wxNullBitmap);
dc.DrawBitmap(bmp, 0, 0);
#else
doRender(dc);
#endif
}
void MObjectPanel::doRender(wxDC& dc)
{
auto left = 10;
wxSize size = GetSize();
dc.SetPen(*wxTRANSPARENT_PEN);
auto dwbitmap = m_printer_status_offline;
if (m_state == PrinterState::IDLE) { dwbitmap = m_printer_status_idle; }
if (m_state == PrinterState::BUSY) { dwbitmap = m_printer_status_busy; }
if (m_state == PrinterState::OFFLINE) { dwbitmap = m_printer_status_offline; }
if (m_state == PrinterState::LOCK) { dwbitmap = m_printer_status_lock; }
if (m_state == PrinterState::IN_LAN) { dwbitmap = m_printer_in_lan; }
// dc.DrawCircle(left, size.y / 2, 3);
dc.DrawBitmap(dwbitmap.bmp(), wxPoint(left, (size.y - dwbitmap.GetBmpSize().y) / 2));
left += dwbitmap.GetBmpSize().x + 8;
dc.SetFont(Label::Body_13);
dc.SetBackgroundMode(wxTRANSPARENT);
dc.SetTextForeground(StateColor::darkModeColorFor(SELECT_MACHINE_GREY900));
wxString dev_name = "";
if (m_info) {
dev_name = from_u8(m_info->dev_name);
if (m_state == PrinterState::IN_LAN) {
dev_name += _L("(LAN)");
}
}
auto sizet = dc.GetTextExtent(dev_name);
auto text_end = size.x - FromDIP(15);
wxString finally_name = dev_name;
if (sizet.x > (text_end - left)) {
auto limit_width = text_end - left - dc.GetTextExtent("...").x - 15;
for (auto i = 0; i < dev_name.length(); i++) {
auto curr_width = dc.GetTextExtent(dev_name.substr(0, i));
if (curr_width.x >= limit_width) {
finally_name = dev_name.substr(0, i) + "...";
break;
}
}
}
dc.DrawText(finally_name, wxPoint(left, (size.y - sizet.y) / 2));
if (m_hover) {
dc.SetPen(SELECT_MACHINE_BRAND);
dc.SetBrush(*wxTRANSPARENT_BRUSH);
dc.DrawRectangle(0, 0, size.x, size.y);
}
}
void MObjectPanel::update_machine_info(MachineObject* info, bool is_my_devices)
{
m_info = info;
m_is_my_devices = is_my_devices;
Refresh();
}
void MObjectPanel::on_mouse_enter(wxMouseEvent& evt)
{
m_hover = true;
Refresh();
}
void MObjectPanel::on_mouse_leave(wxMouseEvent& evt)
{
m_hover = false;
Refresh();
}
void MObjectPanel::on_mouse_left_up(wxMouseEvent& evt)
{
if (m_is_my_devices) {
if (m_info && m_info->is_lan_mode_printer()) {
if (m_info->has_access_right() && m_info->is_avaliable()) {
Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
if (!dev) return;
dev->set_selected_machine(m_info->dev_id);
}
}
else {
Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
if (!dev) return;
dev->set_selected_machine(m_info->dev_id);
}
wxCommandEvent event(EVT_DISSMISS_MACHINE_LIST);
event.SetEventObject(this->GetParent()->GetParent());
wxPostEvent(this, event);
}
}
SelectMObjectPopup::SelectMObjectPopup(wxWindow* parent)
:PopupWindow(parent, wxBORDER_NONE | wxPU_CONTAINS_CONTROLS), m_dismiss(false)
{
#ifdef __WINDOWS__
SetDoubleBuffered(true);
#endif //__WINDOWS__
SetSize(SELECT_MACHINE_POPUP_SIZE);
SetMinSize(SELECT_MACHINE_POPUP_SIZE);
SetMaxSize(SELECT_MACHINE_POPUP_SIZE);
Freeze();
wxBoxSizer* m_sizer_main = new wxBoxSizer(wxVERTICAL);
SetBackgroundColour(SELECT_MACHINE_GREY400);
m_scrolledWindow = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, SELECT_MACHINE_LIST_SIZE, wxHSCROLL | wxVSCROLL);
m_scrolledWindow->SetBackgroundColour(*wxWHITE);
m_scrolledWindow->SetMinSize(SELECT_MACHINE_LIST_SIZE);
m_scrolledWindow->SetScrollRate(0, 5);
auto m_sizxer_scrolledWindow = new wxBoxSizer(wxVERTICAL);
m_scrolledWindow->SetSizer(m_sizxer_scrolledWindow);
m_scrolledWindow->Layout();
m_sizxer_scrolledWindow->Fit(m_scrolledWindow);
m_sizer_my_devices = new wxBoxSizer(wxVERTICAL);
m_sizxer_scrolledWindow->Add(m_sizer_my_devices, 0, wxEXPAND, 0);
m_sizer_main->Add(m_scrolledWindow, 0, wxALL | wxEXPAND, FromDIP(2));
SetSizer(m_sizer_main);
Layout();
Thaw();
#ifdef __APPLE__
m_scrolledWindow->Bind(wxEVT_LEFT_UP, &SelectMObjectPopup::OnLeftUp, this);
#endif // __APPLE__
m_refresh_timer = new wxTimer();
m_refresh_timer->SetOwner(this);
Bind(EVT_UPDATE_USER_MLIST, &SelectMObjectPopup::update_machine_list, this);
Bind(wxEVT_TIMER, &SelectMObjectPopup::on_timer, this);
Bind(EVT_DISSMISS_MACHINE_LIST, &SelectMObjectPopup::on_dissmiss_win, this);
}
SelectMObjectPopup::~SelectMObjectPopup() { delete m_refresh_timer; }
void SelectMObjectPopup::Popup(wxWindow* WXUNUSED(focus))
{
BOOST_LOG_TRIVIAL(trace) << "get_print_info: start";
if (m_refresh_timer) {
m_refresh_timer->Stop();
m_refresh_timer->Start(MACHINE_LIST_REFRESH_INTERVAL);
}
if (wxGetApp().is_user_login()) {
if (!get_print_info_thread) {
get_print_info_thread = new boost::thread(Slic3r::create_thread([&] {
NetworkAgent* agent = wxGetApp().getAgent();
unsigned int http_code;
std::string body;
int result = agent->get_user_print_info(&http_code, &body);
if (result == 0) {
m_print_info = body;
}
else {
m_print_info = "";
}
wxCommandEvent event(EVT_UPDATE_USER_MLIST);
event.SetEventObject(this);
wxPostEvent(this, event);
}));
}
}
wxPostEvent(this, wxTimerEvent());
PopupWindow::Popup();
}
void SelectMObjectPopup::OnDismiss()
{
BOOST_LOG_TRIVIAL(trace) << "get_print_info: dismiss";
m_dismiss = true;
if (m_refresh_timer) {
m_refresh_timer->Stop();
}
if (get_print_info_thread) {
if (get_print_info_thread->joinable()) {
get_print_info_thread->join();
delete get_print_info_thread;
get_print_info_thread = nullptr;
}
}
wxCommandEvent event(EVT_FINISHED_UPDATE_MLIST);
event.SetEventObject(this);
wxPostEvent(this, event);
}
bool SelectMObjectPopup::ProcessLeftDown(wxMouseEvent& event) {
return PopupWindow::ProcessLeftDown(event);
}
bool SelectMObjectPopup::Show(bool show) {
if (show) {
for (int i = 0; i < m_user_list_machine_panel.size(); i++) {
m_user_list_machine_panel[i]->mPanel->update_machine_info(nullptr);
m_user_list_machine_panel[i]->mPanel->Hide();
}
}
return PopupWindow::Show(show);
}
void SelectMObjectPopup::on_timer(wxTimerEvent& event)
{
BOOST_LOG_TRIVIAL(trace) << "SelectMObjectPopup on_timer";
wxGetApp().reset_to_active();
wxCommandEvent user_event(EVT_UPDATE_USER_MLIST);
user_event.SetEventObject(this);
wxPostEvent(this, user_event);
}
void SelectMObjectPopup::update_user_devices()
{
Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
if (!dev) return;
if (!m_print_info.empty()) {
dev->parse_user_print_info(m_print_info);
m_print_info = "";
}
m_bind_machine_list.clear();
m_bind_machine_list = dev->get_my_machine_list();
//sort list
std::vector<std::pair<std::string, MachineObject*>> user_machine_list;
for (auto& it : m_bind_machine_list) {
user_machine_list.push_back(it);
}
std::sort(user_machine_list.begin(), user_machine_list.end(), [&](auto& a, auto& b) {
if (a.second && b.second) {
return a.second->dev_name.compare(b.second->dev_name) < 0;
}
return false;
});
BOOST_LOG_TRIVIAL(trace) << "SelectMObjectPopup update_machine_list start";
this->Freeze();
m_scrolledWindow->Freeze();
int i = 0;
for (auto& elem : user_machine_list) {
MachineObject* mobj = elem.second;
MObjectPanel* op = nullptr;
if (i < m_user_list_machine_panel.size()) {
op = m_user_list_machine_panel[i]->mPanel;
op->Show();
}
else {
op = new MObjectPanel(m_scrolledWindow, wxID_ANY);
MPanel* mpanel = new MPanel();
mpanel->mIndex = wxString::Format("%d", i);
mpanel->mPanel = op;
m_user_list_machine_panel.push_back(mpanel);
m_sizer_my_devices->Add(op, 0, wxEXPAND, 0);
}
i++;
op->update_machine_info(mobj, true);
//set in lan
if (mobj->is_lan_mode_printer()) {
if (!mobj->is_online()) {
continue;
}
else {
if (mobj->has_access_right() && mobj->is_avaliable()) {
op->set_printer_state(PrinterState::IN_LAN);
op->SetToolTip(_L("Online"));
}
else {
op->set_printer_state(PrinterState::LOCK);
}
}
}
else {
if (!mobj->is_online()) {
op->SetToolTip(_L("Offline"));
op->set_printer_state(PrinterState::OFFLINE);
}
else {
if (mobj->is_in_printing()) {
op->SetToolTip(_L("Busy"));
op->set_printer_state(PrinterState::BUSY);
}
else {
op->SetToolTip(_L("Online"));
op->set_printer_state(PrinterState::IDLE);
}
}
}
}
for (int j = i; j < m_user_list_machine_panel.size(); j++) {
m_user_list_machine_panel[j]->mPanel->update_machine_info(nullptr);
m_user_list_machine_panel[j]->mPanel->Hide();
}
//m_sizer_my_devices->Layout();
if (m_my_devices_count != i) {
m_scrolledWindow->Fit();
}
m_scrolledWindow->Layout();
m_scrolledWindow->Thaw();
Layout();
Fit();
this->Thaw();
m_my_devices_count = i;
}
void SelectMObjectPopup::on_dissmiss_win(wxCommandEvent& event)
{
Dismiss();
}
void SelectMObjectPopup::update_machine_list(wxCommandEvent& event)
{
update_user_devices();
BOOST_LOG_TRIVIAL(trace) << "SelectMObjectPopup update_machine_list end";
}
void SelectMObjectPopup::OnLeftUp(wxMouseEvent& event)
{
auto mouse_pos = ClientToScreen(event.GetPosition());
auto wxscroll_win_pos = m_scrolledWindow->ClientToScreen(wxPoint(0, 0));
if (mouse_pos.x > wxscroll_win_pos.x && mouse_pos.y > wxscroll_win_pos.y && mouse_pos.x < (wxscroll_win_pos.x + m_scrolledWindow->GetSize().x) &&
mouse_pos.y < (wxscroll_win_pos.y + m_scrolledWindow->GetSize().y)) {
for (MPanel* p : m_user_list_machine_panel) {
auto p_rect = p->mPanel->ClientToScreen(wxPoint(0, 0));
if (mouse_pos.x > p_rect.x && mouse_pos.y > p_rect.y && mouse_pos.x < (p_rect.x + p->mPanel->GetSize().x) && mouse_pos.y < (p_rect.y + p->mPanel->GetSize().y)) {
wxMouseEvent event(wxEVT_LEFT_UP);
auto tag_pos = p->mPanel->ScreenToClient(mouse_pos);
event.SetPosition(tag_pos);
event.SetEventObject(p->mPanel);
wxPostEvent(p->mPanel, event);
}
}
}
}
CalibrationPanel::CalibrationPanel(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
: wxPanel(parent, id, pos, size, style),
m_mobjectlist_popup(SelectMObjectPopup(this))
{
SetBackgroundColour(*wxWHITE);
init_tabpanel();
wxBoxSizer* sizer_main = new wxBoxSizer(wxVERTICAL);
sizer_main->Add(m_tabpanel, 1, wxEXPAND, 0);
SetSizerAndFit(sizer_main);
Layout();
init_timer();
Bind(wxEVT_TIMER, &CalibrationPanel::on_timer, this);
}
void CalibrationPanel::init_tabpanel() {
m_side_tools = new SideTools(this, wxID_ANY);
m_side_tools->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(CalibrationPanel::on_printer_clicked), NULL, this);
wxBoxSizer* sizer_side_tools = new wxBoxSizer(wxVERTICAL);
sizer_side_tools->Add(m_side_tools, 1, wxEXPAND, 0);
m_tabpanel = new Tabbook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, sizer_side_tools, wxNB_LEFT | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME);
m_tabpanel->SetBackgroundColour(*wxWHITE);
m_pa_panel = new PressureAdvanceWizard(m_tabpanel);
m_tabpanel->AddPage(m_pa_panel, _L("Pressure Adavance"), "", true);
m_flow_panel = new FlowRateWizard(m_tabpanel);
m_tabpanel->AddPage(m_flow_panel, _L("Flow Rate"), "", false);
m_volumetric_panel = new MaxVolumetricSpeedWizard(m_tabpanel);
m_tabpanel->AddPage(m_volumetric_panel, _L("Max Volumetric Speed"), "", false);
m_temp_panel = new TemperatureWizard(m_tabpanel);
m_tabpanel->AddPage(m_temp_panel, _L("Temperature"), "", false);
m_retraction_panel = new RetractionWizard(m_tabpanel);
m_tabpanel->AddPage(m_retraction_panel, _L("Retraction"), "", false);
for (int i = 0; i < 5; i++)
m_tabpanel->SetPageImage(i, "");
m_tabpanel->Bind(wxEVT_BOOKCTRL_PAGE_CHANGED, [this](wxBookCtrlEvent&) {
wxCommandEvent e (EVT_CALIBRATION_TAB_CHANGED);
e.SetEventObject(m_tabpanel->GetCurrentPage());
wxPostEvent(m_tabpanel->GetCurrentPage(), e);
}, m_tabpanel->GetId());
}
void CalibrationPanel::init_timer()
{
m_refresh_timer = new wxTimer();
m_refresh_timer->SetOwner(this);
m_refresh_timer->Start(REFRESH_INTERVAL);
wxPostEvent(this, wxTimerEvent());
}
void CalibrationPanel::on_timer(wxTimerEvent& event) {
update_all();
}
void CalibrationPanel::update_all() {
if (m_pa_panel) {
m_pa_panel->update_printer();
if (m_pa_panel->IsShown())
m_pa_panel->update_print_progress();
}
if (m_flow_panel) {
m_flow_panel->update_printer();
if (m_flow_panel->IsShown())
m_flow_panel->update_print_progress();
}
if (m_volumetric_panel) {
m_volumetric_panel->update_printer();
if (m_volumetric_panel->IsShown())
m_volumetric_panel->update_print_progress();
}
if (m_temp_panel) {
m_temp_panel->update_printer();
if (m_temp_panel->IsShown())
m_temp_panel->update_print_progress();
}
if (m_retraction_panel) {
m_retraction_panel->update_printer();
if (m_retraction_panel->IsShown())
m_retraction_panel->update_print_progress();
}
NetworkAgent* m_agent = wxGetApp().getAgent();
Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
if (!dev)
return;
MachineObject* obj = dev->get_selected_machine();
if (!obj) {
m_side_tools->set_none_printer_mode();
return;
}
/* Update Device Info */
m_side_tools->set_current_printer_name(obj->dev_name);
// update wifi signal image
int wifi_signal_val = 0;
if (!obj->is_connected() || obj->is_connecting()) {
m_side_tools->set_current_printer_signal(WifiSignal::NONE);
}
else {
if (!obj->wifi_signal.empty() && boost::ends_with(obj->wifi_signal, "dBm")) {
try {
wifi_signal_val = std::stoi(obj->wifi_signal.substr(0, obj->wifi_signal.size() - 3));
}
catch (...) {
;
}
if (wifi_signal_val > -45) {
m_side_tools->set_current_printer_signal(WifiSignal::STRONG);
}
else if (wifi_signal_val <= -45 && wifi_signal_val >= -60) {
m_side_tools->set_current_printer_signal(WifiSignal::MIDDLE);
}
else {
m_side_tools->set_current_printer_signal(WifiSignal::WEAK);
}
}
else {
m_side_tools->set_current_printer_signal(WifiSignal::MIDDLE);
}
}
}
bool CalibrationPanel::Show(bool show) {
if (show) {
m_refresh_timer->Stop();
m_refresh_timer->SetOwner(this);
m_refresh_timer->Start(REFRESH_INTERVAL);
wxPostEvent(this, wxTimerEvent());
}
else {
m_refresh_timer->Stop();
}
return wxPanel::Show(show);
}
void CalibrationPanel::on_printer_clicked(wxMouseEvent& event)
{
auto mouse_pos = ClientToScreen(event.GetPosition());
wxPoint rect = m_side_tools->ClientToScreen(wxPoint(0, 0));
if (!m_side_tools->is_in_interval()) {
wxPoint pos = m_side_tools->ClientToScreen(wxPoint(0, 0));
pos.y += m_side_tools->GetRect().height;
m_mobjectlist_popup.Move(pos);
#ifdef __linux__
m_mobjectlist_popup.SetSize(wxSize(m_side_tools->GetSize().x, -1));
m_mobjectlist_popup.SetMaxSize(wxSize(m_side_tools->GetSize().x, -1));
m_mobjectlist_popup.SetMinSize(wxSize(m_side_tools->GetSize().x, -1));
#endif
m_mobjectlist_popup.Popup();
}
}
CalibrationPanel::~CalibrationPanel() {
m_side_tools->Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(CalibrationPanel::on_printer_clicked), NULL, this);
if (m_refresh_timer)
m_refresh_timer->Stop();
delete m_refresh_timer;
}
}}