diff --git a/resources/ui_layout/Readme.md b/resources/ui_layout/Readme.md index ce59794a5..16556604a 100644 --- a/resources/ui_layout/Readme.md +++ b/resources/ui_layout/Readme.md @@ -41,6 +41,7 @@ each parameter is separated by ':' * STR, the last parameter: the id name of the setting. * label$STR: to override the label by this new one (if it ends with '_' it won't have a ':' ; if empty it won't have a length). * label_width$INT: change the width of the label. Only works if it's in a line. Override the group one. -1 for auto. + * full_label$STR: to override the full_label by this new one (full_label is used on modifiers). * full_label: to override the label by the "full one". * 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'). @@ -48,6 +49,7 @@ each parameter is separated by ':' * 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. + * precision$INT: number of digit after the dot displayed. * url$STR: the url to call when clicking on it. * id $INT: for setting only a single value of a setting array. * idx: for setting only a single value of a setting array, with the index of the page (for extruder ui page) diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp index 35010af25..058bebeb6 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -1696,6 +1696,8 @@ public: // By setting min=0, only nonnegative input is allowed. double min = INT_MIN; double max = INT_MAX; + // max precision after the dot, only for display + int precision = 6; ConfigOptionMode mode = comSimple; // Legacy names for this configuration option. // Used when parsing legacy configuration file. diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 567bc7435..a9559f49d 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -136,6 +136,7 @@ void PrintConfigDef::init_common_params() "The gap closing operation may reduce the final print resolution, therefore it is advisable to keep the value reasonably low."); def->sidetext = L("mm"); def->min = 0; + def->precision = 8; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0.049)); @@ -835,6 +836,8 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm or %"); def->ratio_over = "nozzle_diameter"; def->min = 0; + def->max = 1000; + def->precision = 6; def->can_phony = true; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(0, false)); @@ -849,6 +852,8 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm or %"); def->ratio_over = "nozzle_diameter"; def->min = 0; + def->max = 1000; + def->precision = 6; def->can_phony = true; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(0, false, true)); @@ -1168,6 +1173,7 @@ void PrintConfigDef::init_fff_params() def->ratio_over = "nozzle_diameter"; def->min = 0; def->max = 1000; + def->precision = 6; def->can_phony = true; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(0, false)); @@ -1181,6 +1187,7 @@ void PrintConfigDef::init_fff_params() def->ratio_over = "nozzle_diameter"; def->min = 0; def->max = 1000; + def->precision = 6; def->can_phony = true; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(0, false, true)); @@ -1753,6 +1760,7 @@ void PrintConfigDef::init_fff_params() def->ratio_over = "nozzle_diameter"; def->min = 0; def->max = 1000; + def->precision = 6; def->can_phony = true; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(140, true)); @@ -1767,6 +1775,7 @@ void PrintConfigDef::init_fff_params() def->ratio_over = "nozzle_diameter"; def->min = 0; def->max = 1000; + def->precision = 6; def->can_phony = true; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(0, false, true)); @@ -2149,6 +2158,7 @@ void PrintConfigDef::init_fff_params() def->ratio_over = "nozzle_diameter"; def->min = 0; def->max = 1000; + def->precision = 6; def->can_phony = true; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(0, false)); @@ -2163,6 +2173,7 @@ void PrintConfigDef::init_fff_params() def->ratio_over = "nozzle_diameter"; def->min = 0; def->max = 1000; + def->precision = 6; def->can_phony = true; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(0, false, true)); @@ -2624,6 +2635,7 @@ void PrintConfigDef::init_fff_params() "\n0 to disable."); def->sidetext = L("mm"); def->min = 0; + def->precision = 8; def->mode = comExpert; def->set_default_value(new ConfigOptionFloat(0.035)); @@ -2888,6 +2900,7 @@ void PrintConfigDef::init_fff_params() def->aliases = { "perimeters_extrusion_width" }; def->min = 0; def->max = 1000; + def->precision = 6; def->can_phony = true; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(0, false)); @@ -2902,6 +2915,7 @@ void PrintConfigDef::init_fff_params() def->aliases = { "perimeters_extrusion_width" }; def->min = 0; def->max = 1000; + def->precision = 6; def->can_phony = true; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(0, false, true)); @@ -3013,6 +3027,7 @@ void PrintConfigDef::init_fff_params() "\nInfill & Thin areas are simplified up to 0.0125mm."); def->sidetext = L("mm"); def->min = 0; + def->precision = 8; def->mode = comExpert; def->set_default_value(new ConfigOptionFloat(0.002)); @@ -3244,9 +3259,10 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Horizontal width of the skirt that will be printed around each object." " If left zero, first layer extrusion width will be used if set and the skirt is only 1 layer height" ", or perimeter extrusion width will be used (using the computed value if not set)."); - def->sidetext = L("mm"); + def->sidetext = L("mm or %"); def->min = 0; def->max = 1000; + def->precision = 6; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(0, false)); @@ -3359,6 +3375,7 @@ void PrintConfigDef::init_fff_params() "\nIt's really only useful to smoothen functional models or very wide angles."); def->sidetext = L("mm"); def->min = 0; + def->precision = 8; def->cli = "curve-smoothing-precision=f"; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0)); @@ -3415,6 +3432,7 @@ void PrintConfigDef::init_fff_params() def->ratio_over = "nozzle_diameter"; def->min = 0; def->max = 1000; + def->precision = 6; def->can_phony = true; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(0, false)); @@ -3429,6 +3447,7 @@ void PrintConfigDef::init_fff_params() def->ratio_over = "nozzle_diameter"; def->min = 0; def->max = 1000; + def->precision = 6; def->can_phony = true; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(0, false, true)); @@ -3535,6 +3554,7 @@ void PrintConfigDef::init_fff_params() " Put 0 to disable."); def->sidetext = L("mm"); def->min = 0; + def->precision = 8; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0.0001)); @@ -3710,6 +3730,7 @@ void PrintConfigDef::init_fff_params() def->ratio_over = "nozzle_diameter"; def->min = 0; def->max = 1000; + def->precision = 6; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(0, false)); @@ -3994,6 +4015,7 @@ void PrintConfigDef::init_fff_params() def->ratio_over = "nozzle_diameter"; def->min = 0; def->max = 1000; + def->precision = 6; def->can_phony = true; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(0, false)); @@ -4007,6 +4029,7 @@ void PrintConfigDef::init_fff_params() def->ratio_over = "nozzle_diameter"; def->min = 0; def->max = 1000; + def->precision = 6; def->can_phony = true; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(0, false, true)); @@ -4348,6 +4371,7 @@ void PrintConfigDef::init_fff_params() def->cli = "z-step=f"; def->sidetext = L("mm"); def->min = 0; + def->precision = 8; def->mode = comExpert; def->set_default_value(new ConfigOptionFloat(0.005)); @@ -5840,6 +5864,7 @@ bool DynamicPrintConfig::update_phony(const std::vector spacing conversion is done via float, so max 6-7 digit of precision. bool DynamicPrintConfig::value_changed(const t_config_option_key& opt_key, const std::vector config_collection) { if (opt_key == "layer_height") { diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index d5619d465..e54519c70 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -26,7 +26,7 @@ namespace Slic3r { namespace GUI { -wxString double_to_string(double const value, const int max_precision /*= 8*/) +wxString double_to_string(double const value, const int max_precision /*= 6*/) { // Style_NoTrailingZeroes does not work on OSX. It also does not work correctly with some locales on Windows. // return wxNumberFormatter::ToString(value, max_precision, wxNumberFormatter::Style_NoTrailingZeroes); @@ -240,7 +240,7 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true wxString label = m_opt.full_label.empty() ? _(m_opt.label) : _(m_opt.full_label); show_error(m_parent, from_u8((boost::format(_utf8(L("%s doesn't support percentage"))) % label).str())); - set_value(double_to_string(m_opt.min), true); + set_value(double_to_string(m_opt.min, m_opt.precision), true); m_value = double(m_opt.min); break; } @@ -260,7 +260,7 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true break; } show_error(m_parent, _(L("Invalid numeric input."))); - set_value(double_to_string(val), true); + set_value(double_to_string(val, m_opt.precision), true); } if (m_opt.min > val || val > m_opt.max) { @@ -280,7 +280,7 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true } else val = boost::any_cast(m_value); - set_value(double_to_string(val), true); + set_value(double_to_string(val, m_opt.precision), true); } } } @@ -288,7 +288,7 @@ 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; if (val > m_opt.max) val = m_opt.max; - set_value(double_to_string(val), true); + set_value(double_to_string(val, m_opt.precision), true); } } } @@ -314,7 +314,7 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true break; } show_error(m_parent, _(L("Invalid numeric input."))); - set_value(double_to_string(val), true); + set_value(double_to_string(val, m_opt.precision), true); } else { //at least check min, as we can want a 0 min @@ -326,7 +326,7 @@ 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), true); + 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(m_value))) @@ -356,7 +356,7 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true 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, 2); + 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()); @@ -456,14 +456,14 @@ void TextCtrl::BUILD() { switch (m_opt.type) { case coFloatOrPercent: { - text_value = double_to_string(m_opt.default_value->getFloat()); + text_value = double_to_string(m_opt.default_value->getFloat(), m_opt.precision); if (m_opt.get_default_value()->percent) text_value += "%"; break; } case coPercent: { - text_value = double_to_string(m_opt.default_value->getFloat()); + text_value = double_to_string(m_opt.default_value->getFloat(), m_opt.precision); text_value += "%"; break; } @@ -476,7 +476,7 @@ void TextCtrl::BUILD() { m_opt.type == coFloat ? m_opt.default_value->getFloat() : m_opt.get_default_value()->get_at(m_opt_idx); - text_value = double_to_string(val); + text_value = double_to_string(val, m_opt.precision); m_last_meaningful_value = text_value; break; } @@ -1082,7 +1082,7 @@ void Choice::set_selection() break; } case coFloatOrPercent: { - text_value = double_to_string(m_opt.default_value->getFloat()); + text_value = double_to_string(m_opt.default_value->getFloat(), m_opt.precision); if (m_opt.get_default_value()->percent) text_value += "%"; break; diff --git a/src/slic3r/GUI/Field.hpp b/src/slic3r/GUI/Field.hpp index 42aaa5372..bd38dc649 100644 --- a/src/slic3r/GUI/Field.hpp +++ b/src/slic3r/GUI/Field.hpp @@ -36,7 +36,7 @@ using t_kill_focus = std::function; using t_change = std::function; using t_back_to_init = std::function; -wxString double_to_string(double const value, const int max_precision = 8); +wxString double_to_string(double const value, const int max_precision = 6); wxString get_points_string(const std::vector& values); class Field { diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index 3740d7bf3..a9e3449d4 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -857,7 +857,7 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config double val = opt->type == coFloats ? config.option(opt_key)->get_at(idx) : config.option(opt_key)->get_at(idx); - ret = double_to_string(val); } + ret = double_to_string(val, opt->precision); } } break; case coBools: @@ -877,7 +877,7 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config case coFloatOrPercent:{ const auto &value = *config.option(opt_key); - text_value = double_to_string(value.value); + text_value = double_to_string(value.value, opt->precision); if (value.percent) text_value += "%"; @@ -886,7 +886,7 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config } case coPercent:{ double val = config.option(opt_key)->value; - text_value = double_to_string(val); + text_value = double_to_string(val, opt->precision); ret = text_value; } break; @@ -897,7 +897,7 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config config.opt_float(opt_key, idx) : opt->type == coFloat ? config.opt_float(opt_key) : config.option(opt_key)->get_at(idx); - ret = double_to_string(val); + ret = double_to_string(val, opt->precision); } break; case coString: diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 8daeacde0..d8f5fb359 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1798,7 +1798,7 @@ bool Tab::create_pages(std::string setting_type_name, int idx_page) option.opt.label = option.opt.full_label; need_to_notified_search = true; } - else if (params[i].find("label$") != std::string::npos) + else if (boost::starts_with(params[i], "label$")) { option.opt.label = L(params[i].substr(6, params[i].size() - 6)); need_to_notified_search = true; @@ -1806,11 +1806,11 @@ bool Tab::create_pages(std::string setting_type_name, int idx_page) else if (boost::starts_with(params[i], "label_width$")) { option.opt.label_width = atoi(params[i].substr(12, params[i].size() - 12).c_str()); } - else if (params[i].find("sidetext$") != std::string::npos) + else if (boost::starts_with(params[i], "sidetext$")) { option.opt.sidetext = L(params[i].substr(9, params[i].size() - 9)); } - else if (params[i].find("sidetext_width$") != std::string::npos) + else if (boost::starts_with(params[i], "sidetext_width$")) { option.opt.sidetext_width = atoi(params[i].substr(15, params[i].size() - 15).c_str()); } @@ -1823,13 +1823,16 @@ bool Tab::create_pages(std::string setting_type_name, int idx_page) else if (boost::starts_with(params[i], "height$")) { option.opt.height = atoi(params[i].substr(7, params[i].size() - 7).c_str()); } + else if (boost::starts_with(params[i], "precision$")) { + option.opt.precision = atoi(params[i].substr(7, params[i].size() - 7).c_str()); + } else if (params[i] == "color") { colored = true; } else if (boost::starts_with(params[i], "url$")) { // only on line label_path = params[i].substr(4, params[i].size() - 4); } - else if (params[i].find("tooltip$") != std::string::npos) + else if (boost::starts_with(params[i], "tooltip$")) { option.opt.tooltip = L(params[i].substr(8, params[i].size() - 8)); need_to_notified_search = true; diff --git a/src/slic3r/GUI/UnsavedChangesDialog.cpp b/src/slic3r/GUI/UnsavedChangesDialog.cpp index c11e0279e..fa1e09d6f 100644 --- a/src/slic3r/GUI/UnsavedChangesDialog.cpp +++ b/src/slic3r/GUI/UnsavedChangesDialog.cpp @@ -911,12 +911,12 @@ static wxString get_string_value(std::string opt_key, const DynamicPrintConfig& return from_u8((boost::format("%1%%%") % int(val)).str()); } case coFloat: - return double_to_string(config.opt_float(opt_key)); + return double_to_string(config.opt_float(opt_key), opt->precision); case coFloats: { double val = is_nullable ? config.opt(opt_key)->get_at(opt_idx) : config.opt(opt_key)->get_at(opt_idx); - return double_to_string(val); + return double_to_string(val, opt->precision); } case coString: return from_u8(config.opt_string(opt_key)); @@ -937,9 +937,9 @@ static wxString get_string_value(std::string opt_key, const DynamicPrintConfig& break; } case coFloatOrPercent: { - const ConfigOptionFloatOrPercent* opt = config.opt(opt_key); - if (opt) - out = double_to_string(opt->value) + (opt->percent ? "%" : ""); + const ConfigOptionFloatOrPercent* float_percent = config.opt(opt_key); + if (float_percent) + out = double_to_string(float_percent->value, opt->precision) + (float_percent->percent ? "%" : ""); return out; } case coEnum: {