diff options
author | David Kocik <kocikdav@gmail.com> | 2022-03-23 14:31:09 +0300 |
---|---|---|
committer | David Kocik <kocikdav@gmail.com> | 2022-04-14 13:53:26 +0300 |
commit | 21f2c68b65080e5cd0242b611cc7f5a393727e56 (patch) | |
tree | 0af7e894f86b8c1c45efa2d0d47b0bf057e39cd7 | |
parent | 09512c086ba3306538f93c1909933ebb5c772e09 (diff) |
User filament cost parameter transfering via aliases with saving to app config.dk_cost
Currency shortcut in preferences.
-rw-r--r-- | src/libslic3r/AppConfig.cpp | 3 | ||||
-rw-r--r-- | src/libslic3r/PresetBundle.cpp | 15 | ||||
-rw-r--r-- | src/libslic3r/PresetBundle.hpp | 5 | ||||
-rw-r--r-- | src/libslic3r/PrintConfig.cpp | 2 | ||||
-rw-r--r-- | src/slic3r/GUI/GUI.cpp | 15 | ||||
-rw-r--r-- | src/slic3r/GUI/GUI.hpp | 3 | ||||
-rw-r--r-- | src/slic3r/GUI/GUI_App.cpp | 3 | ||||
-rw-r--r-- | src/slic3r/GUI/MainFrame.cpp | 25 | ||||
-rw-r--r-- | src/slic3r/GUI/MainFrame.hpp | 3 | ||||
-rw-r--r-- | src/slic3r/GUI/OG_CustomCtrl.cpp | 12 | ||||
-rw-r--r-- | src/slic3r/GUI/OG_CustomCtrl.hpp | 5 | ||||
-rw-r--r-- | src/slic3r/GUI/OptionsGroup.cpp | 4 | ||||
-rw-r--r-- | src/slic3r/GUI/OptionsGroup.hpp | 1 | ||||
-rw-r--r-- | src/slic3r/GUI/Plater.cpp | 4 | ||||
-rw-r--r-- | src/slic3r/GUI/Preferences.cpp | 36 | ||||
-rw-r--r-- | src/slic3r/GUI/Search.cpp | 18 | ||||
-rw-r--r-- | src/slic3r/GUI/Search.hpp | 3 | ||||
-rw-r--r-- | src/slic3r/GUI/Tab.cpp | 231 | ||||
-rw-r--r-- | src/slic3r/GUI/Tab.hpp | 4 |
19 files changed, 371 insertions, 21 deletions
diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp index 928febffd..8ff91e623 100644 --- a/src/libslic3r/AppConfig.cpp +++ b/src/libslic3r/AppConfig.cpp @@ -189,6 +189,9 @@ void AppConfig::set_defaults() if (get("allow_ip_resolve").empty()) set("allow_ip_resolve", "1"); + if (get("currency_shortcut").empty()) + set("currency_shortcut", "money"); + #ifdef _WIN32 if (get("use_legacy_3DConnexion").empty()) set("use_legacy_3DConnexion", "0"); diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index 85bcd69ba..164c7707c 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -5,6 +5,7 @@ #include "Utils.hpp" #include "Model.hpp" #include "format.hpp" +#include "AppConfig.hpp" #include <algorithm> #include <set> @@ -714,6 +715,20 @@ DynamicPrintConfig PresetBundle::full_fff_config() const out.option<ConfigOptionStrings>("filament_settings_id", true)->values = this->filament_presets; out.option<ConfigOptionString >("printer_settings_id", true)->value = this->printers.get_selected_preset_name(); out.option<ConfigOptionString >("physical_printer_settings_id", true)->value = this->physical_printers.get_selected_printer_name(); + + // real filament cost loads from appconfig and is same for each alias of profile + if (app_config) { + // system profile - read cost from appconfig cost_override / alias + std::string real_cost; + if (this->filaments.get_selected_preset().is_system) + real_cost = app_config->get("cost_override", this->filaments.get_selected_preset().alias); + // system inherited profile - read if "Enabled" in cost_override / name than cost from cost_override / alias of parent + else if (this->filaments.get_selected_preset_parent()->is_system && app_config->get("cost_override", this->filaments.get_selected_preset().name) == "Enabled") + real_cost = app_config->get("cost_override", this->filaments.get_selected_preset_parent()->alias); + + if (!real_cost.empty() && real_cost != "0"; float cost_f = std::atof(real_cost.c_str())) + out.option<ConfigOptionFloats>("filament_cost")->values.at(0) = cost_f; + } // Serialize the collected "compatible_printers_condition" and "inherits" fields. // There will be 1 + num_exturders fields for "inherits" and 2 + num_extruders for "compatible_printers_condition" stored. diff --git a/src/libslic3r/PresetBundle.hpp b/src/libslic3r/PresetBundle.hpp index 2a5ce6839..93c9840c0 100644 --- a/src/libslic3r/PresetBundle.hpp +++ b/src/libslic3r/PresetBundle.hpp @@ -11,6 +11,8 @@ namespace Slic3r { +class AppConfig; + // Bundle of Print + Filament + Printer presets. class PresetBundle { @@ -19,6 +21,9 @@ public: PresetBundle(const PresetBundle &rhs); PresetBundle& operator=(const PresetBundle &rhs); + // appconfig is needed for real_filament_cost values. + AppConfig* app_config { nullptr }; + // Remove all the presets but the "-- default --". // Optionally remove all the files referenced by the presets from the user profile directory. void reset(bool delete_files); diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index b21ed5631..02c84cba6 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -1056,6 +1056,8 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionBools { false }); + // we need to get currency shortcut from appconfig but its not initialized yet + // so the money/kg is just placeholder def = this->add("filament_cost", coFloats); def->label = L("Cost"); def->tooltip = L("Enter your filament cost per kg here. This is only for statistical information."); diff --git a/src/slic3r/GUI/GUI.cpp b/src/slic3r/GUI/GUI.cpp index 5886be028..921975655 100644 --- a/src/slic3r/GUI/GUI.cpp +++ b/src/slic3r/GUI/GUI.cpp @@ -24,13 +24,13 @@ #include "AboutDialog.hpp" #include "MsgDialog.hpp" #include "format.hpp" +#include "Field.hpp" +#include "Tab.hpp" +#include "libslic3r/AppConfig.hpp" #include "libslic3r/Print.hpp" namespace Slic3r { - -class AppConfig; - namespace GUI { #if __APPLE__ @@ -444,6 +444,15 @@ AppConfig* get_app_config() return wxGetApp().app_config; } +Preset& get_edited_preset(Preset::Type type) +{ + return wxGetApp().get_tab(type)->m_presets->get_edited_preset(); +} +const Preset& get_edited_preset_const(Preset::Type type) +{ + return wxGetApp().get_tab(type)->m_presets->get_edited_preset(); +} + wxString from_u8(const std::string &str) { return wxString::FromUTF8(str.c_str()); diff --git a/src/slic3r/GUI/GUI.hpp b/src/slic3r/GUI/GUI.hpp index cb7cf5487..1f3d2175e 100644 --- a/src/slic3r/GUI/GUI.hpp +++ b/src/slic3r/GUI/GUI.hpp @@ -35,6 +35,9 @@ extern const std::string& shortkey_alt_prefix(); extern AppConfig* get_app_config(); + Preset& get_edited_preset(Preset::Type type); + const Preset& get_edited_preset_const(Preset::Type type); + extern void add_menus(wxMenuBar *menu, int event_preferences_changed, int event_language_change); // Change option value in config diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 76f321d89..8c53a487b 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -1193,6 +1193,9 @@ bool GUI_App::on_init_inner() preset_bundle = new PresetBundle(); + if(app_config) + preset_bundle->app_config = app_config; + // just checking for existence of Slic3r::data_dir is not enough : it may be an empty directory // supplied as argument to --datadir; in that case we should still run the wizard preset_bundle->setup_directories(); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index af285e46e..f22c77e3d 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -1604,6 +1604,31 @@ void MainFrame::update_menubar() m_changeable_menu_items[miMaterialTab] ->SetBitmap(create_menu_bitmap(is_fff ? "spool" : "resin")); m_changeable_menu_items[miPrinterTab] ->SetBitmap(create_menu_bitmap(is_fff ? "printer" : "sla_printer")); + + +} + +void MainFrame::update_line_sidetext(size_t page, const std::string& line_name, const std::string& sidetext) +{ + if (Tab* tab = dynamic_cast<Tab*>(m_tabpanel->GetPage(page))) { + if (Line* line = tab->get_line(line_name)) { + line->get_options()[0].opt.sidetext = sidetext; + tab->update_dirty(); + } + } +} + +void MainFrame::update_widget_sidetext(size_t page, const std::string& line_name, const std::string& sidetext) +{ + if (Tab* tab = dynamic_cast<Tab*>(m_tabpanel->GetPage(page))) { + if (Line* line = tab->get_line(line_name)) { + if (line->widget_sizer && line->widget_sizer->GetItemCount() > 1) { + wxSizerItem* item = line->widget_sizer->GetItem(1); // sidetext should be second item in sizer + if (wxStaticText* text = dynamic_cast<wxStaticText*>(item->GetWindow())) + text->SetLabel(sidetext); + } + } + } } #if 0 diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index f385ee8f8..3a3922dc9 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -161,6 +161,9 @@ public: void update_menubar(); // Open item in menu by menu and item name (in actual language) void open_menubar_item(const wxString& menu_name,const wxString& item_name); + + void update_line_sidetext(size_t page, const std::string& line_name, const std::string& sidetext); + void update_widget_sidetext(size_t page, const std::string& line_name, const std::string& sidetext); #ifdef _WIN32 void show_tabs_menu(bool show); #endif diff --git a/src/slic3r/GUI/OG_CustomCtrl.cpp b/src/slic3r/GUI/OG_CustomCtrl.cpp index 400db751a..0dd59d9b3 100644 --- a/src/slic3r/GUI/OG_CustomCtrl.cpp +++ b/src/slic3r/GUI/OG_CustomCtrl.cpp @@ -105,6 +105,16 @@ int OG_CustomCtrl::get_height(const Line& line) return 0; } +void OG_CustomCtrl::force_hidden(const Line& line, bool hidden) +{ + for (CtrlLine& ctrl_line : ctrl_lines) { + if (&ctrl_line.og_line == &line) { + ctrl_line.is_forced_hidden = hidden; + break; + } + } +} + wxPoint OG_CustomCtrl::get_pos(const Line& line, Field* field_in/* = nullptr*/) { wxCoord v_pos = 0; @@ -514,7 +524,7 @@ void OG_CustomCtrl::CtrlLine::update_visibility(ConfigOptionMode mode) const std::vector<Option>& option_set = og_line.get_options(); const ConfigOptionMode& line_mode = option_set.front().opt.mode; - is_visible = line_mode <= mode; + is_visible = (!is_forced_hidden) && line_mode <= mode; if (draw_just_act_buttons) return; diff --git a/src/slic3r/GUI/OG_CustomCtrl.hpp b/src/slic3r/GUI/OG_CustomCtrl.hpp index c15132fec..5817c2ec7 100644 --- a/src/slic3r/GUI/OG_CustomCtrl.hpp +++ b/src/slic3r/GUI/OG_CustomCtrl.hpp @@ -43,6 +43,7 @@ class OG_CustomCtrl :public wxPanel bool draw_just_act_buttons { false }; bool draw_mode_bitmap { true }; bool is_visible { true }; + bool is_forced_hidden { false }; bool is_focused { false }; CtrlLine( wxCoord height, @@ -57,7 +58,7 @@ class OG_CustomCtrl :public wxPanel void msw_rescale(); void update_visibility(ConfigOptionMode mode); - void render_separator(wxDC& dc, wxCoord v_pos); + void render_separator(wxDC& dc, wxCoord v_pos); void render(wxDC& dc, wxCoord v_pos); wxCoord draw_mode_bmp(wxDC& dc, wxCoord v_pos); @@ -102,6 +103,8 @@ public: wxPoint get_pos(const Line& line, Field* field = nullptr); int get_height(const Line& line); + void force_hidden(const Line& line, bool hidden); + OptionsGroup* opt_group; }; diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index a861f478f..7f5e1d755 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -817,7 +817,6 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config boost::any ret; wxString text_value = wxString(""); const ConfigOptionDef* opt = config.def()->get(opt_key); - if (opt->nullable) { switch (opt->type) @@ -872,7 +871,7 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config ret = double_to_string(val); } break; - case coString: + case coString: ret = from_u8(config.opt_string(opt_key)); break; case coStrings: @@ -958,7 +957,6 @@ std::pair<OG_CustomCtrl*, bool*> ConfigOptionsGroup::get_custom_ctrl_with_blinki // Change an option on m_config, possibly call ModelConfig::touch(). void ConfigOptionsGroup::change_opt_value(const t_config_option_key& opt_key, const boost::any& value, int opt_index /*= 0*/) - { Slic3r::GUI::change_opt_value(const_cast<DynamicPrintConfig&>(*m_config), opt_key, value, opt_index); if (m_modelconfig) diff --git a/src/slic3r/GUI/OptionsGroup.hpp b/src/slic3r/GUI/OptionsGroup.hpp index f3efd0680..ab220c972 100644 --- a/src/slic3r/GUI/OptionsGroup.hpp +++ b/src/slic3r/GUI/OptionsGroup.hpp @@ -84,6 +84,7 @@ public: const std::vector<widget_t>& get_extra_widgets() const {return m_extra_widgets;} const std::vector<Option>& get_options() const { return m_options; } + std::vector<Option>& get_options() { return m_options; } private: std::vector<Option> m_options;//! {std::vector<Option>()}; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 457b434d0..1d975ead7 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1416,7 +1416,7 @@ void Sidebar::update_sliced_info_sizer() p->sliced_info->SetTextAndShow(siFilament_g, info_text, new_label); } - new_label = _L("Cost"); + new_label = format(("%1% (%2%)"), _L("Cost"), wxGetApp().app_config->get("currency_shortcut")); if (is_wipe_tower) new_label += format_wxstr(":\n - %1%\n - %2%", _L("objects"), _L("wipe tower")); @@ -3185,6 +3185,8 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool update_print_volume_state(); // Apply new config to the possibly running background task. bool was_running = background_process.running(); + if (!wxGetApp().preset_bundle->app_config) + wxGetApp().preset_bundle->app_config = wxGetApp().app_config; Print::ApplyStatus invalidated = background_process.apply(q->model(), wxGetApp().preset_bundle->full_config()); // Just redraw the 3D canvas without reloading the scene to consume the update of the layer height profile. diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index 75c5c116f..398e9d81e 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -9,6 +9,8 @@ #include "Notebook.hpp" #include "ButtonsDescription.hpp" #include "OG_CustomCtrl.hpp" +#include "MainFrame.hpp" +#include "format.hpp" namespace Slic3r { @@ -69,7 +71,7 @@ void PreferencesDialog::show(const std::string& highlight_opt_key /*= std::strin this->ShowModal(); } -static std::shared_ptr<ConfigOptionsGroup>create_options_tab(const wxString& title, wxBookCtrlBase* tabs) +static std::shared_ptr<ConfigOptionsGroup> create_options_tab(const wxString& title, wxBookCtrlBase* tabs) { wxPanel* tab = new wxPanel(tabs, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL); tabs->AddPage(tab, _(title)); @@ -115,6 +117,25 @@ static void append_bool_option( std::shared_ptr<ConfigOptionsGroup> optgroup, wxGetApp().sidebar().get_searcher().add_key(opt_key, Preset::TYPE_PREFERENCES, optgroup->config_category(), L("Preferences")); } +static void append_string_option(std::shared_ptr<ConfigOptionsGroup> optgroup, + const std::string& opt_key, + const std::string& label, + const std::string& tooltip, + const std::string& def_val, + ConfigOptionMode mode = comSimple) +{ + ConfigOptionDef def = { opt_key, coString }; + def.label = label; + def.tooltip = tooltip; + def.mode = mode; + def.set_default_value(new ConfigOptionString{ def_val }); + Option option(def, opt_key); + optgroup->append_single_option_line(option); + + // fill data to the Search Dialog + wxGetApp().sidebar().get_searcher().add_key(opt_key, Preset::TYPE_PREFERENCES, optgroup->config_category(), L("Preferences")); +} + static void append_enum_option( std::shared_ptr<ConfigOptionsGroup> optgroup, const std::string& opt_key, const std::string& label, @@ -177,7 +198,11 @@ void PreferencesDialog::build() m_values[opt_key] = boost::any_cast<bool>(value) ? "none" : "discard"; else if (opt_key == "default_action_on_dirty_project") m_values[opt_key] = boost::any_cast<bool>(value) ? "" : "0"; - else + else if (opt_key == "currency_shortcut") { + m_values[opt_key] = boost::any_cast<std::string>(value); + wxGetApp().mainframe->update_line_sidetext(2, "filament_cost", format("%1%/kg", boost::any_cast<std::string>(value))); + wxGetApp().mainframe->update_widget_sidetext(2, "alias_filament_cost", format("%1%/kg", boost::any_cast<std::string>(value))); + } else m_values[opt_key] = boost::any_cast<bool>(value) ? "1" : "0"; }; @@ -330,6 +355,13 @@ void PreferencesDialog::build() app_config->get("use_legacy_3DConnexion") == "1"); #endif // _WIN32 || __APPLE__ + + // Currency shortcut shown for filament_cost + append_string_option(m_optgroup_general, "currency_shortcut", + L("Currency shortcut"), + L("Currency used for filament cost."), + app_config->get("currency_shortcut")); + activate_options_tab(m_optgroup_general); // Add "Camera" tab diff --git a/src/slic3r/GUI/Search.cpp b/src/slic3r/GUI/Search.cpp index bdb2e55bf..163634764 100644 --- a/src/slic3r/GUI/Search.cpp +++ b/src/slic3r/GUI/Search.cpp @@ -305,7 +305,7 @@ void OptionsSearcher::init(std::vector<InputInfo> input_values) for (auto i : input_values) append_options(i.config, i.type, i.mode); - options.insert(options.end(), preferences_options.begin(), preferences_options.end()); + options.insert(options.end(), non_config_options.begin(), non_config_options.end()); sort_options(); @@ -328,9 +328,8 @@ void OptionsSearcher::apply(DynamicPrintConfig* config, Preset::Type type, Confi search(search_line, true); } -void OptionsSearcher::append_preferences_option(const GUI::Line& opt_line) +void OptionsSearcher::append_non_config_option(const GUI::Line& opt_line, Preset::Type type) { - Preset::Type type = Preset::TYPE_PREFERENCES; wxString label = opt_line.label; if (label.IsEmpty()) return; @@ -338,14 +337,19 @@ void OptionsSearcher::append_preferences_option(const GUI::Line& opt_line) std::string key = get_key(opt_line.get_options().front().opt_id, type); const GroupAndCategory& gc = groups_and_categories[key]; if (gc.group.IsEmpty() || gc.category.IsEmpty()) - return; - - preferences_options.emplace_back(Search::Option{ boost::nowide::widen(key), type, + return; + + non_config_options.emplace_back(Search::Option{ boost::nowide::widen(key), type, label.ToStdWstring(), _(label).ToStdWstring(), gc.group.ToStdWstring(), _(gc.group).ToStdWstring(), gc.category.ToStdWstring(), _(gc.category).ToStdWstring() }); } +void OptionsSearcher::append_preferences_option(const GUI::Line& opt_line) +{ + append_non_config_option(opt_line, Preset::TYPE_PREFERENCES); +} + void OptionsSearcher::append_preferences_options(const std::vector<GUI::Line>& opt_lines) { //Preset::Type type = Preset::TYPE_PREFERENCES; @@ -362,7 +366,7 @@ void OptionsSearcher::append_preferences_options(const std::vector<GUI::Line>& o //if (gc.group.IsEmpty() || gc.category.IsEmpty()) // continue; // - //preferences_options.emplace_back(Search::Option{ boost::nowide::widen(key), type, + //non_config_options.emplace_back(Search::Option{ boost::nowide::widen(key), type, // label.ToStdWstring(), _(label).ToStdWstring(), // gc.group.ToStdWstring(), _(gc.group).ToStdWstring(), // gc.category.ToStdWstring(), _(gc.category).ToStdWstring() }); diff --git a/src/slic3r/GUI/Search.hpp b/src/slic3r/GUI/Search.hpp index 47385e879..b56eea6e6 100644 --- a/src/slic3r/GUI/Search.hpp +++ b/src/slic3r/GUI/Search.hpp @@ -86,7 +86,7 @@ class OptionsSearcher PrinterTechnology printer_technology; std::vector<Option> options {}; - std::vector<Option> preferences_options {}; + std::vector<Option> non_config_options {}; std::vector<FoundOption> found {}; void append_options(DynamicPrintConfig* config, Preset::Type type, ConfigOptionMode mode); @@ -117,6 +117,7 @@ public: ConfigOptionMode mode); void append_preferences_option(const GUI::Line& opt_line); void append_preferences_options(const std::vector<GUI::Line>& opt_lines); + void append_non_config_option(const GUI::Line& opt_line, Preset::Type type); bool search(); bool search(const std::string& search, bool force = false); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index dc254d1af..278ed550d 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -597,6 +597,10 @@ void Tab::update_changed_ui() dirty_options.emplace_back("extruders_count"); if (tab->m_sys_extruders_count != tab->m_extruders_count) nonsys_options.emplace_back("extruders_count"); + } else if (m_type == Slic3r::Preset::TYPE_FILAMENT) { + // In case, this is called from load_current_preset, update_filament_cost_visibility will be called twice + // This second call wont break the previous one and will fix f.e. optgroup show / hide. + dynamic_cast<TabFilament*>(this)->update_filament_cost_visibility(); } for (auto& it : m_options_list) @@ -1925,7 +1929,9 @@ void TabFilament::build() 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"); + Option option = optgroup->get_option("filament_cost"); + option.opt.sidetext = format("%1%/kg", wxGetApp().app_config->get("currency_shortcut")); + optgroup->append_single_option_line(option); optgroup->append_single_option_line("filament_spool_weight"); optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value) @@ -1951,6 +1957,34 @@ void TabFilament::build() line.append_option(optgroup->get_option("bed_temperature")); optgroup->append_line(line); + optgroup = page->new_optgroup(L("User Cost")); + // system inherited profiles has checkbox to override - this info is written to appconfig + line = Line("override_cost", L("Override System Cost"), L("Allows to use User Cost with inherited from system profile.")); + line.widget = [this](wxWindow* parent) { + return create_override_cost_widget(parent); + }; + // Add key and append option. Both needs to be done here as this option is not in config. + wxGetApp().sidebar().get_searcher().add_key("override_cost", static_cast<Preset::Type>(optgroup->config_type()), optgroup->title, optgroup->config_category()); + wxGetApp().sidebar().get_searcher().append_non_config_option(line, Preset::Type::TYPE_FILAMENT); + optgroup->append_line(line); + // Next line is not affecting print config but app config + line = Line("alias_filament_cost", L("User Cost"), L("Current local price of filament, transfering to aliases. Overrides profile filament cost.")); + line.widget = [this](wxWindow* parent) { + return create_filament_cost_widget(parent); + }; + // Add key and append option. Both needs to be done here as this option is not in config. + wxGetApp().sidebar().get_searcher().add_key("alias_filament_cost", static_cast<Preset::Type>(optgroup->config_type()), optgroup->title, optgroup->config_category()); + wxGetApp().sidebar().get_searcher().append_non_config_option(line, Preset::Type::TYPE_FILAMENT); + optgroup->append_line(line); + // Description line + line = { "", "" }; + line.full_width = 1; + line.widget = [this](wxWindow* parent) { + return description_line_widget(parent, &m_alias_filament_cost_description_line); + }; + optgroup->append_line(line); + + page = add_options_page(L("Cooling"), "cooling"); std::string category_path = "cooling_127569#"; optgroup = page->new_optgroup(L("Enable")); @@ -1983,7 +2017,7 @@ void TabFilament::build() 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 = optgroup->get_option("filament_type"); option.opt.width = Field::def_width(); optgroup->append_single_option_line(option); optgroup->append_single_option_line("filament_soluble"); @@ -2107,6 +2141,104 @@ void TabFilament::update_volumetric_flow_preset_hints() m_volumetric_speed_description_line->SetText(text); } +wxSizer* TabFilament::create_filament_cost_widget(wxWindow* parent) +{ + auto size = wxSize(8 * m_em_unit, wxDefaultCoord); + wxTextCtrl* txtctrl = new wxTextCtrl(parent, wxID_ANY, "0", wxDefaultPosition, size, wxTE_PROCESS_ENTER | wxBORDER_SIMPLE); + + txtctrl->SetFont(Slic3r::GUI::wxGetApp().normal_font()); + wxGetApp().UpdateDarkUI(txtctrl); + if (!wxOSX) + // Only disable background refresh for single line input fields, as they are completely painted over by the edit control. + // This does not apply to the multi-line edit field, where the last line and a narrow frame around the text is not cleared. + txtctrl->SetBackgroundStyle(wxBG_STYLE_PAINT); +#ifdef __WXOSX__ + txtctrl->OSXDisableAllSmartSubstitutions(); +#endif // __WXOSX__ + + std::string real_cost = wxGetApp().app_config->get("cost_override", wxGetApp().preset_bundle->filaments.get_edited_preset().alias); + txtctrl->SetValue(real_cost.empty() ? wxString("0") : boost::nowide::widen(real_cost)); + + wxString tooltip = GUI::format_wxstr("%1%\n%2% : 0\n%3% : alias_filament_cost", + _L("Enter your filament cost per kg here. This is only for statistical information."), + _L("Default value"), + _L("parameter name")); + + txtctrl->SetToolTip(tooltip); + + txtctrl->Bind(wxEVT_TEXT_ENTER, ([this, txtctrl](wxEvent& e) + { + if (!txtctrl->IsEnabled() || !txtctrl->IsEditable()) + return; + const Preset& preset = m_presets->get_edited_preset(); + // parent of non system is always system or this txtctrl is not shown at all + std::string saved_val = wxGetApp().app_config->get("cost_override", preset.is_system ? preset.alias : m_presets->get_selected_preset_parent()->alias); + std::string curr_val = boost::nowide::narrow(txtctrl->GetValue()); + if (saved_val != curr_val && (saved_val != "" || curr_val != "0")) + wxGetApp().app_config->set("cost_override", preset.is_system ? preset.alias : m_presets->get_selected_preset_parent()->alias, curr_val); + + }), txtctrl->GetId()); + + txtctrl->Bind(wxEVT_KILL_FOCUS, ([this, txtctrl](wxFocusEvent& e) + { + e.Skip(); + if (!txtctrl->IsEnabled() || !txtctrl->IsEditable()) + return; + const Preset& preset = m_presets->get_edited_preset(); + // parent of non system is always system or this txtctrl is not shown at all + std::string saved_val = wxGetApp().app_config->get("cost_override", preset.is_system ? preset.alias : m_presets->get_selected_preset_parent()->alias); + std::string curr_val = boost::nowide::narrow(txtctrl->GetValue()); + if (saved_val != curr_val && (saved_val != "" || curr_val != "0")) + wxGetApp().app_config->set("cost_override", preset.is_system ? preset.alias : m_presets->get_selected_preset_parent()->alias, curr_val); + + }), txtctrl->GetId()); + + auto* label = new wxStaticText(parent, wxID_ANY, format("%1%/kg", wxGetApp().app_config->get("currency_shortcut"))); + label->SetFont(Slic3r::GUI::wxGetApp().normal_font()); + + auto sizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(txtctrl, 0, wxALIGN_CENTER_VERTICAL); + sizer->Add(label, 0, wxALIGN_CENTER_VERTICAL); + + return sizer; +} + +wxSizer* TabFilament::create_override_cost_widget(wxWindow* parent) +{ + wxCheckBox* checkbox = new wxCheckBox(parent, wxID_ANY, "Enable User cost for this profile"); + checkbox->SetFont(Slic3r::GUI::wxGetApp().normal_font()); + checkbox->Bind(wxEVT_CHECKBOX, ([this, checkbox](wxCommandEvent e) + { + if (Line* line = this->get_line("alias_filament_cost")) { + if (line->widget_sizer && line->widget_sizer->GetItemCount() > 0) { + wxSizerItem* item = line->widget_sizer->GetItem((size_t)0); // text control should be first item in sizer + wxTextCtrl* txtctrl = dynamic_cast<wxTextCtrl*>(item->GetWindow()); + // This value is stored in AppConfig, it is in the same category "cost_override", where user cost are stored. + // Name of inherited profile should never have name of alias of its parent system profile. Otherwise this needs to be changed. + if (txtctrl) { + if (checkbox->GetValue() == wxCHK_CHECKED) { + txtctrl->Enable(); + txtctrl->SetEditable(true); + std::string real_cost = wxGetApp().app_config->get("cost_override", m_presets->get_selected_preset_parent()->alias); + txtctrl->SetValue(real_cost.empty() ? wxString("0") : boost::nowide::widen(real_cost)); + const Preset& preset = m_presets->get_edited_preset(); + wxGetApp().app_config->set("cost_override", preset.name, "Enabled"); + } else { + txtctrl->Disable(); + txtctrl->SetEditable(false); + txtctrl->SetValue(wxString("0")); + const Preset& preset = m_presets->get_edited_preset(); + wxGetApp().app_config->set("cost_override", preset.name, "Disabled"); + } + } + } + } + }) ); + auto sizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(checkbox, 0, wxALIGN_CENTER_VERTICAL); + return sizer; +} + void TabFilament::update_description_lines() { Tab::update_description_lines(); @@ -2118,6 +2250,91 @@ void TabFilament::update_description_lines() 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(); + if (m_active_page->title() == "Filament" && m_alias_filament_cost_description_line) + m_alias_filament_cost_description_line->SetText(_L("This settings allows you to set your current local price of filament spool." + " If you set User cost for filament here, it will transfer to every system profile of the same name." + " It is also possible to allow this price on profiles inherited from system profiles." + " This settings is not part of the filament profile and saves to PrusaSlicer.ini." + " You can change currency shortcut in preferences." + " If user cost is zero, standart Cost settings is used.")); +} + +void TabFilament::update_filament_cost_visibility() +{ + // title is not translated text + if (m_active_page->title() != L"Filament") + return; + const Preset& preset = m_presets->get_edited_preset(); + // For filaments, get alias value for user cost + // if non system without system parent - hide group "User Cost" + // if system - hide override checkox + // if non system with system parent - show checkbox and with it toggle textbox + if (preset.is_system) { + // Find text control, enable it and fill value. + if (Line* line = this->get_line("alias_filament_cost")) { + if (line->widget_sizer && line->widget_sizer->GetItemCount() > 0) { + wxSizerItem* item = line->widget_sizer->GetItem((size_t)0); // text control should be first item in sizer + wxTextCtrl* txtctrl = dynamic_cast<wxTextCtrl*>(item->GetWindow()); + if (txtctrl) { + txtctrl->Enable(); + txtctrl->SetEditable(true); + std::string real_cost = wxGetApp().app_config->get("cost_override", preset.alias); + txtctrl->SetValue(real_cost.empty() ? wxString("0") : boost::nowide::widen(real_cost)); + } + } + } + // Hide line with override checkbox + if (ConfigOptionsGroupShp optgrp = this->m_active_page->get_optgroup(L"User Cost"); optgrp != nullptr) { + if (OG_CustomCtrl* ogcc = optgrp->custom_ctrl) { + if (Line* line = this->get_line("override_cost")) { + ogcc->force_hidden(*line, true); + ogcc->update_visibility(m_mode); + } + } + } + } else if (m_presets->get_selected_preset_parent()->is_system) { + // show override checkbox + if (ConfigOptionsGroupShp optgrp = this->m_active_page->get_optgroup(L"User Cost"); optgrp != nullptr) { + if (OG_CustomCtrl * ogcc = optgrp->custom_ctrl) { + if (Line* line = this->get_line("override_cost")) { + ogcc->force_hidden(*line, false); + } + } + } + // get appconfig value + std::string enabled_string = wxGetApp().app_config->get("cost_override", preset.name); + bool enabled = (enabled_string == "Enabled" ? true : false); + // check / uncheck + if (Line* line = this->get_line("override_cost")) { + if (line->widget_sizer && line->widget_sizer->GetItemCount() > 0) { + if (wxCheckBox* checkbox = dynamic_cast<wxCheckBox*>(line->widget_sizer->GetItem((size_t)0)->GetWindow())) { + checkbox->SetValue(enabled); + } + } + } + // disable / enable textbox + if (Line* line = this->get_line("alias_filament_cost")) { + if (line->widget_sizer && line->widget_sizer->GetItemCount() > 0) { + if (wxTextCtrl* txtctrl = dynamic_cast<wxTextCtrl*>(line->widget_sizer->GetItem((size_t)0)->GetWindow())) { + if (enabled) { + txtctrl->Enable(); + txtctrl->SetEditable(true); + std::string real_cost = wxGetApp().app_config->get("cost_override", m_presets->get_selected_preset_parent()->alias); + txtctrl->SetValue(real_cost.empty() ? wxString("0") : boost::nowide::widen(real_cost)); + } else { + txtctrl->Disable(); + txtctrl->SetEditable(false); + txtctrl->SetValue(wxString("0")); + } + } + } + } + } else { + // Hide whole optgroup if nonsystem and nonsytem parent + if (ConfigOptionsGroupShp optgrp = this->m_active_page->get_optgroup(L"User Cost")) { + optgrp->Hide(); + } + } } void TabFilament::toggle_options() @@ -2165,6 +2382,7 @@ void TabFilament::clear_pages() m_volumetric_speed_description_line = nullptr; m_cooling_description_line = nullptr; + m_alias_filament_cost_description_line = nullptr; } wxSizer* Tab::description_line_widget(wxWindow* parent, ogStaticText* *StaticText, wxString text /*= wxEmptyString*/) @@ -3068,10 +3286,13 @@ void Tab::load_current_preset() on_preset_loaded(); else wxGetApp().sidebar().update_objects_list_extruder_column(1); + } else if (m_type == Slic3r::Preset::TYPE_FILAMENT){ + dynamic_cast<TabFilament*>(this)->update_filament_cost_visibility(); } // Reload preset pages with the new configuration values. reload_config(); + update_ui_items_related_on_parent_preset(m_presets->get_selected_preset_parent()); // m_undo_to_sys_btn->Enable(!preset.is_default); @@ -3593,6 +3814,11 @@ void Tab::save_preset(std::string name /*= ""*/, bool detach) // Save the preset into Slic3r::data_dir / presets / section_name / preset_name.ini m_presets->save_current_preset(name, detach); + + // User filament cost needs to reload preset to correctly show / hide its elements + if (m_type == Preset::TYPE_FILAMENT) + load_current_preset(); + // Mark the print & filament enabled if they are compatible with the currently selected preset. // If saving the preset changes compatibility with other presets, keep the now incompatible dependent presets selected, however with a "red flag" icon showing that they are no more compatible. m_preset_bundle->update_compatible(PresetSelectCompatibleType::Never); @@ -3611,6 +3837,7 @@ void Tab::save_preset(std::string name /*= ""*/, bool detach) if (detach) update_ui_items_related_on_parent_preset(m_presets->get_selected_preset_parent()); + toggle_options(); update_changed_ui(); /* If filament preset is saved for multi-material printer preset, diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index e9a4cee20..18bebf7df 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -436,10 +436,13 @@ class TabFilament : public Tab private: ogStaticText* m_volumetric_speed_description_line {nullptr}; ogStaticText* m_cooling_description_line {nullptr}; + ogStaticText* m_alias_filament_cost_description_line {nullptr}; void add_filament_overrides_page(); void update_filament_overrides_page(); void update_volumetric_flow_preset_hints(); + wxSizer* create_filament_cost_widget(wxWindow* parent); + wxSizer* create_override_cost_widget(wxWindow* parent); std::map<std::string, wxCheckBox*> m_overrides_options; public: @@ -454,6 +457,7 @@ public: void update() override; void clear_pages() override; bool supports_printer_technology(const PrinterTechnology tech) const override { return tech == ptFFF; } + void update_filament_cost_visibility(); }; class TabPrinter : public Tab |