diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 5bf5bba574..1f9179b82d 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -66,6 +66,12 @@ wxString double_to_string(double const value, const int max_precision /*= 4*/) return s; } +wxString get_thumbnail_string(const Vec2d& value) +{ + wxString ret_str = wxString::Format("%.2fx%.2f", value[0], value[1]); + return ret_str; +} + wxString get_thumbnails_string(const std::vector& values) { wxString ret_str; @@ -367,6 +373,34 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true m_value = into_u8(str); break; } + case coPoint:{ + Vec2d out_value; + str.Replace(" ", wxEmptyString, true); + if (!str.IsEmpty()) { + bool invalid_val = true; + double x, y; + wxStringTokenizer thumbnail(str, "x"); + if (thumbnail.HasMoreTokens()) { + wxString x_str = thumbnail.GetNextToken(); + if (x_str.ToDouble(&x) && thumbnail.HasMoreTokens()) { + wxString y_str = thumbnail.GetNextToken(); + if (y_str.ToDouble(&y) && !thumbnail.HasMoreTokens()) { + out_value = Vec2d(x, y); + invalid_val = false; + } + } + } + + if (invalid_val) { + wxString text_value; + if (!m_value.empty()) text_value = get_thumbnail_string(boost::any_cast(m_value)); + set_value(text_value, true); + show_error(m_parent, format_wxstr(_L("Invalid format. Expected vector format: \"%1%\""), "XxY, XxY, ...")); + } + } + + m_value = out_value; + break; } case coPoints: { std::vector out_values; @@ -446,7 +480,7 @@ void Field::sys_color_changed() template bool is_defined_input_value(wxWindow* win, const ConfigOptionType& type) { - if (!win || (static_cast(win)->GetValue().empty() && type != coString && type != coStrings && type != coPoints)) + if (!win || (static_cast(win)->GetValue().empty() && type != coString && type != coStrings && type != coPoints && type != coPoint)) return false; return true; } @@ -495,6 +529,9 @@ void TextCtrl::BUILD() { text_value = vec->get_at(m_opt_idx); break; } + case coPoint: + text_value = get_thumbnail_string(m_opt.get_default_value()->value); + break; case coPoints: text_value = get_thumbnails_string(m_opt.get_default_value()->values); break; @@ -1621,8 +1658,11 @@ void PointCtrl::BUILD() auto temp = new wxBoxSizer(wxHORIZONTAL); const wxSize field_size(4 * m_em_unit, -1); - - auto default_pt = m_opt.get_default_value()->values.at(0); + Slic3r::Vec2d default_pt; + if(m_opt.type == coPoints) + default_pt = m_opt.get_default_value()->values.at(0); + else + default_pt = m_opt.get_default_value()->value; double val = default_pt(0); wxString X = val - int(val) == 0 ? wxString::Format(_T("%i"), int(val)) : wxNumberFormatter::ToString(val, 2, wxNumberFormatter::Style_None); val = default_pt(1); @@ -1733,14 +1773,19 @@ void PointCtrl::set_value(const Vec2d& value, bool change_event) void PointCtrl::set_value(const boost::any& value, bool change_event) { Vec2d pt(Vec2d::Zero()); - const Vec2d *ptf = boost::any_cast(&value); - if (!ptf) - { - ConfigOptionPoints* pts = boost::any_cast(value); - pt = pts->values.at(0); - } - else - pt = *ptf; + const Vec2d* ptf = boost::any_cast(&value); + if (!ptf) { + if (m_opt.type == coPoint) { + ConfigOptionPoint* pts = boost::any_cast(value); + pt = pts->value; + } + else { + ConfigOptionPoints* pts = boost::any_cast(value); + pt = pts->values.at(0); + } + } + else + pt = *ptf; set_value(pt, change_event); } diff --git a/src/slic3r/GUI/Field.hpp b/src/slic3r/GUI/Field.hpp index 1a997a8eba..a951c02132 100644 --- a/src/slic3r/GUI/Field.hpp +++ b/src/slic3r/GUI/Field.hpp @@ -38,6 +38,7 @@ using t_change = std::function; wxString double_to_string(double const value, const int max_precision = 4); +wxString get_thumbnail_string(const Vec2d& value); wxString get_thumbnails_string(const std::vector& values); class Field { diff --git a/src/slic3r/GUI/GUI.cpp b/src/slic3r/GUI/GUI.cpp index e6c4789816..8c85a88e6b 100644 --- a/src/slic3r/GUI/GUI.cpp +++ b/src/slic3r/GUI/GUI.cpp @@ -198,6 +198,10 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt config.option(opt_key)->set_at(vec_new, opt_index, 0); } break; + case coPoint:{ + config.set_key_value(opt_key, new ConfigOptionPoint(boost::any_cast(value))); + } + break; case coPoints:{ if (opt_key == "printable_area" || opt_key == "bed_exclude_area" || opt_key=="thumbnail_size") { config.option(opt_key)->values = boost::any_cast>(value); diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index e5512bff32..4c301a8e42 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -77,6 +77,7 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co case coEnums: m_fields.emplace(id, Choice::Create(this->ctrl_parent(), opt, id)); break; + case coPoint: case coPoints: m_fields.emplace(id, PointCtrl::Create(this->ctrl_parent(), opt, id)); break; @@ -1032,6 +1033,9 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config case coEnums: ret = config.opt_int(opt_key, idx); break; + case coPoint: + ret = config.option(opt_key)->value; + break; case coPoints: if (opt_key == "printable_area") ret = config.option(opt_key)->values; @@ -1144,6 +1148,9 @@ boost::any ConfigOptionsGroup::get_config_value2(const DynamicPrintConfig& confi case coEnums: ret = config.opt_int(opt_key, idx); break; + case coPoint: + ret = config.option(opt_key)->value; + break; case coPoints: if (opt_key == "printable_area") ret = config.option(opt_key)->values; diff --git a/src/slic3r/GUI/UnsavedChangesDialog.cpp b/src/slic3r/GUI/UnsavedChangesDialog.cpp index 401907ccd8..228a39cbe3 100644 --- a/src/slic3r/GUI/UnsavedChangesDialog.cpp +++ b/src/slic3r/GUI/UnsavedChangesDialog.cpp @@ -1349,6 +1349,10 @@ static wxString get_string_value(std::string opt_key, const DynamicPrintConfig& opt_key == "sparse_infill_pattern", opt_idx); } + case coPoint: { + Vec2d val = config.opt(opt_key)->value; + return from_u8((boost::format("[%1%]") % ConfigOptionPoint(val).serialize()).str()); + } case coPoints: { //BBS: add bed_exclude_area if (opt_key == "printable_area") {