Browse Source

Add max_literal to setting def, to set the threshold for popup warning for float% fields
allow max, min and % of nozzle
delete % check from ConfigManipulation
supermerill/SuperSlicer#1774

supermerill 3 years ago
parent
commit
a6802bc728

+ 1 - 0
resources/ui_layout/Readme.md

@@ -47,6 +47,7 @@ each parameter is separated by ':'
 	* full_width: to tell to create a field that span the full width.
 	* sidetext$STR: the suffix at the right of the widget (like 'mm').
 	* sidetext_width$INT: the suffix label length (override the group one). -1 for auto.
+	* max_literal$INT[%]: if the user enter a value higher than that and it's a 'float or percent' field, then emit a pop-up to question if he doesn't forgot a '%'. If negative, it check if the value isn't lower than the absolute max_literal, instead of greater. If there is a '%' after the value, then it's multiplied by the biggest nozzle diameter.
 	* simple|advanced|expert: add one of these to modify the mode in which this setting appear.
 	* width$INT: change the width of the field. Shouod work on most type of settings.
 	* height$INT: change the height of the field. Don't works with every type of setting (mostly multilne text). Set to -1 to 'disable'.

+ 1 - 1
resources/ui_layout/print.ui

@@ -178,7 +178,7 @@ group:Skirt
 	setting:skirts
 	line:Distance
 		setting:skirt_distance
-		setting:label$from brim:sidetext$else from object:skirt_distance_from_brim
+		setting:label$from brim:skirt_distance_from_brim
 	end_line
 	setting:skirt_height
 	setting:draft_shield

+ 2 - 0
src/libslic3r/Config.hpp

@@ -1840,6 +1840,8 @@ public:
     // By setting min=0, only nonnegative input is allowed.
     double                              min             = INT_MIN;
     double                              max             = INT_MAX;
+    // To check if it's not a typo and a % is missing
+    FloatOrPercent                      max_literal     = FloatOrPercent{ 0., false };
     // max precision after the dot, only for display
     int                                 precision       = 6;
     ConfigOptionMode                    mode            = comSimple;

+ 47 - 0
src/libslic3r/PrintConfig.cpp

@@ -320,6 +320,7 @@ void PrintConfigDef::init_fff_params()
     def->sidetext = L("mm/s² or %");
     def->ratio_over = "default_acceleration";
     def->min = 0;
+    def->max_literal = { -220, false };
     def->mode = comExpert;
     def->set_default_value(new ConfigOptionFloatOrPercent(0,false));
 
@@ -663,6 +664,7 @@ void PrintConfigDef::init_fff_params()
     def->sidetext = L("mm/s² or %");
     def->ratio_over = "machine_max_acceleration_X";
     def->min = 0;
+    def->max_literal = { -200, false };
     def->mode = comExpert;
     def->set_default_value(new ConfigOptionFloatOrPercent(0,false));
 
@@ -855,6 +857,7 @@ void PrintConfigDef::init_fff_params()
     def->sidetext = L("mm/%");
     def->ratio_over = "perimeter_extrusion_width";
     def->min = 0;
+    def->max_literal = { 50, true };
     def->mode = comExpert;
     def->set_default_value(new ConfigOptionFloatOrPercent(150, true));
 
@@ -866,6 +869,7 @@ void PrintConfigDef::init_fff_params()
     def->sidetext = L("mm/%");
     def->ratio_over = "external_perimeter_extrusion_width";
     def->min = 0;
+    def->max_literal = { 50, true };
     def->mode = comExpert;
     def->set_default_value(new ConfigOptionFloatOrPercent(200, true));
 
@@ -881,6 +885,7 @@ void PrintConfigDef::init_fff_params()
     def->ratio_over = "nozzle_diameter";
     def->min = 0;
     def->max = 1000;
+    def->max_literal = { 10, true };
     def->precision = 6;
     def->can_phony = true;
     def->mode = comAdvanced;
@@ -897,6 +902,7 @@ void PrintConfigDef::init_fff_params()
     def->ratio_over = "nozzle_diameter";
     def->min = 0;
     def->max = 1000;
