底框信息栏优化。软件启动弹窗优化。配置功能优化

This commit is contained in:
cjw 2025-01-21 14:33:02 +08:00
parent f6c2e90254
commit 0f144c6a76
15 changed files with 34473 additions and 42 deletions

1283
src/libslic3r/AppConfig.cpp Normal file

File diff suppressed because it is too large Load Diff

3598
src/libslic3r/Preset.cpp Normal file

File diff suppressed because it is too large Load Diff

1022
src/libslic3r/Preset.hpp Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,277 @@
#ifndef slic3r_PresetBundle_hpp_
#define slic3r_PresetBundle_hpp_
#include "Preset.hpp"
#include "AppConfig.hpp"
#include "enum_bitmask.hpp"
#include <memory>
#include <unordered_map>
#include <boost/filesystem/path.hpp>
#define DEFAULT_USER_FOLDER_NAME "default"
#define BUNDLE_STRUCTURE_JSON_NAME "bundle_structure.json"
#define VALIDATE_PRESETS_SUCCESS 0
#define VALIDATE_PRESETS_PRINTER_NOT_FOUND 1
#define VALIDATE_PRESETS_FILAMENTS_NOT_FOUND 2
#define VALIDATE_PRESETS_MODIFIED_GCODES 3
namespace Slic3r {
// Bundle of Print + Filament + Printer presets.
class PresetBundle
{
public:
PresetBundle();
PresetBundle(const PresetBundle &rhs);
PresetBundle& operator=(const PresetBundle &rhs);
// Remove all the presets but the "-- default --".
// Optionally remove all the files referenced by the presets from the user profile directory.
void reset(bool delete_files);
void setup_directories();
void copy_files(const std::string& from);
struct PresetPreferences {
std::string printer_model_id;// name of a preferred printer model
std::string printer_variant; // name of a preferred printer variant
std::string filament; // name of a preferred filament preset
std::string sla_material; // name of a preferred sla_material preset
};
// Load ini files of all types (print, filament, printer) from Slic3r::data_dir() / presets.
// Load selections (current print, current filaments, current printer) from config.ini
// select preferred presets, if any exist
PresetsConfigSubstitutions load_presets(AppConfig &config, ForwardCompatibilitySubstitutionRule rule,
const PresetPreferences& preferred_selection = PresetPreferences());
// Load selections (current print, current filaments, current printer) from config.ini
// This is done just once on application start up.
//BBS: change it to public
void load_selections(AppConfig &config, const PresetPreferences& preferred_selection = PresetPreferences());
// BBS Load user presets
PresetsConfigSubstitutions load_user_presets(std::string user, ForwardCompatibilitySubstitutionRule rule);
PresetsConfigSubstitutions load_user_presets(AppConfig &config, std::map<std::string, std::map<std::string, std::string>>& my_presets, ForwardCompatibilitySubstitutionRule rule);
PresetsConfigSubstitutions import_presets(std::vector<std::string> &files, std::function<int(std::string const &)> override_confirm, ForwardCompatibilitySubstitutionRule rule);
bool import_json_presets(PresetsConfigSubstitutions & substitutions,
std::string & file,
std::function<int(std::string const &)> override_confirm,
ForwardCompatibilitySubstitutionRule rule,
int & overwrite,
std::vector<std::string> & result);
void save_user_presets(AppConfig& config, std::vector<std::string>& need_to_delete_list);
void remove_users_preset(AppConfig &config, std::map<std::string, std::map<std::string, std::string>> * my_presets = nullptr);
void update_user_presets_directory(const std::string preset_folder);
void remove_user_presets_directory(const std::string preset_folder);
void update_system_preset_setting_ids(std::map<std::string, std::map<std::string, std::string>>& system_presets);
//BBS: add API to get previous machine
int validate_presets(const std::string &file_name, DynamicPrintConfig& config, std::set<std::string>& different_gcodes);
//BBS: add function to generate differed preset for save
//the pointer should be freed by the caller
Preset* get_preset_differed_for_save(Preset& preset);
int get_differed_values_to_update(Preset& preset, std::map<std::string, std::string>& key_values);
//BBS: get vendor's current version
Semver get_vendor_profile_version(std::string vendor_name);
//BBS: project embedded preset logic
PresetsConfigSubstitutions load_project_embedded_presets(std::vector<Preset*> project_presets, ForwardCompatibilitySubstitutionRule substitution_rule);
std::vector<Preset*> get_current_project_embedded_presets();
void reset_project_embedded_presets();
//BBS: find printer model
std::string get_texture_for_printer_model(std::string model_name);
std::string get_stl_model_for_printer_model(std::string model_name);
std::string get_hotend_model_for_printer_model(std::string model_name);
// Export selections (current print, current filaments, current printer) into config.ini
void export_selections(AppConfig &config);
// BBS
void set_num_filaments(unsigned int n, std::string new_col = "");
unsigned int sync_ams_list(unsigned int & unknowns);
//BBS: check whether this is the only edited filament
bool is_the_only_edited_filament(unsigned int filament_index);
void set_calibrate_printer(std::string name);
std::set<std::string> get_printer_names_by_printer_type_and_nozzle(const std::string &printer_type, std::string nozzle_diameter_str);
bool check_filament_temp_equation_by_printer_type_and_nozzle_for_mas_tray(const std::string &printer_type,
std::string & nozzle_diameter_str,
std::string & setting_id,
std::string & tag_uid,
std::string & nozzle_temp_min,
std::string & nozzle_temp_max,
std::string & preset_setting_id);
PresetCollection prints;
PresetCollection sla_prints;
PresetCollection filaments;
PresetCollection configs;
PresetCollection sla_materials;
PresetCollection& materials(PrinterTechnology pt) { return pt == ptFFF ? this->filaments : this->sla_materials; }
const PresetCollection& materials(PrinterTechnology pt) const { return pt == ptFFF ? this->filaments : this->sla_materials; }
PrinterPresetCollection printers;
PhysicalPrinterCollection physical_printers;
// Filament preset names for a multi-extruder or multi-material print.
// extruders.size() should be the same as printers.get_edited_preset().config.nozzle_diameter.size()
std::vector<std::string> filament_presets;
// BBS: ams
std::map<int, DynamicPrintConfig> filament_ams_list;
std::vector<std::vector<std::string>> ams_multi_color_filment;
// Calibrate
Preset const * calibrate_printer = nullptr;
std::set<Preset const *> calibrate_filaments;
// The project configuration values are kept separated from the print/filament/printer preset,
// they are being serialized / deserialized from / to the .amf, .3mf, .config, .gcode,
// and they are being used by slicing core.
DynamicPrintConfig project_config;
// There will be an entry for each system profile loaded,
// and the system profiles will point to the VendorProfile instances owned by PresetBundle::vendors.
VendorMap vendors;
struct ObsoletePresets {
std::vector<std::string> prints;
std::vector<std::string> sla_prints;
std::vector<std::string> filaments;
std::vector<std::string> sla_materials;
std::vector<std::string> printers;
std::vector<std::string> configs;
};
ObsoletePresets obsolete_presets;
bool has_defauls_only() const
{ return prints.has_defaults_only() && filaments.has_defaults_only() && printers.has_defaults_only(); }
DynamicPrintConfig full_config() const;
// full_config() with the some "useless" config removed.
DynamicPrintConfig full_config_secure() const;
// Load user configuration and store it into the user profiles.
// This method is called by the configuration wizard.
void load_config_from_wizard(const std::string &name, DynamicPrintConfig config, Semver file_version, bool is_custom_defined = false)
{ this->load_config_file_config(name, false, std::move(config), file_version, true, is_custom_defined); }
// Load configuration that comes from a model file containing configuration, such as 3MF et al.
// This method is called by the Plater.
void load_config_model(const std::string &name, DynamicPrintConfig config, Semver file_version = Semver())
{ this->load_config_file_config(name, true, std::move(config), file_version); }
// Load an external config file containing the print, filament and printer presets.
// Instead of a config file, a G-code may be loaded containing the full set of parameters.
// In the future the configuration will likely be read from an AMF file as well.
// If the file is loaded successfully, its print / filament / printer profiles will be activated.
ConfigSubstitutions load_config_file(const std::string &path, ForwardCompatibilitySubstitutionRule compatibility_rule);
// Load a config bundle file, into presets and store the loaded presets into separate files
// of the local configuration directory.
// Load settings into the provided settings instance.
// Activate the presets stored in the config bundle.
// Returns the number of presets loaded successfully.
enum LoadConfigBundleAttribute {
// Save the profiles, which have been loaded.
SaveImported,
// Delete all old config profiles before loading.
ResetUserProfile,
// Load a system config bundle.
LoadSystem,
LoadVendorOnly,
LoadFilamentOnly,
};
using LoadConfigBundleAttributes = enum_bitmask<LoadConfigBundleAttribute>;
// Load the config bundle based on the flags.
// Don't do any config substitutions when loading a system profile, perform and report substitutions otherwise.
/*std::pair<PresetsConfigSubstitutions, size_t> load_configbundle(
const std::string &path, LoadConfigBundleAttributes flags, ForwardCompatibilitySubstitutionRule compatibility_rule);*/
//BBS: add json related logic
std::pair<PresetsConfigSubstitutions, size_t> load_vendor_configs_from_json(
const std::string &path, const std::string &vendor_name, LoadConfigBundleAttributes flags, ForwardCompatibilitySubstitutionRule compatibility_rule);
// Export a config bundle file containing all the presets and the names of the active presets.
//void export_configbundle(const std::string &path, bool export_system_settings = false, bool export_physical_printers = false);
//BBS: add a function to export current configbundle as default
//void export_current_configbundle(const std::string &path);
//BBS: add a function to export system presets for cloud-slicer
//void export_system_configs(const std::string &path);
std::vector<std::string> export_current_configs(const std::string &path, std::function<int(std::string const &)> override_confirm,
bool include_modify, bool export_system_settings = false);
// Enable / disable the "- default -" preset.
void set_default_suppressed(bool default_suppressed);
// Set the filament preset name. As the name could come from the UI selection box,
// an optional "(modified)" suffix will be removed from the filament name.
void set_filament_preset(size_t idx, const std::string &name);
// Read out the number of extruders from an active printer preset,
// update size and content of filament_presets.
void update_multi_material_filament_presets();
// Update the is_compatible flag of all print and filament presets depending on whether they are marked
// as compatible with the currently selected printer (and print in case of filament presets).
// Also updates the is_visible flag of each preset.
// If select_other_if_incompatible is true, then the print or filament preset is switched to some compatible
// preset if the current print or filament preset is not compatible.
void update_compatible(PresetSelectCompatibleType select_other_print_if_incompatible, PresetSelectCompatibleType select_other_filament_if_incompatible);
void update_compatible(PresetSelectCompatibleType select_other_if_incompatible) { this->update_compatible(select_other_if_incompatible, select_other_if_incompatible); }
// Set the is_visible flag for printer vendors, printer models and printer variants
// based on the user configuration.
// If the "vendor" section is missing, enable all models and variants of the particular vendor.
void load_installed_printers(const AppConfig &config);
const std::string& get_preset_name_by_alias(const Preset::Type& preset_type, const std::string& alias) const;
const int get_required_hrc_by_filament_type(const std::string& filament_type) const;
// Save current preset of a provided type under a new name. If the name is different from the old one,
// Unselected option would be reverted to the beginning values
//BBS: add project embedded preset logic
void save_changes_for_preset(const std::string& new_name, Preset::Type type, const std::vector<std::string>& unselected_options, bool save_to_project = false);
std::pair<PresetsConfigSubstitutions, std::string> load_system_models_from_json(ForwardCompatibilitySubstitutionRule compatibility_rule);
std::pair<PresetsConfigSubstitutions, std::string> load_system_filaments_json(ForwardCompatibilitySubstitutionRule compatibility_rule);
VendorProfile get_custom_vendor_models() const;
//BBS: add BBL as default
static const char *BBL_BUNDLE;
static const char *BBL_DEFAULT_PRINTER_MODEL;
static const char *BBL_DEFAULT_PRINTER_VARIANT;
static const char *BBL_DEFAULT_FILAMENT;
private:
//std::pair<PresetsConfigSubstitutions, std::string> load_system_presets(ForwardCompatibilitySubstitutionRule compatibility_rule);
//BBS: add json related logic
std::pair<PresetsConfigSubstitutions, std::string> load_system_presets_from_json(ForwardCompatibilitySubstitutionRule compatibility_rule);
// Merge one vendor's presets with the other vendor's presets, report duplicates.
std::vector<std::string> merge_presets(PresetBundle &&other);
// Update renamed_from and alias maps of system profiles.
void update_system_maps();
// Set the is_visible flag for filaments and sla materials,
// apply defaults based on enabled printers when no filaments/materials are installed.
void load_installed_filaments(AppConfig &config);
void load_installed_sla_materials(AppConfig &config);
// Load print, filament & printer presets from a config. If it is an external config, then the name is extracted from the external path.
// and the external config is just referenced, not stored into user profile directory.
// If it is not an external config, then the config will be stored into the user profile directory.
void load_config_file_config(const std::string &name_or_path, bool is_external, DynamicPrintConfig &&config, Semver file_version = Semver(), bool selected = false, bool is_custom_defined = false);
/*ConfigSubstitutions load_config_file_config_bundle(
const std::string &path, const boost::property_tree::ptree &tree, ForwardCompatibilitySubstitutionRule compatibility_rule);*/
DynamicPrintConfig full_fff_config() const;
DynamicPrintConfig full_sla_config() const;
};
ENABLE_ENUM_BITMASK_OPERATORS(PresetBundle::LoadConfigBundleAttribute)
} // namespace Slic3r
#endif /* slic3r_PresetBundle_hpp_ */

