Merge remote-tracking branch 'remote/master' into SoftFever

# Conflicts:
#	resources/profiles/BBL/filament/Bambu PC @BBL X1C.json
#	resources/profiles/BBL/filament/Bambu TPU 95A @BBL X1C.json
This commit is contained in:
SoftFever 2022-07-23 20:29:33 +08:00
commit b806df7710
269 changed files with 10330 additions and 32230 deletions

View file

@ -221,8 +221,8 @@ set(SLIC3R_GUI_SOURCES
GUI/Monitor.hpp
GUI/WebViewDialog.cpp
GUI/WebViewDialog.hpp
GUI/WebDailytipDialog.hpp
GUI/WebDailytipDialog.cpp
GUI/WebDownPluginDlg.hpp
GUI/WebDownPluginDlg.cpp
GUI/WebGuideDialog.hpp
GUI/WebGuideDialog.cpp
GUI/WebUserLoginDialog.cpp
@ -268,12 +268,16 @@ set(SLIC3R_GUI_SOURCES
GUI/ConfigWizard_private.hpp
GUI/MsgDialog.cpp
GUI/MsgDialog.hpp
GUI/DownloadProgressDialog.hpp
GUI/DownloadProgressDialog.cpp
GUI/UpdateDialogs.cpp
GUI/UpdateDialogs.hpp
GUI/Jobs/Job.hpp
GUI/Jobs/Job.cpp
GUI/Jobs/PlaterJob.hpp
GUI/Jobs/PlaterJob.cpp
GUI/Jobs/UpgradeNetworkJob.hpp
GUI/Jobs/UpgradeNetworkJob.cpp
GUI/Jobs/ArrangeJob.hpp
GUI/Jobs/ArrangeJob.cpp
GUI/Jobs/OrientJob.hpp

View file

@ -4,9 +4,14 @@
#include "I18N.hpp"
namespace Slic3r { namespace GUI {
static bool show_flag;
AMSMaterialsSetting::AMSMaterialsSetting(wxWindow *parent, wxWindowID id): wxPopupTransientWindow(parent, id)
{
#ifdef __APPLE__
#define COMBOBOX_FILAMENT (m_comboBox_filament_mac)
#else
#define COMBOBOX_FILAMENT (m_comboBox_filament)
#endif
AMSMaterialsSetting::AMSMaterialsSetting(wxWindow *parent, wxWindowID id) : wxPopupTransientWindow(parent, wxPU_CONTAINS_CONTROLS) {
create();
}
@ -28,9 +33,13 @@ void AMSMaterialsSetting::create()
m_sizer_filament->Add(0, 0, 0, wxEXPAND, 0);
#ifdef __APPLE__
m_comboBox_filament_mac = new wxComboBox(m_panel_body, wxID_ANY, wxEmptyString, wxDefaultPosition, AMS_MATERIALS_SETTING_COMBOX_WIDTH, 0, nullptr, wxCB_READONLY);
#else
m_comboBox_filament = new ::ComboBox(m_panel_body, wxID_ANY, wxEmptyString, wxDefaultPosition, AMS_MATERIALS_SETTING_COMBOX_WIDTH, 0, nullptr, wxCB_READONLY);
m_sizer_filament->Add(m_comboBox_filament, 0, wxALIGN_CENTER, 0);
#endif
m_sizer_filament->Add(COMBOBOX_FILAMENT, 1, wxALIGN_CENTER, 0);
wxBoxSizer *m_sizer_colour = new wxBoxSizer(wxHORIZONTAL);
m_title_colour = new wxStaticText(m_panel_body, wxID_ANY, _L("Colour"), wxDefaultPosition, wxSize(AMS_MATERIALS_SETTING_LABEL_WIDTH, -1), 0);
@ -77,18 +86,18 @@ void AMSMaterialsSetting::create()
wxBoxSizer *sizer_other = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *sizer_tempinput = new wxBoxSizer(wxHORIZONTAL);
m_input_nozzle_max = new ::TextInput(m_panel_body, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, AMS_MATERIALS_SETTING_INPUT_SIZE,
wxTE_CENTRE | wxTE_PROCESS_ENTER);
m_input_nozzle_max = new ::TextInput(m_panel_body, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, AMS_MATERIALS_SETTING_INPUT_SIZE, wxTE_CENTRE | wxTE_PROCESS_ENTER);
m_input_nozzle_min = new ::TextInput(m_panel_body, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, AMS_MATERIALS_SETTING_INPUT_SIZE, wxTE_CENTRE | wxTE_PROCESS_ENTER);
m_input_nozzle_max->Enable(false);
m_input_nozzle_min->Enable(false);
m_input_nozzle_max->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
m_input_nozzle_max->GetTextCtrl()->SetSize(wxSize(-1, FromDIP(20)));
auto bitmap_max_degree = new wxStaticBitmap(m_panel_body, -1, create_scaled_bitmap("degree", nullptr, 16), wxDefaultPosition, wxDefaultSize);
m_input_nozzle_min = new ::TextInput(m_panel_body, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, AMS_MATERIALS_SETTING_INPUT_SIZE,
wxTE_CENTRE | wxTE_PROCESS_ENTER);
m_input_nozzle_min->GetTextCtrl()->SetSize(wxSize(-1, FromDIP(20)));
m_input_nozzle_min->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
m_input_nozzle_min->GetTextCtrl()->SetSize(wxSize(-1, FromDIP(20)));
auto bitmap_max_degree = new wxStaticBitmap(m_panel_body, -1, create_scaled_bitmap("degree", nullptr, 16), wxDefaultPosition, wxDefaultSize);
auto bitmap_min_degree = new wxStaticBitmap(m_panel_body, -1, create_scaled_bitmap("degree", nullptr, 16), wxDefaultPosition, wxDefaultSize);
sizer_tempinput->Add(m_input_nozzle_max, 1, wxALIGN_CENTER, 0);
@ -125,7 +134,7 @@ void AMSMaterialsSetting::create()
warning_text->SetMinSize(wxSize(AMS_MATERIALS_SETTING_BODY_WIDTH, -1));
warning_text->Hide();
m_input_nozzle_min->GetTextCtrl()->Bind(wxEVT_SET_FOCUS, [this](wxFocusEvent &e) {
m_input_nozzle_min->GetTextCtrl()->Bind(wxEVT_SET_FOCUS, [this](wxFocusEvent &e) {
warning_text->Hide();
Layout();
Fit();
@ -135,22 +144,22 @@ void AMSMaterialsSetting::create()
input_min_finish();
e.Skip();
});
m_input_nozzle_min->GetTextCtrl()->Bind(wxEVT_KILL_FOCUS, [this](wxFocusEvent &e) {
m_input_nozzle_min->GetTextCtrl()->Bind(wxEVT_KILL_FOCUS, [this](wxFocusEvent &e) {
input_min_finish();
e.Skip();
});
m_input_nozzle_max->GetTextCtrl()->Bind(wxEVT_SET_FOCUS, [this](wxFocusEvent& e) {
m_input_nozzle_max->GetTextCtrl()->Bind(wxEVT_SET_FOCUS, [this](wxFocusEvent &e) {
warning_text->Hide();
Layout();
Fit();
e.Skip();
});
m_input_nozzle_max->GetTextCtrl()->Bind(wxEVT_TEXT_ENTER, [this](wxCommandEvent& e) {
m_input_nozzle_max->GetTextCtrl()->Bind(wxEVT_TEXT_ENTER, [this](wxCommandEvent &e) {
input_max_finish();
e.Skip();
});
m_input_nozzle_max->GetTextCtrl()->Bind(wxEVT_KILL_FOCUS, [this](wxFocusEvent& e) {
m_input_nozzle_max->GetTextCtrl()->Bind(wxEVT_KILL_FOCUS, [this](wxFocusEvent &e) {
input_max_finish();
e.Skip();
});
@ -170,13 +179,6 @@ void AMSMaterialsSetting::create()
m_button_confirm->Bind(wxEVT_LEFT_DOWN, &AMSMaterialsSetting::on_select_ok, this);
m_sizer_button->Add(m_button_confirm, 0, wxALIGN_CENTER, 0);
StateColor btn_bg_white(std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Pressed),
std::pair<wxColour, int>(wxColour(238, 238, 238), StateColor::Hovered),
std::pair<wxColour, int>(*wxWHITE, StateColor::Normal));
StateColor btn_bd_white(std::pair<wxColour, int>(*wxWHITE, StateColor::Disabled), std::pair<wxColour, int>(wxColour(38, 46, 48), StateColor::Enabled));
m_sizer_body->Add(m_sizer_filament, 0, wxEXPAND, 0);
m_sizer_body->Add(0, 0, 0, wxEXPAND | wxTOP, FromDIP(16));
m_sizer_body->Add(m_sizer_colour, 0, wxEXPAND, 0);
@ -200,7 +202,7 @@ void AMSMaterialsSetting::create()
this->Centre(wxBOTH);
Bind(wxEVT_PAINT, &AMSMaterialsSetting::paintEvent, this);
m_comboBox_filament->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(AMSMaterialsSetting::on_select_filament), NULL, this);
COMBOBOX_FILAMENT->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(AMSMaterialsSetting::on_select_filament), NULL, this);
}
void AMSMaterialsSetting::paintEvent(wxPaintEvent &evt)
@ -214,13 +216,13 @@ void AMSMaterialsSetting::paintEvent(wxPaintEvent &evt)
AMSMaterialsSetting::~AMSMaterialsSetting()
{
m_comboBox_filament->Disconnect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(AMSMaterialsSetting::on_select_filament), NULL, this);
COMBOBOX_FILAMENT->Disconnect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(AMSMaterialsSetting::on_select_filament), NULL, this);
}
void AMSMaterialsSetting::input_min_finish()
{
if (m_input_nozzle_min->GetTextCtrl()->GetValue().empty())return;
if (m_input_nozzle_min->GetTextCtrl()->GetValue().empty()) return;
auto val = std::atoi(m_input_nozzle_min->GetTextCtrl()->GetValue().c_str());
@ -235,7 +237,7 @@ void AMSMaterialsSetting::input_min_finish()
void AMSMaterialsSetting::input_max_finish()
{
if (m_input_nozzle_max->GetTextCtrl()->GetValue().empty())return;
if (m_input_nozzle_max->GetTextCtrl()->GetValue().empty()) return;
auto val = std::atoi(m_input_nozzle_max->GetTextCtrl()->GetValue().c_str());
@ -279,8 +281,8 @@ void AMSMaterialsSetting::enable_confirm_button(bool en)
void AMSMaterialsSetting::on_select_ok(wxMouseEvent &event)
{
wxString nozzle_temp_min = m_input_nozzle_min->GetTextCtrl()->GetValue();
auto filament = m_comboBox_filament->GetValue();
wxString nozzle_temp_min = m_input_nozzle_min->GetTextCtrl()->GetValue();
auto filament = COMBOBOX_FILAMENT->GetValue();
wxString nozzle_temp_max = m_input_nozzle_max->GetTextCtrl()->GetValue();
@ -295,7 +297,7 @@ void AMSMaterialsSetting::on_select_ok(wxMouseEvent &event)
PresetBundle *preset_bundle = wxGetApp().preset_bundle;
if (preset_bundle) {
for (auto it = preset_bundle->filaments.begin(); it != preset_bundle->filaments.end(); it++) {
if (it->alias.compare(m_comboBox_filament->GetValue().ToStdString()) == 0) {
if (it->alias.compare(COMBOBOX_FILAMENT->GetValue().ToStdString()) == 0) {
ams_filament_id = it->filament_id;
}
}
@ -313,19 +315,12 @@ void AMSMaterialsSetting::on_select_ok(wxMouseEvent &event)
void AMSMaterialsSetting::set_color(wxColour color)
{
m_clrData = new wxColourData();
m_clrData->SetColour(color);
}
static bool show_flag;
void AMSMaterialsSetting::on_clr_picker(wxCommandEvent & event) {
void AMSMaterialsSetting::on_clr_picker(wxCommandEvent & event)
{
auto clr_dialog = new wxColourDialog(this, m_clrData);
clr_dialog->Bind(wxEVT_ACTIVATE, [this](wxActivateEvent &e) {
int a ;
});
show_flag = true;
if (clr_dialog->ShowModal() == wxID_OK) {
m_clrData = &(clr_dialog->GetColourData());
@ -338,12 +333,14 @@ void AMSMaterialsSetting::Dismiss()
if (show_flag)
{
show_flag = false;
}
else
} else
{
wxPopupTransientWindow::Dismiss();
#ifdef __APPLE__
#else
wxPopupTransientWindow::Dismiss();
#endif
}
}
bool AMSMaterialsSetting::Show(bool show)
@ -360,12 +357,14 @@ void AMSMaterialsSetting::Popup(bool show, bool third, wxString filament, wxColo
{
if (!m_is_third) {
m_panel_SN->Show();
m_comboBox_filament->SetValue(filament);
COMBOBOX_FILAMENT->SetValue(filament);
m_sn_number->SetLabelText(sn);
m_input_nozzle_min->GetTextCtrl()->SetValue(tep);
m_clrData->SetColour(colour);
m_comboBox_filament->Disable();
COMBOBOX_FILAMENT->Disable();
m_input_nozzle_min->Disable();
wxPopupTransientWindow::Popup();
Layout();
return;
@ -438,13 +437,13 @@ void AMSMaterialsSetting::Popup(bool show, bool third, wxString filament, wxColo
}
}
}
m_comboBox_filament->Set(filament_items);
COMBOBOX_FILAMENT->Set(filament_items);
if (selection_idx >= 0 && selection_idx < filament_items.size()) {
m_comboBox_filament->SetSelection(selection_idx);
COMBOBOX_FILAMENT->SetSelection(selection_idx);
post_select_event();
}
else {
m_comboBox_filament->SetSelection(selection_idx);
COMBOBOX_FILAMENT->SetSelection(selection_idx);
post_select_event();
}
}
@ -453,8 +452,8 @@ void AMSMaterialsSetting::Popup(bool show, bool third, wxString filament, wxColo
void AMSMaterialsSetting::post_select_event() {
wxCommandEvent event(wxEVT_COMBOBOX);
event.SetEventObject(m_comboBox_filament);
wxPostEvent(m_comboBox_filament, event);
event.SetEventObject(COMBOBOX_FILAMENT);
wxPostEvent(COMBOBOX_FILAMENT, event);
}
void AMSMaterialsSetting::on_select_filament(wxCommandEvent &evt)
@ -464,7 +463,7 @@ void AMSMaterialsSetting::on_select_filament(wxCommandEvent &evt)
if (preset_bundle) {
for (auto it = preset_bundle->filaments.begin(); it != preset_bundle->filaments.end(); it++) {
auto a = it->alias;
if (it->alias.compare(m_comboBox_filament->GetValue().ToStdString()) == 0) {
if (it->alias.compare(COMBOBOX_FILAMENT->GetValue().ToStdString()) == 0) {
// ) if nozzle_temperature_range is found
ConfigOption* opt_min = it->config.option("nozzle_temperature_range_low");
if (opt_min) {
@ -498,10 +497,24 @@ void AMSMaterialsSetting::on_select_filament(wxCommandEvent &evt)
}
}
if (m_input_nozzle_min->GetTextCtrl()->GetValue().IsEmpty()) {
m_input_nozzle_min->GetTextCtrl()->SetValue("220");
m_input_nozzle_min->GetTextCtrl()->SetValue("220");
}
if (m_input_nozzle_max->GetTextCtrl()->GetValue().IsEmpty()) {
m_input_nozzle_max->GetTextCtrl()->SetValue("220");
m_input_nozzle_max->GetTextCtrl()->SetValue("220");
}
}
bool AMSMaterialsSetting::ProcessLeftDown(wxMouseEvent &evt)
{
wxPoint mouse_pos = ClientToScreen(evt.GetPosition());
wxPoint top_left = this->ClientToScreen(wxPoint(0, 0));
wxPoint range = wxPoint(this->GetRect().width, this->GetRect().height);
wxPoint bottom_right = top_left + range;
if (mouse_pos.x > top_left.x && mouse_pos.y > top_left.y && mouse_pos.x < bottom_right.x && mouse_pos.y < bottom_right.y) {
return true;
} else {
wxPopupTransientWindow::Dismiss();
return false;
}
}

View file

@ -39,13 +39,13 @@ public:
void input_max_finish();
void update();
void enable_confirm_button(bool en);
void on_select_cancel(wxMouseEvent &event);
void Dismiss() override;
bool Show(bool show) override;
void Popup(bool show, bool third = true, wxString filament = wxEmptyString, wxColour colour = *wxWHITE, wxString sn = wxEmptyString, wxString tep = wxEmptyString);
void post_select_event();
void on_select_ok(wxMouseEvent &event);
void set_color(wxColour color);
void on_clr_picker(wxCommandEvent &event);
@ -67,6 +67,8 @@ protected:
//void on_dpi_changed(const wxRect &suggested_rect) override;
void on_select_filament(wxCommandEvent& evt);
bool ProcessLeftDown(wxMouseEvent &evt);
protected:
StateColor m_btn_bg_green;
wxPanel * m_panel_SN;
@ -82,6 +84,9 @@ protected:
TextInput * m_input_nozzle_min;
TextInput* m_input_nozzle_max;
Button * m_button_confirm;
#ifdef __APPLE__
wxComboBox *m_comboBox_filament_mac;
#endif
wxColourData * m_clrData;
};

View file

@ -80,7 +80,7 @@ CopyrightsDialog::CopyrightsDialog()
SetSizer(sizer);
sizer->SetSizeHints(this);
CenterOnParent();
}
void CopyrightsDialog::fill_entries()
@ -88,6 +88,7 @@ void CopyrightsDialog::fill_entries()
m_entries = {
{ "Admesh", "", "https://admesh.readthedocs.io/" },
{ "Anti-Grain Geometry", "", "http://antigrain.com" },
{ "ArcWelderLib", "", "https://plugins.octoprint.org/plugins/arc_welder" },
{ "Boost", "", "http://www.boost.org" },
{ "Cereal", "", "http://uscilab.github.io/cereal" },
{ "CGAL", "", "https://www.cgal.org" },
@ -115,6 +116,7 @@ void CopyrightsDialog::fill_entries()
{ "Real-Time DXT1/DXT5 C compression library", "", "https://github.com/Cyan4973/RygsDXTc" },
{ "SemVer", "", "https://semver.org" },
{ "Shinyprofiler", "", "https://code.google.com/p/shinyprofiler" },
{ "SuperSlicer", "", "https://github.com/supermerill/SuperSlicer" },
{ "TBB", "", "https://www.intel.cn/content/www/cn/zh/developer/tools/oneapi/onetbb.html" },
{ "wxWidgets", "", "https://www.wxwidgets.org" },
{ "zlib", "", "http://zlib.net" },
@ -219,7 +221,7 @@ AboutDialog::AboutDialog()
std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str();
SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO));
wxPanel *m_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(430), FromDIP(237)), wxTAB_TRAVERSAL);
wxPanel *m_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(560), FromDIP(237)), wxTAB_TRAVERSAL);
wxBoxSizer *panel_versizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *vesizer = new wxBoxSizer(wxVERTICAL);
@ -233,7 +235,7 @@ AboutDialog::AboutDialog()
main_sizer->Add(ver_sizer, 0, wxEXPAND | wxALL, 0);
// logo
m_logo_bitmap = ScalableBitmap(this, "BambuStudio_about", 240);
m_logo_bitmap = ScalableBitmap(this, "BambuStudio_about", 250);
m_logo = new wxStaticBitmap(this, wxID_ANY, m_logo_bitmap.bmp(), wxDefaultPosition,wxDefaultSize, 0);
m_logo->SetSizer(vesizer);
@ -250,20 +252,70 @@ AboutDialog::AboutDialog()
#else
version_font.SetPointSize(11);
#endif
version_font.SetPointSize(12);
version_font.SetPointSize(FromDIP(16));
version->SetFont(version_font);
version->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT));
version->SetForegroundColour(wxColour(255, 255, 255));
version->SetBackgroundColour(wxColour(0, 174, 66));
vesizer->Add(version, 0, wxALL | wxALIGN_CENTER_HORIZONTAL, FromDIP(5));
vesizer->Add(0, 0, 1, wxEXPAND, FromDIP(5));
}
wxStaticText *html_text = new wxStaticText(this, wxID_ANY, "Copyright(C) 2021-2022 Bambu Lab", wxDefaultPosition, wxDefaultSize);
ver_sizer->Add(0, 0, 0, wxTOP, FromDIP(38));
html_text->SetForegroundColour(wxColour(107, 107, 107));
ver_sizer->Add(html_text, 0, wxALL | wxALIGN_CENTER_HORIZONTAL, 0);
wxBoxSizer *text_sizer_horiz = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *text_sizer = new wxBoxSizer(wxVERTICAL);
text_sizer_horiz->Add( 0, 0, 0, wxLEFT, FromDIP(23));
std::vector<wxString> text_list;
text_list.push_back(_L("Bambu Studio is based on PrusaSlicer by PrusaResearch and SuperSlicer by Merill(supermerill)."));
text_list.push_back(_L("PrusaSlicer is originally based on Slic3r by Alessandro Ranellucci."));
text_list.push_back(_L("Slic3r was created by Alessandro Ranellucci with the help of many other contributors."));
text_list.push_back(_L("Bambu Studio also referenced some ideas from Cura by Ultimaker."));
text_list.push_back(_L("There many parts of the software that come from community contributions, so we're unable to list them one-by-one, and instead, they'll be attributed in the corresponding code comments."));
text_sizer->Add( 0, 0, 0, wxTOP, FromDIP(33));
bool is_zh = wxGetApp().app_config->get("language") == "zh_CN";
for (int i = 0; i < text_list.size(); i++)
{
auto staticText = new wxStaticText( this, wxID_ANY, wxEmptyString,wxDefaultPosition,wxSize(FromDIP(520), -1), wxALIGN_LEFT );
staticText->SetForegroundColour(wxColour(107, 107, 107));
staticText->SetMinSize(wxSize(FromDIP(520), -1));
staticText->SetFont(Label::Body_12);
if (is_zh) {
wxString find_txt = "";
wxString count_txt = "";
for (auto o = 0; o < text_list[i].length(); o++) {
auto size = staticText->GetTextExtent(count_txt);
if (size.x < FromDIP(506)) {
find_txt += text_list[i][o];
count_txt += text_list[i][o];
} else {
find_txt += std::string("\n") + text_list[i][o];
count_txt = text_list[i][o];
}
}
staticText->SetLabel(find_txt);
} else {
staticText->SetLabel(text_list[i]);
staticText->Wrap(FromDIP(520));
}
text_sizer->Add( staticText, 0, wxUP | wxDOWN, FromDIP(3));
}
text_sizer_horiz->Add(text_sizer, 1, wxALL,0);
ver_sizer->Add(text_sizer_horiz, 0, wxALL,0);
ver_sizer->Add( 0, 0, 0, wxTOP, FromDIP(43));
wxBoxSizer *copyright_ver_sizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *copyright_hor_sizer = new wxBoxSizer(wxHORIZONTAL);
copyright_hor_sizer->Add(copyright_ver_sizer, 0, wxALL,5);
copyright_hor_sizer->Add( 0, 0, 0, wxLEFT, FromDIP(120));
wxStaticText *html_text = new wxStaticText(this, wxID_ANY, "Copyright(C) 2021-2022 Bambu Lab", wxDefaultPosition, wxDefaultSize);
html_text->SetForegroundColour(wxColour(107, 107, 107));
copyright_ver_sizer->Add(html_text, 0, wxALL , 0);
// text
m_html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_NEVER /*NEVER*/);
{
wxFont font = get_default_font(this);
@ -276,12 +328,12 @@ AboutDialog::AboutDialog()
(boost::format(
"<html>"
"<body>"
"<p style=\"text-align:center\"><a href=\"www.bambulab.com\">www.bambulab.com</ a></p>"
"<p style=\"text-align:left\"><a href=\"www.bambulab.com\">www.bambulab.com</ a></p>"
"</body>"
"</html>")
).str());
m_html->SetPage(text);
ver_sizer->Add(m_html, 0, wxEXPAND, 0);
copyright_ver_sizer->Add(m_html, 0, wxEXPAND, 0);
m_html->Bind(wxEVT_HTML_LINK_CLICKED, &AboutDialog::onLinkClicked, this);
}
//Add "Portions copyright" button
@ -298,14 +350,21 @@ AboutDialog::AboutDialog()
button_portions->SetCornerRadius(FromDIP(12));
button_portions->SetMinSize(wxSize(FromDIP(120), FromDIP(24)));
ver_sizer->Add( 0, 0, 0, wxTOP, FromDIP(22));
ver_sizer->Add(button_portions, 0, wxALIGN_CENTER_HORIZONTAL|wxALL,0);
ver_sizer->Add( 0, 0, 0, wxTOP, FromDIP(38));
wxBoxSizer *copyright_button_ver = new wxBoxSizer(wxVERTICAL);
copyright_button_ver->Add( 0, 0, 0, wxTOP, FromDIP(10));
copyright_button_ver->Add(button_portions, 0, wxALL,0);
copyright_hor_sizer->Add(copyright_button_ver, 0, wxALL,0);
copyright_hor_sizer->Add( 0, 0, 0, wxRIGHT, FromDIP(13));
ver_sizer->Add(copyright_hor_sizer, 0, wxALIGN_CENTER_HORIZONTAL|wxALL,0);
ver_sizer->Add( 0, 0, 0, wxTOP, FromDIP(30));
button_portions->Bind(wxEVT_BUTTON, &AboutDialog::onCopyrightBtn, this);
m_panel->Layout();
SetSizer(main_sizer);
main_sizer->SetSizeHints(this);
Layout();
Fit();
CenterOnParent();
}
void AboutDialog::on_dpi_changed(const wxRect &suggested_rect)

View file

@ -48,11 +48,12 @@ wxDEFINE_EVENT(EVT_SET_FINISH_MAPPING, wxCommandEvent);
void MaterialItem::msw_rescale() {}
void MaterialItem::set_ams_info(wxColour col, wxString txt)
void MaterialItem::set_ams_info(wxColour col, wxString txt)
{
m_ams_coloul = col;
m_ams_name = txt;
Refresh();
auto need_refresh = false;
if (m_ams_coloul != col) { m_ams_coloul = col; need_refresh = true;}
if (m_ams_name != txt) {m_ams_name = txt;need_refresh = true;}
if (need_refresh) { Refresh();}
}
void MaterialItem::on_selected()
@ -74,17 +75,22 @@ void MaterialItem::on_warning()
void MaterialItem::on_normal()
{
m_selected = false;
m_warning = false;
Refresh();
if (m_selected || m_warning) {
m_selected = false;
m_warning = false;
Refresh();
}
}
void MaterialItem::paintEvent(wxPaintEvent &evt)
{
wxPaintDC dc(this);
render(dc);
//PrepareDC(buffdc);
//PrepareDC(dc);
}
void MaterialItem::render(wxDC &dc)
@ -107,29 +113,33 @@ void MaterialItem::render(wxDC &dc)
doRender(dc);
#endif
//materials name
dc.SetFont(::Label::Body_13);
// materials name
dc.SetFont(::Label::Body_13);
auto material_name_colour = m_material_coloul.GetLuminance() < 0.5 ? *wxWHITE : wxColour(0x26,0x2E,0x30);
dc.SetTextForeground(material_name_colour);
auto material_name_colour = m_material_coloul.GetLuminance() < 0.5 ? *wxWHITE : wxColour(0x26, 0x2E, 0x30);
dc.SetTextForeground(material_name_colour);
auto material_txt_size = dc.GetTextExtent(m_material_name);
dc.DrawText(m_material_name, wxPoint((MATERIAL_ITEM_SIZE.x - material_txt_size.x) / 2, FromDIP(3)));
if (dc.GetTextExtent(m_material_name).x > GetSize().x - 10) {
dc.SetFont(::Label::Body_10);
//mapping num
dc.SetFont(::Label::Body_10);
dc.SetTextForeground(m_ams_coloul.GetLuminance() < 0.5 ? *wxWHITE : wxColour(0x26,0x2E,0x30));
}
auto material_txt_size = dc.GetTextExtent(m_material_name);
dc.DrawText(m_material_name, wxPoint((MATERIAL_ITEM_SIZE.x - material_txt_size.x) / 2, (FromDIP(22) - material_txt_size.y) / 2));
wxString mapping_txt = wxEmptyString;
if (m_ams_name.empty()) {
mapping_txt = "-";
}else{
mapping_txt = m_ams_name;
}
auto mapping_txt_size = dc.GetTextExtent(mapping_txt);
dc.DrawText(mapping_txt, wxPoint((MATERIAL_ITEM_SIZE.x - mapping_txt_size.x) / 2, FromDIP(2) + material_txt_size.y ));
// mapping num
dc.SetFont(::Label::Body_10);
dc.SetTextForeground(m_ams_coloul.GetLuminance() < 0.5 ? *wxWHITE : wxColour(0x26, 0x2E, 0x30));
wxString mapping_txt = wxEmptyString;
if (m_ams_name.empty()) {
mapping_txt = "-";
} else {
mapping_txt = m_ams_name;
}
auto mapping_txt_size = dc.GetTextExtent(mapping_txt);
dc.DrawText(mapping_txt, wxPoint((MATERIAL_ITEM_SIZE.x - mapping_txt_size.x) / 2, FromDIP(20) + (FromDIP(14) - mapping_txt_size.y) / 2));
}
void MaterialItem::doRender(wxDC &dc)
@ -137,36 +147,33 @@ void MaterialItem::doRender(wxDC &dc)
//top
dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetBrush(wxBrush(m_material_coloul));
dc.DrawRoundedRectangle(FromDIP(3), FromDIP(3), MATERIAL_ITEM_SIZE.x - FromDIP(6), MATERIAL_ITEM_SIZE.y / 2, 5);
dc.DrawRoundedRectangle(FromDIP(1), FromDIP(1), MATERIAL_ITEM_REAL_SIZE.x, FromDIP(18), 5);
//bottom
dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetBrush(wxBrush(wxColour(m_ams_coloul)));
dc.DrawRoundedRectangle(FromDIP(3), MATERIAL_ITEM_SIZE.y / 2 - FromDIP(2), MATERIAL_ITEM_SIZE.x - FromDIP(6), MATERIAL_ITEM_SIZE.y / 2, 5);
dc.DrawRoundedRectangle(FromDIP(1), FromDIP(18), MATERIAL_ITEM_REAL_SIZE.x, FromDIP(16), 5);
//middle
////middle
dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetBrush(wxBrush(m_material_coloul));
dc.DrawRectangle(FromDIP(3), FromDIP(10), MATERIAL_ITEM_SIZE.x - FromDIP(6), FromDIP(8));
dc.DrawRectangle(FromDIP(1), FromDIP(11), MATERIAL_ITEM_REAL_SIZE.x, FromDIP(8));
//border
if (m_material_coloul == *wxWHITE) {
dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetBrush(wxBrush(m_ams_coloul));
dc.DrawRectangle(FromDIP(1), FromDIP(18), MATERIAL_ITEM_REAL_SIZE.x, FromDIP(8));
////border
if (m_material_coloul == *wxWHITE || m_ams_coloul == *wxWHITE) {
dc.SetPen(wxColour(0xAC, 0xAC, 0xAC));
dc.SetBrush(*wxTRANSPARENT_BRUSH);
dc.DrawRoundedRectangle(3, 3, MATERIAL_ITEM_SIZE.x -6, MATERIAL_ITEM_SIZE.y - 6, 5);
dc.DrawRoundedRectangle(0, 0, MATERIAL_ITEM_SIZE.x, MATERIAL_ITEM_SIZE.y, 5);
}
if (m_selected) {
dc.SetPen(wxColour(0x00, 0xAE, 0x42));
dc.SetBrush(*wxTRANSPARENT_BRUSH);
dc.DrawRoundedRectangle(1, 1, MATERIAL_ITEM_SIZE.x - 2, MATERIAL_ITEM_SIZE.y - 2, 5);
}
if (m_warning) {
dc.SetPen(wxColour(0xFF, 0x6F, 0x00));
dc.SetBrush(*wxTRANSPARENT_BRUSH);
dc.DrawRoundedRectangle(1, 1, MATERIAL_ITEM_SIZE.x - 2, MATERIAL_ITEM_SIZE.y - 2, 5);
dc.DrawRoundedRectangle(0, 0, MATERIAL_ITEM_SIZE.x, MATERIAL_ITEM_SIZE.y, 5);
}
}
@ -186,10 +193,6 @@ void MaterialItem::doRender(wxDC &dc)
Layout();
}
void AmsMapingPopup::Popup(wxWindow *focus /*= NULL*/)
{
wxPopupTransientWindow::Popup();
}
void AmsMapingPopup::update_materials_list(std::vector<std::string> list)
{
@ -210,6 +213,11 @@ bool AmsMapingPopup::is_match_material(int id, std::string material)
void AmsMapingPopup::update_ams_data(std::map<std::string, Ams*> amsList)
{
if (m_amsmapping_sizer_list.size() > 0) {
for (wxBoxSizer *bz : m_amsmapping_sizer_list) { bz->Clear(true); }
m_amsmapping_sizer_list.clear();
}
std::map<std::string, Ams *>::iterator ams_iter;
BOOST_LOG_TRIVIAL(trace) << "ams_mapping total count " << amsList.size();
@ -229,8 +237,6 @@ void AmsMapingPopup::update_ams_data(std::map<std::string, Ams*> amsList)
td.id = ams_indx * AMS_TOTAL_COUNT + atoi(tray_data->id.c_str());
BOOST_LOG_TRIVIAL(trace) << "ams_mapping ams data ==type==" << tray_data->type << "==colour=="<<tray_data->color << "==trayid=="<<tray_data->id.c_str() << "==ftrayid=="<<td.id;
if (!tray_data->is_exists) {
td.type = EMPTY;
} else {
@ -254,9 +260,7 @@ void AmsMapingPopup::update_ams_data(std::map<std::string, Ams*> amsList)
void AmsMapingPopup::add_ams_mapping(std::vector<TrayData> tray_data)
{
wxBoxSizer *sizer_mapping_list = new wxBoxSizer(wxHORIZONTAL);
auto sizer_mapping_list = new wxBoxSizer(wxHORIZONTAL);
for (auto i = 0; i < tray_data.size(); i++) {
wxBoxSizer *sizer_mapping_item = new wxBoxSizer(wxVERTICAL);
@ -299,7 +303,7 @@ void AmsMapingPopup::add_ams_mapping(std::vector<TrayData> tray_data)
if (!is_match_material(tray_data[i].id, tray_data[i].name)) return;
wxCommandEvent event(EVT_SET_FINISH_MAPPING);
event.SetInt(tray_data[i].id);
wxString param = wxString::Format("%d|%d|%d|%02d", tray_data[i].colour.Red(), tray_data[i].colour.Green(), tray_data[i].colour.Blue(), tray_data[i].id + 1);
wxString param = wxString::Format("%d|%d|%d|%02d|%d", tray_data[i].colour.Red(), tray_data[i].colour.Green(), tray_data[i].colour.Blue(), tray_data[i].id + 1, m_current_filament_id);
event.SetString(param);
event.SetEventObject(this->GetParent());
wxPostEvent(this->GetParent(), event);
@ -317,7 +321,7 @@ void AmsMapingPopup::add_ams_mapping(std::vector<TrayData> tray_data)
m_filament_name->Bind(wxEVT_BUTTON, [this, tray_data, i](wxCommandEvent &e) {
wxCommandEvent event(EVT_SET_FINISH_MAPPING);
event.SetInt(tray_data[i].id);
wxString param = wxString::Format("%d|%d|%d|%02d", 0x6B, 0x6B, 0x6B, tray_data[i].id + 1);
wxString param = wxString::Format("%d|%d|%d|%02d|%d", 0x6B, 0x6B, 0x6B, tray_data[i].id + 1, m_current_filament_id);
event.SetString(param);
event.SetEventObject(this->GetParent());
wxPostEvent(this->GetParent(), event);
@ -334,7 +338,7 @@ void AmsMapingPopup::add_ams_mapping(std::vector<TrayData> tray_data)
m_filament_name->Bind(wxEVT_BUTTON, [this, tray_data, i](wxCommandEvent &e) {
wxCommandEvent event(EVT_SET_FINISH_MAPPING);
event.SetInt(tray_data[i].id);
wxString param = wxString::Format("%d|%d|%d|%02d", 0x6B, 0x6B, 0x6B, tray_data[i].id + 1);
wxString param = wxString::Format("%d|%d|%d|%02d|%d", 0x6B, 0x6B, 0x6B, tray_data[i].id + 1, m_current_filament_id);
event.SetString(param);
event.SetEventObject(this->GetParent());
wxPostEvent(this->GetParent(), event);
@ -342,17 +346,17 @@ void AmsMapingPopup::add_ams_mapping(std::vector<TrayData> tray_data)
});
}
sizer_mapping_item->Add(number, 0, wxALIGN_CENTER_HORIZONTAL, 0);
sizer_mapping_item->Add(m_filament_name, 0, wxALIGN_CENTER_HORIZONTAL, 0);
sizer_mapping_list->Add(sizer_mapping_item, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, FromDIP(5));
m_amsmapping_sizer_list.push_back(sizer_mapping_list);
}
m_sizer_main->Add(sizer_mapping_list, 0, wxALIGN_CENTER_HORIZONTAL, 0);
}
void AmsMapingPopup::OnDismiss()
{
delete this;
}
bool AmsMapingPopup::ProcessLeftDown(wxMouseEvent &event)

View file

@ -39,7 +39,8 @@
namespace Slic3r { namespace GUI {
#define MATERIAL_ITEM_SIZE wxSize(FromDIP(42), FromDIP(31))
#define MATERIAL_ITEM_SIZE wxSize(FromDIP(64), FromDIP(34))
#define MATERIAL_ITEM_REAL_SIZE wxSize(FromDIP(62), FromDIP(32))
#define AMS_TOTAL_COUNT 4
enum TrayType {
@ -92,14 +93,18 @@ public:
~AmsMapingPopup() {};
std::vector<std::string> m_materials_list;
std::string m_tag_material;
wxBoxSizer *m_sizer_main;
std::vector<wxBoxSizer*> m_amsmapping_sizer_list;
int m_current_filament_id;
std::string m_tag_material;
wxBoxSizer *m_sizer_main{nullptr};
virtual void Popup(wxWindow *focus = NULL) wxOVERRIDE;
void update_materials_list(std::vector<std::string> list);
void set_tag_texture(std::string texture);
void update_ams_data(std::map<std::string, Ams *> amsList);
void add_ams_mapping(std::vector<TrayData> tray_data);
void set_current_filament_id(int id){m_current_filament_id = id;};
int get_current_filament_id(){return m_current_filament_id;};
bool is_match_material(int id, std::string material);
virtual void OnDismiss() wxOVERRIDE;
virtual bool ProcessLeftDown(wxMouseEvent &event) wxOVERRIDE;

View file

@ -501,7 +501,7 @@ AuFolderPanel::AuFolderPanel(wxWindow *parent, AuxiliaryFolderType type, wxWindo
m_button_add = new Button(m_scrolledWindow, _L("Add"), "auxiliary_add_file", 12, 12);
m_button_add->SetBackgroundColor(btn_bg_white);
m_button_add->SetBorderColor(btn_bd_white);
m_button_add->SetMinSize(wxSize(FromDIP(80), FromDIP(24)));
m_button_add->SetMinSize(wxSize(-1, FromDIP(24)));
m_button_add->SetCornerRadius(12);
m_button_add->SetFont(Label::Body_14);
// m_button_add->Bind(wxEVT_LEFT_UP, &AuxiliaryPanel::on_add, this);
@ -563,7 +563,7 @@ void AuFolderPanel::update(std::vector<fs::path> paths)
void AuFolderPanel::msw_rescale()
{
m_button_add->SetMinSize(wxSize(FromDIP(80), FromDIP(24)));
m_button_add->SetMinSize(wxSize(-1, FromDIP(24)));
for (auto i = 0; i < m_aufiles_list.GetCount(); i++) {
AuFiles *aufile = m_aufiles_list[i];
aufile->file->msw_rescale();
@ -707,21 +707,14 @@ void AuxiliaryPanel::init_tabpanel()
m_tabpanel->SetBackgroundColour(*wxWHITE);
m_tabpanel->Bind(wxEVT_BOOKCTRL_PAGE_CHANGED, [this](wxBookCtrlEvent &e) { ; });
#if !BBL_RELEASE_TO_PUBLIC
m_designer_panel = new DesignerPanel(m_tabpanel, AuxiliaryFolderType::DESIGNER);
#endif
m_pictures_panel = new AuFolderPanel(m_tabpanel, AuxiliaryFolderType::MODEL_PICTURE);
m_bill_of_materials_panel = new AuFolderPanel(m_tabpanel, AuxiliaryFolderType::BILL_OF_MATERIALS);
m_assembly_panel = new AuFolderPanel(m_tabpanel, AuxiliaryFolderType::ASSEMBLY_GUIDE);
m_others_panel = new AuFolderPanel(m_tabpanel, AuxiliaryFolderType::OTHERS);
#if !BBL_RELEASE_TO_PUBLIC
m_tabpanel->AddPage(m_designer_panel, _L("Basic Info"), "", true);
m_tabpanel->AddPage(m_pictures_panel, _L("Pictures"), "", false);
#else
m_tabpanel->AddPage(m_pictures_panel, _L("Pictures"), "", true);
#endif
m_tabpanel->AddPage(m_bill_of_materials_panel, _L("Bill of Materials"), "", false);
m_tabpanel->AddPage(m_assembly_panel, _L("Assembly Guide"), "", false);
m_tabpanel->AddPage(m_others_panel, _L("Others"), "", false);
@ -743,9 +736,7 @@ void AuxiliaryPanel::msw_rescale() {
m_bill_of_materials_panel->msw_rescale();
m_assembly_panel->msw_rescale();
m_others_panel->msw_rescale();
#if !BBL_RELEASE_TO_PUBLIC
m_designer_panel->msw_rescale();
#endif
}
void AuxiliaryPanel::on_size(wxSizeEvent &event)
@ -897,9 +888,7 @@ void AuxiliaryPanel::Reload(wxString aux_path)
fs::create_directory(folder_path.ToStdWstring());
}
update_all_panel();
#if !BBL_RELEASE_TO_PUBLIC
m_designer_panel->update_info();
#endif
return;
}
@ -947,9 +936,7 @@ void AuxiliaryPanel::Reload(wxString aux_path)
update_all_panel();
update_all_cover();
#if !BBL_RELEASE_TO_PUBLIC
m_designer_panel->update_info();
#endif
}
void AuxiliaryPanel::update_all_panel()

View file

@ -77,28 +77,13 @@ void BBLStatusBarBind::set_progress(int val)
if(val < 0)
return;
bool need_layout = false;
//add the logic for arrange/orient jobs, which don't call stop_busy
if(val == m_prog->GetRange()) {
m_prog->SetValue(0);
set_percent_text("0%");
//m_sizer->Hide(m_prog);
need_layout = true;
}
else
{
if (!m_sizer->IsShown(m_prog)) {
m_sizer->Show(m_prog);
m_sizer->Show(m_cancelbutton);
need_layout = true;
}
m_prog->SetValue(val);
set_percent_text(wxString::Format("%d%%", val));
}
if (need_layout) {
m_sizer->Layout();
if (!m_sizer->IsShown(m_prog)) {
m_sizer->Show(m_prog);
m_sizer->Show(m_cancelbutton);
}
m_prog->SetValue(val);
set_percent_text(wxString::Format("%d%%", val));
m_sizer->Layout();
}
int BBLStatusBarBind::get_range() const

View file

@ -26,19 +26,19 @@ BBLStatusBarSend::BBLStatusBarSend(wxWindow *parent, int id)
wxBoxSizer *m_sizer_body = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *m_sizer_bottom = new wxBoxSizer(wxHORIZONTAL);
m_status_text = new wxStaticText(m_self, wxID_ANY, L(""), wxDefaultPosition, wxDefaultSize, 0);
m_status_text = new wxStaticText(m_self, wxID_ANY, L(""), wxDefaultPosition, wxSize(m_self->FromDIP(280), -1), 0);
m_status_text->SetForegroundColour(wxColour(107, 107, 107));
m_status_text->SetFont(::Label::Body_13);
m_status_text->Wrap(-1);
m_sizer_body->Add(m_status_text, 0, 0, 0);
m_status_text->Wrap(m_self->FromDIP(280));
m_prog = new wxGauge(m_self, wxID_ANY, 100, wxDefaultPosition, wxSize(-1, m_self->FromDIP(6)), wxGA_HORIZONTAL);
m_prog->SetValue(0);
block_left = new wxWindow(m_prog, wxID_ANY, wxPoint(0, 0), wxSize(2, m_prog->GetSize().GetHeight() * 2));
block_left->SetBackgroundColour(wxColour(255, 255, 255));
block_right = new wxWindow(m_prog, wxID_ANY, wxPoint(m_prog->GetSize().GetWidth() - 2, 0), wxSize(2, m_prog->GetSize().GetHeight() * 2));
block_right->SetBackgroundColour(wxColour(255, 255, 255));
/* block_left = new wxWindow(m_prog, wxID_ANY, wxPoint(0, 0), wxSize(2, m_prog->GetSize().GetHeight() * 2));
block_left->SetBackgroundColour(wxColour(255, 255, 255));
block_right = new wxWindow(m_prog, wxID_ANY, wxPoint(m_prog->GetSize().GetWidth() - 2, 0), wxSize(2, m_prog->GetSize().GetHeight() * 2));
block_right->SetBackgroundColour(wxColour(255, 255, 255));*/
m_sizer_bottom->Add(m_prog, 1, wxALIGN_CENTER, 0);
@ -47,9 +47,10 @@ BBLStatusBarSend::BBLStatusBarSend(wxWindow *parent, int id)
m_cancelbutton->SetTextColor(wxColour(107, 107, 107));
m_cancelbutton->SetBackgroundColor(wxColour(255, 255, 255));
m_cancelbutton->SetCornerRadius(12);
m_cancelbutton->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &) {
m_cancelbutton->Bind(wxEVT_BUTTON,
[this](wxCommandEvent &evt) {
m_was_cancelled = true;
if (m_cancel_cb_fina)
if (m_cancel_cb_fina)
m_cancel_cb_fina();
});
@ -60,7 +61,9 @@ BBLStatusBarSend::BBLStatusBarSend(wxWindow *parent, int id)
m_sizer_bottom->Add(m_stext_percent, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, 10);
m_sizer_bottom->Add(m_cancelbutton, 0, wxALIGN_CENTER, 0);
m_sizer_body->Add(0, 0, 0, wxTOP, 5);
m_sizer_body->Add(m_status_text, 0, 0, 0);
m_sizer_body->Add(0, 0, 0, wxTOP, 1);
m_sizer_body->Add(m_sizer_bottom, 1, wxEXPAND, 0);
m_sizer->Add(m_sizer_body, 1, wxALIGN_CENTER, 0);
@ -73,8 +76,8 @@ BBLStatusBarSend::BBLStatusBarSend(wxWindow *parent, int id)
void BBLStatusBarSend::set_prog_block()
{
block_left->SetPosition(wxPoint(0, 0));
block_right->SetPosition(wxPoint(m_prog->GetSize().GetWidth() - 2, 0));
//block_left->SetPosition(wxPoint(0, 0));
//block_right->SetPosition(wxPoint(m_prog->GetSize().GetWidth() - 2, 0));
}
int BBLStatusBarSend::get_progress() const
@ -84,33 +87,19 @@ int BBLStatusBarSend::get_progress() const
void BBLStatusBarSend::set_progress(int val)
{
set_prog_block();
//set_prog_block();
if(val < 0)
return;
bool need_layout = false;
//add the logic for arrange/orient jobs, which don't call stop_busy
if(val == m_prog->GetRange()) {
m_prog->SetValue(0);
set_percent_text("0%");
m_sizer->Hide(m_prog);
need_layout = true;
}
else
{
if (!m_sizer->IsShown(m_prog)) {
m_sizer->Show(m_prog);
m_sizer->Show(m_cancelbutton);
need_layout = true;
}
m_prog->SetValue(val);
set_percent_text(wxString::Format("%d%%", val));
}
if (need_layout) {
m_sizer->Layout();
if (!m_sizer->IsShown(m_prog)) {
m_sizer->Show(m_prog);
m_sizer->Show(m_cancelbutton);
}
m_prog->SetValue(val);
set_percent_text(wxString::Format("%d%%", val));
m_sizer->Layout();
}
int BBLStatusBarSend::get_range() const
@ -185,6 +174,9 @@ void BBLStatusBarSend::set_status_text(const wxString& txt)
//auto txtss = "The printing project is being uploaded... 25%%";
//m_status_text->SetLabelText(txtss);
m_status_text->SetLabelText(txt);
m_status_text->SetSize(wxSize(m_self->FromDIP(280), -1));
m_status_text->SetMaxSize(wxSize(m_self->FromDIP(280), -1));
m_status_text->Wrap(m_self->FromDIP(280));
}
void BBLStatusBarSend::set_percent_text(const wxString &txt)
@ -203,7 +195,7 @@ void BBLStatusBarSend::set_status_text(const char *txt)
}
void BBLStatusBarSend::msw_rescale() {
set_prog_block();
//set_prog_block();
m_cancelbutton->SetMinSize(wxSize(m_self->FromDIP(56), m_self->FromDIP(24)));
}
@ -230,6 +222,7 @@ void BBLStatusBarSend::reset()
set_status_text("");
m_was_cancelled = false;
set_progress(0);
set_percent_text(wxString::Format("%d%%", 0));
}
@ -250,4 +243,9 @@ void BBLStatusBarSend::hide_cancel_button()
m_sizer->Layout();
}
void BBLStatusBarSend::change_button_label(wxString name)
{
m_cancelbutton->SetLabel(name);
}
}

View file

@ -73,6 +73,7 @@ public:
// Temporary methods to satisfy Perl side
void show_cancel_button();
void hide_cancel_button();
void change_button_label(wxString name);
private:
bool m_busy = false;

View file

@ -11,6 +11,7 @@
#include "PartPlate.hpp"
#define TOPBAR_ICON_SIZE 18
#define TOPBAR_TITLE_WIDTH 300
using namespace Slic3r;
@ -243,7 +244,7 @@ void BBLTopbar::Init(wxFrame* parent)
this->AddSpacer(FromDIP(10));
this->AddStretchSpacer(1);
m_title_item = this->AddLabel(ID_TITLE, "", FromDIP(300));
m_title_item = this->AddLabel(ID_TITLE, "", FromDIP(TOPBAR_TITLE_WIDTH));
m_title_item->SetAlignment(wxCENTER);
this->AddSpacer(FromDIP(10));
@ -402,6 +403,9 @@ wxMenu* BBLTopbar::GetTopMenu()
void BBLTopbar::SetTitle(wxString title)
{
wxGCDC dc(this);
title = wxControl::Ellipsize(title, dc, wxELLIPSIZE_END, FromDIP(TOPBAR_TITLE_WIDTH));
m_title_item->SetLabel(title);
m_title_item->SetAlignment(wxALIGN_CENTRE_HORIZONTAL);
this->Refresh();

View file

@ -436,17 +436,23 @@ void UnBindMachineDilaog::on_unbind_printer(wxCommandEvent &event)
if (result == 0) {
DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
if (!dev) return;
dev->update_user_machine_list_info();
// clean local machine access code info
MachineObject* obj = dev->get_local_machine(m_machine_info->dev_id);
if (obj) {
obj->set_access_code("");
}
dev->erase_user_machine(m_machine_info->dev_id);
m_status_text->SetLabelText(_L("Log out successful."));
m_button_cancel->SetLabel(_L("Close"));
m_button_unbind->Hide();
EndModal(wxID_OK);
}
else {
m_status_text->SetLabelText(_L("Failed to log out."));
EndModal(wxID_CANCEL);
return;
}
EndModal(wxID_OK);
}
void UnBindMachineDilaog::on_dpi_changed(const wxRect &suggested_rect)

View file

@ -97,13 +97,23 @@ CalibrationDialog::CalibrationDialog(Plater *plater)
auto staticline = new ::StaticLine(cali_right_panel);
staticline->SetLineColour(wxColour(0x00, 0xAE, 0x42));
m_calibration_flow = new StepIndicator(cali_right_panel, wxID_ANY);
auto calibration_panel = new wxPanel(cali_right_panel);
calibration_panel->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8));
auto calibration_sizer = new wxBoxSizer(wxVERTICAL);
calibration_panel->SetMinSize(wxSize(FromDIP(170), FromDIP(160)));
calibration_panel->SetSize(wxSize(FromDIP(170), FromDIP(160)));
m_calibration_flow = new StepIndicator(calibration_panel, wxID_ANY);
StateColor bg_color(std::pair<wxColour, int>(wxColour(248, 248, 248), StateColor::Normal));
m_calibration_flow->SetBackgroundColor(bg_color);
m_calibration_flow->SetFont(Label::Body_12);
m_calibration_flow->SetMinSize(wxSize(FromDIP(170), FromDIP(160)));
m_calibration_flow->SetSize(wxSize(FromDIP(170), FromDIP(160)));
calibration_panel->SetSizer(calibration_sizer);
calibration_panel->Layout();
calibration_sizer->Add(m_calibration_flow, 0, wxALIGN_CENTER_HORIZONTAL | wxEXPAND, 0);
StateColor btn_bg_green(std::pair<wxColour, int>(AMS_CONTROL_DISABLE_COLOUR, StateColor::Disabled), std::pair<wxColour, int>(wxColour(27, 136, 68), StateColor::Pressed),
std::pair<wxColour, int>(wxColour(61, 203, 115), StateColor::Hovered), std::pair<wxColour, int>(AMS_CONTROL_BRAND_COLOUR, StateColor::Normal));
@ -119,10 +129,10 @@ CalibrationDialog::CalibrationDialog(Plater *plater)
cali_right_sizer_v->Add(cali_text_right_top, 0, wxALIGN_CENTER, 0);
cali_right_sizer_v->Add(0, 0, 0, wxTOP, FromDIP(7));
cali_right_sizer_v->Add(staticline, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(10));
cali_right_sizer_v->Add(0, 0, 0, wxTOP, FromDIP(9));
cali_right_sizer_v->Add(m_calibration_flow, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, FromDIP(6));
cali_right_sizer_v->Add(0, 0, 0, wxTOP, FromDIP(10));
cali_right_sizer_v->Add(m_calibration_btn, 0, wxALIGN_CENTER, 0);
cali_right_sizer_v->Add(0, 0, 0, wxTOP, FromDIP(3));
cali_right_sizer_v->Add(calibration_panel, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT, FromDIP(6));
cali_right_sizer_v->Add(0, 0, 1, wxEXPAND, 5);
cali_right_sizer_v->Add(m_calibration_btn, 0, wxALIGN_CENTER_HORIZONTAL, 0);
cali_right_sizer_h->Add(cali_right_sizer_v, 0, wxALIGN_CENTER, 0);
cali_right_panel->SetSizer(cali_right_sizer_h);
@ -137,7 +147,6 @@ CalibrationDialog::CalibrationDialog(Plater *plater)
SetSizer(m_sizer_main);
Layout();
Fit();
Centre(wxBOTH);
Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent &evt) { Hide(); });
@ -151,29 +160,41 @@ void CalibrationDialog::on_dpi_changed(const wxRect &suggested_rect) {}
void CalibrationDialog::update_cali(MachineObject *obj)
{
if (!obj) return;
// in printing
if (obj->is_in_printing()) {
m_calibration_flow->DeleteAllItems();
m_calibration_btn->Disable();
return;
} else {
m_calibration_btn->Enable();
if (!obj->is_in_calibration()) {
m_calibration_flow->DeleteAllItems();
m_calibration_btn->SetLabel(_L("Start Calibration"));
if (obj->is_in_calibration() || obj->is_calibration_done()) {
if (obj->is_calibration_done()) {
m_calibration_btn->Enable();
m_calibration_btn->SetLabel(_L("Completed"));
} else {
// RUNNING && IDLE
m_calibration_btn->Disable();
m_calibration_btn->SetLabel(_L("Calibrating"));
if (is_stage_list_info_changed(obj)) {
// change items if stage_list_info changed
m_calibration_flow->DeleteAllItems();
for (int i = 0; i < obj->stage_list_info.size(); i++) { m_calibration_flow->AppendItem(get_stage_string(obj->stage_list_info[i])); }
}
int index = obj->get_curr_stage_idx();
m_calibration_flow->SelectItem(index);
}
auto size = wxSize(-1, obj->stage_list_info.size() * FromDIP(44));
if (m_calibration_flow->GetSize().y != size.y) {
m_calibration_flow->SetSize(size);
m_calibration_flow->SetMinSize(size);
m_calibration_flow->SetMaxSize(size);
Layout();
}
if (is_stage_list_info_changed(obj)) {
// change items if stage_list_info changed
m_calibration_flow->DeleteAllItems();
for (int i = 0; i < obj->stage_list_info.size(); i++) {
m_calibration_flow->AppendItem(get_stage_string(obj->stage_list_info[i]));
}
}
int index = obj->get_curr_stage_idx();
m_calibration_flow->SelectItem(index);
} else {
// IDLE
if (obj->is_in_printing()) {
m_calibration_btn->Disable();
}
else {
m_calibration_btn->Enable();
}
m_calibration_flow->DeleteAllItems();
m_calibration_btn->SetLabel(_L("Start Calibration"));
}
}
@ -193,11 +214,23 @@ bool CalibrationDialog::is_stage_list_info_changed(MachineObject *obj)
void CalibrationDialog::on_start_calibration(wxMouseEvent &event)
{
if (m_obj) {
BOOST_LOG_TRIVIAL(trace) << "on_start_calibration";
m_obj->command_start_calibration();
if (m_obj->is_calibration_done()) {
m_obj->calibration_done = false;
EndModal(wxID_CANCEL);
Close();
} else {
BOOST_LOG_TRIVIAL(info) << "on_start_calibration";
m_obj->command_start_calibration();
}
}
}
void CalibrationDialog::update_machine_obj(MachineObject *obj) { m_obj = obj; }
bool CalibrationDialog::Show(bool show)
{
if (show) { CentreOnParent(); }
return DPIDialog::Show(show);
}
}} // namespace Slic3r::GUI

View file

@ -50,6 +50,7 @@ public:
bool is_stage_list_info_changed(MachineObject *obj);
void on_start_calibration(wxMouseEvent &event);
void update_machine_obj(MachineObject *obj);
bool Show(bool show) override;
};
}} // namespace Slic3r::GUI

View file

@ -3,6 +3,10 @@
#include "I18N.hpp"
#include "Widgets/Label.hpp"
#include "libslic3r/Utils.hpp"
#include "BitmapCache.hpp"
#include <wx/progdlg.h>
#include <wx/clipbrd.h>
#include <wx/dcgraph.h>
namespace Slic3r {
namespace GUI {
@ -128,5 +132,94 @@ void CameraPopup::OnMouse(wxMouseEvent &event)
}
CameraItem::CameraItem(wxWindow *parent,std::string off_normal, std::string on_normal, std::string off_hover, std::string on_hover)
: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize)
{
#ifdef __WINDOWS__
SetDoubleBuffered(true);
#endif //__WINDOWS__
m_bitmap_on_normal = create_scaled_bitmap(on_normal, nullptr, 20);
m_bitmap_off_normal = create_scaled_bitmap(off_normal, nullptr, 20);
m_bitmap_on_hover = create_scaled_bitmap(on_hover, nullptr, 20);
m_bitmap_off_hover = create_scaled_bitmap(off_hover, nullptr, 20);
SetSize(wxSize(FromDIP(20), FromDIP(20)));
SetMinSize(wxSize(FromDIP(20), FromDIP(20)));
SetMaxSize(wxSize(FromDIP(20), FromDIP(20)));
Bind(wxEVT_PAINT, &CameraItem::paintEvent, this);
Bind(wxEVT_ENTER_WINDOW, &CameraItem::on_enter_win, this);
Bind(wxEVT_LEAVE_WINDOW, &CameraItem::on_level_win, this);
}
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;
Refresh();
}
void CameraItem::on_level_win(wxMouseEvent &evt)
{
m_hover = false;
Refresh();
}
void CameraItem::paintEvent(wxPaintEvent &evt)
{
wxPaintDC dc(this);
render(dc);
// PrepareDC(buffdc);
// PrepareDC(dc);
}
void CameraItem::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 CameraItem::doRender(wxDC &dc)
{
if (m_on) {
if (m_hover) {
dc.DrawBitmap(m_bitmap_on_hover, wxPoint((GetSize().x - m_bitmap_on_hover.GetSize().x) / 2, (GetSize().y - m_bitmap_on_hover.GetSize().y) / 2));
} else {
dc.DrawBitmap(m_bitmap_on_normal, wxPoint((GetSize().x - m_bitmap_on_normal.GetSize().x) / 2, (GetSize().y - m_bitmap_on_normal.GetSize().y) / 2));
}
} else {
if (m_hover) {
dc.DrawBitmap(m_bitmap_off_hover, wxPoint((GetSize().x - m_bitmap_off_hover.GetSize().x) / 2, (GetSize().y - m_bitmap_off_hover.GetSize().y) / 2));
} else {
dc.DrawBitmap(m_bitmap_off_normal, wxPoint((GetSize().x - m_bitmap_off_normal.GetSize().x) / 2, (GetSize().y - m_bitmap_off_normal.GetSize().y) / 2));
}
}
}
}
}

View file

@ -5,6 +5,11 @@
#include "DeviceManager.hpp"
#include "GUI.hpp"
#include <wx/panel.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/sizer.h>
#include <wx/gbsizer.h>
#include <wx/webrequest.h>
#include "Widgets/SwitchButton.hpp"
namespace Slic3r {
@ -44,6 +49,31 @@ private:
wxDECLARE_EVENT_TABLE();
};
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();
MachineObject *m_obj{nullptr};
bool m_on{false};
bool m_hover{false};
wxBitmap m_bitmap_on_normal;
wxBitmap m_bitmap_on_hover;
wxBitmap m_bitmap_off_normal;
wxBitmap m_bitmap_off_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);
void render(wxDC &dc);
void doRender(wxDC &dc);
};
}
}
#endif

View file

@ -519,7 +519,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
for (auto el : { "support_style", "support_base_pattern",
"support_base_pattern_spacing", "support_angle",
"support_interface_pattern", "support_interface_top_layers", "support_interface_bottom_layers",
"bridge_no_support","max_bridge_length" "support_top_z_distance",
"bridge_no_support", "thick_bridges", "max_bridge_length", "support_top_z_distance",
//BBS: add more support params to dependent of enable_support
"support_type","support_on_build_plate_only",
"support_object_xy_distance", "independent_support_layer_height"})
@ -537,6 +537,10 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
toggle_line("tree_support_branch_angle", support_is_tree);
toggle_line("tree_support_wall_count", support_is_tree);
toggle_line("tree_support_with_infill", support_is_tree);
toggle_line("max_bridge_length", support_is_tree);
// tree support use max_bridge_length instead of bridge_no_support
toggle_line("bridge_no_support", !support_is_tree);
for (auto el : { "support_interface_spacing", "support_interface_filament",
"support_interface_loop_pattern", "support_bottom_interface_spacing" })

View file

@ -96,7 +96,7 @@ ConnectPrinterDialog::ConnectPrinterDialog(wxWindow *parent, wxWindowID id, cons
this->SetSizer(main_sizer);
this->Layout();
this->Fit();
this->Centre(wxBOTH);
CentreOnParent();
m_textCtrl_code->Bind(wxEVT_TEXT, &ConnectPrinterDialog::on_input_enter, this);
m_button_confirm->Bind(wxEVT_BUTTON, &ConnectPrinterDialog::on_button_confirm, this);

View file

@ -8,8 +8,9 @@
#include "libslic3r/PlaceholderParser.hpp"
#include "libslic3r/Print.hpp"
#include "libslic3r/PrintConfig.hpp"
#include "MsgDialog.hpp"
#include "Plater.hpp"
#include "GUI_App.hpp"
#include "nlohmann/json.hpp"
#include <thread>
#include <mutex>
@ -24,7 +25,6 @@ using namespace nlohmann;
namespace pt = boost::property_tree;
const int PRINTING_STAGE_COUNT = 20;
std::string PRINTING_STAGE_STR[PRINTING_STAGE_COUNT] = {
"printing",
@ -455,6 +455,16 @@ void MachineObject::_parse_ams_status(int ams_status)
BOOST_LOG_TRIVIAL(trace) << "ams_debug: main = " << ams_status_main_int << ", sub = " << ams_status_sub;
}
bool MachineObject::is_U0_firmware()
{
auto ota_ver_it = module_vers.find("ota");
if (ota_ver_it != module_vers.end()) {
if (ota_ver_it->second.sw_ver.compare("00.01.04.00") < 0)
return true;
}
return false;
}
bool MachineObject::is_support_ams_mapping()
{
AppConfig* config = Slic3r::GUI::wxGetApp().app_config;
@ -590,7 +600,6 @@ int MachineObject::ams_filament_mapping(std::vector<FilamentInfo> filaments, std
// tray_index : tray_color
std::map<int, FilamentInfo> tray_filaments;
for (auto ams = amsList.begin(); ams != amsList.end(); ams++) {
for (auto tray = ams->second->trayList.begin(); tray != ams->second->trayList.end(); tray++) {
int ams_id = atoi(ams->first.c_str());
@ -634,45 +643,48 @@ int MachineObject::ams_filament_mapping(std::vector<FilamentInfo> filaments, std
// is_support_ams_mapping
if (!is_support_ams_mapping()) {
BOOST_LOG_TRIVIAL(info) << "ams_mapping: do not support, use order mapping";
for (int i = 0; i < filaments.size(); i++) {
FilamentInfo info;
if (i < tray_info_list.size()) {
info.id = filaments[i].id;
info.tray_id = filaments[i].id;
info.color = tray_info_list[i].color;
info.type = tray_info_list[i].type;
} else {
info.id = filaments[i].id;
info.tray_id = -1;
}
info.id = filaments[i].id;
info.tray_id = -1;
result.push_back(info);
}
return 0;
}
// calc distance map
struct DisValue {
int tray_id;
float distance;
bool is_same_color = true;
bool is_type_match = true;
};
char buffer[256];
std::vector<std::vector<DisValue>> distance_map;
// print title
::sprintf(buffer, "F(id)");
std::string line = std::string(buffer);
for (auto tray = tray_filaments.begin(); tray != tray_filaments.end(); tray++) {
::sprintf(buffer, " AMS%02d", tray->second.id+1);
line += std::string(buffer);
}
BOOST_LOG_TRIVIAL(info) << "ams_mapping_distance:" << line;
for (int i = 0; i < filaments.size(); i++) {
std::vector<DisValue> rol;
::sprintf(buffer, "F(%02d)", filaments[i].id+1);
line = std::string(buffer);
for (auto tray = tray_filaments.begin(); tray != tray_filaments.end(); tray++) {
DisValue val;
val.tray_id = tray->first;
val.tray_id = tray->second.id;
wxColour c = wxColour(filaments[i].color);
val.distance = calc_color_distance(c, AmsTray::decode_color(tray->second.color));
//val.is_same_color = val.distance < MAPPING_COLOR_THRESHOLD;
if (filaments[i].type != tray->second.type) {
val.distance = 999999;
val.is_type_match = false;
} else {
val.is_type_match = true;
}
::sprintf(buffer, " %6.0f", val.distance);
line += std::string(buffer);
rol.push_back(val);
}
BOOST_LOG_TRIVIAL(info) << "ams_mapping_distance:" << line;
distance_map.push_back(rol);
}
@ -683,6 +695,7 @@ int MachineObject::ams_filament_mapping(std::vector<FilamentInfo> filaments, std
info.tray_id = -1;
result.push_back(info);
}
std::set<int> picked_src;
std::set<int> picked_tar;
for (int k = 0; k < distance_map.size(); k++) {
@ -693,8 +706,9 @@ int MachineObject::ams_filament_mapping(std::vector<FilamentInfo> filaments, std
if (picked_src.find(i) != picked_src.end())
continue;
for (int j = 0; j < distance_map[i].size(); j++) {
if (picked_tar.find(j) == picked_tar.end()
&& distance_map[i][j].is_same_color
if (picked_tar.find(j) != picked_tar.end())
continue;
if (distance_map[i][j].is_same_color
&& distance_map[i][j].is_type_match) {
if (min_val > distance_map[i][j].distance) {
min_val = distance_map[i][j].distance;
@ -707,25 +721,31 @@ int MachineObject::ams_filament_mapping(std::vector<FilamentInfo> filaments, std
if (picked_src_idx >= 0 && picked_tar_idx >= 0) {
auto tray = tray_filaments.find(distance_map[k][picked_tar_idx].tray_id);
if (tray != tray_filaments.end()) {
result[picked_src_idx].tray_id = tray->first;
result[picked_src_idx].color = tray->second.color;
result[picked_src_idx].type = tray->second.type;
BOOST_LOG_TRIVIAL(trace) << "tray_id = " << tray->first << ", distance = " << distance_map[k][picked_tar_idx].distance;
result[picked_src_idx].tray_id = tray->first;
result[picked_src_idx].color = tray->second.color;
result[picked_src_idx].type = tray->second.type;
result[picked_src_idx].distance = tray->second.distance;
}
else {
FilamentInfo info;
info.tray_id = -1;
}
picked_tar.insert(picked_tar_idx);
::sprintf(buffer, "ams_mapping, picked F(%02d) AMS(%02d), distance=%6.0f", picked_src_idx+1, picked_tar_idx+1,
distance_map[picked_src_idx][picked_tar_idx].distance);
BOOST_LOG_TRIVIAL(info) << std::string(buffer);
picked_src.insert(picked_src_idx);
picked_tar.insert(picked_tar_idx);
}
}
std::vector<FilamentInfo> cache_map_result = result;
//check ams mapping result
if (is_valid_mapping_result(result)) {
return 0;
}
reset_mapping_result(result);
try {
// try to use ordering ams mapping
bool order_mapping_result = true;
@ -749,15 +769,23 @@ int MachineObject::ams_filament_mapping(std::vector<FilamentInfo> filaments, std
}
//check order mapping result
if (!is_valid_mapping_result(result)) {
reset_mapping_result(result);
return -1;
if (is_valid_mapping_result(result)) {
return 0;
}
} catch(...) {
reset_mapping_result(result);
return -1;
}
// try to match some color
reset_mapping_result(result);
result = cache_map_result;
for (auto it = result.begin(); it != result.end(); it++) {
if (it->distance >= 6000) {
it->tray_id = -1;
}
}
return 0;
}
@ -778,6 +806,7 @@ void MachineObject::reset_mapping_result(std::vector<FilamentInfo>& result)
{
for (int i = 0; i < result.size(); i++) {
result[i].tray_id = -1;
result[i].distance = 99999;
}
}
@ -904,7 +933,7 @@ std::map<int, MachineObject::ModuleVersionInfo> MachineObject::get_ams_version()
bool MachineObject::is_system_printing()
{
if (is_in_calibration())
if (is_in_calibration() && is_in_printing_status(print_status))
return true;
//FIXME
//if (print_type == "system" && is_in_printing_status(print_status))
@ -936,10 +965,40 @@ bool MachineObject::is_in_calibration()
if (boost::contains(m_gcode_file, "auto_cali_for_user.gcode")
&& stage_curr != 0) {
return true;
} else {
// reset
if (stage_curr != 0) {
calibration_done = false;
}
}
return false;
}
bool MachineObject::is_calibration_done()
{
return calibration_done;
}
bool MachineObject::is_calibration_running()
{
if (is_in_calibration() && is_in_printing_status(print_status))
return true;
return false;
}
void MachineObject::parse_state_changed_event()
{
// parse calibration done
if (last_mc_print_stage != mc_print_stage) {
if (mc_print_stage == 1 && boost::contains(m_gcode_file, "auto_cali_for_user.gcode")) {
calibration_done = true;
} else {
calibration_done = false;
}
}
last_mc_print_stage = mc_print_stage;
}
PrintingSpeedLevel MachineObject::_parse_printing_speed_lvl(int lvl)
{
if (lvl < (int)SPEED_LEVEL_COUNT)
@ -950,7 +1009,10 @@ PrintingSpeedLevel MachineObject::_parse_printing_speed_lvl(int lvl)
bool MachineObject::is_sdcard_printing()
{
if (can_abort() && obj_subtask_id.compare("0") == 0 && profile_id_ == "0" && project_id_ == "0")
if (can_abort()
&& (obj_subtask_id.compare("0") == 0 || obj_subtask_id.empty())
&& (profile_id_ == "0" || profile_id_.empty())
&& (project_id_ == "0" || project_id_.empty()))
return true;
else
return false;
@ -961,6 +1023,16 @@ bool MachineObject::has_sdcard()
return camera_has_sdcard;
}
bool MachineObject::has_timelapse()
{
return camera_timelapse;
}
bool MachineObject::has_recording()
{
return camera_recording;
}
int MachineObject::command_get_version()
{
json j;
@ -974,10 +1046,10 @@ int MachineObject::command_request_push_all()
auto curr_time = std::chrono::system_clock::now();
auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(curr_time - last_request_push);
if (diff.count() < REQUEST_PUSH_MIN_TIME) {
BOOST_LOG_TRIVIAL(trace) << "command_request_push_all: send request too fast";
BOOST_LOG_TRIVIAL(trace) << "static: command_request_push_all: send request too fast, dev_id=" << dev_id;
return -1;
} else {
BOOST_LOG_TRIVIAL(trace) << "command_request_push_all";
BOOST_LOG_TRIVIAL(trace) << "static: command_request_push_all, dev_id=" << dev_id;
last_request_push = std::chrono::system_clock::now();
}
json j;
@ -1365,6 +1437,11 @@ bool MachineObject::is_in_printing()
return false;
}
bool MachineObject::is_in_prepare()
{
return print_status == "PREPARE";
}
bool MachineObject::is_printing_finished()
{
if (print_status.compare("FINISH") == 0
@ -1388,8 +1465,10 @@ void MachineObject::reset()
camera_recording = false;
camera_timelapse = false;
printing_speed_mag = 100;
gcode_file_prepare_percent = 0;
iot_print_status = "";
print_status = "";
last_mc_print_stage = -1;
subtask_ = nullptr;
@ -1444,6 +1523,11 @@ bool MachineObject::is_connected()
return true;
}
bool MachineObject::is_connecting()
{
return is_connected() && m_push_count == 0;
}
void MachineObject::set_online_state(bool on_off)
{
m_is_online = on_off;
@ -1508,9 +1592,10 @@ int MachineObject::parse_json(std::string payload)
if (j_pre.contains("print")) {
if (j_pre["print"].contains("command")) {
if (j_pre["print"]["command"].get<std::string>() == "push_status") {
m_push_count++;
if (j_pre["print"].contains("msg")) {
if (j_pre["print"]["msg"].get<int>() == 0) { //all message
BOOST_LOG_TRIVIAL(trace) << "static: get push_all msg, dev_id=" << dev_id;
m_push_count++;
print_json.diff2all_base_reset(j_pre);
} else if (j_pre["print"]["msg"].get<int>() == 1) { //diff message
if (print_json.diff2all(j_pre, j) == 0) {
@ -1544,11 +1629,14 @@ int MachineObject::parse_json(std::string payload)
json jj = j["print"];
if (jj.contains("command")) {
if (jj["command"].get<std::string>() == "push_status") {
m_push_count++;
last_push_time = std::chrono::system_clock::now();
#pragma region printing
// U0 firmware
if (jj.contains("print_type")) {
print_type = jj["print_type"].get<std::string>();
}
if (jj.contains("mc_remaining_time")) {
if (jj["mc_remaining_time"].is_string())
mc_left_time = stoi(j["print"]["mc_remaining_time"].get<std::string>()) * 60;
@ -1603,8 +1691,15 @@ int MachineObject::parse_json(std::string payload)
if (jj.contains("gcode_file"))
this->m_gcode_file = jj["gcode_file"].get<std::string>();
if (jj.contains("project_id")
if (jj.contains("gcode_file_prepare_percent")) {
std::string percent_str = jj["gcode_file_prepare_percent"].get<std::string>();
if (!percent_str.empty()) {
try{
this->gcode_file_prepare_percent = atoi(percent_str.c_str());
} catch(...) {}
}
}
if (jj.contains("project_id")
&& jj.contains("profile_id")
&& jj.contains("subtask_id")
){
@ -1633,11 +1728,11 @@ int MachineObject::parse_json(std::string payload)
curr_task->task_progress = mc_print_percent;
curr_task->printing_status = print_status;
curr_task->task_id = jj["subtask_id"].get<std::string>();
}
}
#pragma endregion
#pragma region status
/* temperature */
if (jj.contains("bed_temper")) {
@ -1755,14 +1850,14 @@ int MachineObject::parse_json(std::string payload)
camera_has_sdcard = jj["sdcard"].get<bool>();
} else {
//do not check sdcard if no sdcard field
camera_has_sdcard = true;
camera_has_sdcard = false;
}
}
catch (...) {
;
}
#pragma endregion
#pragma region upgrade
try {
if (jj.contains("upgrade_state")) {
@ -1788,9 +1883,15 @@ int MachineObject::parse_json(std::string payload)
upgrade_force_upgrade = jj["upgrade_state"]["force_upgrade"].get<bool>();
if (jj["upgrade_state"].contains("err_code"))
upgrade_err_code = jj["upgrade_state"]["err_code"].get<int>();
if (jj["upgrade_state"].contains("dis_state"))
if (jj["upgrade_state"].contains("dis_state")) {
if (upgrade_display_state != jj["upgrade_state"]["dis_state"].get<int>()
&& jj["upgrade_state"]["dis_state"].get<int>() == 3) {
GUI::wxGetApp().CallAfter([this] {
this->command_get_version();
});
}
upgrade_display_state = jj["upgrade_state"]["dis_state"].get<int>();
else {
} else {
//BBS compatibility with old version
if (upgrade_status == "DOWNLOADING"
|| upgrade_status == "FLASHING"
@ -1847,7 +1948,7 @@ int MachineObject::parse_json(std::string payload)
catch (...) {
;
}
#pragma endregion
#pragma endregion
#pragma region hms
// parse hms msg
@ -1977,9 +2078,17 @@ int MachineObject::parse_json(std::string payload)
curr_tray = tray_iter->second;
}
if (!curr_tray) continue;
if (curr_tray->hold_count > 0) {
curr_tray->hold_count--;
continue;
}
curr_tray->id = (*tray_it)["id"].get<std::string>();
if (tray_it->contains("tag_uid"))
curr_tray->tag_uid = (*tray_it)["tag_uid"].get<std::string>();
else
curr_tray->tag_uid = "0";
if (tray_it->contains("tray_info_idx") && tray_it->contains("tray_type")) {
curr_tray->setting_id = (*tray_it)["tray_info_idx"].get<std::string>();
std::string type = (*tray_it)["tray_type"].get<std::string>();
@ -1990,32 +2099,59 @@ int MachineObject::parse_json(std::string payload)
} else {
curr_tray->type = type;
}
} else {
curr_tray->setting_id = "";
curr_tray->type = "";
}
if (tray_it->contains("tray_sub_brands"))
curr_tray->sub_brands = (*tray_it)["tray_sub_brands"].get<std::string>();
else
curr_tray->sub_brands = "";
if (tray_it->contains("tray_weight"))
curr_tray->weight = (*tray_it)["tray_weight"].get<std::string>();
else
curr_tray->weight = "";
if (tray_it->contains("tray_diameter"))
curr_tray->diameter = (*tray_it)["tray_diameter"].get<std::string>();
else
curr_tray->diameter = "";
if (tray_it->contains("tray_temp"))
curr_tray->temp = (*tray_it)["tray_temp"].get<std::string>();
else
curr_tray->temp = "";
if (tray_it->contains("tray_time"))
curr_tray->time = (*tray_it)["tray_time"].get<std::string>();
else
curr_tray->time = "";
if (tray_it->contains("bed_temp_type"))
curr_tray->bed_temp_type = (*tray_it)["bed_temp_type"].get<std::string>();
else
curr_tray->bed_temp_type = "";
if (tray_it->contains("bed_temp"))
curr_tray->bed_temp = (*tray_it)["bed_temp"].get<std::string>();
else
curr_tray->bed_temp = "";
if (tray_it->contains("nozzle_temp_max"))
curr_tray->nozzle_temp_max = (*tray_it)["nozzle_temp_max"].get<std::string>();
else
curr_tray->nozzle_temp_max = "";
if (tray_it->contains("nozzle_temp_min"))
curr_tray->nozzle_temp_min = (*tray_it)["nozzle_temp_min"].get<std::string>();
else
curr_tray->nozzle_temp_min = "";
if (tray_it->contains("xcam_info"))
curr_tray->xcam_info = (*tray_it)["xcam_info"].get<std::string>();
else
curr_tray->xcam_info = "";
if (tray_it->contains("tray_uuid"))
curr_tray->uuid = (*tray_it)["tray_uuid"].get<std::string>();
else
curr_tray->uuid = "0";
if (tray_it->contains("tray_color")) {
auto color = (*tray_it)["tray_color"].get<std::string>();
curr_tray->update_color_from_str(color);
} else {
curr_tray->color = "";
}
try {
if (!ams_id.empty() && !curr_tray->id.empty()) {
@ -2051,12 +2187,20 @@ int MachineObject::parse_json(std::string payload)
}
#pragma endregion
} else if (jj["command"].get<std::string>() == "gcode_line") {
//ack of gcode_line
BOOST_LOG_TRIVIAL(debug) << "parse_json, ack of gcode_line = " << j.dump(4);
} else if (jj["command"].get<std::string>() == "project_file") {
//ack of project file
BOOST_LOG_TRIVIAL(debug) << "parse_json, ack of project_file = " << j.dump(4);
std::string result;
if (jj.contains("result")) {
result = jj["result"].get<std::string>();
if (result == "FAIL") {
wxString text = _L("Failed to start printing job");
GUI::wxGetApp().show_dialog(text);
}
}
} else if (jj["command"].get<std::string>() == "ams_filament_setting") {
if (jj["ams_id"].is_number()) {
int ams_id = jj["ams_id"].get<int>();
@ -2071,6 +2215,8 @@ int MachineObject::parse_json(std::string payload)
tray_it->second->type = jj["tray_type"].get<std::string>();
tray_it->second->color = jj["tray_color"].get<std::string>();
tray_it->second->setting_id = jj["tray_info_idx"].get<std::string>();
// delay update
tray_it->second->set_hold_count();
} else {
BOOST_LOG_TRIVIAL(warning) << "ams_filament_setting, can not find in trayList, tray_id=" << tray_id;
}
@ -2133,6 +2279,8 @@ int MachineObject::parse_json(std::string payload)
}
}
catch (...) {}
parse_state_changed_event();
}
catch (...) {
BOOST_LOG_TRIVIAL(trace) << "parse_json failed! dev_id=" << this->dev_id <<", payload = " << payload;
@ -2339,6 +2487,10 @@ DeviceManager::~DeviceManager()
userMachineList.clear();
}
void DeviceManager::set_agent(NetworkAgent* agent)
{
m_agent = agent;
}
void DeviceManager::on_machine_alive(std::string json_str)
{
@ -2376,7 +2528,12 @@ void DeviceManager::on_machine_alive(std::string json_str)
obj->wifi_signal = printer_signal;
obj->dev_connection_type = connect_type;
obj->bind_state = bind_state;
BOOST_LOG_TRIVIAL(info) << "SsdpDiscovery:: Update Machine Info, printer_sn = " << dev_id << ", signal = " << printer_signal;
// U0 firmware
if (obj->dev_connection_type.empty() && obj->bind_state.empty())
obj->bind_state = "free";
BOOST_LOG_TRIVIAL(debug) << "SsdpDiscovery:: Update Machine Info, printer_sn = " << dev_id << ", signal = " << printer_signal;
obj->last_alive = Slic3r::Utils::get_current_time_utc();
obj->m_is_online = true;
}
@ -2396,7 +2553,7 @@ void DeviceManager::on_machine_alive(std::string json_str)
localMachineList.insert(std::make_pair(dev_id, obj));
BOOST_LOG_TRIVIAL(info) << "SsdpDiscovery::New Machine, ip = " << dev_ip << ", printer_name= " << dev_name << ", printer_type = " << printer_type_str << ", signal = " << printer_signal;
BOOST_LOG_TRIVIAL(debug) << "SsdpDiscovery::New Machine, ip = " << dev_ip << ", printer_name= " << dev_name << ", printer_type = " << printer_type_str << ", signal = " << printer_signal;
}
}
catch (...) {
@ -2480,6 +2637,11 @@ MachineObject* DeviceManager::get_local_machine(std::string dev_id)
return it->second;
}
void DeviceManager::erase_user_machine(std::string dev_id)
{
userMachineList.erase(dev_id);
}
MachineObject* DeviceManager::get_user_machine(std::string dev_id)
{
if (!Slic3r::GUI::wxGetApp().is_user_login())
@ -2522,7 +2684,7 @@ void DeviceManager::clean_user_info()
bool DeviceManager::set_selected_machine(std::string dev_id)
{
BOOST_LOG_TRIVIAL(trace) << "set_selected_machine=" << dev_id;
BOOST_LOG_TRIVIAL(info) << "set_selected_machine=" << dev_id;
auto my_machine_list = get_my_machine_list();
auto it = my_machine_list.find(dev_id);
if (it != my_machine_list.end()) {
@ -2534,7 +2696,7 @@ bool DeviceManager::set_selected_machine(std::string dev_id)
if (m_agent) {
if (it->second->connection_type() != "lan" || it->second->connection_type().empty()) {
if (m_agent->get_user_selected_machine() != dev_id) {
BOOST_LOG_TRIVIAL(trace) << "set_selected_machine: same dev_id = " << dev_id;
BOOST_LOG_TRIVIAL(info) << "static: set_selected_machine: same dev_id = " << dev_id;
m_agent->set_user_selected_machine(dev_id);
it->second->reset();
} else {
@ -2680,7 +2842,7 @@ void DeviceManager::update_user_machine_list_info()
{
if (!m_agent) return;
BOOST_LOG_TRIVIAL(trace) << "update_user_machine_list_info";
BOOST_LOG_TRIVIAL(debug) << "update_user_machine_list_info";
unsigned int http_code;
std::string body;
int result = m_agent->get_user_print_info(&http_code, &body);

View file

@ -13,9 +13,9 @@
#define USE_LOCAL_SOCKET_BIND 0
#define DISCONNECT_TIMEOUT 10000.f // milliseconds
#define DISCONNECT_TIMEOUT 30000.f // milliseconds
#define PUSHINFO_TIMEOUT 15000.f // milliseconds
#define REQUEST_PUSH_MIN_TIME 3000.f // milliseconds
#define REQUEST_PUSH_MIN_TIME 15000.f // milliseconds
#define FILAMENT_MAX_TEMP 300
#define FILAMENT_DEF_TEMP 220
@ -153,11 +153,13 @@ public:
wxColour wx_color;
bool is_bbl;
bool is_exists = false;
int hold_count = 0;
AmsRoadPosition road_position;
AmsStep step_state;
AmsRfidState rfid_state;
void set_hold_count() { hold_count = 3; }
void update_color_from_str(std::string color);
wxColour get_color();
@ -244,7 +246,13 @@ public:
#define UpgradeFlashFailed -3
#define UpgradePrinting -4
// calc distance map
struct DisValue {
int tray_id;
float distance;
bool is_same_color = true;
bool is_type_match = true;
};
class MachineObject
{
@ -347,6 +355,7 @@ public:
// parse amsStatusMain and ams_status_sub
void _parse_ams_status(int ams_status);
bool has_ams() { return ams_exist_bits != 0; }
bool is_U0_firmware();
bool is_support_ams_mapping();
bool is_only_support_cloud_print();
static bool is_support_ams_mapping_version(std::string module, std::string version);
@ -415,16 +424,22 @@ public:
int mc_print_line_number;
int mc_print_percent; /* left print progess in percent */
int mc_left_time; /* left time in seconds */
int last_mc_print_stage;
bool is_system_printing();
std::vector<int> stage_list_info;
int stage_curr = 0;
int m_push_count = 0;
bool calibration_done { false };
wxString get_curr_stage();
// return curr stage index of stage list
int get_curr_stage_idx();
bool is_in_calibration();
bool is_calibration_running();
bool is_calibration_done();
void parse_state_changed_event();
/* printing status */
std::string print_status; /* enum string: FINISH, RUNNING, PAUSE, INIT, FAILED */
@ -455,11 +470,14 @@ public:
BBLSliceInfo* slice_info {nullptr};
int plate_index { -1 };
std::string m_gcode_file;
int gcode_file_prepare_percent = 0;
BBLSubTask* subtask_;
std::string obj_subtask_id; // subtask_id == 0 for sdcard
std::string subtask_name;
bool is_sdcard_printing();
bool has_sdcard();
bool has_timelapse();
bool has_recording();
MachineObject(NetworkAgent* agent, std::string name, std::string id, std::string ip);
@ -517,6 +535,7 @@ public:
bool can_pause();
bool can_abort();
bool is_in_printing();
bool is_in_prepare();
bool is_printing_finished();
void reset_update_time();
void reset();
@ -525,6 +544,7 @@ public:
void set_print_state(std::string status);
bool is_connected();
bool is_connecting();
void set_online_state(bool on_off);
bool is_online() { return m_is_online; }
bool is_info_ready();
@ -554,6 +574,7 @@ private:
public:
DeviceManager(NetworkAgent* agent = nullptr);
~DeviceManager();
void set_agent(NetworkAgent* agent);
std::mutex listMutex;
std::string selected_machine; /* dev_id */
@ -566,6 +587,7 @@ public:
MachineObject* get_local_machine(std::string dev_id);
MachineObject* get_user_machine(std::string dev_id);
MachineObject* get_my_machine(std::string dev_id);
void erase_user_machine(std::string dev_id);
void clean_user_info();
bool set_selected_machine(std::string dev_id);
@ -588,8 +610,6 @@ public:
// get alive machine
std::map<std::string, MachineObject*> get_local_machine_list();
void load_last_machine();
void check_alive();
};
} // namespace Slic3r

View file

@ -0,0 +1,100 @@
#include "DownloadProgressDialog.hpp"
#include <wx/settings.h>
#include <wx/sizer.h>
#include <wx/stattext.h>
#include <wx/button.h>
#include <wx/statbmp.h>
#include <wx/scrolwin.h>
#include <wx/clipbrd.h>
#include <wx/checkbox.h>
#include <wx/html/htmlwin.h>
#include <boost/algorithm/string/replace.hpp>
#include "libslic3r/libslic3r.h"
#include "libslic3r/Utils.hpp"
#include "GUI.hpp"
#include "I18N.hpp"
//#include "ConfigWizard.hpp"
#include "wxExtensions.hpp"
#include "slic3r/GUI/MainFrame.hpp"
#include "GUI_App.hpp"
#define DESIGN_INPUT_SIZE wxSize(FromDIP(100), -1)
namespace Slic3r {
namespace GUI {
DownloadProgressDialog::DownloadProgressDialog(wxString title)
: DPIDialog(static_cast<wxWindow *>(wxGetApp().mainframe), wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX)
{
std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str();
SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO));
SetBackgroundColour(*wxWHITE);
wxBoxSizer *m_sizer_main = new wxBoxSizer(wxVERTICAL);
auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1));
m_line_top->SetBackgroundColour(wxColour(166, 169, 170));
m_sizer_main->Add(m_line_top, 0, wxEXPAND, 0);
m_status_bar = std::make_shared<BBLStatusBarSend>(this);
m_panel_download = m_status_bar->get_panel();
m_panel_download->SetSize(wxSize(FromDIP(340), -1));
m_panel_download->SetMinSize(wxSize(FromDIP(340), -1));
m_panel_download->SetMaxSize(wxSize(FromDIP(340), -1));
m_sizer_main->Add(m_panel_download, 0, wxALIGN_CENTER_VERTICAL|wxALL, FromDIP(20));
m_sizer_main->Add(0, 0, 1, wxBOTTOM, 10);
SetSizer(m_sizer_main);
Layout();
Fit();
CentreOnParent();
}
bool DownloadProgressDialog::Show(bool show)
{
if (show) {
m_upgrade_job = std::make_shared<UpgradeNetworkJob>(m_status_bar);
m_upgrade_job->set_event_handle(this);
m_status_bar->set_progress(0);
Bind(EVT_UPGRADE_NETWORK_SUCCESS, [this](wxCommandEvent& evt) {
m_status_bar->change_button_label(_L("Finish"));
wxGetApp().restart_networking();
m_status_bar->set_cancel_callback_fina(
[this]() {
this->Close();
}
);
});
Bind(EVT_UPGRADE_NETWORK_FAILED, [this](wxCommandEvent& evt) {
m_status_bar->change_button_label(_L("Close"));
m_status_bar->set_progress(0);
m_status_bar->set_cancel_callback_fina(
[this]() {
this->Close();
}
);
});
m_status_bar->set_cancel_callback_fina([this]() {
if (m_upgrade_job) {
m_upgrade_job->cancel();
//EndModal(wxID_CLOSE);
}
});
m_upgrade_job->start();
}
return DPIDialog::Show(show);
}
DownloadProgressDialog::~DownloadProgressDialog() {}
void DownloadProgressDialog::on_dpi_changed(const wxRect &suggested_rect) {}
void DownloadProgressDialog::update_release_note(std::string release_note, std::string version) {}
}} // namespace Slic3r::GUI

View file

@ -0,0 +1,55 @@
#ifndef slic3r_DownloadProgressDialog_hpp_
#define slic3r_DownloadProgressDialog_hpp_
#include <string>
#include <unordered_map>
#include "GUI_Utils.hpp"
#include <wx/dialog.h>
#include <wx/font.h>
#include <wx/bitmap.h>
#include <wx/msgdlg.h>
#include <wx/richmsgdlg.h>
#include <wx/textctrl.h>
#include <wx/statline.h>
#include "Widgets/Button.hpp"
#include "BBLStatusBar.hpp"
#include "BBLStatusBarSend.hpp"
#include "Jobs/UpgradeNetworkJob.hpp"
class wxBoxSizer;
class wxCheckBox;
class wxStaticBitmap;
#define MSG_DIALOG_BUTTON_SIZE wxSize(FromDIP(58), FromDIP(24))
#define MSG_DIALOG_MIDDLE_BUTTON_SIZE wxSize(FromDIP(76), FromDIP(24))
#define MSG_DIALOG_LONG_BUTTON_SIZE wxSize(FromDIP(90), FromDIP(24))
namespace Slic3r {
namespace GUI {
class DownloadProgressDialog : public DPIDialog
{
protected:
bool Show(bool show) override;
public:
DownloadProgressDialog(wxString title);
~DownloadProgressDialog();
void on_dpi_changed(const wxRect &suggested_rect) override;
void update_release_note(std::string release_note, std::string version);
std::shared_ptr<BBLStatusBarSend> m_status_bar;
std::shared_ptr<UpgradeNetworkJob> m_upgrade_job;
wxPanel * m_panel_download;
};
}
}
#endif

View file

@ -4988,7 +4988,8 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
::sprintf(buf, imperial_units ? "%.2f in" : "%.2f m", ps.total_used_filament / /*1000*/koef);
imgui.text(buf);
ImGui::SameLine();
::sprintf(buf, " %.2f g", ps.total_weight);
double unit_conver = imperial_units ? GizmoObjectManipulation::oz_to_g : 1;
::sprintf(buf, imperial_units ?" %.2f oz":" %.2f g", ps.total_weight / unit_conver);
imgui.text(buf);
auto role_time = [time_mode](ExtrusionRole role) {

View file

@ -1349,7 +1349,12 @@ void GLCanvas3D::render(bool only_init)
right_margin = SLIDER_RIGHT_MARGIN;
bottom_margin = SLIDER_BOTTOM_MARGIN;
}
wxGetApp().plater()->get_notification_manager()->render_notifications(*this, get_overlay_window_width(), bottom_margin, right_margin);
#if ENABLE_RETINA_GL
float sc = m_retina_helper->get_scale_factor();
wxGetApp().plater()->get_notification_manager()->render_notifications(*this, get_overlay_window_width(), bottom_margin * sc, right_margin);
#else
wxGetApp().plater()->get_notification_manager()->render_notifications(*this, get_overlay_window_width(), bottom_margin, right_margin);
#endif
}
wxGetApp().imgui()->render();
@ -3038,6 +3043,14 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
// Grab keyboard focus for input in gizmo dialogs.
m_canvas->SetFocus();
if (evt.LeftDown()) {
// Clear hover state in main toolbar
wxMouseEvent evt2 = evt;
evt2.SetEventType(wxEVT_MOTION);
evt2.SetLeftDown(false);
m_main_toolbar.on_mouse(evt2, *this);
}
if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp())
mouse_up_cleanup();
@ -6397,34 +6410,25 @@ void GLCanvas3D::_render_paint_toolbar() const
}
}
#ifdef __APPLE__
std::string item_text = (boost::format("%1% %2%") % (11) % filament_types[0]).str();
const ImVec2 label_size = ImGui::CalcTextSize(item_text.c_str(), NULL, true);
int button_size = label_size.x + item_spacing;
#else
int button_size = GLToolbar::Default_Icons_Size * wxGetApp().toolbar_icon_scale() + item_spacing;
#endif
float button_size = GLToolbar::Default_Icons_Size * f_scale * wxGetApp().toolbar_icon_scale() + item_spacing;
imgui.set_next_window_pos(0.5f * (canvas_w + (button_size + item_spacing) * extruder_num), button_size + item_spacing * 2, ImGuiCond_Always, 1.0f, 1.0f);
imgui.begin(_L("Paint Toolbar"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar);
bool disabled = !wxGetApp().plater()->can_fillcolor();
unsigned char rgb[3];
float max_text = 0;
for (int i = 0; i < extruder_num; i++) {
if (i > 0) {
if (filament_types.size() <= i) continue;
std::string item_text = (boost::format("%1% %2%") % (i + 1) % filament_types[i]).str();
const ImVec2 label_size = ImGui::CalcTextSize(item_text.c_str(), NULL, true);
#ifdef __WINDOWS__
if (i > 8)
ImGui::SameLine(0.5 * item_spacing + (button_size - label_size.x) / 2 + (button_size + item_spacing) * i);
else
ImGui::SameLine((button_size - label_size.x) / 2 + (button_size + item_spacing) * i);
#else
ImGui::SameLine();
#endif
}
//ImGui::SameLine();
std::string item_text = (boost::format("%1%%2%") % (i + 1) % filament_types[i]).str();
ImVec2 label_size = ImGui::CalcTextSize(item_text.c_str(), NULL, true);
if (label_size.x > button_size)
label_size.x = button_size * 0.6;
max_text = std::max(max_text,label_size.x);
}
for (int i = 0; i < extruder_num; i++) {
if (filament_types.size() <= i) continue;
ImGui::SameLine(item_spacing / 2 + (button_size - max_text) / 2 + (button_size + item_spacing) * i);
ImGui::PushID(i);
Slic3r::GUI::BitmapCache::parse_color(colors[i], rgb);
ImGui::PushStyleColor(ImGuiCol_Button, ImColor(rgb[0], rgb[1], rgb[2]).Value);
@ -6450,21 +6454,78 @@ void GLCanvas3D::_render_paint_toolbar() const
ImGui::PopItemFlag();
ImGui::PopID();
}
for (int i = 0; i < extruder_num; i++){
if (filament_types.size() <= i) continue;
//TODO use filament type from filament management, current use PLA by default
std::string item_text = (boost::format("%1% %2%") % (i + 1) % filament_types[i]).str();
std::string item_text = (boost::format("%1%%2%") % (i + 1) % filament_types[i]).str();
const ImVec2 label_size = ImGui::CalcTextSize(item_text.c_str(), NULL, true);
ImGui::SameLine(item_spacing + (button_size - label_size.x) / 2 + (button_size + item_spacing) * i);
int len = strlen(filament_types[i].c_str());
ImGui::SameLine(item_spacing / 2 + (button_size - max_text) / 2 + (button_size + item_spacing) * i);
int count = 0;
if (label_size.x > button_size)
{
for (int j = 0; j < filament_types[i].size(); j++)
{
if(std::isalpha(filament_types[i][j]))
count++;
else
break;
}
}
if (i > 8)
{
if (label_size.x > button_size)
{
if(count * ImGui::GetFontSize() > button_size){
if ((len - (count + 1)) <= 3)
item_text = "\t" + std::to_string(i + 1) + "\n" + filament_types[i].substr(0, count) + "\n" + "\t" + filament_types[i].substr(count, len);
else
item_text = "\t" + std::to_string(i + 1) + "\n" + filament_types[i].substr(0, count + 1) + "\n"+ filament_types[i].substr(count + 1, len);
} else {
if (count <= 4)
item_text = "\t" + std::to_string(i + 1) + "\n" + " " + filament_types[i].substr(0, count + 1) + "\n" + filament_types[i].substr(count + 1, len);
else
item_text = "\t" + std::to_string(i + 1) + "\n" + filament_types[i].substr(0, count + 1) + "\n" + filament_types[i].substr(count + 1, len);
}
}
else
{
item_text = (boost::format("\t%1%\n %2%") % (i + 1) % filament_types[i]).str();
}
}
else
{
if (label_size.x > button_size)
{
if(count * ImGui::GetFontSize() > button_size){
if ((len - (count + 1)) <= 3)
item_text = "\t " + std::to_string(i + 1) + "\n" + filament_types[i].substr(0, count) + "\n" + "\t" + filament_types[i].substr(count, len);
else
item_text = "\t " + std::to_string(i + 1) + "\n" + filament_types[i].substr(0, count + 1) + "\n"+ filament_types[i].substr(count + 1, len);
} else {
if (count <= 4)
item_text = "\t " + std::to_string(i + 1) + "\n" + " " + filament_types[i].substr(0, count + 1) + "\n" + filament_types[i].substr(count + 1, len);
else
item_text = "\t " + std::to_string(i + 1) + "\n" + filament_types[i].substr(0, count + 1) + "\n" + filament_types[i].substr(count + 1, len);
}
}
else
{
item_text = (boost::format("\t %1%\n\t%2%") % (i + 1) % filament_types[i]).str();
}
}
Slic3r::GUI::BitmapCache::parse_color(colors[i], rgb);
float gray = 0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2];
if (gray < 80)
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, 1.0f), item_text.c_str());
else
ImGui::TextColored(ImVec4(0.0f, 0.0f, 0.0f, 1.0f), item_text.c_str());
if (gray < 80){
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, 1.0f), item_text.c_str());
} else{
ImGui::TextColored(ImVec4(0.0f, 0.0f, 0.0f, 1.0f), item_text.c_str());
}
}
ImGui::AlignTextToFramePadding();
imgui.end();
@ -7468,8 +7529,8 @@ void GLCanvas3D::_set_warning_notification(EWarning warning, bool state)
case EWarning::SlaSupportsOutside: text = ("SLA supports outside the print area were detected."); error = ErrorType::PLATER_ERROR; break;
case EWarning::SomethingNotShown: text = _u8L("Only the object being edit is visible."); break;
case EWarning::ObjectClashed:
text = _u8L("An object is layed over the boundary of plate.\n"
"Please solve the problem by moving it totally inside or outside plate.");
text = _u8L("An object is laid over the boundary of plate or exceeds the height limit.\n"
"Please solve the problem by moving it totally on or off the plate, and confirming that the height is within the build volume.");
error = ErrorType::PLATER_ERROR;
break;
}

View file

@ -299,10 +299,12 @@ bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::stri
::memcpy((void*)pressed_data.data(), (const void*)sprite_data.data(), sprite_bytes);
for (int i = 0; i < sprite_n_pixels; ++i) {
int offset = i * 4;
if (pressed_data.data()[offset] == 0) {
::memset((void*)&pressed_data.data()[offset], 172, 3);
pressed_data.data()[offset + 3] = (unsigned char)150;
}
if (pressed_data.data()[offset + 0] == 0 &&
pressed_data.data()[offset + 1] == 0 &&
pressed_data.data()[offset + 2] == 0) {
::memset((void*)&pressed_data.data()[offset], 238, 3);
pressed_data.data()[offset + 3] = (unsigned char) 225;
}
}
::memcpy((void*)disable_data.data(), (const void*)sprite_data.data(), sprite_bytes);
@ -315,25 +317,36 @@ bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::stri
::memcpy((void*)hover_data.data(), (const void*)sprite_data.data(), sprite_bytes);
for (int i = 0; i < sprite_n_pixels; ++i) {
int offset = i * 4;
if (hover_data.data()[offset] == 0) {
::memset((void*)&hover_data.data()[offset], 172, 3);
hover_data.data()[offset + 3] = (unsigned char)75;
if (hover_data.data()[offset + 0] == 0 &&
hover_data.data()[offset + 1] == 0 &&
hover_data.data()[offset + 2] == 0)
{
::memset((void *) &hover_data.data()[offset], 238, 3);
hover_data.data()[offset + 3] = (unsigned char) 75;
}
}
::memcpy((void*)sprite_white_only_data.data(), (const void*)sprite_data.data(), sprite_bytes);
for (int i = 0; i < sprite_n_pixels; ++i) {
int offset = i * 4;
if (sprite_white_only_data.data()[offset + 0] != 0 ||
sprite_white_only_data.data()[offset + 1] != 0 ||
sprite_white_only_data.data()[offset + 2] != 0){
sprite_white_only_data.data()[offset + 0] = (unsigned char) 43;
sprite_white_only_data.data()[offset + 1] = (unsigned char) 52;
sprite_white_only_data.data()[offset + 2] = (unsigned char) 54;
}
}
::memcpy((void*)sprite_gray_only_data.data(), (const void*)sprite_data.data(), sprite_bytes);
for (int i = 0; i < sprite_n_pixels; ++i) {
int offset = i * 4;
if (sprite_gray_only_data.data()[offset + 0] == 0) {
if (sprite_gray_only_data.data()[offset + 0] != 0 ||
sprite_gray_only_data.data()[offset + 1] != 0 ||
sprite_gray_only_data.data()[offset + 2] != 0 ) {
::memset((void*)&sprite_gray_only_data.data()[offset], 200, 3);
}
else {
sprite_gray_only_data.data()[offset + 0] = (unsigned char)(sprite_data.data()[offset + 0] * 0.3 + 178);
sprite_gray_only_data.data()[offset + 1] = (unsigned char)(sprite_data.data()[offset + 1] * 0.3 + 178);
sprite_gray_only_data.data()[offset + 2] = (unsigned char)(sprite_data.data()[offset + 2] * 0.3 + 178);
}
}
@ -394,9 +407,9 @@ bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::stri
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
else
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));

View file

@ -538,4 +538,52 @@ void desktop_open_datadir_folder()
#endif
}
void desktop_open_any_folder( const std::string path )
{
// Execute command to open a file explorer, platform dependent.
// FIXME: The const_casts aren't needed in wxWidgets 3.1, remove them when we upgrade.
#ifdef _WIN32
const wxString widepath = from_u8(path);
const wchar_t *argv[] = {L"explorer", widepath.GetData(), nullptr};
::wxExecute(const_cast<wchar_t **>(argv), wxEXEC_ASYNC, nullptr);
#elif __APPLE__
const char *argv[] = {"open", path.data(), nullptr};
::wxExecute(const_cast<char **>(argv), wxEXEC_ASYNC, nullptr);
#else
const char *argv[] = {"xdg-open", path.data(), nullptr};
// Check if we're running in an AppImage container, if so, we need to remove AppImage's env vars,
// because they may mess up the environment expected by the file manager.
// Mostly this is about LD_LIBRARY_PATH, but we remove a few more too for good measure.
if (wxGetEnv("APPIMAGE", nullptr)) {
// We're running from AppImage
wxEnvVariableHashMap env_vars;
wxGetEnvMap(&env_vars);
env_vars.erase("APPIMAGE");
env_vars.erase("APPDIR");
env_vars.erase("LD_LIBRARY_PATH");
env_vars.erase("LD_PRELOAD");
env_vars.erase("UNION_PRELOAD");
wxExecuteEnv exec_env;
exec_env.env = std::move(env_vars);
wxString owd;
if (wxGetEnv("OWD", &owd)) {
// This is the original work directory from which the AppImage image was run,
// set it as CWD for the child process:
exec_env.cwd = std::move(owd);
}
::wxExecute(const_cast<char **>(argv), wxEXEC_ASYNC, nullptr, &exec_env);
} else {
// Looks like we're NOT running from AppImage, we'll make no changes to the environment.
::wxExecute(const_cast<char **>(argv), wxEXEC_ASYNC, nullptr, nullptr);
}
#endif
}
} }

View file

@ -82,7 +82,8 @@ extern void about();
extern void login();
// Ask the destop to open the datadir using the default file explorer.
extern void desktop_open_datadir_folder();
// Ask the destop to open one folder
extern void desktop_open_any_folder(const std::string path);
} // namespace GUI
} // namespace Slic3r

File diff suppressed because it is too large Load diff

View file

@ -11,6 +11,7 @@
#include "slic3r/GUI/DeviceManager.hpp"
#include "slic3r/Utils/NetworkAgent.hpp"
#include "slic3r/GUI/WebViewDialog.hpp"
#include "slic3r/GUI/Jobs/UpgradeNetworkJob.hpp"
#include <wx/app.h>
#include <wx/colour.h>
@ -22,7 +23,8 @@
#include <mutex>
#include <stack>
#define BBL_HAS_FIRST_PAGE 1
#define BBL_HAS_FIRST_PAGE 1
#define STUDIO_INACTIVE_TIMEOUT 15*60*1000
class wxMenuItem;
class wxMenuBar;
@ -104,6 +106,7 @@ enum CameraMenuIDs {
wxID_CAMERA_COUNT,
};
class Tab;
class ConfigWizard;
@ -186,6 +189,7 @@ public:
class GUI_App : public wxApp
{
public:
//BBS: remove GCodeViewer as seperate APP logic
enum class EAppMode : unsigned char
{
@ -241,9 +245,13 @@ private:
//BBS
bool m_is_closing {false};
Slic3r::DeviceManager* m_device_manager;
Slic3r::DeviceManager* m_device_manager { nullptr };
NetworkAgent* m_agent { nullptr };
std::vector<std::string> need_delete_presets; // store setting ids of preset
bool m_networking_compatible { false };
bool m_networking_need_update { false };
bool m_networking_cancel_update { false };
std::shared_ptr<UpgradeNetworkJob> m_upgrade_network_job;
VersionInfo version_info;
@ -335,7 +343,7 @@ public:
void load_gcode(wxWindow* parent, wxString& input_file) const;
void ShowUserGuide();
void ShowDailyTip();
void ShowDownNetPluginDlg();
void ShowUserLogin();
void ShowOnlyFilament();
//BBS
@ -358,11 +366,18 @@ public:
void on_http_error(wxCommandEvent &evt);
void on_user_login(wxCommandEvent &evt);
// BBS
bool is_studio_active();
void reset_to_active();
bool m_studio_active = true;
std::chrono::system_clock::time_point last_active_point;
void check_update(bool show_tips);
void check_new_version(bool show_tips = false);
void request_new_version();
void enter_force_upgrade();
void no_new_version();
void show_dialog(wxString msg);
void reload_settings();
void remove_user_presets();
void sync_preset(Preset* preset);
@ -484,12 +499,23 @@ public:
void associate_files(std::wstring extend);
void disassociate_files(std::wstring extend);
#endif // __WXMSW__
std::string get_plugin_url(std::string country_code);
int download_plugin(InstallProgressFn pro_fn = nullptr, WasCancelledFn cancel_fn = nullptr);
int install_plugin(InstallProgressFn pro_fn = nullptr, WasCancelledFn cancel_fn = nullptr);
std::string get_http_url(std::string country_code);
bool is_compatibility_version();
bool check_networking_version();
void cancel_networking_install();
void restart_networking();
private:
int updating_bambu_networking();
bool on_init_inner();
bool on_init_network();
void init_networking_callbacks();
void init_app_config();
//BBS set extra header for http request
std::map<std::string, std::string> get_extra_header();
void init_http_extra_header();
bool check_older_app_config(Semver current_version, bool backup);
void copy_older_config();

View file

@ -464,7 +464,8 @@ wxMenu* MenuFactory::append_submenu_add_generic(wxMenu* menu, ModelVolumeType ty
auto item = L("Timelapse Wipe Tower");
type = ModelVolumeType::TIMELAPSE_WIPE_TOWER;
append_menu_item(sub_menu, wxID_ANY, _(item), "",
[type, item](wxCommandEvent&) { obj_list()->load_generic_subobject(item, type); }, "", menu);
[type, item](wxCommandEvent &) { obj_list()->load_generic_subobject(item, type); }, "", menu,
[]() { return plater()->can_add_timelapse_wt(); }, m_parent);
}
return sub_menu;

View file

@ -264,6 +264,8 @@ ObjectList::ObjectList(wxWindow* parent) :
// which seems to be working as of now.
this->CallAfter([this](){ ensure_current_item_visible(); });
#else
update_name_column_width();
ensure_current_item_visible();
#endif
e.Skip();
@ -768,17 +770,21 @@ void ObjectList::update_filament_colors()
void ObjectList::update_name_column_width() const
{
auto em = em_unit(const_cast<ObjectList*>(this));
int extra_width = 0;
wxSize client_size = this->GetClientSize();
bool p_vbar = this->GetParent()->HasScrollbar(wxVERTICAL);
bool p_hbar = this->GetParent()->HasScrollbar(wxHORIZONTAL);
auto em = em_unit(const_cast<ObjectList*>(this));
// BBS: walkaround for wxDataViewCtrl::HasScrollbar() does not return correct status
int others_width = 0;
for (int cn = colName; cn < colCount; cn++) {
if (cn != colName) {
if (GetColumn(cn)->IsHidden())
extra_width += m_columns_width[cn];
if (!GetColumn(cn)->IsHidden())
others_width += m_columns_width[cn];
}
}
GetColumn(colName)->SetWidth((m_columns_width[colName] + extra_width) * em);
GetColumn(colName)->SetWidth(client_size.x - (others_width)*em);
}
void ObjectList::set_filament_column_hidden(const bool hide) const
@ -1145,6 +1151,8 @@ void ObjectList::list_manipulation(const wxPoint& mouse_pos, bool evt_context_me
GLGizmosManager& gizmos_mgr = wxGetApp().plater()->get_view3D_canvas3D()->get_gizmos_manager();
if (gizmos_mgr.get_current_type() != GLGizmosManager::EType::FdmSupports)
gizmos_mgr.open_gizmo(GLGizmosManager::EType::FdmSupports);
else
gizmos_mgr.reset_all_states();
}
}
else if (col_num == colColorPaint) {
@ -1153,6 +1161,8 @@ void ObjectList::list_manipulation(const wxPoint& mouse_pos, bool evt_context_me
GLGizmosManager& gizmos_mgr = wxGetApp().plater()->get_view3D_canvas3D()->get_gizmos_manager();
if (gizmos_mgr.get_current_type() != GLGizmosManager::EType::MmuSegmentation)
gizmos_mgr.open_gizmo(GLGizmosManager::EType::MmuSegmentation);
else
gizmos_mgr.reset_all_states();
}
}
else if (col_num == colEditing) {
@ -2028,13 +2038,16 @@ void ObjectList::load_mesh_object(const TriangleMesh &mesh, const wxString &name
new_object->translate(-bb.center());
if (is_timelapse_wt) {
new_object->instances[0]->set_offset( Vec3d(80.0, 230.0, -new_object->origin_translation.z()) );
new_object->is_timelapse_wipe_tower = true;
auto curr_plate = wxGetApp().plater()->get_partplate_list().get_curr_plate();
int highest_extruder = 0;
double max_height = curr_plate->estimate_timelapse_wipe_tower_height(&highest_extruder);
new_object->scale(1, 1, max_height / new_object->bounding_box().size()[2]);
// move to garbage bin of curr plate
auto offset = curr_plate->get_origin() + Vec3d(80.0, 230.0, -new_object->origin_translation.z());
new_object->instances[0]->set_offset(offset);
new_object->config.set_key_value("sparse_infill_density", new ConfigOptionPercent(0));
new_object->config.set_key_value("top_shell_layers", new ConfigOptionInt(0));
new_object->config.set("extruder", highest_extruder);
@ -2237,14 +2250,15 @@ bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, con
// update extruder color in ObjectList
wxDataViewItem obj_item = m_objects_model->GetItemById(obj_idx);
// BBS
#if 0
if (obj_item) {
// BBS
if (last_volume->config.has("extruder")) {
int extruder_id = last_volume->config.opt_int("extruder");
object->config.set("extruder", extruder_id);
}
wxString extruder = object->config.has("extruder") ? wxString::Format("%d", object->config.extruder()) : _devL("1");
m_objects_model->SetExtruder(extruder, obj_item);
}
#endif
// add settings to the object, if it has them
add_settings_item(obj_item, &object->config.get());
}

View file

@ -246,7 +246,7 @@ void GLGizmoBase::GizmoImguiEnd()
m_imgui->end();
}
void GLGizmoBase::GizmoImguiSetNextWIndowPos(float x, float y, int flag, float pivot_x, float pivot_y)
void GLGizmoBase::GizmoImguiSetNextWIndowPos(float &x, float y, int flag, float pivot_x, float pivot_y)
{
if (abs(last_input_window_width) > 0.01f) {
if (x + last_input_window_width > m_parent.get_canvas_size().get_width()) {

View file

@ -206,7 +206,7 @@ protected:
bool GizmoImguiBegin(const std::string& name, int flags);
void GizmoImguiEnd();
void GizmoImguiSetNextWIndowPos(float x, float y, int flag, float pivot_x = 0.0f, float pivot_y = 0.0f);
void GizmoImguiSetNextWIndowPos(float &x, float y, int flag, float pivot_x = 0.0f, float pivot_y = 0.0f);
// Returns the picking color for the given id, based on the BASE_ID constant
// No check is made for clashing with other picking color (i.e. GLVolumes)
std::array<float, 4> picking_color_component(unsigned int id) const;

View file

@ -88,7 +88,7 @@ bool GLGizmoFdmSupports::on_init()
m_desc["remove"] = _L("Erase painting");
m_desc["remove_all"] = _L("Erase all painting");
m_desc["highlight_by_angle"] = _L("Highlight overhang areas") + ": ";
m_desc["fragment_filter"] = _L("Fragment filter");
m_desc["fragment_filter"] = _L("Gap fill");
m_desc["perform_filter"] = _L("Perform");
m_desc["fragment_area"] = _L("Fragment area");
m_desc["brush_size"] = _L("Set pen size");
@ -246,7 +246,7 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc.at("tool_type"));
std::array<wchar_t, 4> tool_icons = { ImGui::CircleButtonIcon, ImGui::SphereButtonIcon, ImGui::FillButtonIcon, ImGui::FragmentFilterIcon };
std::array<wxString, 4> tool_tips = { _L("Circle"), _L("Sphere"), _L("Fill"), _L("Fragment Filter") };
std::array<wxString, 4> tool_tips = { _L("Circle"), _L("Sphere"), _L("Fill"), _L("Gap Fill") };
for (int i = 0; i < tool_icons.size(); i++) {
std::string str_label = std::string("##");
std::wstring btn_name = tool_icons[i] + boost::nowide::widen(str_label);

View file

@ -337,12 +337,12 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
GizmoImguiBegin(get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar);
// First calculate width of all the texts that are could possibly be shown. We will decide set the dialog width based on that:
const float clipping_slider_left = m_imgui->calc_text_size(m_desc.at("clipping_of_view")).x + m_imgui->scaled(1.5f);
const float clipping_slider_left = m_imgui->calc_text_size(m_desc.at("clipping_of_view")).x + m_imgui->scaled(1.f);
const float cursor_slider_left = m_imgui->calc_text_size(m_desc.at("cursor_size")).x + m_imgui->scaled(1.f);
const float smart_fill_slider_left = m_imgui->calc_text_size(m_desc.at("smart_fill_angle")).x + m_imgui->scaled(1.5f);
const float edge_detect_slider_left = m_imgui->calc_text_size(m_desc.at("edge_detection")).x + m_imgui->scaled(1.f);
const float fragment_area_slider_left = m_imgui->calc_text_size(m_desc.at("fragment_area")).x + m_imgui->scaled(1.f);
const float height_range_slider_left = m_imgui->calc_text_size(m_desc.at("height_range")).x + m_imgui->scaled(1.f);
const float fragment_area_slider_left = m_imgui->calc_text_size(m_desc.at("fragment_area")).x + m_imgui->scaled(1.5f);
const float height_range_slider_left = m_imgui->calc_text_size(m_desc.at("height_range")).x + m_imgui->scaled(1.5f);
const float remove_btn_width = m_imgui->calc_text_size(m_desc.at("remove_all")).x + m_imgui->scaled(1.f);
const float filter_btn_width = m_imgui->calc_text_size(m_desc.at("perform_filter")).x + m_imgui->scaled(1.f);
@ -359,6 +359,8 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
total_text_max += caption_max + m_imgui->scaled(1.f);
caption_max += m_imgui->scaled(1.f);
const float circle_max_width = std::max(clipping_slider_left,cursor_slider_left);
const float height_max_width = std::max(clipping_slider_left,height_range_slider_left);
const float sliders_left_width = std::max(smart_fill_slider_left,
std::max(cursor_slider_left, std::max(edge_detect_slider_left, std::max(fragment_area_slider_left, std::max(height_range_slider_left,
clipping_slider_left)))));
@ -404,7 +406,15 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
// draw filament background
ImGuiColorEditFlags flags = ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoTooltip;
if (m_selected_extruder_idx != extruder_idx) flags |= ImGuiColorEditFlags_NoBorder;
bool color_picked = ImGui::ColorButton(color_label.c_str(), color_vec, flags, button_size);
#ifdef __APPLE__
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.4f, 0.4f, 0.4f, 1.0f));
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f);
bool color_picked = ImGui::ColorButton(color_label.c_str(), color_vec, flags, button_size);
ImGui::PopStyleVar(1);
ImGui::PopStyleColor(1);
#else
bool color_picked = ImGui::ColorButton(color_label.c_str(), color_vec, flags, button_size);
#endif
color_button_high = ImGui::GetCursorPos().y - color_button - 2.0;
if (color_picked) { m_selected_extruder_idx = extruder_idx; }
@ -425,7 +435,7 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
m_imgui->text(m_desc.at("tool_type"));
std::array<wchar_t, 6> tool_icons = { ImGui::CircleButtonIcon,ImGui::SphereButtonIcon, ImGui::TriangleButtonIcon, ImGui::HeightRangeIcon, ImGui::FillButtonIcon, ImGui::FragmentFilterIcon };
std::array<wxString, 6> tool_tips = { _L("Circle"), _L("Sphere"), _L("Triangle"), _L("Height Range"), _L("Fill"), _L("Fragment Filter") };
std::array<wxString, 6> tool_tips = { _L("Circle"), _L("Sphere"), _L("Triangle"), _L("Height Range"), _L("Fill"), _L("Gap Fill") };
for (int i = 0; i < tool_icons.size(); i++) {
std::string str_label = std::string("##");
std::wstring btn_name = tool_icons[i] + boost::nowide::widen(str_label);
@ -460,33 +470,54 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
if (m_current_tool != old_tool)
this->tool_changed(old_tool, m_current_tool);
if (m_current_tool == ImGui::CircleButtonIcon) {
m_cursor_type = TriangleSelector::CursorType::CIRCLE;
if (m_current_tool == ImGui::CircleButtonIcon || m_current_tool == ImGui::SphereButtonIcon) {
if (m_current_tool == ImGui::CircleButtonIcon)
m_cursor_type = TriangleSelector::CursorType::CIRCLE;
else
m_cursor_type = TriangleSelector::CursorType::SPHERE;
m_tool_type = ToolType::BRUSH;
ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc.at("cursor_size"));
ImGui::SameLine(sliders_left_width);
ImGui::PushItemWidth(window_width - sliders_left_width - slider_width_times * slider_icon_width);
ImGui::SameLine(circle_max_width);
ImGui::PushItemWidth(window_width - circle_max_width - slider_width_times * slider_icon_width);
m_imgui->bbl_slider_float_style("##cursor_radius", &m_cursor_radius, CursorRadiusMin, CursorRadiusMax, "%.2f", 1.0f, true);
ImGui::SameLine(window_width - slider_icon_width);
ImGui::PushItemWidth(1.5 * slider_icon_width);
ImGui::BBLDragFloat("##cursor_radius_input", &m_cursor_radius, 0.05f, 0.0f, 0.0f, "%.2f");
} else if (m_current_tool == ImGui::SphereButtonIcon){
m_cursor_type = TriangleSelector::CursorType::SPHERE;
m_tool_type = ToolType::BRUSH;
ImGui::Separator();
ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc.at("cursor_size"));
ImGui::SameLine(sliders_left_width);
ImGui::PushItemWidth(window_width - sliders_left_width - slider_width_times * slider_icon_width);
m_imgui->bbl_slider_float_style("##cursor_radius", &m_cursor_radius, CursorRadiusMin, CursorRadiusMax, "%.2f", 1.0f, true);
m_imgui->text(m_desc.at("clipping_of_view"));
auto clp_dist = float(m_c->object_clipper()->get_position());
ImGui::SameLine(circle_max_width);
ImGui::PushItemWidth(window_width - circle_max_width - slider_width_times * slider_icon_width);
bool slider_clp_dist = m_imgui->bbl_slider_float_style("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f", 1.0f, true);
ImGui::SameLine(window_width - slider_icon_width);
ImGui::PushItemWidth(1.5 * slider_icon_width);
ImGui::BBLDragFloat("##cursor_radius_input", &m_cursor_radius, 0.05f, 0.0f, 0.0f, "%.2f");
bool b_clp_dist_input = ImGui::BBLDragFloat("##clp_dist_input", &clp_dist, 0.05f, 0.0f, 0.0f, "%.2f");
if (slider_clp_dist || b_clp_dist_input) { m_c->object_clipper()->set_position(clp_dist, true); }
} else if (m_current_tool == ImGui::TriangleButtonIcon) {
m_cursor_type = TriangleSelector::CursorType::POINTER;
m_tool_type = ToolType::BRUSH;
ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc.at("clipping_of_view"));
auto clp_dist = float(m_c->object_clipper()->get_position());
ImGui::SameLine(clipping_slider_left);
ImGui::PushItemWidth(window_width - clipping_slider_left - slider_width_times * slider_icon_width);
bool slider_clp_dist = m_imgui->bbl_slider_float_style("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f", 1.0f, true);
ImGui::SameLine(window_width - slider_icon_width);
ImGui::PushItemWidth(1.5 * slider_icon_width);
bool b_clp_dist_input = ImGui::BBLDragFloat("##clp_dist_input", &clp_dist, 0.05f, 0.0f, 0.0f, "%.2f");
if (slider_clp_dist || b_clp_dist_input) { m_c->object_clipper()->set_position(clp_dist, true); }
} else if (m_current_tool == ImGui::FillButtonIcon) {
m_cursor_type = TriangleSelector::CursorType::POINTER;
m_imgui->bbl_checkbox(m_desc["edge_detection"], m_detect_geometry_edge);
@ -511,34 +542,6 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
// set to negative value to disable edge detection
m_smart_fill_angle = -1.f;
}
} else if (m_current_tool == ImGui::HeightRangeIcon) {
m_tool_type = ToolType::BRUSH;
m_cursor_type = TriangleSelector::CursorType::HEIGHT_RANGE;
ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc["height_range"] + ":");
ImGui::SameLine(sliders_left_width);
ImGui::PushItemWidth(window_width - sliders_left_width - slider_width_times * slider_icon_width);
std::string format_str = std::string("%.2f") + I18N::translate_utf8("mm", "Heigh range," "Facet in [cursor z, cursor z + height] will be selected.");
m_imgui->bbl_slider_float_style("##cursor_height", &m_cursor_height, CursorHeightMin, CursorHeightMax, format_str.data(), 1.0f, true);
ImGui::SameLine(window_width - slider_icon_width);
ImGui::PushItemWidth(1.5 * slider_icon_width);
ImGui::BBLDragFloat("##cursor_height_input", &m_cursor_height, 0.05f, 0.0f, 0.0f, "%.2f");
}
else if (m_current_tool == ImGui::FragmentFilterIcon) {
m_tool_type = ToolType::FRAGMENT_FILTER;
m_cursor_type = TriangleSelector::CursorType::POINTER;
ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc["fragment_area"] + ":");
ImGui::SameLine(sliders_left_width);
ImGui::PushItemWidth(window_width - sliders_left_width - slider_width_times * slider_icon_width);
std::string format_str = std::string("%.2f") + I18N::translate_utf8("", "Triangle patch area threshold,""triangle patch will be merged to neighbor if its area is less than threshold");
m_imgui->bbl_slider_float_style("##fragment_area", &TriangleSelectorPatch::fragment_area, TriangleSelectorPatch::FragmentAreaMin, TriangleSelectorPatch::FragmentAreaMax, format_str.data(), 1.0f, true);
ImGui::SameLine(window_width - slider_icon_width);
ImGui::PushItemWidth(1.5 * slider_icon_width);
ImGui::BBLDragFloat("##fragment_area_input", &TriangleSelectorPatch::fragment_area, 0.05f, 0.0f, 0.0f, "%.2f");
}
if (m_current_tool != ImGui::FragmentFilterIcon) {
ImGui::Separator();
ImGui::AlignTextToFramePadding();
@ -552,8 +555,49 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
ImGui::PushItemWidth(1.5 * slider_icon_width);
bool b_clp_dist_input = ImGui::BBLDragFloat("##clp_dist_input", &clp_dist, 0.05f, 0.0f, 0.0f, "%.2f");
if (slider_clp_dist || b_clp_dist_input) { m_c->object_clipper()->set_position(clp_dist, true);}
} else if (m_current_tool == ImGui::HeightRangeIcon) {
m_tool_type = ToolType::BRUSH;
m_cursor_type = TriangleSelector::CursorType::HEIGHT_RANGE;
ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc["height_range"] + ":");
ImGui::SameLine(height_max_width);
ImGui::PushItemWidth(window_width - height_max_width - slider_width_times * slider_icon_width);
std::string format_str = std::string("%.2f") + I18N::translate_utf8("mm", "Heigh range," "Facet in [cursor z, cursor z + height] will be selected.");
m_imgui->bbl_slider_float_style("##cursor_height", &m_cursor_height, CursorHeightMin, CursorHeightMax, format_str.data(), 1.0f, true);
ImGui::SameLine(window_width - slider_icon_width);
ImGui::PushItemWidth(1.5 * slider_icon_width);
ImGui::BBLDragFloat("##cursor_height_input", &m_cursor_height, 0.05f, 0.0f, 0.0f, "%.2f");
ImGui::Separator();
ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc.at("clipping_of_view"));
auto clp_dist = float(m_c->object_clipper()->get_position());
ImGui::SameLine(height_max_width);
ImGui::PushItemWidth(window_width - height_max_width - slider_width_times * slider_icon_width);
bool slider_clp_dist = m_imgui->bbl_slider_float_style("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f", 1.0f, true);
ImGui::SameLine(window_width - slider_icon_width);
ImGui::PushItemWidth(1.5 * slider_icon_width);
bool b_clp_dist_input = ImGui::BBLDragFloat("##clp_dist_input", &clp_dist, 0.05f, 0.0f, 0.0f, "%.2f");
if (slider_clp_dist || b_clp_dist_input) { m_c->object_clipper()->set_position(clp_dist, true); }
}
else if (m_current_tool == ImGui::FragmentFilterIcon) {
m_tool_type = ToolType::FRAGMENT_FILTER;
m_cursor_type = TriangleSelector::CursorType::POINTER;
ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc["fragment_area"] + ":");
ImGui::SameLine(fragment_area_slider_left);
ImGui::PushItemWidth(window_width - fragment_area_slider_left - slider_width_times * slider_icon_width);
std::string format_str = std::string("%.2f") + I18N::translate_utf8("", "Triangle patch area threshold,""triangle patch will be merged to neighbor if its area is less than threshold");
m_imgui->bbl_slider_float_style("##fragment_area", &TriangleSelectorPatch::fragment_area, TriangleSelectorPatch::FragmentAreaMin, TriangleSelectorPatch::FragmentAreaMax, format_str.data(), 1.0f, true);
ImGui::SameLine(window_width - slider_icon_width);
ImGui::PushItemWidth(1.5 * slider_icon_width);
ImGui::BBLDragFloat("##fragment_area_input", &TriangleSelectorPatch::fragment_area, 0.05f, 0.0f, 0.0f, "%.2f");
}
ImGui::Separator();
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(6.0f, 10.0f));

View file

@ -85,7 +85,7 @@ size_t GLGizmosManager::get_gizmo_idx_from_mouse(const Vec2d& mouse_pos) const
//if ((border <= (float)mouse_pos(0) && ((float)mouse_pos(0) <= border + icons_size))) {
if (((top_y + border) <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= (top_y + border + icons_size))) {
// which icon is it on?
size_t from_left = (size_t)((float)mouse_pos(0) - top_x) / stride_x;
int from_left = (float) mouse_pos(0) - top_x < 0 ? -1 : (int) ((float) mouse_pos(0) - top_x) / stride_x;
if (from_left < 0)
return Undefined;
// is it really on the icon or already past the border?

View file

@ -18,6 +18,9 @@
#include <boost/algorithm/string.hpp>
#define MAX_NUM 9999.99
#define MAX_SIZE "9999.99"
namespace Slic3r
{
namespace GUI
@ -25,6 +28,8 @@ namespace GUI
const double GizmoObjectManipulation::in_to_mm = 25.4;
const double GizmoObjectManipulation::mm_to_in = 0.0393700787;
const double GizmoObjectManipulation::oz_to_g = 28.34952;
const double GizmoObjectManipulation::g_to_oz = 0.035274;
// Helper function to be used by drop to bed button. Returns lowest point of this
// volume in world coordinate system.
@ -576,9 +581,10 @@ void GizmoObjectManipulation::do_render_move_window(ImGuiWrapper *imgui_wrapper,
else
original_position = this->m_new_position;
Vec3d display_position = m_buffered_position;
// Rotation
Vec3d rotation = this->m_buffered_rotation;
float unit_size = max_unit_size(2, display_position, display_position, "move") + space_size;;
float unit_size = imgui_wrapper->calc_text_size(MAX_SIZE).x + space_size;
int index = 1;
int index_unit = 1;
@ -611,6 +617,12 @@ void GizmoObjectManipulation::do_render_move_window(ImGuiWrapper *imgui_wrapper,
ImGui::BBLInputDouble(label_values[0][2], &display_position[2], 0.0f, 0.0f, "%.2f");
ImGui::SameLine(caption_max + (++index_unit) * unit_size + (++index) * space_size);
imgui_wrapper->text(this->m_new_unit_string);
for (int i = 0;i<display_position.size();i++)
{
if (display_position[i] > MAX_NUM)display_position[i] = MAX_NUM;
}
m_buffered_position = display_position;
update(current_active_id, "position", original_position, m_buffered_position);
// the init position values are not zero, won't add reset button
@ -671,7 +683,7 @@ void GizmoObjectManipulation::do_render_rotate_window(ImGuiWrapper *imgui_wrappe
};
float space_size = imgui_wrapper->get_style_scaling() * 8;
float position_size = imgui_wrapper->calc_text_size(_L("Position")).x + space_size;
float position_size = imgui_wrapper->calc_text_size(_L("Rotation")).x + space_size;
float World_size = imgui_wrapper->calc_text_size(_L("World coordinates")).x + space_size;
float caption_max = std::max(position_size, World_size) + 2 * space_size;
float end_text_size = imgui_wrapper->calc_text_size(this->m_new_unit_string).x;
@ -685,7 +697,8 @@ void GizmoObjectManipulation::do_render_rotate_window(ImGuiWrapper *imgui_wrappe
Vec3d display_position = m_buffered_position;
// Rotation
Vec3d rotation = this->m_buffered_rotation;
float unit_size = max_unit_size(2, rotation, rotation, "rotate") + space_size * 2;
float unit_size = imgui_wrapper->calc_text_size(MAX_SIZE).x + space_size;
int index = 1;
int index_unit = 1;
@ -792,7 +805,9 @@ void GizmoObjectManipulation::do_render_scale_input_window(ImGuiWrapper* imgui_w
};
float space_size = imgui_wrapper->get_style_scaling() * 8;
float caption_max = imgui_wrapper->calc_text_size(_L("Position:")).x + space_size;
float scale_size = imgui_wrapper->calc_text_size(_L("Scale")).x + space_size;
float size_len = imgui_wrapper->calc_text_size(_L("Size")).x + space_size;
float caption_max = std::max(scale_size, size_len) + 2 * space_size;
float end_text_size = imgui_wrapper->calc_text_size(this->m_new_unit_string).x;
ImGui::AlignTextToFramePadding();
unsigned int current_active_id = ImGui::GetActiveID();
@ -802,12 +817,12 @@ void GizmoObjectManipulation::do_render_scale_input_window(ImGuiWrapper* imgui_w
Vec3d display_position = m_buffered_position;
float unit_size = max_unit_size(2, scale, display_size, "scale") + space_size;
float unit_size = imgui_wrapper->calc_text_size(MAX_SIZE).x + space_size;
bool imperial_units = this->m_imperial_units;
int index = 2;
int index_unit = 1;
ImGui::PushItemWidth(caption_max);
ImGui::Dummy(ImVec2(caption_max, -1));
//imgui_wrapper->text(_L(" "));
@ -839,8 +854,6 @@ void GizmoObjectManipulation::do_render_scale_input_window(ImGuiWrapper* imgui_w
ImGui::BBLInputDouble(label_scale_values[0][2], &scale[2], 0.0f, 0.0f, "%.2f");
ImGui::SameLine(caption_max + (++index_unit) *unit_size + (++index) * space_size);
imgui_wrapper->text(_L("%"));
m_buffered_scale = scale;
if (m_show_clear_scale) {
ImGui::SameLine(caption_max + 3 * unit_size + 4 * space_size + end_text_size);
@ -851,7 +864,6 @@ void GizmoObjectManipulation::do_render_scale_input_window(ImGuiWrapper* imgui_w
ImGui::InvisibleButton("", ImVec2(ImGui::GetFontSize(), ImGui::GetFontSize()));
}
//Size
Vec3d original_size;
if (this->m_imperial_units)
@ -875,6 +887,12 @@ void GizmoObjectManipulation::do_render_scale_input_window(ImGuiWrapper* imgui_w
ImGui::BBLInputDouble(label_scale_values[1][2], &display_size[2], 0.0f, 0.0f, "%.2f");
ImGui::SameLine(caption_max + (++index_unit) *unit_size + (++index) * space_size);
imgui_wrapper->text(this->m_new_unit_string);
for (int i = 0;i<display_size.size();i++)
{
if (display_size[i] > MAX_NUM || scale[i]> MAX_NUM)display_size[i] = MAX_NUM;
}
m_buffered_scale = scale;
m_buffered_size = display_size;
int size_sel = update(current_active_id, "size", original_size, m_buffered_size);
ImGui::PopStyleVar(1);

View file

@ -19,6 +19,8 @@ class GizmoObjectManipulation
public:
static const double in_to_mm;
static const double mm_to_in;
static const double g_to_oz;
static const double oz_to_g;
struct Cache
{

View file

@ -451,6 +451,8 @@ bool IMSlider::init_texture()
result &= IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/one_layer_off.svg", 28, 28, m_one_layer_off_id);
result &= IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/one_layer_off_hover.svg", 28, 28, m_one_layer_off_hover_id);
result &= IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/one_layer_arrow.svg", 28, 28, m_one_layer_arrow_id);
result &= IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/im_gcode_pause.svg", 14, 14, m_pause_icon_id);
result &= IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/im_slider_delete.svg", 14, 14, m_delete_icon_id);
}
return result;
@ -859,11 +861,13 @@ void IMSlider::draw_ticks(const ImRect& slideable_region) {
if (m_ticks.empty())
return;
ImGuiContext &context = *GImGui;
ImVec2 tick_box = ImVec2(46.0f, 16.0f) * m_scale;
ImVec2 tick_offset = ImVec2(19.0f, 11.0f) * m_scale;
float tick_width = 1.0f * m_scale;
ImVec2 icon_offset = ImVec2(13.0f, 7.0f) * m_scale;
ImVec2 icon_size = ImVec2(16.0f, 16.0f) * m_scale;
ImVec2 icon_size = ImVec2(14.0f, 14.0f) * m_scale;
const ImU32 tick_clr = IM_COL32(144, 144, 144, 255);
const ImU32 tick_hover_box_clr = IM_COL32(219, 253, 231, 255);
@ -876,12 +880,10 @@ void IMSlider::draw_ticks(const ImRect& slideable_region) {
return get_pos_from_value(v_min, v_max, tick, slideable_region);
};
float tick_pos;
std::set<TickCode>::const_iterator tick_it = m_ticks.ticks.begin();
while (tick_it != m_ticks.ticks.end())
{
tick_pos = get_tick_pos(tick_it->tick);
float tick_pos = get_tick_pos(tick_it->tick);
//draw tick hover box when hovered
ImRect tick_hover_box = ImRect(slideable_region.GetCenter().x - tick_box.x / 2, tick_pos - tick_box.y / 2, slideable_region.GetCenter().x + tick_box.x / 2,
@ -890,8 +892,10 @@ void IMSlider::draw_ticks(const ImRect& slideable_region) {
if (ImGui::IsMouseHoveringRect(tick_hover_box.Min, tick_hover_box.Max))
{
ImGui::RenderFrame(tick_hover_box.Min, tick_hover_box.Max, tick_hover_box_clr, false);
m_tick_value = tick_it->tick;
m_tick_rect = ImVec4(tick_hover_box.Min.x, tick_hover_box.Min.y, tick_hover_box.Max.x, tick_hover_box.Max.y);
if (context.IO.MouseClicked[0]) {
m_tick_value = tick_it->tick;
m_tick_rect = ImVec4(tick_hover_box.Min.x, tick_hover_box.Min.y, tick_hover_box.Max.x, tick_hover_box.Max.y);
}
}
++tick_it;
}
@ -899,7 +903,7 @@ void IMSlider::draw_ticks(const ImRect& slideable_region) {
tick_it = m_ticks.ticks.begin();
while (tick_it != m_ticks.ticks.end())
{
tick_pos = get_tick_pos(tick_it->tick);
float tick_pos = get_tick_pos(tick_it->tick);
//draw ticks
ImRect tick_left = ImRect(slideable_region.GetCenter().x - tick_offset.x, tick_pos - tick_width, slideable_region.GetCenter().x - tick_offset.y, tick_pos);
@ -908,17 +912,36 @@ void IMSlider::draw_ticks(const ImRect& slideable_region) {
ImGui::RenderFrame(tick_right.Min, tick_right.Max, tick_clr, false);
//draw pause icon
ImGui::PushID(tick_it->tick);
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
if (tick_it->type == PausePrint) {
std::wstring pause_icon_name = ImGui::GcodePauseIcon + boost::nowide::widen(std::string(""));
button_with_pos(into_u8(pause_icon_name).c_str(), icon_size, ImVec2(slideable_region.GetCenter().x + icon_offset.x, tick_pos - icon_offset.y));
ImTextureID pause_icon_id = m_pause_icon_id;
ImVec2 icon_pos = ImVec2(slideable_region.GetCenter().x + icon_offset.x, tick_pos - icon_offset.y);
button_with_pos(pause_icon_id, icon_size, icon_pos);
if (ImGui::IsMouseHoveringRect(icon_pos, icon_pos + icon_size)) {
if(context.IO.MouseClicked[0])
int a = 0;
}
}
ImGui::PopStyleColor(1);
ImGui::PopID();
++tick_it;
}
tick_it = GetSelection() == ssHigher ? m_ticks.ticks.find(TickCode{this->GetHigherValue()}) :
GetSelection() == ssLower ? m_ticks.ticks.find(TickCode{this->GetLowerValue()}) :
m_ticks.ticks.end();
if (tick_it != m_ticks.ticks.end()) {
// draw delete icon
ImTextureID delete_icon_id = m_delete_icon_id;
ImVec2 icon_pos = ImVec2(slideable_region.GetCenter().x + icon_offset.x, get_tick_pos(tick_it->tick) - icon_offset.y);
button_with_pos(m_delete_icon_id, icon_size, icon_pos);
if (ImGui::IsMouseHoveringRect(icon_pos, icon_pos + icon_size)) {
if (context.IO.MouseClicked[0]) {
// delete tick
Type type = tick_it->type;
m_ticks.ticks.erase(tick_it);
post_ticks_changed_event(type);
}
}
}
}
bool IMSlider::vertical_slider(const char* str_id, int* higher_value, int* lower_value, std::string& higher_label, std::string& lower_label,int v_min, int v_max, const ImVec2& pos,const ImVec2& size, SelectedSlider& selection, bool one_layer_flag, float scale)
@ -989,8 +1012,7 @@ bool IMSlider::vertical_slider(const char* str_id, int* higher_value, int* lower
ImRect one_handle = ImRect(higher_handle.Min - ImVec2(one_handle_offset, 0), higher_handle.Max - ImVec2(one_handle_offset, 0));
static bool become_del_handle = false;
static bool pressed_in_del = false;
//static bool become_del_handle = false;
bool value_changed = false;
if (!one_layer_flag)
{
@ -999,14 +1021,10 @@ bool IMSlider::vertical_slider(const char* str_id, int* higher_value, int* lower
if (ImGui::ItemHoverable(higher_handle, id) && context.IO.MouseClicked[0]) {
selection = ssHigher;
h_selected = true;
m_tick_value = -1;
m_tick_rect = ImVec4();
}
if (ImGui::ItemHoverable(lower_handle, id) && context.IO.MouseClicked[0]) {
selection = ssLower;
h_selected = false;
m_tick_value = -1;
m_tick_rect = ImVec4();
}
// update handle position and value
@ -1015,31 +1033,11 @@ bool IMSlider::vertical_slider(const char* str_id, int* higher_value, int* lower
value_changed = slider_behavior(id, higher_slideable_region, v_min, v_max,
higher_value, &higher_handle, ImGuiSliderFlags_Vertical,
m_tick_value, m_tick_rect);
auto it = m_ticks.ticks.find(TickCode{ *higher_value });
if (it != m_ticks.ticks.end() && check_ticks_changed_event(it->type))
{
become_del_handle = true;
}
else {
become_del_handle = false;
pressed_in_del = false;
}
}
if (!h_selected) {
value_changed = slider_behavior(id, lower_slideable_region, v_min, v_max,
lower_value, &lower_handle, ImGuiSliderFlags_Vertical,
m_tick_value, m_tick_rect);
auto it = m_ticks.ticks.find(TickCode{ *lower_value });
if (it != m_ticks.ticks.end() && check_ticks_changed_event(it->type))
{
become_del_handle = true;
}
else {
become_del_handle = false;
pressed_in_del = false;
}
}
ImVec2 higher_handle_center = higher_handle.GetCenter();
@ -1095,37 +1093,6 @@ bool IMSlider::vertical_slider(const char* str_id, int* higher_value, int* lower
window->DrawList->AddLine(lower_handle_center + ImVec2(0.0f, -line_offset), lower_handle_center + ImVec2(0.0f, line_offset), white_bg, line_width);
}
if (become_del_handle) {
if (context.IO.MouseDown[0] &&
(ImGui::ItemHoverable(h_selected ? higher_handle : lower_handle, id)))
{
pressed_in_del = true;
}
if (pressed_in_del && context.IO.MouseReleased[0] && ImGui::ItemHoverable(h_selected ? higher_handle : lower_handle, id)) {
pressed_in_del = false;
//delete tick
auto it = m_ticks.ticks.find(TickCode{ h_selected ? *higher_value : *lower_value });
if (it != m_ticks.ticks.end() && check_ticks_changed_event(it->type))
{
Type type = it->type;
m_ticks.ticks.erase(it);
post_ticks_changed_event(type);
m_tick_value = -1;
m_tick_rect = ImVec4();
}
}
if (h_selected) {
window->DrawList->AddCircleFilled(higher_handle_center, handle_radius - handle_border, delete_btn_clr);
window->DrawList->AddLine(higher_handle_center + ImVec2(-line_offset, 0.0f), higher_handle_center + ImVec2(line_offset, 0.0f), white_bg, line_width);
}
if (!h_selected) {
window->DrawList->AddCircleFilled(lower_handle_center, handle_radius - handle_border, delete_btn_clr);
window->DrawList->AddLine(lower_handle_center + ImVec2(-line_offset, 0.0f), lower_handle_center + ImVec2(line_offset, 0.0f), white_bg, line_width);
}
}
// draw higher label
auto text_utf8 = into_u8(higher_label);
text_content_size = ImGui::CalcTextSize(text_utf8.c_str());
@ -1157,15 +1124,7 @@ bool IMSlider::vertical_slider(const char* str_id, int* higher_value, int* lower
value_changed = slider_behavior(id, one_slideable_region, v_min, v_max,
higher_value, &one_handle, ImGuiSliderFlags_Vertical,
m_tick_value, m_tick_rect);
auto it = m_ticks.ticks.find(TickCode{ *higher_value });
if (it != m_ticks.ticks.end() && check_ticks_changed_event(it->type))
{
become_del_handle = true;
}
else {
become_del_handle = false;
pressed_in_del;
}
ImVec2 handle_center = one_handle.GetCenter();
// judge whether to open menu
@ -1190,28 +1149,6 @@ bool IMSlider::vertical_slider(const char* str_id, int* higher_value, int* lower
window->DrawList->AddCircleFilled(handle_center, handle_radius - handle_border, handle_clr);
window->DrawList->AddLine(handle_center + ImVec2(-line_offset, 0.0f), handle_center + ImVec2(line_offset, 0.0f), white_bg, line_width);
window->DrawList->AddLine(handle_center + ImVec2(0.0f, -line_offset), handle_center + ImVec2(0.0f, line_offset), white_bg, line_width);
if (become_del_handle) {
if (context.IO.MouseDown[0] &&
(ImGui::ItemHoverable(one_handle, id)))
{
pressed_in_del = true;
}
if (pressed_in_del && context.IO.MouseReleased[0] && ImGui::ItemHoverable(one_handle, id)) {
pressed_in_del = false;
//delete tick
auto it = m_ticks.ticks.find(TickCode{ *higher_value });
if (it != m_ticks.ticks.end() && check_ticks_changed_event(it->type))
{
Type type = it->type;
m_ticks.ticks.erase(it);
post_ticks_changed_event(type);
m_tick_value = -1;
m_tick_rect = ImVec4();
}
}
window->DrawList->AddCircleFilled(handle_center, handle_radius - handle_border, delete_btn_clr);
window->DrawList->AddLine(handle_center + ImVec2(-line_offset, 0.0f), handle_center + ImVec2(line_offset, 0.0f), white_bg, line_width);
}
// draw label
auto text_utf8 = into_u8(higher_label);
@ -1222,6 +1159,7 @@ bool IMSlider::vertical_slider(const char* str_id, int* higher_value, int* lower
ImGui::RenderFrame(text_rect.Min, text_rect.Max, white_bg, false, rounding);
ImGui::RenderText(text_start + text_padding, higher_label.c_str());
}
return value_changed;
}
@ -1294,6 +1232,7 @@ bool IMSlider::render(int canvas_width, int canvas_height)
ImGui::PopStyleVar(3);
ImGui::PopStyleColor(2);
return result;
}

View file

@ -343,6 +343,8 @@ private:
void *m_one_layer_arrow_id;
void *m_one_layer_off_id;
void *m_one_layer_off_hover_id;
void *m_pause_icon_id;
void *m_delete_icon_id;
DrawMode m_draw_mode = dmRegular;
Mode m_mode = SingleExtruder;

View file

@ -64,8 +64,7 @@ static const std::map<const wchar_t, std::string> font_icons = {
{ImGui::FragmentFilterIcon , "fragment_filter" },
{ImGui::FoldButtonIcon , "im_fold" },
{ImGui::UnfoldButtonIcon , "im_unfold" },
{ImGui::GcodePauseIcon , "im_gcode_pause" },
{ImGui::SphereButtonIcon , "toolbar_modifier_sphere" },
{ImGui::SphereButtonIcon , "toolbar_modifier_sphere" },
};
static const std::map<const wchar_t, std::string> font_icons_large = {
@ -257,30 +256,37 @@ bool slider_behavior(ImGuiID id, const ImRect& region, const ImS32 v_min, const
return value_changed;
}
bool button_with_pos(const char* label, const ImVec2& size, const ImVec2& pos, ImGuiButtonFlags flags/* = 0*/) {
bool button_with_pos(ImTextureID user_texture_id, const ImVec2 &size, const ImVec2 &pos, const ImVec2 &uv0, const ImVec2 &uv1, int frame_padding, const ImVec4 &bg_col, const ImVec4 &tint_col, const ImVec2 &margin)
{
ImGuiWindow* window = ImGui::GetCurrentWindow();
if (window->SkipItems)
return false;
ImGuiContext &g = *GImGui;
ImGuiWindow * window = g.CurrentWindow;
if (window->SkipItems) return false;
ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const ImGuiID id = window->GetID(label);
const ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true);
// Default to using texture ID as ID. User can still push string/integer prefixes.
ImGui::PushID((void *) (intptr_t) user_texture_id);
const ImGuiID id = window->GetID("#image");
ImGui::PopID();
const ImRect bb(pos, pos + size);
const ImVec2 padding = (frame_padding >= 0) ? ImVec2((float) frame_padding, (float) frame_padding) : g.Style.FramePadding;
const ImRect bb(pos, pos + size + padding * 2 + margin * 2);
bool hovered, held;
bool pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held, flags);
bool pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held);
// Render
const ImU32 col = ImGui::GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
ImGui::RenderNavHighlight(bb, id);
ImGui::RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding);
if (g.LogEnabled)
ImGui::LogSetNextTextDecoration("[", "]");
ImGui::RenderTextClipped(bb.Min + style.FramePadding, bb.Max - style.FramePadding, label, NULL, &label_size, style.ButtonTextAlign, &bb);
const float border_size = g.Style.FrameBorderSize;
if (border_size > 0.0f) {
window->DrawList->AddRect(bb.Min + ImVec2(1, 1), bb.Max + ImVec2(1, 1), col, g.Style.FrameRounding, 0, border_size);
window->DrawList->AddRect(bb.Min, bb.Max, col, g.Style.FrameRounding, 0, border_size);
}
if (bg_col.w > 0.0f) window->DrawList->AddRectFilled(bb.Min + padding, bb.Max - padding, ImGui::GetColorU32(bg_col));
window->DrawList->AddImage(user_texture_id, bb.Min + padding + margin, bb.Max - padding - margin, uv0, uv1, ImGui::GetColorU32(tint_col));
return pressed;
}

View file

@ -28,7 +28,15 @@ namespace GUI {
bool get_data_from_svg(const std::string &filename, unsigned int max_size_px, ThumbnailData &thumbnail_data);
bool slider_behavior(ImGuiID id, const ImRect& region, const ImS32 v_min, const ImS32 v_max, ImS32* out_value, ImRect* out_handle, ImGuiSliderFlags flags = 0, const int fixed_value = -1, const ImVec4& fixed_rect = ImVec4());
bool button_with_pos(const char* label, const ImVec2& size, const ImVec2& pos, ImGuiButtonFlags flags = 0);
bool button_with_pos(ImTextureID user_texture_id,
const ImVec2 &size,
const ImVec2 &pos,
const ImVec2 &uv0 = ImVec2(0, 0),
const ImVec2 &uv1 = ImVec2(1, 1),
int frame_padding = -1,
const ImVec4 &bg_col = ImVec4(0, 0, 0, 0),
const ImVec4 &tint_col = ImVec4(1, 1, 1, 1),
const ImVec2 &margin = ImVec2(0, 0));
bool menu_item_with_icon(const char* label, const char* shortcut, ImU32 icon_color, bool selected, bool enabled = true);

View file

@ -99,9 +99,11 @@ void BindJob::process()
} else if (stage == BBL::BindJobStage::LoginStageFinished) {
curr_percent = 100;
msg = _L("Logging in");
} else {
msg = _L("Logging in");
}
if (code != 0) {
msg = login_failed_str + wxString::Format("(code=%d,info=%s)", code, info);
msg = _L("Login failed") + wxString::Format("(code=%d,info=%s)", code, info);
}
update_status(curr_percent, msg);
}

View file

@ -51,6 +51,49 @@ void PrintJob::on_success(std::function<void()> success)
m_success_fun = success;
}
wxString PrintJob::get_http_error_msg(unsigned int status, std::string body)
{
int code = 0;
std::string error;
std::string message;
wxString result;
if (status >= 400 && status < 500)
try {
json j = json::parse(body);
if (j.contains("code")) {
if (!j["code"].is_null())
code = j["code"].get<int>();
}
if (j.contains("error")) {
if (!j["error"].is_null())
error = j["error"].get<std::string>();
}
if (j.contains("message")) {
if (!j["message"].is_null())
message = j["message"].get<std::string>();
}
switch (status) {
;
}
}
catch (...) {
;
}
else if (status == 503) {
return _L("Service Unavailable");
}
else {
wxString unkown_text = _L("Unkown Error.");
unkown_text += wxString::Format("status=%u, body=%s", status, body);
return unkown_text;
}
BOOST_LOG_TRIVIAL(error) << "http_error: status=" << status << ", code=" << code << ", error=" << error;
result = wxString::Format("code=%u, error=%s", code, from_u8(error));
return result;
}
void PrintJob::process()
{
/* display info */
@ -114,8 +157,10 @@ void PrintJob::process()
params.dev_ip = m_dev_ip;
params.username = "bblp";
params.password = m_access_code;
wxString error_text;
wxString msg_text;
auto update_fn = [this, &msg, &curr_percent](int stage, int code, std::string info) {
auto update_fn = [this, &msg, &curr_percent, &error_text](int stage, int code, std::string info) {
if (stage == BBL::SendingPrintJobStage::PrintingStageCreate) {
if (this->connection_type == "lan") {
msg = _L("Sending print job over LAN");
@ -157,7 +202,7 @@ void PrintJob::process()
}
else if (stage == BBL::SendingPrintJobStage::PrintingStageFinished) {
curr_percent = 100;
msg = wxString::Format(_L("Successfully sent.Will automatically jump to the device page in %s s"), info);
msg = wxString::Format(_L("Successfully sent. Will automatically jump to the device page in %s s"), info);
} else {
if (this->connection_type == "lan") {
msg = _L("Sending print job over LAN");
@ -165,6 +210,10 @@ void PrintJob::process()
msg = _L("Sending print job through cloud service");
}
}
if (code != 0) {
error_text = this->get_http_error_msg(code, info);
msg += wxString::Format("[%s]", error_text);
}
this->update_status(curr_percent, msg);
};
@ -193,19 +242,6 @@ void PrintJob::process()
BOOST_LOG_TRIVIAL(info) << "print_job: send with cloud";
this->update_status(curr_percent, _L("Sending print job through cloud service"));
result = m_agent->start_print(params, update_fn, cancel_fn);
if (result < 0) {
if (!params.password.empty() && !params.dev_ip.empty()) {
//try to send with local only
if (this->has_sdcard) {
this->update_status(curr_percent, _L("Sending print job over LAN"));
result = m_agent->start_local_print(params, update_fn, cancel_fn);
} else {
this->update_status(curr_percent, _L("Failed to connect to the cloud server connection. Please insert an SD card and resend the print job, which will transfer the print file via LAN. "));
BOOST_LOG_TRIVIAL(error) << "print_job: failed, need sdcard";
return;
}
}
}
}
} else {
if (this->has_sdcard) {
@ -224,26 +260,29 @@ void PrintJob::process()
if (result < 0) {
if (result == BAMBU_NETWORK_ERR_FTP_LOGIN_DENIED) {
update_status(curr_percent, upload_failed_str);
msg_text = upload_failed_str;
} if (result == BAMBU_NETWORK_ERR_FILE_NOT_EXIST) {
update_status(curr_percent, file_is_not_exists_str);
msg_text = file_is_not_exists_str;
} else if (result == BAMBU_NETWORK_ERR_FILE_OVER_SIZE) {
update_status(curr_percent, file_over_size_str);
msg_text = file_over_size_str;
} else if (result == BAMBU_NETWORK_ERR_CHECK_MD5_FAILED) {
update_status(curr_percent, failed_in_cloud_service_str);
msg_text = failed_in_cloud_service_str;
} else if (result == BAMBU_NETWORK_ERR_INVALID_PARAMS) {
update_status(curr_percent, upload_failed_str);
msg_text = upload_failed_str;
} else if (result == BAMBU_NETWORK_ERR_CANCELED) {
update_status(curr_percent, print_canceled_str);
msg_text = print_canceled_str;
} else if (result == BAMBU_NETWORK_ERR_TIMEOUT) {
update_status(curr_percent, timeout_to_upload_str);
msg_text = timeout_to_upload_str;
} else if (result == BAMBU_NETWORK_ERR_INVALID_RESULT) {
update_status(curr_percent, upload_failed_str);
msg_text = upload_failed_str;
} else if (result == BAMBU_NETWORK_ERR_FTP_UPLOAD_FAILED) {
update_status(curr_percent, upload_failed_str);
msg_text = upload_failed_str;
} else {
update_status(curr_percent, failed_in_cloud_service_str);
}
if (!error_text.IsEmpty())
msg_text += wxString::Format("[%s]", error_text);
update_status(curr_percent, msg_text);
BOOST_LOG_TRIVIAL(error) << "print_job: failed, result = " << result;
} else {
BOOST_LOG_TRIVIAL(error) << "print_job: send ok.";

View file

@ -70,6 +70,7 @@ public:
void set_print_job_finished_event(int event_id) { m_print_job_completed_id = event_id; }
void on_success(std::function<void()> success);
wxString get_http_error_msg(unsigned int status, std::string body);
void process() override;
void finalize() override;
};

View file

@ -0,0 +1,136 @@
#include "UpgradeNetworkJob.hpp"
#include "slic3r/GUI/GUI.hpp"
#include "slic3r/GUI/GUI_App.hpp"
#include "slic3r/Utils/Http.hpp"
namespace Slic3r {
namespace GUI {
wxDEFINE_EVENT(EVT_UPGRADE_UPDATE_MESSAGE, wxCommandEvent);
wxDEFINE_EVENT(EVT_UPGRADE_NETWORK_SUCCESS, wxCommandEvent);
wxDEFINE_EVENT(EVT_UPGRADE_NETWORK_FAILED, wxCommandEvent);
UpgradeNetworkJob::UpgradeNetworkJob(std::shared_ptr<ProgressIndicator> pri)
: Job{std::move(pri)}
{
;
}
void UpgradeNetworkJob::on_exception(const std::exception_ptr &eptr)
{
try {
if (eptr)
std::rethrow_exception(eptr);
} catch (std::exception &e) {
UpgradeNetworkJob::on_exception(eptr);
}
}
void UpgradeNetworkJob::on_success(std::function<void()> success)
{
m_success_fun = success;
}
void UpgradeNetworkJob::update_status(int st, const wxString &msg)
{
GUI::Job::update_status(st, msg);
wxCommandEvent event(EVT_UPGRADE_UPDATE_MESSAGE);
event.SetString(msg);
event.SetEventObject(m_event_handle);
wxPostEvent(m_event_handle, event);
}
void UpgradeNetworkJob::process()
{
// downloading
int result = 0;
AppConfig* app_config = wxGetApp().app_config;
if (!app_config)
return;
BOOST_LOG_TRIVIAL(info) << "[download_plugin]: enter";
// get temp path
fs::path target_file_path = (fs::temp_directory_path() / "network_plugin.zip");
fs::path tmp_path = target_file_path;
auto path_str = tmp_path.string() + wxString::Format(".%d%s", get_current_pid(), ".tmp").ToStdString();
tmp_path = fs::path(path_str);
auto cancel_fn = [this]() {
return was_canceled();
};
int curr_percent = 0;
result = wxGetApp().download_plugin(
[this, &curr_percent](int state, int percent, bool &cancel) {
if (state == InstallStatusNormal) {
update_status(percent, _L("Downloading"));
} else if (state == InstallStatusDownloadFailed) {
update_status(percent, _L("Download failed"));
} else {
update_status(percent, _L("Downloading"));
}
curr_percent = percent;
}, cancel_fn);
if (was_canceled()) {
update_status(0, _L("Cancelled"));
wxCommandEvent event(wxEVT_CLOSE_WINDOW);
event.SetEventObject(m_event_handle);
wxPostEvent(m_event_handle, event);
return;
}
if (result < 0) {
update_status(curr_percent, _L("Download failed"));
wxCommandEvent event(EVT_UPGRADE_NETWORK_FAILED);
event.SetEventObject(m_event_handle);
wxPostEvent(m_event_handle, event);
return;
}
result = wxGetApp().install_plugin([this](int state, int percent, bool&cancel) {
if (state == InstallStatusInstallCompleted) {
update_status(percent, _L("Finish"));
} else {
update_status(percent, _L("Installing"));
}
}, cancel_fn);
if (was_canceled()) {
update_status(0, _L("Cancelled"));
wxCommandEvent event(wxEVT_CLOSE_WINDOW);
event.SetEventObject(m_event_handle);
wxPostEvent(m_event_handle, event);
return;
}
if (result != 0) {
update_status(curr_percent, _L("Install failed"));
wxCommandEvent event(EVT_UPGRADE_NETWORK_FAILED);
event.SetEventObject(m_event_handle);
wxPostEvent(m_event_handle, event);
return;
}
wxCommandEvent event(EVT_UPGRADE_NETWORK_SUCCESS);
event.SetEventObject(m_event_handle);
wxPostEvent(m_event_handle, event);
return;
}
void UpgradeNetworkJob::finalize()
{
if (was_canceled()) return;
Job::finalize();
}
void UpgradeNetworkJob::set_event_handle(wxWindow *hanle)
{
m_event_handle = hanle;
}
}} // namespace Slic3r::GUI

View file

@ -0,0 +1,56 @@
#ifndef __UpgradeNetworkJob_HPP__
#define __UpgradeNetworkJob_HPP__
#include <functional>
#include "Job.hpp"
namespace fs = boost::filesystem;
namespace Slic3r {
namespace GUI {
enum PluginInstallStatus {
InstallStatusNormal = 0,
InstallStatusDownloadFailed = 1,
InstallStatusDownloadCompleted = 2,
InstallStatusUnzipFailed = 3,
InstallStatusInstallCompleted = 4,
};
typedef std::function<void(int status, int percent, bool& cancel)> InstallProgressFn;
class UpgradeNetworkJob : public Job
{
wxWindow * m_event_handle{nullptr};
std::function<void()> m_success_fun{nullptr};
bool m_job_finished{ false };
int m_print_job_completed_id = 0;
InstallProgressFn pro_fn { nullptr };
protected:
void on_exception(const std::exception_ptr &) override;
public:
UpgradeNetworkJob(std::shared_ptr<ProgressIndicator> pri);
int status_range() const override
{
return 100;
}
bool is_finished() { return m_job_finished; }
void on_success(std::function<void()> success);
void update_status(int st, const wxString &msg);
void process() override;
void finalize() override;
void set_event_handle(wxWindow* hanle);
};
wxDECLARE_EVENT(EVT_UPGRADE_UPDATE_MESSAGE, wxCommandEvent);
wxDECLARE_EVENT(EVT_UPGRADE_NETWORK_SUCCESS, wxCommandEvent);
wxDECLARE_EVENT(EVT_UPGRADE_NETWORK_FAILED, wxCommandEvent);
}} // namespace Slic3r::GUI
#endif // ARRANGEJOB_HPP

View file

@ -157,7 +157,7 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_
#ifdef __WXOSX__
set_miniaturizable(GetHandle());
#endif
//reset developer_mode to false and user_mode to comAdvanced
wxGetApp().app_config->set_bool("developer_mode", false);
if (wxGetApp().app_config->get("user_mode") == "develop") {
@ -178,17 +178,17 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_
// Fonts were created by the DPIFrame constructor for the monitor, on which the window opened.
wxGetApp().update_fonts(this);
#ifdef __WINDOWS__
m_topbar = new BBLTopbar(this);
#else
#ifdef __WINDOWS__
m_topbar = new BBLTopbar(this);
#else
auto panel_topbar = new wxPanel(this, wxID_ANY);
panel_topbar->SetBackgroundColour(wxColour(38, 46, 48));
auto sizer_tobar = new wxBoxSizer(wxVERTICAL);
m_topbar = new BBLTopbar(panel_topbar, this);
m_topbar = new BBLTopbar(this);
sizer_tobar->Add(m_topbar, 0, wxEXPAND);
panel_topbar->SetSizer(sizer_tobar);
panel_topbar->Layout();
#endif
#endif
@ -326,11 +326,11 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_
// initialize layout
m_main_sizer = new wxBoxSizer(wxVERTICAL);
wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
#ifdef __WINDOWS__
#ifdef __WINDOWS__
sizer->Add(m_topbar, 0, wxEXPAND);
#else
#else
sizer->Add(panel_topbar, 0, wxEXPAND);
#endif // __WINDOWS__
#endif // __WINDOWS__
sizer->Add(m_main_sizer, 1, wxEXPAND);
@ -357,14 +357,10 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_
Fit();
const wxSize min_size = wxGetApp().get_min_size(); //wxSize(76*wxGetApp().em_unit(), 49*wxGetApp().em_unit());
#ifdef __APPLE__
// Using SetMinSize() on Mac messes up the window position in some cases
// cf. https://groups.google.com/forum/#!topic/wx-users/yUKPBBfXWO0
SetSize(min_size/*wxSize(760, 490)*/);
#else
SetMinSize(min_size/*wxSize(760, 490)*/);
SetSize(wxSize(FromDIP(1200), FromDIP(800)));
#endif
Layout();
update_title();
@ -747,6 +743,29 @@ void MainFrame::init_tabpanel()
m_tabpanel->Hide();
m_settings_dialog.set_tabpanel(m_tabpanel);
m_tabpanel->Bind(wxEVT_NOTEBOOK_PAGE_CHANGING, [this](wxBookCtrlEvent& e) {
int old_sel = e.GetOldSelection();
int new_sel = e.GetSelection();
if (new_sel == tpMonitor) {
if (!wxGetApp().getAgent()) {
e.Veto();
BOOST_LOG_TRIVIAL(info) << boost::format("skipped tab switch from %1% to %2%, lack of network plugins")%old_sel %new_sel;
if (m_plater) {
wxCommandEvent *evt = new wxCommandEvent(EVT_INSTALL_PLUGIN_HINT);
wxQueueEvent(m_plater, evt);
}
}
}
else if (new_sel == tp3DEditor) {
if (m_plater && (m_plater->only_gcode_mode() || (m_plater->using_exported_file()))) {
e.Veto();
BOOST_LOG_TRIVIAL(info) << boost::format("skipped tab switch from %1% to %2% in preview mode")%old_sel %new_sel;
wxCommandEvent *evt = new wxCommandEvent(EVT_PREVIEW_ONLY_MODE_HINT);
wxQueueEvent(m_plater, evt);
}
}
});
#ifdef __WXMSW__
m_tabpanel->Bind(wxEVT_BOOKCTRL_PAGE_CHANGED, [this](wxBookCtrlEvent& e) {
#else
@ -758,12 +777,11 @@ void MainFrame::init_tabpanel()
//wxString page_text = m_tabpanel->GetPageText(sel);
m_last_selected_tab = m_tabpanel->GetSelection();
if (panel == m_plater) {
if (m_with_3dEditor && (sel == tp3DEditor)) {
if (sel == tp3DEditor) {
wxPostEvent(m_plater, SimpleEvent(EVT_GLVIEWTOOLBAR_3D));
m_param_panel->OnActivate();
}
else if ((m_with_3dEditor&&(sel == tpPreview))
|| (!m_with_3dEditor&&(sel == tp3DEditor))){
else if (sel == tpPreview) {
wxPostEvent(m_plater, SimpleEvent(EVT_GLVIEWTOOLBAR_PREVIEW));
m_param_panel->OnActivate();
}
@ -774,7 +792,7 @@ void MainFrame::init_tabpanel()
//monitor
}
if (m_with_3dEditor && (sel == tp3DEditor)) {
if (sel == tp3DEditor) {
m_topbar->EnableUndoRedoItems();
}
else {
@ -1672,10 +1690,13 @@ void MainFrame::init_menubar_as_editor()
append_menu_item(export_menu, wxID_ANY, _L("Export all objects as STL") + dots, _L("Export all objects as STL"),
[this](wxCommandEvent&) { if (m_plater) m_plater->export_stl(); }, "menu_export_stl", nullptr,
[this](){return can_export_model(); }, this);
// BBS export Gcode
wxMenuItem* item_export_gcode = append_menu_item(export_menu, wxID_ANY, _L("Export Sliced File") + dots/* + "\tCtrl+G"*/, _L("Export current Sliced file"),
// BBS export .gcode.3mf
append_menu_item(export_menu, wxID_ANY, _L("Export Sliced File") + dots/* + "\tCtrl+G"*/, _L("Export current Sliced file"),
[this](wxCommandEvent&) { if (m_plater) wxPostEvent(m_plater, SimpleEvent(EVT_GLTOOLBAR_EXPORT_SLICED_FILE)); }, "menu_export_sliced_file", nullptr,
[this](){return can_export_gcode(); }, this);
append_menu_item(export_menu, wxID_ANY, _L("Export G-code") + dots/* + "\tCtrl+G"*/, _L("Export current plate as G-code"),
[this](wxCommandEvent&) { if (m_plater) m_plater->export_gcode(false); }, "menu_export_gcode", nullptr,
[this]() {return can_export_gcode(); }, this);
append_submenu(fileMenu, export_menu, wxID_ANY, _L("Export"), "");
@ -1788,20 +1809,20 @@ void MainFrame::init_menubar_as_editor()
append_menu_item(editMenu, wxID_ANY, _L("Deselect all") + "\tEsc",
_L("Deselects all objects"), [this](wxCommandEvent&) { m_plater->deselect_all(); },
"", nullptr, [this](){return can_deselect(); }, this);
editMenu->AppendSeparator();
append_menu_check_item(editMenu, wxID_ANY, _L("Show Model Mesh(TODO)"),
_L("Display triangles of models"), [this](wxCommandEvent& evt) {
wxGetApp().app_config->set_bool("show_model_mesh", evt.GetInt() == 1);
}, nullptr, [this]() {return can_select(); }, [this]() { return wxGetApp().app_config->get("show_model_mesh").compare("true") == 0; }, this);
append_menu_check_item(editMenu, wxID_ANY, _L("Show Model Shadow(TODO)"), _L("Display shadow of objects"),
[this](wxCommandEvent& evt) {
wxGetApp().app_config->set_bool("show_model_shadow", evt.GetInt() == 1);
}, nullptr, [this]() {return can_select(); }, [this]() { return wxGetApp().app_config->get("show_model_shadow").compare("true") == 0; }, this);
editMenu->AppendSeparator();
append_menu_check_item(editMenu, wxID_ANY, _L("Show Printable Box(TODO)"), _L("Display printable box"),
[this](wxCommandEvent& evt) {
wxGetApp().app_config->set_bool("show_printable_box", evt.GetInt() == 1);
}, nullptr, [this]() {return can_select(); }, [this]() { return wxGetApp().app_config->get("show_printable_box").compare("true") == 0; }, this);
//editMenu->AppendSeparator();
//append_menu_check_item(editMenu, wxID_ANY, _L("Show Model Mesh(TODO)"),
// _L("Display triangles of models"), [this](wxCommandEvent& evt) {
// wxGetApp().app_config->set_bool("show_model_mesh", evt.GetInt() == 1);
// }, nullptr, [this]() {return can_select(); }, [this]() { return wxGetApp().app_config->get("show_model_mesh").compare("true") == 0; }, this);
//append_menu_check_item(editMenu, wxID_ANY, _L("Show Model Shadow(TODO)"), _L("Display shadow of objects"),
// [this](wxCommandEvent& evt) {
// wxGetApp().app_config->set_bool("show_model_shadow", evt.GetInt() == 1);
// }, nullptr, [this]() {return can_select(); }, [this]() { return wxGetApp().app_config->get("show_model_shadow").compare("true") == 0; }, this);
//editMenu->AppendSeparator();
//append_menu_check_item(editMenu, wxID_ANY, _L("Show Printable Box(TODO)"), _L("Display printable box"),
// [this](wxCommandEvent& evt) {
// wxGetApp().app_config->set_bool("show_printable_box", evt.GetInt() == 1);
// }, nullptr, [this]() {return can_select(); }, [this]() { return wxGetApp().app_config->get("show_printable_box").compare("true") == 0; }, this);
}
// BBS
@ -2234,7 +2255,7 @@ void MainFrame::select_tab(wxPanel* panel)
//BBS
void MainFrame::jump_to_monitor(std::string dev_id)
{
m_tabpanel->SetSelection(m_with_3dEditor? tpMonitor:(tpMonitor-1));
m_tabpanel->SetSelection(tpMonitor);
((MonitorPanel*)m_monitor)->select_machine(dev_id);
}
@ -2273,42 +2294,10 @@ void MainFrame::select_tab(size_t tab/* = size_t(-1)*/)
select(false);
}
void MainFrame::enable_tab(size_t tab, bool enabled)
{
if (tab != tp3DEditor)
//currently only support 3dEditor
return;
if ((enabled && m_with_3dEditor) || (!enabled && !m_with_3dEditor))
//already done
return;
Freeze();
if (enabled) {
int sel = m_tabpanel->GetSelection();
m_tabpanel->InsertPage(tab, m_plater, _L("Prepare"), std::string("tab_3d_active"), std::string("tab_3d_active"));
if (sel >= tab)
m_tabpanel->SetSelection(sel + 1);
}
else {
int sel = m_tabpanel->GetSelection();
m_tabpanel->RemovePage(tab);
if (sel >= tab)
m_tabpanel->SetSelection(sel - 1);
}
m_with_3dEditor = enabled;
m_plater->Show();
m_tabpanel->Show();
Thaw();
}
void MainFrame::request_select_tab(TabPosition pos)
{
int position = pos;
if ((!m_with_3dEditor)&&(pos >= tpPreview))
position = (int)pos -1;
wxCommandEvent* evt = new wxCommandEvent(EVT_SELECT_TAB);
evt->SetInt(position);
evt->SetInt(pos);
wxQueueEvent(this, evt);
}
@ -2487,6 +2476,12 @@ void MainFrame::load_url(wxString url)
wxQueueEvent(this, evt);
}
void MainFrame::refresh_plugin_tips()
{
if (m_webview != nullptr)
m_webview->ShowNetpluginTip();
}
void MainFrame::RunScript(wxString js)
{
if (m_webview != nullptr)
@ -2538,7 +2533,7 @@ void MainFrame::on_select_default_preset(SimpleEvent& evt)
{
MessageDialog dialog(this,
_L("Do you want to synchronize your personal data from Bambu Cloud? \n"
"Contains the following information:\n"
"It contains the following information:\n"
"1. The Process presets\n"
"2. The Filament presets\n"
"3. The Printer presets\n"),

View file

@ -83,7 +83,6 @@ protected:
class MainFrame : public DPIFrame
{
bool m_loaded {false};
bool m_with_3dEditor { true };
wxString m_qs_last_input_file = wxEmptyString;
wxString m_qs_last_output_file = wxEmptyString;
@ -278,7 +277,6 @@ public:
// Select tab in m_tabpanel
// When tab == -1, will be selected last selected tab
//BBS: GUI refactor
void enable_tab(size_t tab, bool enabled = true);
void select_tab(wxPanel* panel);
void select_tab(size_t tab = size_t(-1));
void request_select_tab(TabPosition pos);
@ -301,6 +299,7 @@ public:
//BBS
void load_url(wxString url);
void refresh_plugin_tips();
void RunScript(wxString js);
// BBS. Replace title bar and menu bar with top bar.

View file

@ -108,19 +108,23 @@ bool MarkdownTip::ShowTip(wxPoint pos, std::string const &tip, std::string const
return false;
if (pos.x) {
_hide = true;
BOOST_LOG_TRIVIAL(info) << "MarkdownTip::ShowTip: hide soon on empty tip.";
this->Hide();
}
else if (!_hide) {
_hide = true;
BOOST_LOG_TRIVIAL(info) << "MarkdownTip::ShowTip: start hide timer (300)...";
_timer->StartOnce(300);
}
return false;
}
if (_lastTip != tip) {
bool tipChanged = _lastTip != tip;
if (tipChanged) {
auto content = LoadTip(tip, tooltip);
if (content.empty()) {
_hide = true;
this->Hide();
BOOST_LOG_TRIVIAL(info) << "MarkdownTip::ShowTip: hide soon on empty content.";
return false;
}
auto script = "window.showMarkdown('" + url_encode(content) + "', true);";
@ -140,8 +144,11 @@ bool MarkdownTip::ShowTip(wxPoint pos, std::string const &tip, std::string const
if (pos.y + this->GetSize().y > size.y)
pos.y = size.y - this->GetSize().y;
this->SetPosition(pos);
_hide = false;
_timer->StartOnce(500);
if (tipChanged || _hide) {
_hide = false;
BOOST_LOG_TRIVIAL(info) << "MarkdownTip::ShowTip: start show timer (500)...";
_timer->StartOnce(500);
}
}
return true;
}
@ -264,11 +271,14 @@ void MarkdownTip::OnTimer(wxTimerEvent& event)
if (_hide) {
wxPoint pos = ScreenToClient(wxGetMousePosition());
if (GetClientRect().Contains(pos)) {
BOOST_LOG_TRIVIAL(info) << "MarkdownTip::OnTimer: restart hide timer...";
_timer->StartOnce();
return;
}
BOOST_LOG_TRIVIAL(info) << "MarkdownTip::OnTimer: hide.";
this->Hide();
} else {
BOOST_LOG_TRIVIAL(info) << "MarkdownTip::OnTimer: show.";
this->Show();
}
}

View file

@ -163,7 +163,7 @@ void MediaFilePanel::SetMachineObject(MachineObject* obj)
auto fs = m_image_grid->GetFileSystem();
if (fs) {
m_image_grid->SetFileSystem(nullptr);
fs->Unbind(EVT_MODE_CHANGED, &MediaFilePanel::fileChanged, this);
fs->Unbind(EVT_MODE_CHANGED, &MediaFilePanel::modeChanged, this);
fs->Stop(true);
}
if (m_machine.empty()) {
@ -171,7 +171,7 @@ void MediaFilePanel::SetMachineObject(MachineObject* obj)
} else {
boost::shared_ptr<PrinterFileSystem> fs(new PrinterFileSystem);
m_image_grid->SetFileSystem(fs);
fs->Bind(EVT_MODE_CHANGED, &MediaFilePanel::fileChanged, this);
fs->Bind(EVT_MODE_CHANGED, &MediaFilePanel::modeChanged, this);
fs->Bind(EVT_STATUS_CHANGED, [this, wfs = boost::weak_ptr(fs)](auto &e) {
boost::shared_ptr fs(wfs.lock());
if (m_image_grid->GetFileSystem() != fs) // canceled
@ -183,6 +183,7 @@ void MediaFilePanel::SetMachineObject(MachineObject* obj)
case PrinterFileSystem::Connecting: icon = m_bmp_loading.bmp(); msg = _L("Connecting..."); break;
case PrinterFileSystem::Failed: icon = m_bmp_failed.bmp(); msg = _L("Connect failed [%d]!"); break;
case PrinterFileSystem::ListSyncing: icon = m_bmp_loading.bmp(); msg = _L("Loading file list..."); break;
case PrinterFileSystem::ListReady: icon = m_bmp_empty.bmp(); msg = _L("No files"); break;
}
if (fs->GetCount() == 0)
m_image_grid->SetStatus(icon, msg);
@ -192,7 +193,7 @@ void MediaFilePanel::SetMachineObject(MachineObject* obj)
if (IsShown()) fs->Start();
}
wxCommandEvent e(EVT_MODE_CHANGED);
fileChanged(e);
modeChanged(e);
}
void MediaFilePanel::Rescale()
@ -218,12 +219,10 @@ void MediaFilePanel::Rescale()
m_image_grid->Rescale();
}
void MediaFilePanel::fileChanged(wxCommandEvent& e1)
void MediaFilePanel::modeChanged(wxCommandEvent& e1)
{
e1.Skip();
auto fs = m_image_grid->GetFileSystem();
if (fs)
m_image_grid->SetStatus(m_bmp_empty.bmp(), fs->GetCount() ? L"" : _L("No files"));
auto mode = fs ? fs->GetGroupMode() : 0;
if (m_last_mode == mode)
return;
@ -247,7 +246,7 @@ void MediaFilePanel::fetchUrl(boost::weak_ptr<PrinterFileSystem> wfs)
BOOST_LOG_TRIVIAL(info) << "MediaFilePanel::fetchUrl: camera_url: " << url;
CallAfter([this, url, wfs] {
boost::shared_ptr fs(wfs.lock());
if (fs != m_image_grid->GetFileSystem()) return;
if (!fs || fs != m_image_grid->GetFileSystem()) return;
fs->SetUrl(url);
});
});

View file

@ -38,7 +38,7 @@ public:
void Rescale();
private:
void fileChanged(wxCommandEvent & e);
void modeChanged(wxCommandEvent & e);
void fetchUrl(boost::weak_ptr<PrinterFileSystem> fs);

View file

@ -111,7 +111,7 @@ void MediaPlayCtrl::Stop()
m_media_ctrl->InvalidateBestSize();
m_button_play->SetIcon("media_play");
boost::unique_lock lock(m_mutex);
m_tasks.push_back("");
m_tasks.push_back("<stop>");
m_cond.notify_all();
}
m_last_state = MEDIASTATE_IDLE;
@ -132,6 +132,11 @@ void MediaPlayCtrl::SetStatus(wxString const& msg2)
{
auto msg = wxString::Format(msg2, m_failed_code);
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl::SetStatus: " << msg.ToUTF8().data();
#ifdef __WXMSW__
OutputDebugStringA("MediaPlayCtrl::SetStatus: ");
OutputDebugStringA(msg.ToUTF8().data());
OutputDebugStringA("\n");
#endif // __WXMSW__
m_label_status->SetLabel(msg);
//m_label_status->SetForegroundColour(!msg.EndsWith("!") ? 0x42AE00 : 0x3B65E9);
Layout();
@ -147,11 +152,17 @@ void MediaPlayCtrl::media_proc()
wxString url = m_tasks.front();
lock.unlock();
if (url.IsEmpty()) {
break;
}
else if (url == "<stop>") {
m_media_ctrl->Stop();
}
else if (url == "<exit>") {
break;
}
else if (url == "<play>") {
m_media_ctrl->Play();
}
else {
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl: start load";
m_media_ctrl->Load(wxURI(url));
@ -193,10 +204,11 @@ void MediaPlayCtrl::onStateChanged(wxMediaEvent& event)
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl::onStateChanged: size: " << size.x << "x" << size.y;
m_failed_code = m_media_ctrl->GetLastError();
if (size.GetWidth() > 1000) {
m_media_ctrl->Play();
SetStatus(_L("Playing..."));
m_failed_retry = 0;
m_last_state = m_media_ctrl->GetState();
boost::unique_lock lock(m_mutex);
m_tasks.push_back("<play>");
m_cond.notify_all();
}
else if (event.GetId()) {
Stop();

View file

@ -335,7 +335,7 @@ void MonitorPanel::on_size(wxSizeEvent &event)
// update wifi signal image
int wifi_signal_val = 0;
if (!obj->is_connected()) {
if (!obj->is_connected() || obj->is_connecting()) {
m_side_tools->set_current_printer_signal(WifiSignal::NONE);
} else {
if (!obj->wifi_signal.empty() && boost::ends_with(obj->wifi_signal, "dBm")) {
@ -381,6 +381,7 @@ void MonitorPanel::update_all()
}
if (obj) {
wxGetApp().reset_to_active();
if (obj->connection_type() != last_conn_type) {
last_conn_type = obj->connection_type();
}
@ -404,7 +405,10 @@ void MonitorPanel::update_all()
return;
}
if (!obj->is_connected()) {
if (obj->is_connecting()) {
show_status(MONITOR_CONNECTING);
return;
} else if (!obj->is_connected()) {
int server_status = 0;
// only disconnected server in cloud mode
if (obj->connection_type() != "lan") {
@ -413,7 +417,6 @@ void MonitorPanel::update_all()
}
}
show_status((int) MONITOR_DISCONNECTED + server_status);
m_status_info_panel->show_unload_ctrl();
return;
}
@ -457,15 +460,9 @@ bool MonitorPanel::Show(bool show)
obj->reset_update_time();
}
}
if (m_agent)
m_agent->start_subscribe("monitor");
}
else {
} else {
m_refresh_timer->Stop();
m_status_info_panel->m_media_play_ctrl->SetMachineObject(nullptr);
if (m_agent)
m_agent->stop_subscribe("monitor");
}
return wxPanel::Show(show);
}
@ -503,8 +500,15 @@ void MonitorPanel::show_status(int status)
else
m_connection_info->SetLabel(_L("Failed to connect to the printer"));
m_connection_info->Show();
}else if ((status & (int) MonitorStatus::MONITOR_NORMAL) != 0) {
m_connection_info->SetBackgroundColor(wxColour(255, 111, 0));
m_connection_info->SetBorderColor(wxColour(255, 111, 0));
} else if ((status & (int) MonitorStatus::MONITOR_NORMAL) != 0) {
m_connection_info->Hide();
} else if ((status & (int) MonitorStatus::MONITOR_CONNECTING) != 0) {
m_connection_info->SetLabel(_L("Connecting..."));
m_connection_info->SetBackgroundColor(wxColour(0, 174, 66));
m_connection_info->SetBorderColor(wxColour(0, 174, 66));
m_connection_info->Show();
}
Freeze();
@ -515,11 +519,14 @@ void MonitorPanel::show_status(int status)
m_status_info_panel->show_status(status);
m_tabpanel->Refresh();
m_tabpanel->Layout();
} else if (((status & (int)MonitorStatus::MONITOR_NORMAL) != 0) ||
((status & (int)MonitorStatus::MONITOR_DISCONNECTED) != 0) ||
((status & (int) MonitorStatus::MONITOR_DISCONNECTED_SERVER) != 0)
} else if (((status & (int)MonitorStatus::MONITOR_NORMAL) != 0)
|| ((status & (int)MonitorStatus::MONITOR_DISCONNECTED) != 0)
|| ((status & (int) MonitorStatus::MONITOR_DISCONNECTED_SERVER) != 0)
|| ((status & (int)MonitorStatus::MONITOR_CONNECTING) != 0)
) {
if (((status & (int) MonitorStatus::MONITOR_DISCONNECTED) != 0) || ((status & (int) MonitorStatus::MONITOR_DISCONNECTED_SERVER) != 0)) {
if (((status & (int) MonitorStatus::MONITOR_DISCONNECTED) != 0)
|| ((status & (int) MonitorStatus::MONITOR_DISCONNECTED_SERVER) != 0)
|| ((status & (int)MonitorStatus::MONITOR_CONNECTING) != 0)) {
m_side_tools->set_current_printer_signal(WifiSignal::NONE);
set_default();
}

View file

@ -390,5 +390,4 @@ void DownloadDialog::SetExtendedMessage(const wxString &extendedMessage)
Fit();
}
}
}
}} // namespace Slic3r::GUI

View file

@ -13,6 +13,8 @@
#include <wx/textctrl.h>
#include <wx/statline.h>
#include "Widgets/Button.hpp"
#include "BBLStatusBar.hpp"
#include "BBLStatusBarSend.hpp"
class wxBoxSizer;
class wxCheckBox;
@ -364,7 +366,6 @@ private:
wxString msg;
};
}
}

View file

@ -185,7 +185,8 @@ bool ButtonsListCtrl::InsertPage(size_t n, const wxString &text, bool bSelect /*
btn->Bind(wxEVT_BUTTON, [this, btn](wxCommandEvent& event) {
if (auto it = std::find(m_pageButtons.begin(), m_pageButtons.end(), btn); it != m_pageButtons.end()) {
auto sel = it - m_pageButtons.begin();
SetSelection(sel);
//do it later
//SetSelection(sel);
wxCommandEvent evt = wxCommandEvent(wxCUSTOMEVT_NOTEBOOK_SEL_CHANGED);
evt.SetId(sel);
@ -205,7 +206,11 @@ void ButtonsListCtrl::RemovePage(size_t n)
Button* btn = m_pageButtons[n];
m_pageButtons.erase(m_pageButtons.begin() + n);
m_buttons_sizer->Remove(n);
#if __WXOSX__
RemoveChild(btn);
#else
btn->Reparent(nullptr);
#endif
btn->Destroy();
m_sizer->Layout();
}

View file

@ -85,7 +85,7 @@ public:
SetSizer(mainSizer);
this->Bind(wxCUSTOMEVT_NOTEBOOK_SEL_CHANGED, [this](wxCommandEvent& evt)
{
{
if (int page_idx = evt.GetId(); page_idx >= 0)
SetSelection(page_idx);
});
@ -183,8 +183,14 @@ public:
virtual int SetSelection(size_t n) override
{
GetBtnsListCtrl()->SetSelection(n);
int ret = DoSetSelection(n, SetSelection_SendEvent);
int new_sel = GetSelection();
//check the new_sel firstly
if (new_sel != n) {
//not allowed, skip it
return ret;
}
GetBtnsListCtrl()->SetSelection(n);
// check that only the selected page is visible and others are hidden:
for (size_t page = 0; page < m_pages.size(); page++) {

View file

@ -2050,7 +2050,7 @@ size_t NotificationManager::get_notification_count() const
void NotificationManager::bbl_show_plateinfo_notification(const std::string &text)
{
NotificationData data{NotificationType::BBLPlateInfo, NotificationLevel::PrintInfoNotificationLevel, 86400 * 10, text};
NotificationData data{NotificationType::BBLPlateInfo, NotificationLevel::PrintInfoNotificationLevel, BBL_NOTICE_MAX_INTERVAL, text};
for (std::unique_ptr<PopNotification> &notification : m_pop_notifications) {
if (notification->get_type() == NotificationType::BBLPlateInfo) {
@ -2072,6 +2072,30 @@ void NotificationManager::bbl_close_plateinfo_notification()
}
}
void NotificationManager::bbl_show_preview_only_notification(const std::string &text)
{
NotificationData data{NotificationType::BBLPreviewOnlyMode, NotificationLevel::WarningNotificationLevel, 0, text};
for (std::unique_ptr<PopNotification> &notification : m_pop_notifications) {
if (notification->get_type() == NotificationType::BBLPreviewOnlyMode) {
notification->reinit();
notification->update(data);
return;
}
}
auto notification = std::make_unique<NotificationManager::PopNotification>(data, m_id_provider, m_evt_handler);
push_notification_data(std::move(notification), 0);
}
void NotificationManager::bbl_close_preview_only_notification()
{
for (std::unique_ptr<PopNotification> &notification : m_pop_notifications)
if (notification->get_type() == NotificationType::BBLPreviewOnlyMode) {
notification->close();
}
}
void NotificationManager::bbl_show_objectsinfo_notification(const std::string &text, bool is_warning, bool is_hidden)
{
std::string hyper_text;
@ -2084,7 +2108,7 @@ void NotificationManager::bbl_show_objectsinfo_notification(const std::string &t
};
hyper_text = _u8L(" (Repair)");
}
NotificationData data{NotificationType::BBLObjectInfo, NotificationLevel::PrintInfoNotificationLevel, 86400 * 10, text, hyper_text, callback};
NotificationData data{NotificationType::BBLObjectInfo, NotificationLevel::PrintInfoNotificationLevel, BBL_NOTICE_MAX_INTERVAL, text, hyper_text, callback};
if (is_warning)
data.use_warn_color = true;
@ -2113,7 +2137,7 @@ void NotificationManager::bbl_close_objectsinfo_notification()
void NotificationManager::bbl_show_seqprintinfo_notification(const std::string &text)
{
NotificationData data{NotificationType::BBLSeqPrintInfo, NotificationLevel::PrintInfoNotificationLevel, 86400 * 10, text};
NotificationData data{NotificationType::BBLSeqPrintInfo, NotificationLevel::PrintInfoNotificationLevel, BBL_NOTICE_MAX_INTERVAL, text};
for (std::unique_ptr<PopNotification> &notification : m_pop_notifications) {
if (notification->get_type() == NotificationType::BBLSeqPrintInfo) {
@ -2134,6 +2158,36 @@ void NotificationManager::bbl_close_seqprintinfo_notification()
if (notification->get_type() == NotificationType::BBLSeqPrintInfo) { notification->close(); }
}
void NotificationManager::bbl_show_plugin_install_notification(const std::string &text)
{
std::string hyper_text;
auto callback = [](wxEvtHandler *) {
wxCommandEvent *evt = new wxCommandEvent(EVT_INSTALL_PLUGIN_NETWORKING);
wxQueueEvent(wxGetApp().plater(), evt);
return false;
};
hyper_text = _u8L(" Click here to install it.");
NotificationData data{NotificationType::BBLPluginInstallHint, NotificationLevel::WarningNotificationLevel, 0, text, hyper_text, callback};
for (std::unique_ptr<PopNotification> &notification : m_pop_notifications) {
if (notification->get_type() == NotificationType::BBLPluginInstallHint) {
notification->reinit();
notification->update(data);
return;
}
}
auto notification = std::make_unique<NotificationManager::PopNotification>(data, m_id_provider, m_evt_handler);
notification->set_Multiline(true);
push_notification_data(std::move(notification), 0);
}
void NotificationManager::bbl_close_plugin_install_notification()
{
for (std::unique_ptr<PopNotification> &notification : m_pop_notifications)
if (notification->get_type() == NotificationType::BBLPluginInstallHint) { notification->close(); }
}
void NotificationManager::bbl_show_slice_emptylayer_notification(const std::string &text, bool bOverride)
{
NotificationData data{NotificationType::BBLSliceEmptyLayer, NotificationLevel::WarningNotificationLevel, 0, _u8L("WARNING:") + "\n" + text};
@ -2225,7 +2279,7 @@ void NotificationManager::bbl_show_sole_text_notification(NotificationType sType
default:
nlevel = NotificationLevel::PrintInfoNotificationLevel;
if (autohide == false) nHideTime = 86400 * 10;
if (autohide == false) nHideTime = BBL_NOTICE_MAX_INTERVAL;
break;
}

View file

@ -37,6 +37,8 @@ enum class InfoItemType;
#define BBL_NOTICE_PLATEINFO_OBJID 1024+1
#define BBL_NOTICE_OBJECTS_OBJID 1024+2
#define BBL_NOTICE_MAX_INTERVAL 86400 * 10
enum class NotificationType
{
CustomNotification,
@ -131,6 +133,9 @@ enum class NotificationType
BBLGcodeOverlap,
//BBL: sequence print info
BBLSeqPrintInfo,
//BBL: plugin install hint
BBLPluginInstallHint,
BBLPreviewOnlyMode,
};
class NotificationManager
@ -270,6 +275,14 @@ public:
void bbl_show_plateinfo_notification(const std::string &text);
void bbl_close_plateinfo_notification();
//BBS--preview only mode
void bbl_show_preview_only_notification(const std::string &text);
void bbl_close_preview_only_notification();
//BBS--PluginInstallHint
void bbl_show_plugin_install_notification(const std::string &text);
void bbl_close_plugin_install_notification();
//BBS--Objects Info
void bbl_show_objectsinfo_notification(const std::string &text, bool is_warning, bool is_hidden);
void bbl_close_objectsinfo_notification();
@ -791,7 +804,7 @@ private:
// non-static so its not loaded too early. If static, the translations wont load correctly.
const std::vector<NotificationData> basic_notifications = {
NotificationData{NotificationType::Mouse3dDisconnected, NotificationLevel::RegularNotificationLevel, 10, _u8L("3D Mouse disconnected.")},
NotificationData{NotificationType::PresetUpdateAvailable, NotificationLevel::ImportantNotificationLevel, 20, _u8L("Configuration can update now."), _u8L("Detail."),
NotificationData{NotificationType::PresetUpdateAvailable, NotificationLevel::ImportantNotificationLevel, BBL_NOTICE_MAX_INTERVAL, _u8L("Configuration can update now."), _u8L("Detail."),
[](wxEvtHandler* evnthndlr) {
if (evnthndlr != nullptr)
wxPostEvent(evnthndlr, PresetUpdateAvailableClickedEvent(EVT_PRESET_UPDATE_AVAILABLE_CLICKED));

View file

@ -123,35 +123,6 @@ int OG_CustomCtrl::get_height(const Line& line)
return 0;
}
static wxSize split_lines(wxDC &dc, int width, const wxString &text, wxString &multiline_text)
{
if (width > 0 && dc.GetTextExtent(text).x > width) {
multiline_text = text;
size_t start = 0;
while (true) {
size_t idx = size_t(-1);
for (size_t i = start; i < multiline_text.Len(); i++) {
if (multiline_text[i] == ' ') {
if (dc.GetTextExtent(multiline_text.SubString(start, i)).x < width)
idx = i;
else {
if (idx == size_t(-1))
idx = i;
break;
}
}
}
if (idx == size_t(-1))
break;
multiline_text[idx] = '\n';
start = idx + 1;
if (dc.GetTextExtent(multiline_text.Mid(start)).x < width)
break;
}
}
return dc.GetMultiLineTextExtent(multiline_text.IsEmpty() ? text : multiline_text);
}
wxPoint OG_CustomCtrl::get_pos(const Line& line, Field* field_in/* = nullptr*/)
{
// BBS: new layout
@ -178,7 +149,7 @@ wxPoint OG_CustomCtrl::get_pos(const Line& line, Field* field_in/* = nullptr*/)
wxClientDC dc(this);
dc.SetFont(m_font);
wxString multiline_text;
auto size = split_lines(dc, label_width, label, multiline_text);
auto size = Label::split_lines(dc, label_width, label, multiline_text);
if (label_width > 0) size.x = label_width;
h_pos += size.x + m_h_gap;
if (ctrl_line.height < size.y)
@ -915,7 +886,7 @@ void OG_CustomCtrl::CtrlLine::render(wxDC& dc, wxCoord h_pos, wxCoord v_pos)
wxCoord OG_CustomCtrl::CtrlLine::draw_text(wxDC& dc, wxPoint pos, const wxString& text, const wxColour* color, int width, bool is_main/* = false*/)
{
wxString multiline_text;
auto size = split_lines(dc, width, text, multiline_text);
auto size = Label::split_lines(dc, width, text, multiline_text);
if (!text.IsEmpty()) {
const wxString& out_text = multiline_text.IsEmpty() ? text : multiline_text;

View file

@ -1938,9 +1938,13 @@ wxDataViewItem ObjectDataViewModel::GetObjectItem(const ModelObject* mo) const
wxDataViewItem ObjectDataViewModel::GetVolumeItem(const wxDataViewItem& parent, int vol_idx) const
{
ObjectDataViewModelNode* obj_node = (ObjectDataViewModelNode*)parent.GetID();
for (auto child : obj_node->GetChildren()) {
if (child->GetType() == itVolume && child->GetIdx() == vol_idx)
return wxDataViewItem(child);
// BBS
if (obj_node != nullptr) {
for (auto child : obj_node->GetChildren()) {
if (child->GetType() == itVolume && child->GetIdx() == vol_idx)
return wxDataViewItem(child);
}
}
return wxDataViewItem(nullptr);

View file

@ -21,7 +21,7 @@
namespace Slic3r {
namespace GUI {
TipsDialog::TipsDialog(wxWindow *parent, const wxString &title)
: DPIDialog(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX)
{
@ -230,16 +230,17 @@ ParamsPanel::ParamsPanel( wxWindow* parent, wxWindowID id, const wxPoint& pos, c
//m_search_btn = new ScalableButton(m_top_panel, wxID_ANY, "search", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, true);
//m_search_btn->SetToolTip(format_wxstr(_L("Search in settings [%1%]"), "Ctrl+F"));
//m_search_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { wxGetApp().plater()->search(false); });
#if !BBL_RELEASE_TO_PUBLIC
m_compare_btn = new ScalableButton(m_top_panel, wxID_ANY, "compare", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, true);
m_compare_btn->SetToolTip(_L("Compare presets"));
m_compare_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { wxGetApp().mainframe->diff_dialog.show(); }));
#endif
#if !BBL_RELEASE_TO_PUBLIC
m_setting_btn = new ScalableButton(m_top_panel, wxID_ANY, "table", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, true);
m_setting_btn->SetToolTip(_L("View all object's settings"));
m_setting_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { wxGetApp().plater()->PopupObjectTable(-1, -1, {0, 0}); });
#endif
m_highlighter.set_timer_owner(this, 0);
m_highlighter.set_timer_owner(this, 0);
this->Bind(wxEVT_TIMER, [this](wxTimerEvent &)
{
m_highlighter.blink();
@ -332,12 +333,13 @@ void ParamsPanel::create_layout()
m_mode_sizer->Add( m_title_view, 0, wxALIGN_CENTER );
m_mode_sizer->AddSpacer(FromDIP(9));
m_mode_sizer->Add( m_mode_view, 0, wxALIGN_CENTER );
m_mode_sizer->AddSpacer(FromDIP(16));
m_mode_sizer->Add( m_setting_btn, 0, wxALIGN_CENTER );
#if !BBL_RELEASE_TO_PUBLIC
m_mode_sizer->AddSpacer(FromDIP(16));
m_mode_sizer->Add( m_compare_btn, 0, wxALIGN_CENTER );
m_mode_sizer->Add( m_setting_btn, 0, wxALIGN_CENTER );
#endif
m_mode_sizer->AddSpacer(FromDIP(16));
m_mode_sizer->Add( m_compare_btn, 0, wxALIGN_CENTER );
m_mode_sizer->AddSpacer(FromDIP(8));
//m_mode_sizer->Add( m_search_btn, 0, wxALIGN_CENTER );
//m_mode_sizer->AddSpacer(16);
@ -590,7 +592,9 @@ void ParamsPanel::update_mode()
void ParamsPanel::msw_rescale()
{
if (m_process_icon) m_process_icon->msw_rescale();
#if !BBL_RELEASE_TO_PUBLIC
if (m_setting_btn) m_setting_btn->msw_rescale();
#endif
if (m_search_btn) m_search_btn->msw_rescale();
if (m_compare_btn) m_compare_btn->msw_rescale();
m_left_sizer->SetMinSize(wxSize(40 * em_unit(this), -1));

View file

@ -1017,6 +1017,15 @@ void PartPlate::release_opengl_resource()
std::vector<int> PartPlate::get_extruders() const
{
std::vector<int> plate_extruders;
// if gcode.3mf file
if (m_model->objects.empty()) {
for (int i = 0; i < slice_filaments_info.size(); i++) {
plate_extruders.push_back(slice_filaments_info[i].id + 1);
}
return plate_extruders;
}
// if 3mf file
const DynamicPrintConfig& glb_config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
int glb_support_intf_extr = glb_config.opt_int("support_interface_filament");
int glb_support_extr = glb_config.opt_int("support_filament");
@ -1626,6 +1635,33 @@ void PartPlate::move_instances_to(PartPlate& left_plate, PartPlate& right_plate,
return;
}
//can add timelapse object
bool PartPlate::can_add_timelapse_object()
{
bool result = true;
if (obj_to_instance_set.size() == 0)
return false;
for (std::set<std::pair<int, int>>::iterator it = obj_to_instance_set.begin(); it != obj_to_instance_set.end(); ++it)
{
int obj_id = it->first;
if (obj_id >= m_model->objects.size())
continue;
ModelObject* object = m_model->objects[obj_id];
if (object->is_timelapse_wipe_tower)
{
result = false;
break;
}
}
return result;
}
void PartPlate::generate_logo_polygon(ExPolygon &logo_polygon)
{
if (m_shape.size() == 4)
@ -2109,9 +2145,9 @@ int PartPlate::load_pattern_thumbnail_data(std::string filename)
if (result) {
cali_thumbnail_data.set(img.GetWidth(), img.GetHeight());
for (int i = 0; i < img.GetWidth() * img.GetHeight(); i++) {
memcpy(&thumbnail_data.pixels[4 * i], (unsigned char*)(img.GetData() + 3 * i), 3);
memcpy(&cali_thumbnail_data.pixels[4 * i], (unsigned char*)(img.GetData() + 3 * i), 3);
if (img.HasAlpha()) {
thumbnail_data.pixels[4 * i + 3] = *(unsigned char*)(img.GetAlpha() + i);
cali_thumbnail_data.pixels[4 * i + 3] = *(unsigned char*)(img.GetAlpha() + i);
}
}
}
@ -2121,6 +2157,24 @@ int PartPlate::load_pattern_thumbnail_data(std::string filename)
return 0;
}
//load pattern box data from file
int PartPlate::load_pattern_box_data(std::string filename)
{
try {
nlohmann::json j;
boost::nowide::ifstream ifs(filename);
ifs >> j;
PlateBBoxData bbox_data;
bbox_data.from_json(j);
cali_bboxes_data = bbox_data;
return 0;
}
catch(std::exception &ex) {
BOOST_LOG_TRIVIAL(trace) << boost::format("catch an exception %1%")%ex.what();
return -1;
}
}
void PartPlate::print() const
{
@ -4009,6 +4063,11 @@ int PartPlateList::store_to_3mf_structure(PlateDataPtrs& plate_data_list, bool w
if (m_plate_list[i]->get_slice_result() && m_plate_list[i]->is_slice_result_valid()) {
// BBS only include current palte_idx
if (plate_idx == i || plate_idx == -1) {
//load calibration thumbnail
if (m_plate_list[i]->cali_thumbnail_data.is_valid())
plate_data_item->pattern_file = "valid_pattern";
if (m_plate_list[i]->cali_bboxes_data.is_valid())
plate_data_item->pattern_bbox_file = "valid_pattern_bbox";
plate_data_item->gcode_file = m_plate_list[i]->m_gcode_result->filename;
plate_data_item->is_sliced_valid = true;
plate_data_item->gcode_prediction = std::to_string(
@ -4018,7 +4077,10 @@ int PartPlateList::store_to_3mf_structure(PlateDataPtrs& plate_data_list, bool w
m_plate_list[i]->get_print((PrintBase **) &print, nullptr, nullptr);
if (print) {
const PrintStatistics &ps = print->print_statistics();
if (ps.total_weight != 0.0) { plate_data_item->gcode_weight = wxString::Format("%.2f", ps.total_weight).ToStdString(); }
if (ps.total_weight != 0.0) {
CNumericLocalesSetter locales_setter;
plate_data_item->gcode_weight =wxString::Format("%.2f", ps.total_weight).ToStdString();
}
} else {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("print is null!");
}
@ -4072,21 +4134,29 @@ int PartPlateList::load_from_3mf_structure(PlateDataPtrs& plate_data_list)
gcode_result->print_statistics.modes[static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Normal)].time = atoi(plate_data_list[i]->gcode_prediction.c_str());
ps.total_weight = atof(plate_data_list[i]->gcode_weight.c_str());
ps.total_used_filament = 0.f;
for (auto filament_item: plate_data_list[i]->slice_flaments_info)
for (auto filament_item: plate_data_list[i]->slice_filaments_info)
{
ps.total_used_filament += filament_item.used_m;
}
ps.total_used_filament *= 1000; //koef
gcode_result->toolpath_outside = plate_data_list[i]->toolpath_outside;
m_plate_list[index]->slice_filaments_info = plate_data_list[i]->slice_filaments_info;
if (!plate_data_list[i]->thumbnail_file.empty()) {
if (boost::filesystem::exists(plate_data_list[i]->thumbnail_file)) {
m_plate_list[index]->load_thumbnail_data(plate_data_list[i]->thumbnail_file);
}
}
if (!plate_data_list[i]->pattern_file.empty()) {
if (boost::filesystem::exists(plate_data_list[i]->pattern_file)) {
m_plate_list[index]->load_pattern_thumbnail_data(plate_data_list[i]->pattern_file);
//no need to load pattern data currently
//m_plate_list[index]->load_pattern_thumbnail_data(plate_data_list[i]->pattern_file);
}
}
if (!plate_data_list[i]->pattern_bbox_file.empty()) {
if (boost::filesystem::exists(plate_data_list[i]->pattern_bbox_file)) {
m_plate_list[index]->load_pattern_box_data(plate_data_list[i]->pattern_bbox_file);
}
}

View file

@ -96,6 +96,7 @@ private:
Print *m_print; //Print reference, not own it, no need to serialize
GCodeProcessorResult *m_gcode_result;
std::vector<FilamentInfo> slice_filaments_info;
int m_print_index;
std::string m_tmp_gcode_path; //use a temp path to store the gcode
@ -207,6 +208,7 @@ public:
static const int plate_thumbnail_height = 512;
ThumbnailData cali_thumbnail_data;
PlateBBoxData cali_bboxes_data;
//set the plate's index
void set_index(int index);
@ -277,6 +279,9 @@ public:
//move instances to left or right PartPlate
void move_instances_to(PartPlate& left_plate, PartPlate& right_plate, BoundingBoxf3* bounding_box = nullptr);
//can add timelapse object
bool can_add_timelapse_object();
/*rendering related functions*/
const Pointfs& get_shape() const { return m_shape; }
bool set_shape(const Pointfs& shape, const Pointfs& exclude_areas, Vec2d position, float height_to_lid, float height_to_rod);
@ -361,6 +366,8 @@ public:
int load_thumbnail_data(std::string filename);
//load pattern thumbnail data from file
int load_pattern_thumbnail_data(std::string filename);
//load pattern box data from file
int load_pattern_box_data(std::string filename);
void print() const;

View file

@ -152,6 +152,9 @@ wxDEFINE_EVENT(EVT_PRINT_FINISHED, wxCommandEvent);
//BBS: repair model
wxDEFINE_EVENT(EVT_REPAIR_MODEL, wxCommandEvent);
wxDEFINE_EVENT(EVT_FILAMENT_COLOR_CHANGED, wxCommandEvent);
wxDEFINE_EVENT(EVT_INSTALL_PLUGIN_NETWORKING, wxCommandEvent);
wxDEFINE_EVENT(EVT_INSTALL_PLUGIN_HINT, wxCommandEvent);
wxDEFINE_EVENT(EVT_PREVIEW_ONLY_MODE_HINT, wxCommandEvent);
@ -301,7 +304,6 @@ struct Sidebar::priv
wxPanel* m_panel_printer_content = nullptr;
ObjectList *m_object_list{ nullptr };
wxPanel *m_object_panel;
AuxiliaryDialog *m_auxiliary_dialog{ nullptr };
ObjectSettings *object_settings{ nullptr };
@ -335,10 +337,6 @@ Sidebar::priv::~priv()
#if 0
delete frequently_changed_parameters;
#endif
// BBS
if (m_object_panel != nullptr)
delete m_object_panel;
}
void Sidebar::priv::show_preset_comboboxes()
@ -415,6 +413,8 @@ Sidebar::Sidebar(Plater *parent)
// As a result we can see the empty block at the bottom of the sidebar
// But if we set this value to 5, layout will be better
p->scrolled->SetScrollRate(0, 5);
p->scrolled->SetBackgroundColour(*wxWHITE);
SetFont(wxGetApp().normal_font());
#ifndef __APPLE__
@ -437,11 +437,8 @@ Sidebar::Sidebar(Plater *parent)
wxColour active_text = wxColour(0, 0, 0);
wxColour static_line_col = wxColour(166, 169, 170);
bool is_msw = false;
#ifdef __WINDOWS__
p->scrolled->SetDoubleBuffered(true);
is_msw = true;
#endif //__WINDOWS__
// add printer
@ -450,12 +447,13 @@ Sidebar::Sidebar(Plater *parent)
// 1.1 create title bar resources
p->m_panel_printer_title = new StaticBox(p->scrolled, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL | wxBORDER_NONE);
p->m_panel_printer_title->SetBackgroundColor(title_bg);
p->m_panel_printer_title->SetBackgroundColor(0xF1F1F1);
p->m_panel_printer_title->SetBackgroundColor2(0xF1F1F1);
p->m_printer_icon = new ScalableButton(p->m_panel_printer_title, wxID_ANY, "printer");
p->m_text_printer_settings = new wxStaticText(p->m_panel_printer_title, wxID_ANY, _L("Printer"), wxDefaultPosition, wxDefaultSize, 0);
p->m_text_printer_settings->Wrap(-1);
p->m_text_printer_settings->SetFont(Label::Body_14);
p->m_text_printer_settings->SetBackgroundColour(0xF1F1F1);
p->m_printer_setting = new ScalableButton(p->m_panel_printer_title, wxID_ANY, "settings");
p->m_printer_setting->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) {
@ -521,7 +519,6 @@ Sidebar::Sidebar(Plater *parent)
bed_type_title->Wrap(-1);
bed_type_title->SetFont(Label::Body_14);
m_bed_type_list = new ComboBox(p->m_panel_printer_content, wxID_ANY, wxString(""), wxDefaultPosition, {-1, FromDIP(30)}, 0, nullptr, wxCB_READONLY);
DynamicPrintConfig& config = wxGetApp().preset_bundle->project_config;
const ConfigOptionDef* bed_type_def = print_config_def.get("curr_bed_type");
if (bed_type_def && bed_type_def->enum_keys_map) {
for (auto item : *bed_type_def->enum_keys_map)
@ -542,7 +539,7 @@ Sidebar::Sidebar(Plater *parent)
// add filament title
p->m_panel_filament_title = new StaticBox(p->scrolled, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL | wxBORDER_NONE);
p->m_panel_filament_title->SetBackgroundColor(title_bg);
p->m_panel_filament_title->SetBackgroundColor(0xF1F1F1);
p->m_panel_filament_title->SetBackgroundColor2(0xF1F1F1);
wxBoxSizer* bSizer39;
bSizer39 = new wxBoxSizer( wxHORIZONTAL );
@ -550,6 +547,7 @@ Sidebar::Sidebar(Plater *parent)
p->m_staticText_filament_settings = new wxStaticText( p->m_panel_filament_title, wxID_ANY, _L("Filament"), wxDefaultPosition, wxDefaultSize, 0 );
p->m_staticText_filament_settings->Wrap( -1 );
p->m_staticText_filament_settings->SetFont(Label::Body_14);
p->m_staticText_filament_settings->SetBackgroundColour(0xF1F1F1);
bSizer39->Add(p->m_filament_icon, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, FromDIP(10));
bSizer39->Add( p->m_staticText_filament_settings, 0, wxALIGN_CENTER );
bSizer39->Add(FromDIP(10), 0, 0, 0, 0);
@ -577,16 +575,23 @@ Sidebar::Sidebar(Plater *parent)
auto& printer_config = wxGetApp().preset_bundle->printers.get_edited_preset().config;
const std::vector<double>& init_matrix = (project_config.option<ConfigOptionFloats>("flush_volumes_matrix"))->values;
const std::vector<double>& init_extruders = (project_config.option<ConfigOptionFloats>("flush_volumes_vector"))->values;
ConfigOption* extra_flush_volume_opt = printer_config.option("nozzle_volume");
int extra_flush_volume = extra_flush_volume_opt ? (int)extra_flush_volume_opt->getFloat() : 0;
ConfigOption* flush_multi_opt = project_config.option("flush_multiplier");
float flush_multiplier = flush_multi_opt ? flush_multi_opt->getFloat() : 1.f;
const std::vector<std::string> extruder_colours = wxGetApp().plater()->get_extruder_colors_from_plater_config();
WipingDialog dlg(parent, cast<float>(init_matrix), cast<float>(init_extruders), extruder_colours);
WipingDialog dlg(parent, cast<float>(init_matrix), cast<float>(init_extruders), extruder_colours, extra_flush_volume, flush_multiplier);
if (dlg.ShowModal() == wxID_OK) {
std::vector<float> matrix = dlg.get_matrix();
std::vector<float> extruders = dlg.get_extruders();
(project_config.option<ConfigOptionFloats>("flush_volumes_matrix"))->values = std::vector<double>(matrix.begin(), matrix.end());
(project_config.option<ConfigOptionFloats>("flush_volumes_vector"))->values = std::vector<double>(extruders.begin(), extruders.end());
#if !BBL_RELEASE_TO_PUBLIC
(project_config.option<ConfigOptionFloat>("flush_multiplier"))->set(new ConfigOptionFloat(dlg.get_flush_multiplier()));
#endif
wxGetApp().plater()->update_project_dirty_from_presets();
wxPostEvent(parent, SimpleEvent(EVT_SCHEDULE_BACKGROUND_PROCESS, parent));
@ -599,8 +604,8 @@ Sidebar::Sidebar(Plater *parent)
ScalableButton* add_btn = new ScalableButton(p->m_panel_filament_title, wxID_ANY, "add_filament");
add_btn->Bind(wxEVT_BUTTON, [this, scrolled_sizer](wxCommandEvent& e){
// BBS: limit filament choices to 4
if (p->combos_filament.size() >= 4)
// BBS: limit filament choices to 16
if (p->combos_filament.size() >= 16)
return;
int filament_count = p->combos_filament.size() + 1;
@ -717,14 +722,10 @@ Sidebar::Sidebar(Plater *parent)
//add project content
p->sizer_params = new wxBoxSizer(wxVERTICAL);
p->m_object_panel = new wxPanel(p->scrolled);
p->m_object_list = new ObjectList(p->m_object_panel);
wxBoxSizer* object_sizer = new wxBoxSizer(wxVERTICAL);
object_sizer->Add(p->m_object_list, 1, wxEXPAND);
p->m_object_panel->SetSizer(object_sizer);
p->sizer_params->Add(p->m_object_panel, 1, wxEXPAND | wxTOP, 0);
p->m_object_list = new ObjectList(p->scrolled);
p->sizer_params->Add(p->m_object_list, 1, wxEXPAND | wxTOP, 0);
scrolled_sizer->Add(p->sizer_params, 3, wxEXPAND | wxLEFT, 0);
p->m_object_panel->Hide();
p->m_object_list->Hide();
p->m_auxiliary_dialog = new AuxiliaryDialog(this);
@ -1329,7 +1330,7 @@ void Sidebar::update_ui_from_settings()
bool Sidebar::show_object_list(bool show) const
{
if (!p->m_object_panel->Show(show))
if (!p->m_object_list->Show(show))
return false;
p->scrolled->Layout();
return true;
@ -1770,6 +1771,9 @@ struct Plater::priv
//BBS: add model repair
void on_repair_model(wxCommandEvent &event);
void on_filament_color_changed(wxCommandEvent &event);
void show_install_plugin_hint(wxCommandEvent &event);
void install_network_plugin(wxCommandEvent &event);
void show_preview_only_hint(wxCommandEvent &event);
//BBS: add part plate related logic
void on_plate_right_click(RBtnPlateEvent&);
void on_plate_selected(SimpleEvent&);
@ -1801,6 +1805,7 @@ struct Plater::priv
// Sets m_bed.m_polygon to limit the object placement.
//BBS: add bed exclude area
void set_bed_shape(const Pointfs& shape, const Pointfs& exclude_areas, const double printable_height, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom = false);
bool can_add_timelapse_wt() const;
bool can_delete() const;
bool can_delete_all() const;
@ -1963,6 +1968,9 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
this->q->Bind(EVT_PUBLISH, &priv::on_action_publish, this);
this->q->Bind(EVT_REPAIR_MODEL, &priv::on_repair_model, this);
this->q->Bind(EVT_FILAMENT_COLOR_CHANGED, &priv::on_filament_color_changed, this);
this->q->Bind(EVT_INSTALL_PLUGIN_NETWORKING, &priv::install_network_plugin, this);
this->q->Bind(EVT_INSTALL_PLUGIN_HINT, &priv::show_install_plugin_hint, this);
this->q->Bind(EVT_PREVIEW_ONLY_MODE_HINT, &priv::show_preview_only_hint, this);
view3D = new View3D(q, bed, &model, config, &background_process);
//BBS: use partplater's gcode
@ -2987,6 +2995,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
tolal_model_count += model_idx;
if (one_by_one) {
// BBS: add load_old_project logic
if (type_3mf && !is_project_file && !load_old_project)
@ -3061,8 +3070,6 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
//set to 3d tab
q->select_view_3D("Preview");
wxGetApp().mainframe->select_tab(MainFrame::tpPreview);
wxTheApp->CallAfter([]() { wxGetApp().mainframe->enable_tab(MainFrame::tp3DEditor, false);});
notification_manager->bbl_show_plateinfo_notification(into_u8(_L("Preview only mode:\nThe loaded file contains gcode only.")));
}
else {
//set to 3d tab
@ -3112,7 +3119,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
obj_idxs, model.objects, *notification_manager);
if (tolal_model_count <= 0) {
if (tolal_model_count <= 0 && !q->m_exported_file) {
dlg.Hide();
MessageDialog msg(wxGetApp().mainframe, _L("The file does not contain any geometry data."), _L("Warning"), wxYES | wxICON_WARNING);
if (msg.ShowModal() == wxID_YES) {}
@ -4865,6 +4872,7 @@ void Plater::priv::on_export_began(wxCommandEvent& evt)
void Plater::priv::on_export_finished(wxCommandEvent& evt)
{
#if 0
//BBS: also export 3mf to the same directory for debugging
std::string gcode_path_str(evt.GetString().ToUTF8().data());
fs::path gcode_path(gcode_path_str);
@ -4872,6 +4880,7 @@ void Plater::priv::on_export_finished(wxCommandEvent& evt)
if (q) {
q->export_3mf(gcode_path.replace_extension(".3mf"), SaveStrategy::Silence); // BBS: silence
}
#endif
}
void Plater::priv::on_slicing_began()
@ -5329,6 +5338,22 @@ void Plater::priv::on_filament_color_changed(wxCommandEvent &event)
q->get_preview_canvas3D()->update_plate_thumbnails();
}
void Plater::priv::install_network_plugin(wxCommandEvent &event)
{
wxGetApp().ShowDownNetPluginDlg();
return;
}
void Plater::priv::show_install_plugin_hint(wxCommandEvent &event)
{
notification_manager->bbl_show_plugin_install_notification(into_u8(_L("Network Plug-in is not detected. Network related features are unavailable.")));
}
void Plater::priv::show_preview_only_hint(wxCommandEvent &event)
{
notification_manager->bbl_show_preview_only_notification(into_u8(_L("Preview only mode:\nThe loaded file contains gcode only, Can not enter the Prepare page")));
}
void Plater::priv::on_right_click(RBtnEvent& evt)
{
int obj_idx = get_selected_object_idx();
@ -5871,6 +5896,16 @@ void Plater::priv::set_bed_shape(const Pointfs& shape, const Pointfs& exclude_ar
}
}
bool Plater::priv::can_add_timelapse_wt() const {
const DynamicPrintConfig &dconfig = wxGetApp().preset_bundle->prints.get_edited_preset().config;
const ConfigOption* option = dconfig.option("timelapse_no_toolhead");
bool timelapse_enabled = option?option->getBool():false;
PartPlate* curr_plate = q->get_partplate_list().get_curr_plate();
return timelapse_enabled && curr_plate->can_add_timelapse_object();
}
bool Plater::priv::can_delete() const
{
return !get_selection().is_empty() && !get_selection().is_wipe_tower();
@ -6387,8 +6422,8 @@ int Plater::new_project(bool skip_confirm, bool silent)
m_only_gcode = false;
m_exported_file = false;
wxGetApp().mainframe->enable_tab(MainFrame::tp3DEditor);
get_notification_manager()->bbl_close_plateinfo_notification();
get_notification_manager()->bbl_close_preview_only_notification();
if (!silent)
wxGetApp().mainframe->select_tab(MainFrame::tp3DEditor);
@ -6455,10 +6490,8 @@ void Plater::load_project(wxString const& filename2,
m_only_gcode = false;
m_exported_file = false;
wxGetApp().mainframe->enable_tab(MainFrame::tp3DEditor);
get_notification_manager()->bbl_close_plateinfo_notification();
wxGetApp().mainframe->select_tab(MainFrame::tp3DEditor);
get_notification_manager()->bbl_close_preview_only_notification();
auto path = into_path(filename);
@ -6494,7 +6527,9 @@ void Plater::load_project(wxString const& filename2,
if (!m_exported_file) {
p->select_view("topfront");
p->camera.requires_zoom_to_plate = REQUIRES_ZOOM_TO_ALL_PLATE;
wxGetApp().mainframe->select_tab(MainFrame::tp3DEditor);
}
if (previous_gcode)
collapse_sidebar(false);
@ -6663,8 +6698,7 @@ void Plater::load_gcode(const wxString& filename)
wxGetApp().mainframe->select_tab(MainFrame::tpPreview);
p->set_current_panel(p->preview, true);
p->get_current_canvas3D()->render();
wxTheApp->CallAfter([]() { wxGetApp().mainframe->enable_tab(MainFrame::tp3DEditor, false);});
p->notification_manager->bbl_show_plateinfo_notification(into_u8(_L("Preview only mode for gcode file.")));
//p->notification_manager->bbl_show_plateinfo_notification(into_u8(_L("Preview only mode for gcode file.")));
current_print.apply(this->model(), wxGetApp().preset_bundle->full_config());
@ -8083,8 +8117,10 @@ int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy
}
thumbnails.push_back(thumbnail_data);
calibration_thumbnails.push_back(new ThumbnailData());
plate_bboxes.push_back(new PlateBBoxData());
ThumbnailData* calibration_data = &p->partplate_list.get_plate(i)->cali_thumbnail_data;
calibration_thumbnails.push_back(calibration_data);
PlateBBoxData* plate_bbox_data = &p->partplate_list.get_plate(i)->cali_bboxes_data;
plate_bboxes.push_back(plate_bbox_data);
}
if (p->partplate_list.get_curr_plate()->is_slice_result_valid()) {
@ -8096,7 +8132,11 @@ int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy
const int thumbnail_width = 2560;
const int thumbnail_height = 2560;
p->generate_calibration_thumbnail(*calibration_data, thumbnail_width, thumbnail_height, calibration_params);
*plate_bboxes[index] = p->generate_first_layer_bbox();
if (using_exported_file()) {
//do nothing
}
else
*plate_bboxes[index] = p->generate_first_layer_bbox();
}
}
@ -8128,7 +8168,7 @@ int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy
for (int i = 0; i < plate_data_list.size(); i++) {
PlateData *plate_data = plate_data_list[i];
for (auto it = plate_data->slice_flaments_info.begin(); it != plate_data->slice_flaments_info.end(); it++) {
for (auto it = plate_data->slice_filaments_info.begin(); it != plate_data->slice_filaments_info.end(); it++) {
it->type = cfg.get_filament_type(it->id);
it->color = filament_color ? filament_color->get_at(it->id) : "#FFFFFF";
// save filament info used in curr plate
@ -8192,11 +8232,10 @@ int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy
for (unsigned int i = 0; i < calibration_thumbnails.size(); i++)
{
delete calibration_thumbnails[i];
//release the data here, as it will always be generated when export
calibration_thumbnails[i]->reset();
}
for (int i = 0; i < plate_bboxes.size(); i++)
delete plate_bboxes[i];
thumbnails.clear();
return 0;
}
@ -8428,7 +8467,7 @@ int Plater::send_gcode(int plate_idx, Export3mfProgressFn proFn)
#if !BBL_RELEASE_TO_PUBLIC
//only save model in QA environment
std::string sel = get_app_config()->get("iot_environment");
if (sel == ENV_QAT_HOST)
if (sel == ENV_PRE_HOST)
strategy = SaveStrategy::Silence | SaveStrategy::SplitModel | SaveStrategy::WithGcode;
#endif
@ -9764,6 +9803,7 @@ void Plater::show_status_message(std::string s)
BOOST_LOG_TRIVIAL(trace) << "show_status_message:" << s;
}
bool Plater::can_add_timelapse_wt() const { return p->can_add_timelapse_wt(); } // BBS
bool Plater::can_delete() const { return p->can_delete(); }
bool Plater::can_delete_all() const { return p->can_delete_all(); }
bool Plater::can_add_model() const { return !is_background_process_slicing(); }

View file

@ -82,6 +82,9 @@ wxDECLARE_EVENT(EVT_SLICING_UPDATE, Slic3r::SlicingStatusEvent);
wxDECLARE_EVENT(EVT_PUBLISH, wxCommandEvent);
wxDECLARE_EVENT(EVT_REPAIR_MODEL, wxCommandEvent);
wxDECLARE_EVENT(EVT_FILAMENT_COLOR_CHANGED, wxCommandEvent);
wxDECLARE_EVENT(EVT_INSTALL_PLUGIN_NETWORKING, wxCommandEvent);
wxDECLARE_EVENT(EVT_INSTALL_PLUGIN_HINT, wxCommandEvent);
wxDECLARE_EVENT(EVT_PREVIEW_ONLY_MODE_HINT, wxCommandEvent);
const wxString DEFAULT_PROJECT_NAME = "Untitled";
@ -418,6 +421,7 @@ public:
//BBS:
void fill_color(int extruder_id);
bool can_add_timelapse_wt() const;
bool can_delete() const;
bool can_delete_all() const;

View file

@ -33,7 +33,7 @@ wxBoxSizer *PreferencesDialog::create_item_title(wxString title, wxWindow *paren
m_title->SetForegroundColour(DESIGN_GRAY800_COLOR);
m_title->SetFont(::Label::Head_13);
m_title->Wrap(-1);
m_title->SetToolTip(tooltip);
//m_title->SetToolTip(tooltip);
auto m_line = new wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL);
m_line->SetBackgroundColour(DESIGN_GRAY400_COLOR);
@ -244,12 +244,12 @@ wxBoxSizer *PreferencesDialog::create_item_region_combobox(wxString title, wxWin
return;
} else {
NetworkAgent *agent = wxGetApp().getAgent();
wxGetApp().request_user_logout();
AppConfig * config = GUI::wxGetApp().app_config;
if (agent) {
agent->set_country_code(area);
config->set("region", region.ToStdString());
}
wxGetApp().request_user_logout();
config->set("region", region.ToStdString());
EndModal(wxID_CANCEL);
}
@ -472,7 +472,7 @@ wxBoxSizer *PreferencesDialog::create_item_checkbox(wxString title, wxWindow *pa
if (param == "sync_user_preset") {
bool sync = app_config->get("sync_user_preset") == "true" ? true : false;
if (sync) {
wxGetApp().start_sync_user_preset();
wxGetApp().start_sync_user_preset(true);
} else {
wxGetApp().stop_sync_user_preset();
}
@ -870,7 +870,7 @@ wxBoxSizer* PreferencesDialog::create_debug_page()
wxGetApp().request_user_logout();
agent->set_country_code(country_code);
}
wxMessageBox(_L("Swith cloud environment, Please login again!"));
wxMessageBox(_L("Switch cloud environment, Please login again!"));
}
// bbs backup

View file

@ -233,6 +233,9 @@ int PresetComboBox::update_ams_color()
new_cfg.set_key_value("filament_colour", colors);
cfg->apply(new_cfg);
wxGetApp().plater()->on_config_change(new_cfg);
//trigger the filament color changed
wxCommandEvent *evt = new wxCommandEvent(EVT_FILAMENT_COLOR_CHANGED);
wxQueueEvent(wxGetApp().plater(), evt);
return idx;
}
@ -381,7 +384,7 @@ void PresetComboBox::add_ams_filaments(std::string selected, bool alias_name)
for (auto &f : m_preset_bundle->filament_ams_list) {
std::string setting_id = f.opt_string("filament_settings_id", 0u);
auto iter = std::find_if(filaments.begin(), filaments.end(),
[&setting_id](auto &f) { return f.is_compatible && f.filament_id == setting_id; });
[&setting_id](auto &f) { return f.is_compatible && f.is_system && f.filament_id == setting_id; });
if (iter == filaments.end())
continue;
const_cast<Preset&>(*iter).is_visible = true;

View file

@ -1,6 +1,8 @@
#include "PrinterFileSystem.h"
#include "libslic3r/Utils.hpp"
#include "../../Utils/NetworkAgent.hpp"
#include <boost/algorithm/hex.hpp>
#include <boost/uuid/detail/md5.hpp>
@ -39,8 +41,7 @@ PrinterFileSystem::PrinterFileSystem()
}
PrinterFileSystem::~PrinterFileSystem()
{
}
{ m_recv_thread.detach(); }
void PrinterFileSystem::SetFileType(FileType type)
{
@ -50,6 +51,8 @@ void PrinterFileSystem::SetFileType(FileType type)
m_file_list.swap(m_file_list2);
m_lock_start = m_lock_end = 0;
SendChangedEvent(EVT_FILE_CHANGED);
m_status = Status::ListSyncing;
SendChangedEvent(EVT_STATUS_CHANGED, m_status);
ListAllFiles();
}
@ -110,6 +113,7 @@ void PrinterFileSystem::ListAllFiles()
}
BuildGroups();
m_status = Status::ListReady;
SendChangedEvent(EVT_STATUS_CHANGED, m_status);
SendChangedEvent(EVT_FILE_CHANGED);
return 0;
});
@ -271,13 +275,14 @@ void PrinterFileSystem::SetUrl(std::string const &url)
void PrinterFileSystem::Stop(bool quit)
{
boost::unique_lock l(m_mutex);
if (m_stopped) return;
m_stopped = true;
if (quit) {
m_session.owner = nullptr;
// let the thread delete this
m_callbacks.push_back([thiz = shared_from_this()](int result, json const &, unsigned char const *) { (void) thiz; });
} else if (m_stopped) {
return;
}
m_stopped = true;
m_cond.notify_all();
}
@ -320,7 +325,7 @@ void PrinterFileSystem::DeleteFilesContinue()
req["delete"] = arr;
m_task_flags |= FF_DELETED;
SendRequest<Void>(
FILE_DEL, req, nullptr,
FILE_DEL, req, nullptr,
[indexes, names, this](int, Void const &) {
// TODO:
for (size_t i = indexes.size() - 1; i >= 0; --i)
@ -512,14 +517,15 @@ void PrinterFileSystem::FileRemoved(size_t index, std::string const &name)
struct CallbackEvent : wxCommandEvent
{
CallbackEvent(std::function<void(void)> const &callback) : wxCommandEvent(EVT_FILE_CALLBACK), callback(callback) {}
~CallbackEvent(){ callback(); }
CallbackEvent(std::function<void(void)> const &callback, boost::weak_ptr<PrinterFileSystem> owner) : wxCommandEvent(EVT_FILE_CALLBACK), callback(callback), owner(owner) {}
~CallbackEvent(){ if (!owner.expired()) callback(); }
std::function<void(void)> const callback;
boost::weak_ptr<PrinterFileSystem> owner;
};
void PrinterFileSystem::PostCallback(std::function<void(void)> const& callback)
{
wxCommandEvent *e = new CallbackEvent(callback);
wxCommandEvent *e = new CallbackEvent(callback, boost::weak_ptr(shared_from_this()));
wxQueueEvent(this, e);
}
@ -719,7 +725,7 @@ void PrinterFileSystem::Reconnect(boost::unique_lock<boost::mutex> &l, int resul
if (c) c(result, r, nullptr);
}
m_messages.clear();
while (true) {
while (true) {
while (m_stopped) {
if (m_session.owner == nullptr)
return;
@ -796,25 +802,22 @@ StaticBambuLib &StaticBambuLib::get()
{
static StaticBambuLib lib;
// first load the library
#if defined(_MSC_VER) || defined(_WIN32)
module = LoadLibrary(L"BambuSource.dll");
#elif defined(__WXMAC__)
module = dlopen("libBambuSource.dylib", RTLD_LAZY);
#else
module = dlopen("libBambuSource.so", RTLD_LAZY);
#endif
if (!module) {
module = Slic3r::NetworkAgent::get_bambu_source_entry();
}
if (!module) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", can not Load Library";
}
GET_FUNC(Bambu_Open);
GET_FUNC(Bambu_StartStream);
GET_FUNC(Bambu_SendMessage);
GET_FUNC(Bambu_ReadSample);
GET_FUNC(Bambu_Close);
GET_FUNC(Bambu_FreeLogMsg);
if (!lib.Bambu_Open)
lib.Bambu_Open = Fake_Bambu_Open;
return lib;

View file

@ -184,7 +184,7 @@ private:
template <typename T>
boost::uint32_t SendRequest(int type, json const& req, Translator<T> const& translator, Callback<T> const& callback)
{
auto c = [translator, callback, thiz = shared_from_this()](int result, json const &resp, unsigned char const *data)
auto c = [translator, callback, this](int result, json const &resp, unsigned char const *data)
{
T t;
if (result == 0 || result == CONTINUE) {
@ -196,7 +196,7 @@ private:
result = ERROR_JSON;
}
}
thiz->PostCallback<T>(callback, result, t);
PostCallback<T>(callback, result, t);
};
return SendRequest(type, req, c);
}
@ -206,7 +206,7 @@ private:
template<typename T>
void InstallNotify(int type, Translator<T> const& translator, Applier<T> const& applier)
{
auto c = [translator, applier, thiz = shared_from_this()](int result, json const &resp, unsigned char const *data)
auto c = [translator, applier, this](int result, json const &resp, unsigned char const *data)
{
T t;
if (result == 0 || result == CONTINUE) {
@ -219,7 +219,7 @@ private:
}
}
if (result == 0 && applier) {
thiz->PostCallback<T>([applier](int, T const & t) {
PostCallback<T>([applier](int, T const & t) {
applier(t);
}, 0, t);
}
@ -274,9 +274,9 @@ private:
std::deque<callback_t2> m_callbacks;
std::deque<callback_t2> m_notifies;
bool m_stopped = true;
boost::thread m_recv_thread;
boost::mutex m_mutex;
boost::condition_variable m_cond;
boost::thread m_recv_thread;
Status m_status;
int m_last_error = 0;
};

View file

@ -56,7 +56,7 @@ ReleaseNoteDialog::ReleaseNoteDialog(Plater *plater /*= nullptr*/)
m_sizer_right->Add(0, 0, 1, wxTOP, FromDIP(15));
m_scrollwindw_release_note = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(560), FromDIP(430)));
m_scrollwindw_release_note = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(560), FromDIP(430)), wxVSCROLL);
m_scrollwindw_release_note->SetScrollRate(5, 5);
m_scrollwindw_release_note->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8));
m_scrollwindw_release_note->SetMaxSize(wxSize(FromDIP(560), FromDIP(430)));
@ -84,10 +84,118 @@ void ReleaseNoteDialog::update_release_note(std::string release_note, std::strin
m_text_up_info->SetLabel(wxString::Format("version %s update information :", version));
wxBoxSizer * sizer_text_release_note = new wxBoxSizer(wxVERTICAL);
auto m_staticText_release_note = new wxStaticText(m_scrollwindw_release_note, wxID_ANY, release_note, wxDefaultPosition, wxDefaultSize, 0);
m_staticText_release_note->Wrap(FromDIP(430));
m_staticText_release_note->Wrap(FromDIP(530));
sizer_text_release_note->Add(m_staticText_release_note, 0, wxALL, 5);
m_scrollwindw_release_note->SetSizer(sizer_text_release_note);
m_scrollwindw_release_note->Layout();
}
UpdateVersionDialog::UpdateVersionDialog(wxWindow *parent)
: DPIDialog(parent, wxID_ANY, _L("New version of Bambu Studio"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX)
{
std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str();
SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO));
SetBackgroundColour(*wxWHITE);
wxBoxSizer *m_sizer_main = new wxBoxSizer(wxVERTICAL);
auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1));
m_line_top->SetBackgroundColour(wxColour(166, 169, 170));
m_sizer_main->Add(m_line_top, 0, wxEXPAND, 0);
m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(30));
wxBoxSizer *m_sizer_body = new wxBoxSizer(wxHORIZONTAL);
m_sizer_body->Add(0, 0, 0, wxLEFT, FromDIP(38));
auto sm = create_scaled_bitmap("BambuStudio", nullptr, 70);
auto brand = new wxStaticBitmap(this, wxID_ANY, sm, wxDefaultPosition, wxSize(FromDIP(70), FromDIP(70)));
m_sizer_body->Add(brand, 0, wxALL, 0);
m_sizer_body->Add(0, 0, 0, wxRIGHT, FromDIP(25));
wxBoxSizer *m_sizer_right = new wxBoxSizer(wxVERTICAL);
m_text_up_info = new wxStaticText(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
m_text_up_info->SetFont(::Label::Head_14);
m_text_up_info->SetForegroundColour(wxColour(0x26, 0x2E, 0x30));
m_text_up_info->Wrap(-1);
m_sizer_right->Add(m_text_up_info, 0, 0, 0);
m_sizer_right->Add(0, 0, 1, wxTOP, FromDIP(15));
m_scrollwindw_release_note = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(560), FromDIP(430)), wxVSCROLL);
m_scrollwindw_release_note->SetScrollRate(5, 5);
m_scrollwindw_release_note->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8));
m_scrollwindw_release_note->SetMaxSize(wxSize(FromDIP(560), FromDIP(430)));
auto sizer_button = new wxBoxSizer(wxHORIZONTAL);
StateColor btn_bg_green(std::pair<wxColour, int>(wxColour(27, 136, 68), StateColor::Pressed), std::pair<wxColour, int>(wxColour(61, 203, 115), StateColor::Hovered),
std::pair<wxColour, int>(AMS_CONTROL_BRAND_COLOUR, StateColor::Normal));
StateColor btn_bg_white(std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Pressed), std::pair<wxColour, int>(wxColour(238, 238, 238), StateColor::Hovered),
std::pair<wxColour, int>(*wxWHITE, StateColor::Normal));
auto m_butto_ok = new Button(this, _L("OK"));
m_butto_ok->SetBackgroundColor(btn_bg_green);
m_butto_ok->SetBorderColor(*wxWHITE);
m_butto_ok->SetTextColor(*wxWHITE);
m_butto_ok->SetFont(Label::Body_12);
m_butto_ok->SetSize(wxSize(FromDIP(58), FromDIP(24)));
m_butto_ok->SetMinSize(wxSize(FromDIP(58), FromDIP(24)));
m_butto_ok->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) {
EndModal(wxID_YES);
});
auto m_button_cancel = new Button(this, _L("Cancel"));
m_button_cancel->SetBackgroundColor(*wxWHITE);
m_button_cancel->SetBorderColor(wxColour(38, 46, 48));
m_button_cancel->SetFont(Label::Body_12);
m_button_cancel->SetSize(wxSize(FromDIP(58), FromDIP(24)));
m_button_cancel->SetMinSize(wxSize(FromDIP(58), FromDIP(24)));
m_button_cancel->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) {
EndModal(wxID_NO);
});
sizer_button->Add(0, 0, 1, wxEXPAND, 5);
sizer_button->Add(m_butto_ok, 0, wxALL, 5);
sizer_button->Add(m_button_cancel, 0, wxALL, 5);
m_sizer_right->Add(m_scrollwindw_release_note, 0, wxEXPAND | wxRIGHT, FromDIP(20));
m_sizer_body->Add(m_sizer_right, 1, wxBOTTOM | wxEXPAND, FromDIP(8));
m_sizer_main->Add(m_sizer_body, 0, wxEXPAND, 0);
m_sizer_main->Add(sizer_button, 0, wxEXPAND, 0);
m_sizer_main->Add(0, 0, 0, wxBOTTOM, 10);
SetSizer(m_sizer_main);
Layout();
m_sizer_main->Fit(this);
Centre(wxBOTH);
}
UpdateVersionDialog::~UpdateVersionDialog() {}
void UpdateVersionDialog::on_dpi_changed(const wxRect &suggested_rect) {
}
void UpdateVersionDialog::update_version_info(wxString release_note, wxString version)
{
m_text_up_info->SetLabel(wxString::Format("Click to download new version in default browser: %s", version));
wxBoxSizer *sizer_text_release_note = new wxBoxSizer(wxVERTICAL);
auto m_staticText_release_note = new wxStaticText(m_scrollwindw_release_note, wxID_ANY, release_note, wxDefaultPosition, wxDefaultSize, 0);
m_staticText_release_note->Wrap(FromDIP(530));
sizer_text_release_note->Add(m_staticText_release_note, 0, wxALL, 5);
m_scrollwindw_release_note->SetSizer(sizer_text_release_note);
m_scrollwindw_release_note->Layout();
}
}} // namespace Slic3r::GUI

View file

@ -49,6 +49,21 @@ public:
wxScrolledWindow *m_scrollwindw_release_note {nullptr};
};
class UpdateVersionDialog : public DPIDialog
{
public:
UpdateVersionDialog(wxWindow *parent = nullptr);
~UpdateVersionDialog();
void on_dpi_changed(const wxRect &suggested_rect) override;
void update_version_info(wxString release_note, wxString version);
wxStaticText * m_text_up_info{nullptr};
wxScrolledWindow *m_scrollwindw_release_note{nullptr};
wxBoxSizer * sizer_text_release_note{nullptr};
wxStaticText * m_staticText_release_note{nullptr};
};
}} // namespace Slic3r::GUI
#endif

File diff suppressed because it is too large Load diff

View file

@ -105,6 +105,7 @@ private:
class MachineObjectPanel : public wxPanel
{
private:
bool m_is_my_devices {false};
bool m_show_edit{false};
bool m_show_bind{false};
bool m_hover {false};
@ -142,12 +143,11 @@ public:
void show_bind_dialog();
void set_printer_state(PrinterState state);
//void set_can_bind(bool canbind);
void show_printer_bind(bool show, PrinterBindState state);
void show_edit_printer_name(bool show);
void update_machine_info(MachineObject *info);
void update_machine_info(MachineObject *info, bool is_my_devices = false);
protected:
void OnPaint(wxPaintEvent &event);
@ -155,12 +155,11 @@ protected:
void doRender(wxDC &dc);
void on_mouse_enter(wxMouseEvent &evt);
void on_mouse_leave(wxMouseEvent &evt);
void on_mouse_left_down(wxMouseEvent &evt);
void on_mouse_left_up(wxMouseEvent &evt);
};
#define SELECT_MACHINE_POPUP_SIZE wxSize(FromDIP(218), FromDIP(364))
#define SELECT_MACHINE_LIST_SIZE wxSize(FromDIP(210), FromDIP(306))
#define SELECT_MACHINE_LIST_SIZE wxSize(FromDIP(214), FromDIP(360))
#define SELECT_MACHINE_ITEM_SIZE wxSize(FromDIP(180), FromDIP(35))
#define SELECT_MACHINE_GREY900 wxColour(38, 46, 48)
#define SELECT_MACHINE_GREY600 wxColour(144,144,144)
@ -176,7 +175,8 @@ public:
MachineObjectPanel *mPanel;
};
WX_DEFINE_ARRAY(MachinePanel*, MachinePanelHash);
class ThumbnailPanel;
class SelectMachinePopup : public wxPopupTransientWindow
{
@ -202,7 +202,7 @@ private:
wxWindow * m_panel_body{nullptr};
wxTimer * m_refresh_timer{nullptr};
std::vector<MachinePanel*> m_user_list_machine_panel;
std::vector<MachinePanel*> m_list_Machine_panel;
std::vector<MachinePanel*> m_other_list_machine_panel;
boost::thread* get_print_info_thread{ nullptr };
std::string m_print_info;
bool m_dismiss { false };
@ -211,20 +211,13 @@ private:
std::map<std::string, MachineObject*> m_free_machine_list;
private:
void OnMouse(wxMouseEvent &event);
void OnLeftUp(wxMouseEvent &event);
void OnSize(wxSizeEvent &event);
void OnSetFocus(wxFocusEvent &event);
void OnKillFocus(wxFocusEvent &event);
void on_timer(wxTimerEvent &event);
void update_other_devices();
void update_user_devices();
void on_dissmiss_win(wxCommandEvent &event);
wxWindow *create_title_panel(wxString text);
private:
wxDECLARE_ABSTRACT_CLASS(SelectMachinePopup);
wxDECLARE_EVENT_TABLE();
};
#define SELECT_MACHINE_DIALOG_BUTTON_SIZE wxSize(FromDIP(68), FromDIP(24))
@ -250,7 +243,7 @@ enum PrintDialogStatus {
PrintStatusRefreshingMachineList,
PrintStatusSending,
PrintStatusSendingCanceled,
PrintStatusNoSdcard,
PrintStatusNoSdcard
};
class SelectMachineDialog : public DPIDialog
@ -263,7 +256,7 @@ private:
int m_print_plate_idx;
std::string m_printer_last_select;
PrintDialogStatus m_print_status;
PrintDialogStatus m_print_status { PrintStatusInit };
std::vector<wxString> m_bedtype_list;
std::map<std::string, ::CheckBox *> m_checkbox_list;
@ -279,30 +272,23 @@ protected:
bool ams_mapping_valid { false };
Plater * m_plater{nullptr};
wxPanel * m_line_top{nullptr};
wxPanel * m_image{nullptr};
wxPanel * m_panel_image{nullptr};
wxStaticText *m_stext_time{nullptr};
wxStaticText *m_stext_weight{nullptr};
wxPanel * m__line_materia{nullptr};
wxPanel * m_line_materia{nullptr};
wxStaticText *m_stext_printer_title{nullptr};
wxStaticText *m_text_load_ams_data{nullptr};
wxStaticText *m_error_load_ams_data{nullptr};
wxStaticText *m_statictext_ams_msg{nullptr};
wxStaticText * m_statictext_printer_msg{nullptr};
wxStaticBitmap* m_staticbitmap {nullptr};
ThumbnailPanel *m_thumbnailPanel {nullptr};
::ComboBox * m_comboBox_printer{nullptr};
::ComboBox * m_comboBox_bed{nullptr};
wxPanel * m_panel_warn{nullptr};
wxStaticText *m_statictext_warn{nullptr};
wxPanel * m_line_bed{nullptr};
wxStaticText *m_staticText_bed_title{nullptr};
wxPanel * m_line_schedule{nullptr};
wxPanel * m_panel_err{nullptr};
wxStaticText *m_statictext_err{nullptr};
wxPanel * m_panel_sending{nullptr};
wxStaticText *m_stext_sending{nullptr};
wxStaticText *m_stext_percent{nullptr};
wxGauge * m_sending_gauge{nullptr};
Button * m_cancel{nullptr};
wxPanel * m_panel_prepare{nullptr};
Button * m_button_refresh{nullptr};
Button * m_button_ensure{nullptr};
@ -320,16 +306,13 @@ protected:
wxBoxSizer * m_sizer_bottom;
wxWindow *select_bed{nullptr};
//wxWindow *select_vibration{nullptr};
wxWindow *select_flow{nullptr};
//wxWindow *select_layer_inspect {nullptr};
//wxWindow *select_record{nullptr};
void stripWhiteSpace(std::string& str);
void update_info_msg(wxString msg);
void update_warn_msg(wxString msg);
void update_err_msg(wxString msg);
void stripWhiteSpace(std::string& str);
void update_ams_status_msg(wxString msg, bool is_warning = false);
void update_priner_status_msg(wxString msg, bool is_warning = false);
void update_print_status_msg(wxString msg, bool is_warning = false, bool is_printer = true);
public:
SelectMachineDialog(Plater *plater = nullptr);
@ -341,11 +324,10 @@ public:
void sending_mode();
void finish_mode();
bool do_ams_mapping(MachineObject* obj_);
void sync_ams_mapping_result(std::vector<FilamentInfo>& result);
bool do_ams_mapping(MachineObject *obj_);
bool get_ams_mapping_result(std::string &mapping_array_str);
void prepare(int print_plate_idx);
void update_print_status_msg(wxString msg, bool is_warning = false);
void show_status(PrintDialogStatus status);
PrintDialogStatus get_status() { return m_print_status; }
@ -358,16 +340,21 @@ public:
protected:
std::vector<MachineObject *> m_list;
wxDataViewCtrl * m_dataViewListCtrl_machines;
wxStaticText * m_staticText_left;
wxHyperlinkCtrl * m_hyperlink_add_machine;
wxGauge * m_gauge_job_progress;
wxPanel * m_panel_status;
wxButton * m_button_cancel;
wxDataViewCtrl * m_dataViewListCtrl_machines{nullptr};
wxStaticText * m_staticText_left{nullptr};
wxHyperlinkCtrl * m_hyperlink_add_machine{nullptr};
wxGauge * m_gauge_job_progress{nullptr};
wxPanel * m_panel_status{nullptr};
wxButton * m_button_cancel{nullptr};
AmsMapingPopup m_mapping_popup{nullptr};
std::string m_print_info;
int timeout_count = 0;
bool is_timeout();
void reset_timeout();
bool is_timeout();
void reset_timeout();
void update_user_printer();
void reset_ams_material();
void update_show_status();
wxTimer *m_refresh_timer;
@ -386,6 +373,7 @@ protected:
void Enable_Refresh_Button(bool en);
void Enable_Send_Button(bool en);
void on_dpi_changed(const wxRect &suggested_rect) override;
void update_user_machine_list();
wxImage * LoadImageFromBlob(const unsigned char *data, int size);
std::vector<std::string> sort_string(std::vector<std::string> strArray);
};
@ -394,6 +382,11 @@ wxDECLARE_EVENT(EVT_FINISHED_UPDATE_MACHINE_LIST, wxCommandEvent);
wxDECLARE_EVENT(EVT_REQUEST_BIND_LIST, wxCommandEvent);
wxDECLARE_EVENT(EVT_WILL_DISMISS_MACHINE_LIST, wxCommandEvent);
wxDECLARE_EVENT(EVT_UPDATE_WINDOWS_POSITION, wxCommandEvent);
wxDECLARE_EVENT(EVT_DISSMISS_MACHINE_LIST, wxCommandEvent);
wxDECLARE_EVENT(EVT_CONNECT_LAN_PRINT, wxCommandEvent);
wxDECLARE_EVENT(EVT_EDIT_PRINT_NAME, wxCommandEvent);
wxDECLARE_EVENT(EVT_UNBIND_MACHINE, wxCommandEvent);
wxDECLARE_EVENT(EVT_BIND_MACHINE, wxCommandEvent);
class EditDevNameDialog : public DPIDialog
{
@ -411,6 +404,24 @@ public:
Button* m_button_confirm {nullptr};
};
class ThumbnailPanel : public wxPanel
{
public:
wxBitmap * m_bitmap{nullptr};
wxStaticBitmap *m_staticbitmap{nullptr};
ThumbnailPanel(wxWindow * parent,
wxWindowID winid = wxID_ANY,
const wxPoint & pos = wxDefaultPosition,
const wxSize & size = wxDefaultSize);
void OnPaint(wxPaintEvent &event);
void PaintBackground(wxDC &dc);
void OnEraseBackground(wxEraseEvent &event);
void set_thumbnail(wxImage img);
~ThumbnailPanel();
};
}} // namespace Slic3r::GUI
#endif

View file

@ -39,8 +39,8 @@ static const wxColour STAGE_TEXT_COL = wxColour(0, 174, 66);
static const wxColour GROUP_STATIC_LINE_COL = wxColour(206, 206, 206);
/* font and foreground colors */
static const wxFont PAGE_TITLE_FONT = wxFont(11, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, 0, false, wxT("HarmonyOS Sans SC"));
static const wxFont GROUP_TITLE_FONT = wxFont(13, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, 0, false, wxT("HarmonyOS Sans SC"));
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);
@ -61,6 +61,7 @@ static wxColour TEXT_LIGHT_FONT_COL = wxColour(107, 107, 107);
#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(52), FromDIP(52)))
#define MISC_BUTTON_SIZE (wxSize(FromDIP(68), FromDIP(55)))
#define TEMP_CTRL_MIN_SIZE (wxSize(FromDIP(122), FromDIP(52)))
@ -167,9 +168,10 @@ void StatusBasePanel::init_bitmaps()
m_bitmap_speed_active = create_scaled_bitmap("monitor_speed_active", nullptr, 24);
m_thumbnail_placeholder = create_scaled_bitmap("monitor_placeholder", nullptr, 120);
m_thumbnail_sdcard = create_scaled_bitmap("monitor_sdcard_thumbnail", nullptr, 120);
m_bitmap_camera = create_scaled_bitmap("monitor_camera", nullptr, 18);
//m_bitmap_camera = create_scaled_bitmap("monitor_camera", nullptr, 18);
m_bitmap_extruder = *cache.load_png("monitor_extruder", FromDIP(28), FromDIP(70), false, false);
m_bitmap_sdcard_state_on = create_scaled_bitmap("sdcard_state_on", nullptr, 16);
m_bitmap_sdcard_state_off = create_scaled_bitmap("sdcard_state_off", nullptr, 16);
}
wxBoxSizer *StatusBasePanel::create_monitoring_page()
@ -182,7 +184,7 @@ wxBoxSizer *StatusBasePanel::create_monitoring_page()
wxBoxSizer *bSizer_monitoring_title;
bSizer_monitoring_title = new wxBoxSizer(wxHORIZONTAL);
m_staticText_monitoring = new wxStaticText(m_panel_monitoring_title, wxID_ANY, _L("Monitoring"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
m_staticText_monitoring = new wxStaticText(m_panel_monitoring_title, wxID_ANY, _L("Camera"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
m_staticText_monitoring->Wrap(-1);
m_staticText_monitoring->SetFont(PAGE_TITLE_FONT);
m_staticText_monitoring->SetForegroundColour(PAGE_TITLE_FONT_COL);
@ -202,9 +204,32 @@ wxBoxSizer *StatusBasePanel::create_monitoring_page()
m_bmToggleBtn_timelapse->Hide();
bSizer_monitoring_title->Add(m_bmToggleBtn_timelapse, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
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_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_off_img = new wxStaticBitmap(m_panel_monitoring_title, wxID_ANY, m_bitmap_sdcard_state_off, wxDefaultPosition, wxSize(FromDIP(32), FromDIP(16)), 0);
m_bitmap_sdcard_off_img->SetMinSize(wxSize(FromDIP(32), FromDIP(16)));
m_bitmap_sdcard_on_img = new wxStaticBitmap(m_panel_monitoring_title, wxID_ANY, m_bitmap_sdcard_state_on, wxDefaultPosition, wxSize(FromDIP(32), FromDIP(16)), 0);
m_bitmap_sdcard_on_img->SetMinSize(wxSize(FromDIP(32), FromDIP(16)));
m_bitmap_sdcard_on_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(32, 24));
m_timelapse_button->SetBackgroundColour(STATUS_TITLE_BG);
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(32, 24));
m_recording_button->SetBackgroundColour(STATUS_TITLE_BG);
m_timelapse_button->SetToolTip(_L("Timelapse"));
m_recording_button->SetToolTip(_L("Video"));
bSizer_monitoring_title->Add(m_bitmap_sdcard_off_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(FromDIP(13), 0, 0);
m_panel_monitoring_title->SetSizer(bSizer_monitoring_title);
@ -313,7 +338,7 @@ wxBoxSizer *StatusBasePanel::create_project_task_page(wxWindow *parent)
std::pair<wxColour, int>(wxColour(238, 238, 238), StateColor::Hovered), std::pair<wxColour, int>(wxColour(255, 255, 255), StateColor::Enabled),
std::pair<wxColour, int>(wxColour(255, 255, 255), StateColor::Normal));
m_button_report->SetBackgroundColor(report_bg);
m_button_report->SetMinSize(TASK_BUTTON_SIZE);
m_button_report->SetMinSize(TASK_BUTTON_SIZE2);
StateColor report_bd(std::pair<wxColour, int>(wxColour(144, 144, 144), StateColor::Disabled), std::pair<wxColour, int>(wxColour(38, 46, 48), StateColor::Enabled));
m_button_report->SetBorderColor(report_bd);
StateColor report_text(std::pair<wxColour, int>(wxColour(144, 144, 144), StateColor::Disabled), std::pair<wxColour, int>(wxColour(38, 46, 48), StateColor::Enabled));
@ -333,7 +358,7 @@ wxBoxSizer *StatusBasePanel::create_project_task_page(wxWindow *parent)
StateColor pause_resume_text(std::pair<wxColour, int>(wxColour(144, 144, 144), StateColor::Disabled), std::pair<wxColour, int>(wxColour(255, 255, 255), StateColor::Enabled));
m_button_pause_resume->SetTextColor(pause_resume_text);
m_button_pause_resume->SetFont(Label::Body_10);
m_button_pause_resume->SetMinSize(TASK_BUTTON_SIZE);
m_button_pause_resume->SetMinSize(TASK_BUTTON_SIZE2);
//bSizer_task_btn->Add(m_button_pause_resume, 0, wxALIGN_RIGHT | wxALL, FromDIP(5));
m_sizer_progressbar->Add(m_button_pause_resume, 0, wxALL, FromDIP(5));
@ -348,7 +373,7 @@ wxBoxSizer *StatusBasePanel::create_project_task_page(wxWindow *parent)
StateColor abort_text(std::pair<wxColour, int>(wxColour(144, 144, 144), StateColor::Disabled), std::pair<wxColour, int>(wxColour(38, 46, 48), StateColor::Enabled));
m_button_abort->SetTextColor(abort_text);
m_button_abort->SetFont(Label::Body_10);
m_button_abort->SetMinSize(TASK_BUTTON_SIZE);
m_button_abort->SetMinSize(TASK_BUTTON_SIZE2);
//bSizer_task_btn->Add(m_button_abort, 0, wxALIGN_RIGHT | wxALL, FromDIP(5));
m_sizer_progressbar->Add(m_button_abort, 0, wxALL, FromDIP(5));
@ -435,7 +460,7 @@ wxBoxSizer *StatusBasePanel::create_machine_control_page(wxWindow *parent)
m_calibration_btn->SetBorderColor(btn_bd_green);
m_calibration_btn->SetTextColor(*wxWHITE);
m_calibration_btn->SetSize(wxSize(FromDIP(128), FromDIP(26)));
m_calibration_btn->SetMinSize(wxSize(FromDIP(128), FromDIP(26)));
m_calibration_btn->SetMinSize(wxSize(-1, FromDIP(26)));
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);
@ -623,6 +648,7 @@ void StatusBasePanel::reset_temp_misc_control()
m_tempCtrl_bed->GetTextCtrl()->SetLabel(TEMP_BLANK_STR);
m_tempCtrl_frame->SetLabel(TEMP_BLANK_STR);
m_tempCtrl_frame->GetTextCtrl()->SetLabel(TEMP_BLANK_STR);
m_button_unload->Show();
m_tempCtrl_nozzle->Enable(true);
m_tempCtrl_frame->Enable(true);
@ -778,7 +804,7 @@ wxBoxSizer *StatusBasePanel::create_extruder_control(wxWindow *parent)
StateColor abort_text(std::pair<wxColour, int>(wxColour(144, 144, 144), StateColor::Disabled), std::pair<wxColour, int>(wxColour(38, 46, 48), StateColor::Enabled));
m_button_unload->SetTextColor(abort_text);
m_button_unload->SetFont(Label::Body_10);
m_button_unload->SetMinSize(wxSize(FromDIP(52), FromDIP(26)));
m_button_unload->SetMinSize(wxSize(-1, FromDIP(24)));
m_button_unload->SetCornerRadius(FromDIP(10));
bSizer_e_ctrl->Add(0, 0, 1, wxEXPAND, 0);
bSizer_e_ctrl->Add(m_button_unload, 0, wxALIGN_CENTER_HORIZONTAL| wxTOP|wxBOTTOM, FromDIP(5));
@ -844,6 +870,40 @@ void StatusBasePanel::show_ams_group(bool show)
m_show_ams_group = show;
}
void StatusBasePanel::upodate_camera_state(bool recording, bool timelapse, bool has_sdcard)
{
//sdcard
/* if (has_sdcard && !m_bitmap_sdcard_img->IsShown()) {
m_bitmap_sdcard_img->Show();
m_panel_monitoring_title->Layout();
}
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);
//timelapse
m_timelapse_button->set_switch(timelapse);
}
StatusPanel::StatusPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, const wxString &name)
: StatusBasePanel(parent, id, pos, size, style)
{
@ -855,6 +915,7 @@ StatusPanel::StatusPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, co
m_buttons.push_back(m_button_report);
m_buttons.push_back(m_button_pause_resume);
m_buttons.push_back(m_button_abort);
m_buttons.push_back(m_button_unload);
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);
@ -887,8 +948,7 @@ 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_bitmap_camera_img->Connect(wxEVT_ENTER_WINDOW, wxMouseEventHandler(StatusPanel::on_camera_enter), NULL, this);
//m_bitmap_camera_img->Connect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(StatusPanel::on_camera_leave), NULL, this);
m_recording_button->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(StatusPanel::on_switch_recording), 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);
@ -924,8 +984,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_bitmap_camera_img->Disconnect(wxEVT_ENTER_WINDOW, wxMouseEventHandler(StatusPanel::on_camera_enter), NULL, this);
//m_bitmap_camera_img->Disconnect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(StatusPanel::on_camera_leave), NULL, this);
m_recording_button->Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(StatusPanel::on_switch_recording), 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_tempCtrl_bed->Disconnect(wxEVT_KILL_FOCUS, wxFocusEventHandler(StatusPanel::on_bed_temp_kill_focus), NULL, this);
@ -955,7 +1014,7 @@ void StatusPanel::init_scaled_buttons()
m_button_pause_resume->SetCornerRadius(FromDIP(12));
m_button_abort->SetMinSize(wxSize(FromDIP(48), FromDIP(24)));
m_button_abort->SetCornerRadius(FromDIP(12));
m_button_unload->SetMinSize(wxSize(FromDIP(52), FromDIP(24)));
m_button_unload->SetMinSize(wxSize(-1, FromDIP(24)));
m_button_unload->SetCornerRadius(FromDIP(10));
m_bpButton_z_10->SetMinSize(Z_BUTTON_SIZE);
m_bpButton_z_10->SetCornerRadius(0);
@ -1095,7 +1154,6 @@ void StatusPanel::update(MachineObject *obj)
// update_tasklist(obj);
update_ams(obj);
update_cali(obj);
if (obj) {
if (calibration_dlg == nullptr) {
@ -1108,6 +1166,7 @@ void StatusPanel::update(MachineObject *obj)
}
upodate_camera_state(obj->has_recording(), obj->has_timelapse(), obj->has_sdcard());
m_machine_ctrl_panel->Thaw();
}
@ -1202,22 +1261,21 @@ void StatusPanel::update_temp_ctrl(MachineObject *obj)
m_tempCtrl_frame->SetTagTemp(obj->chamber_temp);
}
void StatusPanel::show_unload_ctrl()
{
m_button_unload->Show();
m_button_unload->GetParent()->Layout();
}
void StatusPanel::update_misc_ctrl(MachineObject *obj)
{
if (!obj) return;
if (obj->has_ams()) {
m_button_unload->Hide();
m_button_unload->GetParent()->Layout();
if (m_button_unload->IsShown()) {
m_button_unload->Hide();
m_button_unload->GetParent()->Layout();
}
} else {
m_button_unload->Show();
m_button_unload->GetParent()->Layout();
if (!m_button_unload->IsShown()) {
m_button_unload->Show();
m_button_unload->GetParent()->Layout();
}
}
// nozzle fan
@ -1285,18 +1343,28 @@ void StatusPanel::update_ams(MachineObject *obj)
info.ams_id = ams->first;
if (ams->second->is_exists && info.parse_ams_info(ams->second)) ams_info.push_back(info);
}
if (obj->ams_exist_bits != last_ams_exist_bits || obj->tray_exist_bits != last_tray_exist_bits || obj->tray_is_bbl_bits != last_tray_is_bbl_bits ||
obj->tray_read_done_bits != last_read_done_bits || obj->ams_version != last_ams_version) {
m_ams_control->UpdateAms(ams_info, false);
// select current ams
//if (!obj->m_ams_id.empty()) m_ams_control->SwitchAms(obj->m_ams_id);
//if (obj->ams_exist_bits != last_ams_exist_bits || obj->tray_exist_bits != last_tray_exist_bits || obj->tray_is_bbl_bits != last_tray_is_bbl_bits ||
// obj->tray_read_done_bits != last_read_done_bits || obj->ams_version != last_ams_version) {
// m_ams_control->UpdateAms(ams_info, false);
// // select current ams
// //if (!obj->m_ams_id.empty()) m_ams_control->SwitchAms(obj->m_ams_id);
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_ams_version = obj->ams_version;
}
// 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_ams_version = obj->ams_version;
//}
// select current ams
// if (!obj->m_ams_id.empty()) m_ams_control->SwitchAms(obj->m_ams_id);
m_ams_control->UpdateAms(ams_info, false);
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_ams_version = obj->ams_version;
}
if (!obj->is_ams_unload()) {
@ -1314,40 +1382,60 @@ void StatusPanel::update_ams(MachineObject *obj)
if (obj->ams_status_main == AMS_STATUS_MAIN_FILAMENT_CHANGE) {
// wait to heat hotend
if (obj->ams_status_sub == 0x02) {
m_ams_control->SetFilamentStep(FilamentStep::STEP_HEAT_NOZZLE);
if (curr_ams_id == obj->m_ams_id) {
if (!obj->is_ams_unload()) {
m_ams_control->SetFilamentStep(FilamentStep::STEP_HEAT_NOZZLE, true);
m_ams_control->SetAmsStep(curr_ams_id, obj->m_tray_id, AMSPassRoadType::AMS_ROAD_TYPE_LOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_3);
} else {
m_ams_control->SetFilamentStep(FilamentStep::STEP_HEAT_NOZZLE, false);
m_ams_control->SetAmsStep(curr_ams_id, obj->m_tray_id, AMSPassRoadType::AMS_ROAD_TYPE_UNLOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_3);
}
}
} else if (obj->ams_status_sub == 0x03) {
m_ams_control->SetFilamentStep(FilamentStep::STEP_CUT_FILAMENT);
if (!obj->is_ams_unload())
if (!obj->is_ams_unload()) {
m_ams_control->SetFilamentStep(FilamentStep::STEP_CUT_FILAMENT, true);
m_ams_control->SetAmsStep(curr_ams_id, obj->m_tray_id, AMSPassRoadType::AMS_ROAD_TYPE_LOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_COMBO_LOAD_STEP1);
else
}
else {
m_ams_control->SetFilamentStep(FilamentStep::STEP_CUT_FILAMENT, false);
m_ams_control->SetAmsStep(curr_ams_id, obj->m_tray_id, AMSPassRoadType::AMS_ROAD_TYPE_UNLOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_COMBO_LOAD_STEP3);
}
} else if (obj->ams_status_sub == 0x04) {
m_ams_control->SetFilamentStep(FilamentStep::STEP_PULL_CURR_FILAMENT);
if (!obj->is_ams_unload())
if (!obj->is_ams_unload()) {
m_ams_control->SetFilamentStep(FilamentStep::STEP_PULL_CURR_FILAMENT, true);
m_ams_control->SetAmsStep(curr_ams_id, obj->m_tray_id, AMSPassRoadType::AMS_ROAD_TYPE_LOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_COMBO_LOAD_STEP2);
else
}
else {
//FilamentStep::STEP_PULL_CURR_FILAMENT);
m_ams_control->SetFilamentStep(FilamentStep::STEP_PULL_CURR_FILAMENT, false);
m_ams_control->SetAmsStep(curr_ams_id, obj->m_tray_id, AMSPassRoadType::AMS_ROAD_TYPE_UNLOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_NONE);
}
} else if (obj->ams_status_sub == 0x05) {
m_ams_control->SetFilamentStep(FilamentStep::STEP_PUSH_NEW_FILAMENT);
if (!obj->is_ams_unload())
if (!obj->is_ams_unload()) {
m_ams_control->SetFilamentStep(FilamentStep::STEP_PUSH_NEW_FILAMENT, true);
m_ams_control->SetAmsStep(curr_ams_id, obj->m_tray_id, AMSPassRoadType::AMS_ROAD_TYPE_LOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_COMBO_LOAD_STEP2);
else
}
else {
m_ams_control->SetFilamentStep(FilamentStep::STEP_PUSH_NEW_FILAMENT, false);
m_ams_control->SetAmsStep(curr_ams_id, obj->m_tray_id, AMSPassRoadType::AMS_ROAD_TYPE_UNLOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_NONE);
}
} else if (obj->ams_status_sub == 0x06) {
m_ams_control->SetFilamentStep(FilamentStep::STEP_PUSH_NEW_FILAMENT);
if (!obj->is_ams_unload())
if (!obj->is_ams_unload()) {
m_ams_control->SetFilamentStep(FilamentStep::STEP_PUSH_NEW_FILAMENT, true);
m_ams_control->SetAmsStep(curr_ams_id, obj->m_tray_id, AMSPassRoadType::AMS_ROAD_TYPE_LOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_COMBO_LOAD_STEP3);
else
} else {
m_ams_control->SetFilamentStep(FilamentStep::STEP_PUSH_NEW_FILAMENT, false);
m_ams_control->SetAmsStep(curr_ams_id, obj->m_tray_id, AMSPassRoadType::AMS_ROAD_TYPE_UNLOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_NONE);
}
} else if (obj->ams_status_sub == 0x07) {
m_ams_control->SetFilamentStep(FilamentStep::STEP_PURGE_OLD_FILAMENT);
if (!obj->is_ams_unload()) {
m_ams_control->SetFilamentStep(FilamentStep::STEP_PURGE_OLD_FILAMENT);
} else {
m_ams_control->SetFilamentStep(FilamentStep::STEP_PURGE_OLD_FILAMENT, false);
}
m_ams_control->SetAmsStep(curr_ams_id, obj->m_tray_id, AMSPassRoadType::AMS_ROAD_TYPE_LOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_COMBO_LOAD_STEP3);
} else {
m_ams_control->SetAmsStep(curr_ams_id, obj->m_tray_id, AMSPassRoadType::AMS_ROAD_TYPE_UNLOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_NONE);
@ -1360,7 +1448,7 @@ void StatusPanel::update_ams(MachineObject *obj)
m_ams_control->SetAmsStep(curr_ams_id, obj->m_tray_id, AMSPassRoadType::AMS_ROAD_TYPE_UNLOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_NONE);
}
} else {
m_ams_control->SetFilamentStep(FilamentStep::STEP_IDLE);
m_ams_control->SetFilamentStep(FilamentStep::STEP_IDLE, false);
if (obj->is_filament_move()) {
m_ams_control->SetAmsStep(curr_ams_id, obj->m_tray_id, AMSPassRoadType::AMS_ROAD_TYPE_UNLOAD, AMSPassRoadSTEP::AMS_ROAD_STEP_COMBO_LOAD_STEP3);
} else {
@ -1387,75 +1475,52 @@ void StatusPanel::update_ams(MachineObject *obj)
// update rfid button style
// update load/unload enable state
// printing
if (obj->ams_status_main != AMS_STATUS_MAIN_FILAMENT_CHANGE) {
if (obj->m_tray_now == "255") {
m_ams_control->SetActionState(AMSAction::AMS_ACTION_LOAD);
} else {
m_ams_control->SetActionState(AMSAction::AMS_ACTION_NORMAL);
}
} else {
if (obj->is_in_printing() && !obj->can_resume()) {
m_ams_control->SetActionState(AMSAction::AMS_ACTION_PRINTING);
} else {
if (obj->ams_status_main != AMS_STATUS_MAIN_FILAMENT_CHANGE) {
if (obj->m_tray_now == "255") {
m_ams_control->SetActionState(AMSAction::AMS_ACTION_LOAD);
} else {
m_ams_control->SetActionState(AMSAction::AMS_ACTION_NORMAL);
}
} else {
m_ams_control->SetActionState(AMSAction::AMS_ACTION_PRINTING);
}
}
}
void StatusPanel::update_cali(MachineObject *obj)
{
if (!obj) return;
if (obj->is_in_printing()) {
m_calibration_btn->Disable();
return;
} else {
m_calibration_btn->Enable();
if (!obj->is_in_calibration()) {
m_calibration_btn->SetLabel(_L("Start Calibration"));
} else {
if (obj->is_in_calibration()) {
m_calibration_btn->SetLabel(_L("Calibrating"));
if (calibration_dlg && calibration_dlg->IsShown()) {
m_calibration_btn->Disable();
m_calibration_btn->SetLabel(_L("Calibrating"));
} else {
m_calibration_btn->Enable();
}
} else {
// IDLE
m_calibration_btn->SetLabel(_L("Start Calibration"));
// disable in printing
if (obj->is_in_printing()) {
m_calibration_btn->Disable();
} else {
m_calibration_btn->Enable();
}
}
}
void StatusPanel::update_subtask(MachineObject *obj)
void StatusPanel::update_left_time(int mc_left_time)
{
if (!obj) return;
if (!obj->is_in_printing()
|| obj->is_system_printing()
) {
reset_printing_values();
return;
}
// update button enable status
if (obj->can_abort()) {
m_button_abort->Enable();
} else {
m_button_abort->Enable(false);
}
if (obj->can_pause() || obj->can_resume()) {
m_button_pause_resume->Enable();
if (obj->can_resume())
m_button_pause_resume->SetLabel(_L("Resume"));
else
m_button_pause_resume->SetLabel(_L("Pause"));
} else {
m_button_pause_resume->Enable(false);
}
if (obj->is_sdcard_printing()) {
update_sdcard_subtask(obj);
} else {
update_cloud_subtask(obj);
}
// update gcode progress
std::string left_time;
wxString left_time_text = NA_STR;
try {
left_time = get_bbl_monitor_time_dhm(obj->mc_left_time);
left_time = get_bbl_monitor_time_dhm(mc_left_time);
} catch (...) {
;
}
@ -1463,12 +1528,57 @@ void StatusPanel::update_subtask(MachineObject *obj)
// update current subtask progress
m_staticText_progress_left->SetLabelText(left_time_text);
}
if (!obj->is_printing_finished()) {
// update printing stage
m_printing_stage_value->SetLabelText(obj->get_curr_stage());
void StatusPanel::update_subtask(MachineObject *obj)
{
if (!obj) return;
if (obj->is_system_printing()) {
reset_printing_values();
} else if (obj->is_in_printing() || obj->print_status == "FINISH") {
if (obj->is_in_prepare()) {
m_button_abort->Enable(false);
m_button_pause_resume->Enable(false);
m_button_pause_resume->SetLabel(_L("Pause"));
wxString prepare_text = wxString::Format(_L("Downloading..."));
if (obj->gcode_file_prepare_percent >= 0 && obj->gcode_file_prepare_percent <= 100)
prepare_text += wxString::Format("(%d%%)", obj->gcode_file_prepare_percent);
m_printing_stage_value->SetLabelText(prepare_text);
m_gauge_progress->SetValue(0);
m_staticText_progress_percent->SetLabelText(NA_STR);
m_staticText_progress_left->SetLabel(NA_STR);
m_staticText_progress_left->SetLabelText(NA_STR);
wxString subtask_text = wxString::Format("%s", GUI::from_u8(obj->subtask_name));
m_staticText_subtask_value->SetLabelText(subtask_text);
} else {
if (obj->can_resume())
m_button_pause_resume->SetLabel(_L("Resume"));
else
m_button_pause_resume->SetLabel(_L("Pause"));
m_button_abort->Enable(true);
m_button_pause_resume->Enable(true);
// update printing stage
m_printing_stage_value->SetLabelText(obj->get_curr_stage());
update_left_time(obj->mc_left_time);
if (obj->subtask_) {
m_gauge_progress->SetValue(obj->subtask_->task_progress);
m_staticText_progress_percent->SetLabelText(wxString::Format("%d%%", obj->subtask_->task_progress));
} else {
m_gauge_progress->SetValue(0);
m_staticText_progress_percent->SetLabelText(NA_STR);
}
}
wxString subtask_text = wxString::Format("%s", GUI::from_u8(obj->subtask_name));
m_staticText_subtask_value->SetLabelText(subtask_text);
//update thumbnail
if (obj->is_sdcard_printing()) {
update_sdcard_subtask(obj);
} else {
update_cloud_subtask(obj);
}
} else {
m_printing_stage_value->SetLabelText("");
reset_printing_values();
}
this->Layout();
@ -1505,42 +1615,28 @@ void StatusPanel::update_cloud_subtask(MachineObject *obj)
}
}
}
// update subtask name
wxString subtask_text;
subtask_text = wxString::Format("%s", GUI::from_u8(obj->subtask_name));
m_staticText_subtask_value->SetLabelText(subtask_text);
m_gauge_progress->SetValue(obj->subtask_->task_progress);
m_staticText_progress_percent->SetLabelText(wxString::Format("%d%%", obj->subtask_->task_progress));
}
void StatusPanel::update_sdcard_subtask(MachineObject *obj)
{
if (!obj) return;
wxString subtask_text = wxString::Format("%s", GUI::from_u8(obj->subtask_name));
m_staticText_subtask_value->SetLabelText(subtask_text);
if (!m_load_sdcard_thumbnail) {
m_bitmap_thumbnail->SetBitmap(m_thumbnail_sdcard);
m_load_sdcard_thumbnail = true;
}
m_gauge_progress->SetValue(obj->subtask_->task_progress);
m_staticText_progress_percent->SetLabelText(wxString::Format("%d%%", obj->subtask_->task_progress));
}
void StatusPanel::reset_printing_values()
{
m_button_pause_resume->Enable(false);
m_button_pause_resume->SetLabel(_L("Pause"));
m_button_abort->Enable(false);
m_gauge_progress->SetValue(0);
m_staticText_subtask_value->SetLabelText("N/A");
m_staticText_subtask_value->SetLabelText(NA_STR);
m_printing_stage_value->SetLabelText("");
m_staticText_progress_left->SetLabelText("N/A");
m_staticText_progress_percent->SetLabelText("N/A");
m_staticText_progress_left->SetLabelText(NA_STR);
m_staticText_progress_percent->SetLabelText(NA_STR);
m_bitmap_thumbnail->SetBitmap(m_thumbnail_placeholder);
m_start_loading_thumbnail = false;
m_load_sdcard_thumbnail = false;
@ -1602,7 +1698,7 @@ void StatusPanel::on_set_bed_temp()
try {
long bed_temp;
if (str.ToLong(&bed_temp) && obj) {
m_temp_bed_timeout = COMMAND_TIMEOUT;
set_hold_count(m_temp_bed_timeout);
obj->command_set_bed(bed_temp);
}
} catch (...) {
@ -1616,7 +1712,7 @@ void StatusPanel::on_set_nozzle_temp()
try {
long nozzle_temp;
if (str.ToLong(&nozzle_temp) && obj) {
m_temp_nozzle_timeout = COMMAND_TIMEOUT;
set_hold_count(m_temp_nozzle_timeout);
obj->command_set_nozzle(nozzle_temp);
}
} catch (...) {
@ -1719,16 +1815,53 @@ void StatusPanel::on_filament_edit(wxCommandEvent &event)
void StatusPanel::on_ams_refresh_rfid(wxCommandEvent &event)
{
if (obj) {
std::string tray_id = event.GetString().ToStdString();
obj->command_ams_refresh_rfid(tray_id);
std::string curr_ams_id = m_ams_control->GetCurentAms();
std::string curr_can_id = event.GetString().ToStdString();
std::map<std::string, Ams *>::iterator it = obj->amsList.find(curr_ams_id);
if (it == obj->amsList.end()) {
BOOST_LOG_TRIVIAL(trace) << "ams: find " << curr_ams_id << " failed";
return;
}
auto tray_it = it->second->trayList.find(curr_can_id);
if (tray_it == it->second->trayList.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_refresh_rfid(std::to_string(tray_index));
} catch (...) {
;
}
}
}
void StatusPanel::on_ams_selected(wxCommandEvent &event)
{
if (obj) {
std::string tray_id = event.GetString().ToStdString();
obj->command_ams_select_tray(tray_id);
std::string curr_ams_id = m_ams_control->GetCurentAms();
std::string curr_can_id = event.GetString().ToStdString();
std::map<std::string, Ams *>::iterator it = obj->amsList.find(curr_ams_id);
if (it == obj->amsList.end()) {
BOOST_LOG_TRIVIAL(trace) << "ams: find " << curr_ams_id << " failed";
return;
}
auto tray_it = it->second->trayList.find(curr_can_id);
if (tray_it == it->second->trayList.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 (...) {
;
}
}
}
@ -1795,7 +1928,7 @@ void StatusPanel::on_switch_speed(wxCommandEvent &event)
step->Bind(EVT_STEP_CHANGED, [this](auto &e) {
this->speed_lvl = e.GetInt() + 1;
if (obj) {
this-> speed_lvl_timeout = COMMAND_TIMEOUT;
set_hold_count(this->speed_lvl_timeout);
obj->command_set_printing_speed((PrintingSpeedLevel)this->speed_lvl);
}
});
@ -1819,11 +1952,11 @@ void StatusPanel::on_printing_fan_switch(wxCommandEvent &event)
if (value) {
obj->command_control_fan(MachineObject::FanType::BIG_COOLING_FAN, true);
m_switch_printing_fan->SetValue(true);
m_switch_printing_fan_timeout = COMMAND_TIMEOUT;
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);
m_switch_printing_fan_timeout = COMMAND_TIMEOUT;
set_hold_count(this->m_switch_printing_fan_timeout);
}
}
@ -1836,11 +1969,11 @@ void StatusPanel::on_nozzle_fan_switch(wxCommandEvent &event)
if (value) {
obj->command_control_fan(MachineObject::FanType::COOLING_FAN, true);
m_switch_nozzle_fan->SetValue(true);
m_switch_nozzle_fan_timeout = COMMAND_TIMEOUT;
set_hold_count(this->m_switch_nozzle_fan_timeout);
} else {
obj->command_control_fan(MachineObject::FanType::COOLING_FAN, false);
m_switch_nozzle_fan->SetValue(false);
m_switch_nozzle_fan_timeout = COMMAND_TIMEOUT;
set_hold_count(this->m_switch_nozzle_fan_timeout);
}
}
void StatusPanel::on_lamp_switch(wxCommandEvent &event)
@ -1852,11 +1985,11 @@ void StatusPanel::on_lamp_switch(wxCommandEvent &event)
if (value) {
m_switch_lamp->SetValue(true);
// do not update when timeout > 0
m_switch_lamp_timeout = COMMAND_TIMEOUT;
set_hold_count(this->m_switch_lamp_timeout);
obj->command_set_chamber_light(MachineObject::LIGHT_EFFECT::LIGHT_EFFECT_ON);
} else {
m_switch_lamp->SetValue(false);
m_switch_lamp_timeout = COMMAND_TIMEOUT;
set_hold_count(this->m_switch_lamp_timeout);
obj->command_set_chamber_light(MachineObject::LIGHT_EFFECT::LIGHT_EFFECT_OFF);
}
}
@ -1892,6 +2025,13 @@ 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_camera_enter(wxMouseEvent& event)
{
if (obj) {
@ -1962,11 +2102,11 @@ void StatusPanel::set_default()
m_switch_nozzle_fan_timeout = 0;
m_switch_printing_fan_timeout = 0;
m_show_ams_group = false;
reset_printing_values();
reset_temp_misc_control();
m_ams_control->Hide();
m_ams_control->Reset();
clean_tasklist_info();
}
@ -1975,14 +2115,29 @@ 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)) {
if (((status & (int) MonitorStatus::MONITOR_DISCONNECTED) != 0)
|| ((status & (int) MonitorStatus::MONITOR_DISCONNECTED_SERVER) != 0)
|| ((status & (int)MonitorStatus::MONITOR_CONNECTING) != 0)
) {
m_text_tasklist_caption->SetForegroundColour(DISCONNECT_TEXT_COL);
show_printing_status(false, false);
m_calibration_btn->Disable();
} else if ((status & (int) MonitorStatus::MONITOR_NORMAL) != 0) {
show_printing_status(true, true);
m_calibration_btn->Disable();
}
}
void StatusPanel::set_hold_count(int& count)
{
if (obj) {
if (obj->is_U0_firmware()) {
count = COMMAND_TIMEOUT_U0;
}
}
count = COMMAND_TIMEOUT;
}
void StatusPanel::msw_rescale()
{
init_bitmaps();
@ -2011,8 +2166,13 @@ void StatusPanel::msw_rescale()
slice_info_list[i]->msw_rescale();
}
m_bitmap_camera_img->SetBitmap(m_bitmap_camera);
m_bitmap_camera_img->SetMinSize(wxSize(FromDIP(32), FromDIP(18)));
//m_bitmap_camera_img->SetBitmap(m_bitmap_camera);
//m_bitmap_camera_img->SetMinSize(wxSize(FromDIP(32), FromDIP(18)));
m_timelapse_button->SetMinSize(wxSize(32, 24));
m_recording_button->SetMinSize(wxSize(32, 24));
m_bitmap_sdcard_off_img->SetMinSize(wxSize(FromDIP(32), FromDIP(20)));
m_bitmap_sdcard_on_img->SetMinSize(wxSize(FromDIP(32), FromDIP(20)));
m_bpButton_xy->Rescale();
m_tempCtrl_nozzle->SetMinSize(TEMP_CTRL_MIN_SIZE);
@ -2039,7 +2199,8 @@ void StatusPanel::msw_rescale()
m_ams_control->msw_rescale();
// m_filament_step->Rescale();
m_calibration_btn->SetMinSize(wxSize(FromDIP(128), FromDIP(26)));
m_calibration_btn->SetMinSize(wxSize(-1, FromDIP(26)));
m_calibration_btn->Rescale();
Layout();
Refresh();

View file

@ -30,17 +30,35 @@
class StepIndicator;
#define COMMAND_TIMEOUT 2
#define COMMAND_TIMEOUT_U0 15
#define COMMAND_TIMEOUT 5
namespace Slic3r {
namespace GUI {
enum MonitorStatus {
MONITOR_UNKNOWN = 0,
MONITOR_NORMAL = 1 << 1,
MONITOR_NO_PRINTER = 1 << 2,
MONITOR_DISCONNECTED = 1 << 3,
MONITOR_UNKNOWN = 0,
MONITOR_NORMAL = 1 << 1,
MONITOR_NO_PRINTER = 1 << 2,
MONITOR_DISCONNECTED = 1 << 3,
MONITOR_DISCONNECTED_SERVER = 1 << 4,
MONITOR_CONNECTING = 1 << 5,
};
enum CameraRecordingStatus {
RECORDING_NONE,
RECORDING_OFF_NORMAL,
RECORDING_OFF_HOVER,
RECORDING_ON_NORMAL,
RECORDING_ON_HOVER,
};
enum CameraTimelapseStatus {
TIMELAPSE_NONE,
TIMELAPSE_OFF_NORMAL,
TIMELAPSE_OFF_HOVER,
TIMELAPSE_ON_NORMAL,
TIMELAPSE_ON_HOVER,
};
class StatusBasePanel : public wxScrolledWindow
@ -60,7 +78,17 @@ protected:
wxBitmap m_bitmap_fan_on;
wxBitmap m_bitmap_fan_off;
wxBitmap m_bitmap_extruder;
CameraRecordingStatus m_state_recording{CameraRecordingStatus::RECORDING_NONE};
CameraTimelapseStatus m_state_timelapse{CameraTimelapseStatus::TIMELAPSE_NONE};
CameraItem *m_timelapse_button;
CameraItem *m_recording_button;
wxBitmap m_bitmap_camera;
wxBitmap m_bitmap_sdcard_state_on;
wxBitmap m_bitmap_sdcard_state_off;
/* title panel */
wxPanel * media_ctrl_panel;
@ -70,9 +98,13 @@ protected:
wxStaticText * m_staticText_monitoring;
wxStaticText * m_staticText_timelapse;
wxStaticBitmap* m_bitmap_camera_img;
SwitchButton * m_bmToggleBtn_timelapse;
wxStaticBitmap *m_bitmap_camera_img;
wxStaticBitmap *m_bitmap_recording_img;
wxStaticBitmap *m_bitmap_sdcard_on_img;
wxStaticBitmap *m_bitmap_sdcard_off_img;
wxMediaCtrl2 * m_media_ctrl;
MediaPlayCtrl * m_media_play_ctrl;
@ -186,6 +218,7 @@ public:
wxBoxSizer *create_ams_group(wxWindow *parent);
void show_ams_group(bool show = true);
void upodate_camera_state(bool recording, bool timelapse, bool has_sdcard);
};
@ -260,7 +293,8 @@ protected:
void on_nozzle_fan_switch(wxCommandEvent &event);
void on_thumbnail_enter(wxMouseEvent &event);
void on_thumbnail_leave(wxMouseEvent &event);
void on_camera_enter(wxMouseEvent& event);
void on_switch_recording(wxMouseEvent &event);
void on_camera_enter(wxMouseEvent &event);
void on_camera_leave(wxMouseEvent& event);
void on_auto_leveling(wxCommandEvent &event);
void on_xyz_abs(wxCommandEvent &event);
@ -272,11 +306,11 @@ protected:
/* update apis */
void update(MachineObject* obj);
void show_printing_status(bool ctrl_area = true, bool temp_area = true);
void update_left_time(int mc_left_time);
void update_subtask(MachineObject *obj);
void update_cloud_subtask(MachineObject *obj);
void update_sdcard_subtask(MachineObject *obj);
void update_temp_ctrl(MachineObject *obj);
void show_unload_ctrl();
void update_misc_ctrl(MachineObject *obj);
void update_ams(MachineObject* obj);
void update_cali(MachineObject* obj);
@ -311,10 +345,10 @@ public:
void set_default();
void show_status(int status);
void set_hold_count(int& count);
void msw_rescale();
};
}
}
#endif

View file

@ -1756,7 +1756,6 @@ void TabPrint::build()
optgroup->append_single_option_line("minimum_sparse_infill_area");
optgroup->append_single_option_line("infill_combination");
optgroup->append_single_option_line("detect_narrow_internal_solid_infill");
optgroup->append_single_option_line("reduce_infill_retraction");
page = add_options_page(L("Speed"), "empty");
optgroup = page->new_optgroup(L("Initial layer speed"), 15);
@ -1827,8 +1826,9 @@ void TabPrint::build()
//optgroup->append_single_option_line("support_interface_loop_pattern");
optgroup->append_single_option_line("support_object_xy_distance");
//optgroup->append_single_option_line("bridge_no_support");
optgroup->append_single_option_line("bridge_no_support");
optgroup->append_single_option_line("max_bridge_length");
optgroup->append_single_option_line("thick_bridges");
//optgroup->append_single_option_line("independent_support_layer_height");
page = add_options_page(L("Others"), "advanced");
@ -1852,6 +1852,7 @@ void TabPrint::build()
optgroup = page->new_optgroup(L("Flush options"));
optgroup->append_single_option_line("flush_into_infill");
optgroup->append_single_option_line("flush_into_objects");
optgroup->append_single_option_line("flush_into_support");
optgroup = page->new_optgroup(L("Special mode"));
optgroup->append_single_option_line("print_sequence");
@ -1875,7 +1876,8 @@ void TabPrint::build()
optgroup->append_single_option_line("fuzzy_skin_thickness");
optgroup = page->new_optgroup(L("Output file"));
optgroup = page->new_optgroup(L("G-code output"));
optgroup->append_single_option_line("reduce_infill_retraction");
optgroup->append_single_option_line("gcode_add_line_number");
Option option = optgroup->get_option("filename_format");
option.opt.full_width = true;

View file

@ -17,8 +17,8 @@ wxDEFINE_EVENT(wxCUSTOMEVT_TABBOOK_SEL_CHANGED, wxCommandEvent);
const static wxColour TAB_BUTTON_BG = wxColour(255, 255, 255, 255);
const static wxColour TAB_BUTTON_SEL = wxColour(219, 253, 213, 255);
static const wxFont TAB_BUTTON_FONT = Label::Body_14;
static const wxFont TAB_BUTTON_FONT_SEL = Label::Head_14;
static const wxFont& TAB_BUTTON_FONT = Label::Body_14;
static const wxFont& TAB_BUTTON_FONT_SEL = Label::Head_14;
static const int BUTTON_DEF_HEIGHT = 46;

View file

@ -1188,9 +1188,10 @@ static wxString get_string_value(std::string opt_key, const DynamicPrintConfig&
int orig_opt_idx = -1;
int opt_idx = -1;
int pos = opt_key.find("#");
std::string temp_str = opt_key;
if (pos > 0) {
boost::erase_head(opt_key, pos + 1);
orig_opt_idx = static_cast<size_t>(atoi(opt_key.c_str()));
boost::erase_head(temp_str, pos + 1);
orig_opt_idx = static_cast<size_t>(atoi(temp_str.c_str()));
}
opt_idx = orig_opt_idx >= 0 ? orig_opt_idx : 0;
opt_key = get_pure_opt_key(opt_key);

View file

@ -141,7 +141,7 @@ MsgUpdateConfig::MsgUpdateConfig(const std::vector<Update> &updates, bool force_
sizer_button->Add(0, 0, 1, wxEXPAND, 5);
StateColor btn_bg_green(std::pair<wxColour, int>(wxColour(27, 136, 68), StateColor::Pressed),
StateColor btn_bg_green(std::pair<wxColour, int>(wxColour(27, 136, 68), StateColor::Pressed),
std::pair<wxColour, int>(wxColour(61, 203, 115), StateColor::Hovered), std::pair<wxColour, int>(AMS_CONTROL_BRAND_COLOUR, StateColor::Normal));
StateColor btn_bg_white(std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Pressed),

View file

@ -1,352 +0,0 @@
#include "WebDailytipDialog.hpp"
#include <string.h>
#include "I18N.hpp"
#include "libslic3r/AppConfig.hpp"
#include "slic3r/GUI/wxExtensions.hpp"
#include "slic3r/GUI/GUI_App.hpp"
#include "libslic3r_version.h"
#include <wx/sizer.h>
#include <wx/toolbar.h>
#include <wx/textdlg.h>
#include <wx/wx.h>
#include <wx/fileconf.h>
#include <wx/file.h>
#include <wx/wfstream.h>
#include <boost/cast.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/dll.hpp>
#include <nlohmann/json.hpp>
#include <slic3r/GUI/Widgets/WebView.hpp>
using namespace nlohmann;
namespace Slic3r { namespace GUI {
// BEGIN_EVENT_TABLE(DailytipFrame,wxCheckBox)
// EVT_CHECKBOX(SKIP_CHECKBOX, DailytipFrame::OnSkipClick)
// END_EVENT_TABLE()
DailytipFrame::DailytipFrame(GUI_App *pGUI)
: wxDialog((wxWindow *) (pGUI->mainframe), wxID_ANY, "BambuStudio")
{
wxString ExePath = boost::dll::program_location().parent_path().string();
wxString TargetUrl = "file:///" + ExePath + "\\resources\\dailytip\\index.html";
m_MainPtr = pGUI;
wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
// Create the webview
m_browser = WebView::CreateWebView(this, TargetUrl);
if (m_browser == nullptr) {
wxLogError("Could not init m_browser");
return;
}
topsizer->Add(m_browser, wxSizerFlags().Expand().Proportion(1));
SetSizer(topsizer);
#ifdef __WXMAC__
// With WKWebView handlers need to be registered before creation
m_browser->RegisterHandler(
wxSharedPtr<wxWebViewHandler>(new wxWebViewArchiveHandler("wxfs")));
m_browser->RegisterHandler(
wxSharedPtr<wxWebViewHandler>(new wxWebViewFSHandler("memory")));
#endif
// topsizer->Add(m_browser, wxSizerFlags().Expand().Proportion(1));
// Set a more sensible size for web browsing
m_browser->SetSize(FromDIP(wxSize(560, 640)));
SetSize(FromDIP(wxSize(560, 710)));
// Connect the webview events
Bind(wxEVT_WEBVIEW_NAVIGATING, &DailytipFrame::OnNavigationRequest, this,
m_browser->GetId());
Bind(wxEVT_WEBVIEW_NAVIGATED, &DailytipFrame::OnNavigationComplete, this,
m_browser->GetId());
Bind(wxEVT_WEBVIEW_LOADED, &DailytipFrame::OnDocumentLoaded, this,
m_browser->GetId());
Bind(wxEVT_WEBVIEW_ERROR, &DailytipFrame::OnError, this,
m_browser->GetId());
Bind(wxEVT_WEBVIEW_NEWWINDOW, &DailytipFrame::OnNewWindow, this,
m_browser->GetId());
Bind(wxEVT_WEBVIEW_TITLE_CHANGED, &DailytipFrame::OnTitleChanged, this,
m_browser->GetId());
Bind(wxEVT_WEBVIEW_FULLSCREEN_CHANGED,
&DailytipFrame::OnFullScreenChanged, this, m_browser->GetId());
Bind(wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED,
&DailytipFrame::OnScriptMessage, this, m_browser->GetId());
// Connect the idle events
// Bind(wxEVT_IDLE, &DailytipFrame::OnIdle, this);
// Bind(wxEVT_CLOSE_WINDOW, &DailytipFrame::OnClose, this);
// UI
SetTitle(L"Daily Tip");
CenterOnParent();
// INI
m_SectionName = "dailytip";
// Skip CheckBox
m_SkipBtn = new wxCheckBox(this, wxID_ANY, L"Never Show",
FromDIP(wxPoint(10, 640)),
FromDIP(wxSize(200, 30)));
Bind(wxEVT_CHECKBOX, &DailytipFrame::OnSkipClick, this,
m_SkipBtn->GetId());
}
DailytipFrame::~DailytipFrame() {}
void DailytipFrame::load_url(wxString &url)
{
this->Show();
m_browser->LoadURL(url);
m_browser->SetFocus();
UpdateState();
}
/**
* Method that retrieves the current state from the web control and updates
* the GUI the reflect this current state.
*/
void DailytipFrame::UpdateState()
{
// SetTitle(m_browser->GetCurrentTitle());
}
void DailytipFrame::OnIdle(wxIdleEvent &WXUNUSED(evt))
{
if (m_browser->IsBusy()) {
wxSetCursor(wxCURSOR_ARROWWAIT);
} else {
wxSetCursor(wxNullCursor);
}
}
/**
* Callback invoked when there is a request to load a new page (for instance
* when the user clicks a link)
*/
void DailytipFrame::OnNavigationRequest(wxWebViewEvent &evt)
{
// wxLogMessage("%s", "Navigation request to '" + evt.GetURL() + "'
// (target='" + evt.GetTarget() + "')");
UpdateState();
}
/**
* Callback invoked when a navigation request was accepted
*/
void DailytipFrame::OnNavigationComplete(wxWebViewEvent &evt)
{
// wxLogMessage("%s", "Navigation complete; url='" + evt.GetURL() + "'");
UpdateState();
}
/**
* Callback invoked when a page is finished loading
*/
void DailytipFrame::OnDocumentLoaded(wxWebViewEvent &evt)
{
UpdateShowTime();
// Only notify if the document is the main frame, not a subframe
wxString tmpUrl = evt.GetURL();
wxString NowUrl = m_browser->GetCurrentURL();
if (evt.GetURL() == m_browser->GetCurrentURL()) {
// wxLogMessage("%s", "Document loaded; url='" + evt.GetURL() + "'");
}
UpdateState();
// wxCommandEvent *event = new
// wxCommandEvent(EVT_WEB_RESPONSE_MESSAGE,this->GetId());
// wxQueueEvent(this, event);
}
/**
* On new window, we veto to stop extra windows appearing
*/
void DailytipFrame::OnNewWindow(wxWebViewEvent &evt)
{
wxString flag = " (other)";
if (evt.GetNavigationAction() == wxWEBVIEW_NAV_ACTION_USER) {
flag = " (user)";
}
// wxLogMessage("%s", "New window; url='" + evt.GetURL() + "'" + flag);
// If we handle new window events then just load them in this window as we
// are a single window browser
// if (m_tools_handle_new_window->IsChecked())
// m_browser->LoadURL(evt.GetURL());
UpdateState();
}
void DailytipFrame::OnTitleChanged(wxWebViewEvent &evt)
{
// SetTitle(evt.GetString());
// wxLogMessage("%s", "Title changed; title='" + evt.GetString() + "'");
}
void DailytipFrame::OnFullScreenChanged(wxWebViewEvent &evt)
{
// wxLogMessage("Full screen changed; status = %d", evt.GetInt());
ShowFullScreen(evt.GetInt() != 0);
}
void DailytipFrame::OnScriptMessage(wxWebViewEvent &evt)
{
;
}
void DailytipFrame::RunScript(const wxString &javascript)
{
// Remember the script we run in any case, so the next time the user opens
// the "Run Script" dialog box, it is shown there for convenient updating.
m_javascript = javascript;
// wxLogMessage("Running JavaScript:\n%s\n", javascript);
if (!m_browser) return;
WebView::RunScript(m_browser, javascript);
}
#if wxUSE_WEBVIEW_IE
void DailytipFrame::OnRunScriptObjectWithEmulationLevel(
wxCommandEvent &WXUNUSED(evt))
{
wxWebViewIE::MSWSetModernEmulationLevel();
RunScript("function f(){var person = new Object();person.name = 'Foo'; \
person.lastName = 'Bar';return person;}f();");
wxWebViewIE::MSWSetModernEmulationLevel(false);
}
void DailytipFrame::OnRunScriptDateWithEmulationLevel(
wxCommandEvent &WXUNUSED(evt))
{
wxWebViewIE::MSWSetModernEmulationLevel();
RunScript("function f(){var d = new Date('10/08/2017 21:30:40'); \
var tzoffset = d.getTimezoneOffset() * 60000; return \
new Date(d.getTime() - tzoffset);}f();");
wxWebViewIE::MSWSetModernEmulationLevel(false);
}
void DailytipFrame::OnRunScriptArrayWithEmulationLevel(
wxCommandEvent &WXUNUSED(evt))
{
wxWebViewIE::MSWSetModernEmulationLevel();
RunScript("function f(){ return [\"foo\", \"bar\"]; }f();");
wxWebViewIE::MSWSetModernEmulationLevel(false);
}
#endif
/**
* Callback invoked when a loading error occurs
*/
void DailytipFrame::OnError(wxWebViewEvent &evt)
{
#define WX_ERROR_CASE(type) \
case type: category = #type; break;
wxString category;
switch (evt.GetInt()) {
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_CONNECTION);
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_CERTIFICATE);
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_AUTH);
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_SECURITY);
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_NOT_FOUND);
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_REQUEST);
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_USER_CANCELLED);
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_OTHER);
}
// wxLogMessage("%s", "Error; url='" + evt.GetURL() + "', error='" +
// category + " (" + evt.GetString() + ")'");
// Show the info bar with an error
// m_info->ShowMessage(_L("An error occurred loading ") + evt.GetURL() +
// "\n" + "'" + category + "'", wxICON_ERROR);
UpdateState();
}
void DailytipFrame::OnScriptResponseMessage(wxCommandEvent &WXUNUSED(evt))
{
// if (!m_response_js.empty())
//{
// RunScript(m_response_js);
//}
// RunScript("This is a message to Web!");
// RunScript("postMessage(\"AABBCCDD\");");
}
bool DailytipFrame::IsTodayUsed()
{
std::string strTime =
wxGetApp().app_config->get(std::string(m_SectionName.mbc_str()),
"lasttime");
int nLastTime = wxAtol(strTime);
int NowTime = std::time(0);
int T1 = NowTime - NowTime % 86400;
int T2 = T1 + 86400;
if (nLastTime >= T1 && nLastTime < T2) return true;
return false;
}
bool DailytipFrame::IsSkip()
{
wxString strSkip = wxGetApp().app_config->get(std::string(
m_SectionName.mbc_str()),
"skip");
if (strSkip == "1") return true;
return false;
}
bool DailytipFrame::IsWhetherShow()
{
if (IsSkip() || IsTodayUsed()) return false;
return true;
}
void DailytipFrame::UpdateShowTime()
{
int NowTime = std::time(0);
wxGetApp().app_config->set(std::string(m_SectionName.mbc_str()),
"lasttime", std::to_string(NowTime));
wxGetApp().app_config->save();
}
void DailytipFrame::OnSkipClick(wxCommandEvent &evt)
{
bool bSelect = m_SkipBtn->GetValue();
int nVal = 0;
if (bSelect) nVal = 1;
// wxMessageBox(wxString::Format(wxT("%i"), nVal), "Checkbox Value", MB_OK);
wxGetApp().app_config->set(std::string(m_SectionName.mbc_str()), "skip",
std::to_string(nVal));
wxGetApp().app_config->save();
}
}} // namespace Slic3r::GUI

View file

@ -0,0 +1,339 @@
#include "WebDownPluginDlg.hpp"
#include "ConfigWizard.hpp"
#include <string.h>
#include "I18N.hpp"
#include "libslic3r/AppConfig.hpp"
#include "slic3r/GUI/wxExtensions.hpp"
#include "slic3r/GUI/GUI_App.hpp"
#include "libslic3r_version.h"
#include <wx/sizer.h>
#include <wx/toolbar.h>
#include <wx/textdlg.h>
#include <wx/wx.h>
#include <wx/fileconf.h>
#include <wx/file.h>
#include <wx/wfstream.h>
#include <boost/cast.hpp>
#include <boost/lexical_cast.hpp>
#include "MainFrame.hpp"
#include <boost/dll.hpp>
#include <slic3r/GUI/Widgets/WebView.hpp>
#include <slic3r/Utils/Http.hpp>
#include <libslic3r/miniz_extension.hpp>
#include <libslic3r/Utils.hpp>
using namespace nlohmann;
namespace Slic3r { namespace GUI {
DownPluginFrame::DownPluginFrame(GUI_App *pGUI) : wxDialog((wxWindow *) (pGUI->mainframe), wxID_ANY, "Bambu Studio"), m_appconfig_new()
{
// INI
m_MainPtr = pGUI;
// set the frame icon
wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
wxString TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/6/index.html").make_preferred().string());
TargetUrl = "file://" + TargetUrl;
// Create the webview
m_browser = WebView::CreateWebView(this, TargetUrl);
if (m_browser == nullptr) {
wxLogError("Could not init m_browser");
return;
}
SetSizer(topsizer);
topsizer->Add(m_browser, wxSizerFlags().Expand().Proportion(1));
// Log backend information
// wxLogMessage(wxWebView::GetBackendVersionInfo().ToString());
// wxLogMessage("Backend: %s Version: %s",
// m_browser->GetClassInfo()->GetClassName(),wxWebView::GetBackendVersionInfo().ToString());
// wxLogMessage("User Agent: %s", m_browser->GetUserAgent());
// Set a more sensible size for web browsing
wxSize pSize = FromDIP(wxSize(410, 200));
SetSize(pSize);
CenterOnParent();
// int screenheight = wxSystemSettings::GetMetric(wxSYS_SCREEN_Y, NULL);
// int screenwidth = wxSystemSettings::GetMetric(wxSYS_SCREEN_X, NULL);
// int MaxY = (screenheight - pSize.y) > 0 ? (screenheight - pSize.y) / 2 : 0;
// MoveWindow(this->m_hWnd, (screenwidth - pSize.x) / 2, MaxY, pSize.x, pSize.y, TRUE);
// Connect the webview events
Bind(wxEVT_WEBVIEW_NAVIGATING, &DownPluginFrame::OnNavigationRequest, this, m_browser->GetId());
Bind(wxEVT_WEBVIEW_NAVIGATED, &DownPluginFrame::OnNavigationComplete, this, m_browser->GetId());
Bind(wxEVT_WEBVIEW_LOADED, &DownPluginFrame::OnDocumentLoaded, this, m_browser->GetId());
Bind(wxEVT_WEBVIEW_ERROR, &DownPluginFrame::OnError, this, m_browser->GetId());
Bind(wxEVT_WEBVIEW_NEWWINDOW, &DownPluginFrame::OnNewWindow, this, m_browser->GetId());
Bind(wxEVT_WEBVIEW_TITLE_CHANGED, &DownPluginFrame::OnTitleChanged, this, m_browser->GetId());
Bind(wxEVT_WEBVIEW_FULLSCREEN_CHANGED, &DownPluginFrame::OnFullScreenChanged, this, m_browser->GetId());
Bind(wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, &DownPluginFrame::OnScriptMessage, this, m_browser->GetId());
}
DownPluginFrame::~DownPluginFrame()
{
if (m_browser) {
delete m_browser;
m_browser = nullptr;
}
}
void DownPluginFrame::load_url(wxString &url)
{
BOOST_LOG_TRIVIAL(trace) << "app_start: DownPluginFrame url=" << url.ToStdString();
this->Show();
m_browser->LoadURL(url);
m_browser->SetFocus();
UpdateState();
}
/**
* Method that retrieves the current state from the web control and updates
* the GUI the reflect this current state.
*/
void DownPluginFrame::UpdateState()
{
// SetTitle(m_browser->GetCurrentTitle());
}
void DownPluginFrame::OnIdle(wxIdleEvent &WXUNUSED(evt))
{
if (m_browser->IsBusy()) {
wxSetCursor(wxCURSOR_ARROWWAIT);
} else {
wxSetCursor(wxNullCursor);
}
}
// void DownPluginFrame::OnClose(wxCloseEvent& evt)
//{
// this->Hide();
//}
/**
* Callback invoked when there is a request to load a new page (for instance
* when the user clicks a link)
*/
void DownPluginFrame::OnNavigationRequest(wxWebViewEvent &evt)
{
// wxLogMessage("%s", "Navigation request to '" + evt.GetURL() + "'
// (target='" + evt.GetTarget() + "')");
UpdateState();
}
/**
* Callback invoked when a navigation request was accepted
*/
void DownPluginFrame::OnNavigationComplete(wxWebViewEvent &evt)
{
// wxLogMessage("%s", "Navigation complete; url='" + evt.GetURL() + "'");
wxString NewUrl = evt.GetURL();
UpdateState();
}
/**
* Callback invoked when a page is finished loading
*/
void DownPluginFrame::OnDocumentLoaded(wxWebViewEvent &evt)
{
// Only notify if the document is the main frame, not a subframe
wxString tmpUrl = evt.GetURL();
wxString NowUrl = m_browser->GetCurrentURL();
if (evt.GetURL() == m_browser->GetCurrentURL()) {
// wxLogMessage("%s", "Document loaded; url='" + evt.GetURL() + "'");
}
UpdateState();
// wxCommandEvent *event = new
// wxCommandEvent(EVT_WEB_RESPONSE_MESSAGE,this->GetId()); wxQueueEvent(this,
// event);
}
/**
* On new window, we veto to stop extra windows appearing
*/
void DownPluginFrame::OnNewWindow(wxWebViewEvent &evt)
{
wxString flag = " (other)";
wxString NewUrl = evt.GetURL();
wxLaunchDefaultBrowser(NewUrl);
// if (evt.GetNavigationAction() == wxWEBVIEW_NAV_ACTION_USER) { flag = " (user)"; }
// wxLogMessage("%s", "New window; url='" + evt.GetURL() + "'" + flag);
// If we handle new window events then just load them in this window as we
// are a single window browser
// if (m_tools_handle_new_window->IsChecked())
// m_browser->LoadURL(evt.GetURL());
UpdateState();
}
void DownPluginFrame::OnTitleChanged(wxWebViewEvent &evt)
{
// SetTitle(evt.GetString());
// wxLogMessage("%s", "Title changed; title='" + evt.GetString() + "'");
}
void DownPluginFrame::OnFullScreenChanged(wxWebViewEvent &evt)
{
// wxLogMessage("Full screen changed; status = %d", evt.GetInt());
ShowFullScreen(evt.GetInt() != 0);
}
void DownPluginFrame::OnScriptMessage(wxWebViewEvent &evt)
{
try {
wxString strInput = evt.GetString();
json j = json::parse(strInput);
wxString strCmd = j["command"];
if (strCmd == "Begin_Download_network_plugin") {
wxGetApp().CallAfter([this] { DownloadPlugin(); });
}
else if (strCmd == "netplugin_download_cancel") {
wxGetApp().cancel_networking_install();
this->EndModal(wxID_CANCEL);
this->Close();
}
else if (strCmd == "begin_install_plugin") {
wxGetApp().CallAfter([this] { InstallPlugin(); });
}
else if (strCmd == "restart_studio") {
wxGetApp().restart_networking();
this->EndModal(wxID_OK);
this->Close();
}
else if (strCmd == "close_download_dialog") {
this->EndModal(wxID_OK);
this->Close();
}
else if (strCmd == "open_plugin_folder") {
auto plugin_folder = (boost::filesystem::path(wxStandardPaths::Get().GetUserDataDir().ToUTF8().data()) / "plugins").make_preferred().string();
desktop_open_any_folder(plugin_folder);
}
} catch (std::exception &e) {
// wxMessageBox(e.what(), "json Exception", MB_OK);
}
}
void DownPluginFrame::RunScript(const wxString &javascript)
{
// Remember the script we run in any case, so the next time the user opens
// the "Run Script" dialog box, it is shown there for convenient updating.
// m_javascript = javascript;
// wxLogMessage("Running JavaScript:\n%s\n", javascript);
if (!m_browser) return;
WebView::RunScript(m_browser, javascript);
}
#if wxUSE_WEBVIEW_IE
void DownPluginFrame::OnRunScriptObjectWithEmulationLevel(wxCommandEvent &WXUNUSED(evt))
{
wxWebViewIE::MSWSetModernEmulationLevel();
RunScript("function f(){var person = new Object();person.name = 'Foo'; \
person.lastName = 'Bar';return person;}f();");
wxWebViewIE::MSWSetModernEmulationLevel(false);
}
void DownPluginFrame::OnRunScriptDateWithEmulationLevel(wxCommandEvent &WXUNUSED(evt))
{
wxWebViewIE::MSWSetModernEmulationLevel();
RunScript("function f(){var d = new Date('10/08/2017 21:30:40'); \
var tzoffset = d.getTimezoneOffset() * 60000; return \
new Date(d.getTime() - tzoffset);}f();");
wxWebViewIE::MSWSetModernEmulationLevel(false);
}
void DownPluginFrame::OnRunScriptArrayWithEmulationLevel(wxCommandEvent &WXUNUSED(evt))
{
wxWebViewIE::MSWSetModernEmulationLevel();
RunScript("function f(){ return [\"foo\", \"bar\"]; }f();");
wxWebViewIE::MSWSetModernEmulationLevel(false);
}
#endif
/**
* Callback invoked when a loading error occurs
*/
void DownPluginFrame::OnError(wxWebViewEvent &evt)
{
#define WX_ERROR_CASE(type) \
case type: category = #type; break;
wxString category;
switch (evt.GetInt()) {
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_CONNECTION);
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_CERTIFICATE);
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_AUTH);
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_SECURITY);
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_NOT_FOUND);
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_REQUEST);
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_USER_CANCELLED);
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_OTHER);
}
// wxLogMessage("%s", "Error; url='" + evt.GetURL() + "', error='" +
// category + " (" + evt.GetString() + ")'");
// Show the info bar with an error
// m_info->ShowMessage(_L("An error occurred loading ") + evt.GetURL() +
// "\n" + "'" + category + "'", wxICON_ERROR);
BOOST_LOG_TRIVIAL(info) << "DownPluginFrame::OnError: An error occurred loading " << evt.GetURL() << category;
UpdateState();
}
void DownPluginFrame::OnScriptResponseMessage(wxCommandEvent &WXUNUSED(evt))
{
}
int DownPluginFrame::DownloadPlugin()
{
return wxGetApp().download_plugin([this](int status, int percent, bool &cancel) { return ShowPluginStatus(status, percent, cancel); }, nullptr);
}
int DownPluginFrame::InstallPlugin()
{
return wxGetApp().install_plugin([this](int status, int percent, bool &cancel) { return ShowPluginStatus(status, percent, cancel); });
}
int DownPluginFrame::ShowPluginStatus(int status, int percent, bool &cancel)
{
// TODO
json m_Data = json::object();
m_Data["status"] = status;
m_Data["percent"] = percent;
json m_Res = json::object();
m_Res["command"] = "ShowStatusPercent";
m_Res["sequence_id"] = "10001";
m_Res["data"] = m_Data;
wxString strJS = wxString::Format("HandleStudio(%s)", m_Res.dump(-1, ' ', false, json::error_handler_t::ignore));
wxGetApp().CallAfter([this, strJS] { RunScript(strJS); });
return 0;
}
}} // namespace Slic3r::GUI

View file

@ -30,15 +30,15 @@
namespace Slic3r { namespace GUI {
enum { SKIP_CHECKBOX };
class DailytipFrame : public wxDialog
class DownPluginFrame : public wxDialog
{
public:
DailytipFrame(GUI_App *pGUI);
virtual ~DailytipFrame();
DownPluginFrame(GUI_App *pGUI);
virtual ~DownPluginFrame();
void load_url(wxString &url);
// Web Function
void load_url(wxString &url);
void UpdateState();
void OnIdle(wxIdleEvent &evt);
@ -56,23 +56,16 @@ public:
void OnScriptResponseMessage(wxCommandEvent &evt);
void RunScript(const wxString &javascript);
bool IsTodayUsed();
bool IsSkip();
bool IsWhetherShow();
void UpdateShowTime();
void OnSkipClick(wxCommandEvent &evt);
// install plugin
int DownloadPlugin();
int InstallPlugin();
int ShowPluginStatus(int status, int percent, bool &cancel);
private:
GUI_App *m_MainPtr;
GUI_App * m_MainPtr;
AppConfig m_appconfig_new;
wxWebView * m_browser;
wxCheckBox *m_SkipBtn;
wxString m_SectionName;
// User Config
bool PrivacyUse;
wxWebView *m_browser;
#if wxUSE_WEBVIEW_IE
wxMenuItem *m_script_object_el;

View file

@ -23,7 +23,9 @@
#include "MainFrame.hpp"
#include <boost/dll.hpp>
#include <slic3r/GUI/Widgets/WebView.hpp>
#include <slic3r/Utils/Http.hpp>
#include <libslic3r/miniz_extension.hpp>
#include <libslic3r/Utils.hpp>
using namespace nlohmann;
@ -38,14 +40,15 @@ GuideFrame::GuideFrame(GUI_App *pGUI, long style)
// INI
m_SectionName = "firstguide";
PrivacyUse = true;
InstallNetplugin = false;
m_MainPtr = pGUI;
// set the frame icon
wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", set start page to welcome");
wxString TargetUrl = SetStartPage(BBL_WELCOME, false);
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", set start page to welcome ") << TargetUrl;
// Create the webview
m_browser = WebView::CreateWebView(this, TargetUrl);
@ -350,7 +353,9 @@ void GuideFrame::OnScriptMessage(wxWebViewEvent &evt)
}
this->EndModal(wxID_OK);
//this->Close();
if (InstallNetplugin)
GUI::wxGetApp().CallAfter([this] { GUI::wxGetApp().ShowDownNetPluginDlg(); });
if (bLogin)
GUI::wxGetApp().CallAfter([this] { login(); });
@ -360,6 +365,14 @@ void GuideFrame::OnScriptMessage(wxWebViewEvent &evt)
this->Close();
} else if (strCmd == "save_region") {
m_Region = j["region"];
}
else if (strCmd == "network_plugin_install") {
std::string sAction = j["data"]["action"];
if (sAction == "yes")
InstallNetplugin = true;
else
InstallNetplugin = false;
}
} catch (std::exception &e) {
// wxMessageBox(e.what(), "json Exception", MB_OK);
@ -433,6 +446,7 @@ void GuideFrame::OnError(wxWebViewEvent &evt)
// Show the info bar with an error
// m_info->ShowMessage(_L("An error occurred loading ") + evt.GetURL() +
// "\n" + "'" + category + "'", wxICON_ERROR);
BOOST_LOG_TRIVIAL(info) << "GuideFrame::OnError: An error occurred loading " << evt.GetURL() << category;
UpdateState();
}
@ -911,8 +925,10 @@ int GuideFrame::LoadProfile()
//----region
m_Region = wxGetApp().app_config->get("region");
m_ProfileJson["region"] = m_Region;
}
m_ProfileJson["network_plugin_install"] = wxGetApp().app_config->get("app","installed_networking");
m_ProfileJson["network_plugin_compability"] = wxGetApp().is_compatibility_version() ? "1" : "0";
}
catch (std::exception &e) {
//wxLogMessage("GUIDE: load_profile_error %s ", e.what());
// wxMessageBox(e.what(), "", MB_OK);
@ -926,6 +942,18 @@ int GuideFrame::LoadProfile()
return 0;
}
void StringReplace(string &strBase, string strSrc, string strDes)
{
string::size_type pos = 0;
string::size_type srcLen = strSrc.size();
string::size_type desLen = strDes.size();
pos = strBase.find(strSrc, pos);
while ((pos != string::npos)) {
strBase.replace(pos, srcLen, strDes);
pos = strBase.find(strSrc, (pos + desLen));
}
}
int GuideFrame::LoadProfileFamily(std::string strVendor, std::string strFilePath)
{
@ -968,7 +996,9 @@ int GuideFrame::LoadProfileFamily(std::string strVendor, std::string strFilePath
//wxLogMessage("GUIDE: json_path2 loaded");
OneModel["vendor"] = strVendor;
OneModel["nozzle_diameter"] = pm["nozzle_diameter"];
std::string NozzleOpt = pm["nozzle_diameter"];
StringReplace(NozzleOpt, " ", "");
OneModel["nozzle_diameter"] = NozzleOpt;
OneModel["materials"] = pm["default_materials"];
//wxString strCoverPath = wxString::Format("%s\\%s\\%s_cover.png", strFolder, strVendor, std::string(s1.mb_str()));
@ -1144,6 +1174,30 @@ bool GuideFrame::LoadFile(std::string jPath, std::string &sContent)
return true;
}
int GuideFrame::DownloadPlugin()
{
return wxGetApp().download_plugin(
[this](int status, int percent, bool& cancel) {
return ShowPluginStatus(status, percent, cancel);
}
, nullptr);
}
int GuideFrame::InstallPlugin()
{
return wxGetApp().install_plugin(
[this](int status, int percent, bool &cancel) {
return ShowPluginStatus(status, percent, cancel);
}
);
}
int GuideFrame::ShowPluginStatus(int status, int percent, bool& cancel)
{
//TODO
return 0;
}
}} // namespace Slic3r::GUI

View file

@ -87,6 +87,11 @@ public:
void GetStardardFilePath(std::string &FilePath);
bool LoadFile(std::string jPath, std::string & sContent);
// install plugin
int DownloadPlugin();
int InstallPlugin();
int ShowPluginStatus(int status, int percent, bool &cancel);
private:
GUI_App *m_MainPtr;
AppConfig m_appconfig_new;
@ -104,6 +109,8 @@ private:
bool PrivacyUse;
std::string m_Region;
bool InstallNetplugin;
#if wxUSE_WEBVIEW_IE
wxMenuItem *m_script_object_el;
wxMenuItem *m_script_date_el;

View file

View file

View file

@ -421,6 +421,27 @@ void WebViewPanel::SendLoginInfo()
}
}
void WebViewPanel::ShowNetpluginTip()
{
// Install Network Plugin
//std::string NP_Installed = wxGetApp().app_config->get("installed_networking");
bool bValid = wxGetApp().is_compatibility_version();
int nShow = 0;
if (!bValid) nShow = 1;
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": bValid=%1%, nShow=%2%")%bValid %nShow;
json m_Res = json::object();
m_Res["command"] = "network_plugin_installtip";
m_Res["sequence_id"] = "10001";
m_Res["show"] = nShow;
wxString strJS = wxString::Format("window.postMessage(%s)", m_Res.dump(-1, ' ', false, json::error_handler_t::ignore));
RunScript(strJS);
}
void WebViewPanel::update_mode()
{
int app_mode = Slic3r::GUI::wxGetApp().get_mode();
@ -486,6 +507,7 @@ void WebViewPanel::OnDocumentLoaded(wxWebViewEvent& evt)
wxLogMessage("%s", "Document loaded; url='" + evt.GetURL() + "'");
}
UpdateState();
ShowNetpluginTip();
}
void WebViewPanel::OnTitleChanged(wxWebViewEvent &evt)

View file

@ -92,6 +92,7 @@ public:
public:
void SendRecentList(wxString const &sequence_id);
void SendLoginInfo();
void ShowNetpluginTip();
void update_mode();
private:

View file

@ -14,14 +14,14 @@ static const int UNLOAD_STEP_COUNT = 3;
static const wxColour AMS_TRAY_DEFAULT_COL = wxColour(255, 255, 255);
static wxString FILAMENT_LOAD_STEP_STRING[LOAD_STEP_COUNT] = {
_L("Heat the nozzle to target \ntemperature"),
_L("Heat the nozzle to target temperature"),
_L("Cut filament"),
_L("Pull back current filament"),
_L("Push new filament \ninto extruder"),
_L("Push new filament into extruder"),
_L("Purge old filament"),
};
static wxString FILAMENT_UNLOAD_STEP_STRING[UNLOAD_STEP_COUNT] = {_L("Heat the nozzle to target \ntemperature"), _L("Cut filament"), _L("Pull back current filament")};
static wxString FILAMENT_UNLOAD_STEP_STRING[UNLOAD_STEP_COUNT] = {_L("Heat the nozzle to target temperature"), _L("Cut filament"), _L("Pull back current filament")};
wxDEFINE_EVENT(EVT_AMS_LOAD, SimpleEvent);
wxDEFINE_EVENT(EVT_AMS_UNLOAD, SimpleEvent);
@ -1138,13 +1138,6 @@ void AmsCans::SelectCan(std::string canid)
void AmsCans::SetAmsStep(wxString canid, AMSPassRoadType type, AMSPassRoadSTEP step)
{
auto tag_can_index = -1;
for (auto i = 0; i < m_can_road_list.GetCount(); i++) {
CanRoads *road = m_can_road_list[i];
if (canid == road->canRoad->m_info.can_id) { tag_can_index = road->canRoad->m_canindex; }
}
if (tag_can_index == -1) return;
if (step == AMSPassRoadSTEP::AMS_ROAD_STEP_NONE) {
for (auto i = 0; i < m_can_road_list.GetCount(); i++) {
@ -1157,6 +1150,14 @@ void AmsCans::SetAmsStep(wxString canid, AMSPassRoadType type, AMSPassRoadSTEP s
return;
}
auto tag_can_index = -1;
for (auto i = 0; i < m_can_road_list.GetCount(); i++) {
CanRoads *road = m_can_road_list[i];
if (canid == road->canRoad->m_info.can_id) { tag_can_index = road->canRoad->m_canindex; }
}
if (tag_can_index == -1) return;
// get colour
auto tag_colour = *wxWHITE;
for (auto i = 0; i < m_can_lib_list.GetCount(); i++) {
@ -1430,6 +1431,7 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons
amswin->SetSizer(m_sizer_body);
amswin->Layout();
amswin->Fit();
//Thaw();
SetSize(amswin->GetSize());
@ -1503,7 +1505,7 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons
m_simplebook_calibration->AddPage(m_calibration_err_panel, wxEmptyString, false);
AddPage(amswin, wxEmptyString, false);
AddPage(m_in_calibration_panel, wxEmptyString, false);
AddPage(m_simplebook_calibration, wxEmptyString, false);
UpdateStepCtrl();
@ -1518,11 +1520,11 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons
void AMSControl::init_scaled_buttons()
{
m_button_extruder_feed->SetMinSize(wxSize(FromDIP(54), FromDIP(24)));
m_button_extruder_feed->SetMinSize(wxSize(-1, FromDIP(24)));
m_button_extruder_feed->SetCornerRadius(FromDIP(11));
m_button_extruder_back->SetMinSize(wxSize(FromDIP(54), FromDIP(24)));
m_button_extruder_back->SetMinSize(wxSize(-1, FromDIP(24)));
m_button_extruder_back->SetCornerRadius(FromDIP(11));
m_button_ams_setting->SetMinSize(wxSize(FromDIP(88), FromDIP(33)));
m_button_ams_setting->SetMinSize(wxSize(-1, FromDIP(33)));
m_button_ams_setting->SetCornerRadius(FromDIP(12));
}
@ -1651,9 +1653,9 @@ void AMSControl::StopRridLoading(wxString amsid, wxString canid)
void AMSControl::msw_rescale()
{
m_extruder->msw_rescale();
m_button_extruder_back->SetMinSize(wxSize(FromDIP(54), FromDIP(24)));
m_button_extruder_feed->SetMinSize(wxSize(FromDIP(54), FromDIP(24)));
m_button_ams_setting->SetMinSize(wxSize(FromDIP(88), FromDIP(33)));
m_button_extruder_back->SetMinSize(wxSize(-1, FromDIP(24)));
m_button_extruder_feed->SetMinSize(wxSize(-1, FromDIP(24)));
m_button_ams_setting->SetMinSize(wxSize(-1, FromDIP(33)));
for (auto i = 0; i < m_ams_cans_list.GetCount(); i++) {
AmsCansWindow *cans = m_ams_cans_list[i];
@ -1689,6 +1691,13 @@ void AMSControl::CreateAms()
Thaw();
}
void AMSControl::Reset()
{
m_current_ams = "";
m_current_senect = "";
}
void AMSControl::UpdateAms(std::vector<AMSinfo> info, bool keep_selection)
{
std::string curr_ams_id = GetCurentAms();

View file

@ -490,6 +490,7 @@ public:
void on_ams_setting_click(wxCommandEvent &event);
void on_clibration_again_click(wxMouseEvent &event);
void on_clibration_cancel_click(wxMouseEvent &event);
void Reset();
void post_event(wxEvent &&event);

View file

@ -151,7 +151,6 @@ void Button::render(wxDC& dc)
wxSize szIcon;
wxSize szContent = textSize;
ScalableBitmap icon;
if (m_selected || ((states & (int)StateColor::State::Hovered) != 0))
icon = active_icon;
@ -217,7 +216,10 @@ void Button::messureSize()
if (szIcon.y > szContent.y)
szContent.y = szIcon.y;
}
wxWindow::SetMinSize(szContent + paddingSize * 2);
wxSize size = szContent + paddingSize * 2;
if (minSize.GetHeight() > 0)
size.SetHeight(minSize.GetHeight());
wxWindow::SetMinSize(size);
}
void Button::mouseDown(wxMouseEvent& event)

View file

@ -4,9 +4,12 @@
CheckBox::CheckBox(wxWindow* parent)
: wxBitmapToggleButton(parent, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE)
, m_on(this, "check_on", 16)
, m_half(this, "check_half", 16)
, m_off(this, "check_off", 16)
, m_on(this, "check_on", 16)
, m_half(this, "check_half", 16)
, m_off(this, "check_off", 16)
, m_on_disabled(this, "check_on_disabled", 16)
, m_half_disabled(this, "check_half_disabled", 16)
, m_off_disabled(this, "check_off_disabled", 16)
{
//SetBackgroundStyle(wxBG_STYLE_TRANSPARENT);
if (parent)
@ -40,4 +43,5 @@ void CheckBox::Rescale()
void CheckBox::update()
{
SetBitmap((m_half_checked ? m_half : GetValue() ? m_on : m_off).bmp());
}
SetBitmapDisabled((m_half_checked ? m_half_disabled : GetValue() ? m_on_disabled : m_off_disabled).bmp());
}

View file

@ -21,10 +21,13 @@ private:
void update();
private:
ScalableBitmap m_on;
ScalableBitmap m_half;
ScalableBitmap m_off;
bool m_half_checked = false;
ScalableBitmap m_on;
ScalableBitmap m_half;
ScalableBitmap m_off;
ScalableBitmap m_on_disabled;
ScalableBitmap m_half_disabled;
ScalableBitmap m_off_disabled;
bool m_half_checked = false;
};
#endif // !slic3r_GUI_CheckBox_hpp_

View file

@ -35,6 +35,33 @@ wxFont Label::Body_14 = Label::sysFont(14, false);
wxFont Label::Body_13 = Label::sysFont(13, false);
wxFont Label::Body_12 = Label::sysFont(12, false);
wxFont Label::Body_10 = Label::sysFont(10, false);
wxFont Label::Body_9 = Label::sysFont(9, false);
wxSize Label::split_lines(wxDC &dc, int width, const wxString &text, wxString &multiline_text)
{
multiline_text = text;
if (width > 0 && dc.GetTextExtent(text).x > width) {
size_t start = 0;
while (true) {
size_t idx = size_t(-1);
for (size_t i = start; i < multiline_text.Len(); i++) {
if (multiline_text[i] == ' ') {
if (dc.GetTextExtent(multiline_text.SubString(start, i)).x < width)
idx = i;
else {
if (idx == size_t(-1)) idx = i;
break;
}
}
}
if (idx == size_t(-1)) break;
multiline_text[idx] = '\n';
start = idx + 1;
if (dc.GetTextExtent(multiline_text.Mid(start)).x < width) break;
}
}
return dc.GetMultiLineTextExtent(multiline_text);
}
Label::Label(wxString const &text, wxWindow *parent) : Label(Body_16, text, parent) {}

View file

@ -29,8 +29,11 @@ public:
static wxFont Body_13;
static wxFont Body_12;
static wxFont Body_10;
static wxFont Body_9;
static wxFont sysFont(int size, bool bold = false);
static wxSize split_lines(wxDC &dc, int width, const wxString &text, wxString &multiline_text);
};
#endif // !slic3r_GUI_Label_hpp_

View file

@ -165,7 +165,11 @@ void SideButton::paintEvent(wxPaintEvent& evt)
{
// depending on your system you may need to look at double-buffered dcs
wxPaintDC dc(this);
#ifdef __WXMSW__
wxGCDC dc2(dc);
#else
wxDC & dc2(dc);
#endif
render(dc2);
}

View file

@ -42,9 +42,18 @@ bool SidePopup::Show( bool show )
void SidePopup::Popup(wxWindow* focus)
{
Create();
int screenwidth = wxSystemSettings::GetMetric(wxSYS_SCREEN_X,NULL);
int max_width = 0;
for (auto btn : btn_list)
{
max_width = std::max(btn->GetMinSize().x, max_width);
}
if (focus) {
wxPoint pos = focus->ClientToScreen(wxPoint(0, -6));
Position(pos, {0, focus->GetSize().y + 12});
if (pos.x + max_width > screenwidth)
Position({pos.x - (pos.x + max_width - screenwidth),pos.y}, {0, focus->GetSize().y + 12});
else
Position(pos, {0, focus->GetSize().y + 12});
}
wxPopupTransientWindow::Popup();
}

View file

@ -242,36 +242,35 @@ void StepIndicator::doRender(wxDC &dc)
states = clr_step.Disabled;
}
int font_height = radius * 2;
if (steps.size() > 0)
font_height = dc.GetTextExtent(steps[0]).y;
int textWidth = size.x - radius * 5;
dc.SetFont(GetFont());
wxString firstLine;
if (step == 0) dc.SetFont(GetFont().Bold());
wxSize firstLineSize = Label::split_lines(dc, textWidth, steps.front(), firstLine);
wxString lastLine;
if (step == steps.size() - 1) dc.SetFont(GetFont().Bold());
wxSize lastLineSize = Label::split_lines(dc, textWidth, steps.back(), lastLine);
int firstPadding = std::max(0, firstLineSize.y / 2 - radius);
int lastPadding = std::max(0, lastLineSize.y / 2 - radius);
int itemWidth = steps.size() == 1 ? size.y : (size.y - font_height) / (steps.size() - 1);
wxRect rcBar = {radius - bar_width / 2, radius, bar_width, size.y - radius * 4};
wxRect rcBar = {radius * 2 - bar_width / 2, radius * 2 + firstPadding, bar_width, size.y - radius * 6 - firstPadding - lastPadding};
int itemWidth = steps.size() == 1 ? size.y : rcBar.height / (steps.size() - 1);
// Draw thin bar stick
dc.SetPen(wxPen(clr_bar.colorForStates(states)));
dc.SetBrush(wxBrush(clr_bar.colorForStates(states)));
dc.DrawRectangle(rcBar);
int circleX = radius;
int circleY = radius;
int circleX = radius * 2;
int circleY = radius * 3 + firstPadding;
dc.SetPen(wxPen(clr_step.colorForStates(states)));
dc.SetBrush(wxBrush(clr_step.colorForStates(states)));
for (int i = 0; i < steps.size(); ++i) {
bool disabled = step > i;
bool checked = step == i;
// Draw circle point & texts in it
dc.DrawEllipse(circleX - radius, circleY - radius, radius * 2, radius * 2);
dc.SetTextForeground(clr_text.colorForStates(states
| (disabled ? StateColor::Disabled : checked ? StateColor::Checked : 0)));
dc.SetFont(checked ? GetFont().Bold() : GetFont());
wxSize textSize = dc.GetTextExtent(steps[i]);
if (steps[i].Find("\n") >= 0) {
dc.DrawText(steps[i], circleX + radius * 3, circleY - textSize.y / 4);
} else {
dc.DrawText(steps[i], circleX + radius * 3, circleY - (textSize.y/2));
}
// Draw content ( icon or text ) in circle
if (disabled) {
wxSize sz = bmp_ok.GetBmpSize();
dc.DrawBitmap(bmp_ok.bmp(), circleX - radius, circleY - radius);
@ -283,6 +282,22 @@ void StepIndicator::doRender(wxDC &dc)
wxSize sz = dc.GetTextExtent(tip);
dc.DrawText(tip, circleX - sz.x / 2, circleY - sz.y / 2 + 1);
}
// Draw step text
dc.SetTextForeground(clr_text.colorForStates(states
| (disabled ? StateColor::Disabled : checked ? StateColor::Checked : 0)));
dc.SetFont(checked ? GetFont().Bold() : GetFont());
wxString text;
wxSize textSize;
if (i == 0) {
text = firstLine;
textSize = firstLineSize;
} else if (i == steps.size() - 1) {
text = lastLine;
textSize = lastLineSize;
} else {
textSize = Label::split_lines(dc, textWidth, steps[i], text);
}
dc.DrawText(text, circleX + radius * 3, circleY - (textSize.y / 2));
circleY += itemWidth;
}
}

Some files were not shown because too many files have changed in this diff Show more