+    def->max_literal = { 10, true };
     def->precision = 6;
     def->can_phony = true;
     def->mode = comAdvanced;
@@ -1246,6 +1252,7 @@ void PrintConfigDef::init_fff_params()
     def->ratio_over = "nozzle_diameter";
     def->min = 0;
     def->max = 1000;
+    def->max_literal = { 10, true };
     def->precision = 6;
     def->can_phony = true;
     def->mode = comAdvanced;
@@ -1260,6 +1267,7 @@ void PrintConfigDef::init_fff_params()
     def->ratio_over = "nozzle_diameter";
     def->min = 0;
     def->max = 1000;
+    def->max_literal = { 10, true };
     def->precision = 6;
     def->can_phony = true;
     def->mode = comAdvanced;
@@ -1842,6 +1850,7 @@ void PrintConfigDef::init_fff_params()
         " A value too low will make your extruder eat the filament.");
     def->ratio_over = "top_infill_extrusion_width";
     def->min = 0;
+    def->max_literal = { 1, true };
     def->mode = comExpert;
     def->sidetext = L("mm/%");
     def->set_default_value(new ConfigOptionFloatOrPercent(50, true));
@@ -1869,6 +1878,7 @@ void PrintConfigDef::init_fff_params()
     def->sidetext = L("mm/s² or %");
     def->ratio_over = "default_acceleration";
     def->min = 0;
+    def->max_literal = { -200, false };
     def->mode = comExpert;
     def->set_default_value(new ConfigOptionFloatOrPercent(0, false));
 
@@ -1898,6 +1908,7 @@ void PrintConfigDef::init_fff_params()
     def->ratio_over = "nozzle_diameter";
     def->min = 0;
     def->max = 1000;
+    def->max_literal = { 10, true };
     def->precision = 6;
     def->can_phony = true;
     def->mode = comAdvanced;
@@ -1913,6 +1924,7 @@ void PrintConfigDef::init_fff_params()
     def->ratio_over = "nozzle_diameter";
     def->min = 0;
     def->max = 1000;
+    def->max_literal = { 10, true };
     def->precision = 6;
     def->can_phony = true;
     def->mode = comAdvanced;
@@ -1928,6 +1940,7 @@ void PrintConfigDef::init_fff_params()
     def->sidetext = L("mm or %");
     def->ratio_over = "nozzle_diameter";
     def->min = 0;
+    def->max_literal = { 20, false };
     def->mode = comAdvanced;
     def->set_default_value(new ConfigOptionFloatOrPercent(75, true));
 
@@ -2150,6 +2163,7 @@ void PrintConfigDef::init_fff_params()
     def->sidetext = L("mm/s² or %");
     def->ratio_over = "default_acceleration";
     def->min = 0;
+    def->max_literal = { -200, false };
     def->mode = comExpert;
     def->set_default_value(new ConfigOptionFloatOrPercent(0,false));
 
@@ -2202,6 +2216,7 @@ void PrintConfigDef::init_fff_params()
     def->ratio_over  = def_infill_anchor_min->ratio_over;
     def->gui_type    = def_infill_anchor_min->gui_type;
     def->enum_values = def_infill_anchor_min->enum_values;
+    def->max_literal = def_infill_anchor_min->max_literal;
     def->enum_labels.push_back(L("0 (Simple connect)"));
     def->enum_labels.push_back("1 mm");
     def->enum_labels.push_back("2 mm");
@@ -2332,6 +2347,7 @@ void PrintConfigDef::init_fff_params()
     def->ratio_over = "nozzle_diameter";
     def->min = 0;
     def->max = 1000;
+    def->max_literal = { 10, true };
     def->precision = 6;
     def->can_phony = true;
     def->mode = comAdvanced;
@@ -2347,6 +2363,7 @@ void PrintConfigDef::init_fff_params()
     def->ratio_over = "nozzle_diameter";
     def->min = 0;
     def->max = 1000;
+    def->max_literal = { 10, true };
     def->precision = 6;
     def->can_phony = true;
     def->mode = comAdvanced;
