Files
OrcaSlicer-KX/src/slic3r/GUI/GUI_ObjectTableSettings.cpp
Ocraftyone dab6fa4db2 Fix Compile Warnings (#5963)
* Fix calls to depreciated wxPen constructor

* Fix use of wxTimerEvent

* Fix unrecognized character escape sequence

* Fix signed/unsigned mismatch

At least as much as possible without significantly altering parts of the application

* Clean unreferenced variables

* fix mistyped namespace selector

* Update deprecated calls

* Fix preprocessor statement

* Remove empty switch statements

* Change int vector used as bool to bool vector

* Remove empty control statements and related unused code

* Change multi character constant to string constant

* Fix discarded return value

json::parse was being called on the object, rather than statically like it should be. Also, the value was not being captured.

* Rename ICON_SIZE def used by MultiMachine

By having the definition in the header, it causes issues when other files define ICON_SIZE. By renaming it to MM_ICON_SIZE, this lessens the issue. It would probably be ideal to have the definitions in the respective .cpp that use them, but it would make it less convenient to update the values if needed in the future.

* Remove unused includes

* Fix linux/macOS compilation

* Hide unused-function errors on non-Windows systems

* Disable signed/unsigned comparison mismatch error

* Remove/Disable more unused variables

Still TODO: check double for loop in Print.cpp

* Remove unused variable that was missed

* Remove unused variables in libraries in the src folder

* Apply temporary fix for subobject linkage error

* Remove/Disable last set of unused variables reported by GCC

* remove redundant for loop

* fix misspelled ifdef check

* Update message on dialog

* Fix hard-coded platform specific modifier keys

* Remove duplicate for loop

* Disable -Wmisleading-indentation warning

* disable -Wswitch warning

* Remove unused local typedefs

* Fix -Wunused-value

* Fix pragma error on Windows from subobject linkage fix

* Fix -Waddress

* Fix null conversions (-Wconversion-null)

---------

Co-authored-by: SoftFever <softfeverever@gmail.com>
2024-07-29 21:00:26 +08:00

539 lines
20 KiB
C++

#include "libslic3r/PresetBundle.hpp"
#include "libslic3r/Model.hpp"
#include "GUI_ObjectList.hpp"
#include "GUI_Factories.hpp"
#include "GUI_ObjectTableSettings.hpp"
#include "GUI_ObjectTable.hpp"
#include "OptionsGroup.hpp"
#include "GUI_App.hpp"
#include "wxExtensions.hpp"
#include "Plater.hpp"
#include <boost/algorithm/string.hpp>
#include "I18N.hpp"
#include "ConfigManipulation.hpp"
#include <wx/wupdlock.h>
namespace Slic3r
{
namespace GUI
{
wxDEFINE_EVENT(EVT_LOCK_DISABLE, wxCommandEvent);
wxDEFINE_EVENT(EVT_LOCK_ENABLE, wxCommandEvent);
OTG_Settings::OTG_Settings(wxWindow* parent, const bool staticbox) :
m_parent(parent)
{
wxString title = ""; // temporary workaround - #ys_FIXME
m_og = std::make_shared<ConfigOptionsGroup>(parent, title, (DynamicPrintConfig*)nullptr, true);
}
bool OTG_Settings::IsShown()
{
return m_og->sizer->IsEmpty() ? false : m_og->sizer->IsShown(size_t(0));
}
void OTG_Settings::Show(const bool show)
{
m_og->Show(show);
}
void OTG_Settings::Hide()
{
Show(false);
}
void OTG_Settings::UpdateAndShow(const bool show)
{
Show(show);
// m_parent->Layout();
}
wxSizer* OTG_Settings::get_sizer()
{
return m_og->sizer;
}
ObjectTableSettings::ObjectTableSettings(wxWindow* parent, ObjectGridTable* table) :
OTG_Settings(parent, true), m_table(table)
{
m_og->activate();
//m_og->set_name(_(L("Per-Object Settings")));
m_settings_list_sizer = new wxBoxSizer(wxVERTICAL);
m_og->sizer->Add(m_settings_list_sizer, 1, wxEXPAND | wxLEFT, 5);
m_bmp_reset = ScalableBitmap(parent, "lock_normal");
m_bmp_reset_focus = ScalableBitmap(parent, "lock_normal");
//TODO, adjust later
m_bmp_reset_disable = ScalableBitmap(parent, "dot");
}
bool ObjectTableSettings::update_settings_list(bool is_object, bool is_multiple_selection, ModelObject* object, ModelConfig* config, const std::string& category)
{
std::string group_category;
int different_count = 0;
m_settings_list_sizer->Clear(true);
m_og_settings.resize(0);
Show(true);
if (!config || is_multiple_selection || !object)
return false;
const auto printer_technology = wxGetApp().plater()->printer_technology();
// update config values according to configuration hierarchy
m_current_config = printer_technology == ptFFF ?
wxGetApp().preset_bundle->prints.get_edited_preset().config :
wxGetApp().preset_bundle->sla_prints.get_edited_preset().config;
//ConfigManipulation config_manipulation(load_config, toggle_field, nullptr, config);
if (!is_object)
{
m_current_config.apply(object->config.get(), true);
}
m_origin_config = m_current_config;
m_current_config.apply(config->get(), true);
//SettingsFactory::Bundle cat_options = SettingsFactory::get_bundle(&config->get(), is_object);
std::map<std::string, std::vector<SimpleSettingData>> cat_options;
std::vector<SimpleSettingData> category_settings = SettingsFactory::get_visible_options(category, !is_object);
auto is_option_modified = [this](std::string key) {
ConfigOption* config_option1 = m_origin_config.option(key);
ConfigOption* config_option2 = m_current_config.option(key);
if (!config_option1 && config_option2)
return true;
else if (config_option1 && config_option2 && (*config_option1 != *config_option2))
return true;
return false;
};
//get the category and settings
if (category_settings.size() == 0) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "can not find settings for category " <<category <<", display all the modified settings instead!!!" << std::endl;
//return false;
cat_options = SettingsFactory::get_all_visible_options(!is_object);
std::map<std::string, std::vector<SimpleSettingData>>::iterator it1 = cat_options.begin();
while (it1 != cat_options.end())
{
std::vector<SimpleSettingData>& settings = it1->second;
std::vector<SimpleSettingData>::iterator it2 = settings.begin();
while ( it2 != settings.end() )
{
if (!is_option_modified(it2->name)) {
it2 = settings.erase(it2);
}
else {
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(" category %1% , keep option %2%")%it1->first % it2->name;
it2++;
}
}
if (settings.size() > 0)
it1++;
else
it1 = cat_options.erase(it1);
}
}
else {
cat_options.emplace(category, category_settings);
}
std::vector<std::string> categories;
categories.reserve(cat_options.size());
for (auto& cat : cat_options)
{
categories.push_back(cat.first);
group_category = cat.first;
auto extra_column = [this, is_object, object, config, group_category](wxWindow* parent, const Line& line)
{
auto opt_key = (line.get_options())[0].opt_id; //we assume that we have one option per line
auto btn = new ScalableButton(parent, wxID_ANY, m_bmp_reset);
btn->SetToolTip(_(L("Reset parameter")));
#ifdef __WINDOWS__
btn->SetBackgroundColour(parent->GetBackgroundColour());
#endif // DEBUG
btn->SetBitmapFocus(m_bmp_reset_focus.bmp());
btn->SetBitmapHover(m_bmp_reset_focus.bmp());
#ifdef __WINDOWS__
btn->SetBitmapDisabled(m_bmp_reset_disable.bmp());
#endif
#ifdef __WXOSX_MAC__
btn->Bind(EVT_LOCK_DISABLE, [this, btn](auto &e) { btn->SetBitmap(m_bmp_reset_disable.bmp()); });
btn->Bind(EVT_LOCK_ENABLE, [this, btn](auto &e) { btn->SetBitmap(m_bmp_reset_focus.bmp()); });
#endif
btn->Bind(wxEVT_BUTTON, [btn, opt_key, this, is_object, object, config, group_category](wxEvent &event) {
//wxGetApp().plater()->take_snapshot(from_u8((boost::format(_utf8(L("Reset Option %s"))) % opt_key).str()));
config->erase(opt_key);
//btn->Hide();
wxGetApp().obj_list()->changed_object();
/*wxTheApp->CallAfter([this, is_object, object, config, category]() {
wxWindowUpdateLocker noUpdates(m_parent);
update_settings_list(is_object, false, object, config, category);
});*/
this->m_parent->Freeze();
/* Check overriden options list after deleting.
* Some options couldn't be deleted because of another one.
* Like, we couldn't delete fill pattern, if fill density is set to 100%
*/
m_current_config = m_origin_config;
m_current_config.apply(config->get(), true);
update_config_values(is_object, object, config, group_category);
this->m_parent->Thaw();
#ifdef __WXOSX_MAC__
if (!btn->IsEnabled()) {
btn->SetBitmap(m_bmp_reset_disable.bmp());
} else {
btn->SetBitmap(m_bmp_reset_focus.bmp());
}
#endif
});
(const_cast<Line&>(line)).extra_widget_win = btn;
return btn;
};
auto optgroup = std::make_shared<ConfigOptionsGroup>(m_og->ctrl_parent(), _(cat.first), &m_current_config, false, extra_column);
optgroup->label_width = 15;
optgroup->sidetext_width = 5;
optgroup->set_config_category_and_type(GUI::from_u8(group_category), Preset::TYPE_PRINT);
std::weak_ptr<ConfigOptionsGroup> weak_optgroup(optgroup);
optgroup->m_on_change = [this, is_object, object, config, group_category](const t_config_option_key &opt_id, const boost::any &value) {
this->m_parent->Freeze();
this->update_config_values(is_object, object, config, group_category);
wxGetApp().obj_list()->changed_object();
this->m_parent->Thaw();
//update_extra_column_visible_status(optgroup.get(), cat.second, config);
};
// call back for rescaling of the extracolumn control
optgroup->rescale_extra_column_item = [this](wxWindow* win) {
auto *ctrl = dynamic_cast<ScalableButton*>(win);
if (ctrl == nullptr)
return;
ctrl->SetBitmap_(m_bmp_reset);
ctrl->SetBitmapFocus(m_bmp_reset_focus.bmp());
ctrl->SetBitmapHover(m_bmp_reset_focus.bmp());
#ifdef __WINDOWS__
ctrl->SetBitmapDisabled(m_bmp_reset_disable.bmp());
#endif
};
const bool is_extruders_cat = cat.first == "Extruders";
for (auto& opt : cat.second)
{
Option option = optgroup->get_option(opt.name);
option.opt.width = 18;
if (is_extruders_cat)
option.opt.max = wxGetApp().extruders_edited_cnt();
optgroup->append_single_option_line(option);
if (!opt.label.empty()) {
auto line = optgroup->get_line(opt.name);
if (line)
line->label = GUI::from_u8(opt.label);
}
}
optgroup->activate();
for (auto& opt : cat.second)
optgroup->get_field(opt.name)->m_on_change = [weak_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((boost::format("Change Option %s") % opt_id).str());
weak_optgroup.lock()->on_change_OG(opt_id, value);
};
optgroup->reload_config();
different_count = update_extra_column_visible_status(optgroup.get(), cat.second, config);
m_current_different += different_count;
if (different_count > 0)
m_different_map[group_category] = different_count;
/*for (auto& opt : cat.second)
{
auto line = optgroup->get_line(opt);
if (line) {
if (config->has(opt))
line->extra_widget_win->Show(true);
else
line->extra_widget_win->Hide();
}
}*/
m_settings_list_sizer->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 0);
m_og_settings.push_back(optgroup);
auto toggle_field = [this, optgroup](const t_config_option_key & opt_key, bool toggle, int opt_index)
{
Field* field = optgroup->get_fieldc(opt_key, opt_index);;
if (field)
field->toggle(toggle);
};
auto toggle_line = [this, optgroup](const t_config_option_key & opt_key, bool toggle)
{
Line* line = optgroup->get_line(opt_key);
if (line) line->toggle_visible = toggle;
};
ConfigManipulation config_manipulation(nullptr, toggle_field, toggle_line, nullptr, &m_current_config);
bool is_BBL_printer = wxGetApp().preset_bundle->is_bbl_vendor();
config_manipulation.set_is_BBL_Printer(is_BBL_printer);
printer_technology == ptFFF ? config_manipulation.toggle_print_fff_options(&m_current_config) :
config_manipulation.toggle_print_sla_options(&m_current_config) ;
optgroup->update_visibility(wxGetApp().get_mode());
}
//if (!categories.empty()) {
// update_config_values(is_object, object, config, category);
//}
if (m_current_different > 0)
m_table->enable_reset_all_button(true);
else
m_table->enable_reset_all_button(false);
return true;
}
bool ObjectTableSettings::add_missed_options(ModelConfig* config_to, const DynamicPrintConfig& config_from)
{
bool is_added = false;
if (wxGetApp().plater()->printer_technology() == ptFFF)
{
if (config_to->has("sparse_infill_density") && !config_to->has("sparse_infill_pattern"))
{
if (config_from.option<ConfigOptionPercent>("sparse_infill_density")->value == 100) {
config_to->set_key_value("sparse_infill_pattern", config_from.option("sparse_infill_pattern")->clone());
is_added = true;
}
}
}
return is_added;
}
int ObjectTableSettings::update_extra_column_visible_status(ConfigOptionsGroup* option_group, const std::vector<SimpleSettingData>& option_keys, ModelConfig* config)
{
int count = 0;
for (auto& opt : option_keys)
{
auto line = option_group->get_line(opt.name);
Field* field = option_group->get_fieldc(opt.name, -1);
wxWindow *reset_window = field?field->getWindow():nullptr;
if (line) {
if ((config->has(opt.name)) && reset_window&&reset_window->IsEnabled()) {
line->extra_widget_win->Enable();
#ifdef __WXOSX_MAC__
wxCommandEvent event(EVT_LOCK_ENABLE);
event.SetEventObject(line->extra_widget_win);
wxPostEvent(line->extra_widget_win, event);
#endif
count++;
} else {
line->extra_widget_win->Disable();
#ifdef __WXOSX_MAC__
wxCommandEvent event(EVT_LOCK_DISABLE);
event.SetEventObject(line->extra_widget_win);
wxPostEvent(line->extra_widget_win, event);
#endif
}
}
}
wxGridSizer* grid_sizer = option_group->get_grid_sizer();
grid_sizer->Layout();
return count;
}
void ObjectTableSettings::update_config_values(bool is_object, ModelObject* object, ModelConfig* config, const std::string& category)
{
int different_count = 0;
const auto printer_technology = wxGetApp().plater()->printer_technology();
if (!object || !config)
return;
// update config values according to configuration hierarchy
DynamicPrintConfig &main_config = m_current_config;
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)
break;
}
if (field)
field->toggle(toggle);
};
auto toggle_line = [this](const t_config_option_key &opt_key, bool toggle) {
for (auto og : m_og_settings) {
Line *line = og->get_line(opt_key);
if (line) { line->toggle_visible = toggle; break; }
}
};
ConfigManipulation config_manipulation(nullptr, toggle_field, toggle_line, nullptr, &m_current_config);
config_manipulation.set_is_BBL_Printer(wxGetApp().preset_bundle->is_bbl_vendor());
printer_technology == ptFFF ? config_manipulation.update_print_fff_config(&main_config) :
config_manipulation.update_print_sla_config(&main_config) ;
printer_technology == ptFFF ? config_manipulation.toggle_print_fff_options(&main_config) :
config_manipulation.toggle_print_sla_options(&main_config) ;
for (auto og : m_og_settings) {
og->update_visibility(wxGetApp().get_mode());
}
m_parent->Layout();
m_parent->Fit();
m_parent->GetParent()->Layout();
t_config_option_keys diff_keys;
for (const t_config_option_key &opt_key : main_config.keys()) {
const ConfigOption *this_opt = main_config.option(opt_key);
const ConfigOption *other_opt = m_origin_config.option(opt_key);
if (this_opt != nullptr && (other_opt == nullptr || *this_opt != *other_opt))
diff_keys.emplace_back(opt_key);
}
// load checked values from main_config to config
config->reset();
config->apply_only(main_config, diff_keys, true);
// Initialize UI components with the config values.
std::vector<SimpleSettingData> category_settings = SettingsFactory::get_visible_options(category, !is_object);
std::string current_category;
for (auto og : m_og_settings)
{
current_category = GUI::into_u8(og->config_category());
og->reload_config();
if (category == ObjectGridTable::category_all) {
category_settings = SettingsFactory::get_visible_options(current_category, !is_object);
different_count = update_extra_column_visible_status(og.get(), category_settings, config);
if (different_count > 0)
m_different_map[current_category] = different_count;
else
m_different_map.erase(current_category);
}
else if (category == current_category){
different_count = update_extra_column_visible_status(og.get(), category_settings, config);
if (different_count > 0)
m_different_map[current_category] = different_count;
else
m_different_map.erase(current_category);
}
}
if (m_different_map.size() > 0)
m_table->enable_reset_all_button(true);
else
m_table->enable_reset_all_button(false);
//update the table and volume settings
m_table->reload_cell_data(m_current_row, category);
}
void ObjectTableSettings::UpdateAndShow(int row, const bool show, bool is_object, bool is_multiple_selection, ModelObject* object, ModelConfig* config, const std::string& category)
{
m_current_row = row;
m_current_category = category;
m_current_different = 0;
m_different_map.clear();
//OTG_Settings::UpdateAndShow(show ? update_settings_list(is_object, is_multiple_selection, object, config, category) : false);
if (show) {
update_settings_list(is_object, is_multiple_selection, object, config, category);
}
else
OTG_Settings::UpdateAndShow(false);
}
void ObjectTableSettings::ValueChanged(int row, bool is_object, ModelObject* object, ModelConfig* config, const std::string& category, const std::string& key)
{
if ((row != m_current_row)
|| ((category != m_current_category) && (m_current_category != ObjectGridTable::category_all)))
return;
ConfigOption *my_opt = m_current_config.option(key, true);
if (config->has(key)) {
my_opt->set(config->option(key));
}
else {
ConfigOption* config_option = m_origin_config.option(key);
if (config_option)
my_opt->set(config_option);
else
m_current_config.erase(key);
}
update_config_values(is_object, object, config, category);
}
void ObjectTableSettings::resetAllValues(int row, bool is_object, ModelObject* object, ModelConfig* config, const std::string& category)
{
if ((row != m_current_row) || (category != m_current_category))
return;
if (category == ObjectGridTable::category_all) {
std::map<std::string, std::vector<SimpleSettingData>> cat_options;
//get the category and settings
cat_options = SettingsFactory::get_all_visible_options(!is_object);
std::map<std::string, std::vector<SimpleSettingData>>::iterator it1 = cat_options.begin();
while (it1 != cat_options.end())
{
std::vector<SimpleSettingData>& settings = it1->second;
std::vector<SimpleSettingData>::iterator it2 = settings.begin();
while ( it2 != settings.end() )
{
config->erase(it2->name);
it2++;
}
it1++;
}
}
else {
// Initialize UI components with the config values.
std::vector<SimpleSettingData> category_settings = SettingsFactory::get_visible_options(category, !is_object);
for (auto& opt : category_settings)
{
config->erase(opt.name);
}
}
m_current_config = m_origin_config;
m_current_config.apply(config->get(), true);
update_config_values(is_object, object, config, category);
}
void ObjectTableSettings::msw_rescale()
{
for (auto group : m_og_settings)
group->msw_rescale();
}
} //namespace GUI
} //namespace Slic3r