diff --git a/resources/ui_layout/default/freq_fff.ui b/resources/ui_layout/default/freq_fff.ui index fcf53c32c19..d80283f490e 100644 --- a/resources/ui_layout/default/freq_fff.ui +++ b/resources/ui_layout/default/freq_fff.ui @@ -1,5 +1,5 @@ #logs -page:print: +page:Frequent settings: group:freq_settings_event:no_title:no_search: line: setting:simple:script:enum$none$None$bp$Support on build plate only$se$For support enforcers only$ev$Everywhere:depends$support_material$support_material_auto$support_material_buildplate_only:label$Supports:tooltip$Select what kind of support do you need:full_width:s_support_fff diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 2f663166cc5..f3b090fe97f 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -3441,7 +3441,7 @@ LayerResult GCode::process_layer( //extrude object-only skirt (for sequential) //TODO: use it also for wiping like the other one (as they are exlusiev) if (single_object_instance_idx != size_t(-1) && !layers.front().object()->skirt().empty() - && extruder_id == layer_tools.extruders.front()) { + && extruder_id == layer_tools.extruders.front() && object_layer) { const PrintObject *print_object = layers.front().object(); //object skirt & brim use the object settings. @@ -3459,7 +3459,7 @@ LayerResult GCode::process_layer( } //extrude object-only brim (for sequential) if (single_object_instance_idx != size_t(-1) && !layers.front().object()->brim().empty() - && extruder_id == layer_tools.extruders.front()) { + && extruder_id == layer_tools.extruders.front() && object_layer) { const PrintObject* print_object = layers.front().object(); //object skirt & brim use the object settings. @@ -5114,9 +5114,15 @@ std::string GCode::extrude_multi_path(const ExtrusionMultiPath &multipath, const //reverse to get a shorter point (hopefully there is still no feature that choose a point that need no perimeter crossing before). // extrude along the reversedpath for (size_t idx_path = multipath.paths.size() - 1; idx_path < multipath.paths.size(); --idx_path) { - assert(multipath.paths[idx_path].can_reverse()); - //extrude_path will reverse the path by itself, no need to copy it do to it here. - gcode += extrude_path(multipath.paths[idx_path], description, speed); + //it's possible to have un-reverseable paths into a reversable multipath: this means that only the whole thing can be reversed, and not individual apths. + if (multipath.paths[idx_path].can_reverse()) { + // extrude_path will reverse the path by itself, no need to copy it do to it here. + gcode += extrude_path(multipath.paths[idx_path], description, speed); + } else { + ExtrusionPath path = multipath.paths[idx_path]; + path.reverse(); + gcode += extrude_path(path, description, speed); + } } } else { // extrude along the path @@ -6373,7 +6379,7 @@ Polyline GCode::travel_to(std::string &gcode, const Point &point, ExtrusionRole bool needs_retraction = this->needs_retraction(travel, role); if (m_config.only_retract_when_crossing_perimeters && !(m_config.enforce_retract_first_layer && m_layer_index == 0)) - needs_retraction = needs_retraction && this->can_cross_perimeter(travel, false); + needs_retraction = needs_retraction && this->can_cross_perimeter(travel, true); // Re-allow avoid_crossing_perimeters for the next travel moves m_avoid_crossing_perimeters.reset_once_modifiers(); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index d4661af775d..3af8dd5bea2 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -873,7 +873,7 @@ bool GUI_App::init_opengl() if (boost::contains(gpu_vendor, "Apple") || boost::contains(gpu_vendor, "APPLE")) { assert(false); // apple gpu are only in _M_ARM64 } - } catch (std::exception &ex) {} + } catch (std::exception &) {} #endif app_config->set_hardware_type(AppConfig::HardwareType(hard_cpu + hard_gpu)); } @@ -2652,7 +2652,7 @@ void GUI_App::add_config_menu(wxMenuBar *menu) associate_gcode_files(); } #endif // _WIN32 - } catch (std::exception &e) {} + } catch (std::exception &) {} } if (app_layout_changed) { // hide full main_sizer for mainFrame diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 9c492156c92..bb6d65c0886 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -686,7 +686,7 @@ void Preview::check_layers_slider_values(std::vector& ticks_f m_schedule_background_process(); } -void Preview::update_layers_slider(const std::vector& layers_z, bool keep_z_range) +void Preview::update_layers_slider(const std::vector& layers_z, bool show_gcode_data, bool keep_z_range) { //lock rendering while updating { @@ -708,7 +708,7 @@ void Preview::update_layers_slider(const std::vector& layers_z, bool kee // Detect and set manipulation mode for double slider update_layers_slider_mode(); - + Plater* plater = wxGetApp().plater(); CustomGCode::Info ticks_info_from_model = plater->model().custom_gcode_per_print_z; if (wxGetApp().is_editor()) @@ -742,46 +742,36 @@ void Preview::update_layers_slider(const std::vector& layers_z, bool kee } m_layers_slider->SetSelectionSpan(idx_low, idx_high); m_layers_slider->SetTicksValues(ticks_info_from_model); - - bool sla_print_technology = plater->printer_technology() == ptSLA; + bool sequential_print = wxGetApp().preset_bundle->fff_prints.get_edited_preset().config.opt_bool("complete_objects"); + bool sla_print_technology = plater->printer_technology() == ptSLA; m_layers_slider->SetDrawMode(sla_print_technology, sequential_print); - if (sla_print_technology) - m_layers_slider->SetLayersTimes(plater->sla_print().print_statistics().layers_times); - else { - if (plater->fff_print().print_statistics().is_computing_gcode || !plater->fff_print().finished()) { - //do not fetch uncomplete data - m_layers_slider->SetLayersTimes({}, 0); + if (show_gcode_data) { + if (sla_print_technology) { + m_layers_slider->SetLayersTimes(plater->sla_print().print_statistics().layers_times); } else { - auto print_mode_stat = m_gcode_result->print_statistics.modes.front(); - m_layers_slider->SetLayersTimes(print_mode_stat.layers_times, print_mode_stat.time); + if (plater->fff_print().print_statistics().is_computing_gcode || !plater->fff_print().finished()) { + // do not fetch uncomplete data + m_layers_slider->SetLayersTimes({}, 0); + } else { + auto print_mode_stat = m_gcode_result->print_statistics.modes.front(); + m_layers_slider->SetLayersTimes(print_mode_stat.layers_times, print_mode_stat.time); + } } - } // create area array - //area not computed for sla_print_technology //TODO - if (!sla_print_technology){ - if (plater->fff_print().print_statistics().is_computing_gcode || !plater->fff_print().finished()) { - //do not fetch uncomplete data - m_layers_slider->SetLayersAreas({}); - } else { - const std::vector> &layerz_to_area = plater->fff_print().print_statistics().layer_area_stats; - std::vector areas; - for(auto [z, area] : layerz_to_area) - areas.push_back(area); - m_layers_slider->SetLayersAreas(areas); - assert(areas.size() == m_gcode_result->print_statistics.modes.front().layers_times.size()); - //auto objects = plater->fff_print().objects(); - //for (auto object : objects) { - // for (auto layer : object->layers()) { - // assert(layer->print_z > 100); - // coord_t layer_z = 100*(coord_t(layer->print_z + 50)/100); - // int32_t area = layerz_to_area[layer_z]; - // for (auto poly : layer->lslices) { - // area += poly.area(); - // } - // layerz_to_area[layer_z] = area; - // } - //} + // area not computed for sla_print_technology //TODO + if (!sla_print_technology) { + if (plater->fff_print().print_statistics().is_computing_gcode || !plater->fff_print().finished()) { + // do not fetch uncomplete data + m_layers_slider->SetLayersAreas({}); + } else { + const std::vector> &layerz_to_area = + plater->fff_print().print_statistics().layer_area_stats; + std::vector areas; + for (auto [z, area] : layerz_to_area) areas.push_back(area); + m_layers_slider->SetLayersAreas(areas); + assert(areas.size() == m_gcode_result->print_statistics.modes.front().layers_times.size()); + } } } @@ -1066,6 +1056,7 @@ void Preview::load_print_as_fff(bool keep_z_range) m_canvas->set_items_show(true, true); m_canvas->set_selected_extruder(0); + bool gcode_not_extrusions = false; if (current_force_state == ForceState::ForceGcode || (gcode_preview_data_valid && current_force_state != ForceState::ForceExtrusions)) { // Load the real G-code preview. if (current_force_state == ForceState::NoForce) @@ -1077,6 +1068,7 @@ void Preview::load_print_as_fff(bool keep_z_range) Refresh(); zs = m_canvas->get_gcode_layers_zs(); m_loaded = true; + gcode_not_extrusions = true; } else if (wxGetApp().is_editor()) { // Load the initial preview based on slices, not the final G-code. @@ -1087,6 +1079,7 @@ void Preview::load_print_as_fff(bool keep_z_range) m_left_sizer->Layout(); Refresh(); zs = m_canvas->get_volumes_print_zs(true); + gcode_not_extrusions = false; } if (!zs.empty() && !m_keep_current_preview_type) { @@ -1116,7 +1109,7 @@ void Preview::load_print_as_fff(bool keep_z_range) hide_layers_slider(); m_canvas_widget->Refresh(); } else { - update_layers_slider(zs, keep_z_range); + update_layers_slider(zs, gcode_not_extrusions, keep_z_range); } } } @@ -1163,7 +1156,7 @@ void Preview::load_print_as_sla() Refresh(); if (n_layers > 0) - update_layers_slider(zs); + update_layers_slider(zs, true); m_loaded = true; } diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index 3bc93bb9aee..f9535f0aadb 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -214,7 +214,7 @@ Preview(wxWindow* parent, Bed3D& bed, Model* model, DynamicPrintConfig* config, void check_layers_slider_values(std::vector& ticks_from_model, const std::vector& layers_z); void reset_layers_slider(); - void update_layers_slider(const std::vector& layers_z, bool keep_z_range = false); + void update_layers_slider(const std::vector& layers_z, bool show_gcode_data = false, bool keep_z_range = false); void update_layers_slider_mode(); // update vertical DoubleSlider after keyDown in canvas void update_layers_slider_from_canvas(wxKeyEvent& event); diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index facaefc6734..b2cdbb82276 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -126,11 +126,14 @@ OptionsGroup::OptionsGroup( wxWindow* _parent, const wxString& title, m_use_custom_ctrl(is_tab_opt), staticbox(title!=""), extra_column(extra_clmn) { + assert(Tab::fake_build || m_parent); } wxWindow* OptionsGroup::ctrl_parent() const { - return this->custom_ctrl && m_use_custom_ctrl_as_parent ? static_cast(this->custom_ctrl) : (this->stb ? static_cast(this->stb) : this->parent()); + wxWindow* ret_val = this->custom_ctrl && m_use_custom_ctrl_as_parent ? static_cast(this->custom_ctrl) : (this->stb ? static_cast(this->stb) : this->parent()); + assert(ret_val); + return ret_val; } bool OptionsGroup::is_legend_line() @@ -190,7 +193,7 @@ void OptionsGroup::show_field(const t_config_option_key& opt_key, bool show/* = void OptionsGroup::append_line(const Line& line) { - m_lines.emplace_back(line); + m_lines.push_back(line); if (line.full_width && ( line.widget != nullptr || diff --git a/src/slic3r/GUI/OptionsGroup.hpp b/src/slic3r/GUI/OptionsGroup.hpp index 56de96f7dcb..e0a0252d02d 100644 --- a/src/slic3r/GUI/OptionsGroup.hpp +++ b/src/slic3r/GUI/OptionsGroup.hpp @@ -135,7 +135,7 @@ class OptionsGroup { /// Returns a copy of the pointer of the parent wxWindow. /// Accessor function is because users are not allowed to change the parent /// but defining it as const means a lot of const_casts to deal with wx functions. - inline wxWindow* parent() const { return m_parent; } + inline wxWindow* parent() const { assert(m_parent); return m_parent; } wxWindow* ctrl_parent() const; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index e28ded9cdbd..f95f146b174 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -343,7 +343,7 @@ class FreqChangedParams : public OG_Settings void FreqChangedParams::msw_rescale() { - m_og->msw_rescale(); + if(m_og) m_og->msw_rescale(); for(auto& entry : m_og_other) entry.second->msw_rescale(); @@ -353,7 +353,7 @@ void FreqChangedParams::msw_rescale() void FreqChangedParams::sys_color_changed() { - m_og->sys_color_changed(); + if(m_og) m_og->sys_color_changed(); for (auto& entry : m_og_other) entry.second->sys_color_changed(); @@ -389,16 +389,17 @@ void FreqChangedParams::init() assert(tab_freq_fff == nullptr || dynamic_cast(tab_freq_fff)); if (tab_freq_fff && dynamic_cast(tab_freq_fff)) { - // std::vector pages; + static_cast(tab_freq_fff)->set_freq_parent(m_og->parent()); tab_freq_fff->build(); - // if(tab_freq_fff != nullptr) pages = - // tab_freq_fff->create_pages(Preset::type_name(tab_freq_fff->type())+".ui", -1, tab_freq_fff->type()); if (tab_freq_fff->get_page_count() > 0) { + assert(tab_freq_fff->get_page_count() == 1); + assert(tab_freq_fff->get_page(0)); + assert(tab_freq_fff->get_page(0)->m_optgroups.size() == 1); + m_og = (tab_freq_fff->get_page(0)->m_optgroups[0]); m_og->set_config(config); m_og->hide_labels(); m_og->m_on_change = Tab::set_or_add(m_og->m_on_change, [tab_freq_fff, this](t_config_option_key opt_key, boost::any value) - // m_og->m_on_change = [tab_print, this](t_config_option_key opt_key, boost::any value) { const Option *opt_def = this->m_og->get_option_def(opt_key); if (opt_def && !opt_def->opt.is_script) { @@ -470,10 +471,9 @@ void FreqChangedParams::init() line_for_purge->append_widget(wiping_dialog_btn); } - for (const Line &l : page->m_optgroups[0]->get_lines()) { m_og->append_line(l); } - // current_group->m_on_change = on_change; m_og->activate(); + assert(m_og->sizer); m_sizer->Add(m_og->sizer, 0, wxEXPAND); } } @@ -483,12 +483,14 @@ void FreqChangedParams::init() Tab* tab_freq_sla = wxGetApp().get_tab(Preset::TYPE_FREQUENT_SLA, false); assert(tab_freq_sla == nullptr || dynamic_cast(tab_freq_sla)); if (tab_freq_sla && dynamic_cast(tab_freq_sla)) { + static_cast(tab_freq_sla)->set_freq_parent(m_parent); tab_freq_sla->build(); - // if (tab_freq_sla != nullptr) pages = - // tab_freq_sla->create_pages(Preset::type_name(tab_freq_sla->type())+".ui", -1, tab_freq_sla->type()); if (tab_freq_sla->get_page_count() > 0) { + assert(tab_freq_fff->get_page_count() == 1); + assert(tab_freq_fff->get_page(0)); + assert(tab_freq_fff->get_page(0)->m_optgroups.size() == 1); std::shared_ptr m_og_sla = m_og_other[ptSLA] = - std::make_shared(m_parent, ""); + (tab_freq_sla->get_page(0)->m_optgroups[0]); m_og_sla->set_config(config); m_og_sla->hide_labels(); m_og_sla->m_on_change = Tab::set_or_add(m_og_sla->m_on_change, [tab_freq_sla, @@ -512,8 +514,8 @@ void FreqChangedParams::init() l.append_widget(empty_widget); } } - for (const Line &l : page->m_optgroups[0]->get_lines()) { m_og_sla->append_line(l); } m_og_sla->activate(); + assert(m_og_sla->sizer); m_sizer->Add(m_og_sla->sizer, 0, wxEXPAND); } } @@ -533,7 +535,7 @@ void FreqChangedParams::Show(bool visible) { void FreqChangedParams::Show(PrinterTechnology tech) { - m_og->Show( (tech & PrinterTechnology::ptFFF) != 0); + if(m_og) m_og->Show( (tech & PrinterTechnology::ptFFF) != 0); for (auto& entry : m_og_other) entry.second->Show( (entry.first & tech) != 0); @@ -1155,7 +1157,7 @@ void Sidebar::jump_to_option(size_t selected) } } - wxGetApp().get_tab(opt.type)->activate_option(opt.opt_key_with_idx(), boost::nowide::narrow(opt.category)); + wxGetApp().get_tab(opt.type, false)->activate_option(opt.opt_key_with_idx(), boost::nowide::narrow(opt.category)); // Switch to the Settings NotePad // wxGetApp().mainframe->select_tab(MainFrame::ETabType::LastSettings); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index da99d32c599..c16edfe4dd5 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -467,33 +467,42 @@ void Tab::load_initial_data() m_tt_non_system_script = has_parent ? &m_tt_value_unlock_script : &m_ttg_white_bullet_ns; } -Slic3r::GUI::PageShp Tab::create_options_page(const wxString& title, const std::string& icon) +int Tab::get_icon_id(const wxString& title, const std::string& icon) { // Index of icon in an icon list $self->{icons}. - auto icon_idx = 0; + int icon_idx = 0; if (!icon.empty()) { icon_idx = (m_icon_index.find(icon) == m_icon_index.end()) ? -1 : m_icon_index.at(icon); if (icon_idx == -1 && m_icons) { // Add a new icon to the icon list. m_scaled_icons_list.push_back(ScalableBitmap(this, icon)); m_icons->Add(m_scaled_icons_list.back().bmp()); - icon_idx = ++m_icon_count; + 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; + } } - } + return icon_idx; +} + +Slic3r::GUI::PageShp Tab::create_options_page(const wxString& title, const std::string& icon) +{ + assert((this->type() & Preset::Type::TYPE_FREQUENT) == 0); + assert(Tab::fake_build || m_page_view); // Initialize the page. - PageShp page(new Page(this, m_page_view, title, icon_idx)); -// page->SetBackgroundStyle(wxBG_STYLE_SYSTEM); -#ifdef __WINDOWS__ -// page->SetDoubleBuffered(true); -#endif //__WINDOWS__ + PageShp page(new Page(this, m_page_view, title, get_icon_id(title, icon))); + return page; +} - //page->set_config(m_config); +Slic3r::GUI::PageShp TabFrequent::create_options_page(const wxString &title, const std::string &icon) { + assert(!m_page_view); + assert(m_freq_parent); + // Initialize the page. + PageShp page(new Page(this, m_freq_parent, title, get_icon_id(title, icon))); return page; } @@ -1247,12 +1256,12 @@ Field* Tab::get_field(const t_config_option_key& opt_key, int opt_index/* = -1*/ std::pair Tab::get_custom_ctrl_with_blinking_ptr(const t_config_option_key& opt_key, int opt_index/* = -1*/) { - if (!m_active_page) + if (!m_active_page && m_pages.empty()) return {nullptr, nullptr}; std::pair ret = {nullptr, nullptr}; - for (auto opt_group : m_active_page->m_optgroups) { + for (auto opt_group : m_active_page ? m_active_page->m_optgroups : m_pages.front()->m_optgroups) { ret = opt_group->get_custom_ctrl_with_blinking_ptr(opt_key, opt_index); if (ret.first && ret.second) break; @@ -1508,6 +1517,14 @@ void Tab::activate_option(const std::string& opt_key, const wxString& category) m_highlighter.init(get_custom_ctrl_with_blinking_ptr(opt_key)); } +void TabFrequent::activate_option(const std::string &opt_key, const wxString &category){ + wxGetApp().plater()->collapse_sidebar(false); + wxGetApp().mainframe->select_tab(MainFrame::ETabType::Plater3D); + // no act btns -> no blink arrow + //std::pair ctrl = get_custom_ctrl_with_blinking_ptr(opt_key); + //m_highlighter.init(ctrl); +} + void Tab::cache_config_diff(const std::vector& selected_options) { m_cache_config.apply_only(m_presets->get_edited_preset().config, selected_options); @@ -1807,7 +1824,7 @@ std::vector Tab::create_pages(std::string setting_type_nam } if(logs) Slic3r::slic3r_log->info("settings gui") << "create page " << label.c_str() <<" : "<< params[params.size() - 1] << "\n"; - pages.push_back(create_options_page(label, params[params.size() - 1])); + pages.push_back(this->create_options_page(label, params[params.size() - 1])); current_page = pages.back(); } else if (boost::starts_with(full_line, "end_page")) @@ -3185,13 +3202,16 @@ void TabPrinter::init() // For DiffPresetDialog we use options list which is saved in Searcher class. // Options for the Searcher is added in the moment of pages creation. - // So, build first of all printer pages for non-selected printer technology... + // So, fake-build first of all printer pages for non-selected printer technology... + // //FIXME: split into PRINTERSLA and PRINTERFFF + Tab::fake_build = true; std::string def_preset_name = "- default " + std::string(m_printer_technology == ptSLA ? "FFF" : "SLA") + " -"; m_config = &m_presets->find_preset(def_preset_name)->config; m_config_base = m_config; m_printer_technology != ptSLA ? build_sla() : build_fff(); if (m_printer_technology == ptSLA) m_extruders_count_old = 0;// revert this value + Tab::fake_build = false; // ... and than for selected printer technology load_initial_data(); diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 29d587c479f..95df5c82cb1 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -122,7 +122,7 @@ class Page// : public wxScrolledWindow //DynamicPrintConfig* m_config; wxBoxSizer* vsizer() const { return m_vsizer; } - wxWindow* parent() const { return m_parent; } + wxWindow* parent() const { assert(m_parent); return m_parent; } const wxString& title() const { return m_title; } size_t iconID() const { return m_iconID; } //void set_config(DynamicPrintConfig* config_in) { m_config = config_in; } @@ -384,6 +384,7 @@ class Tab: public wxPanel // 3. propagate changed configuration to the Plater when (m_update_cnt == 0) only std::atomic_int16_t m_update_cnt = 0; + static inline bool fake_build = false; public: Tab(wxBookCtrlBase* parent, const wxString& title, Preset::Type type); ~Tab() {} @@ -433,10 +434,12 @@ class Tab: public wxPanel void update_undo_buttons(); void on_roll_back_value(const bool to_sys = false); - - PageShp create_options_page(const wxString& title, const std::string& icon); + + int get_icon_id(const wxString& title, const std::string &icon); + virtual PageShp create_options_page(const wxString &title, const std::string &icon); static wxString translate_category(const wxString& title, Preset::Type preset_type); + virtual void OnActivate(); virtual void on_preset_loaded() {} virtual void init() = 0; @@ -475,7 +478,7 @@ class Tab: public wxPanel void on_value_change(const std::string& opt_key, const boost::any& value); void update_wiping_button_visibility(); - void activate_option(const std::string& opt_key, const wxString& category); + virtual void activate_option(const std::string& opt_key, const wxString& category); void cache_config_diff(const std::vector& selected_options); void apply_config_from_cache(); @@ -510,6 +513,7 @@ class Tab: public wxPanel class TabFrequent : public Tab { MultiPtrPrintConfig m_multi_conf; + wxWindow * m_freq_parent = nullptr; public: TabFrequent(wxBookCtrlBase* parent, const wxString &title, Preset::Type tab_type) : Tab(parent, title, tab_type) {} @@ -524,6 +528,9 @@ class TabFrequent : public Tab PrinterTechnology get_printer_technology() const override { return (m_type & Preset::Type::TYPE_TECHNOLOGY) == Preset::Type::TYPE_FFF ? PrinterTechnology::ptFFF : (m_type & Preset::Type::TYPE_TECHNOLOGY) == Preset::Type::TYPE_SLA ? PrinterTechnology::ptSLA : PrinterTechnology::ptAny; } + virtual void activate_option(const std::string& opt_key, const wxString& category) override; + void set_freq_parent(wxWindow * freq_parent) { m_freq_parent = freq_parent;} + virtual PageShp create_options_page(const wxString &title, const std::string &icon) override; }; class TabPrint : public Tab