@@ -2376,6 +2393,8 @@ void PrintConfigDef::init_fff_params()
                    "as percentage (example: 15%) it is calculated over perimeter extrusion width.");
     def->sidetext = L("mm or %");
     def->ratio_over = "perimeter_extrusion_width";
+    def->min = 0;
+    def->max_literal = { 1, true };
     def->mode = comExpert;
     def->set_default_value(new ConfigOptionFloatOrPercent(25, true));
 
@@ -2744,6 +2763,7 @@ void PrintConfigDef::init_fff_params()
     def->sidetext = L("mm or %");
     def->ratio_over = "nozzle_diameter";
     def->min = 0;
+    def->max_literal = { 10, false };
     def->mode = comSimple;
     def->is_vector_extruder = true;
     def->set_default_value(new ConfigOptionFloatsOrPercents{ FloatOrPercent{ 75, true} });
@@ -2836,6 +2856,7 @@ void PrintConfigDef::init_fff_params()
     def->sidetext = L("mm or %");
     def->ratio_over = "nozzle_diameter";
     def->min = 0;
+    def->max_literal = { 5, false };
     def->mode = comSimple;
     def->is_vector_extruder = true;
     def->set_default_value(new ConfigOptionFloatsOrPercents{ FloatOrPercent{ 5, true} });
@@ -2861,6 +2882,7 @@ void PrintConfigDef::init_fff_params()
     def->sidetext = L("mm or %");
     def->ratio_over = "perimeter_extrusion_width";
     def->min = 0;
+    def->max_literal = { 15, false };
     def->mode = comExpert;
     def->set_default_value(new ConfigOptionFloatOrPercent(200, true));
 
@@ -3011,6 +3033,7 @@ void PrintConfigDef::init_fff_params()
         " Set to 0 to deactivate.");
     def->ratio_over = "nozzle_diameter";
     def->min = 0;
+    def->max_literal = { 10, true };
     def->mode = comExpert;
     def->set_default_value(new ConfigOptionFloatOrPercent(75, true));
 
@@ -3030,6 +3053,7 @@ void PrintConfigDef::init_fff_params()
     def->tooltip = L("Number of mm the overhang need to be for the reversal to be considered useful. Can be a % of the perimeter width.");
     def->ratio_over = "perimeter_extrusion_width";
     def->min = 0;
+    def->max_literal = { 20, false };
     def->mode = comAdvanced;
     def->set_default_value(new ConfigOptionFloatOrPercent(250, true));
 
@@ -3085,6 +3109,7 @@ void PrintConfigDef::init_fff_params()
     def->sidetext = L("mm/s² or %");
     def->ratio_over = "default_acceleration";
     def->min = 0;
+    def->max_literal = { -200, false };
     def->mode = comExpert;
     def->set_default_value(new ConfigOptionFloatOrPercent(0,false));
 
@@ -3120,6 +3145,7 @@ void PrintConfigDef::init_fff_params()
     def->aliases = { "perimeters_extrusion_width" };
     def->min = 0;
     def->max = 1000;
+    def->max_literal = { 10, true };
     def->precision = 6;
     def->can_phony = true;
     def->mode = comAdvanced;
@@ -3135,6 +3161,7 @@ void PrintConfigDef::init_fff_params()
     def->aliases = { "perimeters_extrusion_width" };
     def->min = 0;
     def->max = 1000;
+    def->max_literal = { 10, true };
     def->precision = 6;
     def->can_phony = true;
     def->mode = comAdvanced;
@@ -3455,6 +3482,7 @@ void PrintConfigDef::init_fff_params()
                     "\nCan be a mm or a % of the current extruder diameter.");
     def->sidetext = L("mm or %");
     def->min = 0;
+    def->max_literal = { 5, false };
     def->mode = comExpert;
     def->is_vector_extruder = true;
     def->set_default_value(new ConfigOptionFloatsOrPercents{ FloatOrPercent{15,true} });
@@ -3528,6 +3556,7 @@ void PrintConfigDef::init_fff_params()
     def->sidetext = L("mm or %");
     def->min = 0;
     def->max = 1000;
