diff options
author | supermerill <merill@free.fr> | 2022-09-06 23:51:47 +0300 |
---|---|---|
committer | supermerill <merill@free.fr> | 2022-09-16 17:21:47 +0300 |
commit | 4792683e3eb006f78f95359240be531838ec39ea (patch) | |
tree | 6825f4628172fc110d8578f8e11ecbfe314b052b | |
parent | 2c379a2afdf565889116e660a6242367e93a2d49 (diff) |
scripted widget: now executed at conf load, to apply changes
fix refresh for float/&percent
fixed ask_for_refresh() for non-bool
supermerill/SuperSlicer#3175
-rw-r--r-- | resources/ui_layout/Readme.md | 4 | ||||
-rw-r--r-- | src/slic3r/GUI/OptionsGroup.cpp | 5 | ||||
-rw-r--r-- | src/slic3r/GUI/OptionsGroup.hpp | 4 | ||||
-rw-r--r-- | src/slic3r/GUI/ScriptExecutor.cpp | 74 | ||||
-rw-r--r-- | src/slic3r/GUI/Tab.cpp | 66 |
5 files changed, 83 insertions, 70 deletions
diff --git a/resources/ui_layout/Readme.md b/resources/ui_layout/Readme.md index 4c764006e..d205e8646 100644 --- a/resources/ui_layout/Readme.md +++ b/resources/ui_layout/Readme.md @@ -161,8 +161,8 @@ Here are all the functions you need to define for your custom widget to work (fo * float **OPTNAME_get**() * void **OPTNAME_set**(float set) ### type float_or_percent: - * float **OPTNAME_get**(bool &out is_percent) - * void **OPTNAME_set**(float set, bool is_percent) + * float **OPTNAME_get**(bool &out isPercent) + * void **OPTNAME_set**(float set, bool isPercent) ### type string: * void **OPTNAME_get**(string &out get) * void **OPTNAME_set**(string &in set) diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index f218c1c1e..1d5a97b85 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -589,11 +589,10 @@ void OptionsGroup::on_change_OG(const t_config_option_key& opt_id, const boost:: m_on_change(opt_id, value); } -void OptionsGroup::update_script_presets() { +void OptionsGroup::update_script_presets(bool init) { for (auto& key_opt : m_options) { if (key_opt.second.opt.is_script) { - Field* field = get_field(key_opt.first); - if (field) { + if (init || get_field(key_opt.first)) { boost::any val = key_opt.second.script->call_script_function_get_value(key_opt.second.opt); if (val.empty()) { MessageDialog(nullptr, "Error, can't find the script to get the value for the widget '" + key_opt.first + "'", _L("Error"), wxOK | wxICON_ERROR).ShowModal(); diff --git a/src/slic3r/GUI/OptionsGroup.hpp b/src/slic3r/GUI/OptionsGroup.hpp index bc068c1ed..9a494d23d 100644 --- a/src/slic3r/GUI/OptionsGroup.hpp +++ b/src/slic3r/GUI/OptionsGroup.hpp @@ -143,8 +143,8 @@ public: // delete all controls from the option group void clear(bool destroy_custom_ctrl = false); - // ask for each script option to recompute their value - void update_script_presets(); + // ask for each script option to recompute their value. If init is true, it will ask for get/set even if the Field isn't created. + void update_script_presets(bool init = false); Line create_single_option_line(const Option& option, const std::string& path = std::string()) const; void append_single_option_line(const Option& option, const std::string& path = std::string()) { append_line(create_single_option_line(option, path)); } diff --git a/src/slic3r/GUI/ScriptExecutor.cpp b/src/slic3r/GUI/ScriptExecutor.cpp index 4565d1aec..e923bb5e8 100644 --- a/src/slic3r/GUI/ScriptExecutor.cpp +++ b/src/slic3r/GUI/ScriptExecutor.cpp @@ -191,25 +191,25 @@ void as_set_float(std::string& key, float f_val) double new_val = round(f_val); // only update if difference is significant if (std::abs(old_value - new_val) / std::abs(old_value) < 0.0000001) - return; - conf.set_key_value(key, new ConfigOptionFloat(f_val)); + new_val = old_value; // don't return int these check, as it can escpae a refresh of the scripted widget + conf.set_key_value(key, new ConfigOptionFloat(new_val)); } else if (result.second->type() == ConfigOptionType::coFloats) { ConfigOptionFloats* new_opt = static_cast<ConfigOptionFloats*>(result.second->clone()); + double new_val = round(f_val); if (!new_opt->values.empty()) { // only update if difference is significant double old_value = new_opt->values.front(); - double new_val = round(f_val); if (std::abs(old_value - new_val) / std::abs(old_value) < 0.0000001) - return; + new_val = old_value; } - new_opt->set_at(f_val, 0); + new_opt->set_at(new_val, 0); conf.set_key_value(key, new_opt); } else if (result.second->type() == ConfigOptionType::coPercent) { double percent_f = floor(f_val * 100000. + 0.5) / 1000.; // only update if difference is significant double old_value = result.second->getFloat(); if (std::abs(old_value - percent_f) / std::abs(old_value) < 0.0000001) - return; + percent_f = old_value; conf.set_key_value(key, new ConfigOptionPercent(percent_f)); } else if (result.second->type() == ConfigOptionType::coPercents) { ConfigOptionPercents* new_opt = static_cast<ConfigOptionPercents*>(result.second->clone()); @@ -218,29 +218,29 @@ void as_set_float(std::string& key, float f_val) // only update if difference is significant double old_value = new_opt->values.front(); if (std::abs(old_value - percent_f) / std::abs(old_value) < 0.0000001) - return; + percent_f = old_value; } new_opt->set_at(percent_f, 0); conf.set_key_value(key, new_opt); } else if (result.second->type() == ConfigOptionType::coFloatOrPercent) { + double new_val = round(f_val); if (!static_cast<const ConfigOptionFloatOrPercent*>(result.second)->percent) { // only update if difference is significant double old_value = result.second->getFloat(); - double new_val = round(f_val); if (std::abs(old_value - new_val) / std::abs(old_value) < 0.0000001) - return; + new_val = old_value; } - conf.set_key_value(key, new ConfigOptionFloatOrPercent(f_val, false)); + conf.set_key_value(key, new ConfigOptionFloatOrPercent(new_val, false)); } else if (result.second->type() == ConfigOptionType::coFloatsOrPercents) { ConfigOptionFloatsOrPercents* new_opt = static_cast<ConfigOptionFloatsOrPercents*>(result.second->clone()); + double new_val = round(f_val); if (!new_opt->values.empty() && !new_opt->values.front().percent) { // only update if difference is significant double old_value = new_opt->values.front().value; - double new_val = round(f_val); if (std::abs(old_value - new_val) / std::abs(old_value) < 0.0000001) - return; + new_val = old_value; } - new_opt->set_at(FloatOrPercent{ f_val, false}, 0); + new_opt->set_at(FloatOrPercent{ new_val, false}, 0); conf.set_key_value(key, new_opt); } } @@ -265,7 +265,7 @@ void as_set_percent(std::string& key, float f_val) // only update if difference is significant double old_value = result.second->getFloat() * 100; if (std::abs(old_value - percent_f) / std::abs(old_value) < 0.0000001) - return; + percent_f = old_value; // don't return int these check, as it can escpae a refresh of the scripted widget conf.set_key_value(key, new ConfigOptionFloat(percent_f / 100.)); } else if (result.second->type() == ConfigOptionType::coFloats) { ConfigOptionFloats* new_opt = static_cast<ConfigOptionFloats*>(result.second->clone()); @@ -273,7 +273,7 @@ void as_set_percent(std::string& key, float f_val) // only update if difference is significant double old_value = new_opt->values.front() * 100; if (std::abs(old_value - percent_f) / std::abs(old_value) < 0.0000001) - return; + percent_f = old_value; } new_opt->set_at(percent_f / 100., 0); conf.set_key_value(key, new_opt); @@ -281,7 +281,7 @@ void as_set_percent(std::string& key, float f_val) // only update if difference is significant double old_value = get_coll(key).second->getFloat(); if (std::abs(old_value - percent_f) / std::abs(old_value) < 0.0000001) - return; + percent_f = old_value; conf.set_key_value(key, new ConfigOptionPercent(percent_f)); } else if (result.second->type() == ConfigOptionType::coPercents) { ConfigOptionPercents* new_opt = static_cast<ConfigOptionPercents*>(result.second->clone()); @@ -289,7 +289,7 @@ void as_set_percent(std::string& key, float f_val) // only update if difference is significant double old_value = new_opt->values.front(); if (std::abs(old_value - percent_f) / std::abs(old_value) < 0.0000001) - return; + percent_f = old_value; } new_opt->set_at(percent_f, 0); conf.set_key_value(key, new_opt); @@ -298,7 +298,7 @@ void as_set_percent(std::string& key, float f_val) // only update if difference is significant double old_value = result.second->getFloat(); if (std::abs(old_value - percent_f) / std::abs(old_value) < 0.0000001) - return; + percent_f = old_value; } conf.set_key_value(key, new ConfigOptionFloatOrPercent(percent_f, true)); } else if (result.second->type() == ConfigOptionType::coFloatsOrPercents) { @@ -307,7 +307,7 @@ void as_set_percent(std::string& key, float f_val) // only update if difference is significant double old_value = new_opt->values.front().value; if (std::abs(old_value - percent_f) / std::abs(old_value) < 0.0000001) - return; + percent_f = old_value; } new_opt->set_at(FloatOrPercent{ percent_f, true }, 0); conf.set_key_value(key, new_opt); @@ -1017,51 +1017,55 @@ boost::any ScriptContainer::call_script_function_get_value(const ConfigOptionDef int res = ctx->Execute(); int32_t ret_int; float ret_float; - boost::any ret_val; + boost::any field_val; + boost::any opt_val; switch (def.type) { case coBool: - case coBools: { ret_int = ctx->GetReturnDWord(); ret_val = uint8_t(ret_int < 0 ? 2 : ret_int); break; } //CheckBox + case coBools: { ret_int = ctx->GetReturnDWord(); field_val = uint8_t(ret_int < 0 ? 2 : ret_int); opt_val = uint8_t((ret_int > 0)?1:0); break; } //CheckBox case coInt: - case coInts: { ret_int = ctx->GetReturnDWord(); ret_val = int32_t(ret_int); break; } //SpinCtrl + case coInts: { ret_int = ctx->GetReturnDWord(); field_val = int32_t(ret_int); opt_val = int(ret_int); break; } //SpinCtrl case coString: - case coStrings: { ret_val = from_u8(ret_str); break; } //TextCtrl + case coStrings: { field_val = from_u8(ret_str); opt_val = ret_str; break; } //TextCtrl case coPercent: case coPercents: ret_percent = true; + case coFloat: + case coFloats: opt_val = double(ctx->GetReturnFloat()); case coFloatOrPercent: case coFloatsOrPercents: - case coFloat: - case coFloats: { + { ret_float = ctx->GetReturnFloat(); wxString ret_wstring = double_to_string(ret_float); if (ret_percent) ret_wstring += '%'; - ret_val = ret_wstring; //TextCtrl + field_val = ret_wstring; //TextCtrl + if (opt_val.empty()) { opt_val = ret_wstring.ToStdString(); } break; } case coPoint: - case coPoints: { ret_float = ctx->GetReturnFloat(); ret_val = Vec2d{ ret_float, ret_float }; break; } //FIXME PointCtrl - case coPoint3: { ret_float = ctx->GetReturnFloat(); ret_val = Vec3d{ ret_float, ret_float, ret_float }; break; } + case coPoints: { ret_float = ctx->GetReturnFloat(); field_val = Vec2d{ ret_float, ret_float }; opt_val = double(ctx->GetReturnFloat()); break; } //FIXME PointCtrl + case coPoint3: { ret_float = ctx->GetReturnFloat(); field_val = Vec3d{ ret_float, ret_float, ret_float }; opt_val = double(ctx->GetReturnFloat()); break; } case coEnum: { ret_int = ctx->GetReturnDWord(); if (ret_int >= 0 && ret_int < def.enum_values.size()) { - ret_val = int32_t(ret_int); + field_val = int32_t(ret_int); } else { - ret_val = int32_t(0); + field_val = int32_t(0); for (size_t i = 0; i < def.enum_values.size(); i++) { if (ret_str == def.enum_values[i]) - ret_val = int32_t(i); + field_val = int32_t(i); } } + opt_val = field_val; break; //Choice } } if (m_need_refresh) { - refresh(def, ret_val); + refresh(def, opt_val); } - if (ret_val.empty()) { + if (field_val.empty()) { std::cout << "Error nullptr for script\n"; } - return ret_val; + return field_val; } void ScriptContainer::refresh(const ConfigOptionDef& def, boost::any value) @@ -1072,7 +1076,7 @@ void ScriptContainer::refresh(const ConfigOptionDef& def, boost::any value) return; //if bool, need to change the int in bool if (def.type == coBool || def.type == coBools) { - value = bool(boost::any_cast<uint8_t>(value) == 1); + value = bool(boost::any_cast<uint8_t>(value) != 0); } m_currently_reset.push_back(def.opt_key); call_script_function_set(def, value); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 289fa3c35..0fdd89491 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1082,6 +1082,15 @@ void Tab::reload_config() { if (m_active_page) m_active_page->reload_config(); + //also reload scripted that aren't on the active page. + for (PageShp page : m_pages) { + if (page.get() != m_active_page) { + for (auto group : page->m_optgroups) { + // ask for activated the preset even if the gui isn't created, as the script may want to modify the conf. + group->update_script_presets(true); + } + } + } } void Tab::update_mode() @@ -2120,36 +2129,18 @@ std::vector<Slic3r::GUI::PageShp> Tab::create_pages(std::string setting_type_nam option.opt.max_literal = { boost::lexical_cast<double>(params[i].substr(12, params[i].size() - 12).c_str()), false }; } else if (is_script) { - if (params[i] == "bool") { - option.opt.type = coBool; - option.opt.set_default_value(new ConfigOptionBool(false)); - } else if (boost::starts_with(params[i], "int")) { - option.opt.type = coInt; - option.opt.set_default_value(new ConfigOptionInt(0)); - fct_add_enum(params[i]); - } else if (boost::starts_with(params[i], "float")) { - option.opt.type = coFloat; - option.opt.set_default_value(new ConfigOptionFloat(0.)); - fct_add_enum(params[i]); - } else if (boost::starts_with(params[i], "percent")) { - option.opt.type = coPercent; - option.opt.set_default_value(new ConfigOptionPercent(0)); - fct_add_enum(params[i]); - } else if (boost::starts_with(params[i], "float_or_percent")) { - option.opt.type = coFloatOrPercent; - option.opt.set_default_value(new ConfigOptionFloatOrPercent(0.f, false)); - fct_add_enum(params[i]); - } else if (boost::starts_with(params[i], "string")) { - option.opt.type = coString; - option.opt.set_default_value(new ConfigOptionString("")); - fct_add_enum(params[i]); - } else if (params[i] == "bools") { + //be careful, "floatX" has to deteted before "float". + if (params[i] == "bools") { option.opt.type = coBools; option.opt.set_default_value(new ConfigOptionBools{ false }); } else if (boost::starts_with(params[i], "ints")) { option.opt.type = coInts; option.opt.set_default_value(new ConfigOptionInts{ 0 }); fct_add_enum(params[i]); + } else if (boost::starts_with(params[i], "floats_or_percents")) { + option.opt.type = coFloatsOrPercents; + option.opt.set_default_value(new ConfigOptionFloatsOrPercents{ FloatOrPercent{0.f, false} }); + fct_add_enum(params[i]); } else if (boost::starts_with(params[i], "floats")) { option.opt.type = coFloats; option.opt.set_default_value(new ConfigOptionFloats{ 0. }); @@ -2158,14 +2149,33 @@ std::vector<Slic3r::GUI::PageShp> Tab::create_pages(std::string setting_type_nam option.opt.type = coPercents; option.opt.set_default_value(new ConfigOptionPercents{ 0 }); fct_add_enum(params[i]); - } else if (boost::starts_with(params[i], "floats_or_percents")) { - option.opt.type = coFloatsOrPercents; - option.opt.set_default_value(new ConfigOptionFloatsOrPercents{ FloatOrPercent{0.f, false} }); - fct_add_enum(params[i]); } else if (boost::starts_with(params[i], "strings")) { option.opt.type = coStrings; option.opt.set_default_value(new ConfigOptionString{ "" }); fct_add_enum(params[i]); + } else if (params[i] == "bool") { + option.opt.type = coBool; + option.opt.set_default_value(new ConfigOptionBool(false)); + } else if (boost::starts_with(params[i], "int")) { + option.opt.type = coInt; + option.opt.set_default_value(new ConfigOptionInt(0)); + fct_add_enum(params[i]); + } else if (boost::starts_with(params[i], "float_or_percent")) { + option.opt.type = coFloatOrPercent; + option.opt.set_default_value(new ConfigOptionFloatOrPercent(0.f, false)); + fct_add_enum(params[i]); + } else if (boost::starts_with(params[i], "float")) { + option.opt.type = coFloat; + option.opt.set_default_value(new ConfigOptionFloat(0.)); + fct_add_enum(params[i]); + } else if (boost::starts_with(params[i], "percent")) { + option.opt.type = coPercent; + option.opt.set_default_value(new ConfigOptionPercent(0)); + fct_add_enum(params[i]); + } else if (boost::starts_with(params[i], "string")) { + option.opt.type = coString; + option.opt.set_default_value(new ConfigOptionString("")); + fct_add_enum(params[i]); } else if (boost::starts_with(params[i], "enum")) { option.opt.type = coEnum; std::vector<std::string> enum_strs; |