ENH: refine display of camera state and add setting

Change-Id: I85f02565e1581fde9a6c161f4fbed0283fda208f
This commit is contained in:
tao.jin 2022-11-18 11:16:24 +08:00 committed by Lane.Wei
parent dc7822e816
commit e217baad50
30 changed files with 597 additions and 295 deletions

View file

@ -20,9 +20,10 @@ wxBEGIN_EVENT_TABLE(CameraPopup, wxPopupTransientWindow)
EVT_KILL_FOCUS(CameraPopup::OnKillFocus )
wxEND_EVENT_TABLE()
wxDEFINE_EVENT(EVT_VCAMERA_SWITCH, wxMouseEvent);
wxDEFINE_EVENT(EVT_SDCARD_ABSENT_HINT, wxCommandEvent);
static const wxFont TEXT_FONT = Label::Body_14;
static wxColour TEXT_COL = wxColour(43, 52, 54);
const wxColour TEXT_COL = wxColour(43, 52, 54);
CameraPopup::CameraPopup(wxWindow *parent, MachineObject* obj)
: wxPopupTransientWindow(parent, wxBORDER_NONE | wxPU_CONTAINS_CONTROLS),
@ -33,34 +34,70 @@ CameraPopup::CameraPopup(wxWindow *parent, MachineObject* obj)
#endif
m_panel = new wxScrolledWindow(this, wxID_ANY);
m_panel->SetBackgroundColour(*wxWHITE);
m_panel->SetMinSize(wxSize(FromDIP(180),-1));
m_panel->Bind(wxEVT_MOTION, &CameraPopup::OnMouse, this);
wxBoxSizer * main_sizer = new wxBoxSizer(wxHORIZONTAL);
wxFlexGridSizer* top_sizer = new wxFlexGridSizer(0, 2, 0, 0);
main_sizer = new wxBoxSizer(wxVERTICAL);
wxFlexGridSizer* top_sizer = new wxFlexGridSizer(0, 2, 0, FromDIP(50));
top_sizer->AddGrowableCol(0);
top_sizer->SetFlexibleDirection(wxBOTH);
top_sizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
//timelapse
m_text_timelapse = new wxStaticText(m_panel, wxID_ANY, _L("Timelapse"));
m_text_timelapse->Wrap(-1);
m_text_timelapse->SetFont(TEXT_FONT);
m_text_timelapse->SetFont(Label::Head_14);
m_text_timelapse->SetForegroundColour(TEXT_COL);
m_switch_timelapse = new SwitchButton(m_panel);
if (obj)
m_switch_timelapse->SetValue(obj->camera_timelapse);
//recording
m_text_recording = new wxStaticText(m_panel, wxID_ANY, _L("Monitoring Recording"));
m_text_recording->Wrap(-1);
m_text_recording->SetFont(TEXT_FONT);
m_text_recording->SetFont(Label::Head_14);
m_text_recording->SetForegroundColour(TEXT_COL);
m_switch_recording = new SwitchButton(m_panel);
if (obj)
m_switch_recording->SetValue(obj->camera_recording_when_printing);
top_sizer->Add(m_text_timelapse, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, FromDIP(5));
top_sizer->Add(m_switch_timelapse, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, FromDIP(5));
top_sizer->Add(m_text_recording, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, FromDIP(5));
top_sizer->Add(m_switch_recording, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, FromDIP(5));
//vcamera
m_text_vcamera = new wxStaticText(m_panel, wxID_ANY, _L("Virtual Camera"));
m_text_vcamera->Wrap(-1);
m_text_vcamera->SetFont(Label::Head_14);
m_text_vcamera->SetForegroundColour(TEXT_COL);
m_switch_vcamera = new SwitchButton(m_panel);
top_sizer->Add(m_text_timelapse, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, FromDIP(5));
top_sizer->Add(m_switch_timelapse, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, FromDIP(5));
top_sizer->Add(m_text_recording, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, FromDIP(5));
top_sizer->Add(m_switch_recording, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, FromDIP(5));
top_sizer->Add(m_text_vcamera, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, FromDIP(5));
top_sizer->Add(m_switch_vcamera, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, FromDIP(5));
//resolution
m_text_resolution = new wxStaticText(m_panel, wxID_ANY, _L("Resolution"));
m_text_resolution->Wrap(-1);
m_text_resolution->SetFont(Label::Head_14);
m_text_resolution->SetForegroundColour(TEXT_COL);
top_sizer->Add(m_text_resolution, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, FromDIP(5));
top_sizer->Add(0, 0, wxALL, 0);
for (int i = 0; i < (int)RESOLUTION_OPTIONS_NUM; ++i)
{
m_resolution_options[i] = create_item_radiobox(to_resolution_label_string(CameraResolution(i)), m_panel, wxEmptyString, FromDIP(10));
top_sizer->Add(m_resolution_options[i], 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, FromDIP(5));
top_sizer->Add(0, 0, wxALL, 0);
}
if (obj)
sync_resolution_setting(obj->camera_resolution);
main_sizer->Add(top_sizer, 0, wxALL, FromDIP(10));
auto url = wxString::Format(L"https://wiki.bambulab.com/%s/software/bambu-studio/virtual-camera", L"en");
vcamera_guide_link = new wxHyperlinkCtrl(m_panel, wxID_ANY, _L("Show 'Streaming Video' guide page."),
url, wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE);
vcamera_guide_link->Hide();
main_sizer->Add(vcamera_guide_link, 0, wxALL, FromDIP(15));
m_panel->SetSizer(main_sizer);
m_panel->Layout();
@ -69,12 +106,32 @@ CameraPopup::CameraPopup(wxWindow *parent, MachineObject* obj)
SetClientSize(m_panel->GetSize());
m_switch_timelapse->Connect(wxEVT_LEFT_DOWN, wxCommandEventHandler(CameraPopup::on_switch_timelapse), NULL, this);
m_switch_recording->Connect(wxEVT_LEFT_DOWN, wxCommandEventHandler(CameraPopup::on_switch_recording), NULL, this);
m_switch_vcamera->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) {
wxMouseEvent evt(EVT_VCAMERA_SWITCH);
evt.SetEventObject(this);
GetEventHandler()->ProcessEvent(evt);
});
#ifdef __APPLE__
m_panel->Bind(wxEVT_LEFT_UP, &CameraPopup::OnLeftUp, this);
#endif //APPLE
check_func_supported();
}
void CameraPopup::sdcard_absent_hint()
{
wxCommandEvent evt(EVT_SDCARD_ABSENT_HINT);
evt.SetEventObject(this);
GetEventHandler()->ProcessEvent(evt);
}
void CameraPopup::on_switch_timelapse(wxCommandEvent& event)
{
if (!m_obj) return;
if (m_obj->sdcard_state != MachineObject::SdcardState::HAS_SDCARD_NORMAL) {
sdcard_absent_hint();
return;
}
bool value = m_switch_timelapse->GetValue();
m_switch_timelapse->SetValue(!value);
m_obj->command_ipcam_timelapse(!value);
@ -83,12 +140,22 @@ void CameraPopup::on_switch_timelapse(wxCommandEvent& event)
void CameraPopup::on_switch_recording(wxCommandEvent& event)
{
if (!m_obj) return;
if (m_obj->sdcard_state != MachineObject::SdcardState::HAS_SDCARD_NORMAL) {
sdcard_absent_hint();
return;
}
bool value = m_switch_recording->GetValue();
m_switch_recording->SetValue(!value);
m_obj->command_ipcam_record(!value);
}
void CameraPopup::on_set_resolution()
{
if (!m_obj) return;
m_obj->command_ipcam_resolution_set(to_resolution_msg_string(curr_sel_resolution));
}
void CameraPopup::Popup(wxWindow *WXUNUSED(focus))
{
wxPoint curr_position = this->GetPosition();
@ -98,6 +165,235 @@ void CameraPopup::Popup(wxWindow *WXUNUSED(focus))
wxPopupTransientWindow::Popup();
}
wxWindow* CameraPopup::create_item_radiobox(wxString title, wxWindow* parent, wxString tooltip, int padding_left)
{
wxWindow *item = new wxWindow(parent, wxID_ANY, wxDefaultPosition, wxSize(-1, FromDIP(20)));
item->SetBackgroundColour(*wxWHITE);
RadioBox *radiobox = new RadioBox(item);
radiobox->SetPosition(wxPoint(padding_left, (item->GetSize().GetHeight() - radiobox->GetSize().GetHeight()) / 2));
resolution_rbtns.push_back(radiobox);
int btn_idx = resolution_rbtns.size() - 1;
radiobox->Bind(wxEVT_LEFT_DOWN, [this, btn_idx](wxMouseEvent &e) {
if (m_obj && allow_alter_resolution) {
select_curr_radiobox(btn_idx, false);
on_set_resolution();
}
});
wxStaticText *text = new wxStaticText(item, wxID_ANY, title, wxDefaultPosition, wxDefaultSize);
resolution_texts.push_back(text);
text->SetPosition(wxPoint(padding_left + radiobox->GetSize().GetWidth() + 10, (item->GetSize().GetHeight() - text->GetSize().GetHeight()) / 2));
text->SetFont(Label::Body_13);
text->SetForegroundColour(0x6B6B6B);
text->Bind(wxEVT_LEFT_DOWN, [this, btn_idx](wxMouseEvent &e) {
if (m_obj && allow_alter_resolution) {
select_curr_radiobox(btn_idx, false);
on_set_resolution();
}
});
radiobox->SetToolTip(tooltip);
text->SetToolTip(tooltip);
return item;
}
void CameraPopup::select_curr_radiobox(int btn_idx, bool ui_change)
{
int len = resolution_rbtns.size();
for (int i = 0; i < len; ++i) {
if (i == btn_idx) {
curr_sel_resolution = CameraResolution(i);
if (ui_change)
resolution_rbtns[i]->SetValue(true);
}
else {
if (ui_change)
resolution_rbtns[i]->SetValue(false);
}
}
}
void CameraPopup::sync_resolution_setting(std::string resolution)
{
if (resolution == "") {
reset_resolution_setting();
return;
}
int res = 0;
for (CameraResolution i = RESOLUTION_720P; i < RESOLUTION_OPTIONS_NUM; i = CameraResolution(i+1)){
if (resolution == to_resolution_msg_string(i)) {
res = int(i);
break;
}
}
select_curr_radiobox(res, true);
}
void CameraPopup::reset_resolution_setting()
{
int len = resolution_rbtns.size();
for (int i = 0; i < len; ++i) {
resolution_rbtns[i]->SetValue(false);
}
curr_sel_resolution = RESOLUTION_OPTIONS_NUM;
}
void CameraPopup::sync_vcamera_state(bool show_vcamera)
{
is_vcamera_show = show_vcamera;
if (is_vcamera_show) {
m_switch_vcamera->SetValue(true);
vcamera_guide_link->Show();
}
else {
m_switch_vcamera->SetValue(false);
vcamera_guide_link->Hide();
}
rescale();
}
void CameraPopup::check_func_supported()
{
// function supported
if (m_obj->is_function_supported(PrinterFunction::FUNC_TIMELAPSE) && m_obj->has_ipcam) {
m_text_timelapse->Show();
m_switch_timelapse->Show();
} else {
m_text_timelapse->Hide();
m_switch_timelapse->Hide();
}
if (m_obj->is_function_supported(PrinterFunction::FUNC_RECORDING) && m_obj->has_ipcam) {
m_text_recording->Show();
m_switch_recording->Show();
} else {
m_text_recording->Hide();
m_switch_recording->Hide();
}
if (m_obj->is_function_supported(PrinterFunction::FUNC_VIRTUAL_CAMERA) && m_obj->has_ipcam) {
m_text_vcamera->Show();
m_switch_vcamera->Show();
if (is_vcamera_show)
vcamera_guide_link->Show();
} else {
m_text_vcamera->Hide();
m_switch_vcamera->Hide();
vcamera_guide_link->Hide();
}
allow_alter_resolution = (m_obj->is_function_supported(PrinterFunction::FUNC_ALTER_RESOLUTION) && m_obj->has_ipcam);
//resolution supported
std::vector<std::string> resolution_supported = m_obj->get_resolution_supported();
for (int i = 0; i < (int)RESOLUTION_OPTIONS_NUM; ++i){
auto curr_res = to_resolution_msg_string(CameraResolution(i));
std::vector <std::string> ::iterator it = std::find(resolution_supported.begin(), resolution_supported.end(), curr_res);
if (it!= resolution_supported.end())
m_resolution_options[i] -> Show();
else
m_resolution_options[i] -> Hide();
}
}
void CameraPopup::update()
{
if (!m_obj) return;
check_func_supported();
m_switch_timelapse->SetValue(m_obj->camera_timelapse);
m_switch_recording->SetValue(m_obj->camera_recording_when_printing);
sync_resolution_setting(m_obj->camera_resolution);
rescale();
}
wxString CameraPopup::to_resolution_label_string(CameraResolution resolution) {
switch (resolution) {
case RESOLUTION_720P:
return _L("720p");
case RESOLUTION_1080P:
return _L("1080p");
default:
return _L("");
}
return "";
}
std::string CameraPopup::to_resolution_msg_string(CameraResolution resolution) {
switch (resolution) {
case RESOLUTION_720P:
return std::string("720p");
case RESOLUTION_1080P:
return std::string("1080p");
default:
return "";
}
return "";
}
void CameraPopup::rescale()
{
m_panel->Layout();
main_sizer->Fit(m_panel);
SetClientSize(m_panel->GetSize());
wxPopupTransientWindow::Update();
}
void CameraPopup::OnLeftUp(wxMouseEvent &event)
{
auto mouse_pos = ClientToScreen(event.GetPosition());
auto wxscroll_win_pos = m_panel->ClientToScreen(wxPoint(0, 0));
if (mouse_pos.x > wxscroll_win_pos.x && mouse_pos.y > wxscroll_win_pos.y && mouse_pos.x < (wxscroll_win_pos.x + m_panel->GetSize().x) && mouse_pos.y < (wxscroll_win_pos.y + m_panel->GetSize().y)) {
//timelapse
auto timelapse_rect = m_switch_timelapse->ClientToScreen(wxPoint(0, 0));
if (mouse_pos.x > timelapse_rect.x && mouse_pos.y > timelapse_rect.y && mouse_pos.x < (timelapse_rect.x + m_switch_timelapse->GetSize().x) && mouse_pos.y < (timelapse_rect.y + m_switch_timelapse->GetSize().y)) {
wxMouseEvent timelapse_evt(wxEVT_LEFT_DOWN);
m_switch_timelapse->GetEventHandler()->ProcessEvent(timelapse_evt);
return;
}
//recording
auto recording_rect = m_switch_recording->ClientToScreen(wxPoint(0, 0));
if (mouse_pos.x > recording_rect.x && mouse_pos.y > recording_rect.y && mouse_pos.x < (recording_rect.x + m_switch_recording->GetSize().x) && mouse_pos.y < (recording_rect.y + m_switch_recording->GetSize().y)) {
wxMouseEvent recording_evt(wxEVT_LEFT_DOWN);
m_switch_recording->GetEventHandler()->ProcessEvent(recording_evt);
return;
}
//vcamera
auto vcamera_rect = m_switch_vcamera->ClientToScreen(wxPoint(0, 0));
if (mouse_pos.x > vcamera_rect.x && mouse_pos.y > vcamera_rect.y && mouse_pos.x < (vcamera_rect.x + m_switch_vcamera->GetSize().x) && mouse_pos.y < (vcamera_rect.y + m_switch_vcamera->GetSize().y)) {
wxMouseEvent vcamera_evt(wxEVT_LEFT_DOWN);
m_switch_vcamera->GetEventHandler()->ProcessEvent(vcamera_evt);
return;
}
//resolution
for (int i = 0; i < (int)RESOLUTION_OPTIONS_NUM; ++i){
auto resolution_rbtn = resolution_rbtns[i];
auto rbtn_rect = resolution_rbtn->ClientToScreen(wxPoint(0, 0));
if (mouse_pos.x > rbtn_rect.x && mouse_pos.y > rbtn_rect.y && mouse_pos.x < (rbtn_rect.x + resolution_rbtn->GetSize().x) && mouse_pos.y < (rbtn_rect.y + resolution_rbtn->GetSize().y)) {
wxMouseEvent resolution_evt(wxEVT_LEFT_DOWN);
resolution_rbtn->GetEventHandler()->ProcessEvent(resolution_evt);
return;
}
auto resolution_txt = resolution_texts[i];
auto txt_rect = resolution_txt->ClientToScreen(wxPoint(0, 0));
if (mouse_pos.x > txt_rect.x && mouse_pos.y > txt_rect.y && mouse_pos.x < (txt_rect.x + resolution_txt->GetSize().x) && mouse_pos.y < (txt_rect.y + resolution_txt->GetSize().y)) {
wxMouseEvent resolution_evt(wxEVT_LEFT_DOWN);
resolution_txt->GetEventHandler()->ProcessEvent(resolution_evt);
return;
}
}
//hyper link
auto h_rect = vcamera_guide_link->ClientToScreen(wxPoint(0, 0));
if (mouse_pos.x > h_rect.x && mouse_pos.y > h_rect.y && mouse_pos.x < (h_rect.x + vcamera_guide_link->GetSize().x) && mouse_pos.y < (h_rect.y + vcamera_guide_link->GetSize().y)) {
auto url = wxString::Format(L"https://wiki.bambulab.com/%s/software/bambu-studio/virtual-camera", L"en");
wxLaunchDefaultBrowser(url);
}
}
}
void CameraPopup::OnDismiss() {
wxPopupTransientWindow::OnDismiss();
}
@ -106,6 +402,7 @@ bool CameraPopup::ProcessLeftDown(wxMouseEvent &event)
{
return wxPopupTransientWindow::ProcessLeftDown(event);
}
bool CameraPopup::Show(bool show)
{
return wxPopupTransientWindow::Show(show);
@ -131,18 +428,15 @@ void CameraPopup::OnMouse(wxMouseEvent &event)
event.Skip();
}
CameraItem::CameraItem(wxWindow *parent,std::string off_normal, std::string on_normal, std::string off_hover, std::string on_hover)
CameraItem::CameraItem(wxWindow *parent, std::string normal, std::string hover)
: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize)
{
#ifdef __WINDOWS__
SetDoubleBuffered(true);
#endif //__WINDOWS__
m_bitmap_on_normal = ScalableBitmap(this, on_normal, 20);
m_bitmap_off_normal = ScalableBitmap(this, off_normal, 20);
m_bitmap_on_hover = ScalableBitmap(this, on_hover, 20);
m_bitmap_off_hover = ScalableBitmap(this, off_hover, 20);
m_bitmap_normal = ScalableBitmap(this, normal, 20);
m_bitmap_hover = ScalableBitmap(this, hover, 20);
SetSize(wxSize(FromDIP(20), FromDIP(20)));
SetMinSize(wxSize(FromDIP(20), FromDIP(20)));
@ -156,12 +450,6 @@ CameraItem::~CameraItem() {}
void CameraItem::msw_rescale() {}
void CameraItem::set_switch(bool is_on)
{
m_on = is_on;
Refresh();
}
void CameraItem::on_enter_win(wxMouseEvent &evt)
{
m_hover = true;
@ -206,20 +494,12 @@ void CameraItem::render(wxDC &dc)
void CameraItem::doRender(wxDC &dc)
{
if (m_on) {
if (m_hover) {
dc.DrawBitmap(m_bitmap_on_hover.bmp(), wxPoint((GetSize().x - m_bitmap_on_hover.GetBmpSize().x) / 2, (GetSize().y - m_bitmap_on_hover.GetBmpSize().y) / 2));
} else {
dc.DrawBitmap(m_bitmap_on_normal.bmp(), wxPoint((GetSize().x - m_bitmap_on_normal.GetBmpSize().x) / 2, (GetSize().y - m_bitmap_on_normal.GetBmpSize().y) / 2));
}
if (m_hover) {
dc.DrawBitmap(m_bitmap_hover.bmp(), wxPoint((GetSize().x - m_bitmap_hover.GetBmpSize().x) / 2, (GetSize().y - m_bitmap_hover.GetBmpSize().y) / 2));
} else {
if (m_hover) {
dc.DrawBitmap(m_bitmap_off_hover.bmp(), wxPoint((GetSize().x - m_bitmap_off_hover.GetBmpSize().x) / 2, (GetSize().y - m_bitmap_off_hover.GetBmpSize().y) / 2));
} else {
dc.DrawBitmap(m_bitmap_off_normal.bmp(), wxPoint((GetSize().x - m_bitmap_off_normal.GetBmpSize().x) / 2, (GetSize().y - m_bitmap_off_normal.GetBmpSize().y) / 2));
}
dc.DrawBitmap(m_bitmap_normal.bmp(), wxPoint((GetSize().x - m_bitmap_normal.GetBmpSize().x) / 2, (GetSize().y - m_bitmap_normal.GetBmpSize().y) / 2));
}
}
}
}

View file

@ -10,11 +10,16 @@
#include <wx/sizer.h>
#include <wx/gbsizer.h>
#include <wx/webrequest.h>
#include <wx/hyperlink.h>
#include "Widgets/SwitchButton.hpp"
#include "Widgets/RadioBox.hpp"
namespace Slic3r {
namespace GUI {
wxDECLARE_EVENT(EVT_VCAMERA_SWITCH, wxMouseEvent);
wxDECLARE_EVENT(EVT_SDCARD_ABSENT_HINT, wxCommandEvent);
class CameraPopup : public wxPopupTransientWindow
{
public:
@ -27,9 +32,31 @@ public:
virtual bool ProcessLeftDown(wxMouseEvent &event) wxOVERRIDE;
virtual bool Show(bool show = true) wxOVERRIDE;
void sync_vcamera_state(bool show_vcamera);
void check_func_supported();
void update();
enum CameraResolution
{
RESOLUTION_720P = 0,
RESOLUTION_1080P = 1,
RESOLUTION_OPTIONS_NUM = 2
};
void rescale();
protected:
void on_switch_timelapse(wxCommandEvent& event);
void on_switch_recording(wxCommandEvent& event);
void on_set_resolution();
void sdcard_absent_hint();
wxWindow * create_item_radiobox(wxString title, wxWindow *parent, wxString tooltip, int padding_left);
void select_curr_radiobox(int btn_idx, bool ui_change);
void sync_resolution_setting(std::string resolution);
void reset_resolution_setting();
wxString to_resolution_label_string(CameraResolution resolution);
std::string to_resolution_msg_string(CameraResolution resolution);
private:
MachineObject* m_obj { nullptr };
@ -37,12 +64,24 @@ private:
SwitchButton* m_switch_recording;
wxStaticText* m_text_timelapse;
SwitchButton* m_switch_timelapse;
wxStaticText* m_text_vcamera;
SwitchButton* m_switch_vcamera;
wxStaticText* m_text_resolution;
wxWindow* m_resolution_options[RESOLUTION_OPTIONS_NUM];
wxScrolledWindow *m_panel;
wxBoxSizer* main_sizer;
std::vector<RadioBox*> resolution_rbtns;
std::vector<wxStaticText*> resolution_texts;
CameraResolution curr_sel_resolution = RESOLUTION_1080P;
wxHyperlinkCtrl* vcamera_guide_link { nullptr };
bool is_vcamera_show = false;
bool allow_alter_resolution = false;
void OnMouse(wxMouseEvent &event);
void OnSize(wxSizeEvent &event);
void OnSetFocus(wxFocusEvent &event);
void OnKillFocus(wxFocusEvent &event);
void OnLeftUp(wxMouseEvent& event);
private:
wxDECLARE_ABSTRACT_CLASS(CameraPopup);
@ -53,20 +92,15 @@ private:
class CameraItem : public wxPanel
{
public:
CameraItem(wxWindow *parent, std::string off_normal, std::string on_normal, std::string off_hover, std::string on_hover);
CameraItem(wxWindow *parent, std::string normal, std::string hover);
~CameraItem();
MachineObject *m_obj{nullptr};
bool m_on{false};
bool m_hover{false};
ScalableBitmap m_bitmap_on_normal;
ScalableBitmap m_bitmap_on_hover;
ScalableBitmap m_bitmap_off_normal;
ScalableBitmap m_bitmap_off_hover;
ScalableBitmap m_bitmap_normal;
ScalableBitmap m_bitmap_hover;
void msw_rescale();
void set_switch(bool is_on);
bool get_switch_status() { return m_on; };
void on_enter_win(wxMouseEvent &evt);
void on_level_win(wxMouseEvent &evt);
void paintEvent(wxPaintEvent &evt);

View file

@ -1149,8 +1149,9 @@ void MachineObject::parse_status(int flag)
else {
ams_auto_switch_filament_flag = ((flag >> 10) & 0x1) != 0;
}
sdcard_state = MachineObject::SdcardState((flag >> 8) & 0x11);
}
PrintingSpeedLevel MachineObject::_parse_printing_speed_lvl(int lvl)
{
@ -1173,7 +1174,12 @@ bool MachineObject::is_sdcard_printing()
bool MachineObject::has_sdcard()
{
return camera_has_sdcard;
return (sdcard_state == MachineObject::SdcardState::HAS_SDCARD_NORMAL);
}
MachineObject::SdcardState MachineObject::get_sdcard_state()
{
return sdcard_state;
}
bool MachineObject::has_timelapse()
@ -1608,6 +1614,16 @@ int MachineObject::command_ipcam_timelapse(bool on_off)
return this->publish_json(j.dump());
}
int MachineObject::command_ipcam_resolution_set(std::string resolution)
{
json j;
j["camera"]["command"] = "ipcam_resolution_set";
j["camera"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
j["camera"]["resolution"] = resolution;
BOOST_LOG_TRIVIAL(info) << "command:ipcam_resolution_set" << ", resolution:" << resolution;
return this->publish_json(j.dump());
}
int MachineObject::command_xcam_control(std::string module_name, bool on_off, std::string lvl)
{
json j;
@ -1620,8 +1636,7 @@ int MachineObject::command_xcam_control(std::string module_name, bool on_off, st
if (!lvl.empty()) {
j["xcam"]["halt_print_sensitivity"] = lvl;
}
BOOST_LOG_TRIVIAL(info) << "command:xcam_control_set" << ", sequence_id:" << std::to_string(MachineObject::m_sequence_id)<<
", module_name:" << module_name << ", control:" << on_off << ", halt_print_sensitivity:" << lvl;
BOOST_LOG_TRIVIAL(info) << "command:xcam_control_set" << ", module_name:" << module_name << ", control:" << on_off << ", halt_print_sensitivity:" << lvl;
return this->publish_json(j.dump());
}
@ -1753,6 +1768,7 @@ void MachineObject::reset()
camera_recording = false;
camera_recording_when_printing = false;
camera_timelapse = false;
camera_resolution = "";
printing_speed_mag = 100;
gcode_file_prepare_percent = 0;
iot_print_status = "";
@ -1889,12 +1905,20 @@ bool MachineObject::is_function_supported(PrinterFunction func)
case FUNC_USE_AMS:
func_name = "FUNC_USE_AMS";
break;
case FUNC_ALTER_RESOLUTION:
func_name = "FUNC_ALTER_RESOLUTION";
break;
default:
return true;
}
return DeviceManager::is_function_supported(printer_type, func_name);
}
std::vector<std::string> MachineObject::get_resolution_supported()
{
return DeviceManager::get_resolution_supported(printer_type);
}
bool MachineObject::is_support_print_with_timelapse()
{
//TODO version check, set true by default
@ -2239,10 +2263,13 @@ int MachineObject::parse_json(std::string payload)
// media
try {
if (jj.contains("sdcard")) {
camera_has_sdcard = jj["sdcard"].get<bool>();
if (jj["sdcard"].get<bool>())
sdcard_state = MachineObject::SdcardState::HAS_SDCARD_NORMAL;
else
sdcard_state = MachineObject::SdcardState::NO_SDCARD;
} else {
//do not check sdcard if no sdcard field
camera_has_sdcard = false;
sdcard_state = MachineObject::SdcardState::NO_SDCARD;
}
}
catch (...) {
@ -2367,6 +2394,9 @@ int MachineObject::parse_json(std::string payload)
has_ipcam = false;
}
}
if (jj["ipcam"].contains("resolution")) {
camera_resolution = jj["ipcam"]["resolution"].get<std::string>();
}
}
}
catch (...) {
@ -2831,6 +2861,8 @@ int MachineObject::parse_json(std::string payload)
this->camera_recording_when_printing = true;
if (j["camera"]["control"].get<std::string>() == "disable")
this->camera_recording_when_printing = false;
} else if (j["camera"]["command"].get<std::string>() == "ipcam_resolution_set") {
this->camera_resolution = j["camera"]["resolution"].get<std::string>();
}
}
}
@ -3524,6 +3556,22 @@ bool DeviceManager::is_function_supported(std::string type_str, std::string func
return true;
}
std::vector<std::string> DeviceManager::get_resolution_supported(std::string type_str)
{
std::vector<std::string> resolution_supported;
if (DeviceManager::function_table.contains("printers")) {
for (auto printer : DeviceManager::function_table["printers"]) {
if (printer.contains("model_id") && printer["model_id"].get<std::string>() == type_str) {
if (printer.contains("camera_resolution")) {
for (auto res : printer["camera_resolution"])
resolution_supported.emplace_back(res.get<std::string>());
}
}
}
}
return resolution_supported;
}
bool DeviceManager::load_functional_config(std::string config_file)
{
std::ifstream json_file(config_file.c_str());

View file

@ -11,6 +11,7 @@
#include "libslic3r/ProjectTask.hpp"
#include "slic3r/Utils/json_diff.hpp"
#include "slic3r/Utils/NetworkAgent.hpp"
#include "CameraPopup.hpp"
#define USE_LOCAL_SOCKET_BIND 0
@ -74,6 +75,7 @@ enum PrinterFunction {
FUNC_PRINT_WITHOUT_SD,
FUNC_VIRTUAL_CAMERA,
FUNC_USE_AMS,
FUNC_ALTER_RESOLUTION,
FUNC_MAX
};
@ -346,6 +348,13 @@ public:
std::string sw_new_ver;
};
enum SdcardState {
NO_SDCARD = 0,
HAS_SDCARD_NORMAL = 1,
HAS_SDCARD_ABNORMAL = 2,
SDCARD_STATE_NUM = 3
};
/* static members and functions */
static inline int m_sequence_id = 20000;
static std::string parse_printer_type(std::string type_str);
@ -530,7 +539,7 @@ public:
bool camera_recording { false };
bool camera_recording_when_printing { false };
bool camera_timelapse { false };
bool camera_has_sdcard { false };
std::string camera_resolution = "";
bool xcam_first_layer_inspector { false };
int xcam_first_layer_hold_count = 0;
@ -543,6 +552,10 @@ public:
int xcam_auto_recovery_hold_count = 0;
int ams_print_option_count = 0;
/* sdcard */
MachineObject::SdcardState sdcard_state { NO_SDCARD };
MachineObject::SdcardState get_sdcard_state();
/* HMS */
std::vector<HMSItem> hms_list;
@ -626,6 +639,7 @@ public:
// camera control
int command_ipcam_record(bool on_off);
int command_ipcam_timelapse(bool on_off);
int command_ipcam_resolution_set(std::string resolution);
int command_xcam_control(std::string module_name, bool on_off, std::string lvl = "");
int command_xcam_control_ai_monitoring(bool on_off, std::string lvl);
int command_xcam_control_first_layer_inspector(bool on_off, bool print_halt);
@ -655,6 +669,7 @@ public:
bool is_online() { return m_is_online; }
bool is_info_ready();
bool is_function_supported(PrinterFunction func);
std::vector<std::string> get_resolution_supported();
bool is_support_print_with_timelapse();
@ -724,6 +739,7 @@ public:
static std::string parse_printer_type(std::string type_str);
static std::string get_printer_display_name(std::string type_str);
static bool is_function_supported(std::string type_str, std::string function_name);
static std::vector<std::string> get_resolution_supported(std::string type_str);
static bool load_functional_config(std::string config_file);
};

