Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/slic3r/GUI/OptionsGroup.cpp')
-rw-r--r--src/slic3r/GUI/OptionsGroup.cpp640
1 files changed, 436 insertions, 204 deletions
diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp
index 207d42b5b..10774abe3 100644
--- a/src/slic3r/GUI/OptionsGroup.cpp
+++ b/src/slic3r/GUI/OptionsGroup.cpp
@@ -1,40 +1,46 @@
#include "OptionsGroup.hpp"
#include "ConfigExceptions.hpp"
+#include "Plater.hpp"
+#include "GUI_App.hpp"
+#include "OG_CustomCtrl.hpp"
#include <utility>
#include <wx/numformatter.h>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
+#include "libslic3r/Exception.hpp"
#include "libslic3r/Utils.hpp"
#include "I18N.hpp"
namespace Slic3r { namespace GUI {
-const t_field& OptionsGroup::build_field(const Option& opt, wxStaticText* label/* = nullptr*/) {
- return build_field(opt.opt_id, opt.opt, label);
+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, wxStaticText* label/* = nullptr*/) {
+const t_field& OptionsGroup::build_field(const t_config_option_key& id) {
const ConfigOptionDef& opt = m_options.at(id).opt;
- return build_field(id, opt, label);
+ return build_field(id, opt);
}
-const t_field& OptionsGroup::build_field(const t_config_option_key& id, const ConfigOptionDef& opt, wxStaticText* label/* = nullptr*/) {
+const t_field& OptionsGroup::build_field(const t_config_option_key& id, const ConfigOptionDef& opt) {
// Check the gui_type field first, fall through
// is the normal type.
- if (opt.gui_type.compare("select") == 0) {
- } else if (opt.gui_type.compare("select_open") == 0) {
+ if (opt.gui_type == "select") {
+ } else if (opt.gui_type == "select_open") {
m_fields.emplace(id, std::move(Choice::Create<Choice>(this->ctrl_parent(), opt, id)));
- } else if (opt.gui_type.compare("color") == 0) {
+ } else if (opt.gui_type == "color") {
m_fields.emplace(id, std::move(ColourPicker::Create<ColourPicker>(this->ctrl_parent(), opt, id)));
- } else if (opt.gui_type.compare("f_enum_open") == 0 ||
- opt.gui_type.compare("i_enum_open") == 0 ||
- opt.gui_type.compare("i_enum_closed") == 0) {
+ } else if (opt.gui_type == "f_enum_open" ||
+ opt.gui_type == "i_enum_open" ||
+ opt.gui_type == "i_enum_closed") {
m_fields.emplace(id, std::move(Choice::Create<Choice>(this->ctrl_parent(), opt, id)));
- } else if (opt.gui_type.compare("slider") == 0) {
+ } else if (opt.gui_type == "slider") {
m_fields.emplace(id, std::move(SliderCtrl::Create<SliderCtrl>(this->ctrl_parent(), opt, id)));
- } else if (opt.gui_type.compare("i_spin") == 0) { // Spinctrl
- } else if (opt.gui_type.compare("legend") == 0) { // StaticText
+ } else if (opt.gui_type == "i_spin") { // Spinctrl
+ } else if (opt.gui_type == "legend") { // StaticText
m_fields.emplace(id, std::move(StaticText::Create<StaticText>(this->ctrl_parent(), opt, id)));
+ } else if (opt.gui_type == "one_string") {
+ m_fields.emplace(id, std::move(TextCtrl::Create<TextCtrl>(this->ctrl_parent(), opt, id)));
} else {
switch (opt.type) {
case coFloatOrPercent:
@@ -62,7 +68,7 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co
break;
case coNone: break;
default:
- throw /*//!ConfigGUITypeError("")*/std::logic_error("This control doesn't exist till now"); break;
+ throw Slic3r::LogicError("This control doesn't exist till now"); break;
}
}
// Grab a reference to fields for convenience
@@ -84,9 +90,7 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co
this->on_set_focus(opt_id);
};
field->m_parent = parent();
-
- //! Label to change background color, when option is modified
- field->m_Label = label;
+
field->m_back_to_initial_value = [this](std::string opt_id) {
if (!m_disabled)
this->back_to_initial_value(opt_id);
@@ -100,29 +104,98 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co
return field;
}
-void OptionsGroup::add_undo_buttuns_to_sizer(wxSizer* sizer, const t_field& field)
+OptionsGroup::OptionsGroup( wxWindow* _parent, const wxString& title,
+ bool is_tab_opt /* = false */,
+ column_t extra_clmn /* = nullptr */) :
+ m_parent(_parent), title(title),
+ m_use_custom_ctrl(is_tab_opt),
+ staticbox(title!=""), extra_column(extra_clmn)
{
- if (!m_show_modified_btns) {
- field->m_Undo_btn->set_as_hidden();
- field->m_Undo_to_sys_btn->set_as_hidden();
- return;
+}
+
+wxWindow* OptionsGroup::ctrl_parent() const
+{
+ return this->custom_ctrl && m_use_custom_ctrl_as_parent ? static_cast<wxWindow*>(this->custom_ctrl) : (this->stb ? static_cast<wxWindow*>(this->stb) : this->parent());
+}
+
+bool OptionsGroup::is_legend_line()
+{
+ if (m_lines.size() == 1) {
+ const std::vector<Option>& option_set = m_lines.front().get_options();
+ return !option_set.empty() && option_set.front().opt.gui_type == "legend";
}
+ return false;
+}
- sizer->Add(field->m_Undo_to_sys_btn, 0, wxALIGN_CENTER_VERTICAL);
- sizer->Add(field->m_Undo_btn, 0, wxALIGN_CENTER_VERTICAL);
+void OptionsGroup::show_field(const t_config_option_key& opt_key, bool show/* = true*/)
+{
+ Field* field = get_field(opt_key);
+ if (!field) return;
+ wxWindow* win = field->getWindow();
+ if (!win) return;
+ wxSizerItem* win_item = m_grid_sizer->GetItem(win, true);
+ if (!win_item) return;
+
+ const size_t cols = (size_t)m_grid_sizer->GetCols();
+ const size_t rows = (size_t)m_grid_sizer->GetEffectiveRowsCount();
+
+ auto show_row = [this, show, cols, win_item](wxSizerItem* item, size_t row_shift) {
+ // check if item contanes required win
+ if (!item->IsWindow() || item != win_item)
+ return false;
+ // show/hide hole line contanes this window
+ for (size_t i = 0; i < cols; ++i)
+ m_grid_sizer->Show(row_shift + i, show);
+ return true;
+ };
+
+ size_t row_shift = 0;
+ for (size_t j = 0; j < rows; ++j) {
+ for (size_t i = 0; i < cols; ++i) {
+ wxSizerItem* item = m_grid_sizer->GetItem(row_shift + i);
+ if (!item)
+ continue;
+ if (item->IsSizer()) {
+ for (wxSizerItem* child_item : item->GetSizer()->GetChildren())
+ if (show_row(child_item, row_shift))
+ return;
+ }
+ else if (show_row(item, row_shift))
+ return;
+ }
+ row_shift += cols;
+ }
}
-void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = nullptr*/) {
- if ( line.full_width && (
- line.sizer != nullptr ||
- line.widget != nullptr ||
- !line.get_extra_widgets().empty() )
+void OptionsGroup::append_line(const Line& line)
+{
+ m_lines.emplace_back(line);
+
+ if (line.full_width && (
+ line.widget != nullptr ||
+ !line.get_extra_widgets().empty())
+ )
+ return;
+
+ auto option_set = line.get_options();
+ for (auto opt : option_set)
+ m_options.emplace(opt.opt_id, opt);
+
+ // add mode value for current line to m_options_mode
+ if (!option_set.empty())
+ m_options_mode.push_back(option_set[0].opt.mode);
+}
+
+void OptionsGroup::activate_line(Line& line)
+{
+ m_use_custom_ctrl_as_parent = false;
+
+ if (line.full_width && (
+ line.widget != nullptr ||
+ !line.get_extra_widgets().empty())
) {
- if (line.sizer != nullptr) {
- sizer->Add(line.sizer, 0, wxEXPAND | wxALL, wxOSX ? 0 : 15);
- return;
- }
if (line.widget != nullptr) {
+ // description lines
sizer->Add(line.widget(this->ctrl_parent()), 0, wxEXPAND | wxALL, wxOSX ? 0 : 15);
return;
}
@@ -140,140 +213,128 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n
}
auto option_set = line.get_options();
- for (auto opt : option_set)
- m_options.emplace(opt.opt_id, opt);
+ bool is_legend_line = option_set.front().opt.gui_type == "legend";
+
+ if (!custom_ctrl && m_use_custom_ctrl) {
+ custom_ctrl = new OG_CustomCtrl(is_legend_line || !staticbox ? this->parent() : static_cast<wxWindow*>(this->stb), this);
+ if (is_legend_line)
+ sizer->Add(custom_ctrl, 0, wxEXPAND | wxLEFT, wxOSX ? 0 : 10);
+ else
+ sizer->Add(custom_ctrl, 0, wxEXPAND | wxALL, wxOSX || !staticbox ? 0 : 5);
+ }
// Set sidetext width for a better alignment of options in line
// "m_show_modified_btns==true" means that options groups are in tabs
- if (option_set.size() > 1 && m_show_modified_btns) {
+ if (option_set.size() > 1 && m_use_custom_ctrl) {
sidetext_width = Field::def_width_thinner();
- /* Temporary commented till UI-review will be completed
- if (m_show_modified_btns) // means that options groups are in tabs
- sublabel_width = Field::def_width();
- */
}
- // add mode value for current line to m_options_mode
- if (!option_set.empty())
- m_options_mode.push_back(option_set[0].opt.mode);
-
// 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.label.empty() &&
option_set.front().opt.sidetext.size() == 0 && option_set.front().side_widget == nullptr &&
line.get_extra_widgets().size() == 0) {
- wxSizer* tmp_sizer;
-#if 0//#ifdef __WXGTK__
- tmp_sizer = new wxBoxSizer(wxVERTICAL);
- m_panel->SetSizer(tmp_sizer);
- m_panel->Layout();
-#else
- tmp_sizer = sizer;
-#endif /* __WXGTK__ */
const auto& option = option_set.front();
const auto& field = build_field(option);
- auto btn_sizer = new wxBoxSizer(wxHORIZONTAL);
- add_undo_buttuns_to_sizer(btn_sizer, field);
- tmp_sizer->Add(btn_sizer, 0, wxEXPAND | wxALL, 0);
if (is_window_field(field))
- tmp_sizer->Add(field->getWindow(), 0, wxEXPAND | wxALL, wxOSX ? 0 : 5);
+ sizer->Add(field->getWindow(), 0, wxEXPAND | wxALL, wxOSX ? 0 : 5);
if (is_sizer_field(field))
- tmp_sizer->Add(field->getSizer(), 0, wxEXPAND | wxALL, wxOSX ? 0 : 5);
+ sizer->Add(field->getSizer(), 0, wxEXPAND | wxALL, wxOSX ? 0 : 5);
return;
}
auto grid_sizer = m_grid_sizer;
-#if 0//#ifdef __WXGTK__
- m_panel->SetSizer(m_grid_sizer);
- m_panel->Layout();
-#endif /* __WXGTK__ */
+
+ if (custom_ctrl)
+ m_use_custom_ctrl_as_parent = true;
// if we have an extra column, build it
- if (extra_column)
- {
- m_extra_column_item_ptrs.push_back(extra_column(this->ctrl_parent(), line));
- grid_sizer->Add(m_extra_column_item_ptrs.back(), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 3);
- }
+ if (extra_column)
+ {
+ m_extra_column_item_ptrs.push_back(extra_column(this->ctrl_parent(), line));
+ grid_sizer->Add(m_extra_column_item_ptrs.back(), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 3);
+ }
- // Build a label if we have it
+ // Build a label if we have it
wxStaticText* label=nullptr;
if (label_width != 0) {
- if (! line.near_label_widget || ! line.label.IsEmpty()) {
- // Only create the label if it is going to be displayed.
- long label_style = staticbox ? 0 : wxALIGN_RIGHT;
+ if (custom_ctrl) {
+ if (line.near_label_widget)
+ line.near_label_widget_win = line.near_label_widget(this->ctrl_parent());
+ }
+ else {
+ if (!line.near_label_widget || !line.label.IsEmpty()) {
+ // Only create the label if it is going to be displayed.
+ long label_style = staticbox ? 0 : wxALIGN_RIGHT;
#ifdef __WXGTK__
- // workaround for correct text align of the StaticBox on Linux
- // flags wxALIGN_RIGHT and wxALIGN_CENTRE don't work when Ellipsize flags are _not_ given.
- // Text is properly aligned only when Ellipsize is checked.
- label_style |= staticbox ? 0 : wxST_ELLIPSIZE_END;
+ // workaround for correct text align of the StaticBox on Linux
+ // flags wxALIGN_RIGHT and wxALIGN_CENTRE don't work when Ellipsize flags are _not_ given.
+ // Text is properly aligned only when Ellipsize is checked.
+ label_style |= staticbox ? 0 : wxST_ELLIPSIZE_END;
#endif /* __WXGTK__ */
- label = new wxStaticText(this->ctrl_parent(), wxID_ANY, line.label + (line.label.IsEmpty() ? "" : ": "),
- wxDefaultPosition, wxSize(label_width*wxGetApp().em_unit(), -1), label_style);
- label->SetBackgroundStyle(wxBG_STYLE_PAINT);
- label->SetFont(wxGetApp().normal_font());
- label->Wrap(label_width*wxGetApp().em_unit()); // avoid a Linux/GTK bug
- }
- if (!line.near_label_widget)
- grid_sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, line.label.IsEmpty() ? 0 : 5);
- else {
- m_near_label_widget_ptrs.push_back(line.near_label_widget(this->ctrl_parent()));
-
- if (line.label.IsEmpty())
- grid_sizer->Add(m_near_label_widget_ptrs.back(), 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 7);
- else {
+ label = new wxStaticText(this->ctrl_parent(), wxID_ANY, line.label + (line.label.IsEmpty() ? "" : ": "),
+ wxDefaultPosition, wxSize(label_width * wxGetApp().em_unit(), -1), label_style);
+ label->SetBackgroundStyle(wxBG_STYLE_PAINT);
+ label->SetFont(wxGetApp().normal_font());
+ label->Wrap(label_width * wxGetApp().em_unit()); // avoid a Linux/GTK bug
+ }
+ if (!line.near_label_widget)
+ grid_sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, line.label.IsEmpty() ? 0 : 5);
+ else if (!line.label.IsEmpty()) {
// If we're here, we have some widget near the label
// so we need a horizontal sizer to arrange these things
auto sizer = new wxBoxSizer(wxHORIZONTAL);
grid_sizer->Add(sizer, 0, wxEXPAND | (staticbox ? wxALL : wxBOTTOM | wxTOP | wxLEFT), staticbox ? 0 : 1);
- sizer->Add(m_near_label_widget_ptrs.back(), 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 7);
sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, 5);
}
+ if (label != nullptr && line.label_tooltip != "")
+ label->SetToolTip(line.label_tooltip);
}
- if (label != nullptr && line.label_tooltip != "")
- label->SetToolTip(line.label_tooltip);
}
- if (full_Label != nullptr)
- *full_Label = label; // Initiate the pointer to the control of the full label, if we need this one.
- // If there's a widget, build it and add the result to the sizer.
+ // If there's a widget, build it and add the result to the sizer.
if (line.widget != nullptr) {
auto wgt = line.widget(this->ctrl_parent());
- // If widget doesn't have label, don't use border
- grid_sizer->Add(wgt, 0, wxEXPAND | wxBOTTOM | wxTOP, (wxOSX || line.label.IsEmpty()) ? 0 : 5);
+ if (custom_ctrl)
+ line.widget_sizer = wgt;
+ else
+ grid_sizer->Add(wgt, 0, wxEXPAND | wxBOTTOM | wxTOP, (wxOSX || line.label.IsEmpty()) ? 0 : 5);
return;
}
-
+
// 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
auto sizer = new wxBoxSizer(wxHORIZONTAL);
- grid_sizer->Add(sizer, 0, wxEXPAND | (staticbox ? wxALL : wxBOTTOM | wxTOP | wxLEFT), staticbox ? 0 : 1);
+ if (!custom_ctrl)
+ grid_sizer->Add(sizer, 0, wxEXPAND | (staticbox ? wxALL : wxBOTTOM | wxTOP | wxLEFT), staticbox ? 0 : 1);
// If we have a single option with no sidetext just add it directly to the grid sizer
if (option_set.size() == 1 && option_set.front().opt.sidetext.size() == 0 &&
option_set.front().opt.label.empty() &&
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);
-
- add_undo_buttuns_to_sizer(sizer, field);
- if (is_window_field(field))
- sizer->Add(field->getWindow(), option.opt.full_width ? 1 : 0, //(option.opt.full_width ? wxEXPAND : 0) |
- wxBOTTOM | wxTOP | (option.opt.full_width ? wxEXPAND : wxALIGN_CENTER_VERTICAL), (wxOSX || !staticbox) ? 0 : 2);
- if (is_sizer_field(field))
- sizer->Add(field->getSizer(), 1, /*(*/option.opt.full_width ? wxEXPAND : /*0) |*/ wxALIGN_CENTER_VERTICAL, 0);
- return;
+ const auto& field = build_field(option);
+
+ if (!custom_ctrl) {
+ if (is_window_field(field))
+ sizer->Add(field->getWindow(), option.opt.full_width ? 1 : 0,
+ wxBOTTOM | wxTOP | (option.opt.full_width ? wxEXPAND : wxALIGN_CENTER_VERTICAL), (wxOSX || !staticbox) ? 0 : 2);
+ if (is_sizer_field(field))
+ sizer->Add(field->getSizer(), 1, option.opt.full_width ? wxEXPAND : wxALIGN_CENTER_VERTICAL, 0);
+ }
+ return;
}
for (auto opt : option_set) {
ConfigOptionDef option = opt.opt;
wxSizer* sizer_tmp = sizer;
// add label if any
- if (!option.label.empty()) {
+ if (!option.label.empty() && !custom_ctrl) {
//! To correct translation by context have to use wxGETTEXT_IN_CONTEXT macro from wxWidget 3.1.1
wxString str_label = (option.label == L_CONTEXT("Top", "Layers") || option.label == L_CONTEXT("Bottom", "Layers")) ?
- _CTX(option.label, "Layers") :
- _(option.label);
+ _CTX(option.label, "Layers") :
+ _(option.label);
label = new wxStaticText(this->ctrl_parent(), wxID_ANY, str_label + ": ", wxDefaultPosition, //wxDefaultSize);
wxSize(sublabel_width != -1 ? sublabel_width * wxGetApp().em_unit() : -1, -1), wxALIGN_RIGHT);
label->SetBackgroundStyle(wxBG_STYLE_PAINT);
@@ -283,42 +344,41 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n
// add field
const Option& opt_ref = opt;
- auto& field = build_field(opt_ref, label);
- add_undo_buttuns_to_sizer(sizer_tmp, field);
- if (option_set.size() == 1 && option_set.front().opt.full_width)
- {
- const auto v_sizer = new wxBoxSizer(wxVERTICAL);
- sizer_tmp->Add(v_sizer, 1, wxEXPAND);
- is_sizer_field(field) ?
- v_sizer->Add(field->getSizer(), 0, wxEXPAND) :
- v_sizer->Add(field->getWindow(), 0, wxEXPAND);
- break;//return;
- }
+ auto& field = build_field(opt_ref);
+ if (!custom_ctrl) {
+ if (option_set.size() == 1 && option_set.front().opt.full_width)
+ {
+ const auto v_sizer = new wxBoxSizer(wxVERTICAL);
+ sizer_tmp->Add(v_sizer, 1, wxEXPAND);
+ is_sizer_field(field) ?
+ v_sizer->Add(field->getSizer(), 0, wxEXPAND) :
+ v_sizer->Add(field->getWindow(), 0, wxEXPAND);
+ break;
+ }
- is_sizer_field(field) ?
- sizer_tmp->Add(field->getSizer(), 0, wxALIGN_CENTER_VERTICAL, 0) :
- sizer_tmp->Add(field->getWindow(), 0, wxALIGN_CENTER_VERTICAL, 0);
-
- // add sidetext if any
- if (!option.sidetext.empty() || sidetext_width > 0) {
- auto sidetext = new wxStaticText( this->ctrl_parent(), wxID_ANY, _(option.sidetext), wxDefaultPosition,
- wxSize(sidetext_width != -1 ? sidetext_width*wxGetApp().em_unit() : -1, -1), wxALIGN_LEFT);
- sidetext->SetBackgroundStyle(wxBG_STYLE_PAINT);
- sidetext->SetFont(wxGetApp().normal_font());
- sizer_tmp->Add(sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4);
- field->set_side_text_ptr(sidetext);
- }
+ is_sizer_field(field) ?
+ sizer_tmp->Add(field->getSizer(), 0, wxALIGN_CENTER_VERTICAL, 0) :
+ sizer_tmp->Add(field->getWindow(), 0, wxALIGN_CENTER_VERTICAL, 0);
+
+ // add sidetext if any
+ if (!option.sidetext.empty() || sidetext_width > 0) {
+ auto sidetext = new wxStaticText(this->ctrl_parent(), wxID_ANY, _(option.sidetext), wxDefaultPosition,
+ wxSize(sidetext_width != -1 ? sidetext_width * wxGetApp().em_unit() : -1, -1), wxALIGN_LEFT);
+ sidetext->SetBackgroundStyle(wxBG_STYLE_PAINT);
+ sidetext->SetFont(wxGetApp().normal_font());
+ sizer_tmp->Add(sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4);
+ }
- // add side widget if any
- if (opt.side_widget != nullptr) {
- sizer_tmp->Add(opt.side_widget(this->ctrl_parent())/*!.target<wxWindow>()*/, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 1); //! requires verification
- }
+ // add side widget if any
+ if (opt.side_widget != nullptr) {
+ sizer_tmp->Add(opt.side_widget(this->ctrl_parent())/*!.target<wxWindow>()*/, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 1); //! requires verification
+ }
- if (opt.opt_id != option_set.back().opt_id) //! istead of (opt != option_set.back())
- {
- sizer_tmp->AddSpacer(6);
- }
+ if (opt.opt_id != option_set.back().opt_id) //! istead of (opt != option_set.back())
+ sizer_tmp->AddSpacer(6);
+ }
}
+
// add extra sizers if any
for (auto extra_widget : line.get_extra_widgets())
{
@@ -331,15 +391,108 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n
return;
}
- sizer->Add(extra_widget(this->ctrl_parent())/*!.target<wxWindow>()*/, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4); //! requires verification
+ line.extra_widget_sizer = extra_widget(this->ctrl_parent());
+ if (!custom_ctrl)
+ sizer->Add(line.extra_widget_sizer, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4); //! requires verification
+ }
+}
+
+// create all controls for the option group from the m_lines
+bool OptionsGroup::activate(std::function<void()> throw_if_canceled)
+{
+ if (sizer)//(!sizer->IsEmpty())
+ return false;
+
+ try {
+ if (staticbox) {
+ stb = new wxStaticBox(m_parent, wxID_ANY, _(title));
+ if (!wxOSX) stb->SetBackgroundStyle(wxBG_STYLE_PAINT);
+ stb->SetFont(wxOSX ? wxGetApp().normal_font() : wxGetApp().bold_font());
+ }
+ else
+ stb = nullptr;
+ sizer = (staticbox ? new wxStaticBoxSizer(stb, wxVERTICAL) : new wxBoxSizer(wxVERTICAL));
+
+ auto num_columns = 1U;
+ size_t grow_col = 1;
+
+ if (label_width == 0)
+ grow_col = 0;
+ else
+ num_columns++;
+
+ if (extra_column) {
+ num_columns++;
+ grow_col++;
+ }
+
+ m_grid_sizer = new wxFlexGridSizer(0, num_columns, 1, 0);
+ static_cast<wxFlexGridSizer*>(m_grid_sizer)->SetFlexibleDirection(wxBOTH);
+ static_cast<wxFlexGridSizer*>(m_grid_sizer)->AddGrowableCol(grow_col);
+
+ sizer->Add(m_grid_sizer, 0, wxEXPAND | wxALL, wxOSX || !staticbox ? 0 : 5);
+
+ // activate lines
+ for (Line& line: m_lines) {
+ throw_if_canceled();
+ activate_line(line);
+ }
+ } catch (UIBuildCanceled&) {
+ auto p = sizer;
+ this->clear();
+ p->Clear(true);
+ delete p;
+ throw;
+ }
+
+ return true;
+}
+// delete all controls from the option group
+void OptionsGroup::clear(bool destroy_custom_ctrl)
+{
+ if (!sizer)
+ return;
+
+ m_grid_sizer = nullptr;
+ sizer = nullptr;
+
+ for (Line& line : m_lines) {
+ if (line.near_label_widget_win)
+ line.near_label_widget_win = nullptr;
+
+ if (line.widget_sizer) {
+ line.widget_sizer->Clear(true);
+ line.widget_sizer = nullptr;
+ }
+
+ if (line.extra_widget_sizer) {
+ line.extra_widget_sizer->Clear(true);
+ line.extra_widget_sizer = nullptr;
+ }
}
+
+ if (custom_ctrl) {
+ for (auto const &item : m_fields) {
+ wxWindow* win = item.second.get()->getWindow();
+ if (win)
+ win = nullptr;
+ }
+ if (destroy_custom_ctrl)
+ custom_ctrl->Destroy();
+ else
+ custom_ctrl = nullptr;
+ }
+
+ m_extra_column_item_ptrs.clear();
+ m_fields.clear();
}
-Line OptionsGroup::create_single_option_line(const Option& option) const {
+Line OptionsGroup::create_single_option_line(const Option& option, const wxString& path/* = wxEmptyString*/) const {
// Line retval{ _(option.opt.label), _(option.opt.tooltip) };
wxString tooltip = _(option.opt.tooltip);
edit_tooltip(tooltip);
Line retval{ _(option.opt.label), tooltip };
+ retval.label_path = path;
Option tmp(option);
tmp.opt.label = std::string("");
retval.append_option(tmp);
@@ -378,6 +531,9 @@ Option ConfigOptionsGroup::get_option(const std::string& opt_key, int opt_index
std::pair<std::string, int> pair(opt_key, opt_index);
m_opt_map.emplace(opt_id, pair);
+ if (m_use_custom_ctrl) // fill group and category values just for options from Settings Tab
+ wxGetApp().sidebar().get_searcher().add_key(opt_id, title, this->config_category());
+
return Option(*m_config->def()->get(opt_key), opt_id);
}
@@ -392,13 +548,11 @@ void ConfigOptionsGroup::on_change_OG(const t_config_option_key& opt_id, const b
return;
}
- auto itOption = it->second;
- std::string opt_key = itOption.first;
- int opt_index = itOption.second;
+ auto itOption = it->second;
+ const std::string &opt_key = itOption.first;
+ int opt_index = itOption.second;
- auto option = m_options.at(opt_id).opt;
-
- change_opt_value(*m_config, opt_key, value, opt_index == -1 ? 0 : opt_index);
+ this->change_opt_value(opt_key, value, opt_index == -1 ? 0 : opt_index);
}
OptionsGroup::on_change_OG(opt_id, value);
@@ -429,9 +583,10 @@ void ConfigOptionsGroup::back_to_config_value(const DynamicPrintConfig& config,
}
else if (m_opt_map.find(opt_key) == m_opt_map.end() ||
// This option don't have corresponded field
- opt_key == "bed_shape" || opt_key == "compatible_printers" || opt_key == "compatible_prints" ) {
+ opt_key == "bed_shape" || opt_key == "filament_ramming_parameters" ||
+ opt_key == "compatible_printers" || opt_key == "compatible_prints" ) {
value = get_config_value(config, opt_key);
- change_opt_value(*m_config, opt_key, value);
+ this->change_opt_value(opt_key, value);
return;
}
else
@@ -482,15 +637,38 @@ void ConfigOptionsGroup::Show(const bool show)
#endif /* __WXGTK__ */
}
-bool ConfigOptionsGroup::update_visibility(ConfigOptionMode mode) {
+bool ConfigOptionsGroup::is_visible(ConfigOptionMode mode)
+{
if (m_options_mode.empty())
return true;
- int opt_mode_size = m_options_mode.size();
- if (m_grid_sizer->GetEffectiveRowsCount() != opt_mode_size &&
- opt_mode_size == 1)
+ if (m_options_mode.size() == 1)
return m_options_mode[0] <= mode;
- Show(true);
+ size_t hidden_row_cnt = 0;
+ for (auto opt_mode : m_options_mode)
+ if (opt_mode > mode)
+ hidden_row_cnt++;
+
+ return hidden_row_cnt != m_options_mode.size();
+}
+
+bool ConfigOptionsGroup::update_visibility(ConfigOptionMode mode)
+{
+ if (m_options_mode.empty() || !m_grid_sizer)
+ return true;
+
+ if (custom_ctrl) {
+ bool show = custom_ctrl->update_visibility(mode);
+ this->Show(show);
+ return show;
+ }
+
+ int opt_mode_size = m_options_mode.size();
+ if (m_grid_sizer->GetEffectiveRowsCount() != opt_mode_size &&
+ opt_mode_size == 1)
+ return m_options_mode[0] <= mode;
+
+ Show(true);
int coef = 0;
int hidden_row_cnt = 0;
@@ -519,48 +697,53 @@ void ConfigOptionsGroup::msw_rescale()
for (auto extra_col : m_extra_column_item_ptrs)
rescale_extra_column_item(extra_col);
- // update bitmaps for near label widgets (like "Set uniform scale" button on settings panel)
- if (rescale_near_label_widget)
- for (auto near_label_widget : m_near_label_widget_ptrs)
- rescale_near_label_widget(near_label_widget);
-
// update undo buttons : rescale bitmaps
for (const auto& field : m_fields)
- field.second->msw_rescale(sidetext_width>0);
-
- const int em = em_unit(parent());
-
- // rescale width of label column
- if (!m_options_mode.empty() && label_width > 1)
- {
- const int cols = m_grid_sizer->GetCols();
- const int rows = m_grid_sizer->GetEffectiveRowsCount();
- const int label_col = extra_column == nullptr ? 0 : 1;
-
- for (int i = 0; i < rows; i++)
- {
- const wxSizerItem* label_item = m_grid_sizer->GetItem(i*cols+label_col);
- if (label_item->IsWindow())
- {
- auto label = dynamic_cast<wxStaticText*>(label_item->GetWindow());
- if (label != nullptr) {
- label->SetMinSize(wxSize(label_width*em, -1));
+ field.second->msw_rescale();
+
+ auto rescale = [](wxSizer* sizer) {
+ for (wxSizerItem* item : sizer->GetChildren())
+ if (item->IsWindow()) {
+ wxWindow* win = item->GetWindow();
+ // check if window is ScalableButton
+ ScalableButton* sc_btn = dynamic_cast<ScalableButton*>(win);
+ if (sc_btn) {
+ sc_btn->msw_rescale();
+ sc_btn->SetSize(sc_btn->GetBestSize());
+ return;
}
- }
- else if (label_item->IsSizer()) // case when we have near_label_widget
- {
- const wxSizerItem* l_item = label_item->GetSizer()->GetItem(1);
- if (l_item->IsWindow())
- {
- auto label = dynamic_cast<wxStaticText*>(l_item->GetWindow());
- if (label != nullptr) {
- label->SetMinSize(wxSize(label_width*em, -1));
- }
+ // check if window is wxButton
+ wxButton* btn = dynamic_cast<wxButton*>(win);
+ if (btn) {
+ btn->SetSize(btn->GetBestSize());
+ return;
}
}
- }
- m_grid_sizer->Layout();
+ };
+
+ // scale widgets and extra widgets if any exists
+ for (const Line& line : m_lines) {
+ if (line.widget_sizer)
+ rescale(line.widget_sizer);
+ if (line.extra_widget_sizer)
+ rescale(line.extra_widget_sizer);
}
+
+ if (custom_ctrl)
+ custom_ctrl->msw_rescale();
+}
+
+void ConfigOptionsGroup::sys_color_changed()
+{
+ // update undo buttons : rescale bitmaps
+ for (const auto& field : m_fields)
+ field.second->sys_color_changed();
+}
+
+void ConfigOptionsGroup::refresh()
+{
+ if (custom_ctrl)
+ custom_ctrl->Refresh();
}
boost::any ConfigOptionsGroup::config_value(const std::string& opt_key, int opt_index, bool deserialize) {
@@ -570,7 +753,7 @@ boost::any ConfigOptionsGroup::config_value(const std::string& opt_key, int opt_
// 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");
+ throw Slic3r::OutOfRange("Can't deserialize option indexed value");
// return join(';', m_config->get(opt_key)});
return get_config_value(*m_config, opt_key);
}
@@ -650,11 +833,15 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
ret = config.option<ConfigOptionStrings>(opt_key)->values;
break;
}
+ if (opt_key == "filament_ramming_parameters") {
+ ret = config.opt_string(opt_key, static_cast<unsigned int>(idx));
+ break;
+ }
if (config.option<ConfigOptionStrings>(opt_key)->values.empty())
ret = text_value;
- else if (opt->gui_flags.compare("serialized") == 0) {
+ else if (opt->gui_flags == "serialized") {
std::vector<std::string> values = config.option<ConfigOptionStrings>(opt_key)->values;
- if (!values.empty() && values[0].compare("") != 0)
+ if (!values.empty() && !values[0].empty())
for (auto el : values)
text_value += el + ";";
ret = text_value;
@@ -680,29 +867,40 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
opt_key == "fill_pattern" ) {
ret = static_cast<int>(config.option<ConfigOptionEnum<InfillPattern>>(opt_key)->value);
}
- else if (opt_key.compare("gcode_flavor") == 0 ) {
+ else if (opt_key == "ironing_type") {
+ ret = static_cast<int>(config.option<ConfigOptionEnum<IroningType>>(opt_key)->value);
+ }
+ else if (opt_key == "gcode_flavor") {
ret = static_cast<int>(config.option<ConfigOptionEnum<GCodeFlavor>>(opt_key)->value);
}
- else if (opt_key.compare("support_material_pattern") == 0) {
+ else if (opt_key == "machine_limits_usage") {
+ ret = static_cast<int>(config.option<ConfigOptionEnum<MachineLimitsUsage>>(opt_key)->value);
+ }
+ else if (opt_key == "support_material_pattern") {
ret = static_cast<int>(config.option<ConfigOptionEnum<SupportMaterialPattern>>(opt_key)->value);
}
- else if (opt_key.compare("seam_position") == 0) {
+ else if (opt_key == "seam_position") {
ret = static_cast<int>(config.option<ConfigOptionEnum<SeamPosition>>(opt_key)->value);
}
- else if (opt_key.compare("host_type") == 0) {
+ else if (opt_key == "host_type") {
ret = static_cast<int>(config.option<ConfigOptionEnum<PrintHostType>>(opt_key)->value);
}
- else if (opt_key.compare("display_orientation") == 0) {
+ else if (opt_key == "display_orientation") {
ret = static_cast<int>(config.option<ConfigOptionEnum<SLADisplayOrientation>>(opt_key)->value);
}
- else if (opt_key.compare("support_pillar_connection_mode") == 0) {
+ else if (opt_key == "support_pillar_connection_mode") {
ret = static_cast<int>(config.option<ConfigOptionEnum<SLAPillarConnectionMode>>(opt_key)->value);
}
+ else if (opt_key == "printhost_authorization_type") {
+ ret = static_cast<int>(config.option<ConfigOptionEnum<AuthorizationType>>(opt_key)->value);
+ }
}
break;
case coPoints:
- if (opt_key.compare("bed_shape") == 0)
+ if (opt_key == "bed_shape")
ret = config.option<ConfigOptionPoints>(opt_key)->values;
+ if (opt_key == "thumbnails")
+ ret = get_thumbnails_string(config.option<ConfigOptionPoints>(opt_key)->values);
else
ret = config.option<ConfigOptionPoints>(opt_key)->get_at(idx);
break;
@@ -728,6 +926,40 @@ Field* ConfigOptionsGroup::get_fieldc(const t_config_option_key& opt_key, int op
return opt_id.empty() ? nullptr : get_field(opt_id);
}
+std::pair<OG_CustomCtrl*, bool*> ConfigOptionsGroup::get_custom_ctrl_with_blinking_ptr(const t_config_option_key& opt_key, int opt_index/* = -1*/)
+{
+ Field* field = get_fieldc(opt_key, opt_index);
+
+ if (field)
+ return {custom_ctrl, field->get_blink_ptr()};
+
+ for (Line& line : m_lines)
+ for (const Option& opt : line.get_options())
+ if (opt.opt_id == opt_key && line.widget)
+ return { custom_ctrl, line.get_blink_ptr() };
+
+ return { nullptr, nullptr };
+}
+
+// Change an option on m_config, possibly call ModelConfig::touch().
+void ConfigOptionsGroup::change_opt_value(const t_config_option_key& opt_key, const boost::any& value, int opt_index /*= 0*/)
+
+{
+ Slic3r::GUI::change_opt_value(const_cast<DynamicPrintConfig&>(*m_config), opt_key, value, opt_index);
+ if (m_modelconfig)
+ m_modelconfig->touch();
+}
+
+ogStaticText::ogStaticText(wxWindow* parent, const wxString& text) :
+ wxStaticText(parent, wxID_ANY, text, wxDefaultPosition, wxDefaultSize)
+{
+ if (!text.IsEmpty()) {
+ Wrap(60 * wxGetApp().em_unit());
+ GetParent()->Layout();
+ }
+}
+
+
void ogStaticText::SetText(const wxString& value, bool wrap/* = true*/)
{
SetLabel(value);