diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index f908ed8d47..a8293cb689 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -2685,6 +2685,28 @@ void MainFrame::on_config_changed(DynamicPrintConfig* config) const m_plater->on_config_change(*config); // propagate config change events to the plater } +void MainFrame::set_print_button_to_default(PrintSelectType select_type) +{ + if (select_type == PrintSelectType::ePrintPlate) { + m_print_btn->SetLabel(_L("Send and Print")); + m_print_select = ePrintPlate; + if (m_print_enable) + m_print_enable = get_enable_print_status(); + m_print_btn->Enable(m_print_enable); + this->Layout(); + } else if (select_type == PrintSelectType::eSendGcode) { + m_print_btn->SetLabel(_L("Send and Print")); + m_print_select = eSendGcode; + if (m_print_enable) + m_print_enable = get_enable_print_status() && can_send_gcode(); + m_print_btn->Enable(m_print_enable); + this->Layout(); + } else { + //unsupport + return; + } +} + void MainFrame::add_to_recent_projects(const wxString& filename) { if (wxFileExists(filename)) diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index 1a9eb1eb85..416552743b 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -168,18 +168,6 @@ class MainFrame : public DPIFrame ESettingsLayout m_layout{ ESettingsLayout::Unknown }; - //BBS GUI refactor - enum PrintSelectType - { - ePrintAll = 0, - ePrintPlate = 1, - eExportSlicedFile = 2, - eExportGcode = 3, - eSendGcode = 4, - eSendToPrinter = 5, - eUploadGcode = 6 - }; - enum SliceSelectType { eSliceAll = 0, @@ -195,7 +183,6 @@ protected: #endif public: - MainFrame(); ~MainFrame() = default; @@ -210,6 +197,18 @@ public: tpProject = 4, }; + //BBS GUI refactor + enum PrintSelectType + { + ePrintAll = 0, + ePrintPlate = 1, + eExportSlicedFile = 2, + eExportGcode = 3, + eSendGcode = 4, + eSendToPrinter = 5, + eUploadGcode = 6 + }; + //BBS: add slice&&print status update logic enum SlicePrintEventType { @@ -290,6 +289,7 @@ public: void select_view(const std::string& direction); // Propagate changed configuration from the Tab to the Plater and save changes to the AppConfig void on_config_changed(DynamicPrintConfig* cfg) const ; + void set_print_button_to_default(PrintSelectType select_type); bool can_save() const; bool can_save_as() const; diff --git a/src/slic3r/GUI/PhysicalPrinterDialog.cpp b/src/slic3r/GUI/PhysicalPrinterDialog.cpp index c1394a72a2..5a8ffc4d03 100644 --- a/src/slic3r/GUI/PhysicalPrinterDialog.cpp +++ b/src/slic3r/GUI/PhysicalPrinterDialog.cpp @@ -49,13 +49,51 @@ PhysicalPrinterDialog::PhysicalPrinterDialog(wxWindow* parent) : #ifndef _WIN32 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); #endif - + + // input the preset name + Tab *tab = wxGetApp().get_tab(Preset::TYPE_PRINTER); + m_presets = tab->get_presets(); + const Preset &sel_preset = m_presets->get_selected_preset(); + std::string suffix = _CTX_utf8(L_CONTEXT("Copy", "PresetName"), "PresetName"); + std::string preset_name = sel_preset.is_default ? "Untitled" : sel_preset.is_system ? (boost::format(("%1% - %2%")) % sel_preset.name % suffix).str() : sel_preset.name; + + auto input_sizer = new wxBoxSizer(wxVERTICAL); + + wxStaticText *label_top = new wxStaticText(this, wxID_ANY, from_u8((boost::format(_utf8(L("Save %s as"))) % into_u8(tab->title())).str())); + label_top->SetFont(::Label::Body_13); + label_top->SetForegroundColour(wxColour(38,46,48)); + + m_input_area = new RoundedRectangle(this, wxColor(172, 172, 172), wxDefaultPosition, wxSize(-1,-1), 3, 1); + m_input_area->SetMinSize(wxSize(FromDIP(360), FromDIP(32))); + + wxBoxSizer *input_sizer_h = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer *input_sizer_v = new wxBoxSizer(wxVERTICAL); + + m_input_ctrl = new wxTextCtrl(m_input_area, -1, from_u8(preset_name), wxDefaultPosition, wxSize(wxSize(FromDIP(360), FromDIP(32)).x, -1), 0 | wxBORDER_NONE); + m_input_ctrl->SetBackgroundColour(wxColour(255, 255, 255)); + m_input_ctrl->Bind(wxEVT_TEXT, [this](wxCommandEvent &) { update(); }); + + + input_sizer_v->Add(m_input_ctrl, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, 12); + input_sizer_h->Add(input_sizer_v, 0, wxALIGN_CENTER, 0); + + m_input_area->SetSizer(input_sizer_h); + m_input_area->Layout(); + + m_valid_label = new wxStaticText(this, wxID_ANY, ""); + m_valid_label->SetForegroundColour(wxColor(255, 111, 0)); + + input_sizer->Add(label_top, 0, wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, BORDER_W); + input_sizer->Add(m_input_area, 0, wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, BORDER_W); + input_sizer->Add(m_valid_label, 0, wxEXPAND | wxLEFT | wxRIGHT, BORDER_W); + + m_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config; m_optgroup = new ConfigOptionsGroup(this, _L("Print Host upload"), m_config); build_printhost_settings(m_optgroup); wxStdDialogButtonSizer* btns = this->CreateStdDialogButtonSizer(wxOK | wxCANCEL); - wxButton* btnOK = static_cast(this->FindWindowById(wxID_OK, this)); + btnOK = static_cast(this->FindWindowById(wxID_OK, this)); wxGetApp().UpdateDarkUI(btnOK); btnOK->Bind(wxEVT_BUTTON, &PhysicalPrinterDialog::OnOK, this); @@ -65,8 +103,9 @@ PhysicalPrinterDialog::PhysicalPrinterDialog(wxWindow* parent) : wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL); // topSizer->Add(label_top , 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, BORDER_W); + topSizer->Add(input_sizer , 0, wxEXPAND | wxALL, BORDER_W); topSizer->Add(m_optgroup->sizer , 1, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, BORDER_W); - topSizer->Add(btns , 0, wxEXPAND | wxALL, BORDER_W); + topSizer->Add(btns , 0, wxEXPAND | wxALL, BORDER_W); SetSizer(topSizer); topSizer->SetSizeHints(this); @@ -280,6 +319,84 @@ void PhysicalPrinterDialog::update_printhost_buttons() } } +void PhysicalPrinterDialog::update_preset_input() { + m_preset_name = into_u8(m_input_ctrl->GetValue()); + + m_valid_type = Valid; + wxString info_line; + + const char *unusable_symbols = "<>[]:/\\|?*\""; + + const std::string unusable_suffix = PresetCollection::get_suffix_modified(); //"(modified)"; + for (size_t i = 0; i < std::strlen(unusable_symbols); i++) { + if (m_preset_name.find_first_of(unusable_symbols[i]) != std::string::npos) { + info_line = _L("Name is invalid;") + "\n" + _L("illegal characters:") + " " + unusable_symbols; + m_valid_type = NoValid; + break; + } + } + + + if (m_valid_type == Valid && m_preset_name.find(unusable_suffix) != std::string::npos) { + info_line = _L("Name is invalid;") + "\n" + _L("illegal suffix:") + "\n\t" + from_u8(PresetCollection::get_suffix_modified()); + m_valid_type = NoValid; + } + + if (m_valid_type == Valid && + (m_preset_name == "Default Setting" || m_preset_name == "Default Filament" || m_preset_name == "Default Printer")) { + info_line = _L("Name is unavailable."); + m_valid_type = NoValid; + } + + const Preset *existing = m_presets->find_preset(m_preset_name, false); + if (m_valid_type == Valid && existing && (existing->is_default || existing->is_system)) { + info_line = _L("Overwrite a system profile is not allowed"); + m_valid_type = NoValid; + } + + if (m_valid_type == Valid && existing && m_preset_name != m_presets->get_selected_preset_name()) { + if (existing->is_compatible) + info_line = from_u8((boost::format(_u8L("Preset \"%1%\" already exists.")) % m_preset_name).str()); + else + info_line = from_u8((boost::format(_u8L("Preset \"%1%\" already exists and is incompatible with current printer.")) % m_preset_name).str()); + info_line += "\n" + _L("Please note that saving action will replace this preset"); + m_valid_type = Warning; + } + + if (m_valid_type == Valid && m_preset_name.empty()) { + info_line = _L("The name is not allowed to be empty."); + m_valid_type = NoValid; + } + + if (m_valid_type == Valid && m_preset_name.find_first_of(' ') == 0) { + info_line = _L("The name is not allowed to start with space character."); + m_valid_type = NoValid; + } + + if (m_valid_type == Valid && m_preset_name.find_last_of(' ') == m_preset_name.length() - 1) { + info_line = _L("The name is not allowed to end with space character."); + m_valid_type = NoValid; + } + + if (m_valid_type == Valid && m_presets->get_preset_name_by_alias(m_preset_name) != m_preset_name) { + info_line = _L("The name cannot be the same as a preset alias name."); + m_valid_type = NoValid; + } + + m_valid_label->SetLabel(info_line); + m_input_area->Refresh(); + m_valid_label->Show(!info_line.IsEmpty()); + + if (m_valid_type == NoValid) { + if (btnOK) + btnOK->Disable(); + } + else { + if (btnOK) + btnOK->Enable(); + } +} + void PhysicalPrinterDialog::update(bool printer_change) { m_optgroup->reload_config(); @@ -322,6 +439,8 @@ void PhysicalPrinterDialog::update(bool printer_change) m_optgroup->show_field("printhost_port", supports_multiple_printers); m_printhost_port_browse_btn->Show(supports_multiple_printers); + update_preset_input(); + update_printhost_buttons(); this->SetSize(this->GetBestSize()); @@ -400,7 +519,7 @@ void PhysicalPrinterDialog::on_dpi_changed(const wxRect& suggested_rect) void PhysicalPrinterDialog::OnOK(wxEvent& event) { - wxGetApp().get_tab(Preset::TYPE_PRINTER)->save_preset(); + wxGetApp().get_tab(Preset::TYPE_PRINTER)->save_preset("", false, false, true, m_preset_name ); event.Skip(); } diff --git a/src/slic3r/GUI/PhysicalPrinterDialog.hpp b/src/slic3r/GUI/PhysicalPrinterDialog.hpp index e6d2015e63..ee88e34f7c 100644 --- a/src/slic3r/GUI/PhysicalPrinterDialog.hpp +++ b/src/slic3r/GUI/PhysicalPrinterDialog.hpp @@ -7,6 +7,7 @@ #include "libslic3r/Preset.hpp" #include "GUI_Utils.hpp" +#include "Widgets/RoundedRectangle.hpp" class wxString; class wxTextCtrl; @@ -34,6 +35,10 @@ class PhysicalPrinterDialog : public DPIDialog ScalableButton* m_printhost_client_cert_browse_btn {nullptr}; ScalableButton* m_printhost_port_browse_btn {nullptr}; + RoundedRectangle* m_input_area {nullptr}; + wxStaticText* m_valid_label {nullptr}; + wxTextCtrl* m_input_ctrl {nullptr}; + wxButton* btnOK {nullptr}; void build_printhost_settings(ConfigOptionsGroup* optgroup); void OnOK(wxEvent& event); @@ -42,8 +47,19 @@ public: PhysicalPrinterDialog(wxWindow* parent); ~PhysicalPrinterDialog(); + enum ValidationType + { + Valid, + NoValid, + Warning + }; + PresetCollection* m_presets {nullptr}; + ValidationType m_valid_type; + std::string m_preset_name; + void update(bool printer_change = false); void update_host_type(bool printer_change); + void update_preset_input(); void update_printhost_buttons(); void update_printers(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 5af37e3c4d..2a7c784b81 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -709,7 +709,7 @@ Sidebar::Sidebar(Plater *parent) bSizer39->Add(del_btn, 0, wxALIGN_CENTER_VERTICAL, FromDIP(5)); bSizer39->Add(FromDIP(20), 0, 0, 0, 0); - ScalableButton *ams_btn = new ScalableButton(p->m_panel_filament_title, wxID_ANY, "ams_fila_sync", wxEmptyString, wxDefaultSize, wxDefaultPosition, + ams_btn = new ScalableButton(p->m_panel_filament_title, wxID_ANY, "ams_fila_sync", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, false, 18); ams_btn->SetToolTip(_L("Sync material list from AMS")); ams_btn->Bind(wxEVT_BUTTON, [this, scrolled_sizer](wxCommandEvent &e) { @@ -909,8 +909,20 @@ void Sidebar::update_all_preset_comboboxes() PresetBundle &preset_bundle = *wxGetApp().preset_bundle; const auto print_tech = preset_bundle.printers.get_edited_preset().printer_technology(); - //only show connection button for not-BBL printer - update_printer_host_icon(); + bool is_bbl_preset = preset_bundle.printers.get_edited_preset().is_bbl_vendor_preset(&preset_bundle); + + if (is_bbl_preset) { + //only show connection button for not-BBL printer + connection_btn->Hide(); + //only show sync-ams button for BBL printer + ams_btn->Show(); + //update print button default value for bbl or third-party printer + wxGetApp().mainframe->set_print_button_to_default(MainFrame::PrintSelectType::ePrintPlate); + } else { + connection_btn->Show(); + ams_btn->Hide(); + wxGetApp().mainframe->set_print_button_to_default(MainFrame::PrintSelectType::eSendGcode); + } // Update the print choosers to only contain the compatible presets, update the dirty flags. //BBS @@ -1315,19 +1327,6 @@ void Sidebar::enable_buttons(bool enable) #endif } -void Sidebar::update_printer_host_icon() { - bool is_bbl_vendor_preset = false; - PresetBundle* preset_bundle = wxGetApp().preset_bundle; - if (preset_bundle) { - is_bbl_vendor_preset = preset_bundle->printers.get_edited_preset().is_bbl_vendor_preset(preset_bundle); - } - if (is_bbl_vendor_preset) { - connection_btn->Hide(); - }else{ - connection_btn->Show(); - } -} - bool Sidebar::show_reslice(bool show) const { return p->btn_reslice->Show(show); } bool Sidebar::show_export(bool show) const { return p->btn_export_gcode->Show(show); } bool Sidebar::show_send(bool show) const { return p->btn_send_gcode->Show(show); } diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index cc35dda275..11556056d9 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -120,7 +120,6 @@ public: void on_bed_type_change(BedType bed_type); void load_ams_list(std::map const &list); void sync_ams_list(); - void update_printer_host_icon(); ObjectList* obj_list(); ObjectSettings* obj_settings(); @@ -163,6 +162,7 @@ private: wxBoxSizer* m_scrolled_sizer = nullptr; ComboBox* m_bed_type_list = nullptr; ScalableButton* connection_btn = nullptr; + ScalableButton* ams_btn = nullptr; }; class Plater: public wxPanel diff --git a/src/slic3r/GUI/PrintHostDialogs.cpp b/src/slic3r/GUI/PrintHostDialogs.cpp index 2a1d6d2a29..8bc4e3ceca 100644 --- a/src/slic3r/GUI/PrintHostDialogs.cpp +++ b/src/slic3r/GUI/PrintHostDialogs.cpp @@ -50,7 +50,7 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, PrintHostPostUplo auto *label_dir_hint = new wxStaticText(this, wxID_ANY, _L("Use forward slashes ( / ) as a directory separator if needed.")); label_dir_hint->Wrap(CONTENT_WIDTH * wxGetApp().em_unit()); - content_sizer->Add(txt_filename, 0, wxEXPAND, FromDIP(10)); + content_sizer->Add(txt_filename, 0, wxEXPAND | wxALL, FromDIP(10)); content_sizer->Add(FromDIP(10), FromDIP(10), 0, 0); content_sizer->Add(label_dir_hint, 0, 0, FromDIP(10)); content_sizer->AddSpacer(VERT_SPACING); diff --git a/src/slic3r/GUI/SavePresetDialog.cpp b/src/slic3r/GUI/SavePresetDialog.cpp index ae71b707ae..e66e0536f6 100644 --- a/src/slic3r/GUI/SavePresetDialog.cpp +++ b/src/slic3r/GUI/SavePresetDialog.cpp @@ -388,6 +388,19 @@ std::string SavePresetDialog::get_name(Preset::Type type) return ""; } +void SavePresetDialog::input_name_from_other(std::string new_preset_name) { + //only work for one-item + Item* curr_item = m_items[0]; + curr_item->m_input_ctrl->SetValue(new_preset_name); +} + +void SavePresetDialog::confirm_from_other() { + for (Item *item : m_items) { + item->accept(); + if (item->type() == Preset::TYPE_PRINTER) update_physical_printers(item->preset_name()); + } +} + // BBS: add project relate bool SavePresetDialog::get_save_to_project_selection(Preset::Type type) { diff --git a/src/slic3r/GUI/SavePresetDialog.hpp b/src/slic3r/GUI/SavePresetDialog.hpp index 1b2089f898..0644a3a190 100644 --- a/src/slic3r/GUI/SavePresetDialog.hpp +++ b/src/slic3r/GUI/SavePresetDialog.hpp @@ -97,6 +97,8 @@ public: std::string get_name(); std::string get_name(Preset::Type type); + void input_name_from_other(std::string new_preset_name); + void confirm_from_other(); bool enable_ok_btn() const; void add_info_for_edit_ph_printer(wxBoxSizer *sizer); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index be9020ce70..b2e402d4e6 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -4255,12 +4255,21 @@ void Tab::compare_preset() // Wizard calls save_preset with a name "My Settings", otherwise no name is provided and this method // opens a Slic3r::GUI::SavePresetDialog dialog. //BBS: add project embedded preset relate logic -void Tab::save_preset(std::string name /*= ""*/, bool detach, bool save_to_project) +void Tab::save_preset(std::string name /*= ""*/, bool detach, bool save_to_project, bool from_input, std::string input_name ) { // since buttons(and choices too) don't get focus on Mac, we set focus manually // to the treectrl so that the EVT_* events are fired for the input field having // focus currently.is there anything better than this ? //! m_tabctrl->OnSetFocus(); + if (from_input) { + SavePresetDialog dlg(m_parent, m_type, detach ? _u8L("Detached") : ""); + dlg.Show(false); + dlg.input_name_from_other(input_name); + wxCommandEvent evt(wxEVT_TEXT, GetId()); + dlg.GetEventHandler()->ProcessEvent(evt); + dlg.confirm_from_other(); + name = input_name; + } if (name.empty()) { SavePresetDialog dlg(m_parent, m_type, detach ? _u8L("Detached") : ""); diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 65422637a6..44e8061d30 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -333,7 +333,7 @@ public: void compare_preset(); //BBS: add project embedded preset relate logic - void save_preset(std::string name = std::string(), bool detach = false, bool save_to_project = false); + void save_preset(std::string name = std::string(), bool detach = false, bool save_to_project = false, bool from_input = false, std::string input_name = ""); //void save_preset(std::string name = std::string(), bool detach = false); void delete_preset();