Merge branch 'master' into SoftFever

This commit is contained in:
SoftFever 2022-08-11 20:06:32 +08:00
commit 159ff850e4
256 changed files with 14986 additions and 4365 deletions

View file

@ -68,6 +68,8 @@ set(SLIC3R_GUI_SOURCES
GUI/Widgets/SideTools.hpp
GUI/Widgets/WebView.cpp
GUI/Widgets/WebView.hpp
GUI/Widgets/wxStaticText2.cpp
GUI/Widgets/wxStaticText2.hpp
GUI/AboutDialog.cpp
GUI/AboutDialog.hpp
GUI/AuxiliaryDialog.cpp
@ -125,8 +127,6 @@ set(SLIC3R_GUI_SOURCES
GUI/Gizmos/GLGizmoFaceDetector.hpp
GUI/Gizmos/GLGizmoSeam.cpp
GUI/Gizmos/GLGizmoSeam.hpp
GUI/Gizmos/GLGizmoModifier.cpp
GUI/Gizmos/GLGizmoModifier.hpp
GUI/GLSelectionRectangle.cpp
GUI/GLSelectionRectangle.hpp
GUI/Gizmos/GizmoObjectManipulation.cpp
@ -213,6 +213,8 @@ set(SLIC3R_GUI_SOURCES
GUI/MonitorPage.hpp
GUI/StatusPanel.cpp
GUI/StatusPanel.hpp
GUI/UpdateErrorMessage.cpp
GUI/UpdateErrorMessage.hpp
GUI/SliceInfoPanel.cpp
GUI/SliceInfoPanel.hpp
GUI/CameraPopup.cpp
@ -344,6 +346,8 @@ set(SLIC3R_GUI_SOURCES
GUI/ReleaseNote.cpp
GUI/Calibration.hpp
GUI/Calibration.cpp
GUI/PrintOptionsDialog.hpp
GUI/PrintOptionsDialog.cpp
Utils/json_diff.hpp
Utils/json_diff.cpp
GUI/KBShortcutsDialog.hpp

View file

@ -11,7 +11,9 @@ static bool show_flag;
#else
#define COMBOBOX_FILAMENT (m_comboBox_filament)
#endif
AMSMaterialsSetting::AMSMaterialsSetting(wxWindow *parent, wxWindowID id) : wxPopupTransientWindow(parent, wxPU_CONTAINS_CONTROLS) {
AMSMaterialsSetting::AMSMaterialsSetting(wxWindow *parent, wxWindowID id)
: DPIDialog(parent, id, _L("AMSMaterialsSetting"), wxDefaultPosition, wxDefaultSize, wxBORDER_NONE)
{
create();
}
@ -19,13 +21,15 @@ void AMSMaterialsSetting::create()
{
SetBackgroundColour(*wxWHITE);
wxBoxSizer *m_sizer_main = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *m_sizer_body = new wxBoxSizer(wxVERTICAL);
SetSize(wxSize(AMS_MATERIALS_SETTING_BODY_WIDTH, -1));
SetMinSize(wxSize(AMS_MATERIALS_SETTING_BODY_WIDTH, -1));
SetMaxSize(wxSize(AMS_MATERIALS_SETTING_BODY_WIDTH, -1));
m_panel_body = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(AMS_MATERIALS_SETTING_BODY_WIDTH, -1), wxTAB_TRAVERSAL);
m_panel_body->SetBackgroundColour(*wxWHITE);
wxBoxSizer *m_sizer_filament = new wxBoxSizer(wxHORIZONTAL);
m_title_filament = new wxStaticText(m_panel_body, wxID_ANY, _L("Filament"), wxDefaultPosition, wxSize(AMS_MATERIALS_SETTING_LABEL_WIDTH, -1), 0);
m_title_filament = new wxStaticText(this, wxID_ANY, _L("Filament"), wxDefaultPosition, wxSize(AMS_MATERIALS_SETTING_LABEL_WIDTH, -1), 0);
m_title_filament->SetFont(::Label::Body_13);
m_title_filament->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800);
m_title_filament->Wrap(-1);
@ -34,15 +38,15 @@ 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);
m_comboBox_filament_mac = new wxComboBox(this, 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_comboBox_filament = new ::ComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, AMS_MATERIALS_SETTING_COMBOX_WIDTH, 0, nullptr, wxCB_READONLY);
#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);
m_title_colour = new wxStaticText(this, wxID_ANY, _L("Colour"), wxDefaultPosition, wxSize(AMS_MATERIALS_SETTING_LABEL_WIDTH, -1), 0);
m_title_colour->SetFont(::Label::Body_13);
m_title_colour->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800);
m_title_colour->Wrap(-1);
@ -53,30 +57,18 @@ void AMSMaterialsSetting::create()
m_clrData = new wxColourData();
m_clrData->SetChooseFull(true);
m_clrData->SetChooseAlpha(false);
m_clr_picker = new wxButton(m_panel_body, wxID_ANY, "", wxDefaultPosition, wxSize(FromDIP(20), FromDIP(20)), wxBU_EXACTFIT | wxBORDER_NONE);
m_clr_picker = new Button(this, "", "");
m_clr_picker->SetCanFocus(false);
m_clr_picker->SetSize(FromDIP(50), FromDIP(25));
m_clr_picker->SetMinSize(wxSize(FromDIP(50), FromDIP(25)));
m_clr_picker->SetCornerRadius(FromDIP(6));
m_clr_picker->SetBorderColor(wxColour(172, 172, 172));
m_clr_picker->Bind(wxEVT_BUTTON, &AMSMaterialsSetting::on_clr_picker, this);
m_sizer_colour->Add(m_clr_picker, 0, 0, 0);
m_panel_SN = new wxPanel(m_panel_body, wxID_ANY);
wxBoxSizer *m_sizer_SN = new wxBoxSizer(wxHORIZONTAL);
auto m_title_SN = new wxStaticText(m_panel_SN, wxID_ANY, _L("SN"), wxDefaultPosition, wxSize(AMS_MATERIALS_SETTING_LABEL_WIDTH, -1), 0);
m_title_SN->SetFont(::Label::Body_13);
m_title_SN->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800);
m_title_SN->Wrap(-1);
m_sizer_SN->Add(m_title_SN, 0, wxALIGN_CENTER, 0);
m_sizer_SN->Add(0, 0, 0, wxEXPAND, 0);
m_sn_number = new wxStaticText(m_panel_SN, wxID_ANY, wxEmptyString, wxDefaultPosition, AMS_MATERIALS_SETTING_COMBOX_WIDTH);
m_sizer_SN->Add(m_sn_number, 0, wxALIGN_CENTER, 0);
m_panel_SN->SetSizer(m_sizer_SN);
m_panel_SN->Layout();
m_panel_SN->Fit();
wxBoxSizer *m_sizer_temperature = new wxBoxSizer(wxHORIZONTAL);
m_title_temperature = new wxStaticText(m_panel_body, wxID_ANY, _L("Nozzle\nTemperature"), wxDefaultPosition, wxSize(AMS_MATERIALS_SETTING_LABEL_WIDTH, -1), 0);
m_title_temperature = new wxStaticText(this, wxID_ANY, _L("Nozzle\nTemperature"), wxDefaultPosition, wxSize(AMS_MATERIALS_SETTING_LABEL_WIDTH, -1), 0);
m_title_temperature->SetFont(::Label::Body_13);
m_title_temperature->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800);
m_title_temperature->Wrap(-1);
@ -87,8 +79,8 @@ 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_min = 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(this, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, AMS_MATERIALS_SETTING_INPUT_SIZE, wxTE_CENTRE | wxTE_PROCESS_ENTER);
m_input_nozzle_min = new ::TextInput(this, 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);
@ -97,8 +89,8 @@ void AMSMaterialsSetting::create()
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);
auto bitmap_max_degree = new wxStaticBitmap(this, -1, create_scaled_bitmap("degree", nullptr, 16), wxDefaultPosition, wxDefaultSize);
auto bitmap_min_degree = new wxStaticBitmap(this, -1, create_scaled_bitmap("degree", nullptr, 16), wxDefaultPosition, wxDefaultSize);
sizer_tempinput->Add(m_input_nozzle_max, 1, wxALIGN_CENTER, 0);
sizer_tempinput->Add(bitmap_min_degree, 0, wxALIGN_CENTER, 0);
@ -107,10 +99,10 @@ void AMSMaterialsSetting::create()
sizer_tempinput->Add(bitmap_max_degree, 0, wxALIGN_CENTER, 0);
wxBoxSizer *sizer_temp_txt = new wxBoxSizer(wxHORIZONTAL);
auto m_title_max = new wxStaticText(m_panel_body, wxID_ANY, _L("max"), wxDefaultPosition, AMS_MATERIALS_SETTING_INPUT_SIZE);
auto m_title_max = new wxStaticText(this, wxID_ANY, _L("max"), wxDefaultPosition, AMS_MATERIALS_SETTING_INPUT_SIZE);
m_title_max->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800);
m_title_max->SetFont(::Label::Body_13);
auto m_title_min = new wxStaticText(m_panel_body, wxID_ANY, _L("min"), wxDefaultPosition, AMS_MATERIALS_SETTING_INPUT_SIZE);
auto m_title_min = new wxStaticText(this, wxID_ANY, _L("min"), wxDefaultPosition, AMS_MATERIALS_SETTING_INPUT_SIZE);
m_title_min->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800);
m_title_min->SetFont(::Label::Body_13);
sizer_temp_txt->Add(m_title_max, 1, wxALIGN_CENTER, 0);
@ -126,7 +118,7 @@ void AMSMaterialsSetting::create()
wxString warning_string = wxString::FromUTF8(
(boost::format(_u8L("The input value should be greater than %1% and less than %2%")) % FILAMENT_MIN_TEMP % FILAMENT_MAX_TEMP).str());
warning_text = new wxStaticText(m_panel_body, wxID_ANY, warning_string, wxDefaultPosition, wxDefaultSize, 0);
warning_text = new wxStaticText(this, wxID_ANY, warning_string, wxDefaultPosition, wxDefaultSize, 0);
warning_text->SetFont(::Label::Body_13);
warning_text->SetForegroundColour(wxColour(255, 111, 0));
@ -164,42 +156,71 @@ void AMSMaterialsSetting::create()
e.Skip();
});
m_panel_SN = new wxPanel(this, wxID_ANY);
wxBoxSizer *m_sizer_SN = new wxBoxSizer(wxVERTICAL);
m_sizer_SN->AddSpacer(FromDIP(16));
wxBoxSizer *m_sizer_SN_inside = new wxBoxSizer(wxHORIZONTAL);
auto m_title_SN = new wxStaticText(m_panel_SN, wxID_ANY, _L("SN"), wxDefaultPosition, wxSize(AMS_MATERIALS_SETTING_LABEL_WIDTH, -1), 0);
m_title_SN->SetFont(::Label::Body_13);
m_title_SN->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800);
m_title_SN->Wrap(-1);
m_sizer_SN_inside->Add(m_title_SN, 0, wxALIGN_CENTER, 0);
m_sizer_SN_inside->Add(0, 0, 0, wxEXPAND, 0);
m_sn_number = new wxStaticText(m_panel_SN, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize);
m_sizer_SN_inside->Add(m_sn_number, 0, wxALIGN_CENTER, 0);
m_sizer_SN->Add(m_sizer_SN_inside);
m_panel_SN->SetSizer(m_sizer_SN);
m_panel_SN->Layout();
m_panel_SN->Fit();
wxBoxSizer *m_sizer_button = new wxBoxSizer(wxHORIZONTAL);
m_sizer_button->Add(0, 0, 1, wxEXPAND, 0);
m_button_confirm = new Button(m_panel_body, _L("Confirm"));
m_button_confirm = new Button(this, _L("Confirm"));
m_btn_bg_green = StateColor(std::pair<wxColour, int>(wxColour(27, 136, 68), StateColor::Pressed), std::pair<wxColour, int>(wxColour(61, 203, 115), StateColor::Hovered),
std::pair<wxColour, int>(wxColour(0, 174, 66), StateColor::Normal));
m_button_confirm->SetBackgroundColor(m_btn_bg_green);
m_button_confirm->SetBorderColor(wxColour(0, 174, 66));
m_button_confirm->SetTextColor(AMS_MATERIALS_SETTING_GREY200);
m_button_confirm->SetMinSize(AMS_MATERIALS_SETTING_BUTTON_SIZE);
m_button_confirm->SetCornerRadius(12);
m_button_confirm->Bind(wxEVT_LEFT_DOWN, &AMSMaterialsSetting::on_select_ok, this);
m_sizer_button->Add(m_button_confirm, 0, wxALIGN_CENTER, 0);
m_button_confirm->SetCornerRadius(FromDIP(12));
m_button_confirm->Bind(wxEVT_BUTTON, &AMSMaterialsSetting::on_select_ok, this);
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);
m_sizer_body->Add(0, 0, 0, wxEXPAND | wxTOP, FromDIP(16));
m_sizer_body->Add(m_panel_SN, 0, wxEXPAND, 0);
m_sizer_body->Add(0, 0, 0, wxEXPAND | wxTOP, FromDIP(10));
m_sizer_body->Add(m_sizer_temperature, 0, wxEXPAND, 0);
m_sizer_body->Add(0, 0, 0, wxEXPAND | wxTOP, FromDIP(5));
m_sizer_body->Add(warning_text, 0, wxEXPAND, 0);
m_sizer_body->Add(0, 0, 0, wxEXPAND | wxTOP, FromDIP(24));
m_sizer_body->Add(m_sizer_button, 0, wxEXPAND, 0);
m_button_close = new Button(this, _L("Close"));
m_btn_bg_gray = StateColor(std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Pressed), std::pair<wxColour, int>(*wxWHITE, StateColor::Focused),
std::pair<wxColour, int>(wxColour(238, 238, 238), StateColor::Hovered),
std::pair<wxColour, int>(*wxWHITE, StateColor::Normal));
m_button_close->SetBackgroundColor(m_btn_bg_gray);
m_button_close->SetBorderColor(AMS_MATERIALS_SETTING_GREY900);
m_button_close->SetTextColor(AMS_MATERIALS_SETTING_GREY900);
m_button_close->SetMinSize(AMS_MATERIALS_SETTING_BUTTON_SIZE);
m_button_close->SetCornerRadius(FromDIP(12));
m_button_close->Bind(wxEVT_BUTTON, &AMSMaterialsSetting::on_select_close, this);
m_panel_body->SetSizer(m_sizer_body);
m_panel_body->Layout();
m_sizer_main->Add(m_panel_body, 0, wxALL | wxEXPAND, 24);
m_sizer_button->Add(m_button_confirm, 0, wxALIGN_CENTER | wxRIGHT, FromDIP(20));
m_sizer_button->Add(m_button_close, 0, wxALIGN_CENTER, 0);
this->SetSizer(m_sizer_main);
this->Layout();
m_sizer_main->Fit(this);
m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(16));
m_sizer_main->Add(m_sizer_filament, 0, wxLEFT | wxRIGHT, FromDIP(20));
m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(16));
m_sizer_main->Add(m_sizer_colour, 0, wxLEFT | wxRIGHT, FromDIP(20));
m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(16));
m_sizer_main->Add(m_sizer_temperature, 0, wxLEFT | wxRIGHT, FromDIP(20));
m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(5));
m_sizer_main->Add(warning_text, 0, wxLEFT | wxRIGHT, FromDIP(20));
m_sizer_main->Add(m_panel_SN, 0, wxLEFT, FromDIP(20));
m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(24));
m_sizer_main->Add(m_sizer_button, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(20));
m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(16));
this->Centre(wxBOTH);
SetSizer(m_sizer_main);
Layout();
Fit();
Bind(wxEVT_PAINT, &AMSMaterialsSetting::paintEvent, this);
COMBOBOX_FILAMENT->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(AMSMaterialsSetting::on_select_filament), NULL, this);
@ -219,7 +240,6 @@ AMSMaterialsSetting::~AMSMaterialsSetting()
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;
@ -264,23 +284,29 @@ void AMSMaterialsSetting::update()
void AMSMaterialsSetting::enable_confirm_button(bool en)
{
if (!en) {
if (m_button_confirm->IsEnabled()) {
m_button_confirm->Disable();
m_button_confirm->SetBackgroundColor(wxColour(0x90, 0x90, 0x90));
m_button_confirm->SetBorderColor(wxColour(0x90, 0x90, 0x90));
}
} else {
if (!m_button_confirm->IsEnabled()) {
m_button_confirm->Enable();
m_button_confirm->SetBackgroundColor(m_btn_bg_green);
m_button_confirm->SetBorderColor(m_btn_bg_green);
}
}
if (m_is_third) m_button_confirm->Show(en);
//if (!en) {
// if (m_button_confirm->IsEnabled()) {
// m_button_confirm->Disable();
// m_button_confirm->SetBackgroundColor(wxColour(0x90, 0x90, 0x90));
// m_button_confirm->SetBorderColor(wxColour(0x90, 0x90, 0x90));
// }
//} else {
// if (!m_button_confirm->IsEnabled()) {
// m_button_confirm->Enable();
// m_button_confirm->SetBackgroundColor(m_btn_bg_green);
// m_button_confirm->SetBorderColor(m_btn_bg_green);
// }
//}
}
void AMSMaterialsSetting::on_select_ok(wxMouseEvent &event)
void AMSMaterialsSetting::on_select_ok(wxCommandEvent &event)
{
if (!m_is_third) {
Close();
return;
}
wxString nozzle_temp_min = m_input_nozzle_min->GetTextCtrl()->GetValue();
auto filament = COMBOBOX_FILAMENT->GetValue();
@ -310,7 +336,12 @@ void AMSMaterialsSetting::on_select_ok(wxMouseEvent &event)
obj->command_ams_filament_settings(ams_id, tray_id, ams_filament_id, std::string(col_buf), m_filament_type, nozzle_temp_min_int, nozzle_temp_max_int);
}
}
wxPopupTransientWindow::Dismiss();
Close();
}
void AMSMaterialsSetting::on_select_close(wxCommandEvent &event)
{
Close();
}
void AMSMaterialsSetting::set_color(wxColour color)
@ -320,26 +351,13 @@ void AMSMaterialsSetting::set_color(wxColour color)
void AMSMaterialsSetting::on_clr_picker(wxCommandEvent & event)
{
if(!m_is_third)
return;
auto clr_dialog = new wxColourDialog(this, m_clrData);
show_flag = true;
if (clr_dialog->ShowModal() == wxID_OK) {
m_clrData = &(clr_dialog->GetColourData());
m_clr_picker->SetBackgroundColour(m_clrData->GetColour());
}
}
void AMSMaterialsSetting::Dismiss()
{
if (show_flag)
{
show_flag = false;
} else
{
#ifdef __APPLE__
#else
wxPopupTransientWindow::Dismiss();
#endif
m_clr_picker->SetBackgroundColor(m_clrData->GetColour());
}
}
@ -350,36 +368,45 @@ bool AMSMaterialsSetting::Show(bool show)
m_input_nozzle_max->GetTextCtrl()->SetSize(wxSize(-1, FromDIP(20)));
m_input_nozzle_min->GetTextCtrl()->SetSize(wxSize(-1, FromDIP(20)));
}
return wxPopupTransientWindow::Show(show);
return DPIDialog::Show(show);
}
void AMSMaterialsSetting::Popup(bool show, bool third, wxString filament, wxColour colour, wxString sn, wxString tep)
void AMSMaterialsSetting::Popup(wxString filament, wxString sn, wxString temp_min, wxString temp_max)
{
m_clr_picker->SetBackgroundColor(m_clrData->GetColour());
if (!m_is_third) {
m_button_confirm->Hide();
m_sn_number->SetLabel(sn);
m_panel_SN->Show();
#ifdef __APPLE__
wxArrayString filament_only;
filament_only.push_back(filament);
COMBOBOX_FILAMENT->Set(filament_only);
#else
COMBOBOX_FILAMENT->Set(wxArrayString());
#endif
COMBOBOX_FILAMENT->SetValue(filament);
m_sn_number->SetLabelText(sn);
m_input_nozzle_min->GetTextCtrl()->SetValue(tep);
m_clrData->SetColour(colour);
COMBOBOX_FILAMENT->Disable();
m_input_nozzle_min->Disable();
m_input_nozzle_min->GetTextCtrl()->SetValue(temp_min);
m_input_nozzle_max->GetTextCtrl()->SetValue(temp_max);
wxPopupTransientWindow::Popup();
Layout();
Fit();
ShowModal();
return;
}
m_button_confirm->Show();
m_panel_SN->Hide();
Layout();
Fit();
m_clr_picker->SetBackgroundColour(m_clrData->GetColour());
int selection_idx = -1, idx = 0;
wxArrayString filament_items;
std::set<std::string> filament_id_set;
if (show) {
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
if (preset_bundle) {
BOOST_LOG_TRIVIAL(trace) << "system_preset_bundle filament number=" << preset_bundle->filaments.size();
@ -436,18 +463,12 @@ void AMSMaterialsSetting::Popup(bool show, bool third, wxString filament, wxColo
}
}
}
}
COMBOBOX_FILAMENT->Set(filament_items);
if (selection_idx >= 0 && selection_idx < filament_items.size()) {
COMBOBOX_FILAMENT->SetSelection(selection_idx);
post_select_event();
}
else {
COMBOBOX_FILAMENT->SetSelection(selection_idx);
post_select_event();
}
COMBOBOX_FILAMENT->SetSelection(selection_idx);
post_select_event();
}
wxPopupTransientWindow::Popup();
update();
ShowModal();
}
void AMSMaterialsSetting::post_select_event() {
@ -488,7 +509,8 @@ void AMSMaterialsSetting::on_select_filament(wxCommandEvent &evt)
if (opt_type_strs) {
found_filament_type = true;
//m_filament_type = opt_type_strs->get_at(0);
m_filament_type = it->config.get_filament_type();
std::string display_filament_type;
m_filament_type = it->config.get_filament_type(display_filament_type);
}
}
if (!found_filament_type)
@ -504,18 +526,6 @@ void AMSMaterialsSetting::on_select_filament(wxCommandEvent &evt)
}
}
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;
}
}
void AMSMaterialsSetting::on_dpi_changed(const wxRect &suggested_rect) { this->Refresh(); }
}} // namespace Slic3r::GUI

View file

@ -15,11 +15,12 @@
#include "Widgets/TextInput.hpp"
#define AMS_MATERIALS_SETTING_DEF_COLOUR wxColour(255, 255, 255)
#define AMS_MATERIALS_SETTING_GREY900 wxColour(38, 46, 48)
#define AMS_MATERIALS_SETTING_GREY800 wxColour(50, 58, 61)
#define AMS_MATERIALS_SETTING_GREY700 wxColour(107, 107, 107)
#define AMS_MATERIALS_SETTING_GREY300 wxColour(174,174,174)
#define AMS_MATERIALS_SETTING_GREY200 wxColour(248, 248, 248)
#define AMS_MATERIALS_SETTING_BODY_WIDTH FromDIP(340)
#define AMS_MATERIALS_SETTING_BODY_WIDTH FromDIP(380)
#define AMS_MATERIALS_SETTING_LABEL_WIDTH FromDIP(80)
#define AMS_MATERIALS_SETTING_COMBOX_WIDTH wxSize(FromDIP(250), FromDIP(30))
#define AMS_MATERIALS_SETTING_BUTTON_SIZE wxSize(FromDIP(90), FromDIP(24))
@ -27,7 +28,7 @@
namespace Slic3r { namespace GUI {
class AMSMaterialsSetting : public wxPopupTransientWindow
class AMSMaterialsSetting : public DPIDialog
{
public:
AMSMaterialsSetting(wxWindow *parent, wxWindowID id);
@ -39,17 +40,13 @@ public:
void input_max_finish();
void update();
void enable_confirm_button(bool en);
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 Popup(wxString filament = wxEmptyString, wxString sn = wxEmptyString, wxString temp_min = wxEmptyString, wxString temp_max = wxEmptyString);
void post_select_event();
void on_select_ok(wxMouseEvent &event);
void set_color(wxColour color);
void on_clr_picker(wxCommandEvent &event);
MachineObject *obj{nullptr};
int ams_id { 0 }; /* 0 ~ 3 */
int tray_id { 0 }; /* 0 ~ 3 */
@ -64,31 +61,35 @@ public:
std::string m_filament_type;
protected:
//void on_dpi_changed(const wxRect &suggested_rect) override;
void on_dpi_changed(const wxRect &suggested_rect) override;
void on_select_filament(wxCommandEvent& evt);
bool ProcessLeftDown(wxMouseEvent &evt);
void on_select_ok(wxCommandEvent &event);
void on_select_close(wxCommandEvent &event);
void on_clr_picker(wxCommandEvent &event);
protected:
StateColor m_btn_bg_green;
StateColor m_btn_bg_gray;
wxPanel * m_panel_SN;
wxStaticText * m_sn_number;
wxStaticText * warning_text;
wxPanel * m_panel_body;
//wxPanel * m_panel_body;
wxStaticText * m_title_filament;
ComboBox * m_comboBox_filament;
wxStaticText * m_title_colour;
wxButton * m_clr_picker;
wxStaticText * m_title_temperature;
wxStaticText * m_label_other;
TextInput * m_input_nozzle_min;
TextInput* m_input_nozzle_max;
Button * m_button_confirm;
#ifdef __APPLE__
wxComboBox *m_comboBox_filament_mac;
#endif
Button * m_button_close;
Button * m_clr_picker;
wxColourData * m_clrData;
#ifdef __APPLE__
wxComboBox *m_comboBox_filament_mac;
#else
ComboBox *m_comboBox_filament;
#endif
};
}} // namespace Slic3r::GUI

View file

@ -17,8 +17,8 @@ AboutDialogLogo::AboutDialogLogo(wxWindow* parent)
: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize)
{
this->SetBackgroundColour(*wxWHITE);
this->logo = wxBitmap(from_u8(Slic3r::var("BambuStudio_192px.png")), wxBITMAP_TYPE_PNG);
this->SetMinSize(this->logo.GetSize());
this->logo = ScalableBitmap(this, Slic3r::var("BambuStudio_192px.png"), wxBITMAP_TYPE_PNG);
this->SetMinSize(this->logo.GetBmpSize());
this->Bind(wxEVT_PAINT, &AboutDialogLogo::onRepaint, this);
}
@ -29,9 +29,9 @@ void AboutDialogLogo::onRepaint(wxEvent &event)
dc.SetBackgroundMode(wxTRANSPARENT);
wxSize size = this->GetSize();
int logo_w = this->logo.GetWidth();
int logo_h = this->logo.GetHeight();
dc.DrawBitmap(this->logo, (size.GetWidth() - logo_w)/2, (size.GetHeight() - logo_h)/2, true);
int logo_w = this->logo.GetBmpWidth();
int logo_h = this->logo.GetBmpHeight();
dc.DrawBitmap(this->logo.bmp(), (size.GetWidth() - logo_w)/2, (size.GetHeight() - logo_h)/2, true);
event.Skip();
}

View file

@ -17,7 +17,7 @@ public:
AboutDialogLogo(wxWindow* parent);
private:
wxBitmap logo;
ScalableBitmap logo;
void onRepaint(wxEvent &event);
};

View file

@ -179,9 +179,9 @@ void MaterialItem::doRender(wxDC &dc)
AmsMapingPopup::AmsMapingPopup(wxWindow *parent)
:wxPopupTransientWindow(parent, wxBORDER_NONE)
{
SetSize(wxSize(FromDIP(220), -1));
SetMinSize(wxSize(FromDIP(220), -1));
SetMaxSize(wxSize(FromDIP(220), -1));
SetSize(wxSize(FromDIP(300), -1));
SetMinSize(wxSize(FromDIP(300), -1));
SetMaxSize(wxSize(FromDIP(300), -1));
Bind(wxEVT_PAINT, &AmsMapingPopup::paintEvent, this);
@ -193,11 +193,62 @@ void MaterialItem::doRender(wxDC &dc)
m_sizer_main = new wxBoxSizer(wxVERTICAL);
//m_sizer_main->Add(0, 0, 1, wxEXPAND, 0);
auto title_panel = new wxPanel(this, wxID_ANY);
title_panel->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8));
title_panel->SetSize(wxSize(-1, FromDIP(30)));
title_panel->SetMinSize(wxSize(-1, FromDIP(30)));
wxBoxSizer *title_sizer_h= new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *title_sizer_v = new wxBoxSizer(wxVERTICAL);
auto title_text = new wxStaticText(title_panel, wxID_ANY, _L("AMS Slots"));
title_text->SetForegroundColour(wxColour(0x32, 0x3A, 0x3D));
title_text->SetFont(::Label::Head_13);
title_sizer_v->Add(title_text, 0, wxALIGN_CENTER, 5);
title_sizer_h->Add(title_sizer_v, 1, wxALIGN_CENTER, 5);
title_panel->SetSizer(title_sizer_h);
title_panel->Layout();
title_panel->Fit();
m_sizer_list = new wxBoxSizer(wxVERTICAL);
m_warning_text = new wxStaticText(this, wxID_ANY, wxEmptyString);
m_warning_text->SetForegroundColour(wxColour(0xFF, 0x6F, 0x00));
m_warning_text->SetFont(::Label::Body_12);
auto cant_not_match_tip = _L("Note: Only the AMS slots loaded with the same material type can be selected.");
m_warning_text->SetLabel(format_text(cant_not_match_tip));
m_warning_text->SetMinSize(wxSize(FromDIP(280), FromDIP(-1)));
m_warning_text->Wrap(FromDIP(280));
m_sizer_main->Add(title_panel, 0, wxEXPAND | wxALL, FromDIP(2));
m_sizer_main->Add(m_sizer_list, 0, wxEXPAND | wxALL, FromDIP(0));
m_sizer_main->Add(m_warning_text, 0, wxEXPAND | wxALL, FromDIP(10));
SetSizer(m_sizer_main);
Layout();
}
wxString AmsMapingPopup::format_text(wxString &m_msg)
{
if (wxGetApp().app_config->get("language") != "zh_CN") { return m_msg; }
wxString out_txt = m_msg;
wxString count_txt = "";
int new_line_pos = 0;
for (int i = 0; i < m_msg.length(); i++) {
auto text_size = m_warning_text->GetTextExtent(count_txt);
if (text_size.x < (FromDIP(280))) {
count_txt += m_msg[i];
} else {
out_txt.insert(i - 1, '\n');
count_txt = "";
}
}
return out_txt;
}
void AmsMapingPopup::update_materials_list(std::vector<std::string> list)
{
@ -224,7 +275,7 @@ void AmsMapingPopup::on_left_down(wxMouseEvent &evt)
auto left = item->GetSize();
if (pos.x > p_rect.x && pos.y > p_rect.y && pos.x < (p_rect.x + item->GetSize().x) && pos.y < (p_rect.y + item->GetSize().y)) {
if (item->m_tray_data.type == TrayType::NORMAL && !is_match_material(item->m_tray_data.name)) return;
if (item->m_tray_data.type == TrayType::NORMAL && !is_match_material(item->m_tray_data.filament_type)) return;
item->send_event(m_current_filament_id);
Dismiss();
}
@ -233,6 +284,7 @@ void AmsMapingPopup::on_left_down(wxMouseEvent &evt)
void AmsMapingPopup::update_ams_data(std::map<std::string, Ams*> amsList)
{
m_has_unmatch_filament = false;
m_mapping_item_list.clear();
if (m_amsmapping_sizer_list.size() > 0) {
for (wxBoxSizer *bz : m_amsmapping_sizer_list) { bz->Clear(true); }
@ -266,7 +318,8 @@ void AmsMapingPopup::update_ams_data(std::map<std::string, Ams*> amsList)
} else {
td.type = NORMAL;
td.colour = AmsTray::decode_color(tray_data->color);
td.name = tray_data->type;
td.name = tray_data->get_display_filament_type();
td.filament_type = tray_data->get_filament_type();
}
}
@ -275,6 +328,8 @@ void AmsMapingPopup::update_ams_data(std::map<std::string, Ams*> amsList)
add_ams_mapping(tray_datas);
}
m_warning_text->Show(m_has_unmatch_filament);
Layout();
Fit();
}
@ -294,57 +349,43 @@ void AmsMapingPopup::add_ams_mapping(std::vector<TrayData> tray_data)
// set button
MappingItem *m_filament_name = new MappingItem(this);
m_filament_name->SetSize(wxSize(FromDIP(38), FromDIP(20)));
m_filament_name->SetMinSize(wxSize(FromDIP(38), FromDIP(20)));
m_filament_name->SetMaxSize(wxSize(FromDIP(38), FromDIP(20)));
m_filament_name->SetSize(wxSize(FromDIP(62), FromDIP(22)));
m_filament_name->SetMinSize(wxSize(FromDIP(62), FromDIP(22)));
m_filament_name->SetMaxSize(wxSize(FromDIP(62), FromDIP(22)));
//m_filament_name->SetCornerRadius(5);
m_filament_name->SetFont(::Label::Body_12);
m_mapping_item_list.push_back(m_filament_name);
if (tray_data[i].type == NORMAL) {
m_filament_name->set_data(tray_data[i].colour, tray_data[i].name, tray_data[i]);
if (is_match_material(tray_data[i].filament_type)) {
m_filament_name->set_data(tray_data[i].colour, tray_data[i].name, tray_data[i]);
} else {
m_filament_name->set_data(wxColour(0xEE,0xEE,0xEE), tray_data[i].name, tray_data[i], true);
m_has_unmatch_filament = true;
}
m_filament_name->Bind(wxEVT_LEFT_DOWN, [this, tray_data, i, m_filament_name](wxMouseEvent &e) {
if (!is_match_material(tray_data[i].name)) return;
if (!is_match_material(tray_data[i].filament_type)) return;
m_filament_name->send_event(m_current_filament_id);
Dismiss();
/* wxCommandEvent event(EVT_SET_FINISH_MAPPING);
event.SetInt(tray_data[i].id);
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);
Dismiss();*/
});
}
// temp
if (tray_data[i].type == EMPTY) {
m_filament_name->set_data(wxColour(0x6B, 0x6B, 0x6B), "-", tray_data[i]);
m_filament_name->set_data(wxColour(0xCE, 0xCE, 0xCE), "-", tray_data[i]);
m_filament_name->Bind(wxEVT_LEFT_DOWN, [this, tray_data, i, m_filament_name](wxMouseEvent &e) {
m_filament_name->send_event(m_current_filament_id);
/* wxCommandEvent event(EVT_SET_FINISH_MAPPING);
event.SetInt(tray_data[i].id);
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);*/
Dismiss();
});
}
// third party
if (tray_data[i].type == THIRD) {
m_filament_name->set_data(wxColour(0x6B, 0x6B, 0x6B), "?", tray_data[i]);
m_filament_name->set_data(wxColour(0xCE, 0xCE, 0xCE), "?", tray_data[i]);
m_filament_name->Bind(wxEVT_LEFT_DOWN, [this, tray_data, i, m_filament_name](wxMouseEvent &e) {
m_filament_name->send_event(m_current_filament_id);
//wxCommandEvent event(EVT_SET_FINISH_MAPPING);
//event.SetInt(tray_data[i].id);
//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);
Dismiss();
});
}
@ -355,7 +396,7 @@ void AmsMapingPopup::add_ams_mapping(std::vector<TrayData> tray_data)
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);
m_sizer_list->Add(sizer_mapping_list, 0, wxALIGN_CENTER_HORIZONTAL, 0);
}
void AmsMapingPopup::OnDismiss()
@ -399,14 +440,6 @@ void MappingItem::send_event(int fliament_id)
event.SetString(param);
event.SetEventObject(this->GetParent()->GetParent());
wxPostEvent(this->GetParent()->GetParent(), event);
/* wxCommandEvent event(EVT_SET_FINISH_MAPPING);
event.SetInt(tray_data[i].id);
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);*/
}
void MappingItem::msw_rescale()
@ -443,22 +476,25 @@ void MappingItem::render(wxDC &dc)
#endif
// materials name
dc.SetFont(::Label::Body_13);
dc.SetFont(::Label::Body_12);
auto txt_colour = m_coloul.GetLuminance() < 0.5 ? *wxWHITE : wxColour(0x26, 0x2E, 0x30);
txt_colour = m_unmatch ? wxColour(0xCE, 0xCE, 0xCE) : txt_colour;
dc.SetTextForeground(txt_colour);
if (dc.GetTextExtent(m_name).x > GetSize().x - 10) {
/*if (dc.GetTextExtent(m_name).x > GetSize().x - 10) {
dc.SetFont(::Label::Body_10);
m_name = m_name.substr(0, 3) + "." + m_name.substr(m_name.length() - 1);
}
}*/
auto txt_size = dc.GetTextExtent(m_name);
dc.DrawText(m_name, wxPoint((GetSize().x - txt_size.x) / 2, (GetSize().y - txt_size.y) / 2));
}
void MappingItem::set_data(wxColour colour, wxString name, TrayData data)
void MappingItem::set_data(wxColour colour, wxString name, TrayData data, bool unmatch)
{
m_unmatch = unmatch;
m_tray_data = data;
if (m_coloul != colour || m_name != name) {
m_coloul = colour;

View file

@ -54,6 +54,7 @@ struct TrayData
TrayType type;
int id;
std::string name;
std::string filament_type;
wxColour colour;
};
@ -96,11 +97,12 @@ public:
wxColour m_coloul;
wxString m_name;
TrayData m_tray_data;
bool m_unmatch{false};
void msw_rescale();
void paintEvent(wxPaintEvent &evt);
void render(wxDC &dc);
void set_data(wxColour colour, wxString name, TrayData data);
void set_data(wxColour colour, wxString name, TrayData data, bool unmatch = false);
void doRender(wxDC &dc);
};
@ -108,15 +110,19 @@ class AmsMapingPopup : public wxPopupTransientWindow
{
public:
AmsMapingPopup(wxWindow *parent);
~AmsMapingPopup() {};
wxString format_text(wxString &m_msg);
~AmsMapingPopup(){};
wxStaticText * m_warning_text{nullptr};
std::vector<std::string> m_materials_list;
std::vector<wxBoxSizer*> m_amsmapping_sizer_list;
std::vector<MappingItem*> m_mapping_item_list;
bool m_has_unmatch_filament {false};
int m_current_filament_id;
std::string m_tag_material;
wxBoxSizer *m_sizer_main{nullptr};
wxBoxSizer *m_sizer_list{nullptr};
void update_materials_list(std::vector<std::string> list);
void set_tag_texture(std::string texture);

View file

@ -94,9 +94,9 @@ AuFile::AuFile(wxWindow *parent, fs::path file_path, wxString file_name, Auxilia
cover_text_right = _L("Rename");
cover_text_cover = _L("Cover");
m_file_cover = create_scaled_bitmap("auxiliary_cover", this, 50);
m_file_edit_mask = create_scaled_bitmap("auxiliary_edit_mask", this, 43);
m_file_delete = create_scaled_bitmap("auxiliary_delete", this, 28);
m_file_cover = ScalableBitmap(this, "auxiliary_cover", 50);
m_file_edit_mask = ScalableBitmap(this, "auxiliary_edit_mask", 43);
m_file_delete = ScalableBitmap(this, "auxiliary_delete", 28);
auto m_text_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(300), FromDIP(40)), wxTAB_TRAVERSAL);
m_text_panel->SetBackgroundColour(AUFILE_GREY300);
@ -183,7 +183,7 @@ void AuFile::PaintForeground(wxDC &dc)
wxSize size = wxSize(FromDIP(300), FromDIP(300));
if (m_hover) {
dc.DrawBitmap(m_file_edit_mask, 0, size.y - m_file_edit_mask.GetSize().y);
dc.DrawBitmap(m_file_edit_mask.bmp(), 0, size.y - m_file_edit_mask.GetBmpSize().y);
dc.SetFont(Label::Body_14);
dc.SetTextForeground(*wxWHITE);
if (m_type == MODEL_PICTURE) {
@ -191,14 +191,14 @@ void AuFile::PaintForeground(wxDC &dc)
auto sizet = dc.GetTextExtent(cover_text_left);
auto pos = wxPoint(0, 0);
pos.x = (size.x / 2 - sizet.x) / 2;
pos.y = (size.y - (m_file_edit_mask.GetSize().y + sizet.y) / 2);
pos.y = (size.y - (m_file_edit_mask.GetBmpSize().y + sizet.y) / 2);
dc.DrawText(cover_text_left, pos);
// right text
sizet = dc.GetTextExtent(cover_text_right);
pos = wxPoint(0, 0);
pos.x = size.x / 2 + (size.x / 2 - sizet.x) / 2;
pos.y = (size.y - (m_file_edit_mask.GetSize().y + sizet.y) / 2);
pos.y = (size.y - (m_file_edit_mask.GetBmpSize().y + sizet.y) / 2);
dc.DrawText(cover_text_right, pos);
// Split
@ -206,21 +206,21 @@ void AuFile::PaintForeground(wxDC &dc)
dc.SetBrush(AUFILE_GREY700);
pos = wxPoint(0, 0);
pos.x = size.x / 2 - 1;
pos.y = size.y - FromDIP(30) - (m_file_edit_mask.GetSize().y - FromDIP(30)) / 2;
pos.y = size.y - FromDIP(30) - (m_file_edit_mask.GetBmpSize().y - FromDIP(30)) / 2;
dc.DrawRectangle(pos.x, pos.y, 2, FromDIP(30));
} else {
// right text
auto sizet = dc.GetTextExtent(cover_text_right);
auto pos = wxPoint(0, 0);
pos.x = (size.x - sizet.x) / 2;
pos.y = (size.y - (m_file_edit_mask.GetSize().y + sizet.y) / 2);
pos.y = (size.y - (m_file_edit_mask.GetBmpSize().y + sizet.y) / 2);
dc.DrawText(cover_text_right, pos);
}
}
if (m_cover) {
dc.SetTextForeground(*wxWHITE);
dc.DrawBitmap(m_file_cover, size.x - m_file_cover.GetSize().x, 0);
dc.DrawBitmap(m_file_cover.bmp(), size.x - m_file_cover.GetBmpSize().x, 0);
dc.SetFont(Label::Body_12);
auto sizet = dc.GetTextExtent(cover_text_cover);
auto pos = wxPoint(0, 0);
@ -229,7 +229,7 @@ void AuFile::PaintForeground(wxDC &dc)
dc.DrawText(cover_text_cover, pos);
}
if (m_hover) { dc.DrawBitmap(m_file_delete, size.x - m_file_delete.GetSize().x - FromDIP(15), FromDIP(15)); }
if (m_hover) { dc.DrawBitmap(m_file_delete.bmp(), size.x - m_file_delete.GetBmpSize().x - FromDIP(15), FromDIP(15)); }
}
void AuFile::on_mouse_enter(wxMouseEvent &evt)
@ -337,7 +337,7 @@ void AuFile::on_mouse_left_up(wxMouseEvent &evt)
auto pos = evt.GetPosition();
// set cover
auto mask_size = m_file_edit_mask.GetSize();
auto mask_size = m_file_edit_mask.GetBmpSize();
auto cover_left = 0;
auto cover_top = size.y - mask_size.y;
auto cover_right = mask_size.x / 2;
@ -353,10 +353,10 @@ void AuFile::on_mouse_left_up(wxMouseEvent &evt)
if (pos.x > rename_left && pos.x < rename_right && pos.y > rename_top && pos.y < rename_bottom) { on_set_rename(); }
// close
auto close_left = size.x - m_file_delete.GetSize().x - FromDIP(15);
auto close_left = size.x - m_file_delete.GetBmpSize().x - FromDIP(15);
auto close_top = FromDIP(15);
auto close_right = size.x - FromDIP(15);
auto close_bottom = m_file_delete.GetSize().y + FromDIP(15);
auto close_bottom = m_file_delete.GetBmpSize().y + FromDIP(15);
if (pos.x > close_left && pos.x < close_right && pos.y > close_top && pos.y < close_bottom) { on_set_delete(); }
}
@ -449,9 +449,9 @@ AuFile::~AuFile() {}
void AuFile::msw_rescale()
{
m_file_cover = create_scaled_bitmap("auxiliary_cover", this, 50);
m_file_edit_mask = create_scaled_bitmap("auxiliary_edit_mask", this, 43);
m_file_delete = create_scaled_bitmap("auxiliary_delete", this, 28);
m_file_cover = ScalableBitmap(this, "auxiliary_cover", 50);
m_file_edit_mask = ScalableBitmap(this, "auxiliary_edit_mask", 43);
m_file_delete = ScalableBitmap(this, "auxiliary_delete", 28);
if (m_type == MODEL_PICTURE) {
if (m_file_path.empty()) { return;}

View file

@ -81,9 +81,9 @@ public:
wxString cover_text_right;
wxString cover_text_cover;
wxBitmap m_file_bitmap;
wxBitmap m_file_cover;
wxBitmap m_file_edit_mask;
wxBitmap m_file_delete;
ScalableBitmap m_file_cover;
ScalableBitmap m_file_edit_mask;
ScalableBitmap m_file_delete;
wxBitmap m_bitmap_excel;
wxBitmap m_bitmap_pdf;

View file

@ -493,6 +493,9 @@ void BBLTopbar::OnFullScreen(wxAuiToolBarEvent& event)
m_frame->Restore();
}
else {
wxDisplay display(wxDisplay::GetFromWindow(this));
auto size = display.GetClientArea().GetSize();
m_frame->SetMaxSize(size + wxSize{16, 16});
m_normalRect = m_frame->GetRect();
m_frame->Maximize();
}
@ -505,17 +508,25 @@ void BBLTopbar::OnCloseFrame(wxAuiToolBarEvent& event)
void BBLTopbar::OnMouseLeftDClock(wxMouseEvent& mouse)
{
wxPoint mouse_pos = ::wxGetMousePosition();
// check whether mouse is not on any tool item
if (this->FindToolByCurrentPosition() != NULL &&
this->FindToolByCurrentPosition() != m_title_item) {
mouse.Skip();
return;
}
#ifdef __W1XMSW__
::PostMessage((HWND) m_frame->GetHandle(), WM_NCLBUTTONDBLCLK, HTCAPTION, MAKELPARAM(mouse_pos.x, mouse_pos.y));
return;
#endif // __WXMSW__
if (m_frame->IsMaximized()) {
m_frame->Restore();
}
else {
wxDisplay display(wxDisplay::GetFromWindow(this));
auto size = display.GetClientArea().GetSize();
m_frame->SetMaxSize(size + wxSize{16, 16});
m_normalRect = m_frame->GetRect();
m_frame->Maximize();
}
@ -561,16 +572,23 @@ void BBLTopbar::OnMouseLeftDown(wxMouseEvent& event)
wxPoint frame_pos = m_frame->GetScreenPosition();
m_delta = mouse_pos - frame_pos;
if (FindToolByCurrentPosition() == NULL)
if (FindToolByCurrentPosition() == NULL
|| this->FindToolByCurrentPosition() == m_title_item)
{
CaptureMouse();
#ifdef __WXMSW__
ReleaseMouse();
::PostMessage((HWND) m_frame->GetHandle(), WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(mouse_pos.x, mouse_pos.y));
return;
#endif // __WXMSW__
}
event.Skip();
}
void BBLTopbar::OnMouseLeftUp(wxMouseEvent& event)
{
wxPoint mouse_pos = ::wxGetMousePosition();
if (HasCapture())
{
ReleaseMouse();
@ -581,7 +599,8 @@ void BBLTopbar::OnMouseLeftUp(wxMouseEvent& event)
void BBLTopbar::OnMouseMotion(wxMouseEvent& event)
{
wxPoint mouse_pos = event.GetPosition();
wxPoint mouse_pos = ::wxGetMousePosition();
if (!HasCapture()) {
//m_frame->OnMouseMotion(event);
@ -591,7 +610,6 @@ void BBLTopbar::OnMouseMotion(wxMouseEvent& event)
if (event.Dragging() && event.LeftIsDown())
{
wxPoint mouse_pos = ::wxGetMousePosition();
// leave max state and adjust position
if (m_frame->IsMaximized()) {
wxRect rect = m_frame->GetRect();

View file

@ -148,8 +148,6 @@ CalibrationDialog::CalibrationDialog(Plater *plater)
Layout();
Fit();
Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent &evt) { Hide(); });
m_calibration_btn->Bind(wxEVT_LEFT_DOWN, &CalibrationDialog::on_start_calibration, this);
}

View file

@ -139,10 +139,10 @@ CameraItem::CameraItem(wxWindow *parent,std::string off_normal, std::string on_n
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);
m_bitmap_on_normal = ScalableBitmap(this, on_normal, 20);
m_bitmap_off_normal = ScalableBitmap(this, off_normal, 20);
m_bitmap_on_hover = ScalableBitmap(this, on_hover, 20);
m_bitmap_off_hover = ScalableBitmap(this, off_hover, 20);
SetSize(wxSize(FromDIP(20), FromDIP(20)));
SetMinSize(wxSize(FromDIP(20), FromDIP(20)));
@ -208,16 +208,16 @@ 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));
dc.DrawBitmap(m_bitmap_on_hover.bmp(), wxPoint((GetSize().x - m_bitmap_on_hover.GetBmpSize().x) / 2, (GetSize().y - m_bitmap_on_hover.GetBmpSize().y) / 2));
} else {
dc.DrawBitmap(m_bitmap_on_normal, wxPoint((GetSize().x - m_bitmap_on_normal.GetSize().x) / 2, (GetSize().y - m_bitmap_on_normal.GetSize().y) / 2));
dc.DrawBitmap(m_bitmap_on_normal.bmp(), wxPoint((GetSize().x - m_bitmap_on_normal.GetBmpSize().x) / 2, (GetSize().y - m_bitmap_on_normal.GetBmpSize().y) / 2));
}
} 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));
dc.DrawBitmap(m_bitmap_off_hover.bmp(), wxPoint((GetSize().x - m_bitmap_off_hover.GetBmpSize().x) / 2, (GetSize().y - m_bitmap_off_hover.GetBmpSize().y) / 2));
} else {
dc.DrawBitmap(m_bitmap_off_normal, wxPoint((GetSize().x - m_bitmap_off_normal.GetSize().x) / 2, (GetSize().y - m_bitmap_off_normal.GetSize().y) / 2));
dc.DrawBitmap(m_bitmap_off_normal.bmp(), wxPoint((GetSize().x - m_bitmap_off_normal.GetBmpSize().x) / 2, (GetSize().y - m_bitmap_off_normal.GetBmpSize().y) / 2));
}
}
}

View file

@ -59,10 +59,10 @@ public:
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;
ScalableBitmap m_bitmap_on_normal;
ScalableBitmap m_bitmap_on_hover;
ScalableBitmap m_bitmap_off_normal;
ScalableBitmap m_bitmap_off_hover;
void msw_rescale();
void set_switch(bool is_on);

View file

@ -291,17 +291,6 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
is_msg_dlg_already_exist = false;
}
//BBS
if (config->opt_bool("timelapse_no_toolhead") && !is_timelapse_wipe_tower_already_prompted) {
wxString msg_text = _(L("When recording timelapse without toolhead, it is recommended to add a \"Timelapse Wipe Tower\" \n"
"by right-click the empty position of build plate and choose \"Add Primitive\"->\"Timelapse Wipe Tower\".\n"));
MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
is_msg_dlg_already_exist = true;
dialog.ShowModal();
is_msg_dlg_already_exist = false;
is_timelapse_wipe_tower_already_prompted = true;
}
// BBS
int filament_cnt = wxGetApp().preset_bundle->filament_presets.size();
#if 0

View file

@ -21,7 +21,6 @@ namespace GUI {
class ConfigManipulation
{
bool is_msg_dlg_already_exist{ false };
bool is_timelapse_wipe_tower_already_prompted{false}; // BBS
bool m_is_initialized_support_material_overhangs_queried{ false };
bool m_support_material_overhangs_queried{ false };

View file

@ -33,6 +33,7 @@ ConnectPrinterDialog::ConnectPrinterDialog(wxWindow *parent, wxWindowID id, cons
sizer_connect = new wxBoxSizer(wxHORIZONTAL);
m_textCtrl_code = new TextInput(this, wxEmptyString);
m_textCtrl_code->GetTextCtrl()->SetMaxLength(10);
m_textCtrl_code->SetFont(Label::Body_14);
m_textCtrl_code->SetCornerRadius(FromDIP(5));
m_textCtrl_code->SetSize(wxSize(FromDIP(330), FromDIP(40)));
@ -132,6 +133,12 @@ void ConnectPrinterDialog::on_input_enter(wxCommandEvent& evt)
void ConnectPrinterDialog::on_button_confirm(wxCommandEvent &event)
{
wxString code = m_textCtrl_code->GetTextCtrl()->GetValue();
for (char c : code) {
if (!('0' <= c && c <= '9' || 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z')) {
show_error(this, _L("Invalid input."));
return;
}
}
if (m_obj) {
m_obj->set_access_code(code.ToStdString());
}

View file

@ -148,6 +148,47 @@ bool AmsTray::is_tray_info_ready()
return true;
}
bool AmsTray::is_unset_third_filament()
{
if (this->is_bbl)
return false;
if (color.empty() || type.empty())
return true;
return false;
}
std::string AmsTray::get_display_filament_type()
{
if (type == "PLA-S")
return "Support W";
else if (type == "PA-S")
return "Support G";
else
return type;
return type;
}
std::string AmsTray::get_filament_type()
{
if (type == "Support W") {
return "PLA-S";
} else if (type == "Support G") {
return "PA-S";
} else if (type == "Support") {
if (setting_id == "GFS00") {
type = "PLA-S";
} else if (setting_id == "GFS01") {
type = "PA-S";
} else {
return "PLA-S";
}
} else {
return type;
}
return type;
}
bool HMSItem::parse_hms_info(unsigned attr, unsigned code)
{
bool result = true;
@ -336,6 +377,7 @@ MachineObject::MachineObject(NetworkAgent* agent, std::string name, std::string
/* printing */
mc_print_stage = 0;
mc_print_error_code = 0;
print_error = 0;
mc_print_line_number = 0;
mc_print_percent = 0;
mc_print_sub_stage = 0;
@ -350,6 +392,13 @@ MachineObject::~MachineObject()
subtask_ = nullptr;
}
if (get_slice_info_thread) {
if (get_slice_info_thread->joinable()) {
get_slice_info_thread->join();
get_slice_info_thread = nullptr;
}
}
if (slice_info) {
delete slice_info;
slice_info = nullptr;
@ -614,7 +663,7 @@ int MachineObject::ams_filament_mapping(std::vector<FilamentInfo> filaments, std
if (tray->second->is_tray_info_ready()) {
FilamentInfo info;
info.color = tray->second->color;
info.type = tray->second->type;
info.type = tray->second->get_filament_type();
info.id = tray_index;
tray_filaments.emplace(std::make_pair(tray_index, info));
}
@ -631,7 +680,7 @@ int MachineObject::ams_filament_mapping(std::vector<FilamentInfo> filaments, std
info.id = atoi(tray_it->first.c_str()) + atoi(it->first.c_str()) * 4;
info.tray_id = atoi(tray_it->first.c_str()) + atoi(it->first.c_str()) * 4;
info.color = tray_it->second->color;
info.type = tray_it->second->type;
info.type = tray_it->second->get_filament_type();
}
else {
info.id = -1;
@ -647,7 +696,29 @@ int MachineObject::ams_filament_mapping(std::vector<FilamentInfo> filaments, std
for (int i = 0; i < filaments.size(); i++) {
FilamentInfo info;
info.id = filaments[i].id;
info.tray_id = filaments[i].id;
int ams_id = filaments[i].id / 4;
auto ams_it = amsList.find(std::to_string(ams_id));
if (ams_it == amsList.end()) {
info.tray_id = -1;
info.mapping_result = (int)MappingResult::MAPPING_RESULT_EXCEED;
} else {
info.tray_id = filaments[i].id;
int tray_id = filaments[i].id % 4;
auto tray_it = ams_it->second->trayList.find(std::to_string(tray_id));
if (tray_it != ams_it->second->trayList.end()) {
if (!tray_it->second->is_exists || tray_it->second->is_unset_third_filament()) {
;
} else {
if (filaments[i].type == tray_it->second->get_filament_type()) {
info.color = tray_it->second->color;
info.type = tray_it->second->get_filament_type();
} else {
info.tray_id = -1;
info.mapping_result = (int)MappingResult::MAPPING_RESULT_TYPE_MISMATCH;
}
}
}
}
result.push_back(info);
}
return 1;
@ -807,11 +878,12 @@ bool MachineObject::is_valid_mapping_result(std::vector<FilamentInfo>& result)
for (int i = 0; i < result.size(); i++) {
// invalid mapping result
if (result[i].tray_id < 0)
return false;
is_valid = false;
else {
int ams_id = result[i].tray_id / 4;
if (amsList.find(std::to_string(ams_id)) == amsList.end()) {
return false;
result[i].tray_id = -1;
is_valid = false;
}
}
}
@ -820,12 +892,32 @@ bool MachineObject::is_valid_mapping_result(std::vector<FilamentInfo>& result)
return true;
}
bool MachineObject::is_mapping_exceed_filament(std::vector<FilamentInfo> & result, int &exceed_index)
{
bool is_exceed = false;
for (int i = 0; i < result.size(); i++) {
int ams_id = result[i].tray_id / 4;
if (amsList.find(std::to_string(ams_id)) == amsList.end()) {
exceed_index = result[i].tray_id;
result[i].tray_id = -1;
is_exceed = true;
break;
}
if (result[i].mapping_result == MappingResult::MAPPING_RESULT_EXCEED) {
exceed_index = result[i].id;
is_exceed = true;
break;
}
}
return is_exceed;
}
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;
result[i].mapping_result = 0;
}
}
@ -1387,6 +1479,31 @@ int MachineObject::command_ipcam_timelapse(bool on_off)
return this->publish_json(j.dump());
}
int MachineObject::command_xcam_control(std::string module_name, bool on_off, bool print_halt)
{
json j;
j["xcam"]["command"] = "xcam_control_set";
j["xcam"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
j["xcam"]["module_name"] = module_name;
j["xcam"]["control"] = on_off;
j["xcam"]["print_halt"] = print_halt;
return this->publish_json(j.dump());
}
int MachineObject::command_xcam_control_first_layer_inspector(bool on_off, bool print_halt)
{
xcam_first_layer_inspector = on_off;
xcam_first_layer_hold_count = HOLD_COUNT_MAX;
return command_xcam_control("first_layer_inspector", on_off, print_halt);
}
int MachineObject::command_xcam_control_spaghetti_detector(bool on_off, bool print_halt)
{
xcam_spaghetti_detector = on_off;
xcam_spaghetti_print_halt = print_halt;
xcam_spaghetti_hold_count = HOLD_COUNT_MAX;
return command_xcam_control("spaghetti_detector", on_off, print_halt);
}
void MachineObject::set_bind_status(std::string status)
{
@ -1680,8 +1797,6 @@ int MachineObject::parse_json(std::string payload)
mc_print_stage = jj["mc_print_stage"].get<int>();
}
if (jj.contains("mc_print_error_code")) {
if (jj["mc_print_error_code"].is_string())
mc_print_error_code = atoi(jj["mc_print_error_code"].get<std::string>().c_str());
if (jj["mc_print_error_code"].is_number())
mc_print_error_code = jj["mc_print_error_code"].get<int>();
@ -1690,6 +1805,11 @@ int MachineObject::parse_json(std::string payload)
if (jj["mc_print_line_number"].is_string() && !jj["mc_print_line_number"].is_null())
mc_print_line_number = atoi(jj["mc_print_line_number"].get<std::string>().c_str());
}
if (jj.contains("print_error")) {
if (jj["print_error"].is_number())
print_error = jj["print_error"].get<int>();
}
#pragma endregion
#pragma region print_task
@ -1750,6 +1870,8 @@ int MachineObject::parse_json(std::string payload)
}
}
#pragma endregion
#pragma region status
@ -1967,6 +2089,32 @@ int MachineObject::parse_json(std::string payload)
catch (...) {
;
}
try {
if (jj.contains("xcam")) {
if (xcam_first_layer_hold_count > 0)
xcam_first_layer_hold_count--;
else {
if (jj["xcam"].contains("first_layer_inspector")) {
xcam_first_layer_inspector = jj["xcam"]["first_layer_inspector"].get<bool>();
}
}
if (xcam_spaghetti_hold_count > 0) {
xcam_spaghetti_hold_count--;
} else {
if (jj["xcam"].contains("spaghetti_detector")) {
xcam_spaghetti_detector = jj["xcam"]["spaghetti_detector"].get<bool>();
}
if (jj["xcam"].contains("print_halt")) {
xcam_spaghetti_print_halt = jj["xcam"]["print_halt"].get<bool>();
}
}
}
}
catch (...) {
;
}
#pragma endregion
#pragma region hms
@ -2112,9 +2260,10 @@ int MachineObject::parse_json(std::string payload)
curr_tray->setting_id = (*tray_it)["tray_info_idx"].get<std::string>();
std::string type = (*tray_it)["tray_type"].get<std::string>();
if (curr_tray->setting_id == "GFS00") {
curr_tray->type = "Support W";
} else if (curr_tray->setting_id == "GFS01") {
curr_tray->type = "Support G";
curr_tray->type = "PLA-S";
}
else if (curr_tray->setting_id == "GFS01") {
curr_tray->type = "PA-S";
} else {
curr_tray->type = type;
}
@ -2243,6 +2392,18 @@ int MachineObject::parse_json(std::string payload)
BOOST_LOG_TRIVIAL(warning) << "ams_filament_setting, can not find in amsList, ams_id=" << ams_id;
}
}
} else if (jj["command"].get<std::string>() == "xcam_control_set") {
if (jj.contains("module_name") && jj.contains("control")) {
if (jj["module_name"].get<std::string>() == "first_layer_inspector") {
xcam_first_layer_inspector = jj["control"].get<bool>();
xcam_first_layer_hold_count = HOLD_COUNT_MAX;
} else if (jj["module_name"].get<std::string>() == "spaghetti_detector") {
xcam_spaghetti_detector = jj["control"].get<bool>();
xcam_spaghetti_hold_count = HOLD_COUNT_MAX;
if (jj.contains("print_halt"))
xcam_spaghetti_print_halt = jj["print_halt"].get<bool>();
}
}
}
}
}
@ -2352,7 +2513,7 @@ void MachineObject::update_slice_info(std::string project_id, std::string profil
BOOST_LOG_TRIVIAL(trace) << "slice_info: start";
slice_info = new BBLSliceInfo();
auto get_slice_info_thread = boost::thread([this, project_id, profile_id, subtask_id, plate_idx] {
get_slice_info_thread = new boost::thread([this, project_id, profile_id, subtask_id, plate_idx] {
int plate_index = -1;
if (!m_agent) return;
@ -2360,6 +2521,8 @@ void MachineObject::update_slice_info(std::string project_id, std::string profil
if (plate_idx >= 0) {
plate_index = plate_idx;
} else {
if (subtask_id.compare("0") == 0)
return;
m_agent->get_task_plate_index(subtask_id, &plate_index);
}
@ -2686,6 +2849,7 @@ void DeviceManager::clean_user_info()
BOOST_LOG_TRIVIAL(trace) << "DeviceManager::clean_user_info";
// reset selected_machine
selected_machine = "";
local_selected_machine = "";
// clean access code
for (auto it = userMachineList.begin(); it != userMachineList.end(); it++) {

View file

@ -21,6 +21,8 @@
#define FILAMENT_DEF_TEMP 220
#define FILAMENT_MIN_TEMP 120
#define HOLD_COUNT_MAX 3
inline int correct_filament_temperature(int filament_temp)
{
int temp = std::min(filament_temp, FILAMENT_MAX_TEMP);
@ -159,11 +161,14 @@ public:
AmsStep step_state;
AmsRfidState rfid_state;
void set_hold_count() { hold_count = 3; }
void set_hold_count() { hold_count = HOLD_COUNT_MAX; }
void update_color_from_str(std::string color);
wxColour get_color();
bool is_tray_info_ready();
bool is_unset_third_filament();
std::string get_display_filament_type();
std::string get_filament_type();
};
@ -362,6 +367,8 @@ public:
int ams_filament_mapping(std::vector<FilamentInfo> filaments, std::vector<FilamentInfo> &result, std::vector<int> exclude_id = std::vector<int>());
bool is_valid_mapping_result(std::vector<FilamentInfo>& result);
// exceed index start with 0
bool is_mapping_exceed_filament(std::vector<FilamentInfo>& result, int &exceed_index);
void reset_mapping_result(std::vector<FilamentInfo>& result);
@ -426,6 +433,7 @@ public:
int mc_left_time; /* left time in seconds */
int last_mc_print_stage;
bool is_system_printing();
int print_error;
std::vector<int> stage_list_info;
int stage_curr = 0;
@ -452,6 +460,11 @@ public:
bool camera_recording { false };
bool camera_timelapse { false };
bool camera_has_sdcard { false };
bool xcam_first_layer_inspector { false };
int xcam_first_layer_hold_count = 0;
bool xcam_spaghetti_detector { false };
bool xcam_spaghetti_print_halt{ false };
int xcam_spaghetti_hold_count = 0;
/* HMS */
std::vector<HMSItem> hms_list;
@ -468,6 +481,8 @@ public:
std::string task_id_;
std::string subtask_id_;
BBLSliceInfo* slice_info {nullptr};
boost::thread* get_slice_info_thread { nullptr };
int plate_index { -1 };
std::string m_gcode_file;
int gcode_file_prepare_percent = 0;
@ -525,6 +540,9 @@ public:
// camera control
int command_ipcam_record(bool on_off);
int command_ipcam_timelapse(bool on_off);
int command_xcam_control(std::string module_name, bool on_off, bool print_halt);
int command_xcam_control_first_layer_inspector(bool on_off, bool print_halt);
int command_xcam_control_spaghetti_detector(bool on_off, bool print_halt);
/* common apis */
inline bool is_local() { return !dev_ip.empty(); }

View file

@ -317,25 +317,14 @@ wxWindow* BitmapChoiceRenderer::CreateEditorCtrl(wxWindow* parent, wxRect labelR
c_editor->SetSelection(atoi(data.GetText().c_str()) - 1);
#ifndef _WIN32
c_editor->Bind(wxEVT_COMBOBOX, [this, c_editor](wxCommandEvent& evt) {
#ifdef __linux__
c_editor->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent& evt) {
// to avoid event propagation to other sidebar items
evt.StopPropagation();
// FinishEditing grabs new selection and triggers config update. We better call
// it explicitly, automatic update on KILL_FOCUS didn't work on Linux.
c_editor->SetClientData(this);
this->FinishEditing();
});
c_editor->Bind(wxEVT_COMBOBOX_DROPDOWN, [this, c_editor](wxCommandEvent& evt) {
c_editor->SetClientData(this);
this->FinishEditing();
});
c_editor->Bind(wxEVT_KILL_FOCUS, [this, c_editor](wxFocusEvent& evt) {
if (!c_editor->GetDropDown().IsShown() && c_editor->GetClientData() == nullptr) { // TODO: Fix called twice
c_editor->SetClientData(this);
this->FinishEditing();
}
}, c_editor->GetId());
#else
// to avoid event propagation to other sidebar items
c_editor->Bind(wxEVT_COMBOBOX, [](wxCommandEvent& evt) { evt.StopPropagation(); });

View file

@ -195,22 +195,21 @@ void Field::toggle(bool en) { en && !m_opt.readonly ? enable() : disable(); }
wxString Field::get_tooltip_text(const wxString &default_string)
{
wxString tooltip_text("");
//wxString tooltip = _(m_opt.tooltip);
// edit_tooltip(tooltip);
#ifdef NDEBUG
wxString tooltip = _(m_opt.tooltip);
edit_tooltip(tooltip);
// std::string opt_id = m_opt_id;
// auto hash_pos = opt_id.find("#");
// if (hash_pos != std::string::npos) {
// opt_id.replace(hash_pos, 1,"[");
// opt_id += "]";
// }
//if (tooltip.length() > 0)
// tooltip_text = tooltip + "\n" + _(L("default value")) + "\t: " +
// (boost::iends_with(opt_id, "_gcode") ? "\n" : "") + default_string +
// (boost::iends_with(opt_id, "_gcode") ? "" : "\n") +
// _(L("parameter name")) + "\t: " + opt_id;
std::string opt_id = m_opt_id;
auto hash_pos = opt_id.find("#");
if (hash_pos != std::string::npos) {
opt_id.replace(hash_pos, 1,"[");
opt_id += "]";
}
if (tooltip.length() > 0)
tooltip_text = tooltip + "\n" +
_(L("parameter name")) + "\t: " + opt_id;
#endif
return tooltip_text;
}
@ -374,9 +373,17 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true
if (x_str.ToDouble(&x) && thumbnail.HasMoreTokens()) {
wxString y_str = thumbnail.GetNextToken();
if (y_str.ToDouble(&y) && !thumbnail.HasMoreTokens()) {
if (0 < x && x < 1000 && 0 < y && y < 1000) {
out_values.push_back(Vec2d(x, y));
continue;
if (m_opt_id == "bed_exclude_area") {
if (0 <= x && x <= 256 && 0 <= y && y <= 256) {
out_values.push_back(Vec2d(x, y));
continue;
}
}
else {
if (0 < x && x < 1000 && 0 < y && y < 1000) {
out_values.push_back(Vec2d(x, y));
continue;
}
}
out_of_range_val = true;
break;

View file

@ -1070,7 +1070,6 @@ void GCodeViewer::reset()
}
m_paths_bounding_box = BoundingBoxf3();
m_max_bounding_box = BoundingBoxf3();
m_shell_bounding_box = BoundingBoxf3();
m_max_print_height = 0.0f;
m_tools.m_tool_colors = std::vector<Color>();
m_tools.m_tool_visibles = std::vector<bool>();
@ -4423,7 +4422,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
};
const bool visible = m_buffers[buffer_id(type)].visible;
if (type == EMoveType::Travel) {
//TODO display travel time, salt.wei
//TODO display travel time
append_option_item_with_type(type, Travel_Colors[0], _u8L("Travel"), visible);
}
else if (type == EMoveType::Seam)

View file

@ -27,6 +27,7 @@
#include "slic3r/Utils/UndoRedo.hpp"
#include "slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp"
#include "slic3r/GUI/BitmapCache.hpp"
#include "slic3r/Utils/MacDarkMode.hpp"
#include "GUI_App.hpp"
#include "GUI_ObjectList.hpp"
@ -739,6 +740,15 @@ void GLCanvas3D::set_as_dirty()
m_dirty = true;
}
const float GLCanvas3D::get_scale() const
{
#if ENABLE_RETINA_GL
return m_retina_helper->get_scale_factor();
#else
return 1.0f;
#endif
}
unsigned int GLCanvas3D::get_volumes_count() const
{
return (unsigned int)m_volumes.volumes.size();
@ -2133,8 +2143,15 @@ void GLCanvas3D::bind_event_handlers()
m_canvas->Bind(wxEVT_RIGHT_DCLICK, &GLCanvas3D::on_mouse, this);
m_canvas->Bind(wxEVT_PAINT, &GLCanvas3D::on_paint, this);
m_canvas->Bind(wxEVT_SET_FOCUS, &GLCanvas3D::on_set_focus, this);
m_canvas->Bind(wxEVT_KILL_FOCUS, &GLCanvas3D::on_kill_focus, this);
m_event_handlers_bound = true;
m_canvas->Bind(wxEVT_GESTURE_PAN, &GLCanvas3D::on_gesture, this);
m_canvas->Bind(wxEVT_GESTURE_ZOOM, &GLCanvas3D::on_gesture, this);
m_canvas->Bind(wxEVT_GESTURE_ROTATE, &GLCanvas3D::on_gesture, this);
m_canvas->EnableTouchEvents(wxTOUCH_ZOOM_GESTURE | wxTOUCH_ROTATE_GESTURE);
#if __WXOSX__
initGestures(m_canvas->GetHandle(), m_canvas); // for UIPanGestureRecognizer allowedScrollTypesMask
#endif
}
}
@ -2163,9 +2180,11 @@ void GLCanvas3D::unbind_event_handlers()
m_canvas->Unbind(wxEVT_RIGHT_DCLICK, &GLCanvas3D::on_mouse, this);
m_canvas->Unbind(wxEVT_PAINT, &GLCanvas3D::on_paint, this);
m_canvas->Unbind(wxEVT_SET_FOCUS, &GLCanvas3D::on_set_focus, this);
m_canvas->Unbind(wxEVT_KILL_FOCUS, &GLCanvas3D::on_kill_focus, this);
m_event_handlers_bound = false;
m_canvas->Unbind(wxEVT_GESTURE_PAN, &GLCanvas3D::on_gesture, this);
m_canvas->Unbind(wxEVT_GESTURE_ZOOM, &GLCanvas3D::on_gesture, this);
m_canvas->Unbind(wxEVT_GESTURE_ROTATE, &GLCanvas3D::on_gesture, this);
}
}
@ -2935,6 +2954,40 @@ std::string format_mouse_event_debug_message(const wxMouseEvent &evt)
}
#endif /* SLIC3R_DEBUG_MOUSE_EVENTS */
void GLCanvas3D::on_gesture(wxGestureEvent &evt)
{
if (!m_initialized || !_set_current())
return;
auto & camera = wxGetApp().plater()->get_camera();
if (evt.GetEventType() == wxEVT_GESTURE_PAN) {
auto p = evt.GetPosition();
auto d = static_cast<wxPanGestureEvent&>(evt).GetDelta();
float z = 0;
const Vec3d &p2 = _mouse_to_3d({p.x, p.y}, &z);
const Vec3d &p1 = _mouse_to_3d({p.x - d.x, p.y - d.y}, &z);
camera.set_target(camera.get_target() + p2 - p1);
} else if (evt.GetEventType() == wxEVT_GESTURE_ZOOM) {
static float zoom_start = 1;
if (evt.IsGestureStart())
zoom_start = camera.get_zoom();
camera.set_zoom(zoom_start * static_cast<wxZoomGestureEvent&>(evt).GetZoomFactor());
} else if (evt.GetEventType() == wxEVT_GESTURE_ROTATE) {
PartPlate* plate = wxGetApp().plater()->get_partplate_list().get_curr_plate();
bool rotate_limit = current_printer_technology() != ptSLA;
static double last_rotate = 0;
if (evt.IsGestureStart())
last_rotate = 0;
auto rotate = static_cast<wxRotateGestureEvent&>(evt).GetRotationAngle() - last_rotate;
last_rotate += rotate;
if (plate)
camera.rotate_on_sphere_with_target(-rotate, 0, rotate_limit, plate->get_bounding_box().center());
else
camera.rotate_on_sphere(-rotate, 0, rotate_limit);
}
m_dirty = true;
}
void GLCanvas3D::on_mouse(wxMouseEvent& evt)
{
if (!m_initialized || !_set_current())
@ -3136,7 +3189,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
return;
}
if (evt.LeftDown() && (evt.ShiftDown() || evt.AltDown()) && m_picking_enabled) {
// BBS: define Alt key to enable volume selection mode
m_selection.set_volume_selection_mode(evt.AltDown() ? Selection::Volume : Selection::Instance);
if (evt.LeftDown() && evt.ShiftDown() && m_picking_enabled) {
if (m_gizmos.get_current_type() != GLGizmosManager::SlaSupports
&& m_gizmos.get_current_type() != GLGizmosManager::FdmSupports
&& m_gizmos.get_current_type() != GLGizmosManager::Seam
@ -3484,19 +3539,14 @@ void GLCanvas3D::on_set_focus(wxFocusEvent& evt)
{
m_tooltip_enabled = false;
if (m_canvas_type == ECanvasType::CanvasPreview) {
// update thumbnails and update plate toolbar
wxGetApp().plater()->update_platplate_thumbnails();
_update_imgui_select_plate_toolbar();
}
_refresh_if_shown_on_screen();
m_tooltip_enabled = true;
}
void GLCanvas3D::on_kill_focus(wxFocusEvent& evt)
{
if (m_canvas_type == ECanvasType::CanvasView3D) {
wxGetApp().plater()->update_platplate_thumbnails();
}
}
Size GLCanvas3D::get_canvas_size() const
{
int w = 0;
@ -4363,7 +4413,7 @@ bool GLCanvas3D::_render_orient_menu(float left, float right, float bottom, floa
//now change to left_up as {0,0}, and top is 0, bottom is canvas_h
#if BBS_TOOLBAR_ON_TOP
const float x = left * float(wxGetApp().plater()->get_camera().get_zoom()) + 0.5f * canvas_w;
ImGuiWrapper::push_toolbar_style();
ImGuiWrapper::push_toolbar_style(get_scale());
imgui->set_next_window_pos(x, m_main_toolbar.get_height(), ImGuiCond_Always, 0.5f, 0.0f);
#else
const float x = canvas_w - m_main_toolbar.get_width();
@ -4459,7 +4509,7 @@ bool GLCanvas3D::_render_arrange_menu(float left, float right, float bottom, flo
#endif
//BBS
ImGuiWrapper::push_toolbar_style();
ImGuiWrapper::push_toolbar_style(get_scale());
imgui->begin(_L("Arrange options"), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar);
@ -5026,7 +5076,7 @@ bool GLCanvas3D::_init_main_toolbar()
item.name = "add";
item.icon_filename = "toolbar_open.svg";
item.tooltip = _utf8(L("Add"));
item.tooltip = _utf8(L("Add")) + " [" + GUI::shortkey_ctrl_prefix() + "I]";
item.sprite_id = 0;
item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_ADD)); };
item.enabling_callback = []()->bool {return wxGetApp().plater()->can_add_model(); };
@ -5064,7 +5114,7 @@ bool GLCanvas3D::_init_main_toolbar()
item.name = "arrange";
item.icon_filename = "toolbar_arrange.svg";
item.tooltip = _utf8(L("Auto arrange"));
item.tooltip = _utf8(L("Arrange all objects")) + " [A]\n" + _utf8(L("Arrange objects on selected plates")) + " [Shift+A]";
item.sprite_id++;
item.left.action_callback = []() {};
item.enabling_callback = []()->bool { return wxGetApp().plater()->can_arrange(); };
@ -6404,7 +6454,9 @@ void GLCanvas3D::_render_paint_toolbar() const
for (auto filament_name : preset_bundle->filament_presets) {
for (auto iter = preset_bundle->filaments.lbegin(); iter != preset_bundle->filaments.end(); iter++) {
if (filament_name.compare(iter->name) == 0) {
filament_types.push_back(iter->config.get_filament_type());
std::string display_filament_type;
iter->config.get_filament_type(display_filament_type);
filament_types.push_back(display_filament_type);
}
}
}
@ -6541,7 +6593,7 @@ void GLCanvas3D::_render_explosion_control() const
ImGuiWrapper* imgui = wxGetApp().imgui();
ImGuiWrapper::push_toolbar_style();
ImGuiWrapper::push_toolbar_style(get_scale());
auto canvas_w = float(get_canvas_size().get_width());
auto canvas_h = float(get_canvas_size().get_height());
@ -6611,7 +6663,7 @@ void GLCanvas3D::_render_assemble_info() const
ImGui::PushFont(font);
ImGui::PopFont();
imgui->set_next_window_pos(canvas_w - window_width, 0.0f, ImGuiCond_Always, 0, 0);
ImGuiWrapper::push_toolbar_style();
ImGuiWrapper::push_toolbar_style(get_scale());
imgui->begin(_L("Assembly Info"), ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse);
font->Scale = origScale;
ImGui::PushFont(font);

View file

@ -361,7 +361,7 @@ public:
// float distance_seq_print = 6.; // Used when sequential print is ON
// float distance_sla = 6.;
float accuracy = 0.65f; // Unused currently
bool enable_rotation = true;
bool enable_rotation = false;
bool allow_multi_materials_on_same_plate = true;
bool avoid_extrusion_cali_region = true;
//BBS: add more arrangeSettings
@ -600,6 +600,7 @@ public:
const GLVolumeCollection& get_volumes() const { return m_volumes; }
void reset_volumes();
ModelInstanceEPrintVolumeState check_volumes_outside_state() const;
const float get_scale() const;
//BBS
GCodeViewer& get_gcode_viewer() { return m_gcode_viewer; }
@ -765,9 +766,9 @@ public:
void on_timer(wxTimerEvent& evt);
void on_render_timer(wxTimerEvent& evt);
void on_mouse(wxMouseEvent& evt);
void on_gesture(wxGestureEvent& evt);
void on_paint(wxPaintEvent& evt);
void on_set_focus(wxFocusEvent& evt);
void on_kill_focus(wxFocusEvent& evt);
Size get_canvas_size() const;
Vec2d get_local_mouse_position() const;
@ -909,6 +910,10 @@ public:
bool is_object_sinking(int object_idx) const;
// Convert the screen space coordinate to an object space coordinate.
// If the Z screen space coordinate is not provided, a depth buffer value is substituted.
Vec3d _mouse_to_3d(const Point& mouse_pos, float* z = nullptr);
private:
bool _is_shown_on_screen() const;
@ -981,10 +986,6 @@ private:
void _update_volumes_hover_state();
// Convert the screen space coordinate to an object space coordinate.
// If the Z screen space coordinate is not provided, a depth buffer value is substituted.
Vec3d _mouse_to_3d(const Point& mouse_pos, float* z = nullptr);
// Convert the screen space coordinate to world coordinate on the bed.
Vec3d _mouse_to_bed_3d(const Point& mouse_pos);

View file

@ -197,7 +197,7 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt
}
break;
case coPoints:{
if (opt_key == "printable_area") {
if (opt_key == "printable_area" || opt_key == "bed_exclude_area") {
config.option<ConfigOptionPoints>(opt_key)->values = boost::any_cast<std::vector<Vec2d>>(value);
break;
}

View file

@ -187,9 +187,9 @@ public:
scale_bitmap(m_main_bitmap, m_scale);
// init constant texts and scale fonts
m_constant_text.init(get_default_font(this));
m_constant_text.init(Label::Body_16);
scale_font(m_constant_text.title_font, 2.0f);
scale_font(m_constant_text.version_font, 1.5f);
scale_font(m_constant_text.version_font, 1.2f);
// this font will be used for the action string
m_action_font = m_constant_text.credits_font;
@ -930,23 +930,32 @@ void GUI_App::post_init()
bool switch_to_3d = false;
if (!this->init_params->input_files.empty()) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", init with input files, size %1%, input_gcode %2%")
%this->init_params->input_files.size() %this->init_params->input_gcode;
switch_to_3d = true;
mainframe->select_tab(size_t(MainFrame::tp3DEditor));
plater_->select_view_3D("3D");
const std::vector<size_t> res = this->plater()->load_files(this->init_params->input_files);
if (!res.empty()) {
if (this->init_params->input_files.size() == 1) {
// Update application titlebar when opening a project file
const std::string& filename = this->init_params->input_files.front();
//BBS: remove amf logic as project
if (boost::algorithm::iends_with(filename, ".3mf"))
this->plater()->set_project_filename(from_u8(filename));
if (this->init_params->input_gcode) {
mainframe->select_tab(size_t(MainFrame::tp3DEditor));
plater_->select_view_3D("3D");
this->plater()->load_gcode(from_u8(this->init_params->input_files.front()));
}
else {
mainframe->select_tab(size_t(MainFrame::tp3DEditor));
plater_->select_view_3D("3D");
const std::vector<size_t> res = this->plater()->load_files(this->init_params->input_files);
if (!res.empty()) {
if (this->init_params->input_files.size() == 1) {
// Update application titlebar when opening a project file
const std::string& filename = this->init_params->input_files.front();
//BBS: remove amf logic as project
if (boost::algorithm::iends_with(filename, ".3mf"))
this->plater()->set_project_filename(from_u8(filename));
}
}
}
}
#if BBL_HAS_FIRST_PAGE
if (!switch_to_3d) {
BOOST_LOG_TRIVIAL(info) << "begin load_gl_resources";
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", begin load_gl_resources";
mainframe->Freeze();
plater_->canvas3D()->enable_render(false);
mainframe->select_tab(size_t(MainFrame::tp3DEditor));
@ -954,26 +963,26 @@ void GUI_App::post_init()
//BBS init the opengl resource here
Size canvas_size = plater_->canvas3D()->get_canvas_size();
wxGetApp().imgui()->set_display_size(static_cast<float>(canvas_size.get_width()), static_cast<float>(canvas_size.get_height()));
BOOST_LOG_TRIVIAL(info) << "start to init opengl";
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", start to init opengl";
wxGetApp().init_opengl();
BOOST_LOG_TRIVIAL(info) << "finished init opengl";
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished init opengl";
plater_->canvas3D()->init();
BOOST_LOG_TRIVIAL(info) << "finished init canvas3D";
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished init canvas3D";
wxGetApp().imgui()->new_frame();
BOOST_LOG_TRIVIAL(info) << "finished init imgui frame";
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished init imgui frame";
plater_->canvas3D()->enable_render(true);
BOOST_LOG_TRIVIAL(info) << "start to render a first frame for test";
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", start to render a first frame for test";
plater_->canvas3D()->render(false);
BOOST_LOG_TRIVIAL(info) << "finished rendering a first frame for test";
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished rendering a first frame for test";
if (is_editor())
mainframe->select_tab(size_t(0));
mainframe->Thaw();
plater_->trigger_restore_project(1);
BOOST_LOG_TRIVIAL(info) << "end load_gl_resources";
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", end load_gl_resources";
}
#endif
@ -1046,7 +1055,8 @@ void GUI_App::post_init()
bool cw_showed = this->config_wizard_startup();
std::string http_url = get_http_url(app_config->get_country_code());
this->preset_updater->sync(http_url, preset_bundle);
std::string language = GUI::into_u8(current_language_code());
this->preset_updater->sync(http_url, language, preset_bundle);
//BBS: check new version
this->check_new_version();
@ -1056,16 +1066,19 @@ void GUI_App::post_init()
if(!m_networking_need_update && m_agent) {
m_agent->set_on_ssdp_msg_fn(
[this](std::string json_str) {
if (m_is_closing) {
return;
}
GUI::wxGetApp().CallAfter([this, json_str] {
if (m_is_closing) {
return;
}
if (m_device_manager) {
m_device_manager->on_machine_alive(json_str);
}
});
}
);
m_agent->set_on_http_error_fn([this](unsigned int status, std::string body) {
this->handle_http_error(status, body);
});
m_agent->start_discovery(true, false);
}
@ -1105,6 +1118,26 @@ GUI_App::GUI_App()
reset_to_active();
}
void GUI_App::shutdown()
{
BOOST_LOG_TRIVIAL(info) << "shutdown";
if (m_is_recreating_gui) return;
m_is_closing = true;
stop_sync_user_preset();
if (m_device_manager) {
delete m_device_manager;
m_device_manager = nullptr;
}
if (m_agent) {
m_agent->start_discovery(false, false);
delete m_agent;
m_agent = nullptr;
}
}
std::string GUI_App::get_http_url(std::string country_code)
{
@ -1196,7 +1229,7 @@ int GUI_App::download_plugin(InstallProgressFn pro_fn, WasCancelledFn cancel_fn)
for (auto sub_iter = iter.value().begin(); sub_iter != iter.value().end(); sub_iter++) {
if (boost::iequals(sub_iter.key(), "type")) {
type = sub_iter.value();
BOOST_LOG_TRIVIAL(info) << "[BBL Updater]: get version of settings's type, " << sub_iter.value();
BOOST_LOG_TRIVIAL(info) << "[download_plugin]: get version of settings's type, " << sub_iter.value();
}
else if (boost::iequals(sub_iter.key(), "version")) {
version = *(Semver::parse(sub_iter.value()));
@ -1208,22 +1241,22 @@ int GUI_App::download_plugin(InstallProgressFn pro_fn, WasCancelledFn cancel_fn)
url = sub_iter.value();
}
}
BOOST_LOG_TRIVIAL(info) << "[download_plugin]: get type " << type << ", version " << version.to_string() << ", url " << url;
BOOST_LOG_TRIVIAL(info) << "[download_plugin 1]: get type " << type << ", version " << version.to_string() << ", url " << url;
download_url = url;
}
}
}
else {
BOOST_LOG_TRIVIAL(info) << "[download_plugin]: get version of plugin failed, body=" << body;
BOOST_LOG_TRIVIAL(info) << "[download_plugin 1]: get version of plugin failed, body=" << body;
}
}
catch (...) {
BOOST_LOG_TRIVIAL(error) << "[download_plugin]: catch unknown exception";
BOOST_LOG_TRIVIAL(error) << "[download_plugin 1]: catch unknown exception";
;
}
}).on_error(
[&result](std::string body, std::string error, unsigned int status) {
BOOST_LOG_TRIVIAL(error) << "" << body;
BOOST_LOG_TRIVIAL(error) << "[download_plugin 1] on_error: " << error<<", body = " << body;
result = -1;
}).perform_sync();
@ -1235,7 +1268,7 @@ int GUI_App::download_plugin(InstallProgressFn pro_fn, WasCancelledFn cancel_fn)
if (download_url.empty()) {
BOOST_LOG_TRIVIAL(info) << "[download_plugin]: no availaible plugin found for this app version: " << SLIC3R_VERSION;
BOOST_LOG_TRIVIAL(info) << "[download_plugin 1]: no availaible plugin found for this app version: " << SLIC3R_VERSION;
if (pro_fn) pro_fn(InstallStatusDownloadFailed, 0, cancel);
return -1;
}
@ -1244,10 +1277,10 @@ int GUI_App::download_plugin(InstallProgressFn pro_fn, WasCancelledFn cancel_fn)
}
if (m_networking_cancel_update || cancel) {
BOOST_LOG_TRIVIAL(info) << boost::format("download_plugin: %1%, cancelled by user") % __LINE__;
BOOST_LOG_TRIVIAL(info) << boost::format("[download_plugin 1]: %1%, cancelled by user") % __LINE__;
return -1;
}
BOOST_LOG_TRIVIAL(info) << "download_plugin, get_url = " << download_url;
BOOST_LOG_TRIVIAL(info) << "[download_plugin] get_url = " << download_url;
// download
Slic3r::Http http = Slic3r::Http::get(download_url);
@ -1261,6 +1294,7 @@ int GUI_App::download_plugin(InstallProgressFn pro_fn, WasCancelledFn cancel_fn)
if (pro_fn && ((percent - reported_percent) >= 10)) {
pro_fn(InstallStatusNormal, percent, was_cancel);
reported_percent = percent;
BOOST_LOG_TRIVIAL(info) << "[download_plugin 2] progress: " << reported_percent;
}
cancel = m_networking_cancel_update || was_cancel;
if (cancel_fn)
@ -1271,7 +1305,7 @@ int GUI_App::download_plugin(InstallProgressFn pro_fn, WasCancelledFn cancel_fn)
result = -1;
})
.on_complete([&pro_fn, tmp_path, target_file_path](std::string body, unsigned status) {
BOOST_LOG_TRIVIAL(info) << "download_plugin, completed";
BOOST_LOG_TRIVIAL(info) << "[download_plugin 2] completed";
bool cancel = false;
int percent = 0;
fs::fstream file(tmp_path, std::ios::out | std::ios::binary | std::ios::trunc);
@ -1283,6 +1317,7 @@ int GUI_App::download_plugin(InstallProgressFn pro_fn, WasCancelledFn cancel_fn)
.on_error([&pro_fn, &result](std::string body, std::string error, unsigned int status) {
bool cancel = false;
if (pro_fn) pro_fn(InstallStatusDownloadFailed, 0, cancel);
BOOST_LOG_TRIVIAL(error) << "[download_plugin 2] on_error: " << error<<", body = " << body;
result = -1;
});
http.perform_sync();
@ -1293,14 +1328,22 @@ int GUI_App::install_plugin(InstallProgressFn pro_fn, WasCancelledFn cancel_fn)
{
bool cancel = false;
std::string target_file_path = (fs::temp_directory_path() / "network_plugin.zip").string();
BOOST_LOG_TRIVIAL(info) << "[install_plugin] enter";
// get plugin folder
auto plugin_folder = boost::filesystem::path(wxStandardPaths::Get().GetUserDataDir().ToUTF8().data()) / "plugins";
auto backup_folder = plugin_folder/"backup";
if (!boost::filesystem::exists(plugin_folder)) {
BOOST_LOG_TRIVIAL(info) << "[install_plugin] will create directory "<<plugin_folder.string();
boost::filesystem::create_directory(plugin_folder);
}
if (!boost::filesystem::exists(backup_folder)) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", will create directory %1%")%backup_folder.string();
boost::filesystem::create_directory(backup_folder);
}
if (m_networking_cancel_update) {
BOOST_LOG_TRIVIAL(info) << boost::format("install_plugin: %1%, cancelled by user")%__LINE__;
BOOST_LOG_TRIVIAL(info) << boost::format("[install_plugin]: %1%, cancelled by user")%__LINE__;
return -1;
}
if (pro_fn) {
@ -1310,17 +1353,17 @@ int GUI_App::install_plugin(InstallProgressFn pro_fn, WasCancelledFn cancel_fn)
mz_zip_archive archive;
mz_zip_zero_struct(&archive);
if (!open_zip_reader(&archive, target_file_path)) {
BOOST_LOG_TRIVIAL(error) << boost::format("install_plugin: %1%, open zip file failed")%__LINE__;
BOOST_LOG_TRIVIAL(error) << boost::format("[install_plugin]: %1%, open zip file failed")%__LINE__;
if (pro_fn) pro_fn(InstallStatusDownloadFailed, 0, cancel);
return InstallStatusUnzipFailed;
}
mz_uint num_entries = mz_zip_reader_get_num_files(&archive);
mz_zip_archive_file_stat stat;
BOOST_LOG_TRIVIAL(error) << boost::format("install_plugin: %1%, got %2% files")%__LINE__ %num_entries;
BOOST_LOG_TRIVIAL(error) << boost::format("[install_plugin]: %1%, got %2% files")%__LINE__ %num_entries;
for (mz_uint i = 0; i < num_entries; i++) {
if (m_networking_cancel_update || cancel) {
BOOST_LOG_TRIVIAL(info) << boost::format("install_plugin: %1%, cancelled by user")%__LINE__;
BOOST_LOG_TRIVIAL(info) << boost::format("[install_plugin]: %1%, cancelled by user")%__LINE__;
return -1;
}
if (mz_zip_reader_file_stat(&archive, i, &stat)) {
@ -1356,6 +1399,21 @@ int GUI_App::install_plugin(InstallProgressFn pro_fn, WasCancelledFn cancel_fn)
if (pro_fn) {
pro_fn(InstallStatusNormal, 50 + i/num_entries, cancel);
}
try {
auto backup_path = boost::filesystem::path(backup_folder.string() + "/" + dest_file);
if (fs::exists(backup_path))
fs::remove(backup_path);
std::string error_message;
CopyFileResult cfr = copy_file(dest_path.string(), backup_path.string(), error_message, false);
if (cfr != CopyFileResult::SUCCESS) {
BOOST_LOG_TRIVIAL(error) << "Copying to backup failed(" << cfr << "): " << error_message;
}
}
catch (const std::exception& e)
{
BOOST_LOG_TRIVIAL(error) << "Copying to backup failed: " << e.what();
//continue
}
}
}
catch (const std::exception& e)
@ -1371,7 +1429,7 @@ int GUI_App::install_plugin(InstallProgressFn pro_fn, WasCancelledFn cancel_fn)
}
}
else {
BOOST_LOG_TRIVIAL(error) << boost::format("install_plugin: %1%, mz_zip_reader_file_stat for file %2% failed")%__LINE__%i;
BOOST_LOG_TRIVIAL(error) << boost::format("[install_plugin]: %1%, mz_zip_reader_file_stat for file %2% failed")%__LINE__%i;
}
}
@ -1380,27 +1438,31 @@ int GUI_App::install_plugin(InstallProgressFn pro_fn, WasCancelledFn cancel_fn)
if (pro_fn)
pro_fn(InstallStatusInstallCompleted, 100, cancel);
app_config->set_str("app", "installed_networking", "1");
BOOST_LOG_TRIVIAL(info) << "[install_plugin] success";
return 0;
}
void GUI_App::restart_networking()
{
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(" enter, mainframe %1%")%mainframe;
on_init_network();
on_init_network(true);
if(m_agent) {
init_networking_callbacks();
m_agent->set_on_ssdp_msg_fn(
[this](std::string json_str) {
if (m_is_closing) {
return;
}
GUI::wxGetApp().CallAfter([this, json_str] {
if (m_is_closing) {
return;
}
if (m_device_manager) {
m_device_manager->on_machine_alive(json_str);
}
});
}
);
m_agent->set_on_http_error_fn([this](unsigned int status, std::string body) {
this->handle_http_error(status, body);
});
m_agent->start_discovery(true, false);
if (mainframe)
mainframe->refresh_plugin_tips();
@ -1412,7 +1474,7 @@ void GUI_App::restart_networking()
int GUI_App::updating_bambu_networking()
{
DownloadProgressDialog dlg(_L("Downloading Bambu Network plug-in"));
DownloadProgressDialog dlg(_L("Downloading Bambu Network Plug-in"));
dlg.ShowModal();
return 0;
}
@ -1457,20 +1519,20 @@ void GUI_App::init_networking_callbacks()
});
m_agent->set_on_server_connected_fn([this]() {
if (m_is_closing) {
return;
}
GUI::wxGetApp().CallAfter([this] {
if (m_is_closing) {
return;
}
BOOST_LOG_TRIVIAL(trace) << "static: server connected";
m_agent->set_user_selected_machine(m_agent->get_user_selected_machine());
});
});
m_agent->set_on_printer_connected_fn([this](std::string dev_id) {
if (m_is_closing) {
return;
}
GUI::wxGetApp().CallAfter([this, dev_id] {
if (m_is_closing) {
return;
}
/* request_pushing */
MachineObject* obj = m_device_manager->get_my_machine(dev_id);
if (obj) {
@ -1489,6 +1551,9 @@ void GUI_App::init_networking_callbacks()
m_agent->set_on_local_connect_fn(
[this](int state, std::string dev_id, std::string msg) {
if (m_is_closing) {
return;
}
CallAfter([this, state, dev_id, msg] {
if (m_is_closing) {
return;
@ -1502,31 +1567,31 @@ void GUI_App::init_networking_callbacks()
obj->command_get_version();
} else if (state == ConnectStatus::ConnectStatusFailed || ConnectStatus::ConnectStatusLost) {
obj->set_access_code("");
wxString text = wxString::Format(_L("Connect %s[SN:%s] failed!"), from_u8(obj->dev_name), obj->dev_id);
MessageDialog msg_dlg(nullptr, text, "", wxAPPLY | wxOK);
if (msg_dlg.ShowModal() == wxOK) {
return;
wxString text;
if (msg == "5") {
text = wxString::Format(_L("Incorrect password"));
wxGetApp().show_dialog(text);
} else {
text = wxString::Format(_L("Connect %s failed! [SN:%s, code=%s]"), from_u8(obj->dev_name), obj->dev_id, msg);
wxGetApp().show_dialog(text);
}
} else {
BOOST_LOG_TRIVIAL(info) << "set_on_local_connect_fn: state = " << state;
}
}
}
});
});
}
);
m_agent->set_on_http_error_fn([this](unsigned int status, std::string body) {
this->handle_http_error(status, body);
});
auto message_arrive_fn = [this](std::string dev_id, std::string msg) {
if (m_is_closing) {
return;
}
CallAfter([this, dev_id, msg] {
if (m_is_closing) {
return;
}
MachineObject* obj = this->m_device_manager->get_user_machine(dev_id);
if (obj) {
obj->is_ams_need_update = false;
obj->parse_json(msg);
if (this->m_device_manager->get_selected_machine() == obj && obj->is_ams_need_update) {
@ -1539,11 +1604,10 @@ void GUI_App::init_networking_callbacks()
m_agent->set_on_message_fn(message_arrive_fn);
auto lan_message_arrive_fn = [this](std::string dev_id, std::string msg) {
if (m_is_closing) {
return;
}
CallAfter([this, dev_id, msg] {
if (m_is_closing) {
return;
}
MachineObject* obj = m_device_manager->get_my_machine(dev_id);
if (!obj) {
obj = m_device_manager->get_local_machine(dev_id);
@ -1943,13 +2007,13 @@ bool GUI_App::on_init_inner()
});
Bind(EVT_SHOW_DIALOG, [this](const wxCommandEvent& evt) {
/*wxString msg = evt.GetString();
wxString msg = evt.GetString();
InfoDialog dlg(this->mainframe, _L("Info"), msg);
dlg.ShowModal();*/
dlg.ShowModal();
wxString text = evt.GetString();
/*wxString text = evt.GetString();
Slic3r::GUI::MessageDialog msg_dlg(this->mainframe, text, "", wxAPPLY | wxOK);
msg_dlg.ShowModal();
msg_dlg.ShowModal();*/
});
}
else {
@ -2032,7 +2096,9 @@ bool GUI_App::on_init_inner()
}
// BBS:
#ifdef __WINDOWS__
mainframe->topbar()->SaveNormalRect();
#endif
mainframe->Show(true);
BOOST_LOG_TRIVIAL(info) << "main frame firstly shown";
@ -2093,16 +2159,17 @@ bool GUI_App::on_init_inner()
// BBS
//this->obj_manipul()->update_if_dirty();
static bool update_gui_after_init = true;
//use m_post_initialized instead
//static bool update_gui_after_init = true;
// An ugly solution to GH #5537 in which GUI_App::init_opengl (normally called from events wxEVT_PAINT
// and wxEVT_SET_FOCUS before GUI_App::post_init is called) wasn't called before GUI_App::post_init and OpenGL wasn't initialized.
#ifdef __linux__
if (update_gui_after_init && m_opengl_initialized) {
if (!m_post_initialized && m_opengl_initialized) {
#else
if (update_gui_after_init) {
if (!m_post_initialized) {
#endif
update_gui_after_init = false;
m_post_initialized = true;
#ifdef WIN32
this->mainframe->register_win32_callbacks();
#endif
@ -2120,10 +2187,11 @@ bool GUI_App::on_init_inner()
return true;
}
bool GUI_App::on_init_network()
bool GUI_App::on_init_network(bool try_backup)
{
int load_agent_dll = Slic3r::NetworkAgent::initialize_network_module();
bool create_network_agent = false;
__retry:
if (!load_agent_dll) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": on_init_network, load dll ok";
if (check_networking_version()) {
@ -2138,6 +2206,13 @@ bool GUI_App::on_init_network()
else
create_network_agent = true;
} else {
if (try_backup) {
int result = Slic3r::NetworkAgent::unload_network_module();
BOOST_LOG_TRIVIAL(info) << "on_init_network, version mismatch, unload_network_module, result = " << result;
load_agent_dll = Slic3r::NetworkAgent::initialize_network_module(true);
try_backup = false;
goto __retry;
}
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": on_init_network, version dismatch, need upload network module";
if (app_config->get("installed_networking") == "1") {
m_networking_need_update = true;
@ -2240,11 +2315,11 @@ const wxColour GUI_App::get_label_default_clr_modified()
void GUI_App::init_label_colours()
{
m_color_label_modified = wxColour("#F1754E");
m_color_label_sys = wxColour("#2B3436");
m_color_label_sys = wxColour("#323A3D");
bool is_dark_mode = dark_mode();
#ifdef _WIN32
m_color_label_default = is_dark_mode ? wxColour(250, 250, 250): wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
m_color_label_default = is_dark_mode ? wxColour(250, 250, 250) : m_color_label_sys; // wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
m_color_highlight_label_default = is_dark_mode ? wxColour(230, 230, 230): wxSystemSettings::GetColour(/*wxSYS_COLOUR_HIGHLIGHTTEXT*/wxSYS_COLOUR_WINDOWTEXT);
m_color_highlight_default = is_dark_mode ? wxColour(78, 78, 78) : wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT);
m_color_hovered_btn_label = is_dark_mode ? wxColour(253, 111, 40) : wxColour(252, 77, 1);
@ -2523,7 +2598,7 @@ void GUI_App::recreate_GUI(const wxString& msg_name)
dlg.Update(80, _L("Loading current presets") + dots);
load_current_presets();
mainframe->Show(true);
mainframe->refresh_plugin_tips();
//mainframe->refresh_plugin_tips();
dlg.Update(90, _L("Loading a mode view") + dots);
@ -2574,7 +2649,7 @@ void GUI_App::ShowUserGuide() {
void GUI_App::ShowDownNetPluginDlg() {
try {
DownloadProgressDialog dlg(_L("Downloading Bambu Network plug-in"));
DownloadProgressDialog dlg(_L("Downloading Bambu Network Plug-in"));
dlg.ShowModal();
} catch (std::exception &e) {
;
@ -2699,21 +2774,7 @@ void GUI_App::persist_window_geometry(wxTopLevelWindow *window, bool default_max
const std::string name = into_u8(window->GetName());
window->Bind(wxEVT_CLOSE_WINDOW, [=](wxCloseEvent &event) {
m_is_closing = true;
window_pos_save(window, "mainframe");
//
stop_sync_user_preset();
if (m_device_manager) {
delete m_device_manager;
m_device_manager = nullptr;
}
if (m_agent) {
m_agent->start_discovery(false, false);
delete m_agent;
m_agent = nullptr;
}
event.Skip();
});
@ -2823,6 +2884,12 @@ void GUI_App::request_user_login(int online_login)
void GUI_App::request_user_logout()
{
if (m_agent) {
bool transfer_preset_changes = false;
wxString header = _L("Some presets are modified.") + "\n" +
_L("You can keep the modifield presets to the new project, discard or save changes as new presets.");
using ab = UnsavedChangesDialog::ActionButtons;
wxGetApp().check_and_keep_current_preset_changes(_L("User logged out"), header, ab::KEEP | ab::SAVE, &transfer_preset_changes);
m_agent->user_logout();
m_agent->set_user_selected_machine("");
/* delete old user settings */
@ -2936,6 +3003,26 @@ std::string GUI_App::handle_web_request(std::string cmd)
else if (command_str.compare("begin_network_plugin_download") == 0) {
CallAfter([this] { wxGetApp().ShowDownNetPluginDlg(); });
}
else if (command_str.compare("get_web_shortcut") == 0) {
if (root.get_child_optional("key_event") != boost::none) {
pt::ptree key_event_node = root.get_child("key_event");
auto keyCode = key_event_node.get<int>("key");
auto ctrlKey = key_event_node.get<bool>("ctrl");
auto shiftKey = key_event_node.get<bool>("shift");
auto cmdKey = key_event_node.get<bool>("cmd");
wxKeyEvent e(wxEVT_CHAR_HOOK);
#ifdef __APPLE__
e.SetControlDown(cmdKey);
#else
e.SetControlDown(ctrlKey);
#endif
e.SetShiftDown(shiftKey);
e.m_keyCode = keyCode;
e.SetEventObject(mainframe);
wxPostEvent(mainframe, e);
}
}
}
}
catch (...) {
@ -2992,6 +3079,11 @@ void GUI_App::request_project_download(std::string project_id)
void GUI_App::request_open_project(std::string project_id)
{
if (plater()->is_background_process_slicing()) {
Slic3r::GUI::show_info(nullptr, _L("new or open project file is not allowed during the slicing process!"), _L("Open Project"));
return;
}
if (project_id == "<new>")
plater()->new_project();
else if (project_id.empty())
@ -3624,6 +3716,7 @@ bool GUI_App::load_language(wxString language, bool initial)
{"fr", wxString::FromUTF8("\x46\x72\x61\x6E\xC3\xA7\x61\x69\x73")},
{"it", wxString::FromUTF8("\x49\x74\x61\x6C\x69\x61\x6E\x6F")},
{"ru", wxString::FromUTF8("\xD1\x80\xD1\x83\xD1\x81\xD1\x81\xD0\xBA\xD0\xB8\xD0\xB9")},
{"hu", wxString::FromUTF8("Magyar")}
};
for (auto l : language_descptions) {
const wxLanguageInfo *langinfo = wxLocale::FindLanguageInfo(l.first);
@ -3720,13 +3813,22 @@ bool GUI_App::load_language(wxString language, bool initial)
else if (initial) {
// bbs supported languages
//TODO: use a global one with Preference
wxLanguage supported_languages[] {wxLANGUAGE_ENGLISH, wxLANGUAGE_CHINESE_SIMPLIFIED, wxLANGUAGE_GERMAN, wxLANGUAGE_FRENCH, wxLANGUAGE_SPANISH, wxLANGUAGE_SWEDISH, wxLANGUAGE_DUTCH };
wxLanguage supported_languages[] {
wxLANGUAGE_ENGLISH,
wxLANGUAGE_CHINESE_SIMPLIFIED,
wxLANGUAGE_GERMAN,
wxLANGUAGE_FRENCH,
wxLANGUAGE_SPANISH,
wxLANGUAGE_SWEDISH,
wxLANGUAGE_DUTCH,
wxLANGUAGE_HUNGARIAN };
std::string cur_language = app_config->get("language");
if (cur_language != "") {
//cleanup the language wrongly set before
const wxLanguageInfo *langinfo = nullptr;
bool embedded_language = false;
for (auto index = 0; index < 7; index++) {
int language_num = sizeof(supported_languages) / sizeof(supported_languages[0]);
for (auto index = 0; index < language_num; index++) {
langinfo = wxLocale::GetLanguageInfo(supported_languages[index]);
std::string temp_lan = langinfo->CanonicalName.ToUTF8().data();
if (cur_language == temp_lan) {
@ -4283,6 +4385,7 @@ void GUI_App::MacOpenFiles(const wxArrayString &fileNames)
std::vector<std::string> files;
std::vector<wxString> gcode_files;
std::vector<wxString> non_gcode_files;
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", open files, size " << fileNames.size();
for (const auto& filename : fileNames) {
if (is_gcode_file(into_u8(filename)))
gcode_files.emplace_back(filename);
@ -4303,21 +4406,27 @@ void GUI_App::MacOpenFiles(const wxArrayString &fileNames)
} else*/
{
if (! files.empty()) {
wxArrayString input_files;
for (size_t i = 0; i < non_gcode_files.size(); ++i) {
input_files.push_back(non_gcode_files[i]);
if (m_post_initialized) {
wxArrayString input_files;
for (size_t i = 0; i < non_gcode_files.size(); ++i) {
input_files.push_back(non_gcode_files[i]);
}
this->plater()->load_files(input_files);
}
this->plater()->load_files(input_files);
if (gcode_files.size() > 0) {
show_info(this->plater(), _L("G-code files can not be loaded with models together!"), _L("G-code loading"));
else {
for (size_t i = 0; i < files.size(); ++i) {
this->init_params->input_files.emplace_back(files[i]);
}
}
}
else {
wxArrayString input_files;
for (size_t i = 0; i < gcode_files.size(); ++i) {
input_files.push_back(gcode_files[i]);
if (m_post_initialized) {
this->plater()->load_gcode(gcode_files.front());
}
else {
this->init_params->input_gcode = true;
this->init_params->input_files = { into_u8(gcode_files.front()) };
}
this->plater()->load_files(input_files);
}
/*for (const wxString &filename : gcode_files)
start_new_gcodeviewer(&filename);*/
@ -4352,12 +4461,16 @@ const Plater* GUI_App::plater() const
ParamsPanel* GUI_App::params_panel()
{
return mainframe->m_param_panel;
if (mainframe)
return mainframe->m_param_panel;
return nullptr;
}
ParamsDialog* GUI_App::params_dialog()
{
return mainframe->m_param_dialog;
if (mainframe)
return mainframe->m_param_dialog;
return nullptr;
}
Model& GUI_App::model()
@ -4367,22 +4480,28 @@ Model& GUI_App::model()
void GUI_App::load_url(wxString url)
{
return mainframe->load_url(url);
if (mainframe)
return mainframe->load_url(url);
}
void GUI_App::run_script(wxString js)
{
return mainframe->RunScript(js);
if (mainframe)
return mainframe->RunScript(js);
}
Notebook* GUI_App::tab_panel() const
{
return mainframe->m_tabpanel;
if (mainframe)
return mainframe->m_tabpanel;
return nullptr;
}
NotificationManager * GUI_App::notification_manager()
{
return plater_->get_notification_manager();
if (plater_)
return plater_->get_notification_manager();
return nullptr;
}
// extruders count from selected printer preset
@ -4807,8 +4926,15 @@ void GUI_App::disassociate_files(std::wstring extend)
bool is_new = false;
is_new |= del_win_registry(HKEY_CURRENT_USER, reg_extension.c_str(), prog_id.c_str());
is_new |= del_win_registry(HKEY_CURRENT_USER, reg_prog_id.c_str(), prog_desc.c_str());
is_new |= del_win_registry(HKEY_CURRENT_USER, reg_prog_id_command.c_str(), prog_command.c_str());
bool is_associate_3mf = app_config->get("associate_3mf") == "true";
bool is_associate_stl = app_config->get("associate_stl") == "true";
bool is_associate_step = app_config->get("associate_step") == "true";
if (!is_associate_3mf && !is_associate_stl && !is_associate_step)
{
is_new |= del_win_registry(HKEY_CURRENT_USER, reg_prog_id.c_str(), prog_desc.c_str());
is_new |= del_win_registry(HKEY_CURRENT_USER, reg_prog_id_command.c_str(), prog_command.c_str());
}
if (is_new)
::SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr);

View file

@ -100,6 +100,11 @@ enum ConfigMenuIDs {
ConfigMenuCnt,
};
enum BambuStudioMenuIDs {
BambuStudioMenuAbout,
BambuStudioMenuPreferences,
};
enum CameraMenuIDs {
wxID_CAMERA_PERSPECTIVE,
wxID_CAMERA_ORTHOGONAL,
@ -189,7 +194,7 @@ public:
class GUI_App : public wxApp
{
public:
//BBS: remove GCodeViewer as seperate APP logic
enum class EAppMode : unsigned char
{
@ -199,6 +204,7 @@ public:
private:
bool m_initialized { false };
bool m_post_initialized { false };
bool m_app_conf_exists{ false };
EAppMode m_app_mode{ EAppMode::Editor };
bool m_is_recreating_gui{ false };
@ -280,6 +286,7 @@ public:
// Process command line parameters cached in this->init_params,
// load configs, STLs etc.
void post_init();
void shutdown();
// If formatted for github, plaintext with OpenGL extensions enclosed into <details>.
// Otherwise HTML formatted for the system info dialog.
static std::string get_gl_info(bool for_github);
@ -511,7 +518,7 @@ public:
private:
int updating_bambu_networking();
bool on_init_inner();
bool on_init_network();
bool on_init_network(bool try_backup = false);
void init_networking_callbacks();
void init_app_config();
//BBS set extra header for http request

View file

@ -53,7 +53,16 @@ int GUI_Run(GUI_InitParams &params)
GUI::GUI_App::SetInstance(gui);
gui->init_params = &params;
return wxEntry(params.argc, params.argv);
if (params.argc > 1) {
// STUDIO-273 wxWidgets report error when opening some files with specific names
// wxWidgets does not handle parameters, so intercept parameters here, only keep the app name
int argc = 1;
std::vector<char *> argv;
argv.push_back(params.argv[0]);
return wxEntry(argc, argv.data());
} else {
return wxEntry(params.argc, params.argv);
}
} catch (const Slic3r::Exception &ex) {
BOOST_LOG_TRIVIAL(error) << ex.what() << std::endl;
wxMessageBox(boost::nowide::widen(ex.what()), _L("Bambu Studio GUI initialization failed"), wxICON_STOP);

View file

@ -22,6 +22,7 @@ struct GUI_InitParams
//BBS: remove start_as_gcodeviewer logic
//bool start_as_gcodeviewer;
bool input_gcode { false };
};
int GUI_Run(GUI_InitParams &params);

View file

@ -71,9 +71,6 @@ static void take_snapshot(const std::string& snapshot_name)
plater->take_snapshot(snapshot_name);
}
#define ID_OBJECT_ORG_MENU_ITEM_MODULE 11000
#define ID_OBJECT_ORG_MENU_ITEM_PLATE 11001
ObjectList::ObjectList(wxWindow* parent) :
wxDataViewCtrl(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxDV_MULTIPLE)
{
@ -85,17 +82,6 @@ ObjectList::ObjectList(wxWindow* parent) :
//BBS: add part plate related event
//Bind(EVT_PARTPLATE_LIST_PLATE_SELECT, &ObjectList::on_select_plate, this);
// BBS
wxMenuItem* org_by_plate = new wxMenuItem(&m_object_org_menu, ID_OBJECT_ORG_MENU_ITEM_PLATE, "Organize By Plate");
m_object_org_menu.Append(org_by_plate);
wxMenuItem* org_by_module = new wxMenuItem(&m_object_org_menu, ID_OBJECT_ORG_MENU_ITEM_MODULE, "Organize By Module");
m_object_org_menu.Append(org_by_module);
//Bind(wxEVT_DATAVIEW_COLUMN_HEADER_CLICK, &ObjectList::OnColumnHeadClicked, this);
Bind(wxEVT_MENU, [this](wxCommandEvent& evt) { this->OnOrganizeObjects(ortByPlate); }, ID_OBJECT_ORG_MENU_ITEM_PLATE);
Bind(wxEVT_MENU, [this](wxCommandEvent& evt) { this->OnOrganizeObjects(ortByModule); }, ID_OBJECT_ORG_MENU_ITEM_MODULE);
// describe control behavior
Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [this](wxDataViewEvent& event) {
// detect the current mouse position here, to pass it to list_manipulation() method
@ -266,7 +252,8 @@ ObjectList::ObjectList(wxWindow* parent) :
#else
update_name_column_width();
ensure_current_item_visible();
// BBS
this->CallAfter([this]() { ensure_current_item_visible(); });
#endif
e.Skip();
}));
@ -278,10 +265,13 @@ ObjectList::~ObjectList()
void ObjectList::set_min_height()
{
// BBS
#if 0
if (m_items_count == size_t(-1))
m_items_count = 7;
int list_min_height = lround(2.25 * (m_items_count + 1) * wxGetApp().em_unit()); // +1 is for height of control header
this->SetMinSize(wxSize(1, list_min_height));
#endif
}
void ObjectList::update_min_height()
@ -289,10 +279,14 @@ void ObjectList::update_min_height()
wxDataViewItemArray all_items;
m_objects_model->GetAllChildren(wxDataViewItem(nullptr), all_items);
size_t items_cnt = all_items.Count();
#if 0
if (items_cnt < 7)
items_cnt = 7;
else if (items_cnt >= 15)
items_cnt = 15;
#else
items_cnt = 8;
#endif
if (m_items_count == items_cnt)
return;
@ -304,14 +298,14 @@ void ObjectList::update_min_height()
void ObjectList::create_objects_ctrl()
{
// BBS
#if 0
/* Temporary workaround for the correct behavior of the Scrolled sidebar panel:
* 1. set a height of the list to some big value
* 2. change it to the normal(meaningful) min value after first whole Mainframe updating/layouting
*/
SetMinSize(wxSize(-1, 3000));
m_sizer = new wxBoxSizer(wxVERTICAL);
m_sizer->Add(this, 1, wxGROW);
#endif
m_objects_model = new ObjectDataViewModel;
AssociateModel(m_objects_model);
@ -356,7 +350,7 @@ void ObjectList::create_objects_ctrl()
bmp_choice_renderer->set_default_extruder_idx([this]() {
return m_objects_model->GetDefaultExtruderIdx(GetSelection());
});
AppendColumn(new wxDataViewColumn(_L(""), bmp_choice_renderer,
AppendColumn(new wxDataViewColumn(_L("Fila."), bmp_choice_renderer,
colFilament, m_columns_width[colFilament] * em, wxALIGN_CENTER_HORIZONTAL, 0));
// BBS
@ -642,6 +636,9 @@ void ObjectList::update_plate_values_for_items()
if (plate_idx == old_plate_idx)
continue;
// hotfix for wxDataViewCtrl selection not updated after wxDataViewModel::ItemDeleted()
Unselect(item);
bool is_old_parent_expanded = IsExpanded(old_parent);
bool is_expanded = IsExpanded(item);
m_objects_model->OnPlateChange(plate_idx, item);
@ -661,20 +658,6 @@ void ObjectList::update_name_for_items()
wxGetApp().plater()->update();
}
// BBS
void ObjectList::OnColumnHeadClicked(wxDataViewEvent& event)
{
int col = event.GetColumn();
if (col == 0) {
this->PopupMenu(&m_object_org_menu, 0, FromDIP(20));
}
}
void ObjectList::OnOrganizeObjects(OBJECT_ORGANIZE_TYPE type)
{
printf("%d\n", type);
}
void ObjectList::object_config_options_changed(const ObjectVolumeID& ov_id)
{
if (ov_id.object == nullptr)
@ -1977,6 +1960,30 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode
// update printable state on canvas
wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_object((size_t)obj_idx);
// apply the instance transform to all volumes and reset instance transform except the offset
{
const Geometry::Transformation &instance_transformation = model_object.instances[0]->get_transformation();
Vec3d original_instance_center = instance_transformation.get_offset();
const Transform3d &transformation_matrix = instance_transformation.get_matrix();
for (ModelVolume *volume : model_object.volumes) {
const Transform3d &volume_matrix = volume->get_matrix();
Transform3d new_matrix = transformation_matrix * volume_matrix;
volume->set_transformation(new_matrix);
}
model_object.instances[0]->set_transformation(Geometry::Transformation());
model_object.ensure_on_bed();
// keep new instance center the same as the original center
model_object.translate(-original_instance_center);
model_object.origin_translation += original_instance_center;
model_object.translate_instances(model_object.origin_translation);
model_object.origin_translation = Vec3d::Zero();
// update the cache data in selection to keep the data of ModelVolume and GLVolume are consistent
wxGetApp().plater()->update();
}
selection_changed();
//BBS: notify partplate the modify
@ -4734,9 +4741,7 @@ void ObjectList::OnEditingStarted(wxDataViewEvent &event)
auto item = event.GetItem();
if (!renderer->GetEditorCtrl()) {
renderer->StartEditing(item, GetItemRect(item, column));
if (col == colFilament) // TODO: not handle KILL_FOCUS from ComboBox
renderer->GetEditorCtrl()->PopEventHandler();
else if (col == colName) // TODO: for colName editing, disable shortcuts
if (col == colName) // TODO: for colName editing, disable shortcuts
SetAcceleratorTable(wxNullAcceleratorTable);
}
#endif //__WXMSW__

View file

@ -163,8 +163,6 @@ private:
} m_dragged_data;
wxBoxSizer *m_sizer {nullptr};
ObjectDataViewModel *m_objects_model{ nullptr };
ModelConfig *m_config {nullptr};
std::vector<ModelObject*> *m_objects{ nullptr };
@ -308,7 +306,6 @@ public:
bool can_merge_to_single_object() const;
wxPoint get_mouse_position_in_control() const { return wxGetMousePosition() - this->GetScreenPosition(); }
wxBoxSizer* get_sizer() {return m_sizer;}
int get_selected_obj_idx() const;
ModelConfig& get_item_config(const wxDataViewItem& item) const;
@ -453,11 +450,6 @@ private:
void OnEditingStarted(wxDataViewEvent &event);
void OnEditingDone(wxDataViewEvent &event);
// BBS
void OnColumnHeadClicked(wxDataViewEvent& event);
void OnOrganizeObjects(OBJECT_ORGANIZE_TYPE type);
wxMenu m_object_org_menu;
std::vector<int> m_columns_width;
};

View file

@ -236,6 +236,25 @@ void GridCellFilamentsEditor::BeginEdit(int row, int col, wxGrid* grid)
}
}
bool GridCellFilamentsEditor::EndEdit(int WXUNUSED(row),
int WXUNUSED(col),
const wxGrid* WXUNUSED(grid),
const wxString& WXUNUSED(oldval),
wxString *newval)
{
const wxString value = Combo()->GetValue();
if ( value == m_value )
return false;
m_value = value;
if ( newval )
*newval = value;
return true;
}
wxGridActivationResult GridCellFilamentsEditor::TryActivate(int row, int col, wxGrid* grid, const wxGridActivationSource& actSource)
{
ObjectGridTable *table = dynamic_cast<ObjectGridTable *>(grid->GetTable());
@ -2365,7 +2384,7 @@ ObjectTablePanel::ObjectTablePanel( wxWindow* parent, wxWindowID id, const wxPoi
SetSize(wxSize(-1, FromDIP(450)));
SetMinSize(wxSize(-1, FromDIP(450)));
SetMaxSize(wxSize(-1, FromDIP(450)));
//m_search_line = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
init_bitmap();
@ -2401,7 +2420,7 @@ ObjectTablePanel::ObjectTablePanel( wxWindow* parent, wxWindowID id, const wxPoi
m_page_top_sizer->Add(m_page_text, 0, wxEXPAND, 5);*/
//TODO, adjust later
/*
@ -2445,7 +2464,7 @@ ObjectTablePanel::ObjectTablePanel( wxWindow* parent, wxWindowID id, const wxPoi
int ObjectTablePanel::init_bitmap()
{
m_undo_bitmap = create_scaled_bitmap("undo", nullptr, 24);
m_undo_bitmap = create_scaled_bitmap("lock_normal", nullptr, 24);
m_color_bitmaps = get_extruder_color_icons();
return 0;

View file

@ -40,7 +40,7 @@ public:
const wxRect& rect,
int row, int col,
bool isSelected) wxOVERRIDE;
virtual wxSize GetBestSize(wxGrid& WXUNUSED(grid),
wxGridCellAttr& attr,
wxDC& dc,
@ -71,6 +71,8 @@ public:
virtual wxGridCellEditor *Clone() const wxOVERRIDE;
virtual void BeginEdit(int row, int col, wxGrid* grid) wxOVERRIDE;
virtual bool EndEdit(int row, int col, const wxGrid* grid,
const wxString& oldval, wxString *newval) wxOVERRIDE;
virtual wxGridActivationResult TryActivate(int row, int col, wxGrid* grid, const wxGridActivationSource& actSource) wxOVERRIDE;
virtual void DoActivate(int row, int col, wxGrid* grid) wxOVERRIDE;
@ -151,7 +153,7 @@ public:
//ObjectGrid for the param setting table
class ObjectGrid : public wxGrid
{
public:
public:
ObjectGrid(wxWindow *parent,
wxWindowID id,
const wxPoint& pos = wxDefaultPosition,
@ -377,7 +379,7 @@ public:
virtual int GetNumberRows() wxOVERRIDE;
virtual int GetNumberCols() wxOVERRIDE;
virtual bool IsEmptyCell( int row, int col ) wxOVERRIDE;
//virtual wxString GetColLabelValue( int col ) wxOVERRIDE;
@ -537,7 +539,7 @@ private:
wxFloatingPointValidator<float> m_float_validator;
wxBitmap m_undo_bitmap;
std::vector<wxBitmap*> m_color_bitmaps;
std::vector<wxBitmap*> m_color_bitmaps;
ScalableBitmap m_bmp_reset;
ScalableBitmap m_bmp_reset_disable;
private:

View file

@ -66,8 +66,8 @@ ObjectTableSettings::ObjectTableSettings(wxWindow* parent, ObjectGridTable* tabl
m_settings_list_sizer = new wxBoxSizer(wxVERTICAL);
m_og->sizer->Add(m_settings_list_sizer, 1, wxEXPAND | wxLEFT, 5);
m_bmp_reset = ScalableBitmap(parent, "undo");
m_bmp_reset_focus = ScalableBitmap(parent, "undo");
m_bmp_reset = ScalableBitmap(parent, "lock_normal");
m_bmp_reset_focus = ScalableBitmap(parent, "lock_normal");
//TODO, adjust later
m_bmp_reset_disable = ScalableBitmap(parent, "dot");
}

View file

@ -766,6 +766,7 @@ bool AssembleView::init(wxWindow* parent, Bed3D& bed, Model* model, DynamicPrint
// BBS: set volume_selection_mode to Volume
m_canvas->get_selection().set_volume_selection_mode(Selection::Volume);
m_canvas->get_selection().lock_volume_selection_mode();
wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);
main_sizer->Add(m_canvas_widget, 1, wxALL | wxEXPAND, 0);

View file

@ -158,6 +158,10 @@ void GLGizmoAdvancedCut::reset_cut_plane()
m_rotation.setZero();
//m_current_base_rotation.setZero();
m_rotate_cmds.clear();
m_buffered_movement = 0.0;
m_buffered_height = m_height;
m_buffered_rotation.setZero();
}
void GLGizmoAdvancedCut::reset_all()
@ -174,7 +178,7 @@ bool GLGizmoAdvancedCut::on_init()
if (!GLGizmoRotate3D::on_init())
return false;
m_shortcut_key = WXK_NONE;
m_shortcut_key = WXK_CONTROL_C;
return true;
}
@ -414,7 +418,7 @@ void GLGizmoAdvancedCut::on_render_input_window(float x, float y, float bottom_l
GizmoImguiSetNextWIndowPos(x, y, ImGuiCond_Always, 0.0f, 0.0f);
ImGuiWrapper::push_toolbar_style();
ImGuiWrapper::push_toolbar_style(m_parent.get_scale());
GizmoImguiBegin(on_get_name(), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar);

View file

@ -76,7 +76,7 @@ std::string GLGizmoFdmSupports::on_get_name() const
bool GLGizmoFdmSupports::on_init()
{
// BBS
m_shortcut_key = WXK_NONE;
m_shortcut_key = WXK_CONTROL_L;
m_desc["clipping_of_view"] = _L("Section view") + ": ";
m_desc["cursor_size"] = _L("Pen size") + ": ";
@ -88,9 +88,9 @@ 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("Gap fill");
m_desc["perform_filter"] = _L("Perform");
m_desc["fragment_area"] = _L("Fragment area");
m_desc["gap_fill"] = _L("Gap fill");
m_desc["perform"] = _L("Perform");
m_desc["gap_area"] = _L("Gap area");
m_desc["brush_size"] = _L("Set pen size");
m_desc["brush_size_caption"] = _L("Ctrl + Mouse wheel") + ": ";
m_desc["tool_type"] = _L("Tool type");
@ -175,6 +175,10 @@ void GLGizmoFdmSupports::on_set_state()
if (get_state() == On) {
m_support_threshold_angle = -1;
}
else if (get_state() == Off) {
ModelObject* mo = m_c->selection_info()->model_object();
if (mo) Slic3r::save_object_mesh(*mo);
}
}
static std::string into_u8(const wxString& str)
@ -206,16 +210,16 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
GizmoImguiSetNextWIndowPos(x, y, ImGuiCond_Always, 0.0f, 0.0f);
//BBS
ImGuiWrapper::push_toolbar_style();
ImGuiWrapper::push_toolbar_style(m_parent.get_scale());
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 cursor_slider_left = m_imgui->calc_text_size(m_desc.at("cursor_size")).x + m_imgui->scaled(1.5f);
const float fragment_filter_slider_left = m_imgui->calc_text_size(m_desc.at("fragment_filter")).x + m_imgui->scaled(1.5f);
const float gap_fill_slider_left = m_imgui->calc_text_size(m_desc.at("gap_fill")).x + m_imgui->scaled(1.5f);
const float highlight_slider_left = m_imgui->calc_text_size(m_desc.at("highlight_by_angle")).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.5f);
const float filter_btn_width = m_imgui->calc_text_size(m_desc.at("perform_filter")).x + m_imgui->scaled(1.5f);
const float filter_btn_width = m_imgui->calc_text_size(m_desc.at("perform")).x + m_imgui->scaled(1.5f);
const float buttons_width = remove_btn_width + filter_btn_width + m_imgui->scaled(1.5f);
const float empty_button_width = m_imgui->calc_button_size("").x;
@ -232,7 +236,7 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
total_text_max += caption_max + m_imgui->scaled(1.f);
caption_max += m_imgui->scaled(1.f);
const float sliders_left_width = std::max(std::max(cursor_slider_left, clipping_slider_left), std::max(highlight_slider_left, fragment_filter_slider_left));
const float sliders_left_width = std::max(std::max(cursor_slider_left, clipping_slider_left), std::max(highlight_slider_left, gap_fill_slider_left));
const float slider_icon_width = m_imgui->get_slider_icon_size().x;
float window_width = minimal_slider_width + sliders_left_width + slider_icon_width;
const float max_tooltip_width = ImGui::GetFontSize() * 20.0f;
@ -245,7 +249,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<wchar_t, 4> tool_icons = { ImGui::CircleButtonIcon, ImGui::SphereButtonIcon, ImGui::FillButtonIcon, ImGui::GapFillIcon };
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("##");
@ -322,19 +326,19 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
ImGui::SameLine(window_width - drag_pos_times * slider_icon_width);
ImGui::PushItemWidth(1.5 * slider_icon_width);
ImGui::BBLDragFloat("##smart_fill_angle_input", &m_smart_fill_angle, 0.05f, 0.0f, 0.0f, "%.2f");
} else if (m_current_tool == ImGui::FragmentFilterIcon) {
m_tool_type = ToolType::FRAGMENT_FILTER;
} else if (m_current_tool == ImGui::GapFillIcon) {
m_tool_type = ToolType::GAP_FILL;
m_cursor_type = TriangleSelector::CursorType::POINTER;
ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc["fragment_area"] + ":");
m_imgui->text(m_desc["gap_area"] + ":");
ImGui::SameLine(sliders_left_width);
ImGui::PushItemWidth(window_width - sliders_left_width - 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);
m_imgui->bbl_slider_float_style("##gap_area", &TriangleSelectorPatch::gap_area, TriangleSelectorPatch::GapAreaMin, TriangleSelectorPatch::GapAreaMax, format_str.data(), 1.0f, true);
ImGui::SameLine(window_width - drag_pos_times * 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::BBLDragFloat("##gap_area_input", &TriangleSelectorPatch::gap_area, 0.05f, 0.0f, 0.0f, "%.2f");
}
float position_before_text_y = ImGui::GetCursorPos().y;
@ -374,7 +378,7 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
ImGui::PushItemWidth(1.5 * slider_icon_width);
ImGui::BBLDragFloat("##angle_threshold_deg_input", &m_highlight_by_angle_threshold_deg, 0.05f, 0.0f, 0.0f, "%.2f");
if (m_current_tool != ImGui::FragmentFilterIcon) {
if (m_current_tool != ImGui::GapFillIcon) {
ImGui::Separator();
ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc.at("clipping_of_view"));
@ -395,12 +399,15 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(6.0f, 10.0f));
float get_cur_y = ImGui::GetContentRegionMax().y + ImGui::GetFrameHeight() + y;
show_tooltip_information(caption_max, x, get_cur_y);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.0f, 5.0f));
float f_scale =m_parent.get_gizmos_manager().get_layout_scale();
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.0f, 4.0f * f_scale));
ImGui::SameLine();
// Perform button is for gap fill
if (m_current_tool == ImGui::FragmentFilterIcon) {
if (m_imgui->button(m_desc.at("perform_filter"))) {
if (m_current_tool == ImGui::GapFillIcon) {
if (m_imgui->button(m_desc.at("perform"))) {
Plater::TakeSnapshot snapshot(wxGetApp().plater(), "Reset selection", UndoRedo::SnapshotType::GizmoAction);
for (int i = 0; i < m_triangle_selectors.size(); i++) {
@ -439,13 +446,13 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
void GLGizmoFdmSupports::tool_changed(wchar_t old_tool, wchar_t new_tool)
{
if ((old_tool == ImGui::FragmentFilterIcon && new_tool == ImGui::FragmentFilterIcon) ||
(old_tool != ImGui::FragmentFilterIcon && new_tool != ImGui::FragmentFilterIcon))
if ((old_tool == ImGui::GapFillIcon && new_tool == ImGui::GapFillIcon) ||
(old_tool != ImGui::GapFillIcon && new_tool != ImGui::GapFillIcon))
return;
for (auto& selector_ptr : m_triangle_selectors) {
TriangleSelectorPatch* tsp = dynamic_cast<TriangleSelectorPatch*>(selector_ptr.get());
tsp->set_filter_state(new_tool == ImGui::FragmentFilterIcon);
tsp->set_filter_state(new_tool == ImGui::GapFillIcon);
}
}
@ -549,8 +556,6 @@ void GLGizmoFdmSupports::update_model_object()
const ModelObjectPtrs& mos = wxGetApp().model().objects;
wxGetApp().obj_list()->update_info_items(std::find(mos.begin(), mos.end(), mo) - mos.begin());
// BBS: backup
Slic3r::save_object_mesh(*mo);
m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
}

View file

@ -25,7 +25,7 @@ GLGizmoFlatten::GLGizmoFlatten(GLCanvas3D& parent, const std::string& icon_filen
bool GLGizmoFlatten::on_init()
{
// BBS
m_shortcut_key = WXK_NONE;
m_shortcut_key = WXK_CONTROL_F;
return true;
}

View file

@ -94,7 +94,7 @@ void GLGizmoMmuSegmentation::init_extruders_data()
bool GLGizmoMmuSegmentation::on_init()
{
// BBS
m_shortcut_key = WXK_NONE;
m_shortcut_key = WXK_CONTROL_N;
m_desc["clipping_of_view"] = _L("Section view") + ": ";
m_desc["cursor_size"] = _L("Pen size") + ": ";
@ -108,10 +108,10 @@ bool GLGizmoMmuSegmentation::on_init()
m_desc["shortcut_key_caption"] = _L("Key 1~9") + ": ";
m_desc["shortcut_key"] = _L("Choose filament");
m_desc["edge_detection"] = _L("Edge detection");
m_desc["fragment_area"] = _L("Fragment area");
m_desc["perform_filter"] = _L("Perform");
m_desc["gap_area"] = _L("Gap area");
m_desc["perform"] = _L("Perform");
m_desc["remove_all"] = _L("Clear all");
m_desc["remove_all"] = _L("Erase all painting");
m_desc["circle"] = _L("Circle");
m_desc["sphere"] = _L("Sphere");
m_desc["pointer"] = _L("Triangles");
@ -332,7 +332,7 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
wchar_t old_tool = m_current_tool;
// BBS
ImGuiWrapper::push_toolbar_style();
ImGuiWrapper::push_toolbar_style(m_parent.get_scale());
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8.0f, 16.0f));
GizmoImguiBegin(get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar);
@ -341,11 +341,11 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
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.5f);
const float gap_area_slider_left = m_imgui->calc_text_size(m_desc.at("gap_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);
const float filter_btn_width = m_imgui->calc_text_size(m_desc.at("perform")).x + m_imgui->scaled(1.f);
const float buttons_width = remove_btn_width + filter_btn_width + m_imgui->scaled(1.f);
const float minimal_slider_width = m_imgui->scaled(4.f);
const float color_button_width = m_imgui->calc_text_size("").x + m_imgui->scaled(1.75f);
@ -362,7 +362,7 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
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,
std::max(cursor_slider_left, std::max(edge_detect_slider_left, std::max(gap_area_slider_left, std::max(height_range_slider_left,
clipping_slider_left)))));
const float slider_icon_width = m_imgui->get_slider_icon_size().x;
float window_width = minimal_slider_width + sliders_left_width + slider_icon_width;
@ -434,7 +434,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<wchar_t, 6> tool_icons = { ImGui::CircleButtonIcon,ImGui::SphereButtonIcon, ImGui::TriangleButtonIcon, ImGui::HeightRangeIcon, ImGui::FillButtonIcon, ImGui::GapFillIcon };
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("##");
@ -585,31 +585,33 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
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;
else if (m_current_tool == ImGui::GapFillIcon) {
m_tool_type = ToolType::GAP_FILL;
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);
m_imgui->text(m_desc["gap_area"] + ":");
ImGui::SameLine(gap_area_slider_left);
ImGui::PushItemWidth(window_width - gap_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);
m_imgui->bbl_slider_float_style("##gap_area", &TriangleSelectorPatch::gap_area, TriangleSelectorPatch::GapAreaMin, TriangleSelectorPatch::GapAreaMax, 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::BBLDragFloat("##gap_area_input", &TriangleSelectorPatch::gap_area, 0.05f, 0.0f, 0.0f, "%.2f");
}
ImGui::Separator();
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(6.0f, 10.0f));
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.0f, 5.0f));
float get_cur_y = ImGui::GetContentRegionMax().y + ImGui::GetFrameHeight() + y;
show_tooltip_information(caption_max, x, get_cur_y);
float f_scale =m_parent.get_gizmos_manager().get_layout_scale();
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.0f, 4.0f * f_scale));
ImGui::SameLine();
if (m_current_tool == ImGui::FragmentFilterIcon) {
if (m_imgui->button(m_desc.at("perform_filter"))) {
Plater::TakeSnapshot snapshot(wxGetApp().plater(), "Filter fragment", UndoRedo::SnapshotType::GizmoAction);
if (m_current_tool == ImGui::GapFillIcon) {
if (m_imgui->button(m_desc.at("perform"))) {
Plater::TakeSnapshot snapshot(wxGetApp().plater(), "Gap fill", UndoRedo::SnapshotType::GizmoAction);
for (int i = 0; i < m_triangle_selectors.size(); i++) {
TriangleSelectorPatch* ts_mm = dynamic_cast<TriangleSelectorPatch*>(m_triangle_selectors[i].get());
@ -661,11 +663,7 @@ void GLGizmoMmuSegmentation::update_model_object()
if (updated) {
const ModelObjectPtrs &mos = wxGetApp().model().objects;
wxGetApp().obj_list()->update_info_items(std::find(mos.begin(), mos.end(), mo) - mos.begin());
// BBS: backup
Slic3r::save_object_mesh(*mo);
m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
// BBS
m_parent.post_event(SimpleEvent(EVT_GLCANVAS_FORCE_UPDATE));
}
}
@ -730,13 +728,13 @@ void GLGizmoMmuSegmentation::update_from_model_object(bool first_update)
void GLGizmoMmuSegmentation::tool_changed(wchar_t old_tool, wchar_t new_tool)
{
if ((old_tool == ImGui::FragmentFilterIcon && new_tool == ImGui::FragmentFilterIcon) ||
(old_tool != ImGui::FragmentFilterIcon && new_tool != ImGui::FragmentFilterIcon))
if ((old_tool == ImGui::GapFillIcon && new_tool == ImGui::GapFillIcon) ||
(old_tool != ImGui::GapFillIcon && new_tool != ImGui::GapFillIcon))
return;
for (auto& selector_ptr : m_triangle_selectors) {
TriangleSelectorPatch* tsp = dynamic_cast<TriangleSelectorPatch*>(selector_ptr.get());
tsp->set_filter_state(new_tool == ImGui::FragmentFilterIcon);
tsp->set_filter_state(new_tool == ImGui::GapFillIcon);
}
}
@ -754,6 +752,16 @@ std::array<float, 4> GLGizmoMmuSegmentation::get_cursor_hover_color() const
return m_extruders_colors[0];
}
void GLGizmoMmuSegmentation::on_set_state()
{
GLGizmoPainterBase::on_set_state();
if (get_state() == Off) {
ModelObject* mo = m_c->selection_info()->model_object();
if (mo) Slic3r::save_object_mesh(*mo);
}
}
wxString GLGizmoMmuSegmentation::handle_snapshot_action_name(bool shift_down, GLGizmoPainterBase::Button button_down) const
{
wxString action_name;

View file

@ -87,6 +87,7 @@ public:
protected:
// BBS
std::array<float, 4> get_cursor_hover_color() const override;
void on_set_state() override;
EnforcerBlockerType get_left_button_state_type() const override { return EnforcerBlockerType(m_selected_extruder_idx + 1); }
EnforcerBlockerType get_right_button_state_type() const override { return EnforcerBlockerType::NONE; }

View file

@ -1,138 +0,0 @@
// Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro.
#include "GLGizmoModifier.hpp"
#include "slic3r/GUI/GUI_App.hpp"
#include "slic3r/GUI/GUI_ObjectList.hpp"
#include "slic3r/GUI/ImGuiWrapper.hpp"
#include "slic3r/GUI/GLCanvas3D.hpp"
#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp"
#include "libslic3r/Geometry/ConvexHull.hpp"
#include "libslic3r/Model.hpp"
#include <numeric>
#include <GL/glew.h>
namespace Slic3r {
namespace GUI {
const int SHAPE_IMAGE_SIZE = 34;
const std::vector<std::pair<std::string, std::string>> GLGizmoModifier::MODIFIER_SHAPES = {
{L("Cube"), "toolbar_modifier_cube.svg" },
{L("Cylinder"), "toolbar_modifier_cylinder.svg" },
{L("Sphere"), "toolbar_modifier_sphere.svg" },
{L("Cone"), "toolbar_modifier_cone.svg" },
{L("Timelapse Wipe Tower"), "toolbar_modifier_cube.svg"},
};
GLGizmoModifier::GLGizmoModifier(GLCanvas3D &parent, const std::string &icon_filename, unsigned int sprite_id)
: GLGizmoBase(parent, icon_filename, sprite_id)
{
}
bool GLGizmoModifier::on_init()
{
bool result = true;
texture_ids.clear();
for (auto item: MODIFIER_SHAPES) {
result = result && init_shape_texture(item.second);
}
// BBS
m_shortcut_key = WXK_NONE;
return result;
}
bool GLGizmoModifier::init_shape_texture(std::string image_name)
{
// init shapes image
bool compress = false;
GLint last_texture;
unsigned m_image_texture{0};
std::string path = resources_dir() + "/images/";
std::string file_name = path + image_name;
ThumbnailData data;
if (!get_data_from_svg(file_name, SHAPE_IMAGE_SIZE, data)) return false;
unsigned char *pixels = (unsigned char *) (&data.pixels[0]);
glsafe(::glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture));
glsafe(::glGenTextures(1, &m_image_texture));
glsafe(::glBindTexture(GL_TEXTURE_2D, m_image_texture));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
glsafe(::glPixelStorei(GL_UNPACK_ROW_LENGTH, 0));
if (compress && GLEW_EXT_texture_compression_s3tc)
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, data.width, data.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels));
else
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, data.width, data.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels));
// Store our identifier
ImTextureID texture_id = (ImTextureID) (intptr_t) m_image_texture;
texture_ids.push_back(texture_id);
// Restore state
glsafe(::glBindTexture(GL_TEXTURE_2D, last_texture));
return true;
}
void GLGizmoModifier::on_set_state()
{
}
void GLGizmoModifier::on_render_input_window(float x, float y, float bottom_limit)
{
// BBS: GUI refactor: move gizmo to the right
m_imgui->set_next_window_pos(x, y, ImGuiCond_Always, 0.f, 0.0f);
// BBS
ImGuiWrapper::push_toolbar_style();
std::string name = "Add Modifier##Modifier";
m_imgui->begin(_L(name), ImGuiWrapper::TOOLBAR_WINDOW_FLAGS);
for (int i = 0; i < MODIFIER_SHAPES.size(); i++) {
if (ImGui::ImageButton(texture_ids[i], ImVec2(34.0f, 34.0f))) {
wxGetApp().obj_list()->load_generic_subobject(MODIFIER_SHAPES[i].first, ModelVolumeType::PARAMETER_MODIFIER);
}
ImGui::SameLine();
}
m_imgui->end();
ImGuiWrapper::pop_toolbar_style();
}
CommonGizmosDataID GLGizmoModifier::on_get_requirements() const
{
return CommonGizmosDataID::SelectionInfo;
}
std::string GLGizmoModifier::on_get_name() const
{
return _u8L("Add Modifier");
}
bool GLGizmoModifier::on_is_activable() const
{
return m_parent.get_selection().is_single_full_instance();
}
void GLGizmoModifier::on_start_dragging()
{
;
}
void GLGizmoModifier::on_render()
{
;
}
void GLGizmoModifier::on_render_for_picking()
{
;
}
} // namespace GUI
} // namespace Slic3r

View file

@ -1,42 +0,0 @@
#ifndef slic3r_GLGizmoModifier_hpp_
#define slic3r_GLGizmoModifier_hpp_
#include "GLGizmoBase.hpp"
#include "slic3r/GUI/3DScene.hpp"
namespace Slic3r {
enum class ModelVolumeType : int;
namespace GUI {
class GLGizmoModifier : public GLGizmoBase
{
// This gizmo does not use grabbers. The m_hover_id relates to polygon managed by the class itself.
private:
std::vector<void*> texture_ids;
public:
static const std::vector<std::pair<std::string, std::string>> MODIFIER_SHAPES;
GLGizmoModifier(GLCanvas3D &parent, const std::string &icon_filename, unsigned int sprite_id);
protected:
virtual bool on_init() override;
virtual std::string on_get_name() const override;
virtual bool on_is_activable() const override;
virtual void on_start_dragging() override;
virtual void on_render() override;
virtual void on_render_for_picking() override;
virtual void on_set_state() override;
virtual void on_render_input_window(float x, float y, float bottom_limit);
virtual CommonGizmosDataID on_get_requirements() const override;
bool init_shape_texture(std::string image_name);
};
} // namespace GUI
} // namespace Slic3r
#endif // slic3r_GLGizmoFlatten_hpp_

View file

@ -56,7 +56,7 @@ bool GLGizmoMove3D::on_init()
m_grabbers.push_back(Grabber());
}
m_shortcut_key = WXK_NONE;
m_shortcut_key = WXK_CONTROL_M;
return true;
}

View file

@ -1036,10 +1036,10 @@ void TriangleSelectorGUI::update_render_data()
// BBS
bool TrianglePatch::is_fragment() const
{
return this->area < TriangleSelectorPatch::fragment_area;
return this->area < TriangleSelectorPatch::gap_area;
}
float TriangleSelectorPatch::fragment_area = TriangleSelectorPatch::FragmentAreaMin;
float TriangleSelectorPatch::gap_area = TriangleSelectorPatch::GapAreaMin;
void TriangleSelectorPatch::render(ImGuiWrapper* imgui)
{
@ -1198,7 +1198,7 @@ void TriangleSelectorPatch::update_triangles_per_patch()
visited[current_facet] = true;
}
patch.area = calc_fragment_area(patch, FragmentAreaMax);
patch.area = calc_fragment_area(patch, GapAreaMax);
patch.type = start_facet_state;
m_triangle_patches.emplace_back(std::move(patch));
}

View file

@ -78,7 +78,7 @@ public:
void request_update_render_data(bool paint_changed = false)
{
m_update_render_data = true;
m_paint_changed = paint_changed;
m_paint_changed |= paint_changed;
};
// BBS
@ -116,7 +116,7 @@ struct TrianglePatch {
std::vector<int> facet_indices;
EnforcerBlockerType type = EnforcerBlockerType::NONE;
std::set<EnforcerBlockerType> neighbor_types;
// if area is larger than FragmentAreaMax, stop accumulate left triangle areas to improve performance
// if area is larger than GapAreaMax, stop accumulate left triangle areas to improve performance
float area = 0.f;
bool is_fragment() const;
@ -140,11 +140,11 @@ public:
void set_ebt_colors(const std::vector<std::array<float, 4>> ebt_colors) { m_ebt_colors = ebt_colors; }
void set_filter_state(bool is_filter_state);
constexpr static float FragmentAreaMin = 0.f;
constexpr static float FragmentAreaMax = 5.f;
constexpr static float GapAreaMin = 0.f;
constexpr static float GapAreaMax = 5.f;
// BBS: fix me
static float fragment_area;
static float gap_area;
protected:
// Release the geometry data, release OpenGL VBOs.
@ -265,7 +265,7 @@ protected:
BUCKET_FILL,
SMART_FILL,
// BBS
FRAGMENT_FILTER,
GAP_FILL,
};
struct ProjectedMousePosition

View file

@ -466,7 +466,7 @@ bool GLGizmoRotate3D::on_init()
m_gizmos[i].set_highlight_color(AXES_COLOR[i]);
}
m_shortcut_key = WXK_NONE;
m_shortcut_key = WXK_CONTROL_R;
return true;
}

View file

@ -74,7 +74,7 @@ bool GLGizmoScale3D::on_init()
// BBS
m_grabbers[4].enabled = false;
m_shortcut_key = WXK_NONE;
m_shortcut_key = WXK_CONTROL_S;
return true;
}

View file

@ -28,7 +28,7 @@ bool GLGizmoSeam::on_init()
{
m_shortcut_key = WXK_CONTROL_P;
m_desc["clipping_of_view"] = _L("Clipping of view") + ": ";
m_desc["clipping_of_view"] = _L("Section view") + ": ";
m_desc["reset_direction"] = _L("Reset direction");
m_desc["cursor_size"] = _L("Brush size") + ": ";
m_desc["cursor_type"] = _L("Brush shape") + ": ";
@ -38,13 +38,18 @@ bool GLGizmoSeam::on_init()
m_desc["block"] = _L("Block seam");
m_desc["remove_caption"] = _L("Shift + Left mouse button") + ": ";
m_desc["remove"] = _L("Remove selection");
m_desc["remove_all"] = _L("Remove all selection");
m_desc["remove_all"] = _L("Erase all painting");
m_desc["circle"] = _L("Circle");
m_desc["sphere"] = _L("Sphere");
return true;
}
GLGizmoSeam::GLGizmoSeam(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
: GLGizmoPainterBase(parent, icon_filename, sprite_id), m_current_tool(ImGui::CircleButtonIcon)
{
}
std::string GLGizmoSeam::on_get_name() const
@ -114,6 +119,48 @@ void GLGizmoSeam::render_triangles(const Selection& selection) const
}
}
void GLGizmoSeam::show_tooltip_information(float caption_max, float x, float y)
{
ImTextureID normal_id = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP);
ImTextureID hover_id = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP_HOVER);
float font_size = ImGui::GetFontSize();
ImVec2 button_size = ImVec2(font_size * 1.8, font_size * 1.3);
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f);
ImGui::ImageButton3(normal_id, hover_id, button_size);
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip2(ImVec2(x, y));
auto draw_text_with_caption = [this, &caption_max](const wxString &caption, const wxString &text) {
m_imgui->text_colored(ImGuiWrapper::COL_ACTIVE, caption);
ImGui::SameLine(caption_max);
m_imgui->text_colored(ImGuiWrapper::COL_WINDOW_BG, text);
};
for (const auto &t : std::array<std::string, 3>{"enforce", "block", "remove"}) draw_text_with_caption(m_desc.at(t + "_caption"), m_desc.at(t));
ImGui::EndTooltip();
}
ImGui::PopStyleVar(1);
}
void GLGizmoSeam::tool_changed(wchar_t old_tool, wchar_t new_tool)
{
if ((old_tool == ImGui::GapFillIcon && new_tool == ImGui::GapFillIcon) ||
(old_tool != ImGui::GapFillIcon && new_tool != ImGui::GapFillIcon))
return;
for (auto& selector_ptr : m_triangle_selectors) {
TriangleSelectorPatch* tsp = dynamic_cast<TriangleSelectorPatch*>(selector_ptr.get());
tsp->set_filter_state(new_tool == ImGui::GapFillIcon);
}
}
static std::string into_u8(const wxString& str)
{
auto buffer_utf8 = str.utf8_str();
return std::string(buffer_utf8.data());
}
void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit)
{
if (! m_c->selection_info()->model_object())
@ -123,16 +170,17 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit)
y = std::min(y, bottom_limit - approx_height);
//BBS: GUI refactor: move gizmo to the right
#if BBS_TOOLBAR_ON_TOP
m_imgui->set_next_window_pos(x, y, ImGuiCond_Always, 0.0f, 0.0f);
GizmoImguiSetNextWIndowPos(x, y, ImGuiCond_Always, 0.0f, 0.0f);
#else
m_imgui->set_next_window_pos(x, y, ImGuiCond_Always, 1.0f, 0.0f);
GizmoImguiSetNextWIndowPos(x, y, ImGuiCond_Always, 1.0f, 0.0f);
#endif
//m_imgui->set_next_window_pos(x, y, ImGuiCond_Always);
wchar_t old_tool = m_current_tool;
//BBS
ImGuiWrapper::push_toolbar_style();
ImGuiWrapper::push_toolbar_style(m_parent.get_scale());
m_imgui->begin(get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse);
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 = std::max(m_imgui->calc_text_size(m_desc.at("clipping_of_view")).x,
@ -146,6 +194,7 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit)
const float button_width = m_imgui->calc_text_size(m_desc.at("remove_all")).x + m_imgui->scaled(1.f);
const float minimal_slider_width = m_imgui->scaled(4.f);
const float empty_button_width = m_imgui->calc_button_size("").x;
float caption_max = 0.f;
float total_text_max = 0.f;
@ -155,7 +204,7 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit)
}
total_text_max += caption_max + m_imgui->scaled(1.f);
caption_max += m_imgui->scaled(1.f);
float slider_width_times = 1.5;
const float sliders_left_width = std::max(cursor_size_slider_left, clipping_slider_left);
#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT
const float slider_icon_width = m_imgui->get_slider_icon_size().x;
@ -167,82 +216,89 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit)
window_width = std::max(window_width, button_width);
window_width = std::max(window_width, cursor_type_radio_left + cursor_type_radio_sphere + cursor_type_radio_circle);
auto draw_text_with_caption = [this, &caption_max](const wxString& caption, const wxString& text) {
//BBS set text colored to BLUE_LIGHT
m_imgui->text_colored(ImGuiWrapper::COL_BLUE_LIGHT, caption);
ImGui::SameLine(caption_max);
m_imgui->text(text);
};
for (const auto &t : std::array<std::string, 3>{"enforce", "block", "remove"})
draw_text_with_caption(m_desc.at(t + "_caption"), m_desc.at(t));
ImGui::Separator();
const float max_tooltip_width = ImGui::GetFontSize() * 20.0f;
ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc.at("cursor_type"));
std::array<wchar_t, 2> tool_icons = { ImGui::CircleButtonIcon, ImGui::SphereButtonIcon};
std::array<wxString, 2> tool_tips = { _L("Circle"), _L("Sphere")};
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);
if (i != 0) ImGui::SameLine((empty_button_width + m_imgui->scaled(1.75f)) * i + m_imgui->scaled(1.3f));
if (m_current_tool == tool_icons[i]) {
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.81f, 0.81f, 0.81f, 1.0f)); // r, g, b, a
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.81f, 0.81f, 0.81f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.81f, 0.81f, 0.81f, 1.0f));
}
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0);
bool btn_clicked = ImGui::Button(into_u8(btn_name).c_str());
ImGui::PopStyleVar(1);
if (m_current_tool == tool_icons[i])ImGui::PopStyleColor(3);
if (btn_clicked && m_current_tool != tool_icons[i]) {
m_current_tool = tool_icons[i];
for (auto& triangle_selector : m_triangle_selectors) {
triangle_selector->seed_fill_unselect_all_triangles();
triangle_selector->request_update_render_data();
}
}
if (ImGui::IsItemHovered()) {
m_imgui->tooltip(tool_tips[i], max_tooltip_width);
}
}
if (m_current_tool != old_tool)
this->tool_changed(old_tool, m_current_tool);
ImGui::Dummy(ImVec2(0.0f, ImGui::GetFontSize() * 0.1));
if (m_current_tool == ImGui::CircleButtonIcon) {
m_cursor_type = TriangleSelector::CursorType::CIRCLE;
m_tool_type = ToolType::BRUSH;
} else if (m_current_tool == ImGui::SphereButtonIcon) {
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);
#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT
ImGui::PushItemWidth(window_width - sliders_left_width - slider_icon_width);
m_imgui->slider_float("##cursor_radius", &m_cursor_radius, CursorRadiusMin, CursorRadiusMax, "%.2f", 1.0f, true, _L("Alt + Mouse wheel"));
#else
ImGui::PushItemWidth(window_width - sliders_left_width);
m_imgui->slider_float("##cursor_radius", &m_cursor_radius, CursorRadiusMin, CursorRadiusMax, "%.2f");
if (ImGui::IsItemHovered())
m_imgui->tooltip(_L("Alt + Mouse wheel"), max_tooltip_width);
#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT
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);
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");
ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc.at("cursor_type"));
float cursor_type_offset = cursor_type_radio_left + (window_width - cursor_type_radio_left - cursor_type_radio_sphere - cursor_type_radio_circle + m_imgui->scaled(0.5f)) / 2.f;
ImGui::SameLine(cursor_type_offset);
ImGui::PushItemWidth(cursor_type_radio_sphere);
if (m_imgui->radio_button(m_desc["sphere"], m_cursor_type == TriangleSelector::CursorType::SPHERE))
m_cursor_type = TriangleSelector::CursorType::SPHERE;
if (ImGui::IsItemHovered())
m_imgui->tooltip(_L("Paints all facets inside, regardless of their orientation."), max_tooltip_width);
ImGui::SameLine(cursor_type_offset + cursor_type_radio_sphere);
ImGui::PushItemWidth(cursor_type_radio_circle);
if (m_imgui->radio_button(m_desc["circle"], m_cursor_type == TriangleSelector::CursorType::CIRCLE))
m_cursor_type = TriangleSelector::CursorType::CIRCLE;
if (ImGui::IsItemHovered())
m_imgui->tooltip(_L("Ignores facets facing away from the camera."), max_tooltip_width);
ImGui::Separator();
if (m_c->object_clipper()->get_position() == 0.f) {
ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc.at("clipping_of_view"));
}
else {
if (m_imgui->button(m_desc.at("reset_direction"))) {
wxGetApp().CallAfter([this](){
m_c->object_clipper()->set_position(-1., false);
});
}
}
m_imgui->text(m_desc.at("clipping_of_view"));
auto clp_dist = float(m_c->object_clipper()->get_position());
ImGui::SameLine(sliders_left_width);
#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT
ImGui::PushItemWidth(window_width - sliders_left_width - slider_icon_width);
if (m_imgui->slider_float("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f", 1.0f, true, _L("Ctrl + Mouse wheel")))
m_c->object_clipper()->set_position(clp_dist, true);
#else
ImGui::PushItemWidth(window_width - sliders_left_width);
if (m_imgui->slider_float("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f"))
m_c->object_clipper()->set_position(clp_dist, true);
if (ImGui::IsItemHovered())
m_imgui->tooltip(_L("Ctrl + Mouse wheel"), max_tooltip_width);
#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT
ImGui::PushItemWidth(window_width - sliders_left_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); }
ImGui::Separator();
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(6.0f, 10.0f));
float get_cur_y = ImGui::GetContentRegionMax().y + ImGui::GetFrameHeight() + y;
show_tooltip_information(caption_max, x, get_cur_y);
float f_scale =m_parent.get_gizmos_manager().get_layout_scale();
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.0f, 4.0f * f_scale));
ImGui::SameLine();
if (m_imgui->button(m_desc.at("remove_all"))) {
Plater::TakeSnapshot snapshot(wxGetApp().plater(), "Reset selection", UndoRedo::SnapshotType::GizmoAction);
ModelObject *mo = m_c->selection_info()->model_object();
@ -251,19 +307,29 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit)
if (mv->is_model_part()) {
++idx;
m_triangle_selectors[idx]->reset();
m_triangle_selectors[idx]->request_update_render_data();
m_triangle_selectors[idx]->request_update_render_data(true);
}
update_model_object();
m_parent.set_as_dirty();
}
m_imgui->end();
ImGui::PopStyleVar(2);
GizmoImguiEnd();
//BBS
ImGuiWrapper::pop_toolbar_style();
}
// BBS
void GLGizmoSeam::on_set_state()
{
GLGizmoPainterBase::on_set_state();
if (get_state() == Off) {
ModelObject* mo = m_c->selection_info()->model_object();
if (mo) Slic3r::save_object_mesh(*mo);
}
}
//BBS: remove const
void GLGizmoSeam::update_model_object()
@ -281,9 +347,6 @@ void GLGizmoSeam::update_model_object()
if (updated) {
const ModelObjectPtrs& mos = wxGetApp().model().objects;
wxGetApp().obj_list()->update_info_items(std::find(mos.begin(), mos.end(), mo) - mos.begin());
// BBS: backup
Slic3r::save_object_mesh(*mo);
m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
}
}

View file

@ -8,17 +8,24 @@ namespace Slic3r::GUI {
class GLGizmoSeam : public GLGizmoPainterBase
{
public:
GLGizmoSeam(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
: GLGizmoPainterBase(parent, icon_filename, sprite_id) {}
GLGizmoSeam(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
void render_painter_gizmo() const override;
protected:
// BBS
void on_set_state() override;
wchar_t m_current_tool = 0;
void on_render_input_window(float x, float y, float bottom_limit) override;
std::string on_get_name() const override;
PainterGizmoType get_painter_type() const override;
void render_triangles(const Selection& selection) const override;
void render_triangles(const Selection &selection) const override;
void show_tooltip_information(float caption_max, float x, float y);
void tool_changed(wchar_t old_tool, wchar_t new_tool);
wxString handle_snapshot_action_name(bool shift_down, Button button_down) const override;

View file

@ -22,7 +22,6 @@
#include "slic3r/GUI/Gizmos/GLGizmoSeam.hpp"
#include "slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp"
#include "slic3r/GUI/Gizmos/GLGizmoSimplify.hpp"
#include "slic3r/GUI/Gizmos/GLGizmoModifier.hpp"
#include "libslic3r/format.hpp"
#include "libslic3r/Model.hpp"
@ -146,10 +145,9 @@ bool GLGizmosManager::init()
m_gizmos.emplace_back(new GLGizmoFlatten(m_parent, "toolbar_flatten.svg", EType::Flatten));
m_gizmos.emplace_back(new GLGizmoAdvancedCut(m_parent, "toolbar_cut.svg", EType::Cut));
m_gizmos.emplace_back(new GLGizmoFdmSupports(m_parent, "toolbar_support.svg", EType::FdmSupports));
m_gizmos.emplace_back(new GLGizmoSeam(m_parent, "toolbar_seam.svg", EType::Seam));
m_gizmos.emplace_back(new GLGizmoMmuSegmentation(m_parent, "mmu_segmentation.svg", EType::MmuSegmentation));
m_gizmos.emplace_back(new GLGizmoSimplify(m_parent, "reduce_triangles.svg", EType::Simplify));
//m_gizmos.emplace_back(new GLGizmoModifier(m_parent, "toolbar_modifier.svg", EType::Modifier));
//m_gizmos.emplace_back(new GLGizmoSeam(m_parent, "toolbar_seam.svg", EType::Seam));
//m_gizmos.emplace_back(new GLGizmoSlaSupports(m_parent, "sla_supports.svg", sprite_id++));
//m_gizmos.emplace_back(new GLGizmoFaceDetector(m_parent, "face recognition.svg", sprite_id++));
//m_gizmos.emplace_back(new GLGizmoHollow(m_parent, "hollow.svg", sprite_id++));
@ -199,6 +197,11 @@ bool GLGizmosManager::init_icon_textures()
return true;
}
float GLGizmosManager::get_layout_scale()
{
return m_layout.scale;
}
bool GLGizmosManager::init_arrow(const BackgroundTexture::Metadata& arrow_texture)
{
if (m_arrow_texture.texture.get_id() != 0)
@ -515,12 +518,8 @@ void GLGizmosManager::set_painter_gizmo_data()
return;
dynamic_cast<GLGizmoFdmSupports*>(m_gizmos[FdmSupports].get())->set_painter_gizmo_data(m_parent.get_selection());
dynamic_cast<GLGizmoSeam*>(m_gizmos[Seam].get())->set_painter_gizmo_data(m_parent.get_selection());
dynamic_cast<GLGizmoMmuSegmentation*>(m_gizmos[MmuSegmentation].get())->set_painter_gizmo_data(m_parent.get_selection());
if (Seam < m_gizmos.size()) {
GLGizmoSeam* gizmo_seam = dynamic_cast<GLGizmoSeam*>(m_gizmos[Seam].get());
if (gizmo_seam != nullptr)
gizmo_seam->set_painter_gizmo_data(m_parent.get_selection());
}
}
// Returns true if the gizmo used the event to do something, false otherwise.

View file

@ -71,10 +71,9 @@ public:
Flatten,
Cut,
FdmSupports,
Seam,
MmuSegmentation,
Simplify,
Modifier,
Seam,
SlaSupports,
// BBS
//FaceRecognition,
@ -159,6 +158,8 @@ public:
bool init_icon_textures();
float get_layout_scale();
bool init_arrow(const BackgroundTexture::Metadata& arrow_texture);
template<class Archive>

View file

@ -98,7 +98,7 @@ void GizmoObjectManipulation::update_settings_value(const Selection& selection)
if (m_world_coordinates) {
m_new_rotate_label_string = L("Rotate");
m_new_rotation = Vec3d::Zero();
m_new_rotation = volume->get_instance_rotation() * (180. / M_PI);
m_new_size = selection.get_scaled_instance_bounding_box().size();
m_new_scale = m_new_size.cwiseProduct(selection.get_unscaled_instance_bounding_box().size().cwiseInverse()) * 100.;
}
@ -550,7 +550,7 @@ void GizmoObjectManipulation::do_render_move_window(ImGuiWrapper *imgui_wrapper,
#endif
// BBS
ImGuiWrapper::push_toolbar_style();
ImGuiWrapper::push_toolbar_style(m_glcanvas.get_scale());
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0, 6.0));
std::string name = this->m_new_title_string + "##" + window_name;
@ -664,7 +664,7 @@ void GizmoObjectManipulation::do_render_rotate_window(ImGuiWrapper *imgui_wrappe
#endif
// BBS
ImGuiWrapper::push_toolbar_style();
ImGuiWrapper::push_toolbar_style(m_glcanvas.get_scale());
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0, 6.0));
std::string name = this->m_new_title_string + "##" + window_name;
@ -783,7 +783,7 @@ void GizmoObjectManipulation::do_render_scale_input_window(ImGuiWrapper* imgui_w
#endif
//BBS
ImGuiWrapper::push_toolbar_style();
ImGuiWrapper::push_toolbar_style(m_glcanvas.get_scale());
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0, 6.0));
std::string name = this->m_new_title_string + "##" + window_name;

View file

@ -1238,7 +1238,7 @@ bool IMSlider::render(int canvas_width, int canvas_height)
void IMSlider::render_menu()
{
ImGuiWrapper::push_menu_style();
ImGuiWrapper::push_menu_style(m_scale);
std::vector<std::string> colors = wxGetApp().plater()->get_extruder_colors_from_plater_config();
int extruder_num = colors.size();
@ -1246,24 +1246,25 @@ void IMSlider::render_menu()
ImGui::OpenPopup("slider_menu_popup");
}
ImGui::PushStyleVar(ImGuiStyleVar_::ImGuiStyleVar_ChildRounding, 4.0f * m_scale);
if (ImGui::BeginPopup("slider_menu_popup")) {
bool selected = false;
ImGui::MenuItem(_u8L("Add Pause").c_str(), "", &selected);
if (selected) { add_code_as_tick(PausePrint); }
if(menu_item_with_icon(_u8L("Add Pause").c_str(), "")) { add_code_as_tick(PausePrint); }
//BBS render this menu item only when extruder_num > 1
if (extruder_num > 1) {
if (ImGui::BeginMenu(_u8L("Change Filament").c_str())) {
if (begin_menu(_u8L("Change Filament").c_str())) {
for (int i = 0; i < extruder_num; i++) {
std::array<float, 4> rgba = decode_color_to_float_array(colors[i]);
ImU32 icon_clr = IM_COL32(rgba[0] * 255.0f, rgba[1] * 255.0f, rgba[2] * 255.0f, rgba[3] * 255.0f);
if (menu_item_with_icon((_u8L("Filament ") + std::to_string(i + 1)).c_str(), "", icon_clr, false, true)) add_code_as_tick(ToolChange, i + 1);
if (menu_item_with_icon((_u8L("Filament ") + std::to_string(i + 1)).c_str(), "", ImVec2(14, 14) * m_scale, icon_clr)) add_code_as_tick(ToolChange, i + 1);
}
ImGui::EndMenu();
end_menu();
}
}
ImGui::EndPopup();
}
ImGui::PopStyleVar(1);
ImGuiWrapper::pop_menu_style();
}

View file

@ -58,10 +58,10 @@ static const std::map<const wchar_t, std::string> font_icons = {
{ImGui::SliderFloatEditBtnIcon, "edit_button" },
#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT
{ImGui::CircleButtonIcon , "circle_paint" },
{ImGui::TriangleButtonIcon , "Triangle_paint" },
{ImGui::TriangleButtonIcon , "triangle_paint" },
{ImGui::FillButtonIcon , "fill_paint" },
{ImGui::HeightRangeIcon , "height_range" },
{ImGui::FragmentFilterIcon , "fragment_filter" },
{ImGui::GapFillIcon , "gap_fill" },
{ImGui::FoldButtonIcon , "im_fold" },
{ImGui::UnfoldButtonIcon , "im_unfold" },
{ImGui::SphereButtonIcon , "toolbar_modifier_sphere" },
@ -196,7 +196,7 @@ bool slider_behavior(ImGuiID id, const ImRect& region, const ImS32 v_min, const
mouse_wheel_responsive_region = ImRect(region.Min - ImVec2(0, handle_sz.y), region.Max + ImVec2(0, handle_sz.y));
if (ImGui::ItemHoverable(mouse_wheel_responsive_region, id)) {
#ifdef __APPLE__
if (io.KeyShift)
if (io.KeyShift)
v_new = ImClamp(*out_value - 5 * (ImS32) (context.IO.MouseWheel), v_min, v_max);
else if (io.KeyCtrl)
v_new = ImClamp(*out_value + 5 * (ImS32) (context.IO.MouseWheel), v_min, v_max);
@ -236,7 +236,7 @@ bool slider_behavior(ImGuiID id, const ImRect& region, const ImS32 v_min, const
{
v_new = fixed_value;
}
// apply result, output value
if (*out_value != v_new)
{
@ -291,56 +291,6 @@ bool button_with_pos(ImTextureID user_texture_id, const ImVec2 &size, const ImVe
return pressed;
}
bool menu_item_with_icon(const char* label, const char* shortcut, ImU32 icon_color, bool selected, bool enabled/* = true*/) {
ImGuiWindow* window = ImGui::GetCurrentWindow();
if (window->SkipItems)
return false;
ImGuiContext& g = *GImGui;
ImGuiStyle& style = g.Style;
ImVec2 pos = window->DC.CursorPos;
ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true);
// We've been using the equivalent of ImGuiSelectableFlags_SetNavIdOnHover on all Selectable() since early Nav system days (commit 43ee5d73),
// but I am unsure whether this should be kept at all. For now moved it to be an opt-in feature used by menus only.
ImGuiSelectableFlags flags = ImGuiSelectableFlags_SelectOnRelease | ImGuiSelectableFlags_SetNavIdOnHover | (enabled ? 0 : ImGuiSelectableFlags_Disabled);
bool pressed;
if (window->DC.LayoutType == ImGuiLayoutType_Horizontal)
{
// Mimic the exact layout spacing of BeginMenu() to allow MenuItem() inside a menu bar, which is a little misleading but may be useful
// Note that in this situation: we don't render the shortcut, we render a highlight instead of the selected tick mark.
float w = label_size.x;
window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * 0.5f);
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x * 2.0f, style.ItemSpacing.y));
pressed = ImGui::Selectable(label, selected, flags, ImVec2(w, 0.0f));
ImGui::PopStyleVar();
window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar().
}
else
{
// Menu item inside a vertical menu
// (In a typical menu window where all items are BeginMenu() or MenuItem() calls, extra_w will always be 0.0f.
// Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system.
float shortcut_w = shortcut ? ImGui::CalcTextSize(shortcut, NULL).x : 0.0f;
float min_w = window->DC.MenuColumns.DeclColumns(label_size.x, shortcut_w, IM_FLOOR(g.FontSize * 1.20f)); // Feedback for next frame
float extra_w = std::max(0.0f, ImGui::GetContentRegionAvail().x - min_w);
pressed = ImGui::Selectable(label, false, flags | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, 0.0f));
ImVec2 pos_min = pos + ImVec2(window->DC.MenuColumns.Pos[2] + extra_w + g.FontSize * 0.40f, g.FontSize * 0.134f * 0.5f);
ImGui::RenderFrame(pos_min, pos_min + ImVec2(14, 14), icon_color);
if (shortcut_w > 0.0f)
{
ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]);
ImGui::RenderText(pos + ImVec2(window->DC.MenuColumns.Pos[1] + extra_w, 0.0f), shortcut, NULL, false);
ImGui::PopStyleColor();
}
if (selected)
ImGui::RenderCheckMark(window->DrawList, pos + ImVec2(window->DC.MenuColumns.Pos[2] + extra_w + g.FontSize * 0.40f, g.FontSize * 0.134f * 0.5f), ImGui::GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled), g.FontSize * 0.866f);
}
IMGUI_TEST_ENGINE_ITEM_INFO(window->DC.LastItemId, label, window->DC.LastItemStatusFlags | ImGuiItemStatusFlags_Checkable | (selected ? ImGuiItemStatusFlags_Checked : 0));
return pressed;
}
ImGuiWrapper::ImGuiWrapper()
{
ImGui::CreateContext();
@ -606,7 +556,7 @@ bool ImGuiWrapper::bbl_slider_float_style(const std::string &label, float *v, fl
bool ImGuiWrapper::bbl_slider_float(const std::string& label, float* v, float v_min, float v_max, const char* format, float power, bool clamp, const wxString& tooltip)
{
const float max_tooltip_width = ImGui::GetFontSize() * 20.0f;
// let the label string start with "##" to hide the automatic label from ImGui::SliderFloat()
@ -969,7 +919,7 @@ bool ImGuiWrapper::combo(const wxString& label, const std::vector<std::string>&
return res;
}
// Scroll up for one item
// Scroll up for one item
static void scroll_up()
{
ImGuiContext& g = *GImGui;
@ -981,7 +931,7 @@ static void scroll_up()
ImGui::SetScrollY(win_top - item_size_y);
}
// Scroll down for one item
// Scroll down for one item
static void scroll_down()
{
ImGuiContext& g = *GImGui;
@ -1170,14 +1120,17 @@ static bool selectable(const char* label, bool selected, ImGuiSelectableFlags fl
// mark a label with a ColorMarkerHovered, if item is hovered
char marked_label[512]; //255 symbols is not enough for translated string (e.t. to Russian)
if (hovered)
if (hovered || selected) {
sprintf(marked_label, "%c%s", ImGui::ColorMarkerHovered, label);
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
}
else
strcpy(marked_label, label);
if (flags & ImGuiSelectableFlags_Disabled) ImGui::PushStyleColor(ImGuiCol_Text, style.Colors[ImGuiCol_TextDisabled]);
ImGui::RenderTextClipped(text_min, text_max, marked_label, NULL, &label_size, style.SelectableTextAlign, &bb);
if (flags & ImGuiSelectableFlags_Disabled) ImGui::PopStyleColor();
if (hovered || selected) ImGui::PopStyleColor();
// Automatically close popups
if (pressed && (window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiSelectableFlags_DontClosePopups) && !(g.CurrentItemFlags & ImGuiItemFlags_SelectableDontClosePopup))
@ -1187,6 +1140,228 @@ static bool selectable(const char* label, bool selected, ImGuiSelectableFlags fl
return pressed;
}
bool begin_menu(const char *label, bool enabled)
{
ImGuiWindow *window = ImGui::GetCurrentWindow();
if (window->SkipItems) return false;
ImGuiContext & g = *GImGui;
const ImGuiStyle &style = g.Style;
const ImGuiID id = window->GetID(label);
bool menu_is_open = ImGui::IsPopupOpen(id, ImGuiPopupFlags_None);
// Sub-menus are ChildWindow so that mouse can be hovering across them (otherwise top-most popup menu would steal focus and not allow hovering on parent menu)
ImGuiWindowFlags flags = ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar |
ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoNavFocus;
if (window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu)) flags |= ImGuiWindowFlags_ChildWindow;
// If a menu with same the ID was already submitted, we will append to it, matching the behavior of Begin().
// We are relying on a O(N) search - so O(N log N) over the frame - which seems like the most efficient for the expected small amount of BeginMenu() calls per frame.
// If somehow this is ever becoming a problem we can switch to use e.g. ImGuiStorage mapping key to last frame used.
if (g.MenusIdSubmittedThisFrame.contains(id)) {
if (menu_is_open)
menu_is_open = ImGui::BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
else
g.NextWindowData.ClearFlags(); // we behave like Begin() and need to consume those values
return menu_is_open;
}
// Tag menu as used. Next time BeginMenu() with same ID is called it will append to existing menu
g.MenusIdSubmittedThisFrame.push_back(id);
ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true);
bool pressed;
bool menuset_is_open = !(window->Flags & ImGuiWindowFlags_Popup) &&
(g.OpenPopupStack.Size > g.BeginPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].OpenParentId == window->IDStack.back());
ImGuiWindow *backed_nav_window = g.NavWindow;
if (menuset_is_open) g.NavWindow = window; // Odd hack to allow hovering across menus of a same menu-set (otherwise we wouldn't be able to hover parent)
// The reference position stored in popup_pos will be used by Begin() to find a suitable position for the child menu,
// However the final position is going to be different! It is chosen by FindBestWindowPosForPopup().
// e.g. Menus tend to overlap each other horizontally to amplify relative Z-ordering.
ImVec2 popup_pos, pos = window->DC.CursorPos;
if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) {
// Menu inside an horizontal menu bar
// Selectable extend their highlight by half ItemSpacing in each direction.
// For ChildMenu, the popup position will be overwritten by the call to FindBestWindowPosForPopup() in Begin()
popup_pos = ImVec2(pos.x - 1.0f - IM_FLOOR(style.ItemSpacing.x * 0.5f), pos.y - style.FramePadding.y + window->MenuBarHeight());
window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * 0.5f);
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x * 2.0f, style.ItemSpacing.y));
float w = label_size.x;
pressed = selectable(label, menu_is_open,
ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_DontClosePopups |
(!enabled ? ImGuiSelectableFlags_Disabled : 0),
ImVec2(w, 0.0f));
ImGui::PopStyleVar();
window->DC.CursorPos.x += IM_FLOOR(
style.ItemSpacing.x *
(-1.0f +
0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar().
} else {
// Menu inside a menu
// (In a typical menu window where all items are BeginMenu() or MenuItem() calls, extra_w will always be 0.0f.
// Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system.
popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y);
float min_w = window->DC.MenuColumns.DeclColumns(label_size.x, 0.0f, IM_FLOOR(g.FontSize * 1.20f)); // Feedback to next frame
float extra_w = ImMax(0.0f, ImGui::GetContentRegionAvail().x - min_w);
pressed = selectable(label, menu_is_open,
ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_DontClosePopups |
ImGuiSelectableFlags_SpanAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0),
ImVec2(min_w, 0.0f));
ImU32 text_col = ImGui::GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled);
ImGui::RenderArrow(window->DrawList, pos + ImVec2(window->DC.MenuColumns.Pos[2] + extra_w + g.FontSize * 0.30f, 0.0f), text_col, ImGuiDir_Right);
}
const bool hovered = enabled && ImGui::ItemHoverable(window->DC.LastItemRect, id);
if (menuset_is_open) g.NavWindow = backed_nav_window;
bool want_open = false;
bool want_close = false;
if (window->DC.LayoutType == ImGuiLayoutType_Vertical) // (window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu))
{
// Close menu when not hovering it anymore unless we are moving roughly in the direction of the menu
// Implement http://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown to avoid using timers, so menus feels more reactive.
bool moving_toward_other_child_menu = false;
ImGuiWindow *child_menu_window = (g.BeginPopupStack.Size < g.OpenPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].SourceWindow == window) ?
g.OpenPopupStack[g.BeginPopupStack.Size].Window :
NULL;
if (g.HoveredWindow == window && child_menu_window != NULL && !(window->Flags & ImGuiWindowFlags_MenuBar)) {
// FIXME-DPI: Values should be derived from a master "scale" factor.
ImRect next_window_rect = child_menu_window->Rect();
ImVec2 ta = g.IO.MousePos - g.IO.MouseDelta;
ImVec2 tb = (window->Pos.x < child_menu_window->Pos.x) ? next_window_rect.GetTL() : next_window_rect.GetTR();
ImVec2 tc = (window->Pos.x < child_menu_window->Pos.x) ? next_window_rect.GetBL() : next_window_rect.GetBR();
float extra = ImClamp(ImFabs(ta.x - tb.x) * 0.30f, 5.0f, 30.0f); // add a bit of extra slack.
ta.x += (window->Pos.x < child_menu_window->Pos.x) ? -0.5f : +0.5f; // to avoid numerical issues
tb.y = ta.y +
ImMax((tb.y - extra) - ta.y, -100.0f); // triangle is maximum 200 high to limit the slope and the bias toward large sub-menus // FIXME: Multiply by fb_scale?
tc.y = ta.y + ImMin((tc.y + extra) - ta.y, +100.0f);
moving_toward_other_child_menu = ImTriangleContainsPoint(ta, tb, tc, g.IO.MousePos);
// GetForegroundDrawList()->AddTriangleFilled(ta, tb, tc, moving_within_opened_triangle ? IM_COL32(0,128,0,128) : IM_COL32(128,0,0,128)); // [DEBUG]
}
if (menu_is_open && !hovered && g.HoveredWindow == window && g.HoveredIdPreviousFrame != 0 && g.HoveredIdPreviousFrame != id && !moving_toward_other_child_menu)
want_close = true;
if (!menu_is_open && hovered && pressed) // Click to open
want_open = true;
else if (!menu_is_open && hovered && !moving_toward_other_child_menu) // Hover to open
want_open = true;
if (g.NavActivateId == id) {
want_close = menu_is_open;
want_open = !menu_is_open;
}
if (g.NavId == id && g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Right) // Nav-Right to open
{
want_open = true;
ImGui::NavMoveRequestCancel();
}
} else {
// Menu bar
if (menu_is_open && pressed && menuset_is_open) // Click an open menu again to close it
{
want_close = true;
want_open = menu_is_open = false;
} else if (pressed || (hovered && menuset_is_open && !menu_is_open)) // First click to open, then hover to open others
{
want_open = true;
} else if (g.NavId == id && g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Down) // Nav-Down to open
{
want_open = true;
ImGui::NavMoveRequestCancel();
}
}
if (!enabled) // explicitly close if an open menu becomes disabled, facilitate users code a lot in pattern such as 'if (BeginMenu("options", has_object)) { ..use object.. }'
want_close = true;
if (want_close && ImGui::IsPopupOpen(id, ImGuiPopupFlags_None)) ImGui::ClosePopupToLevel(g.BeginPopupStack.Size, true);
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags | ImGuiItemStatusFlags_Openable | (menu_is_open ? ImGuiItemStatusFlags_Opened : 0));
if (!menu_is_open && want_open && g.OpenPopupStack.Size > g.BeginPopupStack.Size) {
// Don't recycle same menu level in the same frame, first close the other menu and yield for a frame.
ImGui::OpenPopup(label);
return false;
}
menu_is_open |= want_open;
if (want_open) ImGui::OpenPopup(label);
if (menu_is_open) {
ImGui::SetNextWindowPos(popup_pos,
ImGuiCond_Always); // Note: this is super misleading! The value will serve as reference for FindBestWindowPosForPopup(), not actual pos.
menu_is_open = ImGui::BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
} else {
g.NextWindowData.ClearFlags(); // We behave like Begin() and need to consume those values
}
return menu_is_open;
}
void end_menu()
{
ImGui::EndMenu();
}
bool menu_item_with_icon(const char *label, const char *shortcut, ImVec2 icon_size /* = ImVec2(0, 0)*/, ImU32 icon_color /* = 0*/, bool selected /* = false*/, bool enabled /* = true*/)
{
ImGuiWindow *window = ImGui::GetCurrentWindow();
if (window->SkipItems) return false;
ImGuiContext &g = *GImGui;
ImGuiStyle & style = g.Style;
ImVec2 pos = window->DC.CursorPos;
ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true);
// We've been using the equivalent of ImGuiSelectableFlags_SetNavIdOnHover on all Selectable() since early Nav system days (commit 43ee5d73),
// but I am unsure whether this should be kept at all. For now moved it to be an opt-in feature used by menus only.
ImGuiSelectableFlags flags = ImGuiSelectableFlags_SelectOnRelease | ImGuiSelectableFlags_SetNavIdOnHover | (enabled ? 0 : ImGuiSelectableFlags_Disabled);
bool pressed;
if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) {
// Mimic the exact layout spacing of BeginMenu() to allow MenuItem() inside a menu bar, which is a little misleading but may be useful
// Note that in this situation: we don't render the shortcut, we render a highlight instead of the selected tick mark.
float w = label_size.x;
window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * 0.5f);
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x * 2.0f, style.ItemSpacing.y));
pressed = ImGui::Selectable(label, selected, flags, ImVec2(w, 0.0f));
ImGui::PopStyleVar();
window->DC.CursorPos.x += IM_FLOOR(
style.ItemSpacing.x *
(-1.0f +
0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar().
} else {
// Menu item inside a vertical menu
// (In a typical menu window where all items are BeginMenu() or MenuItem() calls, extra_w will always be 0.0f.
// Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system.
float shortcut_w = shortcut ? ImGui::CalcTextSize(shortcut, NULL).x : 0.0f;
float min_w = window->DC.MenuColumns.DeclColumns(label_size.x, shortcut_w, IM_FLOOR(g.FontSize * 1.20f)); // Feedback for next frame
float extra_w = std::max(0.0f, ImGui::GetContentRegionAvail().x - min_w);
pressed = selectable(label, false, flags | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, 0.0f));
if (icon_size.x != 0 && icon_size.y != 0) {
float selectable_pos_y = pos.y + -0.5f * style.ItemSpacing.y;
float icon_pos_y = selectable_pos_y + (label_size.y + style.ItemSpacing.y - icon_size.y) / 2;
float icon_pos_x = pos.x + window->DC.MenuColumns.Pos[2] + extra_w + g.FontSize * 0.40f;
ImVec2 icon_pos = ImVec2(icon_pos_x, icon_pos_y);
ImGui::RenderFrame(icon_pos, icon_pos + icon_size, icon_color);
}
if (shortcut_w > 0.0f) {
ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]);
ImGui::RenderText(pos + ImVec2(window->DC.MenuColumns.Pos[1] + extra_w, 0.0f), shortcut, NULL, false);
ImGui::PopStyleColor();
}
if (selected) {
//ImGui::RenderCheckMark(window->DrawList, pos + ImVec2(window->DC.MenuColumns.Pos[2] + extra_w + g.FontSize * 0.40f, g.FontSize * 0.134f * 0.5f),
// ImGui::GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled), g.FontSize * 0.866f);
}
}
IMGUI_TEST_ENGINE_ITEM_INFO(window->DC.LastItemId, label, window->DC.LastItemStatusFlags | ImGuiItemStatusFlags_Checkable | (selected ? ImGuiItemStatusFlags_Checked : 0));
return pressed;
}
// Scroll so that the hovered item is at the top of the window
static void scroll_y(int hover_id)
{
@ -1229,7 +1404,7 @@ void ImGuiWrapper::search_list(const ImVec2& size_, bool (*items_getter)(int, co
{
int& hovered_id = view_params.hovered_id;
// ImGui::ListBoxHeader("", size);
{
{
// rewrote part of function to add a TextInput instead of label Text
ImGuiContext& g = *GImGui;
ImGuiWindow* window = ImGui::GetCurrentWindow();
@ -1445,13 +1620,13 @@ std::vector<unsigned char> ImGuiWrapper::load_svg(const std::string& bitmap_name
//BBS
void ImGuiWrapper::push_toolbar_style()
void ImGuiWrapper::push_toolbar_style(const float scale)
{
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20.0f, 10.0f));
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 3.0f);
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f * scale);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20.0f, 10.0f) * scale);
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 3.0f * scale);
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f));
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f) * scale);
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(50/255.0f, 58/255.0f, 61/255.0f, 1.00f)); // 1
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImGuiWrapper::COL_WINDOW_BG); // 2
ImGui::PushStyleColor(ImGuiCol_TitleBg, ImGuiWrapper::COL_TITLE_BG); // 3
@ -1476,11 +1651,11 @@ void ImGuiWrapper::pop_toolbar_style()
ImGui::PopStyleVar(5);
}
void ImGuiWrapper::push_menu_style()
void ImGuiWrapper::push_menu_style(const float scale)
{
ImGuiWrapper::push_toolbar_style();
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10.0f, 10.0f));
ImGui::PushStyleVar(ImGuiStyleVar_PopupRounding, 4.0f);
ImGuiWrapper::push_toolbar_style(scale);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10.0f, 10.0f) * scale);
ImGui::PushStyleVar(ImGuiStyleVar_PopupRounding, 4.0f * scale);
ImGui::PushStyleVar(ImGuiStyleVar_PopupBorderSize, 0.0f);
ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGuiWrapper::COL_WINDOW_BG);
ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.00f, 0.68f, 0.26f, 1.0f));

View file

@ -37,7 +37,9 @@ bool button_with_pos(ImTextureID user_texture_id,
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);
bool begin_menu(const char *label, bool enabled = true);
void end_menu();
bool menu_item_with_icon(const char *label, const char *shortcut, ImVec2 icon_size = ImVec2(0, 0), ImU32 icon_color = 0, bool selected = false, bool enabled = true);
class ImGuiWrapper
@ -181,9 +183,9 @@ public:
static const ImVec4 COL_SEPARATOR;
//BBS
static void push_toolbar_style();
static void push_toolbar_style(const float scale);
static void pop_toolbar_style();
static void push_menu_style();
static void push_menu_style(const float scale);
static void pop_menu_style();
//BBS

View file

@ -403,7 +403,7 @@ void ArrangeJob::prepare()
int state = m_plater->get_prepare_state();
if (state == Job::JobPrepareState::PREPARE_STATE_DEFAULT) {
only_on_partplate = false;
prepare_selected();
prepare_all();
}
else if (state == Job::JobPrepareState::PREPARE_STATE_MENU) {
only_on_partplate = true; // only arrange items on current plate
@ -412,7 +412,7 @@ void ArrangeJob::prepare()
//add the virtual object into unselect list if has
m_plater->get_partplate_list().preprocess_exclude_areas(m_unselected, MAX_NUM_PLATES);
#if SAVE_ARRANGE_POLY
if (1)
{ // subtract excluded region and get a polygon bed
@ -508,16 +508,8 @@ void ArrangeJob::process()
double skirt_distance = print.has_skirt() ? print.config().skirt_distance.value : 0;
bool is_auto_brim = print.has_auto_brim();
double brim_max = 0;
if (is_auto_brim) {
brim_max = 0;
std::for_each(m_selected.begin(), m_selected.end(), [&](ArrangePolygon ap) { brim_max = std::max(brim_max, ap.auto_brim_width); });
}
else {
brim_max = print.has_brim() ? print.default_object_config().brim_width : 0;
std::for_each(m_selected.begin(), m_selected.end(), [&](ArrangePolygon ap) { brim_max = std::max(brim_max, ap.user_brim_width); });
}
std::for_each(m_selected.begin(), m_selected.end(), [&](ArrangePolygon ap) { brim_max = std::max(brim_max, ap.brim_width); });
// Note: skirt_distance is now defined between outermost brim and skirt, not the object and skirt.
// So we can't do max but do adding instead.
@ -558,10 +550,8 @@ void ArrangeJob::process()
params.stopcondition = [this]() { return was_canceled(); };
auto count = unsigned(m_selected.size());// + m_unprintable.size());
params.progressind = [this, count](unsigned num_finished, std::string str="") {
// if (num_finished >= 0 && num_finished <= count)
// update_status(int(float(num_finished) / count * 100), _L("Arranging") + " "+str);
params.progressind = [this](unsigned num_finished, std::string str="") {
update_status(num_finished, _L("Arranging") + " " + str);
};
if(!params.is_seq_print)
@ -610,7 +600,7 @@ void ArrangeJob::process()
}
// finalize just here.
update_status(100,
update_status(status_range(),
was_canceled() ? _(L("Arranging canceled.")) :
we_have_unpackable_items ? _(L("Arranging is done but there are unpacked items. Reduce spacing and try again.")) : _(L("Arranging done.")));
}

View file

@ -59,7 +59,8 @@ public:
int status_range() const override
{
return int(m_selected.size() + m_unprintable.size());
// ensure finalize() is called after all operations in process() is finished.
return int(m_selected.size() + m_unprintable.size() + 1);
}
void finalize() override;

View file

@ -101,10 +101,10 @@ void PrintJob::process()
int curr_percent = 10;
if (this->connection_type == "lan") {
msg = sending_over_lan_str;
msg = _L("Sending print job over LAN");
}
else {
msg = sending_over_cloud_str;
msg = _L("Sending print job through cloud service");
}
int result = -1;

View file

@ -46,12 +46,12 @@ void UpgradeNetworkJob::process()
{
// downloading
int result = 0;
AppConfig* app_config = wxGetApp().app_config;
if (!app_config)
return;
BOOST_LOG_TRIVIAL(info) << "[download_plugin]: enter";
BOOST_LOG_TRIVIAL(info) << "[UpgradeNetworkJob process]: enter";
// get temp path
fs::path target_file_path = (fs::temp_directory_path() / "network_plugin.zip");
@ -74,7 +74,7 @@ void UpgradeNetworkJob::process()
}
curr_percent = percent;
}, cancel_fn);
if (was_canceled()) {
update_status(0, _L("Cancelled"));
wxCommandEvent event(wxEVT_CLOSE_WINDOW);
@ -84,7 +84,7 @@ void UpgradeNetworkJob::process()
}
if (result < 0) {
update_status(curr_percent, _L("Download failed"));
update_status(0, _L("Download failed"));
wxCommandEvent event(EVT_UPGRADE_NETWORK_FAILED);
event.SetEventObject(m_event_handle);
wxPostEvent(m_event_handle, event);
@ -108,7 +108,7 @@ void UpgradeNetworkJob::process()
}
if (result != 0) {
update_status(curr_percent, _L("Install failed"));
update_status(0, _L("Install failed"));
wxCommandEvent event(EVT_UPGRADE_NETWORK_FAILED);
event.SetEventObject(m_event_handle);
wxPostEvent(m_event_handle, event);
@ -118,6 +118,7 @@ void UpgradeNetworkJob::process()
wxCommandEvent event(EVT_UPGRADE_NETWORK_SUCCESS);
event.SetEventObject(m_event_handle);
wxPostEvent(m_event_handle, event);
BOOST_LOG_TRIVIAL(info) << "[UpgradeNetworkJob process]: exit";
return;
}

View file

@ -178,28 +178,14 @@ void KBShortcutsDialog::fill_shortcuts()
// File>Import
{ ctrl + "I", L("Import geometry data from STL/STEP/3MF/OBJ/AMF files.") },
// Edit
{ ctrl + "A", L("Select all objects") },
{ ctrl + "D", L("Delete all") },
{ ctrl + "Z", L("Undo") },
{ ctrl + "Y", L("Redo") },
{ ctrl + "X", L("Cut") },
{ ctrl + "C", L("Copy to clipboard") },
{ ctrl + "V", L("Paste from clipboard") },
{ ctrl + "M", L("Clone selected")},
// Window
{ ctrl + "0", L("Camera view - Default") },
{ ctrl + "1", L("Camera view - Top") },
{ ctrl + "2", L("Camera view - Bottom") },
{ ctrl + "3", L("Camera view - Front") },
{ ctrl + "4", L("Camera view - Behind") },
{ ctrl + "5", L("Camera Angle - Left side") },
{ ctrl + "6", L("Camera Angle - Right side") },
// Configuration
{ ctrl + "P", L("Preferences") },
{ "Esc", L("Deselect all") },
{ "Del", L("Delete selected") },
// View
{ "1-9", L("keyboard 1-9: set filament for object/part") },
#ifdef __APPLE__
{"fn+⌫", L("Delete selected")},
#else
{"Del", L("Delete selected")},
#endif
// Help
{ "?", L("Show keyboard shortcuts list") }
};
@ -209,16 +195,20 @@ void KBShortcutsDialog::fill_shortcuts()
{ "A", L("Arrange all objects") },
{ "Shift+A", L("Arrange objects on selected plates") },
{ "R", L("Auto orientates selected objects or all objects.If there are selected objects, it just orientates the selected ones.Otherwise, it will orientates all objects in the project.") },
//{ "R", L("Auto orientates selected objects or all objects.If there are selected objects, it just orientates the selected ones.Otherwise, it will orientates all objects in the project.") },
{"Shift+R", L("Auto orientates selected objects or all objects.If there are selected objects, it just orientates the selected ones.Otherwise, it will orientates all objects in the current disk.")},
#ifdef __APPLE__
{"Shift+Tab", L("Collapse/Expand the sidebar")},
#ifdef __APPLE__
{L("⌘+Any arrow"), L("Movement in camera space")},
{L("⌥+Left mouse button"), L("Select a part")},
{L("⌘+Left mouse button"), L("Select multiple objects")},
#else
{L("Ctrl+Left mouse button"), L("Select multiple objects")},
#endif
{L("Ctrl+Any arrow"), L("Movement in camera space")},
{L("Alt+Left mouse button"), L("Select a part")},
{L("Ctrl+Left mouse button"), L("Select multiple objects")},
#endif
{L("Shift+Left mouse button"), L("Select objects by rectangle")},
{L("Arrow Up"), L("Move selection 10 mm in positive Y direction")},
{L("Arrow Down"), L("Move selection 10 mm in negative Y direction")},
@ -226,12 +216,27 @@ void KBShortcutsDialog::fill_shortcuts()
{L("Arrow Right"), L("Move selection 10 mm in positive X direction")},
{L("Shift+Any arrow"), L("Movement step set to 1 mm")},
#ifdef __APPLE__
{L("⌘+Any arrow"), L("Movement in camera space")},
#else
{L("Ctrl+Any arrow"), L("Movement in camera space")},
#endif
{"Shift+Tab", L("Collapse/Expand the sidebar")},
{"Esc", L("Deselect all")},
{"1-9", L("keyboard 1-9: set filament for object/part")},
{ctrl + "0", L("Camera view - Default")},
{ctrl + "1", L("Camera view - Top")},
{ctrl + "2", L("Camera view - Bottom")},
{ctrl + "3", L("Camera view - Front")},
{ctrl + "4", L("Camera view - Behind")},
{ctrl + "5", L("Camera Angle - Left side")},
{ctrl + "6", L("Camera Angle - Right side")},
{ctrl + "A", L("Select all objects")},
{ctrl + "D", L("Delete all")},
{ctrl + "Z", L("Undo")},
{ctrl + "Y", L("Redo")},
{ctrl + "M", L("Clone selected")},
{ "M", L("Gizmo move") },
{ "S", L("Gizmo scale") },
{ "R", L("Gizmo rotate") },
{ "C", L("Gizmo cut") },
{ "F", L("Gizmo Place face on bed") },
{ "L", L("Gizmo SLA support points") },
{ "P", L("Gizmo FDM paint-on seam") },
};
m_full_shortcuts.push_back({ { _L("Plater"), "" }, plater_shortcuts });
@ -305,34 +310,25 @@ wxPanel* KBShortcutsDialog::create_page(wxWindow* parent, const ShortcutsItem& s
main_sizer->AddSpacer(FromDIP(10));
}
static const int max_items_per_column = 20;
int columns_count = 1 + static_cast<int>(shortcuts.second.size()) / max_items_per_column;
wxScrolledWindow* scrollable_panel = new wxScrolledWindow(main_page);
int items_count = (int) shortcuts.second.size();
wxScrolledWindow *scrollable_panel = new wxScrolledWindow(main_page);
wxGetApp().UpdateDarkUI(scrollable_panel);
scrollable_panel->SetScrollbars(20, 20, 50, 50);
scrollable_panel->SetInitialSize(wxSize(FromDIP(850), FromDIP(450)));
wxBoxSizer* scrollable_panel_sizer = new wxBoxSizer(wxVERTICAL);
wxFlexGridSizer* grid_sizer = new wxFlexGridSizer(3 * columns_count, 5, 15);
wxBoxSizer * scrollable_panel_sizer = new wxBoxSizer(wxVERTICAL);
wxFlexGridSizer *grid_sizer = new wxFlexGridSizer(items_count, 2, FromDIP(10), FromDIP(20));
int items_count = (int)shortcuts.second.size();
for (int i = 0; i < max_items_per_column; ++i) {
for (int j = 0; j < columns_count; ++j) {
int id = j * max_items_per_column + i;
if (id < items_count) {
const auto& [shortcut, description] = shortcuts.second[id];
auto key = new wxStaticText(scrollable_panel, wxID_ANY, _(shortcut));
key->SetFont(bold_font);
grid_sizer->Add(key, 0, wxALIGN_CENTRE_VERTICAL);
for (int i = 0; i < items_count; ++i) {
const auto &[shortcut, description] = shortcuts.second[i];
auto key = new wxStaticText(scrollable_panel, wxID_ANY, _(shortcut));
key->SetFont(bold_font);
grid_sizer->Add(key, 0, wxALIGN_CENTRE_VERTICAL);
grid_sizer->Add(new wxStaticText(scrollable_panel, wxID_ANY, " "), 0, wxALIGN_CENTRE_VERTICAL);
auto desc = new wxStaticText(scrollable_panel, wxID_ANY, _(description));
desc->SetFont(font);
grid_sizer->Add(desc, 0, wxALIGN_CENTRE_VERTICAL);
}
}
auto desc = new wxStaticText(scrollable_panel, wxID_ANY, _(description));
desc->SetFont(font);
desc->Wrap(FromDIP(600));
grid_sizer->Add(desc, 0, wxALIGN_CENTRE_VERTICAL);
}
scrollable_panel_sizer->Add(grid_sizer, 1, wxEXPAND | wxALL, FromDIP(20));

View file

@ -142,7 +142,7 @@ static wxIcon main_frame_icon(GUI_App::EAppMode app_mode)
#ifdef __WINDOWS__
#define BORDERLESS_FRAME_STYLE (wxRESIZE_BORDER | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxCLOSE_BOX)
#else
#define BORDERLESS_FRAME_STYLE (wxRESIZE_BORDER)
#define BORDERLESS_FRAME_STYLE (wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxCLOSE_BOX)
#endif
wxDEFINE_EVENT(EVT_SYNC_CLOUD_PRESET, SimpleEvent);
@ -184,8 +184,6 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_
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(this);
sizer_tobar->Add(m_topbar, 0, wxEXPAND);
panel_topbar->SetSizer(sizer_tobar);
panel_topbar->Layout();
#endif
@ -206,7 +204,7 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_
default:
case GUI_App::EAppMode::Editor:
m_taskbar_icon = std::make_unique<BambuStudioTaskBarIcon>(wxTBI_DOCK);
m_taskbar_icon->SetIcon(wxIcon(Slic3r::var("BambuStudio-mac_128px.png"), wxBITMAP_TYPE_PNG), "BambuStudio");
m_taskbar_icon->SetIcon(wxIcon(Slic3r::var("BambuStudio-mac_256px.ico"), wxBITMAP_TYPE_ICO), "BambuStudio");
break;
case GUI_App::EAppMode::GCodeViewer:
break;
@ -238,61 +236,63 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_
#endif // _WIN32
// BBS
wxAcceleratorEntry entries[13];
int index = 0;
entries[index++].Set(wxACCEL_CTRL, (int)'N', wxID_HIGHEST + wxID_NEW);
entries[index++].Set(wxACCEL_CTRL, (int)'O', wxID_HIGHEST + wxID_OPEN);
entries[index++].Set(wxACCEL_CTRL, (int)'S', wxID_HIGHEST + wxID_SAVE);
entries[index++].Set(wxACCEL_CTRL | wxACCEL_SHIFT, (int)'S', wxID_HIGHEST + wxID_SAVEAS);
entries[index++].Set(wxACCEL_CTRL, (int)'X', wxID_HIGHEST + wxID_CUT);
//entries[index++].Set(wxACCEL_CTRL, (int)'I', wxID_HIGHEST + wxID_ADD);
entries[index++].Set(wxACCEL_CTRL, (int)'A', wxID_HIGHEST + wxID_SELECTALL);
entries[index++].Set(wxACCEL_NORMAL, (int)27 /* escape */, wxID_HIGHEST + wxID_CANCEL);
entries[index++].Set(wxACCEL_CTRL, (int)'Z', wxID_HIGHEST + wxID_UNDO);
entries[index++].Set(wxACCEL_CTRL, (int)'Y', wxID_HIGHEST + wxID_REDO);
entries[index++].Set(wxACCEL_CTRL, (int)'C', wxID_HIGHEST + wxID_COPY);
entries[index++].Set(wxACCEL_CTRL, (int)'V', wxID_HIGHEST + wxID_PASTE);
entries[index++].Set(wxACCEL_CTRL, (int)'P', wxID_HIGHEST + wxID_PREFERENCES);
entries[index++].Set(wxACCEL_CTRL, (int)'I', wxID_HIGHEST + wxID_FILE6);
wxAcceleratorTable accel(sizeof(entries) / sizeof(entries[0]), entries);
SetAcceleratorTable(accel);
//wxAcceleratorEntry entries[13];
//int index = 0;
//entries[index++].Set(wxACCEL_CTRL, (int)'N', wxID_HIGHEST + wxID_NEW);
//entries[index++].Set(wxACCEL_CTRL, (int)'O', wxID_HIGHEST + wxID_OPEN);
//entries[index++].Set(wxACCEL_CTRL, (int)'S', wxID_HIGHEST + wxID_SAVE);
//entries[index++].Set(wxACCEL_CTRL | wxACCEL_SHIFT, (int)'S', wxID_HIGHEST + wxID_SAVEAS);
//entries[index++].Set(wxACCEL_CTRL, (int)'X', wxID_HIGHEST + wxID_CUT);
////entries[index++].Set(wxACCEL_CTRL, (int)'I', wxID_HIGHEST + wxID_ADD);
//entries[index++].Set(wxACCEL_CTRL, (int)'A', wxID_HIGHEST + wxID_SELECTALL);
//entries[index++].Set(wxACCEL_NORMAL, (int)27 /* escape */, wxID_HIGHEST + wxID_CANCEL);
//entries[index++].Set(wxACCEL_CTRL, (int)'Z', wxID_HIGHEST + wxID_UNDO);
//entries[index++].Set(wxACCEL_CTRL, (int)'Y', wxID_HIGHEST + wxID_REDO);
//entries[index++].Set(wxACCEL_CTRL, (int)'C', wxID_HIGHEST + wxID_COPY);
//entries[index++].Set(wxACCEL_CTRL, (int)'V', wxID_HIGHEST + wxID_PASTE);
//entries[index++].Set(wxACCEL_CTRL, (int)'P', wxID_HIGHEST + wxID_PREFERENCES);
//entries[index++].Set(wxACCEL_CTRL, (int)'I', wxID_HIGHEST + wxID_FILE6);
//wxAcceleratorTable accel(sizeof(entries) / sizeof(entries[0]), entries);
//SetAcceleratorTable(accel);
Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->new_project(); }, wxID_HIGHEST + wxID_NEW);
Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->load_project(); }, wxID_HIGHEST + wxID_OPEN);
// BBS: close save project
Bind(wxEVT_MENU, [this](wxCommandEvent&) { if (m_plater) m_plater->save_project(); }, wxID_HIGHEST + wxID_SAVE);
Bind(wxEVT_MENU, [this](wxCommandEvent&) { if (m_plater) m_plater->save_project(true); }, wxID_HIGHEST + wxID_SAVEAS);
//Bind(wxEVT_MENU, [this](wxCommandEvent&) { if (m_plater) m_plater->add_model(); }, wxID_HIGHEST + wxID_ADD);
//Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->remove_selected(); }, wxID_HIGHEST + wxID_DELETE);
Bind(wxEVT_MENU, [this](wxCommandEvent&) {
if (!can_add_models())
return;
if (m_plater) {
m_plater->add_model();
}
}, wxID_HIGHEST + wxID_FILE6);
Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->select_all(); }, wxID_HIGHEST + wxID_SELECTALL);
Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->deselect_all(); }, wxID_HIGHEST + wxID_CANCEL);
Bind(wxEVT_MENU, [this](wxCommandEvent&) {
if (m_plater->is_view3D_shown())
m_plater->undo();
}, wxID_HIGHEST + wxID_UNDO);
Bind(wxEVT_MENU, [this](wxCommandEvent&) {
if (m_plater->is_view3D_shown())
m_plater->redo();
}, wxID_HIGHEST + wxID_REDO);
Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->copy_selection_to_clipboard(); }, wxID_HIGHEST + wxID_COPY);
Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->paste_from_clipboard(); }, wxID_HIGHEST + wxID_PASTE);
Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->cut_selection_to_clipboard(); }, wxID_HIGHEST + wxID_CUT);
//Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->new_project(); }, wxID_HIGHEST + wxID_NEW);
//Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->load_project(); }, wxID_HIGHEST + wxID_OPEN);
//// BBS: close save project
//Bind(wxEVT_MENU, [this](wxCommandEvent&) { if (m_plater) m_plater->save_project(); }, wxID_HIGHEST + wxID_SAVE);
//Bind(wxEVT_MENU, [this](wxCommandEvent&) { if (m_plater) m_plater->save_project(true); }, wxID_HIGHEST + wxID_SAVEAS);
////Bind(wxEVT_MENU, [this](wxCommandEvent&) { if (m_plater) m_plater->add_model(); }, wxID_HIGHEST + wxID_ADD);
////Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->remove_selected(); }, wxID_HIGHEST + wxID_DELETE);
//Bind(wxEVT_MENU, [this](wxCommandEvent&) {
// if (!can_add_models())
// return;
// if (m_plater) {
// m_plater->add_model();
// }
// }, wxID_HIGHEST + wxID_FILE6);
//Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->select_all(); }, wxID_HIGHEST + wxID_SELECTALL);
//Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->deselect_all(); }, wxID_HIGHEST + wxID_CANCEL);
//Bind(wxEVT_MENU, [this](wxCommandEvent&) {
// if (m_plater->is_view3D_shown())
// m_plater->undo();
// }, wxID_HIGHEST + wxID_UNDO);
//Bind(wxEVT_MENU, [this](wxCommandEvent&) {
// if (m_plater->is_view3D_shown())
// m_plater->redo();
// }, wxID_HIGHEST + wxID_REDO);
//Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->copy_selection_to_clipboard(); }, wxID_HIGHEST + wxID_COPY);
//Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->paste_from_clipboard(); }, wxID_HIGHEST + wxID_PASTE);
//Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->cut_selection_to_clipboard(); }, wxID_HIGHEST + wxID_CUT);
Bind(wxEVT_SIZE, [this](wxSizeEvent&) {
BOOST_LOG_TRIVIAL(trace) << "mainframe: size changed, is maximized = " << this->IsMaximized();
#ifdef __WINDOWS__
if (this->IsMaximized()) {
m_topbar->SetWindowSize();
} else {
m_topbar->SetMaximizedSize();
}
Refresh();
Layout();
#endif
Refresh();
Layout();
});
//BBS
@ -302,18 +302,18 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_
});
Bind(EVT_SYNC_CLOUD_PRESET, &MainFrame::on_select_default_preset, this);
Bind(wxEVT_MENU,
[this](wxCommandEvent&)
{
PreferencesDialog dlg(this);
dlg.ShowModal();
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
if (dlg.seq_top_layer_only_changed() || dlg.seq_seq_top_gcode_indices_changed())
#else
if (dlg.seq_top_layer_only_changed())
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
plater()->refresh_print();
}, wxID_HIGHEST + wxID_PREFERENCES);
// Bind(wxEVT_MENU,
// [this](wxCommandEvent&)
// {
// PreferencesDialog dlg(this);
// dlg.ShowModal();
//#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
// if (dlg.seq_top_layer_only_changed() || dlg.seq_seq_top_gcode_indices_changed())
//#else
// if (dlg.seq_top_layer_only_changed())
//#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
// plater()->refresh_print();
// }, wxID_HIGHEST + wxID_PREFERENCES);
// set default tooltip timer in msec
@ -352,6 +352,12 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_
e.Skip();
});
setMaxSize();
this->Bind(wxEVT_MAXIMIZE, [this](auto &e) {
wxDisplay display(wxDisplay::GetFromWindow(this));
auto pos = display.GetClientArea().GetPosition();
Move(pos - wxPoint{8, 8});
e.Skip();
});
#endif // WIN32
// BBS
Fit();
@ -468,6 +474,35 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_
Slic3r::run_backup_ui_tasks();
});
; }
this->Bind(wxEVT_CHAR_HOOK, [this](wxKeyEvent &evt) {
#ifdef __APPLE__
if (evt.CmdDown() && evt.GetKeyCode() == 'H') { this->Iconize(); return;}
if (evt.CmdDown() && evt.GetKeyCode() == 'Q') { wxPostEvent(this, wxCloseEvent(wxEVT_CLOSE_WINDOW)); return;}
#endif
if (evt.CmdDown() && evt.GetKeyCode() == 'N') { m_plater->new_project(); return;}
if (evt.CmdDown() && evt.GetKeyCode() == 'O') { m_plater->load_project(); return;}
if (evt.CmdDown() && evt.ShiftDown() && evt.GetKeyCode() == 'S') { if (m_plater) m_plater->save_project(true); return;}
else if (evt.CmdDown() && evt.GetKeyCode() == 'S') { if (m_plater) m_plater->save_project(); return;}
if (evt.CmdDown() && evt.GetKeyCode() == 'P') {
PreferencesDialog dlg(this);
dlg.ShowModal();
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
if (dlg.seq_top_layer_only_changed() || dlg.seq_seq_top_gcode_indices_changed())
#else
if (dlg.seq_top_layer_only_changed())
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
plater()->refresh_print();
return;
}
if (evt.CmdDown() && evt.GetKeyCode() == 'I') {
if (!can_add_models()) return;
if (m_plater) { m_plater->add_model(); }
return;
}
evt.Skip();
});
}
#ifdef __WIN32__
@ -700,13 +735,21 @@ void MainFrame::shutdown()
// to avoid any manipulations with them from App->wxEVT_IDLE after of the mainframe closing
wxGetApp().tabs_list.clear();
wxGetApp().model_tabs_list.clear();
wxGetApp().shutdown();
// BBS: why clear ?
//wxGetApp().plater_ = nullptr;
}
void MainFrame::update_title()
{
return;
return;
}
void MainFrame::update_title_colour_after_set_title()
{
#ifdef __WXOSX__
set_title_colour_after_set_title();
#endif
}
void MainFrame::show_option(bool show)
@ -792,13 +835,14 @@ void MainFrame::init_tabpanel()
//monitor
}
#ifdef __WINDOWS__
if (sel == tp3DEditor) {
m_topbar->EnableUndoRedoItems();
}
else {
m_topbar->DisableUndoRedoItems();
}
#endif
/*switch (sel) {
case TabPosition::tpHome:
@ -1452,8 +1496,10 @@ void MainFrame::on_dpi_changed(const wxRect& suggested_rect)
dynamic_cast<Notebook*>(m_tabpanel)->Rescale();
#endif
#ifdef __WINDOWS__
// BBS
m_topbar->Rescale();
#endif
m_tabpanel->Rescale();
@ -1573,9 +1619,11 @@ static wxMenu* generate_help_menu()
return true;
});
// About
#ifdef __WINDOWS__
wxString about_title = wxString::Format(_L("&About %s"), SLIC3R_APP_FULL_NAME);
append_menu_item(helpMenu, wxID_ANY, about_title, about_title,
[](wxCommandEvent&) { Slic3r::GUI::about(); });
#endif
return helpMenu;
}
@ -1605,6 +1653,7 @@ void MainFrame::init_menubar_as_editor()
{
#ifdef __APPLE__
wxMenuBar::SetAutoWindowMenu(false);
m_menubar = new wxMenuBar();
#endif
// File menu
@ -1867,10 +1916,18 @@ void MainFrame::init_menubar_as_editor()
//auto config_wizard_name = _(ConfigWizard::name(true) + "(Debug)");
//const auto config_wizard_tooltip = from_u8((boost::format(_utf8(L("Run %s"))) % config_wizard_name).str());
//auto config_item = new wxMenuItem(m_topbar->GetTopMenu(), ConfigMenuWizard + config_id_base, config_wizard_name, config_wizard_tooltip);
auto preference_item = new wxMenuItem(m_topbar->GetTopMenu(), ConfigMenuPreferences + config_id_base, _L("Preferences") + "\tCtrl+P", "");
//auto printer_item = new wxMenuItem(m_topbar->GetTopMenu(), ConfigMenuPrinter + config_id_base, _L("Printer"), "");
//auto language_item = new wxMenuItem(m_topbar->GetTopMenu(), ConfigMenuLanguage + config_id_base, _L("Switch Language"), "");
m_topbar->GetTopMenu()->Bind(wxEVT_MENU, [this, config_id_base](wxEvent& event) {
#ifdef __APPLE__
wxWindowID bambu_studio_id_base = wxWindow::NewControlId(int(2));
wxMenu* parent_menu = m_menubar->OSXGetAppleMenu();
auto preference_item = new wxMenuItem(parent_menu, BambuStudioMenuPreferences + bambu_studio_id_base, _L("Preferences") + "\tCtrl+P", "");
#else
wxMenu* parent_menu = m_topbar->GetTopMenu();
auto preference_item = new wxMenuItem(parent_menu, ConfigMenuPreferences + config_id_base, _L("Preferences") + "\tCtrl+P", "");
#endif
//auto printer_item = new wxMenuItem(parent_menu, ConfigMenuPrinter + config_id_base, _L("Printer"), "");
//auto language_item = new wxMenuItem(parent_menu, ConfigMenuLanguage + config_id_base, _L("Switch Language"), "");
parent_menu->Bind(wxEVT_MENU, [this, config_id_base](wxEvent& event) {
switch (event.GetId() - config_id_base) {
//case ConfigMenuLanguage:
//{
@ -1935,10 +1992,50 @@ void MainFrame::init_menubar_as_editor()
}
});
#ifdef __APPLE__
wxString about_title = wxString::Format(_L("&About %s"), SLIC3R_APP_FULL_NAME);
auto about_item = new wxMenuItem(parent_menu, BambuStudioMenuAbout + bambu_studio_id_base, about_title, "");
parent_menu->Bind(wxEVT_MENU, [this, bambu_studio_id_base](wxEvent& event) {
switch (event.GetId() - bambu_studio_id_base) {
case BambuStudioMenuAbout:
Slic3r::GUI::about();
break;
case BambuStudioMenuPreferences:
wxGetApp().CallAfter([this] {
PreferencesDialog dlg(this);
dlg.ShowModal();
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
if (dlg.seq_top_layer_only_changed() || dlg.seq_seq_top_gcode_indices_changed())
#else
if (dlg.seq_top_layer_only_changed())
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
plater()->refresh_print();
#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
#ifdef _WIN32
/*
if (wxGetApp().app_config()->get("associate_3mf") == "true")
wxGetApp().associate_3mf_files();
if (wxGetApp().app_config()->get("associate_stl") == "true")
wxGetApp().associate_stl_files();
/*if (wxGetApp().app_config()->get("associate_step") == "true")
wxGetApp().associate_step_files();*/
#endif // _WIN32
#endif
});
break;
default:
break;
}
});
parent_menu->Insert(0, about_item);
parent_menu->Insert(1, preference_item);
#endif
// Help menu
auto helpMenu = generate_help_menu();
#ifdef __WINDOWS__
m_topbar->SetFileMenu(fileMenu);
if (editMenu)
m_topbar->AddDropDownSubMenu(editMenu, _L("Edit"));
@ -1950,6 +2047,16 @@ void MainFrame::init_menubar_as_editor()
//m_topbar->AddDropDownMenuItem(language_item);
//m_topbar->AddDropDownMenuItem(config_item);
m_topbar->AddDropDownSubMenu(helpMenu, _L("Help"));
#else
m_menubar->Append(fileMenu, _L("&File"));
if (editMenu)
m_menubar->Append(editMenu, _L("&Edit"));
if (viewMenu)
m_menubar->Append(viewMenu, _L("&View"));
if (helpMenu)
m_menubar->Append(helpMenu, _L("&Help"));
SetMenuBar(m_menubar);
#endif
#ifdef _MSW_DARK_MODE
if (wxGetApp().tabs_as_menu())
@ -1959,12 +2066,12 @@ void MainFrame::init_menubar_as_editor()
#ifdef __APPLE__
// This fixes a bug on Mac OS where the quit command doesn't emit window close events
// wx bug: https://trac.wxwidgets.org/ticket/18328
/* wxMenu* apple_menu = m_menubar->OSXGetAppleMenu();
wxMenu* apple_menu = m_menubar->OSXGetAppleMenu();
if (apple_menu != nullptr) {
apple_menu->Bind(wxEVT_MENU, [this](wxCommandEvent &) {
Close();
}, wxID_EXIT);
}*/
}
#endif // __APPLE__
}

View file

@ -226,7 +226,8 @@ public:
void update_title();
void show_option(bool show);
void update_title_colour_after_set_title();
void show_option(bool show);
void init_tabpanel();
void create_preset_tabs();
//BBS: GUI refactor

View file

@ -293,6 +293,9 @@ MarkdownTip* MarkdownTip::markdownTip(bool create)
bool MarkdownTip::ShowTip(std::string const& tip, std::string const & tooltip, wxPoint pos)
{
#ifdef NDEBUG
return false;
#endif
return markdownTip()->ShowTip(pos, tip, tooltip);
}

View file

@ -230,11 +230,13 @@ void wxMediaCtrl2::DoSetSize(int x, int y, int width, int height, int sizeFlags)
size = wxSize{16, 9};
int maxHeight = (width * size.GetHeight() + size.GetHeight() - 1) / size.GetWidth();
if (maxHeight != GetMaxHeight()) {
BOOST_LOG_TRIVIAL(info) << "wxMediaCtrl2::DoSetSize: width: " << width << ", height: " << height << ", maxHeight: " << maxHeight;
// BOOST_LOG_TRIVIAL(info) << "wxMediaCtrl2::DoSetSize: width: " << width << ", height: " << height << ", maxHeight: " << maxHeight;
SetMaxSize({-1, maxHeight});
Slic3r::GUI::wxGetApp().CallAfter([this] {
GetParent()->Layout();
GetParent()->Refresh();
if (auto p = GetParent()) {
p->Layout();
p->Refresh();
}
});
}
}

View file

@ -148,6 +148,12 @@ MonitorPanel::~MonitorPanel()
m_refresh_timer->SetOwner(this);
m_refresh_timer->Start(REFRESH_INTERVAL);
wxPostEvent(this, wxTimerEvent());
Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
if (!dev) return;
MachineObject *obj_ = dev->get_selected_machine();
if (obj_)
GUI::wxGetApp().sidebar().load_ams_list(obj_->amsList);
}
void MonitorPanel::init_tabpanel()

View file

@ -227,7 +227,7 @@ static void add_msg_content(wxWindow* parent, wxBoxSizer* content_sizer, wxStrin
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
wxFont monospace = wxGetApp().code_font();
#ifdef _WIN32
#if 1
wxColour text_clr = wxGetApp().get_label_clr_default();
#else
wxColour text_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
@ -318,7 +318,7 @@ WarningDialog::WarningDialog(wxWindow *parent,
finalize();
}
#ifdef _WIN32
#if 1
// MessageDialog
MessageDialog::MessageDialog(wxWindow* parent,

View file

@ -122,7 +122,7 @@ public:
virtual ~WarningDialog() = default;
};
#ifdef _WIN32
#if 1
// Generic static line, used intead of wxStaticLine
class StaticLine: public wxTextCtrl
{

View file

@ -148,7 +148,7 @@ NotificationManager::PopNotification::PopNotification(const NotificationData &n,
m_TextColor = ImVec4(.2f, .2f, .2f, 1.0f);
m_HyperTextColor = ImVec4(0.03, 0.6, 0.18, 1);
m_WindowRadius = 4;
m_WindowRadius = 4.0f * wxGetApp().plater()->get_current_canvas3D()->get_scale();
}

View file

@ -848,7 +848,8 @@ void OG_CustomCtrl::CtrlLine::render(wxDC& dc, wxCoord h_pos, wxCoord v_pos)
// is_url_string = false;
//else if(opt == option_set.front())
// is_url_string = !suppress_hyperlinks && !og_line.label_path.empty();
h_pos = draw_text(dc, wxPoint(h_pos, v_pos), label, field ? (field->blink() ? &blink_color : field->label_color()) : nullptr, ctrl->opt_group->sublabel_width * ctrl->m_em_unit);
static wxColor c("#6B6B6B");
h_pos = draw_text(dc, wxPoint(h_pos, v_pos), label, field ? (field->blink() ? &blink_color : &c) : nullptr, ctrl->opt_group->sublabel_width * ctrl->m_em_unit);
h_pos += 8;
}

View file

@ -196,7 +196,7 @@ void ObjectDataViewModelNode::set_printable_icon(PrintIndicator printable)
void ObjectDataViewModelNode::set_action_icon(bool enable)
{
m_action_enable = enable;
auto undo = enable ? "undo" : "dot";
auto undo = enable ? "lock_normal" : "dot";
m_action_icon_name = m_type & itPlate ? "dot" :
m_type & itObject ? undo :
m_type & (itVolume | itLayer) ? undo : /*m_type & itInstance*/ "set_separate_obj";

View file

@ -462,8 +462,8 @@ bool OptionsGroup::activate(std::function<void()> throw_if_canceled/* = [](){}*/
else {
// BBS: new layout
::StaticLine* stl = new ::StaticLine(m_parent, false, _(title));
stl->SetFont(wxGetApp().normal_font());
stl->SetForegroundColour("#6B6B6B");
stl->SetFont(Label::Head_14);
stl->SetForegroundColour("#262E30");
sizer = new wxBoxSizer(wxVERTICAL);
if (title.IsEmpty()) {
stl->Hide();
@ -1022,6 +1022,8 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
case coPoints:
if (opt_key == "printable_area")
ret = config.option<ConfigOptionPoints>(opt_key)->values;
else if (opt_key == "bed_exclude_area")
ret = get_thumbnails_string(config.option<ConfigOptionPoints>(opt_key)->values);
else
ret = config.option<ConfigOptionPoints>(opt_key)->get_at(idx);
break;
@ -1130,6 +1132,8 @@ boost::any ConfigOptionsGroup::get_config_value2(const DynamicPrintConfig& confi
case coPoints:
if (opt_key == "printable_area")
ret = config.option<ConfigOptionPoints>(opt_key)->values;
else if (opt_key == "bed_exclude_area")
ret = get_thumbnails_string(config.option<ConfigOptionPoints>(opt_key)->values);
else
ret = config.option<ConfigOptionPoints>(opt_key)->get_at(idx);
break;

View file

@ -21,11 +21,10 @@ ParamsDialog::ParamsDialog(wxWindow * parent)
m_panel = new ParamsPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL);
auto* topsizer = new wxBoxSizer(wxVERTICAL);
topsizer->Add(m_panel, 1, wxALL | wxEXPAND, 5, NULL);
topsizer->Add(-1, 5);
topsizer->Add(m_panel, 1, wxALL | wxEXPAND, 0, NULL);
SetSizerAndFit(topsizer);
SetSize({100 * em_unit(), 60 * em_unit()});
SetSize({70 * em_unit(), 60 * em_unit()});
Layout();
Center();
@ -70,7 +69,7 @@ void ParamsDialog::Popup()
void ParamsDialog::on_dpi_changed(const wxRect &suggested_rect)
{
Fit();
SetSize({100 * em_unit(), 60 * em_unit()});
SetSize({70 * em_unit(), 60 * em_unit()});
m_panel->msw_rescale();
Refresh();
}

View file

@ -402,6 +402,7 @@ void ParamsPanel::create_layout()
//m_top_sizer->Add( m_right_sizer, 1, wxEXPAND, 5 );
// BBS: new layout
m_left_sizer->AddSpacer(6 * em_unit(this) / 10);
#if __WXOSX__
m_left_sizer->Add(m_tmp_panel, 1, wxEXPAND | wxALL, 0);
m_tmp_panel->GetSizer()->Add( m_page_view, 1, wxEXPAND );

View file

@ -62,7 +62,7 @@ namespace GUI {
class Bed3D;
std::array<float, 4> PartPlate::SELECT_COLOR = { 0.4196f, 0.4235f, 0.4235f, 1.0f };
std::array<float, 4> PartPlate::SELECT_COLOR = { 0.2666f, 0.2784f, 0.2784f, 1.0f }; //{ 0.4196f, 0.4235f, 0.4235f, 1.0f };
std::array<float, 4> PartPlate::UNSELECT_COLOR = { 0.82f, 0.82f, 0.82f, 1.0f };
std::array<float, 4> PartPlate::DEFAULT_COLOR = { 0.5f, 0.5f, 0.5f, 1.0f };
std::array<float, 4> PartPlate::LINE_TOP_COLOR = { 0.89f, 0.89f, 0.89f, 1.0f };
@ -199,11 +199,11 @@ void PartPlate::calc_gridlines(const ExPolygon& poly, const BoundingBox& pp_bbox
line.append(Point(x, pp_bbox.min(1)));
line.append(Point(x, pp_bbox.max(1)));
count ++;
if ( (count % 5) == 0 )
axes_lines_bolder.push_back(line);
else
axes_lines.push_back(line);
count ++;
}
count = 0;
for (coord_t y = pp_bbox.min(1); y <= pp_bbox.max(1); y += scale_(10.0)) {
@ -212,11 +212,11 @@ void PartPlate::calc_gridlines(const ExPolygon& poly, const BoundingBox& pp_bbox
line.append(Point(pp_bbox.max(0), y));
axes_lines.push_back(line);
count ++;
if ( (count % 5) == 0 )
axes_lines_bolder.push_back(line);
else
axes_lines.push_back(line);
count ++;
}
// clip with a slightly grown expolygon because our lines lay on the contours and may get erroneously clipped
@ -385,7 +385,8 @@ void PartPlate::render_logo(bool bottom) const
// starts generating the main texture, compression will run asynchronously
GLint max_tex_size = OpenGLManager::get_gl_info().get_max_tex_size();
if (!m_partplate_list->m_logo_texture.load_from_svg_file(m_partplate_list->m_logo_texture_filename, true, true, true, max_tex_size/8)) {
GLint logo_tex_size = (max_tex_size < 2048)?max_tex_size: 2048;
if (!m_partplate_list->m_logo_texture.load_from_svg_file(m_partplate_list->m_logo_texture_filename, true, true, true, logo_tex_size)) {
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": load logo texture from %1% failed!")%m_partplate_list->m_logo_texture_filename;
return;
}
@ -1838,8 +1839,8 @@ bool PartPlate::set_shape(const Pointfs& shape, const Pointfs& exclude_areas, Ve
ExPolygon logo_poly;
generate_logo_polygon(logo_poly);
if (!m_logo_triangles.set_from_triangles(triangulate_expolygon_2f(logo_poly, NORMALS_UP), GROUND_Z+0.28f))
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":Unable to create plate triangles\n";
if (!m_logo_triangles.set_from_triangles(triangulate_expolygon_2f(logo_poly, NORMALS_UP), GROUND_Z+0.02f))
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":Unable to create logo triangles\n";
ExPolygon poly;
/*for (const Vec2d& p : m_shape) {
@ -1882,9 +1883,9 @@ const BoundingBox PartPlate::get_bounding_box_crd()
return plate_shape.bounding_box();
}
bool PartPlate::contains(const Point& point) const
bool PartPlate::contains(const Vec3d& point) const
{
return m_polygon.contains(point);
return m_bounding_box.contains(point);
}
bool PartPlate::contains(const GLVolume& v) const
@ -1916,11 +1917,6 @@ bool PartPlate::intersects(const BoundingBoxf3& bb) const
return print_volume.intersects(bb);
}
Point PartPlate::point_projection(const Point& point) const
{
return m_polygon.point_projection(point);
}
void PartPlate::render(bool bottom, bool only_body, bool force_background_color, HeightLimitMode mode, int hover_id)
{
glsafe(::glEnable(GL_DEPTH_TEST));

View file

@ -114,7 +114,6 @@ private:
Transform3d m_grabber_trans_matrix;
Slic3r::Geometry::Transformation position;
std::vector<Vec3f> positions;
Polygon m_polygon;
unsigned int m_vbo_id{ 0 };
GeometryBuffer m_triangles;
GeometryBuffer m_exclude_triangles;
@ -285,12 +284,11 @@ public:
/*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);
bool contains(const Point& point) const;
bool contains(const Vec3d& point) const;
bool contains(const GLVolume& v) const;
bool contains(const BoundingBoxf3& bb) const;
bool intersects(const BoundingBoxf3& bb) const;
Point point_projection(const Point& point) const;
void render(bool bottom, bool only_body = false, bool force_background_color = false, HeightLimitMode mode = HEIGHT_LIMIT_NONE, int hover_id = -1);
void render_for_picking() const { on_render_for_picking(); }
void set_selected();
@ -520,6 +518,7 @@ public:
Vec3d get_current_plate_origin() { return compute_origin(m_current_plate, m_plate_cols); }
Vec2d get_current_shape_position() { return compute_shape_position(m_current_plate, m_plate_cols); }
Pointfs get_exclude_area() { return m_exclude_areas; }
//select plate
int select_plate(int index);

View file

@ -103,7 +103,6 @@
#include "Widgets/ProgressDialog.hpp"
#include "BBLStatusBar.hpp"
#include "BitmapCache.hpp"
#include "AuxiliaryDialog.hpp"
#include "ParamsDialog.hpp"
#include "Widgets/Label.hpp"
#include "Widgets/RoundedRectangle.hpp"
@ -268,7 +267,7 @@ struct Sidebar::priv
{
Plater *plater;
wxScrolledWindow *scrolled;
wxPanel *scrolled;
PlaterPresetComboBox *combo_print;
std::vector<PlaterPresetComboBox*> combos_filament;
int editing_filament = -1;
@ -304,7 +303,6 @@ struct Sidebar::priv
wxPanel* m_panel_printer_content = nullptr;
ObjectList *m_object_list{ nullptr };
AuxiliaryDialog *m_auxiliary_dialog{ nullptr };
ObjectSettings *object_settings{ nullptr };
wxButton *btn_export_gcode;
@ -407,12 +405,12 @@ void Sidebar::priv::hide_rich_tip(wxButton* btn)
Sidebar::Sidebar(Plater *parent)
: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(42 * wxGetApp().em_unit(), -1)), p(new priv(parent))
{
p->scrolled = new wxScrolledWindow(this);
p->scrolled = new wxPanel(this);
// p->scrolled->SetScrollbars(0, 100, 1, 2); // ys_DELETE_after_testing. pixelsPerUnitY = 100
// but this cause the bad layout of the sidebar, when all infoboxes appear.
// 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->SetScrollRate(0, 5);
p->scrolled->SetBackgroundColour(*wxWHITE);
@ -476,16 +474,16 @@ Sidebar::Sidebar(Plater *parent)
// 1.2 Add spliters around title bar
// add spliter 1
auto spliter_1 = new ::StaticLine(p->scrolled);
spliter_1->SetBackgroundColour("#A6A9AA");
scrolled_sizer->Add(spliter_1, 0, wxEXPAND);
//auto spliter_1 = new ::StaticLine(p->scrolled);
//spliter_1->SetBackgroundColour("#A6A9AA");
//scrolled_sizer->Add(spliter_1, 0, wxEXPAND);
// add printer title
scrolled_sizer->Add(p->m_panel_printer_title, 0, wxEXPAND | wxALL, 0);
// add spliter 2
auto spliter_2 = new ::StaticLine(p->scrolled);
spliter_2->SetBackgroundColour("#ACACAC");
spliter_2->SetLineColour("#CECECE");
scrolled_sizer->Add(spliter_2, 0, wxEXPAND);
@ -518,7 +516,7 @@ Sidebar::Sidebar(Plater *parent)
wxStaticText* bed_type_title = new wxStaticText(p->m_panel_printer_content, wxID_ANY, _L("Bed type"));
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);
m_bed_type_list = new ComboBox(p->m_panel_printer_content, wxID_ANY, wxString(""), wxDefaultPosition, {-1, FromDIP(24)}, 0, nullptr, wxCB_READONLY);
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)
@ -532,10 +530,11 @@ Sidebar::Sidebar(Plater *parent)
p->m_panel_printer_content->SetSizer(vsizer_printer);
p->m_panel_printer_content->Layout();
scrolled_sizer->Add(p->m_panel_printer_content, 0, wxTOP | wxEXPAND, FromDIP(5));
scrolled_sizer->AddSpacer(FromDIP(20));
scrolled_sizer->Add(p->m_panel_printer_content, 0, wxTOP | wxEXPAND, FromDIP(14));
scrolled_sizer->AddSpacer(FromDIP(16));
}
{
// 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);
@ -556,11 +555,11 @@ Sidebar::Sidebar(Plater *parent)
p->m_panel_filament_title->SetSizer( bSizer39 );
p->m_panel_filament_title->Layout();
auto spliter_1 = new ::StaticLine(p->scrolled);
spliter_1->SetBackgroundColour("#A6A9AA");
spliter_1->SetLineColour("#A6A9AA");
scrolled_sizer->Add(spliter_1, 0, wxEXPAND);
scrolled_sizer->Add(p->m_panel_filament_title, 0, wxEXPAND | wxALL, 0);
auto spliter_2 = new ::StaticLine(p->scrolled);
spliter_2->SetBackgroundColour("#ACACAC");
spliter_2->SetLineColour("#CECECE");
scrolled_sizer->Add(spliter_2, 0, wxEXPAND);
// BBS
@ -701,22 +700,21 @@ Sidebar::Sidebar(Plater *parent)
//bSizer_filament_content->Add(p->sizer_filaments, 1, wxALIGN_CENTER | wxALL);
p->m_panel_filament_content->SetSizer(p->sizer_filaments);
p->m_panel_filament_content->Layout();
scrolled_sizer->Add(p->m_panel_filament_content, 0, wxTOP | wxEXPAND, FromDIP(5));
scrolled_sizer->AddSpacer(FromDIP(20));
scrolled_sizer->Add(p->m_panel_filament_content, 0, wxTOP | wxEXPAND, FromDIP(14));
scrolled_sizer->AddSpacer(FromDIP(16));
}
{
//add project title
auto params_panel = ((MainFrame*)parent->GetParent())->m_param_panel;
if (params_panel) {
params_panel->get_top_panel()->Reparent(p->scrolled);
auto spliter_1 = new ::StaticLine(p->scrolled);
spliter_1->SetBackgroundColour("#A6A9AA");
scrolled_sizer->Add(spliter_1, 0, wxEXPAND);
spliter_1 = new ::StaticLine(p->scrolled); // double line
spliter_1->SetBackgroundColour("#A6A9AA");
spliter_1->SetLineColour("#A6A9AA");
scrolled_sizer->Add(spliter_1, 0, wxEXPAND);
scrolled_sizer->Add(params_panel->get_top_panel(), 0, wxEXPAND);
auto spliter_2 = new ::StaticLine(p->scrolled);
spliter_2->SetBackgroundColour("#ACACAC");
spliter_2->SetLineColour("#CECECE");
scrolled_sizer->Add(spliter_2, 0, wxEXPAND);
}
@ -724,11 +722,9 @@ Sidebar::Sidebar(Plater *parent)
p->sizer_params = new wxBoxSizer(wxVERTICAL);
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);
scrolled_sizer->Add(p->sizer_params, 2, wxEXPAND | wxLEFT, 0);
p->m_object_list->Hide();
p->m_auxiliary_dialog = new AuxiliaryDialog(this);
// Frequently Object Settings
p->object_settings = new ObjectSettings(p->scrolled);
#if !NEW_OBJECT_SETTING
@ -737,9 +733,10 @@ Sidebar::Sidebar(Plater *parent)
#else
if (params_panel) {
params_panel->Reparent(p->scrolled);
scrolled_sizer->Add(params_panel, 2, wxEXPAND);
scrolled_sizer->Add(params_panel, 3, wxEXPAND);
}
#endif
}
auto *sizer = new wxBoxSizer(wxVERTICAL);
sizer->Add(p->scrolled, 1, wxEXPAND);
@ -1192,17 +1189,12 @@ ObjectList* Sidebar::obj_list()
return p->m_object_list;
}
AuxiliaryList* Sidebar::aux_list()
{
return p->m_auxiliary_dialog->aux_list();
}
ObjectSettings* Sidebar::obj_settings()
{
return p->object_settings;
}
wxScrolledWindow* Sidebar::scrolled_panel()
wxPanel* Sidebar::scrolled_panel()
{
return p->scrolled;
}
@ -1336,12 +1328,6 @@ bool Sidebar::show_object_list(bool show) const
return true;
}
bool Sidebar::show_auxiliary_dialog() const
{
p->m_auxiliary_dialog->Reparent(wxGetApp().mainframe);
return p->m_auxiliary_dialog->ShowModal();
}
std::vector<PlaterPresetComboBox*>& Sidebar::combos_filament()
{
return p->combos_filament;
@ -2003,11 +1989,8 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
// BBS: move sidebar to left side
hsizer->Add(sidebar, 0, wxEXPAND | wxLEFT | wxRIGHT, 0);
auto spliter_1 = new ::StaticLine(q, true);
spliter_1->SetBackgroundColour("#A6A9AA");
spliter_1->SetLineColour("#A6A9AA");
hsizer->Add(spliter_1, 0, wxEXPAND);
auto spliter_2 = new ::StaticLine(q, true);
spliter_2->SetBackgroundColour("#A6A9AA");
hsizer->Add(spliter_2, 0, wxEXPAND);
panel_sizer = new wxBoxSizer(wxHORIZONTAL);
panel_sizer->Add(view3D, 1, wxEXPAND | wxALL, 0);
@ -2642,11 +2625,11 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
// BBS: add part plate related logic
PlateDataPtrs plate_data;
bool is_bbs_3mf;
En3mfType en_3mf_file_type = En3mfType::From_BBS;
ConfigSubstitutionContext config_substitutions{ForwardCompatibilitySubstitutionRule::Enable};
std::vector<Preset *> project_presets;
// BBS: backup & restore
model = Slic3r::Model::read_from_archive(path.string(), &config_loaded, &config_substitutions, strategy, &plate_data, &project_presets, &is_bbs_3mf,
model = Slic3r::Model::read_from_archive(path.string(), &config_loaded, &config_substitutions, en_3mf_file_type, strategy, &plate_data, &project_presets,
&file_version,
[this, &dlg, real_filename, progress_percent](int import_stage, int current, int total, bool &cancel) {
bool cont = true;
@ -2657,16 +2640,45 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__
<< boost::format(", plate_data.size %1%, project_preset.size %2%, is_bbs_3mf %3%, file_version %4% \n") % plate_data.size() %
project_presets.size() % is_bbs_3mf % file_version.to_string();
project_presets.size() % (en_3mf_file_type == En3mfType::From_BBS) % file_version.to_string();
// add extruder for prusa model if the number of existing extruders is not enough
if (en_3mf_file_type == En3mfType::From_Prusa) {
std::set<int> extruderIds;
for (ModelObject *o : model.objects) {
if (o->config.option("extruder")) extruderIds.insert(o->config.extruder());
for (auto volume : o->volumes) {
if (volume->config.option("extruder")) extruderIds.insert(volume->config.extruder());
for (int extruder : volume->get_extruders()) { extruderIds.insert(extruder); }
}
}
int size = extruderIds.size() == 0 ? 0 : *(extruderIds.rbegin());
int filament_size = sidebar->combos_filament().size();
while (filament_size < 16 && filament_size < size) {
int filament_count = filament_size + 1;
wxColour new_col = Plater::get_next_color_for_filament();
std::string new_color = new_col.GetAsString(wxC2S_HTML_SYNTAX).ToStdString();
wxGetApp().preset_bundle->set_num_filaments(filament_count, new_color);
wxGetApp().plater()->on_filaments_change(filament_count);
++filament_size;
}
wxGetApp().get_tab(Preset::TYPE_PRINT)->update();
}
// BBS: version check
Semver app_version = *(Semver::parse(SLIC3R_VERSION));
if (load_config && (file_version.maj() != app_version.maj())) {
if (en_3mf_file_type == En3mfType::From_Prusa) {
// do not reset the model config
load_config = false;
show_info(q, _L("The 3mf is not from Bambu Lab, load geometry data only."), _L("Load 3mf"));
}
else if (load_config && (file_version.maj() != app_version.maj())) {
// version mismatch, only load geometries
load_config = false;
if (!load_model) {
// only load config case, return directly
show_info(q, _L("The Config is not compatible and can not be loaded."), _L("Incompatible 3mf"));
show_info(q, _L("The Config can not be loaded."), _L("Load 3mf"));
return empty_result;
}
load_old_project = true;
@ -2674,7 +2686,10 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
q->select_view_3D("3D");
// select plate 0 as default
q->select_plate(0);
show_info(q, _L("the 3mf is not compatible, load geometry data only!"), _L("Incompatible 3mf"));
if (en_3mf_file_type == En3mfType::From_BBS)
show_info(q, _L("The 3mf is generated by old Bambu Studio, load geometry data only."), _L("Load 3mf"));
else
show_info(q, _L("The 3mf is not from Bambu Lab, load geometry data only."), _L("Load 3mf"));
for (ModelObject *model_object : model.objects) {
model_object->config.reset();
// Is there any modifier or advanced config data?
@ -2773,7 +2788,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
q->select_view_3D("3D");
// select plate 0 as default
q->select_plate(0);
show_info(q, _L("the 3mf is not compatible, load geometry data only!"), _L("Incompatible 3mf"));
show_info(q, _L("The 3mf is not compatible, load geometry data only!"), _L("Incompatible 3mf"));
for (ModelObject *model_object : model.objects) {
model_object->config.reset();
// Is there any modifier or advanced config data?
@ -3166,27 +3181,36 @@ std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs& mode
#endif /* AUTOPLACEMENT_ON_LOAD */
}
//BBS: remove the auto scaled_down logic when load models
/*
//BBS: when the object is too large, let the user choose whether to scale it down
for (size_t i = 0; i < object->instances.size(); ++i) {
ModelInstance* instance = object->instances[i];
const Vec3d size = object->instance_bounding_box(i).size();
const Vec3d ratio = size.cwiseQuotient(bed_size);
const double max_ratio = std::max(ratio(0), ratio(1));
if (max_ratio > 10000) {
// the size of the object is too big -> this could lead to overflow when moving to clipper coordinates,
// so scale down the mesh
object->scale_mesh_after_creation(1. / max_ratio);
object->origin_translation = Vec3d::Zero();
object->center_around_origin();
scaled_down = true;
break;
MessageDialog dlg(q, _L("Your object appears to be too large, Do you want to scale it down to fit the heat bed automatically?"), _L("Object too large"),
wxICON_QUESTION | wxYES_NO);
int answer = dlg.ShowModal();
if (answer == wxID_YES) {
// the size of the object is too big -> this could lead to overflow when moving to clipper coordinates,
// so scale down the mesh
object->scale_mesh_after_creation(1. / max_ratio);
object->origin_translation = Vec3d::Zero();
object->center_around_origin();
scaled_down = true;
break;
}
}
else if (max_ratio > 5) {
instance->set_scaling_factor(instance->get_scaling_factor() / max_ratio);
scaled_down = true;
else if (max_ratio > 10) {
MessageDialog dlg(q, _L("Your object appears to be too large, Do you want to scale it down to fit the heat bed automatically?"), _L("Object too large"),
wxICON_QUESTION | wxYES_NO);
int answer = dlg.ShowModal();
if (answer == wxID_YES) {
instance->set_scaling_factor(instance->get_scaling_factor() / max_ratio);
scaled_down = true;
}
}
}*/
}
object->ensure_on_bed(allow_negative_z);
if (!split_object) {
@ -3261,8 +3285,6 @@ std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs& mode
// BBS
void Plater::priv::load_auxiliary_files()
{
// AuxiliaryList* aux_list = dynamic_cast<AuxiliaryList*>(sidebar->aux_list());
// aux_list->reload(auxiliary_path);
std::string auxiliary_path = encode_path(q->model().get_auxiliary_file_temp_path().c_str());
wxGetApp().mainframe->m_auxiliary->Reload(auxiliary_path);
}
@ -4482,7 +4504,14 @@ void Plater::priv::set_current_panel(wxPanel* panel, bool no_slice)
preview->get_canvas3d()->render(true);
}
}
this->partplate_list.select_plate_view();
//TODO: turn off this switch currently
/*auto canvas_w = float(preview->get_canvas3d()->get_canvas_size().get_width());
auto canvas_h = float(preview->get_canvas3d()->get_canvas_size().get_height());
Point screen_center(canvas_w/2, canvas_h/2);
auto center_point = preview->get_canvas3d()->_mouse_to_3d(screen_center);
center_point(2) = 0.f;
if (!current_plate->contains(center_point))
this->partplate_list.select_plate_view();*/
// keeps current gcode preview, if any
if (this->m_slice_all) {
@ -4724,6 +4753,7 @@ void Plater::priv::on_select_preset(wxCommandEvent &evt)
if (preset_type == Preset::TYPE_FILAMENT) {
wxGetApp().preset_bundle->set_filament_preset(idx, preset_name);
//wxGetApp().get_tab(preset_type)->select_preset(preset_name);
}
bool select_preset = !combo->selection_is_changed_according_to_physical_printers();
@ -5557,7 +5587,13 @@ void Plater::priv::set_project_name(const wxString& project_name)
{
m_project_name = project_name;
//update topbar title
#ifdef __WINDOWS__
wxGetApp().mainframe->topbar()->SetTitle(m_project_name);
#else
wxGetApp().mainframe->SetTitle(m_project_name);
if (!m_project_name.IsEmpty())
wxGetApp().mainframe->update_title_colour_after_set_title();
#endif
}
void Plater::priv::set_project_filename(const wxString& filename)
@ -5879,7 +5915,9 @@ void Plater::priv::set_bed_shape(const Pointfs& shape, const Pointfs& exclude_ar
partplate_list.get_height_limits(prev_height_lid, prev_height_rod);
double height_to_lid = config->opt_float("extruder_clearance_height_to_lid");
double height_to_rod = config->opt_float("extruder_clearance_height_to_rod");
new_shape |= (height_to_lid != prev_height_lid) || (height_to_rod != prev_height_rod);
Pointfs prev_exclude_areas = partplate_list.get_exclude_area();
new_shape |= (height_to_lid != prev_height_lid) || (height_to_rod != prev_height_rod) || (prev_exclude_areas != exclude_areas);
if (new_shape) {
if (view3D) view3D->bed_shape_changed();
if (preview) preview->bed_shape_changed();
@ -6570,6 +6608,8 @@ int Plater::save_project(bool saveAs)
up_to_date(true, false);
up_to_date(true, true);
wxGetApp().update_saved_preset_from_current_preset();
p->dirty_state.reset_after_save();
return wxID_YES;
}
@ -8169,7 +8209,8 @@ 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_filaments_info.begin(); it != plate_data->slice_filaments_info.end(); it++) {
it->type = cfg.get_filament_type(it->id);
std::string display_filament_type;
it->type = cfg.get_filament_type(display_filament_type, it->id);
it->color = filament_color ? filament_color->get_at(it->id) : "#FFFFFF";
// save filament info used in curr plate
int index = p->partplate_list.get_curr_plate_index();
@ -8697,7 +8738,7 @@ void Plater::on_config_change(const DynamicPrintConfig &config)
GLCanvas3D* view3d_canvas = get_view3D_canvas3D();
auto seq_print = config.option<ConfigOptionEnum<PrintSequence>>("print_sequence");
if ( seq_print && view3d_canvas && view3d_canvas->is_rendering_enabled() ) {
if ( seq_print && view3d_canvas && view3d_canvas->is_initialized() && view3d_canvas->is_rendering_enabled() ) {
NotificationManager *notify_manager = get_notification_manager();
if (seq_print->value == PrintSequence::ByObject) {
std::string info_text = L("Print By Object: \nSuggest to use auto-arrange to avoid collisions when printing.");

View file

@ -19,7 +19,6 @@
#include "Search.hpp"
#include "PartPlate.hpp"
#include "GUI_App.hpp"
#include "GUI_AuxiliaryList.hpp"
#include "Jobs/PrintJob.hpp"
#include "libslic3r/Model.hpp"
@ -122,12 +121,10 @@ public:
ObjectList* obj_list();
ObjectSettings* obj_settings();
wxScrolledWindow* scrolled_panel();
wxPanel* scrolled_panel();
wxPanel* print_panel();
wxPanel* filament_panel();
AuxiliaryList* aux_list();
ConfigOptionsGroup* og_freq_chng_params(const bool is_fff);
wxButton* get_wiping_dialog_button();
@ -147,7 +144,6 @@ public:
void update_searcher();
void update_ui_from_settings();
bool show_object_list(bool show) const;
bool show_auxiliary_dialog() const;
#ifdef _MSW_DARK_MODE
void show_mode_sizer(bool show);

View file

@ -125,6 +125,9 @@ wxBoxSizer *PreferencesDialog::create_item_language_combobox(
else if (vlist[i] == wxLocale::GetLanguageInfo(wxLANGUAGE_FRENCH)) {
language_name = wxString::FromUTF8("\x46\x72\x61\x6E\xC3\xA7\x61\x69\x73");
}
else if (vlist[i] == wxLocale::GetLanguageInfo(wxLANGUAGE_HUNGARIAN)) {
language_name = wxString::FromUTF8("Magyar");
}
if (app_config->get(param) == vlist[i]->CanonicalName) {
m_current_language_selected = i;
@ -237,20 +240,24 @@ wxBoxSizer *PreferencesDialog::create_item_region_combobox(wxString title, wxWin
else
area = "Others";
MessageDialog msg_wingow(nullptr, _L("Changing the region will log out your account.\n") + "\n" + _L("Do you want to continue?"), L("Region selection"),
wxICON_QUESTION | wxOK | wxCANCEL);
if (msg_wingow.ShowModal() == wxID_CANCEL) {
combobox->SetSelection(current_region);
return;
} else {
NetworkAgent *agent = wxGetApp().getAgent();
wxGetApp().request_user_logout();
AppConfig * config = GUI::wxGetApp().app_config;
if (agent) {
agent->set_country_code(area);
NetworkAgent* agent = wxGetApp().getAgent();
AppConfig* config = GUI::wxGetApp().app_config;
if (agent) {
MessageDialog msg_wingow(this, _L("Changing the region will log out your account.\n") + "\n" + _L("Do you want to continue?"), L("Region selection"),
wxICON_QUESTION | wxOK | wxCANCEL);
if (msg_wingow.ShowModal() == wxID_CANCEL) {
combobox->SetSelection(current_region);
return;
} else {
wxGetApp().request_user_logout();
if (agent) {
agent->set_country_code(area);
}
config->set("region", region.ToStdString());
EndModal(wxID_CANCEL);
}
} else {
config->set("region", region.ToStdString());
EndModal(wxID_CANCEL);
}
e.Skip();
@ -561,9 +568,14 @@ void PreferencesDialog::create()
SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO));
SetSizeHints(wxDefaultSize, wxDefaultSize);
auto main_sizer = new wxBoxSizer(wxVERTICAL);
m_scrolledWindow = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
m_scrolledWindow->SetScrollRate(5, 5);
m_sizer_body = new wxBoxSizer(wxVERTICAL);
auto m_top_line = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(DESIGN_RESOUTION_PREFERENCES.x, 1), wxTAB_TRAVERSAL);
auto m_top_line = new wxPanel(m_scrolledWindow, wxID_ANY, wxDefaultPosition, wxSize(DESIGN_RESOUTION_PREFERENCES.x, 1), wxTAB_TRAVERSAL);
m_top_line->SetBackgroundColour(DESIGN_GRAY400_COLOR);
m_sizer_body->Add(m_top_line, 0, wxEXPAND, 0);
@ -576,16 +588,26 @@ void PreferencesDialog::create()
create_sync_page();
create_shortcuts_page();*/
m_sizer_body->Add(0, 0, 0, wxTOP, FromDIP(28));
m_sizer_body->Add(0, 0, 0, wxTOP, FromDIP(28));
m_sizer_body->Add(general_page, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(38));
#if !BBL_RELEASE_TO_PUBLIC
m_sizer_body->Add(debug_page, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(38));
#endif
m_sizer_body->Add(0, 0, 0, wxBOTTOM, FromDIP(28));
SetSizer(m_sizer_body);
m_scrolledWindow->SetSizerAndFit(m_sizer_body);
main_sizer->Add(m_scrolledWindow, 1, wxEXPAND);
SetSizer(main_sizer);
Layout();
Fit();
int screen_height = wxGetDisplaySize().GetY();
if (this->GetSize().GetY() > screen_height)
this->SetSize(this->GetSize().GetX() + FromDIP(40), screen_height * 4 / 5);
CenterOnParent();
wxPoint start_pos = this->GetPosition();
if (start_pos.y < 0) { this->SetPosition(wxPoint(start_pos.x, 0)); }
//select first
auto event = wxCommandEvent(EVT_PREFERENCES_SELECT_TAB);
@ -625,14 +647,22 @@ void PreferencesDialog::Split(const std::string &src, const std::string &separat
wxWindow* PreferencesDialog::create_general_page()
{
auto page = new wxWindow(this, wxID_ANY);
auto page = new wxWindow(m_scrolledWindow, wxID_ANY);
page->SetBackgroundColour(*wxWHITE);
wxBoxSizer *sizer_page = new wxBoxSizer(wxVERTICAL);
auto title_general_settings = create_item_title(_L("General Settings"), page, _L("General Settings"));
// bbs supported languages
wxLanguage supported_languages[]{wxLANGUAGE_ENGLISH, wxLANGUAGE_CHINESE_SIMPLIFIED, wxLANGUAGE_GERMAN, wxLANGUAGE_FRENCH, wxLANGUAGE_SPANISH, wxLANGUAGE_SWEDISH, wxLANGUAGE_DUTCH };
wxLanguage supported_languages[]{
wxLANGUAGE_ENGLISH,
wxLANGUAGE_CHINESE_SIMPLIFIED,
wxLANGUAGE_GERMAN,
wxLANGUAGE_FRENCH,
wxLANGUAGE_SPANISH,
wxLANGUAGE_SWEDISH,
wxLANGUAGE_DUTCH,
wxLANGUAGE_HUNGARIAN };
auto translations = wxTranslations::Get()->GetAvailableTranslations(SLIC3R_APP_KEY);
std::vector<const wxLanguageInfo *> language_infos;
@ -641,8 +671,8 @@ wxWindow* PreferencesDialog::create_general_page()
const wxLanguageInfo *langinfo = wxLocale::FindLanguageInfo(translations[i]);
if (langinfo == nullptr) continue;
for (auto si = 0; si < 7; si++) {
int language_num = sizeof(supported_languages) / sizeof(supported_languages[0]);
for (auto si = 0; si < language_num; si++) {
if (langinfo == wxLocale::GetLanguageInfo(supported_languages[si])) {
language_infos.emplace_back(langinfo);
}
@ -782,19 +812,19 @@ wxBoxSizer* PreferencesDialog::create_debug_page()
wxBoxSizer *bSizer = new wxBoxSizer(wxVERTICAL);
auto title_develop_mode = create_item_title(_L("Develop mode"), this, _L("Develop mode"));
auto item_develop_mode = create_item_checkbox(_L("Develop mode"), this, _L("Develop mode"), 50, "developer_mode");
auto item_dump_video = create_item_checkbox(_L("Dump video"), this, _L("Dump video"), 50, "dump_video");
auto title_develop_mode = create_item_title(_L("Develop mode"), m_scrolledWindow, _L("Develop mode"));
auto item_develop_mode = create_item_checkbox(_L("Develop mode"), m_scrolledWindow, _L("Develop mode"), 50, "developer_mode");
auto item_dump_video = create_item_checkbox(_L("Dump video"), m_scrolledWindow, _L("Dump video"), 50, "dump_video");
auto title_log_level = create_item_title(_L("Log Level"), this, _L("Log Level"));
auto title_log_level = create_item_title(_L("Log Level"), m_scrolledWindow, _L("Log Level"));
auto log_level_list = std::vector<wxString>{_L("fatal"), _L("error"), _L("warning"), _L("info"), _L("debug"), _L("trace")};
auto loglevel_combox = create_item_loglevel_combobox(_L("Log Level"), this, _L("Log Level"), log_level_list);
auto loglevel_combox = create_item_loglevel_combobox(_L("Log Level"), m_scrolledWindow, _L("Log Level"), log_level_list);
auto title_host = create_item_title(_L("Host Setting"), this, _L("Host Setting"));
auto radio1 = create_item_radiobox(_L("DEV host: api-dev.bambu-lab.com/v1"), this, wxEmptyString, 50, 1, "dev_host");
auto radio2 = create_item_radiobox(_L("QA host: api-qa.bambu-lab.com/v1"), this, wxEmptyString, 50, 1, "qa_host");
auto radio3 = create_item_radiobox(_L("PRE host: api-pre.bambu-lab.com/v1"), this, wxEmptyString, 50, 1, "pre_host");
auto radio4 = create_item_radiobox(_L("Product host"), this, wxEmptyString, 50, 1, "product_host");
auto title_host = create_item_title(_L("Host Setting"), m_scrolledWindow, _L("Host Setting"));
auto radio1 = create_item_radiobox(_L("DEV host: api-dev.bambu-lab.com/v1"), m_scrolledWindow, wxEmptyString, 50, 1, "dev_host");
auto radio2 = create_item_radiobox(_L("QA host: api-qa.bambu-lab.com/v1"), m_scrolledWindow, wxEmptyString, 50, 1, "qa_host");
auto radio3 = create_item_radiobox(_L("PRE host: api-pre.bambu-lab.com/v1"), m_scrolledWindow, wxEmptyString, 50, 1, "pre_host");
auto radio4 = create_item_radiobox(_L("Product host"), m_scrolledWindow, wxEmptyString, 50, 1, "product_host");
if (m_iot_environment_def == ENV_DEV_HOST) {
on_select_radio("dev_host");
@ -806,7 +836,7 @@ wxBoxSizer* PreferencesDialog::create_debug_page()
on_select_radio("product_host");
}
wxButton *debug_button = new wxButton(this, wxID_ANY, _L("debug save button"), wxDefaultPosition, wxDefaultSize, 0);
wxButton *debug_button = new wxButton(m_scrolledWindow, wxID_ANY, _L("debug save button"), wxDefaultPosition, wxDefaultSize, 0);
debug_button->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) {
// success message box
MessageDialog dialog(this, _L("save debug settings"), _L("DEBUG settings have saved successfully!"), wxNO_DEFAULT | wxYES_NO | wxICON_INFORMATION);

View file

@ -60,6 +60,7 @@ private:
protected:
wxBoxSizer * m_sizer_body;
wxScrolledWindow *m_scrolledWindow;
// bool m_settings_layout_changed {false};
bool m_seq_top_layer_only_changed{false};

View file

@ -225,9 +225,14 @@ int PresetComboBox::update_ams_color()
if (m_filament_idx < 0) return -1;
int idx = selected_ams_filament();
if (idx < 0) return -1;
auto &ams_list = wxGetApp().preset_bundle->filament_ams_list;
if (idx >= ams_list.size()) {
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": ams %1% out of range %2%") % idx % ams_list.size();
return -1;
}
DynamicPrintConfig *cfg = &wxGetApp().preset_bundle->project_config;
auto colors = static_cast<ConfigOptionStrings*>(cfg->option("filament_colour")->clone());
colors->values[m_filament_idx] = wxGetApp().preset_bundle->filament_ams_list[idx]
colors->values[m_filament_idx] = ams_list[idx]
.opt_string("filament_colour", 0u);
DynamicPrintConfig new_cfg;
new_cfg.set_key_value("filament_colour", colors);
@ -397,7 +402,7 @@ void PresetComboBox::add_ams_filaments(std::string selected, bool alias_name)
} else {
img.SetRGB(wxRect({0, 0}, img.GetSize()), clr.Red(), clr.Green(), clr.Blue());
}
int item_id = Append(get_preset_name(*iter), img);
int item_id = Append(get_preset_name(*iter), img, &m_first_ams_filament + (&f - &m_preset_bundle->filament_ams_list.front()));
//validate_selection(id->value == selected); // can not select
}
m_last_ams_filament = GetCount();
@ -407,7 +412,7 @@ void PresetComboBox::add_ams_filaments(std::string selected, bool alias_name)
int PresetComboBox::selected_ams_filament() const
{
if (m_first_ams_filament && m_last_selected >= m_first_ams_filament && m_last_selected < m_last_ams_filament) {
return m_last_selected - m_first_ams_filament;
return reinterpret_cast<int *>(GetClientData(m_last_selected)) - &m_first_ams_filament;
}
return -1;
}
@ -609,7 +614,7 @@ bool PresetComboBox::selection_is_changed_according_to_physical_printers()
// ---------------------------------
PlaterPresetComboBox::PlaterPresetComboBox(wxWindow *parent, Preset::Type preset_type) :
PresetComboBox(parent, preset_type, wxSize(15 * wxGetApp().em_unit(), 3 * wxGetApp().em_unit()))
PresetComboBox(parent, preset_type, wxSize(15 * wxGetApp().em_unit(), 24 * wxGetApp().em_unit() / 10))
{
GetDropDown().SetUseContentWidth(true);
@ -892,10 +897,15 @@ void PlaterPresetComboBox::update()
// BBS
wxColor clr(filament_color);
clr_picker->SetBackgroundColour(clr);
auto style = clr_picker->GetWindowStyle() & ~(wxBORDER_NONE | wxBORDER_SIMPLE);
auto diff_clr = different_color(clr);
clr_picker->SetWindowStyle(clr.Red() > 224 && clr.Blue() > 224 && clr.Green() > 224 ? (style | wxBORDER_SIMPLE) : (style | wxBORDER_NONE));
clr_picker->SetForegroundColour(diff_clr);
auto style = clr_picker->GetWindowStyle() & ~(wxBORDER_NONE | wxBORDER_SIMPLE);
style = clr.Red() > 224 && clr.Blue() > 224 && clr.Green() > 224 ? (style | wxBORDER_SIMPLE) : (style | wxBORDER_NONE);
clr_picker->SetWindowStyle(style);
#ifdef __WXOSX__
clr_picker->SetLabel(clr_picker->GetLabel()); // Let setBezelStyle: be called
clr_picker->Refresh();
#endif
selected_filament_preset = m_collection->find_preset(m_preset_bundle->filament_presets[m_filament_idx]);
if (!selected_filament_preset) {
//can not find this filament, should be caused by project embedded presets, will be updated later
@ -1092,7 +1102,7 @@ void PlaterPresetComboBox::update()
void PlaterPresetComboBox::msw_rescale()
{
PresetComboBox::msw_rescale();
SetMinSize({-1, 3 * m_em_unit});
SetMinSize({-1, 24 * m_em_unit / 10});
if (clr_picker)
clr_picker->SetSize(20 * m_em_unit / 10, 20 * m_em_unit / 10);
@ -1322,7 +1332,7 @@ void TabPresetComboBox::update()
void TabPresetComboBox::msw_rescale()
{
PresetComboBox::msw_rescale();
PresetComboBox::Rescale();
// BBS: new layout
wxSize sz = wxSize(20 * m_em_unit, GetSize().GetHeight());
SetMinSize(sz);

View file

@ -0,0 +1,137 @@
#include "PrintOptionsDialog.hpp"
#include "I18N.hpp"
#include "libslic3r/Utils.hpp"
#define DLG_SIZE (wxSize(FromDIP(360), FromDIP(160)))
static const wxColour STATIC_BOX_LINE_COL = wxColour(238, 238, 238);
namespace Slic3r { namespace GUI {
PrintOptionsDialog::PrintOptionsDialog(wxWindow* parent)
: DPIDialog(parent, wxID_ANY, _L("Print Options"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX)
{
this->SetDoubleBuffered(true);
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);
this->SetMinSize(DLG_SIZE);
this->SetSize(DLG_SIZE);
auto m_options_sizer = create_settings_group(this);
this->SetSizer(m_options_sizer);
this->Layout();
m_options_sizer->Fit(this);
this->Fit();
m_cb_first_layer->Bind(wxEVT_TOGGLEBUTTON, [this](wxCommandEvent& evt) {
if (obj) {
obj->command_xcam_control_first_layer_inspector(m_cb_first_layer->GetValue(), false);
}
evt.Skip();
});
m_cb_spaghetti->Bind(wxEVT_TOGGLEBUTTON, [this](wxCommandEvent& evt) {
update_spaghetti();
if (obj) {
obj->command_xcam_control_spaghetti_detector(m_cb_spaghetti->GetValue(), m_cb_spaghetti_print_halt->GetValue());
}
evt.Skip();
});
m_cb_spaghetti_print_halt->Bind(wxEVT_TOGGLEBUTTON, [this](wxCommandEvent&evt) {
if (obj) {
obj->command_xcam_control_spaghetti_detector(m_cb_spaghetti->GetValue(), m_cb_spaghetti_print_halt->GetValue());
}
evt.Skip();
});
}
PrintOptionsDialog::~PrintOptionsDialog() {}
void PrintOptionsDialog::on_dpi_changed(const wxRect &suggested_rect)
{
this->SetMinSize(DLG_SIZE);
this->SetSize(DLG_SIZE);
Fit();
}
void PrintOptionsDialog::update_spaghetti()
{
if (m_cb_spaghetti->GetValue()) {
m_cb_spaghetti_print_halt->Enable();
text_spaghetti_print_halt->Enable();
}
else {
m_cb_spaghetti_print_halt->Disable();
text_spaghetti_print_halt->Disable();
}
}
void PrintOptionsDialog::update_options(MachineObject *obj_)
{
if (!obj_) return;
this->Freeze();
m_cb_spaghetti->SetValue(obj_->xcam_spaghetti_detector);
m_cb_spaghetti_print_halt->SetValue(obj_->xcam_spaghetti_print_halt);
m_cb_first_layer->SetValue(obj_->xcam_first_layer_inspector);
update_spaghetti();
this->Thaw();
}
wxBoxSizer* PrintOptionsDialog::create_settings_group(wxWindow* parent)
{
auto sizer = new wxBoxSizer(wxVERTICAL);
auto line_sizer = new wxBoxSizer(wxHORIZONTAL);
m_cb_spaghetti = new CheckBox(parent);
auto text_spaghetti = new wxStaticText(parent, wxID_ANY, _L("Spaghetti Detection"));
text_spaghetti->SetFont(Label::Body_14);
line_sizer->Add(FromDIP(5), 0, 0, 0);
line_sizer->Add(m_cb_spaghetti, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5));
line_sizer->Add(text_spaghetti, 1, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5));
sizer->Add(line_sizer, 0, wxEXPAND | wxALL, FromDIP(5));
line_sizer = new wxBoxSizer(wxHORIZONTAL);
m_cb_spaghetti_print_halt = new CheckBox(parent);
text_spaghetti_print_halt = new wxStaticText(parent, wxID_ANY, _L("Stop printing when spaghetti detected"));
text_spaghetti_print_halt->SetFont(Label::Body_14);
line_sizer->Add(FromDIP(30), 0, 0, 0);
line_sizer->Add(m_cb_spaghetti_print_halt, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5));
line_sizer->Add(text_spaghetti_print_halt, 1, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5));
sizer->Add(line_sizer, 0, wxEXPAND | wxALL , 0);
sizer->Add(0, FromDIP(10), 0, 0);
StaticLine* line = new StaticLine(parent, false);
line->SetLineColour(STATIC_BOX_LINE_COL);
sizer->Add(line, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(20));
line_sizer = new wxBoxSizer(wxHORIZONTAL);
m_cb_first_layer = new CheckBox(parent);
auto text_first_layer = new wxStaticText(parent, wxID_ANY, _L("First Layer Inspection"));
text_first_layer->SetFont(Label::Body_14);
line_sizer->Add(FromDIP(5), 0, 0, 0);
line_sizer->Add(m_cb_first_layer, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5));
line_sizer->Add(text_first_layer, 1, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5));
sizer->Add(line_sizer, 1, wxEXPAND | wxALL, FromDIP(5));
line_sizer->Add(FromDIP(5), 0, 0, 0);
return sizer;
}
void PrintOptionsDialog::update_machine_obj(MachineObject *obj_)
{
obj = obj_;
}
bool PrintOptionsDialog::Show(bool show)
{
if (show) { CentreOnParent(); }
return DPIDialog::Show(show);
}
}} // namespace Slic3r::GUI

View file

@ -0,0 +1,47 @@
#ifndef slic3r_GUI_PrintOptionsDialog_hpp_
#define slic3r_GUI_PrintOptionsDialog_hpp_
#include <wx/wx.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/string.h>
#include <wx/sizer.h>
#include <wx/dialog.h>
#include "GUI_Utils.hpp"
#include "wxExtensions.hpp"
#include "DeviceManager.hpp"
#include "Widgets/Label.hpp"
#include "Widgets/CheckBox.hpp"
#include "Widgets/StaticLine.hpp"
namespace Slic3r { namespace GUI {
class PrintOptionsDialog : public DPIDialog
{
protected:
// settings
CheckBox* m_cb_first_layer;
CheckBox* m_cb_spaghetti;
CheckBox* m_cb_spaghetti_print_halt;
wxStaticText* text_spaghetti_print_halt;
wxBoxSizer* create_settings_group(wxWindow* parent);
public:
PrintOptionsDialog(wxWindow* parent);
~PrintOptionsDialog();
void on_dpi_changed(const wxRect &suggested_rect) override;
void update_spaghetti();
MachineObject *obj { nullptr };
std::vector<int> last_stage_list_info;
int m_state{0};
void update_options(MachineObject *obj_);
void update_machine_obj(MachineObject *obj_);
bool Show(bool show) override;
};
}} // namespace Slic3r::GUI
#endif

View file

@ -28,8 +28,14 @@ void ProjectDirtyStateManager::update_from_presets()
// check switching of the presets only for exist/loaded project, but not for new
GUI_App &app = wxGetApp();
if (!app.plater()->get_project_filename().IsEmpty()) {
for (const auto& [type, name] : app.get_selected_presets())
m_presets_dirty |= !m_initial_presets[type].empty() && m_initial_presets[type] != name;
for (const auto &[type, name] : app.get_selected_presets()) {
if (type == Preset::Type::TYPE_FILAMENT) {
m_presets_dirty |= m_initial_filament_presets != wxGetApp().preset_bundle->filament_presets;
} else {
m_presets_dirty |= !m_initial_presets[type].empty() && m_initial_presets[type] != name;
}
}
}
m_presets_dirty |= app.has_unsaved_preset_changes();
m_project_config_dirty = m_initial_project_config != app.preset_bundle->project_config;
@ -49,8 +55,13 @@ void ProjectDirtyStateManager::reset_initial_presets()
{
m_initial_presets.fill(std::string{});
GUI_App &app = wxGetApp();
for (const auto& [type, name] : app.get_selected_presets())
m_initial_presets[type] = name;
for (const auto &[type, name] : app.get_selected_presets()) {
if (type == Preset::Type::TYPE_FILAMENT) {
m_initial_filament_presets = wxGetApp().preset_bundle->filament_presets;
} else {
m_initial_presets[type] = name;
}
}
m_initial_project_config = app.preset_bundle->project_config;
}

View file

@ -31,6 +31,9 @@ private:
// Keeps track of preset names selected at the time of last project save.
std::array<std::string, Preset::TYPE_COUNT> m_initial_presets;
DynamicPrintConfig m_initial_project_config;
// filament preset independent of the m_initial_presets
std::vector<std::string> m_initial_filament_presets;
};
} // namespace GUI

View file

@ -340,7 +340,7 @@ void SavePresetDialog::build(std::vector<Preset::Type> types, std::string suffix
m_confirm->SetTextColor(wxColour(255, 255, 255));
m_confirm->SetMinSize(SAVE_PRESET_DIALOG_BUTTON_SIZE);
m_confirm->SetCornerRadius(12);
m_confirm->Bind(wxEVT_LEFT_DOWN, &SavePresetDialog::accept, this);
m_confirm->Bind(wxEVT_BUTTON, &SavePresetDialog::accept, this);
btns->Add(m_confirm, 0, wxEXPAND, 0);
auto block_middle = new wxWindow(this, -1);
@ -351,7 +351,7 @@ void SavePresetDialog::build(std::vector<Preset::Type> types, std::string suffix
m_cancel->SetMinSize(SAVE_PRESET_DIALOG_BUTTON_SIZE);
m_cancel->SetTextColor(wxColour(107, 107, 107));
m_cancel->SetCornerRadius(12);
m_cancel->Bind(wxEVT_LEFT_DOWN, &SavePresetDialog::on_select_cancel, this);
m_cancel->Bind(wxEVT_BUTTON, &SavePresetDialog::on_select_cancel, this);
btns->Add(m_cancel, 0, wxEXPAND, 0);
auto block_right = new wxWindow(this, -1);
@ -372,7 +372,7 @@ void SavePresetDialog::build(std::vector<Preset::Type> types, std::string suffix
this->Centre(wxBOTH);
}
void SavePresetDialog::on_select_cancel(wxMouseEvent &event)
void SavePresetDialog::on_select_cancel(wxCommandEvent &event)
{
EndModal(wxID_CANCEL);
}
@ -511,7 +511,7 @@ void SavePresetDialog::update_physical_printers(const std::string &preset_name)
}
}
void SavePresetDialog::accept(wxMouseEvent &event)
void SavePresetDialog::accept(wxCommandEvent &event)
{
for (Item *item : m_items) {
item->accept();

View file

@ -111,9 +111,9 @@ protected:
private:
void build(std::vector<Preset::Type> types, std::string suffix = "");
void on_select_cancel(wxMouseEvent &event);
void on_select_cancel(wxCommandEvent &event);
void update_physical_printers(const std::string &preset_name);
void accept(wxMouseEvent &event);
void accept(wxCommandEvent &event);
};
} // namespace GUI

View file

@ -102,15 +102,15 @@ MachineObjectPanel::MachineObjectPanel(wxWindow *parent, wxWindowID id, const wx
SetBackgroundColour(*wxWHITE);
m_unbind_img = create_scaled_bitmap("unbind", nullptr, 18);
m_edit_name_img = create_scaled_bitmap("edit_button", nullptr, 18);
m_select_unbind_img = create_scaled_bitmap("unbind_selected", nullptr, 18);
m_unbind_img = ScalableBitmap(this, "unbind", 18);
m_edit_name_img = ScalableBitmap(this, "edit_button", 18);
m_select_unbind_img = ScalableBitmap(this, "unbind_selected", 18);
m_printer_status_offline = create_scaled_bitmap("printer_status_offline", nullptr, 12);
m_printer_status_busy = create_scaled_bitmap("printer_status_busy", nullptr, 12);
m_printer_status_idle = create_scaled_bitmap("printer_status_idle", nullptr, 12);
m_printer_status_lock = create_scaled_bitmap("printer_status_lock", nullptr, 16);
m_printer_in_lan = create_scaled_bitmap("printer_in_lan", nullptr, 16);
m_printer_status_offline = ScalableBitmap(this, "printer_status_offline", 12);
m_printer_status_busy = ScalableBitmap(this, "printer_status_busy", 12);
m_printer_status_idle = ScalableBitmap(this, "printer_status_idle", 12);
m_printer_status_lock = ScalableBitmap(this, "printer_status_lock", 16);
m_printer_in_lan = ScalableBitmap(this, "printer_in_lan", 16);
this->Bind(wxEVT_ENTER_WINDOW, &MachineObjectPanel::on_mouse_enter, this);
this->Bind(wxEVT_LEAVE_WINDOW, &MachineObjectPanel::on_mouse_leave, this);
@ -188,9 +188,9 @@ void MachineObjectPanel::doRender(wxDC &dc)
if (m_state == PrinterState::IN_LAN) { dwbitmap = m_printer_in_lan; }
// dc.DrawCircle(left, size.y / 2, 3);
dc.DrawBitmap(dwbitmap, wxPoint(left, (size.y - dwbitmap.GetSize().y) / 2));
dc.DrawBitmap(dwbitmap.bmp(), wxPoint(left, (size.y - dwbitmap.GetBmpSize().y) / 2));
left += dwbitmap.GetSize().x + 8;
left += dwbitmap.GetBmpSize().x + 8;
dc.SetFont(Label::Body_13);
dc.SetBackgroundMode(wxTRANSPARENT);
dc.SetTextForeground(SELECT_MACHINE_GREY900);
@ -199,7 +199,7 @@ void MachineObjectPanel::doRender(wxDC &dc)
dev_name = from_u8(m_info->dev_name);
}
auto sizet = dc.GetTextExtent(dev_name);
auto text_end = size.x - m_unbind_img.GetSize().x - 30;
auto text_end = size.x - m_unbind_img.GetBmpSize().x - 30;
wxString finally_name = dev_name;
if (sizet.x > (text_end - left)) {
auto limit_width = text_end - left - dc.GetTextExtent("...").x - 15;
@ -221,13 +221,14 @@ void MachineObjectPanel::doRender(wxDC &dc)
if (m_show_bind) {
if (m_bind_state == ALLOW_UNBIND) {
left = size.x - m_unbind_img.GetSize().x - 6;
dc.DrawBitmap(m_select_unbind_img, left, (size.y - m_unbind_img.GetSize().y) / 2); }
left = size.x - m_unbind_img.GetBmpSize().x - 6;
dc.DrawBitmap(m_select_unbind_img.bmp(), left, (size.y - m_unbind_img.GetBmpSize().y) / 2);
}
}
if (m_show_edit) {
left = size.x - m_unbind_img.GetSize().x - 6 - m_edit_name_img.GetSize().x - 6;
dc.DrawBitmap(m_edit_name_img, left, (size.y - m_edit_name_img.GetSize().y) / 2);
left = size.x - m_unbind_img.GetBmpSize().x - 6 - m_edit_name_img.GetBmpSize().x - 6;
dc.DrawBitmap(m_edit_name_img.bmp(), left, (size.y - m_edit_name_img.GetBmpSize().y) / 2);
}
}
}
@ -256,10 +257,10 @@ void MachineObjectPanel::on_mouse_left_up(wxMouseEvent &evt)
if (m_is_my_devices) {
// show edit
if (m_show_edit) {
auto edit_left = GetSize().x - m_unbind_img.GetSize().x - 6 - m_edit_name_img.GetSize().x - 6;
auto edit_right = edit_left + m_edit_name_img.GetSize().x;
auto edit_top = (GetSize().y - m_edit_name_img.GetSize().y) / 2;
auto edit_bottom = (GetSize().y - m_edit_name_img.GetSize().y) / 2 + m_edit_name_img.GetSize().y;
auto edit_left = GetSize().x - m_unbind_img.GetBmpSize().x - 6 - m_edit_name_img.GetBmpSize().x - 6;
auto edit_right = edit_left + m_edit_name_img.GetBmpSize().x;
auto edit_top = (GetSize().y - m_edit_name_img.GetBmpSize().y) / 2;
auto edit_bottom = (GetSize().y - m_edit_name_img.GetBmpSize().y) / 2 + m_edit_name_img.GetBmpSize().y;
if ((evt.GetPosition().x >= edit_left && evt.GetPosition().x <= edit_right) && evt.GetPosition().y >= edit_top && evt.GetPosition().y <= edit_bottom) {
wxCommandEvent event(EVT_EDIT_PRINT_NAME);
event.SetEventObject(this);
@ -268,10 +269,10 @@ void MachineObjectPanel::on_mouse_left_up(wxMouseEvent &evt)
}
}
if (m_show_bind) {
auto left = GetSize().x - m_unbind_img.GetSize().x - 6;
auto right = left + m_unbind_img.GetSize().x;
auto top = (GetSize().y - m_unbind_img.GetSize().y) / 2;
auto bottom = (GetSize().y - m_unbind_img.GetSize().y) / 2 + m_unbind_img.GetSize().y;
auto left = GetSize().x - m_unbind_img.GetBmpSize().x - 6;
auto right = left + m_unbind_img.GetBmpSize().x;
auto top = (GetSize().y - m_unbind_img.GetBmpSize().y) / 2;
auto bottom = (GetSize().y - m_unbind_img.GetBmpSize().y) / 2 + m_unbind_img.GetBmpSize().y;
if ((evt.GetPosition().x >= left && evt.GetPosition().x <= right) && evt.GetPosition().y >= top && evt.GetPosition().y <= bottom) {
wxCommandEvent event(EVT_UNBIND_MACHINE, GetId());
@ -742,6 +743,26 @@ void SelectMachineDialog::stripWhiteSpace(std::string& str)
}
}
wxString SelectMachineDialog::format_text(wxString &m_msg)
{
if (wxGetApp().app_config->get("language") != "zh_CN") {return m_msg; }
wxString out_txt = m_msg;
wxString count_txt = "";
int new_line_pos = 0;
for (int i = 0; i < m_msg.length(); i++) {
auto text_size = m_statictext_ams_msg->GetTextExtent(count_txt);
if (text_size.x < (FromDIP(400))) {
count_txt += m_msg[i];
} else {
out_txt.insert(i - 1, '\n');
count_txt = "";
}
}
return out_txt;
}
SelectMachineDialog::SelectMachineDialog(Plater *plater)
: DPIDialog(static_cast<wxWindow *>(wxGetApp().mainframe), wxID_ANY, _L("Send print job to"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX)
, m_plater(plater), m_export_3mf_cancel(false)
@ -1014,6 +1035,13 @@ void SelectMachineDialog::update_select_layout(PRINTER_TYPE type)
void SelectMachineDialog::prepare_mode()
{
m_is_in_sending_mode = false;
if (m_print_job) {
m_print_job->join();
}
wxEndBusyCursor();
Enable_Send_Button(true);
m_status_bar->reset();
if (m_simplebook->GetSelection() != 0) {
m_simplebook->SetSelection(0);
@ -1024,6 +1052,7 @@ void SelectMachineDialog::prepare_mode()
void SelectMachineDialog::sending_mode()
{
m_is_in_sending_mode = true;
if (m_simplebook->GetSelection() != 1){
m_simplebook->SetSelection(1);
Layout();
@ -1033,6 +1062,7 @@ void SelectMachineDialog::sending_mode()
void SelectMachineDialog::finish_mode()
{
m_is_in_sending_mode = false;
m_simplebook->SetSelection(2);
Layout();
Fit();
@ -1064,7 +1094,7 @@ void SelectMachineDialog::sync_ams_mapping_result(std::vector<FilamentInfo> &res
ams_col = AmsTray::decode_color(f->color);
} else {
// default color
ams_col = wxColour(0xEE, 0xEE, 0xEE);
ams_col = wxColour(0xCE, 0xCE, 0xCE);
}
m->set_ams_info(ams_col, ams_id);
@ -1109,8 +1139,8 @@ bool SelectMachineDialog::do_ams_mapping(MachineObject *obj_)
} else {
// do not support ams mapping try to use order mapping
bool is_valid = obj_->is_valid_mapping_result(m_ams_mapping_result);
if (!is_valid) {
// reset invalid result
if (result != 1 && !is_valid) {
//reset invalid result
for (int i = 0; i < m_ams_mapping_result.size(); i++) {
m_ams_mapping_result[i].tray_id = -1;
m_ams_mapping_result[i].distance = 99999;
@ -1174,6 +1204,8 @@ void SelectMachineDialog::update_ams_status_msg(wxString msg, bool is_warning)
Fit();
}
} else {
msg = format_text(msg);
auto str_new = msg.ToStdString();
stripWhiteSpace(str_new);
@ -1207,6 +1239,8 @@ void SelectMachineDialog::update_priner_status_msg(wxString msg, bool is_warning
Fit();
}
} else {
msg = format_text(msg);
auto str_new = msg.ToStdString();
stripWhiteSpace(str_new);
@ -1238,7 +1272,7 @@ void SelectMachineDialog::update_print_status_msg(wxString msg, bool is_warning,
}
}
void SelectMachineDialog::show_status(PrintDialogStatus status)
void SelectMachineDialog::show_status(PrintDialogStatus status, std::vector<wxString> params)
{
if (m_print_status != status)
BOOST_LOG_TRIVIAL(info) << "select_machine_dialog: show_status = " << status;
@ -1306,7 +1340,11 @@ void SelectMachineDialog::show_status(PrintDialogStatus status)
Enable_Send_Button(false);
Enable_Refresh_Button(true);
} else if (status == PrintDialogStatus::PrintStatusNeedUpgradingAms) {
wxString msg_text = _L("The filament index exceeds the AMS's slot count and cannot send the print job.");
wxString msg_text;
if (params.size() > 0)
msg_text = wxString::Format(_L("Filament %s exceeds the number of AMS slots. Please update the printer firmware to support AMS slot assignment."), params[0]);
else
msg_text = _L("Filament exceeds the number of AMS slots. Please update the printer firmware to support AMS slot assignment.");
update_print_status_msg(msg_text, true, false);
Enable_Send_Button(false);
Enable_Refresh_Button(true);
@ -1320,6 +1358,15 @@ void SelectMachineDialog::show_status(PrintDialogStatus status)
update_print_status_msg(msg_text, true, false);
Enable_Send_Button(false);
Enable_Refresh_Button(true);
} else if (status == PrintDialogStatus::PrintStatusAmsMappingU0Invalid) {
wxString msg_text;
if (params.size() > 1)
msg_text = wxString::Format(_L("Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment."), params[0], params[1]);
else
msg_text = _L("Filament does not match the filament in AMS slot. Please update the printer firmware to support AMS slot assignment.");
update_print_status_msg(msg_text, true, false);
Enable_Send_Button(false);
Enable_Refresh_Button(true);
} else if (status == PrintDialogStatus::PrintStatusAmsMappingValid) {
update_print_status_msg(wxEmptyString, false, false);
Enable_Send_Button(true);
@ -1392,6 +1439,12 @@ void SelectMachineDialog::on_cancel(wxCloseEvent &event)
void SelectMachineDialog::on_ok(wxCommandEvent &event)
{
BOOST_LOG_TRIVIAL(info) << "print_job: on_ok to send";
m_is_canceled = false;
Enable_Send_Button(false);
if (m_is_in_sending_mode)
return;
int result = 0;
if (m_printer_last_select.empty()) {
return;
@ -1406,31 +1459,55 @@ void SelectMachineDialog::on_ok(wxCommandEvent &event)
return;
}
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "for send task, current printer id = " << m_printer_last_select << std::endl;
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", print_job: for send task, current printer id = " << m_printer_last_select << std::endl;
show_status(PrintDialogStatus::PrintStatusSending);
m_status_bar->reset();
m_status_bar->set_prog_block();
m_status_bar->set_cancel_callback_fina([this]() {
BOOST_LOG_TRIVIAL(info) << "print_job: enter canceled";
if (m_print_job) {
if (m_print_job->is_running()) {
BOOST_LOG_TRIVIAL(info) << "print_job: canceled";
m_print_job->cancel();
}
m_print_job->join();
}
m_is_canceled = true;
wxCommandEvent* event = new wxCommandEvent(EVT_PRINT_JOB_CANCEL);
wxQueueEvent(this, event);
});
if (m_is_canceled) {
BOOST_LOG_TRIVIAL(info) << "print_job: m_is_canceled";
m_status_bar->set_status_text(task_canceled_text);
return;
}
// enter sending mode
sending_mode();
// get ams_mapping_result
std::string ams_mapping_array;
get_ams_mapping_result(ams_mapping_array);
result = m_plater->send_gcode(m_print_plate_idx, [this](int export_stage, int current, int total, bool &cancel) {
if (this->m_is_canceled) return;
bool cancelled = false;
wxString msg = _L("Preparing print job");
m_status_bar->update_status(msg, cancelled, 10, true);
m_export_3mf_cancel = cancel = cancelled;
});
if (result < 0) {
wxString msg = _L("Abnormal print file data. Please slice again");
m_status_bar->set_status_text(msg);
if (m_is_canceled || m_export_3mf_cancel) {
BOOST_LOG_TRIVIAL(info) << "print_job: m_export_3mf_cancel or m_is_canceled";
m_status_bar->set_status_text(task_canceled_text);
return;
}
if (m_export_3mf_cancel) {
m_status_bar->set_status_text(task_canceled_text);
if (result < 0) {
wxString msg = _L("Abnormal print file data. Please slice again");
m_status_bar->set_status_text(msg);
return;
}
@ -1442,6 +1519,11 @@ void SelectMachineDialog::on_ok(wxCommandEvent &event)
return;
}
}
if (m_is_canceled || m_export_3mf_cancel) {
BOOST_LOG_TRIVIAL(info) << "print_job: m_export_3mf_cancel or m_is_canceled";
m_status_bar->set_status_text(task_canceled_text);
return;
}
m_print_job = std::make_shared<PrintJob>(m_status_bar, m_plater, m_printer_last_select);
m_print_job->m_dev_ip = obj_->dev_ip;
@ -1468,14 +1550,9 @@ void SelectMachineDialog::on_ok(wxCommandEvent &event)
m_print_job->on_success([this]() { finish_mode(); });
m_status_bar->set_cancel_callback_fina([this]() {
m_print_job->cancel();
wxCommandEvent *event = new wxCommandEvent(EVT_PRINT_JOB_CANCEL);
wxQueueEvent(this, event);
});
wxCommandEvent evt(m_plater->get_print_finished_event());
m_print_job->start();
BOOST_LOG_TRIVIAL(info) << "print_job: start print job";
}
void SelectMachineDialog::update_user_machine_list()
@ -1542,8 +1619,10 @@ void SelectMachineDialog::on_set_finish_mapping(wxCommandEvent &evt)
void SelectMachineDialog::on_print_job_cancel(wxCommandEvent &evt)
{
if (m_print_job->is_running()) { m_print_job->join(5 * 1000); }
BOOST_LOG_TRIVIAL(info) << "print_job: canceled";
show_status(PrintDialogStatus::PrintStatusSendingCanceled);
// enter prepare mode
prepare_mode();
}
std::vector<std::string> SelectMachineDialog::sort_string(std::vector<std::string> strArray)
@ -1682,6 +1761,7 @@ void SelectMachineDialog::on_selection_changed(wxCommandEvent &event)
}
if (obj) {
obj->command_get_version();
dev->set_selected_machine(m_printer_last_select);
update_select_layout(obj->printer_type);
} else {
@ -1782,10 +1862,29 @@ void SelectMachineDialog::update_show_status()
}
if (!obj_->is_support_ams_mapping()) {
if (obj_->is_valid_mapping_result(m_ams_mapping_result)) {
show_status(PrintDialogStatus::PrintStatusAmsMappingByOrder);
int exceed_index = -1;
if (obj_->is_mapping_exceed_filament(m_ams_mapping_result, exceed_index)) {
std::vector<wxString> params;
params.push_back(wxString::Format("%02d", exceed_index+1));
show_status(PrintDialogStatus::PrintStatusNeedUpgradingAms, params);
} else {
show_status(PrintDialogStatus::PrintStatusNeedUpgradingAms);
if (obj_->is_valid_mapping_result(m_ams_mapping_result)) {
show_status(PrintDialogStatus::PrintStatusAmsMappingByOrder);
} else {
int mismatch_index = -1;
for (int i = 0; i < m_ams_mapping_result.size(); i++) {
if (m_ams_mapping_result[i].mapping_result == MappingResult::MAPPING_RESULT_TYPE_MISMATCH) {
mismatch_index = m_ams_mapping_result[i].id;
break;
}
}
std::vector<wxString> params;
if (mismatch_index >= 0) {
params.push_back(wxString::Format("%02d", mismatch_index+1));
params.push_back(wxString::Format("%02d", mismatch_index+1));
}
show_status(PrintDialogStatus::PrintStatusAmsMappingU0Invalid, params);
}
}
return;
}
@ -1926,12 +2025,16 @@ void SelectMachineDialog::set_default()
//sizer_thumbnail->Layout();
std::vector<std::string> materials;
std::vector<std::string> display_materials;
{
auto preset_bundle = wxGetApp().preset_bundle;
for (auto filament_name : preset_bundle->filament_presets) {
for (auto iter = preset_bundle->filaments.lbegin(); iter != preset_bundle->filaments.end(); iter++) {
if (filament_name.compare(iter->name) == 0) {
materials.push_back(iter->config.get_filament_type());
std::string display_filament_type;
std::string filament_type = iter->config.get_filament_type(display_filament_type);
display_materials.push_back(display_filament_type);
materials.push_back(filament_type);
}
}
}
@ -1962,9 +2065,9 @@ void SelectMachineDialog::set_default()
bmcache.parse_color(colour, rgb);
auto colour_rgb = wxColour((int) rgb[0], (int) rgb[1], (int) rgb[2]);
if (extruder >= materials.size() || extruder < 0)
if (extruder >= materials.size() || extruder < 0 || extruder >= display_materials.size())
continue;
MaterialItem *item = new MaterialItem(this, colour_rgb, _L(materials[extruder]));
MaterialItem *item = new MaterialItem(this, colour_rgb, _L(display_materials[extruder]));
m_sizer_material->Add(item, 0, wxALL, FromDIP(4));
item->Bind(wxEVT_LEFT_UP, [this, item, materials, extruder](wxMouseEvent &e) {
@ -2000,8 +2103,8 @@ void SelectMachineDialog::set_default()
if (obj_ && obj_->has_ams()) {
m_mapping_popup.set_current_filament_id(extruder);
m_mapping_popup.update_ams_data(obj_->amsList);
m_mapping_popup.set_tag_texture(materials[extruder]);
m_mapping_popup.update_ams_data(obj_->amsList);
m_mapping_popup.Popup();
}
}

View file

@ -114,20 +114,19 @@ private:
PrinterBindState m_bind_state;
PrinterState m_state;
wxBitmap m_unbind_img;
wxBitmap m_edit_name_img;
wxBitmap m_select_unbind_img;
ScalableBitmap m_unbind_img;
ScalableBitmap m_edit_name_img;
ScalableBitmap m_select_unbind_img;
wxBitmap m_printer_status_offline;
wxBitmap m_printer_status_busy;
wxBitmap m_printer_status_idle;
wxBitmap m_printer_status_lock;
wxBitmap m_printer_in_lan;
ScalableBitmap m_printer_status_offline;
ScalableBitmap m_printer_status_busy;
ScalableBitmap m_printer_status_idle;
ScalableBitmap m_printer_status_lock;
ScalableBitmap m_printer_in_lan;
MachineObject *m_info;
protected:
wxBitmap m_bitmap_type;
wxStaticBitmap *m_bitmap_info;
wxStaticBitmap *m_bitmap_bind;
@ -238,6 +237,7 @@ enum PrintDialogStatus {
PrintStatusInPrinting,
PrintStatusAmsMappingSuccess,
PrintStatusAmsMappingInvalid,
PrintStatusAmsMappingU0Invalid,
PrintStatusAmsMappingValid,
PrintStatusAmsMappingByOrder,
PrintStatusRefreshingMachineList,
@ -298,6 +298,7 @@ protected:
StateColor btn_bg_enable;
int m_current_filament_id;
bool m_is_in_sending_mode { false };
wxGridSizer *m_sizer_select;
wxBoxSizer * sizer_thumbnail;
@ -310,7 +311,8 @@ protected:
void stripWhiteSpace(std::string& str);
void update_ams_status_msg(wxString msg, bool is_warning = false);
wxString format_text(wxString &m_msg);
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);
@ -328,7 +330,7 @@ public:
bool do_ams_mapping(MachineObject *obj_);
bool get_ams_mapping_result(std::string &mapping_array_str);
void prepare(int print_plate_idx);
void show_status(PrintDialogStatus status);
void show_status(PrintDialogStatus status, std::vector<wxString> params = std::vector<wxString>());
PrintDialogStatus get_status() { return m_print_status; }
bool Show(bool show);
@ -337,6 +339,7 @@ public:
wxObjectDataPtr<MachineListModel> machine_model;
std::shared_ptr<BBLStatusBarSend> m_status_bar;
bool m_export_3mf_cancel{false};
bool m_is_canceled { false };
protected:
std::vector<MachineObject *> m_list;

View file

@ -226,6 +226,7 @@ private:
// BBS
EMode m_volume_selection_mode{ Instance };
bool m_volume_selection_locked { false };
public:
Selection();
@ -343,7 +344,10 @@ public:
void translate(unsigned int object_idx, unsigned int instance_idx, const Vec3d& displacement);
//BBS: add partplate related logic
void notify_instance_update(int object_idx, int instance_idx);
void set_volume_selection_mode(EMode mode) { m_volume_selection_mode = mode; }
// BBS
void set_volume_selection_mode(EMode mode) { if (!m_volume_selection_locked) m_volume_selection_mode = mode; }
void lock_volume_selection_mode() { m_volume_selection_locked = true; }
void unlock_volume_selection_mode() { m_volume_selection_locked = false; }
void erase();

View file

@ -7,6 +7,10 @@
#include "BitmapCache.hpp"
#include "GUI_App.hpp"
#include "slic3r/Utils/Http.hpp"
#include "libslic3r/Thread.hpp"
namespace Slic3r { namespace GUI {
#define TEMP_THRESHOLD_VAL 2
@ -105,6 +109,7 @@ StatusBasePanel::StatusBasePanel(wxWindow *parent, wxWindowID id, const wxPoint
m_project_task_panel = new wxPanel(this);
m_project_task_panel->SetBackgroundColour(*wxWHITE);
auto m_project_task_sizer = create_project_task_page(m_project_task_panel);
m_project_task_panel->SetSizer(m_project_task_sizer);
m_project_task_panel->Layout();
@ -145,7 +150,6 @@ StatusBasePanel::StatusBasePanel(wxWindow *parent, wxWindowID id, const wxPoint
m_panel_separotor_bottom->SetBackgroundColour(STATUS_PANEL_BG);
bSizer_status->Add(m_panel_separotor_bottom, 0, wxEXPAND | wxALL, 0);
this->SetSizerAndFit(bSizer_status);
this->Layout();
}
@ -159,15 +163,15 @@ void StatusBasePanel::init_bitmaps()
m_bitmap_item_prediction = create_scaled_bitmap("monitor_item_prediction", nullptr, 16);
m_bitmap_item_cost = create_scaled_bitmap("monitor_item_cost", nullptr, 16);
m_bitmap_item_print = create_scaled_bitmap("monitor_item_print", nullptr, 18);
m_bitmap_axis_home = create_scaled_bitmap("monitor_axis_home", nullptr, 32);
m_bitmap_lamp_on = create_scaled_bitmap("monitor_lamp_on", nullptr, 24);
m_bitmap_lamp_off = create_scaled_bitmap("monitor_lamp_off", nullptr, 24);
m_bitmap_fan_on = create_scaled_bitmap("monitor_fan_on", nullptr, 24);
m_bitmap_fan_off = create_scaled_bitmap("monitor_fan_off", nullptr, 24);
m_bitmap_speed = create_scaled_bitmap("monitor_speed", nullptr, 24);
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_axis_home = ScalableBitmap(this, "monitor_axis_home", 32);
m_bitmap_lamp_on = ScalableBitmap(this, "monitor_lamp_on", 24);
m_bitmap_lamp_off = ScalableBitmap(this, "monitor_lamp_off", 24);
m_bitmap_fan_on = ScalableBitmap(this, "monitor_fan_on", 24);
m_bitmap_fan_off = ScalableBitmap(this, "monitor_fan_off", 24);
m_bitmap_speed = ScalableBitmap(this, "monitor_speed", 24);
m_bitmap_speed_active = ScalableBitmap(this, "monitor_speed_active", 24);
m_thumbnail_placeholder = ScalableBitmap(this, "monitor_placeholder", 120);
m_thumbnail_sdcard = ScalableBitmap(this, "monitor_sdcard_thumbnail", 120);
//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);
@ -278,7 +282,7 @@ wxBoxSizer *StatusBasePanel::create_project_task_page(wxWindow *parent)
m_printing_sizer = new wxBoxSizer(wxHORIZONTAL);
m_printing_sizer->SetMinSize(wxSize(PAGE_MIN_WIDTH, -1));
m_bitmap_thumbnail = new wxStaticBitmap(parent, wxID_ANY, m_thumbnail_placeholder, wxDefaultPosition, TASK_THUMBNAIL_SIZE, 0);
m_bitmap_thumbnail = new wxStaticBitmap(parent, wxID_ANY, m_thumbnail_placeholder.bmp(), wxDefaultPosition, TASK_THUMBNAIL_SIZE, 0);
m_printing_sizer->Add(m_bitmap_thumbnail, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxLEFT, FromDIP(12));
@ -392,14 +396,11 @@ wxBoxSizer *StatusBasePanel::create_project_task_page(wxWindow *parent)
m_staticText_progress_percent->SetFont(::Label::Head_13);
m_staticText_progress_percent->SetForegroundColour(wxColour(0, 174, 66));
m_staticText_progress_left = new wxStaticText(penel_text, wxID_ANY, _L("N/A"), wxDefaultPosition, wxDefaultSize, 0);
m_staticText_progress_left->Wrap(-1);
m_staticText_progress_left->SetFont(wxFont(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxT("HarmonyOS Sans SC")));
m_staticText_progress_left->SetForegroundColour(wxColour(146, 146, 146));
//fgSizer_task->Add(bSizer_buttons, 0, wxEXPAND, 0);
//fgSizer_task->Add(0, 0, 0, wxEXPAND, FromDIP(5));
@ -417,7 +418,6 @@ wxBoxSizer *StatusBasePanel::create_project_task_page(wxWindow *parent)
penel_text->SetSizer(bSizer_text);
penel_text->Layout();
bSizer_buttons->Add(penel_text, 1, wxEXPAND | wxALL, 0);
bSizer_buttons->Add(panel_button_block, 0, wxALIGN_CENTER | wxALL, 0);
@ -431,6 +431,37 @@ wxBoxSizer *StatusBasePanel::create_project_task_page(wxWindow *parent)
sizer->Add(m_printing_sizer, 0, wxEXPAND | wxALL, 0);
m_staticline = new wxPanel( parent, wxID_ANY);
m_staticline->SetBackgroundColour(wxColour(238,238,238));
m_staticline->Layout();
m_staticline->Hide();
sizer->Add(0, 0, 0, wxTOP, FromDIP(15));
sizer->Add(m_staticline, 0, wxEXPAND|wxALL, FromDIP(10));
m_panel_error_txt = new wxPanel(parent, wxID_ANY);
m_panel_error_txt->SetBackgroundColour(*wxWHITE);
wxBoxSizer *static_text_sizer = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *text_sizer = new wxBoxSizer(wxHORIZONTAL);
m_error_text = new wxStaticText2(m_panel_error_txt);
m_error_text->SetForegroundColour(PAGE_TITLE_FONT_COL);
text_sizer->Add(m_error_text, 1, wxEXPAND|wxLEFT, FromDIP(17));
m_button_clean = new Button(m_panel_error_txt, _L("Clean"));
m_button_clean->SetBackgroundColor(abort_bg);
m_button_clean->SetBorderColor(abort_bd);
m_button_clean->SetTextColor(abort_text);
m_button_clean->SetFont(Label::Body_10);
m_button_clean->SetMinSize(TASK_BUTTON_SIZE2);
static_text_sizer->Add(text_sizer, 1, wxEXPAND|wxTOP, FromDIP(7));
static_text_sizer->Add( FromDIP(10), 0, 0, 0, 0 );
static_text_sizer->Add(m_button_clean, 0, wxALIGN_CENTRE_VERTICAL|wxRIGHT,FromDIP(5));
m_panel_error_txt->SetSizer(static_text_sizer);
m_panel_error_txt->Hide();
sizer->Add(m_panel_error_txt, 0, wxEXPAND | wxALL,0);
sizer->Add(0, FromDIP(12), 0);
m_tasklist_sizer = new wxBoxSizer(wxVERTICAL);
@ -451,11 +482,19 @@ wxBoxSizer *StatusBasePanel::create_machine_control_page(wxWindow *parent)
m_staticText_control->SetFont(PAGE_TITLE_FONT);
m_staticText_control->SetForegroundColour(PAGE_TITLE_FONT_COL);
m_calibration_btn = new Button(m_panel_control_title, _L("Start Calibration"));
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));
std::pair<wxColour, int>(wxColour(61, 203, 115), StateColor::Hovered), std::pair<wxColour, int>(AMS_CONTROL_BRAND_COLOUR, StateColor::Normal));
StateColor btn_bd_green(std::pair<wxColour, int>(AMS_CONTROL_WHITE_COLOUR, StateColor::Disabled), std::pair<wxColour, int>(AMS_CONTROL_BRAND_COLOUR, StateColor::Enabled));
m_options_btn = new Button(m_panel_control_title, _L("Print Options"));
m_options_btn->SetBackgroundColor(btn_bg_green);
m_options_btn->SetBorderColor(btn_bd_green);
m_options_btn->SetTextColor(*wxWHITE);
m_options_btn->SetSize(wxSize(FromDIP(128), FromDIP(26)));
m_options_btn->SetMinSize(wxSize(-1, FromDIP(26)));
m_calibration_btn = new Button(m_panel_control_title, _L("Calibration"));
m_calibration_btn->SetBackgroundColor(btn_bg_green);
m_calibration_btn->SetBorderColor(btn_bd_green);
m_calibration_btn->SetTextColor(*wxWHITE);
@ -464,6 +503,7 @@ wxBoxSizer *StatusBasePanel::create_machine_control_page(wxWindow *parent)
bSizer_control_title->Add(m_staticText_control, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, PAGE_TITLE_LEFT_MARGIN);
bSizer_control_title->Add(0, 0, 1, wxEXPAND, 0);
bSizer_control_title->Add(m_options_btn, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(10));
bSizer_control_title->Add(m_calibration_btn, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(10));
m_panel_control_title->SetSizer(bSizer_control_title);
@ -477,7 +517,7 @@ wxBoxSizer *StatusBasePanel::create_machine_control_page(wxWindow *parent)
bSizer_control->Add(temp_axis_ctrl_sizer, 0, wxEXPAND, 0);
auto m_ams_ctrl_sizer = create_ams_group(parent);
bSizer_control->Add(m_ams_ctrl_sizer, 0, wxEXPAND, 0);
bSizer_control->Add(m_ams_ctrl_sizer, 0, wxEXPAND|wxBOTTOM, FromDIP(10));
bSizer_right->Add(bSizer_control, 1, wxEXPAND | wxALL, 0);
@ -563,7 +603,6 @@ wxBoxSizer *StatusBasePanel::create_temp_control(wxWindow *parent)
m_tempCtrl_frame->SetBorderColor(StateColor(std::make_pair(*wxWHITE, (int) StateColor::Disabled), std::make_pair(BUTTON_HOVER_COL, (int) StateColor::Focused),
std::make_pair(BUTTON_HOVER_COL, (int) StateColor::Hovered), std::make_pair(*wxWHITE, (int) StateColor::Normal)));
sizer->Add(m_tempCtrl_frame, 0, wxEXPAND | wxALL, 1);
line = new StaticLine(parent);
line->SetLineColour(STATIC_BOX_LINE_COL);
sizer->Add(line, 0, wxEXPAND | wxLEFT | wxRIGHT, 12);
@ -705,6 +744,7 @@ wxBoxSizer *StatusBasePanel::create_bed_control(wxWindow *parent)
bSizer_z_ctrl->AddStretchSpacer();
m_bpButton_z_10 = new Button(panel, wxString("10"), "monitor_bed_up", 0, FromDIP(15));
m_bpButton_z_10->SetFont(::Label::Body_13);
m_bpButton_z_10->SetBorderWidth(2);
m_bpButton_z_10->SetBackgroundColor(z_10_ctrl_bg);
m_bpButton_z_10->SetBorderColor(z_10_ctrl_bd);
m_bpButton_z_10->SetTextColor(StateColor(std::make_pair(DISCONNECT_TEXT_COL, (int) StateColor::Disabled), std::make_pair(NORMAL_TEXT_COL, (int) StateColor::Normal)));
@ -715,6 +755,7 @@ wxBoxSizer *StatusBasePanel::create_bed_control(wxWindow *parent)
m_bpButton_z_1 = new Button(panel, wxString(" 1"), "monitor_bed_up", 0, FromDIP(15));
m_bpButton_z_1->SetFont(::Label::Body_13);
m_bpButton_z_1->SetBorderWidth(2);
m_bpButton_z_1->SetBackgroundColor(z_1_ctrl_bg);
m_bpButton_z_1->SetBorderColor(z_1_ctrl_bd);
m_bpButton_z_1->SetMinSize(Z_BUTTON_SIZE);
@ -726,6 +767,7 @@ wxBoxSizer *StatusBasePanel::create_bed_control(wxWindow *parent)
m_bpButton_z_down_1 = new Button(panel, wxString(" 1"), "monitor_bed_down", 0, FromDIP(15));
m_bpButton_z_down_1->SetFont(::Label::Body_13);
m_bpButton_z_down_1->SetBorderWidth(2);
m_bpButton_z_down_1->SetBackgroundColor(z_1_ctrl_bg);
m_bpButton_z_down_1->SetBorderColor(z_1_ctrl_bd);
m_bpButton_z_down_1->SetMinSize(Z_BUTTON_SIZE);
@ -735,6 +777,7 @@ wxBoxSizer *StatusBasePanel::create_bed_control(wxWindow *parent)
m_bpButton_z_down_10 = new Button(panel, wxString("10"), "monitor_bed_down", 0, FromDIP(15));
m_bpButton_z_down_10->SetFont(::Label::Body_13);
m_bpButton_z_down_10->SetBorderWidth(2);
m_bpButton_z_down_10->SetBackgroundColor(z_10_ctrl_bg);
m_bpButton_z_down_10->SetBorderColor(z_10_ctrl_bd);
m_bpButton_z_down_10->SetMinSize(Z_BUTTON_SIZE);
@ -772,6 +815,7 @@ wxBoxSizer *StatusBasePanel::create_extruder_control(wxWindow *parent)
StateColor e_ctrl_bg(std::pair<wxColour, int>(BUTTON_PRESS_COL, StateColor::Pressed), std::pair<wxColour, int>(BUTTON_NORMAL1_COL, StateColor::Normal));
StateColor e_ctrl_bd(std::pair<wxColour, int>(BUTTON_HOVER_COL, StateColor::Hovered), std::pair<wxColour, int>(BUTTON_NORMAL1_COL, StateColor::Normal));
m_bpButton_e_10 = new Button(panel, "", "monitor_extruder_up", 0, FromDIP(22));
m_bpButton_e_10->SetBorderWidth(2);
m_bpButton_e_10->SetBackgroundColor(e_ctrl_bg);
m_bpButton_e_10->SetBorderColor(e_ctrl_bd);
m_bpButton_e_10->SetMinSize(wxSize(FromDIP(40), FromDIP(40)));
@ -786,6 +830,7 @@ wxBoxSizer *StatusBasePanel::create_extruder_control(wxWindow *parent)
bSizer_e_ctrl->Add(m_bitmap_extruder_img, 0, wxALIGN_CENTER_HORIZONTAL | wxTOP | wxBOTTOM, FromDIP(5));
bSizer_e_ctrl->Add(0, FromDIP(7), 0, 0, 0);
m_bpButton_e_down_10 = new Button(panel, "", "monitor_extruder_down", 0, FromDIP(22));
m_bpButton_e_down_10->SetBorderWidth(2);
m_bpButton_e_down_10->SetBackgroundColor(e_ctrl_bg);
m_bpButton_e_down_10->SetBorderColor(e_ctrl_bd);
m_bpButton_e_down_10->SetMinSize(wxSize(FromDIP(40), FromDIP(40)));
@ -829,36 +874,25 @@ wxBoxSizer *StatusBasePanel::create_ams_group(wxWindow *parent)
{
auto sizer = new wxBoxSizer(wxVERTICAL);
auto sizer_box = new wxBoxSizer(wxVERTICAL);
auto box = new RoundedRectangle(parent, wxColour(0xEE, 0xEE, 0xEE), wxDefaultPosition, wxDefaultSize, 5, 1);
m_ams_control_box = new RoundedRectangle(parent, wxColour(0xEE, 0xEE, 0xEE), wxDefaultPosition, wxDefaultSize, 5, 1);
m_ams_control_box->SetMinSize(wxSize(FromDIP(530), FromDIP(310)));
m_ams_control_box->SetBackgroundColour(*wxWHITE);
#if !BBL_RELEASE_TO_PUBLIC
m_ams_debug = new wxStaticText(box, wxID_ANY, _L("Debug Info"), wxDefaultPosition, wxDefaultSize, 0);
m_ams_debug = new wxStaticText(m_ams_control_box, wxID_ANY, _L("Debug Info"), wxDefaultPosition, wxDefaultSize, 0);
sizer_box->Add(m_ams_debug, 0, wxALIGN_CENTER_HORIZONTAL, 0);
m_ams_debug->Hide();
#endif
m_ams_control = new AMSControl(box, wxID_ANY);
m_ams_control->SetMinSize(m_ams_control->GetSize());
m_ams_control = new AMSControl(m_ams_control_box, wxID_ANY);
//m_ams_control->SetMinSize(wxSize(FromDIP(510), FromDIP(286)));
m_ams_control->SetDoubleBuffered(true);
sizer_box->Add(m_ams_control, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, FromDIP(10));
box->SetBackgroundColour(*wxWHITE);
box->SetSizer(sizer_box);
box->Layout();
sizer->Add(box, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, FromDIP(9));
// display demo, to be removed
// auto caninfo0_0 = Caninfo{"can0", _L("PLA1"), *wxWHITE, AMSCanType::AMS_CAN_TYPE_NONE};
// auto caninfo0_1 = Caninfo{"can1", _L("PLA2"), wxColour(255,192,203), AMSCanType::AMS_CAN_TYPE_BRAND};
// auto caninfo0_2 = Caninfo{"can2", _L("PLA3"), *wxWHITE, AMSCanType::AMS_CAN_TYPE_THIRDBRAND};
// auto caninfo0_3 = Caninfo{"cam3", _L("PLA4"), *wxWHITE, AMSCanType::AMS_CAN_TYPE_THIRDBRAND};
// auto caninfo0_33 = Caninfo{"can43", _L("DDD"), wxColour(148,0,211), AMSCanType::AMS_CAN_TYPE_THIRDBRAND};
// AMSinfo ams1 = AMSinfo{"ams0", std::vector<Caninfo>{caninfo0_0, caninfo0_1}};
// AMSinfo ams2 = AMSinfo{"ams1", std::vector<Caninfo>{caninfo0_0, caninfo0_1, caninfo0_2}};
// AMSinfo ams3 = AMSinfo{"ams2", std::vector<Caninfo>{caninfo0_0, caninfo0_1, caninfo0_2, caninfo0_3}};
// AMSinfo ams4 = AMSinfo{"ams3", std::vector<Caninfo>{caninfo0_0, caninfo0_1, caninfo0_2, caninfo0_33}};
// std::vector<AMSinfo> ams_info{ams1,ams2,ams3,ams4};
// m_ams_control->UpdateAms(ams_info);
m_ams_control_box->SetBackgroundColour(*wxWHITE);
m_ams_control_box->SetSizer(sizer_box);
m_ams_control_box->Layout();
m_ams_control_box->Fit();
sizer->Add(m_ams_control_box, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, FromDIP(0));
return sizer;
}
@ -866,6 +900,8 @@ void StatusBasePanel::show_ams_group(bool show)
{
if (m_show_ams_group != show) {
m_ams_control->Show(show);
m_ams_control_box->Show(show);
Fit();
}
m_show_ams_group = show;
}
@ -916,6 +952,7 @@ StatusPanel::StatusPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, co
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_button_clean);
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);
@ -924,7 +961,6 @@ StatusPanel::StatusPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, co
m_buttons.push_back(m_bpButton_e_down_10);
obj = nullptr;
/* set default values */
m_switch_lamp->SetValue(false);
m_switch_printing_fan->SetValue(false);
@ -945,6 +981,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);
@ -953,6 +990,7 @@ StatusPanel::StatusPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, co
m_button_pause_resume->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_pause_resume), NULL, this);
m_button_abort->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_abort), NULL, this);
m_button_clean->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_clean), NULL, this);
m_tempCtrl_bed->Connect(wxEVT_KILL_FOCUS, wxFocusEventHandler(StatusPanel::on_bed_temp_kill_focus), NULL, this);
m_tempCtrl_bed->Connect(wxEVT_SET_FOCUS, wxFocusEventHandler(StatusPanel::on_bed_temp_set_focus), NULL, this);
m_tempCtrl_nozzle->Connect(wxEVT_KILL_FOCUS, wxFocusEventHandler(StatusPanel::on_nozzle_temp_kill_focus), NULL, this);
@ -974,9 +1012,11 @@ StatusPanel::StatusPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, co
Bind(EVT_AMS_REFRESH_RFID, &StatusPanel::on_ams_refresh_rfid, this);
Bind(EVT_AMS_ON_SELECTED, &StatusPanel::on_ams_selected, this);
Bind(EVT_AMS_ON_FILAMENT_EDIT, &StatusPanel::on_filament_edit, this);
Bind(EVT_UPDATE_ERROR_MESSAGE, &StatusPanel::on_update_error_message, this);
m_switch_speed->Connect(wxEVT_LEFT_DOWN, wxCommandEventHandler(StatusPanel::on_switch_speed), NULL, this);
m_calibration_btn->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_start_calibration), NULL, this);
m_options_btn->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_show_print_options), NULL, this);
}
StatusPanel::~StatusPanel()
@ -987,6 +1027,7 @@ StatusPanel::~StatusPanel()
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_button_clean->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_clean), NULL, this);
m_tempCtrl_bed->Disconnect(wxEVT_KILL_FOCUS, wxFocusEventHandler(StatusPanel::on_bed_temp_kill_focus), NULL, this);
m_tempCtrl_bed->Disconnect(wxEVT_SET_FOCUS, wxFocusEventHandler(StatusPanel::on_bed_temp_set_focus), NULL, this);
m_tempCtrl_nozzle->Disconnect(wxEVT_KILL_FOCUS, wxFocusEventHandler(StatusPanel::on_nozzle_temp_kill_focus), NULL, this);
@ -1003,6 +1044,7 @@ StatusPanel::~StatusPanel()
m_bpButton_e_down_10->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_axis_ctrl_e_down_10), NULL, this);
m_switch_speed->Disconnect(wxEVT_LEFT_DOWN, wxCommandEventHandler(StatusPanel::on_switch_speed), NULL, this);
m_calibration_btn->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_start_calibration), NULL, this);
m_options_btn->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_show_print_options), NULL, this);
m_button_unload->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_start_unload), NULL, this);
}
@ -1014,6 +1056,8 @@ 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_clean->SetMinSize(wxSize(FromDIP(48), FromDIP(24)));
m_button_clean->SetCornerRadius(FromDIP(12));
m_button_unload->SetMinSize(wxSize(-1, FromDIP(24)));
m_button_unload->SetCornerRadius(FromDIP(10));
m_bpButton_z_10->SetMinSize(Z_BUTTON_SIZE);
@ -1066,6 +1110,7 @@ void StatusPanel::show_task_list_info(bool show)
m_tasklist_sizer->Hide(m_tasklist_caption_sizer);
}
Layout();
}
void StatusPanel::update_tasklist_info()
@ -1091,6 +1136,20 @@ void StatusPanel::on_subtask_abort(wxCommandEvent &event)
if (obj) obj->command_task_abort();
}
void StatusPanel::error_info_reset()
{
m_staticline->Hide();
m_panel_error_txt->Hide();
m_panel_error_txt->GetParent()->Layout();
m_error_text->SetLabel("");
before_error_code = 0;
}
void StatusPanel::on_subtask_clean(wxCommandEvent &event)
{
error_info_reset();
}
void StatusPanel::on_webrequest_state(wxWebRequestEvent &evt)
{
BOOST_LOG_TRIVIAL(trace) << "monitor: monitor_panel web request state = " << evt.GetState();
@ -1098,7 +1157,7 @@ void StatusPanel::on_webrequest_state(wxWebRequestEvent &evt)
case wxWebRequest::State_Completed: {
wxImage img(*evt.GetResponse().GetStream());
img_list.insert(std::make_pair(m_request_url, img));
wxImage resize_img = img.Scale(m_bitmap_thumbnail->GetSize().x, m_bitmap_thumbnail->GetSize().y);
wxImage resize_img = img.Scale(m_bitmap_thumbnail->GetSize().x, m_bitmap_thumbnail->GetSize().y, wxIMAGE_QUALITY_HIGH);
m_bitmap_thumbnail->SetBitmap(resize_img);
break;
}
@ -1155,6 +1214,7 @@ void StatusPanel::update(MachineObject *obj)
update_ams(obj);
update_cali(obj);
if (obj) {
if (calibration_dlg == nullptr) {
calibration_dlg = new CalibrationDialog();
@ -1163,13 +1223,51 @@ void StatusPanel::update(MachineObject *obj)
calibration_dlg->update_machine_obj(obj);
}
calibration_dlg->update_cali(obj);
if (print_options_dlg == nullptr) {
print_options_dlg = new PrintOptionsDialog(this);
print_options_dlg->update_machine_obj(obj);
} else {
print_options_dlg->update_machine_obj(obj);
}
print_options_dlg->update_options(obj);
update_error_message();
}
upodate_camera_state(obj->has_recording(), obj->has_timelapse(), obj->has_sdcard());
m_machine_ctrl_panel->Thaw();
}
void StatusPanel::on_update_error_message(wxCommandEvent &event)
{
m_error_text->SetLabel(event.GetString());
m_staticline->Show();
m_panel_error_txt->Show();
}
void StatusPanel::update_error_message()
{
if (obj->print_error <= 0) {
before_error_code = obj->print_error;
if (m_panel_error_txt->IsShown())
error_info_reset();
return;
}
if (before_error_code != obj->print_error) {
get_error_message_thread = new boost::thread(Slic3r::create_thread([&] {
std::string message = show_error_message(obj->print_error);
wxCommandEvent event(EVT_UPDATE_ERROR_MESSAGE);
event.SetString(wxString(message));
event.SetEventObject(this);
wxPostEvent(this, event);
}));
before_error_code = obj->print_error;
}
}
void StatusPanel::show_printing_status(bool ctrl_area, bool temp_area)
{
if (!ctrl_area) {
@ -1503,7 +1601,7 @@ void StatusPanel::update_cali(MachineObject *obj)
}
} else {
// IDLE
m_calibration_btn->SetLabel(_L("Start Calibration"));
m_calibration_btn->SetLabel(_L("Calibration"));
// disable in printing
if (obj->is_in_printing()) {
m_calibration_btn->Disable();
@ -1556,8 +1654,13 @@ void StatusPanel::update_subtask(MachineObject *obj)
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);
if (obj->print_status == "FINISH") {
m_button_abort->Enable(false);
m_button_pause_resume->Enable(false);
} else {
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);
@ -1622,7 +1725,7 @@ void StatusPanel::update_sdcard_subtask(MachineObject *obj)
if (!obj) return;
if (!m_load_sdcard_thumbnail) {
m_bitmap_thumbnail->SetBitmap(m_thumbnail_sdcard);
m_bitmap_thumbnail->SetBitmap(m_thumbnail_sdcard.bmp());
m_load_sdcard_thumbnail = true;
}
}
@ -1637,7 +1740,7 @@ void StatusPanel::reset_printing_values()
m_printing_stage_value->SetLabelText("");
m_staticText_progress_left->SetLabelText(NA_STR);
m_staticText_progress_percent->SetLabelText(NA_STR);
m_bitmap_thumbnail->SetBitmap(m_thumbnail_placeholder);
m_bitmap_thumbnail->SetBitmap(m_thumbnail_placeholder.bmp());
m_start_loading_thumbnail = false;
m_load_sdcard_thumbnail = false;
this->Layout();
@ -1794,6 +1897,10 @@ void StatusPanel::on_filament_edit(wxCommandEvent &event)
m_filament_setting_dlg->ams_id = ams_id_int;
m_filament_setting_dlg->tray_id = tray_id_int;
std::string sn_number;
std::string filament;
std::string temp_max;
std::string temp_min;
auto it = obj->amsList.find(ams_id);
if (it != obj->amsList.end()) {
auto tray_it = it->second->trayList.find(tray_id);
@ -1802,10 +1909,16 @@ void StatusPanel::on_filament_edit(wxCommandEvent &event)
m_filament_setting_dlg->set_color(color);
m_filament_setting_dlg->ams_filament_id = tray_it->second->setting_id;
m_filament_setting_dlg->m_is_third = !MachineObject::is_bbl_filament(tray_it->second->tag_uid);
if (!m_filament_setting_dlg->m_is_third) {
sn_number = tray_it->second->uuid;
filament = tray_it->second->sub_brands;
temp_max = tray_it->second->nozzle_temp_max;
temp_min = tray_it->second->nozzle_temp_min;
}
}
}
m_filament_setting_dlg->Popup(true);
m_filament_setting_dlg->SetPosition(m_ams_control->GetScreenPosition());
m_filament_setting_dlg->Popup(filament, sn_number, temp_min, temp_max);
} catch (...) {
;
}
@ -2061,6 +2174,21 @@ void StatusPanel::on_xyz_abs(wxCommandEvent &event)
if (obj) obj->command_xyz_abs();
}
void StatusPanel::on_show_print_options(wxCommandEvent &event)
{
if (obj) {
if (print_options_dlg == nullptr) {
print_options_dlg = new PrintOptionsDialog(this);
print_options_dlg->update_machine_obj(obj);
print_options_dlg->ShowModal();
}
else {
print_options_dlg->update_machine_obj(obj);
print_options_dlg->ShowModal();
}
}
}
void StatusPanel::on_start_calibration(wxCommandEvent &event)
{
if (obj) {
@ -2106,8 +2234,10 @@ void StatusPanel::set_default()
reset_temp_misc_control();
m_ams_control->Hide();
m_ams_control_box->Hide();
m_ams_control->Reset();
clean_tasklist_info();
error_info_reset();
}
void StatusPanel::show_status(int status)
@ -2122,9 +2252,11 @@ void StatusPanel::show_status(int status)
m_text_tasklist_caption->SetForegroundColour(DISCONNECT_TEXT_COL);
show_printing_status(false, false);
m_calibration_btn->Disable();
m_options_btn->Disable();
} else if ((status & (int) MonitorStatus::MONITOR_NORMAL) != 0) {
show_printing_status(true, true);
m_calibration_btn->Disable();
m_options_btn->Enable();
}
}
@ -2202,6 +2334,9 @@ void StatusPanel::msw_rescale()
m_calibration_btn->SetMinSize(wxSize(-1, FromDIP(26)));
m_calibration_btn->Rescale();
m_options_btn->SetMinSize(wxSize(-1, FromDIP(26)));
m_options_btn->Rescale();
Layout();
Refresh();
}

View file

@ -17,6 +17,7 @@
#include "MediaPlayCtrl.h"
#include "AMSSetting.hpp"
#include "Calibration.hpp"
#include "PrintOptionsDialog.hpp"
#include "AMSMaterialsSetting.hpp"
#include "Widgets/SwitchButton.hpp"
#include "Widgets/AxisCtrlButton.hpp"
@ -26,8 +27,8 @@
#include "Widgets/ProgressBar.hpp"
#include "Widgets/ImageSwitchButton.hpp"
#include "Widgets/AMSControl.hpp"
#include "UpdateErrorMessage.hpp"
#include "Widgets/wxStaticText2.hpp"
class StepIndicator;
#define COMMAND_TIMEOUT_U0 15
@ -65,18 +66,18 @@ class StatusBasePanel : public wxScrolledWindow
{
protected:
wxBitmap m_item_placeholder;
wxBitmap m_thumbnail_placeholder;
wxBitmap m_thumbnail_sdcard;
ScalableBitmap m_thumbnail_placeholder;
ScalableBitmap m_thumbnail_sdcard;
wxBitmap m_bitmap_item_prediction;
wxBitmap m_bitmap_item_cost;
wxBitmap m_bitmap_item_print;
wxBitmap m_bitmap_speed;
wxBitmap m_bitmap_speed_active;
wxBitmap m_bitmap_axis_home;
wxBitmap m_bitmap_lamp_on;
wxBitmap m_bitmap_lamp_off;
wxBitmap m_bitmap_fan_on;
wxBitmap m_bitmap_fan_off;
ScalableBitmap m_bitmap_speed;
ScalableBitmap m_bitmap_speed_active;
ScalableBitmap m_bitmap_axis_home;
ScalableBitmap m_bitmap_lamp_on;
ScalableBitmap m_bitmap_lamp_off;
ScalableBitmap m_bitmap_fan_on;
ScalableBitmap m_bitmap_fan_off;
wxBitmap m_bitmap_extruder;
CameraRecordingStatus m_state_recording{CameraRecordingStatus::RECORDING_NONE};
@ -119,6 +120,7 @@ protected:
Button * m_button_report;
Button * m_button_pause_resume;
Button * m_button_abort;
Button * m_button_clean;
wxStaticText * m_text_tasklist_caption;
@ -157,6 +159,7 @@ protected:
wxStaticText * m_ams_debug;
bool m_show_ams_group{false};
AMSControl* m_ams_control;
RoundedRectangle* m_ams_control_box;
wxStaticBitmap *m_ams_extruder_img;
wxStaticBitmap* m_bitmap_extruder_img;
wxPanel * m_panel_separator_right;
@ -165,9 +168,13 @@ protected:
wxBoxSizer * m_printing_sizer;
wxBoxSizer * m_tasklist_sizer;
wxBoxSizer * m_tasklist_caption_sizer;
wxPanel* m_panel_error_txt;
wxPanel* m_staticline;
wxStaticText2 * m_error_text;
wxStaticText* m_staticText_calibration_caption;
wxStaticText* m_staticText_calibration_caption_top;
wxStaticText* m_calibration_text;
Button* m_options_btn;
Button* m_calibration_btn;
StepIndicator* m_calibration_flow;
@ -214,8 +221,9 @@ public:
wxBoxSizer *create_extruder_control(wxWindow *parent);
void reset_temp_misc_control();
int before_error_code = 0;
wxBoxSizer *create_ams_group(wxWindow *parent);
wxBoxSizer *create_settings_group(wxWindow *parent);
void show_ams_group(bool show = true);
void upodate_camera_state(bool recording, bool timelapse, bool has_sdcard);
@ -233,14 +241,14 @@ protected:
std::shared_ptr<CameraPopup> m_camera_popup;
std::vector<SliceInfoPanel *> slice_info_list;
AMSSetting *m_ams_setting_dlg{nullptr};
CalibrationDialog* calibration_dlg{nullptr};
PrintOptionsDialog* print_options_dlg { nullptr };
CalibrationDialog* calibration_dlg {nullptr};
AMSMaterialsSetting *m_filament_setting_dlg{nullptr};
wxString m_request_url;
bool m_start_loading_thumbnail = false;
bool m_load_sdcard_thumbnail = false;
wxWebRequest web_request;
bool bed_temp_input = false;
bool nozzle_temp_input = false;
int speed_lvl = 1; // 0 - 3
@ -250,9 +258,8 @@ protected:
std::map<wxString, wxImage> img_list; // key: url, value: wxBitmap png Image
std::vector<Button *> m_buttons;
int last_status;
void init_scaled_buttons();
void update_error_message();
void create_tasklist_info();
void clean_tasklist_info();
void show_task_list_info(bool show = true);
@ -260,6 +267,9 @@ protected:
void on_subtask_pause_resume(wxCommandEvent &event);
void on_subtask_abort(wxCommandEvent &event);
void on_subtask_clean(wxCommandEvent &event);
void on_update_error_message(wxCommandEvent &event);
void error_info_reset();
/* axis control */
void on_axis_ctrl_xy(wxCommandEvent &event);
@ -299,6 +309,9 @@ protected:
void on_auto_leveling(wxCommandEvent &event);
void on_xyz_abs(wxCommandEvent &event);
/* print options */
void on_show_print_options(wxCommandEvent &event);
/* calibration */
void on_start_calibration(wxCommandEvent &event);
@ -339,6 +352,7 @@ public:
long last_ams_version { -1 };
std::vector<int> last_stage_list_info;
boost::thread * get_error_message_thread{nullptr};
bool is_stage_list_info_changed(MachineObject* obj);

View file

@ -557,7 +557,7 @@ Slic3r::GUI::PageShp Tab::add_options_page(const wxString& title, const std::str
if (icon_idx == -1) {
// Add a new icon to the icon list.
m_scaled_icons_list.push_back(ScalableBitmap(this, icon, 32, false, true));
m_icons->Add(m_scaled_icons_list.back().bmp());
//m_icons->Add(m_scaled_icons_list.back().bmp());
icon_idx = ++m_icon_count;
m_icon_index[icon] = icon_idx;
}
@ -851,7 +851,7 @@ void TabPrinter::init_options_list()
for (const std::string& opt_key : m_config->keys())
{
if (opt_key == "printable_area") {
if (opt_key == "printable_area" || opt_key == "bed_exclude_area") {
m_options_list.emplace(opt_key, m_opt_status_value);
continue;
}
@ -1180,7 +1180,7 @@ void Tab::msw_rescale()
m_icons->RemoveAll();
m_icons = new wxImageList(m_scaled_icons_list.front().bmp().GetWidth(), m_scaled_icons_list.front().bmp().GetHeight(), false);
for (ScalableBitmap& bmp : m_scaled_icons_list)
m_icons->Add(bmp.bmp());
//m_icons->Add(bmp.bmp());
m_tabctrl->AssignImageList(m_icons);
// rescale options_groups
@ -1214,7 +1214,7 @@ void Tab::sys_color_changed()
m_icons->RemoveAll();
m_icons = new wxImageList(m_scaled_icons_list.front().bmp().GetWidth(), m_scaled_icons_list.front().bmp().GetHeight(), false);
for (ScalableBitmap& bmp : m_scaled_icons_list)
m_icons->Add(bmp.bmp());
//m_icons->Add(bmp.bmp());
m_tabctrl->AssignImageList(m_icons);
// Colors for ui "decoration"
@ -1374,6 +1374,12 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
if (opt_key == "enable_prime_tower" || opt_key == "single_extruder_multi_material" || opt_key == "extruders_count" )
update_wiping_button_visibility();
//popup message dialog when first selected
if (opt_key == "timelapse_no_toolhead" && boost::any_cast<bool>(value))
show_timelapse_warning_dialog();
// BBS
#if 0
if (opt_key == "extruders_count")
@ -1391,6 +1397,16 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
m_page_view->GetParent()->Layout();
}
void Tab::show_timelapse_warning_dialog() {
if (!m_is_timelapse_wipe_tower_already_prompted) {
wxString msg_text = _(L("When recording timelapse without toolhead, it is recommended to add a \"Timelapse Wipe Tower\" \n"
"by right-click the empty position of build plate and choose \"Add Primitive\"->\"Timelapse Wipe Tower\".\n"));
MessageDialog dialog(nullptr, msg_text, "", wxICON_WARNING | wxOK);
dialog.ShowModal();
m_is_timelapse_wipe_tower_already_prompted = true;
}
}
// Show/hide the 'purging volumes' button
void Tab::update_wiping_button_visibility() {
if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA)
@ -1503,7 +1519,6 @@ void Tab::apply_config_from_cache()
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<<boost::format(": exit, was_applied=%1%")%was_applied;
}
// Call a callback to update the selection of presets on the plater:
// To update the content of the selection boxes,
// to update the filament colors of the selection boxes,
@ -2092,6 +2107,9 @@ void TabPrintModel::update_model_config()
m_config->apply_only(local_config, local_keys);
m_config_manipulation.apply_null_fff_config(m_config, m_null_keys, m_object_configs);
}
toggle_options();
if (m_active_page)
m_active_page->update_visibility(m_mode, true); // for taggle line
update_dirty();
TabPrint::reload_config();
//update();
@ -2677,7 +2695,9 @@ void TabPrinter::build_fff()
//create_line_with_widget(optgroup.get(), "printable_area", "custom-svg-and-png-bed-textures_124612", [this](wxWindow* parent) {
// return create_bed_shape_widget(parent);
//});
Option option = optgroup->get_option("bed_exclude_area");
option.opt.full_width = true;
optgroup->append_single_option_line(option);
optgroup->append_single_option_line("printable_height");
optgroup->append_single_option_line("nozzle_volume");
// BBS
@ -2793,7 +2813,7 @@ void TabPrinter::build_fff()
optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
validate_custom_gcode_cb(this, optgroup, opt_key, value);
};
Option option = optgroup->get_option("machine_start_gcode");
option = optgroup->get_option("machine_start_gcode");
option.opt.full_width = true;
option.opt.is_code = true;
option.opt.height = gcode_field_height;//150;
@ -3094,7 +3114,7 @@ void TabPrinter::build_unregular_pages(bool from_initial_build/* = false*/)
// Build missed extruder pages
//for (auto extruder_idx = m_extruders_count_old; extruder_idx < m_extruders_count; ++extruder_idx)
auto extruder_idx = 0;
const wxString& page_name = wxString::Format("Extruder %d", int(extruder_idx + 1));
const wxString& page_name = (m_extruders_count > 1) ? wxString::Format("Extruder %d", int(extruder_idx + 1)) : wxString::Format("Extruder");
bool page_exist = false;
for (auto page_temp : m_pages) {
if (page_temp->title() == page_name) {
@ -3153,10 +3173,8 @@ void TabPrinter::build_unregular_pages(bool from_initial_build/* = false*/)
optgroup->append_single_option_line("min_layer_height", "", extruder_idx);
optgroup->append_single_option_line("max_layer_height", "", extruder_idx);
#if 0
//optgroup = page->new_optgroup(L("Position (for multi-extruder printers)"), -1, true);
//optgroup->append_single_option_line("extruder_offset", "", extruder_idx);
#endif
optgroup = page->new_optgroup(L("Position"), -1, true);
optgroup->append_single_option_line("extruder_offset", "", extruder_idx);
//BBS: don't show retract related config menu in machine page
optgroup = page->new_optgroup(L("Retraction"));
@ -4714,7 +4732,7 @@ void Page::activate(ConfigOptionMode mode, std::function<void()> throw_if_cancel
for (auto group : m_optgroups) {
if (!group->activate(throw_if_canceled))
continue;
m_vsizer->Add(group->sizer, 0, wxEXPAND | (group->is_legend_line() ? (wxLEFT|wxTOP) : wxALL), 10);
m_vsizer->Add(group->sizer, 0, wxEXPAND | (group->is_legend_line() ? (wxLEFT|wxTOP) : wxALL), 5);
group->update_visibility(mode);
#if HIDE_FIRST_SPLIT_LINE
if (first) group->stb->Hide();

View file

@ -272,6 +272,8 @@ protected:
bool m_page_switch_running = false;
bool m_page_switch_planned = false;
bool m_is_timelapse_wipe_tower_already_prompted = false;
public:
PresetBundle* m_preset_bundle;
bool m_show_btn_incompatible_presets = false;
@ -389,6 +391,7 @@ public:
void apply_searcher();
void cache_config_diff(const std::vector<std::string>& selected_options);
void apply_config_from_cache();
void show_timelapse_warning_dialog();
const std::map<wxString, std::string>& get_category_icon_map() { return m_category_icon; }
//BBS: GUI refactor

View file

@ -33,13 +33,13 @@ TabButton::TabButton()
std::make_pair(*wxWHITE, (int) StateColor::Normal));
}
TabButton::TabButton(wxWindow *parent, wxString text, wxBitmap &bmp, long style, int iconSize)
TabButton::TabButton(wxWindow *parent, wxString text, ScalableBitmap &bmp, long style, int iconSize)
: TabButton()
{
Create(parent, text, bmp, style, iconSize);
}
bool TabButton::Create(wxWindow *parent, wxString text, wxBitmap &bmp, long style, int iconSize)
bool TabButton::Create(wxWindow *parent, wxString text, ScalableBitmap &bmp, long style, int iconSize)
{
StaticBox::Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, style);
state_handler.attach({&text_color, &border_color});
@ -47,7 +47,7 @@ bool TabButton::Create(wxWindow *parent, wxString text, wxBitmap &bmp, long styl
//BBS set default font
SetFont(Label::Body_14);
wxWindow::SetLabel(text);
this->icon = bmp.GetSubBitmap(wxRect(0, 0, bmp.GetWidth(), bmp.GetHeight()));
this->icon = bmp;
messureSize();
return true;
}
@ -92,9 +92,9 @@ void TabButton::SetBGColor(StateColor const &color)
Refresh();
}
void TabButton::SetBitmap(wxBitmap &bitmap)
void TabButton::SetBitmap(ScalableBitmap &bitmap)
{
this->icon = bitmap.GetSubBitmap(wxRect(0, 0, bitmap.GetWidth(), bitmap.GetHeight()));
this->icon = bitmap;
}
bool TabButton::Enable(bool enable)
@ -138,12 +138,12 @@ void TabButton::render(wxDC &dc)
// calc content size
wxSize szIcon;
wxSize szContent = textSize;
if (icon.IsOk()) {
if (icon.bmp().IsOk()) {
if (szContent.y > 0) {
// BBS norrow size between text and icon
szContent.x += 5;
}
szIcon = icon.GetSize();
szIcon = icon.GetBmpSize();
szContent.x += szIcon.x;
if (szIcon.y > szContent.y) szContent.y = szIcon.y;
}
@ -163,10 +163,10 @@ void TabButton::render(wxDC &dc)
dc.DrawText(text, pt);
}
if (icon.IsOk()) {
pt.x = size.x - icon.GetWidth() - paddingSize.y;
pt.y = (size.y - icon.GetHeight()) / 2;
dc.DrawBitmap(icon, pt);
if (icon.bmp().IsOk()) {
pt.x = size.x - icon.GetBmpWidth() - paddingSize.y;
pt.y = (size.y - icon.GetBmpHeight()) / 2;
dc.DrawBitmap(icon.bmp(), pt);
}
}
@ -179,12 +179,12 @@ void TabButton::messureSize()
return;
}
wxSize szContent = textSize;
if (this->icon.IsOk()) {
if (this->icon.bmp().IsOk()) {
if (szContent.y > 0) {
// BBS norrow size between text and icon
szContent.x += 5;
}
wxSize szIcon = this->icon.GetSize();
wxSize szIcon = this->icon.GetBmpSize();
szContent.x += szIcon.x;
if (szIcon.y > szContent.y) szContent.y = szIcon.y;
}

View file

@ -9,7 +9,7 @@ class TabButton : public StaticBox
wxSize textSize;
wxSize minSize;
wxSize paddingSize;
wxBitmap icon;
ScalableBitmap icon;
StateColor text_color;
StateColor border_color;
@ -18,9 +18,9 @@ class TabButton : public StaticBox
public:
TabButton();
TabButton(wxWindow *parent, wxString text, wxBitmap &icon, long style = 0, int iconSize = 0);
TabButton(wxWindow *parent, wxString text, ScalableBitmap &icon, long style = 0, int iconSize = 0);
bool Create(wxWindow *parent, wxString text, wxBitmap &icon, long style = 0, int iconSize = 0);
bool Create(wxWindow *parent, wxString text, ScalableBitmap &icon, long style = 0, int iconSize = 0);
void SetLabel(const wxString& label) override;
@ -34,7 +34,7 @@ public:
void SetBGColor(StateColor const &color);
void SetBitmap(wxBitmap &bitmap);
void SetBitmap(ScalableBitmap &bitmap);
bool Enable(bool enable = true);

View file

@ -38,7 +38,7 @@ TabButtonsListCtrl::TabButtonsListCtrl(wxWindow *parent, wxBoxSizer *side_tools)
m_btn_margin = 0;
m_line_margin = std::lround(0.1 * em);
m_arrow_img = create_scaled_bitmap("monitor_arrow", nullptr, 14);
m_arrow_img = ScalableBitmap(this, "monitor_arrow", 14);
m_sizer = new wxBoxSizer(wxVERTICAL);
this->SetSizer(m_sizer);
@ -87,7 +87,7 @@ void TabButtonsListCtrl::OnPaint(wxPaintEvent &)
void TabButtonsListCtrl::Rescale()
{
m_arrow_img = create_scaled_bitmap("monitor_arrow", nullptr, 14);
m_arrow_img = ScalableBitmap(this, "monitor_arrow", 14);
int em = em_unit(this);
for (TabButton *btn : m_pageButtons) {

View file

@ -5,6 +5,7 @@
#include <wx/bookctrl.h>
#include <wx/sizer.h>
#include "wxExtensions.hpp"
class ScalableButton;
@ -33,8 +34,8 @@ private:
wxWindow* m_parent;
wxFlexGridSizer* m_buttons_sizer;
wxBoxSizer* m_sizer;
wxBitmap m_arrow_img;
std::vector<TabButton*> m_pageButtons;
ScalableBitmap m_arrow_img;
std::vector<TabButton*> m_pageButtons;
int m_selection {-1};
int m_btn_margin;
int m_line_margin;

View file

@ -955,7 +955,7 @@ void UnsavedChangesDialog::build(Preset::Type type, PresetCollection *dependent_
(*btn)->SetMinSize(UNSAVE_CHANGE_DIALOG_BUTTON_SIZE);
(*btn)->SetCornerRadius(12);
(*btn)->Bind(wxEVT_LEFT_DOWN, [this, close_act, dependent_presets](wxEvent &) {
(*btn)->Bind(wxEVT_BUTTON, [this, close_act, dependent_presets](wxEvent &) {
bool save_names_and_types = close_act == Action::Save || (close_act == Action::Transfer && ActionButtons::KEEP & m_buttons);
if (save_names_and_types && !save(dependent_presets, close_act == Action::Save)) return;
close(close_act);

View file

@ -0,0 +1,60 @@
#include "UpdateErrorMessage.hpp"
namespace Slic3r {
namespace GUI {
wxDEFINE_EVENT(EVT_UPDATE_ERROR_MESSAGE, wxCommandEvent);
std::string show_error_message(int error_code)
{
char buf[64];
std::string result_str = "";
std::sprintf(buf,"%08X",error_code);
std::string hms_host = wxGetApp().app_config->get_hms_host();
std::string get_lang = wxGetApp().app_config->get_langauge_code();
std::string url = (boost::format("https://%1%/query.php?lang=%2%&e=%3%")
%hms_host
%get_lang
%buf).str();
Slic3r::Http http = Slic3r::Http::get(url);
http.header("accept", "application/json")
.timeout_max(10)
.on_complete([get_lang, &result_str](std::string body, unsigned status) {
try {
json j = json::parse(body);
if (j.contains("result")) {
if (j["result"].get<int>() == 0) {
if (j.contains("data")) {
json jj = j["data"];
if (jj.contains("device_error")) {
if (jj["device_error"].contains(get_lang)) {
if (jj["device_error"][get_lang].size() > 0) {
if (!jj["device_error"][get_lang][0]["intro"].empty() || !jj["device_error"][get_lang][0]["ecode"].empty()) {
std::string error_info = jj["device_error"][get_lang][0]["intro"].get<std::string>();
std::string error_code = jj["device_error"][get_lang][0]["ecode"].get<std::string>();
error_code.insert(4, " ");
result_str = from_u8(error_info).ToStdString() + "[" + error_code + "]";
}
}
}
}
}
}
}
} catch (...) {
;
}
})
.on_error([](std::string body, std::string error, unsigned status) {
BOOST_LOG_TRIVIAL(trace) << boost::format("[BBL ErrorMessage]: status=%1%, error=%2%, body=%3%") % status % error % body;
}).perform_sync();
return result_str;
}
}
}

View file

@ -0,0 +1,26 @@
#ifndef slic3r_UpdateErrorMessage_hpp_
#define slic3r_UpdateErrorMessage_hpp_
#include "GUI_App.hpp"
#include "GUI.hpp"
#include "I18N.hpp"
#include "Widgets/Label.hpp"
#include "Widgets/Button.hpp"
#include "Widgets/StepCtrl.hpp"
#include "BitmapCache.hpp"
#include "slic3r/Utils/Http.hpp"
#include "libslic3r/Thread.hpp"
namespace Slic3r {
namespace GUI {
std::string show_error_message(int error_code);
wxDECLARE_EVENT(EVT_UPDATE_ERROR_MESSAGE, wxCommandEvent);
}
}
#endif

View file

@ -319,7 +319,12 @@ int DownPluginFrame::InstallPlugin()
int DownPluginFrame::ShowPluginStatus(int status, int percent, bool &cancel)
{
// TODO
static int nPercent = 0;
if (nPercent == percent)
return 0;
nPercent = percent;
json m_Data = json::object();
m_Data["status"] = status;
m_Data["percent"] = percent;

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