View file

@ -273,7 +273,7 @@ void MediaPlayCtrl::ToggleStream()
std::string file_ff_cfg = data_dir() + "/cameratools/ffmpeg.cfg";
#endif
if (!boost::filesystem::exists(file_source) || !boost::filesystem::exists(file_ffmpeg) || !boost::filesystem::exists(file_ff_cfg)) {
auto res = MessageDialog(this, _L("Virtual Camera Tools is required for this task!\nDo you want to install them?"), _L("Error"),
auto res = MessageDialog(this, _L("Virtual Camera Tools is required for this task!\nDo you want to install them?"), _L("Info"),
wxOK | wxCANCEL).ShowModal();
if (res == wxID_OK) {
// download tools
@ -345,18 +345,6 @@ void MediaPlayCtrl::ToggleStream()
file.write(url2.c_str(), url2.size());
file.close();
m_streaming = true;
if (wxGetApp().app_config->get("not_show_vcamera_wiki") != "1") {
MessageDialog dlg(this, _L("Virtual camera is started.\nPress 'OK' to navigate the guide page of 'Streaming video of Bambu Printer'."), _L("Information"),
wxOK | wxCANCEL | wxICON_INFORMATION);
dlg.show_dsa_button();
auto res = dlg.ShowModal();
if (dlg.get_checkbox_state())
wxGetApp().app_config->set("not_show_vcamera_wiki", "1");
if (res == wxID_OK) {
auto url = wxString::Format(L"https://wiki.bambulab.com/%s/software/bambu-studio/virtual-camera", L"en");
wxLaunchDefaultBrowser(url);
}
}
});
});
}

