diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index d95848300..490e8e54a 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -2564,9 +2564,9 @@ bool ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese bool check_unsaved_preset_changes = page_welcome->reset_user_profile(); if (check_unsaved_preset_changes) header = _L("All user presets will be deleted."); - int act_btns = UnsavedChangesDialog::ActionButtons::KEEP; + int act_btns = ActionButtons::KEEP; if (!check_unsaved_preset_changes) - act_btns |= UnsavedChangesDialog::ActionButtons::SAVE; + act_btns |= ActionButtons::SAVE; // Install bundles from resources if needed: std::vector install_bundles; diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 901a3c0ff..c054a2e3b 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -2521,9 +2521,9 @@ bool GUI_App::check_and_save_current_preset_changes(const wxString& caption, con { if (has_current_preset_changes()) { const std::string app_config_key = remember_choice ? "default_action_on_close_application" : ""; - int act_buttons = UnsavedChangesDialog::ActionButtons::SAVE; + int act_buttons = ActionButtons::SAVE; if (dont_save_insted_of_discard) - act_buttons |= UnsavedChangesDialog::ActionButtons::DONT_SAVE; + act_buttons |= ActionButtons::DONT_SAVE; UnsavedChangesDialog dlg(caption, header, app_config_key, act_buttons); std::string act = app_config_key.empty() ? "none" : wxGetApp().app_config->get(app_config_key); if (act == "none" && dlg.ShowModal() == wxID_CANCEL) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index d4198b4c5..3875d8cdf 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -277,8 +277,52 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S preferences_dialog = new PreferencesDialog(this); } + + // bind events from DiffDlg + + bind_diff_dialog(); } +void MainFrame::bind_diff_dialog() +{ + auto get_tab = [](Preset::Type type) { + Tab* null_tab = nullptr; + for (Tab* tab : wxGetApp().tabs_list) + if (tab->type() == type) + return tab; + return null_tab; + }; + + auto transfer = [this, get_tab](Preset::Type type) { + get_tab(type)->transfer_options(diff_dialog.get_left_preset_name(type), + diff_dialog.get_right_preset_name(type), + std::move(diff_dialog.get_selected_options(type))); + }; + + auto save = [this, get_tab](Preset::Type type) { + get_tab(type)->save_options(diff_dialog.get_left_preset_name(type), + diff_dialog.get_right_preset_name(type), + std::move(diff_dialog.get_selected_options(type))); + }; + + auto process_options = [this](std::function process) { + const Preset::Type diff_dlg_type = diff_dialog.view_type(); + if (diff_dlg_type == Preset::TYPE_INVALID) { + for (const Preset::Type& type : diff_dialog.printer_technology() == ptFFF ? + std::initializer_list{Preset::TYPE_PRINTER, Preset::TYPE_PRINT, Preset::TYPE_FILAMENT} : + std::initializer_list{ Preset::TYPE_PRINTER, Preset::TYPE_SLA_PRINT, Preset::TYPE_SLA_MATERIAL } ) + process(type); + } + else + process(diff_dlg_type); + }; + + diff_dialog.Bind(EVT_DIFF_DIALOG_TRANSFER, [this, process_options, transfer](SimpleEvent&) { process_options(transfer); }); + + diff_dialog.Bind(EVT_DIFF_DIALOG_SAVE, [this, process_options, save](SimpleEvent&) { process_options(save); }); +} + + #ifdef _MSW_DARK_MODE static wxString pref() { return " [ "; } static wxString suff() { return " ] "; } @@ -2130,9 +2174,6 @@ void MainFrame::add_to_recent_projects(const wxString& filename) void MainFrame::technology_changed() { - // upadte DiffDlg - diff_dialog.update_presets(); - // update menu titles PrinterTechnology pt = plater()->printer_technology(); if (int id = m_menubar->FindMenu(pt == ptFFF ? _L("Material Settings") : _L("Filament Settings")); id != wxNOT_FOUND) diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index 893febf4b..66adf806a 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -107,6 +107,7 @@ class MainFrame : public DPIFrame bool can_delete() const; bool can_delete_all() const; bool can_reslice() const; + void bind_diff_dialog(); // MenuBar items changeable in respect to printer technology enum MenuItems diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 85978ed6b..683789215 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -5328,10 +5328,9 @@ void Plater::new_project() (saved_project == wxID_YES ? _L("You can keep presets modifications to the new project or discard them") : _L("You can keep presets modifications to the new project, discard them or save changes as new presets.\n" "Note, if changes will be saved then new project wouldn't keep them")); - using ab = UnsavedChangesDialog::ActionButtons; - int act_buttons = ab::KEEP; + int act_buttons = ActionButtons::KEEP; if (saved_project == wxID_NO) - act_buttons |= ab::SAVE; + act_buttons |= ActionButtons::SAVE; if (!wxGetApp().check_and_keep_current_preset_changes(_L("Creating a new project"), header, act_buttons)) return; } diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 5f92f98a3..f57a68cae 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1183,9 +1183,9 @@ void Tab::activate_option(const std::string& opt_key, const wxString& category) m_highlighter.init(get_custom_ctrl_with_blinking_ptr(opt_key)); } -void Tab::cache_config_diff(const std::vector& selected_options) +void Tab::cache_config_diff(const std::vector& selected_options, const DynamicPrintConfig* config/* = nullptr*/) { - m_cache_config.apply_only(m_presets->get_edited_preset().config, selected_options); + m_cache_config.apply_only(config ? *config : m_presets->get_edited_preset().config, selected_options); } void Tab::apply_config_from_cache() @@ -3583,6 +3583,42 @@ void Tab::compare_preset() wxGetApp().mainframe->diff_dialog.show(m_type); } +void Tab::transfer_options(const std::string &name_from, const std::string &name_to, std::vector options) +{ + if (options.empty()) + return; + + Preset* preset_from = m_presets->find_preset(name_from); + Preset* preset_to = m_presets->find_preset(name_to); + + if (m_type == Preset::TYPE_PRINTER) { + auto it = std::find(options.begin(), options.end(), "extruders_count"); + if (it != options.end()) { + // erase "extruders_count" option from the list + options.erase(it); + // cache the extruders count + static_cast(this)->cache_extruder_cnt(&preset_from->config); + } + } + cache_config_diff(options, &preset_from->config); + + if (name_to != m_presets->get_edited_preset().name ) + select_preset(preset_to->name); + + apply_config_from_cache(); + load_current_preset(); +} + +void Tab::save_options(const std::string &name_from, const std::string &name_to, std::vector options) +{ + if (options.empty()) + return; + + Preset* preset_from = m_presets->find_preset(name_from); + Preset* preset_to = m_presets->find_preset(name_to); + +} + // Save the current preset into file. // This removes the "dirty" flag of the preset, possibly creates a new preset under a new name, // and activates the new preset. @@ -4267,12 +4303,15 @@ wxSizer* TabPrinter::create_bed_shape_widget(wxWindow* parent) return sizer; } -void TabPrinter::cache_extruder_cnt() +void TabPrinter::cache_extruder_cnt(const DynamicPrintConfig* config/* = nullptr*/) { - if (m_presets->get_edited_preset().printer_technology() == ptSLA) + const DynamicPrintConfig& cached_config = config ? *config : m_presets->get_edited_preset().config; + if (Preset::printer_technology(cached_config) == ptSLA) return; - m_cache_extruder_count = m_extruders_count; + // get extruders count + auto* nozzle_diameter = dynamic_cast(cached_config.option("nozzle_diameter")); + m_cache_extruder_count = nozzle_diameter->values.size(); //m_extruders_count; } bool TabPrinter::apply_extruder_cnt_from_cache() @@ -4282,6 +4321,7 @@ bool TabPrinter::apply_extruder_cnt_from_cache() if (m_cache_extruder_count > 0) { m_presets->get_edited_preset().set_num_extruders(m_cache_extruder_count); +// extruders_count_changed(m_cache_extruder_count); m_cache_extruder_count = 0; return true; } diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 8ed11bf9d..9c4b10140 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -322,6 +322,8 @@ public: void OnKeyDown(wxKeyEvent& event); void compare_preset(); + void transfer_options(const std::string&name_from, const std::string&name_to, std::vector options); + void save_options(const std::string &name_from, const std::string &name_to, std::vector options); void save_preset(std::string name = std::string(), bool detach = false); void rename_preset(); void delete_preset(); @@ -374,7 +376,7 @@ public: void update_wiping_button_visibility(); void activate_option(const std::string& opt_key, const wxString& category); - void cache_config_diff(const std::vector& selected_options); + void cache_config_diff(const std::vector& selected_options, const DynamicPrintConfig* config = nullptr); void apply_config_from_cache(); const std::map& get_category_icon_map() { return m_category_icon; } @@ -503,7 +505,7 @@ public: bool supports_printer_technology(const PrinterTechnology /* tech */) const override { return true; } wxSizer* create_bed_shape_widget(wxWindow* parent); - void cache_extruder_cnt(); + void cache_extruder_cnt(const DynamicPrintConfig* config = nullptr); bool apply_extruder_cnt_from_cache(); }; diff --git a/src/slic3r/GUI/UnsavedChangesDialog.cpp b/src/slic3r/GUI/UnsavedChangesDialog.cpp index 225d92ec6..9bcb9def0 100644 --- a/src/slic3r/GUI/UnsavedChangesDialog.cpp +++ b/src/slic3r/GUI/UnsavedChangesDialog.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include @@ -22,10 +21,6 @@ #include "MainFrame.hpp" #include "MsgDialog.hpp" -//#define FTS_FUZZY_MATCH_IMPLEMENTATION -//#include "fts_fuzzy_match.h" - -#include "BitmapCache.hpp" #include "PresetComboBoxes.hpp" using boost::optional; @@ -40,6 +35,10 @@ namespace Slic3r { namespace GUI { +wxDEFINE_EVENT(EVT_DIFF_DIALOG_TRANSFER, SimpleEvent); +wxDEFINE_EVENT(EVT_DIFF_DIALOG_SAVE, SimpleEvent); + + // ---------------------------------------------------------------------------- // ModelNode: a node inside DiffModel // ---------------------------------------------------------------------------- @@ -104,8 +103,8 @@ ModelNode::ModelNode(ModelNode* parent, const wxString& text, const std::string& ModelNode::ModelNode(ModelNode* parent, const wxString& text) : m_parent_win(parent->m_parent_win), m_parent(parent), - m_text(text), - m_icon_name("dot_small") + m_icon_name("dot_small"), + m_text(text) { UpdateIcons(); } @@ -135,12 +134,12 @@ ModelNode::ModelNode(ModelNode* parent, const wxString& text, const wxString& ol m_old_color(old_value.StartsWith("#") ? old_value : ""), m_mod_color(mod_value.StartsWith("#") ? mod_value : ""), m_new_color(new_value.StartsWith("#") ? new_value : ""), - m_container(false), - m_text(text), m_icon_name("empty"), + m_text(text), m_old_value(old_value), m_mod_value(mod_value), - m_new_value(new_value) + m_new_value(new_value), + m_container(false) { // check if old/new_value is color if (m_old_color.IsEmpty()) { @@ -505,7 +504,7 @@ unsigned int DiffModel::GetChildren(const wxDataViewItem& parent, wxDataViewItem for (const std::unique_ptr& child : children) array.Add(wxDataViewItem((void*)child.get())); - return array.size(); + return array.Count(); } @@ -591,7 +590,7 @@ void DiffModel::Clear() static std::string get_pure_opt_key(std::string opt_key) { - int pos = opt_key.find("#"); + const int pos = opt_key.find("#"); if (pos > 0) boost::erase_tail(opt_key, opt_key.size() - pos); return opt_key; @@ -1472,34 +1471,11 @@ static std::string get_selection(PresetComboBox* preset_combo) return into_u8(preset_combo->GetString(preset_combo->GetSelection())); } -DiffPresetDialog::DiffPresetDialog(MainFrame* mainframe) - : DPIDialog(mainframe, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER), - m_pr_technology(wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology()) -{ -#if defined(__WXMSW__) - // ys_FIXME! temporary workaround for correct font scaling - // Because of from wxWidgets 3.1.3 auto rescaling is implemented for the Fonts, - // From the very beginning set dialog font to the wxSYS_DEFAULT_GUI_FONT - this->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); -#endif // __WXMSW__ +void DiffPresetDialog::create_presets_sizer() +{ + m_presets_sizer = new wxBoxSizer(wxVERTICAL); - int border = 10; - int em = em_unit(); - - assert(wxGetApp().preset_bundle); - - m_preset_bundle_left = std::make_unique(*wxGetApp().preset_bundle); - m_preset_bundle_right = std::make_unique(*wxGetApp().preset_bundle); - - m_top_info_line = new wxStaticText(this, wxID_ANY, _L("Select presets to compare")); - m_top_info_line->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold()); - - m_bottom_info_line = new wxStaticText(this, wxID_ANY, ""); - m_bottom_info_line->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold()); - - wxBoxSizer* presets_sizer = new wxBoxSizer(wxVERTICAL); - - for (auto new_type : { Preset::TYPE_PRINT, Preset::TYPE_FILAMENT, Preset::TYPE_SLA_PRINT, Preset::TYPE_SLA_MATERIAL, Preset::TYPE_PRINTER }) + for (auto new_type : { Preset::TYPE_PRINT, Preset::TYPE_SLA_PRINT, Preset::TYPE_FILAMENT, Preset::TYPE_SLA_MATERIAL, Preset::TYPE_PRINTER }) { const PresetCollection* collection = get_preset_collection(new_type); wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL); @@ -1507,13 +1483,13 @@ DiffPresetDialog::DiffPresetDialog(MainFrame* mainframe) PresetComboBox* presets_right; ScalableButton* equal_bmp = new ScalableButton(this, wxID_ANY, "equal"); - auto add_preset_combobox = [collection, sizer, new_type, em, this](PresetComboBox** cb_, PresetBundle* preset_bundle) { - *cb_ = new PresetComboBox(this, new_type, wxSize(em * 35, -1), preset_bundle); - PresetComboBox* cb = (*cb_); + auto add_preset_combobox = [collection, sizer, new_type, this](PresetComboBox** cb_, PresetBundle* preset_bundle) { + *cb_ = new PresetComboBox(this, new_type, wxSize(em_unit() * 35, -1), preset_bundle); + PresetComboBox*cb = (*cb_); cb->show_modif_preset_separately(); cb->set_selection_changed_function([this, new_type, preset_bundle, cb](int selection) { if (m_view_type == Preset::TYPE_INVALID) { - std::string preset_name = cb->GetString(selection).ToUTF8().data(); + std::string preset_name = Preset::remove_suffix_modified(cb->GetString(selection).ToUTF8().data()); update_compatibility(preset_name, new_type, preset_bundle); } update_tree(); @@ -1527,7 +1503,7 @@ DiffPresetDialog::DiffPresetDialog(MainFrame* mainframe) add_preset_combobox(&presets_left, m_preset_bundle_left.get()); sizer->Add(equal_bmp, 0, wxRIGHT | wxLEFT | wxALIGN_CENTER_VERTICAL, 5); add_preset_combobox(&presets_right, m_preset_bundle_right.get()); - presets_sizer->Add(sizer, 1, wxTOP, 5); + m_presets_sizer->Add(sizer, 1, wxTOP, 5); equal_bmp->Show(new_type == Preset::TYPE_PRINTER); m_preset_combos.push_back({ presets_left, equal_bmp, presets_right }); @@ -1540,7 +1516,10 @@ DiffPresetDialog::DiffPresetDialog(MainFrame* mainframe) update_tree(); }); } +} +void DiffPresetDialog::create_show_all_presets_chb() +{ m_show_all_presets = new wxCheckBox(this, wxID_ANY, _L("Show all presets (including incompatible)")); m_show_all_presets->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent&) { bool show_all = m_show_all_presets->GetValue(); @@ -1553,26 +1532,171 @@ DiffPresetDialog::DiffPresetDialog(MainFrame* mainframe) if (m_view_type == Preset::TYPE_INVALID) update_tree(); }); +} - m_tree = new DiffViewCtrl(this, wxSize(em * 65, em * 40)); +void DiffPresetDialog::create_info_lines() +{ + const wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold(); + + m_top_info_line = new wxStaticText(this, wxID_ANY, _L("Select presets to compare")); + m_top_info_line->SetFont(font); + + m_bottom_info_line = new wxStaticText(this, wxID_ANY, ""); + m_bottom_info_line->SetFont(font); +} + +void DiffPresetDialog::create_tree() +{ + m_tree = new DiffViewCtrl(this, wxSize(em_unit() * 65, em_unit() * 40)); + m_tree->AppendToggleColumn_(L"\u2714", DiffModel::colToggle, wxLinux ? 9 : 6); m_tree->AppendBmpTextColumn("", DiffModel::colIconText, 35); m_tree->AppendBmpTextColumn(_L("Left Preset Value"), DiffModel::colOldValue, 15); m_tree->AppendBmpTextColumn(_L("Right Preset Value"),DiffModel::colModValue, 15); m_tree->Hide(); + m_tree->GetColumn(DiffModel::colToggle)->SetHidden(true); +} - wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL); +void DiffPresetDialog::create_buttons() +{ + wxFont font = this->GetFont().Scaled(1.4f); + m_buttons = new wxBoxSizer(wxHORIZONTAL); - topSizer->Add(m_top_info_line, 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, 2 * border); - topSizer->Add(presets_sizer, 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, border); - topSizer->Add(m_show_all_presets, 0, wxEXPAND | wxALL, border); - topSizer->Add(m_tree, 1, wxEXPAND | wxALL, border); - topSizer->Add(m_bottom_info_line, 0, wxEXPAND | wxALL, 2 * border); + auto show_in_bottom_info = [this](const wxString& ext_line, wxMouseEvent& e) { + m_bottom_info_line->SetLabel(ext_line); + m_bottom_info_line->Show(true); + Layout(); + e.Skip(); + }; - this->SetMinSize(wxSize(80 * em, 30 * em)); + // Transfer + m_transfer_btn = new ScalableButton(this, wxID_ANY, "paste_menu", _L("Transfer"), wxDefaultSize, wxDefaultPosition, wxBORDER_DEFAULT, 24); + m_transfer_btn->Bind(wxEVT_BUTTON, [this](wxEvent&) { button_event(Action::Transfer);}); + + + auto enable_transfer = [this](const Preset::Type& type) { + const Preset& main_edited_preset = get_preset_collection(type, wxGetApp().preset_bundle)->get_edited_preset(); + if (main_edited_preset.is_dirty) + return main_edited_preset.name == get_right_preset_name(type); + return true; + }; + m_transfer_btn->Bind(wxEVT_UPDATE_UI, [this, enable_transfer](wxUpdateUIEvent& evt) { + bool enable = m_tree->has_selection(); + if (enable) { + if (m_view_type == Preset::TYPE_INVALID) { + for (const Preset::Type& type : (m_pr_technology == ptFFF ? std::initializer_list{Preset::TYPE_PRINTER, Preset::TYPE_PRINT, Preset::TYPE_FILAMENT} : + std::initializer_list{ Preset::TYPE_PRINTER, Preset::TYPE_SLA_PRINT, Preset::TYPE_SLA_MATERIAL })) + if (!enable_transfer(type)) { + enable = false; + break; + } + } + else + enable = enable_transfer(m_view_type); + } + evt.Enable(enable); + }); + m_transfer_btn->Bind(wxEVT_ENTER_WINDOW, [this, show_in_bottom_info](wxMouseEvent& e) { + show_in_bottom_info(_L("Transfer the selected options from left preset to the right.\n" + "Note: New modified presets will be selected in setting stabs after close this dialog."), e); }); + + // Save + m_save_btn = new ScalableButton(this, wxID_ANY, "save", _L("Save"), wxDefaultSize, wxDefaultPosition, wxBORDER_DEFAULT, 24); + m_save_btn->Bind(wxEVT_BUTTON, [this](wxEvent&) { button_event(Action::Save); }); + m_save_btn->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(m_tree->has_selection()); }); + m_save_btn->Bind(wxEVT_ENTER_WINDOW, [this, show_in_bottom_info](wxMouseEvent& e) { + show_in_bottom_info(_L("Save the selected options from left preset to the right."), e); }); + + // Cancel + m_cancel_btn = new ScalableButton(this, wxID_CANCEL, "cross", _L("Cancel"), wxDefaultSize, wxDefaultPosition, wxBORDER_DEFAULT, 24); + m_cancel_btn->Bind(wxEVT_BUTTON, [this](wxEvent&) { button_event(Action::Discard);}); + + for (ScalableButton* btn : { m_transfer_btn, m_save_btn, m_cancel_btn }) { + btn->Bind(wxEVT_LEAVE_WINDOW, [this](wxMouseEvent& e) { update_bottom_info(); Layout(); e.Skip(); }); + m_buttons->Add(btn, 1, wxLEFT, 5); + btn->SetFont(font); + } + + m_buttons->Show(false); +} + +void DiffPresetDialog::create_edit_sizer() +{ + // Add check box for the edit mode + m_use_for_transfer = new wxCheckBox(this, wxID_ANY, _L("Transfer values from left to right")); + m_use_for_transfer->SetToolTip(_L("If enabled, this dialog can be used for transver selected values from left to right preset.")); + m_use_for_transfer->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent&) { + bool use = m_use_for_transfer->GetValue(); + m_tree->GetColumn(DiffModel::colToggle)->SetHidden(!use); + if (m_tree->IsShown()) { + m_buttons->Show(use); + Fit(); + Refresh(); + } + else + this->Layout(); + }); + + // Add Buttons + create_buttons(); + + // Create and fill edit sizer + m_edit_sizer = new wxBoxSizer(wxHORIZONTAL); + m_edit_sizer->Add(m_use_for_transfer, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 5); + m_edit_sizer->AddSpacer(em_unit() * 10); + m_edit_sizer->Add(m_buttons, 1, wxLEFT, 5); + m_edit_sizer->Show(false); +} + +void DiffPresetDialog::complete_dialog_creation() +{ + wxBoxSizer*topSizer = new wxBoxSizer(wxVERTICAL); + + int border = 10; + topSizer->Add(m_top_info_line, 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, 2 * border); + topSizer->Add(m_presets_sizer, 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, border); + topSizer->Add(m_show_all_presets, 0, wxEXPAND | wxALL, border); + topSizer->Add(m_tree, 1, wxEXPAND | wxALL, border); + topSizer->Add(m_bottom_info_line, 0, wxEXPAND | wxALL, 2 * border); + topSizer->Add(m_edit_sizer, 0, wxEXPAND | wxLEFT | wxBOTTOM | wxRIGHT, 2 * border); + + this->SetMinSize(wxSize(80 * em_unit(), 30 * em_unit())); this->SetSizer(topSizer); topSizer->SetSizeHints(this); } +DiffPresetDialog::DiffPresetDialog(MainFrame* mainframe) + : DPIDialog(mainframe, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER), + m_pr_technology(wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology()) +{ +#if defined(__WXMSW__) + // ys_FIXME! temporary workaround for correct font scaling + // Because of from wxWidgets 3.1.3 auto rescaling is implemented for the Fonts, + // From the very beginning set dialog font to the wxSYS_DEFAULT_GUI_FONT + this->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); +#endif // __WXMSW__ + + // Init bundles + + assert(wxGetApp().preset_bundle); + + m_preset_bundle_left = std::make_unique(*wxGetApp().preset_bundle); + m_preset_bundle_right = std::make_unique(*wxGetApp().preset_bundle); + + // Create UI items + + create_info_lines(); + + create_presets_sizer(); + + create_show_all_presets_chb(); + + create_tree(); + + create_edit_sizer(); + + complete_dialog_creation(); +} + void DiffPresetDialog::update_controls_visibility(Preset::Type type /* = Preset::TYPE_INVALID*/) { for (auto preset_combos : m_preset_combos) { @@ -1598,6 +1722,8 @@ void DiffPresetDialog::update_bundles_from_app() { *m_preset_bundle_left = *wxGetApp().preset_bundle; *m_preset_bundle_right = *wxGetApp().preset_bundle; + + m_pr_technology = m_preset_bundle_left.get()->printers.get_edited_preset().printer_technology(); } void DiffPresetDialog::show(Preset::Type type /* = Preset::TYPE_INVALID*/) @@ -1620,8 +1746,6 @@ void DiffPresetDialog::show(Preset::Type type /* = Preset::TYPE_INVALID*/) void DiffPresetDialog::update_presets(Preset::Type type) { - m_pr_technology = m_preset_bundle_left.get()->printers.get_edited_preset().printer_technology(); - update_bundles_from_app(); update_controls_visibility(type); @@ -1645,9 +1769,20 @@ void DiffPresetDialog::update_presets(Preset::Type type) update_tree(); } +void DiffPresetDialog::update_bottom_info(wxString bottom_info) +{ + if (m_tree->has_long_strings()) + bottom_info = _L("Some fields are too long to fit. Right mouse click reveals the full text."); + + const bool show_bottom_info = !m_tree->IsShown() || m_tree->has_long_strings(); + if (show_bottom_info) + m_bottom_info_line->SetLabel(bottom_info); + m_bottom_info_line->Show(show_bottom_info); +} + void DiffPresetDialog::update_tree() { - // update searcher befofre update of tree + // update searcher before update of tree wxGetApp().sidebar().check_and_update_searcher(); Search::OptionsSearcher& searcher = wxGetApp().sidebar().get_searcher(); searcher.sort_options_by_key(); @@ -1739,17 +1874,15 @@ void DiffPresetDialog::update_tree() left_val, right_val, "", category_icon_map.at(option.category)); } } - - if (m_tree->has_long_strings()) - bottom_info = _L("Some fields are too long to fit. Right mouse click reveals the full text."); bool tree_was_shown = m_tree->IsShown(); m_tree->Show(show_tree); - bool show_bottom_info = !show_tree || m_tree->has_long_strings(); - if (show_bottom_info) - m_bottom_info_line->SetLabel(bottom_info); - m_bottom_info_line->Show(show_bottom_info); + bool can_transfer_options = m_view_type == Preset::TYPE_INVALID || get_left_preset_name(m_view_type) != get_right_preset_name(m_view_type); + m_edit_sizer->Show(show_tree && can_transfer_options); + m_buttons->Show(m_edit_sizer->IsShown(size_t(0)) && m_use_for_transfer->GetValue()); + + update_bottom_info(bottom_info); if (tree_was_shown == m_tree->IsShown()) Layout(); @@ -1802,6 +1935,10 @@ void DiffPresetDialog::on_sys_color_changed() preset_combos.equal_bmp->sys_color_changed(); preset_combos.presets_right->sys_color_changed(); } + + for (ScalableButton* btn : { m_transfer_btn, m_save_btn, m_cancel_btn }) + btn->sys_color_changed(); + // msw_rescale updates just icons, so use it m_tree->Rescale(); Refresh(); @@ -1865,6 +2002,31 @@ void DiffPresetDialog::update_compatibility(const std::string& preset_name, Pres } } +void DiffPresetDialog::button_event(Action act) +{ + if (act == Action::Save) { + wxPostEvent(this, SimpleEvent(EVT_DIFF_DIALOG_SAVE)); + } + else { + Hide(); + if (act == Action::Transfer) + wxPostEvent(this, SimpleEvent(EVT_DIFF_DIALOG_TRANSFER)); + } +} + +std::string DiffPresetDialog::get_left_preset_name(Preset::Type type) +{ + PresetComboBox* cb = m_preset_combos[int(type - Preset::TYPE_PRINT)].presets_left; + return Preset::remove_suffix_modified(get_selection(cb)); +} + +std::string DiffPresetDialog::get_right_preset_name(Preset::Type type) +{ + + PresetComboBox* cb = m_preset_combos[int(type - Preset::TYPE_PRINT)].presets_right; + return Preset::remove_suffix_modified(get_selection(cb)); +} + } } // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/UnsavedChangesDialog.hpp b/src/slic3r/GUI/UnsavedChangesDialog.hpp index 0d9812932..2397c419e 100644 --- a/src/slic3r/GUI/UnsavedChangesDialog.hpp +++ b/src/slic3r/GUI/UnsavedChangesDialog.hpp @@ -15,6 +15,9 @@ class wxStaticText; namespace Slic3r { namespace GUI{ +wxDECLARE_EVENT(EVT_DIFF_DIALOG_TRANSFER, SimpleEvent); +wxDECLARE_EVENT(EVT_DIFF_DIALOG_SAVE, SimpleEvent); + // ---------------------------------------------------------------------------- // ModelNode: a node inside DiffModel // ---------------------------------------------------------------------------- @@ -103,7 +106,7 @@ public: ModelNode* GetParent() { return m_parent; } ModelNodePtrArray& GetChildren() { return m_children; } ModelNode* GetNthChild(unsigned int n) { return m_children[n].get(); } - unsigned int GetChildCount() const { return m_children.size(); } + unsigned int GetChildCount() const { return (unsigned int)(m_children.size()); } void Append(std::unique_ptr child) { m_children.emplace_back(std::move(child)); } @@ -154,7 +157,7 @@ public: }; DiffModel(wxWindow* parent); - ~DiffModel() {} + ~DiffModel() override = default; void SetAssociatedControl(wxDataViewCtrl* ctrl) { m_ctrl = ctrl; } @@ -242,6 +245,20 @@ public: std::vector selected_options(); }; +// Discard and Cancel buttons are always but next buttons are optional +enum ActionButtons { + TRANSFER = 1, + KEEP = 2, + SAVE = 4, + DONT_SAVE = 8, +}; + +enum class Action { + Undef, + Transfer, + Discard, + Save +}; //------------------------------------------ // UnsavedChangesDialog @@ -262,13 +279,6 @@ class UnsavedChangesDialog : public DPIDialog std::string m_app_config_key; - enum class Action { - Undef, - Transfer, - Discard, - Save - }; - static constexpr char ActTransfer[] = "transfer"; static constexpr char ActDiscard[] = "discard"; static constexpr char ActSave[] = "save"; @@ -281,19 +291,12 @@ class UnsavedChangesDialog : public DPIDialog int m_buttons { ActionButtons::TRANSFER | ActionButtons::SAVE }; public: - // Discard and Cancel buttons are always but next buttons are optional - enum ActionButtons { - TRANSFER = 1, - KEEP = 2, - SAVE = 4, - DONT_SAVE = 8, - }; // show unsaved changes when preset is switching UnsavedChangesDialog(Preset::Type type, PresetCollection* dependent_presets, const std::string& new_selected_preset = std::string()); // show unsaved changes for all another cases UnsavedChangesDialog(const wxString& caption, const wxString& header, const std::string& app_config_key, int act_buttons); - ~UnsavedChangesDialog() {} + ~UnsavedChangesDialog() override = default; void build(Preset::Type type, PresetCollection* dependent_presets, const std::string& new_selected_preset, const wxString& header = ""); void update(Preset::Type type, PresetCollection* dependent_presets, const std::string& new_selected_preset, const wxString& header); @@ -332,7 +335,7 @@ class FullCompareDialog : public wxDialog public: FullCompareDialog(const wxString& option_name, const wxString& old_value, const wxString& mod_value, const wxString& new_value, const wxString& old_value_header, const wxString& mod_value_header, const wxString& new_value_header); - ~FullCompareDialog() {} + ~FullCompareDialog() override = default; }; @@ -342,19 +345,37 @@ public: class DiffPresetDialog : public DPIDialog { DiffViewCtrl* m_tree { nullptr }; + wxBoxSizer* m_presets_sizer { nullptr }; wxStaticText* m_top_info_line { nullptr }; wxStaticText* m_bottom_info_line { nullptr }; wxCheckBox* m_show_all_presets { nullptr }; + wxCheckBox* m_use_for_transfer { nullptr }; + ScalableButton* m_transfer_btn { nullptr }; + ScalableButton* m_save_btn { nullptr }; + ScalableButton* m_cancel_btn { nullptr }; + wxBoxSizer* m_buttons { nullptr }; + wxBoxSizer* m_edit_sizer { nullptr }; Preset::Type m_view_type { Preset::TYPE_INVALID }; PrinterTechnology m_pr_technology; std::unique_ptr m_preset_bundle_left; std::unique_ptr m_preset_bundle_right; - void update_tree(); - void update_bundles_from_app(); - void update_controls_visibility(Preset::Type type = Preset::TYPE_INVALID); - void update_compatibility(const std::string& preset_name, Preset::Type type, PresetBundle* preset_bundle); + void create_buttons(); + void create_edit_sizer(); + void complete_dialog_creation(); + void create_presets_sizer(); + void create_info_lines(); + void create_tree(); + void create_show_all_presets_chb(); + + void update_bottom_info(wxString bottom_info = ""); + void update_tree(); + void update_bundles_from_app(); + void update_controls_visibility(Preset::Type type = Preset::TYPE_INVALID); + void update_compatibility(const std::string& preset_name, Preset::Type type, PresetBundle* preset_bundle); + + void button_event(Action act); struct DiffPresets { @@ -366,11 +387,19 @@ class DiffPresetDialog : public DPIDialog std::vector m_preset_combos; public: - DiffPresetDialog(MainFrame* mainframe); - ~DiffPresetDialog() {} + DiffPresetDialog(MainFrame*mainframe); + ~DiffPresetDialog() override = default; - void show(Preset::Type type = Preset::TYPE_INVALID); - void update_presets(Preset::Type type = Preset::TYPE_INVALID); + void show(Preset::Type type = Preset::TYPE_INVALID); + void update_presets(Preset::Type type = Preset::TYPE_INVALID); + + Preset::Type view_type() const { return m_view_type; } + PrinterTechnology printer_technology() const { return m_pr_technology; } + + std::string get_left_preset_name(Preset::Type type); + std::string get_right_preset_name(Preset::Type type); + + std::vector get_selected_options(Preset::Type type) const { return std::move(m_tree->options(type, true)); } protected: void on_dpi_changed(const wxRect& suggested_rect) override;