mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-12-11 16:00:17 -07:00
Merge branch 'master-remote' into feature/1.5
Signed-off-by: SoftFever <softfeverever@gmail.com> # Conflicts: # bbl/i18n/BambuStudio.pot # bbl/i18n/de/BambuStudio_de.po # bbl/i18n/en/BambuStudio_en.po # bbl/i18n/es/BambuStudio_es.po # bbl/i18n/fr/BambuStudio_fr.po # bbl/i18n/hu/BambuStudio_hu.po # bbl/i18n/it/BambuStudio_it.po # bbl/i18n/nl/BambuStudio_nl.po # bbl/i18n/sv/BambuStudio_sv.po # bbl/i18n/zh_cn/BambuStudio_zh_CN.po # deps/Boost/Boost.cmake # deps/wxWidgets/wxWidgets.cmake # resources/config.json # resources/i18n/de/BambuStudio.mo # resources/i18n/en/BambuStudio.mo # resources/i18n/es/BambuStudio.mo # resources/i18n/fr/BambuStudio.mo # resources/i18n/hu/BambuStudio.mo # resources/i18n/it/BambuStudio.mo # resources/i18n/nl/BambuStudio.mo # resources/i18n/sv/BambuStudio.mo # resources/i18n/zh_cn/BambuStudio.mo # resources/images/tips_arrow.svg # resources/profiles/Anycubic.json # resources/profiles/Anycubic/filament/Anycubic Generic ABS.json # resources/profiles/Anycubic/filament/Anycubic Generic ASA.json # resources/profiles/Anycubic/filament/Anycubic Generic PA-CF.json # resources/profiles/Anycubic/filament/Anycubic Generic PA.json # resources/profiles/Anycubic/filament/Anycubic Generic PC.json # resources/profiles/Anycubic/filament/Anycubic Generic PETG.json # resources/profiles/Anycubic/filament/Anycubic Generic PLA-CF.json # resources/profiles/Anycubic/filament/Anycubic Generic PLA.json # resources/profiles/Anycubic/filament/Anycubic Generic PVA.json # resources/profiles/Anycubic/filament/Anycubic Generic TPU.json # resources/profiles/Anycubic/filament/fdm_filament_common.json # resources/profiles/Anycubic/machine/Anycubic 4Max Pro 0.4 nozzle.json # resources/profiles/Anycubic/machine/Anycubic 4Max Pro.json # resources/profiles/Anycubic/process/0.20mm Standard @4MaxPro.json # resources/profiles/Anycubic/process/fdm_process_common.json # resources/profiles/BBL.json # resources/profiles/BBL/machine/Bambu Lab P1P 0.2 nozzle.json # resources/profiles/BBL/machine/Bambu Lab P1P 0.4 nozzle.json # resources/profiles/BBL/machine/Bambu Lab P1P 0.6 nozzle.json # resources/profiles/BBL/machine/Bambu Lab P1P 0.8 nozzle.json # resources/profiles/BBL/machine/Bambu Lab X1 0.2 nozzle.json # resources/profiles/BBL/machine/Bambu Lab X1 0.4 nozzle.json # resources/profiles/BBL/machine/Bambu Lab X1 0.6 nozzle.json # resources/profiles/BBL/machine/Bambu Lab X1 0.8 nozzle.json # resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.2 nozzle.json # resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.4 nozzle.json # resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.6 nozzle.json # resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.8 nozzle.json # resources/profiles/BBL/machine/fdm_bbl_3dp_001_common.json # resources/profiles/Voron.json # resources/web/data/text.js # resources/web/image/printer/Anycubic 4Max Pro_cover.png # src/BambuStudio.cpp # src/libslic3r/GCode.cpp # src/libslic3r/GCode.hpp # src/libslic3r/GCode/GCodeProcessor.cpp # src/libslic3r/GCodeWriter.hpp # src/libslic3r/PerimeterGenerator.cpp # src/libslic3r/PresetBundle.cpp # src/libslic3r/Print.cpp # src/libslic3r/Print.hpp # src/libslic3r/PrintConfig.cpp # src/libslic3r/PrintConfig.hpp # src/libslic3r/PrintObject.cpp # src/slic3r/GUI/AMSMaterialsSetting.cpp # src/slic3r/GUI/AMSMaterialsSetting.hpp # src/slic3r/GUI/AmsMappingPopup.cpp # src/slic3r/GUI/AmsMappingPopup.hpp # src/slic3r/GUI/Auxiliary.cpp # src/slic3r/GUI/BackgroundSlicingProcess.cpp # src/slic3r/GUI/ConfigManipulation.cpp # src/slic3r/GUI/DeviceManager.cpp # src/slic3r/GUI/DeviceManager.hpp # src/slic3r/GUI/ExtrusionCalibration.cpp # src/slic3r/GUI/GCodeViewer.cpp # src/slic3r/GUI/GCodeViewer.hpp # src/slic3r/GUI/GUI_App.cpp # src/slic3r/GUI/IMSlider.cpp # src/slic3r/GUI/Jobs/PrintJob.cpp # src/slic3r/GUI/Jobs/PrintJob.hpp # src/slic3r/GUI/Jobs/SendJob.cpp # src/slic3r/GUI/Jobs/SendJob.hpp # src/slic3r/GUI/MainFrame.cpp # src/slic3r/GUI/MainFrame.hpp # src/slic3r/GUI/MediaPlayCtrl.cpp # src/slic3r/GUI/OptionsGroup.cpp # src/slic3r/GUI/PhysicalPrinterDialog.cpp # src/slic3r/GUI/Plater.cpp # src/slic3r/GUI/PrintHostDialogs.cpp # src/slic3r/GUI/Printer/BambuTunnel.h # src/slic3r/GUI/Printer/PrinterFileSystem.cpp # src/slic3r/GUI/Printer/gstbambusrc.c # src/slic3r/GUI/Printer/gstbambusrc.h # src/slic3r/GUI/ReleaseNote.cpp # src/slic3r/GUI/ReleaseNote.hpp # src/slic3r/GUI/SelectMachine.cpp # src/slic3r/GUI/SendToPrinter.cpp # src/slic3r/GUI/SetBedTypeDialog.cpp # src/slic3r/GUI/StatusPanel.cpp # src/slic3r/GUI/StatusPanel.hpp # src/slic3r/GUI/Tab.cpp # src/slic3r/GUI/Widgets/AMSControl.cpp # src/slic3r/GUI/Widgets/AMSControl.hpp # src/slic3r/GUI/Widgets/ImageSwitchButton.cpp # src/slic3r/GUI/Widgets/Label.cpp # src/slic3r/GUI/WipeTowerDialog.cpp # src/slic3r/Utils/Process.cpp # src/slic3r/Utils/bambu_networking.hpp # version.inc
This commit is contained in:
commit
5ef51f6c8a
339 changed files with 37169 additions and 5445 deletions
|
|
@ -390,6 +390,8 @@ std::array<float, 4> GLVolume::MODEL_NEGTIVE_COL = {0.3f, 0.3f, 0.3f, 0.4f};
|
|||
std::array<float, 4> GLVolume::SUPPORT_ENFORCER_COL = {0.3f, 0.3f, 1.0f, 0.4f};
|
||||
std::array<float, 4> GLVolume::SUPPORT_BLOCKER_COL = {1.0f, 0.3f, 0.3f, 0.4f};
|
||||
|
||||
std::array<float, 4> GLVolume::MODEL_HIDDEN_COL = {0.f, 0.f, 0.f, 0.3f};
|
||||
|
||||
std::array<std::array<float, 4>, 5> GLVolume::MODEL_COLOR = { {
|
||||
{ 1.0f, 1.0f, 0.0f, 1.f },
|
||||
{ 1.0f, 0.5f, 0.5f, 1.f },
|
||||
|
|
@ -430,6 +432,7 @@ GLVolume::GLVolume(float r, float g, float b, float a)
|
|||
, selected(false)
|
||||
, disabled(false)
|
||||
, printable(true)
|
||||
, visible(true)
|
||||
, is_active(true)
|
||||
, zoom_to_volumes(true)
|
||||
, shader_outside_printer_detection_enabled(false)
|
||||
|
|
@ -521,6 +524,14 @@ void GLVolume::set_render_color()
|
|||
render_color[2] = UNPRINTABLE_COLOR[2];
|
||||
render_color[3] = UNPRINTABLE_COLOR[3];
|
||||
}
|
||||
|
||||
//BBS set invisible color
|
||||
if (!visible) {
|
||||
render_color[0] = MODEL_HIDDEN_COL[0];
|
||||
render_color[1] = MODEL_HIDDEN_COL[1];
|
||||
render_color[2] = MODEL_HIDDEN_COL[2];
|
||||
render_color[3] = MODEL_HIDDEN_COL[3];
|
||||
}
|
||||
}
|
||||
|
||||
std::array<float, 4> color_from_model_volume(const ModelVolume& model_volume)
|
||||
|
|
@ -684,6 +695,9 @@ void GLVolume::render(bool with_outline) const
|
|||
break;
|
||||
|
||||
ModelObject* mo = model_objects[object_idx()];
|
||||
if (volume_idx() >= mo->volumes.size())
|
||||
break;
|
||||
|
||||
ModelVolume* mv = mo->volumes[volume_idx()];
|
||||
if (mv->mmu_segmentation_facets.empty())
|
||||
break;
|
||||
|
|
@ -1149,7 +1163,7 @@ int GLVolumeCollection::load_wipe_tower_preview(
|
|||
std::vector<std::array<float, 4>> extruder_colors = get_extruders_colors();
|
||||
std::vector<std::array<float, 4>> colors;
|
||||
GUI::PartPlateList& ppl = GUI::wxGetApp().plater()->get_partplate_list();
|
||||
std::vector<int> plate_extruders = ppl.get_plate(plate_idx)->get_extruders();
|
||||
std::vector<int> plate_extruders = ppl.get_plate(plate_idx)->get_extruders(true);
|
||||
TriangleMesh wipe_tower_shell = make_cube(width, depth, height);
|
||||
for (int extruder_id : plate_extruders) {
|
||||
if (extruder_id <= extruder_colors.size())
|
||||
|
|
|
|||
|
|
@ -269,6 +269,7 @@ public:
|
|||
static std::array<float, 4> MODEL_NEGTIVE_COL;
|
||||
static std::array<float, 4> SUPPORT_ENFORCER_COL;
|
||||
static std::array<float, 4> SUPPORT_BLOCKER_COL;
|
||||
static std::array<float, 4> MODEL_HIDDEN_COL;
|
||||
|
||||
static void update_render_colors();
|
||||
static void load_render_colors();
|
||||
|
|
@ -286,6 +287,7 @@ public:
|
|||
|
||||
GLVolume(float r = 1.f, float g = 1.f, float b = 1.f, float a = 1.f);
|
||||
GLVolume(const std::array<float, 4>& rgba) : GLVolume(rgba[0], rgba[1], rgba[2], rgba[3]) {}
|
||||
virtual ~GLVolume() = default;
|
||||
|
||||
// BBS
|
||||
protected:
|
||||
|
|
@ -363,6 +365,8 @@ public:
|
|||
bool disabled : 1;
|
||||
// Is this object printable?
|
||||
bool printable : 1;
|
||||
// Is this object visible(in assemble view)?
|
||||
bool visible : 1;
|
||||
// Whether or not this volume is active for rendering
|
||||
bool is_active : 1;
|
||||
// Whether or not to use this volume when applying zoom_to_volumes()
|
||||
|
|
|
|||
|
|
@ -121,12 +121,13 @@ void AMSMaterialsSetting::create_panel_normal(wxWindow* parent)
|
|||
|
||||
m_sizer_filament->Add(m_comboBox_filament, 1, wxALIGN_CENTER, 0);
|
||||
|
||||
m_readonly_filament = new TextInput(parent, wxEmptyString, "", "", wxDefaultPosition, AMS_MATERIALS_SETTING_COMBOX_WIDTH, wxTE_READONLY);
|
||||
m_readonly_filament = new TextInput(parent, wxEmptyString, "", "", wxDefaultPosition, AMS_MATERIALS_SETTING_COMBOX_WIDTH, wxTE_READONLY | wxRIGHT);
|
||||
m_readonly_filament->SetBorderColor(StateColor(std::make_pair(0xDBDBDB, (int)StateColor::Focused), std::make_pair(0x009688, (int)StateColor::Hovered),
|
||||
std::make_pair(0xDBDBDB, (int)StateColor::Normal)));
|
||||
m_readonly_filament->GetTextCtrl()->Bind(wxEVT_SET_FOCUS, [](auto& e) {
|
||||
;
|
||||
});
|
||||
m_readonly_filament->SetFont(::Label::Body_14);
|
||||
m_readonly_filament->SetLabelColor(AMS_MATERIALS_SETTING_GREY800);
|
||||
m_readonly_filament->GetTextCtrl()->Bind(wxEVT_SET_FOCUS, [](auto& e) {});
|
||||
m_readonly_filament->GetTextCtrl()->Hide();
|
||||
m_sizer_filament->Add(m_readonly_filament, 1, wxALIGN_CENTER, 0);
|
||||
m_readonly_filament->Hide();
|
||||
|
||||
|
|
@ -367,6 +368,13 @@ void AMSMaterialsSetting::enable_confirm_button(bool en)
|
|||
else {
|
||||
m_comboBox_filament->Show(en);
|
||||
m_readonly_filament->Show(!en);
|
||||
|
||||
if ( !is_virtual_tray() ) {
|
||||
m_tip_readonly->SetLabelText(_L("Setting AMS slot information while printing is not supported"));
|
||||
}
|
||||
else {
|
||||
m_tip_readonly->SetLabelText(_L("Setting Virtual slot information while printing is not supported"));
|
||||
}
|
||||
m_tip_readonly->Show(!en);
|
||||
}
|
||||
}
|
||||
|
|
@ -376,7 +384,7 @@ void AMSMaterialsSetting::on_select_ok(wxCommandEvent &event)
|
|||
wxString k_text = m_input_k_val->GetTextCtrl()->GetValue();
|
||||
wxString n_text = m_input_n_val->GetTextCtrl()->GetValue();
|
||||
|
||||
if (is_virtual_tray()) {
|
||||
if (is_virtual_tray() && obj && !obj->is_support_filament_edit_virtual_tray) {
|
||||
if (!ExtrusionCalibration::check_k_validation(k_text)) {
|
||||
wxString k_tips = _L("Please input a valid value (K in 0~0.5)");
|
||||
wxString kn_tips = _L("Please input a valid value (K in 0~0.5, N in 0.6~2.0)");
|
||||
|
|
@ -478,8 +486,12 @@ void AMSMaterialsSetting::on_select_ok(wxCommandEvent &event)
|
|||
}
|
||||
|
||||
// set filament
|
||||
if (!is_virtual_tray()) {
|
||||
obj->command_ams_filament_settings(ams_id, tray_id, ams_filament_id, ams_setting_id, std::string(col_buf), m_filament_type, nozzle_temp_min_int, nozzle_temp_max_int);
|
||||
if (obj->is_support_filament_edit_virtual_tray || !is_virtual_tray()) {
|
||||
if (is_virtual_tray()) {
|
||||
obj->command_ams_filament_settings(255, VIRTUAL_TRAY_ID, ams_filament_id, ams_setting_id, std::string(col_buf), m_filament_type, nozzle_temp_min_int, nozzle_temp_max_int);
|
||||
} else {
|
||||
obj->command_ams_filament_settings(ams_id, tray_id, ams_filament_id, ams_setting_id, std::string(col_buf), m_filament_type, nozzle_temp_min_int, nozzle_temp_max_int);
|
||||
}
|
||||
}
|
||||
|
||||
// set k / n value
|
||||
|
|
@ -548,7 +560,10 @@ void AMSMaterialsSetting::update_widgets()
|
|||
{
|
||||
// virtual tray
|
||||
if (is_virtual_tray()) {
|
||||
m_panel_normal->Hide();
|
||||
if (obj && obj->is_support_filament_edit_virtual_tray)
|
||||
m_panel_normal->Show();
|
||||
else
|
||||
m_panel_normal->Hide();
|
||||
m_panel_kn->Show();
|
||||
} else if (obj && obj->is_function_supported(PrinterFunction::FUNC_EXTRUSION_CALI)) {
|
||||
m_panel_normal->Show();
|
||||
|
|
@ -583,7 +598,7 @@ void AMSMaterialsSetting::Popup(wxString filament, wxString sn, wxString temp_mi
|
|||
m_input_k_val->GetTextCtrl()->SetValue(k);
|
||||
m_input_n_val->GetTextCtrl()->SetValue(n);
|
||||
|
||||
if (is_virtual_tray()) {
|
||||
if (is_virtual_tray() && obj && !obj->is_support_filament_edit_virtual_tray) {
|
||||
m_button_confirm->Show();
|
||||
update();
|
||||
Layout();
|
||||
|
|
@ -609,7 +624,8 @@ void AMSMaterialsSetting::Popup(wxString filament, wxString sn, wxString temp_mi
|
|||
m_panel_SN->Show();
|
||||
m_comboBox_filament->Hide();
|
||||
m_readonly_filament->Show();
|
||||
m_readonly_filament->GetTextCtrl()->SetLabel("Bambu " + filament);
|
||||
//m_readonly_filament->GetTextCtrl()->SetLabel("Bambu " + filament);
|
||||
m_readonly_filament->SetLabel("Bambu " + filament);
|
||||
m_input_nozzle_min->GetTextCtrl()->SetValue(temp_min);
|
||||
m_input_nozzle_max->GetTextCtrl()->SetValue(temp_max);
|
||||
|
||||
|
|
@ -712,6 +728,31 @@ void AMSMaterialsSetting::on_select_filament(wxCommandEvent &evt)
|
|||
if (preset_bundle) {
|
||||
for (auto it = preset_bundle->filaments.begin(); it != preset_bundle->filaments.end(); it++) {
|
||||
if (it->alias.compare(m_comboBox_filament->GetValue().ToStdString()) == 0) {
|
||||
|
||||
//check is it in the filament blacklist
|
||||
bool in_blacklist = false;
|
||||
std::string action;
|
||||
std::string info;
|
||||
std::string filamnt_type;
|
||||
it->get_filament_type(filamnt_type);
|
||||
|
||||
if (it->vendor) {
|
||||
DeviceManager::check_filaments_in_blacklist(it->vendor->name, filamnt_type, in_blacklist, action, info);
|
||||
}
|
||||
|
||||
if (in_blacklist) {
|
||||
if (action == "prohibition") {
|
||||
MessageDialog msg_wingow(nullptr, info, _L("Error"), wxICON_WARNING | wxOK);
|
||||
msg_wingow.ShowModal();
|
||||
m_comboBox_filament->SetSelection(m_filament_selection);
|
||||
return;
|
||||
}
|
||||
else if (action == "warning") {
|
||||
MessageDialog msg_wingow(nullptr, info, _L("Warning"), wxICON_INFORMATION | wxOK);
|
||||
msg_wingow.ShowModal();
|
||||
}
|
||||
}
|
||||
|
||||
// ) if nozzle_temperature_range is found
|
||||
ConfigOption* opt_min = it->config.option("nozzle_temperature_range_low");
|
||||
if (opt_min) {
|
||||
|
|
@ -742,6 +783,8 @@ void AMSMaterialsSetting::on_select_filament(wxCommandEvent &evt)
|
|||
}
|
||||
if (!found_filament_type)
|
||||
m_filament_type = "";
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -751,6 +794,8 @@ void AMSMaterialsSetting::on_select_filament(wxCommandEvent &evt)
|
|||
if (m_input_nozzle_max->GetTextCtrl()->GetValue().IsEmpty()) {
|
||||
m_input_nozzle_max->GetTextCtrl()->SetValue("220");
|
||||
}
|
||||
|
||||
m_filament_selection = evt.GetSelection();
|
||||
}
|
||||
|
||||
void AMSMaterialsSetting::on_dpi_changed(const wxRect &suggested_rect) { this->Refresh(); }
|
||||
|
|
|
|||
|
|
@ -98,13 +98,14 @@ protected:
|
|||
TextInput* m_input_k_val;
|
||||
wxStaticText* m_n_param;
|
||||
TextInput* m_input_n_val;
|
||||
int m_filament_selection;
|
||||
|
||||
#ifdef __APPLE__
|
||||
wxComboBox *m_comboBox_filament;
|
||||
#else
|
||||
ComboBox *m_comboBox_filament;
|
||||
#endif
|
||||
TextInput* m_readonly_filament;
|
||||
TextInput* m_readonly_filament;
|
||||
};
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
|
|
|
|||
|
|
@ -53,9 +53,9 @@ void AMSSetting::create()
|
|||
m_sizer_Insert_material_tip->Add(0, 0, 0, wxLEFT, 10);
|
||||
|
||||
// tip line1
|
||||
m_tip_Insert_material_line1 = new wxStaticText(m_panel_body, wxID_ANY,
|
||||
_L("The AMS will automatically read the filament information when inserting a new Bambu Lab filament. This takes about 20 seconds."),
|
||||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_tip_Insert_material_line1 = new Label(m_panel_body,
|
||||
_L("The AMS will automatically read the filament information when inserting a new Bambu Lab filament. This takes about 20 seconds.")
|
||||
);
|
||||
m_tip_Insert_material_line1->SetFont(::Label::Body_13);
|
||||
m_tip_Insert_material_line1->SetForegroundColour(AMS_SETTING_GREY700);
|
||||
m_tip_Insert_material_line1->SetSize(wxSize(AMS_SETTING_BODY_WIDTH, -1));
|
||||
|
|
@ -64,9 +64,9 @@ void AMSSetting::create()
|
|||
m_sizer_Insert_material_tip_inline->Add(m_tip_Insert_material_line1, 0, wxEXPAND, 0);
|
||||
|
||||
// tip line2
|
||||
m_tip_Insert_material_line2 = new wxStaticText(m_panel_body, wxID_ANY,
|
||||
_L("Note: if new filament is inserted during printing, the AMS will not automatically read any information until printing is completed."),
|
||||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_tip_Insert_material_line2 = new Label(m_panel_body,
|
||||
_L("Note: if new filament is inserted during printing, the AMS will not automatically read any information until printing is completed.")
|
||||
);
|
||||
m_tip_Insert_material_line2->SetFont(::Label::Body_13);
|
||||
m_tip_Insert_material_line2->SetForegroundColour(AMS_SETTING_GREY700);
|
||||
m_tip_Insert_material_line2->SetSize(wxSize(AMS_SETTING_BODY_WIDTH, -1));
|
||||
|
|
@ -75,10 +75,9 @@ void AMSSetting::create()
|
|||
m_sizer_Insert_material_tip_inline->Add(m_tip_Insert_material_line2, 0, wxEXPAND | wxTOP, 8);
|
||||
|
||||
// tip line2
|
||||
m_tip_Insert_material_line3 =
|
||||
new wxStaticText(m_panel_body, wxID_ANY,
|
||||
_L("When inserting a new filament, the AMS will not automatically read its information, leaving it blank for you to enter manually."),
|
||||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_tip_Insert_material_line3 = new Label(m_panel_body,
|
||||
_L("When inserting a new filament, the AMS will not automatically read its information, leaving it blank for you to enter manually.")
|
||||
);
|
||||
m_tip_Insert_material_line3->SetFont(::Label::Body_13);
|
||||
m_tip_Insert_material_line3->SetForegroundColour(AMS_SETTING_GREY700);
|
||||
m_tip_Insert_material_line3->SetSize(wxSize(AMS_SETTING_BODY_WIDTH, -1));
|
||||
|
|
@ -109,18 +108,18 @@ void AMSSetting::create()
|
|||
// tip line
|
||||
m_sizer_starting_tip_inline = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_tip_starting_line1 = new wxStaticText(m_panel_body, wxID_ANY,
|
||||
_L("The AMS will automatically read the information of inserted filament on start-up. It will take about 1 minute.The reading process will roll filament spools."),
|
||||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_tip_starting_line1 = new Label(m_panel_body,
|
||||
_L("The AMS will automatically read the information of inserted filament on start-up. It will take about 1 minute.The reading process will roll filament spools.")
|
||||
);
|
||||
m_tip_starting_line1->SetFont(::Label::Body_13);
|
||||
m_tip_starting_line1->SetForegroundColour(AMS_SETTING_GREY700);
|
||||
m_tip_starting_line1->SetSize(wxSize(AMS_SETTING_BODY_WIDTH, -1));
|
||||
m_tip_starting_line1->Wrap(AMS_SETTING_BODY_WIDTH);
|
||||
m_sizer_starting_tip_inline->Add(m_tip_starting_line1, 0, wxEXPAND, 0);
|
||||
|
||||
m_tip_starting_line2 = new wxStaticText(m_panel_body, wxID_ANY,
|
||||
_L("The AMS will not automatically read information from inserted filament during startup and will continue to use the information recorded before the last shutdown."),
|
||||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_tip_starting_line2 = new Label(m_panel_body,
|
||||
_L("The AMS will not automatically read information from inserted filament during startup and will continue to use the information recorded before the last shutdown.")
|
||||
);
|
||||
m_tip_starting_line2->SetFont(::Label::Body_13);
|
||||
m_tip_starting_line2->SetForegroundColour(AMS_SETTING_GREY700);
|
||||
m_tip_starting_line2->SetSize(wxSize(AMS_SETTING_BODY_WIDTH, -1));
|
||||
|
|
@ -148,9 +147,9 @@ void AMSSetting::create()
|
|||
// tip line
|
||||
m_sizer_remain_inline = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_tip_remain_line1 = new wxStaticText(m_panel_body, wxID_ANY,
|
||||
_L("The AMS will estimate Bambu filament's remaining capacity after the filament info is updated. During printing, remaining capacity will be updated automatically."),
|
||||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_tip_remain_line1 = new Label(m_panel_body,
|
||||
_L("The AMS will estimate Bambu filament's remaining capacity after the filament info is updated. During printing, remaining capacity will be updated automatically.")
|
||||
);
|
||||
m_tip_remain_line1->SetFont(::Label::Body_13);
|
||||
m_tip_remain_line1->SetForegroundColour(AMS_SETTING_GREY700);
|
||||
m_tip_remain_line1->SetSize(wxSize(AMS_SETTING_BODY_WIDTH, -1));
|
||||
|
|
@ -178,9 +177,9 @@ void AMSSetting::create()
|
|||
// tip line
|
||||
m_sizer_switch_filament_inline = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_tip_switch_filament_line1 = new wxStaticText(m_panel_body, wxID_ANY,
|
||||
_L("AMS will continue to another spool with the same properties of filament automatically when current filament runs out"),
|
||||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_tip_switch_filament_line1 = new Label(m_panel_body,
|
||||
_L("AMS will continue to another spool with the same properties of filament automatically when current filament runs out")
|
||||
);
|
||||
m_tip_switch_filament_line1->SetFont(::Label::Body_13);
|
||||
m_tip_switch_filament_line1->SetForegroundColour(AMS_SETTING_GREY700);
|
||||
m_tip_switch_filament_line1->SetSize(wxSize(AMS_SETTING_BODY_WIDTH, -1));
|
||||
|
|
|
|||
|
|
@ -49,22 +49,22 @@ protected:
|
|||
wxPanel * m_panel_body;
|
||||
CheckBox * m_checkbox_Insert_material_auto_read;
|
||||
wxStaticText *m_title_Insert_material_auto_read;
|
||||
wxStaticText *m_tip_Insert_material_line1;
|
||||
wxStaticText *m_tip_Insert_material_line2;
|
||||
wxStaticText *m_tip_Insert_material_line3;
|
||||
Label* m_tip_Insert_material_line1;
|
||||
Label* m_tip_Insert_material_line2;
|
||||
Label* m_tip_Insert_material_line3;
|
||||
|
||||
CheckBox * m_checkbox_starting_auto_read;
|
||||
wxStaticText *m_title_starting_auto_read;
|
||||
wxStaticText *m_tip_starting_line1;
|
||||
wxStaticText *m_tip_starting_line2;
|
||||
Label* m_tip_starting_line1;
|
||||
Label* m_tip_starting_line2;
|
||||
|
||||
CheckBox * m_checkbox_remain;
|
||||
wxStaticText *m_title_remain;
|
||||
wxStaticText *m_tip_remain_line1;
|
||||
Label* m_tip_remain_line1;
|
||||
|
||||
CheckBox* m_checkbox_switch_filament;
|
||||
wxStaticText* m_title_switch_filament;
|
||||
wxStaticText* m_tip_switch_filament_line1;
|
||||
Label* m_tip_switch_filament_line1;
|
||||
|
||||
wxStaticText *m_tip_ams_img;
|
||||
Button * m_button_auto_demarcate;
|
||||
|
|
|
|||
|
|
@ -257,6 +257,13 @@ AboutDialog::AboutDialog()
|
|||
version->SetBackgroundColour(wxColour("#009688"));
|
||||
|
||||
vesizer->Add(version, 0, wxALL | wxALIGN_CENTER_HORIZONTAL, FromDIP(5));
|
||||
#if BBL_INTERNAL_TESTING
|
||||
wxString build_time = wxString::Format("Build Time: %s", std::string(SLIC3R_BUILD_TIME));
|
||||
wxStaticText* build_time_text = new wxStaticText(this, wxID_ANY, build_time, wxDefaultPosition, wxDefaultSize);
|
||||
build_time_text->SetForegroundColour(wxColour("#FFFFFE"));
|
||||
build_time_text->SetBackgroundColour(wxColour("#00AF42"));
|
||||
vesizer->Add(build_time_text, 0, wxALL | wxALIGN_CENTER_HORIZONTAL, FromDIP(5));
|
||||
#endif
|
||||
vesizer->Add(0, 0, 1, wxEXPAND, FromDIP(5));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -207,11 +207,11 @@ void MaterialItem::doRender(wxDC &dc)
|
|||
}
|
||||
|
||||
AmsMapingPopup::AmsMapingPopup(wxWindow *parent)
|
||||
:wxPopupTransientWindow(parent, wxBORDER_NONE)
|
||||
: PopupWindow(parent, wxBORDER_NONE)
|
||||
{
|
||||
SetSize(wxSize(FromDIP(300), -1));
|
||||
SetMinSize(wxSize(FromDIP(300), -1));
|
||||
SetMaxSize(wxSize(FromDIP(300), -1));
|
||||
SetSize(wxSize(FromDIP(252), -1));
|
||||
SetMinSize(wxSize(FromDIP(252), -1));
|
||||
SetMaxSize(wxSize(FromDIP(252), -1));
|
||||
Bind(wxEVT_PAINT, &AmsMapingPopup::paintEvent, this);
|
||||
|
||||
|
||||
|
|
@ -243,21 +243,36 @@ void MaterialItem::doRender(wxDC &dc)
|
|||
title_panel->Fit();
|
||||
|
||||
m_sizer_list = new wxBoxSizer(wxVERTICAL);
|
||||
for (auto i = 0; i < AMS_TOTAL_COUNT; i++) {
|
||||
auto sizer_mapping_list = new wxBoxSizer(wxHORIZONTAL);
|
||||
/*auto ams_mapping_item_container = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap("ams_mapping_container", this, 78), wxDefaultPosition,
|
||||
wxSize(FromDIP(230), FromDIP(78)), 0);*/
|
||||
auto ams_mapping_item_container = new MappingContainer(this);
|
||||
ams_mapping_item_container->SetSizer(sizer_mapping_list);
|
||||
ams_mapping_item_container->Layout();
|
||||
//ams_mapping_item_container->Hide();
|
||||
m_amsmapping_container_sizer_list.push_back(sizer_mapping_list);
|
||||
m_amsmapping_container_list.push_back(ams_mapping_item_container);
|
||||
m_sizer_list->Add(ams_mapping_item_container, 0, wxALIGN_CENTER_HORIZONTAL|wxTOP|wxBOTTOM, FromDIP(5));
|
||||
}
|
||||
|
||||
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_warning_text->SetMinSize(wxSize(FromDIP(248), FromDIP(-1)));
|
||||
m_warning_text->Wrap(FromDIP(248));
|
||||
|
||||
m_sizer_main->Add(title_panel, 0, wxEXPAND | wxALL, FromDIP(2));
|
||||
m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(5));
|
||||
m_sizer_main->Add(m_sizer_list, 0, wxEXPAND | wxALL, FromDIP(0));
|
||||
m_sizer_main->Add(m_warning_text, 0, wxEXPAND | wxALL, FromDIP(10));
|
||||
m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(5));
|
||||
m_sizer_main->Add(m_warning_text, 0, wxEXPAND | wxALL, FromDIP(6));
|
||||
|
||||
SetSizer(m_sizer_main);
|
||||
Layout();
|
||||
Fit();
|
||||
}
|
||||
|
||||
wxString AmsMapingPopup::format_text(wxString &m_msg)
|
||||
|
|
@ -315,15 +330,29 @@ 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); }
|
||||
m_amsmapping_sizer_list.clear();
|
||||
//m_mapping_item_list.clear();
|
||||
|
||||
for (auto& ams_container : m_amsmapping_container_list) {
|
||||
ams_container->Hide();
|
||||
}
|
||||
|
||||
|
||||
for (wxWindow *mitem : m_mapping_item_list) {
|
||||
mitem->Destroy();
|
||||
mitem = nullptr;
|
||||
}
|
||||
m_mapping_item_list.clear();
|
||||
|
||||
if (m_amsmapping_container_sizer_list.size() > 0) {
|
||||
for (wxBoxSizer *siz : m_amsmapping_container_sizer_list) {
|
||||
siz->Clear(true);
|
||||
}
|
||||
}
|
||||
|
||||
std::map<std::string, Ams *>::iterator ams_iter;
|
||||
|
||||
BOOST_LOG_TRIVIAL(trace) << "ams_mapping total count " << amsList.size();
|
||||
int m_amsmapping_container_list_index = 0;
|
||||
|
||||
for (ams_iter = amsList.begin(); ams_iter != amsList.end(); ams_iter++) {
|
||||
|
||||
|
|
@ -355,7 +384,10 @@ void AmsMapingPopup::update_ams_data(std::map<std::string, Ams*> amsList)
|
|||
|
||||
tray_datas.push_back(td);
|
||||
}
|
||||
add_ams_mapping(tray_datas);
|
||||
|
||||
m_amsmapping_container_list[m_amsmapping_container_list_index]->Show();
|
||||
add_ams_mapping(tray_datas, m_amsmapping_container_list[m_amsmapping_container_list_index], m_amsmapping_container_sizer_list[m_amsmapping_container_list_index]);
|
||||
m_amsmapping_container_list_index++;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -406,40 +438,38 @@ std::vector<TrayData> AmsMapingPopup::parse_ams_mapping(std::map<std::string, Am
|
|||
return m_tray_data;
|
||||
}
|
||||
|
||||
void AmsMapingPopup::add_ams_mapping(std::vector<TrayData> tray_data)
|
||||
void AmsMapingPopup::add_ams_mapping(std::vector<TrayData> tray_data, wxWindow* container, wxBoxSizer* sizer)
|
||||
{
|
||||
auto sizer_mapping_list = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
sizer->Add(0,0,0,wxLEFT,FromDIP(6));
|
||||
for (auto i = 0; i < tray_data.size(); i++) {
|
||||
wxBoxSizer *sizer_mapping_item = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
// set number
|
||||
auto number = new wxStaticText(this, wxID_ANY, wxGetApp().transition_tridid(tray_data[i].id), wxDefaultPosition, wxDefaultSize, 0);
|
||||
/* auto number = new wxStaticText(this, wxID_ANY, wxGetApp().transition_tridid(tray_data[i].id), wxDefaultPosition, wxDefaultSize, 0);
|
||||
number->SetFont(::Label::Body_13);
|
||||
number->SetForegroundColour(wxColour(0X6B, 0X6B, 0X6B));
|
||||
number->Wrap(-1);
|
||||
number->Wrap(-1);*/
|
||||
|
||||
|
||||
// set button
|
||||
MappingItem *m_filament_name = new MappingItem(this);
|
||||
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);
|
||||
|
||||
MappingItem *m_mapping_item = new MappingItem(container);
|
||||
m_mapping_item->SetSize(wxSize(FromDIP(68 * 0.7), FromDIP(100 * 0.6)));
|
||||
m_mapping_item->SetMinSize(wxSize(FromDIP(68 * 0.7), FromDIP(100 * 0.6)));
|
||||
m_mapping_item->SetMaxSize(wxSize(FromDIP(68 * 0.7), FromDIP(100 * 0.6)));
|
||||
//m_mapping_item->SetCornerRadius(5);
|
||||
m_mapping_item->SetFont(::Label::Body_12);
|
||||
m_mapping_item_list.push_back(m_mapping_item);
|
||||
|
||||
if (tray_data[i].type == NORMAL) {
|
||||
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]);
|
||||
m_mapping_item->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_mapping_item->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) {
|
||||
m_mapping_item->Bind(wxEVT_LEFT_DOWN, [this, tray_data, i, m_mapping_item](wxMouseEvent &e) {
|
||||
if (!is_match_material(tray_data[i].filament_type)) return;
|
||||
m_filament_name->send_event(m_current_filament_id);
|
||||
m_mapping_item->send_event(m_current_filament_id);
|
||||
Dismiss();
|
||||
});
|
||||
}
|
||||
|
|
@ -447,29 +477,30 @@ void AmsMapingPopup::add_ams_mapping(std::vector<TrayData> tray_data)
|
|||
|
||||
// temp
|
||||
if (tray_data[i].type == EMPTY) {
|
||||
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);
|
||||
m_mapping_item->set_data(wxColour(0xCE, 0xCE, 0xCE), "-", tray_data[i]);
|
||||
m_mapping_item->Bind(wxEVT_LEFT_DOWN, [this, tray_data, i, m_mapping_item](wxMouseEvent &e) {
|
||||
m_mapping_item->send_event(m_current_filament_id);
|
||||
Dismiss();
|
||||
});
|
||||
}
|
||||
|
||||
// third party
|
||||
if (tray_data[i].type == THIRD) {
|
||||
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);
|
||||
m_mapping_item->set_data(wxColour(0xCE, 0xCE, 0xCE), "?", tray_data[i]);
|
||||
m_mapping_item->Bind(wxEVT_LEFT_DOWN, [this, tray_data, i, m_mapping_item](wxMouseEvent &e) {
|
||||
m_mapping_item->send_event(m_current_filament_id);
|
||||
Dismiss();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
sizer_mapping_item->Add(number, 0, wxALIGN_CENTER_HORIZONTAL, 0);
|
||||
sizer_mapping_item->Add(m_filament_name, 0, wxALIGN_CENTER_HORIZONTAL, 0);
|
||||
sizer_mapping_list->Add(sizer_mapping_item, 0, wxALL, FromDIP(5));
|
||||
m_amsmapping_sizer_list.push_back(sizer_mapping_list);
|
||||
//sizer_mapping_item->Add(number, 0, wxALIGN_CENTER_HORIZONTAL, 0);
|
||||
//sizer_mapping_item->Add(m_mapping_item, 0, wxALIGN_CENTER_HORIZONTAL, 0);
|
||||
m_mapping_item->set_tray_index(wxGetApp().transition_tridid(tray_data[i].id));
|
||||
sizer->Add(0,0,0,wxRIGHT,FromDIP(6));
|
||||
sizer->Add(m_mapping_item, 0, wxTOP, FromDIP(1));
|
||||
}
|
||||
m_sizer_list->Add(sizer_mapping_list, 0, wxALIGN_CENTER_HORIZONTAL, 0);
|
||||
|
||||
}
|
||||
|
||||
void AmsMapingPopup::OnDismiss()
|
||||
|
|
@ -479,7 +510,7 @@ void AmsMapingPopup::OnDismiss()
|
|||
|
||||
bool AmsMapingPopup::ProcessLeftDown(wxMouseEvent &event)
|
||||
{
|
||||
return wxPopupTransientWindow::ProcessLeftDown(event);
|
||||
return PopupWindow::ProcessLeftDown(event);
|
||||
}
|
||||
|
||||
void AmsMapingPopup::paintEvent(wxPaintEvent &evt)
|
||||
|
|
@ -514,7 +545,7 @@ void MappingItem::send_event(int fliament_id)
|
|||
wxString param = wxString::Format("%d|%d|%d|%s|%d", m_coloul.Red(), m_coloul.Green(), m_coloul.Blue(), number, fliament_id);
|
||||
event.SetString(param);
|
||||
event.SetEventObject(this->GetParent()->GetParent());
|
||||
wxPostEvent(this->GetParent()->GetParent(), event);
|
||||
wxPostEvent(this->GetParent()->GetParent()->GetParent(), event);
|
||||
}
|
||||
|
||||
void MappingItem::msw_rescale()
|
||||
|
|
@ -551,7 +582,7 @@ void MappingItem::render(wxDC &dc)
|
|||
#endif
|
||||
|
||||
// materials name
|
||||
dc.SetFont(::Label::Body_12);
|
||||
dc.SetFont(::Label::Head_13);
|
||||
|
||||
auto txt_colour = m_coloul.GetLuminance() < 0.5 ? *wxWHITE : wxColour(0x26, 0x2E, 0x30);
|
||||
txt_colour = m_unmatch ? wxColour(0xCE, 0xCE, 0xCE) : txt_colour;
|
||||
|
|
@ -563,8 +594,15 @@ void MappingItem::render(wxDC &dc)
|
|||
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));
|
||||
auto txt_size = dc.GetTextExtent(m_tray_index);
|
||||
auto top = (GetSize().y - MAPPING_ITEM_REAL_SIZE.y) / 2 + FromDIP(8);
|
||||
dc.DrawText(m_tray_index, wxPoint((GetSize().x - txt_size.x) / 2, top));
|
||||
|
||||
|
||||
top += txt_size.y + FromDIP(7);
|
||||
dc.SetFont(::Label::Body_12);
|
||||
txt_size = dc.GetTextExtent(m_name);
|
||||
dc.DrawText(m_name, wxPoint((GetSize().x - txt_size.x) / 2, top));
|
||||
}
|
||||
|
||||
void MappingItem::set_data(wxColour colour, wxString name, TrayData data, bool unmatch)
|
||||
|
|
@ -582,21 +620,32 @@ void MappingItem::doRender(wxDC &dc)
|
|||
{
|
||||
dc.SetPen(m_coloul);
|
||||
dc.SetBrush(wxBrush(m_coloul));
|
||||
dc.DrawRoundedRectangle(0, 0, GetSize().x, GetSize().y,5);
|
||||
if (m_coloul == *wxWHITE) {
|
||||
dc.SetPen(wxPen(wxColour(0xAC, 0xAC, 0xAC),1));
|
||||
#ifdef __APPLE__
|
||||
dc.DrawRoundedRectangle(1, 1, GetSize().x - 1, GetSize().y - 1, 5);
|
||||
#else
|
||||
dc.DrawRoundedRectangle(0, 0, GetSize().x, GetSize().y, 5);
|
||||
#endif // __APPLE__
|
||||
dc.DrawRectangle(0, (GetSize().y - MAPPING_ITEM_REAL_SIZE.y) / 2, MAPPING_ITEM_REAL_SIZE.x, MAPPING_ITEM_REAL_SIZE.y);
|
||||
|
||||
|
||||
}
|
||||
// if (m_coloul == *wxWHITE) {
|
||||
// dc.SetPen(wxPen(wxColour(0xAC, 0xAC, 0xAC), 1));
|
||||
//#ifdef __APPLE__
|
||||
// dc.DrawRectangle(1, 1, GetSize().x - 1, GetSize().y - 1);
|
||||
//#else
|
||||
// dc.DrawRectangle(0, 0, tray_size.x, tray_size.y);
|
||||
//#endif // __APPLE__
|
||||
// }
|
||||
|
||||
wxColour side_colour = wxColour(0xE4E4E4);
|
||||
|
||||
dc.SetPen(side_colour);
|
||||
dc.SetBrush(wxBrush(side_colour));
|
||||
#ifdef __APPLE__
|
||||
dc.DrawRectangle(0, 0, FromDIP(4), GetSize().y);
|
||||
dc.DrawRectangle(GetSize().x - FromDIP(4), 0, FromDIP(4), GetSize().y);
|
||||
#else
|
||||
dc.DrawRectangle(0, 0, FromDIP(4), GetSize().y);
|
||||
dc.DrawRectangle(GetSize().x - FromDIP(4), 0, FromDIP(4), GetSize().y);
|
||||
#endif // __APPLE__
|
||||
}
|
||||
|
||||
AmsMapingTipPopup::AmsMapingTipPopup(wxWindow *parent)
|
||||
:wxPopupTransientWindow(parent, wxBORDER_NONE)
|
||||
:PopupWindow(parent, wxBORDER_NONE)
|
||||
{
|
||||
SetBackgroundColour(*wxWHITE);
|
||||
wxBoxSizer *m_sizer_main = new wxBoxSizer(wxVERTICAL);
|
||||
|
|
@ -696,11 +745,11 @@ void AmsMapingTipPopup::paintEvent(wxPaintEvent &evt)
|
|||
void AmsMapingTipPopup::OnDismiss() {}
|
||||
|
||||
bool AmsMapingTipPopup::ProcessLeftDown(wxMouseEvent &event) {
|
||||
return wxPopupTransientWindow::ProcessLeftDown(event); }
|
||||
return PopupWindow::ProcessLeftDown(event); }
|
||||
|
||||
|
||||
AmsHumidityTipPopup::AmsHumidityTipPopup(wxWindow* parent)
|
||||
:wxPopupTransientWindow(parent, wxBORDER_NONE)
|
||||
:PopupWindow(parent, wxBORDER_NONE)
|
||||
{
|
||||
SetBackgroundColour(*wxWHITE);
|
||||
|
||||
|
|
@ -727,7 +776,7 @@ AmsHumidityTipPopup::AmsHumidityTipPopup(wxWindow* parent)
|
|||
m_staticText1->SetFont(::Label::Head_13);
|
||||
|
||||
|
||||
m_staticText2 = new Label(this, _L("Green means that AMS humidity is normal, orange represent humidity is high, red represent humidity is too high.(Hygrometer: lower the better, The bars: higher the better)"));
|
||||
m_staticText2 = new Label(this, _L("Green means that AMS humidity is normal, orange represent humidity is high, red represent humidity is too high.(Hygrometer: lower the better.)"));
|
||||
m_staticText2->SetFont(::Label::Body_13);
|
||||
m_staticText2->SetSize(wxSize(FromDIP(360), -1));
|
||||
m_staticText2->SetMinSize(wxSize(FromDIP(360), -1));
|
||||
|
|
@ -740,7 +789,7 @@ AmsHumidityTipPopup::AmsHumidityTipPopup(wxWindow* parent)
|
|||
m_staticText3->SetFont(::Label::Head_13);
|
||||
|
||||
|
||||
m_staticText4 = new Label(this, _L("A desiccant status lower than two bars indicates that desiccant may be inactive. Please change the desiccant. (Higher is better)"));
|
||||
m_staticText4 = new Label(this, _L("A desiccant status lower than two bars indicates that desiccant may be inactive. Please change the desiccant.(The bars: higher the better.)"));
|
||||
m_staticText4->SetFont(::Label::Body_13);
|
||||
m_staticText4->SetSize(wxSize(FromDIP(360), -1));
|
||||
m_staticText4->SetMinSize(wxSize(FromDIP(360), -1));
|
||||
|
|
@ -766,9 +815,9 @@ AmsHumidityTipPopup::AmsHumidityTipPopup(wxWindow* parent)
|
|||
main_sizer->Add(m_staticText_note, 0, wxALL | wxLEFT | wxRIGHT, 34);
|
||||
|
||||
m_button_confirm = new Button(this, _L("OK"));
|
||||
StateColor btn_bg_green(std::pair<wxColour, int>(wxColour(27, 136, 68), StateColor::Pressed), std::pair<wxColour, int>(wxColour(0, 150, 136), StateColor::Normal));
|
||||
StateColor btn_bg_green(std::pair<wxColour, int>(wxColour(27, 136, 68), StateColor::Pressed), std::pair<wxColour, int>(wxColour(0, 174, 66), StateColor::Normal));
|
||||
m_button_confirm->SetBackgroundColor(btn_bg_green);
|
||||
m_button_confirm->SetBorderColor(wxColour(0, 150, 136));
|
||||
m_button_confirm->SetBorderColor(wxColour(0, 174, 66));
|
||||
m_button_confirm->SetTextColor(wxColour(0xFFFFFE));
|
||||
m_button_confirm->SetSize(wxSize(FromDIP(72), FromDIP(24)));
|
||||
m_button_confirm->SetMinSize(wxSize(FromDIP(72), FromDIP(24)));
|
||||
|
|
@ -814,11 +863,11 @@ void AmsHumidityTipPopup::paintEvent(wxPaintEvent& evt)
|
|||
void AmsHumidityTipPopup::OnDismiss() {}
|
||||
|
||||
bool AmsHumidityTipPopup::ProcessLeftDown(wxMouseEvent& event) {
|
||||
return wxPopupTransientWindow::ProcessLeftDown(event);
|
||||
return PopupWindow::ProcessLeftDown(event);
|
||||
}
|
||||
|
||||
AmsTutorialPopup::AmsTutorialPopup(wxWindow* parent)
|
||||
:wxPopupTransientWindow(parent, wxBORDER_NONE)
|
||||
:PopupWindow(parent, wxBORDER_NONE)
|
||||
{
|
||||
Bind(wxEVT_PAINT, &AmsTutorialPopup::paintEvent, this);
|
||||
SetBackgroundColour(*wxWHITE);
|
||||
|
|
@ -916,12 +965,12 @@ void AmsTutorialPopup::paintEvent(wxPaintEvent& evt)
|
|||
void AmsTutorialPopup::OnDismiss() {}
|
||||
|
||||
bool AmsTutorialPopup::ProcessLeftDown(wxMouseEvent& event) {
|
||||
return wxPopupTransientWindow::ProcessLeftDown(event);
|
||||
return PopupWindow::ProcessLeftDown(event);
|
||||
}
|
||||
|
||||
|
||||
AmsIntroducePopup::AmsIntroducePopup(wxWindow* parent)
|
||||
:wxPopupTransientWindow(parent, wxBORDER_NONE)
|
||||
:PopupWindow(parent, wxBORDER_NONE)
|
||||
{
|
||||
Bind(wxEVT_PAINT, &AmsIntroducePopup::paintEvent, this);
|
||||
SetBackgroundColour(*wxWHITE);
|
||||
|
|
@ -1001,8 +1050,60 @@ void AmsIntroducePopup::paintEvent(wxPaintEvent& evt)
|
|||
void AmsIntroducePopup::OnDismiss() {}
|
||||
|
||||
bool AmsIntroducePopup::ProcessLeftDown(wxMouseEvent& event) {
|
||||
return wxPopupTransientWindow::ProcessLeftDown(event);
|
||||
return PopupWindow::ProcessLeftDown(event);
|
||||
}
|
||||
|
||||
|
||||
MappingContainer::MappingContainer(wxWindow* parent)
|
||||
: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize)
|
||||
{
|
||||
#ifdef __WINDOWS__
|
||||
SetDoubleBuffered(true);
|
||||
#endif //__WINDOWS__
|
||||
SetBackgroundColour(StateColor::darkModeColorFor(*wxWHITE));
|
||||
Bind(wxEVT_PAINT, &MappingContainer::paintEvent, this);
|
||||
|
||||
ams_mapping_item_container = create_scaled_bitmap("ams_mapping_container", this, 78);
|
||||
|
||||
SetMinSize(wxSize(FromDIP(230), FromDIP(78)));
|
||||
SetMaxSize(wxSize(FromDIP(230), FromDIP(78)));
|
||||
}
|
||||
|
||||
MappingContainer::~MappingContainer()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void MappingContainer::paintEvent(wxPaintEvent& evt)
|
||||
{
|
||||
wxPaintDC dc(this);
|
||||
render(dc);
|
||||
}
|
||||
|
||||
void MappingContainer::render(wxDC& dc)
|
||||
{
|
||||
#ifdef __WXMSW__
|
||||
wxSize size = GetSize();
|
||||
wxMemoryDC memdc;
|
||||
wxBitmap bmp(size.x, size.y);
|
||||
memdc.SelectObject(bmp);
|
||||
memdc.Blit({ 0, 0 }, size, &dc, { 0, 0 });
|
||||
|
||||
{
|
||||
wxGCDC dc2(memdc);
|
||||
doRender(dc2);
|
||||
}
|
||||
|
||||
memdc.SelectObject(wxNullBitmap);
|
||||
dc.DrawBitmap(bmp, 0, 0);
|
||||
#else
|
||||
doRender(dc);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MappingContainer::doRender(wxDC& dc)
|
||||
{
|
||||
dc.DrawBitmap(ams_mapping_item_container, 0, 0);
|
||||
}
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include "Widgets/CheckBox.hpp"
|
||||
#include "Widgets/ComboBox.hpp"
|
||||
#include "Widgets/ScrolledWindow.hpp"
|
||||
#include "Widgets/PopupWindow.hpp"
|
||||
#include <wx/simplebook.h>
|
||||
#include <wx/hashmap.h>
|
||||
|
||||
|
|
@ -41,6 +42,7 @@ namespace Slic3r { namespace GUI {
|
|||
|
||||
#define MATERIAL_ITEM_SIZE wxSize(FromDIP(64), FromDIP(34))
|
||||
#define MATERIAL_ITEM_REAL_SIZE wxSize(FromDIP(62), FromDIP(32))
|
||||
#define MAPPING_ITEM_REAL_SIZE wxSize(FromDIP(48), FromDIP(45))
|
||||
#define AMS_TOTAL_COUNT 4
|
||||
|
||||
enum TrayType {
|
||||
|
|
@ -95,8 +97,11 @@ public:
|
|||
MappingItem(wxWindow *parent);
|
||||
~MappingItem();
|
||||
|
||||
void update_data(TrayData data);
|
||||
void send_event(int fliament_id);
|
||||
void update_data(TrayData data);
|
||||
void send_event(int fliament_id);
|
||||
void set_tray_index(wxString t_index) {m_tray_index = t_index;};
|
||||
|
||||
wxString m_tray_index;
|
||||
wxColour m_coloul;
|
||||
wxString m_name;
|
||||
TrayData m_tray_data;
|
||||
|
|
@ -109,7 +114,18 @@ public:
|
|||
void doRender(wxDC &dc);
|
||||
};
|
||||
|
||||
class AmsMapingPopup : public wxPopupTransientWindow
|
||||
class MappingContainer : public wxPanel
|
||||
{
|
||||
public:
|
||||
wxBitmap ams_mapping_item_container;
|
||||
MappingContainer(wxWindow* parent);
|
||||
~MappingContainer();
|
||||
void paintEvent(wxPaintEvent& evt);
|
||||
void render(wxDC& dc);
|
||||
void doRender(wxDC& dc);
|
||||
};
|
||||
|
||||
class AmsMapingPopup : public PopupWindow
|
||||
{
|
||||
public:
|
||||
AmsMapingPopup(wxWindow *parent);
|
||||
|
|
@ -118,7 +134,8 @@ public:
|
|||
|
||||
wxStaticText * m_warning_text{nullptr};
|
||||
std::vector<std::string> m_materials_list;
|
||||
std::vector<wxBoxSizer*> m_amsmapping_sizer_list;
|
||||
std::vector<wxBoxSizer*> m_amsmapping_container_sizer_list;
|
||||
std::vector<wxWindow*> m_amsmapping_container_list;
|
||||
std::vector<MappingItem*> m_mapping_item_list;
|
||||
|
||||
bool m_has_unmatch_filament {false};
|
||||
|
|
@ -130,7 +147,7 @@ public:
|
|||
void update_materials_list(std::vector<std::string> list);
|
||||
void set_tag_texture(std::string texture);
|
||||
void update_ams_data(std::map<std::string, Ams *> amsList);
|
||||
void add_ams_mapping(std::vector<TrayData> tray_data);
|
||||
void add_ams_mapping(std::vector<TrayData> tray_data, wxWindow* container, wxBoxSizer* sizer);
|
||||
void set_current_filament_id(int id){m_current_filament_id = id;};
|
||||
int get_current_filament_id(){return m_current_filament_id;};
|
||||
bool is_match_material(std::string material);
|
||||
|
|
@ -141,7 +158,7 @@ public:
|
|||
std::vector<TrayData> parse_ams_mapping(std::map<std::string, Ams*> amsList);
|
||||
};
|
||||
|
||||
class AmsMapingTipPopup : public wxPopupTransientWindow
|
||||
class AmsMapingTipPopup : public PopupWindow
|
||||
{
|
||||
public:
|
||||
AmsMapingTipPopup(wxWindow *parent);
|
||||
|
|
@ -161,7 +178,7 @@ public:
|
|||
wxStaticText * m_tip_disable_ams;
|
||||
};
|
||||
|
||||
class AmsHumidityTipPopup : public wxPopupTransientWindow
|
||||
class AmsHumidityTipPopup : public PopupWindow
|
||||
{
|
||||
public:
|
||||
AmsHumidityTipPopup(wxWindow* parent);
|
||||
|
|
@ -181,7 +198,7 @@ public:
|
|||
Button* m_button_confirm;
|
||||
};
|
||||
|
||||
class AmsTutorialPopup : public wxPopupTransientWindow
|
||||
class AmsTutorialPopup : public PopupWindow
|
||||
{
|
||||
public:
|
||||
Label* text_title;
|
||||
|
|
@ -203,7 +220,7 @@ public:
|
|||
};
|
||||
|
||||
|
||||
class AmsIntroducePopup : public wxPopupTransientWindow
|
||||
class AmsIntroducePopup : public PopupWindow
|
||||
{
|
||||
public:
|
||||
bool is_enable_ams = {false};
|
||||
|
|
|
|||
|
|
@ -492,6 +492,7 @@ void AuFile::on_set_cover()
|
|||
thumbnail_img.SaveFile(encode_path(middle_img_path.c_str()));
|
||||
}
|
||||
|
||||
wxGetApp().plater()->set_plater_dirty(true);
|
||||
auto evt = wxCommandEvent(EVT_AUXILIARY_UPDATE_COVER);
|
||||
evt.SetString(s_default_folders[m_type]);
|
||||
evt.SetEventObject(m_parent);
|
||||
|
|
@ -1099,26 +1100,26 @@ void AuxiliaryPanel::update_all_cover()
|
|||
wxBoxSizer *m_sizer_body = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer *m_sizer_designer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
auto m_text_designer = new wxStaticText(this, wxID_ANY, _L("Author"), wxDefaultPosition, wxSize(120, -1), 0);
|
||||
auto m_text_designer = new wxStaticText(this, wxID_ANY, _L("Author"), wxDefaultPosition, wxSize(180, -1), 0);
|
||||
m_text_designer->Wrap(-1);
|
||||
m_text_designer->SetForegroundColour(*wxBLACK);
|
||||
m_sizer_designer->Add(m_text_designer, 0, wxALIGN_CENTER, 0);
|
||||
|
||||
m_input_designer = new ::TextInput(this, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(450), FromDIP(30)), wxTE_PROCESS_ENTER);
|
||||
m_input_designer->GetTextCtrl()->SetFont(::Label::Body_14);
|
||||
m_input_designer->GetTextCtrl()->SetSize(wxSize(FromDIP(450), FromDIP(22)));
|
||||
m_input_designer->GetTextCtrl()->SetSize(wxSize(FromDIP(450), -1));
|
||||
m_sizer_designer->Add(m_input_designer, 0, wxALIGN_CENTER, 0);
|
||||
|
||||
wxBoxSizer *m_sizer_model_name = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
auto m_text_model_name = new wxStaticText(this, wxID_ANY, _L("Model Name"), wxDefaultPosition, wxSize(120, -1), 0);
|
||||
auto m_text_model_name = new wxStaticText(this, wxID_ANY, _L("Model Name"), wxDefaultPosition, wxSize(180, -1), 0);
|
||||
m_text_model_name->SetForegroundColour(*wxBLACK);
|
||||
m_text_model_name->Wrap(-1);
|
||||
m_sizer_model_name->Add(m_text_model_name, 0, wxALIGN_CENTER, 0);
|
||||
|
||||
m_imput_model_name = new ::TextInput(this, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition,wxSize(FromDIP(450),FromDIP(30)), wxTE_PROCESS_ENTER);
|
||||
m_imput_model_name->GetTextCtrl()->SetFont(::Label::Body_14);
|
||||
m_imput_model_name->GetTextCtrl()->SetSize(wxSize(FromDIP(450), FromDIP(22)));
|
||||
m_imput_model_name->GetTextCtrl()->SetSize(wxSize(FromDIP(450), -1));
|
||||
m_sizer_model_name->Add(m_imput_model_name, 0, wxALIGN_CENTER, 0);
|
||||
|
||||
/*
|
||||
|
|
@ -1224,8 +1225,8 @@ void DesignerPanel::update_info()
|
|||
|
||||
void DesignerPanel::msw_rescale()
|
||||
{
|
||||
m_input_designer->GetTextCtrl()->SetSize(wxSize(FromDIP(450), FromDIP(22)));
|
||||
m_imput_model_name->GetTextCtrl()->SetSize(wxSize(FromDIP(450), FromDIP(22)));
|
||||
m_input_designer->GetTextCtrl()->SetSize(wxSize(FromDIP(450), -1));
|
||||
m_imput_model_name->GetTextCtrl()->SetSize(wxSize(FromDIP(450), -1));
|
||||
}
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
|
|
|
|||
|
|
@ -119,7 +119,8 @@ void BBLStatusBarSend::set_range(int val)
|
|||
|
||||
void BBLStatusBarSend::clear_percent()
|
||||
{
|
||||
set_percent_text(wxEmptyString);
|
||||
//set_percent_text(wxEmptyString);
|
||||
m_cancelbutton->Hide();
|
||||
}
|
||||
|
||||
void BBLStatusBarSend::show_progress(bool show)
|
||||
|
|
@ -235,6 +236,7 @@ void BBLStatusBarSend::set_status_text(const wxString& txt)
|
|||
wxString str;
|
||||
format_text(m_status_text, m_self->FromDIP(280), txt, str);
|
||||
m_status_text->SetLabelText(str);
|
||||
m_self->Layout();
|
||||
//if (is_english_text(str)) m_status_text->Wrap(m_self->FromDIP(280));
|
||||
}
|
||||
|
||||
|
|
@ -279,6 +281,7 @@ bool BBLStatusBarSend::update_status(wxString &msg, bool &was_cancel, int percen
|
|||
|
||||
void BBLStatusBarSend::reset()
|
||||
{
|
||||
m_cancelbutton->Show();
|
||||
set_status_text("");
|
||||
m_was_cancelled = false;
|
||||
set_progress(0);
|
||||
|
|
|
|||
|
|
@ -263,7 +263,7 @@ void BBLTopbar::Init(wxFrame* parent)
|
|||
m_publish_disable_bitmap = create_scaled_bitmap("topbar_publish_disable", nullptr, TOPBAR_ICON_SIZE);
|
||||
m_publish_item->SetDisabledBitmap(m_publish_disable_bitmap);
|
||||
this->EnableTool(m_publish_item->GetId(), false);
|
||||
this->AddSpacer(FromDIP(12));
|
||||
this->AddSpacer(FromDIP(4));
|
||||
|
||||
/*wxBitmap model_store_bitmap = create_scaled_bitmap("topbar_store", nullptr, TOPBAR_ICON_SIZE);
|
||||
m_model_store_item = this->AddTool(ID_MODEL_STORE, "", model_store_bitmap);
|
||||
|
|
@ -271,12 +271,12 @@ void BBLTopbar::Init(wxFrame* parent)
|
|||
*/
|
||||
|
||||
//this->AddSeparator();
|
||||
this->AddSpacer(FromDIP(6));
|
||||
this->AddSpacer(FromDIP(4));
|
||||
|
||||
wxBitmap iconize_bitmap = create_scaled_bitmap("topbar_min", nullptr, TOPBAR_ICON_SIZE);
|
||||
wxAuiToolBarItem* iconize_btn = this->AddTool(wxID_ICONIZE_FRAME, "", iconize_bitmap);
|
||||
|
||||
this->AddSpacer(FromDIP(6));
|
||||
this->AddSpacer(FromDIP(4));
|
||||
|
||||
maximize_bitmap = create_scaled_bitmap("topbar_max", nullptr, TOPBAR_ICON_SIZE);
|
||||
window_bitmap = create_scaled_bitmap("topbar_win", nullptr, TOPBAR_ICON_SIZE);
|
||||
|
|
@ -287,7 +287,7 @@ void BBLTopbar::Init(wxFrame* parent)
|
|||
maximize_btn = this->AddTool(wxID_MAXIMIZE_FRAME, "", maximize_bitmap);
|
||||
}
|
||||
|
||||
this->AddSpacer(FromDIP(6));
|
||||
this->AddSpacer(FromDIP(4));
|
||||
|
||||
wxBitmap close_bitmap = create_scaled_bitmap("topbar_close", nullptr, TOPBAR_ICON_SIZE);
|
||||
wxAuiToolBarItem* close_btn = this->AddTool(wxID_CLOSE_FRAME, "", close_bitmap);
|
||||
|
|
|
|||
|
|
@ -185,14 +185,9 @@ std::string BackgroundSlicingProcess::output_filepath_for_project(const boost::f
|
|||
// from the G-code generator.
|
||||
void BackgroundSlicingProcess::process_fff()
|
||||
{
|
||||
assert(m_print == m_fff_print);
|
||||
PresetBundle &preset_bundle = *wxGetApp().preset_bundle;
|
||||
|
||||
m_fff_print->is_BBL_printer() =
|
||||
preset_bundle.printers.get_edited_preset().is_bbl_vendor_preset(
|
||||
&preset_bundle);
|
||||
|
||||
|
||||
assert(m_print == m_fff_print);
|
||||
PresetBundle &preset_bundle = *wxGetApp().preset_bundle;
|
||||
m_fff_print->is_BBL_printer() = preset_bundle.printers.get_edited_preset().is_bbl_vendor_preset(&preset_bundle);
|
||||
//BBS: add the logic to process from an existed gcode file
|
||||
if (m_print->finished()) {
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" %1%: skip slicing, to process previous gcode file")%__LINE__;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/I18N.hpp"
|
||||
#include "slic3r/Utils/Bonjour.hpp"
|
||||
#include "Widgets/Button.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
|
@ -60,6 +61,8 @@ BonjourDialog::BonjourDialog(wxWindow *parent, Slic3r::PrinterTechnology tech)
|
|||
, timer_state(0)
|
||||
, tech(tech)
|
||||
{
|
||||
SetBackgroundColour(*wxWHITE);
|
||||
|
||||
const int em = GUI::wxGetApp().em_unit();
|
||||
list->SetMinSize(wxSize(80 * em, 30 * em));
|
||||
|
||||
|
|
@ -78,10 +81,39 @@ BonjourDialog::BonjourDialog(wxWindow *parent, Slic3r::PrinterTechnology tech)
|
|||
|
||||
vsizer->Add(list, 1, wxEXPAND | wxALL, em);
|
||||
|
||||
wxBoxSizer *button_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
button_sizer->Add(new wxButton(this, wxID_OK, "OK"), 0, wxALL, em);
|
||||
button_sizer->Add(new wxButton(this, wxID_CANCEL, "Cancel"), 0, wxALL, em);
|
||||
// ^ Note: The Ok/Cancel labels are translated by wxWidgets
|
||||
|
||||
auto button_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
StateColor btn_bg_green(std::pair<wxColour, int>(wxColour(27, 136, 68), StateColor::Pressed), std::pair<wxColour, int>(wxColour(61, 203, 115), StateColor::Hovered),
|
||||
std::pair<wxColour, int>(wxColour(0, 174, 66), StateColor::Normal));
|
||||
|
||||
StateColor btn_bg_white(std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Pressed), std::pair<wxColour, int>(wxColour(238, 238, 238), StateColor::Hovered),
|
||||
std::pair<wxColour, int>(*wxWHITE, StateColor::Normal));
|
||||
|
||||
auto m_button_ok = new Button(this, _L("OK"));
|
||||
m_button_ok->SetBackgroundColor(btn_bg_green);
|
||||
m_button_ok->SetBorderColor(*wxWHITE);
|
||||
m_button_ok->SetTextColor(*wxWHITE);
|
||||
m_button_ok->SetFont(Label::Body_12);
|
||||
m_button_ok->SetSize(wxSize(FromDIP(58), FromDIP(24)));
|
||||
m_button_ok->SetMinSize(wxSize(FromDIP(58), FromDIP(24)));
|
||||
m_button_ok->SetCornerRadius(FromDIP(12));
|
||||
|
||||
m_button_ok->Bind(wxEVT_LEFT_DOWN, [this](auto &e) { this->EndModal(wxID_OK); });
|
||||
|
||||
auto m_button_cancel = new Button(this, _L("Cancel"));
|
||||
m_button_cancel->SetBackgroundColor(btn_bg_white);
|
||||
m_button_cancel->SetBorderColor(wxColour(38, 46, 48));
|
||||
m_button_cancel->SetFont(Label::Body_12);
|
||||
m_button_cancel->SetSize(wxSize(FromDIP(58), FromDIP(24)));
|
||||
m_button_cancel->SetMinSize(wxSize(FromDIP(58), FromDIP(24)));
|
||||
m_button_cancel->SetCornerRadius(FromDIP(12));
|
||||
|
||||
m_button_cancel->Bind(wxEVT_LEFT_DOWN, [this](auto &e) { this->EndModal(wxID_CANCEL); });
|
||||
|
||||
button_sizer->AddStretchSpacer();
|
||||
button_sizer->Add(m_button_ok, 0, wxALL, FromDIP(5));
|
||||
button_sizer->Add(m_button_cancel, 0, wxALL, FromDIP(5));
|
||||
|
||||
vsizer->Add(button_sizer, 0, wxALIGN_CENTER);
|
||||
SetSizerAndFit(vsizer);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ CalibrationDialog::CalibrationDialog(Plater *plater)
|
|||
auto body_panel = new wxPanel(this, wxID_ANY);
|
||||
|
||||
body_panel->SetBackgroundColour(*wxWHITE);
|
||||
auto cali_left_panel = new StaticBox(body_panel, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(303), FromDIP(243)));
|
||||
auto cali_left_panel = new StaticBox(body_panel, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(303), -1));
|
||||
cali_left_panel->SetBackgroundColor(BG_COLOR);
|
||||
cali_left_panel->SetBorderColor(BG_COLOR);
|
||||
|
||||
|
|
@ -73,9 +73,7 @@ CalibrationDialog::CalibrationDialog(Plater *plater)
|
|||
cali_left_sizer->Add(0, 0, 0, wxTOP, FromDIP(5));
|
||||
|
||||
auto cali_left_text_body =
|
||||
new wxStaticText(cali_left_panel, wxID_ANY,
|
||||
_L("The calibration program detects the status of your device automatically to minimize deviation.\nIt keeps the device performing optimally."),
|
||||
wxDefaultPosition, wxSize(FromDIP(260), -1), 0);
|
||||
new Label(cali_left_panel, _L("The calibration program detects the status of your device automatically to minimize deviation.\nIt keeps the device performing optimally."));
|
||||
cali_left_text_body->Wrap(FromDIP(260));
|
||||
cali_left_text_body->SetForegroundColour(wxColour(0x6B, 0x6B, 0x6B));
|
||||
cali_left_text_body->SetBackgroundColour(BG_COLOR);
|
||||
|
|
@ -174,7 +172,6 @@ CalibrationDialog::CalibrationDialog(Plater *plater)
|
|||
Fit();
|
||||
|
||||
m_calibration_btn->Bind(wxEVT_LEFT_DOWN, &CalibrationDialog::on_start_calibration, this);
|
||||
wxGetApp().UpdateDlgDarkUI(this);
|
||||
}
|
||||
|
||||
CalibrationDialog::~CalibrationDialog() {}
|
||||
|
|
@ -296,7 +293,10 @@ void CalibrationDialog::update_machine_obj(MachineObject *obj) { m_obj = obj; }
|
|||
|
||||
bool CalibrationDialog::Show(bool show)
|
||||
{
|
||||
if (show) { CentreOnParent(); }
|
||||
if (show) {
|
||||
wxGetApp().UpdateDlgDarkUI(this);
|
||||
CentreOnParent();
|
||||
}
|
||||
return DPIDialog::Show(show);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@
|
|||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
wxIMPLEMENT_CLASS(CameraPopup, wxPopupTransientWindow);
|
||||
wxIMPLEMENT_CLASS(CameraPopup, PopupWindow);
|
||||
|
||||
wxBEGIN_EVENT_TABLE(CameraPopup, wxPopupTransientWindow)
|
||||
wxBEGIN_EVENT_TABLE(CameraPopup, PopupWindow)
|
||||
EVT_MOUSE_EVENTS(CameraPopup::OnMouse )
|
||||
EVT_SIZE(CameraPopup::OnSize)
|
||||
EVT_SET_FOCUS(CameraPopup::OnSetFocus )
|
||||
|
|
@ -24,10 +24,12 @@ wxEND_EVENT_TABLE()
|
|||
wxDEFINE_EVENT(EVT_VCAMERA_SWITCH, wxMouseEvent);
|
||||
wxDEFINE_EVENT(EVT_SDCARD_ABSENT_HINT, wxCommandEvent);
|
||||
|
||||
#define CAMERAPOPUP_CLICK_INTERVAL 20
|
||||
|
||||
const wxColour TEXT_COL = wxColour(43, 52, 54);
|
||||
|
||||
CameraPopup::CameraPopup(wxWindow *parent, MachineObject* obj)
|
||||
: wxPopupTransientWindow(parent, wxBORDER_NONE | wxPU_CONTAINS_CONTROLS),
|
||||
: PopupWindow(parent, wxBORDER_NONE | wxPU_CONTAINS_CONTROLS),
|
||||
m_obj(obj)
|
||||
{
|
||||
#ifdef __WINDOWS__
|
||||
|
|
@ -84,10 +86,26 @@ CameraPopup::CameraPopup(wxWindow *parent, MachineObject* obj)
|
|||
main_sizer->Add(top_sizer, 0, wxALL, FromDIP(10));
|
||||
|
||||
auto url = wxString::Format(L"https://wiki.bambulab.com/%s/software/bambu-studio/virtual-camera", L"en");
|
||||
vcamera_guide_link = new wxHyperlinkCtrl(m_panel, wxID_ANY, _L("Show \"Live Video\" guide page."),
|
||||
url, wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE);
|
||||
auto text = _L("Show \"Live Video\" guide page.");
|
||||
|
||||
wxBoxSizer* link_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
vcamera_guide_link = new Label(m_panel, text);
|
||||
vcamera_guide_link->Wrap(-1);
|
||||
vcamera_guide_link->SetForegroundColour(wxColour(0x1F, 0x8E, 0xEA));
|
||||
auto text_size = vcamera_guide_link->GetTextExtent(text);
|
||||
vcamera_guide_link->Bind(wxEVT_LEFT_DOWN, [this, url](wxMouseEvent& e) {wxLaunchDefaultBrowser(url); });
|
||||
|
||||
link_underline = new wxPanel(m_panel, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL);
|
||||
link_underline->SetBackgroundColour(wxColour(0x1F, 0x8E, 0xEA));
|
||||
link_underline->SetSize(wxSize(text_size.x, 1));
|
||||
link_underline->SetMinSize(wxSize(text_size.x, 1));
|
||||
|
||||
vcamera_guide_link->Hide();
|
||||
main_sizer->Add(vcamera_guide_link, 0, wxALL, FromDIP(15));
|
||||
link_underline->Hide();
|
||||
link_sizer->Add(vcamera_guide_link, 0, wxALL, 0);
|
||||
link_sizer->Add(link_underline, 0, wxALL, 0);
|
||||
|
||||
main_sizer->Add(link_sizer, 0, wxALL, FromDIP(15));
|
||||
|
||||
m_panel->SetSizer(main_sizer);
|
||||
m_panel->Layout();
|
||||
|
|
@ -105,6 +123,10 @@ CameraPopup::CameraPopup(wxWindow *parent, MachineObject* obj)
|
|||
m_panel->Bind(wxEVT_LEFT_UP, &CameraPopup::OnLeftUp, this);
|
||||
#endif //APPLE
|
||||
|
||||
this->Bind(wxEVT_TIMER, &CameraPopup::stop_interval, this);
|
||||
m_interval_timer = new wxTimer();
|
||||
m_interval_timer->SetOwner(this);
|
||||
|
||||
check_func_supported();
|
||||
wxGetApp().UpdateDarkUIWin(this);
|
||||
}
|
||||
|
|
@ -141,7 +163,9 @@ void CameraPopup::Popup(wxWindow *WXUNUSED(focus))
|
|||
wxSize win_size = this->GetSize();
|
||||
curr_position.x -= win_size.x;
|
||||
this->SetPosition(curr_position);
|
||||
wxPopupTransientWindow::Popup();
|
||||
|
||||
if (!m_is_in_interval)
|
||||
PopupWindow::Popup();
|
||||
}
|
||||
|
||||
wxWindow* CameraPopup::create_item_radiobox(wxString title, wxWindow* parent, wxString tooltip, int padding_left)
|
||||
|
|
@ -225,10 +249,12 @@ void CameraPopup::sync_vcamera_state(bool show_vcamera)
|
|||
if (is_vcamera_show) {
|
||||
m_switch_vcamera->SetValue(true);
|
||||
vcamera_guide_link->Show();
|
||||
link_underline->Show();
|
||||
}
|
||||
else {
|
||||
m_switch_vcamera->SetValue(false);
|
||||
vcamera_guide_link->Hide();
|
||||
link_underline->Hide();
|
||||
}
|
||||
|
||||
rescale();
|
||||
|
|
@ -248,12 +274,15 @@ void CameraPopup::check_func_supported()
|
|||
if (m_obj->is_function_supported(PrinterFunction::FUNC_VIRTUAL_CAMERA) && m_obj->has_ipcam) {
|
||||
m_text_vcamera->Show();
|
||||
m_switch_vcamera->Show();
|
||||
if (is_vcamera_show)
|
||||
if (is_vcamera_show) {
|
||||
vcamera_guide_link->Show();
|
||||
link_underline->Show();
|
||||
}
|
||||
} else {
|
||||
m_text_vcamera->Hide();
|
||||
m_switch_vcamera->Hide();
|
||||
vcamera_guide_link->Hide();
|
||||
link_underline->Hide();
|
||||
}
|
||||
|
||||
allow_alter_resolution = (m_obj->is_function_supported(PrinterFunction::FUNC_ALTER_RESOLUTION) && m_obj->has_ipcam);
|
||||
|
|
@ -318,7 +347,7 @@ void CameraPopup::rescale()
|
|||
m_panel->Layout();
|
||||
main_sizer->Fit(m_panel);
|
||||
SetClientSize(m_panel->GetSize());
|
||||
wxPopupTransientWindow::Update();
|
||||
PopupWindow::Update();
|
||||
}
|
||||
|
||||
void CameraPopup::OnLeftUp(wxMouseEvent &event)
|
||||
|
|
@ -367,18 +396,31 @@ void CameraPopup::OnLeftUp(wxMouseEvent &event)
|
|||
}
|
||||
}
|
||||
|
||||
void CameraPopup::start_interval()
|
||||
{
|
||||
m_interval_timer->Start(CAMERAPOPUP_CLICK_INTERVAL);
|
||||
m_is_in_interval = true;
|
||||
}
|
||||
|
||||
void CameraPopup::stop_interval(wxTimerEvent& event)
|
||||
{
|
||||
m_is_in_interval = false;
|
||||
m_interval_timer->Stop();
|
||||
}
|
||||
|
||||
void CameraPopup::OnDismiss() {
|
||||
wxPopupTransientWindow::OnDismiss();
|
||||
PopupWindow::OnDismiss();
|
||||
this->start_interval();
|
||||
}
|
||||
|
||||
bool CameraPopup::ProcessLeftDown(wxMouseEvent &event)
|
||||
{
|
||||
return wxPopupTransientWindow::ProcessLeftDown(event);
|
||||
return PopupWindow::ProcessLeftDown(event);
|
||||
}
|
||||
|
||||
bool CameraPopup::Show(bool show)
|
||||
{
|
||||
return wxPopupTransientWindow::Show(show);
|
||||
return PopupWindow::Show(show);
|
||||
}
|
||||
|
||||
void CameraPopup::OnSize(wxSizeEvent &event)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <wx/hyperlink.h>
|
||||
#include "Widgets/SwitchButton.hpp"
|
||||
#include "Widgets/RadioBox.hpp"
|
||||
#include "Widgets/PopupWindow.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
|
@ -20,13 +21,13 @@ namespace GUI {
|
|||
wxDECLARE_EVENT(EVT_VCAMERA_SWITCH, wxMouseEvent);
|
||||
wxDECLARE_EVENT(EVT_SDCARD_ABSENT_HINT, wxCommandEvent);
|
||||
|
||||
class CameraPopup : public wxPopupTransientWindow
|
||||
class CameraPopup : public PopupWindow
|
||||
{
|
||||
public:
|
||||
CameraPopup(wxWindow *parent, MachineObject* obj = nullptr);
|
||||
virtual ~CameraPopup() {}
|
||||
|
||||
// wxPopupTransientWindow virtual methods are all overridden to log them
|
||||
// PopupWindow virtual methods are all overridden to log them
|
||||
virtual void Popup(wxWindow *focus = NULL) wxOVERRIDE;
|
||||
virtual void OnDismiss() wxOVERRIDE;
|
||||
virtual bool ProcessLeftDown(wxMouseEvent &event) wxOVERRIDE;
|
||||
|
|
@ -59,6 +60,8 @@ protected:
|
|||
|
||||
private:
|
||||
MachineObject* m_obj { nullptr };
|
||||
wxTimer* m_interval_timer{nullptr};
|
||||
bool m_is_in_interval{ false };
|
||||
wxStaticText* m_text_recording;
|
||||
SwitchButton* m_switch_recording;
|
||||
wxStaticText* m_text_vcamera;
|
||||
|
|
@ -70,10 +73,13 @@ private:
|
|||
std::vector<RadioBox*> resolution_rbtns;
|
||||
std::vector<wxStaticText*> resolution_texts;
|
||||
CameraResolution curr_sel_resolution = RESOLUTION_1080P;
|
||||
wxHyperlinkCtrl* vcamera_guide_link { nullptr };
|
||||
Label* vcamera_guide_link { nullptr };
|
||||
wxPanel* link_underline{ nullptr };
|
||||
bool is_vcamera_show = false;
|
||||
bool allow_alter_resolution = false;
|
||||
|
||||
void start_interval();
|
||||
void stop_interval(wxTimerEvent& event);
|
||||
void OnMouse(wxMouseEvent &event);
|
||||
void OnSize(wxSizeEvent &event);
|
||||
void OnSetFocus(wxFocusEvent &event);
|
||||
|
|
|
|||
|
|
@ -430,6 +430,19 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
|||
m_support_material_overhangs_queried = false;
|
||||
}
|
||||
|
||||
if (config->opt_bool("enable_support")) {
|
||||
auto support_type = config->opt_enum<SupportType>("support_type");
|
||||
auto support_style = config->opt_enum<SupportMaterialStyle>("support_style");
|
||||
std::set<int> enum_set_normal = {0, 1, 2};
|
||||
std::set<int> enum_set_tree = {0, 3, 4, 5};
|
||||
auto & set = is_tree(support_type) ? enum_set_tree : enum_set_normal;
|
||||
if (set.find(support_style) == set.end()) {
|
||||
DynamicPrintConfig new_conf = *config;
|
||||
new_conf.set_key_value("support_style", new ConfigOptionEnum<SupportMaterialStyle>(smsDefault));
|
||||
apply(config, &new_conf);
|
||||
}
|
||||
}
|
||||
|
||||
if (config->option<ConfigOptionPercent>("sparse_infill_density")->value == 100) {
|
||||
std::string sparse_infill_pattern = config->option<ConfigOptionEnum<InfillPattern>>("sparse_infill_pattern")->serialize();
|
||||
const auto &top_fill_pattern_values = config->def()->get("top_surface_pattern")->enum_values;
|
||||
|
|
@ -480,6 +493,17 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config->opt_enum<PrintSequence>("print_sequence") == PrintSequence::ByObject && config->opt_int("skirt_height") > 1 && config->opt_int("skirt_loops") > 0) {
|
||||
const wxString msg_text = _(L("While printing by Object, the extruder may collide skirt.\nThus, reset the skirt layer to 1 to avoid that."));
|
||||
MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
|
||||
DynamicPrintConfig new_conf = *config;
|
||||
is_msg_dlg_already_exist = true;
|
||||
dialog.ShowModal();
|
||||
new_conf.set_key_value("skirt_height", new ConfigOptionInt(1));
|
||||
apply(config, &new_conf);
|
||||
is_msg_dlg_already_exist = false;
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigManipulation::apply_null_fff_config(DynamicPrintConfig *config, std::vector<std::string> const &keys, std::map<ObjectBase *, ModelConfig *> const &configs)
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ void ConnectPrinterDialog::on_button_confirm(wxCommandEvent &event)
|
|||
}
|
||||
}
|
||||
if (m_obj) {
|
||||
m_obj->set_access_code(code.ToStdString());
|
||||
m_obj->set_user_access_code(code.ToStdString());
|
||||
wxGetApp().getDeviceManager()->set_selected_machine(m_obj->dev_id);
|
||||
}
|
||||
EndModal(wxID_OK);
|
||||
|
|
|
|||
|
|
@ -136,6 +136,32 @@ wxColour AmsTray::get_color()
|
|||
return AmsTray::decode_color(color);
|
||||
}
|
||||
|
||||
void AmsTray::reset()
|
||||
{
|
||||
tag_uid = "";
|
||||
setting_id = "";
|
||||
filament_setting_id = "";
|
||||
type = "";
|
||||
sub_brands = "";
|
||||
color = "";
|
||||
weight = "";
|
||||
diameter = "";
|
||||
temp = "";
|
||||
time = "";
|
||||
bed_temp_type = "";
|
||||
bed_temp = "";
|
||||
nozzle_temp_max = "";
|
||||
nozzle_temp_min = "";
|
||||
xcam_info = "";
|
||||
uuid = "";
|
||||
k = 0.0f;
|
||||
n = 0.0f;
|
||||
is_bbl = false;
|
||||
hold_count = 0;
|
||||
remain = 0;
|
||||
}
|
||||
|
||||
|
||||
bool AmsTray::is_tray_info_ready()
|
||||
{
|
||||
if (color.empty())
|
||||
|
|
@ -302,6 +328,11 @@ std::string MachineObject::get_printer_thumbnail_img_str()
|
|||
return "printer_thumbnail";
|
||||
}
|
||||
|
||||
std::string MachineObject::get_ftp_folder()
|
||||
{
|
||||
return DeviceManager::get_ftp_folder(printer_type);
|
||||
}
|
||||
|
||||
void MachineObject::set_access_code(std::string code)
|
||||
{
|
||||
this->access_code = code;
|
||||
|
|
@ -518,6 +549,10 @@ Ams *MachineObject::get_curr_Ams()
|
|||
|
||||
AmsTray *MachineObject::get_curr_tray()
|
||||
{
|
||||
if (m_tray_now.compare(std::to_string(VIRTUAL_TRAY_ID)) == 0) {
|
||||
return &vt_tray;
|
||||
}
|
||||
|
||||
Ams* curr_ams = get_curr_Ams();
|
||||
if (!curr_ams) return nullptr;
|
||||
|
||||
|
|
@ -639,17 +674,6 @@ bool MachineObject::is_support_ams_mapping_version(std::string module, std::stri
|
|||
return result;
|
||||
}
|
||||
|
||||
bool MachineObject::is_only_support_cloud_print()
|
||||
{
|
||||
auto ap_ver_it = module_vers.find("rv1126");
|
||||
if (ap_ver_it != module_vers.end()) {
|
||||
if (ap_ver_it->second.sw_ver > "00.00.12.61") {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static float calc_color_distance(wxColour c1, wxColour c2)
|
||||
{
|
||||
float lab[2][3];
|
||||
|
|
@ -1229,7 +1253,7 @@ void MachineObject::parse_state_changed_event()
|
|||
{
|
||||
// parse calibration done
|
||||
if (last_mc_print_stage != mc_print_stage) {
|
||||
if (mc_print_stage == 1 && boost::contains(m_gcode_file, "auto_cali_for_user.gcode")) {
|
||||
if (mc_print_stage == 1 && boost::contains(m_gcode_file, "auto_cali_for_user")) {
|
||||
calibration_done = true;
|
||||
} else {
|
||||
calibration_done = false;
|
||||
|
|
@ -1322,6 +1346,7 @@ bool MachineObject::is_recording()
|
|||
void MachineObject::parse_version_func()
|
||||
{
|
||||
auto ota_version = module_vers.find("ota");
|
||||
auto esp32_version = module_vers.find("esp32");
|
||||
if (printer_type == "BL-P001" ||
|
||||
printer_type == "BL-P002") {
|
||||
if (ota_version != module_vers.end()) {
|
||||
|
|
@ -1348,9 +1373,13 @@ void MachineObject::parse_version_func()
|
|||
}
|
||||
} else if (printer_type == "C11") {
|
||||
local_use_ssl = true;
|
||||
is_cloud_print_only = true;
|
||||
if (ota_version != module_vers.end()) {
|
||||
is_support_send_to_sdcard = ota_version->second.sw_ver.compare("01.02.00.00") >= 0;
|
||||
}
|
||||
if (esp32_version != module_vers.end()) {
|
||||
ams_support_auto_switch_filament_flag = esp32_version->second.sw_ver.compare("00.03.11.50") >= 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1533,20 +1562,10 @@ int MachineObject::command_ams_switch(int tray_index, int old_temp, int new_temp
|
|||
|
||||
std::string gcode = "";
|
||||
if (tray_index == 255) {
|
||||
// unload gcode
|
||||
gcode = "M620 S255\nM104 S250\nG28 X\nG91\nG1 Z3.0 F1200\nG90\n"
|
||||
"G1 X70 F12000\nG1 Y245\nG1 Y265 F3000\nM109 S250\nG1 X120 F12000\n"
|
||||
"G1 X20 Y50 F12000\nG1 Y-3\nT255\nM104 S0\nG1 X165 F5000\nG1 Y245\n"
|
||||
"G91\nG1 Z-3.0 F1200\nG90\nM621 S255\n";
|
||||
gcode = DeviceManager::load_gcode(printer_type, "ams_unload.gcode");
|
||||
} else {
|
||||
// load gcode
|
||||
gcode = "M620 S[next_extruder]\nM104 S250\nG28 X\nG91\n\nG1 Z3.0 F1200\nG90\n"
|
||||
"G1 X70 F12000\nG1 Y245\nG1 Y265 F3000\nM109 S250\nG1 X120 F12000\nG1 X20 Y50 F12000\nG1 Y-3"
|
||||
"\nT[next_extruder]\nG1 X54 F12000\nG1 Y265\nM400\nM106 P1 S0\nG92 E0\nG1 E40 F200\nM400"
|
||||
"\nM109 S[new_filament_temp]\nM400\nM106 P1 S255\nG92 E0\nG1 E5 F300\nM400\nM106 P1 S0\nG1 X70 F9000"
|
||||
"\nG1 X76 F15000\nG1 X65 F15000\nG1 X76 F15000\nG1 X65 F15000\nG1 X70 F6000\nG1 X100 F5000\nG1 X70 F15000"
|
||||
"\nG1 X100 F5000\nG1 X70 F15000\nG1 X165 F5000\nG1 Y245\nG91\nG1 Z-3.0 F1200\nG90\nM621 S[next_extruder]\n";
|
||||
|
||||
// include VIRTUAL_TRAY_ID
|
||||
gcode = DeviceManager::load_gcode(printer_type, "ams_load.gcode");
|
||||
boost::replace_all(gcode, "[next_extruder]", std::to_string(tray_index));
|
||||
boost::replace_all(gcode, "[new_filament_temp]", std::to_string(new_temp));
|
||||
}
|
||||
|
|
@ -1649,7 +1668,7 @@ int MachineObject::command_ams_select_tray(std::string tray_id)
|
|||
int MachineObject::command_ams_control(std::string action)
|
||||
{
|
||||
//valid actions
|
||||
if (action == "resume" || action == "reset" || action == "pause") {
|
||||
if (action == "resume" || action == "reset" || action == "pause" || action == "done") {
|
||||
json j;
|
||||
j["print"]["command"] = "ams_control";
|
||||
j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
|
||||
|
|
@ -1840,6 +1859,22 @@ int MachineObject::command_unload_filament()
|
|||
j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
|
||||
return this->publish_json(j.dump());
|
||||
}
|
||||
else if (printer_type == "C11") {
|
||||
std::string gcode = DeviceManager::load_gcode(printer_type, "ams_unload.gcode");
|
||||
if (gcode.empty()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
json j;
|
||||
j["print"]["command"] = "gcode_line";
|
||||
j["print"]["param"] = gcode;
|
||||
j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
|
||||
|
||||
if (m_agent)
|
||||
j["print"]["user_id"] = m_agent->get_user_id();
|
||||
|
||||
return this->publish_json(j.dump());
|
||||
}
|
||||
else {
|
||||
json j;
|
||||
j["print"]["command"] = "unload_filament";
|
||||
|
|
@ -2040,6 +2075,9 @@ void MachineObject::reset()
|
|||
last_mc_print_stage = -1;
|
||||
m_new_ver_list_exist = false;
|
||||
extruder_axis_status = LOAD;
|
||||
nozzle_diameter = 0.0f;
|
||||
|
||||
vt_tray.reset();
|
||||
|
||||
subtask_ = nullptr;
|
||||
|
||||
|
|
@ -2056,7 +2094,7 @@ int MachineObject::connect(bool is_anonymous)
|
|||
std::string password;
|
||||
if (!is_anonymous) {
|
||||
username = "bblp";
|
||||
password = access_code;
|
||||
password = get_access_code();
|
||||
}
|
||||
if (m_agent) {
|
||||
try {
|
||||
|
|
@ -2624,6 +2662,19 @@ int MachineObject::parse_json(std::string payload)
|
|||
}
|
||||
#pragma endregion
|
||||
|
||||
try {
|
||||
if (jj.contains("nozzle_diameter")) {
|
||||
if (jj["nozzle_diameter"].is_number_float()) {
|
||||
nozzle_diameter = jj["nozzle_diameter"].get<float>();
|
||||
} else if (jj["nozzle_diameter"].is_string()) {
|
||||
nozzle_diameter = stof(jj["nozzle_diameter"].get<std::string>().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(...) {
|
||||
;
|
||||
}
|
||||
|
||||
#pragma region upgrade
|
||||
try {
|
||||
if (jj.contains("upgrade_state")) {
|
||||
|
|
@ -2656,29 +2707,36 @@ int MachineObject::parse_json(std::string payload)
|
|||
this->command_get_version();
|
||||
});
|
||||
}
|
||||
upgrade_display_state = jj["upgrade_state"]["dis_state"].get<int>();
|
||||
if (upgrade_display_hold_count > 0)
|
||||
upgrade_display_hold_count--;
|
||||
else
|
||||
upgrade_display_state = jj["upgrade_state"]["dis_state"].get<int>();
|
||||
} else {
|
||||
//BBS compatibility with old version
|
||||
if (upgrade_status == "DOWNLOADING"
|
||||
|| upgrade_status == "FLASHING"
|
||||
|| upgrade_status == "UPGRADE_REQUEST"
|
||||
|| upgrade_status == "PRE_FLASH_START"
|
||||
|| upgrade_status == "PRE_FLASH_SUCCESS") {
|
||||
upgrade_display_state = (int)UpgradingDisplayState::UpgradingInProgress;
|
||||
}
|
||||
else if (upgrade_status == "UPGRADE_SUCCESS"
|
||||
|| upgrade_status == "DOWNLOAD_FAIL"
|
||||
|| upgrade_status == "FLASH_FAIL"
|
||||
|| upgrade_status == "PRE_FLASH_FAIL"
|
||||
|| upgrade_status == "UPGRADE_FAIL") {
|
||||
upgrade_display_state = (int)UpgradingDisplayState::UpgradingFinished;
|
||||
}
|
||||
if (upgrade_display_hold_count > 0)
|
||||
upgrade_display_hold_count--;
|
||||
else {
|
||||
if (upgrade_new_version) {
|
||||
upgrade_display_state = (int)UpgradingDisplayState::UpgradingAvaliable;
|
||||
//BBS compatibility with old version
|
||||
if (upgrade_status == "DOWNLOADING"
|
||||
|| upgrade_status == "FLASHING"
|
||||
|| upgrade_status == "UPGRADE_REQUEST"
|
||||
|| upgrade_status == "PRE_FLASH_START"
|
||||
|| upgrade_status == "PRE_FLASH_SUCCESS") {
|
||||
upgrade_display_state = (int)UpgradingDisplayState::UpgradingInProgress;
|
||||
}
|
||||
else if (upgrade_status == "UPGRADE_SUCCESS"
|
||||
|| upgrade_status == "DOWNLOAD_FAIL"
|
||||
|| upgrade_status == "FLASH_FAIL"
|
||||
|| upgrade_status == "PRE_FLASH_FAIL"
|
||||
|| upgrade_status == "UPGRADE_FAIL") {
|
||||
upgrade_display_state = (int)UpgradingDisplayState::UpgradingFinished;
|
||||
}
|
||||
else {
|
||||
upgrade_display_state = (int)UpgradingDisplayState::UpgradingUnavaliable;
|
||||
if (upgrade_new_version) {
|
||||
upgrade_display_state = (int)UpgradingDisplayState::UpgradingAvaliable;
|
||||
}
|
||||
else {
|
||||
upgrade_display_state = (int)UpgradingDisplayState::UpgradingUnavaliable;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3130,6 +3188,89 @@ int MachineObject::parse_json(std::string payload)
|
|||
vt_tray.n = jj["vt_tray"]["n"].get<float>();
|
||||
}
|
||||
ams_support_virtual_tray = true;
|
||||
|
||||
if (vt_tray.hold_count > 0) {
|
||||
vt_tray.hold_count--;
|
||||
} else {
|
||||
if (jj["vt_tray"].contains("tag_uid"))
|
||||
vt_tray.tag_uid = jj["vt_tray"]["tag_uid"].get<std::string>();
|
||||
else
|
||||
vt_tray.tag_uid = "0";
|
||||
if (jj["vt_tray"].contains("tray_info_idx") && jj["vt_tray"].contains("tray_type")) {
|
||||
vt_tray.setting_id = jj["vt_tray"]["tray_info_idx"].get<std::string>();
|
||||
std::string type = jj["vt_tray"]["tray_type"].get<std::string>();
|
||||
if (vt_tray.setting_id == "GFS00") {
|
||||
vt_tray.type = "PLA-S";
|
||||
}
|
||||
else if (vt_tray.setting_id == "GFS01") {
|
||||
vt_tray.type = "PA-S";
|
||||
}
|
||||
else {
|
||||
vt_tray.type = type;
|
||||
}
|
||||
}
|
||||
else {
|
||||
vt_tray.setting_id = "";
|
||||
vt_tray.type = "";
|
||||
}
|
||||
if (jj["vt_tray"].contains("tray_sub_brands"))
|
||||
vt_tray.sub_brands = jj["vt_tray"]["tray_sub_brands"].get<std::string>();
|
||||
else
|
||||
vt_tray.sub_brands = "";
|
||||
if (jj["vt_tray"].contains("tray_weight"))
|
||||
vt_tray.weight = jj["vt_tray"]["tray_weight"].get<std::string>();
|
||||
else
|
||||
vt_tray.weight = "";
|
||||
if (jj["vt_tray"].contains("tray_diameter"))
|
||||
vt_tray.diameter = jj["vt_tray"]["tray_diameter"].get<std::string>();
|
||||
else
|
||||
vt_tray.diameter = "";
|
||||
if (jj["vt_tray"].contains("tray_temp"))
|
||||
vt_tray.temp = jj["vt_tray"]["tray_temp"].get<std::string>();
|
||||
else
|
||||
vt_tray.temp = "";
|
||||
if (jj["vt_tray"].contains("tray_time"))
|
||||
vt_tray.time = jj["vt_tray"]["tray_time"].get<std::string>();
|
||||
else
|
||||
vt_tray.time = "";
|
||||
if (jj["vt_tray"].contains("bed_temp_type"))
|
||||
vt_tray.bed_temp_type = jj["vt_tray"]["bed_temp_type"].get<std::string>();
|
||||
else
|
||||
vt_tray.bed_temp_type = "";
|
||||
if (jj["vt_tray"].contains("bed_temp"))
|
||||
vt_tray.bed_temp = jj["vt_tray"]["bed_temp"].get<std::string>();
|
||||
else
|
||||
vt_tray.bed_temp = "";
|
||||
if (jj["vt_tray"].contains("nozzle_temp_max"))
|
||||
vt_tray.nozzle_temp_max = jj["vt_tray"]["nozzle_temp_max"].get<std::string>();
|
||||
else
|
||||
vt_tray.nozzle_temp_max = "";
|
||||
if (jj["vt_tray"].contains("nozzle_temp_min"))
|
||||
vt_tray.nozzle_temp_min = jj["vt_tray"]["nozzle_temp_min"].get<std::string>();
|
||||
else
|
||||
vt_tray.nozzle_temp_min = "";
|
||||
if (jj["vt_tray"].contains("xcam_info"))
|
||||
vt_tray.xcam_info = jj["vt_tray"]["xcam_info"].get<std::string>();
|
||||
else
|
||||
vt_tray.xcam_info = "";
|
||||
if (jj["vt_tray"].contains("tray_uuid"))
|
||||
vt_tray.uuid = jj["vt_tray"]["tray_uuid"].get<std::string>();
|
||||
else
|
||||
vt_tray.uuid = "0";
|
||||
if (jj["vt_tray"].contains("tray_color")) {
|
||||
auto color = jj["vt_tray"]["tray_color"].get<std::string>();
|
||||
vt_tray.update_color_from_str(color);
|
||||
}
|
||||
else {
|
||||
vt_tray.color = "";
|
||||
}
|
||||
if (jj["vt_tray"].contains("remain")) {
|
||||
vt_tray.remain = jj["vt_tray"]["remain"].get<int>();
|
||||
}
|
||||
else {
|
||||
vt_tray.remain = -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ams_support_virtual_tray = false;
|
||||
}
|
||||
|
|
@ -3159,24 +3300,39 @@ int MachineObject::parse_json(std::string payload)
|
|||
|
||||
if (jj["ams_id"].is_number()) {
|
||||
int ams_id = jj["ams_id"].get<int>();
|
||||
auto ams_it = amsList.find(std::to_string(ams_id));
|
||||
if (ams_it != amsList.end()) {
|
||||
int tray_id = jj["tray_id"].get<int>();
|
||||
auto tray_it = ams_it->second->trayList.find(std::to_string(tray_id));
|
||||
if (tray_it != ams_it->second->trayList.end()) {
|
||||
BOOST_LOG_TRIVIAL(trace) << "ams_filament_setting, parse tray info";
|
||||
tray_it->second->nozzle_temp_max = std::to_string(jj["nozzle_temp_max"].get<int>());
|
||||
tray_it->second->nozzle_temp_min = std::to_string(jj["nozzle_temp_min"].get<int>());
|
||||
tray_it->second->type = jj["tray_type"].get<std::string>();
|
||||
tray_it->second->color = jj["tray_color"].get<std::string>();
|
||||
tray_it->second->setting_id = jj["tray_info_idx"].get<std::string>();
|
||||
// delay update
|
||||
tray_it->second->set_hold_count();
|
||||
} else {
|
||||
BOOST_LOG_TRIVIAL(warning) << "ams_filament_setting, can not find in trayList, tray_id=" << tray_id;
|
||||
}
|
||||
int tray_id = 0;
|
||||
if (jj.contains("tray_id")) {
|
||||
tray_id = jj["tray_id"].get<int>();
|
||||
}
|
||||
if (ams_id == 255 && tray_id == VIRTUAL_TRAY_ID) {
|
||||
BOOST_LOG_TRIVIAL(trace) << "ams_filament_setting, parse tray info";
|
||||
vt_tray.nozzle_temp_max = std::to_string(jj["nozzle_temp_max"].get<int>());
|
||||
vt_tray.nozzle_temp_min = std::to_string(jj["nozzle_temp_min"].get<int>());
|
||||
vt_tray.type = jj["tray_type"].get<std::string>();
|
||||
vt_tray.color = jj["tray_color"].get<std::string>();
|
||||
vt_tray.setting_id = jj["tray_info_idx"].get<std::string>();
|
||||
// delay update
|
||||
vt_tray.set_hold_count();
|
||||
} else {
|
||||
BOOST_LOG_TRIVIAL(warning) << "ams_filament_setting, can not find in amsList, ams_id=" << ams_id;
|
||||
auto ams_it = amsList.find(std::to_string(ams_id));
|
||||
if (ams_it != amsList.end()) {
|
||||
tray_id = jj["tray_id"].get<int>();
|
||||
auto tray_it = ams_it->second->trayList.find(std::to_string(tray_id));
|
||||
if (tray_it != ams_it->second->trayList.end()) {
|
||||
BOOST_LOG_TRIVIAL(trace) << "ams_filament_setting, parse tray info";
|
||||
tray_it->second->nozzle_temp_max = std::to_string(jj["nozzle_temp_max"].get<int>());
|
||||
tray_it->second->nozzle_temp_min = std::to_string(jj["nozzle_temp_min"].get<int>());
|
||||
tray_it->second->type = jj["tray_type"].get<std::string>();
|
||||
tray_it->second->color = jj["tray_color"].get<std::string>();
|
||||
tray_it->second->setting_id = jj["tray_info_idx"].get<std::string>();
|
||||
// delay update
|
||||
tray_it->second->set_hold_count();
|
||||
} else {
|
||||
BOOST_LOG_TRIVIAL(warning) << "ams_filament_setting, can not find in trayList, tray_id=" << tray_id;
|
||||
}
|
||||
} else {
|
||||
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") {
|
||||
|
|
@ -3336,6 +3492,21 @@ int MachineObject::parse_json(std::string payload)
|
|||
}
|
||||
} catch (...) {}
|
||||
|
||||
// upgrade
|
||||
try {
|
||||
if (j.contains("upgrade")) {
|
||||
if (j["upgrade"].contains("command")) {
|
||||
if (j["upgrade"]["command"].get<std::string>() == "upgrade_confirm") {
|
||||
this->upgrade_display_state == UpgradingInProgress;
|
||||
upgrade_display_hold_count = HOLD_COUNT_MAX;
|
||||
BOOST_LOG_TRIVIAL(info) << "ack of upgrade_confirm";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
;
|
||||
}
|
||||
|
||||
// event info
|
||||
try {
|
||||
|
|
@ -3645,6 +3816,7 @@ void DeviceManager::on_machine_alive(std::string json_str)
|
|||
AppConfig* config = Slic3r::GUI::wxGetApp().app_config;
|
||||
if (config) {
|
||||
obj->set_access_code(Slic3r::GUI::wxGetApp().app_config->get("access_code", dev_id));
|
||||
obj->set_user_access_code(Slic3r::GUI::wxGetApp().app_config->get("user_access_code", dev_id));
|
||||
}
|
||||
localMachineList.insert(std::make_pair(dev_id, obj));
|
||||
|
||||
|
|
@ -3789,6 +3961,18 @@ bool DeviceManager::set_selected_machine(std::string dev_id)
|
|||
BOOST_LOG_TRIVIAL(info) << "set_selected_machine=" << dev_id;
|
||||
auto my_machine_list = get_my_machine_list();
|
||||
auto it = my_machine_list.find(dev_id);
|
||||
|
||||
// disconnect last
|
||||
auto last_selected = my_machine_list.find(selected_machine);
|
||||
if (last_selected != my_machine_list.end()) {
|
||||
if (last_selected->second->connection_type() == "lan") {
|
||||
if (last_selected->second->is_connecting())
|
||||
return false;
|
||||
m_agent->disconnect_printer();
|
||||
}
|
||||
}
|
||||
|
||||
// connect curr
|
||||
if (it != my_machine_list.end()) {
|
||||
if (selected_machine == dev_id) {
|
||||
if (it->second->connection_type() != "lan") {
|
||||
|
|
@ -3815,7 +3999,6 @@ bool DeviceManager::set_selected_machine(std::string dev_id)
|
|||
it->second->reset_update_time();
|
||||
}
|
||||
} else {
|
||||
m_agent->disconnect_printer();
|
||||
it->second->reset();
|
||||
it->second->connect();
|
||||
it->second->set_lan_mode_connection_state(true);
|
||||
|
|
@ -4007,6 +4190,7 @@ void DeviceManager::load_last_machine()
|
|||
}
|
||||
|
||||
json DeviceManager::function_table = json::object();
|
||||
json DeviceManager::filaments_blacklist = json::object();
|
||||
|
||||
std::string DeviceManager::parse_printer_type(std::string type_str)
|
||||
{
|
||||
|
|
@ -4036,6 +4220,20 @@ std::string DeviceManager::get_printer_display_name(std::string type_str)
|
|||
return "";
|
||||
}
|
||||
|
||||
std::string DeviceManager::get_ftp_folder(std::string type_str)
|
||||
{
|
||||
if (DeviceManager::function_table.contains("printers")) {
|
||||
for (auto printer : DeviceManager::function_table["printers"]) {
|
||||
if (printer.contains("model_id") && printer["model_id"].get<std::string>() == type_str) {
|
||||
if (printer.contains("ftp_folder")) {
|
||||
return printer["ftp_folder"].get<std::string>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string DeviceManager::get_printer_thumbnail_img(std::string type_str)
|
||||
{
|
||||
if (DeviceManager::function_table.contains("printers")) {
|
||||
|
|
@ -4115,4 +4313,96 @@ bool DeviceManager::load_functional_config(std::string config_file)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool DeviceManager::load_filaments_blacklist_config(std::string config_file)
|
||||
{
|
||||
filaments_blacklist = json::object();
|
||||
std::ifstream json_file(config_file.c_str());
|
||||
|
||||
try {
|
||||
if (json_file.is_open()) {
|
||||
json_file >> filaments_blacklist;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
BOOST_LOG_TRIVIAL(error) << "load filaments blacklist config failed, file = " << config_file;
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
BOOST_LOG_TRIVIAL(error) << "load filaments blacklist config failed, file = " << config_file;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void DeviceManager::check_filaments_in_blacklist(std::string tag_vendor, std::string tag_type, bool& in_blacklist, std::string& ac, std::string& info)
|
||||
{
|
||||
in_blacklist = false;
|
||||
|
||||
if (filaments_blacklist.contains("blacklist")) {
|
||||
for (auto prohibited_filament : filaments_blacklist["blacklist"]) {
|
||||
|
||||
std::string vendor;
|
||||
std::string type;
|
||||
std::string action;
|
||||
std::string description;
|
||||
|
||||
if (prohibited_filament.contains("vendor") &&
|
||||
prohibited_filament.contains("type") &&
|
||||
prohibited_filament.contains("action") &&
|
||||
prohibited_filament.contains("description"))
|
||||
{
|
||||
vendor = prohibited_filament["vendor"].get<std::string>();
|
||||
type = prohibited_filament["type"].get<std::string>();
|
||||
action = prohibited_filament["action"].get<std::string>();
|
||||
description = prohibited_filament["description"].get<std::string>();
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
|
||||
std::transform(vendor.begin(), vendor.end(), vendor.begin(), ::tolower);
|
||||
std::transform(tag_vendor.begin(), tag_vendor.end(), tag_vendor.begin(), ::tolower);
|
||||
std::transform(tag_type.begin(), tag_type.end(), tag_type.begin(), ::tolower);
|
||||
std::transform(type.begin(), type.end(), type.begin(), ::tolower);
|
||||
|
||||
//third party
|
||||
if (vendor == "third party") {
|
||||
if ("bambulab" != vendor && tag_type == type) {
|
||||
in_blacklist = true;
|
||||
ac = action;
|
||||
info = description;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (vendor == tag_vendor && tag_type == type) {
|
||||
in_blacklist = true;
|
||||
ac = action;
|
||||
info = description;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string DeviceManager::load_gcode(std::string type_str, std::string gcode_file)
|
||||
{
|
||||
std::string gcode_full_path = Slic3r::resources_dir() + "/printers/" + gcode_file;
|
||||
std::ifstream gcode(encode_path(gcode_full_path.c_str()).c_str());
|
||||
try {
|
||||
std::stringstream gcode_str;
|
||||
if (gcode.is_open()) {
|
||||
gcode_str << gcode.rdbuf();
|
||||
gcode.close();
|
||||
return gcode_str.str();
|
||||
}
|
||||
} catch(...) {
|
||||
BOOST_LOG_TRIVIAL(error) << "load gcode file failed, file = " << gcode_file << ", path = " << gcode_full_path;
|
||||
}
|
||||
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
||||
|
|
|
|||
|
|
@ -178,6 +178,8 @@ public:
|
|||
if (digit1 == -1 || digit2 == -1) break;
|
||||
ret[j] = float(digit1 * 16 + digit2);
|
||||
}
|
||||
} else {
|
||||
return wxColour(255, 255, 255);
|
||||
}
|
||||
return wxColour(ret[0], ret[1], ret[2]);
|
||||
}
|
||||
|
|
@ -216,6 +218,8 @@ public:
|
|||
void update_color_from_str(std::string color);
|
||||
wxColour get_color();
|
||||
|
||||
void reset();
|
||||
|
||||
bool is_tray_info_ready();
|
||||
bool is_unset_third_filament();
|
||||
std::string get_display_filament_type();
|
||||
|
|
@ -401,15 +405,20 @@ public:
|
|||
std::string dev_ip;
|
||||
std::string dev_id;
|
||||
bool local_use_ssl { false };
|
||||
float nozzle_diameter { 0.0f };
|
||||
std::string dev_connection_type; /* lan | cloud */
|
||||
std::string connection_type() { return dev_connection_type; }
|
||||
void set_dev_ip(std::string ip) {dev_ip = ip;};
|
||||
bool has_access_right() { return !access_code.empty(); }
|
||||
bool has_access_right() { return !get_access_code().empty(); }
|
||||
std::string get_ftp_folder();
|
||||
void set_access_code(std::string code);
|
||||
std::string get_access_code();
|
||||
|
||||
void set_user_access_code(std::string code);
|
||||
|
||||
std::string get_user_access_code();
|
||||
bool is_lan_mode_printer();
|
||||
|
||||
//PRINTER_TYPE printer_type = PRINTER_3DPrinter_UKNOWN;
|
||||
std::string printer_type; /* model_id */
|
||||
|
||||
|
|
@ -460,7 +469,7 @@ public:
|
|||
int ams_version = 0;
|
||||
std::string m_ams_id; // local ams : "0" ~ "3"
|
||||
std::string m_tray_id; // local tray id : "0" ~ "3"
|
||||
std::string m_tray_now; // tray_now : "0" ~ "15" or "255"
|
||||
std::string m_tray_now; // tray_now : "0" ~ "15" or "254", "255"
|
||||
std::string m_tray_tar; // tray_tar : "0" ~ "15" or "255"
|
||||
|
||||
int extrusion_cali_hold_count = 0;
|
||||
|
|
@ -484,7 +493,6 @@ public:
|
|||
bool can_unload_filament();
|
||||
bool is_U0_firmware();
|
||||
bool is_support_ams_mapping();
|
||||
bool is_only_support_cloud_print();
|
||||
static bool is_support_ams_mapping_version(std::string module, std::string version);
|
||||
|
||||
int ams_filament_mapping(std::vector<FilamentInfo> filaments, std::vector<FilamentInfo> &result, std::vector<int> exclude_id = std::vector<int>());
|
||||
|
|
@ -530,6 +538,7 @@ public:
|
|||
bool upgrade_new_version { false };
|
||||
bool upgrade_consistency_request { false };
|
||||
int upgrade_display_state = 0; // 0 : upgrade unavailable, 1: upgrade idle, 2: upgrading, 3: upgrade_finished
|
||||
int upgrade_display_hold_count = 0;
|
||||
PrinterFirmwareType firmware_type; // engineer|production
|
||||
std::string upgrade_progress;
|
||||
std::string upgrade_message;
|
||||
|
|
@ -630,6 +639,8 @@ public:
|
|||
bool is_support_1080dpi {false};
|
||||
bool is_support_ai_monitoring {false};
|
||||
bool is_support_ams_humidity {true};
|
||||
bool is_support_filament_edit_virtual_tray {true};
|
||||
bool is_cloud_print_only {false};
|
||||
|
||||
/* sdcard */
|
||||
MachineObject::SdcardState sdcard_state { NO_SDCARD };
|
||||
|
|
@ -827,14 +838,20 @@ public:
|
|||
void load_last_machine();
|
||||
|
||||
static json function_table;
|
||||
static json filaments_blacklist;
|
||||
|
||||
static std::string parse_printer_type(std::string type_str);
|
||||
static std::string get_printer_display_name(std::string type_str);
|
||||
static std::string get_printer_thumbnail_img(std::string type_str);
|
||||
static std::string get_ftp_folder(std::string type_str);
|
||||
static bool is_function_supported(std::string type_str, std::string function_name);
|
||||
static std::vector<std::string> get_resolution_supported(std::string type_str);
|
||||
|
||||
static bool get_bed_temperature_limit(std::string type_str, int& limit);
|
||||
static bool load_functional_config(std::string config_file);
|
||||
static bool load_filaments_blacklist_config(std::string config_file);
|
||||
static void check_filaments_in_blacklist(std::string tag_vendor, std::string tag_type, bool& in_blacklist, std::string& ac, std::string& info);
|
||||
static std::string load_gcode(std::string type_str, std::string gcode_file);
|
||||
};
|
||||
|
||||
} // namespace Slic3r
|
||||
|
|
|
|||
|
|
@ -65,10 +65,10 @@ void ExtrusionCalibration::create()
|
|||
#else
|
||||
m_comboBox_nozzle_dia = new ComboBox(m_step_1_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, EXTRUSION_CALIBRATION_BED_COMBOX, 0, nullptr, wxCB_READONLY);
|
||||
#endif
|
||||
m_comboBox_nozzle_dia->AppendString("0.2");
|
||||
m_comboBox_nozzle_dia->AppendString("0.4");
|
||||
m_comboBox_nozzle_dia->AppendString("0.6");
|
||||
m_comboBox_nozzle_dia->AppendString("0.8");
|
||||
m_comboBox_nozzle_dia->AppendString(wxString::Format("%1.1f", 0.2));
|
||||
m_comboBox_nozzle_dia->AppendString(wxString::Format("%1.1f", 0.4));
|
||||
m_comboBox_nozzle_dia->AppendString(wxString::Format("%1.1f", 0.6));
|
||||
m_comboBox_nozzle_dia->AppendString(wxString::Format("%1.1f", 0.8));
|
||||
|
||||
select_sizer->Add(m_comboBox_nozzle_dia, 0, wxEXPAND);
|
||||
select_sizer->Add(0, EXTRUSION_CALIBRATION_WIDGET_GAP, 0, 0);
|
||||
|
|
@ -170,10 +170,10 @@ void ExtrusionCalibration::create()
|
|||
|
||||
m_button_cali = new Button(m_step_1_panel, _L("Start calibration"));
|
||||
m_btn_bg_green = StateColor(std::pair<wxColour, int>(wxColour(238, 238, 238), 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>(wxColour(0, 150, 136), StateColor::Normal));
|
||||
std::pair<wxColour, int>(wxColour(0, 174, 66), StateColor::Normal));
|
||||
m_button_cali->SetBackgroundColor(m_btn_bg_green);
|
||||
m_button_cali->SetFont(Label::Body_13);
|
||||
m_button_cali->SetBorderColor({ std::pair<wxColour, int>(wxColour(238, 238, 238), StateColor::Disabled), std::pair<wxColour, int>(wxColour(0, 150, 136), StateColor::Enabled) });
|
||||
m_button_cali->SetBorderColor({ std::pair<wxColour, int>(wxColour(238, 238, 238), StateColor::Disabled), std::pair<wxColour, int>(wxColour(0, 174, 66), StateColor::Enabled) });
|
||||
m_button_cali->SetTextColor({ std::pair<wxColour, int>(wxColour(172, 172, 172), StateColor::Disabled), std::pair<wxColour, int>(EXTRUSION_CALIBRATION_GREY200, StateColor::Enabled) });
|
||||
m_button_cali->SetCornerRadius(FromDIP(12));
|
||||
m_button_cali->SetMinSize(wxSize(-1, FromDIP(24)));
|
||||
|
|
@ -181,9 +181,9 @@ void ExtrusionCalibration::create()
|
|||
|
||||
m_cali_cancel = new Button(m_step_1_panel, _L("Cancel"));
|
||||
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, 150, 136), StateColor::Normal));
|
||||
std::pair<wxColour, int>(wxColour(0, 174, 66), StateColor::Normal));
|
||||
m_cali_cancel->SetBackgroundColor(m_btn_bg_green);
|
||||
m_cali_cancel->SetBorderColor(wxColour(0, 150, 136));
|
||||
m_cali_cancel->SetBorderColor(wxColour(0, 174, 66));
|
||||
m_cali_cancel->SetTextColor(EXTRUSION_CALIBRATION_GREY200);
|
||||
m_cali_cancel->SetMinSize(EXTRUSION_CALIBRATION_BUTTON_SIZE);
|
||||
m_cali_cancel->SetCornerRadius(FromDIP(12));
|
||||
|
|
@ -256,10 +256,10 @@ void ExtrusionCalibration::create()
|
|||
// save button
|
||||
m_button_save_result = new Button(m_step_2_panel, _L("Save"));
|
||||
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, 150, 136), StateColor::Normal));
|
||||
std::pair<wxColour, int>(wxColour(0, 174, 66), StateColor::Normal));
|
||||
m_button_save_result->SetBackgroundColor(m_btn_bg_green);
|
||||
m_button_save_result->SetFont(Label::Body_13);
|
||||
m_button_save_result->SetBorderColor(wxColour(0, 150, 136));
|
||||
m_button_save_result->SetBorderColor(wxColour(0, 174, 66));
|
||||
m_button_save_result->SetTextColor(EXTRUSION_CALIBRATION_GREY200);
|
||||
m_button_save_result->SetMinSize(EXTRUSION_CALIBRATION_BUTTON_SIZE);
|
||||
m_button_save_result->SetCornerRadius(FromDIP(12));
|
||||
|
|
@ -660,8 +660,6 @@ void ExtrusionCalibration::update_combobox_filaments()
|
|||
}
|
||||
|
||||
for (auto filament_it = preset_bundle->filaments.begin(); filament_it != preset_bundle->filaments.end(); filament_it++) {
|
||||
if (filament_it->setting_id.empty()) continue;
|
||||
|
||||
ConfigOption* printer_opt = filament_it->config.option("compatible_printers");
|
||||
ConfigOptionStrings* printer_strs = dynamic_cast<ConfigOptionStrings*>(printer_opt);
|
||||
for (auto printer_str : printer_strs->values) {
|
||||
|
|
|
|||
|
|
@ -1021,6 +1021,9 @@ void Choice::BUILD()
|
|||
if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit);
|
||||
if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit);
|
||||
|
||||
if (m_opt.nullable)
|
||||
m_last_meaningful_value = dynamic_cast<ConfigOptionEnumsGenericNullable const *>(m_opt.default_value.get())->get_at(0);
|
||||
|
||||
choice_ctrl* temp;
|
||||
auto dynamic_list = dynamic_lists.find(m_opt.opt_key);
|
||||
if (dynamic_list != dynamic_lists.end())
|
||||
|
|
@ -1209,7 +1212,7 @@ void Choice::set_selection()
|
|||
|
||||
void Choice::set_value(const std::string& value, bool change_event) //! Redundant?
|
||||
{
|
||||
m_disable_change_event = !change_event;
|
||||
m_disable_change_event = !change_event;
|
||||
|
||||
size_t idx=0;
|
||||
for (auto el : m_opt.enum_values)
|
||||
|
|
@ -1291,10 +1294,10 @@ void Choice::set_value(const boost::any& value, bool change_event)
|
|||
if (m_opt_id.compare("host_type") == 0 && val != 0 &&
|
||||
m_opt.enum_values.size() > field->GetCount()) // for case, when PrusaLink isn't used as a HostType
|
||||
val--;
|
||||
if (m_opt_id == "top_surface_pattern" || m_opt_id == "bottom_surface_pattern" || m_opt_id == "sparse_infill_pattern")
|
||||
if (m_opt_id == "top_surface_pattern" || m_opt_id == "bottom_surface_pattern" || m_opt_id == "sparse_infill_pattern" || m_opt_id == "support_style")
|
||||
{
|
||||
std::string key;
|
||||
const t_config_enum_values& map_names = ConfigOptionEnum<InfillPattern>::get_enum_values();
|
||||
const t_config_enum_values& map_names = *m_opt.enum_keys_map;
|
||||
for (auto it : map_names)
|
||||
if (val == it.second) {
|
||||
key = it.first;
|
||||
|
|
@ -1305,6 +1308,12 @@ void Choice::set_value(const boost::any& value, bool change_event)
|
|||
auto it = std::find(values.begin(), values.end(), key);
|
||||
val = it == values.end() ? 0 : it - values.begin();
|
||||
}
|
||||
if (m_opt.nullable) {
|
||||
if (val != ConfigOptionEnumsGenericNullable::nil_value())
|
||||
m_last_meaningful_value = value;
|
||||
else
|
||||
val = -1;
|
||||
}
|
||||
field->SetSelection(val);
|
||||
break;
|
||||
}
|
||||
|
|
@ -1370,9 +1379,11 @@ boost::any& Choice::get_value()
|
|||
// BBS
|
||||
if (m_opt.type == coEnum || m_opt.type == coEnums)
|
||||
{
|
||||
if (m_opt_id == "top_surface_pattern" || m_opt_id == "bottom_surface_pattern" || m_opt_id == "sparse_infill_pattern") {
|
||||
if (m_opt.nullable && field->GetSelection() == -1)
|
||||
m_value = ConfigOptionEnumsGenericNullable::nil_value();
|
||||
else if (m_opt_id == "top_surface_pattern" || m_opt_id == "bottom_surface_pattern" || m_opt_id == "sparse_infill_pattern" || m_opt_id == "support_style") {
|
||||
const std::string& key = m_opt.enum_values[field->GetSelection()];
|
||||
m_value = int(ConfigOptionEnum<InfillPattern>::get_enum_values().at(key));
|
||||
m_value = int(m_opt.enum_keys_map->at(key));
|
||||
}
|
||||
// Support ThirdPartyPrinter
|
||||
else if (m_opt_id.compare("host_type") == 0 && m_opt.enum_values.size() > field->GetCount()) {
|
||||
|
|
@ -1404,6 +1415,20 @@ boost::any& Choice::get_value()
|
|||
return m_value;
|
||||
}
|
||||
|
||||
void Choice::set_last_meaningful_value()
|
||||
{
|
||||
if (m_opt.nullable) {
|
||||
set_value(m_last_meaningful_value, false);
|
||||
on_change_field();
|
||||
}
|
||||
}
|
||||
|
||||
void Choice::set_na_value()
|
||||
{
|
||||
dynamic_cast<choice_ctrl *>(window)->SetSelection(-1);
|
||||
on_change_field();
|
||||
}
|
||||
|
||||
void Choice::enable() { dynamic_cast<choice_ctrl*>(window)->Enable(); }
|
||||
void Choice::disable() { dynamic_cast<choice_ctrl*>(window)->Disable(); }
|
||||
|
||||
|
|
|
|||
|
|
@ -386,6 +386,9 @@ public:
|
|||
void set_values(const wxArrayString &values);
|
||||
boost::any& get_value() override;
|
||||
|
||||
void set_last_meaningful_value() override;
|
||||
void set_na_value() override;
|
||||
|
||||
void msw_rescale() override;
|
||||
|
||||
void enable() override ;//{ dynamic_cast<wxBitmapComboBox*>(window)->Enable(); };
|
||||
|
|
|
|||
|
|
@ -357,7 +357,8 @@ void GCodeViewer::SequentialView::Marker::render(int canvas_width, int canvas_he
|
|||
glsafe(::glDisable(GL_BLEND));
|
||||
|
||||
static float last_window_width = 0.0f;
|
||||
static size_t last_text_length = 0;
|
||||
size_t text_line = 0;
|
||||
static size_t last_text_line = 0;
|
||||
const ImU32 text_name_clr = m_is_dark ? IM_COL32(255, 255, 255, 0.88 * 255) : IM_COL32(38, 46, 48, 255);
|
||||
const ImU32 text_value_clr = m_is_dark ? IM_COL32(255, 255, 255, 0.4 * 255) : IM_COL32(144, 144, 144, 255);
|
||||
|
||||
|
|
@ -466,6 +467,7 @@ void GCodeViewer::SequentialView::Marker::render(int canvas_width, int canvas_he
|
|||
default:
|
||||
break;
|
||||
}
|
||||
text_line = 2;
|
||||
}
|
||||
else {
|
||||
sprintf(buf, "%s%.3f", x.c_str(), position.x() - plate->get_origin().x());
|
||||
|
|
@ -485,14 +487,15 @@ void GCodeViewer::SequentialView::Marker::render(int canvas_width, int canvas_he
|
|||
sprintf(buf, "%s%.0f", speed.c_str(), m_curr_move.feedrate);
|
||||
ImGui::PushItemWidth(item_size);
|
||||
imgui.text(buf);
|
||||
|
||||
text_line = 1;
|
||||
}
|
||||
|
||||
// force extra frame to automatically update window size
|
||||
float window_width = ImGui::GetWindowWidth();
|
||||
//size_t length = strlen(buf);
|
||||
if (window_width != last_window_width /*|| length != last_text_length*/) {
|
||||
if (window_width != last_window_width || text_line != last_text_line) {
|
||||
last_window_width = window_width;
|
||||
//last_text_length = length;
|
||||
last_text_line = text_line;
|
||||
#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT
|
||||
imgui.set_requires_extra_frame();
|
||||
#else
|
||||
|
|
@ -945,7 +948,6 @@ void GCodeViewer::update_by_mode(ConfigOptionMode mode)
|
|||
// BBS for first layer inspection
|
||||
view_type_items.push_back(EViewType::FilamentId);
|
||||
|
||||
options_items.push_back(EMoveType::Seam);
|
||||
options_items.push_back(EMoveType::Travel);
|
||||
options_items.push_back(EMoveType::Retract);
|
||||
options_items.push_back(EMoveType::Unretract);
|
||||
|
|
@ -953,6 +955,8 @@ void GCodeViewer::update_by_mode(ConfigOptionMode mode)
|
|||
if (mode == ConfigOptionMode::comDevelop) {
|
||||
options_items.push_back(EMoveType::Tool_change);
|
||||
}
|
||||
//BBS: seam is not real move and extrusion, put at last line
|
||||
options_items.push_back(EMoveType::Seam);
|
||||
}
|
||||
|
||||
std::vector<int> GCodeViewer::get_plater_extruder()
|
||||
|
|
@ -1794,11 +1798,13 @@ void GCodeViewer::update_layers_slider_mode()
|
|||
}
|
||||
|
||||
void GCodeViewer::update_marker_curr_move() {
|
||||
auto it = std::find_if(m_gcode_result->moves.begin(), m_gcode_result->moves.end(), [this](auto move) {
|
||||
return move.gcode_id == static_cast<uint64_t>(m_sequential_view.gcode_ids[m_sequential_view.current.last]);
|
||||
});
|
||||
|
||||
m_sequential_view.marker.update_curr_move(*it);
|
||||
if ((int)m_last_result_id != -1) {
|
||||
auto it = std::find_if(m_gcode_result->moves.begin(), m_gcode_result->moves.end(), [this](auto move) {
|
||||
return move.gcode_id == static_cast<uint64_t>(m_sequential_view.gcode_ids[m_sequential_view.current.last]);
|
||||
});
|
||||
if (it != m_gcode_result->moves.end())
|
||||
m_sequential_view.marker.update_curr_move(*it);
|
||||
}
|
||||
}
|
||||
|
||||
bool GCodeViewer::is_toolpath_move_type_visible(EMoveType type) const
|
||||
|
|
@ -3080,6 +3086,13 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result, const
|
|||
}
|
||||
m_plater_extruder = plater_extruder;
|
||||
|
||||
// replace layers for spiral vase mode
|
||||
if (!gcode_result.spiral_vase_layers.empty()) {
|
||||
m_layers.reset();
|
||||
for (const auto& layer : gcode_result.spiral_vase_layers) {
|
||||
m_layers.append(layer.first, { layer.second.first, layer.second.second });
|
||||
}
|
||||
}
|
||||
|
||||
// set layers z range
|
||||
if (!m_layers.empty())
|
||||
|
|
@ -3325,11 +3338,13 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
|
|||
|
||||
const bool top_layer_only = true;
|
||||
|
||||
SequentialView::Endpoints global_endpoints = { m_moves_count , 0 };
|
||||
//BBS
|
||||
SequentialView::Endpoints global_endpoints = { m_sequential_view.gcode_ids.size() , 0 };
|
||||
SequentialView::Endpoints top_layer_endpoints = global_endpoints;
|
||||
SequentialView* sequential_view = const_cast<SequentialView*>(&m_sequential_view);
|
||||
if (top_layer_only || !keep_sequential_current_first) sequential_view->current.first = 0;
|
||||
if (!keep_sequential_current_last) sequential_view->current.last = m_moves_count;
|
||||
//BBS
|
||||
if (!keep_sequential_current_last) sequential_view->current.last = m_sequential_view.gcode_ids.size();
|
||||
|
||||
// first pass: collect visible paths and update sequential view data
|
||||
std::vector<std::tuple<unsigned char, unsigned int, unsigned int, unsigned int>> paths;
|
||||
|
|
@ -3403,15 +3418,11 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
|
|||
// update current sequential position
|
||||
sequential_view->current.first = !top_layer_only && keep_sequential_current_first ? std::clamp(sequential_view->current.first, global_endpoints.first, global_endpoints.last) : global_endpoints.first;
|
||||
if (global_endpoints.last == 0) {
|
||||
m_no_render_path = true;
|
||||
m_no_render_path = true;
|
||||
sequential_view->current.last = global_endpoints.last;
|
||||
} else {
|
||||
m_no_render_path = false;
|
||||
}
|
||||
|
||||
if (!m_no_render_path) {
|
||||
sequential_view->current.last = keep_sequential_current_last ? std::clamp(sequential_view->current.last, global_endpoints.first, global_endpoints.last) : global_endpoints.last;
|
||||
} else {
|
||||
sequential_view->current.last = sequential_view->current.first;
|
||||
}
|
||||
|
||||
// get the world position from the vertex buffer
|
||||
|
|
@ -4125,6 +4136,214 @@ void GCodeViewer::render_shells()
|
|||
// glsafe(::glDepthMask(GL_TRUE));
|
||||
}
|
||||
|
||||
//BBS
|
||||
void GCodeViewer::render_all_plates_stats(const std::vector<const GCodeProcessorResult*>& gcode_result_list, bool show /*= true*/) const {
|
||||
if (!show)
|
||||
return;
|
||||
for (auto gcode_result : gcode_result_list) {
|
||||
if (gcode_result->moves.size() == 0)
|
||||
return;
|
||||
}
|
||||
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0, 10.0 * m_scale));
|
||||
ImGui::PushStyleColor(ImGuiCol_Separator, ImVec4(1.0f, 1.0f, 1.0f, 0.6f));
|
||||
ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.00f, 0.68f, 0.26f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(0.00f, 0.68f, 0.26f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrab, ImVec4(0.42f, 0.42f, 0.42f, 1.00f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabHovered, ImVec4(0.93f, 0.93f, 0.93f, 1.00f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabActive, ImVec4(0.93f, 0.93f, 0.93f, 1.00f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(340.f * m_scale * imgui.scaled(1.0f / 15.0f), 0));
|
||||
|
||||
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), 0, ImVec2(0.5f, 0.5f));
|
||||
ImGui::Begin(_L("Statistics of All Plates").c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
|
||||
std::vector<float> filament_diameters = gcode_result_list.front()->filament_diameters;
|
||||
std::vector<float> filament_densities = gcode_result_list.front()->filament_densities;
|
||||
std::vector<Color> filament_colors = decode_colors(wxGetApp().plater()->get_extruder_colors_from_plater_config(gcode_result_list.back()));
|
||||
|
||||
bool imperial_units = wxGetApp().app_config->get("use_inches") == "1";
|
||||
float window_padding = 4.0f * m_scale;
|
||||
const float icon_size = ImGui::GetTextLineHeight() * 0.7;
|
||||
std::vector<float> offsets;
|
||||
std::map<int, double> volume_of_extruders_all_plates; // map<extruder_idx, volume>
|
||||
std::map<int, double> flushed_volume_of_extruders_all_plates; // map<extruder_idx, flushed volume>
|
||||
std::vector<double> model_used_filaments_m_all_plates;
|
||||
std::vector<double> model_used_filaments_g_all_plates;
|
||||
std::vector<double> flushed_filaments_m_all_plates;
|
||||
std::vector<double> flushed_filaments_g_all_plates;
|
||||
float total_time_all_plates = 0.0f;
|
||||
bool show_detailed_statistics_page = false;
|
||||
|
||||
auto max_width = [](const std::vector<std::string>& items, const std::string& title, float extra_size = 0.0f) {
|
||||
float ret = ImGui::CalcTextSize(title.c_str()).x;
|
||||
for (const std::string& item : items) {
|
||||
ret = std::max(ret, extra_size + ImGui::CalcTextSize(item.c_str()).x);
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
auto calculate_offsets = [max_width, window_padding](const std::vector<std::pair<std::string, std::vector<::string>>>& title_columns, float extra_size = 0.0f) {
|
||||
const ImGuiStyle& style = ImGui::GetStyle();
|
||||
std::vector<float> offsets;
|
||||
offsets.push_back(max_width(title_columns[0].second, title_columns[0].first, extra_size) + 3.0f * style.ItemSpacing.x + style.WindowPadding.x);
|
||||
for (size_t i = 1; i < title_columns.size() - 1; i++)
|
||||
offsets.push_back(offsets.back() + max_width(title_columns[i].second, title_columns[i].first) + style.ItemSpacing.x);
|
||||
if (title_columns.back().first == _u8L("Display"))
|
||||
offsets.back() = ImGui::GetWindowWidth() - ImGui::CalcTextSize(_u8L("Display").c_str()).x - ImGui::GetFrameHeight() / 2 - 2 * window_padding;
|
||||
|
||||
float average_col_width = ImGui::GetWindowWidth() / static_cast<float>(title_columns.size());
|
||||
std::vector<float> ret;
|
||||
ret.push_back(0);
|
||||
for (size_t i = 1; i < title_columns.size(); i++) {
|
||||
ret.push_back(std::max(offsets[i - 1], i * average_col_width));
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
auto append_item = [icon_size, &imgui, imperial_units, &window_padding, &draw_list, this](const Color& color, const std::vector<std::pair<std::string, float>>& columns_offsets)
|
||||
{
|
||||
// render icon
|
||||
ImVec2 pos = ImVec2(ImGui::GetCursorScreenPos().x + window_padding * 3, ImGui::GetCursorScreenPos().y);
|
||||
|
||||
draw_list->AddRectFilled({ pos.x + 1.0f * m_scale, pos.y + 3.0f * m_scale }, { pos.x + icon_size - 1.0f * m_scale, pos.y + icon_size + 1.0f * m_scale },
|
||||
ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }));
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(20.0 * m_scale, 6.0 * m_scale));
|
||||
|
||||
// render selectable
|
||||
ImGui::Dummy({ 0.0, 0.0 });
|
||||
ImGui::SameLine();
|
||||
|
||||
// render column item
|
||||
{
|
||||
float dummy_size = ImGui::GetStyle().ItemSpacing.x + icon_size;
|
||||
ImGui::SameLine(dummy_size);
|
||||
imgui.text(columns_offsets[0].first);
|
||||
|
||||
for (auto i = 1; i < columns_offsets.size(); i++) {
|
||||
ImGui::SameLine(columns_offsets[i].second);
|
||||
imgui.text(columns_offsets[i].first);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::PopStyleVar(1);
|
||||
};
|
||||
auto append_headers = [&imgui](const std::vector<std::pair<std::string, float>>& title_offsets) {
|
||||
for (size_t i = 0; i < title_offsets.size(); i++) {
|
||||
ImGui::SameLine(title_offsets[i].second);
|
||||
imgui.bold_text(title_offsets[i].first);
|
||||
}
|
||||
ImGui::Separator();
|
||||
};
|
||||
auto get_used_filament_from_volume = [this, imperial_units, &filament_diameters, &filament_densities](double volume, int extruder_id) {
|
||||
double koef = imperial_units ? 1.0 / GizmoObjectManipulation::in_to_mm : 0.001;
|
||||
std::pair<double, double> ret = { koef * volume / (PI * sqr(0.5 * filament_diameters[extruder_id])),
|
||||
volume * filament_densities[extruder_id] * 0.001 };
|
||||
return ret;
|
||||
};
|
||||
|
||||
ImGui::Dummy({ window_padding, window_padding });
|
||||
ImGui::SameLine();
|
||||
// title and item data
|
||||
{
|
||||
PartPlateList& plate_list = wxGetApp().plater()->get_partplate_list();
|
||||
for (auto plate : plate_list.get_nonempty_plate_list())
|
||||
{
|
||||
auto plate_print_statistics = plate->get_slice_result()->print_statistics;
|
||||
auto plate_extruders = plate->get_extruders(true);
|
||||
for (size_t extruder_id : plate_extruders) {
|
||||
extruder_id -= 1;
|
||||
if (plate_print_statistics.volumes_per_extruder.find(extruder_id) == plate_print_statistics.volumes_per_extruder.end())
|
||||
continue;
|
||||
double volume = plate_print_statistics.volumes_per_extruder.at(extruder_id);
|
||||
volume_of_extruders_all_plates[extruder_id] += volume;
|
||||
if (plate_print_statistics.flush_per_filament.find(extruder_id) == plate_print_statistics.flush_per_filament.end())
|
||||
flushed_volume_of_extruders_all_plates[extruder_id] = 0;
|
||||
else {
|
||||
double flushed_volume = plate_print_statistics.flush_per_filament.at(extruder_id);
|
||||
flushed_volume_of_extruders_all_plates[extruder_id] += flushed_volume;
|
||||
}
|
||||
}
|
||||
const PrintEstimatedStatistics::Mode& plate_time_mode = plate_print_statistics.modes[static_cast<size_t>(m_time_estimate_mode)];
|
||||
total_time_all_plates += plate_time_mode.time;
|
||||
}
|
||||
|
||||
for (auto it = volume_of_extruders_all_plates.begin(); it != volume_of_extruders_all_plates.end(); it++) {
|
||||
auto [model_used_filament_m, model_used_filament_g] = get_used_filament_from_volume(it->second, it->first);
|
||||
model_used_filaments_m_all_plates.push_back(model_used_filament_m);
|
||||
model_used_filaments_g_all_plates.push_back(model_used_filament_g);
|
||||
}
|
||||
for (auto it = flushed_volume_of_extruders_all_plates.begin(); it != flushed_volume_of_extruders_all_plates.end(); it++) {
|
||||
auto [flushed_filament_m, flushed_filament_g] = get_used_filament_from_volume(it->second, it->first);
|
||||
if (flushed_filament_m != 0.0 || flushed_filament_g != 0.0)
|
||||
show_detailed_statistics_page = true;
|
||||
flushed_filaments_m_all_plates.push_back(flushed_filament_m);
|
||||
flushed_filaments_g_all_plates.push_back(flushed_filament_g);
|
||||
}
|
||||
|
||||
char buff[64];
|
||||
double longest_str = 0.0;
|
||||
for (auto i : model_used_filaments_g_all_plates) {
|
||||
if (i > longest_str)
|
||||
longest_str = i;
|
||||
}
|
||||
::sprintf(buff, "%.2f", longest_str);
|
||||
offsets = calculate_offsets({ {_u8L("Filament"), {""}}, {_u8L("Model"), {buff}}, {_u8L("Flushed"), {buff}}, /*{_u8L("Tower"), total_filaments},*/ {_u8L("Total"), {buff}} }, icon_size);
|
||||
|
||||
if (!show_detailed_statistics_page)
|
||||
append_headers({ {_u8L("Filament"), offsets[0]}, {_u8L("Model"), offsets[2]} });
|
||||
else
|
||||
append_headers({ {_u8L("Filament"), offsets[0]}, {_u8L("Model"), offsets[1]}, {_u8L("Flushed"), offsets[2]}, /*{_u8L("Tower"), offsets[3]},*/ {_u8L("Total"), offsets[3]} });// to add Tower
|
||||
}
|
||||
|
||||
// item
|
||||
{
|
||||
size_t i = 0;
|
||||
for (auto it = volume_of_extruders_all_plates.begin(); it != volume_of_extruders_all_plates.end(); it++) {
|
||||
if (i < model_used_filaments_m_all_plates.size() && i < model_used_filaments_g_all_plates.size()) {
|
||||
std::vector<std::pair<std::string, float>> columns_offsets;
|
||||
columns_offsets.push_back({ std::to_string(it->first + 1), offsets[0] });
|
||||
|
||||
char buf[64];
|
||||
if (show_detailed_statistics_page) {
|
||||
::sprintf(buf, imperial_units ? "%.2f in\n%.2f oz" : "%.2f m\n%.2f g", model_used_filaments_m_all_plates[i], model_used_filaments_g_all_plates[i]);
|
||||
columns_offsets.push_back({ buf, offsets[1] });
|
||||
|
||||
::sprintf(buf, imperial_units ? "%.2f in\n%.2f oz" : "%.2f m\n%.2f g", flushed_filaments_m_all_plates[i], flushed_filaments_g_all_plates[i]);
|
||||
columns_offsets.push_back({ buf, offsets[2] });
|
||||
|
||||
::sprintf(buf, imperial_units ? "%.2f in\n%.2f oz" : "%.2f m\n%.2f g", model_used_filaments_m_all_plates[i] + flushed_filaments_m_all_plates[i], model_used_filaments_g_all_plates[i] + flushed_filaments_g_all_plates[i]);
|
||||
columns_offsets.push_back({ buf, offsets[3] });
|
||||
}
|
||||
else {
|
||||
::sprintf(buf, imperial_units ? "%.2f in %.2f oz" : "%.2f m %.2f g", model_used_filaments_m_all_plates[i], model_used_filaments_g_all_plates[i]);
|
||||
columns_offsets.push_back({ buf, offsets[2] });
|
||||
}
|
||||
|
||||
append_item(filament_colors[it->first], columns_offsets);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
ImGui::Dummy(ImVec2(0.0f, ImGui::GetFontSize() * 0.1));
|
||||
ImGui::Dummy({ window_padding, window_padding });
|
||||
ImGui::SameLine();
|
||||
imgui.title(_u8L("Total Time Estimation"));
|
||||
|
||||
ImGui::Dummy({ window_padding, window_padding });
|
||||
ImGui::SameLine();
|
||||
imgui.text(_u8L("Total time") + ":");
|
||||
ImGui::SameLine();
|
||||
imgui.text(short_time(get_time_dhms(total_time_all_plates)));
|
||||
}
|
||||
ImGui::End();
|
||||
ImGui::PopStyleColor(6);
|
||||
ImGui::PopStyleVar(3);
|
||||
return;
|
||||
}
|
||||
|
||||
void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canvas_height, int right_margin)
|
||||
{
|
||||
if (!m_legend_enabled)
|
||||
|
|
@ -4283,8 +4502,6 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
|||
const float step_size = range.step_size();
|
||||
for (int i = static_cast<int>(Range_Colors.size()) - 1; i >= 0; --i) {
|
||||
append_range_item(i, range.get_value_at_step(i), decimals);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -4376,6 +4593,11 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
|||
return (it != time_mode.roles_times.end()) ? std::make_pair(it->second, it->second / time_mode.time) : std::make_pair(0.0f, 0.0f);
|
||||
};
|
||||
|
||||
auto move_time_and_percent = [time_mode](EMoveType move_type) {
|
||||
auto it = std::find_if(time_mode.moves_times.begin(), time_mode.moves_times.end(), [move_type](const std::pair<EMoveType, float>& item) { return move_type == item.first; });
|
||||
return (it != time_mode.moves_times.end()) ? std::make_pair(it->second, it->second / time_mode.time) : std::make_pair(0.0f, 0.0f);
|
||||
};
|
||||
|
||||
auto used_filament_per_role = [this, imperial_units](ExtrusionRole role) {
|
||||
auto it = m_print_statistics.used_filaments_per_role.find(role);
|
||||
if (it == m_print_statistics.used_filaments_per_role.end())
|
||||
|
|
@ -4385,6 +4607,14 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
|||
return std::make_pair(it->second.first * koef, it->second.second);
|
||||
};
|
||||
|
||||
// get used filament (meters and grams) from used volume in respect to the active extruder
|
||||
auto get_used_filament_from_volume = [this, imperial_units](double volume, int extruder_id) {
|
||||
double koef = imperial_units ? 1.0 / GizmoObjectManipulation::in_to_mm : 0.001;
|
||||
std::pair<double, double> ret = { koef * volume / (PI * sqr(0.5 * m_filament_diameters[extruder_id])),
|
||||
volume * m_filament_densities[extruder_id] * 0.001 };
|
||||
return ret;
|
||||
};
|
||||
|
||||
//BBS display Color Scheme
|
||||
ImGui::Dummy({ window_padding, window_padding });
|
||||
ImGui::Dummy({ window_padding, window_padding });
|
||||
|
|
@ -4449,7 +4679,9 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
|||
std::vector<float> offsets;
|
||||
std::vector<std::string> labels;
|
||||
std::vector<std::string> times;
|
||||
std::string travel_time;
|
||||
std::vector<std::string> percents;
|
||||
std::string travel_percent;
|
||||
std::vector<double> model_used_filaments_m;
|
||||
std::vector<double> model_used_filaments_g;
|
||||
double total_model_used_filament_m = 0, total_model_used_filament_g = 0;
|
||||
|
|
@ -4462,13 +4694,6 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
|||
double koef = imperial_units ? GizmoObjectManipulation::in_to_mm : 1000.0;
|
||||
double unit_conver = imperial_units ? GizmoObjectManipulation::oz_to_g : 1;
|
||||
|
||||
// get used filament (meters and grams) from used volume in respect to the active extruder
|
||||
auto get_used_filament_from_volume = [this, imperial_units](double volume, int extruder_id) {
|
||||
double koef = imperial_units ? 1.0 / GizmoObjectManipulation::in_to_mm : 0.001;
|
||||
std::pair<double, double> ret = { koef * volume / (PI * sqr(0.5 * m_filament_diameters[extruder_id])),
|
||||
volume * m_filament_densities[extruder_id] * 0.001 };
|
||||
return ret;
|
||||
};
|
||||
|
||||
// extrusion paths section -> title
|
||||
ImGui::Dummy({ window_padding, window_padding });
|
||||
|
|
@ -4496,6 +4721,17 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
|||
}
|
||||
}
|
||||
|
||||
//BBS: get travel time and percent
|
||||
{
|
||||
auto [time, percent] = move_time_and_percent(EMoveType::Travel);
|
||||
travel_time = (time > 0.0f) ? short_time(get_time_dhms(time)) : "";
|
||||
if (percent == 0)
|
||||
::sprintf(buffer, "0%%");
|
||||
else
|
||||
percent > 0.001 ? ::sprintf(buffer, "%.1f%%", percent * 100) : ::sprintf(buffer, "<0.1%%");
|
||||
travel_percent = buffer;
|
||||
}
|
||||
|
||||
offsets = calculate_offsets({ {_u8L("Line Type"), labels}, {_u8L("Time"), times}, {_u8L("Percent"), percents}, {_u8L("Display"), {""}}}, icon_size);
|
||||
append_headers({{_u8L("Line Type"), offsets[0]}, {_u8L("Time"), offsets[1]}, {_u8L("Percent"), offsets[2]}, {_u8L("Display"), offsets[3]}});
|
||||
break;
|
||||
|
|
@ -4584,7 +4820,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
|
||||
//BBS: only display travel time in FeatureType view
|
||||
append_option_item_with_type(type, Travel_Colors[0], _u8L("Travel"), visible);
|
||||
}
|
||||
else if (type == EMoveType::Seam)
|
||||
|
|
@ -4624,7 +4860,23 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
|||
}
|
||||
|
||||
for(auto item : options_items) {
|
||||
append_option_item(item, offsets);
|
||||
if (item != EMoveType::Travel) {
|
||||
append_option_item(item, offsets);
|
||||
} else {
|
||||
//BBS: show travel time in FeatureType view
|
||||
const bool visible = m_buffers[buffer_id(item)].visible;
|
||||
std::vector<std::pair<std::string, float>> columns_offsets;
|
||||
columns_offsets.push_back({ _u8L("Travel"), offsets[0] });
|
||||
columns_offsets.push_back({ travel_time, offsets[1] });
|
||||
columns_offsets.push_back({ travel_percent, offsets[2] });
|
||||
append_item(EItemType::Rect, Travel_Colors[0], columns_offsets, true, visible, [this, item, visible]() {
|
||||
m_buffers[buffer_id(item)].visible = !m_buffers[buffer_id(item)].visible;
|
||||
// update buffers' render paths
|
||||
refresh_render_paths(false, false);
|
||||
update_moves_slider();
|
||||
wxGetApp().plater()->get_current_canvas3D()->set_as_dirty();
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -4668,7 +4920,8 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
|||
}
|
||||
case EViewType::ColorPrint:
|
||||
{
|
||||
const std::vector<CustomGCode::Item>& custom_gcode_per_print_z = wxGetApp().is_editor() ? wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes : m_custom_gcode_per_print_z;
|
||||
//BBS: replace model custom gcode with current plate custom gcode
|
||||
const std::vector<CustomGCode::Item>& custom_gcode_per_print_z = wxGetApp().is_editor() ? wxGetApp().plater()->model().get_curr_plate_custom_gcodes().gcodes : m_custom_gcode_per_print_z;
|
||||
size_t total_items = 1;
|
||||
for (size_t extruder_id : m_extruder_ids) {
|
||||
total_items += color_print_ranges(extruder_id, custom_gcode_per_print_z).size();
|
||||
|
|
@ -4722,13 +4975,13 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
|||
|
||||
char buf[64];
|
||||
if (show_flushed_filaments) {
|
||||
::sprintf(buf, imperial_units ? "%.2f in\n%.2f g" : "%.2f m\n%.2f g", model_used_filaments_m[i], model_used_filaments_g[i]);
|
||||
::sprintf(buf, imperial_units ? "%.2f in\n%.2f oz" : "%.2f m\n%.2f g", model_used_filaments_m[i], model_used_filaments_g[i]);
|
||||
columns_offsets.push_back({ buf, offsets[1] });
|
||||
|
||||
::sprintf(buf, imperial_units ? "%.2f in\n%.2f g" : "%.2f m\n%.2f g", flushed_filaments_m[i], flushed_filaments_g[i]);
|
||||
::sprintf(buf, imperial_units ? "%.2f in\n%.2f oz" : "%.2f m\n%.2f g", flushed_filaments_m[i], flushed_filaments_g[i]);
|
||||
columns_offsets.push_back({ buf, offsets[2] });
|
||||
|
||||
::sprintf(buf, imperial_units ? "%.2f in\n%.2f g" : "%.2f m\n%.2f g", model_used_filaments_m[i] + flushed_filaments_m[i], model_used_filaments_g[i] + flushed_filaments_g[i]);
|
||||
::sprintf(buf, imperial_units ? "%.2f in\n%.2f oz" : "%.2f m\n%.2f g", model_used_filaments_m[i] + flushed_filaments_m[i], model_used_filaments_g[i] + flushed_filaments_g[i]);
|
||||
columns_offsets.push_back({ buf, offsets[3] });
|
||||
}
|
||||
else {
|
||||
|
|
@ -4850,7 +5103,8 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
|||
auto generate_partial_times = [this, get_used_filament_from_volume](const TimesList& times, const std::vector<double>& used_filaments) {
|
||||
PartialTimes items;
|
||||
|
||||
std::vector<CustomGCode::Item> custom_gcode_per_print_z = wxGetApp().is_editor() ? wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes : m_custom_gcode_per_print_z;
|
||||
//BBS: replace model custom gcode with current plate custom gcode
|
||||
std::vector<CustomGCode::Item> custom_gcode_per_print_z = wxGetApp().is_editor() ? wxGetApp().plater()->model().get_curr_plate_custom_gcodes().gcodes : m_custom_gcode_per_print_z;
|
||||
std::vector<Color> last_color(m_extruders_count);
|
||||
for (size_t i = 0; i < m_extruders_count; ++i) {
|
||||
last_color[i] = m_tools.m_tool_colors[i];
|
||||
|
|
@ -5220,19 +5474,19 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
|||
auto it = std::find_if(time_mode.roles_times.begin(), time_mode.roles_times.end(), [role](const std::pair<ExtrusionRole, float>& item) { return role == item.first; });
|
||||
return (it != time_mode.roles_times.end()) ? it->second : 0.0f;
|
||||
};
|
||||
//BBS: start gcode is prepeare time
|
||||
if (role_time(erCustom) != 0.0f) {
|
||||
//BBS: start gcode is mostly same with prepeare time
|
||||
if (time_mode.prepare_time != 0.0f) {
|
||||
ImGui::Dummy({ window_padding, window_padding });
|
||||
ImGui::SameLine();
|
||||
imgui.text(prepare_str + ":");
|
||||
ImGui::SameLine(max_len);
|
||||
imgui.text(short_time(get_time_dhms(role_time(erCustom))));
|
||||
imgui.text(short_time(get_time_dhms(time_mode.prepare_time)));
|
||||
}
|
||||
ImGui::Dummy({ window_padding, window_padding });
|
||||
ImGui::SameLine();
|
||||
imgui.text(print_str + ":");
|
||||
ImGui::SameLine(max_len);
|
||||
imgui.text(short_time(get_time_dhms(time_mode.time - role_time(erCustom))));
|
||||
imgui.text(short_time(get_time_dhms(time_mode.time - time_mode.prepare_time)));
|
||||
ImGui::Dummy({ window_padding, window_padding });
|
||||
ImGui::SameLine();
|
||||
imgui.text(total_str + ":");
|
||||
|
|
@ -5264,16 +5518,16 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
|||
}
|
||||
default : { assert(false); break; }
|
||||
}
|
||||
}
|
||||
|
||||
if (m_view_type == EViewType::ColorPrint) {
|
||||
ImGui::Spacing();
|
||||
ImGui::Dummy({ window_padding, window_padding });
|
||||
ImGui::SameLine();
|
||||
offsets = calculate_offsets({ { _u8L("Options"), { ""}}, { _u8L("Display"), {""}} }, icon_size);
|
||||
append_headers({ {_u8L("Options"), offsets[0] }, { _u8L("Display"), offsets[1]} });
|
||||
for (auto item : options_items)
|
||||
append_option_item(item, offsets);
|
||||
}
|
||||
if (m_view_type == EViewType::ColorPrint) {
|
||||
ImGui::Spacing();
|
||||
ImGui::Dummy({ window_padding, window_padding });
|
||||
ImGui::SameLine();
|
||||
offsets = calculate_offsets({ { _u8L("Options"), { ""}}, { _u8L("Display"), {""}} }, icon_size);
|
||||
append_headers({ {_u8L("Options"), offsets[0] }, { _u8L("Display"), offsets[1]} });
|
||||
for (auto item : options_items)
|
||||
append_option_item(item, offsets);
|
||||
}
|
||||
|
||||
legend_height = ImGui::GetCurrentWindow()->Size.y;
|
||||
|
|
@ -5304,7 +5558,6 @@ void GCodeViewer::pop_combo_style()
|
|||
}
|
||||
|
||||
void GCodeViewer::render_slider(int canvas_width, int canvas_height) {
|
||||
|
||||
m_moves_slider->render(canvas_width, canvas_height);
|
||||
m_layers_slider->render(canvas_width, canvas_height);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -809,6 +809,8 @@ public:
|
|||
void reset_shell();
|
||||
void load_shells(const Print& print, bool initialized, bool force_previewing = false);
|
||||
void set_shells_on_preview(bool is_previewing) { m_shells.previewing = is_previewing; }
|
||||
//BBS: add all plates filament statistics
|
||||
void render_all_plates_stats(const std::vector<const GCodeProcessorResult*>& gcode_result_list, bool show = true) const;
|
||||
//BBS: GUI refactor: add canvas width and height
|
||||
void render(int canvas_width, int canvas_height, int right_margin);
|
||||
//BBS
|
||||
|
|
|
|||
|
|
@ -74,8 +74,8 @@ static constexpr const float TRACKBALLSIZE = 0.8f;
|
|||
|
||||
static const float SLIDER_DEFAULT_RIGHT_MARGIN = 10.0f;
|
||||
static const float SLIDER_DEFAULT_BOTTOM_MARGIN = 10.0f;
|
||||
static const float SLIDER_RIGHT_MARGIN = 115.0f;
|
||||
static const float SLIDER_BOTTOM_MARGIN = 90.0f;
|
||||
static const float SLIDER_RIGHT_MARGIN = 124.0f;
|
||||
static const float SLIDER_BOTTOM_MARGIN = 64.0f;
|
||||
|
||||
float GLCanvas3D::DEFAULT_BG_LIGHT_COLOR[3] = { 0.906f, 0.906f, 0.906f };
|
||||
float GLCanvas3D::DEFAULT_BG_LIGHT_COLOR_DARK[3] = { 0.329f, 0.329f, 0.353f };
|
||||
|
|
@ -1160,6 +1160,7 @@ GLCanvas3D::~GLCanvas3D()
|
|||
reset_volumes();
|
||||
|
||||
m_sel_plate_toolbar.del_all_item();
|
||||
m_sel_plate_toolbar.del_stats_item();
|
||||
}
|
||||
|
||||
void GLCanvas3D::post_event(wxEvent &&event)
|
||||
|
|
@ -1608,6 +1609,11 @@ void GLCanvas3D::enable_main_toolbar(bool enable)
|
|||
m_main_toolbar.set_enabled(enable);
|
||||
}
|
||||
|
||||
void GLCanvas3D::reset_select_plate_toolbar_selection() {
|
||||
if (m_sel_plate_toolbar.m_all_plates_stats_item)
|
||||
m_sel_plate_toolbar.m_all_plates_stats_item->selected = false;
|
||||
}
|
||||
|
||||
void GLCanvas3D::enable_select_plate_toolbar(bool enable)
|
||||
{
|
||||
m_sel_plate_toolbar.set_enabled(enable);
|
||||
|
|
@ -1721,6 +1727,9 @@ float GLCanvas3D::get_collapse_toolbar_height()
|
|||
return collapse_toolbar.is_enabled() ? collapse_toolbar.get_height() : 0;
|
||||
}
|
||||
|
||||
bool GLCanvas3D::make_current_for_postinit() {
|
||||
return _set_current();
|
||||
}
|
||||
|
||||
void GLCanvas3D::render(bool only_init)
|
||||
{
|
||||
|
|
@ -1844,7 +1853,7 @@ void GLCanvas3D::render(bool only_init)
|
|||
_render_platelist(!camera.is_looking_downward(), only_current, only_body, hover_id);
|
||||
}
|
||||
/* preview render */
|
||||
else if (m_canvas_type == ECanvasType::CanvasPreview) {
|
||||
else if (m_canvas_type == ECanvasType::CanvasPreview && m_render_preview) {
|
||||
//BBS: add outline logic
|
||||
_render_objects(GLVolumeCollection::ERenderType::Opaque, !m_gizmos.is_running());
|
||||
//BBS: GUI refactor: add canvas size as parameters
|
||||
|
|
@ -2045,6 +2054,17 @@ void GLCanvas3D::deselect_all()
|
|||
post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT));
|
||||
}
|
||||
|
||||
void GLCanvas3D::set_selected_visible(bool visible)
|
||||
{
|
||||
for (unsigned int i : m_selection.get_volume_idxs()) {
|
||||
GLVolume* volume = const_cast<GLVolume*>(m_selection.get_volume(i));
|
||||
volume->visible = visible;
|
||||
volume->color[3] = visible ? 1.f : GLVolume::MODEL_HIDDEN_COL[3];
|
||||
volume->render_color[3] = volume->color[3];
|
||||
volume->force_native_color = !visible;
|
||||
}
|
||||
}
|
||||
|
||||
void GLCanvas3D::delete_selected()
|
||||
{
|
||||
m_selection.erase();
|
||||
|
|
@ -2383,8 +2403,21 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
|||
}
|
||||
}
|
||||
for (int temp_idx = vol_idx; temp_idx < m_volumes.volumes.size() && !update_object_list; temp_idx++) {
|
||||
if (!m_volumes.volumes[temp_idx]->is_wipe_tower)
|
||||
// Volumes in m_volumes might not exist anymore, so we cannot
|
||||
// directly check if they are is_wipe_towers, for which we do
|
||||
// not want to update the object list. Instead, we do a kind of
|
||||
// slow thing of seeing if they were in the deleted list, and if
|
||||
// so, if they were a wipe tower.
|
||||
bool was_deleted_wipe_tower = false;
|
||||
for (int del_idx = 0; del_idx < deleted_wipe_towers.size(); del_idx++) {
|
||||
if (deleted_wipe_towers[del_idx].volume_idx == temp_idx) {
|
||||
was_deleted_wipe_tower = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!was_deleted_wipe_tower) {
|
||||
update_object_list = true;
|
||||
}
|
||||
}
|
||||
for (int temp_idx = vol_idx; temp_idx < glvolumes_new.size() && !update_object_list; temp_idx++) {
|
||||
if (!glvolumes_new[temp_idx]->is_wipe_tower)
|
||||
|
|
@ -2536,8 +2569,12 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
|||
auto timelapse_type = dconfig.option<ConfigOptionEnum<TimelapseType>>("timelapse_type");
|
||||
bool timelapse_enabled = timelapse_type ? (timelapse_type->value == TimelapseType::tlSmooth) : false;
|
||||
|
||||
if ((timelapse_enabled && wt) || (filaments_count > 1 && wt && co != nullptr && co->value != PrintSequence::ByObject)) {
|
||||
if (wt && (timelapse_enabled || filaments_count > 1)) {
|
||||
for (int plate_id = 0; plate_id < n_plates; plate_id++) {
|
||||
// If print ByObject and there is only one object in the plate, the wipe tower is allowed to be generated.
|
||||
if (co != nullptr && co->value == PrintSequence::ByObject && ppl.get_plate(plate_id)->printable_instance_size() != 1)
|
||||
continue;
|
||||
|
||||
DynamicPrintConfig& proj_cfg = wxGetApp().preset_bundle->project_config;
|
||||
float x = dynamic_cast<const ConfigOptionFloats*>(proj_cfg.option("wipe_tower_x"))->get_at(plate_id);
|
||||
float y = dynamic_cast<const ConfigOptionFloats*>(proj_cfg.option("wipe_tower_y"))->get_at(plate_id);
|
||||
|
|
@ -3458,6 +3495,7 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
|
|||
}
|
||||
}
|
||||
}
|
||||
else return;
|
||||
}
|
||||
|
||||
if (keyCode != WXK_TAB
|
||||
|
|
@ -3529,6 +3567,28 @@ void GLCanvas3D::on_mouse_wheel(wxMouseEvent& evt)
|
|||
if (m_gizmos.on_mouse_wheel(evt))
|
||||
return;
|
||||
|
||||
if (m_canvas_type == CanvasAssembleView && (evt.AltDown() || evt.CmdDown())) {
|
||||
float rotation = (float)evt.GetWheelRotation() / (float)evt.GetWheelDelta();
|
||||
if (evt.AltDown()) {
|
||||
auto clp_dist = m_gizmos.m_assemble_view_data->model_objects_clipper()->get_position();
|
||||
clp_dist = rotation < 0.f
|
||||
? std::max(0., clp_dist - 0.01)
|
||||
: std::min(1., clp_dist + 0.01);
|
||||
m_gizmos.m_assemble_view_data->model_objects_clipper()->set_position(clp_dist, true);
|
||||
}
|
||||
else if (evt.CmdDown()) {
|
||||
m_explosion_ratio = rotation < 0.f
|
||||
? std::max(1., m_explosion_ratio - 0.01)
|
||||
: std::min(3., m_explosion_ratio + 0.01);
|
||||
if (m_explosion_ratio != GLVolume::explosion_ratio) {
|
||||
for (GLVolume* volume : m_volumes.volumes) {
|
||||
volume->set_bounding_boxes_as_dirty();
|
||||
}
|
||||
GLVolume::explosion_ratio = m_explosion_ratio;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Calculate the zoom delta and apply it to the current zoom factor
|
||||
#ifdef SUPPORT_REVERSE_MOUSE_ZOOM
|
||||
double direction_factor = (wxGetApp().app_config->get("reverse_mouse_wheel_zoom") == "1") ? -1.0 : 1.0;
|
||||
|
|
@ -4235,6 +4295,10 @@ void GLCanvas3D::on_paint(wxPaintEvent& evt)
|
|||
this->render();
|
||||
}
|
||||
|
||||
void GLCanvas3D::force_set_focus() {
|
||||
m_canvas->SetFocus();
|
||||
};
|
||||
|
||||
void GLCanvas3D::on_set_focus(wxFocusEvent& evt)
|
||||
{
|
||||
m_tooltip_enabled = false;
|
||||
|
|
@ -5753,6 +5817,9 @@ bool GLCanvas3D::_init_toolbars()
|
|||
if (!_init_separator_toolbar())
|
||||
return false;
|
||||
|
||||
if (!_init_select_plate_toolbar())
|
||||
return false;
|
||||
|
||||
#if 0
|
||||
if (!_init_view_toolbar())
|
||||
return false;
|
||||
|
|
@ -5918,7 +5985,24 @@ bool GLCanvas3D::_init_main_toolbar()
|
|||
//BBS: GUI refactor: GLToolbar
|
||||
bool GLCanvas3D::_init_select_plate_toolbar()
|
||||
{
|
||||
return true;
|
||||
std::string path = resources_dir() + "/images/";
|
||||
IMToolbarItem* item = new IMToolbarItem();
|
||||
bool result = item->image_texture.load_from_svg_file(path + "im_all_plates_stats.svg", false, false, false, 128);
|
||||
result = result && item->image_texture_transparent.load_from_svg_file(path + "im_all_plates_stats_transparent.svg", false, false, false, 128);
|
||||
m_sel_plate_toolbar.m_all_plates_stats_item = item;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void GLCanvas3D::_update_select_plate_toolbar_stats_item(bool force_selected) {
|
||||
PartPlateList& plate_list = wxGetApp().plater()->get_partplate_list();
|
||||
if (plate_list.get_nonempty_plate_list().size() > 1)
|
||||
m_sel_plate_toolbar.show_stats_item = true;
|
||||
else
|
||||
m_sel_plate_toolbar.show_stats_item = false;
|
||||
|
||||
if (force_selected && m_sel_plate_toolbar.show_stats_item)
|
||||
m_sel_plate_toolbar.m_all_plates_stats_item->selected = true;
|
||||
}
|
||||
|
||||
bool GLCanvas3D::_update_imgui_select_plate_toolbar()
|
||||
|
|
@ -5926,6 +6010,8 @@ bool GLCanvas3D::_update_imgui_select_plate_toolbar()
|
|||
bool result = true;
|
||||
if (!m_sel_plate_toolbar.is_enabled()) return false;
|
||||
|
||||
_update_select_plate_toolbar_stats_item();
|
||||
|
||||
m_sel_plate_toolbar.del_all_item();
|
||||
|
||||
PartPlateList& plate_list = wxGetApp().plater()->get_partplate_list();
|
||||
|
|
@ -5941,6 +6027,7 @@ bool GLCanvas3D::_update_imgui_select_plate_toolbar()
|
|||
}
|
||||
m_sel_plate_toolbar.m_items.push_back(item);
|
||||
}
|
||||
|
||||
m_sel_plate_toolbar.is_display_scrollbar = false;
|
||||
return result;
|
||||
}
|
||||
|
|
@ -6565,7 +6652,7 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with
|
|||
return true;
|
||||
}
|
||||
}, with_outline);
|
||||
if (m_canvas_type == CanvasAssembleView) {
|
||||
if (m_canvas_type == CanvasAssembleView && m_gizmos.m_assemble_view_data->model_objects_clipper()->get_position() > 0) {
|
||||
const GLGizmosManager& gm = get_gizmos_manager();
|
||||
shader->stop_using();
|
||||
gm.render_painter_assemble_view();
|
||||
|
|
@ -7031,20 +7118,26 @@ void GLCanvas3D::_render_main_toolbar()
|
|||
|
||||
//BBS: GUI refactor: GLToolbar adjust
|
||||
//when rendering, {0, 0} is at the center, {-0.5, 0.5} at the left-up
|
||||
void GLCanvas3D::_render_imgui_select_plate_toolbar() const
|
||||
void GLCanvas3D::_render_imgui_select_plate_toolbar()
|
||||
{
|
||||
if (!m_sel_plate_toolbar.is_enabled())
|
||||
if (!m_sel_plate_toolbar.is_enabled()) {
|
||||
if (!m_render_preview)
|
||||
m_render_preview = true;
|
||||
return;
|
||||
}
|
||||
|
||||
IMToolbarItem* all_plates_stats_item = m_sel_plate_toolbar.m_all_plates_stats_item;
|
||||
|
||||
PartPlateList& plate_list = wxGetApp().plater()->get_partplate_list();
|
||||
for (int i = 0; i < plate_list.get_plate_count(); i++) {
|
||||
if (i < m_sel_plate_toolbar.m_items.size()) {
|
||||
if (i == plate_list.get_curr_plate_index())
|
||||
if (i == plate_list.get_curr_plate_index() && !all_plates_stats_item->selected)
|
||||
m_sel_plate_toolbar.m_items[i]->selected = true;
|
||||
else
|
||||
m_sel_plate_toolbar.m_items[i]->selected = false;
|
||||
|
||||
m_sel_plate_toolbar.m_items[i]->percent = plate_list.get_plate(i)->get_slicing_percent();
|
||||
|
||||
if (plate_list.get_plate(i)->is_slice_result_valid()) {
|
||||
if (plate_list.get_plate(i)->is_slice_result_ready_for_print())
|
||||
m_sel_plate_toolbar.m_items[i]->slice_state = IMToolbarItem::SliceState::SLICED;
|
||||
|
|
@ -7058,6 +7151,46 @@ void GLCanvas3D::_render_imgui_select_plate_toolbar() const
|
|||
m_sel_plate_toolbar.m_items[i]->slice_state = IMToolbarItem::SliceState::SLICING;
|
||||
}
|
||||
}
|
||||
if (m_sel_plate_toolbar.show_stats_item) {
|
||||
all_plates_stats_item->percent = 0.0f;
|
||||
|
||||
size_t sliced_plates_cnt = 0;
|
||||
bool slice_failed = false;
|
||||
for (auto plate : plate_list.get_nonempty_plate_list()) {
|
||||
if (plate->is_slice_result_valid() && plate->is_slice_result_ready_for_print())
|
||||
sliced_plates_cnt++;
|
||||
if (plate->is_slice_result_valid() && !plate->is_slice_result_ready_for_print())
|
||||
slice_failed = true;
|
||||
}
|
||||
all_plates_stats_item->percent = (float)(sliced_plates_cnt) / (float)(plate_list.get_nonempty_plate_list().size()) * 100.0f;
|
||||
|
||||
if (all_plates_stats_item->percent == 0.0f)
|
||||
all_plates_stats_item->slice_state = IMToolbarItem::SliceState::UNSLICED;
|
||||
else if (sliced_plates_cnt == plate_list.get_nonempty_plate_list().size())
|
||||
all_plates_stats_item->slice_state = IMToolbarItem::SliceState::SLICED;
|
||||
else if (all_plates_stats_item->percent < 100.0f)
|
||||
all_plates_stats_item->slice_state = IMToolbarItem::SliceState::SLICING;
|
||||
|
||||
if (slice_failed)
|
||||
all_plates_stats_item->slice_state = IMToolbarItem::SliceState::SLICE_FAILED;
|
||||
|
||||
// Changing parameters does not invalid all plates, need extra logic to validate
|
||||
bool gcode_result_valid = true;
|
||||
for (auto gcode_result : plate_list.get_nonempty_plates_slice_results()) {
|
||||
if (gcode_result->moves.size() == 0) {
|
||||
gcode_result_valid = false;
|
||||
}
|
||||
}
|
||||
if (all_plates_stats_item->selected && all_plates_stats_item->slice_state == IMToolbarItem::SliceState::SLICED && gcode_result_valid) {
|
||||
m_gcode_viewer.render_all_plates_stats(plate_list.get_nonempty_plates_slice_results());
|
||||
m_render_preview = false;
|
||||
}
|
||||
else{
|
||||
m_gcode_viewer.render_all_plates_stats(plate_list.get_nonempty_plates_slice_results(), false);
|
||||
m_render_preview = true;
|
||||
}
|
||||
}else
|
||||
m_render_preview = true;
|
||||
|
||||
// places the toolbar on the top_left corner of the 3d scene
|
||||
#if ENABLE_RETINA_GL
|
||||
|
|
@ -7081,7 +7214,7 @@ void GLCanvas3D::_render_imgui_select_plate_toolbar() const
|
|||
float button_margin = frame_padding;
|
||||
|
||||
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
||||
int item_count = m_sel_plate_toolbar.m_items.size();
|
||||
int item_count = m_sel_plate_toolbar.m_items.size() + (m_sel_plate_toolbar.show_stats_item ? 1 : 0);
|
||||
bool show_scroll = item_count * (button_height + frame_padding * 2.0f + button_margin) - button_margin + 22.0f * f_scale > canvas_h ? true: false;
|
||||
show_scroll = m_sel_plate_toolbar.is_display_scrollbar && show_scroll;
|
||||
float window_height = std::min(item_count * (button_height + (frame_padding + margin_size) * 2.0f + button_margin) - button_margin + 28.0f * f_scale, canvas_h);
|
||||
|
|
@ -7122,7 +7255,89 @@ void GLCanvas3D::_render_imgui_select_plate_toolbar() const
|
|||
ImVec4 tint_col = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // No tint
|
||||
ImVec2 margin = ImVec2(margin_size, margin_size);
|
||||
|
||||
for (int i = 0; i < item_count; i++) {
|
||||
if(m_sel_plate_toolbar.show_stats_item)
|
||||
{
|
||||
// draw image
|
||||
ImVec2 button_start_pos = ImGui::GetCursorScreenPos();
|
||||
|
||||
if (all_plates_stats_item->selected) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, button_active);
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, button_active);
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, button_active);
|
||||
}
|
||||
else {
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(128.0f, 128.0f, 128.0f, 0.0f));
|
||||
if (all_plates_stats_item->slice_state == IMToolbarItem::SliceState::SLICE_FAILED) {
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::GetStyleColorVec4(ImGuiCol_Button));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGui::GetStyleColorVec4(ImGuiCol_Button));
|
||||
}
|
||||
else {
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, button_hover);
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.42f, 0.42f, 0.42f, 1.0f));
|
||||
}
|
||||
}
|
||||
|
||||
ImVec4 text_clr;
|
||||
ImTextureID btn_texture_id;
|
||||
if (all_plates_stats_item->slice_state == IMToolbarItem::SliceState::UNSLICED || all_plates_stats_item->slice_state == IMToolbarItem::SliceState::SLICING || all_plates_stats_item->slice_state == IMToolbarItem::SliceState::SLICE_FAILED)
|
||||
{
|
||||
text_clr = ImVec4(0, 174.0f / 255.0f, 66.0f / 255.0f, 0.2f);
|
||||
btn_texture_id = (ImTextureID)(intptr_t)(all_plates_stats_item->image_texture_transparent.get_id());
|
||||
}
|
||||
else
|
||||
{
|
||||
text_clr = ImVec4(0, 174.0f / 255.0f, 66.0f / 255.0f, 1);
|
||||
btn_texture_id = (ImTextureID)(intptr_t)(all_plates_stats_item->image_texture.get_id());
|
||||
}
|
||||
|
||||
if (ImGui::ImageButton2(btn_texture_id, size, {0,0}, {1,1}, frame_padding, bg_col, tint_col, margin)) {
|
||||
if (all_plates_stats_item->slice_state != IMToolbarItem::SliceState::SLICE_FAILED) {
|
||||
if (m_process && !m_process->running()) {
|
||||
for (int i = 0; i < m_sel_plate_toolbar.m_items.size(); i++) {
|
||||
m_sel_plate_toolbar.m_items[i]->selected = false;
|
||||
}
|
||||
all_plates_stats_item->selected = true;
|
||||
wxCommandEvent evt = wxCommandEvent(EVT_GLTOOLBAR_SLICE_ALL);
|
||||
wxPostEvent(wxGetApp().plater(), evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::PopStyleColor(3);
|
||||
|
||||
ImVec2 start_pos = ImVec2(button_start_pos.x + frame_padding + margin.x, button_start_pos.y + frame_padding + margin.y);
|
||||
if (all_plates_stats_item->slice_state == IMToolbarItem::SliceState::UNSLICED) {
|
||||
ImVec2 size = ImVec2(button_width, button_height);
|
||||
ImVec2 end_pos = ImVec2(start_pos.x + size.x, start_pos.y + size.y);
|
||||
ImGui::GetForegroundDrawList()->AddRectFilled(start_pos, end_pos, IM_COL32(0, 0, 0, 80));
|
||||
}
|
||||
else if (all_plates_stats_item->slice_state == IMToolbarItem::SliceState::SLICING) {
|
||||
ImVec2 size = ImVec2(button_width, button_height * all_plates_stats_item->percent / 100.0f);
|
||||
ImVec2 rect_start_pos = ImVec2(start_pos.x, start_pos.y + size.y);
|
||||
ImVec2 rect_end_pos = ImVec2(start_pos.x + button_width, start_pos.y + button_height);
|
||||
ImGui::GetForegroundDrawList()->AddRectFilled(rect_start_pos, rect_end_pos, IM_COL32(0, 0, 0, 80));
|
||||
}
|
||||
else if (all_plates_stats_item->slice_state == IMToolbarItem::SliceState::SLICE_FAILED) {
|
||||
ImVec2 size = ImVec2(button_width, button_height);
|
||||
ImVec2 end_pos = ImVec2(start_pos.x + size.x, start_pos.y + size.y);
|
||||
ImGui::GetForegroundDrawList()->AddRectFilled(start_pos, end_pos, IM_COL32(40, 1, 1, 64));
|
||||
ImGui::GetForegroundDrawList()->AddRect(start_pos, end_pos, IM_COL32(208, 27, 27, 255), 0.0f, 0, 1.0f);
|
||||
}
|
||||
|
||||
// draw text
|
||||
GImGui->FontSize = 15.0f;
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, text_clr);
|
||||
ImVec2 text_size = ImGui::CalcTextSize(("All Plates"));
|
||||
ImVec2 text_start_pos = ImVec2(start_pos.x + (button_width - text_size.x) / 2, start_pos.y + 3.0f * button_height / 5.0f);
|
||||
ImGui::RenderText(text_start_pos, ("All Plates"));
|
||||
text_size = ImGui::CalcTextSize(("Stats"));
|
||||
text_start_pos = ImVec2(start_pos.x + (button_width - text_size.x) / 2, text_start_pos.y + ImGui::GetTextLineHeight());
|
||||
ImGui::RenderText(text_start_pos, ("Stats"));
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::SetWindowFontScale(1.2f);
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_sel_plate_toolbar.m_items.size(); i++) {
|
||||
IMToolbarItem* item = m_sel_plate_toolbar.m_items[i];
|
||||
|
||||
// draw image
|
||||
|
|
@ -7134,11 +7349,16 @@ void GLCanvas3D::_render_imgui_select_plate_toolbar() const
|
|||
if (item->selected) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, button_active);
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, button_active);
|
||||
} else
|
||||
}
|
||||
else {
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(128.0f, 128.0f, 128.0f, 0.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.42f, 0.42f, 0.42f, 1.0f));
|
||||
}
|
||||
|
||||
if (ImGui::ImageButton2(item->texture_id, size, uv0, uv1, frame_padding, bg_col, tint_col, margin)) {
|
||||
if (m_process && !m_process->running()) {
|
||||
all_plates_stats_item->selected = false;
|
||||
item->selected = true;
|
||||
// begin to slicing plate
|
||||
wxCommandEvent* evt = new wxCommandEvent(EVT_GLTOOLBAR_SELECT_SLICED_PLATE);
|
||||
evt->SetInt(i);
|
||||
|
|
@ -7146,10 +7366,7 @@ void GLCanvas3D::_render_imgui_select_plate_toolbar() const
|
|||
}
|
||||
}
|
||||
|
||||
if (item->selected)
|
||||
ImGui::PopStyleColor(2);
|
||||
else
|
||||
ImGui::PopStyleColor(1);
|
||||
ImGui::PopStyleColor(2);
|
||||
|
||||
ImVec2 start_pos = ImVec2(button_start_pos.x + frame_padding + margin.x, button_start_pos.y + frame_padding + margin.y);
|
||||
if (item->slice_state == IMToolbarItem::SliceState::UNSLICED) {
|
||||
|
|
@ -7341,60 +7558,59 @@ void GLCanvas3D::_render_paint_toolbar() const
|
|||
float f_scale = 1.0;
|
||||
#endif
|
||||
std::vector<std::string> colors = wxGetApp().plater()->get_extruder_colors_from_plater_config();
|
||||
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
||||
auto canvas_w = float(get_canvas_size().get_width());
|
||||
int extruder_num = colors.size();
|
||||
|
||||
std::vector<std::string> filament_text_first_line;
|
||||
std::vector<std::string> filament_text_second_line;
|
||||
{
|
||||
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) {
|
||||
std::string display_filament_type;
|
||||
iter->config.get_filament_type(display_filament_type);
|
||||
auto pos = display_filament_type.find(' ');
|
||||
if (pos != std::string::npos) {
|
||||
filament_text_first_line.push_back(display_filament_type.substr(0, pos));
|
||||
filament_text_second_line.push_back(display_filament_type.substr(pos + 1));
|
||||
}
|
||||
else {
|
||||
filament_text_first_line.push_back(display_filament_type);
|
||||
filament_text_second_line.push_back("");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
||||
float canvas_w = float(get_canvas_size().get_width());
|
||||
int item_spacing = 8 * wxGetApp().toolbar_icon_scale() * f_scale;
|
||||
float button_size = GLToolbar::Default_Icons_Size * f_scale * wxGetApp().toolbar_icon_scale() + item_spacing;
|
||||
|
||||
std::vector<std::string> filament_types;
|
||||
{
|
||||
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) {
|
||||
std::string display_filament_type;
|
||||
iter->config.get_filament_type(display_filament_type);
|
||||
filament_types.push_back(display_filament_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float button_size = GLToolbar::Default_Icons_Size * f_scale * wxGetApp().toolbar_icon_scale() + item_spacing;
|
||||
|
||||
imgui.set_next_window_pos(0.5f * (canvas_w + (button_size + item_spacing) * extruder_num), button_size + item_spacing * 2, ImGuiCond_Always, 1.0f, 1.0f);
|
||||
imgui.set_next_window_pos(0.5f * canvas_w, 0, ImGuiCond_Always, 0.5f, 0.0f);
|
||||
imgui.begin(_L("Paint Toolbar"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar);
|
||||
bool disabled = !wxGetApp().plater()->can_fillcolor();
|
||||
unsigned char rgb[3];
|
||||
float cursor_y = ImGui::GetCursorPosY();
|
||||
|
||||
float max_text = 0;
|
||||
for (int i = 0; i < extruder_num; i++) {
|
||||
std::string item_text = (boost::format("%1%%2%") % (i + 1) % filament_types[i]).str();
|
||||
ImVec2 label_size = ImGui::CalcTextSize(item_text.c_str(), NULL, true);
|
||||
if (label_size.x > button_size)
|
||||
label_size.x = button_size * 0.6;
|
||||
max_text = std::max(max_text,label_size.x);
|
||||
}
|
||||
for (int i = 0; i < extruder_num; i++) {
|
||||
if (filament_types.size() <= i) continue;
|
||||
|
||||
ImGui::SameLine(item_spacing / 2 + (button_size - max_text) / 2 + (button_size + item_spacing) * i);
|
||||
ImGui::PushID(i);
|
||||
if (i > 0)
|
||||
ImGui::SameLine(0.0f, item_spacing);
|
||||
Slic3r::GUI::BitmapCache::parse_color(colors[i], rgb);
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImColor(rgb[0], rgb[1], rgb[2]).Value);
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImColor(rgb[0], rgb[1], rgb[2]).Value);
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImColor(rgb[0], rgb[1], rgb[2]).Value);
|
||||
if (disabled)
|
||||
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
|
||||
|
||||
if (ImGui::Button("", ImVec2(button_size, button_size))) {
|
||||
if (ImGui::Button(("##filament_button" + std::to_string(i)).c_str(), ImVec2(button_size, button_size))) {
|
||||
wxPostEvent(m_canvas, IntEvent(EVT_GLTOOLBAR_FILLCOLOR, i + 1));
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 20.0f);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.00f, 1.00f, 1.00f, 1.00f));
|
||||
ImGui::TextUnformatted(_L((boost::format("Shortcut key %1%") % (i + 1)).str()).ToUTF8().data());
|
||||
ImGui::TextUnformatted((boost::format(_u8L("Shortcut key %1%")) % (i + 1)).str().c_str());
|
||||
ImGui::PopStyleColor(1);
|
||||
ImGui::PopTextWrapPos();
|
||||
ImGui::EndTooltip();
|
||||
|
|
@ -7402,82 +7618,30 @@ void GLCanvas3D::_render_paint_toolbar() const
|
|||
ImGui::PopStyleColor(3);
|
||||
if (disabled)
|
||||
ImGui::PopItemFlag();
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
float text_offset_y = 3.0f * f_scale;
|
||||
for (int i = 0; i < extruder_num; i++){
|
||||
if (filament_types.size() <= i) continue;
|
||||
//TODO use filament type from filament management, current use PLA by default
|
||||
std::string item_text = (boost::format("%1%%2%") % (i + 1) % filament_types[i]).str();
|
||||
const ImVec2 label_size = ImGui::CalcTextSize(item_text.c_str(), NULL, true);
|
||||
|
||||
int len = strlen(filament_types[i].c_str());
|
||||
|
||||
ImGui::SameLine(item_spacing / 2 + (button_size - max_text) / 2 + (button_size + item_spacing) * i);
|
||||
|
||||
int count = 0;
|
||||
if (label_size.x > button_size)
|
||||
{
|
||||
for (int j = 0; j < filament_types[i].size(); j++)
|
||||
{
|
||||
if(std::isalpha(filament_types[i][j]))
|
||||
count++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i > 8)
|
||||
{
|
||||
if (label_size.x > button_size)
|
||||
{
|
||||
if(count * ImGui::GetFontSize() > button_size){
|
||||
if ((len - (count + 1)) <= 3)
|
||||
item_text = "\t" + std::to_string(i + 1) + "\n" + filament_types[i].substr(0, count) + "\n" + "\t" + filament_types[i].substr(count, len);
|
||||
else
|
||||
item_text = "\t" + std::to_string(i + 1) + "\n" + filament_types[i].substr(0, count + 1) + "\n"+ filament_types[i].substr(count + 1, len);
|
||||
} else {
|
||||
if (count <= 4)
|
||||
item_text = "\t" + std::to_string(i + 1) + "\n" + " " + filament_types[i].substr(0, count + 1) + "\n" + filament_types[i].substr(count + 1, len);
|
||||
else
|
||||
item_text = "\t" + std::to_string(i + 1) + "\n" + filament_types[i].substr(0, count + 1) + "\n" + filament_types[i].substr(count + 1, len);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
item_text = (boost::format("\t%1%\n %2%") % (i + 1) % filament_types[i]).str();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (label_size.x > button_size)
|
||||
{
|
||||
if(count * ImGui::GetFontSize() > button_size){
|
||||
if ((len - (count + 1)) <= 3)
|
||||
item_text = "\t " + std::to_string(i + 1) + "\n" + filament_types[i].substr(0, count) + "\n" + "\t" + filament_types[i].substr(count, len);
|
||||
else
|
||||
item_text = "\t " + std::to_string(i + 1) + "\n" + filament_types[i].substr(0, count + 1) + "\n"+ filament_types[i].substr(count + 1, len);
|
||||
} else {
|
||||
if (count <= 4)
|
||||
item_text = "\t " + std::to_string(i + 1) + "\n" + " " + filament_types[i].substr(0, count + 1) + "\n" + filament_types[i].substr(count + 1, len);
|
||||
else
|
||||
item_text = "\t " + std::to_string(i + 1) + "\n" + filament_types[i].substr(0, count + 1) + "\n" + filament_types[i].substr(count + 1, len);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
item_text = (boost::format("\t %1%\n\t%2%") % (i + 1) % filament_types[i]).str();
|
||||
}
|
||||
}
|
||||
Slic3r::GUI::BitmapCache::parse_color(colors[i], rgb);
|
||||
float gray = 0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2];
|
||||
ImVec4 text_color = gray < 80 ? ImVec4(255, 255, 255, 255) : ImVec4(0, 0, 0, 255);
|
||||
|
||||
ImVec2 number_label_size = ImGui::CalcTextSize(std::to_string(i + 1).c_str());
|
||||
ImGui::SetCursorPosY(cursor_y + text_offset_y);
|
||||
ImGui::SetCursorPosX(item_spacing + i * (item_spacing + button_size) + (button_size - number_label_size.x) / 2);
|
||||
ImGui::TextColored(text_color, std::to_string(i + 1).c_str());
|
||||
|
||||
if (gray < 80){
|
||||
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, 1.0f), item_text.c_str());
|
||||
} else{
|
||||
ImGui::TextColored(ImVec4(0.0f, 0.0f, 0.0f, 1.0f), item_text.c_str());
|
||||
}
|
||||
ImVec2 filament_first_line_label_size = ImGui::CalcTextSize(filament_text_first_line[i].c_str());
|
||||
ImGui::SetCursorPosY(cursor_y + text_offset_y + number_label_size.y);
|
||||
ImGui::SetCursorPosX(item_spacing + i * (item_spacing + button_size) + (button_size - filament_first_line_label_size.x) / 2);
|
||||
ImGui::TextColored(text_color, filament_text_first_line[i].c_str());
|
||||
|
||||
ImVec2 filament_second_line_label_size = ImGui::CalcTextSize(filament_text_second_line[i].c_str());
|
||||
ImGui::SetCursorPosY(cursor_y + text_offset_y + number_label_size.y + filament_first_line_label_size.y);
|
||||
ImGui::SetCursorPosX(item_spacing + i * (item_spacing + button_size) + (button_size - filament_second_line_label_size.x) / 2);
|
||||
ImGui::TextColored(text_color, filament_text_second_line[i].c_str());
|
||||
}
|
||||
ImGui::AlignTextToFramePadding();
|
||||
|
||||
imgui.end();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -543,6 +543,7 @@ private:
|
|||
bool m_dirty;
|
||||
bool m_initialized;
|
||||
//BBS: add flag to controll rendering
|
||||
bool m_render_preview{ true };
|
||||
bool m_enable_render { true };
|
||||
bool m_apply_zoom_to_volumes_filter;
|
||||
bool m_picking_enabled;
|
||||
|
|
@ -785,6 +786,8 @@ public:
|
|||
void enable_selection(bool enable);
|
||||
void enable_main_toolbar(bool enable);
|
||||
//BBS: GUI refactor: GLToolbar
|
||||
void _update_select_plate_toolbar_stats_item(bool force_selected = false);
|
||||
void reset_select_plate_toolbar_selection();
|
||||
void enable_select_plate_toolbar(bool enable);
|
||||
void enable_assemble_view_toolbar(bool enable);
|
||||
void enable_return_toolbar(bool enable);
|
||||
|
|
@ -847,6 +850,7 @@ public:
|
|||
|
||||
void select_all();
|
||||
void deselect_all();
|
||||
void set_selected_visible(bool visible);
|
||||
void delete_selected();
|
||||
void ensure_on_bed(unsigned int object_idx, bool allow_negative_z);
|
||||
|
||||
|
|
@ -893,6 +897,7 @@ public:
|
|||
void on_gesture(wxGestureEvent& evt);
|
||||
void on_paint(wxPaintEvent& evt);
|
||||
void on_set_focus(wxFocusEvent& evt);
|
||||
void force_set_focus();
|
||||
|
||||
Size get_canvas_size() const;
|
||||
Vec2d get_local_mouse_position() const;
|
||||
|
|
@ -1041,6 +1046,8 @@ public:
|
|||
// 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);
|
||||
|
||||
bool make_current_for_postinit();
|
||||
|
||||
private:
|
||||
bool _is_shown_on_screen() const;
|
||||
|
||||
|
|
@ -1093,7 +1100,7 @@ private:
|
|||
void _render_current_gizmo() const;
|
||||
void _render_gizmos_overlay();
|
||||
void _render_main_toolbar();
|
||||
void _render_imgui_select_plate_toolbar() const;
|
||||
void _render_imgui_select_plate_toolbar();
|
||||
void _render_assemble_view_toolbar() const;
|
||||
void _render_return_toolbar() const;
|
||||
void _render_separator_toolbar_right() const;
|
||||
|
|
|
|||
|
|
@ -584,12 +584,7 @@ bool GLTexture::generate_texture_from_text(const std::string& text_str, wxFont&
|
|||
|
||||
// draw message
|
||||
memDC.SetTextForeground(*wxWHITE);
|
||||
|
||||
wxGCDC dc2(memDC);
|
||||
dc2.SetFont(font);
|
||||
dc2.SetBackground(wxBrush(background));
|
||||
dc2.SetTextForeground(*wxWHITE);
|
||||
dc2.DrawLabel(msg, wxRect(0, 0, m_width, m_height), wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
|
||||
memDC.DrawLabel(msg, wxRect(0, 0, m_width, m_height), wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
memDC.SelectObject(wxNullBitmap);
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#include <wx/textctrl.h>
|
||||
#include <wx/splash.h>
|
||||
#include <wx/fontutil.h>
|
||||
#include <wx/glcanvas.h>
|
||||
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
|
|
@ -86,8 +87,8 @@
|
|||
//BBS: DailyTip and UserGuide Dialog
|
||||
#include "WebDownPluginDlg.hpp"
|
||||
#include "WebGuideDialog.hpp"
|
||||
#include "WebUserLoginDialog.hpp"
|
||||
#include "ReleaseNote.hpp"
|
||||
#include "PrivacyUpdateDialog.hpp"
|
||||
#include "ModelMall.hpp"
|
||||
|
||||
//#ifdef WIN32
|
||||
|
|
@ -1016,25 +1017,31 @@ void GUI_App::post_init()
|
|||
mainframe->select_tab(size_t(MainFrame::tp3DEditor));
|
||||
plater_->select_view_3D("3D");
|
||||
//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) << __FUNCTION__ << ", start to init opengl";
|
||||
wxGetApp().init_opengl();
|
||||
#ifdef __linux__
|
||||
if (plater_->canvas3D()->get_wxglcanvas()->IsShownOnScreen()&&plater_->canvas3D()->make_current_for_postinit()) {
|
||||
#endif
|
||||
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) << __FUNCTION__ << ", start to init opengl";
|
||||
wxGetApp().init_opengl();
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished init opengl";
|
||||
plater_->canvas3D()->init();
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished init opengl";
|
||||
plater_->canvas3D()->init();
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished init canvas3D";
|
||||
wxGetApp().imgui()->new_frame();
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished init canvas3D";
|
||||
wxGetApp().imgui()->new_frame();
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished init imgui frame";
|
||||
plater_->canvas3D()->enable_render(true);
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished init imgui frame";
|
||||
plater_->canvas3D()->enable_render(true);
|
||||
|
||||
if (!slow_bootup) {
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", start to render a first frame for test";
|
||||
plater_->canvas3D()->render(false);
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished rendering a first frame for test";
|
||||
if (!slow_bootup) {
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", start to render a first frame for test";
|
||||
plater_->canvas3D()->render(false);
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished rendering a first frame for test";
|
||||
}
|
||||
#ifdef __linux__
|
||||
}
|
||||
#endif
|
||||
if (is_editor())
|
||||
mainframe->select_tab(size_t(0));
|
||||
mainframe->Thaw();
|
||||
|
|
@ -1119,6 +1126,9 @@ void GUI_App::post_init()
|
|||
|
||||
//BBS: check new version
|
||||
this->check_new_version_sf();
|
||||
//BBS: check privacy version
|
||||
if (is_user_login())
|
||||
this->check_privacy_version(0);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -1155,6 +1165,9 @@ void GUI_App::post_init()
|
|||
std::string functional_config_file = Slic3r::resources_dir() + "/config.json";
|
||||
DeviceManager::load_functional_config(encode_path(functional_config_file.c_str()));
|
||||
|
||||
std::string filaments_blacklist_config_file = Slic3r::resources_dir() + "/printers/filaments_blacklist.json";
|
||||
DeviceManager::load_filaments_blacklist_config(encode_path(filaments_blacklist_config_file.c_str()));
|
||||
|
||||
// remove old log files over LOG_FILES_MAX_NUM
|
||||
std::string log_addr = data_dir();
|
||||
if (!log_addr.empty()) {
|
||||
|
|
@ -1228,6 +1241,13 @@ void GUI_App::shutdown()
|
|||
removable_drive_manager()->shutdown();
|
||||
}
|
||||
|
||||
// destroy login dialog
|
||||
if (login_dlg != nullptr) {
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": destroy login dialog");
|
||||
delete login_dlg;
|
||||
login_dlg = nullptr;
|
||||
}
|
||||
|
||||
if (m_is_recreating_gui) return;
|
||||
m_is_closing = true;
|
||||
stop_sync_user_preset();
|
||||
|
|
@ -1646,9 +1666,9 @@ void GUI_App::init_networking_callbacks()
|
|||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": enter, m_agent=%1%")%m_agent;
|
||||
if (m_agent) {
|
||||
//set callbacks
|
||||
m_agent->set_on_user_login_fn([this](int online_login, bool login) {
|
||||
GUI::wxGetApp().request_user_login(online_login);
|
||||
});
|
||||
//m_agent->set_on_user_login_fn([this](int online_login, bool login) {
|
||||
// GUI::wxGetApp().request_user_handle(online_login);
|
||||
// });
|
||||
|
||||
m_agent->set_on_server_connected_fn([this]() {
|
||||
if (m_is_closing) {
|
||||
|
|
@ -1708,6 +1728,7 @@ void GUI_App::init_networking_callbacks()
|
|||
event.SetString(obj->dev_id);
|
||||
} else if (state == ConnectStatus::ConnectStatusFailed) {
|
||||
obj->set_access_code("");
|
||||
obj->set_user_access_code("");
|
||||
m_device_manager->set_selected_machine("");
|
||||
wxString text;
|
||||
if (msg == "5") {
|
||||
|
|
@ -1748,8 +1769,9 @@ void GUI_App::init_networking_callbacks()
|
|||
obj->is_ams_need_update = false;
|
||||
obj->parse_json(msg);
|
||||
|
||||
if (this->m_device_manager->get_selected_machine() == obj && obj->is_ams_need_update) {
|
||||
GUI::wxGetApp().sidebar().load_ams_list(obj->amsList);
|
||||
auto sel = this->m_device_manager->get_selected_machine();
|
||||
if ((sel == obj || sel == nullptr) && obj->is_ams_need_update) {
|
||||
GUI::wxGetApp().sidebar().load_ams_list(obj->dev_id, obj->amsList);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -1773,7 +1795,7 @@ void GUI_App::init_networking_callbacks()
|
|||
if (obj) {
|
||||
obj->parse_json(msg);
|
||||
if (this->m_device_manager->get_selected_machine() == obj && obj->is_ams_need_update) {
|
||||
GUI::wxGetApp().sidebar().load_ams_list(obj->amsList);
|
||||
GUI::wxGetApp().sidebar().load_ams_list(obj->dev_id, obj->amsList);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -1856,10 +1878,8 @@ void GUI_App::init_download_path()
|
|||
fs::path dp(down_path);
|
||||
if (!fs::exists(dp)) {
|
||||
|
||||
if (!fs::create_directory(dp)) {
|
||||
std::string user_down_path = wxStandardPaths::Get().GetUserDir(wxStandardPaths::Dir_Downloads).ToUTF8().data();
|
||||
app_config->set("download_path", user_down_path);
|
||||
}
|
||||
std::string user_down_path = wxStandardPaths::Get().GetUserDir(wxStandardPaths::Dir_Downloads).ToUTF8().data();
|
||||
app_config->set("download_path", user_down_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1978,6 +1998,14 @@ void GUI_App::init_http_extra_header()
|
|||
m_agent->set_extra_http_header(extra_headers);
|
||||
}
|
||||
|
||||
void GUI_App::update_http_extra_header()
|
||||
{
|
||||
std::map<std::string, std::string> extra_headers = get_extra_header();
|
||||
Slic3r::Http::set_extra_headers(extra_headers);
|
||||
if (m_agent)
|
||||
m_agent->set_extra_http_header(extra_headers);
|
||||
}
|
||||
|
||||
std::string GUI_App::get_local_models_path()
|
||||
{
|
||||
std::string local_path = "";
|
||||
|
|
@ -2064,7 +2092,7 @@ bool GUI_App::on_init_inner()
|
|||
}
|
||||
}
|
||||
for (auto d : dialogStack)
|
||||
d->EndModal(wxID_CANCEL);
|
||||
d->EndModal(wxID_ABORT);
|
||||
});
|
||||
|
||||
std::map<std::string, std::string> extra_headers = get_extra_header();
|
||||
|
|
@ -2123,7 +2151,7 @@ bool GUI_App::on_init_inner()
|
|||
#endif // __APPLE__
|
||||
|
||||
|
||||
bool init_dark_color_mode = app_config->get("dark_color_mode") == "1";
|
||||
bool init_dark_color_mode = dark_mode();
|
||||
bool init_sys_menu_enabled = app_config->get("sys_menu_enabled") == "1";
|
||||
#ifdef __WINDOWS__
|
||||
NppDarkMode::InitDarkMode(init_dark_color_mode, init_sys_menu_enabled);
|
||||
|
|
@ -2138,7 +2166,7 @@ bool GUI_App::on_init_inner()
|
|||
|
||||
#ifdef _MSW_DARK_MODE
|
||||
// app_config can be updated in check_older_app_config(), so check if dark_color_mode and sys_menu_enabled was changed
|
||||
if (bool new_dark_color_mode = app_config->get("dark_color_mode") == "1";
|
||||
if (bool new_dark_color_mode = dark_mode();
|
||||
init_dark_color_mode != new_dark_color_mode) {
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
|
|
@ -2325,7 +2353,13 @@ bool GUI_App::on_init_inner()
|
|||
// Suppress the '- default -' presets.
|
||||
preset_bundle->set_default_suppressed(true);
|
||||
|
||||
Bind(EVT_SET_SELECTED_MACHINE, &GUI_App::on_set_selected_machine, this);
|
||||
Bind(EVT_USER_LOGIN, &GUI_App::on_user_login, this);
|
||||
Bind(EVT_USER_LOGIN_HANDLE, &GUI_App::on_user_login_handle, this);
|
||||
Bind(EVT_CHECK_PRIVACY_VER, &GUI_App::on_check_privacy_update, this);
|
||||
Bind(EVT_CHECK_PRIVACY_SHOW, &GUI_App::show_check_privacy_dlg, this);
|
||||
|
||||
Bind(EVT_SHOW_IP_DIALOG, &GUI_App::show_ip_address_enter_dialog_handler, this);
|
||||
|
||||
Bind(EVT_SHOW_IP_DIALOG, &GUI_App::show_ip_address_enter_dialog_handler, this);
|
||||
|
||||
|
|
@ -2334,6 +2368,8 @@ bool GUI_App::on_init_inner()
|
|||
|
||||
if (m_agent && m_agent->is_user_login()) {
|
||||
enable_user_preset_folder(true);
|
||||
} else {
|
||||
enable_user_preset_folder(false);
|
||||
}
|
||||
|
||||
// BBS if load user preset failed
|
||||
|
|
@ -2349,13 +2385,11 @@ bool GUI_App::on_init_inner()
|
|||
}
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
if (app_config->get("sync_user_preset") == "true") {
|
||||
//BBS loading user preset
|
||||
BOOST_LOG_TRIVIAL(info) << "Loading user presets...";
|
||||
scrn->SetText(_L("Loading user presets..."));
|
||||
// Always async, not such startup step
|
||||
//BOOST_LOG_TRIVIAL(info) << "Loading user presets...";
|
||||
//scrn->SetText(_L("Loading user presets..."));
|
||||
if (m_agent) {
|
||||
start_sync_user_preset();
|
||||
}
|
||||
|
|
@ -2798,6 +2832,7 @@ void GUI_App::UpdateDarkUIWin(wxWindow* win)
|
|||
void GUI_App::Update_dark_mode_flag()
|
||||
{
|
||||
m_is_dark_mode = dark_mode();
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": switch the current dark mode status to %1% ")%m_is_dark_mode;
|
||||
}
|
||||
|
||||
void GUI_App::UpdateDlgDarkUI(wxDialog* dlg)
|
||||
|
|
@ -3075,6 +3110,11 @@ void GUI_App::ShowUserGuide() {
|
|||
|
||||
void GUI_App::ShowDownNetPluginDlg() {
|
||||
try {
|
||||
auto iter = std::find_if(dialogStack.begin(), dialogStack.end(), [](auto dialog) {
|
||||
return dynamic_cast<DownloadProgressDialog *>(dialog) != nullptr;
|
||||
});
|
||||
if (iter != dialogStack.end())
|
||||
return;
|
||||
DownloadProgressDialog dlg(_L("Downloading Bambu Network Plug-in"));
|
||||
dlg.ShowModal();
|
||||
} catch (std::exception &e) {
|
||||
|
|
@ -3082,14 +3122,24 @@ void GUI_App::ShowDownNetPluginDlg() {
|
|||
}
|
||||
}
|
||||
|
||||
void GUI_App::ShowUserLogin()
|
||||
void GUI_App::ShowUserLogin(bool show)
|
||||
{
|
||||
// BBS: User Login Dialog
|
||||
try {
|
||||
ZUserLogin LoginDlg;
|
||||
LoginDlg.ShowModal();
|
||||
} catch (std::exception &e) {
|
||||
// wxMessageBox(e.what(), "", MB_OK);
|
||||
if (show) {
|
||||
try {
|
||||
if (!login_dlg)
|
||||
login_dlg = new ZUserLogin();
|
||||
else {
|
||||
delete login_dlg;
|
||||
login_dlg = new ZUserLogin();
|
||||
}
|
||||
login_dlg->ShowModal();
|
||||
} catch (std::exception &e) {
|
||||
;
|
||||
}
|
||||
} else {
|
||||
if (login_dlg)
|
||||
login_dlg->EndModal(wxID_OK);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3168,7 +3218,7 @@ void GUI_App::force_colors_update()
|
|||
{
|
||||
#ifdef _MSW_DARK_MODE
|
||||
#ifdef __WINDOWS__
|
||||
NppDarkMode::SetDarkMode(app_config->get("dark_color_mode") == "1");
|
||||
NppDarkMode::SetDarkMode(dark_mode());
|
||||
if (WXHWND wxHWND = wxToolTip::GetToolTipCtrl())
|
||||
NppDarkMode::SetDarkExplorerTheme((HWND)wxHWND);
|
||||
NppDarkMode::SetDarkTitleBar(mainframe->GetHWND());
|
||||
|
|
@ -3321,6 +3371,13 @@ bool GUI_App::check_login()
|
|||
return result;
|
||||
}
|
||||
|
||||
void GUI_App::request_user_handle(int online_login)
|
||||
{
|
||||
auto evt = new wxCommandEvent(EVT_USER_LOGIN_HANDLE);
|
||||
evt->SetInt(online_login);
|
||||
wxQueueEvent(this, evt);
|
||||
}
|
||||
|
||||
void GUI_App::request_user_login(int online_login)
|
||||
{
|
||||
auto evt = new wxCommandEvent(EVT_USER_LOGIN);
|
||||
|
|
@ -3339,12 +3396,9 @@ void GUI_App::request_user_logout()
|
|||
|
||||
m_agent->user_logout();
|
||||
m_agent->set_user_selected_machine("");
|
||||
BOOST_LOG_TRIVIAL(info) << "preset_folder: set to empty, user_logout";
|
||||
enable_user_preset_folder(false);
|
||||
/* delete old user settings */
|
||||
m_device_manager->clean_user_info();
|
||||
GUI::wxGetApp().sidebar().load_ams_list({});
|
||||
GUI::wxGetApp().remove_user_presets();
|
||||
GUI::wxGetApp().sidebar().load_ams_list({}, {});
|
||||
GUI::wxGetApp().stop_sync_user_preset();
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
|
|
@ -3375,11 +3429,6 @@ std::string GUI_App::handle_web_request(std::string cmd)
|
|||
std::string web_cmd = j["command"].get<std::string>();
|
||||
|
||||
if (web_cmd == "request_model_download") {
|
||||
/* json j_data = j["data"];
|
||||
json import_j;*/
|
||||
/* import_j["model_id"] = j["data"]["model_id"].get<std::string>();
|
||||
import_j["profile_id"] = j["data"]["profile_id"].get<std::string>();*/
|
||||
|
||||
std::string download_url = "";
|
||||
if (j["data"].contains("download_url"))
|
||||
download_url = j["data"]["download_url"].get<std::string>();
|
||||
|
|
@ -3575,7 +3624,7 @@ void GUI_App::request_model_download(std::string url, std::string filename)
|
|||
if (!check_login()) return;
|
||||
|
||||
if (plater_) {
|
||||
plater_->request_model_download(url, filename);
|
||||
plater_->request_model_download();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3685,7 +3734,15 @@ void GUI_App::enable_user_preset_folder(bool enable)
|
|||
}
|
||||
}
|
||||
|
||||
void GUI_App::on_user_login(wxCommandEvent &evt)
|
||||
void GUI_App::on_set_selected_machine(wxCommandEvent &evt)
|
||||
{
|
||||
DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
if (!dev || m_agent) return;
|
||||
|
||||
dev->set_selected_machine(m_agent->get_user_selected_machine());
|
||||
}
|
||||
|
||||
void GUI_App::on_user_login_handle(wxCommandEvent &evt)
|
||||
{
|
||||
if (!m_agent) { return; }
|
||||
|
||||
|
|
@ -3695,8 +3752,12 @@ void GUI_App::on_user_login(wxCommandEvent &evt)
|
|||
// get machine list
|
||||
DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
if (!dev) return;
|
||||
dev->update_user_machine_list_info();
|
||||
dev->set_selected_machine(m_agent->get_user_selected_machine());
|
||||
|
||||
boost::thread update_thread = boost::thread([this, dev] {
|
||||
dev->update_user_machine_list_info();
|
||||
auto evt = new wxCommandEvent(EVT_SET_SELECTED_MACHINE);
|
||||
wxQueueEvent(this, evt);
|
||||
});
|
||||
|
||||
// if (app_config->get("sync_user_preset") == "true") {
|
||||
enable_user_preset_folder(true);
|
||||
|
|
@ -3723,6 +3784,14 @@ void GUI_App::on_user_login(wxCommandEvent &evt)
|
|||
}
|
||||
}
|
||||
|
||||
void GUI_App::on_user_login(wxCommandEvent &evt)
|
||||
{
|
||||
if (!m_agent) { return; }
|
||||
int online_login = evt.GetInt();
|
||||
// check privacy before handle
|
||||
check_privacy_version(online_login);
|
||||
}
|
||||
|
||||
bool GUI_App::is_studio_active()
|
||||
{
|
||||
auto curr_time = std::chrono::system_clock::now();
|
||||
|
|
@ -3947,6 +4016,113 @@ void GUI_App::set_skip_version(bool skip)
|
|||
}
|
||||
}
|
||||
|
||||
void GUI_App::show_check_privacy_dlg(wxCommandEvent& evt)
|
||||
{
|
||||
int online_login = evt.GetInt();
|
||||
PrivacyUpdateDialog privacy_dlg(this->mainframe, wxID_ANY, _L("Privacy Policy Update"));
|
||||
privacy_dlg.Bind(EVT_PRIVACY_UPDATE_CONFIRM, [this, online_login](wxCommandEvent &e) {
|
||||
app_config->set("privacy_version", privacy_version_info.version_str);
|
||||
app_config->set_bool("privacy_update_checked", true);
|
||||
app_config->save();
|
||||
request_user_handle(online_login);
|
||||
});
|
||||
privacy_dlg.Bind(EVT_PRIVACY_UPDATE_CANCEL, [this](wxCommandEvent &e) {
|
||||
app_config->set_bool("privacy_update_checked", false);
|
||||
app_config->save();
|
||||
if (m_agent) {
|
||||
m_agent->user_logout();
|
||||
}
|
||||
});
|
||||
|
||||
privacy_dlg.set_text(privacy_version_info.description);
|
||||
privacy_dlg.on_show();
|
||||
}
|
||||
|
||||
void GUI_App::on_show_check_privacy_dlg(int online_login)
|
||||
{
|
||||
auto evt = new wxCommandEvent(EVT_CHECK_PRIVACY_SHOW);
|
||||
evt->SetInt(online_login);
|
||||
wxQueueEvent(this, evt);
|
||||
}
|
||||
|
||||
bool GUI_App::check_privacy_update()
|
||||
{
|
||||
if (privacy_version_info.version_str.empty() || privacy_version_info.description.empty()
|
||||
|| privacy_version_info.url.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string local_privacy_ver = app_config->get("privacy_version");
|
||||
auto curr_version = Semver::parse(local_privacy_ver);
|
||||
auto remote_version = Semver::parse(privacy_version_info.version_str);
|
||||
if (curr_version && remote_version) {
|
||||
if (*remote_version > *curr_version || app_config->get("privacy_update_checked") != "true") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void GUI_App::on_check_privacy_update(wxCommandEvent& evt)
|
||||
{
|
||||
int online_login = evt.GetInt();
|
||||
bool result = check_privacy_update();
|
||||
if (result)
|
||||
on_show_check_privacy_dlg(online_login);
|
||||
else
|
||||
request_user_handle(online_login);
|
||||
}
|
||||
|
||||
void GUI_App::check_privacy_version(int online_login)
|
||||
{
|
||||
update_http_extra_header();
|
||||
std::string query_params = "?policy/privacy=00.00.00.00";
|
||||
std::string url = get_http_url(app_config->get_country_code()) + query_params;
|
||||
Slic3r::Http http = Slic3r::Http::get(url);
|
||||
|
||||
http.header("accept", "application/json")
|
||||
.timeout_connect(TIMEOUT_CONNECT)
|
||||
.timeout_max(TIMEOUT_RESPONSE)
|
||||
.on_complete([this, online_login](std::string body, unsigned) {
|
||||
try {
|
||||
json j = json::parse(body);
|
||||
if (j.contains("message")) {
|
||||
if (j["message"].get<std::string>() == "success") {
|
||||
if (j.contains("resources")) {
|
||||
for (auto it = j["resources"].begin(); it != j["resources"].end(); it++) {
|
||||
if (it->contains("type")) {
|
||||
if ((*it)["type"] == std::string("policy/privacy")
|
||||
&& it->contains("version")
|
||||
&& it->contains("description")
|
||||
&& it->contains("url")
|
||||
&& it->contains("force_update")) {
|
||||
privacy_version_info.version_str = (*it)["version"].get<std::string>();
|
||||
privacy_version_info.description = (*it)["description"].get<std::string>();
|
||||
privacy_version_info.url = (*it)["url"].get<std::string>();
|
||||
privacy_version_info.force_upgrade = (*it)["force_update"].get<bool>();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
CallAfter([this, online_login]() {
|
||||
auto evt = new wxCommandEvent(EVT_CHECK_PRIVACY_VER);
|
||||
evt->SetInt(online_login);
|
||||
wxQueueEvent(this, evt);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
request_user_handle(online_login);
|
||||
}
|
||||
})
|
||||
.on_error([this, online_login](std::string body, std::string error, unsigned int status) {
|
||||
request_user_handle(online_login);
|
||||
BOOST_LOG_TRIVIAL(error) << "check privacy version error" << body;
|
||||
}).perform();
|
||||
}
|
||||
|
||||
void GUI_App::no_new_version()
|
||||
{
|
||||
wxCommandEvent* evt = new wxCommandEvent(EVT_SHOW_NO_NEW_VERSION);
|
||||
|
|
@ -3986,17 +4162,19 @@ void GUI_App::reload_settings()
|
|||
m_agent->get_user_presets(&user_presets);
|
||||
preset_bundle->load_user_presets(*app_config, user_presets, ForwardCompatibilitySubstitutionRule::Enable);
|
||||
preset_bundle->save_user_presets(*app_config, get_delete_cache_presets());
|
||||
mainframe->update_side_preset_ui();
|
||||
}
|
||||
}
|
||||
|
||||
//BBS reload when login
|
||||
//BBS reload when logout
|
||||
void GUI_App::remove_user_presets()
|
||||
{
|
||||
if (preset_bundle && m_agent) {
|
||||
preset_bundle->remove_users_preset(*app_config);
|
||||
|
||||
std::string user_id = m_agent->get_user_id();
|
||||
preset_bundle->remove_user_presets_directory(user_id);
|
||||
// Not remove user preset cache
|
||||
//std::string user_id = m_agent->get_user_id();
|
||||
//preset_bundle->remove_user_presets_directory(user_id);
|
||||
|
||||
//update ui
|
||||
mainframe->update_side_preset_ui();
|
||||
|
|
@ -4110,9 +4288,9 @@ void GUI_App::sync_preset(Preset* preset)
|
|||
}
|
||||
}
|
||||
|
||||
void GUI_App::start_sync_user_preset(bool with_progress_dlg)
|
||||
void GUI_App::start_sync_user_preset(bool load_immediately, bool with_progress_dlg)
|
||||
{
|
||||
if (!m_agent) return;
|
||||
if (!m_agent || !m_agent->is_user_login()) return;
|
||||
|
||||
enable_user_preset_folder(true);
|
||||
|
||||
|
|
@ -4120,32 +4298,51 @@ void GUI_App::start_sync_user_preset(bool with_progress_dlg)
|
|||
if (enable_sync)
|
||||
return;
|
||||
|
||||
if (m_agent->is_user_login()) {
|
||||
// get setting list, update setting list
|
||||
std::string version = preset_bundle->get_vendor_profile_version(PresetBundle::BBL_BUNDLE).to_string();
|
||||
if (with_progress_dlg) {
|
||||
ProgressDialog dlg(_L("Loading"), "", 100, this->mainframe, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT);
|
||||
dlg.Update(0, _L("Loading user preset"));
|
||||
m_agent->get_setting_list(version,
|
||||
[this, &dlg](int percent){
|
||||
dlg.Update(percent, _L("Loading user preset"));
|
||||
},
|
||||
[this, &dlg]() {
|
||||
dlg.GetValue();
|
||||
bool cont = dlg.Update(dlg.GetValue(), _L("Loading user preset"));
|
||||
return !cont;
|
||||
});
|
||||
} else {
|
||||
m_agent->get_setting_list(version);
|
||||
}
|
||||
GUI::wxGetApp().reload_settings();
|
||||
if (load_immediately) {
|
||||
preset_bundle->load_user_presets(m_agent->get_user_id(), ForwardCompatibilitySubstitutionRule::Enable);
|
||||
mainframe->update_side_preset_ui();
|
||||
}
|
||||
|
||||
ProgressFn progressFn;
|
||||
WasCancelledFn cancelFn;
|
||||
std::function<void()> finishFn;
|
||||
|
||||
if (with_progress_dlg) {
|
||||
auto dlg = new ProgressDialog(_L("Loading"), "", 100, this->mainframe, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT);
|
||||
dlg->Update(0, _L("Loading user preset"));
|
||||
progressFn = [this, dlg](int percent) {
|
||||
CallAfter([=]{
|
||||
dlg->Update(percent, _L("Loading user preset"));
|
||||
});
|
||||
};
|
||||
cancelFn = [dlg]() {
|
||||
return dlg->WasCanceled();
|
||||
};
|
||||
finishFn = [this, dlg] {
|
||||
CallAfter([=]{
|
||||
dlg->Destroy();
|
||||
reload_settings();
|
||||
});
|
||||
};
|
||||
}
|
||||
else {
|
||||
finishFn = [this] {
|
||||
CallAfter([=] {
|
||||
reload_settings();
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << "start_sync_service...";
|
||||
//BBS
|
||||
enable_sync = true;
|
||||
m_sync_update_thread = Slic3r::create_thread(
|
||||
[this] {
|
||||
[this, progressFn, cancelFn, finishFn] {
|
||||
// get setting list, update setting list
|
||||
std::string version = preset_bundle->get_vendor_profile_version(PresetBundle::BBL_BUNDLE).to_string();
|
||||
m_agent->get_setting_list(version, progressFn, cancelFn);
|
||||
finishFn();
|
||||
|
||||
int count = 0, sync_count = 0;
|
||||
std::vector<Preset> presets_to_sync;
|
||||
while (enable_sync) {
|
||||
|
|
@ -4182,12 +4379,13 @@ void GUI_App::start_sync_user_preset(bool with_progress_dlg)
|
|||
unsigned int http_code = 200;
|
||||
|
||||
/* get list witch need to be deleted*/
|
||||
std::vector<string>& delete_cache_presets = get_delete_cache_presets();
|
||||
std::vector<string> delete_cache_presets = get_delete_cache_presets_lock();
|
||||
for (auto it = delete_cache_presets.begin(); it != delete_cache_presets.end();) {
|
||||
if ((*it).empty()) continue;
|
||||
std::string del_setting_id = *it;
|
||||
int result = m_agent->delete_setting(del_setting_id);
|
||||
if (result == 0) {
|
||||
preset_deleted_from_cloud(del_setting_id);
|
||||
it = delete_cache_presets.erase(it);
|
||||
BOOST_LOG_TRIVIAL(trace) << "sync_preset: sync operation: delete success! setting id = " << del_setting_id;
|
||||
}
|
||||
|
|
@ -4206,6 +4404,7 @@ void GUI_App::start_sync_user_preset(bool with_progress_dlg)
|
|||
|
||||
void GUI_App::stop_sync_user_preset()
|
||||
{
|
||||
remove_user_presets();
|
||||
enable_user_preset_folder(false);
|
||||
|
||||
if (!enable_sync)
|
||||
|
|
@ -4216,6 +4415,16 @@ void GUI_App::stop_sync_user_preset()
|
|||
m_sync_update_thread.join();
|
||||
}
|
||||
|
||||
void GUI_App::start_http_server()
|
||||
{
|
||||
if (!m_http_server.is_started())
|
||||
m_http_server.start();
|
||||
}
|
||||
void GUI_App::stop_http_server()
|
||||
{
|
||||
m_http_server.stop();
|
||||
}
|
||||
|
||||
bool GUI_App::switch_language()
|
||||
{
|
||||
if (select_language()) {
|
||||
|
|
@ -4412,7 +4621,8 @@ 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")}
|
||||
{"hu", wxString::FromUTF8("Magyar")},
|
||||
{"ja", wxString::FromUTF8("\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E")}
|
||||
};
|
||||
for (auto l : language_descptions) {
|
||||
const wxLanguageInfo *langinfo = wxLocale::FindLanguageInfo(l.first);
|
||||
|
|
@ -4517,7 +4727,9 @@ bool GUI_App::load_language(wxString language, bool initial)
|
|||
wxLANGUAGE_SPANISH,
|
||||
wxLANGUAGE_SWEDISH,
|
||||
wxLANGUAGE_DUTCH,
|
||||
wxLANGUAGE_HUNGARIAN};
|
||||
wxLANGUAGE_HUNGARIAN,
|
||||
wxLANGUAGE_JAPANESE
|
||||
};
|
||||
std::string cur_language = app_config->get("language");
|
||||
if (cur_language != "") {
|
||||
//cleanup the language wrongly set before
|
||||
|
|
@ -5027,7 +5239,12 @@ bool GUI_App::check_and_keep_current_preset_changes(const wxString& caption, con
|
|||
static_cast<TabPrinter*>(tab)->cache_extruder_cnt();
|
||||
}
|
||||
}
|
||||
tab->cache_config_diff(selected_options);
|
||||
std::vector<std::string> selected_options2;
|
||||
std::transform(selected_options.begin(), selected_options.end(), std::back_inserter(selected_options2), [](auto & o) {
|
||||
auto i = o.find('#');
|
||||
return i != std::string::npos ? o.substr(0, i) : o;
|
||||
});
|
||||
tab->cache_config_diff(selected_options2);
|
||||
if (!is_called_from_configwizard)
|
||||
tab->m_presets->discard_current_changes();
|
||||
}
|
||||
|
|
@ -5114,16 +5331,31 @@ void GUI_App::load_current_presets(bool active_preset_combox/*= false*/, bool ch
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<std::string>& GUI_App::get_delete_cache_presets()
|
||||
static std::mutex mutex_delete_cache_presets;
|
||||
|
||||
std::vector<std::string> & GUI_App::get_delete_cache_presets()
|
||||
{
|
||||
return need_delete_presets;
|
||||
}
|
||||
|
||||
std::vector<std::string> GUI_App::get_delete_cache_presets_lock()
|
||||
{
|
||||
std::scoped_lock l(mutex_delete_cache_presets);
|
||||
return need_delete_presets;
|
||||
}
|
||||
|
||||
void GUI_App::delete_preset_from_cloud(std::string setting_id)
|
||||
{
|
||||
std::scoped_lock l(mutex_delete_cache_presets);
|
||||
need_delete_presets.push_back(setting_id);
|
||||
}
|
||||
|
||||
void GUI_App::preset_deleted_from_cloud(std::string setting_id)
|
||||
{
|
||||
std::scoped_lock l(mutex_delete_cache_presets);
|
||||
need_delete_presets.erase(std::remove(need_delete_presets.begin(), need_delete_presets.end(), setting_id), need_delete_presets.end());
|
||||
}
|
||||
|
||||
bool GUI_App::OnExceptionInMainLoop()
|
||||
{
|
||||
generic_exception_handle();
|
||||
|
|
|
|||
|
|
@ -11,8 +11,10 @@
|
|||
#include "slic3r/GUI/DeviceManager.hpp"
|
||||
#include "slic3r/Utils/NetworkAgent.hpp"
|
||||
#include "slic3r/GUI/WebViewDialog.hpp"
|
||||
#include "slic3r/GUI/WebUserLoginDialog.hpp"
|
||||
#include "slic3r/GUI/HMS.hpp"
|
||||
#include "slic3r/GUI/Jobs/UpgradeNetworkJob.hpp"
|
||||
#include "slic3r/GUI/HttpServer.hpp"
|
||||
#include "../Utils/PrintHost.hpp"
|
||||
|
||||
#include <wx/app.h>
|
||||
|
|
@ -274,7 +276,11 @@ private:
|
|||
bool m_networking_cancel_update { false };
|
||||
std::shared_ptr<UpgradeNetworkJob> m_upgrade_network_job;
|
||||
|
||||
// login widget
|
||||
ZUserLogin* login_dlg { nullptr };
|
||||
|
||||
VersionInfo version_info;
|
||||
VersionInfo privacy_version_info;
|
||||
static std::string version_display;
|
||||
HMSQuery *hms_query { nullptr };
|
||||
|
||||
|
|
@ -283,7 +289,9 @@ private:
|
|||
bool m_is_dark_mode{ false };
|
||||
bool m_adding_script_handler { false };
|
||||
bool m_side_popup_status{false};
|
||||
HttpServer m_http_server;
|
||||
public:
|
||||
void check_filaments_in_blacklist(std::string tag_supplier, std::string tag_material, bool& in_blacklist, std::string& action, std::string& info);
|
||||
std::string get_local_models_path();
|
||||
bool OnInit() override;
|
||||
bool initialized() const { return m_initialized; }
|
||||
|
|
@ -380,7 +388,7 @@ public:
|
|||
wxString transition_tridid(int trid_id);
|
||||
void ShowUserGuide();
|
||||
void ShowDownNetPluginDlg();
|
||||
void ShowUserLogin();
|
||||
void ShowUserLogin(bool show = true);
|
||||
void ShowOnlyFilament();
|
||||
//BBS
|
||||
void request_login(bool show_user_info = false);
|
||||
|
|
@ -388,7 +396,8 @@ public:
|
|||
void get_login_info();
|
||||
bool is_user_login();
|
||||
|
||||
void request_user_login(int online_login);
|
||||
void request_user_login(int online_login = 0);
|
||||
void request_user_handle(int online_login = 0);
|
||||
void request_user_logout();
|
||||
int request_user_unbind(std::string dev_id);
|
||||
std::string handle_web_request(std::string cmd);
|
||||
|
|
@ -401,7 +410,9 @@ public:
|
|||
|
||||
void handle_http_error(unsigned int status, std::string body);
|
||||
void on_http_error(wxCommandEvent &evt);
|
||||
void on_set_selected_machine(wxCommandEvent& evt);
|
||||
void on_user_login(wxCommandEvent &evt);
|
||||
void on_user_login_handle(wxCommandEvent& evt);
|
||||
void enable_user_preset_folder(bool enable);
|
||||
|
||||
// BBS
|
||||
|
|
@ -422,8 +433,16 @@ public:
|
|||
void reload_settings();
|
||||
void remove_user_presets();
|
||||
void sync_preset(Preset* preset);
|
||||
void start_sync_user_preset(bool with_progress_dlg = false);
|
||||
void start_sync_user_preset(bool load_immediately = false, bool with_progress_dlg = false);
|
||||
void stop_sync_user_preset();
|
||||
void start_http_server();
|
||||
void stop_http_server();
|
||||
|
||||
void on_show_check_privacy_dlg(int online_login = 0);
|
||||
void show_check_privacy_dlg(wxCommandEvent& evt);
|
||||
void on_check_privacy_update(wxCommandEvent &evt);
|
||||
bool check_privacy_update();
|
||||
void check_privacy_version(int online_login = 0);
|
||||
|
||||
static bool catch_error(std::function<void()> cb, const std::string& err);
|
||||
|
||||
|
|
@ -457,8 +476,10 @@ public:
|
|||
bool checked_tab(Tab* tab);
|
||||
//BBS: add preset combox re-active logic
|
||||
void load_current_presets(bool active_preset_combox = false, bool check_printer_presets = true);
|
||||
std::vector<std::string>& get_delete_cache_presets();
|
||||
std::vector<std::string> &get_delete_cache_presets();
|
||||
std::vector<std::string> get_delete_cache_presets_lock();
|
||||
void delete_preset_from_cloud(std::string setting_id);
|
||||
void preset_deleted_from_cloud(std::string setting_id);
|
||||
|
||||
wxString current_language_code() const { return m_wxLocale->GetCanonicalName(); }
|
||||
// Translate the language code to a code, for which Prusa Research maintains translations. Defaults to "en_US".
|
||||
|
|
@ -486,13 +507,21 @@ public:
|
|||
Model& model();
|
||||
NotificationManager * notification_manager();
|
||||
|
||||
|
||||
std::string m_mall_model_download_url;
|
||||
std::string m_mall_model_download_name;
|
||||
ModelMallDialog* m_mall_home_dialog{ nullptr };
|
||||
ModelMallDialog* m_mall_publish_dialog{ nullptr };
|
||||
|
||||
void set_download_model_url(std::string url) {m_mall_model_download_url = url;}
|
||||
void set_download_model_name(std::string name) {m_mall_model_download_name = name;}
|
||||
std::string get_download_model_url() {return m_mall_model_download_url;}
|
||||
std::string get_download_model_name() {return m_mall_model_download_name;}
|
||||
|
||||
void load_url(wxString url);
|
||||
void open_mall_page_dialog();
|
||||
void open_publish_page_dialog();
|
||||
void remove_mall_system_dialog();
|
||||
void remove_mall_system_dialog();
|
||||
void run_script(wxString js);
|
||||
bool is_adding_script_handler() { return m_adding_script_handler; }
|
||||
void set_adding_script_handler(bool status) { m_adding_script_handler = status; }
|
||||
|
|
@ -574,6 +603,7 @@ private:
|
|||
//BBS set extra header for http request
|
||||
std::map<std::string, std::string> get_extra_header();
|
||||
void init_http_extra_header();
|
||||
void update_http_extra_header();
|
||||
bool check_older_app_config(Semver current_version, bool backup);
|
||||
void copy_older_config();
|
||||
void window_pos_save(wxTopLevelWindow* window, const std::string &name);
|
||||
|
|
|
|||
|
|
@ -432,6 +432,19 @@ std::vector<wxBitmap> MenuFactory::get_volume_bitmaps()
|
|||
return volume_bmps;
|
||||
}
|
||||
|
||||
void MenuFactory::append_menu_item_set_visible(wxMenu* menu)
|
||||
{
|
||||
bool has_one_shown = false;
|
||||
const Selection& selection = plater()->canvas3D()->get_selection();
|
||||
for (unsigned int i : selection.get_volume_idxs()) {
|
||||
has_one_shown |= selection.get_volume(i)->visible;
|
||||
}
|
||||
|
||||
append_menu_item(menu, wxID_ANY, has_one_shown ?_L("Hide") : _L("Show"), "",
|
||||
[has_one_shown](wxCommandEvent&) { plater()->set_selected_visible(!has_one_shown); }, "", nullptr,
|
||||
[]() { return true; }, m_parent);
|
||||
}
|
||||
|
||||
void MenuFactory::append_menu_item_delete(wxMenu* menu)
|
||||
{
|
||||
#ifdef __WINDOWS__
|
||||
|
|
@ -445,6 +458,19 @@ void MenuFactory::append_menu_item_delete(wxMenu* menu)
|
|||
#endif
|
||||
}
|
||||
|
||||
void MenuFactory::append_menu_item_edit_text(wxMenu *menu)
|
||||
{
|
||||
#ifdef __WINDOWS__
|
||||
append_menu_item(
|
||||
menu, wxID_ANY, _L("Edit Text"), "", [](wxCommandEvent &) { plater()->edit_text(); }, "", nullptr,
|
||||
[]() { return plater()->can_edit_text(); }, m_parent);
|
||||
#else
|
||||
append_menu_item(
|
||||
menu, wxID_ANY, _L("Edit Text"), "", [](wxCommandEvent &) { plater()->edit_text(); }, "", nullptr,
|
||||
[]() { return plater()->can_edit_text(); }, m_parent);
|
||||
#endif
|
||||
}
|
||||
|
||||
wxMenu* MenuFactory::append_submenu_add_generic(wxMenu* menu, ModelVolumeType type) {
|
||||
auto sub_menu = new wxMenu;
|
||||
|
||||
|
|
@ -735,6 +761,8 @@ void MenuFactory::append_menu_items_flush_options(wxMenu* menu)
|
|||
bool show_flush_option_menu = false;
|
||||
ObjectList* object_list = obj_list();
|
||||
const Selection& selection = get_selection();
|
||||
if (selection.get_object_idx() < 0)
|
||||
return;
|
||||
if (wxGetApp().plater()->get_partplate_list().get_curr_plate()->contains(selection.get_bounding_box())) {
|
||||
auto plate_extruders = wxGetApp().plater()->get_partplate_list().get_curr_plate()->get_extruders();
|
||||
for (auto extruder : plate_extruders) {
|
||||
|
|
@ -784,7 +812,7 @@ void MenuFactory::append_menu_items_flush_options(wxMenu* menu)
|
|||
{
|
||||
i++;
|
||||
wxMenuItem* item = node->GetData();
|
||||
if (item->GetItemLabelText() == "Edit in Parameter Table")
|
||||
if (item->GetItemLabelText() == _L("Edit in Parameter Table"))
|
||||
break;
|
||||
}
|
||||
menu->Insert(i, wxID_ANY, _L("Flush Options"), flush_options_menu);
|
||||
|
|
@ -1057,6 +1085,7 @@ void MenuFactory::create_bbl_part_menu()
|
|||
wxMenu* menu = &m_part_menu;
|
||||
|
||||
append_menu_item_delete(menu);
|
||||
append_menu_item_edit_text(menu);
|
||||
append_menu_item_fix_through_netfabb(menu);
|
||||
append_menu_item_simplify(menu);
|
||||
append_menu_item_center(menu);
|
||||
|
|
@ -1310,8 +1339,9 @@ wxMenu* MenuFactory::assemble_multi_selection_menu()
|
|||
return nullptr;
|
||||
|
||||
wxMenu* menu = new MenuWithSeparators();
|
||||
append_menu_item_fix_through_netfabb(menu);
|
||||
append_menu_item_simplify(menu);
|
||||
append_menu_item_set_visible(menu);
|
||||
//append_menu_item_fix_through_netfabb(menu);
|
||||
//append_menu_item_simplify(menu);
|
||||
append_menu_item_delete(menu);
|
||||
menu->AppendSeparator();
|
||||
append_menu_item_change_extruder(menu);
|
||||
|
|
@ -1328,18 +1358,36 @@ wxMenu* MenuFactory::plate_menu()
|
|||
|
||||
wxMenu* MenuFactory::assemble_object_menu()
|
||||
{
|
||||
wxMenu* menu = new MenuWithSeparators();
|
||||
// Set Visible
|
||||
append_menu_item_set_visible(menu);
|
||||
// Delete
|
||||
append_menu_item_delete(menu);
|
||||
//// Object Repair
|
||||
//append_menu_item_fix_through_netfabb(menu);
|
||||
//// Object Simplify
|
||||
//append_menu_item_simplify(menu);
|
||||
menu->AppendSeparator();
|
||||
|
||||
// Set filament
|
||||
append_menu_item_change_extruder(&m_assemble_object_menu);
|
||||
// Enter per object parameters
|
||||
append_menu_item_per_object_settings(&m_assemble_object_menu);
|
||||
return &m_assemble_object_menu;
|
||||
append_menu_item_change_extruder(menu);
|
||||
//// Enter per object parameters
|
||||
//append_menu_item_per_object_settings(menu);
|
||||
return menu;
|
||||
}
|
||||
|
||||
wxMenu* MenuFactory::assemble_part_menu()
|
||||
{
|
||||
append_menu_item_change_extruder(&m_assemble_part_menu);
|
||||
append_menu_item_per_object_settings(&m_assemble_part_menu);
|
||||
return &m_assemble_part_menu;
|
||||
wxMenu* menu = new MenuWithSeparators();
|
||||
|
||||
append_menu_item_set_visible(menu);
|
||||
append_menu_item_delete(menu);
|
||||
//append_menu_item_simplify(menu);
|
||||
menu->AppendSeparator();
|
||||
|
||||
append_menu_item_change_extruder(menu);
|
||||
//append_menu_item_per_object_settings(menu);
|
||||
return menu;
|
||||
}
|
||||
|
||||
void MenuFactory::append_menu_item_clone(wxMenu* menu)
|
||||
|
|
@ -1509,7 +1557,7 @@ void MenuFactory::append_menu_item_set_printable(wxMenu* menu)
|
|||
}
|
||||
}
|
||||
|
||||
wxString menu_text = all_printable ? L("Set Unprintable") : _L("Set Printable");
|
||||
wxString menu_text = all_printable ? _L("Set Unprintable") : _L("Set Printable");
|
||||
append_menu_item(menu, wxID_ANY, menu_text, "", [this, all_printable](wxCommandEvent&) {
|
||||
Selection& selection = plater()->canvas3D()->get_selection();
|
||||
selection.set_printable(!all_printable);
|
||||
|
|
|
|||
|
|
@ -126,7 +126,9 @@ private:
|
|||
void append_menu_item_reload_from_disk(wxMenu* menu);
|
||||
void append_menu_item_replace_with_stl(wxMenu* menu);
|
||||
void append_menu_item_change_extruder(wxMenu* menu);
|
||||
void append_menu_item_set_visible(wxMenu* menu);
|
||||
void append_menu_item_delete(wxMenu* menu);
|
||||
void append_menu_item_edit_text(wxMenu *menu);
|
||||
void append_menu_item_scale_selection_to_fit_print_volume(wxMenu* menu);
|
||||
void append_menu_items_convert_unit(wxMenu* menu); // Add "Conver/Revert..." menu items (from/to inches/meters) after "Reload From Disk"
|
||||
void append_menu_items_flush_options(wxMenu* menu);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "slic3r/Utils/FixModelByWin10.hpp"
|
||||
#include "libslic3r/Format/bbs_3mf.hpp"
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
|
||||
#ifdef __WXMSW__
|
||||
#include "wx/uiaction.h"
|
||||
|
|
@ -91,6 +92,9 @@ ObjectList::ObjectList(wxWindow* parent) :
|
|||
Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [this](wxDataViewEvent& event) {
|
||||
// detect the current mouse position here, to pass it to list_manipulation() method
|
||||
// if we detect it later, the user may have moved the mouse pointer while calculations are performed, and this would mess-up the HitTest() call performed into list_manipulation()
|
||||
if (!GetScreenRect().Contains(wxGetMousePosition())) {
|
||||
return;
|
||||
}
|
||||
#ifndef __WXOSX__
|
||||
const wxPoint mouse_pos = this->get_mouse_position_in_control();
|
||||
#endif
|
||||
|
|
@ -731,7 +735,7 @@ void ObjectList::printable_state_changed(const std::vector<ObjectVolumeID>& ov_i
|
|||
obj_idxs.erase(unique(obj_idxs.begin(), obj_idxs.end()), obj_idxs.end());
|
||||
|
||||
// update printable state on canvas
|
||||
wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_objects(obj_idxs);
|
||||
wxGetApp().plater()->get_view3D_canvas3D()->update_instance_printable_state_for_objects(obj_idxs);
|
||||
|
||||
// update scene
|
||||
wxGetApp().plater()->update();
|
||||
|
|
@ -1397,8 +1401,21 @@ void ObjectList::key_event(wxKeyEvent& event)
|
|||
|
||||
void ObjectList::OnBeginDrag(wxDataViewEvent &event)
|
||||
{
|
||||
bool sequential_print = (wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_enum<PrintSequence>("print_sequence") == PrintSequence::ByObject);
|
||||
if (!sequential_print) {
|
||||
int curr_obj_id = m_objects_model->GetIdByItem(event.GetItem());
|
||||
PartPlateList& partplate_list = wxGetApp().plater()->get_partplate_list();
|
||||
int from_plate = partplate_list.find_instance(curr_obj_id, 0);
|
||||
if (from_plate == -1) {
|
||||
event.Veto();
|
||||
return;
|
||||
}
|
||||
auto curr_plate_seq = partplate_list.get_plate(from_plate)->get_print_seq();
|
||||
if (curr_plate_seq == PrintSequence::ByDefault) {
|
||||
auto curr_preset_config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||
if (curr_preset_config.has("print_sequence"))
|
||||
curr_plate_seq = curr_preset_config.option<ConfigOptionEnum<PrintSequence>>("print_sequence")->value;
|
||||
}
|
||||
|
||||
if (curr_plate_seq != PrintSequence::ByObject) {
|
||||
//drag forbidden under bylayer mode
|
||||
event.Veto();
|
||||
return;
|
||||
|
|
@ -1777,7 +1794,7 @@ void ObjectList::load_subobject(ModelVolumeType type, bool from_galery/* = false
|
|||
|
||||
if (type == ModelVolumeType::MODEL_PART)
|
||||
// update printable state on canvas
|
||||
wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_object((size_t)obj_idx);
|
||||
wxGetApp().plater()->get_view3D_canvas3D()->update_instance_printable_state_for_object((size_t)obj_idx);
|
||||
|
||||
if (items.size() > 1) {
|
||||
m_selection_mode = smVolume;
|
||||
|
|
@ -1923,11 +1940,9 @@ void ObjectList::load_modifier(const wxArrayString& input_files, ModelObject& mo
|
|||
ModelVolume* new_volume = model_object.add_volume(std::move(mesh), type);
|
||||
new_volume->name = boost::filesystem::path(input_file).filename().string();
|
||||
|
||||
// adjust the position according to the bounding box
|
||||
const BoundingBoxf3 mesh_bb = new_volume->mesh().bounding_box();
|
||||
new_volume->set_transformation(Geometry::Transformation::volume_to_bed_transformation(v->get_instance_transformation(), mesh_bb));
|
||||
auto offset = Vec3d(instance_bb.max.x(), instance_bb.min.y(), instance_bb.min.z()) + 0.5 * mesh_bb.size() - v->get_instance_offset();
|
||||
new_volume->set_offset(v->get_instance_transformation().get_matrix(true).inverse() * offset);
|
||||
// BBS: object_mesh.get_init_shift() keep the relative position
|
||||
TriangleMesh object_mesh = model_object.volumes[0]->mesh();
|
||||
new_volume->set_offset(new_volume->mesh().get_init_shift() - object_mesh.get_init_shift());
|
||||
|
||||
// set a default extruder value, since user can't add it manually
|
||||
// BBS
|
||||
|
|
@ -2055,7 +2070,7 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode
|
|||
});
|
||||
if (type == ModelVolumeType::MODEL_PART)
|
||||
// update printable state on canvas
|
||||
wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_object((size_t)obj_idx);
|
||||
wxGetApp().plater()->get_view3D_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
|
||||
apply_object_instance_transfrom_to_all_volumes(&model_object);
|
||||
|
|
@ -2158,50 +2173,54 @@ void ObjectList::load_mesh_object(const TriangleMesh &mesh, const wxString &name
|
|||
#endif /* _DEBUG */
|
||||
}
|
||||
|
||||
void ObjectList::load_mesh_part(const TriangleMesh& mesh, const wxString& name, bool center)
|
||||
int ObjectList::load_mesh_part(const TriangleMesh &mesh, const wxString &name, const TextInfo &text_info, bool is_temp)
|
||||
{
|
||||
wxDataViewItem item = GetSelection();
|
||||
// we can add volumes for Object or Instance
|
||||
if (!item || !(m_objects_model->GetItemType(item) & (itObject | itInstance)))
|
||||
return;
|
||||
return -1;
|
||||
const int obj_idx = m_objects_model->GetObjectIdByItem(item);
|
||||
|
||||
if (obj_idx < 0) return;
|
||||
if (obj_idx < 0)
|
||||
return -1;
|
||||
|
||||
// Get object item, if Instance is selected
|
||||
if (m_objects_model->GetItemType(item) & itInstance)
|
||||
item = m_objects_model->GetItemById(obj_idx);
|
||||
|
||||
take_snapshot("Load Mesh Part");
|
||||
|
||||
ModelObject* mo = (*m_objects)[obj_idx];
|
||||
|
||||
Geometry::Transformation instance_transformation = mo->instances[0]->get_transformation();
|
||||
|
||||
// apply the instance transform to all volumes and reset instance transform except the offset
|
||||
apply_object_instance_transfrom_to_all_volumes(mo);
|
||||
apply_object_instance_transfrom_to_all_volumes(mo, !is_temp);
|
||||
|
||||
ModelVolume* mv = mo->add_volume(mesh);
|
||||
Vec3d instance_bbox = mo->mesh().bounding_box().size();
|
||||
Vec3d offset = Vec3d(0, 0, instance_bbox[2] / 2);
|
||||
mv->set_offset(offset);
|
||||
ModelVolume *mv = mo->add_volume(mesh);
|
||||
mv->name = name.ToStdString();
|
||||
if (!text_info.m_text.empty())
|
||||
mv->set_text_info(text_info);
|
||||
|
||||
std::vector<ModelVolume*> volumes;
|
||||
volumes.push_back(mv);
|
||||
wxDataViewItemArray items = reorder_volumes_and_get_selection(obj_idx, [volumes](const ModelVolume* volume) {
|
||||
return std::find(volumes.begin(), volumes.end(), volume) != volumes.end(); });
|
||||
if (!is_temp) {
|
||||
std::vector<ModelVolume *> volumes;
|
||||
volumes.push_back(mv);
|
||||
wxDataViewItemArray items = reorder_volumes_and_get_selection(obj_idx, [volumes](const ModelVolume *volume) {
|
||||
return std::find(volumes.begin(), volumes.end(), volume) != volumes.end();
|
||||
});
|
||||
|
||||
wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_object((size_t)obj_idx);
|
||||
wxGetApp().plater()->get_view3D_canvas3D()->update_instance_printable_state_for_object((size_t) obj_idx);
|
||||
|
||||
if (items.size() > 1) {
|
||||
m_selection_mode = smVolume;
|
||||
m_last_selected_item = wxDataViewItem(nullptr);
|
||||
if (items.size() > 1) {
|
||||
m_selection_mode = smVolume;
|
||||
m_last_selected_item = wxDataViewItem(nullptr);
|
||||
}
|
||||
select_items(items);
|
||||
|
||||
selection_changed();
|
||||
}
|
||||
select_items(items);
|
||||
|
||||
selection_changed();
|
||||
|
||||
//BBS: notify partplate the modify
|
||||
notify_instance_updated(obj_idx);
|
||||
return mo->volumes.size() - 1;
|
||||
}
|
||||
|
||||
//BBS
|
||||
|
|
@ -4563,7 +4582,7 @@ void ObjectList::instances_to_separated_object(const int obj_idx, const std::set
|
|||
}
|
||||
|
||||
// update printable state for new volumes on canvas3D
|
||||
wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_object(new_obj_indx);
|
||||
wxGetApp().plater()->get_view3D_canvas3D()->update_instance_printable_state_for_object(new_obj_indx);
|
||||
update_info_items(new_obj_indx);
|
||||
}
|
||||
|
||||
|
|
@ -4596,7 +4615,7 @@ void ObjectList::instances_to_separated_objects(const int obj_idx)
|
|||
}
|
||||
|
||||
// update printable state for new volumes on canvas3D
|
||||
wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_objects(object_idxs);
|
||||
wxGetApp().plater()->get_view3D_canvas3D()->update_instance_printable_state_for_objects(object_idxs);
|
||||
for (size_t object : object_idxs)
|
||||
update_info_items(object);
|
||||
}
|
||||
|
|
@ -4707,10 +4726,13 @@ void ObjectList::fix_through_netfabb()
|
|||
std::string res;
|
||||
if (!fix_model_by_win10_sdk_gui(*(object(obj_idx)), vol_idx, progress_dlg, msg, res))
|
||||
return false;
|
||||
wxGetApp().plater()->changed_mesh(obj_idx);
|
||||
|
||||
//wxGetApp().plater()->changed_mesh(obj_idx);
|
||||
object(obj_idx)->ensure_on_bed();
|
||||
plater->changed_mesh(obj_idx);
|
||||
|
||||
plater->get_partplate_list().notify_instance_update(obj_idx, 0);
|
||||
plater->sidebar().obj_list()->update_plate_values_for_items();
|
||||
|
||||
if (res.empty())
|
||||
succes_models.push_back(model_name);
|
||||
else
|
||||
|
|
@ -4719,8 +4741,6 @@ void ObjectList::fix_through_netfabb()
|
|||
update_item_error_icon(obj_idx, vol_idx);
|
||||
update_info_items(obj_idx);
|
||||
|
||||
object(obj_idx)->ensure_on_bed();
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
|
@ -5037,7 +5057,7 @@ void ObjectList::reload_all_plates(bool notify_partplate)
|
|||
m_prevent_canvas_selection_update = false;
|
||||
|
||||
// update printable states on canvas
|
||||
wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_objects(obj_idxs);
|
||||
wxGetApp().plater()->get_view3D_canvas3D()->update_instance_printable_state_for_objects(obj_idxs);
|
||||
// update scene
|
||||
wxGetApp().plater()->update();
|
||||
}
|
||||
|
|
@ -5171,7 +5191,7 @@ void ObjectList::toggle_printable_state()
|
|||
obj_idxs.erase(unique(obj_idxs.begin(), obj_idxs.end()), obj_idxs.end());
|
||||
|
||||
// update printable state on canvas
|
||||
wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_objects(obj_idxs);
|
||||
wxGetApp().plater()->get_view3D_canvas3D()->update_instance_printable_state_for_objects(obj_idxs);
|
||||
|
||||
// update scene
|
||||
wxGetApp().plater()->update();
|
||||
|
|
@ -5190,17 +5210,20 @@ bool ObjectList::has_paint_on_segmentation()
|
|||
return m_objects_model->HasInfoItem(InfoItemType::MmuSegmentation);
|
||||
}
|
||||
|
||||
void ObjectList::apply_object_instance_transfrom_to_all_volumes(ModelObject *model_object) {
|
||||
void ObjectList::apply_object_instance_transfrom_to_all_volumes(ModelObject *model_object, bool need_update_assemble_matrix)
|
||||
{
|
||||
const Geometry::Transformation &instance_transformation = model_object->instances[0]->get_transformation();
|
||||
Vec3d original_instance_center = instance_transformation.get_offset();
|
||||
|
||||
// apply the instance_transform(except offset) to assemble_transform
|
||||
Geometry::Transformation instance_transformation_copy = instance_transformation;
|
||||
instance_transformation_copy.set_offset(Vec3d(0, 0, 0)); // remove the effect of offset
|
||||
const Transform3d & instance_inverse_matrix = instance_transformation_copy.get_matrix().inverse();
|
||||
const Transform3d & assemble_matrix = model_object->instances[0]->get_assemble_transformation().get_matrix();
|
||||
Transform3d new_assemble_transform = assemble_matrix * instance_inverse_matrix;
|
||||
model_object->instances[0]->set_assemble_from_transform(new_assemble_transform);
|
||||
if (need_update_assemble_matrix) {
|
||||
// apply the instance_transform(except offset) to assemble_transform
|
||||
Geometry::Transformation instance_transformation_copy = instance_transformation;
|
||||
instance_transformation_copy.set_offset(Vec3d(0, 0, 0)); // remove the effect of offset
|
||||
const Transform3d &instance_inverse_matrix = instance_transformation_copy.get_matrix().inverse();
|
||||
const Transform3d &assemble_matrix = model_object->instances[0]->get_assemble_transformation().get_matrix();
|
||||
Transform3d new_assemble_transform = assemble_matrix * instance_inverse_matrix;
|
||||
model_object->instances[0]->set_assemble_from_transform(new_assemble_transform);
|
||||
}
|
||||
|
||||
// apply the instance_transform to volumn
|
||||
const Transform3d &transformation_matrix = instance_transformation.get_matrix();
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ class ModelConfig;
|
|||
class ModelObject;
|
||||
class ModelVolume;
|
||||
class TriangleMesh;
|
||||
struct TextInfo;
|
||||
enum class ModelVolumeType : int;
|
||||
|
||||
// FIXME: broken build on mac os because of this is missing:
|
||||
|
|
@ -283,7 +284,7 @@ public:
|
|||
void load_mesh_object(const TriangleMesh &mesh, const wxString &name, bool center = true);
|
||||
// BBS
|
||||
void switch_to_object_process();
|
||||
void load_mesh_part(const TriangleMesh& mesh, const wxString& name, bool center = true);
|
||||
int load_mesh_part(const TriangleMesh &mesh, const wxString &name, const TextInfo &text_info, bool is_temp);
|
||||
void del_object(const int obj_idx, bool refresh_immediately = true);
|
||||
void del_subobject_item(wxDataViewItem& item);
|
||||
void del_settings_from_config(const wxDataViewItem& parent_item);
|
||||
|
|
@ -454,7 +455,7 @@ private:
|
|||
void OnEditingDone(wxDataViewEvent &event);
|
||||
|
||||
// apply the instance transform to all volumes and reset instance transform except the offset
|
||||
void apply_object_instance_transfrom_to_all_volumes(ModelObject *model_object);
|
||||
void apply_object_instance_transfrom_to_all_volumes(ModelObject *model_object, bool need_update_assemble_matrix = true);
|
||||
|
||||
std::vector<int> m_columns_width;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -344,7 +344,10 @@ void GridCellFilamentsRenderer::Draw(wxGrid &grid, wxGridCellAttr &attr, wxDC &d
|
|||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||
dc.SetBrush(wxBrush(attr.GetBackgroundColour()));
|
||||
dc.DrawRectangle(rect);
|
||||
dc.DrawBitmap(*bitmap, wxPoint(rect.x + offset_x, rect.y + offset_y));
|
||||
if ( grid_row->model_volume_type != ModelVolumeType::NEGATIVE_VOLUME) {
|
||||
dc.DrawBitmap(*bitmap, wxPoint(rect.x + offset_x, rect.y + offset_y));
|
||||
}
|
||||
|
||||
text_rect.x += bitmap_width + grid_cell_border_width * 2;
|
||||
text_rect.width -= (bitmap_width + grid_cell_border_width * 2);
|
||||
}
|
||||
|
|
@ -1968,6 +1971,7 @@ void ObjectGridTable::construct_object_configs(ObjectGrid *object_grid)
|
|||
{
|
||||
ModelVolume* volume = object->volumes[j];
|
||||
ObjectGridRow* volume_grid = new ObjectGridRow(i, j, row_volume);
|
||||
volume_grid->model_volume_type = volume->type();
|
||||
volume_grid->config = &(volume->config);
|
||||
volume_grid->name.value = volume->name;
|
||||
size_t pos = volume_grid->name.value.find_first_not_of(' ');
|
||||
|
|
@ -2952,11 +2956,21 @@ void ObjectTablePanel::load_data()
|
|||
break;
|
||||
case coEnum:
|
||||
if (col == ObjectGridTable::col_filaments) {
|
||||
GridCellFilamentsEditor *filament_editor = new GridCellFilamentsEditor(grid_col->choice_count, grid_col->choices, false, &m_color_bitmaps);
|
||||
m_object_grid->SetCellEditor(row, col, filament_editor);
|
||||
m_object_grid->SetCellRenderer(row, col, new GridCellFilamentsRenderer());
|
||||
} else {
|
||||
GridCellChoiceEditor *combo_editor = new GridCellChoiceEditor(grid_col->choice_count, grid_col->choices);
|
||||
if (grid_row->model_volume_type != ModelVolumeType::NEGATIVE_VOLUME) {
|
||||
GridCellFilamentsEditor* filament_editor = new GridCellFilamentsEditor(grid_col->choice_count, grid_col->choices, false, &m_color_bitmaps);
|
||||
m_object_grid->SetCellEditor(row, col, filament_editor);
|
||||
m_object_grid->SetCellRenderer(row, col, new GridCellFilamentsRenderer());
|
||||
}
|
||||
else {
|
||||
m_object_grid->SetCellEditor(row, col, new GridCellTextEditor());
|
||||
auto gcfil = new GridCellFilamentsRenderer();
|
||||
m_object_grid->SetCellRenderer(row, col, gcfil);
|
||||
m_object_grid->SetReadOnly(row, col);
|
||||
//m_object_grid->SetCellFitMode(row, col, wxGridFitMode::Ellipsize());
|
||||
}
|
||||
}
|
||||
else {
|
||||
GridCellChoiceEditor* combo_editor = new GridCellChoiceEditor(grid_col->choice_count, grid_col->choices);
|
||||
m_object_grid->SetCellEditor(row, col, combo_editor);
|
||||
m_object_grid->SetCellRenderer(row, col, new wxGridCellChoiceRenderer());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -348,6 +348,7 @@ public:
|
|||
ConfigOptionFloat ori_speed_perimeter;
|
||||
|
||||
ModelConfig* config;
|
||||
ModelVolumeType model_volume_type;
|
||||
|
||||
ObjectGridRow(int obj_id, int vol_id, GridRowType type)
|
||||
: object_id(obj_id), volume_id(vol_id), row_type(type)
|
||||
|
|
|
|||
|
|
@ -385,9 +385,9 @@ void Preview::sys_color_changed()
|
|||
|
||||
void Preview::on_tick_changed(Type type)
|
||||
{
|
||||
if (type == Type::PausePrint) {
|
||||
m_schedule_background_process();
|
||||
}
|
||||
//if (type == Type::PausePrint) {
|
||||
// m_schedule_background_process();
|
||||
//}
|
||||
m_keep_current_preview_type = false;
|
||||
reload_print(false);
|
||||
}
|
||||
|
|
@ -485,8 +485,7 @@ void Preview::update_layers_slider_mode()
|
|||
// check if whole model uses just only one extruder
|
||||
if (!plate_extruders.empty()) {
|
||||
//const int extruder = objects[0]->config.has("extruder") ? objects[0]->config.option("extruder")->getInt() : 0;
|
||||
const int extruder = plate_extruders[0];
|
||||
only_extruder = extruder;
|
||||
only_extruder = plate_extruders[0];
|
||||
// auto is_one_extruder_printed_model = [objects, extruder]() {
|
||||
// for (ModelObject *object : objects) {
|
||||
// if (object->config.has("extruder") && object->config.option("extruder")->getInt() != extruder) /*return false*/;
|
||||
|
|
@ -552,15 +551,16 @@ void Preview::update_layers_slider(const std::vector<double>& layers_z, bool kee
|
|||
// Detect and set manipulation mode for double slider
|
||||
update_layers_slider_mode();
|
||||
|
||||
Plater * plater = wxGetApp().plater();
|
||||
CustomGCode::Info ticks_info_from_model;
|
||||
Plater* plater = wxGetApp().plater();
|
||||
//BBS: replace model custom gcode with current plate custom gcode
|
||||
CustomGCode::Info ticks_info_from_curr_plate;
|
||||
if (wxGetApp().is_editor())
|
||||
ticks_info_from_model = plater->model().custom_gcode_per_print_z;
|
||||
ticks_info_from_curr_plate = plater->model().get_curr_plate_custom_gcodes();
|
||||
else {
|
||||
ticks_info_from_model.mode = CustomGCode::Mode::SingleExtruder;
|
||||
ticks_info_from_model.gcodes = m_canvas->get_custom_gcode_per_print_z();
|
||||
ticks_info_from_curr_plate.mode = CustomGCode::Mode::SingleExtruder;
|
||||
ticks_info_from_curr_plate.gcodes = m_canvas->get_custom_gcode_per_print_z();
|
||||
}
|
||||
check_layers_slider_values(ticks_info_from_model.gcodes, layers_z);
|
||||
check_layers_slider_values(ticks_info_from_curr_plate.gcodes, layers_z);
|
||||
|
||||
// first of all update extruder colors to avoid crash, when we are switching printer preset from MM to SM
|
||||
m_layers_slider->SetExtruderColors(plater->get_extruder_colors_from_plater_config(wxGetApp().is_editor() ? nullptr : m_gcode_result));
|
||||
|
|
@ -581,9 +581,11 @@ void Preview::update_layers_slider(const std::vector<double>& layers_z, bool kee
|
|||
}
|
||||
}
|
||||
m_layers_slider->SetSelectionSpan(idx_low, idx_high);
|
||||
m_layers_slider->SetTicksValues(ticks_info_from_model);
|
||||
m_layers_slider->SetTicksValues(ticks_info_from_curr_plate);
|
||||
|
||||
bool sequential_print = (wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_enum<PrintSequence>("print_sequence") == PrintSequence::ByObject);
|
||||
auto curr_plate = wxGetApp().plater()->get_partplate_list().get_curr_plate();
|
||||
auto curr_print_seq = curr_plate->get_real_print_seq();
|
||||
bool sequential_print = (curr_print_seq == PrintSequence::ByObject);
|
||||
m_layers_slider->SetDrawMode(sequential_print);
|
||||
|
||||
auto print_mode_stat = m_gcode_result->print_statistics.modes.front();
|
||||
|
|
@ -688,7 +690,8 @@ void Preview::load_print_as_fff(bool keep_z_range, bool only_gcode)
|
|||
|
||||
if (!gcode_preview_data_valid) {
|
||||
if (wxGetApp().is_editor())
|
||||
color_print_values = wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes;
|
||||
//BBS
|
||||
color_print_values = wxGetApp().plater()->model().get_curr_plate_custom_gcodes().gcodes;
|
||||
else
|
||||
color_print_values = m_canvas->get_custom_gcode_per_print_z();
|
||||
colors.push_back("#808080"); // gray color for pause print or custom G-code
|
||||
|
|
@ -703,7 +706,8 @@ void Preview::load_print_as_fff(bool keep_z_range, bool only_gcode)
|
|||
|
||||
if (IsShown()) {
|
||||
m_canvas->set_selected_extruder(0);
|
||||
if (gcode_preview_data_valid) {
|
||||
bool is_slice_result_valid = wxGetApp().plater()->get_partplate_list().get_curr_plate()->is_slice_result_valid();
|
||||
if (gcode_preview_data_valid && (is_slice_result_valid || m_only_gcode)) {
|
||||
// Load the real G-code preview.
|
||||
//BBS: add more log
|
||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": will load gcode_preview from result, moves count %1%") % m_gcode_result->moves.size();
|
||||
|
|
@ -734,7 +738,8 @@ void Preview::load_print_as_fff(bool keep_z_range, bool only_gcode)
|
|||
(unsigned int)print->extruders().size() :
|
||||
m_canvas->get_gcode_extruders_count();
|
||||
std::vector<Item> gcodes = wxGetApp().is_editor() ?
|
||||
wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes :
|
||||
//BBS
|
||||
wxGetApp().plater()->model().get_curr_plate_custom_gcodes().gcodes :
|
||||
m_canvas->get_custom_gcode_per_print_z();
|
||||
const wxString choice = !gcodes.empty() ?
|
||||
_L("Multicolor Print") :
|
||||
|
|
|
|||
|
|
@ -430,7 +430,10 @@ bool load_image(const std::string &filename, wxImage &image)
|
|||
result = image.LoadFile(wxString::FromUTF8(filename.c_str()), wxBITMAP_TYPE_BMP);
|
||||
} else if (boost::algorithm::iends_with(filename, ".jpg")) {
|
||||
result = image.LoadFile(wxString::FromUTF8(filename.c_str()), wxBITMAP_TYPE_JPEG);
|
||||
} else {
|
||||
} else if (boost::algorithm::iends_with(filename, ".jpeg")) {
|
||||
result = image.LoadFile(wxString::FromUTF8(filename.c_str()), wxBITMAP_TYPE_JPEG);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -128,6 +128,29 @@ void GLGizmoFdmSupports::render_painter_gizmo() const
|
|||
glsafe(::glDisable(GL_BLEND));
|
||||
}
|
||||
|
||||
// BBS
|
||||
bool GLGizmoFdmSupports::on_key_down_select_tool_type(int keyCode) {
|
||||
switch (keyCode)
|
||||
{
|
||||
case 'F':
|
||||
m_current_tool = ImGui::FillButtonIcon;
|
||||
break;
|
||||
case 'S':
|
||||
m_current_tool = ImGui::SphereButtonIcon;
|
||||
break;
|
||||
case 'C':
|
||||
m_current_tool = ImGui::CircleButtonIcon;
|
||||
break;
|
||||
case 'G':
|
||||
m_current_tool = ImGui::GapFillIcon;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// BBS
|
||||
void GLGizmoFdmSupports::render_triangles(const Selection& selection) const
|
||||
{
|
||||
|
|
@ -865,42 +888,22 @@ void GLGizmoFdmSupports::run_thread()
|
|||
goto _finished;
|
||||
}
|
||||
|
||||
if (m_is_tree_support)
|
||||
if (!m_print_instance.print_object->support_layers().size())
|
||||
{
|
||||
if (!m_print_instance.print_object->tree_support_layers().size())
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ",no tree support layer found, update status to 100%\n";
|
||||
print->set_status(100, L("Support Generated"));
|
||||
goto _finished;
|
||||
}
|
||||
for (const TreeSupportLayer *support_layer : m_print_instance.print_object->tree_support_layers())
|
||||
{
|
||||
for (const ExtrusionEntity *extrusion_entity : support_layer->support_fills.entities)
|
||||
{
|
||||
_3DScene::extrusionentity_to_verts(extrusion_entity, float(support_layer->print_z), m_print_instance.shift, *m_support_volume);
|
||||
}
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished extrusionentity_to_verts, update status to 100%";
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ",no support layer found, update status to 100%\n";
|
||||
print->set_status(100, L("Support Generated"));
|
||||
goto _finished;
|
||||
}
|
||||
else
|
||||
for (const SupportLayer *support_layer : m_print_instance.print_object->support_layers())
|
||||
{
|
||||
if (!m_print_instance.print_object->support_layers().size())
|
||||
for (const ExtrusionEntity *extrusion_entity : support_layer->support_fills.entities)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ",no support layer found, update status to 100%\n";
|
||||
print->set_status(100, L("Support Generated"));
|
||||
goto _finished;
|
||||
_3DScene::extrusionentity_to_verts(extrusion_entity, float(support_layer->print_z), m_print_instance.shift, *m_support_volume);
|
||||
}
|
||||
for (const SupportLayer *support_layer : m_print_instance.print_object->support_layers())
|
||||
{
|
||||
for (const ExtrusionEntity *extrusion_entity : support_layer->support_fills.entities)
|
||||
{
|
||||
_3DScene::extrusionentity_to_verts(extrusion_entity, float(support_layer->print_z), m_print_instance.shift, *m_support_volume);
|
||||
}
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished extrusionentity_to_verts, update status to 100%";
|
||||
print->set_status(100, L("Support Generated"));
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished extrusionentity_to_verts, update status to 100%";
|
||||
print->set_status(100, L("Support Generated"));
|
||||
|
||||
record_timestamp();
|
||||
}
|
||||
catch (...) {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ public:
|
|||
state_ready
|
||||
};
|
||||
|
||||
//BBS
|
||||
bool on_key_down_select_tool_type(int keyCode);
|
||||
|
||||
protected:
|
||||
void on_render_input_window(float x, float y, float bottom_limit) override;
|
||||
std::string on_get_name() const override;
|
||||
|
|
|
|||
|
|
@ -241,6 +241,34 @@ bool GLGizmoMmuSegmentation::on_number_key_down(int number)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GLGizmoMmuSegmentation::on_key_down_select_tool_type(int keyCode) {
|
||||
switch (keyCode)
|
||||
{
|
||||
case 'F':
|
||||
m_current_tool = ImGui::FillButtonIcon;
|
||||
break;
|
||||
case 'T':
|
||||
m_current_tool = ImGui::TriangleButtonIcon;
|
||||
break;
|
||||
case 'S':
|
||||
m_current_tool = ImGui::SphereButtonIcon;
|
||||
break;
|
||||
case 'C':
|
||||
m_current_tool = ImGui::CircleButtonIcon;
|
||||
break;
|
||||
case 'H':
|
||||
m_current_tool = ImGui::HeightRangeIcon;
|
||||
break;
|
||||
case 'G':
|
||||
m_current_tool = ImGui::GapFillIcon;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void render_extruders_combo(const std::string &label,
|
||||
const std::vector<std::string> &extruders,
|
||||
const std::vector<std::array<float, 4>> &extruders_colors,
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ public:
|
|||
|
||||
// BBS
|
||||
bool on_number_key_down(int number);
|
||||
bool on_key_down_select_tool_type(int keyCode);
|
||||
|
||||
protected:
|
||||
// BBS
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ protected:
|
|||
static constexpr float CursorRadiusMin = 0.4f; // cannot be zero
|
||||
static constexpr float CursorRadiusMax = 8.f;
|
||||
static constexpr float CursorRadiusStep = 0.2f;
|
||||
static constexpr float CursorHeightMin = 0.2f; // cannot be zero
|
||||
static constexpr float CursorHeightMin = 0.1f; // cannot be zero
|
||||
static constexpr float CursorHeightMax = 8.f;
|
||||
static constexpr float CursorHeightStep = 0.2f;
|
||||
|
||||
|
|
|
|||
|
|
@ -226,10 +226,11 @@ void GLGizmoScale3D::on_render()
|
|||
|
||||
//draw connections
|
||||
|
||||
if (single_instance || single_volume) {
|
||||
// BBS: when select multiple objects, uniform scale can be deselected, display the connection(4,5)
|
||||
//if (single_instance || single_volume) {
|
||||
glsafe(::glColor4fv(m_grabbers[4].color.data()));
|
||||
render_grabbers_connection(4, 5);
|
||||
}
|
||||
//}
|
||||
|
||||
glsafe(::glColor4fv(m_grabbers[2].color.data()));
|
||||
render_grabbers_connection(6, 7);
|
||||
|
|
|
|||
|
|
@ -78,6 +78,23 @@ void GLGizmoSeam::render_painter_gizmo() const
|
|||
glsafe(::glDisable(GL_BLEND));
|
||||
}
|
||||
|
||||
// BBS
|
||||
bool GLGizmoSeam::on_key_down_select_tool_type(int keyCode) {
|
||||
switch (keyCode)
|
||||
{
|
||||
case 'S':
|
||||
m_current_tool = ImGui::SphereButtonIcon;
|
||||
break;
|
||||
case 'C':
|
||||
m_current_tool = ImGui::CircleButtonIcon;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void GLGizmoSeam::render_triangles(const Selection& selection) const
|
||||
{
|
||||
ClippingPlaneDataWrapper clp_data = this->get_clipping_plane_data();
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@ public:
|
|||
|
||||
void render_painter_gizmo() const override;
|
||||
|
||||
//BBS
|
||||
bool on_key_down_select_tool_type(int keyCode);
|
||||
|
||||
protected:
|
||||
// BBS
|
||||
void on_set_state() override;
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ GLGizmoSimplify::GLGizmoSimplify(GLCanvas3D & parent,
|
|||
{}
|
||||
|
||||
GLGizmoSimplify::~GLGizmoSimplify()
|
||||
{
|
||||
{
|
||||
stop_worker_thread_request();
|
||||
if (m_worker.joinable())
|
||||
m_worker.join();
|
||||
|
|
@ -173,10 +173,10 @@ void GLGizmoSimplify::on_render_input_window(float x, float y, float bottom_limi
|
|||
|
||||
// Whether to trigger calculation after rendering is done.
|
||||
bool start_process = false;
|
||||
|
||||
|
||||
|
||||
// Check selection of new volume
|
||||
// Do not reselect object when processing
|
||||
// Do not reselect object when processing
|
||||
if (act_volume != m_volume) {
|
||||
bool change_window_position = (m_volume == nullptr);
|
||||
// select different model
|
||||
|
|
@ -193,13 +193,13 @@ void GLGizmoSimplify::on_render_input_window(float x, float y, float bottom_limi
|
|||
// Start processing. If we switched from another object, process will
|
||||
// stop the background thread and it will restart itself later.
|
||||
start_process = true;
|
||||
|
||||
|
||||
// set window position
|
||||
if (m_move_to_center && change_window_position) {
|
||||
m_move_to_center = false;
|
||||
auto parent_size = m_parent.get_canvas_size();
|
||||
auto parent_size = m_parent.get_canvas_size();
|
||||
ImVec2 pos(parent_size.get_width() / 2 - m_gui_cfg->window_offset_x,
|
||||
parent_size.get_height() / 2 - m_gui_cfg->window_offset_y);
|
||||
parent_size.get_height() / 2 - m_gui_cfg->window_offset_y);
|
||||
ImGui::SetNextWindowPos(pos, ImGuiCond_Always);
|
||||
}else if (change_window_position) {
|
||||
ImVec2 pos = ImGui::GetMousePos();
|
||||
|
|
@ -212,7 +212,7 @@ void GLGizmoSimplify::on_render_input_window(float x, float y, float bottom_limi
|
|||
// maximal bottom right value
|
||||
auto parent_size = m_parent.get_canvas_size();
|
||||
ImVec2 br(
|
||||
parent_size.get_width() - (2 * m_gui_cfg->window_offset_x + m_gui_cfg->window_padding),
|
||||
parent_size.get_width() - (2 * m_gui_cfg->window_offset_x + m_gui_cfg->window_padding),
|
||||
parent_size.get_height() - (2 * m_gui_cfg->window_offset_y + m_gui_cfg->window_padding));
|
||||
if (pos.x > br.x) pos.x = br.x;
|
||||
if (pos.y > br.y) pos.y = br.y;
|
||||
|
|
@ -466,7 +466,7 @@ void GLGizmoSimplify::process()
|
|||
m_worker.join();
|
||||
}
|
||||
|
||||
// Copy configuration that will be used.
|
||||
// Copy configuration that will be used.
|
||||
m_state.config = m_configuration;
|
||||
m_state.mv = m_volume;
|
||||
m_state.status = State::running;
|
||||
|
|
@ -542,11 +542,12 @@ void GLGizmoSimplify::apply_simplify() {
|
|||
mv->set_mesh(std::move(*m_state.result));
|
||||
m_state.result.reset();
|
||||
mv->calculate_convex_hull();
|
||||
mv->invalidate_convex_hull_2d();
|
||||
mv->set_new_unique_id();
|
||||
mv->get_object()->invalidate_bounding_box();
|
||||
mv->get_object()->ensure_on_bed();
|
||||
|
||||
// fix hollowing, sla support points, modifiers, ...
|
||||
// fix hollowing, sla support points, modifiers, ...
|
||||
plater->changed_mesh(object_idx);
|
||||
// Fix warning icon in object list
|
||||
wxGetApp().obj_list()->update_item_error_icon(object_idx, -1);
|
||||
|
|
@ -559,7 +560,7 @@ bool GLGizmoSimplify::on_is_activable() const
|
|||
m_parent.get_selection().is_single_volume();
|
||||
}
|
||||
|
||||
void GLGizmoSimplify::on_set_state()
|
||||
void GLGizmoSimplify::on_set_state()
|
||||
{
|
||||
// Closing gizmo. e.g. selecting another one
|
||||
if (GLGizmoBase::m_state == GLGizmoBase::Off) {
|
||||
|
|
@ -574,12 +575,12 @@ void GLGizmoSimplify::on_set_state()
|
|||
}
|
||||
}
|
||||
|
||||
void GLGizmoSimplify::create_gui_cfg() {
|
||||
void GLGizmoSimplify::create_gui_cfg() {
|
||||
if (m_gui_cfg.has_value()) return;
|
||||
int space_size = m_imgui->calc_text_size(":MM").x;
|
||||
GuiCfg cfg;
|
||||
cfg.top_left_width = std::max(m_imgui->calc_text_size(tr_mesh_name).x,
|
||||
m_imgui->calc_text_size(tr_triangles).x)
|
||||
m_imgui->calc_text_size(tr_triangles).x)
|
||||
+ space_size;
|
||||
|
||||
const float radio_size = ImGui::GetFrameHeight();
|
||||
|
|
@ -591,7 +592,7 @@ void GLGizmoSimplify::create_gui_cfg() {
|
|||
cfg.input_width = cfg.bottom_left_width * 1.5;
|
||||
cfg.window_offset_x = (cfg.bottom_left_width + cfg.input_width)/2;
|
||||
cfg.window_offset_y = ImGui::GetTextLineHeightWithSpacing() * 5;
|
||||
|
||||
|
||||
m_gui_cfg = cfg;
|
||||
}
|
||||
|
||||
|
|
@ -605,7 +606,7 @@ void GLGizmoSimplify::request_rerender(bool force) {
|
|||
}
|
||||
|
||||
void GLGizmoSimplify::set_center_position() {
|
||||
m_move_to_center = true;
|
||||
m_move_to_center = true;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -619,7 +620,7 @@ void GLGizmoSimplify::init_model(const indexed_triangle_set& its)
|
|||
m_parent.toggle_model_objects_visibility(true); // selected volume may have changed
|
||||
m_parent.toggle_model_objects_visibility(false, m_c->selection_info()->model_object(),
|
||||
m_c->selection_info()->get_active_instance(), m_volume);
|
||||
|
||||
|
||||
if (const Selection&sel = m_parent.get_selection(); sel.get_volume_idxs().size() == 1)
|
||||
m_glmodel.set_color(-1, sel.get_volume(*sel.get_volume_idxs().begin())->color);
|
||||
m_triangle_count = its.indices.size();
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -4,13 +4,17 @@
|
|||
#include "GLGizmoBase.hpp"
|
||||
#include "slic3r/GUI/3DScene.hpp"
|
||||
#include "../GLTexture.hpp"
|
||||
#include "../Camera.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
enum class ModelVolumeType : int;
|
||||
class ModelVolume;
|
||||
|
||||
namespace GUI {
|
||||
|
||||
enum class SLAGizmoEventType : unsigned char;
|
||||
class GLGizmoText : public GLGizmoBase
|
||||
{
|
||||
private:
|
||||
|
|
@ -22,10 +26,21 @@ private:
|
|||
bool m_bold = true;
|
||||
bool m_italic = false;
|
||||
float m_thickness = 2.f;
|
||||
float m_embeded_depth = 0.f;
|
||||
float m_rotate_angle = 0;
|
||||
float m_text_gap = 0.f;
|
||||
bool m_is_surface_text = false;
|
||||
bool m_keep_horizontal = false;
|
||||
mutable RaycastResult m_rr;
|
||||
|
||||
float m_combo_height = 0.0f;
|
||||
float m_combo_width = 0.0f;
|
||||
float m_scale;
|
||||
|
||||
Vec2d m_mouse_position = Vec2d::Zero();
|
||||
Vec2d m_origin_mouse_position = Vec2d::Zero();
|
||||
bool m_shift_down = false;
|
||||
|
||||
class TextureInfo {
|
||||
public:
|
||||
GLTexture* texture { nullptr };
|
||||
|
|
@ -38,18 +53,46 @@ private:
|
|||
|
||||
std::vector<TextureInfo> m_textures;
|
||||
|
||||
std::vector<std::string> m_font_names;
|
||||
|
||||
bool m_is_modify = false;
|
||||
bool m_need_update_text = false;
|
||||
|
||||
int m_object_idx = -1;
|
||||
int m_volume_idx = -1;
|
||||
|
||||
int m_preview_text_volume_id = -1;
|
||||
|
||||
Vec3d m_mouse_position_world = Vec3d::Zero();
|
||||
Vec3d m_mouse_normal_world = Vec3d::Zero();
|
||||
|
||||
Vec3d m_cut_plane_dir = Vec3d::UnitZ();
|
||||
|
||||
std::vector<Vec3d> m_position_points;
|
||||
std::vector<Vec3d> m_normal_points;
|
||||
|
||||
// This map holds all translated description texts, so they can be easily referenced during layout calculations
|
||||
// etc. When language changes, GUI is recreated and this class constructed again, so the change takes effect.
|
||||
std::map<std::string, wxString> m_desc;
|
||||
|
||||
public:
|
||||
GLGizmoText(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
|
||||
~GLGizmoText();
|
||||
|
||||
void update_font_texture();
|
||||
|
||||
bool gizmo_event(SLAGizmoEventType action, const Vec2d &mouse_position, bool shift_down, bool alt_down, bool control_down);
|
||||
|
||||
bool is_mesh_point_clipped(const Vec3d &point, const Transform3d &trafo) const;
|
||||
BoundingBoxf3 bounding_box() const;
|
||||
|
||||
protected:
|
||||
virtual bool on_init() override;
|
||||
virtual std::string on_get_name() const override;
|
||||
virtual bool on_is_activable() const override;
|
||||
virtual void on_render() override;
|
||||
virtual void on_render_for_picking() override;
|
||||
virtual void on_update(const UpdateData &data) override;
|
||||
void push_combo_style(const float scale);
|
||||
void pop_combo_style();
|
||||
void push_button_style(bool pressed);
|
||||
|
|
@ -57,6 +100,21 @@ protected:
|
|||
virtual void on_set_state() override;
|
||||
virtual CommonGizmosDataID on_get_requirements() const override;
|
||||
virtual void on_render_input_window(float x, float y, float bottom_limit);
|
||||
|
||||
void show_tooltip_information(float x, float y);
|
||||
|
||||
private:
|
||||
ModelVolume *get_selected_single_volume(int& out_object_idx, int& out_volume_idx) const;
|
||||
void reset_text_info();
|
||||
bool update_text_positions(const std::vector<std::string>& texts);
|
||||
TriangleMesh get_text_mesh(const char* text_str, const Vec3d &position, const Vec3d &normal, const Vec3d &text_up_dir);
|
||||
|
||||
bool update_raycast_cache(const Vec2d &mouse_position, const Camera &camera, const std::vector<Transform3d> &trafo_matrices);
|
||||
void generate_text_volume(bool is_temp = true);
|
||||
void delete_temp_preview_text_volume();
|
||||
|
||||
TextInfo get_text_info();
|
||||
void load_from_text_info(const TextInfo &text_info);
|
||||
};
|
||||
|
||||
} // namespace GUI
|
||||
|
|
|
|||
|
|
@ -405,11 +405,12 @@ void GLGizmosManager::update_data()
|
|||
enable_grabber(Rotate, 0, !is_wipe_tower);
|
||||
enable_grabber(Rotate, 1, !is_wipe_tower);
|
||||
|
||||
bool enable_scale_xyz = selection.is_single_full_instance() || selection.is_single_volume() || selection.is_single_modifier();
|
||||
for (unsigned int i = 0; i < 6; ++i)
|
||||
{
|
||||
enable_grabber(Scale, i, enable_scale_xyz);
|
||||
}
|
||||
// BBS: when select multiple objects, uniform scale can be deselected, display the 0-5 grabbers
|
||||
//bool enable_scale_xyz = selection.is_single_full_instance() || selection.is_single_volume() || selection.is_single_modifier();
|
||||
//for (unsigned int i = 0; i < 6; ++i)
|
||||
//{
|
||||
// enable_grabber(Scale, i, enable_scale_xyz);
|
||||
//}
|
||||
|
||||
if (m_common_gizmos_data) {
|
||||
m_common_gizmos_data->update(get_current()
|
||||
|
|
@ -624,6 +625,8 @@ bool GLGizmosManager::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_p
|
|||
return dynamic_cast<GLGizmoSeam*>(m_gizmos[Seam].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
|
||||
else if (m_current == MmuSegmentation)
|
||||
return dynamic_cast<GLGizmoMmuSegmentation*>(m_gizmos[MmuSegmentation].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
|
||||
else if (m_current == Text)
|
||||
return dynamic_cast<GLGizmoText*>(m_gizmos[Text].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
|
@ -756,7 +759,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt)
|
|||
// mouse anywhere
|
||||
if (evt.Moving()) {
|
||||
m_tooltip = update_hover_state(mouse_pos);
|
||||
if (m_current == MmuSegmentation || m_current == FdmSupports)
|
||||
if (m_current == MmuSegmentation || m_current == FdmSupports || m_current == Text)
|
||||
// BBS
|
||||
gizmo_event(SLAGizmoEventType::Moving, mouse_pos, evt.ShiftDown(), evt.AltDown(), evt.ControlDown());
|
||||
} else if (evt.LeftUp()) {
|
||||
|
|
@ -839,8 +842,8 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt)
|
|||
//if (evt.AltDown())
|
||||
// transformation_type.set_independent();
|
||||
selection.scale(get_scale(), transformation_type);
|
||||
//if (control_down)
|
||||
// selection.translate(get_scale_offset(), true);
|
||||
if (control_down && m_gizmos[m_current].get()->get_hover_id() < 6)
|
||||
selection.translate(get_scale_offset(), true);
|
||||
// BBS
|
||||
//wxGetApp().obj_manipul()->set_dirty();
|
||||
break;
|
||||
|
|
@ -869,7 +872,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt)
|
|||
m_tooltip.clear();
|
||||
|
||||
if (evt.LeftDown() && (!control_down || grabber_contains_mouse())) {
|
||||
if ((m_current == SlaSupports || m_current == Hollow || m_current == FdmSupports || m_current == Seam || m_current == MmuSegmentation)
|
||||
if ((m_current == SlaSupports || m_current == Hollow || m_current == FdmSupports || m_current == Seam || m_current == MmuSegmentation || m_current == Text)
|
||||
&& gizmo_event(SLAGizmoEventType::LeftDown, mouse_pos, evt.ShiftDown(), evt.AltDown()))
|
||||
// the gizmo got the event and took some action, there is no need to do anything more
|
||||
processed = true;
|
||||
|
|
@ -1181,10 +1184,40 @@ bool GLGizmosManager::on_key(wxKeyEvent& evt)
|
|||
processed = simplify->on_esc_key_down();
|
||||
}
|
||||
// BBS
|
||||
else if (m_current == MmuSegmentation && keyCode > '0' && keyCode <= '9') {
|
||||
else if (m_current == MmuSegmentation) {
|
||||
GLGizmoMmuSegmentation* mmu_seg = dynamic_cast<GLGizmoMmuSegmentation*>(get_current());
|
||||
if (mmu_seg != nullptr)
|
||||
processed = mmu_seg->on_number_key_down(keyCode - '0');
|
||||
if (mmu_seg != nullptr) {
|
||||
if (keyCode > '0' && keyCode <= '9') {
|
||||
processed = mmu_seg->on_number_key_down(keyCode - '0');
|
||||
}
|
||||
else if (keyCode == 'F' || keyCode == 'T' || keyCode == 'S' || keyCode == 'C' || keyCode == 'H' || keyCode == 'G') {
|
||||
processed = mmu_seg->on_key_down_select_tool_type(keyCode);
|
||||
if (processed) {
|
||||
// force extra frame to automatically update window size
|
||||
wxGetApp().imgui()->set_requires_extra_frame();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (m_current == FdmSupports) {
|
||||
GLGizmoFdmSupports* fdm_support = dynamic_cast<GLGizmoFdmSupports*>(get_current());
|
||||
if (fdm_support != nullptr && keyCode == 'F' || keyCode == 'S' || keyCode == 'C' || keyCode == 'G') {
|
||||
processed = fdm_support->on_key_down_select_tool_type(keyCode);
|
||||
}
|
||||
if (processed) {
|
||||
// force extra frame to automatically update window size
|
||||
wxGetApp().imgui()->set_requires_extra_frame();
|
||||
}
|
||||
}
|
||||
else if (m_current == Seam) {
|
||||
GLGizmoSeam* seam = dynamic_cast<GLGizmoSeam*>(get_current());
|
||||
if (seam != nullptr && keyCode == 'S' || keyCode == 'C') {
|
||||
processed = seam->on_key_down_select_tool_type(keyCode);
|
||||
}
|
||||
if (processed) {
|
||||
// force extra frame to automatically update window size
|
||||
wxGetApp().imgui()->set_requires_extra_frame();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1504,7 +1537,7 @@ void GLGizmosManager::update_on_off_state(const Vec2d& mouse_pos)
|
|||
if (idx != Undefined && m_gizmos[idx]->is_activable() && m_hover == idx) {
|
||||
activate_gizmo(m_current == idx ? Undefined : (EType)idx);
|
||||
// BBS
|
||||
wxGetApp().obj_list()->select_object_item((EType)idx <= Scale);
|
||||
wxGetApp().obj_list()->select_object_item((EType) idx <= Scale || (EType) idx == Text);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -304,7 +304,12 @@ void GizmoObjectManipulation::change_scale_value(int axis, double value)
|
|||
return;
|
||||
|
||||
Vec3d scale = m_cache.scale;
|
||||
scale(axis) = value;
|
||||
if (scale[axis] != 0 && std::abs(m_cache.size[axis] * value / scale[axis]) > MAX_NUM) {
|
||||
scale[axis] *= MAX_NUM / m_cache.size[axis];
|
||||
}
|
||||
else {
|
||||
scale(axis) = value;
|
||||
}
|
||||
|
||||
this->do_scale(axis, scale);
|
||||
|
||||
|
|
@ -351,7 +356,8 @@ void GizmoObjectManipulation::do_scale(int axis, const Vec3d &scale) const
|
|||
transformation_type.set_local();
|
||||
}
|
||||
|
||||
if (m_uniform_scale || selection.requires_uniform_scale())
|
||||
// BBS: when select multiple objects, uniform scale can be deselected
|
||||
if (m_uniform_scale/* || selection.requires_uniform_scale()*/)
|
||||
scaling_factor = scale(axis) * Vec3d::Ones();
|
||||
|
||||
selection.start_dragging();
|
||||
|
|
@ -505,18 +511,6 @@ bool GizmoObjectManipulation::reset_button(ImGuiWrapper *imgui_wrapper, float ca
|
|||
unit_size = std::max(nuit_max[i], unit_size);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (str == "scale") {
|
||||
if (vec1[i] > 39062.46)vec1[i] = 39062.46;
|
||||
if (vec2[i] > 9999.99)vec2[i] = 9999.99;
|
||||
}
|
||||
if (str == "move") {
|
||||
if (vec1[i] > 9999.99)vec1[i] = 9999.99;
|
||||
if (vec2[i] > 9999.99)vec2[i] = 9999.99;
|
||||
}
|
||||
}
|
||||
|
||||
return unit_size + 8.0;
|
||||
}
|
||||
|
||||
|
|
@ -609,6 +603,7 @@ void GizmoObjectManipulation::do_render_move_window(ImGuiWrapper *imgui_wrapper,
|
|||
for (int i = 0;i<display_position.size();i++)
|
||||
{
|
||||
if (display_position[i] > MAX_NUM)display_position[i] = MAX_NUM;
|
||||
if (display_position[i] < -MAX_NUM)display_position[i] = -MAX_NUM;
|
||||
}
|
||||
|
||||
m_buffered_position = display_position;
|
||||
|
|
@ -842,6 +837,7 @@ void GizmoObjectManipulation::do_render_scale_input_window(ImGuiWrapper* imgui_w
|
|||
ImGui::BBLInputDouble(label_scale_values[0][2], &scale[2], 0.0f, 0.0f, "%.2f");
|
||||
ImGui::SameLine(caption_max + (++index_unit) *unit_size + (++index) * space_size);
|
||||
imgui_wrapper->text(_L("%"));
|
||||
m_buffered_scale = scale;
|
||||
|
||||
if (m_show_clear_scale) {
|
||||
ImGui::SameLine(caption_max + 3 * unit_size + 4 * space_size + end_text_size);
|
||||
|
|
@ -878,9 +874,8 @@ void GizmoObjectManipulation::do_render_scale_input_window(ImGuiWrapper* imgui_w
|
|||
|
||||
for (int i = 0;i<display_size.size();i++)
|
||||
{
|
||||
if (display_size[i] > MAX_NUM || scale[i]> MAX_NUM)display_size[i] = MAX_NUM;
|
||||
if (std::abs(display_size[i]) > MAX_NUM) display_size[i] = MAX_NUM;
|
||||
}
|
||||
m_buffered_scale = scale;
|
||||
m_buffered_size = display_size;
|
||||
int size_sel = update(current_active_id, "size", original_size, m_buffered_size);
|
||||
ImGui::PopStyleVar(1);
|
||||
|
|
@ -889,16 +884,18 @@ void GizmoObjectManipulation::do_render_scale_input_window(ImGuiWrapper* imgui_w
|
|||
|
||||
bool uniform_scale = this->m_uniform_scale;
|
||||
|
||||
const Selection &selection = m_glcanvas.get_selection();
|
||||
bool uniform_scale_only = selection.is_multiple_full_object() || selection.is_multiple_full_instance() || selection.is_mixed() || selection.is_multiple_volume() || selection.is_multiple_modifier();
|
||||
// BBS: when select multiple objects, uniform scale can be deselected
|
||||
//const Selection &selection = m_glcanvas.get_selection();
|
||||
//bool uniform_scale_only = selection.is_multiple_full_object() || selection.is_multiple_full_instance() || selection.is_mixed() || selection.is_multiple_volume() ||
|
||||
// selection.is_multiple_modifier();
|
||||
|
||||
if (uniform_scale_only) {
|
||||
imgui_wrapper->disabled_begin(true);
|
||||
imgui_wrapper->bbl_checkbox(_L("uniform scale"), uniform_scale_only);
|
||||
imgui_wrapper->disabled_end();
|
||||
} else {
|
||||
//if (uniform_scale_only) {
|
||||
// imgui_wrapper->disabled_begin(true);
|
||||
// imgui_wrapper->bbl_checkbox(_L("uniform scale"), uniform_scale_only);
|
||||
// imgui_wrapper->disabled_end();
|
||||
//} else {
|
||||
imgui_wrapper->bbl_checkbox(_L("uniform scale"), uniform_scale);
|
||||
}
|
||||
//}
|
||||
if (uniform_scale != this->m_uniform_scale) { this->set_uniform_scaling(uniform_scale); }
|
||||
|
||||
// for (int index = 0; index < 3; index++)
|
||||
|
|
|
|||
|
|
@ -248,26 +248,27 @@ wxString HMSQuery::query_print_error_msg(int print_error)
|
|||
|
||||
int HMSQuery::check_hms_info()
|
||||
{
|
||||
int result = 0;
|
||||
bool download_new_hms_info = true;
|
||||
|
||||
// load local hms json file
|
||||
std::string version = "";
|
||||
if (load_from_local(version) == 0) {
|
||||
BOOST_LOG_TRIVIAL(info) << "HMS: check_hms_info current version = " << version;
|
||||
std::string new_version;
|
||||
get_hms_info_version(new_version);
|
||||
BOOST_LOG_TRIVIAL(info) << "HMS: check_hms_info latest version = " << new_version;
|
||||
if (!version.empty() && version == new_version) {
|
||||
download_new_hms_info = false;
|
||||
boost::thread check_thread = boost::thread([this] {
|
||||
bool download_new_hms_info = true;
|
||||
// load local hms json file
|
||||
std::string version = "";
|
||||
if (load_from_local(version) == 0) {
|
||||
BOOST_LOG_TRIVIAL(info) << "HMS: check_hms_info current version = " << version;
|
||||
std::string new_version;
|
||||
get_hms_info_version(new_version);
|
||||
BOOST_LOG_TRIVIAL(info) << "HMS: check_hms_info latest version = " << new_version;
|
||||
if (!version.empty() && version == new_version) {
|
||||
download_new_hms_info = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << "HMS: check_hms_info need download new hms info = " << download_new_hms_info;
|
||||
// download if version is update
|
||||
if (download_new_hms_info) {
|
||||
result = download_hms_info();
|
||||
}
|
||||
return result;
|
||||
BOOST_LOG_TRIVIAL(info) << "HMS: check_hms_info need download new hms info = " << download_new_hms_info;
|
||||
// download if version is update
|
||||
if (download_new_hms_info) {
|
||||
download_hms_info();
|
||||
}
|
||||
return;
|
||||
});
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string get_hms_wiki_url(std::string error_code)
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ namespace {
|
|||
|
||||
void write_used_binary(const std::vector<std::string>& ids)
|
||||
{
|
||||
boost::nowide::ofstream file((boost::filesystem::path(data_dir()) / "cache" / "hints.cereal").string(), std::ios::binary);
|
||||
boost::nowide::ofstream file((boost::filesystem::path(data_dir()) / "user" / "hints.cereal").string(), std::ios::binary);
|
||||
cereal::BinaryOutputArchive archive(file);
|
||||
HintsCerealData cd{ ids };
|
||||
try
|
||||
|
|
@ -81,7 +81,7 @@ namespace {
|
|||
}
|
||||
void read_used_binary(std::vector<std::string>& ids)
|
||||
{
|
||||
boost::filesystem::path path(boost::filesystem::path(data_dir()) / "cache" / "hints.cereal");
|
||||
boost::filesystem::path path(boost::filesystem::path(data_dir()) / "user" / "hints.cereal");
|
||||
if (!boost::filesystem::exists(path)) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "Failed to load to hints.cereal. File does not exists. " << path.string();
|
||||
return;
|
||||
|
|
|
|||
151
src/slic3r/GUI/HttpServer.cpp
Normal file
151
src/slic3r/GUI/HttpServer.cpp
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
#include "HttpServer.hpp"
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include "GUI_App.hpp"
|
||||
#include "slic3r/Utils/Http.hpp"
|
||||
#include "slic3r/Utils/NetworkAgent.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
static std::string parse_params(std::string url, std::string key)
|
||||
{
|
||||
size_t start = url.find(key);
|
||||
if (start < 0) return "";
|
||||
size_t eq = url.find('=', start);
|
||||
if (eq < 0) return "";
|
||||
std::string key_str = url.substr(start, eq - start);
|
||||
if (key_str != key)
|
||||
return "";
|
||||
start += key.size() + 1;
|
||||
size_t end = url.find('&', start);
|
||||
if (end < 0)
|
||||
return "";
|
||||
std::string result = url.substr(start, end - start);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string http_headers::get_response()
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << "thirdparty_login: get_response";
|
||||
std::stringstream ssOut;
|
||||
std::string url_str = Http::url_decode(url);
|
||||
if (boost::contains(url_str, "access_token")) {
|
||||
std::string sHTML = "<html><body><p>redirect to url </p></body></html>";
|
||||
std::string redirect_url = parse_params(url_str, "redirect_url");
|
||||
std::string access_token = parse_params(url_str, "access_token");
|
||||
std::string refresh_token = parse_params(url_str, "refresh_token");
|
||||
std::string expires_in_str = parse_params(url_str, "expires_in");
|
||||
std::string refresh_expires_in_str = parse_params(url_str, "refresh_expires_in");
|
||||
NetworkAgent* agent = wxGetApp().getAgent();
|
||||
|
||||
unsigned int http_code;
|
||||
std::string http_body;
|
||||
int result = agent->get_my_profile(access_token, &http_code, &http_body);
|
||||
if (result == 0) {
|
||||
std::string user_id;
|
||||
std::string user_name;
|
||||
std::string user_account;
|
||||
std::string user_avatar;
|
||||
try {
|
||||
json user_j = json::parse(http_body);
|
||||
if (user_j.contains("uid"))
|
||||
user_id = std::to_string(user_j["uid"].get<int>());
|
||||
if (user_j.contains("name"))
|
||||
user_name = user_j["name"].get<std::string>();
|
||||
if (user_j.contains("avatar"))
|
||||
user_avatar = user_j["avatar"].get<std::string>();
|
||||
if (user_j.contains("account"))
|
||||
user_account = user_j["account"].get<std::string>();
|
||||
} catch (...) {
|
||||
;
|
||||
}
|
||||
json j;
|
||||
j["data"]["refresh_token"] = refresh_token;
|
||||
j["data"]["token"] = access_token;
|
||||
j["data"]["expires_in"] = expires_in_str;
|
||||
j["data"]["refresh_expires_in"] = refresh_expires_in_str;
|
||||
j["data"]["user"]["uid"] = user_id;
|
||||
j["data"]["user"]["name"] = user_name;
|
||||
j["data"]["user"]["account"] = user_account;
|
||||
j["data"]["user"]["avatar"] = user_avatar;
|
||||
agent->change_user(j.dump());
|
||||
if (agent->is_user_login()) {
|
||||
wxGetApp().request_user_login(1);
|
||||
}
|
||||
GUI::wxGetApp().CallAfter([this] {
|
||||
wxGetApp().ShowUserLogin(false);
|
||||
});
|
||||
std::string location_str = (boost::format("Location: %1%?result=success") % redirect_url).str();
|
||||
ssOut << "HTTP/1.1 302 Found" << std::endl;
|
||||
ssOut << location_str << std::endl;
|
||||
ssOut << "content-type: text/html" << std::endl;
|
||||
ssOut << "content-length: " << sHTML.length() << std::endl;
|
||||
ssOut << std::endl;
|
||||
ssOut << sHTML;
|
||||
} else {
|
||||
std::string error_str = "get_user_profile_error_" + std::to_string(result);
|
||||
std::string location_str = (boost::format("Location: %1%?result=fail&error=%2%") % redirect_url % error_str).str();
|
||||
ssOut << "HTTP/1.1 302 Found" << std::endl;
|
||||
ssOut << location_str << std::endl;
|
||||
ssOut << "content-type: text/html" << std::endl;
|
||||
ssOut << "content-length: " << sHTML.length() << std::endl;
|
||||
ssOut << std::endl;
|
||||
ssOut << sHTML;
|
||||
}
|
||||
} else {
|
||||
std::string sHTML = "<html><body><h1>404 Not Found</h1><p>There's nothing here.</p></body></html>";
|
||||
ssOut << "HTTP/1.1 404 Not Found" << std::endl;
|
||||
ssOut << "content-type: text/html" << std::endl;
|
||||
ssOut << "content-length: " << sHTML.length() << std::endl;
|
||||
ssOut << std::endl;
|
||||
ssOut << sHTML;
|
||||
}
|
||||
return ssOut.str();
|
||||
}
|
||||
|
||||
|
||||
void accept_and_run(boost::asio::ip::tcp::acceptor& acceptor, boost::asio::io_service& io_service)
|
||||
{
|
||||
std::shared_ptr<session> sesh = std::make_shared<session>(io_service);
|
||||
acceptor.async_accept(sesh->socket,
|
||||
[sesh, &acceptor, &io_service](const boost::beast::error_code& accept_error)
|
||||
{
|
||||
accept_and_run(acceptor, io_service);
|
||||
if (!accept_error)
|
||||
{
|
||||
session::interact(sesh);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
HttpServer::HttpServer()
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
void HttpServer::start()
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << "start_http_service...";
|
||||
start_http_server = true;
|
||||
m_http_server_thread = Slic3r::create_thread(
|
||||
[this] {
|
||||
boost::asio::io_service io_service;
|
||||
boost::asio::ip::tcp::endpoint endpoint{ boost::asio::ip::tcp::v4(), LOCALHOST_PORT};
|
||||
boost::asio::ip::tcp::acceptor acceptor { io_service, endpoint};
|
||||
acceptor.listen();
|
||||
accept_and_run(acceptor, io_service);
|
||||
while (start_http_server) {
|
||||
io_service.run();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void HttpServer::stop()
|
||||
{
|
||||
start_http_server = false;
|
||||
if (m_http_server_thread.joinable())
|
||||
m_http_server_thread.join();
|
||||
}
|
||||
|
||||
} // GUI
|
||||
} //Slic3r
|
||||
162
src/slic3r/GUI/HttpServer.hpp
Normal file
162
src/slic3r/GUI/HttpServer.hpp
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
#ifndef slic3r_Http_App_hpp_
|
||||
#define slic3r_Http_App_hpp_
|
||||
|
||||
#include <mutex>
|
||||
#include <stack>
|
||||
|
||||
#include <boost/beast/core.hpp>
|
||||
#include <boost/beast/http.hpp>
|
||||
#include <boost/beast/version.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
using namespace boost;
|
||||
using namespace boost::system;
|
||||
using namespace boost::asio;
|
||||
|
||||
#define LOCALHOST_PORT 13618
|
||||
#define LOCALHOST_URL "http://localhost:"
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
class http_headers
|
||||
{
|
||||
std::string method;
|
||||
std::string url;
|
||||
std::string version;
|
||||
|
||||
std::map<std::string, std::string> headers;
|
||||
|
||||
public:
|
||||
|
||||
std::string get_response();
|
||||
|
||||
int content_length()
|
||||
{
|
||||
auto request = headers.find("content-length");
|
||||
if (request != headers.end())
|
||||
{
|
||||
std::stringstream ssLength(request->second);
|
||||
int content_length;
|
||||
ssLength >> content_length;
|
||||
return content_length;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void on_read_header(std::string line)
|
||||
{
|
||||
//std::cout << "header: " << line << std::endl;
|
||||
|
||||
std::stringstream ssHeader(line);
|
||||
std::string headerName;
|
||||
std::getline(ssHeader, headerName, ':');
|
||||
|
||||
std::string value;
|
||||
std::getline(ssHeader, value);
|
||||
headers[headerName] = value;
|
||||
}
|
||||
|
||||
void on_read_request_line(std::string line)
|
||||
{
|
||||
std::stringstream ssRequestLine(line);
|
||||
ssRequestLine >> method;
|
||||
ssRequestLine >> url;
|
||||
ssRequestLine >> version;
|
||||
|
||||
std::cout << "request for resource: " << url << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
class session
|
||||
{
|
||||
asio::streambuf buff;
|
||||
http_headers headers;
|
||||
|
||||
static void read_body(std::shared_ptr<session> pThis)
|
||||
{
|
||||
int nbuffer = 1000;
|
||||
std::shared_ptr<std::vector<char>> bufptr = std::make_shared<std::vector<char>>(nbuffer);
|
||||
asio::async_read(pThis->socket, boost::asio::buffer(*bufptr, nbuffer), [pThis](const boost::beast::error_code& e, std::size_t s)
|
||||
{
|
||||
});
|
||||
}
|
||||
|
||||
static void read_next_line(std::shared_ptr<session> pThis)
|
||||
{
|
||||
asio::async_read_until(pThis->socket, pThis->buff, '\r', [pThis](const boost::beast::error_code& e, std::size_t s)
|
||||
{
|
||||
std::string line, ignore;
|
||||
std::istream stream{ &pThis->buff };
|
||||
std::getline(stream, line, '\r');
|
||||
std::getline(stream, ignore, '\n');
|
||||
pThis->headers.on_read_header(line);
|
||||
|
||||
if (line.length() == 0)
|
||||
{
|
||||
if (pThis->headers.content_length() == 0)
|
||||
{
|
||||
std::shared_ptr<std::string> str = std::make_shared<std::string>(pThis->headers.get_response());
|
||||
asio::async_write(pThis->socket, boost::asio::buffer(str->c_str(), str->length()), [pThis, str](const boost::beast::error_code& e, std::size_t s)
|
||||
{
|
||||
std::cout << "done" << std::endl;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
pThis->read_body(pThis);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pThis->read_next_line(pThis);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void read_first_line(std::shared_ptr<session> pThis)
|
||||
{
|
||||
asio::async_read_until(pThis->socket, pThis->buff, '\r', [pThis](const boost::beast::error_code& e, std::size_t s)
|
||||
{
|
||||
std::string line, ignore;
|
||||
std::istream stream{ &pThis->buff };
|
||||
std::getline(stream, line, '\r');
|
||||
std::getline(stream, ignore, '\n');
|
||||
pThis->headers.on_read_request_line(line);
|
||||
pThis->read_next_line(pThis);
|
||||
});
|
||||
}
|
||||
|
||||
public:
|
||||
boost::asio::ip::tcp::socket socket;
|
||||
|
||||
session(io_service& io_service)
|
||||
:socket(io_service)
|
||||
{
|
||||
}
|
||||
|
||||
static void interact(std::shared_ptr<session> pThis)
|
||||
{
|
||||
read_first_line(pThis);
|
||||
}
|
||||
};
|
||||
|
||||
class HttpServer {
|
||||
public:
|
||||
HttpServer();
|
||||
|
||||
boost::thread m_http_server_thread;
|
||||
bool start_http_server = false;
|
||||
|
||||
bool is_started() { return start_http_server; }
|
||||
void start();
|
||||
void stop();
|
||||
};
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,16 +1,9 @@
|
|||
#ifndef slic3r_GUI_IMSlider_hpp_
|
||||
#define slic3r_GUI_IMSlider_hpp_
|
||||
|
||||
#include "libslic3r/CustomGCode.hpp"
|
||||
#include "wxExtensions.hpp"
|
||||
#include "IMSlider_Utils.hpp"
|
||||
#include "TickCode.hpp"
|
||||
#include <imgui/imgui.h>
|
||||
#include <wx/window.h>
|
||||
#include <wx/control.h>
|
||||
#include <wx/dc.h>
|
||||
#include <wx/slider.h>
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
class wxMenu;
|
||||
|
|
@ -43,42 +36,6 @@ enum SelectedSlider {
|
|||
ssHigher = 2
|
||||
};
|
||||
|
||||
enum FocusedItem {
|
||||
fiNone,
|
||||
fiRevertIcon,
|
||||
fiOneLayerIcon,
|
||||
fiCogIcon,
|
||||
fiColorBand,
|
||||
fiActionIcon,
|
||||
fiLowerThumb,
|
||||
fiHigherThumb,
|
||||
fiSmartWipeTower,
|
||||
fiTick
|
||||
};
|
||||
|
||||
enum ConflictType
|
||||
{
|
||||
ctNone,
|
||||
ctModeConflict,
|
||||
ctMeaninglessColorChange,
|
||||
ctMeaninglessToolChange,
|
||||
ctRedundant
|
||||
};
|
||||
|
||||
enum MouseAction
|
||||
{
|
||||
maNone,
|
||||
maAddMenu, // show "Add" context menu for NOTexist active tick
|
||||
maEditMenu, // show "Edit" context menu for exist active tick
|
||||
maCogIconMenu, // show context for "cog" icon
|
||||
maForceColorEdit, // force color editing from colored band
|
||||
maAddTick, // force tick adding
|
||||
maDeleteTick, // force tick deleting
|
||||
maCogIconClick, // LeftMouseClick on "cog" icon
|
||||
maOneLayerIconClick, // LeftMouseClick on "one_layer" icon
|
||||
maRevertIconClick, // LeftMouseClick on "revert" icon
|
||||
};
|
||||
|
||||
enum DrawMode
|
||||
{
|
||||
dmRegular,
|
||||
|
|
@ -94,116 +51,6 @@ enum LabelType
|
|||
ltEstimatedTime,
|
||||
};
|
||||
|
||||
enum VSliderMode
|
||||
{
|
||||
Regular,
|
||||
Colored,
|
||||
};
|
||||
|
||||
struct TickCode
|
||||
{
|
||||
bool operator<(const TickCode& other) const { return other.tick > this->tick; }
|
||||
bool operator>(const TickCode& other) const { return other.tick < this->tick; }
|
||||
|
||||
int tick = 0;
|
||||
Type type = ColorChange;
|
||||
int extruder = 0;
|
||||
std::string color;
|
||||
std::string extra;
|
||||
};
|
||||
|
||||
class TickCodeInfo
|
||||
{
|
||||
std::string custom_gcode;
|
||||
std::string pause_print_msg;
|
||||
bool m_suppress_plus = false;
|
||||
bool m_suppress_minus = false;
|
||||
bool m_use_default_colors= false;
|
||||
// int m_default_color_idx = 0;
|
||||
|
||||
std::vector<std::string>* m_colors {nullptr};
|
||||
ColorGenerator color_generator;
|
||||
|
||||
std::string get_color_for_tick(TickCode tick, Type type, const int extruder);
|
||||
|
||||
public:
|
||||
std::set<TickCode> ticks {};
|
||||
Mode mode = Undef;
|
||||
|
||||
bool empty() const { return ticks.empty(); }
|
||||
void set_pause_print_msg(const std::string& message) { pause_print_msg = message; }
|
||||
|
||||
bool add_tick(const int tick, Type type, int extruder, double print_z);
|
||||
bool edit_tick(std::set<TickCode>::iterator it, double print_z);
|
||||
void switch_code(Type type_from, Type type_to);
|
||||
bool switch_code_for_tick(std::set<TickCode>::iterator it, Type type_to, const int extruder);
|
||||
void erase_all_ticks_with_code(Type type);
|
||||
|
||||
bool has_tick_with_code(Type type);
|
||||
bool has_tick(int tick);
|
||||
ConflictType is_conflict_tick(const TickCode& tick, Mode out_mode, int only_extruder, double print_z);
|
||||
|
||||
// Get used extruders for tick.
|
||||
// Means all extruders(tools) which will be used during printing from current tick to the end
|
||||
std::set<int> get_used_extruders_for_tick(int tick, int only_extruder, double print_z, Mode force_mode = Undef) const;
|
||||
|
||||
void suppress_plus (bool suppress) { m_suppress_plus = suppress; }
|
||||
void suppress_minus(bool suppress) { m_suppress_minus = suppress; }
|
||||
bool suppressed_plus () { return m_suppress_plus; }
|
||||
bool suppressed_minus() { return m_suppress_minus; }
|
||||
void set_default_colors(bool default_colors_on) { m_use_default_colors = default_colors_on; }
|
||||
|
||||
void set_extruder_colors(std::vector<std::string>* extruder_colors) { m_colors = extruder_colors; }
|
||||
};
|
||||
|
||||
|
||||
struct ExtrudersSequence
|
||||
{
|
||||
bool is_mm_intervals = true;
|
||||
double interval_by_mm = 3.0;
|
||||
int interval_by_layers = 10;
|
||||
bool random_sequence { false };
|
||||
bool color_repetition { false };
|
||||
std::vector<size_t> extruders = { 0 };
|
||||
|
||||
bool operator==(const ExtrudersSequence& other) const
|
||||
{
|
||||
return (other.is_mm_intervals == this->is_mm_intervals ) &&
|
||||
(other.interval_by_mm == this->interval_by_mm ) &&
|
||||
(other.interval_by_layers == this->interval_by_layers ) &&
|
||||
(other.random_sequence == this->random_sequence ) &&
|
||||
(other.color_repetition == this->color_repetition ) &&
|
||||
(other.extruders == this->extruders ) ;
|
||||
}
|
||||
bool operator!=(const ExtrudersSequence& other) const
|
||||
{
|
||||
return (other.is_mm_intervals != this->is_mm_intervals ) ||
|
||||
(other.interval_by_mm != this->interval_by_mm ) ||
|
||||
(other.interval_by_layers != this->interval_by_layers ) ||
|
||||
(other.random_sequence != this->random_sequence ) ||
|
||||
(other.color_repetition != this->color_repetition ) ||
|
||||
(other.extruders != this->extruders ) ;
|
||||
}
|
||||
|
||||
void add_extruder(size_t pos, size_t extruder_id = size_t(0))
|
||||
{
|
||||
extruders.insert(extruders.begin() + pos+1, extruder_id);
|
||||
}
|
||||
|
||||
void delete_extruder(size_t pos)
|
||||
{
|
||||
if (extruders.size() == 1)
|
||||
return;// last item can't be deleted
|
||||
extruders.erase(extruders.begin() + pos);
|
||||
}
|
||||
|
||||
void init(size_t extruders_count)
|
||||
{
|
||||
extruders.clear();
|
||||
for (size_t extruder = 0; extruder < extruders_count; extruder++)
|
||||
extruders.push_back(extruder);
|
||||
}
|
||||
};
|
||||
|
||||
class IMSlider
|
||||
{
|
||||
|
|
@ -262,7 +109,7 @@ public:
|
|||
void UseDefaultColors(bool def_colors_on) { m_ticks.set_default_colors(def_colors_on); }
|
||||
|
||||
void on_mouse_wheel(wxMouseEvent& evt);
|
||||
void post_ticks_changed_event(Type type = Custom);
|
||||
void post_ticks_changed_event(Type type = Unknown);
|
||||
bool check_ticks_changed_event(Type type);
|
||||
bool switch_one_layer_mode();
|
||||
void show_go_to_layer(bool show) { m_show_go_to_layer_dialog = show; }
|
||||
|
|
@ -279,7 +126,6 @@ public:
|
|||
}
|
||||
Type get_post_tick_event_type() { return m_tick_change_event_type; }
|
||||
|
||||
ExtrudersSequence m_extruders_sequence;
|
||||
float m_scale = 1.0;
|
||||
void set_scale(float scale = 1.0);
|
||||
void on_change_color_mode(bool is_dark);
|
||||
|
|
@ -290,16 +136,16 @@ protected:
|
|||
void do_go_to_layer(size_t layer_number);
|
||||
void correct_lower_value();
|
||||
void correct_higher_value();
|
||||
bool horizontal_slider(const char* str_id, int* v, int v_min, int v_max, const ImVec2& pos, const ImVec2& size, float scale = 1.0);
|
||||
bool horizontal_slider(const char* str_id, int* v, int v_min, int v_max, const ImVec2& size, float scale = 1.0);
|
||||
void render_go_to_layer_dialog();
|
||||
void render_input_custom_gcode();
|
||||
void render_menu();
|
||||
void draw_background(const ImRect& groove);
|
||||
void draw_background_and_groove(const ImRect& bg_rect, const ImRect& groove);
|
||||
void draw_colored_band(const ImRect& groove, const ImRect& slideable_region);
|
||||
void draw_ticks(const ImRect& slideable_region);
|
||||
bool vertical_slider(const char* str_id, int* higher_value, int* lower_value,
|
||||
std::string& higher_label, std::string& lower_label,
|
||||
int v_min, int v_max, const ImVec2& pos, const ImVec2& size,
|
||||
int v_min, int v_max, const ImVec2& size,
|
||||
SelectedSlider& selection, bool one_layer_flag = false, float scale = 1.0f);
|
||||
bool is_wipe_tower_layer(int tick) const;
|
||||
|
||||
|
|
@ -340,6 +186,7 @@ private:
|
|||
bool m_enable_action_icon = true;
|
||||
bool m_enable_cog_icon = false;
|
||||
bool m_is_wipe_tower = false; // This flag indicates that there is multiple extruder print with wipe tower
|
||||
bool m_is_spiral_vase = false;
|
||||
bool m_display_lower = true;
|
||||
bool m_display_higher = true;
|
||||
int m_selected_tick_value = -1;
|
||||
|
|
@ -362,7 +209,6 @@ private:
|
|||
|
||||
DrawMode m_draw_mode = dmRegular;
|
||||
Mode m_mode = SingleExtruder;
|
||||
VSliderMode m_vslider_mode = Regular;
|
||||
int m_only_extruder = -1;
|
||||
|
||||
long m_style;
|
||||
|
|
|
|||
|
|
@ -52,6 +52,11 @@ void IMToolbar::del_all_item()
|
|||
m_items.clear();
|
||||
}
|
||||
|
||||
void IMToolbar::del_stats_item()
|
||||
{
|
||||
delete m_all_plates_stats_item;
|
||||
m_all_plates_stats_item = nullptr;
|
||||
}
|
||||
|
||||
bool IMReturnToolbar::init()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -27,10 +27,11 @@ public:
|
|||
|
||||
bool selected{ false };
|
||||
float percent;
|
||||
ImTextureID texture_id { 0 };
|
||||
GLTexture image_texture;
|
||||
GLTexture image_texture_transparent;
|
||||
SliceState slice_state;
|
||||
|
||||
ImTextureID texture_id { 0 };
|
||||
std::vector<unsigned char> image_data;
|
||||
unsigned int image_width;
|
||||
unsigned int image_height;
|
||||
|
|
@ -47,6 +48,7 @@ public:
|
|||
float icon_width;
|
||||
float icon_height;
|
||||
bool is_display_scrollbar;
|
||||
bool show_stats_item{ false };
|
||||
|
||||
IMToolbar() {
|
||||
icon_width = DEFAULT_TOOLBAR_BUTTON_WIDTH;
|
||||
|
|
@ -54,7 +56,9 @@ public:
|
|||
}
|
||||
|
||||
void del_all_item();
|
||||
void del_stats_item();
|
||||
|
||||
IMToolbarItem* m_all_plates_stats_item = nullptr;
|
||||
std::vector<IMToolbarItem*> m_items;
|
||||
float fontScale;
|
||||
|
||||
|
|
|
|||
|
|
@ -82,6 +82,8 @@ static const std::map<const wchar_t, std::string> font_icons = {
|
|||
{ImGui::GapFillDarkIcon , "gap_fill_dark" },
|
||||
{ImGui::SphereButtonDarkIcon , "toolbar_modifier_sphere_dark" },
|
||||
|
||||
{ImGui::TextSearchIcon , "im_text_search" },
|
||||
{ImGui::TextSearchCloseIcon , "im_text_search_close" },
|
||||
};
|
||||
static const std::map<const wchar_t, std::string> font_icons_large = {
|
||||
{ImGui::CloseNotifButton , "notification_close" },
|
||||
|
|
@ -542,6 +544,123 @@ void ImGuiWrapper::set_next_window_size(float x, float y, ImGuiCond cond)
|
|||
}
|
||||
|
||||
/* BBL style widgets */
|
||||
bool ImGuiWrapper::bbl_combo_with_filter(const char* label, const std::string& preview_value, const std::vector<std::string>& all_items, std::vector<int>* filtered_items_idx, bool* is_filtered, float item_height)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
|
||||
static char pattern_buffer[256] = { 0 };
|
||||
auto simple_match = [](const char* pattern, const char* str) {
|
||||
wxString sub_str = wxString(pattern).Lower();
|
||||
wxString main_str = wxString(str).Lower();
|
||||
return main_str.Find(sub_str);
|
||||
};
|
||||
|
||||
bool is_filtering = false;
|
||||
bool is_new_open = false;
|
||||
|
||||
float sz = ImGui::GetFrameHeight();
|
||||
ImVec2 arrow_size(sz, sz);
|
||||
ImVec2 CursorPos = window->DC.CursorPos;
|
||||
const ImRect arrow_bb(CursorPos, CursorPos + arrow_size);
|
||||
|
||||
float ButtonTextAlignX = g.Style.ButtonTextAlign.x;
|
||||
g.Style.ButtonTextAlign.x = 0;
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, { sz, style.FramePadding.y});
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered));
|
||||
if (button(preview_value + label, ImGui::CalcItemWidth(), 0))
|
||||
{
|
||||
ImGui::OpenPopup(label);
|
||||
is_new_open = true;
|
||||
}
|
||||
g.Style.ButtonTextAlign.x = ButtonTextAlignX;
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::BBLRenderArrow(window->DrawList, arrow_bb.Min + ImVec2(ImMax(0.0f, (arrow_size.x - g.FontSize) * 0.5f), ImMax(0.0f, (arrow_size.y - g.FontSize) * 0.5f)), ImGui::GetColorU32(ImGuiCol_Text), ImGuiDir_Down);
|
||||
|
||||
if (is_new_open)
|
||||
memset(pattern_buffer, 0, IM_ARRAYSIZE(pattern_buffer));
|
||||
|
||||
float item_rect_width = ImGui::GetItemRectSize().x;
|
||||
float item_rect_height = item_height ? item_height : ImGui::GetItemRectSize().y;
|
||||
ImGui::SetNextWindowPos({ CursorPos.x, ImGui::GetItemRectMax().y + 4 * m_style_scaling });
|
||||
ImGui::SetNextWindowSize({ item_rect_width, 0 });
|
||||
if (ImGui::BeginPopup(label))
|
||||
{
|
||||
ImGuiWindow* popup_window = ImGui::GetCurrentWindow();
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(8.0f * m_style_scaling, item_rect_height - g.FontSize) * 0.5f);
|
||||
wchar_t ICON_SEARCH = *pattern_buffer != '\0' ? ImGui::TextSearchCloseIcon : ImGui::TextSearchIcon;
|
||||
const ImVec2 label_size = ImGui::CalcTextSize(into_u8(ICON_SEARCH).c_str(), nullptr, true);
|
||||
const ImVec2 search_icon_pos(ImGui::GetItemRectMax().x - label_size.x, popup_window->DC.CursorPos.y + style.FramePadding.y);
|
||||
ImGui::RenderText(search_icon_pos, into_u8(ICON_SEARCH).c_str());
|
||||
|
||||
auto temp = popup_window->DC.CursorPos;
|
||||
popup_window->DC.CursorPos = search_icon_pos;
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, {0, 0, 0, 0});
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGui::GetStyleColorVec4(ImGuiCol_Button));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::GetStyleColorVec4(ImGuiCol_Button));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::GetStyleColorVec4(ImGuiCol_Button));
|
||||
ImGui::PushStyleColor(ImGuiCol_Border, { 0, 0, 0, 0 });
|
||||
if (button("##invisible_clear_button", label_size.x, label_size.y))
|
||||
{
|
||||
if (*pattern_buffer != '\0')
|
||||
memset(pattern_buffer, 0, IM_ARRAYSIZE(pattern_buffer));
|
||||
}
|
||||
ImGui::PopStyleColor(5);
|
||||
popup_window->DC.CursorPos = temp;
|
||||
|
||||
|
||||
ImGui::PushItemWidth(item_rect_width);
|
||||
if (is_new_open)
|
||||
ImGui::SetKeyboardFocusHere();
|
||||
ImGui::InputText("##bbl_combo_with_filter_inputText", pattern_buffer, sizeof(pattern_buffer));
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
if (*pattern_buffer != '\0')
|
||||
is_filtering = true;
|
||||
|
||||
if (is_filtering)
|
||||
{
|
||||
std::vector<std::pair<int, int> > filtered_items_with_priority;// std::pair<index, priority>
|
||||
for (int i = 0; i < all_items.size(); i++)
|
||||
{
|
||||
int priority = simple_match(pattern_buffer, all_items[i].c_str());
|
||||
if (priority != wxNOT_FOUND)
|
||||
filtered_items_with_priority.push_back({ i, priority });
|
||||
}
|
||||
std::sort(filtered_items_with_priority.begin(), filtered_items_with_priority.end(), [](const std::pair<int, int>& a, const std::pair<int, int>& b) {return (b.second > a.second); });
|
||||
for (auto item : filtered_items_with_priority)
|
||||
{
|
||||
filtered_items_idx->push_back(item.first);
|
||||
}
|
||||
}
|
||||
|
||||
*is_filtered = is_filtering;
|
||||
|
||||
popup_window->DC.CursorPos.y -= 1 * m_style_scaling;
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(1.0f, 1.0f) * m_style_scaling);
|
||||
if (ImGui::BeginListBox("##bbl_combo_with_filter_listBox", { item_rect_width, item_rect_height * 7.75f})) {
|
||||
ImGui::PopStyleVar(2);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::PopStyleVar(2);
|
||||
ImGui::EndPopup();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ImGuiWrapper::bbl_input_double(const wxString& label, const double& value, const std::string& format)
|
||||
{
|
||||
//return ImGui::InputDouble(label.c_str(), const_cast<double *>(&value), 0.0f, 0.0f, format.c_str(), ImGuiInputTextFlags_CharsDecimal);
|
||||
|
|
@ -1636,7 +1755,7 @@ static const ImWchar ranges_keyboard_shortcuts[] =
|
|||
#endif // __APPLE__
|
||||
|
||||
|
||||
std::vector<unsigned char> ImGuiWrapper::load_svg(const std::string& bitmap_name, unsigned target_width, unsigned target_height)
|
||||
std::vector<unsigned char> ImGuiWrapper::load_svg(const std::string& bitmap_name, unsigned target_width, unsigned target_height, unsigned *outwidth, unsigned *outheight)
|
||||
{
|
||||
std::vector<unsigned char> empty_vector;
|
||||
|
||||
|
|
@ -1667,6 +1786,9 @@ std::vector<unsigned char> ImGuiWrapper::load_svg(const std::string& bitmap_name
|
|||
::nsvgDeleteRasterizer(rast);
|
||||
::nsvgDelete(image);
|
||||
|
||||
*outwidth = width;
|
||||
*outheight = height;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
|
@ -1951,11 +2073,12 @@ void ImGuiWrapper::init_font(bool compress)
|
|||
if (const ImFontAtlas::CustomRect* rect = io.Fonts->GetCustomRectByIndex(rect_id)) {
|
||||
assert(rect->Width == icon_sz);
|
||||
assert(rect->Height == icon_sz);
|
||||
std::vector<unsigned char> raw_data = load_svg(icon.second, icon_sz, icon_sz);
|
||||
unsigned outwidth, outheight;
|
||||
std::vector<unsigned char> raw_data = load_svg(icon.second, icon_sz, icon_sz, &outwidth, &outheight);
|
||||
const ImU32* pIn = (ImU32*)raw_data.data();
|
||||
for (int y = 0; y < icon_sz; y++) {
|
||||
for (unsigned y = 0; y < outheight; y++) {
|
||||
ImU32* pOut = (ImU32*)pixels + (rect->Y + y) * width + (rect->X);
|
||||
for (int x = 0; x < icon_sz; x++)
|
||||
for (unsigned x = 0; x < outwidth; x++)
|
||||
*pOut++ = *pIn++;
|
||||
}
|
||||
}
|
||||
|
|
@ -1967,11 +2090,12 @@ void ImGuiWrapper::init_font(bool compress)
|
|||
if (const ImFontAtlas::CustomRect* rect = io.Fonts->GetCustomRectByIndex(rect_id)) {
|
||||
assert(rect->Width == icon_sz);
|
||||
assert(rect->Height == icon_sz);
|
||||
std::vector<unsigned char> raw_data = load_svg(icon.second, icon_sz, icon_sz);
|
||||
unsigned outwidth, outheight;
|
||||
std::vector<unsigned char> raw_data = load_svg(icon.second, icon_sz, icon_sz, &outwidth, &outheight);
|
||||
const ImU32* pIn = (ImU32*)raw_data.data();
|
||||
for (int y = 0; y < icon_sz; y++) {
|
||||
for (unsigned y = 0; y < outheight; y++) {
|
||||
ImU32* pOut = (ImU32*)pixels + (rect->Y + y) * width + (rect->X);
|
||||
for (int x = 0; x < icon_sz; x++)
|
||||
for (unsigned x = 0; x < outwidth; x++)
|
||||
*pOut++ = *pIn++;
|
||||
}
|
||||
}
|
||||
|
|
@ -1983,11 +2107,12 @@ void ImGuiWrapper::init_font(bool compress)
|
|||
if (const ImFontAtlas::CustomRect* rect = io.Fonts->GetCustomRectByIndex(rect_id)) {
|
||||
assert(rect->Width == icon_sz);
|
||||
assert(rect->Height == icon_sz);
|
||||
std::vector<unsigned char> raw_data = load_svg(icon.second, icon_sz, icon_sz);
|
||||
unsigned outwidth, outheight;
|
||||
std::vector<unsigned char> raw_data = load_svg(icon.second, icon_sz, icon_sz, &outwidth, &outheight);
|
||||
const ImU32* pIn = (ImU32*)raw_data.data();
|
||||
for (int y = 0; y < icon_sz; y++) {
|
||||
for (unsigned y = 0; y < outheight; y++) {
|
||||
ImU32* pOut = (ImU32*)pixels + (rect->Y + y) * width + (rect->X);
|
||||
for (int x = 0; x < icon_sz; x++)
|
||||
for (unsigned x = 0; x < outwidth; x++)
|
||||
*pOut++ = *pIn++;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ public:
|
|||
void set_next_window_size(float x, float y, ImGuiCond cond);
|
||||
|
||||
/* BBL style widgets */
|
||||
bool bbl_combo_with_filter(const char* label, const std::string& preview_value, const std::vector<std::string>& all_items, std::vector<int>* filtered_items_idx, bool* is_filtered, float item_height = 0.0f);
|
||||
bool bbl_input_double(const wxString &label, const double &value, const std::string &format = "%0.2f");
|
||||
bool bbl_slider_float(const std::string &label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f, bool clamp = true, const wxString& tooltip = {});
|
||||
bool bbl_slider_float_style(const std::string &label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f, bool clamp = true, const wxString& tooltip = {});
|
||||
|
|
@ -223,7 +224,7 @@ private:
|
|||
void render_draw_data(ImDrawData *draw_data);
|
||||
bool display_initialized() const;
|
||||
void destroy_font();
|
||||
std::vector<unsigned char> load_svg(const std::string& bitmap_name, unsigned target_width, unsigned target_height);
|
||||
std::vector<unsigned char> load_svg(const std::string& bitmap_name, unsigned target_width, unsigned target_height, unsigned *outwidth, unsigned *outheight);
|
||||
|
||||
static const char* clipboard_get(void* user_data);
|
||||
static void clipboard_set(void* user_data, const char* text);
|
||||
|
|
|
|||
|
|
@ -335,6 +335,7 @@ void ArrangeJob::prepare_partplate() {
|
|||
return;
|
||||
}
|
||||
|
||||
params.is_seq_print = plate->get_real_print_seq() == PrintSequence::ByObject;
|
||||
Model& model = m_plater->model();
|
||||
|
||||
// Go through the objects and check if inside the selection
|
||||
|
|
|
|||
|
|
@ -34,6 +34,12 @@ PrintJob::PrintJob(std::shared_ptr<ProgressIndicator> pri, Plater* plater, std::
|
|||
void PrintJob::prepare()
|
||||
{
|
||||
m_plater->get_print_job_data(&job_data);
|
||||
if (&job_data) {
|
||||
std::string temp_file = Slic3r::resources_dir() + "/check_access_code.txt";
|
||||
auto check_access_code_path = temp_file.c_str();
|
||||
BOOST_LOG_TRIVIAL(trace) << "sned_job: check_access_code_path = " << check_access_code_path;
|
||||
job_data._temp_path = fs::path(check_access_code_path);
|
||||
}
|
||||
}
|
||||
|
||||
void PrintJob::on_exception(const std::exception_ptr &eptr)
|
||||
|
|
@ -53,53 +59,60 @@ void PrintJob::on_success(std::function<void()> success)
|
|||
|
||||
wxString PrintJob::get_http_error_msg(unsigned int status, std::string body)
|
||||
{
|
||||
int code = 0;
|
||||
std::string error;
|
||||
std::string message;
|
||||
wxString result;
|
||||
if (status >= 400 && status < 500)
|
||||
try {
|
||||
json j = json::parse(body);
|
||||
if (j.contains("code")) {
|
||||
if (!j["code"].is_null())
|
||||
code = j["code"].get<int>();
|
||||
try {
|
||||
int code = 0;
|
||||
std::string error;
|
||||
std::string message;
|
||||
wxString result;
|
||||
if (status >= 400 && status < 500)
|
||||
try {
|
||||
json j = json::parse(body);
|
||||
if (j.contains("code")) {
|
||||
if (!j["code"].is_null())
|
||||
code = j["code"].get<int>();
|
||||
}
|
||||
if (j.contains("error")) {
|
||||
if (!j["error"].is_null())
|
||||
error = j["error"].get<std::string>();
|
||||
}
|
||||
if (j.contains("message")) {
|
||||
if (!j["message"].is_null())
|
||||
message = j["message"].get<std::string>();
|
||||
}
|
||||
switch (status) {
|
||||
;
|
||||
}
|
||||
}
|
||||
if (j.contains("error")) {
|
||||
if (!j["error"].is_null())
|
||||
error = j["error"].get<std::string>();
|
||||
}
|
||||
if (j.contains("message")) {
|
||||
if (!j["message"].is_null())
|
||||
message = j["message"].get<std::string>();
|
||||
}
|
||||
switch (status) {
|
||||
catch (...) {
|
||||
;
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
else if (status == 503) {
|
||||
return _L("Service Unavailable");
|
||||
}
|
||||
else {
|
||||
wxString unkown_text = _L("Unkown Error.");
|
||||
unkown_text += wxString::Format("status=%u, body=%s", status, body);
|
||||
BOOST_LOG_TRIVIAL(error) << "http_error: status=" << status << ", code=" << code << ", error=" << error;
|
||||
return unkown_text;
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(error) << "http_error: status=" << status << ", code=" << code << ", error=" << error;
|
||||
|
||||
result = wxString::Format("code=%u, error=%s", code, from_u8(error));
|
||||
return result;
|
||||
} catch(...) {
|
||||
;
|
||||
}
|
||||
else if (status == 503) {
|
||||
return _L("Service Unavailable");
|
||||
}
|
||||
else {
|
||||
wxString unkown_text = _L("Unkown Error.");
|
||||
unkown_text += wxString::Format("status=%u, body=%s", status, body);
|
||||
BOOST_LOG_TRIVIAL(error) << "http_error: status=" << status << ", code=" << code << ", error=" << error;
|
||||
return unkown_text;
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(error) << "http_error: status=" << status << ", code=" << code << ", error=" << error;
|
||||
|
||||
result = wxString::Format("code=%u, error=%s", code, from_u8(error));
|
||||
return result;
|
||||
}
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
void PrintJob::process()
|
||||
{
|
||||
/* display info */
|
||||
wxString msg;
|
||||
int curr_percent = 10;
|
||||
NetworkAgent* m_agent = wxGetApp().getAgent();
|
||||
AppConfig* config = wxGetApp().app_config;
|
||||
|
||||
if (this->connection_type == "lan") {
|
||||
msg = _L("Sending print job over LAN");
|
||||
|
|
@ -144,8 +157,34 @@ void PrintJob::process()
|
|||
else
|
||||
curr_plate_idx = m_plater->get_partplate_list().get_curr_plate_index() + 1;
|
||||
|
||||
|
||||
BBL::PrintParams params;
|
||||
|
||||
// local print access
|
||||
params.dev_ip = m_dev_ip;
|
||||
params.use_ssl = m_local_use_ssl;
|
||||
params.username = "bblp";
|
||||
params.password = m_access_code;
|
||||
|
||||
|
||||
// check access code and ip address
|
||||
if (this->connection_type == "lan") {
|
||||
params.dev_id = m_dev_id;
|
||||
params.project_name = "verify_job";
|
||||
params.filename = job_data._temp_path.string();
|
||||
params.connection_type = this->connection_type;
|
||||
|
||||
result = m_agent->start_send_gcode_to_sdcard(params, nullptr, nullptr);
|
||||
if (result != 0) {
|
||||
BOOST_LOG_TRIVIAL(error) << "access code is invalid";
|
||||
m_enter_ip_address_fun_fail();
|
||||
m_job_finished = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
params.dev_id = m_dev_id;
|
||||
params.ftp_folder = m_ftp_folder;
|
||||
//params.project_name = project_name;
|
||||
params.project_name = m_project_name;
|
||||
params.preset_name = wxGetApp().preset_bundle->prints.get_selected_preset_name();
|
||||
|
|
@ -161,12 +200,24 @@ void PrintJob::process()
|
|||
params.ams_mapping_info = this->task_ams_mapping_info;
|
||||
params.connection_type = this->connection_type;
|
||||
params.task_use_ams = this->task_use_ams;
|
||||
if (wxGetApp().model().model_info && wxGetApp().model().model_info.get()) {
|
||||
ModelInfo* model_info = wxGetApp().model().model_info.get();
|
||||
auto origin_profile_id = model_info->metadata_items.find(BBL_DESIGNER_PROFILE_ID_TAG);
|
||||
if (origin_profile_id != model_info->metadata_items.end()) {
|
||||
try {
|
||||
params.origin_profile_id = stoi(origin_profile_id->second.c_str());
|
||||
}
|
||||
catch(...) {}
|
||||
}
|
||||
auto origin_model_id = model_info->metadata_items.find(BBL_DESIGNER_MODEL_ID_TAG);
|
||||
if (origin_model_id != model_info->metadata_items.end()) {
|
||||
try {
|
||||
params.origin_model_id = origin_model_id->second;
|
||||
}
|
||||
catch(...) {}
|
||||
}
|
||||
}
|
||||
|
||||
// local print access
|
||||
params.dev_ip = m_dev_ip;
|
||||
params.use_ssl = m_local_use_ssl;
|
||||
params.username = "bblp";
|
||||
params.password = m_access_code;
|
||||
wxString error_text;
|
||||
wxString msg_text;
|
||||
|
||||
|
|
@ -247,9 +298,6 @@ void PrintJob::process()
|
|||
return was_canceled();
|
||||
};
|
||||
|
||||
|
||||
NetworkAgent* m_agent = wxGetApp().getAgent();
|
||||
|
||||
if (params.connection_type != "lan") {
|
||||
if (params.dev_ip.empty())
|
||||
params.comments = "no_ip";
|
||||
|
|
@ -260,32 +308,56 @@ void PrintJob::process()
|
|||
else if (params.password.empty())
|
||||
params.comments = "no_password";
|
||||
|
||||
if (!this->cloud_print_only
|
||||
&& !params.password.empty()
|
||||
&& !params.dev_ip.empty()
|
||||
&& this->has_sdcard) {
|
||||
// try to send local with record
|
||||
BOOST_LOG_TRIVIAL(info) << "print_job: try to start local print with record";
|
||||
this->update_status(curr_percent, _L("Sending print job over LAN"));
|
||||
result = m_agent->start_local_print_with_record(params, update_fn, cancel_fn);
|
||||
if (result == BAMBU_NETWORK_ERR_FTP_LOGIN_DENIED) {
|
||||
params.comments = "wrong_code";
|
||||
} else if (result == BAMBU_NETWORK_ERR_FTP_UPLOAD_FAILED) {
|
||||
params.comments = "upload_failed";
|
||||
} else {
|
||||
params.comments = (boost::format("failed(%1%)") % result).str();
|
||||
|
||||
//use ftp only
|
||||
if (!wxGetApp().app_config->get("lan_mode_only").empty() && wxGetApp().app_config->get("lan_mode_only") == "1") {
|
||||
|
||||
if (params.password.empty() || params.dev_ip.empty()) {
|
||||
error_text = wxString::Format("Access code:%s Ip address:%s", params.password, params.dev_ip);
|
||||
result = BAMBU_NETWORK_ERR_FTP_UPLOAD_FAILED;
|
||||
}
|
||||
if (result < 0) {
|
||||
// try to send with cloud
|
||||
BOOST_LOG_TRIVIAL(warning) << "print_job: try to send with cloud";
|
||||
else {
|
||||
BOOST_LOG_TRIVIAL(info) << "print_job: use ftp send print only";
|
||||
this->update_status(curr_percent, _L("Sending print job over LAN"));
|
||||
result = m_agent->start_local_print_with_record(params, update_fn, cancel_fn);
|
||||
if (result < 0) {
|
||||
error_text = wxString::Format("Access code:%s Ip address:%s", params.password, params.dev_ip);
|
||||
// try to send with cloud
|
||||
BOOST_LOG_TRIVIAL(warning) << "print_job: use ftp send print failed";
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!this->cloud_print_only
|
||||
&& !params.password.empty()
|
||||
&& !params.dev_ip.empty()
|
||||
&& this->has_sdcard) {
|
||||
// try to send local with record
|
||||
BOOST_LOG_TRIVIAL(info) << "print_job: try to start local print with record";
|
||||
this->update_status(curr_percent, _L("Sending print job over LAN"));
|
||||
result = m_agent->start_local_print_with_record(params, update_fn, cancel_fn);
|
||||
if (result == BAMBU_NETWORK_ERR_FTP_LOGIN_DENIED) {
|
||||
params.comments = "wrong_code";
|
||||
}
|
||||
else if (result == BAMBU_NETWORK_ERR_FTP_UPLOAD_FAILED) {
|
||||
params.comments = "upload_failed";
|
||||
}
|
||||
else {
|
||||
params.comments = (boost::format("failed(%1%)") % result).str();
|
||||
}
|
||||
if (result < 0) {
|
||||
// try to send with cloud
|
||||
BOOST_LOG_TRIVIAL(warning) << "print_job: try to send with cloud";
|
||||
this->update_status(curr_percent, _L("Sending print job through cloud service"));
|
||||
result = m_agent->start_print(params, update_fn, cancel_fn);
|
||||
}
|
||||
}
|
||||
else {
|
||||
BOOST_LOG_TRIVIAL(info) << "print_job: send with cloud";
|
||||
this->update_status(curr_percent, _L("Sending print job through cloud service"));
|
||||
result = m_agent->start_print(params, update_fn, cancel_fn);
|
||||
}
|
||||
} else {
|
||||
BOOST_LOG_TRIVIAL(info) << "print_job: send with cloud";
|
||||
this->update_status(curr_percent, _L("Sending print job through cloud service"));
|
||||
result = m_agent->start_print(params, update_fn, cancel_fn);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (this->has_sdcard) {
|
||||
this->update_status(curr_percent, _L("Sending print job over LAN"));
|
||||
|
|
@ -344,4 +416,14 @@ void PrintJob::set_project_name(std::string name)
|
|||
m_project_name = name;
|
||||
}
|
||||
|
||||
void PrintJob::on_check_ip_address_fail(std::function<void()> func)
|
||||
{
|
||||
m_enter_ip_address_fun_fail = func;
|
||||
}
|
||||
|
||||
void PrintJob::on_check_ip_address_success(std::function<void()> func)
|
||||
{
|
||||
m_enter_ip_address_fun_success = func;
|
||||
}
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ class PrintJob : public PlaterJob
|
|||
std::string m_dev_id;
|
||||
bool m_job_finished{ false };
|
||||
int m_print_job_completed_id = 0;
|
||||
std::function<void()> m_enter_ip_address_fun_fail{ nullptr };
|
||||
std::function<void()> m_enter_ip_address_fun_success{ nullptr };
|
||||
|
||||
protected:
|
||||
|
||||
|
|
@ -40,6 +42,7 @@ public:
|
|||
|
||||
std::string m_project_name;
|
||||
std::string m_dev_ip;
|
||||
std::string m_ftp_folder;
|
||||
bool m_local_use_ssl { true };
|
||||
std::string m_access_code;
|
||||
std::string task_bed_type;
|
||||
|
|
@ -78,6 +81,8 @@ public:
|
|||
void process() override;
|
||||
void finalize() override;
|
||||
void set_project_name(std::string name);
|
||||
void on_check_ip_address_fail(std::function<void()> func);
|
||||
void on_check_ip_address_success(std::function<void()> func);
|
||||
};
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ static wxString file_over_size_str = _L("The print file exceeds the max
|
|||
static wxString print_canceled_str = _L("Task canceled");
|
||||
static wxString upload_failed_str = _L("Failed uploading print file");
|
||||
static wxString upload_login_failed_str = _L("Wrong Access code");
|
||||
static wxString upload_no_space_left_str = _L("No space left on Printer SD card");
|
||||
|
||||
|
||||
static wxString sending_over_lan_str = _L("Sending gcode file over LAN");
|
||||
|
|
@ -39,7 +40,6 @@ void SendJob::prepare()
|
|||
BOOST_LOG_TRIVIAL(trace) << "sned_job: check_access_code_path = " << check_access_code_path;
|
||||
job_data._temp_path = fs::path(check_access_code_path);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SendJob::on_exception(const std::exception_ptr &eptr)
|
||||
|
|
@ -130,31 +130,33 @@ void SendJob::process()
|
|||
params.use_ssl = m_local_use_ssl;
|
||||
|
||||
// check access code and ip address
|
||||
if (m_is_check_mode) {
|
||||
params.dev_id = m_dev_id;
|
||||
params.project_name = "verify_job";
|
||||
params.filename = job_data._temp_path.string();
|
||||
params.connection_type = this->connection_type;
|
||||
params.dev_id = m_dev_id;
|
||||
params.project_name = "verify_job";
|
||||
params.filename = job_data._temp_path.string();
|
||||
params.connection_type = this->connection_type;
|
||||
|
||||
result = m_agent->start_send_gcode_to_sdcard(params, nullptr, nullptr);
|
||||
if (result != 0) {
|
||||
BOOST_LOG_TRIVIAL(error) << "access code is invalid";
|
||||
m_enter_ip_address_fun_fail();
|
||||
}
|
||||
else {
|
||||
m_enter_ip_address_fun_success();
|
||||
}
|
||||
result = m_agent->start_send_gcode_to_sdcard(params, nullptr, nullptr);
|
||||
if (result != 0) {
|
||||
BOOST_LOG_TRIVIAL(error) << "access code is invalid";
|
||||
m_enter_ip_address_fun_fail();
|
||||
m_job_finished = true;
|
||||
return;
|
||||
}
|
||||
/* display info */
|
||||
else if(m_is_check_mode && !m_check_and_continue){
|
||||
m_enter_ip_address_fun_success();
|
||||
m_job_finished = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (this->connection_type == "lan") {
|
||||
/* display info */
|
||||
msg = _L("Sending gcode file over LAN");
|
||||
/* if (this->connection_type == "lan") {
|
||||
msg = _L("Sending gcode file over LAN");
|
||||
}
|
||||
else {
|
||||
msg = _L("Sending gcode file through cloud service");
|
||||
}
|
||||
}*/
|
||||
|
||||
int total_plate_num = m_plater->get_partplate_list().get_plate_count();
|
||||
|
||||
|
|
@ -313,9 +315,11 @@ void SendJob::process()
|
|||
}
|
||||
|
||||
if (result < 0) {
|
||||
if (result == BAMBU_NETWORK_ERR_FTP_LOGIN_DENIED) {
|
||||
if (result == BAMBU_NETWORK_ERR_NO_SPACE_LEFT_ON_DEVICE) {
|
||||
msg_text = upload_no_space_left_str;
|
||||
} else if (result == BAMBU_NETWORK_ERR_FTP_LOGIN_DENIED) {
|
||||
msg_text = upload_login_failed_str;
|
||||
} if (result == BAMBU_NETWORK_ERR_FILE_NOT_EXIST) {
|
||||
} else if (result == BAMBU_NETWORK_ERR_FILE_NOT_EXIST) {
|
||||
msg_text = file_is_not_exists_str;
|
||||
} else if (result == BAMBU_NETWORK_ERR_FILE_OVER_SIZE) {
|
||||
msg_text = file_over_size_str;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ class SendJob : public PlaterJob
|
|||
bool m_job_finished{ false };
|
||||
int m_print_job_completed_id = 0;
|
||||
bool m_is_check_mode{false};
|
||||
bool m_check_and_continue{false};
|
||||
std::function<void()> m_success_fun{nullptr};
|
||||
std::function<void()> m_enter_ip_address_fun_fail{nullptr};
|
||||
std::function<void()> m_enter_ip_address_fun_success{nullptr};
|
||||
|
|
@ -54,6 +55,7 @@ public:
|
|||
|
||||
wxString get_http_error_msg(unsigned int status, std::string body);
|
||||
void set_check_mode() {m_is_check_mode = true;};
|
||||
void check_and_continue() {m_check_and_continue = true;};
|
||||
bool is_finished() { return m_job_finished; }
|
||||
void process() override;
|
||||
void on_success(std::function<void()> success);
|
||||
|
|
|
|||
|
|
@ -177,7 +177,13 @@ void KBShortcutsDialog::fill_shortcuts()
|
|||
{ ctrl + "S", L("Save Project") },
|
||||
{ ctrl + alt + "S", L("Save Project as") },
|
||||
// File>Import
|
||||
{ ctrl + "I", L("Import geometry data from STL/STEP/3MF/OBJ/AMF files.") },
|
||||
{ ctrl + "I", L("Import geometry data from STL/STEP/3MF/OBJ/AMF files") },
|
||||
// File>Export
|
||||
{ ctrl + "G", L("Export plate sliced file")},
|
||||
// Slice plate
|
||||
{ ctrl + "R", L("Slice plate")},
|
||||
// Send to Print
|
||||
{ ctrl + "Shift" + "G", L("Print plate")},
|
||||
// Edit
|
||||
{ ctrl + "X", L("Cut") },
|
||||
{ ctrl + "C", L("Copy to clipboard") },
|
||||
|
|
|
|||
|
|
@ -72,9 +72,15 @@ namespace GUI {
|
|||
wxDEFINE_EVENT(EVT_SELECT_TAB, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_HTTP_ERROR, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_USER_LOGIN, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_USER_LOGIN_HANDLE, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_CHECK_PRIVACY_VER, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_CHECK_PRIVACY_SHOW, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_SHOW_IP_DIALOG, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_SET_SELECTED_MACHINE, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_UPDATE_PRESET_CB, SimpleEvent);
|
||||
|
||||
|
||||
|
||||
// BBS: backup
|
||||
wxDEFINE_EVENT(EVT_BACKUP_POST, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_LOAD_URL, wxCommandEvent);
|
||||
|
|
@ -522,7 +528,19 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_
|
|||
}
|
||||
return;}
|
||||
#endif
|
||||
if (evt.CmdDown() && evt.GetKeyCode() == 'J') { m_printhost_queue_dlg->Show(); return; }
|
||||
if (evt.CmdDown() && evt.GetKeyCode() == 'R') { if (m_slice_enable) { wxPostEvent(m_plater, SimpleEvent(EVT_GLTOOLBAR_SLICE_PLATE)); this->m_tabpanel->SetSelection(tpPreview); } return; }
|
||||
if (evt.CmdDown() && evt.ShiftDown() && evt.GetKeyCode() == 'G') {
|
||||
m_plater->apply_background_progress();
|
||||
m_print_enable = get_enable_print_status();
|
||||
m_print_btn->Enable(m_print_enable);
|
||||
if (m_print_enable) {
|
||||
wxPostEvent(m_plater, SimpleEvent(EVT_GLTOOLBAR_PRINT_PLATE));
|
||||
}
|
||||
evt.Skip();
|
||||
return;
|
||||
}
|
||||
else if (evt.CmdDown() && evt.GetKeyCode() == 'G') { if (can_export_gcode()) { wxPostEvent(m_plater, SimpleEvent(EVT_GLTOOLBAR_EXPORT_SLICED_FILE)); } evt.Skip(); return; }
|
||||
if (evt.CmdDown() && evt.GetKeyCode() == 'J') { m_printhost_queue_dlg->Show(); return; }
|
||||
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 (can_save_as()) m_plater->save_project(true); return;}
|
||||
|
|
@ -693,6 +711,8 @@ void MainFrame::update_layout()
|
|||
{
|
||||
// jump to 3deditor under preview_only mode
|
||||
if (evt.GetId() == tp3DEditor){
|
||||
m_plater->update(true);
|
||||
|
||||
if (!preview_only_hint())
|
||||
return;
|
||||
}
|
||||
|
|
@ -942,6 +962,7 @@ void MainFrame::init_tabpanel()
|
|||
}
|
||||
|
||||
m_plater = new Plater(this, this);
|
||||
m_plater->SetBackgroundColour(*wxWHITE);
|
||||
m_plater->Hide();
|
||||
|
||||
wxGetApp().plater_ = m_plater;
|
||||
|
|
@ -1017,11 +1038,9 @@ bool MainFrame::preview_only_hint()
|
|||
preview_only_to_editor = true;
|
||||
});
|
||||
confirm_dlg.update_btn_label(_L("Yes"), _L("No"));
|
||||
auto filename = wxString((m_plater->get_preview_only_filename()).c_str(), wxConvUTF8);
|
||||
//if size of filename is beyond limit
|
||||
auto format_filename = confirm_dlg.format_text(filename, FromDIP(240));
|
||||
auto filename = m_plater->get_preview_only_filename();
|
||||
|
||||
confirm_dlg.update_text(format_filename + _L(" will be closed before creating a new model. Do you want to continue?"));
|
||||
confirm_dlg.update_text(filename + " " + _L("will be closed before creating a new model. Do you want to continue?"));
|
||||
confirm_dlg.on_show();
|
||||
if (preview_only_to_editor) {
|
||||
m_plater->new_project();
|
||||
|
|
@ -1354,9 +1373,9 @@ wxBoxSizer* MainFrame::create_side_tools()
|
|||
m_slice_select = eSlicePlate;
|
||||
m_print_select = ePrintPlate;
|
||||
|
||||
m_slice_btn = new SideButton(this, _L("Slice"), "");
|
||||
m_slice_btn = new SideButton(this, _L("Slice plate"), "");
|
||||
m_slice_option_btn = new SideButton(this, "", "sidebutton_dropdown", 0, FromDIP(14));
|
||||
m_print_btn = new SideButton(this, _L("Print"), "");
|
||||
m_print_btn = new SideButton(this, _L("Print plate"), "");
|
||||
m_print_option_btn = new SideButton(this, "", "sidebutton_dropdown", 0, FromDIP(14));
|
||||
|
||||
update_side_button_style();
|
||||
|
|
@ -2108,12 +2127,12 @@ void MainFrame::init_menubar_as_editor()
|
|||
[this](wxCommandEvent&) { if (m_plater) m_plater->export_core_3mf(); }, "menu_export_sliced_file", nullptr,
|
||||
[this](){return can_export_model(); }, this);
|
||||
// BBS export .gcode.3mf
|
||||
append_menu_item(export_menu, wxID_ANY, _L("Export plate sliced file") + dots/* + "\tCtrl+G"*/, _L("Export current sliced file"),
|
||||
append_menu_item(export_menu, wxID_ANY, _L("Export plate sliced file") + dots + "\tCtrl+G", _L("Export current sliced file"),
|
||||
[this](wxCommandEvent&) { if (m_plater) wxPostEvent(m_plater, SimpleEvent(EVT_GLTOOLBAR_EXPORT_SLICED_FILE)); }, "menu_export_sliced_file", nullptr,
|
||||
[this](){return can_export_gcode(); }, this);
|
||||
|
||||
append_menu_item(export_menu, wxID_ANY, _L("Export all plate sliced file") + dots/* + "\tCtrl+G"*/, _L("Export all plate sliced file"),
|
||||
[this](wxCommandEvent&) { if (m_plater) wxPostEvent(m_plater, SimpleEvent(EVT_GLTOOLBAR_EXPORT_SLICED_FILE)); }, "menu_export_sliced_file", nullptr,
|
||||
[this](wxCommandEvent&) { if (m_plater) wxPostEvent(m_plater, SimpleEvent(EVT_GLTOOLBAR_EXPORT_ALL_SLICED_FILE)); }, "menu_export_sliced_file", nullptr,
|
||||
[this]() {return can_export_all_gcode(); }, this);
|
||||
|
||||
append_menu_item(export_menu, wxID_ANY, _L("Export G-code") + dots/* + "\tCtrl+G"*/, _L("Export current plate as G-code"),
|
||||
|
|
@ -2730,8 +2749,8 @@ struct ConfigsOverwriteConfirmDialog : MessageDialog
|
|||
{
|
||||
ConfigsOverwriteConfirmDialog(wxWindow *parent, wxString name, bool exported)
|
||||
: MessageDialog(parent,
|
||||
wxString::Format(exported ? _("A file exists with the same name: %s, do you wan't to override it.") :
|
||||
_("A config exists with the same name: %s, do you wan't to override it."),
|
||||
wxString::Format(exported ? _L("A file exists with the same name: %s, do you want to override it.") :
|
||||
_L("A config exists with the same name: %s, do you want to override it."),
|
||||
name),
|
||||
_L(exported ? "Overwrite file" : "Overwrite config"),
|
||||
wxYES_NO | wxNO_DEFAULT)
|
||||
|
|
@ -3065,7 +3084,7 @@ void MainFrame::set_print_button_to_default(PrintSelectType select_type)
|
|||
m_print_btn->SetLabel(_L("Print"));
|
||||
m_print_select = eSendGcode;
|
||||
if (m_print_enable)
|
||||
m_print_enable = get_enable_print_status();
|
||||
m_print_enable = get_enable_print_status() && can_send_gcode();
|
||||
m_print_btn->Enable(m_print_enable);
|
||||
this->Layout();
|
||||
} else {
|
||||
|
|
@ -3293,7 +3312,7 @@ void MainFrame::on_select_default_preset(SimpleEvent& evt)
|
|||
{
|
||||
case wxID_YES: {
|
||||
wxGetApp().app_config->set_bool("sync_user_preset", true);
|
||||
wxGetApp().start_sync_user_preset(true);
|
||||
wxGetApp().start_sync_user_preset(true, true);
|
||||
break;
|
||||
}
|
||||
case wxID_NO:
|
||||
|
|
|
|||
|
|
@ -386,9 +386,15 @@ public:
|
|||
|
||||
wxDECLARE_EVENT(EVT_HTTP_ERROR, wxCommandEvent);
|
||||
wxDECLARE_EVENT(EVT_USER_LOGIN, wxCommandEvent);
|
||||
wxDECLARE_EVENT(EVT_USER_LOGIN_HANDLE, wxCommandEvent);
|
||||
wxDECLARE_EVENT(EVT_CHECK_PRIVACY_VER, wxCommandEvent);
|
||||
wxDECLARE_EVENT(EVT_CHECK_PRIVACY_SHOW, wxCommandEvent);
|
||||
wxDECLARE_EVENT(EVT_SHOW_IP_DIALOG, wxCommandEvent);
|
||||
wxDECLARE_EVENT(EVT_SET_SELECTED_MACHINE, wxCommandEvent);
|
||||
wxDECLARE_EVENT(EVT_UPDATE_PRESET_CB, SimpleEvent);
|
||||
|
||||
|
||||
|
||||
} // GUI
|
||||
} //Slic3r
|
||||
|
||||
|
|
|
|||
|
|
@ -81,16 +81,6 @@ MarkdownTip::MarkdownTip()
|
|||
|
||||
_timer = new wxTimer;
|
||||
_timer->Bind(wxEVT_TIMER, &MarkdownTip::OnTimer, this);
|
||||
|
||||
Bind(EVT_WEBVIEW_RECREATED, [this](auto &evt) {
|
||||
Hide();
|
||||
_lastTip.clear();
|
||||
#ifdef __WXMSW__
|
||||
_tipView = dynamic_cast<wxWebView *>(evt.GetEventObject());
|
||||
GetSizer()->Add(_tipView, wxSizerFlags().Expand().Proportion(1));
|
||||
Layout();
|
||||
#endif
|
||||
});
|
||||
}
|
||||
|
||||
MarkdownTip::~MarkdownTip() { delete _timer; }
|
||||
|
|
|
|||
|
|
@ -13,13 +13,9 @@
|
|||
#include <boost/process.hpp>
|
||||
#ifdef __WIN32__
|
||||
#include <boost/process/windows.hpp>
|
||||
#elif __APPLE__
|
||||
#else
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#else
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h> /* For mode constants */
|
||||
#include <fcntl.h> /* For O_* constants */
|
||||
#endif
|
||||
|
||||
namespace Slic3r {
|
||||
|
|
@ -31,6 +27,9 @@ MediaPlayCtrl::MediaPlayCtrl(wxWindow *parent, wxMediaCtrl2 *media_ctrl, const w
|
|||
{
|
||||
SetBackgroundColour(*wxWHITE);
|
||||
m_media_ctrl->Bind(wxEVT_MEDIA_STATECHANGED, &MediaPlayCtrl::onStateChanged, this);
|
||||
#if wxUSE_GSTREAMER_PLAYER
|
||||
m_media_ctrl->Bind(wxEVT_MEDIA_LOADED, &MediaPlayCtrl::onStateChanged, this);
|
||||
#endif
|
||||
|
||||
m_button_play = new Button(this, "", "media_play", wxBORDER_NONE);
|
||||
m_button_play->SetCanFocus(false);
|
||||
|
|
@ -87,7 +86,7 @@ void MediaPlayCtrl::SetMachineObject(MachineObject* obj)
|
|||
m_lan_ip = obj->is_function_supported(PrinterFunction::FUNC_LOCAL_TUNNEL) ? obj->dev_ip : "";
|
||||
m_lan_passwd = obj->is_function_supported(PrinterFunction::FUNC_LOCAL_TUNNEL) ? obj->get_access_code() : "";
|
||||
m_tutk_support = obj->is_function_supported(PrinterFunction::FUNC_REMOTE_TUNNEL);
|
||||
m_device_busy = obj->is_in_prepare();
|
||||
m_device_busy = obj->is_in_prepare() || obj->is_in_upgrading();
|
||||
} else {
|
||||
m_camera_exists = false;
|
||||
m_lan_mode = false;
|
||||
|
|
@ -141,8 +140,10 @@ void MediaPlayCtrl::Play()
|
|||
m_button_play->SetIcon("media_stop");
|
||||
SetStatus(_L("Initializing..."));
|
||||
|
||||
NetworkAgent *agent = wxGetApp().getAgent();
|
||||
std::string agent_version = agent ? agent->get_version() : "";
|
||||
if (!m_lan_ip.empty() && (!m_lan_mode || !m_lan_passwd.empty()) && !m_device_busy) {
|
||||
m_url = "bambu:///local/" + m_lan_ip + ".?port=6000&user=" + m_lan_user + "&passwd=" + m_lan_passwd;
|
||||
m_url = "bambu:///local/" + m_lan_ip + ".?port=6000&user=" + m_lan_user + "&passwd=" + m_lan_passwd + "&device=" + m_machine + "&version=" + agent_version;
|
||||
m_last_state = MEDIASTATE_LOADING;
|
||||
SetStatus(_L("Loading..."));
|
||||
if (wxGetApp().app_config->get("dump_video") == "true") {
|
||||
|
|
@ -182,9 +183,12 @@ void MediaPlayCtrl::Play()
|
|||
return;
|
||||
}
|
||||
|
||||
NetworkAgent* agent = wxGetApp().getAgent();
|
||||
if (agent) {
|
||||
agent->get_camera_url(m_machine, [this, m = m_machine](std::string url) {
|
||||
agent->get_camera_url(m_machine, [this, m = m_machine, v = agent_version](std::string url) {
|
||||
if (boost::algorithm::starts_with(url, "bambu:///")) {
|
||||
url += "&device=" + m;
|
||||
url += "&version=" + v;
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl camera_url: " << url << ", machine: " << m_machine;
|
||||
CallAfter([this, m, url] {
|
||||
if (m != m_machine) return;
|
||||
|
|
@ -233,14 +237,16 @@ void MediaPlayCtrl::Stop(wxString const &msg)
|
|||
SetStatus(msg, false);
|
||||
}
|
||||
++m_failed_retry;
|
||||
if (m_failed_code != 0 && !m_tutk_support && m_failed_retry > 1) {
|
||||
if (m_failed_code != 0 && !m_tutk_support && (m_failed_retry > 1 || m_user_triggered)) {
|
||||
m_next_retry = wxDateTime(); // stop retry
|
||||
if (wxGetApp().show_modal_ip_address_enter_dialog(_L("LAN Connection Failed (Failed to start liveview)"))) {
|
||||
m_failed_retry = 0;
|
||||
m_user_triggered = true;
|
||||
m_next_retry = wxDateTime::Now();
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_user_triggered = false;
|
||||
if (m_next_retry.IsValid())
|
||||
m_next_retry = wxDateTime::Now() + wxTimeSpan::Seconds(5 * m_failed_retry);
|
||||
}
|
||||
|
|
@ -252,6 +258,7 @@ void MediaPlayCtrl::TogglePlay()
|
|||
Stop();
|
||||
} else {
|
||||
m_failed_retry = 0;
|
||||
m_user_triggered = true;
|
||||
m_next_retry = wxDateTime::Now();
|
||||
Play();
|
||||
}
|
||||
|
|
@ -315,8 +322,12 @@ void MediaPlayCtrl::ToggleStream()
|
|||
}
|
||||
NetworkAgent *agent = wxGetApp().getAgent();
|
||||
if (!agent) return;
|
||||
agent->get_camera_url(m_machine, [this, m = m_machine](std::string url) {
|
||||
BOOST_LOG_TRIVIAL(info) << "camera_url: " << url;
|
||||
agent->get_camera_url(m_machine, [this, m = m_machine, v = agent->get_version()](std::string url) {
|
||||
if (boost::algorithm::starts_with(url, "bambu:///")) {
|
||||
url += "&device=" + m;
|
||||
url += "&version=" + v;
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << "camera_url: " << url;
|
||||
CallAfter([this, m, url] {
|
||||
if (m != m_machine) return;
|
||||
if (url.empty() || !boost::algorithm::starts_with(url, "bambu:///")) {
|
||||
|
|
@ -327,7 +338,7 @@ void MediaPlayCtrl::ToggleStream()
|
|||
}
|
||||
std::string file_url = data_dir() + "/cameratools/url.txt";
|
||||
boost::nowide::ofstream file(file_url);
|
||||
auto url2 = encode_path((url + "&device=" + m).c_str());
|
||||
auto url2 = encode_path(url.c_str());
|
||||
file.write(url2.c_str(), url2.size());
|
||||
file.close();
|
||||
m_streaming = true;
|
||||
|
|
@ -354,11 +365,11 @@ void MediaPlayCtrl::onStateChanged(wxMediaEvent &event)
|
|||
Stop();
|
||||
return;
|
||||
}
|
||||
if (last_state == MEDIASTATE_LOADING && state == wxMEDIASTATE_STOPPED) {
|
||||
if (last_state == MEDIASTATE_LOADING && (state == wxMEDIASTATE_STOPPED || state == wxMEDIASTATE_PAUSED || event.GetEventType() == wxEVT_MEDIA_LOADED)) {
|
||||
wxSize size = m_media_ctrl->GetVideoSize();
|
||||
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl::onStateChanged: size: " << size.x << "x" << size.y;
|
||||
m_failed_code = m_media_ctrl->GetLastError();
|
||||
if (size.GetWidth() > 1000) {
|
||||
if (size.GetWidth() > 1000 || (event.GetEventType() == wxEVT_MEDIA_LOADED)) {
|
||||
m_last_state = state;
|
||||
SetStatus(_L("Playing..."), false);
|
||||
m_failed_retry = 0;
|
||||
|
|
@ -442,14 +453,6 @@ void MediaPlayCtrl::media_proc()
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef __WIN32__
|
||||
struct detach_process
|
||||
: public ::boost::process::detail::windows::handler_base_ext
|
||||
{
|
||||
template<class Executor> void on_setup(Executor &exec) const { exec.creation_flags |= ::boost::winapi::CREATE_NO_WINDOW_; }
|
||||
};
|
||||
#endif
|
||||
|
||||
bool MediaPlayCtrl::start_stream_service(bool *need_install)
|
||||
{
|
||||
#ifdef __WIN32__
|
||||
|
|
@ -487,16 +490,16 @@ bool MediaPlayCtrl::start_stream_service(bool *need_install)
|
|||
std::string file_dll2 = data_dir() + "/plugins/BambuSource.dll";
|
||||
if (!boost::filesystem::exists(file_dll) || boost::filesystem::last_write_time(file_dll) != boost::filesystem::last_write_time(file_dll2))
|
||||
boost::filesystem::copy_file(file_dll2, file_dll, boost::filesystem::copy_option::overwrite_if_exists);
|
||||
boost::process::child process_source(file_source, file_url2.data().AsInternal(), boost::process::std_out > intermediate, detach_process(),
|
||||
boost::process::start_dir(start_dir), boost::process::limit_handles);
|
||||
boost::process::child process_ffmpeg(file_ffmpeg, configss, boost::process::std_in < intermediate, detach_process(), boost::process::limit_handles);
|
||||
boost::process::child process_source(file_source, file_url2.data().AsInternal(), boost::process::start_dir(start_dir), boost::process::windows::create_no_window,
|
||||
boost::process::std_out > intermediate, boost::process::limit_handles);
|
||||
boost::process::child process_ffmpeg(file_ffmpeg, configss, boost::process::windows::create_no_window,
|
||||
boost::process::std_in < intermediate, boost::process::limit_handles);
|
||||
#else
|
||||
boost::filesystem::permissions(file_source, boost::filesystem::owner_exe | boost::filesystem::add_perms);
|
||||
boost::filesystem::permissions(file_ffmpeg, boost::filesystem::owner_exe | boost::filesystem::add_perms);
|
||||
// TODO: limit_handles has bugs on posix
|
||||
boost::process::child process_source(file_source, file_url2.data().AsInternal(), boost::process::std_out > intermediate,
|
||||
boost::process::start_dir(start_dir));
|
||||
boost::process::child process_ffmpeg(file_ffmpeg, configss, boost::process::std_in < intermediate);
|
||||
boost::process::child process_source(file_source, file_url2.data().AsInternal(), boost::process::start_dir(start_dir),
|
||||
boost::process::std_out > intermediate, boost::process::limit_handles);
|
||||
boost::process::child process_ffmpeg(file_ffmpeg, configss, boost::process::std_in < intermediate, boost::process::limit_handles);
|
||||
#endif
|
||||
process_source.detach();
|
||||
process_ffmpeg.detach();
|
||||
|
|
@ -521,7 +524,7 @@ bool MediaPlayCtrl::get_stream_url(std::string *url)
|
|||
}
|
||||
}
|
||||
CloseHandle(shm);
|
||||
#elif __APPLE__
|
||||
#else
|
||||
std::string file_url = data_dir() + "/cameratools/url.txt";
|
||||
key_t key = ::ftok(file_url.c_str(), 1000);
|
||||
int shm = ::shmget(key, 1024, 0);
|
||||
|
|
@ -539,18 +542,6 @@ bool MediaPlayCtrl::get_stream_url(std::string *url)
|
|||
url = nullptr;
|
||||
}
|
||||
}
|
||||
#else
|
||||
int shm = ::shm_open("bambu_stream_url", O_RDONLY, 0);
|
||||
if (shm == -1) return false;
|
||||
if (url) {
|
||||
char *addr = (char *) ::mmap(nullptr, 1024, PROT_READ, MAP_SHARED, shm, 0);
|
||||
if (addr != MAP_FAILED) {
|
||||
*url = addr;
|
||||
::munmap(addr, 1024);
|
||||
url = nullptr;
|
||||
}
|
||||
}
|
||||
::close(shm);
|
||||
#endif
|
||||
return url == nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ private:
|
|||
boost::thread m_thread;
|
||||
|
||||
bool m_streaming = false;
|
||||
bool m_user_triggered = false;
|
||||
int m_failed_retry = 0;
|
||||
int m_failed_code = 0;
|
||||
wxDateTime m_next_retry;
|
||||
|
|
|
|||
|
|
@ -147,7 +147,10 @@ namespace GUI {
|
|||
filename = j["data"]["filename"].get<std::string>();
|
||||
|
||||
if (download_url.empty()) return;
|
||||
wxGetApp().plater()->request_model_download(download_url, filename);
|
||||
|
||||
wxGetApp().set_download_model_url(download_url);
|
||||
wxGetApp().set_download_model_name(filename);
|
||||
wxGetApp().plater()->request_model_download();
|
||||
}
|
||||
else if(strCmd == "request_close_publish_window") {
|
||||
this->Hide();
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ MonitorPanel::~MonitorPanel()
|
|||
if (!dev) return;
|
||||
MachineObject *obj_ = dev->get_selected_machine();
|
||||
if (obj_)
|
||||
GUI::wxGetApp().sidebar().load_ams_list(obj_->amsList);
|
||||
GUI::wxGetApp().sidebar().load_ams_list(obj_->dev_id, obj_->amsList);
|
||||
}
|
||||
|
||||
void MonitorPanel::init_tabpanel()
|
||||
|
|
@ -228,7 +228,7 @@ void MonitorPanel::set_default()
|
|||
/* reset side tool*/
|
||||
//m_bitmap_wifi_signal->SetBitmap(wxNullBitmap);
|
||||
|
||||
wxGetApp().sidebar().load_ams_list({});
|
||||
wxGetApp().sidebar().load_ams_list({}, {});
|
||||
}
|
||||
|
||||
wxWindow* MonitorPanel::create_side_tools()
|
||||
|
|
@ -309,7 +309,7 @@ void MonitorPanel::on_update_all(wxMouseEvent &event)
|
|||
|
||||
MachineObject *obj_ = dev->get_selected_machine();
|
||||
if (obj_)
|
||||
GUI::wxGetApp().sidebar().load_ams_list(obj_->amsList);
|
||||
GUI::wxGetApp().sidebar().load_ams_list(obj_->dev_id, obj_->amsList);
|
||||
|
||||
Layout();
|
||||
Refresh();
|
||||
|
|
@ -478,6 +478,9 @@ bool MonitorPanel::Show(bool show)
|
|||
obj = dev->get_selected_machine();
|
||||
if (obj == nullptr) {
|
||||
dev->load_last_machine();
|
||||
obj = dev->get_selected_machine();
|
||||
if (obj)
|
||||
GUI::wxGetApp().sidebar().load_ams_list(obj->dev_id, obj->amsList);
|
||||
} else {
|
||||
obj->reset_update_time();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -357,8 +357,21 @@ void NotificationManager::PopNotification::count_lines()
|
|||
if (text.empty())
|
||||
return;
|
||||
|
||||
// handle with marks
|
||||
if (pos_start == string::npos && pos_end == string::npos) {
|
||||
pos_start = text.find(error_start);
|
||||
if (pos_start != string::npos) {
|
||||
text.erase(pos_start, error_start.length());
|
||||
pos_end = text.find(error_end);
|
||||
if (pos_end != string::npos) {
|
||||
text.erase(pos_end, error_end.length());
|
||||
}
|
||||
}
|
||||
m_text1 = text;
|
||||
}
|
||||
|
||||
m_endlines.clear();
|
||||
while (last_end < text.length() - 1)
|
||||
while (last_end < text.length())
|
||||
{
|
||||
size_t next_hard_end = text.find_first_of('\n', last_end);
|
||||
if (next_hard_end != std::string::npos && ImGui::CalcTextSize(text.substr(last_end, next_hard_end - last_end).c_str()).x < m_window_width - m_window_width_offset) {
|
||||
|
|
@ -481,7 +494,14 @@ void NotificationManager::PopNotification::render_text(ImGuiWrapper& imgui, cons
|
|||
if (m_text1.size() > m_endlines[i])
|
||||
last_end += (m_text1[m_endlines[i]] == '\n' || m_text1[m_endlines[i]] == ' ' ? 1 : 0);
|
||||
|
||||
imgui.text(line.c_str());
|
||||
if (pos_start != string::npos && pos_end != string::npos&& m_endlines[i] - line.length() >= pos_start && m_endlines[i] <= pos_end) {
|
||||
push_style_color(ImGuiCol_Text, m_ErrorColor, m_state == EState::FadingOut, m_current_fade_opacity);
|
||||
imgui.text(line.c_str());
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
else {
|
||||
imgui.text(line.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
//hyperlink text
|
||||
|
|
@ -819,6 +839,7 @@ void NotificationManager::ExportFinishedNotification::render_close_button(ImGuiW
|
|||
|
||||
void NotificationManager::ExportFinishedNotification::render_eject_button(ImGuiWrapper& imgui, const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y)
|
||||
{
|
||||
auto scale = wxGetApp().plater()->get_current_canvas3D()->get_scale();
|
||||
ImVec2 win_size(win_size_x, win_size_y);
|
||||
ImVec2 win_pos(win_pos_x, win_pos_y);
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(.0f, .0f, .0f, .0f));
|
||||
|
|
@ -836,20 +857,15 @@ void NotificationManager::ExportFinishedNotification::render_eject_button(ImGuiW
|
|||
{
|
||||
button_text = ImGui::EjectHoverButton;
|
||||
//tooltip
|
||||
|
||||
long time_now = wxGetLocalTime();
|
||||
if (m_hover_time > 0 && m_hover_time < time_now) {
|
||||
ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGuiWrapper::COL_WINDOW_BACKGROUND);
|
||||
//ImGui::BeginTooltip();
|
||||
//imgui.text(_u8L("Eject drive") + " " + GUI::shortkey_ctrl_prefix() + "T");
|
||||
//ImGui::EndTooltip();
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
if (m_hover_time == 0)
|
||||
m_hover_time = time_now;
|
||||
ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGuiWrapper::COL_WINDOW_BACKGROUND);
|
||||
ImGui::PushStyleColor(ImGuiCol_Border, { 0,0,0,0 });
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, { 8 * scale, 1 * scale });
|
||||
ImGui::BeginTooltip();
|
||||
imgui.text(_u8L("Safely remove hardware."));
|
||||
ImGui::EndTooltip();
|
||||
ImGui::PopStyleColor(2);
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
else
|
||||
m_hover_time = 0;
|
||||
|
||||
ImVec2 button_pic_size = ImGui::CalcTextSize(button_text.c_str());
|
||||
ImVec2 button_size(button_pic_size.x * 1.25f, button_pic_size.y * 1.25f);
|
||||
|
|
@ -1248,7 +1264,7 @@ void NotificationManager::SlicingProgressNotification::set_status_text(const std
|
|||
break;
|
||||
case Slic3r::GUI::NotificationManager::SlicingProgressNotification::SlicingProgressState::SP_COMPLETED:
|
||||
{
|
||||
NotificationData data{ NotificationType::SlicingProgress, NotificationLevel::ProgressBarNotificationLevel, 0, _u8L("Slice ok."), m_is_fff ? _u8L("Export G-Code.") : _u8L("Export.") };
|
||||
NotificationData data{ NotificationType::SlicingProgress, NotificationLevel::ProgressBarNotificationLevel, 0, _u8L("Slice ok.") };
|
||||
update(data);
|
||||
m_state = EState::Shown;
|
||||
}
|
||||
|
|
@ -1549,8 +1565,8 @@ NotificationManager::NotificationManager(wxEvtHandler* evt_handler) :
|
|||
|
||||
void NotificationManager::on_change_color_mode(bool is_dark) {
|
||||
m_is_dark = is_dark;
|
||||
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications){
|
||||
notification->on_change_color_mode(is_dark);
|
||||
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications){
|
||||
notification->on_change_color_mode(is_dark);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2322,7 +2338,6 @@ size_t NotificationManager::get_notification_count() const
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void NotificationManager::bbl_show_plateinfo_notification(const std::string &text)
|
||||
{
|
||||
NotificationData data{NotificationType::BBLPlateInfo, NotificationLevel::PrintInfoNotificationLevel, BBL_NOTICE_MAX_INTERVAL, text};
|
||||
|
|
@ -2339,6 +2354,30 @@ void NotificationManager::bbl_show_plateinfo_notification(const std::string &tex
|
|||
push_notification_data(std::move(notification), 0);
|
||||
}
|
||||
|
||||
void NotificationManager::bbl_close_3mf_warn_notification()
|
||||
{
|
||||
for (std::unique_ptr<PopNotification> ¬ification : m_pop_notifications)
|
||||
if (notification->get_type() == NotificationType::BBL3MFInfo) {
|
||||
notification->close();
|
||||
}
|
||||
}
|
||||
|
||||
void NotificationManager::bbl_show_3mf_warn_notification(const std::string &text)
|
||||
{
|
||||
NotificationData data{NotificationType::BBL3MFInfo, NotificationLevel::ErrorNotificationLevel, BBL_NOTICE_MAX_INTERVAL, text};
|
||||
|
||||
for (std::unique_ptr<PopNotification> ¬ification : m_pop_notifications) {
|
||||
if (notification->get_type() == NotificationType::BBL3MFInfo) {
|
||||
notification->reinit();
|
||||
notification->update(data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
auto notification = std::make_unique<NotificationManager::PopNotification>(data, m_id_provider, m_evt_handler);
|
||||
push_notification_data(std::move(notification), 0);
|
||||
}
|
||||
|
||||
void NotificationManager::bbl_close_plateinfo_notification()
|
||||
{
|
||||
for (std::unique_ptr<PopNotification> ¬ification : m_pop_notifications)
|
||||
|
|
@ -2347,6 +2386,7 @@ void NotificationManager::bbl_close_plateinfo_notification()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void NotificationManager::bbl_show_preview_only_notification(const std::string &text)
|
||||
{
|
||||
NotificationData data{NotificationType::BBLPreviewOnlyMode, NotificationLevel::WarningNotificationLevel, 0, text};
|
||||
|
|
|
|||
|
|
@ -123,6 +123,8 @@ enum class NotificationType
|
|||
ArrangeOngoing,
|
||||
// BBL: Plate Info ,Design For @YangLeDuo
|
||||
BBLPlateInfo,
|
||||
// BBL: 3MF warnings
|
||||
BBL3MFInfo,
|
||||
// BBL: Some Objects Info, Design For @YangLeDuo
|
||||
BBLObjectInfo,
|
||||
// BBL: Objects have empty layer when Slicing
|
||||
|
|
@ -282,6 +284,10 @@ public:
|
|||
void bbl_show_plateinfo_notification(const std::string &text);
|
||||
void bbl_close_plateinfo_notification();
|
||||
|
||||
//BBS-- 3mf warning
|
||||
void bbl_show_3mf_warn_notification(const std::string &text);
|
||||
void bbl_close_3mf_warn_notification();
|
||||
|
||||
//BBS--preview only mode
|
||||
void bbl_show_preview_only_notification(const std::string &text);
|
||||
void bbl_close_preview_only_notification();
|
||||
|
|
@ -488,6 +494,11 @@ private:
|
|||
std::string m_hypertext;
|
||||
// Aditional text after hypertext - currently not used
|
||||
std::string m_text2;
|
||||
// mark for render operation
|
||||
size_t pos_start = string::npos;
|
||||
size_t pos_end = string::npos;
|
||||
std::string error_start = "<Error>";
|
||||
std::string error_end = "</Error>";
|
||||
|
||||
// inner variables to position notification window, texts and buttons correctly
|
||||
|
||||
|
|
|
|||
|
|
@ -952,14 +952,9 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
|
|||
case coInts:
|
||||
ret = config.option<ConfigOptionIntsNullable>(opt_key)->get_at(idx);
|
||||
break;
|
||||
case coPoints:
|
||||
if (opt_key == "bed_shape")
|
||||
ret = config.option<ConfigOptionPoints>(opt_key)->values;
|
||||
else if (opt_key == "thumbnails")
|
||||
ret = get_thumbnails_string(config.option<ConfigOptionPoints>(opt_key)->values);
|
||||
else
|
||||
ret = config.option<ConfigOptionPoints>(opt_key)->get_at(idx);
|
||||
break;
|
||||
case coEnums:
|
||||
ret = config.option<ConfigOptionEnumsGenericNullable>(opt_key)->get_at(idx);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -1233,13 +1228,22 @@ void ExtruderOptionsGroup::on_change_OG(const t_config_option_key& opt_id, const
|
|||
|
||||
wxString OptionsGroup::get_url(const std::string& path_end)
|
||||
{
|
||||
//BBS
|
||||
wxString str = from_u8(path_end);
|
||||
auto pos = str.find(L'#');
|
||||
if (pos != size_t(-1)) {
|
||||
pos++;
|
||||
wxString anchor = str.Mid(pos).Lower();
|
||||
anchor.Replace(L" ", "-");
|
||||
str = str.Left(pos) + anchor;
|
||||
}
|
||||
// Softfever: point to sf wiki for seam parameters
|
||||
if (path_end == "Seam") {
|
||||
return wxString::Format(L"https://github.com/SoftFever/BambuStudio-SoftFever/wiki/%s", from_u8(path_end));
|
||||
}
|
||||
else {
|
||||
//BBS
|
||||
return wxString::Format(L"https://wiki.bambulab.com/%s/software/bambu-studio/%s", L"en", from_u8(path_end));
|
||||
return wxString::Format(L"https://wiki.bambulab.com/%s/software/bambu-studio/%s", L"en", str);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ void ParamsPanel::Highlighter::set_timer_owner(wxEvtHandler *owner, int timerid
|
|||
m_timer.SetOwner(owner, timerid);
|
||||
}
|
||||
|
||||
void ParamsPanel::Highlighter::init(std::pair<wxStaticBitmap *, bool *> params, wxWindow *parent)
|
||||
void ParamsPanel::Highlighter::init(std::pair<wxWindow *, bool *> params, wxWindow *parent)
|
||||
{
|
||||
if (m_timer.IsRunning()) invalidate();
|
||||
if (!params.first || !params.second) return;
|
||||
|
|
@ -185,7 +185,6 @@ void ParamsPanel::Highlighter::blink()
|
|||
ParamsPanel::ParamsPanel( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name )
|
||||
: wxPanel( parent, id, pos, size, style, name )
|
||||
{
|
||||
init_bitmaps();
|
||||
// BBS: new layout
|
||||
SetBackgroundColour(*wxWHITE);
|
||||
#if __WXOSX__
|
||||
|
|
@ -223,7 +222,7 @@ ParamsPanel::ParamsPanel( wxWindow* parent, wxWindowID id, const wxPoint& pos, c
|
|||
m_mode_region->SetMaxSize({em_unit(this) * 12, -1});
|
||||
m_mode_region->SetLabels(_L("Global"), _L("Objects"));
|
||||
//m_mode_region->GetSize(&width, &height);
|
||||
m_tips_arrow = new wxStaticBitmap(m_top_panel, wxID_ANY, m_tips_arrow_icon);
|
||||
m_tips_arrow = new ScalableButton(m_top_panel, wxID_ANY, "tips_arrow");
|
||||
m_tips_arrow->Hide();
|
||||
|
||||
m_title_view = new Label(m_top_panel, _L("Advance"));
|
||||
|
|
@ -348,11 +347,6 @@ ParamsPanel::ParamsPanel( wxWindow* parent, wxWindowID id, const wxPoint& pos, c
|
|||
//m_import_from_file->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { wxGetApp().mainframe->load_config_file(); });
|
||||
}
|
||||
|
||||
void ParamsPanel::init_bitmaps()
|
||||
{
|
||||
m_tips_arrow_icon = create_scaled_bitmap("tips_arrow", nullptr, 24);
|
||||
}
|
||||
|
||||
void ParamsPanel::create_layout()
|
||||
{
|
||||
#ifdef __WINDOWS__
|
||||
|
|
@ -370,19 +364,18 @@ void ParamsPanel::create_layout()
|
|||
m_mode_sizer->Add(m_process_icon, 0, wxALIGN_CENTER);
|
||||
m_mode_sizer->AddSpacer(FromDIP(11));
|
||||
m_mode_sizer->Add( m_title_label, 0, wxALIGN_CENTER );
|
||||
m_mode_sizer->AddSpacer(FromDIP(9));
|
||||
m_mode_sizer->Add( m_mode_region, 0, wxALIGN_CENTER );
|
||||
m_mode_sizer->AddSpacer(FromDIP(9));
|
||||
m_mode_sizer->Add( m_tips_arrow, 0, wxALIGN_CENTER);
|
||||
m_mode_sizer->AddStretchSpacer(2);
|
||||
m_mode_sizer->Add(m_mode_region, 0, wxALIGN_CENTER);
|
||||
m_mode_sizer->AddStretchSpacer(1);
|
||||
m_mode_sizer->Add(m_tips_arrow, 0, wxALIGN_CENTER);
|
||||
m_mode_sizer->AddStretchSpacer(8);
|
||||
m_mode_sizer->Add( m_title_view, 0, wxALIGN_CENTER );
|
||||
m_mode_sizer->AddSpacer(FromDIP(9));
|
||||
m_mode_sizer->Add( m_mode_view, 0, wxALIGN_CENTER );
|
||||
m_mode_sizer->AddSpacer(FromDIP(16));
|
||||
m_mode_sizer->Add( m_setting_btn, 0, wxALIGN_CENTER );
|
||||
|
||||
m_mode_sizer->AddSpacer(FromDIP(16));
|
||||
m_mode_sizer->Add( m_compare_btn, 0, wxALIGN_CENTER );
|
||||
m_mode_sizer->AddSpacer(FromDIP(2));
|
||||
m_mode_sizer->Add(m_mode_view, 0, wxALIGN_CENTER);
|
||||
m_mode_sizer->AddStretchSpacer(2);
|
||||
m_mode_sizer->Add(m_setting_btn, 0, wxALIGN_CENTER);
|
||||
m_mode_sizer->AddSpacer(FromDIP(2));
|
||||
m_mode_sizer->Add(m_compare_btn, 0, wxALIGN_CENTER);
|
||||
|
||||
m_mode_sizer->AddSpacer(FromDIP(8));
|
||||
//m_mode_sizer->Add( m_search_btn, 0, wxALIGN_CENTER );
|
||||
|
|
@ -649,6 +642,7 @@ void ParamsPanel::msw_rescale()
|
|||
if (m_setting_btn) m_setting_btn->msw_rescale();
|
||||
if (m_search_btn) m_search_btn->msw_rescale();
|
||||
if (m_compare_btn) m_compare_btn->msw_rescale();
|
||||
if (m_tips_arrow) m_tips_arrow->msw_rescale();
|
||||
m_left_sizer->SetMinSize(wxSize(40 * em_unit(this), -1));
|
||||
if (m_mode_sizer)
|
||||
m_mode_sizer->SetMinSize(-1, 3 * em_unit(this));
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ class ParamsPanel : public wxPanel
|
|||
ScalableButton* m_process_icon{ nullptr };
|
||||
wxStaticText* m_title_label { nullptr };
|
||||
SwitchButton* m_mode_region { nullptr };
|
||||
wxStaticBitmap* m_tips_arrow{ nullptr };
|
||||
ScalableButton *m_tips_arrow{nullptr};
|
||||
bool m_tips_arror_blink{false};
|
||||
wxStaticText* m_title_view { nullptr };
|
||||
SwitchButton* m_mode_view { nullptr };
|
||||
|
|
@ -116,7 +116,6 @@ class ParamsPanel : public wxPanel
|
|||
|
||||
wxBitmap m_toggle_on_icon;
|
||||
wxBitmap m_toggle_off_icon;
|
||||
wxBitmap m_tips_arrow_icon;
|
||||
|
||||
wxPanel* m_current_tab { nullptr };
|
||||
|
||||
|
|
@ -125,12 +124,12 @@ class ParamsPanel : public wxPanel
|
|||
struct Highlighter
|
||||
{
|
||||
void set_timer_owner(wxEvtHandler *owner, int timerid = wxID_ANY);
|
||||
void init(std::pair<wxStaticBitmap *, bool *>, wxWindow *parent = nullptr);
|
||||
void init(std::pair<wxWindow *, bool *>, wxWindow *parent = nullptr);
|
||||
void blink();
|
||||
void invalidate();
|
||||
|
||||
private:
|
||||
wxStaticBitmap *m_bitmap { nullptr };
|
||||
wxWindow * m_bitmap{nullptr};
|
||||
bool * m_show_blink_ptr{nullptr};
|
||||
int m_blink_counter{0};
|
||||
wxTimer m_timer;
|
||||
|
|
@ -143,7 +142,6 @@ class ParamsPanel : public wxPanel
|
|||
ParamsPanel( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 1800,1080 ), long style = wxTAB_TRAVERSAL, const wxString& type = wxEmptyString );
|
||||
~ParamsPanel();
|
||||
|
||||
void init_bitmaps();
|
||||
void rebuild_panels();
|
||||
void create_layout();
|
||||
//clear the right page
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ void PartPlate::init()
|
|||
m_print = nullptr;
|
||||
}
|
||||
|
||||
BedType PartPlate::get_bed_type(bool check_global/*= true*/) const
|
||||
BedType PartPlate::get_bed_type() const
|
||||
{
|
||||
std::string bed_type_key = "curr_bed_type";
|
||||
|
||||
|
|
@ -141,32 +141,26 @@ BedType PartPlate::get_bed_type(bool check_global/*= true*/) const
|
|||
assert(m_plater != nullptr);
|
||||
if (m_config.has(bed_type_key)) {
|
||||
BedType bed_type = m_config.opt_enum<BedType>(bed_type_key);
|
||||
if (bed_type != btDefault)
|
||||
return bed_type;
|
||||
return bed_type;
|
||||
}
|
||||
|
||||
if (!check_global)
|
||||
return btDefault;
|
||||
|
||||
if (m_plater) {
|
||||
// In GUI mode
|
||||
DynamicConfig& proj_cfg = wxGetApp().preset_bundle->project_config;
|
||||
if (proj_cfg.has(bed_type_key))
|
||||
return proj_cfg.opt_enum<BedType>(bed_type_key);
|
||||
}
|
||||
|
||||
return BedType::btPC;
|
||||
return btDefault;
|
||||
}
|
||||
|
||||
void PartPlate::set_bed_type(BedType bed_type)
|
||||
{
|
||||
std::string bed_type_key = "curr_bed_type";
|
||||
std::string bed_type_key = "curr_bed_type";
|
||||
|
||||
// should be called in GUI context
|
||||
assert(m_plater != nullptr);
|
||||
// should be called in GUI context
|
||||
assert(m_plater != nullptr);
|
||||
|
||||
// update slice state
|
||||
BedType old_real_bed_type = get_bed_type();
|
||||
if (old_real_bed_type == btDefault) {
|
||||
DynamicConfig& proj_cfg = wxGetApp().preset_bundle->project_config;
|
||||
if (proj_cfg.has(bed_type_key))
|
||||
old_real_bed_type = proj_cfg.opt_enum<BedType>(bed_type_key);
|
||||
}
|
||||
BedType new_real_bed_type = bed_type;
|
||||
if (bed_type == BedType::btDefault) {
|
||||
DynamicConfig& proj_cfg = wxGetApp().preset_bundle->project_config;
|
||||
|
|
@ -177,18 +171,74 @@ void PartPlate::set_bed_type(BedType bed_type)
|
|||
update_slice_result_valid_state(false);
|
||||
}
|
||||
|
||||
if (bed_type == BedType::btDefault)
|
||||
m_config.erase(bed_type_key);
|
||||
else
|
||||
m_config.set_key_value("curr_bed_type", new ConfigOptionEnum<BedType>(bed_type));
|
||||
|
||||
if (m_plater)
|
||||
m_plater->update_project_dirty_from_presets();
|
||||
if (bed_type == BedType::btDefault)
|
||||
m_config.erase(bed_type_key);
|
||||
else
|
||||
m_config.set_key_value("curr_bed_type", new ConfigOptionEnum<BedType>(bed_type));
|
||||
}
|
||||
|
||||
void PartPlate::reset_bed_type()
|
||||
{
|
||||
m_config.erase("curr_bed_type");
|
||||
m_config.erase("curr_bed_type");
|
||||
}
|
||||
|
||||
void PartPlate::set_print_seq(PrintSequence print_seq)
|
||||
{
|
||||
std::string print_seq_key = "print_sequence";
|
||||
|
||||
// should be called in GUI context
|
||||
assert(m_plater != nullptr);
|
||||
|
||||
// update slice state
|
||||
PrintSequence old_real_print_seq = get_print_seq();
|
||||
if (old_real_print_seq == PrintSequence::ByDefault) {
|
||||
auto curr_preset_config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||
if (curr_preset_config.has(print_seq_key))
|
||||
old_real_print_seq = curr_preset_config.option<ConfigOptionEnum<PrintSequence>>(print_seq_key)->value;
|
||||
}
|
||||
|
||||
PrintSequence new_real_print_seq = print_seq;
|
||||
|
||||
if (print_seq == PrintSequence::ByDefault) {
|
||||
auto curr_preset_config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||
if (curr_preset_config.has(print_seq_key))
|
||||
new_real_print_seq = curr_preset_config.option<ConfigOptionEnum<PrintSequence>>(print_seq_key)->value;
|
||||
}
|
||||
|
||||
if (old_real_print_seq != new_real_print_seq) {
|
||||
update_slice_result_valid_state(false);
|
||||
}
|
||||
|
||||
//print_seq_same_global = same_global;
|
||||
if (print_seq == PrintSequence::ByDefault)
|
||||
m_config.erase(print_seq_key);
|
||||
else
|
||||
m_config.set_key_value(print_seq_key, new ConfigOptionEnum<PrintSequence>(print_seq));
|
||||
}
|
||||
|
||||
PrintSequence PartPlate::get_print_seq() const
|
||||
{
|
||||
std::string print_seq_key = "print_sequence";
|
||||
|
||||
// should be called in GUI context
|
||||
assert(m_plater != nullptr);
|
||||
|
||||
if (m_config.has(print_seq_key)) {
|
||||
PrintSequence print_seq = m_config.opt_enum<PrintSequence>(print_seq_key);
|
||||
return print_seq;
|
||||
}
|
||||
|
||||
return PrintSequence::ByDefault;
|
||||
}
|
||||
|
||||
PrintSequence PartPlate::get_real_print_seq() const
|
||||
{
|
||||
PrintSequence curr_plate_seq = get_print_seq();
|
||||
if (curr_plate_seq == PrintSequence::ByDefault) {
|
||||
auto curr_preset_config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||
if (curr_preset_config.has("print_sequence")) curr_plate_seq = curr_preset_config.option<ConfigOptionEnum<PrintSequence>>("print_sequence")->value;
|
||||
}
|
||||
return curr_plate_seq;
|
||||
}
|
||||
|
||||
bool PartPlate::valid_instance(int obj_id, int instance_id)
|
||||
|
|
@ -545,7 +595,7 @@ void PartPlate::render_logo(bool bottom) const
|
|||
|
||||
//canvas.request_extra_frame();
|
||||
}
|
||||
|
||||
|
||||
if (m_vbo_id == 0) {
|
||||
unsigned int* vbo_id_ptr = const_cast<unsigned int*>(&m_vbo_id);
|
||||
glsafe(::glGenBuffers(1, vbo_id_ptr));
|
||||
|
|
@ -561,13 +611,19 @@ void PartPlate::render_logo(bool bottom) const
|
|||
m_partplate_list->load_bedtype_textures();
|
||||
|
||||
// btDefault should be skipped
|
||||
int bed_type_idx = (int)get_bed_type();
|
||||
auto curr_bed_type = get_bed_type();
|
||||
if (curr_bed_type == btDefault) {
|
||||
DynamicConfig& proj_cfg = wxGetApp().preset_bundle->project_config;
|
||||
if (proj_cfg.has(std::string("curr_bed_type")))
|
||||
curr_bed_type = proj_cfg.opt_enum<BedType>(std::string("curr_bed_type"));
|
||||
}
|
||||
int bed_type_idx = (int)curr_bed_type;
|
||||
for (auto &part : m_partplate_list->bed_texture_info[bed_type_idx].parts) {
|
||||
if (part.texture) {
|
||||
if (part.buffer && part.buffer->get_vertices_count() > 0
|
||||
//&& part.vbo_id != 0
|
||||
) {
|
||||
if (part.offset.x() != m_origin.x() || part.offset.y() != m_origin.y()) {
|
||||
if (part.offset.x() != m_origin.x() || part.offset.y() != m_origin.y()) {
|
||||
part.offset = Vec2d(m_origin.x(), m_origin.y());
|
||||
part.update_buffer();
|
||||
}
|
||||
|
|
@ -739,18 +795,18 @@ void PartPlate::render_icons(bool bottom, int hover_id) const
|
|||
render_icon_texture(position_id, tex_coords_id, m_lock_icon, m_partplate_list->m_lockopen_texture, m_lock_vbo_id);
|
||||
}
|
||||
|
||||
if (m_partplate_list->render_bedtype_setting) {
|
||||
if (m_partplate_list->render_plate_settings) {
|
||||
if (hover_id == 5) {
|
||||
if (get_bed_type(false) == BedType::btDefault)
|
||||
render_icon_texture(position_id, tex_coords_id, m_bedtype_icon, m_partplate_list->m_bedtype_hovered_texture, m_bedtype_vbo_id);
|
||||
if (get_bed_type() == BedType::btDefault && get_print_seq() == PrintSequence::ByDefault)
|
||||
render_icon_texture(position_id, tex_coords_id, m_plate_settings_icon, m_partplate_list->m_plate_settings_hovered_texture, m_plate_settings_vbo_id);
|
||||
else
|
||||
render_icon_texture(position_id, tex_coords_id, m_bedtype_icon, m_partplate_list->m_bedtype_changed_hovered_texture, m_bedtype_vbo_id);
|
||||
render_icon_texture(position_id, tex_coords_id, m_plate_settings_icon, m_partplate_list->m_plate_settings_changed_hovered_texture, m_plate_settings_vbo_id);
|
||||
}
|
||||
else {
|
||||
if (get_bed_type(false) == BedType::btDefault)
|
||||
render_icon_texture(position_id, tex_coords_id, m_bedtype_icon, m_partplate_list->m_bedtype_texture, m_bedtype_vbo_id);
|
||||
if (get_bed_type() == BedType::btDefault && get_print_seq() == PrintSequence::ByDefault)
|
||||
render_icon_texture(position_id, tex_coords_id, m_plate_settings_icon, m_partplate_list->m_plate_settings_texture, m_plate_settings_vbo_id);
|
||||
else
|
||||
render_icon_texture(position_id, tex_coords_id, m_bedtype_icon, m_partplate_list->m_bedtype_changed_texture, m_bedtype_vbo_id);
|
||||
render_icon_texture(position_id, tex_coords_id, m_plate_settings_icon, m_partplate_list->m_plate_settings_changed_texture, m_plate_settings_vbo_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1088,8 +1144,8 @@ void PartPlate::on_render_for_picking() const {
|
|||
m_grabber_color[1] = color[1];
|
||||
m_grabber_color[2] = color[2];
|
||||
m_grabber_color[3] = color[3];
|
||||
if (m_partplate_list->render_bedtype_setting)
|
||||
render_rectangle_for_picking(m_bedtype_icon, m_grabber_color);
|
||||
if (m_partplate_list->render_plate_settings)
|
||||
render_rectangle_for_picking(m_plate_settings_icon, m_grabber_color);
|
||||
}
|
||||
|
||||
std::array<float, 4> PartPlate::picking_color_component(int idx) const
|
||||
|
|
@ -1126,9 +1182,9 @@ void PartPlate::release_opengl_resource()
|
|||
glsafe(::glDeleteBuffers(1, &m_lock_vbo_id));
|
||||
m_lock_vbo_id = 0;
|
||||
}
|
||||
if (m_bedtype_vbo_id > 0) {
|
||||
glsafe(::glDeleteBuffers(1, &m_bedtype_vbo_id));
|
||||
m_bedtype_vbo_id = 0;
|
||||
if (m_plate_settings_vbo_id > 0) {
|
||||
glsafe(::glDeleteBuffers(1, &m_plate_settings_vbo_id));
|
||||
m_plate_settings_vbo_id = 0;
|
||||
}
|
||||
if (m_plate_idx_vbo_id > 0) {
|
||||
glsafe(::glDeleteBuffers(1, &m_plate_idx_vbo_id));
|
||||
|
|
@ -1136,7 +1192,7 @@ void PartPlate::release_opengl_resource()
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<int> PartPlate::get_extruders() const
|
||||
std::vector<int> PartPlate::get_extruders(bool conside_custom_gcode) const
|
||||
{
|
||||
std::vector<int> plate_extruders;
|
||||
// if gcode.3mf file
|
||||
|
|
@ -1152,6 +1208,7 @@ std::vector<int> PartPlate::get_extruders() const
|
|||
int glb_support_intf_extr = glb_config.opt_int("support_interface_filament");
|
||||
int glb_support_extr = glb_config.opt_int("support_filament");
|
||||
bool glb_support = glb_config.opt_bool("enable_support");
|
||||
glb_support |= glb_config.opt_int("raft_layers") > 0;
|
||||
|
||||
for (int obj_idx = 0; obj_idx < m_model->objects.size(); obj_idx++) {
|
||||
if (!contain_instance_totally(obj_idx, 0))
|
||||
|
|
@ -1165,8 +1222,13 @@ std::vector<int> PartPlate::get_extruders() const
|
|||
|
||||
bool obj_support = false;
|
||||
const ConfigOption* obj_support_opt = mo->config.option("enable_support");
|
||||
if (obj_support_opt != nullptr)
|
||||
obj_support = obj_support_opt->getBool();
|
||||
const ConfigOption *obj_raft_opt = mo->config.option("raft_layers");
|
||||
if (obj_support_opt != nullptr || obj_raft_opt != nullptr) {
|
||||
if (obj_support_opt != nullptr)
|
||||
obj_support = obj_support_opt->getBool();
|
||||
if (obj_raft_opt != nullptr)
|
||||
obj_support |= obj_raft_opt->getInt() > 0;
|
||||
}
|
||||
else
|
||||
obj_support = glb_support;
|
||||
|
||||
|
|
@ -1192,6 +1254,16 @@ std::vector<int> PartPlate::get_extruders() const
|
|||
plate_extruders.push_back(glb_support_extr);
|
||||
}
|
||||
|
||||
if (conside_custom_gcode) {
|
||||
//BBS
|
||||
if (m_model->plates_custom_gcodes.find(m_plate_index) != m_model->plates_custom_gcodes.end()) {
|
||||
for (auto item : m_model->plates_custom_gcodes.at(m_plate_index).gcodes) {
|
||||
if (item.type == CustomGCode::Type::ToolChange)
|
||||
plate_extruders.push_back(item.extruder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(plate_extruders.begin(), plate_extruders.end());
|
||||
auto it_end = std::unique(plate_extruders.begin(), plate_extruders.end());
|
||||
plate_extruders.resize(std::distance(plate_extruders.begin(), it_end));
|
||||
|
|
@ -1223,7 +1295,7 @@ std::vector<int> PartPlate::get_used_extruders()
|
|||
Vec3d PartPlate::estimate_wipe_tower_size(const double w, const double wipe_volume) const
|
||||
{
|
||||
Vec3d wipe_tower_size;
|
||||
std::vector<int> plate_extruders = get_extruders();
|
||||
std::vector<int> plate_extruders = get_extruders(true);
|
||||
double layer_height = 0.08f; // hard code layer height
|
||||
double max_height = 0.f;
|
||||
wipe_tower_size.setZero();
|
||||
|
|
@ -1673,6 +1745,29 @@ int PartPlate::remove_instance(int obj_id, int instance_id)
|
|||
return result;
|
||||
}
|
||||
|
||||
//translate instance on the plate
|
||||
void PartPlate::translate_all_instance(Vec3d position)
|
||||
{
|
||||
for (std::set<std::pair<int, int>>::iterator it = obj_to_instance_set.begin(); it != obj_to_instance_set.end(); ++it)
|
||||
{
|
||||
int obj_id = it->first;
|
||||
int instance_id = it->second;
|
||||
|
||||
if ((obj_id >= 0) && (obj_id < m_model->objects.size()))
|
||||
{
|
||||
ModelObject* object = m_model->objects[obj_id];
|
||||
if ((instance_id >= 0) && (instance_id < object->instances.size()))
|
||||
{
|
||||
ModelInstance* instance = object->instances[instance_id];
|
||||
const Vec3d& offset = instance->get_offset();
|
||||
instance->set_offset(offset + position);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//update instance exclude state
|
||||
void PartPlate::update_instance_exclude_status(int obj_id, int instance_id, BoundingBoxf3* bounding_box)
|
||||
{
|
||||
|
|
@ -1722,6 +1817,26 @@ void PartPlate::update_object_index(int obj_idx_removed, int obj_idx_max)
|
|||
|
||||
}
|
||||
|
||||
int PartPlate::printable_instance_size()
|
||||
{
|
||||
int size = 0;
|
||||
for (std::set<std::pair<int, int>>::iterator it = obj_to_instance_set.begin(); it != obj_to_instance_set.end(); ++it) {
|
||||
int obj_id = it->first;
|
||||
int instance_id = it->second;
|
||||
|
||||
if (obj_id >= m_model->objects.size())
|
||||
continue;
|
||||
|
||||
ModelObject * object = m_model->objects[obj_id];
|
||||
ModelInstance *instance = object->instances[instance_id];
|
||||
|
||||
if ((instance->printable) && (instance_outside_set.find(std::pair(obj_id, instance_id)) == instance_outside_set.end())) {
|
||||
size++;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
//whether it is has printable instances
|
||||
bool PartPlate::has_printable_instances()
|
||||
{
|
||||
|
|
@ -1917,17 +2032,27 @@ void PartPlate::generate_exclude_polygon(ExPolygon &exclude_polygon)
|
|||
|
||||
bool PartPlate::set_shape(const Pointfs& shape, const Pointfs& exclude_areas, Vec2d position, float height_to_lid, float height_to_rod)
|
||||
{
|
||||
if ((m_shape == shape)&&(m_exclude_area == exclude_areas)
|
||||
Pointfs new_shape, new_exclude_areas;
|
||||
|
||||
for (const Vec2d& p : shape) {
|
||||
new_shape.push_back(Vec2d(p.x() + position.x(), p.y() + position.y()));
|
||||
}
|
||||
|
||||
for (const Vec2d& p : exclude_areas) {
|
||||
new_exclude_areas.push_back(Vec2d(p.x() + position.x(), p.y() + position.y()));
|
||||
}
|
||||
if ((m_shape == new_shape)&&(m_exclude_area == new_exclude_areas)
|
||||
&&(m_height_to_lid == height_to_lid)&&(m_height_to_rod == height_to_rod)) {
|
||||
BOOST_LOG_TRIVIAL(trace) << "PartPlate same shape";
|
||||
BOOST_LOG_TRIVIAL(info) << "PartPlate same shape, skip directly";
|
||||
return false;
|
||||
}
|
||||
|
||||
m_height_to_lid = height_to_lid;
|
||||
m_height_to_rod = height_to_rod;
|
||||
|
||||
if ((m_shape != shape) || (m_exclude_area != exclude_areas))
|
||||
if ((m_shape != new_shape) || (m_exclude_area != new_exclude_areas))
|
||||
{
|
||||
m_shape.clear();
|
||||
/*m_shape.clear();
|
||||
for (const Vec2d& p : shape) {
|
||||
m_shape.push_back(Vec2d(p.x() + position.x(), p.y() + position.y()));
|
||||
}
|
||||
|
|
@ -1935,7 +2060,9 @@ bool PartPlate::set_shape(const Pointfs& shape, const Pointfs& exclude_areas, Ve
|
|||
m_exclude_area.clear();
|
||||
for (const Vec2d& p : exclude_areas) {
|
||||
m_exclude_area.push_back(Vec2d(p.x() + position.x(), p.y() + position.y()));
|
||||
}
|
||||
}*/
|
||||
m_shape = std::move(new_shape);
|
||||
m_exclude_area = std::move(new_exclude_areas);
|
||||
|
||||
calc_bounding_boxes();
|
||||
|
||||
|
|
@ -1970,7 +2097,7 @@ bool PartPlate::set_shape(const Pointfs& shape, const Pointfs& exclude_areas, Ve
|
|||
calc_vertex_for_icons(1, m_orient_icon);
|
||||
calc_vertex_for_icons(2, m_arrange_icon);
|
||||
calc_vertex_for_icons(3, m_lock_icon);
|
||||
calc_vertex_for_icons(4, m_bedtype_icon);
|
||||
calc_vertex_for_icons(4, m_plate_settings_icon);
|
||||
//calc_vertex_for_number(0, (m_plate_index < 9), m_plate_idx_icon);
|
||||
calc_vertex_for_number(0, false, m_plate_idx_icon);
|
||||
}
|
||||
|
|
@ -2188,10 +2315,13 @@ int PartPlate::load_gcode_from_file(const std::string& filename)
|
|||
int ret = 0;
|
||||
|
||||
// process gcode
|
||||
m_print->apply(*m_model, wxGetApp().preset_bundle->full_config());
|
||||
DynamicPrintConfig full_config = wxGetApp().preset_bundle->full_config();
|
||||
full_config.apply(m_config, true);
|
||||
m_print->apply(*m_model, full_config);
|
||||
//BBS: need to apply two times, for after the first apply, the m_print got its object,
|
||||
//which will affect the config when new_full_config.normalize_fdm(used_filaments);
|
||||
m_print->apply(*m_model, wxGetApp().preset_bundle->full_config());
|
||||
m_print->apply(*m_model, full_config);
|
||||
|
||||
// BBS: use backup path to save temp gcode
|
||||
// auto path = get_tmp_gcode_path();
|
||||
// if (boost::filesystem::exists(boost::filesystem::path(path))) {
|
||||
|
|
@ -2372,6 +2502,23 @@ Vec3d PartPlateList::compute_origin(int i, int cols)
|
|||
return origin;
|
||||
}
|
||||
|
||||
//compute the origin for printable plate with index i using new width
|
||||
Vec3d PartPlateList::compute_origin_using_new_size(int i, int new_width, int new_depth)
|
||||
{
|
||||
Vec3d origin;
|
||||
int row, col;
|
||||
|
||||
row = i / m_plate_cols;
|
||||
col = i % m_plate_cols;
|
||||
|
||||
origin(0) = col * (new_width * (1. + LOGICAL_PART_PLATE_GAP));
|
||||
origin(1) = -row * (new_depth * (1. + LOGICAL_PART_PLATE_GAP));
|
||||
origin(2) = 0;
|
||||
|
||||
return origin;
|
||||
}
|
||||
|
||||
|
||||
//compute the origin for printable plate with index i
|
||||
Vec3d PartPlateList::compute_origin_for_unprintable()
|
||||
{
|
||||
|
|
@ -2489,32 +2636,32 @@ void PartPlateList::generate_icon_textures()
|
|||
|
||||
//if (m_bedtype_texture.get_id() == 0)
|
||||
{
|
||||
file_name = path + (m_is_dark ? "plate_set_bedtype_dark.svg" : "plate_set_bedtype.svg");
|
||||
if (!m_bedtype_texture.load_from_svg_file(file_name, true, false, false, icon_size)) {
|
||||
file_name = path + (m_is_dark ? "plate_settings_dark.svg" : "plate_settings.svg");
|
||||
if (!m_plate_settings_texture.load_from_svg_file(file_name, true, false, false, icon_size)) {
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(":load file %1% failed") % file_name;
|
||||
}
|
||||
}
|
||||
|
||||
//if (m_bedtype_changed_texture.get_id() == 0)
|
||||
{
|
||||
file_name = path + (m_is_dark ? "plate_set_bedtype_changed_dark.svg" : "plate_set_bedtype_changed.svg");
|
||||
if (!m_bedtype_changed_texture.load_from_svg_file(file_name, true, false, false, icon_size)) {
|
||||
file_name = path + (m_is_dark ? "plate_settings_changed_dark.svg" : "plate_settings_changed.svg");
|
||||
if (!m_plate_settings_changed_texture.load_from_svg_file(file_name, true, false, false, icon_size)) {
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(":load file %1% failed") % file_name;
|
||||
}
|
||||
}
|
||||
|
||||
//if (m_bedtype_hovered_texture.get_id() == 0)
|
||||
{
|
||||
file_name = path + (m_is_dark ? "plate_set_bedtype_hover_dark.svg" : "plate_set_bedtype_hover.svg");
|
||||
if (!m_bedtype_hovered_texture.load_from_svg_file(file_name, true, false, false, icon_size)) {
|
||||
file_name = path + (m_is_dark ? "plate_settings_hover_dark.svg" : "plate_settings_hover.svg");
|
||||
if (!m_plate_settings_hovered_texture.load_from_svg_file(file_name, true, false, false, icon_size)) {
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(":load file %1% failed") % file_name;
|
||||
}
|
||||
}
|
||||
|
||||
//if (m_bedtype_changed_hovered_texture.get_id() == 0)
|
||||
{
|
||||
file_name = path + (m_is_dark ? "plate_set_bedtype_changed_hover_dark.svg" : "plate_set_bedtype_changed_hover.svg");
|
||||
if (!m_bedtype_changed_hovered_texture.load_from_svg_file(file_name, true, false, false, icon_size)) {
|
||||
file_name = path + (m_is_dark ? "plate_settings_changed_hover_dark.svg" : "plate_settings_changed_hover.svg");
|
||||
if (!m_plate_settings_changed_hovered_texture.load_from_svg_file(file_name, true, false, false, icon_size)) {
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(":load file %1% failed") % file_name;
|
||||
}
|
||||
}
|
||||
|
|
@ -2575,10 +2722,10 @@ void PartPlateList::release_icon_textures()
|
|||
m_locked_hovered_texture.reset();
|
||||
m_lockopen_texture.reset();
|
||||
m_lockopen_hovered_texture.reset();
|
||||
m_bedtype_texture.reset();
|
||||
m_bedtype_changed_texture.reset();
|
||||
m_bedtype_hovered_texture.reset();
|
||||
m_bedtype_changed_hovered_texture.reset();
|
||||
m_plate_settings_texture.reset();
|
||||
m_plate_settings_texture.reset();
|
||||
m_plate_settings_texture.reset();
|
||||
m_plate_settings_hovered_texture.reset();
|
||||
|
||||
for (int i = 0;i < MAX_PLATE_COUNT; i++) {
|
||||
m_idx_textures[i].reset();
|
||||
|
|
@ -2603,7 +2750,7 @@ void PartPlateList::release_icon_textures()
|
|||
}
|
||||
|
||||
//this may be happened after machine changed
|
||||
void PartPlateList::reset_size(int width, int depth, int height)
|
||||
void PartPlateList::reset_size(int width, int depth, int height, bool reload_objects, bool update_shapes)
|
||||
{
|
||||
Vec3d origin1, origin2;
|
||||
|
||||
|
|
@ -2615,7 +2762,13 @@ void PartPlateList::reset_size(int width, int depth, int height)
|
|||
m_plate_depth = depth;
|
||||
m_plate_height = height;
|
||||
update_all_plates_pos_and_size(false, false);
|
||||
reload_all_objects();
|
||||
if (update_shapes) {
|
||||
set_shapes(m_shape, m_exclude_areas, m_logo_texture_filename, m_height_to_lid, m_height_to_rod);
|
||||
}
|
||||
if (reload_objects)
|
||||
reload_all_objects();
|
||||
else
|
||||
clear(false, false, false, -1);
|
||||
}
|
||||
|
||||
return;
|
||||
|
|
@ -2967,6 +3120,25 @@ PartPlate* PartPlateList::get_selected_plate()
|
|||
return m_plate_list[m_current_plate];
|
||||
}
|
||||
|
||||
std::vector<PartPlate*> PartPlateList::get_nonempty_plate_list()
|
||||
{
|
||||
std::vector<PartPlate*> nonempty_plate_list;
|
||||
for (auto plate : m_plate_list){
|
||||
if (plate->get_extruders().size() != 0) {
|
||||
nonempty_plate_list.push_back(plate);
|
||||
}
|
||||
}
|
||||
return nonempty_plate_list;
|
||||
}
|
||||
|
||||
std::vector<const GCodeProcessorResult*> PartPlateList::get_nonempty_plates_slice_results() {
|
||||
std::vector<const GCodeProcessorResult*> nonempty_plates_slice_result;
|
||||
for (auto plate : get_nonempty_plate_list()) {
|
||||
nonempty_plates_slice_result.push_back(plate->get_slice_result());
|
||||
}
|
||||
return nonempty_plates_slice_result;
|
||||
}
|
||||
|
||||
//select plate
|
||||
int PartPlateList::select_plate(int index)
|
||||
{
|
||||
|
|
@ -2989,11 +3161,15 @@ int PartPlateList::select_plate(int index)
|
|||
m_current_plate = index;
|
||||
m_plate_list[m_current_plate]->set_selected();
|
||||
|
||||
//BBS
|
||||
if(m_model)
|
||||
m_model->curr_plate_index = index;
|
||||
|
||||
//BBS update bed origin
|
||||
if (m_intialized && m_plater) {
|
||||
Vec2d pos = compute_shape_position(index, m_plate_cols);
|
||||
m_plater->set_bed_position(pos);
|
||||
wxQueueEvent(m_plater, new SimpleEvent(EVT_GLCANVAS_PLATE_SELECT));
|
||||
//wxQueueEvent(m_plater, new SimpleEvent(EVT_GLCANVAS_PLATE_SELECT));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -3886,10 +4062,10 @@ void PartPlateList::render_for_picking_pass()
|
|||
return 0;
|
||||
}*/
|
||||
|
||||
void PartPlateList::set_render_option(bool bedtype_texture, bool bedtype_setting)
|
||||
void PartPlateList::set_render_option(bool bedtype_texture, bool plate_settings)
|
||||
{
|
||||
render_bedtype_logo = bedtype_texture;
|
||||
render_bedtype_setting = bedtype_setting;
|
||||
render_bedtype_logo = bedtype_texture;
|
||||
render_plate_settings = plate_settings;
|
||||
}
|
||||
|
||||
int PartPlateList::select_plate_by_obj(int obj_index, int instance_index)
|
||||
|
|
@ -4246,8 +4422,8 @@ int PartPlateList::store_to_3mf_structure(PlateDataPtrs& plate_data_list, bool w
|
|||
plate_data_item->objects_and_instances.emplace_back(it->first, it->second);
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ <<boost::format(": plate %1%, gcode_filename=%2%, with_slice_info=%3%, slice_valid %4%")
|
||||
%i %m_plate_list[i]->m_gcode_result->filename % with_slice_info %m_plate_list[i]->is_slice_result_valid();
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ <<boost::format(": plate %1%, gcode_filename=%2%, with_slice_info=%3%, slice_valid %4%, object item count %5%.")
|
||||
%i %m_plate_list[i]->m_gcode_result->filename % with_slice_info %m_plate_list[i]->is_slice_result_valid()%plate_data_item->objects_and_instances.size();
|
||||
|
||||
if (with_slice_info) {
|
||||
if (m_plate_list[i]->get_slice_result() && m_plate_list[i]->is_slice_result_valid()) {
|
||||
|
|
@ -4421,7 +4597,7 @@ void PartPlateList::BedTextureInfo::TexturePart::update_buffer()
|
|||
rectangle.push_back(Vec2d(x+w, y+h));
|
||||
rectangle.push_back(Vec2d(x, y+h));
|
||||
ExPolygon poly;
|
||||
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
const Vec2d & p = rectangle[i];
|
||||
for (auto& p : rectangle) {
|
||||
|
|
|
|||
|
|
@ -133,15 +133,12 @@ private:
|
|||
mutable unsigned int m_orient_vbo_id{ 0 };
|
||||
GeometryBuffer m_lock_icon;
|
||||
mutable unsigned int m_lock_vbo_id{ 0 };
|
||||
GeometryBuffer m_bedtype_icon;
|
||||
mutable unsigned int m_bedtype_vbo_id{ 0 };
|
||||
GeometryBuffer m_plate_settings_icon;
|
||||
mutable unsigned int m_plate_settings_vbo_id{ 0 };
|
||||
GeometryBuffer m_plate_idx_icon;
|
||||
mutable unsigned int m_plate_idx_vbo_id{ 0 };
|
||||
GLTexture m_texture;
|
||||
|
||||
// plate render option
|
||||
bool is_same_bedtype_with_global = true;
|
||||
|
||||
mutable float m_grabber_color[4];
|
||||
float m_scale_factor{ 1.0f };
|
||||
GLUquadricObject* m_quadric;
|
||||
|
|
@ -213,11 +210,21 @@ public:
|
|||
//clear alll the instances in plate
|
||||
void clear(bool clear_sliced_result = true);
|
||||
|
||||
BedType get_bed_type(bool check_global = true) const;
|
||||
BedType get_bed_type() const;
|
||||
void set_bed_type(BedType bed_type);
|
||||
void reset_bed_type();
|
||||
DynamicPrintConfig* config() { return &m_config; }
|
||||
|
||||
// set print sequence per plate
|
||||
//bool print_seq_same_global = true;
|
||||
void set_print_seq(PrintSequence print_seq = PrintSequence::ByDefault);
|
||||
PrintSequence get_print_seq() const;
|
||||
// Get the real effective print sequence of current plate.
|
||||
// If curr_plate's print_seq is ByDefault, use the global sequence
|
||||
// @return PrintSequence::{ByLayer,ByObject}
|
||||
PrintSequence get_real_print_seq() const;
|
||||
|
||||
|
||||
//static const int plate_x_offset = 20; //mm
|
||||
//static const double plate_x_gap = 0.2;
|
||||
ThumbnailData thumbnail_data;
|
||||
|
|
@ -258,7 +265,7 @@ public:
|
|||
|
||||
Vec3d get_origin() { return m_origin; }
|
||||
Vec3d estimate_wipe_tower_size(const double w, const double wipe_volume) const;
|
||||
std::vector<int> get_extruders() const;
|
||||
std::vector<int> get_extruders(bool conside_custom_gcode = false) const;
|
||||
std::vector<int> get_used_extruders();
|
||||
|
||||
/* instance related operations*/
|
||||
|
|
@ -283,6 +290,9 @@ public:
|
|||
//remove instance from plate
|
||||
int remove_instance(int obj_id, int instance_id);
|
||||
|
||||
//translate instance on the plate
|
||||
void translate_all_instance(Vec3d position);
|
||||
|
||||
//update instance exclude state
|
||||
void update_instance_exclude_status(int obj_id, int instance_id, BoundingBoxf3* bounding_box = nullptr);
|
||||
|
||||
|
|
@ -292,6 +302,8 @@ public:
|
|||
//whether it is empty
|
||||
bool empty() { return obj_to_instance_set.empty(); }
|
||||
|
||||
int printable_instance_size();
|
||||
|
||||
//whether it is has printable instances
|
||||
bool has_printable_instances();
|
||||
|
||||
|
|
@ -482,14 +494,14 @@ class PartPlateList : public ObjectBase
|
|||
GLTexture m_locked_hovered_texture;
|
||||
GLTexture m_lockopen_texture;
|
||||
GLTexture m_lockopen_hovered_texture;
|
||||
GLTexture m_bedtype_texture;
|
||||
GLTexture m_bedtype_changed_texture;
|
||||
GLTexture m_bedtype_hovered_texture;
|
||||
GLTexture m_bedtype_changed_hovered_texture;
|
||||
GLTexture m_plate_settings_texture;
|
||||
GLTexture m_plate_settings_changed_texture;
|
||||
GLTexture m_plate_settings_hovered_texture;
|
||||
GLTexture m_plate_settings_changed_hovered_texture;
|
||||
GLTexture m_idx_textures[MAX_PLATE_COUNT];
|
||||
// set render option
|
||||
bool render_bedtype_logo = true;
|
||||
bool render_bedtype_setting = true;
|
||||
bool render_plate_settings = true;
|
||||
|
||||
bool m_is_dark = false;
|
||||
|
||||
|
|
@ -559,11 +571,13 @@ public:
|
|||
~PartPlateList();
|
||||
|
||||
//this may be happened after machine changed
|
||||
void reset_size(int width, int depth, int height);
|
||||
void reset_size(int width, int depth, int height, bool reload_objects = true, bool update_shapes = false);
|
||||
//clear all the instances in the plate, but keep the plates
|
||||
void clear(bool delete_plates = false, bool release_print_list = false, bool except_locked = false, int plate_index = -1);
|
||||
//clear all the instances in the plate, and delete the plates, only keep the first default plate
|
||||
void reset(bool do_init);
|
||||
//compute the origin for printable plate with index i using new width
|
||||
Vec3d compute_origin_using_new_size(int i, int new_width, int new_depth);
|
||||
|
||||
//reset partplate to init states
|
||||
void reinit();
|
||||
|
|
@ -571,6 +585,11 @@ public:
|
|||
//get the plate stride
|
||||
double plate_stride_x();
|
||||
double plate_stride_y();
|
||||
void get_plate_size(int& width, int& depth, int& height) {
|
||||
width = m_plate_width;
|
||||
depth = m_plate_depth;
|
||||
height = m_plate_height;
|
||||
}
|
||||
|
||||
/*basic plate operations*/
|
||||
//create an empty plate and return its index
|
||||
|
|
@ -607,6 +626,10 @@ public:
|
|||
|
||||
PartPlate* get_selected_plate();
|
||||
|
||||
std::vector<PartPlate*> get_nonempty_plate_list();
|
||||
|
||||
std::vector<const GCodeProcessorResult*> get_nonempty_plates_slice_results();
|
||||
|
||||
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; }
|
||||
|
|
@ -683,7 +706,7 @@ public:
|
|||
void on_change_color_mode(bool is_dark) { m_is_dark = is_dark; }
|
||||
void render(bool bottom, bool only_current = false, bool only_body = false, int hover_id = -1);
|
||||
void render_for_picking_pass();
|
||||
void set_render_option(bool bedtype_texture, bool bedtype_settings);
|
||||
void set_render_option(bool bedtype_texture, bool plate_settings);
|
||||
BoundingBoxf3& get_bounding_box() { return m_bounding_box; }
|
||||
//int select_plate_by_hover_id(int hover_id);
|
||||
int select_plate_by_obj(int obj_index, int instance_index);
|
||||
|
|
|
|||
158
src/slic3r/GUI/PlateSettingsDialog.cpp
Normal file
158
src/slic3r/GUI/PlateSettingsDialog.cpp
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
#include "PlateSettingsDialog.hpp"
|
||||
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
wxDEFINE_EVENT(EVT_SET_BED_TYPE_CONFIRM, wxCommandEvent);
|
||||
|
||||
PlateSettingsDialog::PlateSettingsDialog(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
|
||||
:DPIDialog(parent, id, title, pos, size, style)
|
||||
{
|
||||
std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str();
|
||||
SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO));
|
||||
|
||||
SetBackgroundColour(*wxWHITE);
|
||||
wxBoxSizer* m_sizer_main = new wxBoxSizer(wxVERTICAL);
|
||||
auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(400), -1));
|
||||
m_line_top->SetBackgroundColour(wxColour(166, 169, 170));
|
||||
m_sizer_main->Add(m_line_top, 0, wxEXPAND, 0);
|
||||
m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(5));
|
||||
|
||||
wxFlexGridSizer* top_sizer = new wxFlexGridSizer(0, 2, FromDIP(5), 0);
|
||||
top_sizer->AddGrowableCol(0,1);
|
||||
top_sizer->SetFlexibleDirection(wxBOTH);
|
||||
top_sizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
|
||||
|
||||
m_bed_type_choice = new ComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(240),-1), 0, NULL, wxCB_READONLY );
|
||||
for (BedType i = btDefault; i < btCount; i = BedType(int(i) + 1)) {
|
||||
m_bed_type_choice->Append(to_bed_type_name(i));
|
||||
}
|
||||
wxStaticText* m_bed_type_txt = new wxStaticText(this, wxID_ANY, _L("Bed type"));
|
||||
m_bed_type_txt->SetFont(Label::Body_14);
|
||||
top_sizer->Add(m_bed_type_txt, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, FromDIP(5));
|
||||
top_sizer->Add(m_bed_type_choice, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT |wxALL, FromDIP(5));
|
||||
|
||||
wxBoxSizer* m_sizer_selectbox = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_print_seq_choice = new ComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(240),-1), 0, NULL, wxCB_READONLY );
|
||||
m_print_seq_choice->Append(_L("Same as Global Print Sequence"));
|
||||
for (auto i = PrintSequence::ByLayer; i < PrintSequence::ByDefault; i = PrintSequence(int(i) + 1)) {
|
||||
m_print_seq_choice->Append(to_print_sequence_name(i));
|
||||
}
|
||||
wxStaticText* m_print_seq_txt = new wxStaticText(this, wxID_ANY, _L("Print sequence"));
|
||||
m_print_seq_txt->SetFont(Label::Body_14);
|
||||
top_sizer->Add(m_print_seq_txt, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT |wxALL, FromDIP(5));
|
||||
top_sizer->Add(m_print_seq_choice, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT |wxALL, FromDIP(5));
|
||||
|
||||
m_sizer_main->Add(top_sizer, 0, wxEXPAND | wxALL, FromDIP(30));
|
||||
|
||||
auto sizer_button = new wxBoxSizer(wxHORIZONTAL);
|
||||
StateColor btn_bg_green(std::pair<wxColour, int>(wxColour(27, 136, 68), StateColor::Pressed), std::pair<wxColour, int>(wxColour(61, 203, 115), StateColor::Hovered),
|
||||
std::pair<wxColour, int>(wxColour(0, 174, 66), StateColor::Normal));
|
||||
|
||||
StateColor btn_bg_white(std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Pressed), std::pair<wxColour, int>(wxColour(238, 238, 238), StateColor::Hovered),
|
||||
std::pair<wxColour, int>(*wxWHITE, StateColor::Normal));
|
||||
|
||||
m_button_ok = new Button(this, _L("OK"));
|
||||
m_button_ok->SetBackgroundColor(btn_bg_green);
|
||||
m_button_ok->SetBorderColor(*wxWHITE);
|
||||
m_button_ok->SetTextColor(wxColour("#FFFFFE"));
|
||||
m_button_ok->SetFont(Label::Body_12);
|
||||
m_button_ok->SetSize(wxSize(FromDIP(58), FromDIP(24)));
|
||||
m_button_ok->SetMinSize(wxSize(FromDIP(58), FromDIP(24)));
|
||||
m_button_ok->SetCornerRadius(FromDIP(12));
|
||||
m_button_ok->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent& e) {
|
||||
wxCommandEvent evt(EVT_SET_BED_TYPE_CONFIRM, GetId());
|
||||
e.SetEventObject(this);
|
||||
GetEventHandler()->ProcessEvent(evt);
|
||||
if (this->IsModal())
|
||||
EndModal(wxID_YES);
|
||||
else
|
||||
this->Close();
|
||||
});
|
||||
|
||||
m_button_cancel = new Button(this, _L("Cancel"));
|
||||
m_button_cancel->SetBackgroundColor(btn_bg_white);
|
||||
m_button_cancel->SetBorderColor(wxColour(38, 46, 48));
|
||||
m_button_cancel->SetFont(Label::Body_12);
|
||||
m_button_cancel->SetSize(wxSize(FromDIP(58), FromDIP(24)));
|
||||
m_button_cancel->SetMinSize(wxSize(FromDIP(58), FromDIP(24)));
|
||||
m_button_cancel->SetCornerRadius(FromDIP(12));
|
||||
m_button_cancel->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent& e) {
|
||||
if (this->IsModal())
|
||||
EndModal(wxID_NO);
|
||||
else
|
||||
this->Close();
|
||||
});
|
||||
|
||||
sizer_button->AddStretchSpacer();
|
||||
sizer_button->Add(m_button_ok, 0, wxALL, FromDIP(5));
|
||||
sizer_button->Add(m_button_cancel, 0, wxALL, FromDIP(5));
|
||||
sizer_button->Add(FromDIP(30),0, 0, 0);
|
||||
|
||||
m_sizer_main->Add(sizer_button, 0, wxEXPAND, FromDIP(20));
|
||||
|
||||
SetSizer(m_sizer_main);
|
||||
Layout();
|
||||
m_sizer_main->Fit(this);
|
||||
|
||||
CenterOnParent();
|
||||
|
||||
wxGetApp().UpdateDlgDarkUI(this);
|
||||
}
|
||||
|
||||
PlateSettingsDialog::~PlateSettingsDialog()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void PlateSettingsDialog::sync_bed_type(BedType type)
|
||||
{
|
||||
if (m_bed_type_choice != nullptr) {
|
||||
m_bed_type_choice->SetSelection(int(type));
|
||||
}
|
||||
}
|
||||
|
||||
void PlateSettingsDialog::sync_print_seq(int print_seq)
|
||||
{
|
||||
if (m_print_seq_choice != nullptr) {
|
||||
m_print_seq_choice->SetSelection(print_seq);
|
||||
}
|
||||
}
|
||||
|
||||
wxString PlateSettingsDialog::to_bed_type_name(BedType bed_type) {
|
||||
switch (bed_type) {
|
||||
case btDefault:
|
||||
return _L("Same as Global Bed Type");
|
||||
case btPC:
|
||||
return _L("Cool Plate");
|
||||
case btEP:
|
||||
return _L("Engineering Plate");
|
||||
case btPEI:
|
||||
return _L("High Temp Plate");
|
||||
case btPTE:
|
||||
return _L("Textured PEI Plate");
|
||||
default:
|
||||
return _L("Same as Global Bed Type");
|
||||
}
|
||||
return _L("Same as Global Bed Type");
|
||||
}
|
||||
|
||||
wxString PlateSettingsDialog::to_print_sequence_name(PrintSequence print_seq) {
|
||||
switch (print_seq) {
|
||||
case PrintSequence::ByLayer:
|
||||
return _L("By Layer");
|
||||
case PrintSequence::ByObject:
|
||||
return _L("By Object");
|
||||
default:
|
||||
return _L("By Layer");
|
||||
}
|
||||
return _L("By Layer");
|
||||
}
|
||||
|
||||
void PlateSettingsDialog::on_dpi_changed(const wxRect& suggested_rect)
|
||||
{
|
||||
m_button_ok->Rescale();
|
||||
m_button_cancel->Rescale();
|
||||
}
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
61
src/slic3r/GUI/PlateSettingsDialog.hpp
Normal file
61
src/slic3r/GUI/PlateSettingsDialog.hpp
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
#ifndef slic3r_GUI_PlateSettingsDialog_hpp_
|
||||
#define slic3r_GUI_PlateSettingsDialog_hpp_
|
||||
|
||||
#include "Plater.hpp"
|
||||
#include "PartPlate.hpp"
|
||||
#include "Widgets/Button.hpp"
|
||||
#include "Widgets/RadioBox.hpp"
|
||||
#include "Widgets/ComboBox.hpp"
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
wxDECLARE_EVENT(EVT_SET_BED_TYPE_CONFIRM, wxCommandEvent);
|
||||
|
||||
class PlateSettingsDialog : public DPIDialog
|
||||
{
|
||||
public:
|
||||
enum ButtonStyle {
|
||||
ONLY_CONFIRM = 0,
|
||||
CONFIRM_AND_CANCEL = 1,
|
||||
MAX_STYLE_NUM = 2
|
||||
};
|
||||
PlateSettingsDialog(
|
||||
wxWindow* parent,
|
||||
wxWindowID id = wxID_ANY,
|
||||
const wxString& title = wxEmptyString,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = wxCLOSE_BOX | wxCAPTION
|
||||
);
|
||||
|
||||
~PlateSettingsDialog();
|
||||
void sync_bed_type(BedType type);
|
||||
void sync_print_seq(int print_seq = 0);
|
||||
wxString to_bed_type_name(BedType bed_type);
|
||||
wxString to_print_sequence_name(PrintSequence print_seq);
|
||||
void on_dpi_changed(const wxRect& suggested_rect) override;
|
||||
|
||||
int get_print_seq_choice() {
|
||||
int choice = 0;
|
||||
if (m_print_seq_choice != nullptr)
|
||||
choice = m_print_seq_choice->GetSelection();
|
||||
return choice;
|
||||
};
|
||||
|
||||
int get_bed_type_choice() {
|
||||
int choice = 0;
|
||||
if (m_bed_type_choice != nullptr)
|
||||
choice = m_bed_type_choice->GetSelection();
|
||||
return choice;
|
||||
};
|
||||
|
||||
protected:
|
||||
ComboBox* m_print_seq_choice { nullptr };
|
||||
ComboBox* m_bed_type_choice { nullptr };
|
||||
Button* m_button_ok;
|
||||
Button* m_button_cancel;
|
||||
};
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
|
||||
#endif
|
||||
|
|
@ -128,7 +128,7 @@
|
|||
|
||||
#include "PhysicalPrinterDialog.hpp"
|
||||
#include "PrintHostDialogs.hpp"
|
||||
#include "SetBedTypeDialog.hpp"
|
||||
#include "PlateSettingsDialog.hpp"
|
||||
|
||||
using boost::optional;
|
||||
namespace fs = boost::filesystem;
|
||||
|
|
@ -137,7 +137,7 @@ using Slic3r::Preset;
|
|||
using Slic3r::GUI::format_wxstr;
|
||||
using namespace nlohmann;
|
||||
|
||||
static const std::pair<unsigned int, unsigned int> THUMBNAIL_SIZE_3MF = { 256, 256 };
|
||||
static const std::pair<unsigned int, unsigned int> THUMBNAIL_SIZE_3MF = { 512, 512 };
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
|
@ -334,6 +334,7 @@ struct Sidebar::priv
|
|||
|
||||
bool is_collapsed {false};
|
||||
Search::OptionsSearcher searcher;
|
||||
std::string ams_list_device;
|
||||
|
||||
priv(Plater *plater) : plater(plater) {}
|
||||
~priv();
|
||||
|
|
@ -1360,7 +1361,7 @@ void Sidebar::on_filaments_change(size_t num_filaments)
|
|||
sizer->Hide(p->m_flushing_volume_btn);
|
||||
}
|
||||
|
||||
p->m_panel_filament_title->Layout();
|
||||
Layout();
|
||||
p->m_panel_filament_title->Refresh();
|
||||
update_ui_from_settings();
|
||||
dynamic_filament_list.update();
|
||||
|
|
@ -1374,13 +1375,12 @@ void Sidebar::on_bed_type_change(BedType bed_type)
|
|||
m_bed_type_list->SetSelection(sel_idx);
|
||||
}
|
||||
|
||||
void Sidebar::load_ams_list(std::map<std::string, Ams *> const &list)
|
||||
void Sidebar::load_ams_list(std::string const &device, std::map<std::string, Ams *> const &list)
|
||||
{
|
||||
std::vector<DynamicPrintConfig> filament_ams_list;
|
||||
for (auto ams : list) {
|
||||
char n = ams.first.front() - '0' + 'A';
|
||||
for (auto tray : ams.second->trayList) {
|
||||
if (tray.second->setting_id.empty()) continue;
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__
|
||||
<< boost::format(": ams %1% tray %2% id %3% color %4%") % ams.first % tray.first % tray.second->setting_id % tray.second->color;
|
||||
char t = tray.first.front() - '0' + '1';
|
||||
|
|
@ -1392,6 +1392,8 @@ void Sidebar::load_ams_list(std::map<std::string, Ams *> const &list)
|
|||
filament_ams_list.emplace_back(std::move(ams));
|
||||
}
|
||||
}
|
||||
p->ams_list_device = device;
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": %1% items") % filament_ams_list.size();
|
||||
wxGetApp().preset_bundle->filament_ams_list = filament_ams_list;
|
||||
for (auto c : p->combos_filament)
|
||||
c->update();
|
||||
|
|
@ -1407,10 +1409,34 @@ void Sidebar::sync_ams_list()
|
|||
dlg.ShowModal();
|
||||
return;
|
||||
}
|
||||
MessageDialog dlg(this,
|
||||
_L("Sync filaments with AMS will drop all current selected filament presets and colors. Do you want to continue?"),
|
||||
_L("Sync filaments with AMS"), wxYES_NO);
|
||||
if (dlg.ShowModal() != wxID_YES) return;
|
||||
std::string ams_filament_ids = wxGetApp().app_config->get("ams_filament_ids", p->ams_list_device);
|
||||
std::vector<std::string> list2;
|
||||
if (!ams_filament_ids.empty())
|
||||
boost::algorithm::split(list2, ams_filament_ids, boost::algorithm::is_any_of(","));
|
||||
struct SyncAmsDialog : MessageDialog {
|
||||
SyncAmsDialog(wxWindow * parent, bool first): MessageDialog(parent,
|
||||
first
|
||||
? _L("Sync filaments with AMS will drop all current selected filament presets and colors. Do you want to continue?")
|
||||
: _L("Already did a synchronization, do you want to sync only changes or resync all?"),
|
||||
_L("Sync filaments with AMS"), 0)
|
||||
{
|
||||
if (first) {
|
||||
add_button(wxID_YES, true, _L("Yes"));
|
||||
} else {
|
||||
add_button(wxID_OK, true, _L("Sync"));
|
||||
add_button(wxID_YES, false, _L("Resync"));
|
||||
}
|
||||
add_button(wxID_CANCEL, false, _L("Cancel"));
|
||||
}
|
||||
} dlg(this, ams_filament_ids.empty());
|
||||
auto res = dlg.ShowModal();
|
||||
if (res == wxID_CANCEL) return;
|
||||
list2.resize(list.size());
|
||||
for (int i = 0; i < list.size(); ++i) {
|
||||
auto filament_id = list[i].opt_string("filament_id", 0u);
|
||||
list[i].set_key_value("filament_changed", new ConfigOptionBool{res == wxID_YES || list2[i] != filament_id});
|
||||
list2[i] = filament_id;
|
||||
}
|
||||
unsigned int unknowns = 0;
|
||||
auto n = wxGetApp().preset_bundle->sync_ams_list(unknowns);
|
||||
if (n == 0) {
|
||||
|
|
@ -1420,6 +1446,8 @@ void Sidebar::sync_ams_list()
|
|||
dlg.ShowModal();
|
||||
return;
|
||||
}
|
||||
ams_filament_ids = boost::algorithm::join(list2, ",");
|
||||
wxGetApp().app_config ->set("ams_filament_ids", p->ams_list_device, ams_filament_ids);
|
||||
if (unknowns > 0) {
|
||||
MessageDialog dlg(this,
|
||||
_L("There are some unknown filaments mapped to generic preset. Please update Bambu Studio or restart Bambu Studio to check if there is an update to system presets."),
|
||||
|
|
@ -1429,7 +1457,7 @@ void Sidebar::sync_ams_list()
|
|||
wxGetApp().plater()->on_filaments_change(n);
|
||||
for (auto &c : p->combos_filament)
|
||||
c->update();
|
||||
wxGetApp().get_tab(Preset::TYPE_PRINT)->update();
|
||||
wxGetApp().get_tab(Preset::TYPE_FILAMENT)->select_preset(wxGetApp().preset_bundle->filament_presets[0]);
|
||||
wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config);
|
||||
dynamic_filament_list.update();
|
||||
}
|
||||
|
|
@ -1680,6 +1708,10 @@ struct Plater::priv
|
|||
bool m_is_slicing {false};
|
||||
bool m_is_publishing {false};
|
||||
int m_cur_slice_plate;
|
||||
//BBS: m_slice_all in .gcode.3mf file case, set true when slice all
|
||||
bool m_slice_all_only_has_gcode{ false };
|
||||
|
||||
bool m_need_update{false};
|
||||
//BBS: add popup object table logic
|
||||
//ObjectTableDialog* m_popup_table{ nullptr };
|
||||
|
||||
|
|
@ -1791,6 +1823,11 @@ struct Plater::priv
|
|||
priv(Plater *q, MainFrame *main_frame);
|
||||
~priv();
|
||||
|
||||
|
||||
bool need_update() const { return m_need_update; }
|
||||
void set_need_update(bool need_update) { m_need_update = need_update; }
|
||||
|
||||
void set_plater_dirty(bool is_dirty) { dirty_state.set_plater_dirty(is_dirty); }
|
||||
bool is_project_dirty() const { return dirty_state.is_dirty(); }
|
||||
bool is_presets_dirty() const { return dirty_state.is_presets_dirty(); }
|
||||
void update_project_dirty_from_presets()
|
||||
|
|
@ -2064,6 +2101,7 @@ struct Plater::priv
|
|||
|
||||
bool can_delete() const;
|
||||
bool can_delete_all() const;
|
||||
bool can_edit_text() const;
|
||||
bool can_add_plate() const;
|
||||
bool can_delete_plate() const;
|
||||
bool can_increase_instances() const;
|
||||
|
|
@ -2407,20 +2445,23 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
|||
preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_COLLAPSE_SIDEBAR, [this](SimpleEvent&) { this->q->collapse_sidebar(!this->q->is_sidebar_collapsed()); });
|
||||
preview->get_wxglcanvas()->Bind(EVT_CUSTOMEVT_TICKSCHANGED, [this](wxCommandEvent& event) {
|
||||
Type tick_event_type = (Type)event.GetInt();
|
||||
Model &model = wxGetApp().plater()->model();
|
||||
model.custom_gcode_per_print_z = preview->get_canvas3d()->get_gcode_viewer().get_layers_slider()->GetTicksValues();
|
||||
preview->on_tick_changed(tick_event_type);
|
||||
Model& model = wxGetApp().plater()->model();
|
||||
//BBS: replace model custom gcode with current plate custom gcode
|
||||
model.plates_custom_gcodes[model.curr_plate_index] = preview->get_canvas3d()->get_gcode_viewer().get_layers_slider()->GetTicksValues();
|
||||
|
||||
// BBS set to invalid state only
|
||||
if (tick_event_type == Type::ToolChange || tick_event_type == Type::Custom || tick_event_type == Type::Template) {
|
||||
if (tick_event_type == Type::ToolChange || tick_event_type == Type::Custom || tick_event_type == Type::Template || tick_event_type == Type::PausePrint) {
|
||||
PartPlate *plate = this->q->get_partplate_list().get_curr_plate();
|
||||
if (plate) {
|
||||
plate->update_slice_result_valid_state(false);
|
||||
}
|
||||
}
|
||||
|
||||
preview->on_tick_changed(tick_event_type);
|
||||
|
||||
// update slice and print button
|
||||
wxGetApp().mainframe->update_slice_print_status(MainFrame::SlicePrintEventType::eEventSliceUpdate, true, false);
|
||||
set_need_update(true);
|
||||
});
|
||||
}
|
||||
if (wxGetApp().is_gcode_viewer())
|
||||
|
|
@ -2893,6 +2934,8 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
|||
std::vector<size_t> empty_result;
|
||||
bool dlg_cont = true;
|
||||
bool is_user_cancel = false;
|
||||
bool translate_old = false;
|
||||
int current_width, current_depth, current_height;
|
||||
|
||||
if (input_files.empty()) { return std::vector<size_t>(); }
|
||||
|
||||
|
|
@ -3155,7 +3198,17 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
|||
return empty_result;
|
||||
}
|
||||
|
||||
Semver old_version(1, 5, 9);
|
||||
if ((en_3mf_file_type == En3mfType::From_BBS) && (file_version < old_version) && load_model && load_config && !config_loaded.empty()) {
|
||||
translate_old = true;
|
||||
partplate_list.get_plate_size(current_width, current_depth, current_height);
|
||||
}
|
||||
|
||||
if (load_config) {
|
||||
if (translate_old) {
|
||||
//set the size back
|
||||
partplate_list.reset_size(current_width + Bed3D::Axes::DefaultTipRadius, current_depth + Bed3D::Axes::DefaultTipRadius, current_height, false);
|
||||
}
|
||||
partplate_list.load_from_3mf_structure(plate_data);
|
||||
partplate_list.update_slice_context_to_current_plate(background_process);
|
||||
this->preview->update_gcode_result(partplate_list.get_current_slice_result());
|
||||
|
|
@ -3194,11 +3247,26 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
|||
config.apply(static_cast<const ConfigBase &>(FullPrintConfig::defaults()));
|
||||
// and place the loaded config over the base.
|
||||
config += std::move(config_loaded);
|
||||
std::map<std::string, std::string> validity = config.validate();
|
||||
if (!validity.empty()) {
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format("Param values in 3mf error: ");
|
||||
for (std::map<std::string, std::string>::iterator it=validity.begin(); it!=validity.end(); ++it)
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format("%1%: %2%")%it->first %it->second;
|
||||
//
|
||||
NotificationManager *notify_manager = q->get_notification_manager();
|
||||
std::string error_message = L("Invalid values found in the 3mf:");
|
||||
error_message += "\n";
|
||||
for (std::map<std::string, std::string>::iterator it=validity.begin(); it!=validity.end(); ++it)
|
||||
error_message += "-" + it->first + ": " + it->second + "\n";
|
||||
error_message += "\n";
|
||||
error_message += L("Please correct them in the param tabs");
|
||||
notify_manager->bbl_show_3mf_warn_notification(error_message);
|
||||
}
|
||||
}
|
||||
if (!config_substitutions.empty()) show_substitutions_info(config_substitutions.substitutions, filename.string());
|
||||
|
||||
this->model.custom_gcode_per_print_z = model.custom_gcode_per_print_z;
|
||||
// BBS
|
||||
this->model.plates_custom_gcodes = model.plates_custom_gcodes;
|
||||
this->model.design_info = model.design_info;
|
||||
this->model.model_info = model.model_info;
|
||||
}
|
||||
|
|
@ -3532,6 +3600,21 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
|||
|
||||
if (new_model) delete new_model;
|
||||
|
||||
//BBS: translate old 3mf to correct positions
|
||||
if (translate_old) {
|
||||
//translate the objects
|
||||
int plate_count = partplate_list.get_plate_count();
|
||||
for (int index = 1; index < plate_count; index ++) {
|
||||
PartPlate* cur_plate = (PartPlate *)partplate_list.get_plate(index);
|
||||
|
||||
Vec3d cur_origin = cur_plate->get_origin();
|
||||
Vec3d new_origin = partplate_list.compute_origin_using_new_size(index, current_width, current_depth);
|
||||
|
||||
cur_plate->translate_all_instance(new_origin - cur_origin);
|
||||
}
|
||||
partplate_list.reset_size(current_width, current_depth, current_height, true, true);
|
||||
}
|
||||
|
||||
//BBS: add gcode loading logic in the end
|
||||
q->m_exported_file = false;
|
||||
q->skip_thumbnail_invalid = false;
|
||||
|
|
@ -4020,7 +4103,8 @@ void Plater::priv::delete_all_objects_from_model()
|
|||
sidebar->obj_list()->delete_all_objects_from_list();
|
||||
object_list_changed();
|
||||
|
||||
model.custom_gcode_per_print_z.gcodes.clear();
|
||||
//BBS
|
||||
model.plates_custom_gcodes.clear();
|
||||
}
|
||||
|
||||
void Plater::priv::reset(bool apply_presets_change)
|
||||
|
|
@ -4070,7 +4154,8 @@ void Plater::priv::reset(bool apply_presets_change)
|
|||
else
|
||||
wxGetApp().load_current_presets(false, false);
|
||||
|
||||
model.custom_gcode_per_print_z.gcodes.clear();
|
||||
//BBS
|
||||
model.plates_custom_gcodes.clear();
|
||||
|
||||
// BBS
|
||||
m_saved_timestamp = m_backup_timestamp = size_t(-1);
|
||||
|
|
@ -5009,15 +5094,12 @@ void Plater::priv::reload_from_disk()
|
|||
new_volume->config.apply(old_volume->config);
|
||||
new_volume->set_type(old_volume->type());
|
||||
new_volume->set_material_id(old_volume->material_id());
|
||||
#if 0// ENABLE_WORLD_COORDINATE
|
||||
new_volume->set_transformation(Geometry::translation_transform(old_volume->source.transform.get_offset()) *
|
||||
old_volume->get_transformation().get_matrix_no_offset() * old_volume->source.transform.get_matrix_no_offset());
|
||||
new_volume->translate(new_volume->get_transformation().get_matrix_no_offset() * (new_volume->source.mesh_offset - old_volume->source.mesh_offset));
|
||||
#else
|
||||
new_volume->set_transformation(Geometry::assemble_transform(old_volume->source.transform.get_offset()) * old_volume->get_transformation().get_matrix(true) *
|
||||
old_volume->source.transform.get_matrix(true));
|
||||
new_volume->translate(new_volume->get_transformation().get_matrix(true) * (new_volume->source.mesh_offset - old_volume->source.mesh_offset));
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
Transform3d transform = Transform3d::Identity();
|
||||
transform.translate(new_volume->source.mesh_offset - old_volume->source.mesh_offset);
|
||||
new_volume->set_transformation(old_volume->get_transformation().get_matrix() * old_volume->source.transform.get_matrix(true) *
|
||||
transform * new_volume->source.transform.get_matrix(true).inverse());
|
||||
|
||||
new_volume->source.object_idx = old_volume->source.object_idx;
|
||||
new_volume->source.volume_idx = old_volume->source.volume_idx;
|
||||
assert(!old_volume->source.is_converted_from_inches || !old_volume->source.is_converted_from_meters);
|
||||
|
|
@ -5262,6 +5344,9 @@ void Plater::priv::set_current_panel(wxPanel* panel, bool no_slice)
|
|||
return;
|
||||
}
|
||||
|
||||
//BBS: wish to reset all plates stats item selected state when back to View3D Tab
|
||||
preview->get_canvas3d()->reset_select_plate_toolbar_selection();
|
||||
|
||||
wxPanel* old_panel = current_panel;
|
||||
//#if BBL_HAS_FIRST_PAGE
|
||||
if (!old_panel) {
|
||||
|
|
@ -5470,7 +5555,7 @@ void Plater::priv::on_select_bed_type(wxCommandEvent &evt)
|
|||
//update slice status
|
||||
auto plate_list = partplate_list.get_plate_list();
|
||||
for (auto plate : plate_list) {
|
||||
if (plate->get_bed_type(false) == btDefault) {
|
||||
if (plate->get_bed_type() == btDefault) {
|
||||
plate->update_slice_result_valid_state(false);
|
||||
}
|
||||
}
|
||||
|
|
@ -5553,12 +5638,9 @@ void Plater::priv::on_select_preset(wxCommandEvent &evt)
|
|||
Slic3r::put_other_changes();
|
||||
|
||||
// update slice state and set bedtype default for 3rd-party printer
|
||||
bool is_bbl_vendor_preset = wxGetApp().preset_bundle->printers.get_edited_preset().is_bbl_vendor_preset(wxGetApp().preset_bundle);
|
||||
auto plate_list = partplate_list.get_plate_list();
|
||||
for (auto plate : plate_list) {
|
||||
plate->update_slice_result_valid_state(false);
|
||||
if (!is_bbl_vendor_preset)
|
||||
plate->set_bed_type(btDefault);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5765,6 +5847,20 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt)
|
|||
//BBS: add project slice logic
|
||||
bool is_finished = !m_slice_all || (m_cur_slice_plate == (partplate_list.get_plate_count() - 1));
|
||||
|
||||
//BBS: slice .gcode.3mf file related logic, assign is_finished again
|
||||
bool only_has_gcode_need_preview = false;
|
||||
auto plate_list = this->partplate_list.get_plate_list();
|
||||
bool has_print_instances = false;
|
||||
for (auto plate : plate_list)
|
||||
has_print_instances = has_print_instances || plate->has_printable_instances();
|
||||
if (this->model.objects.empty() && !has_print_instances)
|
||||
only_has_gcode_need_preview = true;
|
||||
if (only_has_gcode_need_preview && m_slice_all_only_has_gcode) {
|
||||
is_finished = (m_cur_slice_plate == (partplate_list.get_plate_count() - 1));
|
||||
if (is_finished)
|
||||
m_slice_all_only_has_gcode = false;
|
||||
}
|
||||
|
||||
// Stop the background task, wait until the thread goes into the "Idle" state.
|
||||
// At this point of time the thread should be either finished or canceled,
|
||||
// so the following call just confirms, that the produced data were consumed.
|
||||
|
|
@ -5964,6 +6060,8 @@ void Plater::priv::on_action_add_plate(SimpleEvent&)
|
|||
if (q != nullptr) {
|
||||
take_snapshot("add partplate");
|
||||
this->partplate_list.create_plate();
|
||||
int new_plate = this->partplate_list.get_plate_count() - 1;
|
||||
this->partplate_list.select_plate(new_plate);
|
||||
update();
|
||||
|
||||
// BBS set default view
|
||||
|
|
@ -6013,12 +6111,15 @@ void Plater::priv::on_action_slice_all(SimpleEvent&)
|
|||
Plater::setExtruderParams(Slic3r::Model::extruderParamsMap);
|
||||
Plater::setPrintSpeedTable(Slic3r::Model::printSpeedMap);
|
||||
m_slice_all = true;
|
||||
m_slice_all_only_has_gcode = true;
|
||||
m_cur_slice_plate = 0;
|
||||
//select plate
|
||||
q->select_plate(m_cur_slice_plate);
|
||||
q->reslice();
|
||||
if (!m_is_publishing)
|
||||
q->select_view_3D("Preview");
|
||||
//BBS: wish to select all plates stats item
|
||||
preview->get_canvas3d()->_update_select_plate_toolbar_stats_item(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6398,7 +6499,9 @@ PlateBBoxData Plater::priv::generate_first_layer_bbox()
|
|||
std::vector<BBoxData>& id_bboxes = bboxdata.bbox_objs;
|
||||
BoundingBoxf bbox_all;
|
||||
auto print = this->background_process.m_fff_print;
|
||||
bboxdata.is_seq_print = (print->config().print_sequence == PrintSequence::ByObject);
|
||||
auto curr_plate = this->partplate_list.get_curr_plate();
|
||||
auto curr_plate_seq = curr_plate->get_real_print_seq();
|
||||
bboxdata.is_seq_print = (curr_plate_seq == PrintSequence::ByObject);
|
||||
bboxdata.first_extruder = print->get_tool_ordering().first_extruder();
|
||||
bboxdata.bed_type = bed_type_to_gcode_string(print->config().curr_bed_type.value);
|
||||
// get nozzle diameter
|
||||
|
|
@ -6890,7 +6993,7 @@ void Plater::priv::set_bed_shape(const Pointfs& shape, const Pointfs& exclude_ar
|
|||
double z = config->opt_float("printable_height");
|
||||
|
||||
//Pointfs& exclude_areas = config->option<ConfigOptionPoints>("bed_exclude_area")->values;
|
||||
partplate_list.reset_size(max.x() - min.x(), max.y() - min.y(), z);
|
||||
partplate_list.reset_size(max.x() - min.x() - Bed3D::Axes::DefaultTipRadius, max.y() - min.y() - Bed3D::Axes::DefaultTipRadius, z);
|
||||
partplate_list.set_shapes(shape, exclude_areas, custom_texture, height_to_lid, height_to_rod);
|
||||
|
||||
Vec2d new_shape_position = partplate_list.get_current_shape_position();
|
||||
|
|
@ -6909,6 +7012,24 @@ bool Plater::priv::can_delete_all() const
|
|||
return !model.objects.empty();
|
||||
}
|
||||
|
||||
bool Plater::priv::can_edit_text() const
|
||||
{
|
||||
const Selection &selection = view3D->get_canvas3d()->get_selection();
|
||||
if (selection.is_single_full_instance())
|
||||
return true;
|
||||
|
||||
if (selection.is_single_volume()) {
|
||||
const GLVolume *gl_volume = selection.get_volume(*selection.get_volume_idxs().begin());
|
||||
int out_object_idx = gl_volume->object_idx();
|
||||
ModelObject * model_object = selection.get_model()->objects[out_object_idx];
|
||||
int out_volume_idx = gl_volume->volume_idx();
|
||||
ModelVolume * model_volume = model_object->volumes[out_volume_idx];
|
||||
if (model_volume)
|
||||
return !model_volume->get_text_info().m_text.empty();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Plater::priv::can_add_plate() const
|
||||
{
|
||||
return q->get_partplate_list().get_plate_count() < PartPlateList::MAX_PLATES_COUNT;
|
||||
|
|
@ -7413,6 +7534,7 @@ bool Plater::Show(bool show)
|
|||
|
||||
bool Plater::is_project_dirty() const { return p->is_project_dirty(); }
|
||||
bool Plater::is_presets_dirty() const { return p->is_presets_dirty(); }
|
||||
void Plater::set_plater_dirty(bool is_dirty) { p->set_plater_dirty(is_dirty); }
|
||||
void Plater::update_project_dirty_from_presets() { p->update_project_dirty_from_presets(); }
|
||||
int Plater::save_project_if_dirty(const wxString& reason) { return p->save_project_if_dirty(reason); }
|
||||
void Plater::reset_project_dirty_after_save() { p->reset_project_dirty_after_save(); }
|
||||
|
|
@ -7452,8 +7574,10 @@ int Plater::new_project(bool skip_confirm, bool silent, const wxString& project_
|
|||
|
||||
m_only_gcode = false;
|
||||
m_exported_file = false;
|
||||
m_loading_project = false;
|
||||
get_notification_manager()->bbl_close_plateinfo_notification();
|
||||
get_notification_manager()->bbl_close_preview_only_notification();
|
||||
get_notification_manager()->bbl_close_3mf_warn_notification();
|
||||
|
||||
if (!silent)
|
||||
wxGetApp().mainframe->select_tab(MainFrame::tp3DEditor);
|
||||
|
|
@ -7478,7 +7602,12 @@ int Plater::new_project(bool skip_confirm, bool silent, const wxString& project_
|
|||
|
||||
Model m;
|
||||
model().load_from(m); // new id avoid same path name
|
||||
|
||||
//select first plate
|
||||
get_partplate_list().select_plate(0);
|
||||
SimpleEvent event(EVT_GLCANVAS_PLATE_SELECT);
|
||||
p->on_plate_selected(event);
|
||||
|
||||
p->load_auxiliary_files();
|
||||
wxGetApp().app_config->update_last_backup_dir(model().get_backup_path());
|
||||
|
||||
|
|
@ -7521,10 +7650,21 @@ void Plater::load_project(wxString const& filename2,
|
|||
//BBS: add only gcode mode
|
||||
bool previous_gcode = m_only_gcode;
|
||||
|
||||
// BBS
|
||||
if (m_loading_project) {
|
||||
//some error cases happens
|
||||
//return directly
|
||||
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": current loading other project, return directly");
|
||||
return;
|
||||
}
|
||||
else
|
||||
m_loading_project = true;
|
||||
|
||||
m_only_gcode = false;
|
||||
m_exported_file = false;
|
||||
get_notification_manager()->bbl_close_plateinfo_notification();
|
||||
get_notification_manager()->bbl_close_preview_only_notification();
|
||||
get_notification_manager()->bbl_close_3mf_warn_notification();
|
||||
|
||||
auto path = into_path(filename);
|
||||
|
||||
|
|
@ -7585,6 +7725,8 @@ void Plater::load_project(wxString const& filename2,
|
|||
up_to_date(true, true);
|
||||
|
||||
wxGetApp().params_panel()->switch_to_object_if_has_object_configs();
|
||||
|
||||
m_loading_project = false;
|
||||
}
|
||||
|
||||
// BBS: save logic
|
||||
|
|
@ -7624,15 +7766,15 @@ int Plater::save_project(bool saveAs)
|
|||
//BBS import model by model id
|
||||
void Plater::import_model_id(const std::string& download_info)
|
||||
{
|
||||
std::string download_url = "";
|
||||
std::string filename = "";
|
||||
std::string download_url = wxGetApp().get_download_model_url();
|
||||
std::string filename = wxGetApp().get_download_model_name();
|
||||
|
||||
auto selection_data_arr = wxSplit(download_info, '|');
|
||||
/* auto selection_data_arr = wxSplit(download_info, '|');
|
||||
|
||||
if (selection_data_arr.size() == 2) {
|
||||
download_url = selection_data_arr[0].ToStdString();
|
||||
filename = selection_data_arr[1].ToStdString();
|
||||
}
|
||||
if (selection_data_arr.size() == 2) {
|
||||
download_url = selection_data_arr[0].ToStdString();
|
||||
filename = selection_data_arr[1].ToStdString();
|
||||
}*/
|
||||
|
||||
|
||||
bool download_ok = false;
|
||||
|
|
@ -7809,10 +7951,9 @@ void Plater::download_project(const wxString& project_id)
|
|||
return;
|
||||
}
|
||||
|
||||
void Plater::request_model_download(std::string url, std::string filename)
|
||||
void Plater::request_model_download()
|
||||
{
|
||||
wxCommandEvent* event = new wxCommandEvent(EVT_IMPORT_MODEL_ID);
|
||||
event->SetString(wxString::Format("%s|%s", wxString(url), wxString(filename)));
|
||||
wxQueueEvent(this, event);
|
||||
}
|
||||
|
||||
|
|
@ -8365,7 +8506,13 @@ void Plater::force_update_all_plate_thumbnails()
|
|||
}
|
||||
|
||||
// BBS: backup
|
||||
std::vector<size_t> Plater::load_files(const std::vector<fs::path>& input_files, LoadStrategy strategy, bool ask_multi) { return p->load_files(input_files, strategy, ask_multi); }
|
||||
std::vector<size_t> Plater::load_files(const std::vector<fs::path>& input_files, LoadStrategy strategy, bool ask_multi) {
|
||||
//BBS: wish to reset state when load a new file
|
||||
p->m_slice_all_only_has_gcode = false;
|
||||
//BBS: wish to reset all plates stats item selected state when load a new file
|
||||
p->preview->get_canvas3d()->reset_select_plate_toolbar_selection();
|
||||
return p->load_files(input_files, strategy, ask_multi);
|
||||
}
|
||||
|
||||
// To be called when providing a list of files to the GUI slic3r on command line.
|
||||
std::vector<size_t> Plater::load_files(const std::vector<std::string>& input_files, LoadStrategy strategy, bool ask_multi)
|
||||
|
|
@ -8997,7 +9144,17 @@ void Plater::add_file()
|
|||
}
|
||||
}
|
||||
|
||||
void Plater::update() { p->update(); }
|
||||
void Plater::update(bool conside_update_flag)
|
||||
{
|
||||
if (conside_update_flag) {
|
||||
if (need_update()) {
|
||||
p->update();
|
||||
p->set_need_update(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
p->update();
|
||||
}
|
||||
|
||||
void Plater::object_list_changed() { p->object_list_changed(); }
|
||||
|
||||
|
|
@ -9091,6 +9248,18 @@ void Plater::delete_all_objects_from_model()
|
|||
p->delete_all_objects_from_model();
|
||||
}
|
||||
|
||||
void Plater::set_selected_visible(bool visible)
|
||||
{
|
||||
if (p->get_curr_selection().is_empty())
|
||||
return;
|
||||
|
||||
Plater::TakeSnapshot snapshot(this, "Set Selected Objects Visible in AssembleView");
|
||||
p->m_ui_jobs.cancel_all();
|
||||
|
||||
p->get_current_canvas3D()->set_selected_visible(visible);
|
||||
}
|
||||
|
||||
|
||||
void Plater::remove_selected()
|
||||
{
|
||||
/*if (p->get_selection().is_empty())
|
||||
|
|
@ -10358,6 +10527,24 @@ bool Plater::update_filament_colors_in_full_config()
|
|||
return true;
|
||||
}
|
||||
|
||||
void Plater::config_change_notification(const DynamicPrintConfig &config, const std::string& key)
|
||||
{
|
||||
GLCanvas3D* view3d_canvas = get_view3D_canvas3D();
|
||||
if (key == std::string("print_sequence")) {
|
||||
auto seq_print = config.option<ConfigOptionEnum<PrintSequence>>("print_sequence");
|
||||
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 = _u8L("Print By Object: \nSuggest to use auto-arrange to avoid collisions when printing.");
|
||||
notify_manager->bbl_show_seqprintinfo_notification(info_text);
|
||||
}
|
||||
else
|
||||
notify_manager->bbl_close_seqprintinfo_notification();
|
||||
}
|
||||
}
|
||||
// notification for more options
|
||||
}
|
||||
|
||||
void Plater::on_config_change(const DynamicPrintConfig &config)
|
||||
{
|
||||
bool update_scheduled = false;
|
||||
|
|
@ -10435,20 +10622,7 @@ void Plater::on_config_change(const DynamicPrintConfig &config)
|
|||
if (bed_shape_changed)
|
||||
set_bed_shape();
|
||||
|
||||
GLCanvas3D* view3d_canvas = get_view3D_canvas3D();
|
||||
auto seq_print = config.option<ConfigOptionEnum<PrintSequence>>("print_sequence");
|
||||
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 = _u8L("Print By Object: \nSuggest to use auto-arrange to avoid collisions when printing.");
|
||||
notify_manager->bbl_show_seqprintinfo_notification(info_text);
|
||||
//always show label when switch to sequence print
|
||||
//if (print_sequence_changed)
|
||||
// this->show_view3D_labels(true);
|
||||
}
|
||||
else
|
||||
notify_manager->bbl_close_seqprintinfo_notification();
|
||||
}
|
||||
config_change_notification(config, std::string("print_sequence"));
|
||||
|
||||
if (update_scheduled)
|
||||
update();
|
||||
|
|
@ -10553,7 +10727,6 @@ std::vector<std::string> Plater::get_extruder_colors_from_plater_config(const GC
|
|||
std::vector<std::string> Plater::get_colors_for_color_print(const GCodeProcessorResult* const result) const
|
||||
{
|
||||
std::vector<std::string> colors = get_extruder_colors_from_plater_config(result);
|
||||
colors.reserve(colors.size() + p->model.custom_gcode_per_print_z.gcodes.size());
|
||||
|
||||
if (wxGetApp().is_gcode_viewer() && result != nullptr) {
|
||||
for (const CustomGCode::Item& code : result->custom_gcode_per_print_z) {
|
||||
|
|
@ -10562,7 +10735,9 @@ std::vector<std::string> Plater::get_colors_for_color_print(const GCodeProcessor
|
|||
}
|
||||
}
|
||||
else {
|
||||
for (const CustomGCode::Item& code : p->model.custom_gcode_per_print_z.gcodes) {
|
||||
//BBS
|
||||
colors.reserve(colors.size() + p->model.get_curr_plate_custom_gcodes().gcodes.size());
|
||||
for (const CustomGCode::Item& code : p->model.get_curr_plate_custom_gcodes().gcodes) {
|
||||
if (code.type == CustomGCode::ColorChange)
|
||||
colors.emplace_back(code.color);
|
||||
}
|
||||
|
|
@ -11197,6 +11372,10 @@ int Plater::select_plate_by_hover_id(int hover_id, bool right_click)
|
|||
{
|
||||
//select plate
|
||||
ret = p->partplate_list.select_plate(plate_index);
|
||||
if (!ret) {
|
||||
SimpleEvent event(EVT_GLCANVAS_PLATE_SELECT);
|
||||
p->on_plate_selected(event);
|
||||
}
|
||||
if ((!ret)&&(p->background_process.can_switch_print()))
|
||||
{
|
||||
//select successfully
|
||||
|
|
@ -11317,15 +11496,38 @@ int Plater::select_plate_by_hover_id(int hover_id, bool right_click)
|
|||
//set the plate type
|
||||
ret = select_plate(plate_index);
|
||||
if (!ret) {
|
||||
SetBedTypeDialog dlg(this, wxID_ANY, _L("Select Bed Type"));
|
||||
PlateSettingsDialog dlg(this, wxID_ANY, _L("Plate Settings"));
|
||||
PartPlate* curr_plate = p->partplate_list.get_curr_plate();
|
||||
dlg.sync_bed_type(curr_plate->get_bed_type(false));
|
||||
dlg.Bind(EVT_SET_BED_TYPE_CONFIRM, [this, plate_index](wxCommandEvent& e) {
|
||||
dlg.sync_bed_type(curr_plate->get_bed_type());
|
||||
|
||||
auto curr_print_seq = curr_plate->get_print_seq();
|
||||
if (curr_print_seq != PrintSequence::ByDefault) {
|
||||
dlg.sync_print_seq(int(curr_print_seq) + 1);
|
||||
}
|
||||
else
|
||||
dlg.sync_print_seq(0);
|
||||
|
||||
dlg.Bind(EVT_SET_BED_TYPE_CONFIRM, [this, plate_index, &dlg](wxCommandEvent& e) {
|
||||
PartPlate *curr_plate = p->partplate_list.get_curr_plate();
|
||||
BedType old_bed_type = curr_plate->get_bed_type(false);
|
||||
auto type = (BedType)(e.GetInt());
|
||||
p->partplate_list.get_curr_plate()->set_bed_type(type);
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("select bed type %1% for plate %2% at plate side")%type %plate_index;
|
||||
BedType old_bed_type = curr_plate->get_bed_type();
|
||||
auto bt_sel = BedType(dlg.get_bed_type_choice());
|
||||
if (old_bed_type != bt_sel) {
|
||||
curr_plate->set_bed_type(bt_sel);
|
||||
update_project_dirty_from_presets();
|
||||
set_plater_dirty(true);
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("select bed type %1% for plate %2% at plate side")%bt_sel %plate_index;
|
||||
|
||||
int ps_sel = dlg.get_print_seq_choice();
|
||||
if (ps_sel != 0)
|
||||
curr_plate->set_print_seq(PrintSequence(ps_sel - 1));
|
||||
else
|
||||
curr_plate->set_print_seq(PrintSequence::ByDefault);
|
||||
update_project_dirty_from_presets();
|
||||
set_plater_dirty(true);
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("select print sequence %1% for plate %2% at plate side")%ps_sel %plate_index;
|
||||
auto plate_config = *(curr_plate->config());
|
||||
wxGetApp().plater()->config_change_notification(plate_config, std::string("print_sequence"));
|
||||
});
|
||||
dlg.ShowModal();
|
||||
|
||||
|
|
@ -11468,13 +11670,15 @@ void Plater::show_object_info()
|
|||
wxString info_manifold;
|
||||
int non_manifold_edges = 0;
|
||||
auto mesh_errors = p->sidebar->obj_list()->get_mesh_errors_info(&info_manifold, &non_manifold_edges);
|
||||
info_text += into_u8(info_manifold);
|
||||
|
||||
#ifndef __WINDOWS__
|
||||
if (non_manifold_edges > 0) {
|
||||
info_text += into_u8("\n" + _L("Tips:") + "\n" +_L("\"Fix Model\" feature is currently only on Windows. Please repair the model on Bambu Studio(windows) or CAD softwares."));
|
||||
info_manifold += into_u8("\n" + _L("Tips:") + "\n" +_L("\"Fix Model\" feature is currently only on Windows. Please repair the model on Bambu Studio(windows) or CAD softwares."));
|
||||
}
|
||||
#endif //APPLE & LINUX
|
||||
|
||||
info_manifold = "<Error>" + info_manifold + "</Error>";
|
||||
info_text += into_u8(info_manifold);
|
||||
notify_manager->bbl_show_objectsinfo_notification(info_text, is_windows10()&&(non_manifold_edges > 0), !(p->current_panel == p->view3D));
|
||||
}
|
||||
|
||||
|
|
@ -11496,7 +11700,8 @@ void Plater::post_process_string_object_exception(StringObjectException &err)
|
|||
break;
|
||||
}
|
||||
}
|
||||
err.string = format(_L("Plate %d: %s does not support filament %s (%s)."), err.params[0], err.params[1], err.params[2], filament_name);
|
||||
err.string = format(_L("Plate% d: %s is not suggested to be used to print filament %s(%s). If you still want to do this printing, please set this filament's bed temperature to non zero."),
|
||||
err.params[0], err.params[1], err.params[2], filament_name);
|
||||
err.string += "\n";
|
||||
}
|
||||
} catch (...) {
|
||||
|
|
@ -11590,6 +11795,14 @@ void Plater::show_status_message(std::string s)
|
|||
BOOST_LOG_TRIVIAL(trace) << "show_status_message:" << s;
|
||||
}
|
||||
|
||||
void Plater::edit_text()
|
||||
{
|
||||
auto &manager = get_view3D_canvas3D()->get_gizmos_manager();
|
||||
manager.open_gizmo(GLGizmosManager::Text);
|
||||
update();
|
||||
}
|
||||
|
||||
bool Plater::can_edit_text() const { return p->can_edit_text(); }
|
||||
bool Plater::can_delete() const { return p->can_delete(); }
|
||||
bool Plater::can_delete_all() const { return p->can_delete_all(); }
|
||||
bool Plater::can_add_model() const { return !is_background_process_slicing(); }
|
||||
|
|
@ -11729,6 +11942,16 @@ void Plater::bring_instance_forward()
|
|||
p->bring_instance_forward();
|
||||
}
|
||||
|
||||
bool Plater::need_update() const
|
||||
{
|
||||
return p->need_update();
|
||||
}
|
||||
|
||||
void Plater::set_need_update(bool need_update)
|
||||
{
|
||||
p->set_need_update(need_update);
|
||||
}
|
||||
|
||||
// BBS
|
||||
//BBS: add popup logic for table object
|
||||
bool Plater::PopupObjectTable(int object_id, int volume_id, const wxPoint& position)
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ public:
|
|||
void on_filaments_change(size_t num_filaments);
|
||||
// BBS
|
||||
void on_bed_type_change(BedType bed_type);
|
||||
void load_ams_list(std::map<std::string, Ams *> const &list);
|
||||
void load_ams_list(std::string const & device, std::map<std::string, Ams *> const &list);
|
||||
void sync_ams_list();
|
||||
|
||||
ObjectList* obj_list();
|
||||
|
|
@ -189,6 +189,7 @@ public:
|
|||
|
||||
bool is_project_dirty() const;
|
||||
bool is_presets_dirty() const;
|
||||
void set_plater_dirty(bool is_dirty);
|
||||
void update_project_dirty_from_presets();
|
||||
int save_project_if_dirty(const wxString& reason);
|
||||
void reset_project_dirty_after_save();
|
||||
|
|
@ -212,7 +213,7 @@ public:
|
|||
//BBS download project by project id
|
||||
void import_model_id(const std::string& download_info);
|
||||
void download_project(const wxString& project_id);
|
||||
void request_model_download(std::string url, std::string filename);
|
||||
void request_model_download();
|
||||
void request_download_project(std::string project_id);
|
||||
// BBS: check snapshot
|
||||
bool up_to_date(bool saved, bool backup);
|
||||
|
|
@ -265,7 +266,7 @@ public:
|
|||
|
||||
const wxString& get_last_loaded_gcode() const { return m_last_loaded_gcode; }
|
||||
|
||||
void update();
|
||||
void update(bool conside_update_flag = false);
|
||||
//BBS
|
||||
void object_list_changed();
|
||||
void stop_jobs();
|
||||
|
|
@ -303,6 +304,7 @@ public:
|
|||
void trigger_restore_project(int skip_confirm = 0);
|
||||
void delete_object_from_model(size_t obj_idx, bool refresh_immediately = true); // BBS support refresh immediately
|
||||
void delete_all_objects_from_model(); //BBS delete all objects from model
|
||||
void set_selected_visible(bool visible);
|
||||
void remove_selected();
|
||||
void increase_instances(size_t num = 1);
|
||||
void decrease_instances(size_t num = 1);
|
||||
|
|
@ -388,6 +390,7 @@ public:
|
|||
// BBS
|
||||
void on_bed_type_change(BedType bed_type);
|
||||
bool update_filament_colors_in_full_config();
|
||||
void config_change_notification(const DynamicPrintConfig &config, const std::string& key);
|
||||
void on_config_change(const DynamicPrintConfig &config);
|
||||
void force_filament_colors_update();
|
||||
void force_print_bed_update();
|
||||
|
|
@ -453,6 +456,10 @@ public:
|
|||
//BBS:
|
||||
void fill_color(int extruder_id);
|
||||
|
||||
//BBS:
|
||||
void edit_text();
|
||||
bool can_edit_text() const;
|
||||
|
||||
bool can_delete() const;
|
||||
bool can_delete_all() const;
|
||||
bool can_add_model() const;
|
||||
|
|
@ -567,6 +574,9 @@ public:
|
|||
|
||||
void bring_instance_forward();
|
||||
|
||||
bool need_update() const;
|
||||
void set_need_update(bool need_update);
|
||||
|
||||
// ROII wrapper for suppressing the Undo / Redo snapshot to be taken.
|
||||
class SuppressSnapshots
|
||||
{
|
||||
|
|
@ -692,6 +702,7 @@ private:
|
|||
bool m_only_gcode { false };
|
||||
bool m_exported_file { false };
|
||||
bool skip_thumbnail_invalid { false };
|
||||
bool m_loading_project {false };
|
||||
std::string m_preview_only_filename;
|
||||
int m_valid_plates_count { 0 };
|
||||
|
||||
|
|
|
|||
|
|
@ -110,8 +110,6 @@ wxBoxSizer *PreferencesDialog::create_item_language_combobox(
|
|||
auto language_name = vlist[i]->Description;
|
||||
|
||||
if (vlist[i] == wxLocale::GetLanguageInfo(wxLANGUAGE_CHINESE_SIMPLIFIED)) {
|
||||
//language_name = _L(vlist[i]->Description);
|
||||
//language_name = _L("Chinese (Simplified)");
|
||||
language_name = wxString::FromUTF8("\xe4\xb8\xad\xe6\x96\x87\x28\xe7\xae\x80\xe4\xbd\x93\x29");
|
||||
}
|
||||
else if (vlist[i] == wxLocale::GetLanguageInfo(wxLANGUAGE_SPANISH)) {
|
||||
|
|
@ -132,6 +130,9 @@ wxBoxSizer *PreferencesDialog::create_item_language_combobox(
|
|||
else if (vlist[i] == wxLocale::GetLanguageInfo(wxLANGUAGE_HUNGARIAN)) {
|
||||
language_name = wxString::FromUTF8("Magyar");
|
||||
}
|
||||
else if (vlist[i] == wxLocale::GetLanguageInfo(wxLANGUAGE_JAPANESE)) {
|
||||
language_name = wxString::FromUTF8("\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E");
|
||||
}
|
||||
|
||||
if (app_config->get(param) == vlist[i]->CanonicalName) {
|
||||
m_current_language_selected = i;
|
||||
|
|
@ -157,7 +158,7 @@ wxBoxSizer *PreferencesDialog::create_item_language_combobox(
|
|||
if (wxGetApp().plater()->is_project_dirty()) {
|
||||
auto result = MessageDialog(static_cast<wxWindow*>(this), _L("The current project has unsaved changes, save it before continue?"),
|
||||
wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Save"), wxYES_NO | wxCANCEL | wxYES_DEFAULT | wxCENTRE).ShowModal();
|
||||
|
||||
|
||||
if (result == wxID_YES) {
|
||||
wxGetApp().plater()->save_project();
|
||||
}
|
||||
|
|
@ -241,7 +242,7 @@ wxBoxSizer *PreferencesDialog::create_item_region_combobox(wxString title, wxWin
|
|||
auto region_index = e.GetSelection();
|
||||
auto region = local_regions[region_index];
|
||||
|
||||
auto area = "";
|
||||
/*auto area = "";
|
||||
if (region == "CHN" || region == "China")
|
||||
area = "CN";
|
||||
else if (region == "USA")
|
||||
|
|
@ -253,7 +254,7 @@ wxBoxSizer *PreferencesDialog::create_item_region_combobox(wxString title, wxWin
|
|||
else if (region == "North America")
|
||||
area = "US";
|
||||
else
|
||||
area = "Others";
|
||||
area = "Others";*/
|
||||
|
||||
NetworkAgent* agent = wxGetApp().getAgent();
|
||||
AppConfig* config = GUI::wxGetApp().app_config;
|
||||
|
|
@ -265,10 +266,11 @@ wxBoxSizer *PreferencesDialog::create_item_region_combobox(wxString title, wxWin
|
|||
return;
|
||||
} else {
|
||||
wxGetApp().request_user_logout();
|
||||
config->set("region", region.ToStdString());
|
||||
auto area = config->get_country_code();
|
||||
if (agent) {
|
||||
agent->set_country_code(area);
|
||||
}
|
||||
config->set("region", region.ToStdString());
|
||||
EndModal(wxID_CANCEL);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -497,7 +499,7 @@ wxBoxSizer* PreferencesDialog::create_item_darkmode_checkbox(wxString title, wxW
|
|||
#ifdef _MSW_DARK_MODE
|
||||
wxGetApp().force_colors_update();
|
||||
wxGetApp().update_ui_from_settings();
|
||||
set_dark_mode();
|
||||
set_dark_mode();
|
||||
#endif
|
||||
SimpleEvent evt = SimpleEvent(EVT_GLCANVAS_COLOR_MODE_CHANGED);
|
||||
wxPostEvent(wxGetApp().plater(), evt);
|
||||
|
|
@ -729,7 +731,7 @@ void PreferencesDialog::create()
|
|||
Layout();
|
||||
Fit();
|
||||
int screen_height = wxGetDisplaySize().GetY();
|
||||
if (this->GetSize().GetY() > screen_height)
|
||||
if (this->GetSize().GetY() > screen_height)
|
||||
this->SetSize(this->GetSize().GetX() + FromDIP(40), screen_height * 4 / 5);
|
||||
|
||||
CenterOnParent();
|
||||
|
|
@ -789,7 +791,9 @@ wxWindow* PreferencesDialog::create_general_page()
|
|||
wxLANGUAGE_SPANISH,
|
||||
wxLANGUAGE_SWEDISH,
|
||||
wxLANGUAGE_DUTCH,
|
||||
wxLANGUAGE_HUNGARIAN };
|
||||
wxLANGUAGE_HUNGARIAN,
|
||||
wxLANGUAGE_JAPANESE
|
||||
};
|
||||
|
||||
auto translations = wxTranslations::Get()->GetAvailableTranslations(SLIC3R_APP_KEY);
|
||||
std::vector<const wxLanguageInfo *> language_infos;
|
||||
|
|
@ -848,7 +852,7 @@ wxWindow* PreferencesDialog::create_general_page()
|
|||
auto title_darkmode = create_item_title(_L("Dark Mode"), page, _L("Dark Mode"));
|
||||
auto item_darkmode = create_item_darkmode_checkbox(_L("Enable Dark mode"), page,_L("Enable Dark mode"), 50, "dark_color_mode");
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
sizer_page->Add(title_general_settings, 0, wxEXPAND, 0);
|
||||
sizer_page->Add(item_language, 0, wxTOP, FromDIP(3));
|
||||
|
|
@ -953,9 +957,10 @@ void PreferencesDialog::create_shortcuts_page()
|
|||
sizer_page->Fit(page);
|
||||
}
|
||||
|
||||
wxBoxSizer* PreferencesDialog::create_debug_page()
|
||||
wxWindow* PreferencesDialog::create_debug_page()
|
||||
{
|
||||
//wxBoxSizer *sizer_page = new wxBoxSizer(wxVERTICAL);
|
||||
auto page = new wxWindow(m_scrolledWindow, wxID_ANY);
|
||||
page->SetBackgroundColour(*wxWHITE);
|
||||
|
||||
m_developer_mode_def = app_config->get("developer_mode");
|
||||
m_dump_video_def = app_config->get("dump_video");
|
||||
|
|
@ -964,19 +969,19 @@ wxBoxSizer* PreferencesDialog::create_debug_page()
|
|||
|
||||
wxBoxSizer *bSizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
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_develop_mode = create_item_title(_L("Develop mode"), page, _L("Develop mode"));
|
||||
auto item_develop_mode = create_item_checkbox(_L("Develop mode"), page, _L("Develop mode"), 50, "developer_mode");
|
||||
auto item_dump_video = create_item_checkbox(_L("Dump video"), page, _L("Dump video"), 50, "dump_video");
|
||||
|
||||
auto title_log_level = create_item_title(_L("Log Level"), m_scrolledWindow, _L("Log Level"));
|
||||
auto title_log_level = create_item_title(_L("Log Level"), page, _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"), m_scrolledWindow, _L("Log Level"), log_level_list);
|
||||
auto loglevel_combox = create_item_loglevel_combobox(_L("Log Level"), page, _L("Log Level"), log_level_list);
|
||||
|
||||
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");
|
||||
auto title_host = create_item_title(_L("Host Setting"), page, _L("Host Setting"));
|
||||
auto radio1 = create_item_radiobox(_L("DEV host: api-dev.bambu-lab.com/v1"), page, wxEmptyString, 50, 1, "dev_host");
|
||||
auto radio2 = create_item_radiobox(_L("QA host: api-qa.bambu-lab.com/v1"), page, wxEmptyString, 50, 1, "qa_host");
|
||||
auto radio3 = create_item_radiobox(_L("PRE host: api-pre.bambu-lab.com/v1"), page, wxEmptyString, 50, 1, "pre_host");
|
||||
auto radio4 = create_item_radiobox(_L("Product host"), page, wxEmptyString, 50, 1, "product_host");
|
||||
|
||||
if (m_iot_environment_def == ENV_DEV_HOST) {
|
||||
on_select_radio("dev_host");
|
||||
|
|
@ -994,7 +999,7 @@ wxBoxSizer* PreferencesDialog::create_debug_page()
|
|||
std::pair<wxColour, int>(AMS_CONTROL_WHITE_COLOUR, StateColor::Normal));
|
||||
StateColor btn_bd_white(std::pair<wxColour, int>(AMS_CONTROL_WHITE_COLOUR, StateColor::Disabled), std::pair<wxColour, int>(wxColour(38, 46, 48), StateColor::Enabled));
|
||||
|
||||
Button* debug_button = new Button(m_scrolledWindow, _L("debug save button"));
|
||||
Button* debug_button = new Button(page, _L("debug save button"));
|
||||
debug_button->SetBackgroundColor(btn_bg_white);
|
||||
debug_button->SetBorderColor(btn_bd_white);
|
||||
debug_button->SetFont(Label::Body_13);
|
||||
|
|
@ -1063,7 +1068,9 @@ wxBoxSizer* PreferencesDialog::create_debug_page()
|
|||
wxGetApp().request_user_logout();
|
||||
agent->set_country_code(country_code);
|
||||
}
|
||||
wxMessageBox(_L("Switch cloud environment, Please login again!"));
|
||||
ConfirmBeforeSendDialog confirm_dlg(this, wxID_ANY, _L("Warning"), ConfirmBeforeSendDialog::ButtonStyle::ONLY_CONFIRM);
|
||||
confirm_dlg.update_text(_L("Switch cloud environment, Please login again!"));
|
||||
confirm_dlg.on_show();
|
||||
}
|
||||
|
||||
// bbs backup
|
||||
|
|
@ -1098,7 +1105,11 @@ wxBoxSizer* PreferencesDialog::create_debug_page()
|
|||
bSizer->Add(radio3, 0, wxEXPAND | wxTOP, FromDIP(3));
|
||||
bSizer->Add(radio4, 0, wxEXPAND | wxTOP, FromDIP(3));
|
||||
bSizer->Add(debug_button, 0, wxALIGN_CENTER_HORIZONTAL | wxTOP, FromDIP(15));
|
||||
return bSizer;
|
||||
|
||||
page->SetSizer(bSizer);
|
||||
page->Layout();
|
||||
bSizer->Fit(page);
|
||||
return page;
|
||||
}
|
||||
|
||||
void PreferencesDialog::on_select_radio(std::string param)
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ public:
|
|||
void create_gui_page();
|
||||
void create_sync_page();
|
||||
void create_shortcuts_page();
|
||||
wxBoxSizer* create_debug_page();
|
||||
wxWindow* create_debug_page();
|
||||
|
||||
void on_select_radio(std::string param);
|
||||
wxString get_select_radio(int groupid);
|
||||
|
|
|
|||
|
|
@ -376,8 +376,14 @@ void PresetComboBox::add_ams_filaments(std::string selected, bool alias_name)
|
|||
auto &filaments = m_collection->get_presets();
|
||||
for (auto &f : m_preset_bundle->filament_ams_list) {
|
||||
std::string filament_id = f.opt_string("filament_id", 0u);
|
||||
if (filament_id.empty()) continue;
|
||||
auto iter = std::find_if(filaments.begin(), filaments.end(),
|
||||
[&filament_id](auto &f) { return f.is_compatible && f.is_system && f.filament_id == filament_id; });
|
||||
if (iter == filaments.end()) {
|
||||
auto filament_type = "Generic " + f.opt_string("filament_type", 0u);
|
||||
iter = std::find_if(filaments.begin(), filaments.end(),
|
||||
[&filament_type](auto &f) { return f.is_compatible && f.is_system && boost::algorithm::starts_with(f.name, filament_type); });
|
||||
}
|
||||
if (iter == filaments.end()) {
|
||||
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": filament_id %1% not found or system or compatible") % filament_id;
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -23,11 +23,6 @@ extern "C" {
|
|||
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
|
||||
/* We need these workarounds since we're compiling C source, not C++. */
|
||||
typedef enum Bambu_StreamType Bambu_StreamType;
|
||||
typedef struct Bambu_StreamInfo Bambu_StreamInfo;
|
||||
typedef struct Bambu_Sample Bambu_Sample;
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
|
|
@ -40,31 +35,33 @@ typedef void* Bambu_Tunnel;
|
|||
|
||||
typedef void (*Logger)(void * context, int level, tchar const* msg);
|
||||
|
||||
enum Bambu_StreamType
|
||||
typedef enum __Bambu_StreamType
|
||||
{
|
||||
VIDE,
|
||||
AUDI
|
||||
};
|
||||
} Bambu_StreamType;
|
||||
|
||||
enum Bambu_VideoSubType
|
||||
typedef enum __Bambu_VideoSubType
|
||||
{
|
||||
AVC1,
|
||||
};
|
||||
MJPG,
|
||||
} Bambu_VideoSubType;
|
||||
|
||||
enum Bambu_AudioSubType
|
||||
typedef enum __Bambu_AudioSubType
|
||||
{
|
||||
MP4A
|
||||
};
|
||||
} Bambu_AudioSubType;
|
||||
|
||||
enum Bambu_FormatType
|
||||
typedef enum __Bambu_FormatType
|
||||
{
|
||||
video_avc_packet,
|
||||
video_avc_byte_stream,
|
||||
video_jpeg,
|
||||
audio_raw,
|
||||
audio_adts
|
||||
};
|
||||
} Bambu_FormatType;
|
||||
|
||||
struct Bambu_StreamInfo
|
||||
typedef struct __Bambu_StreamInfo
|
||||
{
|
||||
Bambu_StreamType type;
|
||||
int sub_type;
|
||||
|
|
@ -84,33 +81,34 @@ struct Bambu_StreamInfo
|
|||
} format;
|
||||
int format_type;
|
||||
int format_size;
|
||||
int max_frame_size;
|
||||
unsigned char const * format_buffer;
|
||||
};
|
||||
} Bambu_StreamInfo;
|
||||
|
||||
enum Bambu_SampleFlag
|
||||
typedef enum __Bambu_SampleFlag
|
||||
{
|
||||
f_sync = 1
|
||||
};
|
||||
} Bambu_SampleFlag;
|
||||
|
||||
struct Bambu_Sample
|
||||
typedef struct __Bambu_Sample
|
||||
{
|
||||
int itrack;
|
||||
int size;
|
||||
int flags;
|
||||
unsigned char const * buffer;
|
||||
unsigned long long decode_time;
|
||||
};
|
||||
} Bambu_Sample;
|
||||
|
||||
enum Bambu_Error
|
||||
typedef enum __Bambu_Error
|
||||
{
|
||||
Bambu_success,
|
||||
Bambu_stream_end,
|
||||
Bambu_would_block,
|
||||
Bambu_would_block,
|
||||
Bambu_buffer_limit
|
||||
};
|
||||
} Bambu_Error;
|
||||
|
||||
#ifdef BAMBU_DYNAMIC
|
||||
struct BambuLib {
|
||||
typedef struct __BambuLib {
|
||||
#endif
|
||||
|
||||
BAMBU_EXPORT int BAMBU_FUNC(Bambu_Create)(Bambu_Tunnel* tunnel, char const* path);
|
||||
|
|
@ -148,7 +146,7 @@ BAMBU_EXPORT char const* BAMBU_FUNC(Bambu_GetLastErrorMsg)();
|
|||
BAMBU_EXPORT void BAMBU_FUNC(Bambu_FreeLogMsg)(tchar const* msg);
|
||||
|
||||
#ifdef BAMBU_DYNAMIC
|
||||
};
|
||||
} BambuLib;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -895,7 +895,7 @@ StaticBambuLib &StaticBambuLib::get()
|
|||
{
|
||||
static StaticBambuLib lib;
|
||||
// first load the library
|
||||
|
||||
|
||||
if (lib.Bambu_Open)
|
||||
return lib;
|
||||
|
||||
|
|
@ -910,6 +910,8 @@ StaticBambuLib &StaticBambuLib::get()
|
|||
GET_FUNC(Bambu_Create);
|
||||
GET_FUNC(Bambu_Open);
|
||||
GET_FUNC(Bambu_StartStream);
|
||||
GET_FUNC(Bambu_GetStreamCount);
|
||||
GET_FUNC(Bambu_GetStreamInfo);
|
||||
GET_FUNC(Bambu_SendMessage);
|
||||
GET_FUNC(Bambu_ReadSample);
|
||||
GET_FUNC(Bambu_Close);
|
||||
|
|
@ -922,6 +924,6 @@ StaticBambuLib &StaticBambuLib::get()
|
|||
return lib;
|
||||
}
|
||||
|
||||
extern "C" struct BambuLib *bambulib_get() {
|
||||
extern "C" BambuLib *bambulib_get() {
|
||||
return &StaticBambuLib::get();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
* integration with proprietary Bambu Lab blob for getting raw h.264 video
|
||||
*
|
||||
* Copyright (C) 2023 Joshua Wise <joshua@accelerated.tech>
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
|
|
@ -62,10 +62,10 @@
|
|||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#else
|
||||
extern
|
||||
extern
|
||||
#endif
|
||||
struct BambuLib *bambulib_get();
|
||||
static struct BambuLib *_lib = NULL;
|
||||
BambuLib *bambulib_get();
|
||||
BambuLib *_lib = NULL;
|
||||
#define BAMBULIB(x) (_lib->x)
|
||||
|
||||
#else
|
||||
|
|
@ -78,7 +78,8 @@ GST_DEBUG_CATEGORY_STATIC (gst_bambusrc_debug);
|
|||
static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS("video/x-h264,framerate=0/1,parsed=(boolean)false,stream-format=(string)byte-stream"));
|
||||
GST_STATIC_CAPS_ANY);
|
||||
//GST_STATIC_CAPS("video/x-h264,framerate=0/1,parsed=(boolean)false,stream-format=(string)byte-stream"));
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
@ -264,22 +265,22 @@ gst_bambusrc_create (GstPushSrc * psrc, GstBuffer ** outbuf)
|
|||
GstBambuSrc *src;
|
||||
|
||||
src = GST_BAMBUSRC (psrc);
|
||||
|
||||
|
||||
(void) src;
|
||||
GST_DEBUG_OBJECT (src, "create()");
|
||||
|
||||
|
||||
int rv;
|
||||
struct Bambu_Sample sample;
|
||||
|
||||
Bambu_Sample sample;
|
||||
|
||||
if (!src->tnl) {
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
|
||||
while ((rv = BAMBULIB(Bambu_ReadSample)(src->tnl, &sample)) == Bambu_would_block) {
|
||||
GST_DEBUG_OBJECT(src, "create would block");
|
||||
usleep(33333); /* 30Hz */
|
||||
}
|
||||
|
||||
|
||||
if (rv == Bambu_stream_end) {
|
||||
return GST_FLOW_EOS;
|
||||
}
|
||||
|
|
@ -287,7 +288,7 @@ gst_bambusrc_create (GstPushSrc * psrc, GstBuffer ** outbuf)
|
|||
if (rv != Bambu_success) {
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
|
||||
#if GLIB_CHECK_VERSION(2,68,0)
|
||||
gpointer sbuf = g_memdup2(sample.buffer, sample.size);
|
||||
#else
|
||||
|
|
@ -299,12 +300,33 @@ gst_bambusrc_create (GstPushSrc * psrc, GstBuffer ** outbuf)
|
|||
* need to feed this in too -- otherwise the GStreamer pipeline gets upset
|
||||
* and starts triggering QoS events.
|
||||
*/
|
||||
if (!src->sttime) {
|
||||
src->sttime = sample.decode_time * 100ULL;
|
||||
if (src->video_type == AVC1) {
|
||||
if (!src->sttime) {
|
||||
src->sttime = sample.decode_time * 100ULL;
|
||||
}
|
||||
GST_BUFFER_DTS(*outbuf) = sample.decode_time * 100ULL - src->sttime;
|
||||
GST_BUFFER_PTS(*outbuf) = GST_CLOCK_TIME_NONE;
|
||||
GST_BUFFER_DURATION(*outbuf) = GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
GST_BUFFER_DTS(*outbuf) = sample.decode_time * 100ULL - src->sttime;
|
||||
GST_BUFFER_PTS(*outbuf) = GST_CLOCK_TIME_NONE;
|
||||
GST_BUFFER_DURATION(*outbuf) = GST_CLOCK_TIME_NONE;
|
||||
else {
|
||||
if (!src->sttime) {
|
||||
//only available from 1.18
|
||||
//src->sttime = gst_element_get_current_clock_time((GstElement *)psrc);
|
||||
src->sttime = gst_clock_get_time(((GstElement *)psrc)->clock);
|
||||
//if (GST_CLOCK_TIME_NONE == src->sttime)
|
||||
// src->sttime
|
||||
GST_DEBUG_OBJECT(src,
|
||||
"sttime init to %llu.",
|
||||
src->sttime);
|
||||
}
|
||||
//GST_BUFFER_DTS(*outbuf) = gst_element_get_current_clock_time((GstElement *)psrc) - src->sttime;
|
||||
GST_BUFFER_DTS(*outbuf) = gst_clock_get_time(((GstElement *)psrc)->clock) - src->sttime;
|
||||
GST_BUFFER_PTS(*outbuf) = GST_CLOCK_TIME_NONE;
|
||||
GST_BUFFER_DURATION(*outbuf) = GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
GST_DEBUG_OBJECT(src,
|
||||
"sttime:%llu, DTS:%llu, PTS: %llu~",
|
||||
src->sttime, GST_BUFFER_DTS(*outbuf), GST_BUFFER_PTS(*outbuf));
|
||||
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
|
@ -321,13 +343,13 @@ gst_bambusrc_start (GstBaseSrc * bsrc)
|
|||
GstBambuSrc *src = GST_BAMBUSRC (bsrc);
|
||||
|
||||
GST_DEBUG_OBJECT (src, "start(\"%s\")", src->location);
|
||||
|
||||
|
||||
if (src->tnl) {
|
||||
BAMBULIB(Bambu_Close)(src->tnl);
|
||||
BAMBULIB(Bambu_Destroy)(src->tnl);
|
||||
src->tnl = NULL;
|
||||
}
|
||||
|
||||
|
||||
#ifdef BAMBU_DYNAMIC
|
||||
if (!_lib) {
|
||||
_lib = bambulib_get();
|
||||
|
|
@ -339,15 +361,15 @@ gst_bambusrc_start (GstBaseSrc * bsrc)
|
|||
if (BAMBULIB(Bambu_Create)(&src->tnl, src->location) != Bambu_success) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
BAMBULIB(Bambu_SetLogger)(src->tnl, _log, (void *)src);
|
||||
if (BAMBULIB(Bambu_Open)(src->tnl) != Bambu_success) {
|
||||
BAMBULIB(Bambu_Destroy)(src->tnl);
|
||||
src->tnl = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int rv;
|
||||
|
||||
int rv, n = 0;
|
||||
while ((rv = BAMBULIB(Bambu_StartStream)(src->tnl, 1 /* video */)) == Bambu_would_block) {
|
||||
usleep(100000);
|
||||
}
|
||||
|
|
@ -358,6 +380,21 @@ gst_bambusrc_start (GstBaseSrc * bsrc)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
src->video_type = AVC1;
|
||||
n = BAMBULIB(Bambu_GetStreamCount)(src->tnl);
|
||||
GST_INFO_OBJECT (src, "Bambu_GetStreamCount returned stream count=%d",n);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
Bambu_StreamInfo info;
|
||||
BAMBULIB(Bambu_GetStreamInfo)(src->tnl, i, &info);
|
||||
|
||||
GST_INFO_OBJECT (src, "stream %d type=%d, sub_type=%d", i, info.type, info.sub_type);
|
||||
if (info.type == VIDE) {
|
||||
src->video_type = info.sub_type;
|
||||
GST_INFO_OBJECT (src, " width %d height=%d, frame_rate=%d",
|
||||
info.format.video.width, info.format.video.height, info.format.video.frame_rate);
|
||||
}
|
||||
}
|
||||
|
||||
src->sttime = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -383,9 +420,9 @@ gst_bambusrc_change_state (GstElement * element, GstStateChange transition)
|
|||
{
|
||||
GstStateChangeReturn ret;
|
||||
GstBambuSrc *src;
|
||||
|
||||
|
||||
src = GST_BAMBUSRC (element);
|
||||
|
||||
|
||||
(void) src;
|
||||
|
||||
switch (transition) {
|
||||
|
|
@ -429,7 +466,7 @@ static gboolean
|
|||
gst_bambusrc_is_seekable (GstBaseSrc * bsrc)
|
||||
{
|
||||
GstBambuSrc *src = GST_BAMBUSRC (bsrc);
|
||||
|
||||
|
||||
(void) src;
|
||||
|
||||
return FALSE;
|
||||
|
|
@ -522,7 +559,7 @@ static void
|
|||
gst_bambusrc_uri_handler_init (gpointer g_iface, gpointer iface_data)
|
||||
{
|
||||
GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
|
||||
|
||||
|
||||
iface->get_type = gst_bambusrc_uri_get_type;
|
||||
iface->get_protocols = gst_bambusrc_uri_get_protocols;
|
||||
iface->get_uri = gst_bambusrc_uri_get_uri;
|
||||
|
|
@ -543,7 +580,7 @@ void gstbambusrc_register()
|
|||
if (did_register)
|
||||
return;
|
||||
did_register = 1;
|
||||
|
||||
|
||||
gst_plugin_register_static(GST_VERSION_MAJOR, GST_VERSION_MINOR, "bambusrc", "Bambu Lab source", gstbambusrc_init, "0.0.1", "GPL", "BambuStudio", "BambuStudio", "https://github.com/bambulab/BambuStudio");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
* integration with proprietary Bambu Lab blob for getting raw h.264 video
|
||||
*
|
||||
* Copyright (C) 2023 Joshua Wise <joshua@accelerated.tech>
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
|
|
@ -64,6 +64,7 @@ struct _GstBambuSrc
|
|||
gchar *location;
|
||||
Bambu_Tunnel tnl;
|
||||
GstClockTime sttime;
|
||||
int video_type;
|
||||
};
|
||||
|
||||
extern void gstbambusrc_register();
|
||||
|
|
|
|||
211
src/slic3r/GUI/PrivacyUpdateDialog.cpp
Normal file
211
src/slic3r/GUI/PrivacyUpdateDialog.cpp
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
#include "PrivacyUpdateDialog.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
#include "BitmapCache.hpp"
|
||||
#include <wx/dcgraph.h>
|
||||
#include <slic3r/GUI/I18N.hpp>
|
||||
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
wxDEFINE_EVENT(EVT_PRIVACY_UPDATE_CONFIRM, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_PRIVACY_UPDATE_CANCEL, wxCommandEvent);
|
||||
|
||||
static std::string url_encode(const std::string& value) {
|
||||
std::ostringstream escaped;
|
||||
escaped.fill('0');
|
||||
escaped << std::hex;
|
||||
for (std::string::const_iterator i = value.begin(), n = value.end(); i != n; ++i) {
|
||||
std::string::value_type c = (*i);
|
||||
|
||||
// Keep alphanumeric and other accepted characters intact
|
||||
if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
|
||||
escaped << c;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Any other characters are percent-encoded
|
||||
escaped << std::uppercase;
|
||||
escaped << '%' << std::setw(2) << int((unsigned char)c);
|
||||
escaped << std::nouppercase;
|
||||
}
|
||||
return escaped.str();
|
||||
}
|
||||
|
||||
PrivacyUpdateDialog::PrivacyUpdateDialog(wxWindow* parent, wxWindowID id, const wxString& title, enum ButtonStyle btn_style, const wxPoint& pos, const wxSize& size, long style)
|
||||
:DPIDialog(parent, id, title, pos, size, style)
|
||||
{
|
||||
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);
|
||||
m_sizer_main = new wxBoxSizer(wxVERTICAL);
|
||||
auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(540), 1));
|
||||
m_line_top->SetBackgroundColour(wxColour(166, 169, 170));
|
||||
m_sizer_main->Add(m_line_top, 0, wxEXPAND, 0);
|
||||
m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(5));
|
||||
|
||||
wxBoxSizer* m_sizer_right = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_sizer_right->Add(0, 0, 1, wxTOP, FromDIP(15));
|
||||
//webview
|
||||
m_vebview_release_note = CreateTipView(this);
|
||||
if (m_vebview_release_note == nullptr) {
|
||||
wxLogError("Could not init m_browser");
|
||||
return;
|
||||
}
|
||||
m_vebview_release_note->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8));
|
||||
m_vebview_release_note->SetSize(wxSize(FromDIP(540), FromDIP(340)));
|
||||
m_vebview_release_note->SetMinSize(wxSize(FromDIP(540), FromDIP(340)));
|
||||
|
||||
fs::path ph(data_dir());
|
||||
ph /= "resources/tooltip/privacyupdate.html";
|
||||
if (!fs::exists(ph)) {
|
||||
ph = resources_dir();
|
||||
ph /= "tooltip/privacyupdate.html";
|
||||
}
|
||||
m_host_url = ph.string();
|
||||
std::replace(m_host_url.begin(), m_host_url.end(), '\\', '/');
|
||||
m_host_url = "file:///" + m_host_url;
|
||||
m_vebview_release_note->LoadURL(from_u8(m_host_url));
|
||||
m_sizer_right->Add(m_vebview_release_note, 0, wxEXPAND | wxRIGHT | wxLEFT, FromDIP(15));
|
||||
|
||||
auto sizer_button = new wxBoxSizer(wxHORIZONTAL);
|
||||
StateColor btn_bg_green(std::pair<wxColour, int>(wxColour(27, 136, 68), StateColor::Pressed), std::pair<wxColour, int>(wxColour(61, 203, 115), StateColor::Hovered),
|
||||
std::pair<wxColour, int>(wxColour(0, 174, 66), StateColor::Normal));
|
||||
|
||||
StateColor btn_bg_white(std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Pressed), std::pair<wxColour, int>(wxColour(220, 220, 220), StateColor::Hovered),
|
||||
std::pair<wxColour, int>(wxColour(238, 238, 238), StateColor::Normal));
|
||||
|
||||
#ifndef __WINDOWS__
|
||||
m_vebview_release_note->Bind(wxEVT_WEBVIEW_LOADED, [this](auto& e) {
|
||||
#else
|
||||
m_vebview_release_note->Bind(wxEVT_WEBVIEW_NAVIGATED, [this](auto& e) {
|
||||
#endif
|
||||
if (!m_mkdown_text.empty()) {
|
||||
ShowReleaseNote(m_mkdown_text);
|
||||
}
|
||||
e.Skip();
|
||||
});
|
||||
|
||||
m_vebview_release_note->Bind(wxEVT_WEBVIEW_NAVIGATING , &PrivacyUpdateDialog::OnNavigating, this);
|
||||
|
||||
m_button_ok = new Button(this, _L("Accept"));
|
||||
m_button_ok->SetBackgroundColor(btn_bg_green);
|
||||
m_button_ok->SetBorderColor(*wxWHITE);
|
||||
m_button_ok->SetTextColor(wxColour("#FFFFFE"));
|
||||
m_button_ok->SetFont(Label::Body_12);
|
||||
m_button_ok->SetSize(wxSize(-1, FromDIP(36)));
|
||||
m_button_ok->SetMinSize(wxSize(-1, FromDIP(36)));
|
||||
m_button_ok->SetCornerRadius(FromDIP(3));
|
||||
|
||||
m_button_ok->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent& e) {
|
||||
wxCommandEvent evt(EVT_PRIVACY_UPDATE_CONFIRM, GetId());
|
||||
e.SetEventObject(this);
|
||||
GetEventHandler()->ProcessEvent(evt);
|
||||
this->on_hide();
|
||||
});
|
||||
|
||||
m_button_cancel = new Button(this, _L("Log Out"));
|
||||
m_button_cancel->SetBackgroundColor(btn_bg_white);
|
||||
m_button_cancel->SetBorderColor(*wxWHITE);
|
||||
m_button_cancel->SetFont(Label::Body_12);
|
||||
m_button_cancel->SetSize(wxSize(-1, FromDIP(36)));
|
||||
m_button_cancel->SetMinSize(wxSize(-1, FromDIP(36)));
|
||||
m_button_cancel->SetCornerRadius(FromDIP(3));
|
||||
|
||||
m_button_cancel->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent& e) {
|
||||
wxCommandEvent evt(EVT_PRIVACY_UPDATE_CANCEL);
|
||||
e.SetEventObject(this);
|
||||
GetEventHandler()->ProcessEvent(evt);
|
||||
this->on_hide();
|
||||
});
|
||||
|
||||
Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent& e) {e.Veto(); });
|
||||
|
||||
if (btn_style != CONFIRM_AND_CANCEL)
|
||||
m_button_cancel->Hide();
|
||||
else
|
||||
m_button_cancel->Show();
|
||||
|
||||
sizer_button->Add(m_button_cancel, 1, wxALL | wxEXPAND, FromDIP(10));
|
||||
sizer_button->Add(m_button_ok, 1, wxALL | wxEXPAND, FromDIP(10));
|
||||
|
||||
m_sizer_right->Add(sizer_button, 0, wxEXPAND | wxRIGHT | wxLEFT, FromDIP(5));
|
||||
m_sizer_right->Add(0, 0, 0, wxTOP, FromDIP(10));
|
||||
|
||||
m_sizer_main->Add(m_sizer_right, 0, wxBOTTOM | wxEXPAND, FromDIP(5));
|
||||
|
||||
SetSizer(m_sizer_main);
|
||||
Layout();
|
||||
m_sizer_main->Fit(this);
|
||||
|
||||
CenterOnParent();
|
||||
wxGetApp().UpdateDlgDarkUI(this);
|
||||
}
|
||||
|
||||
wxWebView* PrivacyUpdateDialog::CreateTipView(wxWindow* parent)
|
||||
{
|
||||
wxWebView* tipView = WebView::CreateWebView(parent, "");
|
||||
return tipView;
|
||||
}
|
||||
|
||||
void PrivacyUpdateDialog::OnNavigating(wxWebViewEvent& event)
|
||||
{
|
||||
wxString jump_url = event.GetURL();
|
||||
if (jump_url != m_host_url) {
|
||||
event.Veto();
|
||||
wxLaunchDefaultBrowser(jump_url);
|
||||
}
|
||||
else {
|
||||
event.Skip();
|
||||
}
|
||||
}
|
||||
|
||||
bool PrivacyUpdateDialog::ShowReleaseNote(std::string content)
|
||||
{
|
||||
auto script = "window.showMarkdown('" + url_encode(content) + "', true);";
|
||||
RunScript(script);
|
||||
return true;
|
||||
}
|
||||
|
||||
void PrivacyUpdateDialog::RunScript(std::string script)
|
||||
{
|
||||
WebView::RunScript(m_vebview_release_note, script);
|
||||
script.clear();
|
||||
}
|
||||
|
||||
void PrivacyUpdateDialog::on_show()
|
||||
{
|
||||
wxGetApp().UpdateDlgDarkUI(this);
|
||||
this->ShowModal();
|
||||
}
|
||||
|
||||
void PrivacyUpdateDialog::on_hide()
|
||||
{
|
||||
EndModal(wxID_OK);
|
||||
}
|
||||
|
||||
void PrivacyUpdateDialog::update_btn_label(wxString ok_btn_text, wxString cancel_btn_text)
|
||||
{
|
||||
m_button_ok->SetLabel(ok_btn_text);
|
||||
m_button_cancel->SetLabel(cancel_btn_text);
|
||||
rescale();
|
||||
}
|
||||
|
||||
PrivacyUpdateDialog::~PrivacyUpdateDialog()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void PrivacyUpdateDialog::on_dpi_changed(const wxRect& suggested_rect)
|
||||
{
|
||||
rescale();
|
||||
}
|
||||
|
||||
void PrivacyUpdateDialog::rescale()
|
||||
{
|
||||
m_button_ok->Rescale();
|
||||
m_button_cancel->Rescale();
|
||||
}
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
56
src/slic3r/GUI/PrivacyUpdateDialog.hpp
Normal file
56
src/slic3r/GUI/PrivacyUpdateDialog.hpp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#ifndef slic3r_GUI_PrivacyUpdateDialog_hpp_
|
||||
#define slic3r_GUI_PrivacyUpdateDialog_hpp_
|
||||
|
||||
#include "GUI_Utils.hpp"
|
||||
#include "Widgets/Button.hpp"
|
||||
#include "Widgets/Label.hpp"
|
||||
#include "Widgets/WebView.hpp"
|
||||
#include <wx/webview.h>
|
||||
#include <wx/simplebook.h>
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
wxDECLARE_EVENT(EVT_PRIVACY_UPDATE_CONFIRM, wxCommandEvent);
|
||||
wxDECLARE_EVENT(EVT_PRIVACY_UPDATE_CANCEL, wxCommandEvent);
|
||||
|
||||
class PrivacyUpdateDialog : public DPIDialog
|
||||
{
|
||||
public:
|
||||
enum ButtonStyle {
|
||||
ONLY_CONFIRM = 0,
|
||||
CONFIRM_AND_CANCEL = 1,
|
||||
MAX_STYLE_NUM = 2
|
||||
};
|
||||
PrivacyUpdateDialog(
|
||||
wxWindow* parent,
|
||||
wxWindowID id = wxID_ANY,
|
||||
const wxString& title = wxEmptyString,
|
||||
enum ButtonStyle btn_style = CONFIRM_AND_CANCEL,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = wxPD_APP_MODAL| wxCAPTION
|
||||
);
|
||||
wxWebView* CreateTipView(wxWindow* parent);
|
||||
void OnNavigating(wxWebViewEvent& event);
|
||||
bool ShowReleaseNote(std::string content);
|
||||
void RunScript(std::string script);
|
||||
void set_text(std::string str) { m_mkdown_text = str; };
|
||||
void on_show();
|
||||
void on_hide();
|
||||
void update_btn_label(wxString ok_btn_text, wxString cancel_btn_text);
|
||||
void rescale();
|
||||
~PrivacyUpdateDialog();
|
||||
void on_dpi_changed(const wxRect& suggested_rect);
|
||||
|
||||
wxBoxSizer* m_sizer_main;
|
||||
wxWebView* m_vebview_release_note{ nullptr };
|
||||
Label* m_staticText_release_note{ nullptr };
|
||||
Button* m_button_ok;
|
||||
Button* m_button_cancel;
|
||||
std::string m_mkdown_text;
|
||||
std::string m_host_url;
|
||||
};
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
|
||||
#endif
|
||||
|
|
@ -17,7 +17,8 @@ namespace GUI {
|
|||
|
||||
void ProjectDirtyStateManager::update_from_undo_redo_stack(bool dirty)
|
||||
{
|
||||
m_plater_dirty = dirty;
|
||||
if (!m_plater_dirty)
|
||||
m_plater_dirty = dirty;
|
||||
if (const Plater *plater = wxGetApp().plater(); plater && wxGetApp().initialized())
|
||||
wxGetApp().mainframe->update_title();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ public:
|
|||
void reset_after_save();
|
||||
void reset_initial_presets();
|
||||
|
||||
void set_plater_dirty(bool is_dirty) { m_plater_dirty = is_dirty; }
|
||||
bool is_dirty() const { return m_plater_dirty || m_project_config_dirty || m_presets_dirty; }
|
||||
bool is_presets_dirty() const { return m_presets_dirty; }
|
||||
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@
|
|||
|
||||
const wxColour text_color(107, 107, 107);
|
||||
|
||||
wxString hint1 = _L("Please home all axes (click ");
|
||||
wxString hint2 = _L(") to locate the toolhead's position. This prevents device moving beyond the printable boundary and causing equipment wear.");
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
RecenterDialog::RecenterDialog(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
|
||||
: DPIDialog(parent, id, _L("Confirm"), pos, size, style)
|
||||
|
|
@ -20,6 +17,9 @@ RecenterDialog::RecenterDialog(wxWindow* parent, wxWindowID id, const wxString&
|
|||
std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str();
|
||||
SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO));
|
||||
|
||||
hint1 = _L("Please home all axes (click ");
|
||||
hint2 = _L(") to locate the toolhead's position. This prevents device moving beyond the printable boundary and causing equipment wear.");
|
||||
|
||||
init_bitmap();
|
||||
|
||||
SetBackgroundColour(*wxWHITE);
|
||||
|
|
@ -130,7 +130,7 @@ void RecenterDialog::render(wxDC& dc) {
|
|||
break;
|
||||
}
|
||||
else {
|
||||
fisrt_line = hint2.SubString(0, i);
|
||||
fisrt_line = hint2.SubString(0, i - 1);
|
||||
remaining_line = hint2.SubString(i, hint2.length());
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ private:
|
|||
Button* m_button_close;
|
||||
wxStaticBitmap* m_bitmap_home;
|
||||
ScalableBitmap m_home_bmp;
|
||||
wxString hint1;
|
||||
wxString hint2;
|
||||
|
||||
void init_bitmap();
|
||||
void OnPaint(wxPaintEvent& event);
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ namespace Slic3r { namespace GUI {
|
|||
|
||||
wxDEFINE_EVENT(EVT_SECONDARY_CHECK_CONFIRM, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_SECONDARY_CHECK_CANCEL, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_SECONDARY_CHECK_FUNC, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_CHECKBOX_CHANGE, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_ENTER_IP_ADDRESS, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_CLOSE_IPADDRESS_DLG, wxCommandEvent);
|
||||
|
|
@ -57,7 +58,7 @@ ReleaseNoteDialog::ReleaseNoteDialog(Plater *plater /*= nullptr*/)
|
|||
|
||||
wxBoxSizer *m_sizer_right = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_text_up_info = new wxStaticText(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_text_up_info = new Label(this,wxEmptyString);
|
||||
m_text_up_info->SetFont(::Label::Head_14);
|
||||
m_text_up_info->SetForegroundColour(wxColour(0x26, 0x2E, 0x30));
|
||||
m_text_up_info->Wrap(-1);
|
||||
|
|
@ -93,13 +94,15 @@ void ReleaseNoteDialog::update_release_note(wxString release_note, std::string v
|
|||
{
|
||||
m_text_up_info->SetLabel(wxString::Format(_L("version %s update information :"), version));
|
||||
wxBoxSizer * sizer_text_release_note = new wxBoxSizer(wxVERTICAL);
|
||||
auto m_staticText_release_note = new wxStaticText(m_vebview_release_note, wxID_ANY, release_note, wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_staticText_release_note->SetForegroundColour(*wxBLACK);
|
||||
auto m_staticText_release_note = new ::Label(m_vebview_release_note, release_note);
|
||||
m_staticText_release_note->SetMinSize(wxSize(FromDIP(530), -1));
|
||||
m_staticText_release_note->SetMaxSize(wxSize(FromDIP(530), -1));
|
||||
m_staticText_release_note->Wrap(FromDIP(530));
|
||||
sizer_text_release_note->Add(m_staticText_release_note, 0, wxALL, 5);
|
||||
m_vebview_release_note->SetSizer(sizer_text_release_note);
|
||||
m_vebview_release_note->Layout();
|
||||
m_vebview_release_note->Fit();
|
||||
wxGetApp().UpdateDlgDarkUI(this);
|
||||
}
|
||||
|
||||
UpdatePluginDialog::UpdatePluginDialog(wxWindow* parent /*= nullptr*/)
|
||||
|
|
@ -124,7 +127,7 @@ UpdatePluginDialog::UpdatePluginDialog(wxWindow* parent /*= nullptr*/)
|
|||
|
||||
wxBoxSizer* m_sizer_right = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_text_up_info = new wxStaticText(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_text_up_info = new Label(this,wxEmptyString);
|
||||
m_text_up_info->SetFont(::Label::Head_13);
|
||||
m_text_up_info->SetMaxSize(wxSize(FromDIP(260), -1));
|
||||
m_text_up_info->Wrap(FromDIP(260));
|
||||
|
|
@ -133,10 +136,9 @@ UpdatePluginDialog::UpdatePluginDialog(wxWindow* parent /*= nullptr*/)
|
|||
|
||||
operation_tips = new ::Label(this, _L("Click OK to update the Network plug-in when Bambu Studio launches next time."));
|
||||
operation_tips->SetFont(::Label::Body_12);
|
||||
operation_tips->SetSize(wxSize(FromDIP(260), -1));
|
||||
operation_tips->SetMinSize(wxSize(FromDIP(260), -1));
|
||||
operation_tips->SetMaxSize(wxSize(FromDIP(260), -1));
|
||||
operation_tips->Wrap(FromDIP(260));
|
||||
operation_tips->SetForegroundColour(*wxBLACK);
|
||||
|
||||
|
||||
m_vebview_release_note = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
|
||||
m_vebview_release_note->SetScrollRate(5, 5);
|
||||
|
|
@ -146,7 +148,7 @@ UpdatePluginDialog::UpdatePluginDialog(wxWindow* parent /*= nullptr*/)
|
|||
|
||||
auto sizer_button = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
StateColor btn_bg_green(std::pair<wxColour, int>(wxColour(0, 137, 123), StateColor::Pressed), std::pair<wxColour, int>(wxColour(38, 166, 154), StateColor::Hovered),
|
||||
StateColor btn_bg_green(std::pair<wxColour, int>(wxColour(27, 136, 68), StateColor::Pressed), std::pair<wxColour, int>(wxColour(61, 203, 115), StateColor::Hovered),
|
||||
std::pair<wxColour, int>(AMS_CONTROL_BRAND_COLOUR, StateColor::Normal));
|
||||
|
||||
StateColor btn_bg_white(std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Pressed), std::pair<wxColour, int>(wxColour(238, 238, 238), StateColor::Hovered),
|
||||
|
|
@ -224,8 +226,8 @@ void UpdatePluginDialog::update_info(std::string json_path)
|
|||
version_str = j["version"];
|
||||
description_str = j["description"];
|
||||
}
|
||||
catch(nlohmann::detail::parse_error &err) {
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< ": parse "<<json_path<<" got a nlohmann::detail::parse_error, reason = " << err.what();
|
||||
catch (nlohmann::detail::parse_error& err) {
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": parse " << json_path << " got a nlohmann::detail::parse_error, reason = " << err.what();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -233,12 +235,13 @@ void UpdatePluginDialog::update_info(std::string json_path)
|
|||
description = from_u8(description_str);
|
||||
|
||||
m_text_up_info->SetLabel(wxString::Format(_L("A new Network plug-in(%s) available, Do you want to install it?"), version));
|
||||
m_text_up_info->SetMinSize(wxSize(FromDIP(260), -1));
|
||||
m_text_up_info->SetMaxSize(wxSize(FromDIP(260), -1));
|
||||
m_text_up_info->Wrap(FromDIP(260));
|
||||
wxBoxSizer* sizer_text_release_note = new wxBoxSizer(wxVERTICAL);
|
||||
auto m_text_label = new ::Label(m_vebview_release_note, description);
|
||||
m_text_label->SetFont(::Label::Body_13);
|
||||
m_text_label->SetForegroundColour(*wxBLACK);
|
||||
m_text_label->SetMinSize(wxSize(FromDIP(235), -1));
|
||||
m_text_label->SetMaxSize(wxSize(FromDIP(235), -1));
|
||||
m_text_label->Wrap(FromDIP(235));
|
||||
|
||||
|
|
@ -246,6 +249,7 @@ void UpdatePluginDialog::update_info(std::string json_path)
|
|||
m_vebview_release_note->SetSizer(sizer_text_release_note);
|
||||
m_vebview_release_note->Layout();
|
||||
m_vebview_release_note->Fit();
|
||||
wxGetApp().UpdateDlgDarkUI(this);
|
||||
Layout();
|
||||
Fit();
|
||||
}
|
||||
|
|
@ -274,7 +278,7 @@ UpdateVersionDialog::UpdateVersionDialog(wxWindow *parent)
|
|||
|
||||
wxBoxSizer *m_sizer_right = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_text_up_info = new wxStaticText(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_text_up_info = new Label(this,wxEmptyString);
|
||||
m_text_up_info->SetFont(::Label::Head_14);
|
||||
m_text_up_info->SetForegroundColour(wxColour(0x26, 0x2E, 0x30));
|
||||
m_text_up_info->Wrap(-1);
|
||||
|
|
@ -297,8 +301,9 @@ UpdateVersionDialog::UpdateVersionDialog(wxWindow *parent)
|
|||
m_vebview_release_note->SetMinSize(wxSize(FromDIP(560), FromDIP(430)));
|
||||
//m_vebview_release_note->SetMaxSize(wxSize(FromDIP(560), FromDIP(430)));
|
||||
|
||||
|
||||
fs::path ph(data_dir());
|
||||
ph /= "resources/tooltip/common/releasenote.html";
|
||||
ph /= "resources/tooltip/releasenote.html";
|
||||
if (!fs::exists(ph)) {
|
||||
ph = resources_dir();
|
||||
ph /= "tooltip/releasenote.html";
|
||||
|
|
@ -496,8 +501,9 @@ void UpdateVersionDialog::update_version_info(wxString release_note, wxString ve
|
|||
m_simplebook_release_note->SetSelection(0);
|
||||
m_text_up_info->SetLabel(wxString::Format(_L("Click to download new version in default browser: %s"), version));
|
||||
wxBoxSizer* sizer_text_release_note = new wxBoxSizer(wxVERTICAL);
|
||||
auto m_staticText_release_note = new wxStaticText(m_scrollwindows_release_note, wxID_ANY, release_note, wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_staticText_release_note->SetForegroundColour(*wxBLACK);
|
||||
auto m_staticText_release_note = new ::Label(m_scrollwindows_release_note, release_note);
|
||||
m_staticText_release_note->SetMinSize(wxSize(FromDIP(560), -1));
|
||||
m_staticText_release_note->SetMaxSize(wxSize(FromDIP(560), -1));
|
||||
m_staticText_release_note->Wrap(FromDIP(530));
|
||||
sizer_text_release_note->Add(m_staticText_release_note, 0, wxALL, 5);
|
||||
m_scrollwindows_release_note->SetSizer(sizer_text_release_note);
|
||||
|
|
@ -506,6 +512,8 @@ void UpdateVersionDialog::update_version_info(wxString release_note, wxString ve
|
|||
SetMinSize(GetSize());
|
||||
SetMaxSize(GetSize());
|
||||
//}
|
||||
|
||||
wxGetApp().UpdateDlgDarkUI(this);
|
||||
Layout();
|
||||
Fit();
|
||||
}
|
||||
|
|
@ -518,7 +526,7 @@ SecondaryCheckDialog::SecondaryCheckDialog(wxWindow* parent, wxWindowID id, cons
|
|||
|
||||
SetBackgroundColour(*wxWHITE);
|
||||
m_sizer_main = new wxBoxSizer(wxVERTICAL);
|
||||
auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(480), 1));
|
||||
auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(400), 1));
|
||||
m_line_top->SetBackgroundColour(wxColour(166, 169, 170));
|
||||
m_sizer_main->Add(m_line_top, 0, wxEXPAND, 0);
|
||||
m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(5));
|
||||
|
|
@ -530,8 +538,8 @@ SecondaryCheckDialog::SecondaryCheckDialog(wxWindow* parent, wxWindowID id, cons
|
|||
m_vebview_release_note = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
|
||||
m_vebview_release_note->SetScrollRate(0, 5);
|
||||
m_vebview_release_note->SetBackgroundColour(*wxWHITE);
|
||||
m_vebview_release_note->SetMinSize(wxSize(FromDIP(280), FromDIP(280)));
|
||||
m_sizer_right->Add(m_vebview_release_note, 0, wxEXPAND | wxRIGHT | wxLEFT, FromDIP(35));
|
||||
m_vebview_release_note->SetMinSize(wxSize(FromDIP(400), FromDIP(380)));
|
||||
m_sizer_right->Add(m_vebview_release_note, 0, wxEXPAND | wxRIGHT | wxLEFT, FromDIP(15));
|
||||
|
||||
|
||||
auto bottom_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
|
@ -544,12 +552,15 @@ SecondaryCheckDialog::SecondaryCheckDialog(wxWindow* parent, wxWindowID id, cons
|
|||
|
||||
|
||||
if (not_show_again_check) {
|
||||
auto checkbox_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_show_again_checkbox = new wxCheckBox(this, wxID_ANY, _L("Don't show again"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_show_again_checkbox->Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, [this](wxCommandEvent& e) {
|
||||
not_show_again = !not_show_again;
|
||||
m_show_again_checkbox->SetValue(not_show_again);
|
||||
});
|
||||
bottom_sizer->Add(m_show_again_checkbox, 0, wxALL, FromDIP(5));
|
||||
checkbox_sizer->Add(FromDIP(15), 0, 0, 0);
|
||||
checkbox_sizer->Add(m_show_again_checkbox, 0, wxALL, FromDIP(5));
|
||||
bottom_sizer->Add(checkbox_sizer, 0, wxBOTTOM | wxEXPAND, 0);
|
||||
}
|
||||
m_button_ok = new Button(this, _L("Confirm"));
|
||||
m_button_ok->SetBackgroundColor(btn_bg_green);
|
||||
|
|
@ -576,29 +587,52 @@ SecondaryCheckDialog::SecondaryCheckDialog(wxWindow* parent, wxWindowID id, cons
|
|||
m_button_cancel->SetCornerRadius(FromDIP(12));
|
||||
|
||||
m_button_cancel->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent& e) {
|
||||
wxCommandEvent evt(EVT_SECONDARY_CHECK_CANCEL);
|
||||
e.SetEventObject(this);
|
||||
GetEventHandler()->ProcessEvent(evt);
|
||||
this->on_hide();
|
||||
wxCommandEvent evt(EVT_SECONDARY_CHECK_CANCEL);
|
||||
e.SetEventObject(this);
|
||||
GetEventHandler()->ProcessEvent(evt);
|
||||
this->on_hide();
|
||||
});
|
||||
|
||||
if (btn_style != CONFIRM_AND_CANCEL)
|
||||
m_button_cancel->Hide();
|
||||
else
|
||||
m_button_fn = new Button(this, _L("Done"));
|
||||
m_button_fn->SetBackgroundColor(btn_bg_white);
|
||||
m_button_fn->SetBorderColor(wxColour(38, 46, 48));
|
||||
m_button_fn->SetFont(Label::Body_12);
|
||||
m_button_fn->SetSize(wxSize(FromDIP(58), FromDIP(24)));
|
||||
m_button_fn->SetMinSize(wxSize(-1, FromDIP(24)));
|
||||
m_button_fn->SetCornerRadius(FromDIP(12));
|
||||
|
||||
m_button_fn->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent& e) {
|
||||
post_event(wxCommandEvent(EVT_SECONDARY_CHECK_FUNC));
|
||||
e.Skip();
|
||||
});
|
||||
|
||||
if (btn_style == CONFIRM_AND_CANCEL) {
|
||||
m_button_cancel->Show();
|
||||
m_button_fn->Hide();
|
||||
} else if (btn_style == CONFIRM_AND_FUNC) {
|
||||
m_button_cancel->Hide();
|
||||
m_button_fn->Show();
|
||||
} else {
|
||||
m_button_cancel->Hide();
|
||||
m_button_fn->Hide();
|
||||
}
|
||||
|
||||
sizer_button->AddStretchSpacer();
|
||||
sizer_button->Add(m_button_fn, 0, wxALL, FromDIP(5));
|
||||
sizer_button->Add(m_button_ok, 0, wxALL, FromDIP(5));
|
||||
sizer_button->Add(m_button_cancel, 0, wxALL, FromDIP(5));
|
||||
sizer_button->Add(FromDIP(5),0, 0, 0);
|
||||
bottom_sizer->Add(sizer_button, 0, wxEXPAND | wxRIGHT | wxLEFT, 0);
|
||||
|
||||
|
||||
m_sizer_right->Add(bottom_sizer, 0, wxEXPAND | wxRIGHT | wxLEFT, FromDIP(35));
|
||||
m_sizer_right->Add(0, 0, 0, wxTOP,FromDIP(18));
|
||||
m_sizer_right->Add(bottom_sizer, 0, wxEXPAND | wxRIGHT | wxLEFT, FromDIP(15));
|
||||
m_sizer_right->Add(0, 0, 0, wxTOP,FromDIP(10));
|
||||
|
||||
m_sizer_main->Add(m_sizer_right, 0, wxBOTTOM | wxEXPAND, FromDIP(5));
|
||||
|
||||
Bind(wxEVT_CLOSE_WINDOW, [this](auto& e) {this->on_hide();});
|
||||
|
||||
SetSizer(m_sizer_right);
|
||||
SetSizer(m_sizer_main);
|
||||
Layout();
|
||||
m_sizer_main->Fit(this);
|
||||
|
||||
|
|
@ -606,6 +640,16 @@ SecondaryCheckDialog::SecondaryCheckDialog(wxWindow* parent, wxWindowID id, cons
|
|||
wxGetApp().UpdateFrameDarkUI(this);
|
||||
}
|
||||
|
||||
void SecondaryCheckDialog::post_event(wxCommandEvent&& event)
|
||||
{
|
||||
if (event_parent) {
|
||||
event.SetString("");
|
||||
event.SetEventObject(event_parent);
|
||||
wxPostEvent(event_parent, event);
|
||||
event.Skip();
|
||||
}
|
||||
}
|
||||
|
||||
void SecondaryCheckDialog::update_text(wxString text)
|
||||
{
|
||||
wxBoxSizer* sizer_text_release_note = new wxBoxSizer(wxVERTICAL);
|
||||
|
|
@ -613,11 +657,10 @@ void SecondaryCheckDialog::update_text(wxString text)
|
|||
if (!m_staticText_release_note) {
|
||||
m_staticText_release_note = new Label(m_vebview_release_note, text);
|
||||
}
|
||||
m_staticText_release_note->SetMaxSize(wxSize(FromDIP(330), -1));
|
||||
m_staticText_release_note->SetMinSize(wxSize(FromDIP(330), -1));
|
||||
m_staticText_release_note->SetLabelText(text);
|
||||
m_staticText_release_note->SetSize(wxSize(FromDIP(260), -1));
|
||||
m_staticText_release_note->SetMaxSize(wxSize(FromDIP(260), -1));
|
||||
m_staticText_release_note->SetMinSize(wxSize(FromDIP(260), -1));
|
||||
m_staticText_release_note->Wrap(FromDIP(260));
|
||||
m_staticText_release_note->Wrap(FromDIP(330));
|
||||
|
||||
wxBoxSizer* top_blank_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer* bottom_blank_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
|
@ -629,14 +672,19 @@ void SecondaryCheckDialog::update_text(wxString text)
|
|||
sizer_text_release_note->Add(bottom_blank_sizer, 0, wxALIGN_CENTER | wxALL, FromDIP(5));
|
||||
m_vebview_release_note->SetSizer(sizer_text_release_note);
|
||||
auto text_size = m_staticText_release_note->GetSize();
|
||||
if (text_size.y < FromDIP(280))
|
||||
m_vebview_release_note->SetMinSize(wxSize(FromDIP(280), text_size.y + FromDIP(25)));
|
||||
else
|
||||
m_vebview_release_note->SetMinSize(wxSize(FromDIP(300), FromDIP(280)));
|
||||
if (text_size.y < FromDIP(360))
|
||||
m_vebview_release_note->SetMinSize(wxSize(FromDIP(360), text_size.y + FromDIP(25)));
|
||||
else {
|
||||
m_vebview_release_note->SetMinSize(wxSize(FromDIP(360), FromDIP(360)));
|
||||
m_staticText_release_note->SetMaxSize(wxSize(FromDIP(330), -1));
|
||||
m_staticText_release_note->SetMinSize(wxSize(FromDIP(330), -1));
|
||||
m_staticText_release_note->SetLabelText(text);
|
||||
m_staticText_release_note->Wrap(FromDIP(330));
|
||||
}
|
||||
|
||||
m_vebview_release_note->Layout();
|
||||
m_sizer_main->Layout();
|
||||
m_sizer_main->Fit(this);
|
||||
Layout();
|
||||
Fit();
|
||||
}
|
||||
|
||||
void SecondaryCheckDialog::on_show()
|
||||
|
|
@ -664,6 +712,33 @@ void SecondaryCheckDialog::on_hide()
|
|||
}
|
||||
}
|
||||
|
||||
void SecondaryCheckDialog::update_title_style(wxString title, SecondaryCheckDialog::ButtonStyle style, wxWindow* parent)
|
||||
{
|
||||
SetTitle(title);
|
||||
|
||||
event_parent = parent;
|
||||
|
||||
if (style == CONFIRM_AND_CANCEL) {
|
||||
m_button_cancel->Show();
|
||||
m_button_fn->Hide();
|
||||
}
|
||||
else if (style == CONFIRM_AND_FUNC) {
|
||||
m_button_cancel->Hide();
|
||||
m_button_fn->Show();
|
||||
}
|
||||
else {
|
||||
m_button_cancel->Hide();
|
||||
m_button_fn->Hide();
|
||||
}
|
||||
Layout();
|
||||
}
|
||||
|
||||
void SecondaryCheckDialog::update_func_btn(wxString func_btn_text)
|
||||
{
|
||||
m_button_fn->SetLabel(func_btn_text);
|
||||
rescale();
|
||||
}
|
||||
|
||||
void SecondaryCheckDialog::update_btn_label(wxString ok_btn_text, wxString cancel_btn_text)
|
||||
{
|
||||
m_button_ok->SetLabel(ok_btn_text);
|
||||
|
|
@ -695,7 +770,7 @@ ConfirmBeforeSendDialog::ConfirmBeforeSendDialog(wxWindow* parent, wxWindowID id
|
|||
|
||||
SetBackgroundColour(*wxWHITE);
|
||||
m_sizer_main = new wxBoxSizer(wxVERTICAL);
|
||||
auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(480), 1));
|
||||
auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(400), 1));
|
||||
m_line_top->SetBackgroundColour(wxColour(166, 169, 170));
|
||||
m_sizer_main->Add(m_line_top, 0, wxEXPAND, 0);
|
||||
m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(5));
|
||||
|
|
@ -707,8 +782,8 @@ ConfirmBeforeSendDialog::ConfirmBeforeSendDialog(wxWindow* parent, wxWindowID id
|
|||
m_vebview_release_note = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
|
||||
m_vebview_release_note->SetScrollRate(0, 5);
|
||||
m_vebview_release_note->SetBackgroundColour(*wxWHITE);
|
||||
m_vebview_release_note->SetMinSize(wxSize(FromDIP(280), FromDIP(280)));
|
||||
m_sizer_right->Add(m_vebview_release_note, 0, wxEXPAND | wxRIGHT | wxLEFT, FromDIP(35));
|
||||
m_vebview_release_note->SetMinSize(wxSize(FromDIP(400), FromDIP(380)));
|
||||
m_sizer_right->Add(m_vebview_release_note, 0, wxEXPAND | wxRIGHT | wxLEFT, FromDIP(15));
|
||||
|
||||
|
||||
auto bottom_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
|
@ -721,12 +796,15 @@ ConfirmBeforeSendDialog::ConfirmBeforeSendDialog(wxWindow* parent, wxWindowID id
|
|||
|
||||
|
||||
if (not_show_again_check) {
|
||||
auto checkbox_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_show_again_checkbox = new wxCheckBox(this, wxID_ANY, _L("Don't show again"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_show_again_checkbox->Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, [this](wxCommandEvent& e) {
|
||||
not_show_again = !not_show_again;
|
||||
m_show_again_checkbox->SetValue(not_show_again);
|
||||
});
|
||||
bottom_sizer->Add(m_show_again_checkbox, 0, wxALL, FromDIP(5));
|
||||
});
|
||||
checkbox_sizer->Add(FromDIP(15), 0, 0, 0);
|
||||
checkbox_sizer->Add(m_show_again_checkbox, 0, wxALL, FromDIP(5));
|
||||
bottom_sizer->Add(checkbox_sizer, 0, wxBOTTOM | wxEXPAND, 0);
|
||||
}
|
||||
m_button_ok = new Button(this, _L("Confirm"));
|
||||
m_button_ok->SetBackgroundColor(btn_bg_green);
|
||||
|
|
@ -767,15 +845,18 @@ ConfirmBeforeSendDialog::ConfirmBeforeSendDialog(wxWindow* parent, wxWindowID id
|
|||
sizer_button->AddStretchSpacer();
|
||||
sizer_button->Add(m_button_ok, 0, wxALL, FromDIP(5));
|
||||
sizer_button->Add(m_button_cancel, 0, wxALL, FromDIP(5));
|
||||
sizer_button->Add(FromDIP(5),0, 0, 0);
|
||||
bottom_sizer->Add(sizer_button, 0, wxEXPAND | wxRIGHT | wxLEFT, 0);
|
||||
|
||||
|
||||
m_sizer_right->Add(bottom_sizer, 0, wxEXPAND | wxRIGHT | wxLEFT, FromDIP(35));
|
||||
m_sizer_right->Add(0, 0, 0, wxTOP, FromDIP(18));
|
||||
m_sizer_right->Add(bottom_sizer, 0, wxEXPAND | wxRIGHT | wxLEFT, FromDIP(20));
|
||||
m_sizer_right->Add(0, 0, 0, wxTOP, FromDIP(10));
|
||||
|
||||
m_sizer_main->Add(m_sizer_right, 0, wxBOTTOM | wxEXPAND, FromDIP(5));
|
||||
|
||||
Bind(wxEVT_CLOSE_WINDOW, [this](auto& e) {this->on_hide(); });
|
||||
|
||||
SetSizer(m_sizer_right);
|
||||
SetSizer(m_sizer_main);
|
||||
Layout();
|
||||
m_sizer_main->Fit(this);
|
||||
|
||||
|
|
@ -786,14 +867,13 @@ ConfirmBeforeSendDialog::ConfirmBeforeSendDialog(wxWindow* parent, wxWindowID id
|
|||
void ConfirmBeforeSendDialog::update_text(wxString text)
|
||||
{
|
||||
wxBoxSizer* sizer_text_release_note = new wxBoxSizer(wxVERTICAL);
|
||||
if (!m_staticText_release_note)
|
||||
if (!m_staticText_release_note){
|
||||
m_staticText_release_note = new Label(m_vebview_release_note, text);
|
||||
else
|
||||
m_staticText_release_note->SetLabelText(text);
|
||||
m_staticText_release_note->Wrap(FromDIP(260));
|
||||
m_staticText_release_note->SetSize(wxSize(FromDIP(260), -1));
|
||||
m_staticText_release_note->SetMaxSize(wxSize(FromDIP(260), -1));
|
||||
m_staticText_release_note->SetMinSize(wxSize(FromDIP(260), -1));
|
||||
}
|
||||
m_staticText_release_note->SetMaxSize(wxSize(FromDIP(330), -1));
|
||||
m_staticText_release_note->SetMinSize(wxSize(FromDIP(330), -1));
|
||||
m_staticText_release_note->SetLabelText(text);
|
||||
m_staticText_release_note->Wrap(FromDIP(330));
|
||||
|
||||
wxBoxSizer* top_blank_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer* bottom_blank_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
|
@ -805,14 +885,19 @@ void ConfirmBeforeSendDialog::update_text(wxString text)
|
|||
sizer_text_release_note->Add(bottom_blank_sizer, 0, wxALIGN_CENTER | wxALL, FromDIP(5));
|
||||
m_vebview_release_note->SetSizer(sizer_text_release_note);
|
||||
auto text_size = m_staticText_release_note->GetSize();
|
||||
if (text_size.y < FromDIP(280))
|
||||
m_vebview_release_note->SetMinSize(wxSize(FromDIP(280), text_size.y + FromDIP(25)));
|
||||
else
|
||||
m_vebview_release_note->SetMinSize(wxSize(FromDIP(300), FromDIP(280)));
|
||||
if (text_size.y < FromDIP(360))
|
||||
m_vebview_release_note->SetMinSize(wxSize(FromDIP(360), text_size.y + FromDIP(25)));
|
||||
else {
|
||||
m_vebview_release_note->SetMinSize(wxSize(FromDIP(360), FromDIP(360)));
|
||||
m_staticText_release_note->SetMaxSize(wxSize(FromDIP(330), -1));
|
||||
m_staticText_release_note->SetMinSize(wxSize(FromDIP(330), -1));
|
||||
m_staticText_release_note->SetLabelText(text);
|
||||
m_staticText_release_note->Wrap(FromDIP(330));
|
||||
}
|
||||
|
||||
m_vebview_release_note->Layout();
|
||||
m_sizer_main->Layout();
|
||||
m_sizer_main->Fit(this);
|
||||
Layout();
|
||||
Fit();
|
||||
}
|
||||
|
||||
void ConfirmBeforeSendDialog::on_show()
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue