diff --git a/xs/src/slic3r/GUI/Field.hpp b/xs/src/slic3r/GUI/Field.hpp index 492629b41..0d8c237d2 100644 --- a/xs/src/slic3r/GUI/Field.hpp +++ b/xs/src/slic3r/GUI/Field.hpp @@ -72,6 +72,8 @@ public: virtual void enable() = 0; virtual void disable() = 0; + wxStaticText* m_Label = nullptr; + /// Fires the enable or disable function, based on the input. inline void toggle(bool en) { en ? enable() : disable(); } @@ -85,7 +87,7 @@ public: virtual wxWindow* getWindow() { return nullptr; } bool is_matched(std::string string, std::string pattern); - boost::any get_value_by_opt_type(wxString str); + boost::any get_value_by_opt_type(wxString str); /// Factory method for generating new derived classes. template<class T> diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 4cdafed5a..f9561d7b6 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -505,6 +505,11 @@ wxApp* get_app(){ return g_wxApp; } +wxColour* get_modified_label_clr() +{ + return new wxColour(254, 189, 101); +} + void create_combochecklist(wxComboCtrl* comboCtrl, std::string text, std::string items, bool initial_value) { if (comboCtrl == nullptr) diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index c6922cebc..7a8039e64 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -14,6 +14,7 @@ class wxComboCtrl; class wxString; class wxArrayString; class wxArrayLong; +class wxColour; namespace Slic3r { @@ -35,7 +36,7 @@ class TabIface; #define _CHB(s) wxGetTranslation(wxString(s, wxConvUTF8)).utf8_str() // Minimal buffer length for translated string (char buf[MIN_BUF_LENGTH_FOR_L]) -#define MIN_BUF_LENGTH_FOR_L 128 +#define MIN_BUF_LENGTH_FOR_L 512 namespace GUI { @@ -72,6 +73,7 @@ void set_app_config(AppConfig *app_config); AppConfig* get_app_config(); wxApp* get_app(); +wxColour* get_modified_label_clr(); void add_debug_menu(wxMenuBar *menu, int event_language_change); diff --git a/xs/src/slic3r/GUI/OptionsGroup.cpp b/xs/src/slic3r/GUI/OptionsGroup.cpp index f88b3f8c0..14142d207 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.cpp +++ b/xs/src/slic3r/GUI/OptionsGroup.cpp @@ -6,15 +6,15 @@ namespace Slic3r { namespace GUI { -const t_field& OptionsGroup::build_field(const Option& opt) { - return build_field(opt.opt_id, opt.opt); +const t_field& OptionsGroup::build_field(const Option& opt, wxStaticText* label/* = nullptr*/) { + return build_field(opt.opt_id, opt.opt, label); } -const t_field& OptionsGroup::build_field(const t_config_option_key& id) { +const t_field& OptionsGroup::build_field(const t_config_option_key& id, wxStaticText* label/* = nullptr*/) { const ConfigOptionDef& opt = m_options.at(id).opt; - return build_field(id, opt); + return build_field(id, opt, label); } -const t_field& OptionsGroup::build_field(const t_config_option_key& id, const ConfigOptionDef& opt) { +const t_field& OptionsGroup::build_field(const t_config_option_key& id, const ConfigOptionDef& opt, wxStaticText* label/* = nullptr*/) { // Check the gui_type field first, fall through // is the normal type. if (opt.gui_type.compare("select") == 0) { @@ -72,7 +72,11 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co this->on_kill_focus(); }; field->m_parent = parent(); - // assign function objects for callbacks, etc. + + //! Label to change background color, when option is modified + field->m_Label = label; + + // assign function objects for callbacks, etc. return field; } @@ -110,9 +114,11 @@ void OptionsGroup::append_line(const Line& line) { auto grid_sizer = m_grid_sizer; // Build a label if we have it + wxStaticText* label=nullptr; if (label_width != 0) { - auto label = new wxStaticText(parent(), wxID_ANY, line.label + (line.label.IsEmpty() ? "" : ":"), + /*auto*/ label = new wxStaticText(parent(), wxID_ANY, line.label + (line.label.IsEmpty() ? "" : ":"), wxDefaultPosition, wxSize(label_width, -1)); +// label->SetBackgroundColour(*new wxColour(254, 189, 101)); label->SetFont(label_font); label->Wrap(label_width); // avoid a Linux/GTK bug grid_sizer->Add(label, 0, wxALIGN_CENTER_VERTICAL,0); @@ -131,7 +137,7 @@ void OptionsGroup::append_line(const Line& line) { if (option_set.size() == 1 && option_set.front().opt.sidetext.size() == 0 && option_set.front().side_widget == nullptr && line.get_extra_widgets().size() == 0) { const auto& option = option_set.front(); - const auto& field = build_field(option); + const auto& field = build_field(option, label); //! std::cerr << "single option, no sidetext.\n"; //! std::cerr << "field parent is not null?: " << (field->parent != nullptr) << "\n"; @@ -156,14 +162,14 @@ void OptionsGroup::append_line(const Line& line) { // wxString str_label = (option.label == "Top" || option.label == "Bottom") ? // wxGETTEXT_IN_CONTEXT("Layers", wxString(option.label.c_str()): // L_str(option.label); - auto field_label = new wxStaticText(parent(), wxID_ANY, str_label + ":", wxDefaultPosition, wxDefaultSize); - field_label->SetFont(label_font); - sizer->Add(field_label, 0, wxALIGN_CENTER_VERTICAL, 0); + /*auto field_*/label = new wxStaticText(parent(), wxID_ANY, str_label + ":", wxDefaultPosition, wxDefaultSize); + /*field_*/label->SetFont(label_font); + sizer->Add(/*field_*/label, 0, wxALIGN_CENTER_VERTICAL, 0); } // add field const Option& opt_ref = opt; - auto& field = build_field(opt_ref); + auto& field = build_field(opt_ref, label); is_sizer_field(field) ? sizer->Add(field->getSizer(), 0, wxALIGN_CENTER_VERTICAL, 0) : sizer->Add(field->getWindow(), 0, wxALIGN_CENTER_VERTICAL, 0); diff --git a/xs/src/slic3r/GUI/OptionsGroup.hpp b/xs/src/slic3r/GUI/OptionsGroup.hpp index 6e88d1d88..6819a1174 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.hpp +++ b/xs/src/slic3r/GUI/OptionsGroup.hpp @@ -27,6 +27,9 @@ namespace Slic3r { namespace GUI { using widget_t = std::function<wxSizer*(wxWindow*)>;//!std::function<wxWindow*(wxWindow*)>; using column_t = std::function<wxSizer*(const Line&)>; +//auto default_label_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT); //GetSystemColour +//auto modified_label_clr = *new wxColour(254, 189, 101); + /// Wraps a ConfigOptionDef and adds function object for creating a side_widget. struct Option { ConfigOptionDef opt { ConfigOptionDef() }; @@ -136,9 +139,9 @@ protected: /// Generate a wxSizer or wxWindow from a configuration option /// Precondition: opt resolves to a known ConfigOption /// Postcondition: fields contains a wx gui object. - const t_field& build_field(const t_config_option_key& id, const ConfigOptionDef& opt); - const t_field& build_field(const t_config_option_key& id); - const t_field& build_field(const Option& opt); + const t_field& build_field(const t_config_option_key& id, const ConfigOptionDef& opt, wxStaticText* label = nullptr); + const t_field& build_field(const t_config_option_key& id, wxStaticText* label = nullptr); + const t_field& build_field(const Option& opt, wxStaticText* label = nullptr); virtual void on_kill_focus (){}; virtual void on_change_OG(t_config_option_key opt_id, boost::any value); diff --git a/xs/src/slic3r/GUI/Tab.cpp b/xs/src/slic3r/GUI/Tab.cpp index 946719356..15fc5f006 100644 --- a/xs/src/slic3r/GUI/Tab.cpp +++ b/xs/src/slic3r/GUI/Tab.cpp @@ -139,6 +139,13 @@ PageShp Tab::add_options_page(wxString title, std::string icon, bool is_extruder void Tab::update_dirty(){ m_presets->update_dirty_ui(m_presets_choice); on_presets_changed(); + auto dirty_options = m_presets->current_dirty_options(); + for (auto opt_key : dirty_options){ + if (find(m_dirty_options.begin(), m_dirty_options.end(), opt_key) == m_dirty_options.end()){ + get_field(opt_key)->m_Label->SetBackgroundColour(*get_modified_label_clr()); + m_dirty_options.push_back(opt_key); + } + } } void Tab::update_tab_ui() @@ -211,6 +218,7 @@ void Tab::load_config(DynamicPrintConfig config) } change_opt_value(*m_config, opt_key, value); modified = 1; +// get_field(opt_key)->m_Label->SetBackgroundColour(*get_modified_label_clr()); } if (modified) { update_dirty(); diff --git a/xs/src/slic3r/GUI/Tab.hpp b/xs/src/slic3r/GUI/Tab.hpp index 208f99fec..345559c7e 100644 --- a/xs/src/slic3r/GUI/Tab.hpp +++ b/xs/src/slic3r/GUI/Tab.hpp @@ -99,6 +99,7 @@ protected: bool m_no_controller; std::vector<std::string> m_reload_dependent_tabs = {}; + std::vector<std::string> m_dirty_options = {}; // The two following two event IDs are generated at Plater.pm by calling Wx::NewEventType. wxEventType m_event_value_change = 0;