Merge branch 'vb_optgroup_refact'

This commit is contained in:
Vojtech Bubnik 2020-10-01 20:05:31 +02:00
commit ee58ab4e2d
20 changed files with 913 additions and 503 deletions

View File

@ -229,9 +229,11 @@ void BedShapePanel::build_panel(const ConfigOptionPoints& default_pt, const Conf
auto optgroup = init_shape_options_page(BedShape::get_name(BedShape::Type::Rectangular));
BedShape::append_option_line(optgroup, BedShape::Parameter::RectSize);
BedShape::append_option_line(optgroup, BedShape::Parameter::RectOrigin);
activate_options_page(optgroup);
optgroup = init_shape_options_page(BedShape::get_name(BedShape::Type::Circular));
BedShape::append_option_line(optgroup, BedShape::Parameter::Diameter);
activate_options_page(optgroup);
optgroup = init_shape_options_page(BedShape::get_name(BedShape::Type::Custom));
@ -252,6 +254,7 @@ void BedShapePanel::build_panel(const ConfigOptionPoints& default_pt, const Conf
return sizer;
};
optgroup->append_line(line);
activate_options_page(optgroup);
wxPanel* texture_panel = init_texture_panel();
wxPanel* model_panel = init_model_panel();
@ -294,12 +297,18 @@ ConfigOptionsGroupShp BedShapePanel::init_shape_options_page(const wxString& tit
};
m_optgroups.push_back(optgroup);
panel->SetSizerAndFit(optgroup->sizer);
// panel->SetSizerAndFit(optgroup->sizer);
m_shape_options_book->AddPage(panel, title);
return optgroup;
}
void BedShapePanel::activate_options_page(ConfigOptionsGroupShp options_group)
{
options_group->activate();
options_group->parent()->SetSizerAndFit(options_group->sizer);
}
wxPanel* BedShapePanel::init_texture_panel()
{
wxPanel* panel = new wxPanel(this);
@ -373,6 +382,7 @@ wxPanel* BedShapePanel::init_texture_panel()
return sizer;
};
optgroup->append_line(line);
optgroup->activate();
panel->SetSizerAndFit(optgroup->sizer);
@ -452,6 +462,7 @@ wxPanel* BedShapePanel::init_model_panel()
return sizer;
};
optgroup->append_line(line);
optgroup->activate();
panel->SetSizerAndFit(optgroup->sizer);

View File

@ -75,6 +75,7 @@ public:
private:
ConfigOptionsGroupShp init_shape_options_page(const wxString& title);
void activate_options_page(ConfigOptionsGroupShp options_group);
wxPanel* init_texture_panel();
wxPanel* init_model_panel();
void set_shape(const ConfigOptionPoints& points);

View File

@ -28,9 +28,7 @@ void ConfigManipulation::toggle_field(const std::string& opt_key, const bool tog
if (local_config->option(opt_key) == nullptr)
return;
}
Field* field = get_field(opt_key, opt_index);
if (field==nullptr) return;
field->toggle(toggle);
cb_toggle_field(opt_key, toggle, opt_index);
}
void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, const bool is_global_config)

View File

@ -23,25 +23,25 @@ class ConfigManipulation
// function to loading of changed configuration
std::function<void()> load_config = nullptr;
std::function<Field* (const std::string&, int opt_index)> get_field = nullptr;
std::function<void (const std::string&, bool toggle, int opt_index)> cb_toggle_field = nullptr;
// callback to propagation of changed value, if needed
std::function<void(const std::string&, const boost::any&)> cb_value_change = nullptr;
ModelConfig* local_config = nullptr;
public:
ConfigManipulation(std::function<void()> load_config,
std::function<Field* (const std::string&, int opt_index)> get_field,
std::function<void(const std::string&, bool toggle, int opt_index)> cb_toggle_field,
std::function<void(const std::string&, const boost::any&)> cb_value_change,
ModelConfig* local_config = nullptr) :
load_config(load_config),
get_field(get_field),
cb_toggle_field(cb_toggle_field),
cb_value_change(cb_value_change),
local_config(local_config) {}
ConfigManipulation() {}
~ConfigManipulation() {
load_config = nullptr;
get_field = nullptr;
cb_toggle_field = nullptr;
cb_value_change = nullptr;
}

View File