View file

@ -1690,7 +1690,7 @@ bool SelectMachineDialog::has_tips(MachineObject* obj)
// must set to a status if return true
if (select_timelapse->IsShown() &&
m_checkbox_list["timelapse"]->GetValue()) {
if (!obj->has_sdcard()) {
if (obj->get_sdcard_state() == MachineObject::SdcardState::NO_SDCARD) {
show_status(PrintDialogStatus::PrintStatusTimelapseNoSdcard);
return true;
}
@ -2518,14 +2518,14 @@ void SelectMachineDialog::update_show_status()
show_status(PrintDialogStatus::PrintStatusInPrinting);
return;
}
else if (!obj_->is_function_supported(PrinterFunction::FUNC_PRINT_WITHOUT_SD) && !obj_->has_sdcard()) {
else if (!obj_->is_function_supported(PrinterFunction::FUNC_PRINT_WITHOUT_SD) && (obj_->get_sdcard_state() == MachineObject::SdcardState::NO_SDCARD)) {
show_status(PrintDialogStatus::PrintStatusNoSdcard);
return;
}
// check sdcard when if lan mode printer
if (obj_->is_lan_mode_printer()) {
if (!obj_->has_sdcard()) {
if (obj_->get_sdcard_state() == MachineObject::SdcardState::NO_SDCARD) {
show_status(PrintDialogStatus::PrintStatusLanModeNoSdcard);
return;
}

View file

@ -904,7 +904,7 @@ void SendToPrinterDialog::update_show_status()
// check sdcard when if lan mode printer
/* if (obj_->is_lan_mode_printer()) {
}*/
if (!obj_->has_sdcard()) {
if (obj_->get_sdcard_state() == MachineObject::SdcardState::NO_SDCARD) {
show_status(PrintDialogStatus::PrintStatusNoSdcard);
return;
}

View file

@ -186,7 +186,10 @@ void StatusBasePanel::init_bitmaps()
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_on = create_scaled_bitmap("sdcard_state_on", nullptr, 20);
m_bitmap_sdcard_state_off = create_scaled_bitmap("sdcard_state_off", nullptr, 20);
m_bitmap_sdcard_state_abnormal = create_scaled_bitmap("sdcard_state_abnormal", nullptr, 20);
m_bitmap_recording = create_scaled_bitmap("recording", nullptr, 20);
m_bitmap_timelapse = create_scaled_bitmap("timelapse", nullptr, 20);
m_bitmap_vcamera = create_scaled_bitmap("vcamera", nullptr, 20);
}
wxBoxSizer *StatusBasePanel::create_monitoring_page()
@ -223,33 +226,42 @@ wxBoxSizer *StatusBasePanel::create_monitoring_page()
//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_off_img = new wxStaticBitmap(m_panel_monitoring_title, wxID_ANY, m_bitmap_sdcard_state_off, wxDefaultPosition, wxSize(FromDIP(38), FromDIP(24)), 0);
m_bitmap_sdcard_off_img->SetMinSize(wxSize(FromDIP(38), FromDIP(24)));
m_bitmap_sdcard_abnormal_img = new wxStaticBitmap(m_panel_monitoring_title, wxID_ANY, m_bitmap_sdcard_state_abnormal, wxDefaultPosition, wxSize(FromDIP(38), FromDIP(24)), 0);
m_bitmap_sdcard_abnormal_img->SetMinSize(wxSize(FromDIP(38), FromDIP(24)));
m_bitmap_sdcard_on_img = new wxStaticBitmap(m_panel_monitoring_title, wxID_ANY, m_bitmap_sdcard_state_on, wxDefaultPosition, wxSize(FromDIP(38), FromDIP(24)), 0);
m_bitmap_sdcard_on_img->SetMinSize(wxSize(FromDIP(38), FromDIP(24)));
m_bitmap_sdcard_on_img->Hide();
m_bitmap_sdcard_abnormal_img->Hide();
m_timelapse_button = new CameraItem(m_panel_monitoring_title, "timelapse_off_normal", "timelapse_on_normal", "timelapse_off_hover", "timelapse_on_hover");
m_timelapse_button->SetMinSize(wxSize(FromDIP(38), FromDIP(24)));
m_timelapse_button->SetBackgroundColour(STATUS_TITLE_BG);
m_bitmap_timelapse_img = new wxStaticBitmap(m_panel_monitoring_title, wxID_ANY, m_bitmap_timelapse, wxDefaultPosition, wxSize(FromDIP(38), FromDIP(24)), 0);
m_bitmap_timelapse_img->SetMinSize(wxSize(FromDIP(38), FromDIP(24)));
m_bitmap_timelapse_img->Hide();
m_recording_button = new CameraItem(m_panel_monitoring_title, "recording_off_normal", "recording_on_normal", "recording_off_hover", "recording_on_hover");
m_recording_button->SetMinSize(wxSize(FromDIP(38), FromDIP(24)));
m_recording_button->SetBackgroundColour(STATUS_TITLE_BG);
m_bitmap_recording_img = new wxStaticBitmap(m_panel_monitoring_title, wxID_ANY, m_bitmap_recording, wxDefaultPosition, wxSize(FromDIP(38), FromDIP(24)), 0);
m_bitmap_recording_img->SetMinSize(wxSize(FromDIP(38), FromDIP(24)));
m_bitmap_timelapse_img->Hide();
m_vcamera_button = new CameraItem(m_panel_monitoring_title, "vcamera_off_normal", "vcamera_on_normal", "vcamera_off_hover", "vcamera_on_hover");
m_vcamera_button->SetMinSize(wxSize(FromDIP(38), FromDIP(24)));
m_vcamera_button->SetBackgroundColour(STATUS_TITLE_BG);
m_bitmap_vcamera_img = new wxStaticBitmap(m_panel_monitoring_title, wxID_ANY, m_bitmap_vcamera, wxDefaultPosition, wxSize(FromDIP(38), FromDIP(24)), 0);
m_bitmap_vcamera_img->SetMinSize(wxSize(FromDIP(38), FromDIP(24)));
m_bitmap_vcamera_img->Hide();
m_timelapse_button->SetToolTip(_L("Timelapse"));
m_recording_button->SetToolTip(_L("Video"));
m_vcamera_button->SetToolTip(_L("Virtual Camera"));
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);
bSizer_monitoring_title->Add(m_bitmap_sdcard_off_img, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
m_bitmap_sdcard_on_img->SetToolTip(_L("SD Card"));
m_bitmap_sdcard_abnormal_img->SetToolTip(_L("SD Card Abnormal"));
m_bitmap_timelapse_img->SetToolTip(_L("Timelapse"));
m_bitmap_recording_img->SetToolTip(_L("Video"));
m_bitmap_vcamera_img->SetToolTip(_L("Virtual Camera"));
m_setting_button->SetToolTip(_L("Camera Setting"));
bSizer_monitoring_title->Add(m_bitmap_sdcard_abnormal_img, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
bSizer_monitoring_title->Add(m_bitmap_sdcard_on_img, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
bSizer_monitoring_title->Add(m_timelapse_button, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
bSizer_monitoring_title->Add(m_recording_button, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
bSizer_monitoring_title->Add(m_vcamera_button, 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);
@ -1027,39 +1039,46 @@ void StatusBasePanel::show_ams_group(bool show)
m_show_ams_group = show;
}
void StatusBasePanel::upodate_camera_state(bool recording, bool timelapse, bool has_sdcard)
void StatusPanel::update_img_status(wxStaticBitmap* img, bool on_off)
{
if (on_off)
img->Show();
else
img->Hide();
}
void StatusPanel::update_camera_state(bool recording, bool timelapse, MachineObject::SdcardState sdcard_state)
{
//sdcard
/* if (has_sdcard && !m_bitmap_sdcard_img->IsShown()) {
m_bitmap_sdcard_img->Show();
m_panel_monitoring_title->Layout();
switch (sdcard_state) {
case MachineObject::SdcardState::NO_SDCARD:
m_bitmap_sdcard_on_img->Hide();
m_bitmap_sdcard_abnormal_img->Hide();
break;
case MachineObject::SdcardState::HAS_SDCARD_NORMAL:
m_bitmap_sdcard_on_img->Show();
m_bitmap_sdcard_abnormal_img->Hide();
break;
case MachineObject::SdcardState::HAS_SDCARD_ABNORMAL:
m_bitmap_sdcard_on_img->Hide();
m_bitmap_sdcard_abnormal_img->Show();
break;
default:
;
}
if (!has_sdcard && m_bitmap_sdcard_img->IsShown()) {
m_bitmap_sdcard_img->Hide();
m_panel_monitoring_title->Layout();
}*/
if (has_sdcard) {
if (m_bitmap_sdcard_off_img->IsShown()) {
m_bitmap_sdcard_on_img->Show();
m_bitmap_sdcard_off_img->Hide();
m_panel_monitoring_title->Layout();
}
} else {
if (m_bitmap_sdcard_on_img->IsShown()) {
m_bitmap_sdcard_on_img->Hide();
m_bitmap_sdcard_off_img->Show();
m_panel_monitoring_title->Layout();
}
}
//recording
m_recording_button->set_switch(recording);
m_vcamera_button->set_switch(m_media_play_ctrl->IsStreaming());
//recording
update_img_status(m_bitmap_recording_img, recording);
//timelapse
m_timelapse_button->set_switch(timelapse);
update_img_status(m_bitmap_timelapse_img, timelapse);
//vcamera
update_img_status(m_bitmap_vcamera_img, m_media_play_ctrl->IsStreaming());
show_vcamera = m_media_play_ctrl->IsStreaming();
//camera setting
if (m_camera_popup) {
m_camera_popup->update();
m_camera_popup->sync_vcamera_state(show_vcamera);
}
m_panel_monitoring_title->Layout();
}
StatusPanel::StatusPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, const wxString &name)
@ -1110,10 +1129,8 @@ StatusPanel::StatusPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, co
// Connect Events
//m_bitmap_thumbnail->Connect(wxEVT_ENTER_WINDOW, wxMouseEventHandler(StatusPanel::on_thumbnail_enter), NULL, this);
//m_bitmap_thumbnail->Connect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(StatusPanel::on_thumbnail_leave), NULL, this);
m_recording_button->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(StatusPanel::on_switch_recording), NULL, this);
m_vcamera_button->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(StatusPanel::on_switch_vcamera), NULL, this);
m_setting_button->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(StatusPanel::on_camera_enter), NULL, this);
m_project_task_panel->Connect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(StatusPanel::on_thumbnail_leave), NULL, this);
m_button_pause_resume->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_pause_resume), NULL, this);
m_button_abort->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_abort), NULL, this);
m_button_clean->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_print_error_clean), NULL, this);
@ -1151,8 +1168,7 @@ StatusPanel::~StatusPanel()
// Disconnect Events
//m_bitmap_thumbnail->Disconnect(wxEVT_ENTER_WINDOW, wxMouseEventHandler(StatusPanel::on_thumbnail_enter), NULL, this);
//m_bitmap_thumbnail->Disconnect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(StatusPanel::on_thumbnail_leave), NULL, this);
m_recording_button->Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(StatusPanel::on_switch_recording), NULL, this);
m_vcamera_button->Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(StatusPanel::on_switch_vcamera), NULL, this);
m_setting_button->Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(StatusPanel::on_camera_enter), NULL, this);
m_button_pause_resume->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_pause_resume), NULL, this);
m_button_abort->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_abort), NULL, this);
m_button_clean->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_print_error_clean), NULL, this);
@ -1181,6 +1197,9 @@ StatusPanel::~StatusPanel()
if (abort_dlg != nullptr)
delete abort_dlg;
if (sdcard_hint_dlg != nullptr)
delete sdcard_hint_dlg;
}
void StatusPanel::init_scaled_buttons()
@ -1388,24 +1407,6 @@ void StatusPanel::update(MachineObject *obj)
m_options_btn->Hide();
}
if (obj->is_function_supported(PrinterFunction::FUNC_TIMELAPSE)) {
m_timelapse_button->Show();
} else {
m_timelapse_button->Hide();
}
if (obj->is_function_supported(PrinterFunction::FUNC_RECORDING) || obj->has_ipcam) {
m_recording_button->Show();
} else {
m_recording_button->Hide();
}
if (obj->is_function_supported(PrinterFunction::FUNC_VIRTUAL_CAMERA) && obj->has_ipcam) {
m_vcamera_button->Show();
} else {
m_vcamera_button->Hide();
}
if (obj->is_function_supported(PrinterFunction::FUNC_CHAMBER_TEMP)) {
m_tempCtrl_frame->Enable();
} else {
@ -1417,7 +1418,8 @@ void StatusPanel::update(MachineObject *obj)
update_error_message();
}
upodate_camera_state(obj->is_recording_enable(), obj->has_timelapse(), obj->has_sdcard());
update_camera_state(obj->is_recording_enable(), obj->has_timelapse(), obj->get_sdcard_state());
m_machine_ctrl_panel->Thaw();
}
@ -2552,25 +2554,30 @@ void StatusPanel::on_thumbnail_leave(wxMouseEvent &event)
}
}
void StatusPanel::on_switch_recording(wxMouseEvent &event)
{
if (!obj) return;
bool value = m_recording_button->get_switch_status();
obj->command_ipcam_record(!value);
}
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) {
m_camera_popup = std::make_shared<CameraPopup>(this, 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::ButtonStyle::ONLY_CONFIRM);
sdcard_hint_dlg->update_text(_L("Can't start this without SD card."));
}
sdcard_hint_dlg->on_show();
});
wxWindow* ctrl = (wxWindow*)event.GetEventObject();
wxPoint pos = ctrl->ClientToScreen(wxPoint(0, 0));
wxSize sz = ctrl->GetSize();
@ -2654,9 +2661,10 @@ void StatusPanel::set_default()
m_show_ams_group = false;
reset_printing_values();
m_timelapse_button->Show();
m_recording_button->Show();
m_vcamera_button->Show();
m_bitmap_timelapse_img->Hide();
m_bitmap_recording_img->Hide();
m_bitmap_vcamera_img->Hide();
m_setting_button->Show();
m_tempCtrl_frame->Show();
m_options_btn->Show();
@ -2730,10 +2738,11 @@ void StatusPanel::msw_rescale()
//m_bitmap_camera_img->SetBitmap(m_bitmap_camera);
//m_bitmap_camera_img->SetMinSize(wxSize(FromDIP(32), FromDIP(18)));
m_timelapse_button->SetMinSize(wxSize(38, 24));
m_recording_button->SetMinSize(wxSize(38, 24));
m_vcamera_button->SetMinSize(wxSize(38, 24));
m_bitmap_sdcard_off_img->SetMinSize(wxSize(FromDIP(38), FromDIP(24)));
m_bitmap_timelapse_img->SetMinSize(wxSize(38, 24));
m_bitmap_recording_img->SetMinSize(wxSize(38, 24));
m_bitmap_vcamera_img->SetMinSize(wxSize(38, 24));
m_setting_button->SetMinSize(wxSize(38, 24));
m_bitmap_sdcard_abnormal_img->SetMinSize(wxSize(FromDIP(38), FromDIP(24)));
m_bitmap_sdcard_on_img->SetMinSize(wxSize(FromDIP(38), FromDIP(24)));
m_bpButton_xy->Rescale();