+    def->max_literal = { 10, true };
     def->precision = 6;
     def->mode = comAdvanced;
     def->set_default_value(new ConfigOptionFloatOrPercent(0, false));
@@ -3578,6 +3607,7 @@ void PrintConfigDef::init_fff_params()
     def->sidetext = L("mm or %");
     def->ratio_over = "nozzle_diameter";
     def->min = 0;
+    def->max_literal = { 100, false };
     def->mode = comAdvanced;
     def->set_default_value(new ConfigOptionFloatOrPercent(6, false));
 
@@ -3592,6 +3622,7 @@ void PrintConfigDef::init_fff_params()
     def->sidetext = L("mm or %");
     def->ratio_over = "nozzle_diameter";
     def->min = 0;
+    def->max_literal = { 500, false };
     def->mode = comAdvanced;
     def->set_default_value(new ConfigOptionFloatOrPercent(20, false));
 
@@ -3692,6 +3723,7 @@ void PrintConfigDef::init_fff_params()
     def->ratio_over = "nozzle_diameter";
     def->min = 0;
     def->max = 1000;
+    def->max_literal = { 10, true };
     def->precision = 6;
     def->can_phony = true;
     def->mode = comAdvanced;
@@ -3707,6 +3739,7 @@ void PrintConfigDef::init_fff_params()
     def->ratio_over = "nozzle_diameter";
     def->min = 0;
     def->max = 1000;
+    def->max_literal = { 10, true };
     def->precision = 6;
     def->can_phony = true;
     def->mode = comAdvanced;
@@ -3909,6 +3942,7 @@ void PrintConfigDef::init_fff_params()
     def->sidetext = L("mm or %");
     def->ratio_over = "external_perimeter_extrusion_width";
     def->min = 0;
+    def->max_literal = { 10, false};
     def->mode = comAdvanced;
     // Default is half the external perimeter width.
     def->set_default_value(new ConfigOptionFloatOrPercent(50, true));
@@ -3960,6 +3994,7 @@ void PrintConfigDef::init_fff_params()
     def->ratio_over = "top_infill_extrusion_width";
     def->sidetext = L("mm");
     def->min = 0;
+    def->max_literal = { 20, true };
     def->mode = comAdvanced;
     def->aliases = { "support_material_contact_distance" };
     def->set_default_value(new ConfigOptionFloatOrPercent(0.2, false));
@@ -3973,6 +4008,7 @@ void PrintConfigDef::init_fff_params()
     def->ratio_over = "top_infill_extrusion_width";
     def->sidetext = L("mm");
     def->min = 0;
+    def->max_literal = { 20, true };
     def->mode = comAdvanced;
     def->set_default_value(new ConfigOptionFloatOrPercent(0.2,false));
 
@@ -4009,6 +4045,7 @@ void PrintConfigDef::init_fff_params()
     def->ratio_over = "nozzle_diameter";
     def->min = 0;
     def->max = 1000;
+    def->max_literal = { 10, true };
     def->precision = 6;
     def->mode = comAdvanced;
     def->set_default_value(new ConfigOptionFloatOrPercent(0, false));
@@ -4210,6 +4247,7 @@ void PrintConfigDef::init_fff_params()
     def->ratio_over = "nozzle_diameter";
     def->mode = comExpert;
     def->min = 0;
+    def->max_literal = { 20, true };
     def->set_default_value(new ConfigOptionFloatOrPercent(33, true));
 
     def = this->add("thin_walls_overlap", coFloatOrPercent);
@@ -4220,6 +4258,7 @@ void PrintConfigDef::init_fff_params()
     def->ratio_over = "external_perimeter_extrusion_width";
     def->mode = comExpert;
     def->min = 0;
+    def->max_literal = { 10, true };
     def->set_default_value(new ConfigOptionFloatOrPercent(50, true));
 
     def = this->add("thin_walls_merge", coBool);
@@ -4296,6 +4335,7 @@ void PrintConfigDef::init_fff_params()
     def->ratio_over = "nozzle_diameter";
     def->min = 0;
     def->max = 1000;