View File

@ -1786,13 +1786,13 @@ void PrintConfigDef::init_fff_params()
// "Note that this option only takes effect if no prime tower is generated in current plate.");
//def->set_default_value(new ConfigOptionBool(0));
/* def = this->add("default_print_speed", coFloat);
def = this->add("default_print_speed", coFloat);
def->label = L("Default print speed");
def->tooltip = L("Speed of initial layer except the solid infill part");
def->sidetext = L("mm/s");
def->min = 0;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(30));todo*/
def->set_default_value(new ConfigOptionFloat(30));
def = this->add("initial_layer_speed", coFloat);
def->label = L("Initial layer");
@ -4680,6 +4680,7 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
} else if (opt_key == "support_material_enforce_layers") {
opt_key = "enforce_support_layers";
} else if ((opt_key == "initial_layer_print_height" ||
opt_key == "default_print_speed" ||
opt_key == "initial_layer_speed" ||
opt_key == "internal_solid_infill_speed" ||
opt_key == "top_surface_speed" ||

View File

@ -1019,7 +1019,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
((ConfigOptionFloat, initial_layer_acceleration))
((ConfigOptionFloat, initial_layer_line_width))
((ConfigOptionFloat, initial_layer_print_height))
//((ConfigOptionFloat, default_print_speed))
((ConfigOptionFloat, default_print_speed))
((ConfigOptionFloat, initial_layer_speed))
//BBS
((ConfigOptionFloat, initial_layer_infill_speed))

597
src/slic3r/GUI/GUI.cpp Normal file
View File

@ -0,0 +1,597 @@
#include "GUI.hpp"
#include "GUI_App.hpp"
#include "format.hpp"
#include "I18N.hpp"
#include "libslic3r/LocalesUtils.hpp"
#ifdef __APPLE__
#include "slic3r/Utils/MacDarkMode.hpp"
#endif
#include <string>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/any.hpp>
#if __APPLE__
#import <IOKit/pwr_mgt/IOPMLib.h>
#elif _WIN32
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <Windows.h>
#include "boost/nowide/convert.hpp"
#endif
#include "AboutDialog.hpp"
#include "MsgDialog.hpp"
#include "format.hpp"
#include "WebUserLoginDialog.hpp"
#include "libslic3r/Print.hpp"
namespace Slic3r {
class AppConfig;
namespace GUI {
#if __APPLE__
IOPMAssertionID assertionID;
#endif
void disable_screensaver()
{
#if __APPLE__
CFStringRef reasonForActivity = CFSTR("Slic3r");
[[maybe_unused]]IOReturn success = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep,
kIOPMAssertionLevelOn, reasonForActivity, &assertionID);
// ignore result: success == kIOReturnSuccess
#elif _WIN32
SetThreadExecutionState(ES_DISPLAY_REQUIRED | ES_CONTINUOUS);
#endif
}
void enable_screensaver()
{
#if __APPLE__
IOPMAssertionRelease(assertionID);
#elif _WIN32
SetThreadExecutionState(ES_CONTINUOUS);
#endif
}
bool debugged()
{
#ifdef _WIN32
return IsDebuggerPresent() == TRUE;
#else
return false;
#endif /* _WIN32 */
}
void break_to_debugger()
{
#ifdef _WIN32
if (IsDebuggerPresent())
DebugBreak();
#endif /* _WIN32 */
}
const std::string& shortkey_ctrl_prefix()
{
static const std::string str =
#ifdef __APPLE__
"⌘+"
#else
_u8L("Ctrl+")
#endif
;
return str;
}
const std::string& shortkey_alt_prefix()
{
static const std::string str =
#ifdef __APPLE__
"⌥+"
#else
"Alt+"
#endif
;
return str;
}
// opt_index = 0, by the reason of zero-index in ConfigOptionVector by default (in case only one element)
void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt_key, const boost::any& value, int opt_index /*= 0*/)
{
try{
if (config.def()->get(opt_key)->type == coBools && config.def()->get(opt_key)->nullable) {
ConfigOptionBoolsNullable* vec_new = new ConfigOptionBoolsNullable{ boost::any_cast<unsigned char>(value) };
config.option<ConfigOptionBoolsNullable>(opt_key)->set_at(vec_new, opt_index, 0);
return;
}
const ConfigOptionDef *opt_def = config.def()->get(opt_key);
switch (opt_def->type) {
case coFloatOrPercent:{
std::string str = boost::any_cast<std::string>(value);
bool percent = false;
if (str.back() == '%') {
str.pop_back();
percent = true;
}
double val = std::stod(str); // locale-dependent (on purpose - the input is the actual content of the field)
config.set_key_value(opt_key, new ConfigOptionFloatOrPercent(val, percent));
break;}
case coPercent:
config.set_key_value(opt_key, new ConfigOptionPercent(boost::any_cast<double>(value)));
break;
case coFloat:{
double& val = config.opt_float(opt_key);
val = boost::any_cast<double>(value);
break;
}
case coPercents:{
ConfigOptionPercents* vec_new = new ConfigOptionPercents{ boost::any_cast<double>(value) };
config.option<ConfigOptionPercents>(opt_key)->set_at(vec_new, opt_index, opt_index);
break;
}
case coFloats:{
ConfigOptionFloats* vec_new = new ConfigOptionFloats{ boost::any_cast<double>(value) };
config.option<ConfigOptionFloats>(opt_key)->set_at(vec_new, opt_index, opt_index);
break;
}
case coString:
config.set_key_value(opt_key, new ConfigOptionString(boost::any_cast<std::string>(value)));
break;
case coStrings:{
if (opt_key == "compatible_prints" || opt_key == "compatible_printers") {
config.option<ConfigOptionStrings>(opt_key)->values =
boost::any_cast<std::vector<std::string>>(value);
}
else if (config.def()->get(opt_key)->gui_flags.compare("serialized") == 0) {
std::string str = boost::any_cast<std::string>(value);
std::vector<std::string> values {};
if (!str.empty()) {
if (str.back() == ';') str.pop_back();
// Split a string to multiple strings by a semi - colon.This is the old way of storing multi - string values.
// Currently used for the post_process config value only.
boost::split(values, str, boost::is_any_of(";"));
if (values.size() == 1 && values[0] == "")
values.resize(0);
}
config.option<ConfigOptionStrings>(opt_key)->values = values;
}
else{
ConfigOptionStrings* vec_new = new ConfigOptionStrings{ boost::any_cast<std::string>(value) };
config.option<ConfigOptionStrings>(opt_key)->set_at(vec_new, opt_index, 0);
}
}
break;
case coBool:
config.set_key_value(opt_key, new ConfigOptionBool(boost::any_cast<bool>(value)));
break;
case coBools:{
ConfigOptionBools* vec_new = new ConfigOptionBools{ boost::any_cast<unsigned char>(value) != 0 };
config.option<ConfigOptionBools>(opt_key)->set_at(vec_new, opt_index, 0);
break;}
case coInt:
config.set_key_value(opt_key, new ConfigOptionInt(boost::any_cast<int>(value)));
break;
case coInts:{
ConfigOptionInts* vec_new = new ConfigOptionInts{ boost::any_cast<int>(value) };
config.option<ConfigOptionInts>(opt_key)->set_at(vec_new, opt_index, 0);
}
break;
case coEnum:{
auto *opt = opt_def->default_value.get()->clone();
opt->setInt(boost::any_cast<int>(value));
config.set_key_value(opt_key, opt);
}
break;
// BBS
case coEnums:{
ConfigOptionEnumsGeneric* vec_new = new ConfigOptionEnumsGeneric{ boost::any_cast<int>(value) };
if (config.has(opt_key))
config.option<ConfigOptionEnumsGeneric>(opt_key)->set_at(vec_new, opt_index, 0);
}
break;
case coPoint:{
config.set_key_value(opt_key, new ConfigOptionPoint(boost::any_cast<Vec2d>(value)));
}
break;
case coPoints:{
if (opt_key == "printable_area" || opt_key == "bed_exclude_area" || opt_key=="thumbnail_size") {
config.option<ConfigOptionPoints>(opt_key)->values = boost::any_cast<std::vector<Vec2d>>(value);
break;
}
ConfigOptionPoints* vec_new = new ConfigOptionPoints{ boost::any_cast<Vec2d>(value) };
config.option<ConfigOptionPoints>(opt_key)->set_at(vec_new, opt_index, 0);
}
break;
case coNone:
break;
default:
break;
}
}
catch (const std::exception &e)
{
wxLogError(format_wxstr("Internal error when changing value for %1%: %2%", opt_key, e.what()));
}
}
void show_error(wxWindow* parent, const wxString& message, bool monospaced_font)
{
wxGetApp().CallAfter([=] {
ErrorDialog msg(parent, message, monospaced_font);
msg.ShowModal();
});
}
void show_error(wxWindow* parent, const char* message, bool monospaced_font)
{
assert(message);
show_error(parent, wxString::FromUTF8(message), monospaced_font);
}
void show_error_id(int id, const std::string& message)
{
auto *parent = id != 0 ? wxWindow::FindWindowById(id) : nullptr;
show_error(parent, message);
}
void show_info(wxWindow* parent, const wxString& message, const wxString& title)
{
//wxMessageDialog msg_wingow(parent, message, wxString(SLIC3R_APP_NAME " - ") + (title.empty() ? _L("Notice") : title), wxOK | wxICON_INFORMATION);
MessageDialog msg_wingow(parent, message, wxString(SLIC3R_APP_FULL_NAME " - ") + (title.empty() ? _L("Notice") : title), wxOK | wxICON_INFORMATION);
msg_wingow.ShowModal();
}
void show_info(wxWindow* parent, const char* message, const char* title)
{
assert(message);
show_info(parent, wxString::FromUTF8(message), title ? wxString::FromUTF8(title) : wxString());
}
void warning_catcher(wxWindow* parent, const wxString& message)
{
MessageDialog msg(parent, message, _L("Warning"), wxOK | wxICON_WARNING);
msg.ShowModal();
}
static wxString bold(const wxString& str)
{
return wxString::Format("<b>%s</b>", str);
};
static wxString bold_string(const wxString& str)
{
return wxString::Format("<b>\"%s\"</b>", str);
};
static void add_config_substitutions(const ConfigSubstitutions& conf_substitutions, wxString& changes)
{
changes += "<table>";
for (const ConfigSubstitution& conf_substitution : conf_substitutions) {
wxString new_val;
const ConfigOptionDef* def = conf_substitution.opt_def;
if (!def)
continue;
switch (def->type) {
case coEnum:
{
const std::vector<std::string>& labels = def->enum_labels;
const std::vector<std::string>& values = def->enum_values;
int val = conf_substitution.new_value->getInt();
bool is_infill = def->opt_key == "top_surface_pattern" ||
def->opt_key == "bottom_surface_pattern" ||
def->opt_key == "internal_solid_infill_pattern" ||
def->opt_key == "sparse_infill_pattern";
// Each infill doesn't use all list of infill declared in PrintConfig.hpp.
// So we should "convert" val to the correct one
if (is_infill) {
for (const auto& key_val : *def->enum_keys_map)
if ((int)key_val.second == val) {
auto it = std::find(values.begin(), values.end(), key_val.first);
if (it == values.end())
break;
auto idx = it - values.begin();
new_val = wxString("\"") + values[idx] + "\"" + " (" + from_u8(_utf8(labels[idx])) + ")";
break;
}
if (new_val.IsEmpty()) {
assert(false);
new_val = _L("Undefined");
}
}
else
new_val = wxString("\"") + values[val] + "\"" + " (" + from_u8(_utf8(labels[val])) + ")";
break;
}
case coBool:
new_val = conf_substitution.new_value->getBool() ? "true" : "false";
break;
case coBools:
if (conf_substitution.new_value->nullable())
for (const char v : static_cast<const ConfigOptionBoolsNullable*>(conf_substitution.new_value.get())->values)
new_val += std::string(v == ConfigOptionBoolsNullable::nil_value() ? "nil" : v ? "true" : "false") + ", ";
else
for (const char v : static_cast<const ConfigOptionBools*>(conf_substitution.new_value.get())->values)
new_val += std::string(v ? "true" : "false") + ", ";
if (! new_val.empty())
new_val.erase(new_val.begin() + new_val.size() - 2, new_val.end());
break;
default:
assert(false);
}
changes += format_wxstr("<tr><td><b>\"%1%\" (%2%)</b></td><td>: ", def->opt_key, _(def->label)) +
format_wxstr(_L("%1% was replaced with %2%"), bold_string(conf_substitution.old_value), bold(new_val)) +
"</td></tr>";
}
changes += "</table>";
}
static wxString substitution_message(const wxString& changes)
{
return
_L("The configuration may be generated by a newer version of BambuStudio.") + " " +
_L("Some values have been replaced. Please check them:") + "\n" + changes + "\n";
}
void show_substitutions_info(const PresetsConfigSubstitutions& presets_config_substitutions)
{
wxString changes;
auto preset_type_name = [](Preset::Type type) {
switch (type) {
case Preset::TYPE_PRINT: return _L("Process");
// BBS: remove TYPE_SLA_PRINT
case Preset::TYPE_FILAMENT: return _L("Filament");
// BBS: remove TYPE_SLA_MATERIAL
case Preset::TYPE_PRINTER: return _L("Machine");
// BBS: remove TYPE_PHYSICAL_PRINTER
case Preset::TYPE_CONFIG: return _L("Configuration");
default: assert(false); return wxString();
}
};
for (const PresetConfigSubstitutions& substitution : presets_config_substitutions) {
changes += "\n\n" + format_wxstr("%1% : %2%", preset_type_name(substitution.preset_type), bold_string(substitution.preset_name));
if (!substitution.preset_file.empty())
changes += format_wxstr(" (%1%)", substitution.preset_file);
add_config_substitutions(substitution.substitutions, changes);
}
InfoDialog msg(nullptr, _L("Configuration package was loaded, but some values were not recognized."), substitution_message(changes), true);
msg.ShowModal();
}
void show_substitutions_info(const ConfigSubstitutions& config_substitutions, const std::string& filename)
{
wxString changes = "\n";
add_config_substitutions(config_substitutions, changes);
InfoDialog msg(nullptr,
format_wxstr(_L("Configuration file \"%1%\" was loaded, but some values were not recognized."), from_u8(filename)),
substitution_message(changes), true);
msg.ShowModal();
}
void create_combochecklist(wxComboCtrl* comboCtrl, const std::string& text, const std::string& items)
{
if (comboCtrl == nullptr)
return;
wxGetApp().UpdateDarkUI(comboCtrl);
wxCheckListBoxComboPopup* popup = new wxCheckListBoxComboPopup;
if (popup != nullptr) {
// FIXME If the following line is removed, the combo box popup list will not react to mouse clicks.
// On the other side, with this line the combo box popup cannot be closed by clicking on the combo button on Windows 10.
comboCtrl->UseAltPopupWindow();
int max_width = 0;
// the following line messes up the popup size the first time it is shown on wxWidgets 3.1.3
// comboCtrl->EnablePopupAnimation(false);
#ifdef _WIN32
popup->SetFont(comboCtrl->GetFont());
#endif // _WIN32
comboCtrl->SetPopupControl(popup);
wxString title = from_u8(text);
max_width = std::max(max_width, 60 + comboCtrl->GetTextExtent(title).x);
popup->SetStringValue(title);
popup->Bind(wxEVT_CHECKLISTBOX, [popup](wxCommandEvent& evt) { popup->OnCheckListBox(evt); });
popup->Bind(wxEVT_LISTBOX, [popup](wxCommandEvent& evt) { popup->OnListBoxSelection(evt); });
popup->Bind(wxEVT_KEY_DOWN, [popup](wxKeyEvent& evt) { popup->OnKeyEvent(evt); });
popup->Bind(wxEVT_KEY_UP, [popup](wxKeyEvent& evt) { popup->OnKeyEvent(evt); });
std::vector<std::string> items_str;
boost::split(items_str, items, boost::is_any_of("|"), boost::token_compress_off);
// each item must be composed by 2 parts
assert(items_str.size() %2 == 0);
for (size_t i = 0; i < items_str.size(); i += 2) {
wxString label = from_u8(items_str[i]);
max_width = std::max(max_width, 60 + popup->GetTextExtent(label).x);
popup->Append(label);
popup->Check(i / 2, items_str[i + 1] == "1");
}
comboCtrl->SetMinClientSize(wxSize(max_width, -1));
wxGetApp().UpdateDarkUI(popup);
}
}
unsigned int combochecklist_get_flags(wxComboCtrl* comboCtrl)
{
unsigned int flags = 0;
wxCheckListBoxComboPopup* popup = wxDynamicCast(comboCtrl->GetPopupControl(), wxCheckListBoxComboPopup);
if (popup != nullptr) {
for (unsigned int i = 0; i < popup->GetCount(); ++i) {
if (popup->IsChecked(i))
flags |= 1 << i;
}
}
return flags;
}
void combochecklist_set_flags(wxComboCtrl* comboCtrl, unsigned int flags)
{
wxCheckListBoxComboPopup* popup = wxDynamicCast(comboCtrl->GetPopupControl(), wxCheckListBoxComboPopup);
if (popup != nullptr) {
for (unsigned int i = 0; i < popup->GetCount(); ++i) {
popup->Check(i, (flags & (1 << i)) != 0);
}
}
}
AppConfig* get_app_config()
{
return wxGetApp().app_config;
}
wxString from_u8(const std::string &str)
{
return wxString::FromUTF8(str.c_str());
}
std::string into_u8(const wxString &str)
{
auto buffer_utf8 = str.utf8_str();
return std::string(buffer_utf8.data());
}
wxString from_path(const boost::filesystem::path &path)
{
#ifdef _WIN32
return wxString(path.string<std::wstring>());
#else
return from_u8(path.string<std::string>());
#endif
}
boost::filesystem::path into_path(const wxString &str)
{
return boost::filesystem::path(str.wx_str());
}
void about()
{
AboutDialog dlg;
dlg.ShowModal();
}
void login()
{
//LoginDialog dlg;
//dlg.ShowModal();
ZUserLogin dlg;
dlg.run();
}
void desktop_open_datadir_folder()
{
// Execute command to open a file explorer, platform dependent.
// FIXME: The const_casts aren't needed in wxWidgets 3.1, remove them when we upgrade.
const auto path = data_dir();
#ifdef _WIN32
const wxString widepath = from_u8(path);
const wchar_t *argv[] = { L"explorer", widepath.GetData(), nullptr };
::wxExecute(const_cast<wchar_t**>(argv), wxEXEC_ASYNC, nullptr);
#elif __APPLE__
const char *argv[] = { "open", path.data(), nullptr };
::wxExecute(const_cast<char**>(argv), wxEXEC_ASYNC, nullptr);
#else
const char *argv[] = { "xdg-open", path.data(), nullptr };
// Check if we're running in an AppImage container, if so, we need to remove AppImage's env vars,
// because they may mess up the environment expected by the file manager.
// Mostly this is about LD_LIBRARY_PATH, but we remove a few more too for good measure.
if (wxGetEnv("APPIMAGE", nullptr)) {
// We're running from AppImage
wxEnvVariableHashMap env_vars;
wxGetEnvMap(&env_vars);
env_vars.erase("APPIMAGE");
env_vars.erase("APPDIR");
env_vars.erase("LD_LIBRARY_PATH");
env_vars.erase("LD_PRELOAD");
env_vars.erase("UNION_PRELOAD");
wxExecuteEnv exec_env;
exec_env.env = std::move(env_vars);
wxString owd;
if (wxGetEnv("OWD", &owd)) {
// This is the original work directory from which the AppImage image was run,
// set it as CWD for the child process:
exec_env.cwd = std::move(owd);
}
::wxExecute(const_cast<char**>(argv), wxEXEC_ASYNC, nullptr, &exec_env);
} else {
// Looks like we're NOT running from AppImage, we'll make no changes to the environment.
::wxExecute(const_cast<char**>(argv), wxEXEC_ASYNC, nullptr, nullptr);
}
#endif
}
void desktop_open_any_folder( const std::string path )
{
// Execute command to open a file explorer, platform dependent.
// FIXME: The const_casts aren't needed in wxWidgets 3.1, remove them when we upgrade.
#ifdef _WIN32
const wxString widepath = from_u8(path);
::wxExecute(L"explorer /select," + widepath, wxEXEC_ASYNC, nullptr);
#elif __APPLE__
openFolderForFile(from_u8(path));
#else
const char *argv[] = {"nautilus", path.data(), nullptr};
// Check if we're running in an AppImage container, if so, we need to remove AppImage's env vars,
// because they may mess up the environment expected by the file manager.
// Mostly this is about LD_LIBRARY_PATH, but we remove a few more too for good measure.
if (wxGetEnv("APPIMAGE", nullptr)) {
// We're running from AppImage
wxEnvVariableHashMap env_vars;
wxGetEnvMap(&env_vars);
env_vars.erase("APPIMAGE");
env_vars.erase("APPDIR");
env_vars.erase("LD_LIBRARY_PATH");
env_vars.erase("LD_PRELOAD");
env_vars.erase("UNION_PRELOAD");
wxExecuteEnv exec_env;
exec_env.env = std::move(env_vars);
wxString owd;
if (wxGetEnv("OWD", &owd)) {
// This is the original work directory from which the AppImage image was run,
// set it as CWD for the child process:
exec_env.cwd = std::move(owd);
}
::wxExecute(const_cast<char **>(argv), wxEXEC_ASYNC, nullptr, &exec_env);
} else {
// Looks like we're NOT running from AppImage, we'll make no changes to the environment.
::wxExecute(const_cast<char **>(argv), wxEXEC_ASYNC, nullptr, nullptr);
}
#endif
}
} }

