diff options
author | supermerill <merill@free.fr> | 2022-08-09 22:25:22 +0300 |
---|---|---|
committer | supermerill <merill@free.fr> | 2022-08-11 00:56:51 +0300 |
commit | ed22e605c20332a7b4c6ca7ce2487b08025cc29a (patch) | |
tree | e170f2f688fe8df2b9ce193455ad5003efb614ce | |
parent | 16db2fd49218b9268fb759772792572ced351878 (diff) |
Allow reset function for scripted widget
updated doc in readme
supermerill/SuperSlicer#2930
-rw-r--r-- | resources/ui_layout/Readme.md | 82 | ||||
-rw-r--r-- | resources/ui_layout/default/print.as | 81 | ||||
-rw-r--r-- | src/slic3r/GUI/OptionsGroup.cpp | 48 | ||||
-rw-r--r-- | src/slic3r/GUI/ScriptExecutor.cpp | 60 | ||||
-rw-r--r-- | src/slic3r/GUI/ScriptExecutor.hpp | 2 |
5 files changed, 171 insertions, 102 deletions
diff --git a/resources/ui_layout/Readme.md b/resources/ui_layout/Readme.md index 62410091d..4c764006e 100644 --- a/resources/ui_layout/Readme.md +++ b/resources/ui_layout/Readme.md @@ -87,8 +87,8 @@ each parameter is separated by ':' * `floats_or_percents: mandatory`: Array. Tell the sotfware it's a numeric that can acept a % value (boolean return value) * `strings`: Array. Tell mandatory for a filament or an extruder value. The sotfware it's a numeric an entry field where you can enter a text(string return value) * `enum$STR$STR[$STR$STR]*`: tell the sotfware it's a combobox (string return value). It has to be followed by $name$label for each option you want to show. -Also, script may depends on normal fields. When a setting it depends is modified, the scripted widget will appear modified. And resetting a widget will reset all depending fields. - * `depends$STR[$STR]*`: add the setting fields this scripted widget depends on. Each one has to be suffixed by a '$' + * Also, script may depends on normal fields. When a setting it depends is modified, the scripted widget will appear modified. And resetting a widget will reset all depending fields. + * `depends$STR[$STR]*`: add the setting fields this scripted widget depends on. Each one has to be suffixed by a '$' There is also special commands: * `height:INT`: change the default height of settings. Don't works with every type of setting (mostly multilne text). Set to 0 or -1 to disable. @@ -139,9 +139,87 @@ The second one is called when the user change the value in the gui. At the start of the print.ui file, there is a little dictionnary with he methods available for the script to call. It also contains the list of methods needed for all types (not only int). +You can also write a `void my_widget_reset()` if the default one (reset the settings from the depends property) isn't what's needed. + ## frequent settings The files freq_fff.ui and freq_sla.ui contains teh frequent settings. Their layout is similar as other ui files. They still have to define a page and a group. The group has to be `group:freq_settings_event:no_title:no_search:` to not interfer witht he rest of the gui. If it use scripted widget, they have to be in the print.as file. The syntax is similar to c++/java. + +## Script API: called by the slicer +Here are all the functions you need to define for your custom widget to work (for your type): +### type bool: + * int **OPTNAME_get**() + Will return 1 if checked, 0 if unchecked and -1 if half-checked (not all os, will be unchecked if not available) + * void **OPTNAME_set**(bool set) +### type int: + * int **OPTNAME_get**() + * void **OPTNAME_set**(int set) +### type float & percent: + * 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) +### type string: + * void **OPTNAME_get**(string &out get) + * void **OPTNAME_set**(string &in set) +### type enum: + * int **OPTNAME_get**(string &out enum_value) + Only the return value is used unless it's out of bounds, then it tries to use the enum_value + * void **OPTNAME_set**(string &in set_enum_value, int set_idx) +### all type: + * void **OPTNAME_reset**() + Optional, called when clicked on the "reset" button. + If not present, the software will call a reset on all fields from the 'depends' property. +## Script API: called by the script + Here are listed all the functions to the slicer you can call from the script: +### to get the value of a real settings +These functions can be called everywhere. + * bool **get_bool**(string &in key) + * int **get_int**(string &in key) + Can be used by type int and enum (return the index) + * float **get_float**(string &in key) + Can be used by type float, percent and flaot_or_percent + * float **get_computed_float**(string &in key) + Get the float computed value of the field. Useful if it's a floatOrPercent that is computable. + * bool **is_percent**(string &in key) + * void **get_string**(string &in key, string &out get_val) + Can be used by type string and enum (return the enum_value, not the label) + +### to set the value of real settings +These functions can only be called in a `set` or `reset` function. If you need to set a variable in a `get`, call ask_for_refresh() and write it in the set method. + * void **set_bool**(string &in key, bool new_val) + * void **set_int**(string &in key, int new_val) + if an enum, it's the index in the c++ enum + * void **set_float**(string &in key, float new_val) + if a float_or_percent, unset the percent flag at the same time + * void **set_percent**(string &in key, float new_val) + if a float_or_percent, set the percent flag at the same time + * void **set_string**(string &in key, string &in new_val)) + if an enum, it's one of the enum_value, as saved in a config file + * void **back_initial_value**(string &in key) + revert the setting to the last saved value (same as a click on the reset arrow) +### others + * void **ask_for_refresh**() + ask for a OPTNAME_set() after the current OPTNAME_get(), to be able to set settings. + +### to get/set the value of a custom variable +The first argument is the index of the tab setting: 0 for print settings, 1 for filament settings and 2 for printer settings. +Getters return true if the variable exists, false if it doesn't. If the variable doesn't exists, the 'out' variable isn't set. + * bool **get_custom_bool**(int, string &in, bool &out) + * void **set_custom_bool**(int, string &in, bool new_val) + * bool **get_custom_int**(int, string &in, int &out) + * void **set_custom_int**(int, string &in, int new_val) + * bool **get_custom_float**(int, string &in, float &out) + * void **set_custom_float**(int, string &in, float new_val) + * bool **get_custom_string**(int, string &in, string &out) + * void **set_custom_string**(int, string &in, string &in new_val) + * void **back_custom_initial_value**(int, string &in) +To remove a custom variable, use `set_custom_string` with an empty string as `new_val` + +### to print on the console, for debugging + * void **print**(string &out) + * void **print_float**(float) diff --git a/resources/ui_layout/default/print.as b/resources/ui_layout/default/print.as index 3c830bfd1..18e255178 100644 --- a/resources/ui_layout/default/print.as +++ b/resources/ui_layout/default/print.as @@ -1,73 +1,3 @@ -////////////////////////////////////////// -// Api for SuperSlicer scripted widgets: -// -//// Functions callable //// -// -// -- to print on the console, for debugging -- -// void print(string &out) -// void print_float(float) -// -// -- to get the value of real settings -- -// bool get_bool(string &in key) -// int get_int(string &in key) -// can be used by type int and enum (return the index) -// float get_float(string &in key) -// can be used by type float, percent and flaot_or_percent -// float get_computed_float(string &in key) -// get the float computed value of the field. Useful if it's a floatOrPercent that is computable. -// bool is_percent(string &in key) -// void get_string(string &in key, string &out get_val) -// can be used by type string and enum (return the enum_value, not the label) -// -// -- to set the value of real settings -- -// void set_bool(string &in key, bool new_val) -// void set_int(string &in key, int new_val) -// if an enum, it's the index -// void set_float(string &in key, float new_val) -// if a float_or_percent, unset the percent flag at the same time -// void set_percent(string &in key, float new_val) -// if a float_or_percent, set the percent flag at the same time -// void set_string(string &in key, string &in new_val)) -// if an enum, it's one of the enum_value -// -// void back_initial_value(string &in key) -// revert the setting to the last saved value (same as a click on the reset arrow) -// -// ask_for_refresh() -// ask for a OPTNAME_set() if in a OPTNAME_get() -// -//// Functions to define for each script widget //// -// -// note that you can't call set_thing() in an OPTNAME_get(), you can only call these in an OPTNAME_set() -// -// type bool: -// int OPTNAME_get() -// will return 1 if checkd, 0 if unchecked and -1 if half-checked (not all os, will be uncehcked if not available) -// void OPTNAME_set(bool set) -// -// type int: -// int OPTNAME_get() -// void OPTNAME_set(int set) -// -// type float & percent: -// 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) -// -// type string: -// void OPTNAME_get(string &out get) -// void OPTNAME_set(string &in set) -// -// type enum: -// int OPTNAME_get(string &out enum_value) -// Only the return value is used unless it's out of bounds, then it tries to use the enum_value -// void OPTNAME_set(string &in set_enum_value, int set_idx) -// -// - //overhangs : quick set/unset like the one in prusalicer int s_overhangs_get() @@ -92,12 +22,6 @@ void s_overhangs_set(bool set) } } -void s_overhangs_reset(bool set) -{ - back_initial_value("overhangs_width_speed"); - back_initial_value("overhangs_width"); -} - // "not thick bridge" like in prusaslicer float compute_overlap() @@ -125,11 +49,12 @@ int s_not_thick_bridge_get() return 0; } -void s_not_thick_bridge_reset(bool set) +void s_not_thick_bridge_reset() { - set_custom_bool(0,"not_thick_bridge", false); + set_custom_string(0,"not_thick_bridge", ""); back_initial_value("bridge_type"); back_initial_value("bridge_overlap"); + back_initial_value("bridge_overlap_min"); } void s_not_thick_bridge_set(bool set) diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index 016847178..fa63bd0ad 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -684,30 +684,36 @@ void ConfigOptionsGroup::back_to_config_value(const DynamicPrintConfig& config, auto *milling_diameter = dynamic_cast<const ConfigOptionFloats*>(config.option("milling_diameter")); value = int(milling_diameter->values.size()); } else if (it_opt != m_options.end() && it_opt->second.opt.is_script) { - //when a scripted key is reset, reset its deps - //reset if needed in other tabs - for (const std::string& dep_key : it_opt->second.opt.depends_on) { - for (Tab* tab : wxGetApp().tabs_list) { - if (tab != nullptr && tab->completed()) { - const DynamicPrintConfig& initial_conf = tab->m_presets->get_selected_preset().config; - DynamicPrintConfig& edited_conf = tab->m_presets->get_edited_preset().config; - if (initial_conf.has(dep_key) && edited_conf.has(dep_key)) { - ConfigOption* conf_opt = initial_conf.option(dep_key)->clone(); - //set the conf - edited_conf.set_key_value(dep_key, conf_opt); + // when a scripted key is reset, reset its deps + // call the reset function if it exits + if (!it_opt->second.script->call_script_function_reset(it_opt->second.opt)) { + // Fucntion doesn't exists, reset the fields from the 'depends' + // reset in all tabs + // first set_key_value + for (const std::string& dep_key : it_opt->second.opt.depends_on) { + for (Tab* tab : wxGetApp().tabs_list) { + if (tab != nullptr && tab->completed()) { + const DynamicPrintConfig& initial_conf = tab->m_presets->get_selected_preset().config; + DynamicPrintConfig& edited_conf = tab->m_presets->get_edited_preset().config; + if (initial_conf.has(dep_key) && edited_conf.has(dep_key)) { + ConfigOption* conf_opt = initial_conf.option(dep_key)->clone(); + //set the conf + edited_conf.set_key_value(dep_key, conf_opt); + } } } } - } - for (const std::string& dep_key : it_opt->second.opt.depends_on) { - for (Tab* tab : wxGetApp().tabs_list) { - if (tab != nullptr && tab->completed()) { - const DynamicPrintConfig& initial_conf = tab->m_presets->get_selected_preset().config; - DynamicPrintConfig& edited_conf = tab->m_presets->get_edited_preset().config; - if (initial_conf.has(dep_key) && edited_conf.has(dep_key)) { - ConfigOption* conf_opt = initial_conf.option(dep_key)->clone(); - // update the field - tab->on_value_change(dep_key, conf_opt->getAny()); + // now that all keys are set, call the on_value_change to propagate the changes in one go. + for (const std::string& dep_key : it_opt->second.opt.depends_on) { + for (Tab* tab : wxGetApp().tabs_list) { + if (tab != nullptr && tab->completed()) { + const DynamicPrintConfig& initial_conf = tab->m_presets->get_selected_preset().config; + DynamicPrintConfig& edited_conf = tab->m_presets->get_edited_preset().config; + if (initial_conf.has(dep_key) && edited_conf.has(dep_key)) { + ConfigOption* conf_opt = initial_conf.option(dep_key)->clone(); + // update the field + tab->on_value_change(dep_key, conf_opt->getAny()); + } } } } diff --git a/src/slic3r/GUI/ScriptExecutor.cpp b/src/slic3r/GUI/ScriptExecutor.cpp index 5c5ffbc7c..4565d1aec 100644 --- a/src/slic3r/GUI/ScriptExecutor.cpp +++ b/src/slic3r/GUI/ScriptExecutor.cpp @@ -758,6 +758,7 @@ std::string get_type_name(ConfigOptionType type) default: return ""; } } + void ScriptContainer::call_script_function_set(const ConfigOptionDef& def, const boost::any& value) { if (value.empty() || !is_intialized()) @@ -828,7 +829,7 @@ void ScriptContainer::call_script_function_set(const ConfigOptionDef& def, const m_to_update[tab->type()] = {}; m_can_set = true; // exec - int res = ctx->Execute(); + /*int res = */ctx->Execute(); m_can_set = false; std::map<Preset::Type, DynamicPrintConfig> to_update = m_to_update; m_to_update.clear(); @@ -867,6 +868,63 @@ void ScriptContainer::call_script_function_set(const ConfigOptionDef& def, const } } } + +bool ScriptContainer::call_script_function_reset(const ConfigOptionDef& def) +{ + std::string func_name = ("void " + def.opt_key + "_reset()"); + AngelScript::asIScriptFunction* func = m_script_module->GetFunctionByDecl(func_name.c_str()); + if (func == nullptr) { + return false; + } + AngelScript::asIScriptContext* ctx = m_script_engine->CreateContext(); + if (ctx == nullptr) { + BOOST_LOG_TRIVIAL(error) << "Error, can't create script context for function '" << func_name << "'"; + return false; + } + ctx->Prepare(func); + m_can_set = true; + // exec + /*int res = */ctx->Execute(); + m_can_set = false; + std::map<Preset::Type, DynamicPrintConfig> to_update = m_to_update; + m_to_update.clear(); + auto to_reset = m_to_reset_initial; + m_to_reset_initial.clear(); + + //update the tabs from the results + for (auto& data : to_update) { + Tab* tab = wxGetApp().get_tab(data.first); + //also reset + if (!to_reset.empty()) { + const DynamicPrintConfig& initial_conf = tab->m_presets->get_selected_preset().config; + for (size_t key_idx = 0; key_idx != to_reset.size(); ++key_idx) { + const std::string& key = to_reset[key_idx]; + if (initial_conf.has(key)) { + data.second.set_key_value(key, initial_conf.option(key)->clone()); + to_reset.erase(to_reset.begin() + key_idx); + key_idx--; + } + } + } + tab->load_config(data.second); + } + //also call for value_changed, as it's not really a load but a change + for (const auto& data : to_update) { + Tab* tab = wxGetApp().get_tab(data.first); + for (auto opt_key : data.second.keys()) { + tab->on_value_change(opt_key, data.second.option(opt_key)->getAny()); + } + } + // refresh the field if needed + if (m_need_refresh && m_tab) { + Field* f = m_tab->get_field(def.opt_key); + if (f != nullptr) { + f->set_value(call_script_function_get_value(def), false); + } + } + return true; +} + //void ScriptContainer::call_script_function_refresh(const std::string& def_id) //{ // std::string func_name = ("int " + def_id + "_refresh()"); diff --git a/src/slic3r/GUI/ScriptExecutor.hpp b/src/slic3r/GUI/ScriptExecutor.hpp index 41baef85b..4b6e3c079 100644 --- a/src/slic3r/GUI/ScriptExecutor.hpp +++ b/src/slic3r/GUI/ScriptExecutor.hpp @@ -53,6 +53,8 @@ public: void init(const std::string& tab_key, Tab* tab); void call_script_function_set(const ConfigOptionDef& def, const boost::any& value); void refresh(const ConfigOptionDef& def, boost::any value); + //return false if the function doesn't exists. + bool call_script_function_reset(const ConfigOptionDef& def); //void call_script_function_refresh(const std::string& def_id); boost::any call_script_function_get_value(const ConfigOptionDef& def); }; |