Files
OrcaSlicer/src/slic3r/GUI/StatusPanel.cpp
T
CliffordandClaude Opus 5 83e729d20e fix(build): drop two unused lambda captures that break non-Release clang builds (#15749)
fix(build): drop two unused lambda captures that break non-Release builds

Both handlers capture this and never use it. They sit inside
#if !BBL_RELEASE_TO_PUBLIC, which CMakeLists defines as $<CONFIG:Release>, so
the code compiles in Debug and RelWithDebInfo but not in Release. Clang warns
on an unused capture under -Wall, and since every warning became an error the
two captures fail any clang build that is not Release - an Xcode scheme on its
default Debug configuration, for instance. The CI matrix builds Release, where
the block does not exist, and GCC does not implement the warning at all, so
nothing in CI can see it.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 11:42:31 -03:00

6192 lines
261 KiB
C++

#include "StatusPanel.hpp"
#include "I18N.hpp"
#include "Widgets/Label.hpp"
#include "Widgets/Button.hpp"
#include "Widgets/StepCtrl.hpp"
#include "Widgets/SideTools.hpp"
#include "Widgets/WebView.hpp"
#include "BitmapCache.hpp"
#include "GUI_App.hpp"
#include "MainFrame.hpp"
#include "MsgDialog.hpp"
#include "slic3r/Utils/Http.hpp"
#include "libslic3r/Thread.hpp"
#include "DeviceErrorDialog.hpp"
#include "RecenterDialog.hpp"
#include "CalibUtils.hpp"
#include <slic3r/GUI/Widgets/ProgressDialog.hpp>
#include <wx/display.h>
#include <wx/mstream.h>
#include <wx/sstream.h>
#include <wx/zstream.h>
#include "DeviceCore/DevBed.h"
#include "DeviceCore/DevCtrl.h"
#include "DeviceCore/DevFan.h"
#include "DeviceCore/DevFilaSystem.h"
#include "DeviceCore/DevLamp.h"
#include "DeviceCore/DevStorage.h"
#include "DeviceCore/DevConfig.h"
#include "DeviceCore/DevManager.h"
#include "DeviceCore/DevPrintTaskInfo.h"
#include "DeviceTab/wgtDeviceNozzleRack.h"
#include "PrintOptionsDialog.hpp"
#include "SafetyOptionsDialog.hpp"
#include "ThermalPreconditioningDialog.hpp"
namespace Slic3r { namespace GUI {
#define TEMP_THRESHOLD_VAL 2
#define TEMP_THRESHOLD_ALLOW_E_CTRL 170.0f
/* const strings */
static const wxString NA_STR = _L("N/A");
static const wxString TEMP_BLANK_STR = wxString("_");
static const wxFont SWITCH_FONT = Label::Body_10;
/* const values */
static const int bed_temp_range[2] = {20, 120};
static const int default_champer_temp_min = 20;
static const int default_champer_temp_max = 60;
/* colors */
static const wxColour STATUS_PANEL_BG = wxColour(238, 238, 238);
static const wxColour STATUS_TITLE_BG = wxColour(248, 248, 248);
static const wxColour STATIC_BOX_LINE_COL = wxColour(238, 238, 238);
static const wxColour BUTTON_NORMAL1_COL = wxColour(238, 238, 238);
static const wxColour BUTTON_NORMAL2_COL = wxColour(206, 206, 206);
static const wxColour BUTTON_PRESS_COL = wxColour(172, 172, 172);
static const wxColour BUTTON_HOVER_COL = wxColour(0, 150, 136);
static const wxColour DISCONNECT_TEXT_COL = wxColour(171, 172, 172);
static const wxColour NORMAL_TEXT_COL = wxColour(48,58,60);
static const wxColour NORMAL_FAN_TEXT_COL = wxColour(107, 107, 107);
static const wxColour WARNING_INFO_BG_COL = wxColour(255, 111, 0);
static const wxColour STAGE_TEXT_COL = wxColour(0, 150, 136);
static const wxColour GROUP_STATIC_LINE_COL = wxColour(206, 206, 206);
/* font and foreground colors */
static const wxFont PAGE_TITLE_FONT = Label::Body_14;
//static const wxFont GROUP_TITLE_FONT = Label::sysFont(17);
static wxColour PAGE_TITLE_FONT_COL = wxColour(107, 107, 107);
static wxColour GROUP_TITLE_FONT_COL = wxColour(172, 172, 172);
static wxColour TEXT_LIGHT_FONT_COL = wxColour(107, 107, 107);
static wxImage fail_image;
/* size */
#define PAGE_TITLE_HEIGHT FromDIP(36)
#define PAGE_TITLE_TEXT_WIDTH FromDIP(200)
#define PAGE_TITLE_LEFT_MARGIN FromDIP(17)
#define GROUP_TITLE_LEFT_MARGIN FromDIP(15)
#define GROUP_TITLE_LINE_MARGIN FromDIP(11)
#define GROUP_TITLE_RIGHT_MARGIN FromDIP(15)
#define NORMAL_SPACING FromDIP(5)
#define PAGE_SPACING FromDIP(10)
#define PAGE_MIN_WIDTH FromDIP(574)
#define PROGRESSBAR_HEIGHT FromDIP(8)
#define SWITCH_BUTTON_SIZE (wxSize(FromDIP(40), -1))
#define TASK_THUMBNAIL_SIZE (wxSize(FromDIP(120), FromDIP(120)))
#define TASK_BUTTON_SIZE (wxSize(FromDIP(48), FromDIP(24)))
#define TASK_BUTTON_SIZE2 (wxSize(-1, FromDIP(24)))
#define Z_BUTTON_SIZE (wxSize(FromDIP(44), FromDIP(40)))
#define MISC_BUTTON_PANEL_SIZE (wxSize(FromDIP(136), FromDIP(55)))
#define MISC_BUTTON_1FAN_SIZE (wxSize(FromDIP(132), FromDIP(51)))
#define MISC_BUTTON_2FAN_SIZE (wxSize(FromDIP(66), FromDIP(51)))
#define MISC_BUTTON_3FAN_SIZE (wxSize(FromDIP(44), FromDIP(51)))
#define TEMP_CTRL_MIN_SIZE_ALIGN_ONE_ICON (wxSize(FromDIP(125), FromDIP(52)))
#define TEMP_CTRL_MIN_SIZE_ALIGN_TWO_ICON (wxSize(FromDIP(145), FromDIP(48)))
#define AXIS_MIN_SIZE (wxSize(FromDIP(258), FromDIP(258)))
#define EXTRUDER_IMAGE_SIZE (wxSize(FromDIP(48), FromDIP(76)))
static void market_model_scoring_page(int design_id)
{
std::string url;
std::string country_code = GUI::wxGetApp().app_config->get_country_code();
std::string model_http_url = GUI::wxGetApp().get_model_http_url(country_code);
if (GUI::wxGetApp().getAgent()->get_model_mall_detail_url(&url, std::to_string(design_id)) == 0) {
std::string user_id = GUI::wxGetApp().getAgent()->get_user_id();
boost::algorithm::replace_first(url, "models", "u/" + user_id + "/rating");
// Prevent user_id from containing design_id
size_t sign_in = url.find("/rating");
std::string sub_url = url.substr(0, sign_in + 7);
url.erase(0, sign_in + 7);
boost::algorithm::replace_first(url, std::to_string(design_id), "");
url = sub_url + url;
try {
if (!url.empty()) { wxLaunchDefaultBrowser(url); }
} catch (...) {
return;
}
}
}
/*************************************************
Description:Extruder
**************************************************/
ExtruderImage::ExtruderImage(wxWindow* parent, wxWindowID id, int nozzle_num, const wxPoint& pos, const wxSize& size)
{
wxWindow::Create(parent, id, pos, wxSize(FromDIP(45), FromDIP(112)));
SetBackgroundColour(*wxWHITE);
m_nozzle_num = nozzle_num;
SetSize(wxSize(FromDIP(45), FromDIP(112)));
SetMinSize(wxSize(FromDIP(45), FromDIP(112)));
SetMaxSize(wxSize(FromDIP(45), FromDIP(112)));
m_pipe_filled_load = new ScalableBitmap(this, "pipe_of_loading_selected", 50);
m_pipe_filled_unload = new ScalableBitmap(this, "pipe_of_unloading_selected", 50);
m_pipe_empty_load = new ScalableBitmap(this, "pipe_of_empty", 50);
m_pipe_empty_unload = new ScalableBitmap(this, "pipe_of_empty", 50);
m_pipe_filled_load_unselected = new ScalableBitmap(this, "pipe_of_loading_unselected", 50);
m_pipe_filled_unload_unselected = new ScalableBitmap(this, "pipe_of_unloading_unselected", 50);
m_pipe_empty_load_unselected = new ScalableBitmap(this, "pipe_of_empty", 50);
m_pipe_empty_unload_unselected = new ScalableBitmap(this, "pipe_of_empty", 50);
m_left_extruder_active_filled = new ScalableBitmap(this, "left_extruder_active_filled", 62);
m_left_extruder_active_empty = new ScalableBitmap(this, "left_extruder_active_empty", 62);
m_left_extruder_unactive_filled = new ScalableBitmap(this, "left_extruder_unactive_filled", 62);
m_left_extruder_unactive_empty = new ScalableBitmap(this, "left_extruder_unactive_empty", 62);
m_right_extruder_active_filled = new ScalableBitmap(this, "right_extruder_active_filled", 62);
m_right_extruder_active_empty = new ScalableBitmap(this, "right_extruder_active_empty", 62);
m_right_extruder_unactive_filled = new ScalableBitmap(this, "right_extruder_unactive_filled", 62);
m_right_extruder_unactive_empty = new ScalableBitmap(this, "right_extruder_unactive_empty", 62);
m_extruder_single_nozzle_empty_load = new ScalableBitmap(this, "monitor_extruder_empty_load", 106);
m_extruder_single_nozzle_empty_unload = new ScalableBitmap(this, "monitor_extruder_empty_unload", 106);
m_extruder_single_nozzle_filled_load = new ScalableBitmap(this, "monitor_extruder_filled_load", 106);
m_extruder_single_nozzle_filled_unload = new ScalableBitmap(this, "monitor_extruder_filled_unload", 106);
Bind(wxEVT_PAINT, &ExtruderImage::paintEvent, this);
}
ExtruderImage::~ExtruderImage() {}
void ExtruderImage::msw_rescale()
{
//m_ams_extruder.SetSize(AMS_EXTRUDER_BITMAP_SIZE);
//auto image = m_ams_extruder.ConvertToImage();
//m_extruder_pipe = ScalableBitmap(this, "pipe_of_extruder_control", 50);
m_pipe_filled_load->msw_rescale();
m_pipe_filled_unload->msw_rescale();
m_pipe_empty_load->msw_rescale();
m_pipe_empty_unload->msw_rescale();
m_pipe_filled_load_unselected->msw_rescale();
m_pipe_filled_unload_unselected->msw_rescale();
m_pipe_empty_load_unselected->msw_rescale();
m_pipe_empty_unload_unselected->msw_rescale();
m_left_extruder_active_filled->msw_rescale();
m_left_extruder_active_empty->msw_rescale();
m_left_extruder_unactive_filled->msw_rescale();
m_left_extruder_unactive_empty->msw_rescale();
m_right_extruder_active_filled->msw_rescale();
m_right_extruder_active_empty->msw_rescale();
m_right_extruder_unactive_filled->msw_rescale();
m_right_extruder_unactive_empty->msw_rescale();
m_extruder_single_nozzle_empty_load->msw_rescale();
m_extruder_single_nozzle_empty_unload->msw_rescale();
m_extruder_single_nozzle_filled_load->msw_rescale();
m_extruder_single_nozzle_filled_unload->msw_rescale();
Layout();
Refresh();
}
void ExtruderImage::setExtruderCount(int nozzle_num)
{
m_nozzle_num = nozzle_num;
}
void ExtruderImage::setExtruderUsed(std::string loc)
{
//current_nozzle_idx = nozzle_id;
if (current_nozzle_loc == loc)
{
return;
}
current_nozzle_loc = loc;
Refresh();
}
void ExtruderImage::update(ExtruderState single_state)
{
m_single_ext_state = single_state;
}
void ExtruderImage::update(ExtruderState right_state, ExtruderState left_state) {
m_left_ext_state = left_state;
m_right_ext_state = right_state;
}
void ExtruderImage::paintEvent(wxPaintEvent& evt)
{
wxPaintDC dc(this);
render(dc);
}
void ExtruderImage::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 ExtruderImage::doRender(wxDC& dc)
{
auto size = GetSize();
//dc.DrawRectangle(0, FromDIP(5), size.x, size.y - FromDIP(5) - FromDIP(2));
auto pot = wxPoint(size.x / 2, (size.y - m_pipe_filled_load->GetBmpSize().y - m_left_extruder_active_filled->GetBmpSize().y) / 2);
if (m_nozzle_num >= 2){
ScalableBitmap* left_nozzle_bmp;
ScalableBitmap* right_nozzle_bmp;
ScalableBitmap* left_pipe_bmp;
ScalableBitmap* right_pipe_bmp;
switch (m_right_ext_state)
{
case Slic3r::GUI::FILLED_LOAD:
right_pipe_bmp = current_nozzle_loc == "right" ? m_pipe_filled_load : m_pipe_filled_load_unselected;
right_nozzle_bmp = current_nozzle_loc == "right" ? m_right_extruder_active_filled : m_right_extruder_unactive_filled;
break;
case Slic3r::GUI::FILLED_UNLOAD:
right_pipe_bmp = current_nozzle_loc == "right" ? m_pipe_filled_unload : m_pipe_filled_unload_unselected;
right_nozzle_bmp = current_nozzle_loc == "right" ? m_right_extruder_active_filled : m_right_extruder_unactive_filled;
break;
case Slic3r::GUI::EMPTY_LOAD:
right_pipe_bmp = current_nozzle_loc == "right" ? m_pipe_empty_load : m_pipe_empty_load_unselected;
right_nozzle_bmp = current_nozzle_loc == "right" ? m_right_extruder_active_empty : m_right_extruder_unactive_empty;
break;
case Slic3r::GUI::EMPTY_UNLOAD:
right_pipe_bmp = current_nozzle_loc == "right" ? m_pipe_empty_unload : m_pipe_empty_unload_unselected;
right_nozzle_bmp = current_nozzle_loc == "right" ? m_right_extruder_active_empty : m_right_extruder_unactive_empty;
break;
default:
break;
}
switch (m_left_ext_state)
{
case Slic3r::GUI::FILLED_LOAD:
left_pipe_bmp = current_nozzle_loc == "left" ? m_pipe_filled_load : m_pipe_filled_load_unselected;
left_nozzle_bmp = current_nozzle_loc == "left" ? m_left_extruder_active_filled : m_left_extruder_unactive_filled;
break;
case Slic3r::GUI::FILLED_UNLOAD:
left_pipe_bmp = current_nozzle_loc == "left" ? m_pipe_filled_unload : m_pipe_filled_unload_unselected;
left_nozzle_bmp = current_nozzle_loc == "left" ? m_left_extruder_active_filled : m_left_extruder_unactive_filled;
break;
case Slic3r::GUI::EMPTY_LOAD:
left_pipe_bmp = current_nozzle_loc == "left" ? m_pipe_empty_load : m_pipe_empty_load_unselected;
left_nozzle_bmp = current_nozzle_loc == "left" ? m_left_extruder_active_empty : m_left_extruder_unactive_empty;
break;
case Slic3r::GUI::EMPTY_UNLOAD:
left_pipe_bmp = current_nozzle_loc == "left" ? m_pipe_empty_unload : m_pipe_empty_unload_unselected;
left_nozzle_bmp = current_nozzle_loc == "left" ? m_left_extruder_active_empty : m_left_extruder_unactive_empty;
break;
default:
break;
}
left_pipe_bmp = m_pipe_filled_load;
right_pipe_bmp = m_pipe_filled_load;
dc.DrawBitmap(left_pipe_bmp->bmp(), pot.x - left_nozzle_bmp->GetBmpWidth() / 2 - left_pipe_bmp->GetBmpWidth() / 2 + left_pipe_bmp->GetBmpWidth() / 5, pot.y);
dc.DrawBitmap(left_nozzle_bmp->bmp(), pot.x - left_nozzle_bmp->GetBmpWidth(), pot.y + left_pipe_bmp->GetBmpSize().y);
dc.DrawBitmap(right_pipe_bmp->bmp(), pot.x + right_nozzle_bmp->GetBmpWidth() / 2 - right_pipe_bmp->GetBmpWidth() / 2 - right_pipe_bmp->GetBmpWidth() / 5, pot.y);
dc.DrawBitmap(right_nozzle_bmp->bmp(), pot.x, pot.y + right_pipe_bmp->GetBmpSize().y);
}
else{
ScalableBitmap* nozzle_bmp = nullptr;
switch (m_single_ext_state)
{
case Slic3r::GUI::FILLED_LOAD: nozzle_bmp = m_extruder_single_nozzle_filled_load; break;
case Slic3r::GUI::FILLED_UNLOAD: nozzle_bmp = m_extruder_single_nozzle_filled_unload; break;
case Slic3r::GUI::EMPTY_LOAD: nozzle_bmp = m_extruder_single_nozzle_empty_load; break;
case Slic3r::GUI::EMPTY_UNLOAD: nozzle_bmp = m_extruder_single_nozzle_empty_unload; break;
default: break;
}
if (nozzle_bmp)
{
dc.DrawBitmap(nozzle_bmp->bmp(), pot.x - nozzle_bmp->GetBmpWidth() / 2, (size.y - nozzle_bmp->GetBmpHeight()) / 2);
}
}
}
#define SWITCHING_STATUS_BTN_SIZE wxSize(FromDIP(25), FromDIP(26))
ExtruderSwithingStatus::ExtruderSwithingStatus(wxWindow *parent)
: wxPanel(parent)
{
m_switching_status_label = new Label(this);
m_switching_status_label->SetFont(::Label::Body_13);
if (parent)
{ m_switching_status_label->SetBackgroundColour(parent->GetBackgroundColour());
}
m_button_quit = new Button(this, _L_CONTEXT(L_CONTEXT("Quit", "Quit_Switching"), "Quit_Switching"), "", 0, FromDIP(22));
m_button_quit->SetStyle(ButtonStyle::Regular, ButtonType::Window);
m_button_quit->Bind(wxEVT_BUTTON, &ExtruderSwithingStatus::on_quit, this);
m_button_retry = new Button(this, _L("Retry"), "", 0, FromDIP(22));
m_button_retry->SetStyle(ButtonStyle::Confirm, ButtonType::Window);
m_button_retry->Bind(wxEVT_BUTTON, &ExtruderSwithingStatus::on_retry, this);
wxBoxSizer *btn_sizer = new wxBoxSizer(wxHORIZONTAL);
btn_sizer->Add(m_button_quit, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(10));
btn_sizer->Add(m_button_retry, 0, wxALIGN_CENTER_VERTICAL, 0);
wxBoxSizer *main_sizer = new wxBoxSizer(wxVERTICAL);
main_sizer->Add(m_switching_status_label, 0, wxALIGN_CENTER_HORIZONTAL | wxTOP, FromDIP(10));
main_sizer->Add(btn_sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxTOP, FromDIP(10));
SetSizer(main_sizer);
Layout();
}
void ExtruderSwithingStatus::updateBy(MachineObject *obj)
{
m_obj = obj;
if (!m_obj)
{
Show(false);
}
else
{
/*do not display while command sended in a mean while*/
if ((time(nullptr) - m_last_ctrl_time) > HOLD_TIME_6SEC)
{
updateBy(obj->GetExtderSystem());
}
}
}
void ExtruderSwithingStatus::updateBy(const DevExtderSystem* ext_system)
{
Show(ext_system->GetTotalExtderCount() > 1);
if (!IsShown()) { return; }
auto state = ext_system->GetSwitchState();
{
if (state == DevExtderSwitchState::ES_SWITCHING)
{
m_switching_status_label->SetLabel(_L("Switching..."));
m_switching_status_label->SetForegroundColour(StateColor::darkModeColorFor("#262E30"));
m_switching_status_label->Show(true);
}
else if (state == DevExtderSwitchState::ES_SWITCHING_FAILED)
{
m_switching_status_label->SetLabel(_L("Switching failed"));
m_switching_status_label->SetForegroundColour(StateColor::darkModeColorFor(*wxRED));
m_switching_status_label->Show(true);
}
else
{
m_switching_status_label->Show(false);
}
}
if (state != DevExtderSwitchState::ES_SWITCHING_FAILED)
{
showQuitBtn(false);
showRetryBtn(false);
return;
}
/*can not quit if it's printing*/
if (m_obj && !m_obj->is_in_printing() && !m_obj->is_in_printing_pause())
{
showQuitBtn(true);
}
showRetryBtn(true);
}
void ExtruderSwithingStatus::showQuitBtn(bool show)
{
if (m_button_quit->IsShown() != show)
{
m_button_quit->Show(show);
Layout();
}
}
void ExtruderSwithingStatus::showRetryBtn(bool show)
{
if (m_button_retry->IsShown() != show) {
m_button_retry->Show(show);
Layout();
}
}
bool ExtruderSwithingStatus::has_content_shown() const
{
if (!IsShown()) { return false; }
if (!m_switching_status_label->IsShown() && !m_button_quit->IsShown() && !m_button_retry->IsShown()) { return false; }
return true;
}
void ExtruderSwithingStatus::msw_rescale()
{
m_button_quit->Rescale(); // ORCA
m_button_retry->Rescale(); // ORCA
Layout();
}
void ExtruderSwithingStatus::on_quit(wxCommandEvent &event)
{
Show(false);
if (m_obj)
{
m_obj->command_ams_control("abort");
m_last_ctrl_time = time(nullptr);
}
}
void ExtruderSwithingStatus::on_retry(wxCommandEvent &event)
{
Show(false);
if (m_obj)
{
m_obj->command_ams_control("resume");
m_last_ctrl_time = time(nullptr);
}
}
PrintingTaskPanel::PrintingTaskPanel(wxWindow* parent, PrintingTaskType type)
: wxPanel(parent, wxID_ANY,wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL)
{
m_type = type;
m_question_button = nullptr;
create_panel(this);
SetBackgroundColour(*wxWHITE);
m_bitmap_background = ScalableBitmap(this, "thumbnail_grid", m_bitmap_thumbnail->GetSize().y);
m_bitmap_thumbnail->Bind(wxEVT_PAINT, &PrintingTaskPanel::paint, this);
}
PrintingTaskPanel::~PrintingTaskPanel()
{
if (m_question_button) {
delete m_question_button;
m_question_button = nullptr;
}
}
void PrintingTaskPanel::create_panel(wxWindow* parent)
{
wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *bSizer_printing_title = new wxBoxSizer(wxHORIZONTAL);
m_panel_printing_title = new wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(-1, PAGE_TITLE_HEIGHT), wxTAB_TRAVERSAL);
m_panel_printing_title->SetBackgroundColour(STATUS_TITLE_BG);
m_staticText_printing = new wxStaticText(m_panel_printing_title, wxID_ANY ,_L("Printing progress"));
m_staticText_printing->Wrap(-1);
//m_staticText_printing->SetFont(PAGE_TITLE_FONT);
m_staticText_printing->SetForegroundColour(PAGE_TITLE_FONT_COL);
bSizer_printing_title->Add(m_staticText_printing, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, PAGE_TITLE_LEFT_MARGIN);
bSizer_printing_title->Add(0, 0, 1, wxEXPAND, 0);
m_panel_printing_title->SetSizer(bSizer_printing_title);
m_panel_printing_title->Layout();
bSizer_printing_title->Fit(m_panel_printing_title);
m_bitmap_thumbnail = new wxStaticBitmap(parent, wxID_ANY, m_thumbnail_placeholder.bmp(), wxDefaultPosition, TASK_THUMBNAIL_SIZE, 0);
m_bitmap_thumbnail->SetMaxSize(TASK_THUMBNAIL_SIZE);
m_bitmap_thumbnail->SetMinSize(TASK_THUMBNAIL_SIZE);
wxBoxSizer *bSizer_subtask_info = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *bSizer_task_name = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *bSizer_task_name_hor = new wxBoxSizer(wxHORIZONTAL);
wxPanel* task_name_panel = new wxPanel(parent);
task_name_panel->SetBackgroundColour(*wxWHITE);
m_staticText_subtask_value = new wxStaticText(task_name_panel, wxID_ANY, _L("N/A"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT | wxST_ELLIPSIZE_END);
m_staticText_subtask_value->SetMaxSize(wxSize(FromDIP(600), -1));
m_staticText_subtask_value->Wrap(-1);
#ifdef __WXOSX_MAC__
m_staticText_subtask_value->SetFont(::Label::Body_13);
#else
m_staticText_subtask_value->SetFont(wxFont(13, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxT("HarmonyOS Sans SC")));
#endif
m_staticText_subtask_value->SetForegroundColour(wxColour(44, 44, 46));
m_bitmap_static_use_time = new wxStaticBitmap(task_name_panel, wxID_ANY, m_bitmap_use_time.bmp(), wxDefaultPosition, wxSize(FromDIP(16), FromDIP(16)));
m_staticText_consumption_of_time = new wxStaticText(task_name_panel, wxID_ANY, "0m", wxDefaultPosition, wxDefaultSize, 0);
m_staticText_consumption_of_time->SetFont(::Label::Body_12);
m_staticText_consumption_of_time->SetForegroundColour(wxColour(0x68, 0x68, 0x68));
m_staticText_consumption_of_time->Wrap(-1);
m_bitmap_static_use_weight = new wxStaticBitmap(task_name_panel, wxID_ANY, m_bitmap_use_weight.bmp(), wxDefaultPosition, wxSize(FromDIP(16), FromDIP(16)));
m_staticText_consumption_of_weight = new wxStaticText(task_name_panel, wxID_ANY, "0g", wxDefaultPosition, wxDefaultSize, 0);
m_staticText_consumption_of_weight->SetFont(::Label::Body_12);
m_staticText_consumption_of_weight->SetForegroundColour(wxColour(0x68, 0x68, 0x68));
m_staticText_consumption_of_weight->Wrap(-1);
bSizer_task_name_hor->Add(m_staticText_subtask_value, 1, wxALL | wxEXPAND, 0);
bSizer_task_name_hor->Add(m_bitmap_static_use_time, 0, wxALIGN_CENTER_VERTICAL, 0);
bSizer_task_name_hor->Add(m_staticText_consumption_of_time, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, FromDIP(3));
bSizer_task_name_hor->Add(0, 0, 0, wxLEFT, FromDIP(10));
bSizer_task_name_hor->Add(m_bitmap_static_use_weight, 0, wxALIGN_CENTER_VERTICAL, 0);
bSizer_task_name_hor->Add(m_staticText_consumption_of_weight, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(3));
bSizer_task_name_hor->Add(0, 0, 0, wxRIGHT, FromDIP(10));
task_name_panel->SetSizer(bSizer_task_name_hor);
task_name_panel->Layout();
task_name_panel->Fit();
bSizer_task_name->Add(task_name_panel, 0, wxEXPAND, FromDIP(5));
m_staticText_profile_value = new wxStaticText(parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT | wxST_ELLIPSIZE_END);
m_staticText_profile_value->Wrap(-1);
#ifdef __WXOSX_MAC__
m_staticText_profile_value->SetFont(::Label::Body_11);
#else
m_staticText_profile_value->SetFont(wxFont(11, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxT("HarmonyOS Sans SC")));
#endif
m_staticText_profile_value->SetForegroundColour(0x6B6B6B);
auto progress_lr_panel = new wxPanel(parent, wxID_ANY);
progress_lr_panel->SetBackgroundColour(*wxWHITE);
m_gauge_progress = new ProgressBar(progress_lr_panel, wxID_ANY, 100, wxDefaultPosition, wxDefaultSize);
m_gauge_progress->SetValue(0);
m_gauge_progress->SetHeight(PROGRESSBAR_HEIGHT);
wxBoxSizer *bSizer_task_btn = new wxBoxSizer(wxHORIZONTAL);
bSizer_task_btn->Add(FromDIP(10), 0, 0);
StateColor white_bg(std::pair<wxColour, int>(wxColour(255, 255, 255), StateColor::Disabled), std::pair<wxColour, int>(wxColour(255, 255, 255), StateColor::Pressed),
std::pair<wxColour, int>(wxColour(255, 255, 255), StateColor::Hovered), std::pair<wxColour, int>(wxColour(255, 255, 255), StateColor::Enabled),
std::pair<wxColour, int>(wxColour(255, 255, 255), StateColor::Normal));
m_button_partskip = new Button(progress_lr_panel, wxEmptyString, "print_control_partskip_disable", 0, 16, wxID_ANY); // ORCA match icon size
m_button_partskip->Enable(false);
m_button_partskip->Hide();
m_button_partskip->SetBackgroundColor(white_bg);
m_button_partskip->SetIcon("print_control_partskip_disable");
m_button_partskip->SetBorderColor(*wxWHITE);
m_button_partskip->SetFont(Label::Body_12);
m_button_partskip->SetCornerRadius(0);
m_button_partskip->SetToolTip(_L("Parts Skip"));
m_button_partskip->Bind(wxEVT_ENTER_WINDOW, [this](auto &e) { m_button_partskip->SetIcon("print_control_partskip_hover"); });
m_button_partskip->Bind(wxEVT_LEAVE_WINDOW, [this](auto &e) { m_button_partskip->SetIcon("print_control_partskip"); });
m_button_pause_resume = new ScalableButton(progress_lr_panel, wxID_ANY, "print_control_pause", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER,true);
m_button_pause_resume->Bind(wxEVT_ENTER_WINDOW, [this](auto &e) {
if (m_button_pause_resume->GetToolTipText() == _L("Pause")) {
m_button_pause_resume->SetBitmap_("print_control_pause_hover");
}
if (m_button_pause_resume->GetToolTipText() == _L("Resume")) {
m_button_pause_resume->SetBitmap_("print_control_resume_hover");
}
});
m_button_pause_resume->Bind(wxEVT_LEAVE_WINDOW, [this](auto &e) {
auto buf = m_button_pause_resume->GetClientData();
if (m_button_pause_resume->GetToolTipText() == _L("Pause")) {
m_button_pause_resume->SetBitmap_("print_control_pause");
}
if (m_button_pause_resume->GetToolTipText() == _L("Resume")) {
m_button_pause_resume->SetBitmap_("print_control_resume");
}
});
m_button_abort = new ScalableButton(progress_lr_panel, wxID_ANY, "print_control_stop", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, true);
m_button_abort->SetToolTip(_L("Stop"));
m_button_abort->Bind(wxEVT_ENTER_WINDOW, [this](auto &e) {
m_button_abort->SetBitmap_("print_control_stop_hover");
});
m_button_abort->Bind(wxEVT_LEAVE_WINDOW, [this](auto &e) {
m_button_abort->SetBitmap_("print_control_stop"); }
);
wxBoxSizer *bSizer_buttons = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *bSizer_text = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *bSizer_finish_time = new wxBoxSizer(wxHORIZONTAL);
wxPanel* penel_text = new wxPanel(progress_lr_panel);
wxPanel* penel_finish_time = new wxPanel(progress_lr_panel);
penel_text->SetBackgroundColour(*wxWHITE);
penel_finish_time->SetBackgroundColour(*wxWHITE);
wxBoxSizer *sizer_percent = new wxBoxSizer(wxVERTICAL);
sizer_percent->Add(0, 0, 1, wxEXPAND, 0);
wxBoxSizer *sizer_percent_icon = new wxBoxSizer(wxVERTICAL);
sizer_percent_icon->Add(0, 0, 1, wxEXPAND, 0);
m_staticText_progress_percent = new wxStaticText(penel_text, wxID_ANY, "0", wxDefaultPosition, wxDefaultSize, 0);
m_staticText_progress_percent->SetFont(::Label::Head_18);
m_staticText_progress_percent->SetMaxSize(wxSize(-1, FromDIP(20)));
m_staticText_progress_percent->SetForegroundColour(wxColour(0, 150, 136));
m_staticText_progress_percent_icon = new wxStaticText(penel_text, wxID_ANY, "%", wxDefaultPosition, wxDefaultSize, 0);
m_staticText_progress_percent_icon->SetFont(::Label::Body_11);
m_staticText_progress_percent_icon->SetMaxSize(wxSize(-1, FromDIP(13)));
m_staticText_progress_percent_icon->SetForegroundColour(wxColour(0, 150, 136));
sizer_percent->Add(m_staticText_progress_percent, 0, 0, 0);
#ifdef __WXOSX_MAC__
sizer_percent_icon->Add(m_staticText_progress_percent_icon, 0, wxBOTTOM, FromDIP(2));
#else
sizer_percent_icon->Add(m_staticText_progress_percent_icon, 0, 0, 0);
#endif
m_staticText_progress_left = new wxStaticText(penel_text, wxID_ANY, _L("N/A"), wxDefaultPosition, wxDefaultSize, 0);
m_staticText_progress_left->Wrap(-1);
m_staticText_progress_left->SetFont(wxFont(12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxT("HarmonyOS Sans SC")));
m_staticText_progress_left->SetForegroundColour(wxColour(146, 146, 146));
m_staticText_layers = new wxStaticText(penel_text, wxID_ANY, _L("Layer: N/A"));
m_staticText_layers->SetFont(wxFont(12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxT("HarmonyOS Sans SC")));
m_staticText_layers->SetForegroundColour(wxColour(146, 146, 146));
m_staticText_layers->Hide();
bSizer_text->Add(sizer_percent, 0, wxEXPAND, 0);
bSizer_text->Add(sizer_percent_icon, 0, wxEXPAND, 0);
bSizer_text->Add(0, 0, 1, wxEXPAND, 0);
bSizer_text->Add(m_staticText_layers, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
bSizer_text->Add(0, 0, 0, wxLEFT, FromDIP(20));
bSizer_text->Add(m_staticText_progress_left, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
m_printing_stage_panel = new wxPanel(penel_finish_time);
m_printing_stage_panel->SetBackgroundColour(*wxWHITE);
wxBoxSizer *printingstage_vertical_sizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *printingstage_horizontal_sizer = new wxBoxSizer(wxHORIZONTAL);
m_printing_stage_underline = new wxPanel(m_printing_stage_panel);
m_printing_stage_underline->SetMaxSize(wxSize(-1, FromDIP(1)));
m_printing_stage_underline->SetMinSize(wxSize(-1, FromDIP(1)));
m_printing_stage_underline->SetBackgroundColour(wxColour(146, 146, 146));
m_printing_stage_underline->Hide();
m_printing_stage_value = new wxStaticText(m_printing_stage_panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT | wxST_ELLIPSIZE_END);
m_printing_stage_value->Wrap(-1);
m_printing_stage_value->SetMaxSize(wxSize(FromDIP(800), -1));
#ifdef __WXOSX_MAC__
m_printing_stage_value->SetFont(::Label::Body_11);
#else
m_printing_stage_value->SetFont(wxFont(11, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxT("HarmonyOS Sans SC")));
#endif
m_printing_stage_value->SetForegroundColour(STAGE_TEXT_COL);
m_printing_stage_value->Bind(wxEVT_LEFT_UP, &PrintingTaskPanel::on_stage_clicked, this);
m_printing_stage_value->Bind(wxEVT_ENTER_WINDOW, [this](wxMouseEvent &event) {
auto *dev_manager = wxGetApp().getDeviceManager();
MachineObject *obj = dev_manager ? dev_manager->get_selected_machine() : nullptr;
if (obj && obj->stage_curr == 58) {
m_printing_stage_value->SetCursor(wxCursor(wxCURSOR_HAND));
m_printing_stage_underline->Show();
} else {
m_printing_stage_value->SetCursor(wxCursor(wxCURSOR_ARROW));
m_printing_stage_underline->Hide();
}
m_printing_stage_panel->Layout();
Layout();
event.Skip();
});
m_printing_stage_value->Bind(wxEVT_LEAVE_WINDOW, [this](wxMouseEvent &event) {
auto *dev_manager = wxGetApp().getDeviceManager();
MachineObject *obj = dev_manager ? dev_manager->get_selected_machine() : nullptr;
if (obj && obj->stage_curr == 58) {
m_printing_stage_value->SetCursor(wxCURSOR_ARROW);
m_printing_stage_underline->Hide();
}
m_printing_stage_panel->Layout();
Layout();
event.Skip();
});
// penel_text->SetMaxSize(wxSize(FromDIP(600), -1));
penel_text->SetSizer(bSizer_text);
penel_text->Layout();
// Create question button
m_question_button = new ScalableButton(m_printing_stage_panel, wxID_ANY, "thermal_question", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, true);
m_question_button->SetToolTip(_L("Click to view thermal preconditioning explanation"));
m_question_button->SetBackgroundColour(wxColour(255, 255, 255));
m_question_button->Hide(); // Hide by default
m_question_button->Bind(wxEVT_LEFT_UP, &PrintingTaskPanel::on_stage_clicked, this);
m_question_button->Bind(wxEVT_ENTER_WINDOW, [this](wxMouseEvent &event) {
auto *dev_manager = wxGetApp().getDeviceManager();
MachineObject *obj = dev_manager ? dev_manager->get_selected_machine() : nullptr;
if (obj && obj->stage_curr == 58) {
m_question_button->SetCursor(wxCursor(wxCURSOR_HAND));
m_printing_stage_underline->Show();
}
event.Skip();
});
m_question_button->Bind(wxEVT_LEAVE_WINDOW, [this](wxMouseEvent &event) {
auto *dev_manager = wxGetApp().getDeviceManager();
MachineObject *obj = dev_manager ? dev_manager->get_selected_machine() : nullptr;
if (obj && obj->stage_curr == 58) {
m_question_button->SetCursor(wxCURSOR_ARROW);
m_printing_stage_underline->Hide();
event.Skip();
}
});
printingstage_horizontal_sizer->Add(m_printing_stage_value, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 0);
printingstage_horizontal_sizer->Add(m_question_button, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(5));
printingstage_vertical_sizer->Add(printingstage_horizontal_sizer, 0, wxALIGN_CENTER_VERTICAL, 0);
printingstage_vertical_sizer->Add(m_printing_stage_underline, 0, wxEXPAND, 0);
m_printing_stage_panel->SetSizer(printingstage_vertical_sizer);
// Orca: display the end time of the print
m_staticText_progress_end = new wxStaticText(penel_finish_time, wxID_ANY, _L("N/A"), wxDefaultPosition, wxDefaultSize, 0);
m_staticText_progress_end->Wrap(-1);
m_staticText_progress_end->SetFont(
wxFont(12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxT("HarmonyOS Sans SC")));
m_staticText_progress_end->SetForegroundColour(wxColour(146, 146, 146));
bSizer_finish_time->Add(m_printing_stage_panel, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 0);
bSizer_finish_time->Add(0, 0, 1, wxEXPAND, 0);
bSizer_finish_time->Add(m_staticText_progress_end, 0, wxLEFT | wxEXPAND, 0);
// penel_finish_time->SetMaxSize(wxSize(FromDIP(600), -1));
penel_finish_time->SetSizer(bSizer_finish_time);
penel_finish_time->Layout();
auto progress_lr_sizer = new wxBoxSizer(wxHORIZONTAL);
auto progress_left_sizer = new wxBoxSizer(wxVERTICAL);
auto progress_right_sizer = new wxBoxSizer(wxHORIZONTAL);
progress_left_sizer->Add(penel_text, 0, wxEXPAND | wxALL, 0);
progress_left_sizer->Add(m_gauge_progress, 0, wxEXPAND | wxTOP | wxBOTTOM, FromDIP(10));
progress_left_sizer->Add(penel_finish_time, 0, wxEXPAND |wxALL, 0);
// progress_left_sizer->SetMaxSize(wxSize(FromDIP(600), -1));
progress_right_sizer->Add(0, 0, 0, wxEXPAND | wxLEFT, FromDIP(18));
progress_right_sizer->Add(m_button_partskip, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(0));//5
progress_right_sizer->Add(0, 0, 0, wxEXPAND | wxLEFT, FromDIP(18));
progress_right_sizer->Add(m_button_pause_resume, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(0));
progress_right_sizer->Add(0, 0, 0, wxEXPAND | wxLEFT, FromDIP(18));
progress_right_sizer->Add(m_button_abort, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(0));
progress_right_sizer->Add(0, 0, 0, wxEXPAND | wxLEFT, FromDIP(18));
progress_lr_sizer->Add(progress_left_sizer, 1, wxEXPAND | wxALL, 0);
progress_lr_sizer->Add(progress_right_sizer, 0, wxEXPAND | wxALL , 0);
progress_lr_panel->SetSizer(progress_lr_sizer);
progress_lr_panel->SetMaxSize(wxSize(FromDIP(720), -1));
progress_lr_panel->Layout();
progress_lr_panel->Fit();
bSizer_subtask_info->Add(0, 0, 0, wxEXPAND | wxTOP, FromDIP(14));
bSizer_subtask_info->Add(bSizer_task_name, 0, wxEXPAND|wxRIGHT, FromDIP(18));
bSizer_subtask_info->Add(m_staticText_profile_value, 0, wxEXPAND | wxTOP, FromDIP(5));
bSizer_subtask_info->Add(progress_lr_panel, 0, wxEXPAND | wxTOP, FromDIP(5));
m_printing_sizer = new wxBoxSizer(wxHORIZONTAL);
m_printing_sizer->SetMinSize(wxSize(PAGE_MIN_WIDTH, -1));
m_printing_sizer->Add(m_bitmap_thumbnail, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxLEFT, FromDIP(12));
m_printing_sizer->Add(FromDIP(8), 0, 0, wxEXPAND, 0);
m_printing_sizer->Add(bSizer_subtask_info, 1, wxALL | wxEXPAND, 0);
m_staticline = new wxPanel( parent, wxID_ANY);
m_staticline->SetBackgroundColour(wxColour(238,238,238));
m_staticline->Layout();
m_staticline->Hide();
m_panel_error_txt = new wxPanel(parent, wxID_ANY);
m_panel_error_txt->SetBackgroundColour(*wxWHITE);
wxBoxSizer *static_text_sizer = new wxBoxSizer(wxHORIZONTAL);
m_error_text = new Label(m_panel_error_txt, "", LB_AUTO_WRAP);
m_error_text->SetForegroundColour(wxColour(255, 0, 0));
static_text_sizer->Add(m_error_text, 1, wxEXPAND | wxLEFT, FromDIP(17));
m_button_clean = new Button(m_panel_error_txt, _L("Clear"));
m_button_clean->SetStyle(ButtonStyle::Regular, ButtonType::Window);
static_text_sizer->Add( FromDIP(10), 0, 0, 0, 0 );
static_text_sizer->Add(m_button_clean, 0, wxALIGN_CENTRE_VERTICAL|wxRIGHT, FromDIP(5));
m_panel_error_txt->SetSizer(static_text_sizer);
m_panel_error_txt->Hide();
sizer->Add(m_panel_printing_title, 0, wxEXPAND | wxALL, 0);
sizer->Add(0, FromDIP(12), 0);
sizer->Add(m_printing_sizer, 0, wxEXPAND | wxALL, 0);
sizer->Add(0, 0, 0, wxTOP, FromDIP(15));
sizer->Add(m_staticline, 0, wxEXPAND | wxALL, FromDIP(10));
sizer->Add(m_panel_error_txt, 0, wxEXPAND | wxALL, 0);
sizer->Add(0, FromDIP(12), 0);
m_score_staticline = new wxPanel(parent, wxID_ANY);
m_score_staticline->SetBackgroundColour(wxColour(238, 238, 238));
m_score_staticline->Layout();
m_score_staticline->Hide();
sizer->Add(0, 0, 0, wxTOP, FromDIP(15));
sizer->Add(m_score_staticline, 0, wxEXPAND | wxALL, FromDIP(10));
m_request_failed_panel = new wxPanel(parent, wxID_ANY);
m_request_failed_panel->SetBackgroundColour(*wxWHITE);
wxBoxSizer *static_request_failed_panel_sizer = new wxBoxSizer(wxHORIZONTAL);
m_request_failed_info = new wxStaticText(m_request_failed_panel, wxID_ANY, _L("You have completed printing the mall model, \nbut synchronizing rating information has failed."), wxDefaultPosition, wxDefaultSize, 0);
m_request_failed_info->Wrap(-1);
m_request_failed_info->SetForegroundColour(*wxRED);
m_request_failed_info->SetFont(::Label::Body_10);
static_request_failed_panel_sizer->Add(m_request_failed_info, 0, wxEXPAND | wxALL, FromDIP(10));
m_button_market_retry = new Button(m_request_failed_panel, _L("Retry"));
m_button_market_retry->SetStyle(ButtonStyle::Confirm, ButtonType::Window);
static_request_failed_panel_sizer->Add(0, 0, 1, wxEXPAND, 0);
static_request_failed_panel_sizer->Add(m_button_market_retry, 0, wxEXPAND | wxALL, FromDIP(10));
m_request_failed_panel->SetSizer(static_request_failed_panel_sizer);
m_request_failed_panel->Hide();
sizer->Add(m_request_failed_panel, 0, wxEXPAND | wxALL, FromDIP(10));
m_score_subtask_info = new wxPanel(parent, wxID_ANY);
m_score_subtask_info->SetBackgroundColour(*wxWHITE);
wxBoxSizer * static_score_sizer = new wxBoxSizer(wxVERTICAL);
wxStaticText *static_score_text = new wxStaticText(m_score_subtask_info, wxID_ANY, _L("How do you like this printing file?"), wxDefaultPosition, wxDefaultSize, 0);
static_score_text->Wrap(-1);
static_score_sizer->Add(static_score_text, 1, wxEXPAND | wxALL, FromDIP(10));
m_has_rated_prompt = new wxStaticText(m_score_subtask_info, wxID_ANY, _L("(The model has already been rated. Your rating will overwrite the previous rating.)"), wxDefaultPosition, wxDefaultSize, 0);
m_has_rated_prompt->Wrap(-1);
m_has_rated_prompt->SetForegroundColour(*wxBLACK);
m_has_rated_prompt->SetFont(::Label::Body_10);
m_has_rated_prompt->Hide();
m_star_count = 0;
wxBoxSizer *static_score_star_sizer = new wxBoxSizer(wxHORIZONTAL);
m_score_star.resize(5);
for (int i = 0; i < m_score_star.size(); ++i) {
m_score_star[i] = new ScalableButton(m_score_subtask_info, wxID_ANY, "score_star_dark", wxEmptyString, wxSize(FromDIP(26), FromDIP(26)), wxDefaultPosition,
wxBU_EXACTFIT | wxNO_BORDER, true, 26);
m_score_star[i]->SetMinSize(wxSize(FromDIP(26), FromDIP(26)));
m_score_star[i]->SetMaxSize(wxSize(FromDIP(26), FromDIP(26)));
m_score_star[i]->Bind(wxEVT_LEFT_DOWN, [this, i](auto &e) {
for (int j = 0; j < m_score_star.size(); ++j) {
ScalableBitmap light_star = ScalableBitmap(nullptr, "score_star_light", 26);
m_score_star[j]->SetBitmap(light_star.bmp());
if (m_score_star[j] == m_score_star[i]) {
m_star_count = j + 1;
break;
}
}
for (int k = m_star_count; k < m_score_star.size(); ++k) {
ScalableBitmap dark_star = ScalableBitmap(nullptr, "score_star_dark", 26);
m_score_star[k]->SetBitmap(dark_star.bmp());
}
m_star_count_dirty = true;
m_button_market_scoring->Enable(true);
});
static_score_star_sizer->Add(m_score_star[i], 1, wxEXPAND | wxLEFT, FromDIP(5));
}
m_button_market_scoring = new Button(m_score_subtask_info, _L("Rate"));
m_button_market_scoring->SetStyle(ButtonStyle::Confirm, ButtonType::Window);
m_button_market_scoring->Enable(false);
static_score_star_sizer->Add(0, 0, 1, wxEXPAND, 0);
static_score_star_sizer->Add(m_button_market_scoring, 0, wxEXPAND | wxRIGHT, FromDIP(10));
static_score_sizer->Add(static_score_star_sizer, 0, wxEXPAND, FromDIP(10));
static_score_sizer->Add(m_has_rated_prompt, 1, wxEXPAND | wxALL, FromDIP(10));
m_score_subtask_info->SetSizer(static_score_sizer);
m_score_subtask_info->Layout();
m_score_subtask_info->Hide();
sizer->Add(m_score_subtask_info, 0, wxEXPAND | wxALL, 0);
sizer->Add(0, FromDIP(12), 0);
if (m_type == CALIBRATION) {
m_panel_printing_title->Hide();
m_bitmap_thumbnail->Hide();
task_name_panel->Hide();
m_staticText_profile_value->Hide();
}
parent->SetSizer(sizer);
parent->Layout();
parent->Fit();
}
void PrintingTaskPanel::paint(wxPaintEvent&)
{
wxPaintDC dc(m_bitmap_thumbnail);
if (wxGetApp().dark_mode()) {
if (m_brightness_value > 0 && m_brightness_value < SHOW_BACKGROUND_BITMAP_PIXEL_THRESHOLD) {
dc.DrawBitmap(m_bitmap_background.bmp(), 0, 0);
dc.SetTextForeground(*wxBLACK);
}
else
dc.SetTextForeground(*wxWHITE);
}
else
dc.SetTextForeground(*wxBLACK);
if (m_thumbnail_bmp_display.IsOk()) {
dc.DrawBitmap(m_thumbnail_bmp_display, wxPoint(0, 0));
}
dc.SetFont(Label::Body_12);
if (m_plate_index >= 0) {
wxString plate_id_str = wxString::Format("%d", m_plate_index);
dc.DrawText(plate_id_str, wxPoint(4, 4));
}
}
void PrintingTaskPanel::set_has_reted_text(bool has_rated)
{
if (has_rated) {
m_has_rated_prompt->Show();
} else {
m_has_rated_prompt->Hide();
}
Layout();
Fit();
}
void PrintingTaskPanel::msw_rescale()
{
m_panel_printing_title->SetSize(wxSize(-1, FromDIP(PAGE_TITLE_HEIGHT)));
m_printing_sizer->SetMinSize(wxSize(PAGE_MIN_WIDTH, -1));
//m_staticText_printing->SetMinSize(wxSize(PAGE_TITLE_TEXT_WIDTH, PAGE_TITLE_HEIGHT));
m_gauge_progress->SetHeight(PROGRESSBAR_HEIGHT);
m_gauge_progress->Rescale();
m_button_pause_resume->msw_rescale();
m_button_abort->msw_rescale();
m_bitmap_thumbnail->SetSize(TASK_THUMBNAIL_SIZE);
}
void PrintingTaskPanel::init_bitmaps()
{
m_thumbnail_placeholder = ScalableBitmap(this, "monitor_placeholder", 120);
m_bitmap_use_time = ScalableBitmap(this, "print_info_time", 16);
m_bitmap_use_weight = ScalableBitmap(this, "print_info_weight", 16);
}
void PrintingTaskPanel::init_scaled_buttons()
{
m_button_clean->SetMinSize(wxSize(FromDIP(48), FromDIP(24)));
m_button_clean->SetCornerRadius(FromDIP(12));
}
void PrintingTaskPanel::error_info_reset()
{
if (m_panel_error_txt->IsShown()) {
m_staticline->Hide();
m_panel_error_txt->Hide();
m_panel_error_txt->GetParent()->Layout();
m_error_text->SetLabel(wxEmptyString);
}
}
void PrintingTaskPanel::show_error_msg(wxString msg)
{
m_staticline->Show();
m_panel_error_txt->Show();
m_error_text->SetLabel(msg);
}
void PrintingTaskPanel::reset_printing_value()
{
this->set_thumbnail_img(m_thumbnail_placeholder.bmp(), m_thumbnail_placeholder.name());
this->set_plate_index(-1);
}
void PrintingTaskPanel::enable_partskip_button(MachineObject* obj, bool enable)
{
int stage = 0;
bool in_calibration_mode = false;
if( obj && (obj->print_type == "system" || CalibUtils::get_calib_mode_by_name(obj->subtask_name, stage) != CalibMode::Calib_None)){
in_calibration_mode = true;
}
if (!enable || in_calibration_mode) {
m_button_partskip->Enable(false);
m_button_partskip->SetLabel("");
m_button_partskip->SetIcon("print_control_partskip_disable");
}else if(obj && obj->is_support_brtc){
m_button_partskip->Enable(true);
m_button_partskip->SetIcon("print_control_partskip");
}
}
void PrintingTaskPanel::enable_pause_resume_button(bool enable, std::string type)
{
if (!enable) {
m_button_pause_resume->Enable(false);
if (type == "pause_disable") {
m_button_pause_resume->SetBitmap_("print_control_pause_disable");
}
else if (type == "resume_disable") {
m_button_pause_resume->SetBitmap_("print_control_resume_disable");
}
}
else {
m_button_pause_resume->Enable(true);
if (type == "resume") {
m_button_pause_resume->SetBitmap_("print_control_resume");
if (m_button_pause_resume->GetToolTipText() != _L("Resume")) { m_button_pause_resume->SetToolTip(_L("Resume")); }
}
else if (type == "pause") {
m_button_pause_resume->SetBitmap_("print_control_pause");
if (m_button_pause_resume->GetToolTipText() != _L("Pause")) { m_button_pause_resume->SetToolTip(_L("Pause")); }
}
}
}
void PrintingTaskPanel::enable_abort_button(bool enable)
{
if (!enable) {
m_button_abort->Enable(false);
m_button_abort->SetBitmap_("print_control_stop_disable");
}
else {
m_button_abort->Enable(true);
m_button_abort->SetBitmap_("print_control_stop");
}
}
void PrintingTaskPanel::update_subtask_name(wxString name)
{
if (m_staticText_subtask_value->GetLabelText() != name)
{
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": " << name;
}
m_staticText_subtask_value->SetLabelText(name);
}
void PrintingTaskPanel::update_stage_value(wxString stage, int val)
{
m_printing_stage_value->SetLabelText(stage);
m_gauge_progress->SetValue(val);
}
void PrintingTaskPanel::update_stage_value_with_machine(wxString stage, int val, MachineObject *obj)
{
m_gauge_progress->SetValue(val);
m_printing_stage_value->SetLabelText(stage);
if (obj && obj->stage_curr == 58) {
m_question_button->Show(); // Show question button
} else {
m_question_button->Hide(); // Hide question button
m_printing_stage_underline->Hide();
}
m_printing_stage_panel->Layout();
Layout();
}
void PrintingTaskPanel::on_stage_clicked(wxMouseEvent &event)
{
auto *dev_manager = wxGetApp().getDeviceManager();
MachineObject *obj = dev_manager ? dev_manager->get_selected_machine() : nullptr;
if (obj && obj->stage_curr == 58) {
wxWindow *top = wxGetTopLevelParent(this);
ThermalPreconditioningDialog m_thermal_dialog(top ? top : this, obj->get_dev_id() , "Calculating...");
m_thermal_dialog.ShowModal();
}
event.Skip();
}
void PrintingTaskPanel::update_progress_percent(wxString percent, wxString icon)
{
m_staticText_progress_percent->SetLabelText(percent);
m_staticText_progress_percent_icon->SetLabelText(icon);
}
void PrintingTaskPanel::update_left_time(wxString time)
{
m_staticText_progress_left->SetLabelText(time);
}
void PrintingTaskPanel::update_left_time(int mc_left_time)
{
// update gcode progress
std::string left_time;
wxString left_time_text = NA_STR;
try {
left_time = get_bbl_monitor_time_dhm(mc_left_time);
}
catch (...) {
;
}
if (!left_time.empty()) left_time_text = wxString::Format("-%s", left_time);
update_left_time(left_time_text);
//Update end time
std::string end_time;
wxString end_time_text = NA_STR;
try {
end_time = get_bbl_monitor_end_time_dhm(mc_left_time);
} catch (...) {
;
}
if (!end_time.empty())
end_time_text = wxString::Format("%s", end_time);
else
end_time_text = NA_STR;
m_staticText_progress_end->SetLabelText(end_time_text);
}
void PrintingTaskPanel::update_layers_num(bool show, wxString num)
{
if ((show == m_staticText_layers->IsShown()) && (num == m_staticText_layers->GetLabelText()))
{
return;
}
if (show) {
m_staticText_layers->Show(true);
m_staticText_layers->SetLabelText(num);
}
else {
m_staticText_layers->Show(false);
m_staticText_layers->SetLabelText(num);
}
}
void PrintingTaskPanel::show_priting_use_info(bool show, wxString time /*= wxEmptyString*/, wxString weight /*= wxEmptyString*/)
{
if (show) {
if (!m_staticText_consumption_of_time->IsShown()) {
m_bitmap_static_use_time->Show();
m_staticText_consumption_of_time->Show();
}
if (!m_staticText_consumption_of_weight->IsShown()) {
m_bitmap_static_use_weight->Show();
m_staticText_consumption_of_weight->Show();
}
m_staticText_consumption_of_time->SetLabelText(time);
m_staticText_consumption_of_weight->SetLabelText(weight);
}
else {
m_staticText_consumption_of_time->SetLabelText("0m");
m_staticText_consumption_of_weight->SetLabelText("0g");
if (m_staticText_consumption_of_time->IsShown()) {
m_bitmap_static_use_time->Hide();
m_staticText_consumption_of_time->Hide();
}
if (m_staticText_consumption_of_weight->IsShown()) {
m_bitmap_static_use_weight->Hide();
m_staticText_consumption_of_weight->Hide();
} }
}
void PrintingTaskPanel::show_profile_info(bool show, wxString profile /*= wxEmptyString*/)
{
if (show) {
if (!m_staticText_profile_value->IsShown()) { m_staticText_profile_value->Show(); }
m_staticText_profile_value->SetLabelText(profile);
}
else {
m_staticText_profile_value->SetLabelText(wxEmptyString);
m_staticText_profile_value->Hide();
}
}
// the API will buff the bmp and bmp_name
// when bmp_name is empty, the API will replace the image on force
void PrintingTaskPanel::set_thumbnail_img(const wxBitmap& bmp, const std::string& bmp_name)
{
if (!bmp_name.empty() && m_thumbnail_bmp_display_name == bmp_name) {
return;
}
m_thumbnail_bmp_display_name = bmp_name;
m_thumbnail_bmp_display = bmp;
Refresh();
}
void PrintingTaskPanel::set_plate_index(int plate_idx)
{
m_plate_index = plate_idx;
}
void PrintingTaskPanel::market_scoring_show()
{
m_score_staticline->Show();
m_score_subtask_info->Show();
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " show market scoring page";
}
void PrintingTaskPanel::market_scoring_hide()
{
m_score_staticline->Hide();
m_score_subtask_info->Hide();
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " hide market scoring page";
}
void PrintingTaskPanel::set_star_count(int star_count)
{
m_star_count = star_count;
for (int i = 0; i < m_score_star.size(); ++i) {
if (i < star_count) {
ScalableBitmap light_star = ScalableBitmap(nullptr, "score_star_light", 26);
m_score_star[i]->SetBitmap(light_star.bmp());
} else {
ScalableBitmap dark_star = ScalableBitmap(nullptr, "score_star_dark", 26);
m_score_star[i]->SetBitmap(dark_star.bmp());
}
}
}
StatusBasePanel::StatusBasePanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, const wxString &name)
: wxScrolledWindow(parent, id, pos, size, wxHSCROLL | wxVSCROLL)
{
this->SetScrollRate(25, 25);
Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
if (!dev) return;
obj = dev->get_selected_machine();
init_bitmaps();
this->SetBackgroundColour(wxColour(0xEE, 0xEE, 0xEE));
wxBoxSizer *bSizer_status = new wxBoxSizer(wxVERTICAL);
auto m_panel_separotor_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, PAGE_SPACING), wxTAB_TRAVERSAL);
m_panel_separotor_top->SetBackgroundColour(STATUS_PANEL_BG);
bSizer_status->Add(m_panel_separotor_top, 0, wxEXPAND | wxALL, 0);
wxBoxSizer *bSizer_status_below = new wxBoxSizer(wxHORIZONTAL);
auto m_panel_separotor_left = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
m_panel_separotor_left->SetBackgroundColour(STATUS_PANEL_BG);
m_panel_separotor_left->SetMinSize(wxSize(PAGE_SPACING, -1));
bSizer_status_below->Add(m_panel_separotor_left, 0, wxEXPAND | wxALL, 0);
wxBoxSizer *bSizer_left = new wxBoxSizer(wxVERTICAL);
auto m_monitoring_sizer = create_monitoring_page();
bSizer_left->Add(m_monitoring_sizer, 1, wxEXPAND | wxALL, 0);
auto m_panel_separotor1 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
m_panel_separotor1->SetBackgroundColour(STATUS_PANEL_BG);
m_panel_separotor1->SetMinSize(wxSize(-1, PAGE_SPACING));
m_panel_separotor1->SetMaxSize(wxSize(-1, PAGE_SPACING));
m_monitoring_sizer->Add(m_panel_separotor1, 0, wxEXPAND, 0);
m_project_task_panel = new PrintingTaskPanel(this, PrintingTaskType::PRINGINT);
m_project_task_panel->init_bitmaps();
m_monitoring_sizer->Add(m_project_task_panel, 0, wxALL | wxEXPAND , 0);
// auto m_panel_separotor2 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
// m_panel_separotor2->SetBackgroundColour(STATUS_PANEL_BG);
// m_panel_separotor2->SetMinSize(wxSize(-1, PAGE_SPACING));
// bSizer_left->Add(m_panel_separotor2, 1, wxEXPAND, 0);
bSizer_status_below->Add(bSizer_left, 1, wxALL | wxEXPAND, 0);
auto m_panel_separator_middle = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE | wxTAB_TRAVERSAL);
m_panel_separator_middle->SetBackgroundColour(STATUS_PANEL_BG);
m_panel_separator_middle->SetMinSize(wxSize(PAGE_SPACING, -1));
bSizer_status_below->Add(m_panel_separator_middle, 0, wxEXPAND | wxALL, 0);
m_machine_ctrl_panel = new wxPanel(this);
m_machine_ctrl_panel->SetBackgroundColour(*wxWHITE);
m_machine_ctrl_panel->SetDoubleBuffered(true);
auto m_machine_control = create_machine_control_page(m_machine_ctrl_panel);
m_machine_ctrl_panel->SetSizer(m_machine_control);
m_machine_ctrl_panel->Layout();
m_machine_control->Fit(m_machine_ctrl_panel);
bSizer_status_below->Add(m_machine_ctrl_panel, 0, wxALL, 0);
m_panel_separator_right = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(PAGE_SPACING, -1), wxTAB_TRAVERSAL);
m_panel_separator_right->SetBackgroundColour(STATUS_PANEL_BG);
bSizer_status_below->Add(m_panel_separator_right, 0, wxEXPAND | wxALL, 0);
bSizer_status->Add(bSizer_status_below, 1, wxALL | wxEXPAND, 0);
m_panel_separotor_bottom = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, PAGE_SPACING), wxTAB_TRAVERSAL);
m_panel_separotor_bottom->SetBackgroundColour(STATUS_PANEL_BG);
bSizer_status->Add(m_panel_separotor_bottom, 0, wxEXPAND | wxALL, 0);
this->SetSizerAndFit(bSizer_status);
this->Layout();
}
StatusBasePanel::~StatusBasePanel()
{
delete m_media_play_ctrl;
if (m_custom_camera_view) {
delete m_custom_camera_view;
m_custom_camera_view = nullptr;
}
}
void StatusBasePanel::init_bitmaps()
{
static Slic3r::GUI::BitmapCache cache;
m_bitmap_item_prediction = create_scaled_bitmap("monitor_item_prediction", nullptr, 16);
m_bitmap_item_cost = create_scaled_bitmap("monitor_item_cost", nullptr, 16);
m_bitmap_item_print = create_scaled_bitmap("monitor_item_print", nullptr, 18);
m_bitmap_axis_home = ScalableBitmap(this, "monitor_axis_home", 32);
m_bitmap_lamp_on = ScalableBitmap(this, "monitor_lamp_on", 24);
m_bitmap_lamp_off = ScalableBitmap(this, "monitor_lamp_off", 24);
m_bitmap_fan_on = ScalableBitmap(this, "monitor_fan_on", 22);
m_bitmap_fan_off = ScalableBitmap(this, "monitor_fan_off", 22);
m_bitmap_speed = ScalableBitmap(this, "monitor_speed", 24);
m_bitmap_speed_active = ScalableBitmap(this, "monitor_speed_active", 24);
m_thumbnail_brokenimg = ScalableBitmap(this, "monitor_brokenimg", 120);
m_thumbnail_sdcard = ScalableBitmap(this, "monitor_sdcard_thumbnail", 120);
//m_bitmap_camera = create_scaled_bitmap("monitor_camera", nullptr, 18);
m_bitmap_extruder_empty_load = *cache.load_png("monitor_extruder_empty_load", FromDIP(28), FromDIP(70), false, false);
m_bitmap_extruder_filled_load = *cache.load_png("monitor_extruder_filled_load", FromDIP(28), FromDIP(70), false, false);
m_bitmap_extruder_empty_unload = *cache.load_png("monitor_extruder_empty_unload", FromDIP(28), FromDIP(70), false, false);
m_bitmap_extruder_filled_unload = *cache.load_png("monitor_extruder_filled_unload", FromDIP(28), FromDIP(70), false, false);
m_bitmap_sdcard_state_abnormal = ScalableBitmap(this, wxGetApp().dark_mode() ? "sdcard_state_abnormal_dark" : "sdcard_state_abnormal", 20);
m_bitmap_sdcard_state_normal = ScalableBitmap(this, wxGetApp().dark_mode() ? "sdcard_state_normal_dark" : "sdcard_state_normal", 20);
m_bitmap_sdcard_state_no = ScalableBitmap(this, wxGetApp().dark_mode() ? "sdcard_state_no_dark" : "sdcard_state_no", 20);
m_bitmap_recording_on = ScalableBitmap(this, wxGetApp().dark_mode() ? "monitor_recording_on_dark" : "monitor_recording_on", 20);
m_bitmap_recording_off = ScalableBitmap(this, wxGetApp().dark_mode() ? "monitor_recording_off_dark" : "monitor_recording_off", 20);
m_bitmap_timelapse_on = ScalableBitmap(this, wxGetApp().dark_mode() ? "monitor_timelapse_on_dark" : "monitor_timelapse_on", 20);
m_bitmap_timelapse_off = ScalableBitmap(this, wxGetApp().dark_mode() ? "monitor_timelapse_off_dark" : "monitor_timelapse_off", 20);
m_bitmap_vcamera_on = ScalableBitmap(this, wxGetApp().dark_mode() ? "monitor_vcamera_on_dark" : "monitor_vcamera_on", 20);
m_bitmap_vcamera_off = ScalableBitmap(this, wxGetApp().dark_mode() ? "monitor_vcamera_off_dark" : "monitor_vcamera_off", 20);
m_bitmap_switch_camera = ScalableBitmap(this, wxGetApp().dark_mode() ? "camera_switch_dark" : "camera_switch", 20);
}
wxBoxSizer *StatusBasePanel::create_monitoring_page()
{
wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
m_panel_monitoring_title = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, PAGE_TITLE_HEIGHT), wxTAB_TRAVERSAL);
m_panel_monitoring_title->SetBackgroundColour(STATUS_TITLE_BG);
wxBoxSizer *bSizer_monitoring_title;
bSizer_monitoring_title = new wxBoxSizer(wxHORIZONTAL);
m_staticText_monitoring = new Label(m_panel_monitoring_title, _L("Camera"));
m_staticText_monitoring->Wrap(-1);
//m_staticText_monitoring->SetFont(PAGE_TITLE_FONT);
m_staticText_monitoring->SetForegroundColour(PAGE_TITLE_FONT_COL);
bSizer_monitoring_title->Add(m_staticText_monitoring, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, PAGE_TITLE_LEFT_MARGIN);
bSizer_monitoring_title->Add(FromDIP(13), 0, 0, 0);
bSizer_monitoring_title->AddStretchSpacer();
m_staticText_timelapse = new wxStaticText(m_panel_monitoring_title, wxID_ANY, _L("Timelapse"), wxDefaultPosition, wxDefaultSize, 0);
m_staticText_timelapse->Wrap(-1);
m_staticText_timelapse->Hide();
bSizer_monitoring_title->Add(m_staticText_timelapse, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
m_mqtt_source = new wxStaticText(m_panel_monitoring_title, wxID_ANY, "MqttSource", wxDefaultPosition, wxDefaultSize, 0);
m_mqtt_source->Wrap(-1);
m_mqtt_source->Hide();
bSizer_monitoring_title->Add(m_mqtt_source, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
m_bmToggleBtn_timelapse = new SwitchButton(m_panel_monitoring_title);
m_bmToggleBtn_timelapse->SetMinSize(SWITCH_BUTTON_SIZE);
m_bmToggleBtn_timelapse->Hide();
bSizer_monitoring_title->Add(m_bmToggleBtn_timelapse, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
#if !BBL_RELEASE_TO_PUBLIC
m_staticText_timelapse->Show();
m_bmToggleBtn_timelapse->Show();
m_bmToggleBtn_timelapse->Bind(wxEVT_TOGGLEBUTTON, [](wxCommandEvent &e) {
if (e.IsChecked())
wxGetApp().getAgent()->start_subscribe("tunnel");
else
wxGetApp().getAgent()->stop_subscribe("tunnel");
});
#endif
//m_bitmap_camera_img = new wxStaticBitmap(m_panel_monitoring_title, wxID_ANY, m_bitmap_camera , wxDefaultPosition, wxSize(FromDIP(32), FromDIP(18)), 0);
//m_bitmap_camera_img->SetMinSize(wxSize(FromDIP(32), FromDIP(18)));
//bSizer_monitoring_title->Add(m_bitmap_camera_img, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
m_bitmap_sdcard_img = new wxStaticBitmap(m_panel_monitoring_title, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize(FromDIP(38), FromDIP(24)), 0);
m_bitmap_sdcard_img->SetMinSize(wxSize(FromDIP(38), FromDIP(24)));
m_bitmap_timelapse_img = new wxStaticBitmap(m_panel_monitoring_title, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize(FromDIP(38), FromDIP(24)), 0);
m_bitmap_timelapse_img->SetMinSize(wxSize(FromDIP(38), FromDIP(24)));
m_bitmap_timelapse_img->Hide();
m_bitmap_recording_img = new wxStaticBitmap(m_panel_monitoring_title, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize(FromDIP(38), FromDIP(24)), 0);
m_bitmap_recording_img->SetMinSize(wxSize(FromDIP(38), FromDIP(24)));
m_bitmap_timelapse_img->Hide();
m_bitmap_vcamera_img = new wxStaticBitmap(m_panel_monitoring_title, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize(FromDIP(38), FromDIP(24)), 0);
m_bitmap_vcamera_img->SetMinSize(wxSize(FromDIP(38), FromDIP(24)));
m_bitmap_vcamera_img->Hide();
m_setting_button = new CameraItem(m_panel_monitoring_title, "camera_setting", "camera_setting_hover");
m_setting_button->SetMinSize(wxSize(FromDIP(38), FromDIP(24)));
m_setting_button->SetBackgroundColour(STATUS_TITLE_BG);
m_camera_switch_button = new wxStaticBitmap(m_panel_monitoring_title, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize(FromDIP(38), FromDIP(24)), 0);
m_camera_switch_button->SetMinSize(wxSize(FromDIP(38), FromDIP(24)));
m_camera_switch_button->SetBackgroundColour(STATUS_TITLE_BG);
m_camera_switch_button->SetBitmap(m_bitmap_switch_camera.bmp());
m_camera_switch_button->Bind(wxEVT_LEFT_DOWN, &StatusBasePanel::on_camera_switch_toggled, this);
m_camera_switch_button->Bind(wxEVT_RIGHT_DOWN, [this](auto& e) {
const std::string js_request_pip = R"(
document.querySelector('video').requestPictureInPicture();
)";
m_custom_camera_view->RunScript(js_request_pip);
});
m_camera_switch_button->Hide();
m_bitmap_sdcard_img->SetToolTip(_L("Storage"));
m_bitmap_timelapse_img->SetToolTip(_L("Timelapse"));
m_bitmap_recording_img->SetToolTip(_L("Video"));
m_bitmap_vcamera_img->SetToolTip(_L("Go Live"));
m_setting_button->SetToolTip(_L("Camera Setting"));
m_camera_switch_button->SetToolTip(_L("Switch Camera View"));
bSizer_monitoring_title->Add(m_camera_switch_button, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
bSizer_monitoring_title->Add(m_bitmap_sdcard_img, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
bSizer_monitoring_title->Add(m_bitmap_timelapse_img, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
bSizer_monitoring_title->Add(m_bitmap_recording_img, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
bSizer_monitoring_title->Add(m_bitmap_vcamera_img, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
bSizer_monitoring_title->Add(m_setting_button, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
bSizer_monitoring_title->Add(FromDIP(13), 0, 0);
m_panel_monitoring_title->SetSizer(bSizer_monitoring_title);
m_panel_monitoring_title->Layout();
bSizer_monitoring_title->Fit(m_panel_monitoring_title);
sizer->Add(m_panel_monitoring_title, 0, wxEXPAND | wxALL, 0);
// media_ctrl_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize);
// media_ctrl_panel->SetBackgroundColour(*wxBLACK);
// wxBoxSizer *bSizer_monitoring = new wxBoxSizer(wxVERTICAL);
m_media_ctrl = new wxMediaCtrl3(this);
m_media_ctrl->SetMinSize(wxSize(PAGE_MIN_WIDTH, FromDIP(288)));
m_custom_camera_view = WebView::CreateWebView(this, wxEmptyString);
m_custom_camera_view->EnableContextMenu(false);
Bind(wxEVT_WEBVIEW_NAVIGATING, &StatusBasePanel::on_webview_navigating, this, m_custom_camera_view->GetId());
m_media_play_ctrl = new MediaPlayCtrl(this, m_media_ctrl, wxDefaultPosition, wxSize(-1, FromDIP(40)));
m_custom_camera_view->Hide();
m_custom_camera_view->Bind(wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, [this](wxWebViewEvent& evt) {
if (evt.GetString() == "leavepictureinpicture") {
// When leaving PiP, video gets paused in some cases and toggling play
// programmatically does not work.
m_custom_camera_view->Reload();
}
else if (evt.GetString() == "enterpictureinpicture") {
toggle_builtin_camera();
}
});
sizer->Add(m_media_ctrl, 1, wxEXPAND | wxALL, 0);
sizer->Add(m_custom_camera_view, 1, wxEXPAND | wxALL, 0);
sizer->Add(m_media_play_ctrl, 0, wxEXPAND | wxALL, 0);
// media_ctrl_panel->SetSizer(bSizer_monitoring);
// media_ctrl_panel->Layout();
//
// sizer->Add(media_ctrl_panel, 1, wxEXPAND | wxALL, 1);
if (wxGetApp().app_config->get("camera", "enable_custom_source") == "true") {
handle_camera_source_change();
}
return sizer;
}
void StatusBasePanel::on_webview_navigating(wxWebViewEvent& evt) {
wxGetApp().CallAfter([this] {
remove_controls();
});
}
wxBoxSizer *StatusBasePanel::create_machine_control_page(wxWindow *parent)
{
wxBoxSizer *bSizer_right = new wxBoxSizer(wxVERTICAL);
m_panel_control_title = new wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(-1, PAGE_TITLE_HEIGHT), wxTAB_TRAVERSAL);
m_panel_control_title->SetBackgroundColour(STATUS_TITLE_BG);
wxBoxSizer *bSizer_control_title = new wxBoxSizer(wxHORIZONTAL);
m_staticText_control = new Label(m_panel_control_title,_L("Control"));
m_staticText_control->Wrap(-1);
//m_staticText_control->SetFont(PAGE_TITLE_FONT);
m_staticText_control->SetForegroundColour(PAGE_TITLE_FONT_COL);
m_parts_btn = new Button(m_panel_control_title, _L("Printer Parts"));
m_parts_btn->SetStyle(ButtonStyle::Confirm, ButtonType::Window);
m_options_btn = new Button(m_panel_control_title, _L("Print Options"));
m_options_btn->SetStyle(ButtonStyle::Confirm, ButtonType::Window);
m_safety_btn = new Button(m_panel_control_title, _L("Safety Options"));
m_safety_btn->SetStyle(ButtonStyle::Confirm, ButtonType::Window);
m_calibration_btn = new Button(m_panel_control_title, _L("Calibration"));
m_calibration_btn->SetStyle(ButtonStyle::Confirm, ButtonType::Window);
m_calibration_btn->EnableTooltipEvenDisabled();
m_options_btn->Hide();
m_safety_btn->Hide();
bSizer_control_title->Add(m_staticText_control, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, PAGE_TITLE_LEFT_MARGIN);
bSizer_control_title->Add(0, 0, 1, wxEXPAND, 0);
bSizer_control_title->Add(m_parts_btn, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(10));
bSizer_control_title->Add(m_options_btn, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(10));
bSizer_control_title->Add(m_safety_btn, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(10));
bSizer_control_title->Add(m_calibration_btn, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(10));
m_panel_control_title->SetSizer(bSizer_control_title);
m_panel_control_title->Layout();
bSizer_control_title->Fit(m_panel_control_title);
bSizer_right->Add(m_panel_control_title, 0, wxALL | wxEXPAND, 0);
wxBoxSizer *bSizer_control = new wxBoxSizer(wxVERTICAL);
auto temp_axis_ctrl_sizer = create_temp_axis_group(parent);
auto m_filament_load_sizer = create_filament_group(parent);
/* ams control box or live nozzle-rack panel (rack printers switch between the two) */
wxSizer *ams_rack_sizer = new wxBoxSizer(wxHORIZONTAL);
ams_rack_sizer->Add(create_ams_group(parent), 0, wxEXPAND | wxLEFT);
m_panel_nozzle_rack = new wgtDeviceNozzleRack(parent);
m_panel_nozzle_rack->Show(false);
ams_rack_sizer->Add(m_panel_nozzle_rack, 0, wxEXPAND | wxLEFT);
m_ams_rack_switch = new SwitchBoard(parent, _L("Filament"), _L("Hotends"), wxSize(FromDIP(126), FromDIP(26)));
m_ams_rack_switch->updateState("left");
m_ams_rack_switch->Hide();
m_ams_rack_switch->Bind(wxCUSTOMEVT_SWITCH_POS, &StatusBasePanel::on_ams_rack_switch, this);
bSizer_control->Add(0, 0, 0, wxTOP, FromDIP(8));
bSizer_control->Add(temp_axis_ctrl_sizer, 0, wxALIGN_CENTER|wxLEFT|wxRIGHT, FromDIP(8));
bSizer_control->Add(m_ams_rack_switch, 0, wxALIGN_CENTRE|wxTOP, FromDIP(6));
bSizer_control->Add(0, 0, 0, wxTOP, FromDIP(6));
bSizer_control->Add(ams_rack_sizer, 0, wxALIGN_CENTER|wxLEFT|wxRIGHT, FromDIP(8));
bSizer_control->Add(0, 0, 0, wxTOP, FromDIP(6));
bSizer_control->Add(m_filament_load_sizer, 0, wxALIGN_CENTER|wxLEFT|wxRIGHT, FromDIP(8));
bSizer_control->Add(0, 0, 0, wxTOP, FromDIP(4));
bSizer_right->Add(bSizer_control, 1, wxEXPAND | wxALL, 0);
return bSizer_right;
}
wxBoxSizer *StatusBasePanel::create_temp_axis_group(wxWindow *parent)
{
auto sizer = new wxBoxSizer(wxVERTICAL);
auto box = new StaticBox(parent);
StateColor box_colour(std::pair<wxColour, int>(*wxWHITE, StateColor::Normal));
StateColor box_border_colour(std::pair<wxColour, int>(STATUS_PANEL_BG, StateColor::Normal));
box->SetBackgroundColor(box_colour);
box->SetBorderColor(box_border_colour);
box->SetCornerRadius(5);
box->SetMinSize(wxSize(FromDIP(586), -1));
box->SetMaxSize(wxSize(FromDIP(586), -1));
wxBoxSizer *content_sizer = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *m_temp_ctrl = create_temp_control(box);
m_temp_temp_line = new wxPanel(box);
m_temp_temp_line->SetMaxSize(wxSize(FromDIP(1), -1));
m_temp_temp_line->SetMinSize(wxSize(FromDIP(1), -1));
m_temp_temp_line->SetBackgroundColour(STATIC_BOX_LINE_COL);
auto m_axis_sizer = create_axis_control(box);
auto bedPanel = create_bed_control(box);
wxBoxSizer *extruder_sizer = create_extruder_control(box);
wxBoxSizer* axis_and_bed_control_sizer = new wxBoxSizer(wxVERTICAL);
axis_and_bed_control_sizer->Add(m_axis_sizer, 0, wxEXPAND | wxALL, 0);
axis_and_bed_control_sizer->Add(bedPanel, 0, wxALIGN_CENTER, 0);
content_sizer->Add(m_temp_ctrl, 0, wxEXPAND | wxALL, FromDIP(5));
content_sizer->Add(m_temp_temp_line, 0, wxEXPAND, 1);
//content_sizer->Add(FromDIP(9), 0, 0, wxEXPAND, 1);
/*content_sizer->Add(0, 0, 0, wxLEFT, FromDIP(18));
content_sizer->Add(m_axis_sizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
content_sizer->Add(0, 0, 0, wxLEFT, FromDIP(18));
content_sizer->Add(bed_sizer, 0, wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, FromDIP(12));*/
content_sizer->Add(axis_and_bed_control_sizer, 1, wxALIGN_CENTER, 0);
//content_sizer->Add(0, 0, 0, wxLEFT, FromDIP(18));
m_temp_extruder_line = new wxPanel(box);
m_temp_extruder_line->SetMaxSize(wxSize(FromDIP(1), -1));
m_temp_extruder_line->SetMinSize(wxSize(FromDIP(1), -1));
m_temp_extruder_line->SetBackgroundColour(STATIC_BOX_LINE_COL);
content_sizer->Add(m_temp_extruder_line, 0, wxEXPAND, 1);
content_sizer->Add(extruder_sizer, 0, wxEXPAND | wxTOP | wxBOTTOM, FromDIP(12));
content_sizer->Add(0, 0, 0, wxRIGHT, FromDIP(3));
box->SetSizer(content_sizer);
sizer->Add(box, 0, wxEXPAND | wxALL, FromDIP(9));
return sizer;
}
wxBoxSizer *StatusBasePanel::create_temp_control(wxWindow *parent)
{
auto sizer = new wxBoxSizer(wxVERTICAL);
wxWindowID nozzle_id = wxWindow::NewControlId();
m_tempCtrl_nozzle = new TempInput(parent, nozzle_id, TEMP_BLANK_STR, TempInputType::TEMP_OF_NORMAL_TYPE, TEMP_BLANK_STR, wxString("monitor_nozzle_temp"),
wxString("monitor_nozzle_temp_active"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER);
m_tempCtrl_nozzle->SetMinSize(TEMP_CTRL_MIN_SIZE_ALIGN_TWO_ICON);
m_tempCtrl_nozzle->AddTemp(0); // zero is default temp
m_tempCtrl_nozzle->SetMinTemp(20);
m_tempCtrl_nozzle->SetMaxTemp(300);
m_tempCtrl_nozzle->SetBorderWidth(FromDIP(2));
StateColor tempinput_text_colour(std::make_pair(DISCONNECT_TEXT_COL, (int) StateColor::Disabled), std::make_pair(NORMAL_TEXT_COL, (int) StateColor::Normal));
StateColor tempinput_border_colour(std::make_pair(*wxWHITE, (int)StateColor::Disabled), std::make_pair(BUTTON_HOVER_COL, (int)StateColor::Focused),
std::make_pair(BUTTON_HOVER_COL, (int)StateColor::Hovered), std::make_pair(*wxWHITE, (int)StateColor::Normal));
m_tempCtrl_nozzle->SetTextColor(tempinput_text_colour);
m_tempCtrl_nozzle->SetBorderColor(tempinput_border_colour);
m_tempCtrl_nozzle_deputy = new TempInput(parent, nozzle_id, TEMP_BLANK_STR, TempInputType::TEMP_OF_NORMAL_TYPE, TEMP_BLANK_STR, wxString("monitor_nozzle_temp"), wxString("monitor_nozzle_temp_active"),
wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER);
m_tempCtrl_nozzle_deputy->SetMinSize(TEMP_CTRL_MIN_SIZE_ALIGN_TWO_ICON);
m_tempCtrl_nozzle_deputy->AddTemp(0); // zero is default temp
m_tempCtrl_nozzle_deputy->SetMinTemp(20);
m_tempCtrl_nozzle_deputy->SetMaxTemp(300);
m_tempCtrl_nozzle_deputy->SetBorderWidth(FromDIP(2));
m_tempCtrl_nozzle_deputy->SetTextColor(tempinput_text_colour);
m_tempCtrl_nozzle_deputy->SetBorderColor(tempinput_border_colour);
sizer->Add(m_tempCtrl_nozzle_deputy, 0, wxEXPAND | wxALL, 1);
sizer->Add(m_tempCtrl_nozzle, 0, wxEXPAND | wxALL, 1);
m_tempCtrl_nozzle_deputy->Hide();
m_line_nozzle = new StaticLine(parent);
m_line_nozzle->SetLineColour(STATIC_BOX_LINE_COL);
m_line_nozzle->SetSize(wxSize(FromDIP(1), -1));
sizer->Add(m_line_nozzle, 0, wxEXPAND | wxLEFT | wxRIGHT, 12);
wxWindowID bed_id = wxWindow::NewControlId();
m_tempCtrl_bed = new TempInput(parent, bed_id, TEMP_BLANK_STR, TempInputType::TEMP_OF_NORMAL_TYPE, TEMP_BLANK_STR, wxString("monitor_bed_temp"),
wxString("monitor_bed_temp_active"), wxDefaultPosition,wxDefaultSize, wxALIGN_CENTER);
m_tempCtrl_bed->AddTemp(0); // zero is default temp
m_tempCtrl_bed->SetMinTemp(bed_temp_range[0]);
m_tempCtrl_bed->SetMaxTemp(bed_temp_range[1]);
m_tempCtrl_bed->SetMinSize(TEMP_CTRL_MIN_SIZE_ALIGN_ONE_ICON);
m_tempCtrl_bed->SetBorderWidth(FromDIP(2));
m_tempCtrl_bed->SetTextColor(tempinput_text_colour);
m_tempCtrl_bed->SetBorderColor(tempinput_border_colour);
sizer->Add(m_tempCtrl_bed, 0, wxEXPAND | wxALL, 1);
auto line = new StaticLine(parent);
line->SetLineColour(STATIC_BOX_LINE_COL);
sizer->Add(line, 0, wxEXPAND | wxLEFT | wxRIGHT, 12);
wxWindowID frame_id = wxWindow::NewControlId();
m_tempCtrl_chamber = new TempInput(parent, frame_id, TEMP_BLANK_STR, TempInputType::TEMP_OF_NORMAL_TYPE, TEMP_BLANK_STR, wxString("monitor_frame_temp"),
wxString("monitor_frame_temp_active"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER);
m_tempCtrl_chamber->AddTemp(0); // zero is default temp
m_tempCtrl_chamber->SetReadOnly(true);
m_tempCtrl_chamber->SetMinTemp(default_champer_temp_min);
m_tempCtrl_chamber->SetMaxTemp(default_champer_temp_max);
m_tempCtrl_chamber->SetMinSize(TEMP_CTRL_MIN_SIZE_ALIGN_ONE_ICON);
m_tempCtrl_chamber->SetBorderWidth(FromDIP(2));
m_tempCtrl_chamber->SetTextColor(tempinput_text_colour);
m_tempCtrl_chamber->SetBorderColor(tempinput_border_colour);
sizer->Add(m_tempCtrl_chamber, 0, wxEXPAND | wxALL, 1);
m_misc_ctrl_sizer = create_misc_control(parent);
sizer->Add(m_misc_ctrl_sizer, 0, wxEXPAND, 0);
return sizer;
}
wxBoxSizer *StatusBasePanel::create_misc_control(wxWindow *parent)
{
wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *line_sizer = new wxBoxSizer(wxHORIZONTAL);
/* create speed control */
m_switch_speed = new ImageSwitchButton(parent, m_bitmap_speed_active, m_bitmap_speed);
m_switch_speed->SetLabels("100%", "100%");
m_switch_speed->SetMinSize(MISC_BUTTON_2FAN_SIZE);
m_switch_speed->SetMaxSize(MISC_BUTTON_2FAN_SIZE);
m_switch_speed->SetPadding(FromDIP(3));
m_switch_speed->SetBorderWidth(FromDIP(2));
m_switch_speed->SetFont(Label::Head_13);
m_switch_speed->SetTextColor(StateColor(std::make_pair(DISCONNECT_TEXT_COL, (int) StateColor::Disabled), std::make_pair(NORMAL_TEXT_COL, (int) StateColor::Normal)));
m_switch_speed->SetValue(false);
line_sizer->Add(m_switch_speed, 1, wxALIGN_CENTER | wxALL, 0);
auto line = new StaticLine(parent, true);
line->SetLineColour(STATIC_BOX_LINE_COL);
line_sizer->Add(line, 0, wxEXPAND | wxTOP | wxBOTTOM, 4);
/* create lamp control */
m_switch_lamp = new ImageSwitchButton(parent, m_bitmap_lamp_on, m_bitmap_lamp_off);
m_switch_lamp->SetLabels(_L("Lamp"), _L("Lamp"));
m_switch_lamp->SetMinSize(MISC_BUTTON_2FAN_SIZE);
m_switch_lamp->SetMaxSize(MISC_BUTTON_2FAN_SIZE);
m_switch_lamp->SetPadding(FromDIP(3));
m_switch_lamp->SetBorderWidth(FromDIP(2));
m_switch_lamp->SetFont(Label::Head_13);
m_switch_lamp->SetTextColor(StateColor(std::make_pair(DISCONNECT_TEXT_COL, (int) StateColor::Disabled), std::make_pair(NORMAL_TEXT_COL, (int) StateColor::Normal)));
line_sizer->Add(m_switch_lamp, 1, wxALIGN_CENTER | wxALL, 0);
//sizer->Add(line_sizer, 0, wxEXPAND, FromDIP(5));
line = new StaticLine(parent);
line->SetLineColour(STATIC_BOX_LINE_COL);
sizer->Add(line, 0, wxEXPAND | wxLEFT | wxRIGHT, 12);
m_fan_panel = new StaticBox(parent);
m_fan_panel->SetMinSize(MISC_BUTTON_PANEL_SIZE);
m_fan_panel->SetMaxSize(MISC_BUTTON_PANEL_SIZE);
m_fan_panel->SetBackgroundColor(*wxWHITE);
m_fan_panel->SetBorderWidth(0);
m_fan_panel->SetCornerRadius(0);
auto fan_line_sizer = new wxBoxSizer(wxHORIZONTAL);
m_switch_fan = new FanSwitchButton(m_fan_panel, m_bitmap_fan_on, m_bitmap_fan_off);
m_switch_fan->SetValue(false);
m_switch_fan->SetMinSize(MISC_BUTTON_1FAN_SIZE);
m_switch_fan->SetMaxSize(MISC_BUTTON_1FAN_SIZE);
m_switch_fan->SetPadding(FromDIP(1));
m_switch_fan->SetBorderWidth(0);
m_switch_fan->SetCornerRadius(0);
m_switch_fan->SetFont(::Label::Body_10);
m_switch_fan->UseTextFan();
m_switch_fan->SetTextColor(
StateColor(std::make_pair(DISCONNECT_TEXT_COL, (int)StateColor::Disabled), std::make_pair(NORMAL_FAN_TEXT_COL, (int)StateColor::Normal)));
m_switch_fan->Bind(wxEVT_ENTER_WINDOW, [this](auto& e) {
m_fan_panel->SetBackgroundColor(wxColour(0, 150, 136));
});
m_switch_fan->Bind(wxEVT_LEAVE_WINDOW, [this, parent](auto& e) {
m_fan_panel->SetBackgroundColor(parent->GetBackgroundColour());
});
fan_line_sizer->Add(m_switch_fan, 1, wxEXPAND|wxALL, FromDIP(2));
m_fan_panel->SetSizer(fan_line_sizer);
m_fan_panel->Layout();
m_fan_panel->Fit();
sizer->Add(m_fan_panel, 0, wxEXPAND, FromDIP(5));
line = new StaticLine(parent);
line->SetLineColour(STATIC_BOX_LINE_COL);
sizer->Add(line, 0, wxEXPAND | wxLEFT | wxRIGHT, 12);
sizer->Add(line_sizer, 0, wxEXPAND, FromDIP(5));
return sizer;
}
void StatusBasePanel::reset_temp_misc_control()
{
// reset temp string
m_tempCtrl_nozzle->SetIconNormal();
m_tempCtrl_nozzle->SetLabel(TEMP_BLANK_STR);
m_tempCtrl_nozzle->GetTextCtrl()->SetValue(TEMP_BLANK_STR);
m_tempCtrl_nozzle_deputy->SetIconNormal();
m_tempCtrl_nozzle_deputy->SetLabel(TEMP_BLANK_STR);
m_tempCtrl_nozzle_deputy->GetTextCtrl()->SetValue(TEMP_BLANK_STR);
m_tempCtrl_bed->SetIconNormal();
m_tempCtrl_bed->SetLabel(TEMP_BLANK_STR);
m_tempCtrl_bed->GetTextCtrl()->SetValue(TEMP_BLANK_STR);
m_tempCtrl_chamber->SetIconNormal();
m_tempCtrl_chamber->SetLabel(TEMP_BLANK_STR);
m_tempCtrl_chamber->GetTextCtrl()->SetValue(TEMP_BLANK_STR);
m_tempCtrl_nozzle->Enable(true);
m_tempCtrl_nozzle_deputy->Enable(true);
m_tempCtrl_chamber->Enable(true);
m_tempCtrl_bed->Enable(true);
// reset misc control
m_switch_speed->SetLabels("100%", "100%");
m_switch_speed->SetValue(false);
m_switch_lamp->SetLabels(_L("Lamp"), _L("Lamp"));
m_switch_lamp->SetValue(false);
/*m_switch_nozzle_fan->SetValue(false);
m_switch_printing_fan->SetValue(false);
m_switch_cham_fan->SetValue(false);*/
}
wxBoxSizer *StatusBasePanel::create_axis_control(wxWindow *parent)
{
auto sizer = new wxBoxSizer(wxVERTICAL);
sizer->AddStretchSpacer();
m_bpButton_xy = new AxisCtrlButton(parent, m_bitmap_axis_home);
m_bpButton_xy->SetTextColor(StateColor(std::make_pair(DISCONNECT_TEXT_COL, (int) StateColor::Disabled), std::make_pair(NORMAL_TEXT_COL, (int) StateColor::Normal)));
m_bpButton_xy->SetMinSize(AXIS_MIN_SIZE);
m_bpButton_xy->SetSize(AXIS_MIN_SIZE);
sizer->AddStretchSpacer();
sizer->Add(m_bpButton_xy, 0, wxALIGN_CENTER | wxALL, 0);
sizer->AddStretchSpacer();
return sizer;
}
wxPanel *StatusBasePanel::create_bed_control(wxWindow *parent)
{
wxBoxSizer *bSizer_z_ctrl = new wxBoxSizer(wxHORIZONTAL);
auto panel = new wxPanel(parent, wxID_ANY);
panel->SetBackgroundColour(*wxWHITE);
StateColor z_10_ctrl_bg(std::pair<wxColour, int>(BUTTON_PRESS_COL, StateColor::Pressed), std::pair<wxColour, int>(BUTTON_NORMAL1_COL, StateColor::Normal));
StateColor z_10_ctrl_bd(std::pair<wxColour, int>(BUTTON_HOVER_COL, StateColor::Hovered), std::pair<wxColour, int>(BUTTON_NORMAL1_COL, StateColor::Normal));
StateColor z_1_ctrl_bg(std::pair<wxColour, int>(BUTTON_PRESS_COL, StateColor::Pressed), std::pair<wxColour, int>(BUTTON_NORMAL2_COL, StateColor::Normal));
StateColor z_1_ctrl_bd(std::pair<wxColour, int>(BUTTON_HOVER_COL, StateColor::Hovered), std::pair<wxColour, int>(BUTTON_NORMAL2_COL, StateColor::Normal));
m_bpButton_z_10 = new Button(panel, wxString("10"), "monitor_bed_up", 0, 15); // Orca Dont scale icon size
m_bpButton_z_10->SetFont(::Label::Body_12);
m_bpButton_z_10->SetBorderWidth(0);
m_bpButton_z_10->SetBackgroundColor(z_10_ctrl_bg);
m_bpButton_z_10->SetBorderColor(z_10_ctrl_bd);
m_bpButton_z_10->SetTextColor(StateColor(std::make_pair(DISCONNECT_TEXT_COL, (int) StateColor::Disabled), std::make_pair(NORMAL_TEXT_COL, (int) StateColor::Normal)));
m_bpButton_z_10->SetMinSize(Z_BUTTON_SIZE);
m_bpButton_z_10->SetSize(Z_BUTTON_SIZE);
m_bpButton_z_10->SetCornerRadius(0);
m_bpButton_z_1 = new Button(panel, wxString(" 1"), "monitor_bed_up", 0, 15); // Orca Dont scale icon size
m_bpButton_z_1->SetFont(::Label::Body_12);
m_bpButton_z_1->SetBorderWidth(0);
m_bpButton_z_1->SetBackgroundColor(z_1_ctrl_bg);
m_bpButton_z_1->SetBorderColor(z_1_ctrl_bd);
m_bpButton_z_1->SetMinSize(Z_BUTTON_SIZE);
m_bpButton_z_1->SetSize(Z_BUTTON_SIZE);
m_bpButton_z_1->SetTextColor(StateColor(std::make_pair(DISCONNECT_TEXT_COL, (int) StateColor::Disabled), std::make_pair(NORMAL_TEXT_COL, (int) StateColor::Normal)));
//bSizer_z_ctrl->Add(0, FromDIP(6), 0, wxEXPAND, 0);
m_staticText_z_tip = new wxStaticText(panel, wxID_ANY, _L("Bed"), wxDefaultPosition, wxDefaultSize, 0);
m_staticText_z_tip->SetFont(::Label::Body_12);
if (wxGetApp().app_config->get("language") == "de_DE") m_staticText_z_tip->SetFont(::Label::Body_11);
m_staticText_z_tip->Wrap(-1);
m_staticText_z_tip->SetForegroundColour(TEXT_LIGHT_FONT_COL);
m_bpButton_z_down_1 = new Button(panel, wxString(" 1"), "monitor_bed_down", 0, 15); // Orca Dont scale icon size
m_bpButton_z_down_1->SetFont(::Label::Body_12);
m_bpButton_z_down_1->SetBorderWidth(0);
m_bpButton_z_down_1->SetBackgroundColor(z_1_ctrl_bg);
m_bpButton_z_down_1->SetBorderColor(z_1_ctrl_bd);
m_bpButton_z_down_1->SetMinSize(Z_BUTTON_SIZE);
m_bpButton_z_down_1->SetSize(Z_BUTTON_SIZE);
m_bpButton_z_down_1->SetTextColor(StateColor(std::make_pair(DISCONNECT_TEXT_COL, (int) StateColor::Disabled), std::make_pair(NORMAL_TEXT_COL, (int) StateColor::Normal)));
m_bpButton_z_down_10 = new Button(panel, wxString("10"), "monitor_bed_down", 0, 15); // Orca Dont scale icon size
m_bpButton_z_down_10->SetFont(::Label::Body_12);
m_bpButton_z_down_10->SetBorderWidth(0);
m_bpButton_z_down_10->SetBackgroundColor(z_10_ctrl_bg);
m_bpButton_z_down_10->SetBorderColor(z_10_ctrl_bd);
m_bpButton_z_down_10->SetMinSize(Z_BUTTON_SIZE);
m_bpButton_z_down_10->SetSize(Z_BUTTON_SIZE);
m_bpButton_z_down_10->SetTextColor(StateColor(std::make_pair(DISCONNECT_TEXT_COL, (int) StateColor::Disabled), std::make_pair(NORMAL_TEXT_COL, (int) StateColor::Normal)));
bSizer_z_ctrl->Add(m_bpButton_z_10, 0, wxEXPAND | wxLEFT | wxRIGHT, 0);
bSizer_z_ctrl->Add(m_bpButton_z_1, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(2));
bSizer_z_ctrl->Add(m_staticText_z_tip, 0, wxALIGN_CENTRE, FromDIP(5));
bSizer_z_ctrl->Add(m_bpButton_z_down_1, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(2));
bSizer_z_ctrl->Add(m_bpButton_z_down_10, 0, wxEXPAND | wxLEFT | wxRIGHT, 0);
panel->SetSizer(bSizer_z_ctrl);
panel->Layout();
panel->Fit();
return panel;
}
wxBoxSizer *StatusBasePanel::create_extruder_control(wxWindow *parent)
{
wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *bSizer_e_ctrl = new wxBoxSizer(wxVERTICAL);
auto panel = new wxPanel(parent,wxID_ANY);
panel->SetBackgroundColour(*wxWHITE);
panel->SetSize(wxSize(FromDIP(143), -1));
panel->SetMinSize(wxSize(FromDIP(143), -1));
panel->SetMaxSize(wxSize(FromDIP(143), -1));
StateColor e_ctrl_bg(std::pair<wxColour, int>(BUTTON_PRESS_COL, StateColor::Pressed), std::pair<wxColour, int>(BUTTON_NORMAL1_COL, StateColor::Normal));
StateColor e_ctrl_bd(std::pair<wxColour, int>(BUTTON_HOVER_COL, StateColor::Hovered), std::pair<wxColour, int>(BUTTON_NORMAL1_COL, StateColor::Normal));
m_nozzle_btn_panel = new SwitchBoard(panel, _L_CONTEXT("Left", "Nozzle position"), _L_CONTEXT("Right", "Nozzle position"), wxSize(FromDIP(126), FromDIP(26)));
m_nozzle_btn_panel->SetAutoDisableWhenSwitch();
m_bpButton_e_10 = new Button(panel, "", "monitor_extruder_up", 0, 22); // Orca Dont scale icon size
m_bpButton_e_10->SetBorderWidth(2);
m_bpButton_e_10->SetBackgroundColor(e_ctrl_bg);
m_bpButton_e_10->SetBorderColor(e_ctrl_bd);
m_bpButton_e_10->SetMinSize(wxSize(FromDIP(40), FromDIP(40)));
m_extruder_book = new wxSimplebook(panel, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(45), FromDIP(112)), 0);
m_extruder_book->InsertPage(0, new wxPanel(panel), "");
for (int nozzle_num = 1; nozzle_num <= 2; nozzle_num++) {
auto extruder_img = new ExtruderImage(m_extruder_book, wxID_ANY, nozzle_num);
m_extruder_book->InsertPage(nozzle_num, extruder_img, "");
m_extruderImage.push_back(extruder_img);
}
m_extruder_book->SetSelection(0);
m_bpButton_e_down_10 = new Button(panel, "", "monitor_extruder_down", 0, 22); // Orca Dont scale icon size
m_bpButton_e_down_10->SetBorderWidth(2);
m_bpButton_e_down_10->SetBackgroundColor(e_ctrl_bg);
m_bpButton_e_down_10->SetBorderColor(e_ctrl_bd);
m_bpButton_e_down_10->SetMinSize(wxSize(FromDIP(40), FromDIP(40)));
m_extruder_switching_status = new ExtruderSwithingStatus(panel);
m_extruder_switching_status->SetForegroundColour(TEXT_LIGHT_FONT_COL);
m_extruder_label = new ::Label(panel, _L("Extruder"));
m_extruder_label->SetFont(::Label::Body_13);
m_extruder_label->SetForegroundColour(TEXT_LIGHT_FONT_COL);
bSizer_e_ctrl->Add(0, 0, 0, wxTOP, FromDIP(15));
bSizer_e_ctrl->Add(m_nozzle_btn_panel, 0, wxALIGN_CENTER_HORIZONTAL, 0);
bSizer_e_ctrl->Add(0, 0, 0, wxTOP, FromDIP(15));
bSizer_e_ctrl->Add(m_bpButton_e_10, 0, wxALIGN_CENTER_HORIZONTAL, 0);
bSizer_e_ctrl->Add(0, 0, 0, wxTOP, FromDIP(7));
bSizer_e_ctrl->Add(m_extruder_book, 0, wxALIGN_CENTER_HORIZONTAL, 0);
bSizer_e_ctrl->Add(0, 0, 0, wxTOP, FromDIP(7));
bSizer_e_ctrl->Add(m_bpButton_e_down_10, 0, wxALIGN_CENTER_HORIZONTAL, 0);
bSizer_e_ctrl->Add(0, 0, 1, wxEXPAND, 0);
bSizer_e_ctrl->Add(m_extruder_switching_status, 0, wxALIGN_CENTER_HORIZONTAL, 0);
bSizer_e_ctrl->Add(m_extruder_label, 0, wxTOP | wxALIGN_CENTER_HORIZONTAL, FromDIP(10));
panel->SetSizer(bSizer_e_ctrl);
panel->Layout();
sizer->Add(panel, 1, wxEXPAND, 0);
return sizer;
}
wxBoxSizer *StatusBasePanel::create_ams_group(wxWindow *parent)
{
auto sizer = new wxBoxSizer(wxVERTICAL);
auto sizer_box = new wxBoxSizer(wxVERTICAL);
m_ams_control_box = new StaticBox(parent);
StateColor box_colour(std::pair<wxColour, int>(*wxWHITE, StateColor::Normal));
StateColor box_border_colour(std::pair<wxColour, int>(STATUS_PANEL_BG, StateColor::Normal));
m_ams_control_box->SetBackgroundColor(box_colour);
m_ams_control_box->SetBorderColor(box_border_colour);
m_ams_control_box->SetCornerRadius(5);
m_ams_control_box->SetMinSize(wxSize(FromDIP(586), -1));
m_ams_control_box->SetBackgroundColour(*wxWHITE);
#if !BBL_RELEASE_TO_PUBLIC
m_ams_debug = new wxStaticText(m_ams_control_box, wxID_ANY, _L("Debug Info"), wxDefaultPosition, wxDefaultSize, 0);
sizer_box->Add(m_ams_debug, 0, wxALIGN_CENTER_HORIZONTAL, 0);
m_ams_debug->Hide();
#endif
m_ams_control = new AMSControl(m_ams_control_box, wxID_ANY);
//m_ams_control->SetMinSize(wxSize(FromDIP(510), FromDIP(286)));
m_ams_control->SetDoubleBuffered(true);
sizer_box->Add(m_ams_control, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, FromDIP(10));
m_ams_control_box->SetBackgroundColour(*wxWHITE);
m_ams_control_box->SetSizer(sizer_box);
m_ams_control_box->Layout();
m_ams_control_box->Fit();
sizer->Add(m_ams_control_box, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, FromDIP(0));
return sizer;
}
wxBoxSizer* StatusBasePanel::create_filament_group(wxWindow* parent)
{
auto sizer = new wxBoxSizer(wxVERTICAL);
auto sizer_scale_panel = new wxBoxSizer(wxHORIZONTAL);
m_scale_panel = new wxPanel(parent);
m_scale_panel->SetMinSize(wxSize(FromDIP(586), FromDIP(40)));
m_scale_panel->SetMaxSize(wxSize(FromDIP(586), FromDIP(40)));
m_scale_panel->SetBackgroundColour(*wxWHITE);
auto m_title_filament_loading = new Label(m_scale_panel, _L("Filament loading..."));
m_title_filament_loading->SetBackgroundColour(*wxWHITE);
m_title_filament_loading->SetForegroundColour(wxColour(0, 137, 123));
m_title_filament_loading->SetFont(::Label::Body_14);
m_img_filament_loading = new wxStaticBitmap(m_scale_panel, wxID_ANY, create_scaled_bitmap("filament_load_fold", this, 24), wxDefaultPosition, wxSize(FromDIP(24), FromDIP(24)), 0);
sizer_scale_panel->Add(0, 0, 0, wxLEFT, FromDIP(20));
sizer_scale_panel->Add(m_title_filament_loading, 0, wxALIGN_CENTER, 0);
sizer_scale_panel->Add(m_img_filament_loading, 0, wxALIGN_CENTER, 0);
m_scale_panel->SetSizer(sizer_scale_panel);
m_scale_panel->Layout();
m_scale_panel->Fit();
m_scale_panel->Hide();
m_title_filament_loading->Bind(wxEVT_LEFT_DOWN, &StatusBasePanel::expand_filament_loading, this);
m_scale_panel->Bind(wxEVT_LEFT_DOWN, &StatusBasePanel::expand_filament_loading, this);
auto sizer_box = new wxBoxSizer(wxVERTICAL);
StateColor box_colour(std::pair<wxColour, int>(*wxWHITE, StateColor::Normal));
StateColor box_border_colour(std::pair<wxColour, int>(STATUS_PANEL_BG, StateColor::Normal));
m_filament_load_box = new StaticBox(parent);
m_filament_load_box->SetBackgroundColor(box_colour);
m_filament_load_box->SetBorderColor(box_border_colour);
m_filament_load_box->SetCornerRadius(5);
m_filament_load_box->SetMinSize(wxSize(FromDIP(586), -1));
m_filament_load_box->SetMaxSize(wxSize(FromDIP(586), -1));
m_filament_load_box->SetBackgroundColour(*wxWHITE);
m_filament_load_box->SetSizer(sizer_box);
m_filament_step = new FilamentLoad(m_filament_load_box, wxID_ANY);
m_filament_step->SetDoubleBuffered(true);
m_filament_step->set_min_size(wxSize(wxSize(FromDIP(300), FromDIP(215))));
m_filament_step->set_max_size(wxSize(wxSize(FromDIP(300), FromDIP(215))));
m_filament_step->SetBackgroundColour(*wxWHITE);
m_filament_load_img = new wxStaticBitmap(m_filament_load_box, wxID_ANY, wxNullBitmap);
m_filament_load_img->SetBackgroundColour(*wxWHITE);
wxBoxSizer *steps_sizer = new wxBoxSizer(wxHORIZONTAL);
steps_sizer->Add(m_filament_step, 0, wxALIGN_LEFT, FromDIP(20));
steps_sizer->Add(m_filament_load_img, 0, wxALIGN_TOP, FromDIP(30));
steps_sizer->AddStretchSpacer();
m_button_retry = new Button(m_filament_load_box, _L("Retry"));
m_button_retry->SetStyle(ButtonStyle::Confirm, ButtonType::Choice);
//m_button_retry->Hide();
m_button_retry->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) {
BOOST_LOG_TRIVIAL(info) << "on_ams_retry";
if (obj) { obj->command_ams_control("resume"); }
});
// Orca: filament-change Stop button (aborts an in-progress filament change)
m_fila_change_abort = new Button(m_filament_load_box, _L("Stop"));
m_fila_change_abort->SetStyle(ButtonStyle::Regular, ButtonType::Choice);
m_fila_change_abort->Hide();
m_fila_change_abort->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) {
BOOST_LOG_TRIVIAL(info) << "on_ams_abort";
if (obj) { obj->command_ams_control("abort"); }
});
wxBoxSizer *fila_change_sizer = new wxBoxSizer(wxHORIZONTAL);
fila_change_sizer->Add(m_button_retry, 0, wxRIGHT, FromDIP(7));
fila_change_sizer->Add(m_fila_change_abort, 0, wxLEFT, FromDIP(7));
sizer_box->Add(steps_sizer, 0, wxEXPAND | wxTOP, FromDIP(5));
sizer_box->Add(fila_change_sizer, 0, wxLEFT, FromDIP(28));
sizer_box->Add(0, 0, 0, wxTOP, FromDIP(5));
m_filament_load_box->SetBackgroundColour(*wxWHITE);
m_filament_load_box->Layout();
m_filament_load_box->Fit();
m_filament_load_box->Hide();
sizer->Add(m_scale_panel, 0, wxALIGN_CENTER_HORIZONTAL | wxTOP, FromDIP(5));
sizer->Add(m_filament_load_box, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
return sizer;
}
void StatusBasePanel::expand_filament_loading(wxMouseEvent& e)
{
auto tag_show = false;
if (m_filament_load_box->IsShown()) {
tag_show = false;
m_img_filament_loading->SetBitmap(create_scaled_bitmap("filament_load_fold", this, 24));
} else {
tag_show = true;
m_img_filament_loading->SetBitmap(create_scaled_bitmap("filament_load_expand", this, 24));
}
if (obj)
{
static int load_img_size = 215;
if (obj->is_series_n())
{
m_filament_load_img->SetBitmap(create_scaled_bitmap("filament_load_n_series", this, load_img_size));
}
else if (obj->is_series_x())
{
m_filament_load_img->SetBitmap(create_scaled_bitmap("filament_load_x_series", this, load_img_size));
}
else if (obj->is_series_p())
{
m_filament_load_img->SetBitmap(create_scaled_bitmap("filament_load_p_series", this, load_img_size));
}
else if (obj->is_series_o())
{
const auto& ext_system = obj->GetExtderSystem();
// Prefer the config-driven filament-load image: H2C ships per-extruder bitmaps, and a printer
// fitted with an induction hotend rack picks the rack-specific set (filament_load_image_nozzle_rack).
// Printers whose profile carries no such key (e.g. H2D) get an empty name here and fall through to
// the generic O-series bitmaps below, so their monitor page stays byte-identical. Rack-driven, so
// there is no behavior change for any non-rack printer.
int cur_ext_id = (ext_system && ext_system->GetTotalExtderCount() > 1) ? ext_system->GetCurrentExtderId() : 0;
bool has_nozzle_rack = obj->GetNozzleSystem()->GetNozzleRack()->IsSupported();
std::string img_name = DevPrinterConfigUtil::get_filament_load_img(obj->printer_type, cur_ext_id, has_nozzle_rack);
if (!img_name.empty())
{
m_filament_load_img->SetBitmap(create_scaled_bitmap(img_name, this, load_img_size));
}
else if (ext_system->GetTotalExtderCount() == 2)
{
int cur_extder_id = ext_system->GetCurrentExtderId();
if (cur_extder_id == MAIN_EXTRUDER_ID)
{
m_filament_load_img->SetBitmap(create_scaled_bitmap("filament_load_o_series_right", this, load_img_size));
}
else if (cur_extder_id == DEPUTY_EXTRUDER_ID)
{
m_filament_load_img->SetBitmap(create_scaled_bitmap("filament_load_o_series_left", this, load_img_size));
}
}
else
{
m_filament_load_img->SetBitmap(create_scaled_bitmap("filament_load_o_series", this, load_img_size));
}
}
}
m_filament_load_box->Show(tag_show);
///m_button_retry->Show(tag_show);
m_filament_step->Show(tag_show);
Layout();
Fit();
wxGetApp().mainframe->m_monitor->get_status_panel()->Layout();
wxGetApp().mainframe->m_monitor->Layout();
}
void StatusBasePanel::show_ams_group(bool show)
{
if (m_ams_control->IsShown() != show) {
m_ams_control->Show(show);
m_ams_control->Layout();
m_ams_control->Fit();
Layout();
Fit();
wxGetApp().mainframe->m_monitor->Layout();
}
// On rack printers, don't clobber the rack view when the user has the switch on "Hotends".
// Inert for every non-rack printer: the switch stays hidden, so this guard never triggers.
if (show && m_ams_rack_switch->IsShown() && (m_ams_rack_switch->switch_left != true)) { return; }
if (m_ams_control_box->IsShown() != show) {
m_ams_control_box->Show(show);
m_ams_control->Layout();
m_ams_control->Fit();
Layout();
Fit();
wxGetApp().mainframe->m_monitor->Layout();
}
}
void StatusBasePanel::show_filament_load_group(bool show)
{
if (m_scale_panel->IsShown() != show) {
m_scale_panel->Show(show);
if (!show) {
m_img_filament_loading->SetBitmap(create_scaled_bitmap("filament_load_fold", this, 24));
m_img_filament_loading->Refresh();
}
// m_scale_panel control the display of m_filament_load_box
if (!show && m_filament_load_box->IsShown()) {
m_filament_load_box->Show(false);
}
auto cur_ext = obj->GetExtderSystem()->GetCurrentExtder();
m_filament_step->SetupSteps(obj, cur_ext ? cur_ext->HasFilamentInExt() : false);
Layout();
Fit();
wxGetApp().mainframe->m_monitor->get_status_panel()->Layout();
wxGetApp().mainframe->m_monitor->Layout();
}
}
void StatusBasePanel::jump_to_Rack()
{
if (obj && obj->GetNozzleSystem()->GetNozzleRack()->IsSupported()) {
m_ams_rack_switch->updateState("right");
m_ams_control_box->Show(false);
m_panel_nozzle_rack->Show(true);
Layout();
}
}
void StatusBasePanel::on_ams_rack_switch(wxCommandEvent &e)
{
if (!m_ams_control_box->IsShown() && e.GetInt() == 1) {
m_ams_control_box->Show(e.GetInt() == 1);
m_panel_nozzle_rack->Show(e.GetInt() == 0);
Layout();
} else if (!m_panel_nozzle_rack->IsShown() && e.GetInt() == 0) {
m_ams_control_box->Show(e.GetInt() == 1);
m_panel_nozzle_rack->Show(e.GetInt() == 0);
Layout();
}
e.Skip();
}
void StatusPanel::update_camera_state(MachineObject* obj)
{
if (!obj) return;
//sdcard
auto sdcard_state = obj->GetStorage()->get_sdcard_state();
if (m_last_sdcard != sdcard_state) {
if (sdcard_state == DevStorage::NO_SDCARD) {
m_bitmap_sdcard_img->SetBitmap(m_bitmap_sdcard_state_no.bmp());
m_bitmap_sdcard_img->SetToolTip(_L("No Storage"));
} else if (sdcard_state == DevStorage::HAS_SDCARD_NORMAL) {
m_bitmap_sdcard_img->SetBitmap(m_bitmap_sdcard_state_normal.bmp());
m_bitmap_sdcard_img->SetToolTip(_L("Storage"));
} else if (sdcard_state == DevStorage::HAS_SDCARD_ABNORMAL) {
m_bitmap_sdcard_img->SetBitmap(m_bitmap_sdcard_state_abnormal.bmp());
m_bitmap_sdcard_img->SetToolTip(_L("Storage Abnormal"));
} else {
m_bitmap_sdcard_img->SetBitmap(m_bitmap_sdcard_state_normal.bmp());
m_bitmap_sdcard_img->SetToolTip(_L("Storage"));
}
m_last_sdcard = sdcard_state;
m_panel_monitoring_title->Layout();
}
//recording
if (m_last_recording != (obj->is_recording() ? 1 : 0)) {
if (obj->is_recording()) {
m_bitmap_recording_img->SetBitmap(m_bitmap_recording_on.bmp());
}
else {
m_bitmap_recording_img->SetBitmap(m_bitmap_recording_off.bmp());
}
m_last_recording = obj->is_recording() ? 1 : 0;
}
if (!m_bitmap_recording_img->IsShown()) {
m_bitmap_recording_img->Show();
m_panel_monitoring_title->Layout();
}
/*if (m_bitmap_recording_img->IsShown())
m_bitmap_recording_img->Hide();*/
//timelapse
if (obj->is_support_timelapse) {
if (m_last_timelapse != (obj->is_timelapse() ? 1: 0)) {
if (obj->is_timelapse()) {
m_bitmap_timelapse_img->SetBitmap(m_bitmap_timelapse_on.bmp());
} else {
m_bitmap_timelapse_img->SetBitmap(m_bitmap_timelapse_off.bmp());
}
m_last_timelapse = obj->is_timelapse() ? 1 : 0;
}
if (!m_bitmap_timelapse_img->IsShown()) {
m_bitmap_timelapse_img->Show();
m_panel_monitoring_title->Layout();
}
} else {
if (m_bitmap_timelapse_img->IsShown()) {
m_bitmap_timelapse_img->Hide();
m_panel_monitoring_title->Layout();
}
}
//vcamera
if (obj->virtual_camera) {
if (m_last_vcamera != (m_media_play_ctrl->IsStreaming() ? 1: 0)) {
if (m_media_play_ctrl->IsStreaming()) {
m_bitmap_vcamera_img->SetBitmap(m_bitmap_vcamera_on.bmp());
} else {
m_bitmap_vcamera_img->SetBitmap(m_bitmap_vcamera_off.bmp());
}
m_last_vcamera = m_media_play_ctrl->IsStreaming() ? 1 : 0;
}
if (!m_bitmap_vcamera_img->IsShown()) {
m_bitmap_vcamera_img->Show();
m_panel_monitoring_title->Layout();
}
} else {
if (m_bitmap_vcamera_img->IsShown()) {
m_bitmap_vcamera_img->Hide();
m_panel_monitoring_title->Layout();
}
}
//camera setting
if (m_camera_popup && m_camera_popup->IsShown()) {
bool show_vcamera = m_media_play_ctrl->IsStreaming();
m_camera_popup->update(show_vcamera);
}
}
StatusPanel::StatusPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, const wxString &name)
: StatusBasePanel(parent, id, pos, size, style)
{
init_scaled_buttons();
m_buttons.push_back(m_bpButton_z_10);
m_buttons.push_back(m_bpButton_z_1);
m_buttons.push_back(m_bpButton_z_down_1);
m_buttons.push_back(m_bpButton_z_down_10);
m_buttons.push_back(m_bpButton_e_10);
m_buttons.push_back(m_bpButton_e_down_10);
obj = nullptr;
m_score_data = new ScoreData;
m_score_data->rating_id = -1;
/* set default values */
m_switch_lamp->SetValue(false);
/*m_switch_printing_fan->SetValue(false);
m_switch_nozzle_fan->SetValue(false);
m_switch_cham_fan->SetValue(false);*/
//m_switch_fan->SetValue(false);
/* set default enable state */
m_project_task_panel->enable_partskip_button(nullptr, false);
m_project_task_panel->enable_pause_resume_button(false, "resume_disable");
m_project_task_panel->enable_abort_button(false);
Bind(wxEVT_WEBREQUEST_STATE, &StatusPanel::on_webrequest_state, this);
Bind(wxCUSTOMEVT_SET_TEMP_FINISH, [this](wxCommandEvent e) {
int id = e.GetInt();
if (id == m_tempCtrl_bed->GetType()) {
on_set_bed_temp();
} else if (id == m_tempCtrl_nozzle->GetType()) {
if (e.GetString() == wxString::Format("%d", MAIN_EXTRUDER_ID)) {
on_set_nozzle_temp(MAIN_EXTRUDER_ID);
} else if (e.GetString() == wxString::Format("%d", DEPUTY_EXTRUDER_ID)) {
on_set_nozzle_temp(DEPUTY_EXTRUDER_ID);
} else {
on_set_nozzle_temp(UNIQUE_EXTRUDER_ID);//there is only one nozzle
}
} else if (id == m_tempCtrl_chamber->GetType()) {
if (!m_tempCtrl_chamber->IsOnChanging()) {
m_tempCtrl_chamber->SetOnChanging();
on_set_chamber_temp();
m_tempCtrl_chamber->ReSetOnChanging();
}
}
});
// Connect Events
m_project_task_panel->get_bitmap_thumbnail()->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(StatusPanel::refresh_thumbnail_webrequest), NULL, this);
m_project_task_panel->get_partskip_button()->Connect(wxEVT_LEFT_DOWN, wxCommandEventHandler(StatusPanel::on_subtask_partskip), NULL, this);
m_project_task_panel->get_pause_resume_button()->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_pause_resume), NULL, this);
m_project_task_panel->get_abort_button()->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_abort), NULL, this);
m_project_task_panel->get_market_scoring_button()->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_market_scoring), NULL, this);
m_project_task_panel->get_market_retry_buttom()->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_market_retry), NULL, this);
m_project_task_panel->get_clean_button()->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_print_error_clean), NULL, this);
m_setting_button->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(StatusPanel::on_camera_enter), NULL, this);
m_setting_button->Connect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(StatusPanel::on_camera_enter), NULL, this);
m_tempCtrl_bed->Connect(wxEVT_KILL_FOCUS, wxFocusEventHandler(StatusPanel::on_bed_temp_kill_focus), NULL, this);
m_tempCtrl_bed->Connect(wxEVT_SET_FOCUS, wxFocusEventHandler(StatusPanel::on_bed_temp_set_focus), NULL, this);
m_tempCtrl_nozzle->Connect(wxEVT_KILL_FOCUS, wxFocusEventHandler(StatusPanel::on_nozzle_temp_kill_focus), NULL, this);
m_tempCtrl_nozzle->Connect(wxEVT_SET_FOCUS, wxFocusEventHandler(StatusPanel::on_nozzle_temp_set_focus), NULL, this);
m_tempCtrl_nozzle_deputy->Connect(wxEVT_KILL_FOCUS, wxFocusEventHandler(StatusPanel::on_nozzle_temp_kill_focus), NULL, this);
m_tempCtrl_nozzle_deputy->Connect(wxEVT_SET_FOCUS, wxFocusEventHandler(StatusPanel::on_nozzle_temp_set_focus), NULL, this);
m_tempCtrl_chamber->Connect(wxEVT_KILL_FOCUS, wxFocusEventHandler(StatusPanel::on_cham_temp_kill_focus), NULL, this);
m_tempCtrl_chamber->Connect(wxEVT_SET_FOCUS, wxFocusEventHandler(StatusPanel::on_cham_temp_set_focus), NULL, this);
m_switch_lamp->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_lamp_switch), NULL, this);
//m_switch_nozzle_fan->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_nozzle_fan_switch), NULL, this); // TODO
//m_switch_printing_fan->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_nozzle_fan_switch), NULL, this);
//m_switch_cham_fan->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_nozzle_fan_switch), NULL, this);
m_switch_fan->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_nozzle_fan_switch), NULL, this); // TODO
//m_switch_fan->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_nozzle_fan_switch), NULL, this);
//m_switch_fan->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_nozzle_fan_switch), NULL, this);
m_bpButton_xy->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_axis_ctrl_xy), NULL, this); // TODO
m_bpButton_z_10->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_axis_ctrl_z_up_10), NULL, this);
m_bpButton_z_1->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_axis_ctrl_z_up_1), NULL, this);
m_bpButton_z_down_1->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_axis_ctrl_z_down_1), NULL, this);
m_bpButton_z_down_10->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_axis_ctrl_z_down_10), NULL, this);
m_bpButton_e_10->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_axis_ctrl_e_up_10), NULL, this);
m_bpButton_e_down_10->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_axis_ctrl_e_down_10), NULL, this);
m_nozzle_btn_panel->Connect(wxCUSTOMEVT_SWITCH_POS, wxCommandEventHandler(StatusPanel::on_nozzle_selected), NULL, this);
Bind(EVT_AMS_EXTRUSION_CALI, &StatusPanel::on_filament_extrusion_cali, this);
Bind(EVT_AMS_LOAD, &StatusPanel::on_ams_load, this);
Bind(EVT_AMS_UNLOAD, &StatusPanel::on_ams_unload, this);
Bind(EVT_AMS_SWITCH, &StatusPanel::on_ams_switch, this);
Bind(EVT_AMS_FILAMENT_BACKUP, &StatusPanel::on_ams_filament_backup, this);
Bind(EVT_AMS_SETTINGS, &StatusPanel::on_ams_setting_click, this);
Bind(EVT_AMS_REFRESH_RFID, &StatusPanel::on_ams_refresh_rfid, this);
Bind(EVT_AMS_ON_SELECTED, &StatusPanel::on_ams_selected, this);
Bind(EVT_AMS_ON_FILAMENT_EDIT, &StatusPanel::on_filament_edit, this);
Bind(EVT_VAMS_ON_FILAMENT_EDIT, &StatusPanel::on_ext_spool_edit, this);
Bind(EVT_AMS_GUIDE_WIKI, &StatusPanel::on_ams_guide, this);
Bind(EVT_AMS_RETRY, &StatusPanel::on_ams_retry, this);
Bind(EVT_FAN_CHANGED, &StatusPanel::on_fan_changed, this);
Bind(EVT_SECONDARY_CHECK_RESUME, &StatusPanel::on_subtask_pause_resume, this);
Bind(EVT_SECONDARY_CHECK_RETRY, [this](auto &e) { if (m_ams_control) { m_ams_control->on_retry(); }});
m_switch_speed->Connect(wxEVT_LEFT_DOWN, wxCommandEventHandler(StatusPanel::on_switch_speed), NULL, this);
m_calibration_btn->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_start_calibration), NULL, this);
m_options_btn->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_show_print_options), NULL, this);
m_safety_btn->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_show_safety_options), NULL, this);
m_parts_btn->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_show_parts_options), NULL, this);
}
StatusPanel::~StatusPanel()
{
// Disconnect Events
m_project_task_panel->get_bitmap_thumbnail()->Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(StatusPanel::refresh_thumbnail_webrequest), NULL, this);
m_project_task_panel->get_partskip_button()->Disconnect(wxEVT_LEFT_DOWN, wxCommandEventHandler(StatusPanel::on_subtask_partskip), NULL, this);
m_project_task_panel->get_pause_resume_button()->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_pause_resume), NULL, this);
m_project_task_panel->get_abort_button()->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_abort), NULL, this);
m_project_task_panel->get_market_scoring_button()->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_market_scoring), NULL, this);
m_project_task_panel->get_market_retry_buttom()->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_market_retry), NULL, this);
m_project_task_panel->get_clean_button()->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_print_error_clean), NULL, this);
m_setting_button->Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(StatusPanel::on_camera_enter), NULL, this);
m_setting_button->Disconnect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(StatusPanel::on_camera_enter), NULL, this);
m_tempCtrl_bed->Disconnect(wxEVT_KILL_FOCUS, wxFocusEventHandler(StatusPanel::on_bed_temp_kill_focus), NULL, this);
m_tempCtrl_bed->Disconnect(wxEVT_SET_FOCUS, wxFocusEventHandler(StatusPanel::on_bed_temp_set_focus), NULL, this);
m_tempCtrl_nozzle->Disconnect(wxEVT_KILL_FOCUS, wxFocusEventHandler(StatusPanel::on_nozzle_temp_kill_focus), NULL, this);
m_tempCtrl_nozzle->Disconnect(wxEVT_SET_FOCUS, wxFocusEventHandler(StatusPanel::on_nozzle_temp_set_focus), NULL, this);
m_tempCtrl_nozzle_deputy->Disconnect(wxEVT_KILL_FOCUS, wxFocusEventHandler(StatusPanel::on_nozzle_temp_kill_focus), NULL, this);
m_tempCtrl_nozzle_deputy->Disconnect(wxEVT_SET_FOCUS, wxFocusEventHandler(StatusPanel::on_nozzle_temp_set_focus), NULL, this);
m_switch_lamp->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_lamp_switch), NULL, this);
/*m_switch_nozzle_fan->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_nozzle_fan_switch), NULL, this);
m_switch_printing_fan->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_nozzle_fan_switch), NULL, this);
m_switch_cham_fan->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_nozzle_fan_switch), NULL, this);*/
//m_switch_fan->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_nozzle_fan_switch), NULL, this);
//m_switch_fan->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_nozzle_fan_switch), NULL, this);
m_switch_fan->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_nozzle_fan_switch), NULL, this);
m_bpButton_xy->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_axis_ctrl_xy), NULL, this);
m_bpButton_z_10->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_axis_ctrl_z_up_10), NULL, this);
m_bpButton_z_1->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_axis_ctrl_z_up_1), NULL, this);
m_bpButton_z_down_1->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_axis_ctrl_z_down_1), NULL, this);
m_bpButton_z_down_10->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_axis_ctrl_z_down_10), NULL, this);
m_bpButton_e_10->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_axis_ctrl_e_up_10), NULL, this);
m_bpButton_e_down_10->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_axis_ctrl_e_down_10), NULL, this);
m_nozzle_btn_panel->Disconnect(wxCUSTOMEVT_SWITCH_POS, wxCommandEventHandler(StatusPanel::on_nozzle_selected), NULL, this);
m_switch_speed->Disconnect(wxEVT_LEFT_DOWN, wxCommandEventHandler(StatusPanel::on_switch_speed), NULL, this);
m_calibration_btn->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_start_calibration), NULL, this);
m_options_btn->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_show_print_options), NULL, this);
m_safety_btn->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_show_safety_options), NULL, this);
m_parts_btn->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_show_parts_options), NULL, this);
// remove warning dialogs
if (abort_dlg != nullptr)
delete abort_dlg;
if (ctrl_e_hint_dlg != nullptr)
delete ctrl_e_hint_dlg;
if (sdcard_hint_dlg != nullptr)
delete sdcard_hint_dlg;
if (m_score_data != nullptr) {
delete m_score_data;
}
}
void StatusPanel::init_scaled_buttons()
{
if (!m_project_task_panel) return;
m_project_task_panel->init_scaled_buttons();
m_bpButton_z_10->SetMinSize(Z_BUTTON_SIZE);
m_bpButton_z_10->SetCornerRadius(0);
m_bpButton_z_1->SetMinSize(Z_BUTTON_SIZE);
m_bpButton_z_1->SetCornerRadius(0);
m_bpButton_z_down_1->SetMinSize(Z_BUTTON_SIZE);
m_bpButton_z_down_1->SetCornerRadius(0);
m_bpButton_z_down_10->SetMinSize(Z_BUTTON_SIZE);
m_bpButton_z_down_10->SetCornerRadius(0);
m_bpButton_e_10->SetMinSize(wxSize(FromDIP(40), FromDIP(40)));
m_bpButton_e_10->SetCornerRadius(FromDIP(12));
m_bpButton_e_down_10->SetMinSize(wxSize(FromDIP(40), FromDIP(40)));
m_bpButton_e_down_10->SetCornerRadius(FromDIP(12));
}
void StatusPanel::on_market_scoring(wxCommandEvent &event) {
if (obj && obj->is_makeworld_subtask() && obj->rating_info && obj->rating_info->request_successful) { // model is mall model and has rating_id
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": on_market_scoring" ;
if (m_score_data && m_score_data->rating_id == obj->rating_info->rating_id) { // current score data for model is same as mall model
if (m_score_data->star_count != m_project_task_panel->get_star_count()) m_score_data->star_count = m_project_task_panel->get_star_count();
ScoreDialog m_score_dlg(this, m_score_data);
int ret = m_score_dlg.ShowModal();
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": old data";
if (ret == wxID_OK) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": old data is upload";
m_score_data->rating_id = -1;
m_project_task_panel->set_star_count_dirty(false);
if (obj) obj->get_model_mall_result_need_retry = true;
return;
}
if (m_score_data != nullptr) {
delete m_score_data;
m_score_data = nullptr;
}
m_score_data = new ScoreData(m_score_dlg.get_score_data()); // when user do not submit score, store the data for next opening the score dialog
m_project_task_panel->set_star_count(m_score_data->star_count);
} else {
int star_count = m_project_task_panel->get_star_count_dirty() ? m_project_task_panel->get_star_count() : obj->rating_info->start_count;
bool success_print = obj->rating_info->success_printed;
ScoreDialog m_score_dlg(this, obj->get_modeltask()->design_id, obj->get_modeltask()->model_id, obj->get_modeltask()->profile_id, obj->rating_info->rating_id,
success_print, star_count);
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": new data";
std::string comment = obj->rating_info->content;
if (!comment.empty()) { m_score_dlg.set_comment(comment); }
std::vector<std::string> images_json_array;
images_json_array = obj->rating_info->image_url_paths;
if (!images_json_array.empty()) m_score_dlg.set_cloud_bitmap(images_json_array);
int ret = m_score_dlg.ShowModal();
if (ret == wxID_OK) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": new data is upload";
m_score_data->rating_id = -1;
m_project_task_panel->set_star_count_dirty(false);
if (obj) obj->get_model_mall_result_need_retry = true;
return;
}
if (m_score_data != nullptr) {
delete m_score_data;
m_score_data = nullptr;
}
m_score_data = new ScoreData(m_score_dlg.get_score_data());
m_project_task_panel->set_star_count(m_score_data->star_count);
}
}
}
void StatusPanel::on_market_retry(wxCommandEvent &event)
{
if (obj) {
obj->get_model_mall_result_need_retry = true;
} else {
BOOST_LOG_TRIVIAL(info)<< __FUNCTION__ << "retury failed";
}
}
void StatusPanel::update_partskip_button(MachineObject *obj) {
if (!obj) return;
auto partskip_button = m_project_task_panel->get_partskip_button();
if( obj->is_support_partskip ){
partskip_button->Show();
}else{
partskip_button->Hide();
}
BOOST_LOG_TRIVIAL(info) << "part skip: is_support_partskip: "<< obj->is_support_partskip;
}
void StatusPanel::on_subtask_partskip(wxCommandEvent &event)
{
if (m_partskip_dlg == nullptr) {
m_partskip_dlg = new PartSkipDialog(this->GetParent());
}
auto dm = GUI::wxGetApp().getDeviceManager();
m_partskip_dlg->InitSchedule(dm->get_selected_machine());
BOOST_LOG_TRIVIAL(info) << "part skip: initial part skip dialog.";
if(m_partskip_dlg->ShowModal() == wxID_OK){
int cnt = m_partskip_dlg->GetAllSkippedPartsNum();
m_project_task_panel->set_part_skipped_count(cnt);
m_project_task_panel->set_part_skipped_dirty(5);
BOOST_LOG_TRIVIAL(info) << "part skip: prepare to filter printer dirty data.";
}
}
void StatusPanel::on_subtask_pause_resume(wxCommandEvent &event)
{
if (obj) {
if (obj->can_resume()) {
BOOST_LOG_TRIVIAL(info) << "monitor: resume current print task dev_id =" << obj->get_dev_id();
obj->command_task_resume();
}
else {
BOOST_LOG_TRIVIAL(info) << "monitor: pause current print task dev_id =" << obj->get_dev_id();
obj->command_task_pause();
}
}
}
void StatusPanel::on_subtask_abort(wxCommandEvent &event)
{
if (abort_dlg == nullptr) {
abort_dlg = new SecondaryCheckDialog(this->GetParent(), wxID_ANY, _L("Cancel print"));
abort_dlg->Bind(EVT_SECONDARY_CHECK_CONFIRM, [this](wxCommandEvent &e) {
if (obj) {
BOOST_LOG_TRIVIAL(info) << "monitor: stop current print task dev_id =" << obj->get_dev_id();
obj->command_task_abort();
}
});
}
abort_dlg->update_text(_L("Are you sure you want to stop this print?"));
abort_dlg->m_button_cancel->SetLabel(_L("No"));
abort_dlg->m_button_ok->SetLabel(_L("Yes"));
abort_dlg->on_show();
abort_dlg->Raise();
}
void StatusPanel::error_info_reset()
{
m_project_task_panel->error_info_reset();
}
void StatusPanel::on_print_error_clean(wxCommandEvent &event)
{
error_info_reset();
skip_print_error = obj->print_error;
char buf[32];
::sprintf(buf, "%08X", skip_print_error);
BOOST_LOG_TRIVIAL(info) << "skip_print_error: " << buf;
before_error_code = obj->print_error;
}
void StatusPanel::on_webrequest_state(wxWebRequestEvent &evt)
{
BOOST_LOG_TRIVIAL(trace) << "monitor: monitor_panel web request state = " << evt.GetState();
switch (evt.GetState()) {
case wxWebRequest::State_Completed: {
if (m_current_print_mode != PrintingTaskType::CALIBRATION ||(m_calib_mode == CalibMode::Calib_Flow_Rate && m_calib_method == CalibrationMethod::CALI_METHOD_MANUAL)) {
wxImage img(*evt.GetResponse().GetStream());
img_list.insert(std::make_pair(m_request_url, img));
wxImage resize_img = img.Scale(m_project_task_panel->get_bitmap_thumbnail()->GetSize().x, m_project_task_panel->get_bitmap_thumbnail()->GetSize().y, wxIMAGE_QUALITY_HIGH);
m_project_task_panel->set_thumbnail_img(resize_img, "");
m_project_task_panel->set_brightness_value(get_brightness_value(resize_img));
}
if (obj) {
m_project_task_panel->set_plate_index(obj->m_plate_index);
} else {
m_project_task_panel->set_plate_index(-1);
}
task_thumbnail_state = ThumbnailState::TASK_THUMBNAIL;
break;
}
case wxWebRequest::State_Failed:
case wxWebRequest::State_Cancelled:
case wxWebRequest::State_Unauthorized: {
m_project_task_panel->set_thumbnail_img(m_thumbnail_brokenimg.bmp(), m_thumbnail_brokenimg.name());
m_project_task_panel->set_plate_index(-1);
task_thumbnail_state = ThumbnailState::BROKEN_IMG;
break;
}
case wxWebRequest::State_Active:
case wxWebRequest::State_Idle: break;
default: break;
}
}
void StatusPanel::refresh_thumbnail_webrequest(wxMouseEvent& event)
{
if (!obj) return;
if (task_thumbnail_state != ThumbnailState::BROKEN_IMG) return;
if (obj->slice_info) {
m_request_url = wxString(obj->slice_info->thumbnail_url);
if (!m_request_url.IsEmpty()) {
web_request = wxWebSession::GetDefault().CreateRequest(this, m_request_url);
BOOST_LOG_TRIVIAL(trace) << "monitor: create new webrequest, state = " << web_request.GetState() << ", url = " << m_request_url;
if (web_request.GetState() == wxWebRequest::State_Idle)
web_request.Start();
BOOST_LOG_TRIVIAL(trace) << "monitor: start new webrequest, state = " << web_request.GetState() << ", url = " << m_request_url;
}
}
}
bool StatusPanel::is_task_changed(MachineObject* obj)
{
if (!obj)
return false;
if (last_subtask != obj->subtask_
|| last_profile_id != obj->profile_id_
|| last_task_id != obj->task_id_
) {
last_subtask = obj->subtask_;
last_profile_id = obj->profile_id_;
last_task_id = obj->task_id_;
request_model_info_flag = false;
m_project_task_panel->set_star_count_dirty(false);
return true;
}
return false;
}
void StatusPanel::update(MachineObject *obj)
{
if (!obj || !obj->is_info_ready())
{
m_nozzle_btn_panel->Disable();
return;
}
//m_project_task_panel->Freeze();
update_subtask(obj);
//m_project_task_panel->Thaw();
#if !BBL_RELEASE_TO_PUBLIC
auto delay1 = std::chrono::duration_cast<std::chrono::milliseconds>(obj->last_utc_time - std::chrono::system_clock::now()).count();
auto delay2 = std::chrono::duration_cast<std::chrono::milliseconds>(obj->last_push_time - std::chrono::system_clock::now()).count();
auto delay = wxString::Format(" %ld/%ld", delay1, delay2);
m_staticText_timelapse->SetLabel((obj->is_lan_mode_printer() ? "Local Mqtt" : obj->is_tunnel_mqtt ? "Tunnel Mqtt" : "Cloud Mqtt") + delay);
m_bmToggleBtn_timelapse->Enable(!obj->is_lan_mode_printer());
m_bmToggleBtn_timelapse->SetValue(obj->is_tunnel_mqtt);
#endif
#if !BBL_RELEASE_TO_PUBLIC
if (obj->HasRecentCloudMessage() && obj->HasRecentLanMessage()) m_mqtt_source->SetLabel("Cloud+Lan");
else if (obj->HasRecentCloudMessage()) m_mqtt_source->SetLabel("Cloud");
else if (obj->HasRecentLanMessage()) m_mqtt_source->SetLabel("Lan");
else m_mqtt_source->SetLabel("None");
m_mqtt_source->Show();
#endif
//m_machine_ctrl_panel->Freeze();
if (obj->is_in_printing() && !obj->can_resume()) {
show_printing_status(false, true);
} else {
show_printing_status();
}
/*STUDIO-12573*/
if (!obj->is_fdm_type()) {
m_switch_lamp->Enable(false);
}
update_temp_ctrl(obj);
update_misc_ctrl(obj);
update_ams(obj);
update_cali(obj);
update_rack(obj);
if (obj) {
//nozzle ui
//m_button_left_of_extruder->SetSelected();
// update extrusion calibration
if (m_extrusion_cali_dlg) {
m_extrusion_cali_dlg->update_machine_obj(obj);
m_extrusion_cali_dlg->update();
}
// update calibration status
if (calibration_dlg != nullptr) {
calibration_dlg->update_machine_obj(obj);
calibration_dlg->update_cali(obj);
}
std::string current_printer_type = obj->printer_type;
bool supports_safety = DevPrinterConfigUtil::support_safety_options(current_printer_type);
DevConfig* config = obj->GetConfig();
if (config->SupportFirstLayerInspect() || config->SupportAIMonitor() || obj->is_support_build_plate_marker_detect || obj->is_support_auto_recovery_step_loss) {
m_options_btn->Show();
if (print_options_dlg) {
print_options_dlg->update_machine_obj(obj);
print_options_dlg->update_options(obj);
}
} else {
m_options_btn->Hide();
}
if (obj->support_door_open_check()) {
if (supports_safety) {
m_safety_btn->Show();
if (safety_options_dlg) {
safety_options_dlg->update_machine_obj(obj);
safety_options_dlg->update_options(obj);
}
} else {
m_safety_btn->Hide();
}
} else {
m_safety_btn->Hide();
}
m_parts_btn->Show();
if (m_panel_control_title) {
m_panel_control_title->Layout();
}
if (!obj->dev_connection_type.empty()) {
auto iter_connect_type = m_print_connect_types.find(obj->get_dev_id());
if (iter_connect_type != m_print_connect_types.end()) {
if (iter_connect_type->second != obj->dev_connection_type) {
if (iter_connect_type->second == "lan" && obj->dev_connection_type == "cloud") {
m_print_connect_types[obj->get_dev_id()] = obj->dev_connection_type;
}
if (iter_connect_type->second == "cloud" && obj->dev_connection_type == "lan") {
m_print_connect_types[obj->get_dev_id()] = obj->dev_connection_type;
}
}
}
m_print_connect_types[obj->get_dev_id()] = obj->dev_connection_type;
}
update_error_message();
}
update_camera_state(obj);
//m_machine_ctrl_panel->Thaw();
}
void StatusPanel::show_recenter_dialog() {
RecenterDialog dlg(this);
if (dlg.ShowModal() == wxID_OK)
obj->command_go_home();
}
void StatusPanel::update_error_message()
{
if (!obj) return;
static int last_error = -1;
if (obj->print_error <= 0) {
error_info_reset();
} else if (obj->print_error != last_error) {
/* clear old dialog */
if (m_print_error_dlg) { delete m_print_error_dlg; }
/* show device error message*/
m_print_error_dlg = new DeviceErrorDialog(obj, this);
wxString error_msg = m_print_error_dlg->show_error_code(obj->print_error);
BOOST_LOG_TRIVIAL(info) << "print error: device error code = "<< obj->print_error;
/* show error message on task panel */
if(!error_msg.IsEmpty()) { m_project_task_panel->show_error_msg(error_msg); }
}
last_error = obj->print_error;
}
void StatusPanel::show_printing_status(bool ctrl_area, bool temp_area)
{
if (!ctrl_area) {
m_bpButton_xy->Enable(false);
m_bpButton_z_10->Enable(false);
m_bpButton_z_1->Enable(false);
m_bpButton_z_down_1->Enable(false);
m_bpButton_z_down_10->Enable(false);
m_bpButton_e_10->Enable(false);
m_bpButton_e_down_10->Enable(false);
m_bpButton_z_10->SetIcon("monitor_bed_up_disable");
m_bpButton_z_1->SetIcon("monitor_bed_up_disable");
m_bpButton_z_down_1->SetIcon("monitor_bed_down_disable");
m_bpButton_z_down_10->SetIcon("monitor_bed_down_disable");
m_bpButton_e_10->SetIcon("monitor_extruder_up_disable");
m_bpButton_e_down_10->SetIcon("monitor_extrduer_down_disable");
m_staticText_z_tip->SetForegroundColour(DISCONNECT_TEXT_COL);
m_extruder_label->SetForegroundColour(DISCONNECT_TEXT_COL);
} else {
m_bpButton_xy->Enable();
m_bpButton_z_10->Enable();
m_bpButton_z_1->Enable();
m_bpButton_z_down_1->Enable();
m_bpButton_z_down_10->Enable();
m_bpButton_e_10->Enable();
m_bpButton_e_down_10->Enable();
m_bpButton_z_10->SetIcon("monitor_bed_up");
m_bpButton_z_1->SetIcon("monitor_bed_up");
m_bpButton_z_down_1->SetIcon("monitor_bed_down");
m_bpButton_z_down_10->SetIcon("monitor_bed_down");
m_bpButton_e_10->SetIcon("monitor_extruder_up");
m_bpButton_e_down_10->SetIcon("monitor_extrduer_down");
m_staticText_z_tip->SetForegroundColour(TEXT_LIGHT_FONT_COL);
m_extruder_label->SetForegroundColour(TEXT_LIGHT_FONT_COL);
}
if (!temp_area) {
m_tempCtrl_nozzle->Enable(false);
m_tempCtrl_nozzle_deputy->Enable(false);
m_tempCtrl_bed->Enable(false);
m_tempCtrl_chamber->Enable(false);
m_switch_speed->Enable(false);
m_switch_speed->SetValue(false);
m_switch_lamp->Enable(false);
/*m_switch_nozzle_fan->Enable(false);
m_switch_printing_fan->Enable(false);
m_switch_cham_fan->Enable(false);*/
m_switch_fan->Enable(false);
} else {
m_tempCtrl_nozzle->Enable();
m_tempCtrl_nozzle_deputy->Enable();
m_tempCtrl_bed->Enable();
m_tempCtrl_chamber->Enable();
m_switch_speed->Enable();
m_switch_speed->SetValue(true);
m_switch_lamp->Enable();
/*m_switch_nozzle_fan->Enable();
m_switch_printing_fan->Enable();
m_switch_cham_fan->Enable();*/
m_switch_fan->Enable();
}
}
void StatusPanel::update_temp_ctrl(MachineObject *obj)
{
if (!obj) return;
DevBed* bed = obj->GetBed();
int bed_cur_temp = bed->GetBedTemp();
int bed_target_temp = bed->GetBedTempTarget();
m_tempCtrl_bed->SetCurrTemp((int) bed_cur_temp);
auto limit = obj->get_bed_temperature_limit();
if (obj->bed_temp_range.size() > 1) {
limit = obj->bed_temp_range[1];
}
m_tempCtrl_bed->SetMaxTemp(limit);
if (obj->nozzle_temp_range.size() >= 2) {
m_tempCtrl_nozzle->SetMinTemp(obj->nozzle_temp_range[0]);
m_tempCtrl_nozzle->SetMaxTemp(obj->nozzle_temp_range[1]);
m_tempCtrl_nozzle_deputy->SetMinTemp(obj->nozzle_temp_range[0]);
m_tempCtrl_nozzle_deputy->SetMaxTemp(obj->nozzle_temp_range[1]);
}
// update temprature if not input temp target
if (m_temp_bed_timeout > 0) {
m_temp_bed_timeout--;
} else {
if (!bed_temp_input) { m_tempCtrl_bed->SetTagTemp((int) bed_target_temp); }
}
if ((bed_target_temp - bed_cur_temp) >= TEMP_THRESHOLD_VAL) {
m_tempCtrl_bed->SetIconActive();
} else {
m_tempCtrl_bed->SetIconNormal();
}
bool to_update_layout = false;
int nozzle_num = obj->GetExtderSystem()->GetTotalExtderCount();
if (nozzle_num == 1)
{
m_tempCtrl_nozzle->SetCurrTemp(obj->GetExtderSystem()->GetNozzleTempCurrent(MAIN_EXTRUDER_ID));
m_tempCtrl_nozzle->SetCurrType(TEMP_OF_NORMAL_TYPE);
m_tempCtrl_nozzle_deputy->SetCurrType(TEMP_OF_NORMAL_TYPE);
m_tempCtrl_nozzle_deputy->SetLabel(TEMP_BLANK_STR);
m_tempCtrl_nozzle_deputy->Hide();
if (m_tempCtrl_nozzle->GetMinSize() != TEMP_CTRL_MIN_SIZE_ALIGN_ONE_ICON)
{
to_update_layout = true;
m_tempCtrl_nozzle->SetMinSize(TEMP_CTRL_MIN_SIZE_ALIGN_ONE_ICON);
}
}
else if (nozzle_num == 2)
{
m_tempCtrl_nozzle->SetCurrType(TEMP_OF_MAIN_NOZZLE_TYPE);
m_tempCtrl_nozzle->SetCurrTemp(obj->GetExtderSystem()->GetNozzleTempCurrent(MAIN_EXTRUDER_ID));
m_tempCtrl_nozzle->Show();
m_tempCtrl_nozzle_deputy->SetCurrType(TEMP_OF_DEPUTY_NOZZLE_TYPE);
m_tempCtrl_nozzle_deputy->SetCurrTemp(obj->GetExtderSystem()->GetNozzleTempCurrent(DEPUTY_EXTRUDER_ID));
m_tempCtrl_nozzle_deputy->Show();
if (m_tempCtrl_nozzle->GetMinSize() != TEMP_CTRL_MIN_SIZE_ALIGN_TWO_ICON)
{
to_update_layout = true;
m_tempCtrl_nozzle->SetMinSize(TEMP_CTRL_MIN_SIZE_ALIGN_TWO_ICON);
}
}
if (m_temp_nozzle_timeout > 0) {
m_temp_nozzle_timeout--;
} else {
if (!nozzle_temp_input) {
auto main_extder = obj->GetExtderSystem()->GetExtderById(MAIN_EXTRUDER_ID);
if (main_extder)
{
m_tempCtrl_nozzle->SetTagTemp(main_extder->GetTargetTemp());
m_tempCtrl_nozzle->SetCurrTemp((int)main_extder->GetCurrentTemp());
if (main_extder->GetTargetTemp() - main_extder->GetCurrentTemp() > TEMP_THRESHOLD_VAL)
{
m_tempCtrl_nozzle->SetIconActive();
}
else
{
m_tempCtrl_nozzle->SetIconNormal();
}
}
}
}
if (m_temp_nozzle_deputy_timeout > 0) {
m_temp_nozzle_deputy_timeout--;
}
else {
if (!nozzle_temp_input && nozzle_num >= 2) {
auto deputy_extder = obj->GetExtderSystem()->GetExtderById(DEPUTY_EXTRUDER_ID);
if (deputy_extder)
{
m_tempCtrl_nozzle_deputy->SetTagTemp(deputy_extder->GetTargetTemp());
m_tempCtrl_nozzle_deputy->SetCurrTemp((int)deputy_extder->GetCurrentTemp());
if (deputy_extder->GetTargetTemp() - deputy_extder->GetCurrentTemp() > TEMP_THRESHOLD_VAL)
{
m_tempCtrl_nozzle_deputy->SetIconActive();
}
else
{
m_tempCtrl_nozzle_deputy->SetIconNormal();
}
}
}
}
// support current temp for chamber
if (obj->get_printer_series() == PrinterSeries::SERIES_X1)
{
m_tempCtrl_chamber->SetCurrTemp(obj->chamber_temp);
}
else
{
m_tempCtrl_chamber->SetCurrTemp(TEMP_BLANK_STR);
}
// support edit chamber temp
DevConfig* config = obj->GetConfig();
if (config->SupportChamberEdit())
{
m_tempCtrl_chamber->SetReadOnly(false);
m_tempCtrl_chamber->Enable();
m_tempCtrl_chamber->SetMinTemp(config->GetChamberTempEditMin());
m_tempCtrl_chamber->SetMaxTemp(config->GetChamberTempEditMax());
m_tempCtrl_chamber->AddTemp(0); // zero is default temp
wxCursor cursor(wxCURSOR_IBEAM);
m_tempCtrl_chamber->GetTextCtrl()->SetCursor(cursor);
if (m_temp_chamber_timeout > 0)
{
m_temp_chamber_timeout--;
}
else
{
/*update temprature if not input temp target*/
if (!cham_temp_input) { m_tempCtrl_chamber->SetTagTemp(obj->chamber_temp_target); }
}
}
else
{
m_tempCtrl_chamber->SetReadOnly(true);
m_tempCtrl_chamber->SetTagTemp(TEMP_BLANK_STR);
wxCursor cursor(wxCURSOR_ARROW);
m_tempCtrl_chamber->GetTextCtrl()->SetCursor(cursor);
}
if ((obj->chamber_temp_target - obj->chamber_temp) >= TEMP_THRESHOLD_VAL) {
m_tempCtrl_chamber->SetIconActive();
}
else {
m_tempCtrl_chamber->SetIconNormal();
}
if (to_update_layout)
{
this->Layout();
}
}
void StatusPanel::update_misc_ctrl(MachineObject *obj)
{
auto get_extder_shown_state = [](bool ext_has_filament) -> ExtruderState
{
// no data to distinguish ExtruderState::UNLOAD or LOAD, use LOAD png as default
return ext_has_filament ? ExtruderState::FILLED_LOAD : ExtruderState::EMPTY_LOAD;
};
if (!obj) return;
/*extder*/
auto extder_system = obj->GetExtderSystem();
m_nozzle_num = extder_system->GetTotalExtderCount();
int select_index = m_nozzle_num - 1;
if (m_nozzle_num >= 2) {
m_extruder_book->SetSelection(m_nozzle_num);
/*style*/
m_nozzle_btn_panel->Show();
m_extruderImage[select_index]->setExtruderCount(m_nozzle_num);
if (obj->GetExtderSystem()->GetTotalExtderSize() > 1)
{
m_extruderImage[select_index]->update(get_extder_shown_state(obj->GetExtderSystem()->HasFilamentInExt(0)),
get_extder_shown_state(obj->GetExtderSystem()->HasFilamentInExt(1)));
}
/*current*/
/*update when extder position changed or the machine changed*/
if (obj->GetExtderSystem()->GetCurrentExtderId() == 0xf)
{
m_extruderImage[select_index]->setExtruderUsed("");
m_nozzle_btn_panel->updateState("");
}
else if (obj->GetExtderSystem()->GetCurrentExtderId() == MAIN_EXTRUDER_ID)
{
m_extruderImage[select_index]->setExtruderUsed("right");
m_nozzle_btn_panel->updateState("right");
}
else if (obj->GetExtderSystem()->GetCurrentExtderId() == DEPUTY_EXTRUDER_ID)
{
m_extruderImage[select_index]->setExtruderUsed("left");
m_nozzle_btn_panel->updateState("left");
}
m_nozzle_btn_panel->SetClientData(obj);
/*enable status*/
/* Can do switch while printing pause STUDIO-9789*/
if ((obj->is_in_printing() && !obj->is_in_printing_pause()) ||
obj->ams_status_main == AMS_STATUS_MAIN_FILAMENT_CHANGE ||
obj->targ_nozzle_id_from_pc != INVALID_EXTRUDER_ID)
{
m_nozzle_btn_panel->Disable();
}
else
{
m_nozzle_btn_panel->Enable();
}
} else {
m_nozzle_btn_panel->Hide();
m_extruder_book->SetSelection(m_nozzle_num);
m_extruderImage[select_index]->setExtruderCount(m_nozzle_num);
if (extder_system->GetTotalExtderSize() > 0)
{
ExtruderState shown_state = get_extder_shown_state(extder_system->HasFilamentInExt(0));
m_extruderImage[select_index]->update(shown_state);
}
}
/*switch extder*/
m_extruder_switching_status->updateBy(obj);
m_extruder_label->Show(!m_extruder_switching_status->has_content_shown());/*hide the label if there are shown infos from m_extruder_switching_status*/
/*other*/
if (obj->is_core_xy()) {
m_staticText_z_tip->SetLabel(_L("Bed"));
} else {
m_staticText_z_tip->SetLabel("Z");
}
// update extruder icon
update_extruder_status(obj);
if (obj->is_fdm_type()) {
if (!m_fan_panel->IsShown())
m_fan_panel->Show();
bool is_suppt_part_fun = true;
bool is_suppt_aux_fun = obj->GetFan()->GetSupportAuxFanData();
bool is_suppt_cham_fun = obj->GetFan()->GetSupportChamberFan();
if (m_fan_control_popup) { m_fan_control_popup->update_fan_data(obj); }
} else {
if (m_fan_panel->IsShown()) {
m_fan_panel->Hide();
}
if (m_fan_control_popup && m_fan_control_popup->IsShown())
m_fan_control_popup->Hide();
}
obj->is_series_o() ? m_switch_fan->UseTextAirCondition() : m_switch_fan->UseTextFan();
//update cham fan
/*other*/
bool light_on = obj->GetLamp()->IsChamberLightOn();
BOOST_LOG_TRIVIAL(trace) << "light: " << (light_on ? "on" : "off");
if (m_switch_lamp_timeout > 0)
m_switch_lamp_timeout--;
else {
m_switch_lamp->SetValue(light_on);
/*wxString label = light_on ? "On" : "Off";
m_switch_lamp->SetLabels(label, label);*/
}
if (speed_lvl_timeout > 0)
speed_lvl_timeout--;
else {
// update speed
this->speed_lvl = obj->GetPrintingSpeedLevel();
wxString text_speed = wxString::Format("%d%%", obj->printing_speed_mag);
m_switch_speed->SetLabels(text_speed, text_speed);
}
}
void StatusPanel::update_extruder_status(MachineObject* obj)
{
if (!obj) return;
}
void StatusPanel::update_ams(MachineObject *obj)
{
// update obj in sub dlg
if (m_ams_setting_dlg && m_ams_setting_dlg->IsShown()) {
m_ams_setting_dlg->UpdateByObj(obj);
}
if (m_filament_setting_dlg) { m_filament_setting_dlg->obj = obj; }
if (obj && (obj->last_cali_version != obj->cali_version) && (obj->is_lan_mode_printer() || obj->is_security_control_ready())) {
obj->last_cali_version = obj->cali_version;
PACalibExtruderInfo cali_info;
cali_info.nozzle_diameter = obj->GetExtderSystem()->GetNozzleDiameter(0);
cali_info.use_extruder_id = false;
cali_info.use_nozzle_volume_type = false;
CalibUtils::emit_get_PA_calib_infos(cali_info);
}
bool is_support_virtual_tray = obj->ams_support_virtual_tray;
bool is_support_filament_backup = obj->is_support_filament_backup;
if (obj && (obj->is_lan_mode_printer() || obj->is_security_control_ready())) {
obj->check_ams_filament_valid();
}
AMSModel ams_mode = AMSModel::GENERIC_AMS;
if ((obj->is_enable_np || obj->is_enable_ams_np) && obj->GetFilaSystem()->GetAmsList().size() > 0) {
ams_mode = AMSModel(obj->GetFilaSystem()->GetAmsList().begin()->second->GetAmsType());
} else if (obj->get_printer_ams_type() == "f1") {
ams_mode = AMSModel::AMS_LITE; // STUDIO-14066
}
if (!obj || !obj->is_connected()) {
last_tray_exist_bits = -1;
last_ams_exist_bits = -1;
last_tray_is_bbl_bits = -1;
last_read_done_bits = -1;
last_reading_bits = -1;
last_ams_version = -1;
BOOST_LOG_TRIVIAL(trace) << "machine object" << obj->get_dev_name() << " was disconnected, set show_ams_group is false";
m_ams_control->SetAmsModel(AMSModel::EXT_AMS, ams_mode);
show_ams_group(false);
show_filament_load_group(false);
m_ams_control->show_auto_refill(false);
} else {
m_ams_control->SetAmsModel(ams_mode, ams_mode);
m_filament_step->SetAmsModel(ams_mode, ams_mode);
show_ams_group(true);
//show_filament_load_group(true);
if (obj->GetFilaSystem()->GetAmsList().empty() || obj->ams_exist_bits == 0) {
m_ams_control->show_auto_refill(false);
} else {
m_ams_control->show_auto_refill(true);
}
}
//if (is_support_virtual_tray) m_ams_control->update_vams_kn_value(obj->vt_slot[0], obj);
if (m_filament_setting_dlg) m_filament_setting_dlg->update();
std::vector<AMSinfo> ams_info;
const auto& ams_list = obj->GetFilaSystem()->GetAmsList();
for (auto ams = ams_list.begin(); ams != ams_list.end(); ams++) {
AMSinfo info;
info.ams_id = ams->first;
if (ams->second->IsExist() && info.parse_ams_info(obj, ams->second, obj->GetFilaSystem()->IsDetectRemainEnabled(), obj->is_support_ams_humidity)) {
ams_info.push_back(info);
}
}
std::vector<AMSinfo> ext_info;
ext_info.clear();
for (auto slot : obj->vt_slot) {
AMSinfo info;
info.parse_ext_info(obj, slot);
if (ams_mode == AMSModel::AMS_LITE) info.ext_type = AMSModelOriginType::LITE_EXT;
ext_info.push_back(info);
}
// must select a current can
m_ams_control->UpdateAms(obj->get_printer_series_str(), obj->printer_type, ams_info, ext_info, *obj->GetExtderSystem(), obj->get_dev_id(), obj, false);
m_ams_control->UpdateAmsDryControl(obj);
last_tray_exist_bits = obj->tray_exist_bits;
last_ams_exist_bits = obj->ams_exist_bits;
last_tray_is_bbl_bits = obj->tray_is_bbl_bits;
last_read_done_bits = obj->tray_read_done_bits;
last_reading_bits = obj->tray_reading_bits;
last_ams_version = obj->ams_version;
std::string curr_ams_id = m_ams_control->GetCurentAms();
std::string curr_can_id = m_ams_control->GetCurrentCan(curr_ams_id);
bool is_vt_tray = false;
if (obj->GetExtderSystem()->GetCurrentAmsId() == std::to_string(VIRTUAL_TRAY_MAIN_ID)) is_vt_tray = true;
// set segment 1, 2
//if (!obj->is_enable_np) {
// if (obj->m_tray_now == std::to_string(255) || obj->m_tray_now == std::to_string(254)) {
// m_ams_control->SetAmsStep(obj->m_extder_data.extders[MAIN_NOZZLE_ID].snow.ams_id, obj->m_extder_data.extders[MAIN_NOZZLE_ID].snow.slot_id, AMSPassRoadType::AMS_ROAD_TYPE_UNLOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_NONE);
// } else {
// /*if (obj->m_tray_now != "255" && obj->is_filament_at_extruder() && !obj->m_tray_id.empty()) {
// m_ams_control->SetAmsStep(obj->m_extder_data.extders[MAIN_NOZZLE_ID].snow.ams_id, obj->m_extder_data.extders[MAIN_NOZZLE_ID].snow.slot_id,
// AMSPassRoadType::AMS_ROAD_TYPE_LOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_COMBO_LOAD_STEP2);
// } else if (obj->m_tray_now != "255") {
// m_ams_control->SetAmsStep(obj->m_extder_data.extders[MAIN_NOZZLE_ID].snow.ams_id, obj->m_extder_data.extders[MAIN_NOZZLE_ID].snow.slot_id,
// AMSPassRoadType::AMS_ROAD_TYPE_LOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_COMBO_LOAD_STEP1);
// } else {
// m_ams_control->SetAmsStep(obj->m_extder_data.extders[MAIN_NOZZLE_ID].snow.ams_id, obj->m_extder_data.extders[MAIN_NOZZLE_ID].snow.slot_id,
// AMSPassRoadType::AMS_ROAD_TYPE_UNLOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_NONE);
// }*/
// if () {
// }
// }
// m_ams_control->SetExtruder(obj->is_filament_at_extruder(), obj->m_extder_data.extders[MAIN_NOZZLE_ID].snow.ams_id, obj->m_extder_data.extders[MAIN_NOZZLE_ID].snow.slot_id);
//} else {
/*right*/
if (obj->GetExtderSystem()->GetTotalExtderCount() > 0) {
auto ext = obj->GetExtderSystem()->GetExtderById(MAIN_EXTRUDER_ID);
if (ext->HasFilamentInExt()) {
if (ext->GetSlotNow().ams_id == std::to_string(VIRTUAL_TRAY_MAIN_ID) || ext->GetSlotNow().ams_id == std::to_string(VIRTUAL_TRAY_DEPUTY_ID)) {
m_ams_control->SetAmsStep(ext->GetSlotNow().ams_id, "0", AMSPassRoadType::AMS_ROAD_TYPE_LOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_COMBO_LOAD_STEP3);
} else {
m_ams_control->SetAmsStep(ext->GetSlotNow().ams_id, ext->GetSlotNow().slot_id, AMSPassRoadType::AMS_ROAD_TYPE_LOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_COMBO_LOAD_STEP2);
}
} else {
m_ams_control->SetAmsStep(ext->GetSlotNow().ams_id, ext->GetSlotNow().slot_id, AMSPassRoadType::AMS_ROAD_TYPE_UNLOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_NONE);
}
m_ams_control->SetExtruder(ext->HasFilamentInExt(), MAIN_EXTRUDER_ID, ext->GetSlotNow().ams_id, ext->GetSlotNow().slot_id);
}
/*left*/
if (obj->GetExtderSystem()->GetTotalExtderCount() > 1) {
auto ext = obj->GetExtderSystem()->GetExtderById(DEPUTY_EXTRUDER_ID);
if (ext->HasFilamentInExt()) {
if (ext->GetSlotNow().ams_id == std::to_string(VIRTUAL_TRAY_MAIN_ID) || ext->GetSlotNow().ams_id == std::to_string(VIRTUAL_TRAY_DEPUTY_ID)) {
m_ams_control->SetAmsStep(ext->GetSlotNow().ams_id, "0", AMSPassRoadType::AMS_ROAD_TYPE_LOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_COMBO_LOAD_STEP3);
} else {
m_ams_control->SetAmsStep(ext->GetSlotNow().ams_id, ext->GetSlotNow().slot_id, AMSPassRoadType::AMS_ROAD_TYPE_LOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_COMBO_LOAD_STEP2);
}
} else {
m_ams_control->SetAmsStep(ext->GetSlotNow().ams_id, ext->GetSlotNow().slot_id, AMSPassRoadType::AMS_ROAD_TYPE_UNLOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_NONE);
}
m_ams_control->SetExtruder(ext->HasFilamentInExt(), DEPUTY_EXTRUDER_ID, ext->GetSlotNow().ams_id, ext->GetSlotNow().slot_id);
}
update_filament_loading_panel(obj);
const auto& amslist = obj->GetFilaSystem()->GetAmsList();
for (auto ams_it = amslist.begin(); ams_it != amslist.end(); ams_it++) {
std::string ams_id = ams_it->first;
try {
int ams_id_int = atoi(ams_id.c_str());
for (auto tray_it = ams_it->second->GetTrays().begin(); tray_it != ams_it->second->GetTrays().end(); tray_it++) {
std::string tray_id = tray_it->first;
int tray_id_int = atoi(tray_id.c_str());
// new protocol
if (ams_id_int < 128) {
if (ams_it->second->IsAmsLiteMixed()) {
// Mixed AMS-Lite (A2L / N9) RFID-reading bits occupy positions 24..27.
if ((obj->tray_reading_bits & (1 << (AMS_LITE_MIXED_TRAY_INDEX_OFFSET + tray_id_int))) != 0) {
m_ams_control->PlayRridLoading(ams_id, tray_id);
} else {
m_ams_control->StopRridLoading(ams_id, tray_id);
}
} else if ((obj->tray_reading_bits & (1 << (ams_id_int * 4 + tray_id_int))) != 0) {
m_ams_control->PlayRridLoading(ams_id, tray_id);
} else {
m_ams_control->StopRridLoading(ams_id, tray_id);
}
} else {
int check_flag = (1 << (16 + ams_id_int - 128));
if ((obj->tray_reading_bits & check_flag) != 0) {
m_ams_control->PlayRridLoading(ams_id, tray_id);
} else {
m_ams_control->StopRridLoading(ams_id, tray_id);
}
}
}
} catch (...) {}
}
update_ams_control_state(curr_ams_id, curr_can_id);
}
void StatusPanel::update_ams_control_state(std::string ams_id, std::string slot_id)
{
wxString load_error_info, unload_error_info;
if (obj->is_in_printing() && !obj->can_resume()) {
load_error_info = _L("The printer is busy with another print job.");
unload_error_info = _L("The printer is busy with another print job.");
} else if (obj->can_resume() && !devPrinterUtil::IsVirtualSlot(ams_id)) {
load_error_info = _L("When printing is paused, filament loading and unloading are only supported for external slots.");
unload_error_info = _L("When printing is paused, filament loading and unloading are only supported for external slots.");
} else {
/*switch now*/
bool in_switch_filament = false;
if (obj->is_enable_np) {
if (obj->GetExtderSystem()->IsBusyLoading()) { in_switch_filament = true; }
} else if (obj->ams_status_main == AMS_STATUS_MAIN_FILAMENT_CHANGE) {
in_switch_filament = true;
}
if (in_switch_filament) {
load_error_info = _L("Current extruder is busy changing filament.");
unload_error_info = _L("Current extruder is busy changing filament.");
}
if (ams_id.empty() || slot_id.empty()) {
load_error_info = _L("Choose an AMS slot then press \"Load\" or \"Unload\" button to automatically load or unload filament.");
unload_error_info = _L("Choose an AMS slot then press \"Load\" or \"Unload\" button to automatically load or unload filament.");
} else if (obj->GetFilaSwitch()->IsInstalled() && devPrinterUtil::IsVirtualSlot(ams_id)) {
// Orca: with a Filament Track Switch installed the external spool cannot be routed, so both actions are blocked.
load_error_info = _L("\"Load\" or \"Unload\" is not supported for external spool while using Filament Track Switch.");
unload_error_info = load_error_info;
} else if (obj->GetFilaSwitch()->IsInstalled() && !obj->GetFilaSwitch()->IsReady()) {
// Orca: an un-calibrated Filament Track Switch cannot route filament to either extruder, so block both actions.
load_error_info = _L("The Filament Track Switch has not been setup. Please setup on printer.");
unload_error_info = load_error_info;
} else if (ams_id == std::to_string(VIRTUAL_TRAY_MAIN_ID) || ams_id == std::to_string(VIRTUAL_TRAY_DEPUTY_ID)) {
for (auto ext : obj->GetExtderSystem()->GetExtruders()) {
if (ext.GetSlotNow().ams_id == ams_id && ext.GetSlotNow().slot_id == slot_id)
{
load_error_info = _L("Current slot has already been loaded.");
}
}
} else {
for (auto ext : obj->GetExtderSystem()->GetExtruders()) {
// Orca: with a Filament Track Switch installed a slot is not bound to a single extruder, so skip the "already loaded" identity check.
if (obj->GetFilaSwitch()->IsInstalled()) { continue; }
if (ext.GetSlotNow().ams_id == ams_id && ext.GetSlotNow().slot_id == slot_id)
{
load_error_info = _L("Current slot has already been loaded.");
}
}
/*empty*/
auto ams_item = obj->GetFilaSystem()->GetAmsById(ams_id);
if (!ams_item)
{
load_error_info = _L("Choose an AMS slot then press \"Load\" or \"Unload\" button to automatically load or unload filament.");
}
else
{
auto tray_item = ams_item->GetTray(slot_id);
if (!tray_item)
{
load_error_info = _L("Choose an AMS slot then press \"Load\" or \"Unload\" button to automatically load or unload filament.");
}
else if (!tray_item->is_exists)
{
load_error_info = _L("The selected slot is empty.");
}
}
}
}
m_ams_control->EnableLoadFilamentBtn(load_error_info.empty(), ams_id, slot_id, load_error_info);
m_ams_control->EnableUnLoadFilamentBtn(unload_error_info.empty(), ams_id, slot_id,unload_error_info);
}
void StatusPanel::update_cali(MachineObject *obj)
{
if (!obj) return;
// disable calibration button in 2D
if (!obj->is_fdm_type()) {
m_calibration_btn->SetToolTip(_L("Printer 2D mode does not support 3D calibration"));
m_calibration_btn->SetLabel(_L("Calibration"));
m_calibration_btn->Disable();
return;
} else if (!m_calibration_btn->IsEnabled()) {
m_calibration_btn->SetToolTip(wxEmptyString);
m_calibration_btn->Enable();
}
if (obj->is_calibration_running()) {
m_calibration_btn->SetLabel(_L("Calibrating"));
if (calibration_dlg && calibration_dlg->IsShown()) {
m_calibration_btn->Disable();
} else {
m_calibration_btn->Enable();
}
} else {
// IDLE
m_calibration_btn->SetLabel(_L("Calibration"));
// disable in printing
if (obj->is_in_printing()) {
m_calibration_btn->Disable();
} else {
m_calibration_btn->Enable();
}
}
}
void StatusPanel::update_calib_bitmap() {
m_current_print_mode = PrintingTaskType::NOT_CLEAR; //printing task might be changed when updating.
if (calib_bitmap != nullptr) {
delete calib_bitmap;
calib_bitmap = nullptr;
}
}
void StatusPanel::update_basic_print_data(bool def)
{
if (def) {
if (!obj) return;
if (!obj->slice_info) return;
wxString prediction = wxString::Format("%s", get_bbl_time_dhms(obj->slice_info->prediction));
wxString weight = wxString::Format("%.2fg", obj->slice_info->weight);
m_project_task_panel->show_priting_use_info(true, prediction, weight);
}
else {
m_project_task_panel->show_priting_use_info(false, "0m", "0g");
}
}
void StatusPanel::update_model_info()
{
auto get_subtask_fn = [this](BBLModelTask* subtask) {
CallAfter([this, subtask]() {
if (obj && obj->subtask_id_ == subtask->task_id) {
obj->set_modeltask(subtask);
}
});
};
if (wxGetApp().getAgent() && obj) {
BBLSubTask* curr_task = obj->get_subtask();
if (curr_task) {
BBLModelTask* curr_model_task = obj->get_modeltask();
if (!curr_model_task && !request_model_info_flag) {
curr_model_task = new BBLModelTask();
curr_model_task->task_id = curr_task->task_id;
request_model_info_flag = true;
if (!curr_model_task->task_id.empty() && curr_model_task->task_id.compare("0") != 0) {
wxGetApp().getAgent()->get_subtask(curr_model_task, get_subtask_fn);
}
}
}
}
}
void StatusPanel::update_subtask(MachineObject *obj)
{
if (!obj) return;
if (m_current_print_mode != PRINGINT) {
if (calib_bitmap == nullptr) {
m_calib_mode = get_obj_calibration_mode(obj, m_calib_method, cali_stage);
if (m_calib_mode == CalibMode::Calib_None)
m_current_print_mode = PRINGINT;
// the printing task is calibrattion, not normal printing.
else if (m_calib_mode != CalibMode::Calib_None) {
m_current_print_mode = CALIBRATION;
auto get_bitmap = [](wxString& png_path, int width, int height) {
wxImage image(width, height);
image.LoadFile(png_path, wxBITMAP_TYPE_PNG);
image = image.Scale(width, height, wxIMAGE_QUALITY_NORMAL);
return wxBitmap(image);
};
wxString png_path = "";
int width = m_project_task_panel->get_bitmap_thumbnail()->GetSize().x;
int height = m_project_task_panel->get_bitmap_thumbnail()->GetSize().y;
if (m_calib_method == CALI_METHOD_AUTO || m_calib_method == CalibrationMethod::CALI_METHOD_NEW_AUTO) {
std::string image_name = obj->get_auto_pa_cali_thumbnail_img_str();
if (m_calib_mode == CalibMode::Calib_PA_Line) {
if (obj->is_multi_extruders()) {
int cur_ext_id = obj->GetExtderSystem()->GetCurrentExtderId();
if (cur_ext_id == 0) {
image_name += "_right";
}
else {
image_name += "_left";
}
}
png_path = (boost::format("%1%/images/%2%.png") % resources_dir() % image_name).str();
}
else if (m_calib_mode == CalibMode::Calib_Flow_Rate) {
png_path = (boost::format("%1%/images/flow_rate_calibration_auto.png") % resources_dir()).str();
}
}
else if (m_calib_method == CALI_METHOD_MANUAL) {
if (m_calib_mode== CalibMode::Calib_PA_Line) {
if (cali_stage == 0) { // Line mode
png_path = (boost::format("%1%/images/fd_calibration_manual.png") % resources_dir()).str();
}
else if (cali_stage == 1) { // Pattern mode
png_path = (boost::format("%1%/images/fd_pattern_manual_device.png") % resources_dir()).str();
}
}
}
if (png_path != "") {
calib_bitmap = new wxBitmap;
*calib_bitmap = get_bitmap(png_path, width, height);
}
}
}
if (calib_bitmap != nullptr)
m_project_task_panel->set_thumbnail_img(*calib_bitmap, "");
}
m_project_task_panel->show_layers_num(obj->is_support_layer_num);
update_model_info();
update_partskip_button(obj);
update_printer_parts_options(obj);
if (obj->is_system_printing() || obj->is_in_calibration()) {
reset_printing_values();
} else if (obj->is_in_printing() || obj->print_status == "FINISH") {
update_partskip_subtask(obj);
if (obj->is_in_prepare() || obj->print_status == "SLICING") {
m_project_task_panel->market_scoring_hide();
m_project_task_panel->get_request_failed_panel()->Hide();
m_project_task_panel->enable_partskip_button(nullptr, false);
m_project_task_panel->enable_abort_button(false);
m_project_task_panel->enable_pause_resume_button(false, "pause_disable");
wxString prepare_text;
bool show_percent = true;
if (obj->is_in_prepare()) {
prepare_text = wxString::Format(_L("Downloading..."));
}
else if (obj->print_status == "SLICING") {
if (obj->queue_number <= 0) {
prepare_text = wxString::Format(_L("Cloud Slicing..."));
} else {
prepare_text = wxString::Format(_L("In Cloud Slicing Queue, there are %s tasks ahead of you."), std::to_string(obj->queue_number));
show_percent = false;
}
} else
prepare_text = wxString::Format(_L("Downloading..."));
if (obj->gcode_file_prepare_percent >= 0 && obj->gcode_file_prepare_percent <= 100 && show_percent)
prepare_text += wxString::Format("(%d%%)", obj->gcode_file_prepare_percent);
m_project_task_panel->update_stage_value_with_machine(prepare_text, 0, obj);
m_project_task_panel->update_progress_percent(NA_STR, wxEmptyString);
m_project_task_panel->update_left_time(NA_STR);
m_project_task_panel->update_layers_num(true, wxString::Format(_L("Layer: %s"), NA_STR));
m_project_task_panel->update_subtask_name(wxString::Format("%s", GUI::from_u8(obj->subtask_name)));
if (obj->get_modeltask() && obj->get_modeltask()->design_id > 0) {
m_project_task_panel->show_profile_info(true, wxString::FromUTF8(obj->get_modeltask()->profile_name));
}
else {
m_project_task_panel->show_profile_info(false);
}
update_basic_print_data(false);
} else {
if (obj->can_resume()) {
m_project_task_panel->enable_pause_resume_button(true, "resume");
} else {
m_project_task_panel->enable_pause_resume_button(true, "pause");
}
m_project_task_panel->enable_partskip_button(obj, true);
// update printing stage
m_project_task_panel->update_left_time(obj->mc_left_time);
if (obj->subtask_) {
m_project_task_panel->update_stage_value_with_machine(obj->get_curr_stage(), obj->subtask_->task_progress, obj);
m_project_task_panel->update_progress_percent(wxString::Format("%d", obj->subtask_->task_progress), "%");
m_project_task_panel->update_layers_num(true, wxString::Format(_L("Layer: %d/%d"), obj->curr_layer, obj->total_layers));
} else {
m_project_task_panel->update_stage_value_with_machine(obj->get_curr_stage(), 0, obj);
m_project_task_panel->update_progress_percent(NA_STR, wxEmptyString);
m_project_task_panel->update_layers_num(true, wxString::Format(_L("Layer: %s"), NA_STR));
}
if (obj->is_printing_finished()) {
obj->update_model_task();
m_project_task_panel->enable_abort_button(false);
m_project_task_panel->enable_partskip_button(nullptr, false);
m_project_task_panel->enable_pause_resume_button(false, "resume_disable");
// is makeworld subtask
if (wxGetApp().has_model_mall() && obj->is_makeworld_subtask()) {
// has model mall rating result
if (obj && obj->rating_info && obj->rating_info->request_successful) {
m_project_task_panel->get_request_failed_panel()->Hide();
BOOST_LOG_TRIVIAL(info) << "model mall result request successful";
// has start count
if (!m_project_task_panel->get_star_count_dirty()) {
if (obj->rating_info->start_count > 0) {
m_project_task_panel->set_star_count(obj->rating_info->start_count);
m_project_task_panel->set_star_count_dirty(true);
BOOST_LOG_TRIVIAL(info) << "Initialize scores";
m_project_task_panel->get_market_scoring_button()->Enable(true);
m_project_task_panel->set_has_reted_text(true);
} else {
m_project_task_panel->set_star_count(0);
m_project_task_panel->set_star_count_dirty(false);
m_project_task_panel->get_market_scoring_button()->Enable(false);
m_project_task_panel->set_has_reted_text(false);
}
}
m_project_task_panel->market_scoring_show();
} else if (obj && obj->rating_info && !obj->rating_info->request_successful) {
BOOST_LOG_TRIVIAL(info) << "model mall result request failed";
if (403 != obj->rating_info->http_code) {
BOOST_LOG_TRIVIAL(info) << "Request need retry";
m_project_task_panel->get_market_retry_buttom()->Enable(!obj->get_model_mall_result_need_retry);
m_project_task_panel->get_request_failed_panel()->Show();
} else {
BOOST_LOG_TRIVIAL(info) << "Request rejected";
}
}
} else {
m_project_task_panel->market_scoring_hide();
}
} else { // model printing is not finished, hide scoring page
m_project_task_panel->enable_abort_button(true);
m_project_task_panel->market_scoring_hide();
m_project_task_panel->get_request_failed_panel()->Hide();
}
}
m_project_task_panel->update_subtask_name(wxString::Format("%s", GUI::from_u8(obj->subtask_name)));
if (obj->get_modeltask() && obj->get_modeltask()->design_id > 0) {
m_project_task_panel->show_profile_info(true, wxString::FromUTF8(obj->get_modeltask()->profile_name));
}
else {
m_project_task_panel->show_profile_info(false);
}
//update thumbnail
if (obj->is_sdcard_printing()) {
update_basic_print_data(false);
update_sdcard_subtask(obj);
} else {
update_basic_print_data(true);
update_cloud_subtask(obj);
}
} else {
reset_printing_values();
}
}
void StatusPanel::update_partskip_subtask(MachineObject *obj){
if (!obj) return;
if (!obj->subtask_) return;
auto partskip_button = m_project_task_panel->get_partskip_button();
if (partskip_button) {
int part_cnt = 0;
if(m_project_task_panel->get_part_skipped_dirty() > 0){
m_project_task_panel->set_part_skipped_dirty(m_project_task_panel->get_part_skipped_dirty() - 1);
part_cnt = m_project_task_panel->get_part_skipped_count();
BOOST_LOG_TRIVIAL(info) << "part skip: stop recv printer dirty data.";
}else{
part_cnt = obj->m_partskip_ids.size();
BOOST_LOG_TRIVIAL(info) << "part skip: recv printer normal data.";
}
if (part_cnt > 0)
partskip_button->SetLabel(wxString::Format("(%d)", part_cnt));
else
partskip_button->SetLabel("");
}
if(m_partskip_dlg && m_partskip_dlg->IsShown()) {
m_partskip_dlg->UpdatePartsStateFromPrinter(obj);
}
}
void StatusPanel::update_cloud_subtask(MachineObject *obj)
{
if (!obj) return;
if (!obj->subtask_) return;
if (is_task_changed(obj)) {
obj->set_modeltask(nullptr);
obj->free_slice_info();
reset_printing_values();
BOOST_LOG_TRIVIAL(info) << "monitor: change to sub task id = " << obj->subtask_->task_id;
if (web_request.IsOk() && web_request.GetState() == wxWebRequest::State_Active) {
BOOST_LOG_TRIVIAL(info) << "web_request: cancelled";
web_request.Cancel();
}
m_start_loading_thumbnail = true;
}
if (m_start_loading_thumbnail) {
update_calib_bitmap();
if (obj->slice_info) {
m_request_url = wxString(obj->slice_info->thumbnail_url);
if (!m_request_url.IsEmpty()) {
wxImage img;
std::map<wxString, wxImage>::iterator it = img_list.find(m_request_url);
if (it != img_list.end()) {
if (m_current_print_mode != PrintingTaskType::CALIBRATION ||(m_calib_mode == CalibMode::Calib_Flow_Rate && m_calib_method == CalibrationMethod::CALI_METHOD_MANUAL)) {
img = it->second;
wxImage resize_img = img.Scale(m_project_task_panel->get_bitmap_thumbnail()->GetSize().x, m_project_task_panel->get_bitmap_thumbnail()->GetSize().y);
m_project_task_panel->set_thumbnail_img(resize_img, "");
m_project_task_panel->set_brightness_value(get_brightness_value(resize_img));
}
if (this->obj) {
m_project_task_panel->set_plate_index(obj->m_plate_index);
} else {
m_project_task_panel->set_plate_index(-1);
}
task_thumbnail_state = ThumbnailState::TASK_THUMBNAIL;
BOOST_LOG_TRIVIAL(trace) << "web_request: use cache image";
} else {
web_request = wxWebSession::GetDefault().CreateRequest(this, m_request_url);
BOOST_LOG_TRIVIAL(trace) << "monitor: start request thumbnail, url = " << m_request_url;
web_request.Start();
m_start_loading_thumbnail = false;
}
}
}
}
}
void StatusPanel::update_sdcard_subtask(MachineObject *obj)
{
if (!obj) return;
if (!m_load_sdcard_thumbnail) {
update_calib_bitmap();
if (m_current_print_mode != PrintingTaskType::CALIBRATION) {
m_project_task_panel->get_bitmap_thumbnail()->SetBitmap(m_thumbnail_sdcard.bmp());
m_project_task_panel->set_thumbnail_img(m_thumbnail_sdcard.bmp(), m_thumbnail_sdcard.name());
}
task_thumbnail_state = ThumbnailState::SDCARD_THUMBNAIL;
m_load_sdcard_thumbnail = true;
}
}
void StatusPanel::reset_printing_values()
{
m_project_task_panel->enable_partskip_button(nullptr, false);
m_project_task_panel->enable_pause_resume_button(false, "pause_disable");
m_project_task_panel->enable_abort_button(false);
m_project_task_panel->reset_printing_value();
m_project_task_panel->update_subtask_name(NA_STR);
m_project_task_panel->show_profile_info(false);
// m_project_task_panel->update_stage_value_with_machine(wxEmptyString, 0, obj);
m_project_task_panel->update_stage_value_with_machine(wxEmptyString, 0, obj);
//obj->get_curr_stage()
m_project_task_panel->update_progress_percent(NA_STR, wxEmptyString);
m_project_task_panel->market_scoring_hide();
m_project_task_panel->get_request_failed_panel()->Hide();
update_basic_print_data(false);
m_project_task_panel->update_left_time(NA_STR);
m_project_task_panel->update_layers_num(true, wxString::Format(_L("Layer: %s"), NA_STR));
update_calib_bitmap();
task_thumbnail_state = ThumbnailState::PLACE_HOLDER;
m_start_loading_thumbnail = false;
m_load_sdcard_thumbnail = false;
skip_print_error = 0;
this->Layout();
}
void StatusPanel::on_axis_ctrl_xy(wxCommandEvent &event)
{
if (!obj) return;
//check is at home
static std::unordered_set<int> s_x_ctrl_idxes { 1, 3, 5, 7};
static std::unordered_set<int> s_y_ctrl_idxes{ 0, 2, 4, 6 };
if (s_x_ctrl_idxes.count(event.GetInt()) != 0 && !obj->is_axis_at_home("X"))
{
BOOST_LOG_TRIVIAL(info) << "axis x is not at home";
show_recenter_dialog();
return;
}
else if (s_y_ctrl_idxes.count(event.GetInt()) != 0 && !obj->is_axis_at_home("Y"))
{
BOOST_LOG_TRIVIAL(info) << "axis y is not at home";
show_recenter_dialog();
return;
}
if (event.GetInt() == 0) { obj->command_axis_control("Y", 1.0, 10.0f, 3000); }
else if (event.GetInt() == 1) { obj->command_axis_control("X", 1.0, -10.0f, 3000); }
else if (event.GetInt() == 2) { obj->command_axis_control("Y", 1.0, -10.0f, 3000); }
else if (event.GetInt() == 3) { obj->command_axis_control("X", 1.0, 10.0f, 3000); }
else if (event.GetInt() == 4) { obj->command_axis_control("Y", 1.0, 1.0f, 3000); }
else if (event.GetInt() == 5) { obj->command_axis_control("X", 1.0, -1.0f, 3000); }
else if (event.GetInt() == 6) { obj->command_axis_control("Y", 1.0, -1.0f, 3000); }
else if (event.GetInt() == 7) { obj->command_axis_control("X", 1.0, 1.0f, 3000); }
else if (event.GetInt() == 8) {
if (obj) { obj->command_go_home(); }
}
}
bool StatusPanel::check_axis_z_at_home(MachineObject* obj)
{
if (obj) {
if (!obj->is_axis_at_home("Z")) {
BOOST_LOG_TRIVIAL(info) << "axis z is not at home";
show_recenter_dialog();
return false;
}
return true;
}
return false;
}
void StatusPanel::on_axis_ctrl_z_up_10(wxCommandEvent &event)
{
if (obj) {
obj->command_axis_control("Z", 1.0, -10.0f, 900);
if (!check_axis_z_at_home(obj))
return;
}
}
void StatusPanel::on_axis_ctrl_z_up_1(wxCommandEvent &event)
{
if (obj) {
obj->command_axis_control("Z", 1.0, -1.0f, 900);
if (!check_axis_z_at_home(obj))
return;
}
}
void StatusPanel::on_axis_ctrl_z_down_1(wxCommandEvent &event)
{
if (obj) {
obj->command_axis_control("Z", 1.0, 1.0f, 900);
if (!check_axis_z_at_home(obj))
return;
}
}
void StatusPanel::on_axis_ctrl_z_down_10(wxCommandEvent &event)
{
if (obj) {
obj->command_axis_control("Z", 1.0, 10.0f, 900);
if (!check_axis_z_at_home(obj))
return;
}
}
void StatusPanel::axis_ctrl_e_hint(bool up_down)
{
if (ctrl_e_hint_dlg == nullptr) {
/* ctrl_e_hint_dlg = new SecondaryCheckDialog(this->GetParent(), wxID_ANY, _L("Warning"), SecondaryCheckDialog::VisibleButtons::CONFIRM_AND_CANCEL, wxDefaultPosition,
ctrl_e_hint_dlg->update_text(_L("Please heat the nozzle to above 170\u2103 before loading or unloading filament."));
ctrl_e_hint_dlg->m_show_again_checkbox->Hide();
ctrl_e_hint_dlg->m_button_cancel->Hide();
ctrl_e_hint_dlg->m_staticText_release_note->SetMaxSize(wxSize(FromDIP(360), -1));
ctrl_e_hint_dlg->m_staticText_release_note->SetMinSize(wxSize(FromDIP(360), -1));
ctrl_e_hint_dlg->Fit();*/
ctrl_e_hint_dlg = new MessageDialog(this, _L("Please heat the nozzle to above 170\u2103 before loading or unloading filament."), wxString(_L("Warning")), wxOK | wxCENTER);
}
ctrl_e_hint_dlg->ShowModal();
// ctrl_e_hint_dlg->on_show();
}
void StatusPanel::on_axis_ctrl_e_up_10(wxCommandEvent &event)
{
if (obj) {
auto ext = obj->GetExtderSystem()->GetCurrentExtder();
if (ext && ext->GetCurrentTemp() >= TEMP_THRESHOLD_ALLOW_E_CTRL)
if (obj->is_enable_np) {
obj->command_extruder_control(ext->GetExtId(), -10.0f);
} else {
obj->command_axis_control("E", 1.0, -10.0f, 900);
}
else
axis_ctrl_e_hint(true);
}
}
void StatusPanel::on_axis_ctrl_e_down_10(wxCommandEvent &event)
{
if (obj) {
auto ext = obj->GetExtderSystem()->GetCurrentExtder();
if (ext && ext->GetCurrentTemp() >= TEMP_THRESHOLD_ALLOW_E_CTRL)
if (obj->is_enable_np) {
obj->command_extruder_control(ext->GetExtId(), 10.0f);
} else {
obj->command_axis_control("E", 1.0, 10.0f, 900);
}
else
axis_ctrl_e_hint(false);
}
}
void StatusPanel::on_set_bed_temp()
{
if (!obj) {return;}
wxString str = m_tempCtrl_bed->GetTextCtrl()->GetValue();
try {
long bed_temp;
if (str.ToLong(&bed_temp) && obj) {
set_hold_count(m_temp_bed_timeout);
int limit = obj->get_bed_temperature_limit();
if (obj->bed_temp_range.size() > 1) {
limit = obj->bed_temp_range[1];
}
if (bed_temp >= limit) {
BOOST_LOG_TRIVIAL(info) << "can not set over limit = " << limit << ", set temp = " << bed_temp;
bed_temp = limit;
m_tempCtrl_bed->SetTagTemp(wxString::Format("%d", bed_temp));
m_tempCtrl_bed->Warning(false);
}
obj->command_set_bed(bed_temp);
}
} catch (...) {
;
}
}
void StatusPanel::on_set_nozzle_temp(int nozzle_id)
{
if (!obj) {return;}
try {
long nozzle_temp;
if (nozzle_id == MAIN_EXTRUDER_ID) {
wxString str = m_tempCtrl_nozzle->GetTextCtrl()->GetValue();
if (str.ToLong(&nozzle_temp) && obj) {
set_hold_count(m_temp_nozzle_timeout);
if (nozzle_temp > m_tempCtrl_nozzle->get_max_temp()) {
nozzle_temp = m_tempCtrl_nozzle->get_max_temp();
m_tempCtrl_nozzle->SetTagTemp(wxString::Format("%d", nozzle_temp));
m_tempCtrl_nozzle->Warning(false);
}
if (m_tempCtrl_nozzle->GetCurrType() == TempInputType::TEMP_OF_NORMAL_TYPE) {
obj->command_set_nozzle(nozzle_temp);
} else {
obj->command_set_nozzle_new(MAIN_EXTRUDER_ID, nozzle_temp);
}
}
}
if (nozzle_id == DEPUTY_EXTRUDER_ID) {
wxString str = m_tempCtrl_nozzle_deputy->GetTextCtrl()->GetValue();
if (str.ToLong(&nozzle_temp) && obj) {
set_hold_count(m_temp_nozzle_deputy_timeout);
if (nozzle_temp > m_tempCtrl_nozzle_deputy->get_max_temp()) {
nozzle_temp = m_tempCtrl_nozzle_deputy->get_max_temp();
m_tempCtrl_nozzle_deputy->SetTagTemp(wxString::Format("%d", nozzle_temp));
m_tempCtrl_nozzle_deputy->Warning(false);
}
obj->command_set_nozzle_new(DEPUTY_EXTRUDER_ID, nozzle_temp);
}
}
} catch (...) {
;
}
}
void StatusPanel::on_set_chamber_temp()
{
if (!obj) {return;}
wxString str = m_tempCtrl_chamber->GetTextCtrl()->GetValue();
try {
long chamber_temp;
if (str.ToLong(&chamber_temp) && obj) {
set_hold_count(m_temp_chamber_timeout);
if (chamber_temp > m_tempCtrl_chamber->get_max_temp()) {
chamber_temp = m_tempCtrl_chamber->get_max_temp();
m_tempCtrl_chamber->SetTagTemp(wxString::Format("%d", chamber_temp));
m_tempCtrl_chamber->Warning(false);
}
if(obj->is_in_printing() && obj->GetFan()->GetSupportAirduct() && obj->GetFan()->is_at_cooling_mode())
{
#ifndef __APPLE__
MessageDialog champer_switch_head_dlg(this, _L("Chamber temperature cannot be changed in cooling mode while printing."), wxEmptyString, wxICON_WARNING | wxOK);
#else
wxMessageDialog champer_switch_head_dlg(this, _L("Chamber temperature cannot be changed in cooling mode while printing."), wxEmptyString, wxICON_WARNING | wxOK);
#endif
champer_switch_head_dlg.ShowModal();
return;
}
else if (!obj->GetFan()->is_at_heating_mode() && chamber_temp >= obj->GetConfig()->GetChamberTempSwitchHeat())
{
#ifndef __APPLE__
MessageDialog champer_switch_head_dlg(this, _L("If the chamber temperature exceeds 40\u2103, the system will automatically switch to heating mode. "
"Please confirm whether to switch."), wxEmptyString, wxICON_WARNING | wxOK | wxCANCEL);
#else
/*STUDIO-10386 MessageDialog here may cause block in macOS, use wxMessageDialog*/
wxMessageDialog champer_switch_head_dlg(this, _L("If the chamber temperature exceeds 40\u2103, the system will automatically switch to heating mode. "
"Please confirm whether to switch."), wxEmptyString, wxICON_WARNING | wxOK | wxCANCEL);
#endif
if (champer_switch_head_dlg.ShowModal() != wxID_OK) { return; }
}
obj->command_set_chamber(chamber_temp);
}
}
catch (...) {
;
}
}
void StatusPanel::on_ams_load(SimpleEvent &event)
{
BOOST_LOG_TRIVIAL(info) << "on_ams_load";
on_ams_load_curr();
}
void StatusPanel::update_load_with_temp()
{
if (!obj->is_filament_at_extruder()) {
m_is_load_with_temp = true;
}
else {
m_is_load_with_temp = false;
}
}
void StatusPanel::on_ams_load_curr()
{
if (obj) {
std::string curr_ams_id = m_ams_control->GetCurentAms();
std::string curr_can_id = m_ams_control->GetCurrentCan(curr_ams_id);
std::optional<int> extruder_id = std::nullopt;
if (obj->GetFilaSwitch() && obj->GetFilaSwitch()->IsInstalled()) {
if (!obj->GetFilaSwitch()->IsReady()) {
MessageDialog msg_dlg(nullptr, _L("The Filament Track Switch has not been setup. Please setup on printer."), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return;
}
// Filament Track Switch is calibrated: the load can go to either extruder, so ask the
// user which. Record each extruder's currently-loaded slot so the dialog can grey out a
// side that already holds this filament.
std::vector<std::pair<std::string, std::string>> extruderSlots(2, {"", ""});
if (auto ext = obj->GetExtderSystem()->GetExtderById(MAIN_EXTRUDER_ID); ext.has_value())
{
if (ext->HasFilamentInExt())
{
extruderSlots[MAIN_EXTRUDER_ID] = {ext->GetSlotNow().ams_id, ext->GetSlotNow().slot_id};
}
}
if (auto ext = obj->GetExtderSystem()->GetExtderById(DEPUTY_EXTRUDER_ID); ext.has_value())
{
if (ext->HasFilamentInExt())
{
extruderSlots[DEPUTY_EXTRUDER_ID] = {ext->GetSlotNow().ams_id, ext->GetSlotNow().slot_id};
}
}
FeedDirectionDialog dialog(nullptr, 2, obj->printer_type);
dialog.SetExtruderMapping(obj, curr_ams_id, curr_can_id, extruderSlots);
auto rtn = dialog.ShowModal();
if (rtn != wxID_OK)
{
return;
}
extruder_id = dialog.GetExtruderID();
}
update_load_with_temp();
//virtual tray
if (curr_ams_id.compare(std::to_string(VIRTUAL_TRAY_MAIN_ID)) == 0 ||
curr_ams_id.compare(std::to_string(VIRTUAL_TRAY_DEPUTY_ID)) == 0)
{
int vt_slot_idx = 0;
if (curr_ams_id.compare(std::to_string(VIRTUAL_TRAY_DEPUTY_ID)) == 0)
{
vt_slot_idx = 1;
}
int old_temp = -1;
int new_temp = -1;
DevAmsTray* curr_tray = &obj->vt_slot[vt_slot_idx];
if (!curr_tray) return;
try {
if (!curr_tray->nozzle_temp_max.empty() && !curr_tray->nozzle_temp_min.empty())
old_temp = (atoi(curr_tray->nozzle_temp_min.c_str()) + atoi(curr_tray->nozzle_temp_max.c_str())) / 2;
if (!curr_tray->nozzle_temp_max.empty() && !curr_tray->nozzle_temp_min.empty())
new_temp = (atoi(curr_tray->nozzle_temp_min.c_str()) + atoi(curr_tray->nozzle_temp_max.c_str())) / 2;
}
catch (...) {
;
}
if (obj->is_enable_np || obj->is_enable_ams_np) {
try {
if (!curr_ams_id.empty() && !curr_can_id.empty()) {
obj->command_ams_change_filament(true, curr_ams_id, "0", old_temp, new_temp, extruder_id);
}
} catch (...) {}
} else {
obj->command_ams_change_filament(true, "254", "0", old_temp, new_temp, extruder_id);
}
}
std::map<std::string, DevAms*>::iterator it = obj->GetFilaSystem()->GetAmsList().find(curr_ams_id);
if (it == obj->GetFilaSystem()->GetAmsList().end()) {
BOOST_LOG_TRIVIAL(trace) << "ams: find " << curr_ams_id << " failed";
return;
}
auto tray_it = it->second->GetTrays().find(curr_can_id);
if (tray_it == it->second->GetTrays().end()) {
BOOST_LOG_TRIVIAL(trace) << "ams: find " << curr_can_id << " failed";
return;
}
DevAmsTray* curr_tray = obj->get_curr_tray();
DevAmsTray* targ_tray = obj->get_ams_tray(curr_ams_id, curr_can_id);
int old_temp = -1;
int new_temp = -1;
if (curr_tray && targ_tray) {
try {
if (!curr_tray->nozzle_temp_max.empty() && !curr_tray->nozzle_temp_min.empty())
old_temp = (atoi(curr_tray->nozzle_temp_min.c_str()) + atoi(curr_tray->nozzle_temp_max.c_str())) / 2;
if (!targ_tray->nozzle_temp_max.empty() && !targ_tray->nozzle_temp_min.empty())
new_temp = (atoi(targ_tray->nozzle_temp_min.c_str()) + atoi(targ_tray->nozzle_temp_max.c_str())) / 2;
} catch (...) {
;
}
}
int tray_index = atoi(curr_ams_id.c_str()) * 4 + atoi(tray_it->second->id.c_str());
if (obj->is_enable_np) {
try {
if (!curr_ams_id.empty() && !curr_can_id.empty()) {
obj->command_ams_change_filament(true, curr_ams_id, curr_can_id, old_temp, new_temp, extruder_id);
}
}
catch (...){}
} else {
obj->command_ams_change_filament(true, curr_ams_id, curr_can_id, old_temp, new_temp, extruder_id);
}
}
}
void StatusPanel::on_ams_load_vams(wxCommandEvent& event) {
BOOST_LOG_TRIVIAL(info) << "on_ams_load_vams_tray";
m_ams_control->SwitchAms(std::to_string(VIRTUAL_TRAY_MAIN_ID));
on_ams_load_curr();
}
void StatusPanel::on_ams_switch(SimpleEvent &event)
{
if(obj){
/*right*/
if (obj->GetExtderSystem()->GetTotalExtderCount() > 0) {
auto ext = obj->GetExtderSystem()->GetExtderById(MAIN_EXTRUDER_ID);
if (ext->HasFilamentInExt()) {
if (ext->GetSlotNow().ams_id == std::to_string(VIRTUAL_TRAY_MAIN_ID) || ext->GetSlotNow().ams_id == std::to_string(VIRTUAL_TRAY_DEPUTY_ID)) {
m_ams_control->SetAmsStep(ext->GetSlotNow().ams_id, "0", AMSPassRoadType::AMS_ROAD_TYPE_LOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_COMBO_LOAD_STEP3);
} else {
m_ams_control->SetAmsStep(ext->GetSlotNow().ams_id, ext->GetSlotNow().slot_id, AMSPassRoadType::AMS_ROAD_TYPE_LOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_COMBO_LOAD_STEP2);
}
} else {
m_ams_control->SetAmsStep(ext->GetSlotNow().ams_id, ext->GetSlotNow().slot_id, AMSPassRoadType::AMS_ROAD_TYPE_UNLOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_NONE);
}
m_ams_control->SetExtruder(ext->HasFilamentInExt(), MAIN_EXTRUDER_ID, ext->GetSlotNow().ams_id, ext->GetSlotNow().slot_id);
}
/*left*/
if (obj->GetExtderSystem()->GetTotalExtderCount() > 1) {
auto ext = obj->GetExtderSystem()->GetExtruders()[DEPUTY_EXTRUDER_ID];
if (ext.HasFilamentInExt()) {
if (ext.GetSlotNow().ams_id == std::to_string(VIRTUAL_TRAY_MAIN_ID) || ext.GetSlotNow().ams_id == std::to_string(VIRTUAL_TRAY_DEPUTY_ID)) {
m_ams_control->SetAmsStep(ext.GetSlotNow().ams_id, "0", AMSPassRoadType::AMS_ROAD_TYPE_LOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_COMBO_LOAD_STEP3);
} else {
m_ams_control->SetAmsStep(ext.GetSlotNow().ams_id, ext.GetSlotNow().slot_id, AMSPassRoadType::AMS_ROAD_TYPE_LOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_COMBO_LOAD_STEP2);
}
} else {
m_ams_control->SetAmsStep(ext.GetSlotNow().ams_id, ext.GetSlotNow().slot_id, AMSPassRoadType::AMS_ROAD_TYPE_UNLOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_NONE);
}
m_ams_control->SetExtruder(ext.HasFilamentInExt(), DEPUTY_EXTRUDER_ID, ext.GetSlotNow().ams_id, ext.GetSlotNow().slot_id);
}
}
}
void StatusPanel::on_ams_unload(SimpleEvent &event)
{
if (obj) {
std::string curr_ams_id = m_ams_control->GetCurentAms();
std::string curr_can_id = m_ams_control->GetCurrentCan(curr_ams_id);
if (obj->is_enable_np) {
try {
for (auto ext : obj->GetExtderSystem()->GetExtruders()) {
if (ext.GetSlotNow().ams_id == curr_ams_id && ext.GetSlotNow().slot_id == curr_can_id) { obj->command_ams_change_filament(false, curr_ams_id, "255"); }
}
} catch (...) {}
} else {
obj->command_ams_change_filament(false, curr_ams_id, "255");
}
}
}
void StatusPanel::on_ams_filament_backup(SimpleEvent& event)
{
if (obj) {
AmsReplaceMaterialDialog* m_replace_material_popup = new AmsReplaceMaterialDialog(this);
m_replace_material_popup->update_machine_obj(obj);
m_replace_material_popup->ShowModal();
}
}
void StatusPanel::on_ams_setting_click(SimpleEvent &event)
{
if (obj) {
if (!m_ams_setting_dlg) {
m_ams_setting_dlg = new AMSSetting((wxWindow*)this, wxID_ANY);
}
m_ams_setting_dlg->UpdateByObj(obj);
m_ams_setting_dlg->Show();
}
}
void StatusPanel::on_filament_extrusion_cali(wxCommandEvent &event)
{
if (!m_extrusion_cali_dlg)
m_extrusion_cali_dlg = new ExtrusionCalibration((wxWindow*)this, wxID_ANY);
if (obj) {
m_extrusion_cali_dlg->obj = obj;
std::string ams_id = m_ams_control->GetCurentAms();
std::string tray_id = m_ams_control->GetCurrentCan(ams_id);
if (tray_id.empty() && ams_id.compare(std::to_string(VIRTUAL_TRAY_MAIN_ID)) != 0) {
wxString txt = _L("Please select an AMS slot before calibration");
MessageDialog msg_dlg(nullptr, txt, wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return;
}
int ams_id_int = 0;
int tray_id_int = 0;
// set ams_filament id is is bbl filament
if (ams_id.compare(std::to_string(VIRTUAL_TRAY_MAIN_ID)) == 0) {
tray_id_int = VIRTUAL_TRAY_MAIN_ID;
m_extrusion_cali_dlg->ams_filament_id = "";
}
else {
ams_id_int = atoi(ams_id.c_str());
tray_id_int = atoi(tray_id.c_str());
auto tray = obj->GetFilaSystem()->GetAmsTray(ams_id, tray_id);
if (tray) {
if (DevFilaSystem::IsBBL_Filament(tray->tag_uid))
m_extrusion_cali_dlg->ams_filament_id = tray->setting_id;
else
m_extrusion_cali_dlg->ams_filament_id = "";
}
}
try {
m_extrusion_cali_dlg->ams_id = ams_id_int;
m_extrusion_cali_dlg->tray_id = tray_id_int;
m_extrusion_cali_dlg->SetPosition(m_staticText_control->GetScreenPosition());
m_extrusion_cali_dlg->Popup();
} catch(...) {
;
}
}
}
void StatusPanel::on_filament_edit(wxCommandEvent &event)
{
// update params
if (!m_filament_setting_dlg) m_filament_setting_dlg = new AMSMaterialsSetting((wxWindow *) this, wxID_ANY);
int current_position_x = m_ams_control->GetScreenPosition().x;
int current_position_y = m_ams_control->GetScreenPosition().y - FromDIP(40);
auto drect = wxDisplay(GetParent()).GetGeometry().GetHeight() - FromDIP(50);
current_position_y = current_position_y + m_filament_setting_dlg->GetSize().GetHeight() > drect ? drect - m_filament_setting_dlg->GetSize().GetHeight() : current_position_y;
if (obj) {
m_filament_setting_dlg->obj = obj;
// Orca: 2D mode (laser/cut) only allows viewing filament info, not editing
m_filament_setting_dlg->m_view_only = !obj->is_fdm_type();
int ams_id = event.GetInt();
int slot_id = event.GetString().IsEmpty() ? 0 : std::stoi(event.GetString().ToStdString());
try {
m_filament_setting_dlg->ams_id = ams_id;
m_filament_setting_dlg->slot_id = slot_id;
std::string sn_number;
std::string filament;
std::string temp_max;
std::string temp_min;
wxString k_val;
wxString n_val;
auto tray = obj->GetFilaSystem()->GetAmsTray(std::to_string(ams_id), std::to_string(slot_id));
if (tray)
{
k_val = wxString::Format("%.3f", tray->k);
n_val = wxString::Format("%.3f", tray->n);
wxColor color = DevAmsTray::decode_color(tray->color);
// m_filament_setting_dlg->set_color(color);
std::vector<wxColour> cols;
for (auto col : tray->cols) { cols.push_back(DevAmsTray::decode_color(col)); }
m_filament_setting_dlg->set_ctype(tray->ctype);
m_filament_setting_dlg->ams_filament_id = tray->setting_id;
if (m_filament_setting_dlg->ams_filament_id.empty())
{
m_filament_setting_dlg->set_empty_color(color);
}
else
{
m_filament_setting_dlg->set_color(color);
m_filament_setting_dlg->set_colors(cols);
}
m_filament_setting_dlg->m_is_third = !DevFilaSystem::IsBBL_Filament(tray->tag_uid);
if (!m_filament_setting_dlg->m_is_third)
{
sn_number = tray->uuid;
filament = tray->sub_brands;
temp_max = tray->nozzle_temp_max;
temp_min = tray->nozzle_temp_min;
}
}
m_filament_setting_dlg->Move(wxPoint(current_position_x, current_position_y));
m_filament_setting_dlg->Popup(filament, sn_number, temp_min, temp_max, k_val, n_val);
} catch (...) {
;
}
}
}
void StatusPanel::on_ext_spool_edit(wxCommandEvent &event)
{
// update params
if (!m_filament_setting_dlg) m_filament_setting_dlg = new AMSMaterialsSetting((wxWindow*)this, wxID_ANY);
int current_position_x = m_ams_control->GetScreenPosition().x;
int current_position_y = m_ams_control->GetScreenPosition().y - FromDIP(40);
auto drect = wxDisplay(GetParent()).GetGeometry().GetHeight() - FromDIP(50);
current_position_y = current_position_y + m_filament_setting_dlg->GetSize().GetHeight() > drect ? drect - m_filament_setting_dlg->GetSize().GetHeight() : current_position_y;
if (obj) {
m_filament_setting_dlg->obj = obj;
// Orca: 2D mode (laser/cut) only allows viewing filament info, not editing
m_filament_setting_dlg->m_view_only = !obj->is_fdm_type();
int ams_id = event.GetInt();
int slot_id = event.GetString().IsEmpty() ? 0 : std::stoi(event.GetString().ToStdString());
m_filament_setting_dlg->ams_id = ams_id;
m_filament_setting_dlg->slot_id = slot_id;
int nozzle_index = ams_id == VIRTUAL_TRAY_MAIN_ID ? 0 : 1;
try {
std::string sn_number;
std::string filament;
std::string temp_max;
std::string temp_min;
wxString k_val;
wxString n_val;
k_val = wxString::Format("%.3f", obj->vt_slot[nozzle_index].k);
n_val = wxString::Format("%.3f", obj->vt_slot[nozzle_index].n);
wxColor color = DevAmsTray::decode_color(obj->vt_slot[nozzle_index].color);
m_filament_setting_dlg->ams_filament_id = obj->vt_slot[nozzle_index].setting_id;
std::vector<wxColour> cols;
for (auto col : obj->vt_slot[nozzle_index].cols) {
cols.push_back(DevAmsTray::decode_color(col));
}
m_filament_setting_dlg->set_ctype(obj->vt_slot[nozzle_index].ctype);
if (m_filament_setting_dlg->ams_filament_id.empty()) {
m_filament_setting_dlg->set_empty_color(color);
}
else {
m_filament_setting_dlg->set_color(color);
m_filament_setting_dlg->set_colors(cols);
}
m_filament_setting_dlg->m_is_third = !DevFilaSystem::IsBBL_Filament(obj->vt_slot[nozzle_index].tag_uid);
if (!m_filament_setting_dlg->m_is_third) {
sn_number = obj->vt_slot[nozzle_index].uuid;
filament = obj->vt_slot[nozzle_index].sub_brands;
temp_max = obj->vt_slot[nozzle_index].nozzle_temp_max;
temp_min = obj->vt_slot[nozzle_index].nozzle_temp_min;
}
m_filament_setting_dlg->Move(wxPoint(current_position_x,current_position_y));
m_filament_setting_dlg->Popup(filament, sn_number, temp_min, temp_max, k_val, n_val);
}
catch (...) {
;
}
}
}
void StatusPanel::on_ams_refresh_rfid(wxCommandEvent &event)
{
if (obj) {
//std::string curr_ams_id = m_ams_control->GetCurentAms();
if (event.GetInt() < 0 || event.GetInt() > VIRTUAL_TRAY_MAIN_ID){
return;
}
std::string curr_ams_id = std::to_string(event.GetInt());
// do not support refresh rfid for VIRTUAL_TRAY_MAIN_ID
if (curr_ams_id.compare(std::to_string(VIRTUAL_TRAY_MAIN_ID)) == 0) {
return;
}
std::string curr_can_id = event.GetString().ToStdString();
std::map<std::string, DevAms *>::iterator it = obj->GetFilaSystem()->GetAmsList().find(curr_ams_id);
if (it == obj->GetFilaSystem()->GetAmsList().end()) {
BOOST_LOG_TRIVIAL(trace) << "ams: find " << curr_ams_id << " failed";
return;
}
auto slot_it = it->second->GetTrays().find(curr_can_id);
if (slot_it == it->second->GetTrays().end()) {
BOOST_LOG_TRIVIAL(trace) << "ams: find " << curr_can_id << " failed";
return;
}
auto has_filament_at_extruder = false;
auto use_new_command = false;
if (obj->is_enable_np || obj->is_enable_ams_np) {
use_new_command = true;
if (it->second->GetExtruderId() < obj->GetExtderSystem()->GetTotalExtderSize()) {
has_filament_at_extruder = obj->GetExtderSystem()->HasFilamentInExt(it->second->GetExtruderId());
}
} else {
has_filament_at_extruder = obj->is_filament_at_extruder();
}
if (has_filament_at_extruder) {
MessageDialog msg_dlg(nullptr, _L("Cannot read filament info: the filament is loaded to the tool head. Please unload the filament and try again."), wxEmptyString,
wxICON_WARNING | wxYES);
msg_dlg.ShowModal();
return;
}
try {
if (!use_new_command) {
int tray_index = atoi(curr_ams_id.c_str()) * 4 + atoi(slot_it->second->id.c_str());
obj->command_ams_refresh_rfid(std::to_string(tray_index));
}
if (use_new_command) {
obj->command_ams_refresh_rfid2(stoi(curr_ams_id), stoi(curr_can_id));
}
} catch (...) {
;
}
}
}
void StatusPanel::on_ams_selected(wxCommandEvent &event)
{
if (obj) {
std::string curr_ams_id = m_ams_control->GetCurentAms();
std::string curr_selected_ams_id = std::to_string(event.GetInt());
if (curr_ams_id.compare(std::to_string(VIRTUAL_TRAY_MAIN_ID)) == 0) {
return;
} else {
std::string curr_can_id = event.GetString().ToStdString();
std::map<std::string, DevAms *>::iterator it = obj->GetFilaSystem()->GetAmsList().find(curr_ams_id);
if (it == obj->GetFilaSystem()->GetAmsList().end()) {
BOOST_LOG_TRIVIAL(trace) << "ams: find " << curr_ams_id << " failed";
return;
}
auto tray_it = it->second->GetTrays().find(curr_can_id);
if (tray_it == it->second->GetTrays().end()) {
BOOST_LOG_TRIVIAL(trace) << "ams: find " << curr_can_id << " failed";
return;
}
try {
int tray_index = atoi(curr_ams_id.c_str()) * 4 + atoi(tray_it->second->id.c_str());
obj->command_ams_select_tray(std::to_string(tray_index));
} catch (...) {
;
}
}
}
}
void StatusPanel::on_ams_guide(wxCommandEvent& event)
{
// Orca: neutral wiki link (vendor URLs removed)
wxString ams_wiki_url = "https://www.orcaslicer.com/wiki/";
wxLaunchDefaultBrowser(ams_wiki_url);
}
void StatusPanel::on_ams_retry(wxCommandEvent& event)
{
BOOST_LOG_TRIVIAL(info) << "on_ams_retry";
if (obj) {
obj->command_ams_control("resume");
}
}
void StatusPanel::on_fan_changed(wxCommandEvent& event)
{
auto type = event.GetInt();
auto speed = atoi(event.GetString().c_str());
set_hold_count(this->m_switch_cham_fan_timeout);
}
void StatusPanel::on_cham_temp_kill_focus(wxFocusEvent& event)
{
event.Skip();
cham_temp_input = false;
}
void StatusPanel::on_cham_temp_set_focus(wxFocusEvent& event)
{
event.Skip();
cham_temp_input = true;
}
void StatusPanel::on_bed_temp_kill_focus(wxFocusEvent &event)
{
event.Skip();
bed_temp_input = false;
}
void StatusPanel::on_bed_temp_set_focus(wxFocusEvent &event)
{
event.Skip();
bed_temp_input = true;
}
void StatusPanel::on_nozzle_temp_kill_focus(wxFocusEvent &event)
{
event.Skip();
nozzle_temp_input = false;
}
void StatusPanel::on_nozzle_temp_set_focus(wxFocusEvent &event)
{
event.Skip();
nozzle_temp_input = true;
}
void StatusPanel::on_switch_speed(wxCommandEvent &event)
{
auto now = boost::posix_time::microsec_clock::universal_time();
if ((now - speed_dismiss_time).total_milliseconds() < 200) {
speed_dismiss_time = now - boost::posix_time::seconds(1);
return;
}
#if __WXOSX__
// MacOS has focus problem
PopupWindow *popUp = new PopupWindow(nullptr);
#else
PopupWindow *popUp = new PopupWindow(m_switch_speed);
#endif
#ifdef __WXMSW__
popUp->BindUnfocusEvent();
#endif
popUp->SetBackgroundColour(StateColor::darkModeColorFor(0xeeeeee));
StepCtrl *step = new StepCtrl(popUp, wxID_ANY);
wxSizer *sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(step, 1, wxEXPAND, 0);
popUp->SetSizer(sizer);
auto em = em_unit(this);
popUp->SetSize(em * 36, em * 8);
step->SetHint(_L("This only takes effect during printing"));
step->AppendItem(_L("Silent"), "");
step->AppendItem(_L("Standard"), "");
step->AppendItem(_L("Sport"), "");
step->AppendItem(_L("Ludicrous"), "");
// default speed lvl
int selected_item = 1;
if (obj) {
int speed_lvl_idx = obj->GetPrintingSpeedLevel() - 1;
if (speed_lvl_idx >= 0 && speed_lvl_idx < 4) {
selected_item = speed_lvl_idx;
}
}
step->SelectItem(selected_item);
if (!obj->is_in_printing()) {
step->Bind(wxEVT_LEFT_DOWN, [](auto& e) {
return; });
}
step->Bind(EVT_STEP_CHANGED, [this](auto &e) {
this->speed_lvl = e.GetInt() + 1;
if (obj) {
set_hold_count(this->speed_lvl_timeout);
obj->command_set_printing_speed((DevPrintingSpeedLevel)this->speed_lvl);
}
});
popUp->Bind(wxEVT_SHOW, [this, popUp](auto &e) {
if (!e.IsShown()) {
popUp->Destroy();
speed_dismiss_time = boost::posix_time::microsec_clock::universal_time();
}
});
wxPoint pos = m_switch_speed->ClientToScreen(wxPoint(0, -6));
popUp->Position(pos, {0, m_switch_speed->GetSize().y + 12});
popUp->Popup();
}
void StatusPanel::on_printing_fan_switch(wxCommandEvent &event)
{
/* if (!obj) return;
bool value = m_switch_printing_fan->GetValue();
if (value) {
obj->command_control_fan(MachineObject::FanType::BIG_COOLING_FAN, true);
m_switch_printing_fan->SetValue(true);
set_hold_count(this->m_switch_printing_fan_timeout);
} else {
obj->command_control_fan(MachineObject::FanType::BIG_COOLING_FAN, false);
m_switch_printing_fan->SetValue(false);
set_hold_count(this->m_switch_printing_fan_timeout);
}*/
}
void StatusPanel::on_nozzle_fan_switch(wxCommandEvent &event)
{
if (m_fan_control_popup) {
m_fan_control_popup->Destroy();
m_fan_control_popup = nullptr;
}
if (!obj) { return; }
if (obj->GetFan()->GetAirDuctData().modes.empty())
{
obj->GetFan()->converse_to_duct(true, obj->GetFan()->GetSupportAuxFanData(), obj->GetFan()->GetSupportChamberFan());
}
m_fan_control_popup = new FanControlPopupNew(this, obj, obj->GetFan()->GetAirDuctData());
auto pos = m_switch_fan->GetScreenPosition();
pos.y = pos.y + m_switch_fan->GetSize().y;
int display_idx = wxDisplay::GetFromWindow(this);
auto display = wxDisplay(display_idx).GetClientArea();
wxSize screenSize = wxSize(display.GetWidth(), display.GetHeight());
wxSize fan_popup_size = m_fan_control_popup->GetSize();
pos.x -= FromDIP(150);
pos.y -= FromDIP(20);
if (screenSize.y - fan_popup_size.y < FromDIP(300)) {
pos.y = (screenSize.y - fan_popup_size.y) / 2;
}
m_fan_control_popup->SetPosition(pos);
m_fan_control_popup->ShowModal();
}
void StatusPanel::on_lamp_switch(wxCommandEvent &event)
{
if (!obj) return;
bool value = m_switch_lamp->GetValue();
if (value) {
m_switch_lamp->SetValue(true);
// do not update when timeout > 0
set_hold_count(this->m_switch_lamp_timeout);
obj->GetLamp()->CtrlSetChamberLight(DevLamp::LIGHT_EFFECT_ON);
} else {
if (obj->GetLamp()->HasLampCloseRecheck()){
MessageDialog msg_dlg(nullptr, _L("Turning off the lights during the task will cause the failure of AI monitoring, like spaghetti detection. Please choose carefully."), wxEmptyString, wxICON_WARNING | wxOK | wxCANCEL);
msg_dlg.SetButtonLabel(wxID_OK, _L("Keep it On"));
msg_dlg.SetButtonLabel(wxID_CANCEL, _L("Turn it Off"));
if (msg_dlg.ShowModal() != wxID_CANCEL) {
return;
}
}
m_switch_lamp->SetValue(false);
set_hold_count(this->m_switch_lamp_timeout);
obj->GetLamp()->CtrlSetChamberLight(DevLamp::LIGHT_EFFECT_OFF);
}
}
void StatusPanel::on_switch_vcamera(wxMouseEvent &event)
{
//if (!obj) return;
//bool value = m_recording_button->get_switch_status();
//obj->command_ipcam_record(!value);
m_media_play_ctrl->ToggleStream();
show_vcamera = m_media_play_ctrl->IsStreaming();
if (m_camera_popup)
m_camera_popup->sync_vcamera_state(show_vcamera);
}
void StatusPanel::on_camera_enter(wxMouseEvent& event)
{
if (obj) {
if (m_camera_popup == nullptr)
m_camera_popup = std::make_shared<CameraPopup>(this);
m_camera_popup->check_func_supported(obj);
m_camera_popup->sync_vcamera_state(show_vcamera);
m_camera_popup->Bind(EVT_VCAMERA_SWITCH, &StatusPanel::on_switch_vcamera, this);
m_camera_popup->Bind(EVT_SDCARD_ABSENT_HINT, [this](wxCommandEvent &e) {
if (sdcard_hint_dlg == nullptr) {
sdcard_hint_dlg = new SecondaryCheckDialog(this->GetParent(), wxID_ANY, _L("Warning"), SecondaryCheckDialog::VisibleButtons::ONLY_CONFIRM); // ORCA VisibleButtons instead ButtonStyle
sdcard_hint_dlg->update_text(_L("Can't start this without storage."));
}
sdcard_hint_dlg->on_show();
});
m_camera_popup->Bind(EVT_CAM_SOURCE_CHANGE, &StatusPanel::on_camera_source_change, this);
wxWindow* ctrl = (wxWindow*)event.GetEventObject();
wxPoint pos = ctrl->ClientToScreen(wxPoint(0, 0));
wxSize sz = ctrl->GetSize();
pos.x += sz.x;
pos.y += sz.y;
m_camera_popup->SetPosition(pos);
m_camera_popup->update(m_media_play_ctrl->IsStreaming());
m_camera_popup->Popup();
}
}
void StatusBasePanel::on_camera_source_change(wxCommandEvent& event)
{
handle_camera_source_change();
}
void StatusBasePanel::handle_camera_source_change()
{
const auto new_cam_url = wxGetApp().app_config->get("camera", "custom_source");
const auto enabled = wxGetApp().app_config->get("camera", "enable_custom_source") == "true";
if (enabled && !new_cam_url.empty()) {
m_custom_camera_view->LoadURL(new_cam_url);
toggle_custom_camera();
m_camera_switch_button->Show();
} else {
toggle_builtin_camera();
m_camera_switch_button->Hide();
}
}
void StatusBasePanel::toggle_builtin_camera()
{
m_custom_camera_view->Hide();
m_media_ctrl->Show();
m_media_play_ctrl->Show();
}
void StatusBasePanel::toggle_custom_camera()
{
const auto enabled = wxGetApp().app_config->get("camera", "enable_custom_source") == "true";
if (enabled) {
m_custom_camera_view->Show();
m_media_ctrl->Hide();
m_media_play_ctrl->Hide();
}
}
void StatusBasePanel::on_camera_switch_toggled(wxMouseEvent& event)
{
const auto enabled = wxGetApp().app_config->get("camera", "enable_custom_source") == "true";
if (enabled && m_media_ctrl->IsShown()) {
toggle_custom_camera();
} else {
toggle_builtin_camera();
}
}
void StatusBasePanel::remove_controls()
{
const std::string js_cleanup_video_element = R"(
document.body.style.overflow='hidden';
const video = document.querySelector('video');
video.setAttribute('style', 'width: 100% !important;');
video.removeAttribute('controls');
video.addEventListener('leavepictureinpicture', () => {
window.wx.postMessage('leavepictureinpicture');
});
video.addEventListener('enterpictureinpicture', () => {
window.wx.postMessage('enterpictureinpicture');
});
)";
m_custom_camera_view->RunScript(js_cleanup_video_element);
}
void StatusPanel::on_camera_leave(wxMouseEvent& event)
{
if (obj && m_camera_popup) {
m_camera_popup->Dismiss();
}
}
void StatusPanel::on_auto_leveling(wxCommandEvent &event)
{
if (obj) obj->command_auto_leveling();
}
void StatusPanel::on_xyz_abs(wxCommandEvent &event)
{
if (obj) obj->command_xyz_abs();
}
void StatusPanel::on_nozzle_selected(wxCommandEvent &event)
{
if (obj) {
/*Enable switch head while printing is paused STUDIO-9789*/
if ((obj->is_in_printing() && !obj->is_in_printing_pause()) || obj->ams_status_main == AMS_STATUS_MAIN_FILAMENT_CHANGE) {
MessageDialog dlg(nullptr, _L("The printer is busy with another print job."), _L("Error"), wxICON_WARNING | wxOK);
dlg.ShowModal();
return;
}
auto nozzle_id = event.GetInt();
if (obj->GetCtrl()->command_select_extruder(nozzle_id) == 0)
{
return;
}
}
m_nozzle_btn_panel->Enable();
}
void StatusPanel::on_show_print_options(wxCommandEvent& event)
{
if (obj) {
// Always show print options dialog for all machines
if (print_options_dlg == nullptr) {
print_options_dlg = new PrintOptionsDialog(this);
print_options_dlg->update_machine_obj(obj);
print_options_dlg->update_options(obj);
print_options_dlg->ShowModal();
}
else {
print_options_dlg->update_machine_obj(obj);
print_options_dlg->update_options(obj);
print_options_dlg->ShowModal();
}
}
}
void StatusPanel::on_show_safety_options(wxCommandEvent& event)
{
if (obj) {
std::string current_printer_type = obj->printer_type;
bool supports_safety = DevPrinterConfigUtil::support_safety_options(current_printer_type);
if (supports_safety) {
if (safety_options_dlg == nullptr) {
safety_options_dlg = new SafetyOptionsDialog(this);
safety_options_dlg->update_machine_obj(obj);
safety_options_dlg->update_options(obj);
safety_options_dlg->ShowModal();
}
else {
safety_options_dlg->update_machine_obj(obj);
safety_options_dlg->update_options(obj);
safety_options_dlg->ShowModal();
}
}
}
}
void StatusPanel::on_show_parts_options(wxCommandEvent &event)
{
if (obj) {
if (print_parts_dlg == nullptr) {
print_parts_dlg = new PrinterPartsDialog(this);
print_parts_dlg->update_machine_obj(obj);
print_parts_dlg->ShowModal();
}
else {
print_parts_dlg->update_machine_obj(obj);
print_parts_dlg->ShowModal();
}
}
}
void StatusPanel::update_printer_parts_options(MachineObject* obj_)
{
if(obj_){
if(print_parts_dlg && print_parts_dlg->IsShown()){
print_parts_dlg->update_machine_obj(obj_);
print_parts_dlg->UpdateNozzleInfo();
}
}
}
void StatusPanel::on_start_calibration(wxCommandEvent &event)
{
if (obj) {
if (calibration_dlg == nullptr) {
calibration_dlg = new CalibrationDialog();
calibration_dlg->update_machine_obj(obj);
calibration_dlg->update_cali(obj);
calibration_dlg->ShowModal();
} else {
calibration_dlg->update_machine_obj(obj);
calibration_dlg->update_cali(obj);
calibration_dlg->ShowModal();
}
}
}
bool StatusPanel::is_stage_list_info_changed(MachineObject *obj)
{
if (!obj) return true;
if (last_stage_list_info.size() != obj->stage_list_info.size()) return true;
for (int i = 0; i < last_stage_list_info.size(); i++) {
if (last_stage_list_info[i] != obj->stage_list_info[i]) return true;
}
last_stage_list_info = obj->stage_list_info;
return false;
}
void StatusPanel::set_default()
{
BOOST_LOG_TRIVIAL(trace) << "status_panel: set_default";
obj = nullptr;
last_subtask = nullptr;
last_tray_exist_bits = -1;
speed_lvl = 1;
speed_lvl_timeout = 0;
m_switch_lamp_timeout = 0;
m_temp_nozzle_timeout = 0;
m_temp_nozzle_deputy_timeout = 0;
m_temp_bed_timeout = 0;
m_temp_chamber_timeout = 0;
m_switch_nozzle_fan_timeout = 0;
m_switch_printing_fan_timeout = 0;
m_switch_cham_fan_timeout = 0;
m_show_ams_group = false;
m_show_filament_group = false;
reset_printing_values();
m_bitmap_timelapse_img->Hide();
m_bitmap_recording_img->Hide();
m_bitmap_vcamera_img->Hide();
m_setting_button->Show();
m_tempCtrl_chamber->Show();
m_options_btn->Show();
m_safety_btn->Show();
m_parts_btn->Show();
if (m_panel_control_title) {
m_panel_control_title->Layout();
m_panel_control_title->Refresh();
}
reset_temp_misc_control();
m_extruder_switching_status->Hide();
m_ams_control->Hide();
m_ams_control_box->Hide();
m_ams_control->Reset();
m_ams_rack_switch->updateState("left");
m_ams_rack_switch->Hide();
m_panel_nozzle_rack->Hide();
m_scale_panel->Hide();
m_filament_load_box->Hide();
m_filament_step->Hide();
error_info_reset();
#ifndef __WXGTK__
SetFocus();
#endif
}
void StatusPanel::show_status(int status)
{
if (last_status == status) return;
last_status = status;
if (((status & (int) MonitorStatus::MONITOR_DISCONNECTED) != 0)
|| ((status & (int) MonitorStatus::MONITOR_DISCONNECTED_SERVER) != 0)
|| ((status & (int)MonitorStatus::MONITOR_CONNECTING) != 0)
|| ((status & (int)MonitorStatus::MONITOR_NO_PRINTER) != 0)
) {
show_printing_status(false, false);
m_calibration_btn->Disable();
m_options_btn->Disable();
m_safety_btn->Disable();
m_parts_btn->Disable();
m_panel_monitoring_title->Disable();
} else if ((status & (int) MonitorStatus::MONITOR_NORMAL) != 0) {
show_printing_status(true, true);
m_calibration_btn->Disable();
m_options_btn->Enable();
m_safety_btn->Enable();
m_parts_btn->Enable();
m_panel_monitoring_title->Enable();
}
}
void StatusPanel::set_hold_count(int& count)
{
count = COMMAND_TIMEOUT;
}
void StatusPanel::rescale_camera_icons()
{
if (!GetParent() || IsBeingDeleted()) return;
if (!m_setting_button || !m_media_play_ctrl || !m_bitmap_vcamera_img || !m_bitmap_sdcard_img || !m_bitmap_recording_img || !m_bitmap_timelapse_img) return;
m_setting_button->msw_rescale();
m_bitmap_sdcard_state_abnormal = ScalableBitmap(this, wxGetApp().dark_mode()?"sdcard_state_abnormal_dark":"sdcard_state_abnormal", 20);
m_bitmap_sdcard_state_normal = ScalableBitmap(this, wxGetApp().dark_mode()?"sdcard_state_normal_dark":"sdcard_state_normal", 20);
m_bitmap_sdcard_state_no = ScalableBitmap(this, wxGetApp().dark_mode()?"sdcard_state_no_dark":"sdcard_state_no", 20);
m_bitmap_recording_on = ScalableBitmap(this, wxGetApp().dark_mode()?"monitor_recording_on_dark":"monitor_recording_on", 20);
m_bitmap_recording_off = ScalableBitmap(this, wxGetApp().dark_mode()?"monitor_recording_off_dark":"monitor_recording_off", 20);
m_bitmap_timelapse_on = ScalableBitmap(this, wxGetApp().dark_mode()?"monitor_timelapse_on_dark":"monitor_timelapse_on", 20);
m_bitmap_timelapse_off = ScalableBitmap(this, wxGetApp().dark_mode()?"monitor_timelapse_off_dark":"monitor_timelapse_off", 20);
m_bitmap_vcamera_on = ScalableBitmap(this, wxGetApp().dark_mode()?"monitor_vcamera_on_dark":"monitor_vcamera_on", 20);
m_bitmap_vcamera_off = ScalableBitmap(this, wxGetApp().dark_mode()?"monitor_vcamera_off_dark":"monitor_vcamera_off", 20);
if (m_media_play_ctrl->IsStreaming()) {
m_bitmap_vcamera_img->SetBitmap(m_bitmap_vcamera_on.bmp());
}
else {
m_bitmap_vcamera_img->SetBitmap(m_bitmap_vcamera_off.bmp());
}
if (!obj) return;
if (obj->GetStorage()->get_sdcard_state() == DevStorage::SdcardState::NO_SDCARD) {
m_bitmap_sdcard_img->SetBitmap(m_bitmap_sdcard_state_no.bmp());
} else if (obj->GetStorage()->get_sdcard_state() == DevStorage::SdcardState::HAS_SDCARD_NORMAL) {
m_bitmap_sdcard_img->SetBitmap(m_bitmap_sdcard_state_normal.bmp());
} else if (obj->GetStorage()->get_sdcard_state() == DevStorage::SdcardState::HAS_SDCARD_ABNORMAL) {
m_bitmap_sdcard_img->SetBitmap(m_bitmap_sdcard_state_abnormal.bmp());
} else {
m_bitmap_sdcard_img->SetBitmap(m_bitmap_sdcard_state_normal.bmp());
}
if (obj->is_recording()) {
m_bitmap_recording_img->SetBitmap(m_bitmap_recording_on.bmp());
} else {
m_bitmap_recording_img->SetBitmap(m_bitmap_recording_off.bmp());
}
if (obj->is_timelapse()) {
m_bitmap_timelapse_img->SetBitmap(m_bitmap_timelapse_on.bmp());
} else {
m_bitmap_timelapse_img->SetBitmap(m_bitmap_timelapse_off.bmp());
}
}
void StatusPanel::on_sys_color_changed()
{
m_project_task_panel->msw_rescale();
m_bitmap_speed.msw_rescale();
m_bitmap_speed_active.msw_rescale();
m_switch_speed->SetImages(m_bitmap_speed, m_bitmap_speed);
m_ams_control->msw_rescale();
rescale_camera_icons();
}
void StatusPanel::msw_rescale()
{
init_bitmaps();
m_project_task_panel->init_bitmaps();
m_project_task_panel->msw_rescale();
m_panel_monitoring_title->SetSize(wxSize(-1, FromDIP(PAGE_TITLE_HEIGHT)));
//m_staticText_monitoring->SetMinSize(wxSize(PAGE_TITLE_TEXT_WIDTH, PAGE_TITLE_HEIGHT));
m_bmToggleBtn_timelapse->Rescale();
m_panel_control_title->SetSize(wxSize(-1, FromDIP(PAGE_TITLE_HEIGHT)));
//m_staticText_control->SetMinSize(wxSize(-1, PAGE_TITLE_HEIGHT));
m_media_play_ctrl->msw_rescale();
m_bpButton_xy->SetBitmap(m_bitmap_axis_home);
m_bpButton_xy->SetMinSize(AXIS_MIN_SIZE);
m_bpButton_xy->SetSize(AXIS_MIN_SIZE);
m_temp_extruder_line->SetSize(wxSize(FromDIP(1), -1));
update_extruder_status(obj);
//m_bitmap_extruder_img->SetMinSize(EXTRUDER_IMAGE_SIZE);
for (Button *btn : m_buttons) { btn->Rescale(); }
init_scaled_buttons();
m_bpButton_xy->Rescale();
auto size = TEMP_CTRL_MIN_SIZE_ALIGN_ONE_ICON;
if (obj && obj->GetExtderSystem()->GetTotalExtderCount() >= 2) size = TEMP_CTRL_MIN_SIZE_ALIGN_TWO_ICON;
m_tempCtrl_nozzle->SetMinSize(size);
m_tempCtrl_nozzle->Rescale();
m_tempCtrl_nozzle_deputy->SetMinSize(size);
m_tempCtrl_nozzle_deputy->Rescale();
m_line_nozzle->SetSize(wxSize(-1, FromDIP(1)));
m_tempCtrl_bed->SetMinSize(size);
m_tempCtrl_bed->Rescale();
m_tempCtrl_chamber->SetMinSize(size);
m_tempCtrl_chamber->Rescale();
for(int i = 0; i < m_extruder_book->GetPageCount(); i++)
{
ExtruderImage* ext_img = dynamic_cast<ExtruderImage*> (m_extruder_book->GetPage(i));
if (ext_img)
{
ext_img->msw_rescale();
}
}
m_bitmap_speed.msw_rescale();
m_bitmap_speed_active.msw_rescale();
m_switch_speed->SetImages(m_bitmap_speed, m_bitmap_speed);
m_switch_speed->SetMinSize(MISC_BUTTON_2FAN_SIZE);
m_switch_speed->Rescale();
m_switch_lamp->SetImages(m_bitmap_lamp_on, m_bitmap_lamp_off);
m_switch_lamp->SetMinSize(MISC_BUTTON_2FAN_SIZE);
m_switch_lamp->Rescale();
/*m_switch_nozzle_fan->SetImages(m_bitmap_fan_on, m_bitmap_fan_off);
m_switch_nozzle_fan->Rescale();
m_switch_printing_fan->SetImages(m_bitmap_fan_on, m_bitmap_fan_off);
m_switch_printing_fan->Rescale();
m_switch_cham_fan->SetImages(m_bitmap_fan_on, m_bitmap_fan_off);
m_switch_cham_fan->Rescale();*/
m_switch_fan->SetImages(m_bitmap_fan_on, m_bitmap_fan_off);
m_switch_fan->Rescale();
if (m_fan_control_popup)
{
m_fan_control_popup->msw_rescale();
}
//m_switch_fan->SetImages(m_bitmap_fan_on, m_bitmap_fan_off);
//m_switch_fan->Rescale();
m_bpButton_z_10->Rescale();
m_bpButton_z_1->Rescale();
m_bpButton_z_down_1->Rescale();
m_bpButton_z_down_10->Rescale();
m_extruder_switching_status->msw_rescale();
m_ams_control->msw_rescale();
m_panel_nozzle_rack->Rescale();
// m_filament_step->Rescale();
m_calibration_btn->SetMinSize(wxSize(-1, FromDIP(26)));
m_calibration_btn->Rescale();
m_options_btn->SetMinSize(wxSize(-1, FromDIP(26)));
m_options_btn->Rescale();
m_safety_btn->SetMinSize(wxSize(-1, FromDIP(26)));
m_safety_btn->Rescale();
m_parts_btn->SetMinSize(wxSize(-1, FromDIP(26)));
m_parts_btn->Rescale();
rescale_camera_icons();
Layout();
Refresh();
}
void StatusPanel::update_rack(MachineObject *obj)
{
// Rack switch + live rack panel are shown only for printers whose nozzle system reports a rack
// (H2C). Every other Bambu printer keeps the switch hidden and the panel collapsed -> the AMS
// monitor page is unchanged for X1/P1/A1/H2D/H2S.
if (obj && obj->GetNozzleSystem()->GetNozzleRack()->IsSupported()) {
m_ams_rack_switch->Show();
m_panel_nozzle_rack->UpdateRackInfo(obj->GetNozzleSystem()->GetNozzleRack());
} else {
m_ams_rack_switch->Show(false);
m_panel_nozzle_rack->Show(false);
}
}
void StatusPanel::update_filament_loading_panel(MachineObject* obj)
{
if (!obj) {
show_filament_load_group(false);
return;
}
bool ams_loading_state = false;
auto ams_status_sub = obj->ams_status_sub;
// Skip busy-loading detection during a cold pull.
if (obj->is_enable_np && obj->ams_status_main != AMS_STATUS_MAIN_COLD_PULL) {
ams_loading_state = obj->GetExtderSystem()->IsBusyLoading();
} else if (obj->ams_status_main == AMS_STATUS_MAIN_FILAMENT_CHANGE) {
ams_loading_state = true;
}
if (ams_loading_state) {
update_load_with_temp();
const std::string& cur_ams_id = obj->GetExtderSystem()->GetCurrentAmsId();
const std::string& cur_tray_id = obj->GetExtderSystem()->GetCurrentSlotId();
if (!cur_ams_id.empty() && !cur_tray_id.empty()) {
m_filament_step->updateID(std::atoi(cur_ams_id.c_str()), std::atoi(cur_tray_id.c_str()));
}
auto loading_ext = obj->GetExtderSystem()->GetLoadingExtder();
auto tar = loading_ext ? loading_ext->GetSlotTarget() : DevAmsSlotInfo();
bool busy_for_vt_loading = (tar.ams_id == std::to_string(VIRTUAL_TRAY_MAIN_ID) || tar.ams_id == std::to_string(VIRTUAL_TRAY_DEPUTY_ID)) && !obj->is_target_slot_unload();
if (busy_for_vt_loading) {
// wait to heat hotend
if (ams_status_sub == 0x02) {
m_filament_step->SetFilamentStep(FilamentStep::STEP_HEAT_NOZZLE, FilamentStepType::STEP_TYPE_VT_LOAD);
} else if (ams_status_sub == 0x05) {
m_filament_step->SetFilamentStep(FilamentStep::STEP_PUSH_NEW_FILAMENT, FilamentStepType::STEP_TYPE_VT_LOAD);
} else if (ams_status_sub == 0x06) {
m_filament_step->SetFilamentStep(FilamentStep::STEP_CONFIRM_EXTRUDED, FilamentStepType::STEP_TYPE_VT_LOAD);
} else if (ams_status_sub == 0x07) {
m_filament_step->SetFilamentStep(FilamentStep::STEP_PURGE_OLD_FILAMENT, FilamentStepType::STEP_TYPE_VT_LOAD);
} else {
m_filament_step->SetFilamentStep(FilamentStep::STEP_IDLE, FilamentStepType::STEP_TYPE_VT_LOAD);
ams_loading_state = false;
}
} else {
// wait to heat hotend
if (ams_status_sub == 0x02) {
if (!obj->is_target_slot_unload()) {
m_filament_step->SetFilamentStep(FilamentStep::STEP_HEAT_NOZZLE, FilamentStepType::STEP_TYPE_LOAD);
} else {
m_filament_step->SetFilamentStep(FilamentStep::STEP_HEAT_NOZZLE, FilamentStepType::STEP_TYPE_UNLOAD);
}
} else if (ams_status_sub == 0x03) {
if (!obj->is_target_slot_unload()) {
m_filament_step->SetFilamentStep(FilamentStep::STEP_CUT_FILAMENT, FilamentStepType::STEP_TYPE_LOAD);
} else {
m_filament_step->SetFilamentStep(FilamentStep::STEP_CUT_FILAMENT, FilamentStepType::STEP_TYPE_UNLOAD);
}
} else if (ams_status_sub == 0x04) {
if (!obj->is_target_slot_unload()) {
m_filament_step->SetFilamentStep(FilamentStep::STEP_PULL_CURR_FILAMENT, FilamentStepType::STEP_TYPE_LOAD);
} else {
m_filament_step->SetFilamentStep(FilamentStep::STEP_PULL_CURR_FILAMENT, FilamentStepType::STEP_TYPE_UNLOAD);
}
} else if (ams_status_sub == 0x05) {
if (!obj->is_target_slot_unload()) {
if (m_is_load_with_temp) {
m_filament_step->SetFilamentStep(FilamentStep::STEP_CUT_FILAMENT, FilamentStepType::STEP_TYPE_LOAD);
} else {
m_filament_step->SetFilamentStep(FilamentStep::STEP_PUSH_NEW_FILAMENT, FilamentStepType::STEP_TYPE_LOAD);
}
} else {
m_filament_step->SetFilamentStep(FilamentStep::STEP_PUSH_NEW_FILAMENT, FilamentStepType::STEP_TYPE_UNLOAD);
}
} else if (ams_status_sub == 0x06) {
if (!obj->is_target_slot_unload()) {
m_filament_step->SetFilamentStep(FilamentStep::STEP_PUSH_NEW_FILAMENT, FilamentStepType::STEP_TYPE_LOAD);
} else {
m_filament_step->SetFilamentStep(FilamentStep::STEP_PUSH_NEW_FILAMENT, FilamentStepType::STEP_TYPE_UNLOAD);
}
} else if (ams_status_sub == 0x07) {
if (!obj->is_target_slot_unload()) {
if (m_is_load_with_temp) {
m_filament_step->SetFilamentStep(FilamentStep::STEP_PULL_CURR_FILAMENT, FilamentStepType::STEP_TYPE_LOAD);
} else {
m_filament_step->SetFilamentStep(FilamentStep::STEP_PURGE_OLD_FILAMENT, FilamentStepType::STEP_TYPE_LOAD);
}
} else {
m_filament_step->SetFilamentStep(FilamentStep::STEP_PURGE_OLD_FILAMENT, FilamentStepType::STEP_TYPE_UNLOAD);
}
} else if (ams_status_sub == 0x08) {
if (!obj->is_target_slot_unload()) {
m_filament_step->SetFilamentStep(FilamentStep::STEP_CHECK_POSITION, FilamentStepType::STEP_TYPE_LOAD);
} else {
m_filament_step->SetFilamentStep(FilamentStep::STEP_CHECK_POSITION, FilamentStepType::STEP_TYPE_UNLOAD);
}
} else if (ams_status_sub == 0x09) {
//just wait
} else if (ams_status_sub == 0x0B) {
if (!obj->is_target_slot_unload()) {
m_filament_step->SetFilamentStep(FilamentStep::STEP_CHECK_POSITION, FilamentStepType::STEP_TYPE_LOAD);
} else {
m_filament_step->SetFilamentStep(FilamentStep::STEP_CHECK_POSITION, FilamentStepType::STEP_TYPE_UNLOAD);
}
} else {
m_filament_step->SetFilamentStep(FilamentStep::STEP_IDLE, FilamentStepType::STEP_TYPE_UNLOAD);
ams_loading_state = false;
}
}
} else if (obj->ams_status_main == AMS_STATUS_MAIN_ASSIST) {
m_filament_step->SetFilamentStep(FilamentStep::STEP_IDLE, FilamentStepType::STEP_TYPE_LOAD);
ams_loading_state = false;
} else {
m_filament_step->SetFilamentStep(FilamentStep::STEP_IDLE, FilamentStepType::STEP_TYPE_LOAD);
ams_loading_state = false;
}
// Orca: show the Stop button when the printer supports aborting a filament change (flag3 bit-13 or printer config)
m_fila_change_abort->Show(ams_loading_state &&
(obj->is_support_fila_change_abort || DevPrinterConfigUtil::support_ams_fila_change_abort(obj->printer_type)));
show_filament_load_group(ams_loading_state);
}
ScoreDialog::ScoreDialog(wxWindow *parent, int design_id, std::string model_id, int profile_id, int rating_id, bool success_printed, int star_count)
: DPIDialog(parent, wxID_ANY, _L("Rate the Print Profile"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX | wxRESIZE_BORDER)
, m_design_id(design_id)
, m_model_id(model_id)
, m_profile_id(profile_id)
, m_star_count(star_count)
, m_rating_id(rating_id)
, m_success_printed(success_printed)
, m_upload_status_code(StatusCode::CODE_NUMBER)
{
m_tocken.reset(new int(0));
wxBoxSizer *m_main_sizer = get_main_sizer();
this->SetSizer(m_main_sizer);
Fit();
Layout();
wxGetApp().UpdateDlgDarkUI(this);
}
ScoreDialog::ScoreDialog(wxWindow *parent, ScoreData *score_data)
: DPIDialog(parent, wxID_ANY, _L("Rate the Print Profile"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX | wxRESIZE_BORDER)
, m_design_id(score_data->design_id)
, m_rating_id(score_data->rating_id)
, m_model_id(score_data->model_id)
, m_profile_id(score_data->profile_id)
, m_star_count(score_data->star_count)
, m_success_printed(score_data->success_printed)
, m_upload_status_code(StatusCode::CODE_NUMBER)
{
m_tocken.reset(new int(0));
wxBoxSizer *m_main_sizer = get_main_sizer(score_data->local_to_url_image, score_data->comment_text);
m_image_url_paths = score_data->image_url_paths;
this->SetSizer(m_main_sizer);
Fit();
Layout();
wxGetApp().UpdateDlgDarkUI(this);
}
ScoreDialog::~ScoreDialog() {}
void ScoreDialog::on_dpi_changed(const wxRect &suggested_rect) {}
void ScoreDialog::OnBitmapClicked(wxMouseEvent &event)
{
wxStaticBitmap *clickedBitmap = dynamic_cast<wxStaticBitmap *>(event.GetEventObject());
if (m_image.find(clickedBitmap) != m_image.end()) {
if (!m_image[clickedBitmap].is_selected) {
for (auto panel : m_image[clickedBitmap].image_broad) {
panel->Show();
}
m_image[clickedBitmap].is_selected = true;
m_selected_image_list.insert(clickedBitmap);
} else {
for (auto panel : m_image[clickedBitmap].image_broad) {
panel->Hide();
}
m_image[clickedBitmap].is_selected = false;
m_selected_image_list.erase(clickedBitmap);
m_selected_image_list.erase(clickedBitmap);
}
}
if (m_selected_image_list.empty())
m_delete_photo->Hide();
else
m_delete_photo->Show();
Fit();
Layout();
}
std::set <std::pair<wxStaticBitmap * ,wxString>> ScoreDialog::add_need_upload_imgs()
{
std::set<std::pair<wxStaticBitmap *, wxString>> need_upload_images;
for (auto bitmap : m_image) {
if (!bitmap.second.is_uploaded) {
wxString &local_image_path = bitmap.second.local_image_url;
if (!local_image_path.empty()) { need_upload_images.insert(std::make_pair(bitmap.first, local_image_path)); }
}
}
return need_upload_images;
}
std::pair<wxStaticBitmap *, ScoreDialog::ImageMsg> ScoreDialog::create_local_thumbnail(wxString &local_path)
{
std::pair<wxStaticBitmap *, ImageMsg> bitmap_to_image_msg;
if (local_path.empty()) return bitmap_to_image_msg;
ImageMsg cur_image_msg;
cur_image_msg.local_image_url = local_path;
cur_image_msg.img_url_paths = "";
cur_image_msg.is_uploaded = false;
wxStaticBitmap *imageCtrl = new wxStaticBitmap(this, wxID_ANY, wxBitmap(wxImage(local_path, wxBITMAP_TYPE_ANY).Rescale(FromDIP(80), FromDIP(60))), wxDefaultPosition,
wxDefaultSize, 0);
imageCtrl->Bind(wxEVT_LEFT_DOWN, &ScoreDialog::OnBitmapClicked, this);
m_image_sizer->Add(create_broad_sizer(imageCtrl, cur_image_msg), 0, wxALL, 5);
bitmap_to_image_msg.first = imageCtrl;
bitmap_to_image_msg.second = cur_image_msg;
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": local picture is download";
return bitmap_to_image_msg;
}
std::pair<wxStaticBitmap *, ScoreDialog::ImageMsg> ScoreDialog::create_oss_thumbnail(std::string &oss_path)
{
std::pair<wxStaticBitmap *, ImageMsg> bitmap_to_image_msg;
if (oss_path.empty()) return bitmap_to_image_msg;
ImageMsg cur_image_msg;
cur_image_msg.local_image_url = "";
cur_image_msg.img_url_paths = oss_path;
cur_image_msg.is_uploaded = true;
wxImage image(Slic3r::resources_dir() + "/images/oss_picture_loading.png", wxBITMAP_TYPE_ANY);
wxStaticBitmap *imageCtrl = new wxStaticBitmap(this, wxID_ANY, wxBitmap(image.Rescale(FromDIP(80), FromDIP(60))), wxDefaultPosition, wxDefaultSize, 0);
imageCtrl->Bind(wxEVT_LEFT_DOWN, &ScoreDialog::OnBitmapClicked, this);
Slic3r::Http http = Slic3r::Http::get(oss_path);
std::string suffix = oss_path.substr(oss_path.find_last_of(".") + 1);
http.header("accept", "image/" + suffix) //"image/" + suffix
.header("Accept-Encoding", "gzip")
.on_complete([this, imageCtrl, time = std::weak_ptr<int>(m_tocken)](std::string body, unsigned int status) {
if (time.expired()) return;
wxMemoryInputStream stream(body.data(), body.size());
wxImage success_image;
if (success_image.LoadFile(stream, wxBITMAP_TYPE_ANY)) {
CallAfter([this, success_image, imageCtrl]() { update_static_bitmap(imageCtrl, success_image); });
} else {
CallAfter([this, imageCtrl]() { update_static_bitmap(imageCtrl, fail_image); });
}
})
.on_error([this, imageCtrl, &oss_path](std::string body, std::string error, unsigned status) {
BOOST_LOG_TRIVIAL(info) << "load oss picture failed, oss path: " << oss_path << " status:" << status << " error:" << error;
CallAfter([this, imageCtrl]() { update_static_bitmap(imageCtrl, fail_image); });
}).perform();
m_image_sizer->Add(create_broad_sizer(imageCtrl, cur_image_msg), 0, wxALL, 5);
bitmap_to_image_msg.first = imageCtrl;
bitmap_to_image_msg.second = cur_image_msg;
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": oss picture is download";
return bitmap_to_image_msg;
}
void ScoreDialog::update_static_bitmap(wxStaticBitmap* static_bitmap, wxImage image)
{
static_bitmap->SetBitmap(wxBitmap(image.Rescale(FromDIP(80), FromDIP(60))));
Layout();
Fit();
//Refresh();
}
wxBoxSizer *ScoreDialog::create_broad_sizer(wxStaticBitmap *bitmap, ImageMsg& cur_image_msg)
{
// tb: top and bottom lr: left and right
auto m_image_tb_broad = new wxBoxSizer(wxVERTICAL);
auto line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL);
line_top->SetBackgroundColour(wxColour(0xA6, 0xa9, 0xAA));
m_image_tb_broad->Add(line_top, 0, wxEXPAND, 0);
cur_image_msg.image_broad.push_back(line_top);
line_top->Hide();
auto m_image_lr_broad = new wxBoxSizer(wxHORIZONTAL);
auto line_left = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(1, -1), wxTAB_TRAVERSAL);
line_left->SetBackgroundColour(wxColour(0xA6, 0xa9, 0xAA));
m_image_lr_broad->Add(line_left, 0, wxEXPAND, 0);
cur_image_msg.image_broad.push_back(line_left);
line_left->Hide();
m_image_lr_broad->Add(bitmap, 0, wxALL, 5);
auto line_right = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(1, -1), wxTAB_TRAVERSAL);
line_right->SetBackgroundColour(wxColour(0xA6, 0xa9, 0xAA));
m_image_lr_broad->Add(line_right, 0, wxEXPAND, 0);
m_image_tb_broad->Add(m_image_lr_broad, 0, wxEXPAND, 0);
cur_image_msg.image_broad.push_back(line_right);
line_right->Hide();
auto line_bottom = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL);
line_bottom->SetBackgroundColour(wxColour(0xA6, 0xa9, 0xAA));
m_image_tb_broad->Add(line_bottom, 0, wxEXPAND, 0);
cur_image_msg.image_broad.push_back(line_bottom);
line_bottom->Hide();
cur_image_msg.is_selected = false;
cur_image_msg.image_tb_broad = m_image_tb_broad;
return m_image_tb_broad;
}
void ScoreDialog::init() {
SetBackgroundColour(*wxWHITE);
SetMinSize(wxSize(FromDIP(540), FromDIP(380)));
fail_image = wxImage(Slic3r::resources_dir() + "/images/oss_picture_load_failed.png", wxBITMAP_TYPE_ANY);
}
wxBoxSizer *ScoreDialog::get_score_sizer() {
wxBoxSizer *score_sizer = new wxBoxSizer(wxHORIZONTAL);
wxStaticText *static_score_text = new wxStaticText(this, wxID_ANY, _L("Rate"), wxDefaultPosition, wxDefaultSize, 0);
static_score_text->Wrap(-1);
score_sizer->Add(static_score_text, 1, wxEXPAND | wxLEFT, FromDIP(24));
score_sizer->Add(0, 0, 1, wxEXPAND, 0);
return score_sizer;
}
wxBoxSizer *ScoreDialog::get_star_sizer()
{
wxBoxSizer *static_score_star_sizer = new wxBoxSizer(wxHORIZONTAL);
static_score_star_sizer->AddSpacer(FromDIP(20));
m_score_star.resize(5);
for (int i = 0; i < m_score_star.size(); ++i) {
if (!m_success_printed && m_star_count > 3) {
m_star_count = 3;
warning_text->Show();
Layout();
Fit();
}
if (i < m_star_count) {
m_score_star[i] = new ScalableButton(this, wxID_ANY, "score_star_light", wxEmptyString, wxSize(FromDIP(26), FromDIP(26)), wxDefaultPosition,
wxBU_EXACTFIT | wxNO_BORDER, true, 26);
} else
m_score_star[i] = new ScalableButton(this, wxID_ANY, "score_star_dark", wxEmptyString, wxSize(FromDIP(26), FromDIP(26)), wxDefaultPosition,
wxBU_EXACTFIT | wxNO_BORDER, true, 26);
m_score_star[i]->SetMinSize(wxSize(FromDIP(26), FromDIP(26)));
m_score_star[i]->SetMaxSize(wxSize(FromDIP(26), FromDIP(26)));
m_score_star[i]->Bind(wxEVT_LEFT_DOWN, [this, i](auto &e) {
if (!m_success_printed && i >= 3) {
warning_text->Show();
Layout();
Fit();
return;
} else {
warning_text->Hide();
Layout();
Fit();
}
for (int j = 0; j < m_score_star.size(); ++j) {
ScalableBitmap light_star = ScalableBitmap(nullptr, "score_star_light", 26);
m_score_star[j]->SetBitmap(light_star.bmp());
if (m_score_star[j] == m_score_star[i]) {
m_star_count = j + 1;
break;
}
}
for (int k = m_star_count; k < m_score_star.size(); ++k) {
ScalableBitmap dark_star = ScalableBitmap(nullptr, "score_star_dark", 26);
m_score_star[k]->SetBitmap(dark_star.bmp());
}
});
static_score_star_sizer->Add(m_score_star[i], 1, wxEXPAND | wxLEFT, FromDIP(5));
}
return static_score_star_sizer;
}
wxBoxSizer* ScoreDialog::get_comment_text_sizer() {
wxBoxSizer* m_comment_sizer = new wxBoxSizer(wxHORIZONTAL);
wxStaticText *static_comment_text = new wxStaticText(this, wxID_ANY, _L("Comment"), wxDefaultPosition, wxDefaultSize, 0);
static_comment_text->Wrap(-1);
m_comment_sizer->Add(static_comment_text, 1, wxEXPAND | wxLEFT, FromDIP(24));
m_comment_sizer->Add(0, 0, 1, wxEXPAND, 0);
return m_comment_sizer;
}
void ScoreDialog::create_comment_text(const wxString& comment) {
m_comment_text = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxSize(FromDIP(492), FromDIP(104)), wxTE_MULTILINE);
m_comment_text->SetBackgroundColour(wxColor(*wxWHITE));
if (!comment.empty()) {
m_comment_text->SetValue(comment);
}
m_comment_text->SetHint(_L("Rate this print"));
m_comment_text->SetBackgroundColour(*wxWHITE);
//m_comment_text->SetForegroundColour(wxColor("#BBBBBB"));
m_comment_text->SetMinSize(wxSize(FromDIP(492), FromDIP(104)));
m_comment_text->Bind(wxEVT_SET_FOCUS, [this](auto &event) {
if (wxGetApp().dark_mode()) {
m_comment_text->SetForegroundColour(wxColor(*wxWHITE));
} else
m_comment_text->SetForegroundColour(wxColor(*wxBLACK));
m_comment_text->Refresh();
event.Skip();
});
}
wxBoxSizer *ScoreDialog::get_photo_btn_sizer() {
wxBoxSizer * m_photo_sizer = new wxBoxSizer(wxHORIZONTAL);
ScalableBitmap little_photo = wxGetApp().dark_mode() ? ScalableBitmap(this, "single_little_photo_dark", 20) : ScalableBitmap(this, "single_little_photo", 20);
wxStaticBitmap *little_photo_img = new wxStaticBitmap(this, wxID_ANY, little_photo.bmp(), wxDefaultPosition, wxSize(FromDIP(20), FromDIP(20)), 0);
m_photo_sizer->Add(little_photo_img, 0, wxEXPAND | wxLEFT, FromDIP(24));
m_add_photo = new Label(this, _L("Add Photo"));
m_add_photo->SetBackgroundColour(*wxWHITE);
//m_add_photo->SetForegroundColour(wxColor("#898989"));
m_add_photo->SetSize(wxSize(-1, FromDIP(20)));
m_photo_sizer->Add(m_add_photo, 0, wxEXPAND | wxLEFT, FromDIP(12));
m_delete_photo = new Label(this, _L("Delete Photo"));
m_delete_photo->SetBackgroundColour(*wxWHITE);
//m_delete_photo->SetForegroundColour(wxColor("#898989"));
m_delete_photo->SetSize(wxSize(-1, FromDIP(20)));
m_photo_sizer->Add(m_delete_photo, 0, wxEXPAND | wxLEFT, FromDIP(12));
m_delete_photo->Hide();
m_photo_sizer->Add(0, 0, 1, wxEXPAND, 0);
m_add_photo->Bind(wxEVT_LEFT_DOWN, [this](auto &e) {
// add photo logic
wxFileDialog openFileDialog(this, _L("Select Images"), "", "", _L("Image files (*.png;*.jpg;*jpeg)|*.png;*.jpg;*.jpeg"), wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);
if (openFileDialog.ShowModal() == wxID_CANCEL) return;
wxArrayString filePaths;
openFileDialog.GetPaths(filePaths);
//wxArrayString filePaths_reduction;
std::vector<std::pair<wxString, std::string>> local_path;
for (int i = 0; i < filePaths.GetCount(); i++) { //It's ugly, but useful
bool is_repeat = false;
for (auto image : m_image) {
if (filePaths[i] == image.second.local_image_url) {
is_repeat = true;
continue;
}
}
if (!is_repeat) {
local_path.push_back(std::make_pair(filePaths[i], ""));
if (local_path.size() + m_image.size() > m_photo_nums) {
break;
}
}
}
load_photo(local_path);
m_image_sizer->Layout();
this->Fit();
this->Layout();
});
m_delete_photo->Bind(wxEVT_LEFT_DOWN, [this](auto &e) {
for (auto it = m_selected_image_list.begin(); it != m_selected_image_list.end();) {
auto bitmap = *it;
m_image_sizer->Detach(m_image[bitmap].image_tb_broad);
m_image[bitmap].image_tb_broad->DeleteWindows();
m_image.erase(bitmap);
it = m_selected_image_list.erase(it);
}
m_image_url_paths.clear();
for (const auto& bitmap : m_image) {
if (bitmap.second.is_uploaded) {
if (!bitmap.second.img_url_paths.empty()) {
m_image_url_paths.push_back(bitmap.second.img_url_paths);
}
}
}
m_delete_photo->Hide();
Layout();
Fit();
});
return m_photo_sizer;
}
wxBoxSizer *ScoreDialog::get_button_sizer()
{
wxBoxSizer *bSizer_button = new wxBoxSizer(wxHORIZONTAL);
bSizer_button->Add(0, 0, 1, wxEXPAND, 0);
m_button_ok = new Button(this, _L("Submit"));
m_button_ok->SetStyle(ButtonStyle::Confirm, ButtonType::Choice);
bSizer_button->Add(m_button_ok, 0, wxRIGHT, FromDIP(ButtonProps::ChoiceButtonGap()));
m_button_ok->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) {
m_upload_status_code = StatusCode::UPLOAD_PROGRESS;
if (m_star_count == 0) {
MessageDialog dlg(this, _L("Please click on the star first."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxOK);
dlg.ShowModal();
return;
}
std::set<std::pair<wxStaticBitmap *, wxString>> need_upload_images = add_need_upload_imgs();
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": get need upload picture count: " << need_upload_images.size();
std::string comment = into_u8(m_comment_text->GetValue());
unsigned int http_code;
std::string http_error;
wxString error_info;
if (!need_upload_images.empty()) {
std::string config;
int ret = wxGetApp().getAgent()->get_oss_config(config, wxGetApp().app_config->get_country_code(), http_code, http_error);
if (ret == -1) {
error_info += into_u8(_L("Get oss config failed.")) + "\n\thttp code: " + std::to_string(http_code) + "\n\thttp error: " + http_error;
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": get oss config filed and http_error: " << http_error;
m_upload_status_code = StatusCode::UPLOAD_EXIST_ISSUE;
}
if (m_upload_status_code == StatusCode::UPLOAD_PROGRESS) {
int need_upload_nums = need_upload_images.size();
int upload_nums = 0;
int upload_failed_nums = 0;
ProgressDialog *progress_dialog = new ProgressDialog(_L("Upload Pictures"), _L("Number of images successfully uploaded") + ": " + std::to_string(upload_nums) + "/" + std::to_string(need_upload_nums), need_upload_nums, this);
for (std::set<std::pair<wxStaticBitmap *, wxString>>::iterator it = need_upload_images.begin(); it != need_upload_images.end();) {
std::pair<wxStaticBitmap *, wxString> need_upload = *it;
std::string need_upload_uf8 = into_u8(need_upload.second);
//Local path when incoming, cloud path when outgoing
ret = wxGetApp().getAgent()->put_rating_picture_oss(config, need_upload_uf8, m_model_id, m_profile_id, http_code, http_error);
std::unordered_map<wxStaticBitmap *, ImageMsg>::iterator iter;
switch (ret) {
case 0:
upload_nums++;
iter = m_image.find(need_upload.first);
if (m_image.end() != iter) {
iter->second.img_url_paths = need_upload_uf8;
iter->second.is_uploaded = true;
m_image_url_paths.push_back(need_upload_uf8);
}
it++;
progress_dialog->Update(upload_nums, _L("Number of images successfully uploaded") + ": " + std::to_string(upload_nums) + "/" + std::to_string(need_upload_nums));
progress_dialog->Fit();
BOOST_LOG_TRIVIAL(info) << "put_rating_picture_oss: model_id [" << m_model_id << "] profile_id [" << m_profile_id << "] http_code [" << http_code
<< "] http_error [" << http_error << "] config [" << config << "] image_path [" << need_upload.second << "]";
break;
case -1:
error_info += need_upload.second + _L(" upload failed").ToUTF8().data() + "\n\thttp code:" + std::to_string(http_code) + "\n\thttp_error:" + http_error + "\n";
m_upload_status_code = StatusCode::UPLOAD_IMG_FAILED;
++it;
break;
case BAMBU_NETWORK_ERR_PARSE_CONFIG_FAILED:
error_info += need_upload.second + _L(" upload config prase failed\n").ToUTF8().data() + "\n";
m_upload_status_code = StatusCode::UPLOAD_IMG_FAILED;
++it;
break;
case BAMBU_NETWORK_ERR_NO_CORRESPONDING_BUCKET:
error_info += need_upload.second + _L(" No corresponding storage bucket\n").ToUTF8().data() + "\n";
m_upload_status_code = StatusCode::UPLOAD_IMG_FAILED;
++it;
break;
case BAMBU_NETWORK_ERR_OPEN_FILE_FAILED:
error_info += need_upload.second + _L(" cannot be opened\n").ToUTF8().data() + "\n";
m_upload_status_code = StatusCode::UPLOAD_IMG_FAILED;
++it;
break;
}
}
progress_dialog->Hide();
if (progress_dialog) {
delete progress_dialog;
progress_dialog = nullptr;
}
if (m_upload_status_code == StatusCode::UPLOAD_IMG_FAILED) {
std::string upload_failed_images = into_u8(_L("The following issues occurred during the process of uploading images. Do you want to ignore them?\n\n"));
MessageDialog dlg_info(this, upload_failed_images + error_info, wxString(_L("info")), wxOK | wxNO | wxCENTER);
if (dlg_info.ShowModal() == wxID_OK) {
m_upload_status_code = StatusCode::UPLOAD_PROGRESS;
}
}
}
}
if (m_upload_status_code == StatusCode::UPLOAD_PROGRESS) {
int ret = wxGetApp().getAgent()->put_model_mall_rating(m_rating_id, m_star_count, comment, m_image_url_paths, http_code, http_error);
MessageDialog *dlg_info;
switch (ret) {
case 0: EndModal(wxID_OK); break;
case BAMBU_NETWORK_ERR_GET_RATING_ID_FAILED:
dlg_info = new MessageDialog(this, _L("Synchronizing the printing results. Please retry a few seconds later."), wxString(_L("info")), wxOK | wxCENTER);
dlg_info->ShowModal();
delete dlg_info;
break;
default: // Upload failed and obtaining instance_id failed
if (ret == -1)
error_info += _L("Upload failed\n").ToUTF8().data();
else
error_info += _L("Obtaining instance_id failed\n").ToUTF8().data();
if (!error_info.empty()) { BOOST_LOG_TRIVIAL(info) << error_info; }
dlg_info = new MessageDialog(this,
_L("Your comment result cannot be uploaded due to the following reasons:\n\n error code: ") +
std::to_string(http_code) + "\n " + _L("error message: ") + http_error +
_L("\n\nWould you like to redirect to the webpage to give a rating?"),
wxString(_L("info")), wxOK | wxNO | wxCENTER);
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": upload rating picture failed and http error" << http_error;
if (dlg_info->ShowModal() == wxID_OK) {
market_model_scoring_page(m_design_id);
EndModal(wxID_OK);
}
delete dlg_info;
break;
}
} else if (m_upload_status_code == StatusCode::UPLOAD_IMG_FAILED) {
MessageDialog *dlg_info = new MessageDialog(this,
_L("Some of your images failed to upload. Would you like to redirect to the webpage to give a rating?"),
wxString(_L("info")), wxOK | wxNO | wxCENTER);
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": upload rating picture failed or get oss config failed";
if (dlg_info->ShowModal() == wxID_OK) {
market_model_scoring_page(m_design_id);
EndModal(wxID_OK);
}
delete dlg_info;
if (!error_info.empty()) { BOOST_LOG_TRIVIAL(info) << error_info; }
}
});
m_button_cancel = new Button(this, _L("Cancel"));
m_button_cancel->SetStyle(ButtonStyle::Regular, ButtonType::Choice);
bSizer_button->Add(m_button_cancel, 0, wxRIGHT, FromDIP(ButtonProps::ChoiceButtonGap()));
m_button_cancel->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) { EndModal(wxID_CANCEL); });
return bSizer_button;
}
void ScoreDialog::load_photo(const std::vector<std::pair<wxString, std::string>> &filePaths)
{
for (size_t i = 0; i < filePaths.size(); ++i) {
if (m_image.size() < m_photo_nums) {
std::pair<wxString, std::string> local_to_url_path = filePaths[i];
wxString filePath = local_to_url_path.first;
ImageMsg cur_image_msg;
if (filePath.empty()) { // local img path is empty, oss url path is exist
std::string oss_url_path = local_to_url_path.second;
//to do: load oss image, create wxStaticBitmap
if (!oss_url_path.empty()) {
m_image.insert(create_oss_thumbnail(oss_url_path));
}
continue;
} else {
m_image.insert(create_local_thumbnail(filePath));
}
} else {
MessageDialog *dlg_info_up_to_8 = new MessageDialog(this, _L("You can select up to 16 images."), wxString(_L("info")), wxOK | wxCENTER);
dlg_info_up_to_8->ShowModal();
break;
}
}
}
wxBoxSizer *ScoreDialog::get_main_sizer(const std::vector<std::pair<wxString, std::string>> &images, const wxString &comment)
{
init();
wxBoxSizer *m_main_sizer = new wxBoxSizer(wxVERTICAL);
// top line
auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL);
m_line_top->SetBackgroundColour(wxColour(0xA6, 0xa9, 0xAA));
m_main_sizer->Add(m_line_top, 0, wxEXPAND, 0);
m_main_sizer->Add(0, 0, 0, wxTOP, FromDIP(32));
warning_text = new wxStaticText(this, wxID_ANY, _L("At least one successful print record of this print profile is required \nto give a positive rating (4 or 5 stars)."));
warning_text->SetForegroundColour(*wxRED);
warning_text->SetFont(::Label::Body_13);
wxBoxSizer *score_sizer = get_score_sizer();
m_main_sizer->Add(score_sizer, 0, wxEXPAND, FromDIP(20));
m_main_sizer->Add(0, 0, 0, wxBOTTOM, FromDIP(8));
wxBoxSizer *static_score_star_sizer = get_star_sizer();
m_main_sizer->Add(static_score_star_sizer, 1, wxEXPAND | wxBOTTOM, FromDIP(20));
m_main_sizer->Add(warning_text, 0, wxEXPAND | wxLEFT, FromDIP(24));
m_main_sizer->Add(0, 0, 0, wxBOTTOM, FromDIP(8));
warning_text->Hide();
wxBoxSizer *m_comment_sizer = get_comment_text_sizer();
m_main_sizer->Add(m_comment_sizer, 0, wxEXPAND, FromDIP(20));
m_main_sizer->Add(0, 0, 0, wxBOTTOM, FromDIP(8));
create_comment_text(comment);
m_main_sizer->Add(m_comment_text, 0, wxLEFT, FromDIP(24));
wxBoxSizer *m_photo_sizer = get_photo_btn_sizer();
m_main_sizer->Add(m_photo_sizer, 0, wxEXPAND | wxTOP, FromDIP(8));
m_image_sizer = new wxGridSizer(5, FromDIP(5), FromDIP(5));
if (!images.empty()) {
load_photo(images);
}
m_main_sizer->Add(m_image_sizer, 0, wxEXPAND | wxLEFT, FromDIP(24));
m_main_sizer->Add(0, 0, 1, wxEXPAND, 0);
wxBoxSizer *bSizer_button = get_button_sizer();
m_main_sizer->Add(bSizer_button, 0, wxEXPAND | wxBOTTOM, FromDIP(24));
return m_main_sizer;
}
ScoreData ScoreDialog::get_score_data() {
ScoreData score_data;
score_data.rating_id = m_rating_id;
score_data.design_id = m_design_id;
score_data.model_id = m_model_id;
score_data.profile_id = m_profile_id;
score_data.star_count = m_star_count;
score_data.success_printed = m_success_printed;
score_data.comment_text = m_comment_text->GetValue();
score_data.image_url_paths = m_image_url_paths;
for (auto img : m_image) { score_data.local_to_url_image.push_back(std::make_pair(img.second.local_image_url, img.second.img_url_paths)); }
return score_data;
}
void ScoreDialog::set_comment(std::string comment)
{
if (m_comment_text) {
m_comment_text->SetValue(wxString::FromUTF8(comment));
}
}
void ScoreDialog::set_cloud_bitmap(std::vector<std::string> cloud_bitmaps)
{
m_image_url_paths = cloud_bitmaps;
for (std::string &url : cloud_bitmaps) {
if (std::string::npos == url.find(m_model_id)) continue;
m_image.insert(create_oss_thumbnail(url));
}
Layout();
Fit();
}
} // namespace GUI
} // namespace Slic3r