Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsupermerill <merill@free.fr>2022-08-09 22:25:22 +0300
committersupermerill <merill@free.fr>2022-08-11 00:56:51 +0300
commited22e605c20332a7b4c6ca7ce2487b08025cc29a (patch)
treee170f2f688fe8df2b9ce193455ad5003efb614ce
parent16db2fd49218b9268fb759772792572ced351878 (diff)
Allow reset function for scripted widget
updated doc in readme supermerill/SuperSlicer#2930
-rw-r--r--resources/ui_layout/Readme.md82
-rw-r--r--resources/ui_layout/default/print.as81
-rw-r--r--src/slic3r/GUI/OptionsGroup.cpp48
-rw-r--r--src/slic3r/GUI/ScriptExecutor.cpp60
-rw-r--r--src/slic3r/GUI/ScriptExecutor.hpp2
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);
};