2017-12-19 10:59:42 +00:00
|
|
|
|
#include "OptionsGroup.hpp"
|
2017-12-13 13:45:10 +00:00
|
|
|
|
#include "ConfigExceptions.hpp"
|
2017-12-05 14:54:01 +00:00
|
|
|
|
|
2017-12-13 13:45:10 +00:00
|
|
|
|
#include <utility>
|
2018-01-09 08:41:07 +00:00
|
|
|
|
#include <wx/numformatter.h>
|
2018-03-07 14:05:41 +00:00
|
|
|
|
#include <boost/algorithm/string/split.hpp>
|
|
|
|
|
#include <boost/algorithm/string/classification.hpp>
|
2018-03-06 08:44:53 +00:00
|
|
|
|
#include "Utils.hpp"
|
2017-12-05 14:54:01 +00:00
|
|
|
|
|
|
|
|
|
namespace Slic3r { namespace GUI {
|
|
|
|
|
|
2018-03-02 08:08:11 +00:00
|
|
|
|
const t_field& OptionsGroup::build_field(const Option& opt, wxStaticText* label/* = nullptr*/) {
|
|
|
|
|
return build_field(opt.opt_id, opt.opt, label);
|
2017-12-13 13:45:10 +00:00
|
|
|
|
}
|
2018-03-02 08:08:11 +00:00
|
|
|
|
const t_field& OptionsGroup::build_field(const t_config_option_key& id, wxStaticText* label/* = nullptr*/) {
|
2018-01-16 15:28:01 +00:00
|
|
|
|
const ConfigOptionDef& opt = m_options.at(id).opt;
|
2018-03-02 08:08:11 +00:00
|
|
|
|
return build_field(id, opt, label);
|
2017-12-13 13:45:10 +00:00
|
|
|
|
}
|
2017-12-05 14:54:01 +00:00
|
|
|
|
|
2018-03-02 08:08:11 +00:00
|
|
|
|
const t_field& OptionsGroup::build_field(const t_config_option_key& id, const ConfigOptionDef& opt, wxStaticText* label/* = nullptr*/) {
|
2017-12-13 13:45:10 +00:00
|
|
|
|
// 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) {
|
2018-01-05 14:11:33 +00:00
|
|
|
|
m_fields.emplace(id, STDMOVE(Choice::Create<Choice>(m_parent, opt, id)));
|
2017-12-13 13:45:10 +00:00
|
|
|
|
} else if (opt.gui_type.compare("color") == 0) {
|
2018-01-05 14:11:33 +00:00
|
|
|
|
m_fields.emplace(id, STDMOVE(ColourPicker::Create<ColourPicker>(m_parent, opt, id)));
|
2017-12-13 13:45:10 +00:00
|
|
|
|
} 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) {
|
2018-01-05 14:11:33 +00:00
|
|
|
|
m_fields.emplace(id, STDMOVE(Choice::Create<Choice>(m_parent, opt, id)));
|
2017-12-13 13:45:10 +00:00
|
|
|
|
} else if (opt.gui_type.compare("slider") == 0) {
|
|
|
|
|
} else if (opt.gui_type.compare("i_spin") == 0) { // Spinctrl
|
|
|
|
|
} else {
|
|
|
|
|
switch (opt.type) {
|
|
|
|
|
case coFloatOrPercent:
|
|
|
|
|
case coFloat:
|
2017-12-22 10:50:28 +00:00
|
|
|
|
case coFloats:
|
2017-12-18 12:58:51 +00:00
|
|
|
|
case coPercent:
|
2017-12-22 10:50:28 +00:00
|
|
|
|
case coPercents:
|
2017-12-18 12:58:51 +00:00
|
|
|
|
case coString:
|
|
|
|
|
case coStrings:
|
2018-01-05 14:11:33 +00:00
|
|
|
|
m_fields.emplace(id, STDMOVE(TextCtrl::Create<TextCtrl>(m_parent, opt, id)));
|
2017-12-13 13:45:10 +00:00
|
|
|
|
break;
|
2017-12-18 12:58:51 +00:00
|
|
|
|
case coBool:
|
|
|
|
|
case coBools:
|
2018-01-05 14:11:33 +00:00
|
|
|
|
m_fields.emplace(id, STDMOVE(CheckBox::Create<CheckBox>(m_parent, opt, id)));
|
2017-12-18 12:58:51 +00:00
|
|
|
|
break;
|
|
|
|
|
case coInt:
|
|
|
|
|
case coInts:
|
2018-01-05 14:11:33 +00:00
|
|
|
|
m_fields.emplace(id, STDMOVE(SpinCtrl::Create<SpinCtrl>(m_parent, opt, id)));
|
2017-12-18 12:58:51 +00:00
|
|
|
|
break;
|
|
|
|
|
case coEnum:
|
2018-01-05 14:11:33 +00:00
|
|
|
|
m_fields.emplace(id, STDMOVE(Choice::Create<Choice>(m_parent, opt, id)));
|
2017-12-18 12:58:51 +00:00
|
|
|
|
break;
|
2017-12-22 10:50:28 +00:00
|
|
|
|
case coPoints:
|
2018-01-25 12:46:04 +00:00
|
|
|
|
m_fields.emplace(id, STDMOVE(PointCtrl::Create<PointCtrl>(m_parent, opt, id)));
|
2017-12-22 10:50:28 +00:00
|
|
|
|
break;
|
2017-12-13 13:45:10 +00:00
|
|
|
|
case coNone: break;
|
|
|
|
|
default:
|
2017-12-18 12:58:51 +00:00
|
|
|
|
throw /*//!ConfigGUITypeError("")*/std::logic_error("This control doesn't exist till now"); break;
|
2017-12-13 13:45:10 +00:00
|
|
|
|
}
|
2017-12-05 14:54:01 +00:00
|
|
|
|
}
|
2017-12-13 13:45:10 +00:00
|
|
|
|
// Grab a reference to fields for convenience
|
2018-01-05 14:11:33 +00:00
|
|
|
|
const t_field& field = m_fields[id];
|
|
|
|
|
field->m_on_change = [this](std::string opt_id, boost::any value){
|
|
|
|
|
//! This function will be called from Field.
|
|
|
|
|
//! Call OptionGroup._on_change(...)
|
|
|
|
|
if (!this->m_disabled)
|
|
|
|
|
this->on_change_OG(opt_id, value);
|
|
|
|
|
};
|
2018-01-31 13:59:44 +00:00
|
|
|
|
field->m_on_kill_focus = [this](){
|
|
|
|
|
//! This function will be called from Field.
|
|
|
|
|
if (!this->m_disabled)
|
|
|
|
|
this->on_kill_focus();
|
|
|
|
|
};
|
2018-01-05 14:11:33 +00:00
|
|
|
|
field->m_parent = parent();
|
2018-03-02 08:08:11 +00:00
|
|
|
|
|
|
|
|
|
//! Label to change background color, when option is modified
|
2018-03-06 11:34:20 +00:00
|
|
|
|
field->m_Label = label;
|
|
|
|
|
field->m_back_to_initial_value = [this](std::string opt_id){
|
|
|
|
|
if (!this->m_disabled)
|
|
|
|
|
this->back_to_initial_value(opt_id);
|
|
|
|
|
};
|
2018-03-16 16:25:11 +00:00
|
|
|
|
field->m_back_to_sys_value = [this](std::string opt_id){
|
|
|
|
|
if (!this->m_disabled)
|
|
|
|
|
this->back_to_sys_value(opt_id);
|
|
|
|
|
};
|
2018-03-15 08:55:31 +00:00
|
|
|
|
if (!m_is_tab_opt) {
|
|
|
|
|
field->m_Undo_btn->Hide();
|
|
|
|
|
field->m_Undo_to_sys_btn->Hide();
|
|
|
|
|
}
|
2018-03-21 21:21:37 +00:00
|
|
|
|
if (nonsys_btn_icon != nullptr)
|
|
|
|
|
field->set_nonsys_btn_icon(nonsys_btn_icon());
|
2018-03-02 08:08:11 +00:00
|
|
|
|
|
|
|
|
|
// assign function objects for callbacks, etc.
|
2017-12-13 13:45:10 +00:00
|
|
|
|
return field;
|
2017-12-05 14:54:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2018-04-13 16:22:06 +00:00
|
|
|
|
void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* = nullptr*/) {
|
2017-12-22 10:50:28 +00:00
|
|
|
|
//! if (line.sizer != nullptr || (line.widget != nullptr && line.full_width > 0)){
|
|
|
|
|
if ( (line.sizer != nullptr || line.widget != nullptr) && line.full_width){
|
|
|
|
|
if (line.sizer != nullptr) {
|
2017-12-13 13:45:10 +00:00
|
|
|
|
sizer->Add(line.sizer, 0, wxEXPAND | wxALL, wxOSX ? 0 : 15);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (line.widget != nullptr) {
|
2018-01-05 14:11:33 +00:00
|
|
|
|
sizer->Add(line.widget(m_parent), 0, wxEXPAND | wxALL, wxOSX ? 0 : 15);
|
2017-12-13 13:45:10 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2017-12-05 14:54:01 +00:00
|
|
|
|
}
|
2017-12-13 13:45:10 +00:00
|
|
|
|
|
2017-12-22 10:50:28 +00:00
|
|
|
|
auto option_set = line.get_options();
|
2018-01-16 15:28:01 +00:00
|
|
|
|
for (auto opt : option_set)
|
|
|
|
|
m_options.emplace(opt.opt_id, opt);
|
2017-12-22 10:50:28 +00:00
|
|
|
|
|
|
|
|
|
// if we have a single option with no label, no sidetext just add it directly to sizer
|
|
|
|
|
if (option_set.size() == 1 && label_width == 0 && option_set.front().opt.full_width &&
|
|
|
|
|
option_set.front().opt.sidetext.size() == 0 && option_set.front().side_widget == nullptr &&
|
|
|
|
|
line.get_extra_widgets().size() == 0) {
|
|
|
|
|
const auto& option = option_set.front();
|
|
|
|
|
const auto& field = build_field(option);
|
|
|
|
|
|
2018-03-16 11:56:03 +00:00
|
|
|
|
auto btn_sizer = new wxBoxSizer(wxHORIZONTAL);
|
|
|
|
|
btn_sizer->Add(field->m_Undo_to_sys_btn);
|
|
|
|
|
btn_sizer->Add(field->m_Undo_btn);
|
|
|
|
|
sizer->Add(btn_sizer, 0, wxEXPAND | wxALL, 0);
|
2017-12-22 10:50:28 +00:00
|
|
|
|
if (is_window_field(field))
|
|
|
|
|
sizer->Add(field->getWindow(), 0, wxEXPAND | wxALL, wxOSX ? 0 : 5);
|
|
|
|
|
if (is_sizer_field(field))
|
|
|
|
|
sizer->Add(field->getSizer(), 0, wxEXPAND | wxALL, wxOSX ? 0 : 5);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-05 14:11:33 +00:00
|
|
|
|
auto grid_sizer = m_grid_sizer;
|
2017-12-13 13:45:10 +00:00
|
|
|
|
|
|
|
|
|
// Build a label if we have it
|
2018-03-02 08:08:11 +00:00
|
|
|
|
wxStaticText* label=nullptr;
|
2017-12-05 14:54:01 +00:00
|
|
|
|
if (label_width != 0) {
|
2018-03-06 08:44:53 +00:00
|
|
|
|
label = new wxStaticText(parent(), wxID_ANY, line.label + (line.label.IsEmpty() ? "" : ":"),
|
2018-02-07 16:13:52 +00:00
|
|
|
|
wxDefaultPosition, wxSize(label_width, -1));
|
2017-12-13 13:45:10 +00:00
|
|
|
|
label->SetFont(label_font);
|
|
|
|
|
label->Wrap(label_width); // avoid a Linux/GTK bug
|
2018-02-13 12:39:20 +00:00
|
|
|
|
grid_sizer->Add(label, 0, wxALIGN_CENTER_VERTICAL,0);
|
2018-02-07 16:13:52 +00:00
|
|
|
|
if (line.label_tooltip.compare("") != 0)
|
|
|
|
|
label->SetToolTip(line.label_tooltip);
|
2017-12-05 14:54:01 +00:00
|
|
|
|
}
|
2017-12-13 13:45:10 +00:00
|
|
|
|
|
|
|
|
|
// If there's a widget, build it and add the result to the sizer.
|
2018-02-22 10:34:41 +00:00
|
|
|
|
if (line.widget != nullptr) {
|
|
|
|
|
auto wgt = line.widget(parent());
|
2018-02-13 12:39:20 +00:00
|
|
|
|
grid_sizer->Add(wgt, 0, wxEXPAND | wxBOTTOM | wxTOP, wxOSX ? 0 : 5);
|
2018-04-13 16:22:06 +00:00
|
|
|
|
if (colored_Label != nullptr) *colored_Label = label;
|
2018-02-22 10:34:41 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if we have a single option with no sidetext just add it directly to the grid sizer
|
2018-03-06 08:44:53 +00:00
|
|
|
|
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
|
|
|
|
grid_sizer->Add(sizer, 0, wxEXPAND | wxALL, 0);
|
|
|
|
|
if (option_set.size() == 1 && option_set.front().opt.sidetext.size() == 0 &&
|
|
|
|
|
option_set.front().side_widget == nullptr && line.get_extra_widgets().size() == 0) {
|
|
|
|
|
const auto& option = option_set.front();
|
|
|
|
|
const auto& field = build_field(option, label);
|
2017-12-18 12:58:51 +00:00
|
|
|
|
|
2018-03-15 08:55:31 +00:00
|
|
|
|
sizer->Add(field->m_Undo_to_sys_btn, 0, wxALIGN_CENTER_VERTICAL);
|
2018-03-06 08:44:53 +00:00
|
|
|
|
sizer->Add(field->m_Undo_btn, 0, wxALIGN_CENTER_VERTICAL);
|
|
|
|
|
if (is_window_field(field))
|
|
|
|
|
sizer->Add(field->getWindow(), 0, (option.opt.full_width ? wxEXPAND : 0) |
|
2018-02-13 12:39:20 +00:00
|
|
|
|
wxBOTTOM | wxTOP | wxALIGN_CENTER_VERTICAL, wxOSX ? 0 : 2);
|
2018-03-06 08:44:53 +00:00
|
|
|
|
if (is_sizer_field(field))
|
|
|
|
|
sizer->Add(field->getSizer(), 0, (option.opt.full_width ? wxEXPAND : 0) | wxALIGN_CENTER_VERTICAL, 0);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2017-12-13 13:45:10 +00:00
|
|
|
|
|
|
|
|
|
// if we're here, we have more than one option or a single option with sidetext
|
|
|
|
|
// so we need a horizontal sizer to arrange these things
|
2017-12-14 13:42:47 +00:00
|
|
|
|
for (auto opt : option_set) {
|
|
|
|
|
ConfigOptionDef option = opt.opt;
|
|
|
|
|
// add label if any
|
|
|
|
|
if (option.label != "") {
|
2018-02-28 14:39:20 +00:00
|
|
|
|
wxString str_label = L_str(option.label);
|
|
|
|
|
//! To correct translation by context have to use wxGETTEXT_IN_CONTEXT macro from wxWidget 3.1.1
|
|
|
|
|
// wxString str_label = (option.label == "Top" || option.label == "Bottom") ?
|
|
|
|
|
// wxGETTEXT_IN_CONTEXT("Layers", wxString(option.label.c_str()):
|
|
|
|
|
// L_str(option.label);
|
2018-03-06 08:44:53 +00:00
|
|
|
|
label = new wxStaticText(parent(), wxID_ANY, str_label + ":", wxDefaultPosition, wxDefaultSize);
|
|
|
|
|
label->SetFont(label_font);
|
|
|
|
|
sizer->Add(label, 0, wxALIGN_CENTER_VERTICAL, 0);
|
2017-12-14 13:42:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// add field
|
2017-12-18 12:58:51 +00:00
|
|
|
|
const Option& opt_ref = opt;
|
2018-03-02 08:08:11 +00:00
|
|
|
|
auto& field = build_field(opt_ref, label);
|
2018-03-15 08:55:31 +00:00
|
|
|
|
sizer->Add(field->m_Undo_to_sys_btn, 0, wxALIGN_CENTER_VERTICAL);
|
2018-03-06 08:44:53 +00:00
|
|
|
|
sizer->Add(field->m_Undo_btn, 0, wxALIGN_CENTER_VERTICAL, 0);
|
2017-12-22 10:50:28 +00:00
|
|
|
|
is_sizer_field(field) ?
|
|
|
|
|
sizer->Add(field->getSizer(), 0, wxALIGN_CENTER_VERTICAL, 0) :
|
|
|
|
|
sizer->Add(field->getWindow(), 0, wxALIGN_CENTER_VERTICAL, 0);
|
2017-12-14 13:42:47 +00:00
|
|
|
|
|
|
|
|
|
// add sidetext if any
|
|
|
|
|
if (option.sidetext != "") {
|
2018-02-22 10:34:41 +00:00
|
|
|
|
auto sidetext = new wxStaticText(parent(), wxID_ANY, L_str(option.sidetext), wxDefaultPosition, wxDefaultSize);
|
2017-12-14 13:42:47 +00:00
|
|
|
|
sidetext->SetFont(sidetext_font);
|
|
|
|
|
sizer->Add(sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// add side widget if any
|
|
|
|
|
if (opt.side_widget != nullptr) {
|
2017-12-22 10:50:28 +00:00
|
|
|
|
sizer->Add(opt.side_widget(parent())/*!.target<wxWindow>()*/, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 1); //! requires verification
|
2017-12-14 13:42:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (opt.opt_id != option_set.back().opt_id) //! istead of (opt != option_set.back())
|
|
|
|
|
{
|
2018-02-15 16:30:33 +00:00
|
|
|
|
sizer->AddSpacer(6);
|
2017-12-14 13:42:47 +00:00
|
|
|
|
}
|
2017-12-22 10:50:28 +00:00
|
|
|
|
}
|
|
|
|
|
// add extra sizers if any
|
|
|
|
|
for (auto extra_widget : line.get_extra_widgets()) {
|
|
|
|
|
sizer->Add(extra_widget(parent())/*!.target<wxWindow>()*/, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4); //! requires verification
|
2017-12-14 13:42:47 +00:00
|
|
|
|
}
|
2017-12-13 13:45:10 +00:00
|
|
|
|
}
|
2017-12-14 13:42:47 +00:00
|
|
|
|
|
2017-12-13 13:45:10 +00:00
|
|
|
|
Line OptionsGroup::create_single_option_line(const Option& option) const {
|
2018-02-22 10:34:41 +00:00
|
|
|
|
Line retval{ L_str(option.opt.label), L_str(option.opt.tooltip) };
|
2017-12-13 13:45:10 +00:00
|
|
|
|
Option tmp(option);
|
|
|
|
|
tmp.opt.label = std::string("");
|
|
|
|
|
retval.append_option(tmp);
|
|
|
|
|
return retval;
|
2017-12-05 14:54:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2018-04-13 10:35:04 +00:00
|
|
|
|
void OptionsGroup::on_change_OG(const t_config_option_key& opt_id, const boost::any& value) {
|
2018-01-05 14:11:33 +00:00
|
|
|
|
if (m_on_change != nullptr)
|
2018-04-13 10:35:04 +00:00
|
|
|
|
m_on_change(opt_id, value);
|
2018-01-05 14:11:33 +00:00
|
|
|
|
}
|
2017-12-13 13:45:10 +00:00
|
|
|
|
|
2018-04-13 10:35:04 +00:00
|
|
|
|
Option ConfigOptionsGroup::get_option(const std::string& opt_key, int opt_index /*= -1*/)
|
2018-01-07 17:41:40 +00:00
|
|
|
|
{
|
|
|
|
|
if (!m_config->has(opt_key)) {
|
2018-02-18 22:11:43 +00:00
|
|
|
|
std::cerr << "No " << opt_key << " in ConfigOptionsGroup config.";
|
2018-01-07 17:41:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string opt_id = opt_index == -1 ? opt_key : opt_key + "#" + std::to_string(opt_index);
|
|
|
|
|
std::pair<std::string, int> pair(opt_key, opt_index);
|
|
|
|
|
m_opt_map.emplace(opt_id, pair);
|
|
|
|
|
|
|
|
|
|
return Option(*m_config->def()->get(opt_key), opt_id);
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-13 10:35:04 +00:00
|
|
|
|
void ConfigOptionsGroup::on_change_OG(const t_config_option_key& opt_id, const boost::any& value)
|
2018-01-05 14:11:33 +00:00
|
|
|
|
{
|
2018-01-07 17:41:40 +00:00
|
|
|
|
if (!m_opt_map.empty())
|
|
|
|
|
{
|
2018-01-14 20:52:55 +00:00
|
|
|
|
auto it = m_opt_map.find(opt_id);
|
|
|
|
|
if (it == m_opt_map.end())
|
|
|
|
|
{
|
|
|
|
|
OptionsGroup::on_change_OG(opt_id, value);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto itOption = it->second;
|
|
|
|
|
std::string opt_key = itOption.first;
|
|
|
|
|
int opt_index = itOption.second;
|
|
|
|
|
|
2018-01-16 15:28:01 +00:00
|
|
|
|
auto option = m_options.at(opt_id).opt;
|
2018-01-05 14:11:33 +00:00
|
|
|
|
|
|
|
|
|
// get value
|
2018-01-11 09:33:17 +00:00
|
|
|
|
//! auto field_value = get_value(opt_id);
|
2018-01-07 17:41:40 +00:00
|
|
|
|
if (option.gui_flags.compare("serialized")==0) {
|
|
|
|
|
if (opt_index != -1){
|
|
|
|
|
// die "Can't set serialized option indexed value" ;
|
|
|
|
|
}
|
2018-04-13 10:35:04 +00:00
|
|
|
|
change_opt_value(*m_config, opt_key, value);
|
2018-01-07 17:41:40 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (opt_index == -1) {
|
2018-01-09 12:52:01 +00:00
|
|
|
|
// change_opt_value(*m_config, opt_key, field_value);
|
|
|
|
|
//!? why field_value?? in this case changed value will be lose! No?
|
|
|
|
|
change_opt_value(*m_config, opt_key, value);
|
2018-01-07 17:41:40 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
2018-02-15 16:30:33 +00:00
|
|
|
|
change_opt_value(*m_config, opt_key, value, opt_index);
|
2018-01-07 17:41:40 +00:00
|
|
|
|
// auto value = m_config->get($opt_key);
|
2018-01-05 14:11:33 +00:00
|
|
|
|
// $value->[$opt_index] = $field_value;
|
|
|
|
|
// $self->config->set($opt_key, $value);
|
2018-01-07 17:41:40 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-01-05 14:11:33 +00:00
|
|
|
|
|
2018-01-11 09:33:17 +00:00
|
|
|
|
OptionsGroup::on_change_OG(opt_id, value); //!? Why doing this
|
2018-01-05 14:11:33 +00:00
|
|
|
|
}
|
2017-12-13 13:45:10 +00:00
|
|
|
|
|
2018-04-13 10:35:04 +00:00
|
|
|
|
void ConfigOptionsGroup::back_to_initial_value(const std::string& opt_key)
|
2018-03-06 11:34:20 +00:00
|
|
|
|
{
|
|
|
|
|
if (m_get_initial_config == nullptr)
|
|
|
|
|
return;
|
2018-03-16 16:25:11 +00:00
|
|
|
|
back_to_config_value(m_get_initial_config(), opt_key);
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-13 10:35:04 +00:00
|
|
|
|
void ConfigOptionsGroup::back_to_sys_value(const std::string& opt_key)
|
2018-03-16 16:25:11 +00:00
|
|
|
|
{
|
|
|
|
|
if (m_get_sys_config == nullptr)
|
|
|
|
|
return;
|
|
|
|
|
if (!have_sys_config())
|
|
|
|
|
return;
|
|
|
|
|
back_to_config_value(m_get_sys_config(), opt_key);
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-13 10:35:04 +00:00
|
|
|
|
void ConfigOptionsGroup::back_to_config_value(const DynamicPrintConfig& config, const std::string& opt_key)
|
2018-03-16 16:25:11 +00:00
|
|
|
|
{
|
2018-03-07 14:05:41 +00:00
|
|
|
|
boost::any value;
|
|
|
|
|
if (opt_key == "extruders_count"){
|
|
|
|
|
auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(config.option("nozzle_diameter"));
|
|
|
|
|
value = int(nozzle_diameter->values.size());
|
|
|
|
|
}
|
2018-03-08 10:58:06 +00:00
|
|
|
|
else if (m_opt_map.find(opt_key) != m_opt_map.end())
|
|
|
|
|
{
|
|
|
|
|
auto opt_id = m_opt_map.find(opt_key)->first;
|
|
|
|
|
std::string opt_short_key = m_opt_map.at(opt_id).first;
|
|
|
|
|
int opt_index = m_opt_map.at(opt_id).second;
|
|
|
|
|
value = get_config_value(config, opt_short_key, opt_index);
|
|
|
|
|
}
|
2018-03-23 16:27:43 +00:00
|
|
|
|
else{
|
2018-03-07 14:05:41 +00:00
|
|
|
|
value = get_config_value(config, opt_key);
|
2018-03-23 16:27:43 +00:00
|
|
|
|
change_opt_value(*m_config, opt_key, value);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2018-03-07 14:05:41 +00:00
|
|
|
|
|
2018-03-06 11:34:20 +00:00
|
|
|
|
set_value(opt_key, value);
|
2018-03-07 14:05:41 +00:00
|
|
|
|
on_change_OG(opt_key, get_value(opt_key));
|
2018-03-06 11:34:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2018-01-09 08:41:07 +00:00
|
|
|
|
void ConfigOptionsGroup::reload_config(){
|
2018-03-21 21:21:37 +00:00
|
|
|
|
for (t_opt_map::iterator it = m_opt_map.begin(); it != m_opt_map.end(); ++it) {
|
2018-01-09 08:41:07 +00:00
|
|
|
|
auto opt_id = it->first;
|
|
|
|
|
std::string opt_key = m_opt_map.at(opt_id).first;
|
|
|
|
|
int opt_index = m_opt_map.at(opt_id).second;
|
2018-01-16 15:28:01 +00:00
|
|
|
|
auto option = m_options.at(opt_id).opt;
|
2018-01-09 08:41:07 +00:00
|
|
|
|
set_value(opt_id, config_value(opt_key, opt_index, option.gui_flags.compare("serialized") == 0 ));
|
|
|
|
|
}
|
2018-02-15 16:30:33 +00:00
|
|
|
|
|
2018-01-09 08:41:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
2018-04-13 10:35:04 +00:00
|
|
|
|
boost::any ConfigOptionsGroup::config_value(const std::string& opt_key, int opt_index, bool deserialize){
|
2018-01-09 08:41:07 +00:00
|
|
|
|
|
|
|
|
|
if (deserialize) {
|
|
|
|
|
// Want to edit a vector value(currently only multi - strings) in a single edit box.
|
|
|
|
|
// Aggregate the strings the old way.
|
|
|
|
|
// Currently used for the post_process config value only.
|
|
|
|
|
if (opt_index != -1)
|
|
|
|
|
throw std::out_of_range("Can't deserialize option indexed value");
|
|
|
|
|
// return join(';', m_config->get(opt_key)});
|
|
|
|
|
return get_config_value(*m_config, opt_key);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
// return opt_index == -1 ? m_config->get(opt_key) : m_config->get_at(opt_key, opt_index);
|
|
|
|
|
return get_config_value(*m_config, opt_key, opt_index);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-13 10:35:04 +00:00
|
|
|
|
boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config, const std::string& opt_key, int opt_index /*= -1*/)
|
2018-01-09 08:41:07 +00:00
|
|
|
|
{
|
2018-01-16 15:28:01 +00:00
|
|
|
|
size_t idx = opt_index == -1 ? 0 : opt_index;
|
|
|
|
|
|
2018-01-09 08:41:07 +00:00
|
|
|
|
boost::any ret;
|
|
|
|
|
wxString text_value = wxString("");
|
|
|
|
|
const ConfigOptionDef* opt = config.def()->get(opt_key);
|
|
|
|
|
switch (opt->type){
|
|
|
|
|
case coFloatOrPercent:{
|
|
|
|
|
const auto &value = *config.option<ConfigOptionFloatOrPercent>(opt_key);
|
|
|
|
|
if (value.percent)
|
|
|
|
|
{
|
|
|
|
|
text_value = wxString::Format(_T("%i"), int(value.value));
|
|
|
|
|
text_value += "%";
|
|
|
|
|
}
|
|
|
|
|
else
|
2018-01-27 13:21:16 +00:00
|
|
|
|
text_value = double_to_string(value.value);
|
2018-01-09 08:41:07 +00:00
|
|
|
|
ret = text_value;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case coPercent:{
|
|
|
|
|
double val = config.option<ConfigOptionPercent>(opt_key)->value;
|
|
|
|
|
text_value = wxString::Format(_T("%i"), int(val));
|
|
|
|
|
ret = text_value;// += "%";
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case coPercents:
|
2018-01-27 13:21:16 +00:00
|
|
|
|
case coFloats:
|
|
|
|
|
case coFloat:{
|
2018-01-16 15:28:01 +00:00
|
|
|
|
double val = opt->type == coFloats ?
|
2018-02-18 22:11:43 +00:00
|
|
|
|
config.opt_float(opt_key, idx) :
|
2018-01-27 13:21:16 +00:00
|
|
|
|
opt->type == coFloat ? config.opt_float(opt_key) :
|
2018-03-08 10:58:06 +00:00
|
|
|
|
config.option<ConfigOptionPercents>(opt_key)->get_at(idx);
|
2018-01-27 13:21:16 +00:00
|
|
|
|
ret = double_to_string(val);
|
2018-01-09 08:41:07 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case coString:
|
|
|
|
|
ret = static_cast<wxString>(config.opt_string(opt_key));
|
|
|
|
|
break;
|
|
|
|
|
case coStrings:
|
2018-04-13 16:22:06 +00:00
|
|
|
|
if (opt_key.compare("compatible_printers") == 0){
|
|
|
|
|
ret = config.option<ConfigOptionStrings>(opt_key)->values;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2018-01-09 08:41:07 +00:00
|
|
|
|
if (config.option<ConfigOptionStrings>(opt_key)->values.empty())
|
|
|
|
|
ret = text_value;
|
2018-03-07 14:05:41 +00:00
|
|
|
|
else if (opt->gui_flags.compare("serialized") == 0){
|
|
|
|
|
std::vector<std::string> values = config.option<ConfigOptionStrings>(opt_key)->values;
|
2018-03-23 11:52:37 +00:00
|
|
|
|
if (!values.empty() && values[0].compare("") != 0)
|
|
|
|
|
for (auto el : values)
|
|
|
|
|
text_value += el + ";";
|
2018-03-07 14:05:41 +00:00
|
|
|
|
ret = text_value;
|
|
|
|
|
}
|
2018-01-09 08:41:07 +00:00
|
|
|
|
else
|
2018-02-18 22:11:43 +00:00
|
|
|
|
ret = static_cast<wxString>(config.opt_string(opt_key, static_cast<unsigned int>(idx)));
|
2018-01-09 08:41:07 +00:00
|
|
|
|
break;
|
|
|
|
|
case coBool:
|
|
|
|
|
ret = config.opt_bool(opt_key);
|
|
|
|
|
break;
|
|
|
|
|
case coBools:
|
2018-02-18 22:11:43 +00:00
|
|
|
|
ret = config.opt_bool(opt_key, idx);
|
2018-01-09 08:41:07 +00:00
|
|
|
|
break;
|
|
|
|
|
case coInt:
|
|
|
|
|
ret = config.opt_int(opt_key);
|
|
|
|
|
break;
|
|
|
|
|
case coInts:
|
2018-02-18 22:11:43 +00:00
|
|
|
|
ret = config.opt_int(opt_key, idx);
|
2018-01-09 08:41:07 +00:00
|
|
|
|
break;
|
|
|
|
|
case coEnum:{
|
|
|
|
|
if (opt_key.compare("external_fill_pattern") == 0 ||
|
2018-01-11 09:33:17 +00:00
|
|
|
|
opt_key.compare("fill_pattern") == 0 ){
|
2018-01-09 08:41:07 +00:00
|
|
|
|
ret = static_cast<int>(config.option<ConfigOptionEnum<InfillPattern>>(opt_key)->value);
|
|
|
|
|
}
|
|
|
|
|
else if (opt_key.compare("gcode_flavor") == 0 ){
|
|
|
|
|
ret = static_cast<int>(config.option<ConfigOptionEnum<GCodeFlavor>>(opt_key)->value);
|
|
|
|
|
}
|
|
|
|
|
else if (opt_key.compare("support_material_pattern") == 0){
|
|
|
|
|
ret = static_cast<int>(config.option<ConfigOptionEnum<SupportMaterialPattern>>(opt_key)->value);
|
|
|
|
|
}
|
|
|
|
|
else if (opt_key.compare("seam_position") == 0)
|
|
|
|
|
ret = static_cast<int>(config.option<ConfigOptionEnum<SeamPosition>>(opt_key)->value);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2018-03-08 10:58:06 +00:00
|
|
|
|
case coPoints:
|
2018-03-23 16:27:43 +00:00
|
|
|
|
if (opt_key.compare("bed_shape") == 0)
|
|
|
|
|
ret = config.option<ConfigOptionPoints>(opt_key)->values;
|
|
|
|
|
else
|
|
|
|
|
ret = config.option<ConfigOptionPoints>(opt_key)->get_at(idx);
|
2018-01-09 08:41:07 +00:00
|
|
|
|
break;
|
|
|
|
|
case coNone:
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-13 10:35:04 +00:00
|
|
|
|
Field* ConfigOptionsGroup::get_fieldc(const t_config_option_key& opt_key, int opt_index){
|
2018-03-07 14:05:41 +00:00
|
|
|
|
Field* field = get_field(opt_key);
|
|
|
|
|
if (field != nullptr)
|
|
|
|
|
return field;
|
2018-01-11 09:33:17 +00:00
|
|
|
|
std::string opt_id = "";
|
2018-03-21 21:21:37 +00:00
|
|
|
|
for (t_opt_map::iterator it = m_opt_map.begin(); it != m_opt_map.end(); ++it) {
|
2018-01-11 09:33:17 +00:00
|
|
|
|
if (opt_key == m_opt_map.at(it->first).first && opt_index == m_opt_map.at(it->first).second){
|
|
|
|
|
opt_id = it->first;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return opt_id.empty() ? nullptr : get_field(opt_id);
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-13 10:35:04 +00:00
|
|
|
|
void ogStaticText::SetText(const wxString& value)
|
2018-01-15 11:13:05 +00:00
|
|
|
|
{
|
|
|
|
|
SetLabel(value);
|
|
|
|
|
Wrap(400);
|
|
|
|
|
GetParent()->Layout();
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-05 14:11:33 +00:00
|
|
|
|
} // GUI
|
|
|
|
|
} // Slic3r
|