Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/slic3r/GUI/Tab.cpp')
-rw-r--r--src/slic3r/GUI/Tab.cpp2413
1 files changed, 1425 insertions, 988 deletions
diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp
index adfae9024..ccb82b011 100644
--- a/src/slic3r/GUI/Tab.cpp
+++ b/src/slic3r/GUI/Tab.cpp
@@ -1,15 +1,18 @@
// #include "libslic3r/GCodeSender.hpp"
#include "slic3r/Utils/Serial.hpp"
#include "Tab.hpp"
-#include "PresetBundle.hpp"
#include "PresetHints.hpp"
+#include "libslic3r/PresetBundle.hpp"
#include "libslic3r/Utils.hpp"
+#include "libslic3r/Model.hpp"
#include "slic3r/Utils/Http.hpp"
#include "slic3r/Utils/PrintHost.hpp"
#include "BonjourDialog.hpp"
#include "WipeTowerDialog.hpp"
#include "ButtonsDescription.hpp"
+#include "Search.hpp"
+#include "OG_CustomCtrl.hpp"
#include <wx/app.h>
#include <wx/button.h>
@@ -24,19 +27,75 @@
#include <wx/filedlg.h>
#include <boost/algorithm/string/predicate.hpp>
+#include <boost/algorithm/string/replace.hpp>
#include "wxExtensions.hpp"
+#include "PresetComboBoxes.hpp"
#include <wx/wupdlock.h>
#include "GUI_App.hpp"
#include "GUI_ObjectList.hpp"
-#include "ConfigWizard.hpp"
+#include "Plater.hpp"
+#include "MainFrame.hpp"
+#include "format.hpp"
+#include "PhysicalPrinterDialog.hpp"
+#include "UnsavedChangesDialog.hpp"
+#include "SavePresetDialog.hpp"
+
+#ifdef WIN32
+ #include <commctrl.h>
+#endif // WIN32
namespace Slic3r {
namespace GUI {
-wxDEFINE_EVENT(EVT_TAB_VALUE_CHANGED, wxCommandEvent);
-wxDEFINE_EVENT(EVT_TAB_PRESETS_CHANGED, SimpleEvent);
+void Tab::Highlighter::set_timer_owner(wxEvtHandler* owner, int timerid/* = wxID_ANY*/)
+{
+ m_timer.SetOwner(owner, timerid);
+}
+
+void Tab::Highlighter::init(std::pair<OG_CustomCtrl*, bool*> params)
+{
+ if (m_timer.IsRunning())
+ invalidate();
+ if (!params.first || !params.second)
+ return;
+
+ m_timer.Start(300, false);
+
+ m_custom_ctrl = params.first;
+ m_show_blink_ptr = params.second;
+
+ *m_show_blink_ptr = true;
+ m_custom_ctrl->Refresh();
+}
+
+void Tab::Highlighter::invalidate()
+{
+ m_timer.Stop();
+
+ if (m_custom_ctrl && m_show_blink_ptr) {
+ *m_show_blink_ptr = false;
+ m_custom_ctrl->Refresh();
+ m_show_blink_ptr = nullptr;
+ m_custom_ctrl = nullptr;
+ }
+
+ m_blink_counter = 0;
+}
+
+void Tab::Highlighter::blink()
+{
+ if (m_custom_ctrl && m_show_blink_ptr) {
+ *m_show_blink_ptr = !*m_show_blink_ptr;
+ m_custom_ctrl->Refresh();
+ }
+ else
+ return;
+
+ if ((++m_blink_counter) == 11)
+ invalidate();
+}
Tab::Tab(wxNotebook* parent, const wxString& title, Preset::Type type) :
m_parent(parent), m_title(title), m_type(type)
@@ -47,27 +106,33 @@ Tab::Tab(wxNotebook* parent, const wxString& title, Preset::Type type) :
m_compatible_printers.type = Preset::TYPE_PRINTER;
m_compatible_printers.key_list = "compatible_printers";
m_compatible_printers.key_condition = "compatible_printers_condition";
- m_compatible_printers.dialog_title = _(L("Compatible printers")).ToUTF8();
- m_compatible_printers.dialog_label = _(L("Select the printers this profile is compatible with.")).ToUTF8();
+ m_compatible_printers.dialog_title = _L("Compatible printers");
+ m_compatible_printers.dialog_label = _L("Select the printers this profile is compatible with.");
m_compatible_prints.type = Preset::TYPE_PRINT;
m_compatible_prints.key_list = "compatible_prints";
m_compatible_prints.key_condition = "compatible_prints_condition";
- m_compatible_prints.dialog_title = _(L("Compatible print profiles")).ToUTF8();
- m_compatible_prints.dialog_label = _(L("Select the print profiles this profile is compatible with.")).ToUTF8();
+ m_compatible_prints.dialog_title = _L("Compatible print profiles");
+ m_compatible_prints.dialog_label = _L("Select the print profiles this profile is compatible with.");
wxGetApp().tabs_list.push_back(this);
- m_em_unit = wxGetApp().em_unit();
+ m_em_unit = em_unit(m_parent); //wxGetApp().em_unit();
m_config_manipulation = get_config_manipulation();
Bind(wxEVT_SIZE, ([this](wxSizeEvent &evt) {
- for (auto page : m_pages)
- if (! page.get()->IsShown())
- page->layout_valid = false;
+ //for (auto page : m_pages)
+ // if (! page.get()->IsShown())
+ // page->layout_valid = false;
evt.Skip();
}));
+
+ m_highlighter.set_timer_owner(this, 0);
+ this->Bind(wxEVT_TIMER, [this](wxTimerEvent&)
+ {
+ m_highlighter.blink();
+ });
}
void Tab::set_type()
@@ -112,7 +177,18 @@ void Tab::create_preset_tab()
#endif //__WXOSX__
// preset chooser
- m_presets_choice = new PresetBitmapComboBox(panel, wxSize(35 * m_em_unit, -1));
+ m_presets_choice = new TabPresetComboBox(panel, m_type);
+ m_presets_choice->set_selection_changed_function([this](int selection) {
+ if (!m_presets_choice->selection_is_changed_according_to_physical_printers())
+ {
+ if (m_type == Preset::TYPE_PRINTER && !m_presets_choice->is_selected_physical_printer())
+ m_preset_bundle->physical_printers.unselect_printer();
+
+ // select preset
+ std::string preset_name = m_presets_choice->GetString(selection).ToUTF8().data();
+ select_preset(Preset::remove_suffix_modified(preset_name));
+ }
+ });
auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
@@ -122,6 +198,8 @@ void Tab::create_preset_tab()
add_scaled_button(panel, &m_btn_save_preset, "save");
add_scaled_button(panel, &m_btn_delete_preset, "cross");
+ if (m_type == Preset::Type::TYPE_PRINTER)
+ add_scaled_button(panel, &m_btn_edit_ph_printer, "cog");
m_show_incompatible_presets = false;
add_scaled_bitmap(this, m_bmp_show_incompatible_presets, "flag_red");
@@ -132,22 +210,22 @@ void Tab::create_preset_tab()
// TRN "Save current Settings"
m_btn_save_preset->SetToolTip(from_u8((boost::format(_utf8(L("Save current %s"))) % m_title).str()));
m_btn_delete_preset->SetToolTip(_(L("Delete this preset")));
- m_btn_delete_preset->Disable();
+ m_btn_delete_preset->Hide();
add_scaled_button(panel, &m_question_btn, "question");
-
m_question_btn->SetToolTip(_(L("Hover the cursor over buttons to find more information \n"
"or click this button.")));
- // Determine the theme color of OS (dark or light)
- auto luma = wxGetApp().get_colour_approx_luma(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
+ add_scaled_button(panel, &m_search_btn, "search");
+ m_search_btn->SetToolTip(format_wxstr(_L("Search in settings [%1%]"), "Ctrl+F"));
+
// Bitmaps to be shown on the "Revert to system" aka "Lock to system" button next to each input field.
- add_scaled_bitmap(this, m_bmp_value_lock , luma >= 128 ? "lock_closed" : "lock_closed_white");
+ add_scaled_bitmap(this, m_bmp_value_lock , "lock_closed");
add_scaled_bitmap(this, m_bmp_value_unlock, "lock_open");
m_bmp_non_system = &m_bmp_white_bullet;
// Bitmaps to be shown on the "Undo user changes" button next to each input field.
add_scaled_bitmap(this, m_bmp_value_revert, "undo");
- add_scaled_bitmap(this, m_bmp_white_bullet, luma >= 128 ? "dot" : "dot_white");
+ add_scaled_bitmap(this, m_bmp_white_bullet, "dot");
fill_icon_descriptions();
set_tooltips_text();
@@ -169,6 +247,7 @@ void Tab::create_preset_tab()
}
}
}));
+ m_search_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent) { wxGetApp().plater()->search(false); });
// Colors for ui "decoration"
m_sys_label_clr = wxGetApp().get_label_clr_sys();
@@ -186,13 +265,19 @@ void Tab::create_preset_tab()
m_hsizer->Add(m_btn_save_preset, 0, wxALIGN_CENTER_VERTICAL);
m_hsizer->AddSpacer(int(4 * scale_factor));
m_hsizer->Add(m_btn_delete_preset, 0, wxALIGN_CENTER_VERTICAL);
- m_hsizer->AddSpacer(int(16 * scale_factor));
+ if (m_btn_edit_ph_printer) {
+ m_hsizer->AddSpacer(int(4 * scale_factor));
+ m_hsizer->Add(m_btn_edit_ph_printer, 0, wxALIGN_CENTER_VERTICAL);
+ }
+ m_hsizer->AddSpacer(int(/*16*/8 * scale_factor));
m_hsizer->Add(m_btn_hide_incompatible_presets, 0, wxALIGN_CENTER_VERTICAL);
- m_hsizer->AddSpacer(int(64 * scale_factor));
+ m_hsizer->AddSpacer(int(8 * scale_factor));
+ m_hsizer->Add(m_question_btn, 0, wxALIGN_CENTER_VERTICAL);
+ m_hsizer->AddSpacer(int(32 * scale_factor));
m_hsizer->Add(m_undo_to_sys_btn, 0, wxALIGN_CENTER_VERTICAL);
m_hsizer->Add(m_undo_btn, 0, wxALIGN_CENTER_VERTICAL);
m_hsizer->AddSpacer(int(32 * scale_factor));
- m_hsizer->Add(m_question_btn, 0, wxALIGN_CENTER_VERTICAL);
+ m_hsizer->Add(m_search_btn, 0, wxALIGN_CENTER_VERTICAL);
// m_hsizer->AddStretchSpacer(32);
// StretchSpacer has a strange behavior under OSX, so
// There is used just additional sizer for m_mode_sizer with right alignment
@@ -219,33 +304,46 @@ void Tab::create_preset_tab()
m_treectrl->AssignImageList(m_icons);
m_treectrl->AddRoot("root");
m_treectrl->SetIndent(0);
- m_disable_tree_sel_changed_event = 0;
- m_treectrl->Bind(wxEVT_TREE_SEL_CHANGED, &Tab::OnTreeSelChange, this);
+ // Delay processing of the following handler until the message queue is flushed.
+ // This helps to process all the cursor key events on Windows in the tree control,
+ // so that the cursor jumps to the last item.
+ m_treectrl->Bind(wxEVT_TREE_SEL_CHANGED, [this](wxTreeEvent&) {
+#ifdef __linux__
+ // Events queue is opposite On Linux. wxEVT_SET_FOCUS invokes after wxEVT_TREE_SEL_CHANGED,
+ // and a result wxEVT_KILL_FOCUS doesn't invoke for the TextCtrls.
+ // see https://github.com/prusa3d/PrusaSlicer/issues/5720
+ // So, call SetFocus explicitly for this control before changing of the selection
+ m_treectrl->SetFocus();
+#endif
+ if (!m_disable_tree_sel_changed_event && !m_pages.empty()) {
+ if (m_page_switch_running)
+ m_page_switch_planned = true;
+ else {
+ m_page_switch_running = true;
+ do {
+ m_page_switch_planned = false;
+ m_treectrl->Update();
+ } while (this->tree_sel_change_delayed());
+ m_page_switch_running = false;
+ }
+ }
+ });
+
m_treectrl->Bind(wxEVT_KEY_DOWN, &Tab::OnKeyDown, this);
- m_presets_choice->Bind(wxEVT_COMBOBOX, ([this](wxCommandEvent e) {
- //! Because of The MSW and GTK version of wxBitmapComboBox derived from wxComboBox,
- //! but the OSX version derived from wxOwnerDrawnCombo, instead of:
- //! select_preset(m_presets_choice->GetStringSelection().ToUTF8().data());
- //! we doing next:
- int selected_item = m_presets_choice->GetSelection();
- if (m_selected_preset_item == size_t(selected_item) && !m_presets->current_is_dirty())
- return;
- if (selected_item >= 0) {
- std::string selected_string = m_presets_choice->GetString(selected_item).ToUTF8().data();
- if (selected_string.find(PresetCollection::separator_head()) == 0
- /*selected_string == "------- System presets -------" ||
- selected_string == "------- User presets -------"*/) {
- m_presets_choice->SetSelection(m_selected_preset_item);
- if (wxString::FromUTF8(selected_string.c_str()) == PresetCollection::separator(L("Add a new printer")))
- wxTheApp->CallAfter([]() { wxGetApp().run_wizard(ConfigWizard::RR_USER); });
- return;
- }
- m_selected_preset_item = selected_item;
- select_preset(selected_string);
- }
- }));
+ // Initialize the page.
+#ifdef __WXOSX__
+ auto page_parent = m_tmp_panel;
+#else
+ auto page_parent = this;
+#endif
+
+ m_page_view = new wxScrolledWindow(page_parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
+ m_page_sizer = new wxBoxSizer(wxVERTICAL);
+ m_page_view->SetSizer(m_page_sizer);
+ m_page_view->SetScrollbars(1, 20, 1, 2);
+ m_hsizer->Add(m_page_view, 1, wxEXPAND | wxLEFT, 5);
m_btn_save_preset->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { save_preset(); }));
m_btn_delete_preset->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { delete_preset(); }));
@@ -253,15 +351,23 @@ void Tab::create_preset_tab()
toggle_show_hide_incompatible();
}));
- // Fill cache for mode bitmaps
- m_mode_bitmap_cache.reserve(3);
- m_mode_bitmap_cache.push_back(ScalableBitmap(this, "mode_simple" , mode_icon_px_size()));
- m_mode_bitmap_cache.push_back(ScalableBitmap(this, "mode_advanced", mode_icon_px_size()));
- m_mode_bitmap_cache.push_back(ScalableBitmap(this, "mode_expert" , mode_icon_px_size()));
+ if (m_btn_edit_ph_printer)
+ m_btn_edit_ph_printer->Bind(wxEVT_BUTTON, [this](wxCommandEvent e) {
+ if (m_preset_bundle->physical_printers.has_selection())
+ m_presets_choice->edit_physical_printer();
+ else
+ m_presets_choice->add_physical_printer();
+ });
// Initialize the DynamicPrintConfig by default keys/values.
build();
+
+ // ys_FIXME: Following should not be needed, the function will be called later
+ // (update_mode->update_visibility->rebuild_page_tree). This does not work, during the
+ // second call of rebuild_page_tree m_treectrl->GetFirstVisibleItem(); returns zero
+ // for some unknown reason (and the page is not refreshed until user does a selection).
rebuild_page_tree();
+
m_completed = true;
}
@@ -271,7 +377,7 @@ void Tab::add_scaled_button(wxWindow* parent,
const wxString& label/* = wxEmptyString*/,
long style /*= wxBU_EXACTFIT | wxNO_BORDER*/)
{
- *btn = new ScalableButton(parent, wxID_ANY, icon_name, label, wxDefaultSize, wxDefaultPosition, style);
+ *btn = new ScalableButton(parent, wxID_ANY, icon_name, label, wxDefaultSize, wxDefaultPosition, style, true);
m_scaled_buttons.push_back(*btn);
}
@@ -305,6 +411,11 @@ Slic3r::GUI::PageShp Tab::add_options_page(const wxString& title, const std::str
icon_idx = ++m_icon_count;
m_icon_index[icon] = icon_idx;
}
+
+ if (m_category_icon.find(title) == m_category_icon.end()) {
+ // Add new category to the category_to_icon list.
+ m_category_icon[title] = icon;
+ }
}
// Initialize the page.
#ifdef __WXOSX__
@@ -312,16 +423,12 @@ Slic3r::GUI::PageShp Tab::add_options_page(const wxString& title, const std::str
#else
auto panel = this;
#endif
- PageShp page(new Page(panel, title, icon_idx, m_mode_bitmap_cache));
+ PageShp page(new Page(m_page_view, title, icon_idx));
// page->SetBackgroundStyle(wxBG_STYLE_SYSTEM);
#ifdef __WINDOWS__
// page->SetDoubleBuffered(true);
#endif //__WINDOWS__
- page->SetScrollbars(1, 20, 1, 2);
- page->Hide();
- m_hsizer->Add(page.get(), 1, wxEXPAND | wxLEFT, 5);
-
if (!is_extruder_pages)
m_pages.push_back(page);
@@ -329,21 +436,61 @@ Slic3r::GUI::PageShp Tab::add_options_page(const wxString& title, const std::str
return page;
}
+// Names of categories is save in English always. We translate them only for UI.
+// But category "Extruder n" can't be translated regularly (using _()), so
+// just for this category we should splite the title and translate "Extruder" word separately
+wxString Tab::translate_category(const wxString& title, Preset::Type preset_type)
+{
+ if (preset_type == Preset::TYPE_PRINTER && title.Contains("Extruder ")) {
+ return _("Extruder") + title.SubString(8, title.Last());
+ }
+ return _(title);
+}
+
void Tab::OnActivate()
{
-#ifdef __WXOSX__
wxWindowUpdateLocker noUpdates(this);
-
+#ifdef __WXOSX__
+// wxWindowUpdateLocker noUpdates(this);
auto size = GetSizer()->GetSize();
m_tmp_panel->GetSizer()->SetMinSize(size.x + m_size_move, size.y);
Fit();
m_size_move *= -1;
#endif // __WXOSX__
+
+#ifdef __WXMSW__
+ // Workaround for tooltips over Tree Controls displayed over excessively long
+ // tree control items, stealing the window focus.
+ //
+ // In case the Tab was reparented from the MainFrame to the floating dialog,
+ // the tooltip created by the Tree Control before reparenting is not reparented,
+ // but it still points to the MainFrame. If the tooltip pops up, the MainFrame
+ // is incorrectly focussed, stealing focus from the floating dialog.
+ //
+ // The workaround is to delete the tooltip control.
+ // Vojtech tried to reparent the tooltip control, but it did not work,
+ // and if the Tab was later reparented back to MainFrame, the tooltip was displayed
+ // at an incorrect position, therefore it is safer to just discard the tooltip control
+ // altogether.
+ HWND hwnd_tt = TreeView_GetToolTips(m_treectrl->GetHandle());
+ if (hwnd_tt) {
+ HWND hwnd_toplevel = find_toplevel_parent(m_treectrl)->GetHandle();
+ HWND hwnd_parent = ::GetParent(hwnd_tt);
+ if (hwnd_parent != hwnd_toplevel) {
+ ::DestroyWindow(hwnd_tt);
+ TreeView_SetToolTips(m_treectrl->GetHandle(), nullptr);
+ }
+ }
+#endif
+
+ // create controls on active page
+ activate_selected_page([](){});
+ m_hsizer->Layout();
+ Refresh();
}
void Tab::update_labels_colour()
{
-// Freeze();
//update options "decoration"
for (const auto opt : m_options_list)
{
@@ -358,20 +505,17 @@ void Tab::update_labels_colour()
else
color = &m_modified_label_clr;
}
- if (opt.first == "bed_shape" || opt.first == "compatible_prints" || opt.first == "compatible_printers") {
- wxStaticText* label = (m_colored_Labels.find(opt.first) == m_colored_Labels.end()) ? nullptr : m_colored_Labels.at(opt.first);
- if (label) {
- label->SetForegroundColour(*color);
- label->Refresh(true);
- }
+ if (opt.first == "bed_shape" || opt.first == "filament_ramming_parameters" ||
+ opt.first == "compatible_prints" || opt.first == "compatible_printers" ) {
+ if (m_colored_Label_colors.find(opt.first) != m_colored_Label_colors.end())
+ m_colored_Label_colors.at(opt.first) = *color;
continue;
}
Field* field = get_field(opt.first);
if (field == nullptr) continue;
- field->set_label_colour_force(color);
+ field->set_label_colour(color);
}
-// Thaw();
auto cur_item = m_treectrl->GetFirstVisibleItem();
if (!cur_item || !m_treectrl->IsVisible(cur_item))
@@ -380,7 +524,7 @@ void Tab::update_labels_colour()
auto title = m_treectrl->GetItemText(cur_item);
for (auto page : m_pages)
{
- if (page->title() != title)
+ if (translate_category(page->title(), m_type) != title)
continue;
const wxColor *clr = !page->m_is_nonsys_values ? &m_sys_label_clr :
@@ -394,42 +538,32 @@ void Tab::update_labels_colour()
}
}
-// Update UI according to changes
-void Tab::update_changed_ui()
+void Tab::decorate()
{
- if (m_postpone_update_ui)
- return;
-
- const bool deep_compare = (m_type == Slic3r::Preset::TYPE_PRINTER || m_type == Slic3r::Preset::TYPE_SLA_MATERIAL);
- auto dirty_options = m_presets->current_dirty_options(deep_compare);
- auto nonsys_options = m_presets->current_different_from_parent_options(deep_compare);
- if (m_type == Slic3r::Preset::TYPE_PRINTER) {
- TabPrinter* tab = static_cast<TabPrinter*>(this);
- if (tab->m_initial_extruders_count != tab->m_extruders_count)
- dirty_options.emplace_back("extruders_count");
- if (tab->m_sys_extruders_count != tab->m_extruders_count)
- nonsys_options.emplace_back("extruders_count");
- }
+ for (const auto opt : m_options_list)
+ {
+ Field* field = nullptr;
+ wxColour* colored_label_clr = nullptr;
- for (auto& it : m_options_list)
- it.second = m_opt_status_value;
+ if (opt.first == "bed_shape" || opt.first == "filament_ramming_parameters" ||
+ opt.first == "compatible_prints" || opt.first == "compatible_printers")
+ colored_label_clr = (m_colored_Label_colors.find(opt.first) == m_colored_Label_colors.end()) ? nullptr : &m_colored_Label_colors.at(opt.first);
- for (auto opt_key : dirty_options) m_options_list[opt_key] &= ~osInitValue;
- for (auto opt_key : nonsys_options) m_options_list[opt_key] &= ~osSystemValue;
+ if (!colored_label_clr) {
+ field = get_field(opt.first);
+ if (!field)
+ continue;
+ }
-// Freeze();
- //update options "decoration"
- for (const auto opt : m_options_list)
- {
bool is_nonsys_value = false;
bool is_modified_value = true;
- const ScalableBitmap *sys_icon = &m_bmp_value_lock;
- const ScalableBitmap *icon = &m_bmp_value_revert;
+ const ScalableBitmap* sys_icon = &m_bmp_value_lock;
+ const ScalableBitmap* icon = &m_bmp_value_revert;
- const wxColour *color = m_is_default_preset ? &m_default_text_clr : &m_sys_label_clr;
+ const wxColour* color = m_is_default_preset ? &m_default_text_clr : &m_sys_label_clr;
- const wxString *sys_tt = &m_tt_value_lock;
- const wxString *tt = &m_tt_value_revert;
+ const wxString* sys_tt = &m_tt_value_lock;
+ const wxString* tt = &m_tt_value_revert;
// value isn't equal to system value
if ((opt.second & osSystemValue) == 0) {
@@ -449,17 +583,12 @@ void Tab::update_changed_ui()
icon = &m_bmp_white_bullet;
tt = &m_tt_white_bullet;
}
- if (opt.first == "bed_shape" || opt.first == "compatible_prints" || opt.first == "compatible_printers") {
- wxStaticText* label = (m_colored_Labels.find(opt.first) == m_colored_Labels.end()) ? nullptr : m_colored_Labels.at(opt.first);
- if (label) {
- label->SetForegroundColour(*color);
- label->Refresh(true);
- }
+
+ if (colored_label_clr) {
+ *colored_label_clr = *color;
continue;
}
-
- Field* field = get_field(opt.first);
- if (field == nullptr) continue;
+
field->m_is_nonsys_value = is_nonsys_value;
field->m_is_modified_value = is_modified_value;
field->set_undo_bitmap(icon);
@@ -468,7 +597,35 @@ void Tab::update_changed_ui()
field->set_undo_to_sys_tooltip(sys_tt);
field->set_label_colour(color);
}
-// Thaw();
+
+ if (m_active_page)
+ m_active_page->refresh();
+}
+
+// Update UI according to changes
+void Tab::update_changed_ui()
+{
+ if (m_postpone_update_ui)
+ return;
+
+ const bool deep_compare = (m_type == Slic3r::Preset::TYPE_PRINTER || m_type == Slic3r::Preset::TYPE_SLA_MATERIAL);
+ auto dirty_options = m_presets->current_dirty_options(deep_compare);
+ auto nonsys_options = m_presets->current_different_from_parent_options(deep_compare);
+ if (m_type == Slic3r::Preset::TYPE_PRINTER) {
+ TabPrinter* tab = static_cast<TabPrinter*>(this);
+ if (tab->m_initial_extruders_count != tab->m_extruders_count)
+ dirty_options.emplace_back("extruders_count");
+ if (tab->m_sys_extruders_count != tab->m_extruders_count)
+ nonsys_options.emplace_back("extruders_count");
+ }
+
+ for (auto& it : m_options_list)
+ it.second = m_opt_status_value;
+
+ for (auto opt_key : dirty_options) m_options_list[opt_key] &= ~osInitValue;
+ for (auto opt_key : nonsys_options) m_options_list[opt_key] &= ~osSystemValue;
+
+ decorate();
wxTheApp->CallAfter([this]() {
if (parent()) //To avoid a crash, parent should be exist for a moment of a tree updating
@@ -500,7 +657,7 @@ void TabPrinter::init_options_list()
for (const auto opt_key : m_config->keys())
{
- if (opt_key == "bed_shape") {
+ if (opt_key == "bed_shape" || opt_key == "thumbnails") {
m_options_list.emplace(opt_key, m_opt_status_value);
continue;
}
@@ -527,6 +684,21 @@ void TabPrinter::msw_rescale()
for (auto page : pages)
page->msw_rescale();
+ if (m_reset_to_filament_color)
+ m_reset_to_filament_color->msw_rescale();
+
+ Layout();
+}
+
+void TabPrinter::sys_color_changed()
+{
+ Tab::sys_color_changed();
+
+ // update missed options_groups
+ const std::vector<PageShp>& pages = m_printer_technology == ptFFF ? m_pages_sla : m_pages_fff;
+ for (auto page : pages)
+ page->sys_color_changed();
+
Layout();
}
@@ -579,17 +751,20 @@ void Tab::update_changed_tree_ui()
auto title = m_treectrl->GetItemText(cur_item);
for (auto page : m_pages)
{
- if (page->title() != title)
+ if (translate_category(page->title(), m_type) != title)
continue;
bool sys_page = true;
bool modified_page = false;
- if (title == _("General")) {
+ if (page->title() == "General") {
std::initializer_list<const char*> optional_keys{ "extruders_count", "bed_shape" };
for (auto &opt_key : optional_keys) {
get_sys_and_mod_flags(opt_key, sys_page, modified_page);
}
}
- if (title == _("Dependencies")) {
+ if (m_type == Preset::TYPE_FILAMENT && page->title() == "Advanced") {
+ get_sys_and_mod_flags("filament_ramming_parameters", sys_page, modified_page);
+ }
+ if (page->title() == "Dependencies") {
if (m_type == Slic3r::Preset::TYPE_PRINTER) {
sys_page = m_presets->get_selected_preset_parent() != nullptr;
modified_page = false;
@@ -603,8 +778,8 @@ void Tab::update_changed_tree_ui()
{
if (!sys_page && modified_page)
break;
- for (t_opt_map::iterator it = group->m_opt_map.begin(); it != group->m_opt_map.end(); ++it) {
- const std::string& opt_key = it->first;
+ for (const auto &kvp : group->opt_map()) {
+ const std::string& opt_key = kvp.first;
get_sys_and_mod_flags(opt_key, sys_page, modified_page);
}
}
@@ -642,6 +817,8 @@ void Tab::update_undo_buttons()
void Tab::on_roll_back_value(const bool to_sys /*= true*/)
{
+ if (!m_active_page) return;
+
int os;
if (to_sys) {
if (!m_is_nonsys_values) return;
@@ -654,49 +831,47 @@ void Tab::on_roll_back_value(const bool to_sys /*= true*/)
m_postpone_update_ui = true;
- auto selection = m_treectrl->GetItemText(m_treectrl->GetSelection());
- for (auto page : m_pages)
- if (page->title() == selection) {
- for (auto group : page->m_optgroups) {
- if (group->title == _("Capabilities")) {
- if ((m_options_list["extruders_count"] & os) == 0)
- to_sys ? group->back_to_sys_value("extruders_count") : group->back_to_initial_value("extruders_count");
- }
- if (group->title == _("Size and coordinates")) {
- if ((m_options_list["bed_shape"] & os) == 0) {
- to_sys ? group->back_to_sys_value("bed_shape") : group->back_to_initial_value("bed_shape");
- load_key_value("bed_shape", true/*some value*/, true);
- }
-
- }
- if (group->title == _("Profile dependencies")) {
- // "compatible_printers" option doesn't exists in Printer Settimgs Tab
- if (m_type != Preset::TYPE_PRINTER && (m_options_list["compatible_printers"] & os) == 0) {
- to_sys ? group->back_to_sys_value("compatible_printers") : group->back_to_initial_value("compatible_printers");
- load_key_value("compatible_printers", true/*some value*/, true);
-
- bool is_empty = m_config->option<ConfigOptionStrings>("compatible_printers")->values.empty();
- m_compatible_printers.checkbox->SetValue(is_empty);
- is_empty ? m_compatible_printers.btn->Disable() : m_compatible_printers.btn->Enable();
- }
- // "compatible_prints" option exists only in Filament Settimgs and Materials Tabs
- if ((m_type == Preset::TYPE_FILAMENT || m_type == Preset::TYPE_SLA_MATERIAL) && (m_options_list["compatible_prints"] & os) == 0) {
- to_sys ? group->back_to_sys_value("compatible_prints") : group->back_to_initial_value("compatible_prints");
- load_key_value("compatible_prints", true/*some value*/, true);
-
- bool is_empty = m_config->option<ConfigOptionStrings>("compatible_prints")->values.empty();
- m_compatible_prints.checkbox->SetValue(is_empty);
- is_empty ? m_compatible_prints.btn->Disable() : m_compatible_prints.btn->Enable();
- }
- }
- for (auto kvp : group->m_opt_map) {
- const std::string& opt_key = kvp.first;
- if ((m_options_list[opt_key] & os) == 0)
- to_sys ? group->back_to_sys_value(opt_key) : group->back_to_initial_value(opt_key);
- }
+ for (auto group : m_active_page->m_optgroups) {
+ if (group->title == "Capabilities") {
+ if ((m_options_list["extruders_count"] & os) == 0)
+ to_sys ? group->back_to_sys_value("extruders_count") : group->back_to_initial_value("extruders_count");
+ }
+ if (group->title == "Size and coordinates") {
+ if ((m_options_list["bed_shape"] & os) == 0) {
+ to_sys ? group->back_to_sys_value("bed_shape") : group->back_to_initial_value("bed_shape");
+ load_key_value("bed_shape", true/*some value*/, true);
}
- break;
}
+ if (group->title == "Toolchange parameters with single extruder MM printers") {
+ if ((m_options_list["filament_ramming_parameters"] & os) == 0)
+ to_sys ? group->back_to_sys_value("filament_ramming_parameters") : group->back_to_initial_value("filament_ramming_parameters");
+ }
+ if (group->title == "Profile dependencies") {
+ // "compatible_printers" option doesn't exists in Printer Settimgs Tab
+ if (m_type != Preset::TYPE_PRINTER && (m_options_list["compatible_printers"] & os) == 0) {
+ to_sys ? group->back_to_sys_value("compatible_printers") : group->back_to_initial_value("compatible_printers");
+ load_key_value("compatible_printers", true/*some value*/, true);
+
+ bool is_empty = m_config->option<ConfigOptionStrings>("compatible_printers")->values.empty();
+ m_compatible_printers.checkbox->SetValue(is_empty);
+ is_empty ? m_compatible_printers.btn->Disable() : m_compatible_printers.btn->Enable();
+ }
+ // "compatible_prints" option exists only in Filament Settimgs and Materials Tabs
+ if ((m_type == Preset::TYPE_FILAMENT || m_type == Preset::TYPE_SLA_MATERIAL) && (m_options_list["compatible_prints"] & os) == 0) {
+ to_sys ? group->back_to_sys_value("compatible_prints") : group->back_to_initial_value("compatible_prints");
+ load_key_value("compatible_prints", true/*some value*/, true);
+
+ bool is_empty = m_config->option<ConfigOptionStrings>("compatible_prints")->values.empty();
+ m_compatible_prints.checkbox->SetValue(is_empty);
+ is_empty ? m_compatible_prints.btn->Disable() : m_compatible_prints.btn->Enable();
+ }
+ }
+ for (const auto &kvp : group->opt_map()) {
+ const std::string& opt_key = kvp.first;
+ if ((m_options_list[opt_key] & os) == 0)
+ to_sys ? group->back_to_sys_value(opt_key) : group->back_to_initial_value(opt_key);
+ }
+ }
m_postpone_update_ui = false;
update_changed_ui();
@@ -706,14 +881,14 @@ void Tab::on_roll_back_value(const bool to_sys /*= true*/)
// comparing the selected preset config with $self->{config}.
void Tab::update_dirty()
{
- m_presets->update_dirty_ui(m_presets_choice);
+ m_presets_choice->update_dirty();
on_presets_changed();
update_changed_ui();
}
void Tab::update_tab_ui()
{
- m_selected_preset_item = m_presets->update_tab_ui(m_presets_choice, m_show_incompatible_presets, m_em_unit);
+ m_presets_choice->update();
}
// Load a provied DynamicConfig into the tab, modifying the active preset.
@@ -736,10 +911,8 @@ void Tab::load_config(const DynamicPrintConfig& config)
// Reload current $self->{config} (aka $self->{presets}->edited_preset->config) into the UI fields.
void Tab::reload_config()
{
-// Freeze();
- for (auto page : m_pages)
- page->reload_config();
-// Thaw();
+ if (m_active_page)
+ m_active_page->reload_config();
}
void Tab::update_mode()
@@ -758,16 +931,12 @@ void Tab::update_visibility()
{
Freeze(); // There is needed Freeze/Thaw to avoid a flashing after Show/Layout
- // m_detach_preset_btn will be shown always after call page->update_visibility()
- // So let save a "show state" of m_detach_preset_btn before update_visibility
- bool was_shown = m_detach_preset_btn->IsShown();
-
for (auto page : m_pages)
- page->update_visibility(m_mode);
- update_page_tree_visibility();
+ page->update_visibility(m_mode, page.get() == m_active_page);
+ rebuild_page_tree();
- // update visibility for detach_preset_btn
- m_detach_preset_btn->Show(was_shown);
+ if (this->m_type == Preset::TYPE_SLA_PRINT)
+ update_description_lines();
Layout();
Thaw();
@@ -775,22 +944,21 @@ void Tab::update_visibility()
void Tab::msw_rescale()
{
- m_em_unit = wxGetApp().em_unit();
+ m_em_unit = em_unit(m_parent);
m_mode_sizer->msw_rescale();
+ m_presets_choice->msw_rescale();
- m_presets_choice->SetSize(35 * m_em_unit, -1);
m_treectrl->SetMinSize(wxSize(20 * m_em_unit, -1));
- update_tab_ui();
-
// rescale buttons and cached bitmaps
for (const auto btn : m_scaled_buttons)
btn->msw_rescale();
for (const auto bmp : m_scaled_bitmaps)
bmp->msw_rescale();
- for (ScalableBitmap& bmp : m_mode_bitmap_cache)
- bmp.msw_rescale();
+
+ if (m_detach_preset_btn)
+ m_detach_preset_btn->msw_rescale();
// rescale icons for tree_ctrl
for (ScalableBitmap& bmp : m_scaled_icons_list)
@@ -803,34 +971,86 @@ void Tab::msw_rescale()
m_treectrl->AssignImageList(m_icons);
// rescale options_groups
- for (auto page : m_pages)
- page->msw_rescale();
+ if (m_active_page)
+ m_active_page->msw_rescale();
+
+ Layout();
+}
+
+void Tab::sys_color_changed()
+{
+ update_tab_ui();
+ m_presets_choice->msw_rescale();
+
+ // update buttons and cached bitmaps
+ for (const auto btn : m_scaled_buttons)
+ btn->msw_rescale();
+ for (const auto bmp : m_scaled_bitmaps)
+ bmp->msw_rescale();
+
+ // update icons for tree_ctrl
+ for (ScalableBitmap& bmp : m_scaled_icons_list)
+ bmp.msw_rescale();
+ // recreate and set new ImageList for tree_ctrl
+ m_icons->RemoveAll();
+ m_icons = new wxImageList(m_scaled_icons_list.front().bmp().GetWidth(), m_scaled_icons_list.front().bmp().GetHeight());
+ for (ScalableBitmap& bmp : m_scaled_icons_list)
+ m_icons->Add(bmp.bmp());
+ m_treectrl->AssignImageList(m_icons);
+
+ // Colors for ui "decoration"
+ m_sys_label_clr = wxGetApp().get_label_clr_sys();
+ m_modified_label_clr = wxGetApp().get_label_clr_modified();
+ update_labels_colour();
+
+ // update options_groups
+ if (m_active_page)
+ m_active_page->msw_rescale();
Layout();
}
Field* Tab::get_field(const t_config_option_key& opt_key, int opt_index/* = -1*/) const
{
+ return m_active_page ? m_active_page->get_field(opt_key, opt_index) : nullptr;
+}
+
+std::pair<OG_CustomCtrl*, bool*> Tab::get_custom_ctrl_with_blinking_ptr(const t_config_option_key& opt_key, int opt_index/* = -1*/)
+{
+ if (!m_active_page)
+ return {nullptr, nullptr};
+
+ std::pair<OG_CustomCtrl*, bool*> ret = {nullptr, nullptr};
+
+ for (auto opt_group : m_active_page->m_optgroups) {
+ ret = opt_group->get_custom_ctrl_with_blinking_ptr(opt_key, opt_index);
+ if (ret.first && ret.second)
+ break;
+ }
+ return ret;
+}
+
+Field* Tab::get_field(const t_config_option_key& opt_key, Page** selected_page, int opt_index/* = -1*/)
+{
Field* field = nullptr;
for (auto page : m_pages) {
field = page->get_field(opt_key, opt_index);
- if (field != nullptr)
+ if (field != nullptr) {
+ *selected_page = page.get();
return field;
+ }
}
return field;
}
-// Set a key/value pair on this page. Return true if the value has been modified.
-// Currently used for distributing extruders_count over preset pages of Slic3r::GUI::Tab::Printer
-// after a preset is loaded.
-bool Tab::set_value(const t_config_option_key& opt_key, const boost::any& value) {
- bool changed = false;
- for(auto page: m_pages) {
- if (page->set_value(opt_key, value))
- changed = true;
- }
- return changed;
-}
+void Tab::toggle_option(const std::string& opt_key, bool toggle, int opt_index/* = -1*/)
+{
+ if (!m_active_page)
+ return;
+ Field* field = m_active_page->get_field(opt_key, opt_index);
+ if (field)
+ field->toggle(toggle);
+};
// To be called by custom widgets, load a value into a config,
// update the preset selection boxes (the dirty flags)
@@ -844,7 +1064,7 @@ void Tab::load_key_value(const std::string& opt_key, const boost::any& value, bo
// Don't select another profile if this profile happens to become incompatible.
m_preset_bundle->update_compatible(PresetSelectCompatibleType::Never);
}
- m_presets->update_dirty_ui(m_presets_choice);
+ m_presets_choice->update_dirty();
on_presets_changed();
update();
}
@@ -883,7 +1103,7 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
if (opt_key == "pad_around_object") {
for (PageShp &pg : m_pages) {
- Field * fld = pg->get_field(opt_key);
+ Field * fld = pg->get_field(opt_key); /// !!! ysFIXME ????
if (fld) fld->set_value(value, false);
}
}
@@ -925,6 +1145,65 @@ void Tab::update_wiping_button_visibility() {
}
}
+void Tab::activate_option(const std::string& opt_key, const wxString& category)
+{
+ wxString page_title = translate_category(category, m_type);
+
+ auto cur_item = m_treectrl->GetFirstVisibleItem();
+ if (!cur_item || !m_treectrl->IsVisible(cur_item))
+ return;
+
+ while (cur_item) {
+ auto title = m_treectrl->GetItemText(cur_item);
+ if (page_title != title) {
+ cur_item = m_treectrl->GetNextVisible(cur_item);
+ continue;
+ }
+
+ m_treectrl->SelectItem(cur_item);
+ break;
+ }
+
+ // we should to activate a tab with searched option, if it doesn't.
+ wxGetApp().mainframe->select_tab(this);
+ Field* field = get_field(opt_key);
+
+ // focused selected field
+ if (field)
+ field->getWindow()->SetFocus();
+ else if (category == "Single extruder MM setup") {
+ // When we show and hide "Single extruder MM setup" page,
+ // related options are still in the search list
+ // So, let's hightlighte a "single_extruder_multi_material" option,
+ // as a "way" to show hidden page again
+ field = get_field("single_extruder_multi_material");
+ if (field)
+ field->getWindow()->SetFocus();
+ }
+
+ m_highlighter.init(get_custom_ctrl_with_blinking_ptr(opt_key));
+}
+
+void Tab::apply_searcher()
+{
+ wxGetApp().sidebar().get_searcher().apply(m_config, m_type, m_mode);
+}
+
+void Tab::cache_config_diff(const std::vector<std::string>& selected_options)
+{
+ m_cache_config.apply_only(m_presets->get_edited_preset().config, selected_options);
+}
+
+void Tab::apply_config_from_cache()
+{
+ if (!m_cache_config.empty()) {
+ m_presets->get_edited_preset().config.apply(m_cache_config);
+ m_cache_config.clear();
+
+ update_dirty();
+ }
+}
+
// Call a callback to update the selection of presets on the plater:
// To update the content of the selection boxes,
@@ -939,14 +1218,16 @@ void Tab::on_presets_changed()
// Instead of PostEvent (EVT_TAB_PRESETS_CHANGED) just call update_presets
wxGetApp().plater()->sidebar().update_presets(m_type);
- update_preset_description_line();
// Printer selected at the Printer tab, update "compatible" marks at the print and filament selectors.
for (auto t: m_dependent_tabs)
{
+ Tab* tab = wxGetApp().get_tab(t);
// If the printer tells us that the print or filament/sla_material preset has been switched or invalidated,
// refresh the print or filament/sla_material tab page.
- wxGetApp().get_tab(t)->load_current_preset();
+ // But if there are options, moved from the previously selected preset, update them to edited preset
+ tab->apply_config_from_cache();
+ tab->load_current_preset();
}
// clear m_dependent_tabs after first update from select_preset()
// to avoid needless preset loading from update() function
@@ -960,7 +1241,8 @@ void Tab::build_preset_description_line(ConfigOptionsGroup* optgroup)
};
auto detach_preset_btn = [this](wxWindow* parent) {
- add_scaled_button(parent, &m_detach_preset_btn, "lock_open_sys", _(L("Detach from system preset")), wxBU_LEFT | wxBU_EXACTFIT);
+ m_detach_preset_btn = new ScalableButton(parent, wxID_ANY, "lock_open_sys", _L("Detach from system preset"),
+ wxDefaultSize, wxDefaultPosition, wxBU_LEFT | wxBU_EXACTFIT, true);
ScalableButton* btn = m_detach_preset_btn;
btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
@@ -1013,7 +1295,9 @@ void Tab::update_preset_description_line()
} else if (parent == nullptr) {
description_line = _(L("Current preset is inherited from the default preset."));
} else {
- description_line = _(L("Current preset is inherited from")) + ":\n\t" + parent->name;
+ std::string name = parent->name;
+ boost::replace_all(name, "&", "&&");
+ description_line = _(L("Current preset is inherited from")) + ":\n\t" + from_u8(name);
}
if (preset.is_default || preset.is_system)
@@ -1105,28 +1389,31 @@ void TabPrint::build()
m_presets = &m_preset_bundle->prints;
load_initial_data();
- auto page = add_options_page(_(L("Layers and perimeters")), "layers");
- auto optgroup = page->new_optgroup(_(L("Layer height")));
- optgroup->append_single_option_line("layer_height");
- optgroup->append_single_option_line("first_layer_height");
+ auto page = add_options_page(L("Layers and perimeters"), "layers");
+ wxString category_path = "layers-and-perimeters_1748#";
+ auto optgroup = page->new_optgroup(L("Layer height"));
+ optgroup->append_single_option_line("layer_height", category_path + "layer-height");
+ optgroup->append_single_option_line("first_layer_height", category_path + "first-layer-height");
- optgroup = page->new_optgroup(_(L("Vertical shells")));
- optgroup->append_single_option_line("perimeters");
- optgroup->append_single_option_line("spiral_vase");
+ optgroup = page->new_optgroup(L("Vertical shells"));
+ optgroup->append_single_option_line("perimeters", category_path + "perimeters");
+ optgroup->append_single_option_line("spiral_vase", category_path + "spiral-vase");
Line line { "", "" };
line.full_width = 1;
+ line.label_path = category_path + "recommended-thin-wall-thickness";
line.widget = [this](wxWindow* parent) {
return description_line_widget(parent, &m_recommended_thin_wall_thickness_description_line);
};
optgroup->append_line(line);
- optgroup = page->new_optgroup(_(L("Horizontal shells")));
- line = { _(L("Solid layers")), "" };
+ optgroup = page->new_optgroup(L("Horizontal shells"));
+ line = { L("Solid layers"), "" };
+ line.label_path = category_path + "solid-layers-top-bottom";
line.append_option(optgroup->get_option("top_solid_layers"));
line.append_option(optgroup->get_option("bottom_solid_layers"));
optgroup->append_line(line);
- line = { _(L("Minimum shell thickness")), "" };
+ line = { L("Minimum shell thickness"), "" };
line.append_option(optgroup->get_option("top_solid_min_thickness"));
line.append_option(optgroup->get_option("bottom_solid_min_thickness"));
optgroup->append_line(line);
@@ -1137,74 +1424,86 @@ void TabPrint::build()
};
optgroup->append_line(line);
- optgroup = page->new_optgroup(_(L("Quality (slower slicing)")));
- optgroup->append_single_option_line("extra_perimeters");
- optgroup->append_single_option_line("ensure_vertical_shell_thickness");
- optgroup->append_single_option_line("avoid_crossing_perimeters");
- optgroup->append_single_option_line("thin_walls");
- optgroup->append_single_option_line("overhangs");
-
- optgroup = page->new_optgroup(_(L("Advanced")));
- optgroup->append_single_option_line("seam_position");
- optgroup->append_single_option_line("external_perimeters_first");
-
- page = add_options_page(_(L("Infill")), "infill");
- optgroup = page->new_optgroup(_(L("Infill")));
- optgroup->append_single_option_line("fill_density");
- optgroup->append_single_option_line("fill_pattern");
- optgroup->append_single_option_line("top_fill_pattern");
- optgroup->append_single_option_line("bottom_fill_pattern");
-
- optgroup = page->new_optgroup(_(L("Reducing printing time")));
- optgroup->append_single_option_line("infill_every_layers");
- optgroup->append_single_option_line("infill_only_where_needed");
-
- optgroup = page->new_optgroup(_(L("Advanced")));
- optgroup->append_single_option_line("solid_infill_every_layers");
- optgroup->append_single_option_line("fill_angle");
- optgroup->append_single_option_line("solid_infill_below_area");
+ optgroup = page->new_optgroup(L("Quality (slower slicing)"));
+ optgroup->append_single_option_line("extra_perimeters", category_path + "extra-perimeters-if-needed");
+ optgroup->append_single_option_line("ensure_vertical_shell_thickness", category_path + "ensure-vertical-shell-thickness");
+ optgroup->append_single_option_line("avoid_crossing_perimeters", category_path + "avoid-crossing-perimeters");
+ optgroup->append_single_option_line("avoid_crossing_perimeters_max_detour", category_path + "avoid_crossing_perimeters_max_detour");
+ optgroup->append_single_option_line("thin_walls", category_path + "detect-thin-walls");
+ optgroup->append_single_option_line("overhangs", category_path + "detect-bridging-perimeters");
+
+ optgroup = page->new_optgroup(L("Advanced"));
+ optgroup->append_single_option_line("seam_position", category_path + "seam-position");
+ optgroup->append_single_option_line("external_perimeters_first", category_path + "external-perimeters-first");
+
+ page = add_options_page(L("Infill"), "infill");
+ category_path = "infill_42#";
+ optgroup = page->new_optgroup(L("Infill"));
+ optgroup->append_single_option_line("fill_density", category_path + "fill-density");
+ optgroup->append_single_option_line("fill_pattern", category_path + "fill-pattern");
+ optgroup->append_single_option_line("infill_anchor", category_path + "fill-pattern");
+ optgroup->append_single_option_line("infill_anchor_max", category_path + "fill-pattern");
+ optgroup->append_single_option_line("top_fill_pattern", category_path + "top-fill-pattern");
+ optgroup->append_single_option_line("bottom_fill_pattern", category_path + "bottom-fill-pattern");
+
+ optgroup = page->new_optgroup(L("Ironing"));
+ optgroup->append_single_option_line("ironing");
+ optgroup->append_single_option_line("ironing_type");
+ optgroup->append_single_option_line("ironing_flowrate");
+ optgroup->append_single_option_line("ironing_spacing");
+
+ optgroup = page->new_optgroup(L("Reducing printing time"));
+ optgroup->append_single_option_line("infill_every_layers", category_path + "combine-infill-every-x-layers");
+ optgroup->append_single_option_line("infill_only_where_needed", category_path + "only-infill-where-needed");
+
+ optgroup = page->new_optgroup(L("Advanced"));
+ optgroup->append_single_option_line("solid_infill_every_layers", category_path + "solid-infill-every-x-layers");
+ optgroup->append_single_option_line("fill_angle", category_path + "fill-angle");
+ optgroup->append_single_option_line("solid_infill_below_area", category_path + "solid-infill-threshold-area");
optgroup->append_single_option_line("bridge_angle");
optgroup->append_single_option_line("only_retract_when_crossing_perimeters");
optgroup->append_single_option_line("infill_first");
- page = add_options_page(_(L("Skirt and brim")), "skirt+brim");
- optgroup = page->new_optgroup(_(L("Skirt")));
- optgroup->append_single_option_line("skirts");
- optgroup->append_single_option_line("skirt_distance");
- optgroup->append_single_option_line("skirt_height");
- optgroup->append_single_option_line("draft_shield");
- optgroup->append_single_option_line("min_skirt_length");
-
- optgroup = page->new_optgroup(_(L("Brim")));
- optgroup->append_single_option_line("brim_width");
-
- page = add_options_page(_(L("Support material")), "support");
- optgroup = page->new_optgroup(_(L("Support material")));
- optgroup->append_single_option_line("support_material");
- optgroup->append_single_option_line("support_material_auto");
- optgroup->append_single_option_line("support_material_threshold");
- optgroup->append_single_option_line("support_material_enforce_layers");
-
- optgroup = page->new_optgroup(_(L("Raft")));
- optgroup->append_single_option_line("raft_layers");
+ page = add_options_page(L("Skirt and brim"), "skirt+brim");
+ category_path = "skirt-and-brim_133969#";
+ optgroup = page->new_optgroup(L("Skirt"));
+ optgroup->append_single_option_line("skirts", category_path + "skirt");
+ optgroup->append_single_option_line("skirt_distance", category_path + "skirt");
+ optgroup->append_single_option_line("skirt_height", category_path + "skirt");
+ optgroup->append_single_option_line("draft_shield", category_path + "skirt");
+ optgroup->append_single_option_line("min_skirt_length", category_path + "skirt");
+
+ optgroup = page->new_optgroup(L("Brim"));
+ optgroup->append_single_option_line("brim_width", category_path + "brim");
+
+ page = add_options_page(L("Support material"), "support");
+ category_path = "support-material_1698#";
+ optgroup = page->new_optgroup(L("Support material"));
+ optgroup->append_single_option_line("support_material", category_path + "generate-support-material");
+ optgroup->append_single_option_line("support_material_auto", category_path + "auto-generated-supports");
+ optgroup->append_single_option_line("support_material_threshold", category_path + "overhang-threshold");
+ optgroup->append_single_option_line("support_material_enforce_layers", category_path + "enforce-support-for-the-first");
+
+ optgroup = page->new_optgroup(L("Raft"));
+ optgroup->append_single_option_line("raft_layers", category_path + "raft-layers");
// # optgroup->append_single_option_line(get_option_("raft_contact_distance");
- optgroup = page->new_optgroup(_(L("Options for support material and raft")));
- optgroup->append_single_option_line("support_material_contact_distance");
- optgroup->append_single_option_line("support_material_pattern");
- optgroup->append_single_option_line("support_material_with_sheath");
- optgroup->append_single_option_line("support_material_spacing");
- optgroup->append_single_option_line("support_material_angle");
- optgroup->append_single_option_line("support_material_interface_layers");
- optgroup->append_single_option_line("support_material_interface_spacing");
- optgroup->append_single_option_line("support_material_interface_contact_loops");
- optgroup->append_single_option_line("support_material_buildplate_only");
- optgroup->append_single_option_line("support_material_xy_spacing");
- optgroup->append_single_option_line("dont_support_bridges");
- optgroup->append_single_option_line("support_material_synchronize_layers");
-
- page = add_options_page(_(L("Speed")), "time");
- optgroup = page->new_optgroup(_(L("Speed for print moves")));
+ optgroup = page->new_optgroup(L("Options for support material and raft"));
+ optgroup->append_single_option_line("support_material_contact_distance", category_path + "contact-z-distance");
+ optgroup->append_single_option_line("support_material_pattern", category_path + "pattern");
+ optgroup->append_single_option_line("support_material_with_sheath", category_path + "with-sheath-around-the-support");
+ optgroup->append_single_option_line("support_material_spacing", category_path + "pattern-spacing-0-inf");
+ optgroup->append_single_option_line("support_material_angle", category_path + "pattern-angle");
+ optgroup->append_single_option_line("support_material_interface_layers", category_path + "interface-layers");
+ optgroup->append_single_option_line("support_material_interface_spacing", category_path + "interface-pattern-spacing");
+ optgroup->append_single_option_line("support_material_interface_contact_loops", category_path + "interface-loops");
+ optgroup->append_single_option_line("support_material_buildplate_only", category_path + "support-on-build-plate-only");
+ optgroup->append_single_option_line("support_material_xy_spacing", category_path + "xy-separation-between-an-object-and-its-support");
+ optgroup->append_single_option_line("dont_support_bridges", category_path + "dont-support-bridges");
+ optgroup->append_single_option_line("support_material_synchronize_layers", category_path + "synchronize-with-object-layers");
+
+ page = add_options_page(L("Speed"), "time");
+ optgroup = page->new_optgroup(L("Speed for print moves"));
optgroup->append_single_option_line("perimeter_speed");
optgroup->append_single_option_line("small_perimeter_speed");
optgroup->append_single_option_line("external_perimeter_speed");
@@ -1215,41 +1514,42 @@ void TabPrint::build()
optgroup->append_single_option_line("support_material_interface_speed");
optgroup->append_single_option_line("bridge_speed");
optgroup->append_single_option_line("gap_fill_speed");
+ optgroup->append_single_option_line("ironing_speed");
- optgroup = page->new_optgroup(_(L("Speed for non-print moves")));
+ optgroup = page->new_optgroup(L("Speed for non-print moves"));
optgroup->append_single_option_line("travel_speed");
- optgroup = page->new_optgroup(_(L("Modifiers")));
+ optgroup = page->new_optgroup(L("Modifiers"));
optgroup->append_single_option_line("first_layer_speed");
- optgroup = page->new_optgroup(_(L("Acceleration control (advanced)")));
+ optgroup = page->new_optgroup(L("Acceleration control (advanced)"));
optgroup->append_single_option_line("perimeter_acceleration");
optgroup->append_single_option_line("infill_acceleration");
optgroup->append_single_option_line("bridge_acceleration");
optgroup->append_single_option_line("first_layer_acceleration");
optgroup->append_single_option_line("default_acceleration");
- optgroup = page->new_optgroup(_(L("Autospeed (advanced)")));
- optgroup->append_single_option_line("max_print_speed");
- optgroup->append_single_option_line("max_volumetric_speed");
+ optgroup = page->new_optgroup(L("Autospeed (advanced)"));
+ optgroup->append_single_option_line("max_print_speed", "max-volumetric-speed_127176");
+ optgroup->append_single_option_line("max_volumetric_speed", "max-volumetric-speed_127176");
#ifdef HAS_PRESSURE_EQUALIZER
optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope_positive");
optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope_negative");
#endif /* HAS_PRESSURE_EQUALIZER */
- page = add_options_page(_(L("Multiple Extruders")), "funnel");
- optgroup = page->new_optgroup(_(L("Extruders")));
+ page = add_options_page(L("Multiple Extruders"), "funnel");
+ optgroup = page->new_optgroup(L("Extruders"));
optgroup->append_single_option_line("perimeter_extruder");
optgroup->append_single_option_line("infill_extruder");
optgroup->append_single_option_line("solid_infill_extruder");
optgroup->append_single_option_line("support_material_extruder");
optgroup->append_single_option_line("support_material_interface_extruder");
- optgroup = page->new_optgroup(_(L("Ooze prevention")));
+ optgroup = page->new_optgroup(L("Ooze prevention"));
optgroup->append_single_option_line("ooze_prevention");
optgroup->append_single_option_line("standby_temperature_delta");
- optgroup = page->new_optgroup(_(L("Wipe tower")));
+ optgroup = page->new_optgroup(L("Wipe tower"));
optgroup->append_single_option_line("wipe_tower");
optgroup->append_single_option_line("wipe_tower_x");
optgroup->append_single_option_line("wipe_tower_y");
@@ -1259,11 +1559,11 @@ void TabPrint::build()
optgroup->append_single_option_line("wipe_tower_no_sparse_layers");
optgroup->append_single_option_line("single_extruder_multi_material_priming");
- optgroup = page->new_optgroup(_(L("Advanced")));
+ optgroup = page->new_optgroup(L("Advanced"));
optgroup->append_single_option_line("interface_shells");
- page = add_options_page(_(L("Advanced")), "wrench");
- optgroup = page->new_optgroup(_(L("Extrusion width")));
+ page = add_options_page(L("Advanced"), "wrench");
+ optgroup = page->new_optgroup(L("Extrusion width"));
optgroup->append_single_option_line("extrusion_width");
optgroup->append_single_option_line("first_layer_extrusion_width");
optgroup->append_single_option_line("perimeter_extrusion_width");
@@ -1273,53 +1573,53 @@ void TabPrint::build()
optgroup->append_single_option_line("top_infill_extrusion_width");
optgroup->append_single_option_line("support_material_extrusion_width");
- optgroup = page->new_optgroup(_(L("Overlap")));
+ optgroup = page->new_optgroup(L("Overlap"));
optgroup->append_single_option_line("infill_overlap");
- optgroup = page->new_optgroup(_(L("Flow")));
+ optgroup = page->new_optgroup(L("Flow"));
optgroup->append_single_option_line("bridge_flow_ratio");
- optgroup = page->new_optgroup(_(L("Slicing")));
+ optgroup = page->new_optgroup(L("Slicing"));
optgroup->append_single_option_line("slice_closing_radius");
optgroup->append_single_option_line("resolution");
optgroup->append_single_option_line("xy_size_compensation");
- optgroup->append_single_option_line("elefant_foot_compensation");
+ optgroup->append_single_option_line("elefant_foot_compensation", "elephant-foot-compensation_114487");
- optgroup = page->new_optgroup(_(L("Other")));
+ optgroup = page->new_optgroup(L("Other"));
optgroup->append_single_option_line("clip_multipart_objects");
- page = add_options_page(_(L("Output options")), "output+page_white");
- optgroup = page->new_optgroup(_(L("Sequential printing")));
- optgroup->append_single_option_line("complete_objects");
- line = { _(L("Extruder clearance (mm)")), "" };
+ page = add_options_page(L("Output options"), "output+page_white");
+ optgroup = page->new_optgroup(L("Sequential printing"));
+ optgroup->append_single_option_line("complete_objects", "sequential-printing_124589");
+ line = { L("Extruder clearance"), "" };
line.append_option(optgroup->get_option("extruder_clearance_radius"));
line.append_option(optgroup->get_option("extruder_clearance_height"));
optgroup->append_line(line);
- optgroup = page->new_optgroup(_(L("Output file")));
+ optgroup = page->new_optgroup(L("Output file"));
optgroup->append_single_option_line("gcode_comments");
optgroup->append_single_option_line("gcode_label_objects");
Option option = optgroup->get_option("output_filename_format");
option.opt.full_width = true;
optgroup->append_single_option_line(option);
- optgroup = page->new_optgroup(_(L("Post-processing scripts")), 0);
+ optgroup = page->new_optgroup(L("Post-processing scripts"), 0);
option = optgroup->get_option("post_process");
option.opt.full_width = true;
option.opt.height = 5;//50;
optgroup->append_single_option_line(option);
- page = add_options_page(_(L("Notes")), "note.png");
- optgroup = page->new_optgroup(_(L("Notes")), 0);
+ page = add_options_page(L("Notes"), "note.png");
+ optgroup = page->new_optgroup(L("Notes"), 0);
option = optgroup->get_option("notes");
option.opt.full_width = true;
option.opt.height = 25;//250;
optgroup->append_single_option_line(option);
- page = add_options_page(_(L("Dependencies")), "wrench.png");
- optgroup = page->new_optgroup(_(L("Profile dependencies")));
+ page = add_options_page(L("Dependencies"), "wrench.png");
+ optgroup = page->new_optgroup(L("Profile dependencies"));
- create_line_with_widget(optgroup.get(), "compatible_printers", [this](wxWindow* parent) {
+ create_line_with_widget(optgroup.get(), "compatible_printers", wxEmptyString, [this](wxWindow* parent) {
return compatible_widget_create(parent, m_compatible_printers);
});
@@ -1337,27 +1637,46 @@ void TabPrint::reload_config()
Tab::reload_config();
}
+void TabPrint::update_description_lines()
+{
+ Tab::update_description_lines();
+
+ if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA)
+ return;
+
+ if (m_active_page && m_active_page->title() == "Layers and perimeters" &&
+ m_recommended_thin_wall_thickness_description_line && m_top_bottom_shell_thickness_explanation)
+ {
+ m_recommended_thin_wall_thickness_description_line->SetText(
+ from_u8(PresetHints::recommended_thin_wall_thickness(*m_preset_bundle)));
+ m_top_bottom_shell_thickness_explanation->SetText(
+ from_u8(PresetHints::top_bottom_shell_thickness_explanation(*m_preset_bundle)));
+ }
+}
+
+void TabPrint::toggle_options()
+{
+ if (!m_active_page) return;
+
+ m_config_manipulation.toggle_print_fff_options(m_config);
+}
+
void TabPrint::update()
{
if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA)
return; // ys_FIXME
m_update_cnt++;
-// Freeze();
m_config_manipulation.update_print_fff_config(m_config, true);
- m_recommended_thin_wall_thickness_description_line->SetText(
- from_u8(PresetHints::recommended_thin_wall_thickness(*m_preset_bundle)));
- m_top_bottom_shell_thickness_explanation->SetText(
- from_u8(PresetHints::top_bottom_shell_thickness_explanation(*m_preset_bundle)));
+ update_description_lines();
Layout();
-// Thaw();
m_update_cnt--;
if (m_update_cnt==0) {
- m_config_manipulation.toggle_print_fff_options(m_config);
+ toggle_options();
// update() could be called during undo/redo execution
// Update of objectList can cause a crash in this case (because m_objects doesn't match ObjectList)
@@ -1368,19 +1687,18 @@ void TabPrint::update()
}
}
-void TabPrint::OnActivate()
+void TabPrint::clear_pages()
{
- m_recommended_thin_wall_thickness_description_line->SetText(
- from_u8(PresetHints::recommended_thin_wall_thickness(*m_preset_bundle)));
- m_top_bottom_shell_thickness_explanation->SetText(
- from_u8(PresetHints::top_bottom_shell_thickness_explanation(*m_preset_bundle)));
- Tab::OnActivate();
+ Tab::clear_pages();
+
+ m_recommended_thin_wall_thickness_description_line = nullptr;
+ m_top_bottom_shell_thickness_explanation = nullptr;
}
void TabFilament::add_filament_overrides_page()
{
- PageShp page = add_options_page(_(L("Filament Overrides")), "wrench");
- ConfigOptionsGroupShp optgroup = page->new_optgroup(_(L("Retraction")));
+ PageShp page = add_options_page(L("Filament Overrides"), "wrench");
+ ConfigOptionsGroupShp optgroup = page->new_optgroup(L("Retraction"));
auto append_single_option_line = [optgroup, this](const std::string& opt_key, int opt_index)
{
@@ -1434,12 +1752,11 @@ void TabFilament::add_filament_overrides_page()
void TabFilament::update_filament_overrides_page()
{
- const auto page_it = std::find_if(m_pages.begin(), m_pages.end(), [](const PageShp page) {return page->title() == _(L("Filament Overrides")); });
- if (page_it == m_pages.end())
+ if (!m_active_page || m_active_page->title() != "Filament Overrides")
return;
- PageShp page = *page_it;
+ Page* page = m_active_page;
- const auto og_it = std::find_if(page->m_optgroups.begin(), page->m_optgroups.end(), [](const ConfigOptionsGroupShp og) {return og->title == _(L("Retraction")); });
+ const auto og_it = std::find_if(page->m_optgroups.begin(), page->m_optgroups.end(), [](const ConfigOptionsGroupShp og) { return og->title == "Retraction"; });
if (og_it == page->m_optgroups.end())
return;
ConfigOptionsGroupShp optgroup = *og_it;
@@ -1481,27 +1798,41 @@ void TabFilament::build()
m_presets = &m_preset_bundle->filaments;
load_initial_data();
- auto page = add_options_page(_(L("Filament")), "spool.png");
- auto optgroup = page->new_optgroup(_(L("Filament")));
+ auto page = add_options_page(L("Filament"), "spool.png");
+ auto optgroup = page->new_optgroup(L("Filament"));
optgroup->append_single_option_line("filament_colour");
optgroup->append_single_option_line("filament_diameter");
optgroup->append_single_option_line("extrusion_multiplier");
optgroup->append_single_option_line("filament_density");
optgroup->append_single_option_line("filament_cost");
+ optgroup->append_single_option_line("filament_spool_weight");
- optgroup = page->new_optgroup(_(L("Temperature")) + wxString(" °C", wxConvUTF8));
- Line line = { _(L("Extruder")), "" };
+ optgroup->m_on_change = [this, optgroup](t_config_option_key opt_key, boost::any value)
+ {
+ update_dirty();
+ if (opt_key == "filament_spool_weight") {
+ // Change of this option influences for an update of "Sliced Info"
+ wxGetApp().sidebar().update_sliced_info_sizer();
+ wxGetApp().sidebar().Layout();
+ }
+ else
+ on_value_change(opt_key, value);
+ };
+
+ optgroup = page->new_optgroup(L("Temperature"));
+ Line line = { L("Nozzle"), "" };
line.append_option(optgroup->get_option("first_layer_temperature"));
line.append_option(optgroup->get_option("temperature"));
optgroup->append_line(line);
- line = { _(L("Bed")), "" };
+ line = { L("Bed"), "" };
line.append_option(optgroup->get_option("first_layer_bed_temperature"));
line.append_option(optgroup->get_option("bed_temperature"));
optgroup->append_line(line);
- page = add_options_page(_(L("Cooling")), "cooling");
- optgroup = page->new_optgroup(_(L("Enable")));
+ page = add_options_page(L("Cooling"), "cooling");
+ wxString category_path = "cooling_127569#";
+ optgroup = page->new_optgroup(L("Enable"));
optgroup->append_single_option_line("fan_always_on");
optgroup->append_single_option_line("cooling");
@@ -1512,30 +1843,32 @@ void TabFilament::build()
};
optgroup->append_line(line);
- optgroup = page->new_optgroup(_(L("Fan settings")));
- line = { _(L("Fan speed")), "" };
+ optgroup = page->new_optgroup(L("Fan settings"));
+ line = { L("Fan speed"), "" };
+ line.label_path = category_path + "fan-settings";
line.append_option(optgroup->get_option("min_fan_speed"));
line.append_option(optgroup->get_option("max_fan_speed"));
optgroup->append_line(line);
- optgroup->append_single_option_line("bridge_fan_speed");
- optgroup->append_single_option_line("disable_fan_first_layers");
+ optgroup->append_single_option_line("bridge_fan_speed", category_path + "fan-settings");
+ optgroup->append_single_option_line("disable_fan_first_layers", category_path + "fan-settings");
+ optgroup->append_single_option_line("full_fan_speed_layer", category_path + "fan-settings");
- optgroup = page->new_optgroup(_(L("Cooling thresholds")), 25);
- optgroup->append_single_option_line("fan_below_layer_time");
- optgroup->append_single_option_line("slowdown_below_layer_time");
- optgroup->append_single_option_line("min_print_speed");
+ optgroup = page->new_optgroup(L("Cooling thresholds"), 25);
+ optgroup->append_single_option_line("fan_below_layer_time", category_path + "cooling-thresholds");
+ optgroup->append_single_option_line("slowdown_below_layer_time", category_path + "cooling-thresholds");
+ optgroup->append_single_option_line("min_print_speed", category_path + "cooling-thresholds");
- page = add_options_page(_(L("Advanced")), "wrench");
- optgroup = page->new_optgroup(_(L("Filament properties")));
+ page = add_options_page(L("Advanced"), "wrench");
+ optgroup = page->new_optgroup(L("Filament properties"));
// Set size as all another fields for a better alignment
Option option = optgroup->get_option("filament_type");
option.opt.width = Field::def_width();
optgroup->append_single_option_line(option);
optgroup->append_single_option_line("filament_soluble");
- optgroup = page->new_optgroup(_(L("Print speed override")));
- optgroup->append_single_option_line("filament_max_volumetric_speed");
+ optgroup = page->new_optgroup(L("Print speed override"));
+ optgroup->append_single_option_line("filament_max_volumetric_speed", "max-volumetric-speed_127176");
line = { "", "" };
line.full_width = 1;
@@ -1544,10 +1877,10 @@ void TabFilament::build()
};
optgroup->append_line(line);
- optgroup = page->new_optgroup(_(L("Wipe tower parameters")));
+ optgroup = page->new_optgroup(L("Wipe tower parameters"));
optgroup->append_single_option_line("filament_minimal_purge_on_wipe_tower");
- optgroup = page->new_optgroup(_(L("Toolchange parameters with single extruder MM printers")));
+ optgroup = page->new_optgroup(L("Toolchange parameters with single extruder MM printers"));
optgroup->append_single_option_line("filament_loading_speed_start");
optgroup->append_single_option_line("filament_loading_speed");
optgroup->append_single_option_line("filament_unloading_speed_start");
@@ -1559,22 +1892,22 @@ void TabFilament::build()
optgroup->append_single_option_line("filament_cooling_initial_speed");
optgroup->append_single_option_line("filament_cooling_final_speed");
- line = optgroup->create_single_option_line("filament_ramming_parameters");// { _(L("Ramming")), "" };
- line.widget = [this](wxWindow* parent) {
+ create_line_with_widget(optgroup.get(), "filament_ramming_parameters", wxEmptyString, [this](wxWindow* parent) {
auto ramming_dialog_btn = new wxButton(parent, wxID_ANY, _(L("Ramming settings"))+dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
ramming_dialog_btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
+ ramming_dialog_btn->SetSize(ramming_dialog_btn->GetBestSize());
auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(ramming_dialog_btn);
- ramming_dialog_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent& e)
- {
+ ramming_dialog_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent& e) {
RammingDialog dlg(this,(m_config->option<ConfigOptionStrings>("filament_ramming_parameters"))->get_at(0));
- if (dlg.ShowModal() == wxID_OK)
- (m_config->option<ConfigOptionStrings>("filament_ramming_parameters"))->get_at(0) = dlg.get_parameters();
- }));
+ if (dlg.ShowModal() == wxID_OK) {
+ load_key_value("filament_ramming_parameters", dlg.get_parameters());
+ update_changed_ui();
+ }
+ });
return sizer;
- };
- optgroup->append_line(line);
+ });
add_filament_overrides_page();
@@ -1583,30 +1916,32 @@ void TabFilament::build()
const int gcode_field_height = 15; // 150
const int notes_field_height = 25; // 250
- page = add_options_page(_(L("Custom G-code")), "cog");
- optgroup = page->new_optgroup(_(L("Start G-code")), 0);
+ page = add_options_page(L("Custom G-code"), "cog");
+ optgroup = page->new_optgroup(L("Start G-code"), 0);
option = optgroup->get_option("start_filament_gcode");
option.opt.full_width = true;
+ option.opt.is_code = true;
option.opt.height = gcode_field_height;// 150;
optgroup->append_single_option_line(option);
- optgroup = page->new_optgroup(_(L("End G-code")), 0);
+ optgroup = page->new_optgroup(L("End G-code"), 0);
option = optgroup->get_option("end_filament_gcode");
option.opt.full_width = true;
+ option.opt.is_code = true;
option.opt.height = gcode_field_height;// 150;
optgroup->append_single_option_line(option);
- page = add_options_page(_(L("Notes")), "note.png");
- optgroup = page->new_optgroup(_(L("Notes")), 0);
+ page = add_options_page(L("Notes"), "note.png");
+ optgroup = page->new_optgroup(L("Notes"), 0);
optgroup->label_width = 0;
option = optgroup->get_option("filament_notes");
option.opt.full_width = true;
option.opt.height = notes_field_height;// 250;
optgroup->append_single_option_line(option);
- page = add_options_page(_(L("Dependencies")), "wrench.png");
- optgroup = page->new_optgroup(_(L("Profile dependencies")));
- create_line_with_widget(optgroup.get(), "compatible_printers", [this](wxWindow* parent) {
+ page = add_options_page(L("Dependencies"), "wrench.png");
+ optgroup = page->new_optgroup(L("Profile dependencies"));
+ create_line_with_widget(optgroup.get(), "compatible_printers", wxEmptyString, [this](wxWindow* parent) {
return compatible_widget_create(parent, m_compatible_printers);
});
@@ -1614,7 +1949,7 @@ void TabFilament::build()
option.opt.full_width = true;
optgroup->append_single_option_line(option);
- create_line_with_widget(optgroup.get(), "compatible_prints", [this](wxWindow* parent) {
+ create_line_with_widget(optgroup.get(), "compatible_prints", wxEmptyString, [this](wxWindow* parent) {
return compatible_widget_create(parent, m_compatible_prints);
});
@@ -1644,6 +1979,40 @@ void TabFilament::update_volumetric_flow_preset_hints()
m_volumetric_speed_description_line->SetText(text);
}
+void TabFilament::update_description_lines()
+{
+ Tab::update_description_lines();
+
+ if (!m_active_page)
+ return;
+
+ if (m_active_page->title() == "Cooling" && m_cooling_description_line)
+ m_cooling_description_line->SetText(from_u8(PresetHints::cooling_description(m_presets->get_edited_preset())));
+ if (m_active_page->title() == "Advanced" && m_volumetric_speed_description_line)
+ this->update_volumetric_flow_preset_hints();
+}
+
+void TabFilament::toggle_options()
+{
+ if (!m_active_page)
+ return;
+
+ if (m_active_page->title() == "Cooling")
+ {
+ bool cooling = m_config->opt_bool("cooling", 0);
+ bool fan_always_on = cooling || m_config->opt_bool("fan_always_on", 0);
+
+ for (auto el : { "max_fan_speed", "fan_below_layer_time", "slowdown_below_layer_time", "min_print_speed" })
+ toggle_option(el, cooling);
+
+ for (auto el : { "min_fan_speed", "disable_fan_first_layers", "full_fan_speed_layer" })
+ toggle_option(el, fan_always_on);
+ }
+
+ if (m_active_page->title() == "Filament Overrides")
+ update_filament_overrides_page();
+}
+
void TabFilament::update()
{
if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA)
@@ -1651,21 +2020,10 @@ void TabFilament::update()
m_update_cnt++;
- wxString text = from_u8(PresetHints::cooling_description(m_presets->get_edited_preset()));
- m_cooling_description_line->SetText(text);
- this->update_volumetric_flow_preset_hints();
+ update_description_lines();
Layout();
- bool cooling = m_config->opt_bool("cooling", 0);
- bool fan_always_on = cooling || m_config->opt_bool("fan_always_on", 0);
-
- for (auto el : { "max_fan_speed", "fan_below_layer_time", "slowdown_below_layer_time", "min_print_speed" })
- get_field(el)->toggle(cooling);
-
- for (auto el : { "min_fan_speed", "disable_fan_first_layers" })
- get_field(el)->toggle(fan_always_on);
-
- update_filament_overrides_page();
+ toggle_options();
m_update_cnt--;
@@ -1673,15 +2031,17 @@ void TabFilament::update()
wxGetApp().mainframe->on_config_changed(m_config);
}
-void TabFilament::OnActivate()
+void TabFilament::clear_pages()
{
- this->update_volumetric_flow_preset_hints();
- Tab::OnActivate();
+ Tab::clear_pages();
+
+ m_volumetric_speed_description_line = nullptr;
+ m_cooling_description_line = nullptr;
}
-wxSizer* Tab::description_line_widget(wxWindow* parent, ogStaticText* *StaticText)
+wxSizer* Tab::description_line_widget(wxWindow* parent, ogStaticText* *StaticText, wxString text /*= wxEmptyString*/)
{
- *StaticText = new ogStaticText(parent, "");
+ *StaticText = new ogStaticText(parent, text);
// auto font = (new wxSystemSettings)->GetFont(wxSYS_DEFAULT_GUI_FONT);
(*StaticText)->SetFont(wxGetApp().normal_font());
@@ -1696,132 +2056,6 @@ bool Tab::current_preset_is_dirty()
return m_presets->current_is_dirty();
}
-void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup)
-{
- const PrinterTechnology tech = m_presets->get_selected_preset().printer_technology();
-
- // Only offer the host type selection for FFF, for SLA it's always the SL1 printer (at the moment)
- if (tech == ptFFF) {
- optgroup->append_single_option_line("host_type");
- }
-
- auto printhost_browse = [=](wxWindow* parent) {
- add_scaled_button(parent, &m_printhost_browse_btn, "browse", _(L("Browse")) + " "+ dots, wxBU_LEFT | wxBU_EXACTFIT);
- ScalableButton* btn = m_printhost_browse_btn;
- btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
-
- auto sizer = new wxBoxSizer(wxHORIZONTAL);
- sizer->Add(btn);
-
- btn->Bind(wxEVT_BUTTON, [=](wxCommandEvent &e) {
- BonjourDialog dialog(parent, tech);
- if (dialog.show_and_lookup()) {
- optgroup->set_value("print_host", std::move(dialog.get_selected()), true);
- optgroup->get_field("print_host")->field_changed();
- }
- });
-
- return sizer;
- };
-
- auto print_host_test = [this](wxWindow* parent) {
- add_scaled_button(parent, &m_print_host_test_btn, "test", _(L("Test")), wxBU_LEFT | wxBU_EXACTFIT);
- ScalableButton* btn = m_print_host_test_btn;
- btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
- auto sizer = new wxBoxSizer(wxHORIZONTAL);
- sizer->Add(btn);
-
- btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) {
- std::unique_ptr<PrintHost> host(PrintHost::get_print_host(m_config));
- if (! host) {
- const wxString text = _(L("Could not get a valid Printer Host reference"));
- show_error(this, text);
- return;
- }
- wxString msg;
- if (host->test(msg)) {
- show_info(this, host->get_test_ok_msg(), _(L("Success!")));
- } else {
- show_error(this, host->get_test_failed_msg(msg));
- }
- });
-
- return sizer;
- };
-
- // Set a wider width for a better alignment
- Option option = optgroup->get_option("print_host");
- option.opt.width = Field::def_width_wider();
- Line host_line = optgroup->create_single_option_line(option);
- host_line.append_widget(printhost_browse);
- host_line.append_widget(print_host_test);
- optgroup->append_line(host_line);
- option = optgroup->get_option("printhost_apikey");
- option.opt.width = Field::def_width_wider();
- optgroup->append_single_option_line(option);
-
- const auto ca_file_hint = _utf8(L("HTTPS CA file is optional. It is only needed if you use HTTPS with a self-signed certificate."));
-
- if (Http::ca_file_supported()) {
- option = optgroup->get_option("printhost_cafile");
- option.opt.width = Field::def_width_wider();
- Line cafile_line = optgroup->create_single_option_line(option);
-
- auto printhost_cafile_browse = [this, optgroup] (wxWindow* parent) {
- auto btn = new wxButton(parent, wxID_ANY, " " + _(L("Browse"))+" " +dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
- btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
- btn->SetBitmap(create_scaled_bitmap("browse"));
- auto sizer = new wxBoxSizer(wxHORIZONTAL);
- sizer->Add(btn);
-
- btn->Bind(wxEVT_BUTTON, [this, optgroup] (wxCommandEvent e) {
- static const auto filemasks = _(L("Certificate files (*.crt, *.pem)|*.crt;*.pem|All files|*.*"));
- wxFileDialog openFileDialog(this, _(L("Open CA certificate file")), "", "", filemasks, wxFD_OPEN | wxFD_FILE_MUST_EXIST);
- if (openFileDialog.ShowModal() != wxID_CANCEL) {
- optgroup->set_value("printhost_cafile", std::move(openFileDialog.GetPath()), true);
- optgroup->get_field("printhost_cafile")->field_changed();
- }
- });
-
- return sizer;
- };
-
- cafile_line.append_widget(printhost_cafile_browse);
- optgroup->append_line(cafile_line);
-
- Line cafile_hint { "", "" };
- cafile_hint.full_width = 1;
- cafile_hint.widget = [this, ca_file_hint](wxWindow* parent) {
- auto txt = new wxStaticText(parent, wxID_ANY, ca_file_hint);
- auto sizer = new wxBoxSizer(wxHORIZONTAL);
- sizer->Add(txt);
- return sizer;
- };
- optgroup->append_line(cafile_hint);
- } else {
- Line line { "", "" };
- line.full_width = 1;
-
- line.widget = [ca_file_hint] (wxWindow* parent) {
- std::string info = _utf8(L("HTTPS CA File")) + ":\n\t" +
- (boost::format(_utf8(L("On this system, %s uses HTTPS certificates from the system Certificate Store or Keychain."))) % SLIC3R_APP_NAME).str() +
- "\n\t" + _utf8(L("To use a custom CA file, please import your CA file into Certificate Store / Keychain."));
-
- auto txt = new wxStaticText(parent, wxID_ANY, from_u8((boost::format("%1%\n\n\t%2%") % info % ca_file_hint).str()));
-/* % (boost::format(_utf8(L("HTTPS CA File:\n\
- \tOn this system, %s uses HTTPS certificates from the system Certificate Store or Keychain.\n\
- \tTo use a custom CA file, please import your CA file into Certificate Store / Keychain."))) % SLIC3R_APP_NAME).str()
- % std::string(ca_file_hint.ToUTF8())).str()));
-*/ txt->SetFont(Slic3r::GUI::wxGetApp().normal_font());
- auto sizer = new wxBoxSizer(wxHORIZONTAL);
- sizer->Add(txt, 1, wxEXPAND);
- return sizer;
- };
-
- optgroup->append_line(line);
- }
-}
-
void TabPrinter::build()
{
m_presets = &m_preset_bundle->printers;
@@ -1832,6 +2066,27 @@ void TabPrinter::build()
m_presets->get_selected_preset().printer_technology() == ptSLA ? build_sla() : build_fff();
}
+void TabPrinter::build_print_host_upload_group(Page* page)
+{
+ ConfigOptionsGroupShp optgroup = page->new_optgroup(L("Print Host upload"));
+
+ wxString description_line_text = _L(""
+ "Note: All parameters from this group are moved to the Physical Printer settings (see changelog).\n\n"
+ "A new Physical Printer profile is created by clicking on the \"cog\" icon right of the Printer profiles combo box, "
+ "by selecting the \"Add physical printer\" item in the Printer combo box. The Physical Printer profile editor opens "
+ "also when clicking on the \"cog\" icon in the Printer settings tab. The Physical Printer profiles are being stored "
+ "into PrusaSlicer/physical_printer directory.");
+
+ Line line = { "", "" };
+ line.full_width = 1;
+ line.widget = [this, description_line_text](wxWindow* parent) {
+ return description_line_widget(parent, m_presets->get_selected_preset().printer_technology() == ptFFF ?
+ &m_fff_print_host_upload_description_line : &m_sla_print_host_upload_description_line,
+ description_line_text);
+ };
+ optgroup->append_line(line);
+}
+
void TabPrinter::build_fff()
{
if (!m_pages.empty())
@@ -1847,17 +2102,17 @@ void TabPrinter::build_fff()
m_sys_extruders_count = parent_preset == nullptr ? 0 :
static_cast<const ConfigOptionFloats*>(parent_preset->config.option("nozzle_diameter"))->values.size();
- auto page = add_options_page(_(L("General")), "printer");
- auto optgroup = page->new_optgroup(_(L("Size and coordinates")));
+ auto page = add_options_page(L("General"), "printer");
+ auto optgroup = page->new_optgroup(L("Size and coordinates"));
- create_line_with_widget(optgroup.get(), "bed_shape", [this](wxWindow* parent) {
+ create_line_with_widget(optgroup.get(), "bed_shape", "custom-svg-and-png-bed-textures_124612", [this](wxWindow* parent) {
return create_bed_shape_widget(parent);
});
optgroup->append_single_option_line("max_print_height");
optgroup->append_single_option_line("z_offset");
- optgroup = page->new_optgroup(_(L("Capabilities")));
+ optgroup = page->new_optgroup(L("Capabilities"));
ConfigOptionDef def;
def.type = coInt,
def.set_default_value(new ConfigOptionInt(1));
@@ -1919,59 +2174,15 @@ void TabPrinter::build_fff()
});
};
+ build_print_host_upload_group(page.get());
-#if 0
- if (!m_no_controller)
- {
- optgroup = page->new_optgroup(_(L("USB/Serial connection")));
- line = {_(L("Serial port")), ""};
- Option serial_port = optgroup->get_option("serial_port");
- serial_port.side_widget = ([this](wxWindow* parent) {
- auto btn = new wxBitmapButton(parent, wxID_ANY, wxBitmap(from_u8(Slic3r::var("arrow_rotate_clockwise.png")), wxBITMAP_TYPE_PNG),
- wxDefaultPosition, wxDefaultSize, wxBORDER_NONE);
- btn->SetToolTip(_(L("Rescan serial ports")));
- auto sizer = new wxBoxSizer(wxHORIZONTAL);
- sizer->Add(btn);
-
- btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent e) {update_serial_ports(); });
- return sizer;
- });
- auto serial_test = [this](wxWindow* parent) {
- auto btn = m_serial_test_btn = new wxButton(parent, wxID_ANY,
- _(L("Test")), wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
- btn->SetFont(Slic3r::GUI::small_font());
- btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("wrench.png")), wxBITMAP_TYPE_PNG));
- auto sizer = new wxBoxSizer(wxHORIZONTAL);
- sizer->Add(btn);
-
- btn->Bind(wxEVT_BUTTON, [this, parent](wxCommandEvent e) {
- auto sender = Slic3r::make_unique<GCodeSender>();
- auto res = sender->connect(
- m_config->opt_string("serial_port"),
- m_config->opt_int("serial_speed")
- );
- if (res && sender->wait_connected()) {
- show_info(parent, _(L("Connection to printer works correctly.")), _(L("Success!")));
- }
- else {
- show_error(parent, _(L("Connection failed.")));
- }
- });
- return sizer;
- };
-
- line.append_option(serial_port);
- line.append_option(optgroup->get_option("serial_speed"));
- line.append_widget(serial_test);
- optgroup->append_line(line);
- }
-#endif
+ optgroup = page->new_optgroup(L("Firmware"));
+ optgroup->append_single_option_line("gcode_flavor");
- optgroup = page->new_optgroup(_(L("Print Host upload")));
- build_printhost(optgroup.get());
+ option = optgroup->get_option("thumbnails");
+ option.opt.full_width = true;
+ optgroup->append_single_option_line(option);
- optgroup = page->new_optgroup(_(L("Firmware")));
- optgroup->append_single_option_line("gcode_flavor");
optgroup->append_single_option_line("silent_mode");
optgroup->append_single_option_line("remaining_times");
@@ -1990,7 +2201,7 @@ void TabPrinter::build_fff()
});
};
- optgroup = page->new_optgroup(_(L("Advanced")));
+ optgroup = page->new_optgroup(L("Advanced"));
optgroup->append_single_option_line("use_relative_e_distances");
optgroup->append_single_option_line("use_firmware_retraction");
optgroup->append_single_option_line("use_volumetric_e");
@@ -1998,81 +2209,100 @@ void TabPrinter::build_fff()
const int gcode_field_height = 15; // 150
const int notes_field_height = 25; // 250
- page = add_options_page(_(L("Custom G-code")), "cog");
- optgroup = page->new_optgroup(_(L("Start G-code")), 0);
+ page = add_options_page(L("Custom G-code"), "cog");
+ optgroup = page->new_optgroup(L("Start G-code"), 0);
option = optgroup->get_option("start_gcode");
option.opt.full_width = true;
+ option.opt.is_code = true;
option.opt.height = gcode_field_height;//150;
optgroup->append_single_option_line(option);
- optgroup = page->new_optgroup(_(L("End G-code")), 0);
+ optgroup = page->new_optgroup(L("End G-code"), 0);
option = optgroup->get_option("end_gcode");
option.opt.full_width = true;
+ option.opt.is_code = true;
option.opt.height = gcode_field_height;//150;
optgroup->append_single_option_line(option);
- optgroup = page->new_optgroup(_(L("Before layer change G-code")), 0);
+ optgroup = page->new_optgroup(L("Before layer change G-code"), 0);
option = optgroup->get_option("before_layer_gcode");
option.opt.full_width = true;
+ option.opt.is_code = true;
option.opt.height = gcode_field_height;//150;
optgroup->append_single_option_line(option);
- optgroup = page->new_optgroup(_(L("After layer change G-code")), 0);
+ optgroup = page->new_optgroup(L("After layer change G-code"), 0);
option = optgroup->get_option("layer_gcode");
option.opt.full_width = true;
+ option.opt.is_code = true;
option.opt.height = gcode_field_height;//150;
optgroup->append_single_option_line(option);
- optgroup = page->new_optgroup(_(L("Tool change G-code")), 0);
+ optgroup = page->new_optgroup(L("Tool change G-code"), 0);
option = optgroup->get_option("toolchange_gcode");
option.opt.full_width = true;
+ option.opt.is_code = true;
option.opt.height = gcode_field_height;//150;
optgroup->append_single_option_line(option);
- optgroup = page->new_optgroup(_(L("Between objects G-code (for sequential printing)")), 0);
+ optgroup = page->new_optgroup(L("Between objects G-code (for sequential printing)"), 0);
option = optgroup->get_option("between_objects_gcode");
option.opt.full_width = true;
+ option.opt.is_code = true;
+ option.opt.height = gcode_field_height;//150;
+ optgroup->append_single_option_line(option);
+
+ optgroup = page->new_optgroup(L("Color Change G-code"), 0);
+ option = optgroup->get_option("color_change_gcode");
+ option.opt.is_code = true;
+ option.opt.height = gcode_field_height;//150;
+ optgroup->append_single_option_line(option);
+
+ optgroup = page->new_optgroup(L("Pause Print G-code"), 0);
+ option = optgroup->get_option("pause_print_gcode");
+ option.opt.is_code = true;
option.opt.height = gcode_field_height;//150;
optgroup->append_single_option_line(option);
- page = add_options_page(_(L("Notes")), "note.png");
- optgroup = page->new_optgroup(_(L("Notes")), 0);
+ optgroup = page->new_optgroup(L("Template Custom G-code"), 0);
+ option = optgroup->get_option("template_custom_gcode");
+ option.opt.is_code = true;
+ option.opt.height = gcode_field_height;//150;
+ optgroup->append_single_option_line(option);
+
+ page = add_options_page(L("Notes"), "note.png");
+ optgroup = page->new_optgroup(L("Notes"), 0);
option = optgroup->get_option("printer_notes");
option.opt.full_width = true;
option.opt.height = notes_field_height;//250;
optgroup->append_single_option_line(option);
- page = add_options_page(_(L("Dependencies")), "wrench.png");
- optgroup = page->new_optgroup(_(L("Profile dependencies")));
+ page = add_options_page(L("Dependencies"), "wrench.png");
+ optgroup = page->new_optgroup(L("Profile dependencies"));
build_preset_description_line(optgroup.get());
build_unregular_pages();
-
-#if 0
- if (!m_no_controller)
- update_serial_ports();
-#endif
}
void TabPrinter::build_sla()
{
if (!m_pages.empty())
m_pages.resize(0);
- auto page = add_options_page(_(L("General")), "printer");
- auto optgroup = page->new_optgroup(_(L("Size and coordinates")));
+ auto page = add_options_page(L("General"), "printer");
+ auto optgroup = page->new_optgroup(L("Size and coordinates"));
- create_line_with_widget(optgroup.get(), "bed_shape", [this](wxWindow* parent) {
+ create_line_with_widget(optgroup.get(), "bed_shape", "custom-svg-and-png-bed-textures_124612", [this](wxWindow* parent) {
return create_bed_shape_widget(parent);
});
optgroup->append_single_option_line("max_print_height");
- optgroup = page->new_optgroup(_(L("Display")));
+ optgroup = page->new_optgroup(L("Display"));
optgroup->append_single_option_line("display_width");
optgroup->append_single_option_line("display_height");
auto option = optgroup->get_option("display_pixels_x");
- Line line = { _(option.opt.full_label), "" };
+ Line line = { option.opt.full_label, "" };
line.append_option(option);
line.append_option(optgroup->get_option("display_pixels_y"));
optgroup->append_line(line);
@@ -2082,15 +2312,15 @@ void TabPrinter::build_sla()
optgroup->append_single_option_line("display_mirror_x");
optgroup->append_single_option_line("display_mirror_y");
- optgroup = page->new_optgroup(_(L("Tilt")));
- line = { _(L("Tilt time")), "" };
+ optgroup = page->new_optgroup(L("Tilt"));
+ line = { L("Tilt time"), "" };
line.append_option(optgroup->get_option("fast_tilt_time"));
line.append_option(optgroup->get_option("slow_tilt_time"));
optgroup->append_line(line);
optgroup->append_single_option_line("area_fill");
- optgroup = page->new_optgroup(_(L("Corrections")));
- line = Line{ _(m_config->def()->get("relative_correction")->full_label), "" };
+ optgroup = page->new_optgroup(L("Corrections"));
+ line = Line{ m_config->def()->get("relative_correction")->full_label, "" };
// std::vector<std::string> axes{ "X", "Y", "Z" };
std::vector<std::string> axes{ "XY", "Z" };
int id = 0;
@@ -2106,37 +2336,29 @@ void TabPrinter::build_sla()
optgroup->append_single_option_line("elefant_foot_min_width");
optgroup->append_single_option_line("gamma_correction");
- optgroup = page->new_optgroup(_(L("Exposure")));
+ optgroup = page->new_optgroup(L("Exposure"));
optgroup->append_single_option_line("min_exposure_time");
optgroup->append_single_option_line("max_exposure_time");
optgroup->append_single_option_line("min_initial_exposure_time");
optgroup->append_single_option_line("max_initial_exposure_time");
- optgroup = page->new_optgroup(_(L("Print Host upload")));
- build_printhost(optgroup.get());
+ build_print_host_upload_group(page.get());
const int notes_field_height = 25; // 250
- page = add_options_page(_(L("Notes")), "note.png");
- optgroup = page->new_optgroup(_(L("Notes")), 0);
+ page = add_options_page(L("Notes"), "note.png");
+ optgroup = page->new_optgroup(L("Notes"), 0);
option = optgroup->get_option("printer_notes");
option.opt.full_width = true;
option.opt.height = notes_field_height;//250;
optgroup->append_single_option_line(option);
- page = add_options_page(_(L("Dependencies")), "wrench.png");
- optgroup = page->new_optgroup(_(L("Profile dependencies")));
+ page = add_options_page(L("Dependencies"), "wrench.png");
+ optgroup = page->new_optgroup(L("Profile dependencies"));
build_preset_description_line(optgroup.get());
}
-void TabPrinter::update_serial_ports()
-{
- Field *field = get_field("serial_port");
- Choice *choice = static_cast<Choice *>(field);
- choice->set_values(Utils::scan_serial_ports());
-}
-
void TabPrinter::extruders_count_changed(size_t extruders_count)
{
bool is_count_changed = false;
@@ -2164,7 +2386,7 @@ void TabPrinter::extruders_count_changed(size_t extruders_count)
void TabPrinter::append_option_line(ConfigOptionsGroupShp optgroup, const std::string opt_key)
{
auto option = optgroup->get_option(opt_key, 0);
- auto line = Line{ _(option.opt.full_label), "" };
+ auto line = Line{ option.opt.full_label, "" };
line.append_option(option);
if (m_use_silent_mode)
line.append_option(optgroup->get_option(opt_key, 1));
@@ -2173,18 +2395,27 @@ void TabPrinter::append_option_line(ConfigOptionsGroupShp optgroup, const std::s
PageShp TabPrinter::build_kinematics_page()
{
- auto page = add_options_page(_(L("Machine limits")), "cog", true);
+ auto page = add_options_page(L("Machine limits"), "cog", true);
- if (m_use_silent_mode) {
+ auto optgroup = page->new_optgroup(L("General"));
+ {
+ optgroup->append_single_option_line("machine_limits_usage");
+ Line line { "", "" };
+ line.full_width = 1;
+ line.widget = [this](wxWindow* parent) {
+ return description_line_widget(parent, &m_machine_limits_description_line);
+ };
+ optgroup->append_line(line);
+ }
+
+ if (m_use_silent_mode) {
// Legend for OptionsGroups
auto optgroup = page->new_optgroup("");
- optgroup->set_show_modified_btns_val(false);
- optgroup->label_width = 23;// 230;
auto line = Line{ "", "" };
ConfigOptionDef def;
def.type = coString;
- def.width = 15;
+ def.width = Field::def_width();
def.gui_type = "legend";
def.mode = comAdvanced;
def.tooltip = L("Values in this column are for Normal mode");
@@ -2202,24 +2433,24 @@ PageShp TabPrinter::build_kinematics_page()
}
std::vector<std::string> axes{ "x", "y", "z", "e" };
- auto optgroup = page->new_optgroup(_(L("Maximum feedrates")));
+ optgroup = page->new_optgroup(L("Maximum feedrates"));
for (const std::string &axis : axes) {
append_option_line(optgroup, "machine_max_feedrate_" + axis);
}
- optgroup = page->new_optgroup(_(L("Maximum accelerations")));
+ optgroup = page->new_optgroup(L("Maximum accelerations"));
for (const std::string &axis : axes) {
append_option_line(optgroup, "machine_max_acceleration_" + axis);
}
append_option_line(optgroup, "machine_max_acceleration_extruding");
append_option_line(optgroup, "machine_max_acceleration_retracting");
- optgroup = page->new_optgroup(_(L("Jerk limits")));
+ optgroup = page->new_optgroup(L("Jerk limits"));
for (const std::string &axis : axes) {
append_option_line(optgroup, "machine_max_jerk_" + axis);
}
- optgroup = page->new_optgroup(_(L("Minimum feedrates")));
+ optgroup = page->new_optgroup(L("Minimum feedrates"));
append_option_line(optgroup, "machine_min_extruding_rate");
append_option_line(optgroup, "machine_min_travel_rate");
@@ -2247,18 +2478,18 @@ void TabPrinter::build_unregular_pages()
/* Workaround for correct layout of controls inside the created page:
* In some _strange_ way we should we should imitate page resizing.
*/
- auto layout_page = [this](PageShp page)
+/* auto layout_page = [this](PageShp page)
{
const wxSize& sz = page->GetSize();
page->SetSize(sz.x + 1, sz.y + 1);
page->SetSize(sz);
- };
+ };*/
#endif //__WXMSW__
// Add/delete Kinematics page according to is_marlin_flavor
size_t existed_page = 0;
for (size_t i = n_before_extruders; i < m_pages.size(); ++i) // first make sure it's not there already
- if (m_pages[i]->title().find(_(L("Machine limits"))) != std::string::npos) {
+ if (m_pages[i]->title().find(L("Machine limits")) != std::string::npos) {
if (!is_marlin_flavor || m_rebuild_kinematics_page)
m_pages.erase(m_pages.begin() + i);
else
@@ -2269,7 +2500,7 @@ void TabPrinter::build_unregular_pages()
if (existed_page < n_before_extruders && is_marlin_flavor) {
auto page = build_kinematics_page();
#ifdef __WXMSW__
- layout_page(page);
+// layout_page(page);
#endif
m_pages.insert(m_pages.begin() + n_before_extruders, page);
}
@@ -2283,7 +2514,7 @@ void TabPrinter::build_unregular_pages()
{
// if we have a single extruder MM setup, add a page with configuration options:
for (size_t i = 0; i < m_pages.size(); ++i) // first make sure it's not there already
- if (m_pages[i]->title().find(_(L("Single extruder MM setup"))) != std::string::npos) {
+ if (m_pages[i]->title().find(L("Single extruder MM setup")) != std::string::npos) {
m_pages.erase(m_pages.begin() + i);
break;
}
@@ -2291,8 +2522,8 @@ void TabPrinter::build_unregular_pages()
}
if (m_extruders_count > 1 && m_config->opt_bool("single_extruder_multi_material") && !m_has_single_extruder_MM_page) {
// create a page, but pretend it's an extruder page, so we can add it to m_pages ourselves
- auto page = add_options_page(_(L("Single extruder MM setup")), "printer", true);
- auto optgroup = page->new_optgroup(_(L("Single extruder multimaterial parameters")));
+ auto page = add_options_page(L("Single extruder MM setup"), "printer", true);
+ auto optgroup = page->new_optgroup(L("Single extruder multimaterial parameters"));
optgroup->append_single_option_line("cooling_tube_retraction");
optgroup->append_single_option_line("cooling_tube_length");
optgroup->append_single_option_line("parking_pos_retraction");
@@ -2305,12 +2536,12 @@ void TabPrinter::build_unregular_pages()
// Build missed extruder pages
for (auto extruder_idx = m_extruders_count_old; extruder_idx < m_extruders_count; ++extruder_idx) {
//# build page
- const wxString& page_name = wxString::Format(_(L("Extruder %d")), int(extruder_idx + 1));
+ const wxString& page_name = wxString::Format("Extruder %d", int(extruder_idx + 1));
auto page = add_options_page(page_name, "funnel", true);
m_pages.insert(m_pages.begin() + n_before_extruders + extruder_idx, page);
- auto optgroup = page->new_optgroup(_(L("Size")));
- optgroup->append_single_option_line("nozzle_diameter", extruder_idx);
+ auto optgroup = page->new_optgroup(L("Size"));
+ optgroup->append_single_option_line("nozzle_diameter", wxEmptyString, extruder_idx);
optgroup->m_on_change = [this, extruder_idx](const t_config_option_key& opt_key, boost::any value)
{
@@ -2347,41 +2578,42 @@ void TabPrinter::build_unregular_pages()
update();
};
- optgroup = page->new_optgroup(_(L("Layer height limits")));
- optgroup->append_single_option_line("min_layer_height", extruder_idx);
- optgroup->append_single_option_line("max_layer_height", extruder_idx);
+ optgroup = page->new_optgroup(L("Layer height limits"));
+ optgroup->append_single_option_line("min_layer_height", wxEmptyString, extruder_idx);
+ optgroup->append_single_option_line("max_layer_height", wxEmptyString, extruder_idx);
- optgroup = page->new_optgroup(_(L("Position (for multi-extruder printers)")));
- optgroup->append_single_option_line("extruder_offset", extruder_idx);
+ optgroup = page->new_optgroup(L("Position (for multi-extruder printers)"));
+ optgroup->append_single_option_line("extruder_offset", wxEmptyString, extruder_idx);
- optgroup = page->new_optgroup(_(L("Retraction")));
- optgroup->append_single_option_line("retract_length", extruder_idx);
- optgroup->append_single_option_line("retract_lift", extruder_idx);
- Line line = { _(L("Only lift Z")), "" };
+ optgroup = page->new_optgroup(L("Retraction"));
+ optgroup->append_single_option_line("retract_length", wxEmptyString, extruder_idx);
+ optgroup->append_single_option_line("retract_lift", wxEmptyString, extruder_idx);
+ Line line = { L("Only lift Z"), "" };
line.append_option(optgroup->get_option("retract_lift_above", extruder_idx));
line.append_option(optgroup->get_option("retract_lift_below", extruder_idx));
optgroup->append_line(line);
- optgroup->append_single_option_line("retract_speed", extruder_idx);
- optgroup->append_single_option_line("deretract_speed", extruder_idx);
- optgroup->append_single_option_line("retract_restart_extra", extruder_idx);
- optgroup->append_single_option_line("retract_before_travel", extruder_idx);
- optgroup->append_single_option_line("retract_layer_change", extruder_idx);
- optgroup->append_single_option_line("wipe", extruder_idx);
- optgroup->append_single_option_line("retract_before_wipe", extruder_idx);
+ optgroup->append_single_option_line("retract_speed", wxEmptyString, extruder_idx);
+ optgroup->append_single_option_line("deretract_speed", wxEmptyString, extruder_idx);
+ optgroup->append_single_option_line("retract_restart_extra", wxEmptyString, extruder_idx);
+ optgroup->append_single_option_line("retract_before_travel", wxEmptyString, extruder_idx);
+ optgroup->append_single_option_line("retract_layer_change", wxEmptyString, extruder_idx);
+ optgroup->append_single_option_line("wipe", wxEmptyString, extruder_idx);
+ optgroup->append_single_option_line("retract_before_wipe", wxEmptyString, extruder_idx);
- optgroup = page->new_optgroup(_(L("Retraction when tool is disabled (advanced settings for multi-extruder setups)")));
- optgroup->append_single_option_line("retract_length_toolchange", extruder_idx);
- optgroup->append_single_option_line("retract_restart_extra_toolchange", extruder_idx);
+ optgroup = page->new_optgroup(L("Retraction when tool is disabled (advanced settings for multi-extruder setups)"));
+ optgroup->append_single_option_line("retract_length_toolchange", wxEmptyString, extruder_idx);
+ optgroup->append_single_option_line("retract_restart_extra_toolchange", wxEmptyString, extruder_idx);
- optgroup = page->new_optgroup(_(L("Preview")));
+ optgroup = page->new_optgroup(L("Preview"));
auto reset_to_filament_color = [this, extruder_idx](wxWindow* parent) {
- add_scaled_button(parent, &m_reset_to_filament_color, "undo",
- _(L("Reset to Filament Color")), wxBU_LEFT | wxBU_EXACTFIT);
+ m_reset_to_filament_color = new ScalableButton(parent, wxID_ANY, "undo", _L("Reset to Filament Color"),
+ wxDefaultSize, wxDefaultPosition, wxBU_LEFT | wxBU_EXACTFIT, true);
ScalableButton* btn = m_reset_to_filament_color;
btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
+ btn->SetSize(btn->GetBestSize());
auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(btn);
@@ -2400,12 +2632,12 @@ void TabPrinter::build_unregular_pages()
return sizer;
};
- line = optgroup->create_single_option_line("extruder_colour", extruder_idx);
+ line = optgroup->create_single_option_line("extruder_colour", wxEmptyString, extruder_idx);
line.append_widget(reset_to_filament_color);
optgroup->append_line(line);
#ifdef __WXMSW__
- layout_page(page);
+// layout_page(page);
#endif
}
@@ -2421,6 +2653,9 @@ void TabPrinter::build_unregular_pages()
// Reload preset pages with current configuration values
reload_config();
+
+ // apply searcher with current configuration
+ apply_searcher();
}
// this gets executed after preset is loaded and before GUI fields are updated
@@ -2429,7 +2664,6 @@ void TabPrinter::on_preset_loaded()
// update the extruders count field
auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(m_config->option("nozzle_diameter"));
size_t extruders_count = nozzle_diameter->values.size();
- set_value("extruders_count", int(extruders_count));
// update the GUI field according to the number of nozzle diameters supplied
extruders_count_changed(extruders_count);
}
@@ -2441,9 +2675,8 @@ void TabPrinter::update_pages()
if (new_printer_technology == m_printer_technology)
return;
- // hide all old pages
- for (auto& el : m_pages)
- el.get()->Hide();
+ //clear all active pages before switching
+ clear_pages();
// set m_pages to m_pages_(technology before changing)
m_printer_technology == ptFFF ? m_pages.swap(m_pages_fff) : m_pages.swap(m_pages_sla);
@@ -2473,95 +2706,89 @@ void TabPrinter::update_pages()
rebuild_page_tree();
}
-void TabPrinter::update()
+void TabPrinter::reload_config()
{
- m_update_cnt++;
- m_presets->get_edited_preset().printer_technology() == ptFFF ? update_fff() : update_sla();
- m_update_cnt--;
+ Tab::reload_config();
- if (m_update_cnt == 0)
- wxGetApp().mainframe->on_config_changed(m_config);
+ // "extruders_count" doesn't update from the update_config(),
+ // so update it implicitly
+ if (m_active_page && m_active_page->title() == "General")
+ m_active_page->set_value("extruders_count", int(m_extruders_count));
}
-void TabPrinter::update_fff()
+void TabPrinter::activate_selected_page(std::function<void()> throw_if_canceled)
{
-// Freeze();
+ Tab::activate_selected_page(throw_if_canceled);
- bool en;
- auto serial_speed = get_field("serial_speed");
- if (serial_speed != nullptr) {
- en = !m_config->opt_string("serial_port").empty();
- get_field("serial_speed")->toggle(en);
- if (m_config->opt_int("serial_speed") != 0 && en)
- m_serial_test_btn->Enable();
- else
- m_serial_test_btn->Disable();
- }
-
- {
- std::unique_ptr<PrintHost> host(PrintHost::get_print_host(m_config));
- m_print_host_test_btn->Enable(!m_config->opt_string("print_host").empty() && host->can_test());
- m_printhost_browse_btn->Enable(host->has_auto_discovery());
- }
-
- bool have_multiple_extruders = m_extruders_count > 1;
- get_field("toolchange_gcode")->toggle(have_multiple_extruders);
- get_field("single_extruder_multi_material")->toggle(have_multiple_extruders);
+ // "extruders_count" doesn't update from the update_config(),
+ // so update it implicitly
+ if (m_active_page && m_active_page->title() == "General")
+ m_active_page->set_value("extruders_count", int(m_extruders_count));
+}
- bool is_marlin_flavor = m_config->option<ConfigOptionEnum<GCodeFlavor>>("gcode_flavor")->value == gcfMarlin;
+void TabPrinter::clear_pages()
+{
+ Tab::clear_pages();
+ m_reset_to_filament_color = nullptr;
+}
- {
- Field *sm = get_field("silent_mode");
- if (! is_marlin_flavor)
- // Disable silent mode for non-marlin firmwares.
- get_field("silent_mode")->toggle(false);
- if (is_marlin_flavor)
- sm->enable();
- else
- sm->disable();
- }
+void TabPrinter::toggle_options()
+{
+ if (!m_active_page || m_presets->get_edited_preset().printer_technology() == ptSLA)
+ return;
- if (m_use_silent_mode != m_config->opt_bool("silent_mode")) {
- m_rebuild_kinematics_page = true;
- m_use_silent_mode = m_config->opt_bool("silent_mode");
+ bool have_multiple_extruders = m_extruders_count > 1;
+ if (m_active_page->title() == "Custom G-code")
+ toggle_option("toolchange_gcode", have_multiple_extruders);
+ if (m_active_page->title() == "General") {
+ toggle_option("single_extruder_multi_material", have_multiple_extruders);
+
+ bool is_marlin_flavor = m_config->option<ConfigOptionEnum<GCodeFlavor>>("gcode_flavor")->value == gcfMarlin;
+ // Disable silent mode for non-marlin firmwares.
+ toggle_option("silent_mode", is_marlin_flavor);
}
- for (size_t i = 0; i < m_extruders_count; ++i) {
+ wxString extruder_number;
+ long val;
+ if (m_active_page->title().StartsWith("Extruder ", &extruder_number) && extruder_number.ToLong(&val) &&
+ val > 0 && (size_t)val <= m_extruders_count)
+ {
+ size_t i = size_t(val - 1);
bool have_retract_length = m_config->opt_float("retract_length", i) > 0;
// when using firmware retraction, firmware decides retraction length
bool use_firmware_retraction = m_config->opt_bool("use_firmware_retraction");
- get_field("retract_length", i)->toggle(!use_firmware_retraction);
+ toggle_option("retract_length", !use_firmware_retraction, i);
// user can customize travel length if we have retraction length or we"re using
// firmware retraction
- get_field("retract_before_travel", i)->toggle(have_retract_length || use_firmware_retraction);
+ toggle_option("retract_before_travel", have_retract_length || use_firmware_retraction, i);
// user can customize other retraction options if retraction is enabled
bool retraction = (have_retract_length || use_firmware_retraction);
std::vector<std::string> vec = { "retract_lift", "retract_layer_change" };
for (auto el : vec)
- get_field(el, i)->toggle(retraction);
+ toggle_option(el, retraction, i);
// retract lift above / below only applies if using retract lift
vec.resize(0);
vec = { "retract_lift_above", "retract_lift_below" };
for (auto el : vec)
- get_field(el, i)->toggle(retraction && m_config->opt_float("retract_lift", i) > 0);
+ toggle_option(el, retraction && (m_config->opt_float("retract_lift", i) > 0), i);
// some options only apply when not using firmware retraction
vec.resize(0);
vec = { "retract_speed", "deretract_speed", "retract_before_wipe", "retract_restart_extra", "wipe" };
for (auto el : vec)
- get_field(el, i)->toggle(retraction && !use_firmware_retraction);
+ toggle_option(el, retraction && !use_firmware_retraction, i);
bool wipe = m_config->opt_bool("wipe", i);
- get_field("retract_before_wipe", i)->toggle(wipe);
+ toggle_option("retract_before_wipe", wipe, i);
if (use_firmware_retraction && wipe) {
wxMessageDialog dialog(parent(),
_(L("The Wipe option is not available when using the Firmware Retraction mode.\n"
- "\nShall I disable it in order to enable Firmware Retraction?")),
+ "\nShall I disable it in order to enable Firmware Retraction?")),
_(L("Firmware Retraction")), wxICON_WARNING | wxYES | wxNO);
DynamicPrintConfig new_conf = *m_config;
@@ -2577,14 +2804,45 @@ void TabPrinter::update_fff()
load_config(new_conf);
}
- get_field("retract_length_toolchange", i)->toggle(have_multiple_extruders);
+ toggle_option("retract_length_toolchange", have_multiple_extruders, i);
bool toolchange_retraction = m_config->opt_float("retract_length_toolchange", i) > 0;
- get_field("retract_restart_extra_toolchange", i)->toggle
- (have_multiple_extruders && toolchange_retraction);
+ toggle_option("retract_restart_extra_toolchange", have_multiple_extruders && toolchange_retraction, i);
}
-// Thaw();
+ if (m_active_page->title() == "Machine limits" && m_machine_limits_description_line) {
+ assert(m_config->option<ConfigOptionEnum<GCodeFlavor>>("gcode_flavor")->value == gcfMarlin);
+ const auto *machine_limits_usage = m_config->option<ConfigOptionEnum<MachineLimitsUsage>>("machine_limits_usage");
+ bool enabled = machine_limits_usage->value != MachineLimitsUsage::Ignore;
+ bool silent_mode = m_config->opt_bool("silent_mode");
+ int max_field = silent_mode ? 2 : 1;
+ for (const std::string &opt : Preset::machine_limits_options())
+ for (int i = 0; i < max_field; ++ i)
+ toggle_option(opt, enabled, i);
+ update_machine_limits_description(machine_limits_usage->value);
+ }
+}
+
+void TabPrinter::update()
+{
+ m_update_cnt++;
+ m_presets->get_edited_preset().printer_technology() == ptFFF ? update_fff() : update_sla();
+ m_update_cnt--;
+
+ Layout();
+
+ if (m_update_cnt == 0)
+ wxGetApp().mainframe->on_config_changed(m_config);
+}
+
+void TabPrinter::update_fff()
+{
+ if (m_use_silent_mode != m_config->opt_bool("silent_mode")) {
+ m_rebuild_kinematics_page = true;
+ m_use_silent_mode = m_config->opt_bool("silent_mode");
+ }
+
+ toggle_options();
}
void TabPrinter::update_sla()
@@ -2604,7 +2862,7 @@ void Tab::load_current_preset()
{
const Preset& preset = m_presets->get_edited_preset();
- (preset.is_default || preset.is_system) ? m_btn_delete_preset->Disable() : m_btn_delete_preset->Enable(true);
+ update_btns_enabling();
update();
if (m_type == Slic3r::Preset::TYPE_PRINTER) {
@@ -2639,6 +2897,13 @@ void Tab::load_current_preset()
const PrinterTechnology printer_technology = m_presets->get_edited_preset().printer_technology();
if (printer_technology != static_cast<TabPrinter*>(this)->m_printer_technology)
{
+ // The change of the technology requires to remove some of unrelated Tabs
+ // During this action, wxNoteBook::RemovePage invoke wxEVT_NOTEBOOK_PAGE_CHANGED
+ // and as a result a function select_active_page() is called fron Tab::OnActive()
+ // But we don't need it. So, to avoid activation of the page, set m_active_page to NULL
+ // till unusable Tabs will be deleted
+ Page* tmp_page = m_active_page;
+ m_active_page = nullptr;
for (auto tab : wxGetApp().tabs_list) {
if (tab->type() == Preset::TYPE_PRINTER) // Printer tab is shown every time
continue;
@@ -2657,10 +2922,11 @@ void Tab::load_current_preset()
}
}
static_cast<TabPrinter*>(this)->m_printer_technology = printer_technology;
+ m_active_page = tmp_page;
}
on_presets_changed();
if (printer_technology == ptFFF) {
- static_cast<TabPrinter*>(this)->m_initial_extruders_count = static_cast<TabPrinter*>(this)->m_extruders_count;
+ static_cast<TabPrinter*>(this)->m_initial_extruders_count = static_cast<const ConfigOptionFloats*>(m_presets->get_selected_preset().config.option("nozzle_diameter"))->values.size(); //static_cast<TabPrinter*>(this)->m_extruders_count;
const Preset* parent_preset = m_presets->get_selected_preset_parent();
static_cast<TabPrinter*>(this)->m_sys_extruders_count = parent_preset == nullptr ? 0 :
static_cast<const ConfigOptionFloats*>(parent_preset->config.option("nozzle_diameter"))->values.size();
@@ -2690,61 +2956,57 @@ void Tab::rebuild_page_tree()
const auto selected = sel_item ? m_treectrl->GetItemText(sel_item) : "";
const auto rootItem = m_treectrl->GetRootItem();
- auto have_selection = 0;
+ wxTreeItemId item;
+
+ // Delete/Append events invoke wxEVT_TREE_SEL_CHANGED event.
+ // To avoid redundant clear/activate functions call
+ // suppress activate page before page_tree rebuilding
+ m_disable_tree_sel_changed_event = true;
m_treectrl->DeleteChildren(rootItem);
+
for (auto p : m_pages)
{
- auto itemId = m_treectrl->AppendItem(rootItem, p->title(), p->iconID());
+ if (!p->get_show())
+ continue;
+ auto itemId = m_treectrl->AppendItem(rootItem, translate_category(p->title(), m_type), p->iconID());
m_treectrl->SetItemTextColour(itemId, p->get_item_colour());
- if (p->title() == selected) {
- m_treectrl->SelectItem(itemId);
- have_selection = 1;
- }
+ if (translate_category(p->title(), m_type) == selected)
+ item = itemId;
}
-
- if (!have_selection) {
+ if (!item) {
// this is triggered on first load, so we don't disable the sel change event
- auto item = m_treectrl->GetFirstVisibleItem();
- if (item) {
- m_treectrl->SelectItem(item);
- }
+ item = m_treectrl->GetFirstVisibleItem();
}
+
+ // allow activate page before selection of a page_tree item
+ m_disable_tree_sel_changed_event = false;
+ if (item)
+ m_treectrl->SelectItem(item);
}
-void Tab::update_page_tree_visibility()
+void Tab::update_btns_enabling()
{
- const auto sel_item = m_treectrl->GetSelection();
- const auto selected = sel_item ? m_treectrl->GetItemText(sel_item) : "";
- const auto rootItem = m_treectrl->GetRootItem();
-
- auto have_selection = 0;
- m_treectrl->DeleteChildren(rootItem);
- for (auto p : m_pages)
- {
- if (!p->get_show())
- continue;
- auto itemId = m_treectrl->AppendItem(rootItem, p->title(), p->iconID());
- m_treectrl->SetItemTextColour(itemId, p->get_item_colour());
- if (p->title() == selected) {
- m_treectrl->SelectItem(itemId);
- have_selection = 1;
- }
- }
+ // we can delete any preset from the physical printer
+ // and any user preset
+ const Preset& preset = m_presets->get_edited_preset();
+ m_btn_delete_preset->Show(m_type == Preset::TYPE_PRINTER && m_preset_bundle->physical_printers.has_selection() ||
+ !preset.is_default && !preset.is_system);
- if (!have_selection) {
- // this is triggered on first load, so we don't disable the sel change event
- auto item = m_treectrl->GetFirstVisibleItem();
- if (item) {
- m_treectrl->SelectItem(item);
- }
- }
+ if (m_btn_edit_ph_printer)
+ m_btn_edit_ph_printer->SetToolTip( m_preset_bundle->physical_printers.has_selection() ?
+ _L("Edit physical printer") : _L("Add physical printer"));
+}
+void Tab::update_preset_choice()
+{
+ m_presets_choice->update();
+ update_btns_enabling();
}
// Called by the UI combo box when the user switches profiles, and also to delete the current profile.
// Select a preset by a name.If !defined(name), then the default preset is selected.
// If the current profile is modified, user is asked to save the changes.
-void Tab::select_preset(std::string preset_name, bool delete_current)
+void Tab::select_preset(std::string preset_name, bool delete_current /*=false*/, const std::string& last_selected_ph_printer_name/* =""*/)
{
if (preset_name.empty()) {
if (delete_current) {
@@ -2770,7 +3032,7 @@ void Tab::select_preset(std::string preset_name, bool delete_current)
bool canceled = false;
bool technology_changed = false;
m_dependent_tabs.clear();
- if (current_dirty && ! may_discard_current_dirty_preset()) {
+ if (current_dirty && ! may_discard_current_dirty_preset(nullptr, preset_name)) {
canceled = true;
} else if (print_tab) {
// Before switching the print profile to a new one, verify, whether the currently active filament or SLA material
@@ -2852,7 +3114,21 @@ void Tab::select_preset(std::string preset_name, bool delete_current)
}
if (canceled) {
+ if (m_type == Preset::TYPE_PRINTER) {
+ if (!last_selected_ph_printer_name.empty() &&
+ m_presets->get_edited_preset().name == PhysicalPrinter::get_preset_name(last_selected_ph_printer_name)) {
+ // If preset selection was canceled and previously was selected physical printer, we should select it back
+ m_preset_bundle->physical_printers.select_printer(last_selected_ph_printer_name);
+ }
+ if (m_preset_bundle->physical_printers.has_selection()) {
+ // If preset selection was canceled and physical printer was selected
+ // we must disable selection marker for the physical printers
+ m_preset_bundle->physical_printers.unselect_printer();
+ }
+ }
+
update_tab_ui();
+
// Trigger the on_presets_changed event so that we also restore the previous value in the plater selector,
// if this action was initiated from the plater.
on_presets_changed();
@@ -2894,6 +3170,14 @@ void Tab::select_preset(std::string preset_name, bool delete_current)
else if (printer_technology == ptSLA && m_dependent_tabs.front() != Preset::Type::TYPE_SLA_PRINT)
m_dependent_tabs = { Preset::Type::TYPE_SLA_PRINT, Preset::Type::TYPE_SLA_MATERIAL };
}
+
+ // check and apply extruders count for printer preset
+ if (m_type == Preset::TYPE_PRINTER)
+ static_cast<TabPrinter*>(this)->apply_extruder_cnt_from_cache();
+
+ // check if there is something in the cache to move to the new selected preset
+ apply_config_from_cache();
+
load_current_preset();
}
}
@@ -2903,41 +3187,56 @@ void Tab::select_preset(std::string preset_name, bool delete_current)
bool Tab::may_discard_current_dirty_preset(PresetCollection* presets /*= nullptr*/, const std::string& new_printer_name /*= ""*/)
{
if (presets == nullptr) presets = m_presets;
- // Display a dialog showing the dirty options in a human readable form.
- const Preset& old_preset = presets->get_edited_preset();
- std::string type_name = presets->name();
- wxString tab = " ";
- wxString name = old_preset.is_default ?
- from_u8((boost::format(_utf8(L("Default preset (%s)"))) % _utf8(type_name)).str()) :
- from_u8((boost::format(_utf8(L("Preset (%s)"))) % _utf8(type_name)).str()) + "\n" + tab + old_preset.name;
-
- // Collect descriptions of the dirty options.
- wxString changes;
- for (const std::string &opt_key : presets->current_dirty_options()) {
- const ConfigOptionDef &opt = m_config->def()->options.at(opt_key);
- /*std::string*/wxString name = "";
- if (! opt.category.empty())
- name += _(opt.category) + " > ";
- name += !opt.full_label.empty() ?
- _(opt.full_label) :
- _(opt.label);
- changes += tab + /*from_u8*/(name) + "\n";
- }
- // Show a confirmation dialog with the list of dirty options.
- wxString message = name + "\n\n";
- if (new_printer_name.empty())
- message += _(L("has the following unsaved changes:"));
- else {
- message += (m_type == Slic3r::Preset::TYPE_PRINTER) ?
- _(L("is not compatible with printer")) :
- _(L("is not compatible with print profile"));
- message += wxString("\n") + tab + from_u8(new_printer_name) + "\n\n";
- message += _(L("and it has the following unsaved changes:"));
+
+ UnsavedChangesDialog dlg(m_type, presets, new_printer_name);
+ if (wxGetApp().app_config->get("default_action_on_select_preset") == "none" && dlg.ShowModal() == wxID_CANCEL)
+ return false;
+
+ if (dlg.save_preset()) // save selected changes
+ {
+ const std::vector<std::string>& unselected_options = dlg.get_unselected_options(presets->type());
+ const std::string& name = dlg.get_preset_name();
+
+ if (m_type == presets->type()) // save changes for the current preset from this tab
+ {
+ // revert unselected options to the old values
+ presets->get_edited_preset().config.apply_only(presets->get_selected_preset().config, unselected_options);
+ save_preset(name);
+ }
+ else
+ {
+ m_preset_bundle->save_changes_for_preset(name, presets->type(), unselected_options);
+
+ // If filament preset is saved for multi-material printer preset,
+ // there are cases when filament comboboxs are updated for old (non-modified) colors,
+ // but in full_config a filament_colors option aren't.
+ if (presets->type() == Preset::TYPE_FILAMENT && wxGetApp().extruders_edited_cnt() > 1)
+ wxGetApp().plater()->force_filament_colors_update();
+ }
}
- wxMessageDialog confirm(parent(),
- message + "\n" + changes + "\n\n" + _(L("Discard changes and continue anyway?")),
- _(L("Unsaved Changes")), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION);
- return confirm.ShowModal() == wxID_YES;
+ else if (dlg.transfer_changes()) // move selected changes
+ {
+ std::vector<std::string> selected_options = dlg.get_selected_options();
+ if (m_type == presets->type()) // move changes for the current preset from this tab
+ {
+ if (m_type == Preset::TYPE_PRINTER) {
+ auto it = std::find(selected_options.begin(), selected_options.end(), "extruders_count");
+ if (it != selected_options.end()) {
+ // erase "extruders_count" option from the list
+ selected_options.erase(it);
+ // cache the extruders count
+ static_cast<TabPrinter*>(this)->cache_extruder_cnt();
+ }
+ }
+
+ // copy selected options to the cache from edited preset
+ cache_config_diff(selected_options);
+ }
+ else
+ wxGetApp().get_tab(presets->type())->cache_config_diff(selected_options);
+ }
+
+ return true;
}
// If we are switching from the FFF-preset to the SLA, we should to control the printed objects if they have a part(s).
@@ -2955,14 +3254,48 @@ bool Tab::may_switch_to_SLA_preset()
return true;
}
-void Tab::OnTreeSelChange(wxTreeEvent& event)
+void Tab::clear_pages()
{
- if (m_disable_tree_sel_changed_event)
+ // invalidated highlighter, if any exists
+ m_highlighter.invalidate();
+ m_page_sizer->Clear(true);
+ // clear pages from the controlls
+ for (auto p : m_pages)
+ p->clear();
+
+ // nulling pointers
+ m_parent_preset_description_line = nullptr;
+ m_detach_preset_btn = nullptr;
+
+ m_compatible_printers.checkbox = nullptr;
+ m_compatible_printers.btn = nullptr;
+
+ m_compatible_prints.checkbox = nullptr;
+ m_compatible_prints.btn = nullptr;
+}
+
+void Tab::update_description_lines()
+{
+ if (m_active_page && m_active_page->title() == "Dependencies" && m_parent_preset_description_line)
+ update_preset_description_line();
+}
+
+void Tab::activate_selected_page(std::function<void()> throw_if_canceled)
+{
+ if (!m_active_page)
return;
-// There is a bug related to Ubuntu overlay scrollbars, see https://github.com/prusa3d/PrusaSlicer/issues/898 and https://github.com/prusa3d/PrusaSlicer/issues/952.
-// The issue apparently manifests when Show()ing a window with overlay scrollbars while the UI is frozen. For this reason,
-// we will Thaw the UI prematurely on Linux. This means destroing the no_updates object prematurely.
+ m_active_page->activate(m_mode, throw_if_canceled);
+ update_changed_ui();
+ update_description_lines();
+ toggle_options();
+}
+
+bool Tab::tree_sel_change_delayed()
+{
+ // There is a bug related to Ubuntu overlay scrollbars, see https://github.com/prusa3d/PrusaSlicer/issues/898 and https://github.com/prusa3d/PrusaSlicer/issues/952.
+ // The issue apparently manifests when Show()ing a window with overlay scrollbars while the UI is frozen. For this reason,
+ // we will Thaw the UI prematurely on Linux. This means destroing the no_updates object prematurely.
#ifdef __linux__
std::unique_ptr<wxWindowUpdateLocker> no_updates(new wxWindowUpdateLocker(this));
#else
@@ -2970,44 +3303,60 @@ void Tab::OnTreeSelChange(wxTreeEvent& event)
* so on Window is no needed to call a Freeze/Thaw functions.
* But under OSX (builds compiled with MacOSX10.14.sdk) wxStaticBitmap rendering is broken without Freeze/Thaw call.
*/
-#ifdef __WXOSX__
- wxWindowUpdateLocker noUpdates(this);
-#endif
+//#ifdef __WXOSX__ // Use Freeze/Thaw to avoid flickering during clear/activate new page
+ wxWindowUpdateLocker noUpdates(this);
+//#endif
#endif
- if (m_pages.empty())
- return;
-
Page* page = nullptr;
const auto sel_item = m_treectrl->GetSelection();
const auto selection = sel_item ? m_treectrl->GetItemText(sel_item) : "";
for (auto p : m_pages)
- if (p->title() == selection)
+ if (translate_category(p->title(), m_type) == selection)
{
page = p.get();
m_is_nonsys_values = page->m_is_nonsys_values;
m_is_modified_values = page->m_is_modified_values;
break;
}
- if (page == nullptr) return;
+ if (page == nullptr || m_active_page == page)
+ return false;
- for (auto& el : m_pages)
-// if (el.get()->IsShown()) {
- el.get()->Hide();
-// break;
-// }
+ // clear pages from the controls
+ m_active_page = page;
+
+ auto throw_if_canceled = std::function<void()>([this](){
+#ifdef WIN32
+ wxCheckForInterrupt(m_treectrl);
+ if (m_page_switch_planned)
+ throw UIBuildCanceled();
+#endif // WIN32
+ });
- #ifdef __linux__
- no_updates.reset(nullptr);
- #endif
+ try {
+ clear_pages();
+ throw_if_canceled();
+
+ if (wxGetApp().mainframe!=nullptr && wxGetApp().mainframe->is_active_and_shown_tab(this))
+ activate_selected_page(throw_if_canceled);
+
+ #ifdef __linux__
+ no_updates.reset(nullptr);
+ #endif
+
+ update_undo_buttons();
+ throw_if_canceled();
- update_undo_buttons();
- page->Show();
-// if (! page->layout_valid) {
- page->layout_valid = true;
m_hsizer->Layout();
+ throw_if_canceled();
Refresh();
-// }
+ } catch (const UIBuildCanceled&) {
+ if (m_active_page)
+ m_active_page->clear();
+ return true;
+ }
+
+ return false;
}
void Tab::OnKeyDown(wxKeyEvent& event)
@@ -3022,7 +3371,7 @@ void Tab::OnKeyDown(wxKeyEvent& event)
// This removes the "dirty" flag of the preset, possibly creates a new preset under a new name,
// and activates the new preset.
// Wizard calls save_preset with a name "My Settings", otherwise no name is provided and this method
-// opens a Slic3r::GUI::SavePresetWindow dialog.
+// opens a Slic3r::GUI::SavePresetDialog dialog.
void Tab::save_preset(std::string name /*= ""*/, bool detach)
{
// since buttons(and choices too) don't get focus on Mac, we set focus manually
@@ -3030,59 +3379,11 @@ void Tab::save_preset(std::string name /*= ""*/, bool detach)
// focus currently.is there anything better than this ?
//! m_treectrl->OnSetFocus();
- std::string suffix = detach ? _utf8(L("Detached")) : _CTX_utf8(L_CONTEXT("Copy", "PresetName"), "PresetName");
-
if (name.empty()) {
- const Preset &preset = m_presets->get_selected_preset();
- auto default_name = preset.is_default ? "Untitled" :
-// preset.is_system ? (boost::format(_CTX_utf8(L_CONTEXT("%1% - Copy", "PresetName"), "PresetName")) % preset.name).str() :
- preset.is_system ? (boost::format(("%1% - %2%")) % preset.name % suffix).str() :
- preset.name;
-
- bool have_extention = boost::iends_with(default_name, ".ini");
- if (have_extention) {
- size_t len = default_name.length()-4;
- default_name.resize(len);
- }
- //[map $_->name, grep !$_->default && !$_->external, @{$self->{presets}}],
- std::vector<std::string> values;
- for (size_t i = 0; i < m_presets->size(); ++i) {
- const Preset &preset = m_presets->preset(i);
- if (preset.is_default || preset.is_system || preset.is_external)
- continue;
- values.push_back(preset.name);
- }
-
- SavePresetWindow dlg(parent());
- dlg.build(title(), default_name, values);
+ SavePresetDialog dlg(m_parent, m_type, detach ? _u8L("Detached") : "");
if (dlg.ShowModal() != wxID_OK)
return;
name = dlg.get_name();
- if (name == "") {
- show_error(this, _(L("The supplied name is empty. It can't be saved.")));
- return;
- }
- const Preset *existing = m_presets->find_preset(name, false);
- if (existing && (existing->is_default || existing->is_system)) {
- show_error(this, _(L("Cannot overwrite a system profile.")));
- return;
- }
- if (existing && (existing->is_external)) {
- show_error(this, _(L("Cannot overwrite an external profile.")));
- return;
- }
- if (existing && name != preset.name)
- {
- wxString msg_text = GUI::from_u8((boost::format(_utf8(L("Preset with name \"%1%\" already exists."))) % name).str());
- msg_text += "\n" + _(L("Replace?"));
- wxMessageDialog dialog(nullptr, msg_text, _(L("Warning")), wxICON_WARNING | wxYES | wxNO);
-
- if (dialog.ShowModal() == wxID_NO)
- return;
-
- // Remove the preset from the list.
- m_presets->delete_preset(name);
- }
}
// Save the preset into Slic3r::data_dir / presets / section_name / preset_name.ini
@@ -3095,7 +3396,7 @@ void Tab::save_preset(std::string name /*= ""*/, bool detach)
// Update the selection boxes at the plater.
on_presets_changed();
// If current profile is saved, "delete preset" button have to be enabled
- m_btn_delete_preset->Enable(true);
+ m_btn_delete_preset->Show();
if (m_type == Preset::TYPE_PRINTER)
static_cast<TabPrinter*>(this)->m_initial_extruders_count = static_cast<TabPrinter*>(this)->m_extruders_count;
@@ -3113,28 +3414,28 @@ void Tab::save_preset(std::string name /*= ""*/, bool detach)
wxGetApp().plater()->force_filament_colors_update();
{
- // Profile compatiblity is updated first when the profile is saved.
- // Update profile selection combo boxes at the depending tabs to reflect modifications in profile compatibility.
- std::vector<Preset::Type> dependent;
- switch (m_type) {
- case Preset::TYPE_PRINT:
- dependent = { Preset::TYPE_FILAMENT };
- break;
- case Preset::TYPE_SLA_PRINT:
- dependent = { Preset::TYPE_SLA_MATERIAL };
- break;
- case Preset::TYPE_PRINTER:
+ // Profile compatiblity is updated first when the profile is saved.
+ // Update profile selection combo boxes at the depending tabs to reflect modifications in profile compatibility.
+ std::vector<Preset::Type> dependent;
+ switch (m_type) {
+ case Preset::TYPE_PRINT:
+ dependent = { Preset::TYPE_FILAMENT };
+ break;
+ case Preset::TYPE_SLA_PRINT:
+ dependent = { Preset::TYPE_SLA_MATERIAL };
+ break;
+ case Preset::TYPE_PRINTER:
if (static_cast<const TabPrinter*>(this)->m_printer_technology == ptFFF)
dependent = { Preset::TYPE_PRINT, Preset::TYPE_FILAMENT };
else
dependent = { Preset::TYPE_SLA_PRINT, Preset::TYPE_SLA_MATERIAL };
- break;
+ break;
default:
- break;
- }
- for (Preset::Type preset_type : dependent)
- wxGetApp().get_tab(preset_type)->update_tab_ui();
- }
+ break;
+ }
+ for (Preset::Type preset_type : dependent)
+ wxGetApp().get_tab(preset_type)->update_tab_ui();
+ }
}
// Called for a currently selected preset.
@@ -3144,13 +3445,73 @@ void Tab::delete_preset()
// Don't let the user delete the ' - default - ' configuration.
std::string action = current_preset.is_external ? _utf8(L("remove")) : _utf8(L("delete"));
// TRN remove/delete
- const wxString msg = from_u8((boost::format(_utf8(L("Are you sure you want to %1% the selected preset?"))) % action).str());
+
+ PhysicalPrinterCollection& physical_printers = m_preset_bundle->physical_printers;
+ wxString msg;
+ if (m_presets_choice->is_selected_physical_printer())
+ {
+ PhysicalPrinter& printer = physical_printers.get_selected_printer();
+ if (printer.preset_names.size() == 1) {
+ if (m_presets_choice->del_physical_printer(_L("It's a last preset for this physical printer.")))
+ Layout();
+ return;
+ }
+
+ msg = format_wxstr(_L("Are you sure you want to delete \"%1%\" preset from the physical printer \"%2%\"?"), current_preset.name, printer.name);
+ }
+ else
+ {
+ if (m_type == Preset::TYPE_PRINTER && !physical_printers.empty())
+ {
+ // Check preset for delete in physical printers
+ // Ask a customer about next action, if there is a printer with just one preset and this preset is equal to delete
+ std::vector<std::string> ph_printers = physical_printers.get_printers_with_preset(current_preset.name);
+ std::vector<std::string> ph_printers_only = physical_printers.get_printers_with_only_preset(current_preset.name);
+
+ if (!ph_printers.empty()) {
+ msg += _L("The physical printer(s) below is based on the preset, you are going to delete.");
+ for (const std::string& printer : ph_printers)
+ msg += "\n \"" + from_u8(printer) + "\",";
+ msg.RemoveLast();
+ msg += "\n" + _L("Note, that selected preset will be deleted from this/those printer(s) too.")+ "\n\n";
+ }
+
+ if (!ph_printers_only.empty()) {
+ msg += _L("The physical printer(s) below is based only on the preset, you are going to delete.");
+ for (const std::string& printer : ph_printers_only)
+ msg += "\n \"" + from_u8(printer) + "\",";
+ msg.RemoveLast();
+ msg += "\n" + _L("Note, that this/those printer(s) will be deleted after deleting of the selected preset.") + "\n\n";
+ }
+ }
+
+ msg += from_u8((boost::format(_u8L("Are you sure you want to %1% the selected preset?")) % action).str());
+ }
+
action = current_preset.is_external ? _utf8(L("Remove")) : _utf8(L("Delete"));
// TRN Remove/Delete
wxString title = from_u8((boost::format(_utf8(L("%1% Preset"))) % action).str()); //action + _(L(" Preset"));
if (current_preset.is_default ||
wxID_YES != wxMessageDialog(parent(), msg, title, wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION).ShowModal())
return;
+
+ // if we just delete preset from the physical printer
+ if (m_presets_choice->is_selected_physical_printer()) {
+ PhysicalPrinter& printer = physical_printers.get_selected_printer();
+
+ // just delete this preset from the current physical printer
+ printer.delete_preset(m_presets->get_edited_preset().name);
+ // select first from the possible presets for this printer
+ physical_printers.select_printer(printer);
+
+ this->select_preset(physical_printers.get_selected_printer_preset_name());
+ return;
+ }
+
+ // delete selected preset from printers and printer, if it's needed
+ if (m_type == Preset::TYPE_PRINTER && !physical_printers.empty())
+ physical_printers.delete_preset_from_printers(current_preset.name);
+
// Select will handle of the preset dependencies, of saving & closing the depending profiles, and
// finally of deleting the preset.
this->select_preset("", true);
@@ -3159,6 +3520,7 @@ void Tab::delete_preset()
void Tab::toggle_show_hide_incompatible()
{
m_show_incompatible_presets = !m_show_incompatible_presets;
+ m_presets_choice->set_show_incompatible_presets(m_show_incompatible_presets);
update_show_hide_incompatible_button();
update_tab_ui();
}
@@ -3192,13 +3554,16 @@ void Tab::update_ui_from_settings()
}
}
-void Tab::create_line_with_widget(ConfigOptionsGroup* optgroup, const std::string& opt_key, widget_t widget)
+void Tab::create_line_with_widget(ConfigOptionsGroup* optgroup, const std::string& opt_key, const wxString& path, widget_t widget)
{
Line line = optgroup->create_single_option_line(opt_key);
line.widget = widget;
+ line.label_path = path;
- m_colored_Labels[opt_key] = nullptr;
- optgroup->append_line(line, &m_colored_Labels[opt_key]);
+ m_colored_Label_colors[opt_key] = m_default_text_clr;
+ line.full_Label_color = &m_colored_Label_colors[opt_key];
+
+ optgroup->append_line(line);
}
// Return a callback to create a Tab widget to mark the preferences as compatible / incompatible to the current printer.
@@ -3206,8 +3571,10 @@ wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &dep
{
deps.checkbox = new wxCheckBox(parent, wxID_ANY, _(L("All")));
deps.checkbox->SetFont(Slic3r::GUI::wxGetApp().normal_font());
- add_scaled_button(parent, &deps.btn, "printer_white", from_u8((boost::format(" %s %s") % _utf8(L("Set")) % std::string(dots.ToUTF8())).str()), wxBU_LEFT | wxBU_EXACTFIT);
+ deps.btn = new ScalableButton(parent, wxID_ANY, "printer", from_u8((boost::format(" %s %s") % _utf8(L("Set")) % std::string(dots.ToUTF8())).str()),
+ wxDefaultSize, wxDefaultPosition, wxBU_LEFT | wxBU_EXACTFIT, true);
deps.btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
+ deps.btn->SetSize(deps.btn->GetBestSize());
auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add((deps.checkbox), 0, wxALIGN_CENTER_VERTICAL);
@@ -3269,18 +3636,20 @@ wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &dep
this->update_changed_ui();
}
}));
+
return sizer;
}
// Return a callback to create a TabPrinter widget to edit bed shape
wxSizer* TabPrinter::create_bed_shape_widget(wxWindow* parent)
{
- ScalableButton* btn;
- add_scaled_button(parent, &btn, "printer_white", " " + _(L("Set")) + " " + dots, wxBU_LEFT | wxBU_EXACTFIT);
+ ScalableButton* btn = new ScalableButton(parent, wxID_ANY, "printer", " " + _(L("Set")) + " " + dots,
+ wxDefaultSize, wxDefaultPosition, wxBU_LEFT | wxBU_EXACTFIT, true);
btn->SetFont(wxGetApp().normal_font());
+ btn->SetSize(btn->GetBestSize());
auto sizer = new wxBoxSizer(wxHORIZONTAL);
- sizer->Add(btn);
+ sizer->Add(btn, 0, wxALIGN_CENTER_VERTICAL);
btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e)
{
@@ -3302,15 +3671,67 @@ wxSizer* TabPrinter::create_bed_shape_widget(wxWindow* parent)
}
}));
+ // may be it is not a best place, but
+ // add information about Category/Grope for "bed_custom_texture" and "bed_custom_model" as a copy from "bed_shape" option
+ {
+ Search::OptionsSearcher& searcher = wxGetApp().sidebar().get_searcher();
+ const Search::GroupAndCategory& gc = searcher.get_group_and_category("bed_shape");
+ searcher.add_key("bed_custom_texture", gc.group, gc.category);
+ searcher.add_key("bed_custom_model", gc.group, gc.category);
+ }
+
return sizer;
}
+void TabPrinter::cache_extruder_cnt()
+{
+ if (m_presets->get_edited_preset().printer_technology() == ptSLA)
+ return;
+
+ m_cache_extruder_count = m_extruders_count;
+}
+
+void TabPrinter::apply_extruder_cnt_from_cache()
+{
+ if (m_presets->get_edited_preset().printer_technology() == ptSLA)
+ return;
+
+ if (m_cache_extruder_count > 0) {
+ m_presets->get_edited_preset().set_num_extruders(m_cache_extruder_count);
+ m_cache_extruder_count = 0;
+ }
+}
+
+void TabPrinter::update_machine_limits_description(const MachineLimitsUsage usage)
+{
+ wxString text;
+ switch (usage) {
+ case MachineLimitsUsage::EmitToGCode:
+ text = _L("Machine limits will be emitted to G-code and used to estimate print time.");
+ break;
+ case MachineLimitsUsage::TimeEstimateOnly:
+ text = _L("Machine limits will NOT be emitted to G-code, however they will be used to estimate print time, "
+ "which may therefore not be accurate as the printer may apply a different set of machine limits.");
+ break;
+ case MachineLimitsUsage::Ignore:
+ text = _L("Machine limits are not set, therefore the print time estimate may not be accurate.");
+ break;
+ default: assert(false);
+ }
+ m_machine_limits_description_line->SetText(text);
+}
+
void Tab::compatible_widget_reload(PresetDependencies &deps)
{
+ Field* field = this->get_field(deps.key_condition);
+ if (!field)
+ return;
+
bool has_any = ! m_config->option<ConfigOptionStrings>(deps.key_list)->values.empty();
has_any ? deps.btn->Enable() : deps.btn->Disable();
deps.checkbox->SetValue(! has_any);
- this->get_field(deps.key_condition)->toggle(! has_any);
+
+ field->toggle(! has_any);
}
void Tab::fill_icon_descriptions()
@@ -3371,27 +3792,70 @@ void Tab::set_tooltips_text()
"Click to reset current value to the last saved preset."));
}
+Page::Page(wxWindow* parent, const wxString& title, int iconID) :
+ m_parent(parent),
+ m_title(title),
+ m_iconID(iconID)
+{
+ m_vsizer = (wxBoxSizer*)parent->GetSizer();
+ m_item_color = &wxGetApp().get_label_clr_default();
+}
+
void Page::reload_config()
{
for (auto group : m_optgroups)
group->reload_config();
}
-void Page::update_visibility(ConfigOptionMode mode)
+void Page::update_visibility(ConfigOptionMode mode, bool update_contolls_visibility)
{
bool ret_val = false;
- for (auto group : m_optgroups)
- ret_val = group->update_visibility(mode) || ret_val;
+ for (auto group : m_optgroups) {
+ ret_val = (update_contolls_visibility ?
+ group->update_visibility(mode) : // update visibility for all controlls in group
+ group->is_visible(mode) // just detect visibility for the group
+ ) || ret_val;
+ }
m_show = ret_val;
}
+void Page::activate(ConfigOptionMode mode, std::function<void()> throw_if_canceled)
+{
+ for (auto group : m_optgroups) {
+ if (!group->activate(throw_if_canceled))
+ continue;
+ m_vsizer->Add(group->sizer, 0, wxEXPAND | (group->is_legend_line() ? (wxLEFT|wxTOP) : wxALL), 10);
+ group->update_visibility(mode);
+ group->reload_config();
+ throw_if_canceled();
+ }
+}
+
+void Page::clear()
+{
+ for (auto group : m_optgroups)
+ group->clear();
+}
+
void Page::msw_rescale()
{
for (auto group : m_optgroups)
group->msw_rescale();
}
+void Page::sys_color_changed()
+{
+ for (auto group : m_optgroups)
+ group->sys_color_changed();
+}
+
+void Page::refresh()
+{
+ for (auto group : m_optgroups)
+ group->refresh();
+}
+
Field* Page::get_field(const t_config_option_key& opt_key, int opt_index /*= -1*/) const
{
Field* field = nullptr;
@@ -3407,7 +3871,7 @@ bool Page::set_value(const t_config_option_key& opt_key, const boost::any& value
bool changed = false;
for(auto optgroup: m_optgroups) {
if (optgroup->set_value(opt_key, value))
- changed = 1 ;
+ changed = true ;
}
return changed;
}
@@ -3415,29 +3879,16 @@ bool Page::set_value(const t_config_option_key& opt_key, const boost::any& value
// package Slic3r::GUI::Tab::Page;
ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_label_width /*= -1*/)
{
- auto extra_column = [this](wxWindow* parent, const Line& line)
- {
- std::string bmp_name;
- const std::vector<Option>& options = line.get_options();
- int mode_id = int(options[0].opt.mode);
- const wxBitmap& bitmap = options.size() == 0 || options[0].opt.gui_type == "legend" ? wxNullBitmap :
- m_mode_bitmap_cache[mode_id].bmp();
- auto bmp = new wxStaticBitmap(parent, wxID_ANY, bitmap);
- bmp->SetClientData((void*)&m_mode_bitmap_cache[mode_id]);
-
- bmp->SetBackgroundStyle(wxBG_STYLE_PAINT);
- return bmp;
- };
-
//! config_ have to be "right"
- ConfigOptionsGroupShp optgroup = std::make_shared<ConfigOptionsGroup>(this, title, m_config, true, extra_column);
+ ConfigOptionsGroupShp optgroup = std::make_shared<ConfigOptionsGroup>(m_parent, title, m_config, true);
+ optgroup->set_config_category(m_title.ToStdString());
if (noncommon_label_width >= 0)
optgroup->label_width = noncommon_label_width;
#ifdef __WXOSX__
- auto tab = GetParent()->GetParent();
+ auto tab = parent()->GetParent()->GetParent();// GetParent()->GetParent();
#else
- auto tab = GetParent();
+ auto tab = parent()->GetParent();// GetParent();
#endif
optgroup->m_on_change = [this, tab](t_config_option_key opt_key, boost::any value) {
//! This function will be called from OptionGroup.
@@ -3471,79 +3922,19 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la
ctrl->SetBitmap(reinterpret_cast<ScalableBitmap*>(ctrl->GetClientData())->bmp());
};
- vsizer()->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 10);
m_optgroups.push_back(optgroup);
return optgroup;
}
-void SavePresetWindow::build(const wxString& title, const std::string& default_name, std::vector<std::string> &values)
-{
- // TRN Preset
- auto text = new wxStaticText(this, wxID_ANY, from_u8((boost::format(_utf8(L("Save %s as:"))) % into_u8(title)).str()),
- wxDefaultPosition, wxDefaultSize);
- m_combo = new wxComboBox(this, wxID_ANY, from_u8(default_name),
- wxDefaultPosition, wxDefaultSize, 0, 0, wxTE_PROCESS_ENTER);
- for (auto value : values)
- m_combo->Append(from_u8(value));
- auto buttons = CreateStdDialogButtonSizer(wxOK | wxCANCEL);
-
- auto sizer = new wxBoxSizer(wxVERTICAL);
- sizer->Add(text, 0, wxEXPAND | wxALL, 10);
- sizer->Add(m_combo, 0, wxEXPAND | wxLEFT | wxRIGHT, 10);
- sizer->Add(buttons, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 10);
-
- wxButton* btn = static_cast<wxButton*>(FindWindowById(wxID_OK, this));
- btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { accept(); });
- m_combo->Bind(wxEVT_TEXT_ENTER, [this](wxCommandEvent&) { accept(); });
-
- SetSizer(sizer);
- sizer->SetSizeHints(this);
-}
-
-void SavePresetWindow::accept()
-{
- m_chosen_name = normalize_utf8_nfc(m_combo->GetValue().ToUTF8());
- if (!m_chosen_name.empty()) {
- const char* unusable_symbols = "<>[]:/\\|?*\"";
- bool is_unusable_symbol = false;
- bool is_unusable_suffix = false;
- const std::string unusable_suffix = PresetCollection::get_suffix_modified();//"(modified)";
- for (size_t i = 0; i < std::strlen(unusable_symbols); i++) {
- if (m_chosen_name.find_first_of(unusable_symbols[i]) != std::string::npos) {
- is_unusable_symbol = true;
- break;
- }
- }
- if (m_chosen_name.find(unusable_suffix) != std::string::npos)
- is_unusable_suffix = true;
-
- if (is_unusable_symbol) {
- show_error(this,_(L("The supplied name is not valid;")) + "\n" +
- _(L("the following characters are not allowed:")) + " " + unusable_symbols);
- }
- else if (is_unusable_suffix) {
- show_error(this,_(L("The supplied name is not valid;")) + "\n" +
- _(L("the following suffix is not allowed:")) + "\n\t" +
- wxString::FromUTF8(unusable_suffix.c_str()));
- }
- else if (m_chosen_name == "- default -") {
- show_error(this, _(L("The supplied name is not available.")));
- }
- else {
- EndModal(wxID_OK);
- }
- }
-}
-
void TabSLAMaterial::build()
{
m_presets = &m_preset_bundle->sla_materials;
load_initial_data();
- auto page = add_options_page(_(L("Material")), "resin");
+ auto page = add_options_page(L("Material"), "resin");
- auto optgroup = page->new_optgroup(_(L("Material")));
+ auto optgroup = page->new_optgroup(L("Material"));
optgroup->append_single_option_line("bottle_cost");
optgroup->append_single_option_line("bottle_volume");
optgroup->append_single_option_line("bottle_weight");
@@ -3575,19 +3966,19 @@ void TabSLAMaterial::build()
wxGetApp().sidebar().Layout();
};
- optgroup = page->new_optgroup(_(L("Layers")));
+ optgroup = page->new_optgroup(L("Layers"));
optgroup->append_single_option_line("initial_layer_height");
- optgroup = page->new_optgroup(_(L("Exposure")));
+ optgroup = page->new_optgroup(L("Exposure"));
optgroup->append_single_option_line("exposure_time");
optgroup->append_single_option_line("initial_exposure_time");
- optgroup = page->new_optgroup(_(L("Corrections")));
+ optgroup = page->new_optgroup(L("Corrections"));
std::vector<std::string> corrections = {"material_correction"};
// std::vector<std::string> axes{ "X", "Y", "Z" };
std::vector<std::string> axes{ "XY", "Z" };
for (auto& opt_key : corrections) {
- auto line = Line{ _(m_config->def()->get(opt_key)->full_label), "" };
+ auto line = Line{ m_config->def()->get(opt_key)->full_label, "" };
int id = 0;
for (auto& axis : axes) {
auto opt = optgroup->get_option(opt_key, id);
@@ -3598,18 +3989,18 @@ void TabSLAMaterial::build()
optgroup->append_line(line);
}
- page = add_options_page(_(L("Notes")), "note.png");
- optgroup = page->new_optgroup(_(L("Notes")), 0);
+ page = add_options_page(L("Notes"), "note.png");
+ optgroup = page->new_optgroup(L("Notes"), 0);
optgroup->label_width = 0;
Option option = optgroup->get_option("material_notes");
option.opt.full_width = true;
option.opt.height = 25;//250;
optgroup->append_single_option_line(option);
- page = add_options_page(_(L("Dependencies")), "wrench.png");
- optgroup = page->new_optgroup(_(L("Profile dependencies")));
+ page = add_options_page(L("Dependencies"), "wrench.png");
+ optgroup = page->new_optgroup(L("Profile dependencies"));
- create_line_with_widget(optgroup.get(), "compatible_printers", [this](wxWindow* parent) {
+ create_line_with_widget(optgroup.get(), "compatible_printers", wxEmptyString, [this](wxWindow* parent) {
return compatible_widget_create(parent, m_compatible_printers);
});
@@ -3617,7 +4008,7 @@ void TabSLAMaterial::build()
option.opt.full_width = true;
optgroup->append_single_option_line(option);
- create_line_with_widget(optgroup.get(), "compatible_prints", [this](wxWindow* parent) {
+ create_line_with_widget(optgroup.get(), "compatible_prints", wxEmptyString, [this](wxWindow* parent) {
return compatible_widget_create(parent, m_compatible_prints);
});
@@ -3655,23 +4046,24 @@ void TabSLAPrint::build()
m_presets = &m_preset_bundle->sla_prints;
load_initial_data();
- auto page = add_options_page(_(L("Layers and perimeters")), "layers");
+ auto page = add_options_page(L("Layers and perimeters"), "layers");
- auto optgroup = page->new_optgroup(_(L("Layers")));
+ auto optgroup = page->new_optgroup(L("Layers"));
optgroup->append_single_option_line("layer_height");
optgroup->append_single_option_line("faded_layers");
- page = add_options_page(_(L("Supports")), "support"/*"sla_supports"*/);
- optgroup = page->new_optgroup(_(L("Supports")));
+ page = add_options_page(L("Supports"), "support"/*"sla_supports"*/);
+ optgroup = page->new_optgroup(L("Supports"));
optgroup->append_single_option_line("supports_enable");
- optgroup = page->new_optgroup(_(L("Support head")));
+ optgroup = page->new_optgroup(L("Support head"));
optgroup->append_single_option_line("support_head_front_diameter");
optgroup->append_single_option_line("support_head_penetration");
optgroup->append_single_option_line("support_head_width");
- optgroup = page->new_optgroup(_(L("Support pillar")));
+ optgroup = page->new_optgroup(L("Support pillar"));
optgroup->append_single_option_line("support_pillar_diameter");
+ optgroup->append_single_option_line("support_small_pillar_diameter_percent");
optgroup->append_single_option_line("support_max_bridges_on_pillar");
optgroup->append_single_option_line("support_pillar_connection_mode");
@@ -3683,20 +4075,26 @@ void TabSLAPrint::build()
optgroup->append_single_option_line("support_base_safety_distance");
// Mirrored parameter from Pad page for toggling elevation on the same page
- optgroup->append_single_option_line("pad_around_object");
optgroup->append_single_option_line("support_object_elevation");
- optgroup = page->new_optgroup(_(L("Connection of the support sticks and junctions")));
+ Line line{ "", "" };
+ line.full_width = 1;
+ line.widget = [this](wxWindow* parent) {
+ return description_line_widget(parent, &m_support_object_elevation_description_line);
+ };
+ optgroup->append_line(line);
+
+ optgroup = page->new_optgroup(L("Connection of the support sticks and junctions"));
optgroup->append_single_option_line("support_critical_angle");
optgroup->append_single_option_line("support_max_bridge_length");
optgroup->append_single_option_line("support_max_pillar_link_distance");
- optgroup = page->new_optgroup(_(L("Automatic generation")));
+ optgroup = page->new_optgroup(L("Automatic generation"));
optgroup->append_single_option_line("support_points_density_relative");
optgroup->append_single_option_line("support_points_minimal_distance");
- page = add_options_page(_(L("Pad")), "pad");
- optgroup = page->new_optgroup(_(L("Pad")));
+ page = add_options_page(L("Pad"), "pad");
+ optgroup = page->new_optgroup(L("Pad"));
optgroup->append_single_option_line("pad_enable");
optgroup->append_single_option_line("pad_wall_thickness");
optgroup->append_single_option_line("pad_wall_height");
@@ -3713,27 +4111,27 @@ void TabSLAPrint::build()
optgroup->append_single_option_line("pad_object_connector_width");
optgroup->append_single_option_line("pad_object_connector_penetration");
- page = add_options_page(_(L("Hollowing")), "hollowing");
- optgroup = page->new_optgroup(_(L("Hollowing")));
+ page = add_options_page(L("Hollowing"), "hollowing");
+ optgroup = page->new_optgroup(L("Hollowing"));
optgroup->append_single_option_line("hollowing_enable");
optgroup->append_single_option_line("hollowing_min_thickness");
optgroup->append_single_option_line("hollowing_quality");
optgroup->append_single_option_line("hollowing_closing_distance");
- page = add_options_page(_(L("Advanced")), "wrench");
- optgroup = page->new_optgroup(_(L("Slicing")));
+ page = add_options_page(L("Advanced"), "wrench");
+ optgroup = page->new_optgroup(L("Slicing"));
optgroup->append_single_option_line("slice_closing_radius");
- page = add_options_page(_(L("Output options")), "output+page_white");
- optgroup = page->new_optgroup(_(L("Output file")));
+ page = add_options_page(L("Output options"), "output+page_white");
+ optgroup = page->new_optgroup(L("Output file"));
Option option = optgroup->get_option("output_filename_format");
option.opt.full_width = true;
optgroup->append_single_option_line(option);
- page = add_options_page(_(L("Dependencies")), "wrench");
- optgroup = page->new_optgroup(_(L("Profile dependencies")));
+ page = add_options_page(L("Dependencies"), "wrench");
+ optgroup = page->new_optgroup(L("Profile dependencies"));
- create_line_with_widget(optgroup.get(), "compatible_printers", [this](wxWindow* parent) {
+ create_line_with_widget(optgroup.get(), "compatible_printers", wxEmptyString, [this](wxWindow* parent) {
return compatible_widget_create(parent, m_compatible_printers);
});
@@ -3751,6 +4149,34 @@ void TabSLAPrint::reload_config()
Tab::reload_config();
}
+void TabSLAPrint::update_description_lines()
+{
+ Tab::update_description_lines();
+
+ if (m_active_page && m_active_page->title() == "Supports")
+ {
+ bool is_visible = m_config->def()->get("support_object_elevation")->mode <= m_mode;
+ if (m_support_object_elevation_description_line)
+ {
+ m_support_object_elevation_description_line->Show(is_visible);
+ if (is_visible)
+ {
+ bool elev = !m_config->opt_bool("pad_enable") || !m_config->opt_bool("pad_around_object");
+ m_support_object_elevation_description_line->SetText(elev ? "" :
+ from_u8((boost::format(_u8L("\"%1%\" is disabled because \"%2%\" is on in \"%3%\" category.\n"
+ "To enable \"%1%\", please switch off \"%2%\""))
+ % _L("Object elevation") % _L("Pad around object") % _L("Pad")).str()));
+ }
+ }
+ }
+}
+
+void TabSLAPrint::toggle_options()
+{
+ if (m_active_page)
+ m_config_manipulation.toggle_print_sla_options(m_config);
+}
+
void TabSLAPrint::update()
{
if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptFFF)
@@ -3759,10 +4185,14 @@ void TabSLAPrint::update()
m_update_cnt++;
m_config_manipulation.update_print_sla_config(m_config, true);
+
+ update_description_lines();
+ Layout();
+
m_update_cnt--;
if (m_update_cnt == 0) {
- m_config_manipulation.toggle_print_sla_options(m_config);
+ toggle_options();
// update() could be called during undo/redo execution
// Update of objectList can cause a crash in this case (because m_objects doesn't match ObjectList)
@@ -3773,6 +4203,13 @@ void TabSLAPrint::update()
}
}
+void TabSLAPrint::clear_pages()
+{
+ Tab::clear_pages();
+
+ m_support_object_elevation_description_line = nullptr;
+}
+
ConfigManipulation Tab::get_config_manipulation()
{
auto load_config = [this]()
@@ -3783,15 +4220,15 @@ ConfigManipulation Tab::get_config_manipulation()
update();
};
- auto get_field_ = [this](const t_config_option_key& opt_key, int opt_index) {
- return get_field(opt_key, opt_index);
+ auto cb_toggle_field = [this](const t_config_option_key& opt_key, bool toggle, int opt_index) {
+ return toggle_option(opt_key, toggle, opt_index);
};
auto cb_value_change = [this](const std::string& opt_key, const boost::any& value) {
return on_value_change(opt_key, value);
};
- return ConfigManipulation(load_config, get_field_, cb_value_change);
+ return ConfigManipulation(load_config, cb_toggle_field, cb_value_change);
}