@ -51,6 +51,20 @@ wxString double_to_string(double const value, const int max_precision /*= 4*/)
return s;
}
Field::~Field()
{
if (m_on_kill_focus)
m_on_kill_focus = nullptr;
if (m_on_set_focus)
m_on_set_focus = nullptr;
if (m_on_change)
m_on_change = nullptr;
if (m_back_to_initial_value)
m_back_to_initial_value = nullptr;
if (m_back_to_sys_value)
m_back_to_sys_value = nullptr;
}
void Field::PostInitialize()
{
auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
@ -318,7 +332,7 @@ void Field::sys_color_changed()
template<class T>
bool is_defined_input_value(wxWindow* win, const ConfigOptionType& type)
{
if (static_cast<T*>(win)->GetValue().empty() && type != coString && type != coStrings)
if (!win || (static_cast<T*>(win)->GetValue().empty() && type != coString && type != coStrings))
return false;
return true;
}
@ -1104,8 +1118,7 @@ void Choice::msw_rescale(bool rescale_sidetext/* = false*/)
Field::msw_rescale();
wxBitmapComboBox* field = dynamic_cast<wxBitmapComboBox*>(window);
const wxString selection = field->GetString(field->GetSelection());
const wxString selection = field->GetValue();// field->GetString(index);
/* To correct scaling (set new controll size) of a wxBitmapCombobox
* we need to refill control with new bitmaps. So, in our case :

View File

@ -145,7 +145,7 @@ public:
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) {};
virtual ~Field() {}
virtual ~Field();
/// If you don't know what you are getting back, check both methods for nullptr.
virtual wxSizer* getSizer() { return nullptr; }

View File

@ -634,6 +634,7 @@ bool GUI_App::OnInit()
bool GUI_App::on_init_inner()
{
TaskTimer timer("on_init");
// Verify resources path
const wxString resources_dir = from_u8(Slic3r::resources_dir());
wxCHECK_MSG(wxDirExists(resources_dir), false,
@ -758,9 +759,11 @@ bool GUI_App::on_init_inner()
#endif // ENABLE_GCODE_VIEWER
scrn->SetText(_L("Creating settings tabs..."));
TaskTimer timer2("Creating settings tabs");
mainframe = new MainFrame();
// hide settings tabs after first Layout
mainframe->select_tab(0);
mainframe->select_tab(size_t(0));
sidebar().obj_list()->init_objects(); // propagate model objects to object list
// update_mode(); // !!! do that later
@ -1012,7 +1015,7 @@ void GUI_App::recreate_GUI(const wxString& msg_name)
MainFrame *old_main_frame = mainframe;
mainframe = new MainFrame();
// hide settings tabs after first Layout
mainframe->select_tab(0);
mainframe->select_tab(size_t(0));
// Propagate model objects to object list.
sidebar().obj_list()->init_objects();
SetTopWindow(mainframe);
@ -1461,7 +1464,7 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
// hide full main_sizer for mainFrame
mainframe->GetSizer()->Show(false);
mainframe->update_layout();
mainframe->select_tab(0);
mainframe->select_tab(size_t(0));
}
break;
}

View File

@ -34,6 +34,7 @@ ObjectLayers::ObjectLayers(wxWindow* parent) :
m_grid_sizer->Add(temp);
}
m_og->activate();
m_og->sizer->Clear(true);
m_og->sizer->Add(m_grid_sizer, 0, wxEXPAND | wxALL, wxOSX ? 0 : 5);

View File

@ -431,6 +431,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
m_main_grid_sizer->Add(m_check_inch, 1, wxEXPAND);
m_og->activate();
m_og->sizer->Clear(true);
m_og->sizer->Add(m_main_grid_sizer, 1, wxEXPAND | wxALL, border);
}

View File

@ -58,6 +58,7 @@ wxSizer* OG_Settings::get_sizer()
ObjectSettings::ObjectSettings(wxWindow* parent) :
OG_Settings(parent, true)
{
m_og->activate();
m_og->set_name(_(L("Additional Settings")));
m_settings_list_sizer = new wxBoxSizer(wxVERTICAL);
@ -148,14 +149,15 @@ bool ObjectSettings::update_settings_list()
if (is_extruders_cat)
option.opt.max = wxGetApp().extruders_edited_cnt();
optgroup->append_single_option_line(option);
}
optgroup->activate();
for (auto& opt : cat.second)
optgroup->get_field(opt)->m_on_change = [optgroup](const std::string& opt_id, const boost::any& value) {
// first of all take a snapshot and then change value in configuration
wxGetApp().plater()->take_snapshot(from_u8((boost::format(_utf8(L("Change Option %s"))) % opt_id).str()));
optgroup->on_change_OG(opt_id, value);
};
}
optgroup->reload_config();
m_settings_list_sizer->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 0);
@ -233,18 +235,19 @@ void ObjectSettings::update_config_values(ModelConfig* config)
}
};
auto get_field = [this](const t_config_option_key & opt_key, int opt_index)
auto toggle_field = [this](const t_config_option_key & opt_key, bool toggle, int opt_index)
{
Field* field = nullptr;
for (auto og : m_og_settings) {
field = og->get_fieldc(opt_key, opt_index);
if (field != nullptr)
return field;
break;
}
return field;
if (field)
field->toggle(toggle);
};
ConfigManipulation config_manipulation(load_config, get_field, nullptr, config);
ConfigManipulation config_manipulation(load_config, toggle_field, nullptr, config);
if (!is_object_settings)
{

View File

@ -18,6 +18,8 @@
#include <wx/debug.h>
#include <wx/settings.h>
#include <chrono>
#include "Event.hpp"
class wxCheckBox;
@ -392,6 +394,32 @@ inline int hex_digit_to_int(const char c)
}
#endif // ENABLE_GCODE_VIEWER
class TaskTimer
{
std::chrono::milliseconds start_timer;
std::string task_name;
public:
TaskTimer(std::string task_name):
task_name(task_name.empty() ? "task" : task_name)
{
start_timer = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch());
}
~TaskTimer()
{
std::chrono::milliseconds stop_timer = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch());
auto process_duration = std::chrono::milliseconds(stop_timer - start_timer).count();
std::string out = (boost::format("\n!!! %1% duration = %2% ms \n\n") % task_name % process_duration).str();
printf(out.c_str());
#ifdef __WXMSW__
std::wstring stemp = std::wstring(out.begin(), out.end());
OutputDebugString(stemp.c_str());
#endif
}
};
}}
#endif

View File

@ -345,8 +345,9 @@ void MainFrame::update_layout()
fromDlg,
toDlg
};
State update_scaling_state = m_layout == ESettingsLayout::Dlg ? State::fromDlg :
layout == ESettingsLayout::Dlg ? State::toDlg : State::noUpdate;
State update_scaling_state = m_layout == ESettingsLayout::Unknown ? State::noUpdate : // don't scale settings dialog from the application start
m_layout == ESettingsLayout::Dlg ? State::fromDlg :
layout == ESettingsLayout::Dlg ? State::toDlg : State::noUpdate;
#endif //__WXMSW__
m_layout = layout;
@ -594,7 +595,7 @@ void MainFrame::init_tabpanel()
m_last_selected_tab = m_tabpanel->GetSelection();
}
else
select_tab(0); // select Plater
select_tab(size_t(0)); // select Plater
});
m_plater = new Plater(this, this);
@ -649,6 +650,24 @@ void MainFrame::add_created_tab(Tab* panel)
m_tabpanel->AddPage(panel, panel->title());
}
bool MainFrame::is_active_and_shown_tab(Tab* tab)
{
if (!this)
return false;
int page_id = m_tabpanel->FindPage(tab);
if (m_tabpanel->GetSelection() != page_id)
return false;
if (m_layout == ESettingsLayout::Dlg)
return m_settings_dialog.IsShown();
if (m_layout == ESettingsLayout::New)
return m_main_sizer->IsShown(m_tabpanel);
return true;
}
bool MainFrame::can_start_new_project() const
{
return (m_plater != nullptr) && !m_plater->model().objects.empty();
@ -1166,7 +1185,7 @@ void MainFrame::init_menubar()
{
if (m_plater) {
append_menu_item(windowMenu, wxID_HIGHEST + 1, _L("&Plater Tab") + "\tCtrl+1", _L("Show the plater"),
[this](wxCommandEvent&) { select_tab(0); }, "plater", nullptr,
[this](wxCommandEvent&) { select_tab(size_t(0)); }, "plater", nullptr,
[this]() {return true; }, this);
windowMenu->AppendSeparator();
}
@ -1722,9 +1741,35 @@ void MainFrame::load_config(const DynamicPrintConfig& config)
#endif
}
void MainFrame::select_tab(Tab* tab)
{
if (!tab)
return;
int page_idx = m_tabpanel->FindPage(tab);
if (page_idx != wxNOT_FOUND && m_layout == ESettingsLayout::Dlg)
page_idx++;
select_tab(size_t(page_idx));
}
void MainFrame::select_tab(size_t tab/* = size_t(-1)*/)
{
bool tabpanel_was_hidden = false;
// Controls on page are created on active page of active tab now.
// We should select/activate tab before its showing to avoid an UI-flickering
auto select = [this, tab](bool was_hidden) {
// when tab == -1, it means we should show the last selected tab
size_t new_selection = tab == (size_t)(-1) ? m_last_selected_tab : (m_layout == ESettingsLayout::Dlg && tab != 0) ? tab - 1 : tab;
if (m_tabpanel->GetSelection() != new_selection)
m_tabpanel->SetSelection(new_selection);
else if (was_hidden) {
Tab* cur_tab = dynamic_cast<Tab*>(m_tabpanel->GetPage(new_selection));
if (cur_tab)
cur_tab->OnActivate();
}
};
if (m_layout == ESettingsLayout::Dlg) {
if (tab==0) {
if (m_settings_dialog.IsShown())
@ -1738,14 +1783,20 @@ void MainFrame::select_tab(size_t tab/* = size_t(-1)*/)
#ifdef __WXOSX__ // Don't call SetFont under OSX to avoid name cutting in ObjectList
if (m_settings_dialog.IsShown())
m_settings_dialog.Hide();
else
tabpanel_was_hidden = true;
select(tabpanel_was_hidden);
m_tabpanel->Show();
m_settings_dialog.Show();
#else
if (m_settings_dialog.IsShown())
if (m_settings_dialog.IsShown()) {
select(false);
m_settings_dialog.SetFocus();
}
else {
tabpanel_was_hidden = true;
select(tabpanel_was_hidden);
m_tabpanel->Show();
m_settings_dialog.Show();
}
@ -1754,6 +1805,7 @@ void MainFrame::select_tab(size_t tab/* = size_t(-1)*/)
else if (m_layout == ESettingsLayout::New) {
m_main_sizer->Show(m_plater, tab == 0);
tabpanel_was_hidden = !m_main_sizer->IsShown(m_tabpanel);
select(tabpanel_was_hidden);
m_main_sizer->Show(m_tabpanel, tab != 0);
// plater should be focused for correct navigation inside search window
@ -1761,17 +1813,23 @@ void MainFrame::select_tab(size_t tab/* = size_t(-1)*/)
m_plater->SetFocus();
Layout();
}
else
select(false);
// When we run application in ESettingsLayout::New or ESettingsLayout::Dlg mode, tabpanel is hidden from the very beginning
// and as a result Tab::update_changed_tree_ui() function couldn't update m_is_nonsys_values values,
// which are used for update TreeCtrl and "revert_buttons".
// So, force the call of this function for Tabs, if tab panel was hidden
if (tabpanel_was_hidden)
for (auto tab : wxGetApp().tabs_list)
tab->update_changed_tree_ui();
for (auto cur_tab : wxGetApp().tabs_list)
cur_tab->update_changed_tree_ui();
// when tab == -1, it means we should show the last selected tab
m_tabpanel->SetSelection(tab == (size_t)(-1) ? m_last_selected_tab : (m_layout == ESettingsLayout::Dlg && tab != 0) ? tab - 1 : tab);
//// when tab == -1, it means we should show the last selected tab
//size_t new_selection = tab == (size_t)(-1) ? m_last_selected_tab : (m_layout == ESettingsLayout::Dlg && tab != 0) ? tab - 1 : tab;
//if (m_tabpanel->GetSelection() != new_selection)
// m_tabpanel->SetSelection(new_selection);
//if (tabpanel_was_hidden)
// static_cast<Tab*>(m_tabpanel->GetPage(new_selection))->OnActivate();
}
// Set a camera direction, zoom to all objects.
@ -1918,7 +1976,7 @@ SettingsDialog::SettingsDialog(MainFrame* mainframe)
auto key_up_handker = [this](wxKeyEvent& evt) {
if ((evt.GetModifiers() & wxMOD_CONTROL) != 0) {
switch (evt.GetKeyCode()) {
case '1': { m_main_frame->select_tab(0); break; }
case '1': { m_main_frame->select_tab(size_t(0)); break; }
case '2': { m_main_frame->select_tab(1); break; }
case '3': { m_main_frame->select_tab(2); break; }
case '4': { m_main_frame->select_tab(3); break; }

View File

@ -159,6 +159,7 @@ public:
void init_tabpanel();
void create_preset_tabs();
void add_created_tab(Tab* panel);
bool is_active_and_shown_tab(Tab* tab);
#if ENABLE_GCODE_VIEWER
void init_menubar_as_editor();
void init_menubar_as_gcodeviewer();
@ -184,6 +185,7 @@ public:
void load_config(const DynamicPrintConfig& config);
// Select tab in m_tabpanel
// When tab == -1, will be selected last selected tab
void select_tab(Tab* tab);
void select_tab(size_t tab = size_t(-1));
void select_view(const std::string& direction);
// Propagate changed configuration from the Tab to the Plater and save changes to the AppConfig

View File

@ -110,30 +110,16 @@ OptionsGroup::OptionsGroup( wxWindow* _parent, const wxString& title,
m_show_modified_btns(is_tab_opt),
staticbox(title!=""), extra_column(extra_clmn)
{
if (staticbox) {
/*if (staticbox) {
stb = new wxStaticBox(_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;
if (label_width != 0) num_columns++;
if (extra_column != nullptr) num_columns++;
m_grid_sizer = new wxFlexGridSizer(0, num_columns, 1,0);
static_cast<wxFlexGridSizer*>(m_grid_sizer)->SetFlexibleDirection(wxBOTH/*wxHORIZONTAL*/);
static_cast<wxFlexGridSizer*>(m_grid_sizer)->AddGrowableCol(label_width == 0 ? 0 : !extra_column ? 1 : 2 );
#if 0//#ifdef __WXGTK__
m_panel = new wxPanel( _parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
sizer->Fit(m_panel);
sizer->Add(m_panel, 0, wxEXPAND | wxALL, wxOSX||!staticbox ? 0: 5);
#else
sizer->Add(m_grid_sizer, 0, wxEXPAND | wxALL, wxOSX||!staticbox ? 0: 5);
#endif /* __WXGTK__ */
sizer = (staticbox ? new wxStaticBoxSizer(stb, wxVERTICAL) : new wxBoxSizer(wxVERTICAL));*/
}
void OptionsGroup::add_undo_buttuns_to_sizer(wxSizer* sizer, const t_field& field)
void OptionsGroup::add_undo_buttons_to_sizer(wxSizer* sizer, const t_field& field)
{
if (!m_show_modified_btns) {
field->m_Undo_btn->set_as_hidden();
@ -147,16 +133,31 @@ void OptionsGroup::add_undo_buttuns_to_sizer(wxSizer* sizer, const t_field& fiel
sizer->Add(field->m_Undo_btn, 0, wxALIGN_CENTER_VERTICAL);
}
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)
{
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) {
sizer->Add(line.widget(this->ctrl_parent()), 0, wxEXPAND | wxALL, wxOSX ? 0 : 15);
return;
@ -175,23 +176,13 @@ 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);
// 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) {
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() &&
@ -210,7 +201,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n
const auto& field = build_field(option);
auto btn_sizer = new wxBoxSizer(wxHORIZONTAL);
add_undo_buttuns_to_sizer(btn_sizer, field);
add_undo_buttons_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);
@ -221,16 +212,16 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n
auto grid_sizer = m_grid_sizer;
#if 0//#ifdef __WXGTK__
m_panel->SetSizer(m_grid_sizer);
m_panel->Layout();
m_panel->SetSizer(m_grid_sizer);
m_panel->Layout();
#endif /* __WXGTK__ */
// 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
wxStaticText* label=nullptr;
@ -244,8 +235,8 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n
// 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 = 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
@ -270,16 +261,16 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n
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 (line.full_Label != nullptr)
*line.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 (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);
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);
@ -291,11 +282,11 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n
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))
add_undo_buttons_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;
}
@ -307,8 +298,8 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n
if (!option.label.empty()) {
//! 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);
@ -319,7 +310,7 @@ 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);
add_undo_buttons_to_sizer(sizer_tmp, field);
if (option_set.size() == 1 && option_set.front().opt.full_width)
{
const auto v_sizer = new wxBoxSizer(wxVERTICAL);
@ -330,10 +321,10 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n
break;//return;
}
is_sizer_field(field) ?
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,
@ -370,6 +361,81 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n
}
}
// 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()
{
if (!sizer)//(sizer->IsEmpty())
return;
// m_grid_sizer->Clear(true);
m_grid_sizer = nullptr;
// sizer->Clear(true);
//if (stb) {
// stb->SetContainingSizer(NULL);
// stb->Destroy();
//}
sizer = nullptr;
for (Line& line : m_lines)
if(line.full_Label)
*line.full_Label = nullptr;
m_extra_column_item_ptrs.clear();
m_near_label_widget_ptrs.clear();
m_fields.clear();
}
Line OptionsGroup::create_single_option_line(const Option& option) const {
// Line retval{ _(option.opt.label), _(option.opt.tooltip) };
wxString tooltip = _(option.opt.tooltip);
@ -519,15 +585,31 @@ 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);
int 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;
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;
@ -568,7 +650,7 @@ void ConfigOptionsGroup::msw_rescale()
const int em = em_unit(parent());
// rescale width of label column
if (!m_options_mode.empty() && label_width > 1)
if (m_grid_sizer && !m_options_mode.empty() && label_width > 1)
{
const int cols = m_grid_sizer->GetCols();
const int rows = m_grid_sizer->GetEffectiveRowsCount();

View File

@ -24,6 +24,9 @@
namespace Slic3r { namespace GUI {
// Thrown if the building of a parameter page is canceled.
class UIBuildCanceled : public std::exception {};
/// Widget type describes a function object that returns a wxWindow (our widget) and accepts a wxWidget (parent window).
using widget_t = std::function<wxSizer*(wxWindow*)>;//!std::function<wxWindow*(wxWindow*)>;
@ -48,7 +51,7 @@ public:
wxString label {wxString("")};
wxString label_tooltip {wxString("")};
size_t full_width {0};
wxSizer* sizer {nullptr};
wxStaticText** full_Label {nullptr};
widget_t widget {nullptr};
std::function<wxWindow*(wxWindow*)> near_label_widget{ nullptr };
@ -119,7 +122,15 @@ public:
return this->stb ? (wxWindow*)this->stb : this->parent();
}
void append_line(const Line& line, wxStaticText** full_Label = nullptr);
void append_line(const Line& line);
// create controls for the option group
void activate_line(Line& line);
// create all controls for the option group from the m_lines
bool activate(std::function<void()> throw_if_canceled = [](){});
// delete all controls from the option group
void clear();
Line create_single_option_line(const Option& option) const;
void append_single_option_line(const Option& option) { append_line(create_single_option_line(option)); }
@ -170,11 +181,7 @@ public:
void clear_fields_except_of(const std::vector<std::string> left_fields);
void hide_labels() {
label_width = 0;
m_grid_sizer->SetCols(m_grid_sizer->GetEffectiveColsCount()-1);
static_cast<wxFlexGridSizer*>(m_grid_sizer)->AddGrowableCol(!extra_column ? 0 : 1);
}
void hide_labels() { label_width = 0; }
OptionsGroup( wxWindow* _parent, const wxString& title, bool is_tab_opt = false,
column_t extra_clmn = nullptr);
@ -188,6 +195,8 @@ protected:
std::vector<wxWindow*> m_extra_column_item_ptrs;
std::vector<wxWindow*> m_near_label_widget_ptrs;
std::vector<Line> m_lines;
/// 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.
@ -210,7 +219,7 @@ protected:
const t_field& build_field(const t_config_option_key& id, const ConfigOptionDef& opt, wxStaticText* label = nullptr);
const t_field& build_field(const t_config_option_key& id, wxStaticText* label = nullptr);
const t_field& build_field(const Option& opt, wxStaticText* label = nullptr);
void add_undo_buttuns_to_sizer(wxSizer* sizer, const t_field& field);
void add_undo_buttons_to_sizer(wxSizer* sizer, const t_field& field);
virtual void on_kill_focus(const std::string& opt_key) {};
virtual void on_set_focus(const std::string& opt_key);
@ -259,6 +268,7 @@ public:
// return value shows visibility : false => all options are hidden
void Hide();
void Show(const bool show);
bool is_visible(ConfigOptionMode mode);
bool update_visibility(ConfigOptionMode mode);
void msw_rescale();
void sys_color_changed();

View File

@ -374,6 +374,7 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr
m_optgroup->append_single_option_line(option);
}
m_optgroup->activate();
update();
}
@ -434,6 +435,7 @@ void PhysicalPrinterDialog::on_dpi_changed(const wxRect& suggested_rect)
{
const int& em = em_unit();
m_add_preset_btn->msw_rescale();
m_printhost_browse_btn->msw_rescale();
m_printhost_test_btn->msw_rescale();
if (m_printhost_cafile_browse_btn)

View File

@ -305,11 +305,12 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent) :
if (!tab_print) return;
if (opt_key == "fill_density") {
value = m_og->get_config_value(*config, opt_key);
tab_print->set_value(opt_key, value);
tab_print->update_dirty();
tab_print->reload_config();
tab_print->update();
}
else{
else
{
DynamicPrintConfig new_conf = *config;
if (opt_key == "brim") {
double new_val;
@ -350,8 +351,6 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent) :
}
tab_print->load_config(new_conf);
}
tab_print->update_dirty();
};
@ -439,9 +438,9 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent) :
return sizer;
};
line.append_widget(wiping_dialog_btn);
m_og->append_line(line);
m_og->activate();
// Frequently changed parameters for SLA_technology
m_og_sla = std::make_shared<ConfigOptionsGroup>(parent, "");
@ -513,6 +512,8 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent) :
m_og_sla->append_line(line);
m_og_sla->activate();
m_sizer = new wxBoxSizer(wxVERTICAL);
m_sizer->Add(m_og->sizer, 0, wxEXPAND);
m_sizer->Add(m_og_sla->sizer, 0, wxEXPAND);
@ -980,7 +981,7 @@ void Sidebar::jump_to_option(size_t selected)
wxGetApp().get_tab(opt.type)->activate_option(boost::nowide::narrow(opt.opt_key), boost::nowide::narrow(opt.category));
// Switch to the Settings NotePad
wxGetApp().mainframe->select_tab();
// wxGetApp().mainframe->select_tab();
}
ObjectManipulation* Sidebar::obj_manipul()