6999
src/slic3r/GUI/GUI_App.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -950,7 +950,7 @@ void MainFrame::update_title()
void MainFrame::show_publish_button(bool show)
{
m_publish_btn->Show(show);
//m_publish_btn->Show(show);
Layout();
}
@ -1308,6 +1308,7 @@ void MainFrame::create_preset_tabs()
//add_created_tab(new TabSLAPrint(m_param_panel));
//add_created_tab(new TabSLAMaterial(m_param_panel));
add_created_tab(new TabPrinter(m_param_dialog->panel()), "printer");
//add_created_tab(new TabConfig(m_param_dialog->panel()), "config");
m_param_panel->rebuild_panels();
m_param_dialog->panel()->rebuild_panels();
@ -1571,7 +1572,7 @@ wxBoxSizer* MainFrame::create_side_tools()
m_publish_btn->Hide();
m_slice_option_btn->Enable();
m_print_option_btn->Enable();
sizer->Add(m_publish_btn, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, FromDIP(1));
//sizer->Add(m_publish_btn, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, FromDIP(1));
sizer->Add(FromDIP(15), 0, 0, 0, 0);
sizer->Add(m_slice_option_btn, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, FromDIP(1));
sizer->Add(m_slice_btn, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, FromDIP(1));
@ -1651,19 +1652,19 @@ wxBoxSizer* MainFrame::create_side_tools()
m_slice_option_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event)
{
SidePopup* p = new SidePopup(this);
SideButton* slice_all_btn = new SideButton(p, _L("Slice all"), "");
slice_all_btn->SetCornerRadius(0);
//SideButton* slice_all_btn = new SideButton(p, _L("Slice all"), "");
//slice_all_btn->SetCornerRadius(0);
SideButton* slice_plate_btn = new SideButton(p, _L("Slice plate"), "");
slice_plate_btn->SetCornerRadius(0);
slice_all_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) {
/* slice_all_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) {
m_slice_btn->SetLabel(_L("Slice all"));
m_slice_select = eSliceAll;
m_slice_enable = get_enable_slice_status();
m_slice_btn->Enable(m_slice_enable);
this->Layout();
p->Dismiss();
});
});*/
slice_plate_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) {
m_slice_btn->SetLabel(_L("Slice plate"));
@ -1673,7 +1674,8 @@ wxBoxSizer* MainFrame::create_side_tools()
this->Layout();
p->Dismiss();
});
p->append_button(slice_all_btn);
//xiamian-
//p->append_button(slice_all_btn);
p->append_button(slice_plate_btn);
p->Popup(m_slice_btn);
}
@ -1727,28 +1729,29 @@ wxBoxSizer* MainFrame::create_side_tools()
}
else {
//Bambu Studio Buttons
SideButton* print_plate_btn = new SideButton(p, _L("Print plate"), "");
print_plate_btn->SetCornerRadius(0);
//xiamian-
//SideButton* print_plate_btn = new SideButton(p, _L("Print plate"), "");
//print_plate_btn->SetCornerRadius(0);
SideButton* send_to_printer_btn = new SideButton(p, _L("Send"), "");
send_to_printer_btn->SetCornerRadius(0);
//SideButton* send_to_printer_btn = new SideButton(p, _L("Send"), "");
//send_to_printer_btn->SetCornerRadius(0);
SideButton* export_sliced_file_btn = new SideButton(p, _L("Export plate sliced file"), "");
export_sliced_file_btn->SetCornerRadius(0);
SideButton* export_all_sliced_file_btn = new SideButton(p, _L("Export all sliced file"), "");
export_all_sliced_file_btn->SetCornerRadius(0);
/* SideButton* export_all_sliced_file_btn = new SideButton(p, _L("Export all sliced file"), "");
export_all_sliced_file_btn->SetCornerRadius(0);*/
print_plate_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) {
/* print_plate_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) {
m_print_btn->SetLabel(_L("Print plate"));
m_print_select = ePrintPlate;
m_print_enable = get_enable_print_status();
m_print_btn->Enable(m_print_enable);
this->Layout();
p->Dismiss();
});
});*/
SideButton* print_all_btn = new SideButton(p, _L("Print all"), "");
/* SideButton* print_all_btn = new SideButton(p, _L("Print all"), "");
print_all_btn->SetCornerRadius(0);
print_all_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) {
m_print_btn->SetLabel(_L("Print all"));
@ -1757,18 +1760,18 @@ wxBoxSizer* MainFrame::create_side_tools()
m_print_btn->Enable(m_print_enable);
this->Layout();
p->Dismiss();
});
});*/
send_to_printer_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) {
/* send_to_printer_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) {
m_print_btn->SetLabel(_L("Send"));
m_print_select = eSendToPrinter;
m_print_enable = get_enable_print_status();
m_print_btn->Enable(m_print_enable);
this->Layout();
p->Dismiss();
});
});*/
SideButton* send_to_printer_all_btn = new SideButton(p, _L("Send all"), "");
/* SideButton* send_to_printer_all_btn = new SideButton(p, _L("Send all"), "");
send_to_printer_all_btn->SetCornerRadius(0);
send_to_printer_all_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) {
m_print_btn->SetLabel(_L("Send all"));
@ -1777,7 +1780,7 @@ wxBoxSizer* MainFrame::create_side_tools()
m_print_btn->Enable(m_print_enable);
this->Layout();
p->Dismiss();
});
});*/
export_sliced_file_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) {
m_print_btn->SetLabel(_L("Export plate sliced file"));
@ -1788,22 +1791,22 @@ wxBoxSizer* MainFrame::create_side_tools()
p->Dismiss();
});
export_all_sliced_file_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) {
/* export_all_sliced_file_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) {
m_print_btn->SetLabel(_L("Export all sliced file"));
m_print_select = eExportAllSlicedFile;
m_print_enable = get_enable_print_status();
m_print_btn->Enable(m_print_enable);
this->Layout();
p->Dismiss();
});
});*/
p->append_button(print_plate_btn);
p->append_button(print_all_btn);
p->append_button(send_to_printer_btn);
p->append_button(send_to_printer_all_btn);
//p->append_button(print_plate_btn);
//p->append_button(print_all_btn);
//p->append_button(send_to_printer_btn);
//p->append_button(send_to_printer_all_btn);
p->append_button(export_sliced_file_btn);
p->append_button(export_all_sliced_file_btn);
if (enable_multi_machine) {
//p->append_button(export_all_sliced_file_btn);
/*if (enable_multi_machine) {
SideButton* print_multi_machine_btn = new SideButton(p, _L("Send to Multi-device"), "");
print_multi_machine_btn->SetCornerRadius(0);
print_multi_machine_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) {
@ -1815,7 +1818,7 @@ wxBoxSizer* MainFrame::create_side_tools()
p->Dismiss();
});
p->append_button(print_multi_machine_btn);
}
}*/
}
p->Popup(m_print_btn);
@ -3815,6 +3818,7 @@ void MainFrame::update_side_preset_ui()
//BBS: update the preset
m_plater->sidebar().update_presets(Preset::TYPE_PRINTER);
m_plater->sidebar().update_presets(Preset::TYPE_FILAMENT);
//m_plater->sidebar().update_presets(Preset::TYPE_CONFIG);
//take off multi machine

View File

@ -0,0 +1,836 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.0-4761b0c)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "libslic3r/PresetBundle.hpp"
#include "libslic3r/Preset.hpp"
#include "ParamsPanel.hpp"
#include "Tab.hpp"
#include "format.hpp"
#include "MainFrame.hpp"
#include "GUI_App.hpp"
#include "Plater.hpp"
#include "Widgets/Label.hpp"
#include "Widgets/SwitchButton.hpp"
#include "Widgets/Button.hpp"
#include "GUI_Factories.hpp"
namespace Slic3r {
namespace GUI {
TipsDialog::TipsDialog(wxWindow *parent, const wxString &title, const wxString &description, std::string app_key)
: DPIDialog(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX),
m_app_key(app_key)
{
SetBackgroundColour(*wxWHITE);
std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str();
SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO));
wxBoxSizer *m_sizer_main = new wxBoxSizer(wxVERTICAL);
m_top_line = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
m_top_line->SetBackgroundColour(wxColour(166, 169, 170));
m_sizer_main->Add(m_top_line, 0, wxEXPAND, 0);
m_sizer_main->Add(0, 0, 0, wxEXPAND | wxTOP, FromDIP(20));
m_msg = new wxStaticText(this, wxID_ANY, description, wxDefaultPosition, wxDefaultSize, 0);
m_msg->Wrap(-1);
m_msg->SetFont(::Label::Body_13);
m_msg->SetForegroundColour(wxColour(107, 107, 107));
m_msg->SetBackgroundColour(wxColour(255, 255, 255));
m_sizer_main->Add(m_msg, 1, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(40));
m_sizer_main->Add(0, 0, 0, wxEXPAND | wxTOP, FromDIP(5));
wxBoxSizer *m_sizer_bottom = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *m_sizer_left = new wxBoxSizer(wxHORIZONTAL);
auto dont_show_again = create_item_checkbox(_L("Don't show again"), this, _L("Don't show again"), "do_not_show_tips");
m_sizer_left->Add(dont_show_again, 1, wxALL, FromDIP(5));
m_sizer_bottom->Add(m_sizer_left, 1, wxEXPAND, FromDIP(5));
wxBoxSizer *m_sizer_right = new wxBoxSizer(wxHORIZONTAL);
m_confirm = new Button(this, _L("OK"));
StateColor btn_bg_green(std::pair<wxColour, int>(wxColour(27, 136, 68), StateColor::Pressed), std::pair<wxColour, int>(wxColour(61, 203, 115), StateColor::Hovered),
std::pair<wxColour, int>(wxColour(0, 174, 66), StateColor::Normal));
m_confirm->SetBackgroundColor(btn_bg_green);
m_confirm->SetBorderColor(wxColour(0, 174, 66));
m_confirm->SetTextColor(wxColour(255, 255, 255));
m_confirm->SetSize(TIPS_DIALOG_BUTTON_SIZE);
m_confirm->SetMinSize(TIPS_DIALOG_BUTTON_SIZE);
m_confirm->SetCornerRadius(FromDIP(12));
m_confirm->Bind(wxEVT_LEFT_DOWN, &TipsDialog::on_ok, this);
m_sizer_right->Add(m_confirm, 0, wxALL, FromDIP(5));
m_sizer_bottom->Add(m_sizer_right, 0, wxEXPAND, FromDIP(5));
m_sizer_main->Add(m_sizer_bottom, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(40));
m_sizer_main->Add(0, 0, 0, wxEXPAND | wxTOP, FromDIP(20));
SetSizer(m_sizer_main);
Layout();
Fit();
Centre(wxBOTH);
wxGetApp().UpdateDlgDarkUI(this);
}
wxBoxSizer *TipsDialog::create_item_checkbox(wxString title, wxWindow *parent, wxString tooltip, std::string param)
{
wxBoxSizer *m_sizer_checkbox = new wxBoxSizer(wxHORIZONTAL);
m_sizer_checkbox->Add(0, 0, 0, wxEXPAND | wxLEFT, 5);
auto checkbox = new ::CheckBox(parent);
m_sizer_checkbox->Add(checkbox, 0, wxALIGN_CENTER, 0);
m_sizer_checkbox->Add(0, 0, 0, wxEXPAND | wxLEFT, 8);
auto checkbox_title = new wxStaticText(parent, wxID_ANY, title, wxDefaultPosition, wxSize(-1, -1), 0);
checkbox_title->SetForegroundColour(wxColour(144, 144, 144));
checkbox_title->SetFont(::Label::Body_13);
checkbox_title->Wrap(-1);
m_sizer_checkbox->Add(checkbox_title, 0, wxALIGN_CENTER | wxALL, 3);
m_show_again = wxGetApp().app_config->get(param) == "true" ? true : false;
checkbox->SetValue(m_show_again);
checkbox->Bind(wxEVT_TOGGLEBUTTON, [this, checkbox, param](wxCommandEvent &e) {
m_show_again = m_show_again ? false : true;
e.Skip();
});
return m_sizer_checkbox;
}
void TipsDialog::on_dpi_changed(const wxRect &suggested_rect)
{
if (m_confirm) m_confirm->SetMinSize(TIPS_DIALOG_BUTTON_SIZE);
if (m_cancel) m_cancel->SetMinSize(TIPS_DIALOG_BUTTON_SIZE);
Fit();
Refresh();
}
void TipsDialog::on_ok(wxMouseEvent &event)
{
if (m_show_again) {
if (!m_app_key.empty())
wxGetApp().app_config->set_bool(m_app_key, m_show_again);
}
EndModal(wxID_OK);
}
void ParamsPanel::Highlighter::set_timer_owner(wxEvtHandler *owner, int timerid /* = wxID_ANY*/)
{
m_timer.SetOwner(owner, timerid);
}
void ParamsPanel::Highlighter::init(std::pair<wxWindow *, bool *> params, wxWindow *parent)
{
if (m_timer.IsRunning()) invalidate();
if (!params.first || !params.second) return;
m_timer.Start(300, false);
m_bitmap = params.first;
m_show_blink_ptr = params.second;
m_parent = parent;
*m_show_blink_ptr = true;
}
void ParamsPanel::Highlighter::invalidate()
{
m_timer.Stop();
if (m_bitmap && m_show_blink_ptr) {
*m_show_blink_ptr = false;
m_bitmap->Show(*m_show_blink_ptr);
if (m_parent) {
m_parent->Layout();
m_parent->Refresh();
}
m_show_blink_ptr = nullptr;
m_bitmap = nullptr;
m_parent = nullptr;
}
m_blink_counter = 0;
}
void ParamsPanel::Highlighter::blink()
{
if (m_bitmap && m_show_blink_ptr) {
*m_show_blink_ptr = !*m_show_blink_ptr;
m_bitmap->Show(*m_show_blink_ptr);
if (m_parent) {
m_parent->Layout();
m_parent->Refresh();
}
} else
return;
if ((++m_blink_counter) == 11) invalidate();
}
ParamsPanel::ParamsPanel( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name )
: wxPanel( parent, id, pos, size, style, name )
{
// BBS: new layout
SetBackgroundColour(*wxWHITE);
#if __WXOSX__
m_top_sizer = new wxBoxSizer(wxHORIZONTAL);
m_top_sizer->SetSizeHints(this);
this->SetSizer(m_top_sizer);
// Create additional panel to Fit() it from OnActivate()
// It's needed for tooltip showing on OSX
m_tmp_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL);
auto sizer = new wxBoxSizer(wxHORIZONTAL);
m_tmp_panel->SetSizer(sizer);
m_tmp_panel->Layout();
#else
ParamsPanel*panel = this;
m_top_sizer = new wxBoxSizer(wxHORIZONTAL);
m_top_sizer->SetSizeHints(panel);
panel->SetSizer(m_top_sizer);
#endif //__WXOSX__
if (dynamic_cast<Notebook*>(parent)) {
// BBS: new layout
m_top_panel = new StaticBox(this, wxID_ANY, wxDefaultPosition);
m_top_panel->SetBackgroundColor(0xF8F8F8);
m_top_panel->SetBackgroundColor2(0xF1F1F1);
m_process_icon = new ScalableButton(m_top_panel, wxID_ANY, "process");
m_process_icon->Hide();
m_title_label = new Label(m_top_panel, _L("Process"));
m_title_label->Hide();
//int width, height;
// BBS: new layout
m_mode_region = new SwitchButton(m_top_panel);
m_mode_region->SetMaxSize({em_unit(this) * 12, -1});
m_mode_region->SetLabels(_L("Global"), _L("Objects"));
//m_mode_region->Hide();
//m_mode_region->GetSize(&width, &height);
m_tips_arrow = new ScalableButton(m_top_panel, wxID_ANY, "tips_arrow");
m_tips_arrow->Hide();
m_title_view = new Label(m_top_panel, _L("Advance"));
m_mode_view = new SwitchButton(m_top_panel, wxID_ABOUT);
m_title_view->Hide();
m_mode_view->Hide();
// BBS: new layout
//m_search_btn = new ScalableButton(m_top_panel, wxID_ANY, "search", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, true);
//m_search_btn->SetToolTip(format_wxstr(_L("Search in settings [%1%]"), "Ctrl+F"));
//m_search_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { wxGetApp().plater()->search(false); });
m_compare_btn = new ScalableButton(m_top_panel, wxID_ANY, "compare", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, true);
m_compare_btn->SetToolTip(_L("Compare presets"));
m_compare_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { wxGetApp().mainframe->diff_dialog.show(); }));
m_compare_btn->Hide();
m_setting_btn = new ScalableButton(m_top_panel, wxID_ANY, "table", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, true);
m_setting_btn->SetToolTip(_L("View all object's settings"));
m_setting_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { wxGetApp().plater()->PopupObjectTable(-1, -1, {0, 0}); });
m_setting_btn->Hide();
m_highlighter.set_timer_owner(this, 0);
this->Bind(wxEVT_TIMER, [this](wxTimerEvent &)
{
m_highlighter.blink();
});
}
//m_export_to_file = new Button( this, wxT("Export To File"), "");
//m_import_from_file = new Button( this, wxT("Import From File") );
// Initialize the page.
#if __WXOSX__
auto page_parent = m_tmp_panel;
#else
auto page_parent = this;
#endif
// BBS: fix scroll to tip view
class PageScrolledWindow : public wxScrolledWindow
{
public:
PageScrolledWindow(wxWindow *parent)
: wxScrolledWindow(parent,
wxID_ANY,
wxDefaultPosition,
wxDefaultSize,
wxVSCROLL) // hide hori-bar will cause hidden field mis-position
{
// ShowScrollBar(GetHandle(), SB_BOTH, FALSE);
Bind(wxEVT_SCROLL_CHANGED, [this](auto &e) {
wxWindow *child = dynamic_cast<wxWindow *>(e.GetEventObject());
if (child != this)
EnsureVisible(child);
});
}
virtual bool ShouldScrollToChildOnFocus(wxWindow *child)
{
EnsureVisible(child);
return false;
}
void EnsureVisible(wxWindow* win)
{
const wxRect viewRect(m_targetWindow->GetClientRect());
const wxRect winRect(m_targetWindow->ScreenToClient(win->GetScreenPosition()), win->GetSize());
if (viewRect.Contains(winRect)) {
return;
}
if (winRect.GetWidth() > viewRect.GetWidth() || winRect.GetHeight() > viewRect.GetHeight()) {
return;
}
int stepx, stepy;
GetScrollPixelsPerUnit(&stepx, &stepy);
int startx, starty;
GetViewStart(&startx, &starty);
// first in vertical direction:
if (stepy > 0) {
int diff = 0;
if (winRect.GetTop() < 0) {
diff = winRect.GetTop();
} else if (winRect.GetBottom() > viewRect.GetHeight()) {
diff = winRect.GetBottom() - viewRect.GetHeight() + 1;
// round up to next scroll step if we can't get exact position,
// so that the window is fully visible:
diff += stepy - 1;
}
starty = (starty * stepy + diff) / stepy;
}
// then horizontal:
if (stepx > 0) {
int diff = 0;
if (winRect.GetLeft() < 0) {
diff = winRect.GetLeft();
} else if (winRect.GetRight() > viewRect.GetWidth()) {
diff = winRect.GetRight() - viewRect.GetWidth() + 1;
// round up to next scroll step if we can't get exact position,
// so that the window is fully visible:
diff += stepx - 1;
}
startx = (startx * stepx + diff) / stepx;
}
Scroll(startx, starty);
}
};
m_page_view = new PageScrolledWindow(page_parent);
m_page_view->SetBackgroundColour(*wxWHITE);
m_page_sizer = new wxBoxSizer(wxVERTICAL);
m_page_view->SetSizer(m_page_sizer);
m_page_view->SetScrollbars(1, 20, 1, 2);
//m_page_view->SetScrollRate( 5, 5 );
if (m_mode_region)
m_mode_region->Bind(wxEVT_TOGGLEBUTTON, &ParamsPanel::OnToggled, this);
if (m_mode_view)
m_mode_view->Bind(wxEVT_TOGGLEBUTTON, &ParamsPanel::OnToggled, this);
Bind(wxEVT_TOGGLEBUTTON, &ParamsPanel::OnToggled, this); // For Tab's mode switch
//Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { wxGetApp().plater()->search(false); }, wxID_FIND);
//m_export_to_file->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { wxGetApp().mainframe->export_config(); });
//m_import_from_file->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { wxGetApp().mainframe->load_config_file(); });
}
void ParamsPanel::create_layout()
{
#ifdef __WINDOWS__
this->SetDoubleBuffered(true);
m_page_view->SetDoubleBuffered(true);
#endif //__WINDOWS__
m_left_sizer = new wxBoxSizer( wxVERTICAL );
// BBS: new layout
m_left_sizer->SetMinSize( wxSize(40 * em_unit(this), -1 ) );
if (m_top_panel) {
m_mode_sizer = new wxBoxSizer( wxHORIZONTAL );
m_mode_sizer->AddSpacer(FromDIP(11));
//m_mode_sizer->Add(m_process_icon, 0, wxALIGN_CENTER);
//m_mode_sizer->AddSpacer(FromDIP(11));
//m_mode_sizer->Add( m_title_label, 0, wxALIGN_CENTER );
//m_mode_sizer->AddStretchSpacer(2);
m_mode_sizer->Add(m_mode_region, 0, wxALIGN_CENTER);
m_mode_sizer->AddStretchSpacer(1);
//m_mode_sizer->Add(m_tips_arrow, 0, wxALIGN_CENTER);
// m_mode_sizer->AddStretchSpacer(8);
//m_mode_sizer->Add( m_title_view, 0, wxALIGN_CENTER );
//m_mode_sizer->AddSpacer(FromDIP(2));
//m_mode_sizer->Add(m_mode_view, 0, wxALIGN_CENTER);
//m_mode_sizer->AddStretchSpacer(2);
//m_mode_sizer->Add(m_setting_btn, 0, wxALIGN_CENTER);
//m_mode_sizer->AddSpacer(FromDIP(2));
//m_mode_sizer->Add(m_compare_btn, 0, wxALIGN_CENTER);
m_mode_sizer->AddSpacer(FromDIP(8));
//m_mode_sizer->Add( m_search_btn, 0, wxALIGN_CENTER );
//m_mode_sizer->AddSpacer(16);
m_mode_sizer->SetMinSize(-1, FromDIP(30));
m_top_panel->SetSizer(m_mode_sizer);
//m_left_sizer->Add( m_top_panel, 0, wxEXPAND );
}
if (m_tab_print) {
//m_print_sizer = new wxBoxSizer( wxHORIZONTAL );
//m_print_sizer->Add( m_tab_print, 1, wxEXPAND | wxALL, 5 );
//m_left_sizer->Add( m_print_sizer, 1, wxEXPAND, 5 );
m_left_sizer->Add( m_tab_print, 0, wxEXPAND );
}
if (m_tab_print_plate) {
m_left_sizer->Add(m_tab_print_plate, 0, wxEXPAND);
}
if (m_tab_print_object) {
m_left_sizer->Add( m_tab_print_object, 0, wxEXPAND );
}
if (m_tab_print_part) {
m_left_sizer->Add( m_tab_print_part, 0, wxEXPAND );
}
if (m_tab_print_layer) {
m_left_sizer->Add(m_tab_print_layer, 0, wxEXPAND);
}
if (m_tab_filament) {
//m_filament_sizer = new wxBoxSizer( wxVERTICAL );
//m_filament_sizer->Add( m_tab_filament, 1, wxEXPAND | wxALL, 5 );
// m_left_sizer->Add( m_filament_sizer, 1, wxEXPAND, 5 );
m_left_sizer->Add( m_tab_filament, 0, wxEXPAND );
}
if (m_tab_printer) {
//m_printer_sizer = new wxBoxSizer( wxVERTICAL );
//m_printer_sizer->Add( m_tab_printer, 1, wxEXPAND | wxALL, 5 );
m_left_sizer->Add( m_tab_printer, 0, wxEXPAND );
}
//m_left_sizer->Add( m_printer_sizer, 1, wxEXPAND, 1 );
//m_button_sizer = new wxBoxSizer( wxHORIZONTAL );
//m_button_sizer->Add( m_export_to_file, 0, wxALL, 5 );
//m_button_sizer->Add( m_import_from_file, 0, wxALL, 5 );
//m_left_sizer->Add( m_button_sizer, 0, wxALIGN_CENTER, 5 );
m_top_sizer->Add(m_left_sizer, 1, wxEXPAND);
//m_right_sizer = new wxBoxSizer( wxVERTICAL );
//m_right_sizer->Add( m_page_view, 1, wxEXPAND | wxALL, 5 );
//m_top_sizer->Add( m_right_sizer, 1, wxEXPAND, 5 );
// BBS: new layout
m_left_sizer->AddSpacer(6 * em_unit(this) / 10);
#if __WXOSX__
m_left_sizer->Add(m_tmp_panel, 1, wxEXPAND | wxALL, 0);
m_tmp_panel->GetSizer()->Add( m_page_view, 1, wxEXPAND );
#else
m_left_sizer->Add( m_page_view, 1, wxEXPAND );
#endif
//this->SetSizer( m_top_sizer );
this->Layout();
}
void ParamsPanel::rebuild_panels()
{
refresh_tabs();
free_sizers();
create_layout();
}
void ParamsPanel::refresh_tabs()
{
auto& tabs_list = wxGetApp().tabs_list;
auto print_tech = wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology();
for (auto tab : tabs_list)
if (tab->supports_printer_technology(print_tech))
{
if (tab->GetParent() != this) continue;
switch (tab->type())
{
case Preset::TYPE_PRINT:
case Preset::TYPE_SLA_PRINT:
m_tab_print = tab;
break;
case Preset::TYPE_FILAMENT:
case Preset::TYPE_SLA_MATERIAL:
m_tab_filament = tab;
break;
case Preset::TYPE_PRINTER:
m_tab_printer = tab;
break;
default:
break;
}
}
if (m_top_panel) {
m_tab_print_plate = wxGetApp().get_plate_tab();
m_tab_print_object = wxGetApp().get_model_tab();
m_tab_print_part = wxGetApp().get_model_tab(true);
m_tab_print_layer = wxGetApp().get_layer_tab();
}
return;
}
void ParamsPanel::clear_page()
{
if (m_page_sizer)
m_page_sizer->Clear(true);
}
void ParamsPanel::OnActivate()
{
if (m_current_tab == NULL)
{
//the first time
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": first time opened, set current tab to print");
// BBS: open/close tab
//m_current_tab = m_tab_print;
set_active_tab(m_tab_print ? m_tab_print : m_tab_filament);
}
Tab* cur_tab = dynamic_cast<Tab *> (m_current_tab);
if (cur_tab)
cur_tab->OnActivate();
}
void ParamsPanel::OnToggled(wxCommandEvent& event)
{
if (m_mode_region && m_mode_region->GetId() == event.GetId()) {
wxWindowUpdateLocker locker(GetParent());
set_active_tab(nullptr);
event.Skip();
return;
}
if (wxID_ABOUT != event.GetId()) {
return;
}
// this is from tab's mode switch
bool value = dynamic_cast<SwitchButton*>(event.GetEventObject())->GetValue();
int mode_id;
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": Advanced mode toogle to %1%") % value;
if (value)
{
//m_mode_region->SetBitmap(m_toggle_on_icon);
mode_id = comAdvanced;
}
else
{
//m_mode_region->SetBitmap(m_toggle_off_icon);
mode_id = comSimple;
}
Slic3r::GUI::wxGetApp().save_mode(mode_id);
}
// This is special, DO NOT call it from outer except from Tab
void ParamsPanel::set_active_tab(wxPanel* tab)
{
Tab* cur_tab = dynamic_cast<Tab *> (tab);
if (cur_tab == nullptr) {
if (!m_mode_region->GetValue()) {
cur_tab = (Tab*) m_tab_print;
} else if (m_tab_print_part && ((TabPrintModel*) m_tab_print_part)->has_model_config()) {
cur_tab = (Tab*) m_tab_print_part;
} else if (m_tab_print_layer && ((TabPrintModel*)m_tab_print_layer)->has_model_config()) {
cur_tab = (Tab*)m_tab_print_layer;
} else if (m_tab_print_object && ((TabPrintModel*) m_tab_print_object)->has_model_config()) {
cur_tab = (Tab*) m_tab_print_object;
} else if (m_tab_print_plate && ((TabPrintPlate*)m_tab_print_plate)->has_model_config()) {
cur_tab = (Tab*)m_tab_print_plate;
}
Show(cur_tab != nullptr);
wxGetApp().sidebar().show_object_list(m_mode_region->GetValue());
if (m_current_tab == cur_tab)
return;
if (cur_tab)
cur_tab->restore_last_select_item();
return;
}
m_current_tab = tab;
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": set current to %1%, type=%2%") % cur_tab % cur_tab?cur_tab->type():-1;
update_mode();
// BBS: open/close tab
for (auto t : std::vector<std::pair<wxPanel*, wxStaticLine*>>({
{m_tab_print, m_staticline_print},
{m_tab_print_object, m_staticline_print_object},
{m_tab_print_part, m_staticline_print_part},
{m_tab_print_layer, nullptr},
{m_tab_print_plate, nullptr},
{m_tab_filament, m_staticline_filament},
{m_tab_printer, m_staticline_printer}})) {
if (!t.first) continue;
t.first->Show(tab == t.first);
if (!t.second) continue;
t.second->Show(tab == t.first);
//m_left_sizer->GetItem(t)->SetProportion(tab == t ? 1 : 0);
}
m_left_sizer->Layout();
if (auto dialog = dynamic_cast<wxDialog*>(GetParent())) {
//"Configuration settings"
wxString title;
if (cur_tab->type() == Preset::TYPE_FILAMENT) {
title = _L("Filament settings");
}else if (cur_tab->type() == Preset::TYPE_PRINTER) {
title = _L("Printer settings");
} else {
title = _L("Configuration settings");
}
//wxString title = cur_tab->type() == Preset::TYPE_FILAMENT ? _L("Filament settings") : _L("Printer settings");
dialog->SetTitle(title);
}
}
bool ParamsPanel::is_active_and_shown_tab(wxPanel* tab)
{
if (m_current_tab == tab)
return true;
else
return false;
}
void ParamsPanel::update_mode()
{
int app_mode = Slic3r::GUI::wxGetApp().get_mode();
SwitchButton * mode_view = m_current_tab ? dynamic_cast<Tab*>(m_current_tab)->m_mode_view : nullptr;
if (mode_view == nullptr) mode_view = m_mode_view;
if (mode_view == nullptr) return;
//BBS: disable the mode tab and return directly when enable develop mode
if (app_mode == comDevelop)
{
mode_view->Disable();
return;
}
if (!mode_view->IsEnabled())
mode_view->Enable();
if (app_mode == comAdvanced)
{
mode_view->SetValue(true);
}
else
{
mode_view->SetValue(false);
}
}
void ParamsPanel::msw_rescale()
{
if (m_process_icon) m_process_icon->msw_rescale();
if (m_setting_btn) m_setting_btn->msw_rescale();
if (m_search_btn) m_search_btn->msw_rescale();
if (m_compare_btn) m_compare_btn->msw_rescale();
if (m_tips_arrow) m_tips_arrow->msw_rescale();
if (m_left_sizer) m_left_sizer->SetMinSize(wxSize(40 * em_unit(this), -1));
if (m_mode_sizer)
m_mode_sizer->SetMinSize(-1, 3 * em_unit(this));
if (m_mode_region)
((SwitchButton* )m_mode_region)->Rescale();
if (m_mode_view)
((SwitchButton* )m_mode_view)->Rescale();
for (auto tab : {m_tab_print, m_tab_print_plate, m_tab_print_object, m_tab_print_part, m_tab_print_layer, m_tab_filament, m_tab_printer}) {
if (tab) dynamic_cast<Tab*>(tab)->msw_rescale();
}
//((Button*)m_export_to_file)->Rescale();
//((Button*)m_import_from_file)->Rescale();
}
void ParamsPanel::switch_to_global()
{
m_mode_region->SetValue(false);
set_active_tab(nullptr);
}
void ParamsPanel::switch_to_object(bool with_tips)
{
m_mode_region->SetValue(true);
set_active_tab(nullptr);
if (with_tips) {
m_highlighter.init(std::pair(m_tips_arrow, &m_tips_arror_blink), m_top_panel);
m_highlighter.blink();
}
}
void ParamsPanel::notify_object_config_changed()
{
auto & model = wxGetApp().model();
bool has_config = false;
for (auto obj : model.objects) {
if (!obj->config.empty()) {
SettingsFactory::Bundle cat_options = SettingsFactory::get_bundle(&obj->config.get(), true);
if (cat_options.size() > 0) {
has_config = true;
break;
}
}
for (auto volume : obj->volumes) {
if (!volume->config.empty()) {
SettingsFactory::Bundle cat_options = SettingsFactory::get_bundle(&volume->config.get(), true);
if (cat_options.size() > 0) {
has_config = true;
break;
}
}
}
if (has_config) break;
}
if (has_config == m_has_object_config) return;
m_has_object_config = has_config;
if (has_config)
m_mode_region->SetTextColor2(StateColor(std::pair{0xfffffe, (int) StateColor::Checked}, std::pair{wxGetApp().get_label_clr_modified(), 0}));
else
m_mode_region->SetTextColor2(StateColor());
m_mode_region->Rescale();
}
void ParamsPanel::switch_to_object_if_has_object_configs()
{
if (m_has_object_config)
m_mode_region->SetValue(true);
set_active_tab(nullptr);
}
void ParamsPanel::free_sizers()
{
if (m_top_sizer)
{
m_top_sizer->Clear(false);
//m_top_sizer = nullptr;
}
m_left_sizer = nullptr;
//m_right_sizer = nullptr;
m_mode_sizer = nullptr;
//m_print_sizer = nullptr;
//m_filament_sizer = nullptr;
//m_printer_sizer = nullptr;
m_button_sizer = nullptr;
}
void ParamsPanel::delete_subwindows()
{
if (m_title_label)
{
delete m_title_label;
m_title_label = nullptr;
}
if (m_mode_region)
{
delete m_mode_region;
m_mode_region = nullptr;
}
if (m_mode_view)
{
delete m_mode_view;
m_mode_view = nullptr;
}
if (m_title_view)
{
delete m_title_view;
m_title_view = nullptr;
}
if (m_search_btn)
{
delete m_search_btn;
m_search_btn = nullptr;
}
if (m_staticline_print)
{
delete m_staticline_print;
m_staticline_print = nullptr;
}
if (m_staticline_print_part)
{
delete m_staticline_print_part;
m_staticline_print_part = nullptr;
}
if (m_staticline_print_object)
{
delete m_staticline_print_object;
m_staticline_print_object = nullptr;
}
if (m_staticline_filament)
{
delete m_staticline_filament;
m_staticline_filament = nullptr;
}
if (m_staticline_printer)
{
delete m_staticline_printer;
m_staticline_printer = nullptr;
}
if (m_export_to_file)
{
delete m_export_to_file;
m_export_to_file = nullptr;
}
if (m_import_from_file)
{
delete m_import_from_file;
m_import_from_file = nullptr;
}
if (m_page_view)
{
delete m_page_view;
m_page_view = nullptr;
}
}
ParamsPanel::~ParamsPanel()
{
#if 0
free_sizers();
delete m_top_sizer;
delete_subwindows();
#endif
// BBS: fix double destruct of OG_CustomCtrl
Tab* cur_tab = dynamic_cast<Tab*> (m_current_tab);
if (cur_tab)
cur_tab->clear_pages();
}
} // GUI
} // Slic3r