+    def->max_literal = { 10, true };
     def->precision = 6;
     def->can_phony = true;
     def->mode = comAdvanced;
@@ -4310,6 +4350,7 @@ void PrintConfigDef::init_fff_params()
     def->ratio_over = "nozzle_diameter";
     def->min = 0;
     def->max = 1000;
+    def->max_literal = { 10, true };
     def->precision = 6;
     def->can_phony = true;
     def->mode = comAdvanced;
@@ -4361,6 +4402,7 @@ void PrintConfigDef::init_fff_params()
     def->sidetext = L("mm/s² or %");
     def->ratio_over = "default_acceleration";
     def->min = 0;
+    def->max_literal = { -200, false };
     def->mode = comExpert;
     def->set_default_value(new ConfigOptionFloatOrPercent(1500, false));
 
@@ -4520,6 +4562,8 @@ void PrintConfigDef::init_fff_params()
     def->tooltip = L("Width of the brim for the wipe tower. Can be in mm or in % of the (assumed) only one nozzle diameter.");
     def->ratio_over = "nozzle_diameter";
     def->mode = comAdvanced;
+    def->min = 0;
+    def->max_literal = { 100, true };
     def->set_default_value(new ConfigOptionFloatOrPercent(150,true));
 
     def = this->add("wipe_tower_x", coFloat);
@@ -4652,6 +4696,7 @@ void PrintConfigDef::init_fff_params()
         " This setting allows you some leway to broaden the detection."
         "\nIn mm or in % of the radius.");
     def->sidetext = L("mm or %");
+    def->max_literal = { 10, false};
     def->mode = comExpert;
     def->set_default_value(new ConfigOptionFloatOrPercent(0.01, false));
 
@@ -4877,6 +4922,7 @@ void PrintConfigDef::init_milling_params()
         " You can set a number of mm or a percentage of the calculated optimal extra width (from flow calculation).");
     def->sidetext = L("mm or %");
     def->ratio_over = "computed_on_the_fly";
+    def->max_literal = { 20, false };
     def->mode = comAdvanced;
     def->set_default_value(new ConfigOptionFloatOrPercent(150, true));
 
@@ -4886,6 +4932,7 @@ void PrintConfigDef::init_milling_params()
     def->tooltip = L("This setting restricts the post-process milling to a certain height, to avoid milling the bed. It can be a mm or a % of the first layer height (so it can depend on the object).");
     def->sidetext = L("mm or %");
     def->ratio_over = "first_layer_height";
+    def->max_literal = { 10, false };
     def->mode = comAdvanced;
     def->set_default_value(new ConfigOptionFloatOrPercent(200, true));
 

+ 0 - 36
src/slic3r/GUI/ConfigManipulation.cpp

@@ -210,42 +210,6 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
         apply(config, &new_conf);
     }
 
