"on_change" function call correctly work now. Start adding of Tab::update().
It's need to think about config->set_key_value(...): at cpp side it's non-trivial.
This commit is contained in:
parent
f8a48f5c13
commit
e62c17bddf
9 changed files with 617 additions and 262 deletions
|
@ -158,7 +158,9 @@ sub _build_field {
|
|||
|
||||
my $opt_id = $opt->opt_id;
|
||||
my $on_change = sub {
|
||||
#! This function will be called from Field.
|
||||
my ($opt_id, $value) = @_;
|
||||
#! Call OptionGroup._on_change(...)
|
||||
$self->_on_change($opt_id, $value)
|
||||
unless $self->_disabled;
|
||||
};
|
||||
|
@ -213,6 +215,7 @@ sub _build_field {
|
|||
}
|
||||
return undef if !$field;
|
||||
|
||||
#! setting up a function that will be triggered when the field changes
|
||||
$field->on_change($on_change);
|
||||
$field->on_kill_focus($on_kill_focus);
|
||||
$self->_fields->{$opt_id} = $field;
|
||||
|
|
|
@ -15,13 +15,13 @@ namespace Slic3r { namespace GUI {
|
|||
event.Skip(1);
|
||||
|
||||
// call the registered function if it is available
|
||||
//! if (on_kill_focus)
|
||||
//! on_kill_focus(opt_id);
|
||||
if (on_kill_focus)
|
||||
on_kill_focus(m_opt_id);
|
||||
}
|
||||
void Field::_on_change(wxCommandEvent& event) {
|
||||
std::cerr << "calling Field::_on_change \n";
|
||||
//! if (on_change != nullptr && !disable_change_event)
|
||||
//! on_change(opt_id, "A");
|
||||
void Field::on_change_field(wxCommandEvent& event) {
|
||||
// std::cerr << "calling Field::_on_change \n";
|
||||
if (m_on_change != nullptr && !m_disable_change_event)
|
||||
m_on_change(m_opt_id, get_value());
|
||||
}
|
||||
|
||||
|
||||
|
@ -33,32 +33,32 @@ namespace Slic3r { namespace GUI {
|
|||
|
||||
void TextCtrl::BUILD() {
|
||||
auto size = wxSize(wxDefaultSize);
|
||||
if (opt.height >= 0) size.SetHeight(opt.height);
|
||||
if (opt.width >= 0) size.SetWidth(opt.width);
|
||||
if (m_opt.height >= 0) size.SetHeight(m_opt.height);
|
||||
if (m_opt.width >= 0) size.SetWidth(m_opt.width);
|
||||
|
||||
wxString text_value = wxString("");
|
||||
|
||||
switch (opt.type) {
|
||||
switch (m_opt.type) {
|
||||
case coFloatOrPercent:
|
||||
{
|
||||
if (static_cast<const ConfigOptionFloatOrPercent*>(opt.default_value)->percent)
|
||||
if (static_cast<const ConfigOptionFloatOrPercent*>(m_opt.default_value)->percent)
|
||||
{
|
||||
text_value = wxString::Format(_T("%i"), int(opt.default_value->getFloat()));
|
||||
text_value = wxString::Format(_T("%i"), int(m_opt.default_value->getFloat()));
|
||||
text_value += "%";
|
||||
}
|
||||
else
|
||||
wxNumberFormatter::ToString(opt.default_value->getFloat(), 2);
|
||||
wxNumberFormatter::ToString(m_opt.default_value->getFloat(), 2);
|
||||
break;
|
||||
}
|
||||
case coPercent:
|
||||
{
|
||||
text_value = wxString::Format(_T("%i"), int(opt.default_value->getFloat()));
|
||||
text_value = wxString::Format(_T("%i"), int(m_opt.default_value->getFloat()));
|
||||
text_value += "%";
|
||||
break;
|
||||
}
|
||||
case coPercents:
|
||||
{
|
||||
const ConfigOptionPercents *vec = static_cast<const ConfigOptionPercents*>(opt.default_value);
|
||||
const ConfigOptionPercents *vec = static_cast<const ConfigOptionPercents*>(m_opt.default_value);
|
||||
if (vec == nullptr || vec->empty()) break;
|
||||
if (vec->size() > 1)
|
||||
break;
|
||||
|
@ -68,13 +68,13 @@ namespace Slic3r { namespace GUI {
|
|||
}
|
||||
case coFloat:
|
||||
{
|
||||
double val = opt.default_value->getFloat();
|
||||
double val = m_opt.default_value->getFloat();
|
||||
text_value = (val - int(val)) == 0 ? wxString::Format(_T("%i"), int(val)) : wxNumberFormatter::ToString(val, 2);
|
||||
break;
|
||||
}
|
||||
case coFloats:
|
||||
{
|
||||
const ConfigOptionFloats *vec = static_cast<const ConfigOptionFloats*>(opt.default_value);
|
||||
const ConfigOptionFloats *vec = static_cast<const ConfigOptionFloats*>(m_opt.default_value);
|
||||
if (vec == nullptr || vec->empty()) break;
|
||||
if (vec->size() > 1)
|
||||
break;
|
||||
|
@ -83,11 +83,11 @@ namespace Slic3r { namespace GUI {
|
|||
break;
|
||||
}
|
||||
case coString:
|
||||
text_value = static_cast<const ConfigOptionString*>(opt.default_value)->value;
|
||||
text_value = static_cast<const ConfigOptionString*>(m_opt.default_value)->value;
|
||||
break;
|
||||
case coStrings:
|
||||
{
|
||||
const ConfigOptionStrings *vec = static_cast<const ConfigOptionStrings*>(opt.default_value);
|
||||
const ConfigOptionStrings *vec = static_cast<const ConfigOptionStrings*>(m_opt.default_value);
|
||||
if (vec == nullptr || vec->empty()) break;
|
||||
if (vec->size() > 1)
|
||||
break;
|
||||
|
@ -98,11 +98,11 @@ namespace Slic3r { namespace GUI {
|
|||
break;
|
||||
}
|
||||
|
||||
auto temp = new wxTextCtrl(parent, wxID_ANY, text_value, wxDefaultPosition, size, (opt.multiline ? wxTE_MULTILINE : 0));
|
||||
auto temp = new wxTextCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, (m_opt.multiline ? wxTE_MULTILINE : 0));
|
||||
|
||||
if (opt.tooltip.length() > 0) { temp->SetToolTip(opt.tooltip); }
|
||||
if (m_opt.tooltip.length() > 0) { temp->SetToolTip(m_opt.tooltip); }
|
||||
|
||||
temp->Bind(wxEVT_TEXT, ([=](wxCommandEvent e) { _on_change(e); }), temp->GetId());
|
||||
temp->Bind(wxEVT_TEXT, ([=](wxCommandEvent e) { on_change_field(e); }), temp->GetId());
|
||||
temp->Bind(wxEVT_KILL_FOCUS, ([this](wxFocusEvent e) { _on_kill_focus(e); }), temp->GetId());
|
||||
|
||||
// recast as a wxWindow to fit the calling convention
|
||||
|
@ -116,21 +116,21 @@ namespace Slic3r { namespace GUI {
|
|||
|
||||
void CheckBox::BUILD() {
|
||||
auto size = wxSize(wxDefaultSize);
|
||||
if (opt.height >= 0) size.SetHeight(opt.height);
|
||||
if (opt.width >= 0) size.SetWidth(opt.width);
|
||||
if (m_opt.height >= 0) size.SetHeight(m_opt.height);
|
||||
if (m_opt.width >= 0) size.SetWidth(m_opt.width);
|
||||
|
||||
bool check_value = opt.type == coBool ?
|
||||
opt.default_value->getBool() : opt.type == coBools ?
|
||||
static_cast<ConfigOptionBools*>(opt.default_value)->values.at(0) :
|
||||
bool check_value = m_opt.type == coBool ?
|
||||
m_opt.default_value->getBool() : m_opt.type == coBools ?
|
||||
static_cast<ConfigOptionBools*>(m_opt.default_value)->values.at(0) :
|
||||
false;
|
||||
|
||||
auto temp = new wxCheckBox(parent, wxID_ANY, wxString(""), wxDefaultPosition, size);
|
||||
auto temp = new wxCheckBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size);
|
||||
temp->SetValue(check_value);
|
||||
if (opt.readonly) temp->Disable();
|
||||
if (m_opt.readonly) temp->Disable();
|
||||
|
||||
temp->Bind(wxEVT_CHECKBOX, ([this](wxCommandEvent e) { _on_change(e); }), temp->GetId());
|
||||
temp->Bind(wxEVT_CHECKBOX, ([this](wxCommandEvent e) { on_change_field(e); }), temp->GetId());
|
||||
|
||||
if (opt.tooltip.length() > 0) { temp->SetToolTip(opt.tooltip); }
|
||||
if (m_opt.tooltip.length() > 0) { temp->SetToolTip(m_opt.tooltip); }
|
||||
|
||||
// recast as a wxWindow to fit the calling convention
|
||||
window = dynamic_cast<wxWindow*>(temp);
|
||||
|
@ -140,20 +140,20 @@ int undef_spin_val = -9999; //! Probably, It's not necessary
|
|||
|
||||
void SpinCtrl::BUILD() {
|
||||
auto size = wxSize(wxDefaultSize);
|
||||
if (opt.height >= 0) size.SetHeight(opt.height);
|
||||
if (opt.width >= 0) size.SetWidth(opt.width);
|
||||
if (m_opt.height >= 0) size.SetHeight(m_opt.height);
|
||||
if (m_opt.width >= 0) size.SetWidth(m_opt.width);
|
||||
|
||||
wxString text_value = wxString("");
|
||||
int default_value = 0;
|
||||
|
||||
switch (opt.type) {
|
||||
switch (m_opt.type) {
|
||||
case coInt:
|
||||
default_value = opt.default_value->getInt();
|
||||
default_value = m_opt.default_value->getInt();
|
||||
text_value = wxString::Format(_T("%i"), default_value);
|
||||
break;
|
||||
case coInts:
|
||||
{
|
||||
const ConfigOptionInts *vec = static_cast<const ConfigOptionInts*>(opt.default_value);
|
||||
const ConfigOptionInts *vec = static_cast<const ConfigOptionInts*>(m_opt.default_value);
|
||||
if (vec == nullptr || vec->empty()) break;
|
||||
for (size_t id = 0; id < vec->size(); ++id)
|
||||
{
|
||||
|
@ -166,10 +166,10 @@ void SpinCtrl::BUILD() {
|
|||
break;
|
||||
}
|
||||
|
||||
auto temp = new wxSpinCtrl(parent, wxID_ANY, text_value, wxDefaultPosition, size,
|
||||
0, opt.min >0 ? opt.min : 0, opt.max < 2147483647 ? opt.max : 2147483647, default_value);
|
||||
auto temp = new wxSpinCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size,
|
||||
0, m_opt.min >0 ? m_opt.min : 0, m_opt.max < 2147483647 ? m_opt.max : 2147483647, default_value);
|
||||
|
||||
temp->Bind(wxEVT_SPINCTRL, ([=](wxCommandEvent e) { tmp_value = undef_spin_val; _on_change(e); }), temp->GetId());
|
||||
temp->Bind(wxEVT_SPINCTRL, ([=](wxCommandEvent e) { tmp_value = undef_spin_val; on_change_field(e); }), temp->GetId());
|
||||
temp->Bind(wxEVT_KILL_FOCUS, ([this](wxFocusEvent e) { tmp_value = undef_spin_val; _on_kill_focus(e); }), temp->GetId());
|
||||
temp->Bind(wxEVT_TEXT, ([=](wxCommandEvent e)
|
||||
{
|
||||
|
@ -181,14 +181,14 @@ void SpinCtrl::BUILD() {
|
|||
std::string value = e.GetString();
|
||||
if (is_matched(value, "^\d+$"))
|
||||
tmp_value = std::stoi(value);
|
||||
_on_change(e);
|
||||
on_change_field(e);
|
||||
// # We don't reset tmp_value here because _on_change might put callbacks
|
||||
// # in the CallAfter queue, and we want the tmp value to be available from
|
||||
// # them as well.
|
||||
}), temp->GetId());
|
||||
|
||||
|
||||
if (opt.tooltip.length() > 0) { temp->SetToolTip(opt.tooltip); }
|
||||
if (m_opt.tooltip.length() > 0) { temp->SetToolTip(m_opt.tooltip); }
|
||||
|
||||
// recast as a wxWindow to fit the calling convention
|
||||
window = dynamic_cast<wxWindow*>(temp);
|
||||
|
@ -196,66 +196,66 @@ void SpinCtrl::BUILD() {
|
|||
|
||||
void Choice::BUILD() {
|
||||
auto size = wxSize(wxDefaultSize);
|
||||
if (opt.height >= 0) size.SetHeight(opt.height);
|
||||
if (opt.width >= 0) size.SetWidth(opt.width);
|
||||
if (m_opt.height >= 0) size.SetHeight(m_opt.height);
|
||||
if (m_opt.width >= 0) size.SetWidth(m_opt.width);
|
||||
|
||||
auto temp = new wxComboBox(parent, wxID_ANY, wxString(""), wxDefaultPosition, size);
|
||||
if (opt.gui_type.compare("select_open") != 0)
|
||||
auto temp = new wxComboBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size);
|
||||
if (m_opt.gui_type.compare("select_open") != 0)
|
||||
temp->SetExtraStyle(wxCB_READONLY);
|
||||
|
||||
// recast as a wxWindow to fit the calling convention
|
||||
window = dynamic_cast<wxWindow*>(temp);
|
||||
|
||||
if (opt.enum_labels.empty() && opt.enum_values.empty()){
|
||||
if (m_opt.enum_labels.empty() && m_opt.enum_values.empty()){
|
||||
}
|
||||
else{
|
||||
for (auto el : opt.enum_labels.empty() ? opt.enum_values : opt.enum_labels)
|
||||
for (auto el : m_opt.enum_labels.empty() ? m_opt.enum_values : m_opt.enum_labels)
|
||||
temp->Append(wxString(el));
|
||||
set_selection();
|
||||
}
|
||||
temp->Bind(wxEVT_TEXT, ([=](wxCommandEvent e) { _on_change(e); }), temp->GetId());
|
||||
temp->Bind(wxEVT_COMBOBOX, ([this](wxCommandEvent e) { _on_change(e); }), temp->GetId());
|
||||
temp->Bind(wxEVT_TEXT, ([=](wxCommandEvent e) { on_change_field(e); }), temp->GetId());
|
||||
temp->Bind(wxEVT_COMBOBOX, ([this](wxCommandEvent e) { on_change_field(e); }), temp->GetId());
|
||||
|
||||
if (opt.tooltip.length() > 0) temp->SetToolTip(opt.tooltip);
|
||||
if (m_opt.tooltip.length() > 0) temp->SetToolTip(m_opt.tooltip);
|
||||
}
|
||||
|
||||
void Choice::set_selection()
|
||||
{
|
||||
wxString text_value = wxString("");
|
||||
switch (opt.type){
|
||||
switch (m_opt.type){
|
||||
case coFloat:
|
||||
case coPercent: {
|
||||
double val = opt.default_value->getFloat();
|
||||
double val = m_opt.default_value->getFloat();
|
||||
text_value = val - int(val) == 0 ? wxString::Format(_T("%i"), int(val)) : wxNumberFormatter::ToString(val, 1);
|
||||
auto idx = 0;
|
||||
for (auto el : opt.enum_values)
|
||||
for (auto el : m_opt.enum_values)
|
||||
{
|
||||
if (el.compare(text_value) == 0)
|
||||
break;
|
||||
++idx;
|
||||
}
|
||||
if (opt.type == coPercent) text_value += "%";
|
||||
idx == opt.enum_values.size() ?
|
||||
if (m_opt.type == coPercent) text_value += "%";
|
||||
idx == m_opt.enum_values.size() ?
|
||||
dynamic_cast<wxComboBox*>(window)->SetValue(text_value) :
|
||||
dynamic_cast<wxComboBox*>(window)->SetSelection(idx);
|
||||
break;
|
||||
}
|
||||
case coEnum:{
|
||||
int id_value = static_cast<const ConfigOptionEnum<SeamPosition>*>(opt.default_value)->value; //!!
|
||||
int id_value = static_cast<const ConfigOptionEnum<SeamPosition>*>(m_opt.default_value)->value; //!!
|
||||
dynamic_cast<wxComboBox*>(window)->SetSelection(id_value);
|
||||
break;
|
||||
}
|
||||
case coInt:{
|
||||
int val = opt.default_value->getInt(); //!!
|
||||
int val = m_opt.default_value->getInt(); //!!
|
||||
text_value = wxString::Format(_T("%i"), int(val));
|
||||
auto idx = 0;
|
||||
for (auto el : opt.enum_values)
|
||||
for (auto el : m_opt.enum_values)
|
||||
{
|
||||
if (el.compare(text_value) == 0)
|
||||
break;
|
||||
++idx;
|
||||
}
|
||||
idx == opt.enum_values.size() ?
|
||||
idx == m_opt.enum_values.size() ?
|
||||
dynamic_cast<wxComboBox*>(window)->SetValue(text_value) :
|
||||
dynamic_cast<wxComboBox*>(window)->SetSelection(idx);
|
||||
break;
|
||||
|
@ -276,16 +276,16 @@ void Choice::set_selection()
|
|||
// break;
|
||||
// }
|
||||
case coStrings:{
|
||||
text_value = static_cast<const ConfigOptionStrings*>(opt.default_value)->values.at(0);
|
||||
text_value = static_cast<const ConfigOptionStrings*>(m_opt.default_value)->values.at(0);
|
||||
|
||||
auto idx = 0;
|
||||
for (auto el : opt.enum_values)
|
||||
for (auto el : m_opt.enum_values)
|
||||
{
|
||||
if (el.compare(text_value) == 0)
|
||||
break;
|
||||
++idx;
|
||||
}
|
||||
idx == opt.enum_values.size() ?
|
||||
idx == m_opt.enum_values.size() ?
|
||||
dynamic_cast<wxComboBox*>(window)->SetValue(text_value) :
|
||||
dynamic_cast<wxComboBox*>(window)->SetSelection(idx);
|
||||
break;
|
||||
|
@ -295,27 +295,29 @@ void Choice::set_selection()
|
|||
|
||||
void Choice::set_value(const std::string value) //! Redundant?
|
||||
{
|
||||
disable_change_event = true;
|
||||
m_disable_change_event = true;
|
||||
|
||||
auto idx=0;
|
||||
for (auto el : opt.enum_values)
|
||||
for (auto el : m_opt.enum_values)
|
||||
{
|
||||
if (el.compare(value) == 0)
|
||||
break;
|
||||
++idx;
|
||||
}
|
||||
|
||||
idx == opt.enum_values.size() ?
|
||||
idx == m_opt.enum_values.size() ?
|
||||
dynamic_cast<wxComboBox*>(window)->SetValue(value) :
|
||||
dynamic_cast<wxComboBox*>(window)->SetSelection(idx);
|
||||
|
||||
disable_change_event = false;
|
||||
m_disable_change_event = false;
|
||||
}
|
||||
|
||||
//! it's needed for _update_serial_ports()
|
||||
void Choice::set_values(const std::vector<std::string> values)
|
||||
{
|
||||
disable_change_event = true;
|
||||
if (values.empty())
|
||||
return;
|
||||
m_disable_change_event = true;
|
||||
|
||||
// # it looks that Clear() also clears the text field in recent wxWidgets versions,
|
||||
// # but we want to preserve it
|
||||
|
@ -326,75 +328,75 @@ void Choice::set_values(const std::vector<std::string> values)
|
|||
ww->Append(wxString(el));
|
||||
ww->SetValue(value);
|
||||
|
||||
disable_change_event = false;
|
||||
m_disable_change_event = false;
|
||||
}
|
||||
|
||||
void ColourPicker::BUILD()
|
||||
{
|
||||
auto size = wxSize(wxDefaultSize);
|
||||
if (opt.height >= 0) size.SetHeight(opt.height);
|
||||
if (opt.width >= 0) size.SetWidth(opt.width);
|
||||
if (m_opt.height >= 0) size.SetHeight(m_opt.height);
|
||||
if (m_opt.width >= 0) size.SetWidth(m_opt.width);
|
||||
|
||||
wxString clr(static_cast<ConfigOptionStrings*>(opt.default_value)->values.at(0));
|
||||
auto temp = new wxColourPickerCtrl(parent, wxID_ANY, clr, wxDefaultPosition, size);
|
||||
wxString clr(static_cast<ConfigOptionStrings*>(m_opt.default_value)->values.at(0));
|
||||
auto temp = new wxColourPickerCtrl(m_parent, wxID_ANY, clr, wxDefaultPosition, size);
|
||||
|
||||
// // recast as a wxWindow to fit the calling convention
|
||||
window = dynamic_cast<wxWindow*>(temp);
|
||||
|
||||
temp->Bind(wxEVT_COLOURPICKER_CHANGED, ([=](wxCommandEvent e) { _on_change(e); }), temp->GetId());
|
||||
temp->Bind(wxEVT_COLOURPICKER_CHANGED, ([=](wxCommandEvent e) { on_change_field(e); }), temp->GetId());
|
||||
|
||||
if (opt.tooltip.length() > 0) temp->SetToolTip(opt.tooltip);
|
||||
if (m_opt.tooltip.length() > 0) temp->SetToolTip(m_opt.tooltip);
|
||||
|
||||
}
|
||||
|
||||
void Point::BUILD()
|
||||
{
|
||||
auto size = wxSize(wxDefaultSize);
|
||||
if (opt.height >= 0) size.SetHeight(opt.height);
|
||||
if (opt.width >= 0) size.SetWidth(opt.width);
|
||||
if (m_opt.height >= 0) size.SetHeight(m_opt.height);
|
||||
if (m_opt.width >= 0) size.SetWidth(m_opt.width);
|
||||
|
||||
auto temp = new wxBoxSizer(wxHORIZONTAL);
|
||||
// $self->wxSizer($sizer);
|
||||
//
|
||||
wxSize field_size(40, -1);
|
||||
|
||||
auto default_pt = static_cast<ConfigOptionPoints*>(opt.default_value)->values.at(0);
|
||||
auto default_pt = static_cast<ConfigOptionPoints*>(m_opt.default_value)->values.at(0);
|
||||
double val = default_pt.x;
|
||||
wxString X = val - int(val) == 0 ? wxString::Format(_T("%i"), int(val)) : wxNumberFormatter::ToString(val, 2);
|
||||
val = default_pt.y;
|
||||
wxString Y = val - int(val) == 0 ? wxString::Format(_T("%i"), int(val)) : wxNumberFormatter::ToString(val, 2);
|
||||
|
||||
x_textctrl = new wxTextCtrl(parent, wxID_ANY, X, wxDefaultPosition, field_size);
|
||||
y_textctrl = new wxTextCtrl(parent, wxID_ANY, Y, wxDefaultPosition, field_size);
|
||||
x_textctrl = new wxTextCtrl(m_parent, wxID_ANY, X, wxDefaultPosition, field_size);
|
||||
y_textctrl = new wxTextCtrl(m_parent, wxID_ANY, Y, wxDefaultPosition, field_size);
|
||||
|
||||
temp->Add(new wxStaticText(parent, wxID_ANY, "x:")/*, 0, wxALIGN_CENTER_VERTICAL, 0*/);
|
||||
temp->Add(new wxStaticText(m_parent, wxID_ANY, "x:")/*, 0, wxALIGN_CENTER_VERTICAL, 0*/);
|
||||
temp->Add(x_textctrl);
|
||||
temp->Add(new wxStaticText(parent, wxID_ANY, "y:")/*, 0, wxALIGN_CENTER_VERTICAL, 0*/);
|
||||
temp->Add(new wxStaticText(m_parent, wxID_ANY, "y:")/*, 0, wxALIGN_CENTER_VERTICAL, 0*/);
|
||||
temp->Add(y_textctrl);
|
||||
|
||||
x_textctrl->Bind(wxEVT_TEXT, ([=](wxCommandEvent e) { _on_change(e/*$self->option->opt_id*/); }), x_textctrl->GetId());
|
||||
y_textctrl->Bind(wxEVT_TEXT, ([=](wxCommandEvent e) { _on_change(e/*$self->option->opt_id*/); }), x_textctrl->GetId());
|
||||
x_textctrl->Bind(wxEVT_TEXT, ([=](wxCommandEvent e) { on_change_field(e/*$self->option->opt_id*/); }), x_textctrl->GetId());
|
||||
y_textctrl->Bind(wxEVT_TEXT, ([=](wxCommandEvent e) { on_change_field(e/*$self->option->opt_id*/); }), x_textctrl->GetId());
|
||||
|
||||
// // recast as a wxWindow to fit the calling convention
|
||||
sizer = dynamic_cast<wxSizer*>(temp);
|
||||
|
||||
if (opt.tooltip.length() > 0)
|
||||
if (m_opt.tooltip.length() > 0)
|
||||
{
|
||||
x_textctrl->SetToolTip(opt.tooltip);
|
||||
y_textctrl->SetToolTip(opt.tooltip);
|
||||
x_textctrl->SetToolTip(m_opt.tooltip);
|
||||
y_textctrl->SetToolTip(m_opt.tooltip);
|
||||
}
|
||||
}
|
||||
|
||||
void Point::set_value(const Pointf value)
|
||||
{
|
||||
disable_change_event = true;
|
||||
m_disable_change_event = true;
|
||||
|
||||
double val = value.x;
|
||||
x_textctrl->SetValue(val - int(val) == 0 ? wxString::Format(_T("%i"), int(val)) : wxNumberFormatter::ToString(val, 2));
|
||||
val = value.y;
|
||||
y_textctrl->SetValue(val - int(val) == 0 ? wxString::Format(_T("%i"), int(val)) : wxNumberFormatter::ToString(val, 2));
|
||||
|
||||
disable_change_event = false;
|
||||
m_disable_change_event = false;
|
||||
}
|
||||
|
||||
boost::any Point::get_value()
|
||||
|
|
|
@ -23,6 +23,8 @@ namespace Slic3r { namespace GUI {
|
|||
|
||||
class Field;
|
||||
using t_field = std::unique_ptr<Field>;
|
||||
using t_kill_focus = std::function<void(t_config_option_key)>;
|
||||
using t_change = std::function<void(t_config_option_key, boost::any)>;
|
||||
|
||||
class Field {
|
||||
protected:
|
||||
|
@ -35,47 +37,47 @@ protected:
|
|||
/// Call the attached on_kill_focus method.
|
||||
void _on_kill_focus(wxFocusEvent& event);
|
||||
/// Call the attached on_change method.
|
||||
void _on_change(wxCommandEvent& event);
|
||||
void on_change_field(wxCommandEvent& event);
|
||||
|
||||
public:
|
||||
/// parent wx item, opportunity to refactor (probably not necessary - data duplication)
|
||||
wxWindow* parent {nullptr};
|
||||
wxWindow* m_parent {nullptr};
|
||||
|
||||
/// Function object to store callback passed in from owning object.
|
||||
//! t_kill_focus on_kill_focus {nullptr};
|
||||
t_kill_focus on_kill_focus {nullptr};
|
||||
|
||||
/// Function object to store callback passed in from owning object.
|
||||
//! t_change on_change {nullptr};
|
||||
t_change m_on_change {nullptr};
|
||||
|
||||
bool disable_change_event {false};
|
||||
bool m_disable_change_event {false};
|
||||
|
||||
/// Copy of ConfigOption for deduction purposes
|
||||
const ConfigOptionDef opt {ConfigOptionDef()};
|
||||
const t_config_option_key opt_id;//! {""};
|
||||
const ConfigOptionDef m_opt {ConfigOptionDef()};
|
||||
const t_config_option_key m_opt_id;//! {""};
|
||||
|
||||
/// Sets a value for this control.
|
||||
/// subclasses should overload with a specific version
|
||||
/// Postcondition: Method does not fire the on_change event.
|
||||
virtual void set_value(boost::any value) = 0;
|
||||
virtual void set_value(boost::any value) = 0;
|
||||
|
||||
/// Gets a boost::any representing this control.
|
||||
/// subclasses should overload with a specific version
|
||||
virtual boost::any get_value() = 0;
|
||||
virtual boost::any get_value() = 0;
|
||||
|
||||
virtual void enable() = 0;
|
||||
virtual void disable() = 0;
|
||||
virtual void enable() = 0;
|
||||
virtual void disable() = 0;
|
||||
|
||||
/// Fires the enable or disable function, based on the input.
|
||||
inline void toggle(bool en) { en ? enable() : disable(); }
|
||||
inline void toggle(bool en) { en ? enable() : disable(); }
|
||||
|
||||
virtual void set_tooltip(const wxString& tip) = 0;
|
||||
virtual void set_tooltip(const wxString& tip) = 0;
|
||||
|
||||
Field(const ConfigOptionDef& opt, const t_config_option_key& id) : opt(opt), opt_id(id) {};
|
||||
Field(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : parent(parent), opt(opt), opt_id(id) {};
|
||||
Field(const ConfigOptionDef& opt, const t_config_option_key& id) : m_opt(opt), m_opt_id(id) {};
|
||||
Field(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : m_parent(parent), m_opt(opt), m_opt_id(id) {};
|
||||
|
||||
/// If you don't know what you are getting back, check both methods for nullptr.
|
||||
virtual wxSizer* getSizer() { return nullptr; }
|
||||
virtual wxWindow* getWindow() { return nullptr; }
|
||||
virtual wxSizer* getSizer() { return nullptr; }
|
||||
virtual wxWindow* getWindow() { return nullptr; }
|
||||
|
||||
bool is_matched(std::string string, std::string pattern);
|
||||
|
||||
|
@ -210,14 +212,14 @@ public:
|
|||
wxWindow* window{ nullptr };
|
||||
void BUILD() override;
|
||||
|
||||
void set_selection();
|
||||
// void set_selection();
|
||||
void set_value(const std::string value) {
|
||||
dynamic_cast<wxColourPickerCtrl*>(window)->SetColour(value);
|
||||
}
|
||||
void set_value(boost::any value) {
|
||||
dynamic_cast<wxColourPickerCtrl*>(window)->SetColour(boost::any_cast<std::string>(value));
|
||||
}
|
||||
void set_values(const std::vector<std::string> values);
|
||||
// void set_values(const std::vector<std::string> values);
|
||||
boost::any get_value() override {
|
||||
return boost::any(dynamic_cast<wxColourPickerCtrl*>(window)->GetColour());
|
||||
}
|
||||
|
|
|
@ -32,11 +32,7 @@
|
|||
#include <wx/window.h>
|
||||
|
||||
#include "Tab.h"
|
||||
|
||||
//#include <wx/bmpcbox.h>
|
||||
//#include <wx/bmpbuttn.h>
|
||||
//#include <wx/treectrl.h>
|
||||
//#include <wx/imaglist.h>
|
||||
#include "AppConfig.hpp"
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
|
@ -189,15 +185,53 @@ void add_debug_menu(wxMenuBar *menu)
|
|||
}
|
||||
|
||||
void create_preset_tabs(PresetBundle *preset_bundle, AppConfig *app_config)
|
||||
{
|
||||
add_created_tab(new CTabPrint (g_wxTabPanel, "Print"), preset_bundle, app_config);
|
||||
add_created_tab(new CTabFilament(g_wxTabPanel, "Filament"), preset_bundle, app_config);
|
||||
add_created_tab(new CTabPrinter (g_wxTabPanel, "Printer"), preset_bundle, app_config);
|
||||
{
|
||||
add_created_tab(new TabPrint (g_wxTabPanel, "Print"), preset_bundle, app_config);
|
||||
add_created_tab(new TabFilament(g_wxTabPanel, "Filament"), preset_bundle, app_config);
|
||||
add_created_tab(new TabPrinter (g_wxTabPanel, "Printer"), preset_bundle, app_config);
|
||||
}
|
||||
|
||||
void add_created_tab(CTab* panel, PresetBundle *preset_bundle, AppConfig *app_config)
|
||||
void add_created_tab(Tab* panel, PresetBundle *preset_bundle, AppConfig *app_config)
|
||||
{
|
||||
panel->create_preset_tab(preset_bundle, app_config);
|
||||
panel->m_no_controller = app_config->get("no_controller").empty();
|
||||
panel->create_preset_tab(preset_bundle);
|
||||
// Callback to be executed after any of the configuration fields(Perl class Slic3r::GUI::OptionsGroup::Field) change their value.
|
||||
panel->m_on_value_change = [/*this*/](std::string opt_key, boost::any value){
|
||||
//! plater & loaded - variables of MainFrame
|
||||
// if (plater) {
|
||||
// plater->on_config_change(m_config); //# propagate config change events to the plater
|
||||
// if (opt_key.compare("extruders_count") plater->on_extruders_change(value);
|
||||
// }
|
||||
// don't save while loading for the first time
|
||||
// if (loaded && Slic3r::GUI::autosave) m_config->save(Slic3r::GUI::autosave) ;
|
||||
};
|
||||
|
||||
// # Install a callback for the tab to update the platter and print controller presets, when
|
||||
// # a preset changes at Slic3r::GUI::Tab.
|
||||
// $tab->on_presets_changed(sub{
|
||||
// if ($self->{plater}) {
|
||||
// # Update preset combo boxes(Print settings, Filament, Printer) from their respective tabs.
|
||||
// $self->{plater}->update_presets($tab_name, @_);
|
||||
// if ($tab_name eq 'printer') {
|
||||
// # Printer selected at the Printer tab, update "compatible" marks at the print and filament selectors.
|
||||
// my($presets, $reload_dependent_tabs) = @_;
|
||||
// for my $tab_name_other(qw(print filament)) {
|
||||
// # If the printer tells us that the print or filament preset has been switched or invalidated,
|
||||
// # refresh the print or filament tab page.Otherwise just refresh the combo box.
|
||||
// my $update_action = ($reload_dependent_tabs && (first{ $_ eq $tab_name_other } (@{$reload_dependent_tabs})))
|
||||
// ? 'load_current_preset' : 'update_tab_ui';
|
||||
// $self->{options_tabs}{$tab_name_other}->$update_action;
|
||||
// }
|
||||
// # Update the controller printers.
|
||||
// $self->{controller}->update_presets(@_) if $self->{controller};
|
||||
// }
|
||||
// $self->{plater}->on_config_change($tab->{presets}->get_current_preset->config);
|
||||
// }
|
||||
// });
|
||||
|
||||
//# Load the currently selected preset into the GUI, update the preset selection box.
|
||||
// panel->load_current_preset;
|
||||
|
||||
g_wxTabPanel->AddPage(panel, panel->title());
|
||||
}
|
||||
|
||||
|
|
|
@ -13,11 +13,12 @@ class wxNotebook;
|
|||
namespace Slic3r {
|
||||
|
||||
class PresetBundle;
|
||||
class PresetCollection;
|
||||
class AppConfig;
|
||||
|
||||
namespace GUI {
|
||||
|
||||
class CTab;
|
||||
class Tab;
|
||||
|
||||
void disable_screensaver();
|
||||
void enable_screensaver();
|
||||
|
@ -34,7 +35,7 @@ void add_debug_menu(wxMenuBar *menu);
|
|||
// Create a new preset tab (print, filament and printer),
|
||||
void create_preset_tabs(PresetBundle *preset_bundle, AppConfig *app_config);
|
||||
// add it at the end of the tab panel.
|
||||
void add_created_tab(CTab* panel, PresetBundle *preset_bundle, AppConfig *app_config);
|
||||
void add_created_tab(Tab* panel, PresetBundle *preset_bundle, AppConfig *app_config);
|
||||
|
||||
void show_error(wxWindow* parent, std::string message);
|
||||
void show_info(wxWindow* parent, std::string message, std::string title);
|
||||
|
|
|
@ -10,7 +10,7 @@ const t_field& OptionsGroup::build_field(const Option& opt) {
|
|||
return build_field(opt.opt_id, opt.opt);
|
||||
}
|
||||
const t_field& OptionsGroup::build_field(const t_config_option_key& id) {
|
||||
const ConfigOptionDef& opt = options.at(id);
|
||||
const ConfigOptionDef& opt = m_options_map.at(id);
|
||||
return build_field(id, opt);
|
||||
}
|
||||
|
||||
|
@ -19,13 +19,13 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co
|
|||
// is the normal type.
|
||||
if (opt.gui_type.compare("select") == 0) {
|
||||
} else if (opt.gui_type.compare("select_open") == 0) {
|
||||
fields.emplace(id, STDMOVE(Choice::Create<Choice>(_parent, opt, id)));
|
||||
m_fields.emplace(id, STDMOVE(Choice::Create<Choice>(m_parent, opt, id)));
|
||||
} else if (opt.gui_type.compare("color") == 0) {
|
||||
fields.emplace(id, STDMOVE(ColourPicker::Create<ColourPicker>(_parent, opt, id)));
|
||||
m_fields.emplace(id, STDMOVE(ColourPicker::Create<ColourPicker>(m_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) {
|
||||
fields.emplace(id, STDMOVE(Choice::Create<Choice>(_parent, opt, id)));
|
||||
m_fields.emplace(id, STDMOVE(Choice::Create<Choice>(m_parent, opt, id)));
|
||||
} else if (opt.gui_type.compare("slider") == 0) {
|
||||
} else if (opt.gui_type.compare("i_spin") == 0) { // Spinctrl
|
||||
} else {
|
||||
|
@ -37,21 +37,21 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co
|
|||
case coPercents:
|
||||
case coString:
|
||||
case coStrings:
|
||||
fields.emplace(id, STDMOVE(TextCtrl::Create<TextCtrl>(_parent, opt, id)));
|
||||
m_fields.emplace(id, STDMOVE(TextCtrl::Create<TextCtrl>(m_parent, opt, id)));
|
||||
break;
|
||||
case coBool:
|
||||
case coBools:
|
||||
fields.emplace(id, STDMOVE(CheckBox::Create<CheckBox>(_parent, opt, id)));
|
||||
m_fields.emplace(id, STDMOVE(CheckBox::Create<CheckBox>(m_parent, opt, id)));
|
||||
break;
|
||||
case coInt:
|
||||
case coInts:
|
||||
fields.emplace(id, STDMOVE(SpinCtrl::Create<SpinCtrl>(_parent, opt, id)));
|
||||
m_fields.emplace(id, STDMOVE(SpinCtrl::Create<SpinCtrl>(m_parent, opt, id)));
|
||||
break;
|
||||
case coEnum:
|
||||
fields.emplace(id, STDMOVE(Choice::Create<Choice>(_parent, opt, id)));
|
||||
m_fields.emplace(id, STDMOVE(Choice::Create<Choice>(m_parent, opt, id)));
|
||||
break;
|
||||
case coPoints:
|
||||
fields.emplace(id, STDMOVE(Point::Create<Point>(_parent, opt, id)));
|
||||
m_fields.emplace(id, STDMOVE(Point::Create<Point>(m_parent, opt, id)));
|
||||
break;
|
||||
case coNone: break;
|
||||
default:
|
||||
|
@ -59,9 +59,14 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co
|
|||
}
|
||||
}
|
||||
// Grab a reference to fields for convenience
|
||||
const t_field& field = fields[id];
|
||||
//! field->on_change = [this](std::string id, boost::any val) { };
|
||||
field->parent = parent();
|
||||
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);
|
||||
};
|
||||
field->m_parent = parent();
|
||||
// assign function objects for callbacks, etc.
|
||||
return field;
|
||||
}
|
||||
|
@ -74,7 +79,7 @@ void OptionsGroup::append_line(const Line& line) {
|
|||
return;
|
||||
}
|
||||
if (line.widget != nullptr) {
|
||||
sizer->Add(line.widget(_parent), 0, wxEXPAND | wxALL, wxOSX ? 0 : 15);
|
||||
sizer->Add(line.widget(m_parent), 0, wxEXPAND | wxALL, wxOSX ? 0 : 15);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +100,7 @@ void OptionsGroup::append_line(const Line& line) {
|
|||
return;
|
||||
}
|
||||
|
||||
auto grid_sizer = _grid_sizer;
|
||||
auto grid_sizer = m_grid_sizer;
|
||||
|
||||
// Build a label if we have it
|
||||
if (label_width != 0) {
|
||||
|
@ -146,8 +151,6 @@ void OptionsGroup::append_line(const Line& line) {
|
|||
|
||||
// add field
|
||||
const Option& opt_ref = opt;
|
||||
//! auto field = build_field(opt_ref)->getWindow();
|
||||
//! sizer->Add(field, 0, wxALIGN_CENTER_VERTICAL, 0);
|
||||
auto& field = build_field(opt_ref);
|
||||
is_sizer_field(field) ?
|
||||
sizer->Add(field->getSizer(), 0, wxALIGN_CENTER_VERTICAL, 0) :
|
||||
|
@ -184,14 +187,45 @@ Line OptionsGroup::create_single_option_line(const Option& option) const {
|
|||
return retval;
|
||||
}
|
||||
|
||||
//! void OptionsGroup::_on_change(t_config_option_key id, config_value value) {
|
||||
//! if (on_change != nullptr)
|
||||
//! on_change(id, value);
|
||||
//! }
|
||||
void OptionsGroup::on_change_OG(t_config_option_key id, /*config_value*/boost::any value) {
|
||||
if (m_on_change != nullptr)
|
||||
m_on_change(id, value);
|
||||
}
|
||||
|
||||
void OptionsGroup::_on_kill_focus (t_config_option_key id) {
|
||||
// do nothing.
|
||||
}
|
||||
|
||||
void ConfigOptionsGroup::on_change_OG(t_config_option_key opt_id, boost::any value)
|
||||
{
|
||||
// if (m_options_map.at(opt_id)/*exists $self->_opt_map->{$opt_id}*/) {
|
||||
// my($opt_key, $opt_index) = @{ $self->_opt_map->{$opt_id} };
|
||||
// auto option = m_options->{$opt_id};
|
||||
|
||||
}}
|
||||
// get value
|
||||
auto field_value = get_value(opt_id);
|
||||
// if ($option->gui_flags = ~/ \bserialized\b / ) {
|
||||
// die "Can't set serialized option indexed value" if $opt_index != -1;
|
||||
// # Split a string to multiple strings by a semi - colon.This is the old way of storing multi - string values.
|
||||
// # Currently used for the post_process config value only.
|
||||
// my @values = split / ; / , $field_value;
|
||||
// $self->config->set($opt_key, \@values);
|
||||
// }
|
||||
// else {
|
||||
// if ($opt_index == -1) {
|
||||
// $self->config->set($opt_key, $field_value);
|
||||
//! m_config->set_key_value(opt_id, new ConfigOption(value));
|
||||
// }
|
||||
// else {
|
||||
// my $value = $self->config->get($opt_key);
|
||||
// $value->[$opt_index] = $field_value;
|
||||
// $self->config->set($opt_key, $value);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
OptionsGroup::on_change_OG(opt_id, value);
|
||||
}
|
||||
|
||||
} // GUI
|
||||
} // Slic3r
|
||||
|
|
|
@ -33,118 +33,119 @@ class StaticText;
|
|||
|
||||
/// Wraps a ConfigOptionDef and adds function object for creating a side_widget.
|
||||
struct Option {
|
||||
ConfigOptionDef opt { ConfigOptionDef() };
|
||||
t_config_option_key opt_id;//! {""};
|
||||
widget_t side_widget {nullptr};
|
||||
bool readonly {false};
|
||||
ConfigOptionDef opt { ConfigOptionDef() };
|
||||
t_config_option_key opt_id;//! {""};
|
||||
widget_t side_widget {nullptr};
|
||||
bool readonly {false};
|
||||
|
||||
Option(const ConfigOptionDef& _opt, t_config_option_key id) : opt(_opt), opt_id(id) {};
|
||||
Option(const ConfigOptionDef& _opt, t_config_option_key id) :
|
||||
opt(_opt), opt_id(id) {}
|
||||
};
|
||||
using t_option = std::unique_ptr<Option>; //!
|
||||
|
||||
/// Represents option lines
|
||||
class Line {
|
||||
public:
|
||||
wxString label {wxString("")};
|
||||
wxString label_tooltip {wxString("")};
|
||||
size_t full_width {0};
|
||||
wxSizer* sizer {nullptr};
|
||||
widget_t widget {nullptr};
|
||||
wxString label {wxString("")};
|
||||
wxString label_tooltip {wxString("")};
|
||||
size_t full_width {0};
|
||||
wxSizer* sizer {nullptr};
|
||||
widget_t widget {nullptr};
|
||||
|
||||
void append_option(const Option& option) {
|
||||
_options.push_back(option);
|
||||
m_options.push_back(option);
|
||||
}
|
||||
void append_widget(const widget_t widget) {
|
||||
_extra_widgets.push_back(widget);
|
||||
m_extra_widgets.push_back(widget);
|
||||
}
|
||||
Line(std::string label, std::string tooltip) : label(wxString(label)), label_tooltip(wxString(tooltip)) {} ;
|
||||
Line(std::string label, std::string tooltip) :
|
||||
label(wxString(label)), label_tooltip(wxString(tooltip)) {}
|
||||
|
||||
const std::vector<widget_t>& get_extra_widgets() const {return _extra_widgets;}
|
||||
const std::vector<Option>& get_options() const { return _options; }
|
||||
const std::vector<widget_t>& get_extra_widgets() const {return m_extra_widgets;}
|
||||
const std::vector<Option>& get_options() const { return m_options; }
|
||||
|
||||
private:
|
||||
std::vector<Option> _options;//! {std::vector<Option>()};
|
||||
std::vector<widget_t> _extra_widgets;//! {std::vector<widget_t>()};
|
||||
std::vector<Option> m_options;//! {std::vector<Option>()};
|
||||
std::vector<widget_t> m_extra_widgets;//! {std::vector<widget_t>()};
|
||||
};
|
||||
|
||||
using t_optionfield_map = std::map<t_config_option_key, t_field>;
|
||||
|
||||
class OptionsGroup {
|
||||
public:
|
||||
const bool staticbox {true};
|
||||
const wxString title {wxString("")};
|
||||
size_t label_width {200};
|
||||
wxSizer* sizer {nullptr};
|
||||
column_t extra_column {nullptr};
|
||||
t_change m_on_change {nullptr};
|
||||
|
||||
const bool staticbox {true};
|
||||
const wxString title {wxString("")};
|
||||
size_t label_width {200};
|
||||
wxSizer* sizer {nullptr};
|
||||
column_t extra_column {nullptr};
|
||||
// t_change on_change {nullptr};
|
||||
wxFont sidetext_font {wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) };
|
||||
wxFont label_font {wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) };
|
||||
|
||||
/// Returns a copy of the pointer of the parent wxWindow.
|
||||
/// Accessor function is because users are not allowed to change the parent
|
||||
/// but defining it as const means a lot of const_casts to deal with wx functions.
|
||||
inline wxWindow* parent() const { return _parent; }
|
||||
inline wxWindow* parent() const { return m_parent; }
|
||||
|
||||
wxFont sidetext_font {wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) };
|
||||
wxFont label_font {wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) };
|
||||
|
||||
|
||||
void append_line(const Line& line);
|
||||
/*virtual*/ Line create_single_option_line(const Option& option) const;
|
||||
inline void append_single_option_line(const Option& option) { append_line(create_single_option_line(option)); }
|
||||
void append_line(const Line& line);
|
||||
Line create_single_option_line(const Option& option) const;
|
||||
inline void append_single_option_line(const Option& option) { append_line(create_single_option_line(option)); }
|
||||
|
||||
// return a non-owning pointer reference
|
||||
inline const Field* get_field(t_config_option_key id) const { try { return fields.at(id).get(); } catch (std::out_of_range e) { return nullptr; } }
|
||||
inline /*const*/ Field* get_field(t_config_option_key id) const { try { return m_fields.at(id).get(); } catch (std::out_of_range e) { return nullptr; } }
|
||||
//! inline const Option& get_option(t_config_option_key id) const { try { return options.at(id).get(); } catch (std::out_of_range e) { return nullptr; } }
|
||||
// }
|
||||
//! inline void set_value(t_config_option_key id, boost::any value) { try { fields.at(id).set_value(value); } catch (std::out_of_range e) {;} }
|
||||
inline void set_value(t_config_option_key id, boost::any value) { try { m_fields.at(id)->set_value(value); } catch (std::out_of_range e) {;} }
|
||||
boost::any get_value(t_config_option_key id) { try { return m_fields.at(id)->get_value(); } catch (std::out_of_range e) { ; } }
|
||||
|
||||
inline void enable() { for (auto& field : fields) field.second->enable(); }
|
||||
inline void disable() { for (auto& field : fields) field.second->disable(); }
|
||||
inline void enable() { for (auto& field : m_fields) field.second->enable(); }
|
||||
inline void disable() { for (auto& field : m_fields) field.second->disable(); }
|
||||
|
||||
|
||||
|
||||
OptionsGroup(wxWindow* _parent, std::string title, const ConfigDef& configs) : options(configs.options), _parent(_parent), title(wxString(title)) {
|
||||
OptionsGroup(wxWindow* _parent, std::string title, const ConfigDef& configs) :
|
||||
m_options_map(configs.options), m_parent(_parent), title(wxString(title)) {
|
||||
sizer = (staticbox ? new wxStaticBoxSizer(new wxStaticBox(_parent, wxID_ANY, title), wxVERTICAL) : new wxBoxSizer(wxVERTICAL));
|
||||
auto num_columns = 1U;
|
||||
if (label_width != 0) num_columns++;
|
||||
if (extra_column != nullptr) num_columns++;
|
||||
_grid_sizer = new wxFlexGridSizer(0, num_columns, 0,0);
|
||||
static_cast<wxFlexGridSizer*>(_grid_sizer)->SetFlexibleDirection(wxHORIZONTAL);
|
||||
static_cast<wxFlexGridSizer*>(_grid_sizer)->AddGrowableCol(label_width != 0);
|
||||
m_grid_sizer = new wxFlexGridSizer(0, num_columns, 0,0);
|
||||
static_cast<wxFlexGridSizer*>(m_grid_sizer)->SetFlexibleDirection(wxHORIZONTAL);
|
||||
static_cast<wxFlexGridSizer*>(m_grid_sizer)->AddGrowableCol(label_width != 0);
|
||||
|
||||
sizer->Add(_grid_sizer, 0, wxEXPAND | wxALL, wxOSX ? 0: 5);
|
||||
};
|
||||
sizer->Add(m_grid_sizer, 0, wxEXPAND | wxALL, wxOSX ? 0: 5);
|
||||
}
|
||||
|
||||
protected:
|
||||
const t_optiondef_map& options;
|
||||
wxWindow* _parent {nullptr};
|
||||
const t_optiondef_map& m_options_map;
|
||||
wxWindow* m_parent {nullptr};
|
||||
|
||||
/// Field list, contains unique_ptrs of the derived type.
|
||||
/// using types that need to know what it is beyond the public interface
|
||||
/// need to cast based on the related ConfigOptionDef.
|
||||
t_optionfield_map fields;
|
||||
bool _disabled {false};
|
||||
wxGridSizer* _grid_sizer {nullptr};
|
||||
t_optionfield_map m_fields;
|
||||
bool m_disabled {false};
|
||||
wxGridSizer* m_grid_sizer {nullptr};
|
||||
|
||||
/// Generate a wxSizer or wxWindow from a configuration option
|
||||
/// Precondition: opt resolves to a known ConfigOption
|
||||
/// Postcondition: fields contains a wx gui object.
|
||||
const t_field& build_field(const t_config_option_key& id, const ConfigOptionDef& opt);
|
||||
const t_field& build_field(const t_config_option_key& id);
|
||||
const t_field& build_field(const Option& opt);
|
||||
|
||||
virtual void _on_kill_focus (t_config_option_key id);
|
||||
//! virtual void _on_change(t_config_option_key id, config_value value);
|
||||
|
||||
const t_field& build_field(const t_config_option_key& id, const ConfigOptionDef& opt);
|
||||
const t_field& build_field(const t_config_option_key& id);
|
||||
const t_field& build_field(const Option& opt);
|
||||
|
||||
virtual void _on_kill_focus (t_config_option_key id);
|
||||
virtual void on_change_OG(t_config_option_key opt_id, boost::any value);
|
||||
};
|
||||
|
||||
class ConfigOptionsGroup: public OptionsGroup {
|
||||
public:
|
||||
/// reference to libslic3r config, non-owning pointer (?).
|
||||
const DynamicPrintConfig* config {nullptr};
|
||||
bool full_labels {0};
|
||||
ConfigOptionsGroup(wxWindow* parent, std::string title, DynamicPrintConfig* _config) : OptionsGroup(parent, title, *(_config->def())), config(_config) {}
|
||||
const DynamicPrintConfig* m_config {nullptr};
|
||||
bool m_full_labels {0};
|
||||
ConfigOptionsGroup(wxWindow* parent, std::string title, DynamicPrintConfig* _config) :
|
||||
OptionsGroup(parent, title, *(_config->def())), m_config(_config) {}
|
||||
|
||||
void on_change_OG(t_config_option_key opt_id, boost::any value) override;
|
||||
};
|
||||
|
||||
}}
|
||||
|
|
|
@ -21,12 +21,12 @@ namespace Slic3r {
|
|||
namespace GUI {
|
||||
|
||||
// sub new
|
||||
void CTab::create_preset_tab(PresetBundle *preset_bundle, AppConfig *app_config)
|
||||
void Tab::create_preset_tab(PresetBundle *preset_bundle)
|
||||
{
|
||||
m_preset_bundle = preset_bundle;
|
||||
m_app_config = app_config;
|
||||
|
||||
// Vertical sizer to hold the choice menu and the rest of the page.
|
||||
CTab *panel = this;
|
||||
Tab *panel = this;
|
||||
auto *sizer = new wxBoxSizer(wxVERTICAL);
|
||||
sizer->SetSizeHints(panel);
|
||||
panel->SetSizer(sizer);
|
||||
|
@ -93,13 +93,13 @@ void CTab::create_preset_tab(PresetBundle *preset_bundle, AppConfig *app_config)
|
|||
m_treectrl->SetIndent(0);
|
||||
m_disable_tree_sel_changed_event = 0;
|
||||
|
||||
m_treectrl->Bind(wxEVT_TREE_SEL_CHANGED, &CTab::OnTreeSelChange, this);
|
||||
m_treectrl->Bind(wxEVT_KEY_DOWN, &CTab::OnKeyDown, this);
|
||||
m_treectrl->Bind(wxEVT_COMBOBOX, &CTab::OnComboBox, this);
|
||||
m_treectrl->Bind(wxEVT_TREE_SEL_CHANGED, &Tab::OnTreeSelChange, this);
|
||||
m_treectrl->Bind(wxEVT_KEY_DOWN, &Tab::OnKeyDown, this);
|
||||
m_treectrl->Bind(wxEVT_COMBOBOX, &Tab::OnComboBox, this);
|
||||
|
||||
m_btn_save_preset->Bind(wxEVT_BUTTON, &CTab::save_preset, this);
|
||||
m_btn_delete_preset->Bind(wxEVT_BUTTON, &CTab::delete_preset, this);
|
||||
m_btn_hide_incompatible_presets->Bind(wxEVT_BUTTON, &CTab::toggle_show_hide_incompatible, this);
|
||||
m_btn_save_preset->Bind(wxEVT_BUTTON, &Tab::save_preset, this);
|
||||
m_btn_delete_preset->Bind(wxEVT_BUTTON, &Tab::delete_preset, this);
|
||||
m_btn_hide_incompatible_presets->Bind(wxEVT_BUTTON, &Tab::toggle_show_hide_incompatible, this);
|
||||
|
||||
// Initialize the DynamicPrintConfig by default keys/values.
|
||||
// Possible %params keys: no_controller
|
||||
|
@ -108,7 +108,7 @@ void CTab::create_preset_tab(PresetBundle *preset_bundle, AppConfig *app_config)
|
|||
// _update();
|
||||
}
|
||||
|
||||
CPageShp CTab::add_options_page(wxString title, std::string icon, bool is_extruder_pages/* = false*/)
|
||||
PageShp Tab::add_options_page(wxString title, std::string icon, bool is_extruder_pages/* = false*/)
|
||||
{
|
||||
// Index of icon in an icon list $self->{icons}.
|
||||
auto icon_idx = 0;
|
||||
|
@ -124,7 +124,7 @@ CPageShp CTab::add_options_page(wxString title, std::string icon, bool is_extrud
|
|||
}
|
||||
}
|
||||
// Initialize the page.
|
||||
CPageShp page(new CPage(this, title, icon_idx));
|
||||
PageShp page(new Page(this, title, icon_idx));
|
||||
page->SetScrollbars(1, 1, 1, 1);
|
||||
page->Hide();
|
||||
m_hsizer->Add(page.get(), 1, wxEXPAND | wxLEFT, 5);
|
||||
|
@ -135,7 +135,64 @@ CPageShp CTab::add_options_page(wxString title, std::string icon, bool is_extrud
|
|||
return page;
|
||||
}
|
||||
|
||||
void CTab::load_key_value(std::string opt_key, std::vector<std::string> value)
|
||||
// Update the combo box label of the selected preset based on its "dirty" state,
|
||||
// comparing the selected preset config with $self->{config}.
|
||||
void Tab::update_dirty(){
|
||||
m_presets->update_dirty_ui(m_presets_choice);
|
||||
// _on_presets_changed;
|
||||
}
|
||||
|
||||
// Load a provied DynamicConfig into the tab, modifying the active preset.
|
||||
// This could be used for example by setting a Wipe Tower position by interactive manipulation in the 3D view.
|
||||
void Tab::load_config(DynamicPrintConfig config)
|
||||
{
|
||||
bool modified = 0;
|
||||
for(auto opt_key : m_config.diff(config)) {
|
||||
ConfigOption* opt;
|
||||
switch ( config.def()->get(opt_key)->type ){
|
||||
// case coFloatOrPercent:
|
||||
case coPercent:
|
||||
// case coPercents:
|
||||
case coFloat:
|
||||
opt = new ConfigOptionFloat(config.opt_float(opt_key));
|
||||
break;
|
||||
// case coFloats:
|
||||
case coString:
|
||||
opt = new ConfigOptionString(config.opt_string(opt_key));
|
||||
break;
|
||||
case coStrings:
|
||||
break;
|
||||
case coBool:
|
||||
opt = new ConfigOptionBool(config.opt_bool(opt_key));
|
||||
break;
|
||||
case coBools:
|
||||
// opt = new ConfigOptionBools(0, config.opt_bool(opt_key)); //! 0?
|
||||
break;
|
||||
case coInt:
|
||||
opt = new ConfigOptionInt(config.opt_int(opt_key));
|
||||
break;
|
||||
case coInts:
|
||||
break;
|
||||
case coEnum:
|
||||
break;
|
||||
case coPoints:
|
||||
break;
|
||||
case coNone: break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
m_config.set_key_value(opt_key, opt);
|
||||
modified = 1;
|
||||
}
|
||||
if (modified) {
|
||||
// update_dirty();
|
||||
//# Initialize UI components with the config values.
|
||||
// _reload_config();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void Tab::load_key_value(std::string opt_key, std::vector<std::string> value)
|
||||
{
|
||||
// # To be called by custom widgets, load a value into a config,
|
||||
// # update the preset selection boxes (the dirty flags)
|
||||
|
@ -151,9 +208,10 @@ void CTab::load_key_value(std::string opt_key, std::vector<std::string> value)
|
|||
// $self->_update;
|
||||
}
|
||||
|
||||
void CTabPrint::build()
|
||||
void TabPrint::build()
|
||||
{
|
||||
m_config = m_preset_bundle->prints.get_edited_preset().config;
|
||||
m_presets = &m_preset_bundle->prints;
|
||||
m_config = m_presets->get_edited_preset().config;
|
||||
m_config_def = m_config.def();
|
||||
|
||||
auto page = add_options_page("Layers and perimeters", "layers.png");
|
||||
|
@ -352,7 +410,211 @@ void CTabPrint::build()
|
|||
optgroup->append_line(line);
|
||||
}
|
||||
|
||||
void CTabFilament::build()
|
||||
void TabPrint::update()
|
||||
{
|
||||
Freeze();
|
||||
|
||||
if ( m_config.opt_bool("spiral_vase") &&
|
||||
!(m_config.opt_int("perimeters") == 1 && m_config.opt_int("top_solid_layers") == 0 && m_config.opt_float("fill_density") == 0)) {
|
||||
std::string msg_text = "The Spiral Vase mode requires:\n"
|
||||
"- one perimeter\n"
|
||||
"- no top solid layers\n"
|
||||
"- 0% fill density\n"
|
||||
"- no support material\n"
|
||||
"- no ensure_vertical_shell_thickness\n"
|
||||
"\nShall I adjust those settings in order to enable Spiral Vase?";
|
||||
auto dialog = new wxMessageDialog(parent(), msg_text, wxT("Spiral Vase"), wxICON_WARNING | wxYES | wxNO);
|
||||
DynamicPrintConfig new_conf = m_config;//new DynamicPrintConfig;
|
||||
if (dialog->ShowModal() == wxID_YES) {
|
||||
new_conf.set_key_value("perimeters", new ConfigOptionInt(1));
|
||||
new_conf.set_key_value("top_solid_layers", new ConfigOptionInt(0));
|
||||
new_conf.set_key_value("fill_density", new ConfigOptionPercent(0));
|
||||
new_conf.set_key_value("support_material", new ConfigOptionBool(false));
|
||||
new_conf.set_key_value("ensure_vertical_shell_thickness", new ConfigOptionBool(false));
|
||||
}
|
||||
else {
|
||||
new_conf.set_key_value("spiral_vase", new ConfigOptionBool(false));
|
||||
}
|
||||
load_config(new_conf);
|
||||
}
|
||||
|
||||
// if ($config->wipe_tower &&
|
||||
// ($config->first_layer_height != 0.2 || $config->layer_height < 0.15 || $config->layer_height > 0.35)) {
|
||||
// my $dialog = Wx::MessageDialog->new($self,
|
||||
// "The Wipe Tower currently supports only:\n"
|
||||
// . "- first layer height 0.2mm\n"
|
||||
// . "- layer height from 0.15mm to 0.35mm\n"
|
||||
// . "\nShall I adjust those settings in order to enable the Wipe Tower?",
|
||||
// 'Wipe Tower', wxICON_WARNING | wxYES | wxNO);
|
||||
// my $new_conf = Slic3r::Config->new;
|
||||
// if ($dialog->ShowModal() == wxID_YES) {
|
||||
// $new_conf->set("first_layer_height", 0.2);
|
||||
// $new_conf->set("layer_height", 0.15) if $config->layer_height < 0.15;
|
||||
// $new_conf->set("layer_height", 0.35) if $config->layer_height > 0.35;
|
||||
// }
|
||||
// else {
|
||||
// $new_conf->set("wipe_tower", 0);
|
||||
// }
|
||||
// $self->load_config($new_conf);
|
||||
// }
|
||||
//
|
||||
// if ($config->wipe_tower && $config->support_material && $config->support_material_contact_distance > 0. &&
|
||||
// ($config->support_material_extruder != 0 || $config->support_material_interface_extruder != 0)) {
|
||||
// my $dialog = Wx::MessageDialog->new($self,
|
||||
// "The Wipe Tower currently supports the non-soluble supports only\n"
|
||||
// . "if they are printed with the current extruder without triggering a tool change.\n"
|
||||
// . "(both support_material_extruder and support_material_interface_extruder need to be set to 0).\n"
|
||||
// . "\nShall I adjust those settings in order to enable the Wipe Tower?",
|
||||
// 'Wipe Tower', wxICON_WARNING | wxYES | wxNO);
|
||||
// my $new_conf = Slic3r::Config->new;
|
||||
// if ($dialog->ShowModal() == wxID_YES) {
|
||||
// $new_conf->set("support_material_extruder", 0);
|
||||
// $new_conf->set("support_material_interface_extruder", 0);
|
||||
// }
|
||||
// else {
|
||||
// $new_conf->set("wipe_tower", 0);
|
||||
// }
|
||||
// $self->load_config($new_conf);
|
||||
// }
|
||||
//
|
||||
// if ($config->wipe_tower && $config->support_material && $config->support_material_contact_distance == 0 &&
|
||||
// !$config->support_material_synchronize_layers) {
|
||||
// my $dialog = Wx::MessageDialog->new($self,
|
||||
// "For the Wipe Tower to work with the soluble supports, the support layers\n"
|
||||
// . "need to be synchronized with the object layers.\n"
|
||||
// . "\nShall I synchronize support layers in order to enable the Wipe Tower?",
|
||||
// 'Wipe Tower', wxICON_WARNING | wxYES | wxNO);
|
||||
// my $new_conf = Slic3r::Config->new;
|
||||
// if ($dialog->ShowModal() == wxID_YES) {
|
||||
// $new_conf->set("support_material_synchronize_layers", 1);
|
||||
// }
|
||||
// else {
|
||||
// $new_conf->set("wipe_tower", 0);
|
||||
// }
|
||||
// $self->load_config($new_conf);
|
||||
// }
|
||||
//
|
||||
// if ($config->support_material) {
|
||||
// # Ask only once.
|
||||
// if (!$self->{support_material_overhangs_queried}) {
|
||||
// $self->{support_material_overhangs_queried} = 1;
|
||||
// if ($config->overhangs != 1) {
|
||||
// my $dialog = Wx::MessageDialog->new($self,
|
||||
// "Supports work better, if the following feature is enabled:\n"
|
||||
// . "- Detect bridging perimeters\n"
|
||||
// . "\nShall I adjust those settings for supports?",
|
||||
// 'Support Generator', wxICON_WARNING | wxYES | wxNO | wxCANCEL);
|
||||
// my $answer = $dialog->ShowModal();
|
||||
// my $new_conf = Slic3r::Config->new;
|
||||
// if ($answer == wxID_YES) {
|
||||
// # Enable "detect bridging perimeters".
|
||||
// $new_conf->set("overhangs", 1);
|
||||
// } elsif($answer == wxID_NO) {
|
||||
// # Do nothing, leave supports on and "detect bridging perimeters" off.
|
||||
// } elsif($answer == wxID_CANCEL) {
|
||||
// # Disable supports.
|
||||
// $new_conf->set("support_material", 0);
|
||||
// $self->{support_material_overhangs_queried} = 0;
|
||||
// }
|
||||
// $self->load_config($new_conf);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
// $self->{support_material_overhangs_queried} = 0;
|
||||
// }
|
||||
//
|
||||
// if ($config->fill_density == 100
|
||||
// && !first{ $_ eq $config->fill_pattern } @{$Slic3r::Config::Options->{external_fill_pattern}{values}}) {
|
||||
// my $dialog = Wx::MessageDialog->new($self,
|
||||
// "The ".$config->fill_pattern . " infill pattern is not supposed to work at 100% density.\n"
|
||||
// . "\nShall I switch to rectilinear fill pattern?",
|
||||
// 'Infill', wxICON_WARNING | wxYES | wxNO);
|
||||
//
|
||||
// my $new_conf = Slic3r::Config->new;
|
||||
// if ($dialog->ShowModal() == wxID_YES) {
|
||||
// $new_conf->set("fill_pattern", 'rectilinear');
|
||||
// $new_conf->set("fill_density", 100);
|
||||
// }
|
||||
// else {
|
||||
// $new_conf->set("fill_density", 40);
|
||||
// }
|
||||
// $self->load_config($new_conf);
|
||||
// }
|
||||
//
|
||||
// my $have_perimeters = $config->perimeters > 0;
|
||||
// $self->get_field($_)->toggle($have_perimeters)
|
||||
// for qw(extra_perimeters ensure_vertical_shell_thickness thin_walls overhangs seam_position external_perimeters_first
|
||||
// external_perimeter_extrusion_width
|
||||
// perimeter_speed small_perimeter_speed external_perimeter_speed);
|
||||
//
|
||||
// my $have_infill = $config->fill_density > 0;
|
||||
// # infill_extruder uses the same logic as in Print::extruders()
|
||||
// $self->get_field($_)->toggle($have_infill)
|
||||
// for qw(fill_pattern infill_every_layers infill_only_where_needed solid_infill_every_layers
|
||||
// solid_infill_below_area infill_extruder);
|
||||
//
|
||||
// my $have_solid_infill = ($config->top_solid_layers > 0) || ($config->bottom_solid_layers > 0);
|
||||
// # solid_infill_extruder uses the same logic as in Print::extruders()
|
||||
// $self->get_field($_)->toggle($have_solid_infill)
|
||||
// for qw(external_fill_pattern infill_first solid_infill_extruder solid_infill_extrusion_width
|
||||
// solid_infill_speed);
|
||||
//
|
||||
// $self->get_field($_)->toggle($have_infill || $have_solid_infill)
|
||||
// for qw(fill_angle bridge_angle infill_extrusion_width infill_speed bridge_speed);
|
||||
//
|
||||
// $self->get_field('gap_fill_speed')->toggle($have_perimeters && $have_infill);
|
||||
//
|
||||
// my $have_top_solid_infill = $config->top_solid_layers > 0;
|
||||
// $self->get_field($_)->toggle($have_top_solid_infill)
|
||||
// for qw(top_infill_extrusion_width top_solid_infill_speed);
|
||||
//
|
||||
// my $have_default_acceleration = $config->default_acceleration > 0;
|
||||
// $self->get_field($_)->toggle($have_default_acceleration)
|
||||
// for qw(perimeter_acceleration infill_acceleration bridge_acceleration first_layer_acceleration);
|
||||
//
|
||||
// my $have_skirt = $config->skirts > 0 || $config->min_skirt_length > 0;
|
||||
// $self->get_field($_)->toggle($have_skirt)
|
||||
// for qw(skirt_distance skirt_height);
|
||||
//
|
||||
// my $have_brim = $config->brim_width > 0;
|
||||
// # perimeter_extruder uses the same logic as in Print::extruders()
|
||||
// $self->get_field('perimeter_extruder')->toggle($have_perimeters || $have_brim);
|
||||
//
|
||||
// my $have_raft = $config->raft_layers > 0;
|
||||
// my $have_support_material = $config->support_material || $have_raft;
|
||||
// my $have_support_interface = $config->support_material_interface_layers > 0;
|
||||
// my $have_support_soluble = $have_support_material && $config->support_material_contact_distance == 0;
|
||||
// $self->get_field($_)->toggle($have_support_material)
|
||||
// for qw(support_material_threshold support_material_pattern support_material_with_sheath
|
||||
// support_material_spacing support_material_angle
|
||||
// support_material_interface_layers dont_support_bridges
|
||||
// support_material_extrusion_width support_material_contact_distance support_material_xy_spacing);
|
||||
// $self->get_field($_)->toggle($have_support_material && $have_support_interface)
|
||||
// for qw(support_material_interface_spacing support_material_interface_extruder
|
||||
// support_material_interface_speed support_material_interface_contact_loops);
|
||||
// $self->get_field('support_material_synchronize_layers')->toggle($have_support_soluble);
|
||||
//
|
||||
// $self->get_field('perimeter_extrusion_width')->toggle($have_perimeters || $have_skirt || $have_brim);
|
||||
// $self->get_field('support_material_extruder')->toggle($have_support_material || $have_skirt);
|
||||
// $self->get_field('support_material_speed')->toggle($have_support_material || $have_brim || $have_skirt);
|
||||
//
|
||||
// my $have_sequential_printing = $config->complete_objects;
|
||||
// $self->get_field($_)->toggle($have_sequential_printing)
|
||||
// for qw(extruder_clearance_radius extruder_clearance_height);
|
||||
//
|
||||
// my $have_ooze_prevention = $config->ooze_prevention;
|
||||
// $self->get_field($_)->toggle($have_ooze_prevention)
|
||||
// for qw(standby_temperature_delta);
|
||||
//
|
||||
// my $have_wipe_tower = $config->wipe_tower;
|
||||
// $self->get_field($_)->toggle($have_wipe_tower)
|
||||
// for qw(wipe_tower_x wipe_tower_y wipe_tower_width wipe_tower_per_color_wipe);
|
||||
|
||||
Thaw();
|
||||
}
|
||||
|
||||
void TabFilament::build()
|
||||
{
|
||||
m_config = m_preset_bundle->filaments.get_edited_preset().config;
|
||||
m_config_def = m_config.def();
|
||||
|
@ -447,7 +709,7 @@ void CTabFilament::build()
|
|||
optgroup->append_line(line);
|
||||
}
|
||||
|
||||
wxSizer* CTabFilament::description_line_widget(wxWindow* parent, wxStaticText* StaticText)
|
||||
wxSizer* TabFilament::description_line_widget(wxWindow* parent, wxStaticText* StaticText)
|
||||
{
|
||||
StaticText = new wxStaticText(parent, wxID_ANY, "gfghjkkl;\n fgdsufhsreotklg\n iesrftorsikgyfkh\nauiwrhfidj", wxDefaultPosition, wxDefaultSize);
|
||||
auto font = (new wxSystemSettings)->GetFont(wxSYS_DEFAULT_GUI_FONT);
|
||||
|
@ -460,7 +722,7 @@ wxSizer* CTabFilament::description_line_widget(wxWindow* parent, wxStaticText* S
|
|||
return sizer;
|
||||
}
|
||||
|
||||
void CTabPrinter::build()
|
||||
void TabPrinter::build()
|
||||
{
|
||||
m_config = m_preset_bundle->printers.get_edited_preset().config;
|
||||
m_config_def = m_config.def(); // It will be used in get_option_(const std::string title)
|
||||
|
@ -520,7 +782,7 @@ void CTabPrinter::build()
|
|||
// });
|
||||
|
||||
//if (!$params{ no_controller })
|
||||
if (m_app_config->get("no_controller").empty())
|
||||
if (!m_no_controller/*m_app_config->get("no_controller").empty()*/)
|
||||
{
|
||||
optgroup = page->new_optgroup("USB/Serial connection");
|
||||
line = {"Serial port", ""};
|
||||
|
@ -692,17 +954,17 @@ void CTabPrinter::build()
|
|||
build_extruder_pages();
|
||||
|
||||
// $self->_update_serial_ports if (!$params{ no_controller });
|
||||
if (m_app_config->get("no_controller").empty()){
|
||||
if (!m_no_controller/*m_app_config->get("no_controller").empty()*/){
|
||||
Field *field = optgroup->get_field("serial_port");
|
||||
Choice *choice = static_cast<Choice *>(field);
|
||||
choice->set_values(scan_serial_ports());
|
||||
}
|
||||
}
|
||||
|
||||
void CTabPrinter::build_extruder_pages(){
|
||||
void TabPrinter::build_extruder_pages(){
|
||||
// auto default_config = m_preset_bundle->full_config();
|
||||
|
||||
std::vector<CPageShp> extruder_pages;
|
||||
std::vector<PageShp> extruder_pages;
|
||||
|
||||
for (auto extruder_idx = 0; extruder_idx < m_extruders_count; ++extruder_idx){
|
||||
//# build page
|
||||
|
@ -750,7 +1012,7 @@ void CTabPrinter::build_extruder_pages(){
|
|||
}
|
||||
|
||||
// # rebuild page list
|
||||
CPageShp page_note = m_pages.back();
|
||||
PageShp page_note = m_pages.back();
|
||||
m_pages.pop_back();
|
||||
for (auto page_extruder : extruder_pages)
|
||||
m_pages.push_back(page_extruder);
|
||||
|
@ -759,8 +1021,13 @@ void CTabPrinter::build_extruder_pages(){
|
|||
rebuild_page_tree();
|
||||
}
|
||||
|
||||
void Tab::load_current_preset()
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
//Regerenerate content of the page tree.
|
||||
void CTab::rebuild_page_tree()
|
||||
void Tab::rebuild_page_tree()
|
||||
{
|
||||
Freeze();
|
||||
// get label of the currently selected item
|
||||
|
@ -786,10 +1053,10 @@ void CTab::rebuild_page_tree()
|
|||
Thaw();
|
||||
}
|
||||
|
||||
void CTab::OnTreeSelChange(wxTreeEvent& event)
|
||||
void Tab::OnTreeSelChange(wxTreeEvent& event)
|
||||
{
|
||||
if (m_disable_tree_sel_changed_event) return;
|
||||
CPage* page = nullptr;
|
||||
Page* page = nullptr;
|
||||
auto selection = m_treectrl->GetItemText(m_treectrl->GetSelection());
|
||||
for (auto p : m_pages)
|
||||
if (p->title() == selection)
|
||||
|
@ -806,19 +1073,19 @@ void CTab::OnTreeSelChange(wxTreeEvent& event)
|
|||
Refresh();
|
||||
}
|
||||
|
||||
void CTab::OnKeyDown(wxKeyEvent& event)
|
||||
void Tab::OnKeyDown(wxKeyEvent& event)
|
||||
{
|
||||
event.GetKeyCode() == WXK_TAB ?
|
||||
m_treectrl->Navigate(event.ShiftDown() ? wxNavigationKeyEvent::IsBackward : wxNavigationKeyEvent::IsForward) :
|
||||
event.Skip();
|
||||
};
|
||||
|
||||
void CTab::save_preset(wxCommandEvent &event){};
|
||||
void CTab::delete_preset(wxCommandEvent &event){};
|
||||
void CTab::toggle_show_hide_incompatible(wxCommandEvent &event){};
|
||||
void Tab::save_preset(wxCommandEvent &event){};
|
||||
void Tab::delete_preset(wxCommandEvent &event){};
|
||||
void Tab::toggle_show_hide_incompatible(wxCommandEvent &event){};
|
||||
|
||||
// # Return a callback to create a Tab widget to mark the preferences as compatible / incompatible to the current printer.
|
||||
wxSizer* CTab::compatible_printers_widget(wxWindow* parent, wxCheckBox* checkbox, wxButton* btn)
|
||||
wxSizer* Tab::compatible_printers_widget(wxWindow* parent, wxCheckBox* checkbox, wxButton* btn)
|
||||
{
|
||||
checkbox = new wxCheckBox(parent, wxID_ANY, "All");
|
||||
|
||||
|
@ -890,20 +1157,20 @@ wxSizer* CTab::compatible_printers_widget(wxWindow* parent, wxCheckBox* checkbox
|
|||
}
|
||||
|
||||
// package Slic3r::GUI::Tab::Page;
|
||||
ConfigOptionsGroupShp CPage::new_optgroup(std::string title, int noncommon_label_width /*= -1*/)
|
||||
ConfigOptionsGroupShp Page::new_optgroup(std::string title, int noncommon_label_width /*= -1*/)
|
||||
{
|
||||
//! config_ have to be "right"
|
||||
ConfigOptionsGroupShp optgroup = std::make_shared<ConfigOptionsGroup>(this, title, m_config);
|
||||
if (noncommon_label_width >= 0)
|
||||
optgroup->label_width = noncommon_label_width;
|
||||
|
||||
// on_change => sub {
|
||||
// my ($opt_key, $value) = @_;
|
||||
// wxTheApp->CallAfter(sub {
|
||||
// $self->GetParent->update_dirty;
|
||||
// $self->GetParent->_on_value_change($opt_key, $value);
|
||||
// });
|
||||
// },
|
||||
optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){
|
||||
//! This function will be called from OptionGroup.
|
||||
wxTheApp->CallAfter([this, opt_key, value]() {
|
||||
static_cast<Tab*>(GetParent())->update_dirty();
|
||||
static_cast<Tab*>(GetParent())->on_value_change(opt_key, value);
|
||||
});
|
||||
},
|
||||
|
||||
vsizer()->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 10);
|
||||
m_optgroups.push_back(optgroup);
|
||||
|
|
|
@ -36,14 +36,14 @@ namespace GUI {
|
|||
// Single Tab page containing a{ vsizer } of{ optgroups }
|
||||
// package Slic3r::GUI::Tab::Page;
|
||||
using ConfigOptionsGroupShp = std::shared_ptr<ConfigOptionsGroup>;
|
||||
class CPage : public wxScrolledWindow
|
||||
class Page : public wxScrolledWindow
|
||||
{
|
||||
wxWindow* m_parent;
|
||||
wxString m_title;
|
||||
size_t m_iconID;
|
||||
wxBoxSizer* m_vsizer;
|
||||
public:
|
||||
CPage(wxWindow* parent, const wxString title, const int iconID) :
|
||||
Page(wxWindow* parent, const wxString title, const int iconID) :
|
||||
m_parent(parent),
|
||||
m_title(title),
|
||||
m_iconID(iconID)
|
||||
|
@ -52,7 +52,7 @@ public:
|
|||
m_vsizer = new wxBoxSizer(wxVERTICAL);
|
||||
SetSizer(m_vsizer);
|
||||
}
|
||||
~CPage(){}
|
||||
~Page(){}
|
||||
|
||||
public:
|
||||
std::vector <ConfigOptionsGroupShp> m_optgroups; // $self->{optgroups} = [];
|
||||
|
@ -69,8 +69,8 @@ public:
|
|||
|
||||
// Slic3r::GUI::Tab;
|
||||
|
||||
using CPageShp = std::shared_ptr<CPage>;
|
||||
class CTab: public wxPanel
|
||||
using PageShp = std::shared_ptr<Page>;
|
||||
class Tab: public wxPanel
|
||||
{
|
||||
wxNotebook* m_parent;
|
||||
protected:
|
||||
|
@ -90,26 +90,35 @@ protected:
|
|||
|
||||
int m_icon_count;
|
||||
std::map<std::string, size_t> m_icon_index; // Map from an icon file name to its index in $self->{icons}.
|
||||
std::vector<CPageShp> m_pages; // $self->{pages} = [];
|
||||
std::vector<PageShp> m_pages; // $self->{pages} = [];
|
||||
bool m_disable_tree_sel_changed_event;
|
||||
|
||||
public:
|
||||
PresetBundle* m_preset_bundle;
|
||||
AppConfig* m_app_config;
|
||||
bool m_no_controller;
|
||||
PresetCollection* m_presets;
|
||||
DynamicPrintConfig m_config; //! tmp_val
|
||||
const ConfigDef* m_config_def; // It will be used in get_option_(const std::string title)
|
||||
t_change m_on_value_change{ nullptr };
|
||||
|
||||
public:
|
||||
CTab() {}
|
||||
CTab(wxNotebook* parent, const char *title) : m_parent(parent), m_title(title) {
|
||||
Tab() {}
|
||||
Tab(wxNotebook* parent, const char *title) : m_parent(parent), m_title(title) {
|
||||
Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL);
|
||||
}
|
||||
~CTab(){}
|
||||
~Tab(){}
|
||||
|
||||
wxWindow* parent() const { return m_parent; }
|
||||
wxString title() const { return m_title; }
|
||||
|
||||
void create_preset_tab(PresetBundle *preset_bundle, AppConfig *app_config);
|
||||
void create_preset_tab(PresetBundle *preset_bundle);
|
||||
void on_value_change(std::string opt_key, boost::any value){
|
||||
if (m_on_value_change != nullptr)
|
||||
m_on_value_change(opt_key, value);
|
||||
update();
|
||||
};
|
||||
void on_presets_changed(){};
|
||||
void load_current_preset();
|
||||
void rebuild_page_tree();
|
||||
void select_preset(wxString preset_name){};
|
||||
|
||||
|
@ -124,37 +133,39 @@ public:
|
|||
void delete_preset(wxCommandEvent &event);
|
||||
void toggle_show_hide_incompatible(wxCommandEvent &event);
|
||||
|
||||
CPageShp add_options_page(wxString title, std::string icon, bool is_extruder_pages = false);
|
||||
PageShp add_options_page(wxString title, std::string icon, bool is_extruder_pages = false);
|
||||
|
||||
virtual void build() = 0;
|
||||
virtual void update() = 0;
|
||||
void update_dirty();
|
||||
void load_config(DynamicPrintConfig config);
|
||||
|
||||
Option get_option(const std::string title, int idx = -1){
|
||||
Option get_option(const std::string title, int idx = -1){
|
||||
return Option(*m_config_def->get(title), idx == -1 ? title : title + std::to_string(idx));
|
||||
}
|
||||
};
|
||||
|
||||
//Slic3r::GUI::Tab::Print;
|
||||
class CTabPrint : public CTab
|
||||
class TabPrint : public Tab
|
||||
{
|
||||
public:
|
||||
CTabPrint() {}
|
||||
CTabPrint(wxNotebook* parent, const char *title) : CTab(parent, title) {}
|
||||
~CTabPrint(){}
|
||||
TabPrint() {}
|
||||
TabPrint(wxNotebook* parent, const char *title) : Tab(parent, title) {}
|
||||
~TabPrint(){}
|
||||
|
||||
void build() override;
|
||||
void update() override{};
|
||||
void update() override;
|
||||
};
|
||||
|
||||
//Slic3r::GUI::Tab::Filament;
|
||||
class CTabFilament : public CTab
|
||||
class TabFilament : public Tab
|
||||
{
|
||||
wxStaticText* m_cooling_description_line;
|
||||
wxStaticText* m_volumetric_speed_description_line;
|
||||
public:
|
||||
CTabFilament() {}
|
||||
CTabFilament(wxNotebook* parent, const char *title) : CTab(parent, title) {}
|
||||
~CTabFilament(){}
|
||||
TabFilament() {}
|
||||
TabFilament(wxNotebook* parent, const char *title) : Tab(parent, title) {}
|
||||
~TabFilament(){}
|
||||
|
||||
wxSizer* description_line_widget(wxWindow* parent, wxStaticText* StaticText);
|
||||
|
||||
|
@ -163,7 +174,7 @@ public:
|
|||
};
|
||||
|
||||
//Slic3r::GUI::Tab::Printer;
|
||||
class CTabPrinter : public CTab
|
||||
class TabPrinter : public Tab
|
||||
{
|
||||
public:
|
||||
wxButton* serial_test_btn;
|
||||
|
@ -172,9 +183,9 @@ public:
|
|||
size_t m_extruders_count;
|
||||
|
||||
public:
|
||||
CTabPrinter() {}
|
||||
CTabPrinter(wxNotebook* parent, const char *title) : CTab(parent, title) {}
|
||||
~CTabPrinter(){}
|
||||
TabPrinter() {}
|
||||
TabPrinter(wxNotebook* parent, const char *title) : Tab(parent, title) {}
|
||||
~TabPrinter(){}
|
||||
|
||||
void build() override;
|
||||
void update() override{};
|
||||
|
|
Loading…
Add table
Reference in a new issue