diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 0e21abdf3..f9169fa73 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -63,8 +63,10 @@ void PrintConfigDef::init_common_params() def->set_default_value(new ConfigOptionString("")); def = this->add("thumbnails", coPoints); - def->label = L("Picture sizes to be stored into a .gcode and .sl1 files"); + def->label = L("G-code thumbnails"); + def->tooltip = L("Picture sizes to be stored into a .gcode and .sl1 files"); def->mode = comExpert; + def->gui_type = "one_string"; def->set_default_value(new ConfigOptionPoints()); def = this->add("layer_height", coFloat); diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index eb55e1535..7c70c1635 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include "OG_CustomCtrl.hpp" @@ -52,6 +53,16 @@ wxString double_to_string(double const value, const int max_precision /*= 4*/) return s; } +wxString get_thumbnails_string(const std::vector& values) +{ + wxString ret_str; + if (!values.empty()) + for (auto el : values) + ret_str += wxString::Format("%ix%i, ", int(el[0]), int(el[1])); + return ret_str; +} + + Field::~Field() { if (m_on_kill_focus) @@ -304,6 +315,43 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true m_value = std::string(str.ToUTF8().data()); break; } + + case coPoints: { + std::vector out_values; + str.Replace(" ", wxEmptyString, true); + if (!str.IsEmpty()) { + bool invalid_val = false; + wxStringTokenizer thumbnails(str, ","); + while (thumbnails.HasMoreTokens()) { + wxString token = thumbnails.GetNextToken(); + double x, y; + wxStringTokenizer thumbnail(token, "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_values.push_back(Vec2d(x, y)); + continue; + } + } + } + invalid_val = true; + break; + } + + if (invalid_val) { + wxString text_value; + if (!m_value.empty()) + text_value = get_thumbnails_string(boost::any_cast>(m_value)); + set_value(text_value, true); + show_error(m_parent, format_wxstr(_L("Invalid input format. It must be represented like \"%1%\""),"XxY, XxY, ..." )); + } + } + + m_value = out_values; + break; } + default: break; } @@ -371,6 +419,9 @@ void TextCtrl::BUILD() { text_value = vec->get_at(m_opt_idx); break; } + case coPoints: + text_value = get_thumbnails_string(m_opt.get_default_value()->values); + break; default: break; } diff --git a/src/slic3r/GUI/Field.hpp b/src/slic3r/GUI/Field.hpp index 9a15542de..5b01c92c9 100644 --- a/src/slic3r/GUI/Field.hpp +++ b/src/slic3r/GUI/Field.hpp @@ -37,6 +37,7 @@ using t_change = std::function; wxString double_to_string(double const value, const int max_precision = 4); +wxString get_thumbnails_string(const std::vector& values); class Field { protected: diff --git a/src/slic3r/GUI/GUI.cpp b/src/slic3r/GUI/GUI.cpp index dc7ffe152..dea226012 100644 --- a/src/slic3r/GUI/GUI.cpp +++ b/src/slic3r/GUI/GUI.cpp @@ -201,7 +201,7 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt } break; case coPoints:{ - if (opt_key.compare("bed_shape") == 0) { + if (opt_key == "bed_shape" || opt_key == "thumbnails") { config.option(opt_key)->values = boost::any_cast>(value); break; } diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index 9da291984..d597d9cb2 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -25,20 +25,22 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id) { const t_field& OptionsGroup::build_field(const t_config_option_key& id, const ConfigOptionDef& opt) { // Check the gui_type field first, fall through // is the normal type. - if (opt.gui_type.compare("select") == 0) { - } else if (opt.gui_type.compare("select_open") == 0) { + if (opt.gui_type == "select") { + } else if (opt.gui_type == "select_open") { m_fields.emplace(id, std::move(Choice::Create(this->ctrl_parent(), opt, id))); - } else if (opt.gui_type.compare("color") == 0) { + } else if (opt.gui_type == "color") { m_fields.emplace(id, std::move(ColourPicker::Create(this->ctrl_parent(), opt, id))); - } else if (opt.gui_type.compare("f_enum_open") == 0 || - opt.gui_type.compare("i_enum_open") == 0 || - opt.gui_type.compare("i_enum_closed") == 0) { + } else if (opt.gui_type == "f_enum_open" || + opt.gui_type == "i_enum_open" || + opt.gui_type == "i_enum_closed") { m_fields.emplace(id, std::move(Choice::Create(this->ctrl_parent(), opt, id))); - } else if (opt.gui_type.compare("slider") == 0) { + } else if (opt.gui_type == "slider") { m_fields.emplace(id, std::move(SliderCtrl::Create(this->ctrl_parent(), opt, id))); - } else if (opt.gui_type.compare("i_spin") == 0) { // Spinctrl - } else if (opt.gui_type.compare("legend") == 0) { // StaticText + } else if (opt.gui_type == "i_spin") { // Spinctrl + } else if (opt.gui_type == "legend") { // StaticText m_fields.emplace(id, std::move(StaticText::Create(this->ctrl_parent(), opt, id))); + } else if (opt.gui_type == "one_string") { + m_fields.emplace(id, std::move(TextCtrl::Create(this->ctrl_parent(), opt, id))); } else { switch (opt.type) { case coFloatOrPercent: @@ -837,9 +839,9 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config } if (config.option(opt_key)->values.empty()) ret = text_value; - else if (opt->gui_flags.compare("serialized") == 0) { + else if (opt->gui_flags == "serialized") { std::vector values = config.option(opt_key)->values; - if (!values.empty() && values[0].compare("") != 0) + if (!values.empty() && !values[0].empty()) for (auto el : values) text_value += el + ";"; ret = text_value; @@ -897,6 +899,8 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config case coPoints: if (opt_key == "bed_shape") ret = config.option(opt_key)->values; + if (opt_key == "thumbnails") + ret = get_thumbnails_string(config.option(opt_key)->values); else ret = config.option(opt_key)->get_at(idx); break; diff --git a/src/slic3r/GUI/Search.cpp b/src/slic3r/GUI/Search.cpp index 1542067b3..d61fc05e0 100644 --- a/src/slic3r/GUI/Search.cpp +++ b/src/slic3r/GUI/Search.cpp @@ -94,7 +94,7 @@ void OptionsSearcher::append_options(DynamicPrintConfig* config, Preset::Type ty int cnt = 0; - if ( (type == Preset::TYPE_SLA_MATERIAL || type == Preset::TYPE_PRINTER) && opt_key != "bed_shape") + if ( (type == Preset::TYPE_SLA_MATERIAL || type == Preset::TYPE_PRINTER) && opt_key != "bed_shape" && opt_key != "thumbnails") switch (config->option(opt_key)->type()) { case coInts: change_opt_key(opt_key, config, cnt); break; diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index d7465c570..f7d72ae60 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -653,7 +653,7 @@ void TabPrinter::init_options_list() for (const auto opt_key : m_config->keys()) { - if (opt_key == "bed_shape") { + if (opt_key == "bed_shape" || opt_key == "thumbnails") { m_options_list.emplace(opt_key, m_opt_status_value); continue; } @@ -2173,6 +2173,11 @@ void TabPrinter::build_fff() optgroup = page->new_optgroup(L("Firmware")); optgroup->append_single_option_line("gcode_flavor"); + + option = optgroup->get_option("thumbnails"); + option.opt.full_width = true; + optgroup->append_single_option_line(option); + optgroup->append_single_option_line("silent_mode"); optgroup->append_single_option_line("remaining_times"); diff --git a/src/slic3r/GUI/UnsavedChangesDialog.cpp b/src/slic3r/GUI/UnsavedChangesDialog.cpp index bb1abcf3d..db0e65da9 100644 --- a/src/slic3r/GUI/UnsavedChangesDialog.cpp +++ b/src/slic3r/GUI/UnsavedChangesDialog.cpp @@ -968,6 +968,9 @@ static wxString get_string_value(std::string opt_key, const DynamicPrintConfig& BedShape shape(*config.option(opt_key)); return shape.get_full_name_with_params(); } + if (opt_key == "thumbnails") + return get_thumbnails_string(config.option(opt_key)->values); + Vec2d val = config.opt(opt_key)->get_at(opt_idx); return from_u8((boost::format("[%1%]") % ConfigOptionPoint(val).serialize()).str()); }