View File

@ -140,6 +140,8 @@ void PreferencesDialog::build()
option = Option(def, "show_splash_screen");
m_optgroup_general->append_single_option_line(option);
m_optgroup_general->activate();
m_optgroup_camera = std::make_shared<ConfigOptionsGroup>(this, _(L("Camera")));
m_optgroup_camera->label_width = 40;
m_optgroup_camera->m_on_change = [this](t_config_option_key opt_key, boost::any value) {
@ -160,6 +162,8 @@ void PreferencesDialog::build()
option = Option(def, "use_free_camera");
m_optgroup_camera->append_single_option_line(option);
m_optgroup_camera->activate();
m_optgroup_gui = std::make_shared<ConfigOptionsGroup>(this, _(L("GUI")));
m_optgroup_gui->label_width = 40;
m_optgroup_gui->m_on_change = [this](t_config_option_key opt_key, boost::any value) {
@ -184,6 +188,8 @@ void PreferencesDialog::build()
option = Option(def, "use_custom_toolbar_size");
m_optgroup_gui->append_single_option_line(option);
m_optgroup_gui->activate();
create_icon_size_slider();
m_icon_size_sizer->ShowItems(app_config->get("use_custom_toolbar_size") == "1");
@ -202,6 +208,8 @@ void PreferencesDialog::build()
def.set_default_value(new ConfigOptionBool{ app_config->get("use_environment_map") == "1" });
option = Option(def, "use_environment_map");
m_optgroup_render->append_single_option_line(option);
m_optgroup_render->activate();
#endif // ENABLE_ENVIRONMENT_MAP
auto sizer = new wxBoxSizer(wxVERTICAL);

File diff suppressed because it is too large Load Diff

View File

@ -44,7 +44,7 @@ class TabPresetComboBox;
// Single Tab page containing a{ vsizer } of{ optgroups }
// package Slic3r::GUI::Tab::Page;
using ConfigOptionsGroupShp = std::shared_ptr<ConfigOptionsGroup>;
class Page : public wxScrolledWindow
class Page// : public wxScrolledWindow
{
wxWindow* m_parent;
wxString m_title;
@ -60,7 +60,6 @@ public:
bool m_is_nonsys_values{ true };
// Delayed layout after resizing the main window.
bool layout_valid = false;
const std::vector<ScalableBitmap>& m_mode_bitmap_cache;
public:
@ -73,7 +72,9 @@ public:
size_t iconID() const { return m_iconID; }
void set_config(DynamicPrintConfig* config_in) { m_config = config_in; }
void reload_config();
void update_visibility(ConfigOptionMode mode);
void update_visibility(ConfigOptionMode mode, bool update_contolls_visibility);
void activate(ConfigOptionMode mode, std::function<void()> throw_if_canceled);
void clear();
void msw_rescale();
void sys_color_changed();
Field* get_field(const t_config_option_key& opt_key, int opt_index = -1) const;
@ -126,7 +127,10 @@ protected:
wxTreeCtrl* m_treectrl;
wxImageList* m_icons;
ModeSizer* m_mode_sizer;
wxScrolledWindow* m_page_view {nullptr};
wxBoxSizer* m_page_sizer {nullptr};
ModeSizer* m_mode_sizer;
struct PresetDependencies {
Preset::Type type = Preset::TYPE_INVALID;
@ -195,7 +199,8 @@ protected:
int m_icon_count;
std::map<std::string, size_t> m_icon_index; // Map from an icon file name to its index
std::vector<PageShp> m_pages;
bool m_disable_tree_sel_changed_event;
Page* m_active_page {nullptr};
bool m_disable_tree_sel_changed_event {false};
bool m_show_incompatible_presets;
std::vector<Preset::Type> m_dependent_tabs;
@ -221,9 +226,9 @@ protected:
void set_timer_owner(wxEvtHandler* owner, int timerid = wxID_ANY);
void init(BlinkingBitmap* bmp);
void blink();
void invalidate();
private:
void invalidate();
BlinkingBitmap* bbmp {nullptr};
int blink_counter {0};
@ -233,12 +238,16 @@ protected:
DynamicPrintConfig m_cache_config;
bool m_page_switch_running = false;
bool m_page_switch_planned = false;
public:
PresetBundle* m_preset_bundle;
bool m_show_btn_incompatible_presets = false;
PresetCollection* m_presets;
DynamicPrintConfig* m_config;
ogStaticText* m_parent_preset_description_line;
ogStaticText* m_parent_preset_description_line = nullptr;
ScalableButton* m_detach_preset_btn = nullptr;
// map of option name -> wxStaticText (colored label, associated with option)
@ -277,7 +286,6 @@ public:
void update_ui_items_related_on_parent_preset(const Preset* selected_preset_parent);
void load_current_preset();
void rebuild_page_tree();
void update_page_tree_visibility();
void update_btns_enabling();
void update_preset_choice();
// Select a new preset, possibly delete the current one.
@ -285,6 +293,10 @@ public:
bool may_discard_current_dirty_preset(PresetCollection* presets = nullptr, const std::string& new_printer_name = "");
bool may_switch_to_SLA_preset();
virtual void clear_pages();
virtual void update_description_lines();
virtual void activate_selected_page(std::function<void()> throw_if_canceled);
void OnTreeSelChange(wxTreeEvent& event);
void OnKeyDown(wxKeyEvent& event);
@ -294,6 +306,7 @@ public:
void update_show_hide_incompatible_button();
void update_ui_from_settings();
void update_labels_colour();
void decorate();
void update_changed_ui();
void get_sys_and_mod_flags(const std::string& opt_key, bool& sys_page, bool& modified_page);
void update_changed_tree_ui();
@ -307,6 +320,7 @@ public:
virtual void on_preset_loaded() {}
virtual void build() = 0;
virtual void update() = 0;
virtual void toggle_options() = 0;
virtual void init_options_list();
void load_initial_data();
void update_dirty();
@ -319,7 +333,8 @@ public:
virtual void sys_color_changed();
Field* get_field(const t_config_option_key& opt_key, int opt_index = -1) const;
Field* get_field(const t_config_option_key &opt_key, Page** selected_page, int opt_index = -1);
bool set_value(const t_config_option_key& opt_key, const boost::any& value);
void toggle_option(const std::string& opt_key, bool toggle, int opt_index = -1);
// bool set_value(const t_config_option_key& opt_key, const boost::any& value);
wxSizer* description_line_widget(wxWindow* parent, ogStaticText** StaticText);
bool current_preset_is_dirty();
@ -340,6 +355,8 @@ protected:
void compatible_widget_reload(PresetDependencies &deps);
void load_key_value(const std::string& opt_key, const boost::any& value, bool saved_value = false);
// return true if cancelled
bool tree_sel_change_delayed();
void on_presets_changed();
void build_preset_description_line(ConfigOptionsGroup* optgroup);
void update_preset_description_line();
@ -365,15 +382,18 @@ public:
void build() override;
void reload_config() override;
void update_description_lines() override;
void toggle_options() override;
void update() override;
void OnActivate() override;
// void OnActivate() override;
void clear_pages() override;
bool supports_printer_technology(const PrinterTechnology tech) override { return tech == ptFFF; }
};
class TabFilament : public Tab
{
ogStaticText* m_volumetric_speed_description_line;
ogStaticText* m_cooling_description_line;
ogStaticText* m_volumetric_speed_description_line {nullptr};
ogStaticText* m_cooling_description_line {nullptr};
void add_filament_overrides_page();
void update_filament_overrides_page();
@ -388,8 +408,11 @@ public:
void build() override;
void reload_config() override;
void update_description_lines() override;
void toggle_options() override;
void update() override;
void OnActivate() override;
// void OnActivate() override;
void clear_pages() override;
bool supports_printer_technology(const PrinterTechnology tech) override { return tech == ptFFF; }
};
@ -403,7 +426,7 @@ class TabPrinter : public Tab
std::vector<PageShp> m_pages_fff;
std::vector<PageShp> m_pages_sla;
void build_printhost(ConfigOptionsGroup *optgroup);
// void build_printhost(ConfigOptionsGroup *optgroup);
public:
wxButton* m_serial_test_btn = nullptr;
ScalableButton* m_print_host_test_btn = nullptr;
@ -426,11 +449,14 @@ public:
void build() override;
void build_fff();
void build_sla();
void activate_selected_page(std::function<void()> throw_if_canceled) override;
void clear_pages() override;
void toggle_options() override;
void update() override;
void update_fff();
void update_sla();
void update_pages(); // update m_pages according to printer technology
void update_serial_ports();
// void update_serial_ports();
void extruders_count_changed(size_t extruders_count);
PageShp build_kinematics_page();
void build_unregular_pages();
@ -455,6 +481,7 @@ public:
void build() override;
void reload_config() override;
void toggle_options() override {};
void update() override;
void init_options_list() override;
bool supports_printer_technology(const PrinterTechnology tech) override { return tech == ptSLA; }
@ -472,25 +499,13 @@ public:
void build() override;
void reload_config() override;
void update_description_lines() override;
void toggle_options() override;
void update() override;
// void init_options_list() override;
void clear_pages() override;
bool supports_printer_technology(const PrinterTechnology tech) override { return tech == ptSLA; }
};
class SavePresetWindow :public wxDialog
{
public:
SavePresetWindow(wxWindow* parent) :wxDialog(parent, wxID_ANY, _(L("Save preset"))) {}
~SavePresetWindow() {}
std::string m_chosen_name;
wxComboBox* m_combo;
void build(const wxString& title, const std::string& default_name, std::vector<std::string> &values);
void accept();
std::string get_name() { return m_chosen_name; }
};
} // GUI
} // Slic3r