-    // check forgotten '%'
-    {
-        struct optDescr {
-            ConfigOptionFloatOrPercent* opt;
-            std::string name;
-            float min;
-            float max;
-        };
-        float diameter = 0.4f;
-        if (config->option<ConfigOptionFloatOrPercent>("extrusion_width")->percent) {
-            //has to be percent
-            diameter = 0;
-        } else {
-            diameter = config->option<ConfigOptionFloatOrPercent>("extrusion_width")->value;
-        }
-        std::vector<optDescr> opts;
-        opts.push_back({ config->option<ConfigOptionFloatOrPercent>("infill_overlap"), "infill_overlap", 0, diameter * 10 });
-        for (int i = 0; i < opts.size(); i++) {
-            if ((!opts[i].opt->percent) && (opts[i].opt->get_abs_value(diameter) < opts[i].min || opts[i].opt->get_abs_value(diameter) > opts[i].max)) {
-                wxString msg_text = _(L("Did you forgot to put a '%' in the " + opts[i].name + " field? "
-                    "it's currently set to " + std::to_string(opts[i].opt->get_abs_value(diameter)) + " mm."));
-                if (is_global_config) {
-                    msg_text += "\n\n" + _(L("Shall I add the '%'?"));
-                    wxMessageDialog dialog(nullptr, msg_text, _(L("Wipe Tower")),
-                        wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
-                    DynamicPrintConfig new_conf = *config;
-                    auto answer = dialog.ShowModal();
-                    if (answer == wxID_YES) {
-                        new_conf.set_key_value(opts[i].name, new ConfigOptionFloatOrPercent(opts[i].opt->value * 100, true));
-                        apply(config, &new_conf);
-                    }
-                }
-            }
-        }
-    }
-
     // check changes from FloatOrPercent to percent (useful to migrate config from prusa to Slic3r)
     {
         std::vector<std::string> names;

+ 58 - 35
src/slic3r/GUI/Field.cpp

@@ -405,45 +405,68 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true
                     show_error(m_parent, _(L("Input value is out of range")));
                     if (m_opt.min > val) val = m_opt.min;
                     set_value(double_to_string(val, m_opt.precision), true);
-                } else if (((m_opt.sidetext.rfind("mm/s") != std::string::npos && val > m_opt.max) ||
-                    (m_opt.sidetext.rfind("mm ") != std::string::npos && val > 1)) &&
-                    (m_value.empty() || std::string(str.ToUTF8().data()) != boost::any_cast<std::string>(m_value)))
-                {
-                    // exceptions
-                    if (std::set<t_config_option_key>{"infill_anchor", "infill_anchor_max", "avoid_crossing_perimeters_max_detour"}.count(m_opt.opt_key) > 0) {
-                        m_value = std::string(str.ToUTF8().data());
-                        break;
-                    }
-                    if (m_opt.opt_key.find("extrusion_width") != std::string::npos || m_opt.opt_key.find("extrusion_spacing") != std::string::npos) {
-                        const DynamicPrintConfig& printer_config = wxGetApp().preset_bundle->printers.get_edited_preset().config;
-                        const std::vector<double>& nozzle_diameters = printer_config.option<ConfigOptionFloats>("nozzle_diameter")->values;
-                        double nozzle_diameter = 0;
-                        for (double diameter : nozzle_diameters)
-                            nozzle_diameter = std::max(nozzle_diameter, diameter);
-                        if (val < nozzle_diameter * 10) {
-                            m_value = std::string(str.ToUTF8().data());
+                } else if (m_value.empty() || std::string(str.ToUTF8().data()) != boost::any_cast<std::string>(m_value)) {
+                    bool not_ok = (m_opt.sidetext.rfind("mm/s") != std::string::npos && val > m_opt.max);
+                    if( !not_ok && m_opt.max_literal.value != 0 )
+                        if (m_opt.max_literal.percent) {
+                            const DynamicPrintConfig& printer_config = wxGetApp().preset_bundle->printers.get_edited_preset().config;
+                            const std::vector<double>& nozzle_diameters = printer_config.option<ConfigOptionFloats>("nozzle_diameter")->values;
+                            double nozzle_diameter = 0;
+                            for (double diameter : nozzle_diameters)
+                                nozzle_diameter = std::max(nozzle_diameter, diameter);
+                            if (m_opt.max_literal.value > 0)
+                                not_ok = val > nozzle_diameter * m_opt.max_literal.value;
+                            else
+                                not_ok = val < nozzle_diameter * (-m_opt.max_literal.value);
+                        }else{
+                            if(m_opt.max_literal.value > 0)
+                                not_ok = val > m_opt.max_literal.value;
+                            else
+                                not_ok = val < -m_opt.max_literal.value;
+                        }
+                    if (not_ok) {
+
+                        //    if (
+                        //    (
+                        //        (m_opt.sidetext.rfind("mm/s") != std::string::npos && val > m_opt.max) 
+                        //        || 
+                        //        (m_opt.sidetext.rfind("mm ") != std::string::npos && val > m_opt.max_literal)
+                        //    ) 
+                        //    &&
+                        //        (m_value.empty() || std::string(str.ToUTF8().data()) != boost::any_cast<std::string>(m_value)))
+                        //{
+                        //    if (m_opt.opt_key.find("extrusion_width") != std::string::npos || m_opt.opt_key.find("extrusion_spacing") != std::string::npos) {
+                        //        const DynamicPrintConfig& printer_config = wxGetApp().preset_bundle->printers.get_edited_preset().config;
+                        //        const std::vector<double>& nozzle_diameters = printer_config.option<ConfigOptionFloats>("nozzle_diameter")->values;
+                        //        double nozzle_diameter = 0;
+                        //        for (double diameter : nozzle_diameters)
+                        //            nozzle_diameter = std::max(nozzle_diameter, diameter);
+                        //        if (val < nozzle_diameter * 10) {
+                        //            m_value = std::string(str.ToUTF8().data());
+                        //            break;
+                        //        }
+                        //    }
+                            //TODO: chack for infill_overlap from diameter% => allow max_literal to be a %
+
+                        if (!check_value) {
+                            m_value.clear();
                             break;
                         }
-                    }
 
-                    if (!check_value) {
-                        m_value.clear();
-                        break;
+                        bool infill_anchors = m_opt.opt_key == "infill_anchor" || m_opt.opt_key == "infill_anchor_max";
+
+                        const std::string sidetext = m_opt.sidetext.rfind("mm/s") != std::string::npos ? "mm/s" : "mm";
+                        const wxString stVal = double_to_string(val, m_opt.precision);
+                        const wxString msg_text = from_u8((boost::format(_utf8(L("Do you mean %s%% instead of %s %s?\n"
+                            "Select YES if you want to change this value to %s%%, \n"
+                            "or NO if you are sure that %s %s is a correct value."))) % stVal % stVal % sidetext % stVal % stVal % sidetext).str());
+                        wxMessageDialog dialog(m_parent, msg_text, _(L("Parameter validation")) + ": " + m_opt_id, wxICON_WARNING | wxYES | wxNO);
+                        if ((!infill_anchors || val > 100) && dialog.ShowModal() == wxID_YES) {
+                            set_value(from_u8((boost::format("%s%%") % stVal).str()), false/*true*/);
+                            str += "%%";
+                        } else
+                            set_value(stVal, false); // it's no needed but can be helpful, when inputted value contained "," instead of "."
                     }
-
-                    bool infill_anchors = m_opt.opt_key == "infill_anchor" || m_opt.opt_key == "infill_anchor_max";
-
-                    const std::string sidetext = m_opt.sidetext.rfind("mm/s") != std::string::npos ? "mm/s" : "mm";
-                    const wxString stVal = double_to_string(val, m_opt.precision);
-                    const wxString msg_text = from_u8((boost::format(_utf8(L("Do you mean %s%% instead of %s %s?\n"
-                        "Select YES if you want to change this value to %s%%, \n"
-                        "or NO if you are sure that %s %s is a correct value."))) % stVal % stVal % sidetext % stVal % stVal % sidetext).str());
-                    wxMessageDialog dialog(m_parent, msg_text, _(L("Parameter validation")) + ": " + m_opt_id, wxICON_WARNING | wxYES | wxNO);
-                    if ((!infill_anchors || val > 100) && dialog.ShowModal() == wxID_YES) {
-                        set_value(from_u8((boost::format("%s%%") % stVal).str()), false/*true*/);
-                        str += "%%";
-                    } else
-                        set_value(stVal, false); // it's no needed but can be helpful, when inputted value contained "," instead of "."
                 }
             }
         }

+ 7 - 0
src/slic3r/GUI/Tab.cpp

@@ -1887,6 +1887,13 @@ bool Tab::create_pages(std::string setting_type_name, int idx_page)
                     option.opt.tooltip = (params[i].substr(8, params[i].size() - 8));
                     need_to_notified_search = true;
                 }
+                else if (boost::starts_with(params[i], "max_literal$"))
+                {
+                    if(params[i].back() == '%')
+                        option.opt.max_literal = { boost::lexical_cast<double>(params[i].substr(12, params[i].size() - 13).c_str()), true };
+                    else
+                        option.opt.max_literal = { boost::lexical_cast<double>(params[i].substr(12, params[i].size() - 12).c_str()), false };
+                }
             }
 
             if (need_to_notified_search)