View file

@ -90,13 +90,14 @@ protected:
CameraTimelapseStatus m_state_timelapse{CameraTimelapseStatus::TIMELAPSE_NONE};
CameraItem *m_timelapse_button;
CameraItem *m_recording_button;
CameraItem *m_vcamera_button;
CameraItem *m_setting_button;
wxBitmap m_bitmap_camera;
wxBitmap m_bitmap_sdcard_state_on;
wxBitmap m_bitmap_sdcard_state_off;
wxBitmap m_bitmap_sdcard_state_abnormal;
wxBitmap m_bitmap_recording;
wxBitmap m_bitmap_timelapse;
wxBitmap m_bitmap_vcamera;
/* title panel */
wxPanel * media_ctrl_panel;
@ -112,8 +113,10 @@ protected:
wxStaticBitmap *m_bitmap_camera_img;
wxStaticBitmap *m_bitmap_recording_img;
wxStaticBitmap *m_bitmap_timelapse_img;
wxStaticBitmap* m_bitmap_vcamera_img;
wxStaticBitmap *m_bitmap_sdcard_on_img;
wxStaticBitmap *m_bitmap_sdcard_off_img;
wxStaticBitmap *m_bitmap_sdcard_abnormal_img;
wxStaticBitmap *m_bitmap_static_use_time;
wxStaticBitmap *m_bitmap_static_use_weight;
@ -239,7 +242,6 @@ public:
wxBoxSizer *create_settings_group(wxWindow *parent);
void show_ams_group(bool show = true);
void upodate_camera_state(bool recording, bool timelapse, bool has_sdcard);
};
@ -259,6 +261,7 @@ protected:
AMSMaterialsSetting *m_filament_setting_dlg{nullptr};
SecondaryCheckDialog* m_print_error_dlg = nullptr;
SecondaryCheckDialog* abort_dlg = nullptr;
SecondaryCheckDialog* sdcard_hint_dlg = nullptr;
wxString m_request_url;
bool m_start_loading_thumbnail = false;
@ -323,7 +326,6 @@ protected:
void on_nozzle_fan_switch(wxCommandEvent &event);
void on_thumbnail_enter(wxMouseEvent &event);
void on_thumbnail_leave(wxMouseEvent &event);
void on_switch_recording(wxMouseEvent &event);
void on_switch_vcamera(wxMouseEvent &event);
void on_camera_enter(wxMouseEvent &event);
void on_camera_leave(wxMouseEvent& event);
@ -355,6 +357,11 @@ protected:
void on_webrequest_state(wxWebRequestEvent &evt);
bool is_task_changed(MachineObject* obj);
/* camera */
void update_camera_state(bool recording, bool timelapse, MachineObject::SdcardState sdcard_state);
void update_img_status(wxStaticBitmap* img, bool on_off);
bool show_vcamera = false;
public:
StatusPanel(wxWindow * parent,
wxWindowID id = wxID_ANY,