14108
src/slic3r/GUI/Plater.cpp Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -152,6 +152,7 @@ void Tab::set_type()
else if (m_name == PRESET_FILAMENT_NAME) { m_type = Slic3r::Preset::TYPE_FILAMENT; }
else if (m_name == "sla_material") { m_type = Slic3r::Preset::TYPE_SLA_MATERIAL; }
else if (m_name == PRESET_PRINTER_NAME) { m_type = Slic3r::Preset::TYPE_PRINTER; }
else if (m_name == PRESET_CONFIG_NAME) { m_type = Slic3r::Preset::TYPE_CONFIG; }
else { m_type = Slic3r::Preset::TYPE_INVALID; assert(false); }
}
@ -1929,12 +1930,12 @@ void TabPrint::build()
//auto optgroup = page->new_optgroup(L("Layer height"), L"param_layer_height");
auto optgroup = page->new_optgroup("", L"param_layer_height");
//optgroup->append_single_option_line("layer_height", "layer-height");
optgroup->append_single_option_line("initial_layer_print_height", "layer-height");
//optgroup->append_single_option_line("initial_layer_print_height", "layer-height");
//xiamian-
//optgroup = page->new_optgroup(L("Line width"), L"param_line_width");
//optgroup->append_single_option_line("line_width","parameter/line-width");
optgroup->append_single_option_line("initial_layer_line_width","parameter/line-width");
optgroup->append_single_option_line("outer_wall_line_width","parameter/line-width");
//optgroup->append_single_option_line("initial_layer_line_width","parameter/line-width");
//optgroup->append_single_option_line("outer_wall_line_width","parameter/line-width");
optgroup->append_single_option_line("inner_wall_line_width","parameter/line-width");
optgroup->append_single_option_line("top_surface_line_width","parameter/line-width");
optgroup->append_single_option_line("sparse_infill_line_width","parameter/line-width");
@ -2041,7 +2042,7 @@ void TabPrint::build()
optgroup = page->new_optgroup("", L"param_speed",15);
//xiamian-
//optgroup = page->new_optgroup(L("Initial layer speed"), L"param_speed_first", 15);
//optgroup->append_single_option_line("default_print_speed");todo
optgroup->append_single_option_line("default_print_speed");
optgroup->append_single_option_line("initial_layer_speed");
optgroup->append_single_option_line("initial_layer_infill_speed");
//optgroup = page->new_optgroup(L("Other layers speed"), L"param_speed", 15);
@ -4280,6 +4281,49 @@ void TabPrinter::update_fff()
void TabPrinter::update_sla()
{ ; }
void TabConfig::build() {
m_presets = &m_preset_bundle->configs;
load_initial_data();
auto page = add_options_page(L("Quality"), "config");
auto optgroup = page->new_optgroup("", L"param_layer_height");
//optgroup->append_single_option_line("initial_layer_print_height", "layer-height");
optgroup->append_single_option_line("initial_layer_line_width");
optgroup->append_single_option_line("outer_wall_line_width", "parameter/line-width");
optgroup->append_single_option_line("inner_wall_line_width", "parameter/line-width");
optgroup->append_single_option_line("top_surface_line_width", "parameter/line-width");
optgroup->append_single_option_line("sparse_infill_line_width", "parameter/line-width");
optgroup->append_single_option_line("support_line_width", "parameter/line-width");
optgroup->append_single_option_line("resolution", "acr-move");
optgroup->append_single_option_line("enable_arc_fitting", "acr-move");
optgroup->append_single_option_line("wall_sequence");
}
void TabConfig::reload_config()
{
this->compatible_widget_reload(m_compatible_printers);
this->compatible_widget_reload(m_compatible_prints);
Tab::reload_config();
}
void TabConfig::update_description_lines()
{
Tab::update_description_lines();
//if (!m_active_page)
// return;
//if (m_active_page->title() == "Cooling" && m_cooling_description_line)
// m_cooling_description_line->SetText(from_u8(PresetHints::cooling_description(m_presets->get_edited_preset())));
//BBS
//if (m_active_page->title() == "Filament" && m_volumetric_speed_description_line)
// this->update_volumetric_flow_preset_hints();
}
void TabConfig::toggle_options() {
}
void TabConfig::update() {
}
void TabConfig::clear_pages() {
}
void Tab::update_ui_items_related_on_parent_preset(const Preset* selected_preset_parent)
{
m_is_default_preset = selected_preset_parent != nullptr && selected_preset_parent->is_default;
@ -4359,7 +4403,8 @@ void Tab::load_current_preset()
#ifdef _MSW_DARK_MODE
if (!wxGetApp().tabs_as_menu()) {
std::string bmp_name = tab->type() == Slic3r::Preset::TYPE_FILAMENT ? "spool" :
tab->type() == Slic3r::Preset::TYPE_SLA_MATERIAL ? "" : "cog";
tab->type() == Slic3r::Preset::TYPE_SLA_MATERIAL ? "" :
tab->type() == Slic3r::Preset::TYPE_CONFIG ? "config":"cog";
tab->Hide(); // #ys_WORKAROUND : Hide tab before inserting to avoid unwanted rendering of the tab
dynamic_cast<Notebook*>(wxGetApp().tab_panel())->InsertPage(wxGetApp().tab_panel()->FindPage(this), tab, tab->title(), bmp_name);
}
@ -5218,6 +5263,9 @@ void Tab::save_preset(std::string name /*= ""*/, bool detach, bool save_to_proje
else
dependent = { Preset::TYPE_SLA_PRINT, Preset::TYPE_SLA_MATERIAL };
break;
case Preset::TYPE_CONFIG:
dependent = { Preset::TYPE_CONFIG };
break;
default:
break;
}

View File

@ -565,6 +565,33 @@ public:
bool supports_printer_technology(const PrinterTechnology tech) const override { return tech == ptFFF; }
};
class TabConfig : public Tab
{
private:
//ogStaticText* m_volumetric_speed_description_line{ nullptr };
//ogStaticText* m_cooling_description_line{ nullptr };
//void add_config_overrides_page();
//void update_config_overrides_page();
//void update_volumetric_flow_preset_hints();
std::map<std::string, wxCheckBox*> m_overrides_options;
public:
//BBS: GUI refactor
TabConfig(ParamsPanel* parent) :
Tab(parent, _(L("Configuration")), Slic3r::Preset::TYPE_CONFIG) {}
~TabConfig() {}
void build() override;
void reload_config() override;
void update_description_lines() override;
void toggle_options() override;
void update() override;
void clear_pages() override;
bool supports_printer_technology(const PrinterTechnology tech) const override { return tech == ptFFF; }
};
class TabPrinter : public